diff -Nru a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes	Sun Jun 16 19:31:41 2002
+++ b/Documentation/Changes	Sun Jun 16 19:31:41 2002
@@ -314,7 +314,7 @@
 
 Reiserfsprogs
 -------------
-o  <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.0b.tar.gz>
+o  <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
 
 LVM toolset
 -----------
diff -Nru a/Documentation/filesystems/porting b/Documentation/filesystems/porting
--- a/Documentation/filesystems/porting	Sun Jun 16 19:31:40 2002
+++ b/Documentation/filesystems/porting	Sun Jun 16 19:31:40 2002
@@ -215,3 +215,16 @@
 had been relying on BKL and that's prone to screwups.  Old tree had quite
 a few holes of that kind - unprotected access to ->d_parent leading to
 anything from oops to silent memory corruption.
+
+---
+[mandatory]
+
+	FS_NOMOUNT is gone.  If you use it - just set MS_NOUSER in flags
+(see rootfs for one kind of solution and bdev/socket/pipe for another).
+
+---
+[recommended]
+
+	Use bdev_read_only(bdev) instead of is_read_only(kdev).  The latter
+is still alive, but only because of the mess in drivers/s390/block/dasd.c.
+As soon as it gets fixed is_read_only() will die.
diff -Nru a/Documentation/usb/philips.txt b/Documentation/usb/philips.txt
--- a/Documentation/usb/philips.txt	Sun Jun 16 19:31:41 2002
+++ b/Documentation/usb/philips.txt	Sun Jun 16 19:31:41 2002
@@ -189,10 +189,10 @@
 The fbufs, mbufs and trace parameters are global and apply to all connected
 cameras. Each camera has its own set of buffers.
 
-size, fps, palette only specify defaults when you open() the device; this is
-to accommodate some tools that don't set the size or colour palette. You can
-change these settings after open() with the Video4Linux ioctl() calls. The
-default of defaults is QCIF size at 10 fps, BGR order.
+size and fps only specify defaults when you open() the device; this is to
+accommodate some tools that don't set the size. You can change these
+settings after open() with the Video4Linux ioctl() calls. The default of
+defaults is QCIF size at 10 fps, BGR order.
 
 The compression parameter is semiglobal; it sets the initial compression
 preference for all camera's, but this parameter can be set per camera with
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Sun Jun 16 19:31:39 2002
+++ b/MAINTAINERS	Sun Jun 16 19:31:39 2002
@@ -1127,8 +1127,6 @@
 NETWORKING [IPv4/IPv6]
 P:	David S. Miller
 M:	davem@redhat.com
-P:	Andi Kleen
-M:	ak@muc.de
 P:	Alexey Kuznetsov
 M:	kuznet@ms2.inr.ac.ru
 P:	Pekka Savola (ipv6)
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Sun Jun 16 19:31:39 2002
+++ b/Makefile	Sun Jun 16 19:31:39 2002
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 21
+SUBLEVEL = 22
 EXTRAVERSION =
 
 # We are using a recursive build, so we need to do a little thinking
@@ -122,7 +122,9 @@
 
 noconfig_targets := xconfig menuconfig config oldconfig randconfig \
 		    defconfig allyesconfig allnoconfig allmodconfig \
-		    clean mrproper distclean
+		    clean mrproper distclean \
+		    tags TAGS sgmldocs psdocs pdfdocs htmldocs \
+		    checkconfig checkhelp checkincludes
 
 ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
 
@@ -222,10 +224,10 @@
 
 define rule_link_vmlinux
 	set -e
-	echo Generating build number
+	echo '  Generating build number'
 	. scripts/mkversion > .tmpversion
 	mv -f .tmpversion .version
-	$(MAKE) -C init
+	+$(MAKE) -C init
 	$(call cmd,cmd_link_vmlinux)
 	$(cmd_link_vmlinux)
 	echo 'cmd_$@ := $(cmd_link_vmlinux)' > $(@D)/.$(@F).cmd
@@ -243,14 +245,14 @@
 # 	Handle descending into subdirectories listed in $(SUBDIRS)
 
 .PHONY: $(SUBDIRS)
-$(SUBDIRS): .hdepend prepare include/config/MARKER
+$(SUBDIRS): .hdepend prepare
 	@$(MAKE) -C $@
 
 #	Things we need done before we descend to build or make
 #	module versions are listed in "prepare"
 
 .PHONY: prepare
-prepare: include/linux/version.h include/asm
+prepare: include/linux/version.h include/asm include/config/MARKER
 
 # Single targets
 # ---------------------------------------------------------------------------
@@ -273,13 +275,13 @@
 #	before switching between archs anyway.
 
 include/asm:
-	@echo 'Making asm->asm-$(ARCH) symlink'
+	@echo '  Making asm->asm-$(ARCH) symlink'
 	@ln -s asm-$(ARCH) $@
 
 # 	Split autoconf.h into include/linux/config/*
 
 include/config/MARKER: scripts/split-include include/linux/autoconf.h
-	@echo 'Splitting include/linux/autoconf.h -> include/config'
+	@echo '  SPLIT  include/linux/autoconf.h -> include/config/*'
 	@scripts/split-include include/linux/autoconf.h include/config
 	@touch $@
 
@@ -306,7 +308,7 @@
 	  echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \
 	  exit 1; \
 	fi;
-	@echo -n 'Generating $@'
+	@echo -n '  Generating $@'
 	@(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\"; \
 	  echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)`; \
 	 echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'; \
@@ -349,11 +351,11 @@
 include/linux/modversions.h: scripts/fixdep prepare FORCE
 	@rm -rf .tmp_export-objs
 	@$(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS))
-	@echo -n 'Generating $@'
+	@echo -n '  Generating $@'
 	@( echo "#ifndef _LINUX_MODVERSIONS_H";\
 	   echo "#define _LINUX_MODVERSIONS_H"; \
 	   echo "#include <linux/modsetver.h>"; \
-	   for f in `cd .tmp_export-objs; find modules -name \*.ver -print`; do \
+	   for f in `cd .tmp_export-objs; find modules -name \*.ver -print | sort`; do \
 	     echo "#include <linux/$${f}>"; \
 	   done; \
 	   echo "#endif"; \
@@ -431,44 +433,9 @@
 
 endif # CONFIG_MODULES
 
-# Scripts to check various things for consistency
-# ---------------------------------------------------------------------------
-
-checkconfig:
-	find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w scripts/checkconfig.pl
-
-checkhelp:
-	find * -name [cC]onfig.in -print | sort | xargs $(PERL) -w scripts/checkhelp.pl
-
-checkincludes:
-	find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w scripts/checkincludes.pl
-
-# Generate tags for editors
-# ---------------------------------------------------------------------------
-
-TAGS: FORCE
-	{ find include/asm-${ARCH} -name '*.h' -print ; \
-	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
-	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | etags -
-
-# 	Exuberant ctags works better with -I
-tags: FORCE
-	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
-	ctags $$CTAGSF `find include/asm-$(ARCH) -name '*.h'` && \
-	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs ctags $$CTAGSF -a && \
-	find $(SUBDIRS) init -name '*.[ch]' | xargs ctags $$CTAGSF -a
-
-# Assorted miscellaneous targets
+# RPM target
 # ---------------------------------------------------------------------------
 
-# Documentation targets
-
-sgmldocs psdocs pdfdocs htmldocs:
-	@$(MAKE) -C Documentation/DocBook $@
-
-
-# RPM target
-#
 #	If you do a make spec before packing the tarball you can rpm -ta it
 
 spec:
@@ -574,9 +541,8 @@
 
 #	files removed with 'make clean'
 CLEAN_FILES += \
-	kernel/ksyms.lst include/linux/compile.h \
+	include/linux/compile.h \
 	vmlinux System.map \
-	.tmp* \
 	drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
 	drivers/char/conmakehash \
 	drivers/char/drm/*-mod.c \
@@ -616,9 +582,11 @@
 	.hdepend scripts/split-include scripts/docproc \
 	scripts/fixdep $(TOPDIR)/include/linux/modversions.h \
 	tags TAGS kernel.spec \
+	.tmpversion
 
 # 	directories removed with 'make mrproper'
 MRPROPER_DIRS += \
+	.tmp_export-objs \
 	include/config \
 	$(TOPDIR)/include/linux/modules
 
@@ -631,7 +599,7 @@
 	@find . \( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
 		   -name .\*.tmp -o -name .\*.d \) -type f -print \
 		| grep -v lxdialog/ | xargs rm -f
-	@rm -rf $(CLEAN_FILES)
+	@rm -f $(CLEAN_FILES)
 	@$(MAKE) -C Documentation/DocBook clean
 
 mrproper: clean archmrproper
@@ -649,7 +617,41 @@
 	 	-o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -type f \
 		-print | xargs rm -f
 
+# Generate tags for editors
+# ---------------------------------------------------------------------------
+
+TAGS: FORCE
+	{ find include/asm-${ARCH} -name '*.h' -print ; \
+	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
+	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | etags -
+
+# 	Exuberant ctags works better with -I
+tags: FORCE
+	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
+	ctags $$CTAGSF `find include/asm-$(ARCH) -name '*.h'` && \
+	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs ctags $$CTAGSF -a && \
+	find $(SUBDIRS) init -name '*.[ch]' | xargs ctags $$CTAGSF -a
+
+# Documentation targets
+# ---------------------------------------------------------------------------
+
+sgmldocs psdocs pdfdocs htmldocs:
+	@$(MAKE) -C Documentation/DocBook $@
+
+
 endif # ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
+
+# Scripts to check various things for consistency
+# ---------------------------------------------------------------------------
+
+checkconfig:
+	find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w scripts/checkconfig.pl
+
+checkhelp:
+	find * -name [cC]onfig.in -print | sort | xargs $(PERL) -w scripts/checkhelp.pl
+
+checkincludes:
+	find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w scripts/checkincludes.pl
 
 # FIXME Should go into a make.lib or something 
 # ===========================================================================
diff -Nru a/Rules.make b/Rules.make
--- a/Rules.make	Sun Jun 16 19:31:40 2002
+++ b/Rules.make	Sun Jun 16 19:31:40 2002
@@ -48,12 +48,9 @@
 obj-y		:= $(patsubst %/, %/built-in.o, $(obj-y))
 obj-m		:= $(filter-out %/, $(obj-m))
 
-# If a dir is selected in $(subdir-y) and also mentioned in $(mod-subdirs),
-# add it to $(subdir-m)
+# Subdirectories we need to descend into
 
-both-m          := $(filter $(mod-subdirs), $(subdir-y))
 subdir-ym	:= $(sort $(subdir-y) $(subdir-m))
-subdir-ymn	:= $(sort $(subdir-ym) $(subdir-n) $(subdir-))
 
 # export.o is never a composite object, since $(export-objs) has a
 # fixed meaning (== objects which EXPORT_SYMBOL())
@@ -85,8 +82,116 @@
 real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
 real-objs-m := $(foreach m, $(obj-m), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m)))
 
-# Get things started.
+# Only build module versions for files which are selected to be built
+export-objs := $(filter $(export-objs),$(real-objs-y) $(real-objs-m))
+
+# The temporary file to save gcc -MD generated dependencies must not
+# contain a comma
+depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
+
+# We're called for one of three purposes:
+# o fastdep: build module version files (.ver) for $(export-objs) in
+#   the current directory
+# o modules_install: install the modules in the current directory
+# o build: When no target is given, first_rule is the default and
+#   will build the built-in and modular objects in this dir
+#   (or a subset thereof, depending on $(KBUILD_MODULES),$(KBUILD_BUILTIN)
+#   When targets are given directly (like foo.o), we just build these
+#   targets (That happens when someone does make some/dir/foo.[ois])
+
+ifeq ($(MAKECMDGOALS),fastdep)
+
+# ===========================================================================
+# Module versions
+# ===========================================================================
+
+ifeq ($(strip $(export-objs)),)
+
+# If we don't export any symbols in this dir, just descend
+# ---------------------------------------------------------------------------
+
+fastdep: sub_dirs
+	@echo -n
+
+else
+
+# This sets version suffixes on exported symbols
+# ---------------------------------------------------------------------------
+
+MODVERDIR := $(TOPDIR)/include/linux/modules/$(RELDIR)
+
+#
+# Added the SMP separator to stop module accidents between uniprocessor
+# and SMP Intel boxes - AC - from bits by Michael Chastain
+#
+
+ifdef CONFIG_SMP
+	genksyms_smp_prefix := -p smp_
+else
+	genksyms_smp_prefix := 
+endif
+
+$(MODVERDIR)/$(real-objs-y:.o=.ver): modkern_cflags := $(CFLAGS_KERNEL)
+$(MODVERDIR)/$(real-objs-m:.o=.ver): modkern_cflags := $(CFLAGS_MODULE)
+$(MODVERDIR)/$(export-objs:.o=.ver): export_flags   := -D__GENKSYMS__
+
+c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
+	  $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
+	  -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
+	  $(export_flags) 
+
+# Our objects only depend on modversions.h, not on the individual .ver
+# files (fix-dep filters them), so touch modversions.h if any of the .ver
+# files changes
+
+quiet_cmd_cc_ver_c = MKVER  include/linux/modules/$(RELDIR)/$*.ver
+define cmd_cc_ver_c
+	mkdir -p $(dir $@); \
+	$(CPP) $(c_flags) $< | $(GENKSYMS) $(genksyms_smp_prefix) \
+	  -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
+	if [ ! -r $@ ] || cmp -s $@ $@.tmp; then \
+	  touch $(TOPDIR)/include/linux/modversions.h; \
+	fi; \
+	mv -f $@.tmp $@
+endef
+
+$(MODVERDIR)/%.ver: %.c FORCE
+	@$(call if_changed_dep,cc_ver_c)
+
+targets := $(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver))
+
+fastdep: $(targets) sub_dirs
+	@mkdir -p $(TOPDIR)/.tmp_export-objs/modules/$(RELDIR)
+	@touch $(addprefix $(TOPDIR)/.tmp_export-objs/modules/$(RELDIR)/,$(export-objs:.o=.ver))
+
+endif # export-objs 
+
+else # ! fastdep
+ifeq ($(MAKECMDGOALS),modules_install)
+
+# ==========================================================================
+# Installing modules
+# ==========================================================================
+
+.PHONY: modules_install
+
+modules_install: sub_dirs
+ifneq ($(obj-m),)
+	@echo Installing modules in $(MODLIB)/kernel/$(RELDIR)
+	@mkdir -p $(MODLIB)/kernel/$(RELDIR)
+	@cp $(obj-m) $(MODLIB)/kernel/$(RELDIR)
+else
+	@echo -n
+endif
+
+else # ! modules_install
+
 # ==========================================================================
+# Building
+# ==========================================================================
+
+# If a Makefile does define neither O_TARGET nor L_TARGET,
+# use a standard O_TARGET named "built-in.o"
 
 ifndef O_TARGET
 ifndef L_TARGET
@@ -103,15 +208,9 @@
 # Compile C sources (.c)
 # ---------------------------------------------------------------------------
 
-# If we don't know if built-in or modular, assume built-in.
-# Only happens in Makefiles which override the default first_rule:
+# Default is built-in, unless we know otherwise
 modkern_cflags := $(CFLAGS_KERNEL)
 
-$(real-objs-y)        : modkern_cflags := $(CFLAGS_KERNEL)
-$(real-objs-y:.o=.i)  : modkern_cflags := $(CFLAGS_KERNEL)
-$(real-objs-y:.o=.s)  : modkern_cflags := $(CFLAGS_KERNEL)
-$(real-objs-y:.o=.lst): modkern_cflags := $(CFLAGS_KERNEL)
-
 $(real-objs-m)        : modkern_cflags := $(CFLAGS_MODULE)
 $(real-objs-m:.o=.i)  : modkern_cflags := $(CFLAGS_MODULE)
 $(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
@@ -121,60 +220,59 @@
 $(export-objs:.o=.s)  : export_flags   := $(EXPORT_FLAGS)
 $(export-objs:.o=.lst): export_flags   := $(EXPORT_FLAGS)
 
-c_flags = $(CFLAGS) $(NOSTDINC_FLAGS) $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(export_flags) 
+c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
+	  $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
+	  -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
+	  $(export_flags) 
 
 quiet_cmd_cc_s_c = CC     $(RELDIR)/$@
 cmd_cc_s_c       = $(CC) $(c_flags) -S -o $@ $< 
 
 %.s: %.c FORCE
-	$(call cmd,cmd_cc_s_c)
+	$(call if_changed_dep,cc_s_c)
 
 quiet_cmd_cc_i_c = CPP    $(RELDIR)/$@
 cmd_cc_i_c       = $(CPP) $(c_flags)   -o $@ $<
 
 %.i: %.c FORCE
-	$(call cmd,cmd_cc_i_c)
+	$(call if_changed_dep,cc_i_c)
 
 quiet_cmd_cc_o_c = CC     $(RELDIR)/$@
-cmd_cc_o_c       = $(CC) -Wp,-MD,.$(subst /,_,$@).d $(c_flags) -c -o $@ $<
+cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
 
 %.o: %.c FORCE
 	$(call if_changed_dep,cc_o_c)
 
-quiet_cmd_cc_lst_c = Generating $(RELDIR)/$@
+quiet_cmd_cc_lst_c = '  Generating $(RELDIR)/$@'
 cmd_cc_lst_c     = $(CC) $(c_flags) -g -c -o $*.o $< && $(TOPDIR)/scripts/makelst $*.o $(TOPDIR)/System.map $(OBJDUMP) > $@
 
 %.lst: %.c FORCE
-	$(call cmd,cmd_cc_lst_c)
+	$(call if_changed_dep,cc_lst_c)
 
 # Compile assembler sources (.S)
 # ---------------------------------------------------------------------------
 
-# FIXME (s.a.)
 modkern_aflags := $(AFLAGS_KERNEL)
 
-$(real-objs-y)      : modkern_aflags := $(AFLAGS_KERNEL)
-$(real-objs-y:.o=.s): modkern_aflags := $(AFLAGS_KERNEL)
-
 $(real-objs-m)      : modkern_aflags := $(AFLAGS_MODULE)
 $(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
 
-a_flags = $(AFLAGS) $(NOSTDINC_FLAGS) $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS) \
+	  $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
 
 quiet_cmd_as_s_S = CPP    $(RELDIR)/$@
 cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $< 
 
 %.s: %.S FORCE
-	$(call cmd,cmd_as_s_S)
+	$(call if_changed_dep,as_s_S)
 
 quiet_cmd_as_o_S = AS     $(RELDIR)/$@
-cmd_as_o_S       = $(CC) -Wp,-MD,.$(subst /,_,$@).d $(a_flags) -c -o $@ $<
+cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
 
 %.o: %.S FORCE
 	$(call if_changed_dep,as_o_S)
 
-# If a Makefile does define neither O_TARGET nor L_TARGET,
-# use a standard O_TARGET named "built-in.o"
+targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS)
 
 # Build the compiled-in targets
 # ---------------------------------------------------------------------------
@@ -193,7 +291,9 @@
 		      rm -f $@; $(AR) rcs $@)
 
 $(O_TARGET): $(obj-y) FORCE
-	$(call if_changed,cmd_link_o_target)
+	$(call if_changed,link_o_target)
+
+targets += $(O_TARGET)
 endif # O_TARGET
 
 #
@@ -204,7 +304,9 @@
 cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(obj-y)
 
 $(L_TARGET): $(obj-y) FORCE
-	$(call if_changed,cmd_link_l_target)
+	$(call if_changed,link_l_target)
+
+targets += $(L_TARGET)
 endif
 
 #
@@ -219,10 +321,12 @@
 # but that's not so easy, so we rather make all composite objects depend
 # on the set of all their parts
 $(multi-used-y) : %.o: $(multi-objs-y) FORCE
-	$(call if_changed,cmd_link_multi)
+	$(call if_changed,link_multi)
 
 $(multi-used-m) : %.o: $(multi-objs-m) FORCE
-	$(call if_changed,cmd_link_multi)
+	$(call if_changed,link_multi)
+
+targets += $(multi-used-y) $(multi-used-m)
 
 # Compile programs on the host
 # ===========================================================================
@@ -233,7 +337,8 @@
 
 quiet_cmd_host_cc__c  = HOSTCC $(RELDIR)/$@
 cmd_host_cc__c        = $(HOSTCC) -Wp,-MD,.$(subst /,_,$@).d \
-			$(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -o $@ $<
+			$(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
+			$(HOST_LOADLIBES) -o $@ $<
 
 $(host-progs-single): %: %.c FORCE
 	$(call if_changed_dep,host_cc__c)
@@ -250,51 +355,26 @@
 			$(HOST_LOADLIBES)
 
 $(host-progs-multi): %: $(host-progs-multi-objs) FORCE
-	$(call if_changed,cmd_host_cc__o)
-
-
-# Descending when making module versions
-# ---------------------------------------------------------------------------
-
-fastdep-list := $(addprefix _sfdep_,$(subdir-ymn))
+	$(call if_changed,host_cc__o)
 
-.PHONY: fastdep $(fastdep-list)
+targets += $(host-progs-single) $(host-progs-multi-objs) $(host-progs-multi) 
 
-fastdep: $(fastdep-list)
+endif # ! modules_install
+endif # ! fastdep
 
-$(fastdep-list):
-	@$(MAKE) -C $(patsubst _sfdep_%,%,$@) fastdep
-
-# Descending when building
-# ---------------------------------------------------------------------------
-
-subdir-list := $(addprefix _subdir_,$(subdir-ym))
-
-.PHONY: sub_dirs $(subdir-list)
-
-sub_dirs: $(subdir-list)
-
-$(subdir-list):
-	@$(MAKE) -C $(patsubst _subdir_%,%,$@)
+# ===========================================================================
+# Generic stuff
+# ===========================================================================
 
-# Descending and installing modules
+# Descending
 # ---------------------------------------------------------------------------
 
-modinst-list := $(addprefix _modinst_,$(subdir-ym))
+.PHONY: sub_dirs $(subdir-ym)
 
-.PHONY: modules_install _modinst_ $(modinst-list)
+sub_dirs: $(subdir-ym)
 
-modules_install: $(modinst-list)
-ifneq ($(obj-m),)
-	@echo Installing modules in $(MODLIB)/kernel/$(RELDIR)
-	@mkdir -p $(MODLIB)/kernel/$(RELDIR)
-	@cp $(obj-m) $(MODLIB)/kernel/$(RELDIR)
-else
-	@echo -n
-endif
-
-$(modinst-list):
-	@$(MAKE) -C $(patsubst _modinst_%,%,$@) modules_install
+$(subdir-ym):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
 
 # Add FORCE to the prequisites of a target to force it to be always rebuilt.
 # ---------------------------------------------------------------------------
@@ -304,62 +384,11 @@
 FORCE:
 
 #
-# This is useful for testing
-# FIXME: really?
-script:
-	$(SCRIPT)
-
-#
 # This sets version suffixes on exported symbols
 # Separate the object into "normal" objects and "exporting" objects
 # Exporting objects are: all objects that define symbol tables
 #
 
-ifdef CONFIG_MODVERSIONS
-ifneq "$(strip $(export-objs))" ""
-
-MODVERDIR := $(TOPDIR)/include/linux/modules/$(RELDIR)
-
-#
-# Added the SMP separator to stop module accidents between uniprocessor
-# and SMP Intel boxes - AC - from bits by Michael Chastain
-#
-
-ifdef CONFIG_SMP
-	genksyms_smp_prefix := -p smp_
-else
-	genksyms_smp_prefix := 
-endif
-
-# We don't track dependencies for .ver files, so we FORCE to check
-# them always (i.e. always at "make dep" time).
-
-quiet_cmd_create_ver = Creating include/linux/modules/$(RELDIR)/$*.ver
-cmd_create_ver = $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $< | \
-		 $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp
-
-$(MODVERDIR)/%.ver: %.c FORCE
-	@mkdir -p $(dir $@)
-	@$(call cmd,cmd_create_ver)
-	@if [ -r $@ ] && cmp -s $@ $@.tmp; then \
-	  rm -f $@.tmp; \
-	else \
-	  touch $(TOPDIR)/include/linux/modversions.h; \
-	  mv -f $@.tmp $@; \
-	fi
-
-# updates .ver files but not modversions.h
-fastdep: $(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver))
-ifneq ($(export-objs),)
-	@mkdir -p $(TOPDIR)/.tmp_export-objs/modules/$(RELDIR)
-	@touch $(addprefix $(TOPDIR)/.tmp_export-objs/modules/$(RELDIR)/,$(export-objs:.o=.ver))
-endif
-
-
-endif # export-objs 
-
-endif # CONFIG_MODVERSIONS
-
 # ---------------------------------------------------------------------------
 # Check if command line has changed
 
@@ -391,9 +420,14 @@
 #   which is saved in .<target>.o, to the current command line using
 #   the two filter-out commands)
 
-# read all saved command lines and dependencies
+# Read all saved command lines and dependencies for the $(targets) we
+# may be building above, using $(if_changed{,_dep}). As an
+# optimization, we don't need to read them if the target does not
+# exist, we will rebuild anyway in that case.
+
+targets := $(wildcard $(sort $(targets)))
+cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
 
-cmd_files := $(wildcard .*.cmd)
 ifneq ($(cmd_files),)
   include $(cmd_files)
 endif
@@ -401,9 +435,12 @@
 # function to only execute the passed command if necessary
 
 if_changed = $(if $(strip $? \
-		          $(filter-out $($(1)),$(cmd_$(@F)))\
-			  $(filter-out $(cmd_$(@F)),$($(1)))),\
-	       @$(if $($(quiet)$(1)),echo '  $($(quiet)$(1))' &&) $($(1)) && echo 'cmd_$@ := $($(1))' > $(@D)/.$(@F).cmd)
+		          $(filter-out $(cmd_$(1)),$(cmd_$@))\
+			  $(filter-out $(cmd_$@),$(cmd_$(1)))),\
+	@set -e; \
+	$(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))';) \
+	$(cmd_$(1)); \
+	echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd)
 
 
 # execute the command and also postprocess generated .d dependencies
@@ -415,9 +452,9 @@
 	@set -e; \
 	$(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))';) \
 	$(cmd_$(1)); \
-	$(TOPDIR)/scripts/fixdep $(subst /,_,$@) $(TOPDIR) '$(cmd_$(1))' > .$(subst /,_,$@).tmp; \
-	rm -f .$(subst /,_,$@).d; \
-	mv -f .$(subst /,_,$@).tmp .$(subst /,_,$@).cmd )
+	$(TOPDIR)/scripts/fixdep $(depfile) $@ $(TOPDIR) '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \
+	rm -f $(depfile); \
+	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
 
 # If quiet is set, only print short version of command
 
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/alpha/kernel/setup.c	Sun Jun 16 19:31:39 2002
@@ -31,6 +31,7 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
@@ -608,7 +609,7 @@
 #endif
 
 	/* Default root filesystem to sda2.  */
-	ROOT_DEV = to_kdev_t(0x0802);
+	ROOT_DEV = Root_SDA2;
 
  	/*
 	 * Check ASN in HWRPB for validity, report if bad.
diff -Nru a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
--- a/arch/alpha/kernel/smc37c669.c	Sun Jun 16 19:31:40 2002
+++ b/arch/alpha/kernel/smc37c669.c	Sun Jun 16 19:31:40 2002
@@ -7,6 +7,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/spinlock.h>
 
 #include <asm/hwrpb.h>
 #include <asm/io.h>
@@ -1103,66 +1104,7 @@
     unsigned int drq 
 );
 
-#if 0
-/*
-** External Data Declarations
-*/
-
-extern struct LOCK spl_atomic;
-
-/*
-** External Function Prototype Declarations
-*/
-
-/* From kernel_alpha.mar */
-extern spinlock( 
-    struct LOCK *spl 
-);
-
-extern spinunlock( 
-    struct LOCK *spl 
-);
-
-/* From filesys.c */
-int allocinode(
-    char *name, 
-    int can_create, 
-    struct INODE **ipp
-);
-
-extern int null_procedure( void );
-
-int smcc669_init( void );
-int smcc669_open( struct FILE *fp, char *info, char *next, char *mode );
-int smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf );
-int smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf );
-int smcc669_close( struct FILE *fp );
-
-struct DDB smc_ddb = {
-	"smc",			/* how this routine wants to be called	*/
-	smcc669_read,		/* read routine				*/
-	smcc669_write,		/* write routine			*/
-	smcc669_open,		/* open routine				*/
-	smcc669_close,		/* close routine			*/
-	null_procedure,		/* name expansion routine		*/
-	null_procedure,		/* delete routine			*/
-	null_procedure,		/* create routine			*/
-	null_procedure,		/* setmode				*/
-	null_procedure,		/* validation routine			*/
-	0,			/* class specific use			*/
-	1,			/* allows information			*/
-	0,			/* must be stacked			*/
-	0,			/* is a flash update driver		*/
-	0,			/* is a block device			*/
-	0,			/* not seekable				*/
-	0,			/* is an Ethernet device		*/
-	0,			/* is a filesystem driver		*/
-};
-#endif
-
-#define spinlock(x)
-#define spinunlock(x)
-
+static spinlock_t smc_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
 
 /*
 **++
@@ -2042,10 +1984,10 @@
 ** mode.  Therefore, a spinlock is placed around the two writes to 
 ** guarantee that they complete uninterrupted.
 */
-	spinlock( &spl_atomic );
+	spin_lock(&smc_lock);
     	wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
     	wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
-	spinunlock( &spl_atomic );
+	spin_unlock(&smc_lock);
     }
     else {
     	wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
--- a/arch/arm/kernel/setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/arm/kernel/setup.c	Sun Jun 16 19:31:39 2002
@@ -19,6 +19,7 @@
 #include <linux/seq_file.h>
 #include <linux/tty.h>
 #include <linux/init.h>
+#include <linux/root_dev.h>
 
 #include <asm/elf.h>
 #include <asm/hardware.h>
@@ -438,7 +439,7 @@
 	if (tag->hdr.size > 2) {
 		if ((tag->u.core.flags & 1) == 0)
 			root_mountflags &= ~MS_RDONLY;
-		ROOT_DEV = to_kdev_t(tag->u.core.rootdev);
+		ROOT_DEV = tag->u.core.rootdev;
 	}
 	return 0;
 }
diff -Nru a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
--- a/arch/arm/mach-integrator/pci_v3.c	Sun Jun 16 19:31:39 2002
+++ b/arch/arm/mach-integrator/pci_v3.c	Sun Jun 16 19:31:39 2002
@@ -439,15 +439,16 @@
 #define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x20)
 #define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x24)
 
-static int v3_fault(unsigned long addr, struct pt_regs *regs)
+static int
+v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	unsigned long pc = instruction_pointer(regs);
 	unsigned long instr = *(unsigned long *)pc;
 #if 0
 	char buf[128];
 
-	sprintf(buf, "V3 fault: address=0x%08lx, pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
-		addr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
+	sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
+		addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
 		v3_readb(V3_LB_ISTAT));
 	printk(KERN_DEBUG "%s", buf);
 	printascii(buf);
@@ -515,8 +516,6 @@
 #endif
 }
 
-extern int (*external_fault)(unsigned long addr, struct pt_regs *regs);
-
 int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
 {
 	int ret = 0;
@@ -547,7 +546,10 @@
 	/*
 	 * Hook in our fault handler for PCI errors
 	 */
-	external_fault = v3_fault;
+	hook_fault_code(4, v3_pci_fault, SIGBUS, "external abort on linefetch");
+	hook_fault_code(6, v3_pci_fault, SIGBUS, "external abort on linefetch");
+	hook_fault_code(8, v3_pci_fault, SIGBUS, "external abort on non-linefetch");
+	hook_fault_code(10, v3_pci_fault, SIGBUS, "external abort on non-linefetch");
 
 	spin_lock_irqsave(&v3_lock, flags);
 
diff -Nru a/arch/arm/mach-iop310/iop310-pci.c b/arch/arm/mach-iop310/iop310-pci.c
--- a/arch/arm/mach-iop310/iop310-pci.c	Sun Jun 16 19:31:40 2002
+++ b/arch/arm/mach-iop310/iop310-pci.c	Sun Jun 16 19:31:40 2002
@@ -106,19 +106,32 @@
 	return ret;
 }
 
+static inline u32 iop310_pri_read(struct pci_dev *dev, int where)
+{
+	unsigned long addr = iop310_cfg_address(dev, where);
+	u32 val;
+
+	__asm__ __volatile__(
+		"str	%1, [%2]\n\t"
+		"ldr	%0, [%3]\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		: "=r" (val)
+		: "r" (addr), "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
+
+	return val;
+}
+
 static int
 iop310_pri_rd_cfg_byte(struct pci_dev *dev, int where, u8 *p)
 {
-	int ret;
 	u8 val;
 
-	*IOP310_POCCAR = iop310_cfg_address(dev, where);
+	val = iop310_pri_read(dev, where) >> ((where & 3) * 8);
 
-	val = (*IOP310_POCCDR) >> ((where & 3) * 8);
-	__asm__ __volatile__("nop; nop; nop; nop");
-
-	ret = iop310_pri_pci_status();
-	if (ret)
+	if (iop310_pri_pci_status())
 		val = 0xff;
 
 	*p = val;
@@ -129,16 +142,11 @@
 static int
 iop310_pri_rd_cfg_word(struct pci_dev *dev, int where, u16 *p)
 {
-	int ret;
 	u16 val;
 
-	*IOP310_POCCAR = iop310_cfg_address(dev, where);
-
-	val = (*IOP310_POCCDR) >> ((where & 2) * 8);
-	__asm__ __volatile__("nop; nop; nop; nop");
+	val = iop310_pri_read(dev, where) >> ((where & 3) * 8);
 
-	ret = iop310_pri_pci_status();
-	if (ret)
+	if (iop310_pri_pci_status())
 		val = 0xffff;
 
 	*p = val;
@@ -149,16 +157,11 @@
 static int
 iop310_pri_rd_cfg_dword(struct pci_dev *dev, int where, u32 *p)
 {
-	int ret;
 	u32 val;
 
-	*IOP310_POCCAR = iop310_cfg_address(dev, where);
-
-	val = *IOP310_POCCDR;
-	__asm__ __volatile__("nop; nop; nop; nop");
+	val = iop310_pri_read(dev, where);
 
-	ret = iop310_pri_pci_status();
-	if (ret)
+	if (iop310_pri_pci_status())
 		val = 0xffffffff;
 
 	*p = val;
@@ -169,16 +172,11 @@
 static int
 iop310_pri_wr_cfg_byte(struct pci_dev *dev, int where, u8 v)
 {
-	int ret;
 	u32 val;
 
-	*IOP310_POCCAR = iop310_cfg_address(dev, where);
+	val = iop310_pri_read(dev, where);
 
-	val = *IOP310_POCCDR;
-	__asm__ __volatile__("nop; nop; nop; nop");
-
-	ret = iop310_pri_pci_status();
-	if (ret == 0) {
+	if (iop310_pri_pci_status() == 0) {
 		where = (where & 3) * 8;
 		val &= ~(0xff << where);
 		val |= v << where;
@@ -191,16 +189,11 @@
 static int
 iop310_pri_wr_cfg_word(struct pci_dev *dev, int where, u16 v)
 {
-	int ret;
 	u32 val;
 
-	*IOP310_POCCAR = iop310_cfg_address(dev, where);
-
-	val = *IOP310_POCCDR;
-	__asm__ __volatile__("nop; nop; nop; nop");
+	val = iop310_pri_read(dev, where);
 
-	ret = iop310_pri_pci_status();
-	if (ret == 0) {
+	if (iop310_pri_pci_status() == 0) {
 		where = (where & 2) * 8;
 		val &= ~(0xffff << where);
 		val |= v << where;
@@ -211,11 +204,21 @@
 }
 
 static int
-iop310_pri_wr_cfg_dword(struct pci_dev *dev, int where, u32 v)
+iop310_pri_wr_cfg_dword(struct pci_dev *dev, int where, u32 val)
 {
-	*IOP310_POCCAR = iop310_cfg_address(dev, where);
-	*IOP310_POCCDR = v;
-	__asm__ __volatile__("nop; nop; nop; nop");
+	unsigned long addr;
+
+	addr = iop310_cfg_address(dev, where);
+
+	__asm__ __volatile__(
+		"str	%1, [%2]\n\t"
+		"str	%0, [%3]\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		:
+		: "r" (val), "r" (addr), "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
 
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -248,28 +251,38 @@
 		ret = 1;
 	}
 	if (ret)
-		DBG("ERROR (%08lx %08lx)", usr, uisr);
+		DBG("ERROR (%08x %08x)", usr, uisr);
 	return ret;
 }
 
+static inline u32 iop310_sec_read(struct pci_dev *dev, int where)
+{
+	unsigned long addr = iop310_cfg_address(dev, where);
+	u32 val;
+
+	__asm__ __volatile__(
+		"str	%1, [%2]\n\t"
+		"ldr	%0, [%3]\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		: "=r" (val)
+		: "r" (addr), "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
+
+	return val;
+}
+
 static int
 iop310_sec_rd_cfg_byte(struct pci_dev *dev, int where, u8 *p)
 {
-	int ret;
 	u8 val;
 
-	DBG("rdb: %d:%02x.%x %02x ", dev->bus->number, PCI_SLOT(dev->devfn),
-	    PCI_FUNC(dev->devfn), where);
-	*IOP310_SOCCAR = iop310_cfg_address(dev, where);
-
-	val = (*IOP310_SOCCDR) >> ((where & 3) * 8);
-	__asm__ __volatile__("nop; nop; nop; nop");
+	val = iop310_sec_read(dev, where) >> ((where & 3) * 8);
 
-	DBG(">= %08lx ", val);
-	ret = iop310_sec_pci_status();
-	if (ret)
+	if (iop310_sec_pci_status())
 		val = 0xff;
-	DBG("\n");
+
 	*p = val;
 
 	return PCIBIOS_SUCCESSFUL;
@@ -278,21 +291,13 @@
 static int
 iop310_sec_rd_cfg_word(struct pci_dev *dev, int where, u16 *p)
 {
-	int ret;
 	u16 val;
 
-	DBG("rdw: %d:%02x.%x %02x ", dev->bus->number, PCI_SLOT(dev->devfn),
-	    PCI_FUNC(dev->devfn), where);
-	*IOP310_SOCCAR = iop310_cfg_address(dev, where);
-
-	val = (*IOP310_SOCCDR) >> ((where & 3) * 8);
-	__asm__ __volatile__("nop; nop; nop; nop");
+	val = iop310_sec_read(dev, where) >> ((where & 3) * 8);
 
-	DBG(">= %08lx ", val);
-	ret = iop310_sec_pci_status();
-	if (ret)
+	if (iop310_sec_pci_status())
 		val = 0xffff;
-	DBG("\n");
+
 	*p = val;
 
 	return PCIBIOS_SUCCESSFUL;
@@ -301,21 +306,13 @@
 static int
 iop310_sec_rd_cfg_dword(struct pci_dev *dev, int where, u32 *p)
 {
-	int ret;
 	u32 val;
 
-	DBG("rdl: %d:%02x.%x %02x ", dev->bus->number, PCI_SLOT(dev->devfn),
-	    PCI_FUNC(dev->devfn), where);
-	*IOP310_SOCCAR = iop310_cfg_address(dev, where);
-
-	val = *IOP310_SOCCDR;
-	__asm__ __volatile__("nop; nop; nop; nop");
+	val = iop310_sec_read(dev, where);
 
-	DBG(">= %08lx ", val);
-	ret = iop310_sec_pci_status();
-	if (ret)
+	if (iop310_sec_pci_status())
 		val = 0xffffffff;
-	DBG("\n");
+
 	*p = val;
 
 	return PCIBIOS_SUCCESSFUL;
@@ -324,63 +321,54 @@
 static int
 iop310_sec_wr_cfg_byte(struct pci_dev *dev, int where, u8 v)
 {
-	int ret;
 	u32 val;
 
-	DBG("wrb: %d:%02x.%x %02x ", dev->bus->number, PCI_SLOT(dev->devfn),
-	    PCI_FUNC(dev->devfn), where);
-	*IOP310_SOCCAR = iop310_cfg_address(dev, where);
-
-	val = *IOP310_SOCCDR;
-	__asm__ __volatile__("nop; nop; nop; nop");
-
-	DBG("<= %08lx", v);
-	ret = iop310_sec_pci_status();
-	if (ret == 0) {
+	val = iop310_sec_read(dev, where);
+
+	if (iop310_sec_pci_status() == 0) {
 		where = (where & 3) * 8;
 		val &= ~(0xff << where);
 		val |= v << where;
 		*IOP310_SOCCDR = val;
 	}
-	DBG("\n");
+
 	return PCIBIOS_SUCCESSFUL;
 }
 
 static int
 iop310_sec_wr_cfg_word(struct pci_dev *dev, int where, u16 v)
 {
-	int ret;
 	u32 val;
 
-	DBG("wrw: %d:%02x.%x %02x ", dev->bus->number, PCI_SLOT(dev->devfn),
-	    PCI_FUNC(dev->devfn), where);
-	*IOP310_SOCCAR = iop310_cfg_address(dev, where);
-
-	val = *IOP310_SOCCDR;
-	__asm__ __volatile__("nop; nop; nop; nop");
-
-	DBG("<= %08lx", v);
-	ret = iop310_sec_pci_status();
-	if (ret == 0) {
+	val = iop310_sec_read(dev, where);
+
+	if (iop310_sec_pci_status() == 0) {
 		where = (where & 2) * 8;
 		val &= ~(0xffff << where);
 		val |= v << where;
 		*IOP310_SOCCDR = val;
 	}
-	DBG("\n");
+
 	return PCIBIOS_SUCCESSFUL;
 }
 
 static int
-iop310_sec_wr_cfg_dword(struct pci_dev *dev, int where, u32 v)
+iop310_sec_wr_cfg_dword(struct pci_dev *dev, int where, u32 val)
 {
-	DBG("wrl: %d:%02x.%x %02x ", dev->bus->number, PCI_SLOT(dev->devfn),
-	    PCI_FUNC(dev->devfn), where);
-	*IOP310_SOCCAR = iop310_cfg_address(dev, where);
-	*IOP310_SOCCDR = v;
-	__asm__ __volatile__("nop; nop; nop; nop");
+	unsigned long addr;
+
+	addr = iop310_cfg_address(dev, where);
+
+	__asm__ __volatile__(
+		"str	%1, [%2]\n\t"
+		"str	%0, [%3]\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		:
+		: "r" (val), "r" (addr), "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
 
-	DBG("<= %08lx\n", v);
 	return PCIBIOS_SUCCESSFUL;
 }
 
@@ -394,13 +382,34 @@
 };
 
 /*
- * When a PCI device does not exist during config cycles, the 80200 gets a
- * bus error instead of returning 0xffffffff. This handler simply returns.
+ * When a PCI device does not exist during config cycles, the 80200 gets
+ * an external abort instead of returning 0xffffffff.  If it was an
+ * imprecise abort, we need to correct the return address to point after
+ * the instruction.  Also note that the Xscale manual says:
+ *
+ *  "if a stall-until-complete LD or ST instruction triggers an
+ *  imprecise fault, then that fault will be seen by the program
+ *  within 3 instructions."
+ *
+ * This does not appear to be the case.  With 8 NOPs after the load, we
+ * see the imprecise abort occuring on the STM of iop310_sec_pci_status()
+ * which is about 10 instructions away.
+ *
+ * Always trust reality!
  */
-int iop310_pci_abort_handler(unsigned long addr, struct pt_regs *regs)
+static int
+iop310_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
-	DBG("PCI abort: address = %08x PC = %08x LR = %08lx\n",
-		addr, regs->ARM_pc, regs->ARM_lr);
+	DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
+		addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
 	return 0;
 }
 
@@ -515,6 +524,5 @@
 	 */
 	*IOP310_PCR &= 0xfff8;
 
-	external_fault = iop310_pci_abort_handler;
+	hook_fault_code(6, iop310_pci_abort, SIGBUS, "imprecise external abort");
 }
-
diff -Nru a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
--- a/arch/arm/mach-sa1100/Makefile	Sun Jun 16 19:31:41 2002
+++ b/arch/arm/mach-sa1100/Makefile	Sun Jun 16 19:31:41 2002
@@ -40,6 +40,7 @@
 
 obj-$(CONFIG_SA1100_BADGE4)		+= badge4.o
 export-objs				+= badge4.o
+led-$(CONFIG_SA1100_BADGE4)		+= leds-badge4.o
 
 obj-$(CONFIG_SA1100_BRUTUS)		+= brutus.o
 led-$(CONFIG_SA1100_BRUTUS)		+= leds-brutus.o
diff -Nru a/arch/arm/mach-sa1100/leds-badge4.c b/arch/arm/mach-sa1100/leds-badge4.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mach-sa1100/leds-badge4.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,112 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-badge4.c
+ *
+ * Author: Christopher Hoover <ch@hpl.hp.com>
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_RED		GPIO_GPIO(7)
+#define LED_GREEN       GPIO_GPIO(9)
+#define LED_MASK	(LED_RED|LED_GREEN)
+
+#define LED_IDLE	LED_GREEN
+#define LED_TIMER	LED_RED
+
+void badge4_leds_event(led_event_t evt)
+{
+        unsigned long flags;
+
+	local_irq_save(flags);
+
+        switch (evt) {
+        case led_start:
+		GPDR |= LED_MASK;
+                hw_led_state = LED_MASK;
+                led_state = LED_STATE_ENABLED;
+                break;
+
+        case led_stop:
+                led_state &= ~LED_STATE_ENABLED;
+                break;
+
+        case led_claim:
+                led_state |= LED_STATE_CLAIMED;
+                hw_led_state = LED_MASK;
+                break;
+
+        case led_release:
+                led_state &= ~LED_STATE_CLAIMED;
+                hw_led_state = LED_MASK;
+                break;
+
+#ifdef CONFIG_LEDS_TIMER
+        case led_timer:
+                if (!(led_state & LED_STATE_CLAIMED))
+                        hw_led_state ^= LED_TIMER;
+                break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+        case led_idle_start:
+		/* LED off when system is idle */
+                if (!(led_state & LED_STATE_CLAIMED))
+                        hw_led_state &= ~LED_IDLE;
+                break;
+
+        case led_idle_end:
+                if (!(led_state & LED_STATE_CLAIMED))
+                        hw_led_state |= LED_IDLE;
+                break;
+#endif
+
+        case led_red_on:
+                if (!(led_state & LED_STATE_CLAIMED))
+                        hw_led_state &= ~LED_RED;
+                break;
+
+        case led_red_off:
+                if (!(led_state & LED_STATE_CLAIMED))
+                        hw_led_state |= LED_RED;
+                break;
+
+        case led_green_on:
+                if (!(led_state & LED_STATE_CLAIMED))
+                        hw_led_state &= ~LED_GREEN;
+                break;
+
+        case led_green_off:
+                if (!(led_state & LED_STATE_CLAIMED))
+                        hw_led_state |= LED_GREEN;
+                break;
+
+	default:
+		break;
+        }
+
+        if  (led_state & LED_STATE_ENABLED) {
+                GPSR = hw_led_state;
+                GPCR = hw_led_state ^ LED_MASK;
+        }
+
+	local_irq_restore(flags);
+}
diff -Nru a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c
--- a/arch/arm/mach-sa1100/leds.c	Sun Jun 16 19:31:39 2002
+++ b/arch/arm/mach-sa1100/leds.c	Sun Jun 16 19:31:39 2002
@@ -19,6 +19,8 @@
 		leds_event = assabet_leds_event;
  	if (machine_is_consus())
  	        leds_event = consus_leds_event;
+	if (machine_is_badge4())
+	  	leds_event = badge4_leds_event;
 	if (machine_is_brutus())
 		leds_event = brutus_leds_event;
 	if (machine_is_cerf())
diff -Nru a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h
--- a/arch/arm/mach-sa1100/leds.h	Sun Jun 16 19:31:39 2002
+++ b/arch/arm/mach-sa1100/leds.h	Sun Jun 16 19:31:39 2002
@@ -1,4 +1,5 @@
 extern void assabet_leds_event(led_event_t evt);
+extern void badge4_leds_event(led_event_t evt);
 extern void consus_leds_event(led_event_t evt);
 extern void brutus_leds_event(led_event_t evt);
 extern void cerf_leds_event(led_event_t evt);
diff -Nru a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
--- a/arch/arm/mm/Makefile	Sun Jun 16 19:31:40 2002
+++ b/arch/arm/mm/Makefile	Sun Jun 16 19:31:40 2002
@@ -26,11 +26,11 @@
 obj-$(CONFIG_DISCONTIGMEM) += discontig.o
 
 # Select the processor-specific files
-p-$(CONFIG_CPU_26)	+= proc-arm2,3.o
+p-$(CONFIG_CPU_26)	+= proc-arm2_3.o
 
 # ARMv3
-p-$(CONFIG_CPU_ARM610)	+= proc-arm6,7.o  tlb-v3.o   copypage-v3.o
-p-$(CONFIG_CPU_ARM710)	+= proc-arm6,7.o  tlb-v3.o   copypage-v3.o
+p-$(CONFIG_CPU_ARM610)	+= proc-arm6_7.o  tlb-v3.o   copypage-v3.o
+p-$(CONFIG_CPU_ARM710)	+= proc-arm6_7.o  tlb-v3.o   copypage-v3.o
 
 # ARMv4
 p-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o  tlb-v4.o   copypage-v4wt.o abort-lv4t.o
diff -Nru a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
--- a/arch/arm/mm/alignment.c	Sun Jun 16 19:31:39 2002
+++ b/arch/arm/mm/alignment.c	Sun Jun 16 19:31:39 2002
@@ -30,9 +30,7 @@
 #include <asm/pgtable.h>
 #include <asm/unaligned.h>
 
-extern void
-do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-	    int error_code, struct pt_regs *regs);
+#include "fault.h"
 
 /*
  * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
@@ -130,31 +128,6 @@
 	return count;
 }
 
-/*
- * This needs to be done after sysctl_init, otherwise sys/ will be
- * overwritten.  Actually, this shouldn't be in sys/ at all since
- * it isn't a sysctl, and it doesn't contain sysctl information.
- * We now locate it in /proc/cpu/alignment instead.
- */
-static int __init alignment_init(void)
-{
-	struct proc_dir_entry *res;
-
-	res = proc_mkdir("cpu", NULL);
-	if (!res)
-		return -ENOMEM;
-
-	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
-	if (!res)
-		return -ENOMEM;
-
-	res->read_proc = proc_alignment_read;
-	res->write_proc = proc_alignment_write;
-
-	return 0;
-}
-
-__initcall(alignment_init);
 #endif /* CONFIG_PROC_FS */
 
 union offset_union {
@@ -486,7 +459,8 @@
 	return TYPE_ERROR;
 }
 
-int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
+static int
+do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	union offset_union offset;
 	unsigned long instr, instrptr;
@@ -577,7 +551,7 @@
 	/*
 	 * We got a fault - fix it up, or die.
 	 */
-	do_bad_area(current, current->mm, addr, error_code, regs);
+	do_bad_area(current, current->mm, addr, fsr, regs);
 	return 0;
 
  bad:
@@ -594,8 +568,8 @@
 
 	if (ai_usermode & 1)
 		printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%08lx "
-		       "Address=0x%08lx Code 0x%02x\n", current->comm,
-			current->pid, instrptr, instr, addr, error_code);
+		       "Address=0x%08lx FSR 0x%03x\n", current->comm,
+			current->pid, instrptr, instr, addr, fsr);
 
 	if (ai_usermode & 2)
 		goto fixup;
@@ -607,3 +581,34 @@
 
 	return 0;
 }
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten.  Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *res;
+
+	res = proc_mkdir("cpu", NULL);
+	if (!res)
+		return -ENOMEM;
+
+	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
+	if (!res)
+		return -ENOMEM;
+
+	res->read_proc = proc_alignment_read;
+	res->write_proc = proc_alignment_write;
+#endif
+
+	hook_fault_code(1, do_alignment, SIGILL, "alignment exception");
+	hook_fault_code(3, do_alignment, SIGILL, "alignment exception");
+
+	return 0;
+}
+
+__initcall(alignment_init);
diff -Nru a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
--- a/arch/arm/mm/fault-armv.c	Sun Jun 16 19:31:39 2002
+++ b/arch/arm/mm/fault-armv.c	Sun Jun 16 19:31:39 2002
@@ -2,108 +2,79 @@
  *  linux/arch/arm/mm/fault-armv.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Modifications for ARM processor (c) 1995-2001 Russell King
+ *  Modifications for ARM processor (c) 1995-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/config.h>
-#include <linux/compiler.h>
-#include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
-#include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
 
-#include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 
-extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
-extern void show_pte(struct mm_struct *mm, unsigned long addr);
-extern int do_page_fault(unsigned long addr, int error_code,
-			 struct pt_regs *regs);
-extern int do_translation_fault(unsigned long addr, int error_code,
-				struct pt_regs *regs);
-extern void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
-			unsigned long addr, int error_code,
-			struct pt_regs *regs);
-
-#ifdef CONFIG_ALIGNMENT_TRAP
-extern int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs);
-#else
-#define do_alignment do_bad
-#endif
-
+#include "fault.h"
 
 /*
  * Some section permission faults need to be handled gracefully.
  * They can happen due to a __{get,put}_user during an oops.
  */
 static int
-do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
-	do_bad_area(tsk, tsk->active_mm, addr, error_code, regs);
+	do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
 	return 0;
 }
 
 /*
- * Hook for things that need to trap external faults.  Note that
- * we don't guarantee that this will be the final version of the
- * interface.
- */
-int (*external_fault)(unsigned long addr, struct pt_regs *regs);
-
-static int
-do_external_fault(unsigned long addr, int error_code, struct pt_regs *regs)
-{
-	if (external_fault)
-		return external_fault(addr, regs);
-	return 1;
-}
-
-/*
  * This abort handler always returns "fault".
  */
 static int
-do_bad(unsigned long addr, int error_code, struct pt_regs *regs)
+do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	return 1;
 }
 
-static const struct fsr_info {
-	int	(*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
+static struct fsr_info {
+	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 	int	sig;
 	const char *name;
 } fsr_info[] = {
 	{ do_bad,		SIGSEGV, "vector exception"		   },
-	{ do_alignment,		SIGILL,	 "alignment exception"		   },
+	{ do_bad,		SIGILL,	 "alignment exception"		   },
 	{ do_bad,		SIGKILL, "terminal exception"		   },
-	{ do_alignment,		SIGILL,	 "alignment exception"		   },
-	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
+	{ do_bad,		SIGILL,	 "alignment exception"		   },
+	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
 	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
-	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
+	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
 	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
-	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
+	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
 	{ do_bad,		SIGSEGV, "section domain fault"		   },
-	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
+	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
 	{ do_bad,		SIGSEGV, "page domain fault"		   },
 	{ do_bad,		SIGBUS,	 "external abort on translation"   },
 	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
 	{ do_bad,		SIGBUS,	 "external abort on translation"   },
 	{ do_page_fault,	SIGSEGV, "page permission fault"	   }
 };
+
+void __init
+hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
+		int sig, const char *name)
+{
+	if (nr >= 0 && nr < 16) {
+		fsr_info[nr].fn   = fn;
+		fsr_info[nr].sig  = sig;
+		fsr_info[nr].name = name;
+	}
+}
 
 /*
  * Dispatch a data abort to the relevant handler.
diff -Nru a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
--- a/arch/arm/mm/fault-common.c	Sun Jun 16 19:31:39 2002
+++ b/arch/arm/mm/fault-common.c	Sun Jun 16 19:31:39 2002
@@ -23,9 +23,9 @@
 #include <linux/init.h>
 
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/unaligned.h>
+
+#include "fault.h"
 
 #ifdef CONFIG_CPU_26
 #define FAULT_CODE_WRITE	0x02
@@ -43,8 +43,6 @@
 #define READ_FAULT(code)	(!DO_COW(code))
 #endif
 
-NORET_TYPE void die(const char *msg, struct pt_regs *regs, int err) ATTRIB_NORET;
-
 /*
  * This is useful to dump out the page tables associated with
  * 'addr' in mm 'mm'.
@@ -101,7 +99,7 @@
  * Oops.  The kernel tried to access some page that wasn't present.
  */
 static void
-__do_kernel_fault(struct mm_struct *mm, unsigned long addr, int error_code,
+__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
 		  struct pt_regs *regs)
 {
 	unsigned long fixup;
@@ -127,7 +125,7 @@
 		"paging request", addr);
 
 	show_pte(mm, addr);
-	die("Oops", regs, error_code);
+	die("Oops", regs, fsr);
 	do_exit(SIGKILL);
 }
 
@@ -136,20 +134,20 @@
  * User mode accesses just cause a SIGSEGV
  */
 static void
-__do_user_fault(struct task_struct *tsk, unsigned long addr, int error_code,
-		int code, struct pt_regs *regs)
+__do_user_fault(struct task_struct *tsk, unsigned long addr,
+		unsigned int fsr, int code, struct pt_regs *regs)
 {
 	struct siginfo si;
 
 #ifdef CONFIG_DEBUG_USER
 	printk(KERN_DEBUG "%s: unhandled page fault at 0x%08lx, code 0x%03x\n",
-	       tsk->comm, addr, error_code);
+	       tsk->comm, addr, fsr);
 	show_pte(tsk->mm, addr);
 	show_regs(regs);
 #endif
 
 	tsk->thread.address = addr;
-	tsk->thread.error_code = error_code;
+	tsk->thread.error_code = fsr;
 	tsk->thread.trap_no = 14;
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
@@ -160,20 +158,20 @@
 
 void
 do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-	    int error_code, struct pt_regs *regs)
+	    unsigned int fsr, struct pt_regs *regs)
 {
 	/*
 	 * If we are in kernel mode at this point, we
 	 * have no context to handle this fault with.
 	 */
 	if (user_mode(regs))
-		__do_user_fault(tsk, addr, error_code, SEGV_MAPERR, regs);
+		__do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs);
 	else
-		__do_kernel_fault(mm, addr, error_code, regs);
+		__do_kernel_fault(mm, addr, fsr, regs);
 }
 
 static int
-__do_page_fault(struct mm_struct *mm, unsigned long addr, int error_code,
+__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
 		struct task_struct *tsk)
 {
 	struct vm_area_struct *vma;
@@ -191,7 +189,7 @@
 	 * memory access, so we can handle it.
 	 */
 good_area:
-	if (READ_FAULT(error_code)) /* read? */
+	if (READ_FAULT(fsr)) /* read? */
 		mask = VM_READ|VM_EXEC;
 	else
 		mask = VM_WRITE;
@@ -206,7 +204,7 @@
 	 * than endlessly redo the fault.
 	 */
 survive:
-	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(error_code));
+	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(fsr));
 
 	/*
 	 * Handle the "normal" cases first - successful and sigbus
@@ -239,7 +237,7 @@
 	return fault;
 }
 
-int do_page_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
@@ -256,7 +254,7 @@
 		goto no_context;
 
 	down_read(&mm->mmap_sem);
-	fault = __do_page_fault(mm, addr, error_code, tsk);
+	fault = __do_page_fault(mm, addr, fsr, tsk);
 	up_read(&mm->mmap_sem);
 
 	/*
@@ -287,7 +285,7 @@
 		printk("VM: killing process %s\n", tsk->comm);
 		do_exit(SIGKILL);
 	} else
-		__do_user_fault(tsk, addr, error_code, fault == -1 ?
+		__do_user_fault(tsk, addr, fsr, fault == -1 ?
 				SEGV_ACCERR : SEGV_MAPERR, regs);
 	return 0;
 
@@ -302,7 +300,7 @@
 	 * or user mode.
 	 */
 	tsk->thread.address = addr;
-	tsk->thread.error_code = error_code;
+	tsk->thread.error_code = fsr;
 	tsk->thread.trap_no = 14;
 	force_sig(SIGBUS, tsk);
 #ifdef CONFIG_DEBUG_USER
@@ -315,7 +313,7 @@
 		return 0;
 
 no_context:
-	__do_kernel_fault(mm, addr, error_code, regs);
+	__do_kernel_fault(mm, addr, fsr, regs);
 	return 0;
 }
 
@@ -336,7 +334,8 @@
  * interrupt or a critical region, and should only copy the information
  * from the master page table, nothing more.
  */
-int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+int do_translation_fault(unsigned long addr, unsigned int fsr,
+			 struct pt_regs *regs)
 {
 	struct task_struct *tsk;
 	unsigned int offset;
@@ -344,7 +343,7 @@
 	pmd_t *pmd, *pmd_k;
 
 	if (addr < TASK_SIZE)
-		return do_page_fault(addr, error_code, regs);
+		return do_page_fault(addr, fsr, regs);
 
 	offset = __pgd_offset(addr);
 
@@ -372,6 +371,6 @@
 bad_area:
 	tsk = current;
 
-	do_bad_area(tsk, tsk->active_mm, addr, error_code, regs);
+	do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
 	return 0;
 }
diff -Nru a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mm/fault.h	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,8 @@
+void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
+		 unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+
+void show_pte(struct mm_struct *mm, unsigned long addr);
+
+int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+
+int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
diff -Nru a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S
--- a/arch/arm/mm/proc-arm2,3.S	Sun Jun 16 19:31:40 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,370 +0,0 @@
-/*
- *  linux/arch/arm/mm/proc-arm2,3.S
- *
- *  Copyright (C) 1997-1999 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  MMU functions for ARM2,3
- *
- *  These are the low level assembler for performing cache
- *  and memory functions on ARM2, ARM250 and ARM3 processors.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/constants.h>
-#include <asm/procinfo.h>
-
-/*
- * MEMC workhorse code.  It's both a horse which things it's a pig.
- */
-/*
- * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
- * Params  : pgd	Page tables/MEMC mapping
- *         : phys_pte	physical address, or PTE
- *         : addr	virtual address
- */
-ENTRY(cpu_memc_update_entry)
-		tst	r1, #PAGE_PRESENT		@ is the page present
-		orreq	r1, r1, #PAGE_OLD | PAGE_CLEAN
-		moveq	r2, #0x01f00000
-		mov	r3, r1, lsr #13			@ convert to physical page nr
-		and	r3, r3, #0x3fc
-		adr	ip, memc_phys_table_32
-		ldr	r3, [ip, r3]
-		tst	r1, #PAGE_OLD | PAGE_NOT_USER
-		biceq	r3, r3, #0x200
-		tsteq	r1, #PAGE_READONLY | PAGE_CLEAN
-		biceq	r3, r3, #0x300
-		mov	r2, r2, lsr #15			@ virtual -> nr
-		orr	r3, r3, r2, lsl #15
-		and	r2, r2, #0x300
-		orr	r3, r3, r2, lsl #2
-		and	r2, r3, #255
-		sub	r0, r0, #256 * 4
-		str	r3, [r0, r2, lsl #2]
-		strb	r3, [r3]
-		movs	pc, lr
-/*
- * Params  : r0 = preserved
- *         : r1 = memc table base (preserved)
- *         : r2 = page table entry
- *         : r3 = preserved
- *         : r4 = unused
- *         : r5 = memc physical address translation table
- *         : ip = virtual address (preserved)
- */
-update_pte:
-		mov	r4, r2, lsr #13
-		and	r4, r4, #0x3fc
-		ldr	r4, [r5, r4]			@ covert to MEMC page
-
-		tst	r2, #PAGE_OLD | PAGE_NOT_USER	@ check for MEMC read
-		biceq	r4, r4, #0x200
-		tsteq	r2, #PAGE_READONLY | PAGE_CLEAN	@ check for MEMC write
-		biceq	r4, r4, #0x300
-
-		orr	r4, r4, ip
-		and	r2, ip, #0x01800000
-		orr	r4, r4, r2, lsr #13
-
-		and	r2, r4, #255
-		str	r4, [r1, r2, lsl #2]
-		movs	pc, lr
-
-/*
- * Params  : r0 = preserved
- *         : r1 = memc table base (preserved)
- *         : r2 = page table base
- *         : r3 = preserved
- *         : r4 = unused
- *         : r5 = memc physical address translation table
- *         : ip = virtual address (updated)
- */
-update_pte_table:
-		stmfd	sp!, {r0, lr}
-		bic	r0, r2, #3
-1:		ldr	r2, [r0], #4			@ get entry
-		tst	r2, #PAGE_PRESENT		@ page present
-		blne	update_pte			@ process pte
-		add	ip, ip, #32768			@ increment virt addr
-		ldr	r2, [r0], #4			@ get entry
-		tst	r2, #PAGE_PRESENT		@ page present
-		blne	update_pte			@ process pte
-		add	ip, ip, #32768			@ increment virt addr
-		ldr	r2, [r0], #4			@ get entry
-		tst	r2, #PAGE_PRESENT		@ page present
-		blne	update_pte			@ process pte
-		add	ip, ip, #32768			@ increment virt addr
-		ldr	r2, [r0], #4			@ get entry
-		tst	r2, #PAGE_PRESENT		@ page present
-		blne	update_pte			@ process pte
-		add	ip, ip, #32768			@ increment virt addr
-		tst	ip, #32768 * 31			@ finished?
-		bne	1b
-		ldmfd	sp!, {r0, pc}^
-
-/*
- * Function: cpu_memc_update_all(pgd_t *pgd)
- * Params  : pgd	Page tables/MEMC mapping
- * Notes   : this is optimised for 32k pages
- */
-ENTRY(cpu_memc_update_all)
-		stmfd	sp!, {r4, r5, lr}
-		bl	clear_tables
-		sub	r1, r0, #256 * 4		@ start of MEMC tables
-		adr	r5, memc_phys_table_32		@ Convert to logical page number
-		mov	ip, #0				@ virtual address
-1:		ldmia	r0!, {r2, r3}
-		tst	r2, #PAGE_PRESENT
-		addeq	ip, ip, #1048576
-		blne	update_pte_table
-		mov	r2, r3
-		tst	r2, #PAGE_PRESENT
-		addeq	ip, ip, #1048576
-		blne	update_pte_table
-		teq	ip, #32 * 1048576
-		bne	1b
-		ldmfd	sp!, {r4, r5, pc}^
-
-/*
- * Build the table to map from physical page number to memc page number
- */
-		.type	memc_phys_table_32, #object
-memc_phys_table_32:
-		.irp	b7, 0x00, 0x80
-		.irp	b6, 0x00, 0x02
-		.irp	b5, 0x00, 0x04
-		.irp	b4, 0x00, 0x01
-
-		.irp	b3, 0x00, 0x40
-		.irp	b2, 0x00, 0x20
-		.irp	b1, 0x00, 0x10
-		.irp	b0, 0x00, 0x08
-		.long	0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
-		.endr
-		.endr
-		.endr
-		.endr
-
-		.endr
-		.endr
-		.endr
-		.endr
-		.size	memc_phys_table_32, . - memc_phys_table_32
-
-/*
- * helper for cpu_memc_update_all, this clears out all
- * mappings, setting them close to the top of memory,
- * and inaccessible (0x01f00000).
- * Params  : r0 = page table pointer
- */
-clear_tables:	ldr	r1, _arm3_set_pgd - 4
-		ldr	r2, [r1]
-		sub	r1, r0, #256 * 4		@ start of MEMC tables
-		add	r2, r1, r2, lsl #2		@ end of tables
-		mov	r3, #0x03f00000			@ Default mapping (null mapping)
-		orr	r3, r3, #0x00000f00
-		orr	r4, r3, #1
-		orr	r5, r3, #2
-		orr	ip, r3, #3
-1:		stmia	r1!, {r3, r4, r5, ip}
-		add	r3, r3, #4
-		add	r4, r4, #4
-		add	r5, r5, #4
-		add	ip, ip, #4
-		stmia	r1!, {r3, r4, r5, ip}
-		add	r3, r3, #4
-		add	r4, r4, #4
-		add	r5, r5, #4
-		add	ip, ip, #4
-		teq	r1, r2
-		bne	1b
-		mov	pc, lr
-
-/*
- * Function: *_set_pgd(pgd_t *pgd)
- * Params  : pgd	New page tables/MEMC mapping
- * Purpose : update MEMC hardware with new mapping
- */
-		.word	page_nr
-_arm3_set_pgd:	mcr	p15, 0, r1, c1, c0, 0		@ flush cache
-_arm2_set_pgd:	stmfd	sp!, {lr}
-		ldr	r1, _arm3_set_pgd - 4
-		ldr	r2, [r1]
-		sub	r0, r0, #256 * 4		@ start of MEMC tables
-		add	r1, r0, r2, lsl #2		@ end of tables
-1:		ldmia	r0!, {r2, r3, ip, lr}
-		strb	r2, [r2]
-		strb	r3, [r3]
-		strb	ip, [ip]
-		strb	lr, [lr]
-		ldmia	r0!, {r2, r3, ip, lr}
-		strb	r2, [r2]
-		strb	r3, [r3]
-		strb	ip, [ip]
-		strb	lr, [lr]
-		teq	r0, r1
-		bne	1b
-		ldmfd	sp!, {pc}^
-
-/*
- * Function: *_proc_init (void)
- * Purpose : Initialise the cache control registers
- */
-_arm3_proc_init:
-		mov	r0, #0x001f0000
-		orr	r0, r0, #0x0000ff00
-		orr	r0, r0, #0x000000ff
-		mcr	p15, 0, r0, c3, c0		@ ARM3 Cacheable
-		mcr     p15, 0, r0, c4, c0		@ ARM3 Updateable
-		mov	r0, #0
-		mcr     p15, 0, r0, c5, c0		@ ARM3 Disruptive
-		mcr     p15, 0, r0, c1, c0		@ ARM3 Flush
-		mov	r0, #3
-		mcr     p15, 0, r0, c2, c0		@ ARM3 Control
-_arm2_proc_init:
-		movs	pc, lr
-
-/*
- * Function: *_proc_fin (void)
- * Purpose : Finalise processor (disable caches)
- */
-_arm3_proc_fin:	mov	r0, #2
-		mcr	p15, 0, r0, c2, c0
-_arm2_proc_fin:	orrs	pc, lr, #PSR_I_BIT|PSR_F_BIT
-
-/*
- * Function: *_xchg_1 (int new, volatile void *ptr)
- * Params  : new	New value to store at...
- *	   : ptr	pointer to byte-wide location
- * Purpose : Performs an exchange operation
- * Returns : Original byte data at 'ptr'
- */
-_arm2_xchg_1:	mov	r2, pc
-		orr	r2, r2, #PSR_I_BIT
-		teqp	r2, #0
-		ldrb	r2, [r1]
-		strb	r0, [r1]
-		mov	r0, r2
-		movs	pc, lr
-
-_arm3_xchg_1:	swpb	r0, r0, [r1]
-		movs	pc, lr
-
-/*
- * Function: *_xchg_4 (int new, volatile void *ptr)
- * Params  : new	New value to store at...
- *	   : ptr	pointer to word-wide location
- * Purpose : Performs an exchange operation
- * Returns : Original word data at 'ptr'
- */
-_arm2_xchg_4:	mov	r2, pc
-		orr	r2, r2, #PSR_I_BIT
-		teqp	r2, #0
-		ldr	r2, [r1]
-		str	r0, [r1]
-		mov	r0, r2
-		movs	pc, lr
-
-_arm3_xchg_4:	swp	r0, r0, [r1]
-		movs	pc, lr
-
-_arm2_3_check_bugs:
-		bics	pc, lr, #0x04000000		@ Clear FIQ disable bit
-
-armvlsi_name:	.asciz	"ARM/VLSI"
-_arm2_name:	.asciz	"ARM 2"
-_arm250_name:	.asciz	"ARM 250"
-_arm3_name:	.asciz	"ARM 3"
-
-		.section ".text.init", #alloc, #execinstr
-/*
- * Purpose : Function pointers used to access above functions - all calls
- *	     come through these
- */
-		.globl	arm2_processor_functions
-arm2_processor_functions:
-		.word	_arm2_3_check_bugs
-		.word	_arm2_proc_init
-		.word	_arm2_proc_fin
-		.word	_arm2_set_pgd
-		.word	_arm2_xchg_1
-		.word	_arm2_xchg_4
-
-cpu_arm2_info:
-		.long	armvlsi_name
-		.long	_arm2_name
-
-		.globl	arm250_processor_functions
-arm250_processor_functions:
-		.word	_arm2_3_check_bugs
-		.word	_arm2_proc_init
-		.word	_arm2_proc_fin
-		.word	_arm2_set_pgd
-		.word	_arm3_xchg_1
-		.word	_arm3_xchg_4
-
-cpu_arm250_info:
-		.long	armvlsi_name
-		.long	_arm250_name
-
-		.globl	arm3_processor_functions
-arm3_processor_functions:
-		.word	_arm2_3_check_bugs
-		.word	_arm3_proc_init
-		.word	_arm3_proc_fin
-		.word	_arm3_set_pgd
-		.word	_arm3_xchg_1
-		.word	_arm3_xchg_4
-
-cpu_arm3_info:
-		.long	armvlsi_name
-		.long	_arm3_name
-
-arm2_arch_name:	.asciz	"armv1"
-arm3_arch_name:	.asciz	"armv2"
-arm2_elf_name:	.asciz	"v1"
-arm3_elf_name:	.asciz	"v2"
-		.align
-
-		.section ".proc.info", #alloc, #execinstr
-
-		.long	0x41560200
-		.long	0xfffffff0
-		.long	0
-		mov	pc, lr
-		.long	arm2_arch_name
-		.long	arm2_elf_name
-		.long	0
-		.long	cpu_arm2_info
-		.long	arm2_processor_functions
-		.long	0
-		.long	0
-
-		.long	0x41560250
-		.long	0xfffffff0
-		.long	0
-		mov	pc, lr
-		.long	arm3_arch_name
-		.long	arm3_elf_name
-		.long	0
-		.long	cpu_arm250_info
-		.long	arm250_processor_functions
-		.long	0
-		.long	0
-
-		.long	0x41560300
-		.long	0xfffffff0
-		.long	0
-		mov	pc, lr
-		.long	arm3_arch_name
-		.long	arm3_elf_name
-		.long	0
-		.long	cpu_arm3_info
-		.long	arm3_processor_functions
-		.long	0
-		.long	0
-
diff -Nru a/arch/arm/mm/proc-arm2_3.S b/arch/arm/mm/proc-arm2_3.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mm/proc-arm2_3.S	Sun Jun 16 19:31:40 2002
@@ -0,0 +1,370 @@
+/*
+ *  linux/arch/arm/mm/proc-arm2,3.S
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  MMU functions for ARM2,3
+ *
+ *  These are the low level assembler for performing cache
+ *  and memory functions on ARM2, ARM250 and ARM3 processors.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+
+/*
+ * MEMC workhorse code.  It's both a horse which things it's a pig.
+ */
+/*
+ * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
+ * Params  : pgd	Page tables/MEMC mapping
+ *         : phys_pte	physical address, or PTE
+ *         : addr	virtual address
+ */
+ENTRY(cpu_memc_update_entry)
+		tst	r1, #PAGE_PRESENT		@ is the page present
+		orreq	r1, r1, #PAGE_OLD | PAGE_CLEAN
+		moveq	r2, #0x01f00000
+		mov	r3, r1, lsr #13			@ convert to physical page nr
+		and	r3, r3, #0x3fc
+		adr	ip, memc_phys_table_32
+		ldr	r3, [ip, r3]
+		tst	r1, #PAGE_OLD | PAGE_NOT_USER
+		biceq	r3, r3, #0x200
+		tsteq	r1, #PAGE_READONLY | PAGE_CLEAN
+		biceq	r3, r3, #0x300
+		mov	r2, r2, lsr #15			@ virtual -> nr
+		orr	r3, r3, r2, lsl #15
+		and	r2, r2, #0x300
+		orr	r3, r3, r2, lsl #2
+		and	r2, r3, #255
+		sub	r0, r0, #256 * 4
+		str	r3, [r0, r2, lsl #2]
+		strb	r3, [r3]
+		movs	pc, lr
+/*
+ * Params  : r0 = preserved
+ *         : r1 = memc table base (preserved)
+ *         : r2 = page table entry
+ *         : r3 = preserved
+ *         : r4 = unused
+ *         : r5 = memc physical address translation table
+ *         : ip = virtual address (preserved)
+ */
+update_pte:
+		mov	r4, r2, lsr #13
+		and	r4, r4, #0x3fc
+		ldr	r4, [r5, r4]			@ covert to MEMC page
+
+		tst	r2, #PAGE_OLD | PAGE_NOT_USER	@ check for MEMC read
+		biceq	r4, r4, #0x200
+		tsteq	r2, #PAGE_READONLY | PAGE_CLEAN	@ check for MEMC write
+		biceq	r4, r4, #0x300
+
+		orr	r4, r4, ip
+		and	r2, ip, #0x01800000
+		orr	r4, r4, r2, lsr #13
+
+		and	r2, r4, #255
+		str	r4, [r1, r2, lsl #2]
+		movs	pc, lr
+
+/*
+ * Params  : r0 = preserved
+ *         : r1 = memc table base (preserved)
+ *         : r2 = page table base
+ *         : r3 = preserved
+ *         : r4 = unused
+ *         : r5 = memc physical address translation table
+ *         : ip = virtual address (updated)
+ */
+update_pte_table:
+		stmfd	sp!, {r0, lr}
+		bic	r0, r2, #3
+1:		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		tst	ip, #32768 * 31			@ finished?
+		bne	1b
+		ldmfd	sp!, {r0, pc}^
+
+/*
+ * Function: cpu_memc_update_all(pgd_t *pgd)
+ * Params  : pgd	Page tables/MEMC mapping
+ * Notes   : this is optimised for 32k pages
+ */
+ENTRY(cpu_memc_update_all)
+		stmfd	sp!, {r4, r5, lr}
+		bl	clear_tables
+		sub	r1, r0, #256 * 4		@ start of MEMC tables
+		adr	r5, memc_phys_table_32		@ Convert to logical page number
+		mov	ip, #0				@ virtual address
+1:		ldmia	r0!, {r2, r3}
+		tst	r2, #PAGE_PRESENT
+		addeq	ip, ip, #1048576
+		blne	update_pte_table
+		mov	r2, r3
+		tst	r2, #PAGE_PRESENT
+		addeq	ip, ip, #1048576
+		blne	update_pte_table
+		teq	ip, #32 * 1048576
+		bne	1b
+		ldmfd	sp!, {r4, r5, pc}^
+
+/*
+ * Build the table to map from physical page number to memc page number
+ */
+		.type	memc_phys_table_32, #object
+memc_phys_table_32:
+		.irp	b7, 0x00, 0x80
+		.irp	b6, 0x00, 0x02
+		.irp	b5, 0x00, 0x04
+		.irp	b4, 0x00, 0x01
+
+		.irp	b3, 0x00, 0x40
+		.irp	b2, 0x00, 0x20
+		.irp	b1, 0x00, 0x10
+		.irp	b0, 0x00, 0x08
+		.long	0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
+		.endr
+		.endr
+		.endr
+		.endr
+
+		.endr
+		.endr
+		.endr
+		.endr
+		.size	memc_phys_table_32, . - memc_phys_table_32
+
+/*
+ * helper for cpu_memc_update_all, this clears out all
+ * mappings, setting them close to the top of memory,
+ * and inaccessible (0x01f00000).
+ * Params  : r0 = page table pointer
+ */
+clear_tables:	ldr	r1, _arm3_set_pgd - 4
+		ldr	r2, [r1]
+		sub	r1, r0, #256 * 4		@ start of MEMC tables
+		add	r2, r1, r2, lsl #2		@ end of tables
+		mov	r3, #0x03f00000			@ Default mapping (null mapping)
+		orr	r3, r3, #0x00000f00
+		orr	r4, r3, #1
+		orr	r5, r3, #2
+		orr	ip, r3, #3
+1:		stmia	r1!, {r3, r4, r5, ip}
+		add	r3, r3, #4
+		add	r4, r4, #4
+		add	r5, r5, #4
+		add	ip, ip, #4
+		stmia	r1!, {r3, r4, r5, ip}
+		add	r3, r3, #4
+		add	r4, r4, #4
+		add	r5, r5, #4
+		add	ip, ip, #4
+		teq	r1, r2
+		bne	1b
+		mov	pc, lr
+
+/*
+ * Function: *_set_pgd(pgd_t *pgd)
+ * Params  : pgd	New page tables/MEMC mapping
+ * Purpose : update MEMC hardware with new mapping
+ */
+		.word	page_nr
+_arm3_set_pgd:	mcr	p15, 0, r1, c1, c0, 0		@ flush cache
+_arm2_set_pgd:	stmfd	sp!, {lr}
+		ldr	r1, _arm3_set_pgd - 4
+		ldr	r2, [r1]
+		sub	r0, r0, #256 * 4		@ start of MEMC tables
+		add	r1, r0, r2, lsl #2		@ end of tables
+1:		ldmia	r0!, {r2, r3, ip, lr}
+		strb	r2, [r2]
+		strb	r3, [r3]
+		strb	ip, [ip]
+		strb	lr, [lr]
+		ldmia	r0!, {r2, r3, ip, lr}
+		strb	r2, [r2]
+		strb	r3, [r3]
+		strb	ip, [ip]
+		strb	lr, [lr]
+		teq	r0, r1
+		bne	1b
+		ldmfd	sp!, {pc}^
+
+/*
+ * Function: *_proc_init (void)
+ * Purpose : Initialise the cache control registers
+ */
+_arm3_proc_init:
+		mov	r0, #0x001f0000
+		orr	r0, r0, #0x0000ff00
+		orr	r0, r0, #0x000000ff
+		mcr	p15, 0, r0, c3, c0		@ ARM3 Cacheable
+		mcr     p15, 0, r0, c4, c0		@ ARM3 Updateable
+		mov	r0, #0
+		mcr     p15, 0, r0, c5, c0		@ ARM3 Disruptive
+		mcr     p15, 0, r0, c1, c0		@ ARM3 Flush
+		mov	r0, #3
+		mcr     p15, 0, r0, c2, c0		@ ARM3 Control
+_arm2_proc_init:
+		movs	pc, lr
+
+/*
+ * Function: *_proc_fin (void)
+ * Purpose : Finalise processor (disable caches)
+ */
+_arm3_proc_fin:	mov	r0, #2
+		mcr	p15, 0, r0, c2, c0
+_arm2_proc_fin:	orrs	pc, lr, #PSR_I_BIT|PSR_F_BIT
+
+/*
+ * Function: *_xchg_1 (int new, volatile void *ptr)
+ * Params  : new	New value to store at...
+ *	   : ptr	pointer to byte-wide location
+ * Purpose : Performs an exchange operation
+ * Returns : Original byte data at 'ptr'
+ */
+_arm2_xchg_1:	mov	r2, pc
+		orr	r2, r2, #PSR_I_BIT
+		teqp	r2, #0
+		ldrb	r2, [r1]
+		strb	r0, [r1]
+		mov	r0, r2
+		movs	pc, lr
+
+_arm3_xchg_1:	swpb	r0, r0, [r1]
+		movs	pc, lr
+
+/*
+ * Function: *_xchg_4 (int new, volatile void *ptr)
+ * Params  : new	New value to store at...
+ *	   : ptr	pointer to word-wide location
+ * Purpose : Performs an exchange operation
+ * Returns : Original word data at 'ptr'
+ */
+_arm2_xchg_4:	mov	r2, pc
+		orr	r2, r2, #PSR_I_BIT
+		teqp	r2, #0
+		ldr	r2, [r1]
+		str	r0, [r1]
+		mov	r0, r2
+		movs	pc, lr
+
+_arm3_xchg_4:	swp	r0, r0, [r1]
+		movs	pc, lr
+
+_arm2_3_check_bugs:
+		bics	pc, lr, #0x04000000		@ Clear FIQ disable bit
+
+armvlsi_name:	.asciz	"ARM/VLSI"
+_arm2_name:	.asciz	"ARM 2"
+_arm250_name:	.asciz	"ARM 250"
+_arm3_name:	.asciz	"ARM 3"
+
+		.section ".text.init", #alloc, #execinstr
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.globl	arm2_processor_functions
+arm2_processor_functions:
+		.word	_arm2_3_check_bugs
+		.word	_arm2_proc_init
+		.word	_arm2_proc_fin
+		.word	_arm2_set_pgd
+		.word	_arm2_xchg_1
+		.word	_arm2_xchg_4
+
+cpu_arm2_info:
+		.long	armvlsi_name
+		.long	_arm2_name
+
+		.globl	arm250_processor_functions
+arm250_processor_functions:
+		.word	_arm2_3_check_bugs
+		.word	_arm2_proc_init
+		.word	_arm2_proc_fin
+		.word	_arm2_set_pgd
+		.word	_arm3_xchg_1
+		.word	_arm3_xchg_4
+
+cpu_arm250_info:
+		.long	armvlsi_name
+		.long	_arm250_name
+
+		.globl	arm3_processor_functions
+arm3_processor_functions:
+		.word	_arm2_3_check_bugs
+		.word	_arm3_proc_init
+		.word	_arm3_proc_fin
+		.word	_arm3_set_pgd
+		.word	_arm3_xchg_1
+		.word	_arm3_xchg_4
+
+cpu_arm3_info:
+		.long	armvlsi_name
+		.long	_arm3_name
+
+arm2_arch_name:	.asciz	"armv1"
+arm3_arch_name:	.asciz	"armv2"
+arm2_elf_name:	.asciz	"v1"
+arm3_elf_name:	.asciz	"v2"
+		.align
+
+		.section ".proc.info", #alloc, #execinstr
+
+		.long	0x41560200
+		.long	0xfffffff0
+		.long	0
+		mov	pc, lr
+		.long	arm2_arch_name
+		.long	arm2_elf_name
+		.long	0
+		.long	cpu_arm2_info
+		.long	arm2_processor_functions
+		.long	0
+		.long	0
+
+		.long	0x41560250
+		.long	0xfffffff0
+		.long	0
+		mov	pc, lr
+		.long	arm3_arch_name
+		.long	arm3_elf_name
+		.long	0
+		.long	cpu_arm250_info
+		.long	arm250_processor_functions
+		.long	0
+		.long	0
+
+		.long	0x41560300
+		.long	0xfffffff0
+		.long	0
+		mov	pc, lr
+		.long	arm3_arch_name
+		.long	arm3_elf_name
+		.long	0
+		.long	cpu_arm3_info
+		.long	arm3_processor_functions
+		.long	0
+		.long	0
+
diff -Nru a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
--- a/arch/arm/mm/proc-arm6,7.S	Sun Jun 16 19:31:41 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,504 +0,0 @@
-/*
- *  linux/arch/arm/mm/proc-arm6,7.S
- *
- *  Copyright (C) 1997-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  These are the low level assembler for performing cache and TLB
- *  functions on the ARM610 & ARM710.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/constants.h>
-#include <asm/procinfo.h>
-
-/*
- * Function: arm6_7_cache_clean_invalidate_all (void)
- *	   : arm6_7_cache_clean_invalidate_page (unsigned long address, int size, int flags)
- *
- * Params  : address	Area start address
- *	   : size	size of area
- *	   : flags	b0 = I cache as well
- *
- * Purpose : Flush all cache lines
- */
-ENTRY(cpu_arm6_cache_clean_invalidate_all)
-ENTRY(cpu_arm7_cache_clean_invalidate_all)
-ENTRY(cpu_arm6_cache_clean_invalidate_range)
-ENTRY(cpu_arm7_cache_clean_invalidate_range)
-ENTRY(cpu_arm6_icache_invalidate_range)
-ENTRY(cpu_arm7_icache_invalidate_range)
-ENTRY(cpu_arm6_icache_invalidate_page)
-ENTRY(cpu_arm7_icache_invalidate_page)
-ENTRY(cpu_arm6_dcache_clean_range)
-ENTRY(cpu_arm7_dcache_clean_range)
-ENTRY(cpu_arm6_dcache_invalidate_range)
-ENTRY(cpu_arm7_dcache_invalidate_range)
-		mov	r0, #0
-		mcr	p15, 0, r0, c7, c0, 0		@ flush cache
-ENTRY(cpu_arm6_dcache_clean_page)
-ENTRY(cpu_arm7_dcache_clean_page)
-ENTRY(cpu_arm6_dcache_clean_entry)
-ENTRY(cpu_arm7_dcache_clean_entry)
-		mov	pc, lr
-
-/*
- * Function: arm6_7_data_abort ()
- *
- * Params  : r0 = address of aborted instruction
- *
- * Purpose : obtain information about current aborted instruction
- *
- * Returns : r0 = address of abort
- *	   : r1 != 0 if writing
- *	   : r3 = FSR
- *	   : sp = pointer to registers
- */
-
-ENTRY(cpu_arm6_data_abort)
-		ldr	r4, [r0]			@ read instruction causing problem
-		tst	r4, r4, lsr #21			@ C = bit 20
-		sbc	r1, r1, r1			@ r1 = C - 1
-		and	r2, r4, #14 << 24
-		teq	r2, #8 << 24			@ was it ldm/stm
-		bne	Ldata_simple
-
-Ldata_ldmstm:	tst	r4, #1 << 21			@ check writeback bit
-		beq	Ldata_simple
-		mov	r7, #0x11
-		orr	r7, r7, r7, lsl #8
-		and	r0, r4, r7
-		and	r2, r4, r7, lsl #1
-		add	r0, r0, r2, lsr #1
-		and	r2, r4, r7, lsl #2
-		add	r0, r0, r2, lsr #2
-		and	r2, r4, r7, lsl #3
-		add	r0, r0, r2, lsr #3
-		add	r0, r0, r0, lsr #8
-		add	r0, r0, r0, lsr #4
-		and	r7, r0, #15			@ r7 = no. of registers to transfer.
-		and	r5, r4, #15 << 16		@ Get Rn
-		ldr	r0, [sp, r5, lsr #14]		@ Get register
-		tst	r4, #1 << 23			@ U bit
-		subne	r7, r0, r7, lsl #2
-		addeq	r7, r0, r7, lsl #2		@ Do correction (signed)
-Ldata_saver7:	str	r7, [sp, r5, lsr #14]		@ Put register
-Ldata_simple:	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-		mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-		and	r3, r3, #255
-		mov	pc, lr
-
-ENTRY(cpu_arm7_data_abort)
-		ldr	r4, [r0]			@ read instruction causing problem
-		tst	r4, r4, lsr #21			@ C = bit 20
-		sbc	r1, r1, r1			@ r1 = C - 1
-		and	r2, r4, #15 << 24
-		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
-		movs	pc, lr
-
-		b	Ldata_unknown
-		b	Ldata_unknown
-		b	Ldata_unknown
-		b	Ldata_unknown
-		b	Ldata_lateldrpostconst		@ ldr	rd, [rn], #m
-		b	Ldata_lateldrpreconst		@ ldr	rd, [rn, #m]	@ RegVal
-		b	Ldata_lateldrpostreg		@ ldr	rd, [rn], rm
-		b	Ldata_lateldrprereg		@ ldr	rd, [rn, rm]
-		b	Ldata_ldmstm			@ ldm*a	rn, <rlist>
-		b	Ldata_ldmstm			@ ldm*b	rn, <rlist>
-		b	Ldata_unknown
-		b	Ldata_unknown
-		b	Ldata_simple			@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
-		b	Ldata_simple			@ ldc	rd, [rn, #m]
-		b	Ldata_unknown
-Ldata_unknown:	@ Part of jumptable
-		mov	r0, r2
-		mov	r1, r4
-		mov	r2, r3
-		bl	baddataabort
-		b	ret_from_exception
-
-Ldata_lateldrpreconst:
-		tst	r4, #1 << 21			@ check writeback bit
-		beq	Ldata_simple
-Ldata_lateldrpostconst:
-		movs	r2, r4, lsl #20			@ Get offset
-		beq	Ldata_simple
-		and	r5, r4, #15 << 16		@ Get Rn
-		ldr	r0, [sp, r5, lsr #14]
-		tst	r4, #1 << 23			@ U bit
-		subne	r7, r0, r2, lsr #20
-		addeq	r7, r0, r2, lsr #20
-		b	Ldata_saver7
-
-Ldata_lateldrprereg:
-		tst	r4, #1 << 21			@ check writeback bit
-		beq	Ldata_simple
-Ldata_lateldrpostreg:
-		and	r5, r4, #15
-		ldr	r2, [sp, r5, lsl #2]		@ Get Rm
-		mov	r3, r4, lsr #7
-		ands	r3, r3, #31
-		and	r6, r4, #0x70
-		orreq	r6, r6, #8
-		add	pc, pc, r6
-		mov	r0, r0
-
-		mov	r2, r2, lsl r3			@ 0: LSL #!0
-		b	1f
-		b	1f				@ 1: LSL #0
-		mov	r0, r0
-		b	1f				@ 2: MUL?
-		mov	r0, r0
-		b	1f				@ 3: MUL?
-		mov	r0, r0
-		mov	r2, r2, lsr r3			@ 4: LSR #!0
-		b	1f
-		mov	r2, r2, lsr #32			@ 5: LSR #32
-		b	1f
-		b	1f				@ 6: MUL?
-		mov	r0, r0
-		b	1f				@ 7: MUL?
-		mov	r0, r0
-		mov	r2, r2, asr r3			@ 8: ASR #!0
-		b	1f
-		mov	r2, r2, asr #32			@ 9: ASR #32
-		b	1f
-		b	1f				@ A: MUL?
-		mov	r0, r0
-		b	1f				@ B: MUL?
-		mov	r0, r0
-		mov	r2, r2, ror r3			@ C: ROR #!0
-		b	1f
-		mov	r2, r2, rrx			@ D: RRX
-		b	1f
-		mov	r0, r0				@ E: MUL?
-		mov	r0, r0
-		mov	r0, r0				@ F: MUL?
-
-
-1:		and	r5, r4, #15 << 16		@ Get Rn
-		ldr	r0, [sp, r5, lsr #14]
-		tst	r4, #1 << 23			@ U bit
-		subne	r7, r0, r2
-		addeq	r7, r0, r2
-		b	Ldata_saver7
-
-/*
- * Function: arm6_7_check_bugs (void)
- *	   : arm6_7_proc_init (void)
- *	   : arm6_7_proc_fin (void)
- *
- * Notes   : This processor does not require these
- */
-ENTRY(cpu_arm6_check_bugs)
-ENTRY(cpu_arm7_check_bugs)
-		mrs	ip, cpsr
-		bic	ip, ip, #PSR_F_BIT
-		msr	cpsr, ip
-		mov	pc, lr
-
-ENTRY(cpu_arm6_proc_init)
-ENTRY(cpu_arm7_proc_init)
-		mov	pc, lr
-
-ENTRY(cpu_arm6_proc_fin)
-ENTRY(cpu_arm7_proc_fin)
-		mov	r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-		msr	cpsr_c, r0
-		mov	r0, #0x31			@ ....S..DP...M
-		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-		mov	pc, lr
-
-ENTRY(cpu_arm6_do_idle)
-ENTRY(cpu_arm7_do_idle)
-		mov	r0, #-EINVAL
-		mov	pc, lr
-
-/*
- * Function: arm6_7_set_pgd(unsigned long pgd_phys)
- * Params  : pgd_phys	Physical address of page table
- * Purpose : Perform a task switch, saving the old processes state, and restoring
- *	     the new.
- */
-ENTRY(cpu_arm6_set_pgd)
-ENTRY(cpu_arm7_set_pgd)
-		mov	r1, #0
-		mcr	p15, 0, r1, c7, c0, 0		@ flush cache
-		mcr	p15, 0, r0, c2, c0, 0		@ update page table ptr
-		mcr	p15, 0, r1, c5, c0, 0		@ flush TLBs
-		mov	pc, lr
-
-/*
- * Function: arm6_set_pmd ()
- *
- * Params  : r0 = Address to set
- *	   : r1 = value to set
- *
- * Purpose : Set a PMD and flush it out of any WB cache
- */
-ENTRY(cpu_arm6_set_pmd)
-		and	r2, r1, #11
-		teq	r2, #1
-		teqne	r2, #9
-		teqne	r2, #10
-		orreq	r1, r1, #16			@ Updatable = 1 if Page table/Cacheable section
-		str	r1, [r0]
-		mov	pc, lr
-
-/*
- * Function: arm7_set_pmd ()
- *
- * Params  : r0 = Address to set
- *	   : r1 = value to set
- *
- * Purpose : Set a PMD and flush it out of any WB cache
- */
-ENTRY(cpu_arm7_set_pmd)
-		tst	r1, #3
-		orrne	r1, r1, #16			@ Updatable bit is always set on ARM7
-		str	r1, [r0]
-		mov	pc, lr
-
-/*
- * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
- * Params  : r0 = Address to set
- *	   : r1 = value to set
- * Purpose : Set a PTE and flush it out of any WB cache
- */
-		.align	5
-ENTRY(cpu_arm6_set_pte)
-ENTRY(cpu_arm7_set_pte)
-		tst	r0, #2048
-		streq	r0, [r0, -r0]			@ BUG_ON
-		str	r1, [r0], #-2048		@ linux version
-
-		eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
-
-		bic	r2, r1, #0xff0
-		bic	r2, r2, #3
-		orr	r2, r2, #HPTE_TYPE_SMALL
-
-		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
-		orrne	r2, r2, #HPTE_AP_READ
-
-		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
-		orreq	r2, r2, #HPTE_AP_WRITE
-
-		tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young
-		movne	r2, #0
-
-		str	r2, [r0]			@ hardware version
-		mov	pc, lr
-
-/*
- * Function: _arm6_7_reset
- * Params  : r0 = address to jump to
- * Notes   : This sets up everything for a reset
- */
-ENTRY(cpu_arm6_reset)
-ENTRY(cpu_arm7_reset)
-		mov	r1, #0
-		mcr	p15, 0, r1, c7, c0, 0		@ flush cache
-		mcr	p15, 0, r1, c5, c0, 0		@ flush TLB
-		mov	r1, #0x30
-		mcr	p15, 0, r1, c1, c0, 0		@ turn off MMU etc
-		mov	pc, r0
-
-cpu_armvlsi_name:
-		.asciz	"ARM/VLSI"
-cpu_arm6_name:	.asciz	"ARM 6"
-cpu_arm610_name:
-		.asciz	"ARM 610"
-cpu_arm7_name:	.asciz	"ARM 7"
-cpu_arm710_name:
-		.asciz	"ARM 710"
-		.align
-
-		.section ".text.init", #alloc, #execinstr
-
-__arm6_setup:	mov	r0, #0
-		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
-		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
-		mcr	p15, 0, r4, c2, c0		@ load page table pointer
-		mov	r0, #0x1f			@ Domains 0, 1 = client
-		mcr	p15, 0, r0, c3, c0		@ load domain access register
-		mov	r0, #0x3d			@ . ..RS BLDP WCAM
-		orr	r0, r0, #0x100			@ . ..01 0011 1101
-		mov	pc, lr
-
-__arm7_setup:	mov	r0, #0
-		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
-		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
-		mcr	p15, 0, r4, c2, c0		@ load page table pointer
-		mov	r0, #0x1f			@ Domains 0, 1 = client
-		mcr	p15, 0, r0, c3, c0		@ load domain access register
-		mov	r0, #0x7d			@ . ..RS BLDP WCAM
-		orr	r0, r0, #0x100			@ . ..01 0111 1101
-		mov	pc, lr
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- *	     come through these
- */
-		.type	arm6_processor_functions, #object
-ENTRY(arm6_processor_functions)
-		.word	cpu_arm6_data_abort
-		.word	cpu_arm6_check_bugs
-		.word	cpu_arm6_proc_init
-		.word	cpu_arm6_proc_fin
-		.word	cpu_arm6_reset
-		.word	cpu_arm6_do_idle
-
-		/* cache */
-		.word	cpu_arm6_cache_clean_invalidate_all
-		.word	cpu_arm6_cache_clean_invalidate_range
-
-		/* dcache */
-		.word	cpu_arm6_dcache_invalidate_range
-		.word	cpu_arm6_dcache_clean_range
-		.word	cpu_arm6_dcache_clean_page
-		.word	cpu_arm6_dcache_clean_entry
-
-		/* icache */
-		.word	cpu_arm6_icache_invalidate_range
-		.word	cpu_arm6_icache_invalidate_page
-
-		/* pgtable */
-		.word	cpu_arm6_set_pgd
-		.word	cpu_arm6_set_pmd
-		.word	cpu_arm6_set_pte
-
-		.size	arm6_processor_functions, . - arm6_processor_functions
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- *	     come through these
- */
-		.type	arm7_processor_functions, #object
-ENTRY(arm7_processor_functions)
-		.word	cpu_arm7_data_abort
-		.word	cpu_arm7_check_bugs
-		.word	cpu_arm7_proc_init
-		.word	cpu_arm7_proc_fin
-		.word	cpu_arm7_reset
-		.word	cpu_arm7_do_idle
-
-		/* cache */
-		.word	cpu_arm7_cache_clean_invalidate_all
-		.word	cpu_arm7_cache_clean_invalidate_range
-
-		/* dcache */
-		.word	cpu_arm7_dcache_invalidate_range
-		.word	cpu_arm7_dcache_clean_range
-		.word	cpu_arm7_dcache_clean_page
-		.word	cpu_arm7_dcache_clean_entry
-
-		/* icache */
-		.word	cpu_arm7_icache_invalidate_range
-		.word	cpu_arm7_icache_invalidate_page
-
-		/* pgtable */
-		.word	cpu_arm7_set_pgd
-		.word	cpu_arm7_set_pmd
-		.word	cpu_arm7_set_pte
-
-		.size	arm7_processor_functions, . - arm7_processor_functions
-
-		.type	cpu_arm6_info, #object
-cpu_arm6_info:
-		.long	cpu_armvlsi_name
-		.long	cpu_arm6_name
-		.size	cpu_arm6_info, . - cpu_arm6_info
-
-		.type	cpu_arm610_info, #object
-cpu_arm610_info:
-		.long	cpu_armvlsi_name
-		.long	cpu_arm610_name
-		.size	cpu_arm610_info, . - cpu_Arm610_info
-
-		.type	cpu_arm7_info, #object
-cpu_arm7_info:
-		.long	cpu_armvlsi_name
-		.long	cpu_arm7_name
-		.size	cpu_arm7_info, . - cpu_arm7_info
-
-		.type	cpu_arm710_info, #object
-cpu_arm710_info:
-		.long	cpu_armvlsi_name
-		.long	cpu_arm710_name
-		.size	cpu_arm710_info, . - cpu_arm710_info
-
-		.type	cpu_arch_name, #object
-cpu_arch_name:	.asciz	"armv3"
-		.size	cpu_arch_name, . - cpu_arch_name
-
-		.type	cpu_elf_name, #object
-cpu_elf_name:	.asciz	"v3"
-		.size	cpu_elf_name, . - cpu_elf_name
-		.align
-
-		.section ".proc.info", #alloc, #execinstr
-
-		.type	__arm6_proc_info, #object
-__arm6_proc_info:
-		.long	0x41560600
-		.long	0xfffffff0
-		.long	0x00000c1e
-		b	__arm6_setup
-		.long	cpu_arch_name
-		.long	cpu_elf_name
-		.long	HWCAP_SWP | HWCAP_26BIT
-		.long	cpu_arm6_info
-		.long	arm6_processor_functions
-		.long	v3_tlb_fns
-		.long	v3_user_fns
-		.size	__arm6_proc_info, . - __arm6_proc_info
-
-		.type	__arm610_proc_info, #object
-__arm610_proc_info:
-		.long	0x41560610
-		.long	0xfffffff0
-		.long	0x00000c1e
-		b	__arm6_setup
-		.long	cpu_arch_name
-		.long	cpu_elf_name
-		.long	HWCAP_SWP | HWCAP_26BIT
-		.long	cpu_arm610_info
-		.long	arm6_processor_functions
-		.long	v3_tlb_fns
-		.long	v3_user_fns
-		.size	__arm610_proc_info, . - __arm610_proc_info
-
-		.type	__arm7_proc_info, #object
-__arm7_proc_info:
-		.long	0x41007000
-		.long	0xffffff00
-		.long	0x00000c1e
-		b	__arm7_setup
-		.long	cpu_arch_name
-		.long	cpu_elf_name
-		.long	HWCAP_SWP | HWCAP_26BIT
-		.long	cpu_arm7_info
-		.long	arm7_processor_functions
-		.long	v3_tlb_fns
-		.long	v3_user_fns
-		.size	__arm7_proc_info, . - __arm7_proc_info
-
-		.type	__arm710_proc_info, #object
-__arm710_proc_info:
-		.long	0x41007100
-		.long	0xfff8ff00
-		.long	0x00000c1e
-		b	__arm7_setup
-		.long	cpu_arch_name
-		.long	cpu_elf_name
-		.long	HWCAP_SWP | HWCAP_26BIT
-		.long	cpu_arm710_info
-		.long	arm7_processor_functions
-		.long	v3_tlb_fns
-		.long	v3_user_fns
-		.size	__arm710_proc_info, . - __arm710_proc_info
diff -Nru a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mm/proc-arm6_7.S	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,504 @@
+/*
+ *  linux/arch/arm/mm/proc-arm6,7.S
+ *
+ *  Copyright (C) 1997-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  These are the low level assembler for performing cache and TLB
+ *  functions on the ARM610 & ARM710.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+
+/*
+ * Function: arm6_7_cache_clean_invalidate_all (void)
+ *	   : arm6_7_cache_clean_invalidate_page (unsigned long address, int size, int flags)
+ *
+ * Params  : address	Area start address
+ *	   : size	size of area
+ *	   : flags	b0 = I cache as well
+ *
+ * Purpose : Flush all cache lines
+ */
+ENTRY(cpu_arm6_cache_clean_invalidate_all)
+ENTRY(cpu_arm7_cache_clean_invalidate_all)
+ENTRY(cpu_arm6_cache_clean_invalidate_range)
+ENTRY(cpu_arm7_cache_clean_invalidate_range)
+ENTRY(cpu_arm6_icache_invalidate_range)
+ENTRY(cpu_arm7_icache_invalidate_range)
+ENTRY(cpu_arm6_icache_invalidate_page)
+ENTRY(cpu_arm7_icache_invalidate_page)
+ENTRY(cpu_arm6_dcache_clean_range)
+ENTRY(cpu_arm7_dcache_clean_range)
+ENTRY(cpu_arm6_dcache_invalidate_range)
+ENTRY(cpu_arm7_dcache_invalidate_range)
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c0, 0		@ flush cache
+ENTRY(cpu_arm6_dcache_clean_page)
+ENTRY(cpu_arm7_dcache_clean_page)
+ENTRY(cpu_arm6_dcache_clean_entry)
+ENTRY(cpu_arm7_dcache_clean_entry)
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_data_abort ()
+ *
+ * Params  : r0 = address of aborted instruction
+ *
+ * Purpose : obtain information about current aborted instruction
+ *
+ * Returns : r0 = address of abort
+ *	   : r1 != 0 if writing
+ *	   : r3 = FSR
+ *	   : sp = pointer to registers
+ */
+
+ENTRY(cpu_arm6_data_abort)
+		ldr	r4, [r0]			@ read instruction causing problem
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
+		and	r2, r4, #14 << 24
+		teq	r2, #8 << 24			@ was it ldm/stm
+		bne	Ldata_simple
+
+Ldata_ldmstm:	tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+		mov	r7, #0x11
+		orr	r7, r7, r7, lsl #8
+		and	r0, r4, r7
+		and	r2, r4, r7, lsl #1
+		add	r0, r0, r2, lsr #1
+		and	r2, r4, r7, lsl #2
+		add	r0, r0, r2, lsr #2
+		and	r2, r4, r7, lsl #3
+		add	r0, r0, r2, lsr #3
+		add	r0, r0, r0, lsr #8
+		add	r0, r0, r0, lsr #4
+		and	r7, r0, #15			@ r7 = no. of registers to transfer.
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]		@ Get register
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r7, lsl #2
+		addeq	r7, r0, r7, lsl #2		@ Do correction (signed)
+Ldata_saver7:	str	r7, [sp, r5, lsr #14]		@ Put register
+Ldata_simple:	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+		mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+		and	r3, r3, #255
+		mov	pc, lr
+
+ENTRY(cpu_arm7_data_abort)
+		ldr	r4, [r0]			@ read instruction causing problem
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
+		and	r2, r4, #15 << 24
+		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
+		movs	pc, lr
+
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_lateldrpostconst		@ ldr	rd, [rn], #m
+		b	Ldata_lateldrpreconst		@ ldr	rd, [rn, #m]	@ RegVal
+		b	Ldata_lateldrpostreg		@ ldr	rd, [rn], rm
+		b	Ldata_lateldrprereg		@ ldr	rd, [rn, rm]
+		b	Ldata_ldmstm			@ ldm*a	rn, <rlist>
+		b	Ldata_ldmstm			@ ldm*b	rn, <rlist>
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_simple			@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
+		b	Ldata_simple			@ ldc	rd, [rn, #m]
+		b	Ldata_unknown
+Ldata_unknown:	@ Part of jumptable
+		mov	r0, r2
+		mov	r1, r4
+		mov	r2, r3
+		bl	baddataabort
+		b	ret_from_exception
+
+Ldata_lateldrpreconst:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostconst:
+		movs	r2, r4, lsl #20			@ Get offset
+		beq	Ldata_simple
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2, lsr #20
+		addeq	r7, r0, r2, lsr #20
+		b	Ldata_saver7
+
+Ldata_lateldrprereg:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostreg:
+		and	r5, r4, #15
+		ldr	r2, [sp, r5, lsl #2]		@ Get Rm
+		mov	r3, r4, lsr #7
+		ands	r3, r3, #31
+		and	r6, r4, #0x70
+		orreq	r6, r6, #8
+		add	pc, pc, r6
+		mov	r0, r0
+
+		mov	r2, r2, lsl r3			@ 0: LSL #!0
+		b	1f
+		b	1f				@ 1: LSL #0
+		mov	r0, r0
+		b	1f				@ 2: MUL?
+		mov	r0, r0
+		b	1f				@ 3: MUL?
+		mov	r0, r0
+		mov	r2, r2, lsr r3			@ 4: LSR #!0
+		b	1f
+		mov	r2, r2, lsr #32			@ 5: LSR #32
+		b	1f
+		b	1f				@ 6: MUL?
+		mov	r0, r0
+		b	1f				@ 7: MUL?
+		mov	r0, r0
+		mov	r2, r2, asr r3			@ 8: ASR #!0
+		b	1f
+		mov	r2, r2, asr #32			@ 9: ASR #32
+		b	1f
+		b	1f				@ A: MUL?
+		mov	r0, r0
+		b	1f				@ B: MUL?
+		mov	r0, r0
+		mov	r2, r2, ror r3			@ C: ROR #!0
+		b	1f
+		mov	r2, r2, rrx			@ D: RRX
+		b	1f
+		mov	r0, r0				@ E: MUL?
+		mov	r0, r0
+		mov	r0, r0				@ F: MUL?
+
+
+1:		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2
+		addeq	r7, r0, r2
+		b	Ldata_saver7
+
+/*
+ * Function: arm6_7_check_bugs (void)
+ *	   : arm6_7_proc_init (void)
+ *	   : arm6_7_proc_fin (void)
+ *
+ * Notes   : This processor does not require these
+ */
+ENTRY(cpu_arm6_check_bugs)
+ENTRY(cpu_arm7_check_bugs)
+		mrs	ip, cpsr
+		bic	ip, ip, #PSR_F_BIT
+		msr	cpsr, ip
+		mov	pc, lr
+
+ENTRY(cpu_arm6_proc_init)
+ENTRY(cpu_arm7_proc_init)
+		mov	pc, lr
+
+ENTRY(cpu_arm6_proc_fin)
+ENTRY(cpu_arm7_proc_fin)
+		mov	r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+		msr	cpsr_c, r0
+		mov	r0, #0x31			@ ....S..DP...M
+		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+		mov	pc, lr
+
+ENTRY(cpu_arm6_do_idle)
+ENTRY(cpu_arm7_do_idle)
+		mov	r0, #-EINVAL
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_set_pgd(unsigned long pgd_phys)
+ * Params  : pgd_phys	Physical address of page table
+ * Purpose : Perform a task switch, saving the old processes state, and restoring
+ *	     the new.
+ */
+ENTRY(cpu_arm6_set_pgd)
+ENTRY(cpu_arm7_set_pgd)
+		mov	r1, #0
+		mcr	p15, 0, r1, c7, c0, 0		@ flush cache
+		mcr	p15, 0, r0, c2, c0, 0		@ update page table ptr
+		mcr	p15, 0, r1, c5, c0, 0		@ flush TLBs
+		mov	pc, lr
+
+/*
+ * Function: arm6_set_pmd ()
+ *
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ *
+ * Purpose : Set a PMD and flush it out of any WB cache
+ */
+ENTRY(cpu_arm6_set_pmd)
+		and	r2, r1, #11
+		teq	r2, #1
+		teqne	r2, #9
+		teqne	r2, #10
+		orreq	r1, r1, #16			@ Updatable = 1 if Page table/Cacheable section
+		str	r1, [r0]
+		mov	pc, lr
+
+/*
+ * Function: arm7_set_pmd ()
+ *
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ *
+ * Purpose : Set a PMD and flush it out of any WB cache
+ */
+ENTRY(cpu_arm7_set_pmd)
+		tst	r1, #3
+		orrne	r1, r1, #16			@ Updatable bit is always set on ARM7
+		str	r1, [r0]
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+		.align	5
+ENTRY(cpu_arm6_set_pte)
+ENTRY(cpu_arm7_set_pte)
+		tst	r0, #2048
+		streq	r0, [r0, -r0]			@ BUG_ON
+		str	r1, [r0], #-2048		@ linux version
+
+		eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+		bic	r2, r1, #0xff0
+		bic	r2, r2, #3
+		orr	r2, r2, #HPTE_TYPE_SMALL
+
+		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+		orrne	r2, r2, #HPTE_AP_READ
+
+		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+		orreq	r2, r2, #HPTE_AP_WRITE
+
+		tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young
+		movne	r2, #0
+
+		str	r2, [r0]			@ hardware version
+		mov	pc, lr
+
+/*
+ * Function: _arm6_7_reset
+ * Params  : r0 = address to jump to
+ * Notes   : This sets up everything for a reset
+ */
+ENTRY(cpu_arm6_reset)
+ENTRY(cpu_arm7_reset)
+		mov	r1, #0
+		mcr	p15, 0, r1, c7, c0, 0		@ flush cache
+		mcr	p15, 0, r1, c5, c0, 0		@ flush TLB
+		mov	r1, #0x30
+		mcr	p15, 0, r1, c1, c0, 0		@ turn off MMU etc
+		mov	pc, r0
+
+cpu_armvlsi_name:
+		.asciz	"ARM/VLSI"
+cpu_arm6_name:	.asciz	"ARM 6"
+cpu_arm610_name:
+		.asciz	"ARM 610"
+cpu_arm7_name:	.asciz	"ARM 7"
+cpu_arm710_name:
+		.asciz	"ARM 710"
+		.align
+
+		.section ".text.init", #alloc, #execinstr
+
+__arm6_setup:	mov	r0, #0
+		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
+		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
+		mcr	p15, 0, r4, c2, c0		@ load page table pointer
+		mov	r0, #0x1f			@ Domains 0, 1 = client
+		mcr	p15, 0, r0, c3, c0		@ load domain access register
+		mov	r0, #0x3d			@ . ..RS BLDP WCAM
+		orr	r0, r0, #0x100			@ . ..01 0011 1101
+		mov	pc, lr
+
+__arm7_setup:	mov	r0, #0
+		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
+		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
+		mcr	p15, 0, r4, c2, c0		@ load page table pointer
+		mov	r0, #0x1f			@ Domains 0, 1 = client
+		mcr	p15, 0, r0, c3, c0		@ load domain access register
+		mov	r0, #0x7d			@ . ..RS BLDP WCAM
+		orr	r0, r0, #0x100			@ . ..01 0111 1101
+		mov	pc, lr
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.type	arm6_processor_functions, #object
+ENTRY(arm6_processor_functions)
+		.word	cpu_arm6_data_abort
+		.word	cpu_arm6_check_bugs
+		.word	cpu_arm6_proc_init
+		.word	cpu_arm6_proc_fin
+		.word	cpu_arm6_reset
+		.word	cpu_arm6_do_idle
+
+		/* cache */
+		.word	cpu_arm6_cache_clean_invalidate_all
+		.word	cpu_arm6_cache_clean_invalidate_range
+
+		/* dcache */
+		.word	cpu_arm6_dcache_invalidate_range
+		.word	cpu_arm6_dcache_clean_range
+		.word	cpu_arm6_dcache_clean_page
+		.word	cpu_arm6_dcache_clean_entry
+
+		/* icache */
+		.word	cpu_arm6_icache_invalidate_range
+		.word	cpu_arm6_icache_invalidate_page
+
+		/* pgtable */
+		.word	cpu_arm6_set_pgd
+		.word	cpu_arm6_set_pmd
+		.word	cpu_arm6_set_pte
+
+		.size	arm6_processor_functions, . - arm6_processor_functions
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.type	arm7_processor_functions, #object
+ENTRY(arm7_processor_functions)
+		.word	cpu_arm7_data_abort
+		.word	cpu_arm7_check_bugs
+		.word	cpu_arm7_proc_init
+		.word	cpu_arm7_proc_fin
+		.word	cpu_arm7_reset
+		.word	cpu_arm7_do_idle
+
+		/* cache */
+		.word	cpu_arm7_cache_clean_invalidate_all
+		.word	cpu_arm7_cache_clean_invalidate_range
+
+		/* dcache */
+		.word	cpu_arm7_dcache_invalidate_range
+		.word	cpu_arm7_dcache_clean_range
+		.word	cpu_arm7_dcache_clean_page
+		.word	cpu_arm7_dcache_clean_entry
+
+		/* icache */
+		.word	cpu_arm7_icache_invalidate_range
+		.word	cpu_arm7_icache_invalidate_page
+
+		/* pgtable */
+		.word	cpu_arm7_set_pgd
+		.word	cpu_arm7_set_pmd
+		.word	cpu_arm7_set_pte
+
+		.size	arm7_processor_functions, . - arm7_processor_functions
+
+		.type	cpu_arm6_info, #object
+cpu_arm6_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm6_name
+		.size	cpu_arm6_info, . - cpu_arm6_info
+
+		.type	cpu_arm610_info, #object
+cpu_arm610_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm610_name
+		.size	cpu_arm610_info, . - cpu_Arm610_info
+
+		.type	cpu_arm7_info, #object
+cpu_arm7_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm7_name
+		.size	cpu_arm7_info, . - cpu_arm7_info
+
+		.type	cpu_arm710_info, #object
+cpu_arm710_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm710_name
+		.size	cpu_arm710_info, . - cpu_arm710_info
+
+		.type	cpu_arch_name, #object
+cpu_arch_name:	.asciz	"armv3"
+		.size	cpu_arch_name, . - cpu_arch_name
+
+		.type	cpu_elf_name, #object
+cpu_elf_name:	.asciz	"v3"
+		.size	cpu_elf_name, . - cpu_elf_name
+		.align
+
+		.section ".proc.info", #alloc, #execinstr
+
+		.type	__arm6_proc_info, #object
+__arm6_proc_info:
+		.long	0x41560600
+		.long	0xfffffff0
+		.long	0x00000c1e
+		b	__arm6_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm6_info
+		.long	arm6_processor_functions
+		.long	v3_tlb_fns
+		.long	v3_user_fns
+		.size	__arm6_proc_info, . - __arm6_proc_info
+
+		.type	__arm610_proc_info, #object
+__arm610_proc_info:
+		.long	0x41560610
+		.long	0xfffffff0
+		.long	0x00000c1e
+		b	__arm6_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm610_info
+		.long	arm6_processor_functions
+		.long	v3_tlb_fns
+		.long	v3_user_fns
+		.size	__arm610_proc_info, . - __arm610_proc_info
+
+		.type	__arm7_proc_info, #object
+__arm7_proc_info:
+		.long	0x41007000
+		.long	0xffffff00
+		.long	0x00000c1e
+		b	__arm7_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm7_info
+		.long	arm7_processor_functions
+		.long	v3_tlb_fns
+		.long	v3_user_fns
+		.size	__arm7_proc_info, . - __arm7_proc_info
+
+		.type	__arm710_proc_info, #object
+__arm710_proc_info:
+		.long	0x41007100
+		.long	0xfff8ff00
+		.long	0x00000c1e
+		b	__arm7_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm710_info
+		.long	arm7_processor_functions
+		.long	v3_tlb_fns
+		.long	v3_user_fns
+		.size	__arm710_proc_info, . - __arm710_proc_info
diff -Nru a/arch/cris/drivers/ide.c b/arch/cris/drivers/ide.c
--- a/arch/cris/drivers/ide.c	Sun Jun 16 19:31:39 2002
+++ b/arch/cris/drivers/ide.c	Sun Jun 16 19:31:39 2002
@@ -791,7 +791,7 @@
 
 		if(!atapi) {
 			/* set the irq handler which will finish the request when DMA is done */
-			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
+			ata_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
 
 			/* issue cmd to drive */
 			OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
@@ -802,10 +802,10 @@
 		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
 
 		/* initiate a multi word dma read using DMA handshaking */
-		
+
 		*R_ATA_TRANSFER_CNT =
 			IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
-		
+
 		*R_ATA_CTRL_DATA =
 			IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
 			IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
@@ -831,7 +831,7 @@
 
 		if(!atapi) {
 			/* set the irq handler which will finish the request when DMA is done */
-			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
+			ata_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
 
 			/* issue cmd to drive */
 			OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
diff -Nru a/arch/i386/Config.help b/arch/i386/Config.help
--- a/arch/i386/Config.help	Sun Jun 16 19:31:39 2002
+++ b/arch/i386/Config.help	Sun Jun 16 19:31:39 2002
@@ -944,10 +944,12 @@
 Software Suspend
 CONFIG_SOFTWARE_SUSPEND
   Enable the possibilty of suspendig machine. It doesn't need APM.
-  You may suspend your machine by either pressing Sysrq-d or with
-  'swsusp' or 'shutdown -z <time>' (patch for sysvinit needed). It
-  creates an image which is saved in your active swaps. By the next
-  booting the kernel detects the saved image, restores the memory from
+  You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 
+  (patch for sysvinit needed). 
+
+  It creates an image which is saved in your active swaps. By the next
+  booting the, pass 'resume=/path/to/your/swap/file' and kernel will 
+  detect the saved image, restore the memory from
   it and then it continues to run as before you've suspended.
   If you don't want the previous state to continue use the 'noresume'
   kernel option. However note that your partitions will be fsck'd and
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c	Sun Jun 16 19:31:39 2002
+++ b/arch/i386/kernel/apm.c	Sun Jun 16 19:31:39 2002
@@ -848,6 +848,7 @@
 			case 1: apm_idle_done = 1;
 				break;
 			default: /* BIOS refused */
+				;
 			}
 		}
 		if (original_pm_idle)
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	Sun Jun 16 19:31:40 2002
+++ b/arch/i386/kernel/dmi_scan.c	Sun Jun 16 19:31:40 2002
@@ -185,28 +185,6 @@
 #define NO_MATCH	{ NONE, NULL}
 #define MATCH(a,b)	{ a, b }
 
-/*
- *	We have problems with IDE DMA on some platforms. In paticular the
- *	KT7 series. On these it seems the newer BIOS has fixed them. The
- *	rule needs to be improved to match specific BIOS revisions with
- *	corruption problems
- */ 
- 
-#if 0
-static __init int disable_ide_dma(struct dmi_blacklist *d)
-{
-#ifdef CONFIG_BLK_DEV_IDE
-	extern int noautodma;
-	if(noautodma == 0)
-	{
-		noautodma = 1;
-		printk(KERN_INFO "%s series board detected. Disabling IDE DMA.\n", d->ident);
-	}
-#endif	
-	return 0;
-}
-#endif
-
 /* 
  * Reboot options and system auto-detection code provided by
  * Dell Computer Corporation so their systems "just work". :-)
@@ -511,12 +489,6 @@
  */
  
 static __initdata struct dmi_blacklist dmi_blacklist[]={
-#if 0
-	{ disable_ide_dma, "KT7", {	/* Overbroad right now - kill DMA on problem KT7 boards */
-			MATCH(DMI_PRODUCT_NAME, "KT7-RAID"),
-			NO_MATCH, NO_MATCH, NO_MATCH
-			} },
-#endif			
 	{ broken_ps2_resume, "Dell Latitude C600", {	/* Handle problems with APM on the C600 */
 			MATCH(DMI_SYS_VENDOR, "Dell"),
 			MATCH(DMI_PRODUCT_NAME, "Latitude C600"),
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Sun Jun 16 19:31:40 2002
+++ b/arch/i386/kernel/entry.S	Sun Jun 16 19:31:40 2002
@@ -70,34 +70,15 @@
 NT_MASK		= 0x00004000
 VM_MASK		= 0x00020000
 
-/*
- * These are offsets into the irq_stat structure
- * There is one per cpu and it is aligned to 32
- * byte boundry (we put that here as a shift count)
- */
-irq_array_shift	= CONFIG_X86_L1_CACHE_SHIFT
-local_irq_count	= 4
-local_bh_count	= 8
-
-#ifdef CONFIG_SMP
-#define GET_CPU_IDX \
-		movl TI_CPU(%ebx), %eax;  \
-		shll $irq_array_shift, %eax
-#define CPU_IDX (,%eax)
-#else
-#define GET_CPU_IDX
-#define CPU_IDX
-#endif
-
 #ifdef CONFIG_PREEMPT
-#define preempt_stop cli
-#define INC_PRE_COUNT(reg) incl TI_PRE_COUNT(reg);
-#define DEC_PRE_COUNT(reg) decl TI_PRE_COUNT(reg);
+#define preempt_stop		cli
+#define INC_PRE_COUNT(reg)	incl TI_PRE_COUNT(reg);
+#define DEC_PRE_COUNT(reg)	decl TI_PRE_COUNT(reg);
 #else
 #define preempt_stop
 #define INC_PRE_COUNT(reg)
 #define DEC_PRE_COUNT(reg)
-#define resume_kernel restore_all
+#define resume_kernel		restore_all
 #endif
 
 #define SAVE_ALL \
@@ -193,6 +174,7 @@
 
 ENTRY(ret_from_fork)
 #if CONFIG_SMP || CONFIG_PREEMPT
+	# NOTE: this function takes a parameter but it's unused on x86.
 	call schedule_tail
 #endif
 	GET_THREAD_INFO(%ebx)
@@ -227,20 +209,20 @@
 
 #ifdef CONFIG_PREEMPT
 ENTRY(resume_kernel)
-	cmpl $0,TI_PRE_COUNT(%ebx)
+	cmpl $0,TI_PRE_COUNT(%ebx)	# non-zero preempt_count ?
 	jnz restore_all
-	movl TI_FLAGS(%ebx), %ecx
+need_resched:
+	movl TI_FLAGS(%ebx), %ecx	# need_resched set ?
 	testb $_TIF_NEED_RESCHED, %cl
 	jz restore_all
-	GET_CPU_IDX
-	movl irq_stat+local_bh_count CPU_IDX, %ecx
-	addl irq_stat+local_irq_count CPU_IDX, %ecx
-	jnz restore_all
+	testl $IF_MASK,EFLAGS(%esp)     # interrupts off (execption path) ?
+	jz restore_all
 	movl $PREEMPT_ACTIVE,TI_PRE_COUNT(%ebx)
 	sti
 	call schedule
 	movl $0,TI_PRE_COUNT(%ebx) 
-	jmp restore_all
+	cli
+	jmp need_resched
 #endif
 
 	# system call handler stub
diff -Nru a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
--- a/arch/i386/kernel/i387.c	Sun Jun 16 19:31:41 2002
+++ b/arch/i386/kernel/i387.c	Sun Jun 16 19:31:41 2002
@@ -357,14 +357,14 @@
 
 static inline int restore_i387_fxsave( struct _fpstate *buf )
 {
+	int err;
 	struct task_struct *tsk = current;
 	clear_fpu( tsk );
-	if ( __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
-			       sizeof(struct i387_fxsave_struct) ) )
-		return 1;
+	err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
+				sizeof(struct i387_fxsave_struct) );
 	/* mxcsr bit 6 and 31-16 must be zero for security reasons */
 	tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
-	return convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
+	return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
 }
 
 int restore_i387( struct _fpstate *buf )
diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
--- a/arch/i386/kernel/i8259.c	Sun Jun 16 19:31:41 2002
+++ b/arch/i386/kernel/i8259.c	Sun Jun 16 19:31:41 2002
@@ -238,9 +238,21 @@
 	}
 }
 
+static int i8259A_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON)
+		init_8259A(0);
+	return 0;
+}
+
+static struct device_driver driver_i8259A = {
+	resume:		i8259A_resume,
+};
+
 static struct device device_i8259A = {
 	name:	       	"i8259A",
 	bus_id:		"0020",
+	driver:		&driver_i8259A,
 };
 
 static int __init init_8259A_devicefs(void)
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Sun Jun 16 19:31:40 2002
+++ b/arch/i386/kernel/io_apic.c	Sun Jun 16 19:31:40 2002
@@ -207,7 +207,7 @@
 } ____cacheline_aligned irq_balance_t;
 
 static irq_balance_t irq_balance[NR_IRQS] __cacheline_aligned
-			= { [ 0 ... NR_IRQS-1 ] = { 1, 0 } };
+			= { [ 0 ... NR_IRQS-1 ] = { 0, 0 } };
 
 extern unsigned long irq_affinity [NR_IRQS];
 
@@ -251,7 +251,7 @@
 	irq_balance_t *entry = irq_balance + irq;
 	unsigned long now = jiffies;
 
-	if (unlikely(entry->timestamp != now)) {
+	if (entry->timestamp != now) {
 		unsigned long allowed_mask;
 		int random_number;
 
diff -Nru a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c
--- a/arch/i386/kernel/ioport.c	Sun Jun 16 19:31:40 2002
+++ b/arch/i386/kernel/ioport.c	Sun Jun 16 19:31:40 2002
@@ -10,10 +10,10 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
+#include <linux/slab.h>
 
 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
 static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
@@ -66,12 +66,16 @@
 	 * IO bitmap up. ioperm() is much less timing critical than clone(),
 	 * this is why we delay this operation until now:
 	 */
-	if (!t->ioperm) {
+	if (!t->ts_io_bitmap) {
+		unsigned long *bitmap;
+		bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+		if (!bitmap)
+			return -ENOMEM;
 		/*
 		 * just in case ...
 		 */
-		memset(t->io_bitmap,0xff,(IO_BITMAP_SIZE+1)*4);
-		t->ioperm = 1;
+		memset(bitmap, 0xff, IO_BITMAP_BYTES);
+		t->ts_io_bitmap = bitmap;
 		/*
 		 * this activates it in the TSS
 		 */
@@ -81,7 +85,7 @@
 	/*
 	 * do it in the per-thread copy and in the TSS ...
 	 */
-	set_bitmap(t->io_bitmap, from, num, !turn_on);
+	set_bitmap(t->ts_io_bitmap, from, num, !turn_on);
 	set_bitmap(tss->io_bitmap, from, num, !turn_on);
 
 	return 0;
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c	Sun Jun 16 19:31:40 2002
+++ b/arch/i386/kernel/mpparse.c	Sun Jun 16 19:31:40 2002
@@ -89,46 +89,6 @@
 }
 
 /*
- * Processor encoding in an MP configuration block
- */
-
-static char __init *mpc_family(int family,int model)
-{
-	static char n[32];
-	static char *model_defs[]=
-	{
-		"80486DX","80486DX",
-		"80486SX","80486DX/2 or 80487",
-		"80486SL","80486SX/2",
-		"Unknown","80486DX/2-WB",
-		"80486DX/4","80486DX/4-WB"
-	};
-
-	switch (family) {
-		case 0x04:
-			if (model < 10)
-				return model_defs[model];
-			break;
-
-		case 0x05:
-			return("Pentium(tm)");
-
-		case 0x06:
-			return("Pentium(tm) Pro");
-
-		case 0x0F:
-			if (model == 0x00)
-				return("Pentium 4(tm)");
-			if (model == 0x02)
-				return("XEON(tm)");
-			if (model == 0x0F)
-				return("Special controller");
-	}
-	sprintf(n,"Unknown CPU [%d:%d]",family, model);
-	return n;
-}
-
-/* 
  * Have to match translation table entries to main table entries by counter
  * hence the mpc_record variable .... can't see a less disgusting way of
  * doing this ....
@@ -149,16 +109,16 @@
 		quad = translation_table[mpc_record]->trans_quad;
 		logical_apicid = (quad << 4) + 
 			(m->mpc_apicid ? m->mpc_apicid << 1 : 1);
-		printk("Processor #%d %s APIC version %d (quad %d, apic %d)\n",
+		printk("Processor #%d %ld:%ld APIC version %d (quad %d, apic %d)\n",
 			m->mpc_apicid,
-			mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
-				   (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
+		        (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8,
+			(m->mpc_cpufeature & CPU_MODEL_MASK)>>4,
 			m->mpc_apicver, quad, logical_apicid);
 	} else {
-		printk("Processor #%d %s APIC version %d\n",
+		printk("Processor #%d %ld:%ld APIC version %d\n",
 			m->mpc_apicid,
-			mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
-				   (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
+			(m->mpc_cpufeature & CPU_FAMILY_MASK)>>8,
+			(m->mpc_cpufeature & CPU_MODEL_MASK)>>4,
 			m->mpc_apicver);
 	}
 
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Sun Jun 16 19:31:38 2002
+++ b/arch/i386/kernel/process.c	Sun Jun 16 19:31:38 2002
@@ -509,7 +509,13 @@
  */
 void exit_thread(void)
 {
-	/* nothing to do ... */
+	struct task_struct *tsk = current;
+
+	/* The process may have allocated an io port bitmap... nuke it. */
+	if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
+		kfree(tsk->thread.ts_io_bitmap);
+		tsk->thread.ts_io_bitmap = NULL;
+	}
 }
 
 void flush_thread(void)
@@ -549,6 +555,7 @@
 	struct task_struct * p, struct pt_regs * regs)
 {
 	struct pt_regs * childregs;
+	struct task_struct *tsk;
 
 	childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
 	struct_cpy(childregs, regs);
@@ -563,8 +570,17 @@
 	savesegment(fs,p->thread.fs);
 	savesegment(gs,p->thread.gs);
 
-	unlazy_fpu(current);
-	struct_cpy(&p->thread.i387, &current->thread.i387);
+	tsk = current;
+	unlazy_fpu(tsk);
+	struct_cpy(&p->thread.i387, &tsk->thread.i387);
+
+	if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
+		p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+		if (!p->thread.ts_io_bitmap)
+			return -ENOMEM;
+		memcpy(p->thread.ts_io_bitmap, tsk->thread.ts_io_bitmap,
+			IO_BITMAP_BYTES);
+	}
 
 	return 0;
 }
@@ -685,8 +701,8 @@
 		loaddebug(next, 7);
 	}
 
-	if (unlikely(prev->ioperm || next->ioperm)) {
-		if (next->ioperm) {
+	if (unlikely(prev->ts_io_bitmap || next->ts_io_bitmap)) {
+		if (next->ts_io_bitmap) {
 			/*
 			 * 4 cachelines copy ... not good, but not that
 			 * bad either. Anyone got something better?
@@ -695,8 +711,8 @@
 			 * and playing VM tricks to switch the IO bitmap
 			 * is not really acceptable.]
 			 */
-			memcpy(tss->io_bitmap, next->io_bitmap,
-				 IO_BITMAP_SIZE*sizeof(unsigned long));
+			memcpy(tss->io_bitmap, next->ts_io_bitmap,
+				IO_BITMAP_BYTES);
 			tss->bitmap = IO_BITMAP_OFFSET;
 		} else
 			/*
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/i386/kernel/setup.c	Sun Jun 16 19:31:40 2002
@@ -32,6 +32,7 @@
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/console.h>
+#include <linux/root_dev.h>
 #include <linux/highmem.h>
 #include <asm/e820.h>
 #include <asm/mpspec.h>
@@ -602,7 +603,7 @@
 	visws_get_board_type_and_rev();
 #endif
 
- 	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
+ 	ROOT_DEV = ORIG_ROOT_DEV;
  	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
 	apm_info.bios = APM_BIOS_INFO;
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Sun Jun 16 19:31:40 2002
+++ b/arch/i386/kernel/smpboot.c	Sun Jun 16 19:31:40 2002
@@ -189,10 +189,10 @@
 		/* 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:
 
+valid_k7:
+	;
 }
 
 /*
diff -Nru a/arch/i386/kernel/suspend.c b/arch/i386/kernel/suspend.c
--- a/arch/i386/kernel/suspend.c	Sun Jun 16 19:31:41 2002
+++ b/arch/i386/kernel/suspend.c	Sun Jun 16 19:31:41 2002
@@ -4,9 +4,9 @@
  * Distribute under GPLv2
  *
  * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
+ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
  */
 
-#define ACPI_C
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -26,7 +26,6 @@
 #include <asm/acpi.h>
 #include <asm/tlbflush.h>
 
-
 static struct saved_context saved_context;
 
 /*
@@ -229,6 +228,7 @@
         kernel_fpu_end();
 }
 
+#ifdef CONFIG_SOFTWARE_SUSPEND
 /* Local variables for do_magic */
 static int loop __nosavedata = 0;
 static int loop2 __nosavedata = 0;
@@ -300,3 +300,4 @@
 
 	do_magic_resume_2();
 }
+#endif
diff -Nru a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
--- a/arch/ia64/dig/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ia64/dig/setup.c	Sun Jun 16 19:31:40 2002
@@ -19,6 +19,7 @@
 #include <linux/console.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
+#include <linux/root_dev.h>
 
 #include <asm/io.h>
 #include <asm/machvec.h>
@@ -44,7 +45,7 @@
 	 * is physical disk 1 partition 1 and the Linux root disk is
 	 * physical disk 1 partition 2.
 	 */
-	ROOT_DEV = to_kdev_t(0x0802);		/* default to second partition on first drive */
+	ROOT_DEV = Root_SDA2;		/* default to second partition on first drive */
 
 #ifdef CONFIG_SMP
 	init_smp_config();
diff -Nru a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c
--- a/arch/ia64/hp/sim/hpsim_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ia64/hp/sim/hpsim_setup.c	Sun Jun 16 19:31:40 2002
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/kdev_t.h>
 #include <linux/console.h>
+#include <linux/root_dev.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -52,7 +53,7 @@
 void __init
 hpsim_setup (char **cmdline_p)
 {
-	ROOT_DEV = to_kdev_t(0x0801);		/* default to first SCSI drive */
+	ROOT_DEV = Root_SDA1;		/* default to first SCSI drive */
 
 	register_console (&hpsim_cons);
 }
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ia64/sn/kernel/setup.c	Sun Jun 16 19:31:40 2002
@@ -47,6 +47,7 @@
 #include <linux/bootmem.h>
 #include <linux/mmzone.h>
 #include <linux/interrupt.h>
+#include <linux/root_dev.h>
 
 #include <asm/io.h>
 #include <asm/sal.h>
@@ -259,7 +260,7 @@
 	 * we set the default root device to /dev/hda
 	 * to make simulation easy
 	 */
-	ROOT_DEV = to_kdev_t(0x0301);
+	ROOT_DEV = Root_HDA1;
 
 	/*
 	 * Create the PDAs and NODEPDAs for all the cpus.
diff -Nru a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
--- a/arch/m68k/atari/stram.c	Sun Jun 16 19:31:39 2002
+++ b/arch/m68k/atari/stram.c	Sun Jun 16 19:31:39 2002
@@ -31,13 +31,13 @@
 #include <asm/io.h>
 #include <asm/semaphore.h>
 
+#include <linux/swapops.h>
 
 #ifdef CONFIG_STRAM_SWAP
 #define MAJOR_NR    Z2RAM_MAJOR
 #define do_z2_request do_stram_request
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
-#undef DEVICE_NAME
-#define DEVICE_NAME	"stram"
 #endif
 
 #undef DEBUG
@@ -984,35 +984,35 @@
 	unsigned long len;
 
 	while (1) {
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		struct request *req;
+		if (blk_queue_empty(QUEUE))
 			return;
-		}
 
-		start = swap_start + (CURRENT->sector << 9);
-		len   = CURRENT->current_nr_sectors << 9;
+		req = CURRENT;
+		start = swap_start + (req->sector << 9);
+		len   = req->current_nr_sectors << 9;
 		if ((start + len) > swap_end) {
 			printk( KERN_ERR "stram: bad access beyond end of device: "
 					"block=%ld, count=%ld\n",
-					CURRENT->sector,
-					CURRENT->current_nr_sectors );
-			end_request( 0 );
+					req->sector,
+					req->current_nr_sectors );
+			end_request(req, 0);
 			continue;
 		}
 
-		if (CURRENT->cmd == READ) {
-			memcpy(CURRENT->buffer, start, len);
+		if (req->cmd == READ) {
+			memcpy(req->buffer, start, len);
 #ifdef DO_PROC
 			stat_swap_read += N_PAGES(len);
 #endif
 		}
 		else {
-			memcpy(start, CURRENT->buffer, len);
+			memcpy(start, req->buffer, len);
 #ifdef DO_PROC
 			stat_swap_write += N_PAGES(len);
 #endif
 		}
-		end_request( 1 );
+		end_request(req, 1);
 	}
 }
 
diff -Nru a/arch/mips/au1000/pb1000/setup.c b/arch/mips/au1000/pb1000/setup.c
--- a/arch/mips/au1000/pb1000/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/mips/au1000/pb1000/setup.c	Sun Jun 16 19:31:40 2002
@@ -33,6 +33,7 @@
 #include <linux/ioport.h>
 #include <linux/console.h>
 #include <linux/mc146818rtc.h>
+#include <linux/root_dev.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -104,7 +105,7 @@
 	ioport_resource.end = au1000_resources.lcd.end;
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	ROOT_DEV = Root_RAM0;
 #endif
 
 	outl(PC_CNTRL_E0 | PC_CNTRL_EN0 | PC_CNTRL_EN0, PC_COUNTER_CNTRL);
diff -Nru a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c
--- a/arch/mips/ddb5xxx/ddb5477/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/mips/ddb5xxx/ddb5477/setup.c	Sun Jun 16 19:31:40 2002
@@ -23,9 +23,10 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
-#include <linux/fs.h>		/* for ROOT_DEV */
+#include <linux/fs.h>
 #include <linux/ioport.h>
 #include <linux/param.h>	/* for HZ */
+#include <linux/root_dev.h>
 
 #include <asm/addrspace.h>
 #include <asm/time.h>
@@ -152,7 +153,7 @@
 	ddb5477_board_init();
 
 #if defined(CONFIG_BLK_DEV_INITRD)
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	ROOT_DEV = Root_RAM0;
 	initrd_start = (unsigned long)&__rd_start;
 	initrd_end = (unsigned long)&__rd_end;
 #endif
diff -Nru a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
--- a/arch/mips/ite-boards/generic/it8172_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/mips/ite-boards/generic/it8172_setup.c	Sun Jun 16 19:31:40 2002
@@ -34,6 +34,7 @@
 #include <linux/console.h>
 #include <linux/mc146818rtc.h>
 #include <linux/serial_reg.h>
+#include <linux/root_dev.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -149,7 +150,7 @@
 #endif
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	ROOT_DEV = Root_RAM0;
 #endif
 
 	/*
diff -Nru a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
--- a/arch/mips/kernel/setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/mips/kernel/setup.c	Sun Jun 16 19:31:39 2002
@@ -29,6 +29,7 @@
 #include <linux/blk.h>
 #include <linux/ide.h>
 #include <linux/timex.h>
+#include <linux/root_dev.h>
 
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
@@ -724,7 +725,7 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Board specific code should have set up initrd_start and initrd_end */
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	ROOT_DEV = Root_RAM0;
 	if( __rd_start != __rd_end ) {
 		initrd_start = (unsigned long)&__rd_start;
 		initrd_end = (unsigned long)&__rd_end;
diff -Nru a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
--- a/arch/parisc/hpux/sys_hpux.c	Sun Jun 16 19:31:40 2002
+++ b/arch/parisc/hpux/sys_hpux.c	Sun Jun 16 19:31:40 2002
@@ -107,9 +107,7 @@
 	struct statfs sbuf;
 	int err = -EINVAL;
 
-	lock_kernel();
-	s = get_super(to_kdev_t(dev));
-	unlock_kernel();
+	s = user_get_super(dev);
 	if (s == NULL)
 		goto out;
 	err = vfs_statfs(s, &sbuf);
diff -Nru a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c
--- a/arch/ppc/kernel/m8xx_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/kernel/m8xx_setup.c	Sun Jun 16 19:31:40 2002
@@ -34,6 +34,7 @@
 #include <linux/ioport.h>
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/mmu.h>
 #include <asm/processor.h>
@@ -76,12 +77,12 @@
 #endif
 
 #ifdef notdef
-	ROOT_DEV = to_kdev_t(0x0301); /* hda1 */
+	ROOT_DEV = Root_HDA1; /* hda1 */
 #endif
 
 #ifdef CONFIG_BLK_DEV_INITRD
 #if 0
-	ROOT_DEV = to_kdev_t(0x0200); /* floppy */
+	ROOT_DEV = Root_FD0; /* floppy */
 	rd_prompt = 1;
 	rd_doload = 1;
 	rd_image_start = 0;
diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
--- a/arch/ppc/kernel/ppc_ksyms.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc/kernel/ppc_ksyms.c	Sun Jun 16 19:31:41 2002
@@ -217,7 +217,7 @@
 EXPORT_SYMBOL(__global_sti);
 EXPORT_SYMBOL(__global_save_flags);
 EXPORT_SYMBOL(__global_restore_flags);
-#ifdef SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 EXPORT_SYMBOL(_raw_spin_lock);
 EXPORT_SYMBOL(_raw_spin_unlock);
 EXPORT_SYMBOL(_raw_spin_trylock);
diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
--- a/arch/ppc/kernel/setup.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc/kernel/setup.c	Sun Jun 16 19:31:41 2002
@@ -17,6 +17,7 @@
 #include <linux/tty.h>
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/residual.h>
 #include <asm/io.h>
@@ -431,7 +432,7 @@
 				r3 += KERNELBASE;
 			initrd_start = r3;
 			initrd_end = r3 + r4;
-			ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
+			ROOT_DEV = Root_RAM0;
 			initrd_below_start_ok = 1;
 		}
 #endif
diff -Nru a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c
--- a/arch/ppc/lib/locks.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc/lib/locks.c	Sun Jun 16 19:31:39 2002
@@ -16,7 +16,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#ifdef SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 
 #undef INIT_STUCK
 #define INIT_STUCK 200000000 /*0xffffffff*/
diff -Nru a/arch/ppc/platforms/adir_setup.c b/arch/ppc/platforms/adir_setup.c
--- a/arch/ppc/platforms/adir_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/adir_setup.c	Sun Jun 16 19:31:40 2002
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -111,13 +112,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0801);	/* /dev/sda1 */
+		ROOT_DEV = Root_SDA1;
 #endif
 
 	/* Identify the system */
diff -Nru a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
--- a/arch/ppc/platforms/chrp_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/chrp_setup.c	Sun Jun 16 19:31:40 2002
@@ -38,6 +38,7 @@
 #include <linux/irq.h>
 #include <linux/console.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -232,10 +233,10 @@
 	initrd_below_start_ok = 1;
 	
 	if (initrd_start)
-		ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
-		ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
+		ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
 
 	/* Lookup PCI host bridges */
 	chrp_find_bridges();
diff -Nru a/arch/ppc/platforms/ev64260_setup.c b/arch/ppc/platforms/ev64260_setup.c
--- a/arch/ppc/platforms/ev64260_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/ev64260_setup.c	Sun Jun 16 19:31:40 2002
@@ -33,6 +33,7 @@
 #include <linux/irq.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 #if	!defined(CONFIG_GT64260_CONSOLE)
 #include <linux/serial.h>
 #endif
@@ -195,13 +196,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef	CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802);	/* /dev/sda2 SCSI disk */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 	if ( ppc_md.progress )
diff -Nru a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
--- a/arch/ppc/platforms/gemini_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/gemini_setup.c	Sun Jun 16 19:31:40 2002
@@ -26,6 +26,7 @@
 #include <linux/console.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -174,10 +175,10 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* bootable off CDROM */
 	if (initrd_start)
-		ROOT_DEV = MKDEV(SCSI_CDROM_MAJOR, 0);
+		ROOT_DEV = Root_SR0;
 	else
 #endif
-		ROOT_DEV = to_kdev_t(0x0801);
+		ROOT_DEV = Root_SDA1;
 
 	/* nothing but serial consoles... */
 	sprintf(cmd_line, "%s console=ttyS0", cmd_line);
diff -Nru a/arch/ppc/platforms/iSeries_setup.c b/arch/ppc/platforms/iSeries_setup.c
--- a/arch/ppc/platforms/iSeries_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/iSeries_setup.c	Sun Jun 16 19:31:40 2002
@@ -24,6 +24,7 @@
 #include <linux/bootmem.h>
 #include <linux/blk.h>
 #include <linux/ide.h>
+#include <linux/root_dev.h>
 #include <linux/seq_file.h>
 
 #include <asm/processor.h>
@@ -154,7 +155,7 @@
 		initrd_start = xNaca.xRamDisk + KERNELBASE;
 		initrd_end   = initrd_start + xNaca.xRamDiskSize * PAGE_SIZE;
 		initrd_below_start_ok = 1;	// ramdisk in kernel space
-		ROOT_DEV = MKDEV( RAMDISK_MAJOR, 0 );
+		ROOT_DEV = Root_RAM0;
 
 		if ( ((rd_size*1024)/PAGE_SIZE) < xNaca.xRamDiskSize )
 			rd_size = (xNaca.xRamDiskSize*PAGE_SIZE)/1024;
@@ -163,7 +164,7 @@
 #endif /* CONFIG_BLK_DEV_INITRD */
 #if CONFIG_VIODASD_IDE
 	  {
-		ROOT_DEV = MKDEV( IDE0_MAJOR, 1 );
+		ROOT_DEV = Root_HDA1;
 	  }
 #elif defined(CONFIG_VIODASD)
 	  {
diff -Nru a/arch/ppc/platforms/k2_setup.c b/arch/ppc/platforms/k2_setup.c
--- a/arch/ppc/platforms/k2_setup.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc/platforms/k2_setup.c	Sun Jun 16 19:31:41 2002
@@ -29,6 +29,7 @@
 #include <linux/ide.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -178,13 +179,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x1601);	/* /dev/hdc1 */
+		ROOT_DEV = Root_HDC1;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c
--- a/arch/ppc/platforms/lopec_setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc/platforms/lopec_setup.c	Sun Jun 16 19:31:39 2002
@@ -24,6 +24,7 @@
 #include <linux/seq_file.h>
 #include <linux/blk.h>
 #include <linux/console.h>
+#include <linux/root_dev.h>
 
 #include <asm/io.h>
 #include <asm/open_pic.h>
@@ -319,14 +320,14 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #elif defined(CONFIG_ROOT_NFS)
-        	ROOT_DEV = to_kdev_t(0x00ff);
+        	ROOT_DEV = Root_NFS;
 #elif defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-	        ROOT_DEV = to_kdev_t(0x0301);
+	        ROOT_DEV = Root_HDA1;
 #else
-        	ROOT_DEV = to_kdev_t(0x0801);
+        	ROOT_DEV = Root_SDA1;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/mcpn765_setup.c b/arch/ppc/platforms/mcpn765_setup.c
--- a/arch/ppc/platforms/mcpn765_setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc/platforms/mcpn765_setup.c	Sun Jun 16 19:31:39 2002
@@ -32,6 +32,7 @@
 #include <linux/irq.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -92,13 +93,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef	CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802);	/* /dev/sda2 SCSI disk */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/menf1_setup.c b/arch/ppc/platforms/menf1_setup.c
--- a/arch/ppc/platforms/menf1_setup.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc/platforms/menf1_setup.c	Sun Jun 16 19:31:41 2002
@@ -29,6 +29,7 @@
 #include <linux/ide.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -69,13 +70,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
         if (initrd_start)
-                ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+                ROOT_DEV = Root_RAM0;
         else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0302); /* /dev/hda2 */
+		ROOT_DEV = Root_HDA2;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/mvme5100_setup.c b/arch/ppc/platforms/mvme5100_setup.c
--- a/arch/ppc/platforms/mvme5100_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/mvme5100_setup.c	Sun Jun 16 19:31:40 2002
@@ -28,6 +28,7 @@
 #include <linux/irq.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -77,13 +78,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef	CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802);	/* /dev/sda2 */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/pcore_setup.c b/arch/ppc/platforms/pcore_setup.c
--- a/arch/ppc/platforms/pcore_setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc/platforms/pcore_setup.c	Sun Jun 16 19:31:39 2002
@@ -29,6 +29,7 @@
 #include <linux/irq.h>
 #include <linux/seq_file.h>
 #include <linux/ide.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -118,13 +119,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
         else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
--- a/arch/ppc/platforms/pmac_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/pmac_setup.c	Sun Jun 16 19:31:40 2002
@@ -53,6 +53,7 @@
 #include <linux/pmu.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/processor.h>
 #include <asm/sections.h>
@@ -348,10 +349,10 @@
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
-		ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE);
+		ROOT_DEV = DEFAULT_ROOT_DEVICE;
 
 #ifdef CONFIG_SMP
 	/* Check for Core99 */
@@ -475,7 +476,7 @@
 	if (!initializing)
 		return;
 	if ((goodness <= current_root_goodness) &&
-	    !kdev_same(ROOT_DEV, to_kdev_t(DEFAULT_ROOT_DEVICE)))
+	    ROOT_DEV != DEFAULT_ROOT_DEVICE)
 		return;
 	p = strstr(saved_command_line, "root=");
 	if (p != NULL && (p == saved_command_line || p[-1] == ' '))
@@ -486,7 +487,7 @@
 		found_boot = 1;
 	}
 	if (kdev_same(boot_dev, NODEV) || kdev_same(dev, boot_dev)) {
-		ROOT_DEV = mk_kdev(major(dev), minor(dev) + part);
+		ROOT_DEV = MKDEV(major(dev), minor(dev) + part);
 		boot_dev = NODEV;
 		current_root_goodness = goodness;
 	}
diff -Nru a/arch/ppc/platforms/powerpmc250.c b/arch/ppc/platforms/powerpmc250.c
--- a/arch/ppc/platforms/powerpmc250.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc/platforms/powerpmc250.c	Sun Jun 16 19:31:39 2002
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/ide.h>
+#include <linux/root_dev.h>
 
 #include <asm/byteorder.h>
 #include <asm/system.h>
@@ -81,13 +82,13 @@
 	
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 	printk("Force PowerPMC250 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
diff -Nru a/arch/ppc/platforms/pplus_setup.c b/arch/ppc/platforms/pplus_setup.c
--- a/arch/ppc/platforms/pplus_setup.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc/platforms/pplus_setup.c	Sun Jun 16 19:31:41 2002
@@ -48,6 +48,7 @@
 #include <linux/ide.h>
 #include <linux/kdev_t.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/sections.h>
 #include <asm/mmu.h>
@@ -131,13 +132,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 	printk("PowerPlus port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
diff -Nru a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
--- a/arch/ppc/platforms/prep_setup.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc/platforms/prep_setup.c	Sun Jun 16 19:31:41 2002
@@ -41,6 +41,7 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/sections.h>
 #include <asm/mmu.h>
@@ -346,20 +347,20 @@
 	case _PREP_IBM:
 		/* Enable L2.  Assume we don't need to flush -- Cort*/
 		*(unsigned char *)(0x8000081c) |= 3;
-		ROOT_DEV = to_kdev_t(0x0301); /* hda1 */
+		ROOT_DEV = Root_HDA1;
 		break;
 	case _PREP_Motorola:
 		/* Enable L2.  Assume we don't need to flush -- Cort*/
 		*(unsigned char *)(0x8000081c) |= 3;
 #ifdef CONFIG_BLK_DEV_INITRD
 		if (initrd_start)
-			ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0); /* /dev/ram */
+			ROOT_DEV = Root_RAM0;
 		else
 #endif
 #ifdef CONFIG_ROOT_NFS
-			ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs */
+			ROOT_DEV = Root_NFS;
 #else
-			ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+			ROOT_DEV = Root_SDA2;
 #endif
 		break;
 	}
diff -Nru a/arch/ppc/platforms/prpmc750_setup.c b/arch/ppc/platforms/prpmc750_setup.c
--- a/arch/ppc/platforms/prpmc750_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/prpmc750_setup.c	Sun Jun 16 19:31:40 2002
@@ -29,6 +29,7 @@
 #include <linux/irq.h>
 #include <linux/seq_file.h>
 #include <linux/ide.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -85,13 +86,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/prpmc800_setup.c b/arch/ppc/platforms/prpmc800_setup.c
--- a/arch/ppc/platforms/prpmc800_setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc/platforms/prpmc800_setup.c	Sun Jun 16 19:31:40 2002
@@ -26,6 +26,7 @@
 #include <linux/irq.h>
 #include <linux/seq_file.h>
 #include <linux/ide.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -92,13 +93,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+		ROOT_DEV = Root_SDA2;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/sandpoint_setup.c b/arch/ppc/platforms/sandpoint_setup.c
--- a/arch/ppc/platforms/sandpoint_setup.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc/platforms/sandpoint_setup.c	Sun Jun 16 19:31:41 2002
@@ -72,6 +72,7 @@
 #include <linux/irq.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -162,13 +163,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef	CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0301);	/* /dev/hda1 IDE disk */
+		ROOT_DEV = Root_HDA1;
 #endif
 
 	/* Lookup PCI host bridges */
diff -Nru a/arch/ppc/platforms/spruce_setup.c b/arch/ppc/platforms/spruce_setup.c
--- a/arch/ppc/platforms/spruce_setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc/platforms/spruce_setup.c	Sun Jun 16 19:31:39 2002
@@ -44,6 +44,7 @@
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/ide.h>
+#include <linux/root_dev.h>
 
 #include <asm/keyboard.h>
 #include <asm/system.h>
@@ -143,13 +144,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0801);	/* /dev/sda1 */
+		ROOT_DEV = Root_SDA1;
 #endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
diff -Nru a/arch/ppc/platforms/zx4500_setup.c b/arch/ppc/platforms/zx4500_setup.c
--- a/arch/ppc/platforms/zx4500_setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc/platforms/zx4500_setup.c	Sun Jun 16 19:31:39 2002
@@ -42,6 +42,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -95,13 +96,13 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
-		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
 #if	defined(CONFIG_ROOT_NFS)
-		ROOT_DEV = to_kdev_t(0x00FF);	/* /dev/nfs pseudo device */
+		ROOT_DEV = Root_NFS;
 #else
-		ROOT_DEV = to_kdev_t(0x0801);	/* /dev/sda1 SCSI disk */
+		ROOT_DEV = Root_SDA1;
 #endif
 
 	/* Get boot string from flash */
diff -Nru a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c
--- a/arch/ppc64/kernel/chrp_setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/ppc64/kernel/chrp_setup.c	Sun Jun 16 19:31:39 2002
@@ -43,6 +43,7 @@
 
 #include <linux/irq.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/mmu.h>
 #include <asm/processor.h>
@@ -148,10 +149,10 @@
 	initrd_below_start_ok = 1;
 	
 	if (initrd_start)
-		ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	else
 #endif
-	ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
+	ROOT_DEV = Root_SDA2;
 
 	printk("Boot arguments: %s\n", cmd_line);
 
diff -Nru a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
--- a/arch/ppc64/kernel/iSeries_setup.c	Sun Jun 16 19:31:41 2002
+++ b/arch/ppc64/kernel/iSeries_setup.c	Sun Jun 16 19:31:41 2002
@@ -27,6 +27,7 @@
 #include <linux/bootmem.h>
 #include <linux/blk.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 
 #include <asm/processor.h>
 #include <asm/machdep.h>
@@ -295,7 +296,7 @@
 		initrd_start = (unsigned long)__va(naca->xRamDisk);
 		initrd_end   = initrd_start + naca->xRamDiskSize * PAGE_SIZE;
 		initrd_below_start_ok = 1;	// ramdisk in kernel space
-		ROOT_DEV = mk_kdev( RAMDISK_MAJOR, 0 );
+		ROOT_DEV = Root_RAM0;
 
 		if ( ((rd_size*1024)/PAGE_SIZE) < naca->xRamDiskSize )
 			rd_size = (naca->xRamDiskSize*PAGE_SIZE)/1024;
@@ -304,7 +305,7 @@
 #endif /* CONFIG_BLK_DEV_INITRD */
 	  {
                 
-	    /*		ROOT_DEV = mk_kdev( VIODASD_MAJOR, 1 ); */
+	    /*		ROOT_DEV = MKDEV( VIODASD_MAJOR, 1 ); */
 	  }
 
 	iSeries_recal_tb = get_tb();
diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
--- a/arch/ppc64/kernel/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/ppc64/kernel/setup.c	Sun Jun 16 19:31:40 2002
@@ -22,6 +22,7 @@
 #include <linux/seq_file.h>
 #include <linux/ioport.h>
 #include <linux/tty.h>
+#include <linux/root_dev.h>
 #include <asm/init.h>
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -373,7 +374,7 @@
 	if ((initrd_start == 0) && r3 && r4 && r4 != 0xdeadbeef) {
 		initrd_start = (r3 >= KERNELBASE) ? r3 : (unsigned long)__va(r3);
 		initrd_end = initrd_start + r4;
-		ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 		initrd_below_start_ok = 1;
 	}
 #endif
@@ -464,7 +465,7 @@
 		case BI_INITRD:
 			initrd_start = (unsigned long)__va(rec->data[0]);
 			initrd_end = initrd_start + rec->data[1];
-			ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
+			ROOT_DEV = Root_RAM0;
 			initrd_below_start_ok = 1;
 			break;
 #endif /* CONFIG_BLK_DEV_INITRD */
diff -Nru a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
--- a/arch/s390/kernel/setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/s390/kernel/setup.c	Sun Jun 16 19:31:39 2002
@@ -33,6 +33,7 @@
 #include <linux/blk.h>
 #endif
 #include <linux/bootmem.h>
+#include <linux/root_dev.h>
 #include <linux/console.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
@@ -321,7 +322,7 @@
 	       "This machine has an IEEE fpu\n" :
 	       "This machine has no IEEE fpu\n");
 
-        ROOT_DEV = to_kdev_t(0x0100);
+        ROOT_DEV = Root_RAM0;
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
 	memory_end = memory_size & ~0x400000UL;  /* align memory end to 4MB */
         /*
diff -Nru a/arch/s390x/kernel/setup.c b/arch/s390x/kernel/setup.c
--- a/arch/s390x/kernel/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/s390x/kernel/setup.c	Sun Jun 16 19:31:40 2002
@@ -33,6 +33,7 @@
 #include <linux/blk.h>
 #endif
 #include <linux/bootmem.h>
+#include <linux/root_dev.h>
 #include <linux/console.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
@@ -318,7 +319,7 @@
 	       "We are running under VM (64 bit mode)\n" :
 	       "We are running native (64 bit mode)\n");
 
-        ROOT_DEV = to_kdev_t(0x0100);
+        ROOT_DEV = Root_RAM0;
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
 	memory_end = memory_size & ~0x200000UL;  /* detected in head.s */
         init_mm.start_code = PAGE_OFFSET;
diff -Nru a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
--- a/arch/sh/kernel/setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/sh/kernel/setup.c	Sun Jun 16 19:31:39 2002
@@ -32,6 +32,7 @@
 #include <linux/console.h>
 #include <linux/ctype.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -275,7 +276,7 @@
 	sh_console_init();
 #endif
 	
-	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
+	ROOT_DEV = ORIG_ROOT_DEV;
 
 #ifdef CONFIG_BLK_DEV_RAM
 	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
diff -Nru a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
--- a/arch/sparc/kernel/setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/sparc/kernel/setup.c	Sun Jun 16 19:31:39 2002
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/console.h>
 #include <linux/spinlock.h>
+#include <linux/root_dev.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -377,7 +378,7 @@
 
 	if (!root_flags)
 		root_mountflags &= ~MS_RDONLY;
-	ROOT_DEV = to_kdev_t(root_dev);
+	ROOT_DEV = root_dev;
 #ifdef CONFIG_BLK_DEV_INITRD
 	rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
 	rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
diff -Nru a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S
--- a/arch/sparc64/kernel/dtlb_backend.S	Sun Jun 16 19:31:40 2002
+++ b/arch/sparc64/kernel/dtlb_backend.S	Sun Jun 16 19:31:40 2002
@@ -7,6 +7,7 @@
  */
 
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 
 #if PAGE_SHIFT == 13
 #define FILL_VALID_SZ_BITS1(r1) \
diff -Nru a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
--- a/arch/sparc64/kernel/dtlb_base.S	Sun Jun 16 19:31:40 2002
+++ b/arch/sparc64/kernel/dtlb_base.S	Sun Jun 16 19:31:40 2002
@@ -6,6 +6,9 @@
  * Copyright (C) 1997,1998 Jakub Jelinek   (jj@ultra.linux.cz)
  */
 
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+
 /* %g1	TLB_SFSR	(%g1 + %g1 == TLB_TAG_ACCESS)
  * %g2	(KERN_HIGHBITS | KERN_LOWBITS)
  * %g3  VPTE base	(0xfffffffe00000000)	Spitfire/Blackbird (44-bit VA space)
diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
--- a/arch/sparc64/kernel/setup.c	Sun Jun 16 19:31:40 2002
+++ b/arch/sparc64/kernel/setup.c	Sun Jun 16 19:31:40 2002
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/inet.h>
 #include <linux/console.h>
+#include <linux/root_dev.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -40,6 +41,7 @@
 #include <asm/head.h>
 #include <asm/starfire.h>
 #include <asm/hardirq.h>
+#include <asm/mmu_context.h>
 
 #ifdef CONFIG_IP_PNP
 #include <net/ipconfig.h>
@@ -537,7 +539,7 @@
 
 	if (!root_flags)
 		root_mountflags &= ~MS_RDONLY;
-	ROOT_DEV = to_kdev_t(root_dev);
+	ROOT_DEV = root_dev;
 #ifdef CONFIG_BLK_DEV_INITRD
 	rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
 	rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c	Sun Jun 16 19:31:39 2002
+++ b/arch/sparc64/kernel/smp.c	Sun Jun 16 19:31:39 2002
@@ -23,6 +23,7 @@
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
 #include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
 
 #include <asm/irq.h>
 #include <asm/page.h>
diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c	Sun Jun 16 19:31:40 2002
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	Sun Jun 16 19:31:40 2002
@@ -143,7 +143,7 @@
 
 #if defined(CONFIG_MCOUNT)
 extern void mcount(void);
-EXPORT_SYMBOL(mcount);
+EXPORT_SYMBOL_NOVERS(mcount);
 #endif
 
 /* Per-CPU information table */
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Sun Jun 16 19:31:40 2002
+++ b/arch/sparc64/kernel/sys_sparc32.c	Sun Jun 16 19:31:40 2002
@@ -513,9 +513,9 @@
 
 	if (!p)
 		return -ENOMEM;
-	err = get_user (p->mtype, &up->mtype);
-	err |= __copy_from_user (p->mtext, &up->mtext, second);
-	if (err)
+	err = -EFAULT;
+	if (get_user (p->mtype, &up->mtype) ||
+	    __copy_from_user (p->mtext, &up->mtext, second))
 		goto out;
 	old_fs = get_fs ();
 	set_fs (KERNEL_DS);
@@ -1001,7 +1001,7 @@
 static long do_readv_writev32(int type, struct file *file,
 			      const struct iovec32 *vector, u32 count)
 {
-	unsigned long tot_len;
+	__kernel_ssize_t32 tot_len;
 	struct iovec iovstack[UIO_FASTIOV];
 	struct iovec *iov=iovstack, *ivp;
 	struct inode *inode;
@@ -1031,13 +1031,19 @@
 	tot_len = 0;
 	i = count;
 	ivp = iov;
+	retval = -EINVAL;
 	while(i > 0) {
-		u32 len;
+		__kernel_ssize_t32 tmp = tot_len;
+		__kernel_ssize_t32 len;
 		u32 buf;
 
 		__get_user(len, &vector->iov_len);
 		__get_user(buf, &vector->iov_base);
+		if (len < 0)	/* size_t not fittina an ssize_t32 .. */
+			goto out;
 		tot_len += len;
+		if (tot_len < tmp) /* maths overflow on the ssize_t32 */
+			goto out;
 		ivp->iov_base = (void *)A(buf);
 		ivp->iov_len = (__kernel_size_t) len;
 		vector++;
@@ -2759,6 +2765,8 @@
 		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
+		if (ret)
+			ret = -EFAULT;
         }
 
         return ret;
@@ -3494,7 +3502,7 @@
 	err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
 			  &arg32->ca32_client.cl32_fhkey[0],
 			  NFSCLNT_KEYMAX);
-	return err;
+	return (err ? -EFAULT : 0);
 }
 
 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
@@ -3520,7 +3528,7 @@
 		      &arg32->ca32_export.ex32_anon_gid);
 	karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
 	karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
-	return err;
+	return (err ? -EFAULT : 0);
 }
 
 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
@@ -3568,7 +3576,7 @@
 		err |= __get_user(karg->ca_umap.ug_gdimap[i],
 			      &(((__kernel_gid_t32 *)A(uaddr))[i]));
 
-	return err;
+	return (err ? -EFAULT : 0);
 }
 
 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
@@ -3585,7 +3593,7 @@
 		      &arg32->ca32_getfh.gf32_ino);
 	err |= __get_user(karg->ca_getfh.gf_version,
 		      &arg32->ca32_getfh.gf32_version);
-	return err;
+	return (err ? -EFAULT : 0);
 }
 
 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
@@ -3601,7 +3609,7 @@
 			  (NFS_MAXPATHLEN+1));
 	err |= __get_user(karg->ca_getfd.gd_version,
 		      &arg32->ca32_getfd.gd32_version);
-	return err;
+	return (err ? -EFAULT : 0);
 }
 
 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
@@ -3617,7 +3625,7 @@
 			  (NFS_MAXPATHLEN+1));
 	err |= __get_user(karg->ca_getfs.gd_maxlen,
 		      &arg32->ca32_getfs.gd32_maxlen);
-	return err;
+	return (err ? -EFAULT : 0);
 }
 
 /* This really doesn't need translations, we are only passing
@@ -3625,7 +3633,7 @@
  */
 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
 {
-	return copy_to_user(res32, kres, sizeof(*res32));
+	return (copy_to_user(res32, kres, sizeof(*res32)) ? -EFAULT : 0);
 }
 
 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
--- a/arch/sparc64/kernel/sys_sunos32.c	Sun Jun 16 19:31:40 2002
+++ b/arch/sparc64/kernel/sys_sunos32.c	Sun Jun 16 19:31:40 2002
@@ -445,7 +445,7 @@
 	ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
 	ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
 	up_read(&uts_sem);
-	return ret;
+	return (ret ? -EFAULT : 0);
 }
 
 asmlinkage int sunos_nosys(void)
diff -Nru a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c	Sun Jun 16 19:31:40 2002
+++ b/arch/sparc64/mm/init.c	Sun Jun 16 19:31:40 2002
@@ -30,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
 #include <asm/dma.h>
 #include <asm/starfire.h>
 #include <asm/tlb.h>
@@ -89,17 +90,15 @@
         if (pgd_cache_size > PGT_CACHE_HIGH / 4) {
 		struct page *page, *page2;
                 for (page2 = NULL, page = (struct page *)pgd_quicklist; page;) {
-                        if ((unsigned long)page->pprev_hash == 3) {
+                        if ((unsigned long)page->lru.prev == 3) {
                                 if (page2)
-                                        page2->next_hash = page->next_hash;
+                                        page2->lru.next = page->lru.next;
                                 else
-                                        (struct page *)pgd_quicklist = page->next_hash;
-                                page->next_hash = NULL;
-                                page->pprev_hash = NULL;
+                                        (struct page *)pgd_quicklist = page->lru.next;
                                 pgd_cache_size -= 2;
                                 __free_page(page);
                                 if (page2)
-                                        page = page2->next_hash;
+                                        page = (struct page *)page2->lru.next;
                                 else
                                         page = (struct page *)pgd_quicklist;
                                 if (pgd_cache_size <= PGT_CACHE_LOW / 4)
@@ -107,7 +106,7 @@
                                 continue;
                         }
                         page2 = page;
-                        page = page->next_hash;
+                        page = (struct page *)page->lru.next;
                 }
         }
 #endif
diff -Nru a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
--- a/arch/sparc64/solaris/fs.c	Sun Jun 16 19:31:39 2002
+++ b/arch/sparc64/solaris/fs.c	Sun Jun 16 19:31:39 2002
@@ -409,7 +409,7 @@
 		    __put_user (s.f_files, &ss->f_files)	||
 		    __put_user (s.f_ffree, &ss->f_ffree)	||
 		    __put_user (s.f_ffree, &ss->f_favail)	||
-		    __put_user (R4_DEV(kdev_t_to_nr(inode->i_sb->s_dev)), &ss->f_fsid) ||
+		    __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
 		    __copy_to_user (ss->f_basetype,p,j)		||
 		    __put_user (0, (char *)&ss->f_basetype[j])	||
 		    __put_user (s.f_namelen, &ss->f_namemax)	||
@@ -443,7 +443,7 @@
 		    __put_user (s.f_files, &ss->f_files)	||
 		    __put_user (s.f_ffree, &ss->f_ffree)	||
 		    __put_user (s.f_ffree, &ss->f_favail)	||
-		    __put_user (R4_DEV(kdev_t_to_nr(inode->i_sb->s_dev)), &ss->f_fsid) ||
+		    __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
 		    __copy_to_user (ss->f_basetype,p,j)		||
 		    __put_user (0, (char *)&ss->f_basetype[j])	||
 		    __put_user (s.f_namelen, &ss->f_namemax)	||
diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile
--- a/arch/x86_64/Makefile	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/Makefile	Sun Jun 16 19:31:40 2002
@@ -23,7 +23,7 @@
 
 #
 # early bootup linking needs 32bit. You can either use real 32bit tools
-# here or 64bit tools switch to 32bit mode.
+# here or 64bit tools in 32bit mode.
 #
 IA32_CC := $(CROSS_COMPILE)gcc -m32 -O2 -fomit-frame-pointer -nostdinc -I $(HPATH)
 IA32_LD := $(CROSS_COMPILE)ld -m elf_i386
@@ -41,11 +41,12 @@
 CFLAGS += -mno-red-zone
 CFLAGS += -mcmodel=kernel
 CFLAGS += -pipe
+# this makes reading assembly source easier
 CFLAGS += -fno-reorder-blocks	
 # needed for later gcc 3.1
 CFLAGS += -finline-limit=2000
 # needed for earlier gcc 3.1
-CFLAGS += -fno-strength-reduce
+#CFLAGS += -fno-strength-reduce
 #CFLAGS += -g
 
 # prevent gcc from keeping the stack 16 byte aligned (FIXME)
@@ -63,9 +64,9 @@
 CORE_FILES += arch/x86_64/ia32/ia32.o
 endif
 
-ifdef CONFIG_HOSTFS
-SUBDIRS += arch/x86_64/hostfs
-core-$(CONFIG_HOSTFS) += arch/x86_64/hostfs/hostfs.o
+ifdef CONFIG_PCI
+SUBDIRS += arch/x86_64/pci
+DRIVERS += arch/x86_64/pci/pci.o
 endif
 
 CORE_FILES += $(core-y)
@@ -77,7 +78,7 @@
 .PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
 		clean archclean archmrproper archdep checkoffset
 
-checkoffset: FORCE
+checkoffset: FORCE include/asm
 	make -C arch/$(ARCH)/tools $(TOPDIR)/include/asm-x86_64/offset.h
 
 bzImage: checkoffset vmlinux
diff -Nru a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
--- a/arch/x86_64/boot/setup.S	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/boot/setup.S	Sun Jun 16 19:31:40 2002
@@ -452,7 +452,7 @@
 	cmpw	$0, %cs:realmode_swtch
 	jz	rmodeswtch_normal
 
-	lcall	%cs:realmode_swtch
+	lcall	*%cs:realmode_swtch
 
 	jmp	rmodeswtch_end
 
diff -Nru a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S
--- a/arch/x86_64/boot/video.S	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/boot/video.S	Sun Jun 16 19:31:40 2002
@@ -437,6 +437,7 @@
 
 # Setting of user mode (AX=mode ID) => CF=success
 mode_set:
+       	movw    %ax, %fs:(0x01fa)
 	movw	%ax, %bx
 	cmpb	$0xff, %ah
 	jz	setalias
diff -Nru a/arch/x86_64/config.in b/arch/x86_64/config.in
--- a/arch/x86_64/config.in	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/config.in	Sun Jun 16 19:31:39 2002
@@ -2,12 +2,17 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
+# Note: ISA is disabled and will hopefully never be enabled.
+# If you managed to buy an ISA x86-64 box you'll have to fix all the
+# ISA drivers you need yourself. 
+#
+
 mainmenu_name "Linux Kernel Configuration"
 
 define_bool CONFIG_X86_64 y
 
 define_bool CONFIG_X86 y
-define_bool CONFIG_ISA y
+define_bool CONFIG_ISA n
 define_bool CONFIG_SBUS n
 
 define_bool CONFIG_UID16 y
@@ -22,7 +27,8 @@
 mainmenu_option next_comment
 comment 'Processor type and features'
 choice 'Processor family' \
-	"AMD-Hammer			CONFIG_MK8" CONFIG_MK8
+	"AMD-Hammer			CONFIG_MK8 \
+	 Generic-x86-64			CONFIG_GENERIC_CPU" AMD-Hammer
 	
 #
 # Define implied options from the CPU selection here
@@ -44,8 +50,10 @@
 #currently broken:
 #bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
-bool 'Preemptible Kernel' CONFIG_PREEMPT
-if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
+if [ "$CONFIG_SMP" = "n" ]; then
+   bool 'Preemptible Kernel' CONFIG_PREEMPT
+fi
+if [ "$CONFIG_SMP" = "y" ]; then
     define_bool CONFIG_HAVE_DEC_LOCK y
 fi
 
@@ -56,10 +64,18 @@
 
 mainmenu_option next_comment
 
-comment 'General options'
+comment 'Power management options'
+
+bool 'Power Management support' CONFIG_PM
 
 source drivers/acpi/Config.in
 
+endmenu
+
+mainmenu_option next_comment
+
+comment 'Bus options (PCI etc.)'
+
 bool 'PCI support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
 # x86-64 doesn't support PCI BIOS access from long mode so always go direct. 
@@ -77,6 +93,12 @@
    define_bool CONFIG_PCMCIA n
 fi
 
+endmenu
+
+mainmenu_option next_comment
+
+comment 'Executable file formats / Emulations'
+
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
 fi
@@ -84,8 +106,6 @@
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
-bool 'Power Management support' CONFIG_PM
-
 bool 'IA32 Emulation' CONFIG_IA32_EMULATION
 
 endmenu
@@ -94,7 +114,7 @@
 
 source drivers/parport/Config.in
 
-source drivers/pnp/Config.in
+#source drivers/pnp/Config.in
 
 source drivers/block/Config.in
 
@@ -142,9 +162,10 @@
    bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
-         source drivers/atm/Config.in
-      fi
+# ATM seems to be largely 64bit unsafe and also unmaintained - disable it for now.
+#      if [ "$CONFIG_ATM" = "y" ]; then
+#         source drivers/atm/Config.in
+#      fi
    fi
    endmenu
 fi
@@ -155,14 +176,7 @@
 
 source drivers/isdn/Config.in
 
-mainmenu_option next_comment
-comment 'Old CD-ROM drivers (not SCSI, not IDE)'
-
-bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
-if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-   source drivers/cdrom/Config.in
-fi
-endmenu
+# no support for non IDE/SCSI cdroms as they were all ISA only
 
 #
 # input before char - char/joystick depends on it. As does USB.
diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig
--- a/arch/x86_64/defconfig	Sun Jun 16 19:31:41 2002
+++ b/arch/x86_64/defconfig	Sun Jun 16 19:31:41 2002
@@ -1,9 +1,9 @@
 #
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
 #
 CONFIG_X86_64=y
 CONFIG_X86=y
-CONFIG_ISA=y
+# CONFIG_ISA is not set
 # CONFIG_SBUS is not set
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -35,6 +35,7 @@
 # Processor type and features
 #
 CONFIG_MK8=y
+# CONFIG_GENERIC_CPU is not set
 CONFIG_X86_L1_CACHE_BYTES=64
 CONFIG_X86_L1_CACHE_SHIFT=6
 CONFIG_X86_TSC=y
@@ -47,28 +48,35 @@
 CONFIG_X86_IO_APIC=y
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_SMP=y
-# CONFIG_PREEMPT is not set
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_X86_MCE=y
 # CONFIG_X86_MCE_NONFATAL is not set
 
 #
-# General options
+# Power management options
 #
+# CONFIG_PM is not set
 
 #
 # ACPI Support
 #
 # CONFIG_ACPI is not set
+
+#
+# Bus options (PCI etc.)
+#
 CONFIG_PCI=y
 CONFIG_PCI_DIRECT=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+
+#
+# Executable file formats / Emulations
+#
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
 CONFIG_IA32_EMULATION=y
 
 #
@@ -82,26 +90,21 @@
 # CONFIG_PARPORT is not set
 
 #
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
-
-#
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_FD=y
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
 
 #
 # Multi-device support (RAID and LVM)
@@ -118,17 +121,19 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
@@ -136,12 +141,13 @@
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
 
 #
+# Appletalk devices
 #  
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -174,10 +180,6 @@
 # ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
@@ -188,10 +190,6 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support
-#
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -199,17 +197,17 @@
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_PCI_AUTO is not set
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_BLK_DEV_IDE_TCQ is not set
 # CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_AEC6280_BURST is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -226,9 +224,11 @@
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
+CONFIG_ATAPI=y
+# CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
@@ -236,16 +236,67 @@
 #
 # SCSI support
 #
-# CONFIG_SCSI is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_REPORT_LUNS is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
 
 #
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_BOOT is not set
-# CONFIG_FUSION_ISENSE is not set
-# CONFIG_FUSION_CTL is not set
-# CONFIG_FUSION_LAN is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -255,7 +306,83 @@
 #
 # Network device support
 #
-# CONFIG_NETDEVICES is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+# CONFIG_ELMC is not set
+# CONFIG_ELMC_II is not set
+CONFIG_VORTEX=y
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+CONFIG_TIGON3=y
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
 
 #
 # Amateur Radio support
@@ -273,11 +400,6 @@
 # CONFIG_ISDN_BOOL is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Input device support
 #
 # CONFIG_INPUT is not set
@@ -329,7 +451,7 @@
 # CONFIG_WATCHDOG is not set
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
+CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -356,9 +478,11 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
+CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
@@ -366,8 +490,8 @@
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
@@ -377,7 +501,7 @@
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -410,15 +534,15 @@
 #
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
-# CONFIG_NFS_FS is not set
+CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 # CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
+CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
 # CONFIG_NFSD_TCP is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
-# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -471,7 +595,7 @@
 #
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_CHECKING is not set
 # CONFIG_INIT_DEBUG is not set
diff -Nru a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile
--- a/arch/x86_64/ia32/Makefile	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/ia32/Makefile	Sun Jun 16 19:31:40 2002
@@ -2,11 +2,16 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-O_TARGET := ia32.o
+USE_STANDARD_AS_RULE := true
+
+export-objs := ia32_ioctl.o sys_ia32.o
 
-export-objs := ia32_ioctl.o	
+all: ia32.o
 
+O_TARGET := ia32.o
 obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o \
 	ia32_binfmt.o fpu32.o socket32.o ptrace32.o
+
+clean::
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
--- a/arch/x86_64/ia32/ia32_ioctl.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/ia32/ia32_ioctl.c	Sun Jun 16 19:31:39 2002
@@ -113,6 +113,7 @@
 	return err;
 }
  
+#if 0 
 static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	mm_segment_t old_fs = get_fs();
@@ -128,6 +129,7 @@
 		return -EFAULT;
 	return err;
 }
+#endif
 
 static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
@@ -2971,11 +2973,6 @@
 	return err;
 }
 
-static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
-}
-
 /* SuSE extension */ 
 #ifndef TIOCGDEV
 #define TIOCGDEV       _IOR('T',0x32, unsigned int)
@@ -3087,19 +3084,13 @@
 	return err;	
 }
 
-struct ioctl_trans {
-	unsigned long cmd;
-	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
-	struct ioctl_trans *next;
-};
-
-/* generic function to change a single long put_user to arg to 32bit */
-static int arg2long(unsigned int fd, unsigned int cmd, unsigned long arg)
+static int generic_long_put(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	int ret; 
 	unsigned long val = 0; 
 	mm_segment_t oldseg = get_fs();
 	set_fs(KERNEL_DS);
+	cmd = (cmd & 0xc000ffff)  | (sizeof(unsigned long) << _IOC_SIZESHIFT); 
 	ret = sys_ioctl(fd, cmd, (unsigned long)&val);  
 	set_fs(oldseg); 
 	if (!ret || val) {
@@ -3109,6 +3100,29 @@
 	return ret; 
 } 
 
+static int generic_long_get(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	int ret; 
+	unsigned int ival; 
+	unsigned long val = 0; 
+	mm_segment_t oldseg = get_fs();
+	if (get_user(ival, (unsigned int *)arg))
+		return -EFAULT;
+	val = ival;
+	set_fs(KERNEL_DS);
+	cmd = (cmd & 0xc000ffff)  | (sizeof(unsigned long) << _IOC_SIZESHIFT); 
+	ret = sys_ioctl(fd, cmd, (unsigned long)&val);  
+	set_fs(oldseg); 
+	return ret; 
+} 
+
+
+struct ioctl_trans {
+	unsigned long cmd;
+	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
+	struct ioctl_trans *next;
+};
+
 #define REF_SYMBOL(handler) if (0) (void)handler;
 #define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler);  asm volatile(".quad %c0, " #handler ",0"::"i" (cmd)); 
 #define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler)
@@ -3316,10 +3330,6 @@
 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
 /* Little p (/dev/rtc, /dev/envctrl, etc.) */
-#if 0
-COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
-COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-#endif
 COMPATIBLE_IOCTL(RTC_AIE_ON)
 COMPATIBLE_IOCTL(RTC_AIE_OFF)
 COMPATIBLE_IOCTL(RTC_UIE_ON)
@@ -3334,10 +3344,14 @@
 COMPATIBLE_IOCTL(RTC_SET_TIME)
 COMPATIBLE_IOCTL(RTC_WKALM_SET)
 COMPATIBLE_IOCTL(RTC_WKALM_RD)
-HANDLE_IOCTL(RTC_IRQP_READ,arg2long)
-COMPATIBLE_IOCTL(RTC_IRQP_SET)
-COMPATIBLE_IOCTL(RTC_EPOCH_READ)
-COMPATIBLE_IOCTL(RTC_EPOCH_SET)
+#define RTC_IRQP_READ32	_IOR('p', 0x0b, unsigned int)	 /* Read IRQ rate   */
+HANDLE_IOCTL(RTC_IRQP_READ32,generic_long_put)
+#define RTC_IRQP_SET32	_IOW('p', 0x0c, unsigned int)	 /* Set IRQ rate    */
+HANDLE_IOCTL(RTC_IRQP_SET32,generic_long_get)
+#define RTC_EPOCH_READ32	_IOR('p', 0x0d, unsigned long)	 /* Read epoch      */
+#define RTC_EPOCH_SET32		_IOW('p', 0x0e, unsigned long)	 /* Set epoch       */
+HANDLE_IOCTL(RTC_EPOCH_READ32, generic_long_put)
+HANDLE_IOCTL(RTC_EPOCH_SET32, generic_long_get)
 /* Little m */
 COMPATIBLE_IOCTL(MTIOCTOP)
 /* Socket level stuff */
@@ -3605,6 +3619,8 @@
 COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
 COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
+HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, generic_long_get); 
 /* DEVFS */
 COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
 COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
@@ -3671,14 +3687,6 @@
 COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
 COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
 #endif /* DRM */
-#ifdef CONFIG_AUTOFS_FS
-COMPATIBLE_IOCTL(AUTOFS_IOC_READY);
-COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL);
-COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC);
-COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER);
-COMPATIBLE_IOCTL(AUTOFS_IOC_SETTIMEOUT);
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE);
-#endif
 COMPATIBLE_IOCTL(REISERFS_IOC_UNPACK);
 /* serial driver */ 
 HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl);
@@ -3771,8 +3779,6 @@
 HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
 HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
 HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
-#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
-HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
 HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
 HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
 HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
--- a/arch/x86_64/ia32/ia32_signal.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/ia32/ia32_signal.c	Sun Jun 16 19:31:40 2002
@@ -241,7 +241,7 @@
 	return eax;
 
 badframe:
-	force_sig(SIGSEGV, current);
+	signal_fault(&regs, frame, "32bit sigreturn"); 
 	return 0;
 }	
 
@@ -280,7 +280,7 @@
 	return eax;
 
 badframe:
-	force_sig(SIGSEGV, current);
+	signal_fault(&regs, frame, "32bit rt sigreturn"); 
 	return 0;
 }	
 
@@ -420,7 +420,7 @@
 give_sigsegv:
 	if (sig == SIGSEGV)
 		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	signal_fault(regs,frame,"32bit signal setup"); 
 }
 
 void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -493,6 +493,6 @@
 give_sigsegv:
 	if (sig == SIGSEGV)
 		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	signal_fault(regs, frame, "32bit rt signal setup"); 
 }
 
diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
--- a/arch/x86_64/ia32/ia32entry.S	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/ia32/ia32entry.S	Sun Jun 16 19:31:40 2002
@@ -24,9 +24,6 @@
 
 /*
  * 32bit SYSCALL instruction entry. 	
- * It'll probably kill you because it destroys your segments.
- * Should coredump here, but the next instruction will likely do 
- * that anyways.
  */ 	
 ENTRY(ia32_cstar_target)
 	movq $-ENOSYS,%rax
@@ -117,6 +114,7 @@
 
 	.data
 	.align 8
+	.globl ia32_sys_call_table
 ia32_sys_call_table:
 	.quad ni_syscall	/* 0  -  old "setup" system call*/
 	.quad sys_exit
@@ -143,7 +141,7 @@
 	.quad sys_oldumount	/* old_umount  */
 	.quad sys_setuid16
 	.quad sys_getuid16
-	.quad ni_syscall	/* stime */		/* 25 */
+	.quad sys_stime		/* stime */		/* 25 */
 	.quad sys32_ptrace	/* ptrace */
 	.quad sys_alarm		/* XXX sign extension??? */ 
 	.quad ni_syscall	/* (old)fstat */
@@ -240,7 +238,7 @@
 	.quad stub32_sigreturn
 	.quad stub32_clone		/* 120 */
 	.quad sys_setdomainname
-	.quad sys_newuname
+	.quad sys32_newuname
 	.quad sys_modify_ldt
 	.quad sys32_adjtimex
 	.quad sys32_mprotect		/* 125 */
diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/ia32/sys_ia32.c	Sun Jun 16 19:31:40 2002
@@ -2579,6 +2579,8 @@
 	down_read(&uts_sem);
 	err=copy_to_user(name, &system_utsname, sizeof (*name));
 	up_read(&uts_sem);
+	if (current->personality == PER_LINUX32) 
+		err |= copy_to_user(&name->machine, "i386", 5);
 	return err?-EFAULT:0;
 }
 
@@ -3125,3 +3127,6 @@
 }
 
 __initcall(ia32_init);
+
+extern unsigned long ia32_sys_call_table[];
+EXPORT_SYMBOL(ia32_sys_call_table);
diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
--- a/arch/x86_64/kernel/Makefile	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/Makefile	Sun Jun 16 19:31:39 2002
@@ -12,11 +12,6 @@
 		pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
 		setup64.o bluesmoke.o bootflag.o
 
-ifdef CONFIG_PCI
-obj-y			+= pci-x86_64.o
-obj-y			+= pci-pc.o pci-irq.o
-endif
-
 obj-$(CONFIG_MTRR)	+= mtrr.o
 obj-$(CONFIG_X86_MSR)	+= msr.o
 obj-$(CONFIG_X86_CPUID)	+= cpuid.o
diff -Nru a/arch/x86_64/kernel/bootflag.c b/arch/x86_64/kernel/bootflag.c
--- a/arch/x86_64/kernel/bootflag.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/bootflag.c	Sun Jun 16 19:31:40 2002
@@ -48,7 +48,7 @@
 	unsigned int i;
 	struct sbf_boot sb;
 	
-	memcpy_fromio(&sb, tptr, sizeof(sb));
+	memcpy_fromio(&sb, (void *)tptr, sizeof(sb));
 
 	if(sb.sbf_len != 40 && sb.sbf_len != 39)
 		// 39 on IBM ThinkPad A21m, BIOS version 1.02b (KXET24WW; 2000-12-19).
@@ -238,6 +238,7 @@
 		rp = (unsigned long)ioremap(rp, 4096);
 		if(rp == 0)
 			continue;
+		
 		if(sbf_struct_valid(rp))
 		{
 			/* Found the BOOT table and processed it */
diff -Nru a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
--- a/arch/x86_64/kernel/early_printk.c	Sun Jun 16 19:31:41 2002
+++ b/arch/x86_64/kernel/early_printk.c	Sun Jun 16 19:31:41 2002
@@ -94,15 +94,20 @@
 
 static __init void early_serial_init(char *opt)
 {
-	static int bases[] = { 0x3f8, 0x2f8 };
 	unsigned char c; 
 	unsigned divisor, baud = 38400;
 	char *s, *e;
 
+	if (*opt == ',') 
+		++opt;
+
 	s = strsep(&opt, ","); 
 	if (s != NULL) { 
 		unsigned port; 
-		++s; 
+		if (!strncmp(s,"0x",2))
+			early_serial_base = simple_strtoul(s, &e, 16);
+		else {	
+			static int bases[] = { 0x3f8, 0x2f8 };
 		if (!strncmp(s,"ttyS",4)) 
 			s+=4; 
 		port = simple_strtoul(s, &e, 10); 
@@ -110,12 +115,11 @@
 			port = 0; 
 		early_serial_base = bases[port];
 	}
+	}
 
-	c = inb(early_serial_base + LCR); 
-	outb(c & ~DLAB, early_serial_base + LCR); 
+	outb(0x3, early_serial_base + LCR); /* 8n1 */
 	outb(0, early_serial_base + IER); /* no interrupt */ 
 	outb(0, early_serial_base + FCR); /* no fifo */ 
-	outb(0x3, early_serial_base + LCR); /* 8n1 */
 	outb(0x3, early_serial_base + MCR); /* DTR + RTS */ 
 
 	s = strsep(&opt, ","); 
@@ -155,33 +159,55 @@
 	va_end(ap); 
 } 
 
+static int keep_early; 
+
 int __init setup_early_printk(char *opt) 
 {  
+	char *space;
+	char buf[256]; 
+
 	if (early_console_initialized)
-		return;
-	early_console_initialized = 1;
+		return -1;
+
+	strncpy(buf,opt,256); 
+	buf[255] = 0; 
+	space = strchr(buf, ' '); 
+	if (space)
+		*space = 0; 
+
+	if (strstr(buf,"keep"))
+		keep_early = 1; 
 
-	if (!strncmp(opt, "serial", 6)) { 
-		early_serial_init(opt+7);
+	if (!strncmp(buf, "serial", 6)) { 
+		early_serial_init(buf + 6);
 		early_console = &early_serial_console;
-	} else if (!strncmp(opt, "vga", 3))
+	} else if (!strncmp(buf, "vga", 3)) {
 		early_console = &early_vga_console; 
-	else
+	} else {
+		early_console = NULL; 		
 		return -1; 
+	}
+	early_console_initialized = 1;
 	register_console(early_console);       
 	return 0;
 }
 
 void __init disable_early_printk(void)
 { 
-	if (early_console_initialized) {
+	if (!early_console_initialized || !early_console)
+		return;
+	if (!keep_early) {
+		printk("disabling early console...\n"); 
 		unregister_console(early_console);
 		early_console_initialized = 0;
+	} else { 
+		printk("keeping early console.\n"); 
 	}
 } 
 
 /* syntax: earlyprintk=vga
            earlyprintk=serial[,ttySn[,baudrate]] 
+   Append ,keep to not disable it when the real console takes over.
    Only vga or serial at a time, not both.
    Currently only ttyS0 and ttyS1 are supported. 
    Interaction with the standard serial driver is not very good. 
diff -Nru a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/entry.S	Sun Jun 16 19:31:40 2002
@@ -40,6 +40,7 @@
 #include <asm/unistd.h>
 #include <asm/thread_info.h>
 #include <asm/hw_irq.h>
+#include <asm/errno.h>
 
 	.code64
 
@@ -270,8 +271,8 @@
 	/* Check for syscall exit trace */	
 	bt $TIF_SYSCALL_TRACE,%edx
 	jnc int_signal
-	movq %rsp,%rdi		# &ptregs -> arg1
 	pushq %rdi
+	leaq 8(%rsp),%rdi	# &ptregs -> arg1	
 	call syscall_trace
 	popq %rdi
 	btr  $TIF_SYSCALL_TRACE,%edi
@@ -563,16 +564,17 @@
 
 	# rdi: flags, rsi: usp, rdx: will be &pt_regs
 	movq %rdx,%rdi
-	orq  $CLONE_VM, %rdi
-
+	orq  kernel_thread_flags(%rip), %rdi
 	movq $-1, %rsi
-
 	movq %rsp, %rdx
 
 	# clone now
-	call do_fork_FIXME_NOW_RETURNS_TASK_STRUCT
-	# save retval on the stack so it's popped before `ret`
-	movq %rax, RAX(%rsp)
+	call do_fork
+
+	xorl %edi,%edi
+	cmpq $-1000,%rax
+	cmovb %rdi,%rax
+	movq %rax,RAX(%rsp)
 
 	/*
 	 * It isn't worth to check for reschedule here,
diff -Nru a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
--- a/arch/x86_64/kernel/head.S	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/head.S	Sun Jun 16 19:31:40 2002
@@ -38,7 +38,11 @@
 
 	movl %ebx,%ebp	/* Save trampoline flag */
 	
-	/* First check if extended functions are implemented */
+	/* If the CPU doesn't support CPUID this will double fault.
+	 * Unfortunately it is hard to check for CPUID without a stack. 
+	 */
+	
+	/* Check if extended functions are implemented */		
 	movl	$0x80000000, %eax
 	cpuid
 	cmpl	$0x80000000, %eax
@@ -157,6 +161,17 @@
 	 */
 	lgdt	pGDT64
 
+	/* 
+	 * Setup up a dummy PDA. this is just for some early bootup code
+	 * that does in_interrupt() 
+	 */ 
+	movl	$MSR_GS_BASE,%ecx
+	movq	$empty_zero_page,%rax
+	movq    %rax,%rdx
+	shrq	$32,%rdx
+	wrmsr	
+
+	/* set up data segments. actually 0 would do too */
 	movl $__KERNEL_DS,%eax
 	movl %eax,%ds	
 	movl %eax,%ss
diff -Nru a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
--- a/arch/x86_64/kernel/head64.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/head64.c	Sun Jun 16 19:31:40 2002
@@ -70,16 +70,18 @@
 	boot_cpu_data.x86_mask = eax & 0xf;
 }
 
-extern void start_kernel(void), pda_init(int); 
+extern void start_kernel(void), pda_init(int), setup_early_printk(char *); 
 
 void __init x86_64_start_kernel(char * real_mode_data)
 {
+	char *s;
+
 	clear_bss();
 	pda_init(0);
-
 	copy_bootdata(real_mode_data);
+	s = strstr(saved_command_line, "earlyprintk="); 
+	if (s != NULL)
+		setup_early_printk(s+12); 
 	setup_boot_cpu_data();
-
-
 	start_kernel();
 }
diff -Nru a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c
--- a/arch/x86_64/kernel/i387.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/i387.c	Sun Jun 16 19:31:40 2002
@@ -24,8 +24,6 @@
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 
-static struct i387_fxsave_struct init_fpu_env; 
-
 /*
  * Called at bootup to set up the initial FPU state that is later cloned
  * into all processes.
@@ -76,6 +74,9 @@
 		if (sizeof(struct user_i387_struct) != sizeof(tsk->thread.i387.fxsave))
 			bad_user_i387_struct();
 	} 
+
+	if ((unsigned long)buf % 16) 
+		printk("save_i387: bad fpstate %p\n",buf); 
 
 	if (!tsk->used_math) 
 		return 0;
diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
--- a/arch/x86_64/kernel/i8259.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/i8259.c	Sun Jun 16 19:31:39 2002
@@ -12,6 +12,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
+#include <linux/device.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
@@ -318,6 +319,18 @@
 		goto handle_real_irq;
 	}
 }
+
+static struct device device_i8259A = {
+       name:           "i8259A",
+       bus_id:         "0020",
+};
+
+static int __init init_8259A_devicefs(void)
+{
+       return register_sys_device(&device_i8259A);
+}
+
+__initcall(init_8259A_devicefs);
 
 void __init init_8259A(int auto_eoi)
 {
diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/irq.c	Sun Jun 16 19:31:40 2002
@@ -163,7 +163,7 @@
 	}
 	seq_printf(p, "NMI: ");
 	for (j = 0; j < smp_num_cpus; j++)
-		seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j)));
+		seq_printf(p, "%10u ", cpu_pda[cpu_logical_map(j)].__nmi_count);
 	seq_putc(p, '\n');
 #if CONFIG_X86_LOCAL_APIC
 	seq_printf(p, "LOC: ");
diff -Nru a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c
--- a/arch/x86_64/kernel/ldt.c	Sun Jun 16 19:31:41 2002
+++ b/arch/x86_64/kernel/ldt.c	Sun Jun 16 19:31:41 2002
@@ -8,11 +8,6 @@
  * This handles calls from both 32bit and 64bit mode.
  */
 
-/* 
- * FIXME:
- * Need to add locking for LAR in load_gs_index.
- */ 
-
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -20,42 +15,164 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/ldt.h>
 #include <asm/desc.h>
 
+void load_gs_index(unsigned gs)
+{
+	int access;
+	struct task_struct *me = current;
+	if (me->mm) 
+		read_lock(&me->mm->context.ldtlock); 
+	asm volatile("pushf\n\t" 
+		     "cli\n\t"
+		     "swapgs\n\t"
+		     "lar %1,%0\n\t"
+		     "jnz 1f\n\t"
+		     "movl %1,%%eax\n\t"
+		     "movl %%eax,%%gs\n\t"
+		     "jmp 2f\n\t"
+		     "1: movl %2,%%gs\n\t"
+		     "2: swapgs\n\t"
+		     "popf" : "=g" (access) : "g" (gs), "r" (0) : "rax"); 
+	if (me->mm) 
+		read_unlock(&me->mm->context.ldtlock); 
+}
+
+#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
+static void flush_ldt(void *mm)
+{
+	if (current->mm)
+		load_LDT(&current->mm->context);
+}
+#endif
+
+static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+{
+	void *oldldt;
+	void *newldt;
+	int oldsize;
+
+	if (mincount <= pc->size)
+		return 0;
+	oldsize = pc->size;
+	mincount = (mincount+511)&(~511);
+	if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
+		newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
+	else
+		newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
+
+	if (!newldt)
+		return -ENOMEM;
+
+	if (oldsize)
+		memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
+	oldldt = pc->ldt;
+	memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
+	wmb();
+	pc->ldt = newldt;
+	pc->size = mincount;
+	if (reload) {
+		load_LDT(pc);
+#ifdef CONFIG_SMP
+		if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
+			smp_call_function(flush_ldt, 0, 1, 1);
+#endif
+	}
+	wmb();
+	if (oldsize) {
+		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
+			vfree(oldldt);
+		else
+			kfree(oldldt);
+	}
+	return 0;
+}
+
+static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+{
+	int err = alloc_ldt(new, old->size, 0);
+	if (err < 0) {
+		printk(KERN_WARNING "ldt allocation failed\n");
+		new->size = 0;
+		return err;
+	}
+	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
+	return 0;
+}
+
 /*
- * read_ldt() is not really atomic - this is not a problem since
- * synchronization of reads and writes done to the LDT has to be
- * assured by user-space anyway. Writes are atomic, to protect
- * the security checks done on new descriptors.
+ * we do not have to muck with descriptors here, that is
+ * done in switch_mm() as needed.
  */
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	struct mm_struct * old_mm;
+	int retval = 0;
+
+	init_MUTEX(&mm->context.sem);
+	mm->context.size = 0;
+	old_mm = current->mm;
+	if (old_mm && old_mm->context.size > 0) {
+		down(&old_mm->context.sem);
+		retval = copy_ldt(&mm->context, &old_mm->context);
+		up(&old_mm->context.sem);
+	}
+	rwlock_init(&mm->context.ldtlock);
+	return retval;
+}
+
+/*
+ * No need to lock the MM as we are the last user
+ */
+void release_segments(struct mm_struct *mm)
+{
+	if (mm->context.size) {
+		clear_LDT();
+		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+			vfree(mm->context.ldt);
+		else
+			kfree(mm->context.ldt);
+		mm->context.size = 0;
+	}
+}
+
 static int read_ldt(void * ptr, unsigned long bytecount)
 {
 	int err;
 	unsigned long size;
 	struct mm_struct * mm = current->mm;
 
-	err = 0;
-	if (!mm->context.segments)
-		goto out;
-
-	size = LDT_ENTRIES*LDT_ENTRY_SIZE;
+	if (!mm->context.size)
+		return 0;
+	if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+		bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
+	down(&mm->context.sem);
+	size = mm->context.size*LDT_ENTRY_SIZE;
 	if (size > bytecount)
 		size = bytecount;
 
-	err = size;
-	if (copy_to_user(ptr, mm->context.segments, size))
+	err = 0;
+	if (copy_to_user(ptr, mm->context.ldt, size))
 		err = -EFAULT;
-out:
+	up(&mm->context.sem);
+	if (err < 0)
 	return err;
+	if (size != bytecount) {
+		/* zero-fill the rest */
+		clear_user(ptr+size, bytecount-size);
+	}
+	return bytecount;
 }
 
 static int read_default_ldt(void * ptr, unsigned long bytecount)
 {
 	/* Arbitary number */ 
+	/* x86-64 default LDT is all zeros */
 	if (bytecount > 128) 
 		bytecount = 128; 	
 	if (clear_user(ptr, bytecount))
@@ -94,24 +211,14 @@
 	me->thread.gs = 0; 
 	me->thread.fs = 0; 
 
-	/*
-	 * the GDT index of the LDT is allocated dynamically, and is
-	 * limited by MAX_LDT_DESCRIPTORS.
-	 */
-	down_write(&mm->mmap_sem);
-	if (!mm->context.segments) {
-		void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
-		error = -ENOMEM;
-		if (!segments)
+	down(&mm->context.sem);
+	if (ldt_info.entry_number >= mm->context.size) {
+		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
+		if (error < 0)
 			goto out_unlock;
-		memset(segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE);
-		wmb();
-		mm->context.segments = segments;
-		mm->context.cpuvalid = 1UL << smp_processor_id();
-		load_LDT(mm);
 	}
 
-	lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.segments);
+	lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
 
    	/* Allow LDTs to be cleared by the user. */
    	if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
@@ -146,12 +253,14 @@
 
 	/* Install the new entry ...  */
 install:
+	write_lock(&mm->context.ldtlock); 
 	*lp	= entry_1;
 	*(lp+1)	= entry_2;
+	write_unlock(&mm->context.ldtlock);
 	error = 0;
 
 out_unlock:
-	up_write(&mm->mmap_sem);
+	up(&mm->context.sem);
 out:
 	return error;
 }
diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
--- a/arch/x86_64/kernel/mpparse.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/mpparse.c	Sun Jun 16 19:31:40 2002
@@ -95,42 +95,6 @@
 	return sum & 0xFF;
 }
 
-/*
- * Processor encoding in an MP configuration block
- */
-
-static char __init *mpc_family(int family,int model)
-{
-	static char n[32];
-	static char *model_defs[]=
-	{
-		"80486DX","80486DX",
-		"80486SX","80486DX/2 or 80487",
-		"80486SL","80486SX/2",
-		"Unknown","80486DX/2-WB",
-		"80486DX/4","80486DX/4-WB"
-	};
-
-	switch (family) {
-		case 0x04:
-			if (model < 10)
-				return model_defs[model];
-			break;
-
-		case 0x05:
-			return("Pentium(tm)");
-
-		case 0x06:
-			return("Pentium(tm) Pro");
-
-		case 0x0F:
-			if (model == 0x0F)
-				return("Special controller");
-	}
-	sprintf(n,"Unknown CPU [%d:%d]",family, model);
-	return n;
-}
-
 static void __init MP_processor_info (struct mpc_config_processor *m)
 {
 	int ver;
@@ -138,10 +102,10 @@
 	if (!(m->mpc_cpuflag & CPU_ENABLED))
 		return;
 
-	printk("Processor #%d %s APIC version %d\n",
+	printk("Processor #%d %d:%d APIC version %d\n",
 		m->mpc_apicid,
-		mpc_family(	(m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
-				(m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
+	       (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8,
+	       (m->mpc_cpufeature & CPU_MODEL_MASK)>>4,
 		m->mpc_apicver);
 
 	if (m->mpc_featureflag&(1<<0))
diff -Nru a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c
--- a/arch/x86_64/kernel/msr.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/msr.c	Sun Jun 16 19:31:39 2002
@@ -41,6 +41,7 @@
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/cpufeature.h>
 
 /* Note: "err" is handled in a funny way below.  Otherwise one version
    of gcc or another breaks. */
@@ -57,7 +58,7 @@
 	       "	jmp 2b\n"
 	       ".previous\n"
 	       ".section __ex_table,\"a\"\n"
-	       "	.align 4\n"
+	       "	.align 8\n"
 	       "	.quad 1b,3b\n"
 	       ".previous"
 	       : "=&bDS" (err)
@@ -236,7 +237,7 @@
   
   if ( !(cpu_online_map & (1UL << cpu)) )
     return -ENXIO;		/* No such CPU */
-  if ( !test_bit(X86_FEATURE_MSR, &c->x86_capability) )
+  if ( !cpu_has(c, X86_FEATURE_MSR) )
     return -EIO;		/* MSR not supported */
   
   return 0;
diff -Nru a/arch/x86_64/kernel/mtrr.c b/arch/x86_64/kernel/mtrr.c
--- a/arch/x86_64/kernel/mtrr.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/mtrr.c	Sun Jun 16 19:31:40 2002
@@ -139,7 +139,7 @@
 	__cli();
 
     /*  Save value of CR4 and clear Page Global Enable (bit 7)  */
-	if (test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability)) {
+	if (cpu_has_ge) {
 	 ctxt->cr4val = read_cr4();
 		write_cr4(ctxt->cr4val & ~(1UL << 7));
     }
@@ -170,7 +170,7 @@
 	write_cr0(read_cr0() & 0xbfffffff);
 
     /*  Restore value of CR4  */
-	if (test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability))
+	if (cpu_has_pge)
 		write_cr4 (ctxt->cr4val);
 
     /*  Re-enable interrupts locally (if enabled previously)  */
@@ -983,7 +983,7 @@
     char *ptr;
     char line[LINE_SIZE];
 
-	if (!capable (CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
     /*  Can't seek (pwrite) on this device  */
@@ -1071,7 +1071,7 @@
 	return -ENOIOCTLCMD;
 
       case MTRRIOC_ADD_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1083,7 +1083,7 @@
 	break;
 
       case MTRRIOC_SET_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1093,7 +1093,7 @@
 	break;
 
       case MTRRIOC_DEL_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1103,7 +1103,7 @@
 	break;
 
       case MTRRIOC_KILL_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1134,7 +1134,7 @@
 	break;
 
       case MTRRIOC_ADD_PAGE_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1146,7 +1146,7 @@
 	break;
 
       case MTRRIOC_SET_PAGE_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1156,7 +1156,7 @@
 	break;
 
       case MTRRIOC_DEL_PAGE_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1166,7 +1166,7 @@
 	break;
 
       case MTRRIOC_KILL_PAGE_ENTRY:
-		if (!capable (CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1277,7 +1277,7 @@
 {
 	printk ("mtrr: v%s)\n", MTRR_VERSION);
 
-	if (test_bit (X86_FEATURE_MTRR, &boot_cpu_data.x86_capability)) {
+	if (cpu_has_mtrr) { 
 		 /* Query the width (in bits) of the physical
 		   addressable memory on the Hammer family. */
 		if ((cpuid_eax (0x80000000) >= 0x80000008)) {
diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
--- a/arch/x86_64/kernel/nmi.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/nmi.c	Sun Jun 16 19:31:40 2002
@@ -50,15 +50,19 @@
 
 	printk(KERN_INFO "testing NMI watchdog ... ");
 
-	for (j = 0; j < NR_CPUS; ++j) 
-		counts[j] = cpu_pda[cpu_logical_map(j)].__nmi_count; 
+	for (j = 0; j < NR_CPUS; ++j) {
+		cpu = cpu_logical_map(j); 
+		counts[cpu] = cpu_pda[cpu].__nmi_count; 
+	}
 	sti();
 	mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
 	for (j = 0; j < smp_num_cpus; j++) {
 		cpu = cpu_logical_map(j);
-		if (nmi_count(cpu) - counts[j] <= 5) {
-			printk("CPU#%d: NMI appears to be stuck!\n", cpu);
+		if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
+			printk("CPU#%d: NMI appears to be stuck (%d)!\n", 
+			       cpu,
+			       cpu_pda[cpu].__nmi_count);
 			return -1;
 		}
 	}
diff -Nru a/arch/x86_64/kernel/pci-irq.c b/arch/x86_64/kernel/pci-irq.c
--- a/arch/x86_64/kernel/pci-irq.c	Sun Jun 16 19:31:40 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,833 +0,0 @@
-/*
- *	Low-Level PCI Support for PC -- Routing of Interrupts
- *
- *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/io_apic.h>
-
-#include "pci-x86_64.h"
-
-#define PIRQ_SIGNATURE	(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
-#define PIRQ_VERSION 0x0100
-
-int pci_use_acpi_routing = 0;
-
-static struct irq_routing_table *pirq_table;
-
-/*
- * Never use: 0, 1, 2 (timer, keyboard, and cascade)
- * Avoid using: 13, 14 and 15 (FP error and IDE).
- * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
- */
-unsigned int pcibios_irq_mask = 0xfff8;
-
-static int pirq_penalty[16] = {
-	1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
-	0, 0, 0, 0, 1000, 100000, 100000, 100000
-};
-
-struct irq_router {
-	char *name;
-	u16 vendor, device;
-	int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
-	int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
-};
-
-/*
- *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
- */
-
-static struct irq_routing_table * __init pirq_find_routing_table(void)
-{
-	u8 *addr;
-	struct irq_routing_table *rt;
-	int i;
-	u8 sum;
-
-	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
-		rt = (struct irq_routing_table *) addr;
-		if (rt->signature != PIRQ_SIGNATURE ||
-		    rt->version != PIRQ_VERSION ||
-		    rt->size % 16 ||
-		    rt->size < sizeof(struct irq_routing_table))
-			continue;
-		sum = 0;
-		for(i=0; i<rt->size; i++)
-			sum += addr[i];
-		if (!sum) {
-			DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
-			return rt;
-		}
-	}
-	return NULL;
-}
-
-/*
- *  If we have a IRQ routing table, use it to search for peer host
- *  bridges.  It's a gross hack, but since there are no other known
- *  ways how to get a list of buses, we have to go this way.
- *
- *  [maybe x86-64 architecture should define way to query this info in
- more reasonable way?]
- */
-
-static void __init pirq_peer_trick(void)
-{
-	struct irq_routing_table *rt = pirq_table;
-	u8 busmap[256];
-	int i;
-	struct irq_info *e;
-
-	memset(busmap, 0, sizeof(busmap));
-	for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
-		e = &rt->slots[i];
-#ifdef DEBUG
-		{
-			int j;
-			DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
-			for(j=0; j<4; j++)
-				DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
-			DBG("\n");
-		}
-#endif
-		busmap[e->bus] = 1;
-	}
-	for(i=1; i<256; i++)
-		/*
-		 *  It might be a secondary bus, but in this case its parent is already
-		 *  known (ascending bus order) and therefore pci_scan_bus returns immediately.
-		 */
-		if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
-			printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
-	pcibios_last_bus = -1;
-}
-
-/*
- *  Code for querying and setting of IRQ routes on various interrupt routers.
- */
-
-static void eisa_set_level_irq(unsigned int irq)
-{
-	unsigned char mask = 1 << (irq & 7);
-	unsigned int port = 0x4d0 + (irq >> 3);
-	unsigned char val = inb(port);
-
-	if (!(val & mask)) {
-		DBG(" -> edge");
-		outb(val | mask, port);
-	}
-}
-
-/*
- * Common IRQ routing practice: nybbles in config space,
- * offset by some magic constant.
- */
-static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr)
-{
-	u8 x;
-	unsigned reg = offset + (nr >> 1);
-
-	pci_read_config_byte(router, reg, &x);
-	return (nr & 1) ? (x >> 4) : (x & 0xf);
-}
-
-static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val)
-{
-	u8 x;
-	unsigned reg = offset + (nr >> 1);
-
-	pci_read_config_byte(router, reg, &x);
-	x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val);
-	pci_write_config_byte(router, reg, x);
-}
-
-/*
- * ALI pirq entries are damn ugly, and completely undocumented.
- * This has been figured out from pirq tables, and it's not a pretty
- * picture.
- */
-static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
-
-	return irqmap[read_config_nybble(router, 0x48, pirq-1)];
-}
-
-static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
-	unsigned int val = irqmap[irq];
-		
-	if (val) {
-		write_config_nybble(router, 0x48, pirq-1, val);
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * The Intel PIIX4 pirq rules are fairly simple: "pirq" is
- * just a pointer to the config space.
- */
-static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	u8 x;
-
-	pci_read_config_byte(router, pirq, &x);
-	return (x < 16) ? x : 0;
-}
-
-static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	pci_write_config_byte(router, pirq, irq);
-	return 1;
-}
-
-/*
- * The VIA pirq rules are nibble-based, like ALI,
- * but without the ugly irq number munging.
- */
-static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	return read_config_nybble(router, 0x55, pirq);
-}
-
-static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	write_config_nybble(router, 0x55, pirq, irq);
-	return 1;
-}
-
-/*
- * OPTI: high four bits are nibble pointer..
- * I wonder what the low bits do?
- */
-static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	return read_config_nybble(router, 0xb8, pirq >> 4);
-}
-
-static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	write_config_nybble(router, 0xb8, pirq >> 4, irq);
-	return 1;
-}
-
-/*
- * Cyrix: nibble offset 0x5C
- */
-static int pirq_cyrix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	return read_config_nybble(router, 0x5C, pirq-1);
-}
-
-static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	write_config_nybble(router, 0x5C, pirq-1, irq);
-	return 1;
-}
-
-/*
- *	PIRQ routing for SiS 85C503 router used in several SiS chipsets
- *	According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
- *	the related registers work as follows:
- *	
- *	general: one byte per re-routable IRQ,
- *		 bit 7      IRQ mapping enabled (0) or disabled (1)
- *		 bits [6:4] reserved
- *		 bits [3:0] IRQ to map to
- *		     allowed: 3-7, 9-12, 14-15
- *		     reserved: 0, 1, 2, 8, 13
- *
- *	individual registers in device config space:
- *
- *	0x41/0x42/0x43/0x44:	PCI INT A/B/C/D - bits as in general case
- *
- *	0x61:			IDEIRQ: bits as in general case - but:
- *				bits [6:5] must be written 01
- *				bit 4 channel-select primary (0), secondary (1)
- *
- *	0x62:			USBIRQ: bits as in general case - but:
- *				bit 4 OHCI function disabled (0), enabled (1)
- *	
- *	0x6a:			ACPI/SCI IRQ - bits as in general case
- *
- *	0x7e:			Data Acq. Module IRQ - bits as in general case
- *
- *	Apparently there are systems implementing PCI routing table using both
- *	link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
- *	like 0x62 as link values for USBIRQ e.g. So there is no simple
- *	"register = offset + pirq" relation.
- *	Currently we support PCI INTA..D and USBIRQ and try our best to handle
- *	both link mappings.
- *	IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
- */
-
-static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	u8 x;
-	int reg = pirq;
-
-	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-	pci_read_config_byte(router, reg, &x);
-			if (reg != 0x62)
-				break;
-			if (!(x & 0x40))
-				return 0;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
-	}
-	return (x & 0x80) ? 0 : (x & 0x0f);
-}
-
-static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	u8 x;
-	int reg = pirq;
-
-	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-			x = (irq&0x0f) ? (irq&0x0f) : 0x80;
-			if (reg != 0x62)
-				break;
-			/* always mark OHCI enabled, as nothing else knows about this */
-			x |= 0x40;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
-	}
-	pci_write_config_byte(router, reg, x);
-
-	return 1;
-}
-
-/*
- * VLSI: nibble offset 0x74 - educated guess due to routing table and
- *       config space of VLSI 82C534 PCI-bridge/router (1004:0102)
- *       Tested on HP OmniBook 800 covering PIRQ 1, 2, 4, 8 for onboard
- *       devices, PIRQ 3 for non-pci(!) soundchip and (untested) PIRQ 6
- *       for the busbridge to the docking station.
- */
-
-static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	if (pirq > 8) {
-		printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
-		return 0;
-	}
-	return read_config_nybble(router, 0x74, pirq-1);
-}
-
-static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	if (pirq > 8) {
-		printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
-		return 0;
-	}
-	write_config_nybble(router, 0x74, pirq-1, irq);
-	return 1;
-}
-
-/*
- * ServerWorks: PCI interrupts mapped to system IRQ lines through Index
- * and Redirect I/O registers (0x0c00 and 0x0c01).  The Index register
- * format is (PCIIRQ## | 0x10), e.g.: PCIIRQ10=0x1a.  The Redirect
- * register is a straight binary coding of desired PIC IRQ (low nibble).
- *
- * The 'link' value in the PIRQ table is already in the correct format
- * for the Index register.  There are some special index values:
- * 0x00 for ACPI (SCI), 0x01 for USB, 0x02 for IDE0, 0x04 for IDE1,
- * and 0x03 for SMBus.
- */
-static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	outb_p(pirq, 0xc00);
-	return inb(0xc01) & 0xf;
-}
-
-static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	outb_p(pirq, 0xc00);
-	outb_p(irq, 0xc01);
-	return 1;
-}
-
-/* Support for AMD756 PCI IRQ Routing
- * Jhon H. Caicedo <jhcaiced@osso.org.co>
- * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced)
- * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced)
- * The AMD756 pirq rules are nibble-based
- * offset 0x56 0-3 PIRQA  4-7  PIRQB
- * offset 0x57 0-3 PIRQC  4-7  PIRQD
- */
-static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	u8 irq;
-	irq = 0;
-	if (pirq <= 4)
-	{
-		irq = read_config_nybble(router, 0x56, pirq - 1);
-	}
-	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n",
-		dev->vendor, dev->device, pirq, irq);
-	return irq;
-}
-
-static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", 
-		dev->vendor, dev->device, pirq, irq);
-	if (pirq <= 4)
-	{
-		write_config_nybble(router, 0x56, pirq - 1, irq);
-	}
-	return 1;
-}
-
-#ifdef CONFIG_PCI_BIOS
-
-static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	struct pci_dev *bridge;
-	int pin = pci_get_interrupt_pin(dev, &bridge);
-	return pcibios_set_irq_routing(bridge, pin, irq);
-}
-
-static struct irq_router pirq_bios_router =
-	{ "BIOS", 0, 0, NULL, pirq_bios_set };
-
-#endif
-
-static struct irq_router pirq_routers[] = {
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, pirq_piix_get, pirq_piix_set },
-
-	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
-
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
-
-	{ "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set },
-
-	{ "NatSemi", PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, pirq_cyrix_get, pirq_cyrix_set },
-	{ "SIS", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, pirq_sis_get, pirq_sis_set },
-	{ "VLSI 82C534", PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C534, pirq_vlsi_get, pirq_vlsi_set },
-	{ "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4,
-	  pirq_serverworks_get, pirq_serverworks_set },
-	{ "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5,
-	  pirq_serverworks_get, pirq_serverworks_set },
-	{ "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
-		pirq_amd756_get, pirq_amd756_set },
-
-	{ "default", 0, 0, NULL, NULL }
-};
-
-static struct irq_router *pirq_router;
-static struct pci_dev *pirq_router_dev;
-
-static void __init pirq_find_router(void)
-{
-	struct irq_routing_table *rt = pirq_table;
-	struct irq_router *r;
-
-#ifdef CONFIG_PCI_BIOS
-	if (!rt->signature) {
-		printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n");
-		pirq_router = &pirq_bios_router;
-		return;
-	}
-#endif
-
-	DBG("PCI: Attempting to find IRQ router for %04x:%04x\n",
-	    rt->rtr_vendor, rt->rtr_device);
-
-	/* fall back to default router if nothing else found */
-	pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1];
-
-	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
-	if (!pirq_router_dev) {
-		DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
-		return;
-	}
-
-	for(r=pirq_routers; r->vendor; r++) {
-		/* Exact match against router table entry? Use it! */
-		if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) {
-			pirq_router = r;
-			break;
-		}
-		/* Match against router device entry? Use it as a fallback */
-		if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) {
-	pirq_router = r;
-		}
-	}
-	printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
-		pirq_router->name,
-		pirq_router_dev->vendor,
-		pirq_router_dev->device,
-		pirq_router_dev->slot_name);
-}
-
-static struct irq_info *pirq_get_info(struct pci_dev *dev)
-{
-	struct irq_routing_table *rt = pirq_table;
-	int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-	struct irq_info *info;
-
-	for (info = rt->slots; entries--; info++)
-		if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
-			return info;
-	return NULL;
-}
-
-static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-}
-
-#ifdef CONFIG_ACPI_PCI
-
-static int acpi_lookup_irq (
-	struct pci_dev		*dev,
-	u8			pin,
-	int			assign)
-{
-	int			result = 0;
-	int			irq = 0;
-
-	/* TBD: Select IRQ from possible to improve routing performance. */
-
-	result = acpi_prt_get_irq(dev, pin, &irq);
-	if (!irq)
-		result = -ENODEV;
-	if (0 != result) {
-		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s\n",
-		       'A'+pin, dev->slot_name);
-		return result;
-	}
-
-	dev->irq = irq;
-
-	if (!assign) {
-		/* only check for the IRQ */
-		printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", irq, 
-		       dev->slot_name);
-		return 1;
-	}
-
-	/* also assign an IRQ */
-	if (irq && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
-		result = acpi_prt_set_irq(dev, pin, irq);
-		if (0 != result) {
-			printk(KERN_WARNING "PCI: Could not assign IRQ %d to device %s\n", irq, dev->slot_name);
-			return result;
-		}
-
-		eisa_set_level_irq(irq);
-
-		printk(KERN_INFO "PCI: Assigned IRQ %d for device %s\n", irq, dev->slot_name);
-	}
-
-	return 1;
-}
-
-#endif /* CONFIG_ACPI_PCI */
-
-static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
-{
-	u8 pin;
-	struct irq_info *info;
-	int i, pirq, newirq;
-	int irq = 0;
-	u32 mask;
-	struct irq_router *r = pirq_router;
-	struct pci_dev *dev2;
-	char *msg = NULL;
-
-	/* Find IRQ pin */
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-	if (!pin) {
-		DBG(" -> no interrupt pin\n");
-		return 0;
-	}
-	pin = pin - 1;
-	
-#ifdef CONFIG_ACPI_PCI
-	/* Use ACPI to lookup IRQ */
-	if (pci_use_acpi_routing)
-		return acpi_lookup_irq(dev, pin, assign);
-#endif
-
-	/* Find IRQ routing entry */
-
-	if (!pirq_table)
-		return 0;
-	
-	DBG("IRQ for %s:%d", dev->slot_name, pin);
-	info = pirq_get_info(dev);
-	if (!info) {
-		DBG(" -> not found in routing table\n");
-		return 0;
-	}
-	pirq = info->irq[pin].link;
-	mask = info->irq[pin].bitmap;
-	if (!pirq) {
-		DBG(" -> not routed\n");
-		return 0;
-	}
-	DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
-	mask &= pcibios_irq_mask;
-
-	/*
-	 * Find the best IRQ to assign: use the one
-	 * reported by the device if possible.
-	 */
-	newirq = dev->irq;
-	if (!((1 << newirq) & mask)) {
-		if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
-		else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, dev->slot_name);
-	}
-	if (!newirq && assign) {
-		for (i = 0; i < 16; i++) {
-			if (!(mask & (1 << i)))
-				continue;
-			if (pirq_penalty[i] < pirq_penalty[newirq] &&
-			    !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ, "pci-test", dev)) {
-				free_irq(i, dev);
-				newirq = i;
-			}
-		}
-	}
-	DBG(" -> newirq=%d", newirq);
-
-	/* Check if it is hardcoded */
-	if ((pirq & 0xf0) == 0xf0) {
-		irq = pirq & 0xf;
-		DBG(" -> hardcoded IRQ %d\n", irq);
-		msg = "Hardcoded";
-	} else if ( r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
-	((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) {
-		DBG(" -> got IRQ %d\n", irq);
-		msg = "Found";
-	} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
-		DBG(" -> assigning IRQ %d", newirq);
-		if (r->set(pirq_router_dev, dev, pirq, newirq)) {
-			eisa_set_level_irq(newirq);
-			DBG(" ... OK\n");
-			msg = "Assigned";
-			irq = newirq;
-		}
-	}
-
-	if (!irq) {
-		DBG(" ... failed\n");
-		if (newirq && mask == (1 << newirq)) {
-			msg = "Guessed";
-			irq = newirq;
-		} else
-			return 0;
-	}
-	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
-
-	/* Update IRQ for all devices with the same pirq value */
-	pci_for_each_dev(dev2) {
-		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
-		if (!pin)
-			continue;
-		pin--;
-		info = pirq_get_info(dev2);
-		if (!info)
-			continue;
-		if (info->irq[pin].link == pirq) {
-			/* We refuse to override the dev->irq information. Give a warning! */
-		    	if ( dev2->irq && dev2->irq != irq && \
-			(!(pci_probe & PCI_USE_PIRQ_MASK) || \
-			((1 << dev2->irq) & mask)) ) {
-		    		printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
-				       dev2->slot_name, dev2->irq, irq);
-		    		continue;
-		    	}
-			dev2->irq = irq;
-			pirq_penalty[irq]++;
-			if (dev != dev2)
-				printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, dev2->slot_name);
-		}
-	}
-	return 1;
-}
-
-void __init pcibios_irq_init(void)
-{
-	DBG("PCI: IRQ init\n");
-
-#ifdef CONFIG_ACPI_PCI
-	if (!(pci_probe & PCI_NO_ACPI_ROUTING)) {
-		if (acpi_prts.count) {
-			printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
-			pci_use_acpi_routing = 1;
-			return;
-		}
-		else
-			printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
-	}
-#endif
-
-	pirq_table = pirq_find_routing_table();
-
-#ifdef CONFIG_PCI_BIOS
-	if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
-		pirq_table = pcibios_get_irq_routing_table();
-#endif
-	if (pirq_table) {
-		pirq_peer_trick();
-		pirq_find_router();
-		if (pirq_table->exclusive_irqs) {
-			int i;
-			for (i=0; i<16; i++)
-				if (!(pirq_table->exclusive_irqs & (1 << i)))
-					pirq_penalty[i] += 100;
-		}
-		/* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
-		if (io_apic_assign_pci_irqs)
-			pirq_table = NULL;
-	}
-}
-
-void __init pcibios_fixup_irqs(void)
-{
-	struct pci_dev *dev;
-	u8 pin;
-
-	DBG("PCI: IRQ fixup\n");
-	pci_for_each_dev(dev) {
-		/*
-		 * If the BIOS has set an out of range IRQ number, just ignore it.
-		 * Also keep track of which IRQ's are already in use.
-		 */
-		if (dev->irq >= 16) {
-			DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
-			dev->irq = 0;
-		}
-		/* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
-		if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000)
-			pirq_penalty[dev->irq] = 0;
-		pirq_penalty[dev->irq]++;
-	}
-
-	pci_for_each_dev(dev) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-#ifdef CONFIG_X86_IO_APIC
-		/*
-		 * Recalculate IRQ numbers if we use the I/O APIC.
-		 */
-		if (io_apic_assign_pci_irqs)
-		{
-			int irq;
-
-			if (pin) {
-				pin--;		/* interrupt pins are numbered starting from 1 */
-				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-	/*
-	 * Busses behind bridges are typically not listed in the MP-table.
-	 * In this case we have to look up the IRQ based on the parent bus,
-	 * parent slot, and pin number. The SMP code detects such bridged
-	 * busses itself so we should get into this branch reliably.
-	 */
-				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
-					struct pci_dev * bridge = dev->bus->self;
-
-					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
-							PCI_SLOT(bridge->devfn), pin);
-					if (irq >= 0)
-						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
-							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
-				}
-				if (irq >= 0) {
-					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
-						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
-					dev->irq = irq;
-				}
-			}
-		}
-#endif
-		/*
-		 * Still no IRQ? Try to lookup one...
-		 */
-		if (pin && !dev->irq)
-			pcibios_lookup_irq(dev, 0);
-	}
-}
-
-void pcibios_penalize_isa_irq(int irq)
-{
-	/*
-	 *  If any ISAPnP device reports an IRQ in its list of possible
-	 *  IRQ's, we try to avoid assigning it to PCI devices.
-	 */
-	pirq_penalty[irq] += 100;
-}
-
-void pcibios_enable_irq(struct pci_dev *dev)
-{
-		u8 pin;
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-	if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
-			char *msg;
-			if (io_apic_assign_pci_irqs)
-				msg = " Probably buggy MP table.";
-			else if (pci_probe & PCI_BIOS_IRQ_SCAN)
-				msg = "";
-			else
-				msg = " Please try using pci=biosirq.";
-			printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
-			       'A' + pin - 1, dev->slot_name, msg);
-	}
-}
diff -Nru a/arch/x86_64/kernel/pci-pc.c b/arch/x86_64/kernel/pci-pc.c
--- a/arch/x86_64/kernel/pci-pc.c	Sun Jun 16 19:31:39 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,447 +0,0 @@
-/*
- *	Low-Level PCI Support for PC
- *
- *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
- * 	2001 Andi Kleen. Cleanup for x86-64. Removed PCI-BIOS access and fixups
- *	for hardware that is unlikely to exist on any Hammer platform.
- * 
- * 	On x86-64 we don't have any access to the PCI-BIOS in long mode, so we
- *	cannot sort the pci device table based on what the BIOS did. This might 
- *	change the probing order of some devices compared to an i386 kernel.
- * 	May need to use ACPI to fix this.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-
-#include "pci-x86_64.h"
-
-unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
-
-int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus;
-struct pci_ops *pci_root_ops;
-
-/*
- * Direct access to PCI hardware...
- */
-
-#ifdef CONFIG_PCI_DIRECT
-
-/*
- * Functions for accessing PCI configuration space with type 1 accesses
- */
-
-#define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
-
-static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
-{
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	*value = inb(0xCFC + (where&3));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
-	outl(CONFIG_CMD(dev,where), 0xCF8);    
-	*value = inw(0xCFC + (where&2));
-	return PCIBIOS_SUCCESSFUL;    
-}
-
-static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	*value = inl(0xCFC);
-	return PCIBIOS_SUCCESSFUL;    
-}
-
-static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
-	outl(CONFIG_CMD(dev,where), 0xCF8);    
-	outb(value, 0xCFC + (where&3));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
-{
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	outw(value, 0xCFC + (where&2));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	outl(value, 0xCFC);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-#undef CONFIG_CMD
-
-static struct pci_ops pci_direct_conf1 = {
-	pci_conf1_read_config_byte,
-	pci_conf1_read_config_word,
-	pci_conf1_read_config_dword,
-	pci_conf1_write_config_byte,
-	pci_conf1_write_config_word,
-	pci_conf1_write_config_dword
-};
-
-/*
- * Functions for accessing PCI configuration space with type 2 accesses
- */
-
-#define IOADDR(devfn, where)	((0xC000 | ((devfn & 0x78) << 5)) + where)
-#define FUNC(devfn)		(((devfn & 7) << 1) | 0xf0)
-#define SET(dev)		if (dev->devfn & 0x80) return PCIBIOS_DEVICE_NOT_FOUND;		\
-				outb(FUNC(dev->devfn), 0xCF8);					\
-				outb(dev->bus->number, 0xCFA);
-
-static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
-{
-	SET(dev);
-	*value = inb(IOADDR(dev->devfn,where));
-	outb (0, 0xCF8);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf2_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
-	SET(dev);
-	*value = inw(IOADDR(dev->devfn,where));
-	outb (0, 0xCF8);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
-	SET(dev);
-	*value = inl (IOADDR(dev->devfn,where));    
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
-	SET(dev);
-	outb (value, IOADDR(dev->devfn,where));
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf2_write_config_word(struct pci_dev *dev, int where, u16 value)
-{
-	SET(dev);
-	outw (value, IOADDR(dev->devfn,where));
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_conf2_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
-	SET(dev);
-	outl (value, IOADDR(dev->devfn,where));    
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
-}
-
-#undef SET
-#undef IOADDR
-#undef FUNC
-
-static struct pci_ops pci_direct_conf2 = {
-	pci_conf2_read_config_byte,
-	pci_conf2_read_config_word,
-	pci_conf2_read_config_dword,
-	pci_conf2_write_config_byte,
-	pci_conf2_write_config_word,
-	pci_conf2_write_config_dword
-};
-
-/*
- * Before we decide to use direct hardware access mechanisms, we try to do some
- * trivial checks to ensure it at least _seems_ to be working -- we just test
- * whether bus 00 contains a host bridge (this is similar to checking
- * techniques used in XFree86, but ours should be more reliable since we
- * attempt to make use of direct access hints provided by the PCI BIOS).
- *
- * This should be close to trivial, but it isn't, because there are buggy
- * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
- */
-static int __devinit pci_sanity_check(struct pci_ops *o)
-{
-	u16 x;
-	struct pci_bus bus;		/* Fake bus and device */
-	struct pci_dev dev;
-
-	if (pci_probe & PCI_NO_CHECKS)
-		return 1;
-	bus.number = 0;
-	dev.bus = &bus;
-	for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++)
-		if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) &&
-		     (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
-		    (!o->read_word(&dev, PCI_VENDOR_ID, &x) &&
-		     (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
-			return 1;
-	DBG("PCI: Sanity check failed\n");
-	return 0;
-}
-
-static struct pci_ops * __devinit pci_check_direct(void)
-{
-	unsigned int tmp;
-	unsigned long flags;
-
-	__save_flags(flags); __cli();
-
-	/*
-	 * Check if configuration type 1 works.
-	 */
-	if (pci_probe & PCI_PROBE_CONF1) {
-		outb (0x01, 0xCFB);
-		tmp = inl (0xCF8);
-		outl (0x80000000, 0xCF8);
-		if (inl (0xCF8) == 0x80000000 &&
-		    pci_sanity_check(&pci_direct_conf1)) {
-			outl (tmp, 0xCF8);
-			__restore_flags(flags);
-			printk("PCI: Using configuration type 1\n");
-			request_region(0xCF8, 8, "PCI conf1");
-			return &pci_direct_conf1;
-		}
-		outl (tmp, 0xCF8);
-	}
-
-	/*
-	 * Check if configuration type 2 works.
-	 */
-	if (pci_probe & PCI_PROBE_CONF2) {
-		outb (0x00, 0xCFB);
-		outb (0x00, 0xCF8);
-		outb (0x00, 0xCFA);
-		if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 &&
-		    pci_sanity_check(&pci_direct_conf2)) {
-			__restore_flags(flags);
-			printk("PCI: Using configuration type 2\n");
-			request_region(0xCF8, 4, "PCI conf2");
-			return &pci_direct_conf2;
-		}
-	}
-
-	__restore_flags(flags);
-	return NULL;
-}
-
-#endif
-
-
-/*
- * Several buggy motherboards address only 16 devices and mirror
- * them to next 16 IDs. We try to detect this `feature' on all
- * primary buses (those containing host bridges as they are
- * expected to be unique) and remove the ghost devices.
- */
-
-static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
-{
-	struct list_head *ln, *mn;
-	struct pci_dev *d, *e;
-	int mirror = PCI_DEVFN(16,0);
-	int seen_host_bridge = 0;
-	int i;
-
-	DBG("PCI: Scanning for ghost devices on bus %d\n", b->number);
-	for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
-		d = pci_dev_b(ln);
-		if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
-			seen_host_bridge++;
-		for (mn=ln->next; mn != &b->devices; mn=mn->next) {
-			e = pci_dev_b(mn);
-			if (e->devfn != d->devfn + mirror ||
-			    e->vendor != d->vendor ||
-			    e->device != d->device ||
-			    e->class != d->class)
-				continue;
-			for(i=0; i<PCI_NUM_RESOURCES; i++)
-				if (e->resource[i].start != d->resource[i].start ||
-				    e->resource[i].end != d->resource[i].end ||
-				    e->resource[i].flags != d->resource[i].flags)
-					continue;
-			break;
-		}
-		if (mn == &b->devices)
-			return;
-	}
-	if (!seen_host_bridge)
-		return;
-	printk("PCI: Ignoring ghost devices on bus %02x\n", b->number);
-
-	ln = &b->devices;
-	while (ln->next != &b->devices) {
-		d = pci_dev_b(ln->next);
-		if (d->devfn >= mirror) {
-			list_del(&d->global_list);
-			list_del(&d->bus_list);
-			kfree(d);
-		} else
-			ln = ln->next;
-	}
-}
-
-/*
- * Discover remaining PCI buses in case there are peer host bridges.
- * We use the number of last PCI bus provided by the PCI BIOS.
- */
-static void __devinit pcibios_fixup_peer_bridges(void)
-{
-	int n;
-	struct pci_bus bus;
-	struct pci_dev dev;
-	u16 l;
-
-	if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
-		return;
-	DBG("PCI: Peer bridge fixup\n");
-	for (n=0; n <= pcibios_last_bus; n++) {
-		if (pci_bus_exists(&pci_root_buses, n))
-			continue;
-		bus.number = n;
-		bus.ops = pci_root_ops;
-		dev.bus = &bus;
-		for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
-			if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
-			    l != 0x0000 && l != 0xffff) {
-				DBG("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
-				printk("PCI: Discovered peer bus %02x\n", n);
-				pci_scan_bus(n, pci_root_ops, NULL);
-				break;
-			}
-	}
-}
-
-struct pci_fixup pcibios_fixups[] = {
-	/* Currently no fixup for hammer systems. May need to readd them
-		as needed. */ 
-	{ 0 }
-};
-
-/*
- *  Called after each bus is probed, but before its children
- *  are examined.
- */
-
-void __devinit pcibios_fixup_bus(struct pci_bus *b)
-{
-	pcibios_fixup_ghosts(b);
-	pci_read_bridge_bases(b);
-}
-
-/*
- * Initialization. Try all known PCI access methods. Note that we support
- * using both PCI BIOS and direct access: in such cases, we use I/O ports
- * to access config space, but we still keep BIOS order of cards to be
- * compatible with 2.0.X. This should go away some day.
- */
-
-void __devinit pcibios_init(void)
-{
-	struct pci_ops *bios = NULL;
-	struct pci_ops *dir = NULL;
-
-#ifdef CONFIG_PCI_DIRECT
-	if (pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2))
-		dir = pci_check_direct();
-#endif
-	if (dir)
-		pci_root_ops = dir;
-	else if (bios)
-		pci_root_ops = bios;
-	else {
-		printk("PCI: No PCI bus detected\n");
-		return;
-	}
-
-	printk("PCI: Probing PCI hardware\n");
-	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
-
-	pcibios_irq_init();
-	pcibios_fixup_peer_bridges();
-	pcibios_fixup_irqs();
-	pcibios_resource_survey();
-
-}
-
-char * __devinit pcibios_setup(char *str)
-{
-	if (!strcmp(str, "off")) {
-		pci_probe = 0;
-		return NULL;
-	}
-	else if (!strncmp(str, "bios", 4)) {
-		printk("PCI: No PCI bios access on x86-64. BIOS hint ignored.\n");
-		return NULL;
-	} else if (!strcmp(str, "nobios")) {
-		pci_probe &= ~PCI_PROBE_BIOS;
-		return NULL;
-	} else if (!strcmp(str, "nosort")) { /* Default */ 
-		pci_probe |= PCI_NO_SORT;
-		return NULL;
-	} 
-#ifdef CONFIG_PCI_DIRECT
-	else if (!strcmp(str, "conf1")) {
-		pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
-		return NULL;
-	}
-	else if (!strcmp(str, "conf2")) {
-		pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
-		return NULL;
-	}
-#endif
-#ifdef CONFIG_ACPI_PCI
-	else if (!strcmp(str, "noacpi")) {
-		pci_probe |= PCI_NO_ACPI_ROUTING;
-		return NULL;
-	}
-#endif
-	else if (!strcmp(str, "rom")) {
-		pci_probe |= PCI_ASSIGN_ROMS;
-		return NULL;
-	} else if (!strcmp(str, "assign-busses")) {
-		pci_probe |= PCI_ASSIGN_ALL_BUSSES;
-		return NULL;
-	} else if (!strncmp(str, "irqmask=", 8)) {
-		pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
-		return NULL;
-	} else if (!strncmp(str, "lastbus=", 8)) {
-		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
-		return NULL;
-	} else if (!strcmp(str, "usepirqmask")) { 
-		pci_probe |= PCI_USE_PIRQ_MASK;
-		return NULL;
-	}
-	return str;
-}
-
-unsigned int pcibios_assign_all_busses(void)
-{
-	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
-}
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
-	int err;
-
-	if ((err = pcibios_enable_resources(dev)) < 0)
-		return err;
-	pcibios_enable_irq(dev);
-	return 0;
-}
diff -Nru a/arch/x86_64/kernel/pci-x86_64.c b/arch/x86_64/kernel/pci-x86_64.c
--- a/arch/x86_64/kernel/pci-x86_64.c	Sun Jun 16 19:31:41 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,385 +0,0 @@
-/*
- *	Low-Level PCI Access for x86-64 machines
- *
- * Copyright 1993, 1994 Drew Eckhardt
- *      Visionary Computing
- *      (Unix and Linux consulting and custom programming)
- *      Drew@Colorado.EDU
- *      +1 (303) 786-7975
- *
- * Drew's work was sponsored by:
- *	iX Multiuser Multitasking Magazine
- *	Hannover, Germany
- *	hm@ix.de
- *
- * Copyright 1997--2000 Martin Mares <mj@ucw.cz>
- *
- * For more information, please consult the following manuals (look at
- * http://www.pcisig.com/ for how to get them):
- *
- * PCI BIOS Specification
- * PCI Local Bus Specification
- * PCI to PCI Bridge Specification
- * PCI System Design Guide
- *
- *
- * CHANGELOG :
- * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
- *	Revision 2.0 present on <thys@dennis.ee.up.ac.za>'s ASUS mainboard.
- *
- * Jan 5,  1995 : Modified to probe PCI hardware at boot time by Frederic
- *     Potter, potter@cao-vlsi.ibp.fr
- *
- * Jan 10, 1995 : Modified to store the information about configured pci
- *      devices into a list, which can be accessed via /proc/pci by
- *      Curtis Varner, cvarner@cs.ucr.edu
- *
- * Jan 12, 1995 : CPU-PCI bridge optimization support by Frederic Potter.
- *	Alpha version. Intel & UMC chipset support only.
- *
- * Apr 16, 1995 : Source merge with the DEC Alpha PCI support. Most of the code
- *	moved to drivers/pci/pci.c.
- *
- * Dec 7, 1996  : Added support for direct configuration access of boards
- *      with Intel compatible access schemes (tsbogend@alpha.franken.de)
- *
- * Feb 3, 1997  : Set internal functions to static, save/restore flags
- *	avoid dead locks reading broken PCI BIOS, werner@suse.de 
- *
- * Apr 26, 1997 : Fixed case when there is BIOS32, but not PCI BIOS
- *	(mj@atrey.karlin.mff.cuni.cz)
- *
- * May 7,  1997 : Added some missing cli()'s. [mj]
- * 
- * Jun 20, 1997 : Corrected problems in "conf1" type accesses.
- *      (paubert@iram.es)
- *
- * Aug 2,  1997 : Split to PCI BIOS handling and direct PCI access parts
- *	and cleaned it up...     Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- *
- * Feb 6,  1998 : No longer using BIOS to find devices and device classes. [mj]
- *
- * May 1,  1998 : Support for peer host bridges. [mj]
- *
- * Jun 19, 1998 : Changed to use spinlocks, so that PCI configuration space
- *	can be accessed from interrupts even on SMP systems. [mj]
- *
- * August  1998 : Better support for peer host bridges and more paranoid
- *	checks for direct hardware access. Ugh, this file starts to look as
- *	a large gallery of common hardware bug workarounds (watch the comments)
- *	-- the PCI specs themselves are sane, but most implementors should be
- *	hit hard with \hammer scaled \magstep5. [mj]
- *
- * Jan 23, 1999 : More improvements to peer host bridge logic. i450NX fixup. [mj]
- *
- * Feb 8,  1999 : Added UM8886BF I/O address fixup. [mj]
- *
- * August  1999 : New resource management and configuration access stuff. [mj]
- *
- * Sep 19, 1999 : Use PCI IRQ routing tables for detection of peer host bridges.
- *		  Based on ideas by Chris Frantz and David Hinds. [mj]
- *
- * Sep 28, 1999 : Handle unreported/unassigned IRQs. Thanks to Shuu Yamaguchi
- *		  for a lot of patience during testing. [mj]
- *
- * Oct  8, 1999 : Split to pci-i386.c, pci-pc.c and pci-visws.c. [mj]
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-
-#include "pci-x86_64.h"
-
-void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			struct resource *res, int resource)
-{
-	u32 new, check;
-	int reg;
-
-	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
-	if (resource < 6) {
-		reg = PCI_BASE_ADDRESS_0 + 4*resource;
-	} else if (resource == PCI_ROM_RESOURCE) {
-		res->flags |= PCI_ROM_ADDRESS_ENABLE;
-		new |= PCI_ROM_ADDRESS_ENABLE;
-		reg = dev->rom_base_reg;
-	} else {
-		/* Somebody might have asked allocation of a non-standard resource */
-		return;
-	}
-	
-	pci_write_config_dword(dev, reg, new);
-	pci_read_config_dword(dev, reg, &check);
-	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
-		printk(KERN_ERR "PCI: Error while updating region "
-		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
-		       new, check);
-	}
-}
-
-/*
- * We need to avoid collisions with `mirrored' VGA ports
- * and other strange ISA hardware, so we always want the
- * addresses to be allocated in the 0x000-0x0ff region
- * modulo 0x400.
- *
- * Why? Because some silly external IO cards only decode
- * the low 10 bits of the IO address. The 0x00-0xff region
- * is reserved for motherboard devices that decode all 16
- * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
- * but we want to try to avoid allocating at 0x2900-0x2bff
- * which might have be mirrored at 0x0100-0x03ff..
- */
-void
-pcibios_align_resource(void *data, struct resource *res,
-		       unsigned long size, unsigned long align)
-{
-	if (res->flags & IORESOURCE_IO) {
-		unsigned long start = res->start;
-
-		if (start & 0x300) {
-			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	}
-}
-
-
-/*
- *  Handle resources of PCI devices.  If the world were perfect, we could
- *  just allocate all the resource regions and do nothing more.  It isn't.
- *  On the other hand, we cannot just re-allocate all devices, as it would
- *  require us to know lots of host bridge internals.  So we attempt to
- *  keep as much of the original configuration as possible, but tweak it
- *  when it's found to be wrong.
- *
- *  Known BIOS problems we have to work around:
- *	- I/O or memory regions not configured
- *	- regions configured, but not enabled in the command register
- *	- bogus I/O addresses above 64K used
- *	- expansion ROMs left enabled (this may sound harmless, but given
- *	  the fact the PCI specs explicitly allow address decoders to be
- *	  shared between expansion ROMs and other resource regions, it's
- *	  at least dangerous)
- *
- *  Our solution:
- *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
- *	    This gives us fixed barriers on where we can allocate.
- *	(2) Allocate resources for all enabled devices.  If there is
- *	    a collision, just mark the resource as unallocated. Also
- *	    disable expansion ROMs during this step.
- *	(3) Try to allocate resources for disabled devices.  If the
- *	    resources were assigned correctly, everything goes well,
- *	    if they weren't, they won't disturb allocation of other
- *	    resources.
- *	(4) Assign new addresses to resources which were either
- *	    not configured at all or misconfigured.  If explicitly
- *	    requested by the user, configure expansion ROM address
- *	    as well.
- */
-
-static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
-{
-	struct list_head *ln;
-	struct pci_bus *bus;
-	struct pci_dev *dev;
-	int idx;
-	struct resource *r, *pr;
-
-	/* Depth-First Search on bus tree */
-	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
-		bus = pci_bus_b(ln);
-		if ((dev = bus->self)) {
-			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
-				r = &dev->resource[idx];
-				if (!r->start)
-					continue;
-				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0)
-					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
-			}
-		}
-		pcibios_allocate_bus_resources(&bus->children);
-	}
-}
-
-static void __init pcibios_allocate_resources(int pass)
-{
-	struct pci_dev *dev;
-	int idx, disabled;
-	u16 command;
-	struct resource *r, *pr;
-
-	pci_for_each_dev(dev) {
-		pci_read_config_word(dev, PCI_COMMAND, &command);
-		for(idx = 0; idx < 6; idx++) {
-			r = &dev->resource[idx];
-			if (r->parent)		/* Already allocated */
-				continue;
-			if (!r->start)		/* Address not assigned at all */
-				continue;
-			if (r->flags & IORESOURCE_IO)
-				disabled = !(command & PCI_COMMAND_IO);
-			else
-				disabled = !(command & PCI_COMMAND_MEMORY);
-			if (pass == disabled) {
-				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
-				    r->start, r->end, r->flags, disabled, pass);
-				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0) {
-					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
-					/* We'll assign a new address later */
-					r->end -= r->start;
-					r->start = 0;
-				}
-			}
-		}
-		if (!pass) {
-			r = &dev->resource[PCI_ROM_RESOURCE];
-			if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
-				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
-				u32 reg;
-				DBG("PCI: Switching off ROM of %s\n", dev->slot_name);
-				r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
-				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
-				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
-			}
-		}
-	}
-}
-
-static void __init pcibios_assign_resources(void)
-{
-	struct pci_dev *dev;
-	int idx;
-	struct resource *r;
-
-	pci_for_each_dev(dev) {
-		int class = dev->class >> 8;
-
-		/* Don't touch classless devices and host bridges */
-		if (!class || class == PCI_CLASS_BRIDGE_HOST)
-			continue;
-
-		for(idx=0; idx<6; idx++) {
-			r = &dev->resource[idx];
-
-			/*
-			 *  Don't touch IDE controllers and I/O ports of video cards!
-			 */
-			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
-			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
-				continue;
-
-			/*
-			 *  We shall assign a new address to this resource, either because
-			 *  the BIOS forgot to do so or because we have decided the old
-			 *  address was unusable for some reason.
-			 */
-			if (!r->start && r->end)
-				pci_assign_resource(dev, idx);
-		}
-
-		if (pci_probe & PCI_ASSIGN_ROMS) {
-			r = &dev->resource[PCI_ROM_RESOURCE];
-			r->end -= r->start;
-			r->start = 0;
-			if (r->end)
-				pci_assign_resource(dev, PCI_ROM_RESOURCE);
-		}
-	}
-}
-
-void __init pcibios_resource_survey(void)
-{
-	DBG("PCI: Allocating resources\n");
-	pcibios_allocate_bus_resources(&pci_root_buses);
-	pcibios_allocate_resources(0);
-	pcibios_allocate_resources(1);
-	pcibios_assign_resources();
-}
-
-int pcibios_enable_resources(struct pci_dev *dev)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for(idx=0; idx<6; idx++) {
-		r = &dev->resource[idx];
-		if (!r->start && r->end) {
-			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
-	if (cmd != old_cmd) {
-		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-}
-
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
-int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-			enum pci_mmap_state mmap_state, int write_combine)
-{
-	unsigned long prot;
-
-	/* I/O space cannot be accessed via normal processor loads and
-	 * stores on this platform.
-	 */
-	if (mmap_state == pci_mmap_io)
-		return -EINVAL;
-
-	/* Leave vm_pgoff as-is, the PCI space address is the physical
-	 * address on this platform.
-	 */
-	vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
-
-	prot = pgprot_val(vma->vm_page_prot);
-	if (boot_cpu_data.x86 > 3)
-		prot |= _PAGE_PCD | _PAGE_PWT;
-	vma->vm_page_prot = __pgprot(prot);
-
-	/* Write-combine setting is ignored, it is changed via the mtrr
-	 * interfaces on this platform.
-	 */
-	if (remap_page_range(vma, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
-			     vma->vm_end - vma->vm_start,
-			     vma->vm_page_prot))
-		return -EAGAIN;
-
-	return 0;
-}
diff -Nru a/arch/x86_64/kernel/pci-x86_64.h b/arch/x86_64/kernel/pci-x86_64.h
--- a/arch/x86_64/kernel/pci-x86_64.h	Sun Jun 16 19:31:40 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,76 +0,0 @@
-/*
- *	Low-Level PCI Access for i386 machines.
- *
- *	(c) 1999 Martin Mares <mj@ucw.cz>
- */
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#define PCI_PROBE_BIOS		0x0001
-#define PCI_PROBE_CONF1		0x0002
-#define PCI_PROBE_CONF2		0x0004
-#define PCI_NO_SORT		0x0100
-#define PCI_BIOS_SORT		0x0200
-#define PCI_NO_CHECKS		0x0400
-#define PCI_USE_PIRQ_MASK	0x0800
-#define PCI_ASSIGN_ROMS		0x1000
-#define PCI_BIOS_IRQ_SCAN	0x2000
-#define PCI_ASSIGN_ALL_BUSSES	0x4000
-#define PCI_NO_ACPI_ROUTING	0x8000
-
-extern unsigned int pci_probe;
-
-/* pci-i386.c */
-
-extern unsigned int pcibios_max_latency;
-
-void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *);
-
-/* pci-pc.c */
-
-extern int pcibios_last_bus;
-extern struct pci_bus *pci_root_bus;
-extern struct pci_ops *pci_root_ops;
-
-struct irq_routing_table *pcibios_get_irq_routing_table(void);
-int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
-
-/* pci-irq.c */
-
-struct irq_info {
-	u8 bus, devfn;			/* Bus, device and function */
-	struct {
-		u8 link;		/* IRQ line ID, chipset dependent, 0=not routed */
-		u16 bitmap;		/* Available IRQs */
-	} __attribute__((packed)) irq[4];
-	u8 slot;			/* Slot number, 0=onboard */
-	u8 rfu;
-} __attribute__((packed));
-
-struct irq_routing_table {
-	u32 signature;			/* PIRQ_SIGNATURE should be here */
-	u16 version;			/* PIRQ_VERSION */
-	u16 size;			/* Table size in bytes */
-	u8 rtr_bus, rtr_devfn;		/* Where the interrupt router lies */
-	u16 exclusive_irqs;		/* IRQs devoted exclusively to PCI usage */
-	u16 rtr_vendor, rtr_device;	/* Vendor and device ID of interrupt router */
-	u32 miniport_data;		/* Crap */
-	u8 rfu[11];
-	u8 checksum;			/* Modulo 256 checksum must give zero */
-	struct irq_info slots[0];
-} __attribute__((packed));
-
-extern unsigned int pcibios_irq_mask;
-
-extern int pci_use_acpi_routing;
-
-void pcibios_irq_init(void);
-void pcibios_fixup_irqs(void);
-void pcibios_enable_irq(struct pci_dev *dev);
diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/process.c	Sun Jun 16 19:31:39 2002
@@ -57,6 +57,8 @@
 
 asmlinkage extern void ret_from_fork(void);
 
+unsigned long kernel_thread_flags = CLONE_VM;
+
 int hlt_counter;
 
 /*
@@ -318,44 +320,11 @@
 	printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
 }
 
-/*
- * No need to lock the MM as we are the last user
- */
-void release_segments(struct mm_struct *mm)
-{
-	void * ldt = mm->context.segments;
-
-	/*
-	 * free the LDT
-	 */
-	if (ldt) {
-		mm->context.segments = NULL;
-		clear_LDT();
-		vfree(ldt);
-	}
-}
-
-void load_gs_index(unsigned gs)
-{
-	int access; 
-	/* should load gs in syscall exit after swapgs instead */ 
-	/* XXX need to add LDT locking for SMP to protect against parallel changes */ 
-	asm volatile("pushf\n\t" 
-		     "cli\n\t"
-		     "swapgs\n\t"
-		     "lar %1,%0\n\t"
-		     "jnz 1f\n\t"
-		     "movl %1,%%eax\n\t"
-		     "movl %%eax,%%gs\n\t"
-		     "jmp 2f\n\t"
-		     "1: movl %2,%%gs\n\t"
-		     "2: swapgs\n\t"
-		     "popf" : "=g" (access) : "g" (gs), "r" (0) : "rax"); 
-}
-	
 #define __STR(x) #x
 #define __STR2(x) __STR(x)
 
+extern void load_gs_index(unsigned);
+
 /*
  * Free current thread data structures etc..
  */
@@ -379,41 +348,14 @@
 void release_thread(struct task_struct *dead_task)
 {
 	if (dead_task->mm) {
-		void * ldt = dead_task->mm->context.segments;
-
-		// temporary debugging check
-		if (ldt) {
-			printk("WARNING: dead process %8s still has LDT? <%p>\n",
-					dead_task->comm, ldt);
+		if (dead_task->mm->context.size) {
+			printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
+					dead_task->comm,
+					dead_task->mm->context.ldt,
+					dead_task->mm->context.size);
 			BUG();
 		}
 	}
-}
-
-/*
- * we do not have to muck with descriptors here, that is
- * done in switch_mm() as needed.
- */
-void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
-{
-	struct mm_struct * old_mm;
-	void *old_ldt, *ldt;
- 
-	ldt = NULL;
-	old_mm = current->mm;
-	if (old_mm && (old_ldt = old_mm->context.segments) != NULL) {
-		/*
-		 * Completely new LDT, we initialize it from the parent:
-		 */
-		ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
-		if (!ldt)
-			printk(KERN_WARNING "ldt allocation failed\n");
-		else
-			memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
-	}
-	new_mm->context.segments = ldt;
-	new_mm->context.cpuvalid = 0UL;
-	return;
 }
 
 int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, 
diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/setup.c	Sun Jun 16 19:31:39 2002
@@ -28,7 +28,6 @@
 #include <linux/delay.h>
 #include <linux/config.h>
 #include <linux/init.h>
-#include <linux/apm_bios.h>
 #ifdef CONFIG_BLK_DEV_RAM
 #include <linux/blk.h>
 #endif
@@ -37,6 +36,7 @@
 #include <asm/processor.h>
 #include <linux/console.h>
 #include <linux/seq_file.h>
+#include <linux/root_dev.h>
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -65,6 +65,8 @@
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0x10000000;
 
+unsigned long saved_video_mode;
+
 /*
  * Setup options
  */
@@ -545,15 +547,18 @@
 
 unsigned long start_pfn, end_pfn; 
 
+extern void exception_table_check(void);
+
 void __init setup_arch(char **cmdline_p)
 {
 	unsigned long bootmap_size, low_mem_size;
 	int i;
 
- 	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
+ 	ROOT_DEV = ORIG_ROOT_DEV;
  	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
 	aux_device_present = AUX_DEVICE_INFO;
+	saved_video_mode = SAVED_VIDEO_MODE;
 
 #ifdef CONFIG_BLK_DEV_RAM
 	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
@@ -782,6 +787,8 @@
 	conswitchp = &dummy_con;
 #endif
 #endif
+
+	exception_table_check(); 
 }
 
 #ifndef CONFIG_X86_TSC
@@ -1092,7 +1099,7 @@
 	else
 		seq_printf(m, "stepping\t: unknown\n");
 	
-	if ( test_bit(X86_FEATURE_TSC, &c->x86_capability) ) {
+	if (cpu_has(c,X86_FEATURE_TSC)) {
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
 			     cpu_khz / 1000, (cpu_khz % 1000));
 	}
diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/setup64.c	Sun Jun 16 19:31:40 2002
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
+#include <linux/bootmem.h>
 #include <asm/pda.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -31,42 +32,64 @@
 
 extern struct task_struct init_task;
 
+extern unsigned char __per_cpu_start[], __per_cpu_end[]; 
+
 struct desc_ptr gdt_descr = { 0 /* filled in */, (unsigned long) gdt_table }; 
 struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; 
 
 char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned;
 
+void __init setup_per_cpu_areas(void)
+{ 
+	unsigned long size, i;
+	unsigned char *ptr;
+
+	/* Copy section for each CPU (we discard the original) */
+	size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
+	if (!size)
+		return;
+
+	ptr = alloc_bootmem(size * NR_CPUS);
+
+	for (i = 0; i < NR_CPUS; i++, ptr += size) {
+		cpu_pda[cpu_logical_map(i)].cpudata_offset = ptr - __per_cpu_start;
+		memcpy(ptr, __per_cpu_start, size);
+	}
+} 
+
 void pda_init(int cpu)
 { 
         pml4_t *level4;
+	struct x8664_pda *pda = &cpu_pda[cpu];
 
 	if (cpu == 0) {
 		/* others are initialized in smpboot.c */
-		cpu_pda[cpu].pcurrent = &init_task;
-		cpu_pda[cpu].irqstackptr = boot_cpu_stack; 
+		pda->pcurrent = &init_task;
+		pda->irqstackptr = boot_cpu_stack; 
 		level4 = init_level4_pgt; 
 	} else {
-		cpu_pda[cpu].irqstackptr = (char *)
+		pda->irqstackptr = (char *)
 			__get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
-		if (!cpu_pda[cpu].irqstackptr)
+		if (!pda->irqstackptr)
 			panic("cannot allocate irqstack for cpu %d\n", cpu); 
 		level4 = (pml4_t *)__get_free_pages(GFP_ATOMIC, 0); 
 	}
 	if (!level4) 
 		panic("Cannot allocate top level page for cpu %d", cpu); 
 
-	cpu_pda[cpu].level4_pgt = (unsigned long *)level4; 
+	pda->level4_pgt = (unsigned long *)level4; 
 	if (level4 != init_level4_pgt)
 		memcpy(level4, &init_level4_pgt, PAGE_SIZE); 
 	set_pml4(level4 + 510, mk_kernel_pml4(__pa_symbol(boot_vmalloc_pgt)));
 	asm volatile("movq %0,%%cr3" :: "r" (__pa(level4))); 
 
-	cpu_pda[cpu].irqstackptr += IRQSTACKSIZE-64;
-	cpu_pda[cpu].cpunumber = cpu; 
-	cpu_pda[cpu].irqcount = -1;
-	cpu_pda[cpu].kernelstack = 
+	pda->irqstackptr += IRQSTACKSIZE-64;
+	pda->cpunumber = cpu; 
+	pda->irqcount = -1;
+	pda->kernelstack = 
 		(unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; 
-	cpu_pda[cpu].me = &cpu_pda[cpu];
+	pda->me = pda;
+	pda->cpudata_offset = 0;
 
 	asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); 
 	wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
@@ -75,7 +98,6 @@
 #define EXCEPTION_STK_ORDER 0 /* >= N_EXCEPTION_STACKS*EXCEPTION_STKSZ */
 char boot_exception_stacks[N_EXCEPTION_STACKS*EXCEPTION_STKSZ];
 
-
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -93,6 +115,7 @@
 	struct tss_struct * t = &init_tss[nr];
 	unsigned long v; 
 	char *estacks; 
+	struct task_struct *me;
 
 	/* CPU 0 is initialised in head64.c */
 	if (nr != 0) {
@@ -103,6 +126,8 @@
 	} else 
 		estacks = boot_exception_stacks; 
 
+	me = current;
+
 	if (test_and_set_bit(nr, &cpu_initialized))
 		panic("CPU#%d already initialized!\n", nr);
 
@@ -150,14 +175,14 @@
 	}
 
 	atomic_inc(&init_mm.mm_count);
-	current->active_mm = &init_mm;
-	if(current->mm)
+	me->active_mm = &init_mm;
+	if (me->mm)
 		BUG();
-	enter_lazy_tlb(&init_mm, current, nr);
+	enter_lazy_tlb(&init_mm, me, nr);
 
 	set_tss_desc(nr, t);
 	load_TR(nr);
-	load_LDT(&init_mm);
+	load_LDT(&init_mm.context);
 
 	/*
 	 * Clear all 6 debug registers:
diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/signal.c	Sun Jun 16 19:31:39 2002
@@ -22,10 +22,8 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
-#include <linux/tty.h>
 #include <linux/personality.h>
 #include <linux/compiler.h>
-#include <linux/binfmts.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
@@ -86,7 +84,7 @@
 	char *pretcode;
 	struct ucontext uc;
 	struct siginfo info;
-	struct _fpstate fpstate __attribute__((aligned(8)));
+	struct _fpstate fpstate;
 };
 
 static int
@@ -126,6 +124,7 @@
 	{
 		struct _fpstate * buf;
 		err |= __get_user(buf, &sc->fpstate);
+
 		if (buf) {
 			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
 				goto badframe;
@@ -147,10 +146,12 @@
 	stack_t st;
 	long eax;
 
-	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame))) { 
 		goto badframe;
-	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+	} 
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) { 
 		goto badframe;
+	} 
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
@@ -158,15 +159,17 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sigmask_lock);
 	
-	if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax))
+	if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax)) { 
 		goto badframe;
+	} 
 
 #if DEBUG_SIG
 	printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax);
 #endif
 
-	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) {
 		goto badframe;
+	} 
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
 	do_sigaltstack(&st, NULL, regs.rsp);
@@ -174,10 +177,7 @@
 	return eax;
 
 badframe:
-#if DEBUG_SIG
-	printk("%d bad frame %p\n",current->pid,frame);
-#endif
-	force_sig(SIGSEGV, current);
+	signal_fault(&regs,frame,"sigreturn");
 	return 0;
 }	
 
@@ -233,8 +233,8 @@
 /*
  * Determine which stack to use..
  */
-static inline void *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+static inline struct rt_sigframe *
+get_sigframe(struct k_sigaction *ka, struct pt_regs * regs)
 {
 	unsigned long rsp;
 
@@ -247,15 +247,10 @@
 			rsp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
-	{ 
-		extern void bad_sigframe(void); 
-		/* beginning of sigframe is 8 bytes misaligned, but fpstate
-		   must end up on a 16byte boundary */ 
-		if ((offsetof(struct rt_sigframe, fpstate) & 16) != 0) 
-			bad_sigframe(); 		
-	} 
+	rsp = (rsp - sizeof(struct _fpstate)) & ~(15UL); 
+	rsp -= offsetof(struct rt_sigframe, fpstate);
 
-	return (void *)((rsp - frame_size) & ~(15UL)) - 8;
+	return (struct rt_sigframe *) rsp; 
 }
 
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -264,16 +259,17 @@
 	struct rt_sigframe *frame;
 	int err = 0;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, regs);
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
 
 	if (ka->sa.sa_flags & SA_SIGINFO) { 
 		err |= copy_siginfo_to_user(&frame->info, info);
-		if (err)
+		if (err) { 
 			goto give_sigsegv;
 	}
+	}
 		
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->uc.uc_flags);
@@ -285,9 +281,10 @@
 	err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
 			        regs, set->sig[0]);
 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
-	if (err)
-		goto give_sigsegv;
 
+	if (err) { 
+		goto give_sigsegv;
+	} 
 
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
@@ -299,8 +296,10 @@
 		goto give_sigsegv; 
 	}
 
-	if (err)
+	if (err) { 
+		printk("fault 3\n"); 
 		goto give_sigsegv;
+	} 
 
 #if DEBUG_SIG
 	printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax);
@@ -337,7 +336,7 @@
 give_sigsegv:
 	if (sig == SIGSEGV)
 		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	signal_fault(regs,frame,"signal setup");
 }
 
 /*
@@ -459,3 +458,15 @@
 	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(regs,oldset);
 }
+
+extern int exception_trace;
+
+void signal_fault(struct pt_regs *regs, void *frame, char *where)
+{ 
+	struct task_struct *me = current; 
+	if (exception_trace)
+		printk("%s[%d] bad frame in %s frame:%p rip:%lx rsp:%lx orax:%lx\n",
+	       me->comm,me->pid,where,frame,regs->rip,regs->rsp,regs->orig_rax); 
+
+	force_sig(SIGSEGV, me); 
+} 
diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/smp.c	Sun Jun 16 19:31:39 2002
@@ -150,6 +150,7 @@
 	if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
 		BUG();
 	clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
+	__flush_tlb();
 }
 
 /*
@@ -200,10 +201,12 @@
 
 asmlinkage void smp_invalidate_interrupt (void)
 {
-	unsigned long cpu = smp_processor_id();
+	unsigned long cpu;
+
+	cpu = get_cpu();
 
 	if (!test_bit(cpu, &flush_cpumask))
-		return;
+		goto out;
 		/* 
 		 * This was a BUG() but until someone can quote me the
 		 * line from the intel manual that guarantees an IPI to
@@ -224,6 +227,9 @@
 	}
 	ack_APIC_irq();
 	clear_bit(cpu, &flush_cpumask);
+
+out:
+	put_cpu();
 }
 
 static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
@@ -273,16 +279,23 @@
 void flush_tlb_current_task(void)
 {
 	struct mm_struct *mm = current->mm;
-	unsigned long cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
+	unsigned long cpu_mask;
+
+	preempt_disable();
+	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
 
 	local_flush_tlb();
 	if (cpu_mask)
 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+	preempt_enable();
 }
 
 void flush_tlb_mm (struct mm_struct * mm)
 {
-	unsigned long cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
+	unsigned long cpu_mask;
+
+	preempt_disable();
+	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
 
 	if (current->active_mm == mm) {
 		if (current->mm)
@@ -292,12 +305,17 @@
 	}
 	if (cpu_mask)
 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+
+	preempt_enable();
 }
 
 void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
+	unsigned long cpu_mask;
+
+	preempt_disable();
+	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
 
 	if (current->active_mm == mm) {
 		if(current->mm)
@@ -308,6 +326,8 @@
 
 	if (cpu_mask)
 		flush_tlb_others(cpu_mask, mm, va);
+
+	preempt_enable();
 }
 
 static inline void do_flush_tlb_all_local(void)
diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c	Sun Jun 16 19:31:41 2002
+++ b/arch/x86_64/kernel/smpboot.c	Sun Jun 16 19:31:41 2002
@@ -50,9 +50,6 @@
 #include <asm/kdebug.h>
 #include <asm/tlbflush.h>
 
-/* Set if we find a B stepping CPU			*/
-static int smp_b_stepping;
-
 /* Setup configured maximum number of CPUs to activate */
 static int max_cpus = -1;
 
@@ -151,17 +148,6 @@
 
 	*c = boot_cpu_data;
 	identify_cpu(c);
-	/*
-	 * Mask B, Pentium, but not Pentium MMX
-	 */
-	if (c->x86_vendor == X86_VENDOR_INTEL &&
-	    c->x86 == 5 &&
-	    c->x86_mask >= 1 && c->x86_mask <= 4 &&
-	    c->x86_model <= 3)
-		/*
-		 * Remember we have B step Pentia with bugs
-		 */
-		smp_b_stepping = 1;
 }
 
 /*
@@ -772,7 +758,7 @@
 static void smp_tune_scheduling (void)
 {
 	unsigned long cachesize;       /* kB   */
-	unsigned long bandwidth = 350; /* MB/s */
+	unsigned long bandwidth = 1000; /* MB/s */
 	/*
 	 * Rough estimation for SMP scheduling, this is the number of
 	 * cycles it takes for a fully memory-limited process to flush
@@ -883,8 +869,7 @@
 	/*
 	 * If we couldn't find a local APIC, then get out of here now!
 	 */
-	if (APIC_INTEGRATED(apic_version[boot_cpu_id]) &&
-	    !test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability)) {
+	if (APIC_INTEGRATED(apic_version[boot_cpu_id]) && !cpu_has_apic) {
 		printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
 			boot_cpu_id);
 		printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
@@ -965,7 +950,7 @@
 
 	Dprintk("Before bogomips.\n");
 	if (!cpucount) {
-		printk(KERN_ERR "Error: only one processor found.\n");
+		printk(KERN_INFO "Only one processor found.\n");
 	} else {
 		unsigned long bogosum = 0;
 		for (cpu = 0; cpu < NR_CPUS; cpu++)
@@ -979,8 +964,6 @@
 	}
 	smp_num_cpus = cpucount + 1;
 
-	if (smp_b_stepping)
-		printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
 	Dprintk("Boot done.\n");
 
 	/*
diff -Nru a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
--- a/arch/x86_64/kernel/sys_x86_64.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/kernel/sys_x86_64.c	Sun Jun 16 19:31:40 2002
@@ -14,6 +14,7 @@
 #include <linux/mman.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
+#include <linux/personality.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -22,7 +23,7 @@
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way Unix traditionally does this, though.
  */
-asmlinkage long sys_pipe(unsigned long * fildes)
+asmlinkage long sys_pipe(int *fildes)
 {
 	int fd[2];
 	int error;
@@ -93,18 +94,15 @@
 	}
 }
 
-/*
- * Old cruft
- */
-asmlinkage long sys_uname(struct old_utsname * name)
+asmlinkage long sys_uname(struct new_utsname * name)
 {
 	int err;
-	if (!name)
-		return -EFAULT;
 	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, &system_utsname, sizeof (*name));
 	up_read(&uts_sem);
-	return err?-EFAULT:0;
+	if (current->personality == PER_LINUX32) 
+		err |= copy_to_user(&name->machine, "i386", 5); 		
+	return err ? -EFAULT : 0;
 }
 
 asmlinkage long sys_pause(void)
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c	Sun Jun 16 19:31:41 2002
+++ b/arch/x86_64/kernel/time.c	Sun Jun 16 19:31:41 2002
@@ -41,6 +41,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/smp.h>
+#include <linux/device.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -57,12 +58,8 @@
 
 #include <asm/fixmap.h>
 
-/*
- * for x86_do_profile()
- */
 #include <linux/irq.h>
 
-
 unsigned int cpu_khz;	/* Detected as we calibrate the TSC */
 
 /* Number of usecs that the last interrupt was delayed */
@@ -79,9 +76,9 @@
 
 extern rwlock_t xtime_lock;
 struct timeval __xtime __section_xtime;
-volatile unsigned long __jiffies __section_jiffies;
 unsigned long __wall_jiffies __section_wall_jiffies;
 struct timezone __sys_tz __section_sys_tz;
+volatile unsigned long __jiffies __section_jiffies;
  
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 
@@ -527,3 +524,15 @@
 
 	setup_irq(0, &irq0);
 }
+
+static struct device device_i8253 = {
+       name:           "i8253",
+       bus_id:         "0040",
+};
+
+static int time_init_driverfs(void)
+{
+       return register_sys_device(&device_i8253);
+}
+
+__initcall(time_init_driverfs);
diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/traps.c	Sun Jun 16 19:31:39 2002
@@ -77,7 +77,7 @@
 asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void call_debug(void);
 
-extern char iret_address[];
+extern int exception_trace;
 
 struct notifier_block *die_chain;
 
@@ -172,6 +172,8 @@
 	i = 1;
 	if (stack >= irqstack && stack < irqstack_end) {
 		unsigned long *tstack;
+
+		printk("<IRQ> ");  
 		while (stack < irqstack_end) {
 			addr = *stack++;
 			/*
@@ -197,13 +199,11 @@
 		tstack = (unsigned long *)(current_thread_info()+1);
 		if (stack < tstack || (char*)stack > (char*)tstack+THREAD_SIZE) 
 			printk("\n" KERN_DEBUG 
-		       "no stack at the end of irqstack; stack:%lx, curstack %lx\n",
+		       "no stack at the end of irqstack; stack:%p, curstack %p\n",
 			       stack, tstack); 
 #endif			       
 	} 
 
-	
-
 	while (((long) stack & (THREAD_SIZE-1)) != 0) {
 		addr = *stack++;
 		if (kernel_text_address(addr)) { 	 
@@ -263,7 +263,7 @@
 void show_registers(struct pt_regs *regs)
 {
 	int i;
-	int in_kernel = 1;
+	int in_kernel = (regs->cs & 3) == 0;
 	unsigned long rsp;
 #ifdef CONFIG_SMP
 	/* For SMP should get the APIC id here, just to protect against corrupted GS */ 
@@ -273,11 +273,8 @@
 #endif	
 	struct task_struct *cur = cpu_pda[cpu].pcurrent; 
 
-	rsp = (unsigned long) (&regs->rsp);
-	if (regs->rsp < TASK_SIZE) {
-		in_kernel = 0;
 		rsp = regs->rsp;
-	}
+
 	printk("CPU %d ", cpu);
 	show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
@@ -383,7 +380,7 @@
 	if ((regs->cs & 3)  != 0) { 
 		struct task_struct *tsk = current;
 
-		if (trapnr != 3)
+		if (exception_trace && trapnr != 3)
 			printk("%s[%d] trap %s at rip:%lx rsp:%lx err:%lx\n",
 		       tsk->comm, tsk->pid, str, regs->rip, regs->rsp, error_code);
 
@@ -456,9 +453,14 @@
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
 	if ((regs->cs & 3)!=0) { 
-	current->thread.error_code = error_code;
-	current->thread.trap_no = 13;
-	force_sig(SIGSEGV, current);
+		struct task_struct *tsk = current;
+		if (exception_trace)
+			printk("%s[%d] #gp at rip:%lx rsp:%lx err:%lx\n",
+			       tsk->comm, tsk->pid, regs->rip, regs->rsp, error_code);
+
+		tsk->thread.error_code = error_code;
+		tsk->thread.trap_no = 13;
+		force_sig(SIGSEGV, tsk);
 	return;
 	} 
 
@@ -509,8 +511,7 @@
 {
 	unsigned char reason = inb(0x61);
 
-
-	++nmi_count(smp_processor_id());
+	add_pda(__nmi_count,1);
 	if (!(reason & 0xc0)) {
 #if CONFIG_X86_LOCAL_APIC
 		/*
diff -Nru a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
--- a/arch/x86_64/kernel/vsyscall.c	Sun Jun 16 19:31:41 2002
+++ b/arch/x86_64/kernel/vsyscall.c	Sun Jun 16 19:31:41 2002
@@ -47,14 +47,14 @@
 
 #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
 
-//#define NO_VSYSCALL 1
+#define NO_VSYSCALL 1
 
 #ifdef NO_VSYSCALL
 #include <asm/unistd.h>
 
 static int errno __section_vxtime_sequence; 
 
-__syscall2(static inline int,int,gettimeofday,struct timeval *,tv,struct timezone *,tz)
+static inline _syscall2(int,gettimeofday,struct timeval *,tv,struct timezone *,tz)
 
 #else
 static inline void timeval_normalize(struct timeval * tv)
@@ -148,28 +148,11 @@
 
 static time_t __vsyscall(1) vtime(time_t * t)
 {
-#ifdef NO_VSYSCALL
 	struct timeval tv; 
-	gettimeofday(&tv,NULL); 
-	if (t) *t = tv.tv_sec; 
-	return tv.tv_sec; 
-#else
-	long sequence;
-	time_t __time;
-
-	do {
-		sequence = __vxtime_sequence[1];
-		rmb();
-
-		__time = __xtime.tv_sec;
-
-		rmb();
-	} while (sequence != __vxtime_sequence[0]);
-
+	vgettimeofday(&tv,NULL); 
 	if (t)
-		*t = __time;
-	return __time;
-#endif
+		*t = tv.tv_sec; 
+	return tv.tv_sec;
 }
 
 static long __vsyscall(2) venosys_0(void)
diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
--- a/arch/x86_64/kernel/x8664_ksyms.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/kernel/x8664_ksyms.c	Sun Jun 16 19:31:39 2002
@@ -88,8 +88,9 @@
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(clear_user);
 EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(__generic_copy_from_user);
-EXPORT_SYMBOL(__generic_copy_to_user);
+EXPORT_SYMBOL(copy_user_generic);
+EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(copy_to_user);
 EXPORT_SYMBOL(strnlen_user);
 
 EXPORT_SYMBOL(pci_alloc_consistent);
diff -Nru a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
--- a/arch/x86_64/lib/Makefile	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/lib/Makefile	Sun Jun 16 19:31:39 2002
@@ -1,11 +1,21 @@
 #
-# Makefile for x86_64-specific library files..
+# Makefile for x86_64-specific library files.
 #
 
+USE_STANDARD_AS_RULE := true
+
+EXTRA_CFLAGS_csum-partial.o := -funroll-loops
+
 L_TARGET = lib.a
-obj-y  = generic-checksum.o old-checksum.o delay.o \
+obj-y  = csum-partial.o csum-copy.o csum-wrappers.o delay.o \
 	usercopy.o getuser.o putuser.o  \
-	checksum_copy.o thunk.o mmx.o
+	thunk.o io.o clear_page.o copy_page.o
+obj-y += memcpy.o
+obj-y += memmove.o
+#obj-y += memset.o
+obj-y += copy_user.o
+
+export-objs := io.o csum-wrappers.o csum-partial.o
 
 obj-$(CONFIG_IO_DEBUG) += iodebug.o
 obj-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff -Nru a/arch/x86_64/lib/checksum_copy.S b/arch/x86_64/lib/checksum_copy.S
--- a/arch/x86_64/lib/checksum_copy.S	Sun Jun 16 19:31:40 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,142 +0,0 @@
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		IP/TCP/UDP checksumming routines
- *
- * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
- *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- *		Tom May, <ftom@netcom.com>
- *              Pentium Pro/II routines:
- *              Alexander Kjeldaas <astor@guardian.no>
- *              Finn Arne Gangstad <finnag@guardian.no>
- *		Lots of code moved from tcp.c and ip.c; see those files
- *		for more names.
- *
- * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
- *			     handling.
- *		Andi Kleen,  add zeroing on error
- *                   converted to pure assembler
- *              Andi Kleen   initial raw port to x86-64
- *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <asm/errno.h>
-
-
-/* Version for PentiumII/PPro ported to x86-64. Still very raw and
-   does not exploit 64bit.  */ 	
-
-#define SRC(y...)			\
-	9999: y;			\
-	.section __ex_table, "a";	\
-	.quad 9999b, 6001f	;	\
-	.previous
-
-#define DST(y...)			\
-	9999: y;			\
-	.section __ex_table, "a";	\
-	.quad 9999b, 6002f	;	\
-	.previous
-	
-#define ROUND1(x) \
-	SRC(movl x(%rsi), %ebx	)	;	\
-	addl %ebx, %eax			;	\
-	DST(movl %ebx, x(%rdi)	)	;
-
-#define ROUND(x) \
-	SRC(movl x(%rsi), %ebx	)	;	\
-	adcl %ebx, %eax			;	\
-	DST(movl %ebx, x(%rdi)	)	;
-
-#define ARGBASE 0
-
-/*
-	asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
-	                                                   int *src_err_ptr, int *dst_err_ptr);
-	rdi .. src
-	rsi .. dst	(copy in r12)
-	rdx .. len	(copy in r10)
-	rcx .. sum
-	r8 ..  src_err_ptr
-	r9 ..  dst_err_ptr
-
-	OPTIMIZEME: this routine should take advantage of checksumming 64bits at a time
-*/
-
-	.globl csum_partial_copy_generic		
-csum_partial_copy_generic:
-	pushq %r10
-	pushq %r12
-	pushq %rbx
-	pushq %rbp
-	xchgq %rsi, %rdi
-
-	movq %rdx, %r10
-	movq %rsi, %r12
-	
-	movq %rcx, %rax
-	movq %rdx, %rcx	# And now it looks like PII case
-	movl %ecx, %ebx
-	movl %esi, %edx
-	shrl $6, %ecx
-	andl $0x3c, %ebx
-	negq %rbx
-	subq %rbx, %rsi
-	subq %rbx, %rdi
-	lea 3f(%rbx,%rbx), %rbx
-	testq %rsi, %rsi
-	jmp *%rbx
-1:	addq $64,%rsi
-	addq $64,%rdi
-	ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)	
-	ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)	
-	ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)	
-	ROUND (-16) ROUND(-12) ROUND(-8)  ROUND(-4)	
-3:	adcl $0,%eax
-	addl $64,%edx
-	dec %ecx
-	jge 1b
-4:      movq %r10,%rdx
-	andl $3, %edx
-	jz 7f
-	cmpl $2, %edx
-	jb 5f
-SRC(	movw (%rsi), %dx         )
-	leaq 2(%rsi), %rsi
-DST(	movw %dx, (%rdi)         )
-	leaq 2(%rdi), %rdi
-	je 6f
-	shll $16,%edx
-5:
-SRC(	movb (%rsi), %dl         )
-DST(	movb %dl, (%rdi)         )
-6:	addl %edx, %eax
-	adcl $0, %eax
-7:
-.section .fixup, "ax"
-6001:	
-	movl $-EFAULT, (%r8)
-	# zero the complete destination (computing the rest is too much work)
-	movq %r12,%rdi	# dst
-	movq %r10,%rcx	# len
-	xorl %eax,%eax
-	rep; stosb
-	jmp 7b
-6002:	movl $-EFAULT,(%r9)
-	jmp  7b			
-.previous
-	popq %rbp
-	popq %rbx
-	popq %r12
-	popq %r10
-	ret
-				
-#undef ROUND
-#undef ROUND1
diff -Nru a/arch/x86_64/lib/clear_page.S b/arch/x86_64/lib/clear_page.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/clear_page.S	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ */		 
+	
+	#include <linux/linkage.h>
+
+/*
+ * Zero a page. 	
+ * rdi	page
+ */			
+ENTRY(clear_page)
+	xorl   %eax,%eax
+	movl   $4096/128,%ecx
+	movl   $128,%edx
+loop:
+#define PUT(x) movnti %rax,x*8(%rdi) 
+	PUT(0)
+	PUT(1)
+	PUT(2)
+	PUT(3)
+	PUT(4)
+	PUT(5)
+	PUT(6)
+	PUT(7)
+	PUT(8)
+	PUT(9)
+	PUT(10)
+	PUT(11)
+	PUT(12)
+	PUT(13)
+	PUT(14)
+	PUT(15)
+	addq    %rdx,%rdi
+	decl	%ecx
+	jnz	loop
+	sfence	
+	ret
+	    	
diff -Nru a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/copy_page.S	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ */	 	
+	#include <linux/linkage.h>
+	#include <linux/config.h>
+	#ifdef CONFIG_PREEMPT
+	#warning "check your fpu context saving!"
+	#endif
+
+/*
+ * Copy a page. 
+ *		
+ * rdi destination page
+ * rsi source page
+ *		
+ * src/dst must be aligned to 16 bytes.
+ * 
+ * Warning: in case of super lazy FP save this needs to be preempt_stop	
+ */
+	
+ENTRY(copy_page)
+	prefetchnta (%rsi) 
+	prefetchnta 64(%rsi)
+	    
+	movq %rsp,%rax
+	subq $16*4,%rsp
+	andq $~15,%rsp		
+	movdqa %xmm0,(%rsp) 
+	movdqa %xmm1,16(%rsp) 
+	movdqa %xmm2,32(%rsp) 
+	movdqa %xmm3,48(%rsp)
+	
+	movl   $(4096/128)-2,%ecx
+	movl   $128,%edx
+loop:
+	prefetchnta (%rsi) 
+	prefetchnta 64(%rsi) 
+loop_no_prefetch:	
+	movdqa (%rsi),%xmm0 	 			 
+	movdqa 1*16(%rsi),%xmm1
+	movdqa 2*16(%rsi),%xmm2 	 			 
+	movdqa 3*16(%rsi),%xmm3 	 			 
+	movntdq %xmm0,(%rdi)	 
+	movntdq %xmm1,16(%rdi)	 
+	movntdq %xmm2,2*16(%rdi)	 
+	movntdq %xmm3,3*16(%rdi)
+	
+	movdqa 4*16(%rsi),%xmm0 	 			 
+	movdqa 5*16(%rsi),%xmm1
+	movdqa 6*16(%rsi),%xmm2 	 			 
+	movdqa 7*16(%rsi),%xmm3 	 			 
+	movntdq %xmm0,4*16(%rdi)	 
+	movntdq %xmm1,5*16(%rdi)	 
+	movntdq %xmm2,6*16(%rdi)	 
+	movntdq %xmm3,7*16(%rdi)
+
+	addq   %rdx,%rdi	
+	addq   %rdx,%rsi
+	decl   %ecx
+	jns    loop
+	cmpl   $-1,%ecx
+	je     loop_no_prefetch
+	
+	sfence
+
+	movdqa (%rsp),%xmm0
+	movdqa 16(%rsp),%xmm1
+	movdqa 32(%rsp),%xmm2
+	movdqa 48(%rsp),%xmm3
+	movq   %rax,%rsp
+	ret
diff -Nru a/arch/x86_64/lib/copy_user.S b/arch/x86_64/lib/copy_user.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/copy_user.S	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,230 @@
+/* Copyright 2002 Andi Kleen, SuSE Labs.
+ * Subject to the GNU Public License v2.
+ * 
+ * Functions to copy from and to user space.		
+ */		 
+
+#define FIX_ALIGNMENT 1
+		
+	#include <asm/thread_info.h>
+	#include <asm/offset.h>
+
+/* Standard copy_to_user with segment limit checking */		
+	.globl copy_to_user
+	.p2align 	
+copy_to_user:
+	GET_THREAD_INFO(%rax)
+	movq %rdi,%rcx
+	addq %rdx,%rcx
+	jc  bad_to_user
+	cmpq threadinfo_addr_limit(%rax),%rcx
+	jae bad_to_user
+	jmp copy_user_generic
+
+/* Standard copy_from_user with segment limit checking */	
+	.globl copy_from_user
+	.p2align 	
+copy_from_user:
+	GET_THREAD_INFO(%rax)
+	movq %rsi,%rcx
+	addq %rdx,%rcx
+	jc  bad_from_user
+	cmpq threadinfo_addr_limit(%rax),%rcx
+	jae  bad_from_user
+	/* FALL THROUGH to copy_user_generic */
+	
+	.section .fixup,"ax"
+	/* must zero dest */
+bad_from_user:
+	movl %edx,%ecx
+	xorl %eax,%eax
+	rep
+	stosb
+bad_to_user:
+	movl	%edx,%eax
+	ret
+	.previous
+	
+/*
+ * copy_user_generic - memory copy with exception handling.
+ * 	
+ * Input:	
+ * rdi destination
+ * rsi source
+ * rdx count
+ *
+ * Output:		
+ * eax uncopied bytes or 0 if successfull. 
+ */
+	.globl copy_user_generic	
+copy_user_generic:	
+	/* Put the first cacheline into cache. This should handle
+	   the small movements in ioctls etc., but not penalize the bigger
+	   filesystem data copies too much. */
+	pushq %rbx
+	prefetcht0 (%rsi)
+	xorl %eax,%eax		/*zero for the exception handler */
+
+#ifdef FIX_ALIGNMENT
+	/* check for bad alignment of destination */
+	movl %edi,%ecx
+	andl $7,%ecx
+	jnz  bad_alignment
+after_bad_alignment:
+#endif
+
+	movq %rdx,%rcx
+
+	movl $64,%ebx	
+	shrq $6,%rdx
+	decq %rdx
+	js   handle_tail
+	jz   loop_no_prefetch
+	
+loop:
+	prefetchnta 64(%rsi)
+	
+loop_no_prefetch:	
+s1:	movq (%rsi),%r11
+s2:	movq 1*8(%rsi),%r8
+s3:	movq 2*8(%rsi),%r9
+s4:	movq 3*8(%rsi),%r10
+d1:	movnti %r11,(%rdi)
+d2:	movnti %r8,1*8(%rdi)
+d3:	movnti %r9,2*8(%rdi)
+d4:	movnti %r10,3*8(%rdi)
+		
+s5:	movq 4*8(%rsi),%r11
+s6:	movq 5*8(%rsi),%r8
+s7:	movq 6*8(%rsi),%r9
+s8:	movq 7*8(%rsi),%r10
+d5:	movnti %r11,4*8(%rdi)
+d6:	movnti %r8,5*8(%rdi)
+d7:	movnti %r9,6*8(%rdi)
+d8:	movnti %r10,7*8(%rdi)
+
+	addq %rbx,%rsi	
+	addq %rbx,%rdi
+	
+	decq %rdx
+	jz   loop_no_prefetch
+	jns  loop
+
+handle_tail:
+	movl %ecx,%edx
+	andl $63,%ecx
+	shrl $3,%ecx
+	jz   handle_7
+	movl $8,%ebx
+loop_8:
+s9:	movq (%rsi),%r8
+d9:	movnti %r8,(%rdi)
+	addq %rbx,%rdi
+	addq %rbx,%rsi
+	loop loop_8
+	
+handle_7:		
+	movl %edx,%ecx	
+	andl $7,%ecx
+	jz   ende
+loop_1:
+s10:	movb (%rsi),%bl
+d10:	movb %bl,(%rdi)
+	incq %rdi
+	incq %rsi
+	loop loop_1
+			
+ende:
+	sfence
+	popq %rbx
+	ret	
+
+#ifdef FIX_ALIGNMENT		  		
+	/* align destination */
+bad_alignment:
+	movl $8,%r9d
+	subl %ecx,%r9d
+	movl %r9d,%ecx
+	subq %r9,%rdx
+	jz   small_align
+	js   small_align
+align_1:		
+s11:	movb (%rsi),%bl
+d11:	movb %bl,(%rdi)
+	incq %rsi
+	incq %rdi
+	loop align_1
+	jmp after_bad_alignment
+small_align:
+	addq %r9,%rdx
+	jmp handle_7
+#endif
+	
+	/* table sorted by exception address */	
+	.section __ex_table,"a"
+	.align 8
+	.quad s1,s1e
+	.quad s2,s2e
+	.quad s3,s3e
+	.quad s4,s4e	
+	.quad d1,s1e
+	.quad d2,s2e
+	.quad d3,s3e
+	.quad d4,s4e
+	.quad s5,s5e
+	.quad s6,s6e
+	.quad s7,s7e
+	.quad s8,s8e	
+	.quad d5,s5e
+	.quad d6,s6e
+	.quad d7,s7e
+	.quad d8,s8e
+	.quad s9,e_quad
+	.quad d9,e_quad
+	.quad s10,e_byte
+	.quad d10,e_byte
+#ifdef FIX_ALIGNMENT	
+	.quad s11,e_byte
+	.quad d11,e_byte
+#endif
+	.quad e5,e_zero
+	.previous
+
+	/* compute 64-offset for main loop. 8 bytes accuracy with error on the 
+	   pessimistic side. this is gross. it would be better to fix the 
+	   interface. */	
+	/* eax: zero, ebx: 64 */
+s1e: 	addl $8,%eax
+s2e: 	addl $8,%eax
+s3e: 	addl $8,%eax
+s4e: 	addl $8,%eax
+s5e: 	addl $8,%eax
+s6e: 	addl $8,%eax
+s7e: 	addl $8,%eax
+s8e: 	addl $8,%eax
+	addq %rbx,%rdi	/* +64 */
+	subq %rax,%rdi  /* correct destination with computed offset */
+
+	shlq $6,%rdx	/* loop counter * 64 (stride length) */
+	addq %rax,%rdx	/* add offset to loopcnt */
+	andl $63,%ecx	/* remaining bytes */
+	addq %rcx,%rdx	/* add them */
+	jmp zero_rest
+
+	/* exception on quad word loop in tail handling */
+	/* ecx:	loopcnt/8, %edx: length, rdi: correct */
+e_quad:
+	shll $3,%ecx
+	andl $7,%edx
+	addl %ecx,%edx
+	/* edx: bytes to zero, rdi: dest, eax:zero */
+zero_rest:
+	movq %rdx,%rcx
+e_byte:
+	xorl %eax,%eax
+e5:	rep 
+	stosb
+	/* when there is another exception while zeroing the rest just return */
+e_zero:		
+	movq %rdx,%rax
+	jmp ende
diff -Nru a/arch/x86_64/lib/csum-copy.S b/arch/x86_64/lib/csum-copy.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/csum-copy.S	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2002 Andi Kleen
+ *	
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details. No warranty for anything given at all.
+ */
+ 	#include <linux/linkage.h>
+	#include <asm/errno.h>
+
+//	#define FIX_ALIGNMENT 1
+/*
+ * Checksum copy with exception handling.
+ * On exceptions src_err_ptr or dst_err_ptr is set to -EFAULT and the 
+ * destination is zeroed.
+ * 
+ * Input
+ * rdi  source
+ * rsi  destination
+ * edx  len (32bit)
+ * ecx  sum (32bit) 
+ * r8   src_err_ptr (int)
+ * r9   dst_err_ptr (int)
+ *
+ * Output
+ * eax  64bit sum. undefined in case of exception.
+ * 
+ * Wrappers need to take care of valid exception sum and zeroing.		 
+ */
+
+	.macro source
+10:
+	.section __ex_table,"a"
+	.align 8
+	.quad 10b,bad_source
+	.previous
+	.endm
+		
+	.macro dest
+20:
+	.section __ex_table,"a"
+	.align 8
+	.quad 20b,bad_dest
+	.previous
+	.endm
+			
+	.globl csum_partial_copy_generic
+	.p2align
+csum_partial_copy_generic:
+	prefetchnta (%rdi)
+	
+	pushq %rbx
+	pushq %r12
+	pushq %r14
+	pushq %r15
+	movq %r8,%r14
+	movq %r9,%r15
+	movl  %ecx,%eax
+	movl  %edx,%ecx
+
+#ifdef FIX_ALIGNMENT
+	/* align source to 8 bytes */	
+	movl %edi,%r8d
+	andl $7,%r8d
+	jnz  bad_alignment	
+after_bad_alignment:
+#endif
+
+	movl  $64,%r10d
+	xorl  %r9d,%r9d
+	movq  %rcx,%r12
+
+	shrq  $6,%r12
+	/* loopcounter is maintained as one less to test efficiently for the
+	   previous to last iteration. This is needed to stop the prefetching. */
+	decq  %r12
+	js    handle_tail       /* < 64 */
+	jz    loop_no_prefetch  /* = 64 + X */ 
+	
+	/* main loop. clear in 64 byte blocks */
+	/* tries hard not to prefetch over the boundary */
+	/* r10:	64, r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */
+	/* r11:	temp3, rdx: temp4, r12 loopcnt */
+	.p2align
+loop:
+	/* Could prefetch more than one loop, but then it would be even
+	   trickier to avoid prefetching over the boundary. The hardware prefetch
+	   should take care of this anyways. The reason for this prefetch is
+	   just the non temporal hint to avoid cache pollution. Hopefully this
+	   will be handled properly by the hardware. */
+	prefetchnta 64(%rdi) 
+	
+loop_no_prefetch:
+	source
+	movq  (%rdi),%rbx
+	source
+	movq  8(%rdi),%r8
+	source
+	movq  16(%rdi),%r11
+	source
+	movq  24(%rdi),%rdx
+
+	dest
+	movnti %rbx,(%rsi)
+	dest
+	movnti %r8,8(%rsi)
+	dest
+	movnti %r11,16(%rsi)
+	dest
+	movnti %rdx,24(%rsi)
+		
+	addq  %rbx,%rax
+	adcq  %r8,%rax
+	adcq  %r11,%rax
+	adcq  %rdx,%rax
+
+	source
+	movq  32(%rdi),%rbx
+	source
+	movq  40(%rdi),%r8
+	source
+	movq  48(%rdi),%r11
+	source
+	movq  56(%rdi),%rdx
+	
+	dest
+	movnti %rbx,32(%rsi)
+	dest
+	movnti %r8,40(%rsi)
+	dest
+	movnti %r11,48(%rsi)
+	dest
+	movnti %rdx,56(%rsi)
+
+	adcq %rbx,%rax
+	adcq %r8,%rax
+	adcq %r11,%rax
+	adcq %rdx,%rax
+	
+	adcq %r9,%rax	/* add in carry */
+	
+	addq %r10,%rdi		
+	addq %r10,%rsi
+
+	decq %r12
+	jz   loop_no_prefetch	/* previous to last iteration? */
+	jns  loop
+
+	/* do last upto 56 bytes */
+handle_tail:
+	/* ecx:	count */
+	movl %ecx,%r10d
+	andl $63,%ecx
+	shrl $3,%ecx
+	jz 	 fold
+	clc
+	movl $8,%edx
+loop_8:	
+	source
+	movq (%rdi),%rbx
+	adcq %rbx,%rax
+	dest
+	movnti %rbx,(%rsi)
+	leaq (%rsi,%rdx),%rsi /* preserve carry */
+	leaq (%rdi,%rdx),%rdi
+	loop loop_8
+	adcq %r9,%rax	/* add in carry */
+
+fold:
+	movl %eax,%ebx
+	shrq $32,%rax
+	addq %rbx,%rax
+
+	/* do last upto 6 bytes */	
+handle_7:
+	movl %r10d,%ecx
+	andl $7,%ecx
+	shrl $1,%ecx
+	jz   handle_1
+	movl $2,%edx
+	xorl %ebx,%ebx
+	clc  
+loop_1:	
+	source
+	movw (%rdi),%bx
+	adcq %rbx,%rax
+	dest
+	movw %bx,(%rsi)
+	addq %rdx,%rdi
+	addq %rdx,%rsi
+	loop loop_1
+	adcw %r9w,%ax	/* add in carry */
+	
+	/* handle last odd byte */
+handle_1:	
+	testl $1,%r10d
+	jz    ende
+	xorl  %ebx,%ebx
+	source
+	movb (%rdi),%bl
+	dest
+	movb %bl,(%rsi)
+	addw %bx,%ax
+	adcw %r9w,%ax		/* carry */
+			
+ende:		
+	sfence
+	popq %r15
+	popq %r14
+	popq %r12
+	popq %rbx
+	ret
+
+#ifdef FIX_ALIGNMENT
+	/* align source to 8 bytes. */
+	/* r8d:	unalignedness, ecx len */
+bad_alignment:
+	testl $1,%edi
+	jnz   odd_source
+
+	/* compute distance to next aligned position */
+	movl $8,%r8d
+	xchgl %r8d,%ecx
+	subl %r8d,%ecx
+
+	/* handle unaligned part */
+	shrl $1,%ecx
+	xorl %ebx,%ebx	
+	movl $2,%r10d
+align_loop:
+	source
+	movw (%rdi),%bx
+	addq %rbx,%rax	/* carry cannot happen */
+	dest
+	movw %bx,(%rsi)
+	addq %r10,%rdi
+	addq %r10,%rsi
+	loop align_loop 
+	jmp after_bad_alignment
+
+	/* weird case. need to swap the sum at the end because the spec requires
+	   16 bit words of the sum to be always paired. 
+	   handle it recursively because it should be rather rare. */
+odd_source:
+	/* copy odd byte */
+	xorl %ebx,%ebx
+	source
+	movb (%rdi),%bl
+	addl %ebx,%eax       /* add to old checksum */
+	adcl $0,%ecx
+	dest
+	movb %al,(%rsi)
+	
+	/* fix arguments */
+	movl %eax,%ecx
+	incq %rsi
+	incq %rdi
+	decq %rdx 
+	call csum_partial_copy_generic
+	bswap %eax        /* this should work, but check */
+	jmp ende
+#endif
+
+	/* Exception handlers. Very simple, zeroing is done in the wrappers */
+bad_source:
+	movl $-EFAULT,(%r14)
+	jmp  ende
+	
+bad_dest:
+	movl $-EFAULT,(%r15)
+	jmp ende
diff -Nru a/arch/x86_64/lib/csum-partial.c b/arch/x86_64/lib/csum-partial.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/csum-partial.c	Sun Jun 16 19:31:39 2002
@@ -0,0 +1,126 @@
+/*
+ * arch/x86_64/lib/csum-partial.c
+ *
+ * This file contains network checksum routines that are better done
+ * in an architecture-specific manner due to speed.
+ */
+ 
+#include <linux/compiler.h>
+#include <linux/module.h>
+
+/* Better way for this sought */
+static inline unsigned short from64to16(unsigned long x)
+{
+	/* add up 32-bit words for 33 bits */
+	x = (x & 0xffffffff) + (x >> 32);
+	/* add up 16-bit and 17-bit words for 17+c bits */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up 16-bit and 2-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+/*
+ * Do a 64-bit checksum on an arbitrary memory area.
+ * Returns a 32bit checksum.
+ *
+ * This isn't a great routine, but it's not _horrible_ either. 
+ * We rely on the compiler to unroll.
+ */
+static inline unsigned do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (unlikely(odd)) {
+		result = *buff << 8;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+			if (4 & (unsigned long) buff) {
+				result += *(unsigned int *) buff;
+				count--;
+				len -= 4;
+				buff += 4;
+			}
+			count >>= 1;	/* nr of 64-bit words.. */
+			if (count) {
+				unsigned long zero = 0; 
+				do {
+					asm("  addq %1,%0\n"
+					    "  adcq %2,%0\n" 
+					    : "=r" (result)
+					    : "m"  (*buff), "r" (zero),  "0" (result));
+					count--;
+					buff += 8;
+				} while (count);
+				result = (result & 0xffffffff) + (result >> 32);
+			}
+			if (len & 4) {
+				result += *(unsigned int *) buff;
+				buff += 4;
+			}
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += *buff;
+	result = from64to16(result);
+	if (unlikely(odd))
+		return ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 64-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	asm("addl %1,%0\n\t"
+	    "adcl $0,%0" : "=r" (result) : "r" (sum), "0" (result)); 
+	return result;
+}
+
+//EXPORT_SYMBOL(csum_partial);
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+	return ~csum_partial(buff,len,0); 
+}
+
+EXPORT_SYMBOL(ip_compute_csum);
diff -Nru a/arch/x86_64/lib/csum-wrappers.c b/arch/x86_64/lib/csum-wrappers.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/csum-wrappers.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,109 @@
+/* Copyright 2002 Andi Kleen, SuSE Labs.
+ * Subject to the GNU Public License v.2
+ * 
+ * Wrappers of assembly checksum functions for x86-64.
+ */
+
+#include <asm/checksum.h>
+#include <linux/module.h>
+
+/* Better way for this sought */
+static inline unsigned from64to32(unsigned long x)
+{
+	/* add up 32-bit words for 33 bits */
+        x = (x & 0xffffffff) + (x >> 32);
+        /* add up 16-bit and 17-bit words for 17+c bits */
+        x = (x & 0xffff) + (x >> 16);
+        /* add up 16-bit and 2-bit for 16+c bit */
+        x = (x & 0xffff) + (x >> 16);
+        return x;
+}
+
+/** 
+ * csum_partial_copy_from_user - Copy and checksum from user space. 
+ * @src: source address (user space) 
+ * @dst: destination address
+ * @len: number of bytes to be copied.
+ * @isum: initial sum that is added into the result (32bit unfolded)
+ * @errp: set to -EFAULT for an bad source address.
+ * 
+ * Returns an 32bit unfolded checksum of the buffer.
+ * src and dst are best aligned to 64bits. 
+ */ 
+unsigned int 
+csum_partial_copy_from_user(const char *src, char *dst, 
+			    int len, unsigned int isum, int *errp)
+{ 
+	*errp = 0;
+	if (likely(access_ok(VERIFY_READ,src, len))) { 
+		unsigned long sum; 
+		sum = csum_partial_copy_generic(src,dst,len,isum,errp,NULL);
+		if (likely(*errp == 0)) 
+			return from64to32(sum); 
+	} 
+	*errp = -EFAULT;
+	memset(dst,0,len); 
+	return 0;		
+} 
+
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+
+/** 
+ * csum_partial_copy_to_user - Copy and checksum to user space. 
+ * @src: source address
+ * @dst: destination address (user space)
+ * @len: number of bytes to be copied.
+ * @isum: initial sum that is added into the result (32bit unfolded)
+ * @errp: set to -EFAULT for an bad destination address.
+ * 
+ * Returns an 32bit unfolded checksum of the buffer.
+ * src and dst are best aligned to 64bits.
+ */ 
+unsigned int 
+csum_partial_copy_to_user(const char *src, char *dst, 
+			  int len, unsigned int isum, int *errp)
+{ 
+	if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
+		*errp = -EFAULT;
+		return 0; 
+	}
+	*errp = 0;
+	return from64to32(csum_partial_copy_generic(src,dst,len,isum,NULL,errp)); 
+} 
+
+EXPORT_SYMBOL(csum_partial_copy_to_user);
+
+/** 
+ * csum_partial_copy_nocheck - Copy and checksum.
+ * @src: source address
+ * @dst: destination address
+ * @len: number of bytes to be copied.
+ * @isum: initial sum that is added into the result (32bit unfolded)
+ * 
+ * Returns an 32bit unfolded checksum of the buffer.
+ */ 
+unsigned int 
+csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
+{ 
+	return from64to32(csum_partial_copy_generic(src,dst,len,sum,NULL,NULL));
+} 
+
+//EXPORT_SYMBOL(csum_partial_copy_nocheck);
+
+unsigned short csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
+			       __u32 len, unsigned short proto, unsigned int sum) 
+{
+	__u64 rest, sum64;
+     
+	rest = (__u64)htonl(len) + (__u64)htons(proto) + (__u64)sum;
+	asm("  addq (%[saddr]),%[sum]\n"
+	    "  adcq 8(%[saddr]),%[sum]\n"
+	    "  adcq (%[daddr]),%[sum]\n" 
+	    "  adcq 8(%[daddr]),%[sum]\n"
+	    "  adcq $0,%[sum]\n"
+	    : [sum] "=r" (sum64) 
+	    : "[sum]" (rest),[saddr] "r" (saddr), [daddr] "r" (daddr));
+	return csum_fold(from64to32(sum64)); 
+}
+
+EXPORT_SYMBOL(csum_ipv6_magic);
diff -Nru a/arch/x86_64/lib/generic-checksum.c b/arch/x86_64/lib/generic-checksum.c
--- a/arch/x86_64/lib/generic-checksum.c	Sun Jun 16 19:31:39 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,124 +0,0 @@
-/*
- * arch/x86_64/lib/checksum.c
- *
- * This file contains network checksum routines that are better done
- * in an architecture-specific manner due to speed..
- */
- 
-#include <linux/string.h>
-#include <asm/byteorder.h>
-
-static inline unsigned short from64to16(unsigned long x)
-{
-	/* add up 32-bit words for 33 bits */
-	x = (x & 0xffffffff) + (x >> 32);
-	/* add up 16-bit and 17-bit words for 17+c bits */
-	x = (x & 0xffff) + (x >> 16);
-	/* add up 16-bit and 2-bit for 16+c bit */
-	x = (x & 0xffff) + (x >> 16);
-	/* add up carry.. */
-	x = (x & 0xffff) + (x >> 16);
-	return x;
-}
-
-/*
- * Do a 64-bit checksum on an arbitrary memory area..
- *
- * This isn't a great routine, but it's not _horrible_ either. The
- * inner loop could be unrolled a bit further, and there are better
- * ways to do the carry, but this is reasonable.
- */
-static inline unsigned long do_csum(const unsigned char * buff, int len)
-{
-	int odd, count;
-	unsigned long result = 0;
-
-	if (len <= 0)
-		goto out;
-	odd = 1 & (unsigned long) buff;
-	if (odd) {
-		result = *buff << 8;
-		len--;
-		buff++;
-	}
-	count = len >> 1;		/* nr of 16-bit words.. */
-	if (count) {
-		if (2 & (unsigned long) buff) {
-			result += *(unsigned short *) buff;
-			count--;
-			len -= 2;
-			buff += 2;
-		}
-		count >>= 1;		/* nr of 32-bit words.. */
-		if (count) {
-			if (4 & (unsigned long) buff) {
-				result += *(unsigned int *) buff;
-				count--;
-				len -= 4;
-				buff += 4;
-			}
-			count >>= 1;	/* nr of 64-bit words.. */
-			if (count) {
-				unsigned long carry = 0;
-				do {
-					unsigned long w = *(unsigned long *) buff;
-					count--;
-					buff += 8;
-					result += carry;
-					result += w;
-					carry = (w > result);
-				} while (count);
-				result += carry;
-				result = (result & 0xffffffff) + (result >> 32);
-			}
-			if (len & 4) {
-				result += *(unsigned int *) buff;
-				buff += 4;
-			}
-		}
-		if (len & 2) {
-			result += *(unsigned short *) buff;
-			buff += 2;
-		}
-	}
-	if (len & 1)
-		result += *buff;
-	result = from64to16(result);
-	if (odd)
-		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
-out:
-	return result;
-}
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
-{
-	unsigned long result = do_csum(buff, len);
-
-	/* add in old sum, and carry.. */
-	result += sum;
-	/* 32+c bits -> 32 bits */
-	result = (result & 0xffffffff) + (result >> 32);
-	return result;
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-unsigned short ip_compute_csum(unsigned char * buff, int len)
-{
-	return ~from64to16(do_csum(buff,len));
-}
-
diff -Nru a/arch/x86_64/lib/io.c b/arch/x86_64/lib/io.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/io.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,17 @@
+#include <linux/string.h>
+#include <asm/io.h>
+#include <linux/module.h>
+
+void *memcpy_toio(void *dst,void*src,unsigned len)
+{
+	return __inline_memcpy(__io_virt(dst),src,len);
+}
+
+void *memcpy_fromio(void *dst,void*src,unsigned len)
+{
+	return __inline_memcpy(dst,__io_virt(src),len);
+}
+
+EXPORT_SYMBOL(memcpy_toio);
+EXPORT_SYMBOL(memcpy_fromio);
+
diff -Nru a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/memcpy.S	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,107 @@
+/* Copyright 2002 Andi Kleen */
+	
+/*
+ * memcpy - Copy a memory block.
+ *
+ * Input:	
+ * rdi destination
+ * rsi source
+ * rdx count
+ * 
+ * Output:
+ * rax original destination
+ */	
+ 	.globl __memcpy
+	.globl memcpy
+	.p2align
+__memcpy:
+memcpy:		
+	pushq %rbx
+	prefetcht0 (%rsi)	/*for more hopefully the hw prefetch will kick in*/
+	movq %rdi,%rax
+
+	movl %edi,%ecx
+	andl $7,%ecx
+	jnz  bad_alignment	
+after_bad_alignment:
+
+	movq %rdx,%rcx
+	movl $64,%ebx
+	shrq $6,%rcx
+	jz handle_tail
+	
+loop_64:
+	/* no prefetch because we assume the hw prefetcher does it already 
+           and we have no specific temporal hint to give. XXX or give a nta
+	   hint for the source? */
+	movq (%rsi),%r11
+	movq 8(%rsi),%r8
+	movq 2*8(%rsi),%r9
+	movq 3*8(%rsi),%r10
+	movnti %r11,(%rdi)
+	movnti %r8,1*8(%rdi)
+	movnti %r9,2*8(%rdi)
+	movnti %r10,3*8(%rdi)
+		
+	movq 4*8(%rsi),%r11
+	movq 5*8(%rsi),%r8
+	movq 6*8(%rsi),%r9
+	movq 7*8(%rsi),%r10
+	movnti %r11,4*8(%rdi)
+	movnti %r8,5*8(%rdi)
+	movnti %r9,6*8(%rdi)
+	movnti %r10,7*8(%rdi)
+
+	addq %rbx,%rsi	
+	addq %rbx,%rdi
+	loop loop_64
+
+handle_tail:
+	movl %edx,%ecx
+	andl $63,%ecx
+	shrl $3,%ecx
+	jz   handle_7
+	movl $8,%ebx
+loop_8: 
+	movq (%rsi),%r8
+	movnti %r8,(%rdi) 
+	addq %rbx,%rdi
+	addq %rbx,%rsi
+	loop loop_8
+
+handle_7:
+	movl %edx,%ecx
+	andl $7,%ecx
+	jz ende
+loop_1:
+	movb (%rsi),%r8b
+	movb %r8b,(%rdi) 
+	incq %rdi
+	incq %rsi
+	loop loop_1
+	
+ende: 	
+	sfence
+	popq %rbx
+	ret
+	
+	/* align destination */
+	/* This is simpleminded. For bigger blocks it may make sense to align
+	   src and dst to their aligned subset and handle the rest separately */
+bad_alignment:
+	movl $8,%r9d
+	subl %ecx,%r9d
+	movl %r9d,%ecx
+	subq %r9,%rdx
+	js   small_alignment
+	jz   small_alignment
+align_1:
+	movb (%rsi),%r8b
+	movb %r8b,(%rdi) 
+	incq %rdi
+	incq %rsi
+	loop align_1
+	jmp after_bad_alignment
+small_alignment:
+	addq %r9,%rdx
+	jmp handle_7
diff -Nru a/arch/x86_64/lib/memmove.c b/arch/x86_64/lib/memmove.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/memmove.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,27 @@
+/* Normally compiler builtins are used, but sometimes the compiler calls out
+   of line code. Based on asm-i386/string.h.
+ */
+#define _STRING_C
+#include <linux/string.h>
+
+#undef memmove
+void *memmove(void * dest,const void *src,size_t count)
+{
+	if (dest < src) { 
+		__inline_memcpy(dest,src,count);
+	} else {
+		/* Could be more clever and move longs */
+		unsigned long d0, d1, d2;
+		__asm__ __volatile__(
+			"std\n\t"
+			"rep\n\t"
+			"movsb\n\t"
+			"cld"
+			: "=&c" (d0), "=&S" (d1), "=&D" (d2)
+			:"0" (count),
+			"1" (count-1+(const char *)src),
+			"2" (count-1+(char *)dest)
+			:"memory");
+	}
+	return dest;
+} 
diff -Nru a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/lib/memset.S	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,85 @@
+/* Copyright 2002 Andi Kleen, SuSE Labs */
+
+	// #define FIX_ALIGNMENT 1
+
+/*
+ * ISO C memset - set a memory block to a byte value.
+ *	
+ * rdi   destination
+ * rsi   value (char) 
+ * rdx   count (bytes) 
+ * 
+ * rax   original destination
+ */	
+	.globl ____memset
+	.p2align
+____memset:
+	movq %rdi,%r10		/* save destination for return address */
+	movq %rdx,%r11		/* save count */ 
+
+	/* expand byte value  */
+	movzbl %sil,%ecx	/* zero extend char value */
+	movabs $0x0101010101010101,%rax		/* expansion pattern */
+	mul    %rcx		/* expand with rax, clobbers rdx */
+
+#ifdef FIX_ALIGNMENT
+	/* align dst */
+	movl  %edi,%r9d		
+	andl  $7,%r9d		/* test unaligned bits */
+	jnz  bad_alignment
+after_bad_alignment:
+#endif
+	
+	movq %r11,%rcx		/* restore count */
+	shrq $6,%rcx		/* divide by 64 */
+	jz	 handle_tail	/* block smaller than 64 bytes? */
+	movl $64,%r8d		/* CSE loop block size */
+
+loop_64:	
+	movnti  %rax,0*8(%rdi) 
+	movnti  %rax,1*8(%rdi) 
+	movnti  %rax,2*8(%rdi) 
+	movnti  %rax,3*8(%rdi) 
+	movnti  %rax,4*8(%rdi) 
+	movnti  %rax,5*8(%rdi) 
+	movnti  %rax,6*8(%rdi) 
+	movnti  %rax,7*8(%rdi) 	/* clear 64 byte blocks */
+	addq    %r8,%rdi	/* increase pointer by 64 bytes */
+	loop	loop_64		/* decrement rcx and if not zero loop */
+
+	/* Handle tail in loops. The loops should be faster than hard
+	   to predict jump tables. */ 
+handle_tail:
+	movl	%r11d,%ecx
+	andl    $63,%ecx
+	shrl	$3,%ecx
+	jz 	handle_7
+loop_8:
+	movnti  %rax,(%rdi) 	/* long words */
+	addq    $8,%rdi
+	loop 	loop_8   
+
+handle_7:
+	movl	%r11d,%ecx
+	andl	$7,%ecx
+	jz      ende
+loop_1:
+	movb 	%al,(%rdi)	/* bytes */
+	incq	%rdi
+	loop	loop_1
+	
+ende:	
+	movq	%r10,%rax
+	ret
+
+#ifdef FIX_ALIGNMENT
+bad_alignment:
+	andq $-8,%r11		/* shorter than 8 bytes */
+	jz      handle_7	/* if yes handle it in the tail code */
+	movnti %rax,(%rdi)	/* unaligned store of 8 bytes */
+	movq $8,%r8			
+	subq %r9,%r8 		/* compute alignment (8-misalignment) */
+	addq %r8,%rdi		/* fix destination */
+	subq %r8,%r11		/* fix count */
+	jmp after_bad_alignment
+#endif
diff -Nru a/arch/x86_64/lib/mmx.c b/arch/x86_64/lib/mmx.c
--- a/arch/x86_64/lib/mmx.c	Sun Jun 16 19:31:41 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,256 +0,0 @@
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/compiler.h>
-
-#include <asm/i387.h>
-#include <asm/hardirq.h> 
-#include <asm/page.h>
-
-/*
- *	MMX 3DNow! library helper functions
- *
- *	To do:
- *	We can use MMX just for prefetch in IRQ's. This may be a win. 
- *		(reported so on K6-III)
- *	We should use a better code neutral filler for the short jump
- *		leal ebx. [ebx] is apparently best for K6-2, but Cyrix ??
- *	We also want to clobber the filler register so we dont get any
- *		register forwarding stalls on the filler. 
- *
- *	Add *user handling. Checksums are not a win with MMX on any CPU
- *	tested so far for any MMX solution figured.
- *
- *	22/09/2000 - Arjan van de Ven 
- *		Improved for non-egineering-sample Athlons 
- *
- *	2002 Andi Kleen. Some cleanups and changes for x86-64. 
- *	Not really tuned yet. Using the Athlon version for now.
- *      This currenly uses MMX for 8 byte stores, but on hammer we could
- *      use integer 8 byte stores too and avoid the FPU save overhead.
- *	Disadvantage is that the integer load/stores have strong ordering
- *	model and may be slower.
- * 
- *	$Id$
- */
-
-#ifdef MMX_MEMCPY_THRESH
-
- 
-void *_mmx_memcpy(void *to, const void *from, size_t len)
-{
- 	void *p;
- 	int i;
-  
- 	p = to;
-
- 	if (unlikely(in_interrupt()))
-		goto standard;
-	
-	/* XXX: check if this is still memory bound with unaligned to/from.
-	   if not align them here to 8bytes. */
- 	i = len >> 6; /* len/64 */
- 
- 	kernel_fpu_begin();
-
-	__asm__ __volatile__ (
-		"   prefetch (%0)\n"		/* This set is 28 bytes */
-		"   prefetch 64(%0)\n"
-		"   prefetch 128(%0)\n"
-		"   prefetch 192(%0)\n"
-		"   prefetch 256(%0)\n"
-		"\n"
-		: : "r" (from) );
-		
-	for(; i>5; i--)
-	{
-		__asm__ __volatile__ (
-		"  prefetch 320(%0)\n"
-		"  movq (%0), %%mm0\n"
-		"  movq 8(%0), %%mm1\n"
-		"  movq 16(%0), %%mm2\n"
-		"  movq 24(%0), %%mm3\n"
-		"  movq %%mm0, (%1)\n"
-		"  movq %%mm1, 8(%1)\n"
-		"  movq %%mm2, 16(%1)\n"
-		"  movq %%mm3, 24(%1)\n"
-		"  movq 32(%0), %%mm0\n"
-		"  movq 40(%0), %%mm1\n"
-		"  movq 48(%0), %%mm2\n"
-		"  movq 56(%0), %%mm3\n"
-		"  movq %%mm0, 32(%1)\n"
-		"  movq %%mm1, 40(%1)\n"
-		"  movq %%mm2, 48(%1)\n"
-		"  movq %%mm3, 56(%1)\n"
-		: : "r" (from), "r" (to) : "memory");
-		from+=64;
-		to+=64;
-	}
-
-	for(; i>0; i--)
-	{
-		__asm__ __volatile__ (
-		"  movq (%0), %%mm0\n"
-		"  movq 8(%0), %%mm1\n"
-		"  movq 16(%0), %%mm2\n"
-		"  movq 24(%0), %%mm3\n"
-		"  movq %%mm0, (%1)\n"
-		"  movq %%mm1, 8(%1)\n"
-		"  movq %%mm2, 16(%1)\n"
-		"  movq %%mm3, 24(%1)\n"
-		"  movq 32(%0), %%mm0\n"
-		"  movq 40(%0), %%mm1\n"
-		"  movq 48(%0), %%mm2\n"
-		"  movq 56(%0), %%mm3\n"
-		"  movq %%mm0, 32(%1)\n"
-		"  movq %%mm1, 40(%1)\n"
-		"  movq %%mm2, 48(%1)\n"
-		"  movq %%mm3, 56(%1)\n"
-		: : "r" (from), "r" (to) : "memory");
-		from+=64;
-		to+=64;
-	}
-	len &= 63; 	
-	kernel_fpu_end();
-
-	/*
-	 *	Now do the tail of the block
-	 */
-
- standard:
-	__inline_memcpy(to, from, len);
-	return p;
-}
-#endif
-
-static inline void fast_clear_page(void *page)
-{
-	int i;
-
-	kernel_fpu_begin();
-	
-	__asm__ __volatile__ (
-		"  pxor %%mm0, %%mm0\n" : :
-	);
-
-	for(i=0;i<4096/64;i++)
-	{
-		__asm__ __volatile__ (
-		"  movntq %%mm0, (%0)\n"
-		"  movntq %%mm0, 8(%0)\n"
-		"  movntq %%mm0, 16(%0)\n"
-		"  movntq %%mm0, 24(%0)\n"
-		"  movntq %%mm0, 32(%0)\n"
-		"  movntq %%mm0, 40(%0)\n"
-		"  movntq %%mm0, 48(%0)\n"
-		"  movntq %%mm0, 56(%0)\n"
-		: : "r" (page) : "memory");
-		page+=64;
-	}
-	/* since movntq is weakly-ordered, a "sfence" is needed to become
-	 * ordered again.
-	 */
-	__asm__ __volatile__ (
-		"  sfence \n" : :
-	);
-	kernel_fpu_end();
-}
-
-static inline void fast_copy_page(void *to, void *from)
-{
-	int i;
-
-	kernel_fpu_begin();
-
-	/* maybe the prefetch stuff can go before the expensive fnsave...
-	 * but that is for later. -AV
-	 */
-	__asm__ __volatile__ (
-		"   prefetch (%0)\n"
-		"   prefetch 64(%0)\n"
-		"   prefetch 128(%0)\n"
-		"   prefetch 192(%0)\n"
-		"   prefetch 256(%0)\n"
-		: : "r" (from) );
-
-	for(i=0; i<(4096-320)/64; i++)
-	{
-		__asm__ __volatile__ (
-		"   prefetch 320(%0)\n"
-		"   movq (%0), %%mm0\n"
-		"   movntq %%mm0, (%1)\n"
-		"   movq 8(%0), %%mm1\n"
-		"   movntq %%mm1, 8(%1)\n"
-		"   movq 16(%0), %%mm2\n"
-		"   movntq %%mm2, 16(%1)\n"
-		"   movq 24(%0), %%mm3\n"
-		"   movntq %%mm3, 24(%1)\n"
-		"   movq 32(%0), %%mm4\n"
-		"   movntq %%mm4, 32(%1)\n"
-		"   movq 40(%0), %%mm5\n"
-		"   movntq %%mm5, 40(%1)\n"
-		"   movq 48(%0), %%mm6\n"
-		"   movntq %%mm6, 48(%1)\n"
-		"   movq 56(%0), %%mm7\n"
-		"   movntq %%mm7, 56(%1)\n"
-		: : "r" (from), "r" (to) : "memory");
-		from+=64;
-		to+=64;
-	}
-	for(i=(4096-320)/64; i<4096/64; i++)
-	{
-		__asm__ __volatile__ (
-		"2: movq (%0), %%mm0\n"
-		"   movntq %%mm0, (%1)\n"
-		"   movq 8(%0), %%mm1\n"
-		"   movntq %%mm1, 8(%1)\n"
-		"   movq 16(%0), %%mm2\n"
-		"   movntq %%mm2, 16(%1)\n"
-		"   movq 24(%0), %%mm3\n"
-		"   movntq %%mm3, 24(%1)\n"
-		"   movq 32(%0), %%mm4\n"
-		"   movntq %%mm4, 32(%1)\n"
-		"   movq 40(%0), %%mm5\n"
-		"   movntq %%mm5, 40(%1)\n"
-		"   movq 48(%0), %%mm6\n"
-		"   movntq %%mm6, 48(%1)\n"
-		"   movq 56(%0), %%mm7\n"
-		"   movntq %%mm7, 56(%1)\n"
-		: : "r" (from), "r" (to) : "memory");
-		from+=64;
-		to+=64;
-	}
-	/* since movntq is weakly-ordered, a "sfence" is needed to become
-	 * ordered again.
-	 */
-	__asm__ __volatile__ (
-		"  sfence \n" : :
-	);
-	kernel_fpu_end();
-}
-
-void mmx_clear_page(void * page)
-{
-#if 1 
-	__builtin_memset(page,0,PAGE_SIZE);
-#else
-	/* AK: these in_interrupt checks should not be needed. */
-	if(unlikely(in_interrupt()))
-		__builtin_memset(page,0,PAGE_SIZE);
-	else
-		fast_clear_page(page);
-#endif
-}
-
-void mmx_copy_page(void *to, void *from)
-{
-#if 1
-	__builtin_memcpy(to,from,PAGE_SIZE);
-#else
-	/* AK: these in_interrupt checks should not be needed. */
-	if(unlikely(in_interrupt()))
-		__builtin_memcpy(to,from,PAGE_SIZE);
-	else
-		fast_copy_page(to, from);
-#endif
-}
diff -Nru a/arch/x86_64/lib/rwsem_thunk.S b/arch/x86_64/lib/rwsem_thunk.S
--- a/arch/x86_64/lib/rwsem_thunk.S	Sun Jun 16 19:31:39 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,27 +0,0 @@
-	#include <asm/calling.h>
-
-	/*
-	 * Save registers for the slow path of semaphores here to avoid
-	 * disturbance of register allocation in fast paths with function calls.
-	 * Written 2001 by Andi Kleen.
-	 */
-	
-	.macro rwsem_thunk name,func
-	.globl \name
-\name:	
-	SAVE_ARGS
-	movq %rax,%rdi
-	call \func
-	jmp  restore
-	.endm
-
-	rwsem_thunk rwsem_down_read_failed_thunk,rwsem_down_read_failed
-	rwsem_thunk rwsem_down_write_failed_thunk,rwsem_down_write_failed
-	rwsem_thunk rwsem_wake_thunk,rwsem_wake
-	/* This does not really belong here, but the macros are so
-	   convenient. */ 
-	rwsem_thunk do_softirq_thunk,do_softirq
-
-restore:	
-	RESTORE_ARGS
-	ret
diff -Nru a/arch/x86_64/lib/usercopy.c b/arch/x86_64/lib/usercopy.c
--- a/arch/x86_64/lib/usercopy.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/lib/usercopy.c	Sun Jun 16 19:31:39 2002
@@ -1,122 +1,93 @@
 /* 
  * User address space access functions.
- * The non inlined parts of asm-i386/uaccess.h are here.
  *
  * Copyright 1997 Andi Kleen <ak@muc.de>
  * Copyright 1997 Linus Torvalds
+ * Copyright 2002 Andi Kleen <ak@suse.de>
  */
-#include <linux/config.h>
 #include <asm/uaccess.h>
-#include <asm/mmx.h>
-
-unsigned long
-__generic_copy_to_user(void *to, const void *from, unsigned long n)
-{
-	prefetch(from);
-	if (access_ok(VERIFY_WRITE, to, n))
-		__copy_user(to,from,n);
-	return n;
-}
-
-unsigned long
-__generic_copy_from_user(void *to, const void *from, unsigned long n)
-{
-	prefetchw(to);
-	if (access_ok(VERIFY_READ, from, n))
-		__copy_user_zeroing(to,from,n);
-	else
-		memset(to, 0, n);
-	return n;
-}
 
 /*
  * Copy a null terminated string from userspace.
  */
 
-#define __do_strncpy_from_user(dst,src,count,res)			   \
-do {									   \
-	long __d0, __d1, __d2;						   \
-	__asm__ __volatile__(						   \
-		"	testq %1,%1\n"					   \
-		"	jz 2f\n"					   \
-		"0:	lodsb\n"					   \
-		"	stosb\n"					   \
-		"	testb %%al,%%al\n"				   \
-		"	jz 1f\n"					   \
-		"	decq %1\n"					   \
-		"	jnz 0b\n"					   \
-		"1:	subq %1,%0\n"					   \
-		"2:\n"							   \
-		".section .fixup,\"ax\"\n"				   \
-		"3:	movq %5,%0\n"					   \
-		"	jmp 2b\n"					   \
-		".previous\n"						   \
-		".section __ex_table,\"a\"\n"				   \
-		"	.align 4\n"					   \
-		"	.quad 0b,3b\n"					   \
-		".previous"						   \
-		: "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),	   \
-		  "=&D" (__d2)						   \
-		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
-		: "memory");						   \
-} while (0)
-
-long
-__strncpy_from_user(char *dst, const char *src, long count)
+long __strncpy_from_user(char *dst, const char *src, long count)
 {
 	long res;
-	__do_strncpy_from_user(dst, src, count, res);
+	long __d0, __d1, __d2;
+	asm volatile(		\
+		"	testq %1,%1\n"
+		"	jz 2f\n"
+		"0:	lodsb\n"
+		"	stosb\n"
+		"	testb %%al,%%al\n"
+		"   	loopnz 0b\n"
+		"1:	subq %1,%0\n"
+		"2:\n"
+		".section .fixup,\"ax\"\n"
+		"3:	movq %5,%0\n"
+		"	jmp 2b\n"
+		".previous\n"
+		".section __ex_table,\"a\"\n"
+		"	.align 8\n"
+		"	.quad 0b,3b\n"
+		".previous"
+		: "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
+		  "=&D" (__d2)
+		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst)
+		: "memory");
 	return res;
 }
 
-long
-strncpy_from_user(char *dst, const char *src, long count)
+long strncpy_from_user(char *dst, const char *src, long count)
 {
-	long res = -EFAULT;
 	if (access_ok(VERIFY_READ, src, 1))
-		__do_strncpy_from_user(dst, src, count, res);
-	return res;
+		return __strncpy_from_user(dst, src, count);
+	return -EFAULT;
 }
 
-
 /*
  * Zero Userspace
  */
 
-#define __do_clear_user(addr,size)					\
-do {									\
-	long __d0;							\
-  	__asm__ __volatile__(						\
-		"cld\n" \
-		"0:	rep; stosl\n"					\
-		"	movq %2,%0\n"					\
-		"1:	rep; stosb\n"					\
-		"2:\n"							\
-		".section .fixup,\"ax\"\n"				\
-		"3:	lea 0(%2,%0,4),%0\n"				\
-		"	jmp 2b\n"					\
-		".previous\n"						\
-		".section __ex_table,\"a\"\n"				\
-		"	.align 4\n"					\
-		"	.quad 0b,3b\n"					\
-		"	.quad 1b,2b\n"					\
-		".previous"						\
-		: "=&c"(size), "=&D" (__d0)				\
-		: "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));	\
-} while (0)
-
-unsigned long
-clear_user(void *to, unsigned long n)
+unsigned long __clear_user(void *addr, unsigned long size)
 {
-	if (access_ok(VERIFY_WRITE, to, n))
-		__do_clear_user(to, n);
-	return n;
+	long __d0;
+	/* no memory constraint because it doesn't change any memory gcc knows
+	   about */
+	asm volatile(
+		"	testq  %[size8],%[size8]\n"
+		"	jz     4f\n"
+		"0:	movnti %[zero],(%[dst])\n"
+		"	addq   %[eight],%[dst]\n"
+		"	loop   0b\n"
+		"4:	movq  %[size1],%%rcx\n"
+		"	testl %%ecx,%%ecx\n"
+		"	jz     2f\n"
+		"1:	movb   %b[zero],(%[dst])\n"
+		"	incq   %[dst]\n"
+		"	loop   1b\n"
+		"2:	sfence\n"
+		".section .fixup,\"ax\"\n"
+		"3:	lea 0(%[size1],%[size8],8),%[size8]\n"
+		"	jmp 2b\n"
+		".previous\n"
+		".section __ex_table,\"a\"\n"
+		"       .align 8\n"
+		"	.quad 0b,3b\n"
+		"	.quad 1b,2b\n"
+		".previous"
+		: [size8] "=c"(size), [dst] "=&D" (__d0)
+		: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst] "(addr),
+		  [zero] "r" (0UL), [eight] "r" (8UL));
+	return size;
 }
 
-unsigned long
-__clear_user(void *to, unsigned long n)
+
+unsigned long clear_user(void *to, unsigned long n)
 {
-	__do_clear_user(to, n);
+	if (access_ok(VERIFY_WRITE, to, n))
+		return __clear_user(to, n);
 	return n;
 }
 
diff -Nru a/arch/x86_64/mm/extable.c b/arch/x86_64/mm/extable.c
--- a/arch/x86_64/mm/extable.c	Sun Jun 16 19:31:41 2002
+++ b/arch/x86_64/mm/extable.c	Sun Jun 16 19:31:41 2002
@@ -1,16 +1,34 @@
 /*
- * linux/arch/i386/mm/extable.c
+ * linux/arch/x86_64/mm/extable.c
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
+#include <linux/init.h>
 
 extern const struct exception_table_entry __start___ex_table[];
 extern const struct exception_table_entry __stop___ex_table[];
 
-static inline unsigned long
+
+void __init exception_table_check(void)
+{ 
+	const struct exception_table_entry *e;
+	unsigned long prev;
+
+	prev = 0;
+	for (e = __start___ex_table; e < __stop___ex_table; e++) { 		
+		if (e->insn < prev) {
+			panic("unordered exception table at %016lx:%016lx and %016lx:%016lx\n",
+				   prev, e[-1].fixup, 
+			       e->insn, e->fixup);
+		}		   	
+		prev = e->insn;
+	} 
+} 
+
+static unsigned long
 search_one_table(const struct exception_table_entry *first,
 		 const struct exception_table_entry *last,
 		 unsigned long value)
@@ -41,8 +59,7 @@
 
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
-	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	return ret;
+	return search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
--- a/arch/x86_64/mm/fault.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/mm/fault.c	Sun Jun 16 19:31:39 2002
@@ -85,7 +85,7 @@
 }
 
 int page_fault_trace; 
-int exception_trace;
+int exception_trace = 1;
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -311,11 +311,7 @@
 		if (!pte_present(*pte))
 			goto bad_area_nosemaphore;
 
-		/* Strictly a flush_tlb_all because vmalloc is global,
-		   but this only applies to new global pages so it should
-		   not be needed. vmalloc will likely touch multiple ptes,
-		   so do a full flush instead of a partial one. */ 
-		__flush_tlb();		
+		__flush_tlb_all();		
 		return;
 	}
 }
diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
--- a/arch/x86_64/mm/init.c	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/mm/init.c	Sun Jun 16 19:31:39 2002
@@ -153,6 +153,7 @@
 } temp_mappings[] __initdata = { 
 	{ &temp_boot_pmds[0], (void *)(40UL * 1024 * 1024) },
 	{ &temp_boot_pmds[1], (void *)(42UL * 1024 * 1024) }, 
+	{ &temp_boot_pmds[1], (void *)(44UL * 1024 * 1024) }, 
 	{}
 }; 
 
diff -Nru a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
--- a/arch/x86_64/mm/ioremap.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/mm/ioremap.c	Sun Jun 16 19:31:40 2002
@@ -9,6 +9,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 #include <asm/fixmap.h>
@@ -165,5 +166,5 @@
 void iounmap(void *addr)
 {
 	if (addr > high_memory)
-		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+		vfree((void *) (PAGE_MASK & (unsigned long) addr));
 }
diff -Nru a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/Makefile	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,17 @@
+O_TARGET        := pci.o
+
+obj-y		:= x86-64.o
+
+obj-$(CONFIG_PCI_DIRECT)	+= direct.o
+
+obj-y		+= fixup.o
+
+ifdef	CONFIG_ACPI_PCI
+obj-y		+= acpi.o
+endif
+obj-y		+= legacy.o
+
+
+obj-y		+= irq.o common.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/arch/x86_64/pci/acpi.c b/arch/x86_64/pci/acpi.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/acpi.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,25 @@
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include "pci.h"
+
+static int __init pci_acpi_init(void)
+{
+	if (pcibios_scanned)
+		return 0;
+
+	if (!(pci_probe & PCI_NO_ACPI_ROUTING)) {
+		if (!acpi_pci_irq_init()) {
+			printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+			printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi'\n");
+			pcibios_scanned++;
+			pcibios_enable_irq = acpi_pci_irq_enable;
+		} else
+			printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
+
+	}
+
+	return 0;
+}
+
+subsys_initcall(pci_acpi_init);
diff -Nru a/arch/x86_64/pci/changelog b/arch/x86_64/pci/changelog
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/changelog	Sun Jun 16 19:31:41 2002
@@ -0,0 +1 @@
+See arch/i386/pci/changelog for early changelog.
diff -Nru a/arch/x86_64/pci/common.c b/arch/x86_64/pci/common.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/common.c	Sun Jun 16 19:31:39 2002
@@ -0,0 +1,196 @@
+/*
+ *	Low-Level PCI Support for PC
+ *
+ *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
+
+ Note: on x86-64 there is no PCI BIOS so there is no way to sort in the 
+ same order as 32bit Linux. This could cause grief for dualbooting because
+ devices may wander.  May want to use ACPI for sorting eventually. 
+
+ */
+
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+
+#include "pci.h"
+
+unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
+
+int pcibios_last_bus = 0xfe; /* XXX */
+struct pci_bus *pci_root_bus = NULL;
+struct pci_ops *pci_root_ops = NULL;
+
+int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
+int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
+
+/*
+ * legacy, numa, and acpi all want to call pcibios_scan_root
+ * from their initcalls. This flag prevents that.
+ */
+int pcibios_scanned;
+
+/*
+ * This interrupt-safe spinlock protects all accesses to PCI
+ * configuration space.
+ */
+spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Several buggy motherboards address only 16 devices and mirror
+ * them to next 16 IDs. We try to detect this `feature' on all
+ * primary buses (those containing host bridges as they are
+ * expected to be unique) and remove the ghost devices.
+ */
+
+static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
+{
+	struct list_head *ln, *mn;
+	struct pci_dev *d, *e;
+	int mirror = PCI_DEVFN(16,0);
+	int seen_host_bridge = 0;
+	int i;
+
+	DBG("PCI: Scanning for ghost devices on bus %d\n", b->number);
+	for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
+		d = pci_dev_b(ln);
+		if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+			seen_host_bridge++;
+		for (mn=ln->next; mn != &b->devices; mn=mn->next) {
+			e = pci_dev_b(mn);
+			if (e->devfn != d->devfn + mirror ||
+			    e->vendor != d->vendor ||
+			    e->device != d->device ||
+			    e->class != d->class)
+				continue;
+			for(i=0; i<PCI_NUM_RESOURCES; i++)
+				if (e->resource[i].start != d->resource[i].start ||
+				    e->resource[i].end != d->resource[i].end ||
+				    e->resource[i].flags != d->resource[i].flags)
+					continue;
+			break;
+		}
+		if (mn == &b->devices)
+			return;
+	}
+	if (!seen_host_bridge)
+		return;
+	printk(KERN_WARNING "PCI: Ignoring ghost devices on bus %02x\n", b->number);
+
+	ln = &b->devices;
+	while (ln->next != &b->devices) {
+		d = pci_dev_b(ln->next);
+		if (d->devfn >= mirror) {
+			list_del(&d->global_list);
+			list_del(&d->bus_list);
+			kfree(d);
+		} else
+			ln = ln->next;
+	}
+}
+
+/*
+ *  Called after each bus is probed, but before its children
+ *  are examined.
+ */
+
+void __devinit  pcibios_fixup_bus(struct pci_bus *b)
+{
+	pcibios_fixup_ghosts(b);
+	pci_read_bridge_bases(b);
+}
+
+
+struct pci_bus * __devinit pcibios_scan_root(int busnum)
+{
+	struct list_head *list;
+	struct pci_bus *bus;
+
+	list_for_each(list, &pci_root_buses) {
+		bus = pci_bus_b(list);
+		if (bus->number == busnum) {
+			/* Already scanned */
+			return bus;
+		}
+	}
+
+	printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
+
+	return pci_scan_bus(busnum, pci_root_ops, NULL);
+}
+
+static int __init pcibios_init(void)
+{
+	if (!pci_root_ops) {
+		printk("PCI: System does not support PCI\n");
+		return 0;
+	}
+
+	pcibios_resource_survey();
+
+	/* may eventually need to do ACPI sort here. */
+	return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+char * __devinit  pcibios_setup(char *str)
+{
+	if (!strcmp(str, "off")) {
+		pci_probe = 0;
+		return NULL;
+	}
+#ifdef CONFIG_PCI_DIRECT
+	else if (!strcmp(str, "conf1")) {
+		pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
+		return NULL;
+	}
+	else if (!strcmp(str, "conf2")) {
+		pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
+		return NULL;
+	}
+#endif
+#ifdef CONFIG_ACPI_PCI
+	else if (!strcmp(str, "noacpi")) {
+		pci_probe |= PCI_NO_ACPI_ROUTING;
+		return NULL;
+	}
+#endif
+	else if (!strcmp(str, "rom")) {
+		pci_probe |= PCI_ASSIGN_ROMS;
+		return NULL;
+	} else if (!strcmp(str, "assign-busses")) {
+		pci_probe |= PCI_ASSIGN_ALL_BUSSES;
+		return NULL;
+	} else if (!strcmp(str, "usepirqmask")) {
+		pci_probe |= PCI_USE_PIRQ_MASK;
+		return NULL;
+	} else if (!strncmp(str, "irqmask=", 8)) {
+		pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
+		return NULL;
+	} else if (!strncmp(str, "lastbus=", 8)) {
+		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
+		return NULL;
+	}
+	return str;
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	int err;
+
+	if ((err = pcibios_enable_resources(dev)) < 0)
+		return err;
+
+	return pcibios_enable_irq(dev);
+}
diff -Nru a/arch/x86_64/pci/direct.c b/arch/x86_64/pci/direct.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/direct.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,367 @@
+/*
+ * direct.c - Low-level direct PCI config space access
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci.h"
+
+/*
+ * Functions for accessing PCI configuration space with type 1 accesses
+ */
+
+#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
+	(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
+
+static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+	unsigned long flags;
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+	switch (len) {
+	case 1:
+		*value = inb(0xCFC + (reg & 3));
+		break;
+	case 2:
+		*value = inw(0xCFC + (reg & 2));
+		break;
+	case 4:
+		*value = inl(0xCFC);
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+	unsigned long flags;
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+	switch (len) {
+	case 1:
+		outb((u8)value, 0xCFC + (reg & 3));
+		break;
+	case 2:
+		outw((u16)value, 0xCFC + (reg & 2));
+		break;
+	case 4:
+		outl((u32)value, 0xCFC);
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+
+#undef PCI_CONF1_ADDRESS
+
+static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	int result; 
+	u32 data;
+
+	if (!value) 
+		return -EINVAL;
+
+	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, &data);
+
+	*value = (u8)data;
+
+	return result;
+}
+
+static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	int result; 
+	u32 data;
+
+	if (!value) 
+		return -EINVAL;
+
+	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, &data);
+
+	*value = (u16)data;
+
+	return result;
+}
+
+static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	if (!value) 
+		return -EINVAL;
+
+	return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, value);
+}
+
+static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, value);
+}
+
+static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static struct pci_ops pci_direct_conf1 = {
+	pci_conf1_read_config_byte,
+	pci_conf1_read_config_word,
+	pci_conf1_read_config_dword,
+	pci_conf1_write_config_byte,
+	pci_conf1_write_config_word,
+	pci_conf1_write_config_dword
+};
+
+
+/*
+ * Functions for accessing PCI configuration space with type 2 accesses
+ */
+
+#define PCI_CONF2_ADDRESS(dev, reg)	(u16)(0xC000 | (dev << 8) | reg)
+
+static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+	unsigned long flags;
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	if (dev & 0x10) 
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+	outb((u8)bus, 0xCFA);
+
+	switch (len) {
+	case 1:
+		*value = inb(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 2:
+		*value = inw(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 4:
+		*value = inl(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	}
+
+	outb (0, 0xCF8);
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+	unsigned long flags;
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	if (dev & 0x10) 
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+	outb((u8)bus, 0xCFA);
+
+	switch (len) {
+	case 1:
+		outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 2:
+		outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 4:
+		outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	}
+
+	outb (0, 0xCF8);    
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+#undef PCI_CONF2_ADDRESS
+
+static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	int result; 
+	u32 data;
+	result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, &data);
+	*value = (u8)data;
+	return result;
+}
+
+static int pci_conf2_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	int result; 
+	u32 data;
+	result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, &data);
+	*value = (u16)data;
+	return result;
+}
+
+static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	return pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, value);
+}
+
+static int pci_conf2_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, value);
+}
+
+static int pci_conf2_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static struct pci_ops pci_direct_conf2 = {
+	pci_conf2_read_config_byte,
+	pci_conf2_read_config_word,
+	pci_conf2_read_config_dword,
+	pci_conf2_write_config_byte,
+	pci_conf2_write_config_word,
+	pci_conf2_write_config_dword
+};
+
+
+/*
+ * Before we decide to use direct hardware access mechanisms, we try to do some
+ * trivial checks to ensure it at least _seems_ to be working -- we just test
+ * whether bus 00 contains a host bridge (this is similar to checking
+ * techniques used in XFree86, but ours should be more reliable since we
+ * attempt to make use of direct access hints provided by the PCI BIOS).
+ *
+ * This should be close to trivial, but it isn't, because there are buggy
+ * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
+ */
+static int __devinit pci_sanity_check(struct pci_ops *o)
+{
+	u16 x;
+	struct pci_bus bus;		/* Fake bus and device */
+	struct pci_dev dev;
+
+	if (pci_probe & PCI_NO_CHECKS)
+		return 1;
+	bus.number = 0;
+	dev.bus = &bus;
+	for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++)
+		if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) &&
+		     (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
+		    (!o->read_word(&dev, PCI_VENDOR_ID, &x) &&
+		     (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
+			return 1;
+	DBG("PCI: Sanity check failed\n");
+	return 0;
+}
+
+static struct pci_ops * __devinit pci_check_direct(void)
+{
+	unsigned int tmp;
+	unsigned long flags;
+
+	__save_flags(flags); __cli();
+
+	/*
+	 * Check if configuration type 1 works.
+	 */
+	if (pci_probe & PCI_PROBE_CONF1) {
+		outb (0x01, 0xCFB);
+		tmp = inl (0xCF8);
+		outl (0x80000000, 0xCF8);
+		if (inl (0xCF8) == 0x80000000 &&
+		    pci_sanity_check(&pci_direct_conf1)) {
+			outl (tmp, 0xCF8);
+			__restore_flags(flags);
+			printk(KERN_INFO "PCI: Using configuration type 1\n");
+			if (!request_region(0xCF8, 8, "PCI conf1"))
+				return NULL;
+			return &pci_direct_conf1;
+		}
+		outl (tmp, 0xCF8);
+	}
+
+	/*
+	 * Check if configuration type 2 works.
+	 */
+	if (pci_probe & PCI_PROBE_CONF2) {
+		outb (0x00, 0xCFB);
+		outb (0x00, 0xCF8);
+		outb (0x00, 0xCFA);
+		if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 &&
+		    pci_sanity_check(&pci_direct_conf2)) {
+			__restore_flags(flags);
+			printk(KERN_INFO "PCI: Using configuration type 2\n");
+			if (!request_region(0xCF8, 4, "PCI conf2"))
+				return NULL;
+			return &pci_direct_conf2;
+		}
+	}
+
+	__restore_flags(flags);
+	return NULL;
+}
+
+static int __init pci_direct_init(void)
+{
+	if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) 
+		&& (pci_root_ops = pci_check_direct())) {
+		if (pci_root_ops == &pci_direct_conf1) {
+			pci_config_read = pci_conf1_read;
+			pci_config_write = pci_conf1_write;
+		}
+		else {
+			pci_config_read = pci_conf2_read;
+			pci_config_write = pci_conf2_write;
+		}
+	}
+	return 0;
+}
+
+arch_initcall(pci_direct_init);
diff -Nru a/arch/x86_64/pci/fixup.c b/arch/x86_64/pci/fixup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/fixup.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,61 @@
+/*
+ * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
+ *
+
+Short list on x86-64........so far. 
+
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci.h"
+
+static void __devinit  pci_fixup_ncr53c810(struct pci_dev *d)
+{
+	/*
+	 * NCR 53C810 returns class code 0 (at least on some systems).
+	 * Fix class to be PCI_CLASS_STORAGE_SCSI
+	 */
+	if (!d->class) {
+		printk(KERN_WARNING "PCI: fixing NCR 53C810 class code for %s\n", d->slot_name);
+		d->class = PCI_CLASS_STORAGE_SCSI << 8;
+	}
+}
+
+static void __devinit pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	DBG("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+static void __devinit  pci_fixup_ide_trash(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * There exist PCI IDE controllers which have utter garbage
+	 * in first four base registers. Ignore that.
+	 */
+	DBG("PCI: IDE base address trash cleared for %s\n", d->slot_name);
+	for(i=0; i<4; i++)
+		d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pci_fixup_ide_bases },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C810,	pci_fixup_ncr53c810 },
+	{ 0 }
+};
diff -Nru a/arch/x86_64/pci/irq.c b/arch/x86_64/pci/irq.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/irq.c	Sun Jun 16 19:31:40 2002
@@ -0,0 +1,652 @@
+/*
+ *	Low-Level PCI Support for PC -- Routing of Interrupts
+ *
+ *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/io_apic.h>
+
+#include "pci.h"
+
+#define PIRQ_SIGNATURE	(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
+#define PIRQ_VERSION 0x0100
+
+int broken_hp_bios_irq9;
+
+static struct irq_routing_table *pirq_table;
+
+/*
+ * Never use: 0, 1, 2 (timer, keyboard, and cascade)
+ * Avoid using: 13, 14 and 15 (FP error and IDE).
+ * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
+ */
+unsigned int pcibios_irq_mask = 0xfff8;
+
+static int pirq_penalty[16] = {
+	1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
+	0, 0, 0, 0, 1000, 100000, 100000, 100000
+};
+
+struct irq_router {
+	char *name;
+	u16 vendor, device;
+	int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
+	int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
+};
+
+int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+
+/*
+ *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
+ */
+
+static struct irq_routing_table * __init pirq_find_routing_table(void)
+{
+	u8 *addr;
+	struct irq_routing_table *rt;
+	int i;
+	u8 sum;
+
+	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
+		rt = (struct irq_routing_table *) addr;
+		if (rt->signature != PIRQ_SIGNATURE ||
+		    rt->version != PIRQ_VERSION ||
+		    rt->size % 16 ||
+		    rt->size < sizeof(struct irq_routing_table))
+			continue;
+		sum = 0;
+		for(i=0; i<rt->size; i++)
+			sum += addr[i];
+		if (!sum) {
+			DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+			return rt;
+		}
+	}
+	return NULL;
+}
+
+/*
+ *  If we have a IRQ routing table, use it to search for peer host
+ *  bridges.  It's a gross hack, but since there are no other known
+ *  ways how to get a list of buses, we have to go this way.
+ */
+
+static void __init pirq_peer_trick(void)
+{
+	struct irq_routing_table *rt = pirq_table;
+	u8 busmap[256];
+	int i;
+	struct irq_info *e;
+
+	memset(busmap, 0, sizeof(busmap));
+	for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
+		e = &rt->slots[i];
+#ifdef DEBUG
+		{
+			int j;
+			DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
+			for(j=0; j<4; j++)
+				DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
+			DBG("\n");
+		}
+#endif
+		busmap[e->bus] = 1;
+	}
+	for(i=1; i<256; i++)
+		/*
+		 *  It might be a secondary bus, but in this case its parent is already
+		 *  known (ascending bus order) and therefore pci_scan_bus returns immediately.
+		 */
+		if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
+			printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
+	pcibios_last_bus = -1;
+}
+
+/*
+ *  Code for querying and setting of IRQ routes on various interrupt routers.
+ */
+
+void eisa_set_level_irq(unsigned int irq)
+{
+	unsigned char mask = 1 << (irq & 7);
+	unsigned int port = 0x4d0 + (irq >> 3);
+	unsigned char val = inb(port);
+
+	if (!(val & mask)) {
+		DBG(" -> edge");
+		outb(val | mask, port);
+	}
+}
+
+/*
+ * Common IRQ routing practice: nybbles in config space,
+ * offset by some magic constant.
+ */
+static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr)
+{
+	u8 x;
+	unsigned reg = offset + (nr >> 1);
+
+	pci_read_config_byte(router, reg, &x);
+	return (nr & 1) ? (x >> 4) : (x & 0xf);
+}
+
+static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val)
+{
+	u8 x;
+	unsigned reg = offset + (nr >> 1);
+
+	pci_read_config_byte(router, reg, &x);
+	x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val);
+	pci_write_config_byte(router, reg, x);
+}
+
+/*
+ * ALI pirq entries are damn ugly, and completely undocumented.
+ * This has been figured out from pirq tables, and it's not a pretty
+ * picture.
+ */
+static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
+
+	return irqmap[read_config_nybble(router, 0x48, pirq-1)];
+}
+
+static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
+	unsigned int val = irqmap[irq];
+		
+	if (val) {
+		write_config_nybble(router, 0x48, pirq-1, val);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * The VIA pirq rules are nibble-based, like ALI,
+ * but without the ugly irq number munging.
+ */
+static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	return read_config_nybble(router, 0x55, pirq);
+}
+
+static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	write_config_nybble(router, 0x55, pirq, irq);
+	return 1;
+}
+
+/*
+ *	PIRQ routing for SiS 85C503 router used in several SiS chipsets
+ *	According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
+ *	the related registers work as follows:
+ *	
+ *	general: one byte per re-routable IRQ,
+ *		 bit 7      IRQ mapping enabled (0) or disabled (1)
+ *		 bits [6:4] reserved
+ *		 bits [3:0] IRQ to map to
+ *		     allowed: 3-7, 9-12, 14-15
+ *		     reserved: 0, 1, 2, 8, 13
+ *
+ *	individual registers in device config space:
+ *
+ *	0x41/0x42/0x43/0x44:	PCI INT A/B/C/D - bits as in general case
+ *
+ *	0x61:			IDEIRQ: bits as in general case - but:
+ *				bits [6:5] must be written 01
+ *				bit 4 channel-select primary (0), secondary (1)
+ *
+ *	0x62:			USBIRQ: bits as in general case - but:
+ *				bit 4 OHCI function disabled (0), enabled (1)
+ *	
+ *	0x6a:			ACPI/SCI IRQ - bits as in general case
+ *
+ *	0x7e:			Data Acq. Module IRQ - bits as in general case
+ *
+ *	Apparently there are systems implementing PCI routing table using both
+ *	link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
+ *	like 0x62 as link values for USBIRQ e.g. So there is no simple
+ *	"register = offset + pirq" relation.
+ *	Currently we support PCI INTA..D and USBIRQ and try our best to handle
+ *	both link mappings.
+ *	IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
+ */
+
+static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 x;
+	int reg = pirq;
+
+	switch(pirq) {
+		case 0x01:
+		case 0x02:
+		case 0x03:
+		case 0x04:
+			reg += 0x40;
+		case 0x41:
+		case 0x42:
+		case 0x43:
+		case 0x44:
+		case 0x62:
+			pci_read_config_byte(router, reg, &x);
+			if (reg != 0x62)
+				break;
+			if (!(x & 0x40))
+				return 0;
+			break;
+		case 0x61:
+		case 0x6a:
+		case 0x7e:
+			printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
+			return 0;
+		default:			
+			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
+			return 0;
+	}
+	return (x & 0x80) ? 0 : (x & 0x0f);
+}
+
+static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	u8 x;
+	int reg = pirq;
+
+	switch(pirq) {
+		case 0x01:
+		case 0x02:
+		case 0x03:
+		case 0x04:
+			reg += 0x40;
+		case 0x41:
+		case 0x42:
+		case 0x43:
+		case 0x44:
+		case 0x62:
+			x = (irq&0x0f) ? (irq&0x0f) : 0x80;
+			if (reg != 0x62)
+				break;
+			/* always mark OHCI enabled, as nothing else knows about this */
+			x |= 0x40;
+			break;
+		case 0x61:
+		case 0x6a:
+		case 0x7e:
+			printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
+			return 0;
+		default:			
+			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
+			return 0;
+	}
+	pci_write_config_byte(router, reg, x);
+
+	return 1;
+}
+
+#if 0 /* kept as reference */
+/* Support for AMD756 PCI IRQ Routing
+ * Jhon H. Caicedo <jhcaiced@osso.org.co>
+ * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced)
+ * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced)
+ * The AMD756 pirq rules are nibble-based
+ * offset 0x56 0-3 PIRQA  4-7  PIRQB
+ * offset 0x57 0-3 PIRQC  4-7  PIRQD
+ *
+ * AMD8111 is similar NIY.
+ */
+static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 irq;
+	irq = 0;
+	if (pirq <= 4)
+	{
+		irq = read_config_nybble(router, 0x56, pirq - 1);
+	}
+	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n",
+		dev->vendor, dev->device, pirq, irq);
+	return irq;
+}
+
+static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", 
+		dev->vendor, dev->device, pirq, irq);
+	if (pirq <= 4)
+	{
+		write_config_nybble(router, 0x56, pirq - 1, irq);
+	}
+	return 1;
+}
+#endif
+
+static struct irq_router pirq_routers[] = {
+	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
+	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
+	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
+	{ "SIS", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, pirq_sis_get, pirq_sis_set },
+	{ "default", 0, 0, NULL, NULL }
+};
+
+static struct irq_router *pirq_router;
+static struct pci_dev *pirq_router_dev;
+
+static void __init pirq_find_router(void)
+{
+	struct irq_routing_table *rt = pirq_table;
+	struct irq_router *r;
+
+#ifdef CONFIG_PCI_BIOS
+	if (!rt->signature) {
+		printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n");
+		pirq_router = &pirq_bios_router;
+		return;
+	}
+#endif
+
+	DBG("PCI: Attempting to find IRQ router for %04x:%04x\n",
+	    rt->rtr_vendor, rt->rtr_device);
+
+	/* fall back to default router if nothing else found */
+	pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1];
+
+	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
+	if (!pirq_router_dev) {
+		DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
+		return;
+	}
+
+	for(r=pirq_routers; r->vendor; r++) {
+		/* Exact match against router table entry? Use it! */
+		if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) {
+			pirq_router = r;
+			break;
+		}
+		/* Match against router device entry? Use it as a fallback */
+		if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) {
+			pirq_router = r;
+		}
+	}
+	printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
+		pirq_router->name,
+		pirq_router_dev->vendor,
+		pirq_router_dev->device,
+		pirq_router_dev->slot_name);
+}
+
+static struct irq_info *pirq_get_info(struct pci_dev *dev)
+{
+	struct irq_routing_table *rt = pirq_table;
+	int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
+	struct irq_info *info;
+
+	for (info = rt->slots; entries--; info++)
+		if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
+			return info;
+	return NULL;
+}
+
+static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+}
+
+static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
+{
+	u8 pin;
+	struct irq_info *info;
+	int i, pirq, newirq;
+	int irq = 0;
+	u32 mask;
+	struct irq_router *r = pirq_router;
+	struct pci_dev *dev2;
+	char *msg = NULL;
+
+	/* Find IRQ pin */
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (!pin) {
+		DBG(" -> no interrupt pin\n");
+		return 0;
+	}
+	pin = pin - 1;
+
+	/* Find IRQ routing entry */
+
+	if (!pirq_table)
+		return 0;
+	
+	DBG("IRQ for %s:%d", dev->slot_name, pin);
+	info = pirq_get_info(dev);
+	if (!info) {
+		DBG(" -> not found in routing table\n");
+		return 0;
+	}
+	pirq = info->irq[pin].link;
+	mask = info->irq[pin].bitmap;
+	if (!pirq) {
+		DBG(" -> not routed\n");
+		return 0;
+	}
+	DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
+	mask &= pcibios_irq_mask;
+
+	/* Work around broken HP Pavilion Notebooks which assign USB to
+	   IRQ 9 even though it is actually wired to IRQ 11 */
+
+	if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) {
+		dev->irq = 11;
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+		r->set(pirq_router_dev, dev, pirq, 11);
+	}
+
+	/*
+	 * Find the best IRQ to assign: use the one
+	 * reported by the device if possible.
+	 */
+	newirq = dev->irq;
+	if (!((1 << newirq) & mask)) {
+		if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
+		else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, dev->slot_name);
+	}
+	if (!newirq && assign) {
+		for (i = 0; i < 16; i++) {
+			if (!(mask & (1 << i)))
+				continue;
+			if (pirq_penalty[i] < pirq_penalty[newirq] &&
+			    !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ, "pci-test", dev)) {
+				free_irq(i, dev);
+				newirq = i;
+			}
+		}
+	}
+	DBG(" -> newirq=%d", newirq);
+
+	/* Check if it is hardcoded */
+	if ((pirq & 0xf0) == 0xf0) {
+		irq = pirq & 0xf;
+		DBG(" -> hardcoded IRQ %d\n", irq);
+		msg = "Hardcoded";
+	} else if ( r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
+	((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) {
+		DBG(" -> got IRQ %d\n", irq);
+		msg = "Found";
+	} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
+		DBG(" -> assigning IRQ %d", newirq);
+		if (r->set(pirq_router_dev, dev, pirq, newirq)) {
+			eisa_set_level_irq(newirq);
+			DBG(" ... OK\n");
+			msg = "Assigned";
+			irq = newirq;
+		}
+	}
+
+	if (!irq) {
+		DBG(" ... failed\n");
+		if (newirq && mask == (1 << newirq)) {
+			msg = "Guessed";
+			irq = newirq;
+		} else
+			return 0;
+	}
+	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
+
+	/* Update IRQ for all devices with the same pirq value */
+	pci_for_each_dev(dev2) {
+		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
+		if (!pin)
+			continue;
+		pin--;
+		info = pirq_get_info(dev2);
+		if (!info)
+			continue;
+		if (info->irq[pin].link == pirq) {
+			/* We refuse to override the dev->irq information. Give a warning! */
+		    	if ( dev2->irq && dev2->irq != irq && \
+			(!(pci_probe & PCI_USE_PIRQ_MASK) || \
+			((1 << dev2->irq) & mask)) ) {
+		    		printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
+				       dev2->slot_name, dev2->irq, irq);
+		    		continue;
+		    	}
+			dev2->irq = irq;
+			pirq_penalty[irq]++;
+			if (dev != dev2)
+				printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, dev2->slot_name);
+		}
+	}
+	return 1;
+}
+
+static int __init pcibios_irq_init(void)
+{
+	DBG("PCI: IRQ init\n");
+
+	if (pcibios_enable_irq)
+		return 0;
+
+	pirq_table = pirq_find_routing_table();
+
+	if (pirq_table) {
+		pirq_peer_trick();
+		pirq_find_router();
+		if (pirq_table->exclusive_irqs) {
+			int i;
+			for (i=0; i<16; i++)
+				if (!(pirq_table->exclusive_irqs & (1 << i)))
+					pirq_penalty[i] += 100;
+		}
+		/* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
+		if (io_apic_assign_pci_irqs)
+			pirq_table = NULL;
+	}
+
+	pcibios_enable_irq = pirq_enable_irq;
+
+	pcibios_fixup_irqs();
+	return 0;
+}
+
+subsys_initcall(pcibios_irq_init);
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	u8 pin;
+
+	DBG("PCI: IRQ fixup\n");
+	pci_for_each_dev(dev) {
+		/*
+		 * If the BIOS has set an out of range IRQ number, just ignore it.
+		 * Also keep track of which IRQ's are already in use.
+		 */
+		if (dev->irq >= 16) {
+			DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
+			dev->irq = 0;
+		}
+		/* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
+		if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000)
+			pirq_penalty[dev->irq] = 0;
+		pirq_penalty[dev->irq]++;
+	}
+
+	pci_for_each_dev(dev) {
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+#ifdef CONFIG_X86_IO_APIC
+		/*
+		 * Recalculate IRQ numbers if we use the I/O APIC.
+		 */
+		if (io_apic_assign_pci_irqs)
+		{
+			int irq;
+
+			if (pin) {
+				pin--;		/* interrupt pins are numbered starting from 1 */
+				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
+	/*
+	 * Busses behind bridges are typically not listed in the MP-table.
+	 * In this case we have to look up the IRQ based on the parent bus,
+	 * parent slot, and pin number. The SMP code detects such bridged
+	 * busses itself so we should get into this branch reliably.
+	 */
+				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
+					struct pci_dev * bridge = dev->bus->self;
+
+					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
+					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
+							PCI_SLOT(bridge->devfn), pin);
+					if (irq >= 0)
+						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
+							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
+				}
+				if (irq >= 0) {
+					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
+					dev->irq = irq;
+				}
+			}
+		}
+#endif
+		/*
+		 * Still no IRQ? Try to lookup one...
+		 */
+		if (pin && !dev->irq)
+			pcibios_lookup_irq(dev, 0);
+	}
+}
+
+void pcibios_penalize_isa_irq(int irq)
+{
+	/*
+	 *  If any ISAPnP device reports an IRQ in its list of possible
+	 *  IRQ's, we try to avoid assigning it to PCI devices.
+	 */
+	pirq_penalty[irq] += 100;
+}
+
+int pirq_enable_irq(struct pci_dev *dev)
+{
+	u8 pin;
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
+		char *msg;
+		if (io_apic_assign_pci_irqs)
+			msg = " Probably buggy MP table.";
+		else
+			msg = "";
+		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
+		       'A' + pin - 1, dev->slot_name, msg);
+	}
+
+	return 0;
+}
diff -Nru a/arch/x86_64/pci/legacy.c b/arch/x86_64/pci/legacy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/legacy.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,57 @@
+/*
+ * legacy.c - traditional, old school PCI bus probing
+ */
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci.h"
+
+/*
+ * Discover remaining PCI buses in case there are peer host bridges.
+ * We use the number of last PCI bus provided by the PCI BIOS.
+ */
+static void __devinit pcibios_fixup_peer_bridges(void)
+{
+	int n;
+	struct pci_bus bus;
+	struct pci_dev dev;
+	u16 l;
+
+	if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
+		return;
+	DBG("PCI: Peer bridge fixup\n");
+	for (n=0; n <= pcibios_last_bus; n++) {
+		if (pci_bus_exists(&pci_root_buses, n))
+			continue;
+		bus.number = n;
+		bus.ops = pci_root_ops;
+		dev.bus = &bus;
+		for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
+			if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
+			    l != 0x0000 && l != 0xffff) {
+				DBG("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
+				printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
+				pci_scan_bus(n, pci_root_ops, NULL);
+				break;
+			}
+	}
+}
+
+static int __init pci_legacy_init(void)
+{
+	if (!pci_root_ops) {
+		printk("PCI: System does not support PCI\n");
+		return 0;
+	}
+
+	if (pcibios_scanned++)
+		return 0;
+
+	printk("PCI: Probing PCI hardware\n");
+	pci_root_bus = pcibios_scan_root(0);
+
+	pcibios_fixup_peer_bridges();
+
+	return 0;
+}
+
+subsys_initcall(pci_legacy_init);
diff -Nru a/arch/x86_64/pci/pci.h b/arch/x86_64/pci/pci.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/pci.h	Sun Jun 16 19:31:40 2002
@@ -0,0 +1,73 @@
+/*
+ *	Low-Level PCI Access for x86-64 machines.
+ *
+ *	(c) 1999 Martin Mares <mj@ucw.cz>
+ */
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#define PCI_PROBE_BIOS		0x0001
+#define PCI_PROBE_CONF1		0x0002
+#define PCI_PROBE_CONF2		0x0004
+#define PCI_NO_SORT		0x0100
+#define PCI_BIOS_SORT		0x0200
+#define PCI_NO_CHECKS		0x0400
+#define PCI_USE_PIRQ_MASK	0x0800
+#define PCI_ASSIGN_ROMS		0x1000
+#define PCI_BIOS_IRQ_SCAN	0x2000
+#define PCI_ASSIGN_ALL_BUSSES	0x4000
+#define PCI_NO_ACPI_ROUTING	0x8000
+
+extern unsigned int pci_probe;
+
+extern unsigned int pcibios_max_latency;
+
+void pcibios_resource_survey(void);
+int pcibios_enable_resources(struct pci_dev *);
+
+/* pci-pc.c */
+
+extern int pcibios_last_bus;
+extern struct pci_bus *pci_root_bus;
+extern struct pci_ops *pci_root_ops;
+
+/* pci-irq.c */
+
+struct irq_info {
+	u8 bus, devfn;			/* Bus, device and function */
+	struct {
+		u8 link;		/* IRQ line ID, chipset dependent, 0=not routed */
+		u16 bitmap;		/* Available IRQs */
+	} __attribute__((packed)) irq[4];
+	u8 slot;			/* Slot number, 0=onboard */
+	u8 rfu;
+} __attribute__((packed));
+
+struct irq_routing_table {
+	u32 signature;			/* PIRQ_SIGNATURE should be here */
+	u16 version;			/* PIRQ_VERSION */
+	u16 size;			/* Table size in bytes */
+	u8 rtr_bus, rtr_devfn;		/* Where the interrupt router lies */
+	u16 exclusive_irqs;		/* IRQs devoted exclusively to PCI usage */
+	u16 rtr_vendor, rtr_device;	/* Vendor and device ID of interrupt router */
+	u32 miniport_data;		/* Crap */
+	u8 rfu[11];
+	u8 checksum;			/* Modulo 256 checksum must give zero */
+	struct irq_info slots[0];
+} __attribute__((packed));
+
+extern unsigned int pcibios_irq_mask;
+
+extern int pcibios_scanned;
+extern spinlock_t pci_config_lock;
+
+void pcibios_fixup_irqs(void);
+int pirq_enable_irq(struct pci_dev *dev);
+
+extern int (*pcibios_enable_irq)(struct pci_dev *dev);
diff -Nru a/arch/x86_64/pci/x86-64.c b/arch/x86_64/pci/x86-64.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/pci/x86-64.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,324 @@
+/*
+ *	Low-Level PCI Access for x86-64 machines
+ *
+ * Copyright 1993, 1994 Drew Eckhardt
+ *      Visionary Computing
+ *      (Unix and Linux consulting and custom programming)
+ *      Drew@Colorado.EDU
+ *      +1 (303) 786-7975
+ *
+ * Drew's work was sponsored by:
+ *	iX Multiuser Multitasking Magazine
+ *	Hannover, Germany
+ *	hm@ix.de
+ *
+ * Copyright 1997--2000 Martin Mares <mj@ucw.cz>
+ *
+ * For more information, please consult the following manuals (look at
+ * http://www.pcisig.com/ for how to get them):
+ *
+ * PCI BIOS Specification
+ * PCI Local Bus Specification
+ * PCI to PCI Bridge Specification
+ * PCI System Design Guide
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+
+#include "pci.h"
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+
+/*
+ *  Handle resources of PCI devices.  If the world were perfect, we could
+ *  just allocate all the resource regions and do nothing more.  It isn't.
+ *  On the other hand, we cannot just re-allocate all devices, as it would
+ *  require us to know lots of host bridge internals.  So we attempt to
+ *  keep as much of the original configuration as possible, but tweak it
+ *  when it's found to be wrong.
+ *
+ *  Known BIOS problems we have to work around:
+ *	- I/O or memory regions not configured
+ *	- regions configured, but not enabled in the command register
+ *	- bogus I/O addresses above 64K used
+ *	- expansion ROMs left enabled (this may sound harmless, but given
+ *	  the fact the PCI specs explicitly allow address decoders to be
+ *	  shared between expansion ROMs and other resource regions, it's
+ *	  at least dangerous)
+ *
+ *  Our solution:
+ *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ *	    This gives us fixed barriers on where we can allocate.
+ *	(2) Allocate resources for all enabled devices.  If there is
+ *	    a collision, just mark the resource as unallocated. Also
+ *	    disable expansion ROMs during this step.
+ *	(3) Try to allocate resources for disabled devices.  If the
+ *	    resources were assigned correctly, everything goes well,
+ *	    if they weren't, they won't disturb allocation of other
+ *	    resources.
+ *	(4) Assign new addresses to resources which were either
+ *	    not configured at all or misconfigured.  If explicitly
+ *	    requested by the user, configure expansion ROM address
+ *	    as well.
+ */
+
+static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r, *pr;
+
+	/* Depth-First Search on bus tree */
+	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		if ((dev = bus->self)) {
+			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+				r = &dev->resource[idx];
+				if (!r->start)
+					continue;
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0)
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
+			}
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r, *pr;
+
+	pci_for_each_dev(dev) {
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++) {
+			r = &dev->resource[idx];
+			if (r->parent)		/* Already allocated */
+				continue;
+			if (!r->start)		/* Address not assigned at all */
+				continue;
+			if (r->flags & IORESOURCE_IO)
+				disabled = !(command & PCI_COMMAND_IO);
+			else
+				disabled = !(command & PCI_COMMAND_MEMORY);
+			if (pass == disabled) {
+				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
+				    r->start, r->end, r->flags, disabled, pass);
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0) {
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
+					/* We'll assign a new address later */
+					r->end -= r->start;
+					r->start = 0;
+				}
+			}
+		}
+		if (!pass) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
+				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
+				u32 reg;
+				DBG("PCI: Switching off ROM of %s\n", dev->slot_name);
+				r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
+			}
+		}
+	}
+}
+
+static void __init pcibios_assign_resources(void)
+{
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r;
+
+	pci_for_each_dev(dev) {
+		int class = dev->class >> 8;
+
+		/* Don't touch classless devices and host bridges */
+		if (!class || class == PCI_CLASS_BRIDGE_HOST)
+			continue;
+
+		for(idx=0; idx<6; idx++) {
+			r = &dev->resource[idx];
+
+			/*
+			 *  Don't touch IDE controllers and I/O ports of video cards!
+			 */
+			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
+			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+				continue;
+
+			/*
+			 *  We shall assign a new address to this resource, either because
+			 *  the BIOS forgot to do so or because we have decided the old
+			 *  address was unusable for some reason.
+			 */
+			if (!r->start && r->end)
+				pci_assign_resource(dev, idx);
+		}
+
+		if (pci_probe & PCI_ASSIGN_ROMS) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			r->end -= r->start;
+			r->start = 0;
+			if (r->end)
+				pci_assign_resource(dev, PCI_ROM_RESOURCE);
+		}
+	}
+}
+
+void __init pcibios_resource_survey(void)
+{
+	DBG("PCI: Allocating resources\n");
+	pcibios_allocate_bus_resources(&pci_root_buses);
+	pcibios_allocate_resources(0);
+	pcibios_allocate_resources(1);
+	pcibios_assign_resources();
+}
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check the latency
+ *  timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	unsigned long prot;
+
+	/* I/O space cannot be accessed via normal processor loads and
+	 * stores on this platform.
+	 */
+	if (mmap_state == pci_mmap_io)
+		return -EINVAL;
+
+	/* Leave vm_pgoff as-is, the PCI space address is the physical
+	 * address on this platform.
+	 */
+	vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
+
+	prot = pgprot_val(vma->vm_page_prot);
+	if (boot_cpu_data.x86 > 3)
+		prot |= _PAGE_PCD | _PAGE_PWT;
+	vma->vm_page_prot = __pgprot(prot);
+
+	/* Write-combine setting is ignored, it is changed via the mtrr
+	 * interfaces on this platform.
+	 */
+	if (remap_page_range(vma, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
+			     vma->vm_end - vma->vm_start,
+			     vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
diff -Nru a/arch/x86_64/tools/offset.c b/arch/x86_64/tools/offset.c
--- a/arch/x86_64/tools/offset.c	Sun Jun 16 19:31:40 2002
+++ b/arch/x86_64/tools/offset.c	Sun Jun 16 19:31:40 2002
@@ -24,7 +24,6 @@
 	output("#ifndef ASM_OFFSET_H\n");
 	output("#define ASM_OFFSET_H 1\n"); 
 
-	// task struct entries needed by entry.S
 #define ENTRY(entry) outconst("#define tsk_" #entry " %0", offsetof(struct task_struct, entry))
 	ENTRY(state);
 	ENTRY(flags); 
@@ -43,24 +42,8 @@
 	ENTRY(irqcount);
 	ENTRY(cpunumber);
 	ENTRY(irqstackptr);
-	ENTRY(__softirq_pending); 
-	ENTRY(__local_irq_count);
-	ENTRY(__local_bh_count);
-	ENTRY(__ksoftirqd_task);
-	ENTRY(level4_pgt);
-	ENTRY(me);
 #undef ENTRY
-	output("#ifdef __ASSEMBLY__"); 
-#define CONST(t) outconst("#define " #t " %0", t)
-	CONST(TASK_SIZE);
-	CONST(SIGCHLD); 
-	CONST(CLONE_VFORK); 
-	CONST(CLONE_VM); 
-#undef CONST
-	output("#endif"); 
-
 	output("#endif\n"); 
 
 	return(0); 
 } 
-
diff -Nru a/arch/x86_64/vmlinux.lds b/arch/x86_64/vmlinux.lds
--- a/arch/x86_64/vmlinux.lds	Sun Jun 16 19:31:39 2002
+++ b/arch/x86_64/vmlinux.lds	Sun Jun 16 19:31:39 2002
@@ -3,8 +3,8 @@
  */
 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
 OUTPUT_ARCH(i386:x86-64)
-jiffies = jiffies_64;
 ENTRY(_start)
+jiffies_64 = jiffies;
 SECTIONS
 {
   . = 0xffffffff80100000;
diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	Sun Jun 16 19:31:41 2002
+++ b/drivers/Makefile	Sun Jun 16 19:31:41 2002
@@ -5,13 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-
-mod-subdirs :=	dio mtd sbus video macintosh usb input telephony sgi ide \
-		message scsi md ieee1394 pnp isdn atm \
-		fc4 i2c acpi bluetooth input/serio \
-		input/gameport parport hotplug \
-		base char block misc net media cdrom
-
 obj-$(CONFIG_PCI)		+= pci/
 obj-$(CONFIG_ACPI)		+= acpi/
 obj-$(CONFIG_PARPORT)		+= parport/
diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acorn/block/fd1772.c	Sun Jun 16 19:31:40 2002
@@ -154,6 +154,8 @@
 
 #define MAJOR_NR FLOPPY_MAJOR
 #define FLOPPY_DMA 0
+#define DEVICE_NAME "floppy"
+#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
 #include <linux/blk.h>
 
 /* Note: FD_MAX_UNITS could be redefined to 2 for the Atari (with
@@ -596,7 +598,7 @@
 	CURRENT->errors++;
 	if (CURRENT->errors >= MAX_ERRORS) {
 		printk("fd%d: too many errors.\n", SelectedDrive);
-		end_request(0);
+		end_request(CURRENT, 0);
 	} else if (CURRENT->errors == RECALIBRATE_ERRORS) {
 		printk("fd%d: recalibrating\n", SelectedDrive);
 		if (SelectedDrive != -1)
@@ -621,23 +623,25 @@
 
 static void do_fd_action(int drive)
 {
+	struct request *req;
 	DPRINT(("do_fd_action unit[drive].track=%d\n", unit[drive].track));
 
 #ifdef TRACKBUFFER
 repeat:
 
 	if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
+		req = CURRENT;
 		if (ReqCmd == READ) {
 			copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
-			if (++ReqCnt < CURRENT->current_nr_sectors) {
+			if (++ReqCnt < req->current_nr_sectors) {
 				/* read next sector */
 				setup_req_params( drive );
 				goto repeat;
 			} else {
 				/* all sectors finished */
-				CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
-				CURRENT->sector += CURRENT->current_nr_sectors;
-				end_request( 1 );
+				req->nr_sectors -= req->current_nr_sectors;
+				req->sector += req->current_nr_sectors;
+				end_request(req, 1);
 				redo_fd_request();
 				return;
 			}
@@ -1020,7 +1024,7 @@
 		/* all sectors finished */
 		CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
 		CURRENT->sector += CURRENT->current_nr_sectors;
-		end_request(1);
+		end_request(CURRENT, 1);
 		redo_fd_request();
 	}
 	return;
@@ -1232,7 +1236,7 @@
 	if (!floppy->connected) {
 		/* drive not connected */
 		printk("Unknown Device: fd%d\n", drive);
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 	if (type == 0) {
@@ -1247,7 +1251,7 @@
 		--type;
 		if (type >= NUM_DISK_TYPES) {
 			printk("fd%d: invalid disk format", drive);
-			end_request(0);
+			end_request(CURRENT, 0);
 			goto repeat;
 		}
 		floppy->disktype = &disk_type[type];
@@ -1256,7 +1260,7 @@
 	}
 
 	if (CURRENT->sector + 1 > floppy->disktype->blocks) {
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 	/* stop deselect timer */
diff -Nru a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
--- a/drivers/acorn/block/mfmhd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acorn/block/mfmhd.c	Sun Jun 16 19:31:39 2002
@@ -114,6 +114,7 @@
 #include <linux/delay.h>
 
 #define MAJOR_NR	MFM_ACORN_MAJOR
+#define DEVICE_NR(device) (minor(device) >> 6)
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 
@@ -126,6 +127,7 @@
 #include <asm/ecard.h>
 #include <asm/hardware/ioc.h>
 
+static void (*do_mfm)(void) = NULL;
 /*
  * This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc
  */
@@ -510,7 +512,7 @@
 			CURRENT->sector += CURRENT->current_nr_sectors;
 			SectorsLeftInRequest -= CURRENT->current_nr_sectors;
 
-			end_request(1);
+			end_request(CURRENT, 1);
 			if (SectorsLeftInRequest) {
 				hdc63463_dataptr = (unsigned int) CURRENT->buffer;
 				Copy_buffer = CURRENT->buffer;
@@ -570,7 +572,7 @@
 		DBG("mfm_rw_intr: returned from cont->done\n");
 	} else {
 		/* Its going to generate another interrupt */
-		DEVICE_INTR = mfm_rw_intr;
+		do_mfm = mfm_rw_intr;
 	};
 }
 
@@ -578,7 +580,7 @@
 {
 	DBG("setting up for rw...\n");
 
-	DEVICE_INTR = mfm_rw_intr;
+	do_mfm = mfm_rw_intr;
 	issue_command(raw_cmd.cmdcode, raw_cmd.cmddata, raw_cmd.cmdlen);
 }
 
@@ -608,7 +610,7 @@
 	/* Command end without seek end (see data sheet p.20) for parallel seek
 	   - we have to send a POL command to wait for the seek */
 	if (mfm_status & STAT_CED) {
-		DEVICE_INTR = mfm_recal_intr;
+		do_mfm = mfm_recal_intr;
 		issue_command(CMD_POL, NULL, 0);
 		return;
 	}
@@ -638,7 +640,7 @@
 		return;
 	}
 	if (mfm_status & STAT_CED) {
-		DEVICE_INTR = mfm_seek_intr;
+		do_mfm = mfm_seek_intr;
 		issue_command(CMD_POL, NULL, 0);
 		return;
 	}
@@ -696,7 +698,7 @@
 
 	DBG("seeking...\n");
 	if (MFM_DRV_INFO.cylinder < 0) {
-		DEVICE_INTR = mfm_recal_intr;
+		do_mfm = mfm_recal_intr;
 		DBG("mfm_seek: about to call specify\n");
 		mfm_specify ();	/* DAG added this */
 
@@ -712,7 +714,7 @@
 		cmdb[2] = raw_cmd.cylinder >> 8;
 		cmdb[3] = raw_cmd.cylinder;
 
-		DEVICE_INTR = mfm_seek_intr;
+		do_mfm = mfm_seek_intr;
 		issue_command(CMD_SEK, cmdb, 4);
 	} else
 		mfm_setup_rw();
@@ -733,7 +735,7 @@
 		/* Apparently worked - let's check bytes left to DMA */
 		if (hdc63463_dataleft != (PartFragRead_SectorsLeft * 256)) {
 			printk("mfm: request_done - dataleft=%d - should be %d - Eek!\n", hdc63463_dataleft, PartFragRead_SectorsLeft * 256);
-			end_request(0);
+			end_request(CURRENT, 0);
 			Busy = 0;
 		};
 		/* Potentially this means that we've done; but we might be doing
@@ -766,7 +768,7 @@
 		DBG("request_done: returned from mfm_request\n");
 	} else {
 		printk("mfm:request_done: update=0\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 		Busy = 0;
 	}
 }
@@ -907,7 +909,7 @@
 
 		if (blk_queue_empty(QUEUE)) {
 			printk("mfm_request: Exiting due to empty queue (pre)\n");
-			DEVICE_INTR = NULL;
+			do_mfm = NULL;
 			Busy = 0;
 			return;
 		}
@@ -928,7 +930,7 @@
 				printk("mfm%c: bad access: block=%d, count=%d, nr_sects=%ld\n", (dev >> 6)+'a',
 				       block, nsect, mfm[dev].nr_sects);
 			printk("mfm: continue 1\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			Busy = 0;
 			continue;
 		}
@@ -949,7 +951,7 @@
 
 		if (CURRENT->cmd != READ && CURRENT->cmd != WRITE) {
 			printk("unknown mfm-command %d\n", CURRENT->cmd);
-			end_request(0);
+			end_request(CURRENT, 0);
 			Busy = 0;
 			printk("mfm: continue 4\n");
 			continue;
@@ -969,9 +971,9 @@
 
 static void mfm_interrupt_handler(int unused, void *dev_id, struct pt_regs *regs)
 {
-	void (*handler) (void) = DEVICE_INTR;
+	void (*handler) (void) = do_mfm;
 
-	DEVICE_INTR = NULL;
+	do_mfm = NULL;
 
 	DBG("mfm_interrupt_handler (handler=0x%p)\n", handler);
 
diff -Nru a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c
--- a/drivers/acorn/scsi/acornscsi.c	Sun Jun 16 19:31:38 2002
+++ b/drivers/acorn/scsi/acornscsi.c	Sun Jun 16 19:31:38 2002
@@ -154,7 +154,6 @@
 
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
-#include "../../scsi/constants.h"
 #include "acornscsi.h"
 #include "msgqueue.h"
 #include "scsi.h"
diff -Nru a/drivers/acorn/scsi/cumana_1.c b/drivers/acorn/scsi/cumana_1.c
--- a/drivers/acorn/scsi/cumana_1.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acorn/scsi/cumana_1.c	Sun Jun 16 19:31:39 2002
@@ -61,7 +61,6 @@
 
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
-#include "../../scsi/constants.h"
 
 #include <scsi/scsicam.h>
 
diff -Nru a/drivers/acorn/scsi/ecoscsi.c b/drivers/acorn/scsi/ecoscsi.c
--- a/drivers/acorn/scsi/ecoscsi.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acorn/scsi/ecoscsi.c	Sun Jun 16 19:31:41 2002
@@ -54,7 +54,6 @@
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
 #include "../../scsi/NCR5380.h"
-#include "../../scsi/constants.h"
 
 #define ECOSCSI_PUBLIC_RELEASE 1
 
diff -Nru a/drivers/acorn/scsi/oak.c b/drivers/acorn/scsi/oak.c
--- a/drivers/acorn/scsi/oak.c	Sun Jun 16 19:31:38 2002
+++ b/drivers/acorn/scsi/oak.c	Sun Jun 16 19:31:38 2002
@@ -59,7 +59,6 @@
 
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
-#include "../../scsi/constants.h"
 
 #define OAKSCSI_PUBLIC_RELEASE 1
 
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/Makefile	Sun Jun 16 19:31:40 2002
@@ -12,7 +12,7 @@
 
 EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
 
-export-objs 	:= acpi_ksyms.o
+export-objs 	:= acpi_ksyms.o processor.o
 
 obj-y		:= acpi_ksyms.o 
 
diff -Nru a/drivers/acpi/acpi_drivers.h b/drivers/acpi/acpi_drivers.h
--- a/drivers/acpi/acpi_drivers.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/acpi_drivers.h	Sun Jun 16 19:31:41 2002
@@ -1,5 +1,5 @@
 /*
- *  acpi_drivers.h  ($Revision: 29 $)
+ *  acpi_drivers.h  ($Revision: 30 $)
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -160,6 +160,7 @@
 
 int acpi_pci_root_init (void);
 void acpi_pci_root_exit (void);
+void acpi_pci_get_translations (acpi_pci_id* id, u64* mem_tra, u64* io_tra);
 
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/bus.c	Sun Jun 16 19:31:40 2002
@@ -92,7 +92,7 @@
 #ifdef CONFIG_LDM
 
 static int acpi_device_probe(struct device *dev);
-static int acpi_device_remove(struct device *dev, u32 flags);
+static int acpi_device_remove(struct device *dev);
 static int acpi_device_suspend(struct device *dev, u32 state, u32 stage);
 static int acpi_device_resume(struct device *dev, u32 stage);
 
@@ -121,8 +121,7 @@
 
 static int
 acpi_device_remove (
-	struct device		*dev,
-	u32			flags)
+	struct device		*dev)
 {
 	ACPI_FUNCTION_TRACE("acpi_device_remove");
 
diff -Nru a/drivers/acpi/debugger/dbcmds.c b/drivers/acpi/debugger/dbcmds.c
--- a/drivers/acpi/debugger/dbcmds.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/debugger/dbcmds.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dbcmds - debug commands and output routines
- *              $Revision: 83 $
+ *              $Revision: 84 $
  *
  ******************************************************************************/
 
@@ -663,7 +663,7 @@
 	/* Display short information about the object */
 
 	if (obj_desc) {
-		switch (obj_desc->common.type) {
+		switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 		case ACPI_TYPE_METHOD:
 			acpi_os_printf (" #Args %d Concurrency %X", obj_desc->method.param_count, obj_desc->method.concurrency);
 			break;
@@ -729,7 +729,8 @@
 	}
 
 	acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT);
-	acpi_os_printf ("Objects of type [%s] defined in the current ACPI Namespace: \n", acpi_ut_get_type_name (type));
+	acpi_os_printf ("Objects of type [%s] defined in the current ACPI Namespace: \n",
+		acpi_ut_get_type_name (type));
 
 	acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT);
 
diff -Nru a/drivers/acpi/debugger/dbdisply.c b/drivers/acpi/debugger/dbdisply.c
--- a/drivers/acpi/debugger/dbdisply.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/debugger/dbdisply.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dbdisply - debug display commands
- *              $Revision: 73 $
+ *              $Revision: 75 $
  *
  ******************************************************************************/
 
@@ -300,9 +300,9 @@
 		return;
 	}
 
-	acpi_os_printf (" %s", acpi_ut_get_type_name (obj_desc->common.type));
+	acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc));
 
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_INTEGER:
 
 		acpi_os_printf (" %8.8X%8.8X", ACPI_HIDWORD (obj_desc->integer.value),
@@ -396,7 +396,7 @@
 
 	case ACPI_DESC_TYPE_OPERAND:
 
-		type = obj_desc->common.type;
+		type = ACPI_GET_OBJECT_TYPE (obj_desc);
 		if (type > INTERNAL_TYPE_MAX) {
 			acpi_os_printf (" Type %hX [Invalid Type]", type);
 			return;
@@ -404,25 +404,9 @@
 
 		/* Decode the ACPI object type */
 
-		switch (obj_desc->common.type) {
+		switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 		case INTERNAL_TYPE_REFERENCE:
 			switch (obj_desc->reference.opcode) {
-			case AML_ZERO_OP:
-				acpi_os_printf ("[Const]         Zero (0) [Null Target]", 0);
-				break;
-
-			case AML_ONES_OP:
-				acpi_os_printf ("[Const]         Ones (0xFFFFFFFFFFFFFFFF) [No Limit]");
-				break;
-
-			case AML_ONE_OP:
-				acpi_os_printf ("[Const]         One (1)");
-				break;
-
-			case AML_REVISION_OP:
-				acpi_os_printf ("[Const]         Revision (%X)", ACPI_CA_SUPPORT_LEVEL);
-				break;
-
 			case AML_LOCAL_OP:
 				acpi_os_printf ("[Local%d] ", obj_desc->reference.offset);
 				if (walk_state) {
@@ -451,6 +435,8 @@
 				break;
 
 			default:
+				acpi_os_printf ("Unknown Reference opcode %X\n",
+					obj_desc->reference.opcode);
 				break;
 
 			}
diff -Nru a/drivers/acpi/debugger/dbstats.c b/drivers/acpi/debugger/dbstats.c
--- a/drivers/acpi/debugger/dbstats.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/debugger/dbstats.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dbstats - Generation and display of ACPI table statistics
- *              $Revision: 59 $
+ *              $Revision: 60 $
  *
  ******************************************************************************/
 
@@ -87,18 +87,18 @@
 
 	acpi_gbl_num_objects++;
 
-	if (obj_desc->common.type > INTERNAL_TYPE_NODE_MAX)
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) > INTERNAL_TYPE_NODE_MAX)
 	{
 		acpi_gbl_obj_type_count_misc++;
 	}
 	else
 	{
-		acpi_gbl_obj_type_count [obj_desc->common.type]++;
+		acpi_gbl_obj_type_count [ACPI_GET_OBJECT_TYPE (obj_desc)]++;
 	}
 
 	/* Count the sub-objects */
 
-	switch (obj_desc->common.type)
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc))
 	{
 	case ACPI_TYPE_PACKAGE:
 		for (i = 0; i < obj_desc->package.count; i++)
diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
--- a/drivers/acpi/dispatcher/dsmthdat.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/dispatcher/dsmthdat.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dsmthdat - control method arguments and local variables
- *              $Revision: 61 $
+ *              $Revision: 62 $
  *
  ******************************************************************************/
 
@@ -354,7 +354,7 @@
 
 	/* Get the object type */
 
-	return_VALUE (object->common.type);
+	return_VALUE (ACPI_GET_OBJECT_TYPE (object));
 }
 
 
@@ -602,7 +602,7 @@
 			 * (perform the indirect store)
 			 */
 			status = acpi_ns_attach_object ((acpi_namespace_node *) current_obj_desc,
-					  obj_desc, obj_desc->common.type);
+					  obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc));
 			return_ACPI_STATUS (status);
 		}
 
diff -Nru a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
--- a/drivers/acpi/dispatcher/dsobject.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/dispatcher/dsobject.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dsobject - Dispatcher object management routines
- *              $Revision: 99 $
+ *              $Revision: 103 $
  *
  *****************************************************************************/
 
@@ -29,6 +29,7 @@
 #include "amlcode.h"
 #include "acdispat.h"
 #include "acnamesp.h"
+#include "acinterp.h"
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsobject")
@@ -241,9 +242,10 @@
 {
 	const acpi_opcode_info  *op_info;
 	acpi_operand_object     *obj_desc;
+	acpi_status             status = AE_OK;
 
 
-	ACPI_FUNCTION_NAME ("Ds_init_object_from_op");
+	ACPI_FUNCTION_TRACE ("Ds_init_object_from_op");
 
 
 	obj_desc = *ret_obj_desc;
@@ -251,12 +253,12 @@
 	if (op_info->class == AML_CLASS_UNKNOWN) {
 		/* Unknown opcode */
 
-		return (AE_TYPE);
+		return_ACPI_STATUS (AE_TYPE);
 	}
 
 	/* Perform per-object initialization */
 
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_BUFFER:
 
 		/*
@@ -281,7 +283,62 @@
 
 	case ACPI_TYPE_INTEGER:
 
-		obj_desc->integer.value = op->common.value.integer;
+		switch (op_info->type) {
+		case AML_TYPE_CONSTANT:
+			/*
+			 * Resolve AML Constants here - AND ONLY HERE!
+			 * All constants are integers.
+			 * We mark the integer with a flag that indicates that it started life
+			 * as a constant -- so that stores to constants will perform as expected (noop).
+			 * (Zero_op is used as a placeholder for optional target operands.)
+			 */
+			obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
+
+			switch (opcode) {
+			case AML_ZERO_OP:
+
+				obj_desc->integer.value = 0;
+				break;
+
+			case AML_ONE_OP:
+
+				obj_desc->integer.value = 1;
+				break;
+
+			case AML_ONES_OP:
+
+				obj_desc->integer.value = ACPI_INTEGER_MAX;
+
+				/* Truncate value if we are executing from a 32-bit ACPI table */
+
+				acpi_ex_truncate_for32bit_table (obj_desc);
+				break;
+
+			case AML_REVISION_OP:
+
+				obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL;
+				break;
+
+			default:
+
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode));
+				status = AE_AML_OPERAND_TYPE;
+				break;
+			}
+			break;
+
+
+		case AML_TYPE_LITERAL:
+
+			obj_desc->integer.value = op->common.value.integer;
+			break;
+
+
+		default:
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type));
+			status = AE_AML_OPERAND_TYPE;
+			break;
+		}
 		break;
 
 
@@ -323,7 +380,7 @@
 			break;
 
 
-		default: /* Constants, Literals, etc.. */
+		default: /* Other literals, etc.. */
 
 			if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
 				/* Node was saved in Op */
@@ -340,12 +397,13 @@
 	default:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n",
-			obj_desc->common.type));
+			ACPI_GET_OBJECT_TYPE (obj_desc)));
 
+		status = AE_AML_OPERAND_TYPE;
 		break;
 	}
 
-	return (AE_OK);
+	return_ACPI_STATUS (status);
 }
 
 
@@ -380,7 +438,7 @@
 
 	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
 		/*
-		 * This is an object reference.  If this name was
+		 * This is an named object reference.  If this name was
 		 * previously looked up in the namespace, it was stored in this op.
 		 * Otherwise, go ahead and look it up now
 		 */
@@ -435,7 +493,9 @@
  *
  * FUNCTION:    Acpi_ds_build_internal_buffer_obj
  *
- * PARAMETERS:  Op              - Parser object to be translated
+ * PARAMETERS:  Walk_state      - Current walk state
+ *              Op              - Parser object to be translated
+ *              Buffer_length   - Length of the buffer
  *              Obj_desc_ptr    - Where the ACPI internal object is returned
  *
  * RETURN:      Status
@@ -541,7 +601,9 @@
  *
  * FUNCTION:    Acpi_ds_build_internal_package_obj
  *
- * PARAMETERS:  Op              - Parser object to be translated
+ * PARAMETERS:  Walk_state      - Current walk state
+ *              Op              - Parser object to be translated
+ *              Package_length  - Number of elements in the package
  *              Obj_desc_ptr    - Where the ACPI internal object is returned
  *
  * RETURN:      Status
@@ -658,12 +720,13 @@
  *
  * FUNCTION:    Acpi_ds_create_node
  *
- * PARAMETERS:  Op              - Parser object to be translated
- *              Obj_desc_ptr    - Where the ACPI internal object is returned
+ * PARAMETERS:  Walk_state      - Current walk state
+ *              Node            - NS Node to be initialized
+ *              Op              - Parser object to be translated
  *
  * RETURN:      Status
  *
- * DESCRIPTION:
+ * DESCRIPTION: Create the object to be associated with a namespace node
  *
  ****************************************************************************/
 
@@ -704,7 +767,7 @@
 
 	/* Re-type the object according to it's argument */
 
-	node->type = obj_desc->common.type;
+	node->type = ACPI_GET_OBJECT_TYPE (obj_desc);
 
 	/* Attach obj to node */
 
diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/dispatcher/dsopcode.c	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: dsopcode - Dispatcher Op Region support and handling of
  *                         "control" opcodes
- *              $Revision: 79 $
+ *              $Revision: 80 $
  *
  *****************************************************************************/
 
@@ -396,10 +396,10 @@
 
 	/* Host object must be a Buffer */
 
-	if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
+	if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Target of Create Field is not a Buffer object - %s\n",
-			acpi_ut_get_type_name (buffer_desc->common.type)));
+			acpi_ut_get_object_type_name (buffer_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
@@ -1021,7 +1021,7 @@
 			 * Allow references created by the Index operator to return unchanged.
 			 */
 			if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) &&
-				((walk_state->results->results.obj_desc [0])->common.type == INTERNAL_TYPE_REFERENCE) &&
+				(ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == INTERNAL_TYPE_REFERENCE) &&
 				((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) {
 				status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
 				if (ACPI_FAILURE (status)) {
diff -Nru a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
--- a/drivers/acpi/dispatcher/dsutils.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/dispatcher/dsutils.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dsutils - Dispatcher utilities
- *              $Revision: 92 $
+ *              $Revision: 93 $
  *
  ******************************************************************************/
 
@@ -380,8 +380,8 @@
 			/*
 			 * If the name is null, this means that this is an
 			 * optional result parameter that was not specified
-			 * in the original ASL.  Create an Reference for a
-			 * placeholder
+			 * in the original ASL.  Create a Zero Constant for a
+			 * placeholder.  (Store to a constant is a Noop.)
 			 */
 			opcode = AML_ZERO_OP;       /* Has no arguments! */
 
diff -Nru a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
--- a/drivers/acpi/dispatcher/dswexec.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/dispatcher/dswexec.c	Sun Jun 16 19:31:41 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: dswexec - Dispatcher method execution callbacks;
  *                        dispatch to interpreter.
- *              $Revision: 92 $
+ *              $Revision: 94 $
  *
  *****************************************************************************/
 
@@ -113,10 +113,10 @@
 	 * Result of predicate evaluation currently must
 	 * be a number
 	 */
-	if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Bad predicate (not a number) Obj_desc=%p State=%p Type=%X\n",
-			obj_desc, walk_state, obj_desc->common.type));
+			obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
@@ -124,7 +124,7 @@
 
 	/* Truncate the predicate to 32-bits if necessary */
 
-	acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
+	acpi_ex_truncate_for32bit_table (obj_desc);
 
 	/*
 	 * Save the result of the predicate evaluation on
@@ -605,7 +605,7 @@
 	 * ACPI 2.0 support for 64-bit integers: Truncate numeric
 	 * result value if we are executing from a 32-bit ACPI table
 	 */
-	acpi_ex_truncate_for32bit_table (walk_state->result_obj, walk_state);
+	acpi_ex_truncate_for32bit_table (walk_state->result_obj);
 
 	/*
 	 * Check if we just completed the evaluation of a
diff -Nru a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
--- a/drivers/acpi/dispatcher/dswstate.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/dispatcher/dswstate.c	Sun Jun 16 19:31:41 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dswstate - Dispatcher parse tree walk management routines
- *              $Revision: 64 $
+ *              $Revision: 65 $
  *
  *****************************************************************************/
 
@@ -84,7 +84,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 		"Obj=%p [%s] State=%p Num=%X Cur=%X\n",
-		object, object ? acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type) : "NULL",
+		object, object ? acpi_ut_get_object_type_name ((acpi_operand_object *) object) : "NULL",
 		walk_state, state->results.num_results, walk_state->current_result));
 
 	return (AE_OK);
@@ -148,7 +148,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 		"Obj=%p [%s] Index=%X State=%p Num=%X\n",
-		*object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL",
+		*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
 		index, walk_state, state->results.num_results));
 
 	return (AE_OK);
@@ -204,7 +204,7 @@
 			state->results.obj_desc [index -1] = NULL;
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
-				*object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL",
+				*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
 				index -1, walk_state, state->results.num_results));
 
 			return (AE_OK);
@@ -274,7 +274,7 @@
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n",
-		*object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL",
+		*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
 		state, walk_state));
 
 
@@ -329,7 +329,7 @@
 	state->results.num_results++;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
-		object, object ? acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type) : "NULL",
+		object, object ? acpi_ut_get_object_type_name ((acpi_operand_object *) object) : "NULL",
 		walk_state, state->results.num_results, walk_state->current_result));
 
 	return (AE_OK);
@@ -487,7 +487,7 @@
 	walk_state->num_operands++;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
-			  object, acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type),
+			  object, acpi_ut_get_object_type_name ((acpi_operand_object *) object),
 			  walk_state, walk_state->num_operands));
 
 	return (AE_OK);
@@ -547,7 +547,7 @@
 	walk_state->operands [walk_state->num_operands] = NULL;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
-			  *object, acpi_ut_get_type_name ((*object)->common.type),
+			  *object, acpi_ut_get_object_type_name (*object),
 			  walk_state, walk_state->num_operands));
 
 	return (AE_OK);
diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
--- a/drivers/acpi/events/evregion.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/events/evregion.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch
- *              $Revision: 133 $
+ *              $Revision: 134 $
  *
  *****************************************************************************/
 
@@ -624,7 +624,7 @@
 	/*
 	 *  Devices are handled different than regions
 	 */
-	if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
 		/*
 		 *  See if this guy has any handlers
 		 */
diff -Nru a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
--- a/drivers/acpi/events/evrgnini.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/events/evrgnini.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evrgnini- ACPI Address_space (Op_region) init
- *              $Revision: 61 $
+ *              $Revision: 62 $
  *
  *****************************************************************************/
 
@@ -36,8 +36,8 @@
  *
  * FUNCTION:    Acpi_ev_system_memory_region_setup
  *
- * PARAMETERS:  Region_obj          - region we are interested in
- *              Function            - start or stop
+ * PARAMETERS:  Region_obj          - Region we are interested in
+ *              Function            - Start or stop
  *              Handler_context     - Address space handler context
  *              Region_context      - Region specific context
  *
@@ -57,6 +57,7 @@
 	acpi_operand_object     *region_desc = (acpi_operand_object *) handle;
 	acpi_mem_space_context  *local_region_context;
 
+
 	ACPI_FUNCTION_TRACE ("Ev_system_memory_region_setup");
 
 
@@ -68,8 +69,7 @@
 		return_ACPI_STATUS (AE_OK);
 	}
 
-
-	/* Activate.  Create a new context */
+	/* Create a new context */
 
 	local_region_context = ACPI_MEM_CALLOCATE (sizeof (acpi_mem_space_context));
 	if (!(local_region_context)) {
@@ -90,8 +90,8 @@
  *
  * FUNCTION:    Acpi_ev_io_space_region_setup
  *
- * PARAMETERS:  Region_obj          - region we are interested in
- *              Function            - start or stop
+ * PARAMETERS:  Region_obj          - Region we are interested in
+ *              Function            - Start or stop
  *              Handler_context     - Address space handler context
  *              Region_context      - Region specific context
  *
@@ -126,8 +126,8 @@
  *
  * FUNCTION:    Acpi_ev_pci_config_region_setup
  *
- * PARAMETERS:  Region_obj          - region we are interested in
- *              Function            - start or stop
+ * PARAMETERS:  Region_obj          - Region we are interested in
+ *              Function            - Start or stop
  *              Handler_context     - Address space handler context
  *              Region_context      - Region specific context
  *
@@ -161,8 +161,8 @@
 	handler_obj = region_obj->region.addr_handler;
 	if (!handler_obj) {
 		/*
-		 *  No installed handler. This shouldn't happen because the dispatch
-		 *  routine checks before we get here, but we check again just in case.
+		 * No installed handler. This shouldn't happen because the dispatch
+		 * routine checks before we get here, but we check again just in case.
 		 */
 		ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 			"Attempting to init a region %p, with no handler\n", region_obj));
@@ -178,7 +178,6 @@
 		return_ACPI_STATUS (status);
 	}
 
-
 	/* Create a new context */
 
 	pci_id = ACPI_MEM_CALLOCATE (sizeof (acpi_pci_id));
@@ -187,24 +186,23 @@
 	}
 
 	/*
-	 *  For PCI Config space access, we have to pass the segment, bus,
-	 *  device and function numbers.  This routine must acquire those.
+	 * For PCI Config space access, we have to pass the segment, bus,
+	 * device and function numbers.  This routine must acquire those.
 	 */
 
 	/*
-	 *  First get device and function numbers from the _ADR object
-	 *  in the parent's scope.
+	 * First get device and function numbers from the _ADR object
+	 * in the parent's scope.
 	 */
 	node = acpi_ns_get_parent_node (region_obj->region.node);
 
-
-	/* Acpi_evaluate the _ADR object */
+	/* Evaluate the _ADR object */
 
 	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp);
 
 	/*
-	 *  The default is zero, and since the allocation above zeroed
-	 *  the data, just do nothing on failure.
+	 * The default is zero, and since the allocation above zeroed
+	 * the data, just do nothing on failure.
 	 */
 	if (ACPI_SUCCESS (status)) {
 		pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (temp));
@@ -212,17 +210,17 @@
 	}
 
 	/*
-	 *  Get the _SEG and _BBN values from the device upon which the handler
-	 *  is installed.
+	 * Get the _SEG and _BBN values from the device upon which the handler
+	 * is installed.
 	 *
-	 *  We need to get the _SEG and _BBN objects relative to the PCI BUS device.
-	 *  This is the device the handler has been registered to handle.
+	 * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
+	 * This is the device the handler has been registered to handle.
 	 */
 
 	/*
-	 *  If the Addr_handler.Node is still pointing to the root, we need
-	 *  to scan upward for a PCI Root bridge and re-associate the Op_region
-	 *  handlers with that device.
+	 * If the Addr_handler.Node is still pointing to the root, we need
+	 * to scan upward for a PCI Root bridge and re-associate the Op_region
+	 * handlers with that device.
 	 */
 	if (handler_obj->addr_handler.node == acpi_gbl_root_node) {
 		/*
@@ -231,13 +229,17 @@
 		while (node != acpi_gbl_root_node) {
 			status = acpi_ut_execute_HID (node, &object_hID);
 			if (ACPI_SUCCESS (status)) {
+				/* Got a valid _HID, check if this is a PCI root */
+
 				if (!(ACPI_STRNCMP (object_hID.buffer, PCI_ROOT_HID_STRING,
 						   sizeof (PCI_ROOT_HID_STRING)))) {
+					/* Install a handler for this PCI root bridge */
+
 					status = acpi_install_address_space_handler ((acpi_handle) node,
 							   ACPI_ADR_SPACE_PCI_CONFIG,
 							   ACPI_DEFAULT_HANDLER, NULL, NULL);
 					if (ACPI_FAILURE (status)) {
-						ACPI_REPORT_ERROR (("Could not install handler for %4.4s, %s\n",
+						ACPI_REPORT_ERROR (("Could not install Pci_config handler for %4.4s, %s\n",
 							node->name.ascii, acpi_format_exception (status)));
 					}
 					break;
@@ -276,8 +278,8 @@
  *
  * FUNCTION:    Acpi_ev_pci_bar_region_setup
  *
- * PARAMETERS:  Region_obj          - region we are interested in
- *              Function            - start or stop
+ * PARAMETERS:  Region_obj          - Region we are interested in
+ *              Function            - Start or stop
  *              Handler_context     - Address space handler context
  *              Region_context      - Region specific context
  *
@@ -296,7 +298,6 @@
 	void                    *handler_context,
 	void                    **region_context)
 {
-
 	ACPI_FUNCTION_TRACE ("Ev_pci_bar_region_setup");
 
 
@@ -308,8 +309,8 @@
  *
  * FUNCTION:    Acpi_ev_cmos_region_setup
  *
- * PARAMETERS:  Region_obj          - region we are interested in
- *              Function            - start or stop
+ * PARAMETERS:  Region_obj          - Region we are interested in
+ *              Function            - Start or stop
  *              Handler_context     - Address space handler context
  *              Region_context      - Region specific context
  *
@@ -328,7 +329,6 @@
 	void                    *handler_context,
 	void                    **region_context)
 {
-
 	ACPI_FUNCTION_TRACE ("Ev_cmos_region_setup");
 
 
@@ -340,8 +340,8 @@
  *
  * FUNCTION:    Acpi_ev_default_region_setup
  *
- * PARAMETERS:  Region_obj          - region we are interested in
- *              Function            - start or stop
+ * PARAMETERS:  Region_obj          - Region we are interested in
+ *              Function            - Start or stop
  *              Handler_context     - Address space handler context
  *              Region_context      - Region specific context
  *
@@ -376,7 +376,8 @@
  *
  * FUNCTION:    Acpi_ev_initialize_region
  *
- * PARAMETERS:  Region_obj - Region we are initializing
+ * PARAMETERS:  Region_obj      - Region we are initializing
+ *              Acpi_ns_locked  - Is namespace locked?
  *
  * RETURN:      Status
  *
@@ -423,9 +424,8 @@
 	if (!region_obj2) {
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
-	node = acpi_ns_get_parent_node (region_obj->region.node);
-
 
+	node = acpi_ns_get_parent_node (region_obj->region.node);
 	space_id = region_obj->region.space_id;
 
 	region_obj->region.addr_handler = NULL;
@@ -434,26 +434,26 @@
 	region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
 
 	/*
-	 *  Find any "_REG" associated with this region definition
+	 * Find any "_REG" method associated with this region definition
 	 */
 	status = acpi_ns_search_node (*reg_name_ptr, node,
 			  ACPI_TYPE_METHOD, &method_node);
 	if (ACPI_SUCCESS (status)) {
 		/*
-		 *  The _REG method is optional and there can be only one per region
-		 *  definition.  This will be executed when the handler is attached
-		 *  or removed
+		 * The _REG method is optional and there can be only one per region
+		 * definition.  This will be executed when the handler is attached
+		 * or removed
 		 */
 		region_obj2->extra.method_REG = method_node;
 	}
 
 	/*
-	 *  The following loop depends upon the root Node having no parent
-	 *  ie: Acpi_gbl_Root_node->Parent_entry being set to NULL
+	 * The following loop depends upon the root Node having no parent
+	 * ie: Acpi_gbl_Root_node->Parent_entry being set to NULL
 	 */
 	while (node) {
 		/*
-		 *  Check to see if a handler exists
+		 * Check to see if a handler exists
 		 */
 		handler_obj = NULL;
 		obj_desc = acpi_ns_get_attached_object (node);
@@ -483,39 +483,36 @@
 			}
 
 			while (handler_obj) {
-				/*
-				 *  This guy has at least one address handler
-				 *  see if it has the type we want
-				 */
+				/* Is this handler of the correct type? */
+
 				if (handler_obj->addr_handler.space_id == space_id) {
+					/* Found correct handler */
+
 					ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 						"Found handler %p for region %p in obj %p\n",
 						handler_obj, region_obj, obj_desc));
 
-					/*
-					 *  Found it! Now update the region and the handler
-					 */
 					status = acpi_ev_attach_region (handler_obj, region_obj,
 							 acpi_ns_locked);
 
 					return_ACPI_STATUS (AE_OK);
 				}
 
-				handler_obj = handler_obj->addr_handler.next;
+				/* Try next handler in the list */
 
-			} /* while handlerobj */
+				handler_obj = handler_obj->addr_handler.next;
+			}
 		}
 
 		/*
-		 *  This one does not have the handler we need
-		 *  Pop up one level
+		 * This node does not have the handler we need;
+		 * Pop up one level
 		 */
 		node = acpi_ns_get_parent_node (node);
-
-	} /* while Node != ROOT */
+	}
 
 	/*
-	 *  If we get here, there is no handler for this region
+	 * If we get here, there is no handler for this region
 	 */
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"No handler for Region_type %s(%X) (Region_obj %p)\n",
diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
--- a/drivers/acpi/events/evxface.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/events/evxface.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evxface - External interfaces for ACPI events
- *              $Revision: 128 $
+ *              $Revision: 129 $
  *
  *****************************************************************************/
 
@@ -78,7 +78,6 @@
 		status = AE_ALREADY_EXISTS;
 		goto cleanup;
 	}
-
 
 	/* Install the handler before enabling the event */
 
diff -Nru a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
--- a/drivers/acpi/executer/exconfig.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/executer/exconfig.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
- *              $Revision: 65 $
+ *              $Revision: 66 $
  *
  *****************************************************************************/
 
@@ -274,7 +274,7 @@
 	case ACPI_TYPE_REGION:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n",
-			obj_desc, acpi_ut_get_type_name (obj_desc->common.type)));
+			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
 
 		/* Get the table header */
 
@@ -319,7 +319,7 @@
 	case INTERNAL_TYPE_INDEX_FIELD:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Field %p %s\n",
-			obj_desc, acpi_ut_get_type_name (obj_desc->common.type)));
+			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
 
 		/*
 		 * The length of the field must be at least as large as the table.
@@ -415,8 +415,7 @@
 	 */
 	if ((!ddb_handle) ||
 		(ACPI_GET_DESCRIPTOR_TYPE (ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
-		(((acpi_operand_object  *)ddb_handle)->common.type !=
-				INTERNAL_TYPE_REFERENCE)) {
+		(ACPI_GET_OBJECT_TYPE (ddb_handle) != INTERNAL_TYPE_REFERENCE)) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
diff -Nru a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
--- a/drivers/acpi/executer/exconvrt.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exconvrt.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exconvrt - Object conversion routines
- *              $Revision: 35 $
+ *              $Revision: 37 $
  *
  *****************************************************************************/
 
@@ -64,7 +64,7 @@
 	ACPI_FUNCTION_TRACE_PTR ("Ex_convert_to_integer", obj_desc);
 
 
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_INTEGER:
 		*result_desc = obj_desc;
 		return_ACPI_STATUS (AE_OK);
@@ -103,7 +103,7 @@
 	/*
 	 * String conversion is different than Buffer conversion
 	 */
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_STRING:
 
 		/*
@@ -190,11 +190,11 @@
 	ACPI_FUNCTION_TRACE_PTR ("Ex_convert_to_buffer", obj_desc);
 
 
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_INTEGER:
 
 		/*
-		 * Create a new Buffer
+		 * Create a new Buffer object
 		 */
 		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
 		if (!ret_desc) {
@@ -203,7 +203,6 @@
 
 		/* Need enough space for one integer */
 
-		ret_desc->buffer.length = acpi_gbl_integer_byte_width;
 		new_buf = ACPI_MEM_CALLOCATE (acpi_gbl_integer_byte_width);
 		if (!new_buf) {
 			ACPI_REPORT_ERROR
@@ -217,7 +216,12 @@
 		for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
 			new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8));
 		}
+
+		/* Complete buffer object initialization */
+
+		ret_desc->buffer.flags |= AOPOBJ_DATA_VALID;
 		ret_desc->buffer.pointer = new_buf;
+		ret_desc->buffer.length = acpi_gbl_integer_byte_width;
 
 		/* Return the new buffer descriptor */
 
@@ -373,7 +377,7 @@
 	ACPI_FUNCTION_TRACE_PTR ("Ex_convert_to_string", obj_desc);
 
 
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_INTEGER:
 
 		string_length = acpi_gbl_integer_byte_width * 2;
@@ -565,10 +569,10 @@
 		default:
 			/* No conversion allowed for these types */
 
-			if (destination_type != source_desc->common.type) {
+			if (destination_type != ACPI_GET_OBJECT_TYPE (source_desc)) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 					"Target does not allow conversion of type %s to %s\n",
-					acpi_ut_get_type_name ((source_desc)->common.type),
+					acpi_ut_get_object_type_name (source_desc),
 					acpi_ut_get_type_name (destination_type)));
 				status = AE_TYPE;
 			}
diff -Nru a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
--- a/drivers/acpi/executer/excreate.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/executer/excreate.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: excreate - Named object creation
- *              $Revision: 91 $
+ *              $Revision: 92 $
  *
  *****************************************************************************/
 
@@ -40,8 +40,7 @@
  *
  * FUNCTION:    Acpi_ex_create_alias
  *
- * PARAMETERS:  Walk_state           - Current state, contains List of
- *                                      operands for the opcode
+ * PARAMETERS:  Walk_state           - Current state, contains operands
  *
  * RETURN:      Status
  *
@@ -392,9 +391,7 @@
  *
  * FUNCTION:    Acpi_ex_create_processor
  *
- * PARAMETERS:  Op              - Op containing the Processor definition and
- *                                args
- *              Processor_node  - Parent Node for the processor object
+ * PARAMETERS:  Walk_state          - Current state
  *
  * RETURN:      Status
  *
@@ -447,9 +444,7 @@
  *
  * FUNCTION:    Acpi_ex_create_power_resource
  *
- * PARAMETERS:  Op              - Op containing the Power_resource definition
- *                                and args
- *              Power_node      - Parent Node for the power object
+ * PARAMETERS:  Walk_state          - Current state
  *
  * RETURN:      Status
  *
@@ -502,8 +497,7 @@
  *
  * PARAMETERS:  Aml_start       - First byte of the method's AML
  *              Aml_length      - AML byte count for this method
- *              Method_flags    - AML method flag byte
- *              Method          - Method Node
+ *              Walk_state      - Current state
  *
  * RETURN:      Status
  *
diff -Nru a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
--- a/drivers/acpi/executer/exdump.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exdump.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exdump - Interpreter debug output routines
- *              $Revision: 153 $
+ *              $Revision: 155 $
  *
  *****************************************************************************/
 
@@ -96,34 +96,10 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
 
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case INTERNAL_TYPE_REFERENCE:
 
 		switch (obj_desc->reference.opcode) {
-		case AML_ZERO_OP:
-
-			acpi_os_printf ("Reference: Zero\n");
-			break;
-
-
-		case AML_ONE_OP:
-
-			acpi_os_printf ("Reference: One\n");
-			break;
-
-
-		case AML_ONES_OP:
-
-			acpi_os_printf ("Reference: Ones\n");
-			break;
-
-
-		case AML_REVISION_OP:
-
-			acpi_os_printf ("Reference: Revision\n");
-			break;
-
-
 		case AML_DEBUG_OP:
 
 			acpi_os_printf ("Reference: Debug\n");
@@ -150,7 +126,7 @@
 			acpi_os_printf ("Reference: Arg%d",
 					 obj_desc->reference.offset);
 
-			if (ACPI_TYPE_INTEGER == obj_desc->common.type) {
+			if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 				/* Value is a Number */
 
 				acpi_os_printf (" value is [%8.8X%8.8x]",
@@ -167,7 +143,7 @@
 			acpi_os_printf ("Reference: Local%d",
 					 obj_desc->reference.offset);
 
-			if (ACPI_TYPE_INTEGER == obj_desc->common.type) {
+			if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 
 				/* Value is a Number */
 
@@ -189,7 +165,7 @@
 
 			/*  unknown opcode  */
 
-			acpi_os_printf ("Unknown opcode=%X\n",
+			acpi_os_printf ("Unknown Reference opcode=%X\n",
 				obj_desc->reference.opcode);
 			break;
 
@@ -340,8 +316,7 @@
 		{
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL* \n"));
 		}
-		else if (ACPI_TYPE_BUFFER !=
-				  obj_desc->buffer_field.buffer_obj->common.type)
+		else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER)
 		{
 			acpi_os_printf ("*not a Buffer* \n");
 		}
@@ -399,9 +374,9 @@
 
 
 	default:
-		/* Unknown Obj_desc->Common.Type value */
+		/* Unknown Type */
 
-		acpi_os_printf ("Unknown Type %X\n", obj_desc->common.type);
+		acpi_os_printf ("Unknown Type %X\n", ACPI_GET_OBJECT_TYPE (obj_desc));
 		break;
 	}
 
@@ -603,13 +578,13 @@
 
 	/* Common Fields */
 
-	acpi_ex_out_string ("Type",          acpi_ut_get_type_name (obj_desc->common.type));
+	acpi_ex_out_string ("Type",          acpi_ut_get_object_type_name (obj_desc));
 	acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count);
 	acpi_ex_out_integer ("Flags",        obj_desc->common.flags);
 
 	/* Object-specific Fields */
 
-	switch (obj_desc->common.type)
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc))
 	{
 	case ACPI_TYPE_INTEGER:
 
@@ -649,7 +624,7 @@
 				acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]);
 				if (obj_desc->package.elements[i])
 				{
-					acpi_os_printf (" %s", acpi_ut_get_type_name ((obj_desc->package.elements[i])->common.type));
+					acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc->package.elements[i]));
 				}
 				acpi_os_printf ("\n");
 			}
@@ -745,7 +720,7 @@
 		acpi_ex_out_integer ("End_buf_valid_bits", obj_desc->common_field.end_buffer_valid_bits);
 		acpi_ex_out_pointer ("Parent_node",  obj_desc->common_field.node);
 
-		switch (obj_desc->common.type)
+		switch (ACPI_GET_OBJECT_TYPE (obj_desc))
 		{
 		case ACPI_TYPE_BUFFER_FIELD:
 			acpi_ex_out_pointer ("Buffer_obj",   obj_desc->buffer_field.buffer_obj);
@@ -813,15 +788,10 @@
 	case INTERNAL_TYPE_DEF_ANY:
 	case INTERNAL_TYPE_EXTRA:
 	case INTERNAL_TYPE_DATA:
-
-		acpi_os_printf ("Ex_dump_object_descriptor: Display not implemented for object type %X\n",
-			obj_desc->common.type);
-		break;
-
-
 	default:
 
-		acpi_os_printf ("Ex_dump_object_descriptor: Unknown object type %X\n", obj_desc->common.type);
+		acpi_os_printf ("Ex_dump_object_descriptor: Display not implemented for object type %s\n",
+			acpi_ut_get_object_type_name (obj_desc));
 		break;
 	}
 
diff -Nru a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
--- a/drivers/acpi/executer/exfield.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exfield.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
- *              $Revision: 110 $
+ *              $Revision: 112 $
  *
  *****************************************************************************/
 
@@ -70,7 +70,7 @@
 		return_ACPI_STATUS (AE_AML_NO_OPERAND);
 	}
 
-	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the Buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -110,6 +110,8 @@
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
 
+		/* Complete the buffer object initialization */
+
 		buffer_desc->common.flags = AOPOBJ_DATA_VALID;
 		buffer_desc->buffer.length = length;
 		buffer = buffer_desc->buffer.pointer;
@@ -129,7 +131,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"Obj=%p Type=%X Buf=%p Len=%X\n",
-		obj_desc, obj_desc->common.type, buffer, length));
+		obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, length));
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"Field_write: Bit_len=%X Bit_off=%X Byte_off=%X\n",
 		obj_desc->common_field.bit_length,
@@ -193,7 +195,7 @@
 		return_ACPI_STATUS (AE_AML_NO_OPERAND);
 	}
 
-	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the Buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -209,7 +211,7 @@
 	/*
 	 * Get a pointer to the data to be written
 	 */
-	switch (source_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
 	case ACPI_TYPE_INTEGER:
 		buffer = &source_desc->integer.value;
 		length = sizeof (source_desc->integer.value);
@@ -258,7 +260,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"Obj=%p Type=%X Buf=%p Len=%X\n",
-		obj_desc, obj_desc->common.type, buffer, length));
+		obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, length));
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"Field_read: Bit_len=%X Bit_off=%X Byte_off=%X\n",
 		obj_desc->common_field.bit_length,
diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
--- a/drivers/acpi/executer/exfldio.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/executer/exfldio.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exfldio - Aml Field I/O
- *              $Revision: 86 $
+ *              $Revision: 87 $
  *
  *****************************************************************************/
 
@@ -64,9 +64,11 @@
 
 	rgn_desc = obj_desc->common_field.region_obj;
 
-	if (ACPI_TYPE_REGION != rgn_desc->common.type) {
+	if (ACPI_GET_OBJECT_TYPE (rgn_desc) != ACPI_TYPE_REGION) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X (%s)\n",
-			rgn_desc->common.type, acpi_ut_get_type_name (rgn_desc->common.type)));
+			ACPI_GET_OBJECT_TYPE (rgn_desc),
+			acpi_ut_get_object_type_name (rgn_desc)));
+
 		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 	}
 
@@ -298,7 +300,7 @@
 	 * Bank_fields  - Write to a Bank Register, then read/write from/to an Op_region
 	 * Index_fields - Write to an Index Register, then read/write from/to a Data Register
 	 */
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_BUFFER_FIELD:
 		/*
 		 * If the Buffer_field arguments have not been previously evaluated,
@@ -416,7 +418,7 @@
 	default:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p, Wrong object type - %s\n",
-			obj_desc, acpi_ut_get_type_name (obj_desc->common.type)));
+			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
 		status = AE_AML_INTERNAL;
 		break;
 	}
diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
--- a/drivers/acpi/executer/exmisc.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/executer/exmisc.c	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
- *              $Revision: 104 $
+ *              $Revision: 106 $
  *
  *****************************************************************************/
 
@@ -64,7 +64,7 @@
 	switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
 	case ACPI_DESC_TYPE_OPERAND:
 
-		if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) {
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) != INTERNAL_TYPE_REFERENCE) {
 			*return_desc = NULL;
 			status = AE_TYPE;
 			goto cleanup;
@@ -184,9 +184,9 @@
 	ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, length1);
 	ACPI_MEMCPY (new_buf + length1, obj_desc2->buffer.pointer, length2);
 
-	/*
-	 * Point the return object to the new buffer
-	 */
+	/* Complete the buffer object initialization */
+
+	return_desc->common.flags  = AOPOBJ_DATA_VALID;
 	return_desc->buffer.pointer = (u8 *) new_buf;
 	return_desc->buffer.length = (u32) (length1 + length2);
 
@@ -243,21 +243,22 @@
 
 	/*
 	 * There are three cases to handle:
-	 * 1) Two Integers concatenated to produce a buffer
-	 * 2) Two Strings concatenated to produce a string
-	 * 3) Two Buffers concatenated to produce a buffer
+	 *
+	 * 1) Two Integers concatenated to produce a new Buffer
+	 * 2) Two Strings concatenated to produce a new String
+	 * 3) Two Buffers concatenated to produce a new Buffer
 	 */
-	switch (obj_desc1->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) {
 	case ACPI_TYPE_INTEGER:
 
-		/* Result of two integers is a buffer */
+		/* Result of two Integers is a Buffer */
 
 		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
 		if (!return_desc) {
 			return (AE_NO_MEMORY);
 		}
 
-		/* Need enough space for two integers */
+		/* Need enough buffer space for two integers */
 
 		return_desc->buffer.length = acpi_gbl_integer_byte_width * 2;
 		new_buf = ACPI_MEM_CALLOCATE (return_desc->buffer.length);
@@ -268,8 +269,6 @@
 			goto cleanup;
 		}
 
-		return_desc->buffer.pointer = (u8 *) new_buf;
-
 		/* Convert the first integer */
 
 		this_integer = obj_desc1->integer.value;
@@ -286,11 +285,17 @@
 			this_integer >>= 8;
 		}
 
+		/* Complete the buffer object initialization */
+
+		return_desc->common.flags  = AOPOBJ_DATA_VALID;
+		return_desc->buffer.pointer = (u8 *) new_buf;
 		break;
 
 
 	case ACPI_TYPE_STRING:
 
+		/* Result of two Strings is a String */
+
 		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
 		if (!return_desc) {
 			return (AE_NO_MEMORY);
@@ -307,11 +312,13 @@
 			goto cleanup;
 		}
 
+		/* Concatenate the strings */
+
 		ACPI_STRCPY (new_buf, obj_desc1->string.pointer);
 		ACPI_STRCPY (new_buf + obj_desc1->string.length,
 				  obj_desc2->string.pointer);
 
-		/* Point the return object to the new string */
+		/* Complete the String object initialization */
 
 		return_desc->string.pointer = new_buf;
 		return_desc->string.length = obj_desc1->string.length +
@@ -321,7 +328,7 @@
 
 	case ACPI_TYPE_BUFFER:
 
-		/* Operand0 is a buffer */
+		/* Result of two Buffers is a Buffer */
 
 		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
 		if (!return_desc) {
@@ -337,22 +344,26 @@
 			goto cleanup;
 		}
 
+		/* Concatenate the buffers */
+
 		ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer,
 				  obj_desc1->buffer.length);
 		ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer,
 				   obj_desc2->buffer.length);
 
-		/*
-		 * Point the return object to the new buffer
-		 */
+		/* Complete the buffer object initialization */
 
+		return_desc->common.flags  = AOPOBJ_DATA_VALID;
 		return_desc->buffer.pointer = (u8 *) new_buf;
 		return_desc->buffer.length = obj_desc1->buffer.length +
-				  obj_desc2->buffer.length;
+				   obj_desc2->buffer.length;
 		break;
 
 
 	default:
+
+		/* Invalid object type, should not happen here */
+
 		status = AE_AML_INTERNAL;
 		return_desc = NULL;
 	}
diff -Nru a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
--- a/drivers/acpi/executer/exoparg1.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/executer/exoparg1.c	Sun Jun 16 19:31:41 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
- *              $Revision: 137 $
+ *              $Revision: 139 $
  *
  *****************************************************************************/
 
@@ -560,23 +560,12 @@
 
 	case AML_TYPE_OP:               /* Object_type (Source_object) */
 
-		if (INTERNAL_TYPE_REFERENCE == operand[0]->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (operand[0]) == INTERNAL_TYPE_REFERENCE) {
 			/*
 			 * Not a Name -- an indirect name pointer would have
 			 * been converted to a direct name pointer in Resolve_operands
 			 */
 			switch (operand[0]->reference.opcode) {
-			case AML_ZERO_OP:
-			case AML_ONE_OP:
-			case AML_ONES_OP:
-			case AML_REVISION_OP:
-
-				/* Constants are of type Integer */
-
-				type = ACPI_TYPE_INTEGER;
-				break;
-
-
 			case AML_DEBUG_OP:
 
 				/* The Debug Object is of type "Debug_object" */
@@ -596,7 +585,7 @@
 					 * of the individual package element that is referenced by
 					 * the index.
 					 */
-					type = (*(operand[0]->reference.where))->common.type;
+					type = ACPI_GET_OBJECT_TYPE (*(operand[0]->reference.where));
 				}
 				break;
 
@@ -611,7 +600,7 @@
 
 			default:
 
-				ACPI_REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R/Type_op: Internal error - Unknown Reference subtype %X\n",
+				ACPI_REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R/Type_op: Unknown Reference subtype %X\n",
 					operand[0]->reference.opcode));
 				status = AE_AML_INTERNAL;
 				goto cleanup;
@@ -668,7 +657,7 @@
 			 * point (even if the original operand was an object reference, it
 			 * will be resolved and typechecked during operand resolution.)
 			 */
-			switch (temp_desc->common.type) {
+			switch (ACPI_GET_OBJECT_TYPE (temp_desc)) {
 			case ACPI_TYPE_BUFFER:
 				value = temp_desc->buffer.length;
 				break;
@@ -683,7 +672,7 @@
 
 			default:
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Size_of, Not Buf/Str/Pkg - found type %s\n",
-					acpi_ut_get_type_name (temp_desc->common.type)));
+					acpi_ut_get_object_type_name (temp_desc)));
 				status = AE_AML_OPERAND_TYPE;
 				goto cleanup;
 			}
diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
--- a/drivers/acpi/executer/exoparg2.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/executer/exoparg2.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exoparg2 - AML execution - opcodes with 2 arguments
- *              $Revision: 106 $
+ *              $Revision: 108 $
  *
  *****************************************************************************/
 
@@ -297,7 +297,7 @@
 		 * guaranteed to be either Integer/String/Buffer by the operand
 		 * resolution mechanism above.
 		 */
-		switch (operand[0]->common.type) {
+		switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
 		case ACPI_TYPE_INTEGER:
 			status = acpi_ex_convert_to_integer (operand[1], &operand[1], walk_state);
 			break;
@@ -355,7 +355,7 @@
 		/*
 		 * At this point, the Source operand is either a Package or a Buffer
 		 */
-		if (operand[0]->common.type == ACPI_TYPE_PACKAGE) {
+		if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) {
 			/* Object to be indexed is a Package */
 
 			if (index >= operand[0]->package.count) {
@@ -364,10 +364,10 @@
 				goto cleanup;
 			}
 
-			if ((operand[2]->common.type == INTERNAL_TYPE_REFERENCE) &&
-				(operand[2]->reference.opcode == AML_ZERO_OP)) {
+			if ((ACPI_GET_OBJECT_TYPE (operand[2]) == ACPI_TYPE_INTEGER) &&
+				(operand[2]->common.flags & AOPOBJ_AML_CONSTANT)) {
 				/*
-				 * There is no actual result descriptor (the Zero_op Result
+				 * There is no actual result descriptor (the Zero_op/Constant Result
 				 * descriptor is a placeholder), so just delete the placeholder and
 				 * return a reference to the package element
 				 */
@@ -381,7 +381,7 @@
 				 */
 				temp_desc                        = operand[0]->package.elements [index];
 				return_desc->reference.opcode    = AML_INDEX_OP;
-				return_desc->reference.target_type = temp_desc->common.type;
+				return_desc->reference.target_type = ACPI_GET_OBJECT_TYPE (temp_desc);
 				return_desc->reference.object    = temp_desc;
 
 				status = acpi_ex_store (return_desc, operand[2], walk_state);
diff -Nru a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
--- a/drivers/acpi/executer/exoparg3.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exoparg3.c	Sun Jun 16 19:31:39 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exoparg3 - AML execution - opcodes with 3 arguments
- *              $Revision: 13 $
+ *              $Revision: 14 $
  *
  *****************************************************************************/
 
@@ -159,7 +159,7 @@
 		 * Create the return object.  The Source operand is guaranteed to be
 		 * either a String or a Buffer, so just use its type.
 		 */
-		return_desc = acpi_ut_create_internal_object (operand[0]->common.type);
+		return_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (operand[0]));
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
diff -Nru a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
--- a/drivers/acpi/executer/exoparg6.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exoparg6.c	Sun Jun 16 19:31:39 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exoparg6 - AML execution - opcodes with 6 arguments
- *              $Revision: 10 $
+ *              $Revision: 11 $
  *
  *****************************************************************************/
 
@@ -212,7 +212,7 @@
 			 * Treat any NULL or non-numeric elements as non-matching.
 			 */
 			if (!this_element ||
-				this_element->common.type != ACPI_TYPE_INTEGER) {
+				ACPI_GET_OBJECT_TYPE (this_element) != ACPI_TYPE_INTEGER) {
 				continue;
 			}
 
diff -Nru a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
--- a/drivers/acpi/executer/exprep.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exprep.c	Sun Jun 16 19:31:39 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
- *              $Revision: 117 $
+ *              $Revision: 118 $
  *
  *****************************************************************************/
 
@@ -140,7 +140,7 @@
 		return (0);
 	}
 
-	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * Buffer_field access can be on any byte boundary, so the
 		 * Byte_alignment is always 1 byte -- regardless of any Byte_alignment
diff -Nru a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
--- a/drivers/acpi/executer/exresnte.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exresnte.c	Sun Jun 16 19:31:39 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exresnte - AML Interpreter object resolution
- *              $Revision: 53 $
+ *              $Revision: 56 $
  *
  *****************************************************************************/
 
@@ -73,7 +73,6 @@
 	acpi_operand_object     *obj_desc = NULL;
 	acpi_namespace_node     *node;
 	acpi_object_type        entry_type;
-	acpi_integer            temp_val;
 
 
 	ACPI_FUNCTION_TRACE ("Ex_resolve_node_to_value");
@@ -113,9 +112,9 @@
 	switch (entry_type) {
 	case ACPI_TYPE_PACKAGE:
 
-		if (ACPI_TYPE_PACKAGE != source_desc->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_PACKAGE) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Package, type %s\n",
-				acpi_ut_get_type_name (source_desc->common.type)));
+				acpi_ut_get_object_type_name (source_desc)));
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
@@ -131,9 +130,9 @@
 
 	case ACPI_TYPE_BUFFER:
 
-		if (ACPI_TYPE_BUFFER != source_desc->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Buffer, type %s\n",
-				acpi_ut_get_type_name (source_desc->common.type)));
+				acpi_ut_get_object_type_name (source_desc)));
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
@@ -149,9 +148,9 @@
 
 	case ACPI_TYPE_STRING:
 
-		if (ACPI_TYPE_STRING != source_desc->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a String, type %s\n",
-				acpi_ut_get_type_name (source_desc->common.type)));
+				acpi_ut_get_object_type_name (source_desc)));
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
@@ -164,9 +163,9 @@
 
 	case ACPI_TYPE_INTEGER:
 
-		if (ACPI_TYPE_INTEGER != source_desc->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Integer, type %s\n",
-				acpi_ut_get_type_name (source_desc->common.type)));
+				acpi_ut_get_object_type_name (source_desc)));
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
@@ -216,61 +215,14 @@
 		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);  /* Cannot be AE_TYPE */
 
 
-	/*
-	 * The only named references allowed are named constants
-	 *   e.g. -- Name (\OSFL, Ones)
-	 */
 	case INTERNAL_TYPE_REFERENCE:
 
-		switch (source_desc->reference.opcode) {
-
-		case AML_ZERO_OP:
-
-			temp_val = 0;
-			break;
-
-		case AML_ONE_OP:
-
-			temp_val = 1;
-			break;
-
-		case AML_ONES_OP:
-
-			temp_val = ACPI_INTEGER_MAX;
-			break;
-
-		case AML_REVISION_OP:
-
-			temp_val = ACPI_CA_SUPPORT_LEVEL;
-			break;
+		/* No named references are allowed here */
 
-		default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n",
+			source_desc->reference.opcode));
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n",
-				source_desc->reference.opcode));
-
-			return_ACPI_STATUS (AE_AML_BAD_OPCODE);
-		}
-
-		/* Create object for result */
-
-		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!obj_desc) {
-			return_ACPI_STATUS (AE_NO_MEMORY);
-		}
-
-		obj_desc->integer.value = temp_val;
-
-		/*
-		 * Truncate value if we are executing from a 32-bit ACPI table
-		 * AND actually executing AML code.  If we are resolving
-		 * an object in the namespace via an external call to the
-		 * subsystem, we will have a null Walk_state
-		 */
-		if (walk_state) {
-			acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
-		}
-		break;
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 
 
 	/* Default case is for unknown types */
diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
--- a/drivers/acpi/executer/exresolv.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/executer/exresolv.c	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exresolv - AML Interpreter object resolution
- *              $Revision: 111 $
+ *              $Revision: 114 $
  *
  *****************************************************************************/
 
@@ -130,7 +130,7 @@
 
 	/* This is an acpi_operand_object  */
 
-	switch (stack_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (stack_desc)) {
 	case INTERNAL_TYPE_REFERENCE:
 
 		opcode = stack_desc->reference.opcode;
@@ -178,56 +178,6 @@
 				stack_desc->reference.offset, obj_desc));
 			break;
 
-		/*
-		 * For constants, we must change the reference/constant object
-		 * to a real integer object
-		 */
-		case AML_ZERO_OP:
-		case AML_ONE_OP:
-		case AML_ONES_OP:
-		case AML_REVISION_OP:
-
-			/* Create a new integer object */
-
-			obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
-			if (!obj_desc) {
-				return_ACPI_STATUS (AE_NO_MEMORY);
-			}
-
-			switch (opcode) {
-			case AML_ZERO_OP:
-				obj_desc->integer.value = 0;
-				break;
-
-			case AML_ONE_OP:
-				obj_desc->integer.value = 1;
-				break;
-
-			case AML_ONES_OP:
-				obj_desc->integer.value = ACPI_INTEGER_MAX;
-
-				/* Truncate value if we are executing from a 32-bit ACPI table */
-
-				acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
-				break;
-
-			case AML_REVISION_OP:
-				obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL;
-				break;
-
-			default:
-				/* No other opcodes can get here */
-				break;
-			}
-
-			/*
-			 * Remove a reference from the original reference object
-			 * and put the new object in its place
-			 */
-			acpi_ut_remove_reference (stack_desc);
-			*stack_ptr = obj_desc;
-			break;
-
 
 		case AML_INDEX_OP:
 
@@ -239,6 +189,7 @@
 
 
 			case ACPI_TYPE_PACKAGE:
+
 				obj_desc = *stack_desc->reference.where;
 				if (obj_desc) {
 					/*
@@ -262,7 +213,9 @@
 				}
 				break;
 
+
 			default:
+
 				/* Invalid reference object */
 
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -282,14 +235,12 @@
 
 		default:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference object subtype %02X in %p\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X in %p\n",
 				opcode, stack_desc));
 			status = AE_AML_INTERNAL;
 			break;
-
-		}   /* switch (Opcode) */
-
-		break; /* case INTERNAL_TYPE_REFERENCE */
+		}
+		break;
 
 
 	case ACPI_TYPE_BUFFER:
@@ -313,7 +264,7 @@
 	case INTERNAL_TYPE_INDEX_FIELD:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Field_read Source_desc=%p Type=%X\n",
-			stack_desc, stack_desc->common.type));
+			stack_desc, ACPI_GET_OBJECT_TYPE (stack_desc)));
 
 		status = acpi_ex_read_data_from_field (walk_state, stack_desc, &obj_desc);
 		*stack_ptr = (void *) obj_desc;
diff -Nru a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
--- a/drivers/acpi/executer/exresop.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/executer/exresop.c	Sun Jun 16 19:31:41 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exresop - AML Interpreter operand/object resolution
- *              $Revision: 50 $
+ *              $Revision: 53 $
  *
  *****************************************************************************/
 
@@ -65,6 +65,18 @@
 		return (AE_OK);
 	}
 
+	if (type_needed == INTERNAL_TYPE_REFERENCE) {
+		/*
+		 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
+		 * objects and thus allow them to be targets.  (As per the ACPI
+		 * specification, a store to a constant is a noop.)
+		 */
+		if ((this_type == ACPI_TYPE_INTEGER) &&
+			(((acpi_operand_object *) object)->common.flags & AOPOBJ_AML_CONSTANT)) {
+			return (AE_OK);
+		}
+	}
+
 	if (type_needed != this_type) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Needed [%s], found [%s] %p\n",
@@ -85,18 +97,17 @@
  * PARAMETERS:  Opcode              - Opcode being interpreted
  *              Stack_ptr           - Pointer to the operand stack to be
  *                                    resolved
- *              Walk_state          - Current stateu
+ *              Walk_state          - Current state
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Convert multiple input operands to the types required by the
  *              target operator.
  *
- *      Each nibble (actually 5 bits)  in Arg_types represents one required
- *      operand and indicates the required Type:
- *
- *      The corresponding operand will be converted to the required type if
- *      possible, otherwise we abort with an exception.
+ *      Each 5-bit group in Arg_types represents one required
+ *      operand and indicates the required Type. The corresponding operand
+ *      will be converted to the required type if possible, otherwise we
+ *      abort with an exception.
  *
  ******************************************************************************/
 
@@ -169,7 +180,7 @@
 
 			/* ACPI internal object */
 
-			object_type = obj_desc->common.type;
+			object_type = ACPI_GET_OBJECT_TYPE (obj_desc);
 
 			/* Check for bad acpi_object_type */
 
@@ -190,15 +201,11 @@
 				}
 
 				switch (obj_desc->reference.opcode) {
-				case AML_ZERO_OP:
-				case AML_ONE_OP:
-				case AML_ONES_OP:
 				case AML_DEBUG_OP:
 				case AML_NAME_OP:
 				case AML_INDEX_OP:
 				case AML_ARG_OP:
 				case AML_LOCAL_OP:
-				case AML_REVISION_OP:
 
 					ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 						"Reference Opcode: %s\n", op_info->name)));
@@ -206,7 +213,7 @@
 
 				default:
 					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-						"Reference Opcode: Unknown [%02x]\n",
+						"Unknown Reference Opcode %X\n",
 						obj_desc->reference.opcode));
 
 					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
@@ -293,7 +300,7 @@
 			 * -- All others must be resolved below.
 			 */
 			if ((opcode == AML_STORE_OP) &&
-				((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
+				(ACPI_GET_OBJECT_TYPE (*stack_ptr) == INTERNAL_TYPE_REFERENCE) &&
 				((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
 				goto next_operand;
 			}
@@ -378,7 +385,7 @@
 				if (status == AE_TYPE) {
 					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 						"Needed [Integer/String/Buffer], found [%s] %p\n",
-						acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
+						acpi_ut_get_object_type_name (*stack_ptr), *stack_ptr));
 
 					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 				}
@@ -399,7 +406,7 @@
 				if (status == AE_TYPE) {
 					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 						"Needed [Integer/String/Buffer], found [%s] %p\n",
-						acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
+						acpi_ut_get_object_type_name (*stack_ptr), *stack_ptr));
 
 					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 				}
@@ -420,7 +427,7 @@
 				if (status == AE_TYPE) {
 					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 						"Needed [Integer/String/Buffer], found [%s] %p\n",
-						acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
+						acpi_ut_get_object_type_name (*stack_ptr), *stack_ptr));
 
 					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 				}
@@ -434,7 +441,7 @@
 
 			/* Need an operand of type INTEGER, STRING or BUFFER */
 
-			switch ((*stack_ptr)->common.type) {
+			switch (ACPI_GET_OBJECT_TYPE (*stack_ptr)) {
 			case ACPI_TYPE_INTEGER:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -445,7 +452,7 @@
 			default:
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 					"Needed [Integer/String/Buffer], found [%s] %p\n",
-					acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
+					acpi_ut_get_object_type_name (*stack_ptr), *stack_ptr));
 
 				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 			}
@@ -460,7 +467,7 @@
 			 * The only reference allowed here is a direct reference to
 			 * a namespace node.
 			 */
-			if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
+			if (ACPI_GET_OBJECT_TYPE (*stack_ptr) == INTERNAL_TYPE_REFERENCE) {
 				if (!(*stack_ptr)->reference.node) {
 					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 						"Needed [Node Reference], found [%p]\n",
@@ -492,7 +499,7 @@
 
 			/* Need a buffer, string, package */
 
-			switch ((*stack_ptr)->common.type) {
+			switch (ACPI_GET_OBJECT_TYPE (*stack_ptr)) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -503,7 +510,7 @@
 			default:
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 					"Needed [Buf/Str/Pkg], found [%s] %p\n",
-					acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
+					acpi_ut_get_object_type_name (*stack_ptr), *stack_ptr));
 
 				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 			}
@@ -514,7 +521,7 @@
 
 			/* Need a buffer or package or (ACPI 2.0) String */
 
-			switch ((*stack_ptr)->common.type) {
+			switch (ACPI_GET_OBJECT_TYPE (*stack_ptr)) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -525,7 +532,7 @@
 			default:
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 					"Needed [Buf/Str/Pkg], found [%s] %p\n",
-					acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
+					acpi_ut_get_object_type_name (*stack_ptr), *stack_ptr));
 
 				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 			}
@@ -548,7 +555,7 @@
 		 * required object type (Simple cases only).
 		 */
 		status = acpi_ex_check_object_type (type_needed,
-				  (*stack_ptr)->common.type, *stack_ptr);
+				  ACPI_GET_OBJECT_TYPE (*stack_ptr), *stack_ptr);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
diff -Nru a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
--- a/drivers/acpi/executer/exstore.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/executer/exstore.c	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exstore - AML Interpreter object store support
- *              $Revision: 164 $
+ *              $Revision: 167 $
  *
  *****************************************************************************/
 
@@ -89,18 +89,33 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/* Destination object must be an object of type Reference */
+	/* Destination object must be a Reference or a Constant object */
+
+	switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
+	case INTERNAL_TYPE_REFERENCE:
+		break;
+
+	case ACPI_TYPE_INTEGER:
+
+		/* Allow stores to Constants -- a Noop as per ACPI spec */
+
+		if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
+			return_ACPI_STATUS (AE_OK);
+		}
+
+		/*lint: -fallthrough */
+
+	default:
 
-	if (dest_desc->common.type != INTERNAL_TYPE_REFERENCE) {
 		/* Destination is not an Reference */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Destination is not a Reference_obj [%p]\n", dest_desc));
+			"Destination is not a Reference or Constant object [%p]\n", dest_desc));
 
 		ACPI_DUMP_STACK_ENTRY (source_desc);
 		ACPI_DUMP_STACK_ENTRY (dest_desc);
 		ACPI_DUMP_OPERANDS (&dest_desc, ACPI_IMODE_EXECUTE, "Ex_store",
-				  2, "Target is not a Reference_obj");
+				  2, "Target is not a Reference or Constant object");
 
 		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 	}
@@ -112,7 +127,6 @@
 	 * 2) Store to an indexed area of a Buffer or Package
 	 * 3) Store to a Method Local or Arg
 	 * 4) Store to the debug object
-	 * 5) Store to a constant -- a noop
 	 */
 	switch (ref_desc->reference.opcode) {
 	case AML_NAME_OP:
@@ -151,9 +165,9 @@
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Write to Debug Object: ****:\n\n"));
 
 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
-				  acpi_ut_get_type_name (source_desc->common.type)));
+				  acpi_ut_get_object_type_name (source_desc)));
 
-		switch (source_desc->common.type) {
+		switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
 		case ACPI_TYPE_INTEGER:
 
 			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%8.8X%8.8X\n",
@@ -185,7 +199,7 @@
 		default:
 
 			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Type %s %p\n",
-					acpi_ut_get_type_name (source_desc->common.type), source_desc));
+					acpi_ut_get_object_type_name (source_desc), source_desc));
 			break;
 		}
 
@@ -193,28 +207,15 @@
 		break;
 
 
-	case AML_ZERO_OP:
-	case AML_ONE_OP:
-	case AML_ONES_OP:
-	case AML_REVISION_OP:
-
-		/*
-		 * Storing to a constant is a no-op according to the  ACPI
-		 * Specification. (Delete the reference descriptor, however.)
-		 */
-		break;
-
-
 	default:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference subtype %02x\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X\n",
 			ref_desc->reference.opcode));
 		ACPI_DUMP_ENTRY (ref_desc, ACPI_LV_ERROR);
 
 		status = AE_AML_INTERNAL;
 		break;
-
-	}   /* switch (Ref_desc->Reference.Opcode) */
+	}
 
 	return_ACPI_STATUS (status);
 }
@@ -303,7 +304,7 @@
 		 * Make sure the target is a Buffer
 		 */
 		obj_desc = index_desc->reference.object;
-		if (obj_desc->common.type != ACPI_TYPE_BUFFER) {
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) {
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
@@ -311,7 +312,7 @@
 		 * The assignment of the individual elements will be slightly
 		 * different for each source type.
 		 */
-		switch (source_desc->common.type) {
+		switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
 		case ACPI_TYPE_INTEGER:
 
 			/* Use the least-significant byte of the integer */
@@ -335,7 +336,7 @@
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Source must be Integer/Buffer/String type, not %s\n",
-				acpi_ut_get_type_name (source_desc->common.type)));
+				acpi_ut_get_object_type_name (source_desc)));
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
@@ -403,7 +404,7 @@
 	target_desc = acpi_ns_get_attached_object (node);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
-		source_desc, acpi_ut_get_type_name (source_desc->common.type),
+		source_desc, acpi_ut_get_object_type_name (source_desc),
 			  node, acpi_ut_get_type_name (target_type)));
 
 	/*
@@ -456,8 +457,8 @@
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 				"Store %s into %s via Convert/Attach\n",
-				acpi_ut_get_type_name (source_desc->common.type),
-				acpi_ut_get_type_name (new_desc->common.type)));
+				acpi_ut_get_object_type_name (source_desc),
+				acpi_ut_get_object_type_name (new_desc)));
 		}
 		break;
 
@@ -466,11 +467,11 @@
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 			"Storing %s (%p) directly into node (%p), no implicit conversion\n",
-			acpi_ut_get_type_name (source_desc->common.type), source_desc, node));
+			acpi_ut_get_object_type_name (source_desc), source_desc, node));
 
 		/* No conversions for all other types.  Just attach the source object */
 
-		status = acpi_ns_attach_object (node, source_desc, source_desc->common.type);
+		status = acpi_ns_attach_object (node, source_desc, ACPI_GET_OBJECT_TYPE (source_desc));
 		break;
 	}
 
diff -Nru a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
--- a/drivers/acpi/executer/exstoren.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exstoren.c	Sun Jun 16 19:31:39 2002
@@ -3,7 +3,7 @@
  *
  * Module Name: exstoren - AML Interpreter object store support,
  *                        Store to Node (namespace object)
- *              $Revision: 48 $
+ *              $Revision: 50 $
  *
  *****************************************************************************/
 
@@ -84,7 +84,7 @@
 		 * are all essentially the same.  This case handles the
 		 * "interchangeable" types Integer, String, and Buffer.
 		 */
-		if (source_desc->common.type == INTERNAL_TYPE_REFERENCE) {
+		if (ACPI_GET_OBJECT_TYPE (source_desc) == INTERNAL_TYPE_REFERENCE) {
 			/* Resolve a reference object first */
 
 			status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state);
@@ -96,15 +96,15 @@
 		/*
 		 * Must have a Integer, Buffer, or String
 		 */
-		if ((source_desc->common.type != ACPI_TYPE_INTEGER)    &&
-			(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
-			(source_desc->common.type != ACPI_TYPE_STRING)) {
+		if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER)    &&
+			(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER)     &&
+			(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING)) {
 			/*
 			 * Conversion successful but still not a valid type
 			 */
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
-				acpi_ut_get_type_name (source_desc->common.type),
+				acpi_ut_get_object_type_name (source_desc),
 				acpi_ut_get_type_name (target_type)));
 			status = AE_AML_OPERAND_TYPE;
 		}
@@ -195,7 +195,7 @@
 		return_ACPI_STATUS (status);
 	}
 
-	if (source_desc->common.type != dest_desc->common.type) {
+	if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
 		/*
 		 * The source type does not match the type of the destination.
 		 * Perform the "implicit conversion" of the source to the current type
@@ -205,7 +205,7 @@
 		 * Otherwise, Actual_src_desc is a temporary object to hold the
 		 * converted object.
 		 */
-		status = acpi_ex_convert_to_target_type (dest_desc->common.type, source_desc,
+		status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc), source_desc,
 				  &actual_src_desc, walk_state);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
@@ -216,14 +216,14 @@
 	 * We now have two objects of identical types, and we can perform a
 	 * copy of the *value* of the source object.
 	 */
-	switch (dest_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
 	case ACPI_TYPE_INTEGER:
 
 		dest_desc->integer.value = actual_src_desc->integer.value;
 
 		/* Truncate value if we are executing from a 32-bit ACPI table */
 
-		acpi_ex_truncate_for32bit_table (dest_desc, walk_state);
+		acpi_ex_truncate_for32bit_table (dest_desc);
 		break;
 
 	case ACPI_TYPE_STRING:
@@ -246,7 +246,7 @@
 		 * All other types come here.
 		 */
 		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into type %s not implemented\n",
-			acpi_ut_get_type_name (dest_desc->common.type)));
+			acpi_ut_get_object_type_name (dest_desc)));
 
 		status = AE_NOT_IMPLEMENTED;
 		break;
diff -Nru a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
--- a/drivers/acpi/executer/exutils.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/executer/exutils.c	Sun Jun 16 19:31:39 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exutils - interpreter/scanner utilities
- *              $Revision: 98 $
+ *              $Revision: 100 $
  *
  *****************************************************************************/
 
@@ -148,8 +148,6 @@
  * FUNCTION:    Acpi_ex_truncate_for32bit_table
  *
  * PARAMETERS:  Obj_desc        - Object to be truncated
- *              Walk_state      - Current walk state
- *                                (A method must be executing)
  *
  * RETURN:      none
  *
@@ -160,8 +158,7 @@
 
 void
 acpi_ex_truncate_for32bit_table (
-	acpi_operand_object     *obj_desc,
-	acpi_walk_state         *walk_state)
+	acpi_operand_object     *obj_desc)
 {
 
 	ACPI_FUNCTION_ENTRY ();
@@ -172,8 +169,7 @@
 	 * a control method
 	 */
 	if ((!obj_desc) ||
-		(obj_desc->common.type != ACPI_TYPE_INTEGER) ||
-		(!walk_state->method_node)) {
+		(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER)) {
 		return;
 	}
 
diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
--- a/drivers/acpi/hardware/hwregs.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/hardware/hwregs.c	Sun Jun 16 19:31:40 2002
@@ -3,7 +3,7 @@
  *
  * Module Name: hwregs - Read/write access functions for the various ACPI
  *                       control and status registers.
- *              $Revision: 130 $
+ *              $Revision: 133 $
  *
  ******************************************************************************/
 
@@ -129,7 +129,7 @@
 
 
 	/*
-	 *  Validate parameters
+	 * Validate parameters
 	 */
 	if ((sleep_state > ACPI_S_STATES_MAX) ||
 		!sleep_type_a || !sleep_type_b) {
@@ -137,7 +137,7 @@
 	}
 
 	/*
-	 *  Acpi_evaluate the namespace object containing the values for this state
+	 * Evaluate the namespace object containing the values for this state
 	 */
 	status = acpi_ns_evaluate_by_name ((NATIVE_CHAR *) acpi_gbl_db_sleep_states[sleep_state],
 			  NULL, &obj_desc);
@@ -145,46 +145,47 @@
 		return_ACPI_STATUS (status);
 	}
 
+	/* Must have a return object */
+
 	if (!obj_desc) {
 		ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
-		return_ACPI_STATUS (AE_NOT_EXIST);
+		status = AE_NOT_EXIST;
 	}
 
-	/*
-	 *  We got something, now ensure it is correct.  The object must
-	 *  be a package and must have at least 2 numeric values as the
-	 *  two elements
-	 */
+	/* It must be of type Package */
 
-	/* Even though Acpi_evaluate_object resolves package references,
-	 * Ns_evaluate doesn't. So, we do it here.
-	 */
-	status = acpi_ut_resolve_package_references(obj_desc);
+	else if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_PACKAGE) {
+		ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
+		status = AE_AML_OPERAND_TYPE;
+	}
 
-	if (obj_desc->package.count < 2) {
-		/* Must have at least two elements */
+	/* The package must have at least two elements */
 
+	else if (obj_desc->package.count < 2) {
 		ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
 		status = AE_AML_NO_OPERAND;
 	}
-	else if (((obj_desc->package.elements[0])->common.type != ACPI_TYPE_INTEGER) ||
-			 ((obj_desc->package.elements[1])->common.type != ACPI_TYPE_INTEGER)) {
-		/* Must have two  */
 
-		ACPI_REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
+	/* The first two elements must both be of type Integer */
+
+	else if ((ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[0]) != ACPI_TYPE_INTEGER) ||
+			 (ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[1]) != ACPI_TYPE_INTEGER)) {
+		ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
+			acpi_ut_get_object_type_name (obj_desc->package.elements[0]),
+			acpi_ut_get_object_type_name (obj_desc->package.elements[1])));
 		status = AE_AML_OPERAND_TYPE;
 	}
 	else {
 		/*
-		 *  Valid _Sx_ package size, type, and value
+		 * Valid _Sx_ package size, type, and value
 		 */
 		*sleep_type_a = (u8) (obj_desc->package.elements[0])->integer.value;
 		*sleep_type_b = (u8) (obj_desc->package.elements[1])->integer.value;
 	}
 
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %X\n",
-			obj_desc, obj_desc->common.type));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %s\n",
+			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
 	}
 
 	acpi_ut_remove_reference (obj_desc);
@@ -196,7 +197,7 @@
  *
  * FUNCTION:    Acpi_hw_get_register_bit_mask
  *
- * PARAMETERS:  Register_id     - index of ACPI Register to access
+ * PARAMETERS:  Register_id         - Index of ACPI Register to access
  *
  * RETURN:      The bit mask to be used when accessing the register
  *
@@ -224,8 +225,8 @@
  *
  * FUNCTION:    Acpi_get_register
  *
- * PARAMETERS:  Register_id     - index of ACPI Register to access
- *              Use_lock        - Lock the hardware
+ * PARAMETERS:  Register_id         - Index of ACPI Register to access
+ *              Use_lock            - Lock the hardware
  *
  * RETURN:      Value is read from specified Register.  Value returned is
  *              normalized to bit0 (is shifted all the way right)
diff -Nru a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h
--- a/drivers/acpi/include/acconfig.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/include/acconfig.h	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acconfig.h - Global configuration constants
- *       $Revision: 102 $
+ *       $Revision: 104 $
  *
  *****************************************************************************/
 
@@ -54,36 +54,36 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION             0x20020517
+#define ACPI_CA_VERSION                 0x20020611
 
 /* Version of ACPI supported */
 
-#define ACPI_CA_SUPPORT_LEVEL       2
+#define ACPI_CA_SUPPORT_LEVEL           2
 
 /* Maximum objects in the various object caches */
 
-#define MAX_STATE_CACHE_DEPTH       64          /* State objects for stacks */
-#define MAX_PARSE_CACHE_DEPTH       96          /* Parse tree objects */
-#define MAX_EXTPARSE_CACHE_DEPTH    64          /* Parse tree objects */
-#define MAX_OBJECT_CACHE_DEPTH      64          /* Interpreter operand objects */
-#define MAX_WALK_CACHE_DEPTH        4           /* Objects for parse tree walks */
+#define MAX_STATE_CACHE_DEPTH           64          /* State objects for stacks */
+#define MAX_PARSE_CACHE_DEPTH           96          /* Parse tree objects */
+#define MAX_EXTPARSE_CACHE_DEPTH        64          /* Parse tree objects */
+#define MAX_OBJECT_CACHE_DEPTH          64          /* Interpreter operand objects */
+#define MAX_WALK_CACHE_DEPTH            4           /* Objects for parse tree walks */
 
 /* String size constants */
 
-#define MAX_STRING_LENGTH           512
-#define PATHNAME_MAX                256         /* A full namespace pathname */
+#define MAX_STRING_LENGTH               512
+#define PATHNAME_MAX                    256         /* A full namespace pathname */
 
 /* Maximum count for a semaphore object */
 
-#define MAX_SEMAPHORE_COUNT         256
+#define MAX_SEMAPHORE_COUNT             256
 
 /* Max reference count (for debug only) */
 
-#define MAX_REFERENCE_COUNT         0x400
+#define MAX_REFERENCE_COUNT             0x400
 
 /* Size of cached memory mapping for system memory operation region */
 
-#define SYSMEM_REGION_WINDOW_SIZE   4096
+#define SYSMEM_REGION_WINDOW_SIZE       4096
 
 
 /******************************************************************************
@@ -92,29 +92,12 @@
  *
  *****************************************************************************/
 
-/*
- * Debugger threading model
- * Use single threaded if the entire subsystem is contained in an application
- * Use multiple threaded when the subsystem is running in the kernel.
- *
- * By default the model is single threaded if ACPI_APPLICATION is set,
- * multi-threaded if ACPI_APPLICATION is not set.
- */
-#define DEBUGGER_SINGLE_THREADED    0
-#define DEBUGGER_MULTI_THREADED     1
-
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
-
-#else
-#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
-#endif
 
 /*
  * Should the subystem abort the loading of an ACPI table if the
  * table checksum is incorrect?
  */
-#define ACPI_CHECKSUM_ABORT         FALSE
+#define ACPI_CHECKSUM_ABORT             FALSE
 
 
 /******************************************************************************
@@ -125,54 +108,54 @@
 
 /* Number of distinct GPE register blocks */
 
-#define ACPI_MAX_GPE_BLOCKS         2
+#define ACPI_MAX_GPE_BLOCKS             2
 
 /*
  * Method info (in WALK_STATE), containing local variables and argumetns
  */
-#define MTH_NUM_LOCALS              8
-#define MTH_MAX_LOCAL               7
+#define MTH_NUM_LOCALS                  8
+#define MTH_MAX_LOCAL                   7
 
-#define MTH_NUM_ARGS                7
-#define MTH_MAX_ARG                 6
+#define MTH_NUM_ARGS                    7
+#define MTH_MAX_ARG                     6
 
 /* Maximum length of resulting string when converting from a buffer */
 
-#define ACPI_MAX_STRING_CONVERSION  200
+#define ACPI_MAX_STRING_CONVERSION      200
 
 /*
  * Operand Stack (in WALK_STATE), Must be large enough to contain MTH_MAX_ARG
  */
-#define OBJ_NUM_OPERANDS            8
-#define OBJ_MAX_OPERAND             7
+#define OBJ_NUM_OPERANDS                8
+#define OBJ_MAX_OPERAND                 7
 
 /* Names within the namespace are 4 bytes long */
 
-#define ACPI_NAME_SIZE              4
-#define PATH_SEGMENT_LENGTH         5           /* 4 chars for name + 1 char for separator */
-#define PATH_SEPARATOR              '.'
+#define ACPI_NAME_SIZE                  4
+#define PATH_SEGMENT_LENGTH             5           /* 4 chars for name + 1 char for separator */
+#define PATH_SEPARATOR                  '.'
 
 /* Constants used in searching for the RSDP in low memory */
 
-#define LO_RSDP_WINDOW_BASE         0           /* Physical Address */
-#define HI_RSDP_WINDOW_BASE         0xE0000     /* Physical Address */
-#define LO_RSDP_WINDOW_SIZE         0x400
-#define HI_RSDP_WINDOW_SIZE         0x20000
-#define RSDP_SCAN_STEP              16
+#define LO_RSDP_WINDOW_BASE             0           /* Physical Address */
+#define HI_RSDP_WINDOW_BASE             0xE0000     /* Physical Address */
+#define LO_RSDP_WINDOW_SIZE             0x400
+#define HI_RSDP_WINDOW_SIZE             0x20000
+#define RSDP_SCAN_STEP                  16
 
 /* Operation regions */
 
-#define ACPI_NUM_PREDEFINED_REGIONS 8
-#define ACPI_USER_REGION_BEGIN      0x80
+#define ACPI_NUM_PREDEFINED_REGIONS     8
+#define ACPI_USER_REGION_BEGIN          0x80
 
 /* Maximum Space_ids for Operation Regions */
 
-#define ACPI_MAX_ADDRESS_SPACE      255
+#define ACPI_MAX_ADDRESS_SPACE          255
 
 /* RSDP checksums */
 
-#define ACPI_RSDP_CHECKSUM_LENGTH   20
-#define ACPI_RSDP_XCHECKSUM_LENGTH  36
+#define ACPI_RSDP_CHECKSUM_LENGTH       20
+#define ACPI_RSDP_XCHECKSUM_LENGTH      36
 
 
 /******************************************************************************
@@ -182,10 +165,10 @@
  *****************************************************************************/
 
 
-#define ACPI_DEBUGGER_MAX_ARGS             8  /* Must be max method args + 1 */
+#define ACPI_DEBUGGER_MAX_ARGS          8  /* Must be max method args + 1 */
 
-#define ACPI_DEBUGGER_COMMAND_PROMPT      '-'
-#define ACPI_DEBUGGER_EXECUTE_PROMPT      '%'
+#define ACPI_DEBUGGER_COMMAND_PROMPT    '-'
+#define ACPI_DEBUGGER_EXECUTE_PROMPT    '%'
 
 
 #endif /* _ACCONFIG_H */
diff -Nru a/drivers/acpi/include/acinterp.h b/drivers/acpi/include/acinterp.h
--- a/drivers/acpi/include/acinterp.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/include/acinterp.h	Sun Jun 16 19:31:41 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acinterp.h - Interpreter subcomponent prototypes and defines
- *       $Revision: 137 $
+ *       $Revision: 138 $
  *
  *****************************************************************************/
 
@@ -603,8 +603,7 @@
 
 void
 acpi_ex_truncate_for32bit_table (
-	acpi_operand_object     *obj_desc,
-	acpi_walk_state         *walk_state);
+	acpi_operand_object     *obj_desc);
 
 u8
 acpi_ex_validate_object_type (
diff -Nru a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h
--- a/drivers/acpi/include/acmacros.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/include/acmacros.h	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acmacros.h - C macros for the entire subsystem.
- *       $Revision: 123 $
+ *       $Revision: 124 $
  *
  *****************************************************************************/
 
@@ -262,7 +262,7 @@
 
 /* Macro to test the object type */
 
-#define ACPI_GET_OBJECT_TYPE(d)         (((acpi_operand_object *)(void *)d)->common.type)
+#define ACPI_GET_OBJECT_TYPE(d)         (((acpi_operand_object *)(void *)(d))->common.type)
 
 /* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */
 
diff -Nru a/drivers/acpi/include/acobject.h b/drivers/acpi/include/acobject.h
--- a/drivers/acpi/include/acobject.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/include/acobject.h	Sun Jun 16 19:31:39 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Name: acobject.h - Definition of acpi_operand_object  (Internal object only)
- *       $Revision: 111 $
+ *       $Revision: 112 $
  *
  *****************************************************************************/
 
@@ -56,7 +56,7 @@
 
 /* Values for flag byte above */
 
-#define AOPOBJ_RESERVED             0x01
+#define AOPOBJ_AML_CONSTANT         0x01
 #define AOPOBJ_STATIC_POINTER       0x02
 #define AOPOBJ_DATA_VALID           0x04
 #define AOPOBJ_OBJECT_INITIALIZED   0x08
diff -Nru a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h
--- a/drivers/acpi/include/acoutput.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/include/acoutput.h	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acoutput.h -- debug output
- *       $Revision: 86 $
+ *       $Revision: 87 $
  *
  *****************************************************************************/
 
@@ -105,6 +105,16 @@
 #define ACPI_LV_INTERRUPTS          0x08000000
 #define ACPI_LV_VERBOSITY3          0x0F000000 | ACPI_LV_VERBOSITY2
 
+/* Exceptionally verbose output -- also used in the global "Debug_level" */
+
+#define ACPI_LV_AML_DISASSEMBLE     0x10000000
+#define ACPI_LV_VERBOSE_INFO        0x20000000
+#define ACPI_LV_FULL_TABLES         0x40000000
+#define ACPI_LV_EVENTS              0x80000000
+
+#define ACPI_LV_VERBOSE             0xF0000000
+
+
 /*
  * Debug level macros that are used in the DEBUG_PRINT macros
  */
@@ -145,17 +155,7 @@
 #define ACPI_DB_MUTEX               ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX)
 #define ACPI_DB_INIT                ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
 
-#define ACPI_DB_ALL                 ACPI_DEBUG_LEVEL (0x0FFFFF80)
-
-
-/* Exceptionally verbose output -- also used in the global "Debug_level" */
-
-#define ACPI_DB_AML_DISASSEMBLE     0x10000000
-#define ACPI_DB_VERBOSE_INFO        0x20000000
-#define ACPI_DB_FULL_TABLES         0x40000000
-#define ACPI_DB_EVENTS              0x80000000
-
-#define ACPI_DB_VERBOSE             0xF0000000
+#define ACPI_DB_ALL                 ACPI_DEBUG_LEVEL (ACPI_LV_ALL)
 
 
 /* Defaults for Debug_level, debug and normal */
diff -Nru a/drivers/acpi/include/acpixf.h b/drivers/acpi/include/acpixf.h
--- a/drivers/acpi/include/acpixf.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/include/acpixf.h	Sun Jun 16 19:31:39 2002
@@ -196,6 +196,14 @@
 	acpi_buffer             *return_object_buffer);
 
 acpi_status
+acpi_evaluate_object_typed (
+	acpi_handle             object,
+	acpi_string             pathname,
+	acpi_object_list        *external_params,
+	acpi_buffer             *return_buffer,
+	acpi_object_type        return_type);
+
+acpi_status
 acpi_get_object_info (
 	acpi_handle             device,
 	acpi_device_info        *info);
diff -Nru a/drivers/acpi/include/acutils.h b/drivers/acpi/include/acutils.h
--- a/drivers/acpi/include/acutils.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/include/acutils.h	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures
- *       $Revision: 137 $
+ *       $Revision: 140 $
  *
  *****************************************************************************/
 
@@ -100,12 +100,15 @@
 acpi_ut_get_mutex_name (
 	u32                     mutex_id);
 
+#endif
+
 NATIVE_CHAR *
 acpi_ut_get_type_name (
 	acpi_object_type        type);
 
-#endif
-
+NATIVE_CHAR *
+acpi_ut_get_object_type_name (
+	acpi_operand_object     *obj_desc);
 
 NATIVE_CHAR *
 acpi_ut_get_region_name (
@@ -662,17 +665,6 @@
 NATIVE_CHAR *
 acpi_ut_strupr (
 	NATIVE_CHAR             *src_string);
-
-acpi_status
-acpi_ut_resolve_package_references (
-	acpi_operand_object     *obj_desc);
-
-acpi_status
-acpi_ut_resolve_reference (
-	u8                      object_type,
-	acpi_operand_object     *source_object,
-	acpi_generic_state      *state,
-	void                    *context);
 
 u8 *
 acpi_ut_get_resource_end_tag (
diff -Nru a/drivers/acpi/include/platform/acenv.h b/drivers/acpi/include/platform/acenv.h
--- a/drivers/acpi/include/platform/acenv.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/include/platform/acenv.h	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acenv.h - Generation environment specific items
- *       $Revision: 94 $
+ *       $Revision: 95 $
  *
  *****************************************************************************/
 
@@ -56,17 +56,6 @@
 #endif
 
 /*
- * Memory allocation tracking.  Used only if
- * 1) This is the debug version
- * 2) This is NOT a 16-bit version of the code (not enough real-mode memory)
- */
-#ifdef ACPI_DEBUG
-#if ACPI_MACHINE_WIDTH != 16
-#define ACPI_DBG_TRACK_ALLOCATIONS
-#endif
-#endif
-
-/*
  * Environment configuration.  The purpose of this file is to interface to the
  * local generation environment.
  *
@@ -151,7 +140,38 @@
 
 #endif
 
+/*
+ * Memory allocation tracking.  Used only if
+ * 1) This is the debug version
+ * 2) This is NOT a 16-bit version of the code (not enough real-mode memory)
+ */
+#ifdef ACPI_DEBUG
+#if ACPI_MACHINE_WIDTH != 16
+#define ACPI_DBG_TRACK_ALLOCATIONS
+#endif
+#endif
+
 /*! [End] no source code translation !*/
+
+
+/*
+ * Debugger threading model
+ * Use single threaded if the entire subsystem is contained in an application
+ * Use multiple threaded when the subsystem is running in the kernel.
+ *
+ * By default the model is single threaded if ACPI_APPLICATION is set,
+ * multi-threaded if ACPI_APPLICATION is not set.
+ */
+#define DEBUGGER_SINGLE_THREADED    0
+#define DEBUGGER_MULTI_THREADED     1
+
+#ifdef ACPI_APPLICATION
+#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
+
+#else
+#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
+#endif
+
 
 /******************************************************************************
  *
diff -Nru a/drivers/acpi/include/platform/aclinux.h b/drivers/acpi/include/platform/aclinux.h
--- a/drivers/acpi/include/platform/aclinux.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/include/platform/aclinux.h	Sun Jun 16 19:31:41 2002
@@ -69,7 +69,4 @@
 
 #include "acgcc.h"
 
-#undef DEBUGGER_THREADING
-#define DEBUGGER_THREADING	DEBUGGER_SINGLE_THREADED
-
 #endif /* __ACLINUX_H__ */
diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
--- a/drivers/acpi/namespace/nsaccess.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/namespace/nsaccess.c	Sun Jun 16 19:31:41 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
- *              $Revision: 155 $
+ *              $Revision: 156 $
  *
  ******************************************************************************/
 
@@ -179,7 +179,7 @@
 
 			/* Store pointer to value descriptor in the Node */
 
-			status = acpi_ns_attach_object (new_node, obj_desc, obj_desc->common.type);
+			status = acpi_ns_attach_object (new_node, obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc));
 
 			/* Remove local reference to the object */
 
diff -Nru a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
--- a/drivers/acpi/namespace/nsdump.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/namespace/nsdump.c	Sun Jun 16 19:31:41 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nsdump - table dumping routines for debug
- *              $Revision: 135 $
+ *              $Revision: 136 $
  *
  *****************************************************************************/
 
@@ -500,7 +500,7 @@
 
 		case ACPI_DESC_TYPE_OPERAND:
 
-			obj_type = obj_desc->common.type;
+			obj_type = ACPI_GET_OBJECT_TYPE (obj_desc);
 
 			if (obj_type > INTERNAL_TYPE_MAX) {
 				acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type);
diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
--- a/drivers/acpi/namespace/nseval.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/namespace/nseval.c	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: nseval - Object evaluation interfaces -- includes control
  *                       method lookup and execution.
- *              $Revision: 114 $
+ *              $Revision: 116 $
  *
  ******************************************************************************/
 
@@ -40,12 +40,12 @@
  * FUNCTION:    Acpi_ns_evaluate_relative
  *
  * PARAMETERS:  Handle              - The relative containing object
- *              *Pathname           - Name of method to execute, If NULL, the
+ *              Pathname            - Name of method to execute, If NULL, the
  *                                    handle is the object to execute
- *              **Params            - List of parameters to pass to the method,
+ *              Params              - List of parameters to pass to the method,
  *                                    terminated by NULL.  Params itself may be
  *                                    NULL if no parameters are being passed.
- *              *Return_object      - Where to put method's return value (if
+ *              Return_object       - Where to put method's return value (if
  *                                    any).  If NULL, no value is returned.
  *
  * RETURN:      Status
@@ -141,9 +141,9 @@
  * FUNCTION:    Acpi_ns_evaluate_by_name
  *
  * PARAMETERS:  Pathname            - Fully qualified pathname to the object
- *              *Return_object      - Where to put method's return value (if
+ *              Return_object       - Where to put method's return value (if
  *                                    any).  If NULL, no value is returned.
- *              **Params            - List of parameters to pass to the method,
+ *              Params              - List of parameters to pass to the method,
  *                                    terminated by NULL.  Params itself may be
  *                                    NULL if no parameters are being passed.
  *
@@ -226,10 +226,10 @@
  * FUNCTION:    Acpi_ns_evaluate_by_handle
  *
  * PARAMETERS:  Handle              - Method Node to execute
- *              **Params            - List of parameters to pass to the method,
+ *              Params              - List of parameters to pass to the method,
  *                                    terminated by NULL.  Params itself may be
  *                                    NULL if no parameters are being passed.
- *              *Return_object      - Where to put method's return value (if
+ *              Return_object       - Where to put method's return value (if
  *                                    any).  If NULL, no value is returned.
  *
  * RETURN:      Status
@@ -285,7 +285,6 @@
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-
 	/*
 	 * Two major cases here:
 	 * 1) The object is an actual control method -- execute it.
@@ -302,7 +301,6 @@
 		status = acpi_ns_execute_control_method (node, params,
 				 &local_return_object);
 	}
-
 	else {
 		/*
 		 * Case 2) Object is NOT a method, just return its
@@ -311,7 +309,6 @@
 		status = acpi_ns_get_object_value (node, &local_return_object);
 	}
 
-
 	/*
 	 * Check if there is a return value on the stack that must
 	 * be dealt with
@@ -348,11 +345,11 @@
  *
  * FUNCTION:    Acpi_ns_execute_control_method
  *
- * PARAMETERS:  Method_node     - The object/method
- *              **Params            - List of parameters to pass to the method,
+ * PARAMETERS:  Method_node         - The method to execute
+ *              Params              - List of parameters to pass to the method,
  *                                    terminated by NULL.  Params itself may be
  *                                    NULL if no parameters are being passed.
- *              **Return_obj_desc   - List of result objects to be returned
+ *              Return_obj_desc     - List of result objects to be returned
  *                                    from the method.
  *
  * RETURN:      Status
@@ -424,7 +421,8 @@
  *
  * FUNCTION:    Acpi_ns_get_object_value
  *
- * PARAMETERS:  Node         - The object
+ * PARAMETERS:  Node                - The object
+ *              Return_obj_desc     - Where the objects value is returned
  *
  * RETURN:      Status
  *
diff -Nru a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
--- a/drivers/acpi/namespace/nsobject.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/namespace/nsobject.c	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: nsobject - Utilities for objects attached to namespace
  *                         table entries
- *              $Revision: 82 $
+ *              $Revision: 83 $
  *
  ******************************************************************************/
 
@@ -199,8 +199,9 @@
 
 
 	obj_desc = node->object;
-	if (!obj_desc   ||
-		(obj_desc->common.type == INTERNAL_TYPE_DATA)) {
+
+	if (!obj_desc ||
+		(ACPI_GET_OBJECT_TYPE (obj_desc) == INTERNAL_TYPE_DATA)) {
 		return_VOID;
 	}
 
@@ -210,7 +211,7 @@
 	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) {
 		node->object = obj_desc->common.next_object;
 		if (node->object &&
-		   (node->object->common.type != INTERNAL_TYPE_DATA)) {
+		   (ACPI_GET_OBJECT_TYPE (node->object) != INTERNAL_TYPE_DATA)) {
 			node->object = node->object->common.next_object;
 		}
 	}
@@ -255,7 +256,7 @@
 	if (!node->object ||
 			((ACPI_GET_DESCRIPTOR_TYPE (node->object) != ACPI_DESC_TYPE_OPERAND) &&
 			 (ACPI_GET_DESCRIPTOR_TYPE (node->object) != ACPI_DESC_TYPE_NAMED))  ||
-		(node->object->common.type == INTERNAL_TYPE_DATA)) {
+		(ACPI_GET_OBJECT_TYPE (node->object) == INTERNAL_TYPE_DATA)) {
 		return_PTR (NULL);
 	}
 
@@ -281,10 +282,10 @@
 	ACPI_FUNCTION_TRACE_PTR ("Ns_get_secondary_object", obj_desc);
 
 
-	if ((!obj_desc)                                  ||
-		(obj_desc->common.type == INTERNAL_TYPE_DATA) ||
-		(!obj_desc->common.next_object)              ||
-		(obj_desc->common.next_object->common.type == INTERNAL_TYPE_DATA)) {
+	if ((!obj_desc)                                             ||
+		(ACPI_GET_OBJECT_TYPE (obj_desc) == INTERNAL_TYPE_DATA) ||
+		(!obj_desc->common.next_object)                         ||
+		(ACPI_GET_OBJECT_TYPE (obj_desc->common.next_object) == INTERNAL_TYPE_DATA)) {
 		return_PTR (NULL);
 	}
 
@@ -319,7 +320,7 @@
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((obj_desc->common.type == INTERNAL_TYPE_DATA) &&
+		if ((ACPI_GET_OBJECT_TYPE (obj_desc) == INTERNAL_TYPE_DATA) &&
 			(obj_desc->data.handler == handler)) {
 			return (AE_ALREADY_EXISTS);
 		}
@@ -377,7 +378,7 @@
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((obj_desc->common.type == INTERNAL_TYPE_DATA) &&
+		if ((ACPI_GET_OBJECT_TYPE (obj_desc) == INTERNAL_TYPE_DATA) &&
 			(obj_desc->data.handler == handler)) {
 			if (prev_obj_desc) {
 				prev_obj_desc->common.next_object = obj_desc->common.next_object;
@@ -421,7 +422,7 @@
 
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((obj_desc->common.type == INTERNAL_TYPE_DATA) &&
+		if ((ACPI_GET_OBJECT_TYPE (obj_desc) == INTERNAL_TYPE_DATA) &&
 			(obj_desc->data.handler == handler)) {
 			*data = obj_desc->data.pointer;
 			return (AE_OK);
diff -Nru a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
--- a/drivers/acpi/namespace/nssearch.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/namespace/nssearch.c	Sun Jun 16 19:31:41 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nssearch - Namespace search
- *              $Revision: 85 $
+ *              $Revision: 86 $
  *
  ******************************************************************************/
 
@@ -204,7 +204,8 @@
 		}
 
 		if (acpi_ns_local (type)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"[%4.4s] type [%s] must be local to this scope (no parent search)\n",
 				(char *) &target_name, acpi_ut_get_type_name (type)));
 		}
 
diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
--- a/drivers/acpi/namespace/nsutils.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/namespace/nsutils.c	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
  *                        parents and siblings and Scope manipulation
- *              $Revision: 109 $
+ *              $Revision: 110 $
  *
  *****************************************************************************/
 
@@ -227,7 +227,7 @@
 	NATIVE_CHAR             *internal_name = info->internal_name;
 	NATIVE_CHAR             *external_name = info->next_external_char;
 	NATIVE_CHAR             *result = NULL;
-	NATIVE_UINT_MIN32       i;
+	NATIVE_UINT             i;
 
 
 	ACPI_FUNCTION_TRACE ("Ns_build_internal_name");
diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
--- a/drivers/acpi/parser/psopcode.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/parser/psopcode.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psopcode - Parser/Interpreter opcode information table
- *              $Revision: 69 $
+ *              $Revision: 70 $
  *
  *****************************************************************************/
 
@@ -453,8 +453,8 @@
 /*! [Begin] no source code translation */
 /* Index           Name                 Parser Args               Interpreter Args                ObjectType                Class                      Type                  Flags */
 
-/* 00 */ ACPI_OP ("Zero",               ARGP_ZERO_OP,              ARGI_ZERO_OP,               INTERNAL_TYPE_REFERENCE, AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
-/* 01 */ ACPI_OP ("One",                ARGP_ONE_OP,               ARGI_ONE_OP,                INTERNAL_TYPE_REFERENCE, AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
+/* 00 */ ACPI_OP ("Zero",               ARGP_ZERO_OP,              ARGI_ZERO_OP,               ACPI_TYPE_INTEGER,       AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
+/* 01 */ ACPI_OP ("One",                ARGP_ONE_OP,               ARGI_ONE_OP,                ACPI_TYPE_INTEGER,       AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
 /* 02 */ ACPI_OP ("Alias",              ARGP_ALIAS_OP,             ARGI_ALIAS_OP,              INTERNAL_TYPE_ALIAS,     AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_SIMPLE,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
 /* 03 */ ACPI_OP ("Name",               ARGP_NAME_OP,              ARGI_NAME_OP,               ACPI_TYPE_ANY,           AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_COMPLEX,   AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
 /* 04 */ ACPI_OP ("ByteConst",          ARGP_BYTE_OP,              ARGI_BYTE_OP,               ACPI_TYPE_INTEGER,       AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         AML_CONSTANT),
@@ -522,7 +522,7 @@
 /* 42 */ ACPI_OP ("Return",             ARGP_RETURN_OP,            ARGI_RETURN_OP,             ACPI_TYPE_ANY,           AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         AML_HAS_ARGS),
 /* 43 */ ACPI_OP ("Break",              ARGP_BREAK_OP,             ARGI_BREAK_OP,              ACPI_TYPE_ANY,           AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         0),
 /* 44 */ ACPI_OP ("BreakPoint",         ARGP_BREAK_POINT_OP,       ARGI_BREAK_POINT_OP,        ACPI_TYPE_ANY,           AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         0),
-/* 45 */ ACPI_OP ("Ones",               ARGP_ONES_OP,              ARGI_ONES_OP,               INTERNAL_TYPE_REFERENCE, AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
+/* 45 */ ACPI_OP ("Ones",               ARGP_ONES_OP,              ARGI_ONES_OP,               ACPI_TYPE_INTEGER,       AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
 
 /* Prefixed opcodes (Two-byte opcodes with a prefix op) */
 
@@ -541,7 +541,7 @@
 /* 52 */ ACPI_OP ("FromBCD",            ARGP_FROM_BCD_OP,          ARGI_FROM_BCD_OP,           ACPI_TYPE_ANY,           AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
 /* 53 */ ACPI_OP ("ToBCD",              ARGP_TO_BCD_OP,            ARGI_TO_BCD_OP,             ACPI_TYPE_ANY,           AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
 /* 54 */ ACPI_OP ("Unload",             ARGP_UNLOAD_OP,            ARGI_UNLOAD_OP,             ACPI_TYPE_ANY,           AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_0R,   AML_FLAGS_EXEC_1A_0T_0R),
-/* 55 */ ACPI_OP ("Revision",           ARGP_REVISION_OP,          ARGI_REVISION_OP,           INTERNAL_TYPE_REFERENCE, AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        0),
+/* 55 */ ACPI_OP ("Revision",           ARGP_REVISION_OP,          ARGI_REVISION_OP,           ACPI_TYPE_INTEGER,       AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        0),
 /* 56 */ ACPI_OP ("Debug",              ARGP_DEBUG_OP,             ARGI_DEBUG_OP,              INTERNAL_TYPE_REFERENCE, AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        0),
 /* 57 */ ACPI_OP ("Fatal",              ARGP_FATAL_OP,             ARGI_FATAL_OP,              ACPI_TYPE_ANY,           AML_CLASS_EXECUTE,         AML_TYPE_EXEC_3A_0T_0R,   AML_FLAGS_EXEC_3A_0T_0R),
 /* 58 */ ACPI_OP ("OperationRegion",    ARGP_REGION_OP,            ARGI_REGION_OP,             ACPI_TYPE_REGION,        AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_COMPLEX,   AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/pci_root.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*
- *  pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 37 $)
+ *  pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 38 $)
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -56,11 +56,107 @@
                                 },
 };
 
-struct acpi_pci_root {
-	acpi_handle		handle;
-	acpi_pci_id		id;
-	struct pci_bus		*bus;
-};
+ struct acpi_pci_root {
+	struct list_head	node;
+ 	acpi_handle		handle;
+ 	acpi_pci_id		id;
+ 	struct pci_bus		*bus;
+	u64			mem_tra;
+	u64			io_tra;
+ };
+
+struct list_head		acpi_pci_roots;
+
+
+void
+acpi_pci_get_translations (
+	acpi_pci_id		*id,
+	u64			*mem_tra,
+	u64			*io_tra)
+{
+	struct list_head	*node = NULL;
+	struct acpi_pci_root	*entry;
+
+	/* TBD: Locking */
+	list_for_each(node, &acpi_pci_roots) {
+		entry = list_entry(node, struct acpi_pci_root, node);
+		if ((id->segment == entry->id.segment)
+			&& (id->bus == entry->id.bus)) {
+			*mem_tra = entry->mem_tra;
+			*io_tra = entry->io_tra;
+			return;
+		}
+	}
+
+	*mem_tra = 0;
+	*io_tra = 0;
+}
+
+
+static u64
+acpi_pci_root_bus_tra (
+       acpi_resource           *resource,
+       int                     type)
+{
+	acpi_resource_address16 *address16;
+	acpi_resource_address32 *address32;
+	acpi_resource_address64 *address64;
+
+	while (1) {
+		switch (resource->id) {
+		case ACPI_RSTYPE_END_TAG:
+			return 0;
+
+		case ACPI_RSTYPE_ADDRESS16:
+			address16 = (acpi_resource_address16 *) &resource->data;
+			if (type == address16->resource_type) {
+				return address16->address_translation_offset;
+			}
+			break;
+
+		case ACPI_RSTYPE_ADDRESS32:
+			address32 = (acpi_resource_address32 *) &resource->data;
+			if (type == address32->resource_type) {
+				return address32->address_translation_offset;
+			}
+			break;
+
+		case ACPI_RSTYPE_ADDRESS64:
+			address64 = (acpi_resource_address64 *) &resource->data;
+			if (type == address64->resource_type) {
+				return address64->address_translation_offset;
+			}
+			break;
+		}
+		resource = ACPI_PTR_ADD (acpi_resource,
+				resource, resource->length);
+	}
+
+	return 0;
+}
+
+
+static int
+acpi_pci_evaluate_crs (
+	struct acpi_pci_root	*root)
+{
+	acpi_status		status;
+	acpi_buffer		buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_pci_evaluate_crs");
+
+	status = acpi_get_current_resources (root->handle, &buffer);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	root->io_tra = acpi_pci_root_bus_tra ((acpi_resource *)
+			buffer.pointer, ACPI_IO_RANGE);
+	root->mem_tra = acpi_pci_root_bus_tra ((acpi_resource *)
+			buffer.pointer, ACPI_MEMORY_RANGE);
+
+	kfree(buffer.pointer);
+	return_VALUE(0);
+}
 
 
 static int
@@ -147,9 +243,13 @@
 	root->id.function = device->pnp.bus_address & 0xFFFF;
 
 	/*
-	 * TBD: Evaluate _CRS to get root bridge resources
+	 * Evaluate _CRS to get root bridge resources
 	 * TBD: Need PCI interface for enumeration/configuration of roots.
 	 */
+ 	acpi_pci_evaluate_crs(root);
+
+ 	/* TBD: Locking */
+ 	list_add_tail(&root->node, &acpi_pci_roots);
 
 	printk(KERN_INFO PREFIX "%s [%s] (%02x:%02x)\n", 
 		acpi_device_name(device), acpi_device_bid(device),
@@ -227,6 +327,8 @@
 	acpi_dbg_layer = ACPI_PCI_COMPONENT;
 	acpi_dbg_level = 0xFFFFFFFF;
 	 */
+
+ 	INIT_LIST_HEAD(&acpi_pci_roots);
 
 	if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
 		return_VALUE(-ENODEV);
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/processor.c	Sun Jun 16 19:31:41 2002
@@ -2312,3 +2312,5 @@
 
 module_init(acpi_processor_init);
 module_exit(acpi_processor_exit);
+
+EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
--- a/drivers/acpi/resources/rscalc.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/resources/rscalc.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: rscalc - Calculate stream and list lengths
- *              $Revision: 42 $
+ *              $Revision: 43 $
  *
  ******************************************************************************/
 
@@ -770,8 +770,8 @@
 		name_found = FALSE;
 
 		for (table_index = 0; table_index < 4 && !name_found; table_index++) {
-			if ((ACPI_TYPE_STRING == (*sub_object_list)->common.type) ||
-				((INTERNAL_TYPE_REFERENCE == (*sub_object_list)->common.type) &&
+			if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*sub_object_list)) ||
+				((INTERNAL_TYPE_REFERENCE == ACPI_GET_OBJECT_TYPE (*sub_object_list)) &&
 					((*sub_object_list)->reference.opcode == AML_INT_NAMEPATH_OP))) {
 				name_found = TRUE;
 			}
@@ -789,7 +789,7 @@
 		 * Was a String type found?
 		 */
 		if (name_found) {
-			if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) {
+			if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) {
 				/*
 				 * The length String.Length field includes the
 				 * terminating NULL
diff -Nru a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
--- a/drivers/acpi/resources/rscreate.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/resources/rscreate.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: rscreate - Create resource lists/tables
- *              $Revision: 56 $
+ *              $Revision: 57 $
  *
  ******************************************************************************/
 
@@ -212,12 +212,12 @@
 		/*
 		 * 1) First subobject:  Dereference the Address
 		 */
-		if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_INTEGER) {
 			user_prt->address = (*sub_object_list)->integer.value;
 		}
 		else {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n",
-				acpi_ut_get_type_name ((*sub_object_list)->common.type)));
+				acpi_ut_get_object_type_name (*sub_object_list)));
 			return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
@@ -226,12 +226,12 @@
 		 */
 		sub_object_list++;
 
-		if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_INTEGER) {
 			user_prt->pin = (u32) (*sub_object_list)->integer.value;
 		}
 		else {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n",
-				acpi_ut_get_type_name ((*sub_object_list)->common.type)));
+				acpi_ut_get_object_type_name (*sub_object_list)));
 			return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
@@ -240,7 +240,7 @@
 		 */
 		sub_object_list++;
 
-		switch ((*sub_object_list)->common.type) {
+		switch (ACPI_GET_OBJECT_TYPE (*sub_object_list)) {
 		case INTERNAL_TYPE_REFERENCE:
 
 			if ((*sub_object_list)->reference.opcode != AML_INT_NAMEPATH_OP) {
@@ -288,7 +288,7 @@
 		default:
 
 		   ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n",
-				acpi_ut_get_type_name ((*sub_object_list)->common.type)));
+				acpi_ut_get_object_type_name (*sub_object_list)));
 		   return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
@@ -301,12 +301,12 @@
 		 */
 		sub_object_list++;
 
-		if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) {
+		if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_INTEGER) {
 			user_prt->source_index = (u32) (*sub_object_list)->integer.value;
 		}
 		else {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n",
-				acpi_ut_get_type_name ((*sub_object_list)->common.type)));
+				acpi_ut_get_object_type_name (*sub_object_list)));
 			return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
--- a/drivers/acpi/resources/rsutils.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/resources/rsutils.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: rsutils - Utilities for the resource manager
- *              $Revision: 30 $
+ *              $Revision: 33 $
  *
  ******************************************************************************/
 
@@ -56,7 +56,7 @@
 	acpi_handle             handle,
 	acpi_buffer             *ret_buffer)
 {
-	acpi_operand_object     *ret_obj;
+	acpi_operand_object     *obj_desc;
 	acpi_status             status;
 
 
@@ -68,12 +68,12 @@
 	/*
 	 *  Execute the method, no parameters
 	 */
-	status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &ret_obj);
+	status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	if (!ret_obj) {
+	if (!obj_desc) {
 		/* Return object is required */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRT\n"));
@@ -81,13 +81,13 @@
 	}
 
 	/*
-	 * The return object will be a package, so check the parameters.  If the
+	 * The return object must be a package, so check the parameters.  If the
 	 * return object is not a package, then the underlying AML code is corrupt
 	 * or improperly written.
 	 */
-	if (ACPI_TYPE_PACKAGE != ret_obj->common.type) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_PACKAGE) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_PRT did not return a Package, returned %s\n",
-				acpi_ut_get_type_name (ret_obj->common.type)));
+				acpi_ut_get_object_type_name (obj_desc)));
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
 	}
@@ -96,13 +96,13 @@
 	 * Create a resource linked list from the byte stream buffer that comes
 	 * back from the _CRS method execution.
 	 */
-	status = acpi_rs_create_pci_routing_table (ret_obj, ret_buffer);
+	status = acpi_rs_create_pci_routing_table (obj_desc, ret_buffer);
 
 	/* On exit, we must delete the object returned by Evaluate_object */
 
 cleanup:
 
-	acpi_ut_remove_reference (ret_obj);
+	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
 }
 
@@ -130,7 +130,7 @@
 	acpi_handle             handle,
 	acpi_buffer             *ret_buffer)
 {
-	acpi_operand_object     *ret_obj;
+	acpi_operand_object     *obj_desc;
 	acpi_status             status;
 
 
@@ -142,12 +142,12 @@
 	/*
 	 * Execute the method, no parameters
 	 */
-	status = acpi_ns_evaluate_relative (handle, "_CRS", NULL, &ret_obj);
+	status = acpi_ns_evaluate_relative (handle, "_CRS", NULL, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	if (!ret_obj) {
+	if (!obj_desc) {
 		/* Return object is required */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _CRS\n"));
@@ -160,9 +160,9 @@
 	 * then the underlying AML code is corrupt or improperly
 	 * written.
 	 */
-	if (ACPI_TYPE_BUFFER != ret_obj->common.type) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_CRS did not return a Buffer, returned %s\n",
-				acpi_ut_get_type_name (ret_obj->common.type)));
+				acpi_ut_get_object_type_name (obj_desc)));
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
 	}
@@ -172,13 +172,13 @@
 	 * byte stream buffer that comes back from the _CRS method
 	 * execution.
 	 */
-	status = acpi_rs_create_resource_list (ret_obj, ret_buffer);
+	status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
 
 	/* On exit, we must delete the object returned by evaluate_object */
 
 cleanup:
 
-	acpi_ut_remove_reference (ret_obj);
+	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
 }
 
@@ -206,7 +206,7 @@
 	acpi_handle             handle,
 	acpi_buffer             *ret_buffer)
 {
-	acpi_operand_object     *ret_obj;
+	acpi_operand_object     *obj_desc;
 	acpi_status             status;
 
 
@@ -218,12 +218,12 @@
 	/*
 	 * Execute the method, no parameters
 	 */
-	status = acpi_ns_evaluate_relative (handle, "_PRS", NULL, &ret_obj);
+	status = acpi_ns_evaluate_relative (handle, "_PRS", NULL, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	if (!ret_obj) {
+	if (!obj_desc) {
 		/* Return object is required */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRS\n"));
@@ -236,9 +236,9 @@
 	 * then the underlying AML code is corrupt or improperly
 	 * written..
 	 */
-	if (ACPI_TYPE_BUFFER != ret_obj->common.type) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_PRS did not return a Buffer, returned %s\n",
-				acpi_ut_get_type_name (ret_obj->common.type)));
+				acpi_ut_get_object_type_name (obj_desc)));
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
 	}
@@ -248,13 +248,13 @@
 	 * byte stream buffer that comes back from the _CRS method
 	 * execution.
 	 */
-	status = acpi_rs_create_resource_list (ret_obj, ret_buffer);
+	status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
 
 	/* On exit, we must delete the object returned by evaluate_object */
 
 cleanup:
 
-	acpi_ut_remove_reference (ret_obj);
+	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
 }
 
@@ -319,6 +319,7 @@
 	 */
 	params[0]->buffer.length  = (u32) buffer.length;
 	params[0]->buffer.pointer = buffer.pointer;
+	params[0]->common.flags   = AOPOBJ_DATA_VALID;
 	params[1] = NULL;
 
 	/*
diff -Nru a/drivers/acpi/system.c b/drivers/acpi/system.c
--- a/drivers/acpi/system.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/system.c	Sun Jun 16 19:31:40 2002
@@ -24,6 +24,7 @@
  */
 
 #define ACPI_C
+#define HAVE_NEW_DEVICE_MODEL
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -134,9 +135,11 @@
 
 	/* restore device context */
 	device_resume(RESUME_RESTORE_STATE);
+#else
+#error Resume cant work without driver model
 #endif
 
-	if (dmi_broken & BROKEN_INIT_AFTER_S1) {
+	if ((state == ACPI_STATE_S1) && (dmi_broken & BROKEN_INIT_AFTER_S1)) {
 		printk("Broken toshiba laptop -> kicking interrupts\n");
 		init_8259A(0);
 	}
diff -Nru a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
--- a/drivers/acpi/tables/tbutils.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/tables/tbutils.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbutils - Table manipulation utilities
- *              $Revision: 53 $
+ *              $Revision: 54 $
  *
  *****************************************************************************/
 
@@ -91,7 +91,7 @@
  *             name
  *          3) Table must be readable for length specified in the header
  *          4) Table checksum must be valid (with the exception of the FACS
- *              which has no checksum for some odd reason)
+ *              which has no checksum because it contains variable fields)
  *
  ******************************************************************************/
 
@@ -187,21 +187,26 @@
 
 		table_size = (ACPI_SIZE) table->length;
 
+#if 0
+/* We don't want to validate the header here.  */
 		/*
 		 * Validate the header and delete the mapping.
 		 * We will create a mapping for the full table below.
 		 */
 		status = acpi_tb_validate_table_header (table);
+#endif
 
 		/* Always unmap the memory for the header */
 
 		acpi_os_unmap_memory (table, sizeof (acpi_table_header));
 
+#if 0
 		/* Exit if header invalid */
 
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
+#endif
 	}
 
 	/* Map the physical memory for the correct length */
diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/utilities/utcopy.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: utcopy - Internal to external object translation utilities
- *              $Revision: 98 $
+ *              $Revision: 101 $
  *
  *****************************************************************************/
 
@@ -57,7 +57,6 @@
 	u8                      *data_space,
 	ACPI_SIZE               *buffer_space_used)
 {
-	acpi_buffer             buffer;
 	acpi_status             status = AE_OK;
 
 
@@ -68,7 +67,7 @@
 
 	/*
 	 * Check for NULL object case (could be an uninitialized
-	 * package element
+	 * package element)
 	 */
 	if (!internal_object) {
 		return_ACPI_STATUS (AE_OK);
@@ -82,11 +81,11 @@
 	 * In general, the external object will be the same type as
 	 * the internal object
 	 */
-	external_object->type = internal_object->common.type;
+	external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
 
 	/* However, only a limited number of external types are supported */
 
-	switch (internal_object->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
 	case ACPI_TYPE_STRING:
 
 		external_object->string.pointer = (NATIVE_CHAR *) data_space;
@@ -121,45 +120,9 @@
 		 * This is an object reference.  Attempt to dereference it.
 		 */
 		switch (internal_object->reference.opcode) {
-		case AML_ZERO_OP:
-			external_object->type = ACPI_TYPE_INTEGER;
-			external_object->integer.value = 0;
-			break;
-
-		case AML_ONE_OP:
-			external_object->type = ACPI_TYPE_INTEGER;
-			external_object->integer.value = 1;
-			break;
-
-		case AML_ONES_OP:
-			external_object->type = ACPI_TYPE_INTEGER;
-			external_object->integer.value = ACPI_INTEGER_MAX;
-			break;
-
-		case AML_REVISION_OP:
-			external_object->type = ACPI_TYPE_INTEGER;
-			external_object->integer.value = ACPI_CA_SUPPORT_LEVEL;
-			break;
-
 		case AML_INT_NAMEPATH_OP:
-			/*
-			 * This is a named reference, get the string.  We already know that
-			 * we have room for it, use max length
-			 */
-			external_object->type = ACPI_TYPE_STRING;
-			external_object->string.pointer = (NATIVE_CHAR *) data_space;
-
-			buffer.length = MAX_STRING_LENGTH;
-			buffer.pointer = data_space;
-
-			status = acpi_ns_handle_to_pathname ((acpi_handle) internal_object->reference.node,
-					 &buffer);
 
-			/* Converted (external) string length is returned from above */
-
-			external_object->string.length = (u32) buffer.length;
-			*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (buffer.length);
-			break;
+			/* For namepath, return the object handle ("reference") */
 
 		default:
 			/*
@@ -175,7 +138,7 @@
 
 	case ACPI_TYPE_PROCESSOR:
 
-		external_object->processor.proc_id = internal_object->processor.proc_id;
+		external_object->processor.proc_id    = internal_object->processor.proc_id;
 		external_object->processor.pblk_address = internal_object->processor.address;
 		external_object->processor.pblk_length = internal_object->processor.length;
 		break;
@@ -328,7 +291,7 @@
 	info.num_packages = 1;
 	info.free_space  = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
 
-	external_object->type              = internal_object->common.type;
+	external_object->type              = ACPI_GET_OBJECT_TYPE (internal_object);
 	external_object->package.count     = internal_object->package.count;
 	external_object->package.elements  = ACPI_CAST_PTR (acpi_object, info.free_space);
 
@@ -372,7 +335,7 @@
 	ACPI_FUNCTION_TRACE ("Ut_copy_iobject_to_eobject");
 
 
-	if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
+	if (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE) {
 		/*
 		 * Package object:  Copy all subobjects (including
 		 * nested packages)
@@ -550,7 +513,7 @@
 	free_space = buffer + sizeof(acpi_object);
 
 
-	external_object->type              = internal_object->common.type;
+	external_object->type              = ACPI_GET_OBJECT_TYPE (internal_object);
 	external_object->package.count     = internal_object->package.count;
 	external_object->package.elements  = (acpi_object *)free_space;
 
@@ -653,7 +616,7 @@
 
 	/* Handle the objects with extra data */
 
-	switch (dest_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
 	case ACPI_TYPE_BUFFER:
 
 		dest_desc->buffer.node = NULL;
@@ -729,7 +692,7 @@
 		/*
 		 * This is a simple object, just copy it
 		 */
-		target_object = acpi_ut_create_internal_object (source_object->common.type);
+		target_object = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (source_object));
 		if (!target_object) {
 			return (AE_NO_MEMORY);
 		}
@@ -803,16 +766,16 @@
 	ACPI_FUNCTION_TRACE ("Ut_copy_ipackage_to_ipackage");
 
 
-	dest_obj->common.type   = source_obj->common.type;
+	dest_obj->common.type   = ACPI_GET_OBJECT_TYPE (source_obj);
 	dest_obj->common.flags  = source_obj->common.flags;
 	dest_obj->package.count = source_obj->package.count;
 
-
 	/*
 	 * Create the object array and walk the source package tree
 	 */
-	dest_obj->package.elements = ACPI_MEM_CALLOCATE (((ACPI_SIZE) source_obj->package.count + 1) *
-			 sizeof (void *));
+	dest_obj->package.elements = ACPI_MEM_CALLOCATE (
+			   ((ACPI_SIZE) source_obj->package.count + 1) *
+			   sizeof (void *));
 	if (!dest_obj->package.elements) {
 		ACPI_REPORT_ERROR (
 			("Aml_build_copy_internal_package_object: Package allocation failure\n"));
@@ -863,14 +826,14 @@
 
 	/* Create the top level object */
 
-	*dest_desc = acpi_ut_create_internal_object (source_desc->common.type);
+	*dest_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (source_desc));
 	if (!*dest_desc) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
 	/* Copy the object and possible subobjects */
 
-	if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
+	if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_PACKAGE) {
 		status = acpi_ut_copy_ipackage_to_ipackage (source_desc, *dest_desc,
 				  walk_state);
 	}
diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
--- a/drivers/acpi/utilities/utdelete.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/utilities/utdelete.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: utdelete - object deletion and reference count utilities
- *              $Revision: 90 $
+ *              $Revision: 91 $
  *
  ******************************************************************************/
 
@@ -65,7 +65,7 @@
 	 * Must delete or free any pointers within the object that are not
 	 * actual ACPI objects (for example, a raw buffer pointer).
 	 */
-	switch (object->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (object)) {
 	case ACPI_TYPE_STRING:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
@@ -190,7 +190,7 @@
 	/* Now the object can be safely deleted */
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
-			object, acpi_ut_get_type_name (object->common.type)));
+			object, acpi_ut_get_object_type_name (object)));
 
 	acpi_ut_delete_object_desc (object);
 	return_VOID;
@@ -295,7 +295,7 @@
 				object, new_count));
 		}
 
-		if (object->common.type == ACPI_TYPE_METHOD) {
+		if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
 				object, new_count));
 		}
@@ -403,7 +403,7 @@
 		 * All sub-objects must have their reference count incremented also.
 		 * Different object types have different subobjects.
 		 */
-		switch (object->common.type) {
+		switch (ACPI_GET_OBJECT_TYPE (object)) {
 		case ACPI_TYPE_DEVICE:
 
 			status = acpi_ut_create_update_state_and_push (object->device.addr_handler,
diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
--- a/drivers/acpi/utilities/uteval.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/utilities/uteval.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: uteval - Object evaluation
- *              $Revision: 39 $
+ *              $Revision: 40 $
  *
  *****************************************************************************/
 
@@ -91,11 +91,11 @@
 
 	/* Is the return object of the correct type? */
 
-	if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) {
 		status = AE_TYPE;
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Type returned from %s was not a number: %X \n",
-			object_name, obj_desc->common.type));
+			"Type returned from %s was not an Integer: %X \n",
+			object_name, ACPI_GET_OBJECT_TYPE (obj_desc)));
 	}
 	else {
 		/*
@@ -169,15 +169,16 @@
 	 *  A _HID can return either a Number (32 bit compressed EISA ID) or
 	 *  a string
 	 */
-	if ((obj_desc->common.type != ACPI_TYPE_INTEGER) &&
-		(obj_desc->common.type != ACPI_TYPE_STRING)) {
+	if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) &&
+		(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
 		status = AE_TYPE;
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Type returned from _HID not a number or string: %s(%X) \n",
-			acpi_ut_get_type_name (obj_desc->common.type), obj_desc->common.type));
+			acpi_ut_get_object_type_name (obj_desc),
+			ACPI_GET_OBJECT_TYPE (obj_desc)));
 	}
 	else {
-		if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 			/* Convert the Numeric HID to string */
 
 			acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer);
@@ -253,7 +254,7 @@
 	 *  IDs.  Each compatible ID can be a Number (32 bit compressed EISA ID) or
 	 *  string (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
 	 */
-	switch (obj_desc->common.type) {
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Convert the Numeric CID to string */
@@ -278,7 +279,8 @@
 		status = AE_TYPE;
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Type returned from _CID not a number, string, or package: %s(%X) \n",
-			acpi_ut_get_type_name (obj_desc->common.type), obj_desc->common.type));
+			acpi_ut_get_object_type_name (obj_desc),
+			ACPI_GET_OBJECT_TYPE (obj_desc)));
 		break;
 	}
 
@@ -347,15 +349,15 @@
 	 *  A _UID can return either a Number (32 bit compressed EISA ID) or
 	 *  a string
 	 */
-	if ((obj_desc->common.type != ACPI_TYPE_INTEGER) &&
-		(obj_desc->common.type != ACPI_TYPE_STRING)) {
+	if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) &&
+		(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
 		status = AE_TYPE;
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Type returned from _UID was not a number or string: %X \n",
-			obj_desc->common.type));
+			ACPI_GET_OBJECT_TYPE (obj_desc)));
 	}
 	else {
-		if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 			/* Convert the Numeric UID to string */
 
 			acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer);
@@ -433,11 +435,11 @@
 
 		/* Is the return object of the correct type? */
 
-		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) {
 			status = AE_TYPE;
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Type returned from _STA was not a number: %X \n",
-				obj_desc->common.type));
+				ACPI_GET_OBJECT_TYPE (obj_desc)));
 		}
 		else {
 			/* Extract the status flags */
diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/utilities/utglobal.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: utglobal - Global variables for the ACPI subsystem
- *              $Revision: 161 $
+ *              $Revision: 163 $
  *
  *****************************************************************************/
 
@@ -427,40 +427,6 @@
 }
 
 
-#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER)
-
-/*
- * Strings and procedures used for debug only
- *
- */
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_ut_get_mutex_name
- *
- * PARAMETERS:  None.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
- *
- ****************************************************************************/
-
-NATIVE_CHAR *
-acpi_ut_get_mutex_name (
-	u32                     mutex_id)
-{
-
-	if (mutex_id > MAX_MTX)
-	{
-		return ("Invalid Mutex ID");
-	}
-
-	return (acpi_gbl_mutex_names[mutex_id]);
-}
-
-
 /*****************************************************************************
  *
  * FUNCTION:    Acpi_ut_get_type_name
@@ -538,6 +504,54 @@
 	}
 
 	return ((NATIVE_CHAR *) acpi_gbl_ns_type_names[type]);
+}
+
+
+NATIVE_CHAR *
+acpi_ut_get_object_type_name (
+	acpi_operand_object     *obj_desc)
+{
+
+	if (!obj_desc)
+	{
+		return ("[NULL Object Descriptor]");
+	}
+
+	return (acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)));
+}
+
+
+#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER)
+
+/*
+ * Strings and procedures used for debug only
+ *
+ */
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_get_mutex_name
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+NATIVE_CHAR *
+acpi_ut_get_mutex_name (
+	u32                     mutex_id)
+{
+
+	if (mutex_id > MAX_MTX)
+	{
+		return ("Invalid Mutex ID");
+	}
+
+	return (acpi_gbl_mutex_names[mutex_id]);
 }
 
 
diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
--- a/drivers/acpi/utilities/utmisc.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/acpi/utilities/utmisc.c	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: utmisc - common utility procedures
- *              $Revision: 75 $
+ *              $Revision: 78 $
  *
  ******************************************************************************/
 
@@ -27,6 +27,7 @@
 #include "acpi.h"
 #include "acnamesp.h"
 #include "amlcode.h"
+#include "acinterp.h"
 
 
 #define _COMPONENT          ACPI_UTILITIES
@@ -1100,119 +1101,6 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_ut_resolve_reference
- *
- * PARAMETERS:  ACPI_PKG_CALLBACK
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: Resolve a reference object to an actual value
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ut_resolve_reference (
-	u8                      object_type,
-	acpi_operand_object     *source_object,
-	acpi_generic_state      *state,
-	void                    *context)
-{
-	acpi_pkg_info           *info = (acpi_pkg_info *) context;
-
-
-	switch (object_type) {
-	case ACPI_COPY_TYPE_SIMPLE:
-
-		/*
-		 * Simple object - check for a reference
-		 */
-		if (source_object->common.type == INTERNAL_TYPE_REFERENCE) {
-			switch (source_object->reference.opcode) {
-			case AML_ZERO_OP:
-
-				source_object->common.type = ACPI_TYPE_INTEGER;
-				source_object->integer.value = 0;
-				break;
-
-			case AML_ONE_OP:
-
-				source_object->common.type = ACPI_TYPE_INTEGER;
-				source_object->integer.value = 1;
-				break;
-
-			case AML_ONES_OP:
-
-				source_object->common.type = ACPI_TYPE_INTEGER;
-				source_object->integer.value = ACPI_INTEGER_MAX;
-				break;
-
-			default:
-				/* Other types not supported */
-				return (AE_SUPPORT);
-			}
-		}
-		break;
-
-
-	case ACPI_COPY_TYPE_PACKAGE:
-
-		/* Package object - nothing much to do here, let the walk handle it */
-
-		info->num_packages++;
-		state->pkg.this_target_obj = NULL;
-		break;
-
-	default:
-		return (AE_BAD_PARAMETER);
-	}
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ut_resolve_package_references
- *
- * PARAMETERS:  Obj_desc        - The Package object on which to resolve refs
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Walk through a package and turn internal references into values
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ut_resolve_package_references (
-	acpi_operand_object     *obj_desc)
-{
-	acpi_pkg_info           info;
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_TRACE ("Ut_resolve_package_references");
-
-
-	if (obj_desc->common.type != ACPI_TYPE_PACKAGE) {
-		/* The object must be a package */
-
-		ACPI_REPORT_ERROR (("Expecting a Package object\n"));
-		return_ACPI_STATUS (AE_TYPE);
-	}
-
-	info.length      = 0;
-	info.object_space = 0;
-	info.num_packages = 1;
-
-	status = acpi_ut_walk_package_tree (obj_desc, NULL,
-			 acpi_ut_resolve_reference, &info);
-
-	return_ACPI_STATUS (status);
-}
-
-
-/*******************************************************************************
- *
  * FUNCTION:    Acpi_ut_walk_package_tree
  *
  * PARAMETERS:  Obj_desc        - The Package object on which to resolve refs
@@ -1260,7 +1148,7 @@
 		 */
 		if ((!this_source_obj) ||
 			(ACPI_GET_DESCRIPTOR_TYPE (this_source_obj) != ACPI_DESC_TYPE_OPERAND) ||
-			(this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
+			(ACPI_GET_OBJECT_TYPE (this_source_obj) != ACPI_TYPE_PACKAGE)) {
 			status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
 					 state, context);
 			if (ACPI_FAILURE (status)) {
diff -Nru a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
--- a/drivers/acpi/utilities/utobject.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/acpi/utilities/utobject.c	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: utobject - ACPI object create/delete/size/cache routines
- *              $Revision: 73 $
+ *              $Revision: 76 $
  *
  *****************************************************************************/
 
@@ -37,10 +37,9 @@
  *
  * FUNCTION:    Acpi_ut_create_internal_object_dbg
  *
- * PARAMETERS:  Address             - Address of the memory to deallocate
- *              Component           - Component type of caller
- *              Module              - Source file name of caller
- *              Line                - Line number of caller
+ * PARAMETERS:  Module_name         - Source file name of caller
+ *              Line_number         - Line number of caller
+ *              Component_id        - Component type of caller
  *              Type                - ACPI Type of the new object
  *
  * RETURN:      Object              - The new object.  Null on failure
@@ -119,7 +118,7 @@
  *
  * FUNCTION:    Acpi_ut_valid_internal_object
  *
- * PARAMETERS:  Operand             - Object to be validated
+ * PARAMETERS:  Object              - Object to be validated
  *
  * RETURN:      Validate a pointer to be an acpi_operand_object
  *
@@ -180,7 +179,6 @@
  * PARAMETERS:  Module_name         - Caller's module name (for error output)
  *              Line_number         - Caller's line number (for error output)
  *              Component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
  *
  * RETURN:      Pointer to newly allocated object descriptor.  Null on error
  *
@@ -209,7 +207,6 @@
 		return_PTR (NULL);
 	}
 
-
 	/* Mark the descriptor type */
 
 	ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND);
@@ -225,7 +222,7 @@
  *
  * FUNCTION:    Acpi_ut_delete_object_desc
  *
- * PARAMETERS:  Object          - Acpi internal object to be deleted
+ * PARAMETERS:  Object          - An Acpi internal object to be deleted
  *
  * RETURN:      None.
  *
@@ -260,7 +257,7 @@
  *
  * PARAMETERS:  None
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Purge the global state object cache.  Used during subsystem
  *              termination.
@@ -284,12 +281,12 @@
  * FUNCTION:    Acpi_ut_get_simple_object_size
  *
  * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
- *              *Ret_length         - Where the length is returned
+ *              *Obj_length         - Where the length is returned
  *
  * RETURN:      Status
  *
  * DESCRIPTION: This function is called to determine the space required to
- *              contain a simple object for return to an API user.
+ *              contain a simple object for return to an external user.
  *
  *              The length includes the object structure plus any additional
  *              needed space.
@@ -315,7 +312,6 @@
 		return_ACPI_STATUS (AE_OK);
 	}
 
-
 	/* Start with the length of the Acpi object */
 
 	length = sizeof (acpi_object);
@@ -327,16 +323,13 @@
 		return_ACPI_STATUS (status);
 	}
 
-
 	/*
 	 * The final length depends on the object type
 	 * Strings and Buffers are packed right up against the parent object and
 	 * must be accessed bytewise or there may be alignment problems on
 	 * certain processors
 	 */
-
-	switch (internal_object->common.type) {
-
+	switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
 	case ACPI_TYPE_STRING:
 
 		length += (ACPI_SIZE) internal_object->string.length + 1;
@@ -362,15 +355,6 @@
 	case INTERNAL_TYPE_REFERENCE:
 
 		switch (internal_object->reference.opcode) {
-		case AML_ZERO_OP:
-		case AML_ONE_OP:
-		case AML_ONES_OP:
-		case AML_REVISION_OP:
-
-			/* These Constant opcodes will be resolved to Integers */
-
-			break;
-
 		case AML_INT_NAMEPATH_OP:
 
 			/*
@@ -384,7 +368,7 @@
 
 			/*
 			 * No other reference opcodes are supported.
-			 * Notably, Locals and Args are not supported, by this may be
+			 * Notably, Locals and Args are not supported, but this may be
 			 * required eventually.
 			 */
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -399,12 +383,11 @@
 	default:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n",
-			internal_object->common.type, internal_object));
+			ACPI_GET_OBJECT_TYPE (internal_object), internal_object));
 		status = AE_TYPE;
 		break;
 	}
 
-
 	/*
 	 * Account for the space required by the object rounded up to the next
 	 * multiple of the machine word size.  This keeps each object aligned
@@ -422,7 +405,7 @@
  *
  * PARAMETERS:  ACPI_PKG_CALLBACK
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: Get the length of one package element.
  *
@@ -481,12 +464,12 @@
  * FUNCTION:    Acpi_ut_get_package_object_size
  *
  * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
- *              *Ret_length         - Where the length is returned
+ *              *Obj_length         - Where the length is returned
  *
  * RETURN:      Status
  *
  * DESCRIPTION: This function is called to determine the space required to
- *              contain a package object for return to an API user.
+ *              contain a package object for return to an external user.
  *
  *              This is moderately complex since a package contains other
  *              objects including packages.
@@ -535,7 +518,7 @@
  * FUNCTION:    Acpi_ut_get_object_size
  *
  * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
- *              *Ret_length         - Where the length will be returned
+ *              *Obj_length         - Where the length will be returned
  *
  * RETURN:      Status
  *
@@ -556,7 +539,7 @@
 
 
 	if ((ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_OPERAND) &&
-		(internal_object->common.type == ACPI_TYPE_PACKAGE)) {
+		(ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE)) {
 		status = acpi_ut_get_package_object_size (internal_object, obj_length);
 	}
 	else {
diff -Nru a/drivers/acpi/utils.c b/drivers/acpi/utils.c
--- a/drivers/acpi/utils.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/acpi/utils.c	Sun Jun 16 19:31:41 2002
@@ -1,5 +1,5 @@
 /*
- *  acpi_utils.c - ACPI Utility Functions ($Revision: 5 $)
+ *  acpi_utils.c - ACPI Utility Functions ($Revision: 7 $)
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -425,24 +425,16 @@
 
 		element = &(package->package.elements[i]);
 
-		if (!element || (element->type != ACPI_TYPE_STRING)) {
+		if (!element || (element->type != ACPI_TYPE_ANY)) {
 			status = AE_BAD_DATA;
 			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid element in package (not a device reference)\n"));
 			acpi_util_eval_error(handle, pathname, status);
 			break;
 		}
 
-		/* Convert reference (e.g. "\_PR_.CPU_") to acpi_handle. */
-
-		status = acpi_get_handle(handle, element->string.pointer,
-			&(list->handles[i]));
-		if (ACPI_FAILURE(status)) {
-			status = AE_BAD_DATA;
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference [%s]\n", element->string.pointer));
-			acpi_util_eval_error(handle, pathname, status);
-			break;
-		}
+		/* Get the  acpi_handle. */
 
+		list->handles[i] = element->reference.handle;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resolved reference [%s]->[%p]\n", element->string.pointer, list->handles[i]));
 	}
 
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/block/DAC960.c	Sun Jun 16 19:31:41 2002
@@ -2404,8 +2404,12 @@
 	    DAC960_V1_QueueReadWriteCommand;
 	  break;
 	case DAC960_PD_Controller:
-	  request_region(Controller->IO_Address, 0x80,
-			 Controller->FullModelName);
+	  if (!request_region(Controller->IO_Address, 0x80,
+			      Controller->FullModelName)) {
+		DAC960_Error("IO port 0x%d busy for Controller at\n",
+			     Controller, Controller->IO_Address);
+		goto Failure;
+	  }
 	  DAC960_PD_DisableInterrupts(BaseAddress);
 	  DAC960_PD_AcknowledgeStatus(BaseAddress);
 	  udelay(1000);
@@ -2415,7 +2419,7 @@
 					    &Parameter0, &Parameter1) &&
 		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
 					   Parameter0, Parameter1))
-		goto Failure;
+		goto Failure1;
 	      udelay(10);
 	    }
 	  DAC960_PD_EnableInterrupts(Controller->BaseAddress);
@@ -2430,8 +2434,12 @@
 	    DAC960_V1_QueueReadWriteCommand;
 	  break;
 	case DAC960_P_Controller:
-	  request_region(Controller->IO_Address, 0x80,
-			 Controller->FullModelName);
+	  if (!request_region(Controller->IO_Address, 0x80,
+			      Controller->FullModelName)){
+		DAC960_Error("IO port 0x%d busy for Controller at\n",
+		   	     Controller, Controller->IO_Address);
+		goto Failure;
+	  }
 	  DAC960_PD_DisableInterrupts(BaseAddress);
 	  DAC960_PD_AcknowledgeStatus(BaseAddress);
 	  udelay(1000);
@@ -2441,7 +2449,7 @@
 					    &Parameter0, &Parameter1) &&
 		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
 					   Parameter0, Parameter1))
-		goto Failure;
+		goto Failure1;
 	      udelay(10);
 	    }
 	  DAC960_PD_EnableInterrupts(Controller->BaseAddress);
@@ -2463,7 +2471,7 @@
 	{
 	  DAC960_Error("IRQ Channel %d illegal for Controller at\n",
 		       Controller, IRQ_Channel);
-	  goto Failure;
+	  goto Failure1;
 	}
       strcpy(Controller->FullModelName, "DAC960");
       if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
@@ -2471,7 +2479,7 @@
 	{
 	  DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
 		       Controller, IRQ_Channel);
-	  goto Failure;
+	  goto Failure1;
 	}
       Controller->IRQ_Channel = IRQ_Channel;
       DAC960_ActiveControllerCount++;
@@ -2481,6 +2489,8 @@
       Controller->FreeCommands = &Controller->InitialCommand;
       Controller->ControllerDetectionSuccessful = true;
       continue;
+    Failure1:
+      if (Controller->IO_Address) release_region(Controller->IO_Address, 0x80);
     Failure:
       if (IO_Address == 0)
 	DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
diff -Nru a/drivers/block/acsi.c b/drivers/block/acsi.c
--- a/drivers/block/acsi.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/acsi.c	Sun Jun 16 19:31:40 2002
@@ -44,6 +44,8 @@
  */
 
 #define MAJOR_NR ACSI_MAJOR
+#define DEVICE_NAME "ACSI"
+#define DEVICE_NR(device) (minor(device) >> 4)
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -77,6 +79,7 @@
 #include <asm/atari_stdma.h>
 #include <asm/atari_stram.h>
 
+static void (*do_acsi)(void) = NULL;
 
 #define DEBUG
 #undef DEBUG_DETECT
@@ -735,9 +738,9 @@
 
 static void acsi_interrupt(int irq, void *data, struct pt_regs *fp )
 
-{	void (*acsi_irq_handler)(void) = DEVICE_INTR;
+{	void (*acsi_irq_handler)(void) = do_acsi;
 
-	DEVICE_INTR = NULL;
+	do_acsi = NULL;
 	CLEAR_TIMER();
 
 	if (!acsi_irq_handler)
@@ -772,7 +775,7 @@
 		return;
 
 	if (++CURRENT->errors >= MAX_ERRORS)
-		end_request(0);
+		end_request(CURRENT, 0);
 	/* Otherwise just retry */
 }
 
@@ -838,9 +841,9 @@
 
 {
 	DISABLE_IRQ();
-	if (!DEVICE_INTR) return;
+	if (!do_acsi) return;
 
-	DEVICE_INTR = NULL;
+	do_acsi = NULL;
 	printk( KERN_ERR "ACSI timeout\n" );
 	if (blk_queue_empty(QUEUE))
 	    return;
@@ -848,7 +851,7 @@
 #ifdef DEBUG
 		printk( KERN_ERR "ACSI: too many errors.\n" );
 #endif
-		end_request(0);
+		end_request(CURRENT, 0);
 	}
 
 	redo_acsi_request();
@@ -916,7 +919,7 @@
 		CURRENT->current_nr_sectors -= CurrentNSect;
 		CURRENT->sector += CurrentNSect;
 		if (CURRENT->nr_sectors == 0)
-			end_request(1);
+			end_request(CURRENT, 1);
 	}
 	else {
 		for( i = 0; i < CurrentNReq; ++i ) {
@@ -924,7 +927,7 @@
 			CURRENT->nr_sectors -= n;
 			CURRENT->current_nr_sectors -= n;
 			CURRENT->sector += n;
-			end_request(1);
+			end_request(CURRENT, 1);
 		}
 	}
 }
@@ -956,11 +959,11 @@
   repeat:
 	CLEAR_TIMER();
 
-	if (DEVICE_INTR)
+	if (do_acsi)
 		return;
 
 	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+		do_acsi = NULL;
 		ENABLE_IRQ();
 		stdma_release();
 		return;
@@ -983,13 +986,13 @@
 		       block, block + CURRENT->nr_sectors - 1,
 		       acsi_part[dev].nr_sects);
 #endif
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 	if (acsi_info[DEVICE_NR(dev)].changed) {
 		printk( KERN_NOTICE "ad%c: request denied because cartridge has "
 				"been changed.\n", DEVICE_NR(dev)+'a' );
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 	
@@ -1049,9 +1052,9 @@
 		if (buffer == acsi_buffer)
 			copy_to_acsibuffer();
 		dma_cache_maintenance( pbuffer, nsect*512, 1 );
-		DEVICE_INTR = write_intr;
+		do_acsi = write_intr;
 		if (!acsicmd_dma( write_cmd, buffer, nsect, 1, 1)) {
-			CLEAR_INTR;
+			do_acsi = NULL;
 			printk( KERN_ERR "ACSI (write): Timeout in command block\n" );
 			bad_rw_intr();
 			goto repeat;
@@ -1063,9 +1066,9 @@
 		CMDSET_TARG_LUN( read_cmd, target, lun );
 		CMDSET_BLOCK( read_cmd, block );
 		CMDSET_LEN( read_cmd, nsect );
-		DEVICE_INTR = read_intr;
+		do_acsi = read_intr;
 		if (!acsicmd_dma( read_cmd, buffer, nsect, 0, 1)) {
-			CLEAR_INTR;
+			do_acsi = NULL;
 			printk( KERN_ERR "ACSI (read): Timeout in command block\n" );
 			bad_rw_intr();
 			goto repeat;
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/amiflop.c	Sun Jun 16 19:31:40 2002
@@ -79,6 +79,8 @@
 #include <asm/irq.h>
 
 #define MAJOR_NR FLOPPY_MAJOR
+#define DEVICE_NAME "floppy"
+#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
 #include <linux/blk.h>
 
 #undef DEBUG /* print _LOTS_ of infos */
@@ -1405,7 +1407,7 @@
 #endif
 		block = CURRENT->sector + cnt;
 		if ((int)block > floppy->blocks) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			goto repeat;
 		}
 
@@ -1419,11 +1421,11 @@
 
 		if ((rq_data_dir(CURRENT) != READ) && (rq_data_dir(CURRENT) != WRITE)) {
 			printk(KERN_WARNING "do_fd_request: unknown command\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			goto repeat;
 		}
 		if (get_track(drive, track) == -1) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			goto repeat;
 		}
 
@@ -1437,7 +1439,7 @@
 
 			/* keep the drive spinning while writes are scheduled */
 			if (!fd_motor_on(drive)) {
-				end_request(0);
+				end_request(CURRENT, 0);
 				goto repeat;
 			}
 			/*
@@ -1460,7 +1462,7 @@
 	CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
 	CURRENT->sector += CURRENT->current_nr_sectors;
 
-	end_request(1);
+	end_request(CURRENT, 1);
 	goto repeat;
 }
 
diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c
--- a/drivers/block/ataflop.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/ataflop.c	Sun Jun 16 19:31:39 2002
@@ -92,6 +92,8 @@
 #include <asm/atari_stram.h>
 
 #define MAJOR_NR FLOPPY_MAJOR
+#define DEVICE_NAME "floppy"
+#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 
@@ -632,7 +634,7 @@
 	CURRENT->errors++;
 	if (CURRENT->errors >= MAX_ERRORS) {
 		printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive );
-		end_request( 0 );
+		end_request(CURRENT, 0);
 	}
 	else if (CURRENT->errors == RECALIBRATE_ERRORS) {
 		printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive );
@@ -757,7 +759,7 @@
 			/* all sectors finished */
 			CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
 			CURRENT->sector += CURRENT->current_nr_sectors;
-			end_request( 1 );
+			end_request(CURRENT, 1);
 			redo_fd_request();
 			return;
 		    }
@@ -1164,7 +1166,7 @@
 		/* all sectors finished */
 		CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
 		CURRENT->sector += CURRENT->current_nr_sectors;
-		end_request( 1 );
+		end_request(CURRENT, 1);
 		redo_fd_request();
 	}
 	return;
@@ -1466,7 +1468,7 @@
 	if (!UD.connected) {
 		/* drive not connected */
 		printk(KERN_ERR "Unknown Device: fd%d\n", drive );
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 		
@@ -1482,12 +1484,12 @@
 		/* user supplied disk type */
 		if (--type >= NUM_DISK_MINORS) {
 			printk(KERN_WARNING "fd%d: invalid disk format", drive );
-			end_request( 0 );
+			end_request(CURRENT, 0);
 			goto repeat;
 		}
 		if (minor2disktype[type].drive_types > DriveType)  {
 			printk(KERN_WARNING "fd%d: unsupported disk format", drive );
-			end_request( 0 );
+			end_request(CURRENT, 0);
 			goto repeat;
 		}
 		type = minor2disktype[type].index;
@@ -1497,7 +1499,7 @@
 	}
 	
 	if (CURRENT->sector + 1 > UDT->blocks) {
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 
diff -Nru a/drivers/block/blkpg.c b/drivers/block/blkpg.c
--- a/drivers/block/blkpg.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/blkpg.c	Sun Jun 16 19:31:39 2002
@@ -236,7 +236,7 @@
 			set_device_ro(dev, intval);
 			return 0;
 		case BLKROGET:
-			intval = (is_read_only(dev) != 0);
+			intval = (bdev_read_only(bdev) != 0);
 			return put_user(intval, (int *)(arg));
 
 		case BLKRASET:
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/cpqarray.c	Sun Jun 16 19:31:39 2002
@@ -53,6 +53,8 @@
 
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
 #define LOCAL_END_REQUEST
+#define DEVICE_NAME "ida"
+#define DEVICE_NR(device) (minor(device) >> 4)
 #include <linux/blk.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/floppy.c	Sun Jun 16 19:31:39 2002
@@ -240,6 +240,8 @@
 
 #define LOCAL_END_REQUEST
 #define MAJOR_NR FLOPPY_MAJOR
+#define DEVICE_NAME "floppy"
+#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
 
 #include <linux/blk.h>
 #include <linux/blkpg.h>
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/genhd.c	Sun Jun 16 19:31:40 2002
@@ -177,9 +177,10 @@
 	if (sgp == gendisk_head)
 		seq_puts(part, "major minor  #blocks  name\n\n");
 
-	/* show all non-0 size partitions of this disk */
+	/* show the full disk and all non-0 size partitions of it */
 	for (n = 0; n < (sgp->nr_real << sgp->minor_shift); n++) {
-		if (sgp->part[n].nr_sects == 0)
+		int minormask = (1<<sgp->minor_shift) - 1;
+		if ((n & minormask) && sgp->part[n].nr_sects == 0)
 			continue;
 		seq_printf(part, "%4d  %4d %10d %s\n",
 			sgp->major, n, sgp->sizes[n],
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/ll_rw_blk.c	Sun Jun 16 19:31:39 2002
@@ -49,6 +49,9 @@
  */
 static kmem_cache_t *request_cachep;
 
+/*
+ * plug management
+ */
 static struct list_head blk_plug_list;
 static spinlock_t blk_plug_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 
@@ -297,6 +300,27 @@
 }
 
 /**
+ * blk_queue_find_tag - find a request by its tag and queue
+ *
+ * @q:	 The request queue for the device
+ * @tag: The tag of the request
+ *
+ * Notes:
+ *    Should be used when a device returns a tag and you want to match
+ *    it with a request.
+ *
+ *    no locks need be held.
+ **/
+struct request *blk_queue_find_tag(request_queue_t *q, int tag)
+{
+	struct blk_queue_tag *bqt = q->queue_tags;
+
+	if(unlikely(bqt == NULL || bqt->max_depth < tag))
+		return NULL;
+
+	return bqt->tag_index[tag];
+}
+/**
  * blk_queue_free_tags - release tag maintenance info
  * @q:  the request queue for the device
  *
@@ -429,10 +453,12 @@
  *  Description:
  *    This can either be used as a stand-alone helper, or possibly be
  *    assigned as the queue &prep_rq_fn (in which case &struct request
- *    automagically gets a tag assigned). Note that this function assumes
- *    that only REQ_CMD requests can be queued! The request will also be
- *    removed from the request queue, so it's the drivers responsibility to
- *    readd it if it should need to be restarted for some reason.
+ *    automagically gets a tag assigned). Note that this function
+ *    assumes that any type of request can be queued! if this is not
+ *    true for your device, you must check the request type before
+ *    calling this function.  The request will also be removed from
+ *    the request queue, so it's the drivers responsibility to readd
+ *    it if it should need to be restarted for some reason.
  *
  *  Notes:
  *   queue lock must be held.
@@ -443,8 +469,12 @@
 	unsigned long *map = bqt->tag_map;
 	int tag = 0;
 
-	if (unlikely(!(rq->flags & REQ_CMD)))
-		return 1;
+	if (unlikely((rq->flags & REQ_QUEUED))) {
+		printk(KERN_ERR 
+		       "request %p for device [02%x:02%x] already tagged %d",
+		       rq, major(rq->rq_dev), minor(rq->rq_dev), rq->tag);
+		BUG();
+	}
 
 	for (map = bqt->tag_map; *map == -1UL; map++) {
 		tag += BLK_TAGS_PER_LONG;
@@ -794,18 +824,12 @@
  * force the transfer to start only after we have put all the requests
  * on the list.
  *
- * This is called with interrupts off and no requests on the queue.
- * (and with the request spinlock acquired)
+ * This is called with interrupts off and no requests on the queue and
+ * with the queue lock held.
  */
 void blk_plug_device(request_queue_t *q)
 {
-	/*
-	 * common case
-	 */
-	if (!elv_queue_empty(q))
-		return;
-
-	if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) {
+	if (!blk_queue_plugged(q)) {
 		spin_lock(&blk_plug_lock);
 		list_add_tail(&q->plug_list, &blk_plug_list);
 		spin_unlock(&blk_plug_lock);
@@ -813,14 +837,27 @@
 }
 
 /*
+ * remove the queue from the plugged list, if present. called with
+ * queue lock held and interrupts disabled.
+ */
+inline int blk_remove_plug(request_queue_t *q)
+{
+	if (blk_queue_plugged(q)) {
+		spin_lock(&blk_plug_lock);
+		list_del_init(&q->plug_list);
+		spin_unlock(&blk_plug_lock);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
  * remove the plug and let it rip..
  */
 static inline void __generic_unplug_device(request_queue_t *q)
 {
-	/*
-	 * not plugged
-	 */
-	if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
+	if (!blk_remove_plug(q))
 		return;
 
 	if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
@@ -848,11 +885,10 @@
 void generic_unplug_device(void *data)
 {
 	request_queue_t *q = data;
-	unsigned long flags;
 
-	spin_lock_irqsave(q->queue_lock, flags);
+	spin_lock_irq(q->queue_lock);
 	__generic_unplug_device(q);
-	spin_unlock_irqrestore(q->queue_lock, flags);
+	spin_unlock_irq(q->queue_lock);
 }
 
 /**
@@ -895,17 +931,9 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(q->queue_lock, flags);
-
-	/*
-	 * remove from the plugged list, queue must not be called.
-	 */
-	if (test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) {
-		spin_lock(&blk_plug_lock);
-		list_del(&q->plug_list);
-		spin_unlock(&blk_plug_lock);
-	}
-
+	blk_remove_plug(q);
 	spin_unlock_irqrestore(q->queue_lock, flags);
+
 	set_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
 }
 
@@ -941,12 +969,7 @@
 	while (!list_empty(&local_plug_list)) {
 		request_queue_t *q = blk_plug_entry(local_plug_list.next);
 
-		BUG_ON(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags));
-
-		spin_lock_irq(q->queue_lock);
-		list_del(&q->plug_list);
-		__generic_unplug_device(q);
-		spin_unlock_irq(q->queue_lock);
+		q->unplug_fn(q);
 	}
 }
 
@@ -1089,6 +1112,7 @@
 	q->front_merge_fn      	= ll_front_merge_fn;
 	q->merge_requests_fn	= ll_merge_requests_fn;
 	q->prep_rq_fn		= NULL;
+	q->unplug_fn		= generic_unplug_device;
 	q->queue_flags		= (1 << QUEUE_FLAG_CLUSTER);
 	q->queue_lock		= lock;
 
@@ -1196,6 +1220,11 @@
 	return ro_bits[major][minor >> 5] & (1 << (minor & 31));
 }
 
+int bdev_read_only(struct block_device *bdev)
+{
+	return bdev && is_read_only(to_kdev_t(bdev->bd_dev));
+}
+
 void set_device_ro(kdev_t dev,int flag)
 {
 	int minor,major;
@@ -1381,10 +1410,12 @@
 	req = NULL;
 	insert_here = q->queue_head.prev;
 
-	if (blk_queue_empty(q) || barrier) {
+	if (blk_queue_empty(q)) {
 		blk_plug_device(q);
 		goto get_rq;
 	}
+	if (barrier)
+		goto get_rq;
 
 	el_ret = elv_merge(q, &req, bio);
 	switch (el_ret) {
@@ -1573,7 +1604,7 @@
 			printk(KERN_INFO
 			       "attempt to access beyond end of device\n");
 			printk(KERN_INFO "%s: rw=%ld, want=%ld, limit=%Lu\n",
-			       kdevname(to_kdev_t(bio->bi_bdev->bd_dev)),
+			       bdevname(bio->bi_bdev),
 			       bio->bi_rw,
 			       sector + nr_sectors,
 			       (long long) maxsector);
@@ -1596,7 +1627,7 @@
 		if (!q) {
 			printk(KERN_ERR
 			       "generic_make_request: Trying to access nonexistent block-device %s (%Lu)\n",
-			       kdevname(to_kdev_t(bio->bi_bdev->bd_dev)),
+			       bdevname(bio->bi_bdev),
 			       (long long) bio->bi_sector);
 end_io:
 			bio->bi_end_io(bio);
@@ -1765,7 +1796,7 @@
 		}
 	}
 
-	if ((rw & WRITE) && is_read_only(to_kdev_t(bhs[0]->b_bdev->bd_dev))) {
+	if ((rw & WRITE) && bdev_read_only(bhs[0]->b_bdev)) {
 		printk(KERN_NOTICE "Can't write to read-only device %s\n",
 		       bdevname(bhs[0]->b_bdev));
 		goto sorry;
@@ -2006,6 +2037,8 @@
 EXPORT_SYMBOL(generic_make_request);
 EXPORT_SYMBOL(blkdev_release_request);
 EXPORT_SYMBOL(generic_unplug_device);
+EXPORT_SYMBOL(blk_plug_device);
+EXPORT_SYMBOL(blk_remove_plug);
 EXPORT_SYMBOL(blk_attempt_remerge);
 EXPORT_SYMBOL(blk_max_low_pfn);
 EXPORT_SYMBOL(blk_max_pfn);
@@ -2027,6 +2060,7 @@
 
 EXPORT_SYMBOL(blk_queue_prep_rq);
 
+EXPORT_SYMBOL(blk_queue_find_tag);
 EXPORT_SYMBOL(blk_queue_init_tags);
 EXPORT_SYMBOL(blk_queue_free_tags);
 EXPORT_SYMBOL(blk_queue_start_tag);
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/loop.c	Sun Jun 16 19:31:39 2002
@@ -679,7 +679,7 @@
 
 	get_file(file);
 
-	if (IS_RDONLY (inode) || is_read_only(to_kdev_t(lo_device->bd_dev))
+	if (IS_RDONLY (inode) || bdev_read_only(lo_device)
 	    || !(lo_file->f_mode & FMODE_WRITE))
 		lo_flags |= LO_FLAGS_READ_ONLY;
 
@@ -826,17 +826,22 @@
 
 static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
 {
-	struct loop_info	info;
 	struct file *file = lo->lo_backing_file;
+	struct loop_info info;
+	struct kstat stat;
+	int error;
 
 	if (lo->lo_state != Lo_bound)
 		return -ENXIO;
 	if (!arg)
 		return -EINVAL;
+	error = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
+	if (error)
+		return error;
 	memset(&info, 0, sizeof(info));
 	info.lo_number = lo->lo_number;
-	info.lo_device = kdev_t_to_nr(file->f_dentry->d_inode->i_dev);
-	info.lo_inode = file->f_dentry->d_inode->i_ino;
+	info.lo_device = stat.dev;
+	info.lo_inode = stat.ino;
 	info.lo_rdevice = lo->lo_device->bd_dev;
 	info.lo_offset = lo->lo_offset;
 	info.lo_flags = lo->lo_flags;
diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c
--- a/drivers/block/nbd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/nbd.c	Sun Jun 16 19:31:39 2002
@@ -51,6 +51,7 @@
 #include <asm/types.h>
 
 #define MAJOR_NR NBD_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/nbd.h>
 
 #define LO_MAGIC 0x68797548
diff -Nru a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
--- a/drivers/block/paride/pcd.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/paride/pcd.c	Sun Jun 16 19:31:40 2002
@@ -180,7 +180,6 @@
 /* set up defines for blk.h,  why don't all drivers do it this way ? */
 
 #define MAJOR_NR	major
-#define DEVICE_NAME "PCD"
 #define DEVICE_NR(device) (minor(device))
 #define DEVICE_OFF(device)
 
@@ -329,8 +328,8 @@
 }
 
 int pcd_init (void)	/* preliminary initialisation */
-
-{       int 	i, unit;
+{
+	int unit;
 
 	if (disable) return -1;
 
@@ -760,10 +759,8 @@
 
 	if (pcd_busy) return;
         while (1) {
-	    if (blk_queue_empty(QUEUE)) {
-		    CLEAR_INTR;
+	    if (blk_queue_empty(QUEUE))
 		    return;
-	    }
 
 	    if (rq_data_dir(CURRENT) == READ) {
 		unit = minor(CURRENT->rq_dev);
@@ -778,7 +775,7 @@
 	        ps_set_intr(do_pcd_read,0,0,nice); 
 		return;
 	    } 
-	    else end_request(0);
+	    else end_request(CURRENT, 0);
 	}
 }
 
@@ -820,7 +817,7 @@
 		pcd_bufblk = -1; 
 		spin_lock_irqsave(&pcd_lock,saved_flags);
 		pcd_busy = 0;
-		end_request(0);
+		end_request(CURRENT, 0);
 		do_pcd_request(NULL);
 		spin_unlock_irqrestore(&pcd_lock,saved_flags);
 		return;
@@ -843,7 +840,7 @@
 	pcd_transfer();
 	if (!pcd_count) {
 		spin_lock_irqsave(&pcd_lock,saved_flags);
-		end_request(1);
+		end_request(CURRENT, 1);
 		pcd_busy = 0;
 		do_pcd_request(NULL);
 		spin_unlock_irqrestore(&pcd_lock,saved_flags);
@@ -868,7 +865,7 @@
 		spin_lock_irqsave(&pcd_lock,saved_flags);
 		pcd_busy = 0;
 		pcd_bufblk = -1;
-		end_request(0);
+		end_request(CURRENT, 0);
 		do_pcd_request(NULL);
 		spin_unlock_irqrestore(&pcd_lock,saved_flags);
 		return;
diff -Nru a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
--- a/drivers/block/paride/pd.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/block/paride/pd.c	Sun Jun 16 19:31:41 2002
@@ -204,7 +204,6 @@
 /* set up defines for blk.h,  why don't all drivers do it this way ? */
 
 #define MAJOR_NR   major
-#define DEVICE_NAME "PD"
 #define DEVICE_NR(device) (minor(device)>>PD_BITS)
 #define DEVICE_OFF(device)
 
@@ -381,9 +380,8 @@
 }
 
 int pd_init (void)
-
-{       int i;
-	request_queue_t * q; 
+{
+	request_queue_t * q;
 
 	if (disable) return -1;
         if (devfs_register_blkdev(MAJOR_NR,name,&pd_fops)) {
@@ -835,10 +833,8 @@
 
         if (pd_busy) return;
 repeat:
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
         pd_dev = minor(CURRENT->rq_dev);
 	pd_unit = unit = DEVICE_NR(CURRENT->rq_dev);
@@ -848,7 +844,7 @@
 
         if ((pd_dev >= PD_DEVS) || 
 	    ((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) {
-                end_request(0);
+                end_request(CURRENT, 0);
                 goto repeat;
         }
 
@@ -860,7 +856,7 @@
         if (pd_cmd == READ) pi_do_claimed(PI,do_pd_read);
         else if (pd_cmd == WRITE) pi_do_claimed(PI,do_pd_write);
         else {  pd_busy = 0;
-		end_request(0);
+		end_request(CURRENT, 0);
                 goto repeat;
         }
 }
@@ -870,7 +866,7 @@
 {	long	saved_flags;
 
 	spin_lock_irqsave(&pd_lock,saved_flags);
-	end_request(1);
+	end_request(CURRENT, 1);
 	if (!pd_run) {  spin_unlock_irqrestore(&pd_lock,saved_flags);
 			return; 
 	}
@@ -910,7 +906,7 @@
 			return;
                 }
 		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pd_busy = 0;
 		do_pd_request(NULL);
 		spin_unlock_irqrestore(&pd_lock,saved_flags);
@@ -934,7 +930,7 @@
                         return;
                 }
 		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pd_busy = 0;
 		do_pd_request(NULL);
 		spin_unlock_irqrestore(&pd_lock,saved_flags);
@@ -949,7 +945,7 @@
         }
         pi_disconnect(PI);
 	spin_lock_irqsave(&pd_lock,saved_flags);
-        end_request(1);
+        end_request(CURRENT, 1);
         pd_busy = 0;
 	do_pd_request(NULL);
 	spin_unlock_irqrestore(&pd_lock,saved_flags);
@@ -976,7 +972,7 @@
                         return;
                 }
 		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pd_busy = 0;
 		do_pd_request(NULL);
 		spin_unlock_irqrestore(&pd_lock,saved_flags);
@@ -992,7 +988,7 @@
                         return;
                 }
 		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pd_busy = 0;
 		do_pd_request(NULL);
                 spin_unlock_irqrestore(&pd_lock,saved_flags);
@@ -1021,7 +1017,7 @@
                         return;
                 }
 		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pd_busy = 0;
 		do_pd_request(NULL);
 		spin_unlock_irqrestore(&pd_lock,saved_flags);
@@ -1029,7 +1025,7 @@
         }
         pi_disconnect(PI);
 	spin_lock_irqsave(&pd_lock,saved_flags);
-        end_request(1);
+        end_request(CURRENT, 1);
         pd_busy = 0;
 	do_pd_request(NULL);
 	spin_unlock_irqrestore(&pd_lock,saved_flags);
diff -Nru a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
--- a/drivers/block/paride/pf.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/paride/pf.c	Sun Jun 16 19:31:39 2002
@@ -200,7 +200,6 @@
 /* set up defines for blk.h,  why don't all drivers do it this way ? */
 
 #define MAJOR_NR   major
-#define DEVICE_NAME "PF"
 #define DEVICE_NR(device) minor(device)
 #define DEVICE_OFF(device)
 
@@ -841,10 +840,8 @@
 
         if (pf_busy) return;
 repeat:
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
         pf_unit = unit = DEVICE_NR(CURRENT->rq_dev);
         pf_block = CURRENT->sector;
@@ -852,7 +849,7 @@
         pf_count = CURRENT->current_nr_sectors;
 
         if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) {
-                end_request(0);
+                end_request(CURRENT, 0);
                 goto repeat;
         }
 
@@ -864,7 +861,7 @@
         if (pf_cmd == READ) pi_do_claimed(PI,do_pf_read);
         else if (pf_cmd == WRITE) pi_do_claimed(PI,do_pf_write);
         else {  pf_busy = 0;
-		end_request(0);
+		end_request(CURRENT, 0);
                 goto repeat;
         }
 }
@@ -874,7 +871,7 @@
 {	long	saved_flags;
 
 	spin_lock_irqsave(&pf_spin_lock,saved_flags);
-	end_request(1);
+	end_request(CURRENT, 1);
 	if (!pf_run) { spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
 		       return; 
 	}
@@ -915,7 +912,7 @@
 			return;
                 }
 		spin_lock_irqsave(&pf_spin_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pf_busy = 0;
 		do_pf_request(NULL);
 		spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
@@ -941,7 +938,7 @@
                         return;
                 }
 		spin_lock_irqsave(&pf_spin_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pf_busy = 0;
 		do_pf_request(NULL);
 		spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
@@ -956,7 +953,7 @@
         }
         pi_disconnect(PI);
 	spin_lock_irqsave(&pf_spin_lock,saved_flags); 
-        end_request(1);
+        end_request(CURRENT, 1);
         pf_busy = 0;
 	do_pf_request(NULL);
 	spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
@@ -982,7 +979,7 @@
 			return;
                 }
 		spin_lock_irqsave(&pf_spin_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pf_busy = 0;
 		do_pf_request(NULL);
 		spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
@@ -999,7 +996,7 @@
                         return;
                 }
 		spin_lock_irqsave(&pf_spin_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pf_busy = 0;
 		do_pf_request(NULL);
 		spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
@@ -1029,7 +1026,7 @@
                         return;
                 }
 		spin_lock_irqsave(&pf_spin_lock,saved_flags);
-                end_request(0);
+                end_request(CURRENT, 0);
                 pf_busy = 0;
 		do_pf_request(NULL);
 		spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
@@ -1037,7 +1034,7 @@
         }
         pi_disconnect(PI);
 	spin_lock_irqsave(&pf_spin_lock,saved_flags);
-        end_request(1);
+        end_request(CURRENT, 1);
         pf_busy = 0;
 	do_pf_request(NULL);
 	spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
diff -Nru a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
--- a/drivers/block/ps2esdi.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/ps2esdi.c	Sun Jun 16 19:31:39 2002
@@ -33,6 +33,8 @@
 #ifdef  CONFIG_BLK_DEV_PS2
 
 #define MAJOR_NR PS2ESDI_MAJOR
+#define DEVICE_NAME "PS/2 ESDI"
+#define DEVICE_NR(device) (minor(device) >> 6)
 
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -503,14 +505,12 @@
 
 	/* standard procedure to ensure that requests are really on the
 	   list + sanity checks.                     */
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
 	if (isa_virt_to_bus(CURRENT->buffer + CURRENT->current_nr_sectors * 512) > 16 * MB) {
 		printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
-		end_request(FAIL);
+		end_request(CURRENT, FAIL);
 	}			/* check for above 16Mb dmas */
 	else if ((DEVICE_NR(CURRENT->rq_dev) < ps2esdi_drives) &&
 	    (CURRENT->sector + CURRENT->current_nr_sectors <=
@@ -536,7 +536,7 @@
 			break;
 		default:
 			printk("%s: Unknown command\n", DEVICE_NAME);
-			end_request(FAIL);
+			end_request(CURRENT, FAIL);
 			break;
 		}		/* handle different commands */
 	}
@@ -544,7 +544,7 @@
 	else {
 		printk("Grrr. error. ps2esdi_drives: %d, %lu %lu\n", ps2esdi_drives,
 		       CURRENT->sector, ps2esdi[minor(CURRENT->rq_dev)].nr_sects);
-		end_request(FAIL);
+		end_request(CURRENT, FAIL);
 	}
 
 }				/* main strategy routine */
@@ -609,7 +609,7 @@
 	if (ps2esdi_out_cmd_blk(cmd_blk)) {
 		printk("%s: Controller failed\n", DEVICE_NAME);
 		if ((++CURRENT->errors) >= MAX_RETRIES)
-			end_request(FAIL);
+			end_request(CURRENT, FAIL);
 	}
 	/* check for failure to put out the command block */ 
 	else {
@@ -984,7 +984,7 @@
 	}
 	if(ending != -1) {
 		spin_lock_irqsave(&ps2esdi_lock, flags);
-		end_request(ending);
+		end_request(CURRENT, ending);
 		do_ps2esdi_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
 		spin_unlock_irqrestore(&ps2esdi_lock, flags);
 	}
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/rd.c	Sun Jun 16 19:31:40 2002
@@ -57,6 +57,7 @@
  * include/linux/major.h for now
  */
 #define MAJOR_NR RAMDISK_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 
@@ -357,7 +358,7 @@
 
 static int rd_open(struct inode * inode, struct file * filp)
 {
-	int unit = DEVICE_NR(inode->i_rdev);
+	int unit = minor(inode->i_rdev);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (unit == INITRD_MINOR) {
diff -Nru a/drivers/block/swim3.c b/drivers/block/swim3.c
--- a/drivers/block/swim3.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/swim3.c	Sun Jun 16 19:31:40 2002
@@ -33,6 +33,8 @@
 #include <asm/pmac_feature.h>
 
 #define MAJOR_NR	FLOPPY_MAJOR
+#define DEVICE_NAME "floppy"
+#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
 #include <linux/blk.h>
 #include <linux/devfs_fs_kernel.h>
 
@@ -327,15 +329,15 @@
 #endif
 
 		if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 		if (CURRENT->current_nr_sectors == 0) {
-			end_request(1);
+			end_request(CURRENT, 1);
 			continue;
 		}
 		if (fs->ejected) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 
@@ -343,7 +345,7 @@
 			if (fs->write_prot < 0)
 				fs->write_prot = swim3_readbit(fs, WRITE_PROT);
 			if (fs->write_prot) {
-				end_request(0);
+				end_request(CURRENT, 0);
 				continue;
 			}
 		}
@@ -514,7 +516,7 @@
 		case do_transfer:
 			if (fs->cur_cyl != fs->req_cyl) {
 				if (fs->retries > 5) {
-					end_request(0);
+					end_request(CURRENT, 0);
 					fs->state = idle;
 					return;
 				}
@@ -546,7 +548,7 @@
 	out_8(&sw->intr_enable, 0);
 	fs->cur_cyl = -1;
 	if (fs->retries > 5) {
-		end_request(0);
+		end_request(CURRENT, 0);
 		fs->state = idle;
 		start_request(fs);
 	} else {
@@ -575,7 +577,7 @@
 		return;
 	}
 	printk(KERN_ERR "swim3: seek timeout\n");
-	end_request(0);
+	end_request(CURRENT, 0);
 	fs->state = idle;
 	start_request(fs);
 }
@@ -603,7 +605,7 @@
 	CURRENT->current_nr_sectors -= s;
 	printk(KERN_ERR "swim3: timeout %sing sector %ld\n",
 	       (rq_data_dir(CURRENT)==WRITE? "writ": "read"), CURRENT->sector);
-	end_request(0);
+	end_request(CURRENT, 0);
 	fs->state = idle;
 	start_request(fs);
 }
@@ -637,7 +639,7 @@
 				printk(KERN_ERR "swim3: seen sector but cyl=ff?\n");
 				fs->cur_cyl = -1;
 				if (fs->retries > 5) {
-					end_request(0);
+					end_request(CURRENT, 0);
 					fs->state = idle;
 					start_request(fs);
 				} else {
@@ -708,7 +710,7 @@
 				printk("swim3: error %sing block %ld (err=%x)\n",
 				       rq_data_dir(CURRENT) == WRITE? "writ": "read",
 				       CURRENT->sector, err);
-				end_request(0);
+				end_request(CURRENT, 0);
 				fs->state = idle;
 			}
 		} else {
@@ -717,7 +719,7 @@
 				printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid);
 				printk(KERN_ERR "  state=%d, dir=%lx, intr=%x, err=%x\n",
 				       fs->state, rq_data_dir(CURRENT), intr, err);
-				end_request(0);
+				end_request(CURRENT, 0);
 				fs->state = idle;
 				start_request(fs);
 				break;
@@ -726,7 +728,7 @@
 			CURRENT->current_nr_sectors -= fs->scount;
 			CURRENT->buffer += fs->scount * 512;
 			if (CURRENT->current_nr_sectors <= 0) {
-				end_request(1);
+				end_request(CURRENT, 1);
 				fs->state = idle;
 			} else {
 				fs->req_sector += fs->scount;
diff -Nru a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
--- a/drivers/block/swim_iop.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/block/swim_iop.c	Sun Jun 16 19:31:39 2002
@@ -27,6 +27,8 @@
 /* This has to be defined before some of the #includes below */
 
 #define MAJOR_NR  FLOPPY_MAJOR
+#define DEVICE_NAME "floppy"
+#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
 
 #include <linux/stddef.h>
 #include <linux/kernel.h>
@@ -98,7 +100,7 @@
 
 int swimiop_init(void);
 static void swimiop_init_request(struct swim_iop_req *);
-static int swimiop_send_request(struct swim_iop_req *);
+static int swimiop_send_request(CURRENT, struct swim_iop_req *);
 static void swimiop_receive(struct iop_msg *, struct pt_regs *);
 static void swimiop_status_update(int, struct swim_drvstatus *);
 static int swimiop_eject(struct floppy_state *fs);
@@ -169,7 +171,7 @@
 		swimiop_init_request(&req);
 		cmd->code = CMD_STATUS;
 		cmd->drive_num = i + 1;
-		if (swimiop_send_request(&req) != 0) continue;
+		if (swimiop_send_request(CURRENT, &req) != 0) continue;
 		while (!req.complete);
 		if (cmd->error != 0) {
 			printk(KERN_ERR "SWIM-IOP: probe on drive %d returned error %d\n", i, (uint) cmd->error);
@@ -202,7 +204,7 @@
 	req->done = NULL;
 }
 
-static int swimiop_send_request(struct swim_iop_req *req)
+static int swimiop_send_request(CURRENT, struct swim_iop_req *req)
 {
 	unsigned long cpu_flags;
 	int err;
@@ -317,7 +319,7 @@
 	swimiop_init_request(&req);
 	cmd->code = CMD_EJECT;
 	cmd->drive_num = fs->drive_num;
-	err = swimiop_send_request(&req);
+	err = swimiop_send_request(CURRENT, &req);
 	if (err) {
 		release_drive(fs);
 		return err;
@@ -521,12 +523,12 @@
 	fs->state = idle;
 	if (cmd->error) {
 		printk(KERN_ERR "SWIM-IOP: error %d on read/write request.\n", cmd->error);
-		end_request(0);
+		end_request(CURRENT, 0);
 	} else {
 		CURRENT->sector += cmd->num_blocks;
 		CURRENT->current_nr_sectors -= cmd->num_blocks;
 		if (CURRENT->current_nr_sectors <= 0) {
-			end_request(1);
+			end_request(CURRENT, 1);
 			return;
 		}
 	}
@@ -538,7 +540,7 @@
 	struct floppy_state *fs = (struct floppy_state *) data;
 
 	fs->timeout_pending = 0;
-	end_request(0);
+	end_request(CURRENT, 0);
 	fs->state = idle;
 }
 
@@ -566,15 +568,15 @@
 #endif
 
 		if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 		if (CURRENT->current_nr_sectors == 0) {
-			end_request(1);
+			end_request(CURRENT, 1);
 			continue;
 		}
 		if (fs->ejected) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 
@@ -584,7 +586,7 @@
 
 		if (CURRENT->cmd == WRITE) {
 			if (fs->write_prot) {
-				end_request(0);
+				end_request(CURRENT, 0);
 				continue;
 			}
 			cmd->code = CMD_WRITE;
@@ -597,8 +599,8 @@
 		cmd->first_block = CURRENT->sector;
 		cmd->num_blocks = CURRENT->current_nr_sectors;
 
-		if (swimiop_send_request(&req)) {
-			end_request(0);
+		if (swimiop_send_request(CURRENT, &req)) {
+			end_request(CURRENT, 0);
 			continue;
 		}
 
diff -Nru a/drivers/block/xd.c b/drivers/block/xd.c
--- a/drivers/block/xd.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/xd.c	Sun Jun 16 19:31:40 2002
@@ -52,6 +52,7 @@
 #include <asm/dma.h>
 
 #define MAJOR_NR XT_DISK_MAJOR
+#define DEVICE_NR(device) (minor(device) >> 6)
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 
@@ -283,10 +284,8 @@
 	while (1) {
 		code = 0;
 		/* do some checking on the request structure */
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		if (blk_queue_empty(QUEUE))
 			return;
-		}
 
 		if (DEVICE_NR(CURRENT->rq_dev) < xd_drives
 		    && (CURRENT->flags & REQ_CMD)
@@ -307,7 +306,7 @@
 					break;
 			}
 		}
-		end_request(code);	/* wrap up, 0 = fail, 1 = success */
+		end_request(CURRENT, code);	/* wrap up, 0 = fail, 1 = success */
 	}
 }
 
diff -Nru a/drivers/block/z2ram.c b/drivers/block/z2ram.c
--- a/drivers/block/z2ram.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/block/z2ram.c	Sun Jun 16 19:31:40 2002
@@ -26,6 +26,8 @@
 */
 
 #define MAJOR_NR    Z2RAM_MAJOR
+#define DEVICE_NAME "Z2RAM"
+#define DEVICE_NR(device) (minor(device))
 
 #include <linux/major.h>
 #include <linux/slab.h>
@@ -76,10 +78,8 @@
 
     while ( TRUE )
     {
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
 	start = CURRENT->sector << 9;
 	len  = CURRENT->current_nr_sectors << 9;
@@ -89,14 +89,14 @@
 	    printk( KERN_ERR DEVICE_NAME ": bad access: block=%lu, count=%u\n",
 		CURRENT->sector,
 		CURRENT->current_nr_sectors);
-	    end_request( FALSE );
+	    end_request(CURRENT, FALSE);
 	    continue;
 	}
 
 	if ( ( rq_data_dir(CURRENT) != READ ) && ( rq_data_dir(CURRENT) != WRITE ) )
 	{
 	    printk( KERN_ERR DEVICE_NAME ": bad command: %ld\n", rq_data_dir(CURRENT) );
-	    end_request( FALSE );
+	    end_request(CURRENT, FALSE);
 	    continue;
 	}
 
@@ -118,7 +118,7 @@
 	    len -= size;
 	}
 
-	end_request( TRUE );
+	end_request(CURRENT, TRUE);
     }
 }
 
diff -Nru a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
--- a/drivers/cdrom/aztcd.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/cdrom/aztcd.c	Sun Jun 16 19:31:41 2002
@@ -168,6 +168,7 @@
 #include <linux/version.h>
 
 #define MAJOR_NR AZTECH_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 
 #include <linux/blk.h>
 #include "aztcd.h"
@@ -1597,21 +1598,21 @@
 #endif
 	if (DiskInfo.audio) {
 		printk("aztcd: Error, tried to mount an Audio CD\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 		return;
 	}
 	azt_transfer_is_active = 1;
 	while (current_valid()) {
 		azt_transfer();
 		if (CURRENT->nr_sectors == 0) {
-			end_request(1);
+			end_request(CURRENT, 1);
 		} else {
 			azt_buf_out = -1;	/* Want to read a block not in buffer */
 			if (azt_state == AZT_S_IDLE) {
 				if ((!aztTocUpToDate) || aztDiskChanged) {
 					if (aztUpdateToc() < 0) {
 						while (current_valid())
-							end_request(0);
+							end_request(CURRENT, 0);
 						break;
 					}
 				}
@@ -2008,7 +2009,7 @@
 				loop_ctl = 0;
 			}
 			if (current_valid())
-				end_request(0);
+				end_request(CURRENT, 0);
 			AztTries = 5;
 		}
 		azt_error = 0;
@@ -2057,7 +2058,7 @@
 						aztDiskChanged = 1;
 						aztTocUpToDate = 0;
 						azt_invalidate_buffers();
-						end_request(0);
+						end_request(CURRENT, 0);
 						printk
 						    ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
 					}
@@ -2071,7 +2072,7 @@
 				aztTocUpToDate = 0;
 				printk
 				    ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
-				end_request(0);
+				end_request(CURRENT, 0);
 				printk((st & AST_DOOR_OPEN) ?
 				       "aztcd: door open\n" :
 				       "aztcd: disk removed\n");
@@ -2117,7 +2118,7 @@
 						azt_invalidate_buffers();
 						printk
 						    ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
-						end_request(0);
+						end_request(CURRENT, 0);
 					}
 				} else
 					break;
@@ -2293,7 +2294,7 @@
 						azt_read_count = 0;
 						azt_state = AZT_S_STOP;
 						loop_ctl = 1;
-						end_request(1);	/*should we have here (1) or (0)? */
+						end_request(CURRENT, 1);	/*should we have here (1) or (0)? */
 					} else {
 						if (azt_read_mode ==
 						    AZT_MODE_2) {
@@ -2338,7 +2339,7 @@
 						azt_transfer();
 						if (CURRENT->nr_sectors ==
 						    0)
-							end_request(1);
+							end_request(CURRENT, 1);
 						else
 							break;
 					}
@@ -2413,7 +2414,7 @@
 				azt_invalidate_buffers();
 				printk
 				    ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
-				end_request(0);
+				end_request(CURRENT, 0);
 			}
 
 #ifdef AZT_TEST3
diff -Nru a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
--- a/drivers/cdrom/cdu31a.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/cdrom/cdu31a.c	Sun Jun 16 19:31:39 2002
@@ -177,6 +177,7 @@
 #include "cdu31a.h"
 
 #define MAJOR_NR CDU31A_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 
 #define CDU31A_READAHEAD 4	/* 128 sector, 64kB, 32 reads read-ahead */
@@ -1593,10 +1594,8 @@
 		 * The beginning here is stolen from the hard disk driver.  I hope
 		 * it's right.
 		 */
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		if (blk_queue_empty(QUEUE))
 			goto end_do_cdu31a_request;
-		}
 
 		if (!sony_spun_up) {
 			scd_spinup();
@@ -1607,7 +1606,7 @@
 
 		if (!sony_toc_read) {
 			printk("CDU31A: TOC not read\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			goto cdu31a_request_startover;
 		}
 
@@ -1621,14 +1620,14 @@
 				if ((block / 4) >= sony_toc.lead_out_start_lba) {
 					printk
 						("CDU31A: Request past end of media\n");
-					end_request(0);
+					end_request(CURRENT, 0);
 					goto cdu31a_request_startover;
 				}
 				if (((block + nblock) / 4) >=
 				    sony_toc.lead_out_start_lba) {
 					printk
 						("CDU31A: Request past end of media\n");
-					end_request(0);
+					end_request(CURRENT, 0);
 					goto cdu31a_request_startover;
 				}
 
@@ -1639,7 +1638,7 @@
 
 				if (!sony_toc_read) {
 					printk("CDU31A: TOC not read\n");
-					end_request(0);
+					end_request(CURRENT, 0);
 					goto cdu31a_request_startover;
 				}
 
@@ -1648,7 +1647,7 @@
 				if (sony_blocks_left == 0) {
 					if (start_request
 					    (block / 4, CDU31A_READAHEAD / 4, 0)) {
-						end_request(0);
+						end_request(CURRENT, 0);
 						goto cdu31a_request_startover;
 					}
 				}
@@ -1664,14 +1663,14 @@
 					abort_read();
 					if (!sony_toc_read) {
 						printk("CDU31A: TOC not read\n");
-						end_request(0);
+						end_request(CURRENT, 0);
 						goto cdu31a_request_startover;
 					}
 					if (start_request
 					    (block / 4, CDU31A_READAHEAD / 4, 0)) {
 						printk
 							("CDU31a: start request failed\n");
-						end_request(0);
+						end_request(CURRENT, 0);
 						goto cdu31a_request_startover;
 					}
 				}
@@ -1680,7 +1679,7 @@
 						res_reg, &res_size);
 				if (res_reg[0] == 0x20) {
 					if (num_retries > MAX_CDU31A_RETRIES) {
-						end_request(0);
+						end_request(CURRENT, 0);
 						goto cdu31a_request_startover;
 					}
 
@@ -1697,12 +1696,12 @@
 					}
 					goto try_read_again;
 				} else {
-					end_request(1);
+					end_request(CURRENT, 1);
 				}
 				break;
 
 			case WRITE:
-				end_request(0);
+				end_request(CURRENT, 0);
 				break;
 
 			default:
diff -Nru a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
--- a/drivers/cdrom/cm206.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/cdrom/cm206.c	Sun Jun 16 19:31:40 2002
@@ -198,6 +198,8 @@
 #include <asm/io.h>
 
 #define MAJOR_NR CM206_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
+
 #include <linux/blk.h>
 
 #undef DEBUG
@@ -856,15 +858,13 @@
 	uch *source, *dest;
 
 	while (1) {		/* repeat until all requests have been satisfied */
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		if (blk_queue_empty(QUEUE))
 			return;
-		}
 
 		if (CURRENT->cmd != READ) {
 			debug(("Non-read command %d on cdrom\n",
 			       CURRENT->cmd));
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 		spin_unlock_irq(q->queue_lock);
@@ -895,7 +895,7 @@
 			}
 		}
 		spin_lock_irq(q->queue_lock);
-		end_request(!error);
+		end_request(CURRENT, !error);
 	}
 }
 
diff -Nru a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
--- a/drivers/cdrom/gscd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/cdrom/gscd.c	Sun Jun 16 19:31:39 2002
@@ -70,6 +70,7 @@
 #include <asm/uaccess.h>
 
 #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 #define gscd_port gscd		/* for compatible parameter passing with "insmod" */
 #include "gscd.h"
@@ -279,10 +280,8 @@
 	unsigned int nsect;
 
       repeat:
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
 	dev = minor(CURRENT->rq_dev);
 	block = CURRENT->sector;
@@ -293,13 +292,13 @@
 
 	if (CURRENT->cmd != READ) {
 		printk("GSCD: bad cmd %p\n", CURRENT->cmd);
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 
 	if (dev != 0) {
 		printk("GSCD: this version supports only one device\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 
@@ -308,7 +307,7 @@
 	/* if we satisfied the request from the buffer, we're done. */
 
 	if (CURRENT->nr_sectors == 0) {
-		end_request(1);
+		end_request(CURRENT, 1);
 		goto repeat;
 	}
 #ifdef GSCD_DEBUG
@@ -338,11 +337,11 @@
 	cmd_status();
 	if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
 		printk("GSCD: no disk or door open\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 	} else {
 		if (disk_state & ST_INVALID) {
 			printk("GSCD: disk invalid\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 		} else {
 			gscd_bn = -1;	/* purge our buffer */
 			block = CURRENT->sector / 4;
@@ -361,7 +360,7 @@
 
 			gscd_bn = CURRENT->sector / 4;
 			gscd_transfer();
-			end_request(1);
+			end_request(CURRENT, 1);
 		}
 	}
 	SET_TIMER(__do_gscd_request, 1);
diff -Nru a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c
--- a/drivers/cdrom/mcd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/cdrom/mcd.c	Sun Jun 16 19:31:39 2002
@@ -102,6 +102,7 @@
 #include <asm/uaccess.h>
 
 #define MAJOR_NR MITSUMI_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 
 #define mcd_port mcd		/* for compatible parameter passing with "insmod" */
@@ -621,14 +622,14 @@
 	while (current_valid()) {
 		mcd_transfer();
 		if (CURRENT->nr_sectors == 0) {
-			end_request(1);
+			end_request(CURRENT, 1);
 		} else {
 			mcd_buf_out = -1;	/* Want to read a block not in buffer */
 			if (mcd_state == MCD_S_IDLE) {
 				if (!tocUpToDate) {
 					if (updateToc() < 0) {
 						while (current_valid())
-							end_request(0);
+							end_request(CURRENT, 0);
 						break;
 					}
 				}
@@ -693,7 +694,7 @@
 					goto ret;
 				}
 				if (current_valid())
-					end_request(0);
+					end_request(CURRENT, 0);
 				McdTries = MCD_RETRY_ATTEMPTS;
 			}
 		}
@@ -750,7 +751,7 @@
 				       "mcd: disk removed\n");
 				mcd_state = MCD_S_IDLE;
 				while (current_valid())
-					end_request(0);
+					end_request(CURRENT, 0);
 				goto out;
 			}
 			outb(MCMD_SET_MODE, MCDPORT(0));
@@ -784,7 +785,7 @@
 				       "mcd: disk removed\n");
 				mcd_state = MCD_S_IDLE;
 				while (current_valid())
-					end_request(0);
+					end_request(CURRENT, 0);
 				goto out;
 			}
 
@@ -825,7 +826,7 @@
 					break;
 				}
 				if (current_valid())
-					end_request(0);
+					end_request(CURRENT, 0);
 				McdTries = 5;
 			}
 			mcd_state = MCD_S_START;
@@ -852,7 +853,7 @@
 				while (current_valid()) {
 					mcd_transfer();
 					if (CURRENT->nr_sectors == 0)
-						end_request(1);
+						end_request(CURRENT, 1);
 					else
 						break;
 				}
@@ -1068,7 +1069,7 @@
 		printk(KERN_ERR "mcd: Unable to get major %d for Mitsumi CD-ROM\n", MAJOR_NR);
 		return -EIO;
 	}
-	if (check_region(mcd_port, 4)) {
+	if (!request_region(mcd_port, 4, "mcd")) {
 		cleanup(1);
 		printk(KERN_ERR "mcd: Initialization failed, I/O port (%X) already in use\n", mcd_port);
 		return -EIO;
@@ -1091,7 +1092,7 @@
 	if (count >= 2000000) {
 		printk(KERN_INFO "mcd: initialisation failed - No mcd device at 0x%x irq %d\n",
 		       mcd_port, mcd_irq);
-		cleanup(1);
+		cleanup(2);
 		return -EIO;
 	}
 	count = inb(MCDPORT(0));	/* pick up the status */
@@ -1101,12 +1102,12 @@
 		if (getValue(result + count)) {
 			printk(KERN_ERR "mcd: mitsumi get version failed at 0x%x\n",
 			       mcd_port);
-			cleanup(1);
+			cleanup(2);
 			return -EIO;
 		}
 
 	if (result[0] == result[1] && result[1] == result[2]) {
-		cleanup(1);
+		cleanup(2);
 		return -EIO;
 	}
 
@@ -1119,7 +1120,7 @@
 
 	if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) {
 		printk(KERN_ERR "mcd: Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
-		cleanup(1);
+		cleanup(2);
 		return -EIO;
 	}
 
@@ -1132,8 +1133,6 @@
 	sprintf(msg, " mcd: Mitsumi %s Speed CD-ROM at port=0x%x,"
 		" irq=%d\n", mcd_info.speed == 1 ? "Single" : "Double",
 		mcd_port, mcd_irq);
-
-	request_region(mcd_port, 4, "mcd");
 
 	outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
 	outb(0x02, MCDPORT(0));
diff -Nru a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
--- a/drivers/cdrom/mcdx.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/cdrom/mcdx.c	Sun Jun 16 19:31:40 2002
@@ -73,6 +73,7 @@
 
 #include <linux/major.h>
 #define MAJOR_NR MITSUMI_X_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 #include <linux/devfs_fs_kernel.h>
 
@@ -562,10 +563,8 @@
 
       again:
 
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
 	dev = minor(CURRENT->rq_dev);
 	stuffp = mcdx_stuffp[dev];
@@ -576,14 +575,14 @@
 		xwarn("do_request(): bad device: %s\n",
 		      kdevname(CURRENT->rq_dev));
 		xtrace(REQUEST, "end_request(0): bad device\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 		return;
 	}
 
 	if (stuffp->audio) {
 		xwarn("do_request() attempt to read from audio cd\n");
 		xtrace(REQUEST, "end_request(0): read from audio\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 		return;
 	}
 
@@ -593,7 +592,7 @@
 	if (CURRENT->cmd != READ) {
 		xwarn("do_request(): non-read command to cd!!\n");
 		xtrace(REQUEST, "end_request(0): write\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 		return;
 	}
 	else {
@@ -607,18 +606,18 @@
 					  CURRENT->nr_sectors);
 
 			if (i == -1) {
-				end_request(0);
+				end_request(CURRENT, 0);
 				goto again;
 			}
 			CURRENT->sector += i;
 			CURRENT->nr_sectors -= i;
 			CURRENT->buffer += (i * 512);
 		}
-		end_request(1);
+		end_request(CURRENT, 1);
 		goto again;
 
 		xtrace(REQUEST, "end_request(1)\n");
-		end_request(1);
+		end_request(CURRENT, 1);
 	}
 
 	goto again;
@@ -1106,7 +1105,8 @@
 	init_waitqueue_head(&stuffp->sleepq);
 
 	/* check if i/o addresses are available */
-	if (check_region((unsigned int) stuffp->wreg_data, MCDX_IO_SIZE)) {
+	if (!request_region((unsigned int) stuffp->wreg_data, MCDX_IO_SIZE,
+			    "mcdx")) {
 		xwarn("0x%3p,%d: Init failed. "
 		      "I/O ports (0x%3p..0x%3p) already in use.\n",
 		      stuffp->wreg_data, stuffp->irq,
@@ -1126,6 +1126,8 @@
 	xtrace(INIT, "init() get version\n");
 	if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
 		/* failed, next drive */
+		release_region((unsigned long) stuffp->wreg_data,
+			       MCDX_IO_SIZE);
 		xwarn("%s=0x%3p,%d: Init failed. Can't get version.\n",
 		      MCDX, stuffp->wreg_data, stuffp->irq);
 		xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
@@ -1155,6 +1157,8 @@
 	stuffp->playcmd = READ1X;
 
 	if (!stuffp->present) {
+		release_region((unsigned long) stuffp->wreg_data,
+			       MCDX_IO_SIZE);
 		xwarn("%s=0x%3p,%d: Init failed. No Mitsumi CD-ROM?.\n",
 		      MCDX, stuffp->wreg_data, stuffp->irq);
 		kfree(stuffp);
@@ -1163,6 +1167,8 @@
 
 	xtrace(INIT, "init() register blkdev\n");
 	if (devfs_register_blkdev(MAJOR_NR, "mcdx", &mcdx_bdops) != 0) {
+		release_region((unsigned long) stuffp->wreg_data,
+			       MCDX_IO_SIZE);
 		xwarn("%s=0x%3p,%d: Init failed. Can't get major %d.\n",
 		      MCDX, stuffp->wreg_data, stuffp->irq, MAJOR_NR);
 		kfree(stuffp);
@@ -1175,6 +1181,8 @@
 	xtrace(INIT, "init() subscribe irq and i/o\n");
 	mcdx_irq_map[stuffp->irq] = stuffp;
 	if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, "mcdx", NULL)) {
+		release_region((unsigned long) stuffp->wreg_data,
+			       MCDX_IO_SIZE);
 		xwarn("%s=0x%3p,%d: Init failed. Can't get irq (%d).\n",
 		      MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
 		stuffp->irq = 0;
@@ -1182,8 +1190,6 @@
 		kfree(stuffp);
 		return 0;
 	}
-	request_region((unsigned int) stuffp->wreg_data,
-		       MCDX_IO_SIZE, "mcdx");
 
 	xtrace(INIT, "init() get garbage\n");
 	{
diff -Nru a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
--- a/drivers/cdrom/optcd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/cdrom/optcd.c	Sun Jun 16 19:31:39 2002
@@ -76,6 +76,7 @@
 #include <asm/io.h>
 
 #define MAJOR_NR OPTICS_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 
 #include <linux/cdrom.h>
@@ -1095,7 +1096,7 @@
 			if (transfer_is_active)
 				loop_again = 0;
 			if (current_valid())
-				end_request(0);
+				end_request(CURRENT, 0);
 			tries = 5;
 		}
 		error = 0;
@@ -1129,7 +1130,7 @@
 			if (send_cmd(COMDRVST)) {
 				state = S_IDLE;
 				while (current_valid())
-					end_request(0);
+					end_request(CURRENT, 0);
 				return;
 			}
 			state = S_READ;
@@ -1156,7 +1157,7 @@
 					: "disk removed");
 				state = S_IDLE;
 				while (current_valid())
-					end_request(0);
+					end_request(CURRENT, 0);
 				return;
 			}
 			if (!current_valid()) {
@@ -1211,7 +1212,7 @@
 						break;
 					}
 					if (current_valid())
-						end_request(0);
+						end_request(CURRENT, 0);
 					tries = 5;
 				}
 				state = S_START;
@@ -1247,7 +1248,7 @@
 						read_count = 0;
 						state = S_STOP;
 						loop_again = 1;
-						end_request(0);
+						end_request(CURRENT, 0);
 						break;
 					}
 					fetch_data(buf+
@@ -1277,7 +1278,7 @@
 					while (current_valid()) {
 						transfer();
 						if (CURRENT -> nr_sectors == 0)
-							end_request(1);
+							end_request(CURRENT, 1);
 						else
 							break;
 					}
@@ -1308,7 +1309,7 @@
 			if (send_cmd(COMDRVST)) {
 				state = S_IDLE;
 				while (current_valid())
-					end_request(0);
+					end_request(CURRENT, 0);
 				return;
 			}
 			state = S_STOPPING;
@@ -1349,7 +1350,7 @@
 		if (exec_cmd(COMSTOP) < 0) {
 			state = S_IDLE;
 			while (current_valid())
-				end_request(0);
+				end_request(CURRENT, 0);
 			return;
 		}
 	}
@@ -1365,7 +1366,7 @@
 
 	if (disk_info.audio) {
 		printk(KERN_WARNING "optcd: tried to mount an Audio CD\n");
-		end_request(0);
+		end_request(CURRENT, 0);
 		return;
 	}
 
@@ -1373,14 +1374,14 @@
 	while (current_valid()) {
 		transfer();	/* First try to transfer block from buffers */
 		if (CURRENT -> nr_sectors == 0) {
-			end_request(1);
+			end_request(CURRENT, 1);
 		} else {	/* Want to read a block not in buffer */
 			buf_out = NOBUF;
 			if (state == S_IDLE) {
 				/* %% Should this block the request queue?? */
 				if (update_toc() < 0) {
 					while (current_valid())
-						end_request(0);
+						end_request(CURRENT, 0);
 					break;
 				}
 				/* Start state machine */
@@ -1507,7 +1508,6 @@
 
 static int cdromreadtochdr(unsigned long arg)
 {
-	int status;
 	struct cdrom_tochdr tochdr;
 
 	tochdr.cdth_trk0 = disk_info.first;
@@ -1519,7 +1519,6 @@
 
 static int cdromreadtocentry(unsigned long arg)
 {
-	int status;
 	struct cdrom_tocentry entry;
 	struct cdrom_subchnl *tocptr;
 
@@ -1646,7 +1645,6 @@
 #ifdef MULTISESSION
 static int cdrommultisession(unsigned long arg)
 {
-	int status;
 	struct cdrom_multisession ms;
 
 	if (copy_from_user(&ms, (void*) arg, sizeof ms))
@@ -2010,7 +2008,7 @@
 			"optcd: no Optics Storage CDROM Initialization\n");
 		return -EIO;
 	}
-	if (check_region(optcd_port, 4)) {
+	if (!request_region(optcd_port, 4, "optcd")) {
 		printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
 			optcd_port);
 		return -EIO;
@@ -2018,21 +2016,25 @@
 
 	if (!reset_drive()) {
 		printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port);
+		release_region(optcd_port, 4);
 		return -EIO;
 	}
 	if (!version_ok()) {
 		printk(KERN_ERR "optcd: unknown drive detected; aborting\n");
+		release_region(optcd_port, 4);
 		return -EIO;
 	}
 	status = exec_cmd(COMINITDOUBLE);
 	if (status < 0) {
 		printk(KERN_ERR "optcd: cannot init double speed mode\n");
+		release_region(optcd_port, 4);
 		DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status));
 		return -EIO;
 	}
 	if (devfs_register_blkdev(MAJOR_NR, "optcd", &opt_fops) != 0)
 	{
 		printk(KERN_ERR "optcd: unable to get major %d\n", MAJOR_NR);
+		release_region(optcd_port, 4);
 		return -EIO;
 	}
 	devfs_register (NULL, "optcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
@@ -2040,7 +2042,6 @@
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_optcd_request,
 		       &optcd_lock);
 	blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), 2048);
-	request_region(optcd_port, 4, "optcd");
 	register_disk(NULL, mk_kdev(MAJOR_NR,0), 1, &opt_fops, 0);
 
 	printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port);
diff -Nru a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
--- a/drivers/cdrom/sbpcd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/cdrom/sbpcd.c	Sun Jun 16 19:31:39 2002
@@ -380,7 +380,6 @@
 #include "sbpcd.h"
 
 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
-
 #include <linux/blk.h>
 
 /*==========================================================================*/
@@ -4851,7 +4850,6 @@
 			xnr, current->pid, jiffies);
 		printk( "do_sbpcd_request[%do](NULL) end 0 (null), Time:%li\n",
 			xnr, jiffies);
-		CLEAR_INTR;
 		return;
 	}
 
@@ -4859,16 +4857,14 @@
 		xnr, CURRENT, CURRENT->sector, CURRENT->nr_sectors, current->pid, jiffies);
 #endif
 
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
 	req = CURRENT;		/* take out our request so no other */
 	blkdev_dequeue_request(req);	/* task can fuck it up         GTL  */
 
 	if (req -> sector == -1)
-		end_request(0);
+		end_request(CURRENT, 0);
 	spin_unlock_irq(q->queue_lock);
 
 	down(&ioctl_read_sem);
@@ -4910,7 +4906,7 @@
 #endif
 		up(&ioctl_read_sem);
 		spin_lock_irq(q->queue_lock);
-		end_request(1);
+		end_request(CURRENT, 1);
 		goto request_loop;
 	}
 
@@ -4951,7 +4947,7 @@
 #endif
 			up(&ioctl_read_sem);
 			spin_lock_irq(q->queue_lock);
-			end_request(1);
+			end_request(CURRENT, 1);
 			goto request_loop;
 		}
 	}
@@ -4967,7 +4963,7 @@
 	up(&ioctl_read_sem);
 	sbp_sleep(0);    /* wait a bit, try again */
 	spin_lock_irq(q->queue_lock);
-	end_request(0);
+	end_request(CURRENT, 0);
 	goto request_loop;
 }
 /*==========================================================================*/
diff -Nru a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
--- a/drivers/cdrom/sjcd.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/cdrom/sjcd.c	Sun Jun 16 19:31:41 2002
@@ -77,6 +77,7 @@
 #include <asm/uaccess.h>
 
 #define MAJOR_NR SANYO_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 #include "sjcd.h"
 
@@ -1303,7 +1304,7 @@
 					     sjcd_next_bn);
 #endif
 					if (current_valid())
-						end_request(0);
+						end_request(CURRENT, 0);
 #if defined( SJCD_TRACE )
 					printk
 					    ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
@@ -1377,7 +1378,7 @@
 							    nr_sectors ==
 							    0)
 								end_request
-								    (1);
+								    (CURRENT, 1);
 							else
 								break;
 						}
@@ -1472,7 +1473,7 @@
 	if (--sjcd_transfer_timeout == 0) {
 		printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
 		while (current_valid())
-			end_request(0);
+			end_request(CURRENT, 0);
 		sjcd_send_cmd(SCMD_STOP);
 		sjcd_transfer_state = SJCD_S_IDLE;
 		goto ReSwitch;
@@ -1495,7 +1496,7 @@
 	while (current_valid()) {
 		sjcd_transfer();
 		if (CURRENT->nr_sectors == 0)
-			end_request(1);
+			end_request(CURRENT, 1);
 		else {
 			sjcd_buf_out = -1;	/* Want to read a block not in buffer */
 			if (sjcd_transfer_state == SJCD_S_IDLE) {
@@ -1504,7 +1505,7 @@
 						printk
 						    ("SJCD: transfer: discard\n");
 						while (current_valid())
-							end_request(0);
+							end_request(CURRENT, 0);
 						break;
 					}
 				}
diff -Nru a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
--- a/drivers/cdrom/sonycd535.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/cdrom/sonycd535.c	Sun Jun 16 19:31:40 2002
@@ -135,6 +135,7 @@
 #include <linux/cdrom.h>
 
 #define MAJOR_NR CDU535_CDROM_MAJOR
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 
 #define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */
@@ -817,7 +818,7 @@
 		block = CURRENT->sector;
 		nsect = CURRENT->nr_sectors;
 		if (dev != 0) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 		if(CURRENT->flags & REQ_CMD) {
@@ -829,11 +830,11 @@
 				 */
 				
 				if (sony_toc->lead_out_start_lba <= (block / 4)) {
-					end_request(0);
+					end_request(CURRENT, 0);
 					return;
 				}
 				if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
-					end_request(0);
+					end_request(CURRENT, 0);
 					return;
 				}
 				while (0 < nsect) {
@@ -895,7 +896,7 @@
 									       status[0]);
 								sony_first_block = -1;
 								sony_last_block = -1;
-								end_request(0);
+								end_request(CURRENT, 0);
 								return;
 							}
 							if (readStatus == BAD_STATUS) {
@@ -924,11 +925,11 @@
 					CURRENT->buffer += 512;
 				}
 
-				end_request(1);
+				end_request(CURRENT, 1);
 				break;
 				
 			case WRITE:
-				end_request(0);
+				end_request(CURRENT, 0);
 				break;
 				
 			default:
@@ -1012,7 +1013,6 @@
 sony_get_subchnl_info(long arg)
 {
 	struct cdrom_subchnl schi;
-	int err;
 
 	/* Get attention stuff */
 	if (check_drive_status() != 0)
diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in
--- a/drivers/char/Config.in	Sun Jun 16 19:31:39 2002
+++ b/drivers/char/Config.in	Sun Jun 16 19:31:39 2002
@@ -39,7 +39,7 @@
    if [ "$CONFIG_DIGIEPCA" = "n" ]; then
       tristate '  Digiboard PC/Xx Support' CONFIG_DIGI
    fi
-   tristate '  Hayes ESP serial port support' CONFIG_ESPSERIAL
+   dep_tristate '  Hayes ESP serial port support' CONFIG_ESPSERIAL $CONFIG_ISA
    tristate '  Moxa Intellio support' CONFIG_MOXA_INTELLIO
    tristate '  Moxa SmartIO support' CONFIG_MOXA_SMARTIO
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/char/Makefile	Sun Jun 16 19:31:40 2002
@@ -17,8 +17,6 @@
 			sonypi.o tty_io.o tty_ioctl.o generic_serial.o rtc.o \
 			ip2main.o
 
-mod-subdirs	:=	ftape drm pcmcia
-
 KEYMAP   =defkeymap.o
 KEYBD    =pc_keyb.o
 CONSOLE  =console.o
diff -Nru a/drivers/char/isicom.c b/drivers/char/isicom.c
--- a/drivers/char/isicom.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/char/isicom.c	Sun Jun 16 19:31:39 2002
@@ -1254,7 +1254,11 @@
 			   created more space in xmit_buf when the ctrl 
 			   gets back here  */
 			sti(); 
-			copy_from_user(tmp_buf, buf, cnt);
+			if (copy_from_user(tmp_buf, buf, cnt)) {
+				up(&tmp_buf_sem);
+				restore_flags(flags);
+				return -EFAULT;
+			}
 			cli();
 			cnt = MIN(cnt, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
 			SERIAL_XMIT_SIZE - port->xmit_head));
diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c
--- a/drivers/char/istallion.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/char/istallion.c	Sun Jun 16 19:31:39 2002
@@ -712,7 +712,7 @@
 static void	stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
 static long	stli_mktiocm(unsigned long sigvalue);
 static void	stli_read(stlibrd_t *brdp, stliport_t *portp);
-static void	stli_getserial(stliport_t *portp, struct serial_struct *sp);
+static int	stli_getserial(stliport_t *portp, struct serial_struct *sp);
 static int	stli_setserial(stliport_t *portp, struct serial_struct *sp);
 static int	stli_getbrdstats(combrd_t *bp);
 static int	stli_getportstats(stliport_t *portp, comstats_t *cp);
@@ -1676,7 +1676,8 @@
 		restore_flags(flags);
 
 		down(&stli_tmpwritesem);
-		copy_from_user(stli_tmpwritebuf, chbuf, count);
+		if (copy_from_user(stli_tmpwritebuf, chbuf, count)) 
+			return -EFAULT;
 		chbuf = &stli_tmpwritebuf[0];
 	}
 
@@ -1977,7 +1978,7 @@
  *	Generate the serial struct info.
  */
 
-static void stli_getserial(stliport_t *portp, struct serial_struct *sp)
+static int stli_getserial(stliport_t *portp, struct serial_struct *sp)
 {
 	struct serial_struct	sio;
 	stlibrd_t		*brdp;
@@ -2002,7 +2003,8 @@
 	if (brdp != (stlibrd_t *) NULL)
 		sio.port = brdp->iobase;
 		
-	copy_to_user(sp, &sio, sizeof(struct serial_struct));
+	return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ?
+			-EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -2129,7 +2131,7 @@
 	case TIOCGSERIAL:
 		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
 		    sizeof(struct serial_struct))) == 0)
-			stli_getserial(portp, (struct serial_struct *) arg);
+			rc = stli_getserial(portp, (struct serial_struct *) arg);
 		break;
 	case TIOCSSERIAL:
 		if ((rc = verify_area(VERIFY_READ, (void *) arg,
@@ -3972,7 +3974,7 @@
 	printk(KERN_DEBUG "stli_initecp(brdp=%x)\n", (int) brdp);
 #endif
 
-	if (!request_region(brdp->iobase, brdp->iosize, name))
+	if (!request_region(brdp->iobase, brdp->iosize, "istallion"))
 		return -EIO;
 	
 	if ((brdp->iobase == 0) || (brdp->memaddr == 0))
@@ -4140,7 +4142,7 @@
 
 	brdp->iosize = ONB_IOSIZE;
 	
-	if (!request_region(brdp->iobase, brdp->iosize, name))
+	if (!request_region(brdp->iobase, brdp->iosize, "istallion"))
 		return -EIO;
 
 /*
diff -Nru a/drivers/char/stallion.c b/drivers/char/stallion.c
--- a/drivers/char/stallion.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/char/stallion.c	Sun Jun 16 19:31:39 2002
@@ -521,7 +521,7 @@
 static int	stl_brdinit(stlbrd_t *brdp);
 static int	stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
 static int	stl_mapirq(int irq, char *name);
-static void	stl_getserial(stlport_t *portp, struct serial_struct *sp);
+static int	stl_getserial(stlport_t *portp, struct serial_struct *sp);
 static int	stl_setserial(stlport_t *portp, struct serial_struct *sp);
 static int	stl_getbrdstats(combrd_t *bp);
 static int	stl_getportstats(stlport_t *portp, comstats_t *cp);
@@ -1332,7 +1332,8 @@
 		count = MIN(len, count);
 		
 		down(&stl_tmpwritesem);
-		copy_from_user(stl_tmpwritebuf, chbuf, count);
+		if (copy_from_user(stl_tmpwritebuf, chbuf, count)) 
+			return -EFAULT;
 		chbuf = &stl_tmpwritebuf[0];
 	}
 
@@ -1504,7 +1505,7 @@
  *	Generate the serial struct info.
  */
 
-static void stl_getserial(stlport_t *portp, struct serial_struct *sp)
+static int stl_getserial(stlport_t *portp, struct serial_struct *sp)
 {
 	struct serial_struct	sio;
 	stlbrd_t		*brdp;
@@ -1534,7 +1535,7 @@
 	if (brdp != (stlbrd_t *) NULL)
 		sio.irq = brdp->irq;
 
-	copy_to_user(sp, &sio, sizeof(struct serial_struct));
+	return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -1648,7 +1649,7 @@
 	case TIOCGSERIAL:
 		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
 		    sizeof(struct serial_struct))) == 0)
-			stl_getserial(portp, (struct serial_struct *) arg);
+			rc = stl_getserial(portp, (struct serial_struct *) arg);
 		break;
 	case TIOCSSERIAL:
 		if ((rc = verify_area(VERIFY_READ, (void *) arg,
diff -Nru a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/char/sysrq.c	Sun Jun 16 19:31:40 2002
@@ -105,11 +105,9 @@
 
 /* do_emergency_sync helper function */
 /* Guesses if the device is a local hard drive */
-static int is_local_disk(kdev_t dev) {
-	unsigned int major;
-	major = major(dev);
-
-	switch (major) {
+static int is_local_disk(struct block_device *bdev)
+{
+	switch (MAJOR(bdev->bd_dev)) {
 	case IDE0_MAJOR:
 	case IDE1_MAJOR:
 	case IDE2_MAJOR:
@@ -143,7 +141,7 @@
 	console_loglevel = 7;
 	printk(KERN_INFO "%sing device %s ... ",
 	       remount_flag ? "Remount" : "Sync",
-	       kdevname(sb->s_dev));
+	       sb->s_id);
 
 	if (remount_flag) { /* Remount R/O */
 		int ret, flags;
@@ -202,13 +200,13 @@
 	for (sb = sb_entry(super_blocks.next);
 	     sb != sb_entry(&super_blocks); 
 	     sb = sb_entry(sb->s_list.next))
-		if (is_local_disk(sb->s_dev))
+		if (sb->s_bdev && is_local_disk(sb->s_bdev))
 			go_sync(sb, remount_flag);
 
 	for (sb = sb_entry(super_blocks.next);
 	     sb != sb_entry(&super_blocks); 
 	     sb = sb_entry(sb->s_list.next))
-		if (!is_local_disk(sb->s_dev) && major(sb->s_dev))
+		if (sb->s_bdev && !is_local_disk(sb->s_bdev))
 			go_sync(sb, remount_flag);
 
 	unlock_kernel();
@@ -319,22 +317,6 @@
 	action_msg:	"Kill All Tasks",
 };
 
-#ifdef CONFIG_SOFTWARE_SUSPEND
-static void sysrq_handle_swsusp(int key, struct pt_regs *pt_regs,
-		struct kbd_struct *kbd, struct tty_struct *tty) {
-        if(!software_suspend_enabled) {
-		printk("Software Suspend is not possible now\n");
-		return;
-	}
-	software_suspend();
-}
-static struct sysrq_key_op sysrq_swsusp_op = {
-	handler:	sysrq_handle_swsusp,
-	help_msg:	"suspenD",
-	action_msg:	"Software suspend\n",
-};
-#endif
-
 /* END SIGNAL SYSRQ HANDLERS BLOCK */
 
 
@@ -357,11 +339,7 @@
 		 and will never arive */
 /* b */	&sysrq_reboot_op,
 /* c */	NULL,
-#ifdef CONFIG_SOFTWARE_SUSPEND
-/* d */	&sysrq_swsusp_op,
-#else
 /* d */	NULL,
-#endif
 /* e */	&sysrq_term_op,
 /* f */	NULL,
 /* g */	NULL,
@@ -387,7 +365,7 @@
 /* v */	NULL,
 /* w */	NULL,
 /* x */	NULL,
-/* w */	NULL,
+/* y */	NULL,
 /* z */	NULL
 };
 
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/hotplug/pci_hotplug_core.c	Sun Jun 16 19:31:40 2002
@@ -48,7 +48,7 @@
 	#define MY_NAME	THIS_MODULE->name
 #endif
 
-#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: "__FUNCTION__": " fmt , MY_NAME , ## arg); } while (0)
+#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt, MY_NAME, __FUNCTION__, ## arg); } while (0)
 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
diff -Nru a/drivers/hotplug/pci_hotplug_util.c b/drivers/hotplug/pci_hotplug_util.c
--- a/drivers/hotplug/pci_hotplug_util.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/hotplug/pci_hotplug_util.c	Sun Jun 16 19:31:41 2002
@@ -41,7 +41,7 @@
 	#define MY_NAME	THIS_MODULE->name
 #endif
 
-#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: "__FUNCTION__": " fmt , MY_NAME , ## arg); } while (0)
+#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt, MY_NAME, __FUNCTION__, ## arg); } while (0)
 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/i2c/i2c-core.c	Sun Jun 16 19:31:39 2002
@@ -381,10 +381,10 @@
 						printk("i2c-core.o: while "
 						       "unregistering driver "
 						       "`%s', the client at "
-						       "address %02x of
-						       adapter `%s' could not
-						       be detached; driver
-						       not unloaded!",
+						       "address %02x of "
+						       "adapter `%s' could not "
+						       "be detached; driver "
+						       "not unloaded!",
 						       driver->name,
 						       client->addr,
 						       adap->name);
diff -Nru a/drivers/ide/Config.help b/drivers/ide/Config.help
--- a/drivers/ide/Config.help	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/Config.help	Sun Jun 16 19:31:41 2002
@@ -372,6 +372,8 @@
   HPT366 is an Ultra DMA chipset for ATA-66.
   HPT368 is an Ultra DMA chipset for ATA-66 RAID Based.
   HPT370 is an Ultra DMA chipset for ATA-100.
+  HPT372 is an Ultra DMA chipset for ATA-100.
+  HPT374 is an Ultra DMA chipset for ATA-100.
 
   This driver adds up to 4 more EIDE devices sharing a single
   interrupt.
@@ -407,16 +409,6 @@
   and also for the Efar Victory66 (slc90e66) chip.  This allows
   the kernel to change PIO, DMA and UDMA speeds and to configure
   the chip to optimum performance.
-
-CONFIG_BLK_DEV_PIIX_TRY133
-  The ICH2, ICH2-M, ICH3, ICH3-M, ICH3-S, ICH-4 and CICH chips can
-  support UDMA133 in hardware, even though the specifications of
-  the chips say otherwise. By enabling this option, you allow the
-  driver to enable the UDMA133 mode on these chips. Note that if
-  it doesn't work, your data gets lost, you're on your own, don't
-  expect any help. 
-
-  Say N here, unless you really know what are you doing.
 
 CONFIG_BLK_DEV_PDC202XX
   Promise Ultra33 or PDC20246
diff -Nru a/drivers/ide/Config.in b/drivers/ide/Config.in
--- a/drivers/ide/Config.in	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/Config.in	Sun Jun 16 19:31:41 2002
@@ -50,11 +50,8 @@
       dep_bool '    Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI
       dep_bool '    HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI
       dep_mbool '      HPT34X AUTODMA support (EXPERMENTAL)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_EXPERIMENTAL
-      dep_bool '    HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI
+      dep_bool '    HPT36X/37X chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI
       dep_bool '    Intel and Efar (SMsC) chipset support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI
-      if [ "$CONFIG_BLK_DEV_PIIX" = "y" ]; then
-         dep_bool '      Allow undocumented UDMA133 on ICH chips (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TRY133 $CONFIG_EXPERIMENTAL
-      fi
       if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
          dep_mbool '    IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI
          dep_mbool '      IT8172 IDE Tuning support' CONFIG_IT8172_TUNING $CONFIG_BLK_DEV_IT8172 $CONFIG_IDEDMA_PCI_AUTO
@@ -112,7 +109,8 @@
 	      EXT_DIRECT	CONFIG_IDE_EXT_DIRECT"	8xx_PCCARD
    fi
 
-   bool '  Other IDE chipset support' CONFIG_IDE_CHIPSETS
+   # assume no ISA -> also no VLB
+   dep_bool '  Other ISA/VLB IDE chipset support' CONFIG_IDE_CHIPSETS $CONFIG_ISA
    if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
       comment 'Note: most of these also require special kernel boot parameters'
       bool '    ALI M14xx support' CONFIG_BLK_DEV_ALI14XX
diff -Nru a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
--- a/drivers/ide/aec62xx.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/aec62xx.c	Sun Jun 16 19:31:40 2002
@@ -1,6 +1,6 @@
 /*
  *
- * $Id: aec62xx.c,v 1.0 2002/05/24 14:37:19 vojtech Exp $
+ * aec62xx.c, v1.2 2002/05/24
  *
  *  Copyright (c) 2002 Vojtech Pavlik
  *
@@ -60,7 +60,9 @@
 #define AEC_PLLCLK_ATA133	0x10
 #define AEC_CABLEPINS_INPUT	0x10
 
-static unsigned char aec_cyc2udma[17] = { 0, 0, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1 };
+static unsigned char aec_cyc2udma[9] = { 5, 5, 5, 4, 3, 2, 2, 1, 1 };
+static unsigned char aec_cyc2act[16] = { 1, 1, 2, 3, 4, 5, 6, 0, 0, 7,  7,  7, 7,  7,  7,  7 };
+static unsigned char aec_cyc2rec[16] = { 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 12, 13, 14 };
 
 /*
  * aec_set_speed_old() writes timing values to
@@ -71,8 +73,10 @@
 {
 	unsigned char t;
 
-	pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1),     FIT(timing->active, 0, 15));
-	pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1) + 1, FIT(timing->recover, 0, 15));
+	pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1),
+		aec_cyc2act[FIT(timing->active, 0, 15)]);
+	pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1) + 1,
+		aec_cyc2rec[FIT(timing->recover, 0, 15)]);
 
 	pci_read_config_byte(dev, AEC_UDMA_OLD, &t);
 	t &= ~(3 << (dn << 1));
@@ -91,12 +95,19 @@
 	unsigned char t;
 
 	pci_write_config_byte(dev, AEC_DRIVE_TIMING + dn,
-		(FIT(timing->active, 0, 15) << 4) | FIT(timing->recover, 0, 15));
+		(aec_cyc2act[FIT(timing->active, 0, 15)] << 4)
+		| aec_cyc2rec[FIT(timing->recover, 0, 15)]);
 
 	pci_read_config_byte(dev, AEC_UDMA_NEW + (dn >> 1), &t);
 	t &= ~(0xf << ((dn & 1) << 2));
-	if (timing->udma)
-		t |= aec_cyc2udma[FIT(timing->udma, 2, 16)] << ((dn & 1) << 2);
+	if (timing->udma) {
+		if (timing->udma >= 2)
+			t |= aec_cyc2udma[FIT(timing->udma, 2, 8)] << ((dn & 1) << 2);
+		if (timing->mode == XFER_UDMA_5)
+			t |= 6;
+		if (timing->mode == XFER_UDMA_6)
+			t |= 7;
+	}
 	pci_write_config_byte(dev, AEC_UDMA_NEW + (dn >> 1), t);
 }
 
@@ -120,16 +131,15 @@
 				drive->dn >> 1, drive->dn & 1);
 
 	T = 1000000000 / system_bus_speed;
-	UT = T / (aec_old ? 1 : 4);
+	UT = T / (aec_old ? 1 : 2);
 
 	ata_timing_compute(drive, speed, &t, T, UT);
+	ata_timing_merge_8bit(&t);
 
 	if (aec_old)
 		aec_set_speed_old(drive->channel->pci_dev, drive->dn, &t);
 	else
 		aec_set_speed_new(drive->channel->pci_dev, drive->dn, &t);
-
-	drive->current_speed = speed;
 
 	return 0;
 }
diff -Nru a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
--- a/drivers/ide/alim15x3.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/alim15x3.c	Sun Jun 16 19:31:40 2002
@@ -53,6 +53,7 @@
 
 	t = ata_timing_data(pio);
 
+	/* FIXME: use generic ata-timing library  --bkz */
 	s_time = t->setup;
 	a_time = t->active;
 	if ((s_clc = (s_time * system_bus_speed + 999999) / 1000000) >= 8)
@@ -171,16 +172,9 @@
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-	drive->current_speed = speed;
-
 	return ide_config_drive_speed(drive, speed);
 }
 
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	ali15x3_tune_drive(drive, 5);
-}
-
 #ifdef CONFIG_BLK_DEV_IDEDMA
 static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
 {
@@ -253,7 +247,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive);
+		ali15x3_tune_drive(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
@@ -264,7 +258,7 @@
 static int ali15x3_udma_init(struct ata_device *drive, struct request *rq)
 {
 	if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
-		return 1;	/* try PIO instead of DMA */
+		return ide_stopped;	/* try PIO instead of DMA */
 
 	return udma_pci_init(drive, rq);
 }
diff -Nru a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
--- a/drivers/ide/amd74xx.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/amd74xx.c	Sun Jun 16 19:31:40 2002
@@ -153,8 +153,6 @@
 
 	amd_set_speed(drive->channel->pci_dev, drive->dn, &t);
 
-	drive->current_speed = speed;
-
 	return 0;
 }
 
diff -Nru a/drivers/ide/ata-timing.c b/drivers/ide/ata-timing.c
--- a/drivers/ide/ata-timing.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/ata-timing.c	Sun Jun 16 19:31:40 2002
@@ -137,6 +137,20 @@
 }
 
 /*
+ * Just get a pointer to the struct describing the timing values used commonly
+ * for a particular mode.
+ */
+struct ata_timing* ata_timing_data(short speed)
+{
+	struct ata_timing *t;
+
+	for (t = ata_timing; t->mode != speed; t++)
+		if (t->mode < 0)
+			return NULL;
+	return t;
+}
+
+/*
  * This is just unit conversion.
  */
 void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q,
@@ -179,17 +193,15 @@
 }
 
 /*
- * Just get a pointer to the struct describing the timing values used commonly
- * for a particular mode.
+ * Not all controllers can do separate timing for 8-bit command transfers
+ * and 16-bit data transfers.
  */
-struct ata_timing* ata_timing_data(short speed)
-{
-	struct ata_timing *t;
 
-	for (t = ata_timing; t->mode != speed; t++)
-		if (t->mode < 0)
-			return NULL;
-	return t;
+void ata_timing_merge_8bit(struct ata_timing *t)
+{
+	t->active = max(t->active, t->act8b);
+	t->recover = max(t->recover, t->rec8b);
+	t->cycle = max(t->cycle, t->cyc8b);
 }
 
 int ata_timing_compute(struct ata_device *drive, short speed, struct ata_timing *t,
@@ -204,6 +216,8 @@
 	if (!(s = ata_timing_data(speed)))
 		return -EINVAL;
 
+	memcpy(t, s, sizeof(struct ata_timing));
+
 	/* If the drive is an EIDE drive, it can tell us it needs extended
 	 * PIO/MWDMA cycle timing.
 	 */
@@ -229,7 +243,7 @@
 	/* Convert the timing to bus clock counts.
 	 */
 
-	ata_timing_quantize(s, t, T, UT);
+	ata_timing_quantize(t, t, T, UT);
 
 	/* Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
 	 * S.M.A.R.T and some other commands. We have to ensure that the DMA
@@ -255,4 +269,26 @@
 	}
 
 	return 0;
+}
+
+u8 ata_best_pio_mode(struct ata_device *drive)
+{
+	static u16 eide_pio_timing[6] = { 600, 383, 240, 180, 120, 90 };
+	u16 pio_min;
+	u8 pio;
+
+	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
+
+	/* downgrade mode if necessary */
+	pio_min = (pio > 2) ? drive->id->eide_pio_iordy : drive->id->eide_pio;
+
+	if (pio_min)
+		while (pio && pio_min > eide_pio_timing[pio])
+			pio--;
+
+	if (!pio && drive->id->tPIO)
+		return XFER_PIO_SLOW;
+
+	/* don't allow XFER_PIO_5 for now */
+	return XFER_PIO_0 + min_t(u8, pio, 4);
 }
diff -Nru a/drivers/ide/ata-timing.h b/drivers/ide/ata-timing.h
--- a/drivers/ide/ata-timing.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/ata-timing.h	Sun Jun 16 19:31:41 2002
@@ -69,7 +69,7 @@
 #define XFER_EPIO	0x01
 #define XFER_PIO	0x00
 
-/* External interface to host chips chanell timing setup.
+/* External interface to host chips channel timing setup.
  *
  * It's a bit elaborate due to the legacy we have to bear.
  */
@@ -79,8 +79,10 @@
 		int T, int UT);
 extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b,
 		struct ata_timing *m, unsigned int what);
+void ata_timing_merge_8bit(struct ata_timing *t);
 extern struct ata_timing* ata_timing_data(short speed);
 extern int ata_timing_compute(struct ata_device *drive,
 		short speed, struct ata_timing *t, int T, int UT);
+extern u8 ata_best_pio_mode(struct ata_device *drive);
 
 #endif
diff -Nru a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
--- a/drivers/ide/cmd64x.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/cmd64x.c	Sun Jun 16 19:31:40 2002
@@ -7,8 +7,7 @@
  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
  *           Note, this driver is not used at all on other systems because
  *           there the "BIOS" has done all of the following already.
- *           Due to massive hardware bugs, UltraDMA is only supported
- *           on the 646U2 and not on the 646U.
+ *           Due to massive hardware bugs, UDMA is not supported on the 646U.
  *
  * Copyright (C) 1998		Eddie C. Dost <ecd@skynet.be>
  * Copyright (C) 1998		David S. Miller <davem@redhat.com>
@@ -28,10 +27,6 @@
 #include "ata-timing.h"
 #include "pcihost.h"
 
-#ifndef SPLIT_BYTE
-#define SPLIT_BYTE(B,H,L)	((H)=(B>>4), (L)=(B-((B>>4)<<4)))
-#endif
-
 #define CMD_DEBUG 0
 
 #if CMD_DEBUG
@@ -157,52 +152,53 @@
 }
 
 /*
- * Attempts to set the interface PIO mode.
- * The preferred method of selecting PIO modes (e.g. mode 4) is
- * "echo 'piomode:4' > /proc/ide/hdx/settings".  Special cases are
+ * Attempts to set the interface PIO mode. Special cases are
  * 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
  * Called with 255 at boot time.
  */
-static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted)
+static void cmd64x_tuneproc(struct ata_device *drive, u8 pio)
 {
-	int recovery_time, clock_time;
-	byte recovery_count2, cycle_count;
-	int setup_count, active_count, recovery_count;
+	int T;
+	u8 speed, active, recover;
 	struct ata_timing *t;
 
-	switch (mode_wanted) {
+	switch (pio) {
+		/* FIXME: b0rken  --bkz */
 		case 8: /* set prefetch off */
 		case 9: /* set prefetch on */
-			mode_wanted &= 1;
+			pio &= 1;
 			/*set_prefetch_mode(index, mode_wanted);*/
-			cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis");
+			cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name,
+				  pio ? "en" : "dis");
 			return;
-		case 255: mode_wanted = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
 	}
 
-	t = ata_timing_data(XFER_PIO_0 + min_t(byte, mode_wanted, 4));
+	if (pio == 255)
+		speed = ata_best_pio_mode(drive);
+	else
+		speed = XFER_PIO_0 + min_t(u8, pio, 4);
+
+	t = ata_timing_data(speed);
 
 	/*
 	 * I copied all this complicated stuff from cmd640.c and made a few minor changes.
 	 * For now I am just going to pray that it is correct.
 	 */
+	/* FIXME: verify it  --bkz */
+
+	T = 1000000000 / system_bus_speed;
+	ata_timing_quantize(t, t, T, T);
+
+	/* FIXME: maybe switch to ata_timing_compute()  --bkz */
+	recover = t->cycle - (t->setup + t->active);
+	active = t->active;
 
-	recovery_time = t->cycle - (t->setup + t->active);
-	clock_time = 1000000 / system_bus_speed;
-	cycle_count = (t->cycle + clock_time - 1) / clock_time;
-	setup_count = (t->setup + clock_time - 1) / clock_time;
-	active_count = (t->active + clock_time - 1) / clock_time;
-
-	recovery_count = (recovery_time + clock_time - 1) / clock_time;
-	recovery_count2 = cycle_count - (setup_count + active_count);
-	if (recovery_count2 > recovery_count)
-		recovery_count = recovery_count2;
-	if (recovery_count > 16) {
-		active_count += recovery_count - 16;
-		recovery_count = 16;
+	if (recover > 16) {
+		active += recover - 16;
+		recover = 16;
 	}
-	if (active_count > 16)
-		active_count = 16; /* maximum allowed by cmd646 */
+	if (active > 16)
+		active = 16;	/* maximum allowed by CMD646 */
 
 	/*
 	 * In a perfect world, we might set the drive pio mode here
@@ -212,11 +208,13 @@
 	 *	1) this is the wrong place to do it (proper is do_special() in ide.c)
 	 * 	2) in practice this is rarely, if ever, necessary
 	 */
-	program_drive_counts (drive, setup_count, active_count, recovery_count);
+	program_drive_counts(drive, t->setup, active, recover);
 
 	cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns), clocks=%d/%d/%d\n",
-		drive->name, t.mode - XFER_PIO_0, mode_wanted, cycle_time,
-		setup_count, active_count, recovery_count);
+		drive->name, t.mode - XFER_PIO_0, pio, t->cycle,
+		t->setup, active, recover);
+
+	ide_config_drive_speed(drive, speed);
 }
 
 static int cmd64x_ratemask(struct ata_device *drive)
@@ -236,7 +234,7 @@
 			break;
 		case PCI_DEVICE_ID_CMD_646:
 		{
-			unsigned int class_rev	= 0;
+			u32 class_rev;
 			pci_read_config_dword(dev,
 				PCI_CLASS_REVISION, &class_rev);
 			class_rev &= 0xff;
@@ -256,9 +254,7 @@
 				case 0x07:
 				case 0x05:
 					map |= XFER_UDMA;
-				case 0x03:
-				case 0x01:
-				default:
+				default: /* 0x03, 0x01 */
 					break;
 			}
 		}
@@ -272,13 +268,12 @@
 	return map;
 }
 
-static byte cmd680_taskfile_timing(struct ata_channel *hwif)
+static u8 cmd680_taskfile_timing(struct ata_channel *ch)
 {
-	struct pci_dev *dev	= hwif->pci_dev;
-	byte addr_mask		= (hwif->unit) ? 0xB2 : 0xA2;
-	unsigned short		timing;
+	u8 addr_mask = (ch->unit) ? 0xB2 : 0xA2;
+	u16 timing;
 
-	pci_read_config_word(dev, addr_mask, &timing);
+	pci_read_config_word(ch->pci_dev, addr_mask, &timing);
 
 	switch (timing) {
 		case 0x10c1:	return 4;
@@ -290,12 +285,25 @@
 	}
 }
 
-static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted)
+static void cmd680_tuneproc(struct ata_device *drive, u8 pio)
 {
-	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-	byte			drive_pci;
-	unsigned short		speedt;
+	struct ata_channel *ch = drive->channel;
+	struct pci_dev *dev = ch->pci_dev;
+	u8 unit	= (drive->select.b.unit & 0x01);
+	u8 addr_mask = (ch->unit) ? 0x84 : 0x80;
+	u8 drive_pci, mode_pci, speed;
+	u8 channel_timings = cmd680_taskfile_timing(ch);
+	u16 speedt;
+
+	pci_read_config_byte(dev, addr_mask, &mode_pci);
+	mode_pci &= ~(unit ? 0x30 : 0x03);
+
+	if (pio == 255)
+		pio = ata_best_pio_mode(drive) - XFER_PIO_0;
+
+	/* WARNING PIO timing mess is going to happen b/w devices, argh */
+	if ((channel_timings != pio) && (pio > channel_timings))
+		pio = channel_timings;
 
 	switch (drive->dn) {
 		case 0: drive_pci = 0xA4; break;
@@ -309,7 +317,7 @@
 
 	/* cheat for now and use the docs */
 //	switch(cmd680_taskfile_timing(hwif)) {
-	switch(mode_wanted) {
+	switch(pio) {
 		case 4:		speedt = 0x10c1; break;
 		case 3:		speedt = 0x10C3; break;
 		case 2:		speedt = 0x1104; break;
@@ -318,55 +326,13 @@
 		default:	speedt = 0x328A; break;
 	}
 	pci_write_config_word(dev, drive_pci, speedt);
-}
-
-static void config_cmd64x_chipset_for_pio(struct ata_device *drive, byte set_speed)
-{
-	byte speed	= 0x00;
-	byte set_pio	= ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	cmd64x_tuneproc(drive, set_pio);
-	speed = XFER_PIO_0 + set_pio;
-	if (set_speed)
-		(void) ide_config_drive_speed(drive, speed);
-}
 
-static void config_cmd680_chipset_for_pio(struct ata_device *drive, byte set_speed)
-{
-	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-	u8 unit			= (drive->select.b.unit & 0x01);
-	u8 addr_mask		= (hwif->unit) ? 0x84 : 0x80;
-	u8 speed		= 0x00;
-	u8 mode_pci		= 0x00;
-	u8 channel_timings	= cmd680_taskfile_timing(hwif);
-	u8 set_pio		= ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	pci_read_config_byte(dev, addr_mask, &mode_pci);
-	mode_pci &= ~((unit) ? 0x30 : 0x03);
-
-	/* WARNING PIO timing mess is going to happen b/w devices, argh */
-	if ((channel_timings != set_pio) && (set_pio > channel_timings))
-		set_pio = channel_timings;
-
-	cmd680_tuneproc(drive, set_pio);
-	speed = XFER_PIO_0 + set_pio;
-	if (set_speed) {
-		(void) ide_config_drive_speed(drive, speed);
-		drive->current_speed = speed;
-	}
-}
+	speed = XFER_PIO_0 + min_t(u8, pio, 4);
 
-static void config_chipset_for_pio(struct ata_device *drive, byte set_speed)
-{
-        if (drive->channel->pci_dev->device == PCI_DEVICE_ID_CMD_680) {
-		config_cmd680_chipset_for_pio(drive, set_speed);
-	} else {
-		config_cmd64x_chipset_for_pio(drive, set_speed);
-	}
+	ide_config_drive_speed(drive, speed);
 }
 
-static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
+static int cmd64x_tune_chipset(struct ata_device *drive, u8 speed)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	struct ata_channel *hwif = drive->channel;
@@ -375,57 +341,73 @@
 	u8 unit			= (drive->select.b.unit & 0x01);
 	u8 pciU			= (hwif->unit) ? UDIDETCR1 : UDIDETCR0;
 	u8 pciD			= (hwif->unit) ? BMIDESR1 : BMIDESR0;
-	u8 regU			= 0;
-	u8 regD			= 0;
+	u8 regU, regD, U = 0, D = 0;
 
 	if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
 		return 1;
 
-	(void) pci_read_config_byte(dev, pciD, &regD);
-	(void) pci_read_config_byte(dev, pciU, &regU);
+	pci_read_config_byte(dev, pciD, &regD);
+	pci_read_config_byte(dev, pciU, &regU);
+
+	/* unit 1 - 01000000b	unit 0 - 00100000b */
 	regD &= ~(unit ? 0x40 : 0x20);
+
+	/* unit 1 - 11001010b	unit 0 - 00110101b */
 	regU &= ~(unit ? 0xCA : 0x35);
-	(void) pci_write_config_byte(dev, pciD, regD);
-	(void) pci_write_config_byte(dev, pciU, regU);
 
-	(void) pci_read_config_byte(dev, pciD, &regD);
-	(void) pci_read_config_byte(dev, pciU, &regU);
+	pci_write_config_byte(dev, pciD, regD);
+	pci_write_config_byte(dev, pciU, regU);
+
+	pci_read_config_byte(dev, pciD, &regD);
+	pci_read_config_byte(dev, pciU, &regU);
+
 	switch(speed) {
-		case XFER_UDMA_5:	regU |= (unit ? 0x0A : 0x05); break;
-		case XFER_UDMA_4:	regU |= (unit ? 0x4A : 0x15); break;
-		case XFER_UDMA_3:	regU |= (unit ? 0x8A : 0x25); break;
-		case XFER_UDMA_2:	regU |= (unit ? 0x42 : 0x11); break;
-		case XFER_UDMA_1:	regU |= (unit ? 0x82 : 0x21); break;
-		case XFER_UDMA_0:	regU |= (unit ? 0xC2 : 0x31); break;
-		case XFER_MW_DMA_2:	regD |= (unit ? 0x40 : 0x10); break;
-		case XFER_MW_DMA_1:	regD |= (unit ? 0x80 : 0x20); break;
-		case XFER_MW_DMA_0:	regD |= (unit ? 0xC0 : 0x30); break;
-		case XFER_SW_DMA_2:	regD |= (unit ? 0x40 : 0x10); break;
-		case XFER_SW_DMA_1:	regD |= (unit ? 0x80 : 0x20); break;
-		case XFER_SW_DMA_0:	regD |= (unit ? 0xC0 : 0x30); break;
+		/* FIXME: use tables  --bkz */
+		case XFER_UDMA_5:	U = 0x05; break;
+		case XFER_UDMA_4:	U = 0x15; break;
+		case XFER_UDMA_3:	U = 0x25; break;
+		case XFER_UDMA_2:	U = 0x11; break;
+		case XFER_UDMA_1:	U = 0x21; break;
+		case XFER_UDMA_0:	U = 0x31; break;
+		case XFER_MW_DMA_2:	D = 0x10; break;
+		case XFER_MW_DMA_1:	D = 0x20; break;
+		case XFER_MW_DMA_0:	D = 0x30; break;
+		case XFER_SW_DMA_2:	D = 0x10; break;
+		case XFER_SW_DMA_1:	D = 0x20; break;
+		case XFER_SW_DMA_0:	D = 0x30; break;
 #else
 	switch(speed) {
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-		case XFER_PIO_4:	cmd64x_tuneproc(drive, 4); break;
-		case XFER_PIO_3:	cmd64x_tuneproc(drive, 3); break;
-		case XFER_PIO_2:	cmd64x_tuneproc(drive, 2); break;
-		case XFER_PIO_1:	cmd64x_tuneproc(drive, 1); break;
-		case XFER_PIO_0:	cmd64x_tuneproc(drive, 0); break;
-
+		case XFER_PIO_4:
+		case XFER_PIO_3:
+		case XFER_PIO_2:
+		case XFER_PIO_1:
+		case XFER_PIO_0:
+			cmd64x_tuneproc(drive, speed - XFER_PIO_0);
+			/* FIXME: error checking  --bkz */
+			return 0;
 		default:
 			return 1;
 	}
 
+	cmd64x_tuneproc(drive, 255);
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	(void) pci_write_config_byte(dev, pciU, regU);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 
-	drive->current_speed = speed;
+	if (unit) {
+		if (speed >= XFER_UDMA_0)
+			regU |= (((U & 0xf0) << 2) | ((U & 0x0f) << 1));
+		else if (speed >= XFER_SW_DMA_0)
+			regD |= ((D & 0xf0) << 2);
+	} else {
+		regU |= U;
+		regD |= D;
+	}
+
+	pci_write_config_byte(dev, pciU, regU);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
 	regD |= (unit ? 0x40 : 0x20);
-	(void) pci_write_config_byte(dev, pciD, regD);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+	pci_write_config_byte(dev, pciD, regD);
+#endif
 
 	return ide_config_drive_speed(drive, speed);
 }
@@ -436,23 +418,21 @@
 	struct pci_dev *dev	= hwif->pci_dev;
 	u8 addr_mask		= (hwif->unit) ? 0x84 : 0x80;
 	u8 unit			= (drive->select.b.unit & 0x01);
-	u8 dma_pci		= 0;
-	u8 udma_pci		= 0;
-	u8 mode_pci		= 0;
-	u8 scsc			= 0;
-	u16 ultra		= 0;
-	u16 multi		= 0;
+	u8 dma_pci, udma_pci;
+	u8 mode_pci, scsc, scsc_on = 0;
+	u16 ultra, multi;
 
         pci_read_config_byte(dev, addr_mask, &mode_pci);
 	pci_read_config_byte(dev, 0x8A, &scsc);
 
         switch (drive->dn) {
-		case 0: dma_pci = 0xA8; udma_pci = 0xAC; break;
-		case 1: dma_pci = 0xAA; udma_pci = 0xAE; break;
-		case 2: dma_pci = 0xB8; udma_pci = 0xBC; break;
-		case 3: dma_pci = 0xBA; udma_pci = 0xBE; break;
+		case 0: dma_pci = 0xA8; break;
+		case 1: dma_pci = 0xAA; break;
+		case 2: dma_pci = 0xB8; break;
+		case 3: dma_pci = 0xBA; break;
 		default: return 1;
 	}
+	udma_pci = dma_pci + 4;
 
 	pci_read_config_byte(dev, addr_mask, &mode_pci);
 	mode_pci &= ~((unit) ? 0x30 : 0x03);
@@ -464,46 +444,38 @@
 		pci_read_config_byte(dev, 0x8A, &scsc);
 	}
 
+	if (speed >= XFER_UDMA_0) {
+		ultra &= ~0x3F;
+		multi = 0x10C1;
+		scsc_on = ((scsc & 0x30) == 0x00) ? 1 : 0;
+	}
+
 	switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 		case XFER_UDMA_6:
-			if ((scsc & 0x30) == 0x00)
+			if (scsc_on)
 				goto speed_break;
-			multi = 0x10C1;
-			ultra &= ~0x3F;
 			ultra |= 0x01;
 			break;
 speed_break :
 			speed = XFER_UDMA_5;
 		case XFER_UDMA_5:
-			multi = 0x10C1;
-			ultra &= ~0x3F;
-			ultra |= (((scsc & 0x30) == 0x00) ? 0x01 : 0x02);
+			ultra |= (scsc_on ? 0x01 : 0x02);
 			break;
 		case XFER_UDMA_4:
-			multi = 0x10C1;
-			ultra &= ~0x3F;
-			ultra |= (((scsc & 0x30) == 0x00) ? 0x02 : 0x03);
+			ultra |= (scsc_on ? 0x02 : 0x03);
 			break;
 		case XFER_UDMA_3:
-			multi = 0x10C1;
-			ultra &= ~0x3F;
-			ultra |= (((scsc & 0x30) == 0x00) ? 0x04 : 0x05);
+			ultra |= (scsc_on ? 0x04 : 0x05);
 			break;
 		case XFER_UDMA_2:
-			multi = 0x10C1;
-			ultra &= ~0x3F;
-			ultra |= (((scsc & 0x30) == 0x00) ? 0x05 : 0x07);
+			ultra |= (scsc_on ? 0x05 : 0x07);
 			break;
 		case XFER_UDMA_1:
-			multi = 0x10C1;
-			ultra &= ~0x3F;
-			ultra |= (((scsc & 0x30) == 0x00) ? 0x07 : 0x0B);
+			ultra |= (scsc_on ? 0x07 : 0x0B);
 			break;
 		case XFER_UDMA_0:
-			multi = 0x10C1;
-			ultra &= ~0x3F;
-			ultra |= (((scsc & 0x30) == 0x00) ? 0x0C : 0x0F);
+			ultra |= (scsc_on ? 0x0C : 0x0F);
 			break;
 		case XFER_MW_DMA_2:
 			multi = 0x10C1;
@@ -515,18 +487,19 @@
 			multi = 0x2208;
 			break;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-		case XFER_PIO_4:	cmd680_tuneproc(drive, 4); break;
-		case XFER_PIO_3:	cmd680_tuneproc(drive, 3); break;
-		case XFER_PIO_2:	cmd680_tuneproc(drive, 2); break;
-		case XFER_PIO_1:	cmd680_tuneproc(drive, 1); break;
-		case XFER_PIO_0:	cmd680_tuneproc(drive, 0); break;
+		case XFER_PIO_4:
+		case XFER_PIO_3:
+		case XFER_PIO_2:
+		case XFER_PIO_1:
+		case XFER_PIO_0:
+			cmd680_tuneproc(drive, speed - XFER_PIO_0);
+			/* FIXME: error checking  --bkz */
+			return 0;
 		default:
 			return 1;
 	}
 
-	if (speed >= XFER_MW_DMA_0) 
-		config_cmd680_chipset_for_pio(drive, 0);
-
+	cmd680_tuneproc(drive, 255);
 	if (speed >= XFER_UDMA_0)
 		mode_pci |= ((unit) ? 0x30 : 0x03);
 	else if (speed >= XFER_MW_DMA_0)
@@ -538,8 +511,6 @@
 	pci_write_config_word(dev, dma_pci, multi);
 	pci_write_config_word(dev, udma_pci, ultra);
 
-	drive->current_speed = speed;
-
 	return ide_config_drive_speed(drive, speed);
 }
 
@@ -549,11 +520,6 @@
 	int map;
 	u8 mode;
 
-	if (drive->type != ATA_DISK) {
-		cmdprintk("CMD64X: drive is not a disk at double check, inital check failed!!\n");
-		return 0;
-	}
-
 	if (udma)
 		map = cmd64x_ratemask(drive);
 	else
@@ -561,22 +527,18 @@
 
 	mode = ata_timing_mode(drive, map);
 
-	if (mode < XFER_SW_DMA_0) {
-		config_chipset_for_pio(drive, 1);
-		return 0;
-	}
-
-	config_chipset_for_pio(drive, 0);
 	return !drive->channel->speedproc(drive, mode);
 }
 
-static int cmd64x_config_drive_for_dma(struct ata_device *drive)
+static int cmd6xx_udma_setup(struct ata_device *drive)
 {
 	struct hd_driveid *id	= drive->id;
 	struct ata_channel *hwif = drive->channel;
 	int on = 1;
 	int verbose = 1;
 
+	hwif->tuneproc(drive, 255);
+
 	if ((id != NULL) && ((id->capability & 1) != 0) &&
 	    hwif->autodma && (drive->type == ATA_DISK)) {
 		/* Consult the list of known "bad" drives */
@@ -619,7 +581,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive, 1);
+		hwif->tuneproc(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
@@ -627,11 +589,6 @@
 	return 0;
 }
 
-static int cmd680_udma_setup(struct ata_device *drive)
-{
-	return cmd64x_config_drive_for_dma(drive);
-}
-
 static int cmd64x_udma_stop(struct ata_device *drive)
 {
 	struct ata_channel *ch = drive->channel;
@@ -680,11 +637,10 @@
 	return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
 }
 
-static int cmd64x_udma_setup(struct ata_device *drive)
-{
-	return cmd64x_config_drive_for_dma(drive);
-}
-
+/*
+ * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
+ * event order for DMA transfers.
+ */
 static int cmd646_1_udma_stop(struct ata_device *drive)
 {
 	struct ata_channel *ch = drive->channel;
@@ -699,14 +655,6 @@
 	return (dma_stat & 7) != 4;		/* verify good DMA status */
 }
 
-/*
- * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
- * event order for DMA transfers.
- */
-static int cmd646_1_udma_setup(struct ata_device *drive)
-{
-	return cmd64x_config_drive_for_dma(drive);
-}
 #endif
 
 static int cmd680_busproc(struct ata_device * drive, int state)
@@ -775,8 +723,8 @@
 
 static unsigned int cmd64x_pci_init(struct pci_dev *dev)
 {
-	unsigned char mrdmode;
-	unsigned int class_rev;
+	u8 mrdmode;
+	u32 class_rev;
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
@@ -808,10 +756,7 @@
 				}
 			printk("\n");
                         break;
-		case PCI_DEVICE_ID_CMD_648:
-		case PCI_DEVICE_ID_CMD_649:
-			break;
-		default:
+		default: /* 648, 649 */
 			break;
 	}
 
@@ -863,8 +808,8 @@
 
 static unsigned int cmd680_ata66(struct ata_channel *hwif)
 {
-	byte ata66	= 0;
-	byte addr_mask	= (hwif->unit) ? 0xB0 : 0xA0;
+	u8 ata66;
+	u8 addr_mask = (hwif->unit) ? 0xB0 : 0xA0;
 
 	pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66);
 	return (ata66 & 0x01) ? 1 : 0;
@@ -872,8 +817,8 @@
 
 static unsigned int cmd64x_ata66(struct ata_channel *hwif)
 {
-	byte ata66 = 0;
-	byte mask = (hwif->unit) ? 0x02 : 0x01;
+	u8 ata66;
+	u8 mask = (hwif->unit) ? 0x02 : 0x01;
 
 	pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66);
 	return (ata66 & mask) ? 1 : 0;
@@ -881,8 +826,7 @@
 
 static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif)
 {
-	struct pci_dev *dev	= hwif->pci_dev;
-	if (dev->device == PCI_DEVICE_ID_CMD_680)
+	if (hwif->pci_dev->device == PCI_DEVICE_ID_CMD_680)
 		return cmd680_ata66(hwif);
 	return cmd64x_ata66(hwif);
 }
@@ -890,7 +834,7 @@
 static void __init cmd64x_init_channel(struct ata_channel *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
-	unsigned int class_rev;
+	u32 class_rev;
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
@@ -903,7 +847,7 @@
 			hwif->busproc	= cmd680_busproc;
 #ifdef CONFIG_BLK_DEV_IDEDMA
 			if (hwif->dma_base)
-				hwif->udma_setup = cmd680_udma_setup;
+				hwif->udma_setup = cmd6xx_udma_setup;
 #endif
 			hwif->resetproc = cmd680_reset;
 			hwif->speedproc	= cmd680_tune_chipset;
@@ -914,7 +858,7 @@
 		case PCI_DEVICE_ID_CMD_643:
 #ifdef CONFIG_BLK_DEV_IDEDMA
 			if (hwif->dma_base) {
-				hwif->udma_setup = cmd64x_udma_setup;
+				hwif->udma_setup = cmd6xx_udma_setup;
 				hwif->udma_stop	= cmd64x_udma_stop;
 				hwif->udma_irq_status = cmd64x_udma_irq_status;
 			}
@@ -926,11 +870,10 @@
 			hwif->chipset = ide_cmd646;
 #ifdef CONFIG_BLK_DEV_IDEDMA
 			if (hwif->dma_base) {
+				hwif->udma_setup = cmd6xx_udma_setup;
 				if (class_rev == 0x01) {
-					hwif->udma_setup = cmd646_1_udma_setup;
 					hwif->udma_stop = cmd646_1_udma_stop;
 				} else {
-					hwif->udma_setup = cmd64x_udma_setup;
 					hwif->udma_stop = cmd64x_udma_stop;
 					hwif->udma_irq_status = cmd64x_udma_irq_status;
 				}
@@ -1007,9 +950,8 @@
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(chipsets); ++i) {
+	for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
 		ata_register_chipset(&chipsets[i]);
-	}
 
         return 0;
 }
diff -Nru a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
--- a/drivers/ide/cy82c693.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/cy82c693.c	Sun Jun 16 19:31:39 2002
@@ -21,12 +21,9 @@
  *   hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
  * - this is my first linux driver, so there's probably a lot  of room
  *   for optimizations and bug fixing, so feel free to do it.
- * - use idebus=xx parameter to set PCI bus speed - needed to calc
- *   timings for PIO modes (default will be 40)
- * - if using PIO mode it's a good idea to set the PIO mode and
- *   32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
  * - I had some problems with my IBM DHEA with PIO modes < 2
  *   (lost interrupts) ?????
+ *   FIXME: probably because we set wrong timings for 8bit  --bkz
  * - first tests with DMA look okay, they seem to work, but there is a
  *   problem with sound - the BusMaster IDE TimeOut should fixed this
  *
@@ -83,6 +80,9 @@
 /* here are the offset definitions for the registers */
 #define CY82_IDE_CMDREG		0x04
 #define CY82_IDE_ADDRSETUP	0x48
+
+#define CYPRESS_TIMINGS		0x4C
+
 #define CY82_IDE_MASTER_IOR	0x4C
 #define CY82_IDE_MASTER_IOW	0x4D
 #define CY82_IDE_SLAVE_IOR	0x4E
@@ -105,19 +105,20 @@
 #define CY82C963_MIN_BUS_SPEED	25
 #define CY82C963_MAX_BUS_SPEED	33
 
-/* the struct for the PIO mode timings */
+/* the struct for the PIO mode timings (in clocks) */
 typedef struct pio_clocks_s {
-        byte	address_time;		/* Address setup (clocks) */
-	byte	time_16r;		/* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
-	byte	time_16w;		/* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
-	byte	time_8;			/* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
+	u8 address_time;	/* Address setup */
+	/* 0xF0=Active/data, 0x0F=Recovery */
+	u8 time_16r;		/* 16bit IOR */
+	u8 time_16w;		/* 16bit IOW */
+	u8 time_8;		/* 8bit */
 } pio_clocks_t;
 
 /*
  * calc clocks using bus_speed
  * returns (rounded up) time in bus clocks for time in ns
  */
-static int calc_clk (int time, int bus_speed)
+static u8 calc_clk(int time, int bus_speed)
 {
 	int clocks;
 
@@ -129,7 +130,7 @@
 	if (clocks > 0x0F)
 		clocks = 0x0F;
 
-	return clocks;
+	return (u8)clocks;
 }
 
 /*
@@ -140,7 +141,8 @@
  *       for mode 3 and 4 drives 8 and 16-bit timings are the same
  *
  */
-static void compute_clocks (byte pio, pio_clocks_t *p_pclk)
+/* FIXME: use generic ata-timings library  --bkz */
+static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
 {
 	struct ata_timing *t;
 	int clk1, clk2;
@@ -149,34 +151,33 @@
 
 	/* we don't check against CY82C693's min and max speed,
 	 * so you can play with the idebus=xx parameter
+	 * FIXME: warn about going out of specification  --bkz
 	 */
 
 	if (pio > CY82C693_MAX_PIO)
 		pio = CY82C693_MAX_PIO;
 
-	/* let's calc the address setup time clocks */
-	p_pclk->address_time = (byte)calc_clk(t->setup, system_bus_speed);
+	/* address setup */
+	p_pclk->address_time = calc_clk(t->setup, system_bus_speed);
 
-	/* let's calc the active and recovery time clocks */
+	/* active */
 	clk1 = calc_clk(t->active, system_bus_speed);
 
-	/* calc recovery timing */
-	clk2 =	t->cycle - t->active - t->setup;
-
-	clk2 = calc_clk(clk2, system_bus_speed);
+	/* FIXME: check why not t->cycle - t->active ?  --bkz */
+	/* recovery */
+	clk2 = calc_clk(t->cycle - t->active - t->setup, system_bus_speed);
 
-	clk1 = (clk1<<4)|clk2;	/* combine active and recovery clocks */
+	clk1 = (clk1 << 4) | clk2; /* combine active and recovery clocks */
 
 	/* note: we use the same values for 16bit IOR and IOW
          *	those are all the same, since I don't have other
 	 *	timings than those from ata-timing.h
 	 */
+	p_pclk->time_16w = p_pclk->time_16r = clk1;
 
-	p_pclk->time_16r = (byte)clk1;
-	p_pclk->time_16w = (byte)clk1;
-
+	/* FIXME: ugh...  --bkz */
 	/* what are good values for 8bit ?? */
-	p_pclk->time_8 = (byte)clk1;
+	p_pclk->time_8 = clk1;
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -203,7 +204,7 @@
 	data = IN_BYTE(CY82_DATA_PORT);
 
 	printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", drive->name, drive->channel->unit, drive->select.b.unit, (data&0x3), ((data>>2)&1));
-#endif /* CY82C693_DEBUG_LOGS */
+#endif
 
 	data = (byte)mode|(byte)(single<<2);
 
@@ -212,7 +213,7 @@
 
 #if CY82C693_DEBUG_INFO
 	printk (KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", drive->name, drive->channel->unit, drive->select.b.unit, mode, single);
-#endif /* CY82C693_DEBUG_INFO */
+#endif
 
 	/*
 	 * note: below we set the value for Bus Master IDE TimeOut Register
@@ -230,7 +231,7 @@
 
 #if CY82C693_DEBUG_INFO
 	printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", drive->name, data);
-#endif /* CY82C693_DEBUG_INFO */
+#endif
 }
 
 /*
@@ -276,7 +277,9 @@
 	struct pci_dev *dev = hwif->pci_dev;
 	pio_clocks_t pclk;
 	unsigned int addrCtrl;
+	u8 ior, iow, bit8;
 
+	/* FIXME: probaly broken  --bkz */
 	/* select primary or secondary channel */
 	if (hwif->index > 0) {  /* drive is on the secondary channel */
 		dev = pci_find_slot(dev->bus->number, dev->devfn+1);
@@ -286,40 +289,41 @@
 		}
 	}
 
+	if (drive->select.b.unit == 0) {
+		ior = CY82_IDE_MASTER_IOR;
+		iow = CY82_IDE_MASTER_IOW;
+		bit8 = CY82_IDE_MASTER_8BIT;
+	} else {
+		ior = CY82_IDE_SLAVE_IOR;
+		iow = CY82_IDE_SLAVE_IOW;
+		bit8 = CY82_IDE_SLAVE_8BIT;
+	}
+
 #if CY82C693_DEBUG_LOGS
 	/* for debug let's show the register values */
 
-	if (drive->select.b.unit == 0) {
-		/*
-		 * get master drive registers
-		 * address setup control register
-		 * is 32 bit !!!
-		 */
-		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
-		addrCtrl &= 0x0F;
-
-		/* now let's get the remaining registers */
-		pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r);
-		pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w);
-		pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8);
-	} else {
-		/*
-		 * set slave drive registers
-		 * address setup control register
-		 * is 32 bit !!!
-		 */
-		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
+	/*
+	 * get address setup control register
+	 * mine master or slave data
+	 */
+	pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 
+	if (drive->select.b.unit == 0)
+		addrCtrl &= 0x0F;
+	else {
 		addrCtrl &= 0xF0;
 		addrCtrl >>= 4;
-
-		/* now let's get the remaining registers */
-		pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r);
-		pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w);
-		pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8);
 	}
 
-	printk (KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
+	/* now let's get the remaining registers */
+	pci_read_config_byte(dev, ior, &pclk.time_16r);
+	pci_read_config_byte(dev, iow, &pclk.time_16w);
+	pci_read_config_byte(dev, bit8, &pclk.time_8);
+
+	printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X,"
+			 " ior=0x%X, iow=0x%X, 8bit=0x%X)\n",
+			 drive->name, hwif->unit, drive->select.b.unit,
+			 addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
 #endif /* CY82C693_DEBUG_LOGS */
 
         /* first let's calc the pio modes */
@@ -327,69 +331,41 @@
 
 #if CY82C693_DEBUG_INFO
 	printk (KERN_INFO "%s: Selected PIO mode %d\n", drive->name, pio);
-#endif /* CY82C693_DEBUG_INFO */
+#endif
 
         compute_clocks(pio, &pclk);  /* let's calc the values for this PIO mode */
 
-	/* now let's write  the clocks registers */
+	/*
+	 * set address setup control register
+	 */
+	pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 	if (drive->select.b.unit == 0) {
-		/*
-		 * set master drive
-		 * address setup control register
-		 * is 32 bit !!!
-		 */
-		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
-
-		addrCtrl &= (~0xF);
+		addrCtrl &= (~0x0F);
 		addrCtrl |= (unsigned int)pclk.address_time;
-		pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
-
-		/* now let's set the remaining registers */
-		pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
-		pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
-		pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
-
-		addrCtrl &= 0xF;
 	} else {
-		/*
-		 * set slave drive
-		 * address setup control register
-		 * is 32 bit !!!
-		 */
-		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
-
 		addrCtrl &= (~0xF0);
 		addrCtrl |= ((unsigned int)pclk.address_time<<4);
-		pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
-
-		/* now let's set the remaining registers */
-		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
-		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
-		pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
-
-		addrCtrl >>= 4;
-		addrCtrl &= 0xF;
 	}
+	pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
+
+	/* now let's set the remaining registers */
+	pci_write_config_byte(dev, ior, pclk.time_16r);
+	pci_write_config_byte(dev, iow, pclk.time_16w);
+	pci_write_config_byte(dev, bit8, pclk.time_8);
 
 #if CY82C693_DEBUG_INFO
-	printk (KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
-#endif /* CY82C693_DEBUG_INFO */
+	printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X,"
+			 " ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name,
+			 hwif->unit, drive->select.b.unit, addrCtrl,
+			 pclk.time_16r, pclk.time_16w, pclk.time_8);
+#endif
 }
 
-/*
- * this function is called during init and is used to setup the cy82c693 chip
- */
-/*
- * FIXME! "pci_init_cy82c693" really should replace
- * the "init_cy82c693_chip", it is the correct location to tinker/setup
- * the device prior to INIT.
- */
-
 static unsigned int __init pci_init_cy82c693(struct pci_dev *dev)
 {
 #ifdef CY82C693_SETDMA_CLOCK
-        byte data;
-#endif /* CY82C693_SETDMA_CLOCK */
+	u8 data;
+#endif
 
 	/* write info about this verion of the driver */
 	printk (KERN_INFO CY82_VERSION "\n");
@@ -402,7 +378,7 @@
 
 #if CY82C693_DEBUG_INFO
 	printk (KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", dev->name, data);
-#endif /* CY82C693_DEBUG_INFO */
+#endif
 
         /*
 	 * for some reason sometimes the DMA controller
diff -Nru a/drivers/ide/device.c b/drivers/ide/device.c
--- a/drivers/ide/device.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/device.c	Sun Jun 16 19:31:40 2002
@@ -80,7 +80,29 @@
 }
 
 /*
+ * Spin until the drive is no longer busy.
+ *
+ * Not exported, since it's not used within any modules.
+ */
+int ata_busy_poll(struct ata_device *drive, unsigned long timeout)
+{
+	/* spec allows drive 400ns to assert "BUSY" */
+	udelay(1);
+	if (!ata_status(drive, 0, BUSY_STAT)) {
+		timeout += jiffies;
+		while (!ata_status(drive, 0, BUSY_STAT)) {
+			if (time_after(jiffies, timeout))
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
  * Check the state of the status register.
+ *
+ * FIXME: Channel lock should be held.
  */
 int ata_status(struct ata_device *drive, u8 good, u8 bad)
 {
@@ -94,6 +116,57 @@
 EXPORT_SYMBOL(ata_status);
 
 /*
+ * Busy-wait for the drive status to be not "busy".  Check then the status for
+ * all of the "good" bits and none of the "bad" bits, and if all is okay it
+ * returns 0.  All other cases return 1 after invoking error handler -- caller
+ * should just return.
+ *
+ * This routine should get fixed to not hog the cpu during extra long waits..
+ * That could be done by busy-waiting for the first jiffy or two, and then
+ * setting a timer to wake up at half second intervals thereafter, until
+ * timeout is achieved, before timing out.
+ *
+ * Channel lock should be held.
+ */
+int ata_status_poll(struct ata_device *drive, u8 good, u8 bad,
+		unsigned long timeout,
+		struct request *rq, ide_startstop_t *startstop)
+{
+	int i;
+
+	/* bail early if we've exceeded max_failures */
+	if (drive->max_failures && (drive->failures > drive->max_failures)) {
+		*startstop = ide_stopped;
+
+		return 1;
+	}
+
+	if (ata_busy_poll(drive, timeout)) {
+		*startstop = ata_error(drive, rq, "status timeout");
+
+		return 1;
+	}
+
+	/*
+	 * Allow status to settle, then read it again.  A few rare drives
+	 * vastly violate the 400ns spec here, so we'll wait up to 10usec for a
+	 * "good" status rather than expensively fail things immediately.  This
+	 * fix courtesy of Matthew Faupel & Niccolo Rigacci.
+	 */
+	for (i = 0; i < 10; i++) {
+		udelay(1);
+		if (ata_status(drive, good, bad))
+			return 0;
+	}
+
+	*startstop = ata_error(drive, rq, "status error");
+
+	return 1;
+}
+
+EXPORT_SYMBOL(ata_status_poll);
+
+/*
  * Handle the nIEN - negated Interrupt ENable of the drive.
  * This is controlling whatever the drive will acnowlenge commands
  * with interrupts or not.
@@ -160,7 +233,7 @@
 }
 
 /*
- * Output a complete register file.
+ * Input a complete register file.
  */
 void ata_in_regfile(struct ata_device *drive, struct hd_drive_task_hdr *rf)
 {
diff -Nru a/drivers/ide/hd.c b/drivers/ide/hd.c
--- a/drivers/ide/hd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/hd.c	Sun Jun 16 19:31:39 2002
@@ -52,6 +52,7 @@
 #include <asm/uaccess.h>
 
 #define MAJOR_NR HD_MAJOR
+#define DEVICE_NR(device) (minor(device)>>6)
 #include <linux/blk.h>
 
 #ifdef __arm__
@@ -111,13 +112,16 @@
 
 static struct timer_list device_timer;
 
+#define TIMEOUT_VALUE (6*HZ)
+
 #define SET_TIMER							\
 	do {								\
 		mod_timer(&device_timer, jiffies + TIMEOUT_VALUE);	\
 	} while (0)
 
+static void (*do_hd)(void) = NULL;
 #define SET_HANDLER(x) \
-if ((DEVICE_INTR = (x)) != NULL) \
+if ((do_hd = (x)) != NULL) \
 	SET_TIMER; \
 else \
 	del_timer(&device_timer);
@@ -374,7 +378,7 @@
 		return;
 	dev = DEVICE_NR(CURRENT->rq_dev);
 	if (++CURRENT->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
-		end_request(0);
+		end_request(CURRENT, 0);
 		special_op[dev] = recalibrate[dev] = 1;
 	} else if (CURRENT->errors % RESET_FREQ == 0)
 		reset = 1;
@@ -424,7 +428,7 @@
 		(unsigned long) CURRENT->buffer+512));
 #endif
 	if (CURRENT->current_nr_sectors <= 0)
-		end_request(1);
+		end_request(CURRENT, 1);
 	if (i > 0) {
 		SET_HANDLER(&read_intr);
 		return;
@@ -462,7 +466,7 @@
 	--CURRENT->current_nr_sectors;
 	CURRENT->buffer += 512;
 	if (!i || (CURRENT->bio && !SUBSECTOR(i)))
-		end_request(1);
+		end_request(CURRENT, 1);
 	if (i > 0) {
 		SET_HANDLER(&write_intr);
 		outsw(HD_DATA,CURRENT->buffer,256);
@@ -493,7 +497,7 @@
 {
 	unsigned int dev;
 
-	DEVICE_INTR = NULL;
+	do_hd = NULL;
 
 	if (blk_queue_empty(QUEUE))
 		return;
@@ -507,7 +511,7 @@
 #ifdef DEBUG
 		printk("hd%c: too many errors\n", dev+'a');
 #endif
-		end_request(0);
+		end_request(CURRENT, 0);
 	}
 	cli();
 	hd_request();
@@ -523,7 +527,7 @@
 	}
 	if (hd_info[dev].head > 16) {
 		printk ("hd%c: cannot handle device with more than 16 heads - giving up\n", dev+'a');
-		end_request(0);
+		end_request(CURRENT, 0);
 	}
 	special_op[dev] = 0;
 	return 1;
@@ -543,14 +547,14 @@
 {
 	unsigned int dev, block, nsect, sec, track, head, cyl;
 
-	if (DEVICE_INTR)
+	if (do_hd)
 		return;
 repeat:
 	del_timer(&device_timer);
 	sti();
 
 	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+		do_hd = NULL;
 		return;
 	}
 
@@ -570,7 +574,7 @@
 		else
 			printk("hd%c: bad access: block=%d, count=%d\n",
 				(minor(CURRENT->rq_dev)>>6)+'a', block, nsect);
-		end_request(0);
+		end_request(CURRENT, 0);
 		goto repeat;
 	}
 
@@ -608,7 +612,7 @@
 			break;
 		default:
 			printk("unknown hd-command\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			break;
 		}
 	}
@@ -699,9 +703,9 @@
 	
 static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	void (*handler)(void) = DEVICE_INTR;
+	void (*handler)(void) = do_hd;
 
-	DEVICE_INTR = NULL;
+	do_hd = NULL;
 	del_timer(&device_timer);
 	if (!handler)
 		handler = unexpected_hd_interrupt;
diff -Nru a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c
--- a/drivers/ide/hpt34x.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/hpt34x.c	Sun Jun 16 19:31:39 2002
@@ -5,19 +5,7 @@
  * Copyright (C) 1998-2000	Andre Hedrick <andre@linux-ide.org>
  * May be copied or modified under the terms of the GNU General Public License
  *
- *
- * 00:12.0 Unknown mass storage controller:
- * Triones Technologies, Inc.
- * Unknown device 0003 (rev 01)
- *
- * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010)
- * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030)
- * hde: DMA 2  (0x0000 0x0002) (0x0000 0x0010)
- * hdf: DMA 2  (0x0002 0x0012) (0x0010 0x0030)
- * hdg: DMA 1  (0x0012 0x0052) (0x0030 0x0070)
- * hdh: DMA 1  (0x0052 0x0252) (0x0070 0x00f0)
- *
- * ide-pci.c reference
+ * ide-pci.c reference:
  *
  * Since there are two cards that report almost identically,
  * the only discernable difference is the values reported in pcicmd.
@@ -45,109 +33,42 @@
 #include "ata-timing.h"
 #include "pcihost.h"
 
-#ifndef SPLIT_BYTE
-# define SPLIT_BYTE(B,H,L)	((H)=(B>>4), (L)=(B-((B>>4)<<4)))
-#endif
-
 #define HPT343_DEBUG_DRIVE_INFO		0
 
-static void hpt34x_clear_chipset(struct ata_device *drive)
-{
-	unsigned int reg1	= 0, tmp1 = 0;
-	unsigned int reg2	= 0, tmp2 = 0;
-
-	pci_read_config_dword(drive->channel->pci_dev, 0x44, &reg1);
-	pci_read_config_dword(drive->channel->pci_dev, 0x48, &reg2);
-	tmp1 = ((0x00 << (3 * drive->dn)) | (reg1 & ~(7 << (3 * drive->dn))));
-	tmp2 = (reg2 & ~(0x11 << drive->dn));
-	pci_write_config_dword(drive->channel->pci_dev, 0x44, tmp1);
-	pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2);
-}
-
-static int hpt34x_tune_chipset(struct ata_device *drive, byte speed)
+static int hpt34x_tune_chipset(struct ata_device *drive, u8 speed)
 {
-	byte			hi_speed, lo_speed;
-	unsigned int reg1	= 0, tmp1 = 0;
-	unsigned int reg2	= 0, tmp2 = 0;
-
-	SPLIT_BYTE(speed, hi_speed, lo_speed);
-
-	if (hi_speed & 7) {
-		hi_speed = (hi_speed & 4) ? 0x01 : 0x10;
-	} else {
-		lo_speed <<= 5;
-		lo_speed >>= 5;
-	}
+	struct pci_dev *dev = drive->channel->pci_dev;
+	u8 udma = 0, pio = 0;
+	u32 reg1, reg2, tmp1, tmp2;
+
+	if (speed >= XFER_UDMA_0)
+		udma = 0x01;
+	else if (speed >= XFER_SW_DMA_0)
+		udma = 0x10;
+	else
+		pio = speed & 7;
 
-	pci_read_config_dword(drive->channel->pci_dev, 0x44, &reg1);
-	pci_read_config_dword(drive->channel->pci_dev, 0x48, &reg2);
-	tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
-	tmp2 = ((hi_speed << drive->dn) | reg2);
-	pci_write_config_dword(drive->channel->pci_dev, 0x44, tmp1);
-	pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2);
+	pci_read_config_dword(dev, 0x44, &reg1);
+	pci_read_config_dword(dev, 0x48, &reg2);
+	tmp1 = (pio << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)));
+	tmp2 = (udma << drive->dn) | (reg2 & ~(0x11 << drive->dn));
+	pci_write_config_dword(dev, 0x44, tmp1);
+	pci_write_config_dword(dev, 0x48, tmp2);
 
 #if HPT343_DEBUG_DRIVE_INFO
 	printk("%s: %02x drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
 		" (0x%02x 0x%02x) 0x%04x\n",
 		drive->name, speed,
 		drive->dn, reg1, tmp1, reg2, tmp2,
-		hi_speed, lo_speed, err);
+		udma, pio, err);
 #endif
 
-	drive->current_speed = speed;
 	return ide_config_drive_speed(drive, speed);
 }
 
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
-
-	byte	timing, speed, pio;
-
-	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio > 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
-		}
-	(void) hpt34x_tune_chipset(drive, speed);
-}
-
-static void hpt34x_tune_drive(struct ata_device *drive, byte pio)
+static void hpt34x_tune_drive(struct ata_device *drive, u8 pio)
 {
-	byte speed;
-
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4;break;
-		case 3:		speed = XFER_PIO_3;break;
-		case 2:		speed = XFER_PIO_2;break;
-		case 1:		speed = XFER_PIO_1;break;
-		default:	speed = XFER_PIO_0;break;
-	}
-	hpt34x_clear_chipset(drive);
-	(void) hpt34x_tune_chipset(drive, speed);
+	(void) hpt34x_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -168,7 +89,6 @@
 	if (mode < XFER_SW_DMA_0)
 		return 0;
 
-	hpt34x_clear_chipset(drive);
 	return !hpt34x_tune_chipset(drive, mode);
 }
 
@@ -219,7 +139,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive);
+		hpt34x_tune_chipset(drive, ata_best_pio_mode(drive));
 	}
 
 #ifndef CONFIG_HPT34X_AUTODMA
@@ -254,7 +174,7 @@
 	u8 cmd;
 
 	if (!(count = udma_new_table(drive, rq)))
-		return 1;	/* try PIO instead of DMA */
+		return ide_stopped;	/* try PIO instead of DMA */
 
 	if (rq_data_dir(rq) == READ)
 		cmd = 0x09;
@@ -266,13 +186,12 @@
 	outb(inb(dma_base+2)|6, dma_base+2);	/* clear INTR & ERROR flags */
 	drive->waiting_for_dma = 1;
 
-	if (drive->type != ATA_DISK)
-		return 0;
-
-	ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);	/* issue cmd to drive */
-	OUT_BYTE((cmd == 0x09) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+	if (drive->type == ATA_DISK) {
+		ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);	/* issue cmd to drive */
+		OUT_BYTE((cmd == 0x09) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+	}
 
-	return 0;
+	return ide_started;
 }
 #endif
 
diff -Nru a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
--- a/drivers/ide/hpt366.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/hpt366.c	Sun Jun 16 19:31:39 2002
@@ -140,7 +140,7 @@
 	unsigned int	chipset_settings;
 };
 
-/* key for bus clock timings
+/* key for bus clock timings for HPT370
  * bit
  * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
  *        DMA. cycles = value + 1
@@ -409,26 +409,6 @@
 };
 
 #if 0
-static struct chipset_bus_clock_list_entry fifty_base_hpt374[] = {
-	{	XFER_UDMA_6,	},
-	{	XFER_UDMA_5,	},
-	{	XFER_UDMA_4,	},
-	{	XFER_UDMA_3,	},
-	{	XFER_UDMA_2,	},
-	{	XFER_UDMA_1,	},
-	{	XFER_UDMA_0,	},
-	{	XFER_MW_DMA_2,	},
-	{	XFER_MW_DMA_1,	},
-	{	XFER_MW_DMA_0,	},
-	{	XFER_PIO_4,	},
-	{	XFER_PIO_3,	},
-	{	XFER_PIO_2,	},
-	{	XFER_PIO_1,	},
-	{	XFER_PIO_0,	},
-	{	0,	}
-};
-#endif
-#if 0
 static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
 	{	XFER_UDMA_6,	0x12406231	},	/* checkme */
 	{	XFER_UDMA_5,	0x12446231	},
@@ -476,8 +456,6 @@
 #define F_LOW_PCI_50      0x2d
 #define F_LOW_PCI_66      0x42
 
-static unsigned int hpt_min_rev(struct pci_dev *dev, int rev);
-
 static int check_in_drive_lists(struct ata_device *drive, const char **list)
 {
 	struct hd_driveid *id = drive->id;
@@ -515,29 +493,24 @@
 	return class_rev;
 }
 
-static unsigned int hpt_min_rev(struct pci_dev *dev, int rev)
-{
-	return (hpt_revision(dev) >= rev) ? 1 : 0;
-}
-
 static int hpt3xx_ratemask(struct ata_device *drive)
 {
-	struct pci_dev *dev = drive->channel->pci_dev;
+	u32 rev = hpt_revision(drive->channel->pci_dev);
 	int map = XFER_UDMA;
 
-	if (hpt_min_rev(dev, 8)) {			/* HPT374 */
+	if (rev >= 8) {					/* HPT374 */
 		if (HPT374_ALLOW_ATA133_6)
 			map |= XFER_UDMA_133;
 		map |= (XFER_UDMA_100 | XFER_UDMA_66);
-	} else if (hpt_min_rev(dev, 5)) {		/* HPT372 */
+	} else if (rev >= 5) {				/* HPT372 */
 		if (HPT372_ALLOW_ATA133_6)
 			map |= XFER_UDMA_133;
 		map |= (XFER_UDMA_100 | XFER_UDMA_66);
-	} else if (hpt_min_rev(dev, 4)) {		/* HPT370A */
+	} else if (rev >= 4) {				/* HPT370A */
 		if (HPT370_ALLOW_ATA100_5)
 			map |= XFER_UDMA_100;
 		map |= XFER_UDMA_66;
-	} else if (hpt_min_rev(dev, 3)) {		/* HPT370 */
+	} else if (rev >= 3) {				/* HPT370 */
 		if (HPT370_ALLOW_ATA100_5)
 			map |= XFER_UDMA_100;
 		map |= XFER_UDMA_66;
@@ -600,11 +573,6 @@
 	pci_write_config_dword(dev, regtime, reg2);
 }
 
-static void hpt368_tune_chipset(struct ata_device *drive, u8 speed)
-{
-	hpt366_tune_chipset(drive, speed);
-}
-
 static void hpt370_tune_chipset(struct ata_device *drive, u8 speed)
 {
 	u8 regfast = (drive->channel->unit) ? 0x55 : 0x51;
@@ -674,94 +642,43 @@
 	pci_write_config_dword(dev, drive_pci, list_conf);
 }
 
-static void hpt374_tune_chipset(struct ata_device *drive, u8 speed)
-{
-	hpt372_tune_chipset(drive, speed);
-}
-
 static int hpt3xx_tune_chipset(struct ata_device *drive, u8 speed)
 {
-	struct pci_dev *dev = drive->channel->pci_dev;
+	u32 rev;
 
 	if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
 		return -1;
 
-	if (hpt_min_rev(dev, 7)) {
-		hpt374_tune_chipset(drive, speed);
-	} else if (hpt_min_rev(dev, 5)) {
+	rev = hpt_revision(drive->channel->pci_dev);
+
+	if (rev >= 5) {
 		hpt372_tune_chipset(drive, speed);
-	} else if (hpt_min_rev(dev, 3)) {
+	} else if (rev >= 3) {
 		hpt370_tune_chipset(drive, speed);
-	} else if (hpt_min_rev(dev, 2)) {
-		hpt368_tune_chipset(drive, speed);
 	} else {
                 hpt366_tune_chipset(drive, speed);
         }
-	drive->current_speed = speed;
-	return ((int) ide_config_drive_speed(drive, speed));
-}
-
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	static unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
-	u8 timing, speed, pio;
-
-	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio > 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 :
-			   (drive->id->tPIO & 2) ? 0x02 :
-			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
 
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
-	}
-	hpt3xx_tune_chipset(drive, speed);
+	return ide_config_drive_speed(drive, speed);
 }
 
 static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio)
 {
-	u8 speed;
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4;break;
-		case 3:		speed = XFER_PIO_3;break;
-		case 2:		speed = XFER_PIO_2;break;
-		case 1:		speed = XFER_PIO_1;break;
-		default:	speed = XFER_PIO_0;break;
-	}
-	(void) hpt3xx_tune_chipset(drive, speed);
+	(void) hpt3xx_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 static int config_chipset_for_dma(struct ata_device *drive)
 {
-	struct pci_dev *dev = drive->channel->pci_dev;
 	int map;
+	u32 rev;
 	u8 mode;
 
 	if (drive->type != ATA_DISK)
 		return 0;
 
+	rev = hpt_revision(drive->channel->pci_dev);
+
 	/* FIXME: check SWDMA modes --bkz */
 	map = hpt3xx_ratemask(drive) | XFER_MWDMA;
 	mode = ata_timing_mode(drive, map);
@@ -770,7 +687,7 @@
 		  bad_ata100_5 is for HPT370/370A,
 		  bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368
 	 */
-	if (mode == XFER_UDMA_5 && hpt_min_rev(dev, 5)) {
+	if (mode == XFER_UDMA_5 && rev < 5) {
 		if (check_in_drive_lists(drive, bad_ata100_5)) {
 			/* FIXME: make XFER_UDMA_66/100/133
 				  independent of XFER_UDMA --bkz */
@@ -779,7 +696,7 @@
 			mode = ata_timing_mode(drive, map);
 		}
 	}
-	if (mode == XFER_UDMA_4 && hpt_min_rev(dev, 3)) {
+	if (mode == XFER_UDMA_4 && rev < 3) {
 		if (check_in_drive_lists(drive, bad_ata66_4)) {
 			if (drive->id->dma_ultra & 0x0008) {
 				mode = XFER_UDMA_3;
@@ -790,14 +707,14 @@
 			}
 		}
 	}
-	if (mode == XFER_UDMA_3 && hpt_min_rev(dev, 3)) {
+	if (mode == XFER_UDMA_3 && rev < 3) {
 		if (check_in_drive_lists(drive, bad_ata66_3)) {
 			map &= ~XFER_UDMA_66;
 			map |= XFER_UDMA;
 			mode = ata_timing_mode(drive, map);
 		}
 	}
-	if (check_in_drive_lists(drive, bad_ata33) && hpt_min_rev(dev, 3))
+	if (check_in_drive_lists(drive, bad_ata33) && rev < 3)
 		mode = ata_timing_mode(drive, XFER_MWDMA);
 
 	return !hpt3xx_tune_chipset(drive, mode);
@@ -823,7 +740,8 @@
 	struct ata_channel *ch = drive->channel;
 
 	if (drive->quirk_list) {
-		if (hpt_min_rev(dev, 3)) {
+		u32 rev = hpt_revision(dev);
+		if (rev >= 3) {
 			u8 reg5a;
 			pci_read_config_byte(dev, 0x5a, &reg5a);
 			if ((reg5a & 0x10) >> 4)
@@ -882,8 +800,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-
-		config_chipset_for_pio(drive);
+		hpt3xx_tune_chipset(drive, ata_best_pio_mode(drive));
 	}
 	udma_enable(drive, on, verbose);
 
@@ -892,15 +809,16 @@
 
 static void hpt366_udma_irq_lost(struct ata_device *drive)
 {
+	struct pci_dev *dev = drive->channel->pci_dev;
 	u8 reg50h, reg52h, reg5ah;
 
-	pci_read_config_byte(drive->channel->pci_dev, 0x50, &reg50h);
-	pci_read_config_byte(drive->channel->pci_dev, 0x52, &reg52h);
-	pci_read_config_byte(drive->channel->pci_dev, 0x5a, &reg5ah);
+	pci_read_config_byte(dev, 0x50, &reg50h);
+	pci_read_config_byte(dev, 0x52, &reg52h);
+	pci_read_config_byte(dev, 0x5a, &reg5ah);
 	printk("%s: (%s)  reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
 			drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);
 	if (reg5ah & 0x10)
-		pci_write_config_byte(drive->channel->pci_dev, 0x5a, reg5ah & ~0x10);
+		pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
 }
 
 static void do_udma_start(struct ata_device *drive)
@@ -912,7 +830,7 @@
 	udelay(10);
 }
 
-static int hpt370_udma_start(struct ata_device *drive, struct request *__rq)
+static void hpt370_udma_start(struct ata_device *drive, struct request *__rq)
 {
 	struct ata_channel *ch = drive->channel;
 
@@ -924,8 +842,6 @@
 	 */
 
 	outb(inb(ch->dma_base) | 1, ch->dma_base);	/* start DMA */
-
-	return 0;
 }
 
 static void do_timeout_irq(struct ata_device *drive)
@@ -1127,7 +1043,7 @@
 {
 	int adjust, i;
 	u16 freq;
-	u32 pll;
+	u32 pll, rev = hpt_revision(dev);
 	u8 reg5bh;
 
 	/*
@@ -1144,9 +1060,9 @@
 	freq &= 0x1FF;
 	if (freq < 0x9c) {
 		pll = F_LOW_PCI_33;
-		if (hpt_min_rev(dev, 7)) {
+		if (rev >= 7) {
 			dev->sysdata = (void *) thirty_three_base_hpt374;
-		} else if (hpt_min_rev(dev, 5)) {
+		} else if (rev >= 5) {
 			dev->sysdata = (void *) thirty_three_base_hpt372;
 		} else {
 			dev->sysdata = (void *) thirty_three_base_hpt370;
@@ -1156,10 +1072,10 @@
 		pll = F_LOW_PCI_40;
 	} else if (freq < 0xc8) {
 		pll = F_LOW_PCI_50;
-		if (hpt_min_rev(dev, 7)) {
+		if (rev >= 7) {
 	//		dev->sysdata = (void *) fifty_base_hpt374;
 			BUG();
-		} else if (hpt_min_rev(dev, 5)) {
+		} else if (rev >= 5) {
 			dev->sysdata = (void *) fifty_base_hpt372;
 		} else {
 			dev->sysdata = (void *) fifty_base_hpt370;
@@ -1167,10 +1083,10 @@
 		printk("HPT37X: using 50MHz PCI clock\n");
 	} else {
 		pll = F_LOW_PCI_66;
-		if (hpt_min_rev(dev, 7)) {
+		if (rev >= 7) {
 	//		dev->sysdata = (void *) sixty_six_base_hpt374;
 			BUG();
-		} else if (hpt_min_rev(dev, 5)) {
+		} else if (rev >= 5) {
 			dev->sysdata = (void *) sixty_six_base_hpt372;
 		} else {
 			dev->sysdata = (void *) sixty_six_base_hpt370;
@@ -1213,10 +1129,10 @@
 				pci_write_config_dword(dev, 0x5c,
 						       pll & ~0x100);
 				pci_write_config_byte(dev, 0x5b, 0x21);
-				if (hpt_min_rev(dev, 7)) {
+				if (rev >= 7) {
 	//	dev->sysdata = (void *) fifty_base_hpt374;
 					BUG();
-				} else if (hpt_min_rev(dev, 5)) {
+				} else if (rev >= 5) {
 					dev->sysdata = (void *) fifty_base_hpt372;
 				} else {
 					dev->sysdata = (void *) fifty_base_hpt370;
@@ -1269,6 +1185,7 @@
 
 static unsigned int __init hpt366_init_chipset(struct pci_dev *dev)
 {
+	u32 rev = hpt_revision(dev);
 	u8 test;
 
 	if (dev->resource[PCI_ROM_RESOURCE].start)
@@ -1290,7 +1207,7 @@
 	if (test != 0x08)
 		pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
 
-	if (hpt_min_rev(dev, 3))
+	if (rev >= 3)
 		hpt37x_init(dev);
 	else
 		hpt366_init(dev);
@@ -1315,6 +1232,7 @@
 static void __init hpt366_init_channel(struct ata_channel *ch)
 {
 	struct pci_dev *dev = ch->pci_dev;
+	u32 rev = hpt_revision(dev);
 
 	ch->tuneproc = hpt3xx_tune_drive;
 	ch->speedproc = hpt3xx_tune_chipset;
@@ -1330,7 +1248,7 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (ch->dma_base) {
-		if (hpt_min_rev(dev, 3)) {
+		if (rev >= 3) {
 			u8 reg5ah;
 			pci_read_config_byte(dev, 0x5a, &reg5ah);
 			if (reg5ah & 0x10)	/* interrupt force enable */
@@ -1343,45 +1261,33 @@
 			ch->resetproc	= hpt3xx_reset;
 			ch->busproc	= hpt370_busproc;
 
-			if (hpt_min_rev(dev, 7)) {
+			if (rev >= 5) {
 				ch->udma_stop = hpt374_udma_stop;
-				ch->udma_setup = hpt3xx_udma_setup;
-			} else if (hpt_min_rev(dev, 5)) {
-				ch->udma_stop = hpt374_udma_stop;
-				ch->udma_setup = hpt3xx_udma_setup;
-			} else if (hpt_min_rev(dev, 3)) {
+			} else { /* rev >= 3 */
 			        ch->udma_start = hpt370_udma_start;
 				ch->udma_stop = hpt370_udma_stop;
 				ch->udma_timeout = hpt370_udma_timeout;
 				ch->udma_irq_lost = hpt370_udma_irq_lost;
-				ch->udma_setup = hpt3xx_udma_setup;
 			}
-		} else if (hpt_min_rev(dev, 2)) {
-			ch->udma_irq_lost = hpt366_udma_irq_lost;
-//			ch->resetproc = hpt3xx_reset;
-//			ch->busproc = hpt3xx_tristate;
-			ch->udma_setup = hpt3xx_udma_setup;
 		} else {
 			ch->udma_irq_lost = hpt366_udma_irq_lost;
 //			ch->resetproc = hpt3xx_reset;
 //			ch->busproc = hpt3xx_tristate;
-			ch->udma_setup = hpt3xx_udma_setup;
 		}
+		ch->udma_setup = hpt3xx_udma_setup;
+
 		if (!noautodma)
 			ch->autodma = 1;
 		else
 			ch->autodma = 0;
 		ch->highmem = 1;
-	} else {
+	} else
+#endif
+	{
 		ch->autodma = 0;
 		ch->drives[0].autotune = 1;
 		ch->drives[1].autotune = 1;
 	}
-#else
-	ch->drives[0].autotune = 1;
-	ch->drives[1].autotune = 1;
-	ch->autodma = 0;
-#endif
 }
 
 static void __init hpt366_init_dma(struct ata_channel *ch, unsigned long dmabase)
@@ -1390,10 +1296,9 @@
 	u8 dma_old = inb(dmabase + 2);
 	u8 dma_new = dma_old;
 	u8 primary = ch->unit ? 0x4b : 0x43;
-	u8 secondary = primary + 4;
 
 	pci_read_config_byte(ch->pci_dev, primary, &masterdma);
-	pci_read_config_byte(ch->pci_dev, secondary, &slavedma);
+	pci_read_config_byte(ch->pci_dev, primary + 4, &slavedma);
 
 	if (masterdma & 0x30)
 		dma_new |= 0x20;
@@ -1447,9 +1352,8 @@
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(chipsets); ++i) {
+	for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
 		ata_register_chipset(&chipsets[i]);
-	}
 
 	return 0;
 }
diff -Nru a/drivers/ide/icside.c b/drivers/ide/icside.c
--- a/drivers/ide/icside.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/icside.c	Sun Jun 16 19:31:39 2002
@@ -281,7 +281,7 @@
 	struct scatterlist *sg = ch->sg_table;
 	int nents;
 
-	if (rq->flags & REQ_SPECIAL) {
+	if ((rq->flags & REQ_SPECIAL) && (drive->type == ATA_DISK)) {
 		struct ata_taskfile *args = rq->special;
 
 		if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
@@ -447,18 +447,13 @@
 	return get_dma_residue(ch->hw.dma) != 0;
 }
 
-static int icside_dma_start(struct ata_device *drive, struct request *rq)
+static void icside_dma_start(struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *ch = drive->channel;
 
-	/*
-	 * We can not enable DMA on both channels.
-	 */
+	/* We can not enable DMA on both channels simultaneously. */
 	BUG_ON(dma_channel_active(ch->hw.dma));
-
 	enable_dma(ch->hw.dma);
-
-	return 0;
 }
 
 /*
@@ -521,15 +516,15 @@
 static int icside_dma_init(struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *ch = drive->channel;
-	unsigned int cmd;
+	u8 int cmd;
 
 	if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
-		return 1;
+		return ide_stopped;
 
 	if (drive->type != ATA_DISK)
-		return 0;
+		return ide_started;
 
-	ide_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
+	ata_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
 
 	if ((rq->flags & REQ_SPECIAL) && drive->addressing == 1) {
 		struct ata_taskfile *args = rq->special;
@@ -542,7 +537,8 @@
 	OUT_BYTE(cmd, IDE_COMMAND_REG);
 
 	enable_dma(ch->hw.dma);
-	return 0;
+
+	return ide_started;
 }
 
 static int icside_irq_status(struct ata_device *drive)
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/ide-cd.c	Sun Jun 16 19:31:40 2002
@@ -556,7 +556,7 @@
 	if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
 		uptodate = 1;
 
-	ide_end_request(drive, rq, uptodate);
+	ata_end_request(drive, rq, uptodate);
 }
 
 
@@ -728,39 +728,53 @@
 						  int xferlen,
 						  ata_handler_t handler)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	ide_startstop_t startstop;
 	struct cdrom_info *info = drive->driver_data;
+	int ret;
 
+	spin_lock_irqsave(ch->lock, flags);
 	/* Wait for the controller to be idle. */
-	if (ide_wait_stat(&startstop, drive, rq, 0, BUSY_STAT, WAIT_READY))
-		return startstop;
+	if (ata_status_poll(drive, 0, BUSY_STAT, WAIT_READY, rq, &startstop))
+		ret = startstop;
+	else {
+		if (info->dma) {
+			if (info->cmd == READ || info->cmd == WRITE)
+				info->dma = udma_init(drive, rq);
+			else
+				printk("ide-cd: DMA set, but not allowed\n");
+		}
 
-	if (info->dma) {
-		if (info->cmd == READ || info->cmd == WRITE)
-			info->dma = !udma_init(drive, rq);
-		else
-			printk("ide-cd: DMA set, but not allowed\n");
-	}
-
-	/* Set up the controller registers. */
-	OUT_BYTE(info->dma, IDE_FEATURE_REG);
-	OUT_BYTE(0, IDE_NSECTOR_REG);
-	OUT_BYTE(0, IDE_SECTOR_REG);
-
-	OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
-	OUT_BYTE(xferlen >> 8  , IDE_HCYL_REG);
-	ata_irq_enable(drive, 1);
-	if (info->dma)
-		udma_start(drive, rq);
+		/* Set up the controller registers. */
+		OUT_BYTE(info->dma, IDE_FEATURE_REG);
+		OUT_BYTE(0, IDE_NSECTOR_REG);
+		OUT_BYTE(0, IDE_SECTOR_REG);
+
+		OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
+		OUT_BYTE(xferlen >> 8  , IDE_HCYL_REG);
+		ata_irq_enable(drive, 1);
+		if (info->dma)
+			udma_start(drive, rq);
+
+		if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
+			ata_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
+			OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
+			ret = ide_started;
+		} else {
+			OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
 
-	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
-		ide_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
-		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
-		return ide_started;
-	} else {
-		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
-		return handler(drive, rq);
+			/* FIXME: Oj kurwa! We have to ungrab the lock before
+			 * the IRQ handler gets called.
+			 */
+			spin_unlock_irqrestore(ch->lock, flags);
+			ret = handler(drive, rq);
+			spin_lock_irqsave(ch->lock, flags);
+		}
 	}
+	spin_unlock_irqrestore(ch->lock, flags);
+
+	return ret;
 }
 
 /*
@@ -773,6 +787,8 @@
 		unsigned char *cmd, unsigned long timeout,
 		ata_handler_t handler)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	ide_startstop_t startstop;
 
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
@@ -784,16 +800,24 @@
 		if (cdrom_decode_status(&startstop, drive, rq, DRQ_STAT, &stat_dum))
 			return startstop;
 	} else {
+		/* FIXME: make this locking go away */
+		spin_lock_irqsave(ch->lock, flags);
 		/* Otherwise, we must wait for DRQ to get set. */
-		if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY))
+		if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+					WAIT_READY, rq, &startstop)) {
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return startstop;
+		}
+		spin_unlock_irqrestore(ch->lock, flags);
 	}
 
-	/* Arm the interrupt handler. */
-	ide_set_handler(drive, handler, timeout, cdrom_timer_expiry);
-
-	/* Send the command to the device. */
+	/* Arm the interrupt handler and send the command to the device. */
+	/* FIXME: make this locking go away */
+	spin_lock_irqsave(ch->lock, flags);
+	ata_set_handler(drive, handler, timeout, cdrom_timer_expiry);
 	atapi_write(drive, cmd, CDROM_PACKET_SIZE);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_started;
 }
@@ -893,6 +917,8 @@
  */
 static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	int stat;
 	int ireason, len, sectors_to_transfer, nskip;
 	struct cdrom_info *info = drive->driver_data;
@@ -911,7 +937,14 @@
 
 	if (dma) {
 		if (!dma_error) {
-			__ide_end_request(drive, rq, 1, rq->nr_sectors);
+			/* FIXME: this locking should encompass the above register
+			 * file access too.
+			 */
+
+			spin_lock_irqsave(ch->lock, flags);
+			__ata_end_request(drive, rq, 1, rq->nr_sectors);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ide_stopped;
 		} else
 			return ata_error(drive, rq, "dma error");
@@ -1007,7 +1040,9 @@
 	}
 
 	/* Done moving data! Wait for another interrupt. */
-	ide_set_handler(drive, cdrom_read_intr, WAIT_CMD, NULL);
+	spin_lock_irqsave(ch->lock, flags);
+	ata_set_handler(drive, cdrom_read_intr, WAIT_CMD, NULL);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_started;
 }
@@ -1234,6 +1269,8 @@
 /* Interrupt routine for packet command completion. */
 static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	int ireason, len, stat, thislen;
 
 	/* FIXME --mdcki */
@@ -1326,7 +1363,9 @@
 	}
 
 	/* Now we wait for another interrupt. */
-	ide_set_handler(drive, cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
+	spin_lock_irqsave(ch->lock, flags);
+	ata_set_handler(drive, cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_started;
 }
@@ -1469,6 +1508,8 @@
 
 static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	int stat, ireason, len, sectors_to_transfer, uptodate;
 	struct cdrom_info *info = drive->driver_data;
 	int dma_error = 0, dma = info->dma;
@@ -1495,7 +1536,14 @@
 		if (dma_error)
 			return ata_error(drive, rq, "dma error");
 
-		__ide_end_request(drive, rq, 1, rq->nr_sectors);
+		/* FIXME: this locking should encompass the above register
+		 * file access too.
+		 */
+
+		spin_lock_irqsave(ch->lock, flags);
+		__ata_end_request(drive, rq, 1, rq->nr_sectors);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return ide_stopped;
 	}
 
@@ -1559,7 +1607,9 @@
 	}
 
 	/* re-arm handler */
-	ide_set_handler(drive, cdrom_write_intr, 5 * WAIT_CMD, NULL);
+	spin_lock_irqsave(ch->lock, flags);
+	ata_set_handler(drive, cdrom_write_intr, 5 * WAIT_CMD, NULL);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_started;
 }
@@ -1608,7 +1658,8 @@
 static ide_startstop_t
 ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
-	ide_startstop_t action;
+	struct ata_channel *ch = drive->channel;
+	int ret;
 	struct cdrom_info *info = drive->driver_data;
 
 	if (rq->flags & REQ_CMD) {
@@ -1624,18 +1675,26 @@
 			}
 			CDROM_CONFIG_FLAGS(drive)->seeking = 0;
 		}
-		if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
-			action = cdrom_start_seek(drive, rq, block);
-		else {
+		/* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
+		if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
+			ret = cdrom_start_seek(drive, rq, block);
+		} else {
 			if (rq_data_dir(rq) == READ)
-				action = cdrom_start_read(drive, rq, block);
+				ret = cdrom_start_read(drive, rq, block);
 			else
-				action = cdrom_start_write(drive, rq);
+				ret = cdrom_start_write(drive, rq);
 		}
 		info->last_block = block;
-		return action;
+		spin_lock_irq(ch->lock);
+		return ret;
 	} else if (rq->flags & (REQ_PC | REQ_SENSE)) {
-		return cdrom_do_packet_command(drive, rq);
+		/* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
+		ret = cdrom_do_packet_command(drive, rq);
+		spin_lock_irq(ch->lock);
+
+		return ret;
 	} else if (rq->flags & REQ_SPECIAL) {
 		/*
 		 * FIXME: Kill REQ_SEPCIAL and replace it with commands queued
@@ -1644,7 +1703,11 @@
 		 * right now this can only be a reset...
 		 */
 
+	        /* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
 		cdrom_end_request(drive, rq, 1);
+		spin_lock_irq(ch->lock);
+
 		return ide_stopped;
 	} else if (rq->flags & REQ_BLOCK_PC) {
 		struct packet_command pc;
@@ -1657,7 +1720,11 @@
 		/* FIXME --mdcki */
 		rq->special = (char *) &pc;
 
+		/* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
 		startstop = cdrom_do_packet_command(drive, rq);
+		spin_lock_irq(ch->lock);
+
 		if (pc.stat)
 			++rq->errors;
 
@@ -1665,7 +1732,11 @@
 	}
 
 	blk_dump_rq_flags(rq, "ide-cd bad flags");
+	/* FIXME: make this unlocking go away*/
+	spin_unlock_irq(ch->lock);
 	cdrom_end_request(drive, rq, 0);
+	spin_lock_irq(ch->lock);
+
 	return ide_stopped;
 }
 
diff -Nru a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
--- a/drivers/ide/ide-cs.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/ide-cs.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
-/*======================================================================
-
+/**** vi:set ts=8 sts=8 sw=8:************************************************
+ *
     A driver for PCMCIA IDE/ATA disk cards
 
     ide_cs.c 1.26 1999/11/16 02:10:49
@@ -28,8 +28,8 @@
     and other provisions required by the GPL.  If you do not delete
     the provisions above, a recipient may use your version of this
     file under either the MPL or the GPL.
-    
-======================================================================*/
+ *
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -54,12 +54,12 @@
 #include <pcmcia/ds.h>
 #include <pcmcia/cisreg.h>
 
+#define PCMCIA_DEBUG 100
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
+static const char *version = "ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -81,23 +81,23 @@
 /*====================================================================*/
 
 static const char ide_major[] = {
-    IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
+	IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
 #ifdef IDE4_MAJOR
-    IDE4_MAJOR, IDE5_MAJOR
+	IDE4_MAJOR, IDE5_MAJOR
 #endif
 };
 
 typedef struct ide_info_t {
-    dev_link_t	link;
-    int		ndev;
-    dev_node_t	node;
-    int		hd;
+	dev_link_t link;
+	int ndev;
+	dev_node_t node;
+	int hd;
 } ide_info_t;
 
-static void ide_config(dev_link_t *link);
+static void ide_config(dev_link_t * link);
 static void ide_release(u_long arg);
 static int ide_event(event_t event, int priority,
-		     event_callback_args_t *args);
+		     event_callback_args_t * args);
 
 static dev_info_t dev_info = "ide-cs";
 
@@ -110,8 +110,11 @@
 
 static void cs_error(client_handle_t handle, int func, int ret)
 {
-    error_info_t err = { func, ret };
-    CardServices(ReportError, handle, &err);
+	error_info_t err = { func, ret };
+
+	DEBUG(0, "cs_error\n");
+
+	CardServices(ReportError, handle, &err);
 }
 
 /*======================================================================
@@ -124,56 +127,58 @@
 
 static dev_link_t *ide_attach(void)
 {
-    ide_info_t *info;
-    dev_link_t *link;
-    client_reg_t client_reg;
-    int i, ret;
-    
-    DEBUG(0, "ide_attach()\n");
-
-    /* Create new ide device */
-    info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
-    memset(info, 0, sizeof(*info));
-    link = &info->link; link->priv = info;
-
-    link->release.function = &ide_release;
-    link->release.data = (u_long)link;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-    link->io.IOAddrLines = 3;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.Vcc = 50;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-    client_reg.EventMask =
-	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-    client_reg.event_handler = &ide_event;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	ide_detach(link);
-	return NULL;
-    }
-    
-    return link;
-} /* ide_attach */
+	ide_info_t *info;
+	dev_link_t *link;
+	client_reg_t client_reg;
+	int i, ret;
+
+	DEBUG(0, "ide_attach\n");
+
+	/* Create new ide device */
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return NULL;
+	memset(info, 0, sizeof(*info));
+	link = &info->link;
+	link->priv = info;
+
+	link->release.function = &ide_release;
+	link->release.data = (u_long) link;
+	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+	link->io.IOAddrLines = 3;
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
+	if (irq_list[0] == -1)
+		link->irq.IRQInfo2 = irq_mask;
+	else
+		for (i = 0; i < 4; i++)
+			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->conf.Attributes = CONF_ENABLE_IRQ;
+	link->conf.Vcc = 50;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	/* Register with Card Services */
+	link->next = dev_list;
+	dev_list = link;
+	client_reg.dev_info = &dev_info;
+	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+	client_reg.EventMask =
+	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+	client_reg.event_handler = &ide_event;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	ret = CardServices(RegisterClient, &link->handle, &client_reg);
+	if (ret != CS_SUCCESS) {
+		cs_error(link->handle, RegisterClient, ret);
+		ide_detach(link);
+		return NULL;
+	}
+
+	return link;
+}				/* ide_attach */
 
 /*======================================================================
 
@@ -184,34 +189,35 @@
 
 ======================================================================*/
 
-static void ide_detach(dev_link_t *link)
+static void ide_detach(dev_link_t * link)
 {
-    dev_link_t **linkp;
-    int ret;
+	dev_link_t **linkp;
+	int ret;
 
-    DEBUG(0, "ide_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+	DEBUG(0, "ide_detach(0x%p)\n", link);
+
+	/* Locate device structure */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link)
+			break;
+	if (*linkp == NULL)
+		return;
+
+	del_timer(&link->release);
+	if (link->state & DEV_CONFIG)
+		ide_release((u_long) link);
 
-    del_timer(&link->release);
-    if (link->state & DEV_CONFIG)
-	ide_release((u_long)link);
-    
-    if (link->handle) {
-	ret = CardServices(DeregisterClient, link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
-    }
-    
-    /* Unlink, free device structure */
-    *linkp = link->next;
-    kfree(link->priv);
-    
-} /* ide_detach */
+	if (link->handle) {
+		ret = CardServices(DeregisterClient, link->handle);
+		if (ret != CS_SUCCESS)
+			cs_error(link->handle, DeregisterClient, ret);
+	}
+
+	/* Unlink, free device structure */
+	*linkp = link->next;
+	kfree(link->priv);
+
+}				/* ide_detach */
 
 /*======================================================================
 
@@ -227,199 +233,224 @@
 #define CFG_CHECK(fn, args...) \
 if (CardServices(fn, args) != 0) goto next_entry
 
-int idecs_register (int arg1, int arg2, int irq)
+int idecs_register(int arg1, int arg2, int irq)
 {
-        hw_regs_t hw;
-        ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL);
-        hw.irq = irq;
-        hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */
+	hw_regs_t hw;
 
-        return ide_register_hw(&hw);
+	DEBUG(0, "idecs_register\n");
+
+	ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2,
+			    NULL);
+	hw.irq = irq;
+	hw.chipset = ide_pci;	/* this enables IRQ sharing w/ PCI irqs */
+
+	return ide_register_hw(&hw);
 }
 
-void ide_config(dev_link_t *link)
+void ide_config(dev_link_t * link)
 {
-    client_handle_t handle = link->handle;
-    ide_info_t *info = link->priv;
-    tuple_t tuple;
-    u_short buf[128];
-    cisparse_t parse;
-    config_info_t conf;
-    cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
-    cistpl_cftable_entry_t dflt = { 0 };
-    int i, pass, last_ret, last_fn, hd=-1, io_base, ctl_base;
-
-    DEBUG(0, "ide_config(0x%p)\n", link);
-    
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-    tuple.Attributes = 0;
-    tuple.DesiredTuple = CISTPL_CONFIG;
-    CS_CHECK(GetFirstTuple, handle, &tuple);
-    CS_CHECK(GetTupleData, handle, &tuple);
-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
-    link->conf.ConfigBase = parse.config.base;
-    link->conf.Present = parse.config.rmask[0];
-    
-    /* Configure card */
-    link->state |= DEV_CONFIG;
-
-    /* Not sure if this is right... look up the current Vcc */
-    CS_CHECK(GetConfigurationInfo, handle, &conf);
-    link->conf.Vcc = conf.Vcc;
-    
-    pass = io_base = ctl_base = 0;
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    tuple.Attributes = 0;
-    CS_CHECK(GetFirstTuple, handle, &tuple);
-    while (1) {
-	CFG_CHECK(GetTupleData, handle, &tuple);
-	CFG_CHECK(ParseTuple, handle, &tuple, &parse);
-
-	/* Check for matching Vcc, unless we're desperate */
-	if (!pass) {
-	    if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
-		if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
-		    goto next_entry;
-	    } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
-		if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
-		    goto next_entry;
-	    }
-	}
-	
-	if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
-	    link->conf.Vpp1 = link->conf.Vpp2 =
-		cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
-	else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
-	    link->conf.Vpp1 = link->conf.Vpp2 =
-		dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
-	
-	if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-	    cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-	    link->conf.ConfigIndex = cfg->index;
-	    link->io.BasePort1 = io->win[0].base;
-	    link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-	    if (!(io->flags & CISTPL_IO_16BIT))
-		link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-	    if (io->nwin == 2) {
-		link->io.NumPorts1 = 8;
-		link->io.BasePort2 = io->win[1].base;
-		link->io.NumPorts2 = 1;
-		CFG_CHECK(RequestIO, link->handle, &link->io);
-		io_base = link->io.BasePort1;
-		ctl_base = link->io.BasePort2;
-	    } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
-		link->io.NumPorts1 = io->win[0].len;
-		link->io.NumPorts2 = 0;
-		CFG_CHECK(RequestIO, link->handle, &link->io);
-		io_base = link->io.BasePort1;
-		ctl_base = link->io.BasePort1+0x0e;
-	    } else goto next_entry;
-	    /* If we've got this far, we're done */
-	    break;
+	client_handle_t handle = link->handle;
+	ide_info_t *info = link->priv;
+	tuple_t tuple;
+	u_short buf[128];
+	cisparse_t parse;
+	config_info_t conf;
+	cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
+	cistpl_cftable_entry_t dflt = { 0 };
+	int i, pass, last_ret, last_fn, hd = -1, io_base, ctl_base;
+
+	DEBUG(0, "ide_config(0x%p)\n", link);
+
+	tuple.TupleData = (cisdata_t *) buf;
+	tuple.TupleOffset = 0;
+	tuple.TupleDataMax = 255;
+	tuple.Attributes = 0;
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	CS_CHECK(GetTupleData, handle, &tuple);
+	CS_CHECK(ParseTuple, handle, &tuple, &parse);
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/* Configure card */
+	link->state |= DEV_CONFIG;
+
+	/* Not sure if this is right... look up the current Vcc */
+	CS_CHECK(GetConfigurationInfo, handle, &conf);
+	link->conf.Vcc = conf.Vcc;
+
+	pass = io_base = ctl_base = 0;
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	tuple.Attributes = 0;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	while (1) {
+		CFG_CHECK(GetTupleData, handle, &tuple);
+		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+
+		/* Check for matching Vcc, unless we're desperate */
+		if (!pass) {
+			if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+				if (conf.Vcc !=
+				    cfg->vcc.param[CISTPL_POWER_VNOM] /
+				    10000)
+					goto next_entry;
+			} else if (dflt.vcc.
+				   present & (1 << CISTPL_POWER_VNOM)) {
+				if (conf.Vcc !=
+				    dflt.vcc.param[CISTPL_POWER_VNOM] /
+				    10000)
+					goto next_entry;
+			}
+		}
+
+		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+			    cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+		else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+			    dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io =
+			    (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->conf.ConfigIndex = cfg->index;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.IOAddrLines =
+			    io->flags & CISTPL_IO_LINES_MASK;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 =
+				    IO_DATA_PATH_WIDTH_8;
+			if (io->nwin == 2) {
+				link->io.NumPorts1 = 8;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = 1;
+				CFG_CHECK(RequestIO, link->handle,
+					  &link->io);
+				io_base = link->io.BasePort1;
+				ctl_base = link->io.BasePort2;
+			} else if ((io->nwin == 1)
+				   && (io->win[0].len >= 16)) {
+				link->io.NumPorts1 = io->win[0].len;
+				link->io.NumPorts2 = 0;
+				CFG_CHECK(RequestIO, link->handle,
+					  &link->io);
+				io_base = link->io.BasePort1;
+				ctl_base = link->io.BasePort1 + 0x0e;
+			} else
+				goto next_entry;
+			/* If we've got this far, we're done */
+			break;
+		}
+
+	      next_entry:
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (pass) {
+			CS_CHECK(GetNextTuple, handle, &tuple);
+		} else if (CardServices(GetNextTuple, handle, &tuple) != 0) {
+			CS_CHECK(GetFirstTuple, handle, &tuple);
+			memset(&dflt, 0, sizeof(dflt));
+			pass++;
+		}
 	}
-	
-    next_entry:
-	if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-	if (pass) {
-	    CS_CHECK(GetNextTuple, handle, &tuple);
-	} else if (CardServices(GetNextTuple, handle, &tuple) != 0) {
-	    CS_CHECK(GetFirstTuple, handle, &tuple);
-	    memset(&dflt, 0, sizeof(dflt));
-	    pass++;
+
+	CS_CHECK(RequestIRQ, handle, &link->irq);
+	CS_CHECK(RequestConfiguration, handle, &link->conf);
+
+	/* deal with brain dead IDE resource management */
+	release_region(link->io.BasePort1, link->io.NumPorts1);
+	if (link->io.NumPorts2)
+		release_region(link->io.BasePort2, link->io.NumPorts2);
+
+	/* retry registration in case device is still spinning up */
+	for (i = 0; i < 10; i++) {
+		if (ctl_base)
+			outb(0x02, ctl_base);	/* Set nIEN = disable device interrupts */
+		hd = idecs_register(io_base, ctl_base,
+				    link->irq.AssignedIRQ);
+		if (hd >= 0)
+			break;
+		if (link->io.NumPorts1 == 0x20) {
+			if (ctl_base)
+				outb(0x02, ctl_base + 0x10);
+			hd = idecs_register(io_base + 0x10,
+					    ctl_base + 0x10,
+					    link->irq.AssignedIRQ);
+			if (hd >= 0) {
+				io_base += 0x10;
+				ctl_base += 0x10;
+				break;
+			}
+		}
+		__set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ / 10);
 	}
-    }
-    
-    CS_CHECK(RequestIRQ, handle, &link->irq);
-    CS_CHECK(RequestConfiguration, handle, &link->conf);
-
-    /* deal with brain dead IDE resource management */
-    release_region(link->io.BasePort1, link->io.NumPorts1);
-    if (link->io.NumPorts2)
-	release_region(link->io.BasePort2, link->io.NumPorts2);
-
-    /* retry registration in case device is still spinning up */
-    for (i = 0; i < 10; i++) {
-	if (ctl_base)
-	    outb(0x02, ctl_base); /* Set nIEN = disable device interrupts */
-	hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
-	if (hd >= 0) break;
-	if (link->io.NumPorts1 == 0x20) {
-	    if (ctl_base)
-		outb(0x02, ctl_base+0x10);
-	    hd = idecs_register(io_base+0x10, ctl_base+0x10,
-			      link->irq.AssignedIRQ);
-	    if (hd >= 0) {
-		io_base += 0x10; ctl_base += 0x10;
-		break;
-	    }
+
+	if (hd < 0) {
+		printk(KERN_NOTICE
+		       "ide_cs: ide_register() at 0x%03x & 0x%03x"
+		       ", irq %u failed\n", io_base, ctl_base,
+		       link->irq.AssignedIRQ);
+		goto failed;
 	}
-	__set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ/10);
-    }
-    
-    if (hd < 0) {
-	printk(KERN_NOTICE "ide_cs: ide_register() at 0x%03x & 0x%03x"
-	       ", irq %u failed\n", io_base, ctl_base,
-	       link->irq.AssignedIRQ);
-	goto failed;
-    }
-
-    MOD_INC_USE_COUNT;
-    info->ndev = 1;
-    sprintf(info->node.dev_name, "hd%c", 'a'+(hd*2));
-    info->node.major = ide_major[hd];
-    info->node.minor = 0;
-    info->hd = hd;
-    link->dev = &info->node;
-    printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
-	   info->node.dev_name, link->conf.Vcc/10, link->conf.Vcc%10,
-	   link->conf.Vpp1/10, link->conf.Vpp1%10);
-
-    link->state &= ~DEV_CONFIG_PENDING;
-    return;
-    
-cs_failed:
-    cs_error(link->handle, last_fn, last_ret);
-failed:
-    ide_release((u_long)link);
 
-} /* ide_config */
+	MOD_INC_USE_COUNT;
+	info->ndev = 1;
+	sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
+	info->node.major = ide_major[hd];
+	info->node.minor = 0;
+	info->hd = hd;
+	link->dev = &info->node;
+	printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
+	       info->node.dev_name, link->conf.Vcc / 10,
+	       link->conf.Vcc % 10, link->conf.Vpp1 / 10,
+	       link->conf.Vpp1 % 10);
+
+	link->state &= ~DEV_CONFIG_PENDING;
+	return;
+
+      cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+      failed:
+	ide_release((u_long) link);
+
+}				/* ide_config */
 
 /*======================================================================
 
     After a card is removed, ide_release() will unregister the net
     device, and release the PCMCIA configuration.  If the device is
     still open, this will be postponed until it is closed.
-    
+
 ======================================================================*/
 
 void ide_release(u_long arg)
 {
-    dev_link_t *link = (dev_link_t *)arg;
-    ide_info_t *info = link->priv;
-    
-    DEBUG(0, "ide_release(0x%p)\n", link);
-
-    if (info->ndev) {
-	ide_unregister(&ide_hwifs[info->hd]);
-	MOD_DEC_USE_COUNT;
-    }
-
-    request_region(link->io.BasePort1, link->io.NumPorts1,"ide-cs");
-    if (link->io.NumPorts2)
-	request_region(link->io.BasePort2, link->io.NumPorts2,"ide-cs");
-    
-    info->ndev = 0;
-    link->dev = NULL;
-    
-    CardServices(ReleaseConfiguration, link->handle);
-    CardServices(ReleaseIO, link->handle, &link->io);
-    CardServices(ReleaseIRQ, link->handle, &link->irq);
-    
-    link->state &= ~DEV_CONFIG;
+	dev_link_t *link = (dev_link_t *) arg;
+	ide_info_t *info = link->priv;
+
+	DEBUG(0, "ide_release(0x%p)\n", link);
+
+	if (info->ndev) {
+		ide_unregister(&ide_hwifs[info->hd]);
+		MOD_DEC_USE_COUNT;
+	}
+
+	request_region(link->io.BasePort1, link->io.NumPorts1, "ide-cs");
+	if (link->io.NumPorts2)
+		request_region(link->io.BasePort2, link->io.NumPorts2,
+			       "ide-cs");
+
+	info->ndev = 0;
+	link->dev = NULL;
+
+	CardServices(ReleaseConfiguration, link->handle);
+	CardServices(ReleaseIO, link->handle, &link->io);
+	CardServices(ReleaseIRQ, link->handle, &link->irq);
+
+	link->state &= ~DEV_CONFIG;
 
-} /* ide_release */
+}				/* ide_release */
 
 /*======================================================================
 
@@ -427,66 +458,67 @@
     stuff to run after an event is received.  A CARD_REMOVAL event
     also sets some flags to discourage the ide drivers from
     talking to the ports.
-    
+
 ======================================================================*/
 
-int ide_event(event_t event, int priority,
-	      event_callback_args_t *args)
+int ide_event(event_t event, int priority, event_callback_args_t * args)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = args->client_data;
 
-    DEBUG(1, "ide_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    mod_timer(&link->release, jiffies + HZ/20);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	ide_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG)
-	    CardServices(ReleaseConfiguration, link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (DEV_OK(link))
-	    CardServices(RequestConfiguration, link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* ide_event */
+	DEBUG(1, "ide_event(0x%06x)\n", event);
+
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG)
+			mod_timer(&link->release, jiffies + HZ / 20);
+		break;
+	case CS_EVENT_CARD_INSERTION:
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		ide_config(link);
+		break;
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		if (link->state & DEV_CONFIG)
+			CardServices(ReleaseConfiguration, link->handle);
+		break;
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		if (DEV_OK(link))
+			CardServices(RequestConfiguration, link->handle,
+				     &link->conf);
+		break;
+	}
+	return 0;
+}				/* ide_event */
 
 /*====================================================================*/
 
 static int __init init_ide_cs(void)
 {
-    servinfo_t serv;
-    DEBUG(0, "%s\n", version);
-    CardServices(GetCardServicesInfo, &serv);
-    if (serv.Revision != CS_RELEASE_CODE) {
-	printk(KERN_NOTICE "ide_cs: Card Services release "
-	       "does not match!\n");
-	return -1;
-    }
-    register_pccard_driver(&dev_info, &ide_attach, &ide_detach);
-    return 0;
+	servinfo_t serv;
+	DEBUG(0, "%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk(KERN_NOTICE "ide_cs: Card Services release "
+		       "does not match!\n");
+		return -1;
+	}
+	register_pccard_driver(&dev_info, &ide_attach, &ide_detach);
+
+	return 0;
 }
 
 static void __exit exit_ide_cs(void)
 {
-    DEBUG(0, "ide_cs: unloading\n");
-    unregister_pccard_driver(&dev_info);
-    while (dev_list != NULL)
-	ide_detach(dev_list);
+	DEBUG(0, "ide_cs: unloading\n");
+	unregister_pccard_driver(&dev_info);
+	while (dev_list != NULL)
+		ide_detach(dev_list);
 }
 
 module_init(init_ide_cs);
diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/ide-disk.c	Sun Jun 16 19:31:39 2002
@@ -91,143 +91,126 @@
 }
 
 /*
- * Handler for command with PIO data-in phase
+ * Handler for command with PIO data-in phase.
  */
-static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
+static ide_startstop_t pio_in_intr(struct ata_device *drive, struct request *rq)
 {
-	char *buf = NULL;
 	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
+	unsigned int msect;
 
+	spin_lock_irqsave(ch->lock, flags);
 	if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
-		if (drive->status & (ERR_STAT|DRQ_STAT))
-			return ata_error(drive, rq, __FUNCTION__);
+		if (drive->status & (ERR_STAT|DRQ_STAT)) {
+			spin_unlock_irqrestore(ch->lock, flags);
 
-		if (!(drive->status & BUSY_STAT)) {
-#if 0
-			printk("task_in_intr to Soon wait for next interrupt\n");
-#endif
-			ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
-
-			return ide_started;
+			return ata_error(drive, rq, __FUNCTION__);
 		}
-	}
-	buf = ide_map_rq(rq, &flags);
-#if 0
-	printk("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
-#endif
 
-	ata_read(drive, buf, SECTOR_WORDS);
-	ide_unmap_rq(rq, buf, &flags);
-
-	/* First segment of the request is complete. note that this does not
-	 * necessarily mean that the entire request is done!! this is only true
-	 * if ide_end_request() returns 0.
-	 */
-
-	if (--rq->current_nr_sectors <= 0) {
-#if 0
-		printk("Request Ended stat: %02x\n", drive->status);
-#endif
-		if (!ide_end_request(drive, rq, 1))
-			return ide_stopped;
+		if (!(drive->status & BUSY_STAT))
+			goto cont;
 	}
 
-	/* still data left to transfer */
-	ide_set_handler(drive, task_in_intr,  WAIT_CMD, NULL);
+	msect = drive->mult_count;
+	do {
+		unsigned int nsect;
 
-	return ide_started;
-}
+		if (drive->mult_count) {
+			nsect = rq->current_nr_sectors;
+			/* Don't try to transfer more sectors at once then one
+			 * multi sector command can swallow.
+			 */
+			if (nsect > msect)
+				nsect = msect;
+		} else {
+			nsect = rq->current_nr_sectors;
+			nsect = 1;
+		}
 
-/*
- * Handler for command with PIO data-out phase
- */
-static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
-{
-	char *buf = NULL;
-	unsigned long flags;
+//		printk("Read: rq->current_nr_sectors: %d %d %d\n", msect, nsect,  (int) rq->current_nr_sectors);
+		{
+			unsigned long flags;
+			char *buf;
+
+			buf = ide_map_rq(rq, &flags);
+			ata_read(drive, buf, nsect * SECTOR_WORDS);
+			ide_unmap_rq(rq, buf, &flags);
+		}
 
-	if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
-		return ata_error(drive, rq, __FUNCTION__);
+		/* Segment of the request is complete. note that this does not
+		 * necessarily mean that the entire request is done!! this is
+		 * only true if ata_end_request() returns 0.
+		 */
 
-	if (!rq->current_nr_sectors)
-		if (!ide_end_request(drive, rq, 1))
-			return ide_stopped;
+		rq->errors = 0;
+		rq->current_nr_sectors -= nsect;
 
-	if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
-		buf = ide_map_rq(rq, &flags);
-#if 0
-		printk("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
-#endif
+		if (rq->current_nr_sectors <= 0) {
+			if (!__ata_end_request(drive, rq, 1, 0)) {
+				spin_unlock_irqrestore(ch->lock, flags);
 
-		ata_write(drive, buf, SECTOR_WORDS);
-		ide_unmap_rq(rq, buf, &flags);
-		rq->errors = 0;
-		rq->current_nr_sectors--;
-	}
+				return ide_stopped;
+			}
+		}
+		msect -= nsect;
+	} while (msect > 0);
 
-	ide_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
+cont:
+	/* still data left to transfer */
+	ata_set_handler(drive, pio_in_intr,  WAIT_CMD, NULL);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_started;
 }
 
 /*
- * Handler for command with Read Multiple
+ * Handler for command with PIO data-out phase.
  */
-static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
+static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
 {
-	char *buf = NULL;
-	unsigned int msect, nsect;
 	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
+	int ret;
 
-	if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
-		if (drive->status & (ERR_STAT|DRQ_STAT))
-			return ata_error(drive, rq, __FUNCTION__);
+	spin_lock_irqsave(ch->lock, flags);
+	if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) {
+		spin_unlock_irqrestore(ch->lock, flags);
 
-		/* no data yet, so wait for another interrupt */
-		ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
-		return ide_started;
+		return ata_error(drive, rq, __FUNCTION__);
 	}
 
-	/* (ks/hs): Fixed Multi-Sector transfer */
-	msect = drive->mult_count;
-
-	do {
-		nsect = rq->current_nr_sectors;
-		if (nsect > msect)
-			nsect = msect;
-
-		buf = ide_map_rq(rq, &flags);
+	if (!rq->current_nr_sectors && !__ata_end_request(drive, rq, 1, 0)) {
+		ret = ide_stopped;
+	} else {
+		if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
+			unsigned long flags;
+			char *buf;
+
+//			printk("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
+			buf = ide_map_rq(rq, &flags);
+			ata_write(drive, buf, SECTOR_WORDS);
+			ide_unmap_rq(rq, buf, &flags);
 
-#if 0
-		printk("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
-			buf, nsect, rq->current_nr_sectors);
-#endif
-		ata_read(drive, buf, nsect * SECTOR_WORDS);
-		ide_unmap_rq(rq, buf, &flags);
-		rq->errors = 0;
-		rq->current_nr_sectors -= nsect;
-		msect -= nsect;
-		if (!rq->current_nr_sectors) {
-			if (!ide_end_request(drive, rq, 1))
-				return ide_stopped;
+			rq->errors = 0;
+			--rq->current_nr_sectors;
 		}
-	} while (msect);
+		ata_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
 
+		ret = ide_started;
+	}
+	spin_unlock_irqrestore(ch->lock, flags);
 
-	/*
-	 * more data left
-	 */
-	ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
-
-	return ide_started;
+	return ret;
 }
 
 static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	int ok;
-	int mcount = drive->mult_count;
-	ide_startstop_t startstop;
+	int ret;
 
+	spin_lock_irqsave(ch->lock, flags);
 
 	/*
 	 * FIXME: the drive->status checks here seem to be messy.
@@ -240,298 +223,228 @@
 
 	if (!ok || !rq->nr_sectors) {
 		if (drive->status & (ERR_STAT | DRQ_STAT)) {
-			startstop = ata_error(drive, rq, __FUNCTION__);
+			spin_unlock_irqrestore(ch->lock, flags);
 
-			return startstop;
+			return ata_error(drive, rq, __FUNCTION__);
 		}
 	}
-
 	if (!rq->nr_sectors) {
-		__ide_end_request(drive, rq, 1, rq->hard_nr_sectors);
+		__ata_end_request(drive, rq, 1, rq->hard_nr_sectors);
 		rq->bio = NULL;
-
-		return ide_stopped;
-	}
-
-	if (!ok) {
+		ret = ide_stopped;
+	} else if (!ok) {
 		/* no data yet, so wait for another interrupt */
-		if (!drive->channel->handler)
-			ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
-
-		return ide_started;
-	}
-
-	do {
-		char *buffer;
-		int nsect = rq->current_nr_sectors;
-		unsigned long flags;
-
-		if (nsect > mcount)
-			nsect = mcount;
-		mcount -= nsect;
-
-		buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
-		rq->sector += nsect;
-		rq->nr_sectors -= nsect;
-		rq->current_nr_sectors -= nsect;
+		if (!ch->handler)
+			ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+		ret = ide_started;
+	} else {
+		int mcount = drive->mult_count;
 
-		/* Do we move to the next bio after this? */
-		if (!rq->current_nr_sectors) {
-			/* remember to fix this up /jens */
-			struct bio *bio = rq->bio->bi_next;
-
-			/* end early if we ran out of requests */
-			if (!bio) {
-				mcount = 0;
-			} else {
-				rq->bio = bio;
-				rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
+		do {
+			char *buf;
+			int nsect = rq->current_nr_sectors;
+			unsigned long flags;
+
+			if (nsect > mcount)
+				nsect = mcount;
+			mcount -= nsect;
+
+			buf = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
+			rq->sector += nsect;
+			rq->nr_sectors -= nsect;
+			rq->current_nr_sectors -= nsect;
+
+			/* Do we move to the next bio after this? */
+			if (!rq->current_nr_sectors) {
+				/* remember to fix this up /jens */
+				struct bio *bio = rq->bio->bi_next;
+
+				/* end early if we ran out of requests */
+				if (!bio) {
+					mcount = 0;
+				} else {
+					rq->bio = bio;
+					rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
+				}
 			}
-		}
-
-		/*
-		 * Ok, we're all setup for the interrupt re-entering us on the
-		 * last transfer.
-		 */
-		ata_write(drive, buffer, nsect * SECTOR_WORDS);
-		bio_kunmap_irq(buffer, &flags);
-	} while (mcount);
-
-	rq->errors = 0;
-	if (!drive->channel->handler)
-		ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
 
-	return ide_started;
-}
+			/*
+			 * Ok, we're all setup for the interrupt re-entering us on the
+			 * last transfer.
+			 */
+			ata_write(drive, buf, nsect * SECTOR_WORDS);
+			bio_kunmap_irq(buf, &flags);
+		} while (mcount);
 
-/*
- * Decode with physical ATA command to use and setup associated data.
- */
-static u8 get_command(struct ata_device *drive, struct ata_taskfile *ar, int cmd)
-{
-	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
+		rq->errors = 0;
 
-#if 1
-	lba48bit = drive->addressing;
-#endif
+		if (!ch->handler)
+			ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
 
-	if (lba48bit) {
-		if (cmd == READ) {
-			ar->command_type = IDE_DRIVE_TASK_IN;
-			if (drive->using_tcq) {
-				return WIN_READDMA_QUEUED_EXT;
-			} else if (drive->using_dma) {
-				return WIN_READDMA_EXT;
-			} else if (drive->mult_count) {
-				ar->handler = task_mulin_intr;
-				return WIN_MULTREAD_EXT;
-			} else {
-				ar->handler = task_in_intr;
-				return WIN_READ_EXT;
-			}
-		} else if (cmd == WRITE) {
-			ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
-			if (drive->using_tcq) {
-				return WIN_WRITEDMA_QUEUED_EXT;
-			} else if (drive->using_dma) {
-				return WIN_WRITEDMA_EXT;
-			} else if (drive->mult_count) {
-				ar->handler = task_mulout_intr;
-				return WIN_MULTWRITE_EXT;
-			} else {
-				ar->handler = task_out_intr;
-				return WIN_WRITE_EXT;
-			}
-		}
-	} else {
-		if (cmd == READ) {
-			ar->command_type = IDE_DRIVE_TASK_IN;
-			if (drive->using_tcq) {
-				return WIN_READDMA_QUEUED;
-			} else if (drive->using_dma) {
-				return WIN_READDMA;
-			} else if (drive->mult_count) {
-				ar->handler = task_in_intr;
-				return WIN_MULTREAD;
-			} else {
-				ar->handler = task_in_intr;
-				return WIN_READ;
-			}
-		} else if (cmd == WRITE) {
-			ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
-			if (drive->using_tcq) {
-				return WIN_WRITEDMA_QUEUED;
-			} else if (drive->using_dma) {
-				return WIN_WRITEDMA;
-			} else if (drive->mult_count) {
-				ar->handler = task_mulout_intr;
-				return WIN_MULTWRITE;
-			} else {
-				ar->handler = task_out_intr;
-				return WIN_WRITE;
-			}
-		}
+		ret = ide_started;
 	}
+	spin_unlock_irqrestore(ch->lock, flags);
 
-	/* not reached! */
-	return WIN_NOP;
-}
-
-static ide_startstop_t chs_do_request(struct ata_device *drive, struct request *rq, sector_t block)
-{
-	struct ata_taskfile args;
-	int sectors;
-
-	unsigned int track	= (block / drive->sect);
-	unsigned int sect	= (block % drive->sect) + 1;
-	unsigned int head	= (track % drive->head);
-	unsigned int cyl	= (track / drive->head);
-
-	sectors = rq->nr_sectors;
-	if (sectors == 256)
-		sectors = 0;
-
-	memset(&args, 0, sizeof(args));
-
-	if (blk_rq_tagged(rq)) {
-		args.taskfile.feature = sectors;
-		args.taskfile.sector_count = rq->tag << 3;
-	} else
-		args.taskfile.sector_count = sectors;
-
-	args.taskfile.sector_number = sect;
-	args.taskfile.low_cylinder = cyl;
-	args.taskfile.high_cylinder = (cyl>>8);
-
-	args.taskfile.device_head = head;
-	args.taskfile.device_head |= drive->select.all;
-	args.cmd = get_command(drive, &args, rq_data_dir(rq));
-
-#ifdef DEBUG
-	printk("%s: %sing: ", drive->name,
-		(rq_data_dir(rq)==READ) ? "read" : "writ");
-	if (lba)	printk("LBAsect=%lld, ", block);
-	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
-	printk("sectors=%ld, ", rq->nr_sectors);
-	printk("buffer=%p\n", rq->buffer);
-#endif
-
-	rq->special = &args;
-
-	return ata_taskfile(drive, &args, rq);
+	return ide_started;
 }
 
-static ide_startstop_t lba28_do_request(struct ata_device *drive, struct request *rq, sector_t block)
+/*
+ * Channel lock should be held on entry.
+ */
+static ide_startstop_t __do_request(struct ata_device *drive,
+		struct ata_taskfile *ar, struct request *rq)
 {
-	struct ata_taskfile args;
-	int sectors;
-
-	sectors = rq->nr_sectors;
-	if (sectors == 256)
-		sectors = 0;
-
-	memset(&args, 0, sizeof(args));
-
-	if (blk_rq_tagged(rq)) {
-		args.taskfile.feature = sectors;
-		args.taskfile.sector_count = rq->tag << 3;
-	} else
-		args.taskfile.sector_count = sectors;
-
-	args.taskfile.sector_number = block;
-	args.taskfile.low_cylinder = (block >>= 8);
-
-	args.taskfile.high_cylinder = (block >>= 8);
+	struct hd_driveid *id = drive->id;
 
-	args.taskfile.device_head = ((block >> 8) & 0x0f);
-	args.taskfile.device_head |= drive->select.all;
-	args.cmd = get_command(drive, &args, rq_data_dir(rq));
+	/* (ks/hs): Moved to start, do not use for multiple out commands.
+	 * FIXME: why not?! */
+	if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
+	      ar->cmd == WIN_MULTWRITE ||
+	      ar->cmd == WIN_MULTWRITE_EXT)) {
+		ata_irq_enable(drive, 1);
+		ata_mask(drive);
+	}
+
+	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) &&
+	    (drive->addressing == 1))
+		ata_out_regfile(drive, &ar->hobfile);
+
+	ata_out_regfile(drive, &ar->taskfile);
+
+	OUT_BYTE((ar->taskfile.device_head & (drive->addressing ? 0xE0 : 0xEF)) | drive->select.all,
+			IDE_SELECT_REG);
+
+	if (ar->XXX_handler) {
+		struct ata_channel *ch = drive->channel;
+
+		ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL);
+		OUT_BYTE(ar->cmd, IDE_COMMAND_REG);
+
+		/* FIXME: Warning check for race between handler and prehandler
+		 * for writing first block of data.  however since we are well
+		 * inside the boundaries of the seek, we should be okay.
+		 *
+		 * FIXME: Replace the switch by using a proper command_type.
+		 */
 
-#ifdef DEBUG
-	printk("%s: %sing: ", drive->name,
-		(rq_data_dir(rq)==READ) ? "read" : "writ");
-	if (lba)	printk("LBAsect=%lld, ", block);
-	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
-	printk("sectors=%ld, ", rq->nr_sectors);
-	printk("buffer=%p\n", rq->buffer);
-#endif
+		if (ar->cmd == CFA_WRITE_SECT_WO_ERASE ||
+		    ar->cmd == WIN_WRITE ||
+		    ar->cmd == WIN_WRITE_EXT ||
+		    ar->cmd == WIN_WRITE_VERIFY ||
+		    ar->cmd == WIN_WRITE_BUFFER ||
+		    ar->cmd == WIN_DOWNLOAD_MICROCODE ||
+		    ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
+		    ar->cmd == WIN_MULTWRITE ||
+		    ar->cmd == WIN_MULTWRITE_EXT) {
+			ide_startstop_t startstop;
+
+			if (ata_status_poll(drive, DATA_READY, drive->bad_wstat,
+						WAIT_DRQ, rq, &startstop)) {
+				printk(KERN_ERR "%s: no DRQ after issuing %s\n",
+						drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
 
-	rq->special = &args;
+				return startstop;
+			}
 
-	return ata_taskfile(drive, &args, rq);
-}
+			/* FIXME: This doesn't make the slightest sense.
+			 * (ks/hs): Fixed Multi Write
+			 */
+			if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
+			      ar->cmd == WIN_MULTWRITE ||
+			      ar->cmd == WIN_MULTWRITE_EXT)) {
+				unsigned long flags;
+				char *buf = ide_map_rq(rq, &flags);
 
-/*
- * 268435455  == 137439 MB or 28bit limit
- * 320173056  == 163929 MB or 48bit addressing
- * 1073741822 == 549756 MB or 48bit addressing fake drive
- */
+				/* For Write_sectors we need to stuff the first sector */
+				ata_write(drive, buf, SECTOR_WORDS);
 
-static ide_startstop_t lba48_do_request(struct ata_device *drive, struct request *rq, sector_t block)
-{
-	struct ata_taskfile args;
-	int sectors;
+				rq->current_nr_sectors--;
+				ide_unmap_rq(rq, buf, &flags);
 
-	sectors = rq->nr_sectors;
-	if (sectors == 65536)
-		sectors = 0;
+				return ide_started;
+			} else {
+				int i;
+				int ret;
 
-	memset(&args, 0, sizeof(args));
+				/* Polling wait until the drive is ready.
+				 *
+				 * Stuff the first sector(s) by calling the
+				 * handler driectly therafter.
+				 *
+				 * FIXME: Replace hard-coded 100, what about
+				 * error handling?
+				 */
+
+				for (i = 0; i < 100; ++i) {
+					if (drive_is_ready(drive))
+						break;
+				}
+				if (!drive_is_ready(drive)) {
+					printk(KERN_ERR "DISASTER WAITING TO HAPPEN!\n");
+				}
+				/* FIXME: make this unlocking go away*/
+				spin_unlock_irq(ch->lock);
+				ret =  ar->XXX_handler(drive, rq);
+				spin_lock_irq(ch->lock);
 
-	if (blk_rq_tagged(rq)) {
-		args.taskfile.feature = sectors;
-		args.hobfile.feature = sectors >> 8;
-		args.taskfile.sector_count = rq->tag << 3;
+				return ret;
+			}
+		}
 	} else {
-		args.taskfile.sector_count = sectors;
-		args.hobfile.sector_count = sectors >> 8;
-	}
-
-	args.taskfile.sector_number = block;		/* low lba */
-	args.taskfile.low_cylinder = (block >>= 8);	/* mid lba */
-	args.taskfile.high_cylinder = (block >>= 8);	/* hi  lba */
-	args.taskfile.device_head = drive->select.all;
-
-	args.hobfile.sector_number = (block >>= 8);	/* low lba */
-	args.hobfile.low_cylinder = (block >>= 8);	/* mid lba */
-	args.hobfile.high_cylinder = (block >>= 8);	/* hi  lba */
-	args.hobfile.device_head = drive->select.all;
+		/*
+		 * FIXME: This is a gross hack, need to unify tcq dma proc and
+		 * regular dma proc. It should now be easier.
+		 *
+		 * FIXME: Handle the alternateives by a command type.
+		 */
 
-	args.cmd = get_command(drive, &args, rq_data_dir(rq));
+		if (!drive->using_dma)
+			return ide_started;
 
-#ifdef DEBUG
-	printk("%s: %sing: ", drive->name,
-		(rq_data_dir(rq)==READ) ? "read" : "writ");
-	if (lba)	printk("LBAsect=%lld, ", block);
-	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
-	printk("sectors=%ld, ", rq->nr_sectors);
-	printk("buffer=%p\n",rq->buffer);
+		/* for dma commands we don't set the handler */
+		if (ar->cmd == WIN_WRITEDMA ||
+		    ar->cmd == WIN_WRITEDMA_EXT ||
+		    ar->cmd == WIN_READDMA ||
+		    ar->cmd == WIN_READDMA_EXT)
+			return udma_init(drive, rq);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+		else if (ar->cmd == WIN_WRITEDMA_QUEUED ||
+			 ar->cmd == WIN_WRITEDMA_QUEUED_EXT ||
+			 ar->cmd == WIN_READDMA_QUEUED ||
+			 ar->cmd == WIN_READDMA_QUEUED_EXT)
+			return udma_tcq_init(drive, rq);
 #endif
+		else {
+			printk(KERN_ERR "%s: unknown command %x\n", __FUNCTION__, ar->cmd);
+			return ide_stopped;
+		}
+	}
 
-	rq->special = &args;
-
-	return ata_taskfile(drive, &args, rq);
+	return ide_started;
 }
 
 /*
  * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
  * otherwise, to address sectors.  It also takes care of issuing special
  * DRIVE_CMDs.
+ *
+ * Channel lock should be held.
  */
 static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
-	/*
-	 * Wait until all request have bin finished.
-	 */
+	struct ata_taskfile args;
+	unsigned int sectors;
 
-	while (drive->blocked) {
-		yield();
-		printk(KERN_ERR "ide: Request while drive blocked?");
-	}
+	/* This issues a special drive command.
+	 */
+	if (rq->flags & REQ_SPECIAL)
+		return __do_request(drive, rq->special, rq);
 
+	/* FIXME: this check doesn't make sense */
 	if (!(rq->flags & REQ_CMD)) {
 		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
-		ide_end_request(drive, rq, 0);
+		__ata_end_request(drive, rq, 0, 0);
+
 		return ide_stopped;
 	}
 
@@ -545,39 +458,176 @@
 	 * start a tagged operation
 	 */
 	if (drive->using_tcq) {
-		unsigned long flags;
-		int ret;
-
-		spin_lock_irqsave(drive->channel->lock, flags);
-
-		ret = blk_queue_start_tag(&drive->queue, rq);
+		int st = blk_queue_start_tag(&drive->queue, rq);
 
 		if (ata_pending_commands(drive) > drive->max_depth)
 			drive->max_depth = ata_pending_commands(drive);
 		if (ata_pending_commands(drive) > drive->max_last_depth)
 			drive->max_last_depth = ata_pending_commands(drive);
 
-		spin_unlock_irqrestore(drive->channel->lock, flags);
-
-		if (ret) {
+		if (st) {
 			BUG_ON(!ata_pending_commands(drive));
+
 			return ide_started;
 		}
 	}
 
-	/* 48-bit LBA */
-	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
-		return lba48_do_request(drive, rq, block);
+	memset(&args, 0, sizeof(args));
+	sectors = rq->nr_sectors;
+	/* Dispatch depending up on the drive access method. */
+	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) {
+		/* LBA 48 bit */
+		/*
+		 * 268435455  == 137439 MB or 28bit limit
+		 * 320173056  == 163929 MB or 48bit addressing
+		 * 1073741822 == 549756 MB or 48bit addressing fake drive
+		 */
+		if (sectors == 65536)
+			sectors = 0;
 
-	/* 28-bit LBA */
-	if (drive->select.b.lba)
-		return lba28_do_request(drive, rq, block);
+		if (blk_rq_tagged(rq)) {
+			args.taskfile.feature = sectors;
+			args.hobfile.feature = sectors >> 8;
+			args.taskfile.sector_count = rq->tag << 3;
+		} else {
+			args.taskfile.sector_count = sectors;
+			args.hobfile.sector_count = sectors >> 8;
+		}
 
-	/* 28-bit CHS */
-	return chs_do_request(drive, rq, block);
+		args.taskfile.sector_number = block;		/* low lba */
+		args.taskfile.low_cylinder = (block >>= 8);	/* mid lba */
+		args.taskfile.high_cylinder = (block >>= 8);	/* hi  lba */
+		args.taskfile.device_head = drive->select.all;
+
+		args.hobfile.sector_number = (block >>= 8);	/* low lba */
+		args.hobfile.low_cylinder = (block >>= 8);	/* mid lba */
+		args.hobfile.high_cylinder = (block >>= 8);	/* hi  lba */
+	} else if (drive->select.b.lba) {
+		/* LBA 28 bit  */
+		if (sectors == 256)
+			sectors = 0;
+
+		if (blk_rq_tagged(rq)) {
+			args.taskfile.feature = sectors;
+			args.taskfile.sector_count = rq->tag << 3;
+		} else
+			args.taskfile.sector_count = sectors;
+
+		args.taskfile.sector_number = block;
+		args.taskfile.low_cylinder = (block >>= 8);
+		args.taskfile.high_cylinder = (block >>= 8);
+		args.taskfile.device_head = ((block >> 8) & 0x0f);
+	} else {
+		/* CHS */
+		unsigned int track	= (block / drive->sect);
+		unsigned int sect	= (block % drive->sect) + 1;
+		unsigned int head	= (track % drive->head);
+		unsigned int cyl	= (track / drive->head);
+
+		if (sectors == 256)
+			sectors = 0;
+
+		if (blk_rq_tagged(rq)) {
+			args.taskfile.feature = sectors;
+			args.taskfile.sector_count = rq->tag << 3;
+		} else
+			args.taskfile.sector_count = sectors;
+
+		args.taskfile.sector_number = sect;
+		args.taskfile.low_cylinder = cyl;
+		args.taskfile.high_cylinder = (cyl>>8);
+		args.taskfile.device_head = head;
+	}
+	args.taskfile.device_head |= drive->select.all;
+
+	/*
+	 * Decode with physical ATA command to use and setup associated data.
+	 */
+
+	if (rq_data_dir(rq) == READ) {
+		args.command_type = IDE_DRIVE_TASK_IN;
+		if (drive->addressing) {
+			if (drive->using_tcq) {
+				args.cmd = WIN_READDMA_QUEUED_EXT;
+			} else if (drive->using_dma) {
+				args.cmd = WIN_READDMA_EXT;
+			} else if (drive->mult_count) {
+				args.XXX_handler = pio_in_intr;
+				args.cmd = WIN_MULTREAD_EXT;
+			} else {
+				args.XXX_handler = pio_in_intr;
+				args.cmd = WIN_READ_EXT;
+			}
+		} else {
+			if (drive->using_tcq) {
+				args.cmd = WIN_READDMA_QUEUED;
+			} else if (drive->using_dma) {
+				args.cmd = WIN_READDMA;
+			} else if (drive->mult_count) {
+				args.XXX_handler = pio_in_intr;
+				args.cmd = WIN_MULTREAD;
+			} else {
+				args.XXX_handler = pio_in_intr;
+				args.cmd = WIN_READ;
+			}
+		}
+	} else {
+		args.command_type = IDE_DRIVE_TASK_RAW_WRITE;
+		if (drive->addressing) {
+			if (drive->using_tcq) {
+				args.cmd = WIN_WRITEDMA_QUEUED_EXT;
+			} else if (drive->using_dma) {
+				args.cmd = WIN_WRITEDMA_EXT;
+			} else if (drive->mult_count) {
+				args.XXX_handler = task_mulout_intr;
+				args.cmd = WIN_MULTWRITE_EXT;
+			} else {
+				args.XXX_handler = task_out_intr;
+				args.cmd = WIN_WRITE_EXT;
+			}
+		} else {
+			if (drive->using_tcq) {
+				args.cmd = WIN_WRITEDMA_QUEUED;
+			} else if (drive->using_dma) {
+				args.cmd = WIN_WRITEDMA;
+			} else if (drive->mult_count) {
+				args.XXX_handler = task_mulout_intr;
+				args.cmd = WIN_MULTWRITE;
+			} else {
+				args.XXX_handler = task_out_intr;
+				args.cmd = WIN_WRITE;
+			}
+		}
+	}
+
+
+#ifdef DEBUG
+	printk("%s: %sing: ", drive->name,
+			(rq_data_dir(rq)==READ) ? "read" : "writ");
+	if (lba)	printk("LBAsect=%lld, ", block);
+	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
+	printk("sectors=%ld, ", rq->nr_sectors);
+	printk("buffer=%p\n", rq->buffer);
+#endif
+	rq->special = &args;
+
+	return __do_request(drive, &args, rq);
+}
+
+/*
+ * Small helper function used to execute simple commands.
+ */
+static int simple_taskfile(struct ata_device *drive, u8 cmd)
+{
+	struct ata_taskfile args;
+
+	memset(&args, 0, sizeof(args));
+	args.cmd = cmd;
+
+	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static int idedisk_open (struct inode *inode, struct file *filp, struct ata_device *drive)
+static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_device *drive)
 {
 	MOD_INC_USE_COUNT;
 	if (drive->removable && drive->usage == 1) {
@@ -585,51 +635,40 @@
 
 		/*
 		 * Ignore the return code from door_lock, since the open() has
-		 * already succeeded once, and the door_lock is irrelevant at this
-		 * time.
+		 * already succeeded once, and the door_lock is irrelevant at
+		 * this time.
 		 */
 		if (drive->doorlocking) {
-			struct ata_taskfile args;
-
-			memset(&args, 0, sizeof(args));
-			args.cmd = WIN_DOORLOCK;
-			if (ide_raw_taskfile(drive, &args))
+			if (simple_taskfile(drive, WIN_DOORLOCK))
 				drive->doorlocking = 0;
 		}
 	}
+
 	return 0;
 }
 
-static int idedisk_flushcache(struct ata_device *drive)
+static int flush_cache(struct ata_device *drive)
 {
-	struct ata_taskfile args;
-
-	memset(&args, 0, sizeof(args));
+	u8 cmd;
 
 	if (drive->id->cfs_enable_2 & 0x2400)
-		args.cmd = WIN_FLUSH_CACHE_EXT;
+		cmd = WIN_FLUSH_CACHE_EXT;
 	else
-		args.cmd = WIN_FLUSH_CACHE;
-	return ide_raw_taskfile(drive, &args);
+		cmd = WIN_FLUSH_CACHE;
+
+	return simple_taskfile(drive, cmd);
 }
 
 static void idedisk_release(struct inode *inode, struct file *filp, struct ata_device *drive)
 {
 	if (drive->removable && !drive->usage) {
-		/* XXX I don't think this is up to the lowlevel drivers..  --hch */
-		invalidate_bdev(inode->i_bdev, 0);
-
 		if (drive->doorlocking) {
-			struct ata_taskfile args;
-
-			memset(&args, 0, sizeof(args));
-			args.cmd = WIN_DOORUNLOCK;
-			if (ide_raw_taskfile(drive, &args))
+			if (simple_taskfile(drive, WIN_DOORUNLOCK))
 				drive->doorlocking = 0;
 		}
 	}
 	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
-		if (idedisk_flushcache(drive))
+		if (flush_cache(drive))
 			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
 				drive->name);
 	MOD_DEC_USE_COUNT;
@@ -671,7 +710,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.sector_count = arg;
 	args.cmd = WIN_SETMULT;
-	if (!ide_raw_taskfile(drive, &args)) {
+	if (!ide_raw_taskfile(drive, &args, NULL)) {
 		/* all went well track this setting as valid */
 		drive->mult_count = arg;
 
@@ -700,7 +739,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature	= (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
 	args.cmd = WIN_SETFEATURES;
-	ide_raw_taskfile(drive, &args);
+	ide_raw_taskfile(drive, &args, NULL);
 
 	drive->wcache = arg;
 
@@ -709,11 +748,7 @@
 
 static int idedisk_standby(struct ata_device *drive)
 {
-	struct ata_taskfile args;
-
-	memset(&args, 0, sizeof(args));
-	args.cmd = WIN_STANDBYNOW1;
-	return ide_raw_taskfile(drive, &args);
+	return simple_taskfile(drive, WIN_STANDBYNOW1);
 }
 
 static int set_acoustic(struct ata_device *drive, int arg)
@@ -724,7 +759,7 @@
 	args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
 	args.taskfile.sector_count = arg;
 	args.cmd = WIN_SETFEATURES;
-	ide_raw_taskfile(drive, &args);
+	ide_raw_taskfile(drive, &args, NULL);
 
 	drive->acoustic = arg;
 
@@ -821,9 +856,10 @@
 /* This is just a hook for the overall driver tree.
  */
 
-static struct device_driver idedisk_devdrv = {
-	suspend: idedisk_suspend,
-	resume: idedisk_resume,
+static struct device_driver disk_devdrv = {
+	.lock = RW_LOCK_UNLOCKED,
+	.suspend = idedisk_suspend,
+	.resume = idedisk_resume,
 };
 
 /*
@@ -843,7 +879,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.device_head = 0x40;
 	args.cmd = WIN_READ_NATIVE_MAX;
-	ide_raw_taskfile(drive, &args);
+	ide_raw_taskfile(drive, &args, NULL);
 
 	/* if OK, compute maximum address value */
 	if (!(drive->status & ERR_STAT)) {
@@ -865,10 +901,9 @@
 
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(args));
-
 	args.taskfile.device_head = 0x40;
 	args.cmd = WIN_READ_NATIVE_MAX_EXT;
-        ide_raw_taskfile(drive, &args);
+        ide_raw_taskfile(drive, &args, NULL);
 
 	/* if OK, compute maximum address value */
 	if (!(drive->status & ERR_STAT)) {
@@ -906,7 +941,7 @@
 
 	args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
 	args.cmd = WIN_SET_MAX;
-	ide_raw_taskfile(drive, &args);
+	ide_raw_taskfile(drive, &args, NULL);
 
 	/* if OK, read new maximum address value */
 	if (!(drive->status & ERR_STAT)) {
@@ -939,7 +974,7 @@
 	args.hobfile.high_cylinder = (addr_req >>= 8);
 	args.hobfile.device_head = 0x40;
 
-	ide_raw_taskfile(drive, &args);
+	ide_raw_taskfile(drive, &args, NULL);
 
 	/* if OK, compute maximum address value */
 	if (!(drive->status & ERR_STAT)) {
@@ -964,6 +999,7 @@
 	sector_t capacity;
 	sector_t set_max;
 	int drvid = -1;
+	struct ata_channel *ch = drive->channel;
 
 	if (id == NULL)
 		return;
@@ -973,35 +1009,31 @@
 	 * to us, but they are removable and don't have a doorlock mechanism.
 	 */
 	if (drive->removable && !drive_is_flashcard(drive)) {
-		/*
-		 * Removable disks (eg. SYQUEST); ignore 'WD' drives.
+		/* Removable disks (eg. SYQUEST); ignore 'WD' drives.
 		 */
-		if (id->model[0] != 'W' || id->model[1] != 'D') {
+		if (!strncmp(id->model, "WD", 2))
 			drive->doorlocking = 1;
-		}
 	}
-	for (i = 0; i < MAX_DRIVES; ++i) {
-		struct ata_channel *hwif = drive->channel;
 
-		if (drive != &hwif->drives[i])
+	for (i = 0; i < MAX_DRIVES; ++i) {
+		if (drive != &ch->drives[i])
 		    continue;
 		drvid = i;
-		hwif->gd->de_arr[i] = drive->de;
+		ch->gd->de_arr[i] = drive->de;
 		if (drive->removable)
-			hwif->gd->flags[i] |= GENHD_FL_REMOVABLE;
+			ch->gd->flags[i] |= GENHD_FL_REMOVABLE;
 		break;
 	}
 
 	/* Register us within the device tree.
 	 */
-
 	if (drvid != -1) {
-		sprintf(drive->device.bus_id, "%d", drvid);
-		sprintf(drive->device.name, "ide-disk");
-		drive->device.driver = &idedisk_devdrv;
-		drive->device.parent = &drive->channel->dev;
-		drive->device.driver_data = drive;
-		device_register(&drive->device);
+		sprintf(drive->dev.bus_id, "sd@%x,%x", ch->unit, drvid);
+		strcpy(drive->dev.name, "ATA-Disk");
+		drive->dev.driver = &disk_devdrv;
+		drive->dev.parent = &ch->dev;
+		drive->dev.driver_data = drive;
+		device_register(&drive->dev);
 	}
 
 	/* Extract geometry if we did not already have one for the drive */
@@ -1126,7 +1158,6 @@
 	printk(KERN_INFO " %s: %ld sectors", drive->name, capacity);
 
 #if 0
-
 	/* Right now we avoid this calculation, since it can result in the
 	 * usage of not supported compiler internal functions on 32 bit hosts.
 	 * However since the calculation appears to be an interesting piece of
@@ -1193,15 +1224,27 @@
 
 static int idedisk_cleanup(struct ata_device *drive)
 {
+	int ret;
+
 	if (!drive)
 	    return 0;
 
-	put_device(&drive->device);
-	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
-		if (idedisk_flushcache(drive))
+	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) {
+		if (flush_cache(drive))
 			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
 				drive->name);
-	return ide_unregister_subdriver(drive);
+	}
+	ret = ide_unregister_subdriver(drive);
+
+	/* FIXME: This is killing the kernel with BUG 185 at asm/spinlocks.h
+	 * horribly.  Check whatever we did REGISTER the device properly
+	 * in front?
+	 */
+#if 0
+	put_device(&drive->device);
+#endif
+
+	return ret;
 }
 
 static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/ide-floppy.c	Sun Jun 16 19:31:39 2002
@@ -608,7 +608,7 @@
 /*
  *	idefloppy_end_request is used to finish servicing a request.
  *
- *	For read/write requests, we will call ide_end_request to pass to the
+ *	For read/write requests, we will call ata_end_request to pass to the
  *	next buffer.
  */
 static int idefloppy_end_request(struct ata_device *drive, struct request *rq, int uptodate)
@@ -632,7 +632,7 @@
 		return 0;
 
 	if (!(rq->flags & REQ_SPECIAL)) {
-		ide_end_request(drive, rq, uptodate);
+		ata_end_request(drive, rq, uptodate);
 		return 0;
 	}
 
@@ -821,6 +821,8 @@
  */
 static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	idefloppy_status_reg_t status;
 	idefloppy_bcount_reg_t bcount;
@@ -833,7 +835,7 @@
 #endif
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
+	if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
 		if (udma_stop(drive)) {
 			set_bit (PC_DMA_ERROR, &pc->flags);
 		} else {
@@ -883,15 +885,24 @@
 		return ide_stopped;
 	}
 #endif
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
 	bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG);			/* Get the number of bytes to transfer */
 	bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG);			/* on this interrupt */
 	ireason.all=IN_BYTE (IDE_IREASON_REG);
 
 	if (ireason.b.cod) {
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		printk (KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n");
 		return ide_stopped;
 	}
 	if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) {	/* Hopefully, we will never get here */
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		printk (KERN_ERR "ide-floppy: We wanted to %s, ", ireason.b.io ? "Write":"Read");
 		printk (KERN_ERR "but the floppy wants us to %s !\n",ireason.b.io ? "Read":"Write");
 		return ide_stopped;
@@ -901,8 +912,11 @@
 		if ( temp > pc->request_transfer) {
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
+
 				atapi_discard_data (drive,bcount.all);
-				ide_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
+				ata_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
+				spin_unlock_irqrestore(ch->lock, flags);
+
 				return ide_started;
 			}
 #if IDEFLOPPY_DEBUG_LOG
@@ -924,7 +938,8 @@
 	pc->actually_transferred+=bcount.all;				/* Update the current position */
 	pc->current_position+=bcount.all;
 
-	ide_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
+	ata_set_handler(drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_started;
 }
@@ -936,24 +951,36 @@
  */
 static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	ide_startstop_t startstop;
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	idefloppy_ireason_reg_t ireason;
+	int ret;
 
-	if (ide_wait_stat (&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	/* FIXME: Move this lock upwards.
+	 */
+	spin_lock_irqsave(ch->lock, flags);
+	if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+				WAIT_READY, rq, &startstop)) {
 		printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
-		return startstop;
-	}
-	ireason.all=IN_BYTE (IDE_IREASON_REG);
-	if (!ireason.b.cod || ireason.b.io) {
-		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
-		return ide_stopped;
-	}
 
-	ide_set_handler (drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
-	atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
+		ret = startstop;
+	} else {
+		ireason.all=IN_BYTE (IDE_IREASON_REG);
 
-	return ide_started;
+		if (!ireason.b.cod || ireason.b.io) {
+			printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
+			ret = ide_stopped;
+		} else {
+			ata_set_handler (drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
+			atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
+			ret = ide_started;
+		}
+	}
+	spin_unlock_irqrestore(ch->lock, flags);
+
+	return ret;
 }
 
 
@@ -979,32 +1006,48 @@
 
 static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	ide_startstop_t startstop;
 	idefloppy_ireason_reg_t ireason;
+	int ret;
 
-	if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+				WAIT_READY, rq, &startstop)) {
 		printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
+
 		return startstop;
 	}
-	ireason.all=IN_BYTE (IDE_IREASON_REG);
+
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
+	ireason.all=IN_BYTE(IDE_IREASON_REG);
 	if (!ireason.b.cod || ireason.b.io) {
 		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
-		return ide_stopped;
+		ret = ide_stopped;
+	} else {
+
+		/*
+		 * The following delay solves a problem with ATAPI Zip 100 drives where
+		 * the Busy flag was apparently being deasserted before the unit was
+		 * ready to receive data. This was happening on a 1200 MHz Athlon
+		 * system. 10/26/01 25msec is too short, 40 and 50msec work well.
+		 * idefloppy_pc_intr will not be actually used until after the packet
+		 * is moved in about 50 msec.
+		 */
+		ata_set_handler(drive,
+				idefloppy_pc_intr,	/* service routine for packet command */
+				floppy->ticks,		/* wait this long before "failing" */
+				idefloppy_transfer_pc2);	/* fail == transfer_pc2 */
+		ret = ide_started;
 	}
-	/*
-	 * The following delay solves a problem with ATAPI Zip 100 drives where the
-	 * Busy flag was apparently being deasserted before the unit was ready to
-	 * receive data. This was happening on a 1200 MHz Athlon system. 10/26/01
-	 * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will
-	 * not be actually used until after the packet is moved in about 50 msec.
-	 */
-	ide_set_handler(drive,
-	  idefloppy_pc_intr,		/* service routine for packet command */
-	  floppy->ticks,		/* wait this long before "failing" */
-	  idefloppy_transfer_pc2);	/* fail == transfer_pc2 */
+	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 /*
@@ -1047,7 +1090,7 @@
 	}
 #if IDEFLOPPY_DEBUG_LOG
 	printk (KERN_INFO "Retry number - %d\n",pc->retries);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+#endif
 
 	pc->retries++;
 	pc->actually_transferred=0;					/* We haven't transferred any data yet */
@@ -1059,7 +1102,7 @@
 		udma_enable(drive, 0, 1);
 
 	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-		dma_ok = !udma_init(drive, rq);
+		dma_ok = udma_init(drive, rq);
 #endif
 
 	ata_irq_enable(drive, 1);
@@ -1082,9 +1125,19 @@
 		pkt_xfer_routine = &idefloppy_transfer_pc;	/* immediate */
 	}
 
-	if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
-		ide_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
+	if (test_bit(IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
+		unsigned long flags;
+		struct ata_channel *ch = drive->channel;
+
+		/* FIXME: this locking should encompass the above register
+		 * file access too.
+		 */
+
+		spin_lock_irqsave(ch->lock, flags);
+		ata_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return ide_started;
 	} else {
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -1224,8 +1277,10 @@
  */
 static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
+	struct ata_channel *ch = drive->channel;
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	struct atapi_packet_command *pc;
+	int ret;
 
 #if IDEFLOPPY_DEBUG_LOG
 	printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors);
@@ -1238,13 +1293,22 @@
 				drive->name, floppy->failed_pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
 		else
 			printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name);
+
+		/* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
 		idefloppy_end_request(drive, rq, 0);
+		spin_lock_irq(ch->lock);
+
 		return ide_stopped;
 	}
 	if (rq->flags & REQ_CMD) {
 		if (rq->sector % floppy->bs_factor || rq->nr_sectors % floppy->bs_factor) {
 			printk ("%s: unsupported r/w request size\n", drive->name);
+			/* FIXME: make this unlocking go away*/
+			spin_unlock_irq(ch->lock);
 			idefloppy_end_request(drive, rq, 0);
+			spin_lock_irq(ch->lock);
+
 			return ide_stopped;
 		}
 		pc = idefloppy_next_pc_storage(drive);
@@ -1254,11 +1318,20 @@
 		pc = (struct atapi_packet_command *) rq->buffer;
 	} else {
 		blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue");
+		/* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
 		idefloppy_end_request(drive, rq, 0);
+		spin_lock_irq(ch->lock);
+
 		return ide_stopped;
 	}
 
-	return idefloppy_issue_pc(drive, rq, pc);
+	/* FIXME: make this unlocking go away*/
+	spin_unlock_irq(ch->lock);
+	ret = idefloppy_issue_pc(drive, rq, pc);
+	spin_lock_irq(ch->lock);
+
+	return ret;
 }
 
 /*
@@ -1749,8 +1822,6 @@
 
 	if (!drive->usage) {
 		idefloppy_floppy_t *floppy = drive->driver_data;
-
-		invalidate_bdev (inode->i_bdev, 0);
 
 		/* IOMEGA Clik! drives do not support lock/unlock commands */
                 if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
diff -Nru a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c
--- a/drivers/ide/ide-pmac.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/ide-pmac.c	Sun Jun 16 19:31:41 2002
@@ -1,6 +1,4 @@
 /*
- * linux/drivers/ide/ide-pmac.c		Version ?.??	Mar. 18, 2000
- *
  * Support for IDE interfaces on PowerMacs.
  * These IDE interfaces are memory-mapped and have a DBDMA channel
  * for doing DMA.
@@ -343,21 +341,6 @@
 	}
 }
 
-#if 0
-/* This one could be later extended to handle CMD IDE and be used by some kind
- * of /proc interface. I want to be able to get the devicetree path of a block
- * device for yaboot configuration
- */
-struct device_node*
-pmac_ide_get_devnode(struct ata_device *drive)
-{
-	int i = pmac_ide_find(drive);
-	if (i < 0)
-		return NULL;
-	return pmac_ide[i].node;
-}
-#endif
-
 /* Setup timings for the selected drive (master/slave). I still need to verify if this
  * is enough, I beleive selectproc will be called whenever an IDE command is started,
  * but... */
@@ -1367,7 +1350,8 @@
 	 */
 	ix = pmac_ide_find(drive);
 	if (ix < 0)
-		return 0;
+		return ide_stopped;
+
 	dma = pmac_ide[ix].dma_regs;
 	ata4 = (pmac_ide[ix].kind == controller_kl_ata4 ||
 		pmac_ide[ix].kind == controller_kl_ata4_80);
@@ -1375,7 +1359,8 @@
 	out_le32(&dma->control, (RUN << 16) | RUN);
 	/* Make sure it gets to the controller right now */
 	(void)in_le32(&dma->control);
-	return 0;
+
+	return ide_started;
 }
 
 static int pmac_udma_stop(struct ata_device *drive)
@@ -1413,7 +1398,7 @@
 	 */
 	ix = pmac_ide_find(drive);
 	if (ix < 0)
-		return 0;
+		return ide_stopped;
 
 	if (rq_data_dir(rq) == READ)
 		reading = 1;
@@ -1425,7 +1410,7 @@
 		pmac_ide[ix].kind == controller_kl_ata4_80);
 
 	if (!pmac_ide_build_dmatable(drive, rq, ix, !reading))
-		return 1;
+		return ide_stopped;
 	/* Apple adds 60ns to wrDataSetup on reads */
 	if (ata4 && (pmac_ide[ix].timings[unit] & TR_66_UDMA_EN)) {
 		out_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE),
@@ -1435,8 +1420,9 @@
 	}
 	drive->waiting_for_dma = 1;
 	if (drive->type != ATA_DISK)
-		return 0;
-	ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
+		return ide_started;
+
+	ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
 	if ((rq->flags & REQ_SPECIAL) &&
 		(drive->addressing == 1)) {
 		struct ata_taskfile *args = rq->special;
@@ -1448,7 +1434,9 @@
 		OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 	}
 
-	return udma_start(drive, rq);
+	udma_start(drive, rq);
+
+	return ide_started;
 }
 
 /*
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/ide-tape.c	Sun Jun 16 19:31:39 2002
@@ -892,7 +892,7 @@
 	struct bio *bio;
 	char *b_data;
 	int b_count;
-	
+
 	/*
 	 *	Pipeline parameters.
 	 *
@@ -1864,6 +1864,7 @@
 				idetape_increase_max_pipeline_stages (drive);
 		}
 	}
+
 	blkdev_dequeue_request(rq);
 	drive->rq = NULL;
 	end_that_request_last(rq);
@@ -1977,6 +1978,8 @@
  */
 static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	idetape_tape_t *tape = drive->driver_data;
 	idetape_status_reg_t status;
 	idetape_bcount_reg_t bcount;
@@ -2064,6 +2067,7 @@
 			tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST;
 			tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
 			idetape_postpone_request(drive, rq);		/* Allow ide.c to handle other requests */
+
 			return ide_stopped;
 		}
 		if (tape->failed_pc == pc)
@@ -2071,24 +2075,35 @@
 		pc->callback(drive, rq);	/* Command finished - Call the callback function */
 		return ide_stopped;
 	}
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
 		printk (KERN_ERR "ide-tape: The tape wants to issue more interrupts in DMA mode\n");
 		printk (KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
 		udma_enable(drive, 0, 1);
+		spin_unlock_irqrestore(ch->lock, flags);
 
 		return ide_stopped;
 	}
 #endif
+
 	bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG);			/* Get the number of bytes to transfer */
 	bcount.b.low  = IN_BYTE (IDE_BCOUNTL_REG);			/* on this interrupt */
 	ireason.all   = IN_BYTE (IDE_IREASON_REG);
 
 	if (ireason.b.cod) {
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n");
 		return ide_stopped;
 	}
 	if (ireason.b.io == test_bit (PC_WRITING, &pc->flags)) {	/* Hopefully, we will never get here */
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		printk (KERN_ERR "ide-tape: We wanted to %s, ", ireason.b.io ? "Write":"Read");
 		printk (KERN_ERR "ide-tape: but the tape wants us to %s !\n",ireason.b.io ? "Read":"Write");
 		return ide_stopped;
@@ -2099,7 +2114,9 @@
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
 				atapi_discard_data (drive, bcount.all);
-				ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
+				ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
+				spin_unlock_irqrestore(ch->lock, flags);
+
 				return ide_started;
 			}
 #if IDETAPE_DEBUG_LOG
@@ -2125,7 +2142,9 @@
 	if (tape->debug_level >= 2)
 		printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all);
 #endif
-	ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* And set the interrupt handler again */
+	ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* And set the interrupt handler again */
+	spin_unlock_irqrestore(ch->lock, flags);
+
 	return ide_started;
 }
 
@@ -2173,36 +2192,48 @@
  */
 static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	idetape_tape_t *tape = drive->driver_data;
 	struct atapi_packet_command *pc = tape->pc;
 	idetape_ireason_reg_t ireason;
 	int retries = 100;
 	ide_startstop_t startstop;
+	int ret;
 
-	if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	/* FIXME: Move this lock upwards.
+	 */
+	spin_lock_irqsave(ch->lock, flags);
+	if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+				WAIT_READY, rq, &startstop)) {
 		printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
-		return startstop;
-	}
-	ireason.all = IN_BYTE (IDE_IREASON_REG);
-	while (retries-- && (!ireason.b.cod || ireason.b.io)) {
-		printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
-		udelay(100);
-		ireason.all = IN_BYTE(IDE_IREASON_REG);
-		if (retries == 0) {
-			printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, ignoring\n");
-			ireason.b.cod = 1;
-			ireason.b.io = 0;
+
+		ret = startstop;
+	} else {
+		ireason.all = IN_BYTE (IDE_IREASON_REG);
+		while (retries-- && (!ireason.b.cod || ireason.b.io)) {
+			printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
+			udelay(100);
+			ireason.all = IN_BYTE(IDE_IREASON_REG);
+			if (retries == 0) {
+				printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, ignoring\n");
+				ireason.b.cod = 1;
+				ireason.b.io = 0;
+			}
+		}
+		if (!ireason.b.cod || ireason.b.io) {
+			printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
+			ret = ide_stopped;
+		} else {
+			tape->cmd_start_time = jiffies;
+			ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* Set the interrupt routine */
+			atapi_write(drive,pc->c,12);	/* Send the actual packet */
+			ret = ide_started;
 		}
 	}
-	if (!ireason.b.cod || ireason.b.io) {
-		printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
-		return ide_stopped;
-	}
-	tape->cmd_start_time = jiffies;
-	ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* Set the interrupt routine */
-	atapi_write(drive,pc->c,12);	/* Send the actual packet */
+	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
@@ -2259,7 +2290,7 @@
 		udma_enable(drive, 0, 1);
 	}
 	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-		dma_ok = !udma_init(drive, rq);
+		dma_ok = udma_init(drive, rq);
 #endif
 
 	ata_irq_enable(drive, 1);
@@ -2274,8 +2305,18 @@
 	}
 #endif
 	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
-		ide_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
+		unsigned long flags;
+		struct ata_channel *ch = drive->channel;
+
+		/* FIXME: this locking should encompass the above register
+		 * file access too.
+		 */
+
+		spin_lock_irqsave(ch->lock, flags);
+		ata_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
 		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return ide_started;
 	} else {
 		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -2564,10 +2605,12 @@
  */
 static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
+	struct ata_channel *ch = drive->channel;
 	idetape_tape_t *tape = drive->driver_data;
 	struct atapi_packet_command *pc;
 	struct request *postponed_rq = tape->postponed_rq;
 	idetape_status_reg_t status;
+	int ret;
 
 #if IDETAPE_DEBUG_LOG
 /*	if (tape->debug_level >= 5)
@@ -2581,7 +2624,7 @@
 		 *	We do not support buffer cache originated requests.
 		 */
 		printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%ld)\n", drive->name, rq->flags);
-		ide_end_request(drive, rq, 0);			/* Let the common code handle it */
+		__ata_end_request(drive, rq, 0, 0);			/* Let the common code handle it */
 		return ide_stopped;
 	}
 
@@ -2589,13 +2632,24 @@
 	 *	Retry a failed packet command
 	 */
 	if (tape->failed_pc != NULL && tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
-		return idetape_issue_packet_command(drive, rq, tape->failed_pc);
+		int ret;
+
+		/* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
+		ret = idetape_issue_packet_command(drive, rq, tape->failed_pc);
+		spin_lock_irq(ch->lock);
+
+		return ret;
 	}
 #if IDETAPE_DEBUG_BUGS
 	if (postponed_rq != NULL)
 		if (rq != postponed_rq) {
 			printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests were queued\n");
+			/* FIXME: make this unlocking go away*/
+			spin_unlock_irq(ch->lock);
 			idetape_end_request(drive, rq, 0);
+			spin_lock_irq(ch->lock);
+
 			return ide_stopped;
 		}
 #endif
@@ -2616,7 +2670,7 @@
 	if (tape->onstream)
 		status.b.dsc = 1;
 	if (!drive->dsc_overlap && rq->flags != IDETAPE_PC_RQ2)
-		set_bit (IDETAPE_IGNORE_DSC, &tape->flags);
+		set_bit(IDETAPE_IGNORE_DSC, &tape->flags);
 
 	/*
 	 * For the OnStream tape, check the current status of the tape
@@ -2661,7 +2715,7 @@
 			tape->req_buffer_fill = 1;
 		}
 #if ONSTREAM_DEBUG
-		else if (tape->debug_level >= 4) 
+		else if (tape->debug_level >= 4)
 			printk(KERN_INFO "ide-tape: %s: postpone_cnt %d\n", tape->name, tape->postpone_cnt);
 #endif
 	}
@@ -2673,7 +2727,10 @@
 		} else if ((signed long) (jiffies - tape->dsc_timeout) > 0) {
 			printk (KERN_ERR "ide-tape: %s: DSC timeout\n", tape->name);
 			if (rq->flags == IDETAPE_PC_RQ2) {
+				/* FIXME: make this unlocking go away*/
+				spin_unlock_irq(ch->lock);
 				idetape_media_access_finished(drive, rq);
+				spin_lock_irq(ch->lock);
 				return ide_stopped;
 			} else {
 				return ide_stopped;
@@ -2681,6 +2738,7 @@
 		} else if (jiffies - tape->dsc_polling_start > IDETAPE_DSC_MA_THRESHOLD)
 			tape->dsc_polling_frequency = IDETAPE_DSC_MA_SLOW;
 		idetape_postpone_request(drive, rq);
+
 		return ide_stopped;
 	}
 	switch (rq->flags) {
@@ -2697,8 +2755,8 @@
 				if (jiffies > tape->last_buffer_fill + 5 * HZ / 100)
 					tape->req_buffer_fill = 1;
 			}
-			pc = idetape_next_pc_storage (drive);
-			idetape_create_read_cmd (tape, pc, rq->current_nr_sectors, rq->bio);
+			pc = idetape_next_pc_storage(drive);
+			idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, rq->bio);
 			break;
 		case IDETAPE_WRITE_RQ:
 			tape->buffer_head++;
@@ -2715,12 +2773,12 @@
 				calculate_speeds(drive);
 			}
 			pc = idetape_next_pc_storage (drive);
-			idetape_create_write_cmd (tape, pc, rq->current_nr_sectors, rq->bio);
+			idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, rq->bio);
 			break;
 		case IDETAPE_READ_BUFFER_RQ:
 			tape->postpone_cnt = 0;
 			pc = idetape_next_pc_storage (drive);
-			idetape_create_read_buffer_cmd (tape, pc, rq->current_nr_sectors, rq->bio);
+			idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, rq->bio);
 			break;
 		case IDETAPE_ABORTED_WRITE_RQ:
 			rq->flags = IDETAPE_WRITE_RQ;
@@ -2740,14 +2798,25 @@
 			rq->flags = IDETAPE_PC_RQ2;
 			break;
 		case IDETAPE_PC_RQ2:
+			/* FIXME: make this unlocking go away*/
+			spin_unlock_irq(ch->lock);
 			idetape_media_access_finished(drive, rq);
+			spin_lock_irq(ch->lock);
 			return ide_stopped;
 		default:
 			printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n");
+			/* FIXME: make this unlocking go away*/
+			spin_unlock_irq(ch->lock);
 			idetape_end_request(drive, rq, 0);
+			spin_lock_irq(ch->lock);
 			return ide_stopped;
 	}
-	return idetape_issue_packet_command(drive, rq, pc);
+	/* FIXME: make this unlocking go away*/
+	spin_unlock_irq(ch->lock);
+	ret = idetape_issue_packet_command(drive, rq, pc);
+	spin_lock_irq(ch->lock);
+
+	return ret;
 }
 
 /*
@@ -3326,7 +3395,7 @@
 		tape->merge_stage = NULL;
 	}
 	tape->chrdev_direction = idetape_direction_none;
-	
+
 	if (tape->first_stage == NULL)
 		return 0;
 
@@ -3723,10 +3792,10 @@
 #if IDETAPE_DEBUG_LOG
 	if (tape->debug_level >= 3)
 		printk (KERN_INFO "ide-tape: Reached idetape_add_chrdev_write_request\n");
-#endif /* IDETAPE_DEBUG_LOG */
+#endif
 
-     	/*
-     	 *	Attempt to allocate a new stage.
+	/*
+	 *	Attempt to allocate a new stage.
 	 *	Pay special attention to possible race conditions.
 	 */
 	while ((new_stage = idetape_kmalloc_stage (tape)) == NULL) {
diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/ide-taskfile.c	Sun Jun 16 19:31:40 2002
@@ -176,132 +176,6 @@
 	return 1;	/* drive ready: *might* be interrupting */
 }
 
-ide_startstop_t ata_taskfile(struct ata_device *drive,
-		struct ata_taskfile *ar, struct request *rq)
-{
-	struct hd_driveid *id = drive->id;
-
-	/* (ks/hs): Moved to start, do not use for multiple out commands.
-	 * FIXME: why not?! */
-	if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
-	      ar->cmd == WIN_MULTWRITE ||
-	      ar->cmd == WIN_MULTWRITE_EXT)) {
-		ata_irq_enable(drive, 1);
-		ata_mask(drive);
-	}
-
-	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) &&
-	    (drive->addressing == 1))
-		ata_out_regfile(drive, &ar->hobfile);
-	ata_out_regfile(drive, &ar->taskfile);
-
-	OUT_BYTE((ar->taskfile.device_head & (drive->addressing ? 0xE0 : 0xEF)) | drive->select.all,
-			IDE_SELECT_REG);
-
-	if (ar->handler) {
-
-		/* This is apparently supposed to reset the wait timeout for
-		 * the interrupt to accur.
-		 */
-
-		ide_set_handler(drive, ar->handler, WAIT_CMD, NULL);
-		OUT_BYTE(ar->cmd, IDE_COMMAND_REG);
-
-		/* FIXME: Warning check for race between handler and prehandler
-		 * for writing first block of data.  however since we are well
-		 * inside the boundaries of the seek, we should be okay.
-		 *
-		 * FIXME: Replace the switch by using a proper command_type.
-		 */
-
-		if (ar->cmd == CFA_WRITE_SECT_WO_ERASE ||
-		    ar->cmd == WIN_WRITE ||
-		    ar->cmd == WIN_WRITE_EXT ||
-		    ar->cmd == WIN_WRITE_VERIFY ||
-		    ar->cmd == WIN_WRITE_BUFFER ||
-		    ar->cmd == WIN_DOWNLOAD_MICROCODE ||
-		    ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
-		    ar->cmd == WIN_MULTWRITE ||
-		    ar->cmd == WIN_MULTWRITE_EXT) {
-			ide_startstop_t startstop;
-
-			if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
-				printk(KERN_ERR "%s: no DRQ after issuing %s\n",
-						drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
-				return startstop;
-			}
-
-			/* FIXME: This doesn't make the slightest sense.
-			 * (ks/hs): Fixed Multi Write
-			 */
-			if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
-			      ar->cmd == WIN_MULTWRITE ||
-			      ar->cmd == WIN_MULTWRITE_EXT)) {
-				unsigned long flags;
-				char *buf = ide_map_rq(rq, &flags);
-
-				/* For Write_sectors we need to stuff the first sector */
-				ata_write(drive, buf, SECTOR_WORDS);
-
-				rq->current_nr_sectors--;
-				ide_unmap_rq(rq, buf, &flags);
-
-				return ide_started;
-			} else {
-				int i;
-
-				/* Polling wait until the drive is ready.
-				 *
-				 * Stuff the first sector(s) by calling the
-				 * handler driectly therafter.
-				 *
-				 * FIXME: Replace hard-coded 100, what about
-				 * error handling?
-				 */
-
-				for (i = 0; i < 100; ++i) {
-					if (drive_is_ready(drive))
-						break;
-				}
-				if (!drive_is_ready(drive)) {
-					printk(KERN_ERR "DISASTER WAITING TO HAPPEN!\n");
-				}
-				return ar->handler(drive, rq);
-			}
-		}
-	} else {
-		/*
-		 * FIXME: This is a gross hack, need to unify tcq dma proc and
-		 * regular dma proc. It should now be easier.
-		 *
-		 * FIXME: Handle the alternateives by a command type.
-		 */
-
-		if (!drive->using_dma)
-			return ide_started;
-
-		/* for dma commands we don't set the handler */
-		if (ar->cmd == WIN_WRITEDMA ||
-		    ar->cmd == WIN_WRITEDMA_EXT ||
-		    ar->cmd == WIN_READDMA ||
-		    ar->cmd == WIN_READDMA_EXT)
-			return !udma_init(drive, rq);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-		else if (ar->cmd == WIN_WRITEDMA_QUEUED ||
-			 ar->cmd == WIN_WRITEDMA_QUEUED_EXT ||
-			 ar->cmd == WIN_READDMA_QUEUED ||
-			 ar->cmd == WIN_READDMA_QUEUED_EXT)
-			return udma_tcq_taskfile(drive, rq);
-#endif
-		else {
-			printk(KERN_ERR "%s: unknown command %x\n", __FUNCTION__, ar->cmd);
-			return ide_stopped;
-		}
-	}
-
-	return ide_started;
-}
-
 /*
  * This function issues a special IDE device request onto the request queue.
  *
@@ -368,13 +242,18 @@
 /*
  * Invoked on completion of a special REQ_SPECIAL command.
  */
-ide_startstop_t ata_special_intr(struct ata_device *drive, struct
-		request *rq) {
+static ide_startstop_t special_intr(struct ata_device *drive,
+		struct request *rq)
+{
 
 	struct ata_taskfile *ar = rq->special;
 	ide_startstop_t ret = ide_stopped;
+	unsigned long flags;
 
 	ide__sti();	/* local CPU only */
+
+	spin_lock_irqsave(drive->channel->lock, flags);
+
 	if (rq->buffer && ar->taskfile.sector_number) {
 		if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) {
 			int retries = 10;
@@ -409,19 +288,23 @@
 	drive->rq = NULL;
 	end_that_request_last(rq);
 
+	spin_unlock_irqrestore(drive->channel->lock, flags);
+
 	return ret;
 }
 
-int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar)
+int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar,
+		char *buffer)
 {
 	struct request req;
 
 	ar->command_type = IDE_DRIVE_TASK_NO_DATA;
-	ar->handler = ata_special_intr;
+	ar->XXX_handler = special_intr;
 
 	memset(&req, 0, sizeof(req));
 	req.flags = REQ_SPECIAL;
 	req.special = ar;
+	req.buffer = buffer;
 
 	return ide_do_drive_cmd(drive, &req, ide_wait);
 }
@@ -430,6 +313,4 @@
 EXPORT_SYMBOL(ide_do_drive_cmd);
 EXPORT_SYMBOL(ata_read);
 EXPORT_SYMBOL(ata_write);
-EXPORT_SYMBOL(ata_taskfile);
-EXPORT_SYMBOL(ata_special_intr);
 EXPORT_SYMBOL(ide_raw_taskfile);
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/ide.c	Sun Jun 16 19:31:41 2002
@@ -106,18 +106,19 @@
 	return 0;
 }
 
-int __ide_end_request(struct ata_device *drive, struct request *rq, int uptodate, unsigned int nr_secs)
+/*
+ * Not locking variabt of the end_request method.
+ *
+ * Channel lock should be held.
+ */
+int __ata_end_request(struct ata_device *drive, struct request *rq, int uptodate, unsigned int nr_secs)
 {
-	unsigned long flags;
 	int ret = 1;
 
-	spin_lock_irqsave(drive->channel->lock, flags);
-
 	BUG_ON(!(rq->flags & REQ_STARTED));
 
-	/*
-	 * small hack to eliminate locking from ide_end_request to grab
-	 * the first segment number of sectors
+	/* FIXME: Make this "small" hack to eliminate locking from
+	 * ata_end_request to grab the first segment number of sectors go away.
 	 */
 	if (!nr_secs)
 		nr_secs = rq->hard_cur_sectors;
@@ -126,7 +127,6 @@
 	 * Decide whether to reenable DMA -- 3 is a random magic for now,
 	 * if we DMA timeout more than 3 times, just stay in PIO.
 	 */
-
 	if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
 		drive->state = 0;
 		udma_enable(drive, 1, 1);
@@ -143,15 +143,24 @@
 		ret = 0;
 	}
 
-	spin_unlock_irqrestore(drive->channel->lock, flags);
 
 	return ret;
 }
 
-/* This is the default end request function as well */
-int ide_end_request(struct ata_device *drive, struct request *rq, int uptodate)
+/*
+ * This is the default end request function as well
+ */
+int ata_end_request(struct ata_device *drive, struct request *rq, int uptodate)
 {
-	return __ide_end_request(drive, rq, uptodate, 0);
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
+	int ret;
+
+	spin_lock_irqsave(ch->lock, flags);
+	ret = __ata_end_request(drive, rq, uptodate, 0);
+	spin_unlock_irqrestore(drive->channel->lock, flags);
+
+	return ret;
 }
 
 /*
@@ -160,25 +169,25 @@
  * at the appropriate code to handle the next interrupt, and a
  * timer is started to prevent us from waiting forever in case
  * something goes wrong (see the ide_timer_expiry() handler later on).
+ *
+ * Channel lock should be held.
  */
-void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
+void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
 		      unsigned long timeout, ata_expiry_t expiry)
 {
-	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
 
-	spin_lock_irqsave(ch->lock, flags);
+	if (ch->handler)
+		printk("%s: %s: handler not null; old=%p, new=%p, from %p\n",
+			drive->name, __FUNCTION__, ch->handler, handler, __builtin_return_address(0));
 
-	if (ch->handler != NULL) {
-		printk("%s: ide_set_handler: handler not null; old=%p, new=%p, from %p\n",
-			drive->name, ch->handler, handler, __builtin_return_address(0));
-	}
 	ch->handler = handler;
+
 	ch->expiry = expiry;
 	ch->timer.expires = jiffies + timeout;
+
 	add_timer(&ch->timer);
 
-	spin_unlock_irqrestore(ch->lock, flags);
 }
 
 static void check_crc_errors(struct ata_device *drive)
@@ -256,26 +265,31 @@
  */
 static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq)
 {
+	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
+	int ret = ide_stopped;
 
+	spin_lock_irqsave(ch->lock, flags);
 	ata_select(drive, 10);
-
-	if (ata_status(drive, 0, BUSY_STAT))
-		printk("%s: ATAPI reset complete\n", drive->name);
-	else {
+	if (!ata_status(drive, 0, BUSY_STAT)) {
 		if (time_before(jiffies, ch->poll_timeout)) {
-			ide_set_handler (drive, atapi_reset_pollfunc, HZ/20, NULL);
+			ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
+			ret = ide_started;	/* continue polling */
+		} else {
+			ch->poll_timeout = 0;	/* end of polling */
+			printk("%s: ATAPI reset timed out, status=0x%02x\n", drive->name, drive->status);
 
-			return ide_started;	/* continue polling */
+			ret = do_reset1(drive, 0);	/* do it the old fashioned way */
 		}
-		ch->poll_timeout = 0;	/* end of polling */
-		printk("%s: ATAPI reset timed out, status=0x%02x\n", drive->name, drive->status);
+	} else {
+		printk("%s: ATAPI reset complete\n", drive->name);
+		ch->poll_timeout = 0;	/* done polling */
 
-		return do_reset1(drive, 1);	/* do it the old fashioned way */
+		ret = ide_stopped;
 	}
-	ch->poll_timeout = 0;	/* done polling */
+	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_stopped;
+	return ret;
 }
 
 /*
@@ -285,16 +299,20 @@
  */
 static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *__rq)
 {
+	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
+	int ret;
 
+	spin_lock_irqsave(ch->lock, flags);
 	if (!ata_status(drive, 0, BUSY_STAT)) {
 		if (time_before(jiffies, ch->poll_timeout)) {
-			ide_set_handler(drive, reset_pollfunc, HZ/20, NULL);
-
-			return ide_started;	/* continue polling */
+			ata_set_handler(drive, reset_pollfunc, HZ/20, NULL);
+			ret = ide_started;	/* continue polling */
+		} else {
+			printk("%s: reset timed out, status=0x%02x\n", ch->name, drive->status);
+			++drive->failures;
+			ret = ide_stopped;
 		}
-		printk("%s: reset timed out, status=0x%02x\n", ch->name, drive->status);
-		drive->failures++;
 	} else  {
 		u8 stat;
 
@@ -303,11 +321,11 @@
 			printk("success\n");
 			drive->failures = 0;
 		} else {
-			char *msg;
+			const char *msg = "";
 
 #if FANCY_STATUS_DUMPS
 			u8 val;
-			static char *messages[5] = {
+			static const char *messages[5] = {
 				" passed",
 				" formatter device",
 				" sector buffer",
@@ -319,16 +337,17 @@
 			val = stat & 0x7f;
 			if (val >= 1 && val <= 5)
 				msg = messages[val -1];
-			else
-				msg = "";
 			if (stat & 0x80)
 				printk("; slave:");
 #endif
-			printk("%s error [%02x]\n", msg, stat);
-			drive->failures++;
+			printk(KERN_ERR "%s error [%02x]\n", msg, stat);
+			++drive->failures;
 		}
+
+		ret = ide_stopped;
 	}
 	ch->poll_timeout = 0;	/* done polling */
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_stopped;
 }
@@ -347,9 +366,11 @@
  * Equally poor, though, is the fact that this may a very long time to
  * complete, (up to 30 seconds worst case).  So, instead of busy-waiting here
  * for it, we set a timer to poll at 50ms intervals.
+ *
+ * Channel lock should be held.
  */
 
-static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
+static ide_startstop_t do_reset1(struct ata_device *drive, int try_atapi)
 {
 	unsigned int unit;
 	unsigned long flags;
@@ -359,15 +380,17 @@
 	__cli();		/* local CPU only */
 
 	/* For an ATAPI device, first try an ATAPI SRST. */
-	if (drive->type != ATA_DISK && !do_not_try_atapi) {
-		check_crc_errors(drive);
-		ata_select(drive, 20);
-		OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
-		ch->poll_timeout = jiffies + WAIT_WORSTCASE;
-		ide_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
-		__restore_flags(flags);	/* local CPU only */
+	if (try_atapi) {
+		if (drive->type != ATA_DISK) {
+			check_crc_errors(drive);
+			ata_select(drive, 20);
+			OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
+			ch->poll_timeout = jiffies + WAIT_WORSTCASE;
+			ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
+			__restore_flags(flags);	/* local CPU only */
 
-		return ide_started;
+			return ide_started;
+		}
 	}
 
 	/*
@@ -377,7 +400,7 @@
 	for (unit = 0; unit < MAX_DRIVES; ++unit)
 		check_crc_errors(&ch->drives[unit]);
 
-	__restore_flags (flags);	/* local CPU only */
+	__restore_flags(flags);	/* local CPU only */
 
 	return ide_started;
 }
@@ -537,7 +560,7 @@
 		memset(&args, 0, sizeof(args));
 		args.taskfile.sector_count = drive->sect;
 		args.cmd = WIN_RESTORE;
-		ide_raw_taskfile(drive, &args);
+		ide_raw_taskfile(drive, &args, NULL);
 		printk(KERN_INFO "%s: done!\n", drive->name);
 	}
 
@@ -546,6 +569,8 @@
 
 /*
  * Take action based on the error returned by the drive.
+ *
+ * FIXME: Channel lock should be held.
  */
 ide_startstop_t ata_error(struct ata_device *drive, struct request *rq,	const char *msg)
 {
@@ -562,6 +587,7 @@
 
 		return ide_stopped;
 	}
+
 	/* other bits are useless when BUSY */
 	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr))
 		rq->errors |= ERROR_RESET; /* FIXME: What's that?! */
@@ -588,14 +614,15 @@
 
 	if (rq->errors >= ERROR_MAX) {
 		printk(KERN_ERR "%s: max number of retries exceeded!\n", drive->name);
+		/* FIXME: make sure all end_request implementations are lock free */
 		if (ata_ops(drive) && ata_ops(drive)->end_request)
 			ata_ops(drive)->end_request(drive, rq, 0);
 		else
-			ide_end_request(drive, rq, 0);
+			__ata_end_request(drive, rq, 0, 0);
 	} else {
 		++rq->errors;
 		if ((rq->errors & ERROR_RESET) == ERROR_RESET)
-			return do_reset1(drive, 0);
+			return do_reset1(drive, 1);
 		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
 			return do_recalibrate(drive);
 	}
@@ -604,71 +631,20 @@
 }
 
 /*
- * Busy-wait for the drive status to be not "busy".  Check then the status for
- * all of the "good" bits and none of the "bad" bits, and if all is okay it
- * returns 0.  All other cases return 1 after invoking error handler -- caller
- * should just return.
- *
- * This routine should get fixed to not hog the cpu during extra long waits..
- * That could be done by busy-waiting for the first jiffy or two, and then
- * setting a timer to wake up at half second intervals thereafter, until
- * timeout is achieved, before timing out.
- */
-int ide_wait_stat(ide_startstop_t *startstop,
-		struct ata_device *drive, struct request *rq,
-		byte good, byte bad, unsigned long timeout)
-{
-	int i;
-
-	/* bail early if we've exceeded max_failures */
-	if (drive->max_failures && (drive->failures > drive->max_failures)) {
-		*startstop = ide_stopped;
-
-		return 1;
-	}
-
-	/* spec allows drive 400ns to assert "BUSY" */
-	udelay(1);
-	if (!ata_status(drive, 0, BUSY_STAT)) {
-		timeout += jiffies;
-		while (!ata_status(drive, 0, BUSY_STAT)) {
-			if (time_after(jiffies, timeout)) {
-				*startstop = ata_error(drive, rq, "status timeout");
-				return 1;
-			}
-		}
-	}
-
-	/*
-	 * Allow status to settle, then read it again.  A few rare drives
-	 * vastly violate the 400ns spec here, so we'll wait up to 10usec for a
-	 * "good" status rather than expensively fail things immediately.  This
-	 * fix courtesy of Matthew Faupel & Niccolo Rigacci.
-	 */
-	for (i = 0; i < 10; i++) {
-		udelay(1);
-		if (ata_status(drive, good, bad))
-			return 0;
-	}
-	*startstop = ata_error(drive, rq, "status error");
-
-	return 1;
-}
-
-/*
  * This initiates handling of a new I/O request.
  */
 static ide_startstop_t start_request(struct ata_device *drive, struct request *rq)
 {
+	struct ata_channel *ch = drive->channel;
 	sector_t block;
 	unsigned int minor = minor(rq->rq_dev);
 	unsigned int unit = minor >> PARTN_BITS;
-	struct ata_channel *ch = drive->channel;
+	ide_startstop_t ret;
 
 	BUG_ON(!(rq->flags & REQ_STARTED));
 
 #ifdef DEBUG
-	printk("%s: start_request: current=0x%08lx\n", ch->name, (unsigned long) rq);
+	printk("%s: %s: current=0x%08lx\n", ch->name, __FUNCTION__, (unsigned long) rq);
 #endif
 
 	/* bail early if we've exceeded max_failures */
@@ -688,54 +664,48 @@
 		if (drive->type == ATA_DISK || drive->type == ATA_FLOPPY)
 			block += drive->sect0;
 
-
 	/* Yecch - this will shift the entire interval, possibly killing some
 	 * innocent following sector.
 	 */
 	if (block == 0 && drive->remap_0_to_1 == 1)
 		block = 1;  /* redirect MBR access to EZ-Drive partn table */
-	{
-		ide_startstop_t res;
 
-		ata_select(drive, 0);
-		if (ide_wait_stat(&res, drive, rq, drive->ready_stat,
-					BUSY_STAT|DRQ_STAT, WAIT_READY)) {
-			printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
+	ata_select(drive, 0);
+	if (ata_status_poll(drive, drive->ready_stat, BUSY_STAT | DRQ_STAT,
+				WAIT_READY, rq, &ret)) {
+		printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
 
-			return res;
-		}
+		goto kill_rq;
 	}
 
-	/* This issues a special drive command.
-	 */
-	if (rq->flags & REQ_SPECIAL)
-		return ata_taskfile(drive, rq->special, NULL);
+	if (!ata_ops(drive)) {
+		printk(KERN_WARNING "%s: device type %d not supported\n",
+				drive->name, drive->type);
+		goto kill_rq;
+	}
 
 	/* The normal way of execution is to pass and execute the request
 	 * handler down to the device type driver.
 	 */
-	if (ata_ops(drive)) {
-		if (ata_ops(drive)->do_request)
-			return ata_ops(drive)->do_request(drive, rq, block);
-		else {
-			ide_end_request(drive, rq, 0);
 
-			return ide_stopped;
-		}
+	if (ata_ops(drive)->do_request) {
+		ret = ata_ops(drive)->do_request(drive, rq, block);
+	} else {
+		__ata_end_request(drive, rq, 0, 0);
+		ret = ide_stopped;
 	}
-
-	/*
-	 * Error handling:
-	 */
-
-	printk(KERN_WARNING "%s: device type %d not supported\n",
-			drive->name, drive->type);
+	return ret;
 
 kill_rq:
-	if (ata_ops(drive) && ata_ops(drive)->end_request)
-		ata_ops(drive)->end_request(drive, rq, 0);
-	else
-		ide_end_request(drive, rq, 0);
+	if (ata_ops(drive)) {
+		if (ata_ops(drive)->end_request) {
+			spin_unlock_irq(ch->lock);
+			ata_ops(drive)->end_request(drive, rq, 0);
+			spin_lock_irq(ch->lock);
+		} else
+			__ata_end_request(drive, rq, 0, 0);
+	} else
+		__ata_end_request(drive, rq, 0, 0);
 
 	return ide_stopped;
 }
@@ -744,15 +714,16 @@
 {
 	struct ata_channel *ch = drive->channel;
 	unsigned long flags;
+	int ret;
 
 	spin_lock_irqsave(ch->lock, flags);
 
 	ch->handler = NULL;
 	del_timer(&ch->timer);
-
+	ret = start_request(drive, drive->rq);
 	spin_unlock_irqrestore(ch->lock, flags);
 
-	return start_request(drive, drive->rq);
+	return ret;
 }
 
 /*
@@ -844,14 +815,16 @@
 			sleep = jiffies + WAIT_MIN_SLEEP;
 #if 1
 		if (timer_pending(&channel->timer))
-			printk(KERN_ERR "ide_set_handler: timer already active\n");
+			printk(KERN_ERR "%s: timer already active\n", __FUNCTION__);
 #endif
 		set_bit(IDE_SLEEP, channel->active);
 		mod_timer(&channel->timer, sleep);
 		/* we purposely leave hwgroup busy while sleeping */
 	} else {
+		/* FIXME: use queue plugging instead of active to
+		 * block upper layers from stomping on us */
 		/* Ugly, but how can we sleep for the lock otherwise? */
-		ide_release_lock(&irq_lock);/* for atari only */
+		ide_release_lock(&ide_irq_lock);/* for atari only */
 		clear_bit(IDE_BUSY, channel->active);
 	}
 
@@ -918,13 +891,9 @@
 
 		drive->rq = rq;
 
-		spin_unlock(drive->channel->lock);
-
 		ide__sti();	/* allow other IRQs while we start this request */
 		startstop = start_request(drive, rq);
 
-		spin_lock_irq(drive->channel->lock);
-
 		/* command started, we are busy */
 		if (startstop == ide_started)
 			break;
@@ -948,7 +917,7 @@
  */
 static void do_request(struct ata_channel *channel)
 {
-	ide_get_lock(&irq_lock, ata_irq_request, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */
+	ide_get_lock(&ide_irq_lock, ata_irq_request, channel);/* for atari only: POSSIBLY BROKEN HERE(?) */
 //	__cli();	/* necessary paranoia: ensure IRQs are masked on local CPU */
 
 	while (!test_and_set_bit(IDE_BUSY, channel->active)) {
@@ -988,64 +957,24 @@
 }
 
 /*
- * Un-busy the hwgroup etc, and clear any pending DMA status. we want to
- * retry the current request in PIO mode instead of risking tossing it
- * all away
- */
-static void dma_timeout_retry(struct ata_device *drive, struct request *rq)
-{
-	/*
-	 * end current dma transaction
-	 */
-	udma_stop(drive);
-	udma_timeout(drive);
-
-	/*
-	 * Disable dma for now, but remember that we did so because of
-	 * a timeout -- we'll reenable after we finish this next request
-	 * (or rather the first chunk of it) in pio.
-	 */
-	drive->retry_pio++;
-	drive->state = DMA_PIO_RETRY;
-	udma_enable(drive, 0, 0);
-
-	/*
-	 * un-busy drive etc (hwgroup->busy is cleared on return) and
-	 * make sure request is sane
-	 */
-	drive->rq = NULL;
-
-	rq->errors = 0;
-	if (rq->bio) {
-		rq->sector = rq->bio->bi_sector;
-		rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
-		rq->buffer = NULL;
-	}
-}
-
-/*
  * This is our timeout function for all drive operations.  But note that it can
  * also be invoked as a result of a "sleep" operation triggered by the
  * mod_timer() call in do_request.
+ *
+ * FIXME: this should take a drive context instead of a channel.
  */
 void ide_timer_expiry(unsigned long data)
 {
-	struct ata_channel *ch = (struct ata_channel *) data;
-	ata_handler_t *handler;
-	ata_expiry_t *expiry;
 	unsigned long flags;
-	unsigned long wait;
-
-	/*
-	 * A global lock protects timers etc -- shouldn't get contention
-	 * worth mentioning.
-	 */
+	struct ata_channel *ch = (struct ata_channel *) data;
 
 	spin_lock_irqsave(ch->lock, flags);
 	del_timer(&ch->timer);
 
-	handler = ch->handler;
-	if (!handler) {
+	if (!ch->drive) {
+		printk(KERN_ERR "%s: IRQ handler was NULL\n", __FUNCTION__);
+		ch->handler = NULL;
+	} else if (!ch->handler) {
 
 		/*
 		 * Either a marginal timeout occurred (got the interrupt just
@@ -1058,69 +987,103 @@
 			clear_bit(IDE_BUSY, ch->active);
 	} else {
 		struct ata_device *drive = ch->drive;
-		if (!drive) {
-			printk(KERN_ERR "ide_timer_expiry: IRQ handler was NULL\n");
-			ch->handler = NULL;
-		} else {
-			ide_startstop_t startstop;
+		ide_startstop_t ret;
+		ata_handler_t *handler;
 
-			/* paranoia */
-			if (!test_and_set_bit(IDE_BUSY, ch->active))
-				printk(KERN_ERR "%s: ide_timer_expiry: IRQ handler was not busy??\n", drive->name);
-			if ((expiry = ch->expiry) != NULL) {
-				/* continue */
-				if ((wait = expiry(drive, drive->rq)) != 0) {
-					/* reengage timer */
-					ch->timer.expires  = jiffies + wait;
-					add_timer(&ch->timer);
+		/* paranoia */
+		if (!test_and_set_bit(IDE_BUSY, ch->active))
+			printk(KERN_ERR "%s: %s: IRQ handler was not busy?!\n",
+					drive->name, __FUNCTION__);
+
+		if (ch->expiry) {
+			unsigned long wait;
+
+			/* continue */
+			if ((wait = ch->expiry(drive, drive->rq)) != 0) {
+				/* reengage timer */
+				ch->timer.expires  = jiffies + wait;
+				add_timer(&ch->timer);
 
-					spin_unlock_irqrestore(ch->lock, flags);
+				spin_unlock_irqrestore(ch->lock, flags);
 
-					return;
-				}
+				return;
 			}
-			ch->handler = NULL;
-			/*
-			 * We need to simulate a real interrupt when invoking
-			 * the handler() function, which means we need to globally
-			 * mask the specific IRQ:
-			 */
+		}
 
-			spin_unlock(ch->lock);
+		/*
+		 * We need to simulate a real interrupt when invoking the
+		 * handler() function, which means we need to globally mask the
+		 * specific IRQ:
+		 */
 
-			ch = drive->channel;
+		handler = ch->handler;
+		ch->handler = NULL;
+		spin_unlock(ch->lock);
+
+		ch = drive->channel;
 #if DISABLE_IRQ_NOSYNC
-			disable_irq_nosync(ch->irq);
+		disable_irq_nosync(ch->irq);
 #else
-			disable_irq(ch->irq);	/* disable_irq_nosync ?? */
+		disable_irq(ch->irq);	/* disable_irq_nosync ?? */
 #endif
-			__cli();	/* local CPU only, as if we were handling an interrupt */
-			if (ch->poll_timeout != 0) {
-				startstop = handler(drive, drive->rq);
-			} else if (drive_is_ready(drive)) {
-				if (drive->waiting_for_dma)
-					udma_irq_lost(drive);
-				(void) ide_ack_intr(ch);
-				printk("%s: lost interrupt\n", drive->name);
-				startstop = handler(drive, drive->rq);
-			} else {
-				if (drive->waiting_for_dma) {
-					startstop = ide_stopped;
-					dma_timeout_retry(drive, drive->rq);
-				} else
-					startstop = ata_error(drive, drive->rq, "irq timeout");
+		__cli();	/* local CPU only, as if we were handling an interrupt */
+		if (ch->poll_timeout) {
+			ret = handler(drive, drive->rq);
+		} else if (drive_is_ready(drive)) {
+			if (drive->waiting_for_dma)
+				udma_irq_lost(drive);
+			(void) ide_ack_intr(ch);
+			printk("%s: lost interrupt\n", drive->name);
+			ret = handler(drive, drive->rq);
+		} else if (drive->waiting_for_dma) {
+			struct request *rq = drive->rq;
+
+			/*
+			 * Un-busy the hwgroup etc, and clear any pending DMA
+			 * status. we want to retry the current request in PIO
+			 * mode instead of risking tossing it all away.
+			 */
+
+			udma_stop(drive);
+			udma_timeout(drive);
+
+			/* Disable dma for now, but remember that we did so
+			 * because of a timeout -- we'll reenable after we
+			 * finish this next request (or rather the first chunk
+			 * of it) in pio.
+			 */
+
+			drive->retry_pio++;
+			drive->state = DMA_PIO_RETRY;
+			udma_enable(drive, 0, 0);
+
+			/* Un-busy drive etc (hwgroup->busy is cleared on
+			 * return) and make sure request is sane.
+			 */
+
+			drive->rq = NULL;
+
+			rq->errors = 0;
+			if (rq->bio) {
+				rq->sector = rq->bio->bi_sector;
+				rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+				rq->buffer = NULL;
 			}
-			enable_irq(ch->irq);
+			ret = ide_stopped;
+		} else
+			ret = ata_error(drive, drive->rq, "irq timeout");
 
-			spin_lock_irq(ch->lock);
+		enable_irq(ch->irq);
 
-			if (startstop == ide_stopped)
-				clear_bit(IDE_BUSY, ch->active);
-		}
-	}
+		spin_lock_irq(ch->lock);
+
+		if (ret == ide_stopped)
+			clear_bit(IDE_BUSY, ch->active);
 
-	do_request(ch->drive->channel);
 
+		/* Reenter the request handling engine */
+		do_request(ch);
+	}
 	spin_unlock_irqrestore(ch->lock, flags);
 }
 
@@ -1142,7 +1105,7 @@
  *
  * In reality, this is a non-issue.  The new command is not sent unless the
  * drive is ready to accept one, in which case we know the drive is not
- * trying to interrupt us.  And ide_set_handler() is always invoked before
+ * trying to interrupt us.  And ata_set_handler() is always invoked before
  * completing the issuance of any new drive command, so we will not be
  * accidentally invoked as a result of any valid command completion interrupt.
  *
@@ -1416,15 +1379,14 @@
 EXPORT_SYMBOL(ide_timer_expiry);
 EXPORT_SYMBOL(do_ide_request);
 
-EXPORT_SYMBOL(ide_set_handler);
+EXPORT_SYMBOL(ata_set_handler);
 EXPORT_SYMBOL(ata_dump);
 EXPORT_SYMBOL(ata_error);
 
-EXPORT_SYMBOL(ide_wait_stat);
 /* FIXME: this is a trully bad name */
 EXPORT_SYMBOL(restart_request);
-EXPORT_SYMBOL(__ide_end_request);
-EXPORT_SYMBOL(ide_end_request);
+EXPORT_SYMBOL(ata_end_request);
+EXPORT_SYMBOL(__ata_end_request);
 EXPORT_SYMBOL(ide_stall_queue);
 
 EXPORT_SYMBOL(ide_setup_ports);
diff -Nru a/drivers/ide/ioctl.c b/drivers/ide/ioctl.c
--- a/drivers/ide/ioctl.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/ioctl.c	Sun Jun 16 19:31:40 2002
@@ -47,16 +47,12 @@
 	u8 *argbuf = vals;
 	int argsize = 4;
 	struct ata_taskfile args;
-	struct request rq;
 
 	/* Second phase.
 	 */
 	if (copy_from_user(vals, (void *)arg, 4))
 		return -EFAULT;
 
-	memset(&rq, 0, sizeof(rq));
-	rq.flags = REQ_SPECIAL;
-
 	memset(&args, 0, sizeof(args));
 
 	args.taskfile.feature = vals[2];
@@ -81,13 +77,7 @@
 		memset(argbuf + 4, 0, argsize - 4);
 	}
 
-	/* Issue ATA command and wait for completion.
-	 */
-	args.handler = ata_special_intr;
-
-	rq.buffer = argbuf + 4;
-	rq.special = &args;
-	err = ide_do_drive_cmd(drive, &rq, ide_wait);
+	err = ide_raw_taskfile(drive, &args, argbuf + 4);
 
 	argbuf[0] = drive->status;
 	argbuf[1] = args.taskfile.feature;
diff -Nru a/drivers/ide/it8172.c b/drivers/ide/it8172.c
--- a/drivers/ide/it8172.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/it8172.c	Sun Jun 16 19:31:39 2002
@@ -45,21 +45,11 @@
 #include "ata-timing.h"
 #include "pcihost.h"
 
-/*
- * Prototypes
- */
-static void it8172_tune_drive (struct ata_device *drive, byte pio);
-#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING)
-static byte it8172_dma_2_pio (byte xfer_rate);
-static int it8172_tune_chipset (struct ata_device *drive, byte speed);
-static int it8172_config_chipset_for_dma (struct ata_device *drive);
-static int it8172_dmaproc(ide_dma_action_t func, struct ata_device *drive);
-#endif
-void __init ide_init_it8172(struct ata_channel *channel);
 
-
-static void it8172_tune_drive (struct ata_device *drive, byte pio)
+/* FIXME: fix locking  --bkz */
+static void it8172_tune_drive (struct ata_device *drive, u8 pio)
 {
+	struct pci_dev *dev = drive->channel->pci_dev;
     unsigned long flags;
     u16 drive_enables;
     u32 drive_timing;
@@ -70,8 +60,8 @@
 	else
 		pio = min_t(byte, pio, 4);
 
-    pci_read_config_word(drive->channel->pci_dev, master_port, &master_data);
-    pci_read_config_dword(drive->channel->pci_dev, slave_port, &slave_data);
+	pci_read_config_word(dev, master_port, &master_data);
+	pci_read_config_dword(dev, slave_port, &slave_data);
 
     /*
      * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
@@ -102,7 +92,7 @@
 
     save_flags(flags);
     cli();
-    pci_write_config_word(drive->channel->pci_dev, master_port, master_data);
+	pci_write_config_word(dev, master_port, master_data);
     restore_flags(flags);
 }
 
@@ -110,7 +100,7 @@
 /*
  *
  */
-static byte it8172_dma_2_pio (byte xfer_rate)
+static u8 it8172_dma_2_pio(u8 xfer_rate)
 {
     switch(xfer_rate) {
     case XFER_UDMA_5:
@@ -139,7 +129,7 @@
     }
 }
 
-static int it8172_tune_chipset (struct ata_device *drive, byte speed)
+static int it8172_tune_chipset(struct ata_device *drive, u8 speed)
 {
     struct ata_channel *hwif = drive->channel;
     struct pci_dev *dev	= hwif->pci_dev;
@@ -147,7 +137,7 @@
     int u_flag		= 1 << drive->dn;
     int u_speed		= 0;
     int err		= 0;
-    byte reg48, reg4a;
+	u8 reg48, reg4a;
 
     pci_read_config_byte(dev, 0x48, &reg48);
     pci_read_config_byte(dev, 0x4a, &reg4a);
@@ -187,52 +177,28 @@
 
     it8172_tune_drive(drive, it8172_dma_2_pio(speed));
 
-    err = ide_config_drive_speed(drive, speed);
-    drive->current_speed = speed;
-    return err;
+	return ide_config_drive_speed(drive, speed);
 }
 
-static int it8172_config_chipset_for_dma(struct ata_device *drive)
+static int it8172_udma_setup(struct ata_device *drive)
 {
-    struct hd_driveid *id = drive->id;
-    byte speed;
-
-    speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA);
-
-    (void) it8172_tune_chipset(drive, speed);
+	u8 speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO |
+				   XFER_SWDMA | XFER_MWDMA | XFER_UDMA);
 
-    return ((int)((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-	    ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-	    ((id->dma_mword >> 8) & 7) ? ide_dma_on :
-	    ((id->dma_1word >> 8) & 7) ? ide_dma_on :
-	    ide_dma_off_quietly);
+	return !it8172_tune_chipset(drive, speed);
 }
-
-static int it8172_dmaproc(ide_dma_action_t func, struct ata_device *drive)
-{
-    switch (func) {
-    case ide_dma_check:
-	return ide_dmaproc((ide_dma_action_t)it8172_config_chipset_for_dma(drive),
-			   drive);
-    default :
-	break;
-    }
-    /* Other cases are done by generic IDE-DMA code. */
-    return ide_dmaproc(func, drive);
-}
-
 #endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */
 
 
-static unsigned int __init pci_init_it8172 (struct pci_dev *dev)
+static unsigned int __init pci_init_it8172(struct pci_dev *dev)
 {
-    unsigned char progif;
+	u8 progif;
 
     /*
      * Place both IDE interfaces into PCI "native" mode
      */
-    (void)pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
-    (void)pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05);
+	pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
+	pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05);
 
     return IT8172_IDE_IRQ;
 }
diff -Nru a/drivers/ide/main.c b/drivers/ide/main.c
--- a/drivers/ide/main.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/main.c	Sun Jun 16 19:31:39 2002
@@ -114,12 +114,12 @@
 static int ide_scan_direction;	/* THIS was formerly 2.2.x pci=reverse */
 #endif
 
-#if defined(__mc68000__) || defined(CONFIG_APUS)
+#ifdef ATA_ARCH_LOCK
 /*
  * This is used by the Atari code to obtain access to the IDE interrupt,
  * which is shared between several drivers.
  */
-static int irq_lock;
+int ide_irq_lock;
 #endif
 
 int noautodma = 0;
@@ -325,7 +325,6 @@
 	int i;
 
 	/* Don't reinit the probe if there is already one channel detected. */
-
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		if (ide_hwifs[i].present)
 			goto revalidate;
@@ -430,7 +429,7 @@
 		struct ata_device *drive = &ch->drives[i];
 
 		if (drive->de) {
-			devfs_unregister (drive->de);
+			devfs_unregister(drive->de);
 			drive->de = NULL;
 		}
 		if (!drive->present)
@@ -565,33 +564,12 @@
 		if (drive->present && !drive->driver) {
 			(*ops->attach)(drive);
 			if (drive->driver != NULL)
-				count++;
+				++count;
 		}
 	}
 	return count;
 }
 
-static struct ata_operations * subdriver_iterator(struct ata_operations *prev)
-{
-	struct ata_operations *tmp;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ata_drivers_lock, flags);
-
-	/* Restart from beginning if current ata_operations was deallocated,
-	   or if prev is NULL. */
-	for(tmp = ata_drivers; tmp != prev && tmp; tmp = tmp->next);
-	if (!tmp)
-		tmp = ata_drivers;
-	else
-		tmp = tmp->next;
-
-	spin_unlock_irqrestore(&ata_drivers_lock, flags);
-
-	return tmp;
-
-}
-
 /*
  * Register an IDE interface, specifing exactly the registers etc
  * Set initializing=1 iff calling before probes have taken place.
@@ -601,7 +579,6 @@
 	int h;
 	int retry = 1;
 	struct ata_channel *ch;
-	struct ata_operations *subdriver;
 
 	do {
 		for (h = 0; h < MAX_HWIFS; ++h) {
@@ -639,12 +616,18 @@
 	}
 
 	/* Look up whatever there is a subdriver, which will serve this
-	 * device.
+	 * device and execute the attach method it is providing.
 	 */
-	subdriver = NULL;
-	while ((subdriver = subdriver_iterator(subdriver))) {
-		if (subdriver_match(ch, subdriver) > 0)
-			break;
+	{
+		struct ata_operations *tmp;
+		unsigned long flags;
+
+		spin_lock_irqsave(&ata_drivers_lock, flags);
+		for(tmp = ata_drivers; tmp; tmp = tmp->next) {
+			if (subdriver_match(ch, tmp) > 0)
+				break;
+		}
+		spin_unlock_irqrestore(&ata_drivers_lock, flags);
 	}
 
 	return (initializing || ch->present) ? h : -1;
@@ -679,8 +662,8 @@
  */
 static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals)
 {
-	static const char *decimal = "0123456789";
-	static const char *hex = "0123456789abcdef";
+	static const char decimal[] = "0123456789";
+	static const char hex[] = "0123456789abcdef";
 	int i, n;
 
 	if (*s++ == '=') {
@@ -1246,7 +1229,7 @@
 			return NOTIFY_DONE;
 	}
 
-	printk("flushing ide devices: ");
+	printk(KERN_INFO "flushing ATA/ATAPI devices: ");
 
 	for (i = 0; i < MAX_HWIFS; i++) {
 		int unit;
@@ -1264,9 +1247,10 @@
 			/* set the drive to standby */
 			printk("%s ", drive->name);
 			if (ata_ops(drive)) {
-				if (event != SYS_RESTART)
+				if (event != SYS_RESTART) {
 					if (ata_ops(drive)->standby && ata_ops(drive)->standby(drive))
 						continue;
+				}
 
 				if (ata_ops(drive)->cleanup)
 					ata_ops(drive)->cleanup(drive);
@@ -1290,8 +1274,7 @@
 {
 	printk(KERN_INFO "ATA/ATAPI device driver v" VERSION "\n");
 
-	ide_devfs_handle = devfs_mk_dir(NULL, "ata", NULL);
-	devfs_mk_symlink(NULL, "ide", DEVFS_FL_DEFAULT, "ata", NULL, NULL);
+	ide_devfs_handle = devfs_mk_dir(NULL, "ide", NULL);
 
 	/*
 	 * Because most of the ATA adapters represent the timings in unit of
@@ -1449,7 +1432,7 @@
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 # if defined(__mc68000__) || defined(CONFIG_APUS)
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
-		// ide_get_lock(&irq_lock, NULL, NULL);/* for atari only */
+		ide_get_lock(&ide_irq_lock, NULL, NULL);/* for atari only */
 		disable_irq(ide_hwifs[0].irq);	/* disable_irq_nosync ?? */
 //		disable_irq_nosync(ide_hwifs[0].irq);
 	}
@@ -1460,7 +1443,7 @@
 # if defined(__mc68000__) || defined(CONFIG_APUS)
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
 		enable_irq(ide_hwifs[0].irq);
-		ide_release_lock(&irq_lock);/* for atari only */
+		ide_release_lock(&ide_irq_lock);/* for atari only */
 	}
 # endif
 #endif
diff -Nru a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
--- a/drivers/ide/ns87415.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/ns87415.c	Sun Jun 16 19:31:40 2002
@@ -105,12 +105,12 @@
 {
 	ns87415_prepare_drive(drive, 1);	/* select DMA xfer */
 
-	if (!udma_pci_init(drive, rq))		/* use standard DMA stuff */
-		return 0;
+	if (udma_pci_init(drive, rq))		/* use standard DMA stuff */
+		return ide_started;
 
 	ns87415_prepare_drive(drive, 0);	/* DMA failed: select PIO xfer */
 
-	return 1;
+	return ide_stopped;
 }
 
 static int ns87415_udma_setup(struct ata_device *drive)
diff -Nru a/drivers/ide/opti621.c b/drivers/ide/opti621.c
--- a/drivers/ide/opti621.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/opti621.c	Sun Jun 16 19:31:39 2002
@@ -342,9 +342,8 @@
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(chipsets); ++i) {
+	for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
 		ata_register_chipset(&chipsets[i]);
-	}
 
         return 0;
 }
diff -Nru a/drivers/ide/pcidma.c b/drivers/ide/pcidma.c
--- a/drivers/ide/pcidma.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/pcidma.c	Sun Jun 16 19:31:39 2002
@@ -44,7 +44,17 @@
 
 	if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
 		if (!dma_stat) {
-			__ide_end_request(drive, rq, 1, rq->nr_sectors);
+			unsigned long flags;
+			struct ata_channel *ch = drive->channel;
+
+			/* FIXME: this locking should encompass the above register
+			 * file access too.
+			 */
+
+			spin_lock_irqsave(ch->lock, flags);
+			__ata_end_request(drive, rq, 1, rq->nr_sectors);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ide_stopped;
 		}
 		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
@@ -64,7 +74,7 @@
 	struct scatterlist *sg = ch->sg_table;
 	int nents = 0;
 
-	if (rq->flags & REQ_SPECIAL) {
+	if ((rq->flags & REQ_SPECIAL) && (drive->type == ATA_DISK)) {
 		struct ata_taskfile *args = rq->special;
 #if 1
 		unsigned char *virt_addr = rq->buffer;
@@ -388,7 +398,11 @@
 	return count;
 }
 
-/* Teardown mappings after DMA has completed.  */
+/*
+ * Teardown mappings after DMA has completed.
+ *
+ * Channel lock should be held.
+ */
 void udma_destroy_table(struct ata_channel *ch)
 {
 	pci_unmap_sg(ch->pci_dev, ch->sg_table, ch->sg_nents, ch->sg_dma_direction);
@@ -398,22 +412,24 @@
  * Prepare the channel for a DMA startfer. Please note that only the broken
  * Pacific Digital host chip needs the reques to be passed there to decide
  * about addressing modes.
+ *
+ * Channel lock should be held.
  */
-
-int udma_pci_start(struct ata_device *drive, struct request *rq)
+void udma_pci_start(struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *ch = drive->channel;
 	unsigned long dma_base = ch->dma_base;
 
-	/* Note that this is done *after* the cmd has
-	 * been issued to the drive, as per the BM-IDE spec.
-	 * The Promise Ultra33 doesn't work correctly when
-	 * we do this part before issuing the drive cmd.
+	/* Note that this is done *after* the cmd has been issued to the drive,
+	 * as per the BM-IDE spec.  The Promise Ultra33 doesn't work correctly
+	 * when we do this part before issuing the drive cmd.
 	 */
-	outb(inb(dma_base)|1, dma_base);		/* start DMA */
-	return 0;
+	outb(inb(dma_base) | 1, dma_base);	/* start DMA */
 }
 
+/*
+ * Channel lock should be held.
+ */
 int udma_pci_stop(struct ata_device *drive)
 {
 	struct ata_channel *ch = drive->channel;
@@ -431,6 +447,8 @@
 
 /*
  * FIXME: This should be attached to a channel as we can see now!
+ *
+ * Channel lock should be held.
  */
 int udma_pci_irq_status(struct ata_device *drive)
 {
@@ -517,30 +535,34 @@
  *
  * It's exported only for host chips which use it for fallback or (too) late
  * capability checking.
+ *
+ * Channel lock should be held.
  */
 int udma_pci_init(struct ata_device *drive, struct request *rq)
 {
 	u8 cmd;
 
 	if (ata_start_dma(drive, rq))
-		return 1;
+		return ide_stopped;
 
 	/* No DMA transfers on ATAPI devices. */
 	if (drive->type != ATA_DISK)
-		return 0;
+		return ide_started;
 
 	if (rq_data_dir(rq) == READ)
 		cmd = 0x08;
 	else
 		cmd = 0x00;
 
-	ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);
+	ata_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);
 	if (drive->addressing)
 		outb(cmd ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
 	else
 		outb(cmd ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 
-	return udma_start(drive, rq);
+	udma_start(drive, rq);
+
+	return ide_started;
 }
 
 EXPORT_SYMBOL(ide_dma_intr);
diff -Nru a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c
--- a/drivers/ide/pdc202xx.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/pdc202xx.c	Sun Jun 16 19:31:41 2002
@@ -3,6 +3,11 @@
  *  linux/drivers/ide/pdc202xx.c	Version 0.30	May. 28, 2002
  *
  *  Copyright (C) 1998-2000	Andre Hedrick <andre@linux-ide.org>
+ *  Copyright (C) 2002		Bartlomiej Zolnierkiewicz
+ *
+ *  Portions Copyright (C) 1999 Promise Technology, Inc.
+ *  Author: Frank Tiernan (frankt@promise.com)
+ *
  *  May be copied or modified under the terms of the GNU General Public License
  *
  *  Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
@@ -24,12 +29,6 @@
  *
  */
 
-/*
- *  Portions Copyright (C) 1999 Promise Technology, Inc.
- *  Author: Frank Tiernan (frankt@promise.com)
- *  Released under terms of General Public License
- */
-
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -61,9 +60,10 @@
 #define	IORDY_EN	0x20	/* PIO: IOREADY */
 #define	PREFETCH_EN	0x10	/* PIO: PREFETCH */
 
-
-#define PDC_CLOCK(high_16) IN_BYTE(high_16 + 0x11)
-#define UDMA_SPEED_FLAG(high_16) IN_BYTE(high_16 + 0x001f)
+#define PDC_CLK		0x11
+#define PDC_PRIMARY	0x1a
+#define PDC_SECONDARY	0x1b
+#define PDC_UDMA	0x1f
 
 #if PDC202XX_DECODE_REGISTER_INFO
 
@@ -78,23 +78,12 @@
 	{ 0x20, "IORDY_EN" },
 	{ 0x10, "PREFETCH_EN" },
 	/* PA3-PA0 - PIO "A" timing */
-	{ 0x08, "PA3" },
-	{ 0x04, "PA2" },
-	{ 0x02, "PA1" },
-	{ 0x01, "PA0" }
 };
 
 static struct pdc_bit_messages pdc_reg_B[] = {
 	/* MB2-MB0 - DMA "B" timing */
-	{ 0x80, "MB2" },
-	{ 0x40, "MB1" },
-	{ 0x20, "MB0" },
 	{ 0x10, "PIO_FORCED/PB4" },	/* PIO_FORCE 1:0 */
 	/* PB3-PB0 - PIO "B" timing */
-	{ 0x08, "PB3" },		/* PIO flow Control mode */
-	{ 0x04, "PB2" },		/* PIO 4 */
-	{ 0x02, "PB1" },		/* PIO 3 half */
-	{ 0x01, "PB0" }			/* PIO 3 other half */
 };
 
 static struct pdc_bit_messages pdc_reg_C[] = {
@@ -103,10 +92,6 @@
 	{ 0x20, "DMAR_EN" },
 	{ 0x10, "DMAW_EN" },
 	/* MC3-MC0 - DMA "C" timing */
-	{ 0x08, "MC3" },
-	{ 0x04, "MC2" },
-	{ 0x02, "MC1" },
-	{ 0x01, "MC0" }
 };
 
 static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits)
@@ -115,7 +100,7 @@
 
 	printk(KERN_DEBUG " { ");
 
-	for (i = 0; i < 8; i++, msgs++)
+	for (i = 0; i < ARRAY_SIZE(msgs); i++, msgs++)
 		if (bits & msgs->mask)
 			printk(KERN_DEBUG "%s ", msgs->msg);
 
@@ -123,13 +108,6 @@
 }
 #endif /* PDC202XX_DECODE_REGISTER_INFO */
 
-
-static inline int init_high_16 (struct pci_dev *dev)
-{
-	return pci_resource_start(dev, 4);
-}
-
-
 int check_in_drive_lists(struct ata_device *drive)
 {
 	static const char *pdc_quirk_drives[] = {
@@ -179,14 +157,14 @@
 
 static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
 {
-	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev = hwif->pci_dev;
-
-	unsigned int		drive_conf;
-	byte			drive_pci, AP, BP, CP;
-	byte			TA = 0, TB = 0, TC = 0;
+	struct pci_dev *dev = drive->channel->pci_dev;
+	u32 drive_conf;
+	u8 drive_pci, AP, BP, CP, TA = 0, TB, TC = 0;
+#if PDC202XX_DECODE_REGISTER_INFO
+	u8 DP;
+#endif
 
-	if (drive->dn > 3)
+	if (drive->dn > 3) /* FIXME: remove this --bkz */
 		return -1;
 
 	drive_pci = 0x60 + (drive->dn << 2);
@@ -195,37 +173,12 @@
 		return -1;
 
 	pci_read_config_dword(dev, drive_pci, &drive_conf);
-	pci_read_config_byte(dev, (drive_pci), &AP);
-	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
-	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	if (speed >= XFER_SW_DMA_0) {
-		if ((BP & 0xF0) && (CP & 0x0F)) {
-			/* clear DMA modes of upper 842 bits of B Register */
-			/* clear PIO forced mode upper 1 bit of B Register */
-			pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0);
-			/* clear DMA modes of lower 8421 bits of C Register */
-			pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F);
-		}
-	} else
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	{
-		if ((AP & 0x0F) || (BP & 0x07)) {
-			/* clear PIO modes of lower 8421 bits of A Register */
-			pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
-			/* clear PIO modes of lower 421 bits of B Register */
-			pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
-		}
-	}
-
-	pci_read_config_byte(dev, (drive_pci), &AP);
-	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
-	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+	pci_read_config_byte(dev, drive_pci, &AP);
+	pci_read_config_byte(dev, drive_pci + 1, &BP);
+	pci_read_config_byte(dev, drive_pci + 2, &CP);
 
 	switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
-		/* case XFER_UDMA_6: */
 		case XFER_UDMA_5:
 		case XFER_UDMA_4:	TB = 0x20; TC = 0x01; break;
 		case XFER_UDMA_3:	TB = 0x40; TC = 0x02; break;
@@ -238,7 +191,7 @@
 		case XFER_SW_DMA_2:	TB = 0x60; TC = 0x05; break;
 		case XFER_SW_DMA_1:	TB = 0x80; TC = 0x06; break;
 		case XFER_SW_DMA_0:	TB = 0xC0; TC = 0x0B; break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 		case XFER_PIO_4:	TA = 0x01; TB = 0x04; break;
 		case XFER_PIO_3:	TA = 0x02; TB = 0x06; break;
 		case XFER_PIO_2:	TA = 0x03; TB = 0x08; break;
@@ -249,20 +202,20 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
         if (speed >= XFER_SW_DMA_0) {
-		pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
-		pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);
+		pci_write_config_byte(dev, drive_pci + 1, (BP & ~0xf0) | TB);
+		pci_write_config_byte(dev, drive_pci + 2, (CP & ~0x0f) | TC);
 	} else
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 	{
-		pci_write_config_byte(dev, (drive_pci), AP|TA);
-		pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
+		pci_write_config_byte(dev, drive_pci, (AP & ~0x0f) | TA);
+		pci_write_config_byte(dev, drive_pci + 1, (BP & ~0x07) | TB);
 	}
 
 #if PDC202XX_DECODE_REGISTER_INFO
-	pci_read_config_byte(dev, (drive_pci), &AP);
-	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
-	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
-	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+	pci_read_config_byte(dev, drive_pci, &AP);
+	pci_read_config_byte(dev, drive_pci + 1, &BP);
+	pci_read_config_byte(dev, drive_pci + 2, &CP);
+	pci_read_config_byte(dev, drive_pci + 3, &DP);
 
 	printk(KERN_DEBUG "AP(%x): PIO(A) = %d\n", AP, AP & 0x0f);
 	pdc_dump_bits(pdc_reg_A, AP);
@@ -277,8 +230,6 @@
 	printk(KERN_DEBUG "DP(%x)\n", DP);
 #endif
 
-	drive->current_speed = speed;
-
 #if PDC202XX_DEBUG_DRIVE_INFO
 	printk("%s: %02x drive%d 0x%08x ",
 		drive->name, speed,
@@ -298,7 +249,6 @@
 	OUT_BYTE(value, reg); \
         mdelay(delay);
 
-
 static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed)
 {
 	struct ata_channel *hwif = drive->channel;
@@ -306,7 +256,7 @@
 	unsigned long indexreg	= (hwif->dma_base + 1);
 	unsigned long datareg	= (hwif->dma_base + 3);
 #else
-	unsigned long high_16	= init_high_16(hwif->pci_dev);
+	u32 high_16 = pci_resource_start(hwif->pci_dev, 4);
 	unsigned long indexreg	= high_16 + (hwif->unit ? 0x09 : 0x01);
 	unsigned long datareg	= (indexreg + 2);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -400,8 +350,6 @@
 			;
 	}
 
-	drive->current_speed = speed;
-
 	return ide_config_drive_speed(drive, speed);
 }
 
@@ -412,12 +360,12 @@
  * 180, 120,  90,  90,  90,  60,  30
  *  11,   5,   4,   3,   2,   1,   0
  */
-static void config_chipset_for_pio(struct ata_device *drive, byte pio)
+static void pdc202xx_tune_drive(struct ata_device *drive, u8 pio)
 {
-	byte speed;
+	u8 speed;
 
 	if (pio == 255)
-		speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
+		speed = ata_best_pio_mode(drive);
 	else	speed = XFER_PIO_0 + min_t(byte, pio, 4);
 
 	pdc202xx_tune_chipset(drive, speed);
@@ -431,23 +379,19 @@
 	struct ata_channel *hwif = drive->channel;
 	struct hd_driveid *mate_id = hwif->drives[!(drive->dn%2)].id;
 	struct pci_dev *dev	= hwif->pci_dev;
-	unsigned long high_16   = init_high_16(dev);
-	unsigned long dma_base  = hwif->dma_base;
-	unsigned long indexreg	= dma_base + 1;
-	unsigned long datareg	= dma_base + 3;
+	u32 high_16 = pci_resource_start(dev, 4);
+	u32 dma_base = hwif->dma_base;
+	u32 indexreg = dma_base + 1;
+	u32 datareg = dma_base + 3;
 	byte adj		= (drive->dn%2) ? 0x08 : 0x00;
-	byte jumpbit		= 0;
-	unsigned int		drive_conf;
-	byte drive_pci = 0, AP, tmp, mode = -1;
-	byte CLKSPD		= 0;
-	/* primary - second bit, secondary - fourth bit */
-	byte mask		= hwif->unit ? 0x08 : 0x02;
+	u8 jumpbit;
+	u32 drive_conf;
+	u8 drive_pci = 0, AP, tmp, mode = -1;
+	u8 CLKSPD, mask = hwif->unit ? 0x08 : 0x02;
 	int map;
 
-	byte needs_80w = ((id->dma_ultra & 0x0008) ||
-			  (id->dma_ultra & 0x0010) ||
-			  (id->dma_ultra & 0x0020) ||
-			  (id->dma_ultra & 0x0040));
+	/* UDMA 3, 4, 5 and 6 */
+	u8 needs_80w = (id->dma_ultra & 0x0078);
 
 	switch(dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20267:
@@ -456,52 +400,44 @@
 		case PCI_DEVICE_ID_PROMISE_20246:
 			jumpbit = 0;
 			break;
-		default: /* chipsets newer then 20268 */
+		default: /* chipsets newer then 20267 */
 			jumpbit = 1;
 			break;
 	}
 
-	if (!jumpbit)
-		CLKSPD = PDC_CLOCK(high_16);
+	/* FIXME: this check is wrong for 20246  --bkz */
+	/* */
+	if (needs_80w && !hwif->udma_four) {
+		printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name);
+		printk(KERN_INFO "%s: reduced to UDMA(33) mode.\n", drive->name);
+	}
+
+	if (jumpbit)
+		goto chipset_is_set;
+
 	/*
 	 * Set the control register to use the 66Mhz system
-	 * clock for UDMA 3/4 mode operation. If one drive on
+	 * clock for UDMA 3/4 mode operations. If one drive on
 	 * a channel is U66 capable but the other isn't we
 	 * fall back to U33 mode. The BIOS INT 13 hooks turn
-	 * the clock on then off for each read/write issued. I don't
-	 * do that here because it would require modifying the
-	 * kernel, seperating the fop routines from the kernel or
-	 * somehow hooking the fops calls. It may also be possible to
-	 * leave the 66Mhz clock on and readjust the timing
-	 * parameters.
+	 * the clock on then off for each read/write issued.
+	 * We can do the same in device specific udma_start/stop()
+	 * routines or better try to readjust timings.
+	 *
+	 * FIXME: move this to pdc202xx_tuneproc()
+	 *        right now you can't downgrade from U66 to U33  --bkz
 	 */
 	if (needs_80w) {
-		/* FIXME: this check is wrong for 20246 --bkz */
-		if (!hwif->udma_four) {
-			printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name);
-			printk(KERN_WARNING "%s: reduced to UDMA(33) mode.\n", drive->name);
-			if (!jumpbit)
-				OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
-		}
-		if (!jumpbit) {
-			if (mate_id) {	/* check if mate is at least udma3 */
-				if ((mate_id->dma_ultra & 0x0040) ||
-				    (mate_id->dma_ultra & 0x0020) ||
-				    (mate_id->dma_ultra & 0x0010) ||
-				    (mate_id->dma_ultra & 0x0008)) {
-					OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
-				} else {
-					OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
-				}
-			} else {	/* single drive */
-				OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
-			}
-		}
+		CLKSPD = IN_BYTE(high_16 + PDC_CLK);
+		/* check cable and mate (must be at least udma3 capable) */
+		if (!hwif->udma_four ||
+		    !mate_id || !(mate_id->dma_ultra & 0x0078))
+			OUT_BYTE(CLKSPD & ~mask, high_16 + PDC_CLK);
+		else
+			/* cable ok, mate ok or single drive */
+			OUT_BYTE(CLKSPD | mask, high_16 + PDC_CLK);
 	}
 
-	if (jumpbit)
-		goto chipset_is_set;
-
 	if (drive->dn > 3)	/* FIXME: remove this --bkz */
 		return 0;
 
@@ -560,7 +496,7 @@
 		return 0;
 	}
 
-	return !(hwif->speedproc(drive, mode));
+	return !hwif->speedproc(drive, mode);
 }
 
 static int pdc202xx_udma_setup(struct ata_device *drive)
@@ -603,7 +539,7 @@
 		} else goto no_dma_set;
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 no_dma_set:
-		config_chipset_for_pio(drive, 5);
+		pdc202xx_tune_drive(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
@@ -611,17 +547,17 @@
 	return 0;
 }
 
-static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
+static void pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *ch = drive->channel;
-	unsigned long high_16 = init_high_16(ch->pci_dev);
+	u32 high_16 = pci_resource_start(ch->pci_dev, 4);
 	unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00);
 
 	if (drive->addressing) {
 		unsigned long word_count = 0;
-		u8 clock = PDC_CLOCK(high_16);
+		u8 clock = IN_BYTE(high_16 + PDC_CLK);
 
-		outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + 0x11);
+		outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + PDC_CLK);
 		word_count = (rq->nr_sectors << 8);
 		word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
 		outl(word_count, atapi_reg);
@@ -633,22 +569,20 @@
 	 */
 
 	outb(inb(ch->dma_base) | 1, ch->dma_base); /* start DMA */
-
-	return 0;
 }
 
 int pdc202xx_udma_stop(struct ata_device *drive)
 {
 	struct ata_channel *ch = drive->channel;
-	unsigned long high_16 = init_high_16(ch->pci_dev);
+	u32 high_16 = pci_resource_start(ch->pci_dev, 4);
 	unsigned long atapi_reg	= high_16 + (ch->unit ? 0x24 : 0x00);
 	unsigned long dma_base = ch->dma_base;
 	u8 dma_stat, clock;
 
 	if (drive->addressing) {
 		outl(0, atapi_reg);	/* zero out extra */
-		clock = PDC_CLOCK(high_16);
-		OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + 0x11);
+		clock = IN_BYTE(high_16 + PDC_CLK);
+		OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + PDC_CLK);
 	}
 
 	drive->waiting_for_dma = 0;
@@ -660,16 +594,6 @@
 	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 }
 
-static int pdc202xx_udma_irq_status(struct ata_device *drive)
-{
-	struct ata_channel *ch = drive->channel;
-	u8 dma_stat;
-
-	dma_stat = IN_BYTE(ch->dma_base + 2);
-
-	return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
-}
-
 static void pdc202xx_bug(struct ata_device *drive)
 {
 	if (!drive->channel->resetproc)
@@ -690,55 +614,51 @@
 		drive->channel->unit ? "Secondary" : "Primary");
 }
 
-void pdc202xx_reset(struct ata_device *drive)
+/*
+ * software host reset
+ *
+ * BIOS will set UDMA timing on if the drive supports it.
+ * The user may then want to turn it off. A bug is that
+ * that device cannot handle a downgrade in timing from
+ * UDMA to DMA. Disk accesses after issuing a set
+ * feature command will result in errors.
+ *
+ * A software reset leaves the timing registers intact,
+ * but resets the drives on both channels.
+ */
+static void pdc202xx_reset_host(struct pci_dev *dev)
 {
-	unsigned long high_16	= init_high_16(drive->channel->pci_dev);
-	byte udma_speed_flag	= UDMA_SPEED_FLAG(high_16);
+	u32 high_16 = pci_resource_start(dev, 4);
+	u8 burst = IN_BYTE(high_16 + PDC_UDMA);
 
-	set_reg_and_wait(udma_speed_flag | 0x10, high_16 + 0x001f, 100);
-	set_reg_and_wait(udma_speed_flag & ~0x10, high_16 + 0x001f, 2000);		/* 2 seconds ?! */
-	printk("PDC202XX: %s channel reset.\n",
-		drive->channel->unit ? "Secondary" : "Primary");
+	set_reg_and_wait(burst | 0x10, high_16 + PDC_UDMA, 100);
+	/* FIXME: 2 seconds ?! */
+	set_reg_and_wait(burst & ~0x10, high_16 + PDC_UDMA, 2000);
+	printk(KERN_INFO "%s: device reseted.\n", dev->name);
+}
+
+void pdc202xx_reset(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	printk(KERN_INFO "%s: channel needs reset.\n", ch->name);
+	pdc202xx_reset_host(ch->pci_dev);
 }
 
-/* FIXME: should be splited for old & new chipsets --bkz */
 static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev)
 {
-	unsigned long high_16	= init_high_16(dev);
-	byte udma_speed_flag	= UDMA_SPEED_FLAG(high_16);
-	byte primary_mode	= IN_BYTE(high_16 + 0x001a);
-	byte secondary_mode	= IN_BYTE(high_16 + 0x001b);
-	byte newchip		= 0;
+	u32 high_16 = pci_resource_start(dev, 4);
+	u8 burst = IN_BYTE(high_16 + PDC_UDMA);
 
 	if (dev->resource[PCI_ROM_RESOURCE].start) {
 		pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
-		printk("%s: ROM enabled at 0x%08lx\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start);
+		printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start);
 	}
 
 	switch (dev->device) {
-		case PCI_DEVICE_ID_PROMISE_20275:
-		case PCI_DEVICE_ID_PROMISE_20276:
-		case PCI_DEVICE_ID_PROMISE_20269:
-		case PCI_DEVICE_ID_PROMISE_20268R:
-		case PCI_DEVICE_ID_PROMISE_20268:
-			newchip = 1;
-			break;
 		case PCI_DEVICE_ID_PROMISE_20267:
 		case PCI_DEVICE_ID_PROMISE_20265:
 		case PCI_DEVICE_ID_PROMISE_20262:
-			/*
-			 * software reset - this is required because the BIOS
-			 * will set UDMA timing on if the drive supports it.
-			 * The user may want to turn udma off. A bug is that
-			 * that device cannot handle a downgrade in timing from
-			 * UDMA to DMA. Disk accesses after issuing a set
-			 * feature command will result in errors.
-			 *
-			 * A software reset leaves the timing registers intact,
-			 * but resets the drives.
-			 */
-			set_reg_and_wait(udma_speed_flag | 0x10, high_16 + 0x001f, 100);
-			set_reg_and_wait(udma_speed_flag & ~0x10, high_16 + 0x001f, 2000);   /* 2 seconds ?! */
+			pdc202xx_reset_host(dev);
 			break;
 		default:
 		/* FIXME: only checked for 20246 - is this right?,
@@ -755,51 +675,49 @@
 			break;
 	}
 
-	if (newchip)
-		goto fttk_tx_series;
-
-	printk("%s: (U)DMA Burst Bit %sABLED " \
-		"Primary %s Mode " \
-		"Secondary %s Mode.\n",
-		dev->name,
-		(udma_speed_flag & 1) ? "EN" : "DIS",
-		(primary_mode & 1) ? "MASTER" : "PCI",
-		(secondary_mode & 1) ? "MASTER" : "PCI" );
-
 #ifdef CONFIG_PDC202XX_BURST
-	if (!(udma_speed_flag & 1)) {
-		printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", dev->name, udma_speed_flag, (udma_speed_flag|1));
-		OUT_BYTE(udma_speed_flag|1, high_16 + 0x001f);
-		printk("%sCTIVE\n", (UDMA_SPEED_FLAG(high_16) & 1) ? "A" : "INA");
+	if (!(burst & 1)) {
+		printk(KERN_INFO "%s: forcing (U)DMA BURST.\n", dev->name);
+		OUT_BYTE(burst | 1, high_16 + PDC_UDMA);
 	}
-#endif /* CONFIG_PDC202XX_BURST */
+#endif
+	printk(KERN_INFO "%s: (U)DMA BURST %sabled, "
+			 "primary %s mode, secondary %s mode.\n",
+	       dev->name, (burst & 1) ? "en" : "dis",
+	       (IN_BYTE(high_16 + PDC_PRIMARY) & 1) ? "MASTER" : "PCI",
+	       (IN_BYTE(high_16 + PDC_SECONDARY) & 1) ? "MASTER" : "PCI" );
 
-fttk_tx_series:
 	return dev->irq;
 }
 
-static unsigned int __init ata66_pdc202xx(struct ata_channel *hwif)
+/* chipsets newer then 20267 */
+static unsigned int __init pdc202xx_tx_init_chipset(struct pci_dev *dev)
 {
-	unsigned short mask = (hwif->unit) ? (1<<11) : (1<<10);
-	unsigned short CIS;
-
-        switch(hwif->pci_dev->device) {
-		case PCI_DEVICE_ID_PROMISE_20275:
-		case PCI_DEVICE_ID_PROMISE_20276:
-		case PCI_DEVICE_ID_PROMISE_20269:
-		case PCI_DEVICE_ID_PROMISE_20268:
-		case PCI_DEVICE_ID_PROMISE_20268R:
-			OUT_BYTE(0x0b, (hwif->dma_base + 1));
-			return (!(IN_BYTE((hwif->dma_base + 3)) & 0x04));
-		default:
-			pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
-			return (!(CIS & mask));
+	if (dev->resource[PCI_ROM_RESOURCE].start) {
+		pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
+		printk(KERN_INFO "%s: ROM enabled at 0x%08lx.\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start);
 	}
+	return dev->irq;
+}
+
+static unsigned int __init pdc202xx_ata66_check(struct ata_channel *ch)
+{
+	u16 CIS;
+
+	pci_read_config_word(ch->pci_dev, 0x50, &CIS);
+	return !(CIS & (1 << (10 + ch->unit)));
+}
+
+/* chipsets newer then 20267 */
+static unsigned int __init pdc202xx_tx_ata66_check(struct ata_channel *ch)
+{
+	OUT_BYTE(0x0b, ch->dma_base + 1);
+	return !(IN_BYTE(ch->dma_base + 3) & 0x04);
 }
 
 static void __init ide_init_pdc202xx(struct ata_channel *hwif)
 {
-	hwif->tuneproc  = &config_chipset_for_pio;
+	hwif->tuneproc  = &pdc202xx_tune_drive;
 	hwif->quirkproc = &check_in_drive_lists;
 
         switch(hwif->pci_dev->device) {
@@ -820,7 +738,6 @@
 			if (hwif->dma_base) {
 				hwif->udma_start = pdc202xx_udma_start;
 				hwif->udma_stop = pdc202xx_udma_stop;
-				hwif->udma_irq_status = pdc202xx_udma_irq_status;
 			}
 #endif
 		/* FIXME: check whether 20246 works with lba48 --bkz */
@@ -867,7 +784,7 @@
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20262,
 		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		ata66_check: pdc202xx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 #ifndef CONFIG_PDC202XX_FORCE
 		enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
@@ -880,7 +797,7 @@
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20265,
 		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		ata66_check: pdc202xx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 #ifndef CONFIG_PDC202XX_FORCE
 		enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
@@ -895,7 +812,7 @@
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20267,
 		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		ata66_check: pdc202xx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 #ifndef CONFIG_PDC202XX_FORCE
 		enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
@@ -907,8 +824,8 @@
 	{
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20268,
-		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		init_chipset: pdc202xx_tx_init_chipset,
+		ata66_check: pdc202xx_tx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 		bootable: OFF_BOARD,
 		flags: ATA_F_IRQ | ATA_F_DMA
@@ -920,8 +837,8 @@
 	{
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20268R,
-		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		init_chipset: pdc202xx_tx_init_chipset,
+		ata66_check: pdc202xx_tx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 		bootable: OFF_BOARD,
 		flags: ATA_F_IRQ  | ATA_F_DMA
@@ -929,8 +846,8 @@
 	{
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20269,
-		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		init_chipset: pdc202xx_tx_init_chipset,
+		ata66_check: pdc202xx_tx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 		bootable: OFF_BOARD,
 		flags: ATA_F_IRQ | ATA_F_DMA
@@ -938,8 +855,8 @@
 	{
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20275,
-		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		init_chipset: pdc202xx_tx_init_chipset,
+		ata66_check: pdc202xx_tx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 		bootable: OFF_BOARD,
 		flags: ATA_F_IRQ | ATA_F_DMA
@@ -947,8 +864,8 @@
 	{
 		vendor: PCI_VENDOR_ID_PROMISE,
 		device: PCI_DEVICE_ID_PROMISE_20276,
-		init_chipset: pdc202xx_init_chipset,
-		ata66_check: ata66_pdc202xx,
+		init_chipset: pdc202xx_tx_init_chipset,
+		ata66_check: pdc202xx_tx_ata66_check,
 		init_channel: ide_init_pdc202xx,
 		bootable: OFF_BOARD,
 		flags: ATA_F_IRQ | ATA_F_DMA
diff -Nru a/drivers/ide/pdc4030.c b/drivers/ide/pdc4030.c
--- a/drivers/ide/pdc4030.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/pdc4030.c	Sun Jun 16 19:31:39 2002
@@ -247,11 +247,19 @@
 	if (pdc4030_cmd(drive, PROMISE_GET_CONFIG)) {
 		return 0;
 	}
-	if (ide_wait_stat(&startstop, drive, NULL, DATA_READY,BAD_W_STAT,WAIT_DRQ)) {
+
+	/* FIXME: Make this go away. */
+	spin_lock_irq(hwif->lock);
+	if (ata_status_poll(drive, DATA_READY, BAD_W_STAT,
+				WAIT_DRQ, NULL, &startstop)) {
 		printk(KERN_INFO
 			"%s: Failed Promise read config!\n",hwif->name);
+		spin_unlock_irq(hwif->lock);
+
 		return 0;
 	}
+	spin_unlock_irq(hwif->lock);
+
 	promise_read(drive, &ident, SECTOR_WORDS);
 	if (ident.id[1] != 'P' || ident.id[0] != 'T') {
 		return 0;
@@ -407,7 +415,8 @@
 	rq->nr_sectors -= nsect;
 	total_remaining = rq->nr_sectors;
 	if ((rq->current_nr_sectors -= nsect) <= 0) {
-		ide_end_request(drive, rq, 1);
+		/* FIXME: no queue locking above! */
+		ata_end_request(drive, rq, 1);
 	}
 
 	/*
@@ -428,7 +437,16 @@
 		if (drive->status & DRQ_STAT)
 			goto read_again;
 		if (drive->status & BUSY_STAT) {
-			ide_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
+			unsigned long flags;
+			struct ata_channel *ch = drive->channel;
+
+			/* FIXME: this locking should encompass the above register
+			 * file access too.
+			 */
+
+			spin_lock_irqsave(ch->lock, flags);
+			ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
+			spin_unlock_irqrestore(ch->lock, flags);
 #ifdef DEBUG_READ
 			printk(KERN_DEBUG "%s: promise_read: waiting for"
 			       "interrupt\n", drive->name);
@@ -452,11 +470,19 @@
  */
 static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
 
 	if (!ata_status(drive, 0, BUSY_STAT)) {
 		if (time_before(jiffies, ch->poll_timeout)) {
-			ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
+			/* FIXME: this locking should encompass the above
+			 * register file access too.
+			 */
+
+			spin_lock_irqsave(ch->lock, flags);
+			ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ide_started; /* continue polling... */
 		}
 		ch->poll_timeout = 0;
@@ -469,7 +495,13 @@
 #ifdef DEBUG_WRITE
 	printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name);
 #endif
-	__ide_end_request(drive, rq, 1, rq->nr_sectors);
+	/* FIXME: this locking should encompass the above
+	 * register file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
+	__ata_end_request(drive, rq, 1, rq->nr_sectors);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_stopped;
 }
@@ -531,16 +563,22 @@
  */
 static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
 
+	spin_lock_irqsave(ch->lock, flags);
 	if (inb(IDE_NSECTOR_REG) != 0) {
 		if (time_before(jiffies, ch->poll_timeout)) {
-			ide_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
+			ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ide_started; /* continue polling... */
 		}
 		ch->poll_timeout = 0;
 		printk(KERN_ERR "%s: write timed out!\n", drive->name);
 		ata_status(drive, 0, 0);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return ata_error(drive, rq, "write timeout");
 	}
 
@@ -549,11 +587,12 @@
 	 */
 	promise_multwrite(drive, rq, 4);
 	ch->poll_timeout = jiffies + WAIT_WORSTCASE;
-	ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
+	ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
 #ifdef DEBUG_WRITE
 	printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
 		drive->name, drive->status);
 #endif
+	spin_unlock_irqrestore(ch->lock, flags);
 	return ide_started;
 }
 
@@ -566,6 +605,7 @@
  */
 static ide_startstop_t promise_do_write(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
 
 #ifdef DEBUG_WRITE
@@ -573,26 +613,38 @@
 	       "buffer=%p\n", drive->name, rq->sector,
 	       rq->sector + rq->nr_sectors - 1, rq->buffer);
 #endif
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
 
+	spin_lock_irqsave(ch->lock, flags);
 	/*
 	 * If there are more than 4 sectors to transfer, do n-4 then go into
 	 * the polling strategy as defined above.
 	 */
 	if (rq->nr_sectors > 4) {
-		if (promise_multwrite(drive, rq, rq->nr_sectors - 4))
+		if (promise_multwrite(drive, rq, rq->nr_sectors - 4)) {
+			spin_unlock_irqrestore(ch->lock, flags);
 			return ide_stopped;
+		}
 		ch->poll_timeout = jiffies + WAIT_WORSTCASE;
-		ide_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
+		ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return ide_started;
 	} else {
 	/*
 	 * There are 4 or fewer sectors to transfer, do them all in one go
 	 * and wait for NOT BUSY.
 	 */
-		if (promise_multwrite(drive, rq, rq->nr_sectors))
+		if (promise_multwrite(drive, rq, rq->nr_sectors)) {
+			spin_unlock_irqrestore(ch->lock, flags);
 			return ide_stopped;
+		}
 		ch->poll_timeout = jiffies + WAIT_WORSTCASE;
-		ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
+		ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 #ifdef DEBUG_WRITE
 		printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
 			"status = %02x\n", drive->name, drive->status);
@@ -614,7 +666,7 @@
 	/* Check that it's a regular command. If not, bomb out early. */
 	if (!(rq->flags & REQ_CMD)) {
 		blk_dump_rq_flags(rq, "pdc4030 bad flags");
-		ide_end_request(drive, rq, 0);
+		ata_end_request(drive, rq, 0);
 
 		return ide_stopped;
 	}
@@ -629,16 +681,19 @@
 
 	switch (rq_data_dir(rq)) {
 	case READ:
-/*
- * The card's behaviour is odd at this point. If the data is
- * available, DRQ will be true, and no interrupt will be
- * generated by the card. If this is the case, we need to call the
- * "interrupt" handler (promise_read_intr) directly. Otherwise, if
- * an interrupt is going to occur, bit0 of the SELECT register will
- * be high, so we can set the handler the just return and be interrupted.
- * If neither of these is the case, we wait for up to 50ms (badly I'm
- * afraid!) until one of them is.
- */
+
+		/*
+		 * The card's behaviour is odd at this point. If the data is
+		 * available, DRQ will be true, and no interrupt will be
+		 * generated by the card. If this is the case, we need to call
+		 * the "interrupt" handler (promise_read_intr) directly.
+		 * Otherwise, if an interrupt is going to occur, bit0 of the
+		 * SELECT register will be high, so we can set the handler the
+		 * just return and be interrupted.  If neither of these is the
+		 * case, we wait for up to 50ms (badly I'm afraid!) until one
+		 * of them is.
+		 */
+
 		timeout = jiffies + HZ/20; /* 50ms wait */
 		do {
 			if (!ata_status(drive, 0, DRQ_STAT)) {
@@ -646,11 +701,21 @@
 				return promise_read_intr(drive, rq);
 			}
 			if (inb(IDE_SELECT_REG) & 0x01) {
+				unsigned long flags;
+				struct ata_channel *ch = drive->channel;
+
+				/* FIXME: this locking should encompass the above register
+				 * file access too.
+				 */
+
+				spin_lock_irqsave(ch->lock, flags);
 #ifdef DEBUG_READ
 				printk(KERN_DEBUG "%s: read: waiting for "
 				                  "interrupt\n", drive->name);
 #endif
-				ide_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
+				ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
+				spin_unlock_irqrestore(ch->lock, flags);
+
 				return ide_started;
 			}
 			udelay(1);
@@ -662,26 +727,41 @@
 
 	case WRITE: {
 		ide_startstop_t startstop;
-/*
- * Strategy on write is:
- *	look for the DRQ that should have been immediately asserted
- *	copy the request into the hwgroup's scratchpad
- *	call the promise_write function to deal with writing the data out
- * NOTE: No interrupts are generated on writes. Write completion must be polled
- */
-		if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+		unsigned long flags;
+		struct ata_channel *ch = drive->channel;
+
+		/*
+		 * Strategy on write is: look for the DRQ that should have been
+		 * immediately asserted copy the request into the hwgroup's
+		 * scratchpad call the promise_write function to deal with
+		 * writing the data out.
+		 *
+		 * NOTE: No interrupts are generated on writes. Write
+		 * completion must be polled
+		 */
+
+		/* FIXME: Move this lock upwards.
+		 */
+		spin_lock_irqsave(ch->lock, flags);
+		if (ata_status_poll(drive, DATA_READY, drive->bad_wstat,
+					WAIT_DRQ, rq, &startstop )) {
 			printk(KERN_ERR "%s: no DRQ after issuing "
 			       "PROMISE_WRITE\n", drive->name);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return startstop;
 		}
 		if (!drive->channel->unmask)
 			__cli();	/* local CPU only */
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return promise_do_write(drive, rq);
 	}
 
 	default:
 		printk(KERN_ERR "pdc4030: command not READ or WRITE! Huh?\n");
-		ide_end_request(drive, rq, 0);
+		/* FIXME: This should already run under the lock. */
+		ata_end_request(drive, rq, 0);
 		return ide_stopped;
 	}
 }
@@ -704,7 +784,7 @@
 	args.taskfile.high_cylinder	= (block>>=8);
 	args.taskfile.device_head	= ((block>>8)&0x0f)|drive->select.all;
 	args.cmd = (rq_data_dir(rq) == READ) ? PROMISE_READ : PROMISE_WRITE;
-	args.handler	= NULL;
+	args.XXX_handler	= NULL;
 	rq->special	= &args;
 
 	return do_pdc4030_io(drive, &args, rq);
diff -Nru a/drivers/ide/piix.c b/drivers/ide/piix.c
--- a/drivers/ide/piix.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/piix.c	Sun Jun 16 19:31:40 2002
@@ -72,11 +72,6 @@
 #define PIIX_CHECK_REV		0x40	/* May be a buggy revision of PIIX */
 #define PIIX_NODMA		0x80	/* Don't do DMA with this chip */
 
-#ifdef CONFIG_BLK_DEV_PIIX_TRY133	/* I think even the older ICHs should be able to do UDMA133 */
-#undef PIIX_UDMA_100
-#define PIIX_UDMA_100 PIIX_UDMA_133
-#endif
-
 /*
  * Intel IDE chips
  */
@@ -104,7 +99,6 @@
 
 static struct piix_ide_chip *piix_config;
 static unsigned char piix_enabled;
-static unsigned int piix_80w;
 
 static char *piix_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
 
@@ -227,8 +221,6 @@
 	}
 
 	piix_set_speed(drive->channel->pci_dev, drive->dn, &t, umul);
-
-	drive->current_speed = speed;
 
 	return 0;
 }
diff -Nru a/drivers/ide/probe.c b/drivers/ide/probe.c
--- a/drivers/ide/probe.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/probe.c	Sun Jun 16 19:31:39 2002
@@ -307,16 +307,7 @@
 		(drive->id->hw_config & 0x6000)) ? 1 : 0);
 }
 
-/*
- * Similar to ide_wait_stat(), except it never calls ata_error internally.
- * This is a kludge to handle the new ide_config_drive_speed() function,
- * and should not otherwise be used anywhere.  Eventually, the tuneproc's
- * should be updated to return ide_startstop_t, in which case we can get
- * rid of this abomination again.  :)   -ml
- *
- * It is gone..........
- *
- * const char *msg == consider adding for verbose errors.
+/* FIXME: Channel lock should be held.
  */
 int ide_config_drive_speed(struct ata_device *drive, byte speed)
 {
@@ -329,12 +320,10 @@
 	outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
 #endif
 
-	/*
-	 * Don't use ide_wait_cmd here - it will attempt to set_geometry and
+	/* Don't use ide_wait_cmd here - it will attempt to set_geometry and
 	 * recalibrate, but for some reason these don't work at this point
 	 * (lost interrupt).
-	 */
-        /*
+         *
          * Select the drive, and issue the SETFEATURES command
          */
 	disable_irq(ch->irq);	/* disable_irq_nosync ?? */
@@ -350,20 +339,9 @@
 		ata_irq_enable(drive, 1);
 	udelay(1);
 
-	/*
-	 * Wait for drive to become non-BUSY
-	 */
-	if (!ata_status(drive, 0, BUSY_STAT)) {
-		unsigned long flags, timeout;
-		__save_flags(flags);	/* local CPU only */
-		ide__sti();		/* local CPU only -- for jiffies */
-		timeout = jiffies + WAIT_CMD;
-		while (!ata_status(drive, 0, BUSY_STAT)) {
-			if (time_after(jiffies, timeout))
-				break;
-		}
-		__restore_flags(flags); /* local CPU only */
-	}
+	/* FIXME: use ata_status_poll()  --bkz */
+
+	ata_busy_poll(drive, WAIT_CMD);
 
 	/*
 	 * Allow status to settle, then read it again.
@@ -419,6 +397,8 @@
 		default: break;
 	}
 
+	drive->current_speed = speed;
+
 	return error;
 }
 
@@ -874,10 +854,11 @@
 		goto not_found;
 
 	/* Register this hardware interface within the global device tree.
+	 *
+	 * FIXME: This should be handled as a pci subdevice in a generic way.
 	 */
-	sprintf(ch->dev.bus_id, "%04lx",
-		(unsigned long) ch->io_ports[IDE_DATA_OFFSET]);
-	sprintf(ch->dev.name, "ide");
+	sprintf(ch->dev.bus_id, "ata@%02x", ch->unit);
+	strcpy(ch->dev.name, "ATA/ATAPI Host-Channel");
 	ch->dev.driver_data = ch;
 #ifdef CONFIG_PCI
 	if (ch->pci_dev)
diff -Nru a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
--- a/drivers/ide/serverworks.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/serverworks.c	Sun Jun 16 19:31:40 2002
@@ -123,23 +123,21 @@
 	return map;
 }
 
-static int svwks_tune_chipset(struct ata_device *drive, byte speed)
+static int svwks_tune_chipset(struct ata_device *drive, u8 speed)
 {
 	static u8 dma_modes[]	= { 0x77, 0x21, 0x20 };
 	static u8 pio_modes[]	= { 0x5d, 0x47, 0x34, 0x22, 0x20 };
 
-	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-	byte unit		= (drive->select.b.unit & 0x01);
-	byte csb5		= (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0;
-
-	byte drive_pci, drive_pci2;
-	byte drive_pci3	= hwif->unit ? 0x57 : 0x56;
+	struct ata_channel *ch = drive->channel;
+	struct pci_dev *dev = ch->pci_dev;
+	u8 unit = drive->select.b.unit & 0x01;
+	u8 drive_pci, drive_pci2;
+	u8 drive_pci3 = ch->unit ? 0x57 : 0x56;
 
-	byte ultra_enable, ultra_timing, dma_timing, pio_timing;
-	unsigned short csb5_pio;
+	u8 ultra_enable, ultra_timing, dma_timing, pio_timing;
+	u16 csb5_pio;
 
-	byte pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
+	u8 pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
         switch (drive->dn) {
 		case 0: drive_pci = 0x41; break;
@@ -213,7 +211,8 @@
 #endif
 
 	pci_write_config_byte(dev, drive_pci, pio_timing);
-	if (csb5)
+
+	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
 		pci_write_config_word(dev, 0x4A, csb5_pio);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -221,67 +220,20 @@
 	pci_write_config_byte(dev, drive_pci3, ultra_timing);
 	pci_write_config_byte(dev, 0x54, ultra_enable);
 #endif
-	drive->current_speed = speed;
 
 	return ide_config_drive_speed(drive, speed);
 }
 
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
-	byte timing, speed, pio;
-
-	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio > 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0)
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	else
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 :
-			   (drive->id->tPIO & 2) ? 0x02 :
-			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
-	}
-	(void) svwks_tune_chipset(drive, speed);
-	drive->current_speed = speed;
-}
-
-static void svwks_tune_drive(struct ata_device *drive, byte pio)
+static void svwks_tune_drive(struct ata_device *drive, u8 pio)
 {
-	byte speed;
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4;break;
-		case 3:		speed = XFER_PIO_3;break;
-		case 2:		speed = XFER_PIO_2;break;
-		case 1:		speed = XFER_PIO_1;break;
-		default:	speed = XFER_PIO_0;break;
-	}
-	(void) svwks_tune_chipset(drive, speed);
+	(void) svwks_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 static int config_chipset_for_dma(struct ata_device *drive)
 {
 	int map;
-	byte mode;
+	u8 mode;
 
 	/* FIXME: check SWDMA modes --bkz */
 	map = XFER_MWDMA | svwks_ratemask(drive);
@@ -337,7 +289,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive);
+		svwks_tune_chipset(drive, ata_best_pio_mode(drive));
 	}
 
 	udma_enable(drive, on, verbose);
@@ -392,7 +344,7 @@
 static unsigned int __init svwks_init_chipset(struct pci_dev *dev)
 {
 	unsigned int reg;
-	byte btr;
+	u8 btr;
 
 	/* save revision id to determine DMA capability */
 	pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
@@ -432,8 +384,8 @@
 	return 0;
 }
 
-/* On Dell PowerEdge servers with a CSB5, the top two bits of the subsystem
- * device ID indicate presence of an 80-pin cable.
+/* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits
+ * of the subsystem device ID indicate presence of an 80-pin cable.
  * Bit 15 clear = secondary IDE channel does not have 80-pin cable.
  * Bit 15 set   = secondary IDE channel has 80-pin cable.
  * Bit 14 clear = primary IDE channel does not have 80-pin cable.
@@ -442,9 +394,9 @@
 static unsigned int __init ata66_svwks_dell(struct ata_channel *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
-	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
-	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
-	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
+	if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
+	    (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE ||
+	     dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE))
 		return ((1 << (hwif->unit + 14)) &
 			dev->subsystem_device) ? 1 : 0;
 	return 0;
@@ -459,8 +411,7 @@
 static unsigned int __init ata66_svwks_cobalt(struct ata_channel *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
-	if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&
-	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
+	if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
 	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
 		return ((1 << (hwif->unit + 14)) &
 			dev->subsystem_device) ? 1 : 0;
@@ -538,9 +489,8 @@
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(chipsets); ++i) {
+	for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
 		ata_register_chipset(&chipsets[i]);
-	}
 
         return 0;
 }
diff -Nru a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
--- a/drivers/ide/sis5513.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/sis5513.c	Sun Jun 16 19:31:40 2002
@@ -263,15 +263,11 @@
 
 
 /* Set per-drive active and recovery time */
-static void config_art_rwp_pio(struct ata_device *drive, u8 pio)
+static int config_art_rwp_pio(struct ata_device *drive, u8 pio)
 {
 	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-
-	byte			timing, drive_pci, test1, test2;
-
-	unsigned short eide_pio_timing[6] = {600, 390, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
+	struct pci_dev *dev = hwif->pci_dev;
+	u8 drive_pci, test1, test2;
 
 #ifdef DEBUG
 	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
@@ -279,37 +275,15 @@
 
 	config_drive_art_rwp(drive);
 
-	if (pio == 255)
-		pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio> 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			(xfer_pio > 0) &&
-			(drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]);
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
 #ifdef DEBUG
 	printk("SIS5513: config_drive_art_rwp_pio, drive %d, pio %d, timing %d\n",
 	       drive->dn, pio, timing);
 #endif
 
-	switch(drive->dn) {
-		case 0:		drive_pci = 0x40; break;
-		case 1:		drive_pci = 0x42; break;
-		case 2:		drive_pci = 0x44; break;
-		case 3:		drive_pci = 0x46; break;
-		default:	return;
-	}
+	if (drive->dn > 3)	/* FIXME: remove this  --bkz */
+		return 1;
+
+	drive_pci = 0x40 + (drive->dn << 1);
 
 	/* register layout changed with newer ATA100 chips */
 	if (chipset_family < ATA_100) {
@@ -320,7 +294,7 @@
 		test1 &= ~0x0F;
 		test2 &= ~0x07;
 
-		switch(timing) {
+		switch(pio) {
 			case 4:		test1 |= 0x01; test2 |= 0x03; break;
 			case 3:		test1 |= 0x03; test2 |= 0x03; break;
 			case 2:		test1 |= 0x04; test2 |= 0x04; break;
@@ -330,7 +304,7 @@
 		pci_write_config_byte(dev, drive_pci, test1);
 		pci_write_config_byte(dev, drive_pci+1, test2);
 	} else {
-		switch(timing) { /*   active  recovery
+		switch(pio) { /*   active  recovery
 					  v     v */
 			case 4:		test1 = 0x30|0x01; break;
 			case 3:		test1 = 0x30|0x03; break;
@@ -344,23 +318,8 @@
 #ifdef DEBUG
 	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
 #endif
-}
-
-static int config_chipset_for_pio(struct ata_device *drive, u8 pio)
-{
-	u8 speed;
 
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4; break;
-		case 3:		speed = XFER_PIO_3; break;
-		case 2:		speed = XFER_PIO_2; break;
-		case 1:		speed = XFER_PIO_1; break;
-		default:	speed = XFER_PIO_0; break;
-	}
-
-	config_art_rwp_pio(drive, pio);
-	drive->current_speed = speed;
-	return ide_config_drive_speed(drive, speed);
+	return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4));
 }
 
 static int sis5513_tune_chipset(struct ata_device *drive, u8 speed)
@@ -375,13 +334,11 @@
 	printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n",
 	       drive->dn, speed);
 #endif
-	switch(drive->dn) {
-		case 0:		drive_pci = 0x40; break;
-		case 1:		drive_pci = 0x42; break;
-		case 2:		drive_pci = 0x44; break;
-		case 3:		drive_pci = 0x46; break;
-		default:	return 0;
-	}
+
+	if (drive->dn > 3)	/* FIXME: remove this  --bkz */
+		return 1;
+
+	drive_pci = 0x40 + (drive->dn << 1);
 
 #ifdef BROKEN_LEVEL
 #ifdef DEBUG
@@ -424,23 +381,27 @@
 		case XFER_SW_DMA_0:
 			break;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-		case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
-		case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
-		case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
-		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
+		case XFER_PIO_4:
+		case XFER_PIO_3:
+		case XFER_PIO_2:
+		case XFER_PIO_1:
 		case XFER_PIO_0:
-		default:	 return((int) config_chipset_for_pio(drive, 0));
+			return config_art_rwp_pio(drive, speed - XFER_PIO_0);
+		default:
+			return config_art_rwp_pio(drive, 0);
 	}
-	drive->current_speed = speed;
 #ifdef DEBUG
 	sis5513_load_verify_registers(dev, "sis5513_tune_chipset end");
 #endif
-	return ((int) ide_config_drive_speed(drive, speed));
+	return ide_config_drive_speed(drive, speed);
 }
 
 static void sis5513_tune_drive(struct ata_device *drive, u8 pio)
 {
-	(void) config_chipset_for_pio(drive, pio);
+	if (pio == 255)
+		pio = ata_best_pio_mode(drive) - XFER_PIO_0;
+
+	(void)config_art_rwp_pio(drive, min_t(u8, pio, 4));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -473,8 +434,7 @@
 	int verbose = 1;
 
 	config_drive_art_rwp(drive);
-	config_art_rwp_pio(drive, 5);
-	config_chipset_for_pio(drive, 5);
+	sis5513_tune_drive(drive, 255);
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
@@ -515,7 +475,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		(void) config_chipset_for_pio(drive, 5);
+		sis5513_tune_drive(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
@@ -601,8 +561,8 @@
 
 static unsigned int __init ata66_sis5513(struct ata_channel *hwif)
 {
-	byte reg48h = 0, ata66 = 0;
-	byte mask = hwif->unit ? 0x20 : 0x10;
+	u8 reg48h, ata66 = 0;
+	u8 mask = hwif->unit ? 0x20 : 0x10;
 	pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);
 
 	if (chipset_family >= ATA_66) {
diff -Nru a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
--- a/drivers/ide/sl82c105.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/ide/sl82c105.c	Sun Jun 16 19:31:40 2002
@@ -209,6 +209,7 @@
 static int sl82c105_dma_init(struct ata_device *drive, struct request *rq)
 {
 	sl82c105_reset_host(drive->channel->pci_dev);
+
 	return udma_pci_init(drive, rq);
 }
 
diff -Nru a/drivers/ide/tcq.c b/drivers/ide/tcq.c
--- a/drivers/ide/tcq.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/tcq.c	Sun Jun 16 19:31:41 2002
@@ -58,11 +58,18 @@
 static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq)
 {
 	struct ata_taskfile *args = rq->special;
+	unsigned long flags;
 
 	ide__sti();
+
+	spin_lock_irqsave(drive->channel->lock, flags);
+
 	blkdev_dequeue_request(rq);
 	drive->rq = NULL;
 	end_that_request_last(rq);
+
+	spin_unlock_irqrestore(drive->channel->lock, flags);
+
 	kfree(args);
 
 	return ide_stopped;
@@ -77,7 +84,7 @@
 {
 	struct ata_channel *ch = drive->channel;
 	request_queue_t *q = &drive->queue;
-	struct ata_taskfile *args;
+	struct ata_taskfile *ar;
 	struct request *rq;
 	unsigned long flags;
 
@@ -103,8 +110,8 @@
 	 * executed before any new commands are started. issue a NOP
 	 * to clear internal queue on drive.
 	 */
-	args = kmalloc(sizeof(*args), GFP_ATOMIC);
-	if (!args) {
+	ar = kmalloc(sizeof(*ar), GFP_ATOMIC);
+	if (!ar) {
 		printk(KERN_ERR "ATA: %s: failed to issue NOP\n", drive->name);
 		goto out;
 	}
@@ -119,10 +126,10 @@
 	 */
 	BUG_ON(!rq);
 
-	rq->special = args;
-	args->cmd = WIN_NOP;
-	args->handler = tcq_nop_handler;
-	args->command_type = IDE_DRIVE_TASK_NO_DATA;
+	rq->special = ar;
+	ar->cmd = WIN_NOP;
+	ar->XXX_handler = tcq_nop_handler;
+	ar->command_type = IDE_DRIVE_TASK_NO_DATA;
 
 	rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS);
 	_elv_add_request(q, rq, 0, 0);
@@ -218,6 +225,8 @@
  * and it must have reported a need for service (status has SERVICE_STAT set)
  *
  * Also, nIEN must be set as not to need protection against ide_dmaq_intr
+ *
+ * Channel lock should be held.
  */
 static ide_startstop_t service(struct ata_device *drive, struct request *rq)
 {
@@ -282,7 +291,7 @@
 
 	TCQ_PRINTK("%s: stat %x, feat %x\n", __FUNCTION__, stat, feat);
 
-	rq = blk_queue_tag_request(&drive->queue, tag);
+	rq = blk_queue_find_tag(&drive->queue, tag);
 	if (!rq) {
 		printk(KERN_ERR"%s: missing request for tag %d\n", __FUNCTION__, tag);
 		return ide_stopped;
@@ -318,6 +327,8 @@
 
 static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	u8 dma_stat;
 
 	/*
@@ -339,7 +350,14 @@
 		printk("%s: bad DMA status (dma_stat=%x)\n", drive->name, dma_stat);
 
 	TCQ_PRINTK("%s: ending %p, tag %d\n", __FUNCTION__, rq, rq->tag);
-	__ide_end_request(drive, rq, !dma_stat, rq->nr_sectors);
+
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
+	__ata_end_request(drive, rq, !dma_stat, rq->nr_sectors);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	/*
 	 * we completed this command, check if we can service a new command
@@ -412,7 +430,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = 0x01;
 	args.cmd = WIN_NOP;
-	ide_raw_taskfile(drive, &args);
+	ide_raw_taskfile(drive, &args, NULL);
 	if (args.taskfile.feature & ABRT_ERR)
 		return 1;
 
@@ -440,7 +458,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = SETFEATURES_EN_WCACHE;
 	args.cmd = WIN_SETFEATURES;
-	if (ide_raw_taskfile(drive, &args)) {
+	if (ide_raw_taskfile(drive, &args, NULL)) {
 		printk("%s: failed to enable write cache\n", drive->name);
 		return 1;
 	}
@@ -452,7 +470,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = SETFEATURES_DIS_RI;
 	args.cmd = WIN_SETFEATURES;
-	if (ide_raw_taskfile(drive, &args)) {
+	if (ide_raw_taskfile(drive, &args, NULL)) {
 		printk("%s: disabling release interrupt fail\n", drive->name);
 		return 1;
 	}
@@ -464,7 +482,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = SETFEATURES_EN_SI;
 	args.cmd = WIN_SETFEATURES;
-	if (ide_raw_taskfile(drive, &args)) {
+	if (ide_raw_taskfile(drive, &args, NULL)) {
 		printk("%s: enabling service interrupt fail\n", drive->name);
 		return 1;
 	}
@@ -503,6 +521,8 @@
 /*
  * Invoked from a SERVICE interrupt, command etc already known.  Just need to
  * start the dma engine for this tag.
+ *
+ * Channel lock should be held.
  */
 static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq)
 {
@@ -519,16 +539,17 @@
 		return ide_stopped;
 
 	set_irq(drive, ide_dmaq_intr);
-	if (!udma_start(drive, rq))
-		return ide_started;
+	udma_start(drive, rq);
 
-	return ide_stopped;
+	return ide_started;
 }
 
 /*
  * Start a queued command from scratch.
+ *
+ * Channel lock should be held.
  */
-ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
+ide_startstop_t udma_tcq_init(struct ata_device *drive, struct request *rq)
 {
 	u8 stat;
 	u8 feat;
diff -Nru a/drivers/ide/trm290.c b/drivers/ide/trm290.c
--- a/drivers/ide/trm290.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/ide/trm290.c	Sun Jun 16 19:31:39 2002
@@ -176,10 +176,9 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int trm290_udma_start(struct ata_device *drive, struct request *__rq)
+static void trm290_udma_start(struct ata_device *drive, struct request *__rq)
 {
 	/* Nothing to be done here. */
-	return 0;
 }
 
 static int trm290_udma_stop(struct ata_device *drive)
@@ -210,7 +209,7 @@
 #ifdef TRM290_NO_DMA_WRITES
 		trm290_prepare_drive(drive, 0);	/* select PIO xfer */
 
-		return 1;
+		return ide_stopped;
 #endif
 	} else {
 		reading = 2;
@@ -219,21 +218,21 @@
 
 	if (!(count = udma_new_table(drive, rq))) {
 		trm290_prepare_drive(drive, 0);	/* select PIO xfer */
-		return 1;	/* try PIO instead of DMA */
+		return ide_stopped;	/* try PIO instead of DMA */
 	}
 
 	trm290_prepare_drive(drive, 1);	/* select DMA xfer */
+
 	outl(ch->dmatable_dma|reading|writing, ch->dma_base);
 	drive->waiting_for_dma = 1;
 	outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
 
-	if (drive->type != ATA_DISK)
-		return 0;
-
-	ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
-	OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+	if (drive->type == ATA_DISK) {
+		ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
+		outb(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+	}
 
-	return 0;
+	return ide_started;
 }
 
 static int trm290_udma_irq_status(struct ata_device *drive)
diff -Nru a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
--- a/drivers/ide/via82cxxx.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/ide/via82cxxx.c	Sun Jun 16 19:31:41 2002
@@ -199,8 +199,6 @@
 
 	via_set_speed(drive->channel->pci_dev, drive->dn, &t);
 
-	drive->current_speed = speed;
-
 	return 0;
 }
 
diff -Nru a/drivers/input/Makefile b/drivers/input/Makefile
--- a/drivers/input/Makefile	Sun Jun 16 19:31:41 2002
+++ b/drivers/input/Makefile	Sun Jun 16 19:31:41 2002
@@ -4,7 +4,6 @@
 
 # Objects that export symbols.
 
-mod-subdirs	:= joystick
 export-objs	:= input.o
 
 # Each configuration option enables a list of files.
diff -Nru a/drivers/isdn/Makefile b/drivers/isdn/Makefile
--- a/drivers/isdn/Makefile	Sun Jun 16 19:31:41 2002
+++ b/drivers/isdn/Makefile	Sun Jun 16 19:31:41 2002
@@ -2,8 +2,6 @@
 
 # Object files in subdirectories
 
-mod-subdirs				:= i4l hisax capi eicon
-
 obj-$(CONFIG_ISDN)			+= i4l/
 obj-$(CONFIG_ISDN_CAPI)			+= capi/
 obj-$(CONFIG_ISDN_CAPI)			+= hardware/
diff -Nru a/drivers/isdn/eicon/pc.h b/drivers/isdn/eicon/pc.h
--- a/drivers/isdn/eicon/pc.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/isdn/eicon/pc.h	Sun Jun 16 19:31:40 2002
@@ -11,11 +11,6 @@
 #ifndef PC_H_INCLUDED
 #define PC_H_INCLUDED
 
-
-#define byte unsigned char
-#define word unsigned short
-#define dword unsigned long
-
 /*------------------------------------------------------------------*/
 /* buffer definition                                                */
 /*------------------------------------------------------------------*/
diff -Nru a/drivers/isdn/hardware/Makefile b/drivers/isdn/hardware/Makefile
--- a/drivers/isdn/hardware/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/isdn/hardware/Makefile	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,6 @@
 
 # Object files in subdirectories
 
-mod-subdirs			:= avm
 obj-$(CONFIG_CAPI_AVM)		+= avm/
 
 # The global Rules.make.
diff -Nru a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
--- a/drivers/isdn/hardware/avm/avm_cs.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/isdn/hardware/avm/avm_cs.c	Sun Jun 16 19:31:39 2002
@@ -148,7 +148,7 @@
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
     if (!link)
-	return NULL;
+        goto err;
     memset(link, 0, sizeof(struct dev_link_t));
     link->release.function = &avmcs_release;
     link->release.data = (u_long)link;
@@ -181,7 +181,7 @@
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local)
-	return NULL;
+        goto err_kfree;
     memset(local, 0, sizeof(local_info_t));
     link->priv = local;
     
@@ -201,10 +201,14 @@
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
 	avmcs_detach(link);
-	return NULL;
+	goto err;
     }
-
     return link;
+
+ err_kfree:
+    kfree(link);
+ err:
+    return NULL;
 } /* avmcs_attach */
 
 /*======================================================================
diff -Nru a/drivers/isdn/hisax/Config.in b/drivers/isdn/hisax/Config.in
--- a/drivers/isdn/hisax/Config.in	Sun Jun 16 19:31:39 2002
+++ b/drivers/isdn/hisax/Config.in	Sun Jun 16 19:31:39 2002
@@ -50,12 +50,12 @@
    fi
    bool '  HiSax debugging' CONFIG_HISAX_DEBUG
 
-   dep_tristate 'Sedlbauer PCMCIA cards'                              CONFIG_HISAX_SEDLBAUER_CS  $CONFIG_DRV_ISDN_HISAX $CONFIG_PCMCIA
-   dep_tristate 'ELSA PCMCIA MicroLink cards'                         CONFIG_HISAX_ELSA_CS       $CONFIG_DRV_ISDN_HISAX $CONFIG_PCMCIA
-   dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)'                CONFIG_HISAX_ST5481        $CONFIG_DRV_ISDN_HISAX $CONFIG_USB $CONFIG_EXPERIMENTAL
-   dep_tristate 'AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP  $CONFIG_DRV_ISDN_HISAX $CONFIG_EXPERIMENTAL
-   dep_tristate 'AVM Fritz!Card classic support (EXPERIMENTAL)'       CONFIG_HISAX_FRITZ_CLASSIC $CONFIG_DRV_ISDN_HISAX  $CONFIG_EXPERIMENTAL
-   dep_tristate 'HFC PCI support (EXPERIMENTAL)'                      CONFIG_HISAX_HFCPCI        $CONFIG_DRV_ISDN_HISAX $CONFIG_EXPERIMENTAL
+   dep_tristate 'Sedlbauer PCMCIA cards'                              CONFIG_HISAX_SEDLBAUER_CS  $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA
+   dep_tristate 'ELSA PCMCIA MicroLink cards'                         CONFIG_HISAX_ELSA_CS       $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA
+   dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)'                CONFIG_HISAX_ST5481        $CONFIG_ISDN_DRV_HISAX $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate 'AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP  $CONFIG_ISDN_DRV_HISAX $CONFIG_EXPERIMENTAL
+   dep_tristate 'AVM Fritz!Card classic support (EXPERIMENTAL)'       CONFIG_HISAX_FRITZ_CLASSIC $CONFIG_ISDN_DRV_HISAX  $CONFIG_EXPERIMENTAL
+   dep_tristate 'HFC PCI support (EXPERIMENTAL)'                      CONFIG_HISAX_HFCPCI        $CONFIG_ISDN_DRV_HISAX $CONFIG_EXPERIMENTAL
 fi
 endmenu
 
diff -Nru a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
--- a/drivers/isdn/hisax/amd7930_fn.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/isdn/hisax/amd7930_fn.c	Sun Jun 16 19:31:40 2002
@@ -63,19 +63,42 @@
 
 static void Amd7930_new_ph(struct IsdnCardState *cs);
 
+static inline u8
+HIBYTE(u16 w)
+{
+	return (w >> 8) & 0xff;
+}
+
+static inline u8
+LOBYTE(u16 w)
+{
+	return w & 0xff;
+}
 
-void /* macro wWordAMD */
-WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
+static inline u8
+rByteAMD(struct IsdnCardState *cs, u8 reg)
+{
+	return cs->readisac(cs, reg);
+}
+
+static inline void
+wByteAMD(struct IsdnCardState *cs, u8 reg, u8 val)
+{
+	cs->writeisac(cs, reg, val);
+}
+
+static void
+wWordAMD(struct IsdnCardState *cs, u8 reg, u16 val)
 {
         wByteAMD(cs, 0x00, reg);
         wByteAMD(cs, 0x01, LOBYTE(val));
         wByteAMD(cs, 0x01, HIBYTE(val));
 }
 
-WORD /* macro rWordAMD */
-ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg)
+static u16
+rWordAMD(struct IsdnCardState *cs, u8 reg)
 {
-        WORD res;
+        u16 res;
         /* direct access register */
         if(reg < 8) {
         	res = rByteAMD(cs, reg);
@@ -90,6 +113,17 @@
 	return (res);
 }
 
+static inline void
+AmdIrqOff(struct IsdnCardState *cs)
+{
+	cs->dc.amd7930.setIrqMask(cs, 0);
+}
+
+static inline void
+AmdIrqOn(struct IsdnCardState *cs)
+{
+	cs->dc.amd7930.setIrqMask(cs, 1);
+}
 
 static void
 Amd7930_ph_command(struct IsdnCardState *cs, u_char command, char *s)
@@ -103,7 +137,7 @@
 
 
 
-static BYTE i430States[] = {
+static u8 i430States[] = {
 // to   reset  F3    F4    F5    F6    F7    F8    AR     from
         0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // init
         0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // reset
@@ -117,14 +151,14 @@
 
 
 /*                    Row     init    -   reset  F3    F4    F5    F6    F7    F8    AR */
-static BYTE stateHelper[] = { 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
+static u8 stateHelper[] = { 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
 
 
 
 
 static void
 Amd7930_get_state(struct IsdnCardState *cs) {
-        BYTE lsr = rByteAMD(cs, 0xA1);
+        u8 lsr = rByteAMD(cs, 0xA1);
         cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
         Amd7930_new_ph(cs);
 }
@@ -252,8 +286,8 @@
 Amd7930_empty_Dfifo(struct IsdnCardState *cs, int flag)
 {
 
-        BYTE stat, der;
-	BYTE *ptr;
+        u8 stat, der;
+	u8 *ptr;
 	struct sk_buff *skb;
 
 
@@ -326,9 +360,9 @@
 Amd7930_fill_Dfifo(struct IsdnCardState *cs)
 {
 
-        WORD dtcrr, dtcrw, len, count;
-        BYTE txstat, dmr3;
-        BYTE *ptr, *deb_ptr;
+        u16 dtcrr, dtcrw, len, count;
+        u8 txstat, dmr3;
+        u8 *ptr, *deb_ptr;
 
 	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
 		debugl1(cs, "Amd7930: fill_Dfifo");
@@ -394,10 +428,10 @@
 }
 
 
-void Amd7930_interrupt(struct IsdnCardState *cs, BYTE irflags)
+void Amd7930_interrupt(struct IsdnCardState *cs, u8 irflags)
 {
-	BYTE dsr1, dsr2, lsr;
-        WORD der;
+	u8 dsr1, dsr2, lsr;
+        u16 der;
 
  while (irflags)
  {
@@ -661,8 +695,8 @@
 dbusy_timer_handler(struct IsdnCardState *cs)
 {
 	struct PStack *stptr;
-        WORD dtcr, der;
-        BYTE dsr1, dsr2;
+        u16 dtcr, der;
+        u8 dsr1, dsr2;
 
 
         if (cs->debug & L1_DEB_ISAC)
@@ -711,13 +745,45 @@
 	}
 }
 
+static u16 initAMD[] = {
+	0x0100,
+
+	0x00A5, 3, 0x01, 0x40, 0x58,				// LPR, LMR1, LMR2
+	0x0086, 1, 0x0B,					// DMR1 (D-Buffer TH-Interrupts on)
+	0x0087, 1, 0xFF,					// DMR2
+	0x0092, 1, 0x03,					// EFCR (extended mode d-channel-fifo on)
+	0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F,			// FRAR4, SRAR4, DMR3, DMR4 (address recognition )
+	0x0084, 2, 0x80, 0x00,					// DRLR
+	0x00C0, 1, 0x47,					// PPCR1
+	0x00C8, 1, 0x01,					// PPCR2
+
+	0x0102,
+	0x0107,
+	0x01A1, 1,
+	0x0121, 1,
+	0x0189, 2,
+
+	0x0045, 4, 0x61, 0x72, 0x00, 0x00,			// MCR1, MCR2, MCR3, MCR4
+	0x0063, 2, 0x08, 0x08,					// GX
+	0x0064, 2, 0x08, 0x08,					// GR
+	0x0065, 2, 0x99, 0x00,					// GER
+	0x0066, 2, 0x7C, 0x8B,					// STG
+	0x0067, 2, 0x00, 0x00,					// FTGR1, FTGR2
+	0x0068, 2, 0x20, 0x20,					// ATGR1, ATGR2
+	0x0069, 1, 0x4F,					// MMR1
+	0x006A, 1, 0x00,					// MMR2
+	0x006C, 1, 0x40,					// MMR3
+	0x0021, 1, 0x02,					// INIT
+	0x00A3, 1, 0x40,					// LMR1
+
+	0xFFFF};
 
 
 void __devinit
 Amd7930_init(struct IsdnCardState *cs)
 {
-    WORD *ptr;
-    BYTE cmd, cnt;
+    u16 *ptr;
+    u8 cmd, cnt;
 
         if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "Amd7930: initamd called");
diff -Nru a/drivers/isdn/hisax/amd7930_fn.h b/drivers/isdn/hisax/amd7930_fn.h
--- a/drivers/isdn/hisax/amd7930_fn.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/isdn/hisax/amd7930_fn.h	Sun Jun 16 19:31:40 2002
@@ -12,58 +12,11 @@
  */
 
 
-
-
-#define BYTE							unsigned char
-#define WORD							unsigned int
-#define rByteAMD(cs, reg)					cs->readisac(cs, reg)
-#define wByteAMD(cs, reg, val)					cs->writeisac(cs, reg, val)
-#define rWordAMD(cs, reg)					ReadWordAmd7930(cs, reg)
-#define wWordAMD(cs, reg, val)					WriteWordAmd7930(cs, reg, val)
-#define HIBYTE(w)						((unsigned char)((w & 0xff00) / 256))
-#define LOBYTE(w)						((unsigned char)(w & 0x00ff))
-
-#define AmdIrqOff(cs)						cs->dc.amd7930.setIrqMask(cs, 0)
-#define AmdIrqOn(cs)						cs->dc.amd7930.setIrqMask(cs, 1)
-
 #define AMD_CR		0x00
 #define AMD_DR		0x01
 
 
 #define DBUSY_TIMER_VALUE 80
-
-static WORD initAMD[] = {
-	0x0100,
-
-	0x00A5, 3, 0x01, 0x40, 0x58,				// LPR, LMR1, LMR2
-	0x0086, 1, 0x0B,					// DMR1 (D-Buffer TH-Interrupts on)
-	0x0087, 1, 0xFF,					// DMR2
-	0x0092, 1, 0x03,					// EFCR (extended mode d-channel-fifo on)
-	0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F,			// FRAR4, SRAR4, DMR3, DMR4 (address recognition )
-	0x0084, 2, 0x80, 0x00,					// DRLR
-	0x00C0, 1, 0x47,					// PPCR1
-	0x00C8, 1, 0x01,					// PPCR2
-
-	0x0102,
-	0x0107,
-	0x01A1, 1,
-	0x0121, 1,
-	0x0189, 2,
-
-	0x0045, 4, 0x61, 0x72, 0x00, 0x00,			// MCR1, MCR2, MCR3, MCR4
-	0x0063, 2, 0x08, 0x08,					// GX
-	0x0064, 2, 0x08, 0x08,					// GR
-	0x0065, 2, 0x99, 0x00,					// GER
-	0x0066, 2, 0x7C, 0x8B,					// STG
-	0x0067, 2, 0x00, 0x00,					// FTGR1, FTGR2
-	0x0068, 2, 0x20, 0x20,					// ATGR1, ATGR2
-	0x0069, 1, 0x4F,					// MMR1
-	0x006A, 1, 0x00,					// MMR2
-	0x006C, 1, 0x40,					// MMR3
-	0x0021, 1, 0x02,					// INIT
-	0x00A3, 1, 0x40,					// LMR1
-
-	0xFFFF};
 
 extern void Amd7930_interrupt(struct IsdnCardState *cs, unsigned char irflags);
 extern void Amd7930_init(struct IsdnCardState *cs);
diff -Nru a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
--- a/drivers/isdn/icn/icn.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/isdn/icn/icn.c	Sun Jun 16 19:31:40 2002
@@ -819,34 +819,34 @@
 #endif
 	if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
 		printk(KERN_WARNING "icn: Could not allocate code buffer\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out;
 	}
 	if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) {
-		kfree(codebuf);
-		return -EFAULT;
+		ret = -EFAULT;
+		goto out_kfree;
 	}
 	if (!card->rvalid) {
-		if (check_region(card->port, ICN_PORTLEN)) {
+		if (!request_region(card->port, ICN_PORTLEN, card->regname)) {
 			printk(KERN_WARNING
 			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
 			       CID,
 			       card->port,
 			       card->port + ICN_PORTLEN);
-			kfree(codebuf);
-			return -EBUSY;
+			ret = -EBUSY;
+			goto out_kfree;
 		}
-		request_region(card->port, ICN_PORTLEN, card->regname);
 		card->rvalid = 1;
 		if (card->doubleS0)
 			card->other->rvalid = 1;
 	}
 	if (!dev.mvalid) {
-		if (check_mem_region(dev.memaddr, 0x4000)) {
+		if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) {
 			printk(KERN_WARNING
 			       "icn: memory at 0x%08lx in use.\n", dev.memaddr);
-			return -EBUSY;
+			ret = -EBUSY;
+			goto out_kfree;
 		}
-		request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)");
 		dev.shmem = ioremap(dev.memaddr, 0x4000);
 		dev.mvalid = 1;
 	}
@@ -888,13 +888,15 @@
 		printk(KERN_DEBUG "Bootloader transferred\n");
 #endif
 	}
-	kfree(codebuf);
 	SLEEP(1);
 	OUTB_P(0xff, ICN_RUN);  /* Start Boot-Code */
-	if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1)))
-		return ret;
-	if (!card->doubleS0)
-		return 0;
+	if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) {
+		goto out_kfree;
+	}
+	if (!card->doubleS0) {
+		ret = 0;
+		goto out_kfree;
+	}
 	/* reached only, if we have a Double-S0-Card */
 #ifdef BOOT_DEBUG
 	printk(KERN_DEBUG "Map Bank 0\n");
@@ -905,7 +907,12 @@
 	icn_lock_channel(card, 0);	/* Lock Bank 0     */
 	restore_flags(flags);
 	SLEEP(1);
-	return (icn_check_loader(1));
+	ret = (icn_check_loader(1));
+
+ out_kfree:
+	kfree(codebuf);
+ out:
+	return ret;
 }
 
 static int
diff -Nru a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
--- a/drivers/isdn/sc/init.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/isdn/sc/init.c	Sun Jun 16 19:31:39 2002
@@ -261,39 +261,6 @@
 		}
 
 		pr_debug("current IRQ: %d  b: %d\n",irq[b],b);
-		/*
-		 * See if we should probe for an irq
-		 */
-		if(irq[b]) {
-			/*
-			 * No we were given one
-			 * See that it is supported and free
-			 */
-			pr_debug("Trying for IRQ: %d\n",irq[b]);
-			if (irq_supported(irq[b])) {
-				if(REQUEST_IRQ(irq[b], interrupt_handler, 
-					SA_PROBE, "sc_probe", NULL)) {
-					pr_debug("IRQ %d is already in use\n", 
-						irq[b]);
-					continue;
-				}
-				FREE_IRQ(irq[b], NULL);
-			}
-		}
-		else {
-			/*
-			 * Yes, we need to probe for an IRQ
-			 */
-			pr_debug("Probing for IRQ...\n");
-			for (i = 0; i < MAX_IRQS ; i++) {
-				if(!REQUEST_IRQ(sup_irq[i], interrupt_handler, SA_PROBE, "sc_probe", NULL)) {
-					pr_debug("Probed for and found IRQ %d\n", sup_irq[i]);
-					FREE_IRQ(sup_irq[i], NULL);
-					irq[b] = sup_irq[i];
-					break;
-				}
-			}
-		}
 
 		/*
 		 * Make sure we got an IRQ
@@ -379,8 +346,16 @@
 		 * Lock down the hardware resources
 		 */
 		adapter[cinst]->interrupt = irq[b];
-		REQUEST_IRQ(adapter[cinst]->interrupt, interrupt_handler, SA_INTERRUPT, 
-			interface->id, NULL);
+		if (request_irq(adapter[cinst]->interrupt, interrupt_handler, SA_INTERRUPT, 
+			interface->id, NULL))
+		{
+			kfree(adapter[cinst]->channel);
+			indicate_status(cinst, ISDN_STAT_UNLOAD, 0, NULL);	/* Fix me */
+			kfree(interface);
+			kfree(adapter[cinst]);
+			continue;
+			
+		}
 		adapter[cinst]->iobase = io[b];
 		for(i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
 			adapter[cinst]->ioport[i] = io[b] + i * 0x400;
diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c
--- a/drivers/md/linear.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/md/linear.c	Sun Jun 16 19:31:40 2002
@@ -26,6 +26,7 @@
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
 #define MD_PERSONALITY
+#define DEVICE_NR(device) (minor(device))
 
 static int linear_run (mddev_t *mddev)
 {
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/md/md.c	Sun Jun 16 19:31:40 2002
@@ -49,6 +49,7 @@
 
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
+#define DEVICE_NR(device) (minor(device))
 
 #include <linux/blk.h>
 
diff -Nru a/drivers/md/multipath.c b/drivers/md/multipath.c
--- a/drivers/md/multipath.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/md/multipath.c	Sun Jun 16 19:31:40 2002
@@ -23,11 +23,13 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/raid/multipath.h>
+#include <linux/buffer_head.h>
 #include <asm/atomic.h>
 
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
 #define MD_PERSONALITY
+#define DEVICE_NR(device) (minor(device))
 
 #define MAX_WORK_PER_DISK 128
 
diff -Nru a/drivers/md/raid0.c b/drivers/md/raid0.c
--- a/drivers/md/raid0.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/md/raid0.c	Sun Jun 16 19:31:40 2002
@@ -24,6 +24,7 @@
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
 #define MD_PERSONALITY
+#define DEVICE_NR(device) (minor(device))
 
 static int create_strip_zones (mddev_t *mddev)
 {
diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c
--- a/drivers/md/raid1.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/md/raid1.c	Sun Jun 16 19:31:39 2002
@@ -27,6 +27,7 @@
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
 #define MD_PERSONALITY
+#define DEVICE_NR(device) (minor(device))
 
 /*
  * Number of guaranteed r1bios in case of extreme VM load:
diff -Nru a/drivers/media/Makefile b/drivers/media/Makefile
--- a/drivers/media/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/media/Makefile	Sun Jun 16 19:31:40 2002
@@ -2,8 +2,6 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-mod-subdirs  := video radio
-
 obj-y        := video/ radio/
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/media/radio/Config.in b/drivers/media/radio/Config.in
--- a/drivers/media/radio/Config.in	Sun Jun 16 19:31:40 2002
+++ b/drivers/media/radio/Config.in	Sun Jun 16 19:31:40 2002
@@ -4,6 +4,7 @@
 mainmenu_option next_comment
 comment 'Radio Adapters'
 
+if [ "$CONFIG_ISA" = "y" ]; then
 dep_tristate '  ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV
 dep_tristate '  AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV
 if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then
@@ -21,9 +22,11 @@
 if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
    hex '    GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c
 fi
+fi
 dep_tristate '  GemTek PCI Radio Card support' CONFIG_RADIO_GEMTEK_PCI $CONFIG_VIDEO_DEV $CONFIG_PCI
 dep_tristate '  Guillemot MAXI Radio FM 2000 radio' CONFIG_RADIO_MAXIRADIO $CONFIG_VIDEO_DEV
 dep_tristate '  Maestro on board radio' CONFIG_RADIO_MAESTRO $CONFIG_VIDEO_DEV
+if [ "$CONFIG_ISA" = "y" ]; then
 dep_tristate '  miroSOUND PCM20 radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV $CONFIG_SOUND_ACI_MIXER
 dep_tristate '    miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)' CONFIG_RADIO_MIROPCM20_RDS $CONFIG_RADIO_MIROPCM20 $CONFIG_EXPERIMENTAL
 dep_tristate '  SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV
@@ -48,6 +51,7 @@
 dep_tristate '  Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV
 if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then
    hex '    ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
+fi
 fi
 
 endmenu
diff -Nru a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
--- a/drivers/media/video/tda9875.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/media/video/tda9875.c	Sun Jun 16 19:31:40 2002
@@ -28,6 +28,7 @@
 #include <linux/videodev.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
 
 #include "bttv.h"
 #include "audiochip.h"
diff -Nru a/drivers/message/Makefile b/drivers/message/Makefile
--- a/drivers/message/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/message/Makefile	Sun Jun 16 19:31:40 2002
@@ -2,8 +2,6 @@
 # Makefile for MPT based block devices
 #
 
-mod-subdirs := i2o fusion 
-
 obj-$(CONFIG_I2O)	+= i2o/
 obj-$(CONFIG_FUSION)	+= fusion/
 
diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/message/i2o/i2o_block.c	Sun Jun 16 19:31:41 2002
@@ -72,6 +72,7 @@
 #include <linux/wait.h>
 
 #define MAJOR_NR I2O_MAJOR
+#define DEVICE_NR(device) (minor(device)>>4)
 
 #include <linux/blk.h>
 
diff -Nru a/drivers/mtd/Makefile b/drivers/mtd/Makefile
--- a/drivers/mtd/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/mtd/Makefile	Sun Jun 16 19:31:40 2002
@@ -4,9 +4,6 @@
 #
 # $Id: Makefile,v 1.63 2001/06/13 09:43:07 dwmw2 Exp $
 
-
-mod-subdirs	:= chips maps devices nand
-
 export-objs	:= mtdcore.o mtdpart.o redboot.o bootldr.o afs.o
 
 obj-y           += chips/ maps/	devices/ nand/
diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/mtd/ftl.c	Sun Jun 16 19:31:40 2002
@@ -94,7 +94,6 @@
 
 /* Funky stuff for setting up a block device */
 #define MAJOR_NR		FTL_MAJOR
-#define DEVICE_NAME		"ftl"
 #define DEVICE_OFF(device)
 
 #define DEVICE_NR(minor)	((minor)>>5)
@@ -1192,10 +1191,8 @@
 
     do {
 	//	    sti();
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
 	minor = minor(CURRENT->rq_dev);
 
@@ -1231,7 +1228,7 @@
 	  CURRENT->sector += CURRENT->current_nr_sectors;
 	}
 	
-	end_request((ret == 0) ? 1 : 0);
+	end_request(CURRENT, (ret == 0) ? 1 : 0);
     } while (1);
 } /* do_ftl_request */
 
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/mtd/mtdblock.c	Sun Jun 16 19:31:40 2002
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/buffer_head.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/compatmac.h>
 
@@ -396,10 +397,8 @@
 	unsigned int res;
 
 	for (;;) {
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		if (blk_queue_empty(QUEUE))
 			return;
-		}
 
 		req = CURRENT;
 		spin_unlock_irq(QUEUE->queue_lock);
diff -Nru a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
--- a/drivers/mtd/mtdblock_ro.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/mtd/mtdblock_ro.c	Sun Jun 16 19:31:40 2002
@@ -114,10 +114,8 @@
    {
       /* Grab the Request and unlink it from the request list, we
 	 will execute a return if we are done. */
-	if (blk_queue_empty(QUEUE)) {
-		CLEAR_INTR;
+	if (blk_queue_empty(QUEUE))
 		return;
-	}
 
       current_request = CURRENT;
 
diff -Nru a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
--- a/drivers/mtd/nftlcore.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/mtd/nftlcore.c	Sun Jun 16 19:31:39 2002
@@ -837,10 +837,8 @@
 	int res;
 
 	while (1) {
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		if (blk_queue_empty(QUEUE))
 			return;
-		}
 
 		req = CURRENT;
 		
@@ -928,7 +926,7 @@
 	repeat: 
 		DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
 		spin_lock_irq(QUEUE->queue_lock);
-		end_request(res);
+		end_request(CURRENT, res);
 	}
 }
 
diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/8139cp.c	Sun Jun 16 19:31:40 2002
@@ -32,7 +32,7 @@
 	  h/w stats can be reset only by software reset
 	* Tx checksumming
 	* Handle netif_rx return value
-	* ETHTOOL_GREGS, ETHTOOL_[GS]WOL,
+	* ETHTOOL_[GS]WOL,
 	* Investigate using skb->priority with h/w VLAN priority
 	* Investigate using High Priority Tx Queue with skb->priority
 	* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
@@ -41,12 +41,14 @@
 	  Tx descriptor bit
 	* The real minimum of CP_MIN_MTU is 4 bytes.  However,
 	  for this to be supported, one must(?) turn on packet padding.
+	* Support 8169 GMII
+	* Support external MII transceivers
 
  */
 
 #define DRV_NAME		"8139cp"
-#define DRV_VERSION		"0.0.7"
-#define DRV_RELDATE		"Feb 27, 2002"
+#define DRV_VERSION		"0.1.0"
+#define DRV_RELDATE		"Jun 14, 2002"
 
 
 #include <linux/config.h>
@@ -99,6 +101,7 @@
 				 NETIF_MSG_PROBE 	| \
 				 NETIF_MSG_LINK)
 #define CP_REGS_SIZE		(0xff + 1)
+#define CP_REGS_VER		1		/* version 1 */
 #define CP_RX_RING_SIZE		64
 #define CP_TX_RING_SIZE		64
 #define CP_RING_BYTES		\
@@ -152,7 +155,9 @@
 	NWayExpansion	= 0x6A, /* MII Expansion */
 	Config5		= 0xD8,	/* Config5 */
 	TxPoll		= 0xD9,	/* Tell chip to check Tx descriptors for work */
+	RxMaxSize	= 0xDA, /* Max size of an Rx packet (8169 only) */
 	CpCmd		= 0xE0, /* C+ Command register (C+ mode only) */
+	IntrMitigate	= 0xE2,	/* rx/tx interrupt mitigation control */
 	RxRingAddr	= 0xE4, /* 64-bit start addr of Rx ring */
 	TxThresh	= 0xEC, /* Early Tx threshold */
 	OldRxBufAddr	= 0x30, /* DMA address of Rx ring buffer (C mode) */
@@ -313,6 +318,7 @@
 
 	struct sk_buff		*frag_skb;
 	unsigned		dropping_frag : 1;
+	unsigned int		board_type;
 
 	struct mii_if_info	mii_if;
 };
@@ -341,10 +347,28 @@
 static void cp_tx (struct cp_private *cp);
 static void cp_clean_rings (struct cp_private *cp);
 
+enum board_type {
+	RTL8139Cp,
+	RTL8169,
+};
+
+static struct cp_board_info {
+	const char *name;
+} cp_board_tbl[] __devinitdata = {
+	/* RTL8139Cp */
+	{ "RTL-8139C+" },
+
+	/* RTL8169 */
+	{ "RTL-8169" },
+};
 
 static struct pci_device_id cp_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139Cp },
+#if 0
+	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8169,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8169 },
+#endif
 	{ },
 };
 MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
@@ -890,7 +914,10 @@
 static inline void cp_start_hw (struct cp_private *cp)
 {
 	cpw8(Cmd, RxOn | TxOn);
-	cpw16(CpCmd, PCIMulRW | RxChkSum | CpRxOn | CpTxOn);
+	if (cp->board_type == RTL8169)
+		cpw16(CpCmd, PCIMulRW | RxChkSum);
+	else
+		cpw16(CpCmd, PCIMulRW | RxChkSum | CpRxOn | CpTxOn);
 }
 
 static void cp_init_hw (struct cp_private *cp)
@@ -912,16 +939,14 @@
 	cpw32_f (TxConfig, IFG | (TX_DMA_BURST << TxDMAShift));
 
 	cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable);
-	cpw8(Config3, PARMEnable); /* disables magic packet and WOL */
+	if (cp->board_type == RTL8139Cp)
+		cpw8(Config3, PARMEnable); /* disables magic packet and WOL */
 	cpw8(Config5, cpr8(Config5) & PMEStatus); /* disables more WOL stuff */
+	if (cp->board_type == RTL8169)
+		cpw16(RxMaxSize, cp->rx_buf_sz);
 
 	cpw32_f(HiTxRingAddr, 0);
 	cpw32_f(HiTxRingAddr + 4, 0);
-	cpw32_f(OldRxBufAddr, 0);
-	cpw32_f(OldTSD0, 0);
-	cpw32_f(OldTSD0 + 4, 0);
-	cpw32_f(OldTSD0 + 8, 0);
-	cpw32_f(OldTSD0 + 12, 0);
 
 	cpw32_f(RxRingAddr, cp->ring_dma);
 	cpw32_f(RxRingAddr + 4, 0);
@@ -930,9 +955,9 @@
 
 	cpw16(MultiIntr, 0);
 
-	cpw16(IntrMask, cp_intr_mask);
+	cpw16_f(IntrMask, cp_intr_mask);
 
-	cpw8_f (Cfg9346, Cfg9346_Lock);
+	cpw8_f(Cfg9346, Cfg9346_Lock);
 }
 
 static int cp_refill_rx (struct cp_private *cp)
@@ -1094,6 +1119,8 @@
 
 	dev->mtu = new_mtu;
 	cp_set_rxbufsize(cp);		/* set new rx buf size */
+	if (cp->board_type == RTL8169)
+		cpw16(RxMaxSize, cp->rx_buf_sz);
 
 	rc = cp_init_rings(cp);		/* realloc and restart h/w */
 	cp_start_hw(cp);
@@ -1153,6 +1180,7 @@
 		strcpy (info.driver, DRV_NAME);
 		strcpy (info.version, DRV_VERSION);
 		strcpy (info.bus_info, cp->pdev->slot_name);
+		info.regdump_len = CP_REGS_SIZE;
 		if (copy_to_user (useraddr, &info, sizeof (info)))
 			return -EFAULT;
 		return 0;
@@ -1209,6 +1237,128 @@
 		return 0;
 	}
 
+	/* NIC register dump */
+	case ETHTOOL_GREGS: {
+                struct ethtool_regs regs;
+                u8 *regbuf = kmalloc(CP_REGS_SIZE, GFP_KERNEL);
+                int rc;
+
+		if (!regbuf)
+			return -ENOMEM;
+		memset(regbuf, 0, CP_REGS_SIZE);
+
+                rc = copy_from_user(&regs, useraddr, sizeof(regs));
+		if (rc) {
+			rc = -EFAULT;
+			goto err_out_gregs;
+		}
+                
+                if (regs.len > CP_REGS_SIZE)
+                        regs.len = CP_REGS_SIZE;
+                if (regs.len < CP_REGS_SIZE) {
+			rc = -EINVAL;
+			goto err_out_gregs;
+		}
+
+                regs.version = CP_REGS_VER;
+                rc = copy_to_user(useraddr, &regs, sizeof(regs));
+		if (rc) {
+			rc = -EFAULT;
+			goto err_out_gregs;
+		}
+
+                useraddr += offsetof(struct ethtool_regs, data);
+
+                spin_lock_irq(&cp->lock);
+                memcpy_fromio(regbuf, cp->regs, CP_REGS_SIZE);
+                spin_unlock_irq(&cp->lock);
+
+                if (copy_to_user(useraddr, regbuf, regs.len))
+                        rc = -EFAULT;
+
+err_out_gregs:
+		kfree(regbuf);
+		return rc;
+	}
+
+	/* get/set RX checksumming */
+	case ETHTOOL_GRXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GRXCSUM };
+		u16 cmd = cpr16(CpCmd) & RxChkSum;
+
+		edata.data = cmd ? 1 : 0;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SRXCSUM: {
+		struct ethtool_value edata;
+		u16 cmd = cpr16(CpCmd), newcmd;
+
+		newcmd = cmd;
+
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+
+		if (edata.data)
+			newcmd |= RxChkSum;
+		else
+			newcmd &= ~RxChkSum;
+
+		if (newcmd == cmd)
+			return 0;
+
+		spin_lock_irq(&cp->lock);
+		cpw16_f(CpCmd, newcmd);
+		spin_unlock_irq(&cp->lock);
+	}
+
+	/* get/set TX checksumming */
+	case ETHTOOL_GTXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GTXCSUM };
+
+		edata.data = (cp->dev->features & NETIF_F_IP_CSUM) != 0;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_STXCSUM: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+
+		if (edata.data)
+			cp->dev->features |= NETIF_F_IP_CSUM;
+		else
+			cp->dev->features &= ~NETIF_F_IP_CSUM;
+
+		return 0;
+	}
+
+	/* get/set scatter-gather */
+	case ETHTOOL_GSG: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+
+		edata.data = (cp->dev->features & NETIF_F_SG) != 0;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SSG: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+
+		if (edata.data)
+			cp->dev->features |= NETIF_F_SG;
+		else
+			cp->dev->features &= ~NETIF_F_SG;
+
+		return 0;
+	}
+
 	default:
 		break;
 	}
@@ -1332,6 +1482,7 @@
 	unsigned addr_len, i;
 	u8 pci_rev, cache_size;
 	u16 pci_command;
+	unsigned int board_type = (unsigned int) ent->driver_data;
 
 #ifndef MODULE
 	static int version_printed;
@@ -1355,6 +1506,7 @@
 	SET_MODULE_OWNER(dev);
 	cp = dev->priv;
 	cp->pdev = pdev;
+	cp->board_type = board_type;
 	cp->dev = dev;
 	cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
 	spin_lock_init (&cp->lock);
@@ -1440,7 +1592,7 @@
 		"%02x:%02x:%02x:%02x:%02x:%02x, "
 		"IRQ %d\n",
 		dev->name,
-		"RTL-8139C+",
+		cp_board_tbl[board_type].name,
 		dev->base_addr,
 		dev->dev_addr[0], dev->dev_addr[1],
 		dev->dev_addr[2], dev->dev_addr[3],
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/Makefile	Sun Jun 16 19:31:40 2002
@@ -2,9 +2,6 @@
 # Makefile for the Linux network (ethercard) device drivers.
 #
 
-mod-subdirs     := appletalk arcnet fc irda tokenring tulip pcmcia wireless \
-		   wan ../acorn/net
-
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
diff -Nru a/drivers/net/atarilance.c b/drivers/net/atarilance.c
--- a/drivers/net/atarilance.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/atarilance.c	Sun Jun 16 19:31:39 2002
@@ -546,8 +546,11 @@
 	if (lp->cardtype == PAM_CARD ||
 		memaddr == (unsigned short *)0xffe00000) {
 		/* PAMs card and Riebl on ST use level 5 autovector */
-		request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
-		            "PAM/Riebl-ST Ethernet", dev);
+		if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
+		            "PAM/Riebl-ST Ethernet", dev)) { 
+			printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
+			return( 0 );
+		}
 		dev->irq = (unsigned short)IRQ_AUTO_5;
 	}
 	else {
@@ -560,8 +563,11 @@
 			printk( "Lance: request for VME interrupt failed\n" );
 			return( 0 );
 		}
-		request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
-		            "Riebl-VME Ethernet", dev);
+		if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
+		            "Riebl-VME Ethernet", dev)) {
+			printk( "Lance: request for irq %d failed\n", irq );
+			return( 0 );
+		}
 		dev->irq = irq;
 	}
 
diff -Nru a/drivers/net/e100/e100_proc.c b/drivers/net/e100/e100_proc.c
--- a/drivers/net/e100/e100_proc.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/e100/e100_proc.c	Sun Jun 16 19:31:40 2002
@@ -257,7 +257,8 @@
 	if (count > WRITE_BUF_MAX_LEN) {
 		count = WRITE_BUF_MAX_LEN;
 	}
-	copy_from_user(s_blink_op, buffer, count);
+	if (copy_from_user(s_blink_op, buffer, count))
+		return -EFAULT;
 	s_blink_op[count] = '\0';
 	i_blink_op = simple_strtoul(s_blink_op, &res, 0);
 	if (res == s_blink_op) {
diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/net/eepro.c	Sun Jun 16 19:31:41 2002
@@ -828,8 +828,10 @@
 			}
 
 			/* Grab the region so we can find another board if autoIRQ fails. */
-			request_region(ioaddr, EEPRO_IO_EXTENT, dev->name);
-
+			if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) { 
+				printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n", ioaddr);
+				goto freeall;
+			}
 			((struct eepro_local *)dev->priv)->lock = SPIN_LOCK_UNLOCKED;
 
 			dev->open               = eepro_open;
diff -Nru a/drivers/net/eexpress.c b/drivers/net/eexpress.c
--- a/drivers/net/eexpress.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/eexpress.c	Sun Jun 16 19:31:39 2002
@@ -436,10 +436,26 @@
 	ret = request_irq(dev->irq,&eexp_irq,0,dev->name,dev);
 	if (ret) return ret;
 
-	request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress");
-	request_region(ioaddr+0x4000, 16, "EtherExpress shadow");
-	request_region(ioaddr+0x8000, 16, "EtherExpress shadow");
-	request_region(ioaddr+0xc000, 16, "EtherExpress shadow");
+	if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) {
+		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
+			, ioaddr);
+		goto err_out1;
+	}
+	if (!request_region(ioaddr+0x4000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
+		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
+			, ioaddr+0x4000);
+		goto err_out2;
+	}
+	if (!request_region(ioaddr+0x8000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
+		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
+			, ioaddr+0x8000);
+		goto err_out3;
+	}
+	if (!request_region(ioaddr+0xc000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
+		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
+			, ioaddr+0xc000);
+		goto err_out4;
+	}
 	
 	if (lp->width) {
 		printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
@@ -452,6 +468,16 @@
 	printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
 #endif
 	return 0;
+
+	err_out4:
+		release_region(ioaddr+0x8000, EEXP_IO_EXTENT);
+	err_out3:
+		release_region(ioaddr+0x4000, EEXP_IO_EXTENT);
+	err_out2:
+		release_region(ioaddr, EEXP_IO_EXTENT);
+	err_out1:
+		free_irq(dev->irq, dev);
+		return -EBUSY;
 }
 
 /*
diff -Nru a/drivers/net/hamradio/Config.in b/drivers/net/hamradio/Config.in
--- a/drivers/net/hamradio/Config.in	Sun Jun 16 19:31:38 2002
+++ b/drivers/net/hamradio/Config.in	Sun Jun 16 19:31:38 2002
@@ -4,8 +4,10 @@
 dep_tristate 'Serial port 6PACK driver' CONFIG_6PACK $CONFIG_AX25
 dep_tristate 'BPQ Ethernet driver' CONFIG_BPQETHER $CONFIG_AX25
     
-dep_tristate 'High-speed (DMA) SCC driver for AX.25' CONFIG_DMASCC $CONFIG_AX25
-dep_tristate 'Z8530 SCC driver' CONFIG_SCC $CONFIG_AX25
+if [ "$CONFIG_ISA" = "y" ]; then
+  dep_tristate 'High-speed (DMA) SCC driver for AX.25' CONFIG_DMASCC $CONFIG_AX25
+  dep_tristate 'Z8530 SCC driver' CONFIG_SCC $CONFIG_AX25
+fi
 if [ "$CONFIG_SCC" != "n" ]; then
    bool '  additional delay for PA0HZP OptoSCC compatible boards' CONFIG_SCC_DELAY
    bool '  support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO
diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
--- a/drivers/net/hamradio/yam.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/net/hamradio/yam.c	Sun Jun 16 19:31:41 2002
@@ -841,6 +841,7 @@
 	struct yam_port *yp = (struct yam_port *) dev->priv;
 	enum uart u;
 	int i;
+	int ret=0;
 
 	printk(KERN_INFO "Trying %s at iobase 0x%lx irq %u\n", dev->name, dev->base_addr, dev->irq);
 
@@ -850,24 +851,27 @@
 		dev->irq < 2 || dev->irq > 15) {
 		return -ENXIO;
 	}
-	if (check_region(dev->base_addr, YAM_EXTENT)) {
+	if (!request_region(dev->base_addr, YAM_EXTENT, dev->name))
+	{
 		printk(KERN_ERR "%s: cannot 0x%lx busy\n", dev->name, dev->base_addr);
 		return -EACCES;
 	}
 	if ((u = yam_check_uart(dev->base_addr)) == c_uart_unknown) {
 		printk(KERN_ERR "%s: cannot find uart type\n", dev->name);
-		return -EIO;
+		ret = -EIO;
+		goto out_release_base;
 	}
 	if (fpga_download(dev->base_addr, yp->bitrate)) {
 		printk(KERN_ERR "%s: cannot init FPGA\n", dev->name);
-		return -EIO;
+		ret = -EIO;
+		goto out_release_base;
 	}
 	outb(0, IER(dev->base_addr));
 	if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, dev)) {
 		printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq);
-		return -EBUSY;
+		ret = -EBUSY;
+		goto out_release_base;
 	}
-	request_region(dev->base_addr, YAM_EXTENT, dev->name);
 
 	yam_set_uart(dev);
 
@@ -884,6 +888,10 @@
 	printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq,
 		   uart_str[u]);
 	return 0;
+
+out_release_base:
+	release_region(dev->base_addr, YAM_EXTENT);
+	return ret;
 }
 
 /* --------------------------------------------------------------------- */
diff -Nru a/drivers/net/irda/Config.help b/drivers/net/irda/Config.help
--- a/drivers/net/irda/Config.help	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/irda/Config.help	Sun Jun 16 19:31:39 2002
@@ -157,3 +157,11 @@
   called old_belkin.o.  Some information is contained in the comments
   at the top of <file:drivers/net/irda/old_belkin.c>.
 
+ACTiSYS IR-200L dongle (Experimental)
+CONFIG_ACT200L_DONGLE
+  Say Y here if you want to build support for the ACTiSYS IR-200L
+  dongle. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The ACTiSYS IR-200L dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY. To activate support for ACTiSYS IR-200L dongles
+  you will have to start irattach like this: "irattach -d act200l".
diff -Nru a/drivers/net/irda/Config.in b/drivers/net/irda/Config.in
--- a/drivers/net/irda/Config.in	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/irda/Config.in	Sun Jun 16 19:31:40 2002
@@ -18,6 +18,10 @@
    if [ "$CONFIG_ARCH_EP7211" = "y" ]; then
       dep_tristate '  EP7211 I/R support' CONFIG_EP7211_IR $CONFIG_IRDA
    fi
+   if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
+      dep_tristate '  ACTiSYS IR-200L dongle (Experimental)' CONFIG_ACT200L_DONGLE $CONFIG_IRDA
+      dep_tristate '  Mobile Action MA600 dongle (Experimental)' CONFIG_MA600_DONGLE $CONFIG_IRDA
+   fi
 fi
 
 comment 'FIR device drivers'
diff -Nru a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
--- a/drivers/net/irda/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/irda/Makefile	Sun Jun 16 19:31:40 2002
@@ -25,5 +25,7 @@
 obj-$(CONFIG_OLD_BELKIN_DONGLE)	+= old_belkin.o
 obj-$(CONFIG_EP7211_IR)		+= ep7211_ir.o
 obj-$(CONFIG_MCP2120_DONGLE)	+= mcp2120.o
+obj-$(CONFIG_ACT200L_DONGLE)	+= act200l.o
+obj-$(CONFIG_MA600_DONGLE)	+= ma600.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/net/irda/act200l.c b/drivers/net/irda/act200l.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/irda/act200l.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,299 @@
+/*********************************************************************
+ *
+ * Filename:      act200l.c
+ * Version:       0.8
+ * Description:   Implementation for the ACTiSYS ACT-IR200L dongle
+ * Status:        Experimental.
+ * Author:        SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>
+ * Created at:    Fri Aug  3 17:35:42 2001
+ * Modified at:   Fri Aug 17 10:22:40 2001
+ * Modified by:   SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>
+ *
+ *     Copyright (c) 2001 SHIMIZU Takuya, All Rights Reserved.
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ ********************************************************************/
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irda_device.h>
+#include <net/irda/irtty.h>
+
+static int  act200l_reset(struct irda_task *task);
+static void act200l_open(dongle_t *self, struct qos_info *qos);
+static void act200l_close(dongle_t *self);
+static int  act200l_change_speed(struct irda_task *task);
+
+/* Regsiter 0: Control register #1 */
+#define ACT200L_REG0    0x00
+#define ACT200L_TXEN    0x01 /* Enable transmitter */
+#define ACT200L_RXEN    0x02 /* Enable receiver */
+
+/* Register 1: Control register #2 */
+#define ACT200L_REG1    0x10
+#define ACT200L_LODB    0x01 /* Load new baud rate count value */
+#define ACT200L_WIDE    0x04 /* Expand the maximum allowable pulse */
+
+/* Register 4: Output Power register */
+#define ACT200L_REG4    0x40
+#define ACT200L_OP0     0x01 /* Enable LED1C output */
+#define ACT200L_OP1     0x02 /* Enable LED2C output */
+#define ACT200L_BLKR    0x04
+
+/* Register 5: Receive Mode register */
+#define ACT200L_REG5    0x50
+#define ACT200L_RWIDL   0x01 /* fixed 1.6us pulse mode */
+
+/* Register 6: Receive Sensitivity register #1 */
+#define ACT200L_REG6    0x60
+#define ACT200L_RS0     0x01 /* receive threshold bit 0 */
+#define ACT200L_RS1     0x02 /* receive threshold bit 1 */
+
+/* Register 7: Receive Sensitivity register #2 */
+#define ACT200L_REG7    0x70
+#define ACT200L_ENPOS   0x04 /* Ignore the falling edge */
+
+/* Register 8,9: Baud Rate Dvider register #1,#2 */
+#define ACT200L_REG8    0x80
+#define ACT200L_REG9    0x90
+
+#define ACT200L_2400    0x5f
+#define ACT200L_9600    0x17
+#define ACT200L_19200   0x0b
+#define ACT200L_38400   0x05
+#define ACT200L_57600   0x03
+#define ACT200L_115200  0x01
+
+/* Register 13: Control register #3 */
+#define ACT200L_REG13   0xd0
+#define ACT200L_SHDW    0x01 /* Enable access to shadow registers */
+
+/* Register 15: Status register */
+#define ACT200L_REG15   0xf0
+
+/* Register 21: Control register #4 */
+#define ACT200L_REG21   0x50
+#define ACT200L_EXCK    0x02 /* Disable clock output driver */
+#define ACT200L_OSCL    0x04 /* oscillator in low power, medium accuracy mode */
+
+static struct dongle_reg dongle = {
+	Q_NULL,
+	IRDA_ACT200L_DONGLE,
+	act200l_open,
+	act200l_close,
+	act200l_reset,
+	act200l_change_speed,
+};
+
+int __init act200l_init(void)
+{
+	return irda_device_register_dongle(&dongle);
+}
+
+void __exit act200l_cleanup(void)
+{
+	irda_device_unregister_dongle(&dongle);
+}
+
+static void act200l_open(dongle_t *self, struct qos_info *qos)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	/* Power on the dongle */
+	self->set_dtr_rts(self->dev, TRUE, TRUE);
+
+	/* Set the speeds we can accept */
+	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+	qos->min_turn_time.bits = 0x03;
+
+	MOD_INC_USE_COUNT;
+}
+
+static void act200l_close(dongle_t *self)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	/* Power off the dongle */
+	self->set_dtr_rts(self->dev, FALSE, FALSE);
+
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * Function act200l_change_speed (dev, speed)
+ *
+ *    Set the speed for the ACTiSYS ACT-IR200L type dongle.
+ *
+ */
+static int act200l_change_speed(struct irda_task *task)
+{
+	dongle_t *self = (dongle_t *) task->instance;
+	__u32 speed = (__u32) task->param;
+	__u8 control[3];
+	int ret = 0;
+
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	self->speed_task = task;
+
+	switch (task->state) {
+	case IRDA_TASK_INIT:
+		if (irda_task_execute(self, act200l_reset, NULL, task,
+				(void *) speed))
+		{
+			/* Dongle need more time to reset */
+			irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
+
+			/* Give reset 1 sec to finish */
+			ret = MSECS_TO_JIFFIES(1000);
+		}
+		break;
+	case IRDA_TASK_CHILD_WAIT:
+		WARNING(__FUNCTION__ "(), resetting dongle timed out!\n");
+		ret = -1;
+		break;
+	case IRDA_TASK_CHILD_DONE:
+		/* Clear DTR and set RTS to enter command mode */
+		self->set_dtr_rts(self->dev, FALSE, TRUE);
+
+		switch (speed) {
+		case 9600:
+		default:
+			control[0] = ACT200L_REG8 |  (ACT200L_9600       & 0x0f);
+			control[1] = ACT200L_REG9 | ((ACT200L_9600 >> 4) & 0x0f);
+			break;
+		case 19200:
+			control[0] = ACT200L_REG8 |  (ACT200L_19200       & 0x0f);
+			control[1] = ACT200L_REG9 | ((ACT200L_19200 >> 4) & 0x0f);
+			break;
+		case 38400:
+			control[0] = ACT200L_REG8 |  (ACT200L_38400       & 0x0f);
+			control[1] = ACT200L_REG9 | ((ACT200L_38400 >> 4) & 0x0f);
+			break;
+		case 57600:
+			control[0] = ACT200L_REG8 |  (ACT200L_57600       & 0x0f);
+			control[1] = ACT200L_REG9 | ((ACT200L_57600 >> 4) & 0x0f);
+			break;
+		case 115200:
+			control[0] = ACT200L_REG8 |  (ACT200L_115200       & 0x0f);
+			control[1] = ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f);
+			break;
+		}
+		control[2] = ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE;
+
+		/* Write control bytes */
+		self->write(self->dev, control, 3);
+		irda_task_next_state(task, IRDA_TASK_WAIT);
+		ret = MSECS_TO_JIFFIES(5);
+		break;
+	case IRDA_TASK_WAIT:
+		/* Go back to normal mode */
+		self->set_dtr_rts(self->dev, TRUE, TRUE);
+
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		self->speed_task = NULL;
+		break;
+	default:
+		ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		self->speed_task = NULL;
+		ret = -1;
+		break;
+	}
+	return ret;
+}
+
+/*
+ * Function act200l_reset (driver)
+ *
+ *    Reset the ACTiSYS ACT-IR200L type dongle.
+ */
+static int act200l_reset(struct irda_task *task)
+{
+	dongle_t *self = (dongle_t *) task->instance;
+	__u8 control[9] = {
+		ACT200L_REG15,
+		ACT200L_REG13 | ACT200L_SHDW,
+		ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL,
+		ACT200L_REG13,
+		ACT200L_REG7  | ACT200L_ENPOS,
+		ACT200L_REG6  | ACT200L_RS0  | ACT200L_RS1,
+		ACT200L_REG5  | ACT200L_RWIDL,
+		ACT200L_REG4  | ACT200L_OP0  | ACT200L_OP1 | ACT200L_BLKR,
+		ACT200L_REG0  | ACT200L_TXEN | ACT200L_RXEN
+	};
+	int ret = 0;
+
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	self->reset_task = task;
+
+	switch (task->state) {
+	case IRDA_TASK_INIT:
+		/* Power on the dongle */
+		self->set_dtr_rts(self->dev, TRUE, TRUE);
+
+		irda_task_next_state(task, IRDA_TASK_WAIT1);
+		ret = MSECS_TO_JIFFIES(50);
+		break;
+	case IRDA_TASK_WAIT1:
+		/* Reset the dongle : set RTS low for 25 ms */
+		self->set_dtr_rts(self->dev, TRUE, FALSE);
+
+		irda_task_next_state(task, IRDA_TASK_WAIT2);
+		ret = MSECS_TO_JIFFIES(50);
+		break;
+	case IRDA_TASK_WAIT2:
+		/* Clear DTR and set RTS to enter command mode */
+		self->set_dtr_rts(self->dev, FALSE, TRUE);
+
+		/* Write control bytes */
+		self->write(self->dev, control, 9);
+		irda_task_next_state(task, IRDA_TASK_WAIT3);
+		ret = MSECS_TO_JIFFIES(15);
+		break;
+	case IRDA_TASK_WAIT3:
+		/* Go back to normal mode */
+		self->set_dtr_rts(self->dev, TRUE, TRUE);
+
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		self->reset_task = NULL;
+		break;
+	default:
+		ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		self->reset_task = NULL;
+		ret = -1;
+		break;
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>");
+MODULE_DESCRIPTION("ACTiSYS ACT-IR200L dongle driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Function init_module (void)
+ *
+ *    Initialize ACTiSYS ACT-IR200L module
+ *
+ */
+module_init(act200l_init);
+
+/*
+ * Function cleanup_module (void)
+ *
+ *    Cleanup ACTiSYS ACT-IR200L module
+ *
+ */
+module_exit(act200l_cleanup);
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/irda/irda-usb.c	Sun Jun 16 19:31:40 2002
@@ -30,23 +30,24 @@
  *			    IMPORTANT NOTE
  *			    --------------
  *
- * As of kernel 2.4.10, this is the state of compliance and testing of
+ * As of kernel 2.5.20, this is the state of compliance and testing of
  * this driver (irda-usb) with regards to the USB low level drivers...
  *
  * This driver has been tested SUCCESSFULLY with the following drivers :
- *	o usb-uhci	(For Intel/Via USB controllers)
- *	o usb-ohci	(For other USB controllers)
+ *	o usb-uhci-hcd	(For Intel/Via USB controllers)
+ *	o uhci-hcd	(Alternate/JE driver for Intel/Via USB controllers)
  *
  * This driver has NOT been tested with the following drivers :
- *	o usb-ehci	(USB 2.0 controllers)
+ *	o ehci-hcd	(USB 2.0 controllers)
  *
- * This driver WON'T WORK with the following drivers :
- *	o uhci		(Alternate/JE driver for Intel/Via USB controllers)
- * Amongst the reasons :
- *	o uhci doesn't implement USB_ZERO_PACKET
- *	o uhci non-compliant use of urb->timeout
- * The final fix for USB_ZERO_PACKET in uhci is likely to be in 2.4.19 and
- * 2.5.8. With this fix, the driver will work properly. More on that later.
+ * This driver DOESN'T SEEM TO WORK with the following drivers :
+ *	o ohci-hcd	(For other USB controllers)
+ * The first outgoing URB never calls its completion/failure callback.
+ *
+ * Note that all HCD drivers do USB_ZERO_PACKET and timeout properly,
+ * so we don't have to worry about that anymore.
+ * One common problem is the failure to set the address on the dongle,
+ * but this happens before the driver gets loaded...
  *
  * Jean II
  */
@@ -167,7 +168,8 @@
 
 		IRDA_DEBUG(2, __FUNCTION__ "(), changing speed to %d\n", self->new_speed);
 		self->speed = self->new_speed;
-		self->new_speed = -1;
+		/* We will do ` self->new_speed = -1; ' in the completion
+		 * handler just in case the current URB fail - Jean II */
 
 		switch (self->speed) {
 		case 2400:
@@ -208,7 +210,8 @@
 	if (self->new_xbofs != -1) {
 		IRDA_DEBUG(2, __FUNCTION__ "(), changing xbofs to %d\n", self->new_xbofs);
 		self->xbofs = self->new_xbofs;
-		self->new_xbofs = -1;
+		/* We will do ` self->new_xbofs = -1; ' in the completion
+		 * handler just in case the current URB fail - Jean II */
 
 		switch (self->xbofs) {
 		case 48:
@@ -286,7 +289,8 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Note : this function will be called with both speed_urb and empty_urb...
+ * Speed URB callback
+ * Now, we can only get called for the speed URB.
  */
 static void speed_bulk_callback(struct urb *urb)
 {
@@ -295,10 +299,9 @@
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	/* We should always have a context */
-	if (self == NULL) {
-		WARNING(__FUNCTION__ "(), Bug : self == NULL\n");
-		return;
-	}
+	ASSERT(self != NULL, return;);
+	/* We should always be called for the speed URB */
+	ASSERT(urb == self->speed_urb, return;);
 
 	/* Check for timeout and other USB nasties */
 	if (urb->status != 0) {
@@ -314,12 +317,14 @@
 	}
 
 	/* urb is now available */
-	urb->status = 0;
+	//urb->status = 0; -> tested above
 
-	/* If it was the speed URB, allow the stack to send more packets */
-	if(urb == self->speed_urb) {
-		netif_wake_queue(self->netdev);
-	}
+	/* New speed and xbof is now commited in hardware */
+	self->new_speed = -1;
+	self->new_xbofs = -1;
+
+	/* Allow the stack to send more packets */
+	netif_wake_queue(self->netdev);
 }
 
 /*------------------------------------------------------------------*/
@@ -334,6 +339,9 @@
 	s32 speed;
 	s16 xbofs;
 	int res, mtt;
+	int	err = 1;	/* Failed */
+
+	IRDA_DEBUG(4, __FUNCTION__ "() on %s\n", netdev->name);
 
 	netif_stop_queue(netdev);
 
@@ -343,10 +351,9 @@
 	/* Check if the device is still there.
 	 * We need to check self->present under the spinlock because
 	 * of irda_usb_disconnect() is synchronous - Jean II */
-	if ((!self) || (!self->present)) {
+	if (!self->present) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), Device is gone...\n");
-		spin_unlock_irqrestore(&self->lock, flags);
-		return 1;	/* Failed */
+		goto drop;
 	}
 
 	/* Check if we need to change the number of xbofs */
@@ -373,6 +380,7 @@
 			irda_usb_change_speed_xbofs(self);
 			netdev->trans_start = jiffies;
 			/* Will netif_wake_queue() in callback */
+			err = 0;	/* No error */
 			goto drop;
 		}
 	}
@@ -479,7 +487,7 @@
 	/* Drop silently the skb and exit */
 	dev_kfree_skb(skb);
 	spin_unlock_irqrestore(&self->lock, flags);
-	return 0;
+	return err;		/* Usually 1 */
 }
 
 /*------------------------------------------------------------------*/
@@ -495,10 +503,9 @@
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	/* We should always have a context */
-	if (self == NULL) {
-		WARNING(__FUNCTION__ "(), Bug : self == NULL\n");
-		return;
-	}
+	ASSERT(self != NULL, return;);
+	/* We should always be called for the speed URB */
+	ASSERT(urb == self->tx_urb, return;);
 
 	/* Free up the skb */
 	dev_kfree_skb_any(skb);
@@ -531,10 +538,21 @@
 		return;
 	}
 
-	/* If we need to change the speed or xbofs, do it now */
+	/* If changes to speed or xbofs is pending... */
 	if ((self->new_speed != -1) || (self->new_xbofs != -1)) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Changing speed now...\n");
-		irda_usb_change_speed_xbofs(self);
+		if ((self->new_speed != self->speed) ||
+		    (self->new_xbofs != self->xbofs)) {
+			/* We haven't changed speed yet (because of
+			 * IUC_SPEED_BUG), so do it now - Jean II */
+			IRDA_DEBUG(1, __FUNCTION__ "(), Changing speed now...\n");
+			irda_usb_change_speed_xbofs(self);
+		} else {
+			/* New speed and xbof is now commited in hardware */
+			self->new_speed = -1;
+			self->new_xbofs = -1;
+			/* Done, waiting for next packet */
+			netif_wake_queue(self->netdev);
+		}
 	} else {
 		/* Otherwise, allow the stack to send more packets */
 		netif_wake_queue(self->netdev);
@@ -559,11 +577,13 @@
 	int	done = 0;	/* If we have made any progress */
 
 	IRDA_DEBUG(0, __FUNCTION__ "(), Network layer thinks we timed out!\n");
+	ASSERT(self != NULL, return;);
 
 	/* Protect us from USB callbacks, net Tx and else. */
 	spin_lock_irqsave(&self->lock, flags);
 
-	if ((!self) || (!self->present)) {
+	/* self->present *MUST* be read under spinlock */
+	if (!self->present) {
 		WARNING(__FUNCTION__ "(), device not present!\n");
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&self->lock, flags);
@@ -678,35 +698,7 @@
 /*------------------------------------------------------------------*/
 /*
  * Submit a Rx URB to the USB layer to handle reception of a frame
- *
- * Important note :
- * The function process_urb() in usb-uhci.c contains the following code :
- * >	urb->complete ((struct urb *) urb);
- * >	// Re-submit the URB if ring-linked
- * >	if (is_ring && (urb->status != -ENOENT) && !contains_killed) {
- * >		urb->dev=usb_dev;
- * >		uhci_submit_urb (urb);
- * >	}
- * The way I see it is that if we submit more than one Rx URB at a
- * time, the Rx URB can be automatically re-submitted after the
- * completion handler is called.
- *
- * My take is that it's a questionable feature, and quite difficult
- * to control and to make work effectively.
- * The outcome (re-submited or not) depend on various complex
- * test ('is_ring' and 'contains_killed'), and the completion handler
- * don't have this information, so basically the driver has no way
- * to know if URB are resubmitted or not. Yuck !
- * If everything is perfect, it's cool, but the problem is when
- * an URB is killed (timeout, call to unlink_urb(), ...), things get
- * messy...
- * The other problem is that this scheme deal only with the URB
- * and ignore everything about the associated buffer. So, it would
- * resubmit URB even if the buffer is still in use or non-existent.
- * On the other hand, submitting ourself in the completion callback
- * is quite trivial and work well (this function).
- * Moreover, this scheme doesn't allow to have an idle URB, which is
- * necessary to overcome some URB failures.
+ * Mostly called by the completion callback of the previous URB.
  *
  * Jean II
  */
diff -Nru a/drivers/net/irda/ma600.c b/drivers/net/irda/ma600.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/irda/ma600.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,356 @@
+/*********************************************************************
+ *                
+ * Filename:      ma600.c
+ * Version:       0.1
+ * Description:   Implementation of the MA600 dongle
+ * Status:        Experimental.
+ * Author:        Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95
+ * Created at:    Sat Jun 10 20:02:35 2000
+ * Modified at:   
+ * Modified by:   
+ *
+ * Note: very thanks to Mr. Maru Wang <maru@mobileaction.com.tw> for providing 
+ *       information on the MA600 dongle
+ * 
+ *     Copyright (c) 2000 Leung, All Rights Reserved.
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License 
+ *     along with this program; if not, write to the Free Software 
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *     MA 02111-1307 USA
+ *     
+ ********************************************************************/
+
+/* define this macro for release version */
+//#define NDEBUG
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irda_device.h>
+#include <net/irda/irtty.h>
+
+#ifndef NDEBUG
+	#undef IRDA_DEBUG
+	#define IRDA_DEBUG(n, args...) (printk(KERN_DEBUG args))
+
+	#undef ASSERT(expr, func)
+	#define ASSERT(expr, func) \
+	if(!(expr)) { \
+	        printk( "Assertion failed! %s,%s,%s,line=%d\n",\
+        	#expr,__FILE__,__FUNCTION__,__LINE__); \
+	        ##func}
+#endif
+
+/* convert hex value to ascii hex */
+static const char hexTbl[] = "0123456789ABCDEF";
+
+
+static void ma600_open(dongle_t *self, struct qos_info *qos);
+static void ma600_close(dongle_t *self);
+static int  ma600_change_speed(struct irda_task *task);
+static int  ma600_reset(struct irda_task *task);
+
+/* control byte for MA600 */
+#define MA600_9600	0x00
+#define MA600_19200	0x01
+#define MA600_38400	0x02
+#define MA600_57600	0x03
+#define MA600_115200	0x04
+#define MA600_DEV_ID1	0x05
+#define MA600_DEV_ID2	0x06
+#define MA600_2400	0x08
+
+static struct dongle_reg dongle = {
+	Q_NULL,
+	IRDA_MA600_DONGLE,
+	ma600_open,
+	ma600_close,
+	ma600_reset,
+	ma600_change_speed,
+};
+
+int __init ma600_init(void)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	return irda_device_register_dongle(&dongle);
+}
+
+void __exit ma600_cleanup(void)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	irda_device_unregister_dongle(&dongle);
+}
+
+/*
+	Power on:
+		(0) Clear RTS and DTR for 1 second
+		(1) Set RTS and DTR for 1 second
+		(2) 9600 bps now
+	Note: assume RTS, DTR are clear before
+*/
+static void ma600_open(dongle_t *self, struct qos_info *qos)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400
+				|IR_57600|IR_115200;
+	qos->min_turn_time.bits = 0x01;		/* Needs at least 1 ms */	
+	irda_qos_bits_to_value(qos);
+
+	//self->set_dtr_rts(self->dev, FALSE, FALSE);
+	// should wait 1 second
+
+	self->set_dtr_rts(self->dev, TRUE, TRUE);
+	// should wait 1 second
+
+	MOD_INC_USE_COUNT;
+}
+
+static void ma600_close(dongle_t *self)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	/* Power off dongle */
+	self->set_dtr_rts(self->dev, FALSE, FALSE);
+
+	MOD_DEC_USE_COUNT;
+}
+
+static __u8 get_control_byte(__u32 speed)
+{
+	__u8 byte;
+
+	switch (speed) {
+	default:
+	case 115200:
+		byte = MA600_115200;
+		break;
+	case 57600:
+		byte = MA600_57600;
+		break;
+	case 38400:
+		byte = MA600_38400;
+		break;
+	case 19200:
+		byte = MA600_19200;
+		break;
+	case 9600:
+		byte = MA600_9600;
+		break;
+	case 2400:
+		byte = MA600_2400;
+		break;
+	}
+
+	return byte;
+}
+
+/*
+ * Function ma600_change_speed (dev, state, speed)
+ *
+ *    Set the speed for the MA600 type dongle. Warning, this 
+ *    function must be called with a process context!
+ *
+ *    Algorithm
+ *    1. Reset
+ *    2. clear RTS, set DTR and wait for 1ms
+ *    3. send Control Byte to the MA600 through TXD to set new baud rate
+ *       wait until the stop bit of Control Byte is sent (for 9600 baud rate, 
+ *       it takes about 10 msec)
+ *    4. set RTS, set DTR (return to NORMAL Operation)
+ *    5. wait at least 10 ms, new setting (baud rate, etc) takes effect here 
+ *       after
+ */
+static int ma600_change_speed(struct irda_task *task)
+{
+	dongle_t *self = (dongle_t *) task->instance;
+	__u32 speed = (__u32) task->param;
+	static __u8 byte;
+	__u8 byte_echo;
+	int ret = 0;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	ASSERT(task != NULL, return -1;);
+
+	if (self->speed_task && self->speed_task != task) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n");
+		return MSECS_TO_JIFFIES(10);
+	} else {
+		self->speed_task = task;
+	}
+
+	switch (task->state) {
+	case IRDA_TASK_INIT:
+	case IRDA_TASK_CHILD_INIT:
+		/* 
+		 * Need to reset the dongle and go to 9600 bps before
+                 * programming 
+		 */
+		if (irda_task_execute(self, ma600_reset, NULL, task, 
+				      (void *) speed)) {
+			/* Dongle need more time to reset */
+			irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
+	
+			/* give 1 second to finish */
+			ret = MSECS_TO_JIFFIES(1000);
+		} else {
+			irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
+		}
+		break;
+
+	case IRDA_TASK_CHILD_WAIT:
+		WARNING(__FUNCTION__ "(), resetting dongle timed out!\n");
+		ret = -1;
+		break;
+
+	case IRDA_TASK_CHILD_DONE:
+		/* Set DTR, Clear RTS */
+		self->set_dtr_rts(self->dev, TRUE, FALSE);
+	
+		ret = MSECS_TO_JIFFIES(1);		/* Sleep 1 ms */
+		irda_task_next_state(task, IRDA_TASK_WAIT);
+		break;
+
+	case IRDA_TASK_WAIT:
+		speed = (__u32) task->param;
+		byte = get_control_byte(speed);
+
+		/* Write control byte */
+		self->write(self->dev, &byte, sizeof(byte));
+		
+		irda_task_next_state(task, IRDA_TASK_WAIT1);
+
+		/* Wait at least 10 ms */
+		ret = MSECS_TO_JIFFIES(15);
+		break;
+
+	case IRDA_TASK_WAIT1:
+		/* Read control byte echo */
+		self->read(self->dev, &byte_echo, sizeof(byte_echo));
+
+		if(byte != byte_echo) {
+			/* if control byte != echo, I don't know what to do */
+			printk(KERN_WARNING __FUNCTION__ "() control byte written != read!\n");
+			printk(KERN_WARNING "control byte = 0x%c%c\n", 
+			       hexTbl[(byte>>4)&0x0f], hexTbl[byte&0x0f]);
+			printk(KERN_WARNING "byte echo = 0x%c%c\n", 
+			       hexTbl[(byte_echo>>4) & 0x0f], 
+			       hexTbl[byte_echo & 0x0f]);
+		#ifndef NDEBUG
+		} else {
+			IRDA_DEBUG(2, __FUNCTION__ "() control byte write read OK\n");
+		#endif
+		}
+
+		/* Set DTR, Set RTS */
+		self->set_dtr_rts(self->dev, TRUE, TRUE);
+
+		irda_task_next_state(task, IRDA_TASK_WAIT2);
+
+		/* Wait at least 10 ms */
+		ret = MSECS_TO_JIFFIES(10);
+		break;
+
+	case IRDA_TASK_WAIT2:
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		self->speed_task = NULL;
+		break;
+
+	default:
+		ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		self->speed_task = NULL;
+		ret = -1;
+		break;
+	}
+	return ret;
+}
+
+/*
+ * Function ma600_reset (driver)
+ *
+ *      This function resets the ma600 dongle. Warning, this function 
+ *      must be called with a process context!! 
+ *
+ *      Algorithm:
+ *    	  0. DTR=0, RTS=1 and wait 10 ms
+ *    	  1. DTR=1, RTS=1 and wait 10 ms
+ *        2. 9600 bps now
+ */
+int ma600_reset(struct irda_task *task)
+{
+	dongle_t *self = (dongle_t *) task->instance;
+	int ret = 0;
+
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+	ASSERT(task != NULL, return -1;);
+
+	if (self->reset_task && self->reset_task != task) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n");
+		return MSECS_TO_JIFFIES(10);
+	} else
+		self->reset_task = task;
+	
+	switch (task->state) {
+	case IRDA_TASK_INIT:
+		/* Clear DTR and Set RTS */
+		self->set_dtr_rts(self->dev, FALSE, TRUE);
+		irda_task_next_state(task, IRDA_TASK_WAIT1);
+		ret = MSECS_TO_JIFFIES(10);		/* Sleep 10 ms */
+		break;
+	case IRDA_TASK_WAIT1:
+		/* Set DTR and RTS */
+		self->set_dtr_rts(self->dev, TRUE, TRUE);
+		irda_task_next_state(task, IRDA_TASK_WAIT2);
+		ret = MSECS_TO_JIFFIES(10);		/* Sleep 10 ms */
+		break;
+	case IRDA_TASK_WAIT2:
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		self->reset_task = NULL;
+		break;
+	default:
+		ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
+		irda_task_next_state(task, IRDA_TASK_DONE);		
+		self->reset_task = NULL;
+		ret = -1;
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95");
+MODULE_DESCRIPTION("MA600 dongle driver version 0.1");
+MODULE_LICENSE("GPL");
+		
+/*
+ * Function init_module (void)
+ *
+ *    Initialize MA600 module
+ *
+ */
+module_init(ma600_init);
+
+/*
+ * Function cleanup_module (void)
+ *
+ *    Cleanup MA600 module
+ *
+ */
+module_exit(ma600_cleanup);
+
diff -Nru a/drivers/net/ni65.c b/drivers/net/ni65.c
--- a/drivers/net/ni65.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/ni65.c	Sun Jun 16 19:31:40 2002
@@ -353,18 +353,21 @@
 	unsigned long flags;
 
 	for(i=0;i<NUM_CARDS;i++) {
-		if(check_region(ioaddr, cards[i].total_size))
+		if(!request_region(ioaddr, cards[i].total_size, cards[i].cardname))
 			continue;
 		if(cards[i].id_offset >= 0) {
 			if(inb(ioaddr+cards[i].id_offset+0) != cards[i].id0 ||
 				 inb(ioaddr+cards[i].id_offset+1) != cards[i].id1) {
+				 release_region(ioaddr, cards[i].total_size);
 				 continue;
 			}
 		}
 		if(cards[i].vendor_id) {
 			for(j=0;j<3;j++)
-				if(inb(ioaddr+cards[i].addr_offset+j) != cards[i].vendor_id[j])
+				if(inb(ioaddr+cards[i].addr_offset+j) != cards[i].vendor_id[j]) {
+					release_region(ioaddr, cards[i].total_size);
 					continue;
+			  }
 		}
 		break;
 	}
@@ -374,8 +377,10 @@
 	for(j=0;j<6;j++)
 		dev->dev_addr[j] = inb(ioaddr+cards[i].addr_offset+j);
 
-	if( (j=ni65_alloc_buffer(dev)) < 0)
+	if( (j=ni65_alloc_buffer(dev)) < 0) {
+		release_region(ioaddr, cards[i].total_size);
 		return j;
+	}
 	p = (struct priv *) dev->priv;
 	p->cmdr_addr = ioaddr + cards[i].cmd_offset;
 	p->cardno = i;
@@ -386,6 +391,7 @@
 	if( (j=readreg(CSR0)) != 0x4) {
 		 printk(KERN_ERR "can't RESET card: %04x\n",j);
 		 ni65_free_buffer(p);
+		 release_region(ioaddr, cards[p->cardno].total_size);
 		 return -EAGAIN;
 	}
 
@@ -437,6 +443,7 @@
 			if(i == 5) {
 				printk("Can't detect DMA channel!\n");
 				ni65_free_buffer(p);
+				release_region(ioaddr, cards[p->cardno].total_size);
 				return -EAGAIN;
 			}
 			dev->dma = dmatab[i];
@@ -459,6 +466,7 @@
 			{
 				printk("Failed to detect IRQ line!\n");
 				ni65_free_buffer(p);
+				release_region(ioaddr, cards[p->cardno].total_size);
 				return -EAGAIN;
 			}
 			printk("IRQ %d (autodetected).\n",dev->irq);
@@ -471,13 +479,9 @@
 	{
 		printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma);
 		ni65_free_buffer(p);
+		release_region(ioaddr, cards[p->cardno].total_size);
 		return -EAGAIN;
 	}
-
-	/*
-	 * Grab the region so we can find another board.
-	 */
-	request_region(ioaddr,cards[p->cardno].total_size,cards[p->cardno].cardname);
 
 	dev->base_addr = ioaddr;
 
diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c
--- a/drivers/net/ns83820.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/net/ns83820.c	Sun Jun 16 19:31:41 2002
@@ -1,10 +1,12 @@
-#define _VERSION "0.17"
-/* ns83820.c by Benjamin LaHaise <bcrl@redhat.com> with contributions.
+#define _VERSION "0.18"
+/* ns83820.c by Benjamin LaHaise with contributions.
  *
- * $Revision: 1.34.2.14 $
+ * Questions/comments/discussion to linux-ns83820@kvack.org.
+ *
+ * $Revision: 1.34.2.16 $
  *
  * Copyright 2001 Benjamin LaHaise.
- * Copyright 2001 Red Hat.
+ * Copyright 2001, 2002 Red Hat.
  *
  * Mmmm, chocolate vanilla mocha...
  *
@@ -49,10 +51,12 @@
  *				by Michael Clark <michael@metaparadigm.com>
  *	20011205	0.13b - call register_netdev earlier in initialization
  *				suppress duplicate link status messages
- *	20011117 	0.14 - ethtool GDRVINFO, GLINK support
+ *	20011117 	0.14 - ethtool GDRVINFO, GLINK support from jgarzik
  *	20011204 	0.15	get ppc (big endian) working
  *	20011218	0.16	various cleanups
  *	20020310	0.17	speedups
+ *	20020610	0.18 -	actually use the pci dma api for highmem
+ *			     -	remove pci latency register fiddling
  *
  * Driver Overview
  * ===============
@@ -105,54 +109,16 @@
 #undef Dprintk
 #define	Dprintk			dprintk
 
-#ifdef CONFIG_HIGHMEM64G
-#define USE_64BIT_ADDR	"+"
-#elif defined(__ia64__)
+#if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
 #define USE_64BIT_ADDR	"+"
 #endif
 
-/* Tell davem to fix the pci dma api.  Grrr. */
-/* stolen from acenic.c */
-#if 0 //def CONFIG_HIGHMEM
-#if defined(CONFIG_X86)
-#define DMAADDR_OFFSET  0
-#if defined(CONFIG_HIGHMEM64G)
-typedef u64 dmaaddr_high_t;
-#else
-typedef u32 dmaaddr_high_t;
-#endif
-#elif defined(CONFIG_PPC)
-#define DMAADDR_OFFSET PCI_DRAM_OFFSET
-typedef unsigned long dmaaddr_high_t;
-#endif
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
-		    int offset, size_t size, int dir)
-{
-	u64 phys;
-	phys = page - mem_map;
-	phys <<= PAGE_SHIFT;
-	phys += offset;
-	phys += DMAADDR_OFFSET;
-	return phys;
-}
-#else
-
-typedef unsigned long dmaaddr_high_t;
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
-		    int offset, size_t size, int dir)
-{
-	return pci_map_single(hwdev, page_address(page) + offset, size, dir);
-}
-#endif
-
 #if defined(USE_64BIT_ADDR)
 #define	VERSION	_VERSION USE_64BIT_ADDR
+#define TRY_DAC	1
 #else
 #define	VERSION	_VERSION
+#define TRY_DAC	0
 #endif
 
 /* tunables */
@@ -384,13 +350,22 @@
 } while(0)
 
 #ifdef USE_64BIT_ADDR
-typedef u64	hw_addr_t;
+#define HW_ADDR_LEN	8
+#define desc_addr_set(desc, addr)				\
+	do {							\
+		u64 __addr = (addr);				\
+		desc[BUFPTR] = cpu_to_le32(__addr);		\
+		desc[BUFPTR+1] = cpu_to_le32(__addr >> 32);	\
+	} while(0)
+#define desc_addr_get(desc)					\
+		(((u64)le32_to_cpu(desc[BUFPTR+1]) << 32)	\
+		     | le32_to_cpu(desc[BUFPTR]))
 #else
-typedef u32	hw_addr_t;
+#define HW_ADDR_LEN	4
+#define desc_addr_set(desc, addr)	(desc[BUFPTR] = cpu_to_le32(addr))
+#define desc_addr_get(desc)		(le32_to_cpu(desc[BUFPTR]))
 #endif
 
-#define HW_ADDR_LEN	(sizeof(hw_addr_t))
-
 #define LINK		0
 #define BUFPTR		(LINK + HW_ADDR_LEN/4)
 #define CMDSTS		(BUFPTR + HW_ADDR_LEN/4)
@@ -402,6 +377,7 @@
 #define CMDSTS_INTR	0x20000000
 #define CMDSTS_ERR	0x10000000
 #define CMDSTS_OK	0x08000000
+#define CMDSTS_LEN_MASK	0x0000ffff
 
 #define CMDSTS_DEST_MASK	0x01800000
 #define CMDSTS_DEST_SELF	0x00800000
@@ -515,7 +491,7 @@
 	unsigned next_empty;
 	u32 cmdsts;
 	u32 *sg;
-	hw_addr_t buf;
+	dma_addr_t buf;
 
 	next_empty = dev->rx_info.next_empty;
 
@@ -848,7 +824,7 @@
 	       (cmdsts != CMDSTS_OWN)) {
 		struct sk_buff *skb;
 		u32 extsts = le32_to_cpu(desc[EXTSTS]);
-		dmaaddr_high_t bufptr = le32_to_cpu(desc[BUFPTR]);
+		dma_addr_t bufptr = desc_addr_get(desc);
 
 		dprintk("cmdsts: %08x\n", cmdsts);
 		dprintk("link: %08x\n", cpu_to_le32(desc[LINK]));
@@ -936,6 +912,8 @@
 	while ((tx_done_idx != dev->tx_free_idx) &&
 	       !(CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[CMDSTS]))) ) {
 		struct sk_buff *skb;
+		unsigned len;
+		dma_addr_t addr;
 
 		if (cmdsts & CMDSTS_ERR)
 			dev->stats.tx_errors ++;
@@ -949,13 +927,20 @@
 		skb = dev->tx_skbs[tx_done_idx];
 		dev->tx_skbs[tx_done_idx] = NULL;
 		dprintk("done(%p)\n", skb);
+
+		len = cmdsts & CMDSTS_LEN_MASK;
+		addr = desc_addr_get(desc);
 		if (skb) {
 			pci_unmap_single(dev->pci_dev,
-					le32_to_cpu(desc[BUFPTR]),
-					skb->len,
+					addr,
+					len,
 					PCI_DMA_TODEVICE);
 			dev_kfree_skb_irq(skb);
-		}
+		} else
+			pci_unmap_page(dev->pci_dev, 
+					addr,
+					len,
+					PCI_DMA_TODEVICE);
 
 		tx_done_idx = (tx_done_idx + 1) % NR_TX_DESC;
 		dev->tx_done_idx = tx_done_idx;
@@ -1001,7 +986,7 @@
 	u32 free_idx, cmdsts, extsts;
 	int nr_free, nr_frags;
 	unsigned tx_done_idx;
-	dmaaddr_high_t buf;
+	dma_addr_t buf;
 	unsigned len;
 	skb_frag_t *frag;
 	int stopped = 0;
@@ -1075,7 +1060,7 @@
 			(unsigned long long)buf);
 		free_idx = (free_idx + 1) % NR_TX_DESC;
 		desc[LINK] = cpu_to_le32(dev->tx_phy_descs + (free_idx * DESC_SIZE * 4));
-		desc[BUFPTR] = cpu_to_le32(buf);
+		desc_addr_set(desc, buf);
 		desc[EXTSTS] = cpu_to_le32(extsts);
 
 		cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
@@ -1092,11 +1077,12 @@
 		if (!nr_frags)
 			break;
 
-		buf = pci_map_single_high(dev->pci_dev, frag->page,
-					  frag->page_offset,
-					  frag->size, PCI_DMA_TODEVICE);
-		dprintk("frag: buf=%08Lx  page=%08lx\n",
-			(long long)buf, (long)(frag->page - mem_map));
+		buf = pci_map_page(dev->pci_dev, frag->page,
+				   frag->page_offset,
+				   frag->size, PCI_DMA_TODEVICE);
+		dprintk("frag: buf=%08Lx  page=%08lx offset=%08lx\n",
+			(long long)buf, (long)(frag->page - mem_map),
+			frag->page_offset);
 		len = frag->size;
 		frag++;
 		nr_frags--;
@@ -1427,6 +1413,16 @@
 	struct ns83820 *dev;
 	long addr;
 	int err;
+	int using_dac = 0;
+
+	if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffff)) {
+		using_dac = 1;
+	} else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) {
+		using_dac = 0;
+	} else {
+		printk(KERN_WARNING "ns83820.c: pci_set_dma_mask failed!\n");
+		return -ENODEV;
+	}
 
 	dev = (struct ns83820 *)alloc_etherdev((sizeof *dev) - (sizeof dev->net_dev));
 	err = -ENOMEM;
@@ -1536,6 +1532,9 @@
 #ifdef USE_64BIT_ADDR
 	dev->CFG_cache |= CFG_M64ADDR;
 #endif
+	if (using_dac)
+		dev->CFG_cache |= CFG_T64ADDR;
+
 	/* Big endian mode does not seem to do what the docs suggest */
 	dev->CFG_cache &= ~CFG_BEM;
 
@@ -1561,7 +1560,7 @@
 	writel(dev->CFG_cache, dev->base + CFG);
 	dprintk("CFG: %08x\n", dev->CFG_cache);
 
-#if 1	/* Huh?  This sets the PCI latency register.  Should be done via 
+#if 0	/* Huh?  This sets the PCI latency register.  Should be done via 
 	 * the PCI layer.  FIXME.
 	 */
 	if (readl(dev->base + SRR))
@@ -1614,13 +1613,12 @@
 	/* Yes, we support dumb IP checksum on transmit */
 	dev->net_dev.features |= NETIF_F_SG;
 	dev->net_dev.features |= NETIF_F_IP_CSUM;
-#if defined(USE_64BIT_ADDR) || defined(CONFIG_HIGHMEM4G)
-	if ((dev->CFG_cache & CFG_T64ADDR)) {
+
+	if (using_dac) {
 		printk(KERN_INFO "%s: using 64 bit addressing.\n",
 			dev->net_dev.name);
 		dev->net_dev.features |= NETIF_F_HIGHDMA;
 	}
-#endif
 
 	printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %02x:%02x:%02x:%02x:%02x:%02x io=0x%08lx irq=%d f=%s\n",
 		dev->net_dev.name,
diff -Nru a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c
--- a/drivers/net/pcmcia/ray_cs.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/net/pcmcia/ray_cs.c	Sun Jun 16 19:31:40 2002
@@ -1316,9 +1316,12 @@
 		    err = -E2BIG;
 		    break;
 		}
-		copy_from_user(card_essid,
-			       wrq->u.data.pointer,
-			       wrq->u.data.length);
+		if (copy_from_user(card_essid,
+				   wrq->u.data.pointer,
+				   wrq->u.data.length)) {
+			err = -EFAULT;
+			break;
+		}
 		card_essid[IW_ESSID_MAX_SIZE] = '\0';
 
 		/* Set the ESSID in the card */
diff -Nru a/drivers/net/wan/Config.in b/drivers/net/wan/Config.in
--- a/drivers/net/wan/Config.in	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/wan/Config.in	Sun Jun 16 19:31:39 2002
@@ -9,11 +9,12 @@
 if [ "$CONFIG_WAN" = "y" ]; then
 # There is no way to detect a comtrol sv11 - force it modular for now.
 
+   if [ "$CONFIG_ISA" = "y" ]; then
    dep_tristate '  Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m
-
 # The COSA/SRP driver has not been tested as non-modular yet.
 
    dep_tristate '  COSA/SRP sync serial boards support' CONFIG_COSA m
+   fi
 
 #
 # COMX drivers
diff -Nru a/drivers/net/wan/comx-hw-comx.c b/drivers/net/wan/comx-hw-comx.c
--- a/drivers/net/wan/comx-hw-comx.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/wan/comx-hw-comx.c	Sun Jun 16 19:31:39 2002
@@ -466,16 +466,16 @@
 	}
 
 	if (!twin_open) {
-		if (check_region(dev->base_addr, hw->io_extent)) {
+		if (!request_region(dev->base_addr, hw->io_extent, dev->name)) {
 			return -EAGAIN;
 		}
 		if (request_irq(dev->irq, COMX_interrupt, 0, dev->name, 
 		   (void *)dev)) {
 			printk(KERN_ERR "comx-hw-comx: unable to obtain irq %d\n", dev->irq);
+			release_region(dev->base_addr, hw->io_extent);
 			return -EAGAIN;
 		}
 		ch->init_status |= IRQ_ALLOCATED;
-		request_region(dev->base_addr, hw->io_extent, dev->name);
 		if (!ch->HW_load_board || ch->HW_load_board(dev)) {
 			ch->init_status &= ~IRQ_ALLOCATED;
 			retval=-ENODEV;
diff -Nru a/drivers/net/wan/comx-hw-munich.c b/drivers/net/wan/comx-hw-munich.c
--- a/drivers/net/wan/comx-hw-munich.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/wan/comx-hw-munich.c	Sun Jun 16 19:31:39 2002
@@ -41,6 +41,7 @@
 #include <asm/io.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 
 #define COMX_NEW
 
@@ -2008,7 +2009,8 @@
 	if (board->tiq) kfree((void *)board->tiq);
 	if (board->riq) kfree((void *)board->riq);
 	if (board->piq) kfree((void *)board->piq);
-	board->ccb = board->tiq = board->riq = board->piq = NULL;
+	board->ccb = NULL;
+	board->tiq = board->riq = board->piq = NULL;
     }
 
     /* Enable setting of hw parameters */
diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
--- a/drivers/net/wan/dscc4.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/wan/dscc4.c	Sun Jun 16 19:31:39 2002
@@ -645,6 +645,24 @@
 	rx_fd->end = 0xbabeface;
 }
 
+static void dscc4_free1(struct pci_dev *pdev)
+{
+	struct dscc4_pci_priv *ppriv;
+	struct dscc4_dev_priv *root;
+	int i;
+
+	ppriv = pci_get_drvdata(pdev);
+	root = ppriv->root;
+
+	for (i = 0; i < dev_per_card; i++)
+		unregister_hdlc_device(&root[i].hdlc);
+
+	pci_set_drvdata(pdev, NULL);
+
+	kfree(root);
+	kfree(ppriv);
+}
+
 static int __init dscc4_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
@@ -693,7 +711,7 @@
 
 	if (request_irq(pdev->irq, &dscc4_irq, SA_SHIRQ, DRV_NAME, priv->root)){
 		printk(KERN_WARNING "%s: IRQ %d busy\n", DRV_NAME, pdev->irq);
-		goto err_out_iounmap;
+		goto err_out_free1;
 	}
 
 	/* power up/little endian/dma core controlled via lrda/ltda */
@@ -768,6 +786,8 @@
 			    priv->iqcfg_dma);
 err_out_free_irq:
 	free_irq(pdev->irq, priv->root);
+err_out_free1:
+	dscc4_free1(pdev);
 err_out_iounmap:
 	iounmap ((void *)ioaddr);
 err_out_free_mmio_region:
@@ -1779,9 +1799,6 @@
 			    ppriv->iqcfg_dma);
 	for (i = 0; i < dev_per_card; i++) {
 		struct dscc4_dev_priv *dpriv = root + i;
-		hdlc_device *hdlc = &dpriv->hdlc;
-
-		unregister_hdlc_device(hdlc);
 
 		pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
 				    dpriv->iqrx, dpriv->iqrx_dma);
@@ -1789,11 +1806,9 @@
 				    dpriv->iqtx, dpriv->iqtx_dma);
 	}
 
-	iounmap((void *)ioaddr);
-	kfree(root);
+	dscc4_free1(pdev);
 
-	pci_set_drvdata(pdev, NULL);
-	kfree(ppriv);
+	iounmap((void *)ioaddr);
 
 	release_mem_region(pci_resource_start(pdev, 1),
 			   pci_resource_len(pdev, 1));
diff -Nru a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
--- a/drivers/net/wan/farsync.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/net/wan/farsync.c	Sun Jun 16 19:31:39 2002
@@ -1466,10 +1466,6 @@
                                  + BUF_OFFSET ( txBuffer[i][0][0]);
                 dev->mem_end     = card->phys_mem
                                  + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
-                dev->rmem_start  = card->phys_mem
-                                 + BUF_OFFSET ( rxBuffer[i][0][0]);
-                dev->rmem_end    = card->phys_mem
-                                 + BUF_OFFSET ( rxBuffer[i][NUM_RX_BUFFER][0]);
                 dev->base_addr   = card->pci_conf;
                 dev->irq         = card->irq;
 
@@ -1528,6 +1524,13 @@
         }
         memset ( card, 0, sizeof ( struct fst_card_info ));
 
+        /* Try to enable the device */
+        if (( err = pci_enable_device ( pdev )) != 0 )
+        {
+                printk_err ("Failed to enable card. Err %d\n", -err );
+                goto error_free_card;
+        }
+
         /* Record info we need*/
         card->irq         = pdev->irq;
         card->pci_conf    = pci_resource_start ( pdev, 1 );
@@ -1567,12 +1570,6 @@
                 goto error_release_mem;
         }
 
-        /* Try to enable the device */
-        if (( err = pci_enable_device ( pdev )) != 0 )
-        {
-                printk_err ("Failed to enable card. Err %d\n", -err );
-                goto error_release_ctlmem;
-        }
 
         /* Get virtual addresses of memory regions */
         if (( card->mem = ioremap ( card->phys_mem, FST_MEMSIZE )) == NULL )
diff -Nru a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
--- a/drivers/net/wan/sdla_fr.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/net/wan/sdla_fr.c	Sun Jun 16 19:31:41 2002
@@ -4348,9 +4348,9 @@
 					card->devname,NIPQUAD(arphdr->ar_sip));
 
 			printk(KERN_INFO "%s: mask %u.%u.%u.%u\n", 
-				card->devname, NIPQUAD(in_dev->ida_list->ifa_mask));
+				card->devname, NIPQUAD(in_dev->ifa_list->ifa_mask));
 				printk(KERN_INFO "%s: local %u.%u.%u.%u\n", 
-				card->devname,NIPQUAD(in_dev->ida_list->ifa_local));
+				card->devname,NIPQUAD(in_dev->ifa_list->ifa_local));
 			return -1;
 		}
 
diff -Nru a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c
--- a/drivers/net/wan/sdlamain.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/net/wan/sdlamain.c	Sun Jun 16 19:31:41 2002
@@ -604,7 +604,13 @@
 
   	/* Reserve I/O region and schedule background task */
         if(card->hw.type != SDLA_S514 && !card->wandev.piggyback)
-                request_region(card->hw.port, card->hw.io_range, wandev->name);
+		if (!request_region(card->hw.port, card->hw.io_range, 
+				wandev->name)) {
+			printk(KERN_WARNING "port 0x%04x busy\n", card->hw.port);
+			release_hw(card);
+			wandev->state = WAN_UNCONFIGURED;
+			return -EBUSY;
+	  }
 
 	/* Only use the polling routine for the X25 protocol */
 	
diff -Nru a/drivers/pci/pci.ids b/drivers/pci/pci.ids
--- a/drivers/pci/pci.ids	Sun Jun 16 19:31:38 2002
+++ b/drivers/pci/pci.ids	Sun Jun 16 19:31:38 2002
@@ -2039,6 +2039,7 @@
 		8e2e 7000  KF-230TX
 		8e2e 7100  KF-230TX/2
 		a0a0 0007  ALN-325C
+	8169  RTL-8169
 10ed  Ascii Corporation
 	7310  V7310
 10ee  Xilinx, Inc.
diff -Nru a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
--- a/drivers/pcmcia/cardbus.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/pcmcia/cardbus.c	Sun Jun 16 19:31:40 2002
@@ -274,6 +274,9 @@
 
 		dev->bus = bus;
 		dev->sysdata = bus->sysdata;
+		dev->dev.parent = bus->dev;
+		dev->dev.bus = &pci_bus_type;
+
 		dev->devfn = i;
 		dev->vendor = vend;
 		pci_readw(dev, PCI_DEVICE_ID, &dev->device);
@@ -281,10 +284,8 @@
 
 		pci_setup_device(dev);
 
-		dev->dev.parent = bus->dev;
 		strcpy(dev->dev.name, dev->name);
 		strcpy(dev->dev.bus_id, dev->slot_name);
-		device_register(&dev->dev);
 
 		/* FIXME: Do we need to enable the expansion ROM? */
 		for (r = 0; r < 7; r++) {
@@ -301,6 +302,7 @@
 		}
 
 		pci_enable_device(dev); /* XXX check return */
+		device_register(&dev->dev);
 		pci_insert_device(dev, bus);
 	}
 
diff -Nru a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
--- a/drivers/pcmcia/ti113x.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/pcmcia/ti113x.h	Sun Jun 16 19:31:40 2002
@@ -195,6 +195,8 @@
 #define ti_sysctl(socket)	((socket)->private[0])
 #define ti_cardctl(socket)	((socket)->private[1])
 #define ti_devctl(socket)	((socket)->private[2])
+#define ti_diag(socket)		((socket)->private[3])
+#define ti_irqmux(socket)	((socket)->private[4])
 
 static int ti113x_open(pci_socket_t *socket)
 {
@@ -235,7 +237,6 @@
 	yenta_proc_setup
 };
 
-#define ti_diag(socket)		((socket)->private[0])
 
 static int ti1250_open(pci_socket_t *socket)
 {
@@ -244,16 +245,22 @@
 	ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ);
 	if (socket->cb_irq)
 		ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
-	ti_open(socket);
+	ti113x_open(socket);
 	return 0;
 }
 
 static int ti1250_init(pci_socket_t *socket)
 {
 	yenta_init(socket);
-
+	ti113x_init(socket);
+	ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
+	ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */
+	if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE))
+		ti_irqmux(socket) |= 0x20; /* route INTB */
+	
+	config_writel(socket, TI122X_IRQMUX, ti_irqmux(socket));
+		
 	config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket));
-	ti_intctl(socket);
 	return 0;
 }
 
diff -Nru a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
--- a/drivers/pcmcia/yenta.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/pcmcia/yenta.c	Sun Jun 16 19:31:40 2002
@@ -806,7 +806,7 @@
 	{ PD(TI,1251A),	&ti_ops },
 	{ PD(TI,1211),	&ti_ops },
 	{ PD(TI,1251B),	&ti_ops },
-	{ PD(TI,1410),	&ti_ops },
+	{ PD(TI,1410),	&ti1250_ops },
 	{ PD(TI,1420),	&ti_ops },
 	{ PD(TI,4410),	&ti_ops },
 	{ PD(TI,4451),	&ti_ops },
diff -Nru a/drivers/pnp/pnpbios_proc.c b/drivers/pnp/pnpbios_proc.c
--- a/drivers/pnp/pnpbios_proc.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/pnp/pnpbios_proc.c	Sun Jun 16 19:31:41 2002
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/pnpbios.h>
+#include <linux/init.h>
 
 static struct proc_dir_entry *proc_pnp = NULL;
 static struct proc_dir_entry *proc_pnp_boot = NULL;
diff -Nru a/drivers/s390/Makefile b/drivers/s390/Makefile
--- a/drivers/s390/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/s390/Makefile	Sun Jun 16 19:31:40 2002
@@ -2,12 +2,9 @@
 # Makefile for the S/390 specific device drivers
 #
 
-mod-subdirs := block char misc net scsi cio
-
-export-objs += s390dyn.o
+export-objs := s390dyn.o qdio.o
 
 obj-$(CONFIG_QDIO) += qdio.o
-export-objs += qdio.o
 
 obj-y += s390mach.o s390dyn.o sysinfo.o
 obj-y += block/ char/ misc/ net/ scsi/ cio/
diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
--- a/drivers/s390/block/xpram.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/s390/block/xpram.c	Sun Jun 16 19:31:41 2002
@@ -84,8 +84,6 @@
 devfs_handle_t xpram_devfs_handle;
 
 #define DEVICE_NR(device) MINOR(device)   /* xpram has no partition bits */
-#define DEVICE_NAME "xpram"               /* name for messaging */
-#define DEVICE_INTR xpram_intrptr         /* pointer to the bottom half */
 #define DEVICE_NO_RANDOM                  /* no entropy to contribute */
 #define DEVICE_OFF(d)                     /* do-nothing */
 
@@ -158,7 +156,6 @@
 /* The following items are obtained through kmalloc() in init_module() */
 
 Xpram_Dev *xpram_devices = NULL;
-int *xpram_hardsects = NULL;
 int *xpram_offsets = NULL;   /* partition offsets */
 
 #define MIN(x,y) ((x) < (y) ? (x) : (y))
@@ -684,10 +681,8 @@
         struct request * current_req;      /* working request */
 
 	while(1) {
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		if (blk_queue_empty(QUEUE))
 			return;
-		}
 
 		fault=0;
 		current_req = CURRENT;
@@ -697,7 +692,7 @@
 			static int count = 0;
 			if (count++ < 5) /* print the message at most five times */
 				PRINT_WARN(" request for unknown device\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 
@@ -707,7 +702,7 @@
                 /* does request exceed size of device ? */
 		if ( XPRAM_SEC2KB(sects_to_copy) > xpram_sizes[dev_no] ) {
 			PRINT_WARN(" request past end of device\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 
@@ -721,20 +716,20 @@
                 if ( current_req->sector &  (XPRAM_SEC_IN_PG - 1) ) {
 			PRINT_WARN(" request does not start at an expanded storage page boundery\n");
 			PRINT_WARN(" referenced sector: %ld\n",current_req->sector);
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 		/* Does request refere to partial expanded storage pages? */
                 if ( sects_to_copy & (XPRAM_SEC_IN_PG - 1) ) {
 			PRINT_WARN(" request referes to a partial expanded storage page\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 #endif /*  XPRAM_SEC_IN_PG != 1 */
 		/* Is request buffer aligned with kernel pages? */
 		if ( ((unsigned long)buffer) & (XPRAM_PGSIZE-1) ) {
 			PRINT_WARN(" request buffer is not aligned with kernel pages\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 
@@ -772,11 +767,11 @@
 			break;
 		default:
 			/* can't happen */
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
-		if ( fault ) end_request(0);
-		else end_request(1); /* success */
+		if ( fault ) end_request(CURRENT, 0);
+		else end_request(CURRENT, 1); /* success */
 	}
 }
 
@@ -939,6 +934,7 @@
 
 	q = BLK_DEFAULT_QUEUE(major);
 	blk_init_queue (q, xpram_request);
+	blk_queue_hardsect_size(q, xpram_hardsect);
 
 	/* we want to have XPRAM_UNUSED blocks security buffer between devices */
 	mem_usable=xpram_mem_avail-(XPRAM_UNUSED*(xpram_devs-1));
@@ -978,16 +974,6 @@
 		PRINT_DEBUG(" device(%d) offset = %d kB, size = %d kB\n",i, xpram_offsets[i], xpram_sizes[i]);
 #endif
 
-	xpram_hardsects = kmalloc(xpram_devs * sizeof(int), GFP_KERNEL);
-	if (!xpram_hardsects) {
-		PRINT_ERR("Not enough memory for xpram_hardsects\n");
-                PRINT_ERR("Giving up xpram\n");
-		goto fail_malloc_hardsects;
-	}
-	for (i=0; i < xpram_devs; i++) /* all the same hardsect */
-		xpram_hardsects[i] = xpram_hardsect;
-	hardsect_size[major]=xpram_hardsects;
-   
 	/* 
 	 * allocate the devices -- we can't have them static, as the number
 	 * can be specified at load time
@@ -1040,7 +1026,6 @@
 		  goto fail_devfs_register;
 		}
 #endif  /* WHY? */
-				 
 	}
 
 	return 0; /* succeed */
@@ -1053,10 +1038,7 @@
 	}
 	kfree(xpram_devices);
 	kfree (xpram_offsets);
- fail_malloc_hardsects:
  fail_malloc_devices:
-	kfree(xpram_hardsects);
-	hardsect_size[major] = NULL;
  fail_malloc:
 	/* ???	unregister_chrdev(major, "xpram"); */
 	unregister_blkdev(major, "xpram");
@@ -1086,7 +1068,6 @@
 	int i;
 
 	/* first of all, reset all the data structures */
-	kfree(hardsect_size[major]);
 	kfree(xpram_offsets);
 	blk_clear(major);
 
diff -Nru a/drivers/sbus/Makefile b/drivers/sbus/Makefile
--- a/drivers/sbus/Makefile	Sun Jun 16 19:31:41 2002
+++ b/drivers/sbus/Makefile	Sun Jun 16 19:31:41 2002
@@ -6,8 +6,6 @@
 obj-y    := sbus.o dvma.o
 endif
 
-mod-subdirs := char audio
-
 obj-$(CONFIG_SBUSCHAR) += char/
 obj-$(CONFIG_SPARCAUDIO) += audio/
 
diff -Nru a/drivers/sbus/audio/dbri.c b/drivers/sbus/audio/dbri.c
--- a/drivers/sbus/audio/dbri.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/sbus/audio/dbri.c	Sun Jun 16 19:31:39 2002
@@ -17,6 +17,7 @@
  *   - Data sheet of the T7903, a newer but very similar ISA bus equivalent
  *     available from the Lucent (formarly AT&T microelectronics) home
  *     page.
+ *   - http://www.freesoft.org/Linux/DBRI/
  * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec
  *   Interfaces: CHI, Audio In & Out, 2 bits parallel
  *   Documentation: from the Crystal Semiconductor home page.
diff -Nru a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
--- a/drivers/sbus/char/jsflash.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/sbus/char/jsflash.c	Sun Jun 16 19:31:40 2002
@@ -42,7 +42,6 @@
  */
 #define MAJOR_NR	JSFD_MAJOR
 
-#define DEVICE_NAME "jsfd"
 #define DEVICE_REQUEST jsfd_do_request
 #define DEVICE_NR(device) (MINOR(device))
 #define DEVICE_ON(device)
@@ -207,16 +206,14 @@
 	size_t len;
 
 	for (;;) {
-		if (blk_queue_empty(QUEUE)) {
-			CLEAR_INTR;
+		if (blk_queue_empty(QUEUE))
 			return;
-		}
 
 		req = CURRENT;
 
 		dev = MINOR(req->rq_dev);
 		if (dev >= JSF_MAX || (dev & JSF_PART_MASK) >= JSF_NPART) {
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 		jdp = &jsf0.dv[dev & JSF_PART_MASK];
@@ -224,31 +221,31 @@
 		offset = req->sector << 9;
 		len = req->current_nr_sectors << 9;
 		if ((offset + len) > jdp->dsize) {
-               		end_request(0);
+               		end_request(CURRENT, 0);
 			continue;
 		}
 
 		if (req->cmd == WRITE) {
 			printk(KERN_ERR "jsfd: write\n");
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 		if (req->cmd != READ) {
 			printk(KERN_ERR "jsfd: bad req->cmd %d\n", req->cmd);
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 
 		if ((jdp->dbase & 0xff000000) != 0x20000000) {
 			printk(KERN_ERR "jsfd: bad base %x\n", (int)jdp->dbase);
-			end_request(0);
+			end_request(CURRENT, 0);
 			continue;
 		}
 
 /* printk("jsfd%d: read buf %p off %x len %x\n", dev, req->buffer, (int)offset, (int)len); */ /* P3 */
 		jsfd_read(req->buffer, jdp->dbase + offset, len);
 
-		end_request(1);
+		end_request(CURRENT, 1);
 	}
 }
 
diff -Nru a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c
--- a/drivers/scsi/53c7,8xx.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/53c7,8xx.c	Sun Jun 16 19:31:39 2002
@@ -241,7 +241,6 @@
 #include "scsi.h"
 #include "hosts.h"
 #include "53c7,8xx.h"
-#include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
 #include <linux/stddef.h>
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/53c700.c	Sun Jun 16 19:31:39 2002
@@ -51,6 +51,14 @@
 
 /* CHANGELOG
  *
+ * Version 2.8
+ *
+ * Fixed bad bug affecting tag starvation processing (previously the
+ * driver would hang the system if too many tags starved.  Also fixed
+ * bad bug having to do with 10 byte command processing and REQUEST
+ * SENSE (the command would loop forever getting a transfer length
+ * mismatch in the CMD phase).
+ *
  * Version 2.7
  *
  * Fixed scripts problem which caused certain devices (notably CDRWs)
@@ -104,7 +112,7 @@
  * Initial modularisation from the D700.  See NCR_D700.c for the rest of
  * the changelog.
  * */
-#define NCR_700_VERSION "2.7"
+#define NCR_700_VERSION "2.8"
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -129,7 +137,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 
 #include "53c700.h"
 
@@ -674,21 +681,34 @@
 			print_sense("53c700", SCp);
 
 #endif
-			SCp->use_sg = SCp->cmnd[8];
+			/* restore the old result if the request sense was
+			 * successful */
 			if(result == 0)
 				result = SCp->cmnd[7];
+			/* now restore the original command */
+			memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd,
+			       sizeof(SCp->data_cmnd));
+			SCp->request_buffer = SCp->buffer;
+			SCp->request_bufflen = SCp->bufflen;
+			SCp->use_sg = SCp->old_use_sg;
+			SCp->cmd_len = SCp->old_cmd_len;
+			SCp->sc_data_direction = SCp->sc_old_data_direction;
+			SCp->underflow = SCp->old_underflow;
+			
 		}
 
 		free_slot(slot, hostdata);
-
-		SCp->host_scribble = NULL;
-		SCp->result = result;
-		SCp->scsi_done(SCp);
+#ifdef NCR_700_DEBUG
 		if(NCR_700_get_depth(SCp->device) == 0 ||
 		   NCR_700_get_depth(SCp->device) > NCR_700_MAX_TAGS)
 			printk(KERN_ERR "Invalid depth in NCR_700_scsi_done(): %d\n",
 			       NCR_700_get_depth(SCp->device));
+#endif /* NCR_700_DEBUG */
 		NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) - 1);
+
+		SCp->host_scribble = NULL;
+		SCp->result = result;
+		SCp->scsi_done(SCp);
 	} else {
 		printk(KERN_ERR "53c700: SCSI DONE HAS NULL SCp\n");
 	}
@@ -1048,7 +1068,6 @@
 				 * of the command */
 				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
 				SCp->cmnd[7] = hostdata->status[0];
-				SCp->cmnd[8] = SCp->use_sg;
 				SCp->use_sg = 0;
 				SCp->sc_data_direction = SCSI_DATA_READ;
 				pci_dma_sync_single(hostdata->pci_dev,
@@ -1885,6 +1904,10 @@
 				printk(KERN_WARNING "scsi%d (%d:%d) Target is suffering from tag starvation.\n", SCp->host->host_no, SCp->target, SCp->lun);
 				NCR_700_set_flag(SCp->device, NCR_700_DEV_TAG_STARVATION_WARNED);
 			}
+			/* Release the slot and ajust the depth before refusing
+			 * the command */
+			free_slot(slot, hostdata);
+			NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) - 1);
 			return 1;
 		}
 		slot->tag = SCp->device->current_tag++;
diff -Nru a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
--- a/drivers/scsi/53c7xx.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/53c7xx.c	Sun Jun 16 19:31:40 2002
@@ -281,7 +281,6 @@
 #include "scsi.h"
 #include "hosts.h"
 #include "53c7xx.h"
-#include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
 #include <linux/stddef.h>
diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
--- a/drivers/scsi/AM53C974.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/AM53C974.c	Sun Jun 16 19:31:40 2002
@@ -17,7 +17,6 @@
 #include "scsi.h"
 #include "hosts.h"
 #include "AM53C974.h"
-#include "constants.h"
 #include "sd.h"
 
 /* AM53/79C974 (PCscsi) driver release 0.5
diff -Nru a/drivers/scsi/Config.in b/drivers/scsi/Config.in
--- a/drivers/scsi/Config.in	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/Config.in	Sun Jun 16 19:31:40 2002
@@ -42,11 +42,15 @@
 if [ "$CONFIG_PCI" = "y" ]; then
    dep_tristate '3ware Hardware ATA-RAID support' CONFIG_BLK_DEV_3W_XXXX_RAID $CONFIG_SCSI
 fi
-dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST $CONFIG_SCSI
+dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST $CONFIG_SCSI $CONFIG_ISA
 dep_tristate 'ACARD SCSI support' CONFIG_SCSI_ACARD $CONFIG_SCSI
-dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
-dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
-dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
+if [ "$CONFIG_ISA" = "y" ]; then
+   dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
+   dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
+fi
+if [ "$CONFIG_EISA" = "y" ]; then
+  dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
+fi
 source drivers/scsi/aic7xxx/Config.in
 if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
    dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
@@ -56,10 +60,16 @@
       bool '  Collect statistics to report in /proc' CONFIG_AIC7XXX_OLD_PROC_STATS
    fi
 fi
-dep_tristate 'Adaptec I2O RAID support ' CONFIG_SCSI_DPT_I2O $CONFIG_SCSI
+# All the I2O code and drivers do not seem to be 64bit safe.
+if [ "$CONFIG_X86_64" != "y" ]; then
+  dep_tristate 'Adaptec I2O RAID support ' CONFIG_SCSI_DPT_I2O $CONFIG_SCSI
+fi
 dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
 dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
-dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI $CONFIG_PCI
+# does not use pci dma and seems to be isa/onboard only for old machines
+if [ "$CONFIG_X86_64" != "y" ]; then
+  dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI $CONFIG_PCI
+fi
 dep_tristate 'AMI MegaRAID support' CONFIG_SCSI_MEGARAID $CONFIG_SCSI
 
 dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC $CONFIG_SCSI
@@ -70,7 +80,7 @@
    dep_tristate 'Compaq Fibre Channel 64-bit/66Mhz HBA support' CONFIG_SCSI_CPQFCTS $CONFIG_SCSI
 fi
 dep_tristate 'DMX3191D SCSI support' CONFIG_SCSI_DMX3191D $CONFIG_SCSI $CONFIG_PCI
-dep_tristate 'DTC3180/3280 SCSI support' CONFIG_SCSI_DTC3280 $CONFIG_SCSI
+dep_tristate 'DTC3180/3280 SCSI support' CONFIG_SCSI_DTC3280 $CONFIG_SCSI $CONFIG_ISA
 dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI
 if [ "$CONFIG_SCSI_EATA" != "n" ]; then
    bool '  enable tagged command queueing' CONFIG_SCSI_EATA_TAGGED_QUEUE
@@ -111,7 +121,7 @@
       bool  '  ppa/imm option - Assume slow parport control register' CONFIG_SCSI_IZIP_SLOW_CTR
    fi
 fi
-dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI
+dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI $CONFIG_ISA
 if [ "$CONFIG_MCA" = "y" ]; then
    dep_tristate 'NCR Dual 700 MCA SCSI support' CONFIG_SCSI_NCR_D700 $CONFIG_SCSI
    if [ "$CONFIG_SCSI_NCR_D700" != "n" ]; then
@@ -164,11 +174,11 @@
 if [ "$CONFIG_MCA" = "y" ]; then
    dep_tristate 'NCR MCA 53C9x SCSI support' CONFIG_SCSI_MCA_53C9X $CONFIG_SCSI
 fi
-dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
+dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI $CONFIG_ISA
 dep_tristate 'PCI2000 support' CONFIG_SCSI_PCI2000 $CONFIG_SCSI
 dep_tristate 'PCI2220i support' CONFIG_SCSI_PCI2220I $CONFIG_SCSI
-dep_tristate 'PSI240i support' CONFIG_SCSI_PSI240I $CONFIG_SCSI
-dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI
+dep_tristate 'PSI240i support' CONFIG_SCSI_PSI240I $CONFIG_SCSI $CONFIG_ISA
+dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI $CONFIG_ISA
 if [ "$CONFIG_PCI" = "y" ]; then
    dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
    dep_tristate 'Qlogic ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $CONFIG_SCSI
@@ -177,24 +187,27 @@
    fi
    dep_tristate 'Qlogic QLA 1280 SCSI support' CONFIG_SCSI_QLOGIC_1280 $CONFIG_SCSI
 fi
-if [ "$CONFIG_X86" = "y" ]; then
+if [ "$CONFIG_X86" = "y" -a "$CONFIG_ISA" = "y" ]; then
    dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI
 fi
-dep_tristate 'Simple 53c710 SCSI support (Compaq, NCR machines)' CONFIG_SCSI_SIM710 $CONFIG_SCSI
-dep_tristate 'Symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI
+# definitely looks note 64bit safe:
+if [ "$CONFIG_ISA" = "y" -o "$CONFIG_MCA" = "y" -a "$CONFIG_X86_64" != "y" ]; then
+  dep_tristate 'Simple 53c710 SCSI support (Compaq, NCR machines)' CONFIG_SCSI_SIM710 $CONFIG_SCSI
+fi
+dep_tristate 'Symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI $CONFIG_ISA
 if [ "$CONFIG_PCI" = "y" ]; then
    dep_tristate 'Tekram DC390(T) and Am53/79C974 SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI
    if [ "$CONFIG_SCSI_DC390T" != "n" ]; then
       bool '  _omit_ support for non-DC390 adapters' CONFIG_SCSI_DC390T_NOGENSUPP
    fi
 fi
-dep_tristate 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 $CONFIG_SCSI
+dep_tristate 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 $CONFIG_SCSI $CONFIG_ISA
 dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI
-   if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then
+if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then
       bool '  enable elevator sorting' CONFIG_SCSI_U14_34F_LINKED_COMMANDS
       int  '  maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8
-   fi
-if [ "$CONFIG_X86" = "y" ]; then
+fi
+if [ "$CONFIG_X86" = "y" -a "$CONFIG_ISA" = "y" ]; then
    dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR $CONFIG_SCSI
 fi
 #
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/Makefile	Sun Jun 16 19:31:40 2002
@@ -19,8 +19,6 @@
 CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
 
 export-objs	:= scsi_syms.o 53c700.o
-mod-subdirs	:= pcmcia ../acorn/scsi
-
 
 subdir-$(CONFIG_PCMCIA)		+= pcmcia
 
diff -Nru a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
--- a/drivers/scsi/NCR53C9x.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/NCR53C9x.c	Sun Jun 16 19:31:39 2002
@@ -2048,7 +2048,7 @@
 	 * and not only for the entire host adapter as it is now, the workaround
 	 * is way to expensive performance wise.
 	 * Instead, it turns out that when this happens the target has disconnected
-	 * allready but it doesn't show in the interrupt register. Compensate for
+	 * already but it doesn't show in the interrupt register. Compensate for
 	 * that here to try and avoid a SCSI bus reset.
 	 */
 	if(!esp->fas_premature_intr_workaround && (fifocnt == 1) &&
diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
--- a/drivers/scsi/NCR_D700.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/NCR_D700.c	Sun Jun 16 19:31:39 2002
@@ -115,7 +115,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 
 #include "53c700.h"
 #include "NCR_D700.h"
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/aha152x.c	Sun Jun 16 19:31:39 2002
@@ -234,7 +234,6 @@
 #include "scsi.h"
 #include "sd.h"
 #include "hosts.h"
-#include "constants.h"
 #include <asm/system.h>
 #include <linux/errno.h>
 #include <linux/string.h>
diff -Nru a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
--- a/drivers/scsi/atari_scsi.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/atari_scsi.c	Sun Jun 16 19:31:40 2002
@@ -105,7 +105,6 @@
 #include "hosts.h"
 #include "atari_scsi.h"
 #include "NCR5380.h"
-#include "constants.h"
 #include <asm/atari_stdma.h>
 #include <asm/atari_stram.h>
 #include <asm/io.h>
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/constants.c	Sun Jun 16 19:31:41 2002
@@ -2,7 +2,8 @@
  * ASCII values for a number of symbolic constants, printing functions,
  * etc.
  * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422)
- *
+ * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
+ *   by D. Gilbert and aeb (20020609)
  */
 
 #include <linux/module.h>
@@ -147,661 +148,856 @@
     printk("\n");
 }
 
+/**
+ *
+ *	print_status - print scsi status description
+ *	@scsi_status: scsi status value
+ *
+ *	If the status is recognized, the description is printed.
+ *	Otherwise "Unknown status" is output. No trailing space.
+ *	If CONFIG_SCSI_CONSTANTS is not set, then print status in hex
+ *	(e.g. "0x2" for Check Condition).
+ **/
+void
+print_status(unsigned char scsi_status) {
 #if (CONSTANTS & CONST_STATUS)
-static const char * statuses[] = {
-/* 0-4 */ "Good", "Check Condition", "Condition Met", unknown, "Busy", 
-/* 5-9 */ unknown, unknown, unknown, "Intermediate", unknown, 
-/* a-c */ "Intermediate-Condition Met", unknown, "Reservation Conflict",
-/* d-10 */ unknown, unknown, unknown, unknown,
-/* 11-14 */ "Command Terminated", unknown, unknown, "Queue Full",
-/* 15-1a */ unknown, unknown, unknown, unknown, unknown, unknown,
-/* 1b-1f */ unknown, unknown, unknown, unknown, unknown,
-};
-#endif
+	const char * ccp;
 
-void print_status (int status) {
-    status = (status >> 1) & 0x1f;
-#if (CONSTANTS & CONST_STATUS)
-    printk("%s ",statuses[status]);
+	switch (scsi_status) {
+	case 0:    ccp = "Good"; break;
+	case 0x2:  ccp = "Check Condition"; break;
+	case 0x4:  ccp = "Condition Met"; break;
+	case 0x8:  ccp = "Busy"; break;
+	case 0x10: ccp = "Intermediate"; break;
+	case 0x14: ccp = "Intermediate-Condition Met"; break;
+	case 0x18: ccp = "Reservation Conflict"; break;
+	case 0x22: ccp = "Command Terminated"; break;	/* obsolete */
+	case 0x28: ccp = "Task set Full"; break;	/* was: Queue Full */
+	case 0x30: ccp = "ACA Active"; break;
+	case 0x40: ccp = "Task Aborted"; break;
+	default:   ccp = "Unknown status";
+	}
+	printk("%s", ccp);
 #else
-    printk("0x%0x ", status); 
-#endif 
+	printk("0x%0x", scsi_status);
+#endif
 }
 
 #if (CONSTANTS & CONST_XSENSE)
-#define D 0x0001  /* DIRECT ACCESS DEVICE (disk) */
-#define T 0x0002  /* SEQUENTIAL ACCESS DEVICE (tape) */
-#define L 0x0004  /* PRINTER DEVICE */
-#define P 0x0008  /* PROCESSOR DEVICE */
-#define W 0x0010  /* WRITE ONCE READ MULTIPLE DEVICE */
-#define R 0x0020  /* READ ONLY (CD-ROM) DEVICE */
-#define S 0x0040  /* SCANNER DEVICE */
-#define O 0x0080  /* OPTICAL MEMORY DEVICE */
-#define M 0x0100  /* MEDIA CHANGER DEVICE */
-#define C 0x0200  /* COMMUNICATION DEVICE */
-#define A 0x0400  /* ARRAY STORAGE */
-#define E 0x0800  /* ENCLOSURE SERVICES DEVICE */
-#define B 0x1000  /* SIMPLIFIED DIRECT ACCESS DEVICE */
-#define K 0x2000  /* OPTICAL CARD READER/WRITER DEVICE */
-
-struct error_info{
-    unsigned char code1, code2;
-    unsigned short int devices;
-    const char * text;
-};
-
-struct error_info2{
-    unsigned char code1, code2_min, code2_max;
-    unsigned short int devices;
-    const char * text;
+
+struct error_info {
+	unsigned short code12;	/* 0x0302 looks better than 0x03,0x02 */
+	const char * text;
 };
 
-static struct error_info2 additional2[] =
+static struct error_info additional[] =
 {
-  {0x40,0x00,0x7f,D,"Ram failure (%x)"},
-  {0x40,0x80,0xff,D|T|L|P|W|R|S|O|M|C,"Diagnostic failure on component (%x)"},
-  {0x41,0x00,0xff,D,"Data path failure (%x)"},
-  {0x42,0x00,0xff,D,"Power-on or self-test failure (%x)"},
-  {0, 0, 0, 0, NULL}
+	{0x0000, "No additional sense information"},
+	{0x0001, "Filemark detected"},
+	{0x0002, "End-of-partition/medium detected"},
+	{0x0003, "Setmark detected"},
+	{0x0004, "Beginning-of-partition/medium detected"},
+	{0x0005, "End-of-data detected"},
+	{0x0006, "I/O process terminated"},
+	{0x0011, "Audio play operation in progress"},
+	{0x0012, "Audio play operation paused"},
+	{0x0013, "Audio play operation successfully completed"},
+	{0x0014, "Audio play operation stopped due to error"},
+	{0x0015, "No current audio status to return"},
+	{0x0016, "Operation in progress"},
+	{0x0017, "Cleaning requested"},
+	{0x0018, "Erase operation in progress"},
+	{0x0019, "Locate operation in progress"},
+	{0x001A, "Rewind operation in progress"},
+	{0x001B, "Set capacity operation in progress"},
+	{0x001C, "Verify operation in progress"},
+
+	{0x0100, "No index/sector signal"},
+
+	{0x0200, "No seek complete"},
+
+	{0x0300, "Peripheral device write fault"},
+	{0x0301, "No write current"},
+	{0x0302, "Excessive write errors"},
+
+	{0x0400, "Logical unit not ready, cause not reportable"},
+	{0x0401, "Logical unit is in process of becoming ready"},
+	{0x0402, "Logical unit not ready, initializing cmd. required"},
+	{0x0403, "Logical unit not ready, manual intervention required"},
+	{0x0404, "Logical unit not ready, format in progress"},
+	{0x0405, "Logical unit not ready, rebuild in progress"},
+	{0x0406, "Logical unit not ready, recalculation in progress"},
+	{0x0407, "Logical unit not ready, operation in progress"},
+	{0x0408, "Logical unit not ready, long write in progress"},
+	{0x0409, "Logical unit not ready, self-test in progress"},
+	{0x040A, "Logical unit not accessible, asymmetric access state "
+	 "transition"},
+	{0x040B, "Logical unit not accessible, target port in standby state"},
+	{0x040C, "Logical unit not accessible, target port in unavailable "
+	 "state"},
+	{0x0410, "Logical unit not ready, auxiliary memory not accessible"},
+
+	{0x0500, "Logical unit does not respond to selection"},
+
+	{0x0600, "No reference position found"},
+
+	{0x0700, "Multiple peripheral devices selected"},
+
+	{0x0800, "Logical unit communication failure"},
+	{0x0801, "Logical unit communication time-out"},
+	{0x0802, "Logical unit communication parity error"},
+	{0x0803, "Logical unit communication CRC error (Ultra-DMA/32)"},
+	{0x0804, "Unreachable copy target"},
+
+	{0x0900, "Track following error"},
+	{0x0901, "Tracking servo failure"},
+	{0x0902, "Focus servo failure"},
+	{0x0903, "Spindle servo failure"},
+	{0x0904, "Head select fault"},
+
+	{0x0A00, "Error log overflow"},
+
+	{0x0B00, "Warning"},
+	{0x0B01, "Warning - specified temperature exceeded"},
+	{0x0B02, "Warning - enclosure degraded"},
+
+	{0x0C00, "Write error"},
+	{0x0C01, "Write error - recovered with auto reallocation"},
+	{0x0C02, "Write error - auto reallocation failed"},
+	{0x0C03, "Write error - recommend reassignment"},
+	{0x0C04, "Compression check miscompare error"},
+	{0x0C05, "Data expansion occurred during compression"},
+	{0x0C06, "Block not compressible"},
+	{0x0C07, "Write error - recovery needed"},
+	{0x0C08, "Write error - recovery failed"},
+	{0x0C09, "Write error - loss of streaming"},
+	{0x0C0A, "Write error - padding blocks added"},
+	{0x0C0B, "Auxiliary memory write error"},
+	{0x0C0C, "Write error - unexpected unsolicited data"},
+	{0x0C0D, "Write error - not enough unsolicited data"},
+
+	{0x0D00, "Error detected by third party temporary initiator"},
+	{0x0D01, "Third party device failure"},
+	{0x0D02, "Copy target device not reachable"},
+	{0x0D03, "Incorrect copy target device type"},
+	{0x0D04, "Copy target device data underrun"},
+	{0x0D05, "Copy target device data overrun"},
+
+	{0x1000, "Id CRC or ECC error"},
+
+	{0x1100, "Unrecovered read error"},
+	{0x1101, "Read retries exhausted"},
+	{0x1102, "Error too long to correct"},
+	{0x1103, "Multiple read errors"},
+	{0x1104, "Unrecovered read error - auto reallocate failed"},
+	{0x1105, "L-EC uncorrectable error"},
+	{0x1106, "CIRC unrecovered error"},
+	{0x1107, "Data re-synchronization error"},
+	{0x1108, "Incomplete block read"},
+	{0x1109, "No gap found"},
+	{0x110A, "Miscorrected error"},
+	{0x110B, "Unrecovered read error - recommend reassignment"},
+	{0x110C, "Unrecovered read error - recommend rewrite the data"},
+	{0x110D, "De-compression CRC error"},
+	{0x110E, "Cannot decompress using declared algorithm"},
+	{0x110F, "Error reading UPC/EAN number"},
+	{0x1110, "Error reading ISRC number"},
+	{0x1111, "Read error - loss of streaming"},
+	{0x1112, "Auxiliary memory read error"},
+	{0x1113, "Read error - failed retransmission request"},
+
+	{0x1200, "Address mark not found for id field"},
+
+	{0x1300, "Address mark not found for data field"},
+
+	{0x1400, "Recorded entity not found"},
+	{0x1401, "Record not found"},
+	{0x1402, "Filemark or setmark not found"},
+	{0x1403, "End-of-data not found"},
+	{0x1404, "Block sequence error"},
+	{0x1405, "Record not found - recommend reassignment"},
+	{0x1406, "Record not found - data auto-reallocated"},
+	{0x1407, "Locate operation failure"},
+
+	{0x1500, "Random positioning error"},
+	{0x1501, "Mechanical positioning error"},
+	{0x1502, "Positioning error detected by read of medium"},
+
+	{0x1600, "Data synchronization mark error"},
+	{0x1601, "Data sync error - data rewritten"},
+	{0x1602, "Data sync error - recommend rewrite"},
+	{0x1603, "Data sync error - data auto-reallocated"},
+	{0x1604, "Data sync error - recommend reassignment"},
+
+	{0x1700, "Recovered data with no error correction applied"},
+	{0x1701, "Recovered data with retries"},
+	{0x1702, "Recovered data with positive head offset"},
+	{0x1703, "Recovered data with negative head offset"},
+	{0x1704, "Recovered data with retries and/or circ applied"},
+	{0x1705, "Recovered data using previous sector id"},
+	{0x1706, "Recovered data without ECC - data auto-reallocated"},
+	{0x1707, "Recovered data without ECC - recommend reassignment"},
+	{0x1708, "Recovered data without ECC - recommend rewrite"},
+	{0x1709, "Recovered data without ECC - data rewritten"},
+
+	{0x1800, "Recovered data with error correction applied"},
+	{0x1801, "Recovered data with error corr. & retries applied"},
+	{0x1802, "Recovered data - data auto-reallocated"},
+	{0x1803, "Recovered data with CIRC"},
+	{0x1804, "Recovered data with L-EC"},
+	{0x1805, "Recovered data - recommend reassignment"},
+	{0x1806, "Recovered data - recommend rewrite"},
+	{0x1807, "Recovered data with ECC - data rewritten"},
+	{0x1808, "Recovered data with linking"},
+
+	{0x1900, "Defect list error"},
+	{0x1901, "Defect list not available"},
+	{0x1902, "Defect list error in primary list"},
+	{0x1903, "Defect list error in grown list"},
+
+	{0x1A00, "Parameter list length error"},
+
+	{0x1B00, "Synchronous data transfer error"},
+
+	{0x1C00, "Defect list not found"},
+	{0x1C01, "Primary defect list not found"},
+	{0x1C02, "Grown defect list not found"},
+
+	{0x1D00, "Miscompare during verify operation"},
+
+	{0x1E00, "Recovered id with ECC correction"},
+
+	{0x1F00, "Partial defect list transfer"},
+
+	{0x2000, "Invalid command operation code"},
+	{0x2001, "Access denied - initiator pending-enrolled"},
+	{0x2002, "Access denied - no access rights"},
+	{0x2003, "Access denied - invalid mgmt id key"},
+	{0x2004, "Illegal command while in write capable state"},
+	{0x2005, "Obsolete"},
+	{0x2006, "Illegal command while in explicit address mode"},
+	{0x2007, "Illegal command while in implicit address mode"},
+	{0x2008, "Access denied - enrollment conflict"},
+	{0x2009, "Access denied - invalid LU identifier"},
+	{0x200A, "Access denied - invalid proxy token"},
+	{0x200B, "Access denied - ACL LUN conflict"},
+
+	{0x2100, "Logical block address out of range"},
+	{0x2101, "Invalid element address"},
+	{0x2102, "Invalid address for write"},
+
+	{0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"},
+
+	{0x2400, "Invalid field in cdb"},
+	{0x2401, "CDB decryption error"},
+	{0x2402, "Obsolete"},
+	{0x2403, "Obsolete"},
+
+	{0x2500, "Logical unit not supported"},
+
+	{0x2600, "Invalid field in parameter list"},
+	{0x2601, "Parameter not supported"},
+	{0x2602, "Parameter value invalid"},
+	{0x2603, "Threshold parameters not supported"},
+	{0x2604, "Invalid release of persistent reservation"},
+	{0x2605, "Data decryption error"},
+	{0x2606, "Too many target descriptors"},
+	{0x2607, "Unsupported target descriptor type code"},
+	{0x2608, "Too many segment descriptors"},
+	{0x2609, "Unsupported segment descriptor type code"},
+	{0x260A, "Unexpected inexact segment"},
+	{0x260B, "Inline data length exceeded"},
+	{0x260C, "Invalid operation for copy source or destination"},
+	{0x260D, "Copy segment granularity violation"},
+
+	{0x2700, "Write protected"},
+	{0x2701, "Hardware write protected"},
+	{0x2702, "Logical unit software write protected"},
+	{0x2703, "Associated write protect"},
+	{0x2704, "Persistent write protect"},
+	{0x2705, "Permanent write protect"},
+	{0x2706, "Conditional write protect"},
+
+	{0x2800, "Not ready to ready change, medium may have changed"},
+	{0x2801, "Import or export element accessed"},
+
+	{0x2900, "Power on, reset, or bus device reset occurred"},
+	{0x2901, "Power on occurred"},
+	{0x2902, "Scsi bus reset occurred"},
+	{0x2903, "Bus device reset function occurred"},
+	{0x2904, "Device internal reset"},
+	{0x2905, "Transceiver mode changed to single-ended"},
+	{0x2906, "Transceiver mode changed to lvd"},
+	{0x2907, "I_T nexus loss occurred"},
+
+	{0x2A00, "Parameters changed"},
+	{0x2A01, "Mode parameters changed"},
+	{0x2A02, "Log parameters changed"},
+	{0x2A03, "Reservations preempted"},
+	{0x2A04, "Reservations released"},
+	{0x2A05, "Registrations preempted"},
+	{0x2A06, "Asymmetric access state changed"},
+	{0x2A07, "Implicit asymmetric access state transition failed"},
+
+	{0x2B00, "Copy cannot execute since host cannot disconnect"},
+
+	{0x2C00, "Command sequence error"},
+	{0x2C01, "Too many windows specified"},
+	{0x2C02, "Invalid combination of windows specified"},
+	{0x2C03, "Current program area is not empty"},
+	{0x2C04, "Current program area is empty"},
+	{0x2C05, "Illegal power condition request"},
+	{0x2C06, "Persistent prevent conflict"},
+	{0x2C07, "Previous busy status"},
+	{0x2C08, "Previous task set full status"},
+	{0x2C09, "Previous reservation conflict status"},
+
+	{0x2D00, "Overwrite error on update in place"},
+
+	{0x2E00, "Insufficient time for operation"},
+
+	{0x2F00, "Commands cleared by another initiator"},
+
+	{0x3000, "Incompatible medium installed"},
+	{0x3001, "Cannot read medium - unknown format"},
+	{0x3002, "Cannot read medium - incompatible format"},
+	{0x3003, "Cleaning cartridge installed"},
+	{0x3004, "Cannot write medium - unknown format"},
+	{0x3005, "Cannot write medium - incompatible format"},
+	{0x3006, "Cannot format medium - incompatible medium"},
+	{0x3007, "Cleaning failure"},
+	{0x3008, "Cannot write - application code mismatch"},
+	{0x3009, "Current session not fixated for append"},
+	{0x3010, "Medium not formatted"},
+
+	{0x3100, "Medium format corrupted"},
+	{0x3101, "Format command failed"},
+	{0x3102, "Zoned formatting failed due to spare linking"},
+
+	{0x3200, "No defect spare location available"},
+	{0x3201, "Defect list update failure"},
+
+	{0x3300, "Tape length error"},
+
+	{0x3400, "Enclosure failure"},
+
+	{0x3500, "Enclosure services failure"},
+	{0x3501, "Unsupported enclosure function"},
+	{0x3502, "Enclosure services unavailable"},
+	{0x3503, "Enclosure services transfer failure"},
+	{0x3504, "Enclosure services transfer refused"},
+
+	{0x3600, "Ribbon, ink, or toner failure"},
+
+	{0x3700, "Rounded parameter"},
+
+	{0x3800, "Event status notification"},
+	{0x3802, "Esn - power management class event"},
+	{0x3804, "Esn - media class event"},
+	{0x3806, "Esn - device busy class event"},
+
+	{0x3900, "Saving parameters not supported"},
+
+	{0x3A00, "Medium not present"},
+	{0x3A01, "Medium not present - tray closed"},
+	{0x3A02, "Medium not present - tray open"},
+	{0x3A03, "Medium not present - loadable"},
+	{0x3A04, "Medium not present - medium auxiliary memory accessible"},
+
+	{0x3B00, "Sequential positioning error"},
+	{0x3B01, "Tape position error at beginning-of-medium"},
+	{0x3B02, "Tape position error at end-of-medium"},
+	{0x3B03, "Tape or electronic vertical forms unit not ready"},
+	{0x3B04, "Slew failure"},
+	{0x3B05, "Paper jam"},
+	{0x3B06, "Failed to sense top-of-form"},
+	{0x3B07, "Failed to sense bottom-of-form"},
+	{0x3B08, "Reposition error"},
+	{0x3B09, "Read past end of medium"},
+	{0x3B0A, "Read past beginning of medium"},
+	{0x3B0B, "Position past end of medium"},
+	{0x3B0C, "Position past beginning of medium"},
+	{0x3B0D, "Medium destination element full"},
+	{0x3B0E, "Medium source element empty"},
+	{0x3B0F, "End of medium reached"},
+	{0x3B11, "Medium magazine not accessible"},
+	{0x3B12, "Medium magazine removed"},
+	{0x3B13, "Medium magazine inserted"},
+	{0x3B14, "Medium magazine locked"},
+	{0x3B15, "Medium magazine unlocked"},
+	{0x3B16, "Mechanical positioning or changer error"},
+
+	{0x3D00, "Invalid bits in identify message"},
+
+	{0x3E00, "Logical unit has not self-configured yet"},
+	{0x3E01, "Logical unit failure"},
+	{0x3E02, "Timeout on logical unit"},
+	{0x3E03, "Logical unit failed self-test"},
+	{0x3E04, "Logical unit unable to update self-test log"},
+
+	{0x3F00, "Target operating conditions have changed"},
+	{0x3F01, "Microcode has been changed"},
+	{0x3F02, "Changed operating definition"},
+	{0x3F03, "Inquiry data has changed"},
+	{0x3F04, "Component device attached"},
+	{0x3F05, "Device identifier changed"},
+	{0x3F06, "Redundancy group created or modified"},
+	{0x3F07, "Redundancy group deleted"},
+	{0x3F08, "Spare created or modified"},
+	{0x3F09, "Spare deleted"},
+	{0x3F0A, "Volume set created or modified"},
+	{0x3F0B, "Volume set deleted"},
+	{0x3F0C, "Volume set deassigned"},
+	{0x3F0D, "Volume set reassigned"},
+	{0x3F0E, "Reported luns data has changed"},
+	{0x3F0F, "Echo buffer overwritten"},
+	{0x3F10, "Medium loadable"},
+	{0x3F11, "Medium auxiliary memory accessible"},
+
+#if 0
+	{0x40NN, "Ram failure"},
+	{0x40NN, "Diagnostic failure on component nn"},
+	{0x41NN, "Data path failure"},
+	{0x42NN, "Power-on or self-test failure"},
+#endif
+
+	{0x4300, "Message error"},
+
+	{0x4400, "Internal target failure"},
+
+	{0x4500, "Select or reselect failure"},
+
+	{0x4600, "Unsuccessful soft reset"},
+
+	{0x4700, "Scsi parity error"},
+	{0x4701, "Data phase CRC error detected"},
+	{0x4702, "Scsi parity error detected during st data phase"},
+	{0x4703, "Information unit CRC error detected"},
+	{0x4704, "Asynchronous information protection error detected"},
+	{0x4705, "Protocol service CRC error"},
+
+	{0x4800, "Initiator detected error message received"},
+
+	{0x4900, "Invalid message error"},
+
+	{0x4A00, "Command phase error"},
+
+	{0x4B00, "Data phase error"},
+
+	{0x4C00, "Logical unit failed self-configuration"},
+
+#if 0
+	{0x4DNN, "Tagged overlapped commands (nn = queue tag)"},
+#endif
+
+	{0x4E00, "Overlapped commands attempted"},
+
+	{0x5000, "Write append error"},
+	{0x5001, "Write append position error"},
+	{0x5002, "Position error related to timing"},
+
+	{0x5100, "Erase failure"},
+	{0x5101, "Erase failure - incomplete erase operation detected"},
+
+	{0x5200, "Cartridge fault"},
+
+	{0x5300, "Media load or eject failed"},
+	{0x5301, "Unload tape failure"},
+	{0x5302, "Medium removal prevented"},
+
+	{0x5400, "Scsi to host system interface failure"},
+
+	{0x5500, "System resource failure"},
+	{0x5501, "System buffer full"},
+	{0x5502, "Insufficient reservation resources"},
+	{0x5503, "Insufficient resources"},
+	{0x5504, "Insufficient registration resources"},
+	{0x5505, "Insufficient access control resources"},
+	{0x5506, "Auxiliary memory out of space"},
+
+	{0x5700, "Unable to recover table-of-contents"},
+
+	{0x5800, "Generation does not exist"},
+
+	{0x5900, "Updated block read"},
+
+	{0x5A00, "Operator request or state change input"},
+	{0x5A01, "Operator medium removal request"},
+	{0x5A02, "Operator selected write protect"},
+	{0x5A03, "Operator selected write permit"},
+
+	{0x5B00, "Log exception"},
+	{0x5B01, "Threshold condition met"},
+	{0x5B02, "Log counter at maximum"},
+	{0x5B03, "Log list codes exhausted"},
+
+	{0x5C00, "Rpl status change"},
+	{0x5C01, "Spindles synchronized"},
+	{0x5C02, "Spindles not synchronized"},
+
+	{0x5D00, "Failure prediction threshold exceeded"},
+	{0x5D01, "Media failure prediction threshold exceeded"},
+	{0x5D02, "Logical unit failure prediction threshold exceeded"},
+	{0x5D03, "Spare area exhaustion prediction threshold exceeded"},
+	{0x5D10, "Hardware impending failure general hard drive failure"},
+	{0x5D11, "Hardware impending failure drive error rate too high"},
+	{0x5D12, "Hardware impending failure data error rate too high"},
+	{0x5D13, "Hardware impending failure seek error rate too high"},
+	{0x5D14, "Hardware impending failure too many block reassigns"},
+	{0x5D15, "Hardware impending failure access times too high"},
+	{0x5D16, "Hardware impending failure start unit times too high"},
+	{0x5D17, "Hardware impending failure channel parametrics"},
+	{0x5D18, "Hardware impending failure controller detected"},
+	{0x5D19, "Hardware impending failure throughput performance"},
+	{0x5D1A, "Hardware impending failure seek time performance"},
+	{0x5D1B, "Hardware impending failure spin-up retry count"},
+	{0x5D1C, "Hardware impending failure drive calibration retry count"},
+	{0x5D20, "Controller impending failure general hard drive failure"},
+	{0x5D21, "Controller impending failure drive error rate too high"},
+	{0x5D22, "Controller impending failure data error rate too high"},
+	{0x5D23, "Controller impending failure seek error rate too high"},
+	{0x5D24, "Controller impending failure too many block reassigns"},
+	{0x5D25, "Controller impending failure access times too high"},
+	{0x5D26, "Controller impending failure start unit times too high"},
+	{0x5D27, "Controller impending failure channel parametrics"},
+	{0x5D28, "Controller impending failure controller detected"},
+	{0x5D29, "Controller impending failure throughput performance"},
+	{0x5D2A, "Controller impending failure seek time performance"},
+	{0x5D2B, "Controller impending failure spin-up retry count"},
+	{0x5D2C, "Controller impending failure drive calibration retry count"},
+	{0x5D30, "Data channel impending failure general hard drive failure"},
+	{0x5D31, "Data channel impending failure drive error rate too high"},
+	{0x5D32, "Data channel impending failure data error rate too high"},
+	{0x5D33, "Data channel impending failure seek error rate too high"},
+	{0x5D34, "Data channel impending failure too many block reassigns"},
+	{0x5D35, "Data channel impending failure access times too high"},
+	{0x5D36, "Data channel impending failure start unit times too high"},
+	{0x5D37, "Data channel impending failure channel parametrics"},
+	{0x5D38, "Data channel impending failure controller detected"},
+	{0x5D39, "Data channel impending failure throughput performance"},
+	{0x5D3A, "Data channel impending failure seek time performance"},
+	{0x5D3B, "Data channel impending failure spin-up retry count"},
+	{0x5D3C, "Data channel impending failure drive calibration retry "
+	 "count"},
+	{0x5D40, "Servo impending failure general hard drive failure"},
+	{0x5D41, "Servo impending failure drive error rate too high"},
+	{0x5D42, "Servo impending failure data error rate too high"},
+	{0x5D43, "Servo impending failure seek error rate too high"},
+	{0x5D44, "Servo impending failure too many block reassigns"},
+	{0x5D45, "Servo impending failure access times too high"},
+	{0x5D46, "Servo impending failure start unit times too high"},
+	{0x5D47, "Servo impending failure channel parametrics"},
+	{0x5D48, "Servo impending failure controller detected"},
+	{0x5D49, "Servo impending failure throughput performance"},
+	{0x5D4A, "Servo impending failure seek time performance"},
+	{0x5D4B, "Servo impending failure spin-up retry count"},
+	{0x5D4C, "Servo impending failure drive calibration retry count"},
+	{0x5D50, "Spindle impending failure general hard drive failure"},
+	{0x5D51, "Spindle impending failure drive error rate too high"},
+	{0x5D52, "Spindle impending failure data error rate too high"},
+	{0x5D53, "Spindle impending failure seek error rate too high"},
+	{0x5D54, "Spindle impending failure too many block reassigns"},
+	{0x5D55, "Spindle impending failure access times too high"},
+	{0x5D56, "Spindle impending failure start unit times too high"},
+	{0x5D57, "Spindle impending failure channel parametrics"},
+	{0x5D58, "Spindle impending failure controller detected"},
+	{0x5D59, "Spindle impending failure throughput performance"},
+	{0x5D5A, "Spindle impending failure seek time performance"},
+	{0x5D5B, "Spindle impending failure spin-up retry count"},
+	{0x5D5C, "Spindle impending failure drive calibration retry count"},
+	{0x5D60, "Firmware impending failure general hard drive failure"},
+	{0x5D61, "Firmware impending failure drive error rate too high"},
+	{0x5D62, "Firmware impending failure data error rate too high"},
+	{0x5D63, "Firmware impending failure seek error rate too high"},
+	{0x5D64, "Firmware impending failure too many block reassigns"},
+	{0x5D65, "Firmware impending failure access times too high"},
+	{0x5D66, "Firmware impending failure start unit times too high"},
+	{0x5D67, "Firmware impending failure channel parametrics"},
+	{0x5D68, "Firmware impending failure controller detected"},
+	{0x5D69, "Firmware impending failure throughput performance"},
+	{0x5D6A, "Firmware impending failure seek time performance"},
+	{0x5D6B, "Firmware impending failure spin-up retry count"},
+	{0x5D6C, "Firmware impending failure drive calibration retry count"},
+	{0x5DFF, "Failure prediction threshold exceeded (false)"},
+
+	{0x5E00, "Low power condition on"},
+	{0x5E01, "Idle condition activated by timer"},
+	{0x5E02, "Standby condition activated by timer"},
+	{0x5E03, "Idle condition activated by command"},
+	{0x5E04, "Standby condition activated by command"},
+	{0x5E41, "Power state change to active"},
+	{0x5E42, "Power state change to idle"},
+	{0x5E43, "Power state change to standby"},
+	{0x5E45, "Power state change to sleep"},
+	{0x5E47, "Power state change to device control"},
+
+	{0x6000, "Lamp failure"},
+
+	{0x6100, "Video acquisition error"},
+	{0x6101, "Unable to acquire video"},
+	{0x6102, "Out of focus"},
+
+	{0x6200, "Scan head positioning error"},
+
+	{0x6300, "End of user area encountered on this track"},
+	{0x6301, "Packet does not fit in available space"},
+
+	{0x6400, "Illegal mode for this track"},
+	{0x6401, "Invalid packet size"},
+
+	{0x6500, "Voltage fault"},
+
+	{0x6600, "Automatic document feeder cover up"},
+	{0x6601, "Automatic document feeder lift up"},
+	{0x6602, "Document jam in automatic document feeder"},
+	{0x6603, "Document miss feed automatic in document feeder"},
+
+	{0x6700, "Configuration failure"},
+	{0x6701, "Configuration of incapable logical units failed"},
+	{0x6702, "Add logical unit failed"},
+	{0x6703, "Modification of logical unit failed"},
+	{0x6704, "Exchange of logical unit failed"},
+	{0x6705, "Remove of logical unit failed"},
+	{0x6706, "Attachment of logical unit failed"},
+	{0x6707, "Creation of logical unit failed"},
+	{0x6708, "Assign failure occurred"},
+	{0x6709, "Multiply assigned logical unit"},
+	{0x670A, "Set target port groups command failed"},
+
+	{0x6800, "Logical unit not configured"},
+
+	{0x6900, "Data loss on logical unit"},
+	{0x6901, "Multiple logical unit failures"},
+	{0x6902, "Parity/data mismatch"},
+
+	{0x6A00, "Informational, refer to log"},
+
+	{0x6B00, "State change has occurred"},
+	{0x6B01, "Redundancy level got better"},
+	{0x6B02, "Redundancy level got worse"},
+
+	{0x6C00, "Rebuild failure occurred"},
+
+	{0x6D00, "Recalculate failure occurred"},
+
+	{0x6E00, "Command to logical unit failed"},
+
+	{0x6F00, "Copy protection key exchange failure - authentication "
+	 "failure"},
+	{0x6F01, "Copy protection key exchange failure - key not present"},
+	{0x6F02, "Copy protection key exchange failure - key not established"},
+	{0x6F03, "Read of scrambled sector without authentication"},
+	{0x6F04, "Media region code is mismatched to logical unit region"},
+	{0x6F05, "Drive region must be permanent/region reset count error"},
+
+#if 0
+	{0x70NN, "Decompression exception short algorithm id of nn"},
+#endif
+
+	{0x7100, "Decompression exception long algorithm id"},
+
+	{0x7200, "Session fixation error"},
+	{0x7201, "Session fixation error writing lead-in"},
+	{0x7202, "Session fixation error writing lead-out"},
+	{0x7203, "Session fixation error - incomplete track in session"},
+	{0x7204, "Empty or partially written reserved track"},
+	{0x7205, "No more track reservations allowed"},
+
+	{0x7300, "Cd control error"},
+	{0x7301, "Power calibration area almost full"},
+	{0x7302, "Power calibration area is full"},
+	{0x7303, "Power calibration area error"},
+	{0x7304, "Program memory area update failure"},
+	{0x7305, "Program memory area is full"},
+	{0x7306, "RMA/PMA is almost full"},
+	{0, NULL}
 };
 
-static struct error_info additional[] =
+struct error_info2 {
+	unsigned char code1, code2_min, code2_max;
+	const char * fmt;
+};
+
+static struct error_info2 additional2[] =
 {
-  {0x00,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"No additional sense information"},
-  {0x00,0x01,T,"Filemark detected"},
-  {0x00,0x02,T|S,"End-of-partition/medium detected"},
-  {0x00,0x03,T,"Setmark detected"},
-  {0x00,0x04,T|S,"Beginning-of-partition/medium detected"},
-  {0x00,0x05,T|L|S,"End-of-data detected"},
-  {0x00,0x06,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"I/O process terminated"},
-  {0x00,0x11,R,"Audio play operation in progress"},
-  {0x00,0x12,R,"Audio play operation paused"},
-  {0x00,0x13,R,"Audio play operation successfully completed"},
-  {0x00,0x14,R,"Audio play operation stopped due to error"},
-  {0x00,0x15,R,"No current audio status to return"},
-  {0x00,0x16,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Operation in progress"},
-  {0x00,0x17,D|T|L|W|R|S|O|M|A|E|B|K,"Cleaning requested"},
-  {0x01,0x00,D|W|O|B|K,"No index/sector signal"},
-  {0x02,0x00,D|W|R|O|M|B|K,"No seek complete"},
-  {0x03,0x00,D|T|L|W|S|O|B|K,"Peripheral device write fault"},
-  {0x03,0x01,T,"No write current"},
-  {0x03,0x02,T,"Excessive write errors"},
-  {0x04,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit not ready,cause not reportable"},
-  {0x04,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit is in process of becoming ready"},
-  {0x04,0x02,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit not ready,initializing cmd. required"},
-  {0x04,0x03,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit not ready,manual intervention required"},
-  {0x04,0x04,D|T|L|R|O|B,"Logical unit not ready,format in progress"},
-  {0x04,0x05,D|T|W|O|M|C|A|B|K,"Logical unit not ready,rebuild in progress"},
-  {0x04,0x06,D|T|W|O|M|C|A|B|K,"Logical unit not ready,recalculation in progress"},
-  {0x04,0x07,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit not ready,operation in progress"},
-  {0x04,0x08,R,"Logical unit not ready,long write in progress"},
-  {0x04,0x09,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit not ready,self-test in progress"},
-  {0x05,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Logical unit does not respond to selection"},
-  {0x06,0x00,D|W|R|O|M|B|K,"No reference position found"},
-  {0x07,0x00,D|T|L|W|R|S|O|M|B|K,"Multiple peripheral devices selected"},
-  {0x08,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Logical unit communication failure"},
-  {0x08,0x01,D|T|L|W|R|S|O|M|C|A|E|B|K,"Logical unit communication time-out"},
-  {0x08,0x02,D|T|L|W|R|S|O|M|C|A|E|B|K,"Logical unit communication parity error"},
-  {0x08,0x03,D|T|R|O|M|B|K,"Logical unit communication CRC error (Ultra-DMA/32)"},
-  {0x08,0x04,D|T|L|P|W|R|S|O|C|K,"Unreachable copy target"},
-  {0x09,0x00,D|T|W|R|O|B,"Track following error"},
-  {0x09,0x01,W|R|O|K,"Tracking servo failure"},
-  {0x09,0x02,W|R|O|K,"Focus servo failure"},
-  {0x09,0x03,W|R|O,"Spindle servo failure"},
-  {0x09,0x04,D|T|W|R|O|B,"Head select fault"},
-  {0x0A,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Error log overflow"},
-  {0x0B,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Warning"},
-  {0x0B,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Warning - specified temperature exceeded"},
-  {0x0B,0x02,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Warning - enclosure degraded"},
-  {0x0C,0x00,T|R|S,"Write error"},
-  {0x0C,0x01,K,"Write error - recovered with auto reallocation"},
-  {0x0C,0x02,D|W|O|B|K,"Write error - auto reallocation failed"},
-  {0x0C,0x03,D|W|O|B|K,"Write error - recommend reassignment"},
-  {0x0C,0x04,D|T|W|O|B,"Compression check miscompare error"},
-  {0x0C,0x05,D|T|W|O|B,"Data expansion occurred during compression"},
-  {0x0C,0x06,D|T|W|O|B,"Block not compressible"},
-  {0x0C,0x07,R,"Write error - recovery needed"},
-  {0x0C,0x08,R,"Write error - recovery failed"},
-  {0x0C,0x09,R,"Write error - loss of streaming"},
-  {0x0C,0x0A,R,"Write error - padding blocks added"},
-  {0x10,0x00,D|W|O|B|K,"Id CRC or ECC error"},
-  {0x11,0x00,D|T|W|R|S|O|B|K,"Unrecovered read error"},
-  {0x11,0x01,D|T|W|R|S|O|B|K,"Read retries exhausted"},
-  {0x11,0x02,D|T|W|R|S|O|B|K,"Error too long to correct"},
-  {0x11,0x03,D|T|W|S|O|B|K,"Multiple read errors"},
-  {0x11,0x04,D|W|O|B|K,"Unrecovered read error - auto reallocate failed"},
-  {0x11,0x05,W|R|O|B,"L-EC uncorrectable error"},
-  {0x11,0x06,W|R|O|B,"CIRC unrecovered error"},
-  {0x11,0x07,W|O|B,"Data re-synchronization error"},
-  {0x11,0x08,T,"Incomplete block read"},
-  {0x11,0x09,T,"No gap found"},
-  {0x11,0x0A,D|T|O|B|K,"Miscorrected error"},
-  {0x11,0x0B,D|W|O|B|K,"Unrecovered read error - recommend reassignment"},
-  {0x11,0x0C,D|W|O|B|K,"Unrecovered read error - recommend rewrite the data"},
-  {0x11,0x0D,D|T|W|R|O|B,"De-compression CRC error"},
-  {0x11,0x0E,D|T|W|R|O|B,"Cannot decompress using declared algorithm"},
-  {0x11,0x0F,R,"Error reading UPC/EAN number"},
-  {0x11,0x10,R,"Error reading ISRC number"},
-  {0x11,0x11,R,"Read error - loss of streaming"},
-  {0x12,0x00,D|W|O|B|K,"Address mark not found for id field"},
-  {0x13,0x00,D|W|O|B|K,"Address mark not found for data field"},
-  {0x14,0x00,D|T|L|W|R|S|O|B|K,"Recorded entity not found"},
-  {0x14,0x01,D|T|W|R|O|B|K,"Record not found"},
-  {0x14,0x02,T,"Filemark or setmark not found"},
-  {0x14,0x03,T,"End-of-data not found"},
-  {0x14,0x04,T,"Block sequence error"},
-  {0x14,0x05,D|T|W|O|B|K,"Record not found - recommend reassignment"},
-  {0x14,0x06,D|T|W|O|B|K,"Record not found - data auto-reallocated"},
-  {0x15,0x00,D|T|L|W|R|S|O|M|B|K,"Random positioning error"},
-  {0x15,0x01,D|T|L|W|R|S|O|M|B|K,"Mechanical positioning error"},
-  {0x15,0x02,D|T|W|R|O|B|K,"Positioning error detected by read of medium"},
-  {0x16,0x00,D|W|O|B|K,"Data synchronization mark error"},
-  {0x16,0x01,D|W|O|B|K,"Data sync error - data rewritten"},
-  {0x16,0x02,D|W|O|B|K,"Data sync error - recommend rewrite"},
-  {0x16,0x03,D|W|O|B|K,"Data sync error - data auto-reallocated"},
-  {0x16,0x04,D|W|O|B|K,"Data sync error - recommend reassignment"},
-  {0x17,0x00,D|T|W|R|S|O|B|K,"Recovered data with no error correction applied"},
-  {0x17,0x01,D|T|W|R|S|O|B|K,"Recovered data with retries"},
-  {0x17,0x02,D|T|W|R|O|B|K,"Recovered data with positive head offset"},
-  {0x17,0x03,D|T|W|R|O|B|K,"Recovered data with negative head offset"},
-  {0x17,0x04,W|R|O|B,"Recovered data with retries and/or circ applied"},
-  {0x17,0x05,D|W|R|O|B|K,"Recovered data using previous sector id"},
-  {0x17,0x06,D|W|O|B|K,"Recovered data without ecc - data auto-reallocated"},
-  {0x17,0x07,D|W|R|O|B|K,"Recovered data without ecc - recommend reassignment"},
-  {0x17,0x08,D|W|R|O|B|K,"Recovered data without ecc - recommend rewrite"},
-  {0x17,0x09,D|W|R|O|B|K,"Recovered data without ecc - data rewritten"},
-  {0x18,0x00,D|T|W|R|O|B|K,"Recovered data with error correction applied"},
-  {0x18,0x01,D|W|R|O|B|K,"Recovered data with error corr. & retries applied"},
-  {0x18,0x02,D|W|R|O|B|K,"Recovered data - data auto-reallocated"},
-  {0x18,0x03,R,"Recovered data with CIRC"},
-  {0x18,0x04,R,"Recovered data with L-EC"},
-  {0x18,0x05,D|W|R|O|B|K,"Recovered data - recommend reassignment"},
-  {0x18,0x06,D|W|R|O|B|K,"Recovered data - recommend rewrite"},
-  {0x18,0x07,D|W|O|B|K,"Recovered data with ecc - data rewritten"},
-  {0x19,0x00,D|O|K,"Defect list error"},
-  {0x19,0x01,D|O|K,"Defect list not available"},
-  {0x19,0x02,D|O|K,"Defect list error in primary list"},
-  {0x19,0x03,D|O|K,"Defect list error in grown list"},
-  {0x1A,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Parameter list length error"},
-  {0x1B,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Synchronous data transfer error"},
-  {0x1C,0x00,D|O|B|K,"Defect list not found"},
-  {0x1C,0x01,D|O|B|K,"Primary defect list not found"},
-  {0x1C,0x02,D|O|B|K,"Grown defect list not found"},
-  {0x1D,0x00,D|T|W|R|O|B|K,"Miscompare during verify operation"},
-  {0x1E,0x00,D|W|O|B|K,"Recovered id with ecc correction"},
-  {0x1F,0x00,D|O|K,"Partial defect list transfer"},
-  {0x20,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Invalid command operation code"},
-  {0x21,0x00,D|T|W|R|O|M|B|K,"Logical block address out of range"},
-  {0x21,0x01,D|T|W|R|O|M|B|K,"Invalid element address"},
-  {0x22,0x00,D,"Illegal function (use 20 00,24 00,or 26 00)"},
-  {0x24,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Invalid field in cdb"},
-  {0x24,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"CDB decryption error"},
-  {0x25,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit not supported"},
-  {0x26,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Invalid field in parameter list"},
-  {0x26,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Parameter not supported"},
-  {0x26,0x02,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Parameter value invalid"},
-  {0x26,0x03,D|T|L|P|W|R|S|O|M|C|A|E|K,"Threshold parameters not supported"},
-  {0x26,0x04,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Invalid release of persistent reservation"},
-  {0x26,0x05,D|T|L|P|W|R|S|O|M|C|A|B|K,"Data decryption error"},
-  {0x26,0x06,D|T|L|P|W|R|S|O|C|K,"Too many target descriptors"},
-  {0x26,0x07,D|T|L|P|W|R|S|O|C|K,"Unsupported target descriptor type code"},
-  {0x26,0x08,D|T|L|P|W|R|S|O|C|K,"Too many segment descriptors"},
-  {0x26,0x09,D|T|L|P|W|R|S|O|C|K,"Unsupported segment descriptor type code"},
-  {0x26,0x0A,D|T|L|P|W|R|S|O|C|K,"Unexpected inexact segment"},
-  {0x26,0x0B,D|T|L|P|W|R|S|O|C|K,"Inline data length exceeded"},
-  {0x26,0x0C,D|T|L|P|W|R|S|O|C|K,"Invalid operation for copy source or destination"},
-  {0x26,0x0D,D|T|L|P|W|R|S|O|C|K,"Copy segment granularity violation"},
-  {0x27,0x00,D|T|W|R|O|B|K,"Write protected"},
-  {0x27,0x01,D|T|W|R|O|B|K,"Hardware write protected"},
-  {0x27,0x02,D|T|W|R|O|B|K,"Logical unit software write protected"},
-  {0x27,0x03,T|R,"Associated write protect"},
-  {0x27,0x04,T|R,"Persistent write protect"},
-  {0x27,0x05,T|R,"Permanent write protect"},
-  {0x28,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Not ready to ready change,medium may have changed"},
-  {0x28,0x01,D|T|W|R|O|M|B,"Import or export element accessed"},
-  {0x29,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Power on,reset,or bus device reset occurred"},
-  {0x29,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Power on occurred"},
-  {0x29,0x02,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Scsi bus reset occurred"},
-  {0x29,0x03,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Bus device reset function occurred"},
-  {0x29,0x04,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Device internal reset"},
-  {0x29,0x05,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Transceiver mode changed to single-ended"},
-  {0x29,0x06,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Transceiver mode changed to lvd"},
-  {0x2A,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Parameters changed"},
-  {0x2A,0x01,D|T|L|W|R|S|O|M|C|A|E|B|K,"Mode parameters changed"},
-  {0x2A,0x02,D|T|L|W|R|S|O|M|C|A|E|K,"Log parameters changed"},
-  {0x2A,0x03,D|T|L|P|W|R|S|O|M|C|A|E|K,"Reservations preempted"},
-  {0x2A,0x04,D|T|L|P|W|R|S|O|M|C|A|E,"Reservations released"},
-  {0x2A,0x05,D|T|L|P|W|R|S|O|M|C|A|E,"Registrations preempted"},
-  {0x2B,0x00,D|T|L|P|W|R|S|O|C|K,"Copy cannot execute since host cannot disconnect"},
-  {0x2C,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Command sequence error"},
-  {0x2C,0x01,S,"Too many windows specified"},
-  {0x2C,0x02,S,"Invalid combination of windows specified"},
-  {0x2C,0x03,R,"Current program area is not empty"},
-  {0x2C,0x04,R,"Current program area is empty"},
-  {0x2C,0x05,B,"Illegal power condition request"},
-  {0x2D,0x00,T,"Overwrite error on update in place"},
-  {0x2F,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Commands cleared by another initiator"},
-  {0x30,0x00,D|T|W|R|O|M|B|K,"Incompatible medium installed"},
-  {0x30,0x01,D|T|W|R|O|B|K,"Cannot read medium - unknown format"},
-  {0x30,0x02,D|T|W|R|O|B|K,"Cannot read medium - incompatible format"},
-  {0x30,0x03,D|T|R|K,"Cleaning cartridge installed"},
-  {0x30,0x04,D|T|W|R|O|B|K,"Cannot write medium - unknown format"},
-  {0x30,0x05,D|T|W|R|O|B|K,"Cannot write medium - incompatible format"},
-  {0x30,0x06,D|T|W|R|O|B,"Cannot format medium - incompatible medium"},
-  {0x30,0x07,D|T|L|W|R|S|O|M|A|E|B|K,"Cleaning failure"},
-  {0x30,0x08,R,"Cannot write - application code mismatch"},
-  {0x30,0x09,R,"Current session not fixated for append"},
-  {0x31,0x00,D|T|W|R|O|B|K,"Medium format corrupted"},
-  {0x31,0x01,D|L|R|O|B,"Format command failed"},
-  {0x32,0x00,D|W|O|B|K,"No defect spare location available"},
-  {0x32,0x01,D|W|O|B|K,"Defect list update failure"},
-  {0x33,0x00,T,"Tape length error"},
-  {0x34,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Enclosure failure"},
-  {0x35,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Enclosure services failure"},
-  {0x35,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Unsupported enclosure function"},
-  {0x35,0x02,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Enclosure services unavailable"},
-  {0x35,0x03,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Enclosure services transfer failure"},
-  {0x35,0x04,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Enclosure services transfer refused"},
-  {0x36,0x00,L,"Ribbon,ink,or toner failure"},
-  {0x37,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Rounded parameter"},
-  {0x38,0x00,B,"Event status notification"},
-  {0x38,0x02,B,"Esn - power management class event"},
-  {0x38,0x04,B,"Esn - media class event"},
-  {0x38,0x06,B,"Esn - device busy class event"},
-  {0x39,0x00,D|T|L|W|R|S|O|M|C|A|E|K,"Saving parameters not supported"},
-  {0x3A,0x00,D|T|L|W|R|S|O|M|B|K,"Medium not present"},
-  {0x3A,0x01,D|T|W|R|O|M|B|K,"Medium not present - tray closed"},
-  {0x3A,0x02,D|T|W|R|O|M|B|K,"Medium not present - tray open"},
-  {0x3A,0x03,D|T|W|R|O|M|B,"Medium not present - loadable"},
-  {0x3A,0x04,D|T|W|R|O|M|B,"Medium not present - medium auxiliary memory accessible"},
-  {0x3B,0x00,T|L,"Sequential positioning error"},
-  {0x3B,0x01,T,"Tape position error at beginning-of-medium"},
-  {0x3B,0x02,T,"Tape position error at end-of-medium"},
-  {0x3B,0x03,L,"Tape or electronic vertical forms unit not ready"},
-  {0x3B,0x04,L,"Slew failure"},
-  {0x3B,0x05,L,"Paper jam"},
-  {0x3B,0x06,L,"Failed to sense top-of-form"},
-  {0x3B,0x07,L,"Failed to sense bottom-of-form"},
-  {0x3B,0x08,T,"Reposition error"},
-  {0x3B,0x09,S,"Read past end of medium"},
-  {0x3B,0x0A,S,"Read past beginning of medium"},
-  {0x3B,0x0B,S,"Position past end of medium"},
-  {0x3B,0x0C,T|S,"Position past beginning of medium"},
-  {0x3B,0x0D,D|T|W|R|O|M|B|K,"Medium destination element full"},
-  {0x3B,0x0E,D|T|W|R|O|M|B|K,"Medium source element empty"},
-  {0x3B,0x0F,R,"End of medium reached"},
-  {0x3B,0x11,D|T|W|R|O|M|B|K,"Medium magazine not accessible"},
-  {0x3B,0x12,D|T|W|R|O|M|B|K,"Medium magazine removed"},
-  {0x3B,0x13,D|T|W|R|O|M|B|K,"Medium magazine inserted"},
-  {0x3B,0x14,D|T|W|R|O|M|B|K,"Medium magazine locked"},
-  {0x3B,0x15,D|T|W|R|O|M|B|K,"Medium magazine unlocked"},
-  {0x3B,0x16,R,"Mechanical positioning or changer error"},
-  {0x3D,0x00,D|T|L|P|W|R|S|O|M|C|A|E|K,"Invalid bits in identify message"},
-  {0x3E,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit has not self-configured yet"},
-  {0x3E,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit failure"},
-  {0x3E,0x02,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Timeout on logical unit"},
-  {0x3E,0x03,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit failed self-test"},
-  {0x3E,0x04,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit unable to update self-test log"},
-  {0x3F,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Target operating conditions have changed"},
-  {0x3F,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Microcode has been changed"},
-  {0x3F,0x02,D|T|L|P|W|R|S|O|M|C|B|K,"Changed operating definition"},
-  {0x3F,0x03,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Inquiry data has changed"},
-  {0x3F,0x04,D|T|W|R|O|M|C|A|E|B|K,"Component device attached"},
-  {0x3F,0x05,D|T|W|R|O|M|C|A|E|B|K,"Device identifier changed"},
-  {0x3F,0x06,D|T|W|R|O|M|C|A|E|B,"Redundancy group created or modified"},
-  {0x3F,0x07,D|T|W|R|O|M|C|A|E|B,"Redundancy group deleted"},
-  {0x3F,0x08,D|T|W|R|O|M|C|A|E|B,"Spare created or modified"},
-  {0x3F,0x09,D|T|W|R|O|M|C|A|E|B,"Spare deleted"},
-  {0x3F,0x0A,D|T|W|R|O|M|C|A|E|B|K,"Volume set created or modified"},
-  {0x3F,0x0B,D|T|W|R|O|M|C|A|E|B|K,"Volume set deleted"},
-  {0x3F,0x0C,D|T|W|R|O|M|C|A|E|B|K,"Volume set deassigned"},
-  {0x3F,0x0D,D|T|W|R|O|M|C|A|E|B|K,"Volume set reassigned"},
-  {0x3F,0x0E,D|T|L|P|W|R|S|O|M|C|A|E,"Reported luns data has changed"},
-  {0x3F,0x10,D|T|W|R|O|M|B,"Medium loadable"},
-  {0x3F,0x11,D|T|W|R|O|M|B,"Medium auxiliary memory accessible"},
-  {0x40,0x00,D,"Ram failure (should use 40 nn)"},
-  /*
-   * FIXME(eric) - need a way to represent wildcards here.
-   */
-  {0x40,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Diagnostic failure on component nn (80h-ffh)"},
-  {0x41,0x00,D,"Data path failure (should use 40 nn)"},
-  {0x42,0x00,D,"Power-on or self-test failure (should use 40 nn)"},
-  {0x43,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Message error"},
-  {0x44,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Internal target failure"},
-  {0x45,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Select or reselect failure"},
-  {0x46,0x00,D|T|L|P|W|R|S|O|M|C|B|K,"Unsuccessful soft reset"},
-  {0x47,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Scsi parity error"},
-  {0x47,0x01,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Data phase CRC error detected"},
-  {0x47,0x02,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Scsi parity error detected during st data phase"},
-  {0x47,0x03,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Information unit CRC error detected"},
-  {0x47,0x04,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Asynchronous information protection error detected"},
-  {0x48,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Initiator detected error message received"},
-  {0x49,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Invalid message error"},
-  {0x4A,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Command phase error"},
-  {0x4B,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Data phase error"},
-  {0x4C,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Logical unit failed self-configuration"},
-  /*
-   * FIXME(eric) - need a way to represent wildcards here.
-   */
-  {0x4D,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Tagged overlapped commands (nn = queue tag)"},
-  {0x4E,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Overlapped commands attempted"},
-  {0x50,0x00,T,"Write append error"},
-  {0x50,0x01,T,"Write append position error"},
-  {0x50,0x02,T,"Position error related to timing"},
-  {0x51,0x00,T|R|O,"Erase failure"},
-  {0x52,0x00,T,"Cartridge fault"},
-  {0x53,0x00,D|T|L|W|R|S|O|M|B|K,"Media load or eject failed"},
-  {0x53,0x01,T,"Unload tape failure"},
-  {0x53,0x02,D|T|W|R|O|M|B|K,"Medium removal prevented"},
-  {0x54,0x00,P,"Scsi to host system interface failure"},
-  {0x55,0x00,P,"System resource failure"},
-  {0x55,0x01,D|O|B|K,"System buffer full"},
-  {0x55,0x02,D|T|L|P|W|R|S|O|M|A|E|K,"Insufficient reservation resources"},
-  {0x55,0x03,D|T|L|P|W|R|S|O|M|C|A|E,"Insufficient resources"},
-  {0x55,0x04,D|T|L|P|W|R|S|O|M|A|E,"Insufficient registration resources"},
-  {0x57,0x00,R,"Unable to recover table-of-contents"},
-  {0x58,0x00,O,"Generation does not exist"},
-  {0x59,0x00,O,"Updated block read"},
-  {0x5A,0x00,D|T|L|P|W|R|S|O|M|B|K,"Operator request or state change input"},
-  {0x5A,0x01,D|T|W|R|O|M|B|K,"Operator medium removal request"},
-  {0x5A,0x02,D|T|W|R|O|A|B|K,"Operator selected write protect"},
-  {0x5A,0x03,D|T|W|R|O|A|B|K,"Operator selected write permit"},
-  {0x5B,0x00,D|T|L|P|W|R|S|O|M|K,"Log exception"},
-  {0x5B,0x01,D|T|L|P|W|R|S|O|M|K,"Threshold condition met"},
-  {0x5B,0x02,D|T|L|P|W|R|S|O|M|K,"Log counter at maximum"},
-  {0x5B,0x03,D|T|L|P|W|R|S|O|M|K,"Log list codes exhausted"},
-  {0x5C,0x00,D|O,"Rpl status change"},
-  {0x5C,0x01,D|O,"Spindles synchronized"},
-  {0x5C,0x02,D|O,"Spindles not synchronized"},
-  {0x5D,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Failure prediction threshold exceeded"},
-  {0x5D,0x01,R|B,"Media failure prediction threshold exceeded"},
-  {0x5D,0x02,R,"Logical unit failure prediction threshold exceeded"},
-  {0x5D,0x10,D|B,"Hardware impending failure general hard drive failure"},
-  {0x5D,0x11,D|B,"Hardware impending failure drive error rate too high"},
-  {0x5D,0x12,D|B,"Hardware impending failure data error rate too high"},
-  {0x5D,0x13,D|B,"Hardware impending failure seek error rate too high"},
-  {0x5D,0x14,D|B,"Hardware impending failure too many block reassigns"},
-  {0x5D,0x15,D|B,"Hardware impending failure access times too high"},
-  {0x5D,0x16,D|B,"Hardware impending failure start unit times too high"},
-  {0x5D,0x17,D|B,"Hardware impending failure channel parametrics"},
-  {0x5D,0x18,D|B,"Hardware impending failure controller detected"},
-  {0x5D,0x19,D|B,"Hardware impending failure throughput performance"},
-  {0x5D,0x1A,D|B,"Hardware impending failure seek time performance"},
-  {0x5D,0x1B,D|B,"Hardware impending failure spin-up retry count"},
-  {0x5D,0x1C,D|B,"Hardware impending failure drive calibration retry count"},
-  {0x5D,0x20,D|B,"Controller impending failure general hard drive failure"},
-  {0x5D,0x21,D|B,"Controller impending failure drive error rate too high"},
-  {0x5D,0x22,D|B,"Controller impending failure data error rate too high"},
-  {0x5D,0x23,D|B,"Controller impending failure seek error rate too high"},
-  {0x5D,0x24,D|B,"Controller impending failure too many block reassigns"},
-  {0x5D,0x25,D|B,"Controller impending failure access times too high"},
-  {0x5D,0x26,D|B,"Controller impending failure start unit times too high"},
-  {0x5D,0x27,D|B,"Controller impending failure channel parametrics"},
-  {0x5D,0x28,D|B,"Controller impending failure controller detected"},
-  {0x5D,0x29,D|B,"Controller impending failure throughput performance"},
-  {0x5D,0x2A,D|B,"Controller impending failure seek time performance"},
-  {0x5D,0x2B,D|B,"Controller impending failure spin-up retry count"},
-  {0x5D,0x2C,D|B,"Controller impending failure drive calibration retry count"},
-  {0x5D,0x30,D|B,"Data channel impending failure general hard drive failure"},
-  {0x5D,0x31,D|B,"Data channel impending failure drive error rate too high"},
-  {0x5D,0x32,D|B,"Data channel impending failure data error rate too high"},
-  {0x5D,0x33,D|B,"Data channel impending failure seek error rate too high"},
-  {0x5D,0x34,D|B,"Data channel impending failure too many block reassigns"},
-  {0x5D,0x35,D|B,"Data channel impending failure access times too high"},
-  {0x5D,0x36,D|B,"Data channel impending failure start unit times too high"},
-  {0x5D,0x37,D|B,"Data channel impending failure channel parametrics"},
-  {0x5D,0x38,D|B,"Data channel impending failure controller detected"},
-  {0x5D,0x39,D|B,"Data channel impending failure throughput performance"},
-  {0x5D,0x3A,D|B,"Data channel impending failure seek time performance"},
-  {0x5D,0x3B,D|B,"Data channel impending failure spin-up retry count"},
-  {0x5D,0x3C,D|B,"Data channel impending failure drive calibration retry count"},
-  {0x5D,0x40,D|B,"Servo impending failure general hard drive failure"},
-  {0x5D,0x41,D|B,"Servo impending failure drive error rate too high"},
-  {0x5D,0x42,D|B,"Servo impending failure data error rate too high"},
-  {0x5D,0x43,D|B,"Servo impending failure seek error rate too high"},
-  {0x5D,0x44,D|B,"Servo impending failure too many block reassigns"},
-  {0x5D,0x45,D|B,"Servo impending failure access times too high"},
-  {0x5D,0x46,D|B,"Servo impending failure start unit times too high"},
-  {0x5D,0x47,D|B,"Servo impending failure channel parametrics"},
-  {0x5D,0x48,D|B,"Servo impending failure controller detected"},
-  {0x5D,0x49,D|B,"Servo impending failure throughput performance"},
-  {0x5D,0x4A,D|B,"Servo impending failure seek time performance"},
-  {0x5D,0x4B,D|B,"Servo impending failure spin-up retry count"},
-  {0x5D,0x4C,D|B,"Servo impending failure drive calibration retry count"},
-  {0x5D,0x50,D|B,"Spindle impending failure general hard drive failure"},
-  {0x5D,0x51,D|B,"Spindle impending failure drive error rate too high"},
-  {0x5D,0x52,D|B,"Spindle impending failure data error rate too high"},
-  {0x5D,0x53,D|B,"Spindle impending failure seek error rate too high"},
-  {0x5D,0x54,D|B,"Spindle impending failure too many block reassigns"},
-  {0x5D,0x55,D|B,"Spindle impending failure access times too high"},
-  {0x5D,0x56,D|B,"Spindle impending failure start unit times too high"},
-  {0x5D,0x57,D|B,"Spindle impending failure channel parametrics"},
-  {0x5D,0x58,D|B,"Spindle impending failure controller detected"},
-  {0x5D,0x59,D|B,"Spindle impending failure throughput performance"},
-  {0x5D,0x5A,D|B,"Spindle impending failure seek time performance"},
-  {0x5D,0x5B,D|B,"Spindle impending failure spin-up retry count"},
-  {0x5D,0x5C,D|B,"Spindle impending failure drive calibration retry count"},
-  {0x5D,0x60,D|B,"Firmware impending failure general hard drive failure"},
-  {0x5D,0x61,D|B,"Firmware impending failure drive error rate too high"},
-  {0x5D,0x62,D|B,"Firmware impending failure data error rate too high"},
-  {0x5D,0x63,D|B,"Firmware impending failure seek error rate too high"},
-  {0x5D,0x64,D|B,"Firmware impending failure too many block reassigns"},
-  {0x5D,0x65,D|B,"Firmware impending failure access times too high"},
-  {0x5D,0x66,D|B,"Firmware impending failure start unit times too high"},
-  {0x5D,0x67,D|B,"Firmware impending failure channel parametrics"},
-  {0x5D,0x68,D|B,"Firmware impending failure controller detected"},
-  {0x5D,0x69,D|B,"Firmware impending failure throughput performance"},
-  {0x5D,0x6A,D|B,"Firmware impending failure seek time performance"},
-  {0x5D,0x6B,D|B,"Firmware impending failure spin-up retry count"},
-  {0x5D,0x6C,D|B,"Firmware impending failure drive calibration retry count"},
-  {0x5D,0xFF,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Failure prediction threshold exceeded (false)"},
-  {0x5E,0x00,D|T|L|P|W|R|S|O|C|A|K,"Low power condition on"},
-  {0x5E,0x01,D|T|L|P|W|R|S|O|C|A|K,"Idle condition activated by timer"},
-  {0x5E,0x02,D|T|L|P|W|R|S|O|C|A|K,"Standby condition activated by timer"},
-  {0x5E,0x03,D|T|L|P|W|R|S|O|C|A|K,"Idle condition activated by command"},
-  {0x5E,0x04,D|T|L|P|W|R|S|O|C|A|K,"Standby condition activated by command"},
-  {0x5E,0x41,B,"Power state change to active"},
-  {0x5E,0x42,B,"Power state change to idle"},
-  {0x5E,0x43,B,"Power state change to standby"},
-  {0x5E,0x45,B,"Power state change to sleep"},
-  {0x5E,0x47,B|K,"Power state change to device control"},
-  {0x60,0x00,S,"Lamp failure"},
-  {0x61,0x00,S,"Video acquisition error"},
-  {0x61,0x01,S,"Unable to acquire video"},
-  {0x61,0x02,S,"Out of focus"},
-  {0x62,0x00,S,"Scan head positioning error"},
-  {0x63,0x00,R,"End of user area encountered on this track"},
-  {0x63,0x01,R,"Packet does not fit in available space"},
-  {0x64,0x00,R,"Illegal mode for this track"},
-  {0x64,0x01,R,"Invalid packet size"},
-  {0x65,0x00,D|T|L|P|W|R|S|O|M|C|A|E|B|K,"Voltage fault"},
-  {0x66,0x00,S,"Automatic document feeder cover up"},
-  {0x66,0x01,S,"Automatic document feeder lift up"},
-  {0x66,0x02,S,"Document jam in automatic document feeder"},
-  {0x66,0x03,S,"Document miss feed automatic in document feeder"},
-  {0x67,0x00,A,"Configuration failure"},
-  {0x67,0x01,A,"Configuration of incapable logical units failed"},
-  {0x67,0x02,A,"Add logical unit failed"},
-  {0x67,0x03,A,"Modification of logical unit failed"},
-  {0x67,0x04,A,"Exchange of logical unit failed"},
-  {0x67,0x05,A,"Remove of logical unit failed"},
-  {0x67,0x06,A,"Attachment of logical unit failed"},
-  {0x67,0x07,A,"Creation of logical unit failed"},
-  {0x67,0x08,A,"Assign failure occurred"},
-  {0x67,0x09,A,"Multiply assigned logical unit"},
-  {0x68,0x00,A,"Logical unit not configured"},
-  {0x69,0x00,A,"Data loss on logical unit"},
-  {0x69,0x01,A,"Multiple logical unit failures"},
-  {0x69,0x02,A,"Parity/data mismatch"},
-  {0x6A,0x00,A,"Informational,refer to log"},
-  {0x6B,0x00,A,"State change has occurred"},
-  {0x6B,0x01,A,"Redundancy level got better"},
-  {0x6B,0x02,A,"Redundancy level got worse"},
-  {0x6C,0x00,A,"Rebuild failure occurred"},
-  {0x6D,0x00,A,"Recalculate failure occurred"},
-  {0x6E,0x00,A,"Command to logical unit failed"},
-  {0x6F,0x00,R,"Copy protection key exchange failure - authentication failure"},
-  {0x6F,0x01,R,"Copy protection key exchange failure - key not present"},
-  {0x6F,0x02,R,"Copy protection key exchange failure - key not established"},
-  {0x6F,0x03,R,"Read of scrambled sector without authentication"},
-  {0x6F,0x04,R,"Media region code is mismatched to logical unit region"},
-  {0x6F,0x05,R,"Drive region must be permanent/region reset count error"},
-  /*
-   * FIXME(eric) - need a way to represent wildcards here.
-   */
-  {0x70,0x00,T,"Decompression exception short algorithm id of nn"},
-  {0x71,0x00,T,"Decompression exception long algorithm id"},
-  {0x72,0x00,R,"Session fixation error"},
-  {0x72,0x01,R,"Session fixation error writing lead-in"},
-  {0x72,0x02,R,"Session fixation error writing lead-out"},
-  {0x72,0x03,R,"Session fixation error - incomplete track in session"},
-  {0x72,0x04,R,"Empty or partially written reserved track"},
-  {0x72,0x05,R,"No more track reservations allowed"},
-  {0x73,0x00,R,"Cd control error"},
-  {0x73,0x01,R,"Power calibration area almost full"},
-  {0x73,0x02,R,"Power calibration area is full"},
-  {0x73,0x03,R,"Power calibration area error"},
-  {0x73,0x04,R,"Program memory area update failure"},
-  {0x73,0x05,R,"Program memory area is full"},
-  {0x73,0x06,R,"RMA/PMA is full"},
-  {0, 0, 0, NULL}
+	{0x40,0x00,0x7f,"Ram failure (%x)"},
+	{0x40,0x80,0xff,"Diagnostic failure on component (%x)"},
+	{0x41,0x00,0xff,"Data path failure (%x)"},
+	{0x42,0x00,0xff,"Power-on or self-test failure (%x)"},
+	{0x4D,0x00,0xff,"Tagged overlapped commands (queue tag %x)"},
+	{0x70,0x00,0xff,"Decompression exception short algorithm id of %x"},
+	{0, 0, 0, NULL}
 };
 #endif
 
 #if (CONSTANTS & CONST_SENSE)
+/* description of the sense key values */
 static const char *snstext[] = {
-    "None",                     /* There is no sense information */
-    "Recovered Error",          /* The last command completed successfully
-                                   but used error correction */
-    "Not Ready",                /* The addressed target is not ready */
-    "Medium Error",             /* Data error detected on the medium */
-    "Hardware Error",           /* Controller or device failure */
-    "Illegal Request",
-    "Unit Attention",           /* Removable medium was changed, or
-                                   the target has been reset */
-    "Data Protect",             /* Access to the data is blocked */
-    "Blank Check",              /* Reached unexpected written or unwritten
-                                   region of the medium */
-    "Key=9",                    /* Vendor specific */
-    "Copy Aborted",             /* COPY or COMPARE was aborted */
-    "Aborted Command",          /* The target aborted the command */
-    "Equal",                    /* A SEARCH DATA command found data equal */
-    "Volume Overflow",          /* Medium full with still data to be written */
-    "Miscompare",               /* Source data and data on the medium
-                                   do not agree */
-    "Key=15"                    /* Reserved */
+	"No Sense",	    /* 0: There is no sense information */
+	"Recovered Error",  /* 1: The last command completed successfully
+				  but used error correction */
+	"Not Ready",	    /* 2: The addressed target is not ready */
+	"Medium Error",	    /* 3: Data error detected on the medium */
+	"Hardware Error",   /* 4: Controller or device failure */
+	"Illegal Request",  /* 5: Error in request */
+	"Unit Attention",   /* 6: Removable medium was changed, or
+				  the target has been reset */
+	"Data Protect",	    /* 7: Access to the data is blocked */
+	"Blank Check",	    /* 8: Reached unexpected written or unwritten
+				  region of the medium */
+	"Vendor Specific",  /* 9: Vendor specific */
+	"Copy Aborted",	    /* A: COPY or COMPARE was aborted */
+	"Aborted Command",  /* B: The target aborted the command */
+	"Equal",	    /* C: A SEARCH DATA command found data equal */
+	"Volume Overflow",  /* D: Medium full with still data to be written */
+	"Miscompare",	    /* E: Source data and data on the medium
+				  do not agree */
 };
 #endif
 
-/* Print sense information */
-static 
-void print_sense_internal(const char * devclass, 
-			  const unsigned char * sense_buffer,
-			  kdev_t dev)
-{
-    int i, s;
-    int sense_class, valid, code, info;
-    const char * error = NULL;
-    
-    sense_class = (sense_buffer[0] >> 4) & 0x07;
-    code = sense_buffer[0] & 0xf;
-    valid = sense_buffer[0] & 0x80;
-    
-    if (sense_class == 7) {	/* extended sense data */
-	s = sense_buffer[7] + 8;
-	if(s > SCSI_SENSE_BUFFERSIZE)
-	   s = SCSI_SENSE_BUFFERSIZE;
-	
-	info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
-		(sense_buffer[5] << 8) | sense_buffer[6]);
-	if (info || valid) {
-		printk("Info fld=0x%x", info);
-		if (!valid)	/* info data not according to standard */
-			printk(" (nonstd)");
-		printk(", ");
-	}
-	if (sense_buffer[2] & 0x80)
-           printk( "FMK ");	/* current command has read a filemark */
-	if (sense_buffer[2] & 0x40)
-           printk( "EOM ");	/* end-of-medium condition exists */
-	if (sense_buffer[2] & 0x20)
-           printk( "ILI ");	/* incorrect block length requested */
-	
-	switch (code) {
-	case 0x0:
-	    error = "Current";	/* error concerns current command */
-	    break;
-	case 0x1:
-	    error = "Deferred";	/* error concerns some earlier command */
-            	/* e.g., an earlier write to disk cache succeeded, but
-                   now the disk discovers that it cannot write the data */
-	    break;
-	default:
-	    error = "Invalid";
-	}
-	
-	printk("%s ", error);
-	
+/* Get sense key string or NULL if not available */
+const char *
+scsi_sense_key_string(unsigned char key) {
 #if (CONSTANTS & CONST_SENSE)
-	printk( "%s%s: sense key %s\n", devclass,
-	       kdevname(dev), snstext[sense_buffer[2] & 0x0f]);
-#else
-	printk("%s%s: sns = %2x %2x\n", devclass,
-	       kdevname(dev), sense_buffer[0], sense_buffer[2]);
+	if (key <= 0xE)
+		return snstext[key];
 #endif
-	
-	/* Check to see if additional sense information is available */
-	if(sense_buffer[7] + 7 < 13 ||
-	   (sense_buffer[12] == 0  && sense_buffer[13] ==  0)) goto done;
-	
+	return NULL;
+}
+
+/*
+ * Get extended sense key string or NULL if not available.
+ * This string may contain a %x and must be printed with ascq as arg.
+ */
+const char *
+scsi_extd_sense_format(unsigned char asc, unsigned char ascq) {
 #if (CONSTANTS & CONST_XSENSE)
-	for(i=0; additional[i].text; i++)
-	    if(additional[i].code1 == sense_buffer[12] &&
-	       additional[i].code2 == sense_buffer[13])
-		printk("Additional sense indicates %s\n", additional[i].text);
-	
-	for(i=0; additional2[i].text; i++)
-	    if(additional2[i].code1 == sense_buffer[12] &&
-	       additional2[i].code2_min >= sense_buffer[13]  &&
-	       additional2[i].code2_max <= sense_buffer[13]) {
-		printk("Additional sense indicates ");
-		printk(additional2[i].text, sense_buffer[13]);
-		printk("\n");
-	    };
-#else
-	printk("ASC=%2x ASCQ=%2x\n", sense_buffer[12], sense_buffer[13]);
+	int i;
+	unsigned short code = ((asc << 8) | ascq);
+
+	for (i=0; additional[i].text; i++)
+		if (additional[i].code12 == code)
+			return additional[i].text;
+	for (i=0; additional2[i].fmt; i++)
+		if (additional2[i].code1 == asc &&
+		    additional2[i].code2_min >= ascq &&
+		    additional2[i].code2_max <= ascq)
+			return additional2[i].fmt;
 #endif
-    } else {	/* non-extended sense data */
+	return NULL;
+}
+
+/* Print extended sense information */
+static void
+scsi_show_extd_sense(unsigned char asc, unsigned char ascq) {
+	const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
+
+	if (extd_sense_fmt) {
+		printk("Additional sense: ");
+		printk(extd_sense_fmt, ascq);
+		printk("\n");
+	} else {
+		printk("ASC=%2x ASCQ=%2x\n", asc, ascq);
+	}
+}
 
-         /*
-          * Standard says:
-          *    sense_buffer[0] & 0200 : address valid
-          *    sense_buffer[0] & 0177 : vendor-specific error code
-          *    sense_buffer[1] & 0340 : vendor-specific
-          *    sense_buffer[1..3] : 21-bit logical block address
-          */
+/* Print sense information */
+static void
+print_sense_internal(const char * devclass, 
+		     const unsigned char * sense_buffer,
+		     kdev_t dev)
+{
+	int s, sense_class, valid, code, info;
+	const char * error = NULL;
+	unsigned char asc, ascq;
+	const char *sense_txt;
+    
+	sense_class = (sense_buffer[0] >> 4) & 0x07;
+	code = sense_buffer[0] & 0xf;
+	valid = sense_buffer[0] & 0x80;
+    
+	if (sense_class == 7) {	/* extended sense data */
+		s = sense_buffer[7] + 8;
+		if (s > SCSI_SENSE_BUFFERSIZE)
+			s = SCSI_SENSE_BUFFERSIZE;
 	
-#if (CONSTANTS & CONST_SENSE)
-	if (sense_buffer[0] < 15)
-	    printk("%s%s: old sense key %s\n", devclass,
-	      kdevname(dev), snstext[sense_buffer[0] & 0x0f]);
-	else
-#endif
-	    printk("%s%s: sns = %2x %2x\n", devclass,
-	      kdevname(dev), sense_buffer[0], sense_buffer[2]);
+		info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
+			(sense_buffer[5] << 8) | sense_buffer[6]);
+		if (info || valid) {
+			printk("Info fld=0x%x", info);
+			if (!valid)	/* info data not according to standard */
+				printk(" (nonstd)");
+			printk(", ");
+		}
+		if (sense_buffer[2] & 0x80)
+			printk( "FMK ");	/* current command has read a filemark */
+		if (sense_buffer[2] & 0x40)
+			printk( "EOM ");	/* end-of-medium condition exists */
+		if (sense_buffer[2] & 0x20)
+			printk( "ILI ");	/* incorrect block length requested */
 	
-	printk("Non-extended sense class %d code 0x%0x\n", sense_class, code);
-	s = 4;
-    }
+		switch (code) {
+		case 0x0:
+			error = "Current";	/* error concerns current command */
+			break;
+		case 0x1:
+			error = "Deferred";	/* error concerns some earlier command */
+			/* e.g., an earlier write to disk cache succeeded, but
+			   now the disk discovers that it cannot write the data */
+			break;
+		default:
+			error = "Invalid";
+		}
+
+		printk("%s ", error);
+
+		sense_txt = scsi_sense_key_string(sense_buffer[2]);
+		if (sense_txt)
+			printk("%s%s: sense key %s\n",
+			       devclass, kdevname(dev), sense_txt);
+		else
+			printk("%s%s: sense = %2x %2x\n",
+			       devclass, kdevname(dev),
+			       sense_buffer[0], sense_buffer[2]);
+
+		asc = ascq = 0;
+		if (sense_buffer[7] + 7 >= 13) {
+			asc = sense_buffer[12];
+			ascq = sense_buffer[13];
+		}
+		if (asc || ascq)
+			scsi_show_extd_sense(asc, ascq);
+
+	} else {	/* non-extended sense data */
+
+		/*
+		 * Standard says:
+		 *    sense_buffer[0] & 0200 : address valid
+		 *    sense_buffer[0] & 0177 : vendor-specific error code
+		 *    sense_buffer[1] & 0340 : vendor-specific
+		 *    sense_buffer[1..3] : 21-bit logical block address
+		 */
+
+		sense_txt = scsi_sense_key_string(sense_buffer[0]);
+		if (sense_txt)
+			printk("%s%s: old sense key %s\n",
+			       devclass, kdevname(dev), sense_txt);
+		else
+			printk("%s%s: sense = %2x %2x\n",
+			       devclass, kdevname(dev),
+			       sense_buffer[0], sense_buffer[2]);
+
+		printk("Non-extended sense class %d code 0x%0x\n",
+		       sense_class, code);
+		s = 4;
+	}
     
- done:
 #if !(CONSTANTS & CONST_SENSE)
-    printk("Raw sense data:");
-    for (i = 0; i < s; ++i) 
-	printk("0x%02x ", sense_buffer[i]);
-    printk("\n");
+	printk("Raw sense data:");
+	for (i = 0; i < s; ++i) 
+		printk("0x%02x ", sense_buffer[i]);
+	printk("\n");
 #endif
-    return;
 }
 
 void print_sense(const char * devclass, Scsi_Cmnd * SCpnt)
@@ -983,22 +1179,3 @@
 {   printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
 }
 #endif
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/constants.h b/drivers/scsi/constants.h
--- a/drivers/scsi/constants.h	Sun Jun 16 19:31:40 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,6 +0,0 @@
-#ifndef _CONSTANTS_H
-#define _CONSTANTS_H
-extern int print_msg(unsigned char *);
-extern void print_status(int);
-extern void print_Scsi_Cmnd (Scsi_Cmnd *);
-#endif /* def _CONSTANTS_H */
diff -Nru a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
--- a/drivers/scsi/dmx3191d.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/dmx3191d.c	Sun Jun 16 19:31:40 2002
@@ -34,7 +34,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 #include "sd.h"
 
 #include "dmx3191d.h"
diff -Nru a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
--- a/drivers/scsi/dtc.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/dtc.c	Sun Jun 16 19:31:41 2002
@@ -83,7 +83,6 @@
 #include "dtc.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
-#include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
 #include <linux/string.h>
diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
--- a/drivers/scsi/g_NCR5380.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/g_NCR5380.c	Sun Jun 16 19:31:39 2002
@@ -116,7 +116,6 @@
 #include "hosts.h"
 #include "g_NCR5380.h"
 #include "NCR5380.h"
-#include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
 #include <linux/init.h>
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/ide-scsi.c	Sun Jun 16 19:31:39 2002
@@ -243,8 +243,8 @@
 	u8 *scsi_buf;
 	unsigned long flags;
 
-	if (!(rq->flags & REQ_SPECIAL)) {
-		ide_end_request(drive, rq, uptodate);
+	if (!(rq->flags & REQ_PC)) {
+		ata_end_request(drive, rq, uptodate);
 		return 0;
 	}
 
@@ -293,6 +293,8 @@
  */
 static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	struct Scsi_Host *host = drive->driver_data;
 	idescsi_scsi_t *scsi = idescsi_private(host);
 	u8 ireason;
@@ -333,6 +335,8 @@
 		temp = pc->actually_transferred + bcount;
 		if ( temp > pc->request_transfer) {
 			if (temp > pc->buffer_size) {
+				unsigned long flags;
+				struct ata_channel *ch = drive->channel;
 				printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
 				temp = pc->buffer_size - pc->actually_transferred;
 				if (temp) {
@@ -346,7 +350,14 @@
 				pc->actually_transferred += temp;
 				pc->current_position += temp;
 				atapi_discard_data(drive,bcount - temp);
-				ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
+				/* FIXME: this locking should encompass the above register
+				 * file access too.
+				 */
+
+				spin_lock_irqsave(ch->lock, flags);
+				ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
+				spin_unlock_irqrestore(ch->lock, flags);
+
 				return ide_started;
 			}
 #ifdef DEBUG
@@ -370,30 +381,50 @@
 	pc->actually_transferred+=bcount;				/* Update the current position */
 	pc->current_position+=bcount;
 
-	ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);	/* And set the interrupt handler again */
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
+	ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);	/* And set the interrupt handler again */
+	spin_unlock_irqrestore(ch->lock, flags);
+
 	return ide_started;
 }
 
 static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	struct Scsi_Host *host = drive->driver_data;
 	idescsi_scsi_t *scsi = idescsi_private(host);
 	struct atapi_packet_command *pc = scsi->pc;
-	byte ireason;
+	u8 ireason;
 	ide_startstop_t startstop;
+	int ret;
 
-	if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	/* FIXME: Move this lock upwards.
+	 */
+	spin_lock_irqsave(ch->lock, flags);
+	if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+				WAIT_READY, rq, &startstop)) {
 		printk (KERN_ERR "ide-scsi: Strange, packet command initiated yet DRQ isn't asserted\n");
-		return startstop;
-	}
-	ireason = IN_BYTE (IDE_IREASON_REG);
-	if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
-		printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
-		return ide_stopped;
+		ret = startstop;
+	} else {
+		ireason = IN_BYTE(IDE_IREASON_REG);
+
+		if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
+			printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
+			ret = ide_stopped;
+		} else {
+			ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
+			atapi_write(drive, scsi->pc->c, 12);
+			ret = ide_started;
+		}
 	}
-	ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);	/* Set the interrupt routine */
-	atapi_write(drive, scsi->pc->c, 12);			/* Send the actual packet */
-	return ide_started;
+	spin_unlock_irqrestore(ch->lock, flags);
+
+	return ret;
 }
 
 /*
@@ -413,7 +444,7 @@
 	bcount = min(pc->request_transfer, 63 * 1024);		/* Request to transfer the entire buffer at once */
 
 	if (drive->using_dma && rq->bio)
-		dma_ok = !udma_init(drive, rq);
+		dma_ok = udma_init(drive, rq);
 
 	ata_select(drive, 10);
 	ata_irq_enable(drive, 1);
@@ -425,8 +456,18 @@
 		set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
 		udma_start(drive, rq);
 	}
-	if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
-		ide_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL);
+	if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
+		unsigned long flags;
+		struct ata_channel *ch = drive->channel;
+
+		/* FIXME: this locking should encompass the above register
+		 * file access too.
+		 */
+
+		spin_lock_irqsave(ch->lock, flags);
+		ata_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
 		return ide_started;
 	} else {
@@ -440,6 +481,9 @@
  */
 static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
+	struct ata_channel *ch = drive->channel;
+	int ret;
+
 #ifdef DEBUG
 	printk(KERN_INFO "rq_status: %d, cmd: %d, errors: %d\n",
 			rq->rq_status,
@@ -452,12 +496,18 @@
 			rq->current_nr_sectors);
 #endif
 
-	if (rq->flags & REQ_SPECIAL) {
-		return idescsi_issue_pc(drive, rq, (struct atapi_packet_command *) rq->special);
+	/* FIXME: make this unlocking go away*/
+	spin_unlock_irq(ch->lock);
+	if (rq->flags & REQ_PC) {
+		ret = idescsi_issue_pc(drive, rq, (struct atapi_packet_command *) rq->special);
+	} else {
+	    blk_dump_rq_flags(rq, "ide-scsi: unsup command");
+	    idescsi_end_request(drive, rq, 0);
+	    ret = ide_stopped;
 	}
-	blk_dump_rq_flags(rq, "ide-scsi: unsup command");
-	idescsi_end_request(drive, rq, 0);
-	return ide_stopped;
+	spin_lock_irq(ch->lock);
+
+	return ret;
 }
 
 static int idescsi_open(struct inode *inode, struct file *filp, struct ata_device *drive)
@@ -667,7 +717,7 @@
 	}
 
 	memset(rq, 0, sizeof(*rq));
-	rq->flags = REQ_SPECIAL;
+	rq->flags = REQ_PC;
 	rq->special = (char *) pc;
 	rq->bio = idescsi_dma_bio (drive, pc);
 	spin_unlock_irq(cmd->host->host_lock);
diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
--- a/drivers/scsi/lasi700.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/lasi700.c	Sun Jun 16 19:31:39 2002
@@ -57,7 +57,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 
 #include "lasi700.h"
 #include "53c700.h"
diff -Nru a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
--- a/drivers/scsi/mac_scsi.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/mac_scsi.c	Sun Jun 16 19:31:39 2002
@@ -70,7 +70,6 @@
 #include "hosts.h"
 #include "mac_scsi.h"
 #include "NCR5380.h"
-#include "constants.h"
 
 #if 0
 #define NDEBUG (NDEBUG_INTR | NDEBUG_PSEUDO_DMA | NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_RESELECTION)
diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
--- a/drivers/scsi/ncr53c8xx.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/ncr53c8xx.c	Sun Jun 16 19:31:40 2002
@@ -157,7 +157,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 #include "sd.h"
 
 #include <linux/types.h>
diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/osst.c	Sun Jun 16 19:31:40 2002
@@ -60,6 +60,7 @@
 #define OSST_DEB_MSG  KERN_NOTICE
 
 #define MAJOR_NR OSST_MAJOR
+#define DEVICE_NR(device) (minor(device) & 0x7f) 
 #include <linux/blk.h>
 
 #include "scsi.h"
@@ -72,8 +73,6 @@
 #include "osst.h"
 #include "osst_options.h"
 #include "osst_detect.h"
-
-#include "constants.h"
 
 static int buffer_kbs = 0;
 static int write_threshold_kbs = 0;
diff -Nru a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
--- a/drivers/scsi/pas16.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/pas16.c	Sun Jun 16 19:31:39 2002
@@ -123,7 +123,6 @@
 #include "pas16.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
-#include "constants.h"
 #include "sd.h"
 
 #include <linux/stat.h>
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/scsi.c	Sun Jun 16 19:31:40 2002
@@ -69,7 +69,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/scsi.h	Sun Jun 16 19:31:40 2002
@@ -527,24 +527,30 @@
 
 /*
  * Prototypes for functions in constants.c
+ * Some of these used to live in constants.h
  */
+extern void print_Scsi_Cmnd (Scsi_Cmnd *);
 extern void print_command(unsigned char *);
 extern void print_sense(const char *, Scsi_Cmnd *);
 extern void print_req_sense(const char *, Scsi_Request *);
 extern void print_driverbyte(int scsiresult);
 extern void print_hostbyte(int scsiresult);
-extern void print_status (int status);
+extern void print_status(unsigned char status);
+extern int print_msg(const unsigned char *);
+extern const char *scsi_sense_key_string(unsigned char);
+extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
 
 /*
  *  The scsi_device struct contains what we know about each given scsi
  *  device.
  *
- * FIXME(eric) - one of the great regrets that I have is that I failed to define
- * these structure elements as something like sdev_foo instead of foo.  This would
- * make it so much easier to grep through sources and so forth.  I propose that
- * all new elements that get added to these structures follow this convention.
- * As time goes on and as people have the stomach for it, it should be possible to 
- * go back and retrofit at least some of the elements here with with the prefix.
+ * FIXME(eric) - One of the great regrets that I have is that I failed to
+ * define these structure elements as something like sdev_foo instead of foo.
+ * This would make it so much easier to grep through sources and so forth.
+ * I propose that all new elements that get added to these structures follow
+ * this convention.  As time goes on and as people have the stomach for it,
+ * it should be possible to go back and retrofit at least some of the elements
+ * here with with the prefix.
  */
 
 struct scsi_device {
@@ -851,22 +857,3 @@
 extern int scsi_reset_provider(Scsi_Device *, int);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4 
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/scsi_error.c	Sun Jun 16 19:31:39 2002
@@ -32,7 +32,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 
 /*
  * We must always allow SHUTDOWN_SIGS.  Even if we are not a module,
@@ -1095,6 +1094,8 @@
  */
 STATIC int scsi_eh_completed_normally(Scsi_Cmnd * SCpnt)
 {
+	int rtn;
+
 	/*
 	 * First check the host byte, to see if there is anything in there
 	 * that would indicate what we need to do.
@@ -1102,20 +1103,25 @@
 	if (host_byte(SCpnt->result) == DID_RESET) {
 		if (SCpnt->flags & IS_RESETTING) {
 			/*
-			 * OK, this is normal.  We don't know whether in fact the
-			 * command in question really needs to be rerun or not - 
-			 * if this was the original data command then the answer is yes,
-			 * otherwise we just flag it as success.
+			 * OK, this is normal.  We don't know whether in fact
+			 * the command in question really needs to be rerun
+			 * or not - if this was the original data command then
+			 * the answer is yes, otherwise we just flag it as
+			 * success.
 			 */
 			SCpnt->flags &= ~IS_RESETTING;
-			return NEEDS_RETRY;
+			goto maybe_retry;
 		}
 		/*
-		 * Rats.  We are already in the error handler, so we now get to try
-		 * and figure out what to do next.  If the sense is valid, we have
-		 * a pretty good idea of what to do.  If not, we mark it as failed.
+		 * Rats.  We are already in the error handler, so we now
+		 * get to try and figure out what to do next.  If the sense
+		 * is valid, we have a pretty good idea of what to do.
+		 * If not, we mark it as failed.
 		 */
-		return scsi_check_sense(SCpnt);
+		rtn = scsi_check_sense(SCpnt);
+		if (rtn == NEEDS_RETRY)
+			goto maybe_retry;
+		return rtn;
 	}
 	if (host_byte(SCpnt->result) != DID_OK) {
 		return FAILED;
@@ -1127,14 +1133,18 @@
 		return FAILED;
 	}
 	/*
-	 * Now, check the status byte to see if this indicates anything special.
+	 * Now, check the status byte to see if this indicates
+	 * anything special.
 	 */
 	switch (status_byte(SCpnt->result)) {
 	case GOOD:
 	case COMMAND_TERMINATED:
 		return SUCCESS;
 	case CHECK_CONDITION:
-		return scsi_check_sense(SCpnt);
+		rtn = scsi_check_sense(SCpnt);
+		if (rtn == NEEDS_RETRY)
+			goto maybe_retry;
+		return rtn;
 	case CONDITION_GOOD:
 	case INTERMEDIATE_GOOD:
 	case INTERMEDIATE_C_GOOD:
@@ -1149,6 +1159,14 @@
 		return FAILED;
 	}
 	return FAILED;
+
+ maybe_retry:
+	if ((++SCpnt->retries) < SCpnt->allowed) {
+		return NEEDS_RETRY;
+	} else {
+		/* No more retries - report this one back to upper level */
+		return SUCCESS;
+	}
 }
 
 /*
@@ -1995,23 +2013,3 @@
 
 	return rtn;
 }
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
--- a/drivers/scsi/scsi_ioctl.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/scsi_ioctl.c	Sun Jun 16 19:31:41 2002
@@ -127,7 +127,7 @@
 				/* gag this error, VFS will log it anyway /axboe */
 				/* printk(KERN_INFO "Disc change detected.\n"); */
 				break;
-			};
+			}
 		default:	/* Fall through for non-removable media */
 			printk("SCSI error: host %d id %d lun %d return code = %x\n",
 			       dev->host->host_no,
@@ -139,7 +139,7 @@
 			       sense_error(SRpnt->sr_sense_buffer[0]),
 			       SRpnt->sr_sense_buffer[2] & 0xf);
 
-		};
+		}
 
 	result = SRpnt->sr_result;
 
@@ -152,7 +152,7 @@
 }
 
 /*
- * This interface is depreciated - users should use the scsi generic (sg)
+ * This interface is deprecated - users should use the scsi generic (sg)
  * interface instead, as this is a more flexible approach to performing
  * generic SCSI commands on a device.
  *
@@ -516,22 +516,3 @@
 	set_fs(oldfs);
 	return tmp;
 }
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/scsi_lib.c	Sun Jun 16 19:31:40 2002
@@ -43,7 +43,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 #include <scsi/scsi_ioctl.h>
 
 /*
diff -Nru a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c
--- a/drivers/scsi/scsi_merge.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/scsi_merge.c	Sun Jun 16 19:31:41 2002
@@ -42,7 +42,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 #include <scsi/scsi_ioctl.h>
 
 /*
diff -Nru a/drivers/scsi/scsi_queue.c b/drivers/scsi/scsi_queue.c
--- a/drivers/scsi/scsi_queue.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/scsi_queue.c	Sun Jun 16 19:31:41 2002
@@ -34,7 +34,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 
 /*
  * TODO:
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/scsi_scan.c	Sun Jun 16 19:31:41 2002
@@ -16,7 +16,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/scsi_syms.c	Sun Jun 16 19:31:40 2002
@@ -21,7 +21,6 @@
 #include "scsi.h"
 #include <scsi/scsi_ioctl.h>
 #include "hosts.h"
-#include "constants.h"
 
 #include "sd.h"
 #include <scsi/scsicam.h>
@@ -48,6 +47,8 @@
 EXPORT_SYMBOL(print_req_sense);
 EXPORT_SYMBOL(print_msg);
 EXPORT_SYMBOL(print_status);
+EXPORT_SYMBOL(scsi_sense_key_string);
+EXPORT_SYMBOL(scsi_extd_sense_format);
 EXPORT_SYMBOL(kernel_scsi_ioctl);
 EXPORT_SYMBOL(scsi_release_command);
 EXPORT_SYMBOL(print_Scsi_Cmnd);
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/sd.c	Sun Jun 16 19:31:39 2002
@@ -50,13 +50,13 @@
 
 #define MAJOR_NR SCSI_DISK0_MAJOR
 #define LOCAL_END_REQUEST
+#define DEVICE_NR(device) (((major(device) & SD_MAJOR_MASK) << (8 - 4)) + (minor(device) >> 4))
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 #include "scsi.h"
 #include "hosts.h"
 #include "sd.h"
 #include <scsi/scsi_ioctl.h>
-#include "constants.h"
 #include <scsi/scsicam.h>	/* must follow "hosts.h" */
 
 #include <linux/genhd.h>
@@ -95,7 +95,7 @@
 static int check_scsidisk_media_change(kdev_t);
 static int fop_revalidate_scsidisk(kdev_t);
 
-static int sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr);
+static void sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr);
 
 static int sd_init(void);
 static void sd_finish(void);
@@ -151,22 +151,24 @@
 	Scsi_Device *sdp;
 	struct Scsi_Host *shp = hp;
 	int dsk_nr;
+	kdev_t retval = NODEV;
 	unsigned long iflags;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_find_target: host_nr=%d, "
 			    "scsi_id=%d\n", shp->host_no, scsi_id));
 	read_lock_irqsave(&sd_dsk_arr_lock, iflags);
 	for (dsk_nr = 0; dsk_nr < sd_template.dev_max; ++dsk_nr) {
-		if (NULL == (sdkp = sd_dsk_arr[dsk_nr]))
+		sdkp = sd_dsk_arr[dsk_nr];
+		if (sdkp == NULL)
 			continue;
 		sdp = sdkp->device;
 		if (sdp && (sdp->host == shp) && (sdp->id == scsi_id)) {
-			read_unlock_irqrestore(&sd_dsk_arr_lock, iflags);
-			return MKDEV_SD(dsk_nr);
+			retval = MKDEV_SD(dsk_nr);
+			break;
 		}
 	}
 	read_unlock_irqrestore(&sd_dsk_arr_lock, iflags);
-	return NODEV;
+	return retval;
 }
 #endif
 
@@ -221,15 +223,15 @@
 	
 			/* default to most commonly used values */
 	
-		        diskinfo[0] = 0x40;
-	        	diskinfo[1] = 0x20;
+		        diskinfo[0] = 0x40;	/* 1 << 6 */
+	        	diskinfo[1] = 0x20;	/* 1 << 5 */
 	        	diskinfo[2] = sdkp->capacity >> 11;
 	
 			/* override with calculated, extended default, 
 			   or driver values */
 	
 			if(host->hostt->bios_param != NULL)
-				host->hostt->bios_param(sdkp, dev, 
+				host->hostt->bios_param(sdkp, dev,
 							&diskinfo[0]);
 			else
 				scsicam_bios_param(sdkp, dev, &diskinfo[0]);
@@ -530,7 +532,7 @@
 		/*
 		 * If the drive is empty, just let the open fail.
 		 */
-		if ((!sdkp->ready) && !(filp->f_flags & O_NDELAY)) {
+		if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY)) {
 			retval = -ENOMEDIUM;
 			goto error_out;
 		}
@@ -548,8 +550,7 @@
 	/*
 	 * It is possible that the disk changing stuff resulted in the device
 	 * being taken offline.  If this is the case, report this to the user,
-	 * and don't pretend that
-	 * the open actually succeeded.
+	 * and don't pretend that the open actually succeeded.
 	 */
 	if (!sdp->online) {
 		goto error_out;
@@ -751,6 +752,13 @@
 	scsi_io_completion(SCpnt, good_sectors, block_sectors);
 }
 
+static void
+sd_set_media_not_present(Scsi_Disk *sdkp) {
+	sdkp->media_present = 0;
+	sdkp->capacity = 0;
+	sdkp->device->changed = 1;
+}
+
 /**
  *	check_scsidisk_media_change - self descriptive
  *	@full_dev: kernel device descriptor (kdev_t)
@@ -786,8 +794,7 @@
 	 * that we would ever take a device offline in the first place.
 	 */
 	if (sdp->online == FALSE) {
-		sdkp->ready = 0;
-		sdp->changed = 1;
+		sd_set_media_not_present(sdkp);
 		return 1;	/* This will force a flush, if called from
 				 * check_disk_change */
 	}
@@ -808,18 +815,17 @@
 				 * it out later once the drive is available
 				 * again.  */
 
-		sdkp->ready = 0;
-		sdp->changed = 1;
+		sd_set_media_not_present(sdkp);
 		return 1;	/* This will force a flush, if called from
 				 * check_disk_change */
 	}
 	/*
-	 * for removable scsi disk ( FLOPTICAL ) we have to recognise the
-	 * presence of disk in the drive. This is kept in the Scsi_Disk
+	 * For removable scsi disk we have to recognise the presence
+	 * of a disk in the drive. This is kept in the Scsi_Disk
 	 * struct and tested at open !  Daniel Roche ( dan@lectra.fr )
 	 */
 
-	sdkp->ready = 1;	/* FLOPTICAL */
+	sdkp->media_present = 1;
 
 	retval = sdp->changed;
 	if (!flag)
@@ -827,63 +833,31 @@
 	return retval;
 }
 
-/**
- *	sd_init_onedisk - called the first time a new disk is seen,
- *	performs read_capacity, disk spin up (as required), etc.
- *	@sdkp: pointer to associated Scsi_Disk object
- *	@dsk_nr: disk number within this driver (e.g. 0->/dev/sda,
- *	1->/dev/sdb, etc)
- *
- *	Returns dsk_nr (pointless)
- *
- *	Note: this function is local to this driver.
- **/
-static int sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr)
-{
+static int
+sd_media_not_present(Scsi_Disk *sdkp, Scsi_Request *SRpnt) {
+	int the_result = SRpnt->sr_result;
+
+	if (the_result != 0
+	    && (driver_byte(the_result) & DRIVER_SENSE) != 0
+	    && (SRpnt->sr_sense_buffer[2] == NOT_READY ||
+		SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)
+	    && SRpnt->sr_sense_buffer[12] == 0x3A /* medium not present */) {
+		sd_set_media_not_present(sdkp);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * spinup disk - called only in sd_init_onedisk()
+ */
+static void
+sd_spinup_disk(Scsi_Disk *sdkp, char *diskname,
+	       Scsi_Request *SRpnt, unsigned char *buffer) {
 	unsigned char cmd[10];
-	char nbuff[6];
-	unsigned char *buffer;
+	Scsi_Device *sdp = sdkp->device;
 	unsigned long spintime_value = 0;
 	int the_result, retries, spintime;
-	int sector_size;
-	Scsi_Device *sdp;
-	Scsi_Request *SRpnt;
-
-	SCSI_LOG_HLQUEUE(3, printk("sd_init_onedisk: dsk_nr=%d\n", 
-			    dsk_nr));
-	/*
-	 * Get the name of the disk, in case we need to log it somewhere.
-	 */
-	sd_dskname(dsk_nr, nbuff);
-
-	/*
-	 * If the device is offline, don't try and read capacity or any
-	 * of the other niceties.
-	 */
-	sdp = sdkp->device;
-	if (sdp->online == FALSE)
-		return dsk_nr;
-
-	/*
-	 * We need to retry the READ_CAPACITY because a UNIT_ATTENTION is
-	 * considered a fatal error, and many devices report such an error
-	 * just after a scsi bus reset.
-	 */
-
-	SRpnt = scsi_allocate_request(sdp);
-	if (!SRpnt) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Request allocation "
-		       "failure.\n");
-		return dsk_nr;
-	}
-
-	buffer = kmalloc(512, GFP_DMA);
-	if (!buffer) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation "
-		       "failure.\n");
-		scsi_release_request(SRpnt);
-		return dsk_nr;
-	}
 
 	spintime = 0;
 
@@ -895,15 +869,16 @@
 		while (retries < 3) {
 			cmd[0] = TEST_UNIT_READY;
 			cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-				 ((sdp->lun << 5) & 0xe0) : 0;
+				((sdp->lun << 5) & 0xe0) : 0;
 			memset((void *) &cmd[2], 0, 8);
+
 			SRpnt->sr_cmd_len = 0;
 			SRpnt->sr_sense_buffer[0] = 0;
 			SRpnt->sr_sense_buffer[2] = 0;
 			SRpnt->sr_data_direction = SCSI_DATA_NONE;
 
 			scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
-				0/*512*/, SD_TIMEOUT, MAX_RETRIES);
+				       0/*512*/, SD_TIMEOUT, MAX_RETRIES);
 
 			the_result = SRpnt->sr_result;
 			retries++;
@@ -917,16 +892,8 @@
 		 * any media in it, don't bother with any of the rest of
 		 * this crap.
 		 */
-		if( the_result != 0
-		    && ((driver_byte(the_result) & DRIVER_SENSE) != 0)
-		    && SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION
-		    && SRpnt->sr_sense_buffer[12] == 0x3A ) {
-			sdkp->capacity = 0x1fffff;
-			sector_size = 512;
-			sdp->changed = 1;
-			sdkp->ready = 0;
-			break;
-		}
+		if (sd_media_not_present(sdkp, SRpnt))
+			return;
 
 		/* Look for non-removable devices that return NOT_READY.
 		 * Issue command to spin up drive for these cases. */
@@ -935,10 +902,10 @@
 			unsigned long time1;
 			if (!spintime) {
 				printk(KERN_NOTICE "%s: Spinning up disk...",
-				       nbuff);
+				       diskname);
 				cmd[0] = START_STOP;
 				cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-				 	 ((sdp->lun << 5) & 0xe0) : 0;
+					((sdp->lun << 5) & 0xe0) : 0;
 				cmd[1] |= 1;	/* Return immediately */
 				memset((void *) &cmd[2], 0, 8);
 				cmd[4] = 1;	/* Start spin cycle */
@@ -963,65 +930,63 @@
 		}
 	} while (the_result && spintime &&
 		 time_after(spintime_value + 100 * HZ, jiffies));
+
 	if (spintime) {
 		if (the_result)
 			printk("not responding...\n");
 		else
 			printk("ready\n");
 	}
+}
+
+/*
+ * read disk capacity - called only in sd_init_onedisk()
+ */
+static void
+sd_read_capacity(Scsi_Disk *sdkp, char *diskname,
+		 Scsi_Request *SRpnt, unsigned char *buffer) {
+	unsigned char cmd[10];
+	Scsi_Device *sdp = sdkp->device;
+	int the_result, retries;
+	int sector_size;
+
 	retries = 3;
 	do {
 		cmd[0] = READ_CAPACITY;
 		cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-			 ((sdp->lun << 5) & 0xe0) : 0;
+			((sdp->lun << 5) & 0xe0) : 0;
 		memset((void *) &cmd[2], 0, 8);
 		memset((void *) buffer, 0, 8);
+
 		SRpnt->sr_cmd_len = 0;
 		SRpnt->sr_sense_buffer[0] = 0;
 		SRpnt->sr_sense_buffer[2] = 0;
-
 		SRpnt->sr_data_direction = SCSI_DATA_READ;
+
 		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
-			    8, SD_TIMEOUT, MAX_RETRIES);
+			      8, SD_TIMEOUT, MAX_RETRIES);
+
+		if (sd_media_not_present(sdkp, SRpnt))
+			return;
 
 		the_result = SRpnt->sr_result;
 		retries--;
 
 	} while (the_result && retries);
 
-	/*
-	 * The SCSI standard says:
-	 * "READ CAPACITY is necessary for self configuring software"
-	 *  While not mandatory, support of READ CAPACITY is strongly
-	 *  encouraged.
-	 *  We used to die if we couldn't successfully do a READ CAPACITY.
-	 *  But, now we go on about our way.  The side effects of this are
-	 *
-	 *  1. We can't know block size with certainty. I have said
-	 *     "512 bytes is it" as this is most common.
-	 *
-	 *  2. Recovery from when someone attempts to read past the
-	 *     end of the raw device will be slower.
-	 */
-
 	if (the_result) {
 		printk(KERN_NOTICE "%s : READ CAPACITY failed.\n"
 		       "%s : status=%x, message=%02x, host=%d, driver=%02x \n",
-		       nbuff, nbuff,
+		       diskname, diskname,
 		       status_byte(the_result),
 		       msg_byte(the_result),
 		       host_byte(the_result),
-		       driver_byte(the_result)
-		    );
+		       driver_byte(the_result));
+
 		if (driver_byte(the_result) & DRIVER_SENSE)
 			print_req_sense("sd", SRpnt);
 		else
-			printk("%s : sense not available. \n", nbuff);
-
-		printk(KERN_NOTICE "%s : block size assumed to be 512 "
-		       "bytes, disk size 1GB.  \n", nbuff);
-		sdkp->capacity = 0x1fffff;
-		sector_size = 512;
+			printk("%s : sense not available. \n", diskname);
 
 		/* Set dirty bit for removable devices if not ready -
 		 * sometimes drives will not report this properly. */
@@ -1029,130 +994,193 @@
 		    SRpnt->sr_sense_buffer[2] == NOT_READY)
 			sdp->changed = 1;
 
-	} else {
+		/* Either no media are present but the drive didnt tell us,
+		   or they are present but the read capacity command fails */
+		/* sdkp->media_present = 0; -- not always correct */
+		sdkp->capacity = 0x200000; /* 1 GB - random */
+
+		return;
+	}
+
+	sdkp->capacity = 1 + ((buffer[0] << 24) |
+			      (buffer[1] << 16) |
+			      (buffer[2] << 8) |
+			      buffer[3]);
+
+	sector_size = (buffer[4] << 24) |
+		(buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
+
+	if (sector_size == 0) {
+		sector_size = 512;
+		printk(KERN_NOTICE "%s : sector size 0 reported, "
+		       "assuming 512.\n", diskname);
+	}
+
+	if (sector_size != 512 &&
+	    sector_size != 1024 &&
+	    sector_size != 2048 &&
+	    sector_size != 4096 &&
+	    sector_size != 256) {
+		printk(KERN_NOTICE "%s : unsupported sector size "
+		       "%d.\n", diskname, sector_size);
 		/*
-		 * FLOPTICAL, if read_capa is ok, drive is assumed to be ready
+		 * The user might want to re-format the drive with
+		 * a supported sectorsize.  Once this happens, it
+		 * would be relatively trivial to set the thing up.
+		 * For this reason, we leave the thing in the table.
 		 */
-		sdkp->ready = 1;
+		sdkp->capacity = 0;
+	}
+	{
+		/*
+		 * The msdos fs needs to know the hardware sector size
+		 * So I have created this table. See ll_rw_blk.c
+		 * Jacques Gelinas (Jacques@solucorp.qc.ca)
+		 */
+		int hard_sector = sector_size;
+		int sz = sdkp->capacity * (hard_sector/256);
+		request_queue_t *queue = &sdp->request_queue;
+
+		blk_queue_hardsect_size(queue, hard_sector);
+		printk(KERN_NOTICE "SCSI device %s: "
+		       "%d %d-byte hdwr sectors (%d MB)\n",
+		       diskname, sdkp->capacity,
+		       hard_sector, (sz/2 - sz/1250 + 974)/1950);
+	}
+
+	/* Rescale capacity to 512-byte units */
+	if (sector_size == 4096)
+		sdkp->capacity <<= 3;
+	if (sector_size == 2048)
+		sdkp->capacity <<= 2;
+	if (sector_size == 1024)
+		sdkp->capacity <<= 1;
+	if (sector_size == 256)
+		sdkp->capacity >>= 1;
 
-		sdkp->capacity = 1 + ((buffer[0] << 24) |
-				      (buffer[1] << 16) |
-				      (buffer[2] << 8) |
-				      buffer[3]);
-
-		sector_size = (buffer[4] << 24) |
-		    (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
-
-		if (sector_size == 0) {
-			sector_size = 512;
-			printk(KERN_NOTICE "%s : sector size 0 reported, "
-			       "assuming 512.\n", nbuff);
-		}
-		if (sector_size != 512 &&
-		    sector_size != 1024 &&
-		    sector_size != 2048 &&
-		    sector_size != 4096 &&
-		    sector_size != 256) {
-			printk(KERN_NOTICE "%s : unsupported sector size "
-			       "%d.\n", nbuff, sector_size);
-			/*
-			 * The user might want to re-format the drive with
-			 * a supported sectorsize.  Once this happens, it
-			 * would be relatively trivial to set the thing up.
-			 * For this reason, we leave the thing in the table.
-			 */
-			sdkp->capacity = 0;
-		}
-		{
-			/*
-			 * The msdos fs needs to know the hardware sector size
-			 * So I have created this table. See ll_rw_blk.c
-			 * Jacques Gelinas (Jacques@solucorp.qc.ca)
-			 */
-			int hard_sector = sector_size;
-			int sz = sdkp->capacity * (hard_sector/256);
-			request_queue_t *queue = &sdp->request_queue;
-
-			blk_queue_hardsect_size(queue, hard_sector);
-			printk(KERN_NOTICE "SCSI device %s: "
-			       "%d %d-byte hdwr sectors (%d MB)\n",
-			       nbuff, sdkp->capacity,
-			       hard_sector, (sz/2 - sz/1250 + 974)/1950);
-		}
+	sdkp->device->sector_size = sector_size;
+}
+
+/*
+ * read write protect setting, if possible - called only in sd_init_onedisk()
+ */
+static void
+sd_read_write_protect_flag(Scsi_Disk *sdkp, char *diskname,
+			   Scsi_Request *SRpnt, unsigned char *buffer) {
+	Scsi_Device *sdp = sdkp->device;
+	unsigned char cmd[8];
+	int the_result;
+
+	/*
+	 * For removable scsi disks we have to recognise the
+	 * Write Protect Flag. This flag is kept in the Scsi_Disk
+	 * struct and tested at open !
+	 * Daniel Roche ( dan@lectra.fr )
+	 *
+	 * Changed to get all pages (0x3f) rather than page 1 to
+	 * get around devices which do not have a page 1.  Since
+	 * we're only interested in the header anyway, this should
+	 * be fine.
+	 *   -- Matthew Dharm (mdharm-scsi@one-eyed-alien.net)
+	 *
+	 * As it turns out, some devices return an error for
+	 * every MODE_SENSE request except one for page 0.
+	 * So, we should also try that. --aeb
+	 */
+
+	memset((void *) &cmd[0], 0, 8);
+	cmd[0] = MODE_SENSE;
+	cmd[1] = (sdp->scsi_level <= SCSI_2) ?
+		((sdp->lun << 5) & 0xe0) : 0;
+	cmd[2] = 0x3f;	/* Get all pages */
+	cmd[4] = 255;   /* Ask for 255 bytes, even tho we want just the first 8 */
+	SRpnt->sr_cmd_len = 0;
+	SRpnt->sr_sense_buffer[0] = 0;
+	SRpnt->sr_sense_buffer[2] = 0;
+	SRpnt->sr_data_direction = SCSI_DATA_READ;
 
-		/* Rescale capacity to 512-byte units */
-		if (sector_size == 4096)
-			sdkp->capacity <<= 3;
-		if (sector_size == 2048)
-			sdkp->capacity <<= 2;
-		if (sector_size == 1024)
-			sdkp->capacity <<= 1;
-		if (sector_size == 256)
-			sdkp->capacity >>= 1;
+	scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
+		      512, SD_TIMEOUT, MAX_RETRIES);
+
+	the_result = SRpnt->sr_result;
+
+	if (the_result) {
+		printk("%s: test WP failed, assume Write Enabled\n",
+		       diskname);
+		/* alternatively, try page 0 */
+	} else {
+		sdkp->write_prot = ((buffer[2] & 0x80) != 0);
+		printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname,
+		       sdkp->write_prot ? "on" : "off");
 	}
+}
+
+/**
+ *	sd_init_onedisk - called the first time a new disk is seen,
+ *	performs disk spin up, read_capacity, etc.
+ *	@sdkp: pointer to associated Scsi_Disk object
+ *	@dsk_nr: disk number within this driver (e.g. 0->/dev/sda,
+ *	1->/dev/sdb, etc)
+ *
+ *	Note: this function is local to this driver.
+ **/
+static void
+sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr) {
+	char diskname[40];
+	unsigned char *buffer;
+	Scsi_Device *sdp;
+	Scsi_Request *SRpnt;
+
+	SCSI_LOG_HLQUEUE(3, printk("sd_init_onedisk: dsk_nr=%d\n", dsk_nr));
 
+	/*
+	 * Get the name of the disk, in case we need to log it somewhere.
+	 */
+	sd_dskname(dsk_nr, diskname);
 
 	/*
-	 * Unless otherwise specified, this is not write protected.
+	 * If the device is offline, don't try and read capacity or any
+	 * of the other niceties.
 	 */
-	sdkp->write_prot = 0;
-	if (sdp->removable && sdkp->ready) {
-		/* FLOPTICAL */
+	sdp = sdkp->device;
+	if (sdp->online == FALSE)
+		return;
 
-		/*
-		 * For removable scsi disk ( FLOPTICAL ) we have to recognise
-		 * the Write Protect Flag. This flag is kept in the Scsi_Disk
-		 * struct and tested at open !
-		 * Daniel Roche ( dan@lectra.fr )
-		 *
-		 * Changed to get all pages (0x3f) rather than page 1 to
-		 * get around devices which do not have a page 1.  Since
-		 * we're only interested in the header anyway, this should
-		 * be fine.
-		 *   -- Matthew Dharm (mdharm-scsi@one-eyed-alien.net)
-		 *
-		 * As it turns out, some devices return an error for
-		 * every MODE_SENSE request except one for page 0.
-		 * So, we should also try that. --aeb
-		 */
+	SRpnt = scsi_allocate_request(sdp);
+	if (!SRpnt) {
+		printk(KERN_WARNING "(sd_init_onedisk:) Request allocation "
+		       "failure.\n");
+		return;
+	}
 
-		memset((void *) &cmd[0], 0, 8);
-		cmd[0] = MODE_SENSE;
-		cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-			 ((sdp->lun << 5) & 0xe0) : 0;
-		cmd[2] = 0x3f;	/* Get all pages */
-		cmd[4] = 255;   /* Ask for 255 bytes, even tho we want just the first 8 */
-		SRpnt->sr_cmd_len = 0;
-		SRpnt->sr_sense_buffer[0] = 0;
-		SRpnt->sr_sense_buffer[2] = 0;
+	buffer = kmalloc(512, GFP_DMA);
+	if (!buffer) {
+		printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation "
+		       "failure.\n");
+		goto leave;
+	}
 
-		/* same code as READCAPA !! */
-		SRpnt->sr_data_direction = SCSI_DATA_READ;
-		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
-			    512, SD_TIMEOUT, MAX_RETRIES);
+	/* defaults, until the device tells us otherwise */
+	sdkp->capacity = 0;
+	sdkp->device->sector_size = 512;
+	sdkp->media_present = 1;
+	sdkp->write_prot = 0;
 
-		the_result = SRpnt->sr_result;
+	sd_spinup_disk(sdkp, diskname, SRpnt, buffer);
 
-		if (the_result) {
-			printk("%s: test WP failed, assume Write Enabled\n",
-			       nbuff);
-			/* alternatively, try page 0 */
-		} else {
-			sdkp->write_prot = ((buffer[2] & 0x80) != 0);
-			printk(KERN_NOTICE "%s: Write Protect is %s\n", nbuff,
-			       sdkp->write_prot ? "on" : "off");
-		}
+	if (sdkp->media_present)
+		sd_read_capacity(sdkp, diskname, SRpnt, buffer);
+
+	if (sdp->removable && sdkp->media_present)
+		sd_read_write_protect_flag(sdkp, diskname, SRpnt, buffer);
 
-	}			/* check for write protect */
 	SRpnt->sr_device->ten = 1;
 	SRpnt->sr_device->remap = 1;
-	SRpnt->sr_device->sector_size = sector_size;
-	/* Wake up a process waiting for device */
+
+ leave:
 	scsi_release_request(SRpnt);
-	SRpnt = NULL;
 
 	kfree(buffer);
-	return dsk_nr;
 }
 
 /*
@@ -1275,18 +1303,15 @@
 		vfree(sd_gendisks[k].flags);
 	}
 cleanup_mem:
-	if (sd_gendisks) vfree(sd_gendisks);
+	vfree(sd_gendisks);
 	sd_gendisks = NULL;
-	if (sd) vfree(sd);
+	vfree(sd);
 	sd = NULL;
-	if (sd_sizes) vfree(sd_sizes);
+	vfree(sd_sizes);
 	sd_sizes = NULL;
 	if (sd_dsk_arr) {
-                for (k = 0; k < sd_template.dev_max; ++k) {
-			sdkp = sd_dsk_arr[k];
-			if (sdkp)
-				vfree(sdkp);
-		}
+                for (k = 0; k < sd_template.dev_max; ++k)
+			vfree(sd_dsk_arr[k]);
 		vfree(sd_dsk_arr);
 		sd_dsk_arr = NULL;
 	}
@@ -1298,7 +1323,7 @@
 }
 
 /**
- *	sd_finish- called during driver initialization, after all
+ *	sd_finish - called during driver initialization, after all
  *	the sd_attach() calls are finished.
  *
  *	Note: this function is invoked from the scsi mid-level.
@@ -1321,12 +1346,12 @@
 		sdkp = sd_get_sdisk(k);
 		if (sdkp && (0 == sdkp->capacity) && sdkp->device) {
 			sd_init_onedisk(sdkp, k);
-			if (!sdkp->has_part_table) {
+			if (!sdkp->has_been_registered) {
 				sd_sizes[k << 4] = sdkp->capacity;
 				register_disk(&SD_GENDISK(k), MKDEV_SD(k),
 						1<<4, &sd_fops,
 						sdkp->capacity);
-				sdkp->has_part_table = 1;
+				sdkp->has_been_registered = 1;
 			}
 		}
 	}
@@ -1334,7 +1359,7 @@
 }
 
 /**
- *	sd_detect- called at the start of driver initialization, once 
+ *	sd_detect - called at the start of driver initialization, once 
  *	for each scsi device (not just disks) present.
  *
  *	Returns 0 if not interested in this scsi device (e.g. scanner);
@@ -1353,7 +1378,7 @@
 }
 
 /**
- *	sd_attach- called during driver initialization and whenever a
+ *	sd_attach - called during driver initialization and whenever a
  *	new scsi device is attached to the system. It is called once
  *	for each scsi device (not just disks) present.
  *	@sdp: pointer to mid level scsi device object
@@ -1372,7 +1397,7 @@
         unsigned int devnum;
 	Scsi_Disk *sdkp;
 	int dsk_nr;
-	char nbuff[6];
+	char diskname[6];
 	unsigned long iflags;
 
 	if ((NULL == sdp) ||
@@ -1393,8 +1418,8 @@
 	for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) {
 		sdkp = sd_dsk_arr[dsk_nr];
 		if (!sdkp->device) {
+			memset(sdkp, 0, sizeof(Scsi_Disk));
 			sdkp->device = sdp;
-			sdkp->has_part_table = 0;
 			break;
 		}
 	}
@@ -1412,15 +1437,15 @@
         SD_GENDISK(dsk_nr).de_arr[devnum] = sdp->de;
         if (sdp->removable)
 		SD_GENDISK(dsk_nr).flags[devnum] |= GENHD_FL_REMOVABLE;
-	sd_dskname(dsk_nr, nbuff);
+	sd_dskname(dsk_nr, diskname);
 	printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
 	       "id %d, lun %d\n", sdp->removable ? "removable " : "",
-	       nbuff, sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+	       diskname, sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
 	return 0;
 }
 
 /**
- *	revalidate_scsidisk- called to flush all partitions and partition 
+ *	revalidate_scsidisk - called to flush all partitions and partition 
  *	tables for a changed scsi disk. sd_init_onedisk() is then called
  *	followed by re-reading the new partition table.
  *      @dev: kernel device descriptor (kdev_t)
@@ -1436,8 +1461,8 @@
 	Scsi_Disk * sdkp;
 	Scsi_Device * sdp;
 
-	 SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", 
-			     DEVICE_NR(dev)));
+	SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", 
+				   DEVICE_NR(dev)));
 	sdkp = sd_get_sdisk(dsk_nr);
 	if ((NULL == sdkp) || (NULL == (sdp = sdkp->device)))
 		return -ENODEV;
@@ -1457,6 +1482,7 @@
 	sd_init_onedisk(sdkp, dsk_nr);
 
 	grok_partitions(dev, sdkp->capacity);
+
 leave:
 	sdp->busy = 0;
 	return res;
@@ -1468,7 +1494,7 @@
 }
 
 /**
- *	sd_detach- called whenever a scsi disk (previously recognized by
+ *	sd_detach - called whenever a scsi disk (previously recognized by
  *	sd_attach) is detached from the system. It is called (potentially
  *	multiple times) during sd module unload.
  *	@sdp: pointer to mid level scsi device object
@@ -1494,7 +1520,7 @@
 	for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) {
 		sdkp = sd_dsk_arr[dsk_nr];
 		if (sdkp->device == sdp) {
-			sdkp->has_part_table = 0;
+			sdkp->has_been_registered = 0;
 			sdkp->device = NULL;
 			sdkp->capacity = 0;
 			/* sdkp->detaching = 1; */
@@ -1522,7 +1548,7 @@
 }
 
 /**
- *	init_sd- entry point for this driver (both when built in or when
+ *	init_sd - entry point for this driver (both when built in or when
  *	a module).
  *
  *	Note: this function registers this driver with the scsi mid-level.
@@ -1535,14 +1561,13 @@
 }
 
 /**
- *	exit_sd- exit point for this driver (when it is	a module).
+ *	exit_sd - exit point for this driver (when it is	a module).
  *
  *	Note: this function unregisters this driver from the scsi mid-level.
  **/
 static void __exit exit_sd(void)
 {
 	int k;
-	Scsi_Disk * sdkp;
 
 	SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
 	scsi_unregister_device(&sd_template);
@@ -1551,15 +1576,12 @@
 
 	sd_registered--;
 	if (sd_dsk_arr != NULL) {
-		for (k = 0; k < sd_template.dev_max; ++k) {
-			sdkp = sd_dsk_arr[k];
-			if (sdkp)
-				vfree(sdkp);
-		}
+		for (k = 0; k < sd_template.dev_max; ++k)
+			vfree(sd_dsk_arr[k]);
 		vfree(sd_dsk_arr);
 	}
-	if (sd_sizes) vfree(sd_sizes);
-	if (sd) vfree((char *) sd);
+	vfree(sd_sizes);
+	vfree((char *) sd);
 	for (k = 0; k < N_USED_SD_MAJORS; k++) {
 		blk_dev[SD_MAJOR(k)].queue = NULL;
 		del_gendisk(&(sd_gendisks[k]));
diff -Nru a/drivers/scsi/sd.h b/drivers/scsi/sd.h
--- a/drivers/scsi/sd.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/sd.h	Sun Jun 16 19:31:40 2002
@@ -11,9 +11,6 @@
  */
 #ifndef _SD_H
 #define _SD_H
-/*
-   $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/07/24 06:27:38 root Exp root $
- */
 
 #ifndef _SCSI_H
 #include "scsi.h"
@@ -26,13 +23,11 @@
 extern struct hd_struct *sd;
 
 typedef struct scsi_disk {
-	unsigned capacity;	/* size in blocks */
+	unsigned capacity;		/* size in 512-byte sectors */
 	Scsi_Device *device;
-	unsigned char ready;	/* flag ready for FLOPTICAL */
-	unsigned char write_prot;	/* flag write_protect for rmvable dev */
-	unsigned char sector_bit_size;	/* sector_size = 2 to the  bit size power */
-	unsigned char sector_bit_shift;		/* power of 2 sectors per FS block */
-	unsigned has_part_table:1;	/* has partition table */
+	unsigned char media_present;
+	unsigned char write_prot;
+	unsigned has_been_registered:1;
 } Scsi_Disk;
 
 extern int revalidate_scsidisk(kdev_t dev, int maxusage);
@@ -48,22 +43,3 @@
 #define SD_PARTITION(i)		(((major(i) & SD_MAJOR_MASK) << 8) | (minor(i) & 255))
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
--- a/drivers/scsi/seagate.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/seagate.c	Sun Jun 16 19:31:40 2002
@@ -102,7 +102,6 @@
 #include "scsi.h"
 #include "hosts.h"
 #include "seagate.h"
-#include "constants.h"
 #include <linux/stat.h>
 #include <asm/uaccess.h>
 #include "sd.h"
@@ -1709,7 +1708,7 @@
 #endif
 	printk ("scsi%d : status = ", hostno);
 	print_status (status);
-	printk ("message = %02x\n", message);
+	printk (" message = %02x\n", message);
 #endif
 
 /* We shouldn't reach this until *after* BSY has been deasserted */
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/sr.c	Sun Jun 16 19:31:39 2002
@@ -50,12 +50,12 @@
 
 #define MAJOR_NR SCSI_CDROM_MAJOR
 #define LOCAL_END_REQUEST
+#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
 #include "sr.h"
 #include <scsi/scsi_ioctl.h>	/* For the door lock/unlock commands */
-#include "constants.h"
 
 MODULE_PARM(xa_test, "i");	/* see sr_ioctl.c */
 
diff -Nru a/drivers/scsi/sr.h b/drivers/scsi/sr.h
--- a/drivers/scsi/sr.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/sr.h	Sun Jun 16 19:31:40 2002
@@ -24,8 +24,6 @@
 	Scsi_Device *device;
 	unsigned int vendor;	/* vendor code, see sr_vendor.c         */
 	unsigned long ms_offset;	/* for reading multisession-CD's        */
-	unsigned char sector_bit_size;	/* sector size = 2^sector_bit_size      */
-	unsigned char sector_bit_shift;		/* sectors/FS block = 2^sector_bit_shift */
 	unsigned needs_sector_size:1;	/* needs to get sector size */
 	unsigned use:1;		/* is this device still supportable     */
 	unsigned xa_flag:1;	/* CD has XA sectors ? */
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/st.c	Sun Jun 16 19:31:40 2002
@@ -55,6 +55,7 @@
 #endif
 
 #define MAJOR_NR SCSI_TAPE_MAJOR
+#define DEVICE_NR(device) (minor(device) & 0x7f)
 #include <linux/blk.h>
 
 #include "scsi.h"
@@ -65,8 +66,6 @@
 
 #include "st_options.h"
 #include "st.h"
-
-#include "constants.h"
 
 static int buffer_kbs;
 static int write_threshold_kbs;
diff -Nru a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
--- a/drivers/scsi/sun3_scsi.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/sun3_scsi.c	Sun Jun 16 19:31:39 2002
@@ -78,7 +78,6 @@
 #include "hosts.h"
 #include "sun3_scsi.h"
 #include "NCR5380.h"
-#include "constants.h"
 
 #define USE_WRAPPER
 #define RESET_BOOT
diff -Nru a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
--- a/drivers/scsi/sym53c8xx.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/scsi/sym53c8xx.c	Sun Jun 16 19:31:39 2002
@@ -143,7 +143,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 #include "sd.h"
 
 #include <linux/types.h>
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h	Sun Jun 16 19:31:41 2002
@@ -99,7 +99,6 @@
 
 #include "../scsi.h"
 #include "../hosts.h"
-#include "../constants.h"
 #include "../sd.h"
 
 #include <linux/types.h>
diff -Nru a/drivers/scsi/t128.c b/drivers/scsi/t128.c
--- a/drivers/scsi/t128.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/scsi/t128.c	Sun Jun 16 19:31:41 2002
@@ -116,7 +116,6 @@
 #include "t128.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
-#include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
 #include <linux/init.h>
diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
--- a/drivers/scsi/tmscsim.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/scsi/tmscsim.c	Sun Jun 16 19:31:40 2002
@@ -228,7 +228,6 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
 #include <scsi/scsicam.h>
@@ -254,8 +253,6 @@
  * undef  : traditional save_flags; cli; restore_flags;
  */
 
-//#define DEBUG_SPINLOCKS 2	/* Set to 0, 1 or 2 in include/linux/spinlock.h */
-
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
 # include <linux/init.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
@@ -293,7 +290,7 @@
 
 # if USE_SPINLOCKS == 3 /* both */
 
-#  if defined (CONFIG_SMP) || DEBUG_SPINLOCKS > 0
+#  if defined (CONFIG_SMP)
 #   define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
 #  else
 #   define DC390_LOCKA_INIT
@@ -322,7 +319,7 @@
 
 #  if USE_SPINLOCKS == 2 /* adapter specific locks */
 
-#   if defined (CONFIG_SMP) || DEBUG_SPINLOCKS > 0
+#   if defined (CONFIG_SMP)
 #    define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
 #   else
 #    define DC390_LOCKA_INIT
diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/Makefile	Sun Jun 16 19:31:41 2002
@@ -3,7 +3,6 @@
 #
 
 # Object files in subdirectories
-mod-subdirs	:= serial
 
 obj-$(CONFIG_USB)		+= core/
 
@@ -24,6 +23,7 @@
 
 obj-$(CONFIG_USB_STORAGE)	+= storage/
 
+obj-$(CONFIG_USB_AIPTEK)	+= input/
 obj-$(CONFIG_USB_HID)		+= input/
 obj-$(CONFIG_USB_KBD)		+= input/
 obj-$(CONFIG_USB_MOUSE)		+= input/
diff -Nru a/drivers/usb/class/Config.help b/drivers/usb/class/Config.help
--- a/drivers/usb/class/Config.help	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/class/Config.help	Sun Jun 16 19:31:40 2002
@@ -34,6 +34,26 @@
   The module will be called bluetty.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+CONFIG_USB_MIDI
+  Say Y here if you want to connect a USB MIDI device to your
+  computer's USB port. This driver is for devices that comply with
+  'Universal Serial Bus Device Class Definition for MIDI Device'.
+
+  The following devices are known to work:
+    * Steinberg USB2MIDI
+    * Roland MPU64
+    * Roland PC-300
+    * Roland SC8850
+    * Roland UM-1
+    * Roland UM-2
+    * Roland UA-100
+    * Yamaha MU1000
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called usb-midi.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 CONFIG_USB_PRINTER
   Say Y here if you want to connect a USB printer to your computer's
   USB port.
diff -Nru a/drivers/usb/class/printer.c b/drivers/usb/class/printer.c
--- a/drivers/usb/class/printer.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/class/printer.c	Sun Jun 16 19:31:39 2002
@@ -64,7 +64,7 @@
 #define DRIVER_DESC "USB Printer Device Class driver"
 
 #define USBLP_BUF_SIZE		8192
-#define DEVICE_ID_SIZE		1024
+#define USBLP_DEVICE_ID_SIZE	1024
 
 /* ioctls: */
 #define LPGETSTATUS		0x060b		/* same as in drivers/char/lp.c */
@@ -418,7 +418,8 @@
 {
 	struct usblp *usblp = file->private_data;
 	int length, err, i;
-	unsigned char status, newChannel;
+	unsigned char lpstatus, newChannel;
+	int status;
 	int twoints[2];
 	int retval = 0;
 
@@ -569,12 +570,13 @@
 		switch (cmd) {
 
 			case LPGETSTATUS:
-				if (usblp_read_status(usblp, &status)) {
+				if (usblp_read_status(usblp, &lpstatus)) {
 					err("usblp%d: failed reading printer status", usblp->minor);
 					retval = -EIO;
 					goto done;
 				}
-				if (copy_to_user ((unsigned char *)arg, &status, 1))
+				status = lpstatus;
+				if (copy_to_user ((int *)arg, &status, sizeof(int)))
 					retval = -EFAULT;
 				break;
 
@@ -722,7 +724,8 @@
 			usblp->minor, usblp->readurb->status);
 		usblp->readurb->dev = usblp->dev;
  		usblp->readcount = 0;
-		usb_submit_urb(usblp->readurb, GFP_KERNEL);
+		if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
+			dbg("error submitting urb"); 
 		count = -EIO;
 		goto done;
 	}
@@ -839,7 +842,7 @@
 	/* Malloc device ID string buffer to the largest expected length,
 	 * since we can re-query it on an ioctl and a dynamic string
 	 * could change in length. */
-	if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
+	if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
 		err("out of memory for device_id_string");
 		goto abort_minor;
 	}
@@ -1045,7 +1048,7 @@
 {
 	int err, length;
 
-	err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
+	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
 	if (err < 0) {
 		dbg("usblp%d: error = %d reading IEEE-1284 Device ID string",
 			usblp->minor, err);
@@ -1059,8 +1062,8 @@
 	length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1];
 	if (length < 2)
 		length = 2;
-	else if (length >= DEVICE_ID_SIZE)
-		length = DEVICE_ID_SIZE - 1;
+	else if (length >= USBLP_DEVICE_ID_SIZE)
+		length = USBLP_DEVICE_ID_SIZE - 1;
 	usblp->device_id_string[length] = '\0';
 
 	dbg("usblp%d Device ID string [len=%d]=\"%s\"",
diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/core/devices.c	Sun Jun 16 19:31:40 2002
@@ -574,8 +574,10 @@
 		bus = list_entry(buslist, struct usb_bus, bus_list);
 		/* recurse through all children of the root hub */
 		ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
-		if (ret < 0)
+		if (ret < 0) {
+			up(&usb_bus_list_lock);
 			return ret;
+		}
 		total_written += ret;
 	}
 	up (&usb_bus_list_lock);
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/core/devio.c	Sun Jun 16 19:31:40 2002
@@ -215,8 +215,7 @@
         unsigned long flags;
         
         spin_lock_irqsave(&ps->lock, flags);
-        list_del(&as->asynclist);
-        INIT_LIST_HEAD(&as->asynclist);
+        list_del_init(&as->asynclist);
         spin_unlock_irqrestore(&ps->lock, flags);
 }
 
@@ -228,8 +227,7 @@
         spin_lock_irqsave(&ps->lock, flags);
         if (!list_empty(&ps->async_completed)) {
                 as = list_entry(ps->async_completed.next, struct async, asynclist);
-                list_del(&as->asynclist);
-                INIT_LIST_HEAD(&as->asynclist);
+                list_del_init(&as->asynclist);
         }
         spin_unlock_irqrestore(&ps->lock, flags);
         return as;
@@ -247,8 +245,7 @@
                 p = p->next;
                 if (as->userurb != userurb)
                         continue;
-                list_del(&as->asynclist);
-                INIT_LIST_HEAD(&as->asynclist);
+                list_del_init(&as->asynclist);
                 spin_unlock_irqrestore(&ps->lock, flags);
                 return as;
         }
@@ -263,8 +260,7 @@
 	struct siginfo sinfo;
 
         spin_lock(&ps->lock);
-        list_del(&as->asynclist);
-        list_add_tail(&as->asynclist, &ps->async_completed);
+        list_move_tail(&as->asynclist, &ps->async_completed);
         spin_unlock(&ps->lock);
         wake_up(&ps->wait);
 	if (as->signr) {
@@ -284,8 +280,7 @@
         spin_lock_irqsave(&ps->lock, flags);
         while (!list_empty(&ps->async_pending)) {
                 as = list_entry(ps->async_pending.next, struct async, asynclist);
-                list_del(&as->asynclist);
-                INIT_LIST_HEAD(&as->asynclist);
+                list_del_init(&as->asynclist);
                 spin_unlock_irqrestore(&ps->lock, flags);
                 /* usb_unlink_urb calls the completion handler with status == -ENOENT */
                 usb_unlink_urb(as->urb);
@@ -528,8 +523,8 @@
 	unsigned int i;
 
 	lock_kernel();
-	list_del(&ps->list);
-	INIT_LIST_HEAD(&ps->list);
+	list_del_init(&ps->list);
+
 	if (ps->dev) {
 		for (i = 0; ps->ifclaimed && i < 8*sizeof(ps->ifclaimed); i++)
 			if (test_bit(i, &ps->ifclaimed))
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/core/hcd-pci.c	Sun Jun 16 19:31:40 2002
@@ -20,6 +20,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/irq.h>
 
 #ifdef CONFIG_USB_DEBUG
 	#define DEBUG
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/core/message.c	Sun Jun 16 19:31:39 2002
@@ -471,9 +471,13 @@
 		return 0;
 	}
 
+	if (alternate < 0 || alternate >= iface->num_altsetting)
+		return -EINVAL;
+
 	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-	    USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,
-	    interface, NULL, 0, HZ * 5)) < 0)
+				   USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
+				   iface->altsetting[alternate].bAlternateSetting,
+				   interface, NULL, 0, HZ * 5)) < 0)
 		return ret;
 
 	iface->act_altsetting = alternate;
diff -Nru a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c
--- a/drivers/usb/host/hc_simple.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/host/hc_simple.c	Sun Jun 16 19:31:40 2002
@@ -220,14 +220,12 @@
 		/* URB active? */
 
 		if (urb->transfer_flags & (USB_ASYNC_UNLINK | USB_TIMEOUT_KILLED)) {
-			/* asynchron with callback */
-
-			list_del (&urb->urb_list);	/* relink the urb to the del list */
-			list_add (&urb->urb_list, &hci->del_list);
+			/* asynchronous with callback */
+			/* relink the urb to the del list */
+			list_move (&urb->urb_list, &hci->del_list);
 			spin_unlock_irqrestore (&usb_urb_lock, flags);
-
 		} else {
-			/* synchron without callback */
+			/* synchronous without callback */
 
 			add_wait_queue (&hci->waitq, &wait);
 
@@ -235,8 +233,8 @@
 			comp = urb->complete;
 			urb->complete = NULL;
 
-			list_del (&urb->urb_list);	/* relink the urb to the del list */
-			list_add (&urb->urb_list, &hci->del_list);
+			/* relink the urb to the del list */
+			list_move(&urb->urb_list, &hci->del_list);
 
 			spin_unlock_irqrestore (&usb_urb_lock, flags);
 
@@ -560,10 +558,9 @@
 	epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)];
 
 	DBGFUNC ("enter qu_next_urb\n");
-	list_del (&urb->urb_list);
-	INIT_LIST_HEAD (&urb->urb_list);
-	if (ed->pipe_head == urb) {
+	list_del_init(&urb->urb_list);
 
+	if (ed->pipe_head == urb) {
 #ifdef HC_URB_TIMEOUT
 		if (urb->timeout)
 			del_timer (&ed->timeout);
@@ -574,8 +571,7 @@
 
 		if (!list_empty (&ed->urb_queue)) {
 			urb = list_entry (ed->urb_queue.next, struct urb, urb_list);
-			list_del (&urb->urb_list);
-			INIT_LIST_HEAD (&urb->urb_list);
+			list_del_init (&urb->urb_list);
 			ed->pipe_head = urb;
 			qu_queue_active_urb (hci, urb, ed);
 		} else {
@@ -756,8 +752,7 @@
 		 * only when the new SOF happens */
 
 		lh = hci->bulk_list.next;
-		list_del (&hci->bulk_list);
-		list_add (&hci->bulk_list, lh);
+		list_move (&hci->bulk_list, lh);
 	}
 	return 0;
 }
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/host/ohci-hcd.c	Sun Jun 16 19:31:39 2002
@@ -100,13 +100,12 @@
  *	- lots more testing!!
  */
 
-#define DRIVER_VERSION "2002-Jun-01"
+#define DRIVER_VERSION "2002-Jun-10"
 #define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell"
 #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
 
 /*-------------------------------------------------------------------------*/
 
-#define OHCI_USE_NPS		// force NoPowerSwitching mode
 // #define OHCI_VERBOSE_DEBUG	/* not always helpful */
 
 /* For initializing controller (mask in an HCFS mode too) */
@@ -307,7 +306,6 @@
 	spin_lock_irqsave (&ohci->lock, flags);
 	for (i = 0; i < 32; i++) {
 		struct ed	*ed = dev->ep [i];
-		struct td	*tdTailP;
 
 		if (!ed)
 			continue;
@@ -319,10 +317,7 @@
 		case ED_NEW:
 			break;
 		case ED_UNLINK:
-			tdTailP = dma_to_td (ohci,
-				le32_to_cpup (&ed->hwTailP) & 0xfffffff0);
-			td_free (ohci, tdTailP); /* free dummy td */
-			hash_free_ed (ohci, ed);
+			td_free (ohci, ed->dummy);
 			break;
 
 		case ED_OPER:
@@ -353,22 +348,23 @@
 
 static int hc_reset (struct ohci_hcd *ohci)
 {
-	int timeout = 30;
-	int smm_timeout = 50; /* 0,5 sec */
-	 	
-	if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
+	u32 temp;
+
+	/* SMM owns the HC?  not for long! */
+	if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+		temp = 50;	/* arbitrary: half second */
 		writel (OHCI_INTR_OC, &ohci->regs->intrenable);
 		writel (OHCI_OCR, &ohci->regs->cmdstatus);
 		dbg ("USB HC TakeOver from SMM");
 		while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
 			wait_ms (10);
-			if (--smm_timeout == 0) {
+			if (--temp == 0) {
 				err ("USB HC TakeOver failed!");
 				return -1;
 			}
 		}
-	}	
-		
+	}
+
 	/* Disable HC interrupts */
 	writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
 
@@ -376,31 +372,49 @@
 		ohci->hcd.self.bus_name,
 		readl (&ohci->regs->control));
 
-  	/* Reset USB (needed by some controllers) */
-	writel (0, &ohci->regs->control);
-      	
-	/* HC Reset requires max 10 ms delay */
+  	/* Reset USB (needed by some controllers); RemoteWakeupConnected
+	 * saved if boot firmware (BIOS/SMM/...) told us it's connected
+	 */
+	ohci->hc_control = readl (&ohci->regs->control);
+	ohci->hc_control &= OHCI_CTRL_RWC;	/* hcfs 0 = RESET */
+	writel (ohci->hc_control, &ohci->regs->control);
+	wait_ms (50);
+
+	/* HC Reset requires max 10 us delay */
 	writel (OHCI_HCR,  &ohci->regs->cmdstatus);
+	temp = 30;	/* ... allow extra time */
 	while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
-		if (--timeout == 0) {
+		if (--temp == 0) {
 			err ("USB HC reset timed out!");
 			return -1;
-		}	
+		}
 		udelay (1);
-	}	 
+	}
+
+	/* now we're in the SUSPEND state ... must go OPERATIONAL
+	 * within 2msec else HC enters RESUME
+	 *
+	 * ... but some hardware won't init fmInterval "by the book"
+	 * (SiS, OPTi ...), so reset again instead.  SiS doesn't need
+	 * this if we write fmInterval after we're OPERATIONAL.
+	 */
+	writel (ohci->hc_control, &ohci->regs->control);
+
 	return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
+#define	FI		0x2edf		/* 12000 bits per frame (-1) */
+#define LSTHRESH	0x628		/* lowspeed bit threshold */
+
 /* Start an OHCI controller, set the BUS operational
  * enable interrupts 
  * connect the virtual root hub
  */
 static int hc_start (struct ohci_hcd *ohci)
 {
-  	__u32			mask;
-  	unsigned int		fminterval;
+  	u32			mask;
   	struct usb_device	*udev;
 
 	spin_lock_init (&ohci->lock);
@@ -409,35 +423,44 @@
 
 	/* Tell the controller where the control and bulk lists are
 	 * The lists are empty now. */
-	 
 	writel (0, &ohci->regs->ed_controlhead);
 	writel (0, &ohci->regs->ed_bulkhead);
-	
+
 	/* a reset clears this */
 	writel ((u32) ohci->hcca_dma, &ohci->regs->hcca);
-   
-  	fminterval = 0x2edf;
-	writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
-	fminterval |= ((((fminterval - 210) * 6) / 7) << 16); 
-	writel (fminterval, &ohci->regs->fminterval);	
-	writel (0x628, &ohci->regs->lsthresh);
+
+	/* force default fmInterval (we won't adjust it); init thresholds
+	 * for last FS and LS packets, reserve 90% for periodic.
+	 */
+	writel ((((6 * (FI - 210)) / 7) << 16) | FI, &ohci->regs->fminterval);
+	writel (((9 * FI) / 10) & 0x3fff, &ohci->regs->periodicstart);
+	writel (LSTHRESH, &ohci->regs->lsthresh);
+
+	/* some OHCI implementations are finicky about how they init.
+	 * bogus values here mean not even enumeration could work.
+	 */
+	if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
+			|| !readl (&ohci->regs->periodicstart)) {
+		err ("%s init err", ohci->hcd.self.bus_name);
+		return -EOVERFLOW;
+	}
 
  	/* start controller operations */
- 	ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+	ohci->hc_control &= OHCI_CTRL_RWC;
+ 	ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
 	ohci->disabled = 0;
  	writel (ohci->hc_control, &ohci->regs->control);
- 
+
 	/* Choose the interrupts we care about now, others later on demand */
 	mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH;
 	writel (mask, &ohci->regs->intrstatus);
 	writel (mask, &ohci->regs->intrenable);
 
-#ifdef	OHCI_USE_NPS
-	/* required for AMD-756 and some Mac platforms */
-	writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
+	/* hub power always on: required for AMD-756 and some Mac platforms */
+	writel ((roothub_a (ohci) | RH_A_NPS) & ~(RH_A_PSM | RH_A_OCPM),
 		&ohci->regs->roothub.a);
 	writel (RH_HS_LPSC, &ohci->regs->roothub.status);
-#endif	/* OHCI_USE_NPS */
+	writel (0, &ohci->regs->roothub.b);
 
 	// POTPGT delay is bits 24-31, in 2 ms units.
 	mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
@@ -446,9 +469,10 @@
 	ohci->hcd.self.root_hub = udev = usb_alloc_dev (NULL, &ohci->hcd.self);
 	ohci->hcd.state = USB_STATE_READY;
 	if (!udev) {
-	    ohci->disabled = 1;
-// FIXME cleanup
-	    return -ENOMEM;
+		ohci->disabled = 1;
+		ohci->hc_control &= ~OHCI_CTRL_HCFS;
+		writel (ohci->hc_control, &ohci->regs->control);
+		return -ENOMEM;
 	}
 
 	usb_connect (udev);
@@ -456,10 +480,11 @@
 	if (usb_register_root_hub (udev, ohci->parent_dev) != 0) {
 		usb_free_dev (udev); 
 		ohci->disabled = 1;
-// FIXME cleanup
+		ohci->hc_control &= ~OHCI_CTRL_HCFS;
+		writel (ohci->hc_control, &ohci->regs->control);
 		return -ENODEV;
 	}
-	
+
 	return 0;
 }
 
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/host/ohci-q.c	Sun Jun 16 19:31:41 2002
@@ -440,14 +440,16 @@
 			spin_unlock_irqrestore (&ohci->lock, flags);
 			return NULL;
 		}
+		ed->dummy = td;
 		ed->hwTailP = cpu_to_le32 (td->td_dma);
-		ed->hwHeadP = ed->hwTailP;	
+		ed->hwHeadP = ed->hwTailP;	/* ED_C, ED_H zeroed */
 		ed->state = ED_UNLINK;
 		ed->type = usb_pipetype (pipe);
 	}
 
-// FIXME:  don't do this if it's linked to the HC,
-// we might clobber data toggle or other state ...
+// FIXME:  don't do this if it's linked to the HC, or without knowing it's
+// safe to clobber state/mode info tied to (previous) config/altsetting.
+// (but dev0/ep0, used by set_address, must get clobbered)
 
 	ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe)
 			| usb_pipeendpoint (pipe) << 7
@@ -523,27 +525,31 @@
 	dma_addr_t data, int len,
 	struct urb *urb, int index)
 {
-	volatile struct td	*td, *td_pt;
+	struct td		*td, *td_pt;
 	urb_priv_t		*urb_priv = urb->hcpriv;
+	int			is_iso = info & TD_ISO;
 
 	if (index >= urb_priv->length) {
 		err ("internal OHCI error: TD index > length");
 		return;
 	}
 
-#if 0
-	/* no interrupt needed except for URB's last TD */
+	/* aim for only one interrupt per urb.  mostly applies to control
+	 * and iso; other urbs rarely need more than one TD per urb.
+	 *
+	 * NOTE: could delay interrupts even for the last TD, and get fewer
+	 * interrupts ... increasing per-urb latency by sharing interrupts.
+	 */
 	if (index != (urb_priv->length - 1))
-		info |= TD_DI;
-#endif
+		info |= is_iso ? TD_DI_SET (7) : TD_DI_SET (1);
 
 	/* use this td as the next dummy */
 	td_pt = urb_priv->td [index];
 	td_pt->hwNextTD = 0;
 
 	/* fill the old dummy TD */
-	td = urb_priv->td [index] = dma_to_td (ohci,
-			le32_to_cpup (&urb_priv->ed->hwTailP));
+	td = urb_priv->td [index] = urb_priv->ed->dummy;
+	urb_priv->ed->dummy = td_pt;
 
 	td->ed = urb_priv->ed;
 	td->next_dl_td = NULL;
@@ -554,7 +560,7 @@
 		data = 0;
 
 	td->hwINFO = cpu_to_le32 (info);
-	if ((td->ed->type) == PIPE_ISOCHRONOUS) {
+	if (is_iso) {
 		td->hwCBP = cpu_to_le32 (data & 0xFFFFF000);
 		td->ed->intriso.last_iso = info & 0xffff;
 	} else {
@@ -901,6 +907,7 @@
 		 *     [a2] some (earlier) URBs still linked, re-enable
 		 * (b) finishing ED unlink
 		 *     [b1] no URBs queued, ED is truly idle now
+		 *          ... we could set state ED_NEW and free dummy
 		 *     [b2] URBs now queued, link ED back into schedule
 		 * right now we only have (a)
 		 */
@@ -910,9 +917,6 @@
 		if (tdHeadP == tdTailP) {
 			if (ed->state == ED_OPER)
 				start_ed_unlink (ohci, ed);
-			td_free (ohci, tdTailP);
-			ed->hwINFO = ED_SKIP;
-			ed->state = ED_NEW;
 		} else
 			ed->hwINFO &= ~ED_SKIP;
 
diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
--- a/drivers/usb/host/ohci.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/host/ohci.h	Sun Jun 16 19:31:41 2002
@@ -29,6 +29,7 @@
 	/* rest are purely for the driver's use */
 	dma_addr_t		dma;		/* addr of ED */
 	struct ed		*ed_prev;	/* for non-interrupt EDs */
+	struct td		*dummy;
 
 	u8			type; 		/* PIPE_{BULK,...} */
 	u8			interval;	/* interrupt, isochronous */
@@ -63,24 +64,33 @@
 struct td {
 	/* first fields are hardware-specified, le32 */
 	__u32		hwINFO;		/* transfer info bitmask */
+
+	/* hwINFO bits for both general and iso tds: */
 #define TD_CC       0xf0000000			/* condition code */
 #define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
 //#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
+#define TD_DI       0x00E00000			/* frames before interrupt */
+#define TD_DI_SET(X) (((X) & 0x07)<< 21)
+	/* these two bits are available for definition/use by HCDs in both
+	 * general and iso tds ... others are available for only one type
+	 */
+//#define TD____	    0x00020000
+#define TD_ISO	    0x00010000			/* copy of ED_ISO */
+
+	/* hwINFO bits for general tds: */
 #define TD_EC       0x0C000000			/* error count */
 #define TD_T        0x03000000			/* data toggle state */
 #define TD_T_DATA0  0x02000000				/* DATA0 */
 #define TD_T_DATA1  0x03000000				/* DATA1 */
 #define TD_T_TOGGLE 0x00000000				/* uses ED_C */
-#define TD_DI       0x00E00000			/* frames before interrupt */
-//#define TD_DI_SET(X) (((X) & 0x07)<< 21)
 #define TD_DP       0x00180000			/* direction/pid */
 #define TD_DP_SETUP 0x00000000			/* SETUP pid */
 #define TD_DP_IN    0x00100000				/* IN pid */
 #define TD_DP_OUT   0x00080000				/* OUT pid */
 							/* 0x00180000 rsvd */
 #define TD_R        0x00040000			/* round: short packets OK? */
-					/* bits 0x1ffff are defined by HCD */
-#define TD_ISO	    0x00010000			/* copy of ED_ISO */
+
+	/* (no hwINFO #defines yet for iso tds) */
 
   	__u32		hwCBP;		/* Current Buffer Pointer (or 0) */
   	__u32		hwNextTD;	/* Next TD Pointer */
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/host/uhci-hcd.c	Sun Jun 16 19:31:41 2002
@@ -1773,10 +1773,8 @@
 			uhci_fsbr_timeout(uhci, u);
 
 		/* Check if the URB timed out */
-		if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout)) {
-			list_del(&up->urb_list);
-			list_add_tail(&up->urb_list, &list);
-		}
+		if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout))
+			list_move_tail(&up->urb_list, &list);
 
 		spin_unlock(&u->lock);
 	}
diff -Nru a/drivers/usb/host/uhci.c b/drivers/usb/host/uhci.c
--- a/drivers/usb/host/uhci.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/host/uhci.c	Sun Jun 16 19:31:41 2002
@@ -2008,10 +2008,8 @@
 			uhci_fsbr_timeout(uhci, u);
 
 		/* Check if the URB timed out */
-		if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout)) {
-			list_del(&u->urb_list);
-			list_add_tail(&u->urb_list, &list);
-		}
+		if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout))
+			list_move_tail(&u->urb_list, &list);
 
 		spin_unlock(&u->lock);
 	}
diff -Nru a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c
--- a/drivers/usb/image/hpusbscsi.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/image/hpusbscsi.c	Sun Jun 16 19:31:41 2002
@@ -273,8 +273,6 @@
 	usb_urb_callback usb_callback;
 	int res;
 
-	hpusbscsi->use_count++;
-
 	/* we don't answer for anything but our single device on any faked host controller */
 	if ( srb->device->lun || srb->device->id || srb->device->channel ) {
 		if (callback) {
@@ -341,7 +339,6 @@
 	}
 
 out:
-	hpusbscsi->use_count--;
 	return 0;
 }
 
diff -Nru a/drivers/usb/image/hpusbscsi.h b/drivers/usb/image/hpusbscsi.h
--- a/drivers/usb/image/hpusbscsi.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/image/hpusbscsi.h	Sun Jun 16 19:31:39 2002
@@ -20,25 +20,25 @@
         int ep_in;
         int ep_int;
         int interrupt_interval;
-
+	int number;
+	int fragment;
         struct Scsi_Host *host;
-        Scsi_Host_Template ctempl;
-        int number;
+
 	scsi_callback scallback;
 	Scsi_Cmnd *srb;
-	u8 sense_command[SENSE_COMMAND_SIZE];
 
-        int use_count;
+
         wait_queue_head_t pending;
         wait_queue_head_t deathrow;
 
         struct urb *dataurb;
         struct urb *controlurb;
-        int fragment;
+
 
         int state;
         int current_data_pipe;
-
+	Scsi_Host_Template ctempl;
+	u8 sense_command[SENSE_COMMAND_SIZE];
         u8 scsi_state_byte;
 };
 
diff -Nru a/drivers/usb/input/Config.help b/drivers/usb/input/Config.help
--- a/drivers/usb/input/Config.help	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/input/Config.help	Sun Jun 16 19:31:40 2002
@@ -62,6 +62,17 @@
 
   If even remotely unsure, say N.
 
+CONFIG_USB_AIPTEK
+  Say Y here if you want to use the USB version of the Aiptek 6000U
+  or Aiptek 8000U tablet.  Make sure to say Y to "Mouse support"
+  (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+  (CONFIG_INPUT_EVDEV) as well.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called aiptek.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 CONFIG_USB_WACOM
   Say Y here if you want to use the USB version of the Wacom Intuos
   or Graphire tablet.  Make sure to say Y to "Mouse support"
diff -Nru a/drivers/usb/input/Config.in b/drivers/usb/input/Config.in
--- a/drivers/usb/input/Config.in	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/input/Config.in	Sun Jun 16 19:31:41 2002
@@ -14,5 +14,6 @@
    dep_tristate '  USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
 fi
 
+dep_tristate '  Aiptek 6000U/8000U tablet support' CONFIG_USB_AIPTEK $CONFIG_USB $CONFIG_INPUT
 dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
    
diff -Nru a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
--- a/drivers/usb/input/Makefile	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/input/Makefile	Sun Jun 16 19:31:39 2002
@@ -13,6 +13,7 @@
 	hid-objs        += hid-input.o
 endif
 
+obj-$(CONFIG_USB_AIPTEK)	+= aiptek.o
 obj-$(CONFIG_USB_HID)		+= hid.o
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
 obj-$(CONFIG_USB_MOUSE)		+= usbmouse.o
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/input/aiptek.c	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,339 @@
+/*
+ *  Native support for the Aiptek 8000U
+ *
+ *  Copyright (c) 2001 Chris Atenasio		<chris@crud.net>
+ *
+ *  based on wacom.c by
+ *     Vojtech Pavlik      <vojtech@suse.cz>
+ *     Andreas Bach Aaen   <abach@stofanet.dk>
+ *     Clifford Wolf       <clifford@clifford.at>
+ *     Sam Mosel           <sam.mosel@computer.org>
+ *     James E. Blair      <corvus@gnu.org>
+ *     Daniel Egger        <egger@suse.de>
+ *
+ *
+ *  Many thanks to Oliver Kuechemann for his support.
+ *
+ *  ChangeLog:
+ *      v0.1 - Initial release
+ *      v0.2 - Hack to get around fake event 28's.
+ *      v0.3 - Make URB dynamic (Bryan W. Headley, Jun-8-2002)
+ *             (kernel 2.5.x variant, June-14-2002)
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v0.3"
+#define DRIVER_AUTHOR "Chris Atenasio <chris@crud.net>"
+#define DRIVER_DESC "USB Aiptek 6000U/8000U tablet driver (Linux 2.5.x)"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Aiptek status packet:
+ *
+ *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
+ * byte0   0     0     0     0     0     0     1     0
+ * byte1  X7    X6    X5    X4    X3    X2    X1    X0
+ * byte2  X15   X14   X13   X12   X11   X10   X9    X8
+ * byte3  Y7    Y6    Y5    Y4    Y3    Y2    Y1    Y0
+ * byte4  Y15   Y14   Y13   Y12   Y11   Y10   Y9    Y8
+ * byte5   *     *     *    BS2   BS1   Tip   DV    IR
+ * byte6  P7    P6    P5    P4    P3    P2    P1    P0
+ * byte7  P15   P14   P13   P12   P11   P10   P9    P8
+ *
+ * IR: In Range = Proximity on
+ * DV = Data Valid
+ *
+ * 
+ * Command Summary:
+ *
+ * Command/Data    Description     Return Bytes    Return Value
+ * 0x10/0x00       SwitchToMouse       0
+ * 0x10/0x01       SwitchToTablet      0
+ * 0x18/0x04       Resolution500LPI    0
+ * 0x17/0x00       FilterOn            0
+ * 0x12/0xFF       AutoGainOn          0
+ * 0x01/0x00       GetXExtension       2           MaxX
+ * 0x01/0x01       GetYExtension       2           MaxY
+ * 0x02/0x00       GetModelCode        2           ModelCode = LOBYTE
+ * 0x03/0x00       GetODMCode          2           ODMCode
+ * 0x08/0x00       GetPressureLevels   2           =512
+ * 0x04/0x00       GetFirmwareVersion  2           Firmware Version
+ *
+ *
+ * To initialize the tablet:
+ *
+ * (1) Send command Resolution500LPI
+ * (2) Option Commands (GetXExtension, GetYExtension)
+ * (3) Send command SwitchToTablet
+ */
+
+#define USB_VENDOR_ID_AIPTEK   0x08ca
+
+struct aiptek_features {
+	char *name;
+	int pktlen;
+	int x_max;
+	int y_max;
+	int pressure_min;
+	int pressure_max;
+	void (*irq) (struct urb * urb);
+	unsigned long evbit;
+	unsigned long absbit;
+	unsigned long relbit;
+	unsigned long btnbit;
+	unsigned long digibit;
+};
+
+struct aiptek {
+	signed char data[10];
+	struct input_dev dev;
+	struct usb_device *usbdev;
+	struct urb *irq;
+	struct aiptek_features *features;
+	int tool;
+	int open;
+};
+
+static void
+aiptek_irq(struct urb *urb)
+{
+	struct aiptek *aiptek = urb->context;
+	unsigned char *data = aiptek->data;
+	struct input_dev *dev = &aiptek->dev;
+	int x;
+	int y;
+	int pressure;
+	int proximity;
+
+	if (urb->status)
+		return;
+
+	if ((data[0] & 2) == 0) {
+		dbg("received unknown report #%d", data[0]);
+	}
+
+	proximity = data[5] & 0x01;
+	input_report_key(dev, BTN_TOOL_PEN, proximity);
+
+	x = ((__u32) data[1]) | ((__u32) data[2] << 8);
+	y = ((__u32) data[3]) | ((__u32) data[4] << 8);
+	pressure = ((__u32) data[6]) | ((__u32) data[7] << 8);
+	pressure -= aiptek->features->pressure_min;
+
+	if (pressure < 0) {
+		pressure = 0;
+	}
+
+	if (proximity) {
+		input_report_abs(dev, ABS_X, x);
+		input_report_abs(dev, ABS_Y, y);
+		input_report_abs(dev, ABS_PRESSURE, pressure);
+		input_report_key(dev, BTN_TOUCH, data[5] & 0x04);
+		input_report_key(dev, BTN_STYLUS, data[5] & 0x08);
+		input_report_key(dev, BTN_STYLUS2, data[5] & 0x10);
+	}
+
+}
+
+struct aiptek_features aiptek_features[] = {
+	{"Aiptek 6000U/8000U",
+	 8, 3000, 2250, 26, 511, aiptek_irq, 0, 0, 0, 0},
+	{NULL, 0}
+};
+
+struct usb_device_id aiptek_ids[] = {
+	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20), driver_info:0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, aiptek_ids);
+
+static int
+aiptek_open(struct input_dev *dev)
+{
+	struct aiptek *aiptek = dev->private;
+
+	if (aiptek->open++)
+		return 0;
+
+	aiptek->irq->dev = aiptek->usbdev;
+	if (usb_submit_urb(aiptek->irq, GFP_KERNEL))
+		return -EIO;
+
+	return 0;
+}
+
+static void
+aiptek_close(struct input_dev *dev)
+{
+	struct aiptek *aiptek = dev->private;
+
+	if (!--aiptek->open)
+		usb_unlink_urb(aiptek->irq);
+}
+
+static void
+aiptek_command(struct usb_device *dev, unsigned int ifnum,
+	       unsigned char command, unsigned char data)
+{
+	__u8 buf[3];
+
+	buf[0] = 4;
+	buf[1] = command;
+	buf[2] = data;
+
+	/* 
+	 * FIXME, either remove this call, or talk the maintainer into 
+	 * adding it back into the core.
+	 */
+#if 0
+	if (usb_set_report(dev, ifnum, 3, 2, buf, 3) != 3) {
+		dbg("aiptek_command: 0x%x 0x%x\n", command, data);
+	}
+#endif
+}
+
+static void*
+aiptek_probe(struct usb_device *dev, unsigned int ifnum,
+	     const struct usb_device_id *id)
+{
+	struct usb_endpoint_descriptor *endpoint;
+	struct aiptek *aiptek;
+
+	if (!(aiptek = kmalloc(sizeof (struct aiptek), GFP_KERNEL)))
+		return NULL;
+
+	memset(aiptek, 0, sizeof (struct aiptek));
+
+    aiptek->irq = usb_alloc_urb(0, GFP_KERNEL);
+    if (!aiptek->irq) {
+        kfree(aiptek);
+        return NULL;
+    }
+
+	// Resolution500LPI
+	aiptek_command(dev, ifnum, 0x18, 0x04);
+
+	// SwitchToTablet
+	aiptek_command(dev, ifnum, 0x10, 0x01);
+
+	aiptek->features = aiptek_features + id->driver_info;
+
+	aiptek->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC) |
+	    aiptek->features->evbit;
+
+	aiptek->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
+	    BIT(ABS_MISC) | aiptek->features->absbit;
+
+	aiptek->dev.relbit[0] |= aiptek->features->relbit;
+
+	aiptek->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
+	    BIT(BTN_MIDDLE) | aiptek->features->btnbit;
+
+	aiptek->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) |
+	    BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOUCH) |
+	    BIT(BTN_STYLUS) | BIT(BTN_STYLUS2) | aiptek->features->digibit;
+
+	aiptek->dev.mscbit[0] = BIT(MSC_SERIAL);
+
+	aiptek->dev.absmax[ABS_X] = aiptek->features->x_max;
+	aiptek->dev.absmax[ABS_Y] = aiptek->features->y_max;
+	aiptek->dev.absmax[ABS_PRESSURE] = aiptek->features->pressure_max -
+	    aiptek->features->pressure_min;
+
+	aiptek->dev.absfuzz[ABS_X] = 0;
+	aiptek->dev.absfuzz[ABS_Y] = 0;
+
+	aiptek->dev.private = aiptek;
+	aiptek->dev.open = aiptek_open;
+	aiptek->dev.close = aiptek_close;
+
+	aiptek->dev.name = aiptek->features->name;
+	aiptek->dev.idbus = BUS_USB;
+	aiptek->dev.idvendor = dev->descriptor.idVendor;
+	aiptek->dev.idproduct = dev->descriptor.idProduct;
+	aiptek->dev.idversion = dev->descriptor.bcdDevice;
+	aiptek->usbdev = dev;
+
+	endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
+
+	FILL_INT_URB(aiptek->irq,
+		  dev,
+		  usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+		         aiptek->data,
+		  aiptek->features->pktlen,
+		         aiptek->features->irq,
+		  aiptek,
+		  endpoint->bInterval);
+
+	input_register_device(&aiptek->dev);
+
+	printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
+	       aiptek->dev.number, aiptek->features->name, dev->bus->busnum,
+	       dev->devnum, ifnum);
+
+	return aiptek;
+}
+
+static void
+aiptek_disconnect(struct usb_device *dev, void *ptr)
+{
+	struct aiptek *aiptek = ptr;
+	usb_unlink_urb(aiptek->irq);
+	input_unregister_device(&aiptek->dev);
+    usb_free_urb(aiptek->irq);
+	kfree(aiptek);
+}
+
+static struct usb_driver aiptek_driver = {
+	name:"aiptek",
+	probe:aiptek_probe,
+	disconnect:aiptek_disconnect,
+	id_table:aiptek_ids,
+};
+
+static int __init
+aiptek_init(void)
+{
+	usb_register(&aiptek_driver);
+	info(DRIVER_VERSION " " DRIVER_AUTHOR);
+	info(DRIVER_DESC);
+	return 0;
+}
+
+static void __exit
+aiptek_exit(void)
+{
+	usb_deregister(&aiptek_driver);
+}
+
+module_init(aiptek_init);
+module_exit(aiptek_exit);
diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
--- a/drivers/usb/media/dabusb.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/media/dabusb.c	Sun Jun 16 19:31:40 2002
@@ -80,8 +80,7 @@
 		goto err;
 	}
 	tmp = src->next;
-	list_del (tmp);
-	list_add_tail (tmp, dst);
+	list_move_tail (tmp, dst);
 
   err:	spin_unlock_irqrestore (&s->lock, flags);
 	return ret;
@@ -609,6 +608,7 @@
 		down (&s->mutex);
 	}
 	if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
+		up(&s->mutex);
 		err("set_interface failed");
 		return -EINVAL;
 	}
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/media/ov511.c	Sun Jun 16 19:31:40 2002
@@ -233,7 +233,7 @@
 #define ov51x_mmx_available (0)
 #endif
 
-static __devinitdata struct usb_device_id device_table [] = {
+static struct usb_device_id device_table [] = {
 	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
 	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
 	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV518) },
diff -Nru a/drivers/usb/media/pwc-ctrl.c b/drivers/usb/media/pwc-ctrl.c
--- a/drivers/usb/media/pwc-ctrl.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/media/pwc-ctrl.c	Sun Jun 16 19:31:41 2002
@@ -1,7 +1,7 @@
 /* Driver for Philips webcam
    Functions that send various control messages to the webcam, including
    video modes.
-   (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl)
+   (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -78,10 +78,12 @@
 #define READ_SHUTTER_FORMATTER			0x0600
 #define READ_RED_GAIN_FORMATTER			0x0700
 #define READ_BLUE_GAIN_FORMATTER		0x0800
+#define SENSOR_TYPE_FORMATTER1			0x0C00
 #define READ_RAW_Y_MEAN_FORMATTER		0x3100
 #define SET_POWER_SAVE_MODE_FORMATTER		0x3200
 #define MIRROR_IMAGE_FORMATTER			0x3300
 #define LED_FORMATTER				0x3400
+#define SENSOR_TYPE_FORMATTER2			0x3700
 
 /* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
 #define VIDEO_OUTPUT_CONTROL_FORMATTER		0x0100
@@ -162,6 +164,21 @@
 /****************************************************************************/
 
 
+#define SendControlMsg(request, value, buflen) \
+	usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
+		request, \
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
+		value, \
+		pdev->vcinterface, \
+		&buf, buflen, HZ / 2)
+
+#define RecvControlMsg(request, value, buflen) \
+	usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
+		request, \
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
+		value, \
+		pdev->vcinterface, \
+		&buf, buflen, HZ / 2)
 
 
 #if PWC_DEBUG
@@ -241,7 +258,7 @@
 	ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
 	if (ret < 0)
 		return ret;
-	if (pEntry->compressed)
+	if (pEntry->compressed && pdev->decompressor != NULL)
 		pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
 		
 	/* Set various parameters */
@@ -911,7 +928,7 @@
 	int ret;
 	
 	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
- 	        GET_STATUS_CTL, 
+ 	        GET_CHROM_CTL, 
 		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 	        PRESET_MANUAL_RED_GAIN_FORMATTER,
 		pdev->vcinterface,
@@ -950,7 +967,7 @@
 	int ret;
 	
 	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
-   	        GET_STATUS_CTL,
+   	        GET_CHROM_CTL,
 		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 		PRESET_MANUAL_BLUE_GAIN_FORMATTER,
 		pdev->vcinterface,
@@ -962,6 +979,7 @@
 	return (buf << 8);
 }
 
+
 /* The following two functions are different, since they only read the
    internal red/blue gains, which may be different from the manual 
    gains set or read above.
@@ -979,7 +997,7 @@
 		&buf, 1, HZ / 2);
 
 	if (ret < 0)
-	    return ret;
+		return ret;
 	
 	return (buf << 8);
 }
@@ -997,11 +1015,74 @@
 		&buf, 1, HZ / 2);
 
 	if (ret < 0)
-	    return ret;
+		return ret;
 	
 	return (buf << 8);
 }
 
+
+static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
+{
+	unsigned char buf;
+	
+	/* useful range is 0x01..0x20 */
+	buf = speed / 0x7f0;
+	return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_CHROM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_SPEED_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+}
+
+static inline int pwc_get_wb_speed(struct pwc_device *pdev)
+{
+	unsigned char buf;
+	int ret;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_CHROM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_SPEED_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	return (buf * 0x7f0);
+}
+
+
+static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
+{
+	unsigned char buf;
+	
+	/* useful range is 0x01..0x3F */
+	buf = (delay >> 10);
+	return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_CHROM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_DELAY_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+}
+
+static inline int pwc_get_wb_delay(struct pwc_device *pdev)
+{
+	unsigned char buf;
+	int ret;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_CHROM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_DELAY_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	return (buf << 10);
+}
+
+
 int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
 {
 	unsigned char buf[2];
@@ -1055,61 +1136,248 @@
 	return 0;
 }
 
+static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
+{
+	unsigned char buf;
+	int ret;
+	
+	if (contour < 0)
+		buf = 0xff; /* auto contour on */
+	else
+		buf = 0x0; /* auto contour off */
+	ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_LUM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AUTO_CONTOUR_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	
+	if (contour < 0)
+		return 0;
+	if (contour > 0xffff)
+		contour = 0xffff;
+	
+	buf = (contour >> 10); /* contour preset is [0..3f] */
+	ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_LUM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		PRESET_CONTOUR_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)	
+		return ret;	
+	return 0;
+}
+
+static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
+{
+	unsigned char buf;
+	int ret;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_LUM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AUTO_CONTOUR_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+
+	if (buf == 0) {
+		/* auto mode off, query current preset value */
+		ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+			GET_LUM_CTL,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			PRESET_CONTOUR_FORMATTER,
+			pdev->vcinterface,
+			&buf, 1, HZ / 2);
+		if (ret < 0)	
+			return ret;
+		*contour =  (buf << 10);
+	}
+	else
+		*contour = -1;
+	return 0;
+}
+
+
+static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
+{
+	unsigned char buf;
+	
+	if (backlight)
+		buf = 0xff;
+	else
+		buf = 0x0;
+	return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_LUM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		BACK_LIGHT_COMPENSATION_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+}
+
+static inline int pwc_get_backlight(struct pwc_device *pdev)
+{
+	int ret;
+	unsigned char buf;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_LUM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		BACK_LIGHT_COMPENSATION_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	return buf;
+}
+
+
+static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
+{
+	unsigned char buf;
+	
+	if (flicker)
+		buf = 0xff;
+	else
+		buf = 0x0;
+	return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+}
+
+static inline int pwc_get_flicker(struct pwc_device *pdev)
+{
+	int ret;
+	unsigned char buf;
+	
+	ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+	if (ret < 0)
+		return ret;
+	return buf;
+}
+
+
+static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
+{
+	unsigned char buf;
+
+	if (noise < 0)
+		noise = 0;
+	if (noise > 3)
+		noise = 3;
+	buf = noise;
+	return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+}
+
+static inline int pwc_get_dynamic_noise(struct pwc_device *pdev)
+{
+	int ret;
+	unsigned char buf;
+	
+	ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+	if (ret < 0)
+		return ret;
+//Debug("pwc_get_dynamic_noise = %d\n", buf);
+	return buf;
+}
+
+
+int pwc_get_cmos_sensor(struct pwc_device *pdev)
+{
+	unsigned char buf;
+	int ret = -1, request;
+	
+	if (pdev->type < 675)
+		request = SENSOR_TYPE_FORMATTER1;
+	else if (pdev->type < 730)
+		return -1; /* The Vesta series doesn't have this call */
+	else
+		request = SENSOR_TYPE_FORMATTER2;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_STATUS_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		request,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	if (pdev->type < 675)
+		return buf | 0x100;
+	else
+		return buf;
+}
+
+
  /* End of Add-Ons                                    */
  /* ************************************************* */
 
 int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
 {
+	int ret = 0;
+
 	switch(cmd) {
 	case VIDIOCPWCRUSER:
 	{
 		if (pwc_restore_user(pdev))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 	
 	case VIDIOCPWCSUSER:
 	{
 		if (pwc_save_user(pdev))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 		
 	case VIDIOCPWCFACTORY:
 	{
 		if (pwc_restore_factory(pdev))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 	
 	case VIDIOCPWCSCQUAL:
 	{	
 		int *qual = arg;
-		int ret;
 
 		if (*qual < 0 || *qual > 3)
-			return -EINVAL;
-		ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot);
-		if (ret < 0)
-			return ret;
-		pdev->vcompression = *qual;
+			ret = -EINVAL;
+		else
+			ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot);
+		if (ret >= 0)
+			pdev->vcompression = *qual;
 		break;
 	}
 	
 	case VIDIOCPWCGCQUAL:
 	{
 		int *qual = arg;
-
+		
 		*qual = pdev->vcompression;
 		break;
 	}
 
+	case VIDIOCPWCPROBE:
+	{
+		struct pwc_probe probe;
+		
+		strcpy(probe.name, pdev->vdev->name);
+		probe.type = pdev->type;
+		if (copy_to_user(arg, &probe, sizeof(probe)))
+			ret = -EFAULT;
+		break;
+	}
+
 	case VIDIOCPWCSAGC:
 	{
 		int *agc = arg;
-		
+
 		if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 	
@@ -1118,29 +1386,21 @@
 		int *agc = arg;
 		
 		if (pwc_get_agc(pdev, agc))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 	
 	case VIDIOCPWCSSHUTTER:
 	{
 		int *shutter_speed = arg;
-		int ret;
 
 		ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed);
-		if (ret < 0)
-			return ret;
 		break;
 	}
 	
-
- /* ************************************************* */
- /* Begin of Add-Ons for color compensation           */
-
         case VIDIOCPWCSAWB:
 	{
 		struct pwc_whitebalance *wb = arg;
-		int ret;
 		
 		ret = pwc_set_awb(pdev, wb->mode);
 		if (ret >= 0 && wb->mode == PWC_WB_MANUAL) {
@@ -1153,52 +1413,149 @@
 	case VIDIOCPWCGAWB:
 	{
 		struct pwc_whitebalance *wb = arg;
-		
+
 		memset(wb, 0, sizeof(*wb));
 		wb->mode = pwc_get_awb(pdev);
 		if (wb->mode < 0)
-			return -EINVAL;
-		wb->manual_red = pwc_get_red_gain(pdev);
-		wb->manual_blue = pwc_get_blue_gain(pdev);
-		if (wb->mode == PWC_WB_AUTO) {
-			wb->read_red = pwc_read_red_gain(pdev);
-			wb->read_blue = pwc_read_blue_gain(pdev);
+			ret = -EINVAL;
+		else {
+			if (wb->mode == PWC_WB_MANUAL) {
+				wb->manual_red = pwc_get_red_gain(pdev);
+				wb->manual_blue = pwc_get_blue_gain(pdev);
+			}
+			if (wb->mode == PWC_WB_AUTO) {
+				wb->read_red = pwc_read_red_gain(pdev);
+				wb->read_blue = pwc_read_blue_gain(pdev);
+			}
 		}
 		break;
 	}
+	
+	case VIDIOCPWCSAWBSPEED:
+	{
+		struct pwc_wb_speed *wbs = arg;
+		
+		if (wbs->control_speed > 0) {
+			ret = pwc_set_wb_speed(pdev, wbs->control_speed);
+		}
+		if (wbs->control_delay > 0) {
+			ret = pwc_set_wb_delay(pdev, wbs->control_delay);
+		}
+		break;
+	}
+	
+	case VIDIOCPWCGAWBSPEED:
+	{
+		struct pwc_wb_speed *wbs = arg;
+		
+		ret = pwc_get_wb_speed(pdev);
+		if (ret < 0)
+			break;
+		wbs->control_speed = ret;
+		ret = pwc_get_wb_delay(pdev);
+		if (ret < 0)
+			break;
+		wbs->control_delay = ret;
+		break;
+	}
 
         case VIDIOCPWCSLED:
 	{
-		int ret;
 		struct pwc_leds *leds = arg;
 
 		ret = pwc_set_leds(pdev, leds->led_on, leds->led_off);
-		if (ret<0)
-		    return ret;
-	    break;
+	    	break;
 	}
 
 
-
 	case VIDIOCPWCGLED:
 	{
-		int led;
 		struct pwc_leds *leds = arg;
 		
-		led = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); 
-		if (led < 0)
-			return -EINVAL;
+		ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); 
 		break;
 	}
 
- /* End of Add-Ons                                    */
- /* ************************************************* */
+	case VIDIOCPWCSCONTOUR:
+	{
+		int *contour = arg;
+
+		ret = pwc_set_contour(pdev, *contour);
+		break;
+	}
+			
+	case VIDIOCPWCGCONTOUR:
+	{
+		int *contour = arg;
+		
+		ret = pwc_get_contour(pdev, contour);
+		break;
+	}
+	
+	case VIDIOCPWCSBACKLIGHT:
+	{
+		int *backlight = arg;
+		
+		ret = pwc_set_backlight(pdev, *backlight);
+		break;
+	}
+
+	case VIDIOCPWCGBACKLIGHT:
+	{
+		int *backlight = arg;
+		
+		ret = pwc_get_backlight(pdev);
+		if (ret >= 0)
+			*backlight = ret;
+		break;
+	}
+	
+	case VIDIOCPWCSFLICKER:
+	{
+		int *flicker = arg;
+		
+		ret = pwc_set_flicker(pdev, *flicker);
+		break;
+	}
+
+	case VIDIOCPWCGFLICKER:
+	{
+		int *flicker = arg;
+		
+		ret = pwc_get_flicker(pdev);
+		if (ret >= 0)
+			*flicker = ret;
+		break;
+	}
+	
+	case VIDIOCPWCSDYNNOISE:
+	{
+		int *dynnoise = arg;
+		
+		ret = pwc_set_dynamic_noise(pdev, *dynnoise);
+		break;
+	}
+	
+	case VIDIOCPWCGDYNNOISE:
+	{
+		int *dynnoise = arg;
+
+		ret = pwc_get_dynamic_noise(pdev);
+		if (ret < 0)
+			break;
+		*dynnoise = ret;
+		break;
+	}
+	
 
 	default:
-		return -ENOIOCTLCMD;
+		ret = -ENOIOCTLCMD;
 		break;
 	}
-	return 0;
+	
+	if (ret > 0)
+		return 0;
+	return ret;
 }
 
 
diff -Nru a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c
--- a/drivers/usb/media/pwc-if.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/media/pwc-if.c	Sun Jun 16 19:31:41 2002
@@ -66,7 +66,7 @@
 /* Function prototypes and driver templates */
 
 /* hotplug device table support */
-static __devinitdata struct usb_device_id pwc_device_table [] = {
+static struct usb_device_id pwc_device_table [] = {
 	{ USB_DEVICE(0x0471, 0x0302) },
 	{ USB_DEVICE(0x0471, 0x0303) },
 	{ USB_DEVICE(0x0471, 0x0304) },
diff -Nru a/drivers/usb/media/pwc-ioctl.h b/drivers/usb/media/pwc-ioctl.h
--- a/drivers/usb/media/pwc-ioctl.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/media/pwc-ioctl.h	Sun Jun 16 19:31:40 2002
@@ -1,7 +1,7 @@
 #ifndef PWC_IOCTL_H
 #define PWC_IOCTL_H
 
-/* (C) 2001 Nemosoft Unv.    webcam@smcc.demon.nl
+/* (C) 2001-2002 Nemosoft Unv.    webcam@smcc.demon.nl
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -18,7 +18,9 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-/*
+/*         This is pwc-ioctl.h belonging to PWC 8.7                        */
+
+/* 
    Changes
    2001/08/03  Alvarado   Added ioctl constants to access methods for 
                           changing white balance and red/blue gains
@@ -52,6 +54,14 @@
 #define PWC_FPS_SNAPSHOT	0x00400000
 
 
+
+struct pwc_probe
+{
+	char name[32];
+	int type;
+};
+
+
 /* pwc_whitebalance.mode values */
 #define PWC_WB_INDOOR		0
 #define PWC_WB_OUTDOOR		1
@@ -63,9 +73,9 @@
    Set mode to one of the PWC_WB_* values above.
    *red and *blue are the respective gains of these colour components inside 
    the camera; range 0..65535
-   When mode == PWC_WB_MANUAL, manual_red and manual_blue are set or read; 
+   When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; 
    otherwise undefined.
-   read_red and read_blue are read-only.
+   'read_red' and 'read_blue' are read-only.
 */   
    
 struct pwc_whitebalance
@@ -75,6 +85,17 @@
 	int read_red, read_blue;	/* R/O */
 };
 
+/* 
+   'control_speed' and 'control_delay' are used in automatic whitebalance mode,
+   and tell the camera how fast it should react to changes in lighting, and 
+   with how much delay. Valid values are 0..65535.
+*/
+struct pwc_wb_speed
+{
+	int control_speed;
+	int control_delay;
+
+};
 
 /* Used with VIDIOCPWC[SG]LED */
 struct pwc_leds
@@ -104,6 +125,19 @@
  /* Get preferred compression quality */
 #define VIDIOCPWCGCQUAL		_IOR('v', 195, int)
 
+
+ /* This is a probe function; since so many devices are supported, it
+    becomes difficult to include all the names in programs that want to
+    check for the enhanced Philips stuff. So in stead, try this PROBE;
+    it returns a structure with the original name, and the corresponding 
+    Philips type.
+    To use, fill the structure with zeroes, call PROBE and if that succeeds,
+    compare the name with that returned from VIDIOCGCAP; they should be the
+    same. If so, you can be assured it is a Philips (OEM) cam and the type
+    is valid.
+ */    
+#define VIDIOCPWCPROBE		_IOR('v', 199, struct pwc_probe)
+
  /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
 #define VIDIOCPWCSAGC		_IOW('v', 200, int)
  /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
@@ -115,9 +149,28 @@
 #define VIDIOCPWCSAWB           _IOW('v', 202, struct pwc_whitebalance)
 #define VIDIOCPWCGAWB           _IOR('v', 202, struct pwc_whitebalance)
 
- /* Turn LED on/off ; int range 0..65535 */
+ /* Auto WB speed */
+#define VIDIOCPWCSAWBSPEED	_IOW('v', 203, struct pwc_wb_speed)
+#define VIDIOCPWCGAWBSPEED	_IOR('v', 203, struct pwc_wb_speed)
+
+ /* LEDs on/off/blink; int range 0..65535 */
 #define VIDIOCPWCSLED           _IOW('v', 205, struct pwc_leds)
- /* Get state of LED; int range 0..65535 */
 #define VIDIOCPWCGLED           _IOR('v', 205, struct pwc_leds)
+
+  /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
+#define VIDIOCPWCSCONTOUR	_IOW('v', 206, int)
+#define VIDIOCPWCGCONTOUR	_IOR('v', 206, int)
+
+  /* Backlight compensation; 0 = off, otherwise on */
+#define VIDIOCPWCSBACKLIGHT	_IOW('v', 207, int)
+#define VIDIOCPWCGBACKLIGHT	_IOR('v', 207, int)
+
+  /* Flickerless mode; = 0 off, otherwise on */
+#define VIDIOCPWCSFLICKER	_IOW('v', 208, int)
+#define VIDIOCPWCGFLICKER	_IOR('v', 208, int)  
+
+  /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
+#define VIDIOCPWCSDYNNOISE	_IOW('v', 209, int)
+#define VIDIOCPWCGDYNNOISE	_IOR('v', 209, int)
 
 #endif
diff -Nru a/drivers/usb/media/pwc.h b/drivers/usb/media/pwc.h
--- a/drivers/usb/media/pwc.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/media/pwc.h	Sun Jun 16 19:31:40 2002
@@ -1,4 +1,4 @@
-/* (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl)
+/* (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -60,8 +60,8 @@
 
 /* Version block */
 #define PWC_MAJOR	8
-#define PWC_MINOR	5
-#define PWC_VERSION 	"8.5"
+#define PWC_MINOR	7
+#define PWC_VERSION 	"8.7"
 #define PWC_NAME 	"pwc"
 
 /* Turn certain features on/off */
@@ -247,6 +247,7 @@
 extern int pwc_set_saturation(struct pwc_device *pdev, int value);
 extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
 extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
+extern int pwc_get_cmos_sensor(struct pwc_device *pdev);
 
 /* Power down or up the camera; not supported by all models */
 extern int pwc_camera_power(struct pwc_device *pdev, int power);
diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
--- a/drivers/usb/media/se401.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/media/se401.c	Sun Jun 16 19:31:40 2002
@@ -29,7 +29,6 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
@@ -42,18 +41,12 @@
 #include <linux/wrapper.h>
 #include <linux/mm.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
-#define virt_to_page(arg)	MAP_NR(arg)
-#define vmalloc_32		vmalloc
-#endif
-
 #include "se401.h"
 
 static int flickerless=0;
 static int video_nr = -1;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
-static __devinitdata struct usb_device_id device_table [] = {
+static struct usb_device_id device_table [] = {
 	{ USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
 	{ USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
 	{ USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
@@ -63,7 +56,6 @@
 };
 
 MODULE_DEVICE_TABLE(usb, device_table);
-#endif
 
 MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
 MODULE_DESCRIPTION("SE401 USB Camera Driver");
@@ -1330,7 +1322,13 @@
 
 	se401->sizes=cp[4]+cp[5]*256;
 	se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
+	if (!se401->width)
+		return 1;
 	se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
+	if (!se401->height) {
+		kfree(se401->width);
+		return 1;
+	}
 	for (i=0; i<se401->sizes; i++) {
 		    se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
 		    se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
@@ -1396,12 +1394,8 @@
         return 0;
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
-static void* se401_probe(struct usb_device *dev, unsigned int ifnum)
-#else
-static void* __devinit se401_probe(struct usb_device *dev, unsigned int ifnum,
+static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
 	const struct usb_device_id *id)
-#endif
 {
         struct usb_interface_descriptor *interface;
         struct usb_se401 *se401;
@@ -1529,9 +1523,7 @@
 
 static struct usb_driver se401_driver = {
         name:		"se401",
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
         id_table:	device_table,
-#endif
 	probe:		se401_probe,
         disconnect:	se401_disconnect
 };
diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
--- a/drivers/usb/media/stv680.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/media/stv680.c	Sun Jun 16 19:31:39 2002
@@ -86,7 +86,7 @@
 #define PDEBUG(level, fmt, args...) \
 	do { \
 	if (debug >= level)	\
-		info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args);	\
+		info("[%s:%d] " fmt, __FUNCTION__, __LINE__ , ## args);	\
 	} while (0)
 
 
@@ -1449,7 +1449,7 @@
 	fops:           &stv680_fops,
 };
 
-static void *__devinit stv680_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
+static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
 {
 	struct usb_interface_descriptor *interface;
 	struct usb_stv *stv680;
diff -Nru a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h
--- a/drivers/usb/media/stv680.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/media/stv680.h	Sun Jun 16 19:31:41 2002
@@ -45,7 +45,7 @@
 /* fmt 4 */
 #define STV_VIDEO_PALETTE       VIDEO_PALETTE_RGB24
 
-static __devinitdata struct usb_device_id device_table[] = {
+static struct usb_device_id device_table[] = {
 	{USB_DEVICE (USB_PENCAM_VENDOR_ID, USB_PENCAM_PRODUCT_ID)},
 	{}
 };
diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
--- a/drivers/usb/media/vicam.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/media/vicam.c	Sun Jun 16 19:31:40 2002
@@ -787,7 +787,7 @@
 	return 1;
 }
 
-static void * __devinit vicam_probe(struct usb_device *udev, unsigned int ifnum,
+static void *vicam_probe(struct usb_device *udev, unsigned int ifnum,
 	const struct usb_device_id *id)
 {
 	struct usb_vicam *vicam;
diff -Nru a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c
--- a/drivers/usb/net/cdc-ether.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/net/cdc-ether.c	Sun Jun 16 19:31:39 2002
@@ -129,13 +129,13 @@
 			usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in),
 			ether_dev->rx_buff, ether_dev->wMaxSegmentSize, 
 			read_bulk_callback, ether_dev );
-			
-	// Give this to the USB subsystem so it can tell us 
+
+	// Give this to the USB subsystem so it can tell us
 	// when more data arrives.
 	if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) ) {
-		warn( __FUNCTION__ " failed submint rx_urb %d", res);
+		warn("%s failed submint rx_urb %d", __FUNCTION__, res);
 	}
-	
+
 	// We are no longer busy, show us the frames!!!
 	ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
 }
@@ -339,7 +339,7 @@
 
 	// Turn on the USB and let the packets flow!!!
 	if ( (res = enable_net_traffic( ether_dev )) ) {
-		err( __FUNCTION__ "can't enable_net_traffic() - %d", res );
+		err("%s can't enable_net_traffic() - %d", __FUNCTION__, res );
 		return -EIO;
 	}
 
@@ -353,7 +353,7 @@
 	if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) )
 	{
 		// Hmm...  Okay...
-		warn( __FUNCTION__ " failed rx_urb %d", res );
+		warn("%s failed rx_urb %d", __FUNCTION__, res );
 	}
 
 	// Tell the kernel we are ready to start receiving from it
@@ -411,6 +411,7 @@
 	}
 }
 
+#if 0
 static void CDC_SetEthernetPacketFilter (ether_dev_t *ether_dev)
 {
 	usb_control_msg(ether_dev->usb,
@@ -422,7 +423,8 @@
 			NULL,
 			0, /* size */
 			HZ); /* timeout */
-}	
+}
+#endif
 
 
 static void CDCEther_set_multicast( struct net_device *net )
@@ -430,7 +432,7 @@
 	ether_dev_t *ether_dev = net->priv;
 	int i;
 	__u8 *buff;
-	
+
 
 	// Tell the kernel to stop sending us frames while we get this
 	// all set up.
diff -Nru a/drivers/usb/net/cdc-ether.h b/drivers/usb/net/cdc-ether.h
--- a/drivers/usb/net/cdc-ether.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/net/cdc-ether.h	Sun Jun 16 19:31:39 2002
@@ -43,7 +43,7 @@
 #define	CDC_ETHER_REQ_GET_REGS	0xf0
 #define	CDC_ETHER_REQ_SET_REGS	0xf1
 #define	CDC_ETHER_REQ_SET_REG	PIPERIDER_REQ_SET_REGS
-#define	ALIGN(x)		x __attribute__((aligned(L1_CACHE_BYTES)))
+#define	L1_ALIGN(x)		x __attribute__((aligned(L1_CACHE_BYTES)))
 
 #define MODE_FLAG_PROMISCUOUS   (1<<0)
 #define MODE_FLAG_ALL_MULTICAST (1<<1)
@@ -84,9 +84,9 @@
 	__u8			bNumberPowerFilters;
 	int			intr_interval;
 	struct urb		*rx_urb, *tx_urb, *intr_urb;
-	unsigned char		ALIGN(rx_buff[CDC_ETHER_MAX_MTU]);
-	unsigned char		ALIGN(tx_buff[CDC_ETHER_MAX_MTU]);
-	unsigned char		ALIGN(intr_buff[8]);
+	unsigned char		L1_ALIGN(rx_buff[CDC_ETHER_MAX_MTU]);
+	unsigned char		L1_ALIGN(tx_buff[CDC_ETHER_MAX_MTU]);
+	unsigned char		L1_ALIGN(intr_buff[8]);
 } ether_dev_t;
 
 #define REQ_HDR_FUNC_DESCR	0x0001
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/net/kaweth.c	Sun Jun 16 19:31:41 2002
@@ -75,6 +75,7 @@
 #define KAWETH_MTU			1514
 #define KAWETH_BUF_SIZE			1664
 #define KAWETH_TX_TIMEOUT		(5 * HZ)
+#define KAWETH_SCRATCH_SIZE		32
 #define KAWETH_FIRMWARE_BUF_SIZE	4096
 #define KAWETH_CONTROL_TIMEOUT		(30 * HZ)
 
@@ -220,7 +221,8 @@
 	struct urb *tx_urb;
 	struct urb *irq_urb;
 
-	__u8 firmware_buf[KAWETH_FIRMWARE_BUF_SIZE];
+	__u8 *firmware_buf;
+	__u8 scratch[KAWETH_SCRATCH_SIZE];
 	__u8 tx_buf[KAWETH_BUF_SIZE];
 	__u8 rx_buf[KAWETH_BUF_SIZE];
 	__u8 intbuffer[INTBUFFERSIZE];
@@ -312,7 +314,7 @@
 				USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 				urb_size,
 				0,
-				(void *)&kaweth->firmware_buf,
+				(void *)&kaweth->scratch,
 				0,
 				KAWETH_CONTROL_TIMEOUT);
 
@@ -334,7 +336,7 @@
 				USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 				sofs_wait,
 				0,
-				(void *)&kaweth->firmware_buf,
+				(void *)&kaweth->scratch,
 				0,
 				KAWETH_CONTROL_TIMEOUT);
 
@@ -357,7 +359,7 @@
 				USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 				receive_filter,
 				0,
-				(void *)&kaweth->firmware_buf,
+				(void *)&kaweth->scratch,
 				0,
 				KAWETH_CONTROL_TIMEOUT);
 
@@ -399,7 +401,7 @@
 			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 			      0,
 			      0,
-			      (void *)&kaweth->firmware_buf,
+			      (void *)kaweth->firmware_buf,
 			      data_len,
 			      KAWETH_CONTROL_TIMEOUT);
 }
@@ -427,7 +429,7 @@
 			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 			      0,
 			      0,
-			      (void *)&kaweth->firmware_buf,
+			      (void *)kaweth->firmware_buf,
 			      8,
 			      KAWETH_CONTROL_TIMEOUT);
 }
@@ -755,7 +757,7 @@
 				USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 				packet_filter_bitmap,
 				0,
-				(void *)&kaweth->firmware_buf,
+				(void *)&kaweth->scratch,
 				0,
 				KAWETH_CONTROL_TIMEOUT);
 
@@ -840,12 +842,14 @@
 	} else {
 		/* Download the firmware */
 		kaweth_info("Downloading firmware...");
+		kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
 		if ((result = kaweth_download_firmware(kaweth,
 						      kaweth_new_code,
 						      len_kaweth_new_code,
 						      100,
 						      2)) < 0) {
 			kaweth_err("Error downloading firmware (%d)", result);
+			free_page((unsigned long)kaweth->firmware_buf);
 			kfree(kaweth);
 			return NULL;
 		}
@@ -856,6 +860,7 @@
 						      100,
 						      3)) < 0) {
 			kaweth_err("Error downloading firmware fix (%d)", result);
+			free_page((unsigned long)kaweth->firmware_buf);
 			kfree(kaweth);
 			return NULL;
 		}
@@ -866,6 +871,7 @@
 						      126,
 						      2)) < 0) {
 			kaweth_err("Error downloading trigger code (%d)", result);
+			free_page((unsigned long)kaweth->firmware_buf);
 			kfree(kaweth);
 			return NULL;
 		}
@@ -876,6 +882,7 @@
 						      126,
 						      3)) < 0) {
 			kaweth_err("Error downloading trigger code fix (%d)", result);
+			free_page((unsigned long)kaweth->firmware_buf);
 			kfree(kaweth);
 			return NULL;
 		}
@@ -883,12 +890,14 @@
 
 		if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
 			kaweth_err("Error triggering firmware (%d)", result);
+			free_page((unsigned long)kaweth->firmware_buf);
 			kfree(kaweth);
 			return NULL;
 		}
 
 		/* Device will now disappear for a moment...  */
 		kaweth_info("Firmware loaded.  I'll be back...");
+		free_page((unsigned long)kaweth->firmware_buf);
 		kfree(kaweth);
 		return NULL;
 	}
diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
--- a/drivers/usb/serial/belkin_sa.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/belkin_sa.c	Sun Jun 16 19:31:40 2002
@@ -103,7 +103,7 @@
 static void belkin_sa_break_ctl		(struct usb_serial_port *port, int break_state );
 
 
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
 	{ USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
 	{ USB_DEVICE(PERACOM_VID, PERACOM_PID) },
@@ -129,7 +129,7 @@
 	ioctl:			belkin_sa_ioctl,
 	set_termios:		belkin_sa_set_termios,
 	break_ctl:		belkin_sa_break_ctl,
-	startup:		belkin_sa_startup,
+	attach:			belkin_sa_startup,
 	shutdown:		belkin_sa_shutdown,
 };
 
diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
--- a/drivers/usb/serial/cyberjack.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/serial/cyberjack.c	Sun Jun 16 19:31:41 2002
@@ -66,7 +66,7 @@
 static void cyberjack_read_bulk_callback (struct urb *urb);
 static void cyberjack_write_bulk_callback (struct urb *urb);
 
-static __devinitdata struct usb_device_id id_table [] = {
+static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
 	{ }			/* Terminating entry */
 };
@@ -81,7 +81,7 @@
 	num_bulk_in:		1,
 	num_bulk_out:		1,
 	num_ports:		1,
-	startup:		cyberjack_startup,
+	attach:		cyberjack_startup,
 	shutdown:		cyberjack_shutdown,
 	open:			cyberjack_open,
 	close:			cyberjack_close,
diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
--- a/drivers/usb/serial/digi_acceleport.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/digi_acceleport.c	Sun Jun 16 19:31:40 2002
@@ -483,12 +483,12 @@
 	{ }						/* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id id_table_2 [] = {
+static struct usb_device_id id_table_2 [] = {
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
 	{ }						/* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id id_table_4 [] = {
+static struct usb_device_id id_table_4 [] = {
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
 	{ }						/* Terminating entry */
 };
@@ -517,7 +517,7 @@
 	ioctl:				digi_ioctl,
 	set_termios:			digi_set_termios,
 	break_ctl:			digi_break_ctl,
-	startup:			digi_startup,
+	attach:				digi_startup,
 	shutdown:			digi_shutdown,
 };
 
@@ -541,7 +541,7 @@
 	ioctl:				digi_ioctl,
 	set_termios:			digi_set_termios,
 	break_ctl:			digi_break_ctl,
-	startup:			digi_startup,
+	attach:				digi_startup,
 	shutdown:			digi_shutdown,
 };
 
diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
--- a/drivers/usb/serial/empeg.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/empeg.c	Sun Jun 16 19:31:40 2002
@@ -103,7 +103,7 @@
 static void empeg_write_bulk_callback	(struct urb *urb);
 static void empeg_read_bulk_callback	(struct urb *urb);
 
-static __devinitdata struct usb_device_id id_table [] = {
+static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
@@ -122,7 +122,7 @@
 	close:			empeg_close,
 	throttle:		empeg_throttle,
 	unthrottle:		empeg_unthrottle,
-	startup:		empeg_startup,
+	attach:			empeg_startup,
 	shutdown:		empeg_shutdown,
 	ioctl:			empeg_ioctl,
 	set_termios:		empeg_set_termios,
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/serial/ftdi_sio.c	Sun Jun 16 19:31:39 2002
@@ -120,7 +120,7 @@
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>"
 #define DRIVER_DESC "USB FTDI RS232 Converters Driver"
 
-static __devinitdata struct usb_device_id id_table_sio [] = {
+static struct usb_device_id id_table_sio [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 	{ }						/* Terminating entry */
 };
@@ -133,7 +133,7 @@
   */
 
    
-static __devinitdata struct usb_device_id id_table_8U232AM [] = {
+static struct usb_device_id id_table_8U232AM [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
 	{ }						/* Terminating entry */
@@ -189,7 +189,7 @@
 	ioctl:			ftdi_sio_ioctl,
 	set_termios:		ftdi_sio_set_termios,
 	break_ctl:		ftdi_sio_break_ctl,
-	startup:		ftdi_sio_startup,
+	attach:			ftdi_sio_startup,
         shutdown:               ftdi_sio_shutdown,
 };
 
@@ -210,7 +210,7 @@
 	ioctl:			ftdi_sio_ioctl,
 	set_termios:		ftdi_sio_set_termios,
 	break_ctl:		ftdi_sio_break_ctl,
-	startup:		ftdi_8U232AM_startup,
+	attach:			ftdi_8U232AM_startup,
         shutdown:               ftdi_sio_shutdown,
 };
 
diff -Nru a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
--- a/drivers/usb/serial/io_tables.h	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/serial/io_tables.h	Sun Jun 16 19:31:39 2002
@@ -14,12 +14,12 @@
 #ifndef IO_TABLES_H
 #define IO_TABLES_H
 
-static __devinitdata struct usb_device_id edgeport_1port_id_table [] = {
+static struct usb_device_id edgeport_1port_id_table [] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_PARALLEL_PORT) },
 	{ }
 };
 
-static __devinitdata struct usb_device_id edgeport_2port_id_table [] = {
+static struct usb_device_id edgeport_2port_id_table [] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2I) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_421) },
@@ -33,7 +33,7 @@
 	{ }
 };
 
-static __devinitdata struct usb_device_id edgeport_4port_id_table [] = {
+static struct usb_device_id edgeport_4port_id_table [] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) },
@@ -50,7 +50,7 @@
 	{ }
 };
 
-static __devinitdata struct usb_device_id edgeport_8port_id_table [] = {
+static struct usb_device_id edgeport_8port_id_table [] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8I) },
@@ -109,7 +109,7 @@
 	close:			edge_close,
 	throttle:		edge_throttle,
 	unthrottle:		edge_unthrottle,
-	startup:		edge_startup,
+	attach:			edge_startup,
 	shutdown:		edge_shutdown,
 	ioctl:			edge_ioctl,
 	set_termios:		edge_set_termios,
@@ -131,7 +131,7 @@
 	close:			edge_close,
 	throttle:		edge_throttle,
 	unthrottle:		edge_unthrottle,
-	startup:		edge_startup,
+	attach:			edge_startup,
 	shutdown:		edge_shutdown,
 	ioctl:			edge_ioctl,
 	set_termios:		edge_set_termios,
@@ -153,7 +153,7 @@
 	close:			edge_close,
 	throttle:		edge_throttle,
 	unthrottle:		edge_unthrottle,
-	startup:		edge_startup,
+	attach:			edge_startup,
 	shutdown:		edge_shutdown,
 	ioctl:			edge_ioctl,
 	set_termios:		edge_set_termios,
@@ -175,7 +175,7 @@
 	close:			edge_close,
 	throttle:		edge_throttle,
 	unthrottle:		edge_unthrottle,
-	startup:		edge_startup,
+	attach:			edge_startup,
 	shutdown:		edge_shutdown,
 	ioctl:			edge_ioctl,
 	set_termios:		edge_set_termios,
diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/ipaq.c	Sun Jun 16 19:31:40 2002
@@ -78,7 +78,7 @@
 static void ipaq_destroy_lists(struct usb_serial_port *port);
 
 
-static __devinitdata struct usb_device_id ipaq_id_table [] = {
+static struct usb_device_id ipaq_id_table [] = {
 	{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) },
@@ -99,7 +99,7 @@
 	num_ports:		1,
 	open:			ipaq_open,
 	close:			ipaq_close,
-	startup:		ipaq_startup,
+	attach:			ipaq_startup,
 	shutdown:		ipaq_shutdown,
 	write:			ipaq_write,
 	write_room:		ipaq_write_room,
@@ -401,8 +401,7 @@
 		pkt->written += count;
 		priv->queue_len -= count;
 		if (pkt->written == pkt->len) {
-			list_del(&pkt->list);
-			list_add(&pkt->list, &priv->freelist);
+			list_move(&pkt->list, &priv->freelist);
 			priv->free_len += PACKET_SIZE;
 		}
 		if (room == 0) {
diff -Nru a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
--- a/drivers/usb/serial/ir-usb.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/ir-usb.c	Sun Jun 16 19:31:40 2002
@@ -119,7 +119,7 @@
 static u8 ir_xbof = 0;
 static u8 ir_add_bof = 0;
 
-static __devinitdata struct usb_device_id id_table [] = {
+static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(0x050f, 0x0180) },		/* KC Technology, KC-180 */
 	{ USB_DEVICE(0x08e9, 0x0100) },		/* XTNDAccess */
 	{ USB_DEVICE(0x09c4, 0x0011) },		/* ACTiSys ACT-IR2000U */
@@ -139,7 +139,7 @@
 	num_bulk_out:		1,
 	num_ports:		1,
 	set_termios:		ir_set_termios,
-	startup:		ir_startup,
+	attach:			ir_startup,
 	open:			ir_open,
 	close:			ir_close,
 	write:			ir_write,
diff -Nru a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
--- a/drivers/usb/serial/keyspan.h	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/serial/keyspan.h	Sun Jun 16 19:31:41 2002
@@ -435,7 +435,7 @@
 MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
 
 /* usb_device_id table for the pre-firmware download keyspan devices */
-static __devinitdata struct usb_device_id keyspan_pre_ids[] = {
+static struct usb_device_id keyspan_pre_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) },
@@ -449,7 +449,7 @@
 	{ } /* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id keyspan_1port_ids[] = {
+static struct usb_device_id keyspan_1port_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
@@ -458,14 +458,14 @@
 	{ } /* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id keyspan_2port_ids[] = {
+static struct usb_device_id keyspan_2port_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
 	{ } /* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id keyspan_4port_ids[] = {
+static struct usb_device_id keyspan_4port_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) },
 	{ } /* Terminating entry */
 };
@@ -479,7 +479,7 @@
 	num_bulk_in:		NUM_DONT_CARE,
 	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
-	startup:		keyspan_fake_startup,
+	attach:			keyspan_fake_startup,
 };
 
 static struct usb_serial_device_type keyspan_1port_device = {
@@ -500,7 +500,7 @@
 	ioctl:			keyspan_ioctl,
 	set_termios:		keyspan_set_termios,
 	break_ctl:		keyspan_break_ctl,
-	startup:		keyspan_startup,
+	attach:			keyspan_startup,
 	shutdown:		keyspan_shutdown,
 };
 
@@ -521,7 +521,7 @@
 	unthrottle:		keyspan_rx_unthrottle,
 	ioctl:			keyspan_ioctl,
 	set_termios:		keyspan_set_termios,
-	startup:		keyspan_startup,
+	attach:			keyspan_startup,
 	shutdown:		keyspan_shutdown,
 };
 
@@ -543,7 +543,7 @@
 	ioctl:			keyspan_ioctl,
 	set_termios:		keyspan_set_termios,
 	break_ctl:		keyspan_break_ctl,
-	startup:		keyspan_startup,
+	attach:			keyspan_startup,
 	shutdown:		keyspan_shutdown,
 };
 
diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
--- a/drivers/usb/serial/keyspan_pda.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/keyspan_pda.c	Sun Jun 16 19:31:40 2002
@@ -154,20 +154,20 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
-static __devinitdata struct usb_device_id id_table_std [] = {
+static struct usb_device_id id_table_std [] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
 	{ }						/* Terminating entry */
 };
 
 #ifdef KEYSPAN
-static __devinitdata struct usb_device_id id_table_fake [] = {
+static struct usb_device_id id_table_fake [] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
 	{ }						/* Terminating entry */
 };
 #endif
 
 #ifdef XIRCOM
-static __devinitdata struct usb_device_id id_table_fake_xircom [] = {
+static struct usb_device_id id_table_fake_xircom [] = {
         { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
         { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
         { }                                             
@@ -194,20 +194,24 @@
 
 static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
 {
+	int result;
 
 	dbg(" request_unthrottle");
 	/* ask the device to tell us when the tx buffer becomes
 	   sufficiently empty */
-	usb_control_msg(serial->dev, 
-			     usb_sndctrlpipe(serial->dev, 0),
-			     7, /* request_unthrottle */
-			     USB_TYPE_VENDOR | USB_RECIP_INTERFACE
-			     | USB_DIR_OUT,
-			     16, /* value: threshold */
-			     0, /* index */
-			     NULL,
-			     0,
-			     2*HZ);
+	result = usb_control_msg(serial->dev, 
+				 usb_sndctrlpipe(serial->dev, 0),
+				 7, /* request_unthrottle */
+				 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
+				 | USB_DIR_OUT,
+				 16, /* value: threshold */
+				 0, /* index */
+				 NULL,
+				 0,
+				 2*HZ);
+	if (result < 0)
+		dbg("%s - error %d from usb_control_msg", 
+		    __FUNCTION__, result);
 }
 
 
@@ -334,14 +338,19 @@
 {
 	struct usb_serial *serial = port->serial;
 	int value;
+	int result;
+
 	if (break_state == -1)
 		value = 1; /* start break */
 	else
 		value = 0; /* clear break */
-	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			4, /* set break */
-			USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-			value, 0, NULL, 0, 2*HZ);
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				4, /* set break */
+				USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+				value, 0, NULL, 0, 2*HZ);
+	if (result < 0)
+		dbg("%s - error %d from usb_control_msg", 
+		    __FUNCTION__, result);
 	/* there is something funky about this.. the TCSBRK that 'cu' performs
 	   ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4
 	   seconds apart, but it feels like the break sent isn't as long as it
@@ -802,7 +811,7 @@
 	num_bulk_in:		NUM_DONT_CARE,
 	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
-	startup:		keyspan_pda_fake_startup,
+	attach:			keyspan_pda_fake_startup,
 };
 #endif
 
@@ -815,7 +824,7 @@
 	num_bulk_in:		NUM_DONT_CARE,
 	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
-	startup:		keyspan_pda_fake_startup,
+	attach:			keyspan_pda_fake_startup,
 };
 #endif
 
@@ -839,7 +848,7 @@
 	ioctl:			keyspan_pda_ioctl,
 	set_termios:		keyspan_pda_set_termios,
 	break_ctl:		keyspan_pda_break_ctl,
-	startup:		keyspan_pda_startup,
+	attach:			keyspan_pda_startup,
 	shutdown:		keyspan_pda_shutdown,
 };
 
diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
--- a/drivers/usb/serial/kl5kusb105.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/kl5kusb105.c	Sun Jun 16 19:31:40 2002
@@ -109,7 +109,7 @@
 /*
  * All of the device info needed for the KLSI converters.
  */
-static __devinitdata struct usb_device_id id_table [] = {
+static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) },
 	{ USB_DEVICE(KLSI_VID, KLSI_KL5KUSB105D_PID) },
 	{ }		/* Terminating entry */
@@ -136,7 +136,7 @@
 	ioctl:		     klsi_105_ioctl,
 	set_termios:	     klsi_105_set_termios,
 	/*break_ctl:	     klsi_105_break_ctl,*/
-	startup:	     klsi_105_startup,
+	attach:		     klsi_105_startup,
 	shutdown:	     klsi_105_shutdown,
 	throttle:	     klsi_105_throttle,
 	unthrottle:	     klsi_105_unthrottle,
diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c	Sun Jun 16 19:31:41 2002
+++ b/drivers/usb/serial/mct_u232.c	Sun Jun 16 19:31:41 2002
@@ -129,7 +129,7 @@
 /*
  * All of the device info needed for the MCT USB-RS232 converter.
  */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
@@ -158,7 +158,7 @@
 	ioctl:		     mct_u232_ioctl,
 	set_termios:	     mct_u232_set_termios,
 	break_ctl:	     mct_u232_break_ctl,
-	startup:	     mct_u232_startup,
+	attach:		     mct_u232_startup,
 	shutdown:	     mct_u232_shutdown,
 };
 
diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
--- a/drivers/usb/serial/omninet.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/omninet.c	Sun Jun 16 19:31:40 2002
@@ -76,7 +76,7 @@
 static int  omninet_write_room		(struct usb_serial_port *port);
 static void omninet_shutdown		(struct usb_serial *serial);
 
-static __devinitdata struct usb_device_id id_table [] = {
+static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) },
 	{ }						/* Terminating entry */
 };
diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/pl2303.c	Sun Jun 16 19:31:40 2002
@@ -65,7 +65,7 @@
 
 
 
-static __devinitdata struct usb_device_id id_table [] = {
+static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
@@ -134,7 +134,7 @@
 	read_bulk_callback:	pl2303_read_bulk_callback,
 	read_int_callback:	pl2303_read_int_callback,
 	write_bulk_callback:	pl2303_write_bulk_callback,
-	startup:		pl2303_startup,
+	attach:			pl2303_startup,
 	shutdown:		pl2303_shutdown,
 };
 
diff -Nru a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
--- a/drivers/usb/serial/safe_serial.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/serial/safe_serial.c	Sun Jun 16 19:31:39 2002
@@ -140,7 +140,7 @@
         bInterfaceClass: (ic), \
         bInterfaceSubClass: (isc),
 
-static __devinitdata struct usb_device_id id_table[] = {
+static struct usb_device_id id_table[] = {
 	{MY_USB_DEVICE (0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	// Itsy
 	{MY_USB_DEVICE (0x3f0, 0x2101, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	// Calypso
 	{MY_USB_DEVICE (0x4dd, 0x8001, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	// Iris 
@@ -409,7 +409,7 @@
 	write:			safe_write,
 	write_room:		safe_write_room,
 	read_bulk_callback:	safe_read_bulk_callback,
-	startup:		safe_startup,
+	attach:			safe_startup,
 };
 
 static int __init safe_init (void)
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/usb-serial.h	Sun Jun 16 19:31:40 2002
@@ -130,9 +130,20 @@
  * @num_bulk_in: the number of bulk in endpoints this device will have.
  * @num_bulk_out: the number of bulk out endpoints this device will have.
  * @num_ports: the number of different ports this device will have.
- * @startup: pointer to the driver's startup function.  This will be called
- *	when the driver is inserted into the system.  Return 0 to continue
- *	on with the initialization sequence.  Anything else will abort it.
+ * @calc_num_ports: pointer to a function to determine how many ports this
+ *	device has dynamically.  It will be called after the probe()
+ *	callback is called, but before attach()
+ * @probe: pointer to the driver's probe function.
+ *	This will be called when the device is inserted into the system,
+ *	but before the device has been fully initialized by the usb_serial
+ *	subsystem.  Use this function to download any firmware to the device,
+ *	or any other early initialization that might be needed.
+ *	Return 0 to continue on with the initialization sequence.  Anything 
+ *	else will abort it.
+ * @attach: pointer to the driver's attach function.
+ *	This will be called when the struct usb_serial structure is fully set
+ *	set up.  Do any local initialization of the device, or any private
+ *	memory structure allocation at this point in time.
  * @shutdown: pointer to the driver's shutdown function.  This will be
  *	called when the device is removed from the system.
  *
@@ -153,7 +164,10 @@
 
 	struct list_head	driver_list;
 	
-	int (*startup) (struct usb_serial *serial);
+	int (*probe) (struct usb_serial *serial);
+	int (*attach) (struct usb_serial *serial);
+	int (*calc_num_ports) (struct usb_serial *serial);
+
 	void (*shutdown) (struct usb_serial *serial);
 
 	/* serial function calls */
diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
--- a/drivers/usb/serial/usbserial.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/usbserial.c	Sun Jun 16 19:31:40 2002
@@ -433,9 +433,8 @@
 	return serial_table[minor];
 }
 
-static struct usb_serial *get_free_serial (int num_ports, unsigned int *minor)
+static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor)
 {
-	struct usb_serial *serial = NULL;
 	unsigned int i, j;
 	int good_spot;
 
@@ -453,11 +452,14 @@
 		if (good_spot == 0)
 			continue;
 			
-		if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL))) {
-			err(__FUNCTION__ " - Out of memory");
-			return NULL;
+		if (!serial) {
+			serial = kmalloc(sizeof(*serial), GFP_KERNEL);
+			if (!serial) {
+				err(__FUNCTION__ " - Out of memory");
+				return NULL;
+			}
+			memset(serial, 0, sizeof(*serial));
 		}
-		memset(serial, 0, sizeof(struct usb_serial));
 		serial->magic = USB_SERIAL_MAGIC;
 		serial_table[i] = serial;
 		*minor = i;
@@ -1140,6 +1142,27 @@
 	wake_up_interruptible(&tty->write_wait);
 }
 
+static struct usb_serial * create_serial (struct usb_device *dev, 
+					  struct usb_interface *interface,
+					  struct usb_serial_device_type *type)
+{
+	struct usb_serial *serial;
+
+	serial = kmalloc (sizeof (*serial), GFP_KERNEL);
+	if (!serial) {
+		err ("%s - out of memory", __FUNCTION__);
+		return NULL;
+	}
+	memset (serial, 0, sizeof(*serial));
+	serial->dev = dev;
+	serial->type = type;
+	serial->interface = interface;
+	serial->vendor = dev->descriptor.idVendor;
+	serial->product = dev->descriptor.idProduct;
+
+	return serial;
+}
+
 static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
 			       const struct usb_device_id *id)
 {
@@ -1161,7 +1184,7 @@
 	int num_interrupt_in = 0;
 	int num_bulk_in = 0;
 	int num_bulk_out = 0;
-	int num_ports;
+	int num_ports = 0;
 	int max_endpoints;
 	const struct usb_device_id *id_pattern = NULL;
 
@@ -1184,6 +1207,27 @@
 		return(NULL);
 	}
 
+	/* if this device type has a probe function, call it */
+	if (type->probe) {
+		serial = create_serial (dev, interface, type);
+		if (!serial) {
+			err ("%s - out of memory", __FUNCTION__);
+			return NULL;
+		}
+
+		if (type->owner)
+			__MOD_INC_USE_COUNT(type->owner);
+		retval = type->probe (serial);
+		if (type->owner)
+			__MOD_DEC_USE_COUNT(type->owner);
+
+		if (retval < 0) {
+			dbg ("sub driver rejected device");
+			kfree (serial);
+			return NULL;
+		}
+	}
+
 	/* descriptor matches, let's find the endpoints needed */
 	/* check out the endpoints */
 	iface_desc = &interface->altsetting[0];
@@ -1251,11 +1295,30 @@
 			err("Generic device with no bulk out, not allowed.");
 			return NULL;
 		}
-	} else
+	}
 #endif
-		num_ports = type->num_ports;
+	if (!num_ports) {
+		/* if this device type has a calc_num_ports function, call it */
+		if (type->calc_num_ports) {
+			if (!serial) {
+				serial = create_serial (dev, interface, type);
+				if (!serial) {
+					err ("%s - out of memory", __FUNCTION__);
+					return NULL;
+				}
+			}
 
-	serial = get_free_serial (num_ports, &minor);
+			if (type->owner)
+				__MOD_INC_USE_COUNT(type->owner);
+			num_ports = type->calc_num_ports (serial);
+			if (type->owner)
+				__MOD_DEC_USE_COUNT(type->owner);
+		}
+		if (!num_ports)
+			num_ports = type->num_ports;
+	}
+
+	serial = get_free_serial (serial, num_ports, &minor);
 	if (serial == NULL) {
 		err("No more free serial devices");
 		return NULL;
@@ -1272,17 +1335,6 @@
 	serial->vendor = dev->descriptor.idVendor;
 	serial->product = dev->descriptor.idProduct;
 
-	/* if this device type has a startup function, call it */
-	if (type->startup) {
-		if (type->owner)
-			__MOD_INC_USE_COUNT(type->owner);
-		retval = type->startup (serial);
-		if (type->owner)
-			__MOD_DEC_USE_COUNT(type->owner);
-		if (retval)
-			goto probe_error;
-	}
-
 	/* set up the endpoint information */
 	for (i = 0; i < num_bulk_in; ++i) {
 		endpoint = bulk_in_endpoint[i];
@@ -1372,6 +1424,22 @@
 		port->tqueue.routine = port_softint;
 		port->tqueue.data = port;
 		init_MUTEX (&port->sem);
+	}
+
+	/* if this device type has an attach function, call it */
+	if (type->attach) {
+		if (type->owner)
+			__MOD_INC_USE_COUNT(type->owner);
+		retval = type->attach (serial);
+		if (type->owner)
+			__MOD_DEC_USE_COUNT(type->owner);
+		if (retval < 0)
+			goto probe_error;
+		if (retval > 0) {
+			/* quietly accept this device, but don't bind to a serial port
+			 * as it's about to disappear */
+			return serial;
+		}
 	}
 
 	/* initialize the devfs nodes for this device and let the user know what ports we are bound to */
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/visor.c	Sun Jun 16 19:31:40 2002
@@ -168,7 +168,8 @@
 static int  visor_chars_in_buffer	(struct usb_serial_port *port);
 static void visor_throttle	(struct usb_serial_port *port);
 static void visor_unthrottle	(struct usb_serial_port *port);
-static int  visor_startup	(struct usb_serial *serial);
+static int  visor_probe		(struct usb_serial *serial);
+static int  visor_calc_num_ports(struct usb_serial *serial);
 static void visor_shutdown	(struct usb_serial *serial);
 static int  visor_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void visor_set_termios	(struct usb_serial_port *port, struct termios *old_termios);
@@ -177,7 +178,7 @@
 static int  clie_3_5_startup	(struct usb_serial *serial);
 
 
-static __devinitdata struct usb_device_id combined_id_table [] = {
+static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
@@ -191,12 +192,12 @@
 	{ }					/* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id clie_id_3_5_table [] = {
+static struct usb_device_id clie_id_3_5_table [] = {
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
 	{ }					/* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id id_table [] = {
+static __devinitdata struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
@@ -211,7 +212,7 @@
 	{ }					/* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 
 
@@ -219,7 +220,7 @@
 static struct usb_serial_device_type handspring_device = {
 	owner:			THIS_MODULE,
 	name:			"Handspring Visor / Palm 4.0 / Clié 4.x",
-	id_table:		combined_id_table,
+	id_table:		id_table,
 	num_interrupt_in:	0,
 	num_bulk_in:		2,
 	num_bulk_out:		2,
@@ -228,7 +229,8 @@
 	close:			visor_close,
 	throttle:		visor_throttle,
 	unthrottle:		visor_unthrottle,
-	startup:		visor_startup,
+	probe:			visor_probe,
+	calc_num_ports:		visor_calc_num_ports,
 	shutdown:		visor_shutdown,
 	ioctl:			visor_ioctl,
 	set_termios:		visor_set_termios,
@@ -252,7 +254,7 @@
 	close:			visor_close,
 	throttle:		visor_throttle,
 	unthrottle:		visor_unthrottle,
-	startup:		clie_3_5_startup,
+	attach:			clie_3_5_startup,
 	ioctl:			visor_ioctl,
 	set_termios:		visor_set_termios,
 	write:			visor_write,
@@ -531,11 +533,11 @@
 		err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 }
 
-
-static int  visor_startup (struct usb_serial *serial)
+static int visor_probe (struct usb_serial *serial)
 {
 	int response;
 	int i;
+	int num_ports;
 	unsigned char *transfer_buffer =  kmalloc (256, GFP_KERNEL);
 
 	if (!transfer_buffer) {
@@ -558,8 +560,9 @@
 		char *string;
 
 		le16_to_cpus(&connection_info->num_ports);
+		num_ports = connection_info->num_ports;
 		info("%s: Number of ports: %d", serial->type->name, connection_info->num_ports);
-		for (i = 0; i < connection_info->num_ports; ++i) {
+		for (i = 0; i < num_ports; ++i) {
 			switch (connection_info->connections[i].port_function_id) {
 				case VISOR_FUNCTION_GENERIC:
 					string = "Generic";
@@ -580,7 +583,10 @@
 					string = "unknown";
 					break;	
 			}
-			info("%s: port %d, is for %s use and is bound to ttyUSB%d", serial->type->name, connection_info->connections[i].port, string, serial->minor + i);
+			info("%s: port %d, is for %s use", serial->type->name,
+			     connection_info->connections[i].port, string);
+		/* save off our num_ports info so that we can use it in the calc_num_ports call */
+		serial->private = (void *)num_ports;
 		}
 	}
 
@@ -619,6 +625,17 @@
 
 	/* continue on with initialization */
 	return 0;
+}
+
+static int visor_calc_num_ports (struct usb_serial *serial)
+{
+	int num_ports = 0;
+
+	if (serial->private) {
+		num_ports = (int)serial->private;
+		serial->private = NULL;
+	}
+	return num_ports;
 }
 
 static int clie_3_5_startup (struct usb_serial *serial)
diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
--- a/drivers/usb/serial/whiteheat.c	Sun Jun 16 19:31:40 2002
+++ b/drivers/usb/serial/whiteheat.c	Sun Jun 16 19:31:40 2002
@@ -100,12 +100,12 @@
    separate ID tables, and then a third table that combines them
    just for the purpose of exporting the autoloading information.
 */
-static __devinitdata struct usb_device_id id_table_std [] = {
+static struct usb_device_id id_table_std [] = {
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) },
 	{ }						/* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id id_table_prerenumeration [] = {
+static struct usb_device_id id_table_prerenumeration [] = {
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) },
 	{ }						/* Terminating entry */
 };
@@ -125,9 +125,9 @@
 static void whiteheat_set_termios	(struct usb_serial_port *port, struct termios * old);
 static void whiteheat_throttle		(struct usb_serial_port *port);
 static void whiteheat_unthrottle	(struct usb_serial_port *port);
-static int  whiteheat_fake_startup	(struct usb_serial *serial);
-static int  whiteheat_real_startup	(struct usb_serial *serial);
-static void whiteheat_real_shutdown	(struct usb_serial *serial);
+static int  whiteheat_firmware_download	(struct usb_serial *serial);
+static int  whiteheat_attach		(struct usb_serial *serial);
+static void whiteheat_shutdown		(struct usb_serial *serial);
 
 static struct usb_serial_device_type whiteheat_fake_device = {
 	owner:			THIS_MODULE,
@@ -137,7 +137,7 @@
 	num_bulk_in:		NUM_DONT_CARE,
 	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
-	startup:		whiteheat_fake_startup,
+	probe:			whiteheat_firmware_download,
 };
 
 static struct usb_serial_device_type whiteheat_device = {
@@ -154,8 +154,8 @@
 	unthrottle:		whiteheat_unthrottle,
 	ioctl:			whiteheat_ioctl,
 	set_termios:		whiteheat_set_termios,
-	startup:		whiteheat_real_startup,
-	shutdown:		whiteheat_real_shutdown,
+	attach:			whiteheat_attach,
+	shutdown:		whiteheat_shutdown,
 };
 
 struct whiteheat_private {
@@ -504,7 +504,7 @@
  - device renumerated itself and comes up as new device id with all
    firmware download completed.
 */
-static int  whiteheat_fake_startup (struct usb_serial *serial)
+static int whiteheat_firmware_download (struct usb_serial *serial)
 {
 	int response;
 	const struct whiteheat_hex_record *record;
@@ -518,8 +518,8 @@
 		response = ezusb_writememory (serial, record->address, 
 				(unsigned char *)record->data, record->data_size, 0xa0);
 		if (response < 0) {
-			err(__FUNCTION__ " - ezusb_writememory failed for loader (%d %04X %p %d)", 
-				response, record->address, record->data, record->data_size);
+			err("%s - ezusb_writememory failed for loader (%d %04X %p %d)",
+				__FUNCTION__, response, record->address, record->data, record->data_size);
 			break;
 		}
 		++record;
@@ -535,8 +535,8 @@
 		response = ezusb_writememory (serial, record->address, 
 				(unsigned char *)record->data, record->data_size, 0xa3);
 		if (response < 0) {
-			err(__FUNCTION__ " - ezusb_writememory failed for first firmware step (%d %04X %p %d)", 
-				response, record->address, record->data, record->data_size);
+			err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", 
+				__FUNCTION__, response, record->address, record->data, record->data_size);
 			break;
 		}
 		++record;
@@ -549,8 +549,8 @@
 		response = ezusb_writememory (serial, record->address, 
 				(unsigned char *)record->data, record->data_size, 0xa0);
 		if (response < 0) {
-			err(__FUNCTION__" - ezusb_writememory failed for second firmware step (%d %04X %p %d)", 
-				response, record->address, record->data, record->data_size);
+			err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", 
+				__FUNCTION__, response, record->address, record->data, record->data_size);
 			break;
 		}
 		++record;
@@ -563,7 +563,7 @@
 }
 
 
-static int  whiteheat_real_startup (struct usb_serial *serial)
+static int whiteheat_attach (struct usb_serial *serial)
 {
 	struct whiteheat_hw_info *hw_info;
 	int pipe;
@@ -622,7 +622,7 @@
 	return 0;
 }
 
-static void whiteheat_real_shutdown (struct usb_serial *serial)
+static void whiteheat_shutdown (struct usb_serial *serial)
 {
 	struct usb_serial_port *command_port;
 
diff -Nru a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c
--- a/drivers/usb/storage/debug.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/usb/storage/debug.c	Sun Jun 16 19:31:39 2002
@@ -218,158 +218,17 @@
 		unsigned char asc,
 		unsigned char ascq) {
 
-	char *keys[] = {
-		"No Sense",
-		"Recovered Error",
-		"Not Ready",
-		"Medium Error",
-		"Hardware Error",
-		"Illegal Request",
-		"Unit Attention",
-		"Data Protect",
-		"Blank Check",
-		"Vendor Specific",
-		"Copy Aborted",
-		"Aborted Command",
-		"(Obsolete)",
-		"Volume Overflow",
-		"Miscompare"
-	};
+	const char *what, *keystr;
 
-	unsigned short qual = asc;
+	keystr = scsi_sense_key_string(key);
+	what = scsi_extd_sense_format(asc, ascq);
 
-	char *what = 0;
-	char *keystr = 0;
-
-	qual <<= 8;
-	qual |= ascq;
-
-	if (key>0x0E)
+	if (keystr == NULL)
 		keystr = "(Unknown Key)";
-	else
-		keystr = keys[key];
-
-	switch (qual) {
-
-	case 0x0000: what="no additional sense information"; break;
-	case 0x0001: what="filemark detected"; break;
-	case 0x0002: what="end of partition/medium detected"; break;
-	case 0x0003: what="setmark detected"; break;
-	case 0x0004: what="beginning of partition/medium detected"; break;
-	case 0x0005: what="end of data detected"; break;
-	case 0x0006: what="I/O process terminated"; break;
-	case 0x0011: what="audio play operation in progress"; break;
-	case 0x0012: what="audio play operation paused"; break;
-	case 0x0013: what="audio play operation stopped due to error"; break;
-	case 0x0014: what="audio play operation successfully completed"; break;
-	case 0x0015: what="no current audio status to return"; break;
-	case 0x0016: what="operation in progress"; break;
-	case 0x0017: what="cleaning requested"; break;
-	case 0x0100: what="no index/sector signal"; break;
-	case 0x0200: what="no seek complete"; break;
-	case 0x0300: what="peripheral device write fault"; break;
-	case 0x0301: what="no write current"; break;
-	case 0x0302: what="excessive write errors"; break;
-	case 0x0400: what="LUN not ready, cause not reportable"; break;
-	case 0x0401: what="LUN in process of becoming ready"; break;
-	case 0x0402: what="LUN not ready, initializing cmd. required"; break;
-	case 0x0403: what="LUN not ready, manual intervention required"; break;
-	case 0x0404: what="LUN not ready, format in progress"; break;
-	case 0x0405: what="LUN not ready, rebuild in progress"; break;
-	case 0x0406: what="LUN not ready, recalculation in progress"; break;
-	case 0x0407: what="LUN not ready, operation in progress"; break;
-	case 0x0408: what="LUN not ready, long write in progress"; break;
-	case 0x0500: what="LUN doesn't respond to selection"; break;
-	case 0x0A00: what="error log overflow"; break;
-	case 0x0C04: what="compression check miscompare error"; break;
-	case 0x0C05: what="data expansion occurred during compression"; break;
-	case 0x0C06: what="block not compressible"; break;
-	case 0x1102: what="error too long to correct"; break;
-	case 0x1106: what="CIRC unrecovered error"; break;
-	case 0x1107: what="data resynchronization error"; break;
-	case 0x110D: what="decompression CRC error"; break;
-	case 0x110E: what="can't decompress using declared algorithm"; break;
-	case 0x110F: what="error reading UPC/EAN number"; break;
-	case 0x1110: what="error reading ISRC number"; break;
-	case 0x1200: what="address mark not found for ID field"; break;
-	case 0x1300: what="address mark not found for data field"; break;
-	case 0x1403: what="end of data not found"; break;
-	case 0x1404: what="block sequence error"; break;
-	case 0x1600: what="data sync mark error"; break;
-	case 0x1601: what="data sync error: data rewritten"; break;
-	case 0x1602: what="data sync error: recommend rewrite"; break;
-	case 0x1603: what="data sync error: data auto-reallocated"; break;
-	case 0x1604: what="data sync error: recommend reassignment"; break;
-	case 0x1900: what="defect list error"; break;
-	case 0x1901: what="defect list not available"; break;
-	case 0x1902: what="defect list error in primary list"; break;
-	case 0x1903: what="defect list error in grown list"; break;
-	case 0x1C00: what="defect list not found"; break;
-	case 0x2000: what="invalid command operation code"; break;
-	case 0x2400: what="invalid field in CDB"; break;
-	case 0x2703: what="associated write protect"; break;
-	case 0x2800: what="not ready to ready transition"; break;
-	case 0x2900: what="device reset occurred"; break;
-	case 0x2903: what="bus device reset function occurred"; break;
-	case 0x2904: what="device internal reset"; break;
-	case 0x2B00: what="copy can't execute / host can't disconnect"; break;
-	case 0x2C00: what="command sequence error"; break;
-	case 0x2C03: what="current program area is not empty"; break;
-	case 0x2C04: what="current program area is empty"; break;
-	case 0x2F00: what="commands cleared by another initiator"; break;
-	case 0x3001: what="can't read medium: unknown format"; break;
-	case 0x3002: what="can't read medium: incompatible format"; break;
-	case 0x3003: what="cleaning cartridge installed"; break;
-	case 0x3004: what="can't write medium: unknown format"; break;
-	case 0x3005: what="can't write medium: incompatible format"; break;
-	case 0x3006: what="can't format medium: incompatible medium"; break;
-	case 0x3007: what="cleaning failure"; break;
-	case 0x3008: what="can't write: application code mismatch"; break;
-	case 0x3009: what="current session not fixated for append"; break;
-	case 0x3201: what="defect list update failure"; break;
-	case 0x3400: what="enclosure failure"; break;
-	case 0x3500: what="enclosure services failure"; break;
-	case 0x3502: what="enclosure services unavailable"; break;
-	case 0x3503: what="enclosure services transfer failure"; break;
-	case 0x3504: what="enclosure services transfer refused"; break;
-	case 0x3A00: what="media not present"; break;
-	case 0x3B0F: what="end of medium reached"; break;
-	case 0x3F02: what="changed operating definition"; break;
-	case 0x4100: what="data path failure (should use 40 NN)"; break;
-	case 0x4A00: what="command phase error"; break;
-	case 0x4B00: what="data phase error"; break;
-	case 0x5100: what="erase failure"; break;
-	case 0x5200: what="cartridge fault"; break;
-	case 0x6300: what="end of user area encountered on this track"; break;
-	case 0x6600: what="automatic document feeder cover up"; break;
-	case 0x6601: what="automatic document feeder lift up"; break;
-	case 0x6602: what="document jam in auto doc feeder"; break;
-	case 0x6603: what="document miss feed auto in doc feeder"; break;
-	case 0x6700: what="configuration failure"; break;
-	case 0x6701: what="configuration of incapable LUN's failed"; break;
-	case 0x6702: what="add logical unit failed"; break;
-	case 0x6706: what="attachment of logical unit failed"; break;
-	case 0x6707: what="creation of logical unit failed"; break;
-	case 0x6900: what="data loss on logical unit"; break;
-	case 0x6E00: what="command to logical unit failed"; break;
-	case 0x7100: what="decompression exception long algorithm ID"; break;
-	case 0x7204: what="empty or partially written reserved track"; break;
-	case 0x7300: what="CD control error"; break;
-
-	default:
-		if (asc==0x40) {
-			US_DEBUGP("%s: diagnostic failure on component"
-			  " %02X\n", keystr, ascq);
-			return;
-		}
-		if (asc==0x70) {
-			US_DEBUGP("%s: decompression exception short"
-			  " algorithm ID of %02X\n", keystr, ascq);
-			return;
-		}
+	if (what == NULL)
 		what = "(unknown ASC/ASCQ)";
-	}
 
-	US_DEBUGP("%s: %s\n", keystr, what);
+	US_DEBUGP("%s: ", keystr);
+	US_DEBUGPX(what, ascq);
+	US_DEBUGPX("\n");
 }
-
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	Sun Jun 16 19:31:39 2002
+++ b/drivers/video/Makefile	Sun Jun 16 19:31:39 2002
@@ -2,8 +2,6 @@
 # 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
 # Rewritten to use lists instead of if-statements.
 
-mod-subdirs	:= matrox
-
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
diff -Nru a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
--- a/drivers/video/cfbimgblt.c	Sun Jun 16 19:31:39 2002
+++ b/drivers/video/cfbimgblt.c	Sun Jun 16 19:31:39 2002
@@ -43,12 +43,14 @@
 
 void cfb_imageblit(struct fb_info *p, struct fb_image *image)
 {
-	int pad, ppw, shift, shift_right, shift_left, x2, y2, n, i, j, k, l = 7;
+	int pad, ppw;
+	int x2, y2, n, i, j, k, l = 7;
 	unsigned long tmp = ~0 << (BITS_PER_LONG - p->var.bits_per_pixel);
 	unsigned long fgx, bgx, fgcolor, bgcolor, eorx;	
-	unsigned long end_index, end_mask;
+	unsigned long end_mask;
 	unsigned long *dst = NULL;
-	u8 *dst1, *src;
+	u8 *dst1;
+	u8 *src;
 
 	/* 
 	 * We could use hardware clipping but on many cards you get around hardware
@@ -97,8 +99,8 @@
 			for (j = image->width/ppw; j > 0; j--) {
 				end_mask = 0;
 		
-				for (k = ppw; k > 0; k--) {	
-					if (test_bit(l, src))
+				for (k = ppw; k > 0; k--) {
+					if (test_bit(l, (unsigned long *) src))
 						end_mask |= (tmp >> (p->var.bits_per_pixel*(k-1)));
 					l--;
 					if (l < 0) { l = 7; src++; }
@@ -110,7 +112,7 @@
 			if (n) {
 				end_mask = 0;	
 				for (j = n; j > 0; j--) {
-					if (test_bit(l, src))
+					if (test_bit(l, (unsigned long *) src))
 						end_mask |= (tmp >> (p->var.bits_per_pixel*(j-1)));
 					l--;
 					if (l < 0) { l = 7; src++; }
diff -Nru a/fs/Makefile b/fs/Makefile
--- a/fs/Makefile	Sun Jun 16 19:31:39 2002
+++ b/fs/Makefile	Sun Jun 16 19:31:39 2002
@@ -9,7 +9,6 @@
 
 export-objs :=	filesystems.o open.o dcache.o buffer.o bio.o inode.o dquot.o \
 		mpage.o
-mod-subdirs :=	nls
 
 obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
 		bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \
diff -Nru a/fs/adfs/map.c b/fs/adfs/map.c
--- a/fs/adfs/map.c	Sun Jun 16 19:31:40 2002
+++ b/fs/adfs/map.c	Sun Jun 16 19:31:40 2002
@@ -257,7 +257,7 @@
 adfs_map_lookup(struct super_block *sb, unsigned int frag_id,
 		unsigned int offset)
 {
-	struct adfs_sb_info *asb = &sb->u.adfs_sb;
+	struct adfs_sb_info *asb = ADFS_SB(sb);
 	unsigned int zone, mapoff;
 	int result;
 
diff -Nru a/fs/bfs/inode.c b/fs/bfs/inode.c
--- a/fs/bfs/inode.c	Sun Jun 16 19:31:40 2002
+++ b/fs/bfs/inode.c	Sun Jun 16 19:31:40 2002
@@ -196,7 +196,7 @@
 	buf->f_bfree = buf->f_bavail = info->si_freeb;
 	buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO;
 	buf->f_ffree = info->si_freei;
-	buf->f_fsid.val[0] = kdev_t_to_nr(s->s_dev);
+	buf->f_fsid.val[0] = s->s_dev;
 	buf->f_namelen = BFS_NAMELEN;
 	return 0;
 }
diff -Nru a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c	Sun Jun 16 19:31:39 2002
+++ b/fs/bio.c	Sun Jun 16 19:31:39 2002
@@ -341,11 +341,10 @@
 	int i, offset, size, err, map_i, total_nr_pages, nr_pages;
 	struct bio_vec *bvec;
 	struct bio *bio;
-	kdev_t dev = to_kdev_t(bdev->bd_dev);
 
 	err = 0;
-	if ((rw & WRITE) && is_read_only(dev)) {
-		printk("ll_rw_bio: WRITE to ro device %s\n", kdevname(dev));
+	if ((rw & WRITE) && bdev_read_only(bdev)) {
+		printk("ll_rw_bio: WRITE to ro device %s\n", bdevname(bdev));
 		err = -EPERM;
 		goto out;
 	}
diff -Nru a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c	Sun Jun 16 19:31:40 2002
+++ b/fs/block_dev.c	Sun Jun 16 19:31:40 2002
@@ -181,44 +181,16 @@
  * pseudo-fs
  */
 
-static int bd_fill_super(struct super_block *sb, void *data, int silent)
-{
-	static struct super_operations sops = {};
-	struct inode *root;
-
-	sb->s_maxbytes = ~0ULL;
-	sb->s_blocksize = 1024;
-	sb->s_blocksize_bits = 10;
-	sb->s_magic = 0x62646576;
-	sb->s_op = &sops;
-	root = new_inode(sb);
-	if (!root)
-		return -ENOMEM;
-	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
-	root->i_uid = root->i_gid = 0;
-	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
-	sb->s_root = d_alloc(NULL, &(const struct qstr) { "bdev:", 5, 0 });
-	if (!sb->s_root) {
-		iput(root);
-		return -ENOMEM;
-	}
-	sb->s_root->d_sb = sb;
-	sb->s_root->d_parent = sb->s_root;
-	d_instantiate(sb->s_root, root);
-	return 0;
-}
-
 static struct super_block *bd_get_sb(struct file_system_type *fs_type,
 	int flags, char *dev_name, void *data)
 {
-	return get_sb_nodev(fs_type, flags, data, bd_fill_super);
+	return get_sb_pseudo(fs_type, "bdev:", NULL, 0x62646576);
 }
 
 static struct file_system_type bd_type = {
 	name:		"bdev",
 	get_sb:		bd_get_sb,
 	kill_sb:	kill_anon_super,
-	fs_flags:	FS_NOMOUNT,
 };
 
 static struct vfsmount *bd_mnt;
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Sun Jun 16 19:31:39 2002
+++ b/fs/buffer.c	Sun Jun 16 19:31:39 2002
@@ -232,7 +232,7 @@
  */
 int fsync_bdev(struct block_device *bdev)
 {
-	struct super_block *sb = get_super(to_kdev_t(bdev->bd_dev));
+	struct super_block *sb = get_super(bdev);
 	if (sb) {
 		int res = fsync_super(sb);
 		drop_super(sb);
diff -Nru a/fs/coda/inode.c b/fs/coda/inode.c
--- a/fs/coda/inode.c	Sun Jun 16 19:31:40 2002
+++ b/fs/coda/inode.c	Sun Jun 16 19:31:40 2002
@@ -197,8 +197,8 @@
 	    goto error;
 	} 
 
-	printk("coda_read_super: rootinode is %ld dev %x\n", 
-	       root->i_ino, kdev_val(root->i_dev));
+	printk("coda_read_super: rootinode is %ld dev %s\n", 
+	       root->i_ino, root->i_sb->s_id);
 	sb->s_root = d_alloc_root(root);
         return 0;
 
diff -Nru a/fs/dquot.c b/fs/dquot.c
--- a/fs/dquot.c	Sun Jun 16 19:31:39 2002
+++ b/fs/dquot.c	Sun Jun 16 19:31:39 2002
@@ -179,7 +179,7 @@
 
 static inline int const hashfn(struct super_block *sb, unsigned int id, int type)
 {
-	return((HASHDEV(sb->s_dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
+	return((((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
 }
 
 static inline void insert_dquot_hash(struct dquot *dquot)
diff -Nru a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
--- a/fs/exportfs/expfs.c	Sun Jun 16 19:31:40 2002
+++ b/fs/exportfs/expfs.c	Sun Jun 16 19:31:40 2002
@@ -105,7 +105,7 @@
 	/* It's a directory, or we are required to confirm the file's
 	 * location in the tree based on the parent information
  	 */
-	dprintk("find_exported_dentry: need to look harder for %d/%d\n",kdev_t_to_nr(sb->s_dev),*(int*)obj);
+	dprintk("find_exported_dentry: need to look harder for %s/%d\n",sb->s_id,*(int*)obj);
 	if (S_ISDIR(result->d_inode->i_mode))
 		target_dir = dget(result);
 	else {
diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
--- a/fs/ext2/inode.c	Sun Jun 16 19:31:39 2002
+++ b/fs/ext2/inode.c	Sun Jun 16 19:31:39 2002
@@ -43,8 +43,7 @@
  */
 void ext2_put_inode (struct inode * inode)
 {
-	if (atomic_read(&inode->i_count) < 2)	/* final iput? */
-		ext2_discard_prealloc (inode);
+	ext2_discard_prealloc (inode);
 }
 
 /*
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c	Sun Jun 16 19:31:40 2002
+++ b/fs/ext3/ialloc.c	Sun Jun 16 19:31:40 2002
@@ -389,7 +389,7 @@
 
 	err = -ENOSPC;
 	if (!gdp)
-		goto fail;
+		goto out;
 
 	err = -EIO;
 	bitmap_nr = load_inode_bitmap (sb, i);
@@ -532,9 +532,10 @@
 	return inode;
 
 fail:
+	ext3_std_error(sb, err);
+out:
 	unlock_super(sb);
 	iput(inode);
-	ext3_std_error(sb, err);
 	return ERR_PTR(err);
 }
 
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	Sun Jun 16 19:31:40 2002
+++ b/fs/ext3/namei.c	Sun Jun 16 19:31:40 2002
@@ -514,8 +514,8 @@
 			inode->i_mapping->a_ops = &ext3_writeback_aops;
 		else
 			inode->i_mapping->a_ops = &ext3_aops;
-		ext3_mark_inode_dirty(handle, inode);
 		err = ext3_add_nondir(handle, dentry, inode);
+		ext3_mark_inode_dirty(handle, inode);
 	}
 	ext3_journal_stop(handle, dir);
 	unlock_kernel();
@@ -543,8 +543,8 @@
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
 		init_special_inode(inode, mode, rdev);
-		ext3_mark_inode_dirty(handle, inode);
 		err = ext3_add_nondir(handle, dentry, inode);
+		ext3_mark_inode_dirty(handle, inode);
 	}
 	ext3_journal_stop(handle, dir);
 	unlock_kernel();
@@ -1006,8 +1006,8 @@
 		inode->i_size = l-1;
 	}
 	EXT3_I(inode)->i_disksize = inode->i_size;
-	ext3_mark_inode_dirty(handle, inode);
 	err = ext3_add_nondir(handle, dentry, inode);
+	ext3_mark_inode_dirty(handle, inode);
 out_stop:
 	ext3_journal_stop(handle, dir);
 	unlock_kernel();
@@ -1046,8 +1046,8 @@
 	ext3_inc_count(handle, inode);
 	atomic_inc(&inode->i_count);
 
-	ext3_mark_inode_dirty(handle, inode);
 	err = ext3_add_nondir(handle, dentry, inode);
+	ext3_mark_inode_dirty(handle, inode);
 	ext3_journal_stop(handle, dir);
 	unlock_kernel();
 	return err;
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	Sun Jun 16 19:31:41 2002
+++ b/fs/ext3/super.c	Sun Jun 16 19:31:41 2002
@@ -1400,7 +1400,7 @@
 	int err = 0;
 	int really_read_only;
 
-	really_read_only = is_read_only(sb->s_dev);
+	really_read_only = bdev_read_only(sb->s_bdev);
 
 	/*
 	 * Are we loading a blank journal or performing recovery after a
diff -Nru a/fs/hfs/inode.c b/fs/hfs/inode.c
--- a/fs/hfs/inode.c	Sun Jun 16 19:31:41 2002
+++ b/fs/hfs/inode.c	Sun Jun 16 19:31:41 2002
@@ -20,6 +20,7 @@
 #include <linux/hfs_fs_sb.h>
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
+#include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 
 /*================ Variable-like macros ================*/
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	Sun Jun 16 19:31:40 2002
+++ b/fs/inode.c	Sun Jun 16 19:31:40 2002
@@ -101,7 +101,7 @@
 		struct address_space * const mapping = &inode->i_data;
 
 		inode->i_sb = sb;
-		inode->i_dev = sb->s_dev;
+		inode->i_dev = to_kdev_t(sb->s_dev);
 		inode->i_blkbits = sb->s_blocksize_bits;
 		inode->i_flags = 0;
 		atomic_set(&inode->i_count, 1);
@@ -332,7 +332,7 @@
 		fsync_bdev(bdev);
 
 	res = 0;
-	sb = get_super(dev);
+	sb = get_super(bdev);
 	if (sb) {
 		/*
 		 * no need to lock the super, get_super holds the
diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
--- a/fs/jffs/inode-v23.c	Sun Jun 16 19:31:39 2002
+++ b/fs/jffs/inode-v23.c	Sun Jun 16 19:31:39 2002
@@ -73,7 +73,7 @@
 /* Called by the VFS at mount time to initialize the whole file system.  */
 static int jffs_fill_super(struct super_block *sb, void *data, int silent)
 {
-	kdev_t dev = sb->s_dev;
+	kdev_t dev = to_kdev_t(sb->s_dev);
 	struct inode *root_inode;
 	struct jffs_control *c;
 
diff -Nru a/fs/jffs/intrep.c b/fs/jffs/intrep.c
--- a/fs/jffs/intrep.c	Sun Jun 16 19:31:40 2002
+++ b/fs/jffs/intrep.c	Sun Jun 16 19:31:40 2002
@@ -450,7 +450,7 @@
 	DJM(no_hash++);
 	for (i = 0; i < c->hash_len; i++)
 		INIT_LIST_HEAD(&c->hash[i]);
-	if (!(c->fmc = jffs_build_begin(c, sb->s_dev))) {
+	if (!(c->fmc = jffs_build_begin(c, MINOR(sb->s_dev)))) {
 		goto fail_fminit;
 	}
 	c->next_ino = JFFS_MIN_INO + 1;
@@ -3148,7 +3148,7 @@
 		__u32 pos;
 		__u32 end;
 
-		pos = (__u32)flash_get_direct_pointer(c->sb->s_dev, offset);
+		pos = (__u32)flash_get_direct_pointer(to_kdev_t(c->sb->s_dev), offset);
 		end = pos + erase_size;
 
 		D2(printk("JFFS: Checking erased sector(s)...\n"));
diff -Nru a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
--- a/fs/jffs/jffs_fm.c	Sun Jun 16 19:31:39 2002
+++ b/fs/jffs/jffs_fm.c	Sun Jun 16 19:31:39 2002
@@ -31,7 +31,7 @@
 
 /* This function creates a new shiny flash memory control structure.  */
 struct jffs_fmcontrol *
-jffs_build_begin(struct jffs_control *c, kdev_t dev)
+jffs_build_begin(struct jffs_control *c, int unit)
 {
 	struct jffs_fmcontrol *fmc;
 	struct mtd_info *mtd;
@@ -46,7 +46,7 @@
 	}
 	DJM(no_jffs_fmcontrol++);
 
-	mtd = get_mtd_device(NULL, minor(dev));
+	mtd = get_mtd_device(NULL, unit);
 
 	if (!mtd) {
 		kfree(fmc);
diff -Nru a/fs/jffs/jffs_fm.h b/fs/jffs/jffs_fm.h
--- a/fs/jffs/jffs_fm.h	Sun Jun 16 19:31:40 2002
+++ b/fs/jffs/jffs_fm.h	Sun Jun 16 19:31:40 2002
@@ -122,7 +122,7 @@
 
 
 
-struct jffs_fmcontrol *jffs_build_begin(struct jffs_control *c, kdev_t dev);
+struct jffs_fmcontrol *jffs_build_begin(struct jffs_control *c, int unit);
 void jffs_build_end(struct jffs_fmcontrol *fmc);
 void jffs_cleanup_fmcontrol(struct jffs_fmcontrol *fmc);
 
diff -Nru a/fs/jffs2/super.c b/fs/jffs2/super.c
--- a/fs/jffs2/super.c	Sun Jun 16 19:31:40 2002
+++ b/fs/jffs2/super.c	Sun Jun 16 19:31:40 2002
@@ -43,6 +43,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/fs.h>
+#include <linux/namei.h>
 #include <linux/jffs2.h>
 #include <linux/pagemap.h>
 #include <linux/mtd/mtd.h>
@@ -118,7 +119,7 @@
 	   device */
 	sb->u.generic_sbp = p;
 	p->os_priv = sb;
-	sb->s_dev = mk_kdev(MTD_BLOCK_MAJOR, p->mtd->index);
+	sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index);
 
 	return 0;
 }
diff -Nru a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
--- a/fs/jfs/jfs_mount.c	Sun Jun 16 19:31:40 2002
+++ b/fs/jfs/jfs_mount.c	Sun Jun 16 19:31:40 2002
@@ -507,7 +507,7 @@
 	lrd.backchain = 0;
 	lrd.type = cpu_to_le16(LOG_MOUNT);
 	lrd.length = 0;
-	lrd.aggregate = cpu_to_le32(kdev_t_to_nr(sb->s_dev));
+	lrd.aggregate = cpu_to_le32(sb->s_bdev->bd_dev);
 	lmLog(log, NULL, &lrd, NULL);
 
 	return 0;
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Sun Jun 16 19:31:39 2002
+++ b/fs/jfs/jfs_txnmgr.c	Sun Jun 16 19:31:39 2002
@@ -1325,7 +1325,7 @@
 
 		/* initialize lrd common */
 		ip = tlck->ip;
-		lrd->aggregate = cpu_to_le32(kdev_t_to_nr(ip->i_dev));
+		lrd->aggregate = cpu_to_le32(ip->i_sb->s_bdev->bd_dev);
 		lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset);
 		lrd->log.redopage.inode = cpu_to_le32(ip->i_ino);
 
diff -Nru a/fs/libfs.c b/fs/libfs.c
--- a/fs/libfs.c	Sun Jun 16 19:31:39 2002
+++ b/fs/libfs.c	Sun Jun 16 19:31:39 2002
@@ -155,3 +155,50 @@
 struct inode_operations simple_dir_inode_operations = {
 	lookup:		simple_lookup,
 };
+
+/*
+ * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
+ * will never be mountable)
+ */
+struct super_block *
+get_sb_pseudo(struct file_system_type *fs_type, char *name,
+	struct super_operations *ops, unsigned long magic)
+{
+	struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
+	static struct super_operations default_ops = {statfs: simple_statfs};
+	struct dentry *dentry;
+	struct inode *root;
+	struct qstr d_name = {name:name, len:strlen(name)};
+
+	if (IS_ERR(s))
+		return s;
+
+	s->s_flags = MS_NOUSER;
+	s->s_maxbytes = ~0ULL;
+	s->s_blocksize = 1024;
+	s->s_blocksize_bits = 10;
+	s->s_magic = magic;
+	s->s_op = ops ? ops : &default_ops;
+	root = new_inode(s);
+	if (!root)
+		goto Enomem;
+	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
+	root->i_uid = root->i_gid = 0;
+	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
+	dentry = d_alloc(NULL, &d_name);
+	if (!dentry) {
+		iput(root);
+		goto Enomem;
+	}
+	dentry->d_sb = s;
+	dentry->d_parent = dentry;
+	d_instantiate(dentry, root);
+	s->s_root = dentry;
+	s->s_flags |= MS_ACTIVE;
+	return s;
+
+Enomem:
+	up_write(&s->s_umount);
+	deactivate_super(s);
+	return ERR_PTR(-ENOMEM);
+}
diff -Nru a/fs/locks.c b/fs/locks.c
--- a/fs/locks.c	Sun Jun 16 19:31:40 2002
+++ b/fs/locks.c	Sun Jun 16 19:31:40 2002
@@ -443,15 +443,6 @@
 	list_add(&waiter->fl_link, &blocked_list);
 }
 
-static inline
-void locks_notify_blocked(struct file_lock *waiter)
-{
-	if (waiter->fl_notify)
-		waiter->fl_notify(waiter);
-	else
-		wake_up(&waiter->fl_wait);
-}
-
 /* Wake up processes blocked waiting for blocker.
  * If told to wait then schedule the processes until the block list
  * is empty, otherwise empty the block list ourselves.
@@ -459,12 +450,13 @@
 static void locks_wake_up_blocks(struct file_lock *blocker)
 {
 	while (!list_empty(&blocker->fl_block)) {
-		struct file_lock *waiter = list_entry(blocker->fl_block.next, struct file_lock, fl_block);
-		/* Remove waiter from the block list, because by the
-		 * time it wakes up blocker won't exist any more.
-		 */
+		struct file_lock *waiter = list_entry(blocker->fl_block.next,
+				struct file_lock, fl_block);
 		locks_delete_block(waiter);
-		locks_notify_blocked(waiter);
+		if (waiter->fl_notify)
+			waiter->fl_notify(waiter);
+		else
+			wake_up(&waiter->fl_wait);
 	}
 }
 
@@ -1405,8 +1397,6 @@
 	if (copy_from_user(&flock, l, sizeof(flock)))
 		goto out;
 
-	/* Get arguments and validate them ...
-	 */
 	inode = filp->f_dentry->d_inode;
 
 	/* Don't allow mandatory locks on files that may be memory mapped
@@ -1438,23 +1428,6 @@
 		break;
 	case F_UNLCK:
 		break;
-	case F_SHLCK:
-	case F_EXLCK:
-#ifdef __sparc__
-/* warn a bit for now, but don't overdo it */
-{
-	static int count = 0;
-	if (!count) {
-		count=1;
-		printk(KERN_WARNING
-		       "fcntl_setlk() called by process %d (%s) with broken flock() emulation\n",
-		       current->pid, current->comm);
-	}
-}
-		if (!(filp->f_mode & 3))
-			goto out;
-		break;
-#endif
 	default:
 		error = -EINVAL;
 		goto out;
@@ -1543,8 +1516,6 @@
 	if (copy_from_user(&flock, l, sizeof(flock)))
 		goto out;
 
-	/* Get arguments and validate them ...
-	 */
 	inode = filp->f_dentry->d_inode;
 
 	/* Don't allow mandatory locks on files that may be memory mapped
@@ -1576,8 +1547,6 @@
 		break;
 	case F_UNLCK:
 		break;
-	case F_SHLCK:
-	case F_EXLCK:
 	default:
 		error = -EINVAL;
 		goto out;
diff -Nru a/fs/mpage.c b/fs/mpage.c
--- a/fs/mpage.c	Sun Jun 16 19:31:39 2002
+++ b/fs/mpage.c	Sun Jun 16 19:31:39 2002
@@ -96,6 +96,12 @@
 	struct bio *bio;
 
 	bio = bio_alloc(gfp_flags, nr_vecs);
+
+	if (bio == NULL && (current->flags & PF_MEMALLOC)) {
+		while (!bio && (nr_vecs /= 2))
+			bio = bio_alloc(gfp_flags, nr_vecs);
+	}
+
 	if (bio) {
 		bio->bi_bdev = bdev;
 		bio->bi_vcnt = nr_vecs;
@@ -301,13 +307,13 @@
  * If the page has no buffers (preferred) then the page is mapped here.
  *
  * If all blocks are found to be contiguous then the page can go into the
- * BIO.  Otherwise fall back to block_write_full_page().
+ * BIO.  Otherwise fall back to the mapping's writepage().
  * 
  * FIXME: This code wants an estimate of how many pages are still to be
  * written, so it can intelligently allocate a suitably-sized BIO.  For now,
  * just allocate full-size (16-page) BIOs.
  */
-static /* inline */ struct bio *
+static inline struct bio *
 mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
 			sector_t *last_block_in_bio, int *ret)
 {
@@ -464,7 +470,7 @@
 confused:
 	if (bio)
 		bio = mpage_bio_submit(WRITE, bio);
-	*ret = block_write_full_page(page, get_block);
+	*ret = page->mapping->a_ops->writepage(page);
 out:
 	return bio;
 }
diff -Nru a/fs/nfs/file.c b/fs/nfs/file.c
--- a/fs/nfs/file.c	Sun Jun 16 19:31:40 2002
+++ b/fs/nfs/file.c	Sun Jun 16 19:31:40 2002
@@ -272,7 +272,7 @@
 	 * Not sure whether that would be unique, though, or whether
 	 * that would break in other places.
 	 */
-	if (!fl->fl_owner || (fl->fl_flags & (FL_POSIX|FL_BROKEN)) != FL_POSIX)
+	if (!fl->fl_owner || (fl->fl_flags & FL_POSIX) != FL_POSIX)
 		return -ENOLCK;
 
 	/*
diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c	Sun Jun 16 19:31:41 2002
+++ b/fs/nfs/inode.c	Sun Jun 16 19:31:41 2002
@@ -247,7 +247,7 @@
 	int			tcp, version, maxlen;
 
 	/* We probably want something more informative here */
-	snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", major(sb->s_dev), minor(sb->s_dev));
+	snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
 
 	sb->s_magic      = NFS_SUPER_MAGIC;
 	sb->s_op         = &nfs_sops;
diff -Nru a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
--- a/fs/nfs/nfsroot.c	Sun Jun 16 19:31:41 2002
+++ b/fs/nfs/nfsroot.c	Sun Jun 16 19:31:41 2002
@@ -81,6 +81,7 @@
 #include <linux/major.h>
 #include <linux/utsname.h>
 #include <linux/inet.h>
+#include <linux/root_dev.h>
 #include <net/ipconfig.h>
 
 /* Define this to allow debugging output */
@@ -335,7 +336,7 @@
  */
 int __init nfs_root_setup(char *line)
 {
-	ROOT_DEV = mk_kdev(UNNAMED_MAJOR, 255);
+	ROOT_DEV = Root_NFS;
 	if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
 		strncpy(nfs_root_name, line, sizeof(nfs_root_name));
 		nfs_root_name[sizeof(nfs_root_name)-1] = '\0';
diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c
--- a/fs/nfsd/export.c	Sun Jun 16 19:31:40 2002
+++ b/fs/nfsd/export.c	Sun Jun 16 19:31:40 2002
@@ -52,7 +52,7 @@
 #define CLIENT_HASH(a) \
 		((((a)>>24) ^ ((a)>>16) ^ ((a)>>8) ^(a)) & CLIENT_HASHMASK)
 /* XXX: is this adequate for 32bit kdev_t ? */
-#define EXPORT_HASH(dev)	(minor(dev) & (NFSCLNT_EXPMAX - 1))
+#define EXPORT_HASH(dev)	(MINOR(dev) & (NFSCLNT_EXPMAX - 1))
 #define EXPORT_FSID_HASH(fsid)	((fsid) & (NFSCLNT_EXPMAX - 1))
 
 struct svc_clnthash {
@@ -75,7 +75,7 @@
 	if (!clp)
 		return NULL;
 
-	head = &clp->cl_export[EXPORT_HASH(dev)];
+	head = &clp->cl_export[EXPORT_HASH(kdev_t_to_nr(dev))];
 	list_for_each(p, head) {
 		svc_export *exp = list_entry(p, svc_export, ex_hash);
 		if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev))
@@ -364,7 +364,7 @@
 	if (parent)
 		exp_change_parents(clp, parent, exp);
 
-	list_add(&exp->ex_hash, clp->cl_export + EXPORT_HASH(dev));
+	list_add(&exp->ex_hash, clp->cl_export + EXPORT_HASH(kdev_t_to_nr(dev)));
 	list_add_tail(&exp->ex_list, &clp->cl_list);
 
 	exp_fsid_hash(clp, exp);
diff -Nru a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
--- a/fs/nfsd/nfs3xdr.c	Sun Jun 16 19:31:38 2002
+++ b/fs/nfsd/nfs3xdr.c	Sun Jun 16 19:31:38 2002
@@ -160,35 +160,35 @@
 static inline u32 *
 encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
-	struct inode	*inode = fhp->fh_dentry->d_inode;
+	struct vfsmount *mnt = fhp->fh_export->ex_mnt;
+	struct dentry	*dentry = fhp->fh_dentry;
+	struct kstat stat;
 
-	*p++ = htonl(nfs3_ftypes[(inode->i_mode & S_IFMT) >> 12]);
-	*p++ = htonl((u32) inode->i_mode);
-	*p++ = htonl((u32) inode->i_nlink);
-	*p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid));
-	*p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid));
-	if (S_ISLNK(inode->i_mode) && inode->i_size > NFS3_MAXPATHLEN) {
+	vfs_getattr(mnt, dentry, &stat);
+
+	*p++ = htonl(nfs3_ftypes[(stat.mode & S_IFMT) >> 12]);
+	*p++ = htonl((u32) stat.mode);
+	*p++ = htonl((u32) stat.nlink);
+	*p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid));
+	*p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid));
+	if (S_ISLNK(stat.mode) && stat.size > NFS3_MAXPATHLEN) {
 		p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
 	} else {
-		p = xdr_encode_hyper(p, (u64) inode->i_size);
+		p = xdr_encode_hyper(p, (u64) stat.size);
 	}
-	if (inode->i_blksize == 0 && inode->i_blocks == 0)
-		/* Minix file system(?) i_size is (hopefully) close enough */
-		p = xdr_encode_hyper(p, (u64)(inode->i_size +511)& ~511);
-	else
-		p = xdr_encode_hyper(p, ((u64)inode->i_blocks) << 9);
-	*p++ = htonl((u32) major(inode->i_rdev));
-	*p++ = htonl((u32) minor(inode->i_rdev));
+	p = xdr_encode_hyper(p, ((u64)stat.blocks) << 9);
+	*p++ = htonl((u32) MAJOR(stat.rdev));
+	*p++ = htonl((u32) MINOR(stat.rdev));
 	if (rqstp->rq_reffh->fh_version == 1
 	    && rqstp->rq_reffh->fh_fsid_type == 1
 	    && (fhp->fh_export->ex_flags & NFSEXP_FSID))
 		p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
 	else
-		p = xdr_encode_hyper(p, (u64) kdev_t_to_nr(inode->i_dev));
-	p = xdr_encode_hyper(p, (u64) inode->i_ino);
-	p = encode_time3(p, inode->i_atime);
-	p = encode_time3(p, lease_get_mtime(inode));
-	p = encode_time3(p, inode->i_ctime);
+		p = xdr_encode_hyper(p, (u64) stat.dev);
+	p = xdr_encode_hyper(p, (u64) stat.ino);
+	p = encode_time3(p, stat.atime);
+	p = encode_time3(p, lease_get_mtime(dentry->d_inode));
+	p = encode_time3(p, stat.ctime);
 
 	return p;
 }
diff -Nru a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
--- a/fs/nfsd/nfsxdr.c	Sun Jun 16 19:31:39 2002
+++ b/fs/nfsd/nfsxdr.c	Sun Jun 16 19:31:39 2002
@@ -134,38 +134,43 @@
 static inline u32 *
 encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
-	struct inode *inode = fhp->fh_dentry->d_inode;
-	int type = (inode->i_mode & S_IFMT);
+	struct vfsmount *mnt = fhp->fh_export->ex_mnt;
+	struct dentry	*dentry = fhp->fh_dentry;
+	struct kstat stat;
+	int type;
+
+	vfs_getattr(mnt, dentry, &stat);
+	type = (stat.mode & S_IFMT);
 
 	*p++ = htonl(nfs_ftypes[type >> 12]);
-	*p++ = htonl((u32) inode->i_mode);
-	*p++ = htonl((u32) inode->i_nlink);
-	*p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid));
-	*p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid));
+	*p++ = htonl((u32) stat.mode);
+	*p++ = htonl((u32) stat.nlink);
+	*p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid));
+	*p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid));
 
-	if (S_ISLNK(type) && inode->i_size > NFS_MAXPATHLEN) {
+	if (S_ISLNK(type) && stat.size > NFS_MAXPATHLEN) {
 		*p++ = htonl(NFS_MAXPATHLEN);
 	} else {
-		*p++ = htonl((u32) inode->i_size);
+		*p++ = htonl((u32) stat.size);
 	}
-	*p++ = htonl((u32) inode->i_blksize);
+	*p++ = htonl((u32) stat.blksize);
 	if (S_ISCHR(type) || S_ISBLK(type))
-		*p++ = htonl((u32) kdev_t_to_nr(inode->i_rdev));
+		*p++ = htonl((u32) stat.rdev);
 	else
 		*p++ = htonl(0xffffffff);
-	*p++ = htonl((u32) inode->i_blocks);
+	*p++ = htonl((u32) stat.blocks);
 	if (rqstp->rq_reffh->fh_version == 1 
 	    && rqstp->rq_reffh->fh_fsid_type == 1
 	    && (fhp->fh_export->ex_flags & NFSEXP_FSID))
 		*p++ = htonl((u32) fhp->fh_export->ex_fsid);
 	else
-		*p++ = htonl((u32) kdev_t_to_nr(inode->i_dev));
-	*p++ = htonl((u32) inode->i_ino);
-	*p++ = htonl((u32) inode->i_atime);
+		*p++ = htonl((u32) stat.dev);
+	*p++ = htonl((u32) stat.ino);
+	*p++ = htonl((u32) stat.atime);
 	*p++ = 0;
-	*p++ = htonl((u32) lease_get_mtime(inode));
+	*p++ = htonl((u32) lease_get_mtime(dentry->d_inode));
 	*p++ = 0;
-	*p++ = htonl((u32) inode->i_ctime);
+	*p++ = htonl((u32) stat.ctime);
 	*p++ = 0;
 
 	return p;
diff -Nru a/fs/open.c b/fs/open.c
--- a/fs/open.c	Sun Jun 16 19:31:39 2002
+++ b/fs/open.c	Sun Jun 16 19:31:39 2002
@@ -304,7 +304,8 @@
 		newattrs.ia_mtime = times[1].tv_sec;
 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
 	} else {
-		if ((error = permission(inode,MAY_WRITE)) != 0)
+		if (current->fsuid != inode->i_uid &&
+		    (error = permission(inode,MAY_WRITE)) != 0)
 			goto dput_and_out;
 	}
 	down(&inode->i_sem);
diff -Nru a/fs/partitions/acorn.c b/fs/partitions/acorn.c
--- a/fs/partitions/acorn.c	Sun Jun 16 19:31:39 2002
+++ b/fs/partitions/acorn.c	Sun Jun 16 19:31:39 2002
@@ -12,11 +12,10 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 #include <linux/major.h>
 #include <linux/string.h>
 #include <linux/genhd.h>
-#include <linux/fs.h>
+#include <linux/buffer_head.h>
 
 #include "check.h"
 #include "acorn.h"
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Sun Jun 16 19:31:40 2002
+++ b/fs/partitions/check.c	Sun Jun 16 19:31:40 2002
@@ -412,8 +412,8 @@
 
 	g->part[first_minor].nr_sects = size;
 
-	/* No such device or no minors to use for partitions */
-	if (!size || minors == 1)
+	/* No minors to use for partitions */
+	if (minors == 1)
 		return;
 
 	if (g->sizes) {
@@ -422,6 +422,11 @@
 			g->sizes[i] = 0;
 	}
 	blk_size[g->major] = g->sizes;
+
+	/* No such device (e.g., media were just removed) */
+	if (!size)
+		return;
+
 	check_partition(g, mk_kdev(g->major, first_minor), 1 + first_minor);
 
  	/*
diff -Nru a/fs/pipe.c b/fs/pipe.c
--- a/fs/pipe.c	Sun Jun 16 19:31:39 2002
+++ b/fs/pipe.c	Sun Jun 16 19:31:39 2002
@@ -119,7 +119,7 @@
 		 * writers synchronously that there is more
 		 * room.
 		 */
-		wake_up_interruptible(PIPE_WAIT(*inode));
+		wake_up_interruptible_sync(PIPE_WAIT(*inode));
  		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
 		if (!PIPE_EMPTY(*inode))
 			BUG();
@@ -219,7 +219,7 @@
 			 * is going to give up this CPU, so it doesnt have
 			 * to do idle reschedules.
 			 */
-			wake_up_interruptible(PIPE_WAIT(*inode));
+			wake_up_interruptible_sync(PIPE_WAIT(*inode));
  			kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
 			PIPE_WAITING_WRITERS(*inode)++;
 			pipe_wait(inode);
@@ -665,46 +665,16 @@
  * d_name - pipe: will go nicely and kill the special-casing in procfs.
  */
 
-static struct super_operations pipefs_ops = {
-	statfs:		simple_statfs,
-};
-
-static int pipefs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *root;
-
-	sb->s_blocksize = 1024;
-	sb->s_blocksize_bits = 10;
-	sb->s_magic = PIPEFS_MAGIC;
-	sb->s_op	= &pipefs_ops;
-	root = new_inode(sb);
-	if (!root)
-		return -ENOMEM;
-	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
-	root->i_uid = root->i_gid = 0;
-	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
-	sb->s_root = d_alloc(NULL, &(const struct qstr) { "pipe:", 5, 0 });
-	if (!sb->s_root) {
-		iput(root);
-		return -ENOMEM;
-	}
-	sb->s_root->d_sb = sb;
-	sb->s_root->d_parent = sb->s_root;
-	d_instantiate(sb->s_root, root);
-	return 0;
-}
-
 static struct super_block *pipefs_get_sb(struct file_system_type *fs_type,
 	int flags, char *dev_name, void *data)
 {
-	return get_sb_nodev(fs_type, flags, data, pipefs_fill_super);
+	return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
 }
 
 static struct file_system_type pipe_fs_type = {
 	name:		"pipefs",
 	get_sb:		pipefs_get_sb,
 	kill_sb:	kill_anon_super,
-	fs_flags:	FS_NOMOUNT,
 };
 
 static int __init init_pipe_fs(void)
diff -Nru a/fs/quota.c b/fs/quota.c
--- a/fs/quota.c	Sun Jun 16 19:31:41 2002
+++ b/fs/quota.c	Sun Jun 16 19:31:41 2002
@@ -105,14 +105,14 @@
 	int ret;
 	mode_t mode;
 	struct nameidata nd;
-	kdev_t dev;
+	struct block_device *bdev;
 	struct super_block *sb;
 
 	ret = user_path_walk(path, &nd);
 	if (ret)
 		goto out;
 
-	dev = nd.dentry->d_inode->i_rdev;
+	bdev = nd.dentry->d_inode->i_bdev;
 	mode = nd.dentry->d_inode->i_mode;
 	path_release(&nd);
 
@@ -120,7 +120,7 @@
 	if (!S_ISBLK(mode))
 		goto out;
 	ret = -ENODEV;
-	sb = get_super(dev);
+	sb = get_super(bdev);
 	if (!sb)
 		goto out;
 	return sb;
diff -Nru a/fs/quota_v1.c b/fs/quota_v1.c
--- a/fs/quota_v1.c	Sun Jun 16 19:31:41 2002
+++ b/fs/quota_v1.c	Sun Jun 16 19:31:41 2002
@@ -92,7 +92,7 @@
 					sizeof(struct v1_disk_dqblk), &offset);
 	if (ret != sizeof(struct v1_disk_dqblk)) {
 		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
-			kdevname(dquot->dq_sb->s_dev));
+			dquot->dq_sb->s_id);
 		if (ret >= 0)
 			ret = -EIO;
 		goto out;
@@ -145,7 +145,7 @@
 		return 1;	/* Probably not new format */
 	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
 		return 1;	/* Definitely not new format */
-	printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file. It probably contains newer quota format.\n", kdevname(sb->s_dev));
+	printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file. It probably contains newer quota format.\n", sb->s_id);
         return 0;		/* Seems like a new format file -> refuse it */
 }
 
diff -Nru a/fs/quota_v2.c b/fs/quota_v2.c
--- a/fs/quota_v2.c	Sun Jun 16 19:31:40 2002
+++ b/fs/quota_v2.c	Sun Jun 16 19:31:40 2002
@@ -60,7 +60,7 @@
 	set_fs(fs);
 	if (size != sizeof(struct v2_disk_dqinfo)) {
 		printk(KERN_WARNING "Can't read info structure on device %s.\n",
-			kdevname(f->f_dentry->d_sb->s_dev));
+			f->f_vfsmnt->mnt_sb->s_id);
 		return -1;
 	}
 	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
@@ -95,7 +95,7 @@
 	set_fs(fs);
 	if (size != sizeof(struct v2_disk_dqinfo)) {
 		printk(KERN_WARNING "Can't write info structure on device %s.\n",
-			kdevname(f->f_dentry->d_sb->s_dev));
+			f->f_vfsmnt->mnt_sb->s_id);
 		return -1;
 	}
 	return 0;
@@ -424,7 +424,7 @@
 	ret = filp->f_op->write(filp, (char *)&ddquot, sizeof(struct v2_disk_dqblk), &offset);
 	set_fs(fs);
 	if (ret != sizeof(struct v2_disk_dqblk)) {
-		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", kdevname(dquot->dq_sb->s_dev));
+		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
 		if (ret >= 0)
 			ret = -ENOSPC;
 	}
diff -Nru a/fs/ramfs/inode.c b/fs/ramfs/inode.c
--- a/fs/ramfs/inode.c	Sun Jun 16 19:31:40 2002
+++ b/fs/ramfs/inode.c	Sun Jun 16 19:31:40 2002
@@ -308,6 +308,12 @@
 	return get_sb_nodev(fs_type, flags, data, ramfs_fill_super);
 }
 
+static struct super_block *rootfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
+}
+
 static struct file_system_type ramfs_fs_type = {
 	name:		"ramfs",
 	get_sb:		ramfs_get_sb,
@@ -315,9 +321,8 @@
 };
 static struct file_system_type rootfs_fs_type = {
 	name:		"rootfs",
-	get_sb:		ramfs_get_sb,
+	get_sb:		rootfs_get_sb,
 	kill_sb:	kill_litter_super,
-	fs_flags:	FS_NOMOUNT,
 };
 
 static int __init init_ramfs_fs(void)
@@ -339,4 +344,3 @@
 }
 
 MODULE_LICENSE("GPL");
-
diff -Nru a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
--- a/fs/reiserfs/bitmap.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/bitmap.c	Sun Jun 16 19:31:40 2002
@@ -103,7 +103,7 @@
   if (nr >= sb_bmap_nr (rs)) {
 	  reiserfs_warning ("vs-4075: reiserfs_free_block: "
 			    "block %lu is out of range on %s\n", 
-			    block, s->s_id);
+			    block, reiserfs_bdevname (s));
 	  return;
   }
 
@@ -113,7 +113,7 @@
   if (!reiserfs_test_and_clear_le_bit (offset, apbh[nr]->b_data)) {
       reiserfs_warning ("vs-4080: reiserfs_free_block: "
 			"free_block (%s:%lu)[dev:blocknr]: bit already cleared\n", 
-	    s->s_id, block);
+			reiserfs_bdevname (s), block);
   }
   journal_mark_dirty (th, s, apbh[nr]);
 
@@ -139,10 +139,8 @@
 /* preallocated blocks don't need to be run through journal_mark_freed */
 void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, 
                           unsigned long block) {
-    struct super_block * s = th->t_super;
-
-    RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
-    RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");
+    RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");
+    RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");
     _reiserfs_free_block(th, block) ;
 }
 
@@ -670,10 +668,7 @@
   return ret;
 }
 
-//
-// a portion of this function, was derived from minix or ext2's
-// analog. You should be able to tell which portion by looking at the
-// ext2 code and comparing. 
+
 static void __discard_prealloc (struct reiserfs_transaction_handle * th,
 				struct reiserfs_inode_info *ei)
 {
diff -Nru a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
--- a/fs/reiserfs/dir.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/dir.c	Sun Jun 16 19:31:40 2002
@@ -24,9 +24,10 @@
 };
 
 int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
-  lock_kernel();
-  reiserfs_commit_for_inode(dentry->d_inode) ;
-  unlock_kernel() ;
+  struct inode *inode = dentry->d_inode;
+  reiserfs_write_lock(inode->i_sb);
+  reiserfs_commit_for_inode(inode) ;
+  reiserfs_write_unlock(inode->i_sb) ;
   return 0 ;
 }
 
@@ -50,7 +51,7 @@
     struct reiserfs_dir_entry de;
     int ret = 0;
 
-    lock_kernel();
+    reiserfs_write_lock(inode->i_sb);
 
     reiserfs_check_lock_depth("readdir") ;
 
@@ -109,7 +110,7 @@
 		if (!d_name[d_reclen - 1])
 		    d_reclen = strlen (d_name);
 	
-		if (d_reclen > REISERFS_MAX_NAME_LEN(inode->i_sb->s_blocksize)){
+		if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
 		    /* too big to send back to VFS */
 		    continue ;
 		}
@@ -181,13 +182,12 @@
 
 
  end:
-    // FIXME: ext2_readdir does not reset f_pos
     filp->f_pos = next_pos;
     pathrelse (&path_to_entry);
     reiserfs_check_path(&path_to_entry) ;
     UPDATE_ATIME(inode) ;
  out:
-    unlock_kernel();
+    reiserfs_write_unlock(inode->i_sb);
     return ret;
 }
 
diff -Nru a/fs/reiserfs/file.c b/fs/reiserfs/file.c
--- a/fs/reiserfs/file.c	Sun Jun 16 19:31:39 2002
+++ b/fs/reiserfs/file.c	Sun Jun 16 19:31:39 2002
@@ -39,7 +39,7 @@
 	return 0;
     }    
     
-    lock_kernel() ;
+    reiserfs_write_lock(inode->i_sb);
     down (&inode->i_sem); 
     journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
     reiserfs_update_inode_transaction(inode) ;
@@ -61,14 +61,12 @@
 	pop_journal_writer(windex) ;
     }
     up (&inode->i_sem); 
-    unlock_kernel() ;
+    reiserfs_write_unlock(inode->i_sb);
     return 0;
 }
 
 static void reiserfs_vfs_truncate_file(struct inode *inode) {
-    lock_kernel();
     reiserfs_truncate_file(inode, 1) ;
-    unlock_kernel();
 }
 
 /* Sync a reiserfs file. */
@@ -86,21 +84,21 @@
   struct inode * p_s_inode = p_s_dentry->d_inode;
   int n_err;
 
-  lock_kernel() ;
+  reiserfs_write_lock(p_s_inode->i_sb);
 
   if (!S_ISREG(p_s_inode->i_mode))
       BUG ();
 
   n_err = sync_mapping_buffers(p_s_inode->i_mapping) ;
   reiserfs_commit_for_inode(p_s_inode) ;
-  unlock_kernel() ;
+  reiserfs_write_unlock(p_s_inode->i_sb);
   return ( n_err < 0 ) ? -EIO : 0;
 }
 
 static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
     struct inode *inode = dentry->d_inode ;
     int error ;
-    lock_kernel();
+    reiserfs_write_lock(inode->i_sb);
     if (attr->ia_valid & ATTR_SIZE) {
 	/* version 2 items will be caught by the s_maxbytes check
 	** done for us in vmtruncate
@@ -138,7 +136,7 @@
         inode_setattr(inode, attr) ;
 
 out:
-    unlock_kernel();
+    reiserfs_write_unlock(inode->i_sb);
     return error ;
 }
 
diff -Nru a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
--- a/fs/reiserfs/fix_node.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/fix_node.c	Sun Jun 16 19:31:40 2002
@@ -2092,21 +2092,27 @@
   if (p_s_bh) {
     if (atomic_read (&(p_s_bh->b_count)) <= 0) {
 
-      reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): negative or zero reference counter for buffer %s[%d] (%b)\n", descr, level, p_s_bh);
+      reiserfs_panic (p_s_sb, "jmacd-1: tb_buffer_sanity_check(): negative or zero reference counter for buffer %s[%d] (%b)\n", descr, level, p_s_bh);
     }
 
     if ( ! buffer_uptodate (p_s_bh) ) {
-      reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): buffer is not up to date %s[%d] (%b)\n", descr, level, p_s_bh);
+      reiserfs_panic (p_s_sb, "jmacd-2: tb_buffer_sanity_check(): buffer is not up to date %s[%d] (%b)\n", descr, level, p_s_bh);
     }
 
     if ( ! B_IS_IN_TREE (p_s_bh) ) {
-      reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): buffer is not in tree %s[%d] (%b)\n", descr, level, p_s_bh);
+      reiserfs_panic (p_s_sb, "jmacd-3: tb_buffer_sanity_check(): buffer is not in tree %s[%d] (%b)\n", descr, level, p_s_bh);
     }
 
-    if (p_s_bh->b_bdev != p_s_sb->s_bdev || 
-	p_s_bh->b_size != p_s_sb->s_blocksize ||
-	p_s_bh->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) {
-      reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): check failed for buffer %s[%d] (%b)\n", descr, level, p_s_bh);
+    if (p_s_bh->b_bdev != p_s_sb->s_bdev) {
+	reiserfs_panic (p_s_sb, "jmacd-4: tb_buffer_sanity_check(): buffer has wrong device %s[%d] (%b)\n", descr, level, p_s_bh);
+    }
+
+    if (p_s_bh->b_size != p_s_sb->s_blocksize) {
+	reiserfs_panic (p_s_sb, "jmacd-5: tb_buffer_sanity_check(): buffer has wrong blocksize %s[%d] (%b)\n", descr, level, p_s_bh);
+    }
+
+    if (p_s_bh->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) {
+	reiserfs_panic (p_s_sb, "jmacd-6: tb_buffer_sanity_check(): buffer block number too high %s[%d] (%b)\n", descr, level, p_s_bh);
     }
   }
 }
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/inode.c	Sun Jun 16 19:31:40 2002
@@ -20,10 +20,7 @@
 
 static int reiserfs_get_block (struct inode * inode, sector_t block,
 			       struct buffer_head * bh_result, int create);
-//
-// initially this function was derived from minix or ext2's analog and
-// evolved as the prototype did
-//
+
 void reiserfs_delete_inode (struct inode * inode)
 {
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2; 
@@ -31,7 +28,7 @@
     struct reiserfs_transaction_handle th ;
 
   
-    lock_kernel() ; 
+    reiserfs_write_lock(inode->i_sb);
 
     /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
     if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
@@ -56,7 +53,7 @@
     }
     clear_inode (inode); /* note this must go after the journal_end to prevent deadlock */
     inode->i_blocks = 0;
-    unlock_kernel() ;
+    reiserfs_write_unlock(inode->i_sb);
 }
 
 static void _make_cpu_key (struct cpu_key * key, int version, __u32 dirid, __u32 objectid, 
@@ -112,8 +109,7 @@
 }
 
 //
-// FIXME: we might cache recently accessed indirect item (or at least
-// first 15 pointers just like ext2 does
+// FIXME: we might cache recently accessed indirect item
 
 // Ugh.  Not too eager for that....
 //  I cut the code until such time as I see a convincing argument (benchmark).
@@ -412,10 +408,10 @@
     if (!file_capable (inode, block))
 	return -EFBIG;
 
-    lock_kernel() ;
+    reiserfs_write_lock(inode->i_sb);
     /* do not read the direct item */
     _get_block_create_0 (inode, block, bh_result, 0) ;
-    unlock_kernel() ;
+    reiserfs_write_unlock(inode->i_sb);
     return 0;
 }
 
@@ -521,12 +517,7 @@
 #endif
     return reiserfs_new_unf_blocknrs (th, allocated_block_nr, tag);
 }
-//
-// initially this function was derived from ext2's analog and evolved
-// as the prototype did.  You'll need to look at the ext2 version to
-// determine which parts are derivative, if any, understanding that
-// there are only so many ways to code to a given interface.
-//
+
 int reiserfs_get_block (struct inode * inode, sector_t block,
 			struct buffer_head * bh_result, int create)
 {
@@ -554,17 +545,17 @@
     loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ;
 
 				/* bad.... */
-    lock_kernel() ;
+    reiserfs_write_lock(inode->i_sb);
     th.t_trans_id = 0 ;
     version = get_inode_item_key_version (inode);
 
     if (block < 0) {
-	unlock_kernel();
+	reiserfs_write_unlock(inode->i_sb);
 	return -EIO;
     }
 
     if (!file_capable (inode, block)) {
-	unlock_kernel() ;
+	reiserfs_write_unlock(inode->i_sb);
 	return -EFBIG;
     }
 
@@ -576,7 +567,7 @@
 	/* find number of block-th logical block of the file */
 	ret = _get_block_create_0 (inode, block, bh_result, 
 	                           create | GET_BLOCK_READ_DIRECT) ;
-	unlock_kernel() ;
+	reiserfs_write_unlock(inode->i_sb);
 	return ret;
     }
 
@@ -667,7 +658,7 @@
 	if (transaction_started)
 	    journal_end(&th, inode->i_sb, jbegin_count) ;
 
-	unlock_kernel() ;
+	reiserfs_write_unlock(inode->i_sb);
 	 
 	/* the item was found, so new blocks were not added to the file
 	** there is no need to make sure the inode is updated with this 
@@ -866,7 +857,6 @@
 
 
     retval = 0;
-    reiserfs_check_path(&path) ;
 
  failure:
     if (transaction_started) {
@@ -874,7 +864,7 @@
       journal_end(&th, inode->i_sb, jbegin_count) ;
     }
     pop_journal_writer(windex) ;
-    unlock_kernel() ;
+    reiserfs_write_unlock(inode->i_sb);
     reiserfs_check_path(&path) ;
     return retval;
 }
@@ -1353,10 +1343,6 @@
 }
 
 
-//
-// initially this function was derived from minix or ext2's analog and
-// evolved as the prototype did
-//
 /* looks for stat data, then copies fields to it, marks the buffer
    containing stat data as dirty */
 /* reiserfs inodes are never really dirty, since the dirty inode call
@@ -1379,11 +1365,11 @@
     ** ignored because the altered inode has already been logged.
     */
     if (do_sync && !(current->flags & PF_MEMALLOC)) {
-	lock_kernel() ;
+	reiserfs_write_lock(inode->i_sb);
 	journal_begin(&th, inode->i_sb, jbegin_count) ;
 	reiserfs_update_sd (&th, inode);
 	journal_end_sync(&th, inode->i_sb, jbegin_count) ;
-	unlock_kernel() ;
+	reiserfs_write_unlock(inode->i_sb);
     }
 }
 
@@ -1725,7 +1711,8 @@
 	** call prepare_write
 	*/
 	reiserfs_warning("clm-6000: error reading block %lu on dev %s\n",
-	                  bh->b_blocknr, p_s_inode->i_sb->s_id) ;
+			 bh->b_blocknr,
+			 reiserfs_bdevname (p_s_inode->i_sb)) ;
 	error = -EIO ;
 	goto unlock ;
     }
@@ -1750,7 +1737,6 @@
 void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
     struct reiserfs_transaction_handle th ;
     int windex ;
-
     /* we want the offset for the first byte after the end of the file */
     unsigned long offset = p_s_inode->i_size & (PAGE_CACHE_SIZE - 1) ;
     unsigned blocksize = p_s_inode->i_sb->s_blocksize ;
@@ -1759,6 +1745,8 @@
     int error ;
     struct buffer_head *bh = NULL ;
 
+    reiserfs_write_lock(p_s_inode->i_sb);
+
     if (p_s_inode->i_size > 0) {
         if ((error = grab_tail_page(p_s_inode, &page, &bh))) {
 	    // -ENOENT means we truncated past the end of the file, 
@@ -1812,7 +1800,7 @@
 	page_cache_release(page) ;
     }
 
-    return ;
+    reiserfs_write_unlock(p_s_inode->i_sb);
 }
 
 static int map_block_for_writepage(struct inode *inode, 
@@ -1836,7 +1824,7 @@
 
     kmap(bh_result->b_page) ;
 start_over:
-    lock_kernel() ;
+    reiserfs_write_lock(inode->i_sb);
     journal_begin(&th, inode->i_sb, jbegin_count) ;
     reiserfs_update_inode_transaction(inode) ;
 
@@ -1894,7 +1882,7 @@
 	    goto research ;
 	}
     } else {
-        reiserfs_warning("clm-6003: bad item inode %lu, device %s\n", inode->i_ino, inode->i_sb->s_id) ;
+        reiserfs_warning("clm-6003: bad item inode %lu, device %s\n", inode->i_ino, reiserfs_bdevname (inode->i_sb)) ;
         retval = -EIO ;
 	goto out ;
     }
@@ -1903,7 +1891,7 @@
 out:
     pathrelse(&path) ;
     journal_end(&th, inode->i_sb, jbegin_count) ;
-    unlock_kernel() ;
+    reiserfs_write_unlock(inode->i_sb);
 
     /* this is where we fill in holes in the file. */
     if (use_get_block) {
@@ -2033,18 +2021,13 @@
     return error ;
 }
 
-//
-// this is exactly what 2.3.99-pre9's ext2_readpage is
-//
+
 static int reiserfs_readpage (struct file *f, struct page * page)
 {
     return block_read_full_page (page, reiserfs_get_block);
 }
 
 
-//
-// modified from ext2_writepage is
-//
 static int reiserfs_writepage (struct page * page)
 {
     struct inode *inode = page->mapping->host ;
@@ -2053,9 +2036,6 @@
 }
 
 
-//
-// from ext2_prepare_write, but modified
-//
 int reiserfs_prepare_write(struct file *f, struct page *page, 
 			   unsigned from, unsigned to) {
     struct inode *inode = page->mapping->host ;
@@ -2065,9 +2045,6 @@
 }
 
 
-//
-// this is exactly what 2.3.99-pre9's ext2_bmap is
-//
 static int reiserfs_aop_bmap(struct address_space *as, long block) {
   return generic_block_bmap(as, block, reiserfs_bmap) ;
 }
@@ -2086,13 +2063,13 @@
     */
     if (pos > inode->i_size) {
 	struct reiserfs_transaction_handle th ;
-	lock_kernel() ;
+	reiserfs_write_lock(inode->i_sb);
 	journal_begin(&th, inode->i_sb, 1) ;
 	reiserfs_update_inode_transaction(inode) ;
 	inode->i_size = pos ;
 	reiserfs_update_sd(&th, inode) ;
 	journal_end(&th, inode->i_sb, 1) ;
-	unlock_kernel() ;
+	reiserfs_write_unlock(inode->i_sb);
     }
  
     ret = generic_commit_write(f, page, from, to) ;
@@ -2101,9 +2078,9 @@
     ** for any packed tails the file might have had
     */
     if (f && (f->f_flags & O_SYNC)) {
-	lock_kernel() ;
+	reiserfs_write_lock(inode->i_sb);
  	reiserfs_commit_for_inode(inode) ;
-	unlock_kernel();
+	reiserfs_write_unlock(inode->i_sb);
     }
     return ret ;
 }
diff -Nru a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
--- a/fs/reiserfs/ioctl.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/ioctl.c	Sun Jun 16 19:31:40 2002
@@ -49,7 +49,7 @@
     if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
         return 0 ;
     }
-    lock_kernel();
+    reiserfs_write_lock(inode->i_sb);
 
     /* we need to make sure nobody is changing the file size beneath
     ** us
@@ -88,6 +88,6 @@
 
 out:
     up(&inode->i_sem) ;
-    unlock_kernel();    
+    reiserfs_write_unlock(inode->i_sb);
     return retval;
 }
diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c	Sun Jun 16 19:31:39 2002
+++ b/fs/reiserfs/journal.c	Sun Jun 16 19:31:39 2002
@@ -99,21 +99,6 @@
 static int release_journal_dev( struct super_block *super,
 				struct reiserfs_journal *journal );
 
-static inline struct buffer_head *journ_get_hash_table(struct super_block *s, int block)
-{
-	return __get_hash_table(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize);
-}
- 
-static inline struct buffer_head *journ_getblk(struct super_block *s, int block)
-{
-	return __getblk(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize);
-}
-
-static inline struct buffer_head *journ_bread(struct super_block *s, int block)
-{
-	return __bread(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize);
-}
-
 static void init_journal_hash(struct super_block *p_s_sb) {
   memset(SB_JOURNAL(p_s_sb)->j_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
 }
@@ -704,7 +689,7 @@
   count = 0 ;
   for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && i < (jl->j_len + 1) ; i++) {  /* everything but commit_bh */
     bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start+i) %  SB_ONDISK_JOURNAL_SIZE(s);
-    tbh = journ_get_hash_table(s, bn) ;
+    tbh = journal_get_hash_table(s, bn) ;
 
 /* kill this sanity check */
 if (count > (orig_commit_left + 2)) {
@@ -733,7 +718,7 @@
     for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && 
                  i < (jl->j_len + 1) ; i++) {  /* everything but commit_bh */
       bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s) ;
-      tbh = journ_get_hash_table(s, bn) ;
+      tbh = journal_get_hash_table(s, bn) ;
 
       wait_on_buffer(tbh) ;
       if (!buffer_uptodate(tbh)) {
@@ -1426,7 +1411,7 @@
     offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
 
     /* ok, we have a journal description block, lets see if the transaction was valid */
-    c_bh = journ_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+    c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
 		 ((offset + le32_to_cpu(desc->j_len) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
     if (!c_bh)
       return 0 ;
@@ -1481,7 +1466,7 @@
   unsigned long trans_offset ;
   int i;
 
-  d_bh = journ_bread(p_s_sb, cur_dblock) ;
+  d_bh = journal_bread(p_s_sb, cur_dblock) ;
   if (!d_bh)
     return 1 ;
   desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
@@ -1505,7 +1490,7 @@
     brelse(d_bh) ;
     return 1 ;
   }
-  c_bh = journ_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+  c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
 		((trans_offset + le32_to_cpu(desc->j_len) + 1) % 
 		 SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
   if (!c_bh) {
@@ -1536,7 +1521,7 @@
   }
   /* get all the buffer heads */
   for(i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
-    log_blocks[i] =  journ_getblk(p_s_sb,  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + (trans_offset + 1 + i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+    log_blocks[i] =  journal_getblk(p_s_sb,  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + (trans_offset + 1 + i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
     if (i < JOURNAL_TRANS_HALF) {
       real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ;
     } else {
@@ -1606,16 +1591,13 @@
   return 0 ;
 }
 
-/*
-** read and replay the log
-** on a clean unmount, the journal header's next unflushed pointer will be to an invalid
-** transaction.  This tests that before finding all the transactions in the log, whic makes normal mount times fast.
-**
-** After a crash, this starts with the next unflushed transaction, and replays until it finds one too old, or invalid.
-**
-** On exit, it sets things up so the first transaction will work correctly.
-*/
-struct buffer_head * reiserfs_breada (struct super_block *sb, int block, 
+/* This function reads blocks starting from block and to max_block of bufsize
+   size (but no more than BUFNR blocks at a time). This proved to improve
+   mounting speed on self-rebuilding raid5 arrays at least.
+   Right now it is only used from journal code. But later we might use it
+   from other places.
+   Note: Do not use journal_getblk/sb_getblk functions here! */
+struct buffer_head * reiserfs_breada (struct block_device *dev, int block, int bufsize,
 			    unsigned int max_block)
 {
 	struct buffer_head * bhlist[BUFNR];
@@ -1623,7 +1605,7 @@
 	struct buffer_head * bh;
 	int i, j;
 	
-	bh = sb_getblk (sb, block);
+	bh = __getblk (dev, block, bufsize );
 	if (buffer_uptodate (bh))
 		return (bh);   
 		
@@ -1633,7 +1615,7 @@
 	bhlist[0] = bh;
 	j = 1;
 	for (i = 1; i < blocks; i++) {
-		bh = sb_getblk (sb, block + i);
+		bh = __getblk (dev, block + i, bufsize);
 		if (buffer_uptodate (bh)) {
 			brelse (bh);
 			break;
@@ -1650,6 +1632,16 @@
 	brelse (bh);
 	return NULL;
 }
+
+/*
+** read and replay the log
+** on a clean unmount, the journal header's next unflushed pointer will be to an invalid
+** transaction.  This tests that before finding all the transactions in the log, whic makes normal mount times fast.
+**
+** After a crash, this starts with the next unflushed transaction, and replays until it finds one too old, or invalid.
+**
+** On exit, it sets things up so the first transaction will work correctly.
+*/
 static int journal_read(struct super_block *p_s_sb) {
   struct reiserfs_journal_desc *desc ;
   unsigned long oldest_trans_id = 0;
@@ -1667,14 +1659,14 @@
 
   cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
   printk("reiserfs: checking transaction log (%s) for (%s)\n",
-	 __bdevname(SB_JOURNAL_DEV(p_s_sb)), p_s_sb->s_id) ;
+	 bdevname(SB_JOURNAL(p_s_sb)->j_dev_bd), reiserfs_bdevname(p_s_sb));
   start = CURRENT_TIME ;
 
   /* step 1, read in the journal header block.  Check the transaction it says 
   ** is the first unflushed, and if that transaction is not valid, 
   ** replay is done
   */
-  SB_JOURNAL(p_s_sb)->j_header_bh = journ_bread(p_s_sb,
+  SB_JOURNAL(p_s_sb)->j_header_bh = journal_bread(p_s_sb,
 					   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
 					   SB_ONDISK_JOURNAL_SIZE(p_s_sb));
   if (!SB_JOURNAL(p_s_sb)->j_header_bh) {
@@ -1698,7 +1690,7 @@
     ** there is nothing more we can do, and it makes no sense to read 
     ** through the whole log.
     */
-    d_bh = journ_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ;
+    d_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ;
     ret = journal_transaction_is_valid(p_s_sb, d_bh, NULL, NULL) ;
     if (!ret) {
       continue_replay = 0 ;
@@ -1707,7 +1699,7 @@
     goto start_log_replay;
   }
 
-  if (continue_replay && is_read_only(p_s_sb->s_dev)) {
+  if (continue_replay && bdev_read_only(p_s_sb->s_bdev)) {
     printk("clm-2076: device is readonly, unable to replay log\n") ;
     return -1 ;
   }
@@ -1716,7 +1708,9 @@
   ** all the valid transactions, and pick out the oldest.
   */
   while(continue_replay && cur_dblock < (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb))) {
-    d_bh = reiserfs_breada(p_s_sb, cur_dblock,
+    /* Note that it is required for blocksize of primary fs device and journal
+       device to be the same */
+    d_bh = reiserfs_breada(SB_JOURNAL(p_s_sb)->j_dev_bd, cur_dblock, p_s_sb->s_blocksize,
 			   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
     ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ;
     if (ret == 1) {
@@ -1796,7 +1790,7 @@
     printk("reiserfs: replayed %d transactions in %lu seconds\n", replay_count, 
 	    CURRENT_TIME - start) ;
   }
-  if (!is_read_only(p_s_sb->s_dev) && 
+  if (!bdev_read_only(p_s_sb->s_bdev) && 
        _update_journal_header_block(p_s_sb, SB_JOURNAL(p_s_sb)->j_start, 
                                    SB_JOURNAL(p_s_sb)->j_last_flush_trans_id))
   {
@@ -1925,13 +1919,20 @@
     
     result = 0;
 	
-    if( journal -> j_dev_bd != NULL ) {
-	result = blkdev_put( journal -> j_dev_bd, BDEV_FS );
-	journal -> j_dev_bd = NULL;
-    }
+
     if( journal -> j_dev_file != NULL ) {
+	/*
+	 * journal block device was taken via filp_open
+	 */
 	result = filp_close( journal -> j_dev_file, NULL );
 	journal -> j_dev_file = NULL;
+	journal -> j_dev_bd = NULL;
+    } else if( journal -> j_dev_bd != NULL ) {
+	/*
+	 * journal block device was taken via bdget and blkdev_get
+	 */
+	result = blkdev_put( journal -> j_dev_bd, BDEV_FS );
+	journal -> j_dev_bd = NULL;
     }
     if( result != 0 ) {
 	reiserfs_warning("sh-457: release_journal_dev: Cannot release journal device: %i", result );
@@ -1944,18 +1945,17 @@
 			     const char *jdev_name )
 {
 	int result;
-	kdev_t jdev;
+	dev_t jdev;
 
 	result = 0;
 
 	journal -> j_dev_bd = NULL;
 	journal -> j_dev_file = NULL;
-	jdev = SB_JOURNAL_DEV( super ) = 
-      		SB_ONDISK_JOURNAL_DEVICE( super ) ?
-		to_kdev_t(SB_ONDISK_JOURNAL_DEVICE( super )) : super -> s_dev;	
+	jdev = SB_ONDISK_JOURNAL_DEVICE( super ) ?
+		SB_ONDISK_JOURNAL_DEVICE( super ) : super->s_dev;	
 	/* there is no "jdev" option and journal is on separate device */
 	if( ( !jdev_name || !jdev_name[ 0 ] ) ) {
-		journal -> j_dev_bd = bdget( kdev_t_to_nr( jdev ) );
+		journal -> j_dev_bd = bdget(jdev);
 		if( journal -> j_dev_bd )
 			result = blkdev_get( journal -> j_dev_bd, 
 					     FMODE_READ | FMODE_WRITE, 0, 
@@ -1964,8 +1964,11 @@
 			result = -ENOMEM;
 		if( result != 0 )
 			printk( "sh-458: journal_init_dev: cannot init journal device\n '%s': %i", 
-				kdevname( jdev ), result );
+				kdevname( to_kdev_t(jdev) ), result );
 
+		else if (jdev != super->s_dev) {
+			set_blocksize(journal->j_dev_bd, super->s_blocksize);
+		}
 		return result;
 	}
 
@@ -1981,15 +1984,11 @@
 		} else if( jdev_inode -> i_bdev == NULL ) {
 			printk( "journal_init_dev: bdev unintialized for '%s'", jdev_name );
 			result = -ENOMEM;
-		} else if( ( result = blkdev_get( jdev_inode -> i_bdev, 
-						  FMODE_READ | FMODE_WRITE,
-						  0, BDEV_FS ) ) != 0 ) {
-			printk( "journal_init_dev: Cannot load device '%s': %i", jdev_name,
-			     result );
-		} else
+		} else  {
 			/* ok */
-			SB_JOURNAL_DEV( super ) = 
-				to_kdev_t( jdev_inode -> i_bdev -> bd_dev );
+			jdev = jdev_inode -> i_bdev -> bd_dev;
+			set_blocksize(journal->j_dev_bd, super->s_blocksize);
+		}
 	} else {
 		result = PTR_ERR( journal -> j_dev_file );
 		journal -> j_dev_file = NULL;
@@ -1998,7 +1997,7 @@
 	if( result != 0 ) {
 		release_journal_dev( super, journal );
 	}
-	printk( "journal_init_dev: journal device: %s", kdevname( SB_JOURNAL_DEV( super ) ) );
+	printk( "journal_init_dev: journal device: %s", kdevname(to_kdev_t(jdev)) );
 	return result;
 }
 
@@ -2041,7 +2040,7 @@
      rs = SB_DISK_SUPER_BLOCK(p_s_sb);
      
      /* read journal header */
-     bhjh = journ_bread(p_s_sb,
+     bhjh = journal_bread(p_s_sb,
 		   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb));
      if (!bhjh) {
 	 printk("sh-459: unable to read  journal header\n") ;
@@ -2052,15 +2051,10 @@
      
      /* make sure that journal matches to the super block */
      if (is_reiserfs_jr(rs) && (jh->jh_journal.jp_journal_magic != sb_jp_journal_magic(rs))) {
-	 char jname[ 32 ];
-	 char fname[ 32 ];
-	 
-	 strcpy( jname, kdevname( SB_JOURNAL_DEV(p_s_sb) ) );
-	 strcpy( fname, p_s_sb->s_id);
 	 printk("sh-460: journal header magic %x (device %s) does not match "
 		"to magic found in super block %x (device %s)\n",
-		jh->jh_journal.jp_journal_magic, jname,
-		sb_jp_journal_magic(rs), fname);
+		jh->jh_journal.jp_journal_magic, bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd ),
+		sb_jp_journal_magic(rs), reiserfs_bdevname (p_s_sb));
 	 brelse (bhjh);
 	 release_journal_dev(p_s_sb, journal);
 	 return 1 ;
@@ -2111,7 +2105,7 @@
   printk ("Reiserfs journal params: device %s, size %u, "
 	  "journal first block %u, max trans len %u, max batch %u, "
 	  "max commit age %u, max trans age %u\n",
-	  kdevname( SB_JOURNAL_DEV(p_s_sb) ),
+	  bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd ),
 	  SB_ONDISK_JOURNAL_SIZE(p_s_sb),
 	  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
 	  SB_JOURNAL_TRANS_MAX(p_s_sb),
@@ -2985,7 +2979,7 @@
   
   rs = SB_DISK_SUPER_BLOCK(p_s_sb) ;
   /* setup description block */
-  d_bh = journ_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ; 
+  d_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ; 
   set_buffer_uptodate(d_bh) ;
   desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ;
   memset(desc, 0, sizeof(struct reiserfs_journal_desc)) ;
@@ -2993,7 +2987,7 @@
   desc->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ;
 
   /* setup commit block.  Don't write (keep it clean too) this one until after everyone else is written */
-  c_bh =  journ_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
+  c_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
 		 ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
   commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
   memset(commit, 0, sizeof(struct reiserfs_journal_commit)) ;
@@ -3084,7 +3078,7 @@
     /* copy all the real blocks into log area.  dirty log blocks */
     if (test_bit(BH_JDirty, &cn->bh->b_state)) {
       struct buffer_head *tmp_bh ;
-      tmp_bh =  journ_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
+      tmp_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
 		       ((cur_write_start + jindex) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
       set_buffer_uptodate(tmp_bh) ;
       memcpy(tmp_bh->b_data, cn->bh->b_data, cn->bh->b_size) ;  
diff -Nru a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
--- a/fs/reiserfs/namei.c	Sun Jun 16 19:31:39 2002
+++ b/fs/reiserfs/namei.c	Sun Jun 16 19:31:39 2002
@@ -195,13 +195,6 @@
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_match (struct reiserfs_dir_entry * de, 
 			   const char * name, int namelen)
 {
@@ -284,13 +277,6 @@
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND
 // FIXME: should add something like IOERROR
 static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen, 
@@ -300,7 +286,7 @@
     int retval;
 
 
-    if (namelen > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize))
+    if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
 	return NAME_NOT_FOUND;
 
     /* we will search for this key in the tree */
@@ -330,13 +316,6 @@
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry)
 {
     int retval;
@@ -344,21 +323,21 @@
     struct reiserfs_dir_entry de;
     INITIALIZE_PATH (path_to_entry);
 
-    if (dentry->d_name.len > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize))
+    if (REISERFS_MAX_NAME (dir->i_sb->s_blocksize) < dentry->d_name.len)
 	return ERR_PTR(-ENAMETOOLONG);
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     de.de_gen_number_bit_string = 0;
     retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
     pathrelse (&path_to_entry);
     if (retval == NAME_FOUND) {
 	inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
 	if (!inode || IS_ERR(inode)) {
-	    unlock_kernel();
+	    reiserfs_write_unlock(dir->i_sb);
 	    return ERR_PTR(-EACCES);
         }
     }
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     if ( retval == IO_ERROR ) {
 	return ERR_PTR(-EIO);
     }
@@ -390,15 +369,15 @@
     }
     de.de_gen_number_bit_string = 0;
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     retval = reiserfs_find_entry (dir, "..", 2, &path_to_entry, &de);
     pathrelse (&path_to_entry);
     if (retval != NAME_FOUND) {
-	unlock_kernel();
+	reiserfs_write_unlock(dir->i_sb);
 	return ERR_PTR(-ENOENT);
     }
     inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
 
     if (!inode || IS_ERR(inode)) {
 	return ERR_PTR(-EACCES);
@@ -412,14 +391,6 @@
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
-
 /* add entry to the directory (entry can be hidden). 
 
 insert definition of when hidden directories are used here -Hans
@@ -447,7 +418,7 @@
     if (!namelen)
 	return -EINVAL;
 
-    if (namelen > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize))
+    if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
 	return -ENAMETOOLONG;
 
     /* each entry has unique key. compose it */
@@ -463,7 +434,7 @@
     } else
 	buffer = small_buf;
 
-    paste_size = (old_format_only (dir->i_sb)) ? (DEH_SIZE + namelen) : buflen;
+    paste_size = (get_inode_sd_version (dir) == STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen;
 
     /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */
     deh = (struct reiserfs_de_head *)buffer;
@@ -587,13 +558,6 @@
     return 0 ;
 }
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
 {
     int retval;
@@ -601,15 +565,14 @@
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
     struct reiserfs_transaction_handle th ;
 
-    inode = new_inode(dir->i_sb) ;
-    if (!inode) {
+    if (!(inode = new_inode(dir->i_sb))) {
 	return -ENOMEM ;
     }
     retval = new_inode_init(inode, dir, mode);
     if (retval)
         return retval;
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     journal_begin(&th, dir->i_sb, jbegin_count) ;
     th.t_caller = "create" ;
     retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
@@ -637,18 +600,11 @@
     journal_end(&th, dir->i_sb, jbegin_count) ;
 
 out_failed:
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return retval;
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
     int retval;
@@ -656,15 +612,14 @@
     struct reiserfs_transaction_handle th ;
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
 
-    inode = new_inode(dir->i_sb) ;
-    if (!inode) {
+    if (!(inode = new_inode(dir->i_sb))) {
 	return -ENOMEM ;
     }
     retval = new_inode_init(inode, dir, mode);
     if (retval)
         return retval;
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     journal_begin(&th, dir->i_sb, jbegin_count) ;
 
     retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
@@ -694,18 +649,11 @@
     journal_end(&th, dir->i_sb, jbegin_count) ;
 
 out_failed:
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return retval;
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
 {
     int retval;
@@ -714,15 +662,14 @@
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
 
     mode = S_IFDIR | mode;
-    inode = new_inode(dir->i_sb) ;
-    if (!inode) {
+    if (!(inode = new_inode(dir->i_sb))) {
 	return -ENOMEM ;
     }
     retval = new_inode_init(inode, dir, mode);
     if (retval)
         return retval;
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     journal_begin(&th, dir->i_sb, jbegin_count) ;
 
     /* inc the link count now, so another writer doesn't overflow it while
@@ -762,7 +709,7 @@
     d_instantiate(dentry, inode);
     journal_end(&th, dir->i_sb, jbegin_count) ;
 out_failed:
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return retval;
 }
 
@@ -779,14 +726,6 @@
     return 1 ;
 }
 
-
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
 {
     int retval;
@@ -801,7 +740,7 @@
     /* we will be doing 2 balancings and update 2 stat data */
     jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     journal_begin(&th, dir->i_sb, jbegin_count) ;
     windex = push_journal_writer("reiserfs_rmdir") ;
 
@@ -855,7 +794,7 @@
     pop_journal_writer(windex) ;
     journal_end(&th, dir->i_sb, jbegin_count) ;
     reiserfs_check_path(&path) ;
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return 0;
 	
  end_rmdir:
@@ -865,18 +804,10 @@
     pathrelse (&path);
     pop_journal_writer(windex) ;
     journal_end(&th, dir->i_sb, jbegin_count) ;
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return retval;	
 }
 
-
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
 {
     int retval;
@@ -893,7 +824,7 @@
        two stat datas */
     jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     journal_begin(&th, dir->i_sb, jbegin_count) ;
     windex = push_journal_writer("reiserfs_unlink") ;
 	
@@ -918,7 +849,7 @@
   
     if (!inode->i_nlink) {
 	printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
-	       inode->i_sb->s_id, inode->i_ino, inode->i_nlink);
+	       reiserfs_bdevname (inode->i_sb), inode->i_ino, inode->i_nlink);
 	inode->i_nlink = 1;
     }
 
@@ -942,7 +873,7 @@
     pop_journal_writer(windex) ;
     journal_end(&th, dir->i_sb, jbegin_count) ;
     reiserfs_check_path(&path) ;
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return 0;
 
  end_unlink:
@@ -950,19 +881,12 @@
     pop_journal_writer(windex) ;
     journal_end(&th, dir->i_sb, jbegin_count) ;
     reiserfs_check_path(&path) ;
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return retval;
 }
 
-
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
-static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname)
+static int reiserfs_symlink (struct inode * parent_dir, 
+                            struct dentry * dentry, const char * symname)
 {
     int retval;
     struct inode * inode;
@@ -972,24 +896,23 @@
     int mode = S_IFLNK | S_IRWXUGO;
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
 
-    inode = new_inode(dir->i_sb) ;
-    if (!inode) {
+    if (!(inode = new_inode(parent_dir->i_sb))) {
 	return -ENOMEM ;
     }
-    retval = new_inode_init(inode, dir, mode);
+    retval = new_inode_init(inode, parent_dir, mode);
     if (retval) {
         return retval;
     }
 
-    lock_kernel();
+    reiserfs_write_lock(parent_dir->i_sb);
     item_len = ROUND_UP (strlen (symname));
-    if (item_len > MAX_DIRECT_ITEM_LEN (dir->i_sb->s_blocksize)) {
+    if (item_len > MAX_DIRECT_ITEM_LEN (parent_dir->i_sb->s_blocksize)) {
 	retval =  -ENAMETOOLONG;
 	drop_new_inode(inode);
 	goto out_failed;
     }
   
-    name = reiserfs_kmalloc (item_len, GFP_NOFS, dir->i_sb);
+    name = reiserfs_kmalloc (item_len, GFP_NOFS, parent_dir->i_sb);
     if (!name) {
 	drop_new_inode(inode);
 	retval =  -ENOMEM;
@@ -998,17 +921,17 @@
     memcpy (name, symname, strlen (symname));
     padd_item (name, item_len, strlen (symname));
 
-    journal_begin(&th, dir->i_sb, jbegin_count) ;
+    journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
 
-    retval = reiserfs_new_inode (&th, dir, mode, name, strlen (symname), 
+    retval = reiserfs_new_inode (&th, parent_dir, mode, name, strlen (symname), 
                                  dentry, inode);
-    reiserfs_kfree (name, item_len, dir->i_sb);
+    reiserfs_kfree (name, item_len, parent_dir->i_sb);
     if (retval) { /* reiserfs_new_inode iputs for us */
 	goto out_failed;
     }
 
     reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(dir) ;
+    reiserfs_update_inode_transaction(parent_dir) ;
 
     inode->i_op = &page_symlink_inode_operations;
     inode->i_mapping->a_ops = &reiserfs_address_space_operations;
@@ -1017,31 +940,23 @@
     //
     //reiserfs_update_sd (&th, inode, READ_BLOCKS);
 
-    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 
-				 inode, 1/*visible*/);
+    retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name, 
+                                 dentry->d_name.len, inode, 1/*visible*/);
     if (retval) {
 	inode->i_nlink--;
 	reiserfs_update_sd (&th, inode);
-	journal_end(&th, dir->i_sb, jbegin_count) ;
+	journal_end(&th, parent_dir->i_sb, jbegin_count) ;
 	iput (inode);
 	goto out_failed;
     }
 
     d_instantiate(dentry, inode);
-    journal_end(&th, dir->i_sb, jbegin_count) ;
+    journal_end(&th, parent_dir->i_sb, jbegin_count) ;
 out_failed:
-    unlock_kernel();
+    reiserfs_write_unlock(parent_dir->i_sb);
     return retval;
 }
 
-
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
 {
     int retval;
@@ -1049,11 +964,12 @@
     int windex ;
     struct reiserfs_transaction_handle th ;
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    time_t ctime;
 
-    lock_kernel();
+    reiserfs_write_lock(dir->i_sb);
     if (inode->i_nlink >= REISERFS_LINK_MAX) {
 	//FIXME: sd_nlink is 32 bit for new files
-	unlock_kernel();
+	reiserfs_write_unlock(dir->i_sb);
 	return -EMLINK;
     }
 
@@ -1070,19 +986,20 @@
     if (retval) {
 	pop_journal_writer(windex) ;
 	journal_end(&th, dir->i_sb, jbegin_count) ;
-	unlock_kernel();
+	reiserfs_write_unlock(dir->i_sb);
 	return retval;
     }
 
     inode->i_nlink++;
-    inode->i_ctime = CURRENT_TIME;
+    ctime = CURRENT_TIME;
+    inode->i_ctime = ctime;
     reiserfs_update_sd (&th, inode);
 
     atomic_inc(&inode->i_count) ;
     d_instantiate(dentry, inode);
     pop_journal_writer(windex) ;
     journal_end(&th, dir->i_sb, jbegin_count) ;
-    unlock_kernel();
+    reiserfs_write_unlock(dir->i_sb);
     return 0;
 }
 
@@ -1129,14 +1046,6 @@
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
-
 /* 
  * process, that is going to call fix_nodes/do_balance must hold only
  * one path. If it holds 2 or more, it can get into endless waiting in
@@ -1151,10 +1060,12 @@
     INITIALIZE_PATH (dot_dot_entry_path);
     struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ;
     struct reiserfs_dir_entry old_de, new_de, dot_dot_de;
-    struct inode * old_inode, * new_inode;
+    struct inode * old_inode, * new_dentry_inode;
     int windex ;
     struct reiserfs_transaction_handle th ;
     int jbegin_count ; 
+    umode_t old_inode_mode;
+    time_t ctime;
 
 
     /* two balancings: old name removal, new name insertion or "save" link,
@@ -1163,33 +1074,34 @@
     jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;
 
     old_inode = old_dentry->d_inode;
-    new_inode = new_dentry->d_inode;
+    new_dentry_inode = new_dentry->d_inode;
 
     // make sure, that oldname still exists and points to an object we
     // are going to rename
     old_de.de_gen_number_bit_string = 0;
-    lock_kernel();
+    reiserfs_write_lock(old_dir->i_sb);
     retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len,
 				  &old_entry_path, &old_de);
     pathrelse (&old_entry_path);
     if (retval == IO_ERROR) {
-	unlock_kernel();
+	reiserfs_write_unlock(old_dir->i_sb);
 	return -EIO;
     }
 
     if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {
-	unlock_kernel();
+	reiserfs_write_unlock(old_dir->i_sb);
 	return -ENOENT;
     }
 
-    if (S_ISDIR(old_inode->i_mode)) {
+    old_inode_mode = old_inode->i_mode;
+    if (S_ISDIR(old_inode_mode)) {
 	// make sure, that directory being renamed has correct ".." 
 	// and that its new parent directory has not too many links
 	// already
 
-	if (new_inode) {
-	    if (!reiserfs_empty_dir(new_inode)) {
-		unlock_kernel();
+	if (new_dentry_inode) {
+	    if (!reiserfs_empty_dir(new_dentry_inode)) {
+		reiserfs_write_unlock(old_dir->i_sb);
 		return -ENOTEMPTY;
 	    }
 	}
@@ -1201,13 +1113,13 @@
 	retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de);
 	pathrelse (&dot_dot_entry_path);
 	if (retval != NAME_FOUND) {
-	    unlock_kernel();
+	    reiserfs_write_unlock(old_dir->i_sb);
 	    return -EIO;
 	}
 
 	/* inode number of .. must equal old_dir->i_ino */
 	if (dot_dot_de.de_objectid != old_dir->i_ino) {
-	    unlock_kernel();
+	    reiserfs_write_unlock(old_dir->i_sb);
 	    return -EIO;
 	}
     }
@@ -1219,16 +1131,14 @@
     retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len, 
 				 old_inode, 0);
     if (retval == -EEXIST) {
-	// FIXME: is it possible, that new_inode == 0 here? If yes, it
-	// is not clear how does ext2 handle that
-	if (!new_inode) {
+	if (!new_dentry_inode) {
 	    reiserfs_panic (old_dir->i_sb,
 			    "vs-7050: new entry is found, new inode == 0\n");
 	}
     } else if (retval) {
 	pop_journal_writer(windex) ;
 	journal_end(&th, old_dir->i_sb, jbegin_count) ;
-	unlock_kernel();
+	reiserfs_write_unlock(old_dir->i_sb);
 	return retval;
     }
 
@@ -1240,8 +1150,8 @@
     */
     reiserfs_update_inode_transaction(old_inode) ;
 
-    if (new_inode) 
-	reiserfs_update_inode_transaction(new_inode) ;
+    if (new_dentry_inode) 
+	reiserfs_update_inode_transaction(new_dentry_inode) ;
 
     while (1) {
 	// look for old name using corresponding entry key (found by reiserfs_find_entry)
@@ -1288,18 +1198,18 @@
 	if (item_moved(&new_entry_ih, &new_entry_path) ||
 	    !entry_points_to_object(new_dentry->d_name.name, 
 	                            new_dentry->d_name.len,
-				    &new_de, new_inode) ||
+				    &new_de, new_dentry_inode) ||
 	    item_moved(&old_entry_ih, &old_entry_path) || 
 	    !entry_points_to_object (old_dentry->d_name.name, 
 	                             old_dentry->d_name.len,
 				     &old_de, old_inode)) {
 	    reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
 	    reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
-	    if (S_ISDIR(old_inode->i_mode))
+	    if (S_ISDIR(old_inode_mode))
 		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
 	    continue;
 	}
-	if (S_ISDIR(old_inode->i_mode)) {
+	if (S_ISDIR(old_inode_mode)) {
 	    if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
 		!entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) {
 		reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
@@ -1309,7 +1219,7 @@
 	    }
 	}
 
-	RFALSE( S_ISDIR(old_inode->i_mode) && 
+	RFALSE( S_ISDIR(old_inode_mode) && 
 		 !reiserfs_buffer_prepared(dot_dot_de.de_bh), "" );
 
 	break;
@@ -1327,22 +1237,23 @@
     old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
     new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
 
-    if (new_inode) {
+    if (new_dentry_inode) {
 	// adjust link number of the victim
-	if (S_ISDIR(new_inode->i_mode)) {
-	    new_inode->i_nlink  = 0;
+	if (S_ISDIR(new_dentry_inode->i_mode)) {
+	    new_dentry_inode->i_nlink  = 0;
 	} else {
-	    new_inode->i_nlink--;
+	    new_dentry_inode->i_nlink--;
 	}
-	new_inode->i_ctime = CURRENT_TIME;
+	ctime = CURRENT_TIME;
+	new_dentry_inode->i_ctime = ctime;
     }
 
-    if (S_ISDIR(old_inode->i_mode)) {
+    if (S_ISDIR(old_inode_mode)) {
 	// adjust ".." of renamed directory 
 	set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir));
 	journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh);
 	
-        if (!new_inode)
+        if (!new_dentry_inode)
 	    /* there (in new_dir) was no directory, so it got new link
 	       (".."  of renamed directory) */
 	    INC_DIR_INODE_NLINK(new_dir);
@@ -1367,15 +1278,15 @@
     reiserfs_update_sd (&th, old_dir);
     reiserfs_update_sd (&th, new_dir);
 
-    if (new_inode) {
-	if (new_inode->i_nlink == 0)
-	    add_save_link (&th, new_inode, 0/* not truncate */);
-	reiserfs_update_sd (&th, new_inode);
+    if (new_dentry_inode) {
+	if (new_dentry_inode->i_nlink == 0)
+	    add_save_link (&th, new_dentry_inode, 0/* not truncate */);
+	reiserfs_update_sd (&th, new_dentry_inode);
     }
 
     pop_journal_writer(windex) ;
     journal_end(&th, old_dir->i_sb, jbegin_count) ;
-    unlock_kernel();
+    reiserfs_write_unlock(old_dir->i_sb);
     return 0;
 }
 
diff -Nru a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
--- a/fs/reiserfs/prints.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/prints.c	Sun Jun 16 19:31:40 2002
@@ -337,7 +337,7 @@
 
   /* this is not actually called, but makes reiserfs_panic() "noreturn" */
   panic ("REISERFS: panic (device %s): %s\n",
-	 sb ? sb->s_id : "sb == 0", error_buf);
+	 reiserfs_bdevname (sb), error_buf);
 }
 
 
@@ -490,6 +490,7 @@
 
     return "unknown";
 }
+
 /* return 1 if this is not super block */
 static int print_super_block (struct buffer_head * bh)
 {
@@ -509,8 +510,8 @@
 	return 1;
     }
 
-    printk ("%s\'s super block in block %ld\n======================\n",
-            bdevname (bh->b_bdev), bh->b_blocknr);
+    printk ("%s\'s super block is in block %ld\n", bdevname (bh->b_bdev), 
+            bh->b_blocknr);
     printk ("Reiserfs version %s\n", version );
     printk ("Block count %u\n", sb_block_count(rs));
     printk ("Blocksize %d\n", sb_blocksize(rs));
diff -Nru a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
--- a/fs/reiserfs/procfs.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/procfs.c	Sun Jun 16 19:31:40 2002
@@ -29,14 +29,14 @@
  *
  */
 
-static struct super_block *procinfo_prologue( kdev_t dev )
+static struct super_block *procinfo_prologue(dev_t dev)
 {
 	struct super_block *result;
 
 	/* get super-block by device */
-	result = get_super( dev );
+	result = user_get_super(dev);
 	if( result != NULL ) {
-		if( !reiserfs_is_super( result ) ) {
+		if( !is_reiserfs_super( result ) ) {
 			printk( KERN_DEBUG "reiserfs: procfs-52: "
 				"non-reiserfs super found\n" );
 			drop_super( result );
@@ -78,7 +78,7 @@
 	struct super_block *sb;
 	char *format;
     
-	sb = procinfo_prologue( to_kdev_t((int)data) );
+	sb = procinfo_prologue((dev_t)data);
 	if( sb == NULL )
 		return -ENOENT;
 	if ( REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6) ) {
@@ -136,7 +136,7 @@
 	struct reiserfs_sb_info *r;
 	int len = 0;
     
-	sb = procinfo_prologue( to_kdev_t((int)data) );
+	sb = procinfo_prologue((dev_t)data);
 	if( sb == NULL )
 		return -ENOENT;
 	r = REISERFS_SB(sb);
@@ -216,7 +216,7 @@
 	int len = 0;
 	int level;
 	
-	sb = procinfo_prologue( to_kdev_t((int)data) );
+	sb = procinfo_prologue((dev_t)data);
 	if( sb == NULL )
 		return -ENOENT;
 	r = REISERFS_SB(sb);
@@ -295,7 +295,7 @@
 	struct reiserfs_sb_info *r;
 	int len = 0;
     
-	sb = procinfo_prologue( to_kdev_t((int)data) );
+	sb = procinfo_prologue((dev_t)data);
 	if( sb == NULL )
 		return -ENOENT;
 	r = REISERFS_SB(sb);
@@ -336,7 +336,7 @@
 	int hash_code;
 	int len = 0;
     
-	sb = procinfo_prologue( to_kdev_t((int)data) );
+	sb = procinfo_prologue((dev_t)data);
 	if( sb == NULL )
 		return -ENOENT;
 	sb_info = REISERFS_SB(sb);
@@ -393,7 +393,7 @@
 	int len = 0;
 	int exact;
     
-	sb = procinfo_prologue( to_kdev_t((int)data) );
+	sb = procinfo_prologue((dev_t)data);
 	if( sb == NULL )
 		return -ENOENT;
 	sb_info = REISERFS_SB(sb);
@@ -445,7 +445,7 @@
 	struct journal_params *jp;	
 	int len = 0;
     
-	sb = procinfo_prologue( to_kdev_t((int)data) );
+	sb = procinfo_prologue((dev_t)data);
 	if( sb == NULL )
 		return -ENOENT;
 	r = REISERFS_SB(sb);
@@ -500,7 +500,7 @@
 			"prepare_retry: \t%12lu\n",
 
                         DJP( jp_journal_1st_block ),
-                        DJP( jp_journal_dev ) == 0 ? "none" : __bdevname(to_kdev_t(DJP( jp_journal_dev ))),
+                        bdevname(SB_JOURNAL(sb)->j_dev_bd),
                         DJP( jp_journal_dev ),
                         DJP( jp_journal_size ),
                         DJP( jp_journal_trans_max ),
@@ -556,13 +556,13 @@
 int reiserfs_proc_info_init( struct super_block *sb )
 {
 	spin_lock_init( & __PINFO( sb ).lock );
-	REISERFS_SB(sb)->procdir = proc_mkdir(sb->s_id, proc_info_root);
+	REISERFS_SB(sb)->procdir = proc_mkdir(reiserfs_bdevname (sb), proc_info_root);
 	if( REISERFS_SB(sb)->procdir ) {
 		REISERFS_SB(sb)->procdir -> owner = THIS_MODULE;
 		return 0;
 	}
 	reiserfs_warning( "reiserfs: cannot create /proc/%s/%s\n",
-			  proc_info_root_name, sb->s_id );
+			  proc_info_root_name, reiserfs_bdevname (sb) );
 	return 1;
 }
 
@@ -573,7 +573,7 @@
 	__PINFO( sb ).exiting = 1;
 	spin_unlock( & __PINFO( sb ).lock );
 	if ( proc_info_root ) {
-		remove_proc_entry( sb->s_id, proc_info_root );
+		remove_proc_entry( reiserfs_bdevname (sb), proc_info_root );
 		REISERFS_SB(sb)->procdir = NULL;
 	}
 	return 0;
@@ -588,7 +588,7 @@
 {
 	return ( REISERFS_SB(sb)->procdir ) ? create_proc_read_entry
 		( name, 0, REISERFS_SB(sb)->procdir, func, 
-		  ( void * ) kdev_t_to_nr( sb -> s_dev ) ) : NULL;
+		  ( void * ) sb->s_bdev->bd_dev) : NULL;
 }
 
 void reiserfs_proc_unregister( struct super_block *sb, const char *name )
diff -Nru a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
--- a/fs/reiserfs/stree.c	Sun Jun 16 19:31:41 2002
+++ b/fs/reiserfs/stree.c	Sun Jun 16 19:31:41 2002
@@ -1715,13 +1715,13 @@
 	/* Cut or delete file item. */
 	n_deleted = reiserfs_cut_from_item(th, &s_search_path, &s_item_key, p_s_inode,  page, n_new_file_size);
 	if (n_deleted < 0) {
-	    reiserfs_warning ("vs-5665: reiserfs_truncate_file: cut_from_item failed");
+	    reiserfs_warning ("vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
 	    reiserfs_check_path(&s_search_path) ;
 	    return;
 	}
 
 	RFALSE( n_deleted > n_file_size,
-		"PAP-5670: reiserfs_truncate_file returns too big number: deleted %d, file_size %lu, item_key %K",
+		"PAP-5670: reiserfs_cut_from_item: too many bytes deleted: deleted %d, file_size %lu, item_key %K",
 		n_deleted, n_file_size, &s_item_key);
 
 	/* Change key to search the last file item. */
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/super.c	Sun Jun 16 19:31:40 2002
@@ -24,6 +24,8 @@
 #define REISERFS_OLD_BLOCKSIZE 4096
 #define REISERFS_SUPER_MAGIC_STRING_OFFSET_NJ 20
 
+static struct file_system_type reiserfs_fs_type;
+
 const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
 const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
 const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING;
@@ -55,41 +57,32 @@
 	  is_reiserfs_jr (rs));
 }
 
+int is_reiserfs_super (struct super_block *s)
+{
+	return s -> s_type == & reiserfs_fs_type ;
+}
+
 static int reiserfs_remount (struct super_block * s, int * flags, char * data);
 static int reiserfs_statfs (struct super_block * s, struct statfs * buf);
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static void reiserfs_write_super (struct super_block * s)
 {
 
   int dirty = 0 ;
-  lock_kernel() ;
+  reiserfs_write_lock(s);
   if (!(s->s_flags & MS_RDONLY)) {
     dirty = flush_old_commits(s, 1) ;
   }
   s->s_dirt = dirty;
-  unlock_kernel() ;
+  reiserfs_write_unlock(s);
 }
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static void reiserfs_write_super_lockfs (struct super_block * s)
 {
 
   int dirty = 0 ;
   struct reiserfs_transaction_handle th ;
-  lock_kernel() ;
+  reiserfs_write_lock(s);
   if (!(s->s_flags & MS_RDONLY)) {
     journal_begin(&th, s, 1) ;
     reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -98,7 +91,7 @@
     journal_end(&th, s, 1) ;
   }
   s->s_dirt = dirty;
-  unlock_kernel() ;
+  reiserfs_write_unlock(s);
 }
 
 void reiserfs_unlockfs(struct super_block *s) {
@@ -362,13 +355,6 @@
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static void reiserfs_put_super (struct super_block * s)
 {
   int i;
@@ -469,7 +455,7 @@
 	                  inode->i_ino) ;
         return ;
     }
-    lock_kernel() ;
+    reiserfs_write_lock(inode->i_sb);
 
     /* this is really only used for atime updates, so they don't have
     ** to be included in O_SYNC or fsync
@@ -477,7 +463,7 @@
     journal_begin(&th, inode->i_sb, 1) ;
     reiserfs_update_sd (&th, inode);
     journal_end(&th, inode->i_sb, 1) ;
-    unlock_kernel() ;
+    reiserfs_write_unlock(inode->i_sb);
 }
 
 struct super_operations reiserfs_sops = 
@@ -503,100 +489,190 @@
   get_dentry: reiserfs_get_dentry,
 } ;
 
-/* this was (ext2)parse_options */
-static int parse_options (char * options, unsigned long * mount_options, unsigned long * blocks, char **jdev_name)
-{
-    char * this_char;
+/* this struct is used in reiserfs_getopt () for containing the value for those
+   mount options that have values rather than being toggles. */
+typedef struct {
     char * value;
-  
+    int bitmask; /* bit which is to be set in mount_options bitmask when this
+                    value is found, 0 is no bits are to be set */
+} arg_desc_t;
+
+
+/* this struct is used in reiserfs_getopt() for describing the set of reiserfs
+   mount options */
+typedef struct {
+    char * option_name;
+    int arg_required; /* 0 if argument is not required, not 0 otherwise */
+    const arg_desc_t * values; /* list of values accepted by an option */
+    int bitmask;  /* bit which is to be set in mount_options bitmask when this
+		     option is selected, 0 is not bits are to be set */
+} opt_desc_t;
+
+/* possible values for "-o block-allocator=" and bits which are to be set in
+   s_mount_opt of reiserfs specific part of in-core super block */
+const arg_desc_t balloc[] = {
+    {"noborder", REISERFS_NO_BORDER},
+    {"no_unhashed_relocation", REISERFS_NO_UNHASHED_RELOCATION},
+    {"hashed_relocation", REISERFS_HASHED_RELOCATION},
+    {"test4", REISERFS_TEST4},
+    {NULL, -1}
+};
+
+
+/* proceed only one option from a list *cur - string containing of mount options
+   opts - array of options which are accepted
+   opt_arg - if option is found and requires an argument and if it is specifed
+   in the input - pointer to the argument is stored here
+   bit_flags - if option requires to set a certain bit - it is set here
+   return -1 if unknown option is found, opt->arg_required otherwise */
+static int reiserfs_getopt (char ** cur, opt_desc_t * opts, char ** opt_arg,
+			    unsigned long * bit_flags)
+{
+    char * p;
+    /* foo=bar, 
+       ^   ^  ^
+       |   |  +-- option_end
+       |   +-- arg_start
+       +-- option_start
+    */
+    const opt_desc_t * opt;
+    const arg_desc_t * arg;
+    
+    
+    p = *cur;
+    
+    /* assume argument cannot contain commas */
+    *cur = strchr (p, ',');
+    if (*cur) {
+	*(*cur) = '\0';
+	(*cur) ++;
+    }
+    
+    /* for every option in the list */
+    for (opt = opts; opt->option_name; opt ++) {
+	if (!strncmp (p, opt->option_name, strlen (opt->option_name))) {
+	    if (bit_flags && opt->bitmask != -1)
+		set_bit (opt->bitmask, bit_flags);
+	    break;
+	}
+    }
+    if (!opt->option_name) {
+	printk ("reiserfs_getopt: unknown option \"%s\"\n", p);
+	return -1;
+    }
+    
+    p += strlen (opt->option_name);
+    switch (*p) {
+    case '=':
+	if (!opt->arg_required) {
+	    printk ("reiserfs_getopt: the option \"%s\" does not require an argument\n",
+		    opt->option_name);
+	    return -1;
+	}
+	break;
+	
+    case 0:
+	if (opt->arg_required) {
+	    printk ("reiserfs_getopt: the option \"%s\" requires an argument\n", opt->option_name);
+	    return -1;
+	}
+	break;
+    default:
+	printk ("reiserfs_getopt: head of option \"%s\" is only correct\n", opt->option_name);
+	return -1;
+    }
+	
+    /* move to the argument, or to next option if argument is not required */
+    p ++;
+    
+    if ( opt->arg_required && !strlen (p) ) {
+	/* this catches "option=," */
+	printk ("reiserfs_getopt: empty argument for \"%s\"\n", opt->option_name);
+	return -1;
+    }
+    
+    if (!opt->values) {
+	/* *opt_arg contains pointer to argument */
+	*opt_arg = p;
+	return opt->arg_required;
+    }
+    
+    /* values possible for this option are listed in opt->values */
+    for (arg = opt->values; arg->value; arg ++) {
+	if (!strcmp (p, arg->value)) {
+	    if (bit_flags && arg->bitmask != -1 )
+		set_bit (arg->bitmask, bit_flags);
+	    return opt->arg_required;
+	}
+    }
+    
+    printk ("reiserfs_getopt: bad value \"%s\" for option \"%s\"\n", p, opt->option_name);
+    return -1;
+}
+
+
+/* returns 0 if something is wrong in option string, 1 - otherwise */
+static int reiserfs_parse_options (char * options, /* string given via mount's -o */
+				   unsigned long * mount_options,
+				   /* after the parsing phase, contains the
+				      collection of bitflags defining what
+				      mount options were selected. */
+				   unsigned long * blocks, /* strtol-ed from NNN of resize=NNN */
+				   char ** jdev_name)
+{
+    int c;
+    char * arg = NULL;
+    char * pos;
+    opt_desc_t opts[] = {
+		{"notail", 0, 0, NOTAIL},
+		{"conv", 0, 0, REISERFS_CONVERT}, 
+		{"attrs", 0, 0, REISERFS_ATTRS}, 
+		{"nolog", 0, 0, -1},
+		{"replayonly", 0, 0, REPLAYONLY},
+		
+		{"block-allocator", 'a', balloc, -1}, 
+		
+		{"resize", 'r', 0, -1},
+		{"jdev", 'j', 0, -1},
+		{NULL, 0, 0, -1}
+    };
+	
     *blocks = 0;
-    if (!options)
+    if (!options || !*options)
 	/* use default configuration: create tails, journaling on, no
-           conversion to newest format */
+	   conversion to newest format */
 	return 1;
-    while ((this_char = strsep (&options, ",")) != NULL) {
-	if (!*this_char)
-	    continue;
-	if ((value = strchr (this_char, '=')) != NULL)
-	    *value++ = 0;
-	if (!strcmp (this_char, "notail")) {
-	    set_bit (NOTAIL, mount_options);
-	} else if (!strcmp (this_char, "conv")) {
-	    // if this is set, we update super block such that
-	    // the partition will not be mounable by 3.5.x anymore
-	    set_bit (REISERFS_CONVERT, mount_options);
-	} else if (!strcmp (this_char, "noborder")) {
-				/* this is used for benchmarking
-                                   experimental variations, it is not
-                                   intended for users to use, only for
-                                   developers who want to casually
-                                   hack in something to test */
-	    set_bit (REISERFS_NO_BORDER, mount_options);
-	} else if (!strcmp (this_char, "no_unhashed_relocation")) {
-	    set_bit (REISERFS_NO_UNHASHED_RELOCATION, mount_options);
-	} else if (!strcmp (this_char, "hashed_relocation")) {
-	    set_bit (REISERFS_HASHED_RELOCATION, mount_options);
-	} else if (!strcmp (this_char, "test4")) {
-	    set_bit (REISERFS_TEST4, mount_options);
-	} else if (!strcmp (this_char, "nolog")) {
-	    reiserfs_warning("reiserfs: nolog mount option not supported yet\n");
-	} else if (!strcmp (this_char, "replayonly")) {
-	    set_bit (REPLAYONLY, mount_options);
-	} else if (!strcmp (this_char, "resize")) {
-	    if (value && *value){
-		*blocks = simple_strtoul (value, &value, 0);
-	    } else {
-	  	printk("reiserfs: resize option requires a value\n");
+    
+    for (pos = options; pos; ) {
+	c = reiserfs_getopt (&pos, opts, &arg, mount_options);
+	if (c == -1)
+	    /* wrong option is given */
+	    return 0;
+	
+	if (c == 'r') {
+	    char * p;
+	    
+	    p = 0;
+	    /* "resize=NNN" */
+	    *blocks = simple_strtoul (arg, &p, 0);
+	    if (*p != '\0') {
+		/* NNN does not look like a number */
+		printk ("reiserfs_parse_options: bad value %s\n", arg);
 		return 0;
 	    }
-	} else if (!strcmp (this_char, "hash")) {
-	    if (value && *value) {
-		/* if they specify any hash option, we force detection
-		** to make sure they aren't using the wrong hash
-		*/
-	        if (!strcmp(value, "rupasov")) {
-		    set_bit (FORCE_RUPASOV_HASH, mount_options);
-		    set_bit (FORCE_HASH_DETECT, mount_options);
-		} else if (!strcmp(value, "tea")) {
-		    set_bit (FORCE_TEA_HASH, mount_options);
-		    set_bit (FORCE_HASH_DETECT, mount_options);
-		} else if (!strcmp(value, "r5")) {
-		    set_bit (FORCE_R5_HASH, mount_options);
-		    set_bit (FORCE_HASH_DETECT, mount_options);
-		} else if (!strcmp(value, "detect")) {
-		    set_bit (FORCE_HASH_DETECT, mount_options);
-		} else {
-		    printk("reiserfs: invalid hash function specified\n") ;
-		    return 0 ;
-		}
-	    } else {
-	  	printk("reiserfs: hash option requires a value\n");
-		return 0 ;
-	    }
-	} else if (!strcmp (this_char, "jdev")) {
-	    if (value && *value && jdev_name) {
-		    *jdev_name = value;
-	    } else {
-		    printk("reiserfs: jdev option requires a value\n");
-		    return 0 ;
+	}
+
+	if (c == 'j') {
+	    if (arg && *arg && jdev_name) {
+		*jdev_name = arg;
 	    }
-	} else {
-	    printk ("reiserfs: Unrecognized mount option %s\n", this_char);
-	    return 0;
 	}
     }
+    
     return 1;
 }
 
-
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
-static int reiserfs_remount (struct super_block * s, int * flags, char * data)
+static int reiserfs_remount (struct super_block * s, int * mount_flags, char * arg)
 {
   struct reiserfs_super_block * rs;
   struct reiserfs_transaction_handle th ;
@@ -604,21 +680,21 @@
   unsigned long mount_options;
 
   rs = SB_DISK_SUPER_BLOCK (s);
-  if (!parse_options(data, &mount_options, &blocks, NULL))
-  	return 0;
 
+  if (!reiserfs_parse_options(arg, &mount_options, &blocks, NULL))
+    return -EINVAL;
+  
   if(blocks) {
-      int rc = reiserfs_resize(s, blocks);
-      if (rc != 0)
-	  return rc;
+    int rc = reiserfs_resize(s, blocks);
+    if (rc != 0)
+      return rc;
   }
 
-  if ((unsigned long)(*flags & MS_RDONLY) == (s->s_flags & MS_RDONLY)) {
-    /* there is nothing to do to remount read-only fs as read-only fs */
-    return 0;
-  }
-  
-  if (*flags & MS_RDONLY) {
+  if (*mount_flags & MS_RDONLY) {
+    /* remount rean-only */
+    if (s->s_flags & MS_RDONLY)
+      /* it is read-only already */
+      return 0;
     /* try to remount file system with read-only permissions */
     if (sb_umount_state(rs) == REISERFS_VALID_FS || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
       return 0;
@@ -634,7 +710,7 @@
     REISERFS_SB(s)->s_mount_state = sb_umount_state(rs) ;
     s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
     journal_begin(&th, s, 10) ;
-
+    
     /* Mount a partition which is read-only, read-write */
     reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
     REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
@@ -649,7 +725,7 @@
   SB_JOURNAL(s)->j_must_wait = 1 ;
   journal_end(&th, s, 10) ;
 
-  if (!( *flags & MS_RDONLY ) )
+  if (!( *mount_flags & MS_RDONLY ) )
     finish_unfinished( s );
 
   return 0;
@@ -658,14 +734,14 @@
 
 static int read_bitmaps (struct super_block * s)
 {
-    int i, bmp;
+    int i, bmap_nr;
 
     SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * SB_BMAP_NR(s), GFP_NOFS, s);
     if (SB_AP_BITMAP (s) == 0)
 	return 1;
-    for (i = 0, bmp = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
-	 i < SB_BMAP_NR(s); i++, bmp = s->s_blocksize * 8 * i) {
-	SB_AP_BITMAP (s)[i] = sb_getblk(s, bmp);
+    for (i = 0, bmap_nr = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
+	 i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
+	SB_AP_BITMAP (s)[i] = sb_getblk(s, bmap_nr);
 	if (!buffer_uptodate(SB_AP_BITMAP(s)[i]))
 	    ll_rw_block(READ, 1, SB_AP_BITMAP(s) + i);
     }
@@ -735,7 +811,7 @@
     if (!bh) {
       printk ("sh-2006: read_super_block: "
               "bread failed (dev %s, block %lu, size %lu)\n",
-              s->s_id, offset / s->s_blocksize, s->s_blocksize);
+              reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
       return 1;
     }
  
@@ -755,7 +831,7 @@
     if (!bh) {
 	printk("sh-2007: read_super_block: "
                 "bread failed (dev %s, block %lu, size %lu)\n",
-                s->s_id, offset / s->s_blocksize, s->s_blocksize);
+                reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
 	return 1;
     }
     
@@ -763,7 +839,7 @@
     if (sb_blocksize(rs) != s->s_blocksize) {
 	printk ("sh-2011: read_super_block: "
 		"can't find a reiserfs filesystem on (dev %s, block %lu, size %lu)\n",
-		s->s_id, bh->b_blocknr, s->s_blocksize);
+		reiserfs_bdevname (s), bh->b_blocknr, s->s_blocksize);
 	brelse (bh);
 	return 1;
     }
@@ -772,7 +848,7 @@
        brelse(bh) ;
        printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
               "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
-              "get newer reiserfsprogs package\n", s->s_id);
+              "get newer reiserfsprogs package\n", reiserfs_bdevname (s));
        return 1;
     }
 
@@ -884,7 +960,7 @@
 	     ( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) {
 	    reiserfs_warning("reiserfs: Unable to automatically detect hash"
 		"function for device %s\n"
-		"please mount with -o hash={tea,rupasov,r5}\n", s->s_id);
+		"please mount with -o hash={tea,rupasov,r5}\n", reiserfs_bdevname (s));
 	    hash = UNSET_HASH;
 	    break;
 	}
@@ -896,7 +972,7 @@
 	    hash = R5_HASH;
 	else {
 	    reiserfs_warning("reiserfs: Unrecognised hash function for "
-			     "device %s\n", s->s_id);
+			     "device %s\n", reiserfs_bdevname (s));
 	    hash = UNSET_HASH;
 	}
     } while (0);
@@ -990,14 +1066,7 @@
     return 0;
 }
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
-static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
+static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
 {
     struct inode *root_inode;
     int j;
@@ -1009,21 +1078,24 @@
     struct reiserfs_super_block * rs;
     char *jdev_name;
     struct reiserfs_sb_info *sbi;
+    int errval = -EINVAL;
 
     sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
-    if (!sbi)
-	return -ENOMEM;
+    if (!sbi) {
+	errval = -ENOMEM;
+	goto error;
+    }
     s->u.generic_sbp = sbi;
     memset (sbi, 0, sizeof (struct reiserfs_sb_info));
 
     jdev_name = NULL;
-    if (parse_options ((char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name) == 0) {
-	return -EINVAL;
+    if (reiserfs_parse_options ((char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name) == 0) {
+	goto error;
     }
 
     if (blocks) {
-  	printk("reserfs: resize option for remount only\n");
-	return -EINVAL;
+  	printk("jmacd-7: reiserfs_fill_super: resize option for remount only\n");
+	goto error;
     }	
 
     /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
@@ -1031,14 +1103,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_fill_super: can not find reiserfs on %s\n", s->s_id);
+      printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", reiserfs_bdevname (s));
       goto error;    
     }
     sbi->s_mount_state = SB_REISERFS_STATE(s);
     sbi->s_mount_state = REISERFS_VALID_FS ;
 
     if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { 
-	printk ("reiserfs_fill_super: unable to read bitmap\n");
+	printk ("jmacd-8: reiserfs_fill_super: unable to read bitmap\n");
 	goto error;
     }
 #ifdef CONFIG_REISERFS_CHECK
@@ -1056,14 +1128,14 @@
 			 */
     }
     if (reread_meta_blocks(s)) {
-	printk("reiserfs_fill_super: unable to reread meta blocks after journal init\n") ;
+	printk("jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init\n") ;
 	goto error ;
     }
 
     if (replay_only (s))
 	goto error;
 
-    if (is_read_only(s->s_dev) && !(s->s_flags & MS_RDONLY)) {
+    if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
         printk("clm-7000: Detected readonly device, marking FS readonly\n") ;
 	s->s_flags |= MS_RDONLY ;
     }
@@ -1071,7 +1143,7 @@
     args.dirid = REISERFS_ROOT_PARENT_OBJECTID ;
     root_inode = iget5_locked (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
     if (!root_inode) {
-	printk ("reiserfs_fill_super: get root inode failed\n");
+	printk ("jmacd-10: reiserfs_fill_super: get root inode failed\n");
 	goto error;
     }
 
@@ -1155,7 +1227,7 @@
     reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
     init_waitqueue_head (&(sbi->s_wait));
 
-    return 0;
+    return (0);
 
  error:
     if (jinit_done) { /* kill the commit thread, free journal ram */
@@ -1172,96 +1244,85 @@
     if (SB_BUFFER_WITH_SB (s))
 	brelse(SB_BUFFER_WITH_SB (s));
 
-    kfree(sbi);
-    s->u.generic_sbp = NULL;
+    if (sbi != NULL) {
+	kfree(sbi);
+    }
 
-    return -EINVAL;
+    s->u.generic_sbp = NULL;
+    return errval;
 }
 
 
-//
-// a portion of this function, particularly the VFS interface portion,
-// was derived from minix or ext2's analog and evolved as the
-// prototype did. You should be able to tell which portion by looking
-// at the ext2 code and comparing. It's subfunctions contain no code
-// used as a template unless they are so labeled.
-//
 static int reiserfs_statfs (struct super_block * s, struct statfs * buf)
 {
   struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
   
-				/* changed to accomodate gcc folks.*/
-  buf->f_type    =  REISERFS_SUPER_MAGIC;
-  buf->f_bsize   = s->s_blocksize;
-  buf->f_blocks  = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
+  buf->f_namelen = (REISERFS_MAX_NAME (s->s_blocksize));
+  buf->f_ffree   = -1;
+  buf->f_files   = -1;
   buf->f_bfree   = sb_free_blocks(rs);
   buf->f_bavail  = buf->f_bfree;
-  buf->f_files   = -1;
-  buf->f_ffree   = -1;
-  buf->f_namelen = (REISERFS_MAX_NAME_LEN (s->s_blocksize));
+  buf->f_blocks  = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
+  buf->f_bsize   = s->s_blocksize;
+  /* changed to accomodate gcc folks.*/
+  buf->f_type    =  REISERFS_SUPER_MAGIC;
   return 0;
 }
 
-static struct super_block *reiserfs_get_sb(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
+static struct super_block*
+get_super_block (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);
+	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,
-	kill_sb:	kill_block_super,
-	fs_flags:	FS_REQUIRES_DEV,
-};
-
-int reiserfs_is_super(struct super_block *s)
+static int __init
+init_reiserfs_fs ( void )
 {
-	return s->s_type == &reiserfs_fs_type;
-}
+	int ret;
 
-//
-// this is exactly what 2.3.99-pre9's init_ext2_fs is
-//
-static int __init init_reiserfs_fs (void)
-{
-	int err = init_inodecache();
-	if (err)
-		goto out1;
-	reiserfs_proc_info_global_init();
-	reiserfs_proc_register_global( "version", 
-				       reiserfs_global_version_in_proc );
-        err = register_filesystem(&reiserfs_fs_type);
-	if (err)
-		goto out;
-	return 0;
-out:
-	reiserfs_proc_unregister_global( "version" );
-	reiserfs_proc_info_global_done();
-	destroy_inodecache();
-out1:
-	return err;
-}
+	if ((ret = init_inodecache ())) {
+		return ret;
+	}
 
+	reiserfs_proc_info_global_init ();
+	reiserfs_proc_register_global ("version", reiserfs_global_version_in_proc);
 
-MODULE_DESCRIPTION("ReiserFS journaled filesystem");
-MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");
-MODULE_LICENSE("GPL");
+        ret = register_filesystem (& reiserfs_fs_type);
 
-//
-// this is exactly what 2.3.99-pre9's init_ext2_fs is
-//
-static void __exit exit_reiserfs_fs(void)
-{
-	reiserfs_proc_unregister_global( "version" );
-	reiserfs_proc_info_global_done();
-        unregister_filesystem(&reiserfs_fs_type);
-	destroy_inodecache();
+	if (ret == 0) {
+		return 0;
+	}
+
+	reiserfs_proc_unregister_global ("version");
+	reiserfs_proc_info_global_done ();
+	destroy_inodecache ();
+
+	return ret;
 }
 
-module_init(init_reiserfs_fs) ;
-module_exit(exit_reiserfs_fs) ;
+static void __exit
+exit_reiserfs_fs ( void )
+{
+	reiserfs_proc_unregister_global ("version");
+	reiserfs_proc_info_global_done ();
+        unregister_filesystem (& reiserfs_fs_type);
+	destroy_inodecache ();
+}
 
+static struct file_system_type reiserfs_fs_type = {
+	owner: THIS_MODULE,
+	name: "reiserfs",
+	get_sb: get_super_block,
+	kill_sb: kill_block_super,
+	fs_flags: FS_REQUIRES_DEV,
+};
 
+MODULE_DESCRIPTION ("ReiserFS journaled filesystem");
+MODULE_AUTHOR      ("Hans Reiser <reiser@namesys.com>");
+MODULE_LICENSE     ("GPL");
 
+module_init (init_reiserfs_fs);
+module_exit (exit_reiserfs_fs);
diff -Nru a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
--- a/fs/reiserfs/tail_conversion.c	Sun Jun 16 19:31:40 2002
+++ b/fs/reiserfs/tail_conversion.c	Sun Jun 16 19:31:40 2002
@@ -214,7 +214,7 @@
     copy_item_head (&s_ih, PATH_PITEM_HEAD(p_s_path));
 
     tail_len = (n_new_file_size & (n_block_size - 1));
-    if (!old_format_only (p_s_sb))
+    if (get_inode_sd_version (p_s_inode) == STAT_DATA_V2)
 	round_tail_len = ROUND_UP (tail_len);
     else
 	round_tail_len = tail_len;
diff -Nru a/fs/smbfs/smb_debug.h b/fs/smbfs/smb_debug.h
--- a/fs/smbfs/smb_debug.h	Sun Jun 16 19:31:39 2002
+++ b/fs/smbfs/smb_debug.h	Sun Jun 16 19:31:39 2002
@@ -7,20 +7,20 @@
 	(dentry)->d_parent->d_name.name,(dentry)->d_name.name
 
 /*
- * safety checks that should never happen ??? 
+ * safety checks that should never happen ???
  * these are normally enabled.
  */
 #ifdef SMBFS_PARANOIA
-#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " x)
+# define PARANOIA(f, a...) printk(KERN_NOTICE "%s: " f, __FUNCTION__ , ## a)
 #else
-#define PARANOIA(x...) do { ; } while(0)
+# define PARANOIA(f, a...) do { ; } while(0)
 #endif
 
 /* lots of debug messages */
 #ifdef SMBFS_DEBUG_VERBOSE
-#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " x)
+# define VERBOSE(f, a...) printk(KERN_DEBUG "%s: " f, __FUNCTION__ , ## a)
 #else
-#define VERBOSE(x...) do { ; } while(0)
+# define VERBOSE(f, a...) do { ; } while(0)
 #endif
 
 /*
@@ -28,7 +28,7 @@
  * too common name.
  */
 #ifdef SMBFS_DEBUG
-#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " x)
+#define DEBUG1(f, a...) printk(KERN_DEBUG "%s: " f, __FUNCTION__ , ## a)
 #else
-#define DEBUG1(x...) do { ; } while(0)
+#define DEBUG1(f, a...) do { ; } while(0)
 #endif
diff -Nru a/fs/stat.c b/fs/stat.c
--- a/fs/stat.c	Sun Jun 16 19:31:39 2002
+++ b/fs/stat.c	Sun Jun 16 19:31:39 2002
@@ -33,7 +33,7 @@
 	stat->blksize = inode->i_blksize;
 }
 
-static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
 	struct inode *inode = dentry->d_inode;
 
@@ -58,7 +58,7 @@
 
 	error = user_path_walk(name, &nd);
 	if (!error) {
-		error = do_getattr(nd.mnt, nd.dentry, stat);
+		error = vfs_getattr(nd.mnt, nd.dentry, stat);
 		path_release(&nd);
 	}
 	return error;
@@ -71,7 +71,7 @@
 
 	error = user_path_walk_link(name, &nd);
 	if (!error) {
-		error = do_getattr(nd.mnt, nd.dentry, stat);
+		error = vfs_getattr(nd.mnt, nd.dentry, stat);
 		path_release(&nd);
 	}
 	return error;
@@ -83,7 +83,7 @@
 	int error = -EBADF;
 
 	if (f) {
-		error = do_getattr(f->f_vfsmnt, f->f_dentry, stat);
+		error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
 		fput(f);
 	}
 	return error;
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Sun Jun 16 19:31:40 2002
+++ b/fs/super.c	Sun Jun 16 19:31:40 2002
@@ -151,47 +151,17 @@
 	yield();
 	return 0;
 }
- 
-/**
- *	insert_super	-	put superblock on the lists
- *	@s:	superblock in question
- *	@type:	filesystem type it will belong to
- *
- *	Associates superblock with fs type and puts it on per-type and global
- *	superblocks' lists.  Should be called with sb_lock held; drops it.
- *
- *	NOTE: the super_blocks ordering here is important: writeback wants
- *	the blockdev superblock to be at super_blocks.next.
- */
-static void insert_super(struct super_block *s, struct file_system_type *type)
-{
-	s->s_type = type;
-	list_add(&s->s_list, super_blocks.prev);
-	list_add(&s->s_instances, &type->fs_supers);
-	spin_unlock(&sb_lock);
-	get_filesystem(type);
-}
 
 /**
- *	remove_super	-	makes superblock unreachable
- *	@s:	superblock in question
+ *	generic_shutdown_super	-	common helper for ->kill_sb()
+ *	@sb: superblock to kill
  *
- *	Removes superblock from the lists, and unlocks it.  @s should have
- *	no active references by that time and after remove_super() it's
- *	essentially in rundown mode - all remaining references are temporary,
- *	no new references of any sort are going to appear and all holders
- *	of temporary ones will eventually drop them.  At that point superblock
- *	itself will be destroyed; all its contents is already gone.
+ *	generic_shutdown_super() does all fs-independent work on superblock
+ *	shutdown.  Typical ->kill_sb() should pick all fs-specific objects
+ *	that need destruction out of superblock, call generic_shutdown_super()
+ *	and release aforementioned objects.  Note: dentries and inodes _are_
+ *	taken care of and do not need specific handling.
  */
-static void remove_super(struct super_block *s)
-{
-	spin_lock(&sb_lock);
-	list_del(&s->s_list);
-	list_del(&s->s_instances);
-	spin_unlock(&sb_lock);
-	up_write(&s->s_umount);
-}
-
 void generic_shutdown_super(struct super_block *sb)
 {
 	struct dentry *root = sb->s_root;
@@ -224,9 +194,20 @@
 		unlock_kernel();
 		unlock_super(sb);
 	}
-	remove_super(sb);
+	spin_lock(&sb_lock);
+	list_del(&sb->s_list);
+	list_del(&sb->s_instances);
+	spin_unlock(&sb_lock);
+	up_write(&sb->s_umount);
 }
 
+/**
+ *	sget	-	find or create a superblock
+ *	@type:	filesystem type superblock should belong to
+ *	@test:	comparison callback
+ *	@set:	setup callback
+ *	@data:	argument to each of them
+ */
 struct super_block *sget(struct file_system_type *type,
 			int (*test)(struct super_block *,void *),
 			int (*set)(struct super_block *,void *),
@@ -253,30 +234,21 @@
 	}
 	err = set(s, data);
 	if (err) {
+		spin_unlock(&sb_lock);
 		destroy_super(s);
 		return ERR_PTR(err);
 	}
-	insert_super(s, type);
+	s->s_type = type;
+	list_add(&s->s_list, super_blocks.prev);
+	list_add(&s->s_instances, &type->fs_supers);
+	spin_unlock(&sb_lock);
+	get_filesystem(type);
 	return s;
 }
 
 struct vfsmount *alloc_vfsmnt(char *name);
 void free_vfsmnt(struct vfsmount *mnt);
 
-static inline struct super_block * find_super(kdev_t dev)
-{
-	struct list_head *p;
-
-	list_for_each(p, &super_blocks) {
-		struct super_block * s = sb_entry(p);
-		if (kdev_same(s->s_dev, dev)) {
-			s->s_count++;
-			return s;
-		}
-	}
-	return NULL;
-}
-
 void drop_super(struct super_block *sb)
 {
 	up_read(&sb->s_umount);
@@ -323,26 +295,50 @@
  *	Scans the superblock list and finds the superblock of the file system
  *	mounted on the device given. %NULL is returned if no match is found.
  */
- 
-struct super_block * get_super(kdev_t dev)
-{
-	struct super_block * s;
 
-	if (kdev_none(dev))
+struct super_block * get_super(struct block_device *bdev)
+{
+	struct list_head *p;
+	if (!bdev)
 		return NULL;
+rescan:
+	spin_lock(&sb_lock);
+	list_for_each(p, &super_blocks) {
+		struct super_block *s = sb_entry(p);
+		if (s->s_bdev == bdev) {
+			s->s_count++;
+			spin_unlock(&sb_lock);
+			down_read(&s->s_umount);
+			if (s->s_root)
+				return s;
+			drop_super(s);
+			goto rescan;
+		}
+	}
+	spin_unlock(&sb_lock);
+	return NULL;
+}
+ 
+struct super_block * user_get_super(dev_t dev)
+{
+	struct list_head *p;
 
-	while (1) {
-		spin_lock(&sb_lock);
-		s = find_super(dev);
-		spin_unlock(&sb_lock);
-		if (!s)
-			break;
-		down_read(&s->s_umount);
-		if (s->s_root)
-			break;
-		drop_super(s);
+rescan:
+	spin_lock(&sb_lock);
+	list_for_each(p, &super_blocks) {
+		struct super_block *s = sb_entry(p);
+		if (s->s_dev ==  dev) {
+			s->s_count++;
+			spin_unlock(&sb_lock);
+			down_read(&s->s_umount);
+			if (s->s_root)
+				return s;
+			drop_super(s);
+			goto rescan;
+		}
 	}
-	return s;
+	spin_unlock(&sb_lock);
+	return NULL;
 }
 
 asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf)
@@ -352,7 +348,7 @@
         struct statfs sbuf;
 	int err = -EINVAL;
 
-        s = get_super(to_kdev_t(dev));
+        s = user_get_super(dev);
         if (s == NULL)
                 goto out;
 	err = vfs_statfs(s, &sbuf);
@@ -381,7 +377,7 @@
 {
 	int retval;
 	
-	if (!(flags & MS_RDONLY) && !kdev_none(sb->s_dev) && is_read_only(sb->s_dev))
+	if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev))
 		return -EACCES;
 		/*flags |= MS_RDONLY;*/
 	if (flags & MS_RDONLY)
@@ -423,19 +419,13 @@
 	}
 	set_bit(dev, unnamed_dev_in_use);
 	spin_unlock(&unnamed_dev_lock);
-	s->s_dev = mk_kdev(0, dev);
+	s->s_dev = MKDEV(0, dev);
 	return 0;
 }
 
-struct super_block *get_anon_super(struct file_system_type *type,
-	int (*compare)(struct super_block *,void *), void *data)
-{
-	return sget(type, compare, set_anon_super, data);
-}
- 
 void kill_anon_super(struct super_block *sb)
 {
-	int slot = minor(sb->s_dev);
+	int slot = MINOR(sb->s_dev);
 	generic_shutdown_super(sb);
 	spin_lock(&unnamed_dev_lock);
 	clear_bit(slot, unnamed_dev_in_use);
@@ -452,7 +442,7 @@
 static int set_bdev_super(struct super_block *s, void *data)
 {
 	s->s_bdev = data;
-	s->s_dev = to_kdev_t(s->s_bdev->bd_dev);
+	s->s_dev = s->s_bdev->bd_dev;
 	return 0;
 }
 
@@ -505,14 +495,17 @@
 		goto out;
 	check_disk_change(dev);
 	error = -EACCES;
-	if (!(flags & MS_RDONLY) && is_read_only(dev))
+	if (!(flags & MS_RDONLY) && bdev_read_only(bdev))
 		goto out1;
 	error = bd_claim(bdev, fs_type);
 	if (error)
 		goto out1;
 
 	s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
-	if (s->s_root) {
+	if (IS_ERR(s)) {
+		bd_release(bdev);
+		blkdev_put(bdev, BDEV_FS);
+	} else if (s->s_root) {
 		if ((flags ^ s->s_flags) & MS_RDONLY) {
 			up_write(&s->s_umount);
 			deactivate_super(s);
@@ -557,7 +550,7 @@
 	int (*fill_super)(struct super_block *, void *, int))
 {
 	int error;
-	struct super_block *s = get_anon_super(fs_type, NULL, NULL);
+	struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
 
 	if (IS_ERR(s))
 		return s;
@@ -583,9 +576,10 @@
 	int flags, void *data,
 	int (*fill_super)(struct super_block *, void *, int))
 {
+	struct super_block *s;
 	int error;
-	struct super_block *s = get_anon_super(fs_type, compare_single, NULL);
 
+	s = sget(fs_type, compare_single, set_anon_super, NULL);
 	if (IS_ERR(s))
 		return s;
 	if (!s->s_root) {
@@ -618,8 +612,6 @@
 	sb = type->get_sb(type, flags, name, data);
 	if (IS_ERR(sb))
 		goto out_mnt;
-	if (type->fs_flags & FS_NOMOUNT)
-		sb->s_flags |= MS_NOUSER;
 	mnt->mnt_sb = sb;
 	mnt->mnt_root = dget(sb->s_root);
 	mnt->mnt_mountpoint = sb->s_root;
diff -Nru a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
--- a/include/asm-arm/atomic.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-arm/atomic.h	Sun Jun 16 19:31:39 2002
@@ -32,7 +32,7 @@
 #define atomic_read(v)	((v)->counter)
 #define atomic_set(v,i)	(((v)->counter) = (i))
 
-static __inline__ void atomic_add(int i, volatile atomic_t *v)
+static inline void atomic_add(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 
@@ -41,7 +41,7 @@
 	__restore_flags(flags);
 }
 
-static __inline__ void atomic_sub(int i, volatile atomic_t *v)
+static inline void atomic_sub(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 
@@ -50,7 +50,7 @@
 	__restore_flags(flags);
 }
 
-static __inline__ void atomic_inc(volatile atomic_t *v)
+static inline void atomic_inc(volatile atomic_t *v)
 {
 	unsigned long flags;
 
@@ -59,7 +59,7 @@
 	__restore_flags(flags);
 }
 
-static __inline__ void atomic_dec(volatile atomic_t *v)
+static inline void atomic_dec(volatile atomic_t *v)
 {
 	unsigned long flags;
 
@@ -68,7 +68,7 @@
 	__restore_flags(flags);
 }
 
-static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+static inline int atomic_dec_and_test(volatile atomic_t *v)
 {
 	unsigned long flags;
 	int val;
@@ -94,7 +94,7 @@
 	return val < 0;
 }
 
-static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 {
 	unsigned long flags;
 
diff -Nru a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
--- a/include/asm-arm/bitops.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-arm/bitops.h	Sun Jun 16 19:31:39 2002
@@ -319,6 +319,12 @@
 }
 
 /*
+ * fls: find last bit set.
+ */
+
+#define fls(x) generic_fls(x)
+
+/*
  * ffs: find first bit set. This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
@@ -332,15 +338,14 @@
  */
 static inline int sched_find_first_bit(unsigned long *b)
 {
-	if (unlikely(b[0]))
-		return __ffs(b[0]);
-	if (unlikely(b[1]))
-		return __ffs(b[1]) + 32;
-	if (unlikely(b[2]))
-		return __ffs(b[2]) + 64;
-	if (b[3])
-		return __ffs(b[3]) + 96;
-	return __ffs(b[4]) + 128;
+	unsigned long v;
+	unsigned int off;
+
+	for (off = 0; v = b[off], off < 4; off++) {
+		if (unlikely(v))
+			break;
+	}
+	return __ffs(v) + off * 32;
 }
 
 /*
diff -Nru a/include/asm-arm/system.h b/include/asm-arm/system.h
--- a/include/asm-arm/system.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-arm/system.h	Sun Jun 16 19:31:39 2002
@@ -24,6 +24,17 @@
 #define have_isa_bridge		(0)
 #endif
 
+struct pt_regs;
+
+void die(const char *msg, struct pt_regs *regs, int err)
+		__attribute__((noreturn));
+
+void die_if_kernel(const char *str, struct pt_regs *regs, int err);
+
+void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
+				       struct pt_regs *),
+		     int sig, const char *name);
+
 #include <asm/proc-fns.h>
 
 #define xchg(ptr,x) \
diff -Nru a/include/asm-cris/locks.h b/include/asm-cris/locks.h
--- a/include/asm-cris/locks.h	Sun Jun 16 19:31:40 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,133 +0,0 @@
-/*
- *	SMP locks primitives for building ix86 locks
- *	(not yet used).
- *
- *		Alan Cox, alan@cymru.net, 1995
- */
- 
-/*
- *	This would be much easier but far less clear and easy
- *	to borrow for other processors if it was just assembler.
- */
-
-extern __inline__ void prim_spin_lock(struct spinlock *sp)
-{
-	int processor=smp_processor_id();
-	
-	/*
-	 *	Grab the lock bit
-	 */
-	 
-	while(lock_set_bit(0,&sp->lock))
-	{
-		/*
-		 *	Failed, but that's cos we own it!
-		 */
-		 
-		if(sp->cpu==processor)
-		{
-			sp->users++;
-			return 0;
-		}
-		/*
-		 *	Spin in the cache S state if possible
-		 */
-		while(sp->lock)
-		{
-			/*
-			 *	Wait for any invalidates to go off
-			 */
-			 
-			if(smp_invalidate_needed&(1<<processor))
-				while(lock_clear_bit(processor,&smp_invalidate_needed))
-					local_flush_tlb();
-			sp->spins++;
-		}
-		/*
-		 *	Someone wrote the line, we go 'I' and get
-		 *	the cache entry. Now try to regrab
-		 */
-	}
-	sp->users++;sp->cpu=processor;
-	return 1;
-}
-
-/*
- *	Release a spin lock
- */
- 
-extern __inline__ int prim_spin_unlock(struct spinlock *sp)
-{
-	/* This is safe. The decrement is still guarded by the lock. A multilock would
-	   not be safe this way */
-	if(!--sp->users)
-	{
-		lock_clear_bit(0,&sp->lock);sp->cpu= NO_PROC_ID;
-		return 1;
-	}
-	return 0;
-}
-
-
-/*
- *	Non blocking lock grab
- */
- 
-extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
-{
-	if(lock_set_bit(0,&sp->lock))
-		return 0;		/* Locked already */
-	sp->users++;
-	return 1;			/* We got the lock */
-}
-
-
-/*
- *	These wrap the locking primitives up for usage
- */
- 
-extern __inline__ void spinlock(struct spinlock *sp)
-{
-	if(sp->priority<current->lock_order)
-		panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
-	if(prim_spin_lock(sp))
-	{
-		/*
-		 *	We got a new lock. Update the priority chain
-		 */
-		sp->oldpri=current->lock_order;
-		current->lock_order=sp->priority;
-	}
-}
-
-extern __inline__ void spinunlock(struct spinlock *sp)
-{
-	if(current->lock_order!=sp->priority)
-		panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
-	if(prim_spin_unlock(sp))
-	{
-		/*
-		 *	Update the debugging lock priority chain. We dumped
-		 *	our last right to the lock.
-		 */
-		current->lock_order=sp->oldpri;
-	}	
-}
-
-extern __inline__ void spintestlock(struct spinlock *sp)
-{
-	/*
-	 *	We do no sanity checks, it's legal to optimistically
-	 *	get a lower lock.
-	 */
-	prim_spin_lock_nb(sp);
-}
-
-extern __inline__ void spintestunlock(struct spinlock *sp)
-{
-	/*
-	 *	A testlock doesn't update the lock chain so we
-	 *	must not update it on free
-	 */
-	prim_spin_unlock(sp);
-}
diff -Nru a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
--- a/include/asm-generic/tlb.h	Sun Jun 16 19:31:38 2002
+++ b/include/asm-generic/tlb.h	Sun Jun 16 19:31:38 2002
@@ -22,7 +22,7 @@
  */
 #ifdef CONFIG_SMP
   #define FREE_PTE_NR	507
-  #define tlb_fast_mode(tlb) ((tlb)->nr == ~0UL) 
+  #define tlb_fast_mode(tlb) ((tlb)->nr == ~0U)
 #else
   #define FREE_PTE_NR	1
   #define tlb_fast_mode(tlb) 1
@@ -35,7 +35,8 @@
  */
 typedef struct free_pte_ctx {
 	struct mm_struct	*mm;
-	unsigned long		nr;	/* set to ~0UL means fast mode */
+	unsigned int		nr;	/* set to ~0U means fast mode */
+	unsigned int		fullmm; /* non-zero means full mm flush */
 	unsigned long		freed;
 	struct page *		pages[FREE_PTE_NR];
 } mmu_gather_t;
@@ -46,15 +47,18 @@
 /* tlb_gather_mmu
  *	Return a pointer to an initialized mmu_gather_t.
  */
-static inline mmu_gather_t *tlb_gather_mmu(struct mm_struct *mm)
+static inline mmu_gather_t *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
 {
 	mmu_gather_t *tlb = &mmu_gathers[smp_processor_id()];
 
 	tlb->mm = mm;
-	tlb->freed = 0;
 
 	/* Use fast mode if only one CPU is online */
 	tlb->nr = smp_num_cpus > 1 ? 0UL : ~0UL;
+
+	tlb->fullmm = full_mm_flush;
+	tlb->freed = 0;
+
 	return tlb;
 }
 
diff -Nru a/include/asm-i386/locks.h b/include/asm-i386/locks.h
--- a/include/asm-i386/locks.h	Sun Jun 16 19:31:40 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,135 +0,0 @@
-/*
- *	SMP locks primitives for building ix86 locks
- *	(not yet used).
- *
- *		Alan Cox, alan@redhat.com, 1995
- */
- 
-/*
- *	This would be much easier but far less clear and easy
- *	to borrow for other processors if it was just assembler.
- */
-
-static __inline__ void prim_spin_lock(struct spinlock *sp)
-{
-	int processor=smp_processor_id();
-	
-	/*
-	 *	Grab the lock bit
-	 */
-	 
-	while(lock_set_bit(0,&sp->lock))
-	{
-		/*
-		 *	Failed, but that's cos we own it!
-		 */
-		 
-		if(sp->cpu==processor)
-		{
-			sp->users++;
-			return 0;
-		}
-		/*
-		 *	Spin in the cache S state if possible
-		 */
-		while(sp->lock)
-		{
-			/*
-			 *	Wait for any invalidates to go off
-			 */
-			 
-			if(smp_invalidate_needed&(1<<processor))
-				while(lock_clear_bit(processor,&smp_invalidate_needed))
-					local_flush_tlb();
-			sp->spins++;
-		}
-		/*
-		 *	Someone wrote the line, we go 'I' and get
-		 *	the cache entry. Now try to regrab
-		 */
-	}
-	sp->users++;sp->cpu=processor;
-	return 1;
-}
-
-/*
- *	Release a spin lock
- */
- 
-static __inline__ int prim_spin_unlock(struct spinlock *sp)
-{
-	/* This is safe. The decrement is still guarded by the lock. A multilock would
-	   not be safe this way */
-	if(!--sp->users)
-	{
-		sp->cpu= NO_PROC_ID;lock_clear_bit(0,&sp->lock);
-		return 1;
-	}
-	return 0;
-}
-
-
-/*
- *	Non blocking lock grab
- */
- 
-static __inline__ int prim_spin_lock_nb(struct spinlock *sp)
-{
-	if(lock_set_bit(0,&sp->lock))
-		return 0;		/* Locked already */
-	sp->users++;
-	return 1;			/* We got the lock */
-}
-
-
-/*
- *	These wrap the locking primitives up for usage
- */
- 
-static __inline__ void spinlock(struct spinlock *sp)
-{
-	if(sp->priority<current->lock_order)
-		panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
-	if(prim_spin_lock(sp))
-	{
-		/*
-		 *	We got a new lock. Update the priority chain
-		 */
-		sp->oldpri=current->lock_order;
-		current->lock_order=sp->priority;
-	}
-}
-
-static __inline__ void spinunlock(struct spinlock *sp)
-{
-	int pri;
-	if(current->lock_order!=sp->priority)
-		panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
-	pri=sp->oldpri;
-	if(prim_spin_unlock(sp))
-	{
-		/*
-		 *	Update the debugging lock priority chain. We dumped
-		 *	our last right to the lock.
-		 */
-		current->lock_order=sp->pri;
-	}	
-}
-
-static __inline__ void spintestlock(struct spinlock *sp)
-{
-	/*
-	 *	We do no sanity checks, it's legal to optimistically
-	 *	get a lower lock.
-	 */
-	prim_spin_lock_nb(sp);
-}
-
-static __inline__ void spintestunlock(struct spinlock *sp)
-{
-	/*
-	 *	A testlock doesn't update the lock chain so we
-	 *	must not update it on free
-	 */
-	prim_spin_unlock(sp);
-}
diff -Nru a/include/asm-i386/pci.h b/include/asm-i386/pci.h
--- a/include/asm-i386/pci.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-i386/pci.h	Sun Jun 16 19:31:40 2002
@@ -109,7 +109,7 @@
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
-	return (page - mem_map) * PAGE_SIZE + offset;
+	return (dma_addr_t)(page - mem_map) * PAGE_SIZE + offset;
 }
 
 static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
diff -Nru a/include/asm-i386/processor.h b/include/asm-i386/processor.h
--- a/include/asm-i386/processor.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-i386/processor.h	Sun Jun 16 19:31:39 2002
@@ -267,6 +267,7 @@
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  */
 #define IO_BITMAP_SIZE	32
+#define IO_BITMAP_BYTES	(IO_BITMAP_SIZE * 4)
 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
 #define INVALID_IO_BITMAP_OFFSET 0x8000
 
@@ -370,8 +371,7 @@
 	unsigned long		screen_bitmap;
 	unsigned long		v86flags, v86mask, v86mode, saved_esp0;
 /* IO permissions */
-	int		ioperm;
-	unsigned long	io_bitmap[IO_BITMAP_SIZE+1];
+	unsigned long	*ts_io_bitmap;
 };
 
 #define INIT_THREAD  {						\
@@ -381,7 +381,7 @@
 	0, 0, 0,						\
 	{ { 0, }, },		/* 387 state */			\
 	0,0,0,0,0,0,						\
-	0,{~0,}			/* io permissions */		\
+	NULL,			/* io permissions */		\
 }
 
 #define INIT_TSS  {						\
diff -Nru a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
--- a/include/asm-i386/spinlock.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-i386/spinlock.h	Sun Jun 16 19:31:39 2002
@@ -9,30 +9,20 @@
 extern int printk(const char * fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
 
-/* It seems that people are forgetting to
- * initialize their spinlocks properly, tsk tsk.
- * Remember to turn this off in 2.4. -ben
- */
-#if defined(CONFIG_DEBUG_SPINLOCK)
-#define SPINLOCK_DEBUG	1
-#else
-#define SPINLOCK_DEBUG	0
-#endif
-
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  */
 
 typedef struct {
 	volatile unsigned int lock;
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
 } spinlock_t;
 
 #define SPINLOCK_MAGIC	0xdead4ead
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 #define SPINLOCK_MAGIC_INIT	, SPINLOCK_MAGIC
 #else
 #define SPINLOCK_MAGIC_INIT	/* */
@@ -79,7 +69,7 @@
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	if (lock->magic != SPINLOCK_MAGIC)
 		BUG();
 	if (!spin_is_locked(lock))
@@ -100,7 +90,7 @@
 static inline void _raw_spin_unlock(spinlock_t *lock)
 {
 	char oldval = 1;
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	if (lock->magic != SPINLOCK_MAGIC)
 		BUG();
 	if (!spin_is_locked(lock))
@@ -125,7 +115,7 @@
 
 static inline void _raw_spin_lock(spinlock_t *lock)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	__label__ here;
 here:
 	if (lock->magic != SPINLOCK_MAGIC) {
@@ -151,14 +141,14 @@
  */
 typedef struct {
 	volatile unsigned int lock;
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
 } rwlock_t;
 
 #define RWLOCK_MAGIC	0xdeaf1eed
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 #define RWLOCK_MAGIC_INIT	, RWLOCK_MAGIC
 #else
 #define RWLOCK_MAGIC_INIT	/* */
@@ -181,7 +171,7 @@
 
 static inline void _raw_read_lock(rwlock_t *rw)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	if (rw->magic != RWLOCK_MAGIC)
 		BUG();
 #endif
@@ -190,7 +180,7 @@
 
 static inline void _raw_write_lock(rwlock_t *rw)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	if (rw->magic != RWLOCK_MAGIC)
 		BUG();
 #endif
diff -Nru a/include/asm-i386/system.h b/include/asm-i386/system.h
--- a/include/asm-i386/system.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-i386/system.h	Sun Jun 16 19:31:39 2002
@@ -11,9 +11,12 @@
 struct task_struct;	/* one of the stranger aspects of C forward declarations.. */
 extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
 
-#define prepare_to_switch()	do { } while(0)
+#define prepare_arch_schedule(prev)		do { } while(0)
+#define finish_arch_schedule(prev)		do { } while(0)
+#define prepare_arch_switch(rq)			do { } while(0)
+#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
 
-#define switch_to(prev,next) do {					\
+#define switch_to(prev,next,last) do {					\
 	asm volatile("pushl %%esi\n\t"					\
 		     "pushl %%edi\n\t"					\
 		     "pushl %%ebp\n\t"					\
diff -Nru a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
--- a/include/asm-ppc/spinlock.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-ppc/spinlock.h	Sun Jun 16 19:31:40 2002
@@ -7,22 +7,20 @@
 #include <asm/system.h>
 #include <asm/processor.h>
 
-#undef SPINLOCK_DEBUG
-
 /*
  * Simple spin lock operations.
  */
 
 typedef struct {
 	volatile unsigned long lock;
-#ifdef SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	volatile unsigned long owner_pc;
 	volatile unsigned long owner_cpu;
 #endif
 } spinlock_t;
 
 #ifdef __KERNEL__
-#if SPINLOCK_DEBUG
+#if CONFIG_DEBUG_SPINLOCK
 #define SPINLOCK_DEBUG_INIT     , 0, 0
 #else
 #define SPINLOCK_DEBUG_INIT     /* */
@@ -34,7 +32,7 @@
 #define spin_is_locked(x)	((x)->lock != 0)
 #define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
 
-#ifndef SPINLOCK_DEBUG
+#ifndef CONFIG_DEBUG_SPINLOCK
 
 static inline void _raw_spin_lock(spinlock_t *lock)
 {
@@ -88,12 +86,12 @@
  */
 typedef struct {
 	volatile unsigned long lock;
-#ifdef SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	volatile unsigned long owner_pc;
 #endif
 } rwlock_t;
 
-#if SPINLOCK_DEBUG
+#if CONFIG_DEBUG_SPINLOCK
 #define RWLOCK_DEBUG_INIT     , 0
 #else
 #define RWLOCK_DEBUG_INIT     /* */
@@ -102,7 +100,7 @@
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT }
 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
 
-#ifndef SPINLOCK_DEBUG
+#ifndef CONFIG_DEBUG_SPINLOCK
 
 static __inline__ void _raw_read_lock(rwlock_t *rw)
 {
diff -Nru a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h
--- a/include/asm-sparc64/mmu_context.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-sparc64/mmu_context.h	Sun Jun 16 19:31:41 2002
@@ -141,6 +141,8 @@
 	spin_unlock(&mm->page_table_lock);
 }
 
+extern void __flush_tlb_mm(unsigned long, unsigned long);
+
 /* Activate a new MM instance for the current task. */
 static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
 {
diff -Nru a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
--- a/include/asm-sparc64/pgalloc.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-sparc64/pgalloc.h	Sun Jun 16 19:31:40 2002
@@ -35,11 +35,11 @@
 	struct page *page = virt_to_page(pgd);
 
 	preempt_disable();
-	if (!page->pprev_hash) {
-		(unsigned long *)page->next_hash = pgd_quicklist;
+	if (!page->lru.prev) {
+		(unsigned long *)page->lru.next = pgd_quicklist;
 		pgd_quicklist = (unsigned long *)page;
 	}
-	(unsigned long)page->pprev_hash |=
+	(unsigned long)page->lru.prev |=
 		(((unsigned long)pgd & (PAGE_SIZE / 2)) ? 2 : 1);
 	pgd_cache_size++;
 	preempt_enable();
@@ -51,7 +51,7 @@
 
 	preempt_disable();
         if ((ret = (struct page *)pgd_quicklist) != NULL) {
-                unsigned long mask = (unsigned long)ret->pprev_hash;
+                unsigned long mask = (unsigned long)ret->lru.prev;
 		unsigned long off = 0;
 
 		if (mask & 1)
@@ -60,9 +60,9 @@
 			off = PAGE_SIZE / 2;
 			mask &= ~2;
 		}
-		(unsigned long)ret->pprev_hash = mask;
+		(unsigned long)ret->lru.prev = mask;
 		if (!mask)
-			pgd_quicklist = (unsigned long *)ret->next_hash;
+			pgd_quicklist = (unsigned long *)ret->lru.next;
                 ret = (struct page *)(__page_address(ret) + off);
                 pgd_cache_size--;
 		preempt_enable();
@@ -74,10 +74,10 @@
 		if (page) {
 			ret = (struct page *)page_address(page);
 			clear_page(ret);
-			(unsigned long)page->pprev_hash = 2;
+			(unsigned long)page->lru.prev = 2;
 
 			preempt_disable();
-			(unsigned long *)page->next_hash = pgd_quicklist;
+			(unsigned long *)page->lru.next = pgd_quicklist;
 			pgd_quicklist = (unsigned long *)page;
 			pgd_cache_size++;
 			preempt_enable();
diff -Nru a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
--- a/include/asm-sparc64/pgtable.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-sparc64/pgtable.h	Sun Jun 16 19:31:39 2002
@@ -14,7 +14,6 @@
 
 #include <asm/spitfire.h>
 #include <asm/asi.h>
-#include <asm/mmu_context.h>
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/processor.h>
@@ -63,6 +62,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/sched.h>
+
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
@@ -286,6 +287,7 @@
 #define mmu_lockarea(vaddr, len)		(vaddr)
 #define mmu_unlockarea(vaddr, len)		do { } while(0)
 
+struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 /* Make a non-present pseudo-TTE. */
diff -Nru a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
--- a/include/asm-sparc64/tlb.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-sparc64/tlb.h	Sun Jun 16 19:31:39 2002
@@ -1,14 +1,23 @@
 #ifndef _SPARC64_TLB_H
 #define _SPARC64_TLB_H
 
-#define tlb_flush(tlb)		flush_tlb_mm((tlb)->mm)
+#define tlb_flush(tlb)			\
+do {	if ((tlb)->fullmm)		\
+		flush_tlb_mm((tlb)->mm);\
+} while (0)
 
 #define tlb_start_vma(tlb, vma) \
-	flush_cache_range(vma, vma->vm_start, vma->vm_end)
-#define tlb_end_vma(tlb, vma) \
-	flush_tlb_range(vma, vma->vm_start, vma->vm_end)
+do {	if (!(tlb)->fullmm)	\
+		flush_cache_range(vma, vma->vm_start, vma->vm_end); \
+} while (0)
 
-#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_end_vma(tlb, vma)	\
+do {	if (!(tlb)->fullmm)	\
+		flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
+} while (0)
+
+#define tlb_remove_tlb_entry(tlb, pte, address) \
+	do { } while (0)
 
 #include <asm-generic/tlb.h>
 
diff -Nru a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h
--- a/include/asm-sparc64/tlbflush.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-sparc64/tlbflush.h	Sun Jun 16 19:31:41 2002
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/mm.h>
+#include <asm/mmu_context.h>
 
 /* TLB flush operations. */
 
@@ -22,43 +23,43 @@
 	__flush_tlb_kernel_range(start,end)
 
 #define flush_tlb_mm(__mm) \
-do { if(CTX_VALID((__mm)->context)) \
+do { if (CTX_VALID((__mm)->context)) \
 	__flush_tlb_mm(CTX_HWBITS((__mm)->context), SECONDARY_CONTEXT); \
-} while(0)
+} while (0)
 
 #define flush_tlb_range(__vma, start, end) \
-do { if(CTX_VALID((__vma)->vm_mm->context)) { \
+do { if (CTX_VALID((__vma)->vm_mm->context)) { \
 	unsigned long __start = (start)&PAGE_MASK; \
 	unsigned long __end = PAGE_ALIGN(end); \
 	__flush_tlb_range(CTX_HWBITS((__vma)->vm_mm->context), __start, \
 			  SECONDARY_CONTEXT, __end, PAGE_SIZE, \
 			  (__end - __start)); \
      } \
-} while(0)
+} while (0)
 
 #define flush_tlb_vpte_range(__mm, start, end) \
-do { if(CTX_VALID((__mm)->context)) { \
+do { if (CTX_VALID((__mm)->context)) { \
 	unsigned long __start = (start)&PAGE_MASK; \
 	unsigned long __end = PAGE_ALIGN(end); \
 	__flush_tlb_range(CTX_HWBITS((__mm)->context), __start, \
 			  SECONDARY_CONTEXT, __end, PAGE_SIZE, \
 			  (__end - __start)); \
      } \
-} while(0)
+} while (0)
 
 #define flush_tlb_page(vma, page) \
 do { struct mm_struct *__mm = (vma)->vm_mm; \
-     if(CTX_VALID(__mm->context)) \
+     if (CTX_VALID(__mm->context)) \
 	__flush_tlb_page(CTX_HWBITS(__mm->context), (page)&PAGE_MASK, \
 			 SECONDARY_CONTEXT); \
-} while(0)
+} while (0)
 
 #define flush_tlb_vpte_page(mm, addr) \
 do { struct mm_struct *__mm = (mm); \
-     if(CTX_VALID(__mm->context)) \
+     if (CTX_VALID(__mm->context)) \
 	__flush_tlb_page(CTX_HWBITS(__mm->context), (addr)&PAGE_MASK, \
 			 SECONDARY_CONTEXT); \
-} while(0)
+} while (0)
 
 #else /* CONFIG_SMP */
 
diff -Nru a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h
--- a/include/asm-x86_64/apic.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/apic.h	Sun Jun 16 19:31:40 2002
@@ -41,15 +41,9 @@
 	while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
 }
 
-#ifdef CONFIG_X86_GOOD_APIC
-# define FORCE_READ_AROUND_WRITE 0
-# define apic_read_around(x)
-# define apic_write_around(x,y) apic_write((x),(y))
-#else
-# define FORCE_READ_AROUND_WRITE 1
-# define apic_read_around(x) apic_read(x)
-# define apic_write_around(x,y) apic_write_atomic((x),(y))
-#endif
+#define FORCE_READ_AROUND_WRITE 0
+#define apic_read_around(x)
+#define apic_write_around(x,y) apic_write((x),(y))
 
 static inline void ack_APIC_irq(void)
 {
diff -Nru a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
--- a/include/asm-x86_64/bitops.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/bitops.h	Sun Jun 16 19:31:40 2002
@@ -475,6 +475,9 @@
 #define minix_find_first_zero_bit(addr,size) \
 	find_first_zero_bit((void*)addr,size)
 
+/* find last set bit */
+#define fls(x) generic_fls(x)
+
 #endif /* __KERNEL__ */
 
 #endif /* _X86_64_BITOPS_H */
diff -Nru a/include/asm-x86_64/bootsetup.h b/include/asm-x86_64/bootsetup.h
--- a/include/asm-x86_64/bootsetup.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-x86_64/bootsetup.h	Sun Jun 16 19:31:41 2002
@@ -18,6 +18,7 @@
 #define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
 #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
 #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
+#define SAVED_VIDEO_MODE (*(unsigned short *) (PARAM+0x1FA))
 #define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
 #define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
 #define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
diff -Nru a/include/asm-x86_64/checksum.h b/include/asm-x86_64/checksum.h
--- a/include/asm-x86_64/checksum.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/checksum.h	Sun Jun 16 19:31:39 2002
@@ -1,7 +1,34 @@
 #ifndef _X86_64_CHECKSUM_H
 #define _X86_64_CHECKSUM_H
 
-#include <linux/in6.h>
+/* 
+ * Checksums for x86-64 
+ * Copyright 2002 by Andi Kleen, SuSE Labs 
+ * with some code from asm-i386/checksum.h
+ */ 
+
+#include <linux/compiler.h>
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+/** 
+ * csum_fold - Fold and invert a 32bit checksum.
+ * sum: 32bit unfolded sum
+ * 
+ * Fold a 32bit running checksum to 16bit and invert it. This is usually
+ * the last step before putting a checksum into a packet.
+ * Make sure not to mix with 64bit checksums.
+ */
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	__asm__(
+		"  addl %1,%0\n"
+		"  adcl $0xffff,%0"
+		: "=r" (sum)
+		: "r" (sum << 16), "0" (sum & 0xffff0000)
+	);
+	return (~sum) >> 16;
+}
 
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
@@ -10,28 +37,33 @@
  *	By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
  *	Arnt Gulbrandsen.
  */
-static inline unsigned short ip_fast_csum(unsigned char * iph,
-					  unsigned int ihl) {
+
+/**
+ * ip_fast_csum - Compute the IPv4 header checksum efficiently.
+ * iph: ipv4 header
+ * ihl: length of header / 4
+ */ 
+static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) 
+{
 	unsigned int sum;
 
-	__asm__ __volatile__(
-"\n	    movl (%1), %0"
-"\n	    subl $4, %2"
-"\n	    jbe 2f"
-"\n	    addl 4(%1), %0"
-"\n	    adcl 8(%1), %0"
-"\n	    adcl 12(%1), %0"
-"\n1:	    adcl 16(%1), %0"
-"\n	    lea 4(%1), %1"
-"\n	    decl %2"
-"\n	    jne	1b"
-"\n	    adcl $0, %0"
-"\n	    movl %0, %2"
-"\n	    shrl $16, %0"
-"\n	    addw %w2, %w0"
-"\n	    adcl $0, %0"
-"\n	    notl %0"
-"\n2:"
+	asm(	"  movl (%1), %0\n"
+		"  subl $4, %2\n"
+		"  jbe 2f\n"
+		"  addl 4(%1), %0\n"
+		"  adcl 8(%1), %0\n"
+		"  adcl 12(%1), %0\n"
+		"1: adcl 16(%1), %0\n"
+		"  lea 4(%1), %1\n"
+		"  decl %2\n"
+		"  jne	1b\n"
+		"  adcl $0, %0\n"
+		"  movl %0, %2\n"
+		"  shrl $16, %0\n"
+		"  addw %w2, %w0\n"
+		"  adcl $0, %0\n"
+		"  notl %0\n"
+		"2:"
 	/* Since the input registers which are loaded with iph and ipl
 	   are modified, we must also specify them as outputs, or gcc
 	   will assume they contain their original values. */
@@ -40,120 +72,111 @@
 	return(sum);
 }
 
-
-
-/*
- *	Fold a partial checksum. Note this works on a 32bit unfolded checksum. Make sure
- *	to not mix with 64bit checksums!
- */
-
-static inline unsigned int csum_fold(unsigned int sum)
+/** 
+ * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
+ * @saddr: source address
+ * @daddr: destination address
+ * @len: length of packet
+ * @proto: ip protocol of packet
+ * @sum: initial sum to be added in (32bit unfolded) 
+ * 
+ * Returns the pseudo header checksum the input data. Result is 
+ * 32bit unfolded.
+ */
+static inline unsigned long 
+csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len,
+		   unsigned short proto, unsigned int sum) 
 {
-	__asm__(
-"\n		addl %1,%0"
-"\n		adcl $0xffff,%0"
+	asm("  addl %1, %0\n"
+	    "  adcl %2, %0\n"
+	    "  adcl %3, %0\n"
+	    "  adcl $0, %0\n"
 		: "=r" (sum)
-		: "r" (sum << 16), "0" (sum & 0xffff0000)
-	);
-	return (~sum) >> 16;
-}
-
-
-
-
-static inline unsigned long csum_tcpudp_nofold(unsigned saddr,
-						   unsigned daddr,
-						   unsigned short len,
-						   unsigned short proto,
-						   unsigned int sum) 
-{
-    __asm__(
-"\n	addl %1, %0"
-"\n	adcl %2, %0"
-"\n	adcl %3, %0"
-"\n	adcl $0, %0"
-	: "=r" (sum)
-	: "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
+	    : "g" (daddr), "g" (saddr), "g" ((ntohs(len)<<16)+proto*256), "0" (sum));
     return sum;
 }
 
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
-						   unsigned long daddr,
-						   unsigned short len,
-						   unsigned short proto,
-						   unsigned int sum) 
+
+/** 
+ * csum_tcpup_magic - Compute an IPv4 pseudo header checksum.
+ * @saddr: source address
+ * @daddr: destination address
+ * @len: length of packet
+ * @proto: ip protocol of packet
+ * @sum: initial sum to be added in (32bit unfolded) 
+ * 
+ * Returns the 16bit pseudo header checksum the input data already
+ * complemented and ready to be filled in.
+ */
+static inline unsigned short int 
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
+		  unsigned short len, unsigned short proto, unsigned int sum) 
 {
 	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
 }
 
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
+/** 
+ * csum_partial - Compute an internet checksum.
+ * @buff: buffer to be checksummed
+ * @len: length of buffer.
+ * @sum: initial sum to be added in (32bit unfolded)
  *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
+ * Returns the 32bit unfolded internet checksum of the buffer.
+ * Before filling it in it needs to be csum_fold()'ed.
+ * buff should be aligned to a 64bit boundary if possible.
+ */ 
+extern unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum);
+
+#define  _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1
+#define HAVE_CSUM_COPY_USER 1
+
+
+/* Do not call this directly. Use the wrappers below */
+extern unsigned long csum_partial_copy_generic(const char *src, const char *dst, 
+					       unsigned len,
+					       unsigned sum, 
+					       int *src_err_ptr, int *dst_err_ptr);
+
+
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, 
+				       int len, unsigned int isum, int *errp);
+extern unsigned int csum_partial_copy_to_user(const char *src, char *dst, 
+				      int len, unsigned int isum, int *errp);
+extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, 
+					      unsigned int sum);
+
+/* Old names. To be removed. */
+#define csum_and_copy_to_user csum_partial_copy_to_user
+#define csum_and_copy_from_user csum_partial_copy_from_user
+
+/** 
+ * ip_compute_csum - Compute an 16bit IP checksum.
+ * @buff: buffer address.
+ * @len: length of buffer.
  *
- * it's best to have buff aligned on a 32-bit boundary
+ * Returns the 16bit folded/inverted checksum of the passed buffer.
+ * Ready to fill in.
  */
-extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+extern unsigned short ip_compute_csum(unsigned char * buff, int len);
 
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
+/**
+ * csum_ipv6_magic - Compute checksum of an IPv6 pseudo header.
+ * @saddr: source address
+ * @daddr: destination address
+ * @len: length of packet
+ * @proto: protocol of packet
+ * @sum: initial sum (32bit unfolded) to be added in
  *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum);
-
-/*
- * this is a new version of the above that records errors it finds in *errp,
- * but continues and zeros the rest of the buffer.
- */
-unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errp);
-
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum);
-
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
+ * Computes an IPv6 pseudo header checksum. This sum is added the checksum 
+ * into UDP/TCP packets and contains some link layer information.
+ * Returns the unfolded 32bit checksum.
  */
 
-extern unsigned short ip_compute_csum(unsigned char * buff, int len);
-
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
-						     struct in6_addr *daddr,
-						     __u32 len,
-						     unsigned short proto,
-						     unsigned int sum) 
-{
-	__asm__(
-"\n		addl 0(%1), %0"
-"\n		adcl 4(%1), %0"
-"\n		adcl 8(%1), %0"
-"\n		adcl 12(%1), %0"
-"\n		adcl 0(%2), %0"
-"\n		adcl 4(%2), %0"
-"\n		adcl 8(%2), %0"
-"\n		adcl 12(%2), %0"
-"\n		adcl %3, %0"
-"\n		adcl %4, %0"
-"\n		adcl $0, %0"
-		: "=&r" (sum)
-		: "r" (saddr), "r" (daddr), 
-		  "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
+struct in6_addr;
 
-	return csum_fold(sum);
-}
+#define _HAVE_ARCH_IPV6_CSUM 1
+extern unsigned short 
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
+		__u32 len, unsigned short proto, unsigned int sum);
 
 #endif
diff -Nru a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
--- a/include/asm-x86_64/cpufeature.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/cpufeature.h	Sun Jun 16 19:31:39 2002
@@ -7,9 +7,6 @@
 #ifndef __ASM_X8664_CPUFEATURE_H
 #define __ASM_X8664_CPUFEATURE_H
 
-/* Sample usage: CPU_FEATURE_P(cpu.x86_capability, FPU) */
-#define CPU_FEATURE_P(CAP, FEATURE) test_bit(CAP, X86_FEATURE_##FEATURE ##_BIT)
-
 #define NCAPINTS	4	/* Currently we have 4 32-bit words worth of info */
 
 /* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
@@ -63,11 +60,26 @@
 #define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
 #define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
 
-#endif /* __ASM_X8664_CPUFEATURE_H */
+#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
+#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
+
+#define cpu_has_fpu            1
+#define cpu_has_vme            0
+#define cpu_has_de             1
+#define cpu_has_pse            1
+#define cpu_has_tsc            1
+#define cpu_has_pae            ___BUG___
+#define cpu_has_pge            1
+#define cpu_has_apic           1
+#define cpu_has_mtrr           1
+#define cpu_has_mmx            1
+#define cpu_has_fxsr           1
+#define cpu_has_xmm            1
+#define cpu_has_ht             0 /* you need to report the support from i386. sorry */
+#define cpu_has_mp             1 /* XXX */
+#define cpu_has_k6_mtrr        0
+#define cpu_has_cyrix_arr      0
+#define cpu_has_centaur_mcr    0
 
-/* 
- * Local Variables:
- * mode:c
- * comment-column:42
- * End:
- */
+
+#endif /* __ASM_X8664_CPUFEATURE_H */
diff -Nru a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
--- a/include/asm-x86_64/desc.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/desc.h	Sun Jun 16 19:31:40 2002
@@ -141,17 +141,17 @@
 /*
  * load one particular LDT into the current CPU
  */
-extern inline void load_LDT (struct mm_struct *mm)
+extern inline void load_LDT (mm_context_t *pc)
 {
 	int cpu = smp_processor_id();
-	void *segments = mm->context.segments;
+	int count = pc->size;
 
-	if (!segments) {
+	if (!count) {
 		clear_LDT(cpu);
 		return;
 	}
 		
-	set_ldt_desc(cpu, segments, LDT_ENTRIES);
+	set_ldt_desc(cpu, pc->ldt, count);
 	__load_LDT(cpu);
 }
 
diff -Nru a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
--- a/include/asm-x86_64/i387.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/i387.h	Sun Jun 16 19:31:40 2002
@@ -140,6 +140,7 @@
 {
 	if (!child->used_math) {
 		/* Simulate an empty FPU. */
+		memset(&child->thread.i387.fxsave,0,sizeof(struct i387_fxsave_struct));
 		child->thread.i387.fxsave.cwd = 0x037f; 
 		child->thread.i387.fxsave.swd = 0;
 		child->thread.i387.fxsave.twd = 0; 
diff -Nru a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
--- a/include/asm-x86_64/io.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/io.h	Sun Jun 16 19:31:40 2002
@@ -193,9 +193,9 @@
 #define __raw_writew writew
 #define __raw_writel writel
 
+void *memcpy_fromio(void*,void*,unsigned); 
+void *memcpy_toio(void*,void*,unsigned); 
 #define memset_io(a,b,c)	memset(__io_virt(a),(b),(c))
-#define memcpy_fromio(a,b,c)	memcpy((a),__io_virt(b),(c))
-#define memcpy_toio(a,b,c)	memcpy(__io_virt(a),(b),(c))
 
 /*
  * ISA space is 'always mapped' on a typical x86 system, no need to
diff -Nru a/include/asm-x86_64/ioctls.h b/include/asm-x86_64/ioctls.h
--- a/include/asm-x86_64/ioctls.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-x86_64/ioctls.h	Sun Jun 16 19:31:41 2002
@@ -67,6 +67,7 @@
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE       0x5460
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -Nru a/include/asm-x86_64/locks.h b/include/asm-x86_64/locks.h
--- a/include/asm-x86_64/locks.h	Sun Jun 16 19:31:39 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,135 +0,0 @@
-/*
- *	SMP locks primitives for building ix86 locks
- *	(not yet used).
- *
- *		Alan Cox, alan@redhat.com, 1995
- */
- 
-/*
- *	This would be much easier but far less clear and easy
- *	to borrow for other processors if it was just assembler.
- */
-
-extern __inline__ void prim_spin_lock(struct spinlock *sp)
-{
-	int processor=smp_processor_id();
-	
-	/*
-	 *	Grab the lock bit
-	 */
-	 
-	while(lock_set_bit(0,&sp->lock))
-	{
-		/*
-		 *	Failed, but that's cos we own it!
-		 */
-		 
-		if(sp->cpu==processor)
-		{
-			sp->users++;
-			return 0;
-		}
-		/*
-		 *	Spin in the cache S state if possible
-		 */
-		while(sp->lock)
-		{
-			/*
-			 *	Wait for any invalidates to go off
-			 */
-			 
-			if(smp_invalidate_needed&(1<<processor))
-				while(lock_clear_bit(processor,&smp_invalidate_needed))
-					local_flush_tlb();
-			sp->spins++;
-		}
-		/*
-		 *	Someone wrote the line, we go 'I' and get
-		 *	the cache entry. Now try to regrab
-		 */
-	}
-	sp->users++;sp->cpu=processor;
-	return 1;
-}
-
-/*
- *	Release a spin lock
- */
- 
-extern __inline__ int prim_spin_unlock(struct spinlock *sp)
-{
-	/* This is safe. The decrement is still guarded by the lock. A multilock would
-	   not be safe this way */
-	if(!--sp->users)
-	{
-		sp->cpu= NO_PROC_ID;lock_clear_bit(0,&sp->lock);
-		return 1;
-	}
-	return 0;
-}
-
-
-/*
- *	Non blocking lock grab
- */
- 
-extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
-{
-	if(lock_set_bit(0,&sp->lock))
-		return 0;		/* Locked already */
-	sp->users++;
-	return 1;			/* We got the lock */
-}
-
-
-/*
- *	These wrap the locking primitives up for usage
- */
- 
-extern __inline__ void spinlock(struct spinlock *sp)
-{
-	if(sp->priority<current->lock_order)
-		panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
-	if(prim_spin_lock(sp))
-	{
-		/*
-		 *	We got a new lock. Update the priority chain
-		 */
-		sp->oldpri=current->lock_order;
-		current->lock_order=sp->priority;
-	}
-}
-
-extern __inline__ void spinunlock(struct spinlock *sp)
-{
-	int pri;
-	if(current->lock_order!=sp->priority)
-		panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
-	pri=sp->oldpri;
-	if(prim_spin_unlock(sp))
-	{
-		/*
-		 *	Update the debugging lock priority chain. We dumped
-		 *	our last right to the lock.
-		 */
-		current->lock_order=sp->pri;
-	}	
-}
-
-extern __inline__ void spintestlock(struct spinlock *sp)
-{
-	/*
-	 *	We do no sanity checks, it's legal to optimistically
-	 *	get a lower lock.
-	 */
-	prim_spin_lock_nb(sp);
-}
-
-extern __inline__ void spintestunlock(struct spinlock *sp)
-{
-	/*
-	 *	A testlock doesn't update the lock chain so we
-	 *	must not update it on free
-	 */
-	prim_spin_unlock(sp);
-}
diff -Nru a/include/asm-x86_64/mmu.h b/include/asm-x86_64/mmu.h
--- a/include/asm-x86_64/mmu.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/mmu.h	Sun Jun 16 19:31:40 2002
@@ -1,13 +1,19 @@
 #ifndef __x86_64_MMU_H
 #define __x86_64_MMU_H
 
+#include <linux/spinlock.h>
+
 /*
  * The x86_64 doesn't have a mmu context, but
  * we put the segment information here.
+ *
+ * cpu_vm_mask is used to optimize ldt flushing.
  */
 typedef struct { 
-	void *segments;
-	unsigned long cpuvalid;
+	void *ldt;
+	rwlock_t ldtlock; 
+	int size;
+	struct semaphore sem; 
 } mm_context_t;
 
 #endif
diff -Nru a/include/asm-x86_64/mmu_context.h b/include/asm-x86_64/mmu_context.h
--- a/include/asm-x86_64/mmu_context.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/mmu_context.h	Sun Jun 16 19:31:40 2002
@@ -13,7 +13,7 @@
  * possibly do the LDT unload here?
  */
 #define destroy_context(mm)		do { } while(0)
-#define init_new_context(tsk,mm)	0
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 
 #ifdef CONFIG_SMP
 
@@ -34,20 +34,17 @@
 	if (likely(prev != next)) {
 		/* stop flush ipis for the previous mm */
 		clear_bit(cpu, &prev->cpu_vm_mask);
-		/*
-		 * Re-load LDT if necessary
-		 */
-		if (unlikely(prev->context.segments != next->context.segments))
-			load_LDT(next);
 #ifdef CONFIG_SMP
 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
 		cpu_tlbstate[cpu].active_mm = next;
 #endif
 		set_bit(cpu, &next->cpu_vm_mask);
-		set_bit(cpu, &next->context.cpuvalid);
 		/* Re-load page tables */
 		*read_pda(level4_pgt) = __pa(next->pgd) | _PAGE_TABLE;
 		__flush_tlb();
+
+		if (next->context.size + prev->context.size) 
+			load_LDT(&next->context);
 	}
 #ifdef CONFIG_SMP
 	else {
@@ -59,9 +56,8 @@
 			 * tlb flush IPI delivery. We must flush our tlb.
 			 */
 			local_flush_tlb();
+			load_LDT(&next->context);
 		}
-		if (!test_and_set_bit(cpu, &next->context.cpuvalid))
-			load_LDT(next);
 	}
 #endif
 }
diff -Nru a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
--- a/include/asm-x86_64/page.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/page.h	Sun Jun 16 19:31:39 2002
@@ -9,23 +9,18 @@
 #define PAGE_SIZE	(1UL << PAGE_SHIFT)
 #endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
+#define PHYSICAL_PAGE_MASK	(~(PAGE_SIZE-1) & (__PHYSICAL_MASK << PAGE_SHIFT))
 #define THREAD_SIZE (2*PAGE_SIZE)
 #define CURRENT_MASK (~(THREAD_SIZE-1))
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
-#if 0 
-#include <asm/mmx.h>
-#define clear_page(page)	mmx_clear_page((void *)(page))
-#define copy_page(to,from)	mmx_copy_page(to,from)
-#else
-#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
-#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
-#endif
+void clear_page(void *);
+void copy_page(void *, void *);
 
-#define clear_user_page(page, vaddr)	clear_page(page)
-#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
 /*
  * These are used to make use of C type-checking..
@@ -34,7 +29,7 @@
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pml4; } pml4_t;
-#define PTE_MASK	PAGE_MASK
+#define PTE_MASK	PHYSICAL_PAGE_MASK
 
 typedef struct { unsigned long pgprot; } pgprot_t;
 
@@ -59,9 +54,12 @@
 #define __START_KERNEL		0xffffffff80100000
 #define __START_KERNEL_map	0xffffffff80000000
 #define __PAGE_OFFSET           0x0000010000000000
+#define __PHYSICAL_MASK		0x000000ffffffffff
 
 #ifndef __ASSEMBLY__
 
+#include <linux/stringify.h>
+
 /*
  * Tell the user there is some problem.  The exception handler decodes this frame.
  */ 
@@ -70,7 +68,9 @@
 	char *filename;    /* should use 32bit offset instead, but the assembler doesn't like it */ 
 	unsigned short line; 
 } __attribute__((packed)); 
-#define BUG() asm volatile("ud2 ; .quad %c1 ; .short %c0" :: "i"(__LINE__), "i" (__FILE__))
+#define BUG() \
+	asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \
+		     "i"(__LINE__), "i" (__stringify(KBUILD_BASENAME)))
 #define PAGE_BUG(page) BUG()
 void out_of_line_bug(void);
 
@@ -103,8 +103,11 @@
 	  __pa(v); })
 
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
-#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+#define pfn_to_page(pfn)	(mem_map + (pfn))
+#define page_to_pfn(page)	((unsigned long)((page) - mem_map))
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_valid(pfn)		((pfn) < max_mapnr)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
 
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
diff -Nru a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
--- a/include/asm-x86_64/pci.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/pci.h	Sun Jun 16 19:31:40 2002
@@ -2,7 +2,6 @@
 #define __x8664_PCI_H
 
 #include <linux/config.h>
-#include <asm/io.h>
 
 #ifdef __KERNEL__
 
@@ -20,17 +19,19 @@
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		(pci_mem_start)
 
+void pcibios_config_init(void);
+struct pci_bus * pcibios_scan_root(int bus);
+extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
+extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
 void pcibios_set_master(struct pci_dev *dev);
 void pcibios_penalize_isa_irq(int irq);
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 
-/* Dynamic DMA mapping stuff.
- * x8664 has everything mapped statically.
- */
-
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/init.h>
 #include <asm/scatterlist.h>
 #include <linux/string.h>
 #include <asm/io.h>
diff -Nru a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
--- a/include/asm-x86_64/pda.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/pda.h	Sun Jun 16 19:31:40 2002
@@ -2,19 +2,17 @@
 #define X86_64_PDA_H
 
 #include <linux/stddef.h>
-#ifndef ASM_OFFSET_H
-#include <asm/offset.h>
-#endif
+#include <linux/types.h>
 #include <linux/cache.h>
 
 /* Per processor datastructure. %gs points to it while the kernel runs */ 
-/* To use a new field with the *_pda macros it needs to be added to tools/offset.c */
 struct x8664_pda {
-	struct x8664_pda *me; 
+	struct task_struct *pcurrent;	/* Current process */
+	unsigned long cpudata_offset;
+	struct x8664_pda *me;	    /* Pointer to itself */  
 	unsigned long kernelstack;  /* TOS for current process */ 
 	unsigned long oldrsp; 	    /* user rsp for system call */
 	unsigned long irqrsp;	    /* Old rsp for interrupts. */ 
-	struct task_struct *pcurrent;	/* Current process */
         int irqcount;		    /* Irq nesting counter. Starts with -1 */  	
 	int cpunumber;		    /* Logical CPU number */
 	char *irqstackptr;	/* top of irqstack */
@@ -39,18 +37,19 @@
  */ 
 #define sizeof_field(type,field)  (sizeof(((type *)0)->field))
 #define typeof_field(type,field)  typeof(((type *)0)->field)
-#ifndef __STR
-#define __STR(x) #x
-#endif
-#define __STR2(x) __STR(x) 
 
 extern void __bad_pda_field(void);
 
+#define pda_offset(field) offsetof(struct x8664_pda, field)
+
 #define pda_to_op(op,field,val) do { \
        switch (sizeof_field(struct x8664_pda, field)) { 		\
-       case 2: asm volatile(op "w %0,%%gs:" __STR2(pda_ ## field) ::"r" (val):"memory"); break;	\
-       case 4: asm volatile(op "l %0,%%gs:" __STR2(pda_ ## field) ::"r" (val):"memory"); break;	\
-       case 8: asm volatile(op "q %0,%%gs:" __STR2(pda_ ## field) ::"r" (val):"memory"); break;	\
+case 2: \
+asm volatile(op "w %0,%%gs:%c1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+case 4: \
+asm volatile(op "l %0,%%gs:%c1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+case 8: \
+asm volatile(op "q %0,%%gs:%c1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
        default: __bad_pda_field(); 					\
        } \
        } while (0)
@@ -59,9 +58,12 @@
 #define pda_from_op(op,field) ({ \
        typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \
        switch (sizeof_field(struct x8664_pda, field)) { 		\
-       case 2: asm volatile(op "w %%gs:" __STR2(pda_ ## field) ",%0":"=r" (ret__)::"memory"); break;	\
-       case 4: asm volatile(op "l %%gs:" __STR2(pda_ ## field) ",%0":"=r" (ret__)::"memory"); break;	\
-       case 8: asm volatile(op "q %%gs:" __STR2(pda_ ## field) ",%0":"=r" (ret__)::"memory"); break;	\
+case 2: \
+asm volatile(op "w %%gs:%c1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
+case 4: \
+asm volatile(op "l %%gs:%c1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
+case 8: \
+asm volatile(op "q %%gs:%c1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
        default: __bad_pda_field(); 					\
        } \
        ret__; })
diff -Nru a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h
--- a/include/asm-x86_64/percpu.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/percpu.h	Sun Jun 16 19:31:39 2002
@@ -1,6 +1,12 @@
-#ifndef __ARCH_I386_PERCPU__
-#define __ARCH_I386_PERCPU__
+#ifndef __ARCH_X8664_PERCPU__
+#define __ARCH_X8664_PERCPU__
 
-#include <asm-generic/percpu.h>
+#include <asm/pda.h>
 
-#endif /* __ARCH_I386_PERCPU__ */
+/* var is in discarded region: offset to particular copy we want */
+#define this_cpu(var)     (*RELOC_HIDE(&var, read_pda(cpudata_offset)))
+#define per_cpu(var, cpu) (*RELOC_HIDE(&var, per_cpu_pda[cpu]))
+
+void setup_per_cpu_areas(void);
+
+#endif /* __ARCH_X8664_PERCPU__ */
diff -Nru a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h
--- a/include/asm-x86_64/pgalloc.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/pgalloc.h	Sun Jun 16 19:31:40 2002
@@ -75,5 +75,7 @@
 	__free_page(pte);
 } 
 
+#define pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
+#define pmd_free_tlb(tlb,x)   do { } while (0)
 
 #endif /* _X86_64_PGALLOC_H */
diff -Nru a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
--- a/include/asm-x86_64/pgtable.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/pgtable.h	Sun Jun 16 19:31:39 2002
@@ -65,6 +65,7 @@
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
 
+
 #define pml4_none(x)	(!pml4_val(x))
 #define pgd_none(x)	(!pgd_val(x))
 
@@ -98,13 +99,8 @@
 #define pgd_page(pgd) \
 ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
 
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
-			__pmd_offset(address))
-
 #define ptep_get_and_clear(xp)	__pte(xchg(&(xp)->pte, 0))
 #define pte_same(a, b)		((a).pte == (b).pte)
-#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
 
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
@@ -202,7 +198,7 @@
 static inline unsigned long pgd_bad(pgd_t pgd) 
 { 
        unsigned long val = pgd_val(pgd);
-       val &= ~PAGE_MASK; 
+       val &= ~PTE_MASK; 
        val &= ~(_PAGE_USER | _PAGE_DIRTY); 
        return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED);      
 } 
@@ -211,14 +207,18 @@
 #define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(xp)	do { set_pte(xp, __pte(0)); } while (0)
 
-#define pmd_none(x)	(!pmd_val(x))
-#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
-#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
-#define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE )
-
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))	/* FIXME: is this
 						   right? */
-#define pte_page(x) (mem_map+((unsigned long)((pte_val(x) >> PAGE_SHIFT))))
+#define pte_page(x)	pfn_to_page(pte_pfn(x))
+#define pte_pfn(x)  ((pte_val(x) >> PAGE_SHIFT) & __PHYSICAL_MASK)
+
+static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
+{
+	pte_t pte;
+	pte_val(pte) = (page_nr << PAGE_SHIFT) | pgprot_val(pgprot); 
+	return pte;
+}
+
 
 /*
  * The following only work if pte_present() is true.
@@ -256,7 +256,7 @@
  * Level 4 access.
  * Never use these in the common code.
  */
-#define pml4_page(pml4) ((unsigned long) __va(pml4_val(pml4) & PAGE_MASK))
+#define pml4_page(pml4) ((unsigned long) __va(pml4_val(pml4) & PTE_MASK))
 #define pml4_index(address) ((address >> PML4_SHIFT) & (PTRS_PER_PML4-1))
 #define pml4_offset_k(address) (init_level4_pgt + pml4_index(address))
 #define mk_kernel_pml4(address) ((pml4_t){ (address) | _KERNPG_TABLE })
@@ -277,41 +277,42 @@
 	pml4_t pml4;
 
 	pml4 = init_level4_pgt[pml4_index(address)];
-	return __pgd_offset_k(__va(pml4_val(pml4) & PAGE_MASK), address);
+	return __pgd_offset_k(__va(pml4_val(pml4) & PTE_MASK), address);
 }
 
 #define __pgd_offset(address) pgd_index(address)
 #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
 
 /* PMD  - Level 2 access */
-#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-#define pmd_page(pmd)        (mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
-
-#define __pmd_offset(address) \
-		(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK))
+#define pmd_page(pmd)        (mem_map + ((pmd_val(pmd) & PTE_MASK)>>PAGE_SHIFT))
+#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
+			__pmd_offset(address))
+#define pmd_none(x)	(!pmd_val(x))
+#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
+#define	pmd_bad(x)	((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE )
+#define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
 
 /* PTE - Level 1 access. */
 
-#define mk_pte(page,pgprot) \
-({                                                                     \
-       pte_t __pte;                                                    \
-                                                                       \
-       set_pte(&__pte, __pte(((page)-mem_map) *                        \
-               (unsigned long long)PAGE_SIZE + pgprot_val(pgprot)));   \
-       __pte;                                                          \
-})
+/* page, protection -> pte */
+#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
  
-/* This takes a physical page address that is used by the remapping functions */
+/* physical address -> PTE */
 static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 { 
-       pte_t __pte; 
-       set_pte(&__pte, __pte(physpage + pgprot_val(pgprot))); 
-       return __pte;
+	pte_t pte;
+	pte_val(pte) = physpage | pgprot_val(pgprot); 
+	return pte; 
 }
  
+/* Change flags of a PTE */
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { 
-       set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); 
+	pte_val(pte) &= _PAGE_CHG_MASK;
+	pte_val(pte) |= pgprot_val(newprot);
        return pte; 
 }
 
diff -Nru a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
--- a/include/asm-x86_64/processor.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-x86_64/processor.h	Sun Jun 16 19:31:41 2002
@@ -84,17 +84,6 @@
 #define current_cpu_data boot_cpu_data
 #endif
 
-#define cpu_has_pge 1
-#define cpu_has_pse 1
-#define cpu_has_pae 1
-#define cpu_has_tsc 1
-#define cpu_has_de 1
-#define cpu_has_vme 1
-#define cpu_has_fxsr 1
-#define cpu_has_mmx 1
-#define cpu_has_xmm 1
-#define cpu_has_apic 1
-
 extern char ignore_irq13;
 
 extern void identify_cpu(struct cpuinfo_x86 *);
@@ -371,8 +360,6 @@
  */
 extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-/* Copy and release all segment info associated with a VM */
-extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
 extern void release_segments(struct mm_struct * mm);
 
 /*
diff -Nru a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h
--- a/include/asm-x86_64/ptrace.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/ptrace.h	Sun Jun 16 19:31:40 2002
@@ -85,6 +85,7 @@
 #define user_mode(regs) (!!((regs)->cs & 3))
 #define instruction_pointer(regs) ((regs)->rip)
 extern void show_regs(struct pt_regs *);
+void signal_fault(struct pt_regs *regs, void *frame, char *where);
 
 enum {
         EF_CF   = 0x00000001,
diff -Nru a/include/asm-x86_64/rwsem.h b/include/asm-x86_64/rwsem.h
--- a/include/asm-x86_64/rwsem.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-x86_64/rwsem.h	Sun Jun 16 19:31:41 2002
@@ -146,18 +146,18 @@
 	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
 	__asm__ __volatile__(
 		"# beginning __up_read\n\t"
-LOCK_PREFIX	"  xaddl      %%edx,(%%rdi)\n\t" /* subtracts 1, returns the old value */
+LOCK_PREFIX	"  xaddl      %[tmp],(%%rdi)\n\t" /* subtracts 1, returns the old value */
 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
 		LOCK_SECTION_START("")
 		"2:\n\t"
-		"  decw      %%dx\n\t" /* do nothing if still outstanding active readers */
+		"  decw      %w[tmp]\n\t" /* do nothing if still outstanding active readers */
 		"  jnz       1b\n\t"
 		"  call      rwsem_wake_thunk\n\t"
 		"  jmp       1b\n"
 		LOCK_SECTION_END
 		"# ending __up_read\n"
-		: "+m"(sem->count), "+d"(tmp)
+		: "+m"(sem->count), "+r" (tmp)
 		: "D"(sem)
 		: "memory", "cc");
 }
@@ -167,23 +167,24 @@
  */
 static inline void __up_write(struct rw_semaphore *sem)
 {
+	unsigned tmp; 
 	__asm__ __volatile__(
 		"# beginning __up_write\n\t"
-		"  movl      %2,%%edx\n\t"
-LOCK_PREFIX	"  xaddl     %%edx,(%%rdi)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
+		"  movl      %2,%[tmp]\n\t"
+LOCK_PREFIX	"  xaddl     %[tmp],(%%rdi)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
 		LOCK_SECTION_START("")
 		"2:\n\t"
-		"  decw      %%dx\n\t" /* did the active count reduce to 0? */
+		"  decw      %w[tmp]\n\t" /* did the active count reduce to 0? */
 		"  jnz       1b\n\t" /* jump back if not */
 		"  call      rwsem_wake_thunk\n\t"
 		"  jmp       1b\n"
 		LOCK_SECTION_END
 		"# ending __up_write\n"
-		: "+m"(sem->count)
+		: "+m"(sem->count), [tmp] "r" (tmp)
 		: "D"(sem), "i"(-RWSEM_ACTIVE_WRITE_BIAS)
-		: "memory", "cc", "rdx");
+		: "memory", "cc");
 }
 
 /*
diff -Nru a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h
--- a/include/asm-x86_64/signal.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/signal.h	Sun Jun 16 19:31:39 2002
@@ -1,6 +1,7 @@
 #ifndef _ASMx8664_SIGNAL_H
 #define _ASMx8664_SIGNAL_H
 
+#ifndef __ASSEMBLY__
 #include <linux/types.h>
 #include <linux/linkage.h>
 
@@ -33,6 +34,7 @@
 typedef unsigned long sigset_t;
 
 #endif /* __KERNEL__ */
+#endif
 
 #define SIGHUP		 1
 #define SIGINT		 2
@@ -131,6 +133,7 @@
 #define SIG_UNBLOCK        1	/* for unblocking signals */
 #define SIG_SETMASK        2	/* for setting the signal mask */
 
+#ifndef __ASSEMBLY__
 /* Type of a signal handler.  */
 typedef void (*__sighandler_t)(int);
 
@@ -199,6 +202,7 @@
 	__asm__("bsfq %1,%0" : "=r"(word) : "rm"(word) : "cc");
 	return word;
 }
+#endif
 #endif
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-x86_64/softirq.h b/include/asm-x86_64/softirq.h
--- a/include/asm-x86_64/softirq.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-x86_64/softirq.h	Sun Jun 16 19:31:41 2002
@@ -26,7 +26,8 @@
 		"2: call do_softirq_thunk;"					\
 		"jmp 1b;"							\
 		".previous" 							\
-		:: "i" (pda___softirq_pending), "i" (pda___local_bh_count) : \
+		:: "i" (pda_offset(__softirq_pending)), \
+		   "i" (pda_offset(__local_bh_count)) : \
 		"memory");	\
 } while (0)
 #define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while(0)
diff -Nru a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
--- a/include/asm-x86_64/spinlock.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-x86_64/spinlock.h	Sun Jun 16 19:31:41 2002
@@ -9,30 +9,20 @@
 extern int printk(const char * fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
 
-/* It seems that people are forgetting to
- * initialize their spinlocks properly, tsk tsk.
- * Remember to turn this off in 2.4. -ben
- */
-#if defined(CONFIG_DEBUG_SPINLOCK)
-#define SPINLOCK_DEBUG	1
-#else
-#define SPINLOCK_DEBUG	0
-#endif
-
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  */
 
 typedef struct {
 	volatile unsigned int lock;
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
 } spinlock_t;
 
 #define SPINLOCK_MAGIC	0xdead4ead
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 #define SPINLOCK_MAGIC_INIT	, SPINLOCK_MAGIC
 #else
 #define SPINLOCK_MAGIC_INIT	/* */
@@ -82,7 +72,7 @@
 
 static inline void _raw_spin_lock(spinlock_t *lock)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	__label__ here;
 here:
 	if (lock->magic != SPINLOCK_MAGIC) {
@@ -97,7 +87,7 @@
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	if (lock->magic != SPINLOCK_MAGIC)
 		BUG();
 	if (!spin_is_locked(lock))
@@ -120,14 +110,14 @@
  */
 typedef struct {
 	volatile unsigned int lock;
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
 } rwlock_t;
 
 #define RWLOCK_MAGIC	0xdeaf1eed
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 #define RWLOCK_MAGIC_INIT	, RWLOCK_MAGIC
 #else
 #define RWLOCK_MAGIC_INIT	/* */
@@ -150,7 +140,7 @@
 
 extern inline void _raw_read_lock(rwlock_t *rw)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	if (rw->magic != RWLOCK_MAGIC)
 		BUG();
 #endif
@@ -159,7 +149,7 @@
 
 static inline void _raw_write_lock(rwlock_t *rw)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	if (rw->magic != RWLOCK_MAGIC)
 		BUG();
 #endif
diff -Nru a/include/asm-x86_64/string.h b/include/asm-x86_64/string.h
--- a/include/asm-x86_64/string.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/string.h	Sun Jun 16 19:31:40 2002
@@ -2,36 +2,76 @@
 #define _X86_64_STRING_H_
 
 #ifdef __KERNEL__
-#include <linux/config.h>
 
 #define struct_cpy(x,y) (*(x)=*(y))
 
-#define __HAVE_ARCH_MEMCMP
-#define __HAVE_ARCH_STRLEN
+/* Written 2002 by Andi Kleen */ 
 
-#define memset __builtin_memset
-#define memcpy __builtin_memcpy
-#define memcmp __builtin_memcmp
-
-/* Work around "undefined reference to strlen" linker errors.  */
-/* #define strlen __builtin_strlen */
-
-#define __HAVE_ARCH_STRLEN
-static inline size_t strlen(const char * s)
+/* Only used for special circumstances. Stolen from i386/string.h */ 
+static inline void * __inline_memcpy(void * to, const void * from, size_t n)
 {
-int d0;
-register int __res;
+unsigned long d0, d1, d2;
 __asm__ __volatile__(
-	"repne\n\t"
-	"scasb\n\t"
-	"notl %0\n\t"
-	"decl %0"
-	:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
-return __res;
+	"rep ; movsl\n\t"
+	"testb $2,%b4\n\t"
+	"je 1f\n\t"
+	"movsw\n"
+	"1:\ttestb $1,%b4\n\t"
+	"je 2f\n\t"
+	"movsb\n"
+	"2:"
+	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
+	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+	: "memory");
+return (to);
 }
 
+/* Even with __builtin_ the compiler may decide to use the out of line
+   function. */
+
+#define __HAVE_ARCH_MEMCPY 1
+extern void *__memcpy(void *to, const void *from, size_t len); 
+#define memcpy(dst,src,len) \
+	({ size_t __len = (len);				\
+	   void *__ret;						\
+	   if (__builtin_constant_p(len) && __len >= 64)	\
+		 __ret = __memcpy((dst),(src),__len);		\
+	   else							\
+		 __ret = __builtin_memcpy((dst),(src),__len);	\
+	   __ret; }) 
+
+#if 0
+#define __HAVE_ARCH_MEMSET
+extern void *__memset(void *mem, int val, size_t len); 
+#define memset(dst,val,len)					\
+	({ size_t __len = (len);				\
+	   void *__ret;						\
+	   if (__builtin_constant_p(len) && __len >= 64)	\
+		   __ret = __memset((dst),(val),__len);		\
+	   else							\
+		   __ret = __builtin_memset((dst),(val),__len);	\
+	   __ret; }) 
+#endif	   
+
+#define __HAVE_ARCH_MEMMOVE
+void * memmove(void * dest,const void *src,size_t count);
+
+/* Use C out of line version for memcmp */ 
+#define memcmp __builtin_memcmp
+int memcmp(const void * cs,const void * ct,size_t count);
+
+/* out of line string functions use always C versions */ 
+#define strlen __builtin_strlen
+size_t strlen(const char * s);
+
+#define strcpy __builtin_strcpy
+char * strcpy(char * dest,const char *src);
+
+#define strcat __builtin_strcat
+char * strcat(char * dest, const char * src);
 
-extern char *strstr(const char *cs, const char *ct);
+#define strcmp __builtin_strcmp
+int strcmp(const char * cs,const char * ct);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
--- a/include/asm-x86_64/thread_info.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/thread_info.h	Sun Jun 16 19:31:39 2002
@@ -51,6 +51,8 @@
 
 /* how to get the thread information struct from C */
 
+#define THREAD_SIZE (2*PAGE_SIZE)
+
 static inline struct thread_info *current_thread_info(void)
 { 
 	struct thread_info *ti;
@@ -66,7 +68,6 @@
 }
 
 /* thread information allocation */
-#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)->task)
@@ -75,6 +76,7 @@
 #else /* !__ASSEMBLY__ */
 
 /* how to get the thread information struct from ASM */
+/* only works on the process stack. otherwise get it via the PDA. */
 #define GET_THREAD_INFO(reg) \
 	movq $-8192, reg; \
 	andq %rsp, reg
diff -Nru a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h
--- a/include/asm-x86_64/timex.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/timex.h	Sun Jun 16 19:31:39 2002
@@ -48,4 +48,6 @@
 
 extern unsigned int cpu_khz;
 
+#define ARCH_HAS_JIFFIES_64
+
 #endif
diff -Nru a/include/asm-x86_64/tlb.h b/include/asm-x86_64/tlb.h
--- a/include/asm-x86_64/tlb.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/tlb.h	Sun Jun 16 19:31:39 2002
@@ -1 +1,13 @@
+#ifndef TLB_H
+#define TLB_H 1
+
+
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
 #include <asm-generic/tlb.h>
+
+#endif
diff -Nru a/include/asm-x86_64/types.h b/include/asm-x86_64/types.h
--- a/include/asm-x86_64/types.h	Sun Jun 16 19:31:40 2002
+++ b/include/asm-x86_64/types.h	Sun Jun 16 19:31:40 2002
@@ -17,8 +17,8 @@
 typedef __signed__ int __s32;
 typedef unsigned int __u32;
 
-typedef __signed__ long __s64;
-typedef unsigned long  __u64;
+typedef __signed__ long long __s64;
+typedef unsigned long long  __u64;
 
 /*
  * These aren't exported outside the kernel to avoid name space clashes
@@ -34,8 +34,8 @@
 typedef signed int s32;
 typedef unsigned int u32;
 
-typedef signed long s64;
-typedef unsigned long u64;
+typedef signed long long s64;
+typedef unsigned long long u64;
 
 #define BITS_PER_LONG 64
 
diff -Nru a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
--- a/include/asm-x86_64/uaccess.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/uaccess.h	Sun Jun 16 19:31:39 2002
@@ -230,138 +230,19 @@
 
 /*
  * Copy To/From Userspace
+ * 
+ * This relies on an optimized common worker function.
+ * 
+ * Could do special inline versions for small constant copies, but avoid this
+ * for now. It's not clear it is worth it. 
  */
 
-/* Generic arbitrary sized copy.  */
+extern unsigned long copy_user_generic(void *to, const void *from, unsigned len); 
 
-/* Could do 8byte accesses, instead of 4bytes. */ 
-
-/* Generic arbitrary sized copy.  */
-#define __copy_user(to,from,size)					\
-do {									\
-	long __d0, __d1;						\
-	__asm__ __volatile__(						\
-		"0:	rep; movsl\n"					\
-		"	movq %3,%0\n"					\
-		"1:	rep; movsb\n"					\
-		"2:\n"							\
-		".section .fixup,\"ax\"\n"				\
-		"3:	lea 0(%3,%0,4),%0\n"				\
-		"	jmp 2b\n"					\
-		".previous\n"						\
-		".section __ex_table,\"a\"\n"				\
-		"	.align 8\n"					\
-		"	.quad 0b,3b\n"					\
-		"	.quad 1b,2b\n"					\
-		".previous"						\
-		: "=&c"(size), "=&D" (__d0), "=&S" (__d1)		\
-		: "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)	\
-		: "memory");						\
-} while (0)
-
-#define __copy_user_zeroing(to,from,size)				\
-do {									\
-	long __d0, __d1;						\
-	__asm__ __volatile__(						\
-		"0:	rep; movsl\n"					\
-		"	movq %3,%0\n"					\
-		"1:	rep; movsb\n"					\
-		"2:\n"							\
-		".section .fixup,\"ax\"\n"				\
-		"3:	lea 0(%3,%0,4),%0\n"				\
-		"4:	pushq %0\n"					\
-		"	pushq %%rax\n"					\
-		"	xorq %%rax,%%rax\n"				\
-		"	rep; stosb\n"					\
-		"	popq %%rax\n"					\
-		"	popq %0\n"					\
-		"	jmp 2b\n"					\
-		".previous\n"						\
-		".section __ex_table,\"a\"\n"				\
-		"	.align 8\n"					\
-		"	.quad 0b,3b\n"					\
-		"	.quad 1b,4b\n"					\
-		".previous"						\
-		: "=&c"(size), "=&D" (__d0), "=&S" (__d1)		\
-		: "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)	\
-		: "memory");						\
-} while (0)
-
-
-/* We let the __ versions of copy_from/to_user inline, because they're often
- * used in fast paths and have only a small space overhead.
- */
-static inline unsigned long
-__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
-{
-	__copy_user_zeroing(to,from,n);
-	return n;
-}
-
-static inline unsigned long
-__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
-{
-	prefetch(from);
-	__copy_user(to,from,n);
-	return n;
-}
-
-
-
-unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
-unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
-
-static inline unsigned long
-__constant_copy_to_user(void *to, const void *from, unsigned long n)
-{
-	if (access_ok(VERIFY_WRITE, to, n))
-		__copy_user(to,from,n);
-	return n;
-}
-
-static inline unsigned long
-__constant_copy_from_user(void *to, const void *from, unsigned long n)
-{
-	if (access_ok(VERIFY_READ, from, n))
-		__copy_user_zeroing(to,from,n);
-	else
-		memset(to, 0, n);
-	return n;
-}
-
-static inline unsigned long
-__constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
-{
-	__copy_user(to,from,n);
-	return n;
-}
-
-static inline unsigned long
-__constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
-{
-	__copy_user_zeroing(to,from,n);
-	return n;
-}
-
-#define copy_to_user(to,from,n)				\
-	(__builtin_constant_p(n) ?			\
-	 __constant_copy_to_user((to),(from),(n)) :	\
-	 __generic_copy_to_user((to),(from),(n)))
-
-#define copy_from_user(to,from,n)			\
-	(__builtin_constant_p(n) ?			\
-	 __constant_copy_from_user((to),(from),(n)) :	\
-	 __generic_copy_from_user((to),(from),(n)))
-
-#define __copy_to_user(to,from,n)			\
-	(__builtin_constant_p(n) ?			\
-	 __constant_copy_to_user_nocheck((to),(from),(n)) :	\
-	 __generic_copy_to_user_nocheck((to),(from),(n)))
-
-#define __copy_from_user(to,from,n)			\
-	(__builtin_constant_p(n) ?			\
-	 __constant_copy_from_user_nocheck((to),(from),(n)) :	\
-	 __generic_copy_from_user_nocheck((to),(from),(n)))
+extern unsigned long copy_to_user(void *to, const void *from, unsigned len); 
+extern unsigned long copy_from_user(void *to, const void *from, unsigned len); 
+#define __copy_to_user copy_user_generic
+#define __copy_from_user copy_user_generic
 
 long strncpy_from_user(char *dst, const char *src, long count);
 long __strncpy_from_user(char *dst, const char *src, long count);
diff -Nru a/include/asm-x86_64/user.h b/include/asm-x86_64/user.h
--- a/include/asm-x86_64/user.h	Sun Jun 16 19:31:41 2002
+++ b/include/asm-x86_64/user.h	Sun Jun 16 19:31:41 2002
@@ -84,6 +84,7 @@
 /* ptrace does not yet supply these.  Someday.... */
   int u_fpvalid;		/* True if math co-processor being used. */
                                 /* for this mess. Not yet used. */
+  int pad0;
   struct user_i387_struct i387;	/* Math Co-processor registers. */
 /* The rest of this junk is to help gdb figure out what goes where */
   unsigned long int u_tsize;	/* Text segment size (pages). */
@@ -96,12 +97,15 @@
 				   esp register.  */
   long int signal;     		/* Signal that caused the core dump. */
   int reserved;			/* No longer used */
+  int pad1;
   struct user_pt_regs * u_ar0;	/* Used by gdb to help find the values for */
 				/* the registers. */
   struct user_i387_struct* u_fpstate;	/* Math Co-processor pointer. */
   unsigned long magic;		/* To uniquely identify a core file */
   char u_comm[32];		/* User command that was responsible */
   unsigned long u_debugreg[8];
+  unsigned long error_code; /* CPU error code or 0 */
+  unsigned long fault_address; /* CR3 or 0 */
 };
 #define NBPG PAGE_SIZE
 #define UPAGES 1
diff -Nru a/include/asm-x86_64/xor.h b/include/asm-x86_64/xor.h
--- a/include/asm-x86_64/xor.h	Sun Jun 16 19:31:39 2002
+++ b/include/asm-x86_64/xor.h	Sun Jun 16 19:31:39 2002
@@ -1,5 +1,5 @@
 /*
- * include/asm-i386/xor.h
+ * include/asm-x86_64/xor.h
  *
  * Optimized RAID-5 checksumming functions for MMX and SSE.
  *
@@ -13,525 +13,32 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+
 /*
- * High-speed RAID5 checksumming functions utilizing MMX instructions.
- * Copyright (C) 1998 Ingo Molnar.
+ * Cache avoiding checksumming functions utilizing KNI instructions
+ * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
  */
 
-#define FPU_SAVE							\
-  do {									\
-	if (!test_thread_flag(TIF_USEDFPU))				\
-		__asm__ __volatile__ (" clts;\n");			\
-	__asm__ __volatile__ ("fsave %0; fwait": "=m"(fpu_save[0]));	\
-  } while (0)
-
-#define FPU_RESTORE							\
-  do {									\
-	__asm__ __volatile__ ("frstor %0": : "m"(fpu_save[0]));		\
-	if (!test_thread_flag(TIF_USEDFPU))				\
-		stts();							\
-  } while (0)
-
-#define LD(x,y)		"       movq   8*("#x")(%1), %%mm"#y"   ;\n"
-#define ST(x,y)		"       movq %%mm"#y",   8*("#x")(%1)   ;\n"
-#define XO1(x,y)	"       pxor   8*("#x")(%2), %%mm"#y"   ;\n"
-#define XO2(x,y)	"       pxor   8*("#x")(%3), %%mm"#y"   ;\n"
-#define XO3(x,y)	"       pxor   8*("#x")(%4), %%mm"#y"   ;\n"
-#define XO4(x,y)	"       pxor   8*("#x")(%5), %%mm"#y"   ;\n"
-
-
-static void
-xor_pII_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-{
-	unsigned long lines = bytes >> 7;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
-	LD(i,0)					\
-		LD(i+1,1)			\
-			LD(i+2,2)		\
-				LD(i+3,3)	\
-	XO1(i,0)				\
-	ST(i,0)					\
-		XO1(i+1,1)			\
-		ST(i+1,1)			\
-			XO1(i+2,2)		\
-			ST(i+2,2)		\
-				XO1(i+3,3)	\
-				ST(i+3,3)
-
-	" .align 32			;\n"
-  	" 1:                            ;\n"
-
-	BLOCK(0)
-	BLOCK(4)
-	BLOCK(8)
-	BLOCK(12)
-
-	"       addq $128, %1         ;\n"
-	"       addq $128, %2         ;\n"
-	"       decq %0               ;\n"
-	"       jnz 1b                ;\n"
-       	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2)
-	: "memory");
-
-	FPU_RESTORE;
-}
-
-static void
-xor_pII_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-	      unsigned long *p3)
-{
-	unsigned long lines = bytes >> 7;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
-	LD(i,0)					\
-		LD(i+1,1)			\
-			LD(i+2,2)		\
-				LD(i+3,3)	\
-	XO1(i,0)				\
-		XO1(i+1,1)			\
-			XO1(i+2,2)		\
-				XO1(i+3,3)	\
-	XO2(i,0)				\
-	ST(i,0)					\
-		XO2(i+1,1)			\
-		ST(i+1,1)			\
-			XO2(i+2,2)		\
-			ST(i+2,2)		\
-				XO2(i+3,3)	\
-				ST(i+3,3)
-
-	" .align 32			;\n"
-	" 1:                            ;\n"
-
-	BLOCK(0)
-	BLOCK(4)
-	BLOCK(8)
-	BLOCK(12)
-
-	"       addq $128, %1         ;\n"
-	"       addq $128, %2         ;\n"
-	"       addq $128, %3         ;\n"
-	"       decq %0               ;\n"
-	"       jnz 1b                ;\n"
-       	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3)
-	: "memory");
-
-	FPU_RESTORE;
-}
-
-static void
-xor_pII_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-	      unsigned long *p3, unsigned long *p4)
-{
-	unsigned long lines = bytes >> 7;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
-	LD(i,0)					\
-		LD(i+1,1)			\
-			LD(i+2,2)		\
-				LD(i+3,3)	\
-	XO1(i,0)				\
-		XO1(i+1,1)			\
-			XO1(i+2,2)		\
-				XO1(i+3,3)	\
-	XO2(i,0)				\
-		XO2(i+1,1)			\
-			XO2(i+2,2)		\
-				XO2(i+3,3)	\
-	XO3(i,0)				\
-	ST(i,0)					\
-		XO3(i+1,1)			\
-		ST(i+1,1)			\
-			XO3(i+2,2)		\
-			ST(i+2,2)		\
-				XO3(i+3,3)	\
-				ST(i+3,3)
-
-	" .align 32			;\n"
-	" 1:                            ;\n"
-
-	BLOCK(0)
-	BLOCK(4)
-	BLOCK(8)
-	BLOCK(12)
-
-	"       addq $128, %1         ;\n"
-	"       addq $128, %2         ;\n"
-	"       addq $128, %3         ;\n"
-	"       addq $128, %4         ;\n"
-	"       decq %0               ;\n"
-	"       jnz 1b                ;\n"
-       	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4)
-	: "memory");
-
-	FPU_RESTORE;
-}
-
-static void
-xor_pII_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-	      unsigned long *p3, unsigned long *p4, unsigned long *p5)
-{
-	unsigned long lines = bytes >> 7;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
-	LD(i,0)					\
-		LD(i+1,1)			\
-			LD(i+2,2)		\
-				LD(i+3,3)	\
-	XO1(i,0)				\
-		XO1(i+1,1)			\
-			XO1(i+2,2)		\
-				XO1(i+3,3)	\
-	XO2(i,0)				\
-		XO2(i+1,1)			\
-			XO2(i+2,2)		\
-				XO2(i+3,3)	\
-	XO3(i,0)				\
-		XO3(i+1,1)			\
-			XO3(i+2,2)		\
-				XO3(i+3,3)	\
-	XO4(i,0)				\
-	ST(i,0)					\
-		XO4(i+1,1)			\
-		ST(i+1,1)			\
-			XO4(i+2,2)		\
-			ST(i+2,2)		\
-				XO4(i+3,3)	\
-				ST(i+3,3)
-
-	" .align 32			;\n"
-	" 1:                            ;\n"
-
-	BLOCK(0)
-	BLOCK(4)
-	BLOCK(8)
-	BLOCK(12)
-
-	"       addq $128, %1         ;\n"
-	"       addq $128, %2         ;\n"
-	"       addq $128, %3         ;\n"
-	"       addq $128, %4         ;\n"
-	"       addq $128, %5         ;\n"
-	"       decq %0               ;\n"
-	"       jnz 1b                ;\n"
-       	:
-	: "g" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
-	: "memory");
-
-	FPU_RESTORE;
-}
-
-#undef LD
-#undef XO1
-#undef XO2
-#undef XO3
-#undef XO4
-#undef ST
-#undef BLOCK
-
-static void
-xor_p5_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-{
-	unsigned long lines = bytes >> 6;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-	" .align 32	             ;\n"
-	" 1:                         ;\n"
-	"       movq   (%1), %%mm0   ;\n"
-	"       movq  8(%1), %%mm1   ;\n"
-	"       pxor   (%2), %%mm0   ;\n"
-	"       movq 16(%1), %%mm2   ;\n"
-	"       movq %%mm0,   (%1)   ;\n"
-	"       pxor  8(%2), %%mm1   ;\n"
-	"       movq 24(%1), %%mm3   ;\n"
-	"       movq %%mm1,  8(%1)   ;\n"
-	"       pxor 16(%2), %%mm2   ;\n"
-	"       movq 32(%1), %%mm4   ;\n"
-	"       movq %%mm2, 16(%1)   ;\n"
-	"       pxor 24(%2), %%mm3   ;\n"
-	"       movq 40(%1), %%mm5   ;\n"
-	"       movq %%mm3, 24(%1)   ;\n"
-	"       pxor 32(%2), %%mm4   ;\n"
-	"       movq 48(%1), %%mm6   ;\n"
-	"       movq %%mm4, 32(%1)   ;\n"
-	"       pxor 40(%2), %%mm5   ;\n"
-	"       movq 56(%1), %%mm7   ;\n"
-	"       movq %%mm5, 40(%1)   ;\n"
-	"       pxor 48(%2), %%mm6   ;\n"
-	"       pxor 56(%2), %%mm7   ;\n"
-	"       movq %%mm6, 48(%1)   ;\n"
-	"       movq %%mm7, 56(%1)   ;\n"
-	
-	"       addq $64, %1         ;\n"
-	"       addq $64, %2         ;\n"
-	"       decq %0              ;\n"
-	"       jnz 1b               ;\n"
-	: 
-	: "r" (lines),
-	  "r" (p1), "r" (p2)
-	: "memory");
-
-	FPU_RESTORE;
-}
-
-static void
-xor_p5_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-	     unsigned long *p3)
-{
-	unsigned long lines = bytes >> 6;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-	" .align 32,0x90             ;\n"
-	" 1:                         ;\n"
-	"       movq   (%1), %%mm0   ;\n"
-	"       movq  8(%1), %%mm1   ;\n"
-	"       pxor   (%2), %%mm0   ;\n"
-	"       movq 16(%1), %%mm2   ;\n"
-	"       pxor  8(%2), %%mm1   ;\n"
-	"       pxor   (%3), %%mm0   ;\n"
-	"       pxor 16(%2), %%mm2   ;\n"
-	"       movq %%mm0,   (%1)   ;\n"
-	"       pxor  8(%3), %%mm1   ;\n"
-	"       pxor 16(%3), %%mm2   ;\n"
-	"       movq 24(%1), %%mm3   ;\n"
-	"       movq %%mm1,  8(%1)   ;\n"
-	"       movq 32(%1), %%mm4   ;\n"
-	"       movq 40(%1), %%mm5   ;\n"
-	"       pxor 24(%2), %%mm3   ;\n"
-	"       movq %%mm2, 16(%1)   ;\n"
-	"       pxor 32(%2), %%mm4   ;\n"
-	"       pxor 24(%3), %%mm3   ;\n"
-	"       pxor 40(%2), %%mm5   ;\n"
-	"       movq %%mm3, 24(%1)   ;\n"
-	"       pxor 32(%3), %%mm4   ;\n"
-	"       pxor 40(%3), %%mm5   ;\n"
-	"       movq 48(%1), %%mm6   ;\n"
-	"       movq %%mm4, 32(%1)   ;\n"
-	"       movq 56(%1), %%mm7   ;\n"
-	"       pxor 48(%2), %%mm6   ;\n"
-	"       movq %%mm5, 40(%1)   ;\n"
-	"       pxor 56(%2), %%mm7   ;\n"
-	"       pxor 48(%3), %%mm6   ;\n"
-	"       pxor 56(%3), %%mm7   ;\n"
-	"       movq %%mm6, 48(%1)   ;\n"
-	"       movq %%mm7, 56(%1)   ;\n"
-      
-	"       addq $64, %1         ;\n"
-	"       addq $64, %2         ;\n"
-	"       addq $64, %3         ;\n"
-	"       decq %0              ;\n"
-	"       jnz 1b               ;\n"
-	: 
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3)
-	: "memory" );
-
-	FPU_RESTORE;
-}
-
-static void
-xor_p5_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-	     unsigned long *p3, unsigned long *p4)
-{
-	unsigned long lines = bytes >> 6;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-	" .align 32,0x90             ;\n"
-	" 1:                         ;\n"
-	"       movq   (%1), %%mm0   ;\n"
-	"       movq  8(%1), %%mm1   ;\n"
-	"       pxor   (%2), %%mm0   ;\n"
-	"       movq 16(%1), %%mm2   ;\n"
-	"       pxor  8(%2), %%mm1   ;\n"
-	"       pxor   (%3), %%mm0   ;\n"
-	"       pxor 16(%2), %%mm2   ;\n"
-	"       pxor  8(%3), %%mm1   ;\n"
-	"       pxor   (%4), %%mm0   ;\n"
-	"       movq 24(%1), %%mm3   ;\n"
-	"       pxor 16(%3), %%mm2   ;\n"
-	"       pxor  8(%4), %%mm1   ;\n"
-	"       movq %%mm0,   (%1)   ;\n"
-	"       movq 32(%1), %%mm4   ;\n"
-	"       pxor 24(%2), %%mm3   ;\n"
-	"       pxor 16(%4), %%mm2   ;\n"
-	"       movq %%mm1,  8(%1)   ;\n"
-	"       movq 40(%1), %%mm5   ;\n"
-	"       pxor 32(%2), %%mm4   ;\n"
-	"       pxor 24(%3), %%mm3   ;\n"
-	"       movq %%mm2, 16(%1)   ;\n"
-	"       pxor 40(%2), %%mm5   ;\n"
-	"       pxor 32(%3), %%mm4   ;\n"
-	"       pxor 24(%4), %%mm3   ;\n"
-	"       movq %%mm3, 24(%1)   ;\n"
-	"       movq 56(%1), %%mm7   ;\n"
-	"       movq 48(%1), %%mm6   ;\n"
-	"       pxor 40(%3), %%mm5   ;\n"
-	"       pxor 32(%4), %%mm4   ;\n"
-	"       pxor 48(%2), %%mm6   ;\n"
-	"       movq %%mm4, 32(%1)   ;\n"
-	"       pxor 56(%2), %%mm7   ;\n"
-	"       pxor 40(%4), %%mm5   ;\n"
-	"       pxor 48(%3), %%mm6   ;\n"
-	"       pxor 56(%3), %%mm7   ;\n"
-	"       movq %%mm5, 40(%1)   ;\n"
-	"       pxor 48(%4), %%mm6   ;\n"
-	"       pxor 56(%4), %%mm7   ;\n"
-	"       movq %%mm6, 48(%1)   ;\n"
-	"       movq %%mm7, 56(%1)   ;\n"
-      
-	"       addq $64, %1         ;\n"
-	"       addq $64, %2         ;\n"
-	"       addq $64, %3         ;\n"
-	"       addq $64, %4         ;\n"
-	"       decq %0              ;\n"
-	"       jnz 1b               ;\n"
-	: 
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4)
-	: "memory");
-
-	FPU_RESTORE;
-}
-
-static void
-xor_p5_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-	     unsigned long *p3, unsigned long *p4, unsigned long *p5)
-{
-	unsigned long lines = bytes >> 6;
-	char fpu_save[108];
-
-	FPU_SAVE;
-
-	__asm__ __volatile__ (
-	" .align 32,0x90             ;\n"
-	" 1:                         ;\n"
-	"       movq   (%1), %%mm0   ;\n"
-	"       movq  8(%1), %%mm1   ;\n"
-	"       pxor   (%2), %%mm0   ;\n"
-	"       pxor  8(%2), %%mm1   ;\n"
-	"       movq 16(%1), %%mm2   ;\n"
-	"       pxor   (%3), %%mm0   ;\n"
-	"       pxor  8(%3), %%mm1   ;\n"
-	"       pxor 16(%2), %%mm2   ;\n"
-	"       pxor   (%4), %%mm0   ;\n"
-	"       pxor  8(%4), %%mm1   ;\n"
-	"       pxor 16(%3), %%mm2   ;\n"
-	"       movq 24(%1), %%mm3   ;\n"
-	"       pxor   (%5), %%mm0   ;\n"
-	"       pxor  8(%5), %%mm1   ;\n"
-	"       movq %%mm0,   (%1)   ;\n"
-	"       pxor 16(%4), %%mm2   ;\n"
-	"       pxor 24(%2), %%mm3   ;\n"
-	"       movq %%mm1,  8(%1)   ;\n"
-	"       pxor 16(%5), %%mm2   ;\n"
-	"       pxor 24(%3), %%mm3   ;\n"
-	"       movq 32(%1), %%mm4   ;\n"
-	"       movq %%mm2, 16(%1)   ;\n"
-	"       pxor 24(%4), %%mm3   ;\n"
-	"       pxor 32(%2), %%mm4   ;\n"
-	"       movq 40(%1), %%mm5   ;\n"
-	"       pxor 24(%5), %%mm3   ;\n"
-	"       pxor 32(%3), %%mm4   ;\n"
-	"       pxor 40(%2), %%mm5   ;\n"
-	"       movq %%mm3, 24(%1)   ;\n"
-	"       pxor 32(%4), %%mm4   ;\n"
-	"       pxor 40(%3), %%mm5   ;\n"
-	"       movq 48(%1), %%mm6   ;\n"
-	"       movq 56(%1), %%mm7   ;\n"
-	"       pxor 32(%5), %%mm4   ;\n"
-	"       pxor 40(%4), %%mm5   ;\n"
-	"       pxor 48(%2), %%mm6   ;\n"
-	"       pxor 56(%2), %%mm7   ;\n"
-	"       movq %%mm4, 32(%1)   ;\n"
-	"       pxor 48(%3), %%mm6   ;\n"
-	"       pxor 56(%3), %%mm7   ;\n"
-	"       pxor 40(%5), %%mm5   ;\n"
-	"       pxor 48(%4), %%mm6   ;\n"
-	"       pxor 56(%4), %%mm7   ;\n"
-	"       movq %%mm5, 40(%1)   ;\n"
-	"       pxor 48(%5), %%mm6   ;\n"
-	"       pxor 56(%5), %%mm7   ;\n"
-	"       movq %%mm6, 48(%1)   ;\n"
-	"       movq %%mm7, 56(%1)   ;\n"
-      
-	"       addq $64, %1         ;\n"
-	"       addq $64, %2         ;\n"
-	"       addq $64, %3         ;\n"
-	"       addq $64, %4         ;\n"
-	"       addq $64, %5         ;\n"
-	"       decq %0              ;\n"
-	"       jnz 1b               ;\n"
-	: 
-	: "g" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
-	: "memory");
-
-	FPU_RESTORE;
-}
-
-static struct xor_block_template xor_block_pII_mmx = {
-	name: "pII_mmx",
-	do_2: xor_pII_mmx_2,
-	do_3: xor_pII_mmx_3,
-	do_4: xor_pII_mmx_4,
-	do_5: xor_pII_mmx_5,
-};
-
-static struct xor_block_template xor_block_p5_mmx = {
-	name: "p5_mmx",
-	do_2: xor_p5_mmx_2,
-	do_3: xor_p5_mmx_3,
-	do_4: xor_p5_mmx_4,
-	do_5: xor_p5_mmx_5,
-};
-
-#undef FPU_SAVE
-#undef FPU_RESTORE
+/*
+ * Based on
+ * High-speed RAID5 checksumming functions utilizing SSE instructions.
+ * Copyright (C) 1998 Ingo Molnar.
+ */
 
 /*
- * Cache avoiding checksumming functions utilizing KNI instructions
- * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
+ * x86-64 changes / gcc fixes from Andi Kleen. 
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ *
+ * This hasn't been optimized for the hammer yet, but there are likely
+ * no advantages to be gotten from x86-64 here anyways.
  */
 
+typedef struct { unsigned long a,b; } __attribute__((aligned(16))) xmm_store_t;
+
+/* Doesn't use gcc to save the XMM registers, because there is no easy way to 
+   tell it to do a clts before the register saving. */
 #define XMMS_SAVE				\
-	__asm__ __volatile__ ( 			\
+	asm volatile ( 			\
 		"movq %%cr0,%0		;\n\t"	\
 		"clts			;\n\t"	\
 		"movups %%xmm0,(%1)	;\n\t"	\
@@ -543,7 +50,7 @@
 		: "memory")
 
 #define XMMS_RESTORE				\
-	__asm__ __volatile__ ( 			\
+	asm volatile ( 			\
 		"sfence			;\n\t"	\
 		"movups (%1),%%xmm0	;\n\t"	\
 		"movups 0x10(%1),%%xmm1	;\n\t"	\
@@ -556,31 +63,31 @@
 
 #define OFFS(x)		"16*("#x")"
 #define PF_OFFS(x)	"256+16*("#x")"
-#define	PF0(x)		"	prefetchnta "PF_OFFS(x)"(%1)		;\n"
-#define LD(x,y)		"       movaps   "OFFS(x)"(%1), %%xmm"#y"	;\n"
-#define ST(x,y)		"       movaps %%xmm"#y",   "OFFS(x)"(%1)	;\n"
-#define PF1(x)		"	prefetchnta "PF_OFFS(x)"(%2)		;\n"
-#define PF2(x)		"	prefetchnta "PF_OFFS(x)"(%3)		;\n"
-#define PF3(x)		"	prefetchnta "PF_OFFS(x)"(%4)		;\n"
-#define PF4(x)		"	prefetchnta "PF_OFFS(x)"(%5)		;\n"
-#define PF5(x)		"	prefetchnta "PF_OFFS(x)"(%6)		;\n"
-#define XO1(x,y)	"       xorps   "OFFS(x)"(%2), %%xmm"#y"	;\n"
-#define XO2(x,y)	"       xorps   "OFFS(x)"(%3), %%xmm"#y"	;\n"
-#define XO3(x,y)	"       xorps   "OFFS(x)"(%4), %%xmm"#y"	;\n"
-#define XO4(x,y)	"       xorps   "OFFS(x)"(%5), %%xmm"#y"	;\n"
-#define XO5(x,y)	"       xorps   "OFFS(x)"(%6), %%xmm"#y"	;\n"
+#define	PF0(x)		"	prefetchnta "PF_OFFS(x)"(%[p1])		;\n"
+#define LD(x,y)		"       movaps   "OFFS(x)"(%[p1]), %%xmm"#y"	;\n"
+#define ST(x,y)		"       movaps %%xmm"#y",   "OFFS(x)"(%[p1])	;\n"
+#define PF1(x)		"	prefetchnta "PF_OFFS(x)"(%[p2])		;\n"
+#define PF2(x)		"	prefetchnta "PF_OFFS(x)"(%[p3])		;\n"
+#define PF3(x)		"	prefetchnta "PF_OFFS(x)"(%[p4])		;\n"
+#define PF4(x)		"	prefetchnta "PF_OFFS(x)"(%[p5])		;\n"
+#define PF5(x)		"	prefetchnta "PF_OFFS(x)"(%[p6])		;\n"
+#define XO1(x,y)	"       xorps   "OFFS(x)"(%[p2]), %%xmm"#y"	;\n"
+#define XO2(x,y)	"       xorps   "OFFS(x)"(%[p3]), %%xmm"#y"	;\n"
+#define XO3(x,y)	"       xorps   "OFFS(x)"(%[p4]), %%xmm"#y"	;\n"
+#define XO4(x,y)	"       xorps   "OFFS(x)"(%[p5]), %%xmm"#y"	;\n"
+#define XO5(x,y)	"       xorps   "OFFS(x)"(%[p6]), %%xmm"#y"	;\n"
 
 
 static void
 xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
 {
-        unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+        unsigned int lines = bytes >> 8;
 	unsigned long cr0;
+	xmm_store_t xmm_save[4];
 
 	XMMS_SAVE;
 
-        __asm__ __volatile__ (
+        asm volatile (
 #undef BLOCK
 #define BLOCK(i) \
 		LD(i,0)					\
@@ -612,13 +119,11 @@
 		BLOCK(8)
 		BLOCK(12)
 
-        "       addq $256, %1           ;\n"
-        "       addq $256, %2           ;\n"
-        "       decq %0                 ;\n"
-        "       jnz 1b                  ;\n"
-	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2)
+        "       addq %[inc], %[p1]           ;\n"
+        "       addq %[inc], %[p2]           ;\n"
+		"		decl %[cnt] ; jnz 1b"
+	: [p1] "+r" (p1), [p2] "+r" (p2), [cnt] "+r" (lines)
+	: [inc] "r" (256UL) 
         : "memory");
 
 	XMMS_RESTORE;
@@ -628,8 +133,8 @@
 xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
 	  unsigned long *p3)
 {
-        unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+	unsigned int lines = bytes >> 8;
+	xmm_store_t xmm_save[4];
 	unsigned long cr0;
 
 	XMMS_SAVE;
@@ -672,16 +177,14 @@
 		BLOCK(8)
 		BLOCK(12)
 
-        "       addq $256, %1           ;\n"
-        "       addq $256, %2           ;\n"
-        "       addq $256, %3           ;\n"
-        "       decq %0                 ;\n"
-        "       jnz 1b                  ;\n"
-	:
-	: "r" (lines),
-	  "r" (p1), "r"(p2), "r"(p3)
-        : "memory" );
-
+        "       addq %[inc], %[p1]           ;\n"
+        "       addq %[inc], %[p2]          ;\n"
+        "       addq %[inc], %[p3]           ;\n"
+		"		decl %[cnt] ; jnz 1b"
+	: [cnt] "+r" (lines),
+	  [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3)
+	: [inc] "r" (256UL)
+	: "memory"); 
 	XMMS_RESTORE;
 }
 
@@ -689,8 +192,8 @@
 xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
 	  unsigned long *p3, unsigned long *p4)
 {
-        unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+	unsigned int lines = bytes >> 8;
+	xmm_store_t xmm_save[4]; 
 	unsigned long cr0;
 
 	XMMS_SAVE;
@@ -739,15 +242,14 @@
 		BLOCK(8)
 		BLOCK(12)
 
-        "       addq $256, %1           ;\n"
-        "       addq $256, %2           ;\n"
-        "       addq $256, %3           ;\n"
-        "       addq $256, %4           ;\n"
-        "       decq %0                 ;\n"
-        "       jnz 1b                  ;\n"
-	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4)
+        "       addq %[inc], %[p1]           ;\n"
+        "       addq %[inc], %[p2]           ;\n"
+        "       addq %[inc], %[p3]           ;\n"
+        "       addq %[inc], %[p4]           ;\n"
+	"	decl %[cnt] ; jnz 1b"
+	: [cnt] "+c" (lines),
+	  [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3), [p4] "+r" (p4)
+	: [inc] "r" (256UL)
         : "memory" );
 
 	XMMS_RESTORE;
@@ -757,8 +259,8 @@
 xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
 	  unsigned long *p3, unsigned long *p4, unsigned long *p5)
 {
-        unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+        unsigned int lines = bytes >> 8;
+	xmm_store_t xmm_save[4];
 	unsigned long cr0;
 
 	XMMS_SAVE;
@@ -813,47 +315,36 @@
 		BLOCK(8)
 		BLOCK(12)
 
-        "       addq $256, %1           ;\n"
-        "       addq $256, %2           ;\n"
-        "       addq $256, %3           ;\n"
-        "       addq $256, %4           ;\n"
-        "       addq $256, %5           ;\n"
-        "       decq %0                 ;\n"
-        "       jnz 1b                  ;\n"
-	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
+        "       addq %[inc], %[p1]           ;\n"
+        "       addq %[inc], %[p2]           ;\n"
+        "       addq %[inc], %[p3]           ;\n"
+        "       addq %[inc], %[p4]           ;\n"
+        "       addq %[inc], %[p5]           ;\n"
+	"	decl %[cnt] ; jnz 1b"
+	: [cnt] "+c" (lines),
+  	  [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3), [p4] "+r" (p4), 
+	  [p5] "+r" (p5)
+	: [inc] "r" (256UL)
 	: "memory");
 
 	XMMS_RESTORE;
 }
 
-static struct xor_block_template xor_block_pIII_sse = {
-        name: "pIII_sse",
+static struct xor_block_template xor_block_sse = {
+        name: "generic_sse",
         do_2: xor_sse_2,
         do_3: xor_sse_3,
         do_4: xor_sse_4,
         do_5: xor_sse_5,
 };
 
-/* Also try the generic routines.  */
-#include <asm-generic/xor.h>
-
 #undef XOR_TRY_TEMPLATES
 #define XOR_TRY_TEMPLATES				\
 	do {						\
-		xor_speed(&xor_block_8regs);		\
-		xor_speed(&xor_block_32regs);		\
-	        if (cpu_has_xmm)			\
-			xor_speed(&xor_block_pIII_sse);	\
-	        if (md_cpu_has_mmx()) {			\
-	                xor_speed(&xor_block_pII_mmx);	\
-	                xor_speed(&xor_block_p5_mmx);	\
-	        }					\
+		xor_speed(&xor_block_sse);	\
 	} while (0)
 
 /* We force the use of the SSE xor block because it can write around L2.
    We may also be able to load into the L1 only depending on how the cpu
    deals with a load to a line that is being prefetched.  */
-#define XOR_SELECT_TEMPLATE(FASTEST) \
-	(cpu_has_xmm ? &xor_block_pIII_sse : FASTEST)
+#define XOR_SELECT_TEMPLATE(FASTEST) (&xor_block_sse)
diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h
--- a/include/linux/atmdev.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/atmdev.h	Sun Jun 16 19:31:40 2002
@@ -275,12 +275,8 @@
 
 #define ATM_ATMOPT_CLP	1	/* set CLP bit */
 
-
-typedef struct { unsigned long bits; } atm_vcc_flags_t;
-
-
 struct atm_vcc {
-	atm_vcc_flags_t flags;		/* VCC flags (ATM_VF_*) */
+	unsigned long	flags;		/* VCC flags (ATM_VF_*) */
 	unsigned char	family;		/* address family; 0 if unused */
 	short		vpi;		/* VPI and VCI (types must be equal */
 					/* with sockaddr) */
@@ -330,10 +326,6 @@
 	struct atm_dev_addr *next;	/* next address */
 };
 
-
-typedef struct { unsigned int bits; } atm_dev_flags_t;
-
-
 struct atm_dev {
 	const struct atmdev_ops *ops;	/* device operations; NULL if unused */
 	const struct atmphy_ops *phy;	/* PHY operations, may be undefined */
@@ -344,7 +336,7 @@
 	struct atm_vcc	*last;		/* last VCC (or undefined) */
 	void		*dev_data;	/* per-device data */
 	void		*phy_data;	/* private PHY date */
-	atm_dev_flags_t flags;		/* device flags (ATM_DF_*) */
+	unsigned long	flags;		/* device flags (ATM_DF_*) */
 	struct atm_dev_addr *local;	/* local ATM addresses */
 	unsigned char	esi[ESI_LEN];	/* ESI ("MAC" addr) */
 	struct atm_cirange ci_range;	/* VPI/VCI range */
@@ -414,7 +406,7 @@
 #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
 
 struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
-    int number,atm_dev_flags_t *flags); /* number == -1: pick first available */
+    int number,unsigned long *flags); /* number == -1: pick first available */
 struct atm_dev *atm_find_dev(int number);
 void atm_dev_deregister(struct atm_dev *dev);
 void shutdown_atm_dev(struct atm_dev *dev);
diff -Nru a/include/linux/blk.h b/include/linux/blk.h
--- a/include/linux/blk.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/blk.h	Sun Jun 16 19:31:40 2002
@@ -96,181 +96,8 @@
 } while (0)
 
 #define elv_add_request(q, rq, back) _elv_add_request((q), (rq), (back), 1)
-	
-#if defined(MAJOR_NR) || defined(IDE_DRIVER)
-
-/*
- * Add entries as needed.
- */
-
-#ifdef IDE_DRIVER
-
-#define DEVICE_NR(device)	(minor(device) >> PARTN_BITS)
-#define DEVICE_NAME "ide"
-
-#elif (MAJOR_NR == RAMDISK_MAJOR)
-
-/* ram disk */
-#define DEVICE_NAME "ramdisk"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == Z2RAM_MAJOR)
-
-/* Zorro II Ram */
-#define DEVICE_NAME "Z2RAM"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == FLOPPY_MAJOR)
-
-static void floppy_off(unsigned int nr);
-
-#define DEVICE_NAME "floppy"
-#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
-
-#elif (MAJOR_NR == HD_MAJOR)
-
-/* Hard disk:  timeout is 6 seconds. */
-#define DEVICE_NAME "hard disk"
-#define DEVICE_INTR do_hd
-#define DEVICE_NR(device) (minor(device)>>6)
-
-#elif (SCSI_DISK_MAJOR(MAJOR_NR))
-
-#define DEVICE_NAME "scsidisk"
-#define DEVICE_NR(device) (((major(device) & SD_MAJOR_MASK) << (8 - 4)) + (minor(device) >> 4))
-
-/* Kludge to use the same number for both char and block major numbers */
-#elif  (MAJOR_NR == MD_MAJOR) && defined(MD_DRIVER)
-
-#define DEVICE_NAME "Multiple devices driver"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == SCSI_TAPE_MAJOR)
-
-#define DEVICE_NAME "scsitape"
-#define DEVICE_INTR do_st
-#define DEVICE_NR(device) (minor(device) & 0x7f)
-
-#elif (MAJOR_NR == OSST_MAJOR)
-
-#define DEVICE_NAME "onstream"
-#define DEVICE_INTR do_osst
-#define DEVICE_NR(device) (minor(device) & 0x7f)
-
-#elif (MAJOR_NR == SCSI_CDROM_MAJOR)
-
-#define DEVICE_NAME "CD-ROM"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == XT_DISK_MAJOR)
-
-#define DEVICE_NAME "xt disk"
-#define DEVICE_NR(device) (minor(device) >> 6)
-
-#elif (MAJOR_NR == PS2ESDI_MAJOR)
-
-#define DEVICE_NAME "PS/2 ESDI"
-#define DEVICE_NR(device) (minor(device) >> 6)
-
-#elif (MAJOR_NR == CDU31A_CDROM_MAJOR)
-
-#define DEVICE_NAME "CDU31A"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == ACSI_MAJOR) && (defined(CONFIG_ATARI_ACSI) || defined(CONFIG_ATARI_ACSI_MODULE))
-
-#define DEVICE_NAME "ACSI"
-#define DEVICE_INTR do_acsi
-#define DEVICE_NR(device) (minor(device) >> 4)
-
-#elif (MAJOR_NR == MITSUMI_CDROM_MAJOR)
-
-#define DEVICE_NAME "Mitsumi CD-ROM"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == MITSUMI_X_CDROM_MAJOR)
-
-#define DEVICE_NAME "Mitsumi CD-ROM"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == MATSUSHITA_CDROM_MAJOR)
-
-#define DEVICE_NAME "Matsushita CD-ROM controller"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == AZTECH_CDROM_MAJOR)
-
-#define DEVICE_NAME "Aztech CD-ROM"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == CDU535_CDROM_MAJOR)
-
-#define DEVICE_NAME "SONY-CDU535"
-#define DEVICE_INTR do_cdu535
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == GOLDSTAR_CDROM_MAJOR)
-
-#define DEVICE_NAME "Goldstar R420"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == CM206_CDROM_MAJOR)
-#define DEVICE_NAME "Philips/LMS CD-ROM cm206"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == OPTICS_CDROM_MAJOR)
-
-#define DEVICE_NAME "DOLPHIN 8000AT CD-ROM"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == SANYO_CDROM_MAJOR)
-
-#define DEVICE_NAME "Sanyo H94A CD-ROM"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == APBLOCK_MAJOR)
-
-#define DEVICE_NAME "apblock"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == DDV_MAJOR)
-
-#define DEVICE_NAME "ddv"
-#define DEVICE_NR(device) (minor(device)>>PARTN_BITS)
-
-#elif (MAJOR_NR == MFM_ACORN_MAJOR)
-
-#define DEVICE_NAME "mfm disk"
-#define DEVICE_INTR do_mfm
-#define DEVICE_NR(device) (minor(device) >> 6)
-
-#elif (MAJOR_NR == NBD_MAJOR)
-
-#define DEVICE_NAME "nbd"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == MDISK_MAJOR)
-
-#define DEVICE_NAME "mdisk"
-#define DEVICE_NR(device) (minor(device))
-
-#elif (MAJOR_NR == DASD_MAJOR)
-
-#define DEVICE_NAME "dasd"
-#define DEVICE_NR(device) (minor(device) >> PARTN_BITS)
-
-#elif (MAJOR_NR == I2O_MAJOR)
-
-#define DEVICE_NAME "I2O block"
-#define DEVICE_NR(device) (minor(device)>>4)
-
-#elif (MAJOR_NR == COMPAQ_SMART2_MAJOR)
-
-#define DEVICE_NAME "ida"
-#define DEVICE_NR(device) (minor(device) >> 4)
-
-#endif /* MAJOR_NR == whatever */
 
+#if defined(MAJOR_NR) || defined(IDE_DRIVER)
 #if (MAJOR_NR != SCSI_TAPE_MAJOR) && (MAJOR_NR != OSST_MAJOR)
 #if !defined(IDE_DRIVER)
 
@@ -280,16 +107,6 @@
 #ifndef CURRENT
 # define CURRENT elv_next_request(QUEUE)
 #endif
-#ifndef DEVICE_NAME
-# define DEVICE_NAME "unknown"
-#endif
-
-#ifdef DEVICE_INTR
-static void (*DEVICE_INTR)(void) = NULL;
-#  define CLEAR_INTR DEVICE_INTR = NULL
-# else
-#  define CLEAR_INTR
-# endif
 
 #endif /* !defined(IDE_DRIVER) */
 
@@ -297,11 +114,9 @@
  * If we have our own end_request, we do not want to include this mess
  */
 #ifndef LOCAL_END_REQUEST
-static inline void end_request(int uptodate)
+static inline void end_request(struct request *req, int uptodate)
 {
-	struct request *req = CURRENT;
-
-	if (end_that_request_first(req, uptodate, CURRENT->hard_cur_sectors))
+	if (end_that_request_first(req, uptodate, req->hard_cur_sectors))
 		return;
 
 	add_blkdev_randomness(major(req->rq_dev));
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Sun Jun 16 19:31:39 2002
+++ b/include/linux/blkdev.h	Sun Jun 16 19:31:39 2002
@@ -113,7 +113,7 @@
 typedef request_queue_t * (queue_proc) (kdev_t dev);
 typedef int (make_request_fn) (request_queue_t *q, struct bio *bio);
 typedef int (prep_rq_fn) (request_queue_t *, struct request *);
-typedef void (unplug_device_fn) (void *q);
+typedef void (unplug_fn) (void *q);
 
 enum blk_queue_state {
 	Queue_down,
@@ -157,6 +157,7 @@
 	merge_requests_fn	*merge_requests_fn;
 	make_request_fn		*make_request_fn;
 	prep_rq_fn		*prep_rq_fn;
+	unplug_fn		*unplug_fn;
 
 	struct backing_dev_info	backing_dev_info;
 
@@ -206,13 +207,11 @@
 #define RQ_SCSI_DONE		0xfffe
 #define RQ_SCSI_DISCONNECTING	0xffe0
 
-#define QUEUE_FLAG_PLUGGED	0	/* queue is plugged */
-#define QUEUE_FLAG_CLUSTER	1	/* cluster several segments into 1 */
-#define QUEUE_FLAG_QUEUED	2	/* uses generic tag queueing */
-#define QUEUE_FLAG_STOPPED	3	/* queue is stopped */
+#define QUEUE_FLAG_CLUSTER	0	/* cluster several segments into 1 */
+#define QUEUE_FLAG_QUEUED	1	/* uses generic tag queueing */
+#define QUEUE_FLAG_STOPPED	2	/* queue is stopped */
 
-#define blk_queue_plugged(q)	test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
-#define blk_mark_plugged(q)	set_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
+#define blk_queue_plugged(q)	!list_empty(&(q)->plug_list)
 #define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
 #define blk_queue_empty(q)	elv_queue_empty(q)
 #define list_entry_rq(ptr)	list_entry((ptr), struct request, queuelist)
@@ -292,6 +291,7 @@
 extern struct request *blk_get_request(request_queue_t *, int, int);
 extern void blk_put_request(struct request *);
 extern void blk_plug_device(request_queue_t *);
+extern int blk_remove_plug(request_queue_t *);
 extern void blk_recount_segments(request_queue_t *, struct bio *);
 extern inline int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *);
 extern inline int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *);
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/fs.h	Sun Jun 16 19:31:40 2002
@@ -89,11 +89,6 @@
 
 /* public flags for file_system_type */
 #define FS_REQUIRES_DEV 1 
-#define FS_NO_DCACHE	2 /* Only dcache the necessary things. */
-#define FS_NO_PRELIM	4 /* prevent preloading of dentries, even if
-			   * FS_NO_DCACHE is not set.
-			   */
-#define FS_NOMOUNT	16 /* Never mount from userland */
 #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
 				  * as nfs_rename() will be cleaned up
 				  */
@@ -632,7 +627,7 @@
 #define S_BIAS (1<<30)
 struct super_block {
 	struct list_head	s_list;		/* Keep this first */
-	kdev_t			s_dev;
+	dev_t			s_dev;		/* search index; _not_ kdev_t */
 	unsigned long		s_blocksize;
 	unsigned long		s_old_blocksize;
 	unsigned char		s_blocksize_bits;
@@ -969,6 +964,8 @@
 			int (*test)(struct super_block *,void *),
 			int (*set)(struct super_block *,void *),
 			void *data);
+struct super_block *get_sb_pseudo(struct file_system_type *, char *,
+			struct super_operations *ops, unsigned long);
 
 /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
 #define fops_get(fops) \
@@ -1223,6 +1220,7 @@
 struct bio;
 extern int submit_bio(int, struct bio *);
 extern int is_read_only(kdev_t);
+extern int bdev_read_only(struct block_device *);
 extern int set_blocksize(struct block_device *, int);
 extern int sb_set_blocksize(struct super_block *, int);
 extern int sb_min_blocksize(struct super_block *, int);
@@ -1248,6 +1246,7 @@
 extern int page_symlink(struct inode *inode, const char *symname, int len);
 extern struct inode_operations page_symlink_inode_operations;
 extern void generic_fillattr(struct inode *, struct kstat *);
+extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 
 extern int vfs_readdir(struct file *, filldir_t, void *);
 
@@ -1256,10 +1255,9 @@
 extern int vfs_fstat(unsigned int, struct kstat *);
 
 extern struct file_system_type *get_fs_type(const char *name);
-extern struct super_block *get_super(kdev_t);
+extern struct super_block *get_super(struct block_device *);
+extern struct super_block *user_get_super(dev_t);
 extern void drop_super(struct super_block *sb);
-extern kdev_t ROOT_DEV;
-extern char root_device_name[];
 
 extern int dcache_dir_open(struct inode *, struct file *);
 extern int dcache_dir_close(struct inode *, struct file *);
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h	Sun Jun 16 19:31:39 2002
+++ b/include/linux/ide.h	Sun Jun 16 19:31:39 2002
@@ -213,6 +213,7 @@
 
 /* Currently only m68k, apus and m8xx need it */
 #ifdef ATA_ARCH_ACK_INTR
+extern int ide_irq_lock;
 # define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
 #else
 # define ide_ack_intr(hwif) (1)
@@ -356,7 +357,7 @@
 	byte		queue_depth;	/* max queue depth */
 	unsigned int	failures;	/* current failure count */
 	unsigned int	max_failures;	/* maximum allowed failure count */
-	struct device	device;		/* global device tree handle */
+	struct device	dev;		/* global device tree handle */
 
 	/*
 	 * tcq statistics
@@ -458,9 +459,9 @@
 	int (*udma_setup)(struct ata_device *);
 
 	void (*udma_enable)(struct ata_device *, int, int);
-	int (*udma_start) (struct ata_device *, struct request *rq);
+	void (*udma_start) (struct ata_device *, struct request *);
 	int (*udma_stop) (struct ata_device *);
-	int (*udma_init) (struct ata_device *, struct request *rq);
+	int (*udma_init) (struct ata_device *, struct request *);
 	int (*udma_irq_status) (struct ata_device *);
 	void (*udma_timeout) (struct ata_device *);
 	void (*udma_irq_lost) (struct ata_device *);
@@ -598,16 +599,14 @@
  */
 #define IDE_DRIVER		/* Toggle some magic bits in blk.h */
 #define LOCAL_END_REQUEST	/* Don't generate end_request in blk.h */
+#define DEVICE_NR(device)	(minor(device) >> PARTN_BITS)
 #include <linux/blk.h>
 
-extern int __ide_end_request(struct ata_device *, struct request *, int, unsigned int);
-extern int ide_end_request(struct ata_device *drive, struct request *, int);
+/* Not locking and locking variant: */
+extern int __ata_end_request(struct ata_device *, struct request *, int, unsigned int);
+extern int ata_end_request(struct ata_device *drive, struct request *, int);
 
-/*
- * This is used on exit from the driver, to designate the next irq handler
- * and also to start the safety timer.
- */
-extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
+extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
 		unsigned long timeout, ata_expiry_t expiry);
 
 extern u8 ata_dump(struct ata_device *, struct request *, const char *);
@@ -615,12 +614,6 @@
 
 extern void ide_fixstring(char *s, const int bytecount, const int byteswap);
 
-extern int ide_wait_stat(ide_startstop_t *,
-		struct ata_device *, struct request *rq,
-		byte, byte, unsigned long);
-
-extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long);
-
 /*
  * This routine is called from the partition-table code in genhd.c
  * to "convert" a drive to a logical geometry with fewer than 1024 cyls.
@@ -659,15 +652,12 @@
 	struct hd_drive_task_hdr  hobfile;
 	u8 cmd;					/* actual ATA command */
 	int command_type;
-	ide_startstop_t (*handler)(struct ata_device *, struct request *);
+	ide_startstop_t (*XXX_handler)(struct ata_device *, struct request *);
 };
 
 extern void ata_read(struct ata_device *, void *, unsigned int);
 extern void ata_write(struct ata_device *, void *, unsigned int);
 
-extern ide_startstop_t ata_taskfile(struct ata_device *,
-	struct ata_taskfile *, struct request *);
-
 /*
  * Special Flagged Register Validation Caller
  */
@@ -690,8 +680,7 @@
 		bio_kunmap_irq(to, flags);
 }
 
-extern ide_startstop_t ata_special_intr(struct ata_device *, struct request *);
-extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *);
+extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *, char *);
 
 extern void ide_fix_driveid(struct hd_driveid *id);
 extern int ide_config_drive_speed(struct ata_device *, byte);
@@ -759,9 +748,9 @@
 	drive->channel->udma_enable(drive, on, verbose);
 }
 
-static inline int udma_start(struct ata_device *drive, struct request *rq)
+static inline void udma_start(struct ata_device *drive, struct request *rq)
 {
-	return drive->channel->udma_start(drive, rq);
+	drive->channel->udma_start(drive, rq);
 }
 
 static inline int udma_stop(struct ata_device *drive)
@@ -772,7 +761,7 @@
 /*
  * Initiate actual DMA data transfer. The direction is encoded in the request.
  */
-static inline int udma_init(struct ata_device *drive, struct request *rq)
+static inline ide_startstop_t udma_init(struct ata_device *drive, struct request *rq)
 {
 	return drive->channel->udma_init(drive, rq);
 }
@@ -795,7 +784,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 
 extern void udma_pci_enable(struct ata_device *drive, int on, int verbose);
-extern int udma_pci_start(struct ata_device *drive, struct request *rq);
+extern void udma_pci_start(struct ata_device *drive, struct request *rq);
 extern int udma_pci_stop(struct ata_device *drive);
 extern int udma_pci_init(struct ata_device *drive, struct request *rq);
 extern int udma_pci_irq_status(struct ata_device *drive);
@@ -810,7 +799,7 @@
 extern int udma_black_list(struct ata_device *);
 extern int udma_white_list(struct ata_device *);
 
-extern ide_startstop_t udma_tcq_taskfile(struct ata_device *, struct request *);
+extern ide_startstop_t udma_tcq_init(struct ata_device *, struct request *);
 extern int udma_tcq_enable(struct ata_device *, int);
 
 extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
@@ -834,7 +823,11 @@
 
 extern void ata_select(struct ata_device *, unsigned long);
 extern void ata_mask(struct ata_device *);
+extern int ata_busy_poll(struct ata_device *, unsigned long);
 extern int ata_status(struct ata_device *, u8, u8);
+extern int ata_status_poll( struct ata_device *, u8, u8,
+		unsigned long, struct request *rq, ide_startstop_t *);
+
 extern int ata_irq_enable(struct ata_device *, int);
 extern void ata_reset(struct ata_channel *);
 extern void ata_out_regfile(struct ata_device *, struct hd_drive_task_hdr *);
diff -Nru a/include/linux/irda.h b/include/linux/irda.h
--- a/include/linux/irda.h	Sun Jun 16 19:31:39 2002
+++ b/include/linux/irda.h	Sun Jun 16 19:31:39 2002
@@ -68,6 +68,8 @@
 	IRDA_OLD_BELKIN_DONGLE   = 7,
 	IRDA_EP7211_IR           = 8,
 	IRDA_MCP2120_DONGLE      = 9,
+	IRDA_ACT200L_DONGLE      = 10,
+	IRDA_MA600_DONGLE        = 11,
 } IRDA_DONGLE;
 
 /* Protocol types to be used for SOCK_DGRAM */
diff -Nru a/include/linux/kdev_t.h b/include/linux/kdev_t.h
--- a/include/linux/kdev_t.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/kdev_t.h	Sun Jun 16 19:31:40 2002
@@ -36,8 +36,8 @@
 Admissible operations on an object of type kdev_t:
 - passing it along
 - comparing it for equality with another such object
-- storing it in ROOT_DEV, inode->i_dev, inode->i_rdev, sb->s_dev,
-  bh->b_dev, req->rq_dev, de->dc_dev, tty->device
+- storing it in inode->i_dev, inode->i_rdev, req->rq_dev, de->dc_dev,
+- tty->device
 - using its bit pattern as argument in a hash function
 - finding its major and minor
 - complaining about it
diff -Nru a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h	Sun Jun 16 19:31:39 2002
+++ b/include/linux/list.h	Sun Jun 16 19:31:39 2002
@@ -24,7 +24,7 @@
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
 
 #define LIST_HEAD(name) \
-	struct list_head name = LIST_HEAD_INIT(name)
+	list_t name = LIST_HEAD_INIT(name)
 
 #define INIT_LIST_HEAD(ptr) do { \
 	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
@@ -36,9 +36,7 @@
  * This is only for internal list manipulation where we know
  * the prev/next entries already!
  */
-static __inline__ void __list_add(struct list_head * new,
-	struct list_head * prev,
-	struct list_head * next)
+static inline void __list_add(list_t *new, list_t *prev, list_t *next)
 {
 	next->prev = new;
 	new->next = next;
@@ -54,7 +52,7 @@
  * Insert a new entry after the specified head.
  * This is good for implementing stacks.
  */
-static __inline__ void list_add(struct list_head *new, struct list_head *head)
+static inline void list_add(list_t *new, list_t *head)
 {
 	__list_add(new, head, head->next);
 }
@@ -67,7 +65,7 @@
  * Insert a new entry before the specified head.
  * This is useful for implementing queues.
  */
-static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
+static inline void list_add_tail(list_t *new, list_t *head)
 {
 	__list_add(new, head->prev, head);
 }
@@ -79,8 +77,7 @@
  * This is only for internal list manipulation where we know
  * the prev/next entries already!
  */
-static __inline__ void __list_del(struct list_head * prev,
-				  struct list_head * next)
+static inline void __list_del(list_t * prev, list_t * next)
 {
 	next->prev = prev;
 	prev->next = next;
@@ -91,7 +88,7 @@
  * @entry: the element to delete from the list.
  * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
  */
-static __inline__ void list_del(struct list_head *entry)
+static inline void list_del(list_t *entry)
 {
 	__list_del(entry->prev, entry->next);
 	entry->next = (void *) 0;
@@ -102,17 +99,39 @@
  * list_del_init - deletes entry from list and reinitialize it.
  * @entry: the element to delete from the list.
  */
-static __inline__ void list_del_init(struct list_head *entry)
+static inline void list_del_init(list_t *entry)
 {
 	__list_del(entry->prev, entry->next);
 	INIT_LIST_HEAD(entry); 
 }
 
 /**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(list_t *list, list_t *head)
+{
+        __list_del(list->prev, list->next);
+        list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(list_t *list, list_t *head)
+{
+        __list_del(list->prev, list->next);
+        list_add_tail(list, head);
+}
+
+/**
  * list_empty - tests whether a list is empty
  * @head: the list to test.
  */
-static __inline__ int list_empty(struct list_head *head)
+static inline int list_empty(list_t *head)
 {
 	return head->next == head;
 }
@@ -122,13 +141,13 @@
  * @list: the new list to add.
  * @head: the place to add it in the first list.
  */
-static __inline__ void list_splice(struct list_head *list, struct list_head *head)
+static inline void list_splice(list_t *list, list_t *head)
 {
-	struct list_head *first = list->next;
+	list_t *first = list->next;
 
 	if (first != list) {
-		struct list_head *last = list->prev;
-		struct list_head *at = head->next;
+		list_t *last = list->prev;
+		list_t *at = head->next;
 
 		first->prev = head;
 		head->next = first;
@@ -140,7 +159,7 @@
 
 /**
  * list_entry - get the struct for this entry
- * @ptr:	the &struct list_head pointer.
+ * @ptr:	the &list_t pointer.
  * @type:	the type of the struct this is embedded in.
  * @member:	the name of the list_struct within the struct.
  */
@@ -149,7 +168,7 @@
 
 /**
  * list_for_each	-	iterate over a list
- * @pos:	the &struct list_head to use as a loop counter.
+ * @pos:	the &list_t to use as a loop counter.
  * @head:	the head for your list.
  */
 #define list_for_each(pos, head) \
@@ -157,7 +176,7 @@
         	pos = pos->next, prefetch(pos->next))
 /**
  * list_for_each_prev	-	iterate over a list backwards
- * @pos:	the &struct list_head to use as a loop counter.
+ * @pos:	the &list_t to use as a loop counter.
  * @head:	the head for your list.
  */
 #define list_for_each_prev(pos, head) \
@@ -166,8 +185,8 @@
         	
 /**
  * list_for_each_safe	-	iterate over a list safe against removal of list entry
- * @pos:	the &struct list_head to use as a loop counter.
- * @n:		another &struct list_head to use as temporary storage
+ * @pos:	the &list_t to use as a loop counter.
+ * @n:		another &list_t to use as temporary storage
  * @head:	the head for your list.
  */
 #define list_for_each_safe(pos, n, head) \
diff -Nru a/include/linux/namespace.h b/include/linux/namespace.h
--- a/include/linux/namespace.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/namespace.h	Sun Jun 16 19:31:40 2002
@@ -2,6 +2,9 @@
 #define _NAMESPACE_H_
 #ifdef __KERNEL__
 
+#include <linux/dcache.h>
+#include <linux/sched.h>
+
 struct namespace {
 	atomic_t		count;
 	struct vfsmount *	root;
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/pci_ids.h	Sun Jun 16 19:31:40 2002
@@ -912,6 +912,7 @@
 #define PCI_DEVICE_ID_REALTEK_8029	0x8029
 #define PCI_DEVICE_ID_REALTEK_8129	0x8129
 #define PCI_DEVICE_ID_REALTEK_8139	0x8139
+#define PCI_DEVICE_ID_REALTEK_8169	0x8169
 
 #define PCI_VENDOR_ID_XILINX		0x10ee
 #define PCI_DEVICE_ID_TURBOPAM		0x4020
@@ -1111,6 +1112,7 @@
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5	  0x0201
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	Sun Jun 16 19:31:41 2002
+++ b/include/linux/reiserfs_fs.h	Sun Jun 16 19:31:41 2002
@@ -20,6 +20,7 @@
 #include <asm/unaligned.h>
 #include <linux/bitops.h>
 #include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/reiserfs_fs_i.h>
 #include <linux/reiserfs_fs_sb.h>
@@ -1062,9 +1063,7 @@
 #define B_I_E_NAME(bh,ih,entry_num) ((char *)(bh->b_data + ih_location(ih) + deh_location(B_I_DEH(bh,ih)+(entry_num))))
 
 // two entries per block (at least)
-//#define REISERFS_MAX_NAME_LEN(block_size) 
-//((block_size - BLKH_SIZE - IH_SIZE - DEH_SIZE * 2) / 2)
-#define REISERFS_MAX_NAME_LEN(block_size) 255
+#define REISERFS_MAX_NAME(block_size) 255
 
 
 /* this structure is used for operations on directory entries. It is
@@ -1641,19 +1640,21 @@
 #define JBH_HASH_SHIFT 13 /* these are based on journal hash size of 8192 */
 #define JBH_HASH_MASK 8191
 
-/* After several hours of tedious analysis, the following hash
- * function won.  Do not mess with it... -DaveM
- */
-#define _jhashfn(dev,block)	\
-	((((dev)<<(JBH_HASH_SHIFT - 6)) ^ ((dev)<<(JBH_HASH_SHIFT - 9))) ^ \
+#define _jhashfn(sb,block)	\
+	(((unsigned long)sb>>L1_CACHE_SHIFT) ^ \
 	 (((block)<<(JBH_HASH_SHIFT - 6)) ^ ((block) >> 13) ^ ((block) << (JBH_HASH_SHIFT - 12))))
-#define journal_hash(t,sb,block) ((t)[_jhashfn((kdev_t_to_nr(sb->s_dev)),(block)) & JBH_HASH_MASK])
+#define journal_hash(t,sb,block) ((t)[_jhashfn((sb),(block)) & JBH_HASH_MASK])
 
 /* finds n'th buffer with 0 being the start of this commit.  Needs to go away, j_ap_blocks has changed
 ** since I created this.  One chunk of code in journal.c needs changing before deleting it
 */
 #define JOURNAL_BUFFER(j,n) ((j)->j_ap_blocks[((j)->j_start + (n)) % JOURNAL_BLOCK_COUNT])
 
+// We need these to make journal.c code more readable
+#define journal_get_hash_table(s, block) __get_hash_table(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize)
+#define journal_getblk(s, block) __getblk(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize)
+#define journal_bread(s, block) __bread(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize)
+
 void reiserfs_commit_for_inode(struct inode *) ;
 void reiserfs_update_inode_transaction(struct inode *) ;
 void reiserfs_wait_on_write_block(struct super_block *s) ;
@@ -2073,6 +2074,12 @@
  
 /* ioctl's command */
 #define REISERFS_IOC_UNPACK		_IOW(0xCD,1,long)
+
+/* Locking primitives */
+/* Right now we are still falling back to (un)lock_kernel, but eventually that
+   would evolve into real per-fs locks */
+#define reiserfs_write_lock( sb ) lock_kernel()
+#define reiserfs_write_unlock( sb ) unlock_kernel()
  			         
 #endif /* _LINUX_REISER_FS_H */
 
diff -Nru a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
--- a/include/linux/reiserfs_fs_sb.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/reiserfs_fs_sb.h	Sun Jun 16 19:31:40 2002
@@ -194,7 +194,6 @@
   struct reiserfs_journal_cnode *j_last ; /* newest journal block */
   struct reiserfs_journal_cnode *j_first ; /*  oldest journal block.  start here for traverse */
 
-  kdev_t               j_dev;
   struct file         *j_dev_file;
   struct block_device *j_dev_bd;  
   int j_1st_reserved_block;     /* first block on s_dev of reserved area journal */        
@@ -408,6 +407,8 @@
 #define REISERFS_HASHED_RELOCATION 13
 #define REISERFS_TEST4 14 
 
+#define REISERFS_ATTRS 15
+
 #define REISERFS_TEST1 11
 #define REISERFS_TEST2 12
 #define REISERFS_TEST3 13
@@ -430,7 +431,7 @@
 
 
 void reiserfs_file_buffer (struct buffer_head * bh, int list);
-int reiserfs_is_super(struct super_block *s)  ;
+int is_reiserfs_super(struct super_block *s)  ;
 int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ;
 int flush_old_commits(struct super_block *s, int) ;
 int show_reiserfs_locks(void) ;
@@ -454,6 +455,13 @@
 #define SB_JOURNAL_MAX_BATCH(s)      (SB_JOURNAL(s)->s_journal_max_batch)
 #define SB_JOURNAL_MAX_COMMIT_AGE(s) (SB_JOURNAL(s)->s_journal_max_commit_age)
 #define SB_JOURNAL_MAX_TRANS_AGE(s)  (SB_JOURNAL(s)->s_journal_max_trans_age)
-#define SB_JOURNAL_DEV(s)            (SB_JOURNAL(s)->j_dev)
+
+/* A safe version of the "bdevname", which returns the "s_id" field of
+ * a superblock or else "Null superblock" if the super block is NULL.
+ */
+static inline char *reiserfs_bdevname(struct super_block *s)
+{
+        return (s == NULL) ? "Null superblock" : s -> s_id;
+}
 
 #endif	/* _LINUX_REISER_FS_SB */
diff -Nru a/include/linux/root_dev.h b/include/linux/root_dev.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/root_dev.h	Sun Jun 16 19:31:41 2002
@@ -0,0 +1,19 @@
+#ifndef _ROOT_DEV_H_
+#define _ROOT_DEV_H_
+
+enum {
+	Root_NFS = MKDEV(UNNAMED_MAJOR, 255),
+	Root_RAM0 = MKDEV(RAMDISK_MAJOR, 0),
+	Root_RAM1 = MKDEV(RAMDISK_MAJOR, 1),
+	Root_FD0 = MKDEV(FLOPPY_MAJOR, 0),
+	Root_HDA1 = MKDEV(IDE0_MAJOR, 1),
+	Root_HDA2 = MKDEV(IDE0_MAJOR, 2),
+	Root_SDA1 = MKDEV(SCSI_DISK0_MAJOR, 1),
+	Root_SDA2 = MKDEV(SCSI_DISK0_MAJOR, 2),
+	Root_HDC1 = MKDEV(IDE1_MAJOR, 1),
+	Root_SR0 = MKDEV(SCSI_CDROM_MAJOR, 0),
+};
+
+extern dev_t ROOT_DEV;
+
+#endif
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Sun Jun 16 19:31:39 2002
+++ b/include/linux/sched.h	Sun Jun 16 19:31:39 2002
@@ -491,6 +491,7 @@
 extern unsigned long prof_shift;
 
 extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr));
+extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));
 extern void FASTCALL(sleep_on(wait_queue_head_t *q));
 extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
 				      signed long timeout));
@@ -507,6 +508,11 @@
 #define wake_up_interruptible(x)	__wake_up((x),TASK_INTERRUPTIBLE, 1)
 #define wake_up_interruptible_nr(x, nr)	__wake_up((x),TASK_INTERRUPTIBLE, nr)
 #define wake_up_interruptible_all(x)	__wake_up((x),TASK_INTERRUPTIBLE, 0)
+#ifdef CONFIG_SMP
+#define wake_up_interruptible_sync(x)   __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
+#else
+#define wake_up_interruptible_sync(x)   __wake_up((x),TASK_INTERRUPTIBLE, 1)
+#endif
 asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);
 
 extern int in_group_p(gid_t);
diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h
--- a/include/linux/spinlock.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/spinlock.h	Sun Jun 16 19:31:40 2002
@@ -26,6 +26,7 @@
 #define write_lock_bh(lock)			do { local_bh_disable();         write_lock(lock); } while (0)
 
 #define spin_unlock_irqrestore(lock, flags)	do { spin_unlock(lock);  local_irq_restore(flags); } while (0)
+#define _raw_spin_unlock_irqrestore(lock, flags) do { _raw_spin_unlock(lock);  local_irq_restore(flags); } while (0)
 #define spin_unlock_irq(lock)			do { spin_unlock(lock);  local_irq_enable();       } while (0)
 #define spin_unlock_bh(lock)			do { spin_unlock(lock);  local_bh_enable();        } while (0)
 
@@ -64,13 +65,9 @@
 #elif !defined(spin_lock_init) /* !SMP and spin_lock_init not previously
                                   defined (e.g. by including asm/spinlock.h */
 
-#define DEBUG_SPINLOCKS	0	/* 0 == no debugging, 1 == maintain lock state, 2 == full debug */
-
-#if (DEBUG_SPINLOCKS < 1)
-
 #ifndef CONFIG_PREEMPT
-#define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
-#define ATOMIC_DEC_AND_LOCK
+# define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
+# define ATOMIC_DEC_AND_LOCK
 #endif
 
 /*
@@ -80,10 +77,10 @@
  */
 #if (__GNUC__ > 2)
   typedef struct { } spinlock_t;
-  #define SPIN_LOCK_UNLOCKED (spinlock_t) { }
+# define SPIN_LOCK_UNLOCKED (spinlock_t) { }
 #else
   typedef struct { int gcc_is_buggy; } spinlock_t;
-  #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+# define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
 #endif
 
 #define spin_lock_init(lock)	do { (void)(lock); } while(0)
@@ -93,42 +90,6 @@
 #define spin_unlock_wait(lock)	do { (void)(lock); } while(0)
 #define _raw_spin_unlock(lock)	do { (void)(lock); } while(0)
 
-#elif (DEBUG_SPINLOCKS < 2)
-
-typedef struct {
-	volatile unsigned long lock;
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-
-#define spin_lock_init(x)	do { (x)->lock = 0; } while (0)
-#define spin_is_locked(lock)	(test_bit(0,(lock)))
-#define spin_trylock(lock)	(!test_and_set_bit(0,(lock)))
-
-#define spin_lock(x)		do { (x)->lock = 1; } while (0)
-#define spin_unlock_wait(x)	do { } while (0)
-#define spin_unlock(x)		do { (x)->lock = 0; } while (0)
-
-#else /* (DEBUG_SPINLOCKS >= 2) */
-
-typedef struct {
-	volatile unsigned long lock;
-	volatile unsigned int babble;
-	const char *module;
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 25, __BASE_FILE__ }
-
-#include <linux/kernel.h>
-
-#define spin_lock_init(x)	do { (x)->lock = 0; } while (0)
-#define spin_is_locked(lock)	(test_bit(0,(lock)))
-#define spin_trylock(lock)	(!test_and_set_bit(0,(lock)))
-
-#define spin_lock(x)		do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_lock(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1; restore_flags(__spinflags);} while (0)
-#define spin_unlock_wait(x)	do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock_wait(%s:%p) deadlock\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} restore_flags(__spinflags);} while (0)
-#define spin_unlock(x)		do {unsigned long __spinflags; save_flags(__spinflags); cli(); if (!(x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; restore_flags(__spinflags);} while (0)
-
-#endif	/* DEBUG_SPINLOCKS */
-
 /*
  * Read-write spinlocks, allowing multiple readers
  * but only one writer.
@@ -183,6 +144,12 @@
 		preempt_schedule(); \
 } while (0)
 
+#define preempt_check_resched() \
+do { \
+	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
+		preempt_schedule(); \
+} while (0)
+
 #define spin_lock(lock)	\
 do { \
 	preempt_disable(); \
@@ -197,6 +164,12 @@
 	preempt_enable(); \
 } while (0)
 
+#define spin_unlock_no_resched(lock) \
+do { \
+	_raw_spin_unlock(lock); \
+	preempt_enable_no_resched(); \
+} while (0)
+
 #define read_lock(lock)		({preempt_disable(); _raw_read_lock(lock);})
 #define read_unlock(lock)	({_raw_read_unlock(lock); preempt_enable();})
 #define write_lock(lock)	({preempt_disable(); _raw_write_lock(lock);})
@@ -206,20 +179,22 @@
 
 #else
 
-#define preempt_get_count()	(0)
-#define preempt_disable()	do { } while (0)
+#define preempt_get_count()		(0)
+#define preempt_disable()		do { } while (0)
 #define preempt_enable_no_resched()	do {} while(0)
-#define preempt_enable()	do { } while (0)
+#define preempt_enable()		do { } while (0)
+#define preempt_check_resched()		do { } while (0)
 
-#define spin_lock(lock)		_raw_spin_lock(lock)
-#define spin_trylock(lock)	_raw_spin_trylock(lock)
-#define spin_unlock(lock)	_raw_spin_unlock(lock)
-
-#define read_lock(lock)		_raw_read_lock(lock)
-#define read_unlock(lock)	_raw_read_unlock(lock)
-#define write_lock(lock)	_raw_write_lock(lock)
-#define write_unlock(lock)	_raw_write_unlock(lock)
-#define write_trylock(lock)	_raw_write_trylock(lock)
+#define spin_lock(lock)			_raw_spin_lock(lock)
+#define spin_trylock(lock)		_raw_spin_trylock(lock)
+#define spin_unlock(lock)		_raw_spin_unlock(lock)
+#define spin_unlock_no_resched(lock)	_raw_spin_unlock(lock)
+
+#define read_lock(lock)			_raw_read_lock(lock)
+#define read_unlock(lock)		_raw_read_unlock(lock)
+#define write_lock(lock)		_raw_write_lock(lock)
+#define write_unlock(lock)		_raw_write_unlock(lock)
+#define write_trylock(lock)		_raw_write_trylock(lock)
 #endif
 
 /* "lock on reference count zero" */
diff -Nru a/include/linux/suspend.h b/include/linux/suspend.h
--- a/include/linux/suspend.h	Sun Jun 16 19:31:39 2002
+++ b/include/linux/suspend.h	Sun Jun 16 19:31:39 2002
@@ -1,12 +1,13 @@
 #ifndef _LINUX_SWSUSP_H
 #define _LINUX_SWSUSP_H
 
-#if defined(SUSPEND_C) || defined(ACPI_C)
+#ifdef CONFIG_X86
 #include <asm/suspend.h>
 #endif
 #include <linux/swap.h>
 #include <linux/notifier.h>
 #include <linux/config.h>
+#include <linux/init.h>
 
 extern unsigned char software_suspend_enabled;
 
diff -Nru a/include/linux/types.h b/include/linux/types.h
--- a/include/linux/types.h	Sun Jun 16 19:31:40 2002
+++ b/include/linux/types.h	Sun Jun 16 19:31:40 2002
@@ -3,6 +3,9 @@
 
 #ifdef	__KERNEL__
 #include <linux/config.h>
+
+#define bitmap_member(name,bits) \
+	unsigned long name[((bits)+BITS_PER_LONG-1)/BITS_PER_LONG]
 #endif
 
 #include <linux/posix_types.h>
diff -Nru a/include/linux/vmalloc.h b/include/linux/vmalloc.h
--- a/include/linux/vmalloc.h	Sun Jun 16 19:31:41 2002
+++ b/include/linux/vmalloc.h	Sun Jun 16 19:31:41 2002
@@ -28,7 +28,6 @@
  */
 
 extern void * vmalloc(unsigned long size);
-extern void * vmalloc_dma(unsigned long size);
 extern void * vmalloc_32(unsigned long size);
 
 /*
diff -Nru a/include/net/irda/discovery.h b/include/net/irda/discovery.h
--- a/include/net/irda/discovery.h	Sun Jun 16 19:31:41 2002
+++ b/include/net/irda/discovery.h	Sun Jun 16 19:31:41 2002
@@ -36,7 +36,7 @@
 #include <net/irda/irda.h>
 #include <net/irda/irqueue.h>
 
-#define DISCOVERY_EXPIRE_TIMEOUT 6*HZ
+#define DISCOVERY_EXPIRE_TIMEOUT (2*sysctl_discovery_timeout*HZ)
 #define DISCOVERY_DEFAULT_SLOTS  0
 
 /* Types of discovery */
diff -Nru a/include/scsi/scsi.h b/include/scsi/scsi.h
--- a/include/scsi/scsi.h	Sun Jun 16 19:31:41 2002
+++ b/include/scsi/scsi.h	Sun Jun 16 19:31:41 2002
@@ -223,23 +223,4 @@
 /* Used to get the PCI location of a device */
 #define SCSI_IOCTL_GET_PCI 0x5387
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4 
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
-
 #endif
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	Sun Jun 16 19:31:39 2002
+++ b/include/sound/ac97_codec.h	Sun Jun 16 19:31:39 2002
@@ -160,7 +160,7 @@
 	unsigned int rates_mic_adc;
 	unsigned int spdif_status;
 	unsigned short regs[0x80]; /* register cache */
-	unsigned char reg_accessed[0x80 / 8]; /* bit flags */
+	bitmap_member(reg_accessed, 0x80); /* bit flags */
 	union {			/* vendor specific code */
 		struct {
 			unsigned short unchained[3];	// 0 = C34, 1 = C79, 2 = C69
diff -Nru a/include/sound/core.h b/include/sound/core.h
--- a/include/sound/core.h	Sun Jun 16 19:31:41 2002
+++ b/include/sound/core.h	Sun Jun 16 19:31:41 2002
@@ -345,7 +345,7 @@
 #else /* !CONFIG_SND_DEBUG */
 
 #define snd_printd(fmt, args...)	/* nothing */
-#define snd_assert(expr, args...)	/* nothing */
+#define snd_assert(expr, args...)	(void)(expr)
 #define snd_runtime_check(expr, args...) do { if (!(expr)) { args; } } while (0)
 
 #endif /* CONFIG_SND_DEBUG */
diff -Nru a/include/sound/initval.h b/include/sound/initval.h
--- a/include/sound/initval.h	Sun Jun 16 19:31:39 2002
+++ b/include/sound/initval.h	Sun Jun 16 19:31:39 2002
@@ -144,6 +144,7 @@
 
 #if defined(SNDRV_GET_ID) && !defined(MODULE)
 #include <linux/ctype.h>
+#include <linux/init.h>
 static int __init get_id(char **str, char **dst)
 {
 	char *s, *d;
diff -Nru a/include/sound/pcm_params.h b/include/sound/pcm_params.h
--- a/include/sound/pcm_params.h	Sun Jun 16 19:31:39 2002
+++ b/include/sound/pcm_params.h	Sun Jun 16 19:31:39 2002
@@ -38,7 +38,7 @@
 /* To share the same code we have  alsa-lib */
 #define snd_mask_bits(mask) (*(mask))
 #define INLINE static inline
-#define assert(a)
+#define assert(a) (void)(a)
 
 INLINE unsigned int ld2(u_int32_t v)
 {
diff -Nru a/init/Makefile b/init/Makefile
--- a/init/Makefile	Sun Jun 16 19:31:40 2002
+++ b/init/Makefile	Sun Jun 16 19:31:40 2002
@@ -22,5 +22,5 @@
 # actual file if its content has changed.
 
 ../include/linux/compile.h: FORCE
-	@echo -n 'Generating $@'
+	@echo -n '  Generating $@'
 	@../scripts/mkcompile_h $@ "$(ARCH)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c	Sun Jun 16 19:31:40 2002
+++ b/init/do_mounts.c	Sun Jun 16 19:31:40 2002
@@ -11,6 +11,7 @@
 #include <linux/tty.h>
 #include <linux/init.h>
 #include <linux/suspend.h>
+#include <linux/root_dev.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
@@ -55,7 +56,7 @@
 static char root_device_name[64];
 
 /* this is initialized in init/main.c */
-kdev_t ROOT_DEV;
+dev_t ROOT_DEV;
 
 static int do_devfs = 0;
 
@@ -239,7 +240,7 @@
 	int i;
 	char ch;
 
-	ROOT_DEV = name_to_kdev_t(line);
+	ROOT_DEV = kdev_t_to_nr(name_to_kdev_t(line));
 	memset (root_device_name, 0, sizeof root_device_name);
 	if (strncmp (line, "/dev/", 5) == 0) line += 5;
 	for (i = 0; i < sizeof root_device_name - 1; ++i)
@@ -319,12 +320,12 @@
 		 * and bad superblock on root device.
 		 */
 		printk ("VFS: Cannot open root device \"%s\" or %s\n",
-			root_device_name, kdevname (ROOT_DEV));
+			root_device_name, kdevname (to_kdev_t(ROOT_DEV)));
 		printk ("Please append a correct \"root=\" boot option\n");
 		panic("VFS: Unable to mount root fs on %s",
-			kdevname(ROOT_DEV));
+			kdevname(to_kdev_t(ROOT_DEV)));
 	}
-	panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
+	panic("VFS: Unable to mount root fs on %s", kdevname(to_kdev_t(ROOT_DEV)));
 out:
 	putname(fs_names);
 	sys_chdir("/root");
@@ -345,7 +346,7 @@
 }
 #endif
 
-static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
+static int __init create_dev(char *name, dev_t dev, char *devfs_name)
 {
 	void *handle;
 	char path[64];
@@ -353,10 +354,10 @@
 
 	sys_unlink(name);
 	if (!do_devfs)
-		return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev));
+		return sys_mknod(name, S_IFBLK|0600, dev);
 
-	handle = devfs_find_handle(NULL, kdev_none(dev) ? devfs_name : NULL,
-				major(dev), minor(dev), DEVFS_SPECIAL_BLK, 1);
+	handle = devfs_find_handle(NULL, !dev ? devfs_name : NULL,
+				MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1);
 	if (!handle)
 		return -1;
 	n = devfs_generate_path(handle, path + 5, sizeof (path) - 5);
@@ -634,7 +635,7 @@
 #ifdef CONFIG_BLK_DEV_RAM
 	if (rd_prompt)
 		change_floppy("root floppy disk to be loaded into RAM disk");
-	create_dev("/dev/ram", mk_kdev(RAMDISK_MAJOR, n), NULL);
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
 #endif
 	return rd_load_image("/dev/root");
 }
@@ -699,7 +700,7 @@
 static void __init mount_root(void)
 {
 #ifdef CONFIG_ROOT_NFS
-	if (major(ROOT_DEV) == UNNAMED_MAJOR) {
+	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 		if (mount_nfs_root()) {
 			sys_chdir("/root");
 			ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
@@ -707,17 +708,17 @@
 			return;
 		}
 		printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
-		ROOT_DEV = mk_kdev(FLOPPY_MAJOR, 0);
+		ROOT_DEV = Root_FD0;
 	}
 #endif
 	devfs_make_root(root_device_name);
 	create_dev("/dev/root", ROOT_DEV, root_device_name);
 #ifdef CONFIG_BLK_DEV_FD
-	if (major(ROOT_DEV) == FLOPPY_MAJOR) {
+	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
 		/* rd_doload is 2 for a dual initrd/ramload setup */
 		if (rd_doload==2) {
 			if (rd_load_disk(1)) {
-				ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 1);
+				ROOT_DEV = Root_RAM1;
 				create_dev("/dev/root", ROOT_DEV, NULL);
 			}
 		} else
@@ -752,11 +753,10 @@
 static void __init handle_initrd(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-	kdev_t ram0 = mk_kdev(RAMDISK_MAJOR,0);
 	int error;
 	int i, pid;
 
-	create_dev("/dev/root.old", ram0, NULL);
+	create_dev("/dev/root.old", Root_RAM0, NULL);
 	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
 	sys_mkdir("/old", 0700);
 	sys_chdir("/old");
@@ -770,12 +770,12 @@
 	sys_mount("..", ".", NULL, MS_MOVE, NULL);
 	sys_umount("/old/dev", 0);
 
-	if (real_root_dev == kdev_t_to_nr(ram0)) {
+	if (real_root_dev == Root_RAM0) {
 		sys_chdir("/old");
 		return;
 	}
 
-	ROOT_DEV = to_kdev_t(real_root_dev);
+	ROOT_DEV = real_root_dev;
 	mount_root();
 
 	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
@@ -802,8 +802,8 @@
 static int __init initrd_load(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-	create_dev("/dev/ram", mk_kdev(RAMDISK_MAJOR, 0), NULL);
-	create_dev("/dev/initrd", mk_kdev(RAMDISK_MAJOR, INITRD_MINOR), NULL);
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
+	create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
 #endif
 	return rd_load_image("/dev/initrd");
 }
@@ -813,11 +813,11 @@
  */
 void prepare_namespace(void)
 {
-	int is_floppy = major(ROOT_DEV) == FLOPPY_MAJOR;
+	int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (!initrd_start)
 		mount_initrd = 0;
-	real_root_dev = kdev_t_to_nr(ROOT_DEV);
+	real_root_dev = ROOT_DEV;
 #endif
 	sys_mkdir("/dev", 0700);
 	sys_mkdir("/root", 0700);
@@ -834,12 +834,12 @@
 	software_resume();
 
 	if (mount_initrd) {
-		if (initrd_load() && !kdev_same(ROOT_DEV, mk_kdev(RAMDISK_MAJOR, 0))) {
+		if (initrd_load() && ROOT_DEV != Root_RAM0) {
 			handle_initrd();
 			goto out;
 		}
 	} else if (is_floppy && rd_doload && rd_load_disk(0))
-		ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
+		ROOT_DEV = Root_RAM0;
 	mount_root();
 out:
 	sys_umount("/dev", 0);
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Sun Jun 16 19:31:39 2002
+++ b/kernel/fork.c	Sun Jun 16 19:31:39 2002
@@ -24,6 +24,7 @@
 #include <linux/file.h>
 #include <linux/binfmts.h>
 #include <linux/fs.h>
+#include <linux/mm.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Sun Jun 16 19:31:39 2002
+++ b/kernel/ksyms.c	Sun Jun 16 19:31:39 2002
@@ -49,6 +49,7 @@
 #include <linux/binfmts.h>
 #include <linux/namei.h>
 #include <linux/buffer_head.h>
+#include <linux/root_dev.h>
 #include <asm/checksum.h>
 
 #if defined(CONFIG_PROC_FS)
@@ -108,6 +109,8 @@
 EXPORT_SYMBOL(kfree);
 EXPORT_SYMBOL(vfree);
 EXPORT_SYMBOL(__vmalloc);
+EXPORT_SYMBOL(vmalloc);
+EXPORT_SYMBOL(vmalloc_32);
 EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(remap_page_range);
@@ -130,6 +133,7 @@
 EXPORT_SYMBOL(def_blk_fops);
 EXPORT_SYMBOL(update_atime);
 EXPORT_SYMBOL(get_fs_type);
+EXPORT_SYMBOL(user_get_super);
 EXPORT_SYMBOL(get_super);
 EXPORT_SYMBOL(drop_super);
 EXPORT_SYMBOL(getname);
@@ -256,6 +260,7 @@
 EXPORT_SYMBOL(vfs_fstat);
 EXPORT_SYMBOL(vfs_stat);
 EXPORT_SYMBOL(vfs_lstat);
+EXPORT_SYMBOL(vfs_getattr);
 EXPORT_SYMBOL(lock_rename);
 EXPORT_SYMBOL(unlock_rename);
 EXPORT_SYMBOL(generic_read_dir);
@@ -326,6 +331,7 @@
 EXPORT_SYMBOL(blk_size);
 EXPORT_SYMBOL(blk_dev);
 EXPORT_SYMBOL(is_read_only);
+EXPORT_SYMBOL(bdev_read_only);
 EXPORT_SYMBOL(set_device_ro);
 EXPORT_SYMBOL(bmap);
 EXPORT_SYMBOL(devfs_register_partitions);
@@ -457,6 +463,9 @@
 /* process management */
 EXPORT_SYMBOL(complete_and_exit);
 EXPORT_SYMBOL(__wake_up);
+#if CONFIG_SMP
+EXPORT_SYMBOL_GPL(__wake_up_sync); /* internal use only */
+#endif
 EXPORT_SYMBOL(wake_up_process);
 EXPORT_SYMBOL(sleep_on);
 EXPORT_SYMBOL(sleep_on_timeout);
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Sun Jun 16 19:31:39 2002
+++ b/kernel/sched.c	Sun Jun 16 19:31:39 2002
@@ -135,7 +135,6 @@
  */
 struct runqueue {
 	spinlock_t lock;
-	spinlock_t frozen;
 	unsigned long nr_running, nr_switches, expired_timestamp;
 	signed long nr_uninterruptible;
 	task_t *curr, *idle;
@@ -153,17 +152,21 @@
 #define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
 #define rt_task(p)		((p)->prio < MAX_RT_PRIO)
 
+/*
+ * task_rq_lock - lock the runqueue a given task resides on and disable
+ * interrupts.  Note the ordering: we can safely lookup the task_rq without
+ * explicitly disabling preemption.
+ */
 static inline runqueue_t *task_rq_lock(task_t *p, unsigned long *flags)
 {
 	struct runqueue *rq;
 
 repeat_lock_task:
-	preempt_disable();
+	local_irq_save(*flags);
 	rq = task_rq(p);
-	spin_lock_irqsave(&rq->lock, *flags);
+	spin_lock(&rq->lock);
 	if (unlikely(rq != task_rq(p))) {
 		spin_unlock_irqrestore(&rq->lock, *flags);
-		preempt_enable();
 		goto repeat_lock_task;
 	}
 	return rq;
@@ -172,7 +175,23 @@
 static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags)
 {
 	spin_unlock_irqrestore(&rq->lock, *flags);
-	preempt_enable();
+}
+
+/*
+ * rq_lock - lock a given runqueue and disable interrupts.
+ */
+static inline runqueue_t *rq_lock(runqueue_t *rq)
+{
+	local_irq_disable();
+	rq = this_rq();
+	spin_lock(&rq->lock);
+	return rq;
+}
+
+static inline void rq_unlock(runqueue_t *rq)
+{
+	spin_unlock(&rq->lock);
+	local_irq_enable();
 }
 
 /*
@@ -284,9 +303,15 @@
 repeat:
 	preempt_disable();
 	rq = task_rq(p);
-	while (unlikely(rq->curr == p)) {
+	if (unlikely(rq->curr == p)) {
 		cpu_relax();
-		barrier();
+		/*
+		 * enable/disable preemption just to make this
+		 * a preemption point - we are busy-waiting
+		 * anyway.
+		 */
+		preempt_enable();
+		goto repeat;
 	}
 	rq = task_rq_lock(p, &flags);
 	if (unlikely(rq->curr == p)) {
@@ -322,40 +347,50 @@
  * "current->state = TASK_RUNNING" to mark yourself runnable
  * without the overhead of this.
  */
-static int try_to_wake_up(task_t * p)
+static int try_to_wake_up(task_t * p, int sync)
 {
 	unsigned long flags;
 	int success = 0;
 	long old_state;
 	runqueue_t *rq;
 
+repeat_lock_task:
 	rq = task_rq_lock(p, &flags);
 	old_state = p->state;
-	p->state = TASK_RUNNING;
 	if (!p->array) {
+		if (unlikely(sync && (rq->curr != p))) {
+			if (p->thread_info->cpu != smp_processor_id()) {
+				p->thread_info->cpu = smp_processor_id();
+				task_rq_unlock(rq, &flags);
+				goto repeat_lock_task;
+			}
+		}
 		if (old_state == TASK_UNINTERRUPTIBLE)
 			rq->nr_uninterruptible--;
 		activate_task(p, rq);
+		/*
+		 * If sync is set, a resched_task() is a NOOP
+		 */
 		if (p->prio < rq->curr->prio)
 			resched_task(rq->curr);
 		success = 1;
 	}
+	p->state = TASK_RUNNING;
 	task_rq_unlock(rq, &flags);
+
 	return success;
 }
 
 int wake_up_process(task_t * p)
 {
-	return try_to_wake_up(p);
+	return try_to_wake_up(p, 0);
 }
 
 void wake_up_forked_process(task_t * p)
 {
 	runqueue_t *rq;
 
-	preempt_disable();
-	rq = this_rq();
-	spin_lock_irq(&rq->lock);
+	rq = rq_lock(rq);
 
 	p->state = TASK_RUNNING;
 	if (!rt_task(p)) {
@@ -371,8 +406,7 @@
 	p->thread_info->cpu = smp_processor_id();
 	activate_task(p, rq);
 
-	spin_unlock_irq(&rq->lock);
-	preempt_enable();
+	rq_unlock(rq);
 }
 
 /*
@@ -401,19 +435,18 @@
 }
 
 #if CONFIG_SMP || CONFIG_PREEMPT
-asmlinkage void schedule_tail(void)
+asmlinkage void schedule_tail(task_t *prev)
 {
-	spin_unlock_irq(&this_rq()->frozen);
+	finish_arch_switch(this_rq());
+	finish_arch_schedule(prev);
 }
 #endif
 
-static inline void context_switch(task_t *prev, task_t *next)
+static inline task_t * context_switch(task_t *prev, task_t *next)
 {
 	struct mm_struct *mm = next->mm;
 	struct mm_struct *oldmm = prev->active_mm;
 
-	prepare_to_switch();
-
 	if (unlikely(!mm)) {
 		next->active_mm = oldmm;
 		atomic_inc(&oldmm->mm_count);
@@ -427,7 +460,9 @@
 	}
 
 	/* Here we just switch the register state and the stack. */
-	switch_to(prev, next);
+	switch_to(prev, next, prev);
+
+	return prev;
 }
 
 unsigned long nr_running(void)
@@ -762,8 +797,8 @@
 	list_t *queue;
 	int idx;
 
-	if (unlikely(in_interrupt()))
-		BUG();
+	BUG_ON(in_interrupt());
+
 #if CONFIG_DEBUG_HIGHMEM
 	check_highmem_ptes();
 #endif
@@ -773,6 +808,7 @@
 	rq = this_rq();
 
 	release_kernel_lock(prev, smp_processor_id());
+	prepare_arch_schedule(prev);
 	prev->sleep_timestamp = jiffies;
 	spin_lock_irq(&rq->lock);
 
@@ -828,28 +864,20 @@
 	if (likely(prev != next)) {
 		rq->nr_switches++;
 		rq->curr = next;
-		spin_lock(&rq->frozen);
-		spin_unlock(&rq->lock);
-
-		context_switch(prev, next);
-
-		/*
-		 * The runqueue pointer might be from another CPU
-		 * if the new task was last running on a different
-		 * CPU - thus re-load it.
-		 */
-		mb();
+	
+		prepare_arch_switch(rq);
+		prev = context_switch(prev, next);
+		barrier();
 		rq = this_rq();
-		spin_unlock_irq(&rq->frozen);
-	} else {
+		finish_arch_switch(rq);
+	} else
 		spin_unlock_irq(&rq->lock);
-	}
+	finish_arch_schedule(prev);
 
 	reacquire_kernel_lock(current);
 	preempt_enable_no_resched();
 	if (test_thread_flag(TIF_NEED_RESCHED))
 		goto need_resched;
-	return;
 }
 
 #ifdef CONFIG_PREEMPT
@@ -865,9 +893,15 @@
 	if (unlikely(ti->preempt_count))
 		return;
 
+need_resched:
 	ti->preempt_count = PREEMPT_ACTIVE;
 	schedule();
 	ti->preempt_count = 0;
+
+	/* we can miss a preemption opportunity between schedule and now */
+	barrier();
+	if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
+		goto need_resched;
 }
 #endif /* CONFIG_PREEMPT */
 
@@ -880,7 +914,7 @@
  * started to run but is not in state TASK_RUNNING.  try_to_wake_up() returns
  * zero in this (rare) case, and we handle it by continuing to scan the queue.
  */
-static inline void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
+static inline void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int sync)
 {
 	struct list_head *tmp;
 	unsigned int state;
@@ -891,7 +925,7 @@
 		curr = list_entry(tmp, wait_queue_t, task_list);
 		p = curr->task;
 		state = p->state;
-		if ((state & mode) && try_to_wake_up(p) &&
+		if ((state & mode) && try_to_wake_up(p, sync) &&
 			((curr->flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive))
 				break;
 	}
@@ -905,17 +939,36 @@
 		return;
 
 	spin_lock_irqsave(&q->lock, flags);
-	__wake_up_common(q, mode, nr_exclusive);
+	__wake_up_common(q, mode, nr_exclusive, 0);
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
+#if CONFIG_SMP
+
+void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
+{
+	unsigned long flags;
+
+	if (unlikely(!q))
+		return;
+
+	spin_lock_irqsave(&q->lock, flags);
+	if (likely(nr_exclusive))
+		__wake_up_common(q, mode, nr_exclusive, 1);
+	else
+		__wake_up_common(q, mode, nr_exclusive, 0);
+	spin_unlock_irqrestore(&q->lock, flags);
+}
+
+#endif
+ 
 void complete(struct completion *x)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&x->wait.lock, flags);
 	x->done++;
-	__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1);
+	__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, 0);
 	spin_unlock_irqrestore(&x->wait.lock, flags);
 }
 
@@ -1147,7 +1200,7 @@
 
 	/*
 	 * Valid priorities for SCHED_FIFO and SCHED_RR are
-	 * 1..MAX_USER_RT_PRIO, valid priority for SCHED_OTHER is 0.
+	 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_OTHER is 0.
 	 */
 	retval = -EINVAL;
 	if (lp.sched_priority < 0 || lp.sched_priority > MAX_USER_RT_PRIO-1)
@@ -1342,8 +1395,7 @@
 	runqueue_t *rq;
 	prio_array_t *array;
 
-	preempt_disable();
-	rq = this_rq();
+	rq = rq_lock(rq);
 
 	/*
 	 * Decrease the yielding task's priority by one, to avoid
@@ -1353,7 +1405,6 @@
 	 * If priority is already MAX_PRIO-1 then we still
 	 * roundrobin the task within the runlist.
 	 */
-	spin_lock_irq(&rq->lock);
 	array = current->array;
 	/*
 	 * If the task has reached maximum priority (or is a RT task)
@@ -1370,8 +1421,7 @@
 		list_add_tail(&current->run_list, array->queue + current->prio);
 		__set_bit(current->prio, array->bitmap);
 	}
-	spin_unlock(&rq->lock);
-	preempt_enable_no_resched();
+	spin_unlock_no_resched(&rq->lock);
 
 	schedule();
 
@@ -1599,7 +1649,6 @@
 		rq->active = rq->arrays;
 		rq->expired = rq->arrays + 1;
 		spin_lock_init(&rq->lock);
-		spin_lock_init(&rq->frozen);
 		INIT_LIST_HEAD(&rq->migration_queue);
 
 		for (j = 0; j < 2; j++) {
@@ -1687,7 +1736,15 @@
 		task_rq_unlock(rq, &flags);
 		goto out;
 	}
-
+	/*
+	 * If the task is not on a runqueue (and not running), then
+	 * it is sufficient to simply update the task's cpu field.
+	 */
+	if (!p->array && (p != rq->curr)) {
+		p->thread_info->cpu = __ffs(p->cpus_allowed);
+		task_rq_unlock(rq, &flags);
+		goto out;
+	}
 	init_MUTEX_LOCKED(&req.sem);
 	req.task = p;
 	list_add(&req.list, &rq->migration_queue);
@@ -1710,15 +1767,15 @@
 	sigfillset(&current->blocked);
 	set_fs(KERNEL_DS);
 	/*
-	 * The first migration thread is started on CPU #0. This one can migrate
-	 * the other migration threads to their destination CPUs.
+	 * The first migration thread is started on CPU #0. This one can
+	 * migrate the other migration threads to their destination CPUs.
 	 */
 	if (cpu != 0) {
 		while (!cpu_rq(cpu_logical_map(0))->migration_thread)
 			yield();
 		set_cpus_allowed(current, 1UL << cpu);
 	}
-	printk("migration_task %d on cpu=%d\n",cpu,smp_processor_id());
+	printk("migration_task %d on cpu=%d\n", cpu, smp_processor_id());
 	ret = setscheduler(0, SCHED_FIFO, &param);
 
 	rq = this_rq();
@@ -1790,4 +1847,4 @@
 		while (!cpu_rq(cpu_logical_map(cpu))->migration_thread)
 			schedule_timeout(2);
 }
-#endif
+#endif /* CONFIG_SMP */
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Sun Jun 16 19:31:39 2002
+++ b/kernel/suspend.c	Sun Jun 16 19:31:39 2002
@@ -44,7 +44,6 @@
 #include <linux/version.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
-#include <linux/init.h>
 #include <linux/vt_kern.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
@@ -845,9 +844,6 @@
 	mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
 	printk(KERN_WARNING "%sLeaving do_magic_suspend_2...\n", name_suspend);	
 }
-
-#define SUSPEND_C
-#include <asm/suspend.h>
 
 /*
  * We try to swap out as much as we can then make a copy of the
diff -Nru a/lib/vsprintf.c b/lib/vsprintf.c
--- a/lib/vsprintf.c	Sun Jun 16 19:31:41 2002
+++ b/lib/vsprintf.c	Sun Jun 16 19:31:41 2002
@@ -172,41 +172,50 @@
 	if (!(type&(ZEROPAD+LEFT))) {
 		while(size-->0) {
 			if (buf <= end)
-				*buf++ = ' ';
+				*buf = ' ';
+			++buf;
 		}
 	}
 	if (sign) {
 		if (buf <= end)
-			*buf++ = sign;
+			*buf = sign;
+		++buf;
 	}
 	if (type & SPECIAL) {
 		if (base==8) {
 			if (buf <= end)
-				*buf++ = '0';
+				*buf = '0';
+			++buf;
 		} else if (base==16) {
 			if (buf <= end)
-				*buf++ = '0';
+				*buf = '0';
+			++buf;
 			if (buf <= end)
-				*buf++ = digits[33];
+				*buf = digits[33];
+			++buf;
 		}
 	}
 	if (!(type & LEFT)) {
 		while (size-- > 0) {
 			if (buf <= end)
-				*buf++ = c;
+				*buf = c;
+			++buf;
 		}
 	}
 	while (i < precision--) {
 		if (buf <= end)
-			*buf++ = '0';
+			*buf = '0';
+		++buf;
 	}
 	while (i-- > 0) {
 		if (buf <= end)
-			*buf++ = tmp[i];
+			*buf = tmp[i];
+		++buf;
 	}
 	while (size-- > 0) {
 		if (buf <= end)
-			*buf++ = ' ';
+			*buf = ' ';
+		++buf;
 	}
 	return buf;
 }
@@ -238,10 +247,6 @@
 				/* 'z' support added 23/7/1999 S.H.    */
 				/* 'z' changed to 'Z' --davidm 1/25/99 */
 
-	/* Enforce absolute minimum size: one character + the trailing 0 */
-	if (size < 2)
-		return 0;
-
 	str = buf;
 	end = buf + size - 1;
 
@@ -253,7 +258,8 @@
 	for (; *fmt ; ++fmt) {
 		if (*fmt != '%') {
 			if (str <= end)
-				*str++ = *fmt;
+				*str = *fmt;
+			++str;
 			continue;
 		}
 
@@ -317,15 +323,18 @@
 				if (!(flags & LEFT)) {
 					while (--field_width > 0) {
 						if (str <= end)
-							*str++ = ' ';
+							*str = ' ';
+						++str;
 					}
 				}
 				c = (unsigned char) va_arg(args, int);
 				if (str <= end)
-					*str++ = c;
+					*str = c;
+				++str;
 				while (--field_width > 0) {
 					if (str <= end)
-						*str++ = ' ';
+						*str = ' ';
+					++str;
 				}
 				continue;
 
@@ -339,16 +348,19 @@
 				if (!(flags & LEFT)) {
 					while (len < field_width--) {
 						if (str <= end)
-							*str++ = ' ';
+							*str = ' ';
+						++str;
 					}
 				}
 				for (i = 0; i < len; ++i) {
 					if (str <= end)
-						*str++ = *s++;
+						*str = *s;
+					++str; ++s;
 				}
 				while (len < field_width--) {
 					if (str <= end)
-						*str++ = ' ';
+						*str = ' ';
+					++str;
 				}
 				continue;
 
@@ -380,7 +392,8 @@
 
 			case '%':
 				if (str <= end)
-					*str++ = '%';
+					*str = '%';
+				++str;
 				continue;
 
 				/* integer number formats - set up the flags and "break" */
@@ -402,10 +415,12 @@
 
 			default:
 				if (str <= end)
-					*str++ = '%';
+					*str = '%';
+				++str;
 				if (*fmt) {
 					if (str <= end)
-						*str++ = *fmt;
+						*str = *fmt;
+					++str;
 				} else {
 					--fmt;
 				}
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Sun Jun 16 19:31:40 2002
+++ b/mm/filemap.c	Sun Jun 16 19:31:40 2002
@@ -70,7 +70,7 @@
 {
 	struct address_space *mapping = page->mapping;
 
-	if (unlikely(PageDirty(page)))
+	if (unlikely(PageDirty(page)) && !PageSwapCache(page))
 		BUG();
 
 	radix_tree_delete(&page->mapping->page_tree, page->index);
@@ -2178,7 +2178,7 @@
 		if (unlikely(pos + count > inode->i_sb->s_maxbytes))
 			count = inode->i_sb->s_maxbytes - pos;
 	} else {
-		if (is_read_only(inode->i_rdev)) {
+		if (bdev_read_only(inode->i_bdev)) {
 			err = -EPERM;
 			goto out;
 		}
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Sun Jun 16 19:31:40 2002
+++ b/mm/memory.c	Sun Jun 16 19:31:40 2002
@@ -310,17 +310,6 @@
 	return -ENOMEM;
 }
 
-/*
- * Return indicates whether a page was freed so caller can adjust rss
- */
-static inline void forget_pte(pte_t page)
-{
-	if (!pte_none(page)) {
-		printk("forget_pte: old mapping existed!\n");
-		BUG();
-	}
-}
-
 static void zap_pte_range(mmu_gather_t *tlb, pmd_t * pmd, unsigned long address, unsigned long size)
 {
 	unsigned long offset;
@@ -427,7 +416,7 @@
 	spin_lock(&mm->page_table_lock);
 	flush_cache_range(vma, address, end);
 
-	tlb = tlb_gather_mmu(mm);
+	tlb = tlb_gather_mmu(mm, 0);
 	unmap_page_range(tlb, vma, address, end);
 	tlb_finish_mmu(tlb, start, end);
 	spin_unlock(&mm->page_table_lock);
@@ -777,9 +766,8 @@
 		end = PMD_SIZE;
 	do {
 		pte_t zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE(address), prot));
-		pte_t oldpage = ptep_get_and_clear(pte);
+		BUG_ON(!pte_none(*pte));
 		set_pte(pte, zero_pte);
-		forget_pte(oldpage);
 		address += PAGE_SIZE;
 		pte++;
 	} while (address && (address < end));
@@ -853,11 +841,9 @@
 		end = PMD_SIZE;
 	pfn = phys_addr >> PAGE_SHIFT;
 	do {
-		pte_t oldpage = ptep_get_and_clear(pte);
-
+		BUG_ON(!pte_none(*pte));
 		if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
  			set_pte(pte, pfn_pte(pfn, prot));
-		forget_pte(oldpage);
 		address += PAGE_SIZE;
 		pfn++;
 		pte++;
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Sun Jun 16 19:31:39 2002
+++ b/mm/mmap.c	Sun Jun 16 19:31:39 2002
@@ -848,7 +848,7 @@
 {
 	mmu_gather_t *tlb;
 
-	tlb = tlb_gather_mmu(mm);
+	tlb = tlb_gather_mmu(mm, 0);
 
 	do {
 		unsigned long from, to;
@@ -1105,7 +1105,7 @@
 	release_segments(mm);
 	spin_lock(&mm->page_table_lock);
 
-	tlb = tlb_gather_mmu(mm);
+	tlb = tlb_gather_mmu(mm, 1);
 
 	flush_cache_mm(mm);
 	mpnt = mm->mmap;
diff -Nru a/mm/page_io.c b/mm/page_io.c
--- a/mm/page_io.c	Sun Jun 16 19:31:39 2002
+++ b/mm/page_io.c	Sun Jun 16 19:31:39 2002
@@ -116,8 +116,10 @@
 		PAGE_BUG(page);
 	/* needs sync_page to wait I/O completation */
 	page->mapping = &swapper_space;
-	if (!rw_swap_page_base(rw, entry, page))
-		unlock_page(page);
-	wait_on_page_locked(page);
+	if (rw_swap_page_base(rw, entry, page))
+		lock_page(page);
+	if (page_has_buffers(page) && !try_to_free_buffers(page))
+		PAGE_BUG(page);
 	page->mapping = NULL;
+	unlock_page(page);
 }
diff -Nru a/mm/readahead.c b/mm/readahead.c
--- a/mm/readahead.c	Sun Jun 16 19:31:39 2002
+++ b/mm/readahead.c	Sun Jun 16 19:31:39 2002
@@ -32,7 +32,7 @@
 }
 
 static int
-read_pages(struct address_space *mapping,
+read_pages(struct file *file, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
 	unsigned page_idx;
@@ -44,7 +44,7 @@
 		struct page *page = list_entry(pages->prev, struct page, list);
 		list_del(&page->list);
 		if (!add_to_page_cache_unique(page, mapping, page->index))
-			mapping->a_ops->readpage(NULL, page);
+			mapping->a_ops->readpage(file, page);
 		page_cache_release(page);
 	}
 	return 0;
@@ -167,7 +167,7 @@
 	 * uptodate then the caller will launch readpage again, and
 	 * will then handle the error.
 	 */
-	read_pages(mapping, &page_pool, nr_to_really_read);
+	read_pages(file, mapping, &page_pool, nr_to_really_read);
 	blk_run_queues();
 	BUG_ON(!list_empty(&page_pool));
 	return;
diff -Nru a/mm/shmem.c b/mm/shmem.c
--- a/mm/shmem.c	Sun Jun 16 19:31:40 2002
+++ b/mm/shmem.c	Sun Jun 16 19:31:40 2002
@@ -315,7 +315,6 @@
 	return shmem_truncate_direct(base, start, len);
 }
 
-/* SMP-safe */
 static void shmem_truncate (struct inode * inode)
 {
 	unsigned long index;
@@ -376,29 +375,31 @@
 	clear_inode(inode);
 }
 
-static int shmem_clear_swp (swp_entry_t entry, swp_entry_t *ptr, int size) {
+static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *ptr, swp_entry_t *eptr)
+{
 	swp_entry_t *test;
 
-	for (test = ptr; test < ptr + size; test++) {
-		if (test->val == entry.val) {
-			swap_free (entry);
-			*test = (swp_entry_t) {0};
+	for (test = ptr; test < eptr; test++) {
+		if (test->val == entry.val)
 			return test - ptr;
-		}
 	}
 	return -1;
 }
 
-static int shmem_unuse_inode (struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
+static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
 {
 	swp_entry_t *ptr;
 	unsigned long idx;
 	int offset;
-	struct inode *inode = NULL;
+	struct inode *inode;
 
 	idx = 0;
+	ptr = info->i_direct;
 	spin_lock (&info->lock);
-	offset = shmem_clear_swp (entry, info->i_direct, SHMEM_NR_DIRECT);
+	offset = info->next_index;
+	if (offset > SHMEM_NR_DIRECT)
+		offset = SHMEM_NR_DIRECT;
+	offset = shmem_find_swp(entry, ptr, ptr + offset);
 	if (offset >= 0)
 		goto found;
 
@@ -407,7 +408,10 @@
 		ptr = shmem_swp_entry(info, idx, 0);
 		if (IS_ERR(ptr))
 			continue;
-		offset = shmem_clear_swp (entry, ptr, ENTRIES_PER_PAGE);
+		offset = info->next_index - idx;
+		if (offset > ENTRIES_PER_PAGE)
+			offset = ENTRIES_PER_PAGE;
+		offset = shmem_find_swp(entry, ptr, ptr + offset);
 		if (offset >= 0)
 			goto found;
 	}
@@ -416,7 +420,11 @@
 found:
 	idx += offset;
 	inode = igrab(&info->vfs_inode);
+	/* move head to start search for next from here */
+	list_move_tail(&shmem_inodes, &info->list);
 	spin_unlock(&shmem_ilock);
+	swap_free(entry);
+	ptr[offset] = (swp_entry_t) {0};
 
 	while (inode && move_from_swap_cache(page, idx, inode->i_mapping)) {
 		/*
@@ -454,7 +462,7 @@
 	list_for_each(p, &shmem_inodes) {
 		info = list_entry(p, struct shmem_inode_info, list);
 
-		if (shmem_unuse_inode(info, entry, page))
+		if (info->swapped && shmem_unuse_inode(info, entry, page))
 			return;
 	}
 	spin_unlock (&shmem_ilock);
@@ -754,7 +762,7 @@
 			inode->i_op = &shmem_inode_operations;
 			inode->i_fop = &shmem_file_operations;
 			spin_lock (&shmem_ilock);
-			list_add (&SHMEM_I(inode)->list, &shmem_inodes);
+			list_add_tail(&SHMEM_I(inode)->list, &shmem_inodes);
 			spin_unlock (&shmem_ilock);
 			break;
 		case S_IFDIR:
@@ -1030,14 +1038,13 @@
 /*
  * File creation. Allocate an inode, and we're done..
  */
-/* SMP-safe */
 static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
 {
 	struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev);
 	int error = -ENOSPC;
 
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	if (inode) {
+		dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 		d_instantiate(dentry, inode);
 		dget(dentry); /* Extra count - pin the dentry in core */
 		error = 0;
@@ -1137,19 +1144,25 @@
  */
 static int shmem_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
 {
-	int error = -ENOTEMPTY;
+	struct inode *inode;
 
-	if (shmem_empty(new_dentry)) {
-		struct inode *inode = new_dentry->d_inode;
-		if (inode) {
-			inode->i_ctime = CURRENT_TIME;
-			inode->i_nlink--;
-			dput(new_dentry);
-		}
-		error = 0;
-		old_dentry->d_inode->i_ctime = old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	if (!shmem_empty(new_dentry)) 
+		return -ENOTEMPTY;
+
+	inode = new_dentry->d_inode;
+	if (inode) {
+		inode->i_ctime = CURRENT_TIME;
+		inode->i_nlink--;
+		dput(new_dentry);
 	}
-	return error;
+	inode = old_dentry->d_inode;
+	if (S_ISDIR(inode->i_mode)) {
+		old_dir->i_nlink--;
+		new_dir->i_nlink++;
+	}
+
+	inode->i_ctime = old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	return 0;
 }
 
 static int shmem_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
@@ -1170,14 +1183,11 @@
 
 	info = SHMEM_I(inode);
 	inode->i_size = len-1;
-	if (len <= sizeof(struct shmem_inode_info)) {
+	if (len <= (char *)inode - (char *)info) {
 		/* do it inline */
 		memcpy(info, symname, len);
 		inode->i_op = &shmem_symlink_inline_operations;
 	} else {
-		spin_lock (&shmem_ilock);
-		list_add (&info->list, &shmem_inodes);
-		spin_unlock (&shmem_ilock);
 		down(&info->sem);
 		page = shmem_getpage_locked(info, inode, 0);
 		if (IS_ERR(page)) {
@@ -1185,6 +1195,10 @@
 			iput(inode);
 			return PTR_ERR(page);
 		}
+		inode->i_op = &shmem_symlink_inode_operations;
+		spin_lock (&shmem_ilock);
+		list_add_tail(&info->list, &shmem_inodes);
+		spin_unlock (&shmem_ilock);
 		kaddr = kmap(page);
 		memcpy(kaddr, symname, len);
 		kunmap(page);
@@ -1192,7 +1206,6 @@
 		unlock_page(page);
 		page_cache_release(page);
 		up(&info->sem);
-		inode->i_op = &shmem_symlink_inode_operations;
 	}
 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	d_instantiate(dentry, inode);
@@ -1358,6 +1371,8 @@
 		err = -EINVAL;
 		goto failed;
 	}
+#else
+	sb->s_flags |= MS_NOUSER;
 #endif
 
 	spin_lock_init (&sbinfo->stat_lock);
@@ -1505,21 +1520,13 @@
 	get_sb:		shmem_get_sb,
 	kill_sb:	kill_litter_super,
 };
+#endif
 static struct file_system_type tmpfs_fs_type = {
 	owner:		THIS_MODULE,
 	name:		"tmpfs",
 	get_sb:		shmem_get_sb,
 	kill_sb:	kill_litter_super,
 };
-#else
-static struct file_system_type tmpfs_fs_type = {
-	owner:		THIS_MODULE,
-	name:		"tmpfs",
-	get_sb:		shmem_get_sb,
-	kill_sb:	kill_litter_super,
-	fs_flags:	FS_NOMOUNT,
-};
-#endif
 static struct vfsmount *shm_mnt;
 
 static int __init init_shmem_fs(void)
diff -Nru a/mm/swapfile.c b/mm/swapfile.c
--- a/mm/swapfile.c	Sun Jun 16 19:31:39 2002
+++ b/mm/swapfile.c	Sun Jun 16 19:31:39 2002
@@ -684,10 +684,7 @@
 		 * private" pages, but they are handled by tmpfs files.
 		 * Note shmem_unuse already deleted its from swap cache.
 		 */
-		swcount = *swap_map;
-		if ((swcount > 0) != PageSwapCache(page))
-			BUG();
-		if ((swcount > 1) && PageDirty(page)) {
+		if ((*swap_map > 1) && PageDirty(page) && PageSwapCache(page)) {
 			rw_swap_page(WRITE, page);
 			lock_page(page);
 		}
diff -Nru a/mm/vmalloc.c b/mm/vmalloc.c
--- a/mm/vmalloc.c	Sun Jun 16 19:31:39 2002
+++ b/mm/vmalloc.c	Sun Jun 16 19:31:39 2002
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/spinlock.h>
+#include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/smp_lock.h>
 
diff -Nru a/net/Makefile b/net/Makefile
--- a/net/Makefile	Sun Jun 16 19:31:40 2002
+++ b/net/Makefile	Sun Jun 16 19:31:40 2002
@@ -7,7 +7,6 @@
 
 O_TARGET :=	network.o
 
-mod-subdirs :=	ipv4 ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched
 export-objs :=	netsyms.o
 
 obj-y	:= socket.o core/
diff -Nru a/net/atm/clip.c b/net/atm/clip.c
--- a/net/atm/clip.c	Sun Jun 16 19:31:40 2002
+++ b/net/atm/clip.c	Sun Jun 16 19:31:40 2002
@@ -710,7 +710,7 @@
 	999,		/* dummy device number */
 	NULL,NULL,	/* pretend not to have any VCCs */
 	NULL,NULL,	/* no data */
-	{ 0 },		/* no flags */
+	0,		/* no flags */
 	NULL,		/* no local address */
 	{ 0 }		/* no ESI, no statistics */
 };
diff -Nru a/net/atm/lec.c b/net/atm/lec.c
--- a/net/atm/lec.c	Sun Jun 16 19:31:39 2002
+++ b/net/atm/lec.c	Sun Jun 16 19:31:39 2002
@@ -564,7 +564,7 @@
         999,	    /*dummy device number*/
         NULL,NULL,  /*no VCCs*/
         NULL,NULL,  /*no data*/
-        { 0 },	    /*no flags*/
+        0,	    /*no flags*/
         NULL,	    /* no local address*/
         { 0 }	    /*no ESI or rest of the atm_dev struct things*/
 };
diff -Nru a/net/atm/proc.c b/net/atm/proc.c
--- a/net/atm/proc.c	Sun Jun 16 19:31:40 2002
+++ b/net/atm/proc.c	Sun Jun 16 19:31:40 2002
@@ -220,7 +220,7 @@
 		default:
 			here += sprintf(here,"%3d",vcc->family);
 	}
-	here += sprintf(here," %04lx  %5d %7d/%7d %7d/%7d\n",vcc->flags.bits,
+	here += sprintf(here," %04lx  %5d %7d/%7d %7d/%7d\n",vcc->flags,
 	    vcc->reply,
 	    atomic_read(&vcc->tx_inuse),vcc->sk->sndbuf,
 	    atomic_read(&vcc->rx_inuse),vcc->sk->rcvbuf);
diff -Nru a/net/atm/resources.c b/net/atm/resources.c
--- a/net/atm/resources.c	Sun Jun 16 19:31:41 2002
+++ b/net/atm/resources.c	Sun Jun 16 19:31:41 2002
@@ -83,7 +83,7 @@
 
 
 struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
-				 int number, atm_dev_flags_t *flags)
+				 int number, unsigned long *flags)
 {
 	struct atm_dev *dev;
 
diff -Nru a/net/atm/signaling.c b/net/atm/signaling.c
--- a/net/atm/signaling.c	Sun Jun 16 19:31:41 2002
+++ b/net/atm/signaling.c	Sun Jun 16 19:31:41 2002
@@ -239,7 +239,7 @@
 	999,		/* dummy device number */
 	NULL,NULL,	/* pretend not to have any VCCs */
 	NULL,NULL,	/* no data */
-	{ 0 },		/* no flags */
+	0,		/* no flags */
 	NULL,		/* no local address */
 	{ 0 }		/* no ESI, no statistics */
 };
diff -Nru a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
--- a/net/ipv4/ipconfig.c	Sun Jun 16 19:31:39 2002
+++ b/net/ipv4/ipconfig.c	Sun Jun 16 19:31:39 2002
@@ -48,6 +48,7 @@
 #include <linux/udp.h>
 #include <linux/proc_fs.h>
 #include <linux/major.h>
+#include <linux/root_dev.h>
 #include <net/arp.h>
 #include <net/ip.h>
 #include <net/ipconfig.h>
@@ -1145,7 +1146,7 @@
 	 */
 	if (ic_myaddr == INADDR_NONE ||
 #ifdef CONFIG_ROOT_NFS
-	    (major(ROOT_DEV) == UNNAMED_MAJOR
+	    (MAJOR(ROOT_DEV) == UNNAMED_MAJOR
 	     && root_server_addr == INADDR_NONE
 	     && ic_servaddr == INADDR_NONE) ||
 #endif
@@ -1172,7 +1173,7 @@
 			 * 				-- Chip
 			 */
 #ifdef CONFIG_ROOT_NFS
-			if (kdev_same(ROOT_DEV, mk_kdev(UNNAMED_MAJOR, 255))) {
+			if (ROOT_DEV ==  Root_NFS) {
 				printk(KERN_ERR 
 					"IP-Config: Retrying forever (NFS root)...\n");
 				goto try_try_again;
diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c
--- a/net/irda/af_irda.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/af_irda.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      af_irda.c
  * Version:       0.9
  * Description:   IrDA sockets implementation
@@ -9,37 +9,37 @@
  * Modified at:   Sat Dec 25 21:10:23 1999
  * Modified by:   Dag Brattli <dag@brattli.net>
  * Sources:       af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
- * 
+ *
  *     Copyright (c) 1999 Dag Brattli <dagb@cs.uit.no>
  *     Copyright (c) 1999-2001 Jean Tourrilhes <jt@hpl.hp.com>
  *     All Rights Reserved.
  *
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
- * 
+ *
  *     This program is distributed in the hope that it will be useful,
  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program; if not, write to the Free Software
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *     MA 02111-1307 USA
  *
  *     Linux-IrDA now supports four different types of IrDA sockets:
  *
  *     o SOCK_STREAM:    TinyTP connections with SAR disabled. The
  *                       max SDU size is 0 for conn. of this type
- *     o SOCK_SEQPACKET: TinyTP connections with SAR enabled. TTP may 
+ *     o SOCK_SEQPACKET: TinyTP connections with SAR enabled. TTP may
  *                       fragment the messages, but will preserve
  *                       the message boundaries
- *     o SOCK_DGRAM:     IRDAPROTO_UNITDATA: TinyTP connections with Unitdata 
+ *     o SOCK_DGRAM:     IRDAPROTO_UNITDATA: TinyTP connections with Unitdata
  *                       (unreliable) transfers
  *                       IRDAPROTO_ULTRA: Connectionless and unreliable data
- *     
+ *
  ********************************************************************/
 
 #include <linux/config.h>
@@ -67,7 +67,7 @@
 
 extern int  irda_init(void);
 extern void irda_cleanup(void);
-extern int  irlap_driver_rcv(struct sk_buff *, struct net_device *, 
+extern int  irlap_driver_rcv(struct sk_buff *, struct net_device *,
 			     struct packet_type *);
 
 static int irda_create(struct socket *sock, int protocol);
@@ -125,7 +125,7 @@
  *    Connection has been closed. Check reason to find out why
  *
  */
-static void irda_disconnect_indication(void *instance, void *sap, 
+static void irda_disconnect_indication(void *instance, void *sap,
 				       LM_REASON reason, struct sk_buff *skb)
 {
 	struct irda_sock *self;
@@ -185,9 +185,9 @@
  *    Connections has been confirmed by the remote device
  *
  */
-static void irda_connect_confirm(void *instance, void *sap, 
+static void irda_connect_confirm(void *instance, void *sap,
 				 struct qos_info *qos,
-				 __u32 max_sdu_size, __u8 max_header_size, 
+				 __u32 max_sdu_size, __u8 max_header_size,
 				 struct sk_buff *skb)
 {
 	struct irda_sock *self;
@@ -211,14 +211,14 @@
 	switch (sk->type) {
 	case SOCK_STREAM:
 		if (max_sdu_size != 0) {
-			ERROR(__FUNCTION__ "(), max_sdu_size must be 0\n");
+			ERROR("%s: max_sdu_size must be 0\n", __FUNCTION__);
 			return;
 		}
 		self->max_data_size = irttp_get_max_seg_size(self->tsap);
 		break;
 	case SOCK_SEQPACKET:
 		if (max_sdu_size == 0) {
-			ERROR(__FUNCTION__ "(), max_sdu_size cannot be 0\n");
+			ERROR("%s: max_sdu_size cannot be 0\n", __FUNCTION__);
 			return;
 		}
 		self->max_data_size = max_sdu_size;
@@ -227,7 +227,7 @@
 		self->max_data_size = irttp_get_max_seg_size(self->tsap);
 	};
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), max_data_size=%d\n", 
+	IRDA_DEBUG(2, __FUNCTION__ "(), max_data_size=%d\n",
 		   self->max_data_size);
 
 	memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
@@ -245,14 +245,14 @@
  *    Incoming connection
  *
  */
-static void irda_connect_indication(void *instance, void *sap, 
+static void irda_connect_indication(void *instance, void *sap,
 				    struct qos_info *qos, __u32 max_sdu_size,
 				    __u8 max_header_size, struct sk_buff *skb)
 {
 	struct irda_sock *self;
 	struct sock *sk;
 
- 	self = (struct irda_sock *) instance;
+	self = (struct irda_sock *) instance;
 
 	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
 
@@ -264,20 +264,20 @@
 	self->max_header_size = max_header_size;
 
 	/* IrTTP max SDU size in transmit direction */
-	self->max_sdu_size_tx = max_sdu_size;	
+	self->max_sdu_size_tx = max_sdu_size;
 
 	/* Find out what the largest chunk of data that we can transmit is */
 	switch (sk->type) {
 	case SOCK_STREAM:
 		if (max_sdu_size != 0) {
-			ERROR(__FUNCTION__ "(), max_sdu_size must be 0\n");
+			ERROR("%s: max_sdu_size must be 0\n", __FUNCTION__);
 			return;
 		}
 		self->max_data_size = irttp_get_max_seg_size(self->tsap);
 		break;
 	case SOCK_SEQPACKET:
 		if (max_sdu_size == 0) {
-			ERROR(__FUNCTION__ "(), max_sdu_size cannot be 0\n");
+			ERROR("%s: max_sdu_size cannot be 0\n", __FUNCTION__);
 			return;
 		}
 		self->max_data_size = max_sdu_size;
@@ -286,11 +286,11 @@
 		self->max_data_size = irttp_get_max_seg_size(self->tsap);
 	};
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), max_data_size=%d\n", 
+	IRDA_DEBUG(2, __FUNCTION__ "(), max_data_size=%d\n",
 		   self->max_data_size);
 
 	memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
-	
+
 	skb_queue_tail(&sk->receive_queue, skb);
 	sk->state_change(sk);
 }
@@ -327,19 +327,19 @@
  *    Used by TinyTP to tell us if it can accept more data or not
  *
  */
-static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) 
+static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
 {
 	struct irda_sock *self;
 	struct sock *sk;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
-	
+
 	self = (struct irda_sock *) instance;
 	ASSERT(self != NULL, return;);
 
 	sk = self->sk;
 	ASSERT(sk != NULL, return;);
-	
+
 	switch (flow) {
 	case FLOW_STOP:
 		IRDA_DEBUG(1, __FUNCTION__ "(), IrTTP wants us to slow down\n");
@@ -347,7 +347,7 @@
 		break;
 	case FLOW_START:
 		self->tx_flow = flow;
-		IRDA_DEBUG(1, __FUNCTION__ 
+		IRDA_DEBUG(1, __FUNCTION__
 			   "(), IrTTP wants us to start again\n");
 		wake_up_interruptible(sk->sleep);
 		break;
@@ -367,14 +367,14 @@
  * Note : duplicate from above, but we need our own version that
  * doesn't touch the dtsap_sel and save the full value structure...
  */
-static void irda_getvalue_confirm(int result, __u16 obj_id, 
+static void irda_getvalue_confirm(int result, __u16 obj_id,
 					  struct ias_value *value, void *priv)
 {
 	struct irda_sock *self;
-	
+
 	self = (struct irda_sock *) priv;
 	if (!self) {
-		WARNING(__FUNCTION__ "(), lost myself!\n");
+		WARNING("%s: lost myself!\n", __FUNCTION__);
 		return;
 	}
 
@@ -419,12 +419,12 @@
 						void *priv)
 {
 	struct irda_sock *self;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	self = (struct irda_sock *) priv;
 	if (!self) {
-		WARNING(__FUNCTION__ "(), lost myself!\n");
+		WARNING("%s: lost myself!\n", __FUNCTION__);
 		return;
 	}
 
@@ -456,7 +456,7 @@
 static void irda_discovery_timeout(u_long priv)
 {
 	struct irda_sock *self;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	self = (struct irda_sock *) priv;
@@ -482,10 +482,10 @@
 	notify_t notify;
 
 	if (self->tsap) {
-		WARNING(__FUNCTION__ "(), busy!\n");
+		WARNING("%s: busy!\n", __FUNCTION__);
 		return -EBUSY;
 	}
-	
+
 	/* Initialize callbacks to be used by the IrDA stack */
 	irda_notify_init(&notify);
 	notify.connect_confirm       = irda_connect_confirm;
@@ -498,7 +498,7 @@
 	strncpy(notify.name, name, NOTIFY_MAX_NAME);
 
 	self->tsap = irttp_open_tsap(tsap_sel, DEFAULT_INITIAL_CREDIT,
-				     &notify);	
+				     &notify);
 	if (self->tsap == NULL) {
 		IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to allocate TSAP!\n");
 		return -ENOMEM;
@@ -524,14 +524,14 @@
 		WARNING(__FUNCTION__ "(), busy!\n");
 		return -EBUSY;
 	}
-	
+
 	/* Initialize callbacks to be used by the IrDA stack */
 	irda_notify_init(&notify);
 	notify.udata_indication	= irda_data_indication;
 	notify.instance = self;
 	strncpy(notify.name, "Ultra", NOTIFY_MAX_NAME);
 
-	self->lsap = irlmp_open_lsap(LSAP_CONNLESS, &notify, pid);	
+	self->lsap = irlmp_open_lsap(LSAP_CONNLESS, &notify, pid);
 	if (self->lsap == NULL) {
 		IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to allocate LSAP!\n");
 		return -ENOMEM;
@@ -559,7 +559,7 @@
 	ASSERT(self != NULL, return -1;);
 
 	if (self->iriap) {
-		WARNING(__FUNCTION__ "(), busy with a previous query\n");
+		WARNING("%s: busy with a previous query\n", __FUNCTION__);
 		return -EBUSY;
 	}
 
@@ -596,10 +596,10 @@
 	case IAS_INTEGER:
 		IRDA_DEBUG(4, __FUNCTION__ "() int=%d\n",
 			   self->ias_result->t.integer);
-		
+
 		if (self->ias_result->t.integer != -1)
 			self->dtsap_sel = self->ias_result->t.integer;
-		else 
+		else
 			self->dtsap_sel = 0;
 		break;
 	default:
@@ -655,7 +655,7 @@
 	if (discoveries == NULL)
 		return -ENETUNREACH;	/* No nodes discovered */
 
-	/* 
+	/*
 	 * Now, check all discovered devices (if any), and connect
 	 * client only about the services that the client is
 	 * interested in...
@@ -714,7 +714,7 @@
 	self->saddr = 0x0;
 	self->dtsap_sel = dtsap_sel;
 
-	IRDA_DEBUG(1, __FUNCTION__ 
+	IRDA_DEBUG(1, __FUNCTION__
 		   "(), discovered requested service ''%s'' at address %08x\n",
 		   name, self->daddr);
 
@@ -737,7 +737,7 @@
 	if (peer) {
 		if (sk->state != TCP_ESTABLISHED)
 			return -ENOTCONN;
-		
+
 		saddr.sir_family = AF_IRDA;
 		saddr.sir_lsap_sel = self->dtsap_sel;
 		saddr.sir_addr = self->daddr;
@@ -746,7 +746,7 @@
 		saddr.sir_lsap_sel = self->stsap_sel;
 		saddr.sir_addr = self->saddr;
 	}
-	
+
 	IRDA_DEBUG(1, __FUNCTION__ "(), tsap_sel = %#x\n", saddr.sir_lsap_sel);
 	IRDA_DEBUG(1, __FUNCTION__ "(), addr = %08x\n", saddr.sir_addr);
 
@@ -776,10 +776,10 @@
 	if (sk->state != TCP_LISTEN) {
 		sk->max_ack_backlog = backlog;
 		sk->state           = TCP_LISTEN;
-		
+
 		return 0;
 	}
-	
+
 	return -EOPNOTSUPP;
 }
 
@@ -808,14 +808,14 @@
 	if ((sk->type == SOCK_DGRAM) && (sk->protocol == IRDAPROTO_ULTRA)) {
 		self->pid = addr->sir_lsap_sel;
 		if (self->pid & 0x80) {
-			IRDA_DEBUG(0, __FUNCTION__ 
+			IRDA_DEBUG(0, __FUNCTION__
 				   "(), extension in PID not supp!\n");
 			return -EOPNOTSUPP;
 		}
 		err = irda_open_lsap(self, self->pid);
 		if (err < 0)
 			return err;
-		
+
 		self->max_data_size = ULTRA_MAX_DATA - LMP_PID_HEADER;
 		self->max_header_size = IRDA_MAX_HEADER + LMP_PID_HEADER;
 
@@ -830,13 +830,13 @@
 	err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name);
 	if (err < 0)
 		return err;
-	
+
 	/*  Register with LM-IAS */
 	self->ias_obj = irias_new_object(addr->sir_name, jiffies);
-	irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel", 
+	irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel",
 				 self->stsap_sel, IAS_KERNEL_ATTR);
 	irias_insert_object(self->ias_obj);
-	
+
 	return 0;
 }
 
@@ -872,7 +872,7 @@
 	    (sk->type != SOCK_DGRAM))
 		return -EOPNOTSUPP;
 
-	if (sk->state != TCP_LISTEN) 
+	if (sk->state != TCP_LISTEN)
 		return -EINVAL;
 
 	/*
@@ -921,7 +921,7 @@
 			return -ERESTARTSYS;
 	}
 
- 	newsk = newsock->sk;
+	newsk = newsock->sk;
 	newsk->state = TCP_ESTABLISHED;
 
 	new = irda_sk(newsk);
@@ -933,7 +933,7 @@
 		IRDA_DEBUG(0, __FUNCTION__ "(), dup failed!\n");
 		return -1;
 	}
-		
+
 	new->stsap_sel = new->tsap->stsap_sel;
 	new->dtsap_sel = new->tsap->dtsap_sel;
 	new->saddr = irttp_get_saddr(new->tsap);
@@ -988,7 +988,7 @@
 	struct sockaddr_irda *addr = (struct sockaddr_irda *) uaddr;
 	struct irda_sock *self = irda_sk(sk);
 	int err;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
 
 	/* Don't allow connect for Ultra sockets */
@@ -999,16 +999,16 @@
 		sock->state = SS_CONNECTED;
 		return 0;   /* Connect completed during a ERESTARTSYS event */
 	}
-	
+
 	if (sk->state == TCP_CLOSE && sock->state == SS_CONNECTING) {
 		sock->state = SS_UNCONNECTED;
 		return -ECONNREFUSED;
 	}
-	
+
 	if (sk->state == TCP_ESTABLISHED)
 		return -EISCONN;      /* No reconnect on a seqpacket socket */
-	
-	sk->state   = TCP_CLOSE;	
+
+	sk->state   = TCP_CLOSE;
 	sock->state = SS_UNCONNECTED;
 
 	if (addr_len != sizeof(struct sockaddr_irda))
@@ -1019,7 +1019,7 @@
 		/* Try to find one suitable */
 		err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name);
 		if (err) {
-			IRDA_DEBUG(0, __FUNCTION__ 
+			IRDA_DEBUG(0, __FUNCTION__
 				   "(), auto-connect failed!\n");
 			return err;
 		}
@@ -1027,7 +1027,7 @@
 		/* Use the one provided by the user */
 		self->daddr = addr->sir_addr;
 		IRDA_DEBUG(1, __FUNCTION__ "(), daddr = %08x\n", self->daddr);
-		
+
 		/* Query remote LM-IAS */
 		err = irda_find_lsap_sel(self, addr->sir_name);
 		if (err) {
@@ -1039,14 +1039,14 @@
 	/* Check if we have opened a local TSAP */
 	if (!self->tsap)
 		irda_open_tsap(self, LSAP_ANY, addr->sir_name);
-	
+
 	/* Move to connecting socket, start sending Connect Requests */
 	sock->state = SS_CONNECTING;
 	sk->state   = TCP_SYN_SENT;
 
 	/* Connect to remote device */
-	err = irttp_connect_request(self->tsap, self->dtsap_sel, 
-				    self->saddr, self->daddr, NULL, 
+	err = irttp_connect_request(self->tsap, self->dtsap_sel,
+				    self->saddr, self->daddr, NULL,
 				    self->max_sdu_size_rx, NULL);
 	if (err) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n");
@@ -1064,9 +1064,9 @@
 		sock->state = SS_UNCONNECTED;
 		return sock_error(sk);	/* Always set at this point */
 	}
-	
+
 	sock->state = SS_CONNECTED;
-	
+
 	/* At this point, IrLMP has assigned our source address */
 	self->saddr = irttp_get_saddr(self->tsap);
 
@@ -1085,7 +1085,7 @@
 	struct irda_sock *self;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
-	
+
 	/* Check for valid socket type */
 	switch (sock->type) {
 	case SOCK_STREAM:     /* For TTP connections with SAR disabled */
@@ -1112,7 +1112,7 @@
 
 	init_waitqueue_head(&self->query_wait);
 
-	/* Initialise networking socket struct */ 
+	/* Initialise networking socket struct */
 	sock_init_data(sock, sk);	/* Note : set sk->refcnt to 1 */
 	sk->family = PF_IRDA;
 	sk->protocol = protocol;
@@ -1141,13 +1141,13 @@
 			self->max_sdu_size_rx = TTP_SAR_UNBOUND;
 			break;
 		default:
-			ERROR(__FUNCTION__ "(), protocol not supported!\n");
+			ERROR("%s: protocol not supported!\n", __FUNCTION__);
 			return -ESOCKTNOSUPPORT;
 		}
 		break;
 	default:
 		return -ESOCKTNOSUPPORT;
-	}		
+	}
 
 	/* Register as a client with IrLMP */
 	self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
@@ -1202,25 +1202,22 @@
 #endif /* CONFIG_IRDA_ULTRA */
 	kfree(self);
 	MOD_DEC_USE_COUNT;
-	
+
 	return;
 }
 
 /*
  * Function irda_release (sock)
- *
- *    
- *
  */
 static int irda_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
-        if (sk == NULL) 
+        if (sk == NULL)
 		return 0;
-	
+
 	sk->state       = TCP_CLOSE;
 	sk->shutdown   |= SEND_SHUTDOWN;
 	sk->state_change(sk);
@@ -1231,7 +1228,7 @@
 	irda_sk(sk) = NULL;
 
 	sock_orphan(sk);
-	sock->sk   = NULL;      
+	sock->sk   = NULL;
 
 	/* Purge queues (see sock_init_data()) */
 	skb_queue_purge(&sk->receive_queue);
@@ -1248,7 +1245,7 @@
 	 * 1) This may include IAS request, both in connect and getsockopt.
 	 * Unfortunately, the situation is a bit more messy than it looks,
 	 * because we close iriap and kfree(self) above.
-	 * 
+	 *
 	 * 2) This may include selective discovery in getsockopt.
 	 * Same stuff as above, irlmp registration and self are gone.
 	 *
@@ -1273,10 +1270,10 @@
  * Function irda_sendmsg (sock, msg, len, scm)
  *
  *    Send message down to TinyTP. This function is used for both STREAM and
- *    SEQPACK services. This is possible since it forces the client to 
+ *    SEQPACK services. This is possible since it forces the client to
  *    fragment the message if necessary
  */
-static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len, 
+static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len,
 			struct scm_cookie *scm)
 {
 	struct sock *sk = sock->sk;
@@ -1314,24 +1311,24 @@
 
 	/* Check that we don't send out to big frames */
 	if (len > self->max_data_size) {
-		IRDA_DEBUG(2, __FUNCTION__ 
-			   "(), Chopping frame from %d to %d bytes!\n", len, 
+		IRDA_DEBUG(2, __FUNCTION__
+			   "(), Chopping frame from %d to %d bytes!\n", len,
 			   self->max_data_size);
 		len = self->max_data_size;
 	}
 
-	skb = sock_alloc_send_skb(sk, len + self->max_header_size, 
+	skb = sock_alloc_send_skb(sk, len + self->max_header_size,
 				  msg->msg_flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		return -ENOBUFS;
 
 	skb_reserve(skb, self->max_header_size);
-	
+
 	asmptr = skb->h.raw = skb_put(skb, len);
 	memcpy_fromiovec(asmptr, msg->msg_iov, len);
 
-	/* 
-	 * Just send the message to TinyTP, and let it deal with possible 
+	/*
+	 * Just send the message to TinyTP, and let it deal with possible
 	 * errors. No need to duplicate all that here
 	 */
 	err = irttp_data_request(self->tsap, skb);
@@ -1349,7 +1346,7 @@
  *    Try to receive message and copy it to user. The frame is discarded
  *    after being read, regardless of how much the user actually read
  */
-static int irda_recvmsg_dgram(struct socket *sock, struct msghdr *msg, 
+static int irda_recvmsg_dgram(struct socket *sock, struct msghdr *msg,
 			      int size, int flags, struct scm_cookie *scm)
 {
 	struct sock *sk = sock->sk;
@@ -1361,16 +1358,16 @@
 
 	ASSERT(self != NULL, return -1;);
 
-	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, 
+	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
 				flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		return err;
 
 	skb->h.raw = skb->data;
 	copied     = skb->len;
-	
+
 	if (copied > size) {
-		IRDA_DEBUG(2, __FUNCTION__ 
+		IRDA_DEBUG(2, __FUNCTION__
 			   "(), Received truncated frame (%d < %d)!\n",
 			   copied, size);
 		copied = size;
@@ -1423,11 +1420,8 @@
 
 /*
  * Function irda_recvmsg_stream (sock, msg, size, flags, scm)
- *
- *    
- *
  */
-static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, 
+static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg,
 			       int size, int flags, struct scm_cookie *scm)
 {
 	struct sock *sk = sock->sk;
@@ -1440,7 +1434,7 @@
 
 	ASSERT(self != NULL, return -1;);
 
-	if (sock->flags & __SO_ACCEPTCON) 
+	if (sock->flags & __SO_ACCEPTCON)
 		return(-EINVAL);
 
 	if (flags & MSG_OOB)
@@ -1448,7 +1442,7 @@
 
 	if (flags & MSG_WAITALL)
 		target = size;
-		
+
 	msg->msg_namelen = 0;
 
 	do {
@@ -1459,11 +1453,11 @@
 		if (skb==NULL) {
 			if (copied >= target)
 				break;
-			
+
 			/*
 			 *	POSIX 1003.1g mandates this order.
 			 */
-			
+
 			if (sk->err) {
 				return sock_error(sk);
 			}
@@ -1500,7 +1494,7 @@
 				break;
 			}
 
-			kfree_skb(skb);			
+			kfree_skb(skb);
 		} else {
 			IRDA_DEBUG(0, __FUNCTION__ "() questionable!?\n");
 
@@ -1542,9 +1536,9 @@
 	struct sk_buff *skb;
 	unsigned char *asmptr;
 	int err;
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len);
-	
+
 	if (msg->msg_flags & ~MSG_DONTWAIT)
 		return -EINVAL;
 
@@ -1559,30 +1553,30 @@
 	self = irda_sk(sk);
 	ASSERT(self != NULL, return -1;);
 
-	/*  
-	 * Check that we don't send out to big frames. This is an unreliable 
-	 * service, so we have no fragmentation and no coalescence 
+	/*
+	 * Check that we don't send out to big frames. This is an unreliable
+	 * service, so we have no fragmentation and no coalescence
 	 */
 	if (len > self->max_data_size) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), Warning to much data! "
-			   "Chopping frame from %d to %d bytes!\n", len, 
+			   "Chopping frame from %d to %d bytes!\n", len,
 			   self->max_data_size);
 		len = self->max_data_size;
 	}
 
-	skb = sock_alloc_send_skb(sk, len + self->max_header_size, 
+	skb = sock_alloc_send_skb(sk, len + self->max_header_size,
 				  msg->msg_flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		return -ENOBUFS;
 
 	skb_reserve(skb, self->max_header_size);
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(), appending user data\n");
 	asmptr = skb->h.raw = skb_put(skb, len);
 	memcpy_fromiovec(asmptr, msg->msg_iov, len);
 
-	/* 
-	 * Just send the message to TinyTP, and let it deal with possible 
+	/*
+	 * Just send the message to TinyTP, and let it deal with possible
 	 * errors. No need to duplicate all that here
 	 */
 	err = irttp_udata_request(self->tsap, skb);
@@ -1608,9 +1602,9 @@
 	struct sk_buff *skb;
 	unsigned char *asmptr;
 	int err;
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len);
-	
+
 	if (msg->msg_flags & ~MSG_DONTWAIT)
 		return -EINVAL;
 
@@ -1622,24 +1616,24 @@
 	self = irda_sk(sk);
 	ASSERT(self != NULL, return -1;);
 
-	/*  
-	 * Check that we don't send out to big frames. This is an unreliable 
-	 * service, so we have no fragmentation and no coalescence 
+	/*
+	 * Check that we don't send out to big frames. This is an unreliable
+	 * service, so we have no fragmentation and no coalescence
 	 */
 	if (len > self->max_data_size) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), Warning to much data! "
-			   "Chopping frame from %d to %d bytes!\n", len, 
+			   "Chopping frame from %d to %d bytes!\n", len,
 			   self->max_data_size);
 		len = self->max_data_size;
 	}
 
-	skb = sock_alloc_send_skb(sk, len + self->max_header_size, 
+	skb = sock_alloc_send_skb(sk, len + self->max_header_size,
 				  msg->msg_flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		return -ENOBUFS;
 
 	skb_reserve(skb, self->max_header_size);
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(), appending user data\n");
 	asmptr = skb->h.raw = skb_put(skb, len);
 	memcpy_fromiovec(asmptr, msg->msg_iov, len);
@@ -1655,9 +1649,6 @@
 
 /*
  * Function irda_shutdown (sk, how)
- *
- *    
- *
  */
 static int irda_shutdown(struct socket *sock, int how)
 {
@@ -1693,11 +1684,8 @@
 
 /*
  * Function irda_poll (file, sock, wait)
- *
- *    
- *
  */
-static unsigned int irda_poll(struct file * file, struct socket *sock, 
+static unsigned int irda_poll(struct file * file, struct socket *sock,
 			      poll_table *wait)
 {
 	struct sock *sk = sock->sk;
@@ -1732,7 +1720,7 @@
 		}
 
 		if (sk->state == TCP_ESTABLISHED) {
-			if ((self->tx_flow == FLOW_START) && 
+			if ((self->tx_flow == FLOW_START) &&
 			    sock_writeable(sk))
 			{
 				mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
@@ -1740,9 +1728,9 @@
 		}
 		break;
 	case SOCK_SEQPACKET:
-		if ((self->tx_flow == FLOW_START) && 
+		if ((self->tx_flow == FLOW_START) &&
 		    sock_writeable(sk))
-		{	
+		{
 			mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 		}
 		break;
@@ -1752,22 +1740,19 @@
 		break;
 	default:
 		break;
-	}		
+	}
 	return mask;
 }
 
 /*
  * Function irda_ioctl (sock, cmd, arg)
- *
- *    
- *
  */
 static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	struct sock *sk = sock->sk;
 
 	IRDA_DEBUG(4, __FUNCTION__ "(), cmd=%#x\n", cmd);
-	
+
 	switch (cmd) {
 	case TIOCOUTQ: {
 		long amount;
@@ -1778,7 +1763,7 @@
 			return -EFAULT;
 		return 0;
 	}
-	
+
 	case TIOCINQ: {
 		struct sk_buff *skb;
 		long amount = 0L;
@@ -1789,18 +1774,18 @@
 			return -EFAULT;
 		return 0;
 	}
-	
+
 	case SIOCGSTAMP:
 		if (sk != NULL) {
 			if (sk->stamp.tv_sec == 0)
 				return -ENOENT;
-			if (copy_to_user((void *)arg, &sk->stamp, 
+			if (copy_to_user((void *)arg, &sk->stamp,
 					 sizeof(struct timeval)))
 				return -EFAULT;
 			return 0;
 		}
 		return -EINVAL;
-		
+
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
 	case SIOCGIFDSTADDR:
@@ -1811,7 +1796,7 @@
 	case SIOCSIFNETMASK:
 	case SIOCGIFMETRIC:
 	case SIOCSIFMETRIC:
-		return -EINVAL;		
+		return -EINVAL;
 	default:
 		IRDA_DEBUG(1, __FUNCTION__ "(), doing device ioctl!\n");
 		return dev_ioctl(cmd, (void *) arg);
@@ -1827,23 +1812,23 @@
  *    Set some options for the socket
  *
  */
-static int irda_setsockopt(struct socket *sock, int level, int optname, 
+static int irda_setsockopt(struct socket *sock, int level, int optname,
 			   char *optval, int optlen)
 {
- 	struct sock *sk = sock->sk;
+	struct sock *sk = sock->sk;
 	struct irda_sock *self = irda_sk(sk);
 	struct irda_ias_set    *ias_opt;
 	struct ias_object      *ias_obj;
 	struct ias_attrib *	ias_attr;	/* Attribute in IAS object */
 	int opt;
-	
+
 	ASSERT(self != NULL, return -1;);
 
 	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
 
 	if (level != SOL_IRLMP)
 		return -ENOPROTOOPT;
-		
+
 	switch (optname) {
 	case IRLMP_IAS_SET:
 		/* The user want to add an attribute to an existing IAS object
@@ -1855,7 +1840,7 @@
 
 		if (optlen != sizeof(struct irda_ias_set))
 			return -EINVAL;
-	
+
 		ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
 		if (ias_opt == NULL)
 			return -ENOMEM;
@@ -1863,7 +1848,7 @@
 		/* Copy query to the driver. */
 		if (copy_from_user(ias_opt, (char *)optval, optlen)) {
 			kfree(ias_opt);
-		  	return -EFAULT;
+			return -EFAULT;
 		}
 
 		/* Find the object we target.
@@ -1907,7 +1892,7 @@
 			/* Add an integer attribute */
 			irias_add_integer_attrib(
 				ias_obj,
-				ias_opt->irda_attrib_name, 
+				ias_opt->irda_attrib_name,
 				ias_opt->attribute.irda_attrib_int,
 				IAS_USER_ATTR);
 			break;
@@ -1921,7 +1906,7 @@
 			/* Add an octet sequence attribute */
 			irias_add_octseq_attrib(
 			      ias_obj,
-			      ias_opt->irda_attrib_name, 
+			      ias_opt->irda_attrib_name,
 			      ias_opt->attribute.irda_attrib_octet_seq.octet_seq,
 			      ias_opt->attribute.irda_attrib_octet_seq.len,
 			      IAS_USER_ATTR);
@@ -1939,7 +1924,7 @@
 			/* Add a string attribute */
 			irias_add_string_attrib(
 				ias_obj,
-				ias_opt->irda_attrib_name, 
+				ias_opt->irda_attrib_name,
 				ias_opt->attribute.irda_attrib_string.string,
 				IAS_USER_ATTR);
 			break;
@@ -1958,15 +1943,15 @@
 
 		if (optlen != sizeof(struct irda_ias_set))
 			return -EINVAL;
-	
+
 		ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
 		if (ias_opt == NULL)
 			return -ENOMEM;
-	
+
 		/* Copy query to the driver. */
 		if (copy_from_user(ias_opt, (char *)optval, optlen)) {
 			kfree(ias_opt);
-		  	return -EFAULT;
+			return -EFAULT;
 		}
 
 		/* Find the object we target.
@@ -1993,7 +1978,7 @@
 
 		/* Find the attribute (in the object) we target */
 		ias_attr = irias_find_attrib(ias_obj,
-					     ias_opt->irda_attrib_name); 
+					     ias_opt->irda_attrib_name);
 		if(ias_attr == (struct ias_attrib *) NULL) {
 			kfree(ias_opt);
 			return -EINVAL;
@@ -2001,7 +1986,7 @@
 
 		/* Check is the user space own the object */
 		if(ias_attr->value->owner != IAS_USER_ATTR) {
-			IRDA_DEBUG(1, __FUNCTION__ 
+			IRDA_DEBUG(1, __FUNCTION__
 				   "(), attempting to delete a kernel attribute\n");
 			kfree(ias_opt);
 			return -EPERM;
@@ -2014,26 +1999,25 @@
 	case IRLMP_MAX_SDU_SIZE:
 		if (optlen < sizeof(int))
 			return -EINVAL;
-	
+
 		if (get_user(opt, (int *)optval))
 			return -EFAULT;
-		
+
 		/* Only possible for a seqpacket service (TTP with SAR) */
 		if (sk->type != SOCK_SEQPACKET) {
-			IRDA_DEBUG(2, __FUNCTION__ 
+			IRDA_DEBUG(2, __FUNCTION__
 				   "(), setting max_sdu_size = %d\n", opt);
 			self->max_sdu_size_rx = opt;
 		} else {
-			WARNING(__FUNCTION__ 
-				"(), not allowed to set MAXSDUSIZE for this "
-				"socket type!\n");
+			WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n",
+					__FUNCTION__);
 			return -ENOPROTOOPT;
 		}
 		break;
 	case IRLMP_HINTS_SET:
 		if (optlen < sizeof(int))
 			return -EINVAL;
-	
+
 		if (get_user(opt, (int *)optval))
 			return -EFAULT;
 
@@ -2051,7 +2035,7 @@
 		 */
 		if (optlen < sizeof(int))
 			return -EINVAL;
-	
+
 		if (get_user(opt, (int *)optval))
 			return -EFAULT;
 
@@ -2112,20 +2096,17 @@
 	default :
 		return -EINVAL;
 	}
-	
+
 	/* Copy type over */
 	ias_opt->irda_attrib_type = ias_value->type;
-	
+
 	return 0;
 }
 
 /*
  * Function irda_getsockopt (sock, level, optname, optval, optlen)
- *
- *    
- *
  */
-static int irda_getsockopt(struct socket *sock, int level, int optname, 
+static int irda_getsockopt(struct socket *sock, int level, int optname,
 			   char *optval, int *optlen)
 {
 	struct sock *sk = sock->sk;
@@ -2151,7 +2132,7 @@
 
 	if(len < 0)
 		return -EINVAL;
-		
+
 	switch (optname) {
 	case IRLMP_ENUMDEVICES:
 		/* Ask lmp for the current discovery log */
@@ -2163,13 +2144,13 @@
 		err = 0;
 
 		/* Write total list length back to client */
-		if (copy_to_user(optval, &list, 
+		if (copy_to_user(optval, &list,
 				 sizeof(struct irda_device_list) -
 				 sizeof(struct irda_device_info)))
 			err = -EFAULT;
 
 		/* Offset to first device entry */
-		offset = sizeof(struct irda_device_list) - 
+		offset = sizeof(struct irda_device_list) -
 			sizeof(struct irda_device_info);
 
 		/* Copy the list itself - watch for overflow */
@@ -2198,7 +2179,7 @@
 		len = sizeof(int);
 		if (put_user(len, optlen))
 			return -EFAULT;
-		
+
 		if (copy_to_user(optval, &val, len))
 			return -EFAULT;
 		break;
@@ -2218,7 +2199,7 @@
 		/* Copy query to the driver. */
 		if (copy_from_user((char *) ias_opt, (char *)optval, len)) {
 			kfree(ias_opt);
-		  	return -EFAULT;
+			return -EFAULT;
 		}
 
 		/* Find the object we target.
@@ -2236,7 +2217,7 @@
 
 		/* Find the attribute (in the object) we target */
 		ias_attr = irias_find_attrib(ias_obj,
-					     ias_opt->irda_attrib_name); 
+					     ias_opt->irda_attrib_name);
 		if(ias_attr == (struct ias_attrib *) NULL) {
 			kfree(ias_opt);
 			return -EINVAL;
@@ -2253,7 +2234,7 @@
 		if (copy_to_user((char *)optval, (char *) ias_opt,
 				 sizeof(struct irda_ias_set))) {
 			kfree(ias_opt);
-		  	return -EFAULT;
+			return -EFAULT;
 		}
 		/* Note : don't need to put optlen, we checked it */
 		kfree(ias_opt);
@@ -2274,7 +2255,7 @@
 		/* Copy query to the driver. */
 		if (copy_from_user((char *) ias_opt, (char *)optval, len)) {
 			kfree(ias_opt);
-		  	return -EFAULT;
+			return -EFAULT;
 		}
 
 		/* At this point, there are two cases...
@@ -2301,8 +2282,8 @@
 
 		/* Check that we can proceed with IAP */
 		if (self->iriap) {
-			WARNING(__FUNCTION__
-				"(), busy with a previous query\n");
+			WARNING("%s: busy with a previous query\n",
+					__FUNCTION__);
 			kfree(ias_opt);
 			return -EBUSY;
 		}
@@ -2359,7 +2340,7 @@
 		if (copy_to_user((char *)optval, (char *) ias_opt,
 				 sizeof(struct irda_ias_set))) {
 			kfree(ias_opt);
-		  	return -EFAULT;
+			return -EFAULT;
 		}
 		/* Note : don't need to put optlen, we checked it */
 		kfree(ias_opt);
@@ -2398,7 +2379,7 @@
 		if (!self->cachediscovery) {
 			int ret = 0;
 
-			IRDA_DEBUG(1, __FUNCTION__ 
+			IRDA_DEBUG(1, __FUNCTION__
 				   "(), nothing discovered yet, going to sleep...\n");
 
 			/* Set watchdog timer to expire in <val> ms. */
@@ -2417,14 +2398,14 @@
 			if(timer_pending(&(self->watchdog)))
 				del_timer(&(self->watchdog));
 
-			IRDA_DEBUG(1, __FUNCTION__ 
+			IRDA_DEBUG(1, __FUNCTION__
 				   "(), ...waking up !\n");
 
 			if (ret != 0)
 				return ret;
 		}
 		else
-			IRDA_DEBUG(1, __FUNCTION__ 
+			IRDA_DEBUG(1, __FUNCTION__
 				   "(), found immediately !\n");
 
 		/* Tell IrLMP that we have been notified */
@@ -2445,7 +2426,7 @@
 	default:
 		return -ENOPROTOOPT;
 	}
-	
+
 	return 0;
 }
 
@@ -2456,7 +2437,7 @@
 
 static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
 	family:		PF_IRDA,
-	
+
 	release:	irda_release,
 	bind:		irda_bind,
 	connect:	irda_connect,
@@ -2477,7 +2458,7 @@
 
 static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
 	family:		PF_IRDA,
-	
+
 	release:	irda_release,
 	bind:		irda_bind,
 	connect:	irda_connect,
@@ -2498,7 +2479,7 @@
 
 static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
 	family:		PF_IRDA,
-       
+
 	release:	irda_release,
 	bind:		irda_bind,
 	connect:	irda_connect,
@@ -2520,7 +2501,7 @@
 #ifdef CONFIG_IRDA_ULTRA
 static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
 	family:		PF_IRDA,
-       
+
 	release:	irda_release,
 	bind:		irda_bind,
 	connect:	sock_no_connect,
@@ -2558,11 +2539,11 @@
 			     void *ptr)
 {
 	struct net_device *dev = (struct net_device *) ptr;
-	
+
         /* Reject non IrDA devices */
-	if (dev->type != ARPHRD_IRDA) 
+	if (dev->type != ARPHRD_IRDA)
 		return NOTIFY_DONE;
-	
+
         switch (event) {
 	case NETDEV_UP:
 		IRDA_DEBUG(3, __FUNCTION__ "(), NETDEV_UP\n");
@@ -2581,7 +2562,7 @@
         return NOTIFY_DONE;
 }
 
-static struct packet_type irda_packet_type = 
+static struct packet_type irda_packet_type =
 {
 	0,	/* MUTTER ntohs(ETH_P_IRDA),*/
 	NULL,
@@ -2630,7 +2611,7 @@
 	register_netdevice_notifier(&irda_dev_notifier);
 
 	irda_init();
- 	irda_device_init();
+	irda_device_init();
 	return 0;
 }
 
@@ -2649,16 +2630,16 @@
         dev_remove_pack(&irda_packet_type);
 
         unregister_netdevice_notifier(&irda_dev_notifier);
-	
+
 	sock_unregister(PF_IRDA);
 	irda_cleanup();
-	
+
         return;
 }
 module_exit(irda_proto_cleanup);
- 
+
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem"); 
+MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
 MODULE_LICENSE("GPL");
 #ifdef CONFIG_IRDA_DEBUG
 MODULE_PARM(irda_debug, "1l");
diff -Nru a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
--- a/net/irda/ircomm/ircomm_core.c	Sun Jun 16 19:31:39 2002
+++ b/net/irda/ircomm/ircomm_core.c	Sun Jun 16 19:31:39 2002
@@ -514,7 +514,7 @@
 
 	self = (struct ircomm_cb *) hashbin_get_first(ircomm);
 	while (self != NULL) {
-		ASSERT(self->magic == IRCOMM_MAGIC, return len;);
+		ASSERT(self->magic == IRCOMM_MAGIC, break;);
 
 		if(self->line < 0x10)
 			len += sprintf(buf+len, "ircomm%d", self->line);
diff -Nru a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
--- a/net/irda/ircomm/ircomm_tty.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/ircomm/ircomm_tty.c	Sun Jun 16 19:31:40 2002
@@ -525,6 +525,9 @@
 	if (!tty)
 		return;
 
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+
 	save_flags(flags); 
 	cli();
 
@@ -535,9 +538,6 @@
 		IRDA_DEBUG(0, __FUNCTION__ "(), returning 1\n");
 		return;
 	}
-
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
 	if ((tty->count == 1) && (self->open_count != 1)) {
 		/*
diff -Nru a/net/irda/irda_device.c b/net/irda/irda_device.c
--- a/net/irda/irda_device.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/irda_device.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      irda_device.c
  * Version:       0.9
  * Description:   Utility functions used by the device drivers
@@ -8,25 +8,25 @@
  * Created at:    Sat Oct  9 09:22:27 1999
  * Modified at:   Sun Jan 23 17:41:24 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
+ *
  *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
- * 
+ *
  *     This program is distributed in the hope that it will be useful,
  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program; if not, write to the Free Software
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *     MA 02111-1307 USA
- *     
+ *
  ********************************************************************/
 
 #include <linux/config.h>
@@ -83,7 +83,7 @@
 #ifdef CONFIG_IRDA_DEBUG
 static const char *task_state[] = {
 	"IRDA_TASK_INIT",
-	"IRDA_TASK_DONE", 
+	"IRDA_TASK_DONE",
 	"IRDA_TASK_WAIT",
 	"IRDA_TASK_WAIT1",
 	"IRDA_TASK_WAIT2",
@@ -97,7 +97,7 @@
 static void irda_task_timer_expired(void *data);
 
 #ifdef CONFIG_PROC_FS
-int irda_device_proc_read(char *buf, char **start, off_t offset, int len, 
+int irda_device_proc_read(char *buf, char **start, off_t offset, int len,
 			  int unused);
 
 #endif /* CONFIG_PROC_FS */
@@ -106,21 +106,19 @@
 {
 	dongles = hashbin_new(HB_GLOBAL);
 	if (dongles == NULL) {
-		printk(KERN_WARNING 
-		       "IrDA: Can't allocate dongles hashbin!\n");
+		printk(KERN_WARNING "IrDA: Can't allocate dongles hashbin!\n");
 		return -ENOMEM;
 	}
 
 	tasks = hashbin_new(HB_GLOBAL);
 	if (tasks == NULL) {
-		printk(KERN_WARNING 
-		       "IrDA: Can't allocate tasks hashbin!\n");
+		printk(KERN_WARNING "IrDA: Can't allocate tasks hashbin!\n");
 		return -ENOMEM;
 	}
 
-	/* 
+	/*
 	 * Call the init function of the device drivers that has not been
-	 * compiled as a module 
+	 * compiled as a module
 	 */
 #ifdef CONFIG_IRTTY_SIR
 	irtty_init();
@@ -156,10 +154,10 @@
 	litelink_init();
 #endif
 #ifdef CONFIG_OLD_BELKIN
- 	old_belkin_init();
+	old_belkin_init();
 #endif
 #ifdef CONFIG_EP7211_IR
- 	ep7211_ir_init();
+	ep7211_ir_init();
 #endif
 	return 0;
 }
@@ -178,7 +176,7 @@
  *    Called when we have detected that another station is transmiting
  *    in contention mode.
  */
-void irda_device_set_media_busy(struct net_device *dev, int status) 
+void irda_device_set_media_busy(struct net_device *dev, int status)
 {
 	struct irlap_cb *self;
 
@@ -203,15 +201,15 @@
 }
 
 int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts)
-{	
+{
 	struct if_irda_req req;
 	int ret;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (!dev->do_ioctl) {
-		ERROR(__FUNCTION__ "(), do_ioctl not impl. by "
-		      "device driver\n");
+		ERROR("%s: do_ioctl not impl. by device driver\n",
+				__FUNCTION__);
 		return -1;
 	}
 
@@ -224,15 +222,15 @@
 }
 
 int irda_device_change_speed(struct net_device *dev, __u32 speed)
-{	
+{
 	struct if_irda_req req;
 	int ret;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (!dev->do_ioctl) {
-		ERROR(__FUNCTION__ "(), do_ioctl not impl. by "
-		      "device driver\n");
+		ERROR("%s: do_ioctl not impl. by device driver\n",
+				__FUNCTION__);
 		return -1;
 	}
 
@@ -257,8 +255,8 @@
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (!dev->do_ioctl) {
-		ERROR(__FUNCTION__ "(), do_ioctl not impl. by "
-		      "device driver\n");
+		ERROR("%s: do_ioctl not impl. by device driver\n",
+				__FUNCTION__);
 		return -1;
 	}
 
@@ -279,7 +277,7 @@
 static void __irda_task_delete(struct irda_task *task)
 {
 	del_timer(&task->timer);
-	
+
 	kfree(task);
 }
 
@@ -314,14 +312,14 @@
 	do {
 		timeout = task->function(task);
 		if (count++ > 100) {
-			ERROR(__FUNCTION__ "(), error in task handler!\n");
+			ERROR("%s: error in task handler!\n", __FUNCTION__);
 			irda_task_delete(task);
 			return TRUE;
-		}			
+		}
 	} while ((timeout == 0) && (task->state != IRDA_TASK_DONE));
 
 	if (timeout < 0) {
-		ERROR(__FUNCTION__ "(), Error executing task!\n");
+		ERROR("%s: Error executing task!\n", __FUNCTION__);
 		irda_task_delete(task);
 		return TRUE;
 	}
@@ -346,14 +344,14 @@
 				/* Kick parent task */
 				irda_task_kick(task->parent);
 			}
-		}		
+		}
 		irda_task_delete(task);
 	} else if (timeout > 0) {
-		irda_start_timer(&task->timer, timeout, (void *) task, 
+		irda_start_timer(&task->timer, timeout, (void *) task,
 				 irda_task_timer_expired);
 		finished = FALSE;
 	} else {
-		IRDA_DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__
 			   "(), not finished, and no timeout!\n");
 		finished = FALSE;
 	}
@@ -367,7 +365,7 @@
  *    This function registers and tries to execute tasks that may take some
  *    time to complete. We do it this hairy way since we may have been
  *    called from interrupt context, so it's not possible to use
- *    schedule_timeout() 
+ *    schedule_timeout()
  * Two important notes :
  *	o Make sure you irda_task_delete(task); in case you delete the
  *	  calling instance.
@@ -375,9 +373,9 @@
  *	  want to lock within the task handler.
  * Jean II
  */
-struct irda_task *irda_task_execute(void *instance, 
-				    IRDA_TASK_CALLBACK function, 
-				    IRDA_TASK_CALLBACK finished, 
+struct irda_task *irda_task_execute(void *instance,
+				    IRDA_TASK_CALLBACK function,
+				    IRDA_TASK_CALLBACK finished,
 				    struct irda_task *parent, void *param)
 {
 	struct irda_task *task;
@@ -394,7 +392,7 @@
 	task->function = function;
 	task->finished = finished;
 	task->parent   = parent;
-	task->param    = param;	
+	task->param    = param;
 	task->magic    = IRDA_TASK_MAGIC;
 
 	init_timer(&task->timer);
@@ -433,7 +431,7 @@
  *    This function should be used by low level device drivers in a similar way
  *    as ether_setup() is used by normal network device drivers
  */
-int irda_device_setup(struct net_device *dev) 
+int irda_device_setup(struct net_device *dev)
 {
 	ASSERT(dev != NULL, return -1;);
 
@@ -445,7 +443,7 @@
 
         dev->type            = ARPHRD_IRDA;
         dev->tx_queue_len    = 8; /* Window size + 1 s-frame */
- 
+
 	memset(dev->broadcast, 0xff, 4);
 
 	dev->mtu = 2048;
@@ -491,7 +489,7 @@
 	sprintf(modname, "irda-dongle-%d", type);
 	request_module(modname);
 	}
-#endif /* CONFIG_KMOD */
+#endif
 
 	if (!(reg = hashbin_find(dongles, type, NULL))) {
 		ERROR("IrDA: Unable to find requested dongle\n");
@@ -514,9 +512,6 @@
 
 /*
  * Function irda_device_dongle_cleanup (dongle)
- *
- *    
- *
  */
 int irda_device_dongle_cleanup(dongle_t *dongle)
 {
@@ -531,21 +526,18 @@
 
 /*
  * Function irda_device_register_dongle (dongle)
- *
- *    
- *
  */
 int irda_device_register_dongle(struct dongle_reg *new)
 {
 	/* Check if this dongle has been registred before */
 	if (hashbin_find(dongles, new->type, NULL)) {
-		MESSAGE(__FUNCTION__ "(), Dongle already registered\n");
+		MESSAGE("%s: Dongle already registered\n", __FUNCTION__);
                 return 0;
         }
-	
+
 	/* Insert IrDA dongle into hashbin */
 	hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
-	
+
         return 0;
 }
 
@@ -561,7 +553,7 @@
 
 	node = hashbin_remove(dongles, dongle->type, NULL);
 	if (!node) {
-		ERROR(__FUNCTION__ "(), dongle not found!\n");
+		ERROR("%s: dongle not found!\n", __FUNCTION__);
 		return;
 	}
 }
@@ -574,22 +566,22 @@
  *    driver to find out which modes it support.
  */
 int irda_device_set_mode(struct net_device* dev, int mode)
-{	
+{
 	struct if_irda_req req;
 	int ret;
 
 	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	if (!dev->do_ioctl) {
-		ERROR(__FUNCTION__ "(), set_raw_mode not impl. by "
-		      "device driver\n");
+		ERROR("%s: set_raw_mode not impl. by device driver\n",
+				__FUNCTION__);
 		return -1;
 	}
-	
+
 	req.ifr_mode = mode;
 
 	ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSMODE);
-	
+
 	return ret;
 }
 
@@ -602,9 +594,9 @@
 void setup_dma(int channel, char *buffer, int count, int mode)
 {
 	unsigned long flags;
-	
+
 	flags = claim_dma_lock();
-	
+
 	disable_dma(channel);
 	clear_dma_ff(channel);
 	set_dma_mode(channel, mode);
diff -Nru a/net/irda/iriap.c b/net/irda/iriap.c
--- a/net/irda/iriap.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/iriap.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      iriap.c
  * Version:       0.8
  * Description:   Information Access Protocol (IAP)
@@ -8,18 +8,18 @@
  * Created at:    Thu Aug 21 00:02:07 1997
  * Modified at:   Sat Dec 25 16:42:42 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
  *     All Rights Reserved.
  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
  ********************************************************************/
@@ -59,30 +59,30 @@
 #endif	/* CONFIG_IRDA_DEBUG */
 
 static hashbin_t *iriap = NULL;
-static __u32 service_handle; 
+static __u32 service_handle;
 
 extern char *lmp_reasons[];
 
 static void __iriap_close(struct iriap_cb *self);
 static int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode);
-static void iriap_disconnect_indication(void *instance, void *sap, 
+static void iriap_disconnect_indication(void *instance, void *sap,
 					LM_REASON reason, struct sk_buff *skb);
-static void iriap_connect_indication(void *instance, void *sap, 
+static void iriap_connect_indication(void *instance, void *sap,
 				     struct qos_info *qos, __u32 max_sdu_size,
-				     __u8 max_header_size, 
+				     __u8 max_header_size,
 				     struct sk_buff *skb);
-static void iriap_connect_confirm(void *instance, void *sap, 
-				  struct qos_info *qos, 
+static void iriap_connect_confirm(void *instance, void *sap,
+				  struct qos_info *qos,
 				  __u32 max_sdu_size, __u8 max_header_size,
 				  struct sk_buff *skb);
-static int iriap_data_indication(void *instance, void *sap, 
+static int iriap_data_indication(void *instance, void *sap,
 				 struct sk_buff *skb);
 
 /*
  * Function iriap_init (void)
  *
  *    Initializes the IrIAP layer, called by the module initialization code
- *    in irmod.c 
+ *    in irmod.c
  */
 int __init iriap_init(void)
 {
@@ -98,12 +98,12 @@
 
 	objects = hashbin_new(HB_LOCAL);
 	if (!objects) {
-		WARNING(__FUNCTION__ "(), Can't allocate objects hashbin!\n");
+		WARNING("%s: Can't allocate objects hashbin!\n", __FUNCTION__);
 		return -ENOMEM;
 	}
 
-	/* 
-	 *  Register some default services for IrLMP 
+	/*
+	 *  Register some default services for IrLMP
 	 */
 	hints  = irlmp_service_to_hint(S_COMPUTER);
 	service_handle = irlmp_register_service(hints);
@@ -122,9 +122,9 @@
 				IAS_KERNEL_ATTR);
 	irias_insert_object(obj);
 
-	/*  
-	 *  Register server support with IrLMP so we can accept incoming 
-	 *  connections 
+	/*
+	 *  Register server support with IrLMP so we can accept incoming
+	 *  connections
 	 */
 	server = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
 	if (!server) {
@@ -139,15 +139,15 @@
 /*
  * Function iriap_cleanup (void)
  *
- *    Initializes the IrIAP layer, called by the module cleanup code in 
+ *    Initializes the IrIAP layer, called by the module cleanup code in
  *    irmod.c
  */
 void iriap_cleanup(void)
 {
 	irlmp_unregister_service(service_handle);
-	
+
 	hashbin_delete(iriap, (FREE_FUNC) __iriap_close);
-	hashbin_delete(objects, (FREE_FUNC) __irias_delete_object);	
+	hashbin_delete(objects, (FREE_FUNC) __irias_delete_object);
 }
 
 /*
@@ -155,7 +155,7 @@
  *
  *    Opens an instance of the IrIAP layer, and registers with IrLMP
  */
-struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, 
+struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
 			    CONFIRM_CALLBACK callback)
 {
 	struct iriap_cb *self;
@@ -164,7 +164,7 @@
 
 	self = kmalloc(sizeof(struct iriap_cb), GFP_ATOMIC);
 	if (!self) {
-		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
+		WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 
@@ -172,7 +172,7 @@
 	 *  Initialize instance
 	 */
 	memset(self, 0, sizeof(struct iriap_cb));
-	
+
 	self->magic = IAS_MAGIC;
 	self->mode = mode;
 	if (mode == IAS_CLIENT)
@@ -184,13 +184,13 @@
 	init_timer(&self->watchdog_timer);
 
 	hashbin_insert(iriap, (irda_queue_t *) self, (int) self, NULL);
-	
+
 	/* Initialize state machines */
 	iriap_next_client_state(self, S_DISCONNECT);
 	iriap_next_call_state(self, S_MAKE_CALL);
 	iriap_next_server_state(self, R_DISCONNECT);
 	iriap_next_r_connect_state(self, R_WAITING);
-	
+
 	return self;
 }
 
@@ -261,7 +261,7 @@
 
 	self->lsap = irlmp_open_lsap(slsap_sel, &notify, 0);
 	if (self->lsap == NULL) {
-		ERROR(__FUNCTION__ "(), Unable to allocated LSAP!\n");
+		ERROR("%s: Unable to allocated LSAP!\n", __FUNCTION__);
 		return -1;
 	}
 	self->slsap_sel = self->lsap->slsap_sel;
@@ -275,8 +275,8 @@
  *    Got disconnect, so clean up everything assosiated with this connection
  *
  */
-static void iriap_disconnect_indication(void *instance, void *sap, 
-					LM_REASON reason, 
+static void iriap_disconnect_indication(void *instance, void *sap,
+					LM_REASON reason,
 					struct sk_buff *userdata)
 {
 	struct iriap_cb *self;
@@ -296,18 +296,18 @@
 		IRDA_DEBUG(4, __FUNCTION__ "(), disconnect as client\n");
 
 
-		iriap_do_client_event(self, IAP_LM_DISCONNECT_INDICATION, 
+		iriap_do_client_event(self, IAP_LM_DISCONNECT_INDICATION,
 				      NULL);
-		/* 
-		 * Inform service user that the request failed by sending 
+		/*
+		 * Inform service user that the request failed by sending
 		 * it a NULL value. Warning, the client might close us, so
 		 * remember no to use self anymore after calling confirm
 		 */
 		if (self->confirm)
- 			self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
+			self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
 	} else {
 		IRDA_DEBUG(4, __FUNCTION__ "(), disconnect as server\n");
-		iriap_do_server_event(self, IAP_LM_DISCONNECT_INDICATION, 
+		iriap_do_server_event(self, IAP_LM_DISCONNECT_INDICATION,
 				      NULL);
 		iriap_close(self);
 	}
@@ -318,9 +318,6 @@
 
 /*
  * Function iriap_disconnect_request (handle)
- *
- *    
- *
  */
 void iriap_disconnect_request(struct iriap_cb *self)
 {
@@ -338,35 +335,35 @@
 		return;
 	}
 
-	/* 
-	 *  Reserve space for MUX control and LAP header 
+	/*
+	 *  Reserve space for MUX control and LAP header
 	 */
- 	skb_reserve(skb, LMP_MAX_HEADER);
+	skb_reserve(skb, LMP_MAX_HEADER);
 
 	irlmp_disconnect_request(self->lsap, skb);
 }
 
-void iriap_getinfobasedetails_request(void) 
+void iriap_getinfobasedetails_request(void)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
 }
 
-void iriap_getinfobasedetails_confirm(void) 
+void iriap_getinfobasedetails_confirm(void)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
 }
 
-void iriap_getobjects_request(void) 
+void iriap_getobjects_request(void)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
 }
 
-void iriap_getobjects_confirm(void) 
+void iriap_getobjects_confirm(void)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
 }
 
-void iriap_getvalue(void) 
+void iriap_getvalue(void)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
 }
@@ -378,7 +375,7 @@
  *    name
  */
 int iriap_getvaluebyclass_request(struct iriap_cb *self,
-				  __u32 saddr, __u32 daddr, 
+				  __u32 saddr, __u32 daddr,
 				  char *name, char *attr)
 {
 	struct sk_buff *skb;
@@ -391,18 +388,18 @@
 	/* Client must supply the destination device address */
 	if (!daddr)
 		return -1;
-	
+
 	self->daddr = daddr;
 	self->saddr = saddr;
 
-	/* 
+	/*
 	 *  Save operation, so we know what the later indication is about
 	 */
-	self->operation = GET_VALUE_BY_CLASS; 
+	self->operation = GET_VALUE_BY_CLASS;
 
 	/* Give ourselves 10 secs to finish this operation */
 	iriap_start_watchdog_timer(self, 10*HZ);
-	
+
 	name_len = strlen(name);	/* Up to IAS_MAX_CLASSNAME = 60 */
 	attr_len = strlen(attr);	/* Up to IAS_MAX_ATTRIBNAME = 60 */
 
@@ -412,7 +409,7 @@
 		return -ENOMEM;
 
 	/* Reserve space for MUX and LAP header */
- 	skb_reserve(skb, self->max_header_size);
+	skb_reserve(skb, self->max_header_size);
 	skb_put(skb, 3+name_len+attr_len);
 	frame = skb->data;
 
@@ -435,7 +432,7 @@
  *    to service user.
  *
  */
-void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb) 
+void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb)
 {
 	struct ias_value *value;
 	int charset;
@@ -473,7 +470,7 @@
 		value = irias_new_integer_value(tmp_cpu32);
 
 		/*  Legal values restricted to 0x01-0x6f, page 15 irttp */
-		IRDA_DEBUG(4, __FUNCTION__ "(), lsap=%d\n", value->t.integer); 
+		IRDA_DEBUG(4, __FUNCTION__ "(), lsap=%d\n", value->t.integer);
 		break;
 	case IAS_STRING:
 		charset = fp[n++];
@@ -481,16 +478,16 @@
 		switch (charset) {
 		case CS_ASCII:
 			break;
-/* 		case CS_ISO_8859_1: */
-/* 		case CS_ISO_8859_2: */
-/* 		case CS_ISO_8859_3: */
-/* 		case CS_ISO_8859_4: */
-/* 		case CS_ISO_8859_5: */
-/* 		case CS_ISO_8859_6: */
-/* 		case CS_ISO_8859_7: */
-/* 		case CS_ISO_8859_8: */
-/* 		case CS_ISO_8859_9: */
-/* 		case CS_UNICODE: */
+/*		case CS_ISO_8859_1: */
+/*		case CS_ISO_8859_2: */
+/*		case CS_ISO_8859_3: */
+/*		case CS_ISO_8859_4: */
+/*		case CS_ISO_8859_5: */
+/*		case CS_ISO_8859_6: */
+/*		case CS_ISO_8859_7: */
+/*		case CS_ISO_8859_8: */
+/*		case CS_ISO_8859_9: */
+/*		case CS_UNICODE: */
 		default:
 			IRDA_DEBUG(0, __FUNCTION__
 				   "(), charset %s, not supported\n",
@@ -504,7 +501,7 @@
 		}
 		value_len = fp[n++];
 		IRDA_DEBUG(4, __FUNCTION__ "(), strlen=%d\n", value_len);
-		
+
 		/* Make sure the string is null-terminated */
 		fp[n+value_len] = 0x00;
 		IRDA_DEBUG(4, "Got string %s\n", fp+n);
@@ -515,7 +512,7 @@
 	case IAS_OCT_SEQ:
 		value_len = be16_to_cpu(get_unaligned((__u16 *)(fp+n)));
 		n += 2;
-		
+
 		/* Will truncate to IAS_MAX_OCTET_STRING bytes */
 		value = irias_new_octseq_value(fp+n, value_len);
 		break;
@@ -523,12 +520,12 @@
 		value = irias_new_missing_value();
 		break;
 	}
-	
+
 	/* Finished, close connection! */
 	iriap_disconnect_request(self);
 
 	/* Warning, the client might close us, so remember no to use self
-	 * anymore after calling confirm 
+	 * anymore after calling confirm
 	 */
 	if (self->confirm)
 		self->confirm(IAS_SUCCESS, obj_id, value, self->priv);
@@ -543,9 +540,9 @@
  * Function iriap_getvaluebyclass_response ()
  *
  *    Send answer back to remote LM-IAS
- * 
+ *
  */
-void iriap_getvaluebyclass_response(struct iriap_cb *self, __u16 obj_id, 
+void iriap_getvaluebyclass_response(struct iriap_cb *self, __u16 obj_id,
 				    __u8 ret_code, struct ias_value *value)
 {
 	struct sk_buff *skb;
@@ -563,8 +560,8 @@
 	/* Initialize variables */
 	n = 0;
 
-	/* 
-	 *  We must adjust the size of the response after the length of the 
+	/*
+	 *  We must adjust the size of the response after the length of the
 	 *  value. We add 32 bytes because of the 6 bytes for the frame and
 	 *  max 5 bytes for the value coding.
 	 */
@@ -573,9 +570,9 @@
 		return;
 
 	/* Reserve space for MUX and LAP header */
- 	skb_reserve(skb, self->max_header_size);
+	skb_reserve(skb, self->max_header_size);
 	skb_put(skb, 6);
-	
+
 	fp = skb->data;
 
 	/* Build frame */
@@ -584,7 +581,7 @@
 
 	/* Insert list length (MSB first) */
 	tmp_be16 = __constant_htons(0x0001);
-	memcpy(fp+n, &tmp_be16, 2);  n += 2; 
+	memcpy(fp+n, &tmp_be16, 2);  n += 2;
 
 	/* Insert object identifier ( MSB first) */
 	tmp_be16 = cpu_to_be16(obj_id);
@@ -601,7 +598,7 @@
 	case IAS_INTEGER:
 		skb_put(skb, 5);
 		fp[n++] = value->type;
-		
+
 		tmp_be32 = cpu_to_be32(value->t.integer);
 		memcpy(fp+n, &tmp_be32, 4); n += 4;
 		break;
@@ -631,10 +628,10 @@
  *    getvaluebyclass is requested from peer LM-IAS
  *
  */
-void iriap_getvaluebyclass_indication(struct iriap_cb *self, 
+void iriap_getvaluebyclass_indication(struct iriap_cb *self,
 				      struct sk_buff *skb)
 {
- 	struct ias_object *obj;
+	struct ias_object *obj;
 	struct ias_attrib *attrib;
 	int name_len;
 	int attr_len;
@@ -656,7 +653,7 @@
 	memcpy(name, fp+n, name_len); n+=name_len;
 	name[name_len] = '\0';
 
-	attr_len = fp[n++]; 
+	attr_len = fp[n++];
 	memcpy(attr, fp+n, attr_len); n+=attr_len;
 	attr[attr_len] = '\0';
 
@@ -665,7 +662,7 @@
 
 	IRDA_DEBUG(4, "LM-IAS: Looking up %s: %s\n", name, attr);
 	obj = irias_find_object(name);
-	
+
 	if (obj == NULL) {
 		IRDA_DEBUG(2, "LM-IAS: Object %s not found\n", name);
 		iriap_getvaluebyclass_response(self, 0x1235, IAS_CLASS_UNKNOWN,
@@ -673,7 +670,7 @@
 		return;
 	}
 	IRDA_DEBUG(4, "LM-IAS: found %s, id=%d\n", obj->name, obj->id);
-	
+
 	attrib = irias_find_attrib(obj, attr);
 	if (attrib == NULL) {
 		IRDA_DEBUG(2, "LM-IAS: Attribute %s not found\n", attr);
@@ -681,11 +678,11 @@
 					       IAS_ATTRIB_UNKNOWN, &missing);
 		return;
 	}
-	
+
 	/* We have a match; send the value.  */
-	iriap_getvaluebyclass_response(self, obj->id, IAS_SUCCESS, 
+	iriap_getvaluebyclass_response(self, obj->id, IAS_SUCCESS,
 				       attrib->value);
-	
+
 	return;
 }
 
@@ -695,7 +692,7 @@
  *    Currently not used
  *
  */
-void iriap_send_ack(struct iriap_cb *self) 
+void iriap_send_ack(struct iriap_cb *self)
 {
 	struct sk_buff *skb;
 	__u8 *frame;
@@ -710,7 +707,7 @@
 		return;
 
 	/* Reserve space for MUX and LAP header */
- 	skb_reserve(skb, self->max_header_size);
+	skb_reserve(skb, self->max_header_size);
 	skb_put(skb, 1);
 	frame = skb->data;
 
@@ -727,8 +724,8 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
 
-	ret = irlmp_connect_request(self->lsap, LSAP_IAS, 
-				    self->saddr, self->daddr, 
+	ret = irlmp_connect_request(self->lsap, LSAP_IAS,
+				    self->saddr, self->daddr,
 				    NULL, NULL);
 	if (ret < 0) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n");
@@ -742,22 +739,22 @@
  *    LSAP connection confirmed!
  *
  */
-static void iriap_connect_confirm(void *instance, void *sap, 
-				  struct qos_info *qos, __u32 max_seg_size, 
-				  __u8 max_header_size, 
+static void iriap_connect_confirm(void *instance, void *sap,
+				  struct qos_info *qos, __u32 max_seg_size,
+				  __u8 max_header_size,
 				  struct sk_buff *userdata)
 {
 	struct iriap_cb *self;
-	
+
 	self = (struct iriap_cb *) instance;
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
 	ASSERT(userdata != NULL, return;);
-	
+
 	self->max_data_size = max_seg_size;
 	self->max_header_size = max_header_size;
-	
+
 	del_timer(&self->watchdog_timer);
 
 	iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, userdata);
@@ -769,9 +766,9 @@
  *    Remote LM-IAS is requesting connection
  *
  */
-static void iriap_connect_indication(void *instance, void *sap, 
+static void iriap_connect_indication(void *instance, void *sap,
 				     struct qos_info *qos, __u32 max_seg_size,
-				     __u8 max_header_size, 
+				     __u8 max_header_size,
 				     struct sk_buff *userdata)
 {
 	struct iriap_cb *self, *new;
@@ -782,46 +779,46 @@
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
-	
+
 	/* Start new server */
-	new = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL); 
+	new = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
 	if (!new) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), open failed\n");
 		dev_kfree_skb(userdata);
 		return;
 	}
-	
+
 	/* Now attach up the new "socket" */
 	new->lsap = irlmp_dup(self->lsap, new);
 	if (!new->lsap) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), dup failed!\n");
 		return;
 	}
-		
+
 	new->max_data_size = max_seg_size;
 	new->max_header_size = max_header_size;
 
 	/* Clean up the original one to keep it in listen state */
 	irlmp_listen(self->lsap);
-	
+
 	iriap_do_server_event(new, IAP_LM_CONNECT_INDICATION, userdata);
 }
- 
+
 /*
  * Function iriap_data_indication (handle, skb)
  *
  *    Receives data from connection identified by handle from IrLMP
  *
  */
-static int iriap_data_indication(void *instance, void *sap, 
-				 struct sk_buff *skb) 
+static int iriap_data_indication(void *instance, void *sap,
+				 struct sk_buff *skb)
 {
 	struct iriap_cb *self;
 	__u8  *frame;
 	__u8  opcode;
-	
-	IRDA_DEBUG(3, __FUNCTION__ "()\n"); 
-	
+
+	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+
 	self = (struct iriap_cb *) instance;
 
 	ASSERT(self != NULL, return 0;);
@@ -830,7 +827,7 @@
 	ASSERT(skb != NULL, return 0;);
 
 	frame = skb->data;
-	
+
 	if (self->mode == IAS_SERVER) {
 		/* Call server */
 		IRDA_DEBUG(4, __FUNCTION__ "(), Calling server!\n");
@@ -840,17 +837,17 @@
 	}
 	opcode = frame[0];
 	if (~opcode & IAP_LST) {
-		WARNING(__FUNCTION__ "(), IrIAS multiframe commands or "
-			"results is not implemented yet!\n");
+		WARNING("%s:, IrIAS multiframe commands or "
+			"results is not implemented yet!\n", __FUNCTION__);
 		dev_kfree_skb(skb);
 		return 0;
 	}
-	
+
 	/* Check for ack frames since they don't contain any data */
 	if (opcode & IAP_ACK) {
 		IRDA_DEBUG(0, __FUNCTION__ "() Got ack frame!\n");
 		dev_kfree_skb(skb);
-	 	return 0;
+		return 0;
 	}
 
 	opcode &= ~IAP_LST; /* Mask away LST bit */
@@ -862,7 +859,7 @@
 		break;
 	case GET_VALUE_BY_CLASS:
 		iriap_do_call_event(self, IAP_RECV_F_LST, NULL);
-			
+
 		switch (frame[1]) {
 		case IAS_SUCCESS:
 			iriap_getvaluebyclass_confirm(self, skb);
@@ -872,9 +869,9 @@
 			/* Finished, close connection! */
 			iriap_disconnect_request(self);
 
-			/* 
+			/*
 			 * Warning, the client might close us, so remember
-			 * no to use self anymore after calling confirm 
+			 * no to use self anymore after calling confirm
 			 */
 			if (self->confirm)
 				self->confirm(IAS_CLASS_UNKNOWN, 0, NULL,
@@ -883,22 +880,22 @@
 			break;
 		case IAS_ATTRIB_UNKNOWN:
 			IRDA_DEBUG(1, __FUNCTION__ "(), No such attribute!\n");
-		       	/* Finished, close connection! */
+			/* Finished, close connection! */
 			iriap_disconnect_request(self);
 
-			/* 
+			/*
 			 * Warning, the client might close us, so remember
-			 * no to use self anymore after calling confirm 
+			 * no to use self anymore after calling confirm
 			 */
 			if (self->confirm)
-				self->confirm(IAS_ATTRIB_UNKNOWN, 0, NULL, 
+				self->confirm(IAS_ATTRIB_UNKNOWN, 0, NULL,
 					      self->priv);
 			dev_kfree_skb(skb);
 			break;
-		}		
+		}
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown op-code: %02x\n", 
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown op-code: %02x\n",
 			   opcode);
 		dev_kfree_skb(skb);
 		break;
@@ -927,16 +924,16 @@
 
 	opcode = fp[0];
 	if (~opcode & 0x80) {
-		WARNING(__FUNCTION__ "(), IrIAS multiframe commands or results"
-			"is not implemented yet!\n");
+		WARNING("%s: IrIAS multiframe commands or results"
+			"is not implemented yet!\n", __FUNCTION__);
 		return;
 	}
 	opcode &= 0x7f; /* Mask away LST bit */
-	
+
 	switch (opcode) {
 	case GET_INFO_BASE:
-		WARNING(__FUNCTION__ 
-			"(), GetInfoBaseDetails not implemented yet!\n");
+		WARNING("%s: GetInfoBaseDetails not implemented yet!\n",
+				__FUNCTION__);
 		break;
 	case GET_VALUE_BY_CLASS:
 		iriap_getvaluebyclass_indication(self, skb);
@@ -953,7 +950,7 @@
 void iriap_watchdog_timer_expired(void *data)
 {
 	struct iriap_cb *self = (struct iriap_cb *) data;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
 
@@ -994,23 +991,23 @@
 		len += sprintf(buf+len, "\n");
 
 		/* List all attributes for this object */
-		attrib = (struct ias_attrib *) 
+		attrib = (struct ias_attrib *)
 			hashbin_get_first(obj->attribs);
 		while (attrib != NULL) {
 			ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return 0;);
 
 			len += sprintf(buf+len, " - Attribute name: \"%s\", ",
 				       attrib->name);
-			len += sprintf(buf+len, "value[%s]: ", 
+			len += sprintf(buf+len, "value[%s]: ",
 				       ias_value_types[attrib->value->type]);
-			
+
 			switch (attrib->value->type) {
 			case IAS_INTEGER:
-				len += sprintf(buf+len, "%d\n", 
+				len += sprintf(buf+len, "%d\n",
 					       attrib->value->t.integer);
 				break;
 			case IAS_STRING:
-				len += sprintf(buf+len, "\"%s\"\n", 
+				len += sprintf(buf+len, "\"%s\"\n",
 					       attrib->value->t.string);
 				break;
 			case IAS_OCT_SEQ:
@@ -1020,17 +1017,17 @@
 				len += sprintf(buf+len, "missing\n");
 				break;
 			default:
-				IRDA_DEBUG(0, __FUNCTION__ 
+				IRDA_DEBUG(0, __FUNCTION__
 				      "(), Unknown value type!\n");
 				return -1;
 			}
 			len += sprintf(buf+len, "\n");
-			
-			attrib = (struct ias_attrib *) 
+
+			attrib = (struct ias_attrib *)
 				hashbin_get_next(obj->attribs);
 		}
 	        obj = (struct ias_object *) hashbin_get_next(objects);
- 	} 
+	}
 	restore_flags(flags);
 
 	return len;
diff -Nru a/net/irda/iriap_event.c b/net/irda/iriap_event.c
--- a/net/irda/iriap_event.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/iriap_event.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      iriap_event.c
  * Version:       0.1
  * Description:   IAP Finite State Machine
@@ -8,17 +8,17 @@
  * Created at:    Thu Aug 21 00:02:07 1997
  * Modified at:   Wed Mar  1 11:28:34 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1997, 1999-2000 Dag Brattli <dagb@cs.uit.no>, 
+ *
+ *     Copyright (c) 1997, 1999-2000 Dag Brattli <dagb@cs.uit.no>,
  *     All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
  ********************************************************************/
@@ -28,48 +28,48 @@
 #include <net/irda/iriap.h>
 #include <net/irda/iriap_event.h>
 
-static void state_s_disconnect   (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_disconnect   (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_s_connecting   (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_connecting   (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_s_call         (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_call         (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
 
-static void state_s_make_call    (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_make_call    (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_s_calling      (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_calling      (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_s_outstanding  (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_outstanding  (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_s_replying     (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_replying     (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_s_wait_active  (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_wait_active  (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
 
-static void state_r_disconnect   (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_disconnect   (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_r_call         (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_call         (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_r_waiting      (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_waiting      (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_r_wait_active  (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_wait_active  (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_r_receiving    (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_receiving    (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_r_execute      (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_execute      (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
-static void state_r_returning    (struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_returning    (struct iriap_cb *self, IRIAP_EVENT event,
 				  struct sk_buff *skb);
 
-static void (*iriap_state[])(struct iriap_cb *self, IRIAP_EVENT event, 
-			     struct sk_buff *skb) = { 
+static void (*iriap_state[])(struct iriap_cb *self, IRIAP_EVENT event,
+			     struct sk_buff *skb) = {
 	/* Client FSM */
 	state_s_disconnect,
 	state_s_connecting,
 	state_s_call,
-	
+
 	/* S-Call FSM */
 	state_s_make_call,
 	state_s_calling,
@@ -90,7 +90,7 @@
 	state_r_returning,
 };
 
-void iriap_next_client_state(struct iriap_cb *self, IRIAP_STATE state) 
+void iriap_next_client_state(struct iriap_cb *self, IRIAP_STATE state)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -98,7 +98,7 @@
 	self->client_state = state;
 }
 
-void iriap_next_call_state(struct iriap_cb *self, IRIAP_STATE state) 
+void iriap_next_call_state(struct iriap_cb *self, IRIAP_STATE state)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -118,12 +118,12 @@
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
-	
+
 	self->r_connect_state = state;
 }
 
-void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event, 
-			   struct sk_buff *skb) 
+void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event,
+			   struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -131,30 +131,30 @@
 	(*iriap_state[ self->client_state]) (self, event, skb);
 }
 
-void iriap_do_call_event(struct iriap_cb *self, IRIAP_EVENT event, 
-			 struct sk_buff *skb) 
+void iriap_do_call_event(struct iriap_cb *self, IRIAP_EVENT event,
+			 struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
-	
+
 	(*iriap_state[ self->call_state]) (self, event, skb);
 }
 
-void iriap_do_server_event(struct iriap_cb *self, IRIAP_EVENT event, 
-			   struct sk_buff *skb) 
+void iriap_do_server_event(struct iriap_cb *self, IRIAP_EVENT event,
+			   struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
-	
+
 	(*iriap_state[ self->server_state]) (self, event, skb);
 }
 
-void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event, 
-			      struct sk_buff *skb) 
+void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event,
+			      struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
-	
+
 	(*iriap_state[ self->r_connect_state]) (self, event, skb);
 }
 
@@ -165,8 +165,8 @@
  *    S-Disconnect, The device has no LSAP connection to a particular
  *    remote device.
  */
-static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb) 
+static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
+			       struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -192,8 +192,8 @@
  *    S-Connecting
  *
  */
-static void state_s_connecting(struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb) 
+static void state_s_connecting(struct iriap_cb *self, IRIAP_EVENT event,
+			       struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -223,10 +223,10 @@
  *
  *    S-Call, The device can process calls to a specific remote
  *    device. Whenever the LSAP connection is disconnected, this state
- *    catches that event and clears up 
+ *    catches that event and clears up
  */
-static void state_s_call(struct iriap_cb *self, IRIAP_EVENT event, 
-			 struct sk_buff *skb) 
+static void state_s_call(struct iriap_cb *self, IRIAP_EVENT event,
+			 struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 
@@ -248,8 +248,8 @@
  *    S-Make-Call
  *
  */
-static void state_s_make_call(struct iriap_cb *self, IRIAP_EVENT event, 
-			      struct sk_buff *skb) 
+static void state_s_make_call(struct iriap_cb *self, IRIAP_EVENT event,
+			      struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 
@@ -257,7 +257,7 @@
 	case IAP_CALL_REQUEST:
 		skb = self->skb;
 		self->skb = NULL;
-		
+
 		irlmp_data_request(self->lsap, skb);
 		iriap_next_call_state(self, S_OUTSTANDING);
 		break;
@@ -275,8 +275,8 @@
  *    S-Calling
  *
  */
-static void state_s_calling(struct iriap_cb *self, IRIAP_EVENT event, 
-			    struct sk_buff *skb) 
+static void state_s_calling(struct iriap_cb *self, IRIAP_EVENT event,
+			    struct sk_buff *skb)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
@@ -287,8 +287,8 @@
  *    S-Outstanding, The device is waiting for a response to a command
  *
  */
-static void state_s_outstanding(struct iriap_cb *self, IRIAP_EVENT event, 
-				struct sk_buff *skb) 
+static void state_s_outstanding(struct iriap_cb *self, IRIAP_EVENT event,
+				struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 
@@ -302,7 +302,7 @@
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
-	}		
+	}
 }
 
 /*
@@ -310,8 +310,8 @@
  *
  *    S-Replying, The device is collecting a multiple part response
  */
-static void state_s_replying(struct iriap_cb *self, IRIAP_EVENT event, 
-			     struct sk_buff *skb) 
+static void state_s_replying(struct iriap_cb *self, IRIAP_EVENT event,
+			     struct sk_buff *skb)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
@@ -322,8 +322,8 @@
  *    S-Wait-for-Call
  *
  */
-static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event, 
-				  struct sk_buff *skb) 
+static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event,
+				  struct sk_buff *skb)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
@@ -335,15 +335,15 @@
  *    S-Wait-Active
  *
  */
-static void state_s_wait_active(struct iriap_cb *self, IRIAP_EVENT event, 
-				struct sk_buff *skb) 
+static void state_s_wait_active(struct iriap_cb *self, IRIAP_EVENT event,
+				struct sk_buff *skb)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
 /**************************************************************************
- * 
- *  Server FSM 
+ *
+ *  Server FSM
  *
  **************************************************************************/
 
@@ -353,27 +353,27 @@
  *    LM-IAS server is disconnected (not processing any requests!)
  *
  */
-static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb) 
+static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
+			       struct sk_buff *skb)
 {
 	struct sk_buff *tx_skb;
-	
+
 	switch (event) {
 	case IAP_LM_CONNECT_INDICATION:
 		tx_skb = dev_alloc_skb(64);
 		if (tx_skb == NULL) {
-			WARNING(__FUNCTION__ "(), unable to malloc!\n");
+			WARNING("%s: unable to malloc!\n", __FUNCTION__);
 			return;
 		}
 
 		/* Reserve space for MUX_CONTROL and LAP header */
 		skb_reserve(tx_skb, LMP_MAX_HEADER);
-		
+
 		irlmp_connect_response(self->lsap, tx_skb);
 		/*LM_Idle_request(idle); */
-		
+
 		iriap_next_server_state(self, R_CALL);
-		
+
 		/*
 		 *  Jump to R-Connect FSM, we skip R-Waiting since we do not
 		 *  care about LM_Idle_request()!
@@ -382,22 +382,19 @@
 
 		if (skb)
 			dev_kfree_skb(skb);
-		
+
 		break;
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event %d\n", event);
 		break;
-	}		
+	}
 }
 
 /*
  * Function state_r_call (self, event, skb)
- *
- *    
- *
  */
-static void state_r_call(struct iriap_cb *self, IRIAP_EVENT event, 
-			 struct sk_buff *skb) 
+static void state_r_call(struct iriap_cb *self, IRIAP_EVENT event,
+			 struct sk_buff *skb)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
@@ -405,7 +402,7 @@
 	case IAP_LM_DISCONNECT_INDICATION:
 		/* Abort call */
 		iriap_next_server_state(self, R_DISCONNECT);
-		iriap_next_r_connect_state(self, R_WAITING);		
+		iriap_next_r_connect_state(self, R_WAITING);
 		break;
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event!\n");
@@ -413,24 +410,21 @@
 	}
 }
 
-/* 
- *  R-Connect FSM 
-*/
+/*
+ *  R-Connect FSM
+ */
 
 /*
  * Function state_r_waiting (self, event, skb)
- *
- *    
- *
  */
-static void state_r_waiting(struct iriap_cb *self, IRIAP_EVENT event, 
-			    struct sk_buff *skb) 
+static void state_r_waiting(struct iriap_cb *self, IRIAP_EVENT event,
+			    struct sk_buff *skb)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
-static void state_r_wait_active(struct iriap_cb *self, IRIAP_EVENT event, 
-				struct sk_buff *skb) 
+static void state_r_wait_active(struct iriap_cb *self, IRIAP_EVENT event,
+				struct sk_buff *skb)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
@@ -441,15 +435,15 @@
  *    We are receiving a command
  *
  */
-static void state_r_receiving(struct iriap_cb *self, IRIAP_EVENT event, 
-			      struct sk_buff *skb) 
+static void state_r_receiving(struct iriap_cb *self, IRIAP_EVENT event,
+			      struct sk_buff *skb)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	switch (event) {
 	case IAP_RECV_F_LST:
 		iriap_next_r_connect_state(self, R_EXECUTE);
-	 		
+
 		iriap_call_indication(self, skb);
 		break;
 	default:
@@ -465,26 +459,26 @@
  *    The server is processing the request
  *
  */
-static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event, 
-			    struct sk_buff *skb) 
+static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event,
+			    struct sk_buff *skb)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(skb != NULL, return;);
-	
+
 	if (!self || self->magic != IAS_MAGIC) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), bad pointer self\n");
 		return;
-	}	
+	}
 
 	switch (event) {
 	case IAP_CALL_RESPONSE:
-		/*  
+		/*
 		 *  Since we don't implement the Waiting state, we return
 		 *  to state Receiving instead, DB.
 		 */
 		iriap_next_r_connect_state(self, R_RECEIVING);
-	 		
+
 		irlmp_data_request(self->lsap, skb);
 		break;
 	default:
@@ -493,19 +487,15 @@
 	}
 }
 
-static void state_r_returning(struct iriap_cb *self, IRIAP_EVENT event, 
-			      struct sk_buff *skb) 
+static void state_r_returning(struct iriap_cb *self, IRIAP_EVENT event,
+			      struct sk_buff *skb)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), event=%d\n", event);
 
 	switch (event) {
 	case IAP_RECV_F_LST:
-		
 		break;
 	default:
 		break;
 	}
 }
-
-
-
diff -Nru a/net/irda/irias_object.c b/net/irda/irias_object.c
--- a/net/irda/irias_object.c	Sun Jun 16 19:31:39 2002
+++ b/net/irda/irias_object.c	Sun Jun 16 19:31:39 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      irias_object.c
  * Version:       0.3
  * Description:   IAS object database and functions
@@ -8,18 +8,18 @@
  * Created at:    Thu Oct  1 22:50:04 1998
  * Modified at:   Wed Dec 15 11:23:16 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
+ *
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
- *  
+ *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
- *     
+ *
  ********************************************************************/
 
 #include <linux/string.h>
@@ -47,7 +47,7 @@
 {
 	char *new_str;
 	int len;
-	
+
 	/* Check string */
 	if (str == NULL)
 		return NULL;
@@ -59,14 +59,14 @@
 	/* Allocate new string */
         new_str = kmalloc(len + 1, GFP_ATOMIC);
         if (new_str == NULL) {
-		WARNING(__FUNCTION__"(), Unable to kmalloc!\n");
+		WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 
 	/* Copy and truncate */
 	memcpy(new_str, str, len);
 	new_str[len] = '\0';
-	
+
 	return new_str;
 }
 
@@ -79,10 +79,10 @@
 struct ias_object *irias_new_object( char *name, int id)
 {
         struct ias_object *obj;
-	
+
 	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
 
-	obj = (struct ias_object *) kmalloc(sizeof(struct ias_object), 
+	obj = (struct ias_object *) kmalloc(sizeof(struct ias_object),
 					    GFP_ATOMIC);
 	if (obj == NULL) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unable to allocate object!\n");
@@ -95,7 +95,7 @@
 	obj->id = id;
 
 	obj->attribs = hashbin_new(HB_LOCAL);
-	
+
 	return obj;
 }
 
@@ -115,7 +115,7 @@
 
 	irias_delete_value(attrib->value);
 	attrib->magic = ~IAS_ATTRIB_MAGIC;
-	
+
 	kfree(attrib);
 }
 
@@ -126,11 +126,11 @@
 
 	if (obj->name)
 		kfree(obj->name);
-	
+
 	hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
-	
+
 	obj->magic = ~IAS_OBJECT_MAGIC;
-	
+
 	kfree(obj);
 }
 
@@ -141,7 +141,7 @@
  *    with this object and the object itself
  *
  */
-int irias_delete_object(struct ias_object *obj) 
+int irias_delete_object(struct ias_object *obj)
 {
 	struct ias_object *node;
 
@@ -164,7 +164,7 @@
  *    the object, remove the object as well.
  *
  */
-int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib) 
+int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib)
 {
 	struct ias_attrib *node;
 
@@ -198,7 +198,7 @@
 {
 	ASSERT(obj != NULL, return;);
 	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
-	
+
 	hashbin_insert(objects, (irda_queue_t *) obj, 0, obj->name);
 }
 
@@ -247,7 +247,7 @@
 {
 	ASSERT(obj != NULL, return;);
 	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
-	
+
 	ASSERT(attrib != NULL, return;);
 	ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
 
@@ -263,8 +263,8 @@
  *    Change the value of an objects attribute.
  *
  */
-int irias_object_change_attribute(char *obj_name, char *attrib_name, 
-				  struct ias_value *new_value) 
+int irias_object_change_attribute(char *obj_name, char *attrib_name,
+				  struct ias_value *new_value)
 {
 	struct ias_object *obj;
 	struct ias_attrib *attrib;
@@ -272,7 +272,7 @@
 	/* Find object */
 	obj = hashbin_find(objects, 0, obj_name);
 	if (obj == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to find object: %s\n",
+		WARNING("%s: Unable to find object: %s\n", __FUNCTION__,
 			obj_name);
 		return -1;
 	}
@@ -280,20 +280,20 @@
 	/* Find attribute */
 	attrib = hashbin_find(obj->attribs, 0, attrib_name);
 	if (attrib == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to find attribute: %s\n",
+		WARNING("%s: Unable to find attribute: %s\n", __FUNCTION__,
 			attrib_name);
 		return -1;
 	}
-	
+
 	if ( attrib->value->type != new_value->type) {
-		IRDA_DEBUG( 0, __FUNCTION__ 
+		IRDA_DEBUG( 0, __FUNCTION__
 		       "(), changing value type not allowed!\n");
 		return -1;
 	}
 
 	/* Delete old value */
 	irias_delete_value(attrib->value);
-	
+
 	/* Insert new value */
 	attrib->value = new_value;
 
@@ -315,11 +315,11 @@
 	ASSERT(obj != NULL, return;);
 	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
 	ASSERT(name != NULL, return;);
-	
-	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib), 
+
+	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib),
 					       GFP_ATOMIC);
 	if (attrib == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to allocate attribute!\n");
+		WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__);
 		return;
 	}
 	memset(attrib, 0, sizeof( struct ias_attrib));
@@ -329,7 +329,7 @@
 
 	/* Insert value */
 	attrib->value = irias_new_integer_value(value);
-	
+
 	irias_add_attrib(obj, attrib, owner);
 }
 
@@ -344,27 +344,26 @@
 			     int len, int owner)
 {
 	struct ias_attrib *attrib;
-	
+
 	ASSERT(obj != NULL, return;);
 	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
-	
+
 	ASSERT(name != NULL, return;);
 	ASSERT(octets != NULL, return;);
-	
-	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib), 
+
+	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib),
 					       GFP_ATOMIC);
 	if (attrib == NULL) {
-		WARNING(__FUNCTION__ 
-			"(), Unable to allocate attribute!\n");
+		WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__);
 		return;
 	}
 	memset(attrib, 0, sizeof( struct ias_attrib));
-	
+
 	attrib->magic = IAS_ATTRIB_MAGIC;
 	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
-	
+
 	attrib->value = irias_new_octseq_value( octets, len);
-	
+
 	irias_add_attrib(obj, attrib, owner);
 }
 
@@ -384,11 +383,11 @@
 
 	ASSERT(name != NULL, return;);
 	ASSERT(value != NULL, return;);
-	
-	attrib = (struct ias_attrib *) kmalloc(sizeof( struct ias_attrib), 
+
+	attrib = (struct ias_attrib *) kmalloc(sizeof( struct ias_attrib),
 					       GFP_ATOMIC);
 	if (attrib == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to allocate attribute!\n");
+		WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__);
 		return;
 	}
 	memset(attrib, 0, sizeof( struct ias_attrib));
@@ -413,7 +412,7 @@
 
 	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
 	if (value == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
+		WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 	memset(value, 0, sizeof(struct ias_value));
@@ -438,7 +437,7 @@
 
 	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
 	if (value == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
+		WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 	memset( value, 0, sizeof( struct ias_value));
@@ -465,7 +464,7 @@
 
 	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
 	if (value == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
+		WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 	memset(value, 0, sizeof(struct ias_value));
@@ -478,7 +477,7 @@
 
 	value->t.oct_seq = kmalloc(len, GFP_ATOMIC);
 	if (value->t.oct_seq == NULL){
-		WARNING(__FUNCTION__"(), Unable to kmalloc!\n");
+		WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
 		kfree(value);
 		return NULL;
 	}
@@ -492,7 +491,7 @@
 
 	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
 	if (value == NULL) {
-		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
+		WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 	memset(value, 0, sizeof(struct ias_value));
@@ -536,6 +535,3 @@
 	}
 	kfree(value);
 }
-
-
-
diff -Nru a/net/irda/irlap.c b/net/irda/irlap.c
--- a/net/irda/irlap.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/irlap.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      irlap.c
  * Version:       1.0
  * Description:   IrLAP implementation for Linux
@@ -8,25 +8,25 @@
  * Created at:    Mon Aug  4 20:40:53 1997
  * Modified at:   Tue Dec 14 09:26:44 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
+ *
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
- * 
+ *
  *     This program is distributed in the hope that it will be useful,
  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program; if not, write to the Free Software
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *     MA 02111-1307 USA
- *     
+ *
  ********************************************************************/
 
 #include <linux/config.h>
@@ -82,7 +82,7 @@
 	/* Allocate master array */
 	irlap = hashbin_new(HB_LOCAL);
 	if (irlap == NULL) {
-	        ERROR(__FUNCTION__ "(), can't allocate irlap hashbin!\n");
+	        ERROR("%s: can't allocate irlap hashbin!\n", __FUNCTION__);
 		return -ENOMEM;
 	}
 
@@ -108,12 +108,12 @@
 	struct irlap_cb *self;
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	/* Initialize the irlap structure. */
 	self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);
 	if (self == NULL)
 		return NULL;
-	
+
 	memset(self, 0, sizeof(struct irlap_cb));
 	self->magic = LAP_MAGIC;
 
@@ -145,22 +145,22 @@
 	init_timer(&self->slot_timer);
 	init_timer(&self->query_timer);
 	init_timer(&self->discovery_timer);
-	init_timer(&self->final_timer);		
+	init_timer(&self->final_timer);
 	init_timer(&self->poll_timer);
 	init_timer(&self->wd_timer);
 	init_timer(&self->backoff_timer);
-	init_timer(&self->media_busy_timer);	
+	init_timer(&self->media_busy_timer);
 
 	irlap_apply_default_connection_parameters(self);
 
 	self->N3 = 3; /* # connections attemts to try before giving up */
-	
+
 	self->state = LAP_NDM;
 
 	hashbin_insert(irlap, (irda_queue_t *) self, self->saddr, NULL);
 
 	irlmp_register_link(self, self->saddr, &self->notify);
-	
+
 	return self;
 }
 
@@ -179,16 +179,16 @@
 	del_timer(&self->slot_timer);
 	del_timer(&self->query_timer);
 	del_timer(&self->discovery_timer);
-	del_timer(&self->final_timer);		
+	del_timer(&self->final_timer);
 	del_timer(&self->poll_timer);
 	del_timer(&self->wd_timer);
 	del_timer(&self->backoff_timer);
 	del_timer(&self->media_busy_timer);
 
 	irlap_flush_all_queues(self);
-       
+
 	self->magic = 0;
-	
+
 	kfree(self);
 }
 
@@ -198,12 +198,12 @@
  *    Remove IrLAP instance
  *
  */
-void irlap_close(struct irlap_cb *self) 
+void irlap_close(struct irlap_cb *self)
 {
 	struct irlap_cb *lap;
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
@@ -227,7 +227,7 @@
  *    Another device is attempting to make a connection
  *
  */
-void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) 
+void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
@@ -237,7 +237,7 @@
 	irlap_init_qos_capabilities(self, NULL); /* No user QoS! */
 
 	skb_get(skb); /*LEVEL4*/
-	irlmp_link_connect_indication(self->notify.instance, self->saddr, 
+	irlmp_link_connect_indication(self->notify.instance, self->saddr,
 				      self->daddr, &self->qos_tx, skb);
 }
 
@@ -247,10 +247,10 @@
  *    Service user has accepted incoming connection
  *
  */
-void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb) 
+void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	irlap_do_event(self, CONNECT_RESPONSE, skb, NULL);
 	kfree_skb(skb);
 }
@@ -258,26 +258,26 @@
 /*
  * Function irlap_connect_request (self, daddr, qos_user, sniff)
  *
- *    Request connection with another device, sniffing is not implemented 
+ *    Request connection with another device, sniffing is not implemented
  *    yet.
  *
  */
-void irlap_connect_request(struct irlap_cb *self, __u32 daddr, 
-			   struct qos_info *qos_user, int sniff) 
+void irlap_connect_request(struct irlap_cb *self, __u32 daddr,
+			   struct qos_info *qos_user, int sniff)
 {
 	IRDA_DEBUG(3, __FUNCTION__ "(), daddr=0x%08x\n", daddr);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
- 	self->daddr = daddr;
-	
+	self->daddr = daddr;
+
 	/*
-	 *  If the service user specifies QoS values for this connection, 
+	 *  If the service user specifies QoS values for this connection,
 	 *  then use them
 	 */
 	irlap_init_qos_capabilities(self, qos_user);
-	
+
 	if ((self->state == LAP_NDM) && !self->media_busy)
 		irlap_do_event(self, CONNECT_REQUEST, NULL, NULL);
 	else
@@ -304,12 +304,12 @@
 /*
  * Function irlap_data_indication (self, skb)
  *
- *    Received data frames from IR-port, so we just pass them up to 
+ *    Received data frames from IR-port, so we just pass them up to
  *    IrLMP for further processing
  *
  */
 void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb,
-			   int unreliable) 
+			   int unreliable)
 {
 	/* Hide LAP header from IrLMP layer */
 	skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
@@ -325,7 +325,7 @@
  *    Queue data for transmission, must wait until XMIT state
  *
  */
-void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb, 
+void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb,
 			int unreliable)
 {
 	ASSERT(self != NULL, return;);
@@ -333,12 +333,12 @@
 
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
 
-	ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER), 
+	ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
 	       return;);
 	skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
 
-	/*  
-	 *  Must set frame format now so that the rest of the code knows 
+	/*
+	 *  Must set frame format now so that the rest of the code knows
 	 *  if its dealing with an I or an UI frame
 	 */
 	if (unreliable)
@@ -349,11 +349,11 @@
 	/* Add at the end of the queue (keep ordering) - Jean II */
 	skb_queue_tail(&self->txq, skb);
 
-	/* 
-	 *  Send event if this frame only if we are in the right state 
+	/*
+	 *  Send event if this frame only if we are in the right state
 	 *  FIXME: udata should be sent first! (skb_queue_head?)
 	 */
-  	if ((self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {
+	if ((self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {
 		/* If we are not already processing the Tx queue, trigger
 		 * transmission immediately - Jean II */
 		if((skb_queue_len(&self->txq) <= 1) && (!self->local_busy))
@@ -377,7 +377,7 @@
 
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
 
-	ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER), 
+	ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
 	       return;);
 	skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
 
@@ -399,7 +399,7 @@
 #ifdef CONFIG_IRDA_ULTRA
 void irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "()\n"); 
+	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -418,17 +418,17 @@
  *
  *    Request to disconnect connection by service user
  */
-void irlap_disconnect_request(struct irlap_cb *self) 
+void irlap_disconnect_request(struct irlap_cb *self)
 {
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
-	
+
 	/* Don't disconnect until all data frames are successfully sent */
 	if (skb_queue_len(&self->txq) > 0) {
 		self->disconnect_pending = TRUE;
-		
+
 		return;
 	}
 
@@ -436,9 +436,9 @@
 	switch (self->state) {
 	case LAP_XMIT_P:        /* FALLTROUGH */
 	case LAP_XMIT_S:        /* FALLTROUGH */
- 	case LAP_CONN:          /* FALLTROUGH */
- 	case LAP_RESET_WAIT:    /* FALLTROUGH */
- 	case LAP_RESET_CHECK:   
+	case LAP_CONN:          /* FALLTROUGH */
+	case LAP_RESET_WAIT:    /* FALLTROUGH */
+	case LAP_RESET_CHECK:
 		irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
 		break;
 	default:
@@ -454,30 +454,30 @@
  *    Disconnect request from other device
  *
  */
-void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) 
+void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]); 
+	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
 	/* Flush queues */
 	irlap_flush_all_queues(self);
-	
+
 	switch (reason) {
 	case LAP_RESET_INDICATION:
 		IRDA_DEBUG(1, __FUNCTION__ "(), Sending reset request!\n");
 		irlap_do_event(self, RESET_REQUEST, NULL, NULL);
 		break;
-	case LAP_NO_RESPONSE:	   /* FALLTROUGH */	
+	case LAP_NO_RESPONSE:	   /* FALLTROUGH */
 	case LAP_DISC_INDICATION:  /* FALLTROUGH */
 	case LAP_FOUND_NONE:       /* FALLTROUGH */
 	case LAP_MEDIA_BUSY:
-		irlmp_link_disconnect_indication(self->notify.instance, self, 
+		irlmp_link_disconnect_indication(self->notify.instance, self,
 						 reason, NULL);
 		break;
 	default:
-		ERROR(__FUNCTION__ "(), Unknown reason %d\n", reason);
+		ERROR("%s: Unknown reason %d\n", __FUNCTION__, reason);
 	}
 }
 
@@ -487,23 +487,23 @@
  *    Start one single discovery operation.
  *
  */
-void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery) 
+void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery)
 {
 	struct irlap_info info;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 	ASSERT(discovery != NULL, return;);
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
 
 	ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||
-	       (discovery->nslots == 8) || (discovery->nslots == 16), 
+	       (discovery->nslots == 8) || (discovery->nslots == 16),
 	       return;);
-	
-  	/* Discovery is only possible in NDM mode */
+
+	/* Discovery is only possible in NDM mode */
 	if (self->state != LAP_NDM) {
-		IRDA_DEBUG(4, __FUNCTION__ 
+		IRDA_DEBUG(4, __FUNCTION__
 			   "(), discovery only possible in NDM mode\n");
 		irlap_discovery_confirm(self, NULL);
 		/* Note : in theory, if we are not in NDM, we could postpone
@@ -521,18 +521,18 @@
 		hashbin_delete(self->discovery_log, (FREE_FUNC) kfree);
 		self->discovery_log = NULL;
 	}
-	
+
 	self->discovery_log= hashbin_new(HB_LOCAL);
-	
+
 	info.S = discovery->nslots; /* Number of slots */
 	info.s = 0; /* Current slot */
-	
+
 	self->discovery_cmd = discovery;
 	info.discovery = discovery;
-	
+
 	/* sysctl_slot_timeout bounds are checked in irsysctl.c - Jean II */
 	self->slot_timeout = sysctl_slot_timeout * HZ / 1000;
-	
+
 	irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);
 }
 
@@ -542,15 +542,15 @@
  *    A device has been discovered in front of this station, we
  *    report directly to LMP.
  */
-void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log) 
+void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
-	
+
 	ASSERT(self->notify.instance != NULL, return;);
-	
-	/* 
-	 * Check for successful discovery, since we are then allowed to clear 
+
+	/*
+	 * Check for successful discovery, since we are then allowed to clear
 	 * the media busy condition (IrLAP 6.13.4 - p.94). This should allow
 	 * us to make connection attempts much faster and easier (i.e. no
 	 * collisions).
@@ -562,7 +562,7 @@
 	 */
 	if (discovery_log)
 		irda_device_set_media_busy(self->netdev, FALSE);
-	
+
 	/* Inform IrLMP */
 	irlmp_link_discovery_confirm(self->notify.instance, discovery_log);
 }
@@ -573,7 +573,7 @@
  *    Somebody is trying to discover us!
  *
  */
-void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery) 
+void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
@@ -599,11 +599,8 @@
 
 /*
  * Function irlap_status_indication (quality_of_link)
- *
- *    
- *
  */
-void irlap_status_indication(struct irlap_cb *self, int quality_of_link) 
+void irlap_status_indication(struct irlap_cb *self, int quality_of_link)
 {
 	switch (quality_of_link) {
 	case STATUS_NO_ACTIVITY:
@@ -621,9 +618,6 @@
 
 /*
  * Function irlap_reset_indication (void)
- *
- *    
- *
  */
 void irlap_reset_indication(struct irlap_cb *self)
 {
@@ -631,7 +625,7 @@
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
-	
+
 	if (self->state == LAP_RESET_WAIT)
 		irlap_do_event(self, RESET_REQUEST, NULL, NULL);
 	else
@@ -640,13 +634,10 @@
 
 /*
  * Function irlap_reset_confirm (void)
- *
- *    
- *
  */
 void irlap_reset_confirm(void)
 {
- 	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 }
 
 /*
@@ -656,11 +647,11 @@
  *    S = Number of slots (0 -> S-1)
  *    s = Current slot
  */
-int irlap_generate_rand_time_slot(int S, int s) 
+int irlap_generate_rand_time_slot(int S, int s)
 {
 	static int rand;
 	int slot;
-	
+
 	ASSERT((S - s) > 0, return 0;);
 
 	rand += jiffies;
@@ -668,20 +659,20 @@
 	rand ^= (rand >> 20);
 
 	slot = s + rand % (S-s);
-	
+
 	ASSERT((slot >= s) || (slot < S), return 0;);
-	
+
 	return slot;
 }
 
 /*
  * Function irlap_update_nr_received (nr)
  *
- *    Remove all acknowledged frames in current window queue. This code is 
+ *    Remove all acknowledged frames in current window queue. This code is
  *    not intuitive and you should not try to change it. If you think it
  *    contains bugs, please mail a patch to the author instead.
  */
-void irlap_update_nr_received(struct irlap_cb *self, int nr) 
+void irlap_update_nr_received(struct irlap_cb *self, int nr)
 {
 	struct sk_buff *skb = NULL;
 	int count = 0;
@@ -690,7 +681,7 @@
          * Remove all the ack-ed frames from the window queue.
          */
 
-	/* 
+	/*
 	 *  Optimize for the common case. It is most likely that the receiver
 	 *  will acknowledge all the frames we have sent! So in that case we
 	 *  delete all frames stored in window.
@@ -703,17 +694,17 @@
 		self->va = nr - 1;
 	} else {
 		/* Remove all acknowledged frames in current window */
-		while ((skb_peek(&self->wx_list) != NULL) && 
-		       (((self->va+1) % 8) != nr)) 
+		while ((skb_peek(&self->wx_list) != NULL) &&
+		       (((self->va+1) % 8) != nr))
 		{
 			skb = skb_dequeue(&self->wx_list);
 			dev_kfree_skb(skb);
-			
+
 			self->va = (self->va + 1) % 8;
 			count++;
 		}
 	}
-	
+
 	/* Advance window */
 	self->window = self->window_size - skb_queue_len(&self->wx_list);
 }
@@ -723,7 +714,7 @@
  *
  *    Validate the next to send (ns) field from received frame.
  */
-int irlap_validate_ns_received(struct irlap_cb *self, int ns) 
+int irlap_validate_ns_received(struct irlap_cb *self, int ns)
 {
 	/*  ns as expected?  */
 	if (ns == self->vr)
@@ -733,7 +724,7 @@
 	 *  IrLAP, Recv ... with-invalid-Ns. p. 84
 	 */
 	return NS_UNEXPECTED;
-	
+
 	/* return NR_INVALID; */
 }
 /*
@@ -742,7 +733,7 @@
  *    Validate the next to receive (nr) field from received frame.
  *
  */
-int irlap_validate_nr_received(struct irlap_cb *self, int nr) 
+int irlap_validate_nr_received(struct irlap_cb *self, int nr)
 {
 	/*  nr as expected?  */
 	if (nr == self->vs) {
@@ -751,17 +742,17 @@
 	}
 
 	/*
-	 *  unexpected nr? (but within current window), first we check if the 
+	 *  unexpected nr? (but within current window), first we check if the
 	 *  ns numbers of the frames in the current window wrap.
 	 */
 	if (self->va < self->vs) {
 		if ((nr >= self->va) && (nr <= self->vs))
 			return NR_UNEXPECTED;
 	} else {
-		if ((nr >= self->va) || (nr <= self->vs)) 
+		if ((nr >= self->va) || (nr <= self->vs))
 			return NR_UNEXPECTED;
 	}
-	
+
 	/* Invalid nr!  */
 	return NR_INVALID;
 }
@@ -772,10 +763,10 @@
  *    Initialize the connection state parameters
  *
  */
-void irlap_initiate_connection_state(struct irlap_cb *self) 
+void irlap_initiate_connection_state(struct irlap_cb *self)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
@@ -799,11 +790,11 @@
  *    frame in order to delay for the specified amount of time. This is
  *    done to avoid using timers, and the forbidden udelay!
  */
-void irlap_wait_min_turn_around(struct irlap_cb *self, struct qos_info *qos) 
+void irlap_wait_min_turn_around(struct irlap_cb *self, struct qos_info *qos)
 {
 	__u32 min_turn_time;
 	__u32 speed;
-	
+
 	/* Get QoS values.  */
 	speed = qos->baud_rate.value;
 	min_turn_time = qos->min_turn_time.value;
@@ -813,10 +804,10 @@
 		self->mtt_required = min_turn_time;
 		return;
 	}
-	
-	/*  
+
+	/*
 	 *  Send additional BOF's for the next frame for the requested
-	 *  min turn time, so now we must calculate how many chars (XBOF's) we 
+	 *  min turn time, so now we must calculate how many chars (XBOF's) we
 	 *  must send for the requested time period (min turn time)
 	 */
 	self->xbofs_delay = irlap_min_turn_time_in_bytes(speed, min_turn_time);
@@ -828,7 +819,7 @@
  *    Flush all queues
  *
  */
-void irlap_flush_all_queues(struct irlap_cb *self) 
+void irlap_flush_all_queues(struct irlap_cb *self)
 {
 	struct sk_buff* skb;
 
@@ -838,7 +829,7 @@
 	/* Free transmission queue */
 	while ((skb = skb_dequeue(&self->txq)) != NULL)
 		dev_kfree_skb(skb);
-	
+
 	while ((skb = skb_dequeue(&self->txq_ultra)) != NULL)
 		dev_kfree_skb(skb);
 
@@ -894,7 +885,7 @@
 	irda_qos_compute_intersection(&self->qos_rx, self->qos_dev);
 
 	/*
-	 *  Check for user supplied QoS parameters. The service user is only 
+	 *  Check for user supplied QoS parameters. The service user is only
 	 *  allowed to supply these values. We check each parameter since the
 	 *  user may not have set all of them.
 	 */
@@ -926,7 +917,6 @@
  * Function irlap_apply_default_connection_parameters (void, now)
  *
  *    Use the default connection and transmission parameters
- * 
  */
 void irlap_apply_default_connection_parameters(struct irlap_cb *self)
 {
@@ -945,9 +935,9 @@
 	/* Set mbusy when going to NDM state */
 	irda_device_set_media_busy(self->netdev, TRUE);
 
-	/* 
+	/*
 	 * Generate random connection address for this session, which must
-	 * be 7 bits wide and different from 0x00 and 0xfe 
+	 * be 7 bits wide and different from 0x00 and 0xfe
 	 */
 	while ((self->caddr == 0x00) || (self->caddr == 0xfe)) {
 		get_random_bytes(&self->caddr, sizeof(self->caddr));
@@ -991,10 +981,10 @@
  * frame is sent.
  * If 'now' is true, the speed and xbofs is changed immediately
  */
-void irlap_apply_connection_parameters(struct irlap_cb *self, int now) 
+void irlap_apply_connection_parameters(struct irlap_cb *self, int now)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
@@ -1014,15 +1004,15 @@
 	 *  Calculate how many bytes it is possible to transmit before the
 	 *  link must be turned around
 	 */
-	self->line_capacity = 
+	self->line_capacity =
 		irlap_max_line_capacity(self->qos_tx.baud_rate.value,
 					self->qos_tx.max_turn_time.value);
 	self->bytes_left = self->line_capacity;
 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 
-	
-	/* 
-	 *  Initialize timeout values, some of the rules are listed on 
+
+	/*
+	 *  Initialize timeout values, some of the rules are listed on
 	 *  page 92 in IrLAP.
 	 */
 	ASSERT(self->qos_tx.max_turn_time.value != 0, return;);
@@ -1056,27 +1046,27 @@
 	 */
 
 	/*
-	 *  Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to 
+	 *  Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to
 	 *  3 seconds otherwise. See page 71 in IrLAP for more details.
 	 *  Actually, it's not always 3 seconds, as we allow to set
 	 *  it via sysctl... Max maxtt is 500ms, and N1 need to be multiple
 	 *  of 2, so 1 second is minimum we can allow. - Jean II
 	 */
 	if (self->qos_tx.link_disc_time.value == sysctl_warn_noreply_time)
-		/* 
+		/*
 		 * If we set N1 to 0, it will trigger immediately, which is
 		 * not what we want. What we really want is to disable it,
-		 * Jean II 
+		 * Jean II
 		 */
 		self->N1 = -2; /* Disable - Need to be multiple of 2*/
 	else
 		self->N1 = sysctl_warn_noreply_time * 1000 /
 		  self->qos_rx.max_turn_time.value;
-	
+
 	IRDA_DEBUG(4, "Setting N1 = %d\n", self->N1);
-	
+
 	/* Set N2 to match our own disconnect time */
-	self->N2 = self->qos_tx.link_disc_time.value * 1000 / 
+	self->N2 = self->qos_tx.link_disc_time.value * 1000 /
 		self->qos_rx.max_turn_time.value;
 	IRDA_DEBUG(4, "Setting N2 = %d\n", self->N2);
 }
@@ -1093,7 +1083,7 @@
 	struct irlap_cb *self;
 	unsigned long flags;
 	int i = 0;
-     
+
 	save_flags(flags);
 	cli();
 
@@ -1105,9 +1095,9 @@
 		ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
 
 		len += sprintf(buf+len, "irlap%d ", i++);
-		len += sprintf(buf+len, "state: %s\n", 
+		len += sprintf(buf+len, "state: %s\n",
 			       irlap_state[self->state]);
-		
+
 		len += sprintf(buf+len, "  device name: %s, ",
 			       (self->netdev) ? self->netdev->name : "bug");
 		len += sprintf(buf+len, "hardware name: %s\n", self->hw_name);
@@ -1115,34 +1105,34 @@
 		len += sprintf(buf+len, "  caddr: %#02x, ", self->caddr);
 		len += sprintf(buf+len, "saddr: %#08x, ", self->saddr);
 		len += sprintf(buf+len, "daddr: %#08x\n", self->daddr);
-		
-		len += sprintf(buf+len, "  win size: %d, ", 
+
+		len += sprintf(buf+len, "  win size: %d, ",
 			       self->window_size);
 		len += sprintf(buf+len, "win: %d, ", self->window);
 #if CONFIG_IRDA_DYNAMIC_WINDOW
-		len += sprintf(buf+len, "line capacity: %d, ", 
+		len += sprintf(buf+len, "line capacity: %d, ",
 			       self->line_capacity);
 		len += sprintf(buf+len, "bytes left: %d\n", self->bytes_left);
 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
-		len += sprintf(buf+len, "  tx queue len: %d ", 
+		len += sprintf(buf+len, "  tx queue len: %d ",
 			       skb_queue_len(&self->txq));
-		len += sprintf(buf+len, "win queue len: %d ", 
+		len += sprintf(buf+len, "win queue len: %d ",
 			       skb_queue_len(&self->wx_list));
 		len += sprintf(buf+len, "rbusy: %s", self->remote_busy ?
 			       "TRUE" : "FALSE");
 		len += sprintf(buf+len, " mbusy: %s\n", self->media_busy ?
 			       "TRUE" : "FALSE");
-		
+
 		len += sprintf(buf+len, "  retrans: %d ", self->retry_count);
 		len += sprintf(buf+len, "vs: %d ", self->vs);
 		len += sprintf(buf+len, "vr: %d ", self->vr);
 		len += sprintf(buf+len, "va: %d\n", self->va);
-		
+
 		len += sprintf(buf+len, "  qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
-		
-		len += sprintf(buf+len, "  tx\t%d\t", 
+
+		len += sprintf(buf+len, "  tx\t%d\t",
 			       self->qos_tx.baud_rate.value);
-		len += sprintf(buf+len, "%d\t", 
+		len += sprintf(buf+len, "%d\t",
 			       self->qos_tx.max_turn_time.value);
 		len += sprintf(buf+len, "%d\t",
 			       self->qos_tx.data_size.value);
@@ -1150,15 +1140,15 @@
 			       self->qos_tx.window_size.value);
 		len += sprintf(buf+len, "%d\t",
 			       self->qos_tx.additional_bofs.value);
-		len += sprintf(buf+len, "%d\t", 
+		len += sprintf(buf+len, "%d\t",
 			       self->qos_tx.min_turn_time.value);
-		len += sprintf(buf+len, "%d\t", 
+		len += sprintf(buf+len, "%d\t",
 			       self->qos_tx.link_disc_time.value);
 		len += sprintf(buf+len, "\n");
 
-		len += sprintf(buf+len, "  rx\t%d\t", 
+		len += sprintf(buf+len, "  rx\t%d\t",
 			       self->qos_rx.baud_rate.value);
-		len += sprintf(buf+len, "%d\t", 
+		len += sprintf(buf+len, "%d\t",
 			       self->qos_rx.max_turn_time.value);
 		len += sprintf(buf+len, "%d\t",
 			       self->qos_rx.data_size.value);
@@ -1166,12 +1156,12 @@
 			       self->qos_rx.window_size.value);
 		len += sprintf(buf+len, "%d\t",
 			       self->qos_rx.additional_bofs.value);
-		len += sprintf(buf+len, "%d\t", 
+		len += sprintf(buf+len, "%d\t",
 			       self->qos_rx.min_turn_time.value);
-		len += sprintf(buf+len, "%d\t", 
+		len += sprintf(buf+len, "%d\t",
 			       self->qos_rx.link_disc_time.value);
 		len += sprintf(buf+len, "\n");
-		
+
 		self = (struct irlap_cb *) hashbin_get_next(irlap);
 	}
 	restore_flags(flags);
@@ -1180,4 +1170,3 @@
 }
 
 #endif /* CONFIG_PROC_FS */
-
diff -Nru a/net/irda/irlap_event.c b/net/irda/irlap_event.c
--- a/net/irda/irlap_event.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/irlap_event.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      irlap_event.c
  * Version:       0.9
  * Description:   IrLAP state machine implementation
@@ -8,19 +8,19 @@
  * Created at:    Sat Aug 16 00:59:29 1997
  * Modified at:   Sat Dec 25 21:07:57 1999
  * Modified by:   Dag Brattli <dag@brattli.net>
- * 
+ *
  *     Copyright (c) 1998-2000 Dag Brattli <dag@brattli.net>,
  *     Copyright (c) 1998      Thomas Davis <ratbert@radiks.net>
  *     All Rights Reserved.
  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
  ********************************************************************/
@@ -46,35 +46,35 @@
 int sysctl_fast_poll_increase = 50;
 #endif
 
-static int irlap_state_ndm    (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_ndm    (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_query  (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_query  (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_reply  (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_reply  (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_conn   (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_conn   (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_setup  (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_setup  (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_xmit_p (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_xmit_p (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_pclose (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_pclose (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_nrm_p  (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_nrm_p  (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event,
 				  struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_reset  (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_reset  (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_nrm_s  (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_nrm_s  (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_xmit_s (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_xmit_s (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_sclose (struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_sclose (struct irlap_cb *self, IRLAP_EVENT event,
 			       struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_reset_check(struct irlap_cb *, IRLAP_EVENT event, 
+static int irlap_state_reset_check(struct irlap_cb *, IRLAP_EVENT event,
 				   struct sk_buff *, struct irlap_info *);
 
 #ifdef CONFIG_IRDA_DEBUG
@@ -138,8 +138,8 @@
 	"LAP_RESET_CHECK",
 };
 
-static int (*state[])(struct irlap_cb *self, IRLAP_EVENT event, 
-		      struct sk_buff *skb, struct irlap_info *info) = 
+static int (*state[])(struct irlap_cb *self, IRLAP_EVENT event,
+		      struct sk_buff *skb, struct irlap_info *info) =
 {
 	irlap_state_ndm,
 	irlap_state_query,
@@ -167,10 +167,10 @@
 static void irlap_poll_timer_expired(void *data)
 {
 	struct irlap_cb *self = (struct irlap_cb *) data;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
-	
+
 	irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
 }
 
@@ -186,7 +186,7 @@
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
 #ifdef CONFIG_IRDA_FAST_RR
-	/* 
+	/*
 	 * Send out the RR frames faster if our own transmit queue is empty, or
 	 * if the peer is busy. The effect is a much faster conversation
 	 */
@@ -201,7 +201,7 @@
 				 *  FIXME: this should be a more configurable
 				 *         function
 				 */
-				self->fast_RR_timeout += 
+				self->fast_RR_timeout +=
 					(sysctl_fast_poll_increase * HZ/1000);
 
 				/* Use this fast(er) timeout instead */
@@ -223,7 +223,7 @@
 	if (timeout == 0)
 		irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
 	else
-		irda_start_timer(&self->poll_timer, timeout, self, 
+		irda_start_timer(&self->poll_timer, timeout, self,
 				 irlap_poll_timer_expired);
 }
 
@@ -231,28 +231,28 @@
  * Function irlap_do_event (event, skb, info)
  *
  *    Rushes through the state machine without any delay. If state == XMIT
- *    then send queued data frames. 
+ *    then send queued data frames.
  */
-void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, 
-		    struct sk_buff *skb, struct irlap_info *info) 
+void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
+		    struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret;
-	
+
 	if (!self || self->magic != LAP_MAGIC)
 		return;
 
-  	IRDA_DEBUG(3, __FUNCTION__ "(), event = %s, state = %s\n", 
-		   irlap_event[event], irlap_state[self->state]); 
-	
+	IRDA_DEBUG(3, __FUNCTION__ "(), event = %s, state = %s\n",
+		   irlap_event[event], irlap_state[self->state]);
+
 	ret = (*state[self->state])(self, event, skb, info);
 
-	/* 
+	/*
 	 *  Check if there are any pending events that needs to be executed
 	 */
 	switch (self->state) {
 	case LAP_XMIT_P: /* FALLTHROUGH */
 	case LAP_XMIT_S:
-		/* 
+		/*
 		 * We just received the pf bit and are at the beginning
 		 * of a new LAP transmit window.
 		 * Check if there are any queued data frames, and do not
@@ -299,15 +299,15 @@
 			self->local_busy = FALSE;
 		} else if (self->disconnect_pending) {
 			self->disconnect_pending = FALSE;
-			
+
 			ret = (*state[self->state])(self, DISCONNECT_REQUEST,
 						    NULL, NULL);
 		}
 		break;
 /*	case LAP_NDM: */
-/* 	case LAP_CONN: */
-/* 	case LAP_RESET_WAIT: */
-/* 	case LAP_RESET_CHECK: */
+/*	case LAP_CONN: */
+/*	case LAP_RESET_WAIT: */
+/*	case LAP_RESET_CHECK: */
 	default:
 		break;
 	}
@@ -319,12 +319,12 @@
  *    Switches state and provides debug information
  *
  */
-static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state) 
-{	
+static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
+{
 	/*
 	if (!self || self->magic != LAP_MAGIC)
 		return;
-	
+
 	IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
 	*/
 	self->state = state;
@@ -336,8 +336,8 @@
  *    NDM (Normal Disconnected Mode) state
  *
  */
-static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, 
-			   struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
+			   struct sk_buff *skb, struct irlap_info *info)
 {
 	discovery_t *discovery_rsp;
 	int ret = 0;
@@ -355,14 +355,14 @@
 			 * postpone the event... - Jean II */
 			IRDA_DEBUG(0, __FUNCTION__
 				   "(), CONNECT_REQUEST: media busy!\n");
-			
+
 			/* Always switch state before calling upper layers */
 			irlap_next_state(self, LAP_NDM);
-			
+
 			irlap_disconnect_indication(self, LAP_MEDIA_BUSY);
 		} else {
 			irlap_send_snrm_frame(self, &self->qos_rx);
-			
+
 			/* Start Final-bit timer */
 			irlap_start_final_timer(self, self->final_timeout);
 
@@ -372,10 +372,10 @@
 		break;
 	case RECV_SNRM_CMD:
 		/* Check if the frame contains and I field */
-		if (info) {		       
+		if (info) {
 			self->daddr = info->daddr;
 			self->caddr = info->caddr;
-			
+
 			irlap_next_state(self, LAP_CONN);
 
 			irlap_connect_indication(self, skb);
@@ -384,21 +384,21 @@
 				   "contain an I field!\n");
 		}
 		break;
-	case DISCOVERY_REQUEST:		
+	case DISCOVERY_REQUEST:
 		ASSERT(info != NULL, return -1;);
 
-	 	if (self->media_busy) {
- 			IRDA_DEBUG(0, __FUNCTION__ "(), media busy!\n"); 
+		if (self->media_busy) {
+			IRDA_DEBUG(0, __FUNCTION__ "(), media busy!\n");
 			/* irlap->log.condition = MEDIA_BUSY; */
-						
+
 			/* This will make IrLMP try again */
- 			irlap_discovery_confirm(self, NULL);
+			irlap_discovery_confirm(self, NULL);
 			/* Note : the discovery log is not cleaned up here,
 			 * it will be done in irlap_discovery_request()
 			 * Jean II */
 			return 0;
-	 	} 
-		
+		}
+
 		self->S = info->S;
 		self->s = info->s;
 		irlap_send_discovery_xid_frame(self, info->S, info->s, TRUE,
@@ -419,17 +419,17 @@
 			if (self->slot == info->s) {
 				discovery_rsp = irlmp_get_discovery_response();
 				discovery_rsp->daddr = info->daddr;
-				
-				irlap_send_discovery_xid_frame(self, info->S, 
-							       self->slot, 
+
+				irlap_send_discovery_xid_frame(self, info->S,
+							       self->slot,
 							       FALSE,
 							       discovery_rsp);
 				self->frame_sent = TRUE;
 			} else
 				self->frame_sent = FALSE;
-			
-			/* 
-			 * Remember to multiply the query timeout value with 
+
+			/*
+			 * Remember to multiply the query timeout value with
 			 * the number of slots used
 			 */
 			irlap_start_query_timer(self, QUERY_TIMEOUT*info->S);
@@ -453,7 +453,7 @@
 			IRDA_DEBUG(1, __FUNCTION__ "(), Receiving final discovery request, missed the discovery slots :-(\n");
 
 			/* Last discovery request -> in the log */
-			irlap_discovery_indication(self, info->discovery); 
+			irlap_discovery_indication(self, info->discovery);
 		}
 		break;
 	case MEDIA_BUSY_TIMER_EXPIRED:
@@ -472,7 +472,7 @@
 			/* We don't send the frame, just post an event.
 			 * Also, previously this code was in timer.c...
 			 * Jean II */
-			ret = (*state[self->state])(self, SEND_UI_FRAME, 
+			ret = (*state[self->state])(self, SEND_UI_FRAME,
 						    NULL, NULL);
 		}
 #endif /* CONFIG_IRDA_ULTRA */
@@ -488,7 +488,7 @@
 				irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 			else
 				ret = (*state[self->state])(self,
-							    CONNECT_REQUEST, 
+							    CONNECT_REQUEST,
 							    NULL, NULL);
 			self->disconnect_pending = FALSE;
 		}
@@ -506,13 +506,13 @@
 		break;
 #ifdef CONFIG_IRDA_ULTRA
 	case SEND_UI_FRAME:
-	{   
+	{
 		int i;
 		/* Only allowed to repeat an operation twice */
 		for (i=0; ((i<2) && (self->media_busy == FALSE)); i++) {
 			skb = skb_dequeue(&self->txq_ultra);
 			if (skb)
-				irlap_send_ui_frame(self, skb, CBROADCAST, 
+				irlap_send_ui_frame(self, skb, CBROADCAST,
 						    CMD_FRAME);
 			else
 				break;
@@ -526,7 +526,7 @@
 	case RECV_UI_FRAME:
 		/* Only accept broadcast frames in NDM mode */
 		if (info->caddr != CBROADCAST) {
-			IRDA_DEBUG(0, __FUNCTION__ 
+			IRDA_DEBUG(0, __FUNCTION__
 				   "(), not a broadcast frame!\n");
 		} else
 			irlap_unitdata_indication(self, skb);
@@ -536,7 +536,7 @@
 		/* Remove test frame header */
 		skb_pull(skb, sizeof(struct test_frame));
 
-		/* 
+		/*
 		 * Send response. This skb will not be sent out again, and
 		 * will only be used to send out the same info as the cmd
 		 */
@@ -546,12 +546,12 @@
 		IRDA_DEBUG(0, __FUNCTION__ "() not implemented!\n");
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
 			   irlap_event[event]);
-		
+
 		ret = -1;
 		break;
-	}	
+	}
 	return ret;
 }
 
@@ -561,8 +561,8 @@
  *    QUERY state
  *
  */
-static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event, 
-			     struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
+			     struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
 
@@ -574,16 +574,16 @@
 		ASSERT(info != NULL, return -1;);
 		ASSERT(info->discovery != NULL, return -1;);
 
-		IRDA_DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", 
+		IRDA_DEBUG(4, __FUNCTION__ "(), daddr=%08x\n",
 			   info->discovery->daddr);
 
 		if (!self->discovery_log) {
-			WARNING(__FUNCTION__ "(), discovery log is gone! "
+			WARNING("%s: discovery log is gone! "
 				"maybe the discovery timeout has been set to "
-				"short?\n");
+				"short?\n", __FUNCTION__);
 			break;
 		}
-		hashbin_insert(self->discovery_log, 
+		hashbin_insert(self->discovery_log,
 			       (irda_queue_t *) info->discovery,
 			       info->discovery->daddr, NULL);
 
@@ -609,17 +609,17 @@
 
 		/* Last discovery request ? */
 		if (info->s == 0xff)
-			irlap_discovery_indication(self, info->discovery); 
+			irlap_discovery_indication(self, info->discovery);
 		break;
 	case SLOT_TIMER_EXPIRED:
 		/*
 		 * Wait a little longer if we detect an incoming frame. This
-		 * is not mentioned in the spec, but is a good thing to do, 
+		 * is not mentioned in the spec, but is a good thing to do,
 		 * since we want to work even with devices that violate the
 		 * timing requirements.
 		 */
 		if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
-			IRDA_DEBUG(2, __FUNCTION__ 
+			IRDA_DEBUG(2, __FUNCTION__
 				   "(), device is slow to answer, "
 				   "waiting some more!\n");
 			irlap_start_slot_timer(self, MSECS_TO_JIFFIES(10));
@@ -629,25 +629,25 @@
 		self->add_wait = FALSE;
 
 		if (self->s < self->S) {
-			irlap_send_discovery_xid_frame(self, self->S, 
+			irlap_send_discovery_xid_frame(self, self->S,
 						       self->s, TRUE,
 						       self->discovery_cmd);
 			self->s++;
 			irlap_start_slot_timer(self, self->slot_timeout);
-			
+
 			/* Keep state */
 			irlap_next_state(self, LAP_QUERY);
 		} else {
 			/* This is the final slot! */
-			irlap_send_discovery_xid_frame(self, self->S, 0xff, 
+			irlap_send_discovery_xid_frame(self, self->S, 0xff,
 						       TRUE,
 						       self->discovery_cmd);
 
 			/* Always switch state before calling upper layers */
 			irlap_next_state(self, LAP_NDM);
-	
+
 			/*
-			 *  We are now finished with the discovery procedure, 
+			 *  We are now finished with the discovery procedure,
 			 *  so now we must return the results
 			 */
 			irlap_discovery_confirm(self, self->discovery_log);
@@ -657,7 +657,7 @@
 		}
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
 			   irlap_event[event]);
 
 		ret = -1;
@@ -671,10 +671,10 @@
  *
  *    REPLY, we have received a XID discovery frame from a device and we
  *    are waiting for the right time slot to send a response XID frame
- * 
+ *
  */
-static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event, 
-			     struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
+			     struct sk_buff *skb, struct irlap_info *info)
 {
 	discovery_t *discovery_rsp;
 	int ret=0;
@@ -695,13 +695,13 @@
 		/* Last frame? */
 		if (info->s == 0xff) {
 			del_timer(&self->query_timer);
-			
+
 			/* info->log.condition = REMOTE; */
 
 			/* Always switch state before calling upper layers */
 			irlap_next_state(self, LAP_NDM);
 
-			irlap_discovery_indication(self, info->discovery); 
+			irlap_discovery_indication(self, info->discovery);
 		} else if ((info->s >= self->slot) && (!self->frame_sent)) {
 			discovery_rsp = irlmp_get_discovery_response();
 			discovery_rsp->daddr = info->daddr;
@@ -709,7 +709,7 @@
 			irlap_send_discovery_xid_frame(self, info->S,
 						       self->slot, FALSE,
 						       discovery_rsp);
-			
+
 			self->frame_sent = TRUE;
 			irlap_next_state(self, LAP_REPLY);
 		}
@@ -728,11 +728,11 @@
  * Function irlap_state_conn (event, skb, info)
  *
  *    CONN, we have received a SNRM command and is waiting for the upper
- *    layer to accept or refuse connection 
+ *    layer to accept or refuse connection
  *
  */
-static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event, 
-			    struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event,
+			    struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
 
@@ -751,20 +751,20 @@
 
 		irlap_initiate_connection_state(self);
 
-		/* 
+		/*
 		 * Applying the parameters now will make sure we change speed
 		 * *after* we have sent the next frame
 		 */
 		irlap_apply_connection_parameters(self, FALSE);
 
-		/* 
+		/*
 		 * Sending this frame will force a speed change after it has
 		 * been sent (i.e. the frame will be sent at 9600).
 		 */
 		irlap_send_ua_response_frame(self, &self->qos_rx);
 
 #if 0
-		/* 
+		/*
 		 * We are allowed to send two frames, but this may increase
 		 * the connect latency, so lets not do it for now.
 		 */
@@ -787,20 +787,20 @@
 #endif
 
 		/*
-		 *  The WD-timer could be set to the duration of the P-timer 
-		 *  for this case, but it is recommended to use twice the 
-		 *  value (note 3 IrLAP p. 60). 
+		 *  The WD-timer could be set to the duration of the P-timer
+		 *  for this case, but it is recommended to use twice the
+		 *  value (note 3 IrLAP p. 60).
 		 */
 		irlap_start_wd_timer(self, self->wd_timeout);
 		irlap_next_state(self, LAP_NRM_S);
 
 		break;
 	case RECV_DISCOVERY_XID_CMD:
-		IRDA_DEBUG(3, __FUNCTION__ 
+		IRDA_DEBUG(3, __FUNCTION__
 			   "(), event RECV_DISCOVER_XID_CMD!\n");
 		irlap_next_state(self, LAP_NDM);
 
-		break;		
+		break;
 	case DISCONNECT_REQUEST:
 		IRDA_DEBUG(0, __FUNCTION__ "(), Disconnect request!\n");
 		irlap_send_dm_frame(self);
@@ -810,11 +810,11 @@
 	default:
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
 			   irlap_event[event]);
-		
+
 		ret = -1;
 		break;
 	}
-	
+
 	return ret;
 }
 
@@ -825,26 +825,26 @@
  *    a remote peer layer and is awaiting a reply .
  *
  */
-static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, 
-			     struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
+			     struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
 
 	switch (event) {
 	case FINAL_TIMER_EXPIRED:
 		if (self->retry_count < self->N3) {
-/* 
- *  Perform random backoff, Wait a random number of time units, minimum 
- *  duration half the time taken to transmitt a SNRM frame, maximum duration 
- *  1.5 times the time taken to transmit a SNRM frame. So this time should 
+/*
+ *  Perform random backoff, Wait a random number of time units, minimum
+ *  duration half the time taken to transmitt a SNRM frame, maximum duration
+ *  1.5 times the time taken to transmit a SNRM frame. So this time should
  *  between 15 msecs and 45 msecs.
  */
-			irlap_start_backoff_timer(self, MSECS_TO_JIFFIES(20 + 
+			irlap_start_backoff_timer(self, MSECS_TO_JIFFIES(20 +
 						        (jiffies % 30)));
 		} else {
 			/* Always switch state before calling upper layers */
@@ -877,18 +877,18 @@
 			skb_pull(skb, sizeof(struct snrm_frame));
 
 			irlap_qos_negotiate(self, skb);
-			
+
 			/* Send UA frame and then change link settings */
 			irlap_apply_connection_parameters(self, FALSE);
 			irlap_send_ua_response_frame(self, &self->qos_rx);
 
 			irlap_next_state(self, LAP_NRM_S);
 			irlap_connect_confirm(self, skb);
-			
-			/* 
+
+			/*
 			 *  The WD-timer could be set to the duration of the
 			 *  P-timer for this case, but it is recommended
-			 *  to use twice the value (note 3 IrLAP p. 60).  
+			 *  to use twice the value (note 3 IrLAP p. 60).
 			 */
 			irlap_start_wd_timer(self, self->wd_timeout);
 		} else {
@@ -915,7 +915,7 @@
 		/* Set the new link setting *now* (before the rr frame) */
 		irlap_apply_connection_parameters(self, TRUE);
 		self->retry_count = 0;
-		
+
 		/* Wait for turnaround time to give a chance to the other
 		 * device to be ready to receive us.
 		 * Note : the time to switch speed is typically larger
@@ -933,7 +933,7 @@
 		irlap_connect_confirm(self, skb);
 		break;
 	case RECV_DM_RSP:     /* FALLTHROUGH */
-	case RECV_DISC_CMD: 
+	case RECV_DISC_CMD:
 		del_timer(&self->final_timer);
 		irlap_next_state(self, LAP_NDM);
 
@@ -941,11 +941,11 @@
 		break;
 	default:
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
-			   irlap_event[event]);		
+			   irlap_event[event]);
 
 		ret = -1;
 		break;
-	}	
+	}
 	return ret;
 }
 
@@ -955,8 +955,8 @@
  *    OFFLINE state, not used for now!
  *
  */
-static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event, 
-			       struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event,
+			       struct sk_buff *skb, struct irlap_info *info)
 {
 	IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event\n");
 
@@ -965,31 +965,31 @@
 
 /*
  * Function irlap_state_xmit_p (self, event, skb, info)
- * 
+ *
  *    XMIT, Only the primary station has right to transmit, and we
  *    therefore do not expect to receive any transmissions from other
  *    stations.
- * 
+ *
  */
-static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, 
-			      struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
+			      struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
-	
+
 	switch (event) {
 	case SEND_I_CMD:
 		/*
 		 *  Only send frame if send-window > 0.
-		 */ 
+		 */
 		if ((self->window > 0) && (!self->remote_busy)) {
 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
 			/*
-			 *  Test if we have transmitted more bytes over the 
-			 *  link than its possible to do with the current 
+			 *  Test if we have transmitted more bytes over the
+			 *  link than its possible to do with the current
 			 *  speed and turn-around-time.
 			 */
 			if (skb->len > self->bytes_left) {
-				IRDA_DEBUG(4, __FUNCTION__ 
+				IRDA_DEBUG(4, __FUNCTION__
 					   "(), Not allowed to transmit more "
 					   "bytes!\n");
 				skb_queue_head(&self->txq, skb_get(skb));
@@ -1009,18 +1009,18 @@
 			 *  Send data with poll bit cleared only if window > 1
 			 *  and there is more frames after this one to be sent
 			 */
-			if ((self->window > 1) && 
-			    skb_queue_len( &self->txq) > 0) 
-			{   
+			if ((self->window > 1) &&
+			    skb_queue_len( &self->txq) > 0)
+			{
 				irlap_send_data_primary(self, skb);
 				irlap_next_state(self, LAP_XMIT_P);
 			} else {
 				irlap_send_data_primary_poll(self, skb);
 				irlap_next_state(self, LAP_NRM_P);
-				
-				/* 
+
+				/*
 				 * Make sure state machine does not try to send
-				 * any more frames 
+				 * any more frames
 				 */
 				ret = -EPROTO;
 			}
@@ -1029,12 +1029,12 @@
 			self->fast_RR = FALSE;
 #endif /* CONFIG_IRDA_FAST_RR */
 		} else {
-			IRDA_DEBUG(4, __FUNCTION__ 
+			IRDA_DEBUG(4, __FUNCTION__
 				   "(), Unable to send! remote busy?\n");
 			skb_queue_head(&self->txq, skb_get(skb));
 
 			/*
-			 *  The next ret is important, because it tells 
+			 *  The next ret is important, because it tells
 			 *  irlap_next_state _not_ to deliver more frames
 			 */
 			ret = -EPROTO;
@@ -1067,7 +1067,7 @@
 		 * when we return... - Jean II */
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlap_event[event]);
 
 		ret = -EINVAL;
@@ -1081,15 +1081,15 @@
  *
  *    PCLOSE state
  */
-static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event, 
-			      struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event,
+			      struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
 
 	IRDA_DEBUG(1, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return -1;);
-	ASSERT(self->magic == LAP_MAGIC, return -1;);	
+	ASSERT(self->magic == LAP_MAGIC, return -1;);
 
 	switch (event) {
 	case RECV_UA_RSP: /* FALLTHROUGH */
@@ -1101,7 +1101,7 @@
 
 		/* Always switch state before calling upper layers */
 		irlap_next_state(self, LAP_NDM);
-		
+
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 		break;
 	case FINAL_TIMER_EXPIRED:
@@ -1124,7 +1124,7 @@
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event);
 
 		ret = -1;
-		break;	
+		break;
 	}
 	return ret;
 }
@@ -1138,8 +1138,8 @@
  *   transmit any frames and is expecting to receive frames only from the
  *   secondary to which transmission permissions has been given.
  */
-static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, 
-			     struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
+			     struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
 	int ns_status;
@@ -1149,7 +1149,7 @@
 	case RECV_I_RSP: /* Optimize for the common case */
 		/* FIXME: must check for remote_busy below */
 #ifdef CONFIG_IRDA_FAST_RR
-		/* 
+		/*
 		 *  Reset the fast_RR so we can use the fast RR code with
 		 *  full speed the next time since peer may have more frames
 		 *  to transmitt
@@ -1161,19 +1161,19 @@
 		ns_status = irlap_validate_ns_received(self, info->ns);
 		nr_status = irlap_validate_nr_received(self, info->nr);
 
-		/* 
+		/*
 		 *  Check for expected I(nformation) frame
 		 */
 		if ((ns_status == NS_EXPECTED) && (nr_status == NR_EXPECTED)) {
 			/*  poll bit cleared?  */
 			if (!info->pf) {
 				self->vr = (self->vr + 1) % 8;
-			
+
 				/* Update Nr received */
 				irlap_update_nr_received( self, info->nr);
-				
+
 				self->ack_required = TRUE;
-				
+
 				/* Keep state, do not move this line */
 				irlap_next_state(self, LAP_NRM_P);
 
@@ -1182,18 +1182,18 @@
 				del_timer(&self->final_timer);
 
 				self->vr = (self->vr + 1) % 8;
-			
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-		
-				/*  
+
+				/*
 				 *  Got expected NR, so reset the
 				 *  retry_count. This is not done by IrLAP,
-				 *  which is strange!  
+				 *  which is strange!
 				 */
 				self->retry_count = 0;
 				self->ack_required = TRUE;
-			
+
 				irlap_wait_min_turn_around(self, &self->qos_tx);
 
 				/* Call higher layer *before* changing state
@@ -1218,16 +1218,16 @@
 				irlap_start_poll_timer(self, self->poll_timeout);
 			}
 			break;
-			
+
 		}
 		/* Unexpected next to send (Ns) */
 		if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_EXPECTED))
 		{
 			if (!info->pf) {
 				irlap_update_nr_received(self, info->nr);
-				
+
 				/*
-				 *  Wait until the last frame before doing 
+				 *  Wait until the last frame before doing
 				 *  anything
 				 */
 
@@ -1236,57 +1236,57 @@
 			} else {
 				IRDA_DEBUG(4, __FUNCTION__
 				       "(), missing or duplicate frame!\n");
-				
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-				
+
 				irlap_wait_min_turn_around(self, &self->qos_tx);
 				irlap_send_rr_frame(self, CMD_FRAME);
-				
+
 				self->ack_required = FALSE;
-			
+
 				irlap_start_final_timer(self, self->final_timeout);
 				irlap_next_state(self, LAP_NRM_P);
 			}
 			break;
 		}
-		/* 
-		 *  Unexpected next to receive (Nr) 
+		/*
+		 *  Unexpected next to receive (Nr)
 		 */
 		if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
 		{
 			if (info->pf) {
 				self->vr = (self->vr + 1) % 8;
-			
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-			
+
 				/* Resend rejected frames */
 				irlap_resend_rejected_frames(self, CMD_FRAME);
-				
+
 				self->ack_required = FALSE;
 				irlap_start_final_timer(self, self->final_timeout);
-				
+
 				/* Keep state, do not move this line */
 				irlap_next_state(self, LAP_NRM_P);
 
 				irlap_data_indication(self, skb, FALSE);
 			} else {
-				/* 
+				/*
 				 *  Do not resend frames until the last
 				 *  frame has arrived from the other
 				 *  device. This is not documented in
-				 *  IrLAP!!  
+				 *  IrLAP!!
 				 */
 				self->vr = (self->vr + 1) % 8;
 
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-				
+
 				self->ack_required = FALSE;
 
 				/* Keep state, do not move this line!*/
-				irlap_next_state(self, LAP_NRM_P); 
+				irlap_next_state(self, LAP_NRM_P);
 
 				irlap_data_indication(self, skb, FALSE);
 			}
@@ -1296,15 +1296,15 @@
 		 *  Unexpected next to send (Ns) and next to receive (Nr)
 		 *  Not documented by IrLAP!
 		 */
-		if ((ns_status == NS_UNEXPECTED) && 
-		    (nr_status == NR_UNEXPECTED)) 
+		if ((ns_status == NS_UNEXPECTED) &&
+		    (nr_status == NR_UNEXPECTED))
 		{
-			IRDA_DEBUG(4, __FUNCTION__ 
+			IRDA_DEBUG(4, __FUNCTION__
 				   "(), unexpected nr and ns!\n");
 			if (info->pf) {
 				/* Resend rejected frames */
 				irlap_resend_rejected_frames(self, CMD_FRAME);
-				
+
 				/* Give peer some time to retransmit! */
 				irlap_start_final_timer(self, self->final_timeout);
 
@@ -1313,7 +1313,7 @@
 			} else {
 				/* Update Nr received */
 				/* irlap_update_nr_received( info->nr); */
-				
+
 				self->ack_required = FALSE;
 			}
 			break;
@@ -1325,23 +1325,23 @@
 		if ((nr_status == NR_INVALID) || (ns_status == NS_INVALID)) {
 			if (info->pf) {
 				del_timer(&self->final_timer);
-				
+
 				irlap_next_state(self, LAP_RESET_WAIT);
-				
+
 				irlap_disconnect_indication(self, LAP_RESET_INDICATION);
 				self->xmitflag = TRUE;
 			} else {
 				del_timer(&self->final_timer);
-				
+
 				irlap_disconnect_indication(self, LAP_RESET_INDICATION);
-				
+
 				self->xmitflag = FALSE;
 			}
 			break;
 		}
 		IRDA_DEBUG(1, __FUNCTION__ "(), Not implemented!\n");
-		IRDA_DEBUG(1, __FUNCTION__ 
-		      "(), event=%s, ns_status=%d, nr_status=%d\n", 
+		IRDA_DEBUG(1, __FUNCTION__
+		      "(), event=%s, ns_status=%d, nr_status=%d\n",
 		      irlap_event[ event], ns_status, nr_status);
 		break;
 	case RECV_UI_FRAME:
@@ -1353,34 +1353,34 @@
 			del_timer(&self->final_timer);
 			irlap_data_indication(self, skb, TRUE);
 			irlap_next_state(self, LAP_XMIT_P);
-			printk(__FUNCTION__ "(): RECV_UI_FRAME: next state %s\n", irlap_state[self->state]);
+			printk("%s: RECV_UI_FRAME: next state %s\n", __FUNCTION__, irlap_state[self->state]);
 			irlap_start_poll_timer(self, self->poll_timeout);
 		}
 		break;
 	case RECV_RR_RSP:
-		/*  
-		 *  If you get a RR, the remote isn't busy anymore, 
-		 *  no matter what the NR 
+		/*
+		 *  If you get a RR, the remote isn't busy anymore,
+		 *  no matter what the NR
 		 */
 		self->remote_busy = FALSE;
 
-		/* 
-		 *  Nr as expected? 
+		/*
+		 *  Nr as expected?
 		 */
 		ret = irlap_validate_nr_received(self, info->nr);
-		if (ret == NR_EXPECTED) {	
+		if (ret == NR_EXPECTED) {
 			/* Stop final timer */
 			del_timer(&self->final_timer);
-			
+
 			/* Update Nr received */
 			irlap_update_nr_received(self, info->nr);
-			
+
 			/*
-			 *  Got expected NR, so reset the retry_count. This 
-			 *  is not done by the IrLAP standard , which is 
+			 *  Got expected NR, so reset the retry_count. This
+			 *  is not done by the IrLAP standard , which is
 			 *  strange! DB.
 			 */
-			self->retry_count = 0;			
+			self->retry_count = 0;
 			irlap_wait_min_turn_around(self, &self->qos_tx);
 
 			irlap_next_state(self, LAP_XMIT_P);
@@ -1388,22 +1388,22 @@
 			/* Start poll timer */
 			irlap_start_poll_timer(self, self->poll_timeout);
 		} else if (ret == NR_UNEXPECTED) {
-			ASSERT(info != NULL, return -1;);	
-			/* 
-			 *  Unexpected nr! 
+			ASSERT(info != NULL, return -1;);
+			/*
+			 *  Unexpected nr!
 			 */
-			
+
 			/* Update Nr received */
 			irlap_update_nr_received(self, info->nr);
 
 			IRDA_DEBUG(4, "RECV_RR_FRAME: Retrans:%d, nr=%d, va=%d, "
 			      "vs=%d, vr=%d\n",
-			      self->retry_count, info->nr, self->va, 
+			      self->retry_count, info->nr, self->va,
 			      self->vs, self->vr);
-			
+
 			/* Resend rejected frames */
 			irlap_resend_rejected_frames(self, CMD_FRAME);
-			
+
 			irlap_next_state(self, LAP_NRM_P);
 		} else if (ret == NR_INVALID) {
 			IRDA_DEBUG(1, __FUNCTION__ "(), Received RR with "
@@ -1426,7 +1426,7 @@
 		/* Update Nr received */
 		irlap_update_nr_received(self, info->nr);
 		irlap_next_state(self, LAP_XMIT_P);
-			
+
 		/* Start poll timer */
 		irlap_start_poll_timer(self, self->poll_timeout);
 		break;
@@ -1437,7 +1437,7 @@
 		irlap_reset_indication(self);
 		break;
 	case FINAL_TIMER_EXPIRED:
-		/* 
+		/*
 		 *  We are allowed to wait for additional 300 ms if
 		 *  final timer expires when we are in the middle
 		 *  of receiving a frame (page 45, IrLAP). Check that
@@ -1449,8 +1449,8 @@
 			irlap_start_final_timer(self, MSECS_TO_JIFFIES(300));
 
 			/*
-			 *  Don't allow this to happen one more time in a row, 
-			 *  or else we can get a pretty tight loop here if 
+			 *  Don't allow this to happen one more time in a row,
+			 *  or else we can get a pretty tight loop here if
 			 *  if we only receive half a frame. DB.
 			 */
 			self->add_wait = TRUE;
@@ -1463,9 +1463,9 @@
 			/* Retry sending the pf bit to the secondary */
 			irlap_wait_min_turn_around(self, &self->qos_tx);
 			irlap_send_rr_frame(self, CMD_FRAME);
-			
+
 			irlap_start_final_timer(self, self->final_timeout);
-		 	self->retry_count++;
+			self->retry_count++;
 			IRDA_DEBUG(4, "irlap_state_nrm_p: FINAL_TIMER_EXPIRED:"
 				   " retry_count=%d\n", self->retry_count);
 
@@ -1515,7 +1515,7 @@
 		irlap_disconnect_request(self);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n",
 			   irlap_event[event]);
 
 		ret = -1;
@@ -1531,16 +1531,16 @@
  *    awaiting reset of disconnect request.
  *
  */
-static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event,
 				  struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
-	
+
 	IRDA_DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]);
-	
+
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
-	
+
 	switch (event) {
 	case RESET_REQUEST:
 		if (self->xmitflag) {
@@ -1562,11 +1562,11 @@
 		irlap_next_state( self, LAP_PCLOSE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
 			   irlap_event[event]);
 
 		ret = -1;
-		break;	
+		break;
 	}
 	return ret;
 }
@@ -1578,16 +1578,16 @@
  *    reply.
  *
  */
-static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, 
+static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event,
 			     struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
-	
+
 	IRDA_DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]);
-	
+
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
-	
+
 	switch (event) {
 	case RECV_DISC_CMD:
 		del_timer(&self->final_timer);
@@ -1602,12 +1602,12 @@
 		break;
 	case RECV_UA_RSP:
 		del_timer(&self->final_timer);
-		
+
 		/* Initiate connection state */
 		irlap_initiate_connection_state(self);
-		
+
 		irlap_reset_confirm();
-		
+
 		self->remote_busy = FALSE;
 
 		irlap_next_state(self, LAP_XMIT_P);
@@ -1628,16 +1628,16 @@
 			irlap_next_state(self, LAP_RESET);
 		} else if (self->retry_count >= self->N3) {
 			irlap_apply_default_connection_parameters(self);
-			
+
 			/* Always switch state before calling upper layers */
 			irlap_next_state(self, LAP_NDM);
-			
+
 			irlap_disconnect_indication(self, LAP_NO_RESPONSE);
 		}
 		break;
 	case RECV_SNRM_CMD:
-		/* 
-		 * SNRM frame is not allowed to contain an I-field in this 
+		/*
+		 * SNRM frame is not allowed to contain an I-field in this
 		 * state
 		 */
 		if (!info) {
@@ -1649,47 +1649,47 @@
 			irlap_start_wd_timer(self, self->wd_timeout);
 			irlap_next_state(self, LAP_NDM);
 		} else {
-			IRDA_DEBUG(0, __FUNCTION__ 
+			IRDA_DEBUG(0, __FUNCTION__
 				   "(), SNRM frame contained an I field!\n");
 		}
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", 
-			   irlap_event[event]);	
+		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n",
+			   irlap_event[event]);
 
 		ret = -1;
-		break;	
+		break;
 	}
 	return ret;
 }
 
 /*
  * Function irlap_state_xmit_s (event, skb, info)
- * 
+ *
  *   XMIT_S, The secondary station has been given the right to transmit,
  *   and we therefor do not expect to receive any transmissions from other
- *   stations.  
+ *   stations.
  */
-static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, 
-			      struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
+			      struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
-	
-	IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[event]); 
+
+	IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[event]);
 
 	ASSERT(self != NULL, return -ENODEV;);
 	ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
-	
+
 	switch (event) {
 	case SEND_I_CMD:
 		/*
 		 *  Send frame only if send window > 1
-		 */ 
+		 */
 		if ((self->window > 0) && (!self->remote_busy)) {
 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
 			/*
-			 *  Test if we have transmitted more bytes over the 
-			 *  link than its possible to do with the current 
+			 *  Test if we have transmitted more bytes over the
+			 *  link than its possible to do with the current
 			 *  speed and turn-around-time.
 			 */
 			if (skb->len > self->bytes_left) {
@@ -1697,7 +1697,7 @@
 
 				/*
 				 *  Switch to NRM_S, this is only possible
-				 *  when we are in secondary mode, since we 
+				 *  when we are in secondary mode, since we
 				 *  must be sure that we don't miss any RR
 				 *  frames
 				 */
@@ -1715,18 +1715,18 @@
 			 *  Send data with final bit cleared only if window > 1
 			 *  and there is more frames to be sent
 			 */
-			if ((self->window > 1) && 
-			    skb_queue_len(&self->txq) > 0) 
-			{   
+			if ((self->window > 1) &&
+			    skb_queue_len(&self->txq) > 0)
+			{
 				irlap_send_data_secondary(self, skb);
 				irlap_next_state(self, LAP_XMIT_S);
 			} else {
 				irlap_send_data_secondary_final(self, skb);
 				irlap_next_state(self, LAP_NRM_S);
 
-				/* 
+				/*
 				 * Make sure state machine does not try to send
-				 * any more frames 
+				 * any more frames
 				 */
 				ret = -EPROTO;
 			}
@@ -1747,7 +1747,7 @@
 		 * when we return... - Jean II */
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
 			   irlap_event[event]);
 
 		ret = -EINVAL;
@@ -1759,12 +1759,12 @@
 /*
  * Function irlap_state_nrm_s (event, skb, info)
  *
- *    NRM_S (Normal Response Mode as Secondary) state, in this state we are 
+ *    NRM_S (Normal Response Mode as Secondary) state, in this state we are
  *    expecting to receive frames from the primary station
  *
  */
-static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, 
-			     struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
+			     struct sk_buff *skb, struct irlap_info *info)
 {
 	int ns_status;
 	int nr_status;
@@ -1779,28 +1779,28 @@
 	case RECV_I_CMD: /* Optimize for the common case */
 		/* FIXME: must check for remote_busy below */
 		IRDA_DEBUG(4, __FUNCTION__ "(), event=%s nr=%d, vs=%d, ns=%d, "
-			   "vr=%d, pf=%d\n", irlap_event[event], info->nr, 
+			   "vr=%d, pf=%d\n", irlap_event[event], info->nr,
 			   self->vs, info->ns, self->vr, info->pf);
 
 		self->retry_count = 0;
 
 		ns_status = irlap_validate_ns_received(self, info->ns);
 		nr_status = irlap_validate_nr_received(self, info->nr);
-		/* 
+		/*
 		 *  Check for expected I(nformation) frame
 		 */
 		if ((ns_status == NS_EXPECTED) && (nr_status == NR_EXPECTED)) {
-			/* 
+			/*
 			 *  poll bit cleared?
 			 */
 			if (!info->pf) {
 				self->vr = (self->vr + 1) % 8;
-				
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-				
+
 				self->ack_required = TRUE;
-				
+
 				/*
 				 *  Starting WD-timer here is optional, but
 				 *  not recommended. Note 6 IrLAP p. 83
@@ -1815,18 +1815,18 @@
 				break;
 			} else {
 				self->vr = (self->vr + 1) % 8;
-				
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-				
-				/* 
+
+				/*
 				 *  We should wait before sending RR, and
 				 *  also before changing to XMIT_S
-				 *  state. (note 1, IrLAP p. 82) 
+				 *  state. (note 1, IrLAP p. 82)
 				 */
 				irlap_wait_min_turn_around(self, &self->qos_tx);
 
-				/*  
+				/*
 				 * Give higher layers a chance to
 				 * immediately reply with some data before
 				 * we decide if we should send a RR frame
@@ -1835,17 +1835,17 @@
 				irlap_data_indication(self, skb, FALSE);
 
 				/* Any pending data requests?  */
-				if ((skb_queue_len(&self->txq) > 0) && 
-				    (self->window > 0)) 
+				if ((skb_queue_len(&self->txq) > 0) &&
+				    (self->window > 0))
 				{
 					self->ack_required = TRUE;
-					
+
 					del_timer(&self->wd_timer);
-					
+
 					irlap_next_state(self, LAP_XMIT_S);
 				} else {
 					irlap_send_rr_frame(self, RSP_FRAME);
-					irlap_start_wd_timer(self, 
+					irlap_start_wd_timer(self,
 							     self->wd_timeout);
 
 					/* Keep the state */
@@ -1862,33 +1862,33 @@
 			/* Unexpected next to send, with final bit cleared */
 			if (!info->pf) {
 				irlap_update_nr_received(self, info->nr);
-				
+
 				irlap_start_wd_timer(self, self->wd_timeout);
 			} else {
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-			
+
 				irlap_wait_min_turn_around(self, &self->qos_tx);
 				irlap_send_rr_frame(self, CMD_FRAME);
-			
+
 				irlap_start_wd_timer(self, self->wd_timeout);
 			}
 			break;
 		}
 
-		/* 
+		/*
 		 *  Unexpected Next to Receive(NR) ?
 		 */
 		if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
 		{
 			if (info->pf) {
 				IRDA_DEBUG(4, "RECV_I_RSP: frame(s) lost\n");
-				
+
 				self->vr = (self->vr + 1) % 8;
-				
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-				
+
 				/* Resend rejected frames */
 				irlap_resend_rejected_frames(self, RSP_FRAME);
 
@@ -1905,10 +1905,10 @@
 			 */
 			if (!info->pf) {
 				self->vr = (self->vr + 1) % 8;
-				
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
-				
+
 				/* Keep state, do not move this line */
 				irlap_next_state(self, LAP_NRM_S);
 
@@ -1917,7 +1917,7 @@
 			}
 			break;
 		}
-		
+
 		if (ret == NR_INVALID) {
 			IRDA_DEBUG(0, "NRM_S, NR_INVALID not implemented!\n");
 		}
@@ -1926,7 +1926,7 @@
 		}
 		break;
 	case RECV_UI_FRAME:
-		/* 
+		/*
 		 *  poll bit cleared?
 		 */
 		if (!info->pf) {
@@ -1936,11 +1936,11 @@
 			/*
 			 *  Any pending data requests?
 			 */
-			if ((skb_queue_len(&self->txq) > 0) && 
-			    (self->window > 0) && !self->remote_busy) 
+			if ((skb_queue_len(&self->txq) > 0) &&
+			    (self->window > 0) && !self->remote_busy)
 			{
 				irlap_data_indication(self, skb, TRUE);
-				
+
 				del_timer(&self->wd_timer);
 
 				irlap_next_state(self, LAP_XMIT_S);
@@ -1951,7 +1951,7 @@
 
 				irlap_send_rr_frame(self, RSP_FRAME);
 				self->ack_required = FALSE;
-				
+
 				irlap_start_wd_timer(self, self->wd_timeout);
 
 				/* Keep the state */
@@ -1962,28 +1962,28 @@
 	case RECV_RR_CMD:
 		self->retry_count = 0;
 
-		/* 
-		 *  Nr as expected? 
+		/*
+		 *  Nr as expected?
 		 */
 		nr_status = irlap_validate_nr_received(self, info->nr);
 		if (nr_status == NR_EXPECTED) {
-			if ((skb_queue_len( &self->txq) > 0) && 
+			if ((skb_queue_len( &self->txq) > 0) &&
 			    (self->window > 0)) {
 				self->remote_busy = FALSE;
-				
+
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
 				del_timer(&self->wd_timer);
-				
+
 				irlap_wait_min_turn_around(self, &self->qos_tx);
 				irlap_next_state(self, LAP_XMIT_S);
-			} else {			
+			} else {
 				self->remote_busy = FALSE;
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
 				irlap_wait_min_turn_around(self, &self->qos_tx);
 				irlap_start_wd_timer(self, self->wd_timeout);
-				
+
 				/* Note : if the link is idle (this case),
 				 * we never go in XMIT_S, so we never get a
 				 * chance to process any DISCONNECT_REQUEST.
@@ -1997,7 +1997,7 @@
 				} else {
 					/* Just send back pf bit */
 					irlap_send_rr_frame(self, RSP_FRAME);
-				
+
 					irlap_next_state(self, LAP_NRM_S);
 				}
 			}
@@ -2009,11 +2009,11 @@
 			irlap_start_wd_timer(self, self->wd_timeout);
 
 			/* Keep state */
-			irlap_next_state(self, LAP_NRM_S); 
+			irlap_next_state(self, LAP_NRM_S);
 		} else {
-			IRDA_DEBUG(1, __FUNCTION__ 
+			IRDA_DEBUG(1, __FUNCTION__
 				   "(), invalid nr not implemented!\n");
-		} 
+		}
 		break;
 	case RECV_SNRM_CMD:
 		/* SNRM frame is not allowed to contain an I-field */
@@ -2021,12 +2021,12 @@
 			del_timer(&self->wd_timer);
 			IRDA_DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n");
 			irlap_next_state(self, LAP_RESET_CHECK);
-			
+
 			irlap_reset_indication(self);
 		} else {
-			IRDA_DEBUG(0, __FUNCTION__ 
+			IRDA_DEBUG(0, __FUNCTION__
 				   "(), SNRM frame contained an I-field!\n");
-			
+
 		}
 		break;
 	case RECV_REJ_CMD:
@@ -2057,7 +2057,7 @@
 		 *   which explain why we use (self->N2 / 2) here !!!
 		 * Jean II
 		 */
-		IRDA_DEBUG(1, __FUNCTION__ "(), retry_count = %d\n", 
+		IRDA_DEBUG(1, __FUNCTION__ "(), retry_count = %d\n",
 			   self->retry_count);
 
 		if (self->retry_count < (self->N2 / 2)) {
@@ -2070,7 +2070,7 @@
 							STATUS_NO_ACTIVITY);
 		} else {
 			irlap_apply_default_connection_parameters(self);
-			
+
 			/* Always switch state before calling upper layers */
 			irlap_next_state(self, LAP_NDM);
 			irlap_disconnect_indication(self, LAP_NO_RESPONSE);
@@ -2110,7 +2110,7 @@
 		irlap_send_test_frame(self, self->caddr, info->daddr, skb);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", 
+		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
 			   event, irlap_event[event]);
 
 		ret = -EINVAL;
@@ -2121,12 +2121,9 @@
 
 /*
  * Function irlap_state_sclose (self, event, skb, info)
- *
- *    
- *
  */
-static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event, 
-			      struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event,
+			      struct sk_buff *skb, struct irlap_info *info)
 {
 	int ret = 0;
 
@@ -2134,7 +2131,7 @@
 
 	ASSERT(self != NULL, return -ENODEV;);
 	ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
-	
+
 	switch (event) {
 	case RECV_DISC_CMD:
 		/* Always switch state before calling upper layers */
@@ -2156,7 +2153,7 @@
 
 		del_timer(&self->wd_timer);
 		irlap_apply_default_connection_parameters(self);
-		
+
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 		break;
 	case WD_TIMER_EXPIRED:
@@ -2164,11 +2161,11 @@
 		irlap_next_state(self, LAP_NDM);
 
 		irlap_apply_default_connection_parameters(self);
-		
+
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", 
+		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
 			   event, irlap_event[event]);
 
 		ret = -EINVAL;
@@ -2178,24 +2175,24 @@
 	return -1;
 }
 
-static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event, 
-				   struct sk_buff *skb, 
-				   struct irlap_info *info) 
+static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event,
+				   struct sk_buff *skb,
+				   struct irlap_info *info)
 {
 	int ret = 0;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), event=%s\n", irlap_event[event]); 
+	IRDA_DEBUG(1, __FUNCTION__ "(), event=%s\n", irlap_event[event]);
 
 	ASSERT(self != NULL, return -ENODEV;);
 	ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
-	
+
 	switch (event) {
 	case RESET_RESPONSE:
 		irlap_send_ua_response_frame(self, &self->qos_rx);
 		irlap_initiate_connection_state(self);
 		irlap_start_wd_timer(self, WD_TIMEOUT);
 		irlap_flush_all_queues(self);
-		
+
 		irlap_next_state(self, LAP_NRM_S);
 		break;
 	case DISCONNECT_REQUEST:
@@ -2205,7 +2202,7 @@
 		irlap_next_state(self, LAP_SCLOSE);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", 
+		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
 			   event, irlap_event[event]);
 
 		ret = -EINVAL;
diff -Nru a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
--- a/net/irda/irlap_frame.c	Sun Jun 16 19:31:39 2002
+++ b/net/irda/irlap_frame.c	Sun Jun 16 19:31:39 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      irlap_frame.c
  * Version:       1.0
  * Description:   Build and transmit IrLAP frames
@@ -8,18 +8,18 @@
  * Created at:    Tue Aug 19 10:27:26 1997
  * Modified at:   Wed Jan  5 08:59:04 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
+ *
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
  *     All Rights Reserved.
  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
  ********************************************************************/
@@ -29,10 +29,10 @@
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
 #include <linux/irda.h>
- 
+
 #include <net/pkt_sched.h>
 #include <net/sock.h>
- 
+
 #include <asm/byteorder.h>
 
 #include <net/irda/irda.h>
@@ -46,18 +46,18 @@
 /*
  * Function irlap_insert_info (self, skb)
  *
- *    Insert minimum turnaround time and speed information into the skb. We 
+ *    Insert minimum turnaround time and speed information into the skb. We
  *    need to do this since it's per packet relevant information. Safe to
  *    have this function inlined since it's only called from one place
  */
-static inline void irlap_insert_info(struct irlap_cb *self, 
+static inline void irlap_insert_info(struct irlap_cb *self,
 				     struct sk_buff *skb)
 {
 	struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
 
-	/*  
+	/*
 	 * Insert MTT (min. turn time) and speed into skb, so that the
-	 * device driver knows which settings to use 
+	 * device driver knows which settings to use
 	 */
 	cb->magic = LAP_MAGIC;
 	cb->mtt = self->mtt_required;
@@ -65,15 +65,15 @@
 
 	/* Reset */
 	self->mtt_required = 0;
-	
-	/* 
-	 * Delay equals negotiated BOFs count, plus the number of BOFs to 
-	 * force the negotiated minimum turnaround time 
+
+	/*
+	 * Delay equals negotiated BOFs count, plus the number of BOFs to
+	 * force the negotiated minimum turnaround time
 	 */
 	cb->xbofs = self->bofs_count;
 	cb->next_xbofs = self->next_bofs;
 	cb->xbofs_delay = self->xbofs_delay;
-	
+
 	/* Reset XBOF's delay (used only for getting min turn time) */
 	self->xbofs_delay = 0;
 	/* Put the correct xbofs value for the next packet */
@@ -91,7 +91,7 @@
 	/* Some common init stuff */
 	skb->dev = self->netdev;
 	skb->h.raw = skb->nh.raw = skb->mac.raw = skb->data;
- 	skb->protocol = htons(ETH_P_IRDA);
+	skb->protocol = htons(ETH_P_IRDA);
 	skb->priority = TC_PRIO_BESTEFFORT;
 
 	irlap_insert_info(self, skb);
@@ -104,7 +104,7 @@
  *
  *    Transmits a connect SNRM command frame
  */
-void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos) 
+void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
 {
 	struct sk_buff *skb;
 	struct snrm_frame *frame;
@@ -118,7 +118,7 @@
 	if (!skb)
 		return;
 
-	frame = (struct snrm_frame *) skb_put(skb, 2); 
+	frame = (struct snrm_frame *) skb_put(skb, 2);
 
 	/* Insert connection address field */
 	if (qos)
@@ -127,10 +127,10 @@
 		frame->caddr = CMD_FRAME | self->caddr;
 
 	/* Insert control field */
- 	frame->control = SNRM_CMD | PF_BIT;
-	
+	frame->control = SNRM_CMD | PF_BIT;
+
 	/*
-	 *  If we are establishing a connection then insert QoS paramerters 
+	 *  If we are establishing a connection then insert QoS paramerters
 	 */
 	if (qos) {
 		skb_put(skb, 9); /* 21 left */
@@ -138,7 +138,7 @@
 		frame->daddr = cpu_to_le32(self->daddr);
 
 		frame->ncaddr = self->caddr;
-				
+
 		ret = irlap_insert_qos_negotiation_params(self, skb);
 		if (ret < 0) {
 			dev_kfree_skb(skb);
@@ -154,28 +154,28 @@
  *    Received SNRM (Set Normal Response Mode) command frame
  *
  */
-static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb, 
-				struct irlap_info *info) 
+static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb,
+				struct irlap_info *info)
 {
 	struct snrm_frame *frame;
 
 	frame = (struct snrm_frame *) skb->data;
-	
+
 	if (skb->len >= sizeof(struct snrm_frame)) {
 		/* Copy the new connection address */
 		info->caddr = frame->ncaddr;
 
 		/* Check if the new connection address is valid */
 		if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
-			IRDA_DEBUG(3, __FUNCTION__ 
+			IRDA_DEBUG(3, __FUNCTION__
 			      "(), invalid connection address!\n");
 			return;
 		}
-		
+
 		/* Copy peer device address */
 		info->daddr = le32_to_cpu(frame->saddr);
 		info->saddr = le32_to_cpu(frame->daddr);
-		
+
 		/* Only accept if addressed directly to us */
 		if (info->saddr != self->saddr) {
 			IRDA_DEBUG(2, __FUNCTION__ "(), not addressed to us!\n");
@@ -199,9 +199,9 @@
 	struct sk_buff *skb;
 	struct ua_frame *frame;
 	int ret;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "() <%ld>\n", jiffies);
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
@@ -213,10 +213,10 @@
 		return;
 
 	frame = (struct ua_frame *) skb_put(skb, 10);
-	
+
 	/* Build UA response */
 	frame->caddr = self->caddr;
- 	frame->control = UA_RSP | PF_BIT;
+	frame->control = UA_RSP | PF_BIT;
 
 	frame->saddr = cpu_to_le32(self->saddr);
 	frame->daddr = cpu_to_le32(self->daddr);
@@ -244,7 +244,7 @@
 {
 	struct sk_buff *skb = NULL;
 	__u8 *frame;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
@@ -253,7 +253,7 @@
 		return;
 
 	frame = skb_put( skb, 2);
-	
+
 	if (self->state == LAP_NDM)
 		frame[0] = CBROADCAST;
 	else
@@ -261,7 +261,7 @@
 
 	frame[1] = DM_RSP | PF_BIT;
 
-	irlap_queue_xmit(self, skb);	
+	irlap_queue_xmit(self, skb);
 }
 
 /*
@@ -270,11 +270,11 @@
  *    Send disconnect (DISC) frame
  *
  */
-void irlap_send_disc_frame(struct irlap_cb *self) 
+void irlap_send_disc_frame(struct irlap_cb *self)
 {
 	struct sk_buff *skb = NULL;
 	__u8 *frame;
-	
+
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
@@ -285,7 +285,7 @@
 		return;
 
 	frame = skb_put(skb, 2);
-	
+
 	frame[0] = self->caddr | CMD_FRAME;
 	frame[1] = DISC_CMD | PF_BIT;
 
@@ -296,17 +296,17 @@
  * Function irlap_send_discovery_xid_frame (S, s, command)
  *
  *    Build and transmit a XID (eXchange station IDentifier) discovery
- *    frame. 
+ *    frame.
  */
-void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s, 
-				    __u8 command, discovery_t *discovery) 
+void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
+				    __u8 command, discovery_t *discovery)
 {
 	struct sk_buff *skb = NULL;
 	struct xid_frame *frame;
 	__u32 bcast = BROADCAST;
 	__u8 *info;
 
- 	IRDA_DEBUG(4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S, 
+	IRDA_DEBUG(4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S,
 		   command);
 
 	ASSERT(self != NULL, return;);
@@ -335,7 +335,7 @@
 		frame->daddr = cpu_to_le32(bcast);
 	else
 		frame->daddr = cpu_to_le32(discovery->daddr);
-	
+
 	switch (S) {
 	case 1:
 		frame->flags = 0x00;
@@ -354,10 +354,10 @@
 		break;
 	}
 
-	frame->slotnr = s; 
+	frame->slotnr = s;
 	frame->version = 0x00;
 
-	/*  
+	/*
 	 *  Provide info for final slot only in commands, and for all
 	 *  responses. Send the second byte of the hint only if the
 	 *  EXTENSION bit is set in the first byte.
@@ -366,7 +366,7 @@
 		int len;
 
 		if (discovery->hints.byte[0] & HINT_EXTENSION) {
-			info = skb_put(skb, 2);		
+			info = skb_put(skb, 2);
 			info[0] = discovery->hints.byte[0];
 			info[1] = discovery->hints.byte[1];
 		} else {
@@ -379,7 +379,7 @@
 		len = IRDA_MIN(discovery->name_len, skb_tailroom(skb));
 		info = skb_put(skb, len);
 		memcpy(info, discovery->nickname, len);
-	} 
+	}
 	irlap_queue_xmit(self, skb);
 }
 
@@ -389,9 +389,9 @@
  *    Received a XID discovery response
  *
  */
-static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, 
-					 struct sk_buff *skb, 
-					 struct irlap_info *info) 
+static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
+					 struct sk_buff *skb,
+					 struct irlap_info *info)
 {
 	struct xid_frame *xid;
 	discovery_t *discovery = NULL;
@@ -410,13 +410,13 @@
 
 	/* Make sure frame is addressed to us */
 	if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
-		IRDA_DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__
 			   "(), frame is not addressed to us!\n");
 		return;
 	}
 
 	if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
-		WARNING(__FUNCTION__ "(), kmalloc failed!\n");
+		WARNING("%s: kmalloc failed!\n", __FUNCTION__);
 		return;
 	}
 	memset(discovery, 0, sizeof(discovery_t));
@@ -441,11 +441,11 @@
 		discovery->charset = discovery_info[1];
 		text = (char *) &discovery_info[2];
 	}
-	/* 
-	 *  Terminate info string, should be safe since this is where the 
+	/*
+	 *  Terminate info string, should be safe since this is where the
 	 *  FCS bytes resides.
 	 */
-	skb->data[skb->len] = '\0'; 
+	skb->data[skb->len] = '\0';
 	strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
 	discovery->name_len = strlen(discovery->nickname);
 
@@ -460,9 +460,9 @@
  *    Received a XID discovery command
  *
  */
-static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, 
-					 struct sk_buff *skb, 
-					 struct irlap_info *info) 
+static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
+					 struct sk_buff *skb,
+					 struct irlap_info *info)
 {
 	struct xid_frame *xid;
 	discovery_t *discovery = NULL;
@@ -476,7 +476,7 @@
 
 	/* Make sure frame is addressed to us */
 	if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
-		IRDA_DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__
 			   "(), frame is not addressed to us!\n");
 		return;
 	}
@@ -500,16 +500,16 @@
 		return;
 	}
 	info->s = xid->slotnr;
-	
+
 	discovery_info = skb_pull(skb, sizeof(struct xid_frame));
 
-	/* 
-	 *  Check if last frame 
+	/*
+	 *  Check if last frame
 	 */
 	if (info->s == 0xff) {
 		/* Check if things are sane at this point... */
 		if((discovery_info == NULL) || (skb->len < 3)) {
-			ERROR(__FUNCTION__ "(), discovery frame to short!\n");
+			ERROR("%s: discovery frame to short!\n", __FUNCTION__);
 			return;
 		}
 
@@ -518,10 +518,10 @@
 		 */
 		discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
 		if (!discovery) {
-			WARNING(__FUNCTION__ "(), unable to malloc!\n");
+			WARNING("%s: unable to malloc!\n", __FUNCTION__);
 			return;
 		}
-	      
+
 		discovery->daddr = info->daddr;
 		discovery->saddr = self->saddr;
 		discovery->timestamp = jiffies;
@@ -536,11 +536,11 @@
 			discovery->charset = discovery_info[1];
 			text = (char *) &discovery_info[2];
 		}
-		/* 
-		 *  Terminate string, should be safe since this is where the 
+		/*
+		 *  Terminate string, should be safe since this is where the
 		 *  FCS bytes resides.
 		 */
-		skb->data[skb->len] = '\0'; 
+		skb->data[skb->len] = '\0';
 		strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
 		discovery->name_len = strlen(discovery->nickname);
 
@@ -557,7 +557,7 @@
  *    Build and transmit RR (Receive Ready) frame. Notice that it is currently
  *    only possible to send RR frames with the poll bit set.
  */
-void irlap_send_rr_frame(struct irlap_cb *self, int command) 
+void irlap_send_rr_frame(struct irlap_cb *self, int command)
 {
 	struct sk_buff *skb;
 	__u8 *frame;
@@ -565,9 +565,9 @@
 	skb = dev_alloc_skb(16);
 	if (!skb)
 		return;
-	
+
 	frame = skb_put(skb, 2);
-	
+
 	frame[0] = self->caddr;
 	frame[0] |= (command) ? CMD_FRAME : 0;
 
@@ -579,7 +579,7 @@
 /*
  * Function irlap_send_rd_frame (self)
  *
- *    Request disconnect. Used by a secondary station to request the 
+ *    Request disconnect. Used by a secondary station to request the
  *    disconnection of the link.
  */
 void irlap_send_rd_frame(struct irlap_cb *self)
@@ -590,9 +590,9 @@
 	skb = dev_alloc_skb(16);
 	if (!skb)
 		return;
-	
+
 	frame = skb_put(skb, 2);
-	
+
 	frame[0] = self->caddr;
 	frame[1] = RD_RSP | PF_BIT;
 
@@ -606,8 +606,8 @@
  *    making it inline since its called only from one single place
  *    (irlap_driver_rcv).
  */
-static inline void irlap_recv_rr_frame(struct irlap_cb *self, 
-				       struct sk_buff *skb, 
+static inline void irlap_recv_rr_frame(struct irlap_cb *self,
+				       struct sk_buff *skb,
 				       struct irlap_info *info, int command)
 {
 	info->nr = skb->data[1] >> 5;
@@ -623,7 +623,7 @@
 {
 	struct sk_buff *skb = NULL;
 	__u8 *frame;
-	
+
 	ASSERT( self != NULL, return;);
 	ASSERT( self->magic == LAP_MAGIC, return;);
 
@@ -632,7 +632,7 @@
 		return;
 
 	frame = skb_put( skb, 2);
-	
+
 	frame[0] = self->caddr;
 	frame[0] |= (command) ? CMD_FRAME : 0;
 
@@ -642,7 +642,7 @@
 
 	frame[2] = 0;
 
-   	IRDA_DEBUG(4, __FUNCTION__ "(), vr=%d, %ld\n",self->vr, jiffies); 
+	IRDA_DEBUG(4, __FUNCTION__ "(), vr=%d, %ld\n",self->vr, jiffies);
 
 	irlap_queue_xmit(self, skb);
 }
@@ -653,8 +653,8 @@
  *    Received RNR (Receive Not Ready) frame from peer station
  *
  */
-static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb, 
-				 struct irlap_info *info, int command) 
+static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb,
+				 struct irlap_info *info, int command)
 {
 	info->nr = skb->data[1] >> 5;
 
@@ -666,13 +666,13 @@
 		irlap_do_event(self, RECV_RNR_RSP, skb, info);
 }
 
-static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb, 
+static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb,
 				 struct irlap_info *info, int command)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	info->nr = skb->data[1] >> 5;
-	
+
 	/* Check if this is a command or a response frame */
 	if (command)
 		irlap_do_event(self, RECV_REJ_CMD, skb, info);
@@ -680,13 +680,13 @@
 		irlap_do_event(self, RECV_REJ_RSP, skb, info);
 }
 
-static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb, 
+static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb,
 				  struct irlap_info *info, int command)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	info->nr = skb->data[1] >> 5;
-	
+
 	/* Check if this is a command or a response frame */
 	if (command)
 		irlap_do_event(self, RECV_SREJ_CMD, skb, info);
@@ -694,7 +694,7 @@
 		irlap_do_event(self, RECV_SREJ_RSP, skb, info);
 }
 
-static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb, 
+static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb,
 				  struct irlap_info *info, int command)
 {
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
@@ -712,9 +712,9 @@
  *    Received UA (Unnumbered Acknowledgement) frame
  *
  */
-static inline void irlap_recv_ua_frame(struct irlap_cb *self, 
-				       struct sk_buff *skb, 
-				       struct irlap_info *info) 
+static inline void irlap_recv_ua_frame(struct irlap_cb *self,
+				       struct sk_buff *skb,
+				       struct irlap_info *info)
 {
 	irlap_do_event(self, RECV_UA_RSP, skb, info);
 }
@@ -731,25 +731,25 @@
 
 	if (skb->data[1] == I_FRAME) {
 
-		/*  
+		/*
 		 *  Insert frame sequence number (Vs) in control field before
 		 *  inserting into transmit window queue.
 		 */
 		skb->data[1] = I_FRAME | (self->vs << 1);
-		
+
 		/* Copy buffer */
 		tx_skb = skb_clone(skb, GFP_ATOMIC);
 		if (tx_skb == NULL) {
 			return;
 		}
-		
-		/* 
-		 *  Insert frame in store, in case of retransmissions 
+
+		/*
+		 *  Insert frame in store, in case of retransmissions
 		 */
 		skb_queue_tail(&self->wx_list, skb_get(skb));
-		
+
 		self->vs = (self->vs + 1) % 8;
-		self->ack_required = FALSE;		
+		self->ack_required = FALSE;
 		self->window -= 1;
 
 		irlap_send_i_frame( self, tx_skb, CMD_FRAME);
@@ -764,40 +764,40 @@
  *
  *    Send I(nformation) frame as primary with poll bit set
  */
-void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) 
+void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
 {
 	struct sk_buff *tx_skb;
 
 	/* Stop P timer */
 	del_timer(&self->poll_timer);
-		
+
 	/* Is this reliable or unreliable data? */
 	if (skb->data[1] == I_FRAME) {
-		
-		/*  
+
+		/*
 		 *  Insert frame sequence number (Vs) in control field before
 		 *  inserting into transmit window queue.
 		 */
 		skb->data[1] = I_FRAME | (self->vs << 1);
-		
+
 		/* Copy buffer */
 		tx_skb = skb_clone(skb, GFP_ATOMIC);
 		if (tx_skb == NULL) {
 			return;
 		}
-		
-		/* 
-		 *  Insert frame in store, in case of retransmissions 
+
+		/*
+		 *  Insert frame in store, in case of retransmissions
 		 */
 		skb_queue_tail(&self->wx_list, skb_get(skb));
-		
-		/*  
+
+		/*
 		 *  Set poll bit if necessary. We do this to the copied
 		 *  skb, since retransmitted need to set or clear the poll
-		 *  bit depending on when they are sent.  
+		 *  bit depending on when they are sent.
 		 */
 		tx_skb->data[1] |= PF_BIT;
-		
+
 		self->vs = (self->vs + 1) % 8;
 		self->ack_required = FALSE;
 
@@ -830,8 +830,8 @@
  *    Send I(nformation) frame as secondary with final bit set
  *
  */
-void irlap_send_data_secondary_final(struct irlap_cb *self, 
-				     struct sk_buff *skb) 
+void irlap_send_data_secondary_final(struct irlap_cb *self,
+				     struct sk_buff *skb)
 {
 	struct sk_buff *tx_skb = NULL;
 
@@ -842,26 +842,26 @@
 	/* Is this reliable or unreliable data? */
 	if (skb->data[1] == I_FRAME) {
 
-		/*  
+		/*
 		 *  Insert frame sequence number (Vs) in control field before
 		 *  inserting into transmit window queue.
 		 */
 		skb->data[1] = I_FRAME | (self->vs << 1);
-		
+
 		tx_skb = skb_clone(skb, GFP_ATOMIC);
 		if (tx_skb == NULL) {
 			return;
-		}		
+		}
 
 		/* Insert frame in store */
 		skb_queue_tail(&self->wx_list, skb_get(skb));
-		
+
 		tx_skb->data[1] |= PF_BIT;
-		
-		self->vs = (self->vs + 1) % 8; 
+
+		self->vs = (self->vs + 1) % 8;
 		self->ack_required = FALSE;
-		
-		irlap_send_i_frame(self, tx_skb, RSP_FRAME); 
+
+		irlap_send_i_frame(self, tx_skb, RSP_FRAME);
 	} else {
 		if (self->ack_required) {
 			irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
@@ -888,32 +888,32 @@
  *    Send I(nformation) frame as secondary without final bit set
  *
  */
-void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb) 
+void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb)
 {
 	struct sk_buff *tx_skb = NULL;
 
 	/* Is this reliable or unreliable data? */
 	if (skb->data[1] == I_FRAME) {
-		
-		/*  
+
+		/*
 		 *  Insert frame sequence number (Vs) in control field before
 		 *  inserting into transmit window queue.
 		 */
 		skb->data[1] = I_FRAME | (self->vs << 1);
-		
+
 		tx_skb = skb_clone(skb, GFP_ATOMIC);
 		if (tx_skb == NULL) {
 			return;
-		}		
-		
+		}
+
 		/* Insert frame in store */
 		skb_queue_tail(&self->wx_list, skb_get(skb));
-		
+
 		self->vs = (self->vs + 1) % 8;
-		self->ack_required = FALSE;		
+		self->ack_required = FALSE;
 		self->window -= 1;
 
-		irlap_send_i_frame(self, tx_skb, RSP_FRAME); 
+		irlap_send_i_frame(self, tx_skb, RSP_FRAME);
 	} else {
 		irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
 		self->window -= 1;
@@ -923,8 +923,8 @@
 /*
  * Function irlap_resend_rejected_frames (nr)
  *
- *    Resend frames which has not been acknowledged. Should be safe to 
- *    traverse the list without locking it since this function will only be 
+ *    Resend frames which has not been acknowledged. Should be safe to
+ *    traverse the list without locking it since this function will only be
  *    called from interrupt context (BH)
  */
 void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
@@ -946,8 +946,8 @@
 	while (skb != NULL) {
 		irlap_wait_min_turn_around(self, &self->qos_tx);
 
-		/* We copy the skb to be retransmitted since we will have to 
-		 * modify it. Cloning will confuse packet sniffers 
+		/* We copy the skb to be retransmitted since we will have to
+		 * modify it. Cloning will confuse packet sniffers
 		 */
 		/* tx_skb = skb_clone( skb, GFP_ATOMIC); */
 		tx_skb = skb_copy(skb, GFP_ATOMIC);
@@ -962,17 +962,17 @@
 		/* Clear old Nr field + poll bit */
 		tx_skb->data[1] &= 0x0f;
 
-		/* 
+		/*
 		 *  Set poll bit on the last frame retransmitted
 		 */
-	 	if (count-- == 1)
-	 		tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
+		if (count-- == 1)
+			tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
 		else
 			tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
-	      	
+
 		irlap_send_i_frame(self, tx_skb, command);
 
-		/* 
+		/*
 		 *  If our skb is the last buffer in the list, then
 		 *  we are finished, if not, move to the next sk-buffer
 		 */
@@ -982,23 +982,23 @@
 			skb = skb->next;
 	}
 #if 0 /* Not yet */
-	/* 
+	/*
 	 *  We can now fill the window with additinal data frames
 	 */
 	while (skb_queue_len( &self->txq) > 0) {
-		
+
 		IRDA_DEBUG(0, __FUNCTION__ "(), sending additional frames!\n");
-		if ((skb_queue_len( &self->txq) > 0) && 
+		if ((skb_queue_len( &self->txq) > 0) &&
 		    (self->window > 0)) {
-			skb = skb_dequeue( &self->txq); 
+			skb = skb_dequeue( &self->txq);
 			ASSERT(skb != NULL, return;);
 
 			/*
-			 *  If send window > 1 then send frame with pf 
+			 *  If send window > 1 then send frame with pf
 			 *  bit cleared
-			 */ 
-			if ((self->window > 1) && 
-			    skb_queue_len(&self->txq) > 0) 
+			 */
+			if ((self->window > 1) &&
+			    skb_queue_len(&self->txq) > 0)
 			{
 				irlap_send_data_primary(self, skb);
 			} else {
@@ -1026,14 +1026,14 @@
 	if (skb != NULL) {
 		irlap_wait_min_turn_around(self, &self->qos_tx);
 
-		/* We copy the skb to be retransmitted since we will have to 
-		 * modify it. Cloning will confuse packet sniffers 
+		/* We copy the skb to be retransmitted since we will have to
+		 * modify it. Cloning will confuse packet sniffers
 		 */
 		/* tx_skb = skb_clone( skb, GFP_ATOMIC); */
 		tx_skb = skb_copy(skb, GFP_ATOMIC);
 		if (!tx_skb) {
 			IRDA_DEBUG(0, __FUNCTION__ "(), unable to copy\n");
-			return;	
+			return;
 		}
 		/* Unlink tx_skb from list */
 		tx_skb->next = tx_skb->prev = NULL;
@@ -1044,7 +1044,7 @@
 
 		/*  Set poll/final bit */
 		tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
-	      	
+
 		irlap_send_i_frame(self, tx_skb, command);
 	}
 }
@@ -1055,15 +1055,15 @@
  *    Contruct and transmit an Unnumbered Information (UI) frame
  *
  */
-void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb, 
+void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
 			 __u8 caddr, int command)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 	ASSERT(skb != NULL, return;);
-	
+
 	/* Insert connection address */
 	skb->data[0] = caddr | ((command) ? CMD_FRAME : 0);
 
@@ -1075,13 +1075,13 @@
  *
  *    Contruct and transmit Information (I) frame
  */
-void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb, 
-			int command) 
+void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
+			int command)
 {
 	/* Insert connection address */
 	skb->data[0] = self->caddr;
 	skb->data[0] |= (command) ? CMD_FRAME : 0;
-	
+
 	/* Insert next to receive (Vr) */
 	skb->data[1] |= (self->vr << 5);  /* insert nr */
 
@@ -1094,9 +1094,9 @@
  *    Receive and parse an I (Information) frame, no harm in making it inline
  *    since it's called only from one single place (irlap_driver_rcv).
  */
-static inline void irlap_recv_i_frame(struct irlap_cb *self, 
-				      struct sk_buff *skb, 
-				      struct irlap_info *info, int command) 
+static inline void irlap_recv_i_frame(struct irlap_cb *self,
+				      struct sk_buff *skb,
+				      struct irlap_info *info, int command)
 {
 	info->nr = skb->data[1] >> 5;          /* Next to receive */
 	info->pf = skb->data[1] & PF_BIT;      /* Final bit */
@@ -1115,7 +1115,7 @@
  *    Receive and parse an Unnumbered Information (UI) frame
  *
  */
-static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb, 
+static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
 				struct irlap_info *info)
 {
 	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
@@ -1131,19 +1131,19 @@
  *    Received Frame Reject response.
  *
  */
-static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb, 
-				  struct irlap_info *info) 
+static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb,
+				  struct irlap_info *info)
 {
 	__u8 *frame;
 	int w, x, y, z;
 
 	IRDA_DEBUG(0, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 	ASSERT(skb != NULL, return;);
 	ASSERT(info != NULL, return;);
-	
+
 	frame = skb->data;
 
 	info->nr = frame[2] >> 5;          /* Next to receive */
@@ -1154,11 +1154,11 @@
 	x = frame[3] & 0x02;
 	y = frame[3] & 0x04;
 	z = frame[3] & 0x08;
-	
+
 	if (w) {
 		IRDA_DEBUG(0, "Rejected control field is undefined or not "
 		      "implemented.\n");
-	} 
+	}
 	if (x) {
 		IRDA_DEBUG(0, "Rejected control field was invalid because it "
 		      "contained a non permitted I field.\n");
@@ -1181,7 +1181,7 @@
  *    Send a test frame response
  *
  */
-void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, 
+void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
 			   struct sk_buff *cmd)
 {
 	struct sk_buff *skb;
@@ -1194,7 +1194,7 @@
 
 	/* Broadcast frames must include saddr and daddr fields */
 	if (caddr == CBROADCAST) {
-		frame = (struct test_frame *) 
+		frame = (struct test_frame *)
 			skb_put(skb, sizeof(struct test_frame));
 
 		/* Insert the swapped addresses */
@@ -1221,29 +1221,29 @@
  *    Receive a test frame
  *
  */
-static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb, 
+static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
 				  struct irlap_info *info, int command)
 {
 	struct test_frame *frame;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
-	
+
 	frame = (struct test_frame *) skb->data;
-		
+
 	/* Broadcast frames must carry saddr and daddr fields */
 	if (info->caddr == CBROADCAST) {
 		if (skb->len < sizeof(struct test_frame)) {
-			IRDA_DEBUG(0, __FUNCTION__ 
+			IRDA_DEBUG(0, __FUNCTION__
 				   "() test frame to short!\n");
 			return;
 		}
-		
+
 		/* Read and swap addresses */
 		info->daddr = le32_to_cpu(frame->saddr);
 		info->saddr = le32_to_cpu(frame->daddr);
 
 		/* Make sure frame is addressed to us */
-		if ((info->saddr != self->saddr) && 
+		if ((info->saddr != self->saddr) &&
 		    (info->saddr != BROADCAST)) {
 			return;
 		}
@@ -1258,18 +1258,18 @@
 /*
  * Function irlap_driver_rcv (skb, netdev, ptype)
  *
- *    Called when a frame is received. Dispatches the right receive function 
+ *    Called when a frame is received. Dispatches the right receive function
  *    for processing of the frame.
  *
  */
-int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, 
+int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
 		     struct packet_type *ptype)
 {
 	struct irlap_info info;
 	struct irlap_cb *self;
 	int command;
 	__u8 control;
-	
+
 	/* FIXME: should we get our own field? */
 	self = (struct irlap_cb *) dev->atalk_ptr;
 
@@ -1281,14 +1281,14 @@
 
 	/* Check if frame is large enough for parsing */
 	if (skb->len < 2) {
-		ERROR(__FUNCTION__ "(), frame to short!\n");
+		ERROR("%s: frame to short!\n", __FUNCTION__);
 		dev_kfree_skb(skb);
 		return -1;
 	}
-	
+
 	command    = skb->data[0] & CMD_FRAME;
 	info.caddr = skb->data[0] & CBROADCAST;
-	
+
 	info.pf      = skb->data[1] &  PF_BIT;
 	info.control = skb->data[1] & ~PF_BIT; /* Mask away poll/final bit */
 
@@ -1299,7 +1299,7 @@
 		IRDA_DEBUG(0, __FUNCTION__ "(), wrong connection address!\n");
 		goto out;
 	}
-	/*  
+	/*
 	 *  Optimize for the common case and check if the frame is an
 	 *  I(nformation) frame. Only I-frames have bit 0 set to 0
 	 */
@@ -1308,11 +1308,11 @@
 		goto out;
 	}
 	/*
-	 *  We now check is the frame is an S(upervisory) frame. Only 
+	 *  We now check is the frame is an S(upervisory) frame. Only
 	 *  S-frames have bit 0 set to 1 and bit 1 set to 0
 	 */
 	if (~control & 0x02) {
-		/* 
+		/*
 		 *  Received S(upervisory) frame, check which frame type it is
 		 *  only the first nibble is of interest
 		 */
@@ -1330,15 +1330,14 @@
 			irlap_recv_srej_frame(self, skb, &info, command);
 			break;
 		default:
-			WARNING(__FUNCTION__ 
-				"() Unknown S-frame %02x received!\n",
-				info.control);
+			WARNING("%s: Unknown S-frame %02x received!\n",
+				__FUNCTION__, info.control);
 			break;
 		}
 		goto out;
 	}
-	/* 
-	 *  This must be a C(ontrol) frame 
+	/*
+	 *  This must be a C(ontrol) frame
 	 */
 	switch (control) {
 	case XID_RSP:
@@ -1369,11 +1368,11 @@
 		irlap_recv_ui_frame(self, skb, &info);
 		break;
 	default:
-		WARNING(__FUNCTION__ "(), Unknown frame %02x received!\n", 
-			info.control);
+		WARNING("%s: Unknown frame %02x received!\n",
+				__FUNCTION__, info.control);
 		break;
 	}
 out:
-	dev_kfree_skb(skb); 
+	dev_kfree_skb(skb);
 	return 0;
 }
diff -Nru a/net/irda/irlmp.c b/net/irda/irlmp.c
--- a/net/irda/irlmp.c	Sun Jun 16 19:31:41 2002
+++ b/net/irda/irlmp.c	Sun Jun 16 19:31:41 2002
@@ -1,25 +1,25 @@
 /*********************************************************************
- *                
+ *
  * Filename:      irlmp.c
  * Version:       1.0
- * Description:   IrDA Link Management Protocol (LMP) layer                 
+ * Description:   IrDA Link Management Protocol (LMP) layer
  * Status:        Stable.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 17 20:54:32 1997
  * Modified at:   Wed Jan  5 11:26:03 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
+ *
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
  *     All Rights Reserved.
  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
  ********************************************************************/
@@ -82,7 +82,7 @@
 	if (irlmp == NULL)
 		return -ENOMEM;
 	memset(irlmp, 0, sizeof(struct irlmp_cb));
-	
+
 	irlmp->magic = LMP_MAGIC;
 	spin_lock_init(&irlmp->log_lock);
 
@@ -91,13 +91,13 @@
 	irlmp->links = hashbin_new(HB_GLOBAL);
 	irlmp->unconnected_lsaps = hashbin_new(HB_GLOBAL);
 	irlmp->cachelog = hashbin_new(HB_GLOBAL);
-	
+
 	irlmp->free_lsap_sel = 0x10; /* Reserved 0x00-0x0f */
 	strcpy(sysctl_devname, "Linux");
-	
+
 	/* Do discovery every 3 seconds */
 	init_timer(&irlmp->discovery_timer);
-   	irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ);
+	irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ);
 
 	return 0;
 }
@@ -108,20 +108,20 @@
  *    Remove IrLMP layer
  *
  */
-void irlmp_cleanup(void) 
+void irlmp_cleanup(void)
 {
 	/* Check for main structure */
 	ASSERT(irlmp != NULL, return;);
 	ASSERT(irlmp->magic == LMP_MAGIC, return;);
 
 	del_timer(&irlmp->discovery_timer);
-	
+
 	hashbin_delete(irlmp->links, (FREE_FUNC) kfree);
 	hashbin_delete(irlmp->unconnected_lsaps, (FREE_FUNC) kfree);
 	hashbin_delete(irlmp->clients, (FREE_FUNC) kfree);
 	hashbin_delete(irlmp->services, (FREE_FUNC) kfree);
 	hashbin_delete(irlmp->cachelog, (FREE_FUNC) kfree);
-	
+
 	/* De-allocate main structure */
 	kfree(irlmp);
 	irlmp = NULL;
@@ -152,11 +152,11 @@
 	/* Allocate new instance of a LSAP connection */
 	self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
 	if (self == NULL) {
-		ERROR(__FUNCTION__ "(), can't allocate memory");
+		ERROR("%s: can't allocate memory", __FUNCTION__);
 		return NULL;
 	}
 	memset(self, 0, sizeof(struct lsap_cb));
-	
+
 	self->magic = LMP_LSAP_MAGIC;
 	self->slsap_sel = slsap_sel;
 
@@ -176,11 +176,11 @@
 	self->notify = *notify;
 
 	self->lsap_state = LSAP_DISCONNECTED;
-	
+
 	/* Insert into queue of unconnected LSAPs */
 	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, 
 		       NULL);
-	
+
 	return self;
 }
 
@@ -247,11 +247,11 @@
 	self->lap = NULL;
 	/* Check if we found the LSAP! If not then try the unconnected lsaps */
 	if (!lsap) {
-		lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, 
+		lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self,
 				      NULL);
 	}
 	if (!lsap) {
-		IRDA_DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__
 		     "(), Looks like somebody has removed me already!\n");
 		return;
 	}
@@ -278,11 +278,11 @@
 	 */
 	lap = kmalloc(sizeof(struct lap_cb), GFP_KERNEL);
 	if (lap == NULL) {
-		ERROR(__FUNCTION__ "(), unable to kmalloc\n");
+		ERROR("%s: unable to kmalloc\n", __FUNCTION__);
 		return;
 	}
 	memset(lap, 0, sizeof(struct lap_cb));
-	
+
 	lap->irlap = irlap;
 	lap->magic = LMP_LAP_MAGIC;
 	lap->saddr = saddr;
@@ -293,7 +293,7 @@
 #endif
 
 	lap->lap_state = LAP_STANDBY;
-	
+
 	init_timer(&lap->idle_timer);
 
 	/*
@@ -301,9 +301,9 @@
 	 */
 	hashbin_insert(irlmp->links, (irda_queue_t *) lap, lap->saddr, NULL);
 
-	/* 
+	/*
 	 *  We set only this variable so IrLAP can tell us on which link the
-	 *  different events happened on 
+	 *  different events happened on
 	 */
 	irda_notify_init(notify);
 	notify->instance = lap;
@@ -328,7 +328,7 @@
 		/* Remove all discoveries discovered at this link */
 		irlmp_expire_discoveries(irlmp->cachelog, link->saddr, TRUE);
 
-		del_timer(&link->idle_timer);	
+		del_timer(&link->idle_timer);
 
 		link->magic = 0;
 		kfree(link);
@@ -338,12 +338,12 @@
 /*
  * Function irlmp_connect_request (handle, dlsap, userdata)
  *
- *    Connect with a peer LSAP  
+ *    Connect with a peer LSAP
  *
  */
-int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, 
-			  __u32 saddr, __u32 daddr, 
-			  struct qos_info *qos, struct sk_buff *userdata) 
+int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
+			  __u32 saddr, __u32 daddr,
+			  struct qos_info *qos, struct sk_buff *userdata)
 {
 	struct sk_buff *skb = NULL;
 	struct lap_cb *lap;
@@ -352,18 +352,18 @@
 
 	ASSERT(self != NULL, return -EBADR;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -EBADR;);
-	
-	IRDA_DEBUG(2, __FUNCTION__ 
-	      "(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n", 
+
+	IRDA_DEBUG(2, __FUNCTION__
+	      "(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n",
 	      self->slsap_sel, dlsap_sel, saddr, daddr);
-	
+
 	if (test_bit(0, &self->connected))
 		return -EISCONN;
-	
+
 	/* Client must supply destination device address */
 	if (!daddr)
 		return -EINVAL;
-	
+
 	/* Any userdata? */
 	if (userdata == NULL) {
 		skb = dev_alloc_skb(64);
@@ -373,27 +373,27 @@
 		skb_reserve(skb, LMP_MAX_HEADER);
 	} else
 		skb = userdata;
-	
+
 	/* Make room for MUX control header (3 bytes) */
 	ASSERT(skb_headroom(skb) >= LMP_CONTROL_HEADER, return -1;);
 	skb_push(skb, LMP_CONTROL_HEADER);
 
 	self->dlsap_sel = dlsap_sel;
-	
-	/*  
+
+	/*
 	 * Find the link to where we should try to connect since there may
 	 * be more than one IrDA port on this machine. If the client has
 	 * passed us the saddr (and already knows which link to use), then
 	 * we use that to find the link, if not then we have to look in the
 	 * discovery log and check if any of the links has discovered a
-	 * device with the given daddr 
+	 * device with the given daddr
 	 */
 	if ((!saddr) || (saddr == DEV_ADDR_ANY)) {
 		if (daddr != DEV_ADDR_ANY)
 			discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
 		else {
 			IRDA_DEBUG(2, __FUNCTION__ "(), no daddr\n");
-			discovery = (discovery_t *) 
+			discovery = (discovery_t *)
 				hashbin_get_first(irlmp->cachelog);
 		}
 
@@ -402,7 +402,7 @@
 			daddr = discovery->daddr;
 		}
 	}
-	lap = hashbin_find(irlmp->links, saddr, NULL);	
+	lap = hashbin_find(irlmp->links, saddr, NULL);
 	if (lap == NULL) {
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to find a usable link!\n");
 		return -EHOSTUNREACH;
@@ -433,9 +433,9 @@
 
 	self->lap = lap;
 
-	/* 
-	 *  Remove LSAP from list of unconnected LSAPs and insert it into the 
-	 *  list of connected LSAPs for the particular link 
+	/*
+	 *  Remove LSAP from list of unconnected LSAPs and insert it into the
+	 *  list of connected LSAPs for the particular link
 	 */
 	lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, NULL);
 
@@ -447,13 +447,13 @@
 	hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, NULL);
 
 	set_bit(0, &self->connected);	/* TRUE */
-	
+
 	/*
 	 *  User supplied qos specifications?
 	 */
 	if (qos)
 		self->qos = *qos;
-	
+
 	irlmp_do_lsap_event(self, LM_CONNECT_REQUEST, skb);
 
 	return 0;
@@ -465,18 +465,18 @@
  *    Incoming connection
  *
  */
-void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb) 
+void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb)
 {
 	int max_seg_size;
 	int lap_header_size;
 	int max_header_size;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
 	ASSERT(skb != NULL, return;);
 	ASSERT(self->lap != NULL, return;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
+	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",
 		   self->slsap_sel, self->dlsap_sel);
 
 	/* Note : self->lap is set in irlmp_link_data_indication(),
@@ -492,10 +492,10 @@
 
 	/* Hide LMP_CONTROL_HEADER header from layer above */
 	skb_pull(skb, LMP_CONTROL_HEADER);
-	
+
 	if (self->notify.connect_indication)
-		self->notify.connect_indication(self->notify.instance, self, 
-						&self->qos, max_seg_size, 
+		self->notify.connect_indication(self->notify.instance, self,
+						&self->qos, max_seg_size,
 						max_header_size, skb);
 	else
 		dev_kfree_skb(skb);
@@ -507,7 +507,7 @@
  *    Service user is accepting connection
  *
  */
-int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata) 
+int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata)
 {
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
@@ -515,13 +515,13 @@
 
 	set_bit(0, &self->connected);	/* TRUE */
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
+	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",
 		   self->slsap_sel, self->dlsap_sel);
 
 	/* Make room for MUX control header (3 bytes) */
 	ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return -1;);
 	skb_push(userdata, LMP_CONTROL_HEADER);
-	
+
 	irlmp_do_lsap_event(self, LM_CONNECT_RESPONSE, userdata);
 
 	return 0;
@@ -532,26 +532,26 @@
  *
  *    LSAP connection confirmed peer device!
  */
-void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb) 
+void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb)
 {
 	int max_header_size;
 	int lap_header_size;
 	int max_seg_size;
 
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
-	
+
 	ASSERT(skb != NULL, return;);
 	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);	
+	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
 	ASSERT(self->lap != NULL, return;);
 
 	self->qos = *self->lap->qos;
 
 	max_seg_size    = self->lap->qos->data_size.value-LMP_HEADER;
-	lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);	
+	lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);
 	max_header_size = LMP_HEADER + lap_header_size;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", 
+	IRDA_DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n",
 		   max_header_size);
 
 	/* Hide LMP_CONTROL_HEADER header from layer above */
@@ -572,7 +572,7 @@
  *    new LSAP so it can keep listening on the old one.
  *
  */
-struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) 
+struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance)
 {
 	struct lsap_cb *new;
 
@@ -595,8 +595,8 @@
 	/* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */
 
 	init_timer(&new->watchdog_timer);
-	
-	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new, (int) new, 
+
+	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new, (int) new,
 		       NULL);
 
 	/* Make sure that we invalidate the cache */
@@ -610,10 +610,10 @@
 /*
  * Function irlmp_disconnect_request (handle, userdata)
  *
- *    The service user is requesting disconnection, this will not remove the 
+ *    The service user is requesting disconnection, this will not remove the
  *    LSAP, but only mark it as disconnected
  */
-int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata) 
+int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
 {
 	struct lsap_cb *lsap;
 
@@ -633,13 +633,13 @@
 
 	skb_push(userdata, LMP_CONTROL_HEADER);
 
-	/* 
+	/*
 	 *  Do the event before the other stuff since we must know
 	 *  which lap layer that the frame should be transmitted on
 	 */
 	irlmp_do_lsap_event(self, LM_DISCONNECT_REQUEST, userdata);
 
-	/* 
+	/*
 	 *  Remove LSAP from list of connected LSAPs for the particular link
 	 *  and insert it into the list of unconnected LSAPs
 	 */
@@ -653,13 +653,13 @@
 	ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
 	ASSERT(lsap == self, return -1;);
 
-	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, 
+	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self,
 		       NULL);
-	
+
 	/* Reset some values */
 	self->dlsap_sel = LSAP_ANY;
 	self->lap = NULL;
-	
+
 	return 0;
 }
 
@@ -668,8 +668,8 @@
  *
  *    LSAP is being closed!
  */
-void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, 
-				 struct sk_buff *userdata) 
+void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
+				 struct sk_buff *userdata)
 {
 	struct lsap_cb *lsap;
 
@@ -677,7 +677,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
 
-	IRDA_DEBUG(3, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
+	IRDA_DEBUG(3, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",
 		   self->slsap_sel, self->dlsap_sel);
 
 	/* Already disconnected ?
@@ -691,12 +691,12 @@
 		return;
 	}
 
-	/* 
-	 *  Remove association between this LSAP and the link it used 
+	/*
+	 *  Remove association between this LSAP and the link it used
 	 */
 	ASSERT(self->lap != NULL, return;);
 	ASSERT(self->lap->lsaps != NULL, return;);
-	
+
 	lsap = hashbin_remove(self->lap->lsaps, (int) self, NULL);
 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
 	self->lap->cache.valid = FALSE;
@@ -704,17 +704,17 @@
 
 	ASSERT(lsap != NULL, return;);
 	ASSERT(lsap == self, return;);
-	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap, (int) lsap, 
+	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap, (int) lsap,
 		       NULL);
 
 	self->dlsap_sel = LSAP_ANY;
 	self->lap = NULL;
-	
+
 	/*
 	 *  Inform service user
 	 */
 	if (self->notify.disconnect_indication)
-		self->notify.disconnect_indication(self->notify.instance, 
+		self->notify.disconnect_indication(self->notify.instance,
 						   self, reason, userdata);
 	else {
 		IRDA_DEBUG(0, __FUNCTION__ "(), no handler\n");
@@ -747,7 +747,7 @@
 	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
 	while (lap != NULL) {
 		ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
-		
+
 		if (lap->lap_state == LAP_STANDBY) {
 			/* Expire discoveries discovered on this link */
 			irlmp_expire_discoveries(irlmp->cachelog, lap->saddr,
@@ -770,35 +770,35 @@
 
 	/* Make sure the value is sane */
 	if ((nslots != 1) && (nslots != 6) && (nslots != 8) && (nslots != 16)){
-		WARNING(__FUNCTION__ 
-		       "(), invalid value for number of slots!\n");
+		WARNING("%s: invalid value for number of slots!\n",
+				__FUNCTION__);
 		nslots = sysctl_discovery_slots = 8;
 	}
 
 	/* Construct new discovery info to be used by IrLAP, */
 	irlmp->discovery_cmd.hints.word = irlmp->hints.word;
-	
-	/* 
-	 *  Set character set for device name (we use ASCII), and 
-	 *  copy device name. Remember to make room for a \0 at the 
+
+	/*
+	 *  Set character set for device name (we use ASCII), and
+	 *  copy device name. Remember to make room for a \0 at the
 	 *  end
 	 */
 	irlmp->discovery_cmd.charset = CS_ASCII;
-	strncpy(irlmp->discovery_cmd.nickname, sysctl_devname, 
+	strncpy(irlmp->discovery_cmd.nickname, sysctl_devname,
 		NICKNAME_MAX_LEN);
 	irlmp->discovery_cmd.name_len = strlen(irlmp->discovery_cmd.nickname);
 	irlmp->discovery_cmd.nslots = nslots;
-	
+
 	/*
 	 * Try to send discovery packets on all links
 	 */
 	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
 	while (lap != NULL) {
 		ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
-		
+
 		if (lap->lap_state == LAP_STANDBY) {
 			/* Try to discover */
-			irlmp_do_lap_event(lap, LM_LAP_DISCOVERY_REQUEST, 
+			irlmp_do_lap_event(lap, LM_LAP_DISCOVERY_REQUEST,
 					   NULL);
 		}
 		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
@@ -816,9 +816,9 @@
 	/* Return current cached discovery log */
 	irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_LOG);
 
-	/* 
+	/*
 	 * Start a single discovery operation if discovery is not already
-         * running 
+         * running
 	 */
 	if (!sysctl_discovery) {
 		/* Check if user wants to override the default */
@@ -864,9 +864,6 @@
 #if 0
 /*
  * Function irlmp_check_services (discovery)
- *
- *    
- *
  */
 void irlmp_check_services(discovery_t *discovery)
 {
@@ -896,7 +893,7 @@
 			/* Don't notify about the ANY service */
 			if (service == S_ANY)
 				continue;
-			/*  
+			/*
 			 * Found no clients for dealing with this service,
 			 */
 		}
@@ -923,20 +920,20 @@
 	discovery_t *discovery;
 
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
-	
+
 	/* Check if client wants or not partial/selective log (optimisation) */
 	if (!client->disco_callback)
 		return;
 
-	/* 
-	 * Now, check all discovered devices (if any), and notify client 
-	 * only about the services that the client is interested in 
+	/*
+	 * Now, check all discovered devices (if any), and notify client
+	 * only about the services that the client is interested in
 	 */
 	discovery = (discovery_t *) hashbin_get_first(log);
 	while (discovery != NULL) {
-		IRDA_DEBUG(3, "discovery->daddr = 0x%08x\n", discovery->daddr); 
-		
-		/* 
+		IRDA_DEBUG(3, "discovery->daddr = 0x%08x\n", discovery->daddr);
+
+		/*
 		 * Any common hint bits? Remember to mask away the extension
 		 * bits ;-)
 		 */
@@ -952,24 +949,24 @@
  *
  *    Some device(s) answered to our discovery request! Check to see which
  *    device it is, and give indication to the client(s)
- * 
+ *
  */
-void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode) 
+void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode)
 {
 	irlmp_client_t *client;
-	
+
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
-	
+
 	ASSERT(log != NULL, return;);
-	
+
 	if (!(HASHBIN_GET_SIZE(log)))
 		return;
-	
+
 	client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
 	while (client != NULL) {
 		/* Check if we should notify client */
 		irlmp_notify_client(client, log, mode);
-			
+
 		client = (irlmp_client_t *) hashbin_get_next(irlmp->clients);
 	}
 }
@@ -980,19 +977,19 @@
  *	This device is no longer been discovered, and therefore it is beeing
  *	purged from the discovery log. Inform all clients who have
  *	registered for this event...
- * 
+ *
  *	Note : called exclusively from discovery.c
  *	Note : as we are currently processing the log, the clients callback
  *	should *NOT* attempt to touch the log now.
  */
-void irlmp_discovery_expiry(discovery_t *expiry) 
+void irlmp_discovery_expiry(discovery_t *expiry)
 {
 	irlmp_client_t *client;
-	
+
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
 
 	ASSERT(expiry != NULL, return;);
-	
+
 	client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
 	while (client != NULL) {
 		/* Check if we should notify client */
@@ -1020,14 +1017,14 @@
 
 	irlmp->discovery_rsp.hints.word = irlmp->hints.word;
 
-	/* 
-	 *  Set character set for device name (we use ASCII), and 
-	 *  copy device name. Remember to make room for a \0 at the 
+	/*
+	 *  Set character set for device name (we use ASCII), and
+	 *  copy device name. Remember to make room for a \0 at the
 	 *  end
 	 */
 	irlmp->discovery_rsp.charset = CS_ASCII;
 
-	strncpy(irlmp->discovery_rsp.nickname, sysctl_devname, 
+	strncpy(irlmp->discovery_rsp.nickname, sysctl_devname,
 		NICKNAME_MAX_LEN);
 	irlmp->discovery_rsp.name_len = strlen(irlmp->discovery_rsp.nickname);
 
@@ -1040,15 +1037,15 @@
  *    Send some data to peer device
  *
  */
-int irlmp_data_request(struct lsap_cb *self, struct sk_buff *skb) 
+int irlmp_data_request(struct lsap_cb *self, struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
-	
+
 	/* Make room for MUX header */
 	ASSERT(skb_headroom(skb) >= LMP_HEADER, return -1;);
 	skb_push(skb, LMP_HEADER);
-	
+
 	return irlmp_do_lsap_event(self, LM_DATA_REQUEST, skb);
 }
 
@@ -1058,7 +1055,7 @@
  *    Got data from LAP layer so pass it up to upper layer
  *
  */
-void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb) 
+void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb)
 {
 	/* Hide LMP header from layer above */
 	skb_pull(skb, LMP_HEADER);
@@ -1071,16 +1068,13 @@
 
 /*
  * Function irlmp_udata_request (self, skb)
- *
- *    
- *
  */
-int irlmp_udata_request(struct lsap_cb *self, struct sk_buff *skb) 
+int irlmp_udata_request(struct lsap_cb *self, struct sk_buff *skb)
 {
- 	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(skb != NULL, return -1;);
-	
+
 	/* Make room for MUX header */
 	ASSERT(skb_headroom(skb) >= LMP_HEADER, return -1;);
 	skb_push(skb, LMP_HEADER);
@@ -1094,9 +1088,9 @@
  *    Send unreliable data (but still within the connection)
  *
  */
-void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb) 
+void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb)
 {
- 	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
@@ -1106,7 +1100,7 @@
 	skb_pull(skb, LMP_HEADER);
 
 	if (self->notify.udata_indication)
-		self->notify.udata_indication(self->notify.instance, self, 
+		self->notify.udata_indication(self->notify.instance, self,
 					      skb);
 	else
 		dev_kfree_skb(skb);
@@ -1114,23 +1108,20 @@
 
 /*
  * Function irlmp_connless_data_request (self, skb)
- *
- *    
- *
  */
 #ifdef CONFIG_IRDA_ULTRA
-int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *skb) 
+int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *skb)
 {
 	struct sk_buff *clone_skb;
 	struct lap_cb *lap;
 
- 	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(skb != NULL, return -1;);
-	
+
 	/* Make room for MUX and PID header */
 	ASSERT(skb_headroom(skb) >= LMP_HEADER+LMP_PID_HEADER, return -1;);
-	
+
 	/* Insert protocol identifier */
 	skb_push(skb, LMP_PID_HEADER);
 	skb->data[0] = self->pid;
@@ -1149,7 +1140,7 @@
 			return -ENOMEM;
 
 		irlap_unitdata_request(lap->irlap, clone_skb);
-		
+
 		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
 	}
 	dev_kfree_skb(skb);
@@ -1165,9 +1156,9 @@
  *
  */
 #ifdef CONFIG_IRDA_ULTRA
-void irlmp_connless_data_indication(struct lsap_cb *self, struct sk_buff *skb) 
+void irlmp_connless_data_indication(struct lsap_cb *self, struct sk_buff *skb)
 {
- 	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
@@ -1184,7 +1175,7 @@
 }
 #endif /* CONFIG_IRDA_ULTRA */
 
-void irlmp_status_request(void) 
+void irlmp_status_request(void)
 {
 	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
@@ -1197,7 +1188,7 @@
  * Jean II
  */
 void irlmp_status_indication(struct lap_cb *self,
-			     LINK_STATUS link, LOCK_STATUS lock) 
+			     LINK_STATUS link, LOCK_STATUS lock)
 {
 	struct lsap_cb *next;
 	struct lsap_cb *curr;
@@ -1213,7 +1204,7 @@
 		 *  Inform service user if he has requested it
 		 */
 		if (curr->notify.status_indication != NULL)
-			curr->notify.status_indication(curr->notify.instance, 
+			curr->notify.status_indication(curr->notify.instance,
 						       link, lock);
 		else
 			IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n");
@@ -1279,7 +1270,7 @@
 
 		/* Inform lsap user that it can send one more packet. */
 		if (curr->notify.flow_indication != NULL)
-			curr->notify.flow_indication(curr->notify.instance, 
+			curr->notify.flow_indication(curr->notify.instance,
 						     curr, flow);
 		else
 			IRDA_DEBUG(1, __FUNCTION__ "(), no handler\n");
@@ -1297,8 +1288,8 @@
 	__u8 *service;
 	int i = 0;
 
-	/* 
-	 * Allocate array to store services in. 16 entries should be safe 
+	/*
+	 * Allocate array to store services in. 16 entries should be safe
 	 * since we currently only support 2 hint bytes
 	 */
 	service = kmalloc(16, GFP_ATOMIC);
@@ -1327,10 +1318,10 @@
 	if (hint[0] & HINT_FAX)
 		IRDA_DEBUG(1, "Fax ");
 	if (hint[0] & HINT_LAN) {
-		IRDA_DEBUG(1, "LAN Access ");		
+		IRDA_DEBUG(1, "LAN Access ");
 		service[i++] = S_LAN;
 	}
-	/* 
+	/*
 	 *  Test if extension byte exists. This byte will usually be
 	 *  there, but this is not really required by the standard.
 	 *  (IrLMP p. 29)
@@ -1341,7 +1332,7 @@
 			service[i++] = S_TELEPHONY;
 		} if (hint[1] & HINT_FILE_SERVER)
 			IRDA_DEBUG(1, "File Server ");
-		
+
 		if (hint[1] & HINT_COMM) {
 			IRDA_DEBUG(1, "IrCOMM ");
 			service[i++] = S_COMM;
@@ -1357,7 +1348,7 @@
 	service[i++] = S_ANY;
 
 	service[i] = S_END;
-	
+
 	return service;
 }
 
@@ -1436,7 +1427,7 @@
 	irlmp->hints.word |= hints;
 
 	/* Make a new registration */
- 	service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC);
+	service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC);
 	if (!service) {
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n");
 		return 0;
@@ -1450,19 +1441,19 @@
 /*
  * Function irlmp_unregister_service (handle)
  *
- *    Unregister service with IrLMP. 
+ *    Unregister service with IrLMP.
  *
  *    Returns: 0 on success, -1 on error
  */
 int irlmp_unregister_service(__u32 handle)
 {
 	irlmp_service_t *service;
-		
- 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	if (!handle)
 		return -1;
- 
+
 	service = hashbin_find(irlmp->services, handle, NULL);
 	if (!service) {
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown service!\n");
@@ -1503,14 +1494,14 @@
 
 	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 	ASSERT(irlmp != NULL, return 0;);
-	
+
 	/* Get a unique handle for this client */
 	get_random_bytes(&handle, sizeof(handle));
 	while (hashbin_find(irlmp->clients, handle, NULL) || !handle)
 		get_random_bytes(&handle, sizeof(handle));
 
 	/* Make a new registration */
- 	client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC);
+	client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC);
 	if (!client) {
 		IRDA_DEBUG( 1, __FUNCTION__ "(), Unable to kmalloc!\n");
 		return 0;
@@ -1522,7 +1513,7 @@
 	client->expir_callback = expir_clb;
 	client->priv = priv;
 
- 	hashbin_insert(irlmp->clients, (irda_queue_t *) client, handle, NULL);
+	hashbin_insert(irlmp->clients, (irda_queue_t *) client, handle, NULL);
 
 	return handle;
 }
@@ -1535,8 +1526,8 @@
  *
  *    Returns: 0 on success, -1 on error
  */
-int irlmp_update_client(__u32 handle, __u16 hint_mask, 
-			DISCOVERY_CALLBACK1 disco_clb, 
+int irlmp_update_client(__u32 handle, __u16 hint_mask,
+			DISCOVERY_CALLBACK1 disco_clb,
 			DISCOVERY_CALLBACK1 expir_clb, void *priv)
 {
 	irlmp_client_t *client;
@@ -1554,7 +1545,7 @@
 	client->disco_callback = disco_clb;
 	client->expir_callback = expir_clb;
 	client->priv = priv;
-	
+
 	return 0;
 }
 
@@ -1566,13 +1557,13 @@
  */
 int irlmp_unregister_client(__u32 handle)
 {
- 	struct irlmp_client *client;
- 
- 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	struct irlmp_client *client;
+
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	if (!handle)
 		return -1;
- 
+
 	client = hashbin_find(irlmp->clients, handle, NULL);
 	if (!client) {
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n");
@@ -1583,7 +1574,7 @@
 	client = hashbin_remove( irlmp->clients, handle, NULL);
 	if (client)
 		kfree(client);
-	
+
 	return 0;
 }
 
@@ -1628,13 +1619,13 @@
 
 			if ((self->slsap_sel == slsap_sel)) {
 				IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n",
-				      self->slsap_sel); 
+				      self->slsap_sel);
 				return TRUE;
 			}
 			self = (struct lsap_cb*) hashbin_get_next(lap->lsaps);
 		}
 		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
-	}     
+	}
 	return FALSE;
 }
 
@@ -1644,16 +1635,16 @@
  *    Find a free source LSAP to use. This function is called if the service
  *    user has requested a source LSAP equal to LM_ANY
  */
-__u8 irlmp_find_free_slsap(void) 
+__u8 irlmp_find_free_slsap(void)
 {
 	__u8 lsap_sel;
 	int wrapped = 0;
 
 	ASSERT(irlmp != NULL, return -1;);
 	ASSERT(irlmp->magic == LMP_MAGIC, return -1;);
-      
+
 	lsap_sel = irlmp->free_lsap_sel++;
-	
+
 	/* Check if the new free lsap is really free */
 	while (irlmp_slsap_inuse(irlmp->free_lsap_sel)) {
 		irlmp->free_lsap_sel++;
@@ -1668,7 +1659,7 @@
 		}
 	}
 	IRDA_DEBUG(4, __FUNCTION__ "(), next free lsap_sel=%02x\n", lsap_sel);
-	
+
 	return lsap_sel;
 }
 
@@ -1683,7 +1674,7 @@
 {
 	int reason = LM_LAP_DISCONNECT;
 
-	switch (lap_reason) {		
+	switch (lap_reason) {
 	case LAP_DISC_INDICATION: /* Received a disconnect request from peer */
 		IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_DISC_INDICATION\n");
 		reason = LM_USER_REQUEST;
@@ -1703,14 +1694,14 @@
 		reason = LM_CONNECT_FAILURE;
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ 
+		IRDA_DEBUG(1, __FUNCTION__
 		      "(), Unknow IrLAP disconnect reason %d!\n", lap_reason);
 		reason = LM_LAP_DISCONNECT;
 		break;
 	}
 
 	return reason;
-}	
+}
 
 __u32 irlmp_get_saddr(struct lsap_cb *self)
 {
@@ -1724,7 +1715,7 @@
 {
 	ASSERT(self != NULL, return 0;);
 	ASSERT(self->lap != NULL, return 0;);
-	
+
 	return self->lap->daddr;
 }
 
@@ -1742,37 +1733,37 @@
 	unsigned long flags;
 
 	ASSERT(irlmp != NULL, return 0;);
-	
+
 	save_flags( flags);
 	cli();
 
 	len = 0;
-	
+
 	len += sprintf( buf+len, "Unconnected LSAPs:\n");
 	self = (struct lsap_cb *) hashbin_get_first( irlmp->unconnected_lsaps);
 	while (self != NULL) {
 		ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
-		len += sprintf(buf+len, "lsap state: %s, ", 
+		len += sprintf(buf+len, "lsap state: %s, ",
 			       irlsap_state[ self->lsap_state]);
-		len += sprintf(buf+len, 
+		len += sprintf(buf+len,
 			       "slsap_sel: %#02x, dlsap_sel: %#02x, ",
-			       self->slsap_sel, self->dlsap_sel); 
+			       self->slsap_sel, self->dlsap_sel);
 		len += sprintf(buf+len, "(%s)", self->notify.name);
 		len += sprintf(buf+len, "\n");
 
 		self = (struct lsap_cb *) hashbin_get_next(
 			irlmp->unconnected_lsaps);
- 	} 
+	}
 
 	len += sprintf(buf+len, "\nRegistred Link Layers:\n");
 
 	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
 	while (lap != NULL) {
-		len += sprintf(buf+len, "lap state: %s, ", 
+		len += sprintf(buf+len, "lap state: %s, ",
 			       irlmp_state[lap->lap_state]);
 
 		len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
-			       lap->saddr, lap->daddr); 
+			       lap->saddr, lap->daddr);
 		len += sprintf(buf+len, "num lsaps: %d",
 			       HASHBIN_GET_SIZE(lap->lsaps));
 		len += sprintf(buf+len, "\n");
@@ -1781,27 +1772,24 @@
 		self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
 		while (self != NULL) {
 			ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
-			len += sprintf(buf+len, "  lsap state: %s, ", 
+			len += sprintf(buf+len, "  lsap state: %s, ",
 				       irlsap_state[ self->lsap_state]);
-			len += sprintf(buf+len, 
+			len += sprintf(buf+len,
 				       "slsap_sel: %#02x, dlsap_sel: %#02x, ",
 				       self->slsap_sel, self->dlsap_sel);
 			len += sprintf(buf+len, "(%s)", self->notify.name);
 			len += sprintf(buf+len, "\n");
-			
-			self = (struct lsap_cb *) hashbin_get_next( 
+
+			self = (struct lsap_cb *) hashbin_get_next(
 				lap->lsaps);
-		} 
+		}
 		len += sprintf(buf+len, "\n");
 
 		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
- 	} 
+	}
 	restore_flags(flags);
-	
+
 	return len;
 }
 
 #endif /* PROC_FS */
-
-
-
diff -Nru a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c
--- a/net/irda/irlmp_event.c	Sun Jun 16 19:31:39 2002
+++ b/net/irda/irlmp_event.c	Sun Jun 16 19:31:39 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      irlmp_event.c
  * Version:       0.8
  * Description:   An IrDA LMP event driver for Linux
@@ -8,18 +8,18 @@
  * Created at:    Mon Aug  4 20:40:53 1997
  * Modified at:   Tue Dec 14 23:04:16 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
  *     All Rights Reserved.
  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
  ********************************************************************/
@@ -52,52 +52,52 @@
 #ifdef CONFIG_IRDA_DEBUG
 static const char *irlmp_event[] = {
 	"LM_CONNECT_REQUEST",
- 	"LM_CONNECT_CONFIRM",
+	"LM_CONNECT_CONFIRM",
 	"LM_CONNECT_RESPONSE",
- 	"LM_CONNECT_INDICATION", 	
-	
+	"LM_CONNECT_INDICATION",
+
 	"LM_DISCONNECT_INDICATION",
 	"LM_DISCONNECT_REQUEST",
 
- 	"LM_DATA_REQUEST",
+	"LM_DATA_REQUEST",
 	"LM_UDATA_REQUEST",
- 	"LM_DATA_INDICATION",
+	"LM_DATA_INDICATION",
 	"LM_UDATA_INDICATION",
 
 	"LM_WATCHDOG_TIMEOUT",
 
 	/* IrLAP events */
 	"LM_LAP_CONNECT_REQUEST",
- 	"LM_LAP_CONNECT_INDICATION", 
- 	"LM_LAP_CONNECT_CONFIRM",
- 	"LM_LAP_DISCONNECT_INDICATION", 
+	"LM_LAP_CONNECT_INDICATION",
+	"LM_LAP_CONNECT_CONFIRM",
+	"LM_LAP_DISCONNECT_INDICATION",
 	"LM_LAP_DISCONNECT_REQUEST",
 	"LM_LAP_DISCOVERY_REQUEST",
- 	"LM_LAP_DISCOVERY_CONFIRM",
+	"LM_LAP_DISCOVERY_CONFIRM",
 	"LM_LAP_IDLE_TIMEOUT",
 };
 #endif	/* CONFIG_IRDA_DEBUG */
 
 /* LAP Connection control proto declarations */
-static void irlmp_state_standby  (struct lap_cb *, IRLMP_EVENT, 
+static void irlmp_state_standby  (struct lap_cb *, IRLMP_EVENT,
 				  struct sk_buff *);
-static void irlmp_state_u_connect(struct lap_cb *, IRLMP_EVENT, 
+static void irlmp_state_u_connect(struct lap_cb *, IRLMP_EVENT,
 				  struct sk_buff *);
-static void irlmp_state_active   (struct lap_cb *, IRLMP_EVENT, 
+static void irlmp_state_active   (struct lap_cb *, IRLMP_EVENT,
 				  struct sk_buff *);
 
 /* LSAP Connection control proto declarations */
-static int irlmp_state_disconnected(struct lsap_cb *, IRLMP_EVENT, 
+static int irlmp_state_disconnected(struct lsap_cb *, IRLMP_EVENT,
 				    struct sk_buff *);
-static int irlmp_state_connect     (struct lsap_cb *, IRLMP_EVENT, 
+static int irlmp_state_connect     (struct lsap_cb *, IRLMP_EVENT,
 				    struct sk_buff *);
 static int irlmp_state_connect_pend(struct lsap_cb *, IRLMP_EVENT,
 				    struct sk_buff *);
-static int irlmp_state_dtr         (struct lsap_cb *, IRLMP_EVENT, 
+static int irlmp_state_dtr         (struct lsap_cb *, IRLMP_EVENT,
 				    struct sk_buff *);
-static int irlmp_state_setup       (struct lsap_cb *, IRLMP_EVENT, 
+static int irlmp_state_setup       (struct lsap_cb *, IRLMP_EVENT,
 				    struct sk_buff *);
-static int irlmp_state_setup_pend  (struct lsap_cb *, IRLMP_EVENT, 
+static int irlmp_state_setup_pend  (struct lsap_cb *, IRLMP_EVENT,
 				    struct sk_buff *);
 
 static void (*lap_state[]) (struct lap_cb *, IRLMP_EVENT, struct sk_buff *) =
@@ -118,7 +118,7 @@
 };
 
 static inline void irlmp_next_lap_state(struct lap_cb *self,
-					IRLMP_STATE state) 
+					IRLMP_STATE state)
 {
 	/*
 	IRDA_DEBUG(4, __FUNCTION__ "(), LMP LAP = %s\n", irlmp_state[state]);
@@ -127,7 +127,7 @@
 }
 
 static inline void irlmp_next_lsap_state(struct lsap_cb *self,
-					 LSAP_STATE state) 
+					 LSAP_STATE state)
 {
 	/*
 	ASSERT(self != NULL, return;);
@@ -137,7 +137,7 @@
 }
 
 /* Do connection control events */
-int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, 
+int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event,
 			struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return -1;);
@@ -155,14 +155,14 @@
  *    Do IrLAP control events
  *
  */
-void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event, 
-			struct sk_buff *skb) 
+void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event,
+			struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
-		   irlmp_event[event], 
+		   irlmp_event[event],
 		   irlmp_state[self->lap_state]);
 
 	(*lap_state[self->lap_state]) (self, event, skb);
@@ -171,8 +171,8 @@
 void irlmp_discovery_timer_expired(void *data)
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
-	/* We always cleanup the log (active & passive discovery) */ 
+
+	/* We always cleanup the log (active & passive discovery) */
 	irlmp_do_expiry();
 
 	/* Active discovery is conditional */
@@ -186,7 +186,7 @@
 void irlmp_watchdog_timer_expired(void *data)
 {
 	struct lsap_cb *self = (struct lsap_cb *) data;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
@@ -198,7 +198,7 @@
 void irlmp_idle_timer_expired(void *data)
 {
 	struct lap_cb *self = (struct lap_cb *) data;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
@@ -219,20 +219,20 @@
  *    STANDBY, The IrLAP connection does not exist.
  *
  */
-static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event, 
+static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
 				struct sk_buff *skb)
-{	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
+{
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	ASSERT(self->irlap != NULL, return;);
-	
+
 	switch (event) {
 	case LM_LAP_DISCOVERY_REQUEST:
 		/* irlmp_next_station_state( LMP_DISCOVER); */
-		
+
 		irlap_discovery_request(self->irlap, &irlmp->discovery_cmd);
 		break;
 	case LM_LAP_CONNECT_INDICATION:
-		/*  It's important to switch state first, to avoid IrLMP to 
+		/*  It's important to switch state first, to avoid IrLMP to
 		 *  think that the link is free since IrLMP may then start
 		 *  discovery before the connection is properly set up. DB.
 		 */
@@ -250,16 +250,16 @@
 		irlap_connect_request(self->irlap, self->daddr, NULL, 0);
 		break;
 	case LM_LAP_DISCONNECT_INDICATION:
-		IRDA_DEBUG(4, __FUNCTION__ 
+		IRDA_DEBUG(4, __FUNCTION__
 			   "(), Error LM_LAP_DISCONNECT_INDICATION\n");
-		
+
 		irlmp_next_lap_state(self, LAP_STANDBY);
 		break;
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
+			dev_kfree_skb(skb);
 		break;
 	}
 }
@@ -271,17 +271,17 @@
  *    since the IrLAP connection does not exist, we must first start an
  *    IrLAP connection. We are now waiting response from IrLAP.
  * */
-static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event, 
+static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
 				  struct sk_buff *skb)
 {
 	struct lsap_cb *lsap;
 	struct lsap_cb *lsap_current;
-	
+
 	IRDA_DEBUG(2, __FUNCTION__ "(), event=%s\n", irlmp_event[event]);
 
 	switch (event) {
 	case LM_LAP_CONNECT_INDICATION:
-		/*  It's important to switch state first, to avoid IrLMP to 
+		/*  It's important to switch state first, to avoid IrLMP to
 		 *  think that the link is free since IrLMP may then start
 		 *  discovery before the connection is properly set up. DB.
 		 */
@@ -331,12 +331,12 @@
 		lsap = (struct lsap_cb *) hashbin_get_first( self->lsaps);
 		while (lsap != NULL ) {
 			ASSERT(lsap->magic == LMP_LSAP_MAGIC, return;);
-			
+
 			lsap_current = lsap;
 
 			/* Be sure to stay one item ahead */
 			lsap = (struct lsap_cb *) hashbin_get_next(self->lsaps);
-			irlmp_do_lsap_event(lsap_current, 
+			irlmp_do_lsap_event(lsap_current,
 					    LM_LAP_DISCONNECT_INDICATION,
 					    NULL);
 		}
@@ -354,9 +354,9 @@
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
+			dev_kfree_skb(skb);
 		break;
-	}	
+	}
 }
 
 /*
@@ -365,38 +365,38 @@
  *    ACTIVE, IrLAP connection is active
  *
  */
-static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, 
+static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
 			       struct sk_buff *skb)
 {
 	struct lsap_cb *lsap;
 	struct lsap_cb *lsap_current;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
- 	switch (event) {
+	switch (event) {
 	case LM_LAP_CONNECT_REQUEST:
 		IRDA_DEBUG(4, __FUNCTION__ "(), LS_CONNECT_REQUEST\n");
 
 		/*
-		 *  LAP connection allready active, just bounce back! Since we 
-		 *  don't know which LSAP that tried to do this, we have to 
+		 *  LAP connection allready active, just bounce back! Since we
+		 *  don't know which LSAP that tried to do this, we have to
 		 *  notify all LSAPs using this LAP, but that should be safe to
 		 *  do anyway.
 		 */
 		lsap = (struct lsap_cb *) hashbin_get_first(self->lsaps);
 		while (lsap != NULL) {
 			irlmp_do_lsap_event(lsap, LM_LAP_CONNECT_CONFIRM, NULL);
- 			lsap = (struct lsap_cb*) hashbin_get_next(self->lsaps);
+			lsap = (struct lsap_cb*) hashbin_get_next(self->lsaps);
 		}
-		
+
 		/* Needed by connect indication */
 		lsap = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps);
 		while (lsap != NULL) {
 			lsap_current = lsap;
-			
+
 			/* Be sure to stay one item ahead */
- 			lsap = (struct lsap_cb*) hashbin_get_next(irlmp->unconnected_lsaps);
-			irlmp_do_lsap_event(lsap_current, 
+			lsap = (struct lsap_cb*) hashbin_get_next(irlmp->unconnected_lsaps);
+			irlmp_do_lsap_event(lsap_current,
 					    LM_LAP_CONNECT_CONFIRM, NULL);
 		}
 		/* Keep state */
@@ -404,8 +404,8 @@
 	case LM_LAP_DISCONNECT_REQUEST:
 		/*
 		 *  Need to find out if we should close IrLAP or not. If there
-		 *  is only one LSAP connection left on this link, that LSAP 
-		 *  must be the one that tries to close IrLAP. It will be 
+		 *  is only one LSAP connection left on this link, that LSAP
+		 *  must be the one that tries to close IrLAP. It will be
 		 *  removed later and moved to the list of unconnected LSAPs
 		 */
 		if (HASHBIN_GET_SIZE(self->lsaps) > 0) {
@@ -434,8 +434,8 @@
 		}
 		break;
 	case LM_LAP_DISCONNECT_INDICATION:
-		irlmp_next_lap_state(self, LAP_STANDBY);		
-		
+		irlmp_next_lap_state(self, LAP_STANDBY);
+
 		/* In some case, at this point our side has already closed
 		 * all lsaps, and we are waiting for the idle_timer to
 		 * expire. If another device reconnect immediately, the
@@ -444,18 +444,18 @@
 		 * Therefore, we must stop the timer... */
 		irlmp_stop_idle_timer(self);
 
-		/* 
+		/*
 		 *  Inform all connected LSAP's using this link
 		 */
 		lsap = (struct lsap_cb *) hashbin_get_first(self->lsaps);
 		while (lsap != NULL ) {
 			ASSERT(lsap->magic == LMP_LSAP_MAGIC, return;);
-			
+
 			lsap_current = lsap;
 
 			/* Be sure to stay one item ahead */
 			lsap = (struct lsap_cb *) hashbin_get_next(self->lsaps);
-			irlmp_do_lsap_event(lsap_current, 
+			irlmp_do_lsap_event(lsap_current,
 					    LM_LAP_DISCONNECT_INDICATION,
 					    NULL);
 		}
@@ -473,9 +473,9 @@
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
+			dev_kfree_skb(skb);
 		break;
-	}	
+	}
 }
 
 /*********************************************************************
@@ -491,7 +491,7 @@
  *
  */
 static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event,
-				    struct sk_buff *skb) 
+				    struct sk_buff *skb)
 {
 	int ret = 0;
 
@@ -503,15 +503,15 @@
 	switch (event) {
 #ifdef CONFIG_IRDA_ULTRA
 	case LM_UDATA_INDICATION:
-		irlmp_connless_data_indication(self, skb); 
+		irlmp_connless_data_indication(self, skb);
 		break;
 #endif /* CONFIG_IRDA_ULTRA */
 	case LM_CONNECT_REQUEST:
 		IRDA_DEBUG(4, __FUNCTION__ "(), LM_CONNECT_REQUEST\n");
 
 		if (self->conn_skb) {
-			WARNING(__FUNCTION__ 
-				"(), busy with another request!\n");
+			WARNING("%s: busy with another request!\n",
+					__FUNCTION__);
 			return -EBUSY;
 		}
 		self->conn_skb = skb;
@@ -525,8 +525,8 @@
 		break;
 	case LM_CONNECT_INDICATION:
 		if (self->conn_skb) {
-			WARNING(__FUNCTION__ 
-				"(), busy with another request!\n");
+			WARNING("%s: busy with another request!\n",
+					__FUNCTION__);
 			return -EBUSY;
 		}
 		self->conn_skb = skb;
@@ -549,10 +549,10 @@
 		irlmp_start_watchdog_timer(self, 1*HZ);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
-  			dev_kfree_skb(skb);
+			dev_kfree_skb(skb);
 		break;
 	}
 	return ret;
@@ -564,34 +564,34 @@
  *    CONNECT
  *
  */
-static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event, 
-				struct sk_buff *skb) 
+static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,
+				struct sk_buff *skb)
 {
 	struct lsap_cb *lsap;
 	int ret = 0;
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
 
 	switch (event) {
 	case LM_CONNECT_RESPONSE:
-		/* 
+		/*
 		 *  Bind this LSAP to the IrLAP link where the connect was
-		 *  received 
+		 *  received
 		 */
-		lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, 
+		lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self,
 				      NULL);
 
-		ASSERT(lsap == self, return -1;);		
+		ASSERT(lsap == self, return -1;);
 		ASSERT(self->lap != NULL, return -1;);
 		ASSERT(self->lap->lsaps != NULL, return -1;);
-		
-		hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, 
+
+		hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self,
 			       NULL);
 
-		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, 
+		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
 				   self->slsap_sel, CONNECT_CNF, skb);
 
 		del_timer(&self->watchdog_timer);
@@ -611,7 +611,7 @@
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
+			dev_kfree_skb(skb);
 		break;
 	}
 	return ret;
@@ -624,7 +624,7 @@
  *
  */
 static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event,
-				    struct sk_buff *skb) 
+				    struct sk_buff *skb)
 {
 	int ret = 0;
 
@@ -665,16 +665,16 @@
 		/* Go back to disconnected mode, keep the socket waiting */
 		self->dlsap_sel = LSAP_ANY;
 		if(self->conn_skb)
- 			dev_kfree_skb(self->conn_skb);
+			dev_kfree_skb(self->conn_skb);
 		self->conn_skb = NULL;
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "Unknown event %s\n", 
+		IRDA_DEBUG(0, __FUNCTION__ "Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
-		break;	
+			dev_kfree_skb(skb);
+		break;
 	}
 	return ret;
 }
@@ -685,13 +685,13 @@
  *    DATA_TRANSFER_READY
  *
  */
-static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event, 
-			   struct sk_buff *skb) 
+static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event,
+			   struct sk_buff *skb)
 {
 	LM_REASON reason;
 	int ret = 0;
 
- 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
@@ -699,19 +699,19 @@
 
 	switch (event) {
 	case LM_DATA_REQUEST: /* Optimize for the common case */
-		irlmp_send_data_pdu(self->lap, self->dlsap_sel, 
+		irlmp_send_data_pdu(self->lap, self->dlsap_sel,
 				    self->slsap_sel, FALSE, skb);
 		break;
 	case LM_DATA_INDICATION: /* Optimize for the common case */
-		irlmp_data_indication(self, skb); 
+		irlmp_data_indication(self, skb);
 		break;
 	case LM_UDATA_REQUEST:
 		ASSERT(skb != NULL, return -1;);
-		irlmp_send_data_pdu(self->lap, self->dlsap_sel, 
+		irlmp_send_data_pdu(self->lap, self->dlsap_sel,
 				    self->slsap_sel, TRUE, skb);
 		break;
 	case LM_UDATA_INDICATION:
-		irlmp_udata_indication(self, skb); 
+		irlmp_udata_indication(self, skb);
 		break;
 	case LM_CONNECT_REQUEST:
 		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_REQUEST, "
@@ -719,7 +719,7 @@
 		/* Keep state */
 		break;
 	case LM_CONNECT_RESPONSE:
-		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, " 
+		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, "
 			   "error, LSAP allready connected\n");
 		/* Keep state */
 		break;
@@ -727,12 +727,12 @@
 		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, self->slsap_sel,
 				   DISCONNECT, skb);
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
-		
+
 		/* Try to close the LAP connection if its still there */
 		if (self->lap) {
 			IRDA_DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n");
-			irlmp_do_lap_event(self->lap, 
-					   LM_LAP_DISCONNECT_REQUEST, 
+			irlmp_do_lap_event(self->lap,
+					   LM_LAP_DISCONNECT_REQUEST,
 					   NULL);
 		}
 		break;
@@ -745,10 +745,10 @@
 		break;
 	case LM_DISCONNECT_INDICATION:
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
-			
+
 		ASSERT(self->lap != NULL, return -1;);
 		ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
-	
+
 		ASSERT(skb != NULL, return -1;);
 		ASSERT(skb->len > 3, return -1;);
 		reason = skb->data[3];
@@ -760,11 +760,11 @@
 		irlmp_disconnect_indication(self, reason, skb);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
-		break;	
+			dev_kfree_skb(skb);
+		break;
 	}
 	return ret;
 }
@@ -776,8 +776,8 @@
  *    An LSAP connection request has been transmitted to the peer
  *    LSAP-Connection Control FSM and we are awaiting reply.
  */
-static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event, 
-			     struct sk_buff *skb) 
+static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event,
+			     struct sk_buff *skb)
 {
 	LM_REASON reason;
 	int ret = 0;
@@ -792,15 +792,15 @@
 		irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
 
 		del_timer(&self->watchdog_timer);
-		
+
 		irlmp_connect_confirm(self, skb);
 		break;
 	case LM_DISCONNECT_INDICATION:
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
-			
+
 		ASSERT(self->lap != NULL, return -1;);
 		ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
-	
+
 		ASSERT(skb != NULL, return -1;);
 		ASSERT(skb->len > 3, return -1;);
 		reason = skb->data[3];
@@ -818,26 +818,26 @@
 
 		ASSERT(self->lap != NULL, return -1;);
 		ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
-		
+
 		reason = irlmp_convert_lap_reason(self->lap->reason);
 
 		irlmp_disconnect_indication(self, reason, skb);
 		break;
 	case LM_WATCHDOG_TIMEOUT:
 		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
-		
+
 		ASSERT(self->lap != NULL, return -1;);
 		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
-		
+
 		irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
-		break;	
+			dev_kfree_skb(skb);
+		break;
 	}
 	return ret;
 }
@@ -850,13 +850,13 @@
  *    LAP FSM to set up the underlying IrLAP connection, and we
  *    are awaiting confirm.
  */
-static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event, 
-				  struct sk_buff *skb) 
+static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event,
+				  struct sk_buff *skb)
 {
 	LM_REASON reason;
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(irlmp != NULL, return -1;);
@@ -868,7 +868,7 @@
 		skb = self->conn_skb;
 		self->conn_skb = NULL;
 
-		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, 
+		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
 				   self->slsap_sel, CONNECT_CMD, skb);
 
 		irlmp_next_lsap_state(self, LSAP_SETUP);
@@ -886,17 +886,17 @@
 		del_timer( &self->watchdog_timer);
 
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
-		
+
 		reason = irlmp_convert_lap_reason(self->lap->reason);
-		
+
 		irlmp_disconnect_indication(self, reason, NULL);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", 
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
 		if (skb)
- 			dev_kfree_skb(skb);
-		break;	
+			dev_kfree_skb(skb);
+		break;
 	}
 	return ret;
 }
diff -Nru a/net/irda/irttp.c b/net/irda/irttp.c
--- a/net/irda/irttp.c	Sun Jun 16 19:31:39 2002
+++ b/net/irda/irttp.c	Sun Jun 16 19:31:39 2002
@@ -89,15 +89,15 @@
 			return -ENOMEM;
 	}
 	memset(irttp, 0, sizeof(struct irttp_cb));
-	
+
 	irttp->magic = TTP_MAGIC;
 
 	irttp->tsaps = hashbin_new(HB_LOCAL);
 	if (!irttp->tsaps) {
-		ERROR(__FUNCTION__ "(), can't allocate IrTTP hashbin!\n");
+		ERROR("%s: can't allocate IrTTP hashbin!\n", __FUNCTION__);
 		return -ENOMEM;
 	}
-	
+
 	return 0;
 }
 
@@ -108,19 +108,19 @@
  *
  */
 #ifdef MODULE
-void irttp_cleanup(void) 
+void irttp_cleanup(void)
 {
 	/* Check for main structure */
 	ASSERT(irttp != NULL, return;);
 	ASSERT(irttp->magic == TTP_MAGIC, return;);
-	
+
 	/*
 	 *  Delete hashbin and close all TSAP instances in it
 	 */
 	hashbin_delete(irttp->tsaps, (FREE_FUNC) __irttp_close_tsap);
 
 	irttp->magic = 0;
-	
+
 	/* De-allocate main structure */
 	kfree(irttp);
 
@@ -133,7 +133,7 @@
 /*
  * Function irttp_start_todo_timer (self, timeout)
  *
- *    Start todo timer. 
+ *    Start todo timer.
  *
  * Made it more effient and unsensitive to race conditions - Jean II
  */
@@ -164,7 +164,7 @@
 	/* Check that we still exist */
 	if (!self || self->magic != TTP_TSAP_MAGIC)
 		return;
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(instance=%p)\n", self);
 
 	/* Try to make some progress, especially on Tx side - Jean II */
@@ -185,12 +185,12 @@
 		} else {
 			/* Try again later */
 			irttp_start_todo_timer(self, HZ/10);
-			
+
 			/* No reason to try and close now */
 			return;
 		}
 	}
-	
+
 	/* Check if it's closing time */
 	if (self->close_pend)
 		/* Finish cleanup */
@@ -205,20 +205,20 @@
 void irttp_flush_queues(struct tsap_cb *self)
 {
 	struct sk_buff* skb;
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
-	
+
 	/* Deallocate frames waiting to be sent */
 	while ((skb = skb_dequeue(&self->tx_queue)) != NULL)
 		dev_kfree_skb(skb);
-	
+
 	/* Deallocate received frames */
 	while ((skb = skb_dequeue(&self->rx_queue)) != NULL)
 		dev_kfree_skb(skb);
-	
+
 	/* Deallocate received fragments */
 	while ((skb = skb_dequeue(&self->rx_fragments)) != NULL)
 		dev_kfree_skb(skb);
@@ -235,19 +235,19 @@
 {
 	struct sk_buff *skb, *frag;
 	int n = 0;  /* Fragment index */
-	
-      	ASSERT(self != NULL, return NULL;);
+
+	ASSERT(self != NULL, return NULL;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return NULL;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), self->rx_sdu_size=%d\n", 
+	IRDA_DEBUG(2, __FUNCTION__ "(), self->rx_sdu_size=%d\n",
 		   self->rx_sdu_size);
 
 	skb = dev_alloc_skb(TTP_HEADER + self->rx_sdu_size);
 	if (!skb)
 		return NULL;
 
-	/* 
-	 * Need to reserve space for TTP header in case this skb needs to 
+	/*
+	 * Need to reserve space for TTP header in case this skb needs to
 	 * be requeued in case delivery failes
 	 */
 	skb_reserve(skb, TTP_HEADER);
@@ -259,7 +259,7 @@
 	while ((frag = skb_dequeue(&self->rx_fragments)) != NULL) {
 		memcpy(skb->data+n, frag->data, frag->len);
 		n += frag->len;
-		
+
 		dev_kfree_skb(frag);
 	}
 	IRDA_DEBUG(2, __FUNCTION__ "(), frame len=%d\n", n);
@@ -307,13 +307,13 @@
 		skb_reserve(frag, self->max_header_size);
 
 		/* Copy data from the original skb into this fragment. */
-		memcpy(skb_put(frag, self->max_seg_size), skb->data, 
+		memcpy(skb_put(frag, self->max_seg_size), skb->data,
 		       self->max_seg_size);
 
 		/* Insert TTP header, with the more bit set */
 		frame = skb_push(frag, TTP_HEADER);
 		frame[0] = TTP_MORE;
-		
+
 		/* Hide the copied data from the original skb */
 		skb_pull(skb, self->max_seg_size);
 
@@ -322,7 +322,7 @@
 	}
 	/* Queue what is left of the original skb */
 	IRDA_DEBUG(2, __FUNCTION__  "(), queuing last segment\n");
-	
+
 	frame = skb_push(skb, TTP_HEADER);
 	frame[0] = 0x00; /* Clear more bit */
 
@@ -337,7 +337,7 @@
  *    will be called both when this parameter needs to be inserted into, and
  *    extracted from the connect frames
  */
-static int irttp_param_max_sdu_size(void *instance, irda_param_t *param, 
+static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
 				    int get)
 {
 	struct tsap_cb *self;
@@ -353,7 +353,7 @@
 		self->tx_max_sdu_size = param->pv.i;
 
 	IRDA_DEBUG(1, __FUNCTION__ "(), MaxSduSize=%d\n", param->pv.i);
-	
+
 	return 0;
 }
 
@@ -366,7 +366,7 @@
  *
  *    Create TSAP connection endpoint,
  */
-struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) 
+struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
 {
 	struct tsap_cb *self;
 	struct lsap_cb *lsap;
@@ -421,10 +421,10 @@
 	 */
 	lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0);
 	if (lsap == NULL) {
-		WARNING(__FUNCTION__ "(), unable to allocate LSAP!!\n");
+		WARNING("%s: unable to allocate LSAP!!\n", __FUNCTION__);
 		return NULL;
 	}
-	
+
 	/*
 	 *  If user specified LSAP_ANY as source TSAP selector, then IrLMP
 	 *  will replace it with whatever source selector which is free, so
@@ -443,7 +443,7 @@
 	else
 		self->initial_credit = credit;
 
-	return self;	
+	return self;
 }
 
 /*
@@ -497,7 +497,7 @@
 	if (self->connected) {
 		/* Check if disconnect is not pending */
 		if (!test_bit(0, &self->disconnect_pend)) {
-			WARNING(__FUNCTION__ "(), TSAP still connected!\n");
+			WARNING("%s: TSAP still connected!\n", __FUNCTION__);
 			irttp_disconnect_request(self, NULL, P_NORMAL);
 		}
 		self->close_pend = TRUE;
@@ -505,7 +505,7 @@
 
 		return 0; /* Will be back! */
 	}
-	
+
 	tsap = hashbin_remove(irttp->tsaps, (int) self, NULL);
 
 	ASSERT(tsap == self, return -1;);
@@ -527,7 +527,7 @@
  *    Send unreliable data on this TSAP
  *
  */
-int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb) 
+int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
 {
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
@@ -540,12 +540,12 @@
 		IRDA_DEBUG(1, __FUNCTION__ "(), No data, or not connected\n");
 		return -1;
 	}
-	
+
 	if (skb->len > self->max_seg_size) {
 		IRDA_DEBUG(1, __FUNCTION__ "(), UData is to large for IrLAP!\n");
 		return -1;
 	}
-		    
+
 	irlmp_udata_request(self->lsap, skb);
 	self->stats.tx_packets++;
 
@@ -555,10 +555,10 @@
 /*
  * Function irttp_data_request (handle, skb)
  *
- *    Queue frame for transmission. If SAR is enabled, fragement the frame 
+ *    Queue frame for transmission. If SAR is enabled, fragement the frame
  *    and queue the fragments for transmission
  */
-int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) 
+int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
 {
 	__u8 *frame;
 
@@ -571,33 +571,33 @@
 
 	/* Check that nothing bad happens */
 	if ((skb->len == 0) || (!self->connected)) {
-		WARNING(__FUNCTION__ "(), No data, or not connected\n");
+		WARNING("%s: No data, or not connected\n", __FUNCTION__);
 		return -ENOTCONN;
 	}
 
-	/*  
+	/*
 	 *  Check if SAR is disabled, and the frame is larger than what fits
 	 *  inside an IrLAP frame
 	 */
 	if ((self->tx_max_sdu_size == 0) && (skb->len > self->max_seg_size)) {
-		ERROR(__FUNCTION__ 
-		      "(), SAR disabled, and data is to large for IrLAP!\n");
+		ERROR("%s: SAR disabled, and data is to large for IrLAP!\n",
+				__FUNCTION__);
 		return -EMSGSIZE;
 	}
 
-	/* 
-	 *  Check if SAR is enabled, and the frame is larger than the 
-	 *  TxMaxSduSize 
+	/*
+	 *  Check if SAR is enabled, and the frame is larger than the
+	 *  TxMaxSduSize
 	 */
-	if ((self->tx_max_sdu_size != 0) && 
-	    (self->tx_max_sdu_size != TTP_SAR_UNBOUND) && 
+	if ((self->tx_max_sdu_size != 0) &&
+	    (self->tx_max_sdu_size != TTP_SAR_UNBOUND) &&
 	    (skb->len > self->tx_max_sdu_size))
 	{
-		ERROR(__FUNCTION__ "(), SAR enabled, "
-		      "but data is larger than TxMaxSduSize!\n");
+		ERROR("%s: SAR enabled, but data is larger than TxMaxSduSize!\n",
+		      __FUNCTION__);
 		return -EMSGSIZE;
 	}
-	/* 
+	/*
 	 *  Check if transmit queue is full
 	 */
 	if (skb_queue_len(&self->tx_queue) >= TTP_TX_MAX_QUEUE) {
@@ -610,14 +610,14 @@
 		 * to requeue the packet in the client code - Jean II */
 		return -ENOBUFS;
 	}
-       
+
 	/* Queue frame, or queue frame segments */
 	if ((self->tx_max_sdu_size == 0) || (skb->len < self->max_seg_size)) {
 		/* Queue frame */
 		ASSERT(skb_headroom(skb) >= TTP_HEADER, return -1;);
 		frame = skb_push(skb, TTP_HEADER);
 		frame[0] = 0x00; /* Clear more bit */
-		
+
 		skb_queue_tail(&self->tx_queue, skb);
 	} else {
 		/*
@@ -630,11 +630,11 @@
 	}
 
 	/* Check if we can accept more data from client */
-	if ((!self->tx_sdu_busy) && 
+	if ((!self->tx_sdu_busy) &&
 	    (skb_queue_len(&self->tx_queue) > TTP_TX_HIGH_THRESHOLD)) {
 		/* Tx queue filling up, so stop client. */
 		if (self->notify.flow_indication) {
- 			self->notify.flow_indication(self->notify.instance, 
+			self->notify.flow_indication(self->notify.instance,
 						     self, FLOW_STOP);
 		}
 		/* self->tx_sdu_busy is the state of the client.
@@ -646,7 +646,7 @@
 		 * Jean II */
 		self->tx_sdu_busy = TRUE;
 	}
-	
+
 	/* Try to make some progress */
 	irttp_run_tx_queue(self);
 
@@ -659,7 +659,7 @@
  *    Transmit packets queued for transmission (if possible)
  *
  */
-static void irttp_run_tx_queue(struct tsap_cb *self) 
+static void irttp_run_tx_queue(struct tsap_cb *self)
 {
 	struct sk_buff *skb;
 	unsigned long flags;
@@ -680,7 +680,7 @@
 	       (skb = skb_dequeue(&self->tx_queue)))
 	{
 		/*
-		 *  Since we can transmit and receive frames concurrently, 
+		 *  Since we can transmit and receive frames concurrently,
 		 *  the code below is a critical region and we must assure that
 		 *  nobody messes with the credits while we update them.
 		 */
@@ -688,7 +688,7 @@
 
 		n = self->avail_credit;
 		self->avail_credit = 0;
-		
+
 		/* Only room for 127 credits in frame */
 		if (n > 127) {
 			self->avail_credit = n-127;
@@ -699,19 +699,19 @@
 
 		spin_unlock_irqrestore(&self->lock, flags);
 
-		/* 
-		 *  More bit must be set by the data_request() or fragment() 
+		/*
+		 *  More bit must be set by the data_request() or fragment()
 		 *  functions
 		 */
 		skb->data[0] |= (n & 0x7f);
-		
+
 		/* Detach from socket.
 		 * The current skb has a reference to the socket that sent
 		 * it (skb->sk). When we pass it to IrLMP, the skb will be
 		 * stored in in IrLAP (self->wx_list). When we are within
 		 * IrLAP, we loose the notion of socket, so we should not
 		 * have a reference to a socket. So, we drop it here.
-		 * 
+		 *
 		 * Why does it matter ?
 		 * When the skb is freed (kfree_skb), if it is associated
 		 * with a socket, it release buffer space on the socket
@@ -740,7 +740,7 @@
 	 * to client. That's ok, this test will be true not too often
 	 * (max once per LAP window) and we are called from places
 	 * where we can spend a bit of time doing stuff. - Jean II */
-	if ((self->tx_sdu_busy) && 
+	if ((self->tx_sdu_busy) &&
 	    (skb_queue_len(&self->tx_queue) < TTP_TX_LOW_THRESHOLD) &&
 	    (!self->close_pend))
 	{
@@ -764,16 +764,16 @@
  *    Send a dataless flowdata TTP-PDU and give available credit to peer
  *    TSAP
  */
-static inline void irttp_give_credit(struct tsap_cb *self) 
+static inline void irttp_give_credit(struct tsap_cb *self)
 {
 	struct sk_buff *tx_skb = NULL;
 	unsigned long flags;
 	int n;
 
 	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);	
+	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", 
+	IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
 		   self->send_credit, self->avail_credit, self->remote_credit);
 
 	/* Give credit to peer */
@@ -785,7 +785,7 @@
 	skb_reserve(tx_skb, self->max_header_size);
 
 	/*
-	 *  Since we can transmit and receive frames concurrently, 
+	 *  Since we can transmit and receive frames concurrently,
 	 *  the code below is a critical region and we must assure that
 	 *  nobody messes with the credits while we update them.
 	 */
@@ -793,7 +793,7 @@
 
 	n = self->avail_credit;
 	self->avail_credit = 0;
-	
+
 	/* Only space for 127 credits in frame */
 	if (n > 127) {
 		self->avail_credit = n - 127;
@@ -805,7 +805,7 @@
 
 	skb_put(tx_skb, 1);
 	tx_skb->data[0] = (__u8) (n & 0x7f);
-	
+
 	irlmp_data_request(self->lsap, tx_skb);
 	self->stats.tx_packets++;
 }
@@ -816,8 +816,8 @@
  *    Received some unit-data (unreliable)
  *
  */
-static int irttp_udata_indication(void *instance, void *sap, 
-				  struct sk_buff *skb) 
+static int irttp_udata_indication(void *instance, void *sap,
+				  struct sk_buff *skb)
 {
 	struct tsap_cb *self;
 
@@ -843,10 +843,10 @@
 /*
  * Function irttp_data_indication (instance, sap, skb)
  *
- *    Receive segment from IrLMP. 
+ *    Receive segment from IrLMP.
  *
  */
-static int irttp_data_indication(void *instance, void *sap, 
+static int irttp_data_indication(void *instance, void *sap,
 				 struct sk_buff *skb)
 {
 	struct tsap_cb *self;
@@ -860,7 +860,7 @@
 	self->stats.rx_packets++;
 
 	/*  Deal with inbound credit
-	 *  Since we can transmit and receive frames concurrently, 
+	 *  Since we can transmit and receive frames concurrently,
 	 *  the code below is a critical region and we must assure that
 	 *  nobody messes with the credits while we update them.
 	 */
@@ -870,12 +870,12 @@
 		self->remote_credit--;
 	spin_unlock_irqrestore(&self->lock, flags);
 
-	/* 
-	 *  Data or dataless packet? Dataless frames contains only the 
-	 *  TTP_HEADER. 
+	/*
+	 *  Data or dataless packet? Dataless frames contains only the
+	 *  TTP_HEADER.
 	 */
 	if (skb->len > 1) {
-		/* 
+		/*
 		 *  We don't remove the TTP header, since we must preserve the
 		 *  more bit, so the defragment routing knows what to do
 		 */
@@ -904,7 +904,7 @@
 	 * to miss the next Tx window. The todo timer may take
 	 * a while before it's run... - Jean II */
 
-	/* 
+	/*
 	 * If the peer device has given us some credits and we didn't have
          * anyone from before, then we need to shedule the tx queue.
 	 * We need to do that because our Tx have stopped (so we may not
@@ -936,15 +936,15 @@
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	self = (struct tsap_cb *) instance;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
-	
+
 	/*
 	 *  Inform service user if he has requested it
 	 */
 	if (self->notify.status_indication != NULL)
-		self->notify.status_indication(self->notify.instance, 
+		self->notify.status_indication(self->notify.instance,
 					       link, lock);
 	else
 		IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n");
@@ -961,10 +961,10 @@
 	struct tsap_cb *self;
 
 	self = (struct tsap_cb *) instance;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(instance=%p)\n", self);
 
 	/* We are "polled" directly from LAP, and the LAP want to fill
@@ -998,7 +998,7 @@
  * Function irttp_flow_request (self, command)
  *
  *    This funtion could be used by the upper layers to tell IrTTP to stop
- *    delivering frames if the receive queues are starting to get full, or 
+ *    delivering frames if the receive queues are starting to get full, or
  *    to tell IrTTP to start delivering frames again.
  */
 void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow)
@@ -1016,7 +1016,7 @@
 	case FLOW_START:
 		IRDA_DEBUG(1, __FUNCTION__ "(), flow start\n");
 		self->rx_sdu_busy = FALSE;
-		
+
 		/* Client say he can accept more data, try to free our
 		 * queues ASAP - Jean II */
 		irttp_run_rx_queue(self);
@@ -1026,42 +1026,42 @@
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown flow command!\n");
 	}
 }
-	
+
 /*
  * Function irttp_connect_request (self, dtsap_sel, daddr, qos)
  *
  *    Try to connect to remote destination TSAP selector
  *
  */
-int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, 
+int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
 			  __u32 saddr, __u32 daddr,
-			  struct qos_info *qos, __u32 max_sdu_size, 
-			  struct sk_buff *userdata) 
+			  struct qos_info *qos, __u32 max_sdu_size,
+			  struct sk_buff *userdata)
 {
 	struct sk_buff *skb;
 	__u8 *frame;
 	__u8 n;
-	
-	IRDA_DEBUG(4, __FUNCTION__ "(), max_sdu_size=%d\n", max_sdu_size); 
-	
+
+	IRDA_DEBUG(4, __FUNCTION__ "(), max_sdu_size=%d\n", max_sdu_size);
+
 	ASSERT(self != NULL, return -EBADR;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return -EBADR;);
 
 	if (self->connected)
 		return -EISCONN;
-	
+
 	/* Any userdata supplied? */
 	if (userdata == NULL) {
 		skb = dev_alloc_skb(64);
-		if (!skb) 
+		if (!skb)
 			return -ENOMEM;
-		
+
 		/* Reserve space for MUX_CONTROL and LAP header */
 		skb_reserve(skb, TTP_MAX_HEADER);
 	} else {
 		skb = userdata;
-		/*  
-		 *  Check that the client has reserved enough space for 
+		/*
+		 *  Check that the client has reserved enough space for
 		 *  headers
 		 */
 		ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER, return -1;);
@@ -1079,7 +1079,7 @@
 
 	self->remote_credit = 0;
 	self->send_credit = 0;
-	
+
 	/*
 	 *  Give away max 127 credits for now
 	 */
@@ -1092,41 +1092,41 @@
 
 	/* SAR enabled? */
 	if (max_sdu_size > 0) {
-		ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER), 
+		ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
 		       return -1;);
 
 		/* Insert SAR parameters */
 		frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
-		
-		frame[0] = TTP_PARAMETERS | n; 
+
+		frame[0] = TTP_PARAMETERS | n;
 		frame[1] = 0x04; /* Length */
 		frame[2] = 0x01; /* MaxSduSize */
 		frame[3] = 0x02; /* Value length */
 
-		put_unaligned(cpu_to_be16((__u16) max_sdu_size), 
+		put_unaligned(cpu_to_be16((__u16) max_sdu_size),
 			      (__u16 *)(frame+4));
 	} else {
 		/* Insert plain TTP header */
 		frame = skb_push(skb, TTP_HEADER);
-		
+
 		/* Insert initial credit in frame */
 		frame[0] = n & 0x7f;
 	}
 
 	/* Connect with IrLMP. No QoS parameters for now */
-	return irlmp_connect_request(self->lsap, dtsap_sel, saddr, daddr, qos, 
+	return irlmp_connect_request(self->lsap, dtsap_sel, saddr, daddr, qos,
 				     skb);
 }
 
 /*
  * Function irttp_connect_confirm (handle, qos, skb)
  *
- *    Sevice user confirms TSAP connection with peer. 
+ *    Sevice user confirms TSAP connection with peer.
  *
  */
-static void irttp_connect_confirm(void *instance, void *sap, 
+static void irttp_connect_confirm(void *instance, void *sap,
 				  struct qos_info *qos, __u32 max_seg_size,
-				  __u8 max_header_size, struct sk_buff *skb) 
+				  __u8 max_header_size, struct sk_buff *skb)
 {
 	struct tsap_cb *self;
 	int parameters;
@@ -1135,7 +1135,7 @@
 	__u8 n;
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
+
 	self = (struct tsap_cb *) instance;
 
 	ASSERT(self != NULL, return;);
@@ -1150,21 +1150,21 @@
 	 *  negotiated QoS for the link.
 	 */
 	if (qos) {
-		IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %02x\n", 
-		       qos->baud_rate.bits);			
-		IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %d bps.\n", 
+		IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %02x\n",
+		       qos->baud_rate.bits);
+		IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %d bps.\n",
 		       qos->baud_rate.value);
 	}
 
 	n = skb->data[0] & 0x7f;
-	
+
 	IRDA_DEBUG(4, __FUNCTION__ "(), Initial send_credit=%d\n", n);
-	
+
 	self->send_credit = n;
 	self->tx_max_sdu_size = 0;
 	self->connected = TRUE;
 
-	parameters = skb->data[0] & 0x80;	
+	parameters = skb->data[0] & 0x80;
 
 	ASSERT(skb->len >= TTP_HEADER, return;);
 	skb_pull(skb, TTP_HEADER);
@@ -1173,13 +1173,13 @@
 		plen = skb->data[0];
 
 		ret = irda_param_extract_all(self, skb->data+1,
-					     IRDA_MIN(skb->len-1, plen), 
+					     IRDA_MIN(skb->len-1, plen),
 					     &param_info);
 
 		/* Any errors in the parameter list? */
 		if (ret < 0) {
-			WARNING(__FUNCTION__ 
-				"(), error extracting parameters\n");
+			WARNING("%s: error extracting parameters\n",
+					__FUNCTION__);
 			dev_kfree_skb(skb);
 
 			/* Do not accept this connection attempt */
@@ -1188,8 +1188,8 @@
 		/* Remove parameters */
 		skb_pull(skb, IRDA_MIN(skb->len, plen+1));
 	}
-	
-	IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", 
+
+	IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
 	      self->send_credit, self->avail_credit, self->remote_credit);
 
 	IRDA_DEBUG(2, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size);
@@ -1208,8 +1208,8 @@
  *
  */
 void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos,
-			      __u32 max_seg_size, __u8 max_header_size, 
-			      struct sk_buff *skb) 
+			      __u32 max_seg_size, __u8 max_header_size,
+			      struct sk_buff *skb)
 {
 	struct tsap_cb *self;
 	struct lsap_cb *lsap;
@@ -1222,7 +1222,7 @@
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
- 	ASSERT(skb != NULL, return;);
+	ASSERT(skb != NULL, return;);
 
 	lsap = (struct lsap_cb *) sap;
 
@@ -1238,7 +1238,7 @@
 
 	self->send_credit = n;
 	self->tx_max_sdu_size = 0;
-	
+
 	parameters = skb->data[0] & 0x80;
 
 	ASSERT(skb->len >= TTP_HEADER, return;);
@@ -1246,17 +1246,17 @@
 
 	if (parameters) {
 		plen = skb->data[0];
-		
+
 		ret = irda_param_extract_all(self, skb->data+1,
-					     IRDA_MIN(skb->len-1, plen), 
+					     IRDA_MIN(skb->len-1, plen),
 					     &param_info);
 
 		/* Any errors in the parameter list? */
 		if (ret < 0) {
-			WARNING(__FUNCTION__ 
-				"(), error extracting parameters\n");
+			WARNING("%s: error extracting parameters\n",
+					__FUNCTION__);
 			dev_kfree_skb(skb);
-			
+
 			/* Do not accept this connection attempt */
 			return;
 		}
@@ -1266,8 +1266,8 @@
 	}
 
 	if (self->notify.connect_indication) {
-		self->notify.connect_indication(self->notify.instance, self, 
-						qos, self->tx_max_sdu_size, 
+		self->notify.connect_indication(self->notify.instance, self,
+						qos, self->tx_max_sdu_size,
 						self->max_header_size, skb);
 	} else
 		dev_kfree_skb(skb);
@@ -1278,9 +1278,9 @@
  *
  *    Service user is accepting the connection, just pass it down to
  *    IrLMP!
- * 
+ *
  */
-int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, 
+int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
 			   struct sk_buff *userdata)
 {
 	struct sk_buff *skb;
@@ -1291,9 +1291,9 @@
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), Source TSAP selector=%02x\n", 
+	IRDA_DEBUG(4, __FUNCTION__ "(), Source TSAP selector=%02x\n",
 		   self->stsap_sel);
-	
+
 	/* Any userdata supplied? */
 	if (userdata == NULL) {
 		skb = dev_alloc_skb(64);
@@ -1304,13 +1304,13 @@
 		skb_reserve(skb, TTP_MAX_HEADER);
 	} else {
 		skb = userdata;
-		/*  
-		 *  Check that the client has reserved enough space for 
+		/*
+		 *  Check that the client has reserved enough space for
 		 *  headers
 		 */
 		ASSERT(skb_headroom(skb) >= TTP_MAX_HEADER, return -1;);
 	}
-	
+
 	self->avail_credit = 0;
 	self->remote_credit = 0;
 	self->rx_max_sdu_size = max_sdu_size;
@@ -1330,30 +1330,30 @@
 
 	/* SAR enabled? */
 	if (max_sdu_size > 0) {
-		ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER+TTP_SAR_HEADER), 
+		ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER+TTP_SAR_HEADER),
 		       return -1;);
-		
+
 		/* Insert TTP header with SAR parameters */
 		frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
-		
+
 		frame[0] = TTP_PARAMETERS | n;
 		frame[1] = 0x04; /* Length */
 
 		/* irda_param_insert(self, IRTTP_MAX_SDU_SIZE, frame+1,  */
-/* 				  TTP_SAR_HEADER, &param_info) */
-		
+/*				  TTP_SAR_HEADER, &param_info) */
+
 		frame[2] = 0x01; /* MaxSduSize */
 		frame[3] = 0x02; /* Value length */
 
-		put_unaligned(cpu_to_be16((__u16) max_sdu_size), 
+		put_unaligned(cpu_to_be16((__u16) max_sdu_size),
 			      (__u16 *)(frame+4));
 	} else {
 		/* Insert TTP header */
 		frame = skb_push(skb, TTP_HEADER);
-		
+
 		frame[0] = n & 0x7f;
 	}
-	 
+
 	ret = irlmp_connect_response(self->lsap, skb);
 
 	return ret;
@@ -1365,7 +1365,7 @@
  *    Duplicate TSAP, can be used by servers to confirm a connection on a
  *    new TSAP so it can keep listening on the old one.
  */
-struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) 
+struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
 {
 	struct tsap_cb *new;
 
@@ -1400,11 +1400,11 @@
 /*
  * Function irttp_disconnect_request (self)
  *
- *    Close this connection please! If priority is high, the queued data 
+ *    Close this connection please! If priority is high, the queued data
  *    segments, if any, will be deallocated first
  *
  */
-int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata, 
+int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
 			     int priority)
 {
 	struct sk_buff *skb;
@@ -1441,15 +1441,15 @@
 	 */
 	if (skb_queue_len(&self->tx_queue) > 0) {
 		if (priority == P_HIGH) {
-			/* 
-			 *  No need to send the queued data, if we are 
+			/*
+			 *  No need to send the queued data, if we are
 			 *  disconnecting right now since the data will
 			 *  not have any usable connection to be sent on
 			 */
 			IRDA_DEBUG(1, __FUNCTION__  "High priority!!()\n" );
 			irttp_flush_queues(self);
 		} else if (priority == P_NORMAL) {
-			/* 
+			/*
 			 *  Must delay disconnect until after all data segments
 			 *  have been sent and the tx_queue is empty
 			 */
@@ -1474,12 +1474,12 @@
 		skb = dev_alloc_skb(64);
 		if (!skb)
 			return -ENOMEM;
-		
-		/* 
-		 *  Reserve space for MUX and LAP header 
+
+		/*
+		 *  Reserve space for MUX and LAP header
 		 */
 		skb_reserve(skb, TTP_MAX_HEADER);
-		
+
 		userdata = skb;
 	}
 	ret = irlmp_disconnect_request(self->lsap, userdata);
@@ -1496,21 +1496,21 @@
  *    Disconnect indication, TSAP disconnected by peer?
  *
  */
-void irttp_disconnect_indication(void *instance, void *sap, LM_REASON reason, 
-				 struct sk_buff *skb) 
+void irttp_disconnect_indication(void *instance, void *sap, LM_REASON reason,
+				 struct sk_buff *skb)
 {
 	struct tsap_cb *self;
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	self = (struct tsap_cb *) instance;
-	
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
-	
+
 	/* Prevent higher layer to send more data */
 	self->connected = FALSE;
-	
+
 	/* Check if client has already tried to close the TSAP */
 	if (self->close_pend) {
 		/* In this case, the higher layer is probably gone. Don't
@@ -1558,18 +1558,18 @@
 	/* Usually the layer above will notify that it's input queue is
 	 * starting to get filled by using the flow request, but this may
 	 * be difficult, so it can instead just refuse to eat it and just
-	 * give an error back 
+	 * give an error back
 	 */
 	if (err == -ENOMEM) {
 		IRDA_DEBUG(0, __FUNCTION__ "() requeueing skb!\n");
 
 		/* Make sure we take a break */
 		self->rx_sdu_busy = TRUE;
-		
+
 		/* Need to push the header in again */
 		skb_push(skb, TTP_HEADER);
 		skb->data[0] = 0x00; /* Make sure MORE bit is cleared */
-		
+
 		/* Put skb back on queue */
 		skb_queue_head(&self->rx_queue, skb);
 	}
@@ -1581,18 +1581,18 @@
  *     Check if we have any frames to be transmitted, or if we have any
  *     available credit to give away.
  */
-void irttp_run_rx_queue(struct tsap_cb *self) 
+void irttp_run_rx_queue(struct tsap_cb *self)
 {
 	struct sk_buff *skb;
 	int more = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", 
+	IRDA_DEBUG(2, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
 		   self->send_credit, self->avail_credit, self->remote_credit);
 
 	/* Get exclusive access to the rx queue, otherwise don't touch it */
 	if (irda_lock(&self->rx_queue_lock) == FALSE)
 		return;
-	
+
 	/*
 	 *  Reassemble all frames in receive queue and deliver them
 	 */
@@ -1606,7 +1606,7 @@
 		/* Add the length of the remaining data */
 		self->rx_sdu_size += skb->len;
 
-		/*  
+		/*
 		 * If SAR is disabled, or user has requested no reassembly
 		 * of received fragments then we just deliver them
 		 * immediately. This can be requested by clients that
@@ -1621,8 +1621,8 @@
 
 		/* Check if this is a fragment, and not the last fragment */
 		if (more) {
-			/*  
-			 *  Queue the fragment if we still are within the 
+			/*
+			 *  Queue the fragment if we still are within the
 			 *  limits of the maximum size of the rx_sdu
 			 */
 			if (self->rx_sdu_size <= self->rx_max_sdu_size) {
@@ -1638,32 +1638,32 @@
 		 *  This is the last fragment, so time to reassemble!
 		 */
 		if ((self->rx_sdu_size <= self->rx_max_sdu_size) ||
-		    (self->rx_max_sdu_size == TTP_SAR_UNBOUND)) 
+		    (self->rx_max_sdu_size == TTP_SAR_UNBOUND))
 		{
-			/* 
+			/*
 			 * A little optimizing. Only queue the fragment if
 			 * there are other fragments. Since if this is the
 			 * last and only fragment, there is no need to
-			 * reassemble :-) 
+			 * reassemble :-)
 			 */
 			if (!skb_queue_empty(&self->rx_fragments)) {
-				skb_queue_tail(&self->rx_fragments, 
+				skb_queue_tail(&self->rx_fragments,
 					       skb);
-				
+
 				skb = irttp_reassemble_skb(self);
 			}
-			
+
 			/* Now we can deliver the reassembled skb */
 			irttp_do_data_indication(self, skb);
 		} else {
 			IRDA_DEBUG(1, __FUNCTION__ "(), Truncated frame\n");
-			
+
 			/* Free the part of the SDU that is too big */
 			dev_kfree_skb(skb);
 
 			/* Deliver only the valid but truncated part of SDU */
 			skb = irttp_reassemble_skb(self);
-			
+
 			irttp_do_data_indication(self, skb);
 		}
 		self->rx_sdu_size = 0;
@@ -1671,7 +1671,7 @@
 
 	/*
 	 * It's not trivial to keep track of how many credits are available
-	 * by incrementing at each packet, because delivery may fail 
+	 * by incrementing at each packet, because delivery may fail
 	 * (irttp_do_data_indication() may requeue the frame) and because
 	 * we need to take care of fragmentation.
 	 * We want the other side to send up to initial_credit packets.
@@ -1721,11 +1721,11 @@
 	struct tsap_cb *self;
 	unsigned long flags;
 	int i = 0;
-	
+
 	ASSERT(irttp != NULL, return 0;);
-	
+
 	len = 0;
-	
+
 	save_flags(flags);
 	cli();
 
@@ -1735,9 +1735,9 @@
 			break;
 
 		len += sprintf(buf+len, "TSAP %d, ", i++);
-		len += sprintf(buf+len, "stsap_sel: %02x, ", 
+		len += sprintf(buf+len, "stsap_sel: %02x, ",
 			       self->stsap_sel);
-		len += sprintf(buf+len, "dtsap_sel: %02x\n", 
+		len += sprintf(buf+len, "dtsap_sel: %02x\n",
 			       self->dtsap_sel);
 		len += sprintf(buf+len, "  connected: %s, ",
 			       self->connected? "TRUE":"FALSE");
@@ -1751,9 +1751,9 @@
 			       self->stats.tx_packets);
 		len += sprintf(buf+len, "rx packets: %ld, ",
 			       self->stats.rx_packets);
-		len += sprintf(buf+len, "tx_queue len: %d ", 
+		len += sprintf(buf+len, "tx_queue len: %d ",
 			       skb_queue_len(&self->tx_queue));
-		len += sprintf(buf+len, "rx_queue len: %d\n", 
+		len += sprintf(buf+len, "rx_queue len: %d\n",
 			       skb_queue_len(&self->rx_queue));
 		len += sprintf(buf+len, "  tx_sdu_busy: %s, ",
 			       self->tx_sdu_busy? "TRUE":"FALSE");
@@ -1766,11 +1766,11 @@
 		len += sprintf(buf+len, "rx_max_sdu_size: %d\n",
 			       self->rx_max_sdu_size);
 
-		len += sprintf(buf+len, "  Used by (%s)\n", 
+		len += sprintf(buf+len, "  Used by (%s)\n",
 				self->notify.name);
 
 		len += sprintf(buf+len, "\n");
-		
+
 		self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps);
 	}
 	restore_flags(flags);
diff -Nru a/net/irda/parameters.c b/net/irda/parameters.c
--- a/net/irda/parameters.c	Sun Jun 16 19:31:40 2002
+++ b/net/irda/parameters.c	Sun Jun 16 19:31:40 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      parameters.c
  * Version:       1.0
  * Description:   A more general way to handle (pi,pl,pv) parameters
@@ -8,24 +8,24 @@
  * Created at:    Mon Jun  7 10:25:11 1999
  * Modified at:   Sun Jan 30 14:08:39 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
+ *
  *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
- * 
+ *
  *     This program is distributed in the hope that it will be useful,
  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program; if not, write to the Free Software
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *     MA 02111-1307 USA
- *     
+ *
  ********************************************************************/
 
 #include <linux/types.h>
@@ -35,18 +35,18 @@
 #include <net/irda/irda.h>
 #include <net/irda/parameters.h>
 
-static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi,
 				PV_TYPE type, PI_HANDLER func);
-static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
 			       PV_TYPE type, PI_HANDLER func);
-static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi,
 			       PV_TYPE type, PI_HANDLER func);
-static int irda_extract_no_value(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_extract_no_value(void *self, __u8 *buf, int len, __u8 pi,
 				 PV_TYPE type, PI_HANDLER func);
 
-static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi,
 			       PV_TYPE type, PI_HANDLER func);
-static int irda_insert_no_value(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_insert_no_value(void *self, __u8 *buf, int len, __u8 pi,
 				PV_TYPE type, PI_HANDLER func);
 
 /* Parameter value call table. Must match PV_TYPE */
@@ -72,11 +72,8 @@
 
 /*
  * Function irda_insert_no_value (self, buf, len, pi, type, func)
- *
- *    
- *
  */
-static int irda_insert_no_value(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_insert_no_value(void *self, __u8 *buf, int len, __u8 pi,
 				PV_TYPE type, PI_HANDLER func)
 {
 	irda_param_t p;
@@ -93,7 +90,7 @@
 
 	if (ret < 0)
 		return ret;
-	 
+
 	return 2; /* Inserted pl+2 bytes */
 }
 
@@ -103,7 +100,7 @@
  *    Extracts a parameter without a pv field (pl=0)
  *
  */
-static int irda_extract_no_value(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_extract_no_value(void *self, __u8 *buf, int len, __u8 pi,
 				 PV_TYPE type, PI_HANDLER func)
 {
 	irda_param_t p;
@@ -117,17 +114,14 @@
 
 	if (ret < 0)
 		return ret;
-	 
+
 	return 2; /* Extracted pl+2 bytes */
 }
 
 /*
  * Function irda_insert_integer (self, buf, len, pi, type, func)
- *
- *    
- *
  */
-static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi,
 			       PV_TYPE type, PI_HANDLER func)
 {
 	irda_param_t p;
@@ -141,10 +135,10 @@
 	/* Call handler for this parameter */
 	err = (*func)(self, &p, PV_GET);
 	if (err < 0)
-		return err; 
+		return err;
 
-	/* 
-	 * If parameter lenght is still 0, then (1) this is an any length 
+	/*
+	 * If parameter lenght is still 0, then (1) this is an any length
 	 * integer, and (2) the handler function does not care which length
 	 * we choose to use, so we pick the one the gives the fewest bytes.
 	 */
@@ -162,7 +156,7 @@
 	}
 	/* Check if buffer is long enough for insertion */
 	if (len < (2+p.pl)) {
-		WARNING(__FUNCTION__ "(), buffer to short for insertion!\n");
+		WARNING("%s: buffer to short for insertion!\n", __FUNCTION__);
 		return -1;
 	}
 	IRDA_DEBUG(2, __FUNCTION__ "(), pi=%#x, pl=%d, pi=%d\n", p.pi, p.pl, p.pv.i);
@@ -186,8 +180,8 @@
 
 		break;
 	default:
-		WARNING(__FUNCTION__ "() length %d not supported\n", p.pl);
-		/* Skip parameter */ 
+		WARNING("%s: length %d not supported\n", __FUNCTION__, p.pl);
+		/* Skip parameter */
 		return -1;
 	}
 
@@ -197,10 +191,10 @@
 /*
  * Function irda_extract integer (self, buf, len, pi, type, func)
  *
- *    Extract a possibly variable length integer from buffer, and call 
+ *    Extract a possibly variable length integer from buffer, and call
  *    handler for processing of the parameter
  */
-static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi,
 				PV_TYPE type, PI_HANDLER func)
 {
 	irda_param_t p;
@@ -213,20 +207,21 @@
 
 	/* Check if buffer is long enough for parsing */
 	if (len < (2+p.pl)) {
-		WARNING(__FUNCTION__ "(), buffer to short for parsing! "
-			"Need %d bytes, but len is only %d\n", p.pl, len);
+		WARNING("%s: buffer to short for parsing! "
+			"Need %d bytes, but len is only %d\n",
+			__FUNCTION__, p.pl, len);
 		return -1;
 	}
 
-	/* 
+	/*
 	 * Check that the integer length is what we expect it to be. If the
 	 * handler want a 16 bits integer then a 32 bits is not good enough
 	 */
 	if (((type & PV_MASK) != PV_INTEGER) && ((type & PV_MASK) != p.pl)) {
-		ERROR(__FUNCTION__ "(), invalid parameter length! "
+		ERROR("%s: invalid parameter length! "
 		      "Expected %d bytes, but value had %d bytes!\n",
-		      type & PV_MASK, p.pl);
-		
+		      __FUNCTION__, type & PV_MASK, p.pl);
+
 		/* Skip parameter */
 		return p.pl+2;
 	}
@@ -251,9 +246,9 @@
 			le32_to_cpus(&p.pv.i);
 		break;
 	default:
-		WARNING(__FUNCTION__ "() length %d not supported\n", p.pl);
+		WARNING("%s: length %d not supported\n", __FUNCTION__, p.pl);
 
-		/* Skip parameter */ 
+		/* Skip parameter */
 		return p.pl+2;
 	}
 
@@ -261,18 +256,15 @@
 	/* Call handler for this parameter */
 	err = (*func)(self, &p, PV_PUT);
 	if (err < 0)
-		return err; 
+		return err;
 
 	return p.pl+2; /* Extracted pl+2 bytes */
 }
 
 /*
  * Function irda_extract_string (self, buf, len, type, func)
- *
- *    
- *
  */
-static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, 
+static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
 			       PV_TYPE type, PI_HANDLER func)
 {
 	char str[33];
@@ -288,18 +280,19 @@
 
 	/* Check if buffer is long enough for parsing */
 	if (len < (2+p.pl)) {
-		WARNING(__FUNCTION__ "(), buffer to short for parsing! "
-			"Need %d bytes, but len is only %d\n", p.pl, len);
+		WARNING("%s: buffer to short for parsing! "
+			"Need %d bytes, but len is only %d\n",
+			__FUNCTION__, p.pl, len);
 		return -1;
 	}
 
-	/* Should be safe to copy string like this since we have already 
+	/* Should be safe to copy string like this since we have already
 	 * checked that the buffer is long enough */
 	strncpy(str, buf+2, p.pl);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), str=0x%02x 0x%02x\n", (__u8) str[0], 
+	IRDA_DEBUG(2, __FUNCTION__ "(), str=0x%02x 0x%02x\n", (__u8) str[0],
 	      (__u8) str[1]);
-	
+
 	/* Null terminate string */
 	str[p.pl+1] = '\0';
 
@@ -308,16 +301,13 @@
 	/* Call handler for this parameter */
 	err = (*func)(self, &p, PV_PUT);
 	if (err < 0)
-		return err; 
+		return err;
 
 	return p.pl+2; /* Extracted pl+2 bytes */
 }
 
 /*
  * Function irda_extract_octseq (self, buf, len, type, func)
- *
- *    
- *
  */
 static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi,
 			       PV_TYPE type, PI_HANDLER func)
@@ -329,13 +319,14 @@
 
 	/* Check if buffer is long enough for parsing */
 	if (len < (2+p.pl)) {
-		WARNING(__FUNCTION__ "(), buffer to short for parsing! "
-			"Need %d bytes, but len is only %d\n", p.pl, len);
+		WARNING("%s: buffer to short for parsing! "
+			"Need %d bytes, but len is only %d\n",
+			__FUNCTION__, p.pl, len);
 		return -1;
 	}
 
 	IRDA_DEBUG(0, __FUNCTION__ "(), not impl\n");
-	
+
 	return p.pl+2; /* Extracted pl+2 bytes */
 }
 
@@ -353,7 +344,7 @@
 	va_list args;
 	char *p;
 	int n = 0;
-	
+
 	va_start(args, fmt);
 
 	for (p = fmt; *p != '\0'; p++) {
@@ -380,7 +371,6 @@
 			va_end(args);
 			return -1;
 		}
-		
 	}
 	va_end(args);
 
@@ -389,9 +379,6 @@
 
 /*
  * Function irda_param_unpack (skb, fmt, ...)
- *
- *    
- *
  */
 int irda_param_unpack(__u8 *buf, char *fmt, ...)
 {
@@ -427,7 +414,7 @@
 			va_end(args);
 			return -1;
 		}
-		
+
 	}
 	va_end(args);
 
@@ -440,7 +427,7 @@
  *    Insert the specified parameter (pi) into buffer. Returns number of
  *    bytes inserted
  */
-int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, 
+int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len,
 		      pi_param_info_t *info)
 {
 	pi_minor_info_t *pi_minor_info;
@@ -457,16 +444,16 @@
 	pi_major = pi >> info->pi_major_offset;
 
 	/* Check if the identifier value (pi) is valid */
-	if ((pi_major > info->len-1) || 
+	if ((pi_major > info->len-1) ||
 	    (pi_minor > info->tables[pi_major].len-1))
 	{
-		IRDA_DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__
 		      "(), no handler for parameter=0x%02x\n", pi);
-		
+
 		/* Skip this parameter */
 		return -1;
 	}
-	
+
 	/* Lookup the info on how to parse this parameter */
 	pi_minor_info = &info->tables[pi_major].pi_minor_call_table[pi_minor];
 
@@ -475,13 +462,13 @@
 
 	/*  Check if handler has been implemented */
 	if (!pi_minor_info->func) {
-		MESSAGE(__FUNCTION__"(), no handler for pi=%#x\n", pi);
+		MESSAGE("%s: no handler for pi=%#x\n", __FUNCTION__, pi);
 		/* Skip this parameter */
 		return -1;
 	}
-	
+
 	/* Insert parameter value */
-	ret = (*pv_insert_table[type & PV_MASK])(self, buf+n, len, pi, type, 
+	ret = (*pv_insert_table[type & PV_MASK])(self, buf+n, len, pi, type,
 						 pi_minor_info->func);
 	return ret;
 }
@@ -507,14 +494,14 @@
 
 	pi_minor = buf[n] & info->pi_mask;
 	pi_major = buf[n] >> info->pi_major_offset;
-	
+
 	/* Check if the identifier value (pi) is valid */
-	if ((pi_major > info->len-1) || 
+	if ((pi_major > info->len-1) ||
 	    (pi_minor > info->tables[pi_major].len-1))
 	{
 		IRDA_DEBUG(0, __FUNCTION__ "(), no handler for parameter=0x%02x\n",
 		      buf[0]);
-		
+
 		/* Skip this parameter */
 		return 2 + buf[n + 1];  /* Continue */
 	}
@@ -524,13 +511,13 @@
 
 	/* Find expected data type for this parameter identifier (pi)*/
 	type = pi_minor_info->type;
-	
+
 	IRDA_DEBUG(3, __FUNCTION__ "(), pi=[%d,%d], type=%d\n",
 	      pi_major, pi_minor, type);
-	
+
 	/*  Check if handler has been implemented */
 	if (!pi_minor_info->func) {
-		MESSAGE(__FUNCTION__"(), no handler for pi=%#x\n", buf[n]);
+		MESSAGE("%s: no handler for pi=%#x\n", __FUNCTION__, buf[n]);
 		/* Skip this parameter */
 		return 2 + buf[n + 1]; /* Continue */
 	}
diff -Nru a/net/irda/wrapper.c b/net/irda/wrapper.c
--- a/net/irda/wrapper.c	Sun Jun 16 19:31:39 2002
+++ b/net/irda/wrapper.c	Sun Jun 16 19:31:39 2002
@@ -1,5 +1,5 @@
 /*********************************************************************
- *                
+ *
  * Filename:      wrapper.c
  * Version:       1.2
  * Description:   IrDA SIR async wrapper layer
@@ -10,17 +10,17 @@
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Modified at:   Fri May 28  3:11 CST 1999
  * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
- * 
- *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
+ *
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
  *     All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
  *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
+ *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
  ********************************************************************/
@@ -39,22 +39,22 @@
 
 static inline int stuff_byte(__u8 byte, __u8 *buf);
 
-static void state_outside_frame(struct net_device *dev, 
-				struct net_device_stats *stats, 
+static void state_outside_frame(struct net_device *dev,
+				struct net_device_stats *stats,
 				iobuff_t *rx_buff, __u8 byte);
-static void state_begin_frame(struct net_device *dev, 
-			      struct net_device_stats *stats, 
+static void state_begin_frame(struct net_device *dev,
+			      struct net_device_stats *stats,
 			      iobuff_t *rx_buff, __u8 byte);
-static void state_link_escape(struct net_device *dev, 
-			      struct net_device_stats *stats, 
+static void state_link_escape(struct net_device *dev,
+			      struct net_device_stats *stats,
 			      iobuff_t *rx_buff, __u8 byte);
-static void state_inside_frame(struct net_device *dev, 
-			       struct net_device_stats *stats, 
+static void state_inside_frame(struct net_device *dev,
+			       struct net_device_stats *stats,
 			       iobuff_t *rx_buff, __u8 byte);
 
-static void (*state[])(struct net_device *dev, struct net_device_stats *stats, 
-		       iobuff_t *rx_buff, __u8 byte) = 
-{ 
+static void (*state[])(struct net_device *dev, struct net_device_stats *stats,
+		       iobuff_t *rx_buff, __u8 byte) =
+{
 	state_outside_frame,
 	state_begin_frame,
 	state_link_escape,
@@ -64,14 +64,14 @@
 /*
  * Function async_wrap (skb, *tx_buff, buffsize)
  *
- *    Makes a new buffer with wrapping and stuffing, should check that 
+ *    Makes a new buffer with wrapping and stuffing, should check that
  *    we don't get tx buffer overflow.
  */
 int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
 {
 	struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
 	int xbofs;
- 	int i;
+	int i;
 	int n;
 	union {
 		__u16 value;
@@ -86,11 +86,11 @@
 	 *  Send  XBOF's for required min. turn time and for the negotiated
 	 *  additional XBOFS
 	 */
-	
+
 	if (cb->magic != LAP_MAGIC) {
-		/* 
+		/*
 		 * This will happen for all frames sent from user-space.
-		 * Nothing to worry about, but we set the default number of 
+		 * Nothing to worry about, but we set the default number of
 		 * BOF's
 		 */
 		IRDA_DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n");
@@ -116,7 +116,7 @@
 	for (i=0; i < skb->len; i++) {
 		/*
 		 *  Check for the possibility of tx buffer overflow. We use
-		 *  bufsize-5 since the maximum number of bytes that can be 
+		 *  bufsize-5 since the maximum number of bytes that can be
 		 *  transmitted after this point is 5.
 		 */
 		ASSERT(n < (buffsize-5), return n;);
@@ -124,7 +124,7 @@
 		n += stuff_byte(skb->data[i], tx_buff+n);
 		fcs.value = irda_fcs(fcs.value, skb->data[i]);
 	}
-	
+
 	/* Insert CRC in little endian format (LSB first) */
 	fcs.value = ~fcs.value;
 #ifdef __LITTLE_ENDIAN
@@ -144,9 +144,9 @@
  *
  *    Byte stuff one single byte and put the result in buffer pointed to by
  *    buf. The buffer must at all times be able to have two bytes inserted.
- * 
+ *
  */
-static inline int stuff_byte(__u8 byte, __u8 *buf) 
+static inline int stuff_byte(__u8 byte, __u8 *buf)
 {
 	switch (byte) {
 	case BOF: /* FALLTHROUGH */
@@ -174,7 +174,7 @@
 inline void async_bump(struct net_device *dev, struct net_device_stats *stats,
 		       __u8 *buf, int len)
 {
-       	struct sk_buff *skb;
+	struct sk_buff *skb;
 
 	skb = dev_alloc_skb(len+1);
 	if (!skb)  {
@@ -184,10 +184,10 @@
 
 	/* Align IP header to 20 bytes */
 	skb_reserve(skb, 1);
-	
+
         /* Copy data without CRC */
-	memcpy(skb_put(skb, len-2), buf, len-2); 
-	
+	memcpy(skb_put(skb, len-2), buf, len-2);
+
 	/* Feed it to IrLAP layer */
 	skb->dev = dev;
 	skb->mac.raw  = skb->data;
@@ -196,7 +196,7 @@
 	netif_rx(skb);
 
 	stats->rx_packets++;
-	stats->rx_bytes += len;	
+	stats->rx_bytes += len;
 }
 
 /*
@@ -205,21 +205,21 @@
  *    Parse and de-stuff frame received from the IrDA-port
  *
  */
-inline void async_unwrap_char(struct net_device *dev, 
-			      struct net_device_stats *stats, 
+inline void async_unwrap_char(struct net_device *dev,
+			      struct net_device_stats *stats,
 			      iobuff_t *rx_buff, __u8 byte)
 {
 	(*state[rx_buff->state])(dev, stats, rx_buff, byte);
 }
-	 
+
 /*
  * Function state_outside_frame (dev, rx_buff, byte)
  *
  *    Not receiving any frame (or just bogus data)
  *
  */
-static void state_outside_frame(struct net_device *dev, 
-				struct net_device_stats *stats, 
+static void state_outside_frame(struct net_device *dev,
+				struct net_device_stats *stats,
 				iobuff_t *rx_buff, __u8 byte)
 {
 	switch (byte) {
@@ -245,8 +245,8 @@
  *    Begin of frame detected
  *
  */
-static void state_begin_frame(struct net_device *dev, 
-			      struct net_device_stats *stats, 
+static void state_begin_frame(struct net_device *dev,
+			      struct net_device_stats *stats,
 			      iobuff_t *rx_buff, __u8 byte)
 {
 	/* Time to initialize receive buffer */
@@ -283,27 +283,27 @@
  *    Found link escape character
  *
  */
-static void state_link_escape(struct net_device *dev, 
-			      struct net_device_stats *stats, 
+static void state_link_escape(struct net_device *dev,
+			      struct net_device_stats *stats,
 			      iobuff_t *rx_buff, __u8 byte)
 {
 	switch (byte) {
 	case BOF: /* New frame? */
-		IRDA_DEBUG(1, __FUNCTION__ 
+		IRDA_DEBUG(1, __FUNCTION__
 			   "(), Discarding incomplete frame\n");
 		rx_buff->state = BEGIN_FRAME;
 		irda_device_set_media_busy(dev, TRUE);
 		break;
 	case CE:
-		WARNING(__FUNCTION__ "(), state not defined\n");
+		WARNING("%s: state not defined\n", __FUNCTION__);
 		break;
 	case EOF: /* Abort frame */
 		rx_buff->state = OUTSIDE_FRAME;
 		break;
 	default:
-		/* 
-		 *  Stuffed char, complement bit 5 of byte 
-		 *  following CE, IrLAP p.114 
+		/*
+		 *  Stuffed char, complement bit 5 of byte
+		 *  following CE, IrLAP p.114
 		 */
 		byte ^= IRDA_TRANS;
 		if (rx_buff->len < rx_buff->truesize)  {
@@ -324,15 +324,15 @@
  *    Handle bytes received within a frame
  *
  */
-static void state_inside_frame(struct net_device *dev, 
+static void state_inside_frame(struct net_device *dev,
 			       struct net_device_stats *stats,
 			       iobuff_t *rx_buff, __u8 byte)
 {
-	int ret = 0; 
+	int ret = 0;
 
 	switch (byte) {
 	case BOF: /* New frame? */
-		IRDA_DEBUG(1, __FUNCTION__ 
+		IRDA_DEBUG(1, __FUNCTION__
 			   "(), Discarding incomplete frame\n");
 		rx_buff->state = BEGIN_FRAME;
 		irda_device_set_media_busy(dev, TRUE);
@@ -343,7 +343,7 @@
 	case EOF: /* End of frame */
 		rx_buff->state = OUTSIDE_FRAME;
 		rx_buff->in_frame = FALSE;
-		
+
 		/* Test FCS and signal success if the frame is good */
 		if (rx_buff->fcs == GOOD_FCS) {
 			/* Deliver frame */
@@ -352,24 +352,22 @@
 			break;
 		} else {
 			/* Wrong CRC, discard frame!  */
-			irda_device_set_media_busy(dev, TRUE); 
+			irda_device_set_media_busy(dev, TRUE);
 
 			IRDA_DEBUG(1, __FUNCTION__ "(), crc error\n");
 			stats->rx_errors++;
 			stats->rx_crc_errors++;
-		}			
+		}
 		break;
 	default: /* Must be the next byte of the frame */
 		if (rx_buff->len < rx_buff->truesize)  {
 			rx_buff->data[rx_buff->len++] = byte;
 			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
 		} else {
-			IRDA_DEBUG(1, __FUNCTION__ 
+			IRDA_DEBUG(1, __FUNCTION__
 			      "(), Rx buffer overflow, aborting\n");
 			rx_buff->state = OUTSIDE_FRAME;
 		}
 		break;
 	}
 }
-
-
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Sun Jun 16 19:31:40 2002
+++ b/net/socket.c	Sun Jun 16 19:31:40 2002
@@ -317,34 +317,10 @@
 	statfs:		simple_statfs,
 };
 
-static int sockfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *root;
-	sb->s_blocksize = 1024;
-	sb->s_blocksize_bits = 10;
-	sb->s_magic = SOCKFS_MAGIC;
-	sb->s_op = &sockfs_ops;
-	root = new_inode(sb);
-	if (!root)
-		return -ENOMEM;
-	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
-	root->i_uid = root->i_gid = 0;
-	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
-	sb->s_root = d_alloc(NULL, &(const struct qstr) { "socket:", 7, 0 });
-	if (!sb->s_root) {
-		iput(root);
-		return -ENOMEM;
-	}
-	sb->s_root->d_sb = sb;
-	sb->s_root->d_parent = sb->s_root;
-	d_instantiate(sb->s_root, root);
-	return 0;
-}
-
 static struct super_block *sockfs_get_sb(struct file_system_type *fs_type,
 	int flags, char *dev_name, void *data)
 {
-	return get_sb_nodev(fs_type, flags, data, sockfs_fill_super);
+	return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
 }
 
 static struct vfsmount *sock_mnt;
@@ -353,7 +329,6 @@
 	name:		"sockfs",
 	get_sb:		sockfs_get_sb,
 	kill_sb:	kill_anon_super,
-	fs_flags:	FS_NOMOUNT,
 };
 static int sockfs_delete_dentry(struct dentry *dentry)
 {
@@ -783,11 +758,13 @@
 			return -ENOMEM;
 	}
 
-
 	sock = SOCKET_I(filp->f_dentry->d_inode);
-	
-	if ((sk=sock->sk) == NULL)
+
+	if ((sk=sock->sk) == NULL) {
+		if (fna)
+			kfree(fna);
 		return -EINVAL;
+	}
 
 	lock_sock(sk);
 
diff -Nru a/scripts/Makefile b/scripts/Makefile
--- a/scripts/Makefile	Sun Jun 16 19:31:40 2002
+++ b/scripts/Makefile	Sun Jun 16 19:31:40 2002
@@ -22,7 +22,7 @@
 # Config.in files to depend on anyways.  So I'll force it to remake.
 
 kconfig.tk: $(TOPDIR)/arch/$(ARCH)/config.in tkparse $(HEADER) $(TAIL) FORCE
-	@echo Generating $@
+	@echo '  Generating $@'
 	@(                                                      \
 	  if [ -f /usr/local/bin/wish ];	then            \
 		echo '#!'"/usr/local/bin/wish -f";              \
diff -Nru a/scripts/fixdep.c b/scripts/fixdep.c
--- a/scripts/fixdep.c	Sun Jun 16 19:31:40 2002
+++ b/scripts/fixdep.c	Sun Jun 16 19:31:40 2002
@@ -61,9 +61,9 @@
  *
  * It is invoked as
  *
- *   fixdep <target> <topdir> <cmdline>
+ *   fixdep <depfile> <target> <topdir> <cmdline>
  *
- * and will read the dependency file ".<target>.d".
+ * and will read the dependency file <depfile>
  *
  * The transformed dependency snipped is written to stdout.
  *
@@ -112,29 +112,20 @@
 #define INT_FIG_ ntohl(0x4649475f)
 
 char *topdir;
+char *target;
+char *depfile;
+char *cmdline;
 
 void usage(void)
 
 {
-	fprintf(stderr, "Usage: fixdep <target> <topdir> <cmdline>\n");
+	fprintf(stderr, "Usage: fixdep <depfile> <target> <topdir> <cmdline>\n");
 	exit(1);
 }
 
-void print_cmdline(char *target, char *cmdline)
+void print_cmdline(void)
 {
-	char *s = strdup(target);
-	char *p = s;
-
-	if (!s) {
-		fprintf(stderr, "no mem!\n");
-		exit(2);
-	}
-	while ((p = strchr(p,'/')))
-		*p = '_';
-
-	printf("cmd_%s := %s\n\n", s, cmdline);
-
-	free(s);
+	printf("cmd_%s := %s\n\n", target, cmdline);
 }
 
 char * str_config  = NULL;
@@ -297,11 +288,11 @@
 
 	p = strchr(m, ':');
 	if (!p) {
-		fprintf(stderr, "parse error at %d", __LINE__);
+		fprintf(stderr, "fixdep: parse error\n");
 		exit(1);
 	}
 	memcpy(s, m, p-m); s[p-m] = 0;
-	printf("%s: \\\n", s);
+	printf("%s: \\\n", target);
 	m = p+1;
 
 	clear_config();
@@ -326,22 +317,20 @@
 	printf("\n");
 }
 
-void print_deps(char *target)
+void print_deps(void)
 {
-	char filename[PATH_MAX];
 	struct stat st;
 	int fd;
 	void *map;
 
-	sprintf(filename, ".%s.d", target);
-	fd = open(filename, O_RDONLY);
+	fd = open(depfile, O_RDONLY);
 	if (fd < 0) {
-		perror(filename);
+		perror(depfile);
 		exit(2);
 	}
 	fstat(fd, &st);
 	if (st.st_size == 0) {
-		fprintf(stderr,"%s is empty\n",filename);
+		fprintf(stderr,"fixdep: %s is empty\n",depfile);
 		close(fd);
 		return;
 	}
@@ -359,10 +348,10 @@
 
 void traps(void)
 {
-	char *test = "CONF";
+	static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
 
 	if (*(int *)test != INT_CONF) {
-		fprintf(stderr, "sizeof(int) != 4 or wrong endianess? %#x\n",
+		fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
 			*(int *)test);
 		exit(2);
 	}
@@ -370,19 +359,18 @@
 
 int main(int argc, char *argv[])
 {
-	char *target, *cmdline;
-	
 	traps();
 
-	if (argc != 4)
+	if (argc != 5)
 		usage();
 		
-	target = argv[1];
-	topdir = argv[2];
-	cmdline = argv[3];
+	depfile = argv[1];
+	target = argv[2];
+	topdir = argv[3];
+	cmdline = argv[4];
 
-	print_cmdline(target, cmdline);
-	print_deps(target);
+	print_cmdline();
+	print_deps();
 
 	return 0;
 }
diff -Nru a/sound/Makefile b/sound/Makefile
--- a/sound/Makefile	Sun Jun 16 19:31:40 2002
+++ b/sound/Makefile	Sun Jun 16 19:31:40 2002
@@ -5,8 +5,6 @@
 
 export-objs     := sound_core.o
 
-mod-subdirs	:= oss core i2c drivers isa pci ppc synth
-
 obj-$(CONFIG_SOUND) += soundcore.o
 obj-$(CONFIG_SOUND_PRIME) += oss/
 obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/
diff -Nru a/sound/core/Makefile b/sound/core/Makefile
--- a/sound/core/Makefile	Sun Jun 16 19:31:39 2002
+++ b/sound/core/Makefile	Sun Jun 16 19:31:39 2002
@@ -5,8 +5,6 @@
 
 export-objs  := sound.o pcm.o pcm_lib.o rawmidi.o timer.o rtctimer.o hwdep.o
 
-mod-subdirs  := oss seq
-
 snd-objs     := sound.o init.o isadma.o memory.o info.o control.o misc.o \
                 device.o wrappers.o
 ifeq ($(CONFIG_SND_OSSEMUL),y)
diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c
--- a/sound/core/rawmidi.c	Sun Jun 16 19:31:39 2002
+++ b/sound/core/rawmidi.c	Sun Jun 16 19:31:39 2002
@@ -143,7 +143,7 @@
 			break;
 		}
 		if (runtime->avail < runtime->buffer_size && !timeout) {
-			snd_printk(KERN_WARNING "rawmidi drain error (avail = %li, buffer_size = %li)\n", runtime->avail, runtime->buffer_size);
+			snd_printk(KERN_WARNING "rawmidi drain error (avail = %i, buffer_size = %i)\n", runtime->avail, runtime->buffer_size);
 			err = -EIO;
 			break;
 		}
diff -Nru a/sound/core/seq/Makefile b/sound/core/seq/Makefile
--- a/sound/core/seq/Makefile	Sun Jun 16 19:31:41 2002
+++ b/sound/core/seq/Makefile	Sun Jun 16 19:31:41 2002
@@ -3,8 +3,6 @@
 # Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
 #
 
-mod-subdirs  := instr
-
 obj-$(CONFIG_SND) += instr/
 obj-$(CONFIG_SND_SEQUENCER_OSS) += oss/
 
diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
--- a/sound/core/seq/seq_clientmgr.c	Sun Jun 16 19:31:39 2002
+++ b/sound/core/seq/seq_clientmgr.c	Sun Jun 16 19:31:39 2002
@@ -469,7 +469,7 @@
 	if (! dest->accept_input)
 		goto __not_avail;
 	if ((dest->filter & SNDRV_SEQ_FILTER_USE_EVENT) &&
-	    ! test_bit(event->type, &dest->event_filter))
+	    ! test_bit(event->type, dest->event_filter))
 		goto __not_avail;
 	if (filter && !(dest->filter & filter))
 		goto __not_avail;
diff -Nru a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h
--- a/sound/core/seq/seq_clientmgr.h	Sun Jun 16 19:31:40 2002
+++ b/sound/core/seq/seq_clientmgr.h	Sun Jun 16 19:31:40 2002
@@ -53,8 +53,8 @@
 	char name[64];		/* client name */
 	int number;		/* client number */
 	unsigned int filter;	/* filter flags */
-	unsigned char client_filter[32];
-	unsigned char event_filter[32];
+	bitmap_member(client_filter, 256);
+	bitmap_member(event_filter, 256);
 	snd_use_lock_t use_lock;
 	int event_lost;
 	/* ports */
diff -Nru a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
--- a/sound/core/seq/seq_queue.c	Sun Jun 16 19:31:41 2002
+++ b/sound/core/seq/seq_queue.c	Sun Jun 16 19:31:41 2002
@@ -544,10 +544,10 @@
 		return -EINVAL;
 	down(&queue->timer_mutex);
 	if (use) {
-		if (!test_and_set_bit(client, &queue->clients_bitmap))
+		if (!test_and_set_bit(client, queue->clients_bitmap))
 			queue->clients++;
 	} else {
-		if (test_and_clear_bit(client, &queue->clients_bitmap))
+		if (test_and_clear_bit(client, queue->clients_bitmap))
 			queue->clients--;
 	}
 	if (queue->clients) {
@@ -575,7 +575,7 @@
 	q = queueptr(queueid);
 	if (q == NULL)
 		return -EINVAL; /* invalid queue */
-	result = test_bit(client, &q->clients_bitmap) ? 1 : 0;
+	result = test_bit(client, q->clients_bitmap) ? 1 : 0;
 	queuefree(q);
 	return result;
 }
diff -Nru a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
--- a/sound/core/seq/seq_queue.h	Sun Jun 16 19:31:40 2002
+++ b/sound/core/seq/seq_queue.h	Sun Jun 16 19:31:40 2002
@@ -51,7 +51,7 @@
 	spinlock_t check_lock;
 
 	/* clients which uses this queue (bitmap) */
-	unsigned int clients_bitmap[SNDRV_SEQ_MAX_CLIENTS/sizeof(unsigned long)];
+	bitmap_member(clients_bitmap,SNDRV_SEQ_MAX_CLIENTS);
 	unsigned int clients;	/* users of this queue */
 	struct semaphore timer_mutex;
 
diff -Nru a/sound/drivers/Makefile b/sound/drivers/Makefile
--- a/sound/drivers/Makefile	Sun Jun 16 19:31:41 2002
+++ b/sound/drivers/Makefile	Sun Jun 16 19:31:41 2002
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-mod-subdirs  := opl3 mpu401
-
 snd-dummy-objs := dummy.o
 snd-mtpav-objs := mtpav.o
 snd-serial-u16550-objs := serial-u16550.o
diff -Nru a/sound/i2c/Makefile b/sound/i2c/Makefile
--- a/sound/i2c/Makefile	Sun Jun 16 19:31:40 2002
+++ b/sound/i2c/Makefile	Sun Jun 16 19:31:40 2002
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-mod-subdirs := l3
-
 export-objs  := i2c.o cs8427.o tea6330t.o
 
 snd-i2c-objs := i2c.o
diff -Nru a/sound/isa/Makefile b/sound/isa/Makefile
--- a/sound/isa/Makefile	Sun Jun 16 19:31:39 2002
+++ b/sound/isa/Makefile	Sun Jun 16 19:31:39 2002
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-mod-subdirs  := ad1816a ad1848 cs423x es1688 gus opti9xx sb wavefront
-
 snd-als100-objs := als100.o
 snd-azt2320-objs := azt2320.o
 snd-cmi8330-objs := cmi8330.o
diff -Nru a/sound/pci/Makefile b/sound/pci/Makefile
--- a/sound/pci/Makefile	Sun Jun 16 19:31:39 2002
+++ b/sound/pci/Makefile	Sun Jun 16 19:31:39 2002
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-mod-subdirs  := ac97 ali5451 cs46xx emu10k1 korg1212 nm256 rme9652 trident ymfpci
-
 snd-als4000-objs := als4000.o
 snd-cmipci-objs := cmipci.o
 snd-cs4281-objs := cs4281.o
diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c	Sun Jun 16 19:31:39 2002
+++ b/sound/pci/emu10k1/emufx.c	Sun Jun 16 19:31:39 2002
@@ -29,6 +29,7 @@
 #include <sound/driver.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
diff -Nru a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
--- a/sound/pci/emu10k1/emumixer.c	Sun Jun 16 19:31:40 2002
+++ b/sound/pci/emu10k1/emumixer.c	Sun Jun 16 19:31:40 2002
@@ -29,6 +29,7 @@
 #define __NO_VERSION__
 #include <sound/driver.h>
 #include <linux/time.h>
+#include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
diff -Nru a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
--- a/sound/pci/emu10k1/emumpu401.c	Sun Jun 16 19:31:39 2002
+++ b/sound/pci/emu10k1/emumpu401.c	Sun Jun 16 19:31:39 2002
@@ -22,6 +22,7 @@
 #define __NO_VERSION__
 #include <sound/driver.h>
 #include <linux/time.h>
+#include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
--- a/sound/pci/emu10k1/emupcm.c	Sun Jun 16 19:31:39 2002
+++ b/sound/pci/emu10k1/emupcm.c	Sun Jun 16 19:31:39 2002
@@ -29,6 +29,7 @@
 #include <sound/driver.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
diff -Nru a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c	Sun Jun 16 19:31:40 2002
+++ b/sound/pci/emu10k1/emuproc.c	Sun Jun 16 19:31:40 2002
@@ -28,6 +28,7 @@
 #define __NO_VERSION__
 #include <sound/driver.h>
 #include <linux/slab.h>
+#include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
diff -Nru a/sound/synth/Makefile b/sound/synth/Makefile
--- a/sound/synth/Makefile	Sun Jun 16 19:31:39 2002
+++ b/sound/synth/Makefile	Sun Jun 16 19:31:39 2002
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-mod-subdirs  := emux
-
 export-objs  := util_mem.o
 
 snd-util-mem-objs := util_mem.o
