diff -Nru a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt
--- a/Documentation/usb/usb-serial.txt	Fri Sep 27 14:51:03 2002
+++ b/Documentation/usb/usb-serial.txt	Fri Sep 27 14:51:03 2002
@@ -41,17 +41,13 @@
 ConnectTech WhiteHEAT 4 port converter
 
   ConnectTech has been very forthcoming with information about their
-  device, including providing a unit to test with. This driver will end up
-  being fully supported.
+  device, including providing a unit to test with.
 
-  Current status:
-    The device's firmware is downloaded on connection, the new firmware 
-    runs properly and all four ports are successfully recognized and connected.
-    Data can be sent and received through the device on all ports.
-    Hardware flow control needs to be implemented.
+  The driver is officially supported by Connect Tech Inc.
+  http://www.connecttech.com
 
-  For any questions or problems with this driver, please contact Greg
-  Kroah-Hartman at greg@kroah.com
+  For any questions or problems with this driver, please contact
+  Stuart MacDonald at stuartm@connecttech.com
 
 
 HandSpring Visor, Palm USB, and Clié USB driver
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Fri Sep 27 14:51:04 2002
+++ b/MAINTAINERS	Fri Sep 27 14:51:04 2002
@@ -1132,7 +1132,6 @@
 P:	Networking Team
 M:	netdev@oss.sgi.com
 L:	linux-net@vger.kernel.org
-W:	http://www.uk.linux.org/NetNews.html (2.0 only)
 S:	Maintained
 
 NETWORKING [IPv4/IPv6]
@@ -1829,6 +1828,14 @@
 L:	linux-usb-devel@lists.sourceforge.net
 W:	http://www.kroah.com/linux/
 S:	Maintained
+
+USB SERIAL WHITEHEAT DRIVER
+P:	Stuart MacDonald
+M:	stuartm@connecttech.com
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.connecttech.com
+S:	Supported
 
 USB SUBSYSTEM
 P:	Greg Kroah-Hartman
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Fri Sep 27 14:51:03 2002
+++ b/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 38
+SUBLEVEL = 39
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -138,6 +138,7 @@
 MAKEFILES	= $(TOPDIR)/.config
 GENKSYMS	= /sbin/genksyms
 DEPMOD		= /sbin/depmod
+KALLSYMS	= /sbin/kallsyms
 PERL		= perl
 MODFLAGS	= -DMODULE
 CFLAGS_MODULE   = $(MODFLAGS)
@@ -172,6 +173,9 @@
 		    help tags TAGS sgmldocs psdocs pdfdocs htmldocs \
 		    checkconfig checkhelp checkincludes
 
+RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \) -prune -o
+RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS
+
 # Helpers built in scripts/
 # ---------------------------------------------------------------------------
 
@@ -291,32 +295,64 @@
 vmlinux-objs := $(HEAD) $(INIT) $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS)
 
 quiet_cmd_link_vmlinux = LD      $@
-cmd_link_vmlinux = $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $(HEAD) $(INIT) \
-		--start-group \
-		$(CORE_FILES) \
-		$(LIBS) \
-		$(DRIVERS) \
-		$(NETWORKS) \
-		--end-group \
-		-o vmlinux
+define cmd_link_vmlinux
+	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(HEAD) $(INIT) \
+	--start-group \
+	$(CORE_FILES) \
+	$(LIBS) \
+	$(DRIVERS) \
+	$(NETWORKS) \
+	--end-group \
+	$(filter $(kallsyms.o),$^) \
+	-o $@
+endef
 
 #	set -e makes the rule exit immediately on error
 
-define rule_link_vmlinux
+define rule_vmlinux
 	set -e
 	echo '  Generating build number'
-	. scripts/mkversion > .tmpversion
-	mv -f .tmpversion .version
+	. scripts/mkversion > .tmp_version
+	mv -f .tmp_version .version
 	+$(MAKE) -C init
 	$(call cmd,link_vmlinux)
 	echo 'cmd_$@ := $(cmd_link_vmlinux)' > $(@D)/.$(@F).cmd
-	$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
+	$(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
 endef
 
 LDFLAGS_vmlinux += -T arch/$(ARCH)/vmlinux.lds.s
 
-vmlinux: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE
-	$(call if_changed_rule,link_vmlinux)
+#	Generate section listing all symbols and add it into vmlinux
+
+ifdef CONFIG_KALLSYMS
+
+kallsyms.o := .tmp_kallsyms.o
+
+quiet_cmd_kallsyms = KSYM    $@
+cmd_kallsyms = $(KALLSYMS) $< > $@
+
+.tmp_kallsyms.o: .tmp_vmlinux
+	$(call cmd,kallsyms)
+
+# 	After generating .tmp_vmlinux just like vmlinux, decrement the version
+#	number again, so the final vmlinux gets the same one.
+#	Ignore return value of 'expr'.
+
+define rule_.tmp_vmlinux
+	$(rule_vmlinux)
+	if expr 0`cat .version` - 1 > .tmp_version; then true; fi
+	mv -f .tmp_version .version
+endef
+
+.tmp_vmlinux: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE
+	$(call if_changed_rule,.tmp_vmlinux)
+
+endif
+
+#	Finally the vmlinux rule
+
+vmlinux: $(vmlinux-objs) $(kallsyms.o) arch/$(ARCH)/vmlinux.lds.s FORCE
+	$(call if_changed_rule,vmlinux)
 
 #	The actual objects are generated when descending, 
 #	make sure no implicit rule kicks in
@@ -436,7 +472,8 @@
 	@( 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 SCCS -prune -o -name BitKeeper -prune -o -name \*.ver -print | sort`; do \
+	   cd .tmp_export-objs >/dev/null; \
+	   for f in `find modules -name \*.ver -print | sort`; do \
 	     echo "#include <linux/$${f}>"; \
 	   done; \
 	   echo "#endif"; \
@@ -547,13 +584,13 @@
 #	   will become invalid
 
 rpm:	clean spec
-	find . -name SCCS -prune -o -name BitKeeper -prune -o \
+	find . $(RCS_FIND_IGNORE) \
 		\( -size 0 -o -name .depend -o -name .hdepend \) \
 		-type f -print | xargs rm -f
 	set -e; \
 	cd $(TOPDIR)/.. ; \
 	ln -sf $(TOPDIR) $(KERNELPATH) ; \
-	tar -cvz --exclude CVS -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
+	tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
 	rm $(KERNELPATH) ; \
 	cd $(TOPDIR) ; \
 	. scripts/mkversion > .version ; \
@@ -683,7 +720,7 @@
 
 clean:	archclean
 	@echo 'Cleaning up'
-	@find . -name SCCS -prune -o -name BitKeeper -prune -o \
+	@find . $(RCS_FIND_IGNORE) \
 		\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
 		-name .\*.tmp -o -name .\*.d \) -type f -print \
 		| grep -v lxdialog/ | xargs rm -f
@@ -692,7 +729,7 @@
 
 mrproper: clean archmrproper
 	@echo 'Making mrproper'
-	@find . -name SCCS -prune -o -name BitKeeper -prune -o \
+	@find . $(RCS_FIND_IGNORE) \
 		\( -name .depend -o -name .\*.cmd \) \
 		-type f -print | xargs rm -f
 	@rm -f $(MRPROPER_FILES)
@@ -702,7 +739,7 @@
 
 distclean: mrproper
 	@echo 'Making distclean'
-	@find . -name SCCS -prune -o -name BitKeeper -prune -o \
+	@find . $(RCS_FIND_IGNORE) \
 		\( -not -type d \) -and \
 	 	\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
 		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
@@ -712,25 +749,38 @@
 # Generate tags for editors
 # ---------------------------------------------------------------------------
 
-TAGS: FORCE
-	{ find include/asm-${ARCH} -name SCCS -prune -o -name BitKeeper -prune \
-		-o -name '*.h' -print ; \
-	find include -name SCCS -prune -o -name BitKeeper -prune -o \
-		-type d \( -name "asm-*" -o -name config \) -prune -o \
-		-name '*.h' -print ; \
-	find $(SUBDIRS) init arch/${ARCH} \
-		-name SCCS -prune -o -name BitKeeper -prune -o \
-		-name '*.[chS]' -print ; } | grep -v SCCS | etags -
+define all-sources
+	( find . $(RCS_FIND_IGNORE) \
+	       \( -name include -o -name arch \) -prune -o \
+	       -name '*.[chS]' -print; \
+	  find arch/$(ARCH) $(RCS_FIND_IGNORE) \
+	       -name '*.[chS]' -print; \
+	  find include $(RCS_FIND_IGNORE) \
+	       \( -name config -o -name 'asm-*' \) -prune -o \
+	       -o -name '*.[chS]' -print; \
+	  find include/asm-$(ARCH) $(RCS_FIND_IGNORE) \
+	       -name '*.[chS]' -print; \
+	  find include/asm-generic $(RCS_FIND_IGNORE) \
+	       -name '*.[chS]' -print )
+endef
+
+quiet_cmd_TAGS = MAKE   $@
+cmd_TAGS = $(all-sources) | etags -
 
 # 	Exuberant ctags works better with -I
-tags: FORCE
+
+quiet_cmd_tags = MAKE   $@
+define cmd_tags
+	rm -f $@; \
 	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
-	ctags $$CTAGSF `find include/asm-$(ARCH) -name SCCS -prune -o -name BitKeeper -prune -o -name '*.h' -print` && \
-	find include -name SCCS -prune -o -name BitKeeper -prune -o \
-		-type d \( -name "asm-*" -o -name config \) -prune -o \
-		-name '*.h' -print | xargs ctags $$CTAGSF -a && \
-	find $(SUBDIRS) init -name SCCS -prune -o -name BitKeeper -prune -o \
-		-name '*.[ch]' -print | xargs ctags $$CTAGSF -a
+	$(all-sources) | xargs ctags $$CTAGSF -a
+endef
+
+TAGS: FORCE
+	$(call cmd,TAGS)
+
+tags: FORCE
+	$(call cmd,tags)
 
 # Brief documentation of the typical targets used
 # ---------------------------------------------------------------------------
@@ -778,17 +828,17 @@
 # ---------------------------------------------------------------------------
 
 checkconfig:
-	find * -name SCCS -prune -o -name BitKeeper -prune -o \
+	find * $(RCS_FIND_IGNORE) \
 		-name '*.[hcS]' -type f -print | sort \
 		| xargs $(PERL) -w scripts/checkconfig.pl
 
 checkhelp:
-	find * -name SCCS -prune -o -name BitKeeper -prune -o \
+	find * $(RCS_FIND_IGNORE) \
 		-name [cC]onfig.in -print | sort \
 		| xargs $(PERL) -w scripts/checkhelp.pl
 
 checkincludes:
-	find * -name SCCS -prune -o -name BitKeeper -prune -o \
+	find * $(RCS_FIND_IGNORE) \
 		-name '*.[hcS]' -type f -print | sort \
 		| xargs $(PERL) -w scripts/checkincludes.pl
 
@@ -806,7 +856,7 @@
 
 # FIXME Should go into a make.lib or something 
 # ===========================================================================
-echo_target = $(RELDIR)/$@
+echo_target = $@
 
 a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS) \
 	  $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
diff -Nru a/arch/alpha/Makefile b/arch/alpha/Makefile
--- a/arch/alpha/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/alpha/Makefile	Fri Sep 27 14:51:04 2002
@@ -91,15 +91,9 @@
 
 HEAD := arch/alpha/kernel/head.o
 
-SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/mm arch/alpha/lib \
-	arch/alpha/math-emu
-CORE_FILES := arch/alpha/kernel/kernel.o arch/alpha/mm/mm.o $(CORE_FILES)
-
-ifeq ($(CONFIG_MATHEMU),y)
-  CORE_FILES := $(CORE_FILES) arch/alpha/math-emu/built-in.o
-endif
-
-LIBS := $(TOPDIR)/arch/alpha/lib/lib.a $(LIBS) $(TOPDIR)/arch/alpha/lib/lib.a
+core-y			+= arch/alpha/kernel/ arch/alpha/mm/
+core-$(CONFIG_MATHEMU)  += arch/alpha/math-emu/
+libs-y			+= arch/alpha/lib/
 
 MAKEBOOT = $(MAKE) -C arch/alpha/boot
 
diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
--- a/arch/alpha/kernel/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/alpha/kernel/Makefile	Fri Sep 27 14:51:04 2002
@@ -2,7 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o
 
 EXTRA_AFLAGS	:= $(CFLAGS)
diff -Nru a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
--- a/arch/alpha/kernel/entry.S	Fri Sep 27 14:51:02 2002
+++ b/arch/alpha/kernel/entry.S	Fri Sep 27 14:51:02 2002
@@ -1119,3 +1119,27 @@
 	.quad sys_readahead
 	.quad sys_ni_syscall			/* 380, sys_security */
 	.quad sys_tkill
+	.quad sys_setxattr
+	.quad sys_lsetxattr
+	.quad sys_fsetxattr
+	.quad sys_getxattr
+	.quad sys_lgetxattr
+	.quad sys_fgetxattr
+	.quad sys_listxattr
+	.quad sys_llistxattr
+	.quad sys_flistxattr			/* 390 */
+	.quad sys_removexattr
+	.quad sys_lremovexattr
+	.quad sys_fremovexattr
+	.quad sys_futex
+	.quad sys_sched_setaffinity
+	.quad sys_sched_getaffinity
+	.quad sys_ni_syscall			/* 397, tux */
+	.quad sys_io_setup
+	.quad sys_io_destroy
+	.quad sys_io_getevents			/* 400 */
+	.quad sys_io_submit
+	.quad sys_io_cancel
+	.quad sys_ni_syscall			/* 403, sys_alloc_hugepages */
+	.quad sys_ni_syscall			/* 404, sys_free_hugepages */
+	.quad sys_exit_group
diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
--- a/arch/alpha/kernel/time.c	Fri Sep 27 14:51:04 2002
+++ b/arch/alpha/kernel/time.c	Fri Sep 27 14:51:04 2002
@@ -57,6 +57,8 @@
 
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 
+#define TICK_SIZE (tick_nsec / 1000)
+
 /*
  * Shift amount by which scaled_ticks_per_cycle is scaled.  Shifting
  * by 48 gives us 16 bits for HZ while keeping the accuracy good even
@@ -129,8 +131,8 @@
 	 */
 	if ((time_status & STA_UNSYNC) == 0
 	    && xtime.tv_sec > state.last_rtc_update + 660
-	    && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2
-	    && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	    && xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2
+	    && xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) {
 		int tmp = set_rtc_mmss(xtime.tv_sec);
 		state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0);
 	}
@@ -365,7 +367,7 @@
 		year += 100;
 
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-	xtime.tv_usec = 0;
+	xtime.tv_nsec = 0;
 
 	if (HZ > (1<<16)) {
 		extern void __you_loose (void);
@@ -414,7 +416,7 @@
 
 	delta_cycles = rpcc() - state.last_time;
 	sec = xtime.tv_sec;
-	usec = xtime.tv_usec;
+	usec = (xtime.tv_nsec / 1000);
 	partial_tick = state.partial_tick;
 	lost = jiffies - wall_jiffies;
 
@@ -485,7 +487,7 @@
 	}
 
 	xtime.tv_sec = sec;
-	xtime.tv_usec = usec;
+	xtime.tv_nsec = (usec / 1000);
 	time_adjust = 0;		/* stop active adjtime() */
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
diff -Nru a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
--- a/arch/alpha/lib/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/alpha/lib/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,7 +2,7 @@
 # Makefile for alpha-specific library files..
 #
 
-EXTRA_AFLAGS := $(CFLAGS)
+L_TARGET := lib.a
 
 # Many of these routines have implementations tuned for ev6.
 # Choose them iff we're targeting ev6 specifically.
@@ -17,7 +17,7 @@
   ev67 := ev67-
 endif
 
-OBJS =	__divqu.o __remqu.o __divlu.o __remlu.o \
+obj-y =	__divqu.o __remqu.o __divlu.o __remlu.o \
 	udelay.o \
 	$(ev6)memset.o \
 	$(ev6)memcpy.o \
@@ -46,12 +46,9 @@
 	fpreg.o \
 	callback_srm.o srm_puts.o srm_printk.o
 
-ifeq ($(CONFIG_SMP),y)
-  OBJS += dec_and_lock.o
-endif
+obj-$(CONFIG_SMP) += dec_and_lock.o
 
-lib.a: $(OBJS)
-	$(AR) rcs lib.a $(OBJS)
+include $(TOPDIR)/Rules.make
 
 __divqu.o: $(ev6)divide.S
 	$(CC) $(AFLAGS) -DDIV -c -o __divqu.o $(ev6)divide.S
@@ -64,5 +61,3 @@
 
 __remlu.o: $(ev6)divide.S
 	$(CC) $(AFLAGS) -DREM -DINTSIZE -c -o __remlu.o $(ev6)divide.S
-
-include $(TOPDIR)/Rules.make
diff -Nru a/arch/alpha/math-emu/Makefile b/arch/alpha/math-emu/Makefile
--- a/arch/alpha/math-emu/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/alpha/math-emu/Makefile	Fri Sep 27 14:51:02 2002
@@ -2,10 +2,8 @@
 # Makefile for the FPU instruction emulation.
 #
 
-obj-$(CONFIG_MATHEMU) += math-emu.o
-
-math-emu-objs	:= math.o qrnnd.o
-
 CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
+
+obj-$(CONFIG_MATHEMU) += math.o qrnnd.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile
--- a/arch/alpha/mm/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/alpha/mm/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the linux alpha-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET := mm.o
 
 obj-y	:= init.o fault.o extable.o
 
diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile
--- a/arch/arm/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/Makefile	Fri Sep 27 14:51:04 2002
@@ -165,29 +165,19 @@
 # Do we have FASTFPE?
 FASTFPE		:=arch/arm/fastfpe
 ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
-SUBDIRS		+=$(FASTFPE)
-FASTFPE_OBJ	:=$(FASTFPE)/fast-math-emu.o
+FASTFPE_OBJ	:=$(FASTFPE)/
 endif
 
 # If we have a machine-specific directory, then include it in the build.
-SUBDIRS		+=arch/arm/mach-$(MACHINE) \
-		  arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
-CORE_FILES	:=arch/arm/mach-$(MACHINE)/$(MACHINE).o \
-		  arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
-LIBS		:=arch/arm/lib/lib.a $(LIBS)
+core-y				+= arch/arm/mach-$(MACHINE)/ \
+				   arch/arm/kernel/ arch/arm/mm/
+core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwfpe/
+core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
 
-ifeq ($(CONFIG_FPE_NWFPE),y)
-LIBS		:=arch/arm/nwfpe/math-emu.o $(LIBS)
-endif
-
-ifeq ($(CONFIG_FPE_FASTFPE),y)
-LIBS		:=$(FASTFPE_OBJ) $(LIBS)
-endif
+drivers-$(CONFIG_ARCH_CLPS7500)	+= drivers/acorn/char/
+drivers-$(CONFIG_ARCH_L7200))	+= drivers/acorn/char/
 
-ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y)
-SUBDIRS		+=drivers/acorn/char
-DRIVERS		+=drivers/acorn/char/built-in.o
-endif
+libs-y				+= arch/arm/lib/
 
 MAKEBOOT	 =$(MAKE) -C arch/$(ARCH)/boot
 MAKETOOLS	 =$(MAKE) -C arch/$(ARCH)/tools
diff -Nru a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
--- a/arch/arm/kernel/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/kernel/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,8 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET := kernel.o
-
 ENTRY_OBJ = entry-$(PROCESSOR).o
 
 AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR)
diff -Nru a/arch/arm/mach-adifcc/Makefile b/arch/arm/mach-adifcc/Makefile
--- a/arch/arm/mach-adifcc/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/arm/mach-adifcc/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= adifcc.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-anakin/Makefile b/arch/arm/mach-anakin/Makefile
--- a/arch/arm/mach-anakin/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/mach-anakin/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= anakin.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-arc/Makefile b/arch/arm/mach-arc/Makefile
--- a/arch/arm/mach-arc/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/arm/mach-arc/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,8 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET		:= arc.o
-
 # Object file lists.
 
 obj-y			:= arch.o dma.o fault.o irq.o mm.o oldlatches.o \
diff -Nru a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile
--- a/arch/arm/mach-clps711x/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/mach-clps711x/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= clps711x.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-clps7500/Makefile b/arch/arm/mach-clps7500/Makefile
--- a/arch/arm/mach-clps7500/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/mach-clps7500/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= clps7500.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-ebsa110/Makefile b/arch/arm/mach-ebsa110/Makefile
--- a/arch/arm/mach-ebsa110/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/mach-ebsa110/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= ebsa110.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-epxa10db/Makefile b/arch/arm/mach-epxa10db/Makefile
--- a/arch/arm/mach-epxa10db/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/mach-epxa10db/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= epxa10db.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile
--- a/arch/arm/mach-footbridge/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/mach-footbridge/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= footbridge.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-ftvpci/Makefile b/arch/arm/mach-ftvpci/Makefile
--- a/arch/arm/mach-ftvpci/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/mach-ftvpci/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= ftvpci.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
--- a/arch/arm/mach-integrator/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/mach-integrator/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= integrator.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-iop310/Makefile b/arch/arm/mach-iop310/Makefile
--- a/arch/arm/mach-iop310/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/mach-iop310/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= iop310.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-l7200/Makefile b/arch/arm/mach-l7200/Makefile
--- a/arch/arm/mach-l7200/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/mach-l7200/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= l7200.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
--- a/arch/arm/mach-pxa/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/mach-pxa/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,16 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= pxa.o
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj-  :=
 
 export-objs := generic.o irq.o dma.o sa1111.o
 
diff -Nru a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile
--- a/arch/arm/mach-rpc/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/arm/mach-rpc/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= rpc.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
--- a/arch/arm/mach-sa1100/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/mach-sa1100/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,8 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET		:= sa1100.o
-
 # Common support (must be linked before board specific support)
 obj-y := generic.o irq.o dma.o
 obj-m :=
diff -Nru a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile
--- a/arch/arm/mach-shark/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/arm/mach-shark/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= shark.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mach-tbox/Makefile b/arch/arm/mach-tbox/Makefile
--- a/arch/arm/mach-tbox/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/arm/mach-tbox/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-O_TARGET		:= tbox.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
--- a/arch/arm/mm/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/arm/mm/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the linux arm-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET	:= mm.o
 
 # Object file lists.
 
diff -Nru a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile
--- a/arch/arm/nwfpe/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/arm/nwfpe/Makefile	Fri Sep 27 14:51:02 2002
@@ -2,8 +2,6 @@
 # Copyright (C) 1998, 1999, 2001 Philip Blundell
 #
 
-O_TARGET		:= math-emu.o
-
 obj-y			:=
 obj-m			:=
 obj-n			:=
diff -Nru a/arch/cris/Makefile b/arch/cris/Makefile
--- a/arch/cris/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/cris/Makefile	Fri Sep 27 14:51:04 2002
@@ -32,16 +32,16 @@
 
 HEAD := arch/cris/kernel/head.o
 
-SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers
 ifdef CONFIG_ETRAX_AXISFLASHMAP
 # only build this if axis flash map is used, because they depend on
 # each others config options
 SUBDIRS += arch/cris/boot/rescue
 endif
-CORE_FILES := arch/cris/kernel/kernel.o arch/cris/mm/mm.o $(CORE_FILES)
-DRIVERS += arch/cris/drivers/drivers.o
 LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a)
-LIBS := $(TOPDIR)/arch/cris/lib/lib.a $(LIBS) $(TOPDIR)/arch/cris/lib/lib.a $(LIBGCC)
+
+core-y		+= arch/cris/kernel/   arch/cris/mm/
+drivers-y	+= arch/cris/drivers/
+libs-y		+= arch/cris/lib/lib.a $(LIBGCC)
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
diff -Nru a/arch/cris/drivers/Makefile b/arch/cris/drivers/Makefile
--- a/arch/cris/drivers/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/cris/drivers/Makefile	Fri Sep 27 14:51:02 2002
@@ -2,11 +2,6 @@
 # Makefile for Etrax-specific drivers
 #
 
-O_TARGET := drivers.o
-
-obj-y :=
-
-
 obj-$(CONFIG_ETRAX_ETHERNET)            += ethernet.o
 obj-$(CONFIG_ETRAX_SERIAL)              += serial.o
 obj-$(CONFIG_ETRAX_IDE)                 += ide.o
@@ -18,10 +13,7 @@
 obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL)  += sync_serial.o
 obj-$(CONFIG_ETRAX_PARPORT)             += parport.o
 obj-$(CONFIG_ETRAX_DS1302)              += ds1302.o
-
-
-obj-$(CONFIG_ETRAX_ETHERNET_LPSLAVE)    += lpslave/lpslavedrivers.o
-subdir-$(CONFIG_ETRAX_ETHERNET_LPSLAVE) += lpslave
+obj-$(CONFIG_ETRAX_ETHERNET_LPSLAVE)    += lpslave
 
 include $(TOPDIR)/Rules.make
 
diff -Nru a/arch/cris/drivers/lpslave/Makefile b/arch/cris/drivers/lpslave/Makefile
--- a/arch/cris/drivers/lpslave/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/cris/drivers/lpslave/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,10 +2,7 @@
 # Makefile for parallel port slave drivers
 #
 
-O_TARGET := lpslavedrivers.o
-
 obj-y = e100lpslavenet.o e100lpslave_code.o
-
 
 include $(TOPDIR)/Rules.make
 
diff -Nru a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
--- a/arch/cris/kernel/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/cris/kernel/Makefile	Fri Sep 27 14:51:02 2002
@@ -3,7 +3,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o
 
 export-objs := ksyms.o
diff -Nru a/arch/cris/mm/Makefile b/arch/cris/mm/Makefile
--- a/arch/cris/mm/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/cris/mm/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,13 +1,7 @@
 #
 # Makefile for the linux cris-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
-O_TARGET := mm.o
 obj-y	 := init.o fault.o tlb.o extable.o ioremap.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/i386/Config.help b/arch/i386/Config.help
--- a/arch/i386/Config.help	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/Config.help	Fri Sep 27 14:51:03 2002
@@ -946,6 +946,11 @@
   of the BUG call as well as the EIP and oops trace.  This aids
   debugging but costs about 70-100K of memory.
 
+CONFIG_KALLSYMS
+  Say Y here to let the kernel print out symbolic crash information and
+  symbolic stack backtraces. This increases the size of the kernel
+  somewhat, as all symbols have to be loaded into the kernel image.
+
 CONFIG_DEBUG_OBSOLETE
   Say Y here if you want to reduce the chances of the tree compiling,
   and are prepared to dig into driver internals to fix compile errors.
diff -Nru a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
--- a/arch/i386/boot/compressed/misc.c	Fri Sep 27 14:51:04 2002
+++ b/arch/i386/boot/compressed/misc.c	Fri Sep 27 14:51:04 2002
@@ -121,7 +121,7 @@
 static int lines, cols;
 
 #ifdef CONFIG_MULTIQUAD
-static void * const xquad_portio = NULL;
+static void * xquad_portio = NULL;
 #endif
 
 #include "../../../../lib/inflate.c"
diff -Nru a/arch/i386/config.in b/arch/i386/config.in
--- a/arch/i386/config.in	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/config.in	Fri Sep 27 14:51:03 2002
@@ -260,7 +260,6 @@
    if [ "$CONFIG_SMP" = "y" ]; then
       define_bool CONFIG_X86_IO_APIC y
       define_bool CONFIG_X86_LOCAL_APIC y
-      define_bool CONFIG_X86_MPPARSE y
    fi
    bool 'PCI support' CONFIG_PCI
    if [ "$CONFIG_PCI" = "y" ]; then
@@ -436,11 +435,13 @@
    if [ "$CONFIG_HIGHMEM" = "y" ]; then
       bool '  Highmem debugging' CONFIG_DEBUG_HIGHMEM
    fi
+   bool '  Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
 fi
 
 if [ "$CONFIG_X86_LOCAL_APIC" = "y" ]; then
    define_bool CONFIG_X86_EXTRA_IRQS y
    define_bool CONFIG_X86_FIND_SMP_CONFIG y
+   define_bool CONFIG_X86_MPPARSE y
 fi
 
 endmenu
diff -Nru a/arch/i386/defconfig b/arch/i386/defconfig
--- a/arch/i386/defconfig	Fri Sep 27 14:51:04 2002
+++ b/arch/i386/defconfig	Fri Sep 27 14:51:04 2002
@@ -36,8 +36,8 @@
 # CONFIG_M586TSC is not set
 # CONFIG_M586MMX is not set
 # CONFIG_M686 is not set
-CONFIG_MPENTIUMIII=y
-# CONFIG_MPENTIUM4 is not set
+# CONFIG_MPENTIUMIII is not set
+CONFIG_MPENTIUM4=y
 # CONFIG_MK6 is not set
 # CONFIG_MK7 is not set
 # CONFIG_MELAN is not set
@@ -54,15 +54,16 @@
 CONFIG_X86_POPAD_OK=y
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_X86_L1_CACHE_SHIFT=5
+CONFIG_X86_L1_CACHE_SHIFT=7
 CONFIG_X86_TSC=y
 CONFIG_X86_GOOD_APIC=y
 CONFIG_X86_USE_PPRO_CHECKSUM=y
+# CONFIG_HUGETLB_PAGE is not set
 CONFIG_SMP=y
-# CONFIG_PREEMPT is not set
-# CONFIG_MULTIQUAD is not set
+CONFIG_PREEMPT=y
+# CONFIG_X86_NUMA is not set
 CONFIG_X86_MCE=y
-CONFIG_X86_MCE_NONFATAL=y
+# CONFIG_X86_MCE_NONFATAL is not set
 CONFIG_X86_MCE_P4THERMAL=y
 # CONFIG_TOSHIBA is not set
 # CONFIG_I8K is not set
@@ -73,7 +74,7 @@
 # CONFIG_HIGHMEM4G is not set
 # CONFIG_HIGHMEM64G is not set
 # CONFIG_MATH_EMULATION is not set
-# CONFIG_MTRR is not set
+CONFIG_MTRR=y
 CONFIG_HAVE_DEC_LOCK=y
 
 #
@@ -83,7 +84,25 @@
 #
 # ACPI Support
 #
-# CONFIG_ACPI is not set
+CONFIG_ACPI=y
+# CONFIG_ACPI_HT_ONLY is not set
+CONFIG_ACPI_BOOT=y
+# CONFIG_ACPI_SLEEP is not set
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_DEBUG=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI_SYSTEM=y
 CONFIG_PM=y
 # CONFIG_APM is not set
 
@@ -150,7 +169,7 @@
 # CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_SUNBPP is not set
 # CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
+CONFIG_PARPORT_1284=y
 
 #
 # Plug and Play configuration
@@ -188,23 +207,15 @@
 #
 # 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
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
 # CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
-CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 
 #
@@ -213,8 +224,8 @@
 CONFIG_BLK_DEV_CMD640=y
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
-CONFIG_BLK_DEV_RZ1000=y
 CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
@@ -223,31 +234,30 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_CMD680 is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-CONFIG_PIIX_TUNING=y
+# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_ADMA100 is not set
-# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
 # CONFIG_PDC202XX_FORCE is not set
 CONFIG_BLK_DEV_RZ1000=y
 # CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
@@ -291,8 +301,10 @@
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=64
+CONFIG_AIC7XXX_RESET_DELAY_MS=2000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -317,14 +329,7 @@
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_NCR53C8XX is not set
-CONFIG_SCSI_SYM53C8XX=y
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
-CONFIG_SCSI_NCR53C8XX_SYNC=20
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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
@@ -332,7 +337,7 @@
 # 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_QLOGIC_1280=y
 # CONFIG_SCSI_SEAGATE is not set
 # CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
@@ -408,6 +413,12 @@
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_LLC is not set
@@ -482,10 +493,11 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
+# CONFIG_SUNDANCE_MMIO is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
@@ -497,6 +509,7 @@
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000_NAPI is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -602,9 +615,6 @@
 # CONFIG_GAMEPORT_CS461x is not set
 CONFIG_SERIO=y
 CONFIG_SERIO_I8042=y
-CONFIG_I8042_REG_BASE=60
-CONFIG_I8042_KBD_IRQ=1
-CONFIG_I8042_AUX_IRQ=12
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PARKBD is not set
@@ -714,11 +724,11 @@
 CONFIG_AGP=y
 CONFIG_AGP_INTEL=y
 CONFIG_AGP_I810=y
-# CONFIG_AGP_VIA is not set
-# CONFIG_AGP_AMD is not set
-# CONFIG_AGP_SIS is not set
-# CONFIG_AGP_ALI is not set
-# CONFIG_AGP_SWORKS is not set
+CONFIG_AGP_VIA=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_SWORKS=y
 CONFIG_DRM=y
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_GAMMA is not set
@@ -748,7 +758,7 @@
 # CONFIG_QFMT_V2 is not set
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
-# 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
@@ -756,13 +766,13 @@
 # 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
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
@@ -770,7 +780,7 @@
 CONFIG_TMPFS=y
 CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_JFS_DEBUG is not set
@@ -791,10 +801,13 @@
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_UDF_FS=y
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
 
 #
 # Network File Systems
@@ -828,7 +841,49 @@
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Console drivers
@@ -925,13 +980,13 @@
 # CONFIG_SND_ALS4000 is not set
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_ENS1370 is not set
-CONFIG_SND_ENS1371=y
+# CONFIG_SND_ENS1371 is not set
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
 # CONFIG_SND_MAESTRO3 is not set
 # CONFIG_SND_FM801 is not set
 # CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_INTEL8X0 is not set
+CONFIG_SND_INTEL8X0=y
 # CONFIG_SND_SONICVIBES is not set
 # CONFIG_SND_VIA686 is not set
 # CONFIG_SND_VIA8233 is not set
@@ -945,17 +1000,17 @@
 #
 # Miscellaneous USB options
 #
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_LONG_TIMEOUT=y
+CONFIG_USB_BANDWIDTH=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 
 #
 # USB Host Controller Drivers
 #
-# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_UHCI_HCD_ALT is not set
+CONFIG_USB_UHCI_HCD_ALT=y
 
 #
 # USB Device Class drivers
@@ -1088,7 +1143,15 @@
 # Kernel hacking
 #
 # CONFIG_SOFTWARE_SUSPEND is not set
-# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_IOVIRT is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_KALLSYMS=y
+CONFIG_X86_EXTRA_IRQS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
 
 #
 # Security options
@@ -1101,3 +1164,6 @@
 # CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
diff -Nru a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
--- a/arch/i386/kernel/cpu/common.c	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/kernel/cpu/common.c	Fri Sep 27 14:51:03 2002
@@ -1,6 +1,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/cpu.h>
 #include <linux/smp.h>
 #include <asm/semaphore.h>
 #include <asm/processor.h>
@@ -506,3 +507,37 @@
 	current->used_math = 0;
 	stts();
 }
+
+/*
+ * Bulk registration of the cpu devices with the system.
+ * Some of this stuff could possibly be moved into a shared 
+ * location..
+ * Also, these devices should be integrated with other CPU data..
+ */
+
+static struct cpu cpu_devices[NR_CPUS];
+
+static struct device_driver cpu_driver = {
+	.name		= "cpu",
+	.bus		= &system_bus_type,
+	.devclass	= &cpu_devclass,
+};
+
+static int __init register_cpus(void)
+{
+	int i;
+
+	driver_register(&cpu_driver);
+
+	for (i = 0; i < NR_CPUS; i++) {
+		struct sys_device * sysdev = &cpu_devices[i].sysdev;
+		sysdev->name = "cpu";
+		sysdev->id = i;
+		sysdev->dev.driver = &cpu_driver;
+		if (cpu_possible(i))
+			sys_device_register(sysdev);
+	}
+	return 0;
+}
+
+subsys_initcall(register_cpus);
diff -Nru a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
--- a/arch/i386/kernel/head.S	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/kernel/head.S	Fri Sep 27 14:51:03 2002
@@ -121,7 +121,7 @@
  */
 	xorl %eax,%eax
 	movl $__bss_start,%edi
-	movl $_end,%ecx
+	movl $__bss_stop,%ecx
 	subl %edi,%ecx
 	rep
 	stosb
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c	Fri Sep 27 14:51:04 2002
+++ b/arch/i386/kernel/i386_ksyms.c	Fri Sep 27 14:51:04 2002
@@ -134,6 +134,7 @@
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(cpu_data);
 EXPORT_SYMBOL(cpu_online_map);
+EXPORT_SYMBOL(cpu_callout_map);
 EXPORT_SYMBOL_NOVERS(__write_lock_failed);
 EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
--- a/arch/i386/kernel/i8259.c	Fri Sep 27 14:51:05 2002
+++ b/arch/i386/kernel/i8259.c	Fri Sep 27 14:51:05 2002
@@ -246,22 +246,28 @@
 	return 0;
 }
 
-static struct device_driver driver_i8259A = {
+static struct device_driver i8259A_driver = {
+	.name		= "pic",
+	.bus		= &system_bus_type,
 	.resume		= i8259A_resume,
 };
 
-static struct device device_i8259A = {
-	.name	       	= "i8259A",
-	.bus_id		= "0020",
-	.driver		= &driver_i8259A,
+static struct sys_device device_i8259A = {
+	.name		= "pic",
+	.id		= 0,
+	.dev		= {
+		.name	= "i8259A PIC",
+		.driver	= &i8259A_driver,
+	},
 };
 
 static int __init init_8259A_devicefs(void)
 {
-	return register_sys_device(&device_i8259A);
+	driver_register(&i8259A_driver);
+	return sys_device_register(&device_i8259A);
 }
 
-__initcall(init_8259A_devicefs);
+device_initcall(init_8259A_devicefs);
 
 void init_8259A(int auto_eoi)
 {
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/kernel/mpparse.c	Fri Sep 27 14:51:03 2002
@@ -1019,10 +1019,39 @@
 
 /* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
 
+extern FADT_DESCRIPTOR acpi_fadt;
+
 void __init mp_config_ioapic_for_sci(int irq)
 {
 	int ioapic;
 	int ioapic_pin;
+	struct acpi_table_madt *madt;
+	struct acpi_table_int_src_ovr *entry = NULL;
+	void *madt_end;
+	acpi_status status;
+
+	/*
+	 * Ensure that if there is an interrupt source override entry
+	 * for the ACPI SCI, we leave it as is. Unfortunately this involves
+	 * walking the MADT again.
+	 */
+	status = acpi_get_firmware_table("APIC", 1, ACPI_LOGICAL_ADDRESSING,
+		(acpi_table_header **) &madt);
+	if (ACPI_SUCCESS(status)) {
+		madt_end = madt + madt->header.length;
+
+		entry = (struct acpi_table_int_src_ovr *)
+                ((unsigned long) madt + sizeof(struct acpi_table_madt));
+
+		while ((void *) entry < madt_end) {
+                	if (entry->header.type == ACPI_MADT_INT_SRC_OVR &&
+			    acpi_fadt.sci_int == entry->global_irq)
+                		return;
+
+                	entry = (struct acpi_table_int_src_ovr *)
+                	        ((unsigned long) entry + entry->header.length);
+        	}
+	}
 
 	ioapic = mp_find_ioapic(irq);
 
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Fri Sep 27 14:51:02 2002
+++ b/arch/i386/kernel/process.c	Fri Sep 27 14:51:02 2002
@@ -33,6 +33,7 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/mc146818rtc.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -155,8 +156,6 @@
 
 __setup("idle=", idle_setup);
 
-extern void show_trace(unsigned long* esp);
-
 void show_regs(struct pt_regs * regs)
 {
 	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
@@ -164,6 +163,8 @@
 	printk("\n");
 	printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
 	printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, smp_processor_id());
+	print_symbol("EIP is at %s\n", regs->eip);
+
 	if (regs->xcs & 3)
 		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
 	printk(" EFLAGS: %08lx    %s\n",regs->eflags, print_tainted());
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Fri Sep 27 14:51:04 2002
+++ b/arch/i386/kernel/smpboot.c	Fri Sep 27 14:51:04 2002
@@ -1060,11 +1060,11 @@
         if (clustered_apic_mode && (numnodes > 1)) {
                 printk("Remapping cross-quad port I/O for %d quads\n",
 			numnodes);
+                xquad_portio = ioremap (XQUAD_PORTIO_BASE, 
+			numnodes * XQUAD_PORTIO_QUAD);
                 printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
                         (u_long) xquad_portio, 
-			(u_long) numnodes * XQUAD_PORTIO_LEN);
-                xquad_portio = ioremap (XQUAD_PORTIO_BASE, 
-			numnodes * XQUAD_PORTIO_LEN);
+			(u_long) numnodes * XQUAD_PORTIO_QUAD);
         }
 
 	/*
diff -Nru a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
--- a/arch/i386/kernel/sys_i386.c	Fri Sep 27 14:51:04 2002
+++ b/arch/i386/kernel/sys_i386.c	Fri Sep 27 14:51:04 2002
@@ -272,10 +272,9 @@
 			return -ENOMEM;
 		if (!vma || ((addr + len) < vma->vm_start))
 			goto found_addr;
-		addr = vma->vm_end;
+		addr = HPAGE_ALIGN(vma->vm_end);
 	}
 found_addr:
-	addr = HPAGE_ALIGN(addr);
 	return addr;
 }
 
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c	Fri Sep 27 14:51:04 2002
+++ b/arch/i386/kernel/time.c	Fri Sep 27 14:51:04 2002
@@ -588,17 +588,20 @@
 }
 #endif /* CONFIG_X86_TSC */
 
-static struct device device_i8253 = {
-	.name	       	= "i8253",
-	.bus_id		= "0040",
+static struct sys_device device_i8253 = {
+	.name		= "rtc",
+	.id		= 0,
+	.dev	= {
+		.name	= "i8253 Real Time Clock",
+	},
 };
 
-static int time_init_driverfs(void)
+static int time_init_device(void)
 {
-	return register_sys_device(&device_i8253);
+	return sys_device_register(&device_i8253);
 }
 
-__initcall(time_init_driverfs);
+device_initcall(time_init_device);
 
 void __init time_init(void)
 {
diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
--- a/arch/i386/kernel/traps.c	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/kernel/traps.c	Fri Sep 27 14:51:03 2002
@@ -94,7 +94,6 @@
 
 #ifdef CONFIG_MODULES
 
-extern struct module *module_list;
 extern struct module kernel_module;
 
 static inline int kernel_text_address(unsigned long addr)
@@ -137,15 +136,16 @@
 	if (!stack)
 		stack = (unsigned long*)&stack;
 
-	printk("Call Trace: ");
+	printk("Call Trace:");
+#if CONFIG_KALLSYMS
+	printk("\n");
+#endif
 	i = 1;
 	while (((long) stack & (THREAD_SIZE-1)) != 0) {
 		addr = *stack++;
 		if (kernel_text_address(addr)) {
-			if (i && ((i % 6) == 0))
-				printk("\n   ");
-			printk("[<%08lx>] ", addr);
-			i++;
+			printk(" [<%08lx>]", addr);
+			print_symbol("%s\n", addr);
 		}
 	}
 	printk("\n");
@@ -206,8 +206,11 @@
 		esp = regs->esp;
 		ss = regs->xss & 0xffff;
 	}
+	print_modules();
 	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
 		smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
+
+	print_symbol("EIP is at %s\n", regs->eip);
 	printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
 		regs->eax, regs->ebx, regs->ecx, regs->edx);
 	printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
@@ -225,7 +228,7 @@
 		printk("\nStack: ");
 		show_stack((unsigned long*)esp);
 
-		printk("\nCode: ");
+		printk("Code: ");
 		if(regs->eip < PAGE_OFFSET)
 			goto bad;
 
@@ -268,6 +271,7 @@
 		(unsigned long)file < PAGE_OFFSET || __get_user(c, file))
 		file = "<bad filename>";
 
+	printk("------------[ cut here ]------------\n");
 	printk("kernel BUG at %s:%d!\n", file, line);
 
 no_bug:
diff -Nru a/arch/i386/mach-generic/Makefile b/arch/i386/mach-generic/Makefile
--- a/arch/i386/mach-generic/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/mach-generic/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,14 +1,8 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
 EXTRA_CFLAGS	+= -I../kernel
-export-objs     := 
 
 obj-y				:= setup.o
 
diff -Nru a/arch/i386/mach-visws/Makefile b/arch/i386/mach-visws/Makefile
--- a/arch/i386/mach-visws/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/i386/mach-visws/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,20 +1,8 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
-.S.o:
-	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
-
-all: mach-visws.o
-
-O_TARGET 	:= mach-visws.o
 EXTRA_CFLAGS	+= -I../kernel
-export-objs     := 
 
 obj-y				:= setup.o traps.o
 
diff -Nru a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S
--- a/arch/i386/vmlinux.lds.S	Fri Sep 27 14:51:03 2002
+++ b/arch/i386/vmlinux.lds.S	Fri Sep 27 14:51:03 2002
@@ -78,9 +78,13 @@
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
 
   __bss_start = .;		/* BSS */
-  .bss : {
-	*(.bss)
-	}
+  .bss : { *(.bss) }
+  __bss_stop = .; 
+
+  __start___kallsyms = .;     /* All kernel symbols */
+  __kallsyms : { *(__kallsyms) }
+  __stop___kallsyms = .;
+
   _end = . ;
 
   /* Sections to be discarded */
diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile
--- a/arch/ia64/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/ia64/Makefile	Fri Sep 27 14:51:02 2002
@@ -33,58 +33,20 @@
 	CFLAGS += -mb-step
 endif
 
-ifdef CONFIG_IA64_GENERIC
-	CORE_FILES      :=      arch/$(ARCH)/hp/hp.o			\
-				arch/$(ARCH)/dig/dig.a			\
-				$(CORE_FILES)
-	SUBDIRS		:=	arch/$(ARCH)/hp		\
-				arch/$(ARCH)/dig	\
-				$(SUBDIRS)
-
-else # !GENERIC
-
-ifdef CONFIG_IA64_HP_SIM
-        SUBDIRS         :=      arch/$(ARCH)/hp		\
-                                $(SUBDIRS)
-        CORE_FILES      :=      arch/$(ARCH)/hp/hp.o	\
-                                $(CORE_FILES)
-endif
+HEAD := arch/$(ARCH)/kernel/head.o arch/ia64/kernel/init_task.o
 
-ifdef CONFIG_IA64_HP_ZX1
-        SUBDIRS         :=      arch/$(ARCH)/hp				\
-				arch/$(ARCH)/dig			\
-                                $(SUBDIRS)
-        CORE_FILES      :=      arch/$(ARCH)/hp/hp.o			\
-				arch/$(ARCH)/dig/dig.a			\
-                                $(CORE_FILES)
-endif
+core-$(CONFIG_IA64_GENERIC) 	+= arch/$(ARCH)/hp/	  arch/$(ARCH)/dig/
+core-$(CONFIG_IA64_HP_SIM)	+= arch/$(ARCH)/hp/
+core-$(CONFIG_IA64_HP_ZX1)	+= arch/$(ARCH)/hp/ 	  arch/$(ARCH)/dig/
+core-$(CONFIG_IA64_SGI_SN)	+= arch/$(ARCH)/sn/kernel arch/$(ARCH)/sn/io
+core-$(CONFIG_IA64_DIG) 	+= arch/$(ARCH)/dig/
 
 ifdef CONFIG_IA64_SGI_SN
-	CFLAGS		+= -DBRINGUP
-        SUBDIRS         :=      arch/$(ARCH)/sn/kernel	\
-				arch/$(ARCH)/sn/io	\
-				arch/$(ARCH)/sn/fakeprom	\
-				$(SUBDIRS)
-        CORE_FILES      :=      arch/$(ARCH)/sn/kernel/sn.o	\
-				arch/$(ARCH)/sn/io/sgiio.o	\
-				$(CORE_FILES)
+	CFLAGS			+= -DBRINGUP
+        SUBDIRS         	+= arch/$(ARCH)/sn/fakeprom
 endif
 
-ifdef CONFIG_IA64_DIG
-        SUBDIRS         :=      arch/$(ARCH)/dig	\
-				$(SUBDIRS)
-        CORE_FILES      :=      arch/$(ARCH)/dig/dig.a	\
-				$(CORE_FILES)
-endif
-
-endif # !GENERIC
-
-ifdef CONFIG_IA32_SUPPORT
-	SUBDIRS		:=	arch/$(ARCH)/ia32 $(SUBDIRS)
-	CORE_FILES	:=	arch/$(ARCH)/ia32/ia32.o $(CORE_FILES)
-endif
-
-HEAD := arch/$(ARCH)/kernel/head.o arch/ia64/kernel/init_task.o
+core-$(CONFIG_IA32_SUPPORT)	+= arch/$(ARCH)/ia32/
 
 libs-y				+= arch/$(ARCH)/lib/
 core-y				+= arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
diff -Nru a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile
--- a/arch/ia64/dig/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ia64/dig/Makefile	Fri Sep 27 14:51:03 2002
@@ -5,8 +5,6 @@
 # Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
 #
 
-O_TARGET := dig.a
-
 obj-y := setup.o
 obj-$(CONFIG_IA64_GENERIC) += machvec.o
 
diff -Nru a/arch/ia64/hp/Makefile b/arch/ia64/hp/Makefile
--- a/arch/ia64/hp/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ia64/hp/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,14 +1,7 @@
 # arch/ia64/hp/Makefile
 # Copyright (c) 2002 Matthew Wilcox for Hewlett Packard
 
-ALL_SUB_DIRS := sim zx1 common
-
-O_TARGET := hp.o
-
-subdir-$(CONFIG_IA64_GENERIC) += $(ALL_SUB_DIRS)
-subdir-$(CONFIG_IA64_HP_SIM) += sim
-
-SUB_DIRS := $(subdir-y)
-obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
+obj-$(CONFIG_IA64_GENERIC)	+= sim/ zx1/ common/
+obj-$(CONFIG_IA64_HP_SIM)	+= sim/
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/ia64/hp/sim/Makefile b/arch/ia64/hp/sim/Makefile
--- a/arch/ia64/hp/sim/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ia64/hp/sim/Makefile	Fri Sep 27 14:51:04 2002
@@ -7,8 +7,6 @@
 # Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
 #
 
-O_TARGET := sim.o
-
 obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
 obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
 
diff -Nru a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile
--- a/arch/ia64/ia32/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ia64/ia32/Makefile	Fri Sep 27 14:51:04 2002
@@ -2,8 +2,6 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-O_TARGET := ia32.o
-
 obj-y := ia32_entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o ia32_support.o ia32_traps.o \
 	 binfmt_elf32.o ia32_ldt.o
 
diff -Nru a/arch/ia64/sn/io/Makefile b/arch/ia64/sn/io/Makefile
--- a/arch/ia64/sn/io/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ia64/sn/io/Makefile	Fri Sep 27 14:51:03 2002
@@ -15,11 +15,7 @@
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-O_TARGET := sgiio.o
-
-ifeq ($(CONFIG_MODULES),y)
 export-objs = pciio.o hcl.o
-endif
 
 obj-y  := stubs.o sgi_if.o pciio.o xtalk.o xbow.o xswitch.o klgraph_hack.o \
 		hcl.o labelcl.o invent.o klgraph.o klconflib.o sgi_io_sim.o \
diff -Nru a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
--- a/arch/ia64/sn/kernel/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ia64/sn/kernel/Makefile	Fri Sep 27 14:51:03 2002
@@ -33,22 +33,11 @@
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-O_TARGET        = sn.o
-
-ifeq ($(CONFIG_MODULES),y)
-export-objs = sn_ksyms.o
-endif
-
-subdir-$(CONFIG_IA64_SGI_SN1)	= sn1
-subdir-$(CONFIG_IA64_SGI_SN2)	= sn2
+export-objs 	:= sn_ksyms.o
 
 obj-y		= probe.o setup.o sn_asm.o sv.o bte.o
-obj-$(CONFIG_IA64_SGI_SN1)      += irq.o mca.o
-obj-$(CONFIG_IA64_SGI_SN2)      += irq.o mca.o
-
-obj-$(CONFIG_IA64_SGI_SN1)      += sn1/sn1.a  
-obj-$(CONFIG_IA64_SGI_SN2)      += sn2/sn2.a  
-
+obj-$(CONFIG_IA64_SGI_SN1)      += irq.o mca.o sn1/
+obj-$(CONFIG_IA64_SGI_SN2)      += irq.o mca.o sn2/
 obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
 obj-$(CONFIG_MODULES)           += sn_ksyms.o
diff -Nru a/arch/ia64/sn/kernel/sn1/Makefile b/arch/ia64/sn/kernel/sn1/Makefile
--- a/arch/ia64/sn/kernel/sn1/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ia64/sn/kernel/sn1/Makefile	Fri Sep 27 14:51:04 2002
@@ -32,8 +32,6 @@
 # http://oss.sgi.com/projects/GenInfo/NoticeExplan
 #
 
-O_TARGET := sn1.a
-
 obj-y := cache.o error.o iomv.o synergy.o sn1_smp.o
 
 EXTRA_CFLAGS := -DLITTLE_ENDIAN
diff -Nru a/arch/ia64/sn/kernel/sn2/Makefile b/arch/ia64/sn/kernel/sn2/Makefile
--- a/arch/ia64/sn/kernel/sn2/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ia64/sn/kernel/sn2/Makefile	Fri Sep 27 14:51:05 2002
@@ -32,8 +32,6 @@
 # http://oss.sgi.com/projects/GenInfo/NoticeExplan
 #
 
-O_TARGET := sn2.a
-
 obj-y := cache.o iomv.o sn2_smp.o
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
diff -Nru a/arch/m68k/Makefile b/arch/m68k/Makefile
--- a/arch/m68k/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/m68k/Makefile	Fri Sep 27 14:51:05 2002
@@ -58,79 +58,23 @@
 HEAD := arch/m68k/kernel/sun3-head.o
 endif 
 
-SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib
-CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES)
-LIBS += arch/m68k/lib/lib.a
+core-y				+= arch/m68k/kernel/	arch/m68k/mm/
+libs-y				+= arch/m68k/lib/
 
-ifdef CONFIG_Q40
-CORE_FILES := $(CORE_FILES) arch/m68k/q40/q40.o
-SUBDIRS := $(SUBDIRS) arch/m68k/q40
-endif
-
-ifdef CONFIG_AMIGA
-CORE_FILES := $(CORE_FILES) arch/m68k/amiga/amiga.o
-SUBDIRS := $(SUBDIRS) arch/m68k/amiga
-endif
-
-ifdef CONFIG_ATARI
-CORE_FILES := $(CORE_FILES) arch/m68k/atari/atari.o
-SUBDIRS := $(SUBDIRS) arch/m68k/atari
-endif
-
-ifdef CONFIG_MAC
-CORE_FILES := $(CORE_FILES) arch/m68k/mac/mac.o
-SUBDIRS := $(SUBDIRS) arch/m68k/mac
-endif
-
-ifdef CONFIG_HP300
-CORE_FILES := $(CORE_FILES) arch/m68k/hp300/hp300.o
-SUBDIRS := $(SUBDIRS) arch/m68k/hp300
-endif
-
-ifdef CONFIG_APOLLO
-CORE_FILES := $(CORE_FILES) arch/m68k/apollo/apollo.o
-SUBDIRS := $(SUBDIRS) arch/m68k/apollo
-endif
-
-ifdef CONFIG_MVME147
-CORE_FILES := $(CORE_FILES) arch/m68k/mvme147/mvme147.o
-SUBDIRS := $(SUBDIRS) arch/m68k/mvme147
-endif
-
-ifdef CONFIG_MVME16x
-CORE_FILES := $(CORE_FILES) arch/m68k/mvme16x/mvme16x.o
-SUBDIRS := $(SUBDIRS) arch/m68k/mvme16x
-endif
-
-ifdef CONFIG_BVME6000
-CORE_FILES := $(CORE_FILES) arch/m68k/bvme6000/bvme6000.o
-SUBDIRS := $(SUBDIRS) arch/m68k/bvme6000
-endif
-
-ifdef CONFIG_SUN3X
-CORE_FILES := $(CORE_FILES) arch/m68k/sun3x/sun3x.o arch/m68k/sun3/sun3.o
-SUBDIRS := $(SUBDIRS) arch/m68k/sun3x arch/m68k/sun3
-endif
-
-ifdef CONFIG_SUN3
-CORE_FILES := $(CORE_FILES) arch/m68k/sun3/sun3.o arch/m68k/sun3/prom/promlib.a
-SUBDIRS := $(SUBDIRS) arch/m68k/sun3 arch/m68k/sun3/prom
-endif
-
-ifdef CONFIG_M68040
-CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o
-SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
-endif
-
-ifdef CONFIG_M68060
-CORE_FILES := $(CORE_FILES) arch/m68k/ifpsp060/ifpsp.o
-SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060
-endif
-
-ifdef CONFIG_M68KFPU_EMU
-CORE_FILES := $(CORE_FILES) arch/m68k/math-emu/mathemu.o
-SUBDIRS := $(SUBDIRS) arch/m68k/math-emu
-endif
+core-$(CONFIG_Q40)		+= arch/m68k/q40/
+core-$(CONFIG_AMIGA)		+= arch/m68k/amiga/
+core-$(CONFIG_ATARI)		+= arch/m68k/atari/
+core-$(CONFIG_MAC)		+= arch/m68k/mac/
+core-$(CONFIG_HP300)		+= arch/m68k/hp300/
+core-$(CONFIG_APOLLO)		+= arch/m68k/apollo/
+core-$(CONFIG_MVME147)		+= arch/m68k/mvme147/
+core-$(CONFIG_MVME16x)		+= arch/m68k/mvme16x/
+core-$(CONFIG_BVME6000)		+= arch/m68k/bvme6000/
+core-$(CONFIG_SUN3X)		+= arch/m68k/sun3x/	arch/m68k/sun3/
+core-$(CONFIG_SUN3)		+= arch/m68k/sun3/	arch/m68k/sun3/prom/
+core-$(CONFIG_M68040)		+= arch/m68k/fpsp040/
+core-$(CONFIG_M68060)		+= arch/m68k/ifpsp060/
+core-$(CONFIG_M68KFPU_EMU)	+= arch/m68k/math-emu/
 
 lilo:	vmlinux
 	if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
diff -Nru a/arch/m68k/amiga/Makefile b/arch/m68k/amiga/Makefile
--- a/arch/m68k/amiga/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/m68k/amiga/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/amiga source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := amiga.o
 
 export-objs	:= amiga_ksyms.o
 
diff -Nru a/arch/m68k/apollo/Makefile b/arch/m68k/apollo/Makefile
--- a/arch/m68k/apollo/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/m68k/apollo/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/amiga source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := apollo.o
 
 obj-y		:= config.o dn_ints.o dma.o
 
diff -Nru a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
--- a/arch/m68k/atari/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/m68k/atari/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/atari source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := atari.o
 
 export-objs	:= atari_ksyms.o
 
diff -Nru a/arch/m68k/bvme6000/Makefile b/arch/m68k/bvme6000/Makefile
--- a/arch/m68k/bvme6000/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/m68k/bvme6000/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/bvme6000 source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := bvme6000.o
 
 obj-y		:= config.o bvmeints.o rtc.o
 
diff -Nru a/arch/m68k/fpsp040/Makefile b/arch/m68k/fpsp040/Makefile
--- a/arch/m68k/fpsp040/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/m68k/fpsp040/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,8 +2,6 @@
 # Makefile for Linux arch/m68k/fpsp040 source directory
 #
 
-O_TARGET := fpsp.o
-
 obj-y    := bindec.o binstr.o decbin.o do_func.o gen_except.o get_op.o \
 	    kernel_ex.o res_func.o round.o sacos.o sasin.o satan.o satanh.o \
 	    scosh.o setox.o sgetem.o sint.o slog2.o slogn.o \
diff -Nru a/arch/m68k/hp300/Makefile b/arch/m68k/hp300/Makefile
--- a/arch/m68k/hp300/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/m68k/hp300/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/hp300 source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := hp300.o
 
 obj-y		:= ksyms.o config.o ints.o time.o reboot.o
 
diff -Nru a/arch/m68k/ifpsp060/Makefile b/arch/m68k/ifpsp060/Makefile
--- a/arch/m68k/ifpsp060/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/m68k/ifpsp060/Makefile	Fri Sep 27 14:51:03 2002
@@ -4,8 +4,6 @@
 # License.  See the file "README.legal" in the main directory of this archive
 # for more details.
 
-O_TARGET := ifpsp.o
-
 obj-y := fskeleton.o iskeleton.o os.o
 
 EXTRA_AFLAGS := -traditional
diff -Nru a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
--- a/arch/m68k/kernel/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/m68k/kernel/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,8 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET := kernel.o
-
 ifndef CONFIG_SUN3
   EXTRA_TARGETS := head.o
 else
diff -Nru a/arch/m68k/mac/Makefile b/arch/m68k/mac/Makefile
--- a/arch/m68k/mac/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/m68k/mac/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/mac source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := mac.o
 
 export-objs	:= mac_ksyms.o
 
diff -Nru a/arch/m68k/math-emu/Makefile b/arch/m68k/math-emu/Makefile
--- a/arch/m68k/math-emu/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/m68k/math-emu/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,18 +1,11 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
 EXTRA_AFLAGS := -traditional
 
 #EXTRA_AFLAGS += -DFPU_EMU_DEBUG
 #EXTRA_CFLAGS += -DFPU_EMU_DEBUG
-
-O_TARGET := mathemu.o
 
 obj-y		:= fp_entry.o fp_scan.o fp_util.o fp_move.o fp_movem.o \
 			fp_cond.o fp_arith.o fp_log.o fp_trig.o
diff -Nru a/arch/m68k/mm/Makefile b/arch/m68k/mm/Makefile
--- a/arch/m68k/mm/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/m68k/mm/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the linux m68k-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET := mm.o
 
 obj-y		:= init.o fault.o extable.o hwtest.o
 
diff -Nru a/arch/m68k/mvme147/Makefile b/arch/m68k/mvme147/Makefile
--- a/arch/m68k/mvme147/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/m68k/mvme147/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,12 +1,6 @@
 #
 # Makefile for Linux arch/m68k/mvme147 source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-O_TARGET := mvme147.o
 
 obj-y		:= config.o 147ints.o
 
diff -Nru a/arch/m68k/mvme16x/Makefile b/arch/m68k/mvme16x/Makefile
--- a/arch/m68k/mvme16x/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/m68k/mvme16x/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/mvme16x source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := mvme16x.o
 
 export-objs	:= mvme16x_ksyms.o
 
diff -Nru a/arch/m68k/q40/Makefile b/arch/m68k/q40/Makefile
--- a/arch/m68k/q40/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/m68k/q40/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/q40 source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := q40.o
 
 obj-y		:= config.o q40ints.o 
 
diff -Nru a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile
--- a/arch/m68k/sun3/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/m68k/sun3/Makefile	Fri Sep 27 14:51:02 2002
@@ -1,13 +1,6 @@
-q#
-# Makefile for Linux arch/m68k/sun3 source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
+# Makefile for Linux arch/m68k/sun3 source directory
 #
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := sun3.o 
 
 export-objs	:= sun3_ksyms.o
 
diff -Nru a/arch/m68k/sun3/prom/Makefile b/arch/m68k/sun3/prom/Makefile
--- a/arch/m68k/sun3/prom/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/m68k/sun3/prom/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,21 +2,8 @@
 # Makefile for the Sun Boot PROM interface library under
 # Linux.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
-OBJS  = init.o console.o printf.o  misc.o
+obj-y := init.o console.o printf.o  misc.o
 #bootstr.o init.o misc.o segment.o console.o printf.o
-all: promlib.a
-
-promlib.a: $(OBJS)
-	$(AR) rcs promlib.a $(OBJS)
-	sync
-
-dep:
-	$(CPP) $(CPPFLAGS) -M *.c > .depend
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/m68k/sun3x/Makefile b/arch/m68k/sun3x/Makefile
--- a/arch/m68k/sun3x/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/m68k/sun3x/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/sun3x source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := sun3x.o
 
 export-objs	:= sun3x_ksyms.o
 
diff -Nru a/arch/mips/Makefile b/arch/mips/Makefile
--- a/arch/mips/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/mips/Makefile	Fri Sep 27 14:51:02 2002
@@ -94,85 +94,76 @@
 #
 # We unconditionally build the math emulator
 #
-CORE_FILES	+=arch/mips/math-emu/fpu_emulator.o
-SUBDIRS		+=arch/mips/math-emu
+core-y		+= arch/mips/math-emu/
 
 #
 # Board-dependent options and extra files
 #
 ifdef CONFIG_ALGOR_P4032
-CORE_FILES    += arch/mips/algor/algor.o
-SUBDIRS       += arch/mips/algor
-LOADADDR      += 0x80000000
+core-y		+= arch/mips/algor/
+LOADADDR	+= 0x80000000
 endif
 
 #
 # DECstation family
 #
 ifdef CONFIG_DECSTATION
-CORE_FILES    += arch/mips/dec/dec.o
-SUBDIRS       += arch/mips/dec arch/mips/dec/prom
-LIBS          += arch/mips/dec/prom/lib.a
-LOADADDR      += 0x80040000
+core-y		+= arch/mips/dec/
+libs-y          += arch/mips/dec/prom/
+LOADADDR	+= 0x80040000
 endif
 
 ifdef CONFIG_MIPS_ATLAS
-LIBS          += arch/mips/mips-boards/atlas/atlas.o arch/mips/mips-boards/generic/mipsboards.o
-SUBDIRS       += arch/mips/mips-boards/generic arch/mips/mips-boards/atlas
-LOADADDR      += 0x80100000
+core-y		+= arch/mips/mips-boards/atlas/ arch/mips/mips-boards/generic/
+LOADADDR	+= 0x80100000
 endif
 
 ifdef CONFIG_MIPS_MALTA
-LIBS          += arch/mips/mips-boards/malta/malta.o arch/mips/mips-boards/generic/mipsboards.o
-SUBDIRS       += arch/mips/mips-boards/malta arch/mips/mips-boards/generic
-LOADADDR      += 0x80100000
+core-y          += arch/mips/mips-boards/malta/ arch/mips/mips-boards/generic/
+LOADADDR	+= 0x80100000
 endif
 
 #
 # Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
 #
 ifdef CONFIG_MIPS_JAZZ
-CORE_FILES    += arch/mips/jazz/jazz.o
-SUBDIRS       += arch/mips/jazz arch/mips/arc
-LIBS          += arch/mips/arc/lib.a
-LOADADDR      += 0x80080000
+core-y		+= arch/mips/jazz/
+libs-y		+= arch/mips/arc/
+LOADADDR	+= 0x80080000
 endif
 
 ifdef CONFIG_SNI_RM200_PCI
-CORE_FILES    += arch/mips/sni/sni.o
-SUBDIRS       += arch/mips/sni arch/mips/arc
-LIBS          += arch/mips/arc/lib.a
-LOADADDR      += 0x80080000
+core-y		+= arch/mips/sni/
+libs-y		+= arch/mips/arc/
+LOADADDR	+= 0x80080000
 endif
 
 ifdef CONFIG_SGI_IP22
-CORE_FILES    += arch/mips/sgi/kernel/ip22-kern.o
-LIBS          += arch/mips/arc/lib.a
-SUBDIRS       += arch/mips/sgi/kernel arch/mips/arc
+core-y		+= arch/mips/sgi/kernel/
+libs-y		+= arch/mips/arc/
 #
 # Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
 # 0x88002000 for production kernels.  Note that the value must be
 # 8kb aligned or the handling of the current variable will break.
 #
-LOADADDR      += 0x88002000
+LOADADDR	+= 0x88002000
 endif
 
 #
 # Baget/MIPS
 #
 ifdef CONFIG_BAGET_MIPS
-SUBDIRS       += arch/mips/baget arch/mips/baget/prom
-LIBS          += arch/mips/baget/baget.a arch/mips/baget/prom/lib.a
-LOADADDR      += 0x80001000
+core-y		+= arch/mips/baget/
+libs-y		+= arch/mips/baget/prom/
+LOADADDR	+= 0x80001000
 endif
 
 #
 # NEC DDB Vrc-5074
 #
 ifdef CONFIG_DDB5074
-SUBDIRS       += arch/mips/ddb5074
-LIBS          += arch/mips/ddb5074/ddb5074.a
-LOADADDR      += 0x80080000
+core-y		+= arch/mips/ddb5074/
+LOADADDR	+= 0x80080000
 endif
 
 #
@@ -180,9 +171,8 @@
 # NEC DDB Vrc-5476
 #
 ifdef CONFIG_DDB5476
-SUBDIRS       += arch/mips/ddb5476
-LIBS          += arch/mips/ddb5476/ddb5476.a
-LOADADDR      += 0x80080000
+core-y		+= arch/mips/ddb5476/
+LOADADDR	+= 0x80080000
 endif
 
 #
@@ -190,28 +180,26 @@
 # NEC DDB Vrc-5477
 #
 ifdef CONFIG_DDB5477
-SUBDIRS       += arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5477
-LIBS          += arch/mips/ddb5xxx/common/ddb5xxx.o \
-                 arch/mips/ddb5xxx/ddb5477/ddb5477.o
-LOADADDR      += 0x80080000
+core-y		+= arch/mips/ddb5xxx/common/ \
+		   arch/mips/ddb5xxx/ddb5477/
+LOADADDR	+= 0x80080000
 endif
 
 #
 # Galileo EV64120 Board
 #
 ifdef CONFIG_MIPS_EV64120
-LIBS          += arch/mips/galileo-boards/ev64120/ev64120.o
-SUBDIRS       += arch/mips/galileo-boards/ev64120
-LOADADDR      += 0x80100000
+core-y		+= arch/mips/galileo-boards/ev64120/
+LOADADDR	+= 0x80100000
 endif
 
 #
 # Galileo EV96100 Board
 #
 ifdef CONFIG_MIPS_EV96100
-LIBS          += arch/mips/galileo-boards/ev96100/ev96100.o arch/mips/galileo-boards/generic/galboards.o
-SUBDIRS       += arch/mips/galileo-boards/generic arch/mips/galileo-boards/ev96100
-LOADADDR      += 0x80100000
+core-y		+= arch/mips/galileo-boards/ev96100/ \
+		   arch/mips/galileo-boards/generic/
+LOADADDR	+= 0x80100000
 endif
 
 #
@@ -220,45 +208,44 @@
 ifdef CONFIG_MOMENCO_OCELOT
 # The Ocelot setup.o must be linked early - it does the ioremap() for the
 # mips_io_port_base.
-CORE_FILES    += arch/mips/gt64120/common/gt64120.o arch/mips/gt64120/momenco_ocelot/momenco_ocelot.o
-SUBDIRS       += arch/mips/gt64120/common arch/mips/gt64120/momenco_ocelot
-LOADADDR      += 0x80100000
+core-y		+= arch/mips/gt64120/common/ \
+		   arch/mips/gt64120/momenco_ocelot/
+LOADADDR	+= 0x80100000
 endif
 
 #
 # Philips Nino
 #
 ifdef CONFIG_NINO
-CORE_FILES    += arch/mips/philips/nino/nino.o
-SUBDIRS       += arch/mips/philips/nino
-LOADADDR      += 0x80000000
+core-y		+= arch/mips/philips/nino/
+LOADADDR	+= 0x80000000
 endif
 
 #
 # ITE 8172 eval board with QED 5231 CPU
 #
 ifdef CONFIG_MIPS_ITE8172
-LIBS          += arch/mips/ite-boards/qed-4n-s01b/ite.o arch/mips/ite-boards/generic/it8172.o
-SUBDIRS       += arch/mips/ite-boards/generic arch/mips/ite-boards/qed-4n-s01b
-LOADADDR      += 0x80100000
+core-y		+= arch/mips/ite-boards/qed-4n-s01b/ \
+		   arch/mips/ite-boards/generic/
+LOADADDR	+= 0x80100000
 endif
 
 #
 # Globespan IVR eval board with QED 5231 CPU
 #
 ifdef CONFIG_MIPS_IVR
-LIBS          += arch/mips/ite-boards/ivr/ivr.o arch/mips/ite-boards/generic/it8172.o
-SUBDIRS       += arch/mips/ite-boards/generic arch/mips/ite-boards/ivr
-LOADADDR      += 0x80100000
+core-y		+= arch/mips/ite-boards/ivr/ \
+		   arch/mips/ite-boards/generic/
+LOADADDR	+= 0x80100000
 endif
 
 #
 # Au1000 eval board
 #
 ifdef CONFIG_MIPS_PB1000
-LIBS          += arch/mips/au1000/pb1000/pb1000.o arch/mips/au1000/common/au1000.o
-SUBDIRS       += arch/mips/au1000/pb1000 arch/mips/au1000/common
-LOADADDR      += 0x80100000
+core-y		+= arch/mips/au1000/pb1000/ \
+		   arch/mips/au1000/common/
+LOADADDR	+= 0x80100000
 endif
 
 #
@@ -271,9 +258,10 @@
 
 HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
 
-SUBDIRS := $(addprefix arch/mips/, tools) $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib)
-CORE_FILES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(CORE_FILES)
-LIBS := arch/mips/lib/lib.a $(LIBS)
+SUBDIRS := arch/mips/tools
+
+core-y		+= arch/mips/kernel/ arch/mips/mm/
+libs-y		+= arch/mips/lib/lib.a
 
 ifdef CONFIG_BAGET_MIPS
 
diff -Nru a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
--- a/arch/mips/au1000/common/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/au1000/common/Makefile	Fri Sep 27 14:51:05 2002
@@ -6,8 +6,6 @@
 # Makefile for the Alchemy Au1000 CPU, generic files.
 #
 
-O_TARGET := au1000.o
-
 export-objs := serial.o
 
 obj-y := prom.o dbg_io.o int-handler.o irq.o puts.o time.o reset.o
diff -Nru a/arch/mips/au1000/pb1000/Makefile b/arch/mips/au1000/pb1000/Makefile
--- a/arch/mips/au1000/pb1000/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/au1000/pb1000/Makefile	Fri Sep 27 14:51:03 2002
@@ -6,8 +6,6 @@
 # Makefile for the Alchemy Semiconductor PB1000 board.
 #
 
-O_TARGET := pb1000.o
-
 obj-y := init.o setup.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/mips/baget/Makefile b/arch/mips/baget/Makefile
--- a/arch/mips/baget/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/baget/Makefile	Fri Sep 27 14:51:05 2002
@@ -3,8 +3,6 @@
 # under Linux.
 #
 
-O_TARGET := baget.a
-
 export-objs		:= vacserial.o
 obj-y			:= baget.o print.o setup.o time.o irq.o bagetIRQ.o \
 			   reset.o wbflush.o
diff -Nru a/arch/mips/ddb5074/Makefile b/arch/mips/ddb5074/Makefile
--- a/arch/mips/ddb5074/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/ddb5074/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,16 +2,8 @@
 # Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
 # under Linux.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-#
 
 EXTRA_AFLAGS := $(CFLAGS)
-
-O_TARGET = ddb5074.a
 
 obj-y	:= setup.o irq.o time.o prom.o pci.o int-handler.o nile4.o
 
diff -Nru a/arch/mips/ddb5476/Makefile b/arch/mips/ddb5476/Makefile
--- a/arch/mips/ddb5476/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/ddb5476/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,16 +2,8 @@
 # Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
 # under Linux.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-#
 
 EXTRA_AFLAGS := $(CFLAGS)
-
-O_TARGET = ddb5476.a
 
 obj-y				+= setup.o irq.o time.o prom.o pci.o \
 				   int-handler.o nile4.o
diff -Nru a/arch/mips/ddb5xxx/common/Makefile b/arch/mips/ddb5xxx/common/Makefile
--- a/arch/mips/ddb5xxx/common/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/ddb5xxx/common/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,12 +1,6 @@
 #
 # Makefile for the common code of NEC DDB-Vrc5xxx board
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-O_TARGET:= ddb5xxx.o
 
 obj-y	 += irq.o irq_cpu.o nile4.o prom.o pci.o pci_auto.o rtc_ds1386.o
 
diff -Nru a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile
--- a/arch/mips/ddb5xxx/ddb5477/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/ddb5xxx/ddb5477/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,14 +1,8 @@
 #
 # Makefile for NEC DDB-Vrc5477 board
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
 
 EXTRA_AFLAGS := $(CFLAGS)
-
-O_TARGET:= ddb5477.o
 
 obj-y	 += int-handler.o irq.o irq_5477.o setup.o pci.o pci_ops.o
 
diff -Nru a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
--- a/arch/mips/dec/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/dec/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,8 +2,6 @@
 # Makefile for the DECstation family specific parts of the kernel
 #
 
-O_TARGET := dec.o
-
 export-objs := wbflush.o
 
 obj-y	 := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o
diff -Nru a/arch/mips/dec/boot/Makefile b/arch/mips/dec/boot/Makefile
--- a/arch/mips/dec/boot/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips/dec/boot/Makefile	Fri Sep 27 14:51:04 2002
@@ -4,9 +4,7 @@
 
 netboot: all
 	mipsel-linux-ld -N -G 0 -T ld.ecoff ../../boot/zImage \
-		dec_boot.o ramdisk.img -o nbImage
-
-O_TARGET := dec_boot.o
+		built-in.o ramdisk.img -o nbImage
 
 obj-y	 := decstation.o
 
diff -Nru a/arch/mips/gt64120/common/Makefile b/arch/mips/gt64120/common/Makefile
--- a/arch/mips/gt64120/common/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips/gt64120/common/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,12 +1,6 @@
 #
 # Makefile for common code of gt64120-based boards.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-O_TARGET:= gt64120.o
 
 obj-y	 := gt_irq.o pci.o
 
diff -Nru a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile
--- a/arch/mips/gt64120/momenco_ocelot/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/gt64120/momenco_ocelot/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,14 +1,8 @@
 #
 # Makefile for Momentum's Ocelot board.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
 
 EXTRA_AFLAGS := $(CFLAGS)
-
-O_TARGET:= momenco_ocelot.o
 
 obj-y	 += int-handler.o irq.o pci.o prom.o reset.o setup.o
 
diff -Nru a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile
--- a/arch/mips/ite-boards/generic/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/ite-boards/generic/Makefile	Fri Sep 27 14:51:03 2002
@@ -6,8 +6,6 @@
 # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
 #
 
-O_TARGET := it8172.o
-
 obj-y := it8172_rtc.o it8172_setup.o irq.o int-handler.o pmon_prom.o time.o lpc.o puts.o reset.o
 
 ifdef CONFIG_PCI
diff -Nru a/arch/mips/ite-boards/ivr/Makefile b/arch/mips/ite-boards/ivr/Makefile
--- a/arch/mips/ite-boards/ivr/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/ite-boards/ivr/Makefile	Fri Sep 27 14:51:05 2002
@@ -7,8 +7,6 @@
 # board-specific files.
 #
 
-O_TARGET := ivr.o
-
 obj-y := init.o 
 
 obj-$(CONFIG_PCI) += pci_fixup.o
diff -Nru a/arch/mips/ite-boards/qed-4n-s01b/Makefile b/arch/mips/ite-boards/qed-4n-s01b/Makefile
--- a/arch/mips/ite-boards/qed-4n-s01b/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/ite-boards/qed-4n-s01b/Makefile	Fri Sep 27 14:51:05 2002
@@ -7,13 +7,8 @@
 # specific files.
 #
 
-O_TARGET := ite.o
-
 obj-y := init.o 
 obj-$(CONFIG_PCI) += pci_fixup.o
 obj-$(CONFIG_BLK_DEV_INITRD) += le_ramdisk.o
 
 include $(TOPDIR)/Rules.make
-
-dep:
-	$(CPP) -M *.c > .depend
diff -Nru a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
--- a/arch/mips/jazz/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips/jazz/Makefile	Fri Sep 27 14:51:04 2002
@@ -2,8 +2,6 @@
 # Makefile for the Jazz family specific parts of the kernel
 #
 
-O_TARGET := jazz.o
-
 obj-y	 := int-handler.o irq.o jazzdma.o reset.o rtc-jazz.o setup.o \
 	    floppy-jazz.o kbd-jazz.o
 
diff -Nru a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
--- a/arch/mips/kernel/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips/kernel/Makefile	Fri Sep 27 14:51:04 2002
@@ -4,7 +4,6 @@
 
 # EXTRA_AFLAGS = -mips3 -mcpu=r4000 # not used?
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o init_task.o
 export-objs	:= mips_ksyms.o
 
diff -Nru a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile
--- a/arch/mips/math-emu/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips/math-emu/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,12 +1,6 @@
 #
 # Makefile for the Linux/MIPS kernel FPU emulation.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-O_TARGET:= fpu_emulator.o
 
 obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
 	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
diff -Nru a/arch/mips/mips-boards/atlas/Makefile b/arch/mips/mips-boards/atlas/Makefile
--- a/arch/mips/mips-boards/atlas/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/mips-boards/atlas/Makefile	Fri Sep 27 14:51:05 2002
@@ -23,8 +23,6 @@
 # under Linux.
 #
 
-O_TARGET := atlas.o
-
 obj-y	:= atlas_int.o atlas_rtc.o atlas_setup.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile
--- a/arch/mips/mips-boards/generic/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips/mips-boards/generic/Makefile	Fri Sep 27 14:51:05 2002
@@ -21,15 +21,8 @@
 #
 # Makefile for the MIPS boards generic routines under Linux.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
 EXTRA_AFLAGS := $(CFLAGS)
-
-O_TARGET := mipsboards.o
 
 obj-y				:= mipsIRQ.o pci.o reset.o display.o init.o \
 				   memory.o printf.o cmdline.o time.o
diff -Nru a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile
--- a/arch/mips/mips-boards/malta/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/mips/mips-boards/malta/Makefile	Fri Sep 27 14:51:02 2002
@@ -22,13 +22,6 @@
 # Makefile for the MIPS Malta specific kernel interface routines
 # under Linux.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := malta.o
 
 obj-y := malta_int.o malta_rtc.o malta_setup.o
 
diff -Nru a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
--- a/arch/mips/mm/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/mm/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the Linux/MIPS-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET := mm.o
 
 export-objs			+= ioremap.o umap.o
 obj-y				+= extable.o init.o ioremap.o fault.o loadmmu.o
diff -Nru a/arch/mips/philips/nino/Makefile b/arch/mips/philips/nino/Makefile
--- a/arch/mips/philips/nino/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips/philips/nino/Makefile	Fri Sep 27 14:51:04 2002
@@ -2,8 +2,6 @@
 # Makefile for the Philips Nino specific parts of the kernel
 #
 
-O_TARGET := nino.o
-
 obj-y	 := int-handler.o setup.o irq.o time.o reset.o rtc.o prom.o power.o
 
 obj-$(CONFIG_REMOTE_DEBUG)	+= kgdb.o
diff -Nru a/arch/mips/sgi/kernel/Makefile b/arch/mips/sgi/kernel/Makefile
--- a/arch/mips/sgi/kernel/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/sgi/kernel/Makefile	Fri Sep 27 14:51:03 2002
@@ -3,8 +3,6 @@
 # under Linux.
 #
 
-O_TARGET := ip22-kern.o
-
 obj-y	+= indy_mc.o indy_sc.o indy_hpc.o indy_int.o indy_rtc.o system.o \
 	   indyIRQ.o reset.o setup.o time.o
 
diff -Nru a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
--- a/arch/mips/sni/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips/sni/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,8 +2,6 @@
 # Makefile for the SNI specific part of the kernel
 #
 
-O_TARGET := sni.o
-
 obj-y	 := int-handler.o io.o irq.o pci.o pcimt_scache.o reset.o setup.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff -Nru a/arch/mips64/Makefile b/arch/mips64/Makefile
--- a/arch/mips64/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips64/Makefile	Fri Sep 27 14:51:03 2002
@@ -63,29 +63,26 @@
 CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
 endif
 
-ifdef CONFIG_MIPS_FPU_EMULATOR
-CORE_FILES	+= arch/mips64/math-emu/fpu_emulator.o
-SUBDIRS		+= arch/mips64/math-emu
-endif
+core-$(CONFIG_MIPS_FPU_EMULATOR)	+= arch/mips64/math-emu/
 
 #
 # Board-dependent options and extra files
 #
+
 ifdef CONFIG_SGI_IP22
-LIBS          += arch/mips64/sgi-ip22/lib.a arch/mips64/arc/lib.a
-SUBDIRS       += arch/mips64/sgi-ip22 arch/mips64/arc
+libs-y					+= arch/mips64/sgi-ip22/ \
+					   arch/mips64/arc/
 #
 # Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
 # 0x88004000 for production kernels.  Note that the value must be
 # 16kb aligned or the handling of the current variable will break.
 #
-LOADADDR      += 0x88004000
+LOADADDR	+= 0x88004000
 endif
 
 ifdef CONFIG_SGI_IP27
-CORE_FILES    += arch/mips64/sgi-ip27/ip27.o
-LIBS          += arch/mips64/arc/lib.a
-SUBDIRS       += arch/mips64/sgi-ip27 arch/mips64/arc
+core-y					+= arch/mips64/sgi-ip27/
+libs-y					+= arch/mips64/arc/
 #
 # Set LOADADDR to >= 0xc000000000300000 if you want to leave space for
 # symmon, 0xc00000000001c000 for production kernels.  Note that the value
@@ -100,8 +97,8 @@
 endif
 
 ifdef CONFIG_SGI_IP32
-LIBS		+= arch/mips64/sgi-ip32/ip32-kern.a arch/mips64/arc/lib.a
-SUBDIRS		+= arch/mips64/sgi-ip32 arch/mips64/arc
+libs-y					+= arch/mips64/sgi-ip32/
+					   arch/mips64/arc/
 #
 # Set LOADADDR to >= 0x????????? if you want to leave space for symmon,
 # 0x80002000 for production kernels.  Note that the value must be
@@ -133,9 +130,9 @@
 
 HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o
 
-SUBDIRS := $(addprefix arch/mips64/, tools) $(SUBDIRS) $(addprefix arch/mips64/, kernel mm lib)
-CORE_FILES := arch/mips64/kernel/kernel.o arch/mips64/mm/mm.o $(CORE_FILES)
-LIBS := arch/mips64/lib/lib.a $(LIBS)
+SUBDIRS		:= arch/mips64/tools $(SUBDIRS)
+core-y		+= arch/mips64/kernel/ arch/mips64/mm/
+libs-y		+= arch/mips64/lib/lib.a
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
diff -Nru a/arch/mips64/kernel/Makefile b/arch/mips64/kernel/Makefile
--- a/arch/mips64/kernel/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips64/kernel/Makefile	Fri Sep 27 14:51:04 2002
@@ -2,7 +2,6 @@
 # Makefile for the Linux/MIPS kernel.
 #
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o init_task.o
 
 export-objs	:= mips64_ksyms.o
diff -Nru a/arch/mips64/math-emu/Makefile b/arch/mips64/math-emu/Makefile
--- a/arch/mips64/math-emu/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips64/math-emu/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,12 +1,6 @@
 #
 # Makefile for the Linux/MIPS kernel FPU emulation.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-O_TARGET:= fpu_emulator.o
 
 obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
 	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
diff -Nru a/arch/mips64/mips-boards/atlas/Makefile b/arch/mips64/mips-boards/atlas/Makefile
--- a/arch/mips64/mips-boards/atlas/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips64/mips-boards/atlas/Makefile	Fri Sep 27 14:51:05 2002
@@ -23,8 +23,6 @@
 # under Linux.
 #
 
-O_TARGET := atlas.o
-
 obj-y   := atlas_int.o atlas_rtc.o atlas_setup.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/mips64/mips-boards/generic/Makefile b/arch/mips64/mips-boards/generic/Makefile
--- a/arch/mips64/mips-boards/generic/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/mips64/mips-boards/generic/Makefile	Fri Sep 27 14:51:03 2002
@@ -22,8 +22,6 @@
 # Makefile for the MIPS boards generic routines under Linux.
 #
 
-O_TARGET := mipsboards.o
-
 obj-y                           := mipsIRQ.o pci.o reset.o display.o init.o \
                                    memory.o printf.o cmdline.o time.o
 obj-$(CONFIG_REMOTE_DEBUG)      += gdb_hook.o
diff -Nru a/arch/mips64/mips-boards/malta/Makefile b/arch/mips64/mips-boards/malta/Makefile
--- a/arch/mips64/mips-boards/malta/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips64/mips-boards/malta/Makefile	Fri Sep 27 14:51:04 2002
@@ -23,8 +23,6 @@
 # under Linux.
 #
 
-O_TARGET := malta.o
-
 obj-y := malta_int.o malta_rtc.o malta_setup.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/mips64/mm/Makefile b/arch/mips64/mm/Makefile
--- a/arch/mips64/mm/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/mips64/mm/Makefile	Fri Sep 27 14:51:02 2002
@@ -2,9 +2,8 @@
 # Makefile for the Linux/MIPS-specific parts of the memory manager.
 #
 
-O_TARGET := mm.o
-
 export-objs			+= umap.o
+
 obj-y				:= extable.o init.o fault.o loadmmu.o
 
 obj-$(CONFIG_CPU_R4300)		+= r4xx0.o
diff -Nru a/arch/mips64/sgi-ip27/Makefile b/arch/mips64/sgi-ip27/Makefile
--- a/arch/mips64/sgi-ip27/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/mips64/sgi-ip27/Makefile	Fri Sep 27 14:51:05 2002
@@ -4,8 +4,6 @@
 
 EXTRA_AFLAGS := $(CFLAGS)
 
-O_TARGET = ip27.o
-
 obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
 	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
 	   ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o
diff -Nru a/arch/mips64/sgi-ip32/Makefile b/arch/mips64/sgi-ip32/Makefile
--- a/arch/mips64/sgi-ip32/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/mips64/sgi-ip32/Makefile	Fri Sep 27 14:51:04 2002
@@ -3,7 +3,6 @@
 # under Linux.
 #
 
-O_TARGET	:= ip32-kern.a
 EXTRA_TARGETS	:= ip32-irq-glue.o
 
 obj-y		+= ip32-irq.o ip32-rtc.o ip32-setup.o ip32-irq-glue.o \
diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile
--- a/arch/parisc/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/parisc/Makefile	Fri Sep 27 14:51:05 2002
@@ -38,21 +38,17 @@
 
 HEAD = arch/parisc/kernel/head.o 
 
-SUBDIRS := $(SUBDIRS) $(addprefix arch/parisc/, tools kernel mm lib hpux)
-CORE_FILES :=  $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o \
-	lib/lib.a mm/mm.o kernel/kernel.o hpux/hpux.o) \
-	$(CORE_FILES) arch/parisc/kernel/init_task.o
-LIBS := `$(CC) -print-libgcc-file-name` $(TOPDIR)/arch/parisc/lib/lib.a $(LIBS) 
-
-ifdef CONFIG_MATH_EMULATION
-SUBDIRS := $(SUBDIRS) arch/parisc/math-emu
-DRIVERS := $(DRIVERS) arch/parisc/math-emu/math.a
-endif
-
-ifdef CONFIG_KWDB
-SUBDIRS := $(SUBDIRS) arch/parisc/kdb
-DRIVERS := $(DRIVERS) arch/parisc/kdb/kdb.o
-endif
+SUBDIRS += arch/parisc/tools
+core-y					+= arch/parisc/kernel/pdc_cons.o  \
+					   arch/parisc/kernel/process.o   \
+	   				   arch/parisc/mm/	          \
+					   arch/parisc/kernel/            \
+					   arch/parisc/hpux/		  \
+					   arch/parisc/kernel/init_task.o
+libs-y					+= arch/parisc/lib/lib.a          \
+					   `$(CC) -print-libgcc-file-name`
+drivers-$(CONFIG_MATH_EMULATION)	+= arch/parisc/math-emu/
+drivers-$(CONFIG_KWDB)			+= arch/parisc/kdb/
 
 palo: vmlinux
 	export TOPDIR=`pwd`; export CONFIG_STI_CONSOLE=$(CONFIG_STI_CONSOLE); \
diff -Nru a/arch/parisc/hpux/Makefile b/arch/parisc/hpux/Makefile
--- a/arch/parisc/hpux/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/parisc/hpux/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,8 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET := hpux.o
-
 obj-y := entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
 
 EXTRA_AFLAGS := -traditional
diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
--- a/arch/parisc/kernel/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/parisc/kernel/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,7 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o init_task.o process.o pdc_cons.o
 
 # Object file lists.
diff -Nru a/arch/parisc/mm/Makefile b/arch/parisc/mm/Makefile
--- a/arch/parisc/mm/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/parisc/mm/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,7 @@
 #
 # Makefile for the linux parisc-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
-O_TARGET := mm.o
-O_OBJS	 := init.o fault.o kmap.o extable.o
+objs-y	 := init.o fault.o kmap.o extable.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/ppc/4xx_io/Makefile b/arch/ppc/4xx_io/Makefile
--- a/arch/ppc/4xx_io/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ppc/4xx_io/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,10 +2,7 @@
 # Makefile for the linux MPC4xx ppc-specific parts 
 #
 
-O_TARGET 		:= 4xx_io.o
-
-#obj-y			:=
 
 obj-$(CONFIG_SERIAL_SICC)		+= serial_sicc.o
- 
+
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/ppc/8260_io/Makefile b/arch/ppc/8260_io/Makefile
--- a/arch/ppc/8260_io/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ppc/8260_io/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the linux MPC8xx ppc-specific parts of comm processor
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET		:= 8260_io.o
 
 obj-y			:= commproc.o uart.o
 
diff -Nru a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile
--- a/arch/ppc/8xx_io/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ppc/8xx_io/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the linux MPC8xx ppc-specific parts of comm processor
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET 		:= 8xx_io.o
 
 export-objs		:= fec.o
 
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ppc/Makefile	Fri Sep 27 14:51:03 2002
@@ -53,47 +53,17 @@
   endif
 endif
 
-ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/platforms arch/ppc/mm arch/ppc/lib
-SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS)
-CORE_FILES := arch/ppc/kernel/kernel.o arch/ppc/platforms/platform.o \
-	arch/ppc/mm/mm.o arch/ppc/lib/lib.o $(CORE_FILES)
-
-ifdef CONFIG_MATH_EMULATION
-SUBDIRS += arch/ppc/math-emu
-CORE_FILES += arch/ppc/math-emu/math-emu.o
-endif
-
-ifdef CONFIG_XMON
-SUBDIRS += arch/ppc/xmon
-CORE_FILES += arch/ppc/xmon/x.o
-endif
+core-y				+= arch/ppc/kernel/ arch/ppc/platforms/
+				   arch/ppc/mm/     arch/ppc/lib/
+core-$(CONFIG_MATH_EMULATION)	+= arch/ppc/math-emu/
+core-$(CONFIG_XMON)		+= arch/ppc/xmon/
+core-$(CONFIG_APUS)		+= arch/ppc/amiga/
+core-$(CONFIG_PPC_ISERIES)	+= arch/ppc/iSeries/
+drivers-$(CONFIG_8xx)		+= arch/ppc/8xx_io/
+drivers-$(CONFIG_4xx)		+= arch/ppc/4xx_io/
+drivers-$(CONFIG_8260)		+= arch/ppc/8260_io/
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-
-ifdef CONFIG_8xx
-SUBDIRS += arch/ppc/8xx_io
-DRIVERS += arch/ppc/8xx_io/8xx_io.o
-endif
-
-ifdef CONFIG_8260
-SUBDIRS += arch/ppc/8260_io
-DRIVERS += arch/ppc/8260_io/8260_io.o
-endif
-
-ifdef CONFIG_4xx
-SUBDIRS += arch/ppc/4xx_io
-DRIVERS += arch/ppc/4xx_io/4xx_io.o
-endif
-
-ifdef CONFIG_APUS
-SUBDIRS += arch/ppc/amiga
-CORE_FILES += arch/ppc/amiga/amiga.o
-endif
-
-ifdef CONFIG_PPC_ISERIES
-SUBDIRS += arch/ppc/iSeries
-CORE_FILES += arch/ppc/iSeries/iSeries.o
-endif
 
 BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm
 
diff -Nru a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile
--- a/arch/ppc/amiga/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ppc/amiga/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for Linux arch/m68k/amiga source directory
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := amiga.o
 
 export-objs	:= amiga_ksyms.o
 
diff -Nru a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
--- a/arch/ppc/boot/openfirmware/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/ppc/boot/openfirmware/Makefile	Fri Sep 27 14:51:04 2002
@@ -21,7 +21,7 @@
 NEWWORLDOBJS = ../common/crt0.o $(COMMONOBJS) newworldmain.o
 
 EXTRA_TARGETS	:= $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS)
-LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ../of1275/of1275.a
+LIBS = $(TOPDIR)/lib/lib.a ../lib/lib.a ../of1275/of1275.a
 
 ADDNOTE := ../utils/addnote
 MKNOTE := ../utils/mknote
diff -Nru a/arch/ppc/boot/prep/Makefile b/arch/ppc/boot/prep/Makefile
--- a/arch/ppc/boot/prep/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ppc/boot/prep/Makefile	Fri Sep 27 14:51:05 2002
@@ -24,7 +24,7 @@
 					../common/misc-common.o \
 					../common/mpc10x_memory.o
 OBJCOPY_ARGS			= -O elf32-powerpc
-LIBS 				= ../lib/zlib.a
+LIBS 				= ../lib/lib.a
 
 boot-$(CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o
 boot-$(CONFIG_VGA_CONSOLE)	+= vreset.o kbd.o
diff -Nru a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
--- a/arch/ppc/boot/simple/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/ppc/boot/simple/Makefile	Fri Sep 27 14:51:02 2002
@@ -152,7 +152,7 @@
 boot-$(CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o
 
 EXTRA_TARGETS			:= $(boot-y)
-LIBS				:= ../lib/zlib.a
+LIBS				:= ../lib/lib.a
 
 # Tools
 MKBUGBOOT			:= ../utils/mkbugboot
diff -Nru a/arch/ppc/iSeries/Makefile b/arch/ppc/iSeries/Makefile
--- a/arch/ppc/iSeries/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ppc/iSeries/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,7 +2,6 @@
 # Makefile for Linux arch/ppc/iSeries source directory
 #
 
-O_TARGET := iSeries.o
 export-objs := iSeries_ksyms.o
 obj-y   += LparData.o ItLpQueue.o HvLpEvent.o HvCall.o mf.o iSeries_proc.o mf_proc.o iSeries_ksyms.o HvLpConfig.o pmc_proc.o rtc.o
 
diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ppc/kernel/Makefile	Fri Sep 27 14:51:05 2002
@@ -18,7 +18,6 @@
 HEAD-$(CONFIG_8xx)		:= head_8xx.o
 HEAD-$(CONFIG_PPC_ISERIES)	:= iSeries_head.o
 
-O_TARGET 	:= kernel.o
 EXTRA_TARGETS	:= $(HEAD-y)
 
 export-objs			:= ppc_ksyms.o time.o ppc405_dma.o
diff -Nru a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
--- a/arch/ppc/lib/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ppc/lib/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,8 +2,6 @@
 # Makefile for ppc-specific library files..
 #
 
-O_TARGET		:= lib.o
-
 export-objs		:= dec_and_lock.o
 
 obj-y			:= checksum.o string.o strcase.o dec_and_lock.o
diff -Nru a/arch/ppc/math-emu/Makefile b/arch/ppc/math-emu/Makefile
--- a/arch/ppc/math-emu/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ppc/math-emu/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,4 +1,3 @@
-O_TARGET			:= math-emu.o
 
 obj-y				:= math.o fmr.o lfd.o stfd.o
 
diff -Nru a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile
--- a/arch/ppc/mm/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ppc/mm/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux ppc-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
 ifdef CONFIG_PPC64BRIDGE
 EXTRA_AFLAGS		:= -Wa,-mppc64bridge
@@ -13,7 +8,6 @@
 
 AFLAGS_hashtable.o	+= -I$(TOPDIR)/arch/$(ARCH)/kernel
 
-O_TARGET			:= mm.o
 obj-y				:= fault.o init.o mem_pieces.o extable.o \
 					mmu_context.o pgtable.o
 
diff -Nru a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
--- a/arch/ppc/platforms/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ppc/platforms/Makefile	Fri Sep 27 14:51:05 2002
@@ -12,8 +12,6 @@
 # Extra CFLAGS so we don't have to do relative includes
 CFLAGS_pmac_setup.o	+= -I$(TOPDIR)/arch/$(ARCH)/mm
 
-O_TARGET := platform.o
-
 export-objs			:= prep_setup.o
 
 obj-$(CONFIG_CEDER)		+= ceder.o ibmnp405l.o
diff -Nru a/arch/ppc/xmon/Makefile b/arch/ppc/xmon/Makefile
--- a/arch/ppc/xmon/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ppc/xmon/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,7 +1,5 @@
 # Makefile for xmon
 
-O_TARGET	:= x.o
-
 ifdef CONFIG_8xx
 obj-y		:= start_8xx.o
 else
diff -Nru a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/ppc64/Makefile	Fri Sep 27 14:51:03 2002
@@ -26,15 +26,8 @@
 
 HEAD := arch/ppc64/kernel/head.o
 
-ARCH_SUBDIRS = arch/ppc64/kernel arch/ppc64/mm arch/ppc64/lib
-SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS)
-ARCHIVES := arch/ppc64/kernel/kernel.o arch/ppc64/mm/mm.o arch/ppc64/lib/lib.o $(ARCHIVES)
-CORE_FILES := arch/ppc64/kernel/kernel.o arch/ppc64/mm/mm.o arch/ppc64/lib/lib.o $(CORE_FILES)
-
-ifdef CONFIG_XMON
-SUBDIRS += arch/ppc64/xmon
-CORE_FILES += arch/ppc64/xmon/x.o
-endif
+core-y			+= arch/ppc64/kernel/ arch/ppc64/mm/ arch/ppc64/lib/
+core-$(CONFIG_XMON)	+= arch/ppc64/xmon/
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ppc64/kernel/Makefile	Fri Sep 27 14:51:05 2002
@@ -6,7 +6,6 @@
 
 KHEAD := head.o
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= $(KHEAD)
 
 export-objs         := ppc_ksyms.o
diff -Nru a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
--- a/arch/ppc64/lib/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/ppc64/lib/Makefile	Fri Sep 27 14:51:02 2002
@@ -2,8 +2,6 @@
 # Makefile for ppc64-specific library files..
 #
 
-O_TARGET = lib.o
-
 export-objs     := dec_and_lock.o
 
 obj-y           := checksum.o dec_and_lock.o string.o strcase.o copypage.o \
diff -Nru a/arch/ppc64/mm/Makefile b/arch/ppc64/mm/Makefile
--- a/arch/ppc64/mm/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/ppc64/mm/Makefile	Fri Sep 27 14:51:02 2002
@@ -1,15 +1,8 @@
 #
 # Makefile for the linux ppc-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
 EXTRA_CFLAGS = -mno-minimal-toc
-
-O_TARGET := mm.o
 
 obj-y           := fault.o init.o extable.o imalloc.o
 obj-$(CONFIG_DISCONTIGMEM) += numa.o
diff -Nru a/arch/ppc64/xmon/Makefile b/arch/ppc64/xmon/Makefile
--- a/arch/ppc64/xmon/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/ppc64/xmon/Makefile	Fri Sep 27 14:51:05 2002
@@ -2,8 +2,6 @@
 
 EXTRA_CFLAGS = -mno-minimal-toc
 
-O_TARGET = x.o
-
 obj-y       := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/s390/Makefile b/arch/s390/Makefile
--- a/arch/s390/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/s390/Makefile	Fri Sep 27 14:51:03 2002
@@ -23,16 +23,10 @@
 
 HEAD := arch/s390/kernel/head.o arch/s390/kernel/init_task.o
 
-SUBDIRS += arch/s390/mm arch/s390/kernel arch/s390/lib drivers/s390
-CORE_FILES := arch/s390/mm/mm.o arch/s390/kernel/kernel.o $(CORE_FILES)
-LIBS := $(TOPDIR)/arch/s390/lib/lib.a $(LIBS) $(TOPDIR)/arch/s390/lib/lib.a
-
-DRIVERS += drivers/s390/built-in.o
-
-ifeq ($(CONFIG_MATHEMU),y)
-  SUBDIRS += arch/s390/math-emu
-  DRIVERS += arch/s390/math-emu/math-emu.o
-endif
+core-y				+= arch/s390/mm/ arch/s390/kernel/
+drivers-y			+= drivers/s390/
+drivers-$(CONFIG_MATHEMU)	+= arch/s390/math-emu/
+libs-y				+= arch/s390/lib/
 
 all: image listing
 
diff -Nru a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
--- a/arch/s390/kernel/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/s390/kernel/Makefile	Fri Sep 27 14:51:05 2002
@@ -5,8 +5,6 @@
 EXTRA_TARGETS	:= head.o init_task.o
 EXTRA_AFLAGS	:= -traditional
 
-O_TARGET	:= kernel.o
-
 export-objs	:= debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o
 obj-y	:= entry.o bitmap.o traps.o time.o process.o irq.o \
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
diff -Nru a/arch/s390/math-emu/Makefile b/arch/s390/math-emu/Makefile
--- a/arch/s390/math-emu/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/s390/math-emu/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,7 +2,6 @@
 # Makefile for the FPU instruction emulation.
 #
 
-O_TARGET := math-emu.o
 obj-$(CONFIG_MATHEMU) := math.o qrnnd.o
 
 EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w
diff -Nru a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
--- a/arch/s390/mm/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/s390/mm/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the linux s390-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET := mm.o
 
 obj-y	 := init.o fault.o ioremap.o extable.o
 
diff -Nru a/arch/s390x/Makefile b/arch/s390x/Makefile
--- a/arch/s390x/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/s390x/Makefile	Fri Sep 27 14:51:04 2002
@@ -24,10 +24,9 @@
 
 HEAD := arch/s390x/kernel/head.o arch/s390x/kernel/init_task.o
 
-SUBDIRS += arch/s390x/mm arch/s390x/kernel arch/s390x/lib drivers/s390
-CORE_FILES := arch/s390x/mm/mm.o arch/s390x/kernel/kernel.o $(CORE_FILES)
-DRIVERS := $(DRIVERS) drivers/s390/built-in.o
-LIBS := $(TOPDIR)/arch/s390x/lib/lib.a $(LIBS) $(TOPDIR)/arch/s390x/lib/lib.a
+core-y		+= arch/s390x/mm/ arch/s390x/kernel/
+drivers-y	+= drivers/s390/
+libs-y		+= arch/s390/lib/
 
 all: image listing
 
diff -Nru a/arch/s390x/boot/Makefile b/arch/s390x/boot/Makefile
--- a/arch/s390x/boot/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/s390x/boot/Makefile	Fri Sep 27 14:51:04 2002
@@ -2,8 +2,6 @@
 # Makefile for the linux s390-specific parts of the memory manager.
 #
 
-O_TARGET := 
-
 EXTRA_AFLAGS := -traditional
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/s390x/kernel/Makefile b/arch/s390x/kernel/Makefile
--- a/arch/s390x/kernel/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/s390x/kernel/Makefile	Fri Sep 27 14:51:04 2002
@@ -5,8 +5,6 @@
 EXTRA_TARGETS	:= head.o init_task.o
 EXTRA_AFLAGS	:= -traditional
 
-O_TARGET	:= kernel.o
-
 export-objs	:= debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o \
 		   exec32.o
 
diff -Nru a/arch/s390x/mm/Makefile b/arch/s390x/mm/Makefile
--- a/arch/s390x/mm/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/s390x/mm/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,13 +1,6 @@
 #
 # Makefile for the linux i386-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET := mm.o
 
 obj-y	 := init.o fault.o ioremap.o extable.o
 
diff -Nru a/arch/sh/Makefile b/arch/sh/Makefile
--- a/arch/sh/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/sh/Makefile	Fri Sep 27 14:51:04 2002
@@ -55,18 +55,15 @@
 
 HEAD := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
 
-SUBDIRS := $(SUBDIRS) $(addprefix arch/sh/, kernel mm lib)
-CORE_FILES := arch/sh/kernel/kernel.o arch/sh/mm/mm.o $(CORE_FILES)
 LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
-LIBS := $(TOPDIR)/arch/sh/lib/lib.a $(LIBS) $(TOPDIR)/arch/sh/lib/lib.a \
-	$(LIBGCC)
 
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+core-y				+= arch/sh/kernel/ arch/sh/mm/
+core-$(CONFIG_SH_GENERIC)	+= arch/sh/stboards/
+core-$(CONFIG_SH_STB1_HARP)	+= arch/sh/stboards/
+core-$(CONFIG_SH_STB1_OVERDRIVE)+= arch/sh/stboards/
+libs-y				+= arch/sh/lib/	$(LIBGCC)
 
-ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_SH_STB1_HARP)$(CONFIG_SH_STB1_OVERDRIVE),)
-SUBDIRS += arch/sh/stboards
-CORE_FILES += arch/sh/stboards/stboards.o
-endif
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
 AFLAGS_vmlinux.lds.o := -traditional
 
diff -Nru a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
--- a/arch/sh/kernel/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/sh/kernel/Makefile	Fri Sep 27 14:51:04 2002
@@ -2,7 +2,6 @@
 # Makefile for the Linux/SuperH kernel.
 #
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o init_task.o
 
 export-objs	:= io.o io_generic.o io_hd64465.o setup_hd64465.o sh_ksyms.o \
diff -Nru a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
--- a/arch/sh/mm/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/sh/mm/Makefile	Fri Sep 27 14:51:05 2002
@@ -1,13 +1,7 @@
 #
 # Makefile for the Linux SuperH-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
-O_TARGET := mm.o
 obj-y	 := init.o fault.o extable.o clear_page.o copy_page.o
 
 obj-$(CONFIG_CPU_SH3) += cache-sh3.o
diff -Nru a/arch/sh/stboards/Makefile b/arch/sh/stboards/Makefile
--- a/arch/sh/stboards/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/sh/stboards/Makefile	Fri Sep 27 14:51:03 2002
@@ -2,8 +2,6 @@
 # Makefile for STMicroelectronics board specific parts of the kernel
 #
 
-O_TARGET := stboards.o
-
 obj-y := irq.o setup.o mach.o led.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile
--- a/arch/sparc/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/sparc/Makefile	Fri Sep 27 14:51:03 2002
@@ -34,17 +34,12 @@
 
 HEAD := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o
 
-SUBDIRS += arch/sparc/kernel arch/sparc/lib arch/sparc/prom \
-	arch/sparc/mm arch/sparc/math-emu
-
-CORE_FILES := arch/sparc/kernel/kernel.o arch/sparc/mm/mm.o $(CORE_FILES) \
-	arch/sparc/math-emu/math-emu.o
-
-LIBS := $(LIBS) arch/sparc/prom/lib.a arch/sparc/lib/lib.a
+core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/
+libs-y += arch/sparc/prom/ arch/sparc/lib/
 
 # This one has to come last
 SUBDIRS += arch/sparc/boot
-CORE_FILES_NO_BTFIX := $(CORE_FILES)
+CORE_FILES_NO_BTFIX := $(addsuffix built-in.o,$(core-y))
 CORE_FILES += arch/sparc/boot/btfix.o
 
 # Export what is needed by arch/sparc/boot/Makefile
diff -Nru a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
--- a/arch/sparc/kernel/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/sparc/kernel/Makefile	Fri Sep 27 14:51:03 2002
@@ -4,7 +4,6 @@
 
 SH = $(CONFIG_SHELL)
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o init_task.o
 
 EXTRA_AFLAGS := -ansi
diff -Nru a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile
--- a/arch/sparc/math-emu/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/sparc/math-emu/Makefile	Fri Sep 27 14:51:02 2002
@@ -1,14 +1,7 @@
 #
 # Makefile for the FPU instruction emulation.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
-
-O_TARGET := math-emu.o
 obj-y    := math.o ashldi3.o
 
 EXTRA_AFLAGS := -ansi
diff -Nru a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
--- a/arch/sparc/mm/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/sparc/mm/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,15 +1,9 @@
 # $Id: Makefile,v 1.38 2000/12/15 00:41:22 davem Exp $
 # Makefile for the linux Sparc-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
 EXTRA_AFLAGS := -ansi
 
-O_TARGET := mm.o
 obj-y    := fault.o init.o loadmmu.o generic.o extable.o btfixup.o
 
 ifeq ($(CONFIG_SUN4),y)
diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile
--- a/arch/sparc64/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/sparc64/Makefile	Fri Sep 27 14:51:05 2002
@@ -57,25 +57,10 @@
 
 HEAD := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
 
-SUBDIRS += arch/sparc64/kernel arch/sparc64/lib arch/sparc64/mm \
-	arch/sparc64/prom
-
-ifneq ($(CONFIG_SOLARIS_EMUL),n)
-  SUBDIRS += arch/sparc64/solaris
-endif
-
-SUBDIRS += arch/sparc64/math-emu
-
-CORE_FILES := arch/sparc64/kernel/kernel.o arch/sparc64/mm/mm.o $(CORE_FILES)
-
-ifeq ($(CONFIG_SOLARIS_EMUL),y)
-  CORE_FILES += arch/sparc64/solaris/solaris.o
-endif
-
-CORE_FILES += arch/sparc64/math-emu/math-emu.o
-
-LIBS := $(TOPDIR)/lib/lib.a $(LIBS) $(TOPDIR)/arch/sparc64/prom/lib.a \
-	$(TOPDIR)/arch/sparc64/lib/lib.a
+core-y				+= arch/sparc64/kernel/ arch/sparc64/mm/
+core-$(CONFIG_SOLARIS_EMUL)	+= arch/sparc64/solaris/
+core-y				+= arch/sparc64/math-emu/
+libs-y				+= arch/sparc64/prom/ arch/sparc64/lib/
 
 vmlinux.aout: vmlinux
 	$(ELFTOAOUT) -o $(TOPDIR)/vmlinux.aout $(TOPDIR)/vmlinux
diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
--- a/arch/sparc64/kernel/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/sparc64/kernel/Makefile	Fri Sep 27 14:51:03 2002
@@ -6,7 +6,6 @@
 
 EXTRA_AFLAGS := -ansi
 
-O_TARGET	:= kernel.o
 EXTRA_TARGETS	:= head.o init_task.o
 
 export-objs	:= sparc64_ksyms.o
diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
--- a/arch/sparc64/kernel/ioctl32.c	Fri Sep 27 14:51:05 2002
+++ b/arch/sparc64/kernel/ioctl32.c	Fri Sep 27 14:51:05 2002
@@ -46,6 +46,7 @@
 #include <linux/netdevice.h>
 #include <linux/raw.h>
 #include <linux/smb_fs.h>
+#include <linux/ncp_fs.h>
 #include <linux/blkpg.h>
 #include <linux/blk.h>
 #include <linux/elevator.h>
@@ -2225,6 +2226,307 @@
 	return err;
 }
 
+struct ncp_ioctl_request_32 {
+	unsigned int function;
+	unsigned int size;
+	__kernel_caddr_t32 data;
+};
+
+struct ncp_fs_info_v2_32 {
+	int version;
+	unsigned int mounted_uid;
+	unsigned int connection;
+	unsigned int buffer_size;
+
+	unsigned int volume_number;
+	__u32 directory_id;
+
+	__u32 dummy1;
+	__u32 dummy2;
+	__u32 dummy3;
+};
+
+struct ncp_objectname_ioctl_32
+{
+	int		auth_type;
+	unsigned int	object_name_len;
+	__kernel_caddr_t32	object_name;	/* an userspace data, in most cases user name */
+};
+
+struct ncp_privatedata_ioctl_32
+{
+	unsigned int	len;
+	__kernel_caddr_t32	data;		/* ~1000 for NDS */
+};
+
+#define	NCP_IOC_NCPREQUEST_32		_IOR('n', 1, struct ncp_ioctl_request_32)
+
+#define NCP_IOC_GETMOUNTUID2_32		_IOW('n', 2, unsigned int)
+
+#define NCP_IOC_GET_FS_INFO_V2_32	_IOWR('n', 4, struct ncp_fs_info_v2_32)
+
+#define NCP_IOC_GETOBJECTNAME_32	_IOWR('n', 9, struct ncp_objectname_ioctl_32)
+#define NCP_IOC_SETOBJECTNAME_32	_IOR('n', 9, struct ncp_objectname_ioctl_32)
+#define NCP_IOC_GETPRIVATEDATA_32	_IOWR('n', 10, struct ncp_privatedata_ioctl_32)
+#define NCP_IOC_SETPRIVATEDATA_32	_IOR('n', 10, struct ncp_privatedata_ioctl_32)
+
+static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ncp_ioctl_request_32 n32;
+	struct ncp_ioctl_request n;
+	mm_segment_t old_fs;
+	int err;
+
+	if (copy_from_user(&n32, (struct ncp_ioctl_request_32*)arg,
+	    sizeof(n32)))
+		return -EFAULT;
+
+	n.function = n32.function;
+	n.size = n32.size;
+	if (n.size > 65536)
+		return -EINVAL;
+	n.data = vmalloc(65536);	/* 65536 must be same as NCP_PACKET_SIZE_INTERNAL in ncpfs */
+	if (!n.data)
+		return -ENOMEM;
+	err = -EFAULT;
+	if (copy_from_user(n.data, A(n32.data), n.size))
+		goto out;
+
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, NCP_IOC_NCPREQUEST, (unsigned long)&n);
+	set_fs (old_fs);
+        if(err <= 0)
+		goto out;
+	if (err > 65536) {
+		err = -EINVAL;
+		goto out;
+	}
+	if (copy_to_user(A(n32.data), n.data, err)) {
+		err = -EFAULT;
+		goto out;
+	}
+ out:
+	vfree(n.data);
+	return err;
+}
+
+static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	__kernel_uid_t kuid;
+	int err;
+
+	cmd = NCP_IOC_GETMOUNTUID2;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
+	set_fs(old_fs);
+
+	if (!err)
+		err = put_user(kuid, (unsigned int*)arg);
+
+	return err;
+}
+
+static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct ncp_fs_info_v2_32 n32;
+	struct ncp_fs_info_v2 n;
+	int err;
+
+	if (copy_from_user(&n32, (struct ncp_fs_info_v2_32*)arg, sizeof(n32)))
+		return -EFAULT;
+	if (n32.version != NCP_GET_FS_INFO_VERSION_V2)
+		return -EINVAL;
+	n.version = NCP_GET_FS_INFO_VERSION_V2;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n);
+	set_fs(old_fs);
+
+	if (!err) {
+		n32.version = n.version;
+		n32.mounted_uid = n.mounted_uid;
+		n32.connection = n.connection;
+		n32.buffer_size = n.buffer_size;
+		n32.volume_number = n.volume_number;
+		n32.directory_id = n.directory_id;
+		n32.dummy1 = n.dummy1;
+		n32.dummy2 = n.dummy2;
+		n32.dummy3 = n.dummy3;
+		err = copy_to_user((struct ncp_fs_info_v2_32*)arg, &n32, sizeof(n32)) ? -EFAULT : 0;
+	}
+	return err;
+}
+
+static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ncp_objectname_ioctl_32 n32;
+	struct ncp_objectname_ioctl n;
+	mm_segment_t old_fs;
+	int err;
+	size_t tl;
+
+	if (copy_from_user(&n32, (struct ncp_objectname_ioctl_32*)arg,
+	    sizeof(n32)))
+		return -EFAULT;
+
+	n.object_name_len = tl = n32.object_name_len;
+	if (tl) {
+		n.object_name = kmalloc(tl, GFP_KERNEL);
+		if (!n.object_name)
+			return -ENOMEM;
+	} else {
+		n.object_name = NULL;
+	}
+
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, NCP_IOC_GETOBJECTNAME, (unsigned long)&n);
+	set_fs (old_fs);
+        if(err)
+		goto out;
+		
+	if (tl > n.object_name_len)
+		tl = n.object_name_len;
+
+	err = -EFAULT;
+	if (tl && copy_to_user(A(n32.object_name), n.object_name, tl))
+		goto out;
+
+	n32.auth_type = n.auth_type;
+	n32.object_name_len = n.object_name_len;
+	
+	if (copy_to_user((struct ncp_objectname_ioctl_32*)arg, &n32, sizeof(n32)))
+		goto out;
+	
+	err = 0;
+ out:
+ 	if (n.object_name)
+		kfree(n.object_name);
+
+	return err;
+}
+
+static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ncp_objectname_ioctl_32 n32;
+	struct ncp_objectname_ioctl n;
+	mm_segment_t old_fs;
+	int err;
+	size_t tl;
+
+	if (copy_from_user(&n32, (struct ncp_objectname_ioctl_32*)arg,
+	    sizeof(n32)))
+		return -EFAULT;
+
+	n.auth_type = n32.auth_type;
+	n.object_name_len = tl = n32.object_name_len;
+	if (tl) {
+		n.object_name = kmalloc(tl, GFP_KERNEL);
+		if (!n.object_name)
+			return -ENOMEM;
+		err = -EFAULT;
+		if (copy_from_user(n.object_name, A(n32.object_name), tl))
+			goto out;
+	} else {
+		n.object_name = NULL;
+	}
+	
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, NCP_IOC_SETOBJECTNAME, (unsigned long)&n);
+	set_fs (old_fs);
+		
+ out:
+	if (n.object_name)
+		kfree(n.object_name);
+
+	return err;
+}
+
+static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ncp_privatedata_ioctl_32 n32;
+	struct ncp_privatedata_ioctl n;
+	mm_segment_t old_fs;
+	int err;
+	size_t tl;
+
+	if (copy_from_user(&n32, (struct ncp_privatedata_ioctl_32*)arg,
+	    sizeof(n32)))
+		return -EFAULT;
+
+	n.len = tl = n32.len;
+	if (tl) {
+		n.data = kmalloc(tl, GFP_KERNEL);
+		if (!n.data)
+			return -ENOMEM;
+	} else {
+		n.data = NULL;
+	}
+
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, NCP_IOC_GETPRIVATEDATA, (unsigned long)&n);
+	set_fs (old_fs);
+        if(err)
+		goto out;
+		
+	if (tl > n.len)
+		tl = n.len;
+
+	err = -EFAULT;
+	if (tl && copy_to_user(A(n32.data), n.data, tl))
+		goto out;
+
+	n32.len = n.len;
+	
+	if (copy_to_user((struct ncp_privatedata_ioctl_32*)arg, &n32, sizeof(n32)))
+		goto out;
+	
+	err = 0;
+ out:
+ 	if (n.data)
+		kfree(n.data);
+
+	return err;
+}
+
+static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ncp_privatedata_ioctl_32 n32;
+	struct ncp_privatedata_ioctl n;
+	mm_segment_t old_fs;
+	int err;
+	size_t tl;
+
+	if (copy_from_user(&n32, (struct ncp_privatedata_ioctl_32*)arg,
+	    sizeof(n32)))
+		return -EFAULT;
+
+	n.len = tl = n32.len;
+	if (tl) {
+		n.data = kmalloc(tl, GFP_KERNEL);
+		if (!n.data)
+			return -ENOMEM;
+		err = -EFAULT;
+		if (copy_from_user(n.data, A(n32.data), tl))
+			goto out;
+	} else {
+		n.data = NULL;
+	}
+	
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, NCP_IOC_SETPRIVATEDATA, (unsigned long)&n);
+	set_fs (old_fs);
+		
+ out:
+	if (n.data)
+		kfree(n.data);
+
+	return err;
+}
+
+
 struct atmif_sioc32 {
         int                number;
         int                length;
@@ -4508,6 +4810,18 @@
 COMPATIBLE_IOCTL(RAW_GETBIND)
 /* SMB ioctls which do not need any translations */
 COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
+/* NCP ioctls which do not need any translations */
+COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
+COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
+COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED)
+COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED)
+COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK)
+COMPATIBLE_IOCTL(NCP_IOC_GETROOT)
+COMPATIBLE_IOCTL(NCP_IOC_SETROOT)
+COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS)
+COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS)
+COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL)
+COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL)
 /* Little a */
 COMPATIBLE_IOCTL(ATMSIGD_CTRL)
 COMPATIBLE_IOCTL(ATMARPD_CTRL)
@@ -4754,6 +5068,14 @@
 /* One SMB ioctl needs translations. */
 #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, __kernel_uid_t32)
 HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
+/* NCPFS */
+HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
+HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2)
+HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2)
+HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname)
+HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname)
+HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
+HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
 HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
 HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
 HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl)
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Fri Sep 27 14:51:04 2002
+++ b/arch/sparc64/kernel/sys_sparc32.c	Fri Sep 27 14:51:04 2002
@@ -1489,7 +1489,7 @@
 	return sys_sysfs(option, arg1, arg2);
 }
 
-struct ncp_mount_data32 {
+struct ncp_mount_data32_v3 {
         int version;
         unsigned int ncp_fd;
         __kernel_uid_t32 mounted_uid;
@@ -1504,19 +1504,69 @@
         __kernel_mode_t32 dir_mode;
 };
 
+struct ncp_mount_data32_v4 {
+	int version;
+	/* all members below are "long" in ABI ... i.e. 32bit on sparc32, while 64bits on sparc64 */
+	unsigned int flags;
+	unsigned int mounted_uid;
+	int wdog_pid;
+
+	unsigned int ncp_fd;
+	unsigned int time_out;
+	unsigned int retry_count;
+
+	unsigned int uid;
+	unsigned int gid;
+	unsigned int file_mode;
+	unsigned int dir_mode;
+};
+
 static void *do_ncp_super_data_conv(void *raw_data)
 {
-	struct ncp_mount_data news, *n = &news; 
-	struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
+	switch (*(int*)raw_data) {
+		case NCP_MOUNT_VERSION:
+			{
+				struct ncp_mount_data news, *n = &news; 
+				struct ncp_mount_data32_v3 *n32 = (struct ncp_mount_data32_v3 *)raw_data;
+
+				n->version = n32->version;
+				n->ncp_fd = n32->ncp_fd;
+				n->mounted_uid = low2highuid(n32->mounted_uid);
+				n->wdog_pid = n32->wdog_pid;
+				memmove (n->mounted_vol, n32->mounted_vol, sizeof (n32->mounted_vol));
+				n->time_out = n32->time_out;
+				n->retry_count = n32->retry_count;
+				n->flags = n32->flags;
+				n->uid = low2highuid(n32->uid);
+				n->gid = low2highgid(n32->gid);
+				n->file_mode = n32->file_mode;
+				n->dir_mode = n32->dir_mode;
+				memcpy(raw_data, n, sizeof(*n)); 
+			}
+			break;
+		case NCP_MOUNT_VERSION_V4:
+			{
+				struct ncp_mount_data_v4 news, *n = &news; 
+				struct ncp_mount_data32_v4 *n32 = (struct ncp_mount_data32_v4 *)raw_data;
 
-	n->dir_mode = n32->dir_mode;
-	n->file_mode = n32->file_mode;
-	n->gid = low2highgid(n32->gid);
-	n->uid = low2highuid(n32->uid);
-	memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
-	n->wdog_pid = n32->wdog_pid;
-	n->mounted_uid = low2highuid(n32->mounted_uid);
-	memcpy(raw_data, n, sizeof(struct ncp_mount_data)); 
+				n->version = n32->version;
+				n->flags = n32->flags;
+				n->mounted_uid = n32->mounted_uid;
+				n->wdog_pid = n32->wdog_pid;
+				n->ncp_fd = n32->ncp_fd;
+				n->time_out = n32->time_out;
+				n->retry_count = n32->retry_count;
+				n->uid = n32->uid;
+				n->gid = n32->gid;
+				n->file_mode = n32->file_mode;
+				n->dir_mode = n32->dir_mode;
+				memcpy(raw_data, n, sizeof(*n)); 
+			}
+			break;
+		default:
+			/* do not touch unknown structures */
+			break;
+	}
 	return raw_data;
 }
 
diff -Nru a/arch/sparc64/math-emu/Makefile b/arch/sparc64/math-emu/Makefile
--- a/arch/sparc64/math-emu/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/sparc64/math-emu/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,13 +1,7 @@
 #
 # Makefile for the FPU instruction emulation.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
-O_TARGET := math-emu.o
 obj-y    := math.o
 
 EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w
diff -Nru a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
--- a/arch/sparc64/mm/Makefile	Fri Sep 27 14:51:05 2002
+++ b/arch/sparc64/mm/Makefile	Fri Sep 27 14:51:05 2002
@@ -4,7 +4,6 @@
 
 EXTRA_AFLAGS := -ansi
 
-O_TARGET := mm.o
 obj-y    := ultra.o fault.o init.o generic.o extable.o modutil.o
 
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff -Nru a/arch/um/Makefile b/arch/um/Makefile
--- a/arch/um/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/um/Makefile	Fri Sep 27 14:51:03 2002
@@ -35,14 +35,12 @@
 
 SUBDIRS += $(ARCH_SUBDIRS)
 
-LIBS += $(ARCH_DIR)/kernel/um.o \
-	$(ARCH_DIR)/drivers/drivers.o \
-	$(ARCH_DIR)/sys-$(SUBARCH)/sys.o $(ARCH_DIR)/os/os.o
+core-y			+= $(ARCH_DIR)/kernel/		 \
+			+= $(ARCH_DIR)/drivers/          \
+			+= $(ARCH_DIR)/sys-$(SUBARCH)/	 \
+			+= $(ARCH_DIR)/os-$(OS)/
 
-ifeq ($(CONFIG_PT_PROXY), y)
-SUBDIRS += $(ARCH_DIR)/ptproxy
-LIBS += $(ARCH_DIR)/ptproxy/ptproxy.a
-endif
+libs-$(CONFIG_PT_PROXY)	+= $(ARCH_DIR)/ptproxy/
 
 ARCH_INCLUDE = $(TOPDIR)/$(ARCH_DIR)/include
 
diff -Nru a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
--- a/arch/um/drivers/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/um/drivers/Makefile	Fri Sep 27 14:51:04 2002
@@ -3,13 +3,8 @@
 # Licensed under the GPL
 #
 
-O_TARGET := drivers.o 
-
 CHAN_OBJS := chan_kern.o chan_user.o line.o 
 
-list-multi := slip.o daemon.o mcast.o mconsole.o net.o ubd.o hostaudio.o \
-	port.o harddog.o
-
 slip-objs := slip_kern.o slip_user.o
 daemon-objs := daemon_kern.o daemon_user.o
 mcast-objs := mcast_kern.o mcast_user.o
@@ -60,25 +55,5 @@
 
 dep:
 
-archmrproper:
-
-daemon.o : $(daemon-objs)
-
-slip.o : $(slip-objs)
-
-mcast.o : $(mcast-objs)
-
-mconsole.o : $(mconsole-objs)
-
-net.o : $(net-objs)
-
-hostaudio.o : $(hostaudio-objs)
-
-ubd.o : $(ubd-objs)
-
-port.o : $(port-objs)
-
-harddog.o : $(harddog-objs)
+archmrproper: clean
 
-$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
-	$(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
diff -Nru a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
--- a/arch/um/kernel/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/um/kernel/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,4 +1,5 @@
-O_TARGET = um.o
+
+EXTRA_TARGETS	:= unmap_fin.o
 
 obj-y = config.o exec_kern.o exec_user.o exitcode.o frame_kern.o frame.o \
 	helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
@@ -8,17 +9,16 @@
 	time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
 	umid.o user_util.o
 
-ifeq ($(CONFIG_BLK_DEV_INITRD), y)
-  obj-y += initrd_kern.o initrd_user.o
+obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
 endif
 
 # user_syms.o not included here because Rules.make has its own ideas about
 # building anything in export-objs
 
 USER_OBJS = $(filter %_user.o,$(obj-y)) config.o process.o time.o umid.o \
-	user_util.o user_syms.o helper.o
+	user_util.o user_syms.o helper.o tty_log.o
 
-export-objs := ksyms.o process_kern.o signal_kern.o
+export-objs := ksyms.o process_kern.o signal_kern.o gprof_syms.o gmon_syms.o
 
 UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
 UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
@@ -31,21 +31,9 @@
   DMODVERSIONS = -D__CONFIG_MODVERSIONS__
 endif
 
-ifeq ($(CONFIG_GPROF), y)
-    obj-y += gprof_syms.o
-    export-objs += gprof_syms.o
-endif
-
-ifeq ($(CONFIG_GCOV), y)
-    obj-y += gmon_syms.o
-    export-objs += gmon_syms.o
-endif
-
-ifeq ($(CONFIG_TTY_LOG), y)
-    obj-y += tty_log.o
-    USER_OBJS += tty_log.o
-endif
-
+obj-$(CONFIG_GPROF)	+= gprof_syms.o
+obj-$(CONFIG_GCOV)	+= gmon_syms.o
+obj-$(CONFIG_TTY_LOG)	+= tty_log.o
 
 CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES) $(DMODVERSIONS) \
 	-I/usr/include -I../include
@@ -53,8 +41,6 @@
 CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
 
 include $(TOPDIR)/Rules.make
-
-$(O_TARGET) : unmap_fin.o
 
 $(USER_OBJS) : %.o: %.c
 	$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
diff -Nru a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
--- a/arch/um/os-Linux/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/um/os-Linux/Makefile	Fri Sep 27 14:51:04 2002
@@ -3,8 +3,6 @@
 # Licensed under the GPL
 #
 
-O_TARGET = os.o
-
 obj-y = file.o process.o tty.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/um/os-Linux/drivers/Makefile b/arch/um/os-Linux/drivers/Makefile
--- a/arch/um/os-Linux/drivers/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/um/os-Linux/drivers/Makefile	Fri Sep 27 14:51:04 2002
@@ -3,10 +3,6 @@
 # Licensed under the GPL
 #
 
-O_TARGET := drivers.o
-
-list-multi := tuntap.o ethertap.o
-
 ethertap-objs := ethertap_kern.o ethertap_user.o
 tuntap-objs := tuntap_kern.o tuntap_user.o
 
@@ -22,10 +18,3 @@
 
 $(USER_OBJS) : %.o: %.c
 	$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
-
-ethertap.o : $(ethertap-objs)
-
-tuntap.o : $(tuntap-objs)
-
-$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
-	$(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
diff -Nru a/arch/um/ptproxy/Makefile b/arch/um/ptproxy/Makefile
--- a/arch/um/ptproxy/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/um/ptproxy/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,4 +1,4 @@
-LIB = ptproxy.a
+LIB = lib.a
 
 OBJS = proxy.o ptrace.o sysdep.o wait.o
 
diff -Nru a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
--- a/arch/um/sys-i386/Makefile	Fri Sep 27 14:51:03 2002
+++ b/arch/um/sys-i386/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,4 +1,3 @@
-O_TARGET = sys.o
 
 obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o old-checksum.o \
 	ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
diff -Nru a/arch/um/sys-ia64/Makefile b/arch/um/sys-ia64/Makefile
--- a/arch/um/sys-ia64/Makefile	Fri Sep 27 14:51:02 2002
+++ b/arch/um/sys-ia64/Makefile	Fri Sep 27 14:51:02 2002
@@ -1,4 +1,4 @@
-OBJ = sys.o
+OBJ = built-in.o
 
 OBJS =
 
diff -Nru a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile
--- a/arch/um/sys-ppc/Makefile	Fri Sep 27 14:51:04 2002
+++ b/arch/um/sys-ppc/Makefile	Fri Sep 27 14:51:04 2002
@@ -1,4 +1,4 @@
-OBJ = sys.o
+OBJ = built-in.o
 
 .S.o:
 	$(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/acorn/block/fd1772.c	Fri Sep 27 14:51:04 2002
@@ -1542,7 +1542,7 @@
 static struct gendisk *floppy_find(int minor)
 {
 	int drive = minor & 3;
-	if ((minor>> 2) > NUM_DISK_TYPES || minor >= FD_MAX_UNITS)
+	if ((minor>> 2) > NUM_DISK_TYPES || drive >= FD_MAX_UNITS)
 		return NULL;
 	return &disks[drive];
 }
diff -Nru a/drivers/acpi/Config.in b/drivers/acpi/Config.in
--- a/drivers/acpi/Config.in	Fri Sep 27 14:51:05 2002
+++ b/drivers/acpi/Config.in	Fri Sep 27 14:51:05 2002
@@ -34,6 +34,7 @@
          define_bool CONFIG_ACPI_EC y
          define_bool CONFIG_ACPI_POWER y
          define_bool CONFIG_ACPI_PCI $CONFIG_PCI
+         define_bool CONFIG_ACPI_SLEEP $CONFIG_SOFTWARE_SUSPEND
          define_bool CONFIG_ACPI_SYSTEM	y
       fi
    fi
diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c
--- a/drivers/acpi/tables.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/acpi/tables.c	Fri Sep 27 14:51:04 2002
@@ -55,7 +55,8 @@
 	[ACPI_SPCR]		= "SPCR",
 	[ACPI_SRAT]		= "SRAT",
 	[ACPI_SSDT]		= "SSDT",
-	[ACPI_SPMI]		= "SPMI"
+	[ACPI_SPMI]		= "SPMI",
+	[ACPI_HPET]		= "HPET"
 };
 
 /* System Description Table (RSDT/XSDT) */
@@ -320,7 +321,7 @@
 			handler(entry);
 		}
 		entry = (acpi_table_entry_header *)
-			((unsigned long) entry += entry->length);
+			((unsigned long) entry + entry->length);
 	}
 
 	return count;
diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile	Fri Sep 27 14:51:03 2002
+++ b/drivers/base/Makefile	Fri Sep 27 14:51:03 2002
@@ -1,11 +1,14 @@
 # Makefile for the Linux device tree
 
 obj-y		:= core.o sys.o interface.o power.o bus.o \
-			driver.o class.o intf.o platform.o
+			driver.o class.o intf.o platform.o \
+			cpu.o
 
 obj-y		+= fs/
 
+obj-$(CONFIG_HOTPLUG)	+= hotplug.o
+
 export-objs	:= core.o power.o sys.o bus.o driver.o \
-			class.o intf.o
+			class.o intf.o platform.o cpu.o 
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/base/base.h	Fri Sep 27 14:51:04 2002
@@ -50,3 +50,13 @@
 
 extern int driver_attach(struct device_driver * drv);
 extern void driver_detach(struct device_driver * drv);
+
+#ifdef CONFIG_HOTPLUG
+extern int dev_hotplug(struct device *dev, const char *action);
+#else
+static inline int dev_hotplug(struct device *dev, const char *action)
+{
+	return 0;
+}
+#endif
+
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/base/core.c	Fri Sep 27 14:51:03 2002
@@ -23,6 +23,19 @@
 
 #define to_dev(node) container_of(node,struct device,driver_list)
 
+static int probe(struct device * dev, struct device_driver * drv)
+{
+	dev->driver = drv;
+	return drv->probe ? drv->probe(dev) : 0;
+}
+
+static void attach(struct device * dev)
+{
+	spin_lock(&device_lock);
+	list_add_tail(&dev->driver_list,&dev->driver->devices);
+	spin_unlock(&device_lock);
+	devclass_add_device(dev);
+}
 
 /**
  * found_match - do actual binding of device to driver
@@ -43,25 +56,14 @@
 {
 	int error = 0;
 
-	dev->driver = get_driver(drv);
-	if (drv->probe)
-		if (drv->probe(dev))
-			goto ProbeFailed;
-
-	pr_debug("bound device '%s' to driver '%s'\n",
-		 dev->bus_id,drv->name);
-
-	spin_lock(&device_lock);
-	list_add_tail(&dev->driver_list,&drv->devices);
-	spin_unlock(&device_lock);
-	devclass_add_device(dev);
-
-	goto Done;
-
- ProbeFailed:
-	put_driver(drv);
-	dev->driver = NULL;
- Done:
+	if (!(error = probe(dev,get_driver(drv)))) {
+		pr_debug("bound device '%s' to driver '%s'\n",
+			 dev->bus_id,drv->name);
+		attach(dev);
+	} else {
+		put_driver(drv);
+		dev->driver = NULL;
+	}
 	return error;
 }
 
@@ -80,18 +82,19 @@
 	struct device * dev = (struct device *)data;
 	int error = 0;
 
-	if (!dev->driver) {
-		if (drv->bus->match && drv->bus->match(dev,drv))
-			error = found_match(dev,drv);
-	}
+	if (drv->bus->match && drv->bus->match(dev,drv))
+		error = found_match(dev,drv);
 	return error;
 }
 
 static int device_attach(struct device * dev)
 {
 	int error = 0;
-	if (dev->bus)
-		error = bus_for_each_drv(dev->bus,dev,do_device_attach);
+	if (!dev->driver) {
+		if (dev->bus)
+			error = bus_for_each_drv(dev->bus,dev,do_device_attach);
+	} else
+		attach(dev);
 	return error;
 }
 
@@ -103,7 +106,6 @@
 		devclass_remove_device(dev);
 		if (drv && drv->remove)
 			drv->remove(dev);
-
 		dev->driver = NULL;
 	}
 }
@@ -198,6 +200,9 @@
 	if (platform_notify)
 		platform_notify(dev);
 
+	/* notify userspace of device entry */
+	dev_hotplug(dev, "add");
+
  register_done:
 	if (error) {
 		spin_lock(&device_lock);
@@ -252,6 +257,9 @@
 	 */
 	if (platform_notify_remove)
 		platform_notify_remove(dev);
+
+	/* notify userspace that this device is about to disappear */
+	dev_hotplug (dev, "remove");
 
 	device_detach(dev);
 	bus_remove_device(dev);
diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/cpu.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,28 @@
+/*
+ * cpu.c - basic cpu class support
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+
+static int cpu_add_device(struct device * dev)
+{
+	return 0;
+}
+
+struct device_class cpu_devclass = {
+	.name		= "cpu",
+	.add_device	= cpu_add_device,
+};
+
+
+static int __init cpu_devclass_init(void)
+{
+	return devclass_register(&cpu_devclass);
+}
+
+postcore_initcall(cpu_devclass_init);
+
+EXPORT_SYMBOL(cpu_devclass);
diff -Nru a/drivers/base/hotplug.c b/drivers/base/hotplug.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/hotplug.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,103 @@
+/*
+ * drivers/base/hotplug.c - hotplug call code
+ * 
+ * Copyright (c) 2000-2001 David Brownell
+ * Copyright (c) 2002 Greg Kroah-Hartman
+ * Copyright (c) 2002 IBM Corp.
+ *
+ * Based off of drivers/usb/core/usb.c:call_agent(), which was 
+ * written by David Brownell.
+ *
+ */
+
+#define DEBUG 0
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/kmod.h>
+#include <linux/interrupt.h>
+#include "base.h"
+
+/*
+ * hotplugging invokes what /proc/sys/kernel/hotplug says (normally
+ * /sbin/hotplug) when devices get added or removed.
+ *
+ * This invokes a user mode policy agent, typically helping to load driver
+ * or other modules, configure the device, and more.  Drivers can provide
+ * a MODULE_DEVICE_TABLE to help with module loading subtasks.
+ */
+#define BUFFER_SIZE	1024	/* should be enough memory for the env */
+#define NUM_ENVP	32	/* number of env pointers */
+int dev_hotplug (struct device *dev, const char *action)
+{
+	char *argv [3], **envp, *buffer, *scratch;
+	int retval;
+	int i = 0;
+
+	pr_debug ("%s\n", __FUNCTION__);
+	if (!dev)
+		return -ENODEV;
+
+	if (!dev->bus || !dev->bus->hotplug)
+		return -ENODEV;
+
+	if (!hotplug_path [0])
+		return -ENODEV;
+
+	if (in_interrupt ()) {
+		pr_debug ("%s - in_interrupt, not allowed!", __FUNCTION__);
+		return -EIO;
+	}
+
+	if (!current->fs->root) {
+		/* don't try to do anything unless we have a root partition */
+		pr_debug ("%s - %s -- no FS yet\n", __FUNCTION__, action);
+		return -EIO;
+	}
+
+	envp = (char **) kmalloc (NUM_ENVP * sizeof (char *), GFP_KERNEL);
+	if (!envp)
+		return -ENOMEM;
+
+	buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL);
+	if (!buffer) {
+		kfree (envp);
+		return -ENOMEM;
+	}
+
+	/* only one standardized param to hotplug command: the bus name */
+	argv [0] = hotplug_path;
+	argv [1] = dev->bus->name;
+	argv [2] = 0;
+
+	/* minimal command environment */
+	envp [i++] = "HOME=/";
+	envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+
+	scratch = buffer;
+
+	/* action:  add, remove */
+	envp [i++] = scratch;
+	scratch += sprintf (scratch, "ACTION=%s", action) + 1;
+
+	/* have the bus specific function set up the rest of the environment */
+	retval = dev->bus->hotplug (dev, &envp[i], NUM_ENVP - i,
+				    scratch, BUFFER_SIZE - (scratch - buffer));
+	if (retval) {
+		pr_debug ("%s - hotplug() returned %d\n", __FUNCTION__, retval);
+		goto exit;
+	}
+
+	pr_debug ("%s: %s %s %s %s %s %s\n", __FUNCTION__, argv [0], argv[1],
+		  action, envp[0], envp[1], envp[2]);
+	retval = call_usermodehelper (argv [0], argv, envp);
+	if (retval)
+		pr_debug ("%s - call_usermodehelper returned %d\n",
+			  __FUNCTION__, retval);
+
+exit:
+	kfree (buffer);
+	kfree (envp);
+	return retval;
+}
diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
--- a/drivers/base/platform.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/base/platform.c	Fri Sep 27 14:51:03 2002
@@ -9,19 +9,56 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
+static struct device legacy_bus = {
+	.name		= "legacy bus",
+	.bus_id		= "legacy",
+};
+
+/**
+ *	platform_device_register - add a platform-level device
+ *	@dev:	platform device we're adding
+ *
+ */
+int platform_device_register(struct platform_device * pdev)
+{
+	if (!pdev)
+		return -EINVAL;
+
+	if (!pdev->dev.parent)
+		pdev->dev.parent = &legacy_bus;
+
+	pdev->dev.bus = &platform_bus_type;
+	
+	snprintf(pdev->dev.bus_id,BUS_ID_SIZE,"%s%u",pdev->name,pdev->id);
+
+	pr_debug("Registering platform device '%s'. Parent at %s\n",
+		 pdev->dev.bus_id,pdev->dev.parent->bus_id);
+	return device_register(&pdev->dev);
+}
+
+void platform_device_unregister(struct platform_device * pdev)
+{
+	if (pdev)
+		put_device(&pdev->dev);
+}
+	
 static int platform_match(struct device * dev, struct device_driver * drv)
 {
 	return 0;
 }
 
-struct bus_type platform_bus = {
+struct bus_type platform_bus_type = {
 	.name		= "platform",
 	.match		= platform_match,
 };
 
 static int __init platform_bus_init(void)
 {
-	return bus_register(&platform_bus);
+	device_register(&legacy_bus);
+	return bus_register(&platform_bus_type);
 }
 
 postcore_initcall(platform_bus_init);
+
+EXPORT_SYMBOL(platform_device_register);
+EXPORT_SYMBOL(platform_device_unregister);
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/base/sys.c	Fri Sep 27 14:51:02 2002
@@ -6,44 +6,139 @@
  * 
  * This exports a 'system' bus type. 
  * By default, a 'sys' bus gets added to the root of the system. There will
- * always be core system devices. Devices can use register_sys_device() to
+ * always be core system devices. Devices can use sys_device_register() to
  * add themselves as children of the system bus.
  */
 
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/errno.h>
+#include <linux/err.h>
 
+/* The default system device parent. */
 static struct device system_bus = {
        .name           = "System Bus",
        .bus_id         = "sys",
 };
 
-int register_sys_device(struct device * dev)
+
+/**
+ *	sys_register_root - add a subordinate system root
+ *	@root:	new root
+ *	
+ *	This is for NUMA-like systems so they can accurately 
+ *	represent the topology of the entire system.
+ *	As boards are discovered, a new struct sys_root should 
+ *	be allocated and registered. 
+ *	The discovery mechanism should initialize the id field
+ *	of the struture, as well as much of the embedded device
+ *	structure as possible, inlcuding the name, the bus_id
+ *	and parent fields.
+ *
+ *	This simply calls device_register on the embedded device.
+ *	On success, it will use the struct @root->sysdev 
+ *	device to create a pseudo-parent for system devices
+ *	on that board.
+ *
+ *	The platform code can then use @root to specifiy the
+ *	controlling board when discovering and registering 
+ *	system devices.
+ */
+int sys_register_root(struct sys_root * root)
 {
-       int error = -EINVAL;
+	int error = 0;
+
+	if (!root)
+		return -EINVAL;
+
+	pr_debug("Registering system board %d\n",root->id);
+
+	error = device_register(&root->dev);
+	if (!error) {
+		strncpy(root->sysdev.bus_id,"sys",BUS_ID_SIZE);
+		strncpy(root->sysdev.name,"System Bus",DEVICE_NAME_SIZE);
+		root->sysdev.parent = &root->dev;
+		error = device_register(&root->sysdev);
+	};
 
-       if (dev) {
-               if (!dev->parent)
-                       dev->parent = &system_bus;
-               error = device_register(dev);
-       }
-       return error;
+	return error;
 }
 
-void unregister_sys_device(struct device * dev)
+/**
+ *	sys_unregister_root - remove subordinate root from tree
+ *	@root:	subordinate root in question.
+ *
+ *	We only decrement the reference count on @root->sysdev 
+ *	and @root->dev.
+ *	If both are 0, they will be cleaned up by the core.
+ */
+void sys_unegister_root(struct sys_root *  root)
 {
-       if (dev)
-               put_device(dev);
+	put_device(&root->sysdev);
+	put_device(&root->dev);
 }
 
+/**
+ *	sys_device_register - add a system device to the tree
+ *	@sysdev:	device in question
+ *
+ *	The hardest part about this is getting the ancestry right.
+ *	If the device has a parent - super! We do nothing.
+ *	If the device doesn't, but @dev->root is set, then we're
+ *	dealing with a NUMA like architecture where each root
+ *	has a system pseudo-bus to foster the device.
+ *	If not, then we fallback to system_bus (at the top of 
+ *	this file). 
+ *
+ *	One way or another, we call device_register() on it and 
+ *	are done.
+ *
+ *	The caller is also responsible for initializing the bus_id 
+ *	and name fields of @sysdev->dev.
+ */
+int sys_device_register(struct sys_device * sysdev)
+{
+	if (!sysdev)
+		return -EINVAL;
+
+	if (!sysdev->dev.parent) {
+		if (sysdev->root)
+			sysdev->dev.parent = &sysdev->root->sysdev;
+		else
+			sysdev->dev.parent = &system_bus;
+	}
+
+	/* make sure bus type is set */
+	if (!sysdev->dev.bus)
+		sysdev->dev.bus = &system_bus_type;
+
+	/* construct bus_id */
+	snprintf(sysdev->dev.bus_id,BUS_ID_SIZE,"%s%u",sysdev->name,sysdev->id);
+
+	pr_debug("Registering system device %s\n", sysdev->dev.bus_id);
+
+	return device_register(&sysdev->dev);
+}
+
+void sys_device_unregister(struct sys_device * sysdev)
+{
+	if (sysdev)
+		put_device(&sysdev->dev);
+}
+
+struct bus_type system_bus_type = {
+	.name		= "system",
+};
+
 static int sys_bus_init(void)
 {
-       return device_register(&system_bus);
+	bus_register(&system_bus_type);
+	return device_register(&system_bus);
 }
 
 postcore_initcall(sys_bus_init);
-EXPORT_SYMBOL(register_sys_device);
-EXPORT_SYMBOL(unregister_sys_device);
+EXPORT_SYMBOL(system_bus_type);
+EXPORT_SYMBOL(sys_device_register);
+EXPORT_SYMBOL(sys_device_unregister);
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/block/DAC960.c	Fri Sep 27 14:51:05 2002
@@ -2002,11 +2002,6 @@
     Remove the I/O Request Queue.
   */
   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MajorNumber));
-  /*
-    Remove the Disk Partitions array, Partition Sizes array, Block Sizes
-    array, Max Sectors per Request array, and Max Segments per Request array.
-  */
-  blk_clear(MajorNumber);
 }
 
 static long disk_size(DAC960_Controller_T *Controller, int disk)
diff -Nru a/drivers/block/Makefile b/drivers/block/Makefile
--- a/drivers/block/Makefile	Fri Sep 27 14:51:05 2002
+++ b/drivers/block/Makefile	Fri Sep 27 14:51:05 2002
@@ -9,9 +9,9 @@
 #
 
 export-objs	:= elevator.o ll_rw_blk.o loop.o genhd.o acsi.o \
-		   block_ioctl.o
+		   block_ioctl.o deadline-iosched.o
 
-obj-y	:= elevator.o ll_rw_blk.o blkpg.o genhd.o block_ioctl.o
+obj-y	:= elevator.o ll_rw_blk.o blkpg.o genhd.o block_ioctl.o deadline-iosched.o
 
 obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
 obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/block/amiflop.c	Fri Sep 27 14:51:04 2002
@@ -142,10 +142,6 @@
 };
 static int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]);
 
-/* defaults for 3 1/2" HD-Disks */
-static int floppy_sizes[256]={880,880,880,880,720,720,720,720,};
-/* hardsector size assumed to be 512 */
-
 static int amiga_read(int), dos_read(int);
 static void amiga_write(int), dos_write(int);
 static struct fd_data_type data_types[] = {
@@ -155,6 +151,7 @@
 
 /* current info on each unit */
 static struct amiga_floppy_struct unit[FD_MAX_UNITS];
+static char names[FD_MAX_UNITS][4];
 
 static struct timer_list flush_track_timer[FD_MAX_UNITS];
 static struct timer_list post_write_timer;
@@ -1539,12 +1536,6 @@
 				 sizeof(struct floppy_struct)))
 			return -EFAULT;
 		break;
-	case BLKGETSIZE:
-		return put_user(unit[drive].blocks,(unsigned long *)param);
-		break;
-	case BLKGETSIZE64:
-		return put_user((u64)unit[drive].blocks << 9, (u64 *)param);
-		break;
 	case FDSETPRM:
 	case FDDEFPRM:
 		return -EINVAL;
@@ -1653,7 +1644,7 @@
 	unit[drive].dtype=&data_types[system];
 	unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
 		data_types[system].sects*unit[drive].type->sect_mult;
-	floppy_sizes[minor(inode->i_rdev)] = unit[drive].blocks >> 1;
+	set_capacity(&unit[drive].disk, unit[drive].blocks);
 
 	printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,
 	       unit[drive].type->name, data_types[system].name);
@@ -1720,11 +1711,11 @@
 }
 
 static struct block_device_operations floppy_fops = {
-	owner:			THIS_MODULE,
-	open:			floppy_open,
-	release:		floppy_release,
-	ioctl:			fd_ioctl,
-	check_media_change:	amiga_floppy_change,
+	.owner			= THIS_MODULE,
+	.open			= floppy_open,
+	.release		= floppy_release,
+	.ioctl			= fd_ioctl,
+	.check_media_change	= amiga_floppy_change,
 };
 
 void __init amiga_floppy_setup (char *str, int *ints)
@@ -1743,6 +1734,7 @@
 	for(drive=0;drive<FD_MAX_UNITS;drive++) {
 		fd_probe(drive);
 		if (unit[drive].type->code != FD_NODRIVE) {
+			struct gendisk *disk = &unit[drive].disk;
 			drives++;
 			if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) {
 				printk("no mem for ");
@@ -1751,6 +1743,14 @@
 				nomem = 1;
 			}
 			printk("fd%d ",drive);
+			disk->major = MAJOR_NR;
+			disk->first_minor = drive;
+			disk->minor_shift = 0;
+			disk->fops = &floppy_fops;
+			sprintf(names[drive], "fd%d", drive);
+			disk->major_name = names[drive];
+			set_capacity(disk, 880*2);
+			add_disk(disk);
 		}
 	}
 	if ((drives > 0) || (nomem == 0)) {
@@ -1762,6 +1762,14 @@
 	printk("\n");
 	return -ENOMEM;
 }
+ 
+static struct gendisk *floppy_find(int minor)
+{
+	int drive = minor & 3;
+	if (unit[drive].type->code == FD_NODRIVE)
+		return NULL;
+	return &unit[drive].disk;
+}
 
 int __init amiga_floppy_init(void)
 {
@@ -1805,7 +1813,9 @@
 		unregister_blkdev(MAJOR_NR,"fd");
 		return -EBUSY;
 	}
+	blk_set_probe(MAJOR_NR, floppy_find);
 	if (fd_probe_drives() < 1) { /* No usable drives */
+		blk_set_probe(MAJOR_NR, NULL);
 		free_irq(IRQ_AMIGA_CIAA_TB, NULL);
 		free_irq(IRQ_AMIGA_DSKBLK, NULL);
 		amiga_chip_free(raw_buf);
@@ -1838,8 +1848,6 @@
 	post_write_timer.function = post_write;
   
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_fd_request, &amiflop_lock);
-	blk_size[MAJOR_NR] = floppy_sizes;
-
 	for (i = 0; i < 128; i++)
 		mfmdecode[i]=255;
 	for (i = 0; i < 16; i++)
@@ -1867,9 +1875,13 @@
 {
 	int i;
 
-	for( i = 0; i < FD_MAX_UNITS; i++)
-		if (unit[i].type->code != FD_NODRIVE)
+	for( i = 0; i < FD_MAX_UNITS; i++) {
+		if (unit[i].type->code != FD_NODRIVE) {
+			del_gendisk(&unit[i].disk);
 			kfree(unit[i].trackbuf);
+		}
+	}
+	blk_set_probe(MAJOR_NR, NULL);
 	free_irq(IRQ_AMIGA_CIAA_TB, NULL);
 	free_irq(IRQ_AMIGA_DSKBLK, NULL);
 	custom.dmacon = DMAF_DISK; /* disable DMA */
@@ -1877,6 +1889,5 @@
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 	release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
 	unregister_blkdev(MAJOR_NR, "fd");
-	blk_clear(MAJOR_NR);
 }
 #endif
diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c
--- a/drivers/block/ataflop.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/block/ataflop.c	Fri Sep 27 14:51:03 2002
@@ -222,8 +222,6 @@
  */
 static struct atari_disk_type default_params[FD_MAX_UNITS];
 
-static int floppy_sizes[256];
-
 /* current info on each unit */
 static struct atari_floppy_struct {
 	int connected;				/* !=0 : drive is connected */
@@ -237,6 +235,8 @@
 	unsigned int wpstat;	/* current state of WP signal (for
 				   disk change detection) */
 	int flags;		/* flags */
+	struct gendisk disk;
+	char name[4];
 } unit[FD_MAX_UNITS];
 
 #define	UD	unit[drive]
@@ -1094,7 +1094,8 @@
 			    if (SUDT[-1].blocks > ReqBlock) {
 				/* try another disk type */
 				SUDT--;
-				floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
+				set_capacity(&unit[SelectedDrive].disk,
+							SUDT->blocks);
 			    } else
 				Probing = 0;
 			}
@@ -1108,7 +1109,8 @@
 /* record not found, but not probing. Maybe stretch wrong ? Restart probing */
 			if (SUD.autoprobe) {
 				SUDT = disk_type + StartDiskType[DriveType];
-				floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
+				set_capacity(&unit[SelectedDrive].disk,
+							SUDT->blocks);
 				Probing = 1;
 			}
 		}
@@ -1469,7 +1471,7 @@
 		if (!UDT) {
 			Probing = 1;
 			UDT = disk_type + StartDiskType[DriveType];
-			floppy_sizes[drive] = UDT->blocks >> 1;
+			set_capacity(&unit[drive].disk, UDT->blocks);
 			UD.autoprobe = 1;
 		}
 	} 
@@ -1487,7 +1489,7 @@
 		}
 		type = minor2disktype[type].index;
 		UDT = &disk_type[type];
-		floppy_sizes[drive] = UDT->blocks >> 1;
+		set_capacity(&unit[drive].disk, UDT->blocks);
 		UD.autoprobe = 0;
 	}
 	
@@ -1547,7 +1549,6 @@
 	drive &= 3;
 	switch (cmd) {
 	case FDGETPRM:
-	case BLKGETSIZE:
 		if (type) {
 			if (--type >= NUM_DISK_MINORS)
 				return -ENODEV;
@@ -1565,9 +1566,6 @@
 			else
 				dtp = UDT;
 		}
-		if (cmd == BLKGETSIZE)
-			return put_user(dtp->blocks, (unsigned long *)param);
-
 		memset((void *)&getprm, 0, sizeof(getprm));
 		getprm.size = dtp->blocks;
 		getprm.sect = dtp->spt;
@@ -1638,7 +1636,7 @@
 				    printk (KERN_INFO "floppy%d: setting %s %p!\n",
 				        drive, dtp->name, dtp);
 				UDT = dtp;
-				floppy_sizes[drive] = UDT->blocks >> 1;
+				set_capacity(&unit[drive].disk, UDT->blocks);
 
 				if (cmd == FDDEFPRM) {
 				  /* save settings as permanent default type */
@@ -1684,7 +1682,7 @@
 		}
 
 		UDT = dtp;
-		floppy_sizes[drive] = UDT->blocks >> 1;
+		set_capacity(&unit[drive].disk, UDT->blocks);
 
 		return 0;
 	case FDMSGON:
@@ -1707,7 +1705,7 @@
 		UDT = NULL;
 		/* MSch: invalidate default_params */
 		default_params[drive].blocks  = 0;
-		floppy_sizes[drive] = MAX_DISK_SIZE;
+		set_capacity(&unit[drive].disk, MAX_DISK_SIZE * 2);
 	case FDFMTEND:
 	case FDFLUSH:
 		/* invalidate the buffer track to force a reread */
@@ -1861,11 +1859,6 @@
 	int drive, type;
 	int old_dev;
 
-	if (!filp) {
-		DPRINT (("Weird, open called with filp=0\n"));
-		return -EIO;
-	}
-
 	drive = minor(inode->i_rdev) & 3;
 	type  = minor(inode->i_rdev) >> 2;
 	DPRINT(("fd_open: type=%d\n",type));
@@ -1930,6 +1923,15 @@
 	revalidate:		floppy_revalidate,
 };
 
+static struct gendisk *floppy_find(int minor)
+{
+	int drive = minor & 3;
+	int type  = minor >> 2;
+	if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
+		return NULL;
+	return &unit[drive].disk;
+}
+
 int __init atari_floppy_init (void)
 {
 	int i;
@@ -1972,17 +1974,17 @@
 	for (i = 0; i < FD_MAX_UNITS; i++) {
 		unit[i].track = -1;
 		unit[i].flags = 0;
+		unit[i].disk.major = MAJOR_NR;
+		unit[i].disk.first_minor = i;
+		sprintf(unit[i].name, "fd%d", i);
+		unit[i].disk.major_name = names[drive];
+		unit[i].disk.fops = &floppy_fops;
+		set_capacity(&unit[i].disk, MAX_DISK_SIZE * 2);
+		add_disk(&unit[i].disk);
 	}
 
-	for (i = 0; i < 256; i++)
-		if ((i >> 2) > 0 && (i >> 2) <= NUM_DISK_MINORS) {
-			int type = minor2disktype[(i >> 2) - 1].index;
-			floppy_sizes[i] = disk_type[type].blocks >> 1;
-		} else
-			floppy_sizes[i] = MAX_DISK_SIZE;
-
-	blk_size[MAJOR_NR] = floppy_sizes;
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_fd_request, &ataflop_lock);
+	blk_set_probe(MAJOR_NR, floppy_find);
 
 	printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n",
 	       DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E',
@@ -2034,7 +2036,11 @@
 
 void cleanup_module (void)
 {
+	int i;
+	for (i = 0; i < FD_MAX_UNITS; i++)
+		del_gendisk(&unit[i].disk);
 	unregister_blkdev(MAJOR_NR, "fd");
+	blk_set_probe(MAJOR_NR, NULL);
 
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 	del_timer_sync(&fd_timer);
diff -Nru a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/block/deadline-iosched.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,601 @@
+/*
+ *  linux/drivers/block/deadline-iosched.c
+ *
+ *  Deadline i/o scheduler.
+ *
+ *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
+ */
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
+#include <linux/bio.h>
+#include <linux/blk.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/compiler.h>
+#include <linux/hash.h>
+
+/*
+ * feel free to try other values :-). read_expire value is the timeout for
+ * reads, our goal is to start a request "around" the time when it expires.
+ * fifo_batch is how many steps along the sorted list we will take when the
+ * front fifo request expires.
+ */
+static int read_expire = HZ / 2;	/* 500ms start timeout */
+static int fifo_batch = 32;		/* 4 seeks, or 64 contig */
+static int seek_cost = 16;		/* seek is 16 times more expensive */
+
+/*
+ * how many times reads are allowed to starve writes
+ */
+static int writes_starved = 2;
+
+static const int deadline_hash_shift = 8;
+#define DL_HASH_BLOCK(sec)	((sec) >> 3)
+#define DL_HASH_FN(sec)		(hash_long(DL_HASH_BLOCK((sec)), deadline_hash_shift))
+#define DL_HASH_ENTRIES		(1 << deadline_hash_shift)
+
+#define DL_INVALIDATE_HASH(dd)				\
+	do {						\
+		if (!++(dd)->hash_valid_count)		\
+			(dd)->hash_valid_count = 1;	\
+	} while (0)
+
+struct deadline_data {
+	/*
+	 * run time data
+	 */
+	struct list_head sort_list[2];	/* sorted listed */
+	struct list_head read_fifo;	/* fifo list */
+	struct list_head *dispatch;	/* driver dispatch queue */
+	struct list_head *hash;		/* request hash */
+	sector_t last_sector;		/* last sector sent to drive */
+	unsigned long hash_valid_count;	/* barrier hash count */
+	unsigned int starved;		/* writes starved */
+
+	/*
+	 * settings that change how the i/o scheduler behaves
+	 */
+	unsigned int fifo_batch;
+	unsigned long read_expire;
+	unsigned int seek_cost;
+	unsigned int writes_starved;
+};
+
+/*
+ * pre-request data.
+ */
+struct deadline_rq {
+	struct list_head fifo;
+	struct list_head hash;
+	unsigned long hash_valid_count;
+	struct request *request;
+	unsigned long expires;
+};
+
+static kmem_cache_t *drq_pool;
+
+#define RQ_DATA(rq)	((struct deadline_rq *) (rq)->elevator_private)
+
+/*
+ * rq hash
+ */
+static inline void __deadline_del_rq_hash(struct deadline_rq *drq)
+{
+	drq->hash_valid_count = 0;
+	list_del_init(&drq->hash);
+}
+
+#define ON_HASH(drq)	(drq)->hash_valid_count
+static inline void deadline_del_rq_hash(struct deadline_rq *drq)
+{
+	if (ON_HASH(drq))
+		__deadline_del_rq_hash(drq);
+}
+
+static inline void
+deadline_add_rq_hash(struct deadline_data *dd, struct deadline_rq *drq)
+{
+	struct request *rq = drq->request;
+
+	BUG_ON(ON_HASH(drq));
+
+	drq->hash_valid_count = dd->hash_valid_count;
+	list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq->sector +rq->nr_sectors)]);
+}
+
+#define list_entry_hash(ptr)	list_entry((ptr), struct deadline_rq, hash)
+static struct request *
+deadline_find_hash(struct deadline_data *dd, sector_t offset)
+{
+	struct list_head *hash_list = &dd->hash[DL_HASH_FN(offset)];
+	struct list_head *entry, *next = hash_list->next;
+	struct deadline_rq *drq;
+	struct request *rq = NULL;
+
+	while ((entry = next) != hash_list) {
+		next = entry->next;
+		drq = list_entry_hash(entry);
+
+		BUG_ON(!drq->hash_valid_count);
+
+		if (!rq_mergeable(drq->request)
+		    || drq->hash_valid_count != dd->hash_valid_count) {
+			__deadline_del_rq_hash(drq);
+			continue;
+		}
+
+		if (drq->request->sector + drq->request->nr_sectors == offset) {
+			rq = drq->request;
+			break;
+		}
+	}
+
+	return rq;
+}
+
+static sector_t deadline_get_last_sector(struct deadline_data *dd)
+{
+	sector_t last_sec = dd->last_sector;
+
+	/*
+	 * if dispatch is non-empty, disregard last_sector and check last one
+	 */
+	if (!list_empty(dd->dispatch)) {
+		struct request *__rq = list_entry_rq(dd->dispatch->prev);
+
+		last_sec = __rq->sector + __rq->nr_sectors;
+	}
+
+	return last_sec;
+}
+
+static int
+deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+	const int data_dir = bio_data_dir(bio);
+	struct list_head *entry, *sort_list;
+	struct deadline_rq *drq;
+	struct request *__rq;
+	int ret = ELEVATOR_NO_MERGE;
+
+	/*
+	 * try last_merge to avoid going to hash
+	 */
+	ret = elv_try_last_merge(q, bio);
+	if (ret != ELEVATOR_NO_MERGE) {
+		*insert = q->last_merge;
+		goto out;
+	}
+
+	/*
+	 * see if the merge hash can satisfy a back merge
+	 */
+	if ((__rq = deadline_find_hash(dd, bio->bi_sector))) {
+		BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
+
+		if (elv_rq_merge_ok(__rq, bio)) {
+			*insert = &__rq->queuelist;
+			ret = ELEVATOR_BACK_MERGE;
+			goto out;
+		}
+	}
+
+	/*
+	 * scan list from back to find insertion point.
+	 */
+	entry = sort_list = &dd->sort_list[data_dir];
+	while ((entry = entry->prev) != sort_list) {
+		__rq = list_entry_rq(entry);
+		drq = RQ_DATA(__rq);
+
+		BUG_ON(__rq->flags & REQ_STARTED);
+
+		if (!(__rq->flags & REQ_CMD))
+			continue;
+
+		if (!*insert && bio_rq_in_between(bio, __rq, sort_list))
+			*insert = &__rq->queuelist;
+
+		if (__rq->flags & REQ_BARRIER)
+			break;
+
+		/*
+		 * checking for a front merge, hash will miss those
+		 */
+		if (__rq->sector - bio_sectors(bio) == bio->bi_sector) {
+			ret = elv_try_merge(__rq, bio);
+			if (ret != ELEVATOR_NO_MERGE) {
+				*insert = &__rq->queuelist;
+				break;
+			}
+		}
+	}
+
+	/*
+	 * no insertion point found, check the very front
+	 */
+	if (!*insert && !list_empty(sort_list)) {
+		__rq = list_entry_rq(sort_list->next);
+
+		if (bio->bi_sector + bio_sectors(bio) < __rq->sector &&
+		    bio->bi_sector > deadline_get_last_sector(dd))
+			*insert = sort_list;
+	}
+
+out:
+	return ret;
+}
+
+static void deadline_merged_request(request_queue_t *q, struct request *req)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+	struct deadline_rq *drq = RQ_DATA(req);
+
+	deadline_del_rq_hash(drq);
+	deadline_add_rq_hash(dd, drq);
+
+	q->last_merge = &req->queuelist;
+}
+
+static void
+deadline_merge_request(request_queue_t *q, struct request *req, struct request *next)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+	struct deadline_rq *drq = RQ_DATA(req);
+	struct deadline_rq *dnext = RQ_DATA(next);
+
+	BUG_ON(!drq);
+	BUG_ON(!dnext);
+
+	deadline_del_rq_hash(drq);
+	deadline_add_rq_hash(dd, drq);
+
+	/*
+	 * if dnext expires before drq, assign it's expire time to drq
+	 * and move into dnext position (dnext will be deleted) in fifo
+	 */
+	if (!list_empty(&drq->fifo) && !list_empty(&dnext->fifo)) {
+		if (time_before(dnext->expires, drq->expires)) {
+			list_move(&drq->fifo, &dnext->fifo);
+			drq->expires = dnext->expires;
+		}
+	}
+}
+
+/*
+ * move request from sort list to dispatch queue. maybe remove from rq hash
+ * here too?
+ */
+static inline void
+deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq)
+{
+	struct deadline_rq *drq = RQ_DATA(rq);
+
+	list_move_tail(&rq->queuelist, dd->dispatch);
+	list_del_init(&drq->fifo);
+}
+
+/*
+ * move along sort list and move entries to dispatch queue, starting from rq
+ */
+static void deadline_move_requests(struct deadline_data *dd, struct request *rq)
+{
+	struct list_head *sort_head = &dd->sort_list[rq_data_dir(rq)];
+	sector_t last_sec = deadline_get_last_sector(dd);
+	int batch_count = dd->fifo_batch;
+
+	do {
+		struct list_head *nxt = rq->queuelist.next;
+		int this_rq_cost;
+
+		/*
+		 * take it off the sort and fifo list, move
+		 * to dispatch queue
+		 */
+		deadline_move_to_dispatch(dd, rq);
+
+		/*
+		 * if this is the last entry, don't bother doing accounting
+		 */
+		if (nxt == sort_head)
+			break;
+
+		this_rq_cost = dd->seek_cost;
+		if (rq->sector == last_sec)
+			this_rq_cost = (rq->nr_sectors + 255) >> 8;
+
+		batch_count -= this_rq_cost;
+		if (batch_count <= 0)
+			break;
+
+		last_sec = rq->sector + rq->nr_sectors;
+		rq = list_entry_rq(nxt);
+	} while (1);
+}
+
+/*
+ * returns 0 if there are no expired reads on the fifo, 1 otherwise
+ */
+#define list_entry_fifo(ptr)	list_entry((ptr), struct deadline_rq, fifo)
+static inline int deadline_check_fifo(struct deadline_data *dd)
+{
+	if (!list_empty(&dd->read_fifo)) {
+		struct deadline_rq *drq = list_entry_fifo(dd->read_fifo.next);
+
+		/*
+		 * drq is expired!
+		 */
+		if (time_after(jiffies, drq->expires))
+			return 1;
+	}
+
+	return 0;
+}
+
+static struct request *deadline_next_request(request_queue_t *q)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+	struct deadline_rq *drq;
+	struct list_head *nxt;
+	struct request *rq;
+	int writes;
+
+	/*
+	 * if still requests on the dispatch queue, just grab the first one
+	 */
+	if (!list_empty(&q->queue_head)) {
+dispatch:
+		rq = list_entry_rq(q->queue_head.next);
+		dd->last_sector = rq->sector + rq->nr_sectors;
+		return rq;
+	}
+
+	writes = !list_empty(&dd->sort_list[WRITE]);
+
+	/*
+	 * if we have expired entries on the fifo list, move some to dispatch
+	 */
+	if (deadline_check_fifo(dd)) {
+		if (writes && (dd->starved++ >= dd->writes_starved))
+			goto dispatch_writes;
+
+		nxt = dd->read_fifo.next;
+		drq = list_entry_fifo(nxt);
+		deadline_move_requests(dd, drq->request);
+		goto dispatch;
+	}
+
+	if (!list_empty(&dd->sort_list[READ])) {
+		if (writes && (dd->starved++ >= dd->writes_starved))
+			goto dispatch_writes;
+
+		nxt = dd->sort_list[READ].next;
+		deadline_move_requests(dd, list_entry_rq(nxt));
+		goto dispatch;
+	}
+
+	/*
+	 * either there are no reads expired or on sort list, or the reads
+	 * have starved writes for too long. dispatch some writes
+	 */
+	if (writes) {
+dispatch_writes:
+		nxt = dd->sort_list[WRITE].next;
+		deadline_move_requests(dd, list_entry_rq(nxt));
+		dd->starved = 0;
+		goto dispatch;
+	}
+
+	BUG_ON(!list_empty(&dd->sort_list[READ]));
+	BUG_ON(writes);
+	return NULL;
+}
+
+static void
+deadline_add_request(request_queue_t *q, struct request *rq, struct list_head *insert_here)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+	struct deadline_rq *drq = RQ_DATA(rq);
+	const int data_dir = rq_data_dir(rq);
+
+	/*
+	 * flush hash on barrier insert, as not to allow merges before a
+	 * barrier.
+	 */
+	if (unlikely(rq->flags & REQ_BARRIER)) {
+		DL_INVALIDATE_HASH(dd);
+		q->last_merge = NULL;
+	}
+
+	/*
+	 * add to sort list
+	 */
+	if (!insert_here)
+		insert_here = dd->sort_list[data_dir].prev;
+
+	list_add(&rq->queuelist, insert_here);
+
+	if (unlikely(!(rq->flags & REQ_CMD)))
+		return;
+
+	if (rq_mergeable(rq)) {
+		deadline_add_rq_hash(dd, drq);
+
+		if (!q->last_merge)
+			q->last_merge = &rq->queuelist;
+	}
+
+	if (data_dir == READ) {
+		/*
+		 * set expire time and add to fifo list
+		 */
+		drq->expires = jiffies + dd->read_expire;
+		list_add_tail(&drq->fifo, &dd->read_fifo);
+	}
+}
+
+static void deadline_remove_request(request_queue_t *q, struct request *rq)
+{
+	struct deadline_rq *drq = RQ_DATA(rq);
+
+	if (drq) {
+		list_del_init(&drq->fifo);
+		deadline_del_rq_hash(drq);
+	}
+}
+
+static int deadline_queue_empty(request_queue_t *q)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+
+	if (!list_empty(&dd->sort_list[WRITE]) ||
+	    !list_empty(&dd->sort_list[READ]) ||
+	    !list_empty(&q->queue_head))
+		return 0;
+
+	BUG_ON(!list_empty(&dd->read_fifo));
+	return 1;
+}
+
+static struct list_head *
+deadline_get_sort_head(request_queue_t *q, struct request *rq)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+
+	return &dd->sort_list[rq_data_dir(rq)];
+}
+
+static void deadline_exit(request_queue_t *q, elevator_t *e)
+{
+	struct deadline_data *dd = e->elevator_data;
+	struct deadline_rq *drq;
+	struct request *rq;
+	int i;
+
+	BUG_ON(!list_empty(&dd->read_fifo));
+	BUG_ON(!list_empty(&dd->sort_list[READ]));
+	BUG_ON(!list_empty(&dd->sort_list[WRITE]));
+
+	for (i = READ; i <= WRITE; i++) {
+		struct request_list *rl = &q->rq[i];
+		struct list_head *entry = &rl->free;
+
+		if (list_empty(&rl->free))
+			continue;
+	
+		while ((entry = entry->next) != &rl->free) {
+			rq = list_entry_rq(entry);
+
+			if ((drq = RQ_DATA(rq)) == NULL)
+				continue;
+
+			rq->elevator_private = NULL;
+			kmem_cache_free(drq_pool, drq);
+		}
+	}
+
+	kfree(dd->hash);
+	kfree(dd);
+}
+
+/*
+ * initialize elevator private data (deadline_data), and alloc a drq for
+ * each request on the free lists
+ */
+static int deadline_init(request_queue_t *q, elevator_t *e)
+{
+	struct deadline_data *dd;
+	struct deadline_rq *drq;
+	struct request *rq;
+	int i, ret = 0;
+
+	if (!drq_pool)
+		return -ENOMEM;
+
+	dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+	if (!dd)
+		return -ENOMEM;
+	memset(dd, 0, sizeof(*dd));
+
+	dd->hash = kmalloc(sizeof(struct list_head)*DL_HASH_ENTRIES,GFP_KERNEL);
+	if (!dd->hash) {
+		kfree(dd);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < DL_HASH_ENTRIES; i++)
+		INIT_LIST_HEAD(&dd->hash[i]);
+
+	INIT_LIST_HEAD(&dd->read_fifo);
+	INIT_LIST_HEAD(&dd->sort_list[READ]);
+	INIT_LIST_HEAD(&dd->sort_list[WRITE]);
+	dd->dispatch = &q->queue_head;
+	dd->fifo_batch = fifo_batch;
+	dd->read_expire = read_expire;
+	dd->seek_cost = seek_cost;
+	dd->hash_valid_count = 1;
+	dd->writes_starved = writes_starved;
+	e->elevator_data = dd;
+
+	for (i = READ; i <= WRITE; i++) {
+		struct request_list *rl = &q->rq[i];
+		struct list_head *entry = &rl->free;
+
+		if (list_empty(&rl->free))
+			continue;
+	
+		while ((entry = entry->next) != &rl->free) {
+			rq = list_entry_rq(entry);
+
+			drq = kmem_cache_alloc(drq_pool, GFP_KERNEL);
+			if (!drq) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			memset(drq, 0, sizeof(*drq));
+			INIT_LIST_HEAD(&drq->fifo);
+			INIT_LIST_HEAD(&drq->hash);
+			drq->request = rq;
+			rq->elevator_private = drq;
+		}
+	}
+
+	if (ret)
+		deadline_exit(q, e);
+
+	return ret;
+}
+
+static int __init deadline_slab_setup(void)
+{
+	drq_pool = kmem_cache_create("deadline_drq", sizeof(struct deadline_rq),
+				     0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+	if (!drq_pool)
+		panic("deadline: can't init slab pool\n");
+
+	return 0;
+}
+
+module_init(deadline_slab_setup);
+
+elevator_t iosched_deadline = {
+	.elevator_merge_fn = 		deadline_merge,
+	.elevator_merged_fn =		deadline_merged_request,
+	.elevator_merge_req_fn =	deadline_merge_request,
+	.elevator_next_req_fn =		deadline_next_request,
+	.elevator_add_req_fn =		deadline_add_request,
+	.elevator_remove_req_fn =	deadline_remove_request,
+	.elevator_queue_empty_fn =	deadline_queue_empty,
+	.elevator_get_sort_head_fn =	deadline_get_sort_head,
+	.elevator_init_fn =		deadline_init,
+	.elevator_exit_fn =		deadline_exit,
+};
+
+EXPORT_SYMBOL(iosched_deadline);
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/block/elevator.c	Fri Sep 27 14:51:05 2002
@@ -136,8 +136,7 @@
 	return ret;
 }
 
-inline int elv_try_last_merge(request_queue_t *q, struct request **req,
-			      struct bio *bio)
+inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
 {
 	int ret = ELEVATOR_NO_MERGE;
 
@@ -150,133 +149,29 @@
 
 		if (!rq_mergeable(__rq))
 			q->last_merge = NULL;
-		else if ((ret = elv_try_merge(__rq, bio)))
-			*req = __rq;
+		else
+			ret = elv_try_merge(__rq, bio);
 	}
 
 	return ret;
 }
 
 /*
- * elevator_linux starts here
- */
-int elevator_linus_merge(request_queue_t *q, struct request **req,
-			 struct bio *bio)
-{
-	struct list_head *entry;
-	struct request *__rq;
-	int ret;
-
-	if ((ret = elv_try_last_merge(q, req, bio)))
-		return ret;
-
-	entry = &q->queue_head;
-	ret = ELEVATOR_NO_MERGE;
-	while ((entry = entry->prev) != &q->queue_head) {
-		__rq = list_entry_rq(entry);
-
-		if (__rq->flags & (REQ_BARRIER | REQ_STARTED))
-			break;
-		if (!(__rq->flags & REQ_CMD))
-			continue;
-
-		if (elv_linus_sequence(__rq) < bio_sectors(bio))
-			break;
-
-		if (!*req && bio_rq_in_between(bio, __rq, &q->queue_head))
-			*req = __rq;
-
-		if ((ret = elv_try_merge(__rq, bio))) {
-			if (ret == ELEVATOR_FRONT_MERGE)
-				elv_linus_sequence(__rq) -= bio_sectors(bio);
-			*req = __rq;
-			q->last_merge = &__rq->queuelist;
-			break;
-		}
-	}
-
-	/*
-	 * if *req, it's either a seek or merge in the middle of the queue
-	 */
-	if (*req) {
-		struct list_head *entry = &(*req)->queuelist;
-		int cost = ret ? 1 : ELV_LINUS_SEEK_COST;
-
-		while ((entry = entry->next) != &q->queue_head) {
-			__rq = list_entry_rq(entry);
-			elv_linus_sequence(__rq) -= cost;
-		}
-	}
-
-	return ret;
-}
-
-void elevator_linus_merge_req(request_queue_t *q, struct request *req,
-			      struct request *next)
-{
-	if (elv_linus_sequence(next) < elv_linus_sequence(req))
-		elv_linus_sequence(req) = elv_linus_sequence(next);
-}
-
-void elevator_linus_add_request(request_queue_t *q, struct request *rq,
-				struct list_head *insert_here)
-{
-	elevator_t *e = &q->elevator;
-	int lat = 0, *latency = e->elevator_data;
-
-	if (!insert_here)
-		insert_here = q->queue_head.prev;
-
-	if (!(rq->flags & REQ_BARRIER))
-		lat = latency[rq_data_dir(rq)];
-
-	elv_linus_sequence(rq) = lat;
-
-	list_add(&rq->queuelist, insert_here);
-
-	/*
-	 * new merges must not precede this barrier
-	 */
-	if (rq->flags & REQ_BARRIER)
-		q->last_merge = NULL;
-	else if (!q->last_merge)
-		q->last_merge = &rq->queuelist;
-}
-
-int elevator_linus_init(request_queue_t *q, elevator_t *e)
-{
-	int *latency;
-
-	latency = kmalloc(2 * sizeof(int), GFP_KERNEL);
-	if (!latency)
-		return -ENOMEM;
-
-	latency[READ] = 1024;
-	latency[WRITE] = 2048;
-
-	e->elevator_data = latency;
-	return 0;
-}
-
-void elevator_linus_exit(request_queue_t *q, elevator_t *e)
-{
-	kfree(e->elevator_data);
-}
-
-/*
  * elevator noop
  *
  * See if we can find a request that this buffer can be coalesced with.
  */
-int elevator_noop_merge(request_queue_t *q, struct request **req,
+int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
 			struct bio *bio)
 {
 	struct list_head *entry = &q->queue_head;
 	struct request *__rq;
 	int ret;
 
-	if ((ret = elv_try_last_merge(q, req, bio)))
+	if ((ret = elv_try_last_merge(q, bio))) {
+		*insert = q->last_merge;
 		return ret;
+	}
 
 	while ((entry = entry->prev) != &q->queue_head) {
 		__rq = list_entry_rq(entry);
@@ -288,7 +183,7 @@
 			continue;
 
 		if ((ret = elv_try_merge(__rq, bio))) {
-			*req = __rq;
+			*insert = &__rq->queuelist;
 			q->last_merge = &__rq->queuelist;
 			return ret;
 		}
@@ -346,16 +241,24 @@
 	return 0;
 }
 
-int elv_merge(request_queue_t *q, struct request **rq, struct bio *bio)
+int elv_merge(request_queue_t *q, struct list_head **entry, struct bio *bio)
 {
 	elevator_t *e = &q->elevator;
 
 	if (e->elevator_merge_fn)
-		return e->elevator_merge_fn(q, rq, bio);
+		return e->elevator_merge_fn(q, entry, bio);
 
 	return ELEVATOR_NO_MERGE;
 }
 
+void elv_merged_request(request_queue_t *q, struct request *rq)
+{
+	elevator_t *e = &q->elevator;
+
+	if (e->elevator_merged_fn)
+		e->elevator_merged_fn(q, rq);
+}
+
 void elv_merge_requests(request_queue_t *q, struct request *rq,
 			     struct request *next)
 {
@@ -440,15 +343,6 @@
 	return &q->queue_head;
 }
 
-elevator_t elevator_linus = {
-	elevator_merge_fn:		elevator_linus_merge,
-	elevator_merge_req_fn:		elevator_linus_merge_req,
-	elevator_next_req_fn:		elevator_noop_next_request,
-	elevator_add_req_fn:		elevator_linus_add_request,
-	elevator_init_fn:		elevator_linus_init,
-	elevator_exit_fn:		elevator_linus_exit,
-};
-
 elevator_t elevator_noop = {
 	elevator_merge_fn:		elevator_noop_merge,
 	elevator_next_req_fn:		elevator_noop_next_request,
@@ -457,7 +351,6 @@
 
 module_init(elevator_global_init);
 
-EXPORT_SYMBOL(elevator_linus);
 EXPORT_SYMBOL(elevator_noop);
 
 EXPORT_SYMBOL(__elv_add_request);
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/block/floppy.c	Fri Sep 27 14:51:03 2002
@@ -239,7 +239,6 @@
 
 static int irqdma_allocated;
 
-#define CURRENT current_req
 #define LOCAL_END_REQUEST
 #define MAJOR_NR FLOPPY_MAJOR
 #define DEVICE_NAME "floppy"
@@ -600,7 +599,10 @@
 					 * expressed in units of 512 bytes */
 
 #ifndef fd_eject
-#define fd_eject(x) -EINVAL
+static inline int fd_eject(int drive)
+{
+	return -EINVAL;
+}
 #endif
 
 #ifdef DEBUGT
@@ -662,12 +664,12 @@
 static int output_log_pos;
 #endif
 
-#define CURRENTD -1
+#define current_reqD -1
 #define MAXTIMEOUT -2
 
 static void reschedule_timeout(int drive, const char *message, int marg)
 {
-	if (drive == CURRENTD)
+	if (drive == current_reqD)
 		drive = current_drive;
 	del_timer(&fd_timeout);
 	if (drive < 0 || drive > N_DRIVE) {
@@ -1895,7 +1897,7 @@
 		printk("now=%lu\n",jiffies);
 	}
 	printk("cont=%p\n", cont);
-	printk("CURRENT=%p\n", CURRENT);
+	printk("current_req=%p\n", current_req);
 	printk("command_status=%d\n", command_status);
 	printk("\n");
 }
@@ -2001,7 +2003,7 @@
 
 static void floppy_start(void)
 {
-	reschedule_timeout(CURRENTD, "floppy start", 0);
+	reschedule_timeout(current_reqD, "floppy start", 0);
 
 	scandrives();
 #ifdef DCL_DEBUG
@@ -2305,7 +2307,7 @@
 	end_that_request_last(req);
 
 	/* We're done with the request */
-	CURRENT = NULL;
+	current_req = NULL;
 }
 
 
@@ -2314,7 +2316,7 @@
 static void request_done(int uptodate)
 {
 	struct request_queue *q = QUEUE;
-	struct request *req = CURRENT;
+	struct request *req = current_req;
 	unsigned long flags;
 	int block;
 
@@ -2438,7 +2440,7 @@
 	}
 
 	if (CT(COMMAND) != FD_READ || 
-	     raw_cmd->kernel_data == CURRENT->buffer){
+	     raw_cmd->kernel_data == current_req->buffer){
 		/* transfer directly from buffer */
 		cont->done(1);
 	} else if (CT(COMMAND) == FD_READ){
@@ -2457,10 +2459,10 @@
 	int size, i;
 	char *base;
 
-	base = bio_data(CURRENT->bio);
+	base = bio_data(current_req->bio);
 	size = 0;
 
-	rq_for_each_bio(bio, CURRENT) {
+	rq_for_each_bio(bio, current_req) {
 		bio_for_each_segment(bv, bio, i) {
 			if (page_address(bv->bv_page) + bv->bv_offset != base + size)
 				break;
@@ -2499,23 +2501,23 @@
 
 	max_sector = transfer_size(ssize,
 				   minimum(max_sector, max_sector_2),
-				   CURRENT->nr_sectors);
+				   current_req->nr_sectors);
 
 	if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
-	    buffer_max > fsector_t + CURRENT->nr_sectors)
+	    buffer_max > fsector_t + current_req->nr_sectors)
 		current_count_sectors = minimum(buffer_max - fsector_t,
-						CURRENT->nr_sectors);
+						current_req->nr_sectors);
 
 	remaining = current_count_sectors << 9;
 #ifdef FLOPPY_SANITY_CHECK
-	if ((remaining >> 9) > CURRENT->nr_sectors  &&
+	if ((remaining >> 9) > current_req->nr_sectors  &&
 	    CT(COMMAND) == FD_WRITE){
 		DPRINT("in copy buffer\n");
 		printk("current_count_sectors=%ld\n", current_count_sectors);
 		printk("remaining=%d\n", remaining >> 9);
-		printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
-		printk("CURRENT->current_nr_sectors=%u\n",
-		       CURRENT->current_nr_sectors);
+		printk("current_req->nr_sectors=%ld\n",current_req->nr_sectors);
+		printk("current_req->current_nr_sectors=%u\n",
+		       current_req->current_nr_sectors);
 		printk("max_sector=%d\n", max_sector);
 		printk("ssize=%d\n", ssize);
 	}
@@ -2525,9 +2527,9 @@
 
 	dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9);
 
-	size = CURRENT->current_nr_sectors << 9;
+	size = current_req->current_nr_sectors << 9;
 
-	rq_for_each_bio(bio, CURRENT) {
+	rq_for_each_bio(bio, current_req) {
 		bio_for_each_segment(bv, bio, i) {
 			if (!remaining)
 				break;
@@ -2634,16 +2636,16 @@
 		return 0;
 	}
 
-	set_fdc(DRIVE(CURRENT->rq_dev));
+	set_fdc(DRIVE(current_req->rq_dev));
 
 	raw_cmd = &default_raw_cmd;
 	raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
 		FD_RAW_NEED_SEEK;
 	raw_cmd->cmd_count = NR_RW;
-	if (rq_data_dir(CURRENT) == READ) {
+	if (rq_data_dir(current_req) == READ) {
 		raw_cmd->flags |= FD_RAW_READ;
 		COMMAND = FM_MODE(_floppy,FD_READ);
-	} else if (rq_data_dir(CURRENT) == WRITE){
+	} else if (rq_data_dir(current_req) == WRITE){
 		raw_cmd->flags |= FD_RAW_WRITE;
 		COMMAND = FM_MODE(_floppy,FD_WRITE);
 	} else {
@@ -2653,10 +2655,10 @@
 
 	max_sector = _floppy->sect * _floppy->head;
 
-	TRACK = CURRENT->sector / max_sector;
-	fsector_t = CURRENT->sector % max_sector;
+	TRACK = current_req->sector / max_sector;
+	fsector_t = current_req->sector % max_sector;
 	if (_floppy->track && TRACK >= _floppy->track) {
-		if (CURRENT->current_nr_sectors & 1) {
+		if (current_req->current_nr_sectors & 1) {
 			current_count_sectors = 1;
 			return 1;
 		} else
@@ -2673,7 +2675,7 @@
 		max_sector = 2 * _floppy->sect / 3;
 		if (fsector_t >= max_sector){
 			current_count_sectors = minimum(_floppy->sect - fsector_t,
-							CURRENT->nr_sectors);
+							current_req->nr_sectors);
 			return 1;
 		}
 		SIZECODE = 2;
@@ -2724,7 +2726,7 @@
 
 	in_sector_offset = (fsector_t % _floppy->sect) % ssize;
 	aligned_sector_t = fsector_t - in_sector_offset;
-	max_size = CURRENT->nr_sectors;
+	max_size = current_req->nr_sectors;
 	if ((raw_cmd->track == buffer_track) && 
 	    (current_drive == buffer_drive) &&
 	    (fsector_t >= buffer_min) && (fsector_t < buffer_max)) {
@@ -2733,10 +2735,10 @@
 			copy_buffer(1, max_sector, buffer_max);
 			return 1;
 		}
-	} else if (in_sector_offset || CURRENT->nr_sectors < ssize){
+	} else if (in_sector_offset || current_req->nr_sectors < ssize){
 		if (CT(COMMAND) == FD_WRITE){
-			if (fsector_t + CURRENT->nr_sectors > ssize &&
-			    fsector_t + CURRENT->nr_sectors < ssize + ssize)
+			if (fsector_t + current_req->nr_sectors > ssize &&
+			    fsector_t + current_req->nr_sectors < ssize + ssize)
 				max_size = ssize + ssize;
 			else
 				max_size = ssize;
@@ -2744,7 +2746,7 @@
 		raw_cmd->flags &= ~FD_RAW_WRITE;
 		raw_cmd->flags |= FD_RAW_READ;
 		COMMAND = FM_MODE(_floppy,FD_READ);
-	} else if ((unsigned long)CURRENT->buffer < MAX_DMA_ADDRESS) {
+	} else if ((unsigned long)current_req->buffer < MAX_DMA_ADDRESS) {
 		unsigned long dma_limit;
 		int direct, indirect;
 
@@ -2756,14 +2758,14 @@
 		 * on a 64 bit machine!
 		 */
 		max_size = buffer_chain_size();
-		dma_limit = (MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer)) >> 9;
+		dma_limit = (MAX_DMA_ADDRESS - ((unsigned long) current_req->buffer)) >> 9;
 		if ((unsigned long) max_size > dma_limit) {
 			max_size = dma_limit;
 		}
 		/* 64 kb boundaries */
-		if (CROSS_64KB(CURRENT->buffer, max_size << 9))
+		if (CROSS_64KB(current_req->buffer, max_size << 9))
 			max_size = (K_64 - 
-				    ((unsigned long)CURRENT->buffer) % K_64)>>9;
+				    ((unsigned long)current_req->buffer) % K_64)>>9;
 		direct = transfer_size(ssize,max_sector,max_size) - fsector_t;
 		/*
 		 * We try to read tracks, but if we get too many errors, we
@@ -2777,9 +2779,9 @@
 		     *errors < DP->max_errors.read_track &&
 		     /*!TESTF(FD_NEED_TWADDLE) &&*/
 		     ((!probing || (DP->read_track&(1<<DRS->probed_format)))))){
-			max_size = CURRENT->nr_sectors;
+			max_size = current_req->nr_sectors;
 		} else {
-			raw_cmd->kernel_data = CURRENT->buffer;
+			raw_cmd->kernel_data = current_req->buffer;
 			raw_cmd->length = current_count_sectors << 9;
 			if (raw_cmd->length == 0){
 				DPRINT("zero dma transfer attempted from make_raw_request\n");
@@ -2805,7 +2807,7 @@
 	    fsector_t > buffer_max ||
 	    fsector_t < buffer_min ||
 	    ((CT(COMMAND) == FD_READ ||
-	      (!in_sector_offset && CURRENT->nr_sectors >= ssize))&&
+	      (!in_sector_offset && current_req->nr_sectors >= ssize))&&
 	     max_sector > 2 * max_buffer_sectors + buffer_min &&
 	     max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)
 	    /* not enough space */){
@@ -2840,7 +2842,7 @@
 	/*check_dma_crossing(raw_cmd->kernel_data, raw_cmd->length, 
 	  "end of make_raw_request");*/
 	if ((raw_cmd->length < current_count_sectors << 9) ||
-	    (raw_cmd->kernel_data != CURRENT->buffer &&
+	    (raw_cmd->kernel_data != current_req->buffer &&
 	     CT(COMMAND) == FD_WRITE &&
 	     (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max ||
 	      aligned_sector_t < buffer_min)) ||
@@ -2848,7 +2850,7 @@
 	    raw_cmd->length <= 0 || current_count_sectors <= 0){
 		DPRINT("fractionary current count b=%lx s=%lx\n",
 			raw_cmd->length, current_count_sectors);
-		if (raw_cmd->kernel_data != CURRENT->buffer)
+		if (raw_cmd->kernel_data != current_req->buffer)
 			printk("addr=%d, length=%ld\n",
 			       (int) ((raw_cmd->kernel_data - 
 				       floppy_track_buffer) >> 9),
@@ -2865,7 +2867,7 @@
 		return 0;
 	}
 
-	if (raw_cmd->kernel_data != CURRENT->buffer){
+	if (raw_cmd->kernel_data != current_req->buffer){
 		if (raw_cmd->kernel_data < floppy_track_buffer ||
 		    current_count_sectors < 0 ||
 		    raw_cmd->length < 0 ||
@@ -2883,8 +2885,8 @@
 				printk("write\n");
 			return 0;
 		}
-	} else if (raw_cmd->length > CURRENT->nr_sectors << 9 ||
-		   current_count_sectors > CURRENT->nr_sectors){
+	} else if (raw_cmd->length > current_req->nr_sectors << 9 ||
+		   current_count_sectors > current_req->nr_sectors){
 		DPRINT("buffer overrun in direct transfer\n");
 		return 0;
 	} else if (raw_cmd->length < current_count_sectors << 9){
@@ -2913,21 +2915,21 @@
 		floppy_off(current_drive);
 
 	for (;;) {
-		if (!CURRENT) {
+		if (!current_req) {
 			struct request *req = elv_next_request(QUEUE);
 			if (!req) {
 				do_floppy = NULL;
 				unlock_fdc();
 				return;
 			}
-			CURRENT = req;
+			current_req = req;
 		}
-		if (major(CURRENT->rq_dev) != MAJOR_NR)
+		if (major(current_req->rq_dev) != MAJOR_NR)
 			panic(DEVICE_NAME ": request list destroyed");
 
-		device = CURRENT->rq_dev;
+		device = current_req->rq_dev;
 		set_fdc(DRIVE(device));
-		reschedule_timeout(CURRENTD, "redo fd request", 0);
+		reschedule_timeout(current_reqD, "redo fd request", 0);
 
 		set_floppy(device);
 		raw_cmd = & default_raw_cmd;
@@ -2952,7 +2954,7 @@
 			_floppy = floppy_type+DP->autodetect[DRS->probed_format];
 		} else
 			probing = 0;
-		errors = & (CURRENT->errors);
+		errors = & (current_req->errors);
 		tmp = make_raw_rw_request();
 		if (tmp < 2){
 			request_done(tmp);
@@ -2990,8 +2992,8 @@
 	}
 
 	if (usage_count == 0) {
-		printk("warning: usage count=0, CURRENT=%p exiting\n", CURRENT);
-		printk("sect=%ld flags=%lx\n", CURRENT->sector, CURRENT->flags);
+		printk("warning: usage count=0, current_req=%p exiting\n", current_req);
+		printk("sect=%ld flags=%lx\n", current_req->sector, current_req->flags);
 		return;
 	}
 	if (fdc_busy){
@@ -4218,9 +4220,12 @@
 
 static int have_no_fdc= -ENODEV;
 
-static struct device device_floppy = {
-	name:		"floppy",
-	bus_id:		"03?0",
+static struct platform_device floppy_device = {
+	.name		= "floppy",
+	.id		= 0,
+	.dev		= {
+		.name	= "Floppy Drive",
+	},
 };
 
 static struct gendisk *floppy_find(int minor)
@@ -4374,7 +4379,7 @@
 		add_disk(disks + drive);
 	}
 
-	register_sys_device(&device_floppy);
+	platform_device_register(&floppy_device);
 
 	return have_no_fdc;
 }
@@ -4556,9 +4561,9 @@
 
 void cleanup_module(void)
 {
-	int i;
+	int drive;
 		
-	unregister_sys_device(&device_floppy);
+	platform_device_unregister(&floppy_device);
 	devfs_unregister (devfs_handle);
 	unregister_blkdev(MAJOR_NR, "fd");
 	blk_set_probe(MAJOR_NR, NULL);
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/block/genhd.c	Fri Sep 27 14:51:04 2002
@@ -209,6 +209,10 @@
 extern int atmdev_init(void);
 extern int cpqarray_init(void);
 
+struct device_class disk_devclass = {
+	.name		= "disk",
+};
+
 int __init device_init(void)
 {
 	int i;
@@ -226,7 +230,11 @@
 #ifdef CONFIG_ATM
 	(void) atmdev_init();
 #endif
+
+	devclass_register(&disk_devclass);
 	return 0;
 }
 
 __initcall(device_init);
+
+EXPORT_SYMBOL(disk_devclass);
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/block/ll_rw_blk.c	Fri Sep 27 14:51:03 2002
@@ -46,23 +46,76 @@
 struct blk_dev_struct blk_dev[MAX_BLKDEV]; /* initialized by blk_dev_init() */
 
 /*
- * blk_size contains the size of all block-devices in units of 1024 byte
- * blocks:
- *
- * blk_size[MAJOR][MINOR]
- *
- * if (!blk_size[MAJOR]) then no minor size checking is done.
+ * Number of requests per queue.  This many for reads and for writes (twice
+ * this number, total).
  */
-int * blk_size[MAX_BLKDEV];
+static int queue_nr_requests;
 
 /*
- * How many reqeusts do we allocate per queue,
- * and how many do we "batch" on freeing them?
+ * How many free requests must be available before we wake a process which
+ * is waiting for a request?
  */
-int queue_nr_requests, batch_requests;
+static int batch_requests;
+
 unsigned long blk_max_low_pfn, blk_max_pfn;
 int blk_nohighio = 0;
 
+static struct congestion_state {
+	wait_queue_head_t wqh;
+	atomic_t nr_congested_queues;
+} congestion_states[2];
+
+/*
+ * Return the threshold (number of free requests) at which the queue is
+ * considered to be congested.  It include a little hysteresis to keep the
+ * context switch rate down.
+ */
+static inline int queue_congestion_on_threshold(void)
+{
+	int ret;
+
+	ret = queue_nr_requests / 4 - 1;
+	if (ret < 0)
+		ret = 1;
+	return ret;
+}
+
+/*
+ * The threshold at which a queue is considered to be uncongested
+ */
+static inline int queue_congestion_off_threshold(void)
+{
+	int ret;
+
+	ret = queue_nr_requests / 4 + 1;
+	if (ret > queue_nr_requests)
+		ret = queue_nr_requests;
+	return ret;
+}
+
+static void clear_queue_congested(request_queue_t *q, int rw)
+{
+	enum bdi_state bit;
+	struct congestion_state *cs = &congestion_states[rw];
+
+	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+
+	if (test_and_clear_bit(bit, &q->backing_dev_info.state))
+		atomic_dec(&cs->nr_congested_queues);
+	if (waitqueue_active(&cs->wqh))
+		wake_up(&cs->wqh);
+}
+
+static void set_queue_congested(request_queue_t *q, int rw)
+{
+	enum bdi_state bit;
+
+	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+
+	if (!test_and_set_bit(bit, &q->backing_dev_info.state))
+		atomic_inc(&congestion_states[rw].nr_congested_queues);
+}
+
 /**
  * bdev_get_queue: - return the queue that matches the given device
  * @bdev:    device
@@ -370,8 +423,8 @@
 	struct blk_queue_tag *tags;
 	int bits, i;
 
-	if (depth > queue_nr_requests) {
-		depth = queue_nr_requests;
+	if (depth > (queue_nr_requests*2)) {
+		depth = (queue_nr_requests*2);
 		printk("blk_queue_init_tags: adjusted depth to %d\n", depth);
 	}
 
@@ -1029,7 +1082,7 @@
  **/
 void blk_cleanup_queue(request_queue_t * q)
 {
-	int count = queue_nr_requests;
+	int count = (queue_nr_requests*2);
 
 	count -= __blk_cleanup_queue(&q->rq[READ]);
 	count -= __blk_cleanup_queue(&q->rq[WRITE]);
@@ -1060,7 +1113,7 @@
 	 * Divide requests in half between read and write
 	 */
 	rl = &q->rq[READ];
-	for (i = 0; i < queue_nr_requests; i++) {
+	for (i = 0; i < (queue_nr_requests*2); i++) {
 		rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
 		if (!rq)
 			goto nomem;
@@ -1068,7 +1121,7 @@
 		/*
 		 * half way through, switch to WRITE list
 		 */
-		if (i == queue_nr_requests / 2)
+		if (i == queue_nr_requests)
 			rl = &q->rq[WRITE];
 
 		memset(rq, 0, sizeof(struct request));
@@ -1122,7 +1175,7 @@
 	if (blk_init_free_list(q))
 		return -ENOMEM;
 
-	if ((ret = elevator_init(q, &q->elevator, elevator_linus))) {
+	if ((ret = elevator_init(q, &q->elevator, iosched_deadline))) {
 		blk_cleanup_queue(q);
 		return ret;
 	}
@@ -1154,7 +1207,7 @@
  * Get a free request. queue lock must be held and interrupts
  * disabled on the way in.
  */
-static inline struct request *get_request(request_queue_t *q, int rw)
+static struct request *get_request(request_queue_t *q, int rw)
 {
 	struct request *rq = NULL;
 	struct request_list *rl = q->rq + rw;
@@ -1163,6 +1216,8 @@
 		rq = blkdev_free_rq(&rl->free);
 		list_del(&rq->queuelist);
 		rl->count--;
+		if (rl->count < queue_congestion_on_threshold())
+			set_queue_congested(q, rw);
 		rq->flags = 0;
 		rq->rq_status = RQ_ACTIVE;
 		rq->special = NULL;
@@ -1178,24 +1233,23 @@
  */
 static struct request *get_request_wait(request_queue_t *q, int rw)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 	struct request_list *rl = &q->rq[rw];
 	struct request *rq;
 
 	spin_lock_prefetch(q->queue_lock);
 
 	generic_unplug_device(q);
-	add_wait_queue_exclusive(&rl->wait, &wait);
 	do {
-		set_current_state(TASK_UNINTERRUPTIBLE);
+		prepare_to_wait_exclusive(&rl->wait, &wait,
+					TASK_UNINTERRUPTIBLE);
 		if (!rl->count)
 			schedule();
+		finish_wait(&rl->wait, &wait);
 		spin_lock_irq(q->queue_lock);
 		rq = get_request(q, rw);
 		spin_unlock_irq(q->queue_lock);
 	} while (rq == NULL);
-	remove_wait_queue(&rl->wait, &wait);
-	current->state = TASK_RUNNING;
 	return rq;
 }
 
@@ -1375,13 +1429,48 @@
 	 * it didn't come out of our reserved rq pools
 	 */
 	if (rl) {
+		int rw = 0;
+
 		list_add(&req->queuelist, &rl->free);
 
-		if (++rl->count >= batch_requests &&waitqueue_active(&rl->wait))
+		if (rl == &q->rq[WRITE])
+			rw = WRITE;
+		else if (rl == &q->rq[READ])
+			rw = READ;
+		else
+			BUG();
+
+		rl->count++;
+		if (rl->count >= queue_congestion_off_threshold())
+			clear_queue_congested(q, rw);
+		if (rl->count >= batch_requests && waitqueue_active(&rl->wait))
 			wake_up(&rl->wait);
 	}
 }
 
+/**
+ * blk_congestion_wait - wait for a queue to become uncongested
+ * @rw: READ or WRITE
+ * @timeout: timeout in jiffies
+ *
+ * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
+ * If no queues are congested then just return, in the hope that the caller
+ * will submit some more IO.
+ */
+void blk_congestion_wait(int rw, long timeout)
+{
+	DEFINE_WAIT(wait);
+	struct congestion_state *cs = &congestion_states[rw];
+
+	if (atomic_read(&cs->nr_congested_queues) == 0)
+		return;
+	blk_run_queues();
+	prepare_to_wait(&cs->wqh, &wait, TASK_UNINTERRUPTIBLE);
+	if (atomic_read(&cs->nr_congested_queues) != 0)
+		schedule_timeout(timeout);
+	finish_wait(&cs->wqh, &wait);
+}
+
 /*
  * Has to be called with the request spinlock acquired
  */
@@ -1494,7 +1583,6 @@
 
 	spin_lock_irq(q->queue_lock);
 again:
-	req = NULL;
 	insert_here = NULL;
 
 	if (blk_queue_empty(q)) {
@@ -1504,10 +1592,13 @@
 	if (barrier)
 		goto get_rq;
 
-	el_ret = elv_merge(q, &req, bio);
+	el_ret = elv_merge(q, &insert_here, bio);
 	switch (el_ret) {
 		case ELEVATOR_BACK_MERGE:
+			req = list_entry_rq(insert_here);
+
 			BUG_ON(!rq_mergeable(req));
+
 			if (!q->back_merge_fn(q, req, bio)) {
 				insert_here = &req->queuelist;
 				break;
@@ -1517,11 +1608,15 @@
 			req->biotail = bio;
 			req->nr_sectors = req->hard_nr_sectors += nr_sectors;
 			drive_stat_acct(req, nr_sectors, 0);
+			elv_merged_request(q, req);
 			attempt_back_merge(q, req);
 			goto out;
 
 		case ELEVATOR_FRONT_MERGE:
+			req = list_entry_rq(insert_here);
+
 			BUG_ON(!rq_mergeable(req));
+
 			if (!q->front_merge_fn(q, req, bio)) {
 				insert_here = req->queuelist.prev;
 				break;
@@ -1540,6 +1635,7 @@
 			req->sector = req->hard_sector = sector;
 			req->nr_sectors = req->hard_nr_sectors += nr_sectors;
 			drive_stat_acct(req, nr_sectors, 0);
+			elv_merged_request(q, req);
 			attempt_front_merge(q, req);
 			goto out;
 
@@ -1547,13 +1643,6 @@
 		 * elevator says don't/can't merge. get new request
 		 */
 		case ELEVATOR_NO_MERGE:
-			/*
-			 * use elevator hints as to where to insert the
-			 * request. if no hints, just add it to the back
-			 * of the queue
-			 */
-			if (req)
-				insert_here = &req->queuelist;
 			break;
 
 		default:
@@ -1703,7 +1792,7 @@
 			       bdevname(bio->bi_bdev),
 			       (long long) bio->bi_sector);
 end_io:
-			bio_endio(bio, 0, -EIO);
+			bio_endio(bio, bio->bi_size, -EIO);
 			break;
 		}
 
@@ -1812,18 +1901,19 @@
 
 int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
 {
-	int nsect, total_nsect;
+	int total_nsect = 0, error = 0;
 	struct bio *bio;
 
 	req->errors = 0;
-	if (!uptodate)
+	if (!uptodate) {
 		printk("end_request: I/O error, dev %s, sector %lu\n",
 			kdevname(req->rq_dev), req->sector);
+		error = -EIO;
+	}
 
-	total_nsect = 0;
 	while ((bio = req->bio)) {
-		nsect = bio_iovec(bio)->bv_len >> 9;
-		total_nsect += nsect;
+		const int nsect = bio_iovec(bio)->bv_len >> 9;
+		int new_bio = 0;
 
 		BIO_BUG_ON(bio_iovec(bio)->bv_len > bio->bi_size);
 
@@ -1835,36 +1925,52 @@
 
 			bio_iovec(bio)->bv_offset += partial;
 			bio_iovec(bio)->bv_len -= partial;
-			blk_recalc_rq_sectors(req, total_nsect);
-			blk_recalc_rq_segments(req);
-			bio_endio(bio, partial, !uptodate ? -EIO : 0);
-			return 1;
+			bio_endio(bio, partial, error);
+			total_nsect += nr_sectors;
+			break;
 		}
 
 		/*
-		 * if bio->bi_end_io returns 0, this bio is done. move on
+		 * we are ending the last part of the bio, advance req pointer
 		 */
-		req->bio = bio->bi_next;
-		if (bio_endio(bio, nsect << 9, !uptodate ? -EIO : 0)) {
-			bio->bi_idx++;
-			req->bio = bio;
+		if ((nsect << 9) >= bio->bi_size) {
+			req->bio = bio->bi_next;
+			new_bio = 1;
 		}
 
+		bio_endio(bio, nsect << 9, error);
+
+		total_nsect += nsect;
 		nr_sectors -= nsect;
 
+		/*
+		 * if we didn't advance the req->bio pointer, advance bi_idx
+		 * to indicate we are now on the next bio_vec
+		 */
+		if (!new_bio)
+			bio->bi_idx++;
+
 		if ((bio = req->bio)) {
 			/*
 			 * end more in this run, or just return 'not-done'
 			 */
-			if (unlikely(nr_sectors <= 0)) {
-				blk_recalc_rq_sectors(req, total_nsect);
-				blk_recalc_rq_segments(req);
-				return 1;
-			}
+			if (unlikely(nr_sectors <= 0))
+				break;
 		}
 	}
 
-	return 0;
+	/*
+	 * completely done
+	 */
+	if (!req->bio)
+		return 0;
+
+	/*
+	 * if the request wasn't completed, update state
+	 */
+	blk_recalc_rq_sectors(req, total_nsect);
+	blk_recalc_rq_segments(req);
+	return 1;
 }
 
 void end_that_request_last(struct request *req)
@@ -1878,6 +1984,7 @@
 int __init blk_dev_init(void)
 {
 	int total_ram = nr_free_pages() << (PAGE_SHIFT - 10);
+	int i;
 
 	request_cachep = kmem_cache_create("blkdev_requests",
 			sizeof(struct request), 0,
@@ -1886,26 +1993,33 @@
 		panic("Can't create request pool slab cache\n");
 
 	/*
-	 * Free request slots per queue.
-	 * (Half for reads, half for writes)
+	 * Free request slots per queue.  One per quarter-megabyte.
+	 * We use this many requests for reads, and this many for writes.
 	 */
-	queue_nr_requests = (total_ram >> 8) & ~15;	/* One per quarter-megabyte */
-	if (queue_nr_requests < 32)
-		queue_nr_requests = 32;
-	if (queue_nr_requests > 256)
-		queue_nr_requests = 256;
-
-	/*
-	 * Batch frees according to queue length
-	 */
-	if ((batch_requests = queue_nr_requests / 4) > 32)
-		batch_requests = 32;
-	printk("block: %d slots per queue, batch=%d\n",
-			queue_nr_requests, batch_requests);
+	queue_nr_requests = (total_ram >> 9) & ~7;
+	if (queue_nr_requests < 16)
+		queue_nr_requests = 16;
+	if (queue_nr_requests > 128)
+		queue_nr_requests = 128;
+
+	batch_requests = queue_nr_requests / 8;
+	if (batch_requests > 8)
+		batch_requests = 8;
+
+	printk("block request queues:\n");
+	printk(" %d requests per read queue\n", queue_nr_requests);
+	printk(" %d requests per write queue\n", queue_nr_requests);
+	printk(" %d requests per batch\n", batch_requests);
+	printk(" enter congestion at %d\n", queue_congestion_on_threshold());
+	printk(" exit congestion at %d\n", queue_congestion_off_threshold());
 
 	blk_max_low_pfn = max_low_pfn;
 	blk_max_pfn = max_pfn;
 
+	for (i = 0; i < ARRAY_SIZE(congestion_states); i++) {
+		init_waitqueue_head(&congestion_states[i].wqh);
+		atomic_set(&congestion_states[i].nr_congested_queues, 0);
+	}
 	return 0;
 };
 
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/block/loop.c	Fri Sep 27 14:51:04 2002
@@ -157,18 +157,12 @@
 
 #define MAX_DISK_SIZE 1024*1024*1024
 
-static unsigned long
-compute_loop_size(struct loop_device *lo, struct dentry * lo_dentry)
-{
-	loff_t size = lo_dentry->d_inode->i_mapping->host->i_size;
-	return (size - lo->lo_offset) >> BLOCK_SIZE_BITS;
-}
-
 static void figure_loop_size(struct loop_device *lo)
 {
-	set_capacity(disks + lo->lo_number, compute_loop_size(lo,
-					lo->lo_backing_file->f_dentry));
-					
+	loff_t size = lo->lo_backing_file->f_dentry->d_inode->i_size;
+
+	set_capacity(disks + lo->lo_number,
+		     (size - lo->lo_offset) >> 9);
 }
 
 static inline int lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf,
diff -Nru a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
--- a/drivers/block/paride/pd.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/block/paride/pd.c	Fri Sep 27 14:51:05 2002
@@ -125,31 +125,22 @@
 
 */
 
-static int	verbose = 0;
-static int	major = PD_MAJOR;
-static char	*name = PD_NAME;
-static int	cluster = 64;	
-static int      nice = 0;
-static int      disable = 0;
-
-static int drive0[8] = {0,0,0,-1,0,1,-1,-1};
-static int drive1[8] = {0,0,0,-1,0,1,-1,-1};
-static int drive2[8] = {0,0,0,-1,0,1,-1,-1};
-static int drive3[8] = {0,0,0,-1,0,1,-1,-1};
+static int verbose = 0;
+static int major = PD_MAJOR;
+static char *name = PD_NAME;
+static int cluster = 64;
+static int nice = 0;
+static int disable = 0;
+
+static int drive0[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
+static int drive1[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
+static int drive2[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
+static int drive3[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
 
-static int (*drives[4])[8] = {&drive0,&drive1,&drive2,&drive3};
+static int (*drives[4])[8] = {&drive0, &drive1, &drive2, &drive3};
 static int pd_drive_count;
 
-#define D_PRT	0
-#define D_PRO   1
-#define D_UNI	2
-#define D_MOD	3
-#define D_GEO	4
-#define D_SBY	5
-#define D_DLY	6
-#define D_SLV   7
-
-#define	DU		(*drives[unit])
+enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
 
 /* end of parameters */
 
@@ -168,30 +159,32 @@
 
 #include "setup.h"
 
-static STT pd_stt[7] = {{"drive0",8,drive0},
-		        {"drive1",8,drive1},
-		        {"drive2",8,drive2},
-		        {"drive3",8,drive3},
-			{"disable",1,&disable},
-		        {"cluster",1,&cluster},
-		        {"nice",1,&nice}};
+static STT pd_stt[7] = {
+	{"drive0", 8, drive0},
+	{"drive1", 8, drive1},
+	{"drive2", 8, drive2},
+	{"drive3", 8, drive3},
+	{"disable", 1, &disable},
+	{"cluster", 1, &cluster},
+	{"nice", 1, &nice}
+};
 
-void pd_setup( char *str, int *ints)
+void pd_setup(char *str, int *ints)
 {
-	generic_setup(pd_stt,7,str);
+	generic_setup(pd_stt, 7, str);
 }
 
 #endif
 
-MODULE_PARM(verbose,"i");
-MODULE_PARM(major,"i");
-MODULE_PARM(name,"s");
-MODULE_PARM(cluster,"i");
-MODULE_PARM(nice,"i");
-MODULE_PARM(drive0,"1-8i");
-MODULE_PARM(drive1,"1-8i");
-MODULE_PARM(drive2,"1-8i");
-MODULE_PARM(drive3,"1-8i");
+MODULE_PARM(verbose, "i");
+MODULE_PARM(major, "i");
+MODULE_PARM(name, "s");
+MODULE_PARM(cluster, "i");
+MODULE_PARM(nice, "i");
+MODULE_PARM(drive0, "1-8i");
+MODULE_PARM(drive1, "1-8i");
+MODULE_PARM(drive2, "1-8i");
+MODULE_PARM(drive3, "1-8i");
 
 #include "paride.h"
 
@@ -216,10 +209,10 @@
 #define PD_ID_LEN       14
 
 #define PD_MAX_RETRIES  5
-#define PD_TMO          800             /* interrupt timeout in jiffies */
-#define PD_SPIN_DEL     50              /* spin delay in micro-seconds  */
+#define PD_TMO          800	/* interrupt timeout in jiffies */
+#define PD_SPIN_DEL     50	/* spin delay in micro-seconds  */
 
-#define PD_SPIN         (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)  
+#define PD_SPIN         (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)
 
 #define STAT_ERR        0x00001
 #define STAT_INDEX      0x00002
@@ -250,274 +243,303 @@
 #define IDE_IDENTIFY    	0xec
 #define IDE_EJECT		0xed
 
-void pd_setup(char * str, int * ints);
+void pd_setup(char *str, int *ints);
 static int pd_open(struct inode *inode, struct file *file);
 static void do_pd_request(request_queue_t * q);
-static int pd_ioctl(struct inode *inode,struct file *file,
-                    unsigned int cmd, unsigned long arg);
-static int pd_release (struct inode *inode, struct file *file);
+static int pd_ioctl(struct inode *inode, struct file *file,
+		    unsigned int cmd, unsigned long arg);
+static int pd_release(struct inode *inode, struct file *file);
 static int pd_revalidate(kdev_t dev);
 static int pd_detect(void);
 static void do_pd_read(void);
 static void do_pd_read_start(void);
 static void do_pd_write(void);
 static void do_pd_write_start(void);
-static void do_pd_read_drq( void );
-static void do_pd_write_done( void );
-
-static int pd_identify (int unit);
-static void pd_media_check(int unit);
-static void pd_doorlock(int unit, int func);
-static int pd_check_media(kdev_t dev);
-static void pd_eject( int unit);
+static void do_pd_read_drq(void);
+static void do_pd_write_done(void);
 
 #define PD_NAMELEN	8
 
 struct pd_unit {
-	struct pi_adapter pia;		/* interface to paride layer */
+	struct pi_adapter pia;	/* interface to paride layer */
 	struct pi_adapter *pi;
-	int access;               	/* count of active opens ... */
-	int capacity;             	/* Size of this volume in sectors */
-	int heads;                	/* physical geometry */
+	int access;		/* count of active opens ... */
+	int capacity;		/* Size of this volume in sectors */
+	int heads;		/* physical geometry */
 	int sectors;
 	int cylinders;
 	int can_lba;
-	int drive;			/* master=0 slave=1 */
-	int changed;			/* Have we seen a disk change ? */
-	int removable;			/* removable media device  ?  */
+	int drive;		/* master=0 slave=1 */
+	int changed;		/* Have we seen a disk change ? */
+	int removable;		/* removable media device  ?  */
 	int standby;
 	int alt_geom;
 	int present;
-	char name[PD_NAMELEN];		/* pda, pdb, etc ... */
+	char name[PD_NAMELEN];	/* pda, pdb, etc ... */
 	struct gendisk gd;
 };
 
 struct pd_unit pd[PD_UNITS];
 
-/*  'unit' must be defined in all functions - either as a local or a param */
+static int pd_identify(struct pd_unit *disk);
+static void pd_media_check(struct pd_unit *disk);
+static void pd_doorlock(struct pd_unit *disk, int func);
+static int pd_check_media(kdev_t dev);
+static void pd_eject(struct pd_unit *disk);
 
-#define PD pd[unit]
-#define PI PD.pi
+/*  'unit' must be defined in all functions - either as a local or a param */
 
-static char pd_scratch[512];            /* scratch block buffer */
+static char pd_scratch[512];	/* scratch block buffer */
 
 /* the variables below are used mainly in the I/O request engine, which
    processes only one request at a time.
 */
 
-static int pd_retries = 0;              /* i/o error retry count */
-static int pd_busy = 0;                 /* request being processed ? */
-static int pd_block;                    /* address of next requested block */
-static int pd_count;                    /* number of blocks still to do */
-static int pd_run;			/* sectors in current cluster */
-static int pd_cmd;			/* current command READ/WRITE */
-static int pd_unit;			/* unit of current request */
-static int pd_dev;			/* minor of current request */
-static char * pd_buf;                   /* buffer for request in progress */
+static struct pd_unit *pd_current; /* current request's drive */
+static int pd_retries = 0;	/* i/o error retry count */
+static int pd_busy = 0;		/* request being processed ? */
+static struct request *pd_req;	/* current request */
+static int pd_block;		/* address of next requested block */
+static int pd_count;		/* number of blocks still to do */
+static int pd_run;		/* sectors in current cluster */
+static int pd_cmd;		/* current command READ/WRITE */
+static char *pd_buf;		/* buffer for request in progress */
 
 static DECLARE_WAIT_QUEUE_HEAD(pd_wait_open);
 
-static char *pd_errs[17] = { "ERR","INDEX","ECC","DRQ","SEEK","WRERR",
-                             "READY","BUSY","AMNF","TK0NF","ABRT","MCR",
-                             "IDNF","MC","UNC","???","TMO"};
+static char *pd_errs[17] = { "ERR", "INDEX", "ECC", "DRQ", "SEEK", "WRERR",
+	"READY", "BUSY", "AMNF", "TK0NF", "ABRT", "MCR",
+	"IDNF", "MC", "UNC", "???", "TMO"
+};
 
 /* kernel glue structures */
 
 extern struct block_device_operations pd_fops;
 
 static struct block_device_operations pd_fops = {
-	owner:			THIS_MODULE,
-        open:			pd_open,
-        release:		pd_release,
-        ioctl:			pd_ioctl,
-        check_media_change:	pd_check_media,
-        revalidate:		pd_revalidate
+	.owner			= THIS_MODULE,
+	.open			= pd_open,
+	.release		= pd_release,
+	.ioctl			= pd_ioctl,
+	.check_media_change	= pd_check_media,
+	.revalidate		= pd_revalidate
 };
 
-void pd_init_units( void )
-
-{	int	unit, j;
+static void pd_init_units(void)
+{
+	int unit;
 
 	pd_drive_count = 0;
-	for (unit=0;unit<PD_UNITS;unit++) {
-		PD.pi = & PD.pia;
-		PD.access = 0;
-		PD.changed = 1;
-		PD.capacity = 0;
-		PD.drive = DU[D_SLV];
-		PD.present = 0;
-		j = 0;
-		while ((j < PD_NAMELEN-2) && (PD.name[j]=name[j])) j++;
-		PD.name[j++] = 'a' + unit;
-		PD.name[j] = 0;
-		PD.alt_geom = DU[D_GEO];
-		PD.standby = DU[D_SBY];
-		if (DU[D_PRT]) pd_drive_count++;
+	for (unit = 0; unit < PD_UNITS; unit++) {
+		int *parm = *drives[unit];
+		struct pd_unit *disk = pd + unit;
+		disk->pi = &disk->pia;
+		disk->access = 0;
+		disk->changed = 1;
+		disk->capacity = 0;
+		disk->drive = parm[D_SLV];
+		disk->present = 0;
+		snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a'+unit);
+		disk->alt_geom = parm[D_GEO];
+		disk->standby = parm[D_SBY];
+		if (parm[D_PRT])
+			pd_drive_count++;
 	}
 }
 
-static int pd_open (struct inode *inode, struct file *file)
+static int pd_open(struct inode *inode, struct file *file)
 {
 	int unit = DEVICE_NR(inode->i_rdev);
+	struct pd_unit *disk = pd + unit;
 
-        if ((unit >= PD_UNITS) || (!PD.present))
+	if (unit >= PD_UNITS || !disk->present)
 		return -ENODEV;
 
-        PD.access++;
+	disk->access++;
 
-        if (PD.removable) {
-		pd_media_check(unit);
-		pd_doorlock(unit,IDE_DOORLOCK);
+	if (disk->removable) {
+		pd_media_check(disk);
+		pd_doorlock(disk, IDE_DOORLOCK);
 	}
-        return 0;
+	return 0;
 }
 
-static int pd_ioctl(struct inode *inode,struct file *file,
-                    unsigned int cmd, unsigned long arg)
+static int pd_ioctl(struct inode *inode, struct file *file,
+	 unsigned int cmd, unsigned long arg)
 {
 	struct hd_geometry *geo = (struct hd_geometry *) arg;
 	int err, unit = DEVICE_NR(inode->i_rdev);
+	struct pd_unit *disk = pd + unit;
 
-	if (!PD.present)
+	if (!disk->present)
 		return -ENODEV;
 
 	switch (cmd) {
-	    case CDROMEJECT:
-		if (PD.access == 1) pd_eject(unit);
+	case CDROMEJECT:
+		if (disk->access == 1)
+			pd_eject(disk);
 		return 0;
-	    case HDIO_GETGEO:
-		if (!geo) return -EINVAL;
-		err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
-		if (err) return err;
-
-		if (PD.alt_geom) {
-		    put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS), 
-		    		(short *) &geo->cylinders);
-		    put_user(PD_LOG_HEADS, (char *) &geo->heads);
-		    put_user(PD_LOG_SECTS, (char *) &geo->sectors);
+	case HDIO_GETGEO:
+		if (!geo)
+			return -EINVAL;
+		err = verify_area(VERIFY_WRITE, geo, sizeof (*geo));
+		if (err)
+			return err;
+
+		if (disk->alt_geom) {
+			put_user(disk->capacity / (PD_LOG_HEADS * PD_LOG_SECTS),
+				 (short *) &geo->cylinders);
+			put_user(PD_LOG_HEADS, (char *) &geo->heads);
+			put_user(PD_LOG_SECTS, (char *) &geo->sectors);
 		} else {
-		    put_user(PD.cylinders, (short *) &geo->cylinders);
-		    put_user(PD.heads, (char *) &geo->heads);
-		    put_user(PD.sectors, (char *) &geo->sectors);
+			put_user(disk->cylinders, (short *) &geo->cylinders);
+			put_user(disk->heads, (char *) &geo->heads);
+			put_user(disk->sectors, (char *) &geo->sectors);
 		}
-		put_user(get_start_sect(inode->i_bdev), (long *)&geo->start);
+		put_user(get_start_sect(inode->i_bdev), (long *) &geo->start);
 		return 0;
-	    default:
+	default:
 		return -EINVAL;
 	}
 }
 
-static int pd_release (struct inode *inode, struct file *file)
+static int pd_release(struct inode *inode, struct file *file)
 {
-	int	unit = DEVICE_NR(inode->i_rdev);
+	int unit = DEVICE_NR(inode->i_rdev);
+	struct pd_unit *disk = pd + unit;
 
-        if (!--PD.access && PD.removable)
-		pd_doorlock(unit,IDE_DOORUNLOCK);
+	if (!--disk->access && disk->removable)
+		pd_doorlock(disk, IDE_DOORUNLOCK);
 
 	return 0;
 }
 
-static int pd_check_media( kdev_t dev)
+static int pd_check_media(kdev_t dev)
 {
 	int r, unit = DEVICE_NR(dev);
-	if ((unit >= PD_UNITS) || (!PD.present))
+	struct pd_unit *disk = pd + unit;
+	if (unit >= PD_UNITS || (!disk->present))
 		return -ENODEV;
-        if (!PD.removable)
+	if (!disk->removable)
 		return 0;
-	pd_media_check(unit);
-	r = PD.changed;
-	PD.changed = 0;
+	pd_media_check(disk);
+	r = disk->changed;
+	disk->changed = 0;
 	return r;
 }
 
 static int pd_revalidate(kdev_t dev)
 {
 	int unit = DEVICE_NR(dev);
-	if ((unit >= PD_UNITS) || !PD.present)
+	struct pd_unit *disk = pd + unit;
+	if (unit >= PD_UNITS || !disk->present)
 		return -ENODEV;
-	if (pd_identify(unit))
-		set_capacity(&PD.gd, PD.capacity);
+	if (pd_identify(disk))
+		set_capacity(&disk->gd, disk->capacity);
 	else
-		set_capacity(&PD.gd, 0);
-        return 0;
+		set_capacity(&disk->gd, 0);
+	return 0;
 }
 
-#define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
-#define	RR(c,r)		(pi_read_regr(PI,c,r))
+static inline int status_reg(struct pd_unit *disk)
+{
+	return pi_read_regr(disk->pi, 1, 6);
+}
 
-#define DRIVE		(0xa0+0x10*PD.drive)
+static inline int read_reg(struct pd_unit *disk, int reg)
+{
+	return pi_read_regr(disk->pi, 0, reg);
+}
 
-/*  ide command interface */
+static inline void write_status(struct pd_unit *disk, int val)
+{
+	pi_write_regr(disk->pi, 1, 6, val);
+}
 
-static void pd_print_error( int unit, char * msg, int status )
+static inline void write_reg(struct pd_unit *disk, int reg, int val)
+{
+	pi_write_regr(disk->pi, 0, reg, val);
+}
 
-{       int     i;
+static inline u8 DRIVE(struct pd_unit *disk)
+{
+	return 0xa0+0x10*disk->drive;
+}
+
+/*  ide command interface */
 
-	printk("%s: %s: status = 0x%x =",PD.name,msg,status);
-        for(i=0;i<18;i++) if (status & (1<<i)) printk(" %s",pd_errs[i]);
+static void pd_print_error(struct pd_unit *disk, char *msg, int status)
+{
+	int i;
+
+	printk("%s: %s: status = 0x%x =", disk->name, msg, status);
+	for (i = 0; i < 18; i++)
+		if (status & (1 << i))
+			printk(" %s", pd_errs[i]);
 	printk("\n");
 }
 
-static void pd_reset( int unit )    /* called only for MASTER drive */
-
-{       pi_connect(PI);
-	WR(1,6,4);
-        udelay(50);
-        WR(1,6,0);
-	pi_disconnect(PI);
+static void pd_reset(struct pd_unit *disk)
+{				/* called only for MASTER drive */
+	pi_connect(disk->pi);
+	write_status(disk, 4);
+	udelay(50);
+	write_status(disk, 0);
+	pi_disconnect(disk->pi);
 	udelay(250);
 }
 
 #define DBMSG(msg)	((verbose>1)?(msg):NULL)
 
-static int pd_wait_for( int unit, int w, char * msg )    /* polled wait */
+static int pd_wait_for(struct pd_unit *disk, int w, char *msg)
+{				/* polled wait */
+	int k, r, e;
 
-{       int     k, r, e;
+	k = 0;
+	while (k < PD_SPIN) {
+		r = status_reg(disk);
+		k++;
+		if (((r & w) == w) && !(r & STAT_BUSY))
+			break;
+		udelay(PD_SPIN_DEL);
+	}
+	e = (read_reg(disk, 1) << 8) + read_reg(disk, 7);
+	if (k >= PD_SPIN)
+		e |= ERR_TMO;
+	if ((e & (STAT_ERR | ERR_TMO)) && (msg != NULL))
+		pd_print_error(disk, msg, e);
+	return e;
+}
 
-        k=0;
-        while(k < PD_SPIN) { 
-            r = RR(1,6);
-            k++;
-            if (((r & w) == w) && !(r & STAT_BUSY)) break;
-            udelay(PD_SPIN_DEL);
-        }
-        e = (RR(0,1)<<8) + RR(0,7);
-        if (k >= PD_SPIN)  e |= ERR_TMO;
-        if ((e & (STAT_ERR|ERR_TMO)) && (msg != NULL)) 
-		pd_print_error(unit,msg,e);
-        return e;
-}
-
-static void pd_send_command( int unit, int n, int s, int h, 
-			     int c0, int c1, int func )
-{
-        WR(0,6,DRIVE+h);
-        WR(0,1,0);                /* the IDE task file */
-        WR(0,2,n);
-        WR(0,3,s);
-        WR(0,4,c0);
-        WR(0,5,c1);
-        WR(0,7,func);
+static void pd_send_command(struct pd_unit *disk, int n, int s, int h, int c0, int c1, int func)
+{
+	write_reg(disk, 6, DRIVE(disk) + h);
+	write_reg(disk, 1, 0);		/* the IDE task file */
+	write_reg(disk, 2, n);
+	write_reg(disk, 3, s);
+	write_reg(disk, 4, c0);
+	write_reg(disk, 5, c1);
+	write_reg(disk, 7, func);
 
-        udelay(1);
+	udelay(1);
 }
 
-static void pd_ide_command( int unit, int func, int block, int count )
+static void pd_ide_command(struct pd_unit *disk, int func, int block, int count)
 {
 	int c1, c0, h, s;
 
-	if (PD.can_lba) {
+	if (disk->can_lba) {
 		s = block & 255;
 		c0 = (block >>= 8) & 255;
 		c1 = (block >>= 8) & 255;
 		h = ((block >>= 8) & 15) + 0x40;
 	} else {
-		s  = ( block % PD.sectors) + 1;
-		h  = ( block /= PD.sectors) % PD.heads;
-		c0 = ( block /= PD.heads) % 256;
+		s = (block % disk->sectors) + 1;
+		h = (block /= disk->sectors) % disk->heads;
+		c0 = (block /= disk->heads) % 256;
 		c1 = (block >>= 8);
 	}
-        pd_send_command(unit,count,s,h,c0,c1,func);
+	pd_send_command(disk, count, s, h, c0, c1, func);
 }
 
 /* According to the ATA standard, the default CHS geometry should be
@@ -526,422 +548,404 @@
    parameters are initialised.
 */
 
-static void pd_init_dev_parms( int unit )
- 
-{       pi_connect(PI);
-        pd_wait_for(unit,0,DBMSG("before init_dev_parms"));
-        pd_send_command(unit,PD.sectors,0,PD.heads-1,0,0,IDE_INIT_DEV_PARMS);
-        udelay(300);
-        pd_wait_for(unit,0,"Initialise device parameters");
-        pi_disconnect(PI);
-}
-
-static void pd_doorlock( int unit, int func )
-
-{       pi_connect(PI);
-        if (pd_wait_for(unit,STAT_READY,"Lock") & STAT_ERR) {
-                pi_disconnect(PI);
-                return;
-        }
-        pd_send_command(unit,1,0,0,0,0,func);
-        pd_wait_for(unit,STAT_READY,"Lock done");
-        pi_disconnect(PI);
-}
-
-static void pd_eject( int unit )
-
-{	pi_connect(PI);
-        pd_wait_for(unit,0,DBMSG("before unlock on eject"));
-        pd_send_command(unit,1,0,0,0,0,IDE_DOORUNLOCK);
-        pd_wait_for(unit,0,DBMSG("after unlock on eject"));
-        pd_wait_for(unit,0,DBMSG("before eject"));
-        pd_send_command(unit,0,0,0,0,0,IDE_EJECT);
-        pd_wait_for(unit,0,DBMSG("after eject"));
-        pi_disconnect(PI);
+static void pd_init_dev_parms(struct pd_unit *disk)
+{
+	pi_connect(disk->pi);
+	pd_wait_for(disk, 0, DBMSG("before init_dev_parms"));
+	pd_send_command(disk, disk->sectors, 0, disk->heads - 1, 0, 0,
+			IDE_INIT_DEV_PARMS);
+	udelay(300);
+	pd_wait_for(disk, 0, "Initialise device parameters");
+	pi_disconnect(disk->pi);
+}
+
+static void pd_doorlock(struct pd_unit *disk, int func)
+{
+	pi_connect(disk->pi);
+	if (!(pd_wait_for(disk, STAT_READY, "Lock") & STAT_ERR)) {
+		pd_send_command(disk, 1, 0, 0, 0, 0, func);
+		pd_wait_for(disk, STAT_READY, "Lock done");
+	}
+	pi_disconnect(disk->pi);
 }
 
-static void pd_media_check( int unit )
-
-{       int 	r;
-
-        pi_connect(PI);
-        r = pd_wait_for(unit,STAT_READY,DBMSG("before media_check"));
-        if (!(r & STAT_ERR)) {
-                pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY);  
-                r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after READ_VRFY"));
-        } else PD.changed = 1;   /* say changed if other error */
-        if (r & ERR_MC) {
-                PD.changed = 1;
-                pd_send_command(unit,1,0,0,0,0,IDE_ACKCHANGE);
-                pd_wait_for(unit,STAT_READY,DBMSG("RDY after ACKCHANGE"));
-		pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY);
-                r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after VRFY"));
-        }
-        pi_disconnect(PI);
+static void pd_eject(struct pd_unit *disk)
+{
+	pi_connect(disk->pi);
+	pd_wait_for(disk, 0, DBMSG("before unlock on eject"));
+	pd_send_command(disk, 1, 0, 0, 0, 0, IDE_DOORUNLOCK);
+	pd_wait_for(disk, 0, DBMSG("after unlock on eject"));
+	pd_wait_for(disk, 0, DBMSG("before eject"));
+	pd_send_command(disk, 0, 0, 0, 0, 0, IDE_EJECT);
+	pd_wait_for(disk, 0, DBMSG("after eject"));
+	pi_disconnect(disk->pi);
+}
+
+static void pd_media_check(struct pd_unit *disk)
+{
+	int r;
+
+	pi_connect(disk->pi);
+	r = pd_wait_for(disk, STAT_READY, DBMSG("before media_check"));
+	if (!(r & STAT_ERR)) {
+		pd_send_command(disk, 1, 1, 0, 0, 0, IDE_READ_VRFY);
+		r = pd_wait_for(disk, STAT_READY, DBMSG("RDY after READ_VRFY"));
+	} else
+		disk->changed = 1;	/* say changed if other error */
+	if (r & ERR_MC) {
+		disk->changed = 1;
+		pd_send_command(disk, 1, 0, 0, 0, 0, IDE_ACKCHANGE);
+		pd_wait_for(disk, STAT_READY, DBMSG("RDY after ACKCHANGE"));
+		pd_send_command(disk, 1, 1, 0, 0, 0, IDE_READ_VRFY);
+		r = pd_wait_for(disk, STAT_READY, DBMSG("RDY after VRFY"));
+	}
+	pi_disconnect(disk->pi);
 
 }
 
-static void pd_standby_off( int unit )
-
-{       pi_connect(PI);
-        pd_wait_for(unit,0,DBMSG("before STANDBY"));
-        pd_send_command(unit,0,0,0,0,0,IDE_STANDBY);
-        pd_wait_for(unit,0,DBMSG("after STANDBY"));
-        pi_disconnect(PI);
+static void pd_standby_off(struct pd_unit *disk)
+{
+	pi_connect(disk->pi);
+	pd_wait_for(disk, 0, DBMSG("before STANDBY"));
+	pd_send_command(disk, 0, 0, 0, 0, 0, IDE_STANDBY);
+	pd_wait_for(disk, 0, DBMSG("after STANDBY"));
+	pi_disconnect(disk->pi);
 }
 
-#define  word_val(n) ((pd_scratch[2*n]&0xff)+256*(pd_scratch[2*n+1]&0xff))
-
-static int pd_identify( int unit )
-
-{       int	j;
-	char id[PD_ID_LEN+1];
+static int pd_identify(struct pd_unit *disk)
+{
+	int j;
+	char id[PD_ID_LEN + 1];
 
 /* WARNING:  here there may be dragons.  reset() applies to both drives,
    but we call it only on probing the MASTER. This should allow most
    common configurations to work, but be warned that a reset can clear
    settings on the SLAVE drive.
-*/ 
-
-	if (PD.drive == 0) pd_reset(unit);
-
-        pi_connect(PI);
-	WR(0,6,DRIVE);
-        pd_wait_for(unit,0,DBMSG("before IDENT"));  
-        pd_send_command(unit,1,0,0,0,0,IDE_IDENTIFY);
-
-        if (pd_wait_for(unit,STAT_DRQ,DBMSG("IDENT DRQ")) & STAT_ERR) {
-                pi_disconnect(PI);
-                return 0;
-        }
-        pi_read_block(PI,pd_scratch,512);
-        pi_disconnect(PI);
-	PD.can_lba = pd_scratch[99] & 2;
-	PD.sectors = le16_to_cpu(*(u16*)(pd_scratch+12));
-	PD.heads = le16_to_cpu(*(u16*)(pd_scratch+6));
-	PD.cylinders  = le16_to_cpu(*(u16*)(pd_scratch+2));
-	if (PD.can_lba)
-		PD.capacity = le32_to_cpu(*(u32*)(pd_scratch + 120));
-	else
-		PD.capacity = PD.sectors*PD.heads*PD.cylinders;
-
-        for(j=0;j<PD_ID_LEN;j++) id[j^1] = pd_scratch[j+PD_ID_OFF];
-        j = PD_ID_LEN-1;
-        while ((j >= 0) && (id[j] <= 0x20)) j--;
-        j++; id[j] = 0;
+*/
 
-        PD.removable = (word_val(0) & 0x80);
- 
-        printk("%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media\n",
-                    PD.name,id,
-		    PD.drive?"slave":"master",
-		    PD.capacity,PD.capacity/2048,
-                    PD.cylinders,PD.heads,PD.sectors,
-                    PD.removable?"removable":"fixed");
+	if (disk->drive == 0)
+		pd_reset(disk);
 
-        if (PD.capacity) pd_init_dev_parms(unit);
-        if (!PD.standby) pd_standby_off(unit);
+	pi_connect(disk->pi);
+	write_reg(disk, 6, DRIVE(disk));
+	pd_wait_for(disk, 0, DBMSG("before IDENT"));
+	pd_send_command(disk, 1, 0, 0, 0, 0, IDE_IDENTIFY);
 
-        return 1;
-}
+	if (pd_wait_for(disk, STAT_DRQ, DBMSG("IDENT DRQ")) & STAT_ERR) {
+		pi_disconnect(disk->pi);
+		return 0;
+	}
+	pi_read_block(disk->pi, pd_scratch, 512);
+	pi_disconnect(disk->pi);
+	disk->can_lba = pd_scratch[99] & 2;
+	disk->sectors = le16_to_cpu(*(u16 *) (pd_scratch + 12));
+	disk->heads = le16_to_cpu(*(u16 *) (pd_scratch + 6));
+	disk->cylinders = le16_to_cpu(*(u16 *) (pd_scratch + 2));
+	if (disk->can_lba)
+		disk->capacity = le32_to_cpu(*(u32 *) (pd_scratch + 120));
+	else
+		disk->capacity = disk->sectors * disk->heads * disk->cylinders;
 
-static int pd_probe_drive( int unit )
-{
-	if (PD.drive == -1) {
-		for (PD.drive=0;PD.drive<=1;PD.drive++)
-			if (pd_identify(unit))
+	for (j = 0; j < PD_ID_LEN; j++)
+		id[j ^ 1] = pd_scratch[j + PD_ID_OFF];
+	j = PD_ID_LEN - 1;
+	while ((j >= 0) && (id[j] <= 0x20))
+		j--;
+	j++;
+	id[j] = 0;
+
+	disk->removable = pd_scratch[0] & 0x80;
+
+	printk("%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media\n",
+	       disk->name, id,
+	       disk->drive ? "slave" : "master",
+	       disk->capacity, disk->capacity / 2048,
+	       disk->cylinders, disk->heads, disk->sectors,
+	       disk->removable ? "removable" : "fixed");
+
+	if (disk->capacity)
+		pd_init_dev_parms(disk);
+	if (!disk->standby)
+		pd_standby_off(disk);
+
+	return 1;
+}
+
+static int pd_probe_drive(struct pd_unit *disk)
+{
+	if (disk->drive == -1) {
+		for (disk->drive = 0; disk->drive <= 1; disk->drive++)
+			if (pd_identify(disk))
 				return 1;
 		return 0;
 	}
-	return pd_identify(unit);
+	return pd_identify(disk);
 }
 
-static int pd_detect( void )
+static int pd_detect(void)
 {
-	int	k, unit;
+	int k, unit;
+	struct pd_unit *disk;
 
 	k = 0;
-	if (pd_drive_count == 0) {  /* nothing spec'd - so autoprobe for 1 */
-	    unit = 0;
-	    if (pi_init(PI,1,-1,-1,-1,-1,-1,pd_scratch,
-	             PI_PD,verbose,PD.name)) {
-		if (pd_probe_drive(unit)) {
-			PD.present = 1;
-			k = 1;
-		} else pi_release(PI);
-	    }
-
-   	} else for (unit=0;unit<PD_UNITS;unit++) if (DU[D_PRT])
-	    if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
-			DU[D_PRO],DU[D_DLY],pd_scratch,
-			PI_PD,verbose,PD.name)) {
-                if (pd_probe_drive(unit)) {
-                        PD.present = 1;
-                        k = unit+1;
-                } else pi_release(PI);
-            }
-	for (unit=0;unit<PD_UNITS;unit++) {
-		if (PD.present) {
-			PD.gd.major_name = PD.name;
-			PD.gd.minor_shift = PD_BITS;
-			PD.gd.fops = &pd_fops;
-			PD.gd.major = major;
-			PD.gd.first_minor = unit << PD_BITS;
-			set_capacity(&PD.gd, PD.capacity);
-			add_disk(&PD.gd);
+	if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
+		disk = pd;
+		if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch,
+			    PI_PD, verbose, disk->name)) {
+			if (pd_probe_drive(disk)) {
+				disk->present = 1;
+				k = 1;
+			} else
+				pi_release(disk->pi);
+		}
+
+	} else {
+		for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
+			int *parm = *drives[unit];
+			if (!parm[D_PRT])
+				continue;
+			if (pi_init(disk->pi, 0, parm[D_PRT], parm[D_MOD],
+				     parm[D_UNI], parm[D_PRO], parm[D_DLY],
+				     pd_scratch, PI_PD, verbose, disk->name)) {
+				if (pd_probe_drive(disk)) {
+					disk->present = 1;
+					k = unit + 1;
+				} else
+					pi_release(disk->pi);
+			}
+		}
+	}
+	for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
+		if (disk->present) {
+			disk->gd.major_name = disk->name;
+			disk->gd.minor_shift = PD_BITS;
+			disk->gd.fops = &pd_fops;
+			disk->gd.major = major;
+			disk->gd.first_minor = unit << PD_BITS;
+			set_capacity(&disk->gd, disk->capacity);
+			add_disk(&disk->gd);
 		}
 	}
 	if (k)
-		return 1; 
-        printk("%s: no valid drive found\n",name);
-        return 0;
+		return 1;
+	printk("%s: no valid drive found\n", name);
+	return 0;
 }
 
 /* The i/o request engine */
 
-static int pd_ready( void )
-
-{ 	int unit = pd_unit;
-
-	return (!(RR(1,6) & STAT_BUSY)) ;
+static int pd_ready(void)
+{
+	return !(status_reg(pd_current) & STAT_BUSY);
 }
 
-static void do_pd_request (request_queue_t * q)
+static void do_pd_request(request_queue_t * q)
 {
-	int	unit;
+	int unit;
 
-        if (pd_busy) return;
+	if (pd_busy)
+		return;
 repeat:
 	if (blk_queue_empty(QUEUE))
 		return;
 
-        pd_dev = minor(CURRENT->rq_dev);
-	pd_unit = unit = DEVICE_NR(CURRENT->rq_dev);
-        pd_block = CURRENT->sector;
-        pd_run = CURRENT->nr_sectors;
-        pd_count = CURRENT->current_nr_sectors;
-
-        if ((pd_dev >= PD_DEVS) || 
-	    ((pd_block+pd_count) > get_capacity(&pd[unit].gd))) {
-                end_request(CURRENT, 0);
-                goto repeat;
-        }
-
-	pd_cmd = rq_data_dir(CURRENT);
-        pd_buf = CURRENT->buffer;
-        pd_retries = 0;
-
-	pd_busy = 1;
-        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(CURRENT, 0);
-                goto repeat;
-        }
-}
+	pd_req = elv_next_request(QUEUE);
+	unit = DEVICE_NR(pd_req->rq_dev);
+	if (unit >= PD_UNITS) {
+		end_request(pd_req, 0);
+		goto repeat;
+	}
 
-static void pd_next_buf( int unit )
+	pd_block = pd_req->sector;
+	pd_run = pd_req->nr_sectors;
+	pd_count = pd_req->current_nr_sectors;
+	pd_current = pd + unit;
+	if (pd_block + pd_count > get_capacity(&pd_current->gd)) {
+		end_request(pd_req, 0);
+		goto repeat;
+	}
 
-{	long	saved_flags;
+	pd_cmd = rq_data_dir(pd_req);
+	pd_buf = pd_req->buffer;
+	pd_retries = 0;
 
-	spin_lock_irqsave(&pd_lock,saved_flags);
-	end_request(CURRENT, 1);
-	if (!pd_run) {  spin_unlock_irqrestore(&pd_lock,saved_flags);
-			return; 
+	pd_busy = 1;
+	if (pd_cmd == READ)
+		pi_do_claimed(pd_current->pi, do_pd_read);
+	else if (pd_cmd == WRITE)
+		pi_do_claimed(pd_current->pi, do_pd_write);
+	else {
+		pd_busy = 0;
+		end_request(pd_req, 0);
+		goto repeat;
 	}
-	
-/* paranoia */
+}
 
-	if (blk_queue_empty(QUEUE) ||
-	    (rq_data_dir(CURRENT) != pd_cmd) ||
-	    (minor(CURRENT->rq_dev) != pd_dev) ||
-	    (CURRENT->sector != pd_block)) 
-		printk("%s: OUCH: request list changed unexpectedly\n",
-			PD.name);
+static int pd_next_buf(void)
+{
+	long saved_flags;
 
-	pd_count = CURRENT->current_nr_sectors;
-	pd_buf = CURRENT->buffer;
-	spin_unlock_irqrestore(&pd_lock,saved_flags);
+	pd_count--;
+	pd_run--;
+	pd_buf += 512;
+	pd_block++;
+	if (!pd_run)
+		return 1;
+	if (pd_count)
+		return 0;
+	spin_lock_irqsave(&pd_lock, saved_flags);
+	end_request(pd_req, 1);
+	pd_count = pd_req->current_nr_sectors;
+	pd_buf = pd_req->buffer;
+	spin_unlock_irqrestore(&pd_lock, saved_flags);
+	return 0;
 }
 
-static void do_pd_read( void )
+static inline void next_request(int success)
+{
+	long saved_flags;
 
-{	ps_set_intr(do_pd_read_start,0,0,nice);
+	spin_lock_irqsave(&pd_lock, saved_flags);
+	end_request(pd_req, success);
+	pd_busy = 0;
+	do_pd_request(NULL);
+	spin_unlock_irqrestore(&pd_lock, saved_flags);
 }
 
-static void do_pd_read_start( void )
- 
-{       int	unit = pd_unit;
-	long    saved_flags;
+static void do_pd_read(void)
+{
+	ps_set_intr(do_pd_read_start, 0, 0, nice);
+}
 
+static void do_pd_read_start(void)
+{
 	pd_busy = 1;
 
-        pi_connect(PI);
-        if (pd_wait_for(unit,STAT_READY,"do_pd_read") & STAT_ERR) {
-                pi_disconnect(PI);
-                if (pd_retries < PD_MAX_RETRIES) {
-                        pd_retries++;
-                        pi_do_claimed(PI,do_pd_read_start);
+	pi_connect(pd_current->pi);
+	if (pd_wait_for(pd_current, STAT_READY, "do_pd_read") & STAT_ERR) {
+		pi_disconnect(pd_current->pi);
+		if (pd_retries < PD_MAX_RETRIES) {
+			pd_retries++;
+			pi_do_claimed(pd_current->pi, do_pd_read_start);
 			return;
-                }
-		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(CURRENT, 0);
-                pd_busy = 0;
-		do_pd_request(NULL);
-		spin_unlock_irqrestore(&pd_lock,saved_flags);
-                return;
-        }
-        pd_ide_command(unit,IDE_READ,pd_block,pd_run);
-        ps_set_intr(do_pd_read_drq,pd_ready,PD_TMO,nice);
+		}
+		next_request(0);
+		return;
+	}
+	pd_ide_command(pd_current, IDE_READ, pd_block, pd_run);
+	ps_set_intr(do_pd_read_drq, pd_ready, PD_TMO, nice);
 }
 
-static void do_pd_read_drq( void )
-
-{       int	unit = pd_unit;
-	long    saved_flags;
-
+static void do_pd_read_drq(void)
+{
 	while (1) {
-            if (pd_wait_for(unit,STAT_DRQ,"do_pd_read_drq") & STAT_ERR) {
-                pi_disconnect(PI);
-                if (pd_retries < PD_MAX_RETRIES) {
-                        pd_retries++;
-                        pi_do_claimed(PI,do_pd_read_start);
-                        return;
-                }
-		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(CURRENT, 0);
-                pd_busy = 0;
-		do_pd_request(NULL);
-		spin_unlock_irqrestore(&pd_lock,saved_flags);
-                return;
-            }
-            pi_read_block(PI,pd_buf,512);
-            pd_count--; pd_run--;
-            pd_buf += 512;
-	    pd_block++;
-	    if (!pd_run) break;
-	    if (!pd_count) pd_next_buf(unit);
-        }
-        pi_disconnect(PI);
-	spin_lock_irqsave(&pd_lock,saved_flags);
-        end_request(CURRENT, 1);
-        pd_busy = 0;
-	do_pd_request(NULL);
-	spin_unlock_irqrestore(&pd_lock,saved_flags);
+		if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_read_drq") & STAT_ERR) {
+			pi_disconnect(pd_current->pi);
+			if (pd_retries < PD_MAX_RETRIES) {
+				pd_retries++;
+				pi_do_claimed(pd_current->pi, do_pd_read_start);
+				return;
+			}
+			next_request(0);
+			return;
+		}
+		pi_read_block(pd_current->pi, pd_buf, 512);
+		if (pd_next_buf())
+			break;
+	}
+	pi_disconnect(pd_current->pi);
+	next_request(1);
 }
 
-static void do_pd_write( void )
-
-{	 ps_set_intr(do_pd_write_start,0,0,nice);
+static void do_pd_write(void)
+{
+	ps_set_intr(do_pd_write_start, 0, 0, nice);
 }
 
-static void do_pd_write_start( void )
-
-{       int 	unit = pd_unit;
-	long    saved_flags;
-
+static void do_pd_write_start(void)
+{
 	pd_busy = 1;
 
-        pi_connect(PI);
-        if (pd_wait_for(unit,STAT_READY,"do_pd_write") & STAT_ERR) {
-                pi_disconnect(PI);
-                if (pd_retries < PD_MAX_RETRIES) {
-                        pd_retries++;
-			pi_do_claimed(PI,do_pd_write_start);
-                        return;
-                }
-		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(CURRENT, 0);
-                pd_busy = 0;
-		do_pd_request(NULL);
-		spin_unlock_irqrestore(&pd_lock,saved_flags);
-                return;
-        }
-        pd_ide_command(unit,IDE_WRITE,pd_block,pd_run);
+	pi_connect(pd_current->pi);
+	if (pd_wait_for(pd_current, STAT_READY, "do_pd_write") & STAT_ERR) {
+		pi_disconnect(pd_current->pi);
+		if (pd_retries < PD_MAX_RETRIES) {
+			pd_retries++;
+			pi_do_claimed(pd_current->pi, do_pd_write_start);
+			return;
+		}
+		next_request(0);
+		return;
+	}
+	pd_ide_command(pd_current, IDE_WRITE, pd_block, pd_run);
 	while (1) {
-            if (pd_wait_for(unit,STAT_DRQ,"do_pd_write_drq") & STAT_ERR) {
-                pi_disconnect(PI);
-                if (pd_retries < PD_MAX_RETRIES) {
-                        pd_retries++;
-                        pi_do_claimed(PI,do_pd_write_start);
-                        return;
-                }
-		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(CURRENT, 0);
-                pd_busy = 0;
-		do_pd_request(NULL);
-                spin_unlock_irqrestore(&pd_lock,saved_flags);
+		if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_write_drq") & STAT_ERR) {
+			pi_disconnect(pd_current->pi);
+			if (pd_retries < PD_MAX_RETRIES) {
+				pd_retries++;
+				pi_do_claimed(pd_current->pi, do_pd_write_start);
+				return;
+			}
+			next_request(0);
+			return;
+		}
+		pi_write_block(pd_current->pi, pd_buf, 512);
+		if (pd_next_buf())
+			break;
+	}
+	ps_set_intr(do_pd_write_done, pd_ready, PD_TMO, nice);
+}
+
+static void do_pd_write_done(void)
+{
+	if (pd_wait_for(pd_current, STAT_READY, "do_pd_write_done") & STAT_ERR) {
+		pi_disconnect(pd_current->pi);
+		if (pd_retries < PD_MAX_RETRIES) {
+			pd_retries++;
+			pi_do_claimed(pd_current->pi, do_pd_write_start);
+			return;
+		}
+		next_request(0);
 		return;
-            }
-            pi_write_block(PI,pd_buf,512);
-	    pd_count--; pd_run--;
-	    pd_buf += 512;
-	    pd_block++;
-	    if (!pd_run) break;
-	    if (!pd_count) pd_next_buf(unit);
-	}
-        ps_set_intr(do_pd_write_done,pd_ready,PD_TMO,nice);
-}
-
-static void do_pd_write_done( void )
-
-{       int	unit = pd_unit;
-	long    saved_flags;
-
-        if (pd_wait_for(unit,STAT_READY,"do_pd_write_done") & STAT_ERR) {
-                pi_disconnect(PI);
-                if (pd_retries < PD_MAX_RETRIES) {
-                        pd_retries++;
-                        pi_do_claimed(PI,do_pd_write_start);
-                        return;
-                }
-		spin_lock_irqsave(&pd_lock,saved_flags);
-                end_request(CURRENT, 0);
-                pd_busy = 0;
-		do_pd_request(NULL);
-		spin_unlock_irqrestore(&pd_lock,saved_flags);
-                return;
-        }
-        pi_disconnect(PI);
-	spin_lock_irqsave(&pd_lock,saved_flags);
-        end_request(CURRENT, 1);
-        pd_busy = 0;
-	do_pd_request(NULL);
-	spin_unlock_irqrestore(&pd_lock,saved_flags);
+	}
+	pi_disconnect(pd_current->pi);
+	next_request(1);
 }
 
 static int __init pd_init(void)
 {
-	request_queue_t * q;
-	if (disable) return -1;
-        if (register_blkdev(MAJOR_NR,name,&pd_fops)) {
-                printk("%s: unable to get major number %d\n",
-                        name,major);
-                return -1;
-        }
+	request_queue_t *q;
+	if (disable)
+		return -1;
+	if (register_blkdev(MAJOR_NR, name, &pd_fops)) {
+		printk("%s: unable to get major number %d\n", name, major);
+		return -1;
+	}
 	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
 	blk_init_queue(q, do_pd_request, &pd_lock);
 	blk_queue_max_sectors(q, cluster);
 
 	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
-		name,name,PD_VERSION,major,cluster,nice);
+	       name, name, PD_VERSION, major, cluster, nice);
 	pd_init_units();
-        if (!pd_detect()) {
+	if (!pd_detect()) {
 		unregister_blkdev(MAJOR_NR, name);
 		return -1;
 	}
-        return 0;
+	return 0;
 }
 
 static void __exit pd_exit(void)
 {
+	struct pd_unit *disk;
 	int unit;
 	unregister_blkdev(MAJOR_NR, name);
-	for (unit=0; unit<PD_UNITS; unit++) 
-		if (PD.present) {
-			del_gendisk(&PD.gd);
-			pi_release(PI);
+	for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
+		if (disk->present) {
+			del_gendisk(&disk->gd);
+			pi_release(disk->pi);
 		}
+	}
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
--- a/drivers/block/ps2esdi.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/block/ps2esdi.c	Fri Sep 27 14:51:02 2002
@@ -184,7 +184,6 @@
 			" device, releasing resources\n");
 		unregister_blkdev(MAJOR_NR, "ed");
 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-		blk_clear(MAJOR_NR);
 		return error;
 	}
 	return 0;
@@ -236,7 +235,6 @@
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 	for (i = 0; i < ps2esdi_drives; i++)
 		del_gendisk(ps2esdi_gendisk + i);
-	blk_clear(MAJOR_NR);
 }
 #endif /* MODULE */
 
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/block/rd.c	Fri Sep 27 14:51:04 2002
@@ -418,7 +418,6 @@
 
 	devfs_unregister (devfs_handle);
 	unregister_blkdev( MAJOR_NR, "ramdisk" );
-	blk_clear(MAJOR_NR);
 }
 
 /* This is the registration and initialization section of the RAM disk driver */
diff -Nru a/drivers/block/xd.c b/drivers/block/xd.c
--- a/drivers/block/xd.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/block/xd.c	Fri Sep 27 14:51:05 2002
@@ -1037,7 +1037,6 @@
 	for (i = 0; i < xd_drives; i++)
 		del_gendisk(xd_gendisk + i);
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-	blk_clear(MAJOR_NR);
 	release_region(xd_iobase,4);
 }
 
diff -Nru a/drivers/block/z2ram.c b/drivers/block/z2ram.c
--- a/drivers/block/z2ram.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/block/z2ram.c	Fri Sep 27 14:51:04 2002
@@ -63,7 +63,6 @@
 
 static u_long *z2ram_map    = NULL;
 static u_long z2ram_size    = 0;
-static int z2_sizes[Z2MINOR_COUNT];
 static int z2_count         = 0;
 static int chip_count       = 0;
 static int list_count       = 0;
@@ -71,6 +70,15 @@
 
 static spinlock_t z2ram_lock = SPIN_LOCK_UNLOCKED;
 
+static struct block_device_operations z2_fops;
+static struct gendisk z2ram_gendisk = {
+	.major = MAJOR_NR,
+	.first_minor = 0,
+	.minor_shift = 0,
+	.fops = &z2_fops,
+	.major_name = "z2ram"
+};
+
 static void
 do_z2_request( request_queue_t * q )
 {
@@ -312,8 +320,7 @@
 
 	current_device = device;
 	z2ram_size <<= Z2RAM_CHUNKSHIFT;
-	z2_sizes[ device ] = z2ram_size >> 10;
-	blk_size[ MAJOR_NR ] = z2_sizes;
+	set_capacity(&z2ram_gendisk, z2ram_size >> 9;   
     }
 
     return 0;
@@ -339,11 +346,18 @@
 
 static struct block_device_operations z2_fops =
 {
-	owner:		THIS_MODULE,
-	open:		z2_open,
-	release:	z2_release,
+	.owner		= THIS_MODULE,
+	.open		= z2_open,
+	.release	= z2_release,
 };
 
+static struct gendisk *z2_find(int minor)
+{
+	if (minor > Z2MINOR_COUNT)
+		return NULL;
+	return &z2ram_gendisk;
+}
+
 int __init 
 z2_init( void )
 {
@@ -358,17 +372,9 @@
 	return -EBUSY;
     }
 
-    {
-	    /* Initialize size arrays. */
-	    int i;
-
-	    for (i = 0; i < Z2MINOR_COUNT; i++) {
-		    z2_sizes[ i ] = 0;
-	    }
-    }    
-   
     blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_z2_request, &z2ram_lock);
-    blk_size[ MAJOR_NR ] = z2_sizes;
+    add_disk(&z2ram_gendisk);
+    blk_set_probe(MAJOR_NR, z2_find);
 
     return 0;
 }
@@ -396,9 +402,11 @@
 {
     int i, j;
 
+    blk_set_probe(MAJOR_NR, NULL);
     if ( unregister_blkdev( MAJOR_NR, DEVICE_NAME ) != 0 )
 	printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n");
 
+    del_gendisk(&z2ram_gendisk);
     blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 
     if ( current_device != -1 )
diff -Nru a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
--- a/drivers/cdrom/cdu31a.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/cdrom/cdu31a.c	Fri Sep 27 14:51:03 2002
@@ -386,8 +386,7 @@
 	unsigned long flags;
 
 	if (cdu31a_irq <= 0) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(0);
+		yield();
 	} else {		/* Interrupt driven */
 
 		save_flags(flags);
@@ -3193,10 +3192,10 @@
 	.major		= MAJOR_NR,
 	.first_minor	= 0,
 	.minor_shift	= 0,
-	.major_name	= "cdu31a"
+	.major_name	= "cdu31a",
 	.fops		= &scd_bdops,
 	.flags		= GENHD_FL_CD,
-}
+};
 
 /* The different types of disc loading mechanisms supported */
 static char *load_mech[] __initdata =
diff -Nru a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
--- a/drivers/cdrom/gscd.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/cdrom/gscd.c	Fri Sep 27 14:51:02 2002
@@ -901,7 +901,7 @@
 static struct gendisk gscd_disk = {
 	.major = MAJOR_NR,
 	.first_minor = 0,
-	,minor_shift = 0,
+	.minor_shift = 0,
 	.fops = &gscd_fops,
 	.major_name = "gscd"
 };
diff -Nru a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c
--- a/drivers/cdrom/mcd.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/cdrom/mcd.c	Fri Sep 27 14:51:04 2002
@@ -227,7 +227,7 @@
 	.minor_shift	= 0,
 	.major_name	= "mcd",
 	.fops		= &mcd_bdops,
-	.flags		= GENHD_FL_CD;
+	.flags		= GENHD_FL_CD,
 };
 
 #ifndef MODULE
diff -Nru a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
--- a/drivers/cdrom/sonycd535.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/cdrom/sonycd535.c	Fri Sep 27 14:51:04 2002
@@ -344,8 +344,7 @@
 sony_sleep(void)
 {
 	if (sony535_irq_used <= 0) {	/* poll */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(0);
+		yield();
 	} else {	/* Interrupt driven */
 		cli();
 		enable_interrupts();
@@ -1461,7 +1460,8 @@
 	.first_minor = 0,
 	.minor_shift = 0,
 	.fops = &cdu_fops,
-	.major_name = "cdu"
+	.major_name = "cdu",
+};
 
 /*
  * Initialize the driver.
diff -Nru a/drivers/char/agp/Config.in b/drivers/char/agp/Config.in
--- a/drivers/char/agp/Config.in	Fri Sep 27 14:51:05 2002
+++ b/drivers/char/agp/Config.in	Fri Sep 27 14:51:05 2002
@@ -1,4 +1,9 @@
-dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
+
+if [ "$CONFIG_GART_IOMMU" = "y" ]; then
+   dep_bool '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
+else
+   dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
+fi
 if [ "$CONFIG_AGP" != "n" ]; then
    bool '  Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL
    bool '  Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810
@@ -7,6 +12,9 @@
    bool '  Generic SiS support' CONFIG_AGP_SIS
    bool '  ALI chipset support' CONFIG_AGP_ALI
    bool '  Serverworks LE/HE support' CONFIG_AGP_SWORKS
+   if [ "$CONFIG_GART_IOMMU" != "y" ]; then
+     bool '  AMD 8151 support' CONFIG_AGP_AMD_8151 
+   fi
    if [ "$CONFIG_IA64" = "y" ]; then
      bool '  Intel 460GX support' CONFIG_AGP_I460
      bool '  HP ZX1 AGP support' CONFIG_AGP_HP_ZX1
diff -Nru a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
--- a/drivers/char/agp/Makefile	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/agp/Makefile	Fri Sep 27 14:51:03 2002
@@ -16,6 +16,7 @@
 agpgart-$(CONFIG_AGP_SWORKS)	+= sworks-agp.o
 agpgart-$(CONFIG_AGP_I460)	+= i460-agp.o
 agpgart-$(CONFIG_AGP_HP_ZX1)	+= hp-agp.o
+agpgart-$(CONFIG_AGP_AMD_8151)	+= k8-agp.o
 agpgart-objs := $(agpgart-y)
 
 obj-$(CONFIG_AGP) += agpgart.o
diff -Nru a/drivers/char/agp/agp.c b/drivers/char/agp/agp.c
--- a/drivers/char/agp/agp.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/agp/agp.c	Fri Sep 27 14:51:03 2002
@@ -50,6 +50,9 @@
 struct agp_bridge_data agp_bridge = { type: NOT_SUPPORTED };
 static int agp_try_unsupported __initdata = 0;
 
+int agp_memory_reserved;
+__u32 *agp_gatt_table; 
+
 int agp_backend_acquire(void)
 {
 	if (agp_bridge.type == NOT_SUPPORTED)
@@ -243,7 +246,7 @@
 
 /* Routine to copy over information structure */
 
-void agp_copy_info(agp_kern_info * info)
+int agp_copy_info(agp_kern_info * info)
 {
 	unsigned long page_mask = 0;
 	int i;
@@ -251,7 +254,7 @@
 	memset(info, 0, sizeof(agp_kern_info));
 	if (agp_bridge.type == NOT_SUPPORTED) {
 		info->chipset = agp_bridge.type;
-		return;
+		return -EIO;
 	}
 	info->version.major = agp_bridge.version->major;
 	info->version.minor = agp_bridge.version->minor;
@@ -268,6 +271,7 @@
 		page_mask |= agp_bridge.mask_memory(page_mask, i);
 
 	info->page_mask = ~page_mask;
+	return 0;
 }
 
 /* End - Routine to copy over information structure */
@@ -518,6 +522,7 @@
 		SetPageReserved(page);
 
 	agp_bridge.gatt_table_real = (unsigned long *) table;
+	agp_gatt_table = (void *)table; 
 	CACHE_FLUSH();
 	agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
 					(PAGE_SIZE * (1 << page_order)));
@@ -625,6 +630,9 @@
 		break;
 	}
 
+	num_entries -= agp_memory_reserved/PAGE_SIZE;
+	if (num_entries < 0) num_entries = 0;
+
 	if (type != 0 || mem->type != 0) {
 		/* The generic routines know nothing of memory types */
 		return -EINVAL;
@@ -824,6 +832,17 @@
 	},
 #endif /* CONFIG_AGP_ALI */
 
+#ifdef CONFIG_AGP_AMD_8151
+	{ 
+		.device_id	= PCI_DEVICE_ID_AMD_8151_0,
+		.vendor_id  = PCI_VENDOR_ID_AMD,
+		.chipset    = AMD_8151,
+		.vendor_name = "AMD",
+		.chipset_name = "8151",
+		.chipset_setup = amd_8151_setup 
+	},
+#endif /* CONFIG_AGP_AMD */
+
 #ifdef CONFIG_AGP_AMD
 	{
 		.device_id	= PCI_DEVICE_ID_AMD_FE_GATE_7006,
@@ -858,7 +877,6 @@
 		.chipset_setup	= amd_irongate_setup,
 	},
 #endif /* CONFIG_AGP_AMD */
-
 #ifdef CONFIG_AGP_INTEL
 	{
 		.device_id	= PCI_DEVICE_ID_INTEL_82443LX_0,
@@ -1632,7 +1650,7 @@
 	.probe		= agp_probe,
 };
 
-static int __init agp_init(void)
+int __init agp_init(void)
 {
 	int ret_val;
 
@@ -1658,5 +1676,7 @@
 	}
 }
 
+#ifndef CONFIG_GART_IOMMU
 module_init(agp_init);
 module_exit(agp_cleanup);
+#endif
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/char/agp/agp.h	Fri Sep 27 14:51:04 2002
@@ -49,6 +49,7 @@
 /* chipset specific init routines. */
 int __init ali_generic_setup (struct pci_dev *pdev);
 int __init amd_irongate_setup (struct pci_dev *pdev);
+int __init amd_8151_setup (struct pci_dev *pdev);
 int __init hp_zx1_setup (struct pci_dev *pdev);
 int __init intel_i460_setup (struct pci_dev *pdev);
 int __init intel_generic_setup (struct pci_dev *pdev);
@@ -318,6 +319,22 @@
 #define AMD_ATTBASE	0x04	/* In mmio region (32-bit register) */
 #define AMD_TLBFLUSH	0x0c	/* In mmio region (32-bit register) */
 #define AMD_CACHEENTRY	0x10	/* In mmio region (32-bit register) */
+
+#define AMD_8151_APSIZE	0xb4
+#define AMD_8151_GARTBLOCK	0xb8
+
+#define AMD_X86_64_GARTAPERTURECTL	0x90
+#define AMD_X86_64_GARTAPERTUREBASE	0x94
+#define AMD_X86_64_GARTTABLEBASE	0x98
+#define AMD_X86_64_GARTCACHECTL		0x9c
+#define AMD_X86_64_GARTEN	1<<0
+
+#define AMD_8151_VMAPERTURE		0x10
+#define AMD_8151_AGP_CTL		0xb0
+#define AMD_8151_APERTURESIZE	0xb4
+#define AMD_8151_GARTPTR		0xb8
+#define AMD_8151_GTLBEN	1<<7
+#define AMD_8151_APEREN	1<<8
 
 /* ALi registers */
 #define ALI_APBASE			0x10
diff -Nru a/drivers/char/agp/k8-agp.c b/drivers/char/agp/k8-agp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/agp/k8-agp.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,476 @@
+/* 
+ * Copyright 2001,2002 SuSE Labs
+ * Distributed under the GNU public license, v2.
+ * 
+ * This is a GART driver for the AMD K8 northbridge and the AMD 8151 
+ * AGP bridge. The main work is done in the northbridge. The configuration
+ * is only mirrored in the 8151 for compatibility (could be likely
+ * removed now).
+ */ 
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/agp_backend.h>
+#include "agp.h"
+
+extern int agp_memory_reserved;
+extern __u32 *agp_gatt_table; 
+
+static u_int64_t pci_read64 (struct pci_dev *dev, int reg)
+{
+	union {
+		u64 full;
+		struct {
+			u32 high;
+			u32 low;
+		} split;
+	} tmp;
+	pci_read_config_dword(dev, reg, &tmp.split.high);
+	pci_read_config_dword(dev, reg+4, &tmp.split.low);
+	return tmp.full;
+}
+
+static void pci_write64 (struct pci_dev *dev, int reg, u64 value)
+{
+	union {
+		u64 full;
+		struct {
+			u32 high;
+			u32 low;
+		} split;
+	} tmp;
+	tmp.full = value;
+	pci_write_config_dword(dev, reg, tmp.split.high);
+	pci_write_config_dword(dev, reg+4, tmp.split.low);
+}
+
+
+static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	int i, j, num_entries;
+	void *temp;
+	long tmp;
+	u32 pte;
+	u64 addr;
+
+	temp = agp_bridge.current_size;
+
+	num_entries = A_SIZE_32(temp)->num_entries;
+
+	num_entries -= agp_memory_reserved>>PAGE_SHIFT;
+
+	if (type != 0 || mem->type != 0)
+		return -EINVAL;
+
+	/* Make sure we can fit the range in the gatt table. */
+	if ((pg_start + mem->page_count) > num_entries)
+		return -EINVAL;
+
+	j = pg_start;
+
+	/* gatt table should be empty. */
+	while (j < (pg_start + mem->page_count)) {
+		if (!PGE_EMPTY(agp_bridge.gatt_table[j]))
+			return -EBUSY;
+		j++;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		CACHE_FLUSH();
+		mem->is_flushed = TRUE;
+	}
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		addr = mem->memory[i];
+
+		tmp = addr;
+		BUG_ON(tmp & 0xffffff0000000ffc);
+		pte = (tmp & 0x000000ff00000000) >> 28;
+		pte |=(tmp & 0x00000000fffff000);
+		pte |= 1<<1|1<<0;
+
+		agp_bridge.gatt_table[j] = pte;
+	}
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+/*
+ * This hack alters the order element according
+ * to the size of a long. It sucks. I totally disown this, even
+ * though it does appear to work for the most part.
+ */
+static struct aper_size_info_32 x86_64_aperture_sizes[7] =
+{
+	{32,   8192,   3+(sizeof(long)/8), 0 },
+	{64,   16384,  4+(sizeof(long)/8), 1<<1 },
+	{128,  32768,  5+(sizeof(long)/8), 1<<2 },
+	{256,  65536,  6+(sizeof(long)/8), 1<<1 | 1<<2 },
+	{512,  131072, 7+(sizeof(long)/8), 1<<3 },
+	{1024, 262144, 8+(sizeof(long)/8), 1<<1 | 1<<3},
+	{2048, 524288, 9+(sizeof(long)/8), 1<<2 | 1<<3}
+};
+
+
+/*
+ * Get the current Aperture size from the x86-64.
+ * Note, that there may be multiple x86-64's, but we just return
+ * the value from the first one we find. The set_size functions
+ * keep the rest coherent anyway. Or at least should do.
+ */
+static int amd_x86_64_fetch_size(void)
+{
+	struct pci_dev *dev;
+	int i;
+	u32 temp;
+	struct aper_size_info_32 *values;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 &&
+			PCI_FUNC(dev->devfn)==3 &&
+			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
+
+			pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp);
+			temp = (temp & 0xe);
+			values = A_SIZE_32(x86_64_aperture_sizes);
+
+			for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+				if (temp == values[i].size_value) {
+					agp_bridge.previous_size =
+					    agp_bridge.current_size = (void *) (values + i);
+
+					agp_bridge.aperture_size_idx = i;
+					return values[i].size;
+				}
+			}
+		}
+	}
+	/* erk, couldn't find an x86-64 ? */
+	return 0;
+}
+
+
+static void inline flush_x86_64_tlb(struct pci_dev *dev)
+{
+	u32 tmp;
+
+	pci_read_config_dword (dev, AMD_X86_64_GARTCACHECTL, &tmp);
+	tmp |= 1<<0;
+	pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
+}
+
+
+void amd_x86_64_tlbflush(agp_memory * temp)
+{
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
+		    PCI_SLOT(dev->devfn) >=24 && PCI_SLOT(dev->devfn) <=31) {
+			flush_x86_64_tlb (dev);
+		}
+	}
+}
+
+
+/*
+ * In a multiprocessor x86-64 system, this function gets
+ * called once for each CPU.
+ */
+u64 amd_x86_64_configure (struct pci_dev *hammer, u64 gatt_table)
+{
+	u64 aperturebase;
+	u32 tmp;
+	u64 addr, aper_base;
+
+	/* Address to map to */
+	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
+	aperturebase = tmp << 25;
+	aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* address of the mappings table */
+	addr = (u64) gatt_table;
+	addr >>= 12;
+	tmp = (u32) addr<<4;
+	tmp &= ~0xf;
+	pci_write_config_dword (hammer, AMD_X86_64_GARTTABLEBASE, tmp);
+
+	/* Enable GART translation for this hammer. */
+	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp);
+	tmp &= 0x3f;
+	tmp |= 1<<0;
+	pci_write_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, tmp);
+
+	/* keep CPU's coherent. */
+	flush_x86_64_tlb (hammer);
+	
+	return aper_base;
+}
+
+
+static struct aper_size_info_32 amd_8151_sizes[7] =
+{
+	{2048, 524288, 9, 0x00000000 },	/* 0 0 0 0 0 0 */
+	{1024, 262144, 8, 0x00000400 },	/* 1 0 0 0 0 0 */
+	{512,  131072, 7, 0x00000600 },	/* 1 1 0 0 0 0 */
+	{256,  65536,  6, 0x00000700 },	/* 1 1 1 0 0 0 */
+	{128,  32768,  5, 0x00000720 },	/* 1 1 1 1 0 0 */
+	{64,   16384,  4, 0x00000730 },	/* 1 1 1 1 1 0 */
+	{32,   8192,   3, 0x00000738 } 	/* 1 1 1 1 1 1 */
+};
+
+static int amd_8151_configure(void)
+{
+	struct pci_dev *dev, *hammer=NULL;
+	int current_size;
+	int tmp, tmp2, i;
+	u64 aperbar;
+	unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real);
+
+	/* Configure AGP regs in each x86-64 host bridge. */
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 &&
+			PCI_FUNC(dev->devfn)==3 &&
+			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
+			agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus);
+			hammer = dev;
+
+			/*
+			 * TODO: Cache pci_dev's of x86-64's in private struct to save us
+			 * having to scan the pci list each time.
+			 */
+		}
+	}
+
+	if (hammer == NULL) {
+		return -ENODEV;
+	}
+
+	/* Shadow x86-64 registers into 8151 registers. */
+
+	dev = agp_bridge.dev;
+	if (!dev) 
+		return -ENODEV;
+
+	current_size = amd_x86_64_fetch_size();
+
+	pci_read_config_dword(dev, AMD_8151_APERTURESIZE, &tmp);
+	tmp &= ~(0xfff);
+
+	/* translate x86-64 size bits to 8151 size bits*/
+	for (i=0 ; i<7; i++) {
+		if (amd_8151_sizes[i].size == current_size)
+			tmp |= (amd_8151_sizes[i].size_value) << 3;
+	}
+	pci_write_config_dword(dev, AMD_8151_APERTURESIZE, tmp);
+
+	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
+	aperbar = pci_read64 (dev, AMD_8151_VMAPERTURE);
+	aperbar |= (tmp & 0x7fff) <<25;
+	aperbar &= 0x000000ffffffffff;
+	aperbar |= 1<<2;	/* This address is a 64bit ptr FIXME: Make conditional in 32bit mode */
+	pci_write64 (dev, AMD_8151_VMAPERTURE, aperbar);
+
+	pci_read_config_dword(dev, AMD_8151_AGP_CTL , &tmp);
+	tmp &= ~(AMD_8151_GTLBEN | AMD_8151_APEREN);
+	
+	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp2);
+	if (tmp2 & AMD_X86_64_GARTEN)
+		tmp |= AMD_8151_APEREN;
+	// FIXME: bit 7 of AMD_8151_AGP_CTL (GTLBEN) must be copied if set.
+	// But where is it set ?
+	pci_write_config_dword(dev, AMD_8151_AGP_CTL, tmp);
+
+	return 0;
+}
+
+
+static void amd_8151_cleanup(void)
+{
+	struct pci_dev *dev;
+	u32 tmp;
+
+	pci_for_each_dev(dev) {
+		/* disable gart translation */
+		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
+		    (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) {
+
+			pci_read_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, &tmp);
+			tmp &= ~(AMD_X86_64_GARTEN);
+			pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp);
+		}
+
+		/* Now shadow the disable in the 8151 */
+		if (dev->vendor == PCI_VENDOR_ID_AMD &&
+			dev->device == PCI_DEVICE_ID_AMD_8151_0) {
+
+			pci_read_config_dword (dev, AMD_8151_AGP_CTL, &tmp);
+			tmp &= ~(AMD_8151_APEREN);	
+			pci_write_config_dword (dev, AMD_8151_AGP_CTL, tmp);
+		}
+	}
+}
+
+
+
+static unsigned long amd_8151_mask_memory(unsigned long addr, int type)
+{
+	return addr | agp_bridge.masks[0].mask;
+}
+
+
+static struct gatt_mask amd_8151_masks[] =
+{
+	{0x00000001, 0}
+};
+
+
+/*
+ * Try to configure an AGP v3 capable setup.
+ * If we fail (typically because we don't have an AGP v3
+ * card in the system) we fall back to the generic AGP v2
+ * routines.
+ */
+static void agp_x86_64_agp_enable(u32 mode)
+{
+	struct pci_dev *device = NULL;
+	u32 command, scratch; 
+	u8 cap_ptr;
+	u8 agp_v3;
+	u8 v3_devs=0;
+
+	/* FIXME: If 'mode' is x1/x2/x4 should we call the AGPv2 routines directly ?
+	 * Messy, as some AGPv3 cards can only do x4 as a minimum.
+	 */
+
+	/* PASS1: Count # of devs capable of AGPv3 mode. */
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00) {
+			pci_read_config_dword(device, cap_ptr, &scratch);
+			scratch &= (1<<20|1<<21|1<<22|1<<23);
+			scratch = scratch>>20;
+			/* AGP v3 capable ? */
+			if (scratch>=3) {
+				v3_devs++;
+				printk (KERN_INFO "AGP: Found AGPv3 capable device at %d:%d:%d\n",
+					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
+			} else {
+				printk (KERN_INFO "AGP: Meh. version %x AGP device found.\n", scratch);
+			}
+		}
+	}
+	/* If not enough, go to AGP v2 setup */
+	if (v3_devs<2) {
+		printk (KERN_INFO "AGP: Only %d devices found, not enough, trying AGPv2\n", v3_devs);
+		return agp_generic_agp_enable(mode);
+	} else {
+		printk (KERN_INFO "AGP: Enough AGPv3 devices found, setting up...\n");
+	}
+
+
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
+
+	/*
+	 * PASS2: go through all devices that claim to be
+	 *        AGP devices and collect their data.
+	 */
+
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00) {
+			/*
+			 * Ok, here we have a AGP device. Disable impossible 
+			 * settings, and adjust the readqueue to the minimum.
+			 */
+
+			printk (KERN_INFO "AGP: Setting up AGPv3 capable device at %d:%d:%d\n",
+					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
+			pci_read_config_dword(device, cap_ptr + 4, &scratch);
+			agp_v3 = (scratch & (1<<3) ) >>3;
+
+			/* adjust RQ depth */
+			command =
+			    ((command & ~0xff000000) |
+			     min_t(u32, (mode & 0xff000000),
+				 min_t(u32, (command & 0xff000000),
+				     (scratch & 0xff000000))));
+
+			/* disable SBA if it's not supported */
+			if (!((command & 0x200) && (scratch & 0x200) && (mode & 0x200)))
+				command &= ~0x200;
+
+			/* disable FW if it's not supported */
+			if (!((command & 0x10) && (scratch & 0x10) && (mode & 0x10)))
+				command &= ~0x10;
+
+			if (!((command & 2) && (scratch & 2) && (mode & 2))) {
+				command &= ~2;		/* 8x */
+				printk (KERN_INFO "AGP: Putting device into 8x mode\n");
+			}
+
+			if (!((command & 1) && (scratch & 1) && (mode & 1))) {
+				command &= ~1;		/* 4x */
+				printk (KERN_INFO "AGP: Putting device into 4x mode\n");
+			}
+		}
+	}
+	/*
+	 * PASS3: Figure out the 8X/4X setting and enable the
+	 *        target (our motherboard chipset).
+	 */
+
+	if (command & 2)
+		command &= ~5;	/* 8X */
+
+	if (command & 1)
+		command &= ~6;	/* 4X */
+
+	command |= 0x100;
+
+	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + 8, command);
+
+	/*
+	 * PASS4: Go through all AGP devices and update the
+	 *        command registers.
+	 */
+
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00)
+			pci_write_config_dword(device, cap_ptr + 8, command);
+	}
+}
+
+
+int __init amd_8151_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = amd_8151_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) amd_8151_sizes;
+	agp_bridge.size_type = U32_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = amd_8151_configure;
+	agp_bridge.fetch_size = amd_x86_64_fetch_size;
+	agp_bridge.cleanup = amd_8151_cleanup;
+	agp_bridge.tlb_flush = amd_x86_64_tlbflush;
+	agp_bridge.mask_memory = amd_8151_mask_memory;
+	agp_bridge.agp_enable = agp_x86_64_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = x86_64_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+
+	return 0;
+}
diff -Nru a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
--- a/drivers/char/drm/Makefile	Fri Sep 27 14:51:05 2002
+++ b/drivers/char/drm/Makefile	Fri Sep 27 14:51:05 2002
@@ -8,7 +8,7 @@
 mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o
 i810-objs   := i810_drv.o i810_dma.o
 i830-objs   := i830_drv.o i830_dma.o
-radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o
+radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
 ffb-objs    := ffb_drv.o ffb_context.o
 
 obj-$(CONFIG_DRM_GAMMA) += gamma.o
diff -Nru a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
--- a/drivers/char/drm/drmP.h	Fri Sep 27 14:51:05 2002
+++ b/drivers/char/drm/drmP.h	Fri Sep 27 14:51:05 2002
@@ -165,7 +165,7 @@
 #define pte_unmap(pte)
 #endif
 
-#if LINUX_VERSION_CODE < 0x020413 /* KERNEL_VERSION(2,4,19) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
 static inline struct page * vmalloc_to_page(void * vmalloc_addr)
 {
 	unsigned long addr = (unsigned long) vmalloc_addr;
@@ -190,7 +190,7 @@
 }
 #endif
 
-#if LINUX_VERSION_CODE < 0x020500
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #define DRM_RPR_ARG(vma)
 #else
 #define DRM_RPR_ARG(vma) vma,
@@ -597,7 +597,7 @@
 #endif
 	struct pci_dev *pdev;
 #ifdef __alpha__
-#if LINUX_VERSION_CODE < 0x020403
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
 	struct pci_controler *hose;
 #else
 	struct pci_controller *hose;
diff -Nru a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h
--- a/drivers/char/drm/drm_bufs.h	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/drm/drm_bufs.h	Fri Sep 27 14:51:03 2002
@@ -137,6 +137,7 @@
 		}
 		map->offset = (unsigned long)map->handle;
 		if ( map->flags & _DRM_CONTAINS_LOCK ) {
+			dev->sigdata.lock =
 			dev->lock.hw_lock = map->handle; /* Pointer to lock */
 		}
 		break;
diff -Nru a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h
--- a/drivers/char/drm/drm_drv.h	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/drm/drm_drv.h	Fri Sep 27 14:51:03 2002
@@ -306,7 +306,7 @@
 	dev->map_count = 0;
 
 	dev->vmalist = NULL;
-	dev->lock.hw_lock = NULL;
+	dev->sigdata.lock = dev->lock.hw_lock = NULL;
 	init_waitqueue_head( &dev->lock.lock_queue );
 	dev->queue_count = 0;
 	dev->queue_reserved = 0;
@@ -491,7 +491,7 @@
 	DRM(dma_takedown)( dev );
 #endif
 	if ( dev->lock.hw_lock ) {
-		dev->lock.hw_lock = NULL; /* SHM removed */
+		dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
 		dev->lock.pid = 0;
 		wake_up_interruptible( &dev->lock.lock_queue );
 	}
diff -Nru a/drivers/char/drm/drm_lock.h b/drivers/char/drm/drm_lock.h
--- a/drivers/char/drm/drm_lock.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/char/drm/drm_lock.h	Fri Sep 27 14:51:04 2002
@@ -237,7 +237,7 @@
 
 
 				/* Allow signal delivery if lock isn't held */
-	if (!_DRM_LOCK_IS_HELD(s->lock->lock)
+	if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
 	    || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
 
 				/* Otherwise, set flag to force call to
diff -Nru a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
--- a/drivers/char/drm/drm_os_linux.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/char/drm/drm_os_linux.h	Fri Sep 27 14:51:04 2002
@@ -16,6 +16,9 @@
 #define DRM_DEVICE	drm_file_t	*priv	= filp->private_data; \
 			drm_device_t	*dev	= priv->dev
 
+#define DRM_IRQ_ARGS	        int irq, void *arg, struct pt_regs *regs
+#define DRM_TASKQUEUE_ARGS	void *arg
+
 /* For data going from/to the kernel through the ioctl argument */
 #define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3)	\
 	if ( copy_from_user(&arg1, arg2, arg3) )	\
diff -Nru a/drivers/char/drm/i830.h b/drivers/char/drm/i830.h
--- a/drivers/char/drm/i830.h	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/drm/i830.h	Fri Sep 27 14:51:03 2002
@@ -45,11 +45,11 @@
 
 #define DRIVER_NAME		"i830"
 #define DRIVER_DESC		"Intel 830M"
-#define DRIVER_DATE		"20011004"
+#define DRIVER_DATE		"20020828"
 
 #define DRIVER_MAJOR		1
 #define DRIVER_MINOR		2
-#define DRIVER_PATCHLEVEL	0
+#define DRIVER_PATCHLEVEL	1
 
 #define DRIVER_IOCTLS							    \
 	[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)]   = { i830_dma_init,    1, 1 }, \
@@ -87,50 +87,10 @@
 	i830_dma_quiescent( dev );					\
 } while (0)
 
-#define __HAVE_DMA_IRQ		1
-#define __HAVE_DMA_IRQ_BH	1
-#define __HAVE_SHARED_IRQ       1
-#define DRIVER_PREINSTALL() do {					\
-	drm_i830_private_t *dev_priv =					\
-		(drm_i830_private_t *)dev->dev_private;			\
-	u16 tmp;							\
-   	tmp = I830_READ16( I830REG_HWSTAM );				\
-   	tmp = tmp & 0x6000;						\
-   	I830_WRITE16( I830REG_HWSTAM, tmp );				\
-									\
-      	tmp = I830_READ16( I830REG_INT_MASK_R );			\
-   	tmp = tmp & 0x6000;		/* Unmask interrupts */		\
-   	I830_WRITE16( I830REG_INT_MASK_R, tmp );			\
-   	tmp = I830_READ16( I830REG_INT_ENABLE_R );			\
-   	tmp = tmp & 0x6000;		/* Disable all interrupts */	\
-      	I830_WRITE16( I830REG_INT_ENABLE_R, tmp );			\
-} while (0)
-
-#define DRIVER_POSTINSTALL() do {					\
-	drm_i830_private_t *dev_priv =					\
-		(drm_i830_private_t *)dev->dev_private;	\
-	u16 tmp;							\
-   	tmp = I830_READ16( I830REG_INT_ENABLE_R );			\
-   	tmp = tmp & 0x6000;						\
-   	tmp = tmp | 0x0003;	/* Enable bp & user interrupts */	\
-   	I830_WRITE16( I830REG_INT_ENABLE_R, tmp );			\
-} while (0)
-
-#define DRIVER_UNINSTALL() do {						\
-	drm_i830_private_t *dev_priv =					\
-		(drm_i830_private_t *)dev->dev_private;			\
-	u16 tmp;							\
-	if ( dev_priv ) {						\
-		tmp = I830_READ16( I830REG_INT_IDENTITY_R );		\
-		tmp = tmp & ~(0x6000);	/* Clear all interrupts */	\
-		if ( tmp != 0 )						\
-			I830_WRITE16( I830REG_INT_IDENTITY_R, tmp );	\
-									\
-		tmp = I830_READ16( I830REG_INT_ENABLE_R );		\
-		tmp = tmp & 0x6000;	/* Disable all interrupts */	\
-		I830_WRITE16( I830REG_INT_ENABLE_R, tmp );		\
-	}								\
-} while (0)
+/* Don't need an irq any more.  The template code will make sure that
+ * a noop stub is generated for compatibility.
+ */
+#define __HAVE_DMA_IRQ		0
 
 /* Buffer customization:
  */
diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
--- a/drivers/char/drm/i830_dma.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/drm/i830_dma.c	Fri Sep 27 14:51:03 2002
@@ -26,8 +26,8 @@
  *
  * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
  *	    Jeff Hartmann <jhartmann@valinux.com>
- *      Keith Whitwell <keithw@valinux.com>
- *      Abraham vd Merwe <abraham@2d3d.co.za>
+ *	    Keith Whitwell <keith@tungstengraphics.com>
+ *	    Abraham vd Merwe <abraham@2d3d.co.za>
  *
  */
 
@@ -40,9 +40,10 @@
 #include <linux/interrupt.h>	/* For task queue support */
 #include <linux/delay.h>
 
-/* in case we don't have a 2.3.99-pre6 kernel or later: */
-#ifndef VM_DONTCOPY
-#define VM_DONTCOPY 0
+#ifdef DO_MUNMAP_4_ARGS
+#define DO_MUNMAP(m, a, l)	do_munmap(m, a, l, 1)
+#else
+#define DO_MUNMAP(m, a, l)	do_munmap(m, a, l)
 #endif
 
 #define I830_BUF_FREE		2
@@ -54,26 +55,24 @@
 
 #define RING_LOCALS	unsigned int outring, ringmask; volatile char *virt;
 
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
+#define down_write down
+#define up_write up
+#endif
 
-#define DO_IDLE_WORKAROUND()					\
-do {								\
-   int _head;							\
-   int _tail;							\
-   do { 							\
-      _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;	\
-      _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;	\
-      udelay(10);						\
-   } while(_head != _tail);					\
-} while(0)
+#ifndef LockPage
+#define LockPage(page)		set_bit(PG_locked, &(page)->flags)
+#endif
+#ifndef UnlockPage
+#define UnlockPage(page)	unlock_page(page)
+#endif
 
-#define I830_SYNC_WORKAROUND 0
+#define I830_VERBOSE 0
 
 #define BEGIN_LP_RING(n) do {				\
 	if (I830_VERBOSE)				\
-		DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n",	\
+		printk("BEGIN_LP_RING(%d) in %s\n",	\
 			  n, __FUNCTION__);		\
-	if (I830_SYNC_WORKAROUND)			\
-		DO_IDLE_WORKAROUND();			\
 	if (dev_priv->ring.space < n*4) 		\
 		i830_wait_ring(dev, n*4);		\
 	dev_priv->ring.space -= n*4;			\
@@ -83,13 +82,13 @@
 } while (0)
 
 #define ADVANCE_LP_RING() do {					\
-	if (I830_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n");	\
+	if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring);	\
 	dev_priv->ring.tail = outring;				\
 	I830_WRITE(LP_RING + RING_TAIL, outring);		\
 } while(0)
 
 #define OUT_RING(n) do {						\
-	if (I830_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));	\
+	if (I830_VERBOSE) printk("   OUT_RING %x\n", (int)(n));	\
 	*(volatile unsigned int *)(virt + outring) = n;			\
 	outring += 4;							\
 	outring &= ringmask;						\
@@ -201,36 +200,24 @@
 
 	if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL;
 
-	if(VM_DONTCOPY != 0) {
-#if LINUX_VERSION_CODE <= 0x020402
-		down( &current->mm->mmap_sem );
-#else
-		down_write( &current->mm->mmap_sem );
-#endif
-		old_fops = filp->f_op;
-		filp->f_op = &i830_buffer_fops;
-		dev_priv->mmap_buffer = buf;
-		buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, 
-						    PROT_READ|PROT_WRITE,
-						    MAP_SHARED, 
-						    buf->bus_address);
-		dev_priv->mmap_buffer = NULL;
-   		filp->f_op = old_fops;
-		if ((unsigned long)buf_priv->virtual > -1024UL) {
-			/* Real error */
-			DRM_DEBUG("mmap error\n");
-			retcode = (signed int)buf_priv->virtual;
-			buf_priv->virtual = 0;
-		}
-#if LINUX_VERSION_CODE <= 0x020402
-		up( &current->mm->mmap_sem );
-#else
-		up_write( &current->mm->mmap_sem );
-#endif
-	} else {
-		buf_priv->virtual = buf_priv->kernel_virtual;
-   		buf_priv->currently_mapped = I830_BUF_MAPPED;
+	down_write( &current->mm->mmap_sem );
+	old_fops = filp->f_op;
+	filp->f_op = &i830_buffer_fops;
+	dev_priv->mmap_buffer = buf;
+	buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, 
+					    PROT_READ|PROT_WRITE,
+					    MAP_SHARED, 
+					    buf->bus_address);
+	dev_priv->mmap_buffer = NULL;
+	filp->f_op = old_fops;
+	if ((unsigned long)buf_priv->virtual > -1024UL) {
+		/* Real error */
+		DRM_ERROR("mmap error\n");
+		retcode = (signed int)buf_priv->virtual;
+		buf_priv->virtual = 0;
 	}
+	up_write( &current->mm->mmap_sem );
+
 	return retcode;
 }
 
@@ -239,25 +226,15 @@
 	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
 	int retcode = 0;
 
-	if(VM_DONTCOPY != 0) {
-		if(buf_priv->currently_mapped != I830_BUF_MAPPED) 
-			return -EINVAL;
-#if LINUX_VERSION_CODE <= 0x020402
-		down( &current->mm->mmap_sem );
-#else
-		down_write( &current->mm->mmap_sem );
-#endif
+	if(buf_priv->currently_mapped != I830_BUF_MAPPED) 
+		return -EINVAL;
 
-        	retcode = do_munmap(current->mm, 
-				    (unsigned long)buf_priv->virtual, 
-				    (size_t) buf->total);
+	down_write(&current->mm->mmap_sem);
+	retcode = DO_MUNMAP(current->mm,
+			    (unsigned long)buf_priv->virtual,
+			    (size_t) buf->total);
+	up_write(&current->mm->mmap_sem);
 
-#if LINUX_VERSION_CODE <= 0x020402
-		up( &current->mm->mmap_sem );
-#else
-   		up_write( &current->mm->mmap_sem );
-#endif
-	}
    	buf_priv->currently_mapped = I830_BUF_UNMAPPED;
    	buf_priv->virtual = 0;
 
@@ -275,14 +252,14 @@
 	buf = i830_freelist_get(dev);
 	if (!buf) {
 		retcode = -ENOMEM;
-	   	DRM_DEBUG("retcode=%d\n", retcode);
+	   	DRM_ERROR("retcode=%d\n", retcode);
 		return retcode;
 	}
    
 	retcode = i830_map_buffer(buf, filp);
 	if(retcode) {
 		i830_freelist_put(dev, buf);
-	   	DRM_DEBUG("mapbuf failed, retcode %d\n", retcode);
+	   	DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
 		return retcode;
 	}
 	buf->pid     = priv->pid;
@@ -303,32 +280,17 @@
 	if(address == 0UL) 
 		return 0;
 	
-#if LINUX_VERSION_CODE < 0x020409
-	atomic_inc(&virt_to_page(address)->count);
-	set_bit(PG_locked, &virt_to_page(address)->flags);
-#else
 	get_page(virt_to_page(address));
-#if LINUX_VERSION_CODE < 0x020500
 	LockPage(virt_to_page(address));
-#else
-	SetPageLocked(virt_to_page(address));
-#endif
-#endif
 	return address;
 }
 
 static void i830_free_page(drm_device_t *dev, unsigned long page)
 {
 	if (page) {
-#if LINUX_VERSION_CODE < 0x020409
-		atomic_dec(&virt_to_page(page)->count);
-		clear_bit(PG_locked, &virt_to_page(page)->flags);
-		wake_up(&virt_to_page(page)->wait);
-#else
 		struct page *p = virt_to_page(page);
 		put_page(p);
-		unlock_page(p);
-#endif
+		UnlockPage(p);
 		free_page(page);
 	}
 }
@@ -384,7 +346,7 @@
 		}
 	  
 	   	iters++;
-		if((signed)(end - jiffies) <= 0) {
+		if(time_before(end, jiffies)) {
 		   	DRM_ERROR("space: %d wanted %d\n", ring->space, n);
 		   	DRM_ERROR("lockup\n");
 		   	goto out_wait_ring;
@@ -402,7 +364,7 @@
    	drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
       
    	ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
-     	ring->tail = I830_READ(LP_RING + RING_TAIL);
+     	ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
      	ring->space = ring->head - (ring->tail+8);
      	if (ring->space < 0) ring->space += ring->Size;
 }
@@ -478,9 +440,6 @@
 		((u8 *)dev_priv->sarea_map->handle +
 		 init->sarea_priv_offset);
 
-   	atomic_set(&dev_priv->flush_done, 0);
-	init_waitqueue_head(&dev_priv->flush_queue);
-
    	dev_priv->ring.Start = init->ring_start;
    	dev_priv->ring.End = init->ring_end;
    	dev_priv->ring.Size = init->ring_size;
@@ -504,11 +463,17 @@
 	dev_priv->pitch = init->pitch;
 	dev_priv->back_offset = init->back_offset;
 	dev_priv->depth_offset = init->depth_offset;
+	dev_priv->front_offset = init->front_offset;
 
 	dev_priv->front_di1 = init->front_offset | init->pitch_bits;
 	dev_priv->back_di1 = init->back_offset | init->pitch_bits;
 	dev_priv->zi1 = init->depth_offset | init->pitch_bits;
 
+	DRM_DEBUG("front_di1 %x\n",    dev_priv->front_di1);
+	DRM_DEBUG("back_offset %x\n", dev_priv->back_offset);
+	DRM_DEBUG("back_di1 %x\n",    dev_priv->back_di1);
+	DRM_DEBUG("pitch_bits %x\n",    init->pitch_bits);
+
 	dev_priv->cpp = init->cpp;
 	/* We are using seperate values as placeholders for mechanisms for
 	 * private backbuffer/depthbuffer usage.
@@ -574,38 +539,57 @@
    	return retcode;
 }
 
+#define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE               (1<<16)
+#define ST1_MASK                 (0xffff)
+
 /* Most efficient way to verify state for the i830 is as it is
  * emitted.  Non-conformant state is silently dropped.
- *
- * Use 'volatile' & local var tmp to force the emitted values to be
- * identical to the verified ones.
  */
-static void i830EmitContextVerified( drm_device_t *dev, 
-				     volatile unsigned int *code )
+static void i830EmitContextVerified( drm_device_t *dev,
+				     unsigned int *code )
 {
    	drm_i830_private_t *dev_priv = dev->dev_private;
 	int i, j = 0;
 	unsigned int tmp;
 	RING_LOCALS;
 
-	BEGIN_LP_RING( I830_CTX_SETUP_SIZE );
-	for ( i = 0 ; i < I830_CTX_SETUP_SIZE ; i++ ) {
+	BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 2 );
+
+	OUT_RING( GFX_OP_STIPPLE );
+	OUT_RING( 0 );
+
+
+	for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) {
 		tmp = code[i];
+		if ((tmp & (7<<29)) == CMD_3D &&
+		    (tmp & (0x1f<<24)) < (0x1d<<24)) {
+			OUT_RING( tmp ); 
+			j++;
+		} else {
+			DRM_ERROR("Skipping %d\n", i);
+		}
+	}
 
-#if 0
-		if ((tmp & (7<<29)) == (3<<29) &&
+	OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD ); 
+	OUT_RING( code[I830_CTXREG_BLENDCOLR] ); 
+	j += 2;
+
+	for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) {
+		tmp = code[i];
+		if ((tmp & (7<<29)) == CMD_3D &&
 		    (tmp & (0x1f<<24)) < (0x1d<<24)) {
 			OUT_RING( tmp ); 
 			j++;
 		} else {
-			printk("Skipping %d\n", i);
+			DRM_ERROR("Skipping %d\n", i);
 		}
-#else
-		OUT_RING( tmp ); 
-		j++;
-#endif
 	}
 
+	OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD ); 
+	OUT_RING( code[I830_CTXREG_MCSB1] ); 
+	j += 2;
+
 	if (j & 1) 
 		OUT_RING( 0 ); 
 
@@ -650,6 +634,9 @@
 	unsigned int tmp;
 	RING_LOCALS;
 
+	if (!num)
+		return;
+
 	BEGIN_LP_RING( num );
 
 	for ( i = 0 ; i < num ; i++ ) {
@@ -723,7 +710,7 @@
 			  BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
 		OUT_RING( dev_priv->zi1 );
 	} else {
-		DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
+		DRM_ERROR("bad di1 %x (allow %x or %x)\n",
 			  tmp, dev_priv->front_di1, dev_priv->back_di1);
 	}
 
@@ -745,7 +732,7 @@
 	if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {
 		OUT_RING( tmp );
 	} else {
-		DRM_DEBUG("bad scissor enable\n");
+		DRM_ERROR("bad scissor enable\n");
 		OUT_RING( 0 );
 	}
 
@@ -865,7 +852,7 @@
 			OUT_RING( BR13 );
 			OUT_RING( (pbox->y1 << 16) | pbox->x1 );
 			OUT_RING( (pbox->y2 << 16) | pbox->x2 );
-			OUT_RING( 0 );
+			OUT_RING( dev_priv->front_offset );
 			OUT_RING( clear_color );
 			ADVANCE_LP_RING();
 		}
@@ -953,7 +940,7 @@
 		OUT_RING( (pbox->y2 << 16) |
 			  pbox->x2 );
 
-		OUT_RING( 0 /* front ofs always zero */ );
+		OUT_RING( dev_priv->front_offset );
 		OUT_RING( (pbox->y1 << 16) |
 			  pbox->x1 );
 
@@ -993,7 +980,7 @@
 		}
 	}
 
-	if (used > 4*1024) 
+	if (used > 4*1023) 
 		used = 0;
 
 	if (sarea_priv->dirty)
@@ -1010,12 +997,17 @@
    	DRM_DEBUG(  "start + used - 4 : %ld\n", start + used - 4);
 
 	if (buf_priv->currently_mapped == I830_BUF_MAPPED) {
-		*(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
-					     sarea_priv->vertex_prim |
-					     ((used/4)-2));
+		u32 *vp = buf_priv->virtual;
+
+		vp[0] = (GFX_OP_PRIMITIVE |
+			 sarea_priv->vertex_prim |
+			 ((used/4)-2));
+
+		vp[used/4] = MI_BATCH_BUFFER_END;
+		used += 4;
 		
 		if (used & 4) {
-			*(u32 *)((u32)buf_priv->virtual + used) = 0;
+			vp[used/4] = 0;
 			used += 4;
 		}
 
@@ -1035,80 +1027,35 @@
 				ADVANCE_LP_RING();
 			}
 
-			BEGIN_LP_RING(4);
-
-			OUT_RING( MI_BATCH_BUFFER );
+			BEGIN_LP_RING(2);
+			OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
 			OUT_RING( start | MI_BATCH_NON_SECURE );
-			OUT_RING( start + used - 4 );
-			OUT_RING( 0 );
 			ADVANCE_LP_RING();
 			
 		} while (++i < nbox);
 	}
 
-	BEGIN_LP_RING(10);
-	OUT_RING( CMD_STORE_DWORD_IDX );
-	OUT_RING( 20 );
-	OUT_RING( dev_priv->counter );
-	OUT_RING( 0 );
-
 	if (discard) {
+		dev_priv->counter++;
+
+		(void) cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
+			       I830_BUF_HARDWARE);
+
+		BEGIN_LP_RING(8);
+		OUT_RING( CMD_STORE_DWORD_IDX );
+		OUT_RING( 20 );
+		OUT_RING( dev_priv->counter );
 		OUT_RING( CMD_STORE_DWORD_IDX );
 		OUT_RING( buf_priv->my_use_idx );
 		OUT_RING( I830_BUF_FREE );
+		OUT_RING( CMD_REPORT_HEAD );
 		OUT_RING( 0 );
+		ADVANCE_LP_RING();
 	}
-
-      	OUT_RING( CMD_REPORT_HEAD );
-	OUT_RING( 0 );
-   	ADVANCE_LP_RING();
-}
-
-/* Interrupts are only for flushing */
-void i830_dma_service(int irq, void *device, struct pt_regs *regs)
-{
-	drm_device_t	 *dev = (drm_device_t *)device;
-      	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
-   	u16 temp;
-   
-      	temp = I830_READ16(I830REG_INT_IDENTITY_R);
-   	temp = temp & ~(0x6000);
-   	if(temp != 0) I830_WRITE16(I830REG_INT_IDENTITY_R, 
-				   temp); /* Clear all interrupts */
-	else
-	   return;
- 
-   	queue_task(&dev->tq, &tq_immediate);
-   	mark_bh(IMMEDIATE_BH);
 }
 
-void DRM(dma_immediate_bh)(void *device)
-{
-	drm_device_t *dev = (drm_device_t *) device;
-      	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
 
-   	atomic_set(&dev_priv->flush_done, 1);
-   	wake_up_interruptible(&dev_priv->flush_queue);
-}
-
-static inline void i830_dma_emit_flush(drm_device_t *dev)
-{
-   	drm_i830_private_t *dev_priv = dev->dev_private;
-   	RING_LOCALS;
-
-   	i830_kernel_lost_context(dev);
-
-   	BEGIN_LP_RING(2);
-      	OUT_RING( CMD_REPORT_HEAD );
-      	OUT_RING( GFX_OP_USER_INTERRUPT );
-      	ADVANCE_LP_RING();
-
-	i830_wait_ring( dev, dev_priv->ring.Size - 8 );
-	atomic_set(&dev_priv->flush_done, 1);
-	wake_up_interruptible(&dev_priv->flush_queue);
-}
-
-static inline void i830_dma_quiescent_emit(drm_device_t *dev)
+void i830_dma_quiescent(drm_device_t *dev)
 {
       	drm_i830_private_t *dev_priv = dev->dev_private;
    	RING_LOCALS;
@@ -1119,79 +1066,27 @@
    	OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
    	OUT_RING( CMD_REPORT_HEAD );
       	OUT_RING( 0 );
-      	OUT_RING( GFX_OP_USER_INTERRUPT );
+      	OUT_RING( 0 );
    	ADVANCE_LP_RING();
 
 	i830_wait_ring( dev, dev_priv->ring.Size - 8 );
-	atomic_set(&dev_priv->flush_done, 1);
-	wake_up_interruptible(&dev_priv->flush_queue);
-}
-
-void i830_dma_quiescent(drm_device_t *dev)
-{
-      	DECLARE_WAITQUEUE(entry, current);
-  	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
-	unsigned long end;      
-
-   	if(dev_priv == NULL) {
-	   	return;
-	}
-      	atomic_set(&dev_priv->flush_done, 0);
-   	add_wait_queue(&dev_priv->flush_queue, &entry);
-   	end = jiffies + (HZ*3);
-   
-   	for (;;) {
-		current->state = TASK_INTERRUPTIBLE;
-	      	i830_dma_quiescent_emit(dev);
-	   	if (atomic_read(&dev_priv->flush_done) == 1) break;
-		if((signed)(end - jiffies) <= 0) {
-		   	DRM_ERROR("lockup\n");
-		   	break;
-		}	   
-	      	schedule_timeout(HZ*3);
-	      	if (signal_pending(current)) {
-		   	break;
-		}
-	}
-   
-   	current->state = TASK_RUNNING;
-   	remove_wait_queue(&dev_priv->flush_queue, &entry);
-   
-   	return;
 }
 
 static int i830_flush_queue(drm_device_t *dev)
 {
-   	DECLARE_WAITQUEUE(entry, current);
-  	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+   	drm_i830_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
-	unsigned long end;
-   	int i, ret = 0;      
+   	int i, ret = 0;
+   	RING_LOCALS;
+	
+   	i830_kernel_lost_context(dev);
 
-   	if(dev_priv == NULL) {
-	   	return 0;
-	}
-      	atomic_set(&dev_priv->flush_done, 0);
-   	add_wait_queue(&dev_priv->flush_queue, &entry);
-   	end = jiffies + (HZ*3);
-   	for (;;) {
-		current->state = TASK_INTERRUPTIBLE;
-	      	i830_dma_emit_flush(dev);
-	   	if (atomic_read(&dev_priv->flush_done) == 1) break;
-		if((signed)(end - jiffies) <= 0) {
-		   	DRM_ERROR("lockup\n");
-		   	break;
-		}	   
-	      	schedule_timeout(HZ*3);
-	      	if (signal_pending(current)) {
-		   	ret = -EINTR; /* Can't restart */
-		   	break;
-		}
-	}
-   
-   	current->state = TASK_RUNNING;
-   	remove_wait_queue(&dev_priv->flush_queue, &entry);
+   	BEGIN_LP_RING(2);
+      	OUT_RING( CMD_REPORT_HEAD );
+      	OUT_RING( 0 );
+      	ADVANCE_LP_RING();
 
+	i830_wait_ring( dev, dev_priv->ring.Size - 8 );
 
    	for (i = 0; i < dma->buf_count; i++) {
 	   	drm_buf_t *buf = dma->buflist[ i ];
@@ -1203,7 +1098,7 @@
 		if (used == I830_BUF_HARDWARE)
 			DRM_DEBUG("reclaimed from HARDWARE\n");
 		if (used == I830_BUF_CLIENT)
-			DRM_DEBUG("still on client HARDWARE\n");
+			DRM_DEBUG("still on client\n");
 	}
 
    	return ret;
@@ -1242,8 +1137,7 @@
 {
    	drm_file_t	  *priv	  = filp->private_data;
    	drm_device_t	  *dev	  = priv->dev;
-   
-   	DRM_DEBUG("i830_flush_ioctl\n");
+
    	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
 		DRM_ERROR("i830_flush_ioctl called without lock held\n");
 		return -EINVAL;
@@ -1381,46 +1275,17 @@
 	return retcode;
 }
 
-int i830_copybuf(struct inode *inode, struct file *filp, unsigned int cmd,
-		unsigned long arg)
+int i830_copybuf(struct inode *inode,
+		 struct file *filp, 
+		 unsigned int cmd,
+		 unsigned long arg)
 {
-	drm_file_t	  *priv	    = filp->private_data;
-	drm_device_t	  *dev	    = priv->dev;
-	drm_i830_copy_t	  d;
-   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
-   	u32 *hw_status = (u32 *)dev_priv->hw_status_page;
-   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
-     					dev_priv->sarea_priv; 
-	drm_buf_t *buf;
-	drm_i830_buf_priv_t *buf_priv;
-	drm_device_dma_t *dma = dev->dma;
-
-	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_dma called without lock held\n");
-		return -EINVAL;
-	}
-   
-   	if (copy_from_user(&d, (drm_i830_copy_t *)arg, sizeof(d)))
-		return -EFAULT;
-
-	if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
-	buf = dma->buflist[ d.idx ];
-   	buf_priv = buf->dev_private;
-	if (buf_priv->currently_mapped != I830_BUF_MAPPED) return -EPERM;
-
-	if(d.used < 0 || d.used > buf->total) return -EINVAL;
-
-   	if (copy_from_user(buf_priv->virtual, d.address, d.used))
-		return -EFAULT;
-
-   	sarea_priv->last_dispatch = (int) hw_status[5];
-
+	/* Never copy - 2.4.x doesn't need it */
 	return 0;
 }
 
 int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
 		unsigned long arg)
 {
-	if(VM_DONTCOPY == 0) return 1;
 	return 0;
 }
diff -Nru a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
--- a/drivers/char/drm/i830_drv.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/drm/i830_drv.c	Fri Sep 27 14:51:03 2002
@@ -29,6 +29,7 @@
  *    Jeff Hartmann <jhartmann@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
  *    Abraham vd Merwe <abraham@2d3d.co.za>
+ *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
 #include <linux/config.h>
diff -Nru a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
--- a/drivers/char/drm/i830_drv.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/char/drm/i830_drv.h	Fri Sep 27 14:51:04 2002
@@ -64,14 +64,13 @@
       	unsigned long hw_status_page;
    	unsigned long counter;
 
-   	atomic_t flush_done;
-   	wait_queue_head_t flush_queue;	/* Processes waiting until flush    */
 	drm_buf_t *mmap_buffer;
 	
 	u32 front_di1, back_di1, zi1;
 	
 	int back_offset;
 	int depth_offset;
+	int front_offset;
 	int w, h;
 	int pitch;
 	int back_pitch;
@@ -107,14 +106,13 @@
 extern int i830_clear_bufs(struct inode *inode, struct file *filp,
 			  unsigned int cmd, unsigned long arg);
 
-#define I830_VERBOSE 0
 
 #define I830_BASE(reg)		((unsigned long) \
 				dev_priv->mmio_map->handle)
 #define I830_ADDR(reg)		(I830_BASE(reg) + reg)
-#define I830_DEREF(reg)		*(__volatile__ int *)I830_ADDR(reg)
-#define I830_READ(reg)		I830_DEREF(reg)
-#define I830_WRITE(reg,val) 	do { I830_DEREF(reg) = val; } while (0)
+#define I830_DEREF(reg)		*(__volatile__ unsigned int *)I830_ADDR(reg)
+#define I830_READ(reg)		readl((volatile u32 *)I830_ADDR(reg))
+#define I830_WRITE(reg,val) 	writel(val, (volatile u32 *)I830_ADDR(reg))
 #define I830_DEREF16(reg)	*(__volatile__ u16 *)I830_ADDR(reg)
 #define I830_READ16(reg) 	I830_DEREF16(reg)
 #define I830_WRITE16(reg,val)	do { I830_DEREF16(reg) = val; } while (0)
@@ -143,15 +141,15 @@
 #define LP_RING     		0x2030
 #define HP_RING     		0x2040
 #define RING_TAIL      		0x00
-#define TAIL_ADDR		0x000FFFF8
+#define TAIL_ADDR		0x001FFFF8
 #define RING_HEAD      		0x04
 #define HEAD_WRAP_COUNT     	0xFFE00000
 #define HEAD_WRAP_ONE       	0x00200000
 #define HEAD_ADDR           	0x001FFFFC
 #define RING_START     		0x08
-#define START_ADDR          	0x00FFFFF8
+#define START_ADDR          	0x0xFFFFF000
 #define RING_LEN       		0x0C
-#define RING_NR_PAGES       	0x000FF000 
+#define RING_NR_PAGES       	0x001FF000 
 #define RING_REPORT_MASK    	0x00000006
 #define RING_REPORT_64K     	0x00000002
 #define RING_REPORT_128K    	0x00000004
@@ -182,6 +180,9 @@
 
 #define CMD_OP_DESTBUFFER_INFO	 ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
 
+#define CMD_3D                          (0x3<<29)
+#define STATE3D_CONST_BLEND_COLOR_CMD   (CMD_3D|(0x1d<<24)|(0x88<<16))
+#define STATE3D_MAP_COORD_SETBIND_CMD   (CMD_3D|(0x1d<<24)|(0x02<<16))
 
 #define BR00_BITBLT_CLIENT   0x40000000
 #define BR00_OP_COLOR_BLT    0x10000000
@@ -206,6 +207,8 @@
 #define XY_SRC_COPY_BLT_WRITE_RGB       (1<<20)
 
 #define MI_BATCH_BUFFER 	((0x30<<23)|1)
+#define MI_BATCH_BUFFER_START 	(0x31<<23)
+#define MI_BATCH_BUFFER_END 	(0xA<<23)
 #define MI_BATCH_NON_SECURE	(1)
 
 
diff -Nru a/drivers/char/drm/radeon.h b/drivers/char/drm/radeon.h
--- a/drivers/char/drm/radeon.h	Fri Sep 27 14:51:05 2002
+++ b/drivers/char/drm/radeon.h	Fri Sep 27 14:51:05 2002
@@ -48,10 +48,10 @@
 
 #define DRIVER_NAME		"radeon"
 #define DRIVER_DESC		"ATI Radeon"
-#define DRIVER_DATE		"20020611"
+#define DRIVER_DATE		"20020828"
 
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		5
+#define DRIVER_MINOR		6
 #define DRIVER_PATCHLEVEL	0
 
 /* Interface history:
@@ -68,6 +68,11 @@
  * 1.5 - Add r200 packets to cmdbuf ioctl
  *     - Add r200 function to init ioctl
  *     - Add 'scalar2' instruction to cmdbuf
+ * 1.6 - Add static agp memory manager
+ *       Add irq handler (won't be turned on unless X server knows to)
+ *       Add irq ioctls and irq_active getparam.
+ *       Add wait command for cmdbuf ioctl
+ *       Add agp offset query for getparam
  */
 #define DRIVER_IOCTLS							     \
  [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
@@ -88,9 +93,18 @@
  [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)]    = { radeon_cp_vertex2,  1, 0 }, \
  [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)]     = { radeon_cp_cmdbuf,   1, 0 }, \
  [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)]   = { radeon_cp_getparam, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)]       = { radeon_cp_flip,     1, 0 }, 
-
-/* Driver customization:
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)]       = { radeon_cp_flip,     1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)]      = { radeon_mem_alloc,   1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)]       = { radeon_mem_free,    1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)]  = { radeon_mem_init_heap, 1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)]   = { radeon_irq_emit, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)]   = { radeon_irq_wait, 1, 0 },
+
+/* When a client dies:
+ *    - Check for and clean up flipped page state
+ *    - Free any alloced agp memory.
+ *
+ * DRM infrastructure takes care of reclaiming dma buffers.
  */
 #define DRIVER_PRERELEASE() do {					\
 	if ( dev->dev_private ) {					\
@@ -98,22 +112,78 @@
 		if ( dev_priv->page_flipping ) {			\
 			radeon_do_cleanup_pageflip( dev );		\
 		}							\
+		radeon_mem_release( dev_priv->agp_heap );		\
 	}								\
 } while (0)
 
+/* On unloading the module:
+ *    - Free memory heap structure
+ *    - Remove mappings made at startup and free dev_private.
+ */
 #define DRIVER_PRETAKEDOWN() do {					\
-	if ( dev->dev_private ) radeon_do_cleanup_cp( dev );		\
+	if ( dev->dev_private ) {					\
+		drm_radeon_private_t *dev_priv = dev->dev_private;	\
+		radeon_mem_takedown( &(dev_priv->agp_heap) );		\
+		radeon_do_cleanup_cp( dev );				\
+	}								\
 } while (0)
 
 /* DMA customization:
  */
 #define __HAVE_DMA		1
 
+
+#define __HAVE_DMA_IRQ		1
+#define __HAVE_DMA_IRQ_BH	1 
+#define __HAVE_SHARED_IRQ       1
+
+#define DRIVER_PREINSTALL() do {				\
+	drm_radeon_private_t *dev_priv =			\
+		(drm_radeon_private_t *)dev->dev_private;	\
+	u32 tmp;						\
+								\
+	/* Clear bit if it's already high: */			\
+   	tmp = RADEON_READ( RADEON_GEN_INT_STATUS );		\
+   	tmp = tmp & RADEON_SW_INT_TEST_ACK;			\
+   	RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp );		\
+								\
+ 	/* Disable *all* interrupts */				\
+      	RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );			\
+} while (0)
+
+#ifdef __linux__ 
+#define IWH(x) init_waitqueue_head(x) 
+#else 
+#define IWH(x) 
+#endif 
+
+#define DRIVER_POSTINSTALL() do {				\
+	drm_radeon_private_t *dev_priv =			\
+		(drm_radeon_private_t *)dev->dev_private;	\
+								\
+   	atomic_set(&dev_priv->irq_received, 0);			\
+   	atomic_set(&dev_priv->irq_emitted, 0);			\
+	IWH(&dev_priv->irq_queue);		\
+								\
+	/* Turn on SW_INT only */				\
+   	RADEON_WRITE( RADEON_GEN_INT_CNTL,			\
+		      RADEON_SW_INT_ENABLE );			\
+} while (0)
+
+#define DRIVER_UNINSTALL() do {					\
+	drm_radeon_private_t *dev_priv =			\
+		(drm_radeon_private_t *)dev->dev_private;	\
+	if ( dev_priv ) {					\
+		/* Disable *all* interrupts */			\
+		RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );		\
+	}							\
+} while (0)
+
 /* Buffer customization:
  */
 #define DRIVER_BUF_PRIV_T	drm_radeon_buf_priv_t
 
-#define DRIVER_AGP_BUFFERS_MAP( dev )					\
+#define DRIVER_AGP_BUFFERS_MAP( dev )				\
 	((drm_radeon_private_t *)((dev)->dev_private))->buffers
 
 #endif
diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
--- a/drivers/char/drm/radeon_cp.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/char/drm/radeon_cp.c	Fri Sep 27 14:51:03 2002
@@ -1412,6 +1412,9 @@
 
 	LOCK_TEST_WITH_RETURN( dev );
 
+/* 	if (dev->irq)  */
+/* 		radeon_emit_and_wait_irq( dev ); */
+
 	return radeon_do_cp_idle( dev_priv );
 }
 
diff -Nru a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
--- a/drivers/char/drm/radeon_drm.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/char/drm/radeon_drm.h	Fri Sep 27 14:51:04 2002
@@ -142,6 +142,9 @@
 #define RADEON_CMD_PACKET3     5 /* emit hw packet */
 #define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
 #define RADEON_CMD_SCALARS2     7 /* r200 stopgap */
+#define RADEON_CMD_WAIT         8 /* emit hw wait commands -- note:
+				   *  doesn't make the cpu wait, just
+				   *  the graphics hardware */
 
 
 typedef union {
@@ -161,8 +164,14 @@
 	struct { 
 		unsigned char cmd_type, buf_idx, pad0, pad1; 
 	} dma;
+	struct { 
+		unsigned char cmd_type, flags, pad0, pad1; 
+	} wait;
 } drm_radeon_cmd_header_t;
 
+#define RADEON_WAIT_2D  0x1
+#define RADEON_WAIT_3D  0x2
+
 
 #define RADEON_FRONT			0x1
 #define RADEON_BACK			0x2
@@ -364,6 +373,11 @@
 #define DRM_IOCTL_RADEON_CMDBUF     DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
 #define DRM_IOCTL_RADEON_GETPARAM   DRM_IOWR(0x51, drm_radeon_getparam_t)
 #define DRM_IOCTL_RADEON_FLIP	    DRM_IO(  0x52)
+#define DRM_IOCTL_RADEON_ALLOC      DRM_IOWR( 0x53, drm_radeon_mem_alloc_t)
+#define DRM_IOCTL_RADEON_FREE       DRM_IOW( 0x54, drm_radeon_mem_free_t)
+#define DRM_IOCTL_RADEON_INIT_HEAP  DRM_IOW( 0x55, drm_radeon_mem_init_heap_t)
+#define DRM_IOCTL_RADEON_IRQ_EMIT   DRM_IOWR( 0x56, drm_radeon_irq_emit_t)
+#define DRM_IOCTL_RADEON_IRQ_WAIT   DRM_IOW( 0x57, drm_radeon_irq_wait_t)
 
 typedef struct drm_radeon_init {
 	enum {
@@ -499,14 +513,51 @@
 /* 1.3: An ioctl to get parameters that aren't available to the 3d
  * client any other way.  
  */
-#define RADEON_PARAM_AGP_BUFFER_OFFSET 0x1
-#define RADEON_PARAM_LAST_FRAME 0x2
-#define RADEON_PARAM_LAST_DISPATCH 0x3
-#define RADEON_PARAM_LAST_CLEAR 0x4
+#define RADEON_PARAM_AGP_BUFFER_OFFSET     1 /* card offset of 1st agp buffer */
+#define RADEON_PARAM_LAST_FRAME            2
+#define RADEON_PARAM_LAST_DISPATCH         3
+#define RADEON_PARAM_LAST_CLEAR            4
+#define RADEON_PARAM_IRQ_ACTIVE            5
+#define RADEON_PARAM_AGP_BASE              6 /* card offset of agp base */
 
 typedef struct drm_radeon_getparam {
 	int param;
 	int *value;
 } drm_radeon_getparam_t;
+
+/* 1.6: Set up a memory manager for regions of shared memory:
+ */
+#define RADEON_MEM_REGION_AGP 1
+#define RADEON_MEM_REGION_FB  2
+
+typedef struct drm_radeon_mem_alloc {
+	int region;
+	int alignment;
+	int size;
+	int *region_offset;	/* offset from start of fb or agp */
+} drm_radeon_mem_alloc_t;
+
+typedef struct drm_radeon_mem_free {
+	int region;
+	int region_offset;
+} drm_radeon_mem_free_t;
+
+typedef struct drm_radeon_mem_init_heap {
+	int region;
+	int size;
+	int start;	
+} drm_radeon_mem_init_heap_t;
+
+
+/* 1.6: Userspace can request & wait on irq's:
+ */
+typedef struct drm_radeon_irq_emit {
+	int *irq_seq;
+} drm_radeon_irq_emit_t;
+
+typedef struct drm_radeon_irq_wait {
+	int irq_seq;
+} drm_radeon_irq_wait_t;
+
 
 #endif
diff -Nru a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
--- a/drivers/char/drm/radeon_drv.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/char/drm/radeon_drv.h	Fri Sep 27 14:51:04 2002
@@ -61,6 +61,15 @@
 	u32 se_cntl;
 } drm_radeon_depth_clear_t;
 
+
+struct mem_block {
+	struct mem_block *next;
+	struct mem_block *prev;
+	int start;
+	int size;
+	int pid;		/* 0: free, -1: heap, other: real pids */
+};
+
 typedef struct drm_radeon_private {
 	drm_radeon_ring_buffer_t ring;
 	drm_radeon_sarea_t *sarea_priv;
@@ -126,6 +135,14 @@
 	drm_map_t *ring_rptr;
 	drm_map_t *buffers;
 	drm_map_t *agp_textures;
+
+	struct mem_block *agp_heap;
+	struct mem_block *fb_heap;
+
+   	wait_queue_head_t irq_queue;
+   	atomic_t irq_received;
+   	atomic_t irq_emitted;
+
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
@@ -164,6 +181,20 @@
 extern int radeon_cp_getparam( DRM_IOCTL_ARGS );
 extern int radeon_cp_flip( DRM_IOCTL_ARGS );
 
+extern int radeon_mem_alloc( DRM_IOCTL_ARGS );
+extern int radeon_mem_free( DRM_IOCTL_ARGS );
+extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
+extern void radeon_mem_takedown( struct mem_block **heap );
+extern void radeon_mem_release( struct mem_block *heap );
+
+extern int radeon_irq_emit( DRM_IOCTL_ARGS );
+extern int radeon_irq_wait( DRM_IOCTL_ARGS );
+
+extern int radeon_emit_and_wait_irq(drm_device_t *dev);
+extern int radeon_wait_irq(drm_device_t *dev, int irq_nr);
+extern int radeon_emit_irq(drm_device_t *dev);
+
+
 /* Flags for stats.boxes
  */
 #define RADEON_BOX_DMA_IDLE      0x1
@@ -238,6 +269,16 @@
 				? DRM_READ32( &dev_priv->scratch[(x)] )		\
 				: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
 
+
+#define RADEON_GEN_INT_CNTL		0x0040
+#	define RADEON_GUI_IDLE_INT_ENABLE	(1 << 19)
+#	define RADEON_SW_INT_ENABLE		(1 << 25)
+
+#define RADEON_GEN_INT_STATUS		0x0044
+#	define RADEON_GUI_IDLE_INT_TEST_ACK     (1 << 19)
+#	define RADEON_SW_INT_TEST_ACK   	(1 << 25)
+#	define RADEON_SW_INT_FIRE		(1 << 26)
+
 #define RADEON_HOST_PATH_CNTL		0x0130
 #	define RADEON_HDP_SOFT_RESET		(1 << 26)
 #	define RADEON_HDP_WC_TIMEOUT_MASK	(7 << 28)
@@ -526,6 +567,8 @@
 #define RADEON_TXFORMAT_ARGB4444	5
 #define RADEON_TXFORMAT_ARGB8888	6
 #define RADEON_TXFORMAT_RGBA8888	7
+#define RADEON_TXFORMAT_VYUY422         10
+#define RADEON_TXFORMAT_YVYU422         11
 
 #define R200_PP_TXCBLEND_0                0x2f00
 #define R200_PP_TXCBLEND_1                0x2f10
diff -Nru a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/drm/radeon_irq.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,214 @@
+/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*-
+ *
+ * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+ * 
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "radeon.h"
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+/* Interrupts - Used for device synchronization and flushing in the
+ * following circumstances:
+ *
+ * - Exclusive FB access with hw idle:
+ *    - Wait for GUI Idle (?) interrupt, then do normal flush.
+ *
+ * - Frame throttling, NV_fence:
+ *    - Drop marker irq's into command stream ahead of time.
+ *    - Wait on irq's with lock *not held*
+ *    - Check each for termination condition
+ *
+ * - Internally in cp_getbuffer, etc:
+ *    - as above, but wait with lock held???
+ *
+ * NOTE: These functions are misleadingly named -- the irq's aren't
+ * tied to dma at all, this is just a hangover from dri prehistory.
+ */
+
+void DRM(dma_service)( DRM_IRQ_ARGS )
+{
+	drm_device_t *dev = (drm_device_t *) arg;
+	drm_radeon_private_t *dev_priv = 
+	   (drm_radeon_private_t *)dev->dev_private;
+   	u32 temp;
+
+	/* Need to wait for fifo to drain?
+	 */
+	temp = RADEON_READ(RADEON_GEN_INT_STATUS);  
+	temp = temp & RADEON_SW_INT_TEST_ACK;  
+	if (temp == 0) return;  
+	RADEON_WRITE(RADEON_GEN_INT_STATUS, temp);  
+
+	atomic_inc(&dev_priv->irq_received);
+#ifdef __linux__
+	queue_task(&dev->tq, &tq_immediate);  
+	mark_bh(IMMEDIATE_BH);  
+#endif /* __linux__ */
+#ifdef __FreeBSD__
+	taskqueue_enqueue(taskqueue_swi, &dev->task);
+#endif /* __FreeBSD__ */
+}
+
+void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS )
+{
+	drm_device_t *dev = (drm_device_t *) arg;
+	drm_radeon_private_t *dev_priv = 
+	   (drm_radeon_private_t *)dev->dev_private;
+
+#ifdef __linux__
+	wake_up_interruptible(&dev_priv->irq_queue); 
+#endif /* __linux__ */
+#ifdef __FreeBSD__
+	wakeup( &dev_priv->irq_queue );
+#endif
+}
+
+
+int radeon_emit_irq(drm_device_t *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+
+	atomic_inc(&dev_priv->irq_emitted);
+
+	BEGIN_RING(2); 
+	OUT_RING( CP_PACKET0( RADEON_GEN_INT_STATUS, 0 ) );
+	OUT_RING( RADEON_SW_INT_FIRE );
+	ADVANCE_RING(); 
+ 	COMMIT_RING();
+
+	return atomic_read(&dev_priv->irq_emitted);
+}
+
+
+int radeon_wait_irq(drm_device_t *dev, int irq_nr)
+{
+  	drm_radeon_private_t *dev_priv = 
+	   (drm_radeon_private_t *)dev->dev_private;
+#ifdef __linux__
+	DECLARE_WAITQUEUE(entry, current);
+	unsigned long end = jiffies + HZ*3;
+#endif /* __linux__ */
+	int ret = 0;
+
+ 	if (atomic_read(&dev_priv->irq_received) >= irq_nr)  
+ 		return 0; 
+
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+#ifdef __linux__
+	add_wait_queue(&dev_priv->irq_queue, &entry);
+
+	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
+	   	if (atomic_read(&dev_priv->irq_received) >= irq_nr) 
+		   break;
+		if((signed)(end - jiffies) <= 0) {
+		   	ret = -EBUSY;	/* Lockup?  Missed irq? */
+			break;
+		}
+	      	schedule_timeout(HZ*3);
+	      	if (signal_pending(current)) {
+		   	ret = -EINTR;
+			break;
+		}
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&dev_priv->irq_queue, &entry);
+	return ret;
+#endif /* __linux__ */
+	
+#ifdef __FreeBSD__
+	ret = tsleep( &dev_priv->irq_queue, PZERO | PCATCH, \
+		"rdnirq", 3*hz );
+	if ( (ret == EWOULDBLOCK) || (ret == EINTR) )
+		return DRM_ERR(EBUSY);
+	return ret;
+#endif /* __FreeBSD__ */
+}
+
+
+int radeon_emit_and_wait_irq(drm_device_t *dev)
+{
+	return radeon_wait_irq( dev, radeon_emit_irq(dev) );
+}
+
+
+/* Needs the lock as it touches the ring.
+ */
+int radeon_irq_emit( DRM_IOCTL_ARGS )
+{
+	DRM_DEVICE;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_irq_emit_t emit;
+	int result;
+
+	LOCK_TEST_WITH_RETURN( dev );
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return DRM_ERR(EINVAL);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL( emit, (drm_radeon_irq_emit_t *)data,
+				  sizeof(emit) );
+
+	result = radeon_emit_irq( dev );
+
+	if ( DRM_COPY_TO_USER( emit.irq_seq, &result, sizeof(int) ) ) {
+		DRM_ERROR( "copy_to_user\n" );
+		return DRM_ERR(EFAULT);
+	}
+
+	return 0;
+}
+
+
+/* Doesn't need the hardware lock.
+ */
+int radeon_irq_wait( DRM_IOCTL_ARGS )
+{
+	DRM_DEVICE;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_irq_wait_t irqwait;
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return DRM_ERR(EINVAL);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL( irqwait, (drm_radeon_irq_wait_t *)data,
+				  sizeof(irqwait) );
+
+	return radeon_wait_irq( dev, irqwait.irq_seq );
+}
+
diff -Nru a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/drm/radeon_mem.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,334 @@
+/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*-
+ *
+ * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+ * 
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "radeon.h"
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+/* Very simple allocator for agp memory, working on a static range
+ * already mapped into each client's address space.  
+ */
+
+static struct mem_block *split_block(struct mem_block *p, int start, int size,
+				     int pid )
+{
+	/* Maybe cut off the start of an existing block */
+	if (start > p->start) {
+		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		if (!newblock) 
+			goto out;
+		newblock->start = start;
+		newblock->size = p->size - (start - p->start);
+		newblock->pid = 0;
+		newblock->next = p->next;
+		newblock->prev = p;
+		p->next->prev = newblock;
+		p->next = newblock;
+		p->size -= newblock->size;
+		p = newblock;
+	}
+   
+	/* Maybe cut off the end of an existing block */
+	if (size < p->size) {
+		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		if (!newblock)
+			goto out;
+		newblock->start = start + size;
+		newblock->size = p->size - size;
+		newblock->pid = 0;
+		newblock->next = p->next;
+		newblock->prev = p;
+		p->next->prev = newblock;
+		p->next = newblock;
+		p->size = size;
+	}
+
+ out:
+	/* Our block is in the middle */
+	p->pid = pid;
+	return p;
+}
+
+static struct mem_block *alloc_block( struct mem_block *heap, int size, 
+				      int align2, int pid )
+{
+	struct mem_block *p;
+	int mask = (1 << align2)-1;
+
+	for (p = heap->next ; p != heap ; p = p->next) {
+		int start = (p->start + mask) & ~mask;
+		if (p->pid == 0 && start + size <= p->start + p->size)
+			return split_block( p, start, size, pid );
+	}
+
+	return NULL;
+}
+
+static struct mem_block *find_block( struct mem_block *heap, int start )
+{
+	struct mem_block *p;
+
+	for (p = heap->next ; p != heap ; p = p->next) 
+		if (p->start == start)
+			return p;
+
+	return NULL;
+}
+
+
+static void free_block( struct mem_block *p )
+{
+	p->pid = 0;
+
+	/* Assumes a single contiguous range.  Needs a special pid in
+	 * 'heap' to stop it being subsumed.
+	 */
+	if (p->next->pid == 0) {
+		struct mem_block *q = p->next;
+		p->size += q->size;
+		p->next = q->next;
+		p->next->prev = p;
+		DRM_FREE(p);
+	}
+
+	if (p->prev->pid == 0) {
+		struct mem_block *q = p->prev;
+		q->size += p->size;
+		q->next = p->next;
+		q->next->prev = q;
+		DRM_FREE(p);
+	}
+}
+
+static void print_heap( struct mem_block *heap )
+{
+	struct mem_block *p;
+
+	for (p = heap->next ; p != heap ; p = p->next) 
+		DRM_DEBUG("0x%x..0x%x (0x%x) -- owner %d\n",
+			  p->start, p->start + p->size,
+			  p->size, p->pid);
+}
+
+/* Initialize.  How to check for an uninitialized heap?
+ */
+static int init_heap(struct mem_block **heap, int start, int size)
+{
+	struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
+
+	if (!blocks) 
+		return -ENOMEM;
+	
+	*heap = DRM_MALLOC(sizeof(**heap));
+	if (!*heap) {
+		DRM_FREE( blocks );
+		return -ENOMEM;
+	}
+
+	blocks->start = start;
+	blocks->size = size;
+	blocks->pid = 0;
+	blocks->next = blocks->prev = *heap;
+
+	memset( *heap, 0, sizeof(**heap) );
+	(*heap)->pid = -1;
+	(*heap)->next = (*heap)->prev = blocks;
+	return 0;
+}
+
+
+/* Free all blocks associated with the releasing pid.
+ */
+void radeon_mem_release( struct mem_block *heap )
+{
+	int pid = DRM_CURRENTPID;
+	struct mem_block *p;
+
+	if (!heap || !heap->next)
+		return;
+
+	for (p = heap->next ; p != heap ; p = p->next) {
+		if (p->pid == pid) 
+			p->pid = 0;
+	}
+
+	/* Assumes a single contiguous range.  Needs a special pid in
+	 * 'heap' to stop it being subsumed.
+	 */
+	for (p = heap->next ; p != heap ; p = p->next) {
+		while (p->pid == 0 && p->next->pid == 0) {
+			struct mem_block *q = p->next;
+			p->size += q->size;
+			p->next = q->next;
+			p->next->prev = p;
+			DRM_FREE(q);
+		}
+	}
+}
+
+/* Shutdown.
+ */
+void radeon_mem_takedown( struct mem_block **heap )
+{
+	struct mem_block *p;
+	
+	if (!*heap)
+		return;
+
+	for (p = (*heap)->next ; p != *heap ; ) {
+		struct mem_block *q = p;
+		p = p->next;
+		DRM_FREE(q);
+	}
+
+	DRM_FREE( *heap );
+	*heap = 0;
+}
+
+
+
+/* IOCTL HANDLERS */
+
+static struct mem_block **get_heap( drm_radeon_private_t *dev_priv,
+				   int region )
+{
+	switch( region ) {
+	case RADEON_MEM_REGION_AGP:
+ 		return &dev_priv->agp_heap; 
+	case RADEON_MEM_REGION_FB:
+		return &dev_priv->fb_heap;
+	default:
+		return 0;
+	}
+}
+
+int radeon_mem_alloc( DRM_IOCTL_ARGS )
+{
+	DRM_DEVICE;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_mem_alloc_t alloc;
+	struct mem_block *block, **heap;
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return DRM_ERR(EINVAL);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t *)data,
+				  sizeof(alloc) );
+
+	heap = get_heap( dev_priv, alloc.region );
+	if (!heap || !*heap)
+		return DRM_ERR(EFAULT);
+	
+	/* Make things easier on ourselves: all allocations at least
+	 * 4k aligned.
+	 */
+	if (alloc.alignment < 12)
+		alloc.alignment = 12;
+
+	block = alloc_block( *heap, alloc.size, alloc.alignment,
+			     DRM_CURRENTPID );
+
+	if (!block) 
+		return DRM_ERR(ENOMEM);
+
+	if ( DRM_COPY_TO_USER( alloc.region_offset, &block->start, 
+			       sizeof(int) ) ) {
+		DRM_ERROR( "copy_to_user\n" );
+		return DRM_ERR(EFAULT);
+	}
+	
+	return 0;
+}
+
+
+
+int radeon_mem_free( DRM_IOCTL_ARGS )
+{
+	DRM_DEVICE;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_mem_free_t memfree;
+	struct mem_block *block, **heap;
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return DRM_ERR(EINVAL);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t *)data,
+				  sizeof(memfree) );
+
+	heap = get_heap( dev_priv, memfree.region );
+	if (!heap || !*heap)
+		return DRM_ERR(EFAULT);
+	
+	block = find_block( *heap, memfree.region_offset );
+	if (!block)
+		return DRM_ERR(EFAULT);
+
+	if (block->pid != DRM_CURRENTPID)
+		return DRM_ERR(EPERM);
+
+	free_block( block );	
+	return 0;
+}
+
+int radeon_mem_init_heap( DRM_IOCTL_ARGS )
+{
+	DRM_DEVICE;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_mem_init_heap_t initheap;
+	struct mem_block **heap;
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return DRM_ERR(EINVAL);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL( initheap, (drm_radeon_mem_init_heap_t *)data,
+				  sizeof(initheap) );
+
+	heap = get_heap( dev_priv, initheap.region );
+	if (!heap) 
+		return DRM_ERR(EFAULT);
+	
+	if (*heap) {
+		DRM_ERROR("heap already initialized?");
+		return DRM_ERR(EFAULT);
+	}
+		
+	return init_heap( heap, initheap.start, initheap.size );
+}
+
+
diff -Nru a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
--- a/drivers/char/drm/radeon_state.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/char/drm/radeon_state.c	Fri Sep 27 14:51:05 2002
@@ -719,7 +719,6 @@
 	RING_LOCALS;
 	DRM_DEBUG( "\n" );
 
-
 	/* Do some trivial performance monitoring...
 	 */
 	if (dev_priv->do_boxes)
@@ -1088,6 +1087,8 @@
 	case RADEON_TXFORMAT_ARGB1555:
 	case RADEON_TXFORMAT_RGB565:
 	case RADEON_TXFORMAT_ARGB4444:
+	case RADEON_TXFORMAT_VYUY422:
+	case RADEON_TXFORMAT_YVYU422:
 		format = RADEON_COLOR_FORMAT_RGB565;
 		tex_width = tex->width * 2;
 		blit_width = image->width * 2;
@@ -1226,6 +1227,7 @@
 	return ret;
 }
 
+
 static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1306,6 +1308,9 @@
 	return 0;
 }
 
+/* Called whenever a client dies, from DRM(release).
+ * NOTE:  Lock isn't necessarily held when this is called!
+ */
 int radeon_do_cleanup_pageflip( drm_device_t *dev )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1936,14 +1941,18 @@
 		if ( i < cmdbuf->nbox ) {
 			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
 				return DRM_ERR(EFAULT);
-			/* FIXME The second and subsequent times round this loop, send a
-			 * WAIT_UNTIL_3D_IDLE before calling emit_clip_rect(). This
-			 * fixes a lockup on fast machines when sending several
-			 * cliprects with a cmdbuf, as when waving a 2D window over
-			 * a 3D window. Something in the commands from user space
-			 * seems to hang the card when they're sent several times
-			 * in a row. That would be the correct place to fix it but
-			 * this works around it until I can figure that out - Tim Smith */
+			/* FIXME The second and subsequent times round
+			 * this loop, send a WAIT_UNTIL_3D_IDLE before
+			 * calling emit_clip_rect(). This fixes a
+			 * lockup on fast machines when sending
+			 * several cliprects with a cmdbuf, as when
+			 * waving a 2D window over a 3D
+			 * window. Something in the commands from user
+			 * space seems to hang the card when they're
+			 * sent several times in a row. That would be
+			 * the correct place to fix it but this works
+			 * around it until I can figure that out - Tim
+			 * Smith */
 			if ( i ) {
 				BEGIN_RING( 2 );
 				RADEON_WAIT_UNTIL_3D_IDLE();
@@ -1967,6 +1976,34 @@
 }
 
 
+static int radeon_emit_wait( drm_device_t *dev, int flags )
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+
+	DRM_DEBUG("%s: %x\n", __FUNCTION__, flags);
+	switch (flags) {
+	case RADEON_WAIT_2D:
+		BEGIN_RING( 2 );
+		RADEON_WAIT_UNTIL_2D_IDLE(); 
+		ADVANCE_RING();
+		break;
+	case RADEON_WAIT_3D:
+		BEGIN_RING( 2 );
+		RADEON_WAIT_UNTIL_3D_IDLE(); 
+		ADVANCE_RING();
+		break;
+	case RADEON_WAIT_2D|RADEON_WAIT_3D:
+		BEGIN_RING( 2 );
+		RADEON_WAIT_UNTIL_IDLE(); 
+		ADVANCE_RING();
+		break;
+	default:
+		return DRM_ERR(EINVAL);
+	}
+
+	return 0;
+}
 
 int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
 {
@@ -1989,7 +2026,6 @@
 	DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data,
 			     sizeof(cmdbuf) );
 
-	DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 	VB_AGE_TEST_WITH_RETURN( dev_priv );
 
@@ -2080,6 +2116,14 @@
 				return DRM_ERR(EINVAL);
 			}
 			break;
+
+		case RADEON_CMD_WAIT:
+			DRM_DEBUG("RADEON_CMD_WAIT\n");
+			if (radeon_emit_wait( dev, header.wait.flags )) {
+				DRM_ERROR("radeon_emit_wait failed\n");
+				return DRM_ERR(EINVAL);
+			}
+			break;
 		default:
 			DRM_ERROR("bad cmd_type %d at %p\n", 
 				  header.header.cmd_type,
@@ -2127,6 +2171,12 @@
 	case RADEON_PARAM_LAST_CLEAR:
 		dev_priv->stats.last_clear_reads++;
 		value = GET_SCRATCH( 2 );
+		break;
+	case RADEON_PARAM_IRQ_ACTIVE:
+		value = dev->irq ? 1 : 0;
+		break;
+	case RADEON_PARAM_AGP_BASE:
+		value = dev_priv->agp_vm_start;
 		break;
 	default:
 		return DRM_ERR(EINVAL);
diff -Nru a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/char/sysrq.c	Fri Sep 27 14:51:05 2002
@@ -28,7 +28,8 @@
 #include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/suspend.h>
-#include <linux/buffer_head.h>		/* for fsync_bdev()/wakeup_bdflush() */
+#include <linux/writeback.h>
+#include <linux/buffer_head.h>		/* for fsync_bdev() */
 
 #include <linux/spinlock.h>
 
@@ -227,7 +228,7 @@
 			      struct tty_struct *tty) 
 {
 	emergency_sync_scheduled = EMERG_SYNC;
-	wakeup_bdflush();
+	wakeup_bdflush(0);
 }
 static struct sysrq_key_op sysrq_sync_op = {
 	handler:	sysrq_handle_sync,
@@ -239,7 +240,7 @@
 				 struct tty_struct *tty) 
 {
 	emergency_sync_scheduled = EMERG_REMOUNT;
-	wakeup_bdflush();
+	wakeup_bdflush(0);
 }
 static struct sysrq_key_op sysrq_mountro_op = {
 	handler:	sysrq_handle_mountro,
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/char/tty_io.c	Fri Sep 27 14:51:04 2002
@@ -121,6 +121,8 @@
 extern struct tty_driver pts_driver[];	/* Unix98 pty slaves;  for /dev/ptmx */
 #endif
 
+extern void disable_early_printk(void);
+
 /*
  * redirect is the pseudo-tty that console output
  * is redirected to if asked by TIOCCONS.
@@ -2185,6 +2187,9 @@
 	 * set up the console device so that later boot sequences can 
 	 * inform about problems etc..
 	 */
+#ifdef CONFIG_EARLY_PRINTK
+	disable_early_printk();
+#endif
 #ifdef CONFIG_VT
 	con_init();
 #endif
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/i2c/i2c-core.c	Fri Sep 27 14:51:03 2002
@@ -21,7 +21,7 @@
    All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com>                */
 
-/* $Id: i2c-core.c,v 1.83 2002/07/08 01:37:15 mds Exp $ */
+/* $Id: i2c-core.c,v 1.86 2002/09/12 06:47:26 ac9410 Exp $ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -36,10 +36,6 @@
 #include <linux/version.h>
 #include <linux/init.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-#define init_MUTEX(s) do { *(s) = MUTEX; } while(0)
-#endif
-
 #include <asm/uaccess.h>
 
 /* ----- global defines ---------------------------------------------------- */
@@ -72,7 +68,7 @@
 static int driver_count;
 
 /**** debug level */
-static int i2c_debug=1;
+static int i2c_debug;
 
 /* ---------------------------------------------------
  * /proc entry declarations
@@ -84,10 +80,6 @@
 static int i2cproc_init(void);
 static int i2cproc_cleanup(void);
 
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27))
-static void monitor_bus_i2c(struct inode *inode, int fill);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
-
 static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, 
                                 loff_t *ppos);
 static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
@@ -99,12 +91,6 @@
 	read:		i2cproc_bus_read,
 };
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48))
-static struct inode_operations i2cproc_inode_operations = {
-	&i2cproc_operations
-};
-#endif
-
 static int i2cproc_initialized = 0;
 
 #else /* undef CONFIG_PROC_FS */
@@ -164,16 +150,8 @@
 			goto ERROR1;
 		}
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,48))
 		proc_entry->proc_fops = &i2cproc_operations;
-#else
-		proc_entry->ops = &i2cproc_inode_operations;
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
 		proc_entry->owner = THIS_MODULE;
-#else
-		proc_entry->fill_inode = &monitor_bus_i2c;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
 		adap->inode = proc_entry->low_ino;
 	}
 
@@ -611,18 +589,6 @@
 
 #ifdef CONFIG_PROC_FS
 
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27))
-/* Monitor access to /proc/bus/i2c*; make unloading i2c-proc impossible
-   if some process still uses it or some file in it */
-void monitor_bus_i2c(struct inode *inode, int fill)
-{
-	if (fill)
-		MOD_INC_USE_COUNT;
-	else
-		MOD_DEC_USE_COUNT;
-}
-#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,37)) */
-
 /* This function generates the output for /proc/bus/i2c */
 int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof, 
                  void *private)
@@ -658,18 +624,19 @@
 	struct i2c_client *client;
 	int i,j,k,order_nr,len=0,len_total;
 	int order[I2C_CLIENT_MAX];
+#define OUTPUT_LENGTH_PER_LINE 70
 
-	if (count > 4096)
-		return -EINVAL; 
 	len_total = file->f_pos + count;
-	/* Too bad if this gets longer (unlikely) */
-	if (len_total > 4096)
-		len_total = 4096;
+	if (len_total > (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE) )
+		/* adjust to maximum file size */
+		len_total = (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE);
 	for (i = 0; i < I2C_ADAP_MAX; i++)
 		if (adapters[i]->inode == inode->i_ino) {
 		/* We need a bit of slack in the kernel buffer; this makes the
 		   sprintf safe. */
-			if (! (kbuf = kmalloc(count + 80,GFP_KERNEL)))
+			if (! (kbuf = kmalloc(len_total +
+			                      OUTPUT_LENGTH_PER_LINE,
+			                      GFP_KERNEL)))
 				return -ENOMEM;
 			/* Order will hold the indexes of the clients
 			   sorted by address */
@@ -731,11 +698,7 @@
 		return -ENOENT;
  	}
 	proc_bus_i2c->read_proc = &read_bus_i2c;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
 	proc_bus_i2c->owner = THIS_MODULE;
-#else
-	proc_bus_i2c->fill_inode = &monitor_bus_i2c;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */
 	i2cproc_initialized += 2;
 	return 0;
 }
@@ -1492,6 +1455,11 @@
 	return 0;
 }
 
+static void __exit i2c_exit(void)
+{
+	i2cproc_cleanup();
+}
+
 #ifndef MODULE
 #ifdef CONFIG_I2C_CHARDEV
 	extern int i2c_dev_init(void);
@@ -1622,20 +1590,11 @@
 EXPORT_SYMBOL(i2c_get_functionality);
 EXPORT_SYMBOL(i2c_check_functionality);
 
-#ifdef MODULE
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
 MODULE_PARM(i2c_debug, "i");
 MODULE_PARM_DESC(i2c_debug,"debug level");
 MODULE_LICENSE("GPL");
 
-int init_module(void) 
-{
-	return i2c_init();
-}
-
-void cleanup_module(void) 
-{
-	i2cproc_cleanup();
-}
-#endif
+module_init(i2c_init);
+module_exit(i2c_exit);
diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/i2c/i2c-dev.c	Fri Sep 27 14:51:05 2002
@@ -36,9 +36,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/version.h>
-#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
 #include <linux/smp_lock.h>
-#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
 #ifdef CONFIG_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
 #endif
@@ -52,16 +50,8 @@
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* def MODULE */
-
 /* struct file_operations changed too often in the 2.1 series for nice code */
 
-#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
-static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin);
-#endif
 static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, 
                             loff_t *offset);
 static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, 
@@ -78,23 +68,9 @@
 static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
                            void *arg);
 
-#ifdef MODULE
-static
-#else
-extern
-#endif
-       int __init i2c_dev_init(void);
-static int i2cdev_cleanup(void);
-
 static struct file_operations i2cdev_fops = {
-#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
 	owner:		THIS_MODULE,
-#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
-#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
-	llseek:		i2cdev_lseek,
-#else
 	llseek:		no_llseek,
-#endif
 	read:		i2cdev_read,
 	write:		i2cdev_write,
 	ioctl:		i2cdev_ioctl,
@@ -132,20 +108,6 @@
 
 static int i2cdev_initialized;
 
-#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
-/* Note that the lseek function is called llseek in 2.1 kernels. But things
-   are complicated enough as is. */
-loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin)
-{
-#ifdef DEBUG
-	struct inode *inode = file->f_dentry->d_inode;
-	printk(KERN_DEBUG "i2c-dev.o: i2c-%d lseek to %ld bytes relative to %d.\n",
-	       minor(inode->i_rdev),(long) offset,origin);
-#endif /* DEBUG */
-	return -ESPIPE;
-}
-#endif
-
 static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
                             loff_t *offset)
 {
@@ -411,9 +373,6 @@
 
 	if (i2cdev_adaps[minor]->inc_use)
 		i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]);
-#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0)
-	MOD_INC_USE_COUNT;
-#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */
 
 #ifdef DEBUG
 	printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor);
@@ -429,16 +388,10 @@
 #ifdef DEBUG
 	printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor);
 #endif
-#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0)
-	MOD_DEC_USE_COUNT;
-#else /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
 	lock_kernel();
-#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */
 	if (i2cdev_adaps[minor]->dec_use)
 		i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]);
-#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
 	unlock_kernel();
-#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
 	return 0;
 }
 
@@ -491,6 +444,30 @@
 	return -1;
 }
 
+static void i2cdev_cleanup(void)
+{
+	int res;
+
+	if (i2cdev_initialized >= 2) {
+		if ((res = i2c_del_driver(&i2cdev_driver))) {
+			printk(KERN_ERR "i2c-dev.o: Driver deregistration failed, "
+			       "module not removed.\n");
+		}
+	i2cdev_initialized --;
+	}
+
+	if (i2cdev_initialized >= 1) {
+#ifdef CONFIG_DEVFS_FS
+		devfs_unregister(devfs_handle);
+#endif
+		if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) {
+			printk(KERN_ERR "i2c-dev.o: unable to release major %d for i2c bus\n",
+			       I2C_MAJOR);
+		}
+		i2cdev_initialized --;
+	}
+}
+
 int __init i2c_dev_init(void)
 {
 	int res;
@@ -517,50 +494,11 @@
 	return 0;
 }
 
-int i2cdev_cleanup(void)
-{
-	int res;
-
-	if (i2cdev_initialized >= 2) {
-		if ((res = i2c_del_driver(&i2cdev_driver))) {
-			printk(KERN_ERR "i2c-dev.o: Driver deregistration failed, "
-			       "module not removed.\n");
-			return res;
-		}
-	i2cdev_initialized --;
-	}
-
-	if (i2cdev_initialized >= 1) {
-#ifdef CONFIG_DEVFS_FS
-		devfs_unregister(devfs_handle);
-#endif
-		if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) {
-			printk(KERN_ERR "i2c-dev.o: unable to release major %d for i2c bus\n",
-			       I2C_MAJOR);
-			return res;
-		}
-		i2cdev_initialized --;
-	}
-	return 0;
-}
-
 EXPORT_NO_SYMBOLS;
 
-#ifdef MODULE
-
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C /dev entries driver");
 MODULE_LICENSE("GPL");
 
-int init_module(void)
-{
-	return i2c_dev_init();
-}
-
-int cleanup_module(void)
-{
-	return i2cdev_cleanup();
-}
-
-#endif /* def MODULE */
-
+module_init(i2c_dev_init);
+module_exit(i2cdev_cleanup);
diff -Nru a/drivers/i2c/i2c-proc.c b/drivers/i2c/i2c-proc.c
--- a/drivers/i2c/i2c-proc.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/i2c/i2c-proc.c	Fri Sep 27 14:51:04 2002
@@ -54,8 +54,6 @@
 				void *newval, size_t newlen,
 				void **context);
 
-int __init sensors_init(void);
-
 #define SENSORS_ENTRY_MAX 20
 static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
 
@@ -815,35 +813,23 @@
 	return 0;
 }
 
+static void __exit i2c_cleanup(void)
+{
+	if (i2c_initialized >= 1) {
+		unregister_sysctl_table(i2c_proc_header);
+		i2c_initialized--;
+	}
+}
+
 EXPORT_SYMBOL(i2c_deregister_entry);
 EXPORT_SYMBOL(i2c_detect);
 EXPORT_SYMBOL(i2c_proc_real);
 EXPORT_SYMBOL(i2c_register_entry);
 EXPORT_SYMBOL(i2c_sysctl_real);
 
-#ifdef MODULE
-
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
 MODULE_DESCRIPTION("i2c-proc driver");
 MODULE_LICENSE("GPL");
 
-int i2c_cleanup(void)
-{
-	if (i2c_initialized >= 1) {
-		unregister_sysctl_table(i2c_proc_header);
-		i2c_initialized--;
-	}
-	return 0;
-}
-
-int init_module(void)
-{
-	return sensors_init();
-}
-
-int cleanup_module(void)
-{
-	return i2c_cleanup();
-}
-
-#endif				/* MODULE */
+module_init(sensors_init);
+module_exit(i2c_cleanup);
diff -Nru a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
--- a/drivers/ide/ide-lib.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/ide/ide-lib.c	Fri Sep 27 14:51:05 2002
@@ -394,7 +394,7 @@
 	if (on && drive->media == ide_disk) {
 		if (!PCI_DMA_BUS_IS_PHYS)
 			addr = BLK_BOUNCE_ANY;
-		else
+		else if (HWIF(drive)->pci_dev)
 			addr = HWIF(drive)->pci_dev->dma_mask;
 	}
 
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/ide/ide.c	Fri Sep 27 14:51:03 2002
@@ -980,7 +980,7 @@
 	best = NULL;
 	drive = hwgroup->drive;
 	do {
-		if (!list_empty(&drive->queue.queue_head) && (!drive->sleep || time_after_eq(jiffies, drive->sleep))) {
+		if (!blk_queue_empty(&drive->queue) && (!drive->sleep || time_after_eq(jiffies, drive->sleep))) {
 			if (!best
 			 || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
 			 || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
@@ -1863,7 +1863,6 @@
 	unregister_blkdev(hwif->major, hwif->name);
 	blk_dev[hwif->major].data = NULL;
 	blk_dev[hwif->major].queue = NULL;
-	blk_clear(hwif->major);
 	gd = hwif->drives[0].disk;
 	if (gd) {
 		int i;
diff -Nru a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c
--- a/drivers/ide/legacy/pdc4030.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/ide/legacy/pdc4030.c	Fri Sep 27 14:51:04 2002
@@ -462,7 +462,7 @@
 	rq->nr_sectors -= nsect;
 	total_remaining = rq->nr_sectors;
 	if ((rq->current_nr_sectors -= nsect) <= 0) {
-		DRIVER(drive)->end_request(drive, 1);
+		DRIVER(drive)->end_request(drive, 1, 0);
 	}
 /*
  * Now the data has been read in, do the following:
@@ -539,7 +539,7 @@
 #endif /* DEBUG_WRITE */
 	for (i = rq->nr_sectors; i > 0; ) {
 		i -= rq->current_nr_sectors;
-		DRIVER(drive)->end_request(drive, 1);
+		DRIVER(drive)->end_request(drive, 1, 0);
 	}
 	return ide_stopped;
 }
@@ -584,16 +584,24 @@
 
 		/* Do we move to the next bh after this? */
 		if (!rq->current_nr_sectors) {
-			struct buffer_head *bh = rq->bh->b_reqnext;
+			struct bio *bio = rq->bio;
+
+			/*
+			 * only move to next bio, when we have processed
+			 * all bvecs in this one.
+			 */
+			if (++bio->bi_idx >= bio->bi_vcnt) {
+				bio->bi_idx = 0;
+				bio = bio->bi_next;
+			}
 
 			/* end early early we ran out of requests */
-			if (!bh) {
+			if (!bio) {
 				mcount = 0;
 			} else {
-				rq->bh			= bh;
-				rq->current_nr_sectors	= bh->b_size >> 9;
+				rq->bio = bio;
+				rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
 				rq->hard_cur_sectors = rq->current_nr_sectors;
-				rq->buffer		= bh->b_data;
 			}
 		}
 
@@ -720,6 +728,12 @@
 	unsigned long timeout;
 	u8 stat = 0;
 
+	if (!blk_fs_request(rq)) {
+		blk_dump_rq_flags(rq, "do_pdc4030_io - bad command");
+		DRIVER(drive)->end_request(drive, 0, 0);
+		return ide_stopped;
+	}
+
 #ifdef CONFIG_IDE_TASKFILE_IO
 	if (IDE_CONTROL_REG)
 		HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
@@ -735,8 +749,7 @@
 	HWIF(drive)->OUTB(taskfile->command, IDE_COMMAND_REG);
 #endif /* CONFIG_IDE_TASKFILE_IO */
 
-	switch(rq->cmd) {
-	case READ:
+	if (rq_data_dir(rq) == READ) {
 #ifndef CONFIG_IDE_TASKFILE_IO
 		HWIF(drive)->OUTB(PROMISE_READ, IDE_COMMAND_REG);
 #endif /* CONFIG_IDE_TASKFILE_IO */
@@ -774,7 +787,7 @@
 		printk(KERN_ERR "%s: reading: No DRQ and not "
 				"waiting - Odd!\n", drive->name);
 		return ide_stopped;
-	case WRITE:
+	} else {
 #ifndef CONFIG_IDE_TASKFILE_IO
 		HWIF(drive)->OUTB(PROMISE_WRITE, IDE_COMMAND_REG);
 #endif /* CONFIG_IDE_TASKFILE_IO */
@@ -788,11 +801,6 @@
 			local_irq_disable();
 		HWGROUP(drive)->wrq = *rq; /* scratchpad */
 		return promise_write(drive);
-	default:
-		printk("KERN_WARNING %s: bad command: %d\n",
-			drive->name, rq->cmd);
-		DRIVER(drive)->end_request(drive, 0);
-		return ide_stopped;
 	}
 }
 
diff -Nru a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
--- a/drivers/ide/pci/cy82c693.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/ide/pci/cy82c693.c	Fri Sep 27 14:51:03 2002
@@ -338,6 +338,9 @@
  */
 unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name)
 {
+	if (PCI_FUNC(dev->devfn) != 1)
+		return 0;
+
 #ifdef CY82C693_SETDMA_CLOCK
 	u8 data = 0;
 #endif /* CY82C693_SETDMA_CLOCK */ 
@@ -411,20 +414,30 @@
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
 
-void __init init_dma_cy82c693 (ide_hwif_t *hwif, unsigned long dmabase)
+static __initdata ide_hwif_t *primary;
+
+void __init init_iops_cy82c693(ide_hwif_t *hwif)
 {
-	ide_setup_dma(hwif, dmabase, 8);
+	if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
+		primary = hwif;
+	else {
+		hwif->mate = primary;
+		hwif->channel = 1;
+	}
 }
 
-extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
-
 static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
-        if ((!(PCI_FUNC(dev->devfn) & 1) ||
-	    (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))))
-		return 0;	/* CY82C693 is more than only a IDE controller */
-	ide_setup_pci_device(dev, d);
+	struct pci_dev *dev2;
+
+	/* CY82C693 is more than only a IDE controller.
+	   Function 1 is primary IDE channel, function 2 - secondary. */
+        if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
+	    PCI_FUNC(dev->devfn) == 1) {
+		dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
+		ide_setup_pci_devices(dev, dev2, d);
+	}
 	return 0;
 }
 
diff -Nru a/drivers/ide/pci/cy82c693.h b/drivers/ide/pci/cy82c693.h
--- a/drivers/ide/pci/cy82c693.h	Fri Sep 27 14:51:03 2002
+++ b/drivers/ide/pci/cy82c693.h	Fri Sep 27 14:51:03 2002
@@ -66,7 +66,7 @@
 
 extern unsigned int init_chipset_cy82c693(struct pci_dev *, const char *);
 extern void init_hwif_cy82c693(ide_hwif_t *);
-extern void init_dma_cy82c693(ide_hwif_t *, unsigned long);
+extern void init_iops_cy82c693(ide_hwif_t *);
 
 static ide_pci_device_t cy82c693_chipsets[] __initdata = {
 	{	/* 0 */
@@ -74,10 +74,10 @@
 		device:		PCI_DEVICE_ID_CONTAQ_82C693,
 		name:		"CY82C693",
 		init_chipset:	init_chipset_cy82c693,
-		init_iops:	NULL,
+		init_iops:	init_iops_cy82c693,
 		init_hwif:	init_hwif_cy82c693,
-		init_dma:	init_dma_cy82c693,
-		channels:	2,
+		init_dma:	NULL,
+		channels:	1,
 		autodma:	AUTODMA,
 		enablebits:	{{0x00,0x00,0x00}, {0x00,0x00,0x00}},
 		bootable:	ON_BOARD,
diff -Nru a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
--- a/drivers/ide/pci/sl82c105.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/ide/pci/sl82c105.c	Fri Sep 27 14:51:04 2002
@@ -11,7 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linuyx/module.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
diff -Nru a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
--- a/drivers/ide/pci/trm290.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/ide/pci/trm290.c	Fri Sep 27 14:51:03 2002
@@ -192,7 +192,7 @@
 	trm290_prepare_drive(drive, 0);	/* select PIO xfer */
 	return 1;
 #endif
-	if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_TODEVICE))) {
+	if (!(count = ide_build_dmatable(drive, rq))) {
 		/* try PIO instead of DMA */
 		trm290_prepare_drive(drive, 0); /* select PIO xfer */
 		return 1;
@@ -236,7 +236,7 @@
 	task_ioreg_t command	= WIN_NOP;
 	unsigned int count, reading = 2, writing = 0;
 
-	if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_FROMDEVICE))) {
+	if (!(count = ide_build_dmatable(drive, rq))) {
 		/* try PIO instead of DMA */
 		trm290_prepare_drive(drive, 0); /* select PIO xfer */
 		return 1;
diff -Nru a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
--- a/drivers/ide/setup-pci.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/ide/setup-pci.c	Fri Sep 27 14:51:04 2002
@@ -250,6 +250,7 @@
 
 		switch(dev->device) {
 			case PCI_DEVICE_ID_AL_M5219:
+			case PCI_DEVICE_ID_AL_M5229:
 			case PCI_DEVICE_ID_AMD_VIPER_7409:
 			case PCI_DEVICE_ID_CMD_643:
 			case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
@@ -421,20 +422,17 @@
 {
 	unsigned long ctl = 0, base = 0;
 	ide_hwif_t *hwif;
-	
-	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
-	{
-	    	/*  Possibly we should fail if these checks report true */
-	    	ide_pci_check_iomem(dev, d, 2*port);
-	    	ide_pci_check_iomem(dev, d, 2*port+1);
-	 
-		ctl  = pci_resource_start(dev, 2*port+1);
-		base = pci_resource_start(dev, 2*port);
-		if ((ctl && !base) || (base && !ctl)) {
-			printk(KERN_ERR "%s: inconsistent baseregs (BIOS) "
-				"for port %d, skipping\n", d->name, port);
-			return NULL;
-		}
+
+	/*  Possibly we should fail if these checks report true */
+	ide_pci_check_iomem(dev, d, 2*port);
+	ide_pci_check_iomem(dev, d, 2*port+1);
+ 
+	ctl  = pci_resource_start(dev, 2*port+1);
+	base = pci_resource_start(dev, 2*port);
+	if ((ctl && !base) || (base && !ctl)) {
+		printk(KERN_ERR "%s: inconsistent baseregs (BIOS) "
+			"for port %d, skipping\n", d->name, port);
+		return NULL;
 	}
 	if (!ctl)
 	{
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/input/mousedev.c	Fri Sep 27 14:51:04 2002
@@ -380,18 +380,21 @@
 	if (!list->ready && !list->buffer) {
 
 		add_wait_queue(&list->mousedev->wait, &wait);
-		set_current_state(TASK_INTERRUPTIBLE);
 
-		while (!list->ready) {
+		for (;;) {
+			set_current_state(TASK_INTERRUPTIBLE);
 
-			if (file->f_flags & O_NONBLOCK) {
-				retval = -EAGAIN;
+			retval = 0;
+			if (list->ready || list->buffer)
 				break;
-			}
-			if (signal_pending(current)) {
-				retval = -ERESTARTSYS;
+
+			retval = -EAGAIN;
+			if (file->f_flags & O_NONBLOCK)
+				break;
+
+			retval = -ERESTARTSYS;
+			if (signal_pending(current))
 				break;
-			}
 
 			schedule();
 		}
diff -Nru a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
--- a/drivers/isdn/i4l/isdn_common.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/isdn/i4l/isdn_common.c	Fri Sep 27 14:51:04 2002
@@ -264,8 +264,6 @@
 	if (tf & ISDN_TIMER_SLOW) {
 		if (++isdn_timer_cnt2 >= ISDN_TIMER_1SEC) {
 			isdn_timer_cnt2 = 0;
-			if (tf & ISDN_TIMER_NETHANGUP)
-				isdn_net_autohup();
 			if (++isdn_timer_cnt3 >= ISDN_TIMER_RINGING) {
 				isdn_timer_cnt3 = 0;
 				if (tf & ISDN_TIMER_MODEMRING)
@@ -451,8 +449,6 @@
 		case ISDN_STAT_BSENT:
 			if (i < 0)
 				return -1;
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
 			if (isdn_net_stat_callback(i, c))
 				return 0;
 			if (isdn_v110_stat_callback(&slot[i].iv110, c))
@@ -482,15 +478,11 @@
 			if (i < 0)
 				return -1;
 			dbg_statcallb("ICALL: %d (%d,%ld) %s\n", i, di, c->arg, c->parm.num);
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED) {
-				cmd.driver = di;
-				cmd.arg = c->arg;
-				cmd.command = ISDN_CMD_HANGUP;
-				isdn_command(&cmd);
+			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
 				return 0;
-			}
+
 			/* Try to find a network-interface which will accept incoming call */
-			r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, &c->parm.setup));
+			r = isdn_net_find_icall(di, c->arg, i, &c->parm.setup);
 			switch (r) {
 				case 0:
 					/* No network-device replies.
@@ -550,8 +542,6 @@
 			if (i < 0)
 				return -1;
 			dbg_statcallb("CINF: %d %s\n", i, c->parm.num);
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
 			if (strcmp(c->parm.num, "0"))
 				isdn_net_stat_callback(i, c);
 			isdn_tty_stat_callback(i, c);
@@ -574,8 +564,6 @@
 			if (i < 0)
 				return -1;
 			dbg_statcallb("DCONN: %d\n", i);
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
 			/* Find any net-device, waiting for D-channel setup */
 			if (isdn_net_stat_callback(i, c))
 				break;
@@ -593,8 +581,6 @@
 			if (i < 0)
 				return -1;
 			dbg_statcallb("DHUP: %d\n", i);
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
 			dev->drv[di]->online &= ~(1 << (c->arg));
 			isdn_info_update();
 			/* Signal hangup to network-devices */
@@ -611,8 +597,6 @@
 				return -1;
 			dbg_statcallb("BCONN: %ld\n", c->arg);
 			/* Signal B-channel-connect to network-devices */
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
 			dev->drv[di]->online |= (1 << (c->arg));
 			isdn_info_update();
 			if (isdn_net_stat_callback(i, c))
@@ -625,8 +609,6 @@
 			if (i < 0)
 				return -1;
 			dbg_statcallb("BHUP: %d\n", i);
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
 			dev->drv[di]->online &= ~(1 << (c->arg));
 			isdn_info_update();
 #ifdef CONFIG_ISDN_X25
@@ -642,8 +624,6 @@
 			if (i < 0)
 				return -1;
 			dbg_statcallb("NODCH: %ld\n", c->arg);
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
 			if (isdn_net_stat_callback(i, c))
 				break;
 			if (isdn_tty_stat_callback(i, c))
@@ -1397,12 +1377,12 @@
 		printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
 		return 0;
 	case IIOCSETGST:
-		if (arg)
+		if (arg) {
 			dev->global_flags |= ISDN_GLOBAL_STOPPED;
-		else
+			isdn_net_hangup_all();
+		} else {
 			dev->global_flags &= ~ISDN_GLOBAL_STOPPED;
-		printk(KERN_INFO "isdn: Global Mode %s\n",
-		       (dev->global_flags & ISDN_GLOBAL_STOPPED) ? "stopped" : "running");
+		}
 		return 0;
 	case IIOCSETBRJ:
 		drvidx = -1;
@@ -1619,8 +1599,9 @@
 	.release	= isdn_ctrl_release,
 };
 
+
 /*
- * file_operations for major 43, /dev/isdn*
+ * file_operations for major 45, /dev/isdn*
  * stolen from drivers/char/misc.c
  */
 
@@ -2119,14 +2100,20 @@
 int
 isdn_slot_command(int sl, int cmd, isdn_ctrl *ctrl)
 {
+
 	ctrl->command = cmd;
 	ctrl->driver = isdn_slot_driver(sl);
+
 	switch (cmd) {
 	case ISDN_CMD_SETL2:
 	case ISDN_CMD_SETL3:
 	case ISDN_CMD_PROT_IO:
 		ctrl->arg &= ~0xff; ctrl->arg |= isdn_slot_channel(sl);
 		break;
+	case ISDN_CMD_DIAL:
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return -EBUSY;
+		/* fall through */
 	default:
 		ctrl->arg = isdn_slot_channel(sl);
 		break;
diff -Nru a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
--- a/drivers/isdn/i4l/isdn_net.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/isdn/i4l/isdn_net.c	Fri Sep 27 14:51:05 2002
@@ -206,7 +206,7 @@
 
 int isdn_net_force_dial_lp(isdn_net_local *);
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
-static int do_dialout(isdn_net_local *lp);
+static void do_dialout(isdn_net_local *lp);
 
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
@@ -222,22 +222,14 @@
 static void
 isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason)
 {
-	if(skb) {
-
-		u_short proto = ntohs(skb->protocol);
-
-		printk(KERN_DEBUG "isdn_net: %s: %s, signalling dst_link_failure %s\n",
-		       dev->name,
-		       (reason != NULL) ? reason : "unknown",
-		       (proto != ETH_P_IP) ? "Protocol != ETH_P_IP" : "");
-		
-		dst_link_failure(skb);
-	}
-	else {  /* dial not triggered by rawIP packet */
-		printk(KERN_DEBUG "isdn_net: %s: %s\n",
-			   dev->name,
-			   (reason != NULL) ? reason : "reason unknown");
-	}
+	u_short proto = ntohs(skb->protocol);
+	
+	printk(KERN_DEBUG "isdn_net: %s: %s, signalling dst_link_failure %s\n",
+	       dev->name,
+	       (reason != NULL) ? reason : "unknown",
+	       (proto != ETH_P_IP) ? "Protocol != ETH_P_IP" : "");
+	
+	dst_link_failure(skb);
 }
 
 static void
@@ -348,7 +340,7 @@
 }
 
 /*
- * Perform auto-hangup and cps-calculation for net-interfaces.
+ * Perform auto-hangup for net-interfaces.
  *
  * auto-hangup:
  * Increment idle-counter (this counter is reset on any incoming or
@@ -357,65 +349,53 @@
  * charge-info.
  */
 
-void
-isdn_net_autohup()
+static void isdn_net_hup_timer(unsigned long data)
 {
-	struct list_head *l;
-	int anymore;
-
-	anymore = 0;
-	list_for_each(l, &isdn_net_devs) {
-		isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
-		isdn_net_local *l = &p->local;
-
-		if (!(l->flags & ISDN_NET_CONNECTED) || l->dialstate != ST_ACTIVE)
-			continue;
+	isdn_net_local *lp = (isdn_net_local *) data;
 
-		if(dev->global_flags & ISDN_GLOBAL_STOPPED || 
-		   ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF) {
-			isdn_net_hangup(&p->dev);
-			continue;
-		}
-		dbg_net_dial("%s: huptimer %d, onhtime %d, chargetime %ld, chargeint %d\n",
-			     l->name, l->huptimer, l->onhtime, l->chargetime, l->chargeint);
+	if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate != ST_ACTIVE) {
+		isdn_BUG();
+		return;
+	}
+	
+	dbg_net_dial("%s: huptimer %d, onhtime %d, chargetime %ld, chargeint %d\n",
+		     l->name, l->huptimer, l->onhtime, l->chargetime, l->chargeint);
 
-		if (!(l->onhtime))
-			continue;
+	if (!(lp->onhtime))
+		return;
+	
+	if (lp->huptimer++ <= lp->onhtime)
+		goto mod_timer;
 
-		if (l->huptimer++ <= l->onhtime) {
-			anymore = 1;
-			continue;
-		}
-		if (l->hupflags & ISDN_MANCHARGE && l->hupflags & ISDN_CHARGEHUP) {
-			while (time_after(jiffies, l->chargetime + l->chargeint))
-				l->chargetime += l->chargeint;
-
-			if (time_after(jiffies, l->chargetime + l->chargeint - 2 * HZ)) {
-				if (l->outgoing || l->hupflags & ISDN_INHUP) {
-					isdn_net_hangup(&p->dev);
-					continue;
-				}
-			}
-		} else if (l->outgoing) {
-			if (l->hupflags & ISDN_CHARGEHUP) {
-				if (l->charge_state != ST_CHARGE_HAVE_CINT) {
-					dbg_net_dial("%s: did not get CINT\n", l->name);
-					isdn_net_hangup(&p->dev);
-					continue;
-				} else if (time_after(jiffies, l->chargetime + l->chargeint)) {
-					dbg_net_dial("%s: chtime = %lu, chint = %d\n",
-						     l->name, l->chargetime, l->chargeint);
-					isdn_net_hangup(&p->dev);
-					continue;
-				}
+	if (lp->hupflags & ISDN_MANCHARGE && lp->hupflags & ISDN_CHARGEHUP) {
+		while (time_after(jiffies, lp->chargetime + lp->chargeint))
+			lp->chargetime += lp->chargeint;
+		
+		if (time_after(jiffies, lp->chargetime + lp->chargeint - 2 * HZ)) {
+			if (lp->outgoing || lp->hupflags & ISDN_INHUP) {
+				isdn_net_hangup(lp);
+				return;
+			}
+		}
+	} else if (lp->outgoing) {
+		if (lp->hupflags & ISDN_CHARGEHUP) {
+			if (lp->charge_state != ST_CHARGE_HAVE_CINT) {
+				dbg_net_dial("%s: did not get CINT\n", lp->name);
+				isdn_net_hangup(lp);
+				return;
+			} else if (time_after(jiffies, lp->chargetime + lp->chargeint)) {
+				dbg_net_dial("%s: chtime = %lu, chint = %d\n",
+					     lp->name, lp->chargetime, lp->chargeint);
+				isdn_net_hangup(lp);
+				return;
 			}
-		} else if (l->hupflags & ISDN_INHUP) {
-			isdn_net_hangup(&p->dev);
-			continue;
 		}
-		anymore = 1;
+	} else if (lp->hupflags & ISDN_INHUP) {
+		isdn_net_hangup(lp);
+		return;
 	}
-	isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, anymore);
+ mod_timer:
+	mod_timer(&lp->hup_timer, lp->hup_timer.expires + HZ);
 }
 
 static void isdn_net_lp_disconnected(isdn_net_local *lp)
@@ -430,7 +410,9 @@
 	struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
 #endif
 	lp->dialstate = ST_ACTIVE;
-	isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
+	lp->hup_timer.expires = jiffies + HZ;
+	add_timer(&lp->hup_timer);
+
 	if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
 		isdn_net_ciscohdlck_connected(lp);
 	if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
@@ -495,33 +477,17 @@
 {
 	isdn_net_local *lp = (isdn_net_local *) data;
 
-	if (!lp) {
-		isdn_BUG();
-		return;
-	}
-	printk("%s: %s %#x\n", __FUNCTION__ , lp->name, lp->dial_event);
 	isdn_net_handle_event(lp, lp->dial_event, NULL);
 }
 
 /* Initiate dialout. Set phone-number-pointer to first number
  * of interface.
  */
-static int
+static void
 init_dialout(isdn_net_local *lp)
 {
-	unsigned long flags;
+	lp->dial = 0;
 
-	save_flags(flags);
-	cli();
-	lp->dial = lp->phone[1];
-	restore_flags(flags);
-
-	if (!lp->dial) {
-		printk(KERN_WARNING "%s: phone number deleted?\n",
-		       lp->name);
-		isdn_net_hangup(&lp->netdev->dev);
-		return 0;
-	}
 	if (lp->dialtimeout > 0 &&
 	    (lp->dialstarted == 0 || 
 	     time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))) {
@@ -529,83 +495,70 @@
 		lp->dialwait_timer = 0;
 	}
 	lp->dialretry = 0;
-	return do_dialout(lp);
+	do_dialout(lp);
 }
 
 /* Setup interface, dial current phone-number, switch to next number.
  * If list of phone-numbers is exhausted, increment
  * retry-counter.
  */
-static int
+static void
 do_dialout(isdn_net_local *lp)
 {
+	int i;
 	unsigned long flags;
+	struct isdn_net_phone *phone;
+	struct dial_info dial = {
+		.l2_proto = lp->l2_proto,
+		.l3_proto = lp->l3_proto,
+		.si1      = 7,
+		.si2      = 0,
+		.msn      = lp->msn,
+	};
 
-	if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
-		char *s;
-		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-			s = "dial suppressed: isdn system stopped";
-		else
-			s = "dial suppressed: dialmode `off'";
-		isdn_net_unreachable(&lp->netdev->dev, 0, s);
-		isdn_net_hangup(&lp->netdev->dev);
-		return 0;
-	}
-
-	save_flags(flags);
-	cli();
-	if (!lp->dial) {
-		restore_flags(flags);
-		printk(KERN_WARNING "%s: phone number deleted?\n",
-		       lp->name);
-		isdn_net_hangup(&lp->netdev->dev);
-		return 0;
+	if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)
+		return;
+	
+	spin_lock_irqsave(&lp->lock, flags);
+	if (list_empty(&lp->phone[1])) {
+		spin_unlock_irqrestore(&lp->lock, flags);
+		return;
 	}
-	if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
-		restore_flags(flags);
-		lp->dialstate = ST_OUT_WAIT_DCONN;
-		printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
-		return 1;
-	} else {
-		struct dial_info dial = {
-			.l2_proto = lp->l2_proto,
-			.l3_proto = lp->l3_proto,
-			.si1      = 7,
-			.si2      = 0,
-			.msn      = lp->msn,
-			.phone    = lp->dial->num,
-		};
-		if(lp->dialtimeout > 0) {
-			if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
-				restore_flags(flags);
-				lp->dialwait_timer = jiffies + lp->dialwait;
-				lp->dialstarted = 0;
-				isdn_net_unreachable(&lp->netdev->dev, 0, "dial: timed out");
-				isdn_net_hangup(&lp->netdev->dev);
-				return 0;
-			}
-		}
-		/*
-		 * Switch to next number or back to start if at end of list.
-		 */
-		if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
-			lp->dial = lp->phone[1];
-			lp->dialretry++;
-			
-			if (lp->dialretry > lp->dialmax) {
-				restore_flags(flags);
-				if (lp->dialtimeout == 0) {
-					lp->dialwait_timer = jiffies + lp->dialwait;
-					lp->dialstarted = 0;
-					isdn_net_unreachable(&lp->netdev->dev, 0, "dial: tried all numbers dialmax times");
-				}
-				isdn_net_hangup(&lp->netdev->dev);
-				return 0;
-			}
+	i = 0;
+	list_for_each_entry(phone, &lp->phone[1], list) {
+		if (i++ == lp->dial)
+			goto found;
+	}
+	/* otherwise start in front */
+	phone = list_entry(lp->phone[1].next, struct isdn_net_phone, list);
+	lp->dial = 0;
+	lp->dialretry++;
+	
+ found:
+	lp->dial++;
+	dial.phone = phone->num;
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	if (lp->dialretry > lp->dialmax) {
+		if (lp->dialtimeout == 0) {
+			lp->dialwait_timer = jiffies + lp->dialwait;
+			lp->dialstarted = 0;
 		}
-		restore_flags(flags);
-		isdn_slot_dial(lp->isdn_slot, &dial);
+		isdn_net_hangup(lp);
+		return;
+	}
+	if(lp->dialtimeout > 0 &&
+	   time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
+		lp->dialwait_timer = jiffies + lp->dialwait;
+		lp->dialstarted = 0;
+		isdn_net_hangup(lp);
+		return;
 	}
+	/*
+	 * Switch to next number or back to start if at end of list.
+	 */
+	isdn_slot_dial(lp->isdn_slot, &dial);
+
 	lp->huptimer = 0;
 	lp->outgoing = 1;
 	if (lp->chargeint)
@@ -622,7 +575,6 @@
 	}
 	lp->dialstate = ST_OUT_WAIT_DCONN;
 	add_timer(&lp->dial_timer);
-	return 1;
 }
 
 /* For EV_NET_DIAL, returns 1 if timer callback is needed 
@@ -725,7 +677,7 @@
 			/* Remote does callback. Hangup after cbdelay, 
 			 * then wait for incoming call */
 			printk(KERN_INFO "%s: hangup waiting for callback ...\n", lp->name);
-			isdn_net_hangup(&lp->netdev->dev);
+			isdn_net_hangup(lp);
 			return 1;
 		case ISDN_STAT_DCONN:
 			/* Got D-Channel-Connect, send B-Channel-request */
@@ -766,7 +718,7 @@
 	case ST_IN_WAIT_DCONN:
 		switch (pr) {
 		case EV_NET_TIMER_IN_DCONN:
-			isdn_net_hangup(&p->dev);
+			isdn_net_hangup(lp);
 			return 1;
 		case ISDN_STAT_DCONN:
 			del_timer(&lp->dial_timer);
@@ -787,7 +739,7 @@
 	case ST_IN_WAIT_BCONN:
 		switch (pr) {
 		case EV_NET_TIMER_IN_BCONN:
-			isdn_net_hangup(&p->dev);
+			isdn_net_hangup(lp);
 			break;
 		case ISDN_STAT_BCONN:
 			del_timer(&lp->dial_timer);
@@ -822,15 +774,15 @@
  * Perform hangup for a net-interface.
  */
 void
-isdn_net_hangup(struct net_device *d)
+isdn_net_hangup(isdn_net_local *lp)
 {
-	isdn_net_local *lp = (isdn_net_local *) d->priv;
 	isdn_ctrl cmd;
 #ifdef CONFIG_ISDN_X25
 	struct concap_proto *cprot = lp -> netdev -> cprot;
 	struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
 #endif
 
+	del_timer_sync(&lp->hup_timer);
 	if (lp->flags & ISDN_NET_CONNECTED) {
 		if (lp->slave != NULL) {
 			isdn_net_local *slp = (isdn_net_local *)lp->slave->priv;
@@ -838,7 +790,7 @@
 				printk(KERN_INFO
 					"isdn_net: hang up slave %s before %s\n",
 					slp->name, lp->name);
-				isdn_net_hangup(lp->slave);
+				isdn_net_hangup(slp);
 			}
 		}
 		printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
@@ -862,6 +814,17 @@
 	isdn_net_unbind_channel(lp);
 }
 
+void
+isdn_net_hangup_all()
+{
+	struct list_head *l;
+
+	list_for_each(l, &isdn_net_devs) {
+		isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+		isdn_net_hangup(&p->local);
+	}
+}
+
 typedef struct {
 	unsigned short source;
 	unsigned short dest;
@@ -1173,6 +1136,7 @@
 static int
 isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
+	unsigned long flags;
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 #ifdef CONFIG_ISDN_X25
 	struct concap_proto * cprot = lp -> netdev -> cprot;
@@ -1208,80 +1172,73 @@
 				dev_kfree_skb(skb);
 				return 0;
 			}
-			if (lp->phone[1]) {
-				ulong flags;
-				save_flags(flags);
-				cli();
-
-				if(lp->dialwait_timer <= 0)
-					if(lp->dialstarted > 0 && lp->dialtimeout > 0 && time_before(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))
-						lp->dialwait_timer = lp->dialstarted + lp->dialtimeout + lp->dialwait;
-
-				if(lp->dialwait_timer > 0) {
-					if(time_before(jiffies, lp->dialwait_timer)) {
-						isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
-						dev_kfree_skb(skb);
-						restore_flags(flags);
-						return 0;
-					} else
-						lp->dialwait_timer = 0;
-				}
-				/* Grab a free ISDN-Channel */
-				if (((chi =
-				     isdn_get_free_slot(
-					 		ISDN_USAGE_NET,
-							lp->l2_proto,
-							lp->l3_proto,
-							lp->pre_device,
-						 	lp->pre_channel,
-							lp->msn)
-							) < 0) &&
-					((chi =
-				     isdn_get_free_slot(
-					 		ISDN_USAGE_NET,
-							lp->l2_proto,
-							lp->l3_proto,
-							lp->pre_device,
-							lp->pre_channel^1,
-							lp->msn)
-							) < 0)) {
-					restore_flags(flags);
-					isdn_net_unreachable(ndev, skb,
-							   "No channel");
+
+			save_flags(flags);
+			cli();
+
+			if(lp->dialwait_timer <= 0)
+				if(lp->dialstarted > 0 && lp->dialtimeout > 0 && time_before(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))
+					lp->dialwait_timer = lp->dialstarted + lp->dialtimeout + lp->dialwait;
+			
+			if(lp->dialwait_timer > 0) {
+				if(time_before(jiffies, lp->dialwait_timer)) {
+					isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
 					dev_kfree_skb(skb);
+					restore_flags(flags);
 					return 0;
-				}
-				/* Log packet, which triggered dialing */
-				if (dev->net_verbose)
-					isdn_net_log_skb(skb, lp);
-				/* Connect interface with channel */
-				isdn_net_bind_channel(lp, chi);
+				} else
+					lp->dialwait_timer = 0;
+			}
+			/* Grab a free ISDN-Channel */
+			if (((chi =
+			      isdn_get_free_slot(
+				      ISDN_USAGE_NET,
+				      lp->l2_proto,
+				      lp->l3_proto,
+				      lp->pre_device,
+				      lp->pre_channel,
+				      lp->msn)
+				     ) < 0) &&
+			    ((chi =
+			      isdn_get_free_slot(
+				      ISDN_USAGE_NET,
+				      lp->l2_proto,
+				      lp->l3_proto,
+				      lp->pre_device,
+				      lp->pre_channel^1,
+				      lp->msn)
+				    ) < 0)) {
+				restore_flags(flags);
+				isdn_net_unreachable(ndev, skb,
+						     "No channel");
+				dev_kfree_skb(skb);
+				return 0;
+			}
+			/* Log packet, which triggered dialing */
+			if (dev->net_verbose)
+				isdn_net_log_skb(skb, lp);
+			/* Connect interface with channel */
+			isdn_net_bind_channel(lp, chi);
 #ifdef CONFIG_ISDN_PPP
-				if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
-					/* no 'first_skb' handling for syncPPP */
-					if (isdn_ppp_bind(lp) < 0) {
-						dev_kfree_skb(skb);
-						isdn_net_unbind_channel(lp);
-						restore_flags(flags);
-						return 0;	/* STN (skb to nirvana) ;) */
-					}
+			if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
+				/* no 'first_skb' handling for syncPPP */
+				if (isdn_ppp_bind(lp) < 0) {
+					dev_kfree_skb(skb);
+					isdn_net_unbind_channel(lp);
 					restore_flags(flags);
-					init_dialout(lp);
-					netif_stop_queue(ndev);
-					return 1;	/* let upper layer requeue skb packet */
+					return 0;	/* STN (skb to nirvana) ;) */
 				}
-#endif
-				/* Initiate dialing */
 				restore_flags(flags);
 				init_dialout(lp);
-				isdn_net_device_stop_queue(lp);
-				return 1;
-			} else {
-				isdn_net_unreachable(ndev, skb,
-						     "No phone number");
-				dev_kfree_skb(skb);
-				return 0;
+				netif_stop_queue(ndev);
+				return 1;	/* let upper layer requeue skb packet */
 			}
+#endif
+			/* Initiate dialing */
+			restore_flags(flags);
+			init_dialout(lp);
+			isdn_net_device_stop_queue(lp);
+			return 1;
 		} else {
 			/* Device is connected to an ISDN channel */ 
 			ndev->trans_start = jiffies;
@@ -1324,11 +1281,11 @@
 			if( cprot && cprot -> pops )
 				cprot -> pops -> close( cprot );
 #endif
-			isdn_net_hangup(p);
+			isdn_net_hangup(p->priv);
 			p = (((isdn_net_local *) p->priv)->slave);
 		}
 	}
-	isdn_net_hangup(dev);
+	isdn_net_hangup(dev->priv);
 	isdn_MOD_DEC_USE_COUNT();
 	return 0;
 }
@@ -2118,7 +2075,7 @@
 	int swapped;
 	int sidx = 0;
 	struct list_head *l;
-	isdn_net_phone *n;
+	struct isdn_net_phone *n;
 	ulong flags;
 	char nr[32];
 	char *my_eaz;
@@ -2152,7 +2109,7 @@
                 return 0;
         }
 
-	n = (isdn_net_phone *) 0;
+	n = NULL;
 	ematch = wret = swapped = 0;
 	dbg_net_icall("n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
 		      isdn_slot_usage(idx));
@@ -2258,166 +2215,163 @@
 				}
 			}
 			dbg_net_icall("n_fi: match2\n");
-			n = lp->phone[0];
 			if (lp->flags & ISDN_NET_SECURE) {
-				while (n) {
-					if (!isdn_msncmp(nr, n->num))
+				spin_lock_irqsave(&lp->lock, flags);
+				list_for_each_entry(n, &lp->phone[0], list) {
+					if (!isdn_msncmp(nr, n->num)) {
+						spin_unlock_irqrestore(&lp->lock, flags);
 						break;
-					n = (isdn_net_phone *) n->next;
+					}
 				}
+				spin_unlock_irqrestore(&lp->lock, flags);
+				continue;
 			}
-			if (n || (!(lp->flags & ISDN_NET_SECURE))) {
-				dbg_net_icall("n_fi: match3\n");
-				/* matching interface found */
+			dbg_net_icall("n_fi: match3\n");
+			/* matching interface found */
 
+			/*
+			 * Is the state STOPPED?
+			 * If so, no dialin is allowed,
+			 * so reject actively.
+			 * */
+			if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
+				restore_flags(flags);
+				printk(KERN_INFO "incoming call, interface %s `stopped' -> rejected\n",
+				       lp->name);
+				return 3;
+			}
+			/*
+			 * Is the interface up?
+			 * If not, reject the call actively.
+			 */
+			if (!isdn_net_device_started(p)) {
+				restore_flags(flags);
+				printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
+				       lp->name);
+				return 3;
+			}
+			/* Interface is up, now see if it's a slave. If so, see if
+			 * it's master and parent slave is online. If not, reject the call.
+			 */
+			if (lp->master) {
+				isdn_net_local *mlp = (isdn_net_local *) lp->master->priv;
+				printk(KERN_DEBUG "ICALLslv: %s\n", lp->name);
+				printk(KERN_DEBUG "master=%s\n", mlp->name);
+				if (mlp->flags & ISDN_NET_CONNECTED) {
+					printk(KERN_DEBUG "master online\n");
+					/* Master is online, find parent-slave (master if first slave) */
+					while (mlp->slave) {
+						if ((isdn_net_local *) mlp->slave->priv == lp)
+							break;
+						mlp = (isdn_net_local *) mlp->slave->priv;
+					}
+				} else
+					printk(KERN_DEBUG "master offline\n");
+				/* Found parent, if it's offline iterate next device */
+				printk(KERN_DEBUG "mlpf: %d\n", mlp->flags & ISDN_NET_CONNECTED);
+				if (!(mlp->flags & ISDN_NET_CONNECTED)) {
+					continue;
+				}
+			} 
+			if (lp->flags & ISDN_NET_CALLBACK) {
+				int chi;
 				/*
-				 * Is the state STOPPED?
-				 * If so, no dialin is allowed,
+				 * Is the state MANUAL?
+				 * If so, no callback can be made,
 				 * so reject actively.
 				 * */
 				if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
 					restore_flags(flags);
-					printk(KERN_INFO "incoming call, interface %s `stopped' -> rejected\n",
+					printk(KERN_INFO "incoming call for callback, interface %s `off' -> rejected\n",
 					       lp->name);
 					return 3;
 				}
-				/*
-				 * Is the interface up?
-				 * If not, reject the call actively.
-				 */
-				if (!isdn_net_device_started(p)) {
+				printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
+				       lp->name, nr, eaz);
+
+				/* Grab a free ISDN-Channel */
+				if ((chi = 
+				     isdn_get_free_slot(
+					     ISDN_USAGE_NET,
+					     lp->l2_proto,
+					     lp->l3_proto,
+					     lp->pre_device,
+					     lp->pre_channel,
+					     lp->msn)
+					    ) < 0) {
+					
+					printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
 					restore_flags(flags);
-					printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
-					       lp->name);
-					return 3;
+					return 0;
 				}
-				/* Interface is up, now see if it's a slave. If so, see if
-				 * it's master and parent slave is online. If not, reject the call.
-				 */
-				if (lp->master) {
-					isdn_net_local *mlp = (isdn_net_local *) lp->master->priv;
-					printk(KERN_DEBUG "ICALLslv: %s\n", lp->name);
-					printk(KERN_DEBUG "master=%s\n", mlp->name);
-					if (mlp->flags & ISDN_NET_CONNECTED) {
-						printk(KERN_DEBUG "master online\n");
-						/* Master is online, find parent-slave (master if first slave) */
-						while (mlp->slave) {
-							if ((isdn_net_local *) mlp->slave->priv == lp)
-								break;
-							mlp = (isdn_net_local *) mlp->slave->priv;
-						}
-					} else
-						printk(KERN_DEBUG "master offline\n");
-					/* Found parent, if it's offline iterate next device */
-					printk(KERN_DEBUG "mlpf: %d\n", mlp->flags & ISDN_NET_CONNECTED);
-					if (!(mlp->flags & ISDN_NET_CONNECTED)) {
-						continue;
-					}
-				} 
-				if (lp->flags & ISDN_NET_CALLBACK) {
-					int chi;
-					/*
-					 * Is the state MANUAL?
-					 * If so, no callback can be made,
-					 * so reject actively.
-					 * */
-					if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
-						restore_flags(flags);
-						printk(KERN_INFO "incoming call for callback, interface %s `off' -> rejected\n",
-						       lp->name);
-						return 3;
-					}
-					printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
-					       lp->name, nr, eaz);
-					if (lp->phone[1]) {
-						/* Grab a free ISDN-Channel */
-						if ((chi = 
-							isdn_get_free_slot(
-								ISDN_USAGE_NET,
-								lp->l2_proto,
-								lp->l3_proto,
-							  	lp->pre_device,
-						 		lp->pre_channel,
-						 		lp->msn)
-								) < 0) {
-
-							printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
-							restore_flags(flags);
-							return 0;
-						}
-						/* Setup dialstate. */
-						lp->dial_timer.expires = jiffies + lp->cbdelay;
-						lp->dial_event = EV_NET_TIMER_CB;
-						add_timer(&lp->dial_timer);
-
-						lp->dialstate = ST_WAIT_BEFORE_CB;
-						/* Connect interface with channel */
-						isdn_net_bind_channel(lp, chi);
+				/* Setup dialstate. */
+				lp->dial_timer.expires = jiffies + lp->cbdelay;
+				lp->dial_event = EV_NET_TIMER_CB;
+				add_timer(&lp->dial_timer);
+				
+				lp->dialstate = ST_WAIT_BEFORE_CB;
+				/* Connect interface with channel */
+				isdn_net_bind_channel(lp, chi);
 #ifdef CONFIG_ISDN_PPP
-						if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-							if (isdn_ppp_bind(lp) < 0) {
-								isdn_net_unbind_channel(lp);
-								restore_flags(flags);
-								return 0;
-							}
-#endif
-						/* Initiate dialing by returning 2 or 4 */
+				if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+					if (isdn_ppp_bind(lp) < 0) {
+						isdn_net_unbind_channel(lp);
 						restore_flags(flags);
-						return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
-					} else
-						printk(KERN_WARNING "isdn_net: %s: No phone number\n", lp->name);
-					restore_flags(flags);
-					return 0;
-				} else {
-					printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
-					       eaz);
-					/* if this interface is dialing, it does it probably on a different
-					   device, so free this device */
-					if (lp->dialstate == ST_OUT_WAIT_DCONN) {
-#ifdef CONFIG_ISDN_PPP
-						if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-							isdn_ppp_free(lp);
-#endif
-						isdn_net_lp_disconnected(lp);
-						isdn_slot_free(lp->isdn_slot,
-							 ISDN_USAGE_NET);
+						return 0;
 					}
-					strcpy(isdn_slot_num(idx), nr);
-					isdn_slot_set_usage(idx, (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) | ISDN_USAGE_NET);
-					isdn_slot_set_st_netdev(idx, lp->netdev);
-					lp->isdn_slot = slot;
-					lp->ppp_slot = -1;
-					lp->flags |= ISDN_NET_CONNECTED;
-
-					lp->outgoing = 0;
-					lp->huptimer = 0;
-					lp->charge_state = ST_CHARGE_NULL;
-					/* Got incoming Call, setup L2 and L3 protocols,
-					 * then wait for D-Channel-connect
-					 */
-					cmd.arg = lp->l2_proto << 8;
-					isdn_slot_command(lp->isdn_slot, ISDN_CMD_SETL2, &cmd);
-					cmd.arg = lp->l3_proto << 8;
-					isdn_slot_command(lp->isdn_slot, ISDN_CMD_SETL3, &cmd);
-
-					lp->dial_timer.expires = jiffies + 15 * HZ;
-					lp->dial_event = EV_NET_TIMER_IN_DCONN;
-					add_timer(&lp->dial_timer);
-					lp->dialstate = ST_IN_WAIT_DCONN;
-
+#endif
+				/* Initiate dialing by returning 2 or 4 */
+				restore_flags(flags);
+				return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
+			} else {
+				printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
+				       eaz);
+				/* if this interface is dialing, it does it probably on a different
+				   device, so free this device */
+				if (lp->dialstate == ST_OUT_WAIT_DCONN) {
 #ifdef CONFIG_ISDN_PPP
 					if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-						if (isdn_ppp_bind(lp) < 0) {
-							isdn_net_unbind_channel(lp);
-							restore_flags(flags);
-							return 0;
-						}
+						isdn_ppp_free(lp);
 #endif
-					restore_flags(flags);
-					return 1;
+					isdn_net_lp_disconnected(lp);
+					isdn_slot_free(lp->isdn_slot,
+						       ISDN_USAGE_NET);
 				}
+				strcpy(isdn_slot_num(idx), nr);
+				isdn_slot_set_usage(idx, (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) | ISDN_USAGE_NET);
+				isdn_slot_set_st_netdev(idx, lp->netdev);
+				lp->isdn_slot = slot;
+				lp->ppp_slot = -1;
+				lp->flags |= ISDN_NET_CONNECTED;
+				
+				lp->outgoing = 0;
+				lp->huptimer = 0;
+				lp->charge_state = ST_CHARGE_NULL;
+				/* Got incoming Call, setup L2 and L3 protocols,
+				 * then wait for D-Channel-connect
+				 */
+				cmd.arg = lp->l2_proto << 8;
+				isdn_slot_command(lp->isdn_slot, ISDN_CMD_SETL2, &cmd);
+				cmd.arg = lp->l3_proto << 8;
+				isdn_slot_command(lp->isdn_slot, ISDN_CMD_SETL3, &cmd);
+				
+				lp->dial_timer.expires = jiffies + 15 * HZ;
+				lp->dial_event = EV_NET_TIMER_IN_DCONN;
+				add_timer(&lp->dial_timer);
+				lp->dialstate = ST_IN_WAIT_DCONN;
+				
+#ifdef CONFIG_ISDN_PPP
+				if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+					if (isdn_ppp_bind(lp) < 0) {
+						isdn_net_unbind_channel(lp);
+						restore_flags(flags);
+						return 0;
+					}
+#endif
+				restore_flags(flags);
+				return 1;
 			}
-		}
+			 }
 	}
 	/* If none of configured EAZ/MSN matched and not verbose, be silent */
 	if (!ematch || dev->net_verbose)
@@ -2450,45 +2404,38 @@
 int
 isdn_net_force_dial_lp(isdn_net_local * lp)
 {
-	if ((!(lp->flags & ISDN_NET_CONNECTED)) && lp->dialstate == ST_NULL) {
-		int chi;
-		if (lp->phone[1]) {
-			ulong flags;
-			save_flags(flags);
-			cli();
+	int chi;
+	unsigned long flags;
 
-			/* Grab a free ISDN-Channel */
-			if ((chi = 
-						isdn_get_free_slot(
-							ISDN_USAGE_NET,
-							lp->l2_proto,
-							lp->l3_proto,
-							lp->pre_device,
-						 	lp->pre_channel,
-							lp->msn)
-							) < 0) {
-				printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
-				restore_flags(flags);
-				return -EAGAIN;
-			}
-			/* Connect interface with channel */
-			isdn_net_bind_channel(lp, chi);
+	if (lp->flags & ISDN_NET_CONNECTED || lp->dialstate != ST_NULL)
+		return -EBUSY;
+
+	save_flags(flags);
+	cli();
+	
+	/* Grab a free ISDN-Channel */
+	chi = isdn_get_free_slot(ISDN_USAGE_NET, lp->l2_proto, lp->l3_proto,
+				 lp->pre_device, lp->pre_channel, lp->msn);
+	if (chi < 0) {
+		printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
+		restore_flags(flags);
+		return -EAGAIN;
+	}
+	/* Connect interface with channel */
+	isdn_net_bind_channel(lp, chi);
 #ifdef CONFIG_ISDN_PPP
-			if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-				if (isdn_ppp_bind(lp) < 0) {
-					isdn_net_unbind_channel(lp);
-					restore_flags(flags);
-					return -EAGAIN;
-				}
-#endif
-			/* Initiate dialing */
+	if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+		if (isdn_ppp_bind(lp) < 0) {
+			isdn_net_unbind_channel(lp);
 			restore_flags(flags);
-			init_dialout(lp);
-			return 0;
-		} else
-			return -EINVAL;
-	} else
-		return -EBUSY;
+			return -EAGAIN;
+		}
+#endif
+	/* Initiate dialing */
+	restore_flags(flags);
+	init_dialout(lp);
+
+	return 0;
 }
 
 /*
@@ -2608,6 +2555,12 @@
 	init_timer(&netdev->local.dial_timer);
 	netdev->local.dial_timer.data = (unsigned long) &netdev->local;
 	netdev->local.dial_timer.function = isdn_net_dial_timer;
+	init_timer(&netdev->local.hup_timer);
+	netdev->local.hup_timer.data = (unsigned long) &netdev->local;
+	netdev->local.hup_timer.function = isdn_net_hup_timer;
+	spin_lock_init(&netdev->local.lock);
+	INIT_LIST_HEAD(&netdev->local.phone[0]);
+	INIT_LIST_HEAD(&netdev->local.phone[1]);
 
 	/* Put into to netdev-chain */
 	list_add(&netdev->global_list, &isdn_net_devs);
@@ -2837,6 +2790,9 @@
 		else {
 			lp->flags |= cfg->dialmode;  /* turn on selected bits */
 		}
+		if (lp->flags & ISDN_NET_DM_OFF)
+			isdn_net_hangup(lp);
+
 		if (cfg->chargehup)
 			lp->hupflags |= ISDN_CHARGEHUP;
 		else
@@ -2937,17 +2893,21 @@
 isdn_net_addphone(isdn_net_ioctl_phone * phone)
 {
 	isdn_net_dev *p = isdn_net_findif(phone->name);
-	isdn_net_phone *n;
+	unsigned long flags;
+	struct isdn_net_phone *n;
 
-	if (p) {
-		if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
-			return -ENOMEM;
-		strcpy(n->num, phone->phone);
-		n->next = p->local.phone[phone->outgoing & 1];
-		p->local.phone[phone->outgoing & 1] = n;
-		return 0;
-	}
-	return -ENODEV;
+	if (!p)
+		return -ENODEV;
+
+	n = kmalloc(sizeof(*n), GFP_KERNEL);
+	if (!n)
+		return -ENOMEM;
+
+	strcpy(n->num, phone->phone);
+	spin_lock_irqsave(&p->local.lock, flags);
+	list_add_tail(&n->list, &p->local.phone[phone->outgoing & 1]);
+	spin_unlock_irqrestore(&p->local.lock, flags);
+	return 0;
 }
 
 /*
@@ -2958,28 +2918,37 @@
 isdn_net_getphones(isdn_net_ioctl_phone * phone, char *phones)
 {
 	isdn_net_dev *p = isdn_net_findif(phone->name);
+	unsigned long flags;
 	int inout = phone->outgoing & 1;
-	int more = 0;
 	int count = 0;
-	isdn_net_phone *n;
+	char *buf = (char *)__get_free_page(GFP_KERNEL);
+	struct isdn_net_phone *n;
 
 	if (!p)
 		return -ENODEV;
+
+	if (!buf)
+		return -ENOMEM;
+
 	inout &= 1;
-	for (n = p->local.phone[inout]; n; n = n->next) {
-		if (more) {
-			put_user(' ', phones++);
-			count++;
-		}
-		if (copy_to_user(phones, n->num, strlen(n->num) + 1)) {
-			return -EFAULT;
-		}
-		phones += strlen(n->num);
+	spin_lock_irqsave(&p->local.lock, flags);
+	list_for_each_entry(n, &p->local.phone[inout], list) {
+		strcpy(&buf[count], n->num);
 		count += strlen(n->num);
-		more = 1;
+		buf[count++] = ' ';
+		if (count > PAGE_SIZE - ISDN_MSNLEN - 1)
+			break;
 	}
-	put_user(0, phones);
-	count++;
+	spin_unlock_irqrestore(&p->local.lock, flags);
+	if (!count)
+		count++;
+
+	buf[count-1] = 0;
+
+	if (copy_to_user(phones, buf, count))
+		count = -EFAULT;
+
+	free_page((unsigned long)buf);
 	return count;
 }
 
@@ -3017,34 +2986,25 @@
 {
 	isdn_net_dev *p = isdn_net_findif(phone->name);
 	int inout = phone->outgoing & 1;
-	isdn_net_phone *n;
-	isdn_net_phone *m;
+	struct isdn_net_phone *n;
 	unsigned long flags;
+	int retval;
 
-	if (p) {
-		save_flags(flags);
-		cli();
-		n = p->local.phone[inout];
-		m = NULL;
-		while (n) {
-			if (!strcmp(n->num, phone->phone)) {
-				if (p->local.dial == n)
-					p->local.dial = n->next;
-				if (m)
-					m->next = n->next;
-				else
-					p->local.phone[inout] = n->next;
-				kfree(n);
-				restore_flags(flags);
-				return 0;
-			}
-			m = n;
-			n = (isdn_net_phone *) n->next;
+	if (!p)
+		return -ENODEV;
+
+	retval = -EINVAL;
+	spin_lock_irqsave(&p->local.lock, flags);
+	list_for_each_entry(n, &p->local.phone[inout], list) {
+		if (!strcmp(n->num, phone->phone)) {
+			list_del(&n->list);
+			kfree(n);
+			retval = 0;
+			break;
 		}
-		restore_flags(flags);
-		return -EINVAL;
 	}
-	return -ENODEV;
+	spin_unlock_irqrestore(&p->local.lock, flags);
+	return retval;
 }
 
 /*
@@ -3053,24 +3013,19 @@
 static int
 isdn_net_rmallphone(isdn_net_dev * p)
 {
-	isdn_net_phone *n;
-	isdn_net_phone *m;
+	struct isdn_net_phone *n;
 	unsigned long flags;
 	int i;
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&p->local.lock, flags);
 	for (i = 0; i < 2; i++) {
-		n = p->local.phone[i];
-		while (n) {
-			m = n->next;
+		while (!list_empty(&p->local.phone[i])) {
+			n = list_entry(p->local.phone[i].next, struct isdn_net_phone, list);
+			list_del(&n->list);
 			kfree(n);
-			n = m;
 		}
-		p->local.phone[i] = NULL;
 	}
-	p->local.dial = NULL;
-	restore_flags(flags);
+	spin_lock_irqsave(&p->local.lock, flags);
 	return 0;
 }
 
@@ -3089,10 +3044,10 @@
 		q = p->local.slave;
 		/* If this interface has slaves, do a hangup for them also. */
 		while (q) {
-			isdn_net_hangup(q);
+			isdn_net_hangup(&p->local);
 			q = (((isdn_net_local *) q->priv)->slave);
 		}
-		isdn_net_hangup(&p->dev);
+		isdn_net_hangup(&p->local);
 		return 0;
 	}
 	return -ENODEV;
@@ -3146,9 +3101,6 @@
 			}
 		}
 	}
-	/* If no more net-devices remain, disable auto-hangup timer */
-	if (list_empty(&isdn_net_devs))
-		isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
 	restore_flags(flags);
 	kfree(p);
 
diff -Nru a/drivers/isdn/i4l/isdn_net.h b/drivers/isdn/i4l/isdn_net.h
--- a/drivers/isdn/i4l/isdn_net.h	Fri Sep 27 14:51:05 2002
+++ b/drivers/isdn/i4l/isdn_net.h	Fri Sep 27 14:51:05 2002
@@ -41,8 +41,8 @@
 extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone *);
 extern int isdn_net_delphone(isdn_net_ioctl_phone *);
 extern int isdn_net_find_icall(int, int, int, setup_parm *);
-extern void isdn_net_hangup(struct net_device *);
-extern void isdn_net_autohup(void);
+extern void isdn_net_hangup(isdn_net_local *);
+extern void isdn_net_hangup_all(void);
 extern int isdn_net_force_hangup(char *);
 extern int isdn_net_force_dial(char *);
 extern isdn_net_dev *isdn_net_findif(char *);
diff -Nru a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
--- a/drivers/isdn/i4l/isdn_ppp.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/isdn/i4l/isdn_ppp.c	Fri Sep 27 14:51:04 2002
@@ -19,10 +19,6 @@
 #include "isdn_ppp.h"
 #include "isdn_net.h"
 
-#ifndef PPP_IPX
-#define PPP_IPX 0x002b
-#endif
-
 /* Prototypes */
 static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
 static int isdn_ppp_closewait(int slot);
@@ -348,20 +344,13 @@
 		printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", minor, (long) is->lp);
 
 	if (is->lp) {           /* a lp address says: this link is still up */
-		isdn_net_dev *p = is->lp->netdev;
-
- 		if (!p) {
- 			printk(KERN_ERR "%s: no lp->netdev\n", __FUNCTION__ );
-			unlock_kernel();
- 			return 0;
- 		}
-		is->state &= ~IPPP_CONNECT;	/* -> effect: no call of wakeup */
 		/*
 		 * isdn_net_hangup() calls isdn_ppp_free()
 		 * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1
 		 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon()
 		 */
-		isdn_net_hangup(&p->dev);
+		is->state &= ~IPPP_CONNECT;
+		isdn_net_hangup(is->lp);
 	}
 	for (i = 0; i < NUM_RCV_BUFFS; i++) {
 		if (is->rq[i].buf) {
@@ -424,8 +413,6 @@
 static int
 set_arg(void *b, void *val,int len)
 {
-	if(len <= 0)
-		len = sizeof(void *);
 	if (copy_to_user(b, (void *) val, len))
 		return -EFAULT;
 	return 0;
@@ -571,13 +558,18 @@
 			return isdn_ppp_set_compressor(is, &data);
 		case PPPIOCGCALLINFO:
 			{
+				struct isdn_net_phone *phone;
 				struct pppcallinfo pci;
+				int i;
 				memset((char *) &pci,0,sizeof(struct pppcallinfo));
-				if(lp)
-				{
+				if(lp) {
 					strncpy(pci.local_num,lp->msn,63);
-					if(lp->dial) {
-						strncpy(pci.remote_num,lp->dial->num,63);
+					i = 0;
+					list_for_each_entry(phone, &lp->phone[1], list) {
+						if (i++ == lp->dial) {
+							strncpy(pci.remote_num,phone->num,63);
+							break;
+						}
 					}
 					pci.charge_units = lp->charge;
 					if(lp->outgoing)
@@ -2003,7 +1995,7 @@
 {
 #ifdef CONFIG_ISDN_MPP
 	isdn_net_dev *ndev;
-	isdn_net_local *lp;
+	isdn_net_local *lp, *mlp = NULL;
 	struct net_device *sdev;
 
 	if (!(ndev = isdn_net_findif(name)))
@@ -2014,7 +2006,7 @@
 
 	sdev = lp->slave;
 	while (sdev) {
-		isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
+		mlp = (isdn_net_local *) sdev->priv;
 
 		if (mlp->slave) { /* find last connected link in chain */
 			isdn_net_local *nlp = (isdn_net_local *) mlp->slave->priv;
@@ -2029,7 +2021,7 @@
 	if (!sdev)
 		return 2;
 
-	isdn_net_hangup(sdev);
+	isdn_net_hangup(mlp);
 	return 0;
 #else
 	return -1;
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/md/md.c	Fri Sep 27 14:51:03 2002
@@ -3474,7 +3474,6 @@
 #endif
 
 	blk_dev[MAJOR_NR].queue = NULL;
-	blk_clear(MAJOR_NR);
 }
 #endif
 
diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/mtd/ftl.c	Fri Sep 27 14:51:03 2002
@@ -119,7 +119,7 @@
 /* Each memory region corresponds to a minor device */
 typedef struct partition_t {
     struct mtd_info	*mtd;
-    struct gndisk	*disk;
+    struct gendisk	*disk;
     u_int32_t		state;
     u_int32_t		*VirtualBlockMap;
     u_int32_t		*VirtualPageMap;
@@ -175,7 +175,6 @@
 		     u_int cmd, u_long arg);
 static int ftl_open(struct inode *inode, struct file *file);
 static release_t ftl_close(struct inode *inode, struct file *file);
-static int ftl_reread_partitions(kdev_t dev);
 static int ftl_revalidate(kdev_t dev);
 
 static void ftl_erase_callback(struct erase_info *done);
@@ -1125,7 +1124,7 @@
 	partition_t *part = myparts[unit];
 	scan_header(part);
 	set_capacity(part->disk,
-		le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE));
+		le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
 	return 0;
 }
 
@@ -1151,7 +1150,7 @@
 	if (part) {
 	  ret = 0;
 	  
-	  switch (CURRENT->cmd) {
+	  switch (rq_data_dir(CURRENT)) {
 	  case READ:
 	    ret = ftl_read(part, CURRENT->buffer, CURRENT->sector,
 			   CURRENT->current_nr_sectors);
@@ -1267,7 +1266,7 @@
 
 static void ftl_notify_remove(struct mtd_info *mtd)
 {
-        int i,j;
+        int i;
 
 	/* Q: What happens if you try to remove a device which has
 	 *    a currently-open FTL partition on it?
@@ -1287,7 +1286,7 @@
 			
 			myparts[i]->state = 0;
 			del_gendisk(myparts[i]->disk);
-			kfree(myparts[i]->disk->name);
+			kfree(myparts[i]->disk->major_name);
 			kfree(myparts[i]->disk);
 			kfree(myparts[i]);
 			myparts[i] = NULL;
@@ -1296,7 +1295,7 @@
 
 int init_ftl(void)
 {
-    int i;
+    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
     DEBUG(0, "$Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $\n");
     
     if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
@@ -1304,7 +1303,7 @@
 	       "device number!\n");
 	return -EAGAIN;
     }
-    blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request);
+    blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request, &lock);
     register_mtd_user(&ftl_notifier);
     
     return 0;
@@ -1315,7 +1314,6 @@
     unregister_mtd_user(&ftl_notifier);
     unregister_blkdev(FTL_MAJOR, "ftl");
     blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR));
-    blk_clear(FTL_MAJOR);
 }
 
 module_init(init_ftl);
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/mtd/mtdblock.c	Fri Sep 27 14:51:04 2002
@@ -42,12 +42,12 @@
 	unsigned long cache_offset;
 	unsigned int cache_size;
 	enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
+	struct gendisk disk;
+	char name[7];
 } *mtdblks[MAX_MTD_DEVICES];
 
 static spinlock_t mtdblks_lock;
 
-static int mtd_sizes[MAX_MTD_DEVICES];
-
 /*
  * Cache stuff...
  * 
@@ -257,20 +257,16 @@
 	return 0;
 }
 
-
+static struct block_device_operations mtd_fops;
 
 static int mtdblock_open(struct inode *inode, struct file *file)
 {
 	struct mtdblk_dev *mtdblk;
 	struct mtd_info *mtd;
-	int dev;
+	int dev = minor(inode->i_rdev);
 
 	DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
-	
-	if (!inode)
-		return -EINVAL;
-	
-	dev = minor(inode->i_rdev);
+
 	if (dev >= MAX_MTD_DEVICES)
 		return -EINVAL;
 
@@ -319,6 +315,12 @@
 			return -ENOMEM;
 		}
 	}
+	mtdblk->disk.major = MAJOR_NR;
+	mtdblk->disk.first_minor = dev;
+	mtdblk->disk.minor_shift = 0;
+	mtdblk->disk.fops = &mtd_fops;
+	mtdblk->disk.major_name = mtdblk->name;
+	sprintf(mtdblk->name, "mtd%d", dev);
 
 	/* OK, we've created a new one. Add it to the list. */
 
@@ -335,7 +337,8 @@
 	}
 
 	mtdblks[dev] = mtdblk;
-	mtd_sizes[dev] = mtdblk->mtd->size/1024;
+	set_capacity(&mtdblk->disk, mtdblk->mtd->size/512);
+	add_disk(&mtdblk->disk);
 	set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
 	
 	spin_unlock(&mtdblks_lock);
@@ -366,6 +369,7 @@
 		/* It was the last usage. Free the device */
 		mtdblks[dev] = NULL;
 		spin_unlock(&mtdblks_lock);
+		del_gendisk(&mtdblk->disk);
 		if (mtdblk->mtd->sync)
 			mtdblk->mtd->sync(mtdblk->mtd);
 		put_mtd_device(mtdblk->mtd);
@@ -404,7 +408,7 @@
 		res = 0;
 
 		if (minor(req->rq_dev) >= MAX_MTD_DEVICES)
-			panic(__FUNCTION__": minor out of bound");
+			panic("handle_mtdblock_request: minor out of bound");
 
 		if (! (req->flags & REQ_CMD))
 			goto end_req;
@@ -490,7 +494,7 @@
 	return 0;
 }
 
-static void mtdblock_request(request_queue *q)
+static void mtdblock_request(struct request_queue *q)
 {
 	/* Don't do anything, except wake the thread if necessary */
 	wake_up(&thr_wq);
@@ -510,11 +514,6 @@
 #endif
 
 	switch (cmd) {
-	case BLKGETSIZE:   /* Return device size */
-		return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);
-	case BLKGETSIZE64:
-		return put_user((u64)mtdblk->mtd->size, (u64 *)arg);
-		
 	case BLKFLSBUF:
 		if(!capable(CAP_SYS_ADMIN))
 			return -EACCES;
@@ -571,8 +570,6 @@
 
 int __init init_mtdblock(void)
 {
-	int i;
-
 	spin_lock_init(&mtdblks_lock);
 	if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
 		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
@@ -584,12 +581,7 @@
 	register_mtd_user(&notifier);
 #endif
 	
-	/* We fill it in at open() time. */
-	for (i=0; i< MAX_MTD_DEVICES; i++)
-		mtd_sizes[i] = 0;
 	init_waitqueue_head(&thr_wq);
-	blk_size[MAJOR_NR] = mtd_sizes;
-	
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request, &mtddev_lock);
 	kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
 	return 0;
@@ -606,7 +598,6 @@
 #endif
 	unregister_blkdev(MAJOR_NR,DEVICE_NAME);
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-	blk_size[MAJOR_NR] = NULL;
 }
 
 module_init(init_mtdblock);
diff -Nru a/drivers/net/irda/act200l.c b/drivers/net/irda/act200l.c
--- a/drivers/net/irda/act200l.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/irda/act200l.c	Fri Sep 27 14:51:04 2002
@@ -106,7 +106,7 @@
 
 static void act200l_open(dongle_t *self, struct qos_info *qos)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	/* Power on the dongle */
 	self->set_dtr_rts(self->dev, TRUE, TRUE);
@@ -120,7 +120,7 @@
 
 static void act200l_close(dongle_t *self)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	/* Power off the dongle */
 	self->set_dtr_rts(self->dev, FALSE, FALSE);
@@ -141,7 +141,7 @@
 	__u8 control[3];
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	self->speed_task = task;
 
@@ -233,7 +233,7 @@
 	};
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	self->reset_task = task;
 
diff -Nru a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
--- a/drivers/net/irda/ali-ircc.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/irda/ali-ircc.c	Fri Sep 27 14:51:04 2002
@@ -864,7 +864,7 @@
 		}
 	} while (inb(iobase+UART_LSR) & UART_LSR_DR);	
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 /*
@@ -881,7 +881,7 @@
 
 	ASSERT(self != NULL, return;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	iobase = self->io.sir_base;
 
@@ -900,16 +900,16 @@
 		{
 			/* We must wait until all data are gone */
 			while(!(inb(iobase+UART_LSR) & UART_LSR_TEMT))
-				IRDA_DEBUG(1, __FUNCTION__ "(), UART_LSR_THRE\n");
+				IRDA_DEBUG(1, "%s(), UART_LSR_THRE\n", __FUNCTION__ );
 			
-			IRDA_DEBUG(1, __FUNCTION__ "(), Changing speed! self->new_speed = %d\n", self->new_speed);
+			IRDA_DEBUG(1, "%s(), Changing speed! self->new_speed = %d\n", __FUNCTION__ , self->new_speed);
 			ali_ircc_change_speed(self, self->new_speed);
 			self->new_speed = 0;			
 			
 			// benjamin 2000/11/10 06:32PM
 			if (self->io.speed > 115200)
 			{
-				IRDA_DEBUG(2, __FUNCTION__ "(), ali_ircc_change_speed from UART_LSR_TEMT \n");				
+				IRDA_DEBUG(2, "%s(), ali_ircc_change_speed from UART_LSR_TEMT \n", __FUNCTION__ );				
 					
 				self->ier = IER_EOM;
 				// SetCOMInterrupts(self, TRUE);							
@@ -927,7 +927,7 @@
 		outb(UART_IER_RDI, iobase+UART_IER);
 	}
 		
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud)
@@ -935,9 +935,9 @@
 	struct net_device *dev = self->netdev;
 	int iobase;
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), setting speed = %d \n", baud);
+	IRDA_DEBUG(2, "%s(), setting speed = %d \n", __FUNCTION__ , baud);
 	
 	/* This function *must* be called with irq off and spin-lock.
 	 * - Jean II */
@@ -976,7 +976,7 @@
 		
 	netif_wake_queue(self->netdev);	
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud)
@@ -986,14 +986,14 @@
 	struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv;
 	struct net_device *dev;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 		
 	ASSERT(self != NULL, return;);
 
 	dev = self->netdev;
 	iobase = self->io.fir_base;
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), self->io.speed = %d, change to speed = %d\n",self->io.speed,baud);
+	IRDA_DEBUG(1, "%s(), self->io.speed = %d, change to speed = %d\n", __FUNCTION__ ,self->io.speed,baud);
 	
 	/* Come from SIR speed */
 	if(self->io.speed <=115200)
@@ -1007,7 +1007,7 @@
 	// Set Dongle Speed mode
 	ali_ircc_change_dongle_speed(self, baud);
 		
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 /*
@@ -1025,9 +1025,9 @@
 	int lcr;    /* Line control reg */
 	int divisor;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), Setting speed to: %d\n", speed);
+	IRDA_DEBUG(1, "%s(), Setting speed to: %d\n", __FUNCTION__ , speed);
 
 	ASSERT(self != NULL, return;);
 
@@ -1081,7 +1081,7 @@
 	
 	spin_unlock_irqrestore(&self->lock, flags);
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed)
@@ -1091,14 +1091,14 @@
 	int iobase,dongle_id;
 	int tmp = 0;
 			
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");	
+	IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );	
 	
 	iobase = self->io.fir_base; 	/* or iobase = self->io.sir_base; */
 	dongle_id = self->io.dongle_id;
 	
 	/* We are already locked, no need to do it again */
 		
-	IRDA_DEBUG(1, __FUNCTION__ "(), Set Speed for %s , Speed = %d\n", dongle_types[dongle_id], speed);		
+	IRDA_DEBUG(1, "%s(), Set Speed for %s , Speed = %d\n", __FUNCTION__ , dongle_types[dongle_id], speed);		
 	
 	switch_bank(iobase, BANK2);
 	tmp = inb(iobase+FIR_IRDA_CR);
@@ -1262,7 +1262,7 @@
 			
 	switch_bank(iobase, BANK0);
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");		
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );		
 }
 
 /*
@@ -1275,11 +1275,11 @@
 {
 	int actual = 0;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 		
 	/* Tx FIFO should be empty! */
 	if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n");
+		IRDA_DEBUG(0, "%s(), failed, fifo not empty!\n", __FUNCTION__ );
 		return 0;
 	}
         
@@ -1291,7 +1291,7 @@
 		actual++;
 	}
 	
-        IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+        IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	return actual;
 }
 
@@ -1303,14 +1303,14 @@
  */
 static int ali_ircc_net_init(struct net_device *dev)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	/* Setup to be a normal IrDA network device driver */
 	irda_device_setup(dev);
 
 	/* Insert overrides below this line! */
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	
 	return 0;
 }
@@ -1327,7 +1327,7 @@
 	int iobase;
 	char hwname[32];
 		
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	ASSERT(dev != NULL, return -1;);
 	
@@ -1373,7 +1373,7 @@
 		
 	MOD_INC_USE_COUNT;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	
 	return 0;
 }
@@ -1390,7 +1390,7 @@
 	struct ali_ircc_cb *self;
 	//int iobase;
 			
-	IRDA_DEBUG(4, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(4, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 		
 	ASSERT(dev != NULL, return -1;);
 
@@ -1415,7 +1415,7 @@
 
 	MOD_DEC_USE_COUNT;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	
 	return 0;
 }
@@ -1434,7 +1434,7 @@
 	__u32 speed;
 	int mtt, diff;
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ );	
 	
 	self = (struct ali_ircc_cb *) dev->priv;
 	iobase = self->io.fir_base;
@@ -1488,7 +1488,7 @@
 			diff = self->now.tv_usec - self->stamp.tv_usec;
 			/* self->stamp is set from ali_ircc_dma_receive_complete() */
 							
-			IRDA_DEBUG(1, __FUNCTION__ "(), ******* diff = %d ******* \n", diff);	
+			IRDA_DEBUG(1, "%s(), ******* diff = %d ******* \n", __FUNCTION__ , diff);	
 			
 			if (diff < 0) 
 				diff += 1000000;
@@ -1510,7 +1510,7 @@
 					/* Adjust for timer resolution */
 					mtt = (mtt+250) / 500; 	/* 4 discard, 5 get advanced, Let's round off */
 					
-					IRDA_DEBUG(1, __FUNCTION__ "(), ************** mtt = %d ***********\n", mtt);	
+					IRDA_DEBUG(1, "%s(), ************** mtt = %d ***********\n", __FUNCTION__ , mtt);	
 					
 					/* Setup timer */
 					if (mtt == 1) /* 500 us */
@@ -1566,7 +1566,7 @@
 	spin_unlock_irqrestore(&self->lock, flags);
 	dev_kfree_skb(skb);
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	return 0;	
 }
 
@@ -1577,7 +1577,7 @@
 	unsigned char FIFO_OPTI, Hi, Lo;
 	
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ );	
 	
 	iobase = self->io.fir_base;
 	
@@ -1627,7 +1627,7 @@
 	tmp = inb(iobase+FIR_LCR_B);
 	tmp &= ~0x20; // Disable SIP
 	outb(((unsigned char)(tmp & 0x3f) | LCR_B_TX_MODE) & ~LCR_B_BW, iobase+FIR_LCR_B);
-	IRDA_DEBUG(1, __FUNCTION__ "(), ******* Change to TX mode: FIR_LCR_B = 0x%x ******* \n", inb(iobase+FIR_LCR_B));
+	IRDA_DEBUG(1, "%s(), ******* Change to TX mode: FIR_LCR_B = 0x%x ******* \n", __FUNCTION__ , inb(iobase+FIR_LCR_B));
 	
 	outb(0, iobase+FIR_LSR);
 			
@@ -1637,7 +1637,7 @@
 	
 	switch_bank(iobase, BANK0); 
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );
 }
 
 static int  ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self)
@@ -1645,7 +1645,7 @@
 	int iobase;
 	int ret = TRUE;
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ );	
 	
 	iobase = self->io.fir_base;
 	
@@ -1701,7 +1701,7 @@
 		
 	switch_bank(iobase, BANK0); 
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	return ret;
 }
 
@@ -1716,7 +1716,7 @@
 {
 	int iobase, tmp;
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ );	
 	
 	iobase = self->io.fir_base;
 	
@@ -1754,7 +1754,7 @@
 	//switch_bank(iobase, BANK0);
 	tmp = inb(iobase+FIR_LCR_B);
 	outb((unsigned char)(tmp &0x3f) | LCR_B_RX_MODE | LCR_B_BW , iobase + FIR_LCR_B); // 2000/12/1 05:16PM
-	IRDA_DEBUG(1, __FUNCTION__ "(), *** Change To RX mode: FIR_LCR_B = 0x%x *** \n", inb(iobase+FIR_LCR_B));
+	IRDA_DEBUG(1, "%s(), *** Change To RX mode: FIR_LCR_B = 0x%x *** \n", __FUNCTION__ , inb(iobase+FIR_LCR_B));
 			
 	/* Set Rx Threshold */
 	switch_bank(iobase, BANK1);
@@ -1766,7 +1766,7 @@
 	outb(CR_DMA_EN | CR_DMA_BURST, iobase+FIR_CR);
 				
 	switch_bank(iobase, BANK0); 
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	return 0;
 }
 
@@ -1777,7 +1777,7 @@
 	__u8 status, MessageCount;
 	int len, i, iobase, val;	
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __FUNCTION__ );	
 
 	st_fifo = &self->st_fifo;		
 	iobase = self->io.fir_base;	
@@ -1786,7 +1786,7 @@
 	MessageCount = inb(iobase+ FIR_LSR)&0x07;
 	
 	if (MessageCount > 0)	
-		IRDA_DEBUG(0, __FUNCTION__ "(), Messsage count = %d,\n", MessageCount);	
+		IRDA_DEBUG(0, "%s(), Messsage count = %d,\n", __FUNCTION__ , MessageCount);	
 		
 	for (i=0; i<=MessageCount; i++)
 	{
@@ -1799,11 +1799,11 @@
 		len = len << 8; 
 		len |= inb(iobase+FIR_RX_DSR_LO);
 		
-		IRDA_DEBUG(1, __FUNCTION__ "(), RX Length = 0x%.2x,\n", len);	
-		IRDA_DEBUG(1, __FUNCTION__ "(), RX Status = 0x%.2x,\n", status);
+		IRDA_DEBUG(1, "%s(), RX Length = 0x%.2x,\n", __FUNCTION__ , len);	
+		IRDA_DEBUG(1, "%s(), RX Status = 0x%.2x,\n", __FUNCTION__ , status);
 		
 		if (st_fifo->tail >= MAX_RX_WINDOW) {
-			IRDA_DEBUG(0, __FUNCTION__ "(), window is full!\n");
+			IRDA_DEBUG(0, "%s(), window is full!\n", __FUNCTION__ );
 			continue;
 		}
 			
@@ -1826,7 +1826,7 @@
 		/* Check for errors */
 		if ((status & 0xd8) || self->rcvFramesOverflow || (len==0)) 		
 		{
-			IRDA_DEBUG(0,__FUNCTION__ "(), ************* RX Errors ************ \n");	
+			IRDA_DEBUG(0,"%s(), ************* RX Errors ************ \n", __FUNCTION__ );	
 			
 			/* Skip frame */
 			self->stats.rx_errors++;
@@ -1836,29 +1836,29 @@
 			if (status & LSR_FIFO_UR) 
 			{
 				self->stats.rx_frame_errors++;
-				IRDA_DEBUG(0,__FUNCTION__ "(), ************* FIFO Errors ************ \n");
+				IRDA_DEBUG(0,"%s(), ************* FIFO Errors ************ \n", __FUNCTION__ );
 			}	
 			if (status & LSR_FRAME_ERROR)
 			{
 				self->stats.rx_frame_errors++;
-				IRDA_DEBUG(0,__FUNCTION__ "(), ************* FRAME Errors ************ \n");
+				IRDA_DEBUG(0,"%s(), ************* FRAME Errors ************ \n", __FUNCTION__ );
 			}
 							
 			if (status & LSR_CRC_ERROR) 
 			{
 				self->stats.rx_crc_errors++;
-				IRDA_DEBUG(0,__FUNCTION__ "(), ************* CRC Errors ************ \n");
+				IRDA_DEBUG(0,"%s(), ************* CRC Errors ************ \n", __FUNCTION__ );
 			}
 			
 			if(self->rcvFramesOverflow)
 			{
 				self->stats.rx_frame_errors++;
-				IRDA_DEBUG(0,__FUNCTION__ "(), ************* Overran DMA buffer ************ \n");								
+				IRDA_DEBUG(0,"%s(), ************* Overran DMA buffer ************ \n", __FUNCTION__ );								
 			}
 			if(len == 0)
 			{
 				self->stats.rx_frame_errors++;
-				IRDA_DEBUG(0,__FUNCTION__ "(), ********** Receive Frame Size = 0 ********* \n");
+				IRDA_DEBUG(0,"%s(), ********** Receive Frame Size = 0 ********* \n", __FUNCTION__ );
 			}
 		}	 
 		else 
@@ -1870,7 +1870,7 @@
 				val = inb(iobase+FIR_BSR);	
 				if ((val& BSR_FIFO_NOT_EMPTY)== 0x80) 
 				{
-					IRDA_DEBUG(0, __FUNCTION__ "(), ************* BSR_FIFO_NOT_EMPTY ************ \n");
+					IRDA_DEBUG(0, "%s(), ************* BSR_FIFO_NOT_EMPTY ************ \n", __FUNCTION__ );
 					
 					/* Put this entry back in fifo */
 					st_fifo->head--;
@@ -1934,7 +1934,7 @@
 	
 	switch_bank(iobase, BANK0);	
 		
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	return TRUE;
 }
 
@@ -1953,7 +1953,7 @@
 	int iobase;
 	__u32 speed;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	ASSERT(dev != NULL, return 0;);
 	
@@ -2000,7 +2000,7 @@
 
 	dev_kfree_skb(skb);
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	
 	return 0;	
 }
@@ -2019,7 +2019,7 @@
 	unsigned long flags;
 	int ret = 0;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	ASSERT(dev != NULL, return -1;);
 
@@ -2027,11 +2027,11 @@
 
 	ASSERT(self != NULL, return -1;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+	IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__ , dev->name, cmd);
 	
 	switch (cmd) {
 	case SIOCSBANDWIDTH: /* Set bandwidth */
-		IRDA_DEBUG(1, __FUNCTION__ "(), SIOCSBANDWIDTH\n");
+		IRDA_DEBUG(1, "%s(), SIOCSBANDWIDTH\n", __FUNCTION__ );
 		/*
 		 * This function will also be used by IrLAP to change the
 		 * speed, so we still must allow for speed change within
@@ -2045,13 +2045,13 @@
 		spin_unlock_irqrestore(&self->lock, flags);
 		break;
 	case SIOCSMEDIABUSY: /* Set media busy */
-		IRDA_DEBUG(1, __FUNCTION__ "(), SIOCSMEDIABUSY\n");
+		IRDA_DEBUG(1, "%s(), SIOCSMEDIABUSY\n", __FUNCTION__ );
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		irda_device_set_media_busy(self->netdev, TRUE);
 		break;
 	case SIOCGRECEIVING: /* Check if we are receiving right now */
-		IRDA_DEBUG(2, __FUNCTION__ "(), SIOCGRECEIVING\n");
+		IRDA_DEBUG(2, "%s(), SIOCGRECEIVING\n", __FUNCTION__ );
 		/* This is protected */
 		irq->ifr_receiving = ali_ircc_is_receiving(self);
 		break;
@@ -2059,7 +2059,7 @@
 		ret = -EOPNOTSUPP;
 	}
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	
 	return ret;
 }
@@ -2076,7 +2076,7 @@
 	int status = FALSE;
 	int iobase;		
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start -----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start -----------------\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return FALSE;);
 
@@ -2090,7 +2090,7 @@
 		if((inb(iobase+FIR_FIFO_FR) & 0x3f) != 0) 		
 		{
 			/* We are receiving something */
-			IRDA_DEBUG(1, __FUNCTION__ "(), We are receiving something\n");
+			IRDA_DEBUG(1, "%s(), We are receiving something\n", __FUNCTION__ );
 			status = TRUE;
 		}
 		switch_bank(iobase, BANK0);		
@@ -2102,7 +2102,7 @@
 	
 	spin_unlock_irqrestore(&self->lock, flags);
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );
 	
 	return status;
 }
@@ -2111,16 +2111,16 @@
 {
 	struct ali_ircc_cb *self = (struct ali_ircc_cb *) dev->priv;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 		
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 	
 	return &self->stats;
 }
 
 static void ali_ircc_suspend(struct ali_ircc_cb *self)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	MESSAGE("%s, Suspending\n", driver_name);
 
@@ -2131,12 +2131,12 @@
 
 	self->io.suspended = 1;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 static void ali_ircc_wakeup(struct ali_ircc_cb *self)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	if (!self->io.suspended)
 		return;
@@ -2147,14 +2147,14 @@
 
 	self->io.suspended = 0;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 static int ali_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data)
 {
         struct ali_ircc_cb *self = (struct ali_ircc_cb*) dev->data;
         
-        IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+        IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
         if (self) {
                 switch (rqst) {
@@ -2167,7 +2167,7 @@
                 }
         }
         
-        IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+        IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
         
 	return 0;
 }
@@ -2182,7 +2182,7 @@
 	
 	int iobase = self->io.fir_base; /* or sir_base */
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), -------- Start -------- ( Enable = %d )\n", enable);	
+	IRDA_DEBUG(2, "%s(), -------- Start -------- ( Enable = %d )\n", __FUNCTION__ , enable);	
 	
 	/* Enable the interrupt which we wish to */
 	if (enable){
@@ -2223,14 +2223,14 @@
 	else
 		outb(newMask, iobase+UART_IER);
 		
-	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 static void SIR2FIR(int iobase)
 {
 	//unsigned char tmp;
 		
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	/* Already protected (change_speed() or setup()), no need to lock.
 	 * Jean II */
@@ -2246,14 +2246,14 @@
 	//tmp |= 0x20;
 	//outb(tmp, iobase+FIR_LCR_B);	
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );	
 }
 
 static void FIR2SIR(int iobase)
 {
 	unsigned char val;
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
 	
 	/* Already protected (change_speed() or setup()), no need to lock.
 	 * Jean II */
@@ -2269,7 +2269,7 @@
 	val = inb(iobase+UART_LSR);
 	val = inb(iobase+UART_MSR);
 	
-	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");
+	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __FUNCTION__ );
 }
 
 MODULE_AUTHOR("Benjamin Kong <benjamin_kong@ali.com.tw>");
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/irda/irda-usb.c	Fri Sep 27 14:51:04 2002
@@ -36,14 +36,11 @@
  * This driver has been tested SUCCESSFULLY with the following drivers :
  *	o usb-uhci-hcd	(For Intel/Via USB controllers)
  *	o uhci-hcd	(Alternate/JE driver for Intel/Via USB controllers)
+ *	o ohci-hcd	(For other USB controllers)
  *
  * This driver has NOT been tested with the following drivers :
  *	o ehci-hcd	(USB 2.0 controllers)
  *
- * 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,
@@ -104,8 +101,8 @@
 
 /*------------------------------------------------------------------*/
 
-static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum);
-static void irda_usb_disconnect(struct usb_device *dev, void *ptr);
+static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf);
+static void irda_usb_disconnect(struct usb_interface *intf);
 static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
 static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
 static int irda_usb_open(struct irda_usb_cb *self);
@@ -1340,7 +1337,7 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Function irda_usb_find_class_desc(dev, ifnum)
+ * Function irda_usb_find_class_desc(intf)
  *
  *    Returns instance of IrDA class descriptor, or NULL if not found
  *
@@ -1348,8 +1345,9 @@
  * offer to us, describing their IrDA characteristics. We will use that in
  * irda_usb_init_qos()
  */
-static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
+static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf)
 {
+	struct usb_device *dev = interface_to_usbdev (intf);
 	struct irda_class_desc *desc;
 	int ret;
 
@@ -1368,7 +1366,8 @@
 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
 		IU_REQ_GET_CLASS_DESC,
 		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		0, ifnum, desc, sizeof(*desc), MSECS_TO_JIFFIES(500));
+		0, intf->altsetting->bInterfaceNumber, desc,
+		sizeof(*desc), MSECS_TO_JIFFIES(500));
 	
 	IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret);
 	if (ret < sizeof(*desc)) {
@@ -1403,9 +1402,10 @@
  * Note : it might be worth protecting this function by a global
  * spinlock... Or not, because maybe USB already deal with that...
  */
-static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
-			    const struct usb_device_id *id)
+static int irda_usb_probe(struct usb_interface *intf,
+			  const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct irda_usb_cb *self = NULL;
 	struct usb_interface_descriptor *interface;
 	struct irda_class_desc *irda_desc;
@@ -1430,7 +1430,7 @@
 		   (irda->present == 0) &&
 		   (irda->netopen == 0)) {
 			IRDA_DEBUG(0, "%s(), found a zombie instance !!!\n", __FUNCTION__);
-			irda_usb_disconnect(irda->usbdev, (void *) irda);
+			irda_usb_disconnect(irda->usbintf);
 		}
 	}
 
@@ -1445,7 +1445,7 @@
 	if(self == NULL) {
 		WARNING("Too many USB IrDA devices !!! (max = %d)\n",
 			   NIRUSB);
-		return NULL;
+		return -ENFILE;
 	}
 
 	/* Reset the instance */
@@ -1459,35 +1459,35 @@
 			int j;
 			for (j = 0; j < i; j++)
 				usb_free_urb(self->rx_urb[j]);
-			return NULL;
+			return -ENOMEM;
 		}
 	}
 	self->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!self->tx_urb) {
 		for (i = 0; i < IU_MAX_RX_URBS; i++)
 			usb_free_urb(self->rx_urb[i]);
-		return NULL;
+		return -ENOMEM;
 	}
 	self->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!self->speed_urb) {
 		for (i = 0; i < IU_MAX_RX_URBS; i++)
 			usb_free_urb(self->rx_urb[i]);
 		usb_free_urb(self->tx_urb);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	/* Is this really necessary? */
 	if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) {
 		err("set_configuration failed");
-		return NULL;
+		return -EIO;
 	}
 
 	/* Is this really necessary? */
 	/* Note : some driver do hardcode the interface number, some others
 	 * specify an alternate, but very few driver do like this.
 	 * Jean II */
-	ret = usb_set_interface(dev, ifnum, 0);
-	IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret);
+	ret = usb_set_interface(dev, intf->altsetting->bInterfaceNumber, 0);
+	IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->bInterfaceNumber, ret);
 	switch (ret) {
 		case 0:
 			break;
@@ -1497,33 +1497,35 @@
 			break;
 		default:
 			IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret);
-			return NULL;
+			return -EIO;
 			break;
 	}
 
 	/* Find our endpoints */
-	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	interface = &intf->altsetting[0];
 	if(!irda_usb_parse_endpoints(self, interface->endpoint,
 				     interface->bNumEndpoints)) {
 		ERROR("%s(), Bogus endpoints...\n", __FUNCTION__);
-		return NULL;
+		return -EIO;
 	}
 
 	/* Find IrDA class descriptor */
-	irda_desc = irda_usb_find_class_desc(dev, ifnum);
+	irda_desc = irda_usb_find_class_desc(intf);
 	if (irda_desc == NULL)
-		return NULL;
+		return -ENODEV;
 	
 	self->irda_desc =  irda_desc;	
 	self->present = 1;
 	self->netopen = 0;
 	self->capability = id->driver_info;
 	self->usbdev = dev;
+	self->usbintf = intf;
 	ret = irda_usb_open(self);
 	if (ret)
-		return NULL;
+		return -ENOMEM;
 
-	return self;
+	dev_set_drvdata(&intf->dev, self);
+	return 0;
 }
 
 /*------------------------------------------------------------------*/
@@ -1538,14 +1540,18 @@
  * So, we must make bloody sure that everything gets deactivated.
  * Jean II
  */
-static void irda_usb_disconnect(struct usb_device *dev, void *ptr)
+static void irda_usb_disconnect(struct usb_interface *intf)
 {
 	unsigned long flags;
-	struct irda_usb_cb *self = (struct irda_usb_cb *) ptr;
+	struct irda_usb_cb *self = dev_get_drvdata (&intf->dev);
 	int i;
 
 	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
+	dev_set_drvdata(&intf->dev, NULL);
+	if (!self)
+		return;
+
 	/* Make sure that the Tx path is not executing. - Jean II */
 	spin_lock_irqsave(&self->lock, flags);
 
@@ -1577,6 +1583,7 @@
 	irda_usb_close(self);
 	/* No longer attached to USB bus */
 	self->usbdev = NULL;
+	self->usbintf = NULL;
 
 	/* Clean up our urbs */
 	for (i = 0; i < IU_MAX_RX_URBS; i++)
@@ -1635,7 +1642,7 @@
 		/* If the Device is zombie */
 		if((irda->usbdev != NULL) && (irda->present == 0)) {
 			IRDA_DEBUG(0, "%s(), disconnect zombie now !\n", __FUNCTION__);
-			irda_usb_disconnect(irda->usbdev, (void *) irda);
+			irda_usb_disconnect(irda->usbintf);
 		}
 	}
 
diff -Nru a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c
--- a/drivers/net/irda/smc-ircc.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/net/irda/smc-ircc.c	Fri Sep 27 14:51:02 2002
@@ -170,7 +170,7 @@
 
 static int __init smc_access(unsigned short cfg_base,unsigned char reg)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	outb(reg, cfg_base);
 
@@ -184,7 +184,7 @@
 {
 	u8 devid,xdevid,rev; 
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	/* Leave configuration */
 
@@ -263,7 +263,7 @@
 	u8 mode;
 	int ret = -ENODEV;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	if (smc_probe(cfg_base,0xD,chips,type)==NULL)
 		return ret;
@@ -307,7 +307,7 @@
 	unsigned short sir_io;
 	int ret = -ENODEV;
 	
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	if (smc_probe(cfg_base,0x20,chips,type)==NULL)
 		return ret;
@@ -343,7 +343,7 @@
 static int __init smc_superio_fdc(unsigned short cfg_base)
 {
 	if (check_region(cfg_base, 2) < 0) {
-		IRDA_DEBUG(0, __FUNCTION__ ": can't get cfg_base of 0x%03x\n",
+		IRDA_DEBUG(0, "%s: can't get cfg_base of 0x%03x\n", __FUNCTION__ ,
 			   cfg_base);
 		return -1;
 	}
@@ -358,7 +358,7 @@
 {
 #if 0
 	if (check_region(cfg_base, 2) < 0) {
-		IRDA_DEBUG(0, __FUNCTION__ ": can't get cfg_base of 0x%03x\n",
+		IRDA_DEBUG(0, "%s: can't get cfg_base of 0x%03x\n", __FUNCTION__ ,
 			   cfg_base);
 		return -1;
 	}
@@ -380,7 +380,7 @@
 {
 	int ret=-ENODEV;
 
-	IRDA_DEBUG(0, __FUNCTION__ "\n");
+	IRDA_DEBUG(0, "%s\n", __FUNCTION__ );
 
 	dev_count=0;
 
@@ -403,8 +403,8 @@
 
 	/* Trys to open for all the SMC chipsets we know about */
 
-	IRDA_DEBUG(0, __FUNCTION__ 
-	" Try to open all known SMC chipsets\n");
+	IRDA_DEBUG(0, 
+	"%s Try to open all known SMC chipsets\n", __FUNCTION__ );
 
 	if (!smc_superio_fdc(0x3f0))
 		ret=0;
@@ -434,16 +434,16 @@
 	unsigned long flags;
 
 
-	IRDA_DEBUG(0, __FUNCTION__ "\n");
+	IRDA_DEBUG(0, "%s\n", __FUNCTION__ );
 
 	if (check_region(fir_base, CHIP_IO_EXTENT) < 0) {
-		IRDA_DEBUG(0, __FUNCTION__ ": can't get fir_base of 0x%03x\n",
+		IRDA_DEBUG(0, "%s: can't get fir_base of 0x%03x\n", __FUNCTION__ ,
 			   fir_base);
 		return -ENODEV;
 	}
 #if POSSIBLE_USED_BY_SERIAL_DRIVER
 	if (check_region(sir_base, CHIP_IO_EXTENT) < 0) {
-		IRDA_DEBUG(0, __FUNCTION__ ": can't get sir_base of 0x%03x\n",
+		IRDA_DEBUG(0, "%s: can't get sir_base of 0x%03x\n", __FUNCTION__ ,
 			   sir_base);
 		return -ENODEV;
 	}
@@ -461,8 +461,8 @@
 	dma     = config & 0x0f;
 
         if (high != 0x10 || low != 0xb8 || (chip != 0xf1 && chip != 0xf2)) { 
-	        IRDA_DEBUG(0, __FUNCTION__ 
-			   "(), addr 0x%04x - no device found!\n", fir_base);
+	        IRDA_DEBUG(0, 
+			   "%s(), addr 0x%04x - no device found!\n", __FUNCTION__ , fir_base);
 		return -ENODEV;
 	}
 	MESSAGE("SMC IrDA Controller found\n IrCC version %d.%d, "
@@ -470,8 +470,8 @@
 		chip & 0x0f, version, fir_base, sir_base, dma, irq);
 
 	if (dev_count>DIM(dev_self)) {
-	        IRDA_DEBUG(0, __FUNCTION__ 
-			   "(), to many devices!\n");
+	        IRDA_DEBUG(0, 
+			   "%s(), to many devices!\n", __FUNCTION__ );
 		return -ENOMEM;
 	}
 
@@ -610,7 +610,7 @@
 	struct ircc_cb *self = (struct ircc_cb *) priv;
 	struct net_device *dev;
 
-	IRDA_DEBUG(0, __FUNCTION__ "\n");
+	IRDA_DEBUG(0, "%s\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 
@@ -625,7 +625,7 @@
 
 	switch (speed) {
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", 
+		IRDA_DEBUG(0, "%s(), unknown baud rate of %d\n", __FUNCTION__ , 
 			   speed);
 		/* FALLTHROUGH */
 	case 9600:
@@ -641,19 +641,19 @@
 		ir_mode = IRCC_CFGA_IRDA_HDLC;
 		ctrl = IRCC_CRC;
 		fast = 0;
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
+		IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __FUNCTION__ );
 		break;
 	case 1152000:
 		ir_mode = IRCC_CFGA_IRDA_HDLC;
 		ctrl = IRCC_1152 | IRCC_CRC;
 		fast = 0;
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
+		IRDA_DEBUG(0, "%s(), handling baud of 1152000\n", __FUNCTION__ );
 		break;
 	case 4000000:
 		ir_mode = IRCC_CFGA_IRDA_4PPM;
 		ctrl = IRCC_CRC;
 		fast = IRCC_LCR_A_FAST;
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
+		IRDA_DEBUG(0, "%s(), handling baud of 4000000\n", __FUNCTION__ );
 		break;
 	}
 	
@@ -683,8 +683,8 @@
 		/* No need to lock, already locked - Jean II */
 		irport_start(self->irport);
 		
-	        IRDA_DEBUG(0, __FUNCTION__ 
-			   "(), using irport to change speed to %d\n", speed);
+	        IRDA_DEBUG(0, 
+			   "%s(), using irport to change speed to %d\n", __FUNCTION__ , speed);
 		irport_change_speed(self->irport, speed);
 	}	
 
@@ -792,7 +792,7 @@
 {
 	u8 ctrl;
 
-	IRDA_DEBUG(2, __FUNCTION__ "\n");
+	IRDA_DEBUG(2, "%s\n", __FUNCTION__ );
 #if 0	
 	/* Disable Rx */
 	register_bank(iobase, 0);
@@ -842,7 +842,7 @@
  */
 static void ircc_dma_xmit_complete(struct ircc_cb *self, int iobase)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "\n");
+	IRDA_DEBUG(2, "%s\n", __FUNCTION__ );
 #if 0
 	/* Disable Tx */
 	register_bank(iobase, 0);
@@ -928,7 +928,7 @@
 	struct sk_buff *skb;
 	int len, msgcnt;
 
-	IRDA_DEBUG(2, __FUNCTION__ "\n");
+	IRDA_DEBUG(2, "%s\n", __FUNCTION__ );
 #if 0
 	/* Disable Rx */
 	register_bank(iobase, 0);
@@ -937,7 +937,7 @@
 	register_bank(iobase, 0);
 	msgcnt = inb(iobase+IRCC_LCR_B) & 0x08;
 
-	IRDA_DEBUG(2, __FUNCTION__ ": dma count = %d\n",
+	IRDA_DEBUG(2, "%s: dma count = %d\n", __FUNCTION__ ,
 		   get_dma_residue(self->io->dma));
 
 	len = self->rx_buff.truesize - get_dma_residue(self->io->dma);
@@ -952,7 +952,7 @@
 		WARNING("%s(), bogus len=%d\n", __FUNCTION__, len);
 		return;
 	}
-	IRDA_DEBUG(2, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len);
+	IRDA_DEBUG(2, "%s: msgcnt = %d, len=%d\n", __FUNCTION__ , msgcnt, len);
 
 	skb = dev_alloc_skb(len+1);
 	if (!skb)  {
@@ -1012,7 +1012,7 @@
 	/* Disable interrupts */
 	outb(0, iobase+IRCC_IER);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), iir = 0x%02x\n", iir);
+	IRDA_DEBUG(2, "%s(), iir = 0x%02x\n", __FUNCTION__ , iir);
 
 	if (iir & IRCC_IIR_EOM) {
 		if (self->io->direction == IO_RECV)
@@ -1042,11 +1042,11 @@
 	int status = FALSE;
 	/* int iobase; */
 
-	IRDA_DEBUG(0, __FUNCTION__ "\n");
+	IRDA_DEBUG(0, "%s\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return FALSE;);
 
-	IRDA_DEBUG(0, __FUNCTION__ ": dma count = %d\n",
+	IRDA_DEBUG(0, "%s: dma count = %d\n", __FUNCTION__ ,
 		   get_dma_residue(self->io->dma));
 
 	status = (self->rx_buff.state != OUTSIDE_FRAME);
@@ -1067,7 +1067,7 @@
 	struct ircc_cb *self;
 	int iobase;
 
-	IRDA_DEBUG(0, __FUNCTION__ "\n");
+	IRDA_DEBUG(0, "%s\n", __FUNCTION__ );
 	
 	ASSERT(dev != NULL, return -1;);
 	irport = (struct irport_cb *) dev->priv;
@@ -1180,7 +1180,7 @@
 {
 	int iobase;
 
-	IRDA_DEBUG(0, __FUNCTION__ "\n");
+	IRDA_DEBUG(0, "%s\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 
@@ -1202,7 +1202,7 @@
 #endif
 
 	/* Release the PORT that this driver is using */
-	IRDA_DEBUG(0, __FUNCTION__ "(), releasing 0x%03x\n", iobase);
+	IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__ , iobase);
 
 	release_region(iobase, CHIP_IO_EXTENT);
 
@@ -1226,7 +1226,7 @@
 {
 	int i;
 
-	IRDA_DEBUG(0, __FUNCTION__ "\n");
+	IRDA_DEBUG(0, "%s\n", __FUNCTION__ );
 
 	for (i=0; i < 2; i++) {
 		if (dev_self[i])
diff -Nru a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c
--- a/drivers/net/irda/tekram.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/irda/tekram.c	Fri Sep 27 14:51:04 2002
@@ -66,7 +66,7 @@
 
 static void tekram_open(dongle_t *self, struct qos_info *qos)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
 	qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */	
@@ -77,7 +77,7 @@
 
 static void tekram_close(dongle_t *self)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	/* Power off dongle */
 	self->set_dtr_rts(self->dev, FALSE, FALSE);
@@ -113,12 +113,12 @@
 	__u8 byte;
 	int ret = 0;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(task != NULL, return -1;);
 
 	if (self->speed_task && self->speed_task != task) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n");
+		IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__ );
 		return MSECS_TO_JIFFIES(10);
 	} else
 		self->speed_task = task;
@@ -214,12 +214,12 @@
 	dongle_t *self = (dongle_t *) task->instance;
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(task != NULL, return -1;);
 
 	if (self->reset_task && self->reset_task != task) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n");
+		IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__ );
 		return MSECS_TO_JIFFIES(10);
 	} else
 		self->reset_task = task;
diff -Nru a/drivers/net/irda/toshoboe.c b/drivers/net/irda/toshoboe.c
--- a/drivers/net/irda/toshoboe.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/net/irda/toshoboe.c	Fri Sep 27 14:51:02 2002
@@ -92,7 +92,7 @@
 static void
 toshoboe_stopchip (struct toshoboe_cb *self)
 {
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   outb_p (0x0e, OBOE_REG_11);
 
@@ -113,7 +113,7 @@
 toshoboe_setbaud (struct toshoboe_cb *self, int baud)
 {
   unsigned long flags;
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   printk (KERN_WARNING "ToshOboe: setting baud to %d\n", baud);
 
@@ -183,7 +183,7 @@
 {
   __u32 physaddr;
 
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
 
   outb_p (0, OBOE_LOCK);
@@ -212,7 +212,7 @@
 static void
 toshoboe_enablebm (struct toshoboe_cb *self)
 {
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
   pci_set_master (self->pdev);
 }
 
@@ -221,7 +221,7 @@
 toshoboe_disablebm (struct toshoboe_cb *self)
 {
   __u8 command;
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
   command &= ~PCI_COMMAND_MASTER;
@@ -236,7 +236,7 @@
   int i;
   unsigned long flags;
 
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   save_flags (flags);
   cli ();
@@ -363,7 +363,7 @@
       return;
     }
 
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   irqstat = inb_p (OBOE_ISR);
 
@@ -463,7 +463,7 @@
 static int
 toshoboe_net_init (struct net_device *dev)
 {
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   /* Setup to be a normal IrDA network device driver */
   irda_device_setup (dev);
@@ -512,7 +512,7 @@
   struct toshoboe_cb *self;
   char hwname[32];
 
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   ASSERT (dev != NULL, return -1;
     );
@@ -559,7 +559,7 @@
 {
   struct toshoboe_cb *self;
 
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   ASSERT (dev != NULL, return -1;
     );
@@ -608,7 +608,7 @@
 
 	ASSERT(self != NULL, return -1;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+	IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__ , dev->name, cmd);
 	
 	/* Disable interrupts & save flags */
 	save_flags(flags);
@@ -654,7 +654,7 @@
   int i;
   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
 
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   ASSERT (self != NULL, return;
     );
@@ -704,7 +704,7 @@
   int ok = 0;
   int err;
 
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
+  IRDA_DEBUG (4, "%s()\n", __FUNCTION__ );
 
   if ((err=pci_enable_device(pci_dev)))
 	  return err;
@@ -733,7 +733,7 @@
   /* Lock the port that we need */
   if (NULL==request_region (self->io.sir_base, self->io.sir_ext, driver_name))
     {
-      IRDA_DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+      IRDA_DEBUG (0, "%s(), can't get iobase of 0x%03x\n", __FUNCTION__ ,
              self->io.sir_base);
 
       err = -EBUSY;
diff -Nru a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
--- a/drivers/net/irda/w83977af_ir.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/irda/w83977af_ir.c	Fri Sep 27 14:51:04 2002
@@ -116,7 +116,7 @@
 {
         int i;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	for (i=0; (io[i] < 2000) && (i < 4); i++) { 
 		int ioaddr = io[i];
@@ -138,7 +138,7 @@
 {
 	int i;
 
-        IRDA_DEBUG(4, __FUNCTION__ "()\n");
+        IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	for (i=0; i < 4; i++) {
 		if (dev_self[i])
@@ -160,7 +160,7 @@
 	void *ret;
 	int err;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	if (w83977af_probe(iobase, irq, dma) == -1)
 		return -1;
@@ -190,8 +190,8 @@
 	/* Lock the port that we need */
 	ret = request_region(self->io.fir_base, self->io.fir_ext, driver_name);
 	if (!ret) { 
-		IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
-		      self->io.fir_base);
+		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
+		      __FUNCTION__ , self->io.fir_base);
 		/* w83977af_cleanup( self);  */
 		return -ENODEV;
 	}
@@ -273,7 +273,7 @@
 {
 	int iobase;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
         iobase = self->io.fir_base;
 
@@ -297,8 +297,8 @@
 	}
 
 	/* Release the PORT that this driver is using */
-	IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", 
-	      self->io.fir_base);
+	IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n", 
+	      __FUNCTION__ , self->io.fir_base);
 	release_region(self->io.fir_base, self->io.fir_ext);
 
 	if (self->tx_buff.head)
@@ -318,7 +318,7 @@
 	int i;
   	
  	for (i=0; i < 2; i++) {
- 		IRDA_DEBUG( 0, __FUNCTION__ "()\n");
+ 		IRDA_DEBUG( 0, "%s()\n", __FUNCTION__ );
 #ifdef CONFIG_USE_W977_PNP
  		/* Enter PnP configuration mode */
 		w977_efm_enter(efbase[i]);
@@ -405,7 +405,7 @@
 			return 0;
 		} else {
 			/* Try next extented function register address */
-			IRDA_DEBUG( 0, __FUNCTION__ "(), Wrong chip version");
+			IRDA_DEBUG( 0, "%s(), Wrong chip version", __FUNCTION__ );
 		}
   	}   	
 	return -1;
@@ -441,19 +441,19 @@
 	case 115200: outb(0x01, iobase+ABLL); break;
 	case 576000:
 		ir_mode = HCR_MIR_576;
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
+		IRDA_DEBUG(0, "%s(), handling baud of 576000\n", __FUNCTION__ );
 		break;
 	case 1152000:
 		ir_mode = HCR_MIR_1152;
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
+		IRDA_DEBUG(0, "%s(), handling baud of 1152000\n", __FUNCTION__ );
 		break;
 	case 4000000:
 		ir_mode = HCR_FIR;
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
+		IRDA_DEBUG(0, "%s(), handling baud of 4000000\n", __FUNCTION__ );
 		break;
 	default:
 		ir_mode = HCR_FIR;
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed);
+		IRDA_DEBUG(0, "%s(), unknown baud rate of %d\n", __FUNCTION__ , speed);
 		break;
 	}
 
@@ -503,7 +503,7 @@
 
 	iobase = self->io.fir_base;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, 
+	IRDA_DEBUG(4, "%s(%ld), skb->len=%d\n", __FUNCTION__ , jiffies, 
 		   (int) skb->len);
 	
 	/* Lock transmit buffer */
@@ -550,7 +550,7 @@
 			outb(ICR_ETMRI, iobase+ICR);
 		} else {
 #endif
-			IRDA_DEBUG(4,__FUNCTION__ "(%ld), mtt=%d\n", jiffies, mtt);
+			IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __FUNCTION__ , jiffies, mtt);
 			if (mtt)
 				udelay(mtt);
 
@@ -591,7 +591,7 @@
 	unsigned long flags;
 	__u8 hcr;
 #endif
-        IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", self->tx_buff.len);
+        IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__ , self->tx_buff.len);
 
 	/* Save current set */
 	set = inb(iobase+SSR);
@@ -643,19 +643,19 @@
 	int actual = 0;
 	__u8 set;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	/* Save current bank */
 	set = inb(iobase+SSR);
 
 	switch_bank(iobase, SET0);
 	if (!(inb_p(iobase+USR) & USR_TSRE)) {
-		IRDA_DEBUG(4, __FUNCTION__ 
-			   "(), warning, FIFO not empty yet!\n");
+		IRDA_DEBUG(4,
+			   "%s(), warning, FIFO not empty yet!\n", __FUNCTION__  );
 
 		fifo_size -= 17;
-		IRDA_DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", 
-			   fifo_size);
+		IRDA_DEBUG(4, "%s(), %d bytes left in tx fifo\n", 
+			   __FUNCTION__ , fifo_size);
 	}
 
 	/* Fill FIFO with current frame */
@@ -664,8 +664,8 @@
 		outb(buf[actual++], iobase+TBR);
 	}
         
-	IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", 
-		   fifo_size, actual, len);
+	IRDA_DEBUG(4, "%s(), fifo_size %d ; %d sent of %d\n", 
+		   __FUNCTION__ , fifo_size, actual, len);
 
 	/* Restore bank */
 	outb(set, iobase+SSR);
@@ -685,7 +685,7 @@
 	int iobase;
 	__u8 set;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(%ld)\n", jiffies);
+	IRDA_DEBUG(4, "%s(%ld)\n", __FUNCTION__ , jiffies);
 
 	ASSERT(self != NULL, return;);
 
@@ -700,7 +700,7 @@
 	
 	/* Check for underrrun! */
 	if (inb(iobase+AUDR) & AUDR_UNDR) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), Transmit underrun!\n");
+		IRDA_DEBUG(0, "%s(), Transmit underrun!\n", __FUNCTION__ );
 		
 		self->stats.tx_errors++;
 		self->stats.tx_fifo_errors++;
@@ -741,7 +741,7 @@
 #endif
 	ASSERT(self != NULL, return -1;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "\n");
+	IRDA_DEBUG(4, "%s\n", __FUNCTION__ );
 
 	iobase= self->io.fir_base;
 
@@ -812,7 +812,7 @@
 	__u8 set;
 	__u8 status;
 
-	IRDA_DEBUG(4, __FUNCTION__ "\n");
+	IRDA_DEBUG(4, "%s\n", __FUNCTION__ );
 
 	st_fifo = &self->st_fifo;
 
@@ -939,7 +939,7 @@
 	__u8 byte = 0x00;
 	int iobase;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	
@@ -966,7 +966,7 @@
 	__u8 set;
 	int iobase;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), isr=%#x\n", isr);
+	IRDA_DEBUG(4, "%s(), isr=%#x\n", __FUNCTION__ , isr);
 	
 	iobase = self->io.fir_base;
 	/* Transmit FIFO low on data */
@@ -1002,8 +1002,8 @@
 	if (isr & ISR_TXEMP_I) {		
 		/* Check if we need to change the speed? */
 		if (self->new_speed) {
-			IRDA_DEBUG(2, __FUNCTION__ 
-				   "(), Changing speed!\n");
+			IRDA_DEBUG(2,
+				   "%s(), Changing speed!\n", __FUNCTION__ );
 			w83977af_change_speed(self, self->new_speed);
 			self->new_speed = 0;
 		}
@@ -1185,7 +1185,7 @@
  */
 static int w83977af_net_init(struct net_device *dev)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	/* Set up to be a normal IrDA network device driver */
 	irda_device_setup(dev);
@@ -1209,7 +1209,7 @@
 	char hwname[32];
 	__u8 set;
 	
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(dev != NULL, return -1;);
 	self = (struct w83977af_ir *) dev->priv;
@@ -1274,7 +1274,7 @@
 	int iobase;
 	__u8 set;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(dev != NULL, return -1;);
 	
@@ -1331,7 +1331,7 @@
 
 	ASSERT(self != NULL, return -1;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+	IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__ , dev->name, cmd);
 	
 	spin_lock_irqsave(&self->lock, flags);
 
diff -Nru a/drivers/net/sb1000.c b/drivers/net/sb1000.c
--- a/drivers/net/sb1000.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/net/sb1000.c	Fri Sep 27 14:51:03 2002
@@ -275,7 +275,7 @@
  * SB1000 hardware routines to be used during open/configuration phases
  */
 
-const int TimeOutJiffies = (int)(8.75 * HZ);
+const int TimeOutJiffies = (875 * HZ) / 100;
 
 static inline void nicedelay(unsigned long usecs)
 {
@@ -295,10 +295,10 @@
 	timeout = jiffies + TimeOutJiffies;
 	while (a & 0x80 || a & 0x40) {
 		/* a little sleep */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(0);
+		yield();
+
 		a = inb(ioaddr[0] + 7);
-		if (jiffies >= timeout) {
+		if (time_after_eq(jiffies, timeout)) {
 			printk(KERN_WARNING "%s: card_wait_for_busy_clear timeout\n",
 				name);
 			return -ETIME;
@@ -319,10 +319,10 @@
 	timeout = jiffies + TimeOutJiffies;
 	while (a & 0x80 || !(a & 0x40)) {
 		/* a little sleep */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(0);
+		yield();
+
 		a = inb(ioaddr[1] + 6);
-		if (jiffies >= timeout) {
+		if (time_after_eq(jiffies, timeout)) {
 			printk(KERN_WARNING "%s: card_wait_for_ready timeout\n",
 				name);
 			return -ETIME;
@@ -396,7 +396,7 @@
 
 	timeout = jiffies + Sb1000TimeOutJiffies;
 	while (inb(ioaddr[1] + 6) & 0x80) {
-		if (jiffies >= timeout) {
+		if (time_after_eq(jiffies, timeout)) {
 			printk(KERN_WARNING "%s: sb1000_wait_for_ready timeout\n",
 				name);
 			return -ETIME;
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/sis900.c	Fri Sep 27 14:51:04 2002
@@ -573,8 +573,8 @@
 
 	if(status & MII_STAT_LINK){
 		while (poll_bit) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(0);
+			yield();
+
 			poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit);
 			if (jiffies >= timeout) {
 				printk(KERN_WARNING "%s: reset phy and link down now\n", net_dev->name);
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/net/wireless/airo.c	Fri Sep 27 14:51:03 2002
@@ -80,6 +80,9 @@
 #include <linux/delay.h>
 #endif
 
+/* Hack to do some power saving */
+#define POWER_ON_DOWN
+
 /* As you can see this list is HUGH!
    I really don't know what a lot of these counts are about, but they
    are all here for completeness.  If the IGNLABEL macro is put in
@@ -469,7 +472,7 @@
 typedef struct {
 	u16 len;
 	u16 kindex;
-	u8 mac[6];
+	u8 mac[ETH_ALEN];
 	u16 klen;
 	u8 key[16];
 } WepKeyRid;
@@ -519,7 +522,7 @@
 #define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
 	u16 fragThresh;
 	u16 rtsThres;
-	u8 macAddr[6];
+	u8 macAddr[ETH_ALEN];
 	u8 rates[8];
 	u16 shortRetryLimit;
 	u16 longRetryLimit;
@@ -614,14 +617,14 @@
 
 typedef struct {
 	u16 len;
-	u8 mac[6];
+	u8 mac[ETH_ALEN];
 	u16 mode;
 	u16 errorCode;
 	u16 sigQuality;
 	u16 SSIDlen;
 	char SSID[32];
 	char apName[16];
-	char bssid[4][6];
+	char bssid[4][ETH_ALEN];
 	u16 beaconPeriod;
 	u16 dimPeriod;
 	u16 atimDuration;
@@ -650,7 +653,7 @@
 
 typedef struct {
 	u16 len;
-	u8 ap[4][6];
+	u8 ap[4][ETH_ALEN];
 } APListRid;
 
 typedef struct {
@@ -661,11 +664,11 @@
 	char manName[32];
 	char prodName[16];
 	char prodVer[8];
-	char factoryAddr[6];
-	char aironetAddr[6];
+	char factoryAddr[ETH_ALEN];
+	char aironetAddr[ETH_ALEN];
 	u16 radioType;
 	u16 country;
-	char callid[6];
+	char callid[ETH_ALEN];
 	char supportedRates[8];
 	char rxDiversity;
 	char txDiversity;
@@ -688,7 +691,7 @@
 #define RADIO_DS 2 /* Direct sequence radio type */
 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
   u16 radioType;
-  u8 bssid[6]; /* Mac address of the BSS */
+  u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
   u8 zero;
   u8 ssidLen;
   u8 ssid[32];
@@ -891,10 +894,12 @@
 	struct airo_info *next;
         spinlock_t aux_lock;
         unsigned long flags;
-#define FLAG_PROMISC   IFF_PROMISC
-#define FLAG_RADIO_OFF 0x02
-#define FLAG_LOCKED    2
-#define FLAG_802_11	   0x10
+#define FLAG_PROMISC   IFF_PROMISC	/* 0x100 - include/linux/if.h */
+#define FLAG_RADIO_OFF 0x02		/* User disabling of MAC */
+#define FLAG_RADIO_DOWN 0x08		/* ifup/ifdown disabling of MAC */
+#define FLAG_LOCKED    2		/* 0x04 - use as a bit offset */
+#define FLAG_FLASHING  0x10
+#define FLAG_802_11    0x200
 	int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
 			int whichbap);
 	unsigned short *flash;
@@ -914,7 +919,7 @@
 	struct tq_struct	event_task;
 #ifdef WIRELESS_SPY
 	int			spy_number;
-	u_char			spy_address[IW_MAX_SPY][6];
+	u_char			spy_address[IW_MAX_SPY][ETH_ALEN];
 	struct iw_quality	spy_stat[IW_MAX_SPY];
 #endif /* WIRELESS_SPY */
 #endif /* WIRELESS_EXT */
@@ -1121,20 +1126,26 @@
 
 static int airo_open(struct net_device *dev) {
 	struct airo_info *info = dev->priv;
+	Resp rsp;
+
+	if (info->flags & FLAG_FLASHING)
+		return -EIO;
 
 	/* Make sure the card is configured.
 	 * Wireless Extensions may postpone config changes until the card
 	 * is open (to pipeline changes and speed-up card setup). If
 	 * those changes are not yet commited, do it now - Jean II */
 	if(info->need_commit) {
-		Resp rsp;
 		disable_MAC(info);
 		writeConfigRid(info);
-		enable_MAC(info, &rsp);
 	}
 
-	if (info->wifidev != dev)
+	if (info->wifidev != dev) {
+		/* Power on the MAC controller (which may have been disabled) */
+		info->flags &= ~FLAG_RADIO_DOWN;
 		enable_interrupts(info);
+	}
+	enable_MAC(info, &rsp);
 
 	netif_start_queue(dev);
 	return 0;
@@ -1413,8 +1424,18 @@
 
 	netif_stop_queue(dev);
 
-	if (ai->wifidev != dev)
+	if (ai->wifidev != dev) {
+#ifdef POWER_ON_DOWN
+		/* Shut power to the card. The idea is that the user can save
+		 * power when he doesn't need the card with "ifconfig down".
+		 * That's the method that is most friendly towards the network
+		 * stack (i.e. the network stack won't try to broadcast
+		 * anything on the interface and routes are gone. Jean II */
+		ai->flags |= FLAG_RADIO_DOWN;
+		disable_MAC(ai);
+#endif
 		disable_interrupts( ai );
+	}
 	return 0;
 }
 
@@ -1575,12 +1596,16 @@
 		}
 	}
 
-	if (probe && setup_card( ai, dev->dev_addr ) != SUCCESS ) {
-		printk( KERN_ERR "airo: MAC could not be enabled\n" );
-		rc = -EIO;
-		goto err_out_res;
-	} else
+	if (probe) {
+		if ( setup_card( ai, dev->dev_addr ) != SUCCESS ) {
+			printk( KERN_ERR "airo: MAC could not be enabled\n" );
+			rc = -EIO;
+			goto err_out_res;
+		}
+	} else {
 		ai->bap_read = fast_bap_read;
+		ai->flags |= FLAG_FLASHING;
+	}
 
 	rc = register_netdev(dev);
 	if (rc)
@@ -1849,7 +1874,7 @@
 							hdrlen = 24;
 					}
 				} else
-					hdrlen = 12;
+					hdrlen = ETH_ALEN * 2;
 
 				skb = dev_alloc_skb( len + hdrlen + 2 );
 				if ( !skb ) {
@@ -1879,7 +1904,8 @@
 				} else {
 					bap_read (apriv, buffer,len + hdrlen,BAP0);
 				}
-				OUT4500( apriv, EVACK, EV_RX);
+			}
+			if (len) {
 #ifdef WIRELESS_SPY
 				if (apriv->spy_number > 0) {
 					int i;
@@ -1888,7 +1914,7 @@
 					sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6);
 
 					for (i=0; i<apriv->spy_number; i++)
-						if (!memcmp(sa,apriv->spy_address[i],6))
+						if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN))
 						{
 							if (!(apriv->flags & FLAG_802_11)) {
 								bap_setup (apriv, fid, 8, BAP0);
@@ -1905,6 +1931,8 @@
 						}
 				}
 #endif /* WIRELESS_SPY  */
+				OUT4500( apriv, EVACK, EV_RX);
+
 				if (apriv->flags & FLAG_802_11) {
 					skb->mac.raw = skb->data;
 					skb->pkt_type = PACKET_OTHERHOST;
@@ -1994,7 +2022,13 @@
 	int rc;
         Cmd cmd;
 
-        if (ai->flags&FLAG_RADIO_OFF) return SUCCESS;
+	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
+	 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
+	 * Note : we could try to use !netif_running(dev) in enable_MAC()
+	 * instead of this flag, but I don't trust it *within* the
+	 * open/close functions, and testing both flags together is
+	 * "cheaper" - Jean II */
+	if (ai->flags & (FLAG_RADIO_OFF|FLAG_RADIO_DOWN)) return SUCCESS;
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.cmd = MAC_ENABLE;
 	if (test_bit(FLAG_LOCKED, &ai->flags) != 0)
@@ -2113,7 +2147,7 @@
 		ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
 
 		/* Save off the MAC */
-		for( i = 0; i < 6; i++ ) {
+		for( i = 0; i < ETH_ALEN; i++ ) {
 			mac[i] = ai->config.macAddr[i];
 		}
 
@@ -2161,7 +2195,10 @@
 	if ( status != SUCCESS ) return ERROR;
 
 	status = enable_MAC(ai, &rsp);
-	if ( status != SUCCESS ) return ERROR;
+	if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
+		printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
+		return ERROR;
+	}
 
 	/* Grab the initial wep key, we gotta save it for auto_wep */
 	rc = readWepKeyRid(ai, &wkr, 1);
@@ -2505,7 +2542,7 @@
 	u16 txFid = len;
 	len >>= 16;
 
-	if (len < 12) {
+	if (len < ETH_ALEN * 2) {
 		printk( KERN_WARNING "Short packet %d\n", len );
 		return ERROR;
 	}
@@ -2534,7 +2571,7 @@
 	Resp rsp;
 	int hdrlen;
 	struct {
-		u8 addr4[6];
+		u8 addr4[ETH_ALEN];
 		u16 gaplen;
 		u8 gap[6];
 	} gap;
@@ -3402,7 +3439,7 @@
 
 static int set_wep_key(struct airo_info *ai, u16 index,
 		       const char *key, u16 keylen, int perm ) {
-	static const unsigned char macaddr[6] = { 0x01, 0, 0, 0, 0, 0 };
+	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
 	WepKeyRid wkr;
 
 	memset(&wkr, 0, sizeof(wkr));
@@ -3419,7 +3456,7 @@
 		wkr.kindex = index;
 		wkr.klen = keylen;
 		memcpy( wkr.key, key, keylen );
-		memcpy( wkr.mac, macaddr, 6 );
+		memcpy( wkr.mac, macaddr, ETH_ALEN );
 		printk(KERN_INFO "Setting key %d\n", index);
 	}
 
@@ -3714,7 +3751,7 @@
 	u16 linkstat = IN4500(apriv, LINKSTAT);
 	Resp rsp;
 
-	if (linkstat != 0x400 ) {
+	if (!(apriv->flags & FLAG_FLASHING) && (linkstat != 0x400)) {
 /* We don't have a link so try changing the authtype */
 		if (down_trylock(&apriv->sem) != 0) {
 			apriv->timer.expires = RUN_AT(1);
@@ -4029,11 +4066,11 @@
 	Cmd cmd;
 	Resp rsp;
 	APListRid APList_rid;
-	static const unsigned char bcast[6] = { 255, 255, 255, 255, 255, 255 };
+	static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
 
 	if (awrq->sa_family != ARPHRD_ETHER)
 		return -EINVAL;
-	else if (!memcmp(bcast, awrq->sa_data, 6)) {
+	else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
 		memset(&cmd, 0, sizeof(cmd));
 		cmd.cmd=CMD_LOSE_SYNC;
 		if (down_interruptible(&local->sem))
@@ -4043,7 +4080,7 @@
 	} else {
 		memset(&APList_rid, 0, sizeof(APList_rid));
 		APList_rid.len = sizeof(APList_rid);
-		memcpy(APList_rid.ap[0], awrq->sa_data, 6);
+		memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
 		disable_MAC(local);
 		writeAPListRid(local, &APList_rid);
 		enable_MAC(local, &rsp);
@@ -4066,7 +4103,7 @@
 	readStatusRid(local, &status_rid);
 
 	/* Tentative. This seems to work, wow, I'm lucky !!! */
-	memcpy(awrq->sa_data, status_rid.bssid[0], 6);
+	memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
 	awrq->sa_family = ARPHRD_ETHER;
 
 	return 0;
@@ -4850,7 +4887,7 @@
 		if (readBSSListRid(local, loseSync, &BSSList))
 			break;
 		loseSync = 0;
-		memcpy(address[i].sa_data, BSSList.bssid, 6);
+		memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
 		address[i].sa_family = ARPHRD_ETHER;
 		if (local->rssi)
 			qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
@@ -4880,7 +4917,7 @@
 			      | status_rid.bssid[i][5]);
 		     i++) {
 			memcpy(address[i].sa_data,
-			       status_rid.bssid[i], 6);
+			       status_rid.bssid[i], ETH_ALEN);
 			address[i].sa_family = ARPHRD_ETHER;
 		}
 	} else {
@@ -5105,7 +5142,7 @@
 
 		/* Copy addresses */
 		for (i = 0; i < dwrq->length; i++)
-			memcpy(local->spy_address[i], address[i].sa_data, 6);
+			memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN);
 		/* Reset stats */
 		memset(local->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
 	}
@@ -5132,7 +5169,7 @@
 
 	/* Copy addresses. */
 	for(i = 0; i < local->spy_number; i++) 	{
-		memcpy(address[i].sa_data, local->spy_address[i], 6);
+		memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN);
 		address[i].sa_family = AF_UNIX;
 	}
 	/* Copy stats to the user buffer (just after). */
@@ -5685,6 +5722,10 @@
 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 	unsigned short ridcode;
 	unsigned char iobuf[2048];
+	struct airo_info *ai = dev->priv;
+
+	if (ai->flags & FLAG_FLASHING)
+		return -EIO;
 
 	switch(comp->command)
 	{
@@ -5731,6 +5772,7 @@
  */
 
 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
+	struct airo_info *ai = dev->priv;
 	int  ridcode;
 	Resp      rsp;
 	static int (* writer)(struct airo_info *, u16 rid, const void *, int);
@@ -5740,6 +5782,9 @@
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 
+	if (ai->flags & FLAG_FLASHING)
+		return -EIO;
+
 	ridcode = 0;
 	writer = do_writerid;
 
@@ -5899,6 +5944,8 @@
  */
 
 int setflashmode (struct airo_info *ai) {
+	ai->flags |= FLAG_FLASHING;
+
 	OUT4500(ai, SWS0, FLASH_COMMAND);
 	OUT4500(ai, SWS1, FLASH_COMMAND);
 	if (probe) {
@@ -5913,6 +5960,7 @@
 	schedule_timeout (HZ/2); /* 500ms delay */
 
 	if(!waitbusy(ai)) {
+		ai->flags &= ~FLAG_FLASHING;
 		printk(KERN_INFO "Waitbusy hang after setflash mode\n");
 		return -EIO;
 	}
@@ -6018,6 +6066,7 @@
 
 	set_current_state (TASK_UNINTERRUPTIBLE);
 	schedule_timeout (HZ);          /* Added 12/7/00 */
+	ai->flags &= ~FLAG_FLASHING;
 	status = setup_card(ai, dev->dev_addr);
 
 	for( i = 0; i < MAX_FIDS; i++ ) {
diff -Nru a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
--- a/drivers/net/wireless/airport.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/wireless/airport.c	Fri Sep 27 14:51:04 2002
@@ -1,4 +1,4 @@
-/* airport.c 0.11b
+/* airport.c 0.13
  *
  * A driver for "Hermes" chipset based Apple Airport wireless
  * card.
@@ -30,7 +30,6 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
-#include <linux/list.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 
@@ -39,22 +38,15 @@
 #include <asm/pmac_feature.h>
 #include <asm/irq.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
-static char version[] __initdata = "airport.c 0.11b (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
-MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
-MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
-MODULE_LICENSE("Dual MPL/GPL");
-
 #define AIRPORT_IO_LEN	(0x1000)	/* one page */
 
 struct airport {
-	struct device_node* node;
+	struct device_node *node;
 	void *vaddr;
 	int irq_requested;
 	int ndev_registered;
-	int open;
 };
 
 #ifdef CONFIG_PMAC_PBOOK
@@ -70,101 +62,77 @@
 
 static struct net_device *airport_attach(struct device_node *of_node);
 static void airport_detach(struct net_device *dev);
-static int airport_open(struct net_device *dev);
-static int airport_stop(struct net_device *dev);
-
-/*
-   A linked list of "instances" of the dummy device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
 
 static struct net_device *airport_dev;
 
-static int
-airport_open(struct net_device *dev)
-{
-	struct orinoco_private *priv = dev->priv;
-	struct airport* card = (struct airport *)priv->card;
-	int rc;
-
-	TRACE_ENTER(dev->name);
-
-	netif_device_attach(dev);
-
-	rc = orinoco_reset(priv);
-	if (rc)
-		airport_stop(dev);
-	else {
-		card->open = 1;
-		netif_start_queue(dev);
-	}
-
-	TRACE_EXIT(dev->name);
-
-	return rc;
-}
-
-static int
-airport_stop(struct net_device *dev)
-{
-	struct orinoco_private *priv = dev->priv;
-	struct airport* card = (struct airport *)priv->card;
-
-	TRACE_ENTER(dev->name);
-
-	netif_stop_queue(dev);
-	orinoco_shutdown(priv);
-	card->open = 0;
-
-	TRACE_EXIT(dev->name);
-
-	return 0;
-}
-
 #ifdef CONFIG_PMAC_PBOOK
 static int
 airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
 	struct net_device *dev = airport_dev;
-	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
-	struct hermes *hw = &priv->hw;
-	struct airport* card = (struct airport *)priv->card;
-	int rc;
+	struct orinoco_private *priv = dev->priv;
+	struct airport *card = priv->card;
+	unsigned long flags;
+	int err;
 	
 	if (! airport_dev)
 		return PBOOK_SLEEP_OK;
 
 	switch (when) {
-	case PBOOK_SLEEP_REQUEST:
-		break;
-	case PBOOK_SLEEP_REJECT:
-		break;
 	case PBOOK_SLEEP_NOW:
-		printk(KERN_INFO "%s: Airport entering sleep mode\n", dev->name);
-		if (card->open) {
-			netif_stop_queue(dev);
-			orinoco_shutdown(priv);
-			netif_device_detach(dev);
+		printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name);
+
+		err = orinoco_lock(priv, &flags);
+		if (err) {
+			printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n",
+			       dev->name);
+			break;
 		}
+
+		err = __orinoco_down(dev);
+		if (err)
+			printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
+			       dev->name, err);
+
+		netif_device_detach(dev);
+
+		priv->hw_unavailable = 1;
+
+		orinoco_unlock(priv, &flags);
+
 		disable_irq(dev->irq);
 		pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0);
 		break;
+
 	case PBOOK_WAKE:
-		printk(KERN_INFO "%s: Airport waking up\n", dev->name);
+		printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
 		pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1);
 		mdelay(200);
-		hermes_reset(hw);
-		rc = orinoco_reset(priv);
-		if (rc)
-			printk(KERN_ERR "airport: Error %d re-initing card !\n", rc);
-		else if (card->open)
-			netif_device_attach(dev);
+
 		enable_irq(dev->irq);
+
+		err = orinoco_reinit_firmware(dev);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
+			       dev->name, err);
+			break;
+		}
+
+		spin_lock_irqsave(&priv->lock, flags);
+
+		netif_device_attach(dev);
+
+		if (priv->open) {
+			err = __orinoco_up(dev);
+			if (err)
+				printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
+				       dev->name, err);
+		}
+
+		priv->hw_unavailable = 0;
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+
 		break;
 	}
 	return PBOOK_SLEEP_OK;
@@ -172,7 +140,7 @@
 #endif /* CONFIG_PMAC_PBOOK */
 
 static struct net_device *
-airport_attach(struct device_node* of_node)
+airport_attach(struct device_node *of_node)
 {
 	struct orinoco_private *priv;
 	struct net_device *dev;
@@ -180,15 +148,13 @@
 	unsigned long phys_addr;
 	hermes_t *hw;
 
-	TRACE_ENTER("orinoco");
-
 	if (of_node->n_addrs < 1 || of_node->n_intrs < 1) {
 		printk(KERN_ERR "airport: wrong interrupt/addresses in OF tree\n");
 		return NULL;
 	}
 
 	/* Allocate space for private device-specific data */
-	dev = alloc_orinocodev(sizeof(*card));
+	dev = alloc_orinocodev(sizeof(*card), NULL);
 	if (! dev) {
 		printk(KERN_ERR "airport: can't allocate device datas\n");
 		return NULL;
@@ -204,17 +170,14 @@
 		kfree(dev);
 		return NULL;
 	}
-	
+
 	dev->name[0] = '\0';	/* register_netdev will give us an ethX name */
 	SET_MODULE_OWNER(dev);
 
-	/* Overrides */
-	dev->open = airport_open;
-	dev->stop = airport_stop;
-
 	/* Setup interrupts & base address */
 	dev->irq = of_node->intrs[0].line;
-	phys_addr = of_node->addrs[0].address; /* Physical address */
+	phys_addr = of_node->addrs[0].address;  /* Physical address */
+	printk(KERN_DEBUG "Airport at physical address %lx\n", phys_addr);
 	dev->base_addr = phys_addr;
 	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
 	if (! card->vaddr) {
@@ -231,14 +194,14 @@
 	schedule_timeout(HZ);
 
 	/* Reset it before we get the interrupt */
-	hermes_reset(hw);
+	hermes_init(hw);
 
 	if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
 		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq);
 		goto failed;
 	}
 	card->irq_requested = 1;
-	
+
 	/* Tell the stack we exist */
 	if (register_netdev(dev) != 0) {
 		printk(KERN_ERR "airport: register_netdev() failed\n");
@@ -248,7 +211,7 @@
 	card->ndev_registered = 1;
 
 	/* And give us the proc nodes for debugging */
-	if (orinoco_proc_dev_init(priv) != 0)
+	if (orinoco_proc_dev_init(dev) != 0)
 		printk(KERN_ERR "airport: Failed to create /proc node for %s\n",
 		       dev->name);
 
@@ -257,7 +220,7 @@
 #endif
 	return dev;
 	
-failed:
+ failed:
 	airport_detach(dev);
 	return NULL;
 }				/* airport_attach */
@@ -273,7 +236,7 @@
 	struct airport *card = priv->card;
 
 	/* Unregister proc entry */
-	orinoco_proc_dev_cleanup(priv);
+	orinoco_proc_dev_cleanup(dev);
 
 #ifdef CONFIG_PMAC_PBOOK
 	pmu_unregister_sleep_notifier(&airport_sleep_notifier);
@@ -281,7 +244,7 @@
 	if (card->ndev_registered)
 		unregister_netdev(dev);
 	card->ndev_registered = 0;
-	
+
 	if (card->irq_requested)
 		free_irq(dev->irq, priv);
 	card->irq_requested = 0;
@@ -289,22 +252,28 @@
 	if (card->vaddr)
 		iounmap(card->vaddr);
 	card->vaddr = 0;
-	
+
 	dev->base_addr = 0;
 
 	release_OF_resource(card->node, 0);
-	
+
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0);
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ);
-	
+
 	kfree(dev);
 }				/* airport_detach */
 
+static char version[] __initdata = "airport.c 0.13 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
+MODULE_LICENSE("Dual MPL/GPL");
+EXPORT_NO_SYMBOLS;
+
 static int __init
 init_airport(void)
 {
-	struct device_node* airport_node;
+	struct device_node *airport_node;
 
 	printk(KERN_DEBUG "%s\n", version);
 
diff -Nru a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
--- a/drivers/net/wireless/hermes.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/net/wireless/hermes.c	Fri Sep 27 14:51:03 2002
@@ -45,7 +45,6 @@
 #include <linux/threads.h>
 #include <linux/smp.h>
 #include <asm/io.h>
-#include <linux/ptrace.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -53,7 +52,7 @@
 
 #include "hermes.h"
 
-static char version[] __initdata = "hermes.c: 5 Apr 2002 David Gibson <hermes@gibson.dropbear.id.au>";
+static char version[] __initdata = "hermes.c: 4 Jul 2002 David Gibson <hermes@gibson.dropbear.id.au>";
 MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 #ifdef MODULE_LICENSE
@@ -70,14 +69,14 @@
  * Debugging helpers
  */
 
+#define IO_TYPE(hw)	((hw)->io_space ? "IO " : "MEM ")
+#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %s0x%x: " , IO_TYPE(hw), hw->iobase); \
+			printk(stuff);} while (0)
+
 #undef HERMES_DEBUG
 #ifdef HERMES_DEBUG
-
 #include <stdarg.h>
 
-#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ 0x%x: " , hw->iobase); \
-			printk(stuff);} while (0)
-
 #define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
 
 #else /* ! HERMES_DEBUG */
@@ -86,7 +85,6 @@
 
 #endif /* ! HERMES_DEBUG */
 
-#define IO_TYPE(hw)	((hw)->io_space ? "IO " : "MEM ")
 
 /*
  * Internal functions
@@ -111,7 +109,6 @@
 		udelay(1);
 		reg = hermes_read_regn(hw, CMD);
 	}
-	DEBUG(3, "hermes_issue_cmd: did %d retries.\n", CMD_BUSY_TIMEOUT-k);
 	if (reg & HERMES_CMD_BUSY) {
 		return -EBUSY;
 	}
@@ -143,7 +140,7 @@
 #endif
 }
 
-int hermes_reset(hermes_t *hw)
+int hermes_init(hermes_t *hw)
 {
 	u16 status, reg;
 	int err = 0;
@@ -195,8 +192,6 @@
 		reg = hermes_read_regn(hw, EVSTAT);
 	}
 
-	DEBUG(0, "Reset completed in %d iterations\n", CMD_INIT_TIMEOUT - k);
-
 	hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
 
 	if (! hermes_present(hw)) {
@@ -303,9 +298,6 @@
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
 	if (err) {
-		printk(KERN_WARNING "hermes @ %s0x%lx: "
-		       "Frame allocation command failed (0x%X).\n",
-		       IO_TYPE(hw), hw->iobase, err);
 		return err;
 	}
 
@@ -393,12 +385,10 @@
 	}
 
 	if (reg & HERMES_OFFSET_BUSY) {
-		DEBUG(1,"hermes_bap_seek: timeout\n");
 		return -ETIMEDOUT;
 	}
 
 	if (reg & HERMES_OFFSET_ERR) {
-		DEBUG(1,"hermes_bap_seek: BAP error\n");
 		return -EIO;
 	}
 
@@ -472,6 +462,7 @@
 	int err = 0;
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	u16 rlength, rtype;
+	int nwords;
 
 	if ( (bufsize < 0) || (bufsize % 2) )
 		return -EINVAL;
@@ -500,10 +491,9 @@
 		       "(rid=0x%04x, len=0x%04x)\n",
 		       IO_TYPE(hw), hw->iobase,
 		       HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
-	
-	/* FIXME: we should read the min of the requested length and
-           the actual record length */
-	hermes_read_words(hw, dreg, buf, bufsize / 2);
+
+	nwords = min_t(int, rlength - 1, bufsize / 2);
+	hermes_read_words(hw, dreg, buf, nwords);
 
  out:
 	return err;
@@ -516,9 +506,6 @@
 	int err = 0;
 	int count;
 	
-	DEBUG(3, "write_ltv(): bap=%d rid=0x%04x length=%d (value=0x%04x)\n",
-	      bap, rid, length, * ((u16 *)value));
-
 	err = hermes_bap_seek(hw, bap, rid, 0);
 	if (err)
 		goto out;
@@ -538,7 +525,7 @@
 }
 
 EXPORT_SYMBOL(hermes_struct_init);
-EXPORT_SYMBOL(hermes_reset);
+EXPORT_SYMBOL(hermes_init);
 EXPORT_SYMBOL(hermes_docmd_wait);
 EXPORT_SYMBOL(hermes_allocate);
 
diff -Nru a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
--- a/drivers/net/wireless/hermes.h	Fri Sep 27 14:51:03 2002
+++ b/drivers/net/wireless/hermes.h	Fri Sep 27 14:51:03 2002
@@ -171,6 +171,7 @@
 #define	HERMES_RXSTAT_BADCRC		(0x0001)
 #define	HERMES_RXSTAT_UNDECRYPTABLE	(0x0002)
 #define	HERMES_RXSTAT_MACPORT		(0x0700)
+#define HERMES_RXSTAT_PCF		(0x1000)	/* Frame was received in CF period */
 #define	HERMES_RXSTAT_MSGTYPE		(0xE000)
 #define	HERMES_RXSTAT_1042		(0x2000)	/* RFC-1042 frame */
 #define	HERMES_RXSTAT_TUNNEL		(0x4000)	/* bridge-tunnel encoded frame */
@@ -299,7 +300,7 @@
 
 /* Function prototypes */
 void hermes_struct_init(hermes_t *hw, ulong address, int io_space, int reg_spacing);
-int hermes_reset(hermes_t *hw);
+int hermes_init(hermes_t *hw);
 int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp);
 int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
 
@@ -319,12 +320,6 @@
 	return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
 }
 
-static inline void hermes_enable_interrupt(hermes_t *hw, u16 events)
-{
-	hw->inten |= events;
-	hermes_write_regn(hw, INTEN, hw->inten);
-}
-
 static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
 {
 	hw->inten = events;
@@ -350,7 +345,7 @@
 	return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
 }
 
-#define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 )
+#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
 #define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
 
 /* Note that for the next two, the count is in 16-bit words, not bytes */
diff -Nru a/drivers/net/wireless/ieee802_11.h b/drivers/net/wireless/ieee802_11.h
--- a/drivers/net/wireless/ieee802_11.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/wireless/ieee802_11.h	Fri Sep 27 14:51:04 2002
@@ -3,8 +3,8 @@
 
 #define IEEE802_11_DATA_LEN		2304
 /* Actually, the standard seems to be inconsistent about what the
-   maximum frame size really is.  S6.2.1.1.2 says 2304 octets, but the
-   figure in section 7.1.2 says 2312 octects. */
+   maximum frame size really is.  Section 6.2.1.1.2 says 2304 octets,
+   but the figure in Section 7.1.2 says 2312 octects. */
 #define IEEE802_11_HLEN			30
 #define IEEE802_11_FRAME_LEN		(IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
 
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/wireless/orinoco.c	Fri Sep 27 14:51:04 2002
@@ -1,4 +1,4 @@
-/* orinoco.c 0.11b	- (formerly known as dldwd_cs.c and orinoco_cs.c)
+/* orinoco.c 0.13	- (formerly known as dldwd_cs.c and orinoco_cs.c)
  *
  * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
  * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
@@ -240,7 +240,7 @@
  *	  was never very useful.
  *	o Make Rx errors less noisy.
  *
- * v0.10 -> v0.11 - 5 Apr Mar 2002 - David Gibson
+ * v0.10 -> v0.11 - 5 Apr 2002 - David Gibson
  *	o Laid the groundwork in hermes.[ch] for devices which map
  *	  into PCI memory space rather than IO space.
  *	o Fixed bug in multicast handling (cleared multicast list when
@@ -256,7 +256,7 @@
  *	o Fixes for recent Symbol firmwares which lack AP density
  *	  (Pavel Roskin).
  *
- * v0.11 -> v0.11b - 29 Apr 2002 - David Gibson
+ * v0.11 -> v0.11a - 29 Apr 2002 - David Gibson
  *	o Handle different register spacing, necessary for Prism 2.5
  *	  PCI adaptors (Steve Hill).
  *	o Cleaned up initialization of card structures in orinoco_cs
@@ -279,44 +279,79 @@
  *	o Fixed multiple bad kfree() bugs introduced by the
  *	  alloc_orinocodev() changes.
  *
+ * v0.11b -> v0.12 - 19 Jun 2002 - David Gibson
+ *	o Support changing the MAC address.
+ *	o Correct display of Intersil firmware revision numbers.
+ *	o Entirely revised locking scheme.  Should be both simpler and
+ *	   better.
+ *	o Merged some common code in orinoco_plx, orinoco_pci and
+ *	  airport by creating orinoco_default_{open,stop,reset}()
+ *	  which are used as the dev->open, dev->stop, priv->reset
+ *	  callbacks if none are specified when alloc_orinocodev() is
+ *	  called.
+ *	o Removed orinoco_plx_interupt() and orinoco_pci_interrupt().
+ *	  They didn't do anything.
+ *
+ * v0.12 -> v0.12a - 4 Jul 2002 - David Gibson
+ *	o Some rearrangement of code.
+ *	o Numerous fixups to locking and rest handling, particularly
+ *	  for PCMCIA.
+ *	o This allows open and stop net_device methods to be in
+ *	  orinoco.c now, rather than in the init modules.
+ *	o In orinoco_cs.c link->priv now points to the struct
+ *	  net_device not to the struct orinoco_private.
+ *	o Added a check for undersized SNAP frames, which could cause
+ *	  crashes.
+ *
+ * v0.12a -> v0.12b - 11 Jul 2002 - David Gibson
+ *	o Fix hw->num_init testing code, so num_init is actually
+ *	  incremented.
+ *	o Fix very stupid bug in orinoco_cs which broke compile with
+ *	  CONFIG_SMP.
+ *	o Squashed a warning.
+ *
+ * v0.12b -> v0.12c - 26 Jul 2002 - David Gibson
+ *	o Change to C9X style designated initializers.
+ *	o Add support for 3Com AirConnect PCI.
+ *	o No longer ignore the hard_reset argument to
+ *	  alloc_orinocodev().  Oops.
+ *
+ * v0.12c -> v0.13 - 13 Sep 2002 - David Gibson
+ *	o Revert the broken 0.12* locking scheme and go to a new yet
+ *	  simpler scheme.
+ *	o Do firmware resets only in orinoco_init() and when waking
+ *	  the card from hard sleep.
+ *
+ * v0.13 -> v0.13 - 27 Sep 2002 - David Gibson
+ *	o Re-introduced full resets (via schedule_task()) on Tx
+ *	  timeout.
+ *
  * TODO
- *	o New wireless extensions API
+ *	o New wireless extensions API (patch forthcoming from Moustafa
+ *	  Youssef).
  *	o Handle de-encapsulation within network layer, provide 802.11
- *	  headers
+ *	  headers (patch from Thomas 'Dent' Mirlacher)
  *	o Fix possible races in SPY handling.
  *	o Disconnect wireless extensions from fundamental configuration.
- *
- *	o Convert /proc debugging stuff to seqfile
- *	o Use multiple Tx buffers
- */
-/* Notes on locking:
- *
- * The basic principle of operation is that everything except the
- * interrupt handler is serialized through a single spinlock in the
- * struct orinoco_private structure, using orinoco_lock() and
- * orinoco_unlock() (which in turn use spin_lock_bh() and
- * spin_unlock_bh()).
- *
- * The kernel's IRQ handling stuff ensures that the interrupt handler
- * does not re-enter itself. The interrupt handler is written such
- * that everything it does is safe without a lock: chiefly this means
- * that the Rx path uses one of the Hermes chipset's BAPs while
- * everything else uses the other.
- *
- * Actually, strictly speaking, the updating of the statistics from
- * the interrupt handler isn't safe without a lock.  However the worst
- * that can happen is that we perturb the packet/byte counts slightly.
- * We could fix this to use atomic types, but it's probably not worth
- * it.
- *
- * The big exception is that that we don't want the irq handler
- * running when we actually reset or shut down the card, because
- * strange things might happen (probably the worst would be one packet
- * of garbage, but you can't be too careful). For this we use
- * __orinoco_stop_irqs() which will set a flag to disable the interrupt
- * handler, and wait for any outstanding instances of the handler to
- * complete. THIS WILL LOSE INTERRUPTS! so it shouldn't be used except
- * for resets, where losing a few interrupts is acceptable. */
+ *	o (maybe) Software WEP support (patch from Stano Meduna).
+ *	o (maybe) Convert /proc debugging stuff to seqfile
+ *	o (maybe) Use multiple Tx buffers - driver handling queue
+ *	  rather than firmware. */
+
+/* Locking and synchronization:
+ *
+ * The basic principle is that everything is serialized through a
+ * single spinlock, priv->lock.  The lock is used in user, bh and irq
+ * context, so when taken outside hardirq context it should always be
+ * taken with interrupts disabled.  The lock protects both the
+ * hardware and the struct orinoco_private.
+ *
+ * Another flag, priv->hw_unavailable indicates that the hardware is
+ * unavailable for an extended period of time (e.g. suspended, or in
+ * the middle of a hard reset).  This flag is protected by the
+ * spinlock.  All code which touches the hardware should check the
+ * flag after taking the lock, and if it is set, give up on whatever
+ * they are doing and drop the lock again. */
 
 #include <linux/config.h>
 
@@ -333,31 +368,20 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
-#include <linux/list.h>
 
 #include "hermes.h"
 #include "hermes_rid.h"
 #include "orinoco.h"
 #include "ieee802_11.h"
 
-/* Wireless extensions backwards compatibility */
-#ifndef SIOCIWFIRSTPRIV
-#define SIOCIWFIRSTPRIV		SIOCDEVPRIVATE
-#endif /* SIOCIWFIRSTPRIV */
-
-/* We do this this way to avoid ifdefs in the actual code */
-#ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv)	(priv->spy_number)
-#else
-#define SPY_NUMBER(priv)	0
-#endif /* WIRELESS_SPY */
+/********************************************************************/
+/* Module information                                               */
+/********************************************************************/
 
-static char version[] __initdata = "orinoco.c 0.11b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
 #ifdef MODULE_LICENSE
@@ -371,6 +395,26 @@
 EXPORT_SYMBOL(orinoco_debug);
 #endif
 
+/********************************************************************/
+/* Compile time configuration and compatibility stuff               */
+/********************************************************************/
+
+/* Wireless extensions backwards compatibility */
+#ifndef SIOCIWFIRSTPRIV
+#define SIOCIWFIRSTPRIV		SIOCDEVPRIVATE
+#endif /* SIOCIWFIRSTPRIV */
+
+/* We do this this way to avoid ifdefs in the actual code */
+#ifdef WIRELESS_SPY
+#define SPY_NUMBER(priv)	(priv->spy_number)
+#else
+#define SPY_NUMBER(priv)	0
+#endif /* WIRELESS_SPY */
+
+/********************************************************************/
+/* Internal constants                                               */
+/********************************************************************/
+
 #define ORINOCO_MIN_MTU		256
 #define ORINOCO_MAX_MTU		(IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
 
@@ -386,6 +430,8 @@
 
 #define DUMMY_FID		0xFFFF
 
+#define RUP_EVEN(a) (((a) + 1) & (~1))
+
 /*#define MAX_MULTICAST(priv)	(priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
   HERMES_MAX_MULTICAST : 0)*/
 #define MAX_MULTICAST(priv)	(HERMES_MAX_MULTICAST)
@@ -419,6 +465,10 @@
 };
 #define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
 
+/********************************************************************/
+/* Data types                                                       */
+/********************************************************************/
+
 struct header_struct {
 	/* 802.3 */
 	u8 dest[ETH_ALEN];
@@ -438,27 +488,29 @@
 
 #define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
 
-/*
- * Function prototypes
- */
+/********************************************************************/
+/* Function prototypes                                              */
+/********************************************************************/
 
 static void orinoco_stat_gather(struct net_device *dev,
-			      struct sk_buff *skb,
-			      struct hermes_rx_descriptor *desc);
+				struct sk_buff *skb,
+				struct hermes_rx_descriptor *desc);
 
 static struct net_device_stats *orinoco_get_stats(struct net_device *dev);
 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev);
 
 /* Hardware control routines */
 
+static int __orinoco_program_rids(struct orinoco_private *priv);
+
 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
 static int __orinoco_hw_setup_wep(struct orinoco_private *priv);
 static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]);
 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
-			      char buf[IW_ESSID_MAX_SIZE+1]);
+				char buf[IW_ESSID_MAX_SIZE+1]);
 static long orinoco_hw_get_freq(struct orinoco_private *priv);
 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
-				    s32 *rates, int max);
+				      s32 *rates, int max);
 static void __orinoco_set_multicast_list(struct net_device *dev);
 
 /* Interrupt handling routines */
@@ -471,6 +523,7 @@
 static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw);
 static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw);
 
+/* ioctl() routines */
 static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq);
 static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq);
 static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq);
@@ -495,160 +548,161 @@
 static int orinoco_proc_init(void);
 static void orinoco_proc_cleanup(void);
 
-/*
- * Inline functions
- */
-static inline void
-orinoco_lock(struct orinoco_private *priv)
+int __orinoco_up(struct net_device *dev)
 {
-	spin_lock_bh(&priv->lock);
-}
+	struct orinoco_private *priv = dev->priv;
+	struct hermes *hw = &priv->hw;
+	int err;
 
-static inline void
-orinoco_unlock(struct orinoco_private *priv)
-{
-	spin_unlock_bh(&priv->lock);
-}
+	err = __orinoco_program_rids(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d configuring card\n",
+		       dev->name, err);
+		return err;
+	}
 
-static inline int
-orinoco_irqs_allowed(struct orinoco_private *priv)
-{
-	return test_bit(ORINOCO_STATE_DOIRQ, &priv->state);
-}
+	/* Fire things up again */
+	hermes_set_irqmask(hw, ORINOCO_INTEN);
+	err = hermes_enable_port(hw, 0);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d enabling MAC port\n",
+		       dev->name, err);
+		return err;
+	}
 
-static inline void
-__orinoco_stop_irqs(struct orinoco_private *priv)
-{
-	hermes_t *hw = &priv->hw;
+	netif_start_queue(dev);
 
-	hermes_set_irqmask(hw, 0);
-	clear_bit(ORINOCO_STATE_DOIRQ, &priv->state);
-	while (test_bit(ORINOCO_STATE_INIRQ, &priv->state))
-		;
+	return 0;
 }
 
-static inline void
-__orinoco_start_irqs(struct orinoco_private *priv, u16 irqmask)
+int __orinoco_down(struct net_device *dev)
 {
-	hermes_t *hw = &priv->hw;
+	struct orinoco_private *priv = dev->priv;
+	struct hermes *hw = &priv->hw;
+	int err;
 
-	TRACE_ENTER(priv->ndev->name);
+	netif_stop_queue(dev);
 
-	local_irq_disable(); /* FIXME: is this necessary? */
-	set_bit(ORINOCO_STATE_DOIRQ, &priv->state);
-	hermes_set_irqmask(hw, irqmask);
-	local_irq_enable();
+	err = hermes_disable_port(hw, 0);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d disabling MAC port\n",
+		       dev->name, err);
+		return err;
+	}
+	hermes_set_irqmask(hw, 0);
+	hermes_write_regn(hw, EVACK, 0xffff);
 
-	TRACE_EXIT(priv->ndev->name);
+	return 0;
 }
 
-static inline void
-set_port_type(struct orinoco_private *priv)
+int orinoco_reinit_firmware(struct net_device *dev)
 {
-	switch (priv->iw_mode) {
-	case IW_MODE_INFRA:
-		priv->port_type = 1;
-		priv->allow_ibss = 0;
-		break;
-	case IW_MODE_ADHOC:
-		if (priv->prefer_port3) {
-			priv->port_type = 3;
-			priv->allow_ibss = 0;
-		} else {
-			priv->port_type = priv->ibss_port;
-			priv->allow_ibss = 1;
-		}
-		break;
-	default:
-		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
-		       priv->ndev->name);
+	struct orinoco_private *priv = dev->priv;
+	struct hermes *hw = &priv->hw;
+	int err;
+
+	err = hermes_init(hw);
+	if (err)
+		return err;
+
+	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+	if (err == -EIO) {
+		/* Try workaround for old Symbol firmware bug */
+		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
+		       "(old Symbol firmware?). Trying to work around... ",
+		       dev->name);
+		
+		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+		if (err)
+			printk("failed!\n");
+		else
+			printk("ok.\n");
 	}
-}
 
-static inline int
-is_snap(struct header_struct *hdr)
-{
-	return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3);
+	return err;
 }
 
-static void
-orinoco_set_multicast_list(struct net_device *dev)
+static int orinoco_open(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
+	unsigned long flags;
+	int err;
 
-	orinoco_lock(priv);
-	__orinoco_set_multicast_list(dev);
-	orinoco_unlock(priv);
-}
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-/*
- * Hardware control routines
- */
+        priv->open = 1;
 
-void
-orinoco_shutdown(struct orinoco_private *priv)
+	err = __orinoco_up(dev);
+
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_stop(struct net_device *dev)
 {
-	int err = 0;
+	struct orinoco_private *priv = dev->priv;
+	unsigned long flags;
+	int err;
 
-	TRACE_ENTER(priv->ndev->name);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-	orinoco_lock(priv);
-	__orinoco_stop_irqs(priv);
+	priv->open = 0;
 
-	err = hermes_reset(&priv->hw);
-	if (err && err != -ENODEV) /* If the card is gone, we don't care about shutting it down */
-		printk(KERN_ERR "%s: Error %d shutting down Hermes chipset\n", priv->ndev->name, err);
+	err = __orinoco_down(dev);
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
-	TRACE_EXIT(priv->ndev->name);
+	return err;
 }
 
-int
-orinoco_reset(struct orinoco_private *priv)
+static int __orinoco_program_rids(struct orinoco_private *priv)
 {
 	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
-	int err = 0;
+	int err;
 	struct hermes_idstring idbuf;
 
-	TRACE_ENTER(priv->ndev->name);
-
-	/* Stop other people bothering us */
-	orinoco_lock(priv);
-	__orinoco_stop_irqs(priv);
-
-	/* Check if we need a card reset */
-	if (priv->hard_reset)
-		priv->hard_reset(priv);
-
-	/* Do standard firmware reset if we can */
-	err = hermes_reset(hw);
-	if (err)
-		goto out;
-
-	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-	if (err == -EIO) {
-		/* Try workaround for old Symbol firmware bug */
-		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
-		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-		if (err)
-			goto out;
+	/* Set the MAC address */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting MAC address\n", dev->name, err);
+		return err;
 	}
 
-	/* Now set up all the parameters on the card */
-	
 	/* Set up the link mode */
-	
 	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE, priv->port_type);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting port type\n", dev->name, err);
+		return err;
+	}
+	/* Set the channel/frequency */
+	if (priv->channel == 0) {
+		printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);
+		if (priv->createibss)
+			priv->channel = 10;
+	}
+	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL, priv->channel);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting channel\n", dev->name, err);
+		return err;
+	}
+
 	if (priv->has_ibss) {
 		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFCREATEIBSS,
-					   priv->allow_ibss);
-		if (err)
-			goto out;
-		if((strlen(priv->desired_essid) == 0) && (priv->allow_ibss)
+					   priv->createibss);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", dev->name, err);
+			return err;
+		}
+
+		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)
 		   && (!priv->has_ibss_any)) {
 			printk(KERN_WARNING "%s: This firmware requires an \
 ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
@@ -665,13 +719,17 @@
 	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
 			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
 			       &idbuf);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting OWNSSID\n", dev->name, err);
+		return err;
+	}
 	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
 			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
 			       &idbuf);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n", dev->name, err);
+		return err;
+	}
 
 	/* Set the station name */
 	idbuf.len = cpu_to_le16(strlen(priv->nick));
@@ -679,26 +737,29 @@
 	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
 			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
 			       &idbuf);
-	if (err)
-		goto out;
-
-	/* Set the channel/frequency */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL, priv->channel);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting nickname\n", dev->name, err);
+		return err;
+	}
 
 	/* Set AP density */
 	if (priv->has_sensitivity) {
 		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
 					   priv->ap_density);
-		if (err)
+		if (err) {
+			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
+			       "Disabling sensitivity control\n", dev->name, err);
+
 			priv->has_sensitivity = 0;
+		}
 	}
 
 	/* Set RTS threshold */
 	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, priv->rts_thresh);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting RTS threshold\n", dev->name, err);
+		return err;
+	}
 
 	/* Set fragmentation threshold or MWO robustness */
 	if (priv->has_mwo)
@@ -709,35 +770,52 @@
 		err = hermes_write_wordrec(hw, USER_BAP,
 					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
 					   priv->frag_thresh);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting framentation\n", dev->name, err);
+		return err;
+	}
 
 	/* Set bitrate */
 	err = __orinoco_hw_set_bitrate(priv);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting bitrate\n", dev->name, err);
+		return err;
+	}
 
 	/* Set power management */
 	if (priv->has_pm) {
 		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED,
 					   priv->pm_on);
-		if (err)
-			goto out;
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+
 		err = hermes_write_wordrec(hw, USER_BAP,
 					   HERMES_RID_CNFMULTICASTRECEIVE,
 					   priv->pm_mcast);
-		if (err)
-			goto out;
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
 		err = hermes_write_wordrec(hw, USER_BAP,
 					   HERMES_RID_CNFMAXSLEEPDURATION,
 					   priv->pm_period);
-		if (err)
-			goto out;
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
 		err = hermes_write_wordrec(hw, USER_BAP,
 					   HERMES_RID_CNFPMHOLDOVERDURATION,
 					   priv->pm_timeout);
-		if (err)
-			goto out;
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
 	}
 
 	/* Set preamble - only for Symbol so far... */
@@ -746,8 +824,9 @@
 					   HERMES_RID_CNFPREAMBLE_SYMBOL,
 					   priv->preamble);
 		if (err) {
-			printk(KERN_WARNING "%s: Can't set preamble!\n", dev->name);
-			goto out;
+			printk(KERN_ERR "%s: Error %d setting preamble\n",
+			       dev->name, err);
+			return err;
 		}
 	}
 
@@ -755,41 +834,161 @@
 	if (priv->has_wep) {
 		err = __orinoco_hw_setup_wep(priv);
 		if (err) {
-			printk(KERN_ERR "%s: Error %d activating WEP.\n",
+			printk(KERN_ERR "%s: Error %d activating WEP\n",
 			       dev->name, err);
-			goto out;
+			return err;
 		}
 	}
 
 	/* Set promiscuity / multicast*/
 	priv->promiscuous = 0;
 	priv->mc_count = 0;
-	__orinoco_set_multicast_list(dev);
-	
-	__orinoco_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC |
-			   HERMES_EV_TX | HERMES_EV_TXEXC |
-			   HERMES_EV_WTERR | HERMES_EV_INFO |
-			   HERMES_EV_INFDROP);
+	__orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
 
-	err = hermes_enable_port(hw, 0);
+	return 0;
+}
+
+/* xyzzy */
+static int orinoco_reconfigure(struct orinoco_private *priv)
+{
+	struct hermes *hw = &priv->hw;
+	unsigned long flags;
+	int err = 0;
+
+	orinoco_lock(priv, &flags);
+
+	err = hermes_disable_port(hw, 0);
+	if (err) {
+		printk(KERN_ERR "%s: Unable to disable port in orinco_reconfigure()\n",
+		       priv->ndev->name);
+		goto out;
+	}
+
+	err = __orinoco_program_rids(priv);
 	if (err)
 		goto out;
 
+	err = hermes_enable_port(hw, 0);
+	if (err) {
+		printk(KERN_ERR "%s: Unable to enable port in orinco_reconfigure()\n",
+		       priv->ndev->name);
+		goto out;
+	}
+
  out:
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
+	return err;
 
-	TRACE_EXIT(priv->ndev->name);
+}
 
-	return err;
+/* This must be called from user context, without locks held - use
+ * schedule_task() */
+static void orinoco_reset(struct net_device *dev)
+{
+	struct orinoco_private *priv = dev->priv;
+	int err;
+	unsigned long flags;
+
+	printk(KERN_INFO "%s: orinoco_reset()\n", dev->name);
+
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return;
+
+	priv->hw_unavailable = 1;
+	orinoco_unlock(priv, &flags);
+
+	if (priv->hard_reset)
+		err = (*priv->hard_reset)(priv);
+	if (err) {
+		printk(KERN_ERR "%s: orinoco_reset: Error %d performing hard reset\n",
+		       dev->name, err);
+		/* FIXME: shutdown of some sort */
+		return;
+	}
+
+	err = orinoco_reinit_firmware(dev);
+	if (err) {
+		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
+		       dev->name, err);
+		return;
+	}
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->hw_unavailable = 0;
+
+	err = __orinoco_up(dev);
+	if (err) {
+		printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
+		       dev->name, err);
+	} else
+		dev->trans_start = jiffies;
+
+	orinoco_unlock(priv, &flags);
+
+	return;
 }
 
+/********************************************************************/
+/* Internal helper functions                                        */
+/********************************************************************/
+
+static inline void
+set_port_type(struct orinoco_private *priv)
+{
+	switch (priv->iw_mode) {
+	case IW_MODE_INFRA:
+		priv->port_type = 1;
+		priv->createibss = 0;
+		break;
+	case IW_MODE_ADHOC:
+		if (priv->prefer_port3) {
+			priv->port_type = 3;
+			priv->createibss = 0;
+		} else {
+			priv->port_type = priv->ibss_port;
+			priv->createibss = 1;
+		}
+		break;
+	default:
+		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
+		       priv->ndev->name);
+	}
+}
+
+static inline int
+is_snap(struct header_struct *hdr)
+{
+	return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3);
+}
+
+static void
+orinoco_set_multicast_list(struct net_device *dev)
+{
+	struct orinoco_private *priv = dev->priv;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0) {
+		printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
+		       "called when hw_unavailable\n", dev->name);
+		return;
+	}
+
+	__orinoco_set_multicast_list(dev);
+	orinoco_unlock(priv, &flags);
+}
+
+/********************************************************************/
+/* Hardware control functions                                       */
+/********************************************************************/
+
+
 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 
-	TRACE_ENTER(priv->ndev->name);
-
 	if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
 		printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
 		       priv->ndev->name, priv->bitratemode);
@@ -812,8 +1011,6 @@
 		BUG();
 	}
 
-	TRACE_EXIT(priv->ndev->name);
-
 	return err;
 }
 
@@ -825,8 +1022,6 @@
 	int	master_wep_flag;
 	int	auth_flag;
 
-	TRACE_ENTER(priv->ndev->name);
-
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
 		if (priv->wep_on) {
@@ -920,8 +1115,6 @@
 		}
 	}
 
-	TRACE_EXIT(priv->ndev->name);
-
 	return 0;
 }
 
@@ -929,13 +1122,16 @@
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
 			      ETH_ALEN, NULL, buf);
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -948,10 +1144,11 @@
 	struct hermes_idstring essidbuf;
 	char *p = (char *)(&essidbuf.val);
 	int len;
+	unsigned long flags;
 
-	TRACE_ENTER(priv->ndev->name);
-
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	if (strlen(priv->desired_essid) > 0) {
 		/* We read the desired SSID from the hardware rather
@@ -988,9 +1185,7 @@
 	buf[len] = '\0';
 
  fail_unlock:
-	orinoco_unlock(priv);
-
-	TRACE_EXIT(priv->ndev->name);
+	orinoco_unlock(priv, &flags);
 
 	return err;       
 }
@@ -1002,13 +1197,22 @@
 	int err = 0;
 	u16 channel;
 	long freq = 0;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
 	if (err)
 		goto out;
 
+	/* Intersil firmware 1.3.5 returns 0 when the interface is down */
+	if (channel == 0) {
+		err = -EBUSY;
+		goto out;
+	}
+
 	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
 		struct net_device *dev = priv->ndev;
 
@@ -1020,7 +1224,7 @@
 	freq = channel_frequency[channel-1] * 100000;
 
  out:
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	if (err > 0)
 		err = -EBUSY;
@@ -1036,11 +1240,15 @@
 	int err = 0;
 	int num;
 	int i;
+	unsigned long flags;
+
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-	orinoco_lock(priv);
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
 			      sizeof(list), NULL, &list);
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	if (err)
 		return err;
@@ -1122,7 +1330,7 @@
 /*
  * Interrupt handler
  */
-void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs)
+void orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct orinoco_private *priv = (struct orinoco_private *) dev_id;
 	hermes_t *hw = &priv->hw;
@@ -1134,38 +1342,26 @@
 	 * we panic and shut down the hardware */
 	static int last_irq_jiffy = 0; /* jiffies value the last time we were called */
 	static int loops_this_jiffy = 0;
+	unsigned long flags;
 
-	if (test_and_set_bit(ORINOCO_STATE_INIRQ, &priv->state))
-		BUG();
-
-	if (! orinoco_irqs_allowed(priv)) {
-		clear_bit(ORINOCO_STATE_INIRQ, &priv->state);
+	if (orinoco_lock(priv, &flags) != 0) {
+		/* If hw is unavailable */
 		return;
 	}
 
-	DEBUG(3, "%s: orinoco_interrupt()\n", priv->ndev->name);
-
 	evstat = hermes_read_regn(hw, EVSTAT);
 	events = evstat & hw->inten;
 	
-/*  	if (! events) { */
-/*  		printk(KERN_WARNING "%s: Null event\n", dev->name); */
-/*  	} */
-
 	if (jiffies != last_irq_jiffy)
 		loops_this_jiffy = 0;
 	last_irq_jiffy = jiffies;
 
 	while (events && count--) {
-		DEBUG(3, "__orinoco_interrupt(): count=%d EVSTAT=0x%04x\n",
-		      count, evstat);
-		
 		if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
 			printk(KERN_CRIT "%s: IRQ handler is looping too \
 much! Shutting down.\n",
 			       dev->name);
 			/* Perform an emergency shutdown */
-			clear_bit(ORINOCO_STATE_DOIRQ, &priv->state);
 			hermes_set_irqmask(hw, 0);
 			break;
 		}
@@ -1199,7 +1395,7 @@
 		events = evstat & hw->inten;
 	};
 
-	clear_bit(ORINOCO_STATE_INIRQ, &priv->state);
+	orinoco_unlock(priv, &flags);
 }
 
 static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw)
@@ -1211,8 +1407,8 @@
 {
 	/* This seems to happen a fair bit under load, but ignoring it
 	   seems to work fine...*/
-	DEBUG(1, "%s: MAC controller error (WTERR). Ignoring.\n",
-	      priv->ndev->name);
+	printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
+	       priv->ndev->name);
 }
 
 static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw)
@@ -1235,8 +1431,6 @@
 	 * The controller return to us a pseudo frame containing
 	 * the information in question - Jean II */
 	infofid = hermes_read_regn(hw, INFOFID);
-	DEBUG(3, "%s: __orinoco_ev_info(): INFOFID=0x%04x\n", dev->name,
-	      infofid);
 
 	/* Read the info frame header - don't try too hard */
 	err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
@@ -1277,11 +1471,6 @@
 		wstats->discard.retries +=
 			le16_to_cpu(tallies.TxRetryLimitExceeded);
 		/* wstats->miss.beacon - no match */
-#if ORINOCO_DEBUG > 3
-		/* Hack for debugging - should not be taken as an example */
-		wstats->discard.nwid += le16_to_cpu(tallies.TxUnicastFrames);
-		wstats->miss.beacon += le16_to_cpu(tallies.RxUnicastFrames);
-#endif
 #endif /* WIRELESS_EXT > 11 */
 	}
 	break;
@@ -1308,7 +1497,6 @@
 	int err;
 
 	rxfid = hermes_read_regn(hw, RXFID);
-	DEBUG(3, "__orinoco_ev_rx(): RXFID=0x%04x\n", rxfid);
 
 	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
 			       rxfid, 0);
@@ -1349,11 +1537,11 @@
 	length = ntohs(hdr.len);
 	
 	/* Sanity checks */
-	if (length < sizeof(struct header_struct)) {
-		printk(KERN_WARNING "%s: Undersized frame received (%d bytes)\n",
-		       dev->name, length);
-		stats->rx_length_errors++;
-		stats->rx_errors++;
+	if (length < 3) { /* No for even an 802.2 LLC header */
+		/* At least on Symbol firmware with PCF we get quite a
+                   lot of these legitimately - Poll frames with no
+                   data. */
+		stats->rx_dropped++;
 		goto drop;
 	}
 	if (length > IEEE802_11_DATA_LEN) {
@@ -1373,7 +1561,6 @@
 	if (!skb) {
 		printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
 		       dev->name);
-		stats->rx_dropped++;
 		goto drop;
 	}
 
@@ -1383,8 +1570,7 @@
 	 * In most cases, the firmware tell us about SNAP frames.
 	 * For some reason, the SNAP frames sent by LinkSys APs
 	 * are not properly recognised by most firmwares.
-	 * So, check ourselves (note : only 3 bytes out of 6).
-	 */
+	 * So, check ourselves */
 	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
 	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
 	   is_snap(&hdr)) {
@@ -1392,6 +1578,12 @@
 		   802.11 frame which we'll need to de-encapsulate to
 		   the original EthernetII frame. */
 
+		if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
+			stats->rx_length_errors++;
+			stats->rx_dropped++;
+			goto drop;
+		}
+
 		/* Remove SNAP header, reconstruct EthernetII frame */
 		data_len = length - ENCAPS_OVERHEAD;
 		data_off = HERMES_802_3_OFFSET + sizeof(hdr);
@@ -1414,7 +1606,7 @@
 	err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
 			       rxfid, data_off);
 	if (err) {
-		printk(KERN_ERR "%s: error %d reading frame header. "
+		printk(KERN_ERR "%s: error %d reading frame. "
 		       "Frame dropped.\n", dev->name, err);
 		stats->rx_errors++;
 		goto drop;
@@ -1436,6 +1628,8 @@
 	return;
 
  drop:	
+	stats->rx_dropped++;
+
 	if (skb)
 		dev_kfree_skb_irq(skb);
 	return;
@@ -1469,11 +1663,7 @@
 
 static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw)
 {
-/*  	struct net_device *dev = priv->ndev; */
 	struct net_device_stats *stats = &priv->stats;
-/*  	u16 fid = hermes_read_regn(hw, TXCOMPLFID); */
-
-/*  	DEBUG(2, "%s: Transmit completed (FID=%04X)\n", priv->ndev->name, fid); */
 
 	stats->tx_packets++;
 
@@ -1485,8 +1675,6 @@
 	struct net_device *dev = priv->ndev;
 	u16 fid = hermes_read_regn(hw, ALLOCFID);
 
-	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev->name, fid);
-
 	if (fid != priv->txfid) {
 		if (fid != DUMMY_FID)
 			printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
@@ -1500,16 +1688,17 @@
 }
 
 struct sta_id {
-	u16 id, vendor, major, minor;
+	u16 id, variant, major, minor;
 } __attribute__ ((packed));
 
 static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id)
 {
-	u32 firmver = ((u32)sta_id->major << 16) | sta_id->minor;
+	/* FIXME: this is fundamentally broken */
+	unsigned int firmver = ((u32)sta_id->major << 16) | sta_id->minor;
 	
-	if (sta_id->vendor == 1)
+	if (sta_id->variant == 1)
 		return FIRMWARE_TYPE_AGERE;
-	else if ((sta_id->vendor == 2) &&
+	else if ((sta_id->variant == 2) &&
 		   ((firmver == 0x10001) || (firmver == 0x20001)))
 		return FIRMWARE_TYPE_SYMBOL;
 	else
@@ -1522,7 +1711,7 @@
 	hermes_t *hw = &priv->hw;
 	int err;
 	struct sta_id sta_id;
-	u32 firmver;
+	unsigned int firmver;
 	char tmp[SYMBOL_MAX_VER_LEN+1];
 
 	/* Get the firmware version */
@@ -1533,14 +1722,12 @@
 		memset(&sta_id, 0, sizeof(sta_id));
 	}
 	le16_to_cpus(&sta_id.id);
-	le16_to_cpus(&sta_id.vendor);
+	le16_to_cpus(&sta_id.variant);
 	le16_to_cpus(&sta_id.major);
 	le16_to_cpus(&sta_id.minor);
 
-	firmver = ((u32)sta_id.major << 16) | sta_id.minor;
-
 	printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
-	       dev->name, sta_id.id, sta_id.vendor,
+	       dev->name, sta_id.id, sta_id.variant,
 	       sta_id.major, sta_id.minor);
 
 	if (! priv->firmware_type)
@@ -1555,7 +1742,6 @@
 	priv->has_ibss_any = 0;
 	priv->has_wep = 0;
 	priv->has_big_wep = 0;
-	priv->broken_cor_reset = 0;
 
 	/* Determine capabilities from the firmware version */
 	switch (priv->firmware_type) {
@@ -1566,6 +1752,8 @@
 		       "version %d.%02d\n", dev->name,
 		       sta_id.major, sta_id.minor);
 
+		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
+
 		priv->has_ibss = (firmver >= 0x60006);
 		priv->has_ibss_any = (firmver >= 0x60010);
 		priv->has_wep = (firmver >= 0x40020);
@@ -1575,8 +1763,6 @@
 		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
 		priv->ibss_port = 1;
 
-		/* FIXME: Which firmware really do have a broken reset */
-		priv->broken_cor_reset = (firmver < 0x60000);
 		/* Tested with Agere firmware :
 		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
 		 * Tested CableTron firmware : 4.32 => Anton */
@@ -1628,18 +1814,21 @@
 		/* D-Link MAC : 00:40:05:* */
 		/* Addtron MAC : 00:90:D1:* */
 		printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
-		       "version %d.%02d\n", dev->name,
-		       sta_id.major, sta_id.minor);
+		       "version %d.%d.%d\n", dev->name,
+		       sta_id.major, sta_id.minor, sta_id.variant);
+
+		firmver = ((unsigned long)sta_id.major << 16) |
+			((unsigned long)sta_id.minor << 8) | sta_id.variant;
 
-		priv->has_ibss = (firmver >= 0x00007); /* FIXME */
-		priv->has_big_wep = priv->has_wep = (firmver >= 0x00008);
-		priv->has_pm = (firmver >= 0x00007);
+		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
+		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
+		priv->has_pm = (firmver >= 0x000700);
 
-		if (firmver >= 0x00008)
+		if (firmver >= 0x000800)
 			priv->ibss_port = 0;
 		else {
 			printk(KERN_NOTICE "%s: Intersil firmware earlier "
-			       "than v0.08 - several features not supported\n",
+			       "than v0.8.x - several features not supported\n",
 			       dev->name);
 			priv->ibss_port = 1;
 		}
@@ -1663,16 +1852,16 @@
 	u16 reclen;
 	int len;
 
-	TRACE_ENTER("orinoco");
-
-	orinoco_lock(priv);
+	TRACE_ENTER(dev->name);
 
+	/* No need to lock, the resetting flag is already set in
+	 * alloc_orinocodev() */
 	priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
 
-	/* Do standard firmware reset */
-	err = hermes_reset(hw);
+	/* Initialize the firmware */
+	err = hermes_init(hw);
 	if (err != 0) {
-		printk(KERN_ERR "%s: failed to reset hardware (err = %d)\n",
+		printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
 		       dev->name, err);
 		goto out;
 	}
@@ -1801,20 +1990,38 @@
 	priv->wep_on = 0;
 	priv->tx_key = 0;
 
-	printk(KERN_DEBUG "%s: ready\n", dev->name);
+	priv->hw_unavailable = 0;
 
- out:
-	orinoco_unlock(priv);
+	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+	if (err == -EIO) {
+		/* Try workaround for old Symbol firmware bug */
+		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
+		       "(old Symbol firmware?). Trying to work around... ",
+		       dev->name);
+		
+		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+		if (err)
+			printk("failed!\n");
+		else
+			printk("ok.\n");
+	}
+	if (err) {
+		printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
+		goto out;
+	}
 
-	TRACE_EXIT("orinoco");
+	printk(KERN_DEBUG "%s: ready\n", dev->name);
 
+ out:
+	TRACE_EXIT(dev->name);
 	return err;
 }
 
 struct net_device_stats *
 orinoco_get_stats(struct net_device *dev)
 {
-	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
+	struct orinoco_private *priv = dev->priv;
 	
 	return &priv->stats;
 }
@@ -1822,15 +2029,22 @@
 struct iw_statistics *
 orinoco_get_wireless_stats(struct net_device *dev)
 {
-	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
+	struct orinoco_private *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	struct iw_statistics *wstats = &priv->wstats;
 	int err = 0;
+	unsigned long flags;
 
-	if (! netif_device_present(dev))
-		return NULL; /* FIXME: We may be able to do better than this */
+	if (! netif_device_present(dev)) {
+		printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
+		       dev->name);
+		return NULL; /* FIXME: Can we do better than this? */
+	}
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return NULL; /* FIXME: Erg, we've been signalled, how
+			      * do we propagate this back up? */
 
 	if (priv->iw_mode == IW_MODE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
@@ -1850,9 +2064,6 @@
 		err = HERMES_READ_RECORD(hw, USER_BAP,
 					 HERMES_RID_COMMSQUALITY, &cq);
 		
-		DEBUG(3, "%s: Global stats = %X-%X-%X\n", dev->name,
-		      cq.qual, cq.signal, cq.noise);
-
 		wstats->qual.qual = (int)le16_to_cpu(cq.qual);
 		wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
 		wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
@@ -1862,11 +2073,11 @@
 	/* We can't really wait for the tallies inquiry command to
 	 * complete, so we just use the previous results and trigger
 	 * a new tallies inquiry command for next time - Jean II */
-	/* FIXME: Hmm.. seems a bit ugly, I wonder if there's a way to
-	   do better - dgibson */
+	/* FIXME: We're in user context (I think?), so we should just
+           wait for the tallies to come through */
 	err = hermes_inquire(hw, HERMES_INQ_TALLIES);
                
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	if (err)
 		return NULL;
@@ -1926,21 +2137,31 @@
 	struct ethhdr *eh;
 	int len, data_len, data_off;
 	struct hermes_tx_descriptor desc;
+	unsigned long flags;
+
+	TRACE_ENTER(dev->name);
 
 	if (! netif_running(dev)) {
 		printk(KERN_ERR "%s: Tx on stopped device!\n",
 		       dev->name);
+		TRACE_EXIT(dev->name);
 		return 1;
-
 	}
 	
 	if (netif_queue_stopped(dev)) {
-		printk(KERN_ERR "%s: Tx while transmitter busy!\n", 
+		printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
 		       dev->name);
+		TRACE_EXIT(dev->name);
 		return 1;
 	}
 	
-	orinoco_lock(priv);
+	if (orinoco_lock(priv, &flags) != 0) {
+		printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
+		       dev->name);
+		TRACE_EXIT(dev->name);
+/*  		BUG(); */
+		return 1;
+	}
 
 	/* Length of the packet body */
 	/* FIXME: what if the skb is smaller than this? */
@@ -2011,14 +2232,17 @@
 	dev->trans_start = jiffies;
 	stats->tx_bytes += data_off + data_len;
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	dev_kfree_skb(skb);
 
+	TRACE_EXIT(dev->name);
+
 	return 0;
  fail:
+	TRACE_EXIT(dev->name);
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 	return err;
 }
 
@@ -2028,27 +2252,21 @@
 	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
 	struct net_device_stats *stats = &priv->stats;
 	struct hermes *hw = &priv->hw;
-	int err = 0;
 
-	printk(KERN_WARNING "%s: Tx timeout! Resetting card. ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n", dev->name, hermes_read_regn(hw, ALLOCFID), hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
+	printk(KERN_WARNING "%s: Tx timeout! "
+	       "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
+	       dev->name, hermes_read_regn(hw, ALLOCFID),
+	       hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
 
 	stats->tx_errors++;
 
-	err = orinoco_reset(priv);
-	if (err)
-		printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
-		       dev->name, err);
-	else {
-		dev->trans_start = jiffies;
-		netif_wake_queue(dev);
-	}
+	schedule_task(&priv->timeout_task);
 }
 
 static int
 orinoco_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct orinoco_private *priv = dev->priv;
-	TRACE_ENTER(dev->name);
 
 	if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
 		return -EINVAL;
@@ -2059,11 +2277,10 @@
 
 	dev->mtu = new_mtu;
 
-	TRACE_EXIT(dev->name);
-
 	return 0;
 }
 
+/* FIXME: return int? */
 static void
 __orinoco_set_multicast_list(struct net_device *dev)
 {
@@ -2072,17 +2289,6 @@
 	int err = 0;
 	int promisc, mc_count;
 
-	/* We'll wait until it's ready. Anyway, the network doesn't call us
-	 * here until we are open - Jean II */
-	/* FIXME: do we need this test at all? */
-	if (! netif_device_present(dev)) {
-		printk(KERN_WARNING "%s: __orinoco_set_multicast_list() called while device "
-		       "not present.\n", dev->name);
-		return;
-	}
-
-	TRACE_ENTER(dev->name);
-
 	/* The Hermes doesn't seem to have an allmulti mode, so we go
 	 * into promiscuous mode and let the upper levels deal. */
 	if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
@@ -2140,8 +2346,6 @@
 		dev->flags |= IFF_PROMISC;
 	else
 		dev->flags &= ~IFF_PROMISC;
-
-	TRACE_EXIT(dev->name);
 }
 
 /********************************************************************/
@@ -2156,6 +2360,7 @@
 	struct iw_range range;
 	int numrates;
 	int i, k;
+	unsigned long flags;
 
 	TRACE_ENTER(dev->name);
 
@@ -2165,9 +2370,12 @@
 
 	rrq->length = sizeof(range);
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
+
 	mode = priv->iw_mode;
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	memset(&range, 0, sizeof(range));
 
@@ -2240,7 +2448,9 @@
 	range.min_frag = 256;
 	range.max_frag = 2346;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	if (priv->has_wep) {
 		range.max_encoding_tokens = ORINOCO_MAX_KEYS;
 
@@ -2255,7 +2465,7 @@
 		range.num_encoding_sizes = 0;
 		range.max_encoding_tokens = 0;
 	}
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 		
 	range.min_pmp = 0;
 	range.max_pmp = 65535000;
@@ -2297,6 +2507,7 @@
 	u16 xlen = 0;
 	int err = 0;
 	char keybuf[ORINOCO_MAX_KEY_SIZE];
+	unsigned long flags;
 	
 	if (erq->pointer) {
 		/* We actually have a key to set */
@@ -2307,7 +2518,9 @@
 			return -EFAULT;
 	}
 	
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	
 	if (erq->pointer) {
 		if (erq->length > ORINOCO_MAX_KEY_SIZE) {
@@ -2371,9 +2584,10 @@
 	priv->tx_key = setindex;
 	priv->wep_on = enable;
 	priv->wep_restrict = restricted;
+
 	
  out:
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -2384,9 +2598,12 @@
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	u16 xlen = 0;
 	char keybuf[ORINOCO_MAX_KEY_SIZE];
-
+	int err;
+	unsigned long flags;
 	
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
 		index = priv->tx_key;
@@ -2412,7 +2629,7 @@
 		memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
 	}
 	
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	if (erq->pointer) {
 		if (copy_to_user(erq->pointer, keybuf, xlen))
@@ -2426,6 +2643,8 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	char essidbuf[IW_ESSID_MAX_SIZE+1];
+	int err;
+	unsigned long flags;
 
 	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
 	 * anyway... - Jean II */
@@ -2442,11 +2661,13 @@
 		essidbuf[erq->length] = '\0';
 	}
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return 0;
 }
@@ -2457,6 +2678,7 @@
 	char essidbuf[IW_ESSID_MAX_SIZE+1];
 	int active;
 	int err = 0;
+	unsigned long flags;
 
 	TRACE_ENTER(dev->name);
 
@@ -2465,9 +2687,11 @@
 		if (err)
 			return err;
 	} else {
-		orinoco_lock(priv);
+		err = orinoco_lock(priv, &flags);
+		if (err)
+			return err;
 		memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
-		orinoco_unlock(priv);
+		orinoco_unlock(priv, &flags);
 	}
 
 	erq->flags = 1;
@@ -2485,6 +2709,8 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
+	int err;
+	unsigned long flags;
 
 	if (nrq->length > IW_ESSID_MAX_SIZE)
 		return -E2BIG;
@@ -2496,11 +2722,13 @@
 
 	nickbuf[nrq->length] = '\0';
 	
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	memcpy(priv->nick, nickbuf, sizeof(priv->nick));
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return 0;
 }
@@ -2509,10 +2737,15 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
+	int err;
+	unsigned long flags;
+
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-	orinoco_lock(priv);
 	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	nrq->length = strlen(nickbuf)+1;
 
@@ -2526,6 +2759,8 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int chan = -1;
+	int err;
+	unsigned long flags;
 
 	/* We can only use this in Ad-Hoc demo mode to set the operating
 	 * frequency, or in IBSS mode to set the frequency where the IBSS
@@ -2553,9 +2788,11 @@
 	     ! (priv->channel_mask & (1 << (chan-1)) ) )
 		return -EINVAL;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	priv->channel = chan;
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return 0;
 }
@@ -2566,13 +2803,16 @@
 	hermes_t *hw = &priv->hw;
 	u16 val;
 	int err;
+	unsigned long flags;
 
 	if (!priv->has_sensitivity)
 		return -EOPNOTSUPP;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &val);
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	if (err)
 		return err;
@@ -2587,6 +2827,8 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int val = srq->value;
+	int err;
+	unsigned long flags;
 
 	if (!priv->has_sensitivity)
 		return -EOPNOTSUPP;
@@ -2594,9 +2836,11 @@
 	if ((val < 1) || (val > 3))
 		return -EINVAL;
 	
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	priv->ap_density = val;
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return 0;
 }
@@ -2605,6 +2849,8 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int val = rrq->value;
+	int err;
+	unsigned long flags;
 
 	if (rrq->disabled)
 		val = 2347;
@@ -2612,9 +2858,12 @@
 	if ( (val < 0) || (val > 2347) )
 		return -EINVAL;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
+
 	priv->rts_thresh = val;
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return 0;
 }
@@ -2623,8 +2872,11 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int err = 0;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	if (priv->has_mwo) {
 		if (frq->disabled)
@@ -2646,7 +2898,7 @@
 		}
 	}
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -2657,8 +2909,11 @@
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 val;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	
 	if (priv->has_mwo) {
 		err = hermes_read_wordrec(hw, USER_BAP,
@@ -2681,7 +2936,7 @@
 		frq->fixed = 1;
 	}
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 	
 	return err;
 }
@@ -2693,6 +2948,7 @@
 	int ratemode = -1;
 	int bitrate; /* 100s of kilobits */
 	int i;
+	unsigned long flags;
 	
 	/* As the user space doesn't know our highest rate, it uses -1
 	 * to ask us to set the highest rate.  Test it using "iwconfig
@@ -2719,9 +2975,11 @@
 	if (ratemode == -1)
 		return -EINVAL;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	priv->bitratemode = ratemode;
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -2734,8 +2992,11 @@
 	int ratemode;
 	int i;
 	u16 val;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	ratemode = priv->bitratemode;
 
@@ -2785,7 +3046,7 @@
 	}
 
  out:
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -2794,9 +3055,11 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int err = 0;
+	unsigned long flags;
 
-
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	if (prq->disabled) {
 		priv->pm_on = 0;
@@ -2836,7 +3099,7 @@
 	}
 
  out:
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -2847,8 +3110,11 @@
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 enable, period, timeout, mcast;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
 	if (err)
@@ -2882,7 +3148,7 @@
 		prq->flags |= IW_POWER_UNICAST_R;
 
  out:
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -2894,8 +3160,11 @@
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 short_limit, long_limit, lifetime;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
 				  &short_limit);
@@ -2932,7 +3201,7 @@
 	}
 
  out:
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -2942,14 +3211,19 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int val = *( (int *) wrq->u.name );
+	int err;
+	unsigned long flags;
+
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-	orinoco_lock(priv);
 	priv->ibss_port = val ;
 
 	/* Actually update the mode we are using */
 	set_port_type(priv);
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 	return 0;
 }
 
@@ -2957,10 +3231,15 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int *val = (int *)wrq->u.name;
+	int err;
+	unsigned long flags;
+
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-	orinoco_lock(priv);
 	*val = priv->ibss_port;
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return 0;
 }
@@ -2970,15 +3249,18 @@
 	struct orinoco_private *priv = dev->priv;
 	int val = *( (int *) wrq->u.name );
 	int err = 0;
+	unsigned long flags;
+
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-	orinoco_lock(priv);
 	switch (val) {
 	case 0: /* Try to do IEEE ad-hoc mode */
 		if (! priv->has_ibss) {
 			err = -EINVAL;
 			break;
 		}
-		DEBUG(2, "%s: Prefer IBSS Ad-Hoc mode\n", dev->name);
 		priv->prefer_port3 = 0;
 			
 		break;
@@ -2988,7 +3270,6 @@
 			err = -EINVAL;
 			break;
 		}
-		DEBUG(2, "%s: Prefer Ad-Hoc demo mode\n", dev->name);
 		priv->prefer_port3 = 1;
 		break;
 
@@ -3000,7 +3281,7 @@
 		/* Actually update the mode we are using */
 		set_port_type(priv);
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -3009,10 +3290,15 @@
 {
 	struct orinoco_private *priv = dev->priv;
 	int *val = (int *)wrq->u.name;
+	int err;
+	unsigned long flags;
+
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
-	orinoco_lock(priv);
 	*val = priv->prefer_port3;
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return 0;
 }
@@ -3026,6 +3312,7 @@
 	int number = srq->length;
 	int i;
 	int err = 0;
+	unsigned long flags;
 
 	/* Check the number of addresses */
 	if (number > IW_MAX_SPY)
@@ -3039,7 +3326,9 @@
 	}
 
 	/* Make sure nobody mess with the structure while we do */
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	/* orinoco_lock() doesn't disable interrupts, so make sure the
 	 * interrupt rx path don't get confused while we copy */
@@ -3057,18 +3346,8 @@
 		priv->spy_number = number;
 	}
 
-	/* Time to show what we have done... */
-	DEBUG(0, "%s: New spy list:\n", dev->name);
-	for (i = 0; i < number; i++) {
-		DEBUG(0, "%s: %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
-		      dev->name, i+1,
-		      priv->spy_address[i][0], priv->spy_address[i][1],
-		      priv->spy_address[i][2], priv->spy_address[i][3],
-		      priv->spy_address[i][4], priv->spy_address[i][5]);
-	}
-
 	/* Now, let the others play */
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	return err;
 }
@@ -3080,8 +3359,12 @@
 	struct iw_quality spy_stat[IW_MAX_SPY];
 	int number;
 	int i;
+	int err;
+	unsigned long flags;
 
-	orinoco_lock(priv);
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
 
 	number = priv->spy_number;
 	if ((number > 0) && (srq->pointer)) {
@@ -3101,7 +3384,7 @@
 			priv->spy_stat[i].updated = 0;
 	}
 
-	orinoco_unlock(priv);
+	orinoco_unlock(priv, &flags);
 
 	/* Push stuff to user space */
 	srq->length = number;
@@ -3121,39 +3404,39 @@
 	struct orinoco_private *priv = dev->priv;
 	struct iwreq *wrq = (struct iwreq *)rq;
 	int err = 0;
+	int tmp;
 	int changed = 0;
+	unsigned long flags;
 
 	TRACE_ENTER(dev->name);
 
 	/* In theory, we could allow most of the the SET stuff to be
-	 * done In practice, the laps of time at startup when the card
-	 * is not ready is very short, so why bother...  Note that
-	 * netif_device_present is different from up/down (ifconfig),
-	 * when the device is not yet up, it is usually already
-	 * ready...  Jean II */
+	 * done. In practice, the lapse of time at startup when the
+	 * card is not ready is very short, so why bother...  Note
+	 * that netif_device_present is different from up/down
+	 * (ifconfig), when the device is not yet up, it is usually
+	 * already ready...  Jean II */
 	if (! netif_device_present(dev))
 		return -ENODEV;
 
 	switch (cmd) {
 	case SIOCGIWNAME:
-		DEBUG(1, "%s: SIOCGIWNAME\n", dev->name);
 		strcpy(wrq->u.name, "IEEE 802.11-DS");
 		break;
 		
 	case SIOCGIWAP:
-		DEBUG(1, "%s: SIOCGIWAP\n", dev->name);
 		wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
 		err = orinoco_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
 		break;
 
 	case SIOCGIWRANGE:
-		DEBUG(1, "%s: SIOCGIWRANGE\n", dev->name);
 		err = orinoco_ioctl_getiwrange(dev, &wrq->u.data);
 		break;
 
 	case SIOCSIWMODE:
-		DEBUG(1, "%s: SIOCSIWMODE\n", dev->name);
-		orinoco_lock(priv);
+		err = orinoco_lock(priv, &flags);
+		if (err)
+			return err;
 		switch (wrq->u.mode) {
 		case IW_MODE_ADHOC:
 			if (! (priv->has_ibss || priv->has_port3) )
@@ -3174,18 +3457,18 @@
 			break;
 		}
 		set_port_type(priv);
-		orinoco_unlock(priv);
+		orinoco_unlock(priv, &flags);
 		break;
 
 	case SIOCGIWMODE:
-		DEBUG(1, "%s: SIOCGIWMODE\n", dev->name);
-		orinoco_lock(priv);
+		err = orinoco_lock(priv, &flags);
+		if (err)
+			return err;
 		wrq->u.mode = priv->iw_mode;
-		orinoco_unlock(priv);
+		orinoco_unlock(priv, &flags);
 		break;
 
 	case SIOCSIWENCODE:
-		DEBUG(1, "%s: SIOCSIWENCODE\n", dev->name);
 		if (! priv->has_wep) {
 			err = -EOPNOTSUPP;
 			break;
@@ -3197,7 +3480,6 @@
 		break;
 
 	case SIOCGIWENCODE:
-		DEBUG(1, "%s: SIOCGIWENCODE\n", dev->name);
 		if (! priv->has_wep) {
 			err = -EOPNOTSUPP;
 			break;
@@ -3212,106 +3494,94 @@
 		break;
 
 	case SIOCSIWESSID:
-		DEBUG(1, "%s: SIOCSIWESSID\n", dev->name);
 		err = orinoco_ioctl_setessid(dev, &wrq->u.essid);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWESSID:
-		DEBUG(1, "%s: SIOCGIWESSID\n", dev->name);
 		err = orinoco_ioctl_getessid(dev, &wrq->u.essid);
 		break;
 
 	case SIOCSIWNICKN:
-		DEBUG(1, "%s: SIOCSIWNICKN\n", dev->name);
 		err = orinoco_ioctl_setnick(dev, &wrq->u.data);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWNICKN:
-		DEBUG(1, "%s: SIOCGIWNICKN\n", dev->name);
 		err = orinoco_ioctl_getnick(dev, &wrq->u.data);
 		break;
 
 	case SIOCGIWFREQ:
-		DEBUG(1, "%s: SIOCGIWFREQ\n", dev->name);
-		wrq->u.freq.m = orinoco_hw_get_freq(priv);
-		wrq->u.freq.e = 1;
+		tmp = orinoco_hw_get_freq(priv);
+		if (tmp < 0) {
+			err = tmp;
+		} else {
+			wrq->u.freq.m = tmp;
+			wrq->u.freq.e = 1;
+		}
 		break;
 
 	case SIOCSIWFREQ:
-		DEBUG(1, "%s: SIOCSIWFREQ\n", dev->name);
 		err = orinoco_ioctl_setfreq(dev, &wrq->u.freq);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWSENS:
-		DEBUG(1, "%s: SIOCGIWSENS\n", dev->name);
 		err = orinoco_ioctl_getsens(dev, &wrq->u.sens);
 		break;
 
 	case SIOCSIWSENS:
-		DEBUG(1, "%s: SIOCSIWSENS\n", dev->name);
 		err = orinoco_ioctl_setsens(dev, &wrq->u.sens);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWRTS:
-		DEBUG(1, "%s: SIOCGIWRTS\n", dev->name);
 		wrq->u.rts.value = priv->rts_thresh;
 		wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
 		wrq->u.rts.fixed = 1;
 		break;
 
 	case SIOCSIWRTS:
-		DEBUG(1, "%s: SIOCSIWRTS\n", dev->name);
 		err = orinoco_ioctl_setrts(dev, &wrq->u.rts);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCSIWFRAG:
-		DEBUG(1, "%s: SIOCSIWFRAG\n", dev->name);
 		err = orinoco_ioctl_setfrag(dev, &wrq->u.frag);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWFRAG:
-		DEBUG(1, "%s: SIOCGIWFRAG\n", dev->name);
 		err = orinoco_ioctl_getfrag(dev, &wrq->u.frag);
 		break;
 
 	case SIOCSIWRATE:
-		DEBUG(1, "%s: SIOCSIWRATE\n", dev->name);
 		err = orinoco_ioctl_setrate(dev, &wrq->u.bitrate);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWRATE:
-		DEBUG(1, "%s: SIOCGIWRATE\n", dev->name);
 		err = orinoco_ioctl_getrate(dev, &wrq->u.bitrate);
 		break;
 
 	case SIOCSIWPOWER:
-		DEBUG(1, "%s: SIOCSIWPOWER\n", dev->name);
 		err = orinoco_ioctl_setpower(dev, &wrq->u.power);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWPOWER:
-		DEBUG(1, "%s: SIOCGIWPOWER\n", dev->name);
 		err = orinoco_ioctl_getpower(dev, &wrq->u.power);
 		break;
 
 	case SIOCGIWTXPOW:
-		DEBUG(1, "%s: SIOCGIWTXPOW\n", dev->name);
 		/* The card only supports one tx power, so this is easy */
 		wrq->u.txpower.value = 15; /* dBm */
 		wrq->u.txpower.fixed = 1;
@@ -3321,30 +3591,23 @@
 
 #if WIRELESS_EXT > 10
 	case SIOCSIWRETRY:
-		DEBUG(1, "%s: SIOCSIWRETRY\n", dev->name);
 		err = -EOPNOTSUPP;
 		break;
 
 	case SIOCGIWRETRY:
-		DEBUG(1, "%s: SIOCGIWRETRY\n", dev->name);
 		err = orinoco_ioctl_getretry(dev, &wrq->u.retry);
 		break;
 #endif /* WIRELESS_EXT > 10 */
 
 	case SIOCSIWSPY:
-		DEBUG(1, "%s: SIOCSIWSPY\n", dev->name);
-
 		err = orinoco_ioctl_setspy(dev, &wrq->u.data);
 		break;
 
 	case SIOCGIWSPY:
-		DEBUG(1, "%s: SIOCGIWSPY\n", dev->name);
-
 		err = orinoco_ioctl_getspy(dev, &wrq->u.data);
 		break;
 
 	case SIOCGIWPRIV:
-		DEBUG(1, "%s: SIOCGIWPRIV\n", dev->name);
 		if (wrq->u.data.pointer) {
 			struct iw_priv_args privtab[] = {
 				{ SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
@@ -3381,25 +3644,17 @@
 	       
 	case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
 	case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x0 (force_reset)\n",
-		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
 			break;
 		}
 		
-		printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
+		printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
 
-		/* We need the xmit lock because it protects the
-		   multicast list which orinoco_reset() reads */
-		spin_lock_bh(&dev->xmit_lock);
-		orinoco_reset(priv);
-		spin_unlock_bh(&dev->xmit_lock);
+		schedule_task(&priv->timeout_task);
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x2 (set_port3)\n",
-		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
 			break;
@@ -3411,14 +3666,10 @@
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x3: /* get_port3 */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x3 (get_port3)\n",
-		      dev->name);
 		err = orinoco_ioctl_getport3(dev, wrq);
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x4: /* set_preamble */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x4 (set_preamble)\n",
-		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
 			break;
@@ -3432,32 +3683,32 @@
 		if(priv->has_preamble) {
 			int val = *( (int *) wrq->u.name );
 
-			orinoco_lock(priv);
-			if(val)
+			err = orinoco_lock(priv, &flags);
+			if (err)
+				return err;
+			if (val)
 				priv->preamble = 1;
 			else
 				priv->preamble = 0;
-			orinoco_unlock(priv);
+			orinoco_unlock(priv, &flags);
 			changed = 1;
 		} else
 			err = -EOPNOTSUPP;
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x5: /* get_preamble */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x5 (get_preamble)\n",
-		      dev->name);
 		if(priv->has_preamble) {
 			int *val = (int *)wrq->u.name;
 
-			orinoco_lock(priv);
+			err = orinoco_lock(priv, &flags);
+			if (err)
+				return err;
 			*val = priv->preamble;
-			orinoco_unlock(priv);
+			orinoco_unlock(priv, &flags);
 		} else
 			err = -EOPNOTSUPP;
 		break;
 	case SIOCIWFIRSTPRIV + 0x6: /* set_ibssport */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x6 (set_ibssport)\n",
-		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
 			break;
@@ -3469,8 +3720,6 @@
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x7: /* get_ibssport */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x7 (get_ibssport)\n",
-		      dev->name);
 		err = orinoco_ioctl_getibssport(dev, wrq);
 		break;
 
@@ -3480,22 +3729,11 @@
 	}
 	
 	if (! err && changed && netif_running(dev)) {
-		/* We need the xmit lock because it protects the
-		   multicast list which orinoco_reset() reads */
-		spin_lock_bh(&dev->xmit_lock);
-		err = orinoco_reset(priv);
-		spin_unlock_bh(&dev->xmit_lock);
-		if (err) {
-			/* Ouch ! What are we supposed to do ? */
-			printk(KERN_ERR "orinoco_cs: Failed to set parameters on %s\n",
-			       dev->name);
-			netif_device_detach(dev);
-			orinoco_shutdown(priv);
-		}
+		err = orinoco_reconfigure(priv);
 	}		
 
 	TRACE_EXIT(dev->name);
-		
+
 	return err;
 }
 
@@ -3833,8 +4071,6 @@
 {
 	int err = 0;
 
-	TRACE_ENTER("orinoco");
-
 	/* create the directory for it to sit in */
 	dir_base = create_proc_entry("hermes", S_IFDIR, &proc_root);
 	if (dir_base == NULL) {
@@ -3843,15 +4079,13 @@
 		err = -ENOMEM;
 	}
 
-	TRACE_EXIT("orinoco");
-
 	return err;
 }
 
 int
-orinoco_proc_dev_init(struct orinoco_private *priv)
+orinoco_proc_dev_init(struct net_device *dev)
 {
-	struct net_device *dev = priv->ndev;
+	struct orinoco_private *priv = dev->priv;
 	struct proc_dir_entry *e;
 
 	priv->dir_dev = NULL;
@@ -3889,16 +4123,14 @@
 
 	return 0;
  fail:
-	orinoco_proc_dev_cleanup(priv);
+	orinoco_proc_dev_cleanup(dev);
 	return -ENOMEM;
 }
 
 void
-orinoco_proc_dev_cleanup(struct orinoco_private *priv)
+orinoco_proc_dev_cleanup(struct net_device *dev)
 {
-	struct net_device *dev = priv->ndev;
-
-	TRACE_ENTER(priv->ndev->name);
+	struct orinoco_private *priv = dev->priv;
 
 	if (priv->dir_dev) {
 		remove_proc_entry("prof", priv->dir_dev);
@@ -3907,29 +4139,22 @@
 		remove_proc_entry(dev->name, dir_base);
 		priv->dir_dev = NULL;
 	}
-
-	TRACE_EXIT(priv->ndev->name);
 }
 
 static void
 orinoco_proc_cleanup(void)
 {
-	TRACE_ENTER("orinoco");
-
 	if (dir_base) {
 		remove_proc_entry("hermes", &proc_root);
 		dir_base = NULL;
 	}
-	
-	TRACE_EXIT("orinoco");
 }
 
-struct net_device *alloc_orinocodev(int sizeof_card)
+struct net_device *alloc_orinocodev(int sizeof_card, int (*hard_reset)(struct orinoco_private *))
 {
 	struct net_device *dev;
 	struct orinoco_private *priv;
 
-	TRACE_ENTER("orinoco");
 	dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
 	priv = (struct orinoco_private *)dev->priv;
 	priv->ndev = dev;
@@ -3949,29 +4174,39 @@
 	dev->change_mtu = orinoco_change_mtu;
 	dev->set_multicast_list = orinoco_set_multicast_list;
 
-	dev->open = NULL;		/* Caller *must* override  these */
-	dev->stop = NULL;
-
-	/* Setup the private structure */
+	/* Set up default callbacks */
+	dev->open = orinoco_open;
+	dev->stop = orinoco_stop;
+	priv->hard_reset = hard_reset;
 
 	spin_lock_init(&priv->lock);
-	priv->hard_reset = NULL;	/* Caller may override */
-	
-	TRACE_EXIT("orinoco");
+	priv->open = 0;
+	priv->hw_unavailable = 1; /* orinoco_init() must clear this
+				   * before anything else touches the
+				   * hardware */
+	INIT_TQUEUE(&priv->timeout_task, (void (*)(void *))orinoco_reset, dev);
+
 	return dev;
 
 }
 
 /********************************************************************/
-/* module bookkeeping                                               */
+/* Module initialization                                            */
 /********************************************************************/
 
 EXPORT_SYMBOL(alloc_orinocodev);
-EXPORT_SYMBOL(orinoco_shutdown);
-EXPORT_SYMBOL(orinoco_reset);
+
+EXPORT_SYMBOL(__orinoco_up);
+EXPORT_SYMBOL(__orinoco_down);
+EXPORT_SYMBOL(orinoco_reinit_firmware);
+
 EXPORT_SYMBOL(orinoco_proc_dev_init);
 EXPORT_SYMBOL(orinoco_proc_dev_cleanup);
 EXPORT_SYMBOL(orinoco_interrupt);
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = "orinoco.c 0.13 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 static int __init init_orinoco(void)
 {
diff -Nru a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
--- a/drivers/net/wireless/orinoco.h	Fri Sep 27 14:51:03 2002
+++ b/drivers/net/wireless/orinoco.h	Fri Sep 27 14:51:03 2002
@@ -7,6 +7,8 @@
 #ifndef _ORINOCO_H
 #define _ORINOCO_H
 
+#include "hermes.h"
+
 /* To enable debug messages */
 //#define ORINOCO_DEBUG		3
 
@@ -18,24 +20,26 @@
 #define ORINOCO_MAX_KEY_SIZE	14
 #define ORINOCO_MAX_KEYS	4
 
-typedef struct orinoco_key {
-	u16 len;	/* always store little-endian */
+struct orinoco_key {
+	u16 len;	/* always stored as little-endian */
 	char data[ORINOCO_MAX_KEY_SIZE];
-} __attribute__ ((packed)) orinoco_key_t;
+} __attribute__ ((packed));
 
-typedef orinoco_key_t orinoco_keys_t[ORINOCO_MAX_KEYS];
+#define ORINOCO_INTEN	 	( HERMES_EV_RX | HERMES_EV_ALLOC | HERMES_EV_TX | \
+				HERMES_EV_TXEXC | HERMES_EV_WTERR | HERMES_EV_INFO | \
+				HERMES_EV_INFDROP )
 
-/*====================================================================*/
 
 struct orinoco_private {
 	void *card;	/* Pointer to card dependant structure */
-	/* card dependant extra reset code (i.e. bus/interface specific */
 	int (*hard_reset)(struct orinoco_private *);
 
+	/* Synchronisation stuff */
 	spinlock_t lock;
-	long state;
-#define ORINOCO_STATE_INIRQ 0
-#define ORINOCO_STATE_DOIRQ 1
+	int hw_unavailable;
+	struct tq_struct timeout_task;
+
+	int open;
 
 	/* Net device stuff */
 	struct net_device *ndev;
@@ -58,14 +62,13 @@
 	int has_preamble;
 	int has_sensitivity;
 	int nicbuf_size;
-	int broken_cor_reset;
 	u16 channel_mask;
 
 	/* Configuration paramaters */
 	u32 iw_mode;
 	int prefer_port3;
 	u16 wep_on, wep_restrict, tx_key;
-	orinoco_keys_t keys;
+	struct orinoco_key keys[ORINOCO_MAX_KEYS];
 	int bitratemode;
  	char nick[IW_ESSID_MAX_SIZE+1];
 	char desired_essid[IW_ESSID_MAX_SIZE+1];
@@ -81,38 +84,58 @@
 #endif
 
 	/* Configuration dependent variables */
-	int port_type, allow_ibss;
+	int port_type, createibss;
 	int promiscuous, mc_count;
 
-
 	/* /proc based debugging stuff */
 	struct proc_dir_entry *dir_dev;
 };
 
-/*====================================================================*/
-
-extern struct list_head orinoco_instances;
-
 #ifdef ORINOCO_DEBUG
 extern int orinoco_debug;
 #define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
-#define DEBUGMORE(n, args...) do { if (orinoco_debug>(n)) printk(args); } while (0)
 #else
 #define DEBUG(n, args...) do { } while (0)
-#define DEBUGMORE(n, args...) do { } while (0)
 #endif	/* ORINOCO_DEBUG */
 
 #define TRACE_ENTER(devname) DEBUG(2, "%s: -> " __FUNCTION__ "()\n", devname);
 #define TRACE_EXIT(devname)  DEBUG(2, "%s: <- " __FUNCTION__ "()\n", devname);
 
-#define RUP_EVEN(a) ( (a) % 2 ? (a) + 1 : (a) )
+extern struct net_device *alloc_orinocodev(int sizeof_card,
+					   int (*hard_reset)(struct orinoco_private *));
+extern int __orinoco_up(struct net_device *dev);
+extern int __orinoco_down(struct net_device *dev);
+int orinoco_reinit_firmware(struct net_device *dev);
 
-/* utility routines */
-struct net_device *alloc_orinocodev(int sizeof_card);
-extern void orinoco_shutdown(struct orinoco_private *dev);
-extern int orinoco_reset(struct orinoco_private *dev);
-extern int orinoco_proc_dev_init(struct orinoco_private *dev);
-extern void orinoco_proc_dev_cleanup(struct orinoco_private *priv);
+extern int orinoco_proc_dev_init(struct net_device *dev);
+extern void orinoco_proc_dev_cleanup(struct net_device *dev);
 extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
+
+/********************************************************************/
+/* Locking and synchronization functions                            */
+/********************************************************************/
+
+/* These functions *must* be inline or they will break horribly on
+ * SPARC, due to its weird semantics for save/restore flags. extern
+ * inline should prevent the kernel from linking or module from
+ * loading if they are not inlined. */
+extern inline int orinoco_lock(struct orinoco_private *priv,
+			       unsigned long *flags)
+{
+	spin_lock_irqsave(&priv->lock, *flags);
+	if (priv->hw_unavailable) {
+		printk(KERN_DEBUG "orinoco_lock() called with hw_unavailable (dev=%p)\n",
+		       priv->ndev);
+		spin_unlock_irqrestore(&priv->lock, *flags);
+		return -EBUSY;
+	}
+	return 0;
+}
+
+extern inline void orinoco_unlock(struct orinoco_private *priv,
+				  unsigned long *flags)
+{
+	spin_unlock_irqrestore(&priv->lock, *flags);
+}
 
 #endif /* _ORINOCO_H */
diff -Nru a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
--- a/drivers/net/wireless/orinoco_cs.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/net/wireless/orinoco_cs.c	Fri Sep 27 14:51:05 2002
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.11b	- (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.13	- (formerly known as dldwd_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -32,7 +32,6 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
-#include <linux/list.h>
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
@@ -42,12 +41,11 @@
 #include <pcmcia/ds.h>
 #include <pcmcia/bus_ops.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
-/*====================================================================*/
-
-static char version[] __initdata = "orinoco_cs.c 0.11b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+/********************************************************************/
+/* Module stuff							    */
+/********************************************************************/
 
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
@@ -55,235 +53,131 @@
 MODULE_LICENSE("Dual MPL/GPL");
 #endif
 
-/* Parameters that can be set with 'insmod' */
+/* Module parameters */
 
 /* The old way: bit map of interrupts to choose from */
 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
 static uint irq_mask = 0xdeb8;
 /* Newer, simpler way of listing specific interrupts */
 static int irq_list[4] = { -1 };
-/* Do a Pcmcia soft reset (may help some cards) */
-static int reset_cor = -1;
+
 /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
  * don't have any CIS entry for it. This workaround it... */
 static int ignore_cis_vcc; /* = 0 */
 
 MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM(reset_cor, "i");
 MODULE_PARM(ignore_cis_vcc, "i");
 
-/* Pcmcia specific structure */
+/********************************************************************/
+/* Magic constants						    */
+/********************************************************************/
+
+/*
+ * The dev_info variable is the "key" that is used to match up this
+ * device driver with appropriate cards, through the card
+ * configuration database.
+ */
+static dev_info_t dev_info = "orinoco_cs";
+
+/********************************************************************/
+/* Data structures						    */
+/********************************************************************/
+
+/* PCMCIA specific device information (goes in the card field of
+ * struct orinoco_private */
 struct orinoco_pccard {
 	dev_link_t link;
 	dev_node_t node;
+
+	/* Used to handle hard reset */
+	wait_queue_head_t hard_reset_queue;
+	int hard_reset_flag;
 };
 
 /*
- * Function prototypes
+ * A linked list of "instances" of the device.  Each actual PCMCIA
+ * card corresponds to one device instance, and is described by one
+ * dev_link_t structure (defined in ds.h).
  */
+static dev_link_t *dev_list; /* = NULL */
 
-/* struct net_device methods */
-static int orinoco_cs_open(struct net_device *dev);
-static int orinoco_cs_stop(struct net_device *dev);
+/********************************************************************/
+/* Function prototypes						    */
+/********************************************************************/
+
+/* device methods */
+static int orinoco_cs_hard_reset(struct orinoco_private *priv);
 
 /* PCMCIA gumpf */
 static void orinoco_cs_config(dev_link_t * link);
 static void orinoco_cs_release(u_long arg);
 static int orinoco_cs_event(event_t event, int priority,
-		       event_callback_args_t * args);
+			    event_callback_args_t * args);
 
 static dev_link_t *orinoco_cs_attach(void);
 static void orinoco_cs_detach(dev_link_t *);
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-static dev_info_t dev_info = "orinoco_cs";
-
-/*
-   A linked list of "instances" of the dummy device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-
-static dev_link_t *dev_list; /* = NULL */
-
-/*====================================================================*/
-
-static void
-cs_error(client_handle_t handle, int func, int ret)
-{
-	error_info_t err = { func, ret };
-	CardServices(ReportError, handle, &err);
-}
+/********************************************************************/
+/* Device methods     						    */
+/********************************************************************/
 
 static int
-orinoco_cs_open(struct net_device *dev)
+orinoco_cs_hard_reset(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
-	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
+	struct orinoco_pccard *card = priv->card;
 	dev_link_t *link = &card->link;
 	int err;
-	
-	TRACE_ENTER(dev->name);
 
-	link->open++;
-	netif_device_attach(dev);
-	
-	err = orinoco_reset(priv);
-	if (err)
-		orinoco_cs_stop(dev);
-	else
-		netif_start_queue(dev);
-
-	TRACE_EXIT(dev->name);
-
-	return err;
-}
-
-static int
-orinoco_cs_stop(struct net_device *dev)
-{
-	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
-	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
-	dev_link_t *link = &card->link;
+	card->hard_reset_flag = 0;
 
-	TRACE_ENTER(dev->name);
-
-	netif_stop_queue(dev);
+	err = CardServices(ResetCard, link->handle, NULL);
+	if (err)
+		return err;
 
-	orinoco_shutdown(priv);
-	
-	link->open--;
+	wait_event_interruptible(card->hard_reset_queue,
+				 card->hard_reset_flag);
 
-	if (link->state & DEV_STALE_CONFIG)
-		mod_timer(&link->release, jiffies + HZ/20);
-	
-	TRACE_EXIT(dev->name);
-	
 	return 0;
 }
 
-/*
- * Do a soft reset of the Pcmcia card using the Configuration Option Register
- * Can't do any harm, and actually may do some good on some cards...
- * In fact, this seem necessary for Spectrum cards...
- */
-static int
-orinoco_cs_cor_reset(struct orinoco_private *priv)
-{
-	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
-	dev_link_t *link = &card->link;
-	conf_reg_t reg;
-	u_int default_cor; 
+/********************************************************************/
+/* PCMCIA stuff     						    */
+/********************************************************************/
 
-	TRACE_ENTER(priv->ndev->name);
-
-	/* Doing it if hardware is gone is guaranteed crash */
-	if(! (link->state & DEV_CONFIG) )
-		return -ENODEV;
-
-	/* Save original COR value */
-	reg.Function = 0;
-	reg.Action = CS_READ;
-	reg.Offset = CISREG_COR;
-	reg.Value = 0;
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-	default_cor = reg.Value;
-
-	DEBUG(2, "orinoco : orinoco_cs_cor_reset() : cor=0x%X\n", default_cor);
-
-	/* Soft-Reset card */
-	reg.Action = CS_WRITE;
-	reg.Offset = CISREG_COR;
-	reg.Value = (default_cor | COR_SOFT_RESET);
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-
-	/* Wait until the card has acknowledged our reset */
-	/* FIXME: mdelay() is deprecated -dgibson */
-	mdelay(1);
-
-#if 0 /* This seems to help on Symbol cards, but we're not sure why,
-       and we don't know what it will do to other cards */
-	reg.Action = CS_READ;
-	reg.Offset = CISREG_CCSR;
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-
-	/* Write 7 (RUN) to CCSR, but preserve the original bit 4 */
-	reg.Action = CS_WRITE;
-	reg.Offset = CISREG_CCSR;
-	reg.Value = 7 | (reg.Value & 0x10);
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-	mdelay(1);
-#endif
-
-	/* Restore original COR configuration index */
-	reg.Action = CS_WRITE;
-	reg.Offset = CISREG_COR;
-	reg.Value = (default_cor & ~COR_SOFT_RESET);
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-
-	/* Wait until the card has finished restarting */
-	/* FIXME: mdelay() is deprecated -dgibson */
-	mdelay(1);
-
-	TRACE_EXIT(priv->ndev->name);
-
-	return 0;
-}
-
-static int
-orinoco_cs_hard_reset(struct orinoco_private *priv)
+static void
+cs_error(client_handle_t handle, int func, int ret)
 {
-	if (! priv->broken_cor_reset)
-		return orinoco_cs_cor_reset(priv);
-	else
-		return 0;
-
-#if 0 /* We'd like to use ResetCard, but we can't for the moment - it sleeps */
-	/* Not sure what the second parameter is supposed to be - the 
-	   PCMCIA code doesn't actually use it */
-	if (in_interrupt()) {
-		printk("Not resetting card, in_interrupt() is true\n");
-		return 0;
-	} else {
-		printk("Doing ResetCard\n");
-		return CardServices(ResetCard, link->handle, NULL);
-	}
-#endif
+	error_info_t err = { func, ret };
+	CardServices(ReportError, handle, &err);
 }
 
+
 /* Remove zombie instances (card removed, detach pending) */
 static void
 flush_stale_links(void)
 {
 	dev_link_t *link, *next;
-	TRACE_ENTER("orinoco");
+
+	TRACE_ENTER("");
+
 	for (link = dev_list; link; link = next) {
 		next = link->next;
-		if (link->state & DEV_STALE_LINK)
+		if (link->state & DEV_STALE_LINK) {
 			orinoco_cs_detach(link);
+		}
 	}
-	TRACE_EXIT("orinoco");
+	TRACE_EXIT("");
 }
 
-/*======================================================================
-  orinoco_cs_attach() creates an "instance" of the driver, allocating
-  local data structures for one device.  The device is registered
-  with Card Services.
-  
-  The dev_link structure is initialized, but we don't actually
-  configure the card at this point -- we wait until we receive a
-  card insertion event.
-  ======================================================================*/
-
+/*
+ * This creates an "instance" of the driver, allocating local data
+ * structures for one device.  The device is registered with Card
+ * Services.
+ * 
+ * The dev_link structure is initialized, but we don't actually
+ * configure the card at this point -- we wait until we receive a card
+ * insertion event.  */
 static dev_link_t *
 orinoco_cs_attach(void)
 {
@@ -294,23 +188,19 @@
 	client_reg_t client_reg;
 	int ret, i;
 
-	TRACE_ENTER("orinoco");
 	/* A bit of cleanup */
 	flush_stale_links();
 
-	dev = alloc_orinocodev(sizeof(*card));
+	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
 	if (! dev)
 		return NULL;
 	priv = dev->priv;
 	card = priv->card;
-	/* Overrides */
-	dev->open = orinoco_cs_open;
-	dev->stop = orinoco_cs_stop;
-	priv->hard_reset = orinoco_cs_hard_reset;
+	init_waitqueue_head(&card->hard_reset_queue);
 
 	/* Link both structures together */
 	link = &card->link;
-	link->priv = priv;
+	link->priv = dev;
 
 	/* Initialize the dev_link_t structure */
 	link->release.function = &orinoco_cs_release;
@@ -326,63 +216,59 @@
 			link->irq.IRQInfo2 |= 1 << irq_list[i];
 	link->irq.Handler = NULL;
 
-	/*
-	   General socket configuration defaults can go here.  In this
-	   client, we assume very little, and rely on the CIS for almost
-	   everything.  In most clients, many details (i.e., number, sizes,
-	   and attributes of IO windows) are fixed by the nature of the
-	   device, and can be hard-wired here.
-	 */
+	/* General socket configuration defaults can go here.  In this
+	 * client, we assume very little, and rely on the CIS for
+	 * almost everything.  In most clients, many details (i.e.,
+	 * number, sizes, and attributes of IO windows) are fixed by
+	 * the nature of the device, and can be hard-wired here. */
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
 	/* Register with Card Services */
+	/* FIXME: need a lock? */
 	link->next = dev_list;
 	dev_list = link;
+
 	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;
+		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 = &orinoco_cs_event;
-	client_reg.Version = 0x0210;
+	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
 	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);
 		orinoco_cs_detach(link);
-		link = NULL;
-		goto out;
+		return NULL;
 	}
 
- out:
-	TRACE_EXIT("orinoco");
 	return link;
 }				/* orinoco_cs_attach */
 
-/*======================================================================
-  This deletes a driver "instance".  The device is de-registered
-  with Card Services.  If it has been released, all local data
-  structures are freed.  Otherwise, the structures will be freed
-  when the device is released.
-  ======================================================================*/
-
+/*
+ * This deletes a driver "instance".  The device is de-registered with
+ * Card Services.  If it has been released, all local data structures
+ * are freed.  Otherwise, the structures will be freed when the device
+ * is released.
+ */
 static void
 orinoco_cs_detach(dev_link_t * link)
 {
 	dev_link_t **linkp;
-	struct orinoco_private *priv = link->priv;
-	struct net_device *dev = priv->ndev;
-
-	TRACE_ENTER("orinoco");
+	struct net_device *dev = link->priv;
 
 	/* Locate device structure */
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 		if (*linkp == link)
 			break;
-	if (*linkp == NULL)
-		goto out;
+	if (*linkp == NULL) {
+		BUG();
+		return;
+	}
 
 	/*
 	   If the device is currently configured and active, we won't
@@ -396,7 +282,7 @@
 		       "still locked\n", link->dev->dev_name);
 #endif
 		link->state |= DEV_STALE_LINK;
-		goto out;
+		return;
 	}
 
 	/* Break the link with Card Services */
@@ -408,50 +294,44 @@
 	DEBUG(0, "orinoco_cs: detach: link=%p link->dev=%p\n", link, link->dev);
 	if (link->dev) {
 		DEBUG(0, "orinoco_cs: About to unregister net device %p\n",
-		      priv->ndev);
+		      dev);
 		unregister_netdev(dev);
 	}
 	kfree(dev);
-
- out:
-	TRACE_EXIT("orinoco");
 }				/* orinoco_cs_detach */
 
-/*======================================================================
-  orinoco_cs_config() is scheduled to run after a CARD_INSERTION event
-  is received, to configure the PCMCIA socket, and to make the
-  device available to the system.
-  ======================================================================*/
+/*
+ * orinoco_cs_config() is scheduled to run after a CARD_INSERTION
+ * event is received, to configure the PCMCIA socket, and to make the
+ * device available to the system.
+ */
 
 #define CS_CHECK(fn, args...) \
-while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+	while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
 
 #define CFG_CHECK(fn, args...) \
-if (CardServices(fn, args) != 0) goto next_entry
+	if (CardServices(fn, args) != 0) goto next_entry
 
 static void
-orinoco_cs_config(dev_link_t * link)
+orinoco_cs_config(dev_link_t *link)
 {
+	struct net_device *dev = link->priv;
 	client_handle_t handle = link->handle;
-	struct orinoco_private *priv = link->priv;
-	struct orinoco_pccard *card = (struct orinoco_pccard *)priv->card;
+	struct orinoco_private *priv = dev->priv;
+	struct orinoco_pccard *card = priv->card;
 	hermes_t *hw = &priv->hw;
-	struct net_device *ndev = priv->ndev;
-	tuple_t tuple;
-	cisparse_t parse;
 	int last_fn, last_ret;
 	u_char buf[64];
 	config_info_t conf;
-	cistpl_cftable_entry_t dflt = { 0 };
 	cisinfo_t info;
-
-	TRACE_ENTER("orinoco");
+	tuple_t tuple;
+	cisparse_t parse;
 
 	CS_CHECK(ValidateCIS, handle, &info);
 
 	/*
-	   This reads the card's CONFIG tuple to find its configuration
-	   registers.
+	 * This reads the card's CONFIG tuple to find its
+	 * configuration registers.
 	 */
 	tuple.DesiredTuple = CISTPL_CONFIG;
 	tuple.Attributes = 0;
@@ -471,31 +351,29 @@
 	CS_CHECK(GetConfigurationInfo, handle, &conf);
 	link->conf.Vcc = conf.Vcc;
 
-	DEBUG(0, "orinoco_cs_config: ConfigBase = 0x%x link->conf.Vcc = %d\n", 
-	      link->conf.ConfigBase, link->conf.Vcc);
-
 	/*
-	   In this loop, we scan the CIS for configuration table entries,
-	   each of which describes a valid card configuration, including
-	   voltage, IO window, memory window, and interrupt settings.
-
-	   We make no assumptions about the card to be configured: we use
-	   just the information available in the CIS.  In an ideal world,
-	   this would work for any PCMCIA card, but it requires a complete
-	   and accurate CIS.  In practice, a driver usually "knows" most of
-	   these things without consulting the CIS, and most client drivers
-	   will only use the CIS to fill in implementation-defined details.
+	 * In this loop, we scan the CIS for configuration table
+	 * entries, each of which describes a valid card
+	 * configuration, including voltage, IO window, memory window,
+	 * and interrupt settings.
+	 *
+	 * We make no assumptions about the card to be configured: we
+	 * use just the information available in the CIS.  In an ideal
+	 * world, this would work for any PCMCIA card, but it requires
+	 * a complete and accurate CIS.  In practice, a driver usually
+	 * "knows" most of these things without consulting the CIS,
+	 * and most client drivers will only use the CIS to fill in
+	 * implementation-defined details.
 	 */
 	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
 	CS_CHECK(GetFirstTuple, handle, &tuple);
 	while (1) {
 		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		cistpl_cftable_entry_t dflt = { index: 0 };
+
 		CFG_CHECK(GetTupleData, handle, &tuple);
 		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
 
-		DEBUG(0, "orinoco_cs_config: index = 0x%x, flags = 0x%x\n",
-		      cfg->index, cfg->flags);
-
 		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
 			dflt = *cfg;
 		if (cfg->index == 0)
@@ -509,7 +387,7 @@
 		}
 
 		/* Use power settings for Vcc and Vpp if present */
-		/*  Note that the CIS values need to be rescaled */
+		/* Note that the CIS values need to be rescaled */
 		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
 			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
 				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
@@ -531,8 +409,6 @@
 			link->conf.Vpp1 = link->conf.Vpp2 =
 			    dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
 		
-		DEBUG(0, "orinoco_cs_config: We seem to have configured Vcc and Vpp\n");
-
 		/* Do we need to allocate an interrupt? */
 		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
 			link->conf.Attributes |= CONF_ENABLE_IRQ;
@@ -581,9 +457,9 @@
 	}
 
 	/*
-	   Allocate an interrupt line.  Note that this does not assign a
-	   handler to the interrupt, unless the 'Handler' member of the
-	   irq structure is initialized.
+	 * Allocate an interrupt line.  Note that this does not assign
+	 * a handler to the interrupt, unless the 'Handler' member of
+	 * the irq structure is initialized.
 	 */
 	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
 		int i;
@@ -603,33 +479,43 @@
 	}
 
 	/* We initialize the hermes structure before completing PCMCIA
-	   configuration just in case the interrupt handler gets
-	   called. */
+	 * configuration just in case the interrupt handler gets
+	 * called. */
 	hermes_struct_init(hw, link->io.BasePort1,
 				HERMES_IO, HERMES_16BIT_REGSPACING);
 
 	/*
-	   This actually configures the PCMCIA socket -- setting up
-	   the I/O windows and the interrupt mapping, and putting the
-	   card and host interface into "Memory and IO" mode.
+	 * This actually configures the PCMCIA socket -- setting up
+	 * the I/O windows and the interrupt mapping, and putting the
+	 * card and host interface into "Memory and IO" mode.
 	 */
 	CS_CHECK(RequestConfiguration, link->handle, &link->conf);
 
-	ndev->base_addr = link->io.BasePort1;
-	ndev->irq = link->irq.AssignedIRQ;
+	/* Ok, we have the configuration, prepare to register the netdev */
+	dev->base_addr = link->io.BasePort1;
+	dev->irq = link->irq.AssignedIRQ;
+	SET_MODULE_OWNER(dev);
+	card->node.major = card->node.minor = 0;
 
 	/* register_netdev will give us an ethX name */
-	ndev->name[0] = '\0';
+	dev->name[0] = '\0';
 	/* Tell the stack we exist */
-	if (register_netdev(ndev) != 0) {
+	if (register_netdev(dev) != 0) {
 		printk(KERN_ERR "orinoco_cs: register_netdev() failed\n");
 		goto failed;
 	}
-	strcpy(card->node.dev_name, ndev->name);
+
+	/* At this point, the dev_node_t structure(s) needs to be
+	 * initialized and arranged in a linked list at link->dev. */
+	strcpy(card->node.dev_name, dev->name);
+	link->dev = &card->node; /* link->dev being non-NULL is also
+                                    used to indicate that the
+                                    net_device has been registered */
+	link->state &= ~DEV_CONFIG_PENDING;
 
 	/* Finally, report what we've done */
 	printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d",
-	       ndev->name, link->conf.ConfigIndex,
+	       dev->name, link->conf.ConfigIndex,
 	       link->conf.Vcc / 10, link->conf.Vcc % 10);
 	if (link->conf.Vpp1)
 		printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
@@ -645,59 +531,40 @@
 	printk("\n");
 
 	/* And give us the proc nodes for debugging */
-	if (orinoco_proc_dev_init(priv) != 0) {
+	if (orinoco_proc_dev_init(dev) != 0) {
 		printk(KERN_ERR "orinoco_cs: Failed to create /proc node for %s\n",
-		       ndev->name);
+		       dev->name);
 		goto failed;
 	}
 	
-	/* Note to myself : this replace MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT */
-	SET_MODULE_OWNER(ndev);
-	
-	/* Let reset_cor parameter override determine_firmware()'s guess */
-	if (reset_cor != -1)
-		priv->broken_cor_reset = ! reset_cor;
-
-	/*
-	   At this point, the dev_node_t structure(s) need to be
-	   initialized and arranged in a linked list at link->dev.
-	 */
-	card->node.major = card->node.minor = 0;
-	link->dev = &card->node;
-	link->state &= ~DEV_CONFIG_PENDING;
-
-	TRACE_EXIT("orinoco");
 
 	return;
 
  cs_failed:
 	cs_error(link->handle, last_fn, last_ret);
+
  failed:
 	orinoco_cs_release((u_long) link);
-
-	TRACE_EXIT("orinoco");
 }				/* orinoco_cs_config */
 
-/*======================================================================
-  After a card is removed, orinoco_cs_release() will unregister the
-  device, and release the PCMCIA configuration.  If the device is
-  still open, this will be postponed until it is closed.
-  ======================================================================*/
-
+/*
+ * After a card is removed, orinoco_cs_release() will unregister the
+ * device, and release the PCMCIA configuration.  If the device is
+ * still open, this will be postponed until it is closed.
+ */
 static void
 orinoco_cs_release(u_long arg)
 {
 	dev_link_t *link = (dev_link_t *) arg;
-	struct orinoco_private *priv = link->priv;
-
-	TRACE_ENTER(link->dev->dev_name);
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = dev->priv;
 
 	/*
 	   If the device is currently in use, we won't release until it
 	   is actually closed, because until then, we can't be sure that
 	   no one will try to access the device or its data structures.
 	 */
-	if (link->open) {
+	if (priv->open) {
 		DEBUG(0, "orinoco_cs: release postponed, '%s' still open\n",
 		      link->dev->dev_name);
 		link->state |= DEV_STALE_CONFIG;
@@ -705,7 +572,7 @@
 	}
 
 	/* Unregister proc entry */
-	orinoco_proc_dev_cleanup(priv);
+	orinoco_proc_dev_cleanup(dev);
 
 	/* Don't bother checking to see if these succeed or not */
 	CardServices(ReleaseConfiguration, link->handle);
@@ -714,62 +581,74 @@
 	if (link->irq.AssignedIRQ)
 		CardServices(ReleaseIRQ, link->handle, &link->irq);
 	link->state &= ~DEV_CONFIG;
-
-	TRACE_EXIT(link->dev->dev_name);
 }				/* orinoco_cs_release */
 
-/*======================================================================
-  The card status event handler.  Mostly, this schedules other
-  stuff to run after an event is received.
-
-  When a CARD_REMOVAL event is received, we immediately set a
-  private flag to block future accesses to this device.  All the
-  functions that actually access the device should check this flag
-  to make sure the card is still present.
-  ======================================================================*/
-
+/*
+ * The card status event handler.  Mostly, this schedules other stuff
+ * to run after an event is received.
+ */
 static int
 orinoco_cs_event(event_t event, int priority,
 		       event_callback_args_t * args)
 {
 	dev_link_t *link = args->client_data;
-	struct orinoco_private *priv = (struct orinoco_private *)link->priv;
-	struct net_device *dev = priv->ndev;
-
-	TRACE_ENTER("orinoco");
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = dev->priv;
+	int err = 0;
+	unsigned long flags;
 
 	switch (event) {
 	case CS_EVENT_CARD_REMOVAL:
 		link->state &= ~DEV_PRESENT;
 		if (link->state & DEV_CONFIG) {
-			netif_stop_queue(dev);
-		}
-		orinoco_shutdown(priv);
-		if (link->state & DEV_CONFIG) {
+			orinoco_lock(priv, &flags);
+
 			netif_device_detach(dev);
+			priv->hw_unavailable = 1;
+
+			orinoco_unlock(priv, &flags);
+
+/*  			if (link->open) */
+/*  				orinoco_cs_stop(dev); */
+
 			mod_timer(&link->release, jiffies + HZ / 20);
 		}
 		break;
+
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		orinoco_cs_config(link);
 		break;
-	case CS_EVENT_PM_SUSPEND:
 
+	case CS_EVENT_PM_SUSPEND:
 		link->state |= DEV_SUSPEND;
 		/* Fall through... */
 	case CS_EVENT_RESET_PHYSICAL:
-		orinoco_shutdown(priv);
 		/* Mark the device as stopped, to block IO until later */
-
 		if (link->state & DEV_CONFIG) {
-			if (link->open) {
-				netif_stop_queue(dev);
-				netif_device_detach(dev);
+			err = orinoco_lock(priv, &flags);
+			if (err) {
+				printk(KERN_ERR "%s: hw_unavailable on SUSPEND/RESET_PHYSICAL\n",
+				       dev->name);
+				break;
 			}
+
+			err = __orinoco_down(dev);
+			if (err)
+				printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
+				       dev->name,
+				       event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
+				       err);
+
+			netif_device_detach(dev);
+			priv->hw_unavailable = 1;
+
+			orinoco_unlock(priv, &flags);
+
 			CardServices(ReleaseConfiguration, link->handle);
 		}
 		break;
+
 	case CS_EVENT_PM_RESUME:
 		link->state &= ~DEV_SUSPEND;
 		/* Fall through... */
@@ -778,36 +657,49 @@
 			CardServices(RequestConfiguration, link->handle,
 				     &link->conf);
 
-			if (link->open) {
-				if (orinoco_reset(priv) == 0) {
-					netif_device_attach(dev);
-					netif_start_queue(dev);
-				} else {
-					printk(KERN_ERR "%s: Error resetting device on PCMCIA event\n",
-					       dev->name);
-					orinoco_cs_stop(dev);
-				}
+			/* FIXME: should we double check that this is
+			 * the same card as we had before */
+			err = orinoco_reinit_firmware(dev);
+			if (err) {
+				printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+				       dev->name, err);
+				break;
 			}
+
+			spin_lock_irqsave(&priv->lock, flags);
+
+			netif_device_attach(dev);
+			priv->hw_unavailable = 0;
+
+			if (priv->open) {
+				err = __orinoco_up(dev);
+				if (err)
+					printk(KERN_ERR "%s: Error %d restarting card\n",
+					       dev->name, err);
+
+			}
+
+			orinoco_unlock(priv, &flags);
 		}
-		/*
-		   In a normal driver, additional code may go here to restore
-		   the device state and restart IO. 
-		 */
 		break;
 	}
 
-	TRACE_EXIT("orinoco");
-
-	return 0;
+	return err;
 }				/* orinoco_cs_event */
 
+/********************************************************************/
+/* Module initialization					    */
+/********************************************************************/
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = "orinoco_cs.c 0.13 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+
 static int __init
 init_orinoco_cs(void)
 {
 	servinfo_t serv;
 
-	TRACE_ENTER("orinoco");
-
 	printk(KERN_DEBUG "%s\n", version);
 
 	CardServices(GetCardServicesInfo, &serv);
@@ -819,16 +711,12 @@
 
 	register_pccard_driver(&dev_info, &orinoco_cs_attach, &orinoco_cs_detach);
 
-
-	TRACE_EXIT("orinoco");
 	return 0;
 }
 
 static void __exit
 exit_orinoco_cs(void)
 {
-	TRACE_ENTER("orinoco");
-
 	unregister_pccard_driver(&dev_info);
 
 	if (dev_list)
@@ -839,9 +727,8 @@
 			orinoco_cs_release((u_long) dev_list);
 		orinoco_cs_detach(dev_list);
 	}
-
-	TRACE_EXIT("orinoco");
 }
 
 module_init(init_orinoco_cs);
 module_exit(exit_orinoco_cs);
+
diff -Nru a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
--- a/drivers/net/wireless/orinoco_plx.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/net/wireless/orinoco_plx.c	Fri Sep 27 14:51:05 2002
@@ -1,4 +1,4 @@
-/* orinoco_plx.c 0.11b
+/* orinoco_plx.c 0.13
  * 
  * Driver for Prism II devices which would usually be driven by orinoco_cs,
  * but are connected to the PCI bus by a PLX9052. 
@@ -134,13 +134,6 @@
 #include "hermes.h"
 #include "orinoco.h"
 
-static char version[] __initdata = "orinoco_plx.c 0.11b (Daniel Barlow <dan@telent.net>)";
-MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
-MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("Dual MPL/GPL");
-#endif
-
 static char dev_info[] = "orinoco_plx";
 
 #define COR_OFFSET    (0x3e0 / 2)	/* COR attribute offset of Prism2 PC card */
@@ -149,37 +142,6 @@
 #define PLX_INTCSR       0x4c /* Interrupt Control and Status Register */
 #define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */
 
-static int orinoco_plx_open(struct net_device *dev)
-{
-	struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
-	int err;
-
-	netif_device_attach(dev);
-
-	err = orinoco_reset(priv);
-	if (err)
-		printk(KERN_ERR "%s: orinoco_reset failed in orinoco_plx_open()",
-		       dev->name);
-	else
-		netif_start_queue(dev);
-
-	return err;
-}
-
-static int orinoco_plx_stop(struct net_device *dev)
-{
-	struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
-	netif_stop_queue(dev);
-	orinoco_shutdown(priv);
-	return 0;
-}
-
-static void
-orinoco_plx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	orinoco_interrupt(irq, (struct orinoco_private *)dev_id, regs);
-}
-
 static const u16 cis_magic[] = {
 	0x0001, 0x0003, 0x0000, 0x0000, 0x00ff, 0x0017, 0x0004, 0x0067
 };
@@ -197,8 +159,6 @@
 	int netdev_registered = 0;
 	int i;
 
-	TRACE_ENTER("orinoco_plx");
-
 	err = pci_enable_device(pdev);
 	if (err)
 		return -EIO;
@@ -266,7 +226,7 @@
 		goto fail;
 	}
 
-	dev = alloc_orinocodev(0);
+	dev = alloc_orinocodev(0, NULL);
 	if (! dev) {
 		err = -ENOMEM;
 		goto fail;
@@ -274,8 +234,6 @@
 
 	priv = dev->priv;
 	dev->base_addr = pccard_ioaddr;
-	dev->open = orinoco_plx_open;
-	dev->stop = orinoco_plx_stop;
 	SET_MODULE_OWNER(dev);
 
 	printk(KERN_DEBUG
@@ -286,7 +244,7 @@
 			HERMES_IO, HERMES_16BIT_REGSPACING);
 	pci_set_drvdata(pdev, dev);
 
-	err = request_irq(pdev->irq, orinoco_plx_interrupt, SA_SHIRQ, dev->name, priv);
+	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, priv);
 	if (err) {
 		printk(KERN_ERR "orinoco_plx: Error allocating IRQ %d.\n", pdev->irq);
 		err = -EBUSY;
@@ -299,19 +257,17 @@
 		goto fail;
 	netdev_registered = 1;
 
-	err = orinoco_proc_dev_init(priv);
+	err = orinoco_proc_dev_init(dev);
 	if (err)
 		goto fail;
 
-	TRACE_EXIT("orinoco_plx");
-
 	return 0;		/* succeeded */
 
  fail:	
 	printk(KERN_DEBUG "orinoco_plx: init_one(), FAIL!\n");
 
 	if (priv) {
-		orinoco_proc_dev_cleanup(priv);
+		orinoco_proc_dev_cleanup(dev);
 
 		if (netdev_registered)
 			unregister_netdev(dev);
@@ -330,8 +286,6 @@
 
 	pci_disable_device(pdev);
 
-	TRACE_EXIT("orinoco_plx");
-	
 	return err;
 }
 
@@ -340,12 +294,10 @@
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct orinoco_private *priv = dev->priv;
 
-	TRACE_ENTER("orinoco_plx");
-
 	if (! dev)
 		BUG();
 
-	orinoco_proc_dev_cleanup(priv);
+	orinoco_proc_dev_cleanup(dev);
 
 	unregister_netdev(dev);
 		
@@ -357,13 +309,10 @@
 	release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
 
 	pci_disable_device(pdev);
-
-	TRACE_EXIT("orinoco_plx");
 }
 
 
 static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
-	{0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,},	/* 3ComAirConnect */
 	{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},	/* Siemens SpeedStream SS1023 */
 	{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},	/* Netgear MA301 */
 	{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},	/* Correga  - does this work? */
@@ -376,7 +325,8 @@
 	{0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,},	/* USR 2415 */
 	{0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,},	/* Belkin F5D6000 tested by
 							   Brendan W. McAdams <rit@jacked-in.org> */
-	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},	/* Nortel emobility */
+	{0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,},	/* 3Com AirConnect PCI tested by
+							   Damien Persohn <damien@persohn.net> */
 	{0,},
 };
 
@@ -387,7 +337,16 @@
 	.id_table	= orinoco_plx_pci_id_table,
 	.probe		= orinoco_plx_init_one,
 	.remove		= __devexit_p(orinoco_plx_remove_one),
+	.suspend	= 0,
+	.resume		= 0,
 };
+
+static char version[] __initdata = "orinoco_plx.c 0.13 (Daniel Barlow <dan@telent.net>, David Gibson <hermes@gibson.dropbear.id.au>)";
+MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("Dual MPL/GPL");
+#endif
 
 static int __init orinoco_plx_init(void)
 {
diff -Nru a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
--- a/drivers/net/wireless/wavelan_cs.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/net/wireless/wavelan_cs.c	Fri Sep 27 14:51:04 2002
@@ -676,7 +676,7 @@
   
   while(wavepoint!=NULL)
     {
-      if(wavepoint->last_seen < jiffies-CELL_TIMEOUT)
+      if(time_after(jiffies, wavepoint->last_seen + CELL_TIMEOUT))
 	{
 #ifdef WAVELAN_ROAMING_DEBUG
 	  printk(KERN_DEBUG "WaveLAN: Bye bye %.4X\n",wavepoint->nwid);
@@ -1859,7 +1859,8 @@
 }
 #endif	/* HISTOGRAM */
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static inline int
+wl_netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
 {
 	u32 ethcmd;
 
@@ -2901,7 +2902,9 @@
 	      struct ifreq *	rq,	/* Data passed */
 	      int		cmd)	/* Ioctl number */
 {
+#if WIRELESS_EXT <= 12
   struct iwreq *	wrq = (struct iwreq *) rq;
+#endif
   int			ret = 0;
 
 #ifdef DEBUG_IOCTL_TRACE
@@ -2912,7 +2915,7 @@
   switch(cmd)
     {
     case SIOCETHTOOL:
-      ret = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+      ret = wl_netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
       break;
 
 #if WIRELESS_EXT <= 12
diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
--- a/drivers/pci/hotplug.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/pci/hotplug.c	Fri Sep 27 14:51:05 2002
@@ -1,52 +1,68 @@
 #include <linux/pci.h>
 #include <linux/module.h>
-#include <linux/kmod.h>		/* for hotplug_path */
+#include "pci.h"
 
-#ifndef FALSE
-#define FALSE	(0)
-#define TRUE	(!FALSE)
-#endif
 
 #ifdef CONFIG_HOTPLUG
-static void run_sbin_hotplug(struct pci_dev *pdev, int insert)
+int pci_hotplug (struct device *dev, char **envp, int num_envp,
+		 char *buffer, int buffer_size)
 {
-	int i;
-	char *argv[3], *envp[8];
-	char id[20], sub_id[24], bus_id[24], class_id[20];
-
-	if (!hotplug_path[0])
-		return;
+	struct pci_dev *pdev;
+	char *scratch;
+	int i = 0;
+	int length = 0;
+
+	if (!dev)
+		return -ENODEV;
+
+	pdev = to_pci_dev(dev);
+	if (!pdev)
+		return -ENODEV;
+
+	scratch = buffer;
+
+	/* stuff we want to pass to /sbin/hotplug */
+	envp[i++] = scratch;
+	length += snprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",
+			    pdev->class);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp[i++] = scratch;
+	length += snprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",
+			    pdev->vendor, pdev->device);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp[i++] = scratch;
+	length += snprintf (scratch, buffer_size - length,
+			    "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
+			    pdev->subsystem_device);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp[i++] = scratch;
+	length += snprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",
+			    pdev->slot_name);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
 
-	sprintf(class_id, "PCI_CLASS=%04X", pdev->class);
-	sprintf(id, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device);
-	sprintf(sub_id, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, pdev->subsystem_device);
-	sprintf(bus_id, "PCI_SLOT_NAME=%s", pdev->slot_name);
-
-	i = 0;
-	argv[i++] = hotplug_path;
-	argv[i++] = "pci";
-	argv[i] = 0;
-
-	i = 0;
-	/* minimal command environment */
-	envp[i++] = "HOME=/";
-	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-	
-	/* other stuff we want to pass to /sbin/hotplug */
-	envp[i++] = class_id;
-	envp[i++] = id;
-	envp[i++] = sub_id;
-	envp[i++] = bus_id;
-	if (insert)
-		envp[i++] = "ACTION=add";
-	else
-		envp[i++] = "ACTION=remove";
 	envp[i] = 0;
 
-	call_usermodehelper (argv [0], argv, envp);
+	return 0;
 }
 #else
-static void run_sbin_hotplug(struct pci_dev *pdev, int insert) { }
+int pci_hotplug (struct device *dev, char **envp, int num_envp,
+		 char *buffer, int buffer_size)
+{
+	return -ENODEV;
+}
 #endif
 
 /**
@@ -66,8 +82,6 @@
 #ifdef CONFIG_PROC_FS
 	pci_proc_attach_device(dev);
 #endif
-	/* notify userspace of new hotplug device */
-	run_sbin_hotplug(dev, TRUE);
 }
 
 static void
@@ -99,8 +113,6 @@
 #ifdef CONFIG_PROC_FS
 	pci_proc_detach_device(dev);
 #endif
-	/* notify userspace of hotplug device removal */
-	run_sbin_hotplug(dev, FALSE);
 }
 
 #ifdef CONFIG_HOTPLUG
diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/pci/pci-driver.c	Fri Sep 27 14:51:04 2002
@@ -6,6 +6,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include "pci.h"
 
 /*
  *  Registration of PCI drivers and handling of hot-pluggable devices.
@@ -199,8 +200,9 @@
 }
 
 struct bus_type pci_bus_type = {
-	name:	"pci",
-	match:	pci_bus_match,
+	name:		"pci",
+	match:		pci_bus_match,
+	hotplug:	pci_hotplug,
 };
 
 static int __init pci_driver_init(void)
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/pci/pci.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,5 @@
+/* Functions internal to the PCI core code */
+
+extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
+			 char *buffer, int buffer_size);
+
diff -Nru a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
--- a/drivers/pcmcia/i82092.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/pcmcia/i82092.c	Fri Sep 27 14:51:05 2002
@@ -26,6 +26,8 @@
 #include "i82092aa.h"
 #include "i82365.h"
 
+MODULE_LICENSE("GPL");
+
 /* PCI core routines */
 static struct pci_device_id i82092aa_pci_ids[] = {
 	{
diff -Nru a/drivers/pnp/isapnp.c b/drivers/pnp/isapnp.c
--- a/drivers/pnp/isapnp.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/pnp/isapnp.c	Fri Sep 27 14:51:04 2002
@@ -1048,11 +1048,19 @@
 	isapnp_wait();
 	isapnp_key();
 	isapnp_wake(csn);
-#if 1	/* to avoid malfunction when the isapnptools package is used */
-	isapnp_set_rdp();
-	udelay(1000);	/* delay 1000us */
-	write_address(0x01);
-	udelay(1000);	/* delay 1000us */
+#if 1
+	/* to avoid malfunction when the isapnptools package is used */
+	/* we must set RDP to our value again */
+	/* it is possible to set RDP only in the isolation phase */ 
+	/*   Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
+	isapnp_write_byte(0x02, 0x04);	/* clear CSN of card */
+	mdelay(2);			/* is this necessary? */
+	isapnp_wake(csn);		/* bring card into sleep state */
+	isapnp_wake(0);			/* bring card into isolation state */
+	isapnp_set_rdp();		/* reset the RDP port */
+	udelay(1000);			/* delay 1000us */
+	isapnp_write_byte(0x06, csn);	/* reset CSN to previous value */
+	udelay(250);			/* is this necessary? */
 #endif
 	if (logdev >= 0)
 		isapnp_device(logdev);
diff -Nru a/drivers/pnp/pnpbios_proc.c b/drivers/pnp/pnpbios_proc.c
--- a/drivers/pnp/pnpbios_proc.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/pnp/pnpbios_proc.c	Fri Sep 27 14:51:05 2002
@@ -68,6 +68,7 @@
 	);
 }
 
+#define MAX_SANE_ESCD_SIZE (32*1024)
 static int proc_read_escd(char *buf, char **start, off_t pos,
                           int count, int *eof, void *data)
 {
@@ -79,8 +80,8 @@
 		return -EIO;
 
 	/* sanity check */
-	if (escd.escd_size > (32*1024)) {
-		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size is too great\n");
+	if (escd.escd_size > MAX_SANE_ESCD_SIZE) {
+		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by BIOS escd_info call is too great\n");
 		return -EFBIG;
 	}
 
@@ -90,7 +91,14 @@
 	if (pnp_bios_read_escd(tmpbuf, escd.nv_storage_base))
 		return -EIO;
 
-	escd_size = (unsigned char)(buf[0]) + (unsigned char)(buf[1])*256;
+	escd_size = (unsigned char)(tmpbuf[0]) + (unsigned char)(tmpbuf[1])*256;
+
+	/* sanity check */
+	if (escd_size > MAX_SANE_ESCD_SIZE) {
+		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by BIOS read_escd call is too great\n");
+		return -EFBIG;
+	}
+
 	escd_left_to_read = escd_size - pos;
 	if (escd_left_to_read < 0) escd_left_to_read = 0;
 	if (escd_left_to_read == 0) *eof = 1;
diff -Nru a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
--- a/drivers/s390/block/dasd_genhd.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/s390/block/dasd_genhd.c	Fri Sep 27 14:51:05 2002
@@ -153,7 +153,6 @@
 	/* Clear block device pointers. */
 	major = mi->major;
 	blk_dev[major].queue = NULL;
-	blk_clear(major);
 
 	rc = unregister_blkdev(major, "dasd");
 	if (rc < 0)
diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
--- a/drivers/s390/block/xpram.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/s390/block/xpram.c	Fri Sep 27 14:51:05 2002
@@ -492,7 +492,6 @@
 	int i;
 	for (i = 0; i < xpram_devs; i++)
 		del_gendisk(xpram_disks + i);
-	blk_clear(XPRAM_MAJOR);
 	unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
 	devfs_unregister(xpram_devfs_handle);
 	unregister_sys_device(&xpram_sys_device);
diff -Nru a/drivers/s390/char/tapeblock.c b/drivers/s390/char/tapeblock.c
--- a/drivers/s390/char/tapeblock.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/s390/char/tapeblock.c	Fri Sep 27 14:51:05 2002
@@ -33,24 +33,15 @@
 /*
  * file operation structure for tape devices
  */
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
 static struct block_device_operations tapeblock_fops = {
-#else
-static struct file_operations tapeblock_fops = {
-#endif
-    owner   : THIS_MODULE,
-    open    : tapeblock_open,      /* open */
-    release : tapeblock_release,   /* release */
-        };
+	.owner		= THIS_MODULE,
+	.open		= tapeblock_open,
+	.release	= tapeblock_release,
+};
 
 int    tapeblock_major = 0;
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
 static void tape_request_fn (request_queue_t * queue);
-#else
-static void tape_request_fn (void);
-#endif
-
 static request_queue_t* tapeblock_getqueue (kdev_t kdev);
 
 #ifdef CONFIG_DEVFS_FS
@@ -81,7 +72,6 @@
 
 void 
 tapeblock_setup(tape_dev_t* td) {
-    blk_size[tapeblock_major][td->first_minor]=0; // this will be detected
     blk_queue_hardsect_size(&ti->request_queue, 2048);
     blk_init_queue (&td->blk_data.request_queue, tape_request_fn); 
 #ifdef CONFIG_DEVFS_FS
@@ -106,12 +96,6 @@
 	if (tapeblock_major == 0) tapeblock_major = result;   /* accept dynamic major number*/
 	INIT_BLK_DEV(tapeblock_major,tape_request_fn,tapeblock_getqueue,NULL);
 	PRINT_WARN(KERN_ERR " tape gets major %d for block device\n", tapeblock_major);
-	blk_size[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_KERNEL);
-	if (blk_size[tapeblock_major]==NULL) goto out_undo_bdev;
-	memset(blk_size[tapeblock_major],0,256*sizeof(int));
-	hardsect_size[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_KERNEL);
-	if (hardsect_size[tapeblock_major]==NULL) goto out_undo_blk_size;
-	memset(hardsect_size[tapeblock_major],0,256*sizeof(int));
 	max_sectors[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_KERNEL);
 	if (max_sectors[tapeblock_major]==NULL) goto out_undo_hardsect_size;
 	memset(max_sectors[tapeblock_major],0,256*sizeof(int));
@@ -141,14 +125,10 @@
 out_undo_max_sectors:
 	kfree(max_sectors[tapeblock_major]);
 out_undo_hardsect_size:
-	kfree(hardsect_size[tapeblock_major]);
 out_undo_blk_size:
-	kfree(blk_size[tapeblock_major]);
 out_undo_bdev:
 	unregister_blkdev(tapeblock_major, "tBLK");
 	result=-ENOMEM;
-	blk_size[tapeblock_major]=
-	hardsect_size[tapeblock_major]=
 	max_sectors[tapeblock_major]=NULL;
 	tapeblock_major=-1;    
 out:
@@ -160,14 +140,6 @@
 tapeblock_uninit(void) {
 	if (tapeblock_major==-1)
 	        goto out; /* init failed so there is nothing to clean up */
-	if (blk_size[tapeblock_major]!=NULL) {
-		kfree(blk_size[tapeblock_major]);
-		blk_size[tapeblock_major]=NULL;
-	}
-	if (hardsect_size[tapeblock_major]!=NULL) {
-		kfree (hardsect_size[tapeblock_major]);
-		hardsect_size[tapeblock_major]=NULL;
-	}
 	if (max_sectors[tapeblock_major]!=NULL) {
 		kfree (max_sectors[tapeblock_major]);
 		max_sectors[tapeblock_major]=NULL;
@@ -256,7 +228,6 @@
 	tape_put_device(td); /* 2x ! */
 	if ( td->discipline->owner )
 		__MOD_DEC_USE_COUNT(td->discipline->owner);
-	invalidate_bdev(inode->i_rdev, 0);
 out:
 	return rc;
 }
@@ -321,11 +292,7 @@
     if (tape_state_get (td) == TS_NOT_OPER) {
 	return;
     }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
 	if (list_empty (&td->blk_data.request_queue.queue_head)) {
-#else
-	if (td->blk_data.request_queue==NULL) {
-#endif
 	// nothing more to do or device has dissapeared;)
 	tape_sprintf_event (tape_dbf_area,6,"b:Qempty\n");
 	return;
@@ -396,9 +363,7 @@
         if (atomic_compare_and_swap(0,1,&td->blk_data.bh_scheduled)) {
                 return;
         }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
 	INIT_LIST_HEAD(&td->blk_data.bh_tq.list);
-#endif
 	td->blk_data.bh_tq.sync = 0;
 	td->blk_data.bh_tq.routine = (void *) (void *) run_tapeblock_exec_IO;
 	td->blk_data.bh_tq.data = td;
@@ -408,21 +373,6 @@
 	return;
 }
 
-/* wrappers around do_tape_request for different kernel versions */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))
-static void tape_request_fn (void) { 
-	tape_dev_t* td=tape_first_dev;
-	long lockflags;
-	read_lock_irqsave(&tape_dev_lock,lockflags);
-	while (td!=NULL) {
-		tape_get_device(td);
-		do_tape_request(td);
-		tape_put_device(td);
-		td=td->next;
-	}
-	read_unlock_irqsave(&tape_dev_lock,lockflags);
-}
-#else
 static void  tape_request_fn (request_queue_t* queue) {
 	tape_dev_t* td=tape_get_device_by_queue(queue);
 	if (td!=NULL) {
@@ -430,7 +380,6 @@
 		tape_put_device(td);
 	}		
 }
-#endif
 
 static request_queue_t* tapeblock_getqueue (kdev_t kdev) {
 	tape_dev_t* td=tape_get_device_by_minor(MINOR(kdev));
diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/scsi/3w-xxxx.c	Fri Sep 27 14:51:05 2002
@@ -148,6 +148,11 @@
                  Fix bug in raw command post with data ioctl method.
                  Fix bug where rollcall sometimes failed with cable errors.
                  Print unit # on all command timeouts.
+   1.02.00.026 - Fix possible infinite retry bug with power glitch induced
+                 drive timeouts.
+                 Cleanup some AEN severity levels.
+   1.02.00.027 - Add drive not supported AEN code for SATA controllers.
+                 Remove spurious unknown ioctl error message.
 */
 
 #include <linux/module.h>
@@ -201,7 +206,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.025";
+char *tw_driver_version="1.02.00.027";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -212,7 +217,7 @@
 {
 	TW_Param *param;
 	unsigned short aen;
-	int error = 0;
+	int error = 0, table_max = 0;
 
 	dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
 	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
@@ -227,7 +232,8 @@
 	if (aen == 0x0ff) {
 		printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
 	} else {
-		if ((aen & 0x0ff) < TW_AEN_STRING_MAX) {
+		table_max = sizeof(tw_aen_string)/sizeof(char *);
+		if ((aen & 0x0ff) < table_max) {
 			if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
 				printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
 			} else {
@@ -289,7 +295,7 @@
 	int first_reset = 0;
 	int queue = 0;
 	int imax, i;
-	int found = 0;
+	int found = 0, table_max = 0;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
 
@@ -409,7 +415,8 @@
 						if (aen == 0x0ff) {
 							printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
 						} else {
-							if ((aen & 0x0ff) < TW_AEN_STRING_MAX) {
+							table_max = sizeof(tw_aen_string)/sizeof(char *);
+							if ((aen & 0x0ff) < table_max) {
 								if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
 									printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
 								} else {
@@ -1442,7 +1449,8 @@
 
 					/* If error, command failed */
 					if (error == 1) {
-						tw_dev->srb[request_id]->result = (DID_RESET << 16);
+						/* Ask for a host reset */
+						tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
 					}
 
 					/* Now complete the io */
@@ -1784,7 +1792,7 @@
 				return 1;
 			}
 		default:
-			printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
+			dprintk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
 			tw_dev->state[request_id] = TW_S_COMPLETED;
 			tw_state_request_finish(tw_dev, request_id);
 			tw_dev->srb[request_id]->result = (DID_OK << 16);
diff -Nru a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
--- a/drivers/scsi/3w-xxxx.h	Fri Sep 27 14:51:03 2002
+++ b/drivers/scsi/3w-xxxx.h	Fri Sep 27 14:51:03 2002
@@ -90,13 +90,12 @@
 	"INFO: Verify started: Unit #",                // 0x029
 	"ERROR: Verify failed: Port #",                // 0x02A
 	"INFO: Verify complete: Unit #",               // 0x02B
-	"ERROR: Overwrote bad sector during rebuild: Port #",   //0x02C
-	"ERROR: Encountered bad sector during rebuild: Port #", //0x02D
-	"INFO: Replacement drive is too small: Port #",         //0x02E
-	"WARNING: Verify error: Unit not previously initialized: Unit #" //0x02F
+	"WARNING: Overwrote bad sector during rebuild: Port #",  //0x02C
+	"ERROR: Encountered bad sector during rebuild: Port #",  //0x02D
+	"ERROR: Replacement drive is too small: Port #",         //0x02E
+	"WARNING: Verify error: Unit not previously initialized: Unit #", //0x02F
+	"ERROR: Drive not supported: Port #"           // 0x030
 };
-
-#define TW_AEN_STRING_MAX                      0x030
 
 /*
    Sense key lookup table
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/scsi/sd.c	Fri Sep 27 14:51:03 2002
@@ -1466,10 +1466,8 @@
 			vfree(sd_dsk_arr[k]);
 		vfree(sd_dsk_arr);
 	}
-	for (k = 0; k < N_USED_SD_MAJORS; k++) {
+	for (k = 0; k < N_USED_SD_MAJORS; k++)
 		blk_dev[SD_MAJOR(k)].queue = NULL;
-		blk_clear(SD_MAJOR(k));
-	}
 	sd_template.dev_max = 0;
 	remove_driver(&sd_template.scsi_driverfs_driver);
 }
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/scsi/sr.c	Fri Sep 27 14:51:03 2002
@@ -863,7 +863,6 @@
 	sr_registered--;
 	if (scsi_CDs != NULL)
 		kfree(scsi_CDs);
-	blk_clear(MAJOR_NR);
 
 	sr_template.dev_max = 0;
 	remove_driver(&sr_template.scsi_driverfs_driver);
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/core/usb.c	Fri Sep 27 14:51:04 2002
@@ -63,7 +63,8 @@
 }
 
 static struct device_driver usb_generic_driver = {
-	.name =	"generic usb driver",
+	.name =	"generic",
+	.bus = &usb_bus_type,
 	.probe = generic_probe,
 	.remove = generic_remove,
 	.release = generic_release,
@@ -470,6 +471,10 @@
 	struct usb_driver *usb_drv;
 	const struct usb_device_id *id;
 
+	/* check for generic driver, which we don't match any device with */
+	if (drv == &usb_generic_driver)
+		return 0;
+
 	intf = to_usb_interface(dev);
 
 	usb_drv = to_usb_driver(drv);
@@ -505,57 +510,42 @@
  * cases, we know no other thread can recycle our address, since we must
  * already have been serialized enough to prevent that.
  */
-static void call_policy (char *verb, struct usb_device *dev)
+static int usb_hotplug (struct device *dev, char **envp, int num_envp,
+			char *buffer, int buffer_size)
 {
-	char *argv [3], **envp, *buf, *scratch;
-	int i = 0, value;
+	struct usb_interface *intf;
+	struct usb_device *usb_dev;
+	char *scratch;
+	int i = 0;
+	int length = 0;
 
-	if (!hotplug_path [0])
-		return;
-	if (in_interrupt ()) {
-		dbg ("In_interrupt");
-		return;
-	}
-	if (!current->fs->root) {
-		/* statically linked USB is initted rather early */
-		dbg ("call_policy %s, num %d -- no FS yet", verb, dev->devnum);
-		return;
-	}
-	if (dev->devnum < 0) {
+	dbg ("%s", __FUNCTION__);
+
+	if (!dev)
+		return -ENODEV;
+
+	/* check for generic driver, we do not call do hotplug calls for it */
+	if (dev->driver == &usb_generic_driver)
+		return -ENODEV;
+
+	intf = to_usb_interface(dev);
+	if (!intf)
+		return -ENODEV;
+
+	usb_dev = interface_to_usbdev (intf);
+	if (!usb_dev)
+		return -ENODEV;
+	
+	if (usb_dev->devnum < 0) {
 		dbg ("device already deleted ??");
-		return;
-	}
-	if (!(envp = (char **) kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
-		dbg ("enomem");
-		return;
+		return -ENODEV;
 	}
-	if (!(buf = kmalloc (256, GFP_KERNEL))) {
-		kfree (envp);
-		dbg ("enomem2");
-		return;
+	if (!usb_dev->bus) {
+		dbg ("bus already removed?");
+		return -ENODEV;
 	}
 
-	/* only one standardized param to hotplug command: type */
-	argv [0] = hotplug_path;
-	argv [1] = "usb";
-	argv [2] = 0;
-
-	/* minimal command environment */
-	envp [i++] = "HOME=/";
-	envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
-#ifdef	DEBUG
-	/* hint that policy agent should enter no-stdout debug mode */
-	envp [i++] = "DEBUG=kernel";
-#endif
-	/* extensible set of named bus-specific parameters,
-	 * supporting multiple driver selection algorithms.
-	 */
-	scratch = buf;
-
-	/* action:  add, remove */
-	envp [i++] = scratch;
-	scratch += sprintf (scratch, "ACTION=%s", verb) + 1;
+	scratch = buffer;
 
 #ifdef	CONFIG_USB_DEVICEFS
 	/* If this is available, userspace programs can directly read
@@ -564,27 +554,48 @@
 	 *
 	 * FIXME reduce hardwired intelligence here
 	 */
-	envp [i++] = "DEVFS=/proc/bus/usb";
 	envp [i++] = scratch;
-	scratch += sprintf (scratch, "DEVICE=/proc/bus/usb/%03d/%03d",
-		dev->bus->busnum, dev->devnum) + 1;
+	length += snprintf (scratch, buffer_size - length,
+			    "%s", "DEVFS=/proc/bus/usb");
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp [i++] = scratch;
+	length += snprintf (scratch, buffer_size - length,
+			    "DEVICE=/proc/bus/usb/%03d/%03d",
+			    usb_dev->bus->busnum, usb_dev->devnum);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
 #endif
 
 	/* per-device configuration hacks are common */
 	envp [i++] = scratch;
-	scratch += sprintf (scratch, "PRODUCT=%x/%x/%x",
-		dev->descriptor.idVendor,
-		dev->descriptor.idProduct,
-		dev->descriptor.bcdDevice) + 1;
+	length += snprintf (scratch, buffer_size - length, "PRODUCT=%x/%x/%x",
+			    usb_dev->descriptor.idVendor,
+			    usb_dev->descriptor.idProduct,
+			    usb_dev->descriptor.bcdDevice);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
 
 	/* class-based driver binding models */
 	envp [i++] = scratch;
-	scratch += sprintf (scratch, "TYPE=%d/%d/%d",
-			    dev->descriptor.bDeviceClass,
-			    dev->descriptor.bDeviceSubClass,
-			    dev->descriptor.bDeviceProtocol) + 1;
-	if (dev->descriptor.bDeviceClass == 0) {
-		int alt = dev->actconfig->interface [0].act_altsetting;
+	length += snprintf (scratch, buffer_size - length, "TYPE=%d/%d/%d",
+			    usb_dev->descriptor.bDeviceClass,
+			    usb_dev->descriptor.bDeviceSubClass,
+			    usb_dev->descriptor.bDeviceProtocol);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	if (usb_dev->descriptor.bDeviceClass == 0) {
+		int alt = intf->act_altsetting;
 
 		/* a simple/common case: one config, one interface, one driver
 		 * with current altsetting being a reasonable setting.
@@ -592,31 +603,29 @@
 		 * device-specific binding policies.
 		 */
 		envp [i++] = scratch;
-		scratch += sprintf (scratch, "INTERFACE=%d/%d/%d",
-			dev->actconfig->interface [0].altsetting [alt].bInterfaceClass,
-			dev->actconfig->interface [0].altsetting [alt].bInterfaceSubClass,
-			dev->actconfig->interface [0].altsetting [alt].bInterfaceProtocol)
-			+ 1;
-		/* INTERFACE-0, INTERFACE-1, ... ? */
+		length += snprintf (scratch, buffer_size - length,
+				    "INTERFACE=%d/%d/%d",
+				    intf->altsetting[alt].bInterfaceClass,
+				    intf->altsetting[alt].bInterfaceSubClass,
+				    intf->altsetting[alt].bInterfaceProtocol);
+		if ((buffer_size - length <= 0) || (i >= num_envp))
+			return -ENOMEM;
+		++length;
+		scratch += length;
+
 	}
 	envp [i++] = 0;
-	/* assert: (scratch - buf) < sizeof buf */
 
-	/* NOTE: user mode daemons can call the agents too */
-
-	dbg ("kusbd: %s %s %d", argv [0], verb, dev->devnum);
-	value = call_usermodehelper (argv [0], argv, envp);
-	kfree (buf);
-	kfree (envp);
-	if (value != 0)
-		dbg ("kusbd policy returned 0x%x", value);
+	return 0;
 }
 
 #else
 
-static inline void
-call_policy (char *verb, struct usb_device *dev)
-{ } 
+static int usb_hotplug (struct device *dev, char **envp,
+			char *buffer, int buffer_size)
+{
+	return -ENODEV;
+}
 
 #endif	/* CONFIG_HOTPLUG */
 
@@ -889,9 +898,6 @@
 		put_device(&dev->dev);
 	}
 
-	/* Let policy agent unload modules etc */
-	call_policy ("remove", dev);
-
 	/* Decrement the reference count, it'll auto free everything when */
 	/* it hits 0 which could very well be now */
 	usb_put_dev(dev);
@@ -1142,6 +1148,7 @@
 		struct usb_interface_descriptor *desc = interface->altsetting;
 
 		interface->dev.parent = &dev->dev;
+		interface->dev.driver = NULL;
 		interface->dev.bus = &usb_bus_type;
 		sprintf (&interface->dev.bus_id[0], "%d-%s:%d",
 			 dev->bus->busnum, dev->devpath,
@@ -1168,9 +1175,6 @@
 	/* add a /proc/bus/usb entry */
 	usbfs_add_device(dev);
 
-	/* userspace may load modules and/or configure further */
-	call_policy ("add", dev);
-
 	return 0;
 }
 
@@ -1433,6 +1437,7 @@
 struct bus_type usb_bus_type = {
 	.name =		"usb",
 	.match =	usb_device_match,
+	.hotplug =	usb_hotplug,
 };
 
 /*
@@ -1445,6 +1450,8 @@
 	usbfs_init();
 	usb_hub_init();
 
+	driver_register(&usb_generic_driver);
+
 	return 0;
 }
 
@@ -1453,6 +1460,7 @@
  */
 static void __exit usb_exit(void)
 {
+	remove_driver(&usb_generic_driver);
 	usb_major_cleanup();
 	usbfs_cleanup();
 	usb_hub_cleanup();
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/usb/host/ehci-dbg.c	Fri Sep 27 14:51:03 2002
@@ -79,7 +79,7 @@
 
 	if (HCC_EXT_CAPS (params)) {
 		// EHCI 0.96 ... could interpret these (legacy?)
-		dbg ("%s extended capabilities at pci %d",
+		dbg ("%s extended capabilities at pci %2x",
 			label, HCC_EXT_CAPS (params));
 	}
 	if (HCC_ISOC_CACHE (params)) {
@@ -545,6 +545,18 @@
 		size -= temp;
 		next += temp;
 	}
+
+#ifdef EHCI_STATS
+	temp = snprintf (next, size, "irq normal %ld err %ld reclaim %ld\n",
+		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);
+	size -= temp;
+	next += temp;
+
+	temp = snprintf (next, size, "complete %ld unlink %ld qpatch %ld\n",
+		ehci->stats.complete, ehci->stats.unlink, ehci->stats.qpatch);
+	size -= temp;
+	next += temp;
+#endif
 
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/host/ehci-hcd.c	Fri Sep 27 14:51:04 2002
@@ -63,8 +63,7 @@
  * First was PCMCIA, like ISA; then CardBus, which is PCI.
  * Next comes "CardBay", using USB 2.0 signals.
  *
- * Contains additional contributions by: Brad Hards, Rory Bolt, ...
- *
+ * Contains additional contributions by Brad Hards, Rory Bolt, and others.
  * Special thanks to Intel and VIA for providing host controllers to
  * test this driver on, and Cypress (including In-System Design) for
  * providing early devices for those host controllers to talk to!
@@ -93,14 +92,20 @@
  * 2001-June	Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "2002-Aug-28"
+#define DRIVER_VERSION "2002-Sep-23"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
+static const char	hcd_name [] = "ehci-hcd";
+
 
 // #define EHCI_VERBOSE_DEBUG
 // #define have_split_iso
 
+#ifdef DEBUG
+#define EHCI_STATS
+#endif
+
 #define INTR_AUTOMAGIC		/* to be removed later in 2.5 */
 
 /* magic numbers that can affect system performance */
@@ -118,6 +123,12 @@
 MODULE_PARM (log2_irq_thresh, "i");
 MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 
+/* allow irqs at least every N URB completions */
+static int max_completions = 16;
+MODULE_PARM (max_completions, "i");
+MODULE_PARM_DESC (max_completions,
+		"limit for urb completions called with irqs disenabled");
+
 #define	INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
 
 /*-------------------------------------------------------------------------*/
@@ -426,11 +437,10 @@
         /* PCI Serial Bus Release Number is at 0x60 offset */
 	pci_read_config_byte (hcd->pdev, 0x60, &tempbyte);
 	temp = readw (&ehci->caps->hci_version);
-	info ("USB %x.%x support enabled, EHCI rev %x.%02x",
-	      ((tempbyte & 0xf0)>>4),
-	      (tempbyte & 0x0f),
-	       temp >> 8,
-	       temp & 0xff);
+	info ("USB %x.%x support enabled, EHCI rev %x.%02x, %s %s",
+	      ((tempbyte & 0xf0)>>4), (tempbyte & 0x0f),
+	       temp >> 8, temp & 0xff,
+	       hcd_name, DRIVER_VERSION);
 
 	/*
 	 * From here on, khubd concurrently accesses the root
@@ -441,11 +451,7 @@
 	 */
 	usb_connect (udev);
 	udev->speed = USB_SPEED_HIGH;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
-	if (usb_new_device (udev) != 0) {
-#else
-	if (usb_register_root_hub (udev, &ehci->hcd.pdev->dev) != 0) {
-#endif
+	if (hcd_register_root (hcd) != 0) {
 		if (hcd->state == USB_STATE_RUNNING)
 			ehci_ready (ehci);
 		ehci_reset (ehci);
@@ -487,6 +493,13 @@
 	ehci_tasklet ((unsigned long) ehci);
 	ehci_mem_cleanup (ehci);
 
+#ifdef	EHCI_STATS
+	dbg ("irq normal %ld err %ld reclaim %ld",
+		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);
+	dbg ("complete %ld unlink %ld qpatch %ld",
+		ehci->stats.complete, ehci->stats.unlink, ehci->stats.qpatch);
+#endif
+
 	dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
 }
 
@@ -591,21 +604,16 @@
 static void ehci_tasklet (unsigned long param)
 {
 	struct ehci_hcd		*ehci = (struct ehci_hcd *) param;
-	unsigned long		flags;
 
-	// FIXME don't pass flags; on sparc they aren't really flags.
-	// qh_completions can just leave irqs blocked,
-	// then have scan_async() allow IRQs if it's very busy 
-
-	spin_lock_irqsave (&ehci->lock, flags);
+	spin_lock_irq (&ehci->lock);
 
 	if (ehci->reclaim_ready)
-		flags = end_unlink_async (ehci, flags);
-	flags = scan_async (ehci, flags);
+		end_unlink_async (ehci);
+	scan_async (ehci);
 	if (ehci->next_uframe != -1)
-		flags = scan_periodic (ehci, flags);
+		scan_periodic (ehci);
 
-	spin_unlock_irqrestore (&ehci->lock, flags);
+	spin_unlock_irq (&ehci->lock);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -639,11 +647,17 @@
 	/* INT, ERR, and IAA interrupt rates can be throttled */
 
 	/* normal [4.15.1.2] or error [4.15.1.1] completion */
-	if (likely ((status & (STS_INT|STS_ERR)) != 0))
+	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
+		if (likely ((status & STS_ERR) == 0))
+			COUNT (ehci->stats.normal);
+		else
+			COUNT (ehci->stats.error);
 		bh = 1;
+	}
 
 	/* complete the unlinking of some qh [4.15.2.3] */
 	if (status & STS_IAA) {
+		COUNT (ehci->stats.reclaim);
 		ehci->reclaim_ready = 1;
 		bh = 1;
 	}
@@ -765,10 +779,10 @@
 		spin_lock_irqsave (&ehci->lock, flags);
 		if (qh->qh_state == QH_STATE_LINKED) {
 			/* messy, can spin or block a microframe ... */
-			flags = intr_deschedule (ehci, qh, 1, flags);
+			intr_deschedule (ehci, qh, 1);
 			/* qh_state == IDLE */
 		}
-		flags = qh_completions (ehci, qh, flags);
+		qh_completions (ehci, qh);
 
 		/* reschedule QH iff another request is queued */
 		if (!list_empty (&qh->qtd_list)
@@ -880,8 +894,6 @@
 }
 
 /*-------------------------------------------------------------------------*/
-
-static const char	hcd_name [] = "ehci-hcd";
 
 static const struct hc_driver ehci_driver = {
 	.description =		hcd_name,
diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/host/ehci-hub.c	Fri Sep 27 14:51:04 2002
@@ -239,7 +239,8 @@
 
 		/* whoever resets must GetPortStatus to complete it!! */
 		if ((temp & PORT_RESET)
-				&& jiffies > ehci->reset_done [wIndex]) {
+				&& time_after (jiffies,
+					ehci->reset_done [wIndex])) {
 			status |= 1 << USB_PORT_FEAT_C_RESET;
 
 			/* force reset to complete */
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/usb/host/ehci-q.c	Fri Sep 27 14:51:03 2002
@@ -158,16 +158,13 @@
 	}
 }
 
-/* urb->lock ignored from here on (hcd is done with urb) */
-
-static unsigned long ehci_urb_done (
-	struct ehci_hcd		*ehci,
-	struct urb		*urb,
-	unsigned long		flags
-) {
+static void ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb)
+{
 #ifdef	INTR_AUTOMAGIC
 	struct urb		*resubmit = 0;
 	struct usb_device	*dev = 0;
+
+	static int ehci_urb_enqueue (struct usb_hcd *, struct urb *, int);
 #endif
 
 	if (likely (urb->hcpriv != 0)) {
@@ -199,8 +196,15 @@
 			urb->status = 0;
 	}
 
+	if (likely (urb->status == 0))
+		COUNT (ehci->stats.complete);
+	else if (urb->status == -ECONNRESET || urb->status == -ENOENT)
+		COUNT (ehci->stats.unlink);
+	else
+		COUNT (ehci->stats.error);
+
 	/* complete() can reenter this HCD */
-	spin_unlock_irqrestore (&ehci->lock, flags);
+	spin_unlock (&ehci->lock);
 	usb_hcd_giveback_urb (&ehci->hcd, urb);
 
 #ifdef	INTR_AUTOMAGIC
@@ -222,24 +226,25 @@
 	}
 #endif
 
-	spin_lock_irqsave (&ehci->lock, flags);
-	return flags;
+	spin_lock (&ehci->lock);
 }
 
 
 /*
  * Process and free completed qtds for a qh, returning URBs to drivers.
- * Chases up to qh->hw_current, returns irqsave flags (maybe modified).
+ * Chases up to qh->hw_current.  Returns number of completions called,
+ * indicating how much "real" work we did.
  */
-static unsigned long
-qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, unsigned long flags)
+static unsigned
+qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
 	struct ehci_qtd		*qtd, *last;
 	struct list_head	*next, *qtd_list = &qh->qtd_list;
 	int			unlink = 0, halted = 0;
+	unsigned		count = 0;
 
 	if (unlikely (list_empty (qtd_list)))
-		return flags;
+		return count;
 
 	/* scan QTDs till end of list, or we reach an active one */
 	for (qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list),
@@ -252,8 +257,10 @@
 
 		/* clean up any state from previous QTD ...*/
 		if (last) {
-			if (likely (last->urb != urb))
-				flags = ehci_urb_done (ehci, last->urb, flags);
+			if (likely (last->urb != urb)) {
+				ehci_urb_done (ehci, last->urb);
+				count++;
+			}
 
 			/* qh overlays can have HC's old cached copies of
 			 * next qtd ptrs, if an URB was queued afterwards.
@@ -262,6 +269,7 @@
 					&& last->hw_next != qh->hw_qtd_next) {
 				qh->hw_alt_next = last->hw_alt_next;
 				qh->hw_qtd_next = last->hw_next;
+				COUNT (ehci->stats.qpatch);
 			}
 
 			ehci_qtd_free (ehci, last);
@@ -347,7 +355,8 @@
 
 	/* last urb's completion might still need calling */
 	if (likely (last != 0)) {
-		flags = ehci_urb_done (ehci, last->urb, flags);
+		ehci_urb_done (ehci, last->urb);
+		count++;
 		ehci_qtd_free (ehci, last);
 	}
 
@@ -357,7 +366,7 @@
 				struct ehci_qtd, qtd_list));
 	}
 
-	return flags;
+	return count;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -890,8 +899,7 @@
 /* the async qh for the qtds being reclaimed are now unlinked from the HC */
 /* caller must not own ehci->lock */
 
-static unsigned long
-end_unlink_async (struct ehci_hcd *ehci, unsigned long flags)
+static void end_unlink_async (struct ehci_hcd *ehci)
 {
 	struct ehci_qh		*qh = ehci->reclaim;
 
@@ -903,18 +911,15 @@
 	ehci->reclaim = 0;
 	ehci->reclaim_ready = 0;
 
-	flags = qh_completions (ehci, qh, flags);
+	qh_completions (ehci, qh);
 
 	if (!list_empty (&qh->qtd_list)
 			&& HCD_IS_RUNNING (ehci->hcd.state))
 		qh_link_async (ehci, qh);
 	else
 		qh_put (ehci, qh);		// refcount from async list
-
-	return flags;
 }
 
-
 /* makes sure the async qh will become idle */
 /* caller must own ehci->lock */
 
@@ -944,12 +949,14 @@
 	if (unlikely (qh == ehci->async && qh->qh_next.qh == qh)) {
 		/* can't get here without STS_ASS set */
 		if (ehci->hcd.state != USB_STATE_HALT) {
-			if (cmd & CMD_PSE) {
-				writel (cmd & ~CMD_ASE, &ehci->regs->command);
-				(void) handshake (&ehci->regs->status,
-						  STS_ASS, 0, 150);
-			} else
-				ehci_ready (ehci);
+			writel (cmd & ~CMD_ASE, &ehci->regs->command);
+			(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
+#if 0
+			// one VT8235 system wants to die with STS_FATAL
+			// unless this qh is leaked here. others seem ok...
+			qh = qh_get (qh);
+			dbg_qh ("async/off", ehci, qh);
+#endif
 		}
 		qh->qh_next.qh = ehci->async = 0;
 
@@ -986,13 +993,15 @@
 
 /*-------------------------------------------------------------------------*/
 
-static unsigned long
-scan_async (struct ehci_hcd *ehci, unsigned long flags)
+static void
+scan_async (struct ehci_hcd *ehci)
 {
 	struct ehci_qh		*qh;
+	unsigned		count;
 
 rescan:
 	qh = ehci->async;
+	count = 0;
 	if (likely (qh != 0)) {
 		do {
 			/* clean any finished work for this qh */
@@ -1001,13 +1010,16 @@
 				qh = qh_get (qh);
 
 				/* concurrent unlink could happen here */
-				flags = qh_completions (ehci, qh, flags);
+				count += qh_completions (ehci, qh);
 				qh_put (ehci, qh);
 			}
 
 			/* unlink idle entries, reducing HC PCI usage as
 			 * well as HCD schedule-scanning costs.  removing
 			 * the last qh is deferred, since it's costly.
+			 *
+			 * FIXME don't unlink idle entries so quickly; it
+			 * can penalize (common) half duplex protocols.
 			 */
 			if (list_empty (&qh->qtd_list) && !ehci->reclaim) {
 				if (qh->qh_next.qh != qh) {
@@ -1020,10 +1032,18 @@
 						jiffies + EHCI_ASYNC_JIFFIES);
 				}
 			}
+
+			/* keep latencies down: let any irqs in */
+			if (count > max_completions) {
+				spin_unlock_irq (&ehci->lock);
+				cpu_relax ();
+				spin_lock_irq (&ehci->lock);
+				goto rescan;
+			}
+
 			qh = qh->qh_next.qh;
 			if (!qh)		/* unlinked? */
 				goto rescan;
 		} while (qh != ehci->async);
 	}
-	return flags;
 }
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/usb/host/ehci-sched.c	Fri Sep 27 14:51:03 2002
@@ -222,11 +222,10 @@
 
 // FIXME microframe periods not yet handled
 
-static unsigned long intr_deschedule (
+static void intr_deschedule (
 	struct ehci_hcd	*ehci,
 	struct ehci_qh	*qh,
-	int		wait,
-	unsigned long	flags
+	int		wait
 ) {
 	int		status;
 	unsigned	frame = qh->start;
@@ -256,10 +255,8 @@
 	 */
 	if (((ehci_get_frame (&ehci->hcd) - frame) % qh->period) == 0) {
 		if (wait) {
-			spin_unlock_irqrestore (&ehci->lock, flags);
 			udelay (125);
 			qh->hw_next = EHCI_LIST_END;
-			spin_lock_irqsave (&ehci->lock, flags);
 		} else {
 			/* we may not be IDLE yet, but if the qh is empty
 			 * the race is very short.  then if qh also isn't
@@ -276,10 +273,9 @@
 	hcd_to_bus (&ehci->hcd)->bandwidth_allocated -= 
 		(qh->usecs + qh->c_usecs) / qh->period;
 
-	vdbg ("descheduled qh %p, per = %d frame = %d count = %d, urbs = %d",
+	dbg ("descheduled qh %p, period = %d frame = %d count = %d, urbs = %d",
 		qh, qh->period, frame,
 		atomic_read (&qh->refcount), ehci->periodic_sched);
-	return flags;
 }
 
 static int check_period (
@@ -414,7 +410,7 @@
 
 	/* stuff into the periodic schedule */
 	qh->qh_state = QH_STATE_LINKED;
-	dbg ("qh %p usecs %d/%d period %d.0 starting %d.%d (gap %d)",
+	dbg ("scheduled qh %p usecs %d/%d period %d.0 starting %d.%d (gap %d)",
 		qh, qh->usecs, qh->c_usecs,
 		qh->period, frame, uframe, qh->gap_uf);
 	do {
@@ -495,29 +491,30 @@
 	return status;
 }
 
-static unsigned long
+static unsigned
 intr_complete (
 	struct ehci_hcd	*ehci,
 	unsigned	frame,
-	struct ehci_qh	*qh,
-	unsigned long	flags		/* caller owns ehci->lock ... */
+	struct ehci_qh	*qh
 ) {
+	unsigned	count;
+
 	/* nothing to report? */
 	if (likely ((qh->hw_token & __constant_cpu_to_le32 (QTD_STS_ACTIVE))
 			!= 0))
-		return flags;
+		return 0;
 	if (unlikely (list_empty (&qh->qtd_list))) {
 		dbg ("intr qh %p no TDs?", qh);
-		return flags;
+		return 0;
 	}
 	
 	/* handle any completions */
-	flags = qh_completions (ehci, qh, flags);
+	count = qh_completions (ehci, qh);
 
 	if (unlikely (list_empty (&qh->qtd_list)))
-		flags = intr_deschedule (ehci, qh, 0, flags);
+		intr_deschedule (ehci, qh, 0);
 
-	return flags;
+	return count;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -866,12 +863,11 @@
 
 #define	ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
 
-static unsigned long
+static unsigned
 itd_complete (
 	struct ehci_hcd	*ehci,
 	struct ehci_itd	*itd,
-	unsigned	uframe,
-	unsigned long	flags
+	unsigned	uframe
 ) {
 	struct urb				*urb = itd->urb;
 	struct usb_iso_packet_descriptor	*desc;
@@ -909,7 +905,7 @@
 
 	/* handle completion now? */
 	if ((itd->index + 1) != urb->number_of_packets)
-		return flags;
+		return 0;
 
 	/*
 	 * Always give the urb back to the driver ... expect it to submit
@@ -924,16 +920,17 @@
 	if (urb->status == -EINPROGRESS)
 		urb->status = 0;
 
-	spin_unlock_irqrestore (&ehci->lock, flags);
+	/* complete() can reenter this HCD */
+	spin_unlock (&ehci->lock);
 	usb_hcd_giveback_urb (&ehci->hcd, urb);
-	spin_lock_irqsave (&ehci->lock, flags);
+	spin_lock (&ehci->lock);
 
 	/* defer stopping schedule; completion can submit */
 	ehci->periodic_sched--;
 	if (!ehci->periodic_sched)
 		(void) disable_periodic (ehci);
 
-	return flags;
+	return 1;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -945,10 +942,6 @@
 
 	dbg ("itd_submit urb %p", urb);
 
-	/* NOTE DMA mapping assumes this ... */
-	if (urb->iso_frame_desc [0].offset != 0)
-		return -EINVAL;
-	
 	/* allocate ITDs w/o locking anything */
 	status = itd_urb_transaction (ehci, urb, mem_flags);
 	if (status < 0)
@@ -979,10 +972,11 @@
 
 /*-------------------------------------------------------------------------*/
 
-static unsigned long
-scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
+static void
+scan_periodic (struct ehci_hcd *ehci)
 {
 	unsigned	frame, clock, now_uframe, mod;
+	unsigned	count = 0;
 
 	mod = ehci->periodic_size << 3;
 
@@ -1005,6 +999,14 @@
 		u32			type, *hw_p;
 		unsigned		uframes;
 
+		/* keep latencies down: let any irqs in */
+		if (count > max_completions) {
+			spin_unlock_irq (&ehci->lock);
+			cpu_relax ();
+			count = 0;
+			spin_lock_irq (&ehci->lock);
+		}
+
 restart:
 		/* scan schedule to _before_ current frame index */
 		if (frame == clock)
@@ -1028,8 +1030,8 @@
 				last = (q.qh->hw_next == EHCI_LIST_END);
 				temp = q.qh->qh_next;
 				type = Q_NEXT_TYPE (q.qh->hw_next);
-				flags = intr_complete (ehci, frame,
-						qh_get (q.qh), flags);
+				count += intr_complete (ehci, frame,
+						qh_get (q.qh));
 				qh_put (ehci, q.qh);
 				q = temp;
 				break;
@@ -1061,8 +1063,8 @@
 						type = Q_NEXT_TYPE (*hw_p);
 
 						/* might free q.itd ... */
-						flags = itd_complete (ehci,
-							temp.itd, uf, flags);
+						count += itd_complete (ehci,
+							temp.itd, uf);
 						break;
 					}
 				}
@@ -1078,7 +1080,7 @@
 #ifdef have_split_iso
 			case Q_TYPE_SITD:
 				last = (q.sitd->hw_next == EHCI_LIST_END);
-				flags = sitd_complete (ehci, q.sitd, flags);
+				sitd_complete (ehci, q.sitd);
 				type = Q_NEXT_TYPE (q.sitd->hw_next);
 
 				// FIXME unlink SITD after split completes
@@ -1124,5 +1126,4 @@
 		} else
 			frame = (frame + 1) % ehci->periodic_size;
 	} 
-	return flags;
 }
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/host/ehci.h	Fri Sep 27 14:51:05 2002
@@ -21,6 +21,23 @@
 
 /* definitions used for the EHCI driver */
 
+/* statistics can be kept for for tuning/monitoring */
+struct ehci_stats {
+	/* irq usage */
+	unsigned long		normal;
+	unsigned long		error;
+	unsigned long		reclaim;
+
+	/* termination of urbs from core */
+	unsigned long		complete;
+	unsigned long		unlink;
+
+	/* qhs patched to recover from td queueing race
+	 * (can avoid by using 'dummy td', allowing fewer irqs)
+	 */
+	unsigned long		qpatch;
+};
+
 /* ehci_hcd->lock guards shared data against other CPUs:
  *   ehci_hcd:	async, reclaim, periodic (and shadow), ...
  *   hcd_dev:	ep[]
@@ -72,6 +89,13 @@
 	struct pci_pool		*sitd_pool;	/* sitd per split iso urb */
 
 	struct timer_list	watchdog;
+
+#ifdef EHCI_STATS
+	struct ehci_stats	stats;
+#	define COUNT(x) do { (x)++; } while (0)
+#else
+#	define COUNT(x) do {} while (0)
+#endif
 };
 
 /* unwrap an HCD pointer to get an EHCI_HCD pointer */ 
@@ -400,10 +424,22 @@
 #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb)
 #define STUB_DEBUG_FILES
 
+static inline int hcd_register_root (struct usb_hcd *hcd)
+{
+	return usb_new_device (hcd_to_bus (hcd)->root_hub);
+}
+
 #else	/* LINUX_VERSION_CODE */
 
+// hcd_to_bus() eventually moves to hcd.h on 2.5 too
 static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
 	{ return &hcd->self; }
+// ... as does hcd_register_root()
+static inline int hcd_register_root (struct usb_hcd *hcd)
+{
+	return usb_register_root_hub (
+		hcd_to_bus (hcd)->root_hub, &hcd->pdev->dev);
+}
 
 #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
 
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c	Fri Sep 27 14:51:03 2002
+++ b/drivers/usb/host/ohci-hcd.c	Fri Sep 27 14:51:03 2002
@@ -92,6 +92,7 @@
 #endif
 
 #include <linux/usb.h>
+#include <linux/version.h>
 #include "../core/hcd.h"
 
 #include <asm/io.h>
@@ -108,7 +109,7 @@
  *	- lots more testing!!
  */
 
-#define DRIVER_VERSION "2002-Sep-03"
+#define DRIVER_VERSION "2002-Sep-17"
 #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
 #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
 
@@ -318,9 +319,6 @@
 	struct hcd_dev		*dev = (struct hcd_dev *) udev->hcpriv;
 	int			i;
 	unsigned long		flags;
-#ifdef DEBUG
-	int			rescans = 0;
-#endif
 
 rescan:
 	/* free any eds, and dummy tds, still hanging around */
@@ -340,16 +338,18 @@
 			td_free (ohci, ed->dummy);
 			break;
 		default:
-#ifdef DEBUG
-			err ("illegal ED %d state in free_config, %d",
+			err ("%s-%s ed %p (#%d) not unlinked; disconnect() bug? %d",
+				ohci->hcd.self.bus_name, udev->devpath, ed,
 				i, ed->state);
-#endif
 			/* ED_OPER: some driver disconnect() is broken,
 			 * it didn't even start its unlinks much less wait
 			 * for their completions.
 			 * OTHERWISE:  hcd bug, ed is garbage
+			 *
+			 * ... we can't recycle this memory in either case,
+			 * so just leak it to avoid oopsing.
 			 */
-			BUG ();
+			continue;
 		}
 		ed_free (ohci, ed);
 	}
@@ -360,13 +360,9 @@
 #ifdef DEBUG
 	/* a driver->disconnect() returned before its unlinks completed? */
 	if (in_interrupt ()) {
-		dbg ("WARNING: spin in interrupt; driver->disconnect() bug");
-		dbg ("dev usb-%s-%s ep 0x%x", 
+		warn ("disconnect() bug for dev usb-%s-%s ep 0x%x", 
 			ohci->hcd.self.bus_name, udev->devpath, i);
 	}
-	BUG_ON (!(readl (&ohci->regs->intrenable) & OHCI_INTR_SF));
-	BUG_ON (rescans >= 2);	/* HWBUG */
-	rescans++;
 #endif
 
 	spin_unlock_irqrestore (&ohci->lock, flags);
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/host/ohci-q.c	Fri Sep 27 14:51:05 2002
@@ -36,12 +36,7 @@
 {
 	unsigned long	flags;
 
-#ifdef DEBUG
-	if (!urb->hcpriv) {
-		err ("already unlinked!");
-		BUG ();
-	}
-#endif
+	// ASSERT (urb->hcpriv != 0);
 
 	urb_free_priv (ohci, urb->hcpriv);
 	urb->hcpriv = NULL;
@@ -51,6 +46,7 @@
 		urb->status = 0;
 	spin_unlock_irqrestore (&urb->lock, flags);
 
+	// what lock protects these?
 	switch (usb_pipetype (urb->pipe)) {
 	case PIPE_ISOCHRONOUS:
 		ohci->hcd.self.bandwidth_isoc_reqs--;
@@ -425,6 +421,9 @@
 	/* FIXME:  Don't do this without knowing it's safe to clobber this
 	 * state/mode info.  Currently the upper layers don't support such
 	 * guarantees; we're lucky changing config/altsetting is rare.
+	 * The state/mode info also changes during enumeration: set_address
+	 * uses the 'wrong' device address, and ep0 maxpacketsize will often
+	 * improve on the initial value.
 	 */
   	if (ed->state == ED_IDLE) {
 		u32	info;
@@ -454,25 +453,6 @@
 		}
 		ed->hwINFO = info;
 
-#ifdef DEBUG
-	/*
-	 * There are two other cases we ought to change hwINFO, both during
-	 * enumeration.  There, the control request completes, unlinks, and
-	 * the next request gets queued before the unlink completes, so it
-	 * uses old/wrong hwINFO.  How much of a problem is this?  khubd is
-	 * already retrying after such failures...
-	 */
-	} else if (type == PIPE_CONTROL) {
-		u32	info = le32_to_cpup (&ed->hwINFO);
-
-		if (!(info & 0x7f))
-			dbg ("RETRY ctrl: address != 0");
-		info >>= 16;
-		if (info != udev->epmaxpacketin [0])
-			dbg ("RETRY ctrl: maxpacket %d != 8",
-				udev->epmaxpacketin [0]);
-
-#endif /* DEBUG */
 	}
 
 done:
@@ -526,10 +506,7 @@
 	struct urb_priv		*urb_priv = urb->hcpriv;
 	int			is_iso = info & TD_ISO;
 
-	if (index >= urb_priv->length) {
-		err ("internal OHCI error: TD index > length");
-		return;
-	}
+	// ASSERT (index < urb_priv->length);
 
 	/* aim for only one interrupt per urb.  mostly applies to control
 	 * and iso; other urbs rarely need more than one TD per urb.
@@ -578,6 +555,7 @@
 	wmb ();
 
 	/* append to queue */
+	list_add_tail (&td->td_list, &td->ed->td_list);
 	td->ed->hwTailP = td->hwNextTD;
 }
 
@@ -698,8 +676,7 @@
 		ohci->hcd.self.bandwidth_isoc_reqs++;
 		break;
 	}
-	if (urb_priv->length != cnt)
-		dbg ("TD LENGTH %d != CNT %d", urb_priv->length, cnt);
+	// ASSERT (urb_priv->length == cnt);
 }
 
 /*-------------------------------------------------------------------------*
@@ -714,6 +691,8 @@
 	u32	tdINFO = le32_to_cpup (&td->hwINFO);
 	int	cc = 0;
 
+	list_del (&td->td_list);
+
 	/* ISO ... drivers see per-TD length/status */
   	if (tdINFO & TD_ISO) {
  		u16	tdPSW = le16_to_cpu (td->hwPSW [0]);
@@ -792,74 +771,106 @@
 
 /*-------------------------------------------------------------------------*/
 
+static inline struct td *
+ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
+{
+  	struct urb		*urb = td->urb;
+	struct ed		*ed = td->ed;
+	struct list_head	*tmp = td->td_list.next;
+	u32			toggle = ed->hwHeadP & ED_C;
+
+	/* clear ed halt; this is the td that caused it, but keep it inactive
+	 * until its urb->complete() has a chance to clean up.
+	 */
+	ed->hwINFO |= ED_SKIP;
+	wmb ();
+	td->ed->hwHeadP &= ~ED_H; 
+
+	while (tmp != &ed->td_list) {
+		struct td	*next;
+
+		next = list_entry (tmp, struct td, td_list);
+		tmp = next->td_list.next;
+
+		/* move other tds from this urb to the donelist, after 'td'.
+		 * order won't matter here: no errors, nothing transferred.
+		 *
+		 * NOTE: this "knows" short control reads won't need fixup:
+		 * hc went from the (one) data TD to the status td. that'll
+		 * change if multi-td control DATA segments are supported,
+		 * and we want to send the status packet.
+		 */
+		if (next->urb == urb) {
+			u32	info = next->hwINFO;
+
+			info |= cpu_to_le32 (TD_DONE);
+			info &= ~cpu_to_le32 (TD_CC);
+			next->hwINFO = info;
+			next->next_dl_td = rev;	
+			rev = next;
+			continue;
+		}
+
+		/* restart ed with first td of this next urb */
+		ed->hwHeadP = cpu_to_le32 (next->td_dma) | toggle;
+		tmp = 0;
+		break;
+	}
+
+	/* no urbs queued? then ED is empty. */
+	if (tmp)
+		ed->hwHeadP = cpu_to_le32 (ed->dummy->td_dma) | toggle;
+
+	/* help for troubleshooting: */
+	dbg ("urb %p usb-%s-%s ep-%d-%s cc %d --> status %d",
+		urb,
+		urb->dev->bus->bus_name, urb->dev->devpath,
+		usb_pipeendpoint (urb->pipe),
+		usb_pipein (urb->pipe) ? "IN" : "OUT",
+		cc, cc_to_error [cc]);
+
+	return rev;
+}
+
 /* replies to the request have to be on a FIFO basis so
  * we unreverse the hc-reversed done-list
  */
 static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
 {
-	__u32		td_list_hc;
+	u32		td_dma;
 	struct td	*td_rev = NULL;
-	struct td	*td_list = NULL;
-  	urb_priv_t	*urb_priv = NULL;
+	struct td	*td = NULL;
   	unsigned long	flags;
 
   	spin_lock_irqsave (&ohci->lock, flags);
 
-	td_list_hc = le32_to_cpup (&ohci->hcca->done_head);
+	td_dma = le32_to_cpup (&ohci->hcca->done_head);
 	ohci->hcca->done_head = 0;
 
-	while (td_list_hc) {		
+	/* get TD from hc's singly linked list, and
+	 * prepend to ours.  ed->td_list changes later.
+	 */
+	while (td_dma) {		
 	    	int		cc;
 
-		td_list = dma_to_td (ohci, td_list_hc);
+		td = dma_to_td (ohci, td_dma);
 
-		td_list->hwINFO |= cpu_to_le32 (TD_DONE);
+		td->hwINFO |= cpu_to_le32 (TD_DONE);
+		cc = TD_CC_GET (le32_to_cpup (&td->hwINFO));
 
-		cc = TD_CC_GET (le32_to_cpup (&td_list->hwINFO));
-		if (cc != TD_CC_NOERROR) {
-			urb_priv = (urb_priv_t *) td_list->urb->hcpriv;
-
-			/* Non-iso endpoints can halt on error; un-halt,
-			 * and dequeue any other TDs from this urb.
-			 * No other TD could have caused the halt.
-			 */
-			if (td_list->ed->hwHeadP & ED_H) {
-				if (urb_priv && ((td_list->index + 1)
-						< urb_priv->length)) {
-#ifdef DEBUG
-					struct urb *urb = td_list->urb;
-
-					/* help for troubleshooting: */
-					dbg ("urb %p usb-%s-%s ep-%d-%s "
-						    "(td %d/%d), "
-						    "cc %d --> status %d",
-						td_list->urb,
-						urb->dev->bus->bus_name,
-						urb->dev->devpath,
-						usb_pipeendpoint (urb->pipe),
-						usb_pipein (urb->pipe)
-						    ? "IN" : "OUT",
-						1 + td_list->index,
-						urb_priv->length,
-						cc, cc_to_error [cc]);
-#endif
-					td_list->ed->hwHeadP = 
-			    (urb_priv->td [urb_priv->length - 1]->hwNextTD
-				    & __constant_cpu_to_le32 (TD_MASK))
-			    | (td_list->ed->hwHeadP & ED_C);
-					urb_priv->td_cnt += urb_priv->length
-						- td_list->index - 1;
-				} else 
-					td_list->ed->hwHeadP &= ~ED_H;
-			}
-		}
+		/* Non-iso endpoints can halt on error; un-halt,
+		 * and dequeue any other TDs from this urb.
+		 * No other TD could have caused the halt.
+		 */
+		if (cc != TD_CC_NOERROR && (td->ed->hwHeadP & ED_H))
+			td_rev = ed_halted (ohci, td, cc, td_rev);
 
-		td_list->next_dl_td = td_rev;	
-		td_rev = td_list;
-		td_list_hc = le32_to_cpup (&td_list->hwNextTD);
+		td->next_dl_td = td_rev;	
+		td_rev = td;
+		td_dma = le32_to_cpup (&td->hwNextTD);
 	}	
 	spin_unlock_irqrestore (&ohci->lock, flags);
-	return td_list;
+	return td_rev;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -874,9 +885,9 @@
 
 rescan_all:
 	for (last = &ohci->ed_rm_list, ed = *last; ed != NULL; ed = *last) {
-		struct td	*td, *td_next, *tdHeadP, *tdTailP;
-		u32		*td_p;
-		int		completed, modified;
+		struct list_head	*entry, *tmp;
+		int			completed, modified;
+		u32			*prev;
 
 		/* only take off EDs that the HC isn't using, accounting for
 		 * frame counter wraps.
@@ -897,53 +908,52 @@
 		/* unlink urbs as requested, but rescan the list after
 		 * we call a completion since it might have unlinked
 		 * another (earlier) urb
-		 *
-		 * FIXME use td_list to scan, not td hashtables.
 		 */
 rescan_this:
 		completed = 0;
+		prev = &ed->hwHeadP;
+		list_for_each_safe (entry, tmp, &ed->td_list) {
+			struct td	*td;
+			struct urb	*urb;
+			urb_priv_t	*urb_priv;
+			u32		savebits;
+
+			td = list_entry (entry, struct td, td_list);
+			urb = td->urb;
+			urb_priv = td->urb->hcpriv;
 
-		tdTailP = dma_to_td (ohci, le32_to_cpup (&ed->hwTailP));
-		tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP));
-		td_p = &ed->hwHeadP;
-
-		for (td = tdHeadP; td != tdTailP; td = td_next) {
-			struct urb *urb = td->urb;
-			urb_priv_t *urb_priv = td->urb->hcpriv;
-
-			td_next = dma_to_td (ohci,
-				le32_to_cpup (&td->hwNextTD));
-			if (urb_priv->state == URB_DEL) {
-
-				/* HC may have partly processed this TD */
-				td_done (urb, td);
-				urb_priv->td_cnt++;
-
-				*td_p = td->hwNextTD | (*td_p & ~TD_MASK);
-
-				/* URB is done; clean up */
-				if (urb_priv->td_cnt == urb_priv->length) {
-					modified = completed = 1;
-     					spin_unlock (&ohci->lock);
-					finish_urb (ohci, urb);
-					spin_lock (&ohci->lock);
-				}
-			} else {
-				td_p = &td->hwNextTD;
+			if (urb_priv->state != URB_DEL) {
+				prev = &td->hwNextTD;
+				continue;
+			}
+
+			/* patch pointer hc uses */
+			savebits = *prev & cpu_to_le32 (TD_MASK);
+			*prev = td->hwNextTD | savebits;
+
+			/* HC may have partly processed this TD */
+			td_done (urb, td);
+			urb_priv->td_cnt++;
+
+			/* if URB is done, clean up */
+			if (urb_priv->td_cnt == urb_priv->length) {
+				modified = completed = 1;
+				spin_unlock (&ohci->lock);
+				finish_urb (ohci, urb);
+				spin_lock (&ohci->lock);
 			}
 		}
+		if (completed && !list_empty (&ed->td_list))
+			goto rescan_this;
 
 		/* ED's now officially unlinked, hc doesn't see */
 		ed->state = ED_IDLE;
-		ed->hwINFO &= ~ED_SKIP;
+		ed->hwINFO &= ~(ED_SKIP | ED_DEQUEUE);
 		ed->hwHeadP &= ~ED_H;
 		ed->hwNextED = 0;
 
 		/* but if there's work queued, reschedule */
-		tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP));
-		if (tdHeadP != tdTailP) {
-			if (completed)
-				goto rescan_this;
+		if (!list_empty (&ed->td_list)) {
 			if (!ohci->disabled && !ohci->sleeping)
 				ed_schedule (ohci, ed);
 		}
@@ -1027,10 +1037,15 @@
   		}
 
 		/* clean schedule:  unlink EDs that are no longer busy */
-		if ((ed->hwHeadP & __constant_cpu_to_le32 (TD_MASK))
-					== ed->hwTailP
-				&& (ed->state == ED_OPER)) 
+		if (list_empty (&ed->td_list))
 			ed_deschedule (ohci, ed);
+		/* ... reenabling halted EDs only after fault cleanup */
+		else if (!(ed->hwINFO & ED_DEQUEUE)) {
+			td = list_entry (ed->td_list.next, struct td, td_list);
+			if (!(td->hwINFO & TD_DONE))
+				ed->hwINFO &= ~ED_SKIP;
+		}
+
     		td = td_next;
   	}  
 	spin_unlock_irqrestore (&ohci->lock, flags);
diff -Nru a/drivers/usb/misc/Config.help b/drivers/usb/misc/Config.help
--- a/drivers/usb/misc/Config.help	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/misc/Config.help	Fri Sep 27 14:51:04 2002
@@ -112,3 +112,13 @@
   For more information, see Johan Verrept's webpages at
   <http://linux-usb.sourceforge.net/SpeedTouch/>.
 
+CONFIG_USB_LCD
+  Say Y here if you want to connect an USBLCD to your computer's
+  USB port. The USBLCD is a small USB interface board for
+  alphanumeric LCD modules. See <http://www.usblcd.de> for more
+  information.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called usblcd.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
diff -Nru a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
--- a/drivers/usb/misc/usblcd.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/usb/misc/usblcd.c	Fri Sep 27 14:51:02 2002
@@ -1,7 +1,7 @@
 /***************************************************************************** 
  *                          USBLCD Kernel Driver                             *
  *        See http://www.usblcd.de for Hardware and Documentation.           *
- *                            Version 1.01                                   *
+ *                            Version 1.03                                   *
  *             (C) 2002 Adams IT Services <info@usblcd.de>                   *
  *                                                                           *
  *     This file is licensed under the GPL. See COPYING in the package.      *
@@ -18,7 +18,7 @@
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 
-#define DRIVER_VERSION "USBLCD Driver Version 1.01"
+#define DRIVER_VERSION "USBLCD Driver Version 1.03"
 
 #define USBLCD_MINOR		144
 
@@ -26,7 +26,7 @@
 #define IOCTL_GET_DRV_VERSION	2
 
 /* stall/wait timeout for USBLCD */
-#define NAK_TIMEOUT	(HZ)
+#define NAK_TIMEOUT	(10*HZ)
 
 #define IBUF_SIZE	0x1000
 #define OBUF_SIZE	0x10000
@@ -318,7 +318,7 @@
 }
 
 static struct usb_device_id id_table [] = {
-	{ .idVendor = 0x1212, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
+	{ .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
 	{},
 };
 
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/serial/usb-serial.h	Fri Sep 27 14:51:05 2002
@@ -232,6 +232,7 @@
 
 extern int  usb_serial_register(struct usb_serial_device_type *new_device);
 extern void usb_serial_deregister(struct usb_serial_device_type *device);
+extern void usb_serial_port_softint(void *private);
 
 extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
 extern void usb_serial_disconnect(struct usb_interface *iface);
diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
--- a/drivers/usb/serial/usbserial.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/serial/usbserial.c	Fri Sep 27 14:51:04 2002
@@ -498,7 +498,7 @@
 		return -ENOMEM;
 	}
 	memcpy (transfer_buffer, data, length);
-	result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 300);
+	result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3*HZ);
 	kfree (transfer_buffer);
 	return result;
 }
@@ -557,12 +557,11 @@
 			retval = serial->type->open(port, filp);
 		else
 			retval = generic_open(port, filp);
-	}
-
-	if (retval) {
-		port->open_count = 0;
-		if (serial->type->owner)
-			__MOD_DEC_USE_COUNT(serial->type->owner);
+		if (retval) {
+			port->open_count = 0;
+			if (serial->type->owner)
+				__MOD_DEC_USE_COUNT(serial->type->owner);
+		}
 	}
 
 	up (&port->sem);
@@ -1091,6 +1090,8 @@
 		return;
 	}
 
+	usb_serial_port_softint((void *)port);
+
 	queue_task(&port->tqueue, &tq_immediate);
 	mark_bh(IMMEDIATE_BH);
 
@@ -1109,14 +1110,18 @@
 	}
 }
 
-static void port_softint(void *private)
+void usb_serial_port_softint(void *private)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)private;
-	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+	struct usb_serial *serial;
 	struct tty_struct *tty;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 	
+	if (!port)
+		return;
+
+	serial = get_usb_serial (port, __FUNCTION__);
 	if (!serial)
 		return;
 
@@ -1400,7 +1405,7 @@
 		port->number = i + serial->minor;
 		port->serial = serial;
 		port->magic = USB_SERIAL_PORT_MAGIC;
-		port->tqueue.routine = port_softint;
+		port->tqueue.routine = usb_serial_port_softint;
 		port->tqueue.data = port;
 		init_MUTEX (&port->sem);
 	}
@@ -1690,6 +1695,7 @@
 EXPORT_SYMBOL(usb_serial_deregister);
 EXPORT_SYMBOL(usb_serial_probe);
 EXPORT_SYMBOL(usb_serial_disconnect);
+EXPORT_SYMBOL(usb_serial_port_softint);
 #ifdef USES_EZUSB_FUNCTIONS
 	EXPORT_SYMBOL(ezusb_writememory);
 	EXPORT_SYMBOL(ezusb_set_reset);
diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
--- a/drivers/usb/serial/whiteheat.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/serial/whiteheat.c	Fri Sep 27 14:51:04 2002
@@ -1,6 +1,9 @@
 /*
  * USB ConnectTech WhiteHEAT driver
  *
+ *	Copyright (C) 2002
+ *	    Connect Tech Inc.
+ *
  *	Copyright (C) 1999 - 2001
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
@@ -11,6 +14,9 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (10/09/2002) Stuart MacDonald (stuartm@connecttech.com)
+ *	Upgrade to full working driver
+ *
  * (05/30/2001) gkh
  *	switched from using spinlock to a semaphore, which fixes lots of problems.
  *
@@ -71,6 +77,8 @@
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
+#include <linux/serial_reg.h>
+#include <linux/serial.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
 	static int debug = 1;
@@ -85,8 +93,8 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.2"
-#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
+#define DRIVER_VERSION "v2.0"
+#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Stuart MacDonald <stuartm@connecttech.com>"
 #define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
 
 #define CONNECT_TECH_VENDOR_ID		0x0710
@@ -125,16 +133,25 @@
 	.id_table =	id_table_combined,
 };
 
+/* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
+static int  whiteheat_firmware_download	(struct usb_serial *serial);
+static int  whiteheat_firmware_attach	(struct usb_serial *serial);
+
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
+static int  whiteheat_attach		(struct usb_serial *serial);
+static void whiteheat_shutdown		(struct usb_serial *serial);
 static int  whiteheat_open		(struct usb_serial_port *port, struct file *filp);
 static void whiteheat_close		(struct usb_serial_port *port, struct file *filp);
+static int  whiteheat_write		(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
+static int  whiteheat_write_room	(struct usb_serial_port *port);
 static int  whiteheat_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void whiteheat_set_termios	(struct usb_serial_port *port, struct termios * old);
+static void whiteheat_break_ctl		(struct usb_serial_port *port, int break_state);
+static int  whiteheat_chars_in_buffer	(struct usb_serial_port *port);
 static void whiteheat_throttle		(struct usb_serial_port *port);
 static void whiteheat_unthrottle	(struct usb_serial_port *port);
-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 void whiteheat_read_callback	(struct urb *urb);
+static void whiteheat_write_callback	(struct urb *urb);
 
 static struct usb_serial_device_type whiteheat_fake_device = {
 	.owner =		THIS_MODULE,
@@ -145,6 +162,7 @@
 	.num_bulk_out =		NUM_DONT_CARE,
 	.num_ports =		1,
 	.probe =		whiteheat_firmware_download,
+	.attach =		whiteheat_firmware_attach,
 };
 
 static struct usb_serial_device_type whiteheat_device = {
@@ -155,34 +173,606 @@
 	.num_bulk_in =		NUM_DONT_CARE,
 	.num_bulk_out =		NUM_DONT_CARE,
 	.num_ports =		4,
+	.attach =		whiteheat_attach,
+	.shutdown =		whiteheat_shutdown,
 	.open =			whiteheat_open,
 	.close =		whiteheat_close,
-	.throttle =		whiteheat_throttle,
-	.unthrottle =		whiteheat_unthrottle,
+	.write =		whiteheat_write,
+	.write_room =		whiteheat_write_room,
 	.ioctl =		whiteheat_ioctl,
 	.set_termios =		whiteheat_set_termios,
-	.attach =		whiteheat_attach,
-	.shutdown =		whiteheat_shutdown,
+	.break_ctl =		whiteheat_break_ctl,
+	.chars_in_buffer =	whiteheat_chars_in_buffer,
+	.throttle =		whiteheat_throttle,
+	.unthrottle =		whiteheat_unthrottle,
+	.read_bulk_callback =	whiteheat_read_callback,
+	.write_bulk_callback =	whiteheat_write_callback,
 };
 
-struct whiteheat_private {
+
+struct whiteheat_command_private {
+	spinlock_t		lock;
+	__u8			port_running;
 	__u8			command_finished;
 	wait_queue_head_t	wait_command;	/* for handling sleeping while waiting for a command to finish */
+	__u8			result_buffer[64];
 };
 
 
-/* local function prototypes */
-static inline void set_rts	(struct usb_serial_port *port, unsigned char rts);
-static inline void set_dtr	(struct usb_serial_port *port, unsigned char dtr);
-static inline void set_break	(struct usb_serial_port *port, unsigned char brk);
+#define THROTTLED		0x01
+#define ACTUALLY_THROTTLED	0x02
 
+struct whiteheat_private {
+	spinlock_t		lock;
+	__u8			flags;
+	__u8			mcr;
+};
+
+
+/* local function prototypes */
+static int start_command_port(struct usb_serial *serial);
+static void stop_command_port(struct usb_serial *serial);
+static void command_port_write_callback(struct urb *urb);
+static void command_port_read_callback(struct urb *urb);
+
+static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize);
+static int firm_open(struct usb_serial_port *port);
+static int firm_close(struct usb_serial_port *port);
+static int firm_setup_port(struct usb_serial_port *port);
+static int firm_set_rts(struct usb_serial_port *port, __u8 onoff);
+static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff);
+static int firm_set_break(struct usb_serial_port *port, __u8 onoff);
+static int firm_purge(struct usb_serial_port *port, __u8 rxtx);
+static int firm_get_dtr_rts(struct usb_serial_port *port);
+static int firm_report_tx_done(struct usb_serial_port *port);
 
 
 #define COMMAND_PORT		4
 #define COMMAND_TIMEOUT		(2*HZ)	/* 2 second timeout for a command */
+#define CLOSING_DELAY		(30 * HZ)
+
+
+/*****************************************************************************
+ * Connect Tech's White Heat prerenumeration driver functions
+ *****************************************************************************/
+
+/* steps to download the firmware to the WhiteHEAT device:
+ - hold the reset (by writing to the reset bit of the CPUCS register)
+ - download the VEND_AX.HEX file to the chip using VENDOR_REQUEST-ANCHOR_LOAD
+ - release the reset (by writing to the CPUCS register)
+ - download the WH.HEX file for all addresses greater than 0x1b3f using
+   VENDOR_REQUEST-ANCHOR_EXTERNAL_RAM_LOAD
+ - hold the reset
+ - download the WH.HEX file for all addresses less than 0x1b40 using
+   VENDOR_REQUEST_ANCHOR_LOAD
+ - release the reset
+ - device renumerated itself and comes up as new device id with all
+   firmware download completed.
+*/
+static int whiteheat_firmware_download (struct usb_serial *serial)
+{
+	int response;
+	const struct whiteheat_hex_record *record;
+	
+	dbg("%s", __FUNCTION__);
+	
+	response = ezusb_set_reset (serial, 1);
+
+	record = &whiteheat_loader[0];
+	while (record->address != 0xffff) {
+		response = ezusb_writememory (serial, record->address, 
+				(unsigned char *)record->data, record->data_size, 0xa0);
+		if (response < 0) {
+			err("%s - ezusb_writememory failed for loader (%d %04X %p %d)",
+				__FUNCTION__, response, record->address, record->data, record->data_size);
+			break;
+		}
+		++record;
+	}
+
+	response = ezusb_set_reset (serial, 0);
+
+	record = &whiteheat_firmware[0];
+	while (record->address < 0x1b40) {
+		++record;
+	}
+	while (record->address != 0xffff) {
+		response = ezusb_writememory (serial, record->address, 
+				(unsigned char *)record->data, record->data_size, 0xa3);
+		if (response < 0) {
+			err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", 
+				__FUNCTION__, response, record->address, record->data, record->data_size);
+			break;
+		}
+		++record;
+	}
+	
+	response = ezusb_set_reset (serial, 1);
+
+	record = &whiteheat_firmware[0];
+	while (record->address < 0x1b40) {
+		response = ezusb_writememory (serial, record->address, 
+				(unsigned char *)record->data, record->data_size, 0xa0);
+		if (response < 0) {
+			err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", 
+				__FUNCTION__, response, record->address, record->data, record->data_size);
+			break;
+		}
+		++record;
+	}
+
+	response = ezusb_set_reset (serial, 0);
+
+	return 0;
+}
+
+
+static int whiteheat_firmware_attach (struct usb_serial *serial)
+{
+	/* We want this device to fail to have a driver assigned to it */
+	return 1;
+}
+
 
 /*****************************************************************************
- * Connect Tech's White Heat specific driver functions
+ * Connect Tech's White Heat serial driver functions
+ *****************************************************************************/
+static int whiteheat_attach (struct usb_serial *serial)
+{
+	struct usb_serial_port *command_port;
+	struct whiteheat_command_private *command_info;
+	struct usb_serial_port *port;
+	struct whiteheat_private *info;
+	struct whiteheat_hw_info *hw_info;
+	int pipe;
+	int ret;
+	int alen;
+	__u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };
+	__u8 result[sizeof(*hw_info) + 1];
+	int i;
+
+	command_port = &serial->port[COMMAND_PORT];
+
+	pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress);
+	ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, COMMAND_TIMEOUT);
+	if (ret) {
+		err("%s: Couldn't send command [%d]", serial->type->name, ret);
+		goto no_firmware;
+	} else if (alen != sizeof(command)) {
+		err("%s: Send command incomplete [%d]", serial->type->name, alen);
+		goto no_firmware;
+	}
+
+	pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress);
+	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, COMMAND_TIMEOUT);
+	if (ret) {
+		err("%s: Couldn't get results [%d]", serial->type->name, ret);
+		goto no_firmware;
+	} else if (alen != sizeof(result)) {
+		err("%s: Get results incomplete [%d]", serial->type->name, alen);
+		goto no_firmware;
+	} else if (result[0] != command[0]) {
+		err("%s: Command failed [%d]", serial->type->name, result[0]);
+		goto no_firmware;
+	}
+
+	hw_info = (struct whiteheat_hw_info *)&result[1];
+
+	info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
+	     DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+
+	for (i = 0; i < serial->num_ports; i++) {
+		port = &serial->port[i];
+
+		info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
+		if (info == NULL)
+			goto no_memory;
+
+		spin_lock_init(&info->lock);
+		info->flags = 0;
+		info->mcr = 0;
+		port->private = info;
+	}
+
+	command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
+	if (command_info == NULL)
+		goto no_memory;
+
+	spin_lock_init(&command_info->lock);
+	command_info->port_running = 0;
+	init_waitqueue_head(&command_info->wait_command);
+	command_port->private = command_info;
+	command_port->write_urb->complete = command_port_write_callback;
+	command_port->read_urb->complete = command_port_read_callback;
+
+	return 0;
+
+no_firmware:
+	/* Firmware likely not running */
+	err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
+	err("%s: If the firmware is not running (status led not blinking)\n", serial->type->name);
+	err("%s: please contact support@connecttech.com\n", serial->type->name);
+	return -ENODEV;
+
+no_memory:
+	for (i--; i >= 0; i--) {
+		port = &serial->port[i];
+		kfree(port->private);
+	}
+	err("%s: Out of memory for port structures\n", serial->type->name);
+	return -ENOMEM;
+}
+
+
+static void whiteheat_shutdown (struct usb_serial *serial)
+{
+	struct usb_serial_port *command_port;
+	struct usb_serial_port *port;
+	int i;
+
+	dbg("%s", __FUNCTION__);
+
+	/* free up our private data for our command port */
+	command_port = &serial->port[COMMAND_PORT];
+	kfree (command_port->private);
+	command_port->private = NULL;
+
+	for (i = 0; i < serial->num_ports; i++) {
+		port = &serial->port[i];
+		kfree(port->private);
+		port->private = NULL;
+	}
+
+	return;
+}
+
+
+static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
+{
+	int		retval = 0;
+	struct termios	old_term;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	retval = start_command_port(port->serial);
+	if (retval)
+		goto exit;
+
+	/* Start reading from the device */
+	port->read_urb->dev = port->serial->dev;
+	retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
+	if (retval) {
+		err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
+		stop_command_port(port->serial);
+		goto exit;
+	}
+
+	/* send an open port command */
+	retval = firm_open(port);
+	if (retval) {
+		stop_command_port(port->serial);
+		goto exit;
+	}
+
+	retval = firm_purge(port, WHITEHEAT_PURGE_RX | WHITEHEAT_PURGE_TX);
+	if (retval) {
+		firm_close(port);
+		stop_command_port(port->serial);
+		goto exit;
+	}
+
+	old_term.c_cflag = ~port->tty->termios->c_cflag;
+	old_term.c_iflag = ~port->tty->termios->c_iflag;
+	whiteheat_set_termios(port, &old_term);
+
+	retval = firm_set_rts(port, WHITEHEAT_RTS_ON);
+	if (retval) {
+		firm_close(port);
+		stop_command_port(port->serial);
+		goto exit;
+	}
+	retval = firm_set_dtr(port, WHITEHEAT_DTR_ON);
+	if (retval) {
+		firm_set_rts(port, WHITEHEAT_RTS_OFF);
+		firm_close(port);
+		stop_command_port(port->serial);
+		goto exit;
+	}
+
+exit:
+	dbg("%s - exit, retval = %d", __FUNCTION__, retval);
+	return retval;
+}
+
+
+static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
+{
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	
+	if (tty_hung_up_p(filp)) {
+		return;
+	}
+
+	port->tty->closing = 1;
+
+/*
+ * Not currently in use; tty_wait_until_sent() calls
+ * serial_chars_in_buffer() which deadlocks on the second semaphore
+ * acquisition. This should be fixed at some point. Greg's been
+ * notified.
+	if ((filp->f_flags & (O_NDELAY | O_NONBLOCK)) == 0) {
+		tty_wait_until_sent(port->tty, CLOSING_DELAY);
+	}
+*/
+
+	if (port->tty->driver.flush_buffer)
+		port->tty->driver.flush_buffer(port->tty);
+	if (port->tty->ldisc.flush_buffer)
+		port->tty->ldisc.flush_buffer(port->tty);
+
+	firm_report_tx_done(port);
+
+	firm_set_dtr(port, WHITEHEAT_DTR_OFF);
+	firm_set_rts(port, WHITEHEAT_RTS_OFF);
+
+	firm_close(port);
+
+	/* shutdown our bulk reads and writes */
+	usb_unlink_urb (port->write_urb);
+	usb_unlink_urb (port->read_urb);
+
+	stop_command_port(port->serial);
+
+	port->tty->closing = 0;
+}
+
+
+static int whiteheat_write(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+{
+	struct usb_serial *serial = port->serial;
+	int result;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (count == 0) {
+		dbg("%s - write request of 0 bytes", __FUNCTION__);
+		return (0);
+	}
+
+	if (port->write_urb->status == -EINPROGRESS) {
+		dbg ("%s - already writing", __FUNCTION__);
+		return (0);
+	}
+
+	count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
+
+	if (from_user) {
+		if (copy_from_user(port->write_urb->transfer_buffer, buf, count))
+			return -EFAULT;
+	}
+	else {
+		memcpy (port->write_urb->transfer_buffer, buf, count);
+	}
+
+	usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
+
+	port->write_urb->dev = serial->dev;
+	port->write_urb->transfer_buffer_length = count;
+	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+	if (result)
+		err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
+	else
+		result = count;
+
+	return result;
+}
+
+
+static int whiteheat_write_room(struct usb_serial_port *port)
+{
+	int room = 0;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	
+	if (port->write_urb->status != -EINPROGRESS)
+		room = port->bulk_out_size;
+
+	dbg("%s - returns %d", __FUNCTION__, room);
+	return (room);
+}
+
+
+static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+{
+	struct whiteheat_private *info = (struct whiteheat_private *)port->private;
+	unsigned int modem_signals = 0;
+	struct serial_struct serstruct;
+
+	dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
+
+	switch (cmd) {
+		case TIOCMGET:
+			firm_get_dtr_rts(port);
+			if (info->mcr & UART_MCR_DTR)
+				modem_signals |= TIOCM_DTR;
+			if (info->mcr & UART_MCR_RTS)
+				modem_signals |= TIOCM_RTS;
+			
+			if (copy_to_user((unsigned int *)arg, &modem_signals, sizeof(unsigned int)));
+				return -EFAULT;
+
+			break;
+
+		case TIOCMSET:
+			if (copy_from_user(&modem_signals, (unsigned int *)arg, sizeof(unsigned int)))
+				return -EFAULT;
+
+			if (modem_signals & TIOCM_DTR)
+				info->mcr |= UART_MCR_DTR;
+			else
+				info->mcr &= ~UART_MCR_DTR;
+			if (modem_signals & TIOCM_RTS)
+				info->mcr |= UART_MCR_RTS;
+			else
+				info->mcr &= ~UART_MCR_RTS;
+
+			firm_set_dtr(port, info->mcr & UART_MCR_DTR);
+			firm_set_rts(port, info->mcr & UART_MCR_RTS);
+
+			break;
+
+		case TIOCMBIS:
+			if (copy_from_user(&modem_signals, (unsigned int *)arg, sizeof(unsigned int)))
+				return -EFAULT;
+
+			if (modem_signals & TIOCM_DTR)
+				info->mcr |= UART_MCR_DTR;
+			if (modem_signals & TIOCM_RTS)
+				info->mcr |= UART_MCR_RTS;
+
+			firm_set_dtr(port, info->mcr & UART_MCR_DTR);
+			firm_set_rts(port, info->mcr & UART_MCR_RTS);
+
+			break;
+
+		case TIOCMBIC:
+			if (copy_from_user(&modem_signals, (unsigned int *)arg, sizeof(unsigned int)))
+				return -EFAULT;
+
+			if (modem_signals & TIOCM_DTR)
+				info->mcr &= ~UART_MCR_DTR;
+			if (modem_signals & TIOCM_RTS)
+				info->mcr &= ~UART_MCR_RTS;
+
+			firm_set_dtr(port, info->mcr & UART_MCR_DTR);
+			firm_set_rts(port, info->mcr & UART_MCR_RTS);
+
+			break;
+
+		case TIOCGSERIAL:
+			memset(&serstruct, 0, sizeof(serstruct));
+			serstruct.type = PORT_16654;
+			serstruct.line = port->serial->minor;
+			serstruct.port = port->number;
+			serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+			serstruct.xmit_fifo_size = port->bulk_out_size;
+			serstruct.custom_divisor = 0;
+			serstruct.baud_base = 460800;
+			serstruct.close_delay = CLOSING_DELAY;
+			serstruct.closing_wait = CLOSING_DELAY;
+
+			if (copy_to_user((void *)arg, &serstruct, sizeof(serstruct)))
+				return -EFAULT;
+
+			break;
+
+		case TIOCSSERIAL:
+			if (copy_from_user(&serstruct, (void *)arg, sizeof(serstruct)))
+				return -EFAULT;
+
+			/*
+			 * For now this is ignored. dip sets the ASYNC_[V]HI flags
+			 * but this isn't used by us at all. Maybe someone somewhere
+			 * will need the custom_divisor setting.
+			 */
+
+			break;
+
+		default:
+			return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
+
+static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+{
+	dbg("%s -port %d", __FUNCTION__, port->number);
+
+	if ((!port->tty) || (!port->tty->termios)) {
+		dbg("%s - no tty structures", __FUNCTION__);
+		goto exit;
+	}
+	
+	/* check that they really want us to change something */
+	if (old_termios) {
+		if ((port->tty->termios->c_cflag == old_termios->c_cflag) &&
+		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
+			dbg("%s - nothing to change...", __FUNCTION__);
+			goto exit;
+		}
+	}
+
+	firm_setup_port(port);
+
+exit:
+	return;
+}
+
+
+static void whiteheat_break_ctl(struct usb_serial_port *port, int break_state) {
+	firm_set_break(port, break_state);
+}
+
+
+static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
+{
+	int chars = 0;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (port->write_urb->status == -EINPROGRESS)
+		chars = port->write_urb->transfer_buffer_length;
+
+	dbg ("%s - returns %d", __FUNCTION__, chars);
+	return (chars);
+}
+
+
+static void whiteheat_throttle (struct usb_serial_port *port)
+{
+	struct whiteheat_private *info = (struct whiteheat_private *)port->private;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	spin_lock_irqsave(&info->lock, flags);
+	info->flags |= THROTTLED;
+	spin_unlock_irqrestore(&info->lock, flags);
+
+	return;
+}
+
+
+static void whiteheat_unthrottle (struct usb_serial_port *port)
+{
+	struct whiteheat_private *info = (struct whiteheat_private *)port->private;
+	int result;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	spin_lock_irqsave(&info->lock, flags);
+
+	if (info->flags & ACTUALLY_THROTTLED) {
+		/* Continue trying to always read  */
+		port->read_urb->dev = port->serial->dev;
+		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+		if (result)
+			err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
+	}
+
+	info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
+
+	spin_unlock_irqrestore(&info->lock, flags);
+
+	return;
+}
+
+
+/*****************************************************************************
+ * Connect Tech's White Heat callback routines
  *****************************************************************************/
 static void command_port_write_callback (struct urb *urb)
 {
@@ -201,11 +791,12 @@
 
 static void command_port_read_callback (struct urb *urb)
 {
-	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
-	struct whiteheat_private *info;
+	struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial = get_usb_serial (command_port, __FUNCTION__);
+	struct whiteheat_command_private *command_info;
 	unsigned char *data = urb->transfer_buffer;
 	int result;
+	unsigned long flags;
 
 	dbg("%s", __FUNCTION__);
 
@@ -221,55 +812,146 @@
 	
 	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
-	info = (struct whiteheat_private *)port->private;
-	if (!info) {
-		dbg("%s - info is NULL, exiting.", __FUNCTION__);
+	command_info = (struct whiteheat_command_private *)command_port->private;
+	if (!command_info) {
+		dbg ("%s - command_info is NULL, exiting.", __FUNCTION__);
 		return;
 	}
+	spin_lock_irqsave(&command_info->lock, flags);
 
-	/* right now, if the command is COMMAND_COMPLETE, just flip the bit saying the command finished */
-	/* in the future we're going to have to pay attention to the actual command that completed */
 	if (data[0] == WHITEHEAT_CMD_COMPLETE) {
-		info->command_finished = WHITEHEAT_CMD_COMPLETE;
-		wake_up_interruptible(&info->wait_command);
-	}
-	
-	if (data[0] == WHITEHEAT_CMD_FAILURE) {
-		info->command_finished = WHITEHEAT_CMD_FAILURE;
-		wake_up_interruptible(&info->wait_command);
+		command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
+		wake_up_interruptible(&command_info->wait_command);
+	} else if (data[0] == WHITEHEAT_CMD_FAILURE) {
+		command_info->command_finished = WHITEHEAT_CMD_FAILURE;
+		wake_up_interruptible(&command_info->wait_command);
+	} else if (data[0] == WHITEHEAT_EVENT) {
+		/* These are unsolicited reports from the firmware, hence no waiting command to wakeup */
+		dbg("%s - event received", __FUNCTION__);
+	} else if (data[0] == WHITEHEAT_GET_DTR_RTS) {
+		memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1);
+		command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
+		wake_up_interruptible(&command_info->wait_command);
+	} else {
+		dbg("%s - bad reply from firmware", __FUNCTION__);
 	}
 	
 	/* Continue trying to always read */
-	FILL_BULK_URB(port->read_urb, serial->dev, 
-		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-		      command_port_read_callback, port);
-	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+	command_port->read_urb->dev = serial->dev;
+	result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);
+	spin_unlock_irqrestore(&command_info->lock, flags);
 	if (result)
 		dbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
 }
 
 
-static int whiteheat_send_cmd (struct usb_serial *serial, __u8 command, __u8 *data, __u8 datasize)
+static void whiteheat_read_callback(struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+	struct tty_struct *tty;
+	unsigned char *data = urb->transfer_buffer;
+	int i;
+	int result;
+	struct whiteheat_private *info = (struct whiteheat_private *)port->private;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (!serial) {
+		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
+		return;
+	}
+
+	if (urb->status) {
+		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+		return;
+	}
+
+	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+
+	tty = port->tty;
+	if (tty && urb->actual_length) {
+		for (i = 0; i < urb->actual_length ; ++i) {
+			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				tty_flip_buffer_push(tty);
+			}
+			/* this doesn't actually push the data through unless tty->low_latency is set */
+			tty_insert_flip_char(tty, data[i], 0);
+		}
+	  	tty_flip_buffer_push(tty);
+	}
+
+	spin_lock_irqsave(&info->lock, flags);
+	if (info->flags & THROTTLED) {
+		info->flags |= ACTUALLY_THROTTLED;
+		spin_unlock_irqrestore(&info->lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(&info->lock, flags);
+
+	/* Continue trying to always read  */
+	port->read_urb->dev = serial->dev;
+	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+	if (result)
+		err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
+}
+
+
+static void whiteheat_write_callback(struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (!serial) {
+		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
+		return;
+	}
+
+	if (urb->status) {
+		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+		return;
+	}
+
+	usb_serial_port_softint((void *)port);
+
+	queue_task(&port->tqueue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+
+	return;
+}
+
+
+/*****************************************************************************
+ * Connect Tech's White Heat firmware interface
+ *****************************************************************************/
+static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize)
 {
+	struct usb_serial_port *command_port;
+	struct whiteheat_command_private *command_info;
 	struct whiteheat_private *info;
-	struct usb_serial_port *port;
 	int timeout;
 	__u8 *transfer_buffer;
 	int retval = 0;
+	unsigned long flags;
 
 	dbg("%s - command %d", __FUNCTION__, command);
 
-	port = &serial->port[COMMAND_PORT];
-	info = (struct whiteheat_private *)port->private;
-	info->command_finished = FALSE;
+	command_port = &port->serial->port[COMMAND_PORT];
+	command_info = (struct whiteheat_command_private *)command_port->private;
+	spin_lock_irqsave(&command_info->lock, flags);
+	command_info->command_finished = FALSE;
 	
-	transfer_buffer = (__u8 *)port->write_urb->transfer_buffer;
+	transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer;
 	transfer_buffer[0] = command;
 	memcpy (&transfer_buffer[1], data, datasize);
-	port->write_urb->transfer_buffer_length = datasize + 1;
-	port->write_urb->dev = serial->dev;
-	retval = usb_submit_urb (port->write_urb, GFP_KERNEL);
+	command_port->write_urb->transfer_buffer_length = datasize + 1;
+	command_port->write_urb->dev = port->serial->dev;
+	retval = usb_submit_urb (command_port->write_urb, GFP_KERNEL);
+	spin_unlock_irqrestore(&command_info->lock, flags);
 	if (retval) {
 		dbg("%s - submit urb failed", __FUNCTION__);
 		goto exit;
@@ -277,138 +959,60 @@
 
 	/* wait for the command to complete */
 	timeout = COMMAND_TIMEOUT;
-	while (timeout && (info->command_finished == FALSE)) {
-		timeout = interruptible_sleep_on_timeout (&info->wait_command, timeout);
+	while (timeout && (command_info->command_finished == FALSE)) {
+		timeout = interruptible_sleep_on_timeout (&command_info->wait_command, timeout);
 	}
 
-	if (info->command_finished == FALSE) {
+	spin_lock_irqsave(&command_info->lock, flags);
+
+	if (command_info->command_finished == FALSE) {
 		dbg("%s - command timed out.", __FUNCTION__);
 		retval = -ETIMEDOUT;
 		goto exit;
 	}
 
-	if (info->command_finished == WHITEHEAT_CMD_FAILURE) {
+	if (command_info->command_finished == WHITEHEAT_CMD_FAILURE) {
 		dbg("%s - command failed.", __FUNCTION__);
 		retval = -EIO;
 		goto exit;
 	}
 
-	if (info->command_finished == WHITEHEAT_CMD_COMPLETE)
+	if (command_info->command_finished == WHITEHEAT_CMD_COMPLETE) {
 		dbg("%s - command completed.", __FUNCTION__);
-
-exit:
-	return retval;
-}
-
-
-static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
-{
-	struct whiteheat_min_set	open_command;
-	struct usb_serial_port 		*command_port;
-	struct whiteheat_private	*info;
-	int				retval = 0;
-
-	dbg("%s - port %d", __FUNCTION__, port->number);
-
-	/* set up some stuff for our command port */
-	command_port = &port->serial->port[COMMAND_PORT];
-	if (command_port->private == NULL) {
-		info = (struct whiteheat_private *)kmalloc (sizeof(struct whiteheat_private), GFP_KERNEL);
-		if (info == NULL) {
-			err("%s - out of memory", __FUNCTION__);
-			retval = -ENOMEM;
-			goto exit;
-		}
-		
-		init_waitqueue_head(&info->wait_command);
-		command_port->private = info;
-		command_port->write_urb->complete = command_port_write_callback;
-		command_port->read_urb->complete = command_port_read_callback;
-		command_port->read_urb->dev = port->serial->dev;
-		command_port->tty = port->tty;		/* need this to "fake" our our sanity check macros */
-		retval = usb_submit_urb (command_port->read_urb, GFP_KERNEL);
-		if (retval) {
-			err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
-			goto exit;
+		switch (command) {
+			case WHITEHEAT_GET_DTR_RTS:
+				info = (struct whiteheat_private *)port->private;
+				memcpy(&info->mcr, command_info->result_buffer, sizeof(struct whiteheat_dr_info));
+				break;
 		}
 	}
-	
-	/* Start reading from the device */
-	port->read_urb->dev = port->serial->dev;
-	retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
-	if (retval) {
-		err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
-		goto exit;
-	}
-
-	/* send an open port command */
-	/* firmware uses 1 based port numbering */
-	open_command.port = port->number - port->serial->minor + 1;
-	retval = whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
-	if (retval)
-		goto exit;
-
-	/* Need to do device specific setup here (control lines, baud rate, etc.) */
-	/* FIXME!!! */
 
 exit:
-	dbg("%s - exit, retval = %d", __FUNCTION__, retval);
+	spin_unlock_irqrestore(&command_info->lock, flags);
 	return retval;
 }
 
 
-static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
-{
-	struct whiteheat_min_set	close_command;
-	
-	dbg("%s - port %d", __FUNCTION__, port->number);
-	
-	/* send a close command to the port */
-	/* firmware uses 1 based port numbering */
-	close_command.port = port->number - port->serial->minor + 1;
-	whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
+static int firm_open(struct usb_serial_port *port) {
+	struct whiteheat_simple open_command;
 
-	/* Need to change the control lines here */
-	/* FIXME */
-	
-	/* shutdown our bulk reads and writes */
-	usb_unlink_urb (port->write_urb);
-	usb_unlink_urb (port->read_urb);
+	open_command.port = port->number - port->serial->minor + 1;
+	return firm_send_command(port, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
 }
 
 
-static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
-{
-	dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
+static int firm_close(struct usb_serial_port *port) {
+	struct whiteheat_simple close_command;
 
-	return -ENOIOCTLCMD;
+	close_command.port = port->number - port->serial->minor + 1;
+	return firm_send_command(port, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
 }
 
 
-static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios)
-{
-	unsigned int cflag;
+static int firm_setup_port(struct usb_serial_port *port) {
 	struct whiteheat_port_settings port_settings;
+	unsigned int cflag = port->tty->termios->c_cflag;
 
-	dbg("%s -port %d", __FUNCTION__, port->number);
-
-	if ((!port->tty) || (!port->tty->termios)) {
-		dbg("%s - no tty structures", __FUNCTION__);
-		goto exit;
-	}
-	
-	cflag = port->tty->termios->c_cflag;
-	/* check that they really want us to change something */
-	if (old_termios) {
-		if ((cflag == old_termios->c_cflag) &&
-		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
-			dbg("%s - nothing to change...", __FUNCTION__);
-			goto exit;
-		}
-	}
-
-	/* set the port number */
-	/* firmware uses 1 based port numbering */
 	port_settings.port = port->number + 1;
 
 	/* get the byte size */
@@ -423,12 +1027,18 @@
 	
 	/* determine the parity */
 	if (cflag & PARENB)
-		if (cflag & PARODD)
-			port_settings.parity = 'o';
+		if (cflag & CMSPAR)
+			if (cflag & PARODD)
+				port_settings.parity = WHITEHEAT_PAR_MARK;
+			else
+				port_settings.parity = WHITEHEAT_PAR_SPACE;
 		else
-			port_settings.parity = 'e';
+			if (cflag & PARODD)
+				port_settings.parity = WHITEHEAT_PAR_ODD;
+			else
+				port_settings.parity = WHITEHEAT_PAR_EVEN;
 	else
-		port_settings.parity = 'n';
+		port_settings.parity = WHITEHEAT_PAR_NONE;
 	dbg("%s - parity = %c", __FUNCTION__, port_settings.parity);
 
 	/* figure out the stop bits requested */
@@ -438,23 +1048,22 @@
 		port_settings.stop = 1;
 	dbg("%s - stop bits = %d", __FUNCTION__, port_settings.stop);
 
-	
 	/* figure out the flow control settings */
 	if (cflag & CRTSCTS)
-		port_settings.hflow = (WHITEHEAT_CTS_FLOW | WHITEHEAT_RTS_FLOW);
+		port_settings.hflow = (WHITEHEAT_HFLOW_CTS | WHITEHEAT_HFLOW_RTS);
 	else
-		port_settings.hflow = 0;
+		port_settings.hflow = WHITEHEAT_HFLOW_NONE;
 	dbg("%s - hardware flow control = %s %s %s %s", __FUNCTION__,
-	    (port_settings.hflow & WHITEHEAT_CTS_FLOW) ? "CTS" : "",
-	    (port_settings.hflow & WHITEHEAT_RTS_FLOW) ? "RTS" : "",
-	    (port_settings.hflow & WHITEHEAT_DSR_FLOW) ? "DSR" : "",
-	    (port_settings.hflow & WHITEHEAT_DTR_FLOW) ? "DTR" : "");
+	    (port_settings.hflow & WHITEHEAT_HFLOW_CTS) ? "CTS" : "",
+	    (port_settings.hflow & WHITEHEAT_HFLOW_RTS) ? "RTS" : "",
+	    (port_settings.hflow & WHITEHEAT_HFLOW_DSR) ? "DSR" : "",
+	    (port_settings.hflow & WHITEHEAT_HFLOW_DTR) ? "DTR" : "");
 	
 	/* determine software flow control */
 	if (I_IXOFF(port->tty))
-		port_settings.sflow = 'b';
+		port_settings.sflow = WHITEHEAT_SFLOW_RXTX;
 	else
-		port_settings.sflow = 'n';
+		port_settings.sflow = WHITEHEAT_SFLOW_NONE;
 	dbg("%s - software flow control = %c", __FUNCTION__, port_settings.sflow);
 	
 	port_settings.xon = START_CHAR(port->tty);
@@ -469,214 +1078,110 @@
 	port_settings.lloop = 0;
 	
 	/* now send the message to the device */
-	whiteheat_send_cmd (port->serial, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
-	
-exit:
-	return;
+	return firm_send_command(port, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
 }
 
 
-static void whiteheat_throttle (struct usb_serial_port *port)
-{
-	dbg("%s - port %d", __FUNCTION__, port->number);
-
-	/* Change the control signals */
-	/* FIXME!!! */
+static int firm_set_rts(struct usb_serial_port *port, __u8 onoff) {
+	struct whiteheat_set_rdb rts_command;
 
-	return;
+	rts_command.port = port->number - port->serial->minor + 1;
+	rts_command.state = onoff;
+	return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&rts_command, sizeof(rts_command));
 }
 
 
-static void whiteheat_unthrottle (struct usb_serial_port *port)
-{
-	dbg("%s - port %d", __FUNCTION__, port->number);
-
-	/* Change the control signals */
-	/* FIXME!!! */
+static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff) {
+	struct whiteheat_set_rdb dtr_command;
 
-	return;
+	dtr_command.port = port->number - port->serial->minor + 1;
+	dtr_command.state = onoff;
+	return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&dtr_command, sizeof(dtr_command));
 }
 
 
-/* steps to download the firmware to the WhiteHEAT device:
- - hold the reset (by writing to the reset bit of the CPUCS register)
- - download the VEND_AX.HEX file to the chip using VENDOR_REQUEST-ANCHOR_LOAD
- - release the reset (by writing to the CPUCS register)
- - download the WH.HEX file for all addresses greater than 0x1b3f using
-   VENDOR_REQUEST-ANCHOR_EXTERNAL_RAM_LOAD
- - hold the reset
- - download the WH.HEX file for all addresses less than 0x1b40 using
-   VENDOR_REQUEST_ANCHOR_LOAD
- - release the reset
- - device renumerated itself and comes up as new device id with all
-   firmware download completed.
-*/
-static int whiteheat_firmware_download (struct usb_serial *serial)
-{
-	int response;
-	const struct whiteheat_hex_record *record;
-	
-	dbg("%s", __FUNCTION__);
-	
-	response = ezusb_set_reset (serial, 1);
-
-	record = &whiteheat_loader[0];
-	while (record->address != 0xffff) {
-		response = ezusb_writememory (serial, record->address, 
-				(unsigned char *)record->data, record->data_size, 0xa0);
-		if (response < 0) {
-			err("%s - ezusb_writememory failed for loader (%d %04X %p %d)",
-				__FUNCTION__, response, record->address, record->data, record->data_size);
-			break;
-		}
-		++record;
-	}
-
-	response = ezusb_set_reset (serial, 0);
+static int firm_set_break(struct usb_serial_port *port, __u8 onoff) {
+	struct whiteheat_set_rdb break_command;
 
-	record = &whiteheat_firmware[0];
-	while (record->address < 0x1b40) {
-		++record;
-	}
-	while (record->address != 0xffff) {
-		response = ezusb_writememory (serial, record->address, 
-				(unsigned char *)record->data, record->data_size, 0xa3);
-		if (response < 0) {
-			err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", 
-				__FUNCTION__, response, record->address, record->data, record->data_size);
-			break;
-		}
-		++record;
-	}
-	
-	response = ezusb_set_reset (serial, 1);
-
-	record = &whiteheat_firmware[0];
-	while (record->address < 0x1b40) {
-		response = ezusb_writememory (serial, record->address, 
-				(unsigned char *)record->data, record->data_size, 0xa0);
-		if (response < 0) {
-			err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", 
-				__FUNCTION__, response, record->address, record->data, record->data_size);
-			break;
-		}
-		++record;
-	}
-
-	response = ezusb_set_reset (serial, 0);
-
-	/* we want this device to fail to have a driver assigned to it. */
-	return 1;
+	break_command.port = port->number - port->serial->minor + 1;
+	break_command.state = onoff;
+	return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&break_command, sizeof(break_command));
 }
 
 
-static int whiteheat_attach (struct usb_serial *serial)
-{
-	struct whiteheat_hw_info *hw_info;
-	int pipe;
-	int ret;
-	int alen;
-	__u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };
-	__u8 result[sizeof(*hw_info) + 1];
-
-	pipe = usb_rcvbulkpipe (serial->dev, 7);
-	usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
-	/*
-	 * We ignore the return code. In the case where rmmod/insmod is
-	 * performed with a WhiteHEAT connected, the above times out
-	 * because the endpoint is already prepped, meaning the below succeeds
-	 * regardless. All other cases the above succeeds.
-	 */
-
-	pipe = usb_sndbulkpipe (serial->dev, 7);
-	ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, 2 * HZ);
-	if (ret) {
-		err("%s: Couldn't send command [%d]", serial->type->name, ret);
-		goto error_out;
-	} else if (alen != sizeof(command)) {
-		err("%s: Send command incomplete [%d]", serial->type->name, alen);
-		goto error_out;
-	}
+static int firm_purge(struct usb_serial_port *port, __u8 rxtx) {
+	struct whiteheat_purge purge_command;
 
-	pipe = usb_rcvbulkpipe (serial->dev, 7);
-	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
-	if (ret) {
-		err("%s: Couldn't get results [%d]", serial->type->name, ret);
-		goto error_out;
-	} else if (alen != sizeof(result)) {
-		err("%s: Get results incomplete [%d]", serial->type->name, alen);
-		goto error_out;
-	} else if (result[0] != command[0]) {
-		err("%s: Command failed [%d]", serial->type->name, result[0]);
-		goto error_out;
-	}
+	purge_command.port = port->number - port->serial->minor + 1;
+	purge_command.what = rxtx;
+	return firm_send_command(port, WHITEHEAT_PURGE, (__u8 *)&purge_command, sizeof(purge_command));
+}
 
-	hw_info = (struct whiteheat_hw_info *)&result[1];
 
-	info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
-	     DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+static int firm_get_dtr_rts(struct usb_serial_port *port) {
+	struct whiteheat_simple get_dr_command;
 
-	return 0;
-
-error_out:
-	err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
-	/*
-	 * Return that we've claimed the interface. A failure here may be
-	 * due to interception by the command_callback routine or other
-	 * causes that don't mean that the firmware isn't running. This may
-	 * change in the future. Probably should actually.
-	 */
-	return 0;
+	get_dr_command.port = port->number - port->serial->minor + 1;
+	return firm_send_command(port, WHITEHEAT_GET_DTR_RTS, (__u8 *)&get_dr_command, sizeof(get_dr_command));
 }
 
-static void whiteheat_shutdown (struct usb_serial *serial)
-{
-	struct usb_serial_port *command_port;
 
-	dbg("%s", __FUNCTION__);
+static int firm_report_tx_done(struct usb_serial_port *port) {
+	struct whiteheat_simple close_command;
 
-	/* free up our private data for our command port */
-	command_port = &serial->port[COMMAND_PORT];
-	if (command_port->private != NULL) {
-		kfree (command_port->private);
-		command_port->private = NULL;
-	}
-
-	return;
+	close_command.port = port->number - port->serial->minor + 1;
+	return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE, (__u8 *)&close_command, sizeof(close_command));
 }
 
 
-static void set_command (struct usb_serial_port *port, unsigned char state, unsigned char command)
+/*****************************************************************************
+ * Connect Tech's White Heat utility functions
+ *****************************************************************************/
+static int start_command_port(struct usb_serial *serial)
 {
-	struct whiteheat_rdb_set rdb_command;
+	struct usb_serial_port *command_port;
+	struct whiteheat_command_private *command_info;
+	unsigned long flags;
+	int retval = 0;
 	
-	/* send a set rts command to the port */
-	/* firmware uses 1 based port numbering */
-	rdb_command.port = port->number - port->serial->minor + 1;
-	rdb_command.state = state;
-
-	whiteheat_send_cmd (port->serial, command, (__u8 *)&rdb_command, sizeof(rdb_command));
-}
-
+	command_port = &serial->port[COMMAND_PORT];
+	command_info = (struct whiteheat_command_private *)command_port->private;
+	spin_lock_irqsave(&command_info->lock, flags);
+	if (!command_info->port_running) {
+		command_port->read_urb->dev = serial->dev;
+		retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL);
+		if (retval) {
+			err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
+			goto exit;
+		}
+	}
+	command_info->port_running++;
 
-static inline void set_rts (struct usb_serial_port *port, unsigned char rts)
-{
-	set_command (port, rts, WHITEHEAT_SET_RTS);
+exit:
+	spin_unlock_irqrestore(&command_info->lock, flags);
+	return retval;
 }
 
 
-static inline void set_dtr (struct usb_serial_port *port, unsigned char dtr)
+static void stop_command_port(struct usb_serial *serial)
 {
-	set_command (port, dtr, WHITEHEAT_SET_DTR);
-}
-
+	struct usb_serial_port *command_port;
+	struct whiteheat_command_private *command_info;
+	unsigned long flags;
 
-static inline void set_break (struct usb_serial_port *port, unsigned char brk)
-{
-	set_command (port, brk, WHITEHEAT_SET_BREAK);
+	command_port = &serial->port[COMMAND_PORT];
+	command_info = (struct whiteheat_command_private *)command_port->private;
+	spin_lock_irqsave(&command_info->lock, flags);
+	command_info->port_running--;
+	if (!command_info->port_running)
+		usb_unlink_urb(command_port->read_urb);
+	spin_unlock_irqrestore(&command_info->lock, flags);
 }
 
 
+/*****************************************************************************
+ * Connect Tech's White Heat module functions
+ *****************************************************************************/
 static int __init whiteheat_init (void)
 {
 	usb_serial_register (&whiteheat_fake_device);
@@ -704,4 +1209,3 @@
 
 MODULE_PARM(debug, "i");
 MODULE_PARM_DESC(debug, "Debug enabled or not");
-
diff -Nru a/drivers/usb/serial/whiteheat.h b/drivers/usb/serial/whiteheat.h
--- a/drivers/usb/serial/whiteheat.h	Fri Sep 27 14:51:02 2002
+++ b/drivers/usb/serial/whiteheat.h	Fri Sep 27 14:51:02 2002
@@ -1,6 +1,9 @@
 /*
  * USB ConnectTech WhiteHEAT driver
  *
+ *      Copyright (C) 2002
+ *          Connect Tech Inc.	
+ *
  *      Copyright (C) 1999, 2000
  *          Greg Kroah-Hartman (greg@kroah.com)
  *
@@ -17,8 +20,9 @@
 #define __LINUX_USB_SERIAL_WHITEHEAT_H
 
 
-#define FALSE				0
-#define TRUE				1
+#define FALSE	0
+#define TRUE	1
+
 
 /* WhiteHEAT commands */
 #define WHITEHEAT_OPEN			1	/* open the port */
@@ -39,109 +43,192 @@
 #define WHITEHEAT_CMD_COMPLETE		16	/* reply for certain commands */
 #define WHITEHEAT_CMD_FAILURE		17	/* reply for failed commands */
 
-/* Data for the WHITEHEAT_SETUP_PORT command */
-#define WHITEHEAT_CTS_FLOW		0x08
-#define WHITEHEAT_RTS_FLOW		0x80
-#define WHITEHEAT_DSR_FLOW		0x10
-#define WHITEHEAT_DTR_FLOW		0x02
+
+/*
+ * Commands to the firmware
+ */
+
+
+/*
+ * WHITEHEAT_OPEN
+ * WHITEHEAT_CLOSE
+ * WHITEHEAT_STATUS
+ * WHITEHEAT_GET_DTR_RTS
+ * WHITEHEAT_REPORT_TX_DONE
+*/
+struct whiteheat_simple {
+	__u8	port;	/* port number (1 to N) */
+};
+
+
+/*
+ * WHITEHEAT_SETUP_PORT
+ */
+#define WHITEHEAT_PAR_NONE	'n'	/* no parity */
+#define WHITEHEAT_PAR_EVEN	'e'	/* even parity */
+#define WHITEHEAT_PAR_ODD	'o'	/* odd parity */
+#define WHITEHEAT_PAR_SPACE	'0'	/* space (force 0) parity */
+#define WHITEHEAT_PAR_MARK	'1'	/* mark (force 1) parity */
+
+#define WHITEHEAT_SFLOW_NONE	'n'	/* no software flow control */
+#define WHITEHEAT_SFLOW_RX	'r'	/* XOFF/ON is sent when RX fills/empties */
+#define WHITEHEAT_SFLOW_TX	't'	/* when received XOFF/ON will stop/start TX */
+#define WHITEHEAT_SFLOW_RXTX	'b'	/* both SFLOW_RX and SFLOW_TX */
+
+#define WHITEHEAT_HFLOW_NONE		0x00	/* no hardware flow control */
+#define WHITEHEAT_HFLOW_RTS_TOGGLE	0x01	/* RTS is on during transmit, off otherwise */
+#define WHITEHEAT_HFLOW_DTR		0x02	/* DTR is off/on when RX fills/empties */
+#define WHITEHEAT_HFLOW_CTS		0x08	/* when received CTS off/on will stop/start TX */
+#define WHITEHEAT_HFLOW_DSR		0x10	/* when received DSR off/on will stop/start TX */
+#define WHITEHEAT_HFLOW_RTS		0x80	/* RTS is off/on when RX fills/empties */
+
 struct whiteheat_port_settings {
 	__u8	port;		/* port number (1 to N) */
-	__u32	baud;		/* any value allowed, default 9600, arrives little endian, range is 7 - 460800 */
-	__u8	bits;		/* 5, 6, 7, or 8, default 8 */
+	__u32	baud;		/* any value 7 - 460800, firmware calculates best fit; arrives little endian */
+	__u8	bits;		/* 5, 6, 7, or 8 */
 	__u8	stop;		/* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
-	__u8	parity;		/* 'n, e, o, 0, or 1' (ascii), default 'n'
-				 *	n = none	e = even	o = odd
-				 *	0 = force 0	1 = force 1	*/
-	__u8	sflow;		/* 'n, r, t, or b' (ascii), default 'n'
-				 *	n = none
-				 *	r = receive (XOFF/XON transmitted when receiver fills / empties)
-				 *	t = transmit (XOFF/XON received will stop/start TX)
-				 *	b = both 	*/
-	__u8	xoff;		/* XOFF byte value, default 0x13 */
-	__u8	xon;		/* XON byte value, default 0x11 */
-	__u8	hflow;		/* bits indicate mode as follows:
-				 *	CTS (0x08) (CTS off/on will control/cause TX off/on)
-				 *	DSR (0x10) (DSR off/on will control/cause TX off/on)
-				 *	RTS (0x80) (RTS off/on when receiver fills/empties)
-				 *	DTR (0x02) (DTR off/on when receiver fills/empties) */
-	__u8	lloop;		/* local loopback 0 or 1, default 0 */
+	__u8	parity;		/* see WHITEHEAT_PAR_* above */
+	__u8	sflow;		/* see WHITEHEAT_SFLOW_* above */
+	__u8	xoff;		/* XOFF byte value */
+	__u8	xon;		/* XON byte value */
+	__u8	hflow;		/* see WHITEHEAT_HFLOW_* above */
+	__u8	lloop;		/* 0/1 turns local loopback mode off/on */
 } __attribute__ ((packed));
 
-/* data for WHITEHEAT_SET_RTS, WHITEHEAT_SET_DTR, and WHITEHEAT_SET_BREAK commands */
-struct whiteheat_rdb_set {
+
+/*
+ * WHITEHEAT_SET_RTS
+ * WHITEHEAT_SET_DTR
+ * WHITEHEAT_SET_BREAK
+ */
+#define WHITEHEAT_RTS_OFF	0x00
+#define WHITEHEAT_RTS_ON	0x01
+#define WHITEHEAT_DTR_OFF	0x00
+#define WHITEHEAT_DTR_ON	0x01
+#define WHITEHEAT_BREAK_OFF	0x00
+#define WHITEHEAT_BREAK_ON	0x01
+
+struct whiteheat_set_rdb {
 	__u8	port;		/* port number (1 to N) */
-	__u8	state;		/* 0 = off, non-zero = on */
+	__u8	state;		/* 0/1 turns signal off/on */
 };
 
-/* data for:
-	WHITEHEAT_OPEN
-	WHITEHEAT_CLOSE
-	WHITEHEAT_STATUS
-	WHITEHEAT_GET_DTR_RTS
-	WHITEHEAT_REPORT_TX_DONE */
-struct whiteheat_min_set {
-	__u8	port;		/* port number (1 to N) */
+
+/*
+ * WHITEHEAT_DUMP
+ */
+#define WHITEHEAT_DUMP_MEM_DATA		'd'  /* data */
+#define WHITEHEAT_DUMP_MEM_IDATA	'i'  /* idata */
+#define WHITEHEAT_DUMP_MEM_BDATA	'b'  /* bdata */
+#define WHITEHEAT_DUMP_MEM_XDATA	'x'  /* xdata */
+
+/*
+ * Allowable address ranges (firmware checks address):
+ * Type DATA:  0x00 - 0xff
+ * Type IDATA: 0x80 - 0xff
+ * Type BDATA: 0x20 - 0x2f
+ * Type XDATA: 0x0000 - 0xffff
+ *
+ * B/I/DATA all read the local memory space
+ * XDATA reads the external memory space
+ * BDATA returns bits as bytes
+ *
+ * NOTE: 0x80 - 0xff (local space) are the Special Function Registers
+ *       of the 8051, and some have on-read side-effects.
+ */
+
+struct whiteheat_dump {
+	__u8	mem_type;	/* see WHITEHEAT_DUMP_* above */
+	__u16	addr;		/* address, see restrictions above */
+	__u16	length;		/* number of bytes to dump, max 63 bytes */
 };
 
-/* data for WHITEHEAT_PURGE command */
-#define WHITEHEAT_PURGE_INPUT		0x01
-#define WHITEHEAT_PURGE_OUTPUT		0x02
-struct whiteheat_purge_set {
+
+/*
+ * WHITEHEAT_PURGE
+ */
+#define WHITEHEAT_PURGE_RX	0x01	/* purge rx fifos */
+#define WHITEHEAT_PURGE_TX	0x02	/* purge tx fifos */
+
+struct whiteheat_purge {
 	__u8	port;		/* port number (1 to N) */
 	__u8	what;		/* bit pattern of what to purge */
 };
 
-/* data for WHITEHEAT_DUMP command */
-struct whiteheat_dump_info {
-	__u8	mem_type;	/* memory type: 'd' = data, 'i' = idata, 'b' = bdata, 'x' = xdata */
-	__u16	addr;		/* memory address to dump, address range depends on the above mem_type:
-				 *	'd' = 0 to ff (80 to FF is SFR's)
-				 *	'i' = 80 to ff
-				 *	'b' = 20 to 2f (bits returned as bytes)
-				 *	'x' = 0000 to ffff (also code space)	*/
-	__u16	length;		/* number of bytes to dump, max 64 */
-};
 
-/* data for WHITEHEAT_ECHO command */
-struct whiteheat_echo_set {
+/*
+ * WHITEHEAT_ECHO
+ */
+struct whiteheat_echo {
 	__u8	port;		/* port number (1 to N) */
-	__u8	length;		/* length of message to echo */
+	__u8	length;		/* length of message to echo, max 61 bytes */
 	__u8	echo_data[61];	/* data to echo */
 };
 
-/* data returned from WHITEHEAT_STATUS command */
-#define WHITEHEAT_OVERRUN_ERROR		0x02
-#define WHITEHEAT_PARITY_ERROR		0x04
-#define WHITEHEAT_FRAMING_ERROR		0x08
-#define WHITEHEAT_BREAK_ERROR		0x10
-
-#define WHITEHEAT_OHFLOW		0x01	/* TX is stopped by CTS (waiting for CTS to go ON) */
-#define WHITEHEAT_IHFLOW		0x02	/* remote TX is stopped by RTS */
-#define WHITEHEAT_OSFLOW		0x04	/* TX is stopped by XOFF received (waiting for XON to occur) */
-#define WHITEHEAT_ISFLOW		0x08	/* remote TX is stopped by XOFF transmitted */
-#define WHITEHEAT_TX_DONE		0x80	/* TX has completed */
-
-#define WHITEHEAT_MODEM_EVENT		0x01
-#define WHITEHEAT_ERROR_EVENT		0x02
-#define WHITEHEAT_FLOW_EVENT		0x04
-#define WHITEHEAT_CONNECT_EVENT		0x08
+
+/*
+ * WHITEHEAT_DO_TEST
+ */
+#define WHITEHEAT_TEST_UART_RW		0x01  /* read/write uart registers */
+#define WHITEHEAT_TEST_UART_INTR	0x02  /* uart interrupt */
+#define WHITEHEAT_TEST_SETUP_CONT	0x03  /* setup for PORT_CONT/PORT_DISCONT */
+#define WHITEHEAT_TEST_PORT_CONT	0x04  /* port connect */
+#define WHITEHEAT_TEST_PORT_DISCONT	0x05  /* port disconnect */
+#define WHITEHEAT_TEST_UART_CLK_START	0x06  /* uart clock test start */
+#define WHITEHEAT_TEST_UART_CLK_STOP	0x07  /* uart clock test stop */
+#define WHITEHEAT_TEST_MODEM_FT		0x08  /* modem signals, requires a loopback cable/connector */
+#define WHITEHEAT_TEST_ERASE_EEPROM	0x09  /* erase eeprom */
+#define WHITEHEAT_TEST_READ_EEPROM	0x0a  /* read eeprom */
+#define WHITEHEAT_TEST_PROGRAM_EEPROM	0x0b  /* program eeprom */
+
+struct whiteheat_test {
+	__u8	port;		/* port number (1 to n) */
+	__u8	test;		/* see WHITEHEAT_TEST_* above*/
+	__u8	info[32];	/* additional info */
+};
+
+
+/*
+ * Replies from the firmware
+ */
+
+
+/*
+ * WHITEHEAT_STATUS
+ */
+#define WHITEHEAT_EVENT_MODEM		0x01	/* modem field is valid */
+#define WHITEHEAT_EVENT_ERROR		0x02	/* error field is valid */
+#define WHITEHEAT_EVENT_FLOW		0x04	/* flow field is valid */
+#define WHITEHEAT_EVENT_CONNECT		0x08	/* connect field is valid */
+
+#define WHITEHEAT_FLOW_NONE		0x00	/* no flow control active */
+#define WHITEHEAT_FLOW_HARD_OUT		0x01	/* TX is stopped by CTS (waiting for CTS to go on) */
+#define WHITEHEAT_FLOW_HARD_IN		0x02	/* remote TX is stopped by RTS */
+#define WHITEHEAT_FLOW_SOFT_OUT		0x04	/* TX is stopped by XOFF received (waiting for XON) */
+#define WHITEHEAT_FLOW_SOFT_IN		0x08	/* remote TX is stopped by XOFF transmitted */
+#define WHITEHEAT_FLOW_TX_DONE		0x80	/* TX has completed */
+
 struct whiteheat_status_info {
 	__u8	port;		/* port number (1 to N) */
-	__u8	event;		/* indicates which of the following bytes are the current event */
-	__u8	modem;		/* modem signal status (copy of UART MSR register) */
-	__u8	error;		/* PFO and RX break (copy of UART LSR register) */
-	__u8	flow;		/* flow control state */
-	__u8	connect;	/* connect state, non-zero value indicates connected */
+	__u8	event;		/* indicates what the current event is, see WHITEHEAT_EVENT_* above */
+	__u8	modem;		/* modem signal status (copy of uart's MSR register) */
+	__u8	error;		/* line status (copy of uart's LSR register) */
+	__u8	flow;		/* flow control state, see WHITEHEAT_FLOW_* above */
+	__u8	connect;	/* 0 means not connected, non-zero means connected */
 };
 
-/* data returned from WHITEHEAT_EVENT command */
-struct whiteheat_event {
-	__u8	port;		/* port number (1 to N) */
-	__u8	event;		/* indicates which of the following bytes are the current event */
-	__u8	info;		/* either modem, error, flow, or connect information */
+
+/*
+ * WHITEHEAT_GET_DTR_RTS
+ */
+struct whiteheat_dr_info {
+	__u8	mcr;		/* copy of uart's MCR register */
 };
 
-/* data retured by the WHITEHEAT_GET_HW_INFO command */
+
+/*
+ * WHITEHEAT_GET_HW_INFO
+ */
 struct whiteheat_hw_info {
 	__u8	hw_id;		/* hardware id number, WhiteHEAT = 0 */
 	__u8	sw_major_rev;	/* major version number */
@@ -166,5 +253,30 @@
 	} hw_eeprom_info;	/* EEPROM contents */
 };
 
-#endif
 
+/*
+ * WHITEHEAT_EVENT
+ */
+struct whiteheat_event_info {
+	__u8	port;		/* port number (1 to N) */
+	__u8	event;		/* see whiteheat_status_info.event */
+	__u8	info;		/* see whiteheat_status_info.modem, .error, .flow, .connect */
+};
+
+
+/*
+ * WHITEHEAT_DO_TEST
+ */
+#define WHITEHEAT_TEST_FAIL	0x00  /* test failed */
+#define WHITEHEAT_TEST_UNKNOWN	0x01  /* unknown test requested */
+#define WHITEHEAT_TEST_PASS	0xff  /* test passed */
+
+struct whiteheat_test_info {
+	__u8	port;		/* port number (1 to N) */
+	__u8	test;		/* indicates which test this is a response for, see WHITEHEAT_DO_TEST above */
+	__u8	status;		/* see WHITEHEAT_TEST_* above */
+	__u8	results[32];	/* test-dependent results */
+};
+
+
+#endif
diff -Nru a/drivers/usb/serial/whiteheat_fw.h b/drivers/usb/serial/whiteheat_fw.h
--- a/drivers/usb/serial/whiteheat_fw.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/serial/whiteheat_fw.h	Fri Sep 27 14:51:04 2002
@@ -2,7 +2,7 @@
  *
  *      whiteheat.h  --  ConnectTech WhiteHEAT Firmware.
  *
- *      Copyright (C) 2000  ConnectTech Inc (http://www.connecttech.com/)
+ *      Copyright (C) 2000-2002  ConnectTech Inc (http://www.connecttech.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
@@ -18,6 +18,9 @@
  *      along with this program; if not, write to the Free Software
  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
+ * (10/09/2002) Stuart MacDonald
+ *	Firmware 4.06
+ *
  * (04/09/2000) gkh
  *	Updated the firmware with the latest provided by ConnectTech.
  *
@@ -47,12 +50,12 @@
 };
 
 static const struct whiteheat_hex_record whiteheat_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x95, 0xe7} },
+{ 0x0000,	3,	{0x02, 0x97, 0xaf} },
 { 0x0003,	3,	{0x02, 0x13, 0x12} },
 { 0x000b,	3,	{0x02, 0x0b, 0xb5} },
-{ 0x0033,	3,	{0x02, 0x08, 0x18} },
+{ 0x0033,	3,	{0x02, 0x08, 0x1c} },
 { 0x0043,	3,	{0x02, 0x0a, 0x00} },
-{ 0x005b,	3,	{0x02, 0x11, 0xdd} },
+{ 0x005b,	3,	{0x02, 0x83, 0x3b} },
 { 0x0370,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x73, 0x14, 0x70, 0x03, 0x02, 0x04, 0xe7, 0x24} },
 { 0x0380,	16,	{0xfe, 0x70, 0x03, 0x02, 0x05, 0x4f, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} },
 { 0x0390,	16,	{0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x49, 0x24} },
@@ -61,14 +64,14 @@
 { 0x03c0,	16,	{0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x99, 0xea, 0x49, 0x60, 0x0d} },
 { 0x03d0,	16,	{0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} },
 { 0x03e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x58, 0xea} },
-{ 0x03f0,	16,	{0x49, 0x60, 0x33, 0x12, 0xa0, 0x3f, 0xf5, 0x4c, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4c, 0xd3} },
-{ 0x0400,	16,	{0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4c, 0x40} },
-{ 0x0410,	16,	{0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4c, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xb5} },
-{ 0x0420,	16,	{0xe5, 0x4c, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
+{ 0x03f0,	16,	{0x49, 0x60, 0x33, 0x12, 0xa2, 0x07, 0xf5, 0x4e, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4e, 0xd3} },
+{ 0x0400,	16,	{0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4e, 0xe5, 0x4e, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4e, 0x40} },
+{ 0x0410,	16,	{0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4e, 0x12, 0x91, 0x03, 0x90, 0x7f, 0xb5} },
+{ 0x0420,	16,	{0xe5, 0x4e, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
 { 0x0430,	16,	{0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} },
 { 0x0440,	16,	{0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} },
-{ 0x0450,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x32, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
-{ 0x0460,	16,	{0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x32, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
+{ 0x0450,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x35, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
+{ 0x0460,	16,	{0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x35, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
 { 0x0470,	16,	{0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} },
 { 0x0480,	16,	{0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x05, 0xe4, 0x33, 0x4f, 0x90} },
 { 0x0490,	16,	{0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0xe4} },
@@ -79,8 +82,8 @@
 { 0x04e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} },
 { 0x04f0,	16,	{0x02, 0x60, 0x03, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} },
 { 0x0500,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0} },
-{ 0x0510,	16,	{0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4c, 0xef, 0x30, 0xe7, 0x03} },
-{ 0x0520,	16,	{0x43, 0x4c, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4c, 0xf0, 0xe5, 0x4c, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
+{ 0x0510,	16,	{0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4e, 0xef, 0x30, 0xe7, 0x03} },
+{ 0x0520,	16,	{0x43, 0x4e, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4e, 0xf0, 0xe5, 0x4e, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
 { 0x0530,	16,	{0x54, 0x80, 0xfd, 0xc4, 0x54, 0x0f, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} },
 { 0x0540,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90} },
 { 0x0550,	16,	{0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4} },
@@ -90,226 +93,223 @@
 { 0x0590,	16,	{0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f} },
 { 0x05a0,	12,	{0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
 { 0x05ac,	1,	{0x22} },
-{ 0x05ad,	16,	{0x75, 0x48, 0xff, 0x75, 0x47, 0xff, 0x75, 0x46, 0x0f, 0x75, 0x45, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
+{ 0x05ad,	16,	{0x75, 0x4a, 0xff, 0x75, 0x49, 0xff, 0x75, 0x48, 0x0f, 0x75, 0x47, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
 { 0x05bd,	16,	{0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} },
 { 0x05cd,	16,	{0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} },
-{ 0x05dd,	16,	{0x0c, 0x22, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
-{ 0x05ed,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0x7e} },
-{ 0x05fd,	16,	{0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0x0a, 0x90, 0x01, 0x0b, 0xe0} },
-{ 0x060d,	16,	{0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
-{ 0x061d,	16,	{0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
-{ 0x062d,	16,	{0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} },
-{ 0x063d,	16,	{0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x064d,	16,	{0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
-{ 0x065d,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff, 0x74, 0x01, 0x93, 0x90} },
-{ 0x066d,	16,	{0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff, 0xa3, 0xe0, 0xfe, 0xef} },
-{ 0x067d,	16,	{0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0x6f} },
-{ 0x068d,	16,	{0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x50, 0x10, 0x75, 0x51, 0x02, 0x75} },
-{ 0x069d,	16,	{0x52, 0x12, 0x75, 0x53, 0xac, 0x12, 0x92, 0x2a, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0xb2, 0x90, 0x01} },
-{ 0x06ad,	16,	{0x0d, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82} },
-{ 0x06bd,	16,	{0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
-{ 0x06cd,	16,	{0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} },
-{ 0x06dd,	16,	{0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
-{ 0x06ed,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xae, 0x4a, 0x70, 0x02, 0x05, 0x4a} },
-{ 0x06fd,	16,	{0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83, 0x01, 0xe0, 0xfc, 0xa3} },
-{ 0x070d,	16,	{0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa1, 0xf2, 0x7e, 0x01} },
-{ 0x071d,	16,	{0x7f, 0x18, 0x12, 0x85, 0xcf, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x072d,	16,	{0xa3, 0xe0, 0xff, 0x75, 0x50, 0x0a, 0x75, 0x51, 0x06, 0x75, 0x52, 0x12, 0x75, 0x53, 0xb8, 0x12} },
-{ 0x073d,	16,	{0x92, 0x2a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} },
-{ 0x074d,	16,	{0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x1f, 0xf0, 0xd2, 0xaf} },
-{ 0x075d,	16,	{0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xc1, 0x75, 0x44, 0x50} },
-{ 0x076d,	16,	{0x75, 0x43, 0x6d, 0x75, 0x42, 0x33, 0x75, 0x41, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} },
-{ 0x077d,	16,	{0x7d, 0xff, 0x7c, 0xff, 0x78, 0x41, 0x12, 0xa1, 0xdb, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} },
-{ 0x078d,	16,	{0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0a, 0x12, 0x09, 0xf7, 0x50} },
-{ 0x079d,	16,	{0x03, 0x12, 0x0a, 0xe8, 0xc2, 0x06, 0x12, 0x94, 0x62, 0x90, 0x01, 0xbd, 0xe0, 0x60, 0x0c, 0x12} },
-{ 0x07ad,	16,	{0x90, 0x05, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02, 0xaf, 0xe0, 0xb4} },
-{ 0x07bd,	16,	{0x0f, 0x03, 0x12, 0x97, 0xbd, 0x12, 0x9e, 0x99, 0xe4, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80} },
-{ 0x07cd,	16,	{0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14, 0x74, 0x27, 0x2f} },
-{ 0x07dd,	16,	{0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0x8e, 0x49, 0x80} },
-{ 0x07ed,	16,	{0x03, 0x75, 0x49, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe5, 0x49} },
-{ 0x07fd,	16,	{0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f, 0x01, 0x80, 0x02} },
-{ 0x080d,	10,	{0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} },
-{ 0x0817,	1,	{0x22} },
-{ 0x0818,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x081c,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x44, 0x30, 0xf0, 0x90, 0x7f} },
-{ 0x082c,	16,	{0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0} },
-{ 0x083c,	16,	{0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x08} },
-{ 0x084c,	16,	{0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfb, 0xf0, 0x7f} },
-{ 0x085c,	16,	{0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0x7d} },
-{ 0x086c,	16,	{0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44} },
-{ 0x087c,	16,	{0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96} },
-{ 0x088c,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54} },
-{ 0x089c,	16,	{0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0} },
-{ 0x08ac,	8,	{0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x22} },
-{ 0x08b4,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
-{ 0x08c4,	16,	{0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x82, 0xa8} },
-{ 0x08d4,	16,	{0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05} },
-{ 0x08e4,	16,	{0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00} },
-{ 0x08f4,	16,	{0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09} },
-{ 0x0904,	16,	{0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5} },
-{ 0x0914,	16,	{0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x54, 0xcf, 0xf0, 0x90, 0x7f, 0x95} },
-{ 0x0924,	8,	{0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x0b, 0x00, 0x22} },
-{ 0x092c,	16,	{0x90, 0x0a, 0xf0, 0xe4, 0x93, 0x70, 0x76, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
-{ 0x093c,	16,	{0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa} },
-{ 0x094c,	16,	{0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x08, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf} },
-{ 0x095c,	16,	{0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x20, 0x70, 0xe0, 0xff, 0xc4, 0x54, 0x0f} },
-{ 0x096c,	16,	{0xf5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x07, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x80, 0xf0, 0xe4, 0x90} },
-{ 0x097c,	16,	{0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0b} },
-{ 0x098c,	16,	{0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12} },
-{ 0x099c,	14,	{0xf0, 0x12, 0x08, 0x1c, 0x75, 0x82, 0xf0, 0x75, 0x83, 0x0a, 0x74, 0xff, 0xf0, 0x22} },
-{ 0x09aa,	16,	{0x8e, 0x5b, 0x8f, 0x5c, 0xe5, 0x5c, 0x15, 0x5c, 0xae, 0x5b, 0x70, 0x02, 0x15, 0x5b, 0x4e, 0x60} },
-{ 0x09ba,	7,	{0x05, 0x12, 0x09, 0xe6, 0x80, 0xee, 0x22} },
-{ 0x09c1,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
-{ 0x09d1,	16,	{0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x09e1,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x09e6,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x09f6,	1,	{0x22} },
-{ 0x09f7,	5,	{0x12, 0x08, 0xb4, 0xd3, 0x22} },
-{ 0x09fc,	1,	{0x32} },
-{ 0x09fd,	1,	{0x32} },
-{ 0x09fe,	1,	{0x32} },
-{ 0x09ff,	1,	{0x32} },
+{ 0x05dd,	16,	{0x0c, 0x22, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3} },
+{ 0x05ed,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3} },
+{ 0x05fd,	16,	{0x74, 0x08, 0xf0, 0x7e, 0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x4c, 0x12, 0x75, 0x4d, 0x0a} },
+{ 0x060d,	16,	{0x90, 0x01, 0x0b, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14} },
+{ 0x061d,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4d, 0xe5} },
+{ 0x062d,	16,	{0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01} },
+{ 0x063d,	16,	{0x0d, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82} },
+{ 0x064d,	16,	{0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70} },
+{ 0x065d,	16,	{0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff} },
+{ 0x066d,	16,	{0x74, 0x01, 0x93, 0x90, 0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff} },
+{ 0x067d,	16,	{0xa3, 0xe0, 0xfe, 0xef, 0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90} },
+{ 0x068d,	16,	{0x01, 0x1c, 0xe0, 0x6f, 0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x52, 0x10} },
+{ 0x069d,	16,	{0x75, 0x53, 0x02, 0x75, 0x54, 0x12, 0x75, 0x55, 0xac, 0x12, 0x93, 0xf2, 0x75, 0x4c, 0x12, 0x75} },
+{ 0x06ad,	16,	{0x4d, 0xb2, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05} },
+{ 0x06bd,	16,	{0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4d, 0xe5} },
+{ 0x06cd,	16,	{0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f} },
+{ 0x06dd,	16,	{0x92, 0xe0, 0xff, 0xc4, 0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70} },
+{ 0x06ed,	16,	{0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4d, 0xe5, 0x4d, 0xae, 0x4c} },
+{ 0x06fd,	16,	{0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83} },
+{ 0x070d,	16,	{0x01, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12} },
+{ 0x071d,	16,	{0xa3, 0xba, 0x7e, 0x01, 0x7f, 0x18, 0x12, 0x86, 0xbe, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x072d,	16,	{0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x75, 0x52, 0x0a, 0x75, 0x53, 0x06, 0x75, 0x54, 0x12} },
+{ 0x073d,	16,	{0x75, 0x55, 0xb8, 0x12, 0x93, 0xf2, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff} },
+{ 0x074d,	16,	{0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44} },
+{ 0x075d,	16,	{0x1f, 0xf0, 0xd2, 0xaf, 0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09} },
+{ 0x076d,	16,	{0xc5, 0x75, 0x46, 0x50, 0x75, 0x45, 0x6d, 0x75, 0x44, 0x33, 0x75, 0x43, 0x00, 0x20, 0x01, 0xe4} },
+{ 0x077d,	16,	{0x7f, 0xff, 0x7e, 0xff, 0x7d, 0xff, 0x7c, 0xff, 0x78, 0x43, 0x12, 0xa3, 0xa3, 0xec, 0x4d, 0x4e} },
+{ 0x078d,	16,	{0x4f, 0x60, 0xd1, 0x80, 0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0a} },
+{ 0x079d,	16,	{0x12, 0x09, 0xfb, 0x50, 0x03, 0x12, 0x0a, 0xe8, 0xc2, 0x06, 0x12, 0x96, 0x2a, 0x90, 0x01, 0xbd} },
+{ 0x07ad,	16,	{0xe0, 0x60, 0x0c, 0x12, 0x91, 0xcd, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90} },
+{ 0x07bd,	16,	{0x02, 0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x99, 0x85, 0x12, 0xa0, 0x61, 0xe4, 0xff, 0x74, 0x01} },
+{ 0x07cd,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60} },
+{ 0x07dd,	16,	{0x14, 0x74, 0x28, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e} },
+{ 0x07ed,	16,	{0x00, 0x8e, 0x4b, 0x80, 0x03, 0x75, 0x4b, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20} },
+{ 0x07fd,	16,	{0xf5, 0x83, 0xe5, 0x4b, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2c, 0xd3, 0x94, 0x0a, 0x40, 0x04} },
+{ 0x080d,	14,	{0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x92} },
+{ 0x081b,	1,	{0x22} },
+{ 0x081c,	4,	{0x53, 0xd8, 0xef, 0x32} },
+{ 0x0820,	16,	{0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x44, 0x30, 0xf0, 0x90, 0x7f} },
+{ 0x0830,	16,	{0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0} },
+{ 0x0840,	16,	{0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x08} },
+{ 0x0850,	16,	{0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfb, 0xf0, 0x7f} },
+{ 0x0860,	16,	{0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0x7d} },
+{ 0x0870,	16,	{0xff, 0x12, 0x82, 0xea, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44} },
+{ 0x0880,	16,	{0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96} },
+{ 0x0890,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54} },
+{ 0x08a0,	16,	{0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0} },
+{ 0x08b0,	8,	{0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x22} },
+{ 0x08b8,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
+{ 0x08c8,	16,	{0x09, 0xae, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x82, 0xea} },
+{ 0x08d8,	16,	{0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05} },
+{ 0x08e8,	16,	{0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00} },
+{ 0x08f8,	16,	{0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09} },
+{ 0x0908,	16,	{0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0xe5} },
+{ 0x0918,	16,	{0x33, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x54, 0xcf, 0xf0, 0x90, 0x7f, 0x95} },
+{ 0x0928,	8,	{0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x0b, 0x00, 0x22} },
+{ 0x0930,	16,	{0x90, 0x0a, 0xf4, 0xe4, 0x93, 0x70, 0x76, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
+{ 0x0940,	16,	{0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xae} },
+{ 0x0950,	16,	{0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x08, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf} },
+{ 0x0960,	16,	{0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x20, 0x70, 0xe0, 0xff, 0xc4, 0x54, 0x0f} },
+{ 0x0970,	16,	{0xf5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x07, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x80, 0xf0, 0xe4, 0x90} },
+{ 0x0980,	16,	{0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x0b} },
+{ 0x0990,	16,	{0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12} },
+{ 0x09a0,	14,	{0xf0, 0x12, 0x08, 0x20, 0x75, 0x82, 0xf4, 0x75, 0x83, 0x0a, 0x74, 0xff, 0xf0, 0x22} },
+{ 0x09ae,	16,	{0x8e, 0x5d, 0x8f, 0x5e, 0xe5, 0x5e, 0x15, 0x5e, 0xae, 0x5d, 0x70, 0x02, 0x15, 0x5d, 0x4e, 0x60} },
+{ 0x09be,	7,	{0x05, 0x12, 0x09, 0xea, 0x80, 0xee, 0x22} },
+{ 0x09c5,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
+{ 0x09d5,	16,	{0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0xae, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
+{ 0x09e5,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
+{ 0x09ea,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
+{ 0x09fa,	1,	{0x22} },
+{ 0x09fb,	5,	{0x12, 0x08, 0xb8, 0xd3, 0x22} },
 { 0x0a00,	16,	{0x02, 0x0c, 0x4e, 0x00, 0x02, 0x0c, 0x81, 0x00, 0x02, 0x0c, 0x66, 0x00, 0x02, 0x0c, 0xc0, 0x00} },
-{ 0x0a10,	16,	{0x02, 0x0c, 0xaa, 0x00, 0x02, 0x09, 0xfc, 0x00, 0x02, 0x09, 0xfd, 0x00, 0x02, 0x09, 0xfe, 0x00} },
-{ 0x0a20,	16,	{0x02, 0x0c, 0xdb, 0x00, 0x02, 0x0d, 0xcb, 0x00, 0x02, 0x0d, 0x17, 0x00, 0x02, 0x0e, 0x1f, 0x00} },
-{ 0x0a30,	16,	{0x02, 0x0d, 0x53, 0x00, 0x02, 0x0e, 0x73, 0x00, 0x02, 0x0d, 0x8f, 0x00, 0x02, 0x0e, 0xc7, 0x00} },
-{ 0x0a40,	16,	{0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xee, 0x00, 0x02, 0x0a, 0xed, 0x00, 0x02, 0x0a, 0xef, 0x00} },
-{ 0x0a50,	8,	{0x02, 0x0f, 0x1b, 0x00, 0x02, 0x0f, 0x31, 0x00} },
-{ 0x0a58,	2,	{0x8f, 0x4d} },
-{ 0x0a5a,	16,	{0xe4, 0xf5, 0x4e, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x6a, 0xab, 0x4f, 0xaa, 0x50} },
-{ 0x0a6a,	16,	{0xa9, 0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x03, 0x1d, 0xaf, 0x4e, 0x05, 0x4e, 0xef} },
-{ 0x0a7a,	16,	{0xb5, 0x4d, 0x01, 0x22, 0x12, 0xa0, 0x3f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0a8a,	14,	{0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0a10,	16,	{0x02, 0x0c, 0xaa, 0x00, 0x02, 0x0a, 0xed, 0x00, 0x02, 0x0a, 0xee, 0x00, 0x02, 0x0a, 0xef, 0x00} },
+{ 0x0a20,	16,	{0x02, 0x0c, 0xdb, 0x00, 0x02, 0x0d, 0xcb, 0x00, 0x02, 0x0d, 0x17, 0x00, 0x02, 0x0e, 0x2b, 0x00} },
+{ 0x0a30,	16,	{0x02, 0x0d, 0x53, 0x00, 0x02, 0x0e, 0x8b, 0x00, 0x02, 0x0d, 0x8f, 0x00, 0x02, 0x0e, 0xeb, 0x00} },
+{ 0x0a40,	16,	{0x02, 0x0a, 0xf0, 0x00, 0x02, 0x0a, 0xf2, 0x00, 0x02, 0x0a, 0xf1, 0x00, 0x02, 0x0a, 0xf3, 0x00} },
+{ 0x0a50,	8,	{0x02, 0x0f, 0x4b, 0x00, 0x02, 0x0f, 0x61, 0x00} },
+{ 0x0a58,	2,	{0x8f, 0x4f} },
+{ 0x0a5a,	16,	{0xe4, 0xf5, 0x50, 0x75, 0x51, 0xff, 0x75, 0x52, 0x12, 0x75, 0x53, 0x6a, 0xab, 0x51, 0xaa, 0x52} },
+{ 0x0a6a,	16,	{0xa9, 0x53, 0x90, 0x00, 0x01, 0x12, 0xa2, 0x20, 0xb4, 0x03, 0x1d, 0xaf, 0x50, 0x05, 0x50, 0xef} },
+{ 0x0a7a,	16,	{0xb5, 0x4f, 0x01, 0x22, 0x12, 0xa2, 0x07, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
+{ 0x0a8a,	14,	{0x51, 0xff, 0xf5, 0x52, 0x89, 0x53, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
 { 0x0a98,	1,	{0x22} },
-{ 0x0a99,	16,	{0xe4, 0xfe, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x12, 0xab, 0x4f, 0xaa, 0x50, 0xa9} },
-{ 0x0aa9,	16,	{0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x0ab9,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0xa0, 0xb1, 0x85, 0xf0, 0x4d, 0xf5, 0x4e, 0x62, 0x4d} },
-{ 0x0ac9,	16,	{0xe5, 0x4d, 0x62, 0x4e, 0xe5, 0x4e, 0x62, 0x4d, 0x29, 0xfd, 0xe5, 0x4d, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x0ad9,	14,	{0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0a99,	16,	{0xe4, 0xfe, 0x75, 0x51, 0xff, 0x75, 0x52, 0x12, 0x75, 0x53, 0x12, 0xab, 0x51, 0xaa, 0x52, 0xa9} },
+{ 0x0aa9,	16,	{0x53, 0x90, 0x00, 0x01, 0x12, 0xa2, 0x20, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
+{ 0x0ab9,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0xa2, 0x79, 0x85, 0xf0, 0x4f, 0xf5, 0x50, 0x62, 0x4f} },
+{ 0x0ac9,	16,	{0xe5, 0x4f, 0x62, 0x50, 0xe5, 0x50, 0x62, 0x4f, 0x29, 0xfd, 0xe5, 0x4f, 0x3a, 0xa9, 0x05, 0x75} },
+{ 0x0ad9,	14,	{0x51, 0xff, 0xf5, 0x52, 0x89, 0x53, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
 { 0x0ae7,	1,	{0x22} },
-{ 0x0ae8,	5,	{0x12, 0x08, 0x1c, 0xd3, 0x22} },
+{ 0x0ae8,	5,	{0x12, 0x08, 0x20, 0xd3, 0x22} },
 { 0x0aed,	1,	{0x32} },
 { 0x0aee,	1,	{0x32} },
 { 0x0aef,	1,	{0x32} },
-{ 0x0af0,	3,	{0x00, 0x04, 0x00} },
+{ 0x0af0,	1,	{0x32} },
+{ 0x0af1,	1,	{0x32} },
+{ 0x0af2,	1,	{0x32} },
+{ 0x0af3,	1,	{0x32} },
+{ 0x0af4,	3,	{0x00, 0x04, 0x06} },
 { 0x0b00,	9,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} },
 { 0x0b7d,	16,	{0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
 { 0x0b8d,	16,	{0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} },
 { 0x0b9d,	16,	{0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} },
-{ 0x0bad,	7,	{0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
+{ 0x0bad,	7,	{0x78, 0x28, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
 { 0x0bb4,	1,	{0x22} },
 { 0x0bb5,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} },
 { 0x0bc5,	1,	{0x07} },
 { 0x0bc6,	16,	{0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} },
-{ 0x0bd6,	16,	{0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} },
-{ 0x0be6,	16,	{0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
+{ 0x0bd6,	16,	{0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x28, 0xef, 0xd3} },
+{ 0x0be6,	16,	{0x94, 0x2c, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
 { 0x0bf6,	16,	{0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} },
 { 0x0c06,	13,	{0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} },
 { 0x0c13,	15,	{0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c22,	16,	{0xd2, 0x00, 0x75, 0x8e, 0x10, 0x12, 0x09, 0x2c, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x08, 0x90} },
+{ 0x0c22,	16,	{0xd2, 0x00, 0x75, 0x8e, 0x10, 0x12, 0x09, 0x30, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x08, 0x90} },
 { 0x0c32,	16,	{0x7f, 0x92, 0x74, 0x02, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12} },
-{ 0x0c42,	12,	{0x0f, 0x4d, 0x12, 0x92, 0xfb, 0x12, 0x1b, 0x0c, 0x12, 0x0b, 0x8d, 0x22} },
+{ 0x0c42,	12,	{0x0f, 0x7d, 0x12, 0x94, 0xc3, 0x12, 0x1b, 0x0c, 0x12, 0x0b, 0x8d, 0x22} },
 { 0x0c4e,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} },
 { 0x0c5e,	8,	{0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0c66,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
 { 0x0c76,	11,	{0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0c81,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} },
-{ 0x0c91,	16,	{0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} },
-{ 0x0ca1,	9,	{0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c91,	16,	{0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2c, 0x70, 0x03, 0x75} },
+{ 0x0ca1,	9,	{0x2c, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0caa,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} },
 { 0x0cba,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0cc0,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} },
 { 0x0cd0,	11,	{0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0cdb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0ceb,	16,	{0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x30, 0xe0, 0x13, 0xe5, 0x3c, 0x30, 0xe0, 0x07, 0x90, 0x20} },
-{ 0x0cfb,	16,	{0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0d0b,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0ceb,	16,	{0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x34, 0x30, 0xe0, 0x13, 0xe5, 0x32, 0x30, 0xe0, 0x07, 0x90, 0x20} },
+{ 0x0cfb,	16,	{0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} },
+{ 0x0d0b,	12,	{0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0d17,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0d27,	16,	{0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x30, 0xe1, 0x13, 0xe5, 0x3c, 0x30, 0xe1, 0x07, 0x90, 0x20} },
-{ 0x0d37,	16,	{0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0d47,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d27,	16,	{0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x34, 0x30, 0xe1, 0x13, 0xe5, 0x32, 0x30, 0xe1, 0x07, 0x90, 0x20} },
+{ 0x0d37,	16,	{0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} },
+{ 0x0d47,	12,	{0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0d53,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0d63,	16,	{0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x30, 0xe2, 0x13, 0xe5, 0x3c, 0x30, 0xe2, 0x07, 0x90, 0x20} },
-{ 0x0d73,	16,	{0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0d83,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d63,	16,	{0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x34, 0x30, 0xe2, 0x13, 0xe5, 0x32, 0x30, 0xe2, 0x07, 0x90, 0x20} },
+{ 0x0d73,	16,	{0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} },
+{ 0x0d83,	12,	{0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0d8f,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0d9f,	16,	{0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x30, 0xe3, 0x13, 0xe5, 0x3c, 0x30, 0xe3, 0x07, 0x90, 0x20} },
-{ 0x0daf,	16,	{0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0dbf,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d9f,	16,	{0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x34, 0x30, 0xe3, 0x13, 0xe5, 0x32, 0x30, 0xe3, 0x07, 0x90, 0x20} },
+{ 0x0daf,	16,	{0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} },
+{ 0x0dbf,	12,	{0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x0dcb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0ddb,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x20} },
-{ 0x0deb,	16,	{0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
-{ 0x0dfb,	16,	{0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e0b,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e1b,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e1f,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0e2f,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x20} },
-{ 0x0e3f,	16,	{0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
-{ 0x0e4f,	16,	{0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e5f,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e6f,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e73,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0e83,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x20} },
-{ 0x0e93,	16,	{0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
-{ 0x0ea3,	16,	{0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0eb3,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0ec3,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ec7,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0ed7,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x20} },
-{ 0x0ee7,	16,	{0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
-{ 0x0ef7,	16,	{0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0f07,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0f17,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0f1b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
-{ 0x0f2b,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0f31,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
-{ 0x0f41,	12,	{0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0f4d,	16,	{0x90, 0x01, 0x20, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
-{ 0x0f5d,	16,	{0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
-{ 0x0f6d,	16,	{0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0f7d,	16,	{0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
-{ 0x0f8d,	16,	{0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0} },
-{ 0x0f9d,	16,	{0x16, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0xb7, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
-{ 0x0fad,	16,	{0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0fbd,	16,	{0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
-{ 0x0fcd,	16,	{0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
-{ 0x0fdd,	16,	{0xf5, 0x31, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0fed,	16,	{0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x0ffd,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x84, 0x08, 0x90, 0x01, 0x1e} },
-{ 0x100d,	16,	{0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3b, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x101d,	16,	{0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x102d,	16,	{0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x37} },
-{ 0x103d,	16,	{0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x33, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} },
-{ 0x104d,	16,	{0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x105d,	16,	{0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4c, 0x60, 0x5e} },
-{ 0x106d,	4,	{0xe4, 0x90, 0x01, 0x1e} },
-{ 0x1071,	16,	{0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} },
-{ 0x1081,	16,	{0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4c, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} },
-{ 0x1091,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} },
-{ 0x10a1,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} },
-{ 0x10b1,	16,	{0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} },
-{ 0x10c1,	11,	{0x83, 0x7e, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} },
-{ 0x10cc,	4,	{0x8e, 0x57, 0x8f, 0x58} },
-{ 0x10d0,	16,	{0x75, 0x59, 0x03, 0xe5, 0x58, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfe} },
-{ 0x10e0,	16,	{0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x11, 0xda, 0xe5, 0x59, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
-{ 0x10f0,	16,	{0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x11, 0x7e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
-{ 0x1100,	16,	{0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
-{ 0x1110,	16,	{0x80, 0x6c, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
-{ 0x1120,	16,	{0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x59, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3} },
-{ 0x1130,	16,	{0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x58, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1140,	16,	{0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5} },
-{ 0x1150,	16,	{0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x58, 0x24} },
-{ 0x1160,	16,	{0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0xa0, 0x85, 0x85} },
-{ 0x1170,	16,	{0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x85, 0x90, 0x7f} },
-{ 0x1180,	16,	{0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
-{ 0x1190,	16,	{0x22, 0xe5, 0x5a, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
-{ 0x11a0,	16,	{0xe5, 0x59, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x11b0,	16,	{0x80, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
-{ 0x11c0,	16,	{0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
-{ 0x11d0,	12,	{0x59, 0x03, 0x02, 0x10, 0xd3, 0x15, 0x59, 0x02, 0x10, 0xd3, 0x7f, 0x08} },
-{ 0x11dc,	1,	{0x22} },
-{ 0x11dd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
-{ 0x11ed,	15,	{0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0ddb,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x34, 0x20} },
+{ 0x0deb,	16,	{0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
+{ 0x0dfb,	16,	{0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe0, 0x07, 0x90, 0x20, 0x04, 0xe0} },
+{ 0x0e0b,	16,	{0x44, 0x02, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} },
+{ 0x0e1b,	16,	{0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e2b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e3b,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x34, 0x20} },
+{ 0x0e4b,	16,	{0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
+{ 0x0e5b,	16,	{0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe1, 0x07, 0x90, 0x20, 0x0c, 0xe0} },
+{ 0x0e6b,	16,	{0x44, 0x02, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} },
+{ 0x0e7b,	16,	{0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e8b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e9b,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x34, 0x20} },
+{ 0x0eab,	16,	{0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
+{ 0x0ebb,	16,	{0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe2, 0x07, 0x90, 0x20, 0x14, 0xe0} },
+{ 0x0ecb,	16,	{0x44, 0x02, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} },
+{ 0x0edb,	16,	{0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0eeb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0efb,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x34, 0x20} },
+{ 0x0f0b,	16,	{0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
+{ 0x0f1b,	16,	{0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe3, 0x07, 0x90, 0x20, 0x1c, 0xe0} },
+{ 0x0f2b,	16,	{0x44, 0x02, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} },
+{ 0x0f3b,	16,	{0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f4b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
+{ 0x0f5b,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f61,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
+{ 0x0f71,	12,	{0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f7d,	16,	{0x90, 0x01, 0x20, 0x12, 0xa3, 0xc6, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
+{ 0x0f8d,	16,	{0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
+{ 0x0f9d,	16,	{0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0fad,	16,	{0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
+{ 0x0fbd,	16,	{0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa1} },
+{ 0x0fcd,	16,	{0xde, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x87, 0xa6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
+{ 0x0fdd,	16,	{0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x27, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0fed,	16,	{0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
+{ 0x0ffd,	16,	{0xf0, 0x74, 0x23, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
+{ 0x100d,	16,	{0xf5, 0x34, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x101d,	16,	{0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
+{ 0x102d,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x34, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x84, 0x41, 0x90, 0x01, 0x1e} },
+{ 0x103d,	16,	{0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3e, 0xf5, 0x22, 0xf5, 0x31, 0xf5, 0x32, 0x90, 0x01} },
+{ 0x104d,	16,	{0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
+{ 0x105d,	16,	{0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54, 0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01} },
+{ 0x106d,	16,	{0xf5, 0x83, 0xee, 0xf0, 0x74, 0x3a, 0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x36, 0x2f, 0xf8, 0xe4, 0xf6} },
+{ 0x107d,	16,	{0x74, 0x2d, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
+{ 0x108d,	16,	{0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0} },
+{ 0x109d,	4,	{0x54, 0x0f, 0xf5, 0x4e} },
+{ 0x10a1,	16,	{0x70, 0x03, 0x02, 0x11, 0x26, 0xe4, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3} },
+{ 0x10b1,	16,	{0x94, 0x04, 0x50, 0xe4, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55} },
+{ 0x10c1,	16,	{0x4e, 0x60, 0x5a, 0x90, 0x01, 0x1e, 0xe0, 0xfe, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82} },
+{ 0x10d1,	16,	{0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xff, 0xee, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82} },
+{ 0x10e1,	16,	{0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xee, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
+{ 0x10f1,	16,	{0x34, 0x20, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x06, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5} },
+{ 0x1101,	16,	{0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0} },
+{ 0x1111,	16,	{0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63, 0x7d, 0x06, 0x12, 0x83, 0xdf, 0x90, 0x01, 0x1e} },
+{ 0x1121,	6,	{0xe0, 0x04, 0xf0, 0x80, 0x85, 0x22} },
+{ 0x1127,	2,	{0xac, 0x07} },
+{ 0x1129,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xec, 0x25, 0xe0, 0x44, 0x41, 0x90, 0x7f, 0xa6, 0xf0} },
+{ 0x1139,	16,	{0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90} },
+{ 0x1149,	16,	{0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0xd4, 0x80, 0xf8, 0x90, 0x7f} },
+{ 0x1159,	16,	{0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xdc, 0x20, 0xe1, 0x09, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} },
+{ 0x1169,	16,	{0xf9, 0x22, 0xed, 0x30, 0xe2, 0x0c, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} },
+{ 0x1179,	16,	{0xfa, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7b, 0x1e} },
+{ 0x1189,	16,	{0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6} },
+{ 0x1199,	16,	{0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0x86, 0x80, 0xf8, 0x90, 0x7f, 0xa5, 0xe0} },
+{ 0x11a9,	16,	{0xfd, 0x20, 0xe0, 0xdc, 0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x19, 0x90, 0x7f, 0xa5, 0xe0} },
+{ 0x11b9,	16,	{0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03} },
+{ 0x11c9,	16,	{0x02, 0x11, 0x29, 0x80, 0xf5, 0x90, 0x7f, 0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xd9, 0x30, 0xe2, 0x09} },
+{ 0x11d9,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x11e9,	12,	{0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} },
+{ 0x11f5,	1,	{0x22} },
 { 0x1200,	16,	{0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0x10, 0x07, 0x01, 0x80, 0x42, 0x00, 0x01, 0x02} },
 { 0x1210,	16,	{0x03, 0x01, 0x09, 0x02, 0x58, 0x00, 0x01, 0x01, 0x04, 0x80, 0x3c, 0x09, 0x04, 0x00, 0x00, 0x0a} },
 { 0x1220,	16,	{0xff, 0xff, 0xff, 0x05, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40} },
@@ -332,74 +332,74 @@
 { 0x1322,	16,	{0x75, 0x86, 0x00, 0x75, 0xd0, 0x18, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0xf0, 0x70, 0x11} },
 { 0x1332,	16,	{0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0} },
 { 0x1342,	16,	{0x32, 0x75, 0x86, 0x00, 0x10, 0xf0, 0x0b, 0x10, 0xf1, 0x12, 0x10, 0xf2, 0x19, 0x10, 0xf3, 0x20} },
-{ 0x1352,	16,	{0x80, 0xd4, 0xe5, 0x27, 0x70, 0x03, 0x75, 0x27, 0x14, 0x02, 0x13, 0x7c, 0xe5, 0x28, 0x70, 0x03} },
-{ 0x1362,	16,	{0x75, 0x28, 0x14, 0x02, 0x15, 0x0d, 0xe5, 0x29, 0x70, 0x03, 0x75, 0x29, 0x14, 0x02, 0x16, 0x9e} },
-{ 0x1372,	16,	{0xe5, 0x2a, 0x70, 0x03, 0x75, 0x2a, 0x14, 0x02, 0x18, 0x2f, 0x90, 0x20, 0x02, 0xe0, 0x54, 0x3f} },
+{ 0x1352,	16,	{0x80, 0xd4, 0xe5, 0x28, 0x70, 0x03, 0x75, 0x28, 0x14, 0x02, 0x13, 0x7c, 0xe5, 0x29, 0x70, 0x03} },
+{ 0x1362,	16,	{0x75, 0x29, 0x14, 0x02, 0x15, 0x0d, 0xe5, 0x2a, 0x70, 0x03, 0x75, 0x2a, 0x14, 0x02, 0x16, 0x9e} },
+{ 0x1372,	16,	{0xe5, 0x2b, 0x70, 0x03, 0x75, 0x2b, 0x14, 0x02, 0x18, 0x2f, 0x90, 0x20, 0x02, 0xe0, 0x54, 0x3f} },
 { 0x1382,	16,	{0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02, 0x13} },
-{ 0x1392,	16,	{0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13, 0x43} },
-{ 0x13a2,	16,	{0x43, 0x82, 0x04, 0xe0, 0x43, 0x2c, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x05} },
-{ 0x13b2,	16,	{0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
-{ 0x13c2,	16,	{0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
+{ 0x1392,	16,	{0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x3a, 0x02, 0x13, 0x43} },
+{ 0x13a2,	16,	{0x43, 0x82, 0x04, 0xe0, 0x43, 0x2d, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x05} },
+{ 0x13b2,	16,	{0xe0, 0x42, 0x36, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
+{ 0x13c2,	16,	{0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
 { 0x13d2,	16,	{0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x00, 0xf0, 0x90, 0x20} },
 { 0x13e2,	16,	{0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86} },
 { 0x13f2,	16,	{0x90, 0x7e, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f} },
-{ 0x1402,	16,	{0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1402,	16,	{0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x1412,	16,	{0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90} },
 { 0x1422,	16,	{0x7f, 0xb7, 0xed, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f, 0x40} },
 { 0x1432,	16,	{0x90, 0x7e, 0x80, 0x05, 0x86, 0x90, 0x20, 0x00, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d, 0x84} },
 { 0x1442,	16,	{0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xef, 0x05} },
 { 0x1452,	16,	{0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xb7, 0xf0, 0x05, 0x86, 0xa3, 0xe0, 0x54, 0xfe, 0xf0} },
-{ 0x1462,	16,	{0x02, 0x13, 0x43, 0x53, 0x2c, 0xfa, 0xe5, 0x22, 0x60, 0x08, 0x75, 0x22, 0x00, 0xd2, 0xe7, 0xfe} },
+{ 0x1462,	16,	{0x02, 0x13, 0x43, 0x53, 0x2d, 0xfa, 0xe5, 0x23, 0x60, 0x08, 0x75, 0x23, 0x00, 0xd2, 0xe7, 0xfe} },
 { 0x1472,	16,	{0x80, 0x0a, 0x90, 0x7f, 0xc7, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x14, 0xff, 0x90, 0x20, 0x50, 0x74} },
 { 0x1482,	16,	{0x00, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} },
 { 0x1492,	16,	{0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7e, 0x40, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} },
 { 0x14a2,	16,	{0x05, 0x86, 0x90, 0x7f, 0xe5, 0xee, 0x30, 0xe7, 0x08, 0x05, 0x86, 0xe0, 0x24, 0x38, 0xf0, 0x05} },
 { 0x14b2,	16,	{0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78, 0x60, 0x30, 0x03, 0x03, 0x03} },
 { 0x14c2,	16,	{0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0} },
-{ 0x14d2,	16,	{0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11, 0x8b, 0x22, 0x90, 0x7f} },
+{ 0x14d2,	16,	{0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11, 0x8b, 0x23, 0x90, 0x7f} },
 { 0x14e2,	16,	{0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x80, 0x1b, 0xe0, 0xde, 0xfd} },
 { 0x14f2,	16,	{0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90, 0x20, 0x01} },
 { 0x1502,	16,	{0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20, 0x0a, 0xe0, 0x54} },
 { 0x1512,	16,	{0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02} },
-{ 0x1522,	16,	{0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x38, 0x02, 0x13} },
-{ 0x1532,	16,	{0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2d, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82} },
-{ 0x1542,	16,	{0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
-{ 0x1552,	16,	{0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
+{ 0x1522,	16,	{0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x3b, 0x02, 0x13} },
+{ 0x1532,	16,	{0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82} },
+{ 0x1542,	16,	{0x05, 0xe0, 0x42, 0x37, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
+{ 0x1552,	16,	{0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
 { 0x1562,	16,	{0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x01, 0xf0, 0x90} },
 { 0x1572,	16,	{0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05} },
 { 0x1582,	16,	{0x86, 0x90, 0x7e, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90} },
-{ 0x1592,	16,	{0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1592,	16,	{0x7f, 0xe5, 0xe5, 0x40, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x15a2,	16,	{0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} },
 { 0x15b2,	16,	{0x90, 0x7f, 0xb9, 0xed, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f} },
 { 0x15c2,	16,	{0x40, 0x90, 0x7e, 0x00, 0x05, 0x86, 0x90, 0x20, 0x08, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d} },
 { 0x15d2,	16,	{0x84, 0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xef} },
 { 0x15e2,	16,	{0x05, 0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xb9, 0xf0, 0x05, 0x86, 0xa3, 0xe0, 0x54, 0xfe} },
-{ 0x15f2,	16,	{0xf0, 0x02, 0x13, 0x43, 0x53, 0x2d, 0xfa, 0xe5, 0x23, 0x60, 0x08, 0x75, 0x23, 0x00, 0xd2, 0xe7} },
+{ 0x15f2,	16,	{0xf0, 0x02, 0x13, 0x43, 0x53, 0x2e, 0xfa, 0xe5, 0x24, 0x60, 0x08, 0x75, 0x24, 0x00, 0xd2, 0xe7} },
 { 0x1602,	16,	{0xfe, 0x80, 0x0a, 0x90, 0x7f, 0xc9, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x16, 0x90, 0x90, 0x20, 0x50} },
 { 0x1612,	16,	{0x74, 0x01, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} },
 { 0x1622,	16,	{0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0xc0, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} },
 { 0x1632,	16,	{0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xee, 0x30, 0xe7, 0x08, 0x05, 0x86, 0xe0, 0x24, 0x38, 0xf0} },
 { 0x1642,	16,	{0x05, 0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78, 0x60, 0x30, 0x03, 0x03} },
 { 0x1652,	16,	{0x03, 0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0} },
-{ 0x1662,	16,	{0xe0, 0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11, 0x8b, 0x23, 0x90} },
+{ 0x1662,	16,	{0xe0, 0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11, 0x8b, 0x24, 0x90} },
 { 0x1672,	16,	{0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x80, 0x1b, 0xe0, 0xde} },
 { 0x1682,	14,	{0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} },
 { 0x1690,	16,	{0x90, 0x20, 0x09, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20} },
 { 0x16a0,	16,	{0x12, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14} },
 { 0x16b0,	16,	{0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x17, 0x87, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5} },
-{ 0x16c0,	16,	{0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
-{ 0x16d0,	16,	{0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
-{ 0x16e0,	16,	{0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
+{ 0x16c0,	16,	{0x3c, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
+{ 0x16d0,	16,	{0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x38, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
+{ 0x16e0,	16,	{0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
 { 0x16f0,	16,	{0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74} },
 { 0x1700,	16,	{0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} },
 { 0x1710,	16,	{0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} },
-{ 0x1720,	16,	{0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1720,	16,	{0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x41, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x1730,	16,	{0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58} },
 { 0x1740,	16,	{0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbb, 0xed, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfe, 0xf0, 0x02} },
 { 0x1750,	16,	{0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x80, 0x05, 0x86, 0x90, 0x20, 0x10, 0xe5, 0x84, 0xfe, 0x24} },
 { 0x1760,	16,	{0x05, 0xfd, 0x8d, 0x84, 0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05} },
 { 0x1770,	16,	{0x86, 0xdf, 0xef, 0x05, 0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xbb, 0xf0, 0x05, 0x86, 0xa3} },
-{ 0x1780,	16,	{0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x53, 0x2e, 0xfa, 0xe5, 0x24, 0x60, 0x08, 0x75, 0x24} },
+{ 0x1780,	16,	{0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x53, 0x2f, 0xfa, 0xe5, 0x25, 0x60, 0x08, 0x75, 0x25} },
 { 0x1790,	16,	{0x00, 0xd2, 0xe7, 0xfe, 0x80, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x18, 0x21} },
 { 0x17a0,	16,	{0x90, 0x20, 0x50, 0x74, 0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0} },
 { 0x17b0,	16,	{0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x40, 0x05, 0x86, 0xe5, 0x85, 0xf0} },
@@ -407,32 +407,32 @@
 { 0x17d0,	16,	{0x24, 0x38, 0xf0, 0x05, 0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78, 0x60} },
 { 0x17e0,	16,	{0x30, 0x03, 0x03, 0x03, 0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0, 0xe0} },
 { 0x17f0,	16,	{0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11} },
-{ 0x1800,	16,	{0x8b, 0x24, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x80} },
+{ 0x1800,	16,	{0x8b, 0x25, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x80} },
 { 0x1810,	16,	{0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00} },
 { 0x1820,	16,	{0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x02, 0x13, 0x43, 0x90} },
 { 0x1830,	16,	{0x20, 0x1a, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5} },
 { 0x1840,	16,	{0x14, 0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x19, 0x18, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0} },
-{ 0x1850,	16,	{0xf5, 0x3a, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} },
-{ 0x1860,	16,	{0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x36, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
-{ 0x1870,	16,	{0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
+{ 0x1850,	16,	{0xf5, 0x3d, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x30, 0x01, 0x02, 0x13, 0x43, 0x53} },
+{ 0x1860,	16,	{0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x39, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
+{ 0x1870,	16,	{0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
 { 0x1880,	16,	{0xf8, 0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50} },
 { 0x1890,	16,	{0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} },
 { 0x18a0,	16,	{0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} },
-{ 0x18b0,	16,	{0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x40, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
+{ 0x18b0,	16,	{0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x42, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
 { 0x18c0,	16,	{0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20} },
 { 0x18d0,	16,	{0x58, 0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbd, 0xed, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfe, 0xf0} },
 { 0x18e0,	16,	{0x02, 0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x00, 0x05, 0x86, 0x90, 0x20, 0x18, 0xe5, 0x84, 0xfe} },
 { 0x18f0,	16,	{0x24, 0x05, 0xfd, 0x8d, 0x84, 0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3} },
 { 0x1900,	16,	{0x05, 0x86, 0xdf, 0xef, 0x05, 0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xbd, 0xf0, 0x05, 0x86} },
-{ 0x1910,	16,	{0xa3, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x53, 0x2f, 0xfa, 0xe5, 0x25, 0x60, 0x08, 0x75} },
-{ 0x1920,	16,	{0x25, 0x00, 0xd2, 0xe7, 0xfe, 0x80, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x19} },
+{ 0x1910,	16,	{0xa3, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x53, 0x30, 0xfa, 0xe5, 0x26, 0x60, 0x08, 0x75} },
+{ 0x1920,	16,	{0x26, 0x00, 0xd2, 0xe7, 0xfe, 0x80, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x19} },
 { 0x1930,	16,	{0xb2, 0x90, 0x20, 0x50, 0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2} },
 { 0x1940,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7c, 0xc0, 0x05, 0x86, 0xe5, 0x85} },
 { 0x1950,	16,	{0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xee, 0x30, 0xe7, 0x08, 0x05, 0x86} },
 { 0x1960,	16,	{0xe0, 0x24, 0x38, 0xf0, 0x05, 0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78} },
 { 0x1970,	16,	{0x60, 0x30, 0x03, 0x03, 0x03, 0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0} },
 { 0x1980,	16,	{0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70} },
-{ 0x1990,	16,	{0x11, 0x8b, 0x25, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} },
+{ 0x1990,	16,	{0x11, 0x8b, 0x26, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} },
 { 0x19a0,	16,	{0x80, 0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74} },
 { 0x19b0,	16,	{0x00, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x02, 0x13, 0x43} },
 { 0x19c0,	1,	{0x32} },
@@ -447,630 +447,657 @@
 { 0x1a35,	16,	{0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
 { 0x1a45,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} },
 { 0x1a55,	16,	{0xf0, 0x19, 0x02, 0x1a, 0xdb, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x1a65,	16,	{0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x57, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
+{ 0x1a65,	16,	{0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x59, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
 { 0x1a75,	16,	{0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} },
 { 0x1a85,	16,	{0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1a95,	16,	{0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
+{ 0x1a95,	16,	{0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
 { 0x1aa5,	16,	{0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} },
-{ 0x1ab5,	16,	{0xa0, 0x85, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
+{ 0x1ab5,	16,	{0xa2, 0x4d, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
 { 0x1ac5,	16,	{0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} },
-{ 0x1ad5,	16,	{0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30} },
+{ 0x1ad5,	16,	{0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x59, 0x30, 0xe0, 0xf7, 0x30} },
 { 0x1ae5,	16,	{0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} },
-{ 0x1af5,	16,	{0x19, 0xc7, 0xe5, 0x57, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
+{ 0x1af5,	16,	{0x19, 0xc7, 0xe5, 0x59, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
 { 0x1b05,	6,	{0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} },
 { 0x1b0b,	1,	{0x22} },
-{ 0x1b0c,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x1c, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x02} },
-{ 0x1b1c,	16,	{0x7d, 0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x03, 0x7d, 0xff} },
-{ 0x1b2c,	4,	{0x12, 0x82, 0xa8, 0x22} },
-{ 0x8000,	16,	{0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0xfd, 0x8b, 0x4e, 0x75} },
-{ 0x8010,	16,	{0x4f, 0x12, 0x75, 0x50, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4c} },
-{ 0x8020,	16,	{0xf5, 0x4d, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
+{ 0x1b0c,	16,	{0xe5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x1c, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x7f, 0x02} },
+{ 0x1b1c,	16,	{0x7d, 0xff, 0x12, 0x82, 0xea, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x7f, 0x03, 0x7d, 0xff} },
+{ 0x1b2c,	4,	{0x12, 0x82, 0xea, 0x22} },
+{ 0x8000,	16,	{0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0xa2, 0x20, 0xfd, 0x8b, 0x50, 0x75} },
+{ 0x8010,	16,	{0x51, 0x12, 0x75, 0x52, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4e} },
+{ 0x8020,	16,	{0xf5, 0x4f, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
 { 0x8030,	16,	{0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} },
 { 0x8040,	16,	{0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} },
-{ 0x8050,	16,	{0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4e, 0xaa, 0x4f, 0xa9, 0x50} },
-{ 0x8060,	16,	{0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
-{ 0x8070,	16,	{0x12, 0xa0, 0x58, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58} },
+{ 0x8050,	16,	{0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x50, 0xaa, 0x51, 0xa9, 0x52} },
+{ 0x8060,	16,	{0x90, 0x00, 0x01, 0x12, 0xa2, 0x20, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
+{ 0x8070,	16,	{0x12, 0xa2, 0x20, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0xa2, 0x20} },
 { 0x8080,	16,	{0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x81, 0x16, 0xec, 0xc3, 0x94, 0x10} },
-{ 0x8090,	16,	{0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4d, 0xae, 0x4c, 0x78, 0x02, 0xce} },
+{ 0x8090,	16,	{0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4f, 0xae, 0x4e, 0x78, 0x02, 0xce} },
 { 0x80a0,	16,	{0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
 { 0x80b0,	16,	{0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} },
 { 0x80c0,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} },
-{ 0x80d0,	16,	{0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4d, 0xae, 0x4c, 0x78} },
+{ 0x80d0,	16,	{0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4f, 0xae, 0x4e, 0x78} },
 { 0x80e0,	16,	{0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} },
 { 0x80f0,	16,	{0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} },
 { 0x8100,	16,	{0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} },
-{ 0x8110,	16,	{0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0x25} },
-{ 0x8120,	16,	{0x4d, 0xf5, 0x4d, 0xe4, 0x35, 0x4c, 0xf5, 0x4c, 0x90, 0x00, 0x05, 0x12, 0xa0, 0x58, 0xfe, 0xe4} },
-{ 0x8130,	16,	{0x25, 0x4d, 0xf5, 0x4d, 0xee, 0x35, 0x4c, 0xf5, 0x4c, 0x02, 0x81, 0xb8, 0xab, 0x4e, 0xaa, 0x4f} },
-{ 0x8140,	16,	{0xa9, 0x50, 0x90, 0x00, 0x03, 0x12, 0xa0, 0x58, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
-{ 0x8150,	16,	{0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
+{ 0x8110,	16,	{0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0xa2, 0x20, 0x25} },
+{ 0x8120,	16,	{0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x90, 0x00, 0x05, 0x12, 0xa2, 0x20, 0xfe, 0xe4} },
+{ 0x8130,	16,	{0x25, 0x4f, 0xf5, 0x4f, 0xee, 0x35, 0x4e, 0xf5, 0x4e, 0x02, 0x81, 0xb8, 0xab, 0x50, 0xaa, 0x51} },
+{ 0x8140,	16,	{0xa9, 0x52, 0x90, 0x00, 0x03, 0x12, 0xa2, 0x20, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
+{ 0x8150,	16,	{0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0xa2, 0x20, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
 { 0x8160,	16,	{0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} },
 { 0x8170,	16,	{0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} },
 { 0x8180,	16,	{0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} },
 { 0x8190,	16,	{0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} },
 { 0x81a0,	16,	{0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} },
-{ 0x81b0,	16,	{0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x50, 0xf5, 0x50, 0xe4, 0x35} },
-{ 0x81c0,	16,	{0x4f, 0xf5, 0x4f, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
+{ 0x81b0,	16,	{0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x52, 0xf5, 0x52, 0xe4, 0x35} },
+{ 0x81c0,	16,	{0x51, 0xf5, 0x51, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
 { 0x81d0,	8,	{0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} },
 { 0x81d8,	1,	{0x22} },
-{ 0x81d9,	2,	{0xac, 0x07} },
-{ 0x81db,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xec, 0x25, 0xe0, 0x44, 0x41, 0x90, 0x7f, 0xa6, 0xf0} },
-{ 0x81eb,	16,	{0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90} },
-{ 0x81fb,	16,	{0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0xd4, 0x80, 0xf8, 0x90, 0x7f} },
-{ 0x820b,	16,	{0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xdc, 0x20, 0xe1, 0x09, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} },
-{ 0x821b,	16,	{0xf9, 0x22, 0xed, 0x30, 0xe2, 0x0c, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} },
-{ 0x822b,	16,	{0xfa, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7b, 0x1e} },
-{ 0x823b,	16,	{0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6} },
-{ 0x824b,	16,	{0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0x86, 0x80, 0xf8, 0x90, 0x7f, 0xa5, 0xe0} },
-{ 0x825b,	16,	{0xfd, 0x20, 0xe0, 0xdc, 0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x19, 0x90, 0x7f, 0xa5, 0xe0} },
-{ 0x826b,	16,	{0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03} },
-{ 0x827b,	16,	{0x02, 0x81, 0xdb, 0x80, 0xf5, 0x90, 0x7f, 0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xd9, 0x30, 0xe2, 0x09} },
-{ 0x828b,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x829b,	12,	{0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} },
-{ 0x82a7,	1,	{0x22} },
-{ 0x82a8,	2,	{0xae, 0x07} },
-{ 0x82aa,	16,	{0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
-{ 0x82ba,	16,	{0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
-{ 0x82ca,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
-{ 0x82da,	16,	{0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
-{ 0x82ea,	14,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
-{ 0x82f8,	1,	{0x22} },
-{ 0x82f9,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
-{ 0x8309,	16,	{0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5f, 0x74, 0xbf} },
-{ 0x8319,	16,	{0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x8329,	16,	{0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
-{ 0x8339,	16,	{0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
-{ 0x8349,	16,	{0xef, 0x55, 0x3c, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x8359,	16,	{0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
-{ 0x8369,	16,	{0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5f, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
-{ 0x8379,	4,	{0x83, 0xa3, 0xe9, 0xf0} },
-{ 0x837d,	1,	{0x22} },
-{ 0x837e,	4,	{0x8f, 0x5f, 0x8d, 0x60} },
-{ 0x8382,	16,	{0xe4, 0xf5, 0x61, 0x74, 0x3d, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
-{ 0x8392,	16,	{0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x83a2,	16,	{0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x50} },
-{ 0x83b2,	16,	{0x3c, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} },
-{ 0x83c2,	16,	{0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} },
-{ 0x83d2,	16,	{0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x40, 0x0c, 0x75, 0x61, 0x40, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76} },
-{ 0x83e2,	16,	{0x10, 0x80, 0x0a, 0x75, 0x61, 0x80, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76, 0x38, 0xe5, 0x61, 0x45} },
-{ 0x83f2,	16,	{0x60, 0x44, 0x01, 0xff, 0xe5, 0x5f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x8402,	5,	{0x20, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x8407,	1,	{0x22} },
-{ 0x8408,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x8418,	16,	{0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x8428,	16,	{0x56, 0x8f, 0x57, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
-{ 0x8438,	16,	{0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
-{ 0x8448,	16,	{0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x55, 0xf8, 0xe4, 0xf6, 0xe5, 0x57, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x8458,	16,	{0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e} },
-{ 0x8468,	16,	{0xaf, 0x55, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x85, 0x57, 0x82, 0x85, 0x56, 0x83, 0xa3, 0xa3, 0xe0} },
-{ 0x8478,	16,	{0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83} },
-{ 0x8488,	16,	{0xe0, 0xe5, 0x57, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x55} },
-{ 0x8498,	16,	{0x7d, 0x06, 0x12, 0x83, 0x7e, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
-{ 0x84a8,	16,	{0xe4, 0xf0, 0xe5, 0x55, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} },
-{ 0x84b8,	16,	{0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xef} },
-{ 0x84c8,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x55, 0x74, 0x01} },
-{ 0x84d8,	13,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7f, 0x00} },
-{ 0x84e5,	1,	{0x22} },
-{ 0x84e6,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x84f6,	16,	{0xaf, 0x55, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
-{ 0x8506,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x8516,	16,	{0x20, 0xaf, 0x82, 0xf5, 0x57, 0x8f, 0x58, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
-{ 0x8526,	16,	{0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0xe5} },
-{ 0x8536,	16,	{0x58, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x58} },
-{ 0x8546,	16,	{0x82, 0x85, 0x57, 0x83, 0xe0, 0xf5, 0x56, 0xaf, 0x55, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x8556,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x31, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} },
-{ 0x8566,	16,	{0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} },
-{ 0x8576,	9,	{0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
-{ 0x857f,	1,	{0x22} },
-{ 0x8580,	4,	{0x8e, 0x55, 0x8f, 0x56} },
-{ 0x8584,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x8594,	16,	{0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
-{ 0x85a4,	16,	{0x54, 0x03, 0x70, 0x24, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} },
-{ 0x85b4,	16,	{0x57, 0x7d, 0x02, 0x12, 0x83, 0x7e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe1} },
-{ 0x85c4,	10,	{0x07, 0xaf, 0x57, 0x7d, 0x04, 0x12, 0x83, 0x7e, 0x7f, 0x00} },
-{ 0x85ce,	1,	{0x22} },
-{ 0x85cf,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
-{ 0x85df,	16,	{0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x85ef,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
-{ 0x85ff,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
-{ 0x860f,	16,	{0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
-{ 0x861f,	16,	{0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
-{ 0x862f,	16,	{0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
-{ 0x863f,	16,	{0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x864f,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
-{ 0x865f,	3,	{0x83, 0xf0, 0x22} },
-{ 0x8662,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8666,	16,	{0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
-{ 0x8676,	16,	{0x22, 0x8c, 0x55, 0x8d, 0x56, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x8686,	16,	{0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
-{ 0x8696,	16,	{0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02} },
-{ 0x86a6,	16,	{0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x86b6,	1,	{0x22} },
-{ 0x86b7,	4,	{0x8e, 0x55, 0x8f, 0x56} },
-{ 0x86bb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5c, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x86cb,	16,	{0xe5, 0x5c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x86db,	16,	{0x5d, 0x8f, 0x5e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x86eb,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa1} },
-{ 0x86fb,	16,	{0xb7, 0x40, 0x10, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x00} },
-{ 0x870b,	16,	{0x08, 0x80, 0x2e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x871b,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa1} },
-{ 0x872b,	16,	{0xb7, 0x50, 0x0e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x07, 0x08} },
-{ 0x873b,	16,	{0x00, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
-{ 0x874b,	16,	{0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a} },
-{ 0x875b,	16,	{0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1} },
-{ 0x876b,	16,	{0x25, 0xaf, 0x03, 0x8f, 0x5b, 0xaf, 0x5a, 0xae, 0x59, 0xad, 0x58, 0xac, 0x57, 0x7b, 0x0a, 0x7a} },
-{ 0x877b,	16,	{0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a, 0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57} },
-{ 0x878b,	16,	{0xe5, 0x5b, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x5a, 0x24, 0x01, 0xf5, 0x5a, 0xe4, 0x35, 0x59} },
-{ 0x879b,	16,	{0xf5, 0x59, 0xe4, 0x35, 0x58, 0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0x85, 0x5e, 0x82, 0x85} },
-{ 0x87ab,	16,	{0x5d, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
-{ 0x87bb,	16,	{0x80, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xe5, 0x5a, 0xf0, 0xaf, 0x5a, 0xae, 0x59, 0xad} },
-{ 0x87cb,	16,	{0x58, 0xac, 0x57, 0x78, 0x08, 0x12, 0xa1, 0xc8, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xef} },
-{ 0x87db,	16,	{0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
-{ 0x87eb,	16,	{0x5b, 0xe5, 0x56, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} },
-{ 0x87fb,	16,	{0x05, 0x43, 0x5b, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5b, 0x08, 0x80, 0x11, 0xef} },
-{ 0x880b,	16,	{0xb4, 0x74, 0x05, 0x43, 0x5b, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x881b,	16,	{0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} },
-{ 0x882b,	16,	{0x43, 0x5b, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5b, 0x40, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x883b,	16,	{0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
-{ 0x884b,	16,	{0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5c, 0x74, 0x01} },
-{ 0x885b,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3c, 0xe5, 0x5e, 0x24, 0x04, 0xf5} },
-{ 0x886b,	16,	{0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5b, 0x80, 0x10, 0xaf} },
-{ 0x887b,	16,	{0x5c, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3c, 0x85} },
-{ 0x888b,	16,	{0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
-{ 0x889b,	16,	{0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5b, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x88ab,	16,	{0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83} },
-{ 0x88bb,	16,	{0xef, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
-{ 0x88cb,	16,	{0x5e, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09} },
-{ 0x88db,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
-{ 0x88eb,	16,	{0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5} },
-{ 0x88fb,	16,	{0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x890b,	16,	{0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
-{ 0x891b,	16,	{0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5c, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0x75, 0x5b, 0x08, 0xe5, 0x56} },
-{ 0x892b,	16,	{0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5b, 0x10, 0xe5} },
-{ 0x893b,	16,	{0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5b, 0xf0} },
-{ 0x894b,	16,	{0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} },
-{ 0x895b,	16,	{0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0x06, 0xf5} },
-{ 0x896b,	16,	{0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} },
-{ 0x897b,	16,	{0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} },
-{ 0x898b,	16,	{0xfb, 0x4f, 0xf5, 0x5b, 0xe5, 0x56, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0} },
-{ 0x899b,	16,	{0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} },
-{ 0x89ab,	16,	{0x70, 0x14, 0x43, 0x5b, 0x18, 0x80, 0x12, 0x43, 0x5b, 0x08, 0x80, 0x0d, 0x43, 0x5b, 0x38, 0x80} },
-{ 0x89bb,	16,	{0x08, 0x43, 0x5b, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3} },
-{ 0x89cb,	16,	{0xa3, 0xa3, 0xe5, 0x5b, 0xf0, 0xaf, 0x5c, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0xaa, 0x55, 0xa9, 0x56} },
-{ 0x89db,	16,	{0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5c, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} },
-{ 0x89eb,	15,	{0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0, 0x16, 0x7f, 0x00} },
-{ 0x89fa,	1,	{0x22} },
-{ 0x89fb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8a0b,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
-{ 0x8a1b,	16,	{0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
-{ 0x8a2b,	16,	{0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
-{ 0x8a3b,	16,	{0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8a4b,	16,	{0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
-{ 0x8a5b,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x55, 0xe5, 0x30, 0xc3, 0x94, 0x01} },
-{ 0x8a6b,	16,	{0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x56, 0x00, 0xf5, 0x57, 0x80, 0x09, 0x7f} },
-{ 0x8a7b,	16,	{0x02, 0x12, 0x81, 0xd9, 0x8e, 0x56, 0x8f, 0x57, 0xc3, 0xe5, 0x56, 0x64, 0x80, 0x94, 0x80, 0x40} },
-{ 0x8a8b,	16,	{0xda, 0xe5, 0x55, 0x55, 0x57, 0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12} },
-{ 0x8a9b,	4,	{0x8f, 0x6e, 0x7f, 0x00} },
-{ 0x8a9f,	1,	{0x22} },
-{ 0x8aa0,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8ab0,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
-{ 0x8ac0,	16,	{0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x8ad0,	16,	{0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8f} },
-{ 0x8ae0,	3,	{0x6e, 0x7f, 0x00} },
-{ 0x8ae3,	1,	{0x22} },
-{ 0x8ae4,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8ae8,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8af8,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8b08,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8b18,	16,	{0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8b28,	4,	{0xfd, 0xf0, 0x7f, 0x00} },
-{ 0x8b2c,	1,	{0x22} },
-{ 0x8b2d,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8b31,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8b41,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8b51,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8b61,	16,	{0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8b71,	4,	{0xfe, 0xf0, 0x7f, 0x00} },
-{ 0x8b75,	1,	{0x22} },
-{ 0x8b76,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8b7a,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8b8a,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8b9a,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
-{ 0x8baa,	16,	{0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
-{ 0x8bba,	1,	{0x22} },
-{ 0x8bbb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
-{ 0x8bcb,	16,	{0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0x7f, 0x00} },
-{ 0x8bdb,	1,	{0x22} },
-{ 0x8bdc,	4,	{0x8e, 0x55, 0x8f, 0x56} },
-{ 0x8be0,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x5a, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xd3} },
-{ 0x8bf0,	16,	{0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x57, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
-{ 0x8c00,	16,	{0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x58, 0x7e, 0x75, 0x59} },
-{ 0x8c10,	16,	{0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x58, 0x7e, 0x75, 0x59, 0x00, 0x80, 0x16, 0x7e} },
-{ 0x8c20,	16,	{0x7d, 0x7f, 0x80, 0x75, 0x58, 0x7d, 0x75, 0x59, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
-{ 0x8c30,	16,	{0x58, 0x7d, 0x75, 0x59, 0x00, 0xe5, 0x5a, 0x70, 0x1b, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0x74} },
-{ 0x8c40,	16,	{0xff, 0xf0, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
-{ 0x8c50,	16,	{0x01, 0xf0, 0x80, 0x48, 0xe5, 0x56, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x55, 0xfe, 0xe5, 0x5a, 0x60} },
-{ 0x8c60,	16,	{0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
-{ 0x8c70,	16,	{0x59, 0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
-{ 0x8c80,	16,	{0x15, 0x5a, 0x80, 0xd9, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x57, 0x25} },
-{ 0x8c90,	14,	{0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
-{ 0x8c9e,	1,	{0x22} },
-{ 0x8c9f,	16,	{0xef, 0x24, 0x05, 0xf5, 0x56, 0xe4, 0x3e, 0xf5, 0x55, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
-{ 0x8caf,	16,	{0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3} },
-{ 0x8cbf,	16,	{0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x57, 0xf5, 0x58, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
-{ 0x8ccf,	16,	{0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8d, 0x80} },
-{ 0x8cdf,	16,	{0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0xcc, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe} },
-{ 0x8cef,	16,	{0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x5a, 0x74, 0x01, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a} },
-{ 0x8cff,	16,	{0x94, 0x40, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5} },
-{ 0x8d0f,	16,	{0x58, 0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x50, 0x03, 0x02, 0x8d, 0xcf, 0xae, 0x59, 0xaf, 0x5a} },
-{ 0x8d1f,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
-{ 0x8d2f,	16,	{0x57, 0xf5, 0x58, 0x02, 0x8d, 0xcf, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
-{ 0x8d3f,	16,	{0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a, 0x94} },
-{ 0x8d4f,	16,	{0x10, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x10, 0xd3, 0xe5, 0x58} },
-{ 0x8d5f,	16,	{0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x40, 0x68, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85} },
-{ 0x8d6f,	16,	{0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x80} },
-{ 0x8d7f,	16,	{0x4f, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
-{ 0x8d8f,	16,	{0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0x45, 0x5a, 0x60, 0x0b, 0xd3, 0xe5, 0x5a, 0x94, 0x40, 0xe5} },
-{ 0x8d9f,	16,	{0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5, 0x58, 0x95, 0x5a} },
-{ 0x8daf,	16,	{0xe5, 0x57, 0x95, 0x59, 0x40, 0x17, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
-{ 0x8dbf,	16,	{0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x7f, 0x01, 0x22} },
-{ 0x8dcf,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8e, 0x8f, 0x24, 0xf9} },
-{ 0x8ddf,	16,	{0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0xdf, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8f, 0x23} },
-{ 0x8def,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} },
-{ 0x8dff,	16,	{0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58} },
-{ 0x8e0f,	16,	{0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xe0} },
-{ 0x8e1f,	16,	{0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0} },
-{ 0x8e2f,	16,	{0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
-{ 0x8e3f,	16,	{0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8f} },
-{ 0x8e4f,	16,	{0x23, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x76} },
-{ 0x8e5f,	16,	{0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02} },
-{ 0x8e6f,	16,	{0x8f, 0x23, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8e7f,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} },
-{ 0x8e8f,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} },
-{ 0x8e9f,	16,	{0x94, 0x00, 0x50, 0x03, 0x02, 0x8f, 0x23, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} },
-{ 0x8eaf,	16,	{0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e} },
-{ 0x8ebf,	16,	{0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8ecf,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} },
-{ 0x8edf,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} },
-{ 0x8eef,	16,	{0xa3, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x60, 0x24} },
-{ 0x8eff,	16,	{0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} },
-{ 0x8f0f,	16,	{0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
-{ 0x8f1f,	16,	{0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3} },
-{ 0x8f2f,	11,	{0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
-{ 0x8f3a,	1,	{0x22} },
-{ 0x8f3b,	16,	{0x8e, 0x60, 0x8f, 0x61, 0x8c, 0x62, 0x8d, 0x63, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x61} },
-{ 0x8f4b,	16,	{0xe5, 0x61, 0xae, 0x60, 0x70, 0x02, 0x05, 0x60, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
-{ 0x8f5b,	16,	{0x63, 0xe5, 0x63, 0xac, 0x62, 0x70, 0x02, 0x05, 0x62, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x8f6b,	3,	{0x80, 0xd6, 0x22} },
-{ 0x8f6e,	6,	{0x8d, 0x5b, 0xab, 0x07, 0xaa, 0x06} },
-{ 0x8f74,	16,	{0x75, 0x5f, 0x40, 0x75, 0x5e, 0x0d, 0x75, 0x5d, 0x03, 0x75, 0x5c, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
-{ 0x8f84,	16,	{0x20, 0xe1, 0xf9, 0xaf, 0x5f, 0xae, 0x5e, 0xad, 0x5d, 0xac, 0x5c, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
-{ 0x8f94,	16,	{0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
-{ 0x8fa4,	16,	{0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5b, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xc3} },
-{ 0x8fb4,	8,	{0xe5, 0x5b, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x8fbc,	1,	{0x22} },
-{ 0x8fbd,	16,	{0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0xa3, 0xe5, 0x30, 0xf0, 0x90, 0x0a, 0xf1, 0xe4, 0x93, 0x90} },
-{ 0x8fcd,	16,	{0x01, 0x86, 0xf0, 0x90, 0x0a, 0xf2, 0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c} },
-{ 0x8fdd,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01} },
-{ 0x8fed,	16,	{0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e, 0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84} },
-{ 0x8ffd,	7,	{0x7d, 0x14, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
-{ 0x9004,	1,	{0x22} },
-{ 0x9005,	16,	{0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4c, 0x7b, 0x75, 0x4d, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
-{ 0x9015,	16,	{0x4c, 0x4f, 0x85, 0x4d, 0x50, 0xe5, 0x50, 0x24, 0x01, 0xf5, 0x54, 0xe4, 0x35, 0x4f, 0xf5, 0x53} },
-{ 0x9025,	16,	{0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
-{ 0x9035,	16,	{0x5b, 0x90, 0x90, 0x3d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x90, 0x61, 0x02, 0x90, 0x61, 0x02, 0x90} },
-{ 0x9045,	16,	{0x6b, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x89, 0x02, 0x90, 0x61} },
-{ 0x9055,	16,	{0x02, 0x90, 0x7f, 0x02, 0x90, 0x61, 0x02, 0x90, 0x91, 0x02, 0x90, 0x61, 0xef, 0x64, 0x02, 0x60} },
-{ 0x9065,	16,	{0x2b, 0x75, 0x4e, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4e, 0xff, 0x80, 0x1c} },
-{ 0x9075,	16,	{0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4e, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
-{ 0x9085,	16,	{0x4e, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x60, 0x15} },
-{ 0x9095,	16,	{0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
-{ 0x90a5,	16,	{0x8f, 0x6e, 0xaf, 0x4e, 0x22, 0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0x14} },
-{ 0x90b5,	16,	{0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0xd3, 0x90, 0x90, 0xc4, 0xf8, 0x28, 0x28, 0x73, 0x02} },
-{ 0x90c5,	16,	{0x90, 0xf1, 0x02, 0x90, 0xfd, 0x02, 0x91, 0x09, 0x02, 0x91, 0x57, 0x02, 0x91, 0x62, 0x02, 0x91} },
-{ 0x90d5,	16,	{0x6d, 0x02, 0x91, 0x78, 0x02, 0x91, 0x83, 0x02, 0x91, 0x8e, 0x02, 0x91, 0x99, 0x02, 0x91, 0xa4} },
-{ 0x90e5,	16,	{0x02, 0x91, 0xab, 0x02, 0x91, 0xd3, 0x02, 0x91, 0xb6, 0x02, 0x91, 0xc1, 0xaf, 0x54, 0xae, 0x53} },
-{ 0x90f5,	16,	{0x12, 0x84, 0x08, 0x8f, 0x4e, 0x02, 0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x84, 0xe6, 0x8f} },
-{ 0x9105,	16,	{0x4e, 0x02, 0x91, 0xd6, 0x85, 0x53, 0x51, 0x85, 0x54, 0x52, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4} },
-{ 0x9115,	16,	{0x35, 0x51, 0xfe, 0x12, 0x85, 0xcf, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0x62, 0x8f, 0x4e, 0xef} },
-{ 0x9125,	16,	{0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0xd6, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0xb7, 0x8f, 0x4e} },
-{ 0x9135,	16,	{0xe5, 0x4e, 0x70, 0x03, 0x02, 0x91, 0xd6, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0x75, 0xf0} },
-{ 0x9145,	16,	{0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0xb7, 0x02} },
-{ 0x9155,	16,	{0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xe4, 0x8f, 0x4e, 0x80, 0x74, 0xaf, 0x54, 0xae} },
-{ 0x9165,	16,	{0x53, 0x12, 0x8b, 0x2d, 0x8f, 0x4e, 0x80, 0x69, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0x76, 0x8f} },
-{ 0x9175,	16,	{0x4e, 0x80, 0x5e, 0xaf, 0x4d, 0xae, 0x4c, 0x12, 0x8c, 0x9f, 0x8f, 0x4e, 0x80, 0x53, 0xaf, 0x54} },
-{ 0x9185,	16,	{0xae, 0x53, 0x12, 0x89, 0xfb, 0x8f, 0x4e, 0x80, 0x48, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x85, 0x80} },
-{ 0x9195,	16,	{0x8f, 0x4e, 0x80, 0x3d, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xa0, 0x8f, 0x4e, 0x80, 0x32, 0x12} },
-{ 0x91a5,	16,	{0x8f, 0xbd, 0x8f, 0x4e, 0x80, 0x2b, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xbb, 0x8f, 0x4e, 0x80} },
-{ 0x91b5,	16,	{0x20, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xdc, 0x8f, 0x4e, 0x80, 0x15, 0xaf, 0x4d, 0xae, 0x4c} },
-{ 0x91c5,	16,	{0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8f, 0x3b, 0xe4, 0xf5, 0x4e, 0x80, 0x03, 0x75, 0x4e} },
-{ 0x91d5,	16,	{0xff, 0xe5, 0x4e, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x50, 0x82, 0x85, 0x4f} },
-{ 0x91e5,	16,	{0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8f, 0x6e, 0xaf} },
-{ 0x91f5,	16,	{0x4e, 0x22, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
-{ 0x9205,	16,	{0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x54, 0x82, 0x85} },
-{ 0x9215,	16,	{0x53, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8f, 0x6e} },
-{ 0x9225,	4,	{0x8f, 0x4e, 0xaf, 0x4e} },
-{ 0x9229,	1,	{0x22} },
-{ 0x922a,	8,	{0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c} },
-{ 0x9232,	16,	{0x75, 0x56, 0x01, 0x75, 0x57, 0x9c, 0xe4, 0xf5, 0x55, 0xaf, 0x51, 0x15, 0x51, 0xef, 0x70, 0x03} },
-{ 0x9242,	16,	{0x02, 0x92, 0xc8, 0xaf, 0x50, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4f} },
-{ 0x9252,	16,	{0xae, 0x4e, 0xad, 0x4d, 0xac, 0x4c, 0x12, 0xa1, 0x25, 0xaf, 0x03, 0x8f, 0x54, 0xaf, 0x4f, 0xae} },
-{ 0x9262,	16,	{0x4e, 0xad, 0x4d, 0xac, 0x4c, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x50, 0xe4} },
-{ 0x9272,	16,	{0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
-{ 0x9282,	16,	{0x12, 0xa1, 0x25, 0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c, 0xe5, 0x54, 0x24, 0x30, 0xf5} },
-{ 0x9292,	16,	{0x54, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x54, 0xf5, 0x54, 0x05, 0x57, 0xe5, 0x57} },
-{ 0x92a2,	16,	{0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x57, 0xe5} },
-{ 0x92b2,	16,	{0x57, 0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x54, 0xf0, 0x05} },
-{ 0x92c2,	16,	{0x55, 0x05, 0x55, 0x02, 0x92, 0x3b, 0xe5, 0x57, 0x15, 0x57, 0x70, 0x02, 0x15, 0x56, 0xaf, 0x55} },
-{ 0x92d2,	16,	{0x15, 0x55, 0xef, 0x60, 0x23, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0xf5} },
-{ 0x92e2,	16,	{0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14} },
-{ 0x92f2,	8,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
-{ 0x92fa,	1,	{0x22} },
-{ 0x92fb,	16,	{0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
-{ 0x930b,	10,	{0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
-{ 0x9315,	16,	{0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
-{ 0x9325,	16,	{0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
-{ 0x9335,	16,	{0xe4, 0xef, 0x55, 0x31, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x9345,	16,	{0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
-{ 0x9355,	16,	{0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x9365,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x9375,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x9385,	1,	{0x22} },
-{ 0x9386,	16,	{0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x9396,	16,	{0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
-{ 0x93a6,	16,	{0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
-{ 0x93b6,	16,	{0xa0, 0x16, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x93c6,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x93d6,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x93e6,	1,	{0x22} },
-{ 0x93e7,	16,	{0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x51, 0x7b, 0x75, 0x52} },
-{ 0x93f7,	16,	{0x80, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x51, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x53, 0xf5} },
-{ 0x9407,	16,	{0x54, 0x89, 0x55, 0xfe, 0x12, 0x93, 0x86, 0xef, 0x60, 0x50, 0xab, 0x53, 0xaa, 0x54, 0xa9, 0x55} },
-{ 0x9417,	16,	{0x12, 0xa0, 0x3f, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
-{ 0x9427,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
-{ 0x9437,	16,	{0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
-{ 0x9447,	16,	{0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x31, 0x60, 0x0f, 0x85, 0x52, 0x82, 0x85, 0x51} },
-{ 0x9457,	10,	{0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
-{ 0x9461,	1,	{0x22} },
-{ 0x9462,	16,	{0x12, 0x93, 0xe7, 0xe4, 0xf5, 0x4c, 0x74, 0x37, 0x25, 0x4c, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4d} },
-{ 0x9472,	16,	{0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0xff, 0xc4} },
-{ 0x9482,	16,	{0x54, 0x0f, 0xf5, 0x4e, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
-{ 0x9492,	16,	{0x83, 0xe5, 0x4d, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0xe5, 0x4d, 0x45, 0x4e, 0xfb, 0x12, 0x93, 0x15} },
-{ 0x94a2,	16,	{0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
-{ 0x94b2,	16,	{0xb5, 0x12, 0x93, 0xe7, 0xe5, 0x3b, 0x60, 0x48, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x74, 0x01, 0xa8} },
-{ 0x94c2,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x55, 0x3b, 0x60, 0x29, 0xe5, 0x4c} },
-{ 0x94d2,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
-{ 0x94e2,	16,	{0x16, 0xaf, 0x4c, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7} },
-{ 0x94f2,	16,	{0x80, 0xef, 0xe5, 0x4d, 0xf4, 0x52, 0x3b, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
-{ 0x9502,	16,	{0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0xe3, 0x74, 0x19, 0xf0, 0xe5, 0x30, 0xc3, 0x94} },
-{ 0x9512,	16,	{0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00, 0xf5, 0x50, 0x80, 0x09} },
-{ 0x9522,	16,	{0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f, 0x64, 0x80, 0x94, 0x80} },
-{ 0x9532,	16,	{0x40, 0xda, 0x90, 0x01, 0xbc, 0xe0, 0x65, 0x50, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c} },
-{ 0x9542,	16,	{0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xbc} },
-{ 0x9552,	16,	{0xe0, 0x55, 0x4d, 0x60, 0x14, 0xaf, 0x4c, 0x7d, 0x08, 0xe5, 0x4d, 0x55, 0x50, 0xfb, 0x12, 0x93} },
-{ 0x9562,	16,	{0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04} },
-{ 0x9572,	16,	{0x40, 0xcc, 0x90, 0x01, 0xbc, 0xe5, 0x50, 0xf0, 0xe4, 0xf5, 0x4c, 0xc2, 0xaf, 0x74, 0x33, 0x25} },
-{ 0x9582,	16,	{0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4d, 0x1e, 0xe5, 0x4d, 0x60, 0x11} },
-{ 0x9592,	16,	{0xaf, 0x4c, 0x7d, 0x02, 0xab, 0x4d, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80} },
-{ 0x95a2,	16,	{0xef, 0x74, 0x2c, 0x25, 0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82, 0xe4} },
-{ 0x95b2,	16,	{0x34, 0x02, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0x60, 0x11, 0xaf, 0x4c, 0x7d, 0x04, 0xab, 0x4d, 0x12} },
-{ 0x95c2,	16,	{0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82} },
-{ 0x95d2,	16,	{0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
-{ 0x95e2,	4,	{0x9a, 0x12, 0x93, 0xe7} },
-{ 0x95e6,	1,	{0x22} },
-{ 0x95e7,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x63, 0x02, 0x96, 0x2e} },
-{ 0x95f3,	16,	{0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x9603,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x9613,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x9623,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x96, 0x73, 0xe4, 0x7e} },
-{ 0x9633,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x9643,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x9653,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x9663,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x9673,	16,	{0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
-{ 0x9683,	16,	{0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
-{ 0x9693,	8,	{0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
-{ 0x969b,	1,	{0x00} },
-{ 0x969c,	8,	{0x8b, 0x57, 0x8a, 0x58, 0x89, 0x59, 0x8d, 0x5a} },
-{ 0x96a4,	16,	{0xe4, 0xf5, 0x5b, 0xf5, 0x5c, 0xaf, 0x5a, 0x15, 0x5a, 0xef, 0x60, 0x36, 0xab, 0x57, 0x05, 0x59} },
-{ 0x96b4,	16,	{0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf9, 0x12, 0xa0, 0x3f, 0xff, 0xe5, 0x5b} },
-{ 0x96c4,	16,	{0xe5, 0x5c, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0x99, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
-{ 0x96d4,	16,	{0x9c, 0xf5, 0x83, 0xe5, 0x5b, 0xff, 0xe4, 0x93, 0xf5, 0x5b, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x5c} },
-{ 0x96e4,	6,	{0x80, 0xc3, 0xae, 0x5b, 0xaf, 0x5c} },
-{ 0x96ea,	1,	{0x22} },
-{ 0x96eb,	11,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
-{ 0x96f6,	16,	{0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
-{ 0x9706,	16,	{0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
-{ 0x9716,	16,	{0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
-{ 0x9726,	10,	{0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
-{ 0x9730,	9,	{0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x9739,	2,	{0xa9, 0x03} },
-{ 0x973b,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
-{ 0x974b,	16,	{0x5a, 0x45, 0x5b, 0xf5, 0x5c, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x975b,	16,	{0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
-{ 0x976b,	16,	{0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x5c, 0xeb} },
-{ 0x977b,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x5c, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
-{ 0x978b,	16,	{0x05, 0x22, 0xe5, 0x5a, 0x5c, 0xfe, 0xe5, 0x5b, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
-{ 0x979b,	16,	{0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
-{ 0x97ab,	16,	{0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x5a, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x5b, 0x22, 0x7f} },
-{ 0x97bb,	1,	{0x00} },
-{ 0x97bc,	1,	{0x22} },
-{ 0x97bd,	16,	{0x75, 0x53, 0x02, 0x75, 0x54, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x54, 0x82, 0x85} },
-{ 0x97cd,	16,	{0x53, 0x83, 0xa3, 0xe0, 0xff, 0x90, 0x03, 0x37, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0} },
-{ 0x97dd,	16,	{0x90, 0x03, 0x36, 0xf0, 0x90, 0x03, 0x38, 0x74, 0xff, 0xf0, 0x75, 0x55, 0x03, 0x75, 0x56, 0x39} },
-{ 0x97ed,	16,	{0xef, 0x14, 0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9c, 0x61, 0x90, 0x97, 0xfe, 0xf8, 0x28, 0x28} },
-{ 0x97fd,	16,	{0x73, 0x02, 0x98, 0x1f, 0x02, 0x98, 0xbe, 0x02, 0x99, 0xc3, 0x02, 0x99, 0xe2, 0x02, 0x99, 0xe2} },
-{ 0x980d,	16,	{0x02, 0x9a, 0x98, 0x02, 0x9a, 0xd3, 0x02, 0x9a, 0xf8, 0x02, 0x9b, 0xb6, 0x02, 0x9b, 0xe6, 0x02} },
-{ 0x981d,	16,	{0x9c, 0x12, 0xe4, 0xf5, 0x4c, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} },
-{ 0x982d,	16,	{0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74} },
-{ 0x983d,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4d, 0x80, 0x0d, 0x74} },
-{ 0x984d,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4d, 0xe5, 0x52, 0x24, 0x07} },
-{ 0x985d,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0xe0, 0xf5, 0x4e, 0x65, 0x4d, 0x60} },
-{ 0x986d,	16,	{0x38, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55} },
-{ 0x987d,	16,	{0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x56, 0xe5, 0x56, 0xac} },
-{ 0x988d,	16,	{0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4d, 0xf0, 0x85, 0x56, 0x82} },
-{ 0x989d,	16,	{0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64} },
-{ 0x98ad,	16,	{0x02, 0x70, 0x87, 0x05, 0x4c, 0xe5, 0x4c, 0x64, 0x04, 0x60, 0x03, 0x02, 0x98, 0x22, 0x02, 0x9c} },
-{ 0x98bd,	16,	{0x67, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x05, 0x4c, 0xe5, 0x4c, 0xd3} },
-{ 0x98cd,	16,	{0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0xeb, 0xf0, 0xe4, 0xf5} },
-{ 0x98dd,	16,	{0x4e, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0xf5, 0x4c, 0xaf, 0x4c, 0x74} },
-{ 0x98ed,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xc4, 0xf0} },
-{ 0x98fd,	16,	{0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3} },
-{ 0x990d,	16,	{0x74, 0x02, 0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4d, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02} },
-{ 0x991d,	16,	{0xa3, 0xe0, 0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5, 0x56} },
-{ 0x992d,	16,	{0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56, 0x82} },
-{ 0x993d,	16,	{0x85, 0x55, 0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4e, 0xff, 0x90, 0x01} },
-{ 0x994d,	16,	{0xc4, 0xe0, 0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfe, 0x05, 0x56} },
-{ 0x995d,	16,	{0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05} },
-{ 0x996d,	16,	{0x56, 0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x997d,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4d, 0xf0, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x70, 0x16} },
-{ 0x998d,	16,	{0x74, 0x08, 0x25, 0x52, 0xf5, 0x52, 0xe4, 0x35, 0x51, 0xf5, 0x51, 0x05, 0x4c, 0xe5, 0x4c, 0x64} },
-{ 0x999d,	16,	{0x04, 0x60, 0x03, 0x02, 0x98, 0xea, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
-{ 0x99ad,	16,	{0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3} },
-{ 0x99bd,	16,	{0x74, 0x12, 0xf0, 0x02, 0x9c, 0x67, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0, 0x14, 0xff, 0x74} },
-{ 0x99cd,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01} },
-{ 0x99dd,	16,	{0xc4, 0xf0, 0x02, 0x9c, 0x67, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4} },
-{ 0x99ed,	16,	{0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01} },
-{ 0x99fd,	16,	{0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x56, 0x82, 0x85} },
-{ 0x9a0d,	16,	{0x55, 0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4e, 0xe5, 0x4e, 0x60, 0x03, 0x02, 0x9c, 0x67, 0x90, 0x01} },
-{ 0x9a1d,	16,	{0xc0, 0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6} },
-{ 0x9a2d,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00} },
-{ 0x9a3d,	16,	{0xf5, 0x50, 0x80, 0x09, 0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f} },
-{ 0x9a4d,	16,	{0x64, 0x80, 0x94, 0x80, 0x40, 0xda, 0xe5, 0x50, 0x54, 0x0f, 0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0} },
-{ 0x9a5d,	16,	{0x55, 0x4e, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4d, 0x85, 0x54, 0x82, 0x85} },
-{ 0x9a6d,	16,	{0x53, 0x83, 0xa3, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
-{ 0x9a7d,	16,	{0x00, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x03, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x85} },
-{ 0x9a8d,	16,	{0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0xff, 0xfd, 0x12, 0x82} },
-{ 0x9a9d,	16,	{0xf9, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0x85, 0x52, 0x82, 0x85, 0x51} },
-{ 0x9aad,	16,	{0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0x74, 0x01} },
-{ 0x9abd,	16,	{0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f} },
-{ 0x9acd,	16,	{0xf0, 0xd2, 0x04, 0x02, 0x9c, 0x67, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75} },
-{ 0x9add,	16,	{0x52, 0x00, 0xe5, 0x52, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
-{ 0x9aed,	16,	{0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x02, 0x9c, 0x67, 0xe4, 0xf5, 0x4e, 0xf5, 0x4c} },
-{ 0x9afd,	16,	{0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5} },
-{ 0x9b0d,	16,	{0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04} },
-{ 0x9b1d,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0x7b} },
-{ 0x9b2d,	16,	{0x01, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x11} },
-{ 0x9b3d,	16,	{0xaf, 0x4c, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x5a, 0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f} },
-{ 0x9b4d,	16,	{0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x01, 0xfb, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40} },
-{ 0x9b5d,	16,	{0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x02, 0xfb, 0x75, 0x5a} },
-{ 0x9b6d,	16,	{0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
-{ 0x9b7d,	16,	{0xe5, 0x4e, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5} },
-{ 0x9b8d,	16,	{0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56} },
-{ 0x9b9d,	16,	{0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94} },
-{ 0x9bad,	16,	{0x03, 0x50, 0x03, 0x02, 0x9a, 0xfd, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
-{ 0x9bbd,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x9c, 0xf0, 0xa3, 0x74} },
-{ 0x9bcd,	16,	{0x89, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0xcc, 0xef, 0x64, 0x08, 0x70, 0x03, 0x02, 0x9c} },
-{ 0x9bdd,	16,	{0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
-{ 0x9bed,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x55, 0xf0, 0xa3, 0xe5} },
-{ 0x9bfd,	16,	{0x56, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x5c, 0xe4, 0x90} },
-{ 0x9c0d,	16,	{0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x54, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x53, 0xfa, 0xa9, 0x07} },
-{ 0x9c1d,	16,	{0x7b, 0x01, 0x7d, 0x10, 0x12, 0x96, 0x9c, 0xef, 0x4e, 0x70, 0x32, 0x90, 0x03, 0x59, 0xf0, 0xa3} },
-{ 0x9c2d,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x54, 0x24, 0x02, 0x90} },
-{ 0x9c3d,	16,	{0x03, 0x60, 0xf0, 0xe4, 0x35, 0x53, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10} },
-{ 0x9c4d,	16,	{0xcc, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x0d, 0xe4, 0x90, 0x03} },
-{ 0x9c5d,	16,	{0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3} },
-{ 0x9c6d,	16,	{0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7e, 0x03, 0x7f} },
-{ 0x9c7d,	11,	{0x35, 0x7d, 0x24, 0x12, 0x8f, 0x6e, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
-{ 0x9c88,	1,	{0x22} },
-{ 0x9c89,	16,	{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
-{ 0x9c99,	16,	{0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
-{ 0x9ca9,	16,	{0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
-{ 0x9cb9,	16,	{0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
-{ 0x9cc9,	16,	{0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
-{ 0x9cd9,	16,	{0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
-{ 0x9ce9,	16,	{0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
-{ 0x9cf9,	16,	{0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
-{ 0x9d09,	16,	{0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
-{ 0x9d19,	16,	{0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
-{ 0x9d29,	16,	{0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
-{ 0x9d39,	16,	{0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
-{ 0x9d49,	16,	{0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
-{ 0x9d59,	16,	{0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
-{ 0x9d69,	16,	{0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
-{ 0x9d79,	16,	{0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
-{ 0x9d89,	16,	{0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
-{ 0x9d99,	16,	{0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
-{ 0x9da9,	16,	{0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
-{ 0x9db9,	16,	{0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
-{ 0x9dc9,	16,	{0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
-{ 0x9dd9,	16,	{0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
-{ 0x9de9,	16,	{0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
-{ 0x9df9,	16,	{0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
-{ 0x9e09,	16,	{0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
-{ 0x9e19,	16,	{0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
-{ 0x9e29,	16,	{0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
-{ 0x9e39,	16,	{0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
-{ 0x9e49,	16,	{0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
-{ 0x9e59,	16,	{0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
-{ 0x9e69,	16,	{0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
-{ 0x9e79,	16,	{0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
-{ 0x9e89,	16,	{0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
-{ 0x9e99,	16,	{0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
-{ 0x9ea9,	16,	{0x9f, 0x3c, 0x74, 0x37, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9f, 0x3c, 0xef, 0x75, 0xf0} },
-{ 0x9eb9,	16,	{0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
-{ 0x9ec9,	16,	{0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
-{ 0x9ed9,	16,	{0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
-{ 0x9ee9,	16,	{0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
-{ 0x9ef9,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
-{ 0x9f09,	16,	{0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
-{ 0x9f19,	16,	{0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
-{ 0x9f29,	16,	{0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
-{ 0x9f39,	12,	{0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9e, 0x9b} },
-{ 0x9f45,	1,	{0x22} },
-{ 0x9f46,	16,	{0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
-{ 0x9f56,	16,	{0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
-{ 0x9f66,	16,	{0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
-{ 0x9f76,	16,	{0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
-{ 0x9f86,	16,	{0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
-{ 0x9f96,	16,	{0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
-{ 0x9fa6,	16,	{0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
-{ 0x9fb6,	16,	{0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
-{ 0x9fc6,	16,	{0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
-{ 0x9fd6,	16,	{0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
-{ 0x9fe6,	16,	{0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
-{ 0x9ff6,	16,	{0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
-{ 0xa006,	16,	{0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
-{ 0xa016,	16,	{0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
-{ 0xa026,	16,	{0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
-{ 0xa036,	9,	{0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9f, 0x96, 0x73} },
-{ 0xa03f,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0xa04f,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0xa058,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0xa068,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0xa078,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0xa085,	16,	{0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
-{ 0xa095,	6,	{0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
-{ 0xa09b,	16,	{0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
-{ 0xa0ab,	6,	{0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
-{ 0xa0b1,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0xa0c1,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0xa0d1,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0xa0e1,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0xa0e9,	16,	{0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
-{ 0xa0f9,	16,	{0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
-{ 0xa109,	16,	{0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
-{ 0xa119,	16,	{0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
-{ 0xa129,	16,	{0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
-{ 0xa139,	16,	{0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
-{ 0xa149,	16,	{0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
-{ 0xa159,	16,	{0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
-{ 0xa169,	16,	{0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
-{ 0xa179,	16,	{0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
-{ 0xa189,	16,	{0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
-{ 0xa199,	16,	{0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
-{ 0xa1a9,	14,	{0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
-{ 0xa1b7,	16,	{0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
-{ 0xa1c7,	1,	{0x22} },
-{ 0xa1c8,	16,	{0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
-{ 0xa1d8,	3,	{0xd8, 0xf1, 0x22} },
-{ 0xa1db,	16,	{0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
-{ 0xa1eb,	7,	{0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
-{ 0xa1f2,	12,	{0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
-{ 0xa1fe,	16,	{0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa2, 0x15, 0x12, 0xa2, 0x15, 0x12} },
-{ 0xa20e,	16,	{0xa2, 0x15, 0x12, 0xa2, 0x15, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
-{ 0xa21e,	16,	{0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
-{ 0xa22e,	1,	{0x22} },
+{ 0x81d9,	4,	{0x8e, 0x59, 0x8f, 0x5a} },
+{ 0x81dd,	16,	{0x75, 0x5b, 0x03, 0xe5, 0x5a, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x59, 0xf5, 0x83, 0xe0, 0xfe} },
+{ 0x81ed,	16,	{0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x82, 0xe7, 0xe5, 0x5b, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
+{ 0x81fd,	16,	{0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x82, 0x8b, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
+{ 0x820d,	16,	{0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
+{ 0x821d,	16,	{0x80, 0x6c, 0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
+{ 0x822d,	16,	{0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x5b, 0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3} },
+{ 0x823d,	16,	{0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x5a, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x824d,	16,	{0xe4, 0x35, 0x59, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82, 0xf5} },
+{ 0x825d,	16,	{0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x5a, 0x24} },
+{ 0x826d,	16,	{0x04, 0xf5, 0x82, 0xe4, 0x35, 0x59, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0xa2, 0x4d, 0x85} },
+{ 0x827d,	16,	{0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x4d, 0x90, 0x7f} },
+{ 0x828d,	16,	{0xa5, 0xe0, 0xf5, 0x5c, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
+{ 0x829d,	16,	{0x22, 0xe5, 0x5c, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
+{ 0x82ad,	16,	{0xe5, 0x5b, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x82bd,	16,	{0x80, 0xf0, 0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
+{ 0x82cd,	16,	{0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x5c, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
+{ 0x82dd,	12,	{0x5b, 0x03, 0x02, 0x81, 0xe0, 0x15, 0x5b, 0x02, 0x81, 0xe0, 0x7f, 0x08} },
+{ 0x82e9,	1,	{0x22} },
+{ 0x82ea,	2,	{0xae, 0x07} },
+{ 0x82ec,	16,	{0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
+{ 0x82fc,	16,	{0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
+{ 0x830c,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
+{ 0x831c,	16,	{0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
+{ 0x832c,	14,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
+{ 0x833a,	1,	{0x22} },
+{ 0x833b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
+{ 0x834b,	15,	{0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x835a,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
+{ 0x836a,	16,	{0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x61, 0x74, 0xbf} },
+{ 0x837a,	16,	{0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x838a,	16,	{0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
+{ 0x839a,	16,	{0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
+{ 0x83aa,	16,	{0xef, 0x55, 0x31, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x83ba,	16,	{0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
+{ 0x83ca,	16,	{0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x61, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
+{ 0x83da,	4,	{0x83, 0xa3, 0xe9, 0xf0} },
+{ 0x83de,	1,	{0x22} },
+{ 0x83df,	4,	{0x8f, 0x61, 0x8d, 0x62} },
+{ 0x83e3,	16,	{0xe4, 0xf5, 0x67, 0x74, 0x3f, 0x2f, 0xf8, 0x76, 0x08, 0x7f, 0x80, 0x7e, 0x25, 0x7d, 0x00, 0x7c} },
+{ 0x83f3,	16,	{0x00, 0xab, 0x66, 0xaa, 0x65, 0xa9, 0x64, 0xa8, 0x63, 0xd3, 0x12, 0xa3, 0x7f, 0x40, 0x26, 0x7f} },
+{ 0x8403,	16,	{0x00, 0x7e, 0x96, 0x7d, 0x00, 0x7c, 0x00, 0xa8, 0x63, 0xd3, 0x12, 0xa3, 0x7f, 0x50, 0x0c, 0x75} },
+{ 0x8413,	16,	{0x67, 0x40, 0x74, 0x3f, 0x25, 0x61, 0xf8, 0x76, 0x10, 0x80, 0x0a, 0x75, 0x67, 0x80, 0x74, 0x3f} },
+{ 0x8423,	16,	{0x25, 0x61, 0xf8, 0x76, 0x38, 0xe5, 0x67, 0x45, 0x62, 0x44, 0x01, 0xff, 0xe5, 0x61, 0x75, 0xf0} },
+{ 0x8433,	13,	{0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x8440,	1,	{0x22} },
+{ 0x8441,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8451,	16,	{0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x8461,	16,	{0x58, 0x8f, 0x59, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
+{ 0x8471,	16,	{0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
+{ 0x8481,	16,	{0x83, 0xe4, 0xf0, 0x74, 0x23, 0x25, 0x57, 0xf8, 0xe4, 0xf6, 0xe5, 0x59, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x8491,	16,	{0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
+{ 0x84a1,	16,	{0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x84b1,	16,	{0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63, 0x7d, 0x06, 0xaf, 0x57, 0x12, 0x83} },
+{ 0x84c1,	16,	{0xdf, 0xaf, 0x57, 0x7d, 0x01, 0x12, 0x83, 0x5a, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0xa3, 0xa3} },
+{ 0x84d1,	16,	{0xe0, 0x20, 0xe0, 0x43, 0xe0, 0xff, 0xe5, 0x59, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5} },
+{ 0x84e1,	16,	{0x83, 0xe0, 0xe5, 0x59, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
+{ 0x84f1,	16,	{0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc} },
+{ 0x8501,	16,	{0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63} },
+{ 0x8511,	16,	{0x7d, 0x06, 0xaf, 0x57, 0x12, 0x83, 0xdf, 0x74, 0xf8, 0x25, 0x57, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
+{ 0x8521,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x57, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40} },
+{ 0x8531,	16,	{0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x57, 0x25, 0xe0} },
+{ 0x8541,	16,	{0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x57} },
+{ 0x8551,	15,	{0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x34, 0x7f, 0x00} },
+{ 0x8560,	1,	{0x22} },
+{ 0x8561,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8571,	16,	{0xaf, 0x57, 0xe4, 0xfd, 0x12, 0x83, 0x5a, 0x74, 0xf8, 0x25, 0x57, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
+{ 0x8581,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8591,	16,	{0x20, 0xaf, 0x82, 0xf5, 0x59, 0x8f, 0x5a, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
+{ 0x85a1,	16,	{0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x0c} },
+{ 0x85b1,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
+{ 0x85c1,	16,	{0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x85d1,	16,	{0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63, 0x7d, 0x06, 0xaf, 0x57, 0x12, 0x83} },
+{ 0x85e1,	16,	{0xdf, 0xe5, 0x5a, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x59, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09} },
+{ 0x85f1,	16,	{0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xe0, 0xf5, 0x58, 0xaf, 0x57, 0x74, 0x01, 0xa8, 0x07, 0x08} },
+{ 0x8601,	16,	{0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x34, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc6, 0xf5} },
+{ 0x8611,	16,	{0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc7} },
+{ 0x8621,	11,	{0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
+{ 0x862c,	1,	{0x22} },
+{ 0x862d,	4,	{0x8e, 0x57, 0x8f, 0x58} },
+{ 0x8631,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x59, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8641,	16,	{0xe5, 0x59, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
+{ 0x8651,	16,	{0x54, 0x03, 0x70, 0x66, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x28, 0xe5} },
+{ 0x8661,	16,	{0x59, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc} },
+{ 0x8671,	16,	{0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63} },
+{ 0x8681,	16,	{0x7d, 0x02, 0xaf, 0x59, 0x12, 0x83, 0xdf, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0x30} },
+{ 0x8691,	16,	{0xe1, 0x28, 0xe5, 0x59, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5} },
+{ 0x86a1,	16,	{0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d} },
+{ 0x86b1,	12,	{0x64, 0x8c, 0x63, 0x7d, 0x04, 0xaf, 0x59, 0x12, 0x83, 0xdf, 0x7f, 0x00} },
+{ 0x86bd,	1,	{0x22} },
+{ 0x86be,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
+{ 0x86ce,	16,	{0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x86de,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
+{ 0x86ee,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
+{ 0x86fe,	16,	{0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
+{ 0x870e,	16,	{0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
+{ 0x871e,	16,	{0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
+{ 0x872e,	16,	{0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x873e,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
+{ 0x874e,	3,	{0x83, 0xf0, 0x22} },
+{ 0x8751,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8755,	16,	{0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
+{ 0x8765,	16,	{0x22, 0x8c, 0x57, 0x8d, 0x58, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8775,	16,	{0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
+{ 0x8785,	16,	{0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x58, 0xe5, 0x58, 0xaa, 0x57, 0x70, 0x02} },
+{ 0x8795,	16,	{0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x87a5,	1,	{0x22} },
+{ 0x87a6,	4,	{0x8e, 0x57, 0x8f, 0x58} },
+{ 0x87aa,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5e, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x87ba,	16,	{0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x87ca,	16,	{0x5f, 0x8f, 0x60, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x87da,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa3} },
+{ 0x87ea,	16,	{0x7f, 0x40, 0x10, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0x12, 0xa3, 0xc6, 0x00, 0x00, 0x00} },
+{ 0x87fa,	16,	{0x08, 0x80, 0x2e, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x880a,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa3} },
+{ 0x881a,	16,	{0x7f, 0x50, 0x0e, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0x12, 0xa3, 0xc6, 0x00, 0x07, 0x08} },
+{ 0x882a,	16,	{0x00, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
+{ 0x883a,	16,	{0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa2, 0xed, 0x8f, 0x5c} },
+{ 0x884a,	16,	{0x8e, 0x5b, 0x8d, 0x5a, 0x8c, 0x59, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa2} },
+{ 0x885a,	16,	{0xed, 0xaf, 0x03, 0x8f, 0x5d, 0xaf, 0x5c, 0xae, 0x5b, 0xad, 0x5a, 0xac, 0x59, 0x7b, 0x0a, 0x7a} },
+{ 0x886a,	16,	{0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa2, 0xed, 0x8f, 0x5c, 0x8e, 0x5b, 0x8d, 0x5a, 0x8c, 0x59} },
+{ 0x887a,	16,	{0xe5, 0x5d, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x5c, 0x24, 0x01, 0xf5, 0x5c, 0xe4, 0x35, 0x5b} },
+{ 0x888a,	16,	{0xf5, 0x5b, 0xe4, 0x35, 0x5a, 0xf5, 0x5a, 0xe4, 0x35, 0x59, 0xf5, 0x59, 0x85, 0x60, 0x82, 0x85} },
+{ 0x889a,	16,	{0x5f, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
+{ 0x88aa,	16,	{0x80, 0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xe5, 0x5c, 0xf0, 0xaf, 0x5c, 0xae, 0x5b, 0xad} },
+{ 0x88ba,	16,	{0x5a, 0xac, 0x59, 0x78, 0x08, 0x12, 0xa3, 0x90, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xef} },
+{ 0x88ca,	16,	{0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
+{ 0x88da,	16,	{0x5d, 0xe5, 0x58, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe0} },
+{ 0x88ea,	16,	{0x23, 0x54, 0x01, 0xf0, 0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0} },
+{ 0x88fa,	16,	{0x54, 0xfd, 0xf0, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc} },
+{ 0x890a,	16,	{0x42, 0x22, 0x80, 0x1f, 0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0} },
+{ 0x891a,	16,	{0x44, 0x02, 0xf0, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc} },
+{ 0x892a,	16,	{0xf4, 0x52, 0x22, 0xe5, 0x58, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff} },
+{ 0x893a,	16,	{0xb4, 0x62, 0x05, 0x43, 0x5d, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5d, 0x08, 0x80} },
+{ 0x894a,	16,	{0x11, 0xef, 0xb4, 0x74, 0x05, 0x43, 0x5d, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f} },
+{ 0x895a,	16,	{0xff, 0x22, 0xe5, 0x58, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0x30} },
+{ 0x896a,	16,	{0xe3, 0x03, 0x43, 0x5d, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5d, 0x40, 0xe5, 0x60, 0x24, 0x04} },
+{ 0x897a,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x58, 0x24, 0x0b, 0xf5} },
+{ 0x898a,	16,	{0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x30, 0xe1, 0x20, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07} },
+{ 0x899a,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x32, 0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
+{ 0x89aa,	16,	{0x35, 0x5f, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x10, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07} },
+{ 0x89ba,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x32, 0xe5, 0x58, 0x24, 0x0b, 0xf5, 0x82} },
+{ 0x89ca,	16,	{0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe4, 0x11, 0xae, 0x5e, 0x74, 0x01, 0xa8, 0x06} },
+{ 0x89da,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x80, 0x10, 0xae, 0x5e, 0x74, 0x01, 0xa8} },
+{ 0x89ea,	16,	{0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x31, 0xef, 0x20, 0xe1, 0x03, 0x30} },
+{ 0x89fa,	16,	{0xe4, 0x03, 0xe4, 0xf5, 0x5d, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf} },
+{ 0x8a0a,	16,	{0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5d, 0xf0, 0xe5, 0x58} },
+{ 0x8a1a,	16,	{0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x60, 0x24, 0x04, 0xf5} },
+{ 0x8a2a,	16,	{0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x58, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x8a3a,	16,	{0x57, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x60, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83} },
+{ 0x8a4a,	16,	{0xef, 0xf0, 0xe5, 0x58, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
+{ 0x8a5a,	16,	{0x60, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x58, 0x24, 0x09} },
+{ 0x8a6a,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x60, 0x24, 0x07, 0xf5, 0x82, 0xe4} },
+{ 0x8a7a,	16,	{0x35, 0x5f, 0xf5, 0x83, 0xef, 0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0xe4} },
+{ 0x8a8a,	16,	{0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83} },
+{ 0x8a9a,	16,	{0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d} },
+{ 0x8aaa,	16,	{0x64, 0x8c, 0x63, 0x7d, 0x06, 0xaf, 0x5e, 0x12, 0x83, 0xdf, 0x75, 0x5d, 0x08, 0xe5, 0x58, 0x24} },
+{ 0x8aba,	16,	{0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5d, 0x10, 0xe5, 0x60} },
+{ 0x8aca,	16,	{0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5d, 0xf0, 0xe5} },
+{ 0x8ada,	16,	{0x58, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05, 0x40} },
+{ 0x8aea,	16,	{0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x58, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x8afa,	16,	{0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94, 0x02} },
+{ 0x8b0a,	16,	{0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24, 0xfb} },
+{ 0x8b1a,	16,	{0x4f, 0xf5, 0x5d, 0xe5, 0x58, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x24} },
+{ 0x8b2a,	16,	{0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a, 0x70} },
+{ 0x8b3a,	16,	{0x14, 0x43, 0x5d, 0x18, 0x80, 0x12, 0x43, 0x5d, 0x08, 0x80, 0x0d, 0x43, 0x5d, 0x38, 0x80, 0x08} },
+{ 0x8b4a,	16,	{0x43, 0x5d, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3} },
+{ 0x8b5a,	16,	{0xa3, 0xe5, 0x5d, 0xf0, 0xaf, 0x5e, 0x7d, 0x01, 0x12, 0x83, 0x5a, 0xaa, 0x57, 0xa9, 0x58, 0x7b} },
+{ 0x8b6a,	16,	{0x01, 0xc0, 0x01, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0} },
+{ 0x8b7a,	14,	{0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa1, 0xde, 0x7f, 0x00} },
+{ 0x8b88,	1,	{0x22} },
+{ 0x8b89,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8b99,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
+{ 0x8ba9,	16,	{0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
+{ 0x8bb9,	16,	{0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
+{ 0x8bc9,	16,	{0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8bd9,	16,	{0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2d, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
+{ 0x8be9,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x57, 0xe5, 0x33, 0xc3, 0x94, 0x01} },
+{ 0x8bf9,	16,	{0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x58, 0x00, 0xf5, 0x59, 0x80, 0x09, 0x7f} },
+{ 0x8c09,	16,	{0x02, 0x12, 0x11, 0x27, 0x8e, 0x58, 0x8f, 0x59, 0xc3, 0xe5, 0x58, 0x64, 0x80, 0x94, 0x80, 0x40} },
+{ 0x8c19,	16,	{0xda, 0xe5, 0x57, 0x55, 0x59, 0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12} },
+{ 0x8c29,	4,	{0x91, 0x36, 0x7f, 0x00} },
+{ 0x8c2d,	1,	{0x22} },
+{ 0x8c2e,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8c3e,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
+{ 0x8c4e,	16,	{0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x8c5e,	16,	{0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x91} },
+{ 0x8c6e,	3,	{0x36, 0x7f, 0x00} },
+{ 0x8c71,	1,	{0x22} },
+{ 0x8c72,	4,	{0x8e, 0x57, 0x8f, 0x58} },
+{ 0x8c76,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8c86,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x85, 0x58} },
+{ 0x8c96,	16,	{0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5} },
+{ 0x8ca6,	16,	{0x83, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x43, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x0c, 0xf5, 0x82} },
+{ 0x8cb6,	16,	{0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x20, 0xee, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82} },
+{ 0x8cc6,	16,	{0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x30, 0xe1, 0xf0, 0x7f, 0x60, 0xed, 0x24, 0x05, 0xf5, 0x82} },
+{ 0x8cd6,	16,	{0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0x5f, 0xb5, 0x07, 0xf2, 0xae, 0x04, 0xaf, 0x05, 0xef, 0x24, 0x04} },
+{ 0x8ce6,	12,	{0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0x7f, 0x00} },
+{ 0x8cf2,	1,	{0x22} },
+{ 0x8cf3,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8cf7,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8d07,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8d17,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
+{ 0x8d27,	16,	{0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8d37,	4,	{0xfe, 0xf0, 0x7f, 0x00} },
+{ 0x8d3b,	1,	{0x22} },
+{ 0x8d3c,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8d40,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8d50,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8d60,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
+{ 0x8d70,	16,	{0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
+{ 0x8d80,	1,	{0x22} },
+{ 0x8d81,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
+{ 0x8d91,	16,	{0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3e, 0x7f, 0x00} },
+{ 0x8da1,	1,	{0x22} },
+{ 0x8da2,	4,	{0x8e, 0x57, 0x8f, 0x58} },
+{ 0x8da6,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x5c, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x59, 0xd3} },
+{ 0x8db6,	16,	{0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x59, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
+{ 0x8dc6,	16,	{0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x5a, 0x7e, 0x75, 0x5b} },
+{ 0x8dd6,	16,	{0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x5a, 0x7e, 0x75, 0x5b, 0x00, 0x80, 0x16, 0x7e} },
+{ 0x8de6,	16,	{0x7d, 0x7f, 0x80, 0x75, 0x5a, 0x7d, 0x75, 0x5b, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
+{ 0x8df6,	16,	{0x5a, 0x7d, 0x75, 0x5b, 0x00, 0xe5, 0x5c, 0x70, 0x1b, 0x85, 0x5b, 0x82, 0x85, 0x5a, 0x83, 0x74} },
+{ 0x8e06,	16,	{0xff, 0xf0, 0xe5, 0x59, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
+{ 0x8e16,	16,	{0x01, 0xf0, 0x80, 0x48, 0xe5, 0x58, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x57, 0xfe, 0xe5, 0x5c, 0x60} },
+{ 0x8e26,	16,	{0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
+{ 0x8e36,	16,	{0x5b, 0xe5, 0x5b, 0xaa, 0x5a, 0x70, 0x02, 0x05, 0x5a, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
+{ 0x8e46,	16,	{0x15, 0x5c, 0x80, 0xd9, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x59, 0x25} },
+{ 0x8e56,	14,	{0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
+{ 0x8e64,	1,	{0x22} },
+{ 0x8e65,	16,	{0xef, 0x24, 0x05, 0xf5, 0x58, 0xe4, 0x3e, 0xf5, 0x57, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
+{ 0x8e75,	16,	{0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3} },
+{ 0x8e85,	16,	{0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x59, 0xf5, 0x5a, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83} },
+{ 0x8e95,	16,	{0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8f, 0x46} },
+{ 0x8ea5,	16,	{0x24, 0x14, 0x60, 0x03, 0x02, 0x8f, 0x94, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe} },
+{ 0x8eb5,	16,	{0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x5c, 0x74, 0x01, 0x9e, 0xf5, 0x5b, 0xd3, 0xe5, 0x5c} },
+{ 0x8ec5,	16,	{0x94, 0x3f, 0xe5, 0x5b, 0x94, 0x00, 0x40, 0x06, 0x75, 0x5b, 0x00, 0x75, 0x5c, 0x3f, 0xd3, 0xe5} },
+{ 0x8ed5,	16,	{0x5a, 0x95, 0x5c, 0xe5, 0x59, 0x95, 0x5b, 0x50, 0x03, 0x02, 0x8f, 0x97, 0xae, 0x5b, 0xaf, 0x5c} },
+{ 0x8ee5,	16,	{0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
+{ 0x8ef5,	16,	{0x59, 0xf5, 0x5a, 0x02, 0x8f, 0x97, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
+{ 0x8f05,	16,	{0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x5c, 0xe4, 0x9e, 0xf5, 0x5b, 0xd3, 0xe5, 0x5c, 0x94} },
+{ 0x8f15,	16,	{0x10, 0xe5, 0x5b, 0x94, 0x00, 0x40, 0x06, 0x75, 0x5b, 0x00, 0x75, 0x5c, 0x10, 0xd3, 0xe5, 0x5a} },
+{ 0x8f25,	16,	{0x95, 0x5c, 0xe5, 0x59, 0x95, 0x5b, 0x40, 0x6a, 0xae, 0x5b, 0xaf, 0x5c, 0x85, 0x58, 0x82, 0x85} },
+{ 0x8f35,	16,	{0x57, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x59, 0xf5, 0x5a, 0x80} },
+{ 0x8f45,	16,	{0x51, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
+{ 0x8f55,	16,	{0xf5, 0x5c, 0xe4, 0x9e, 0xf5, 0x5b, 0x45, 0x5c, 0x60, 0x0b, 0xd3, 0xe5, 0x5c, 0x94, 0x3f, 0xe5} },
+{ 0x8f65,	16,	{0x5b, 0x94, 0x00, 0x40, 0x06, 0x75, 0x5b, 0x00, 0x75, 0x5c, 0x3f, 0xd3, 0xe5, 0x5a, 0x95, 0x5c} },
+{ 0x8f75,	16,	{0xe5, 0x59, 0x95, 0x5b, 0x40, 0x1c, 0xae, 0x5b, 0xaf, 0x5c, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83} },
+{ 0x8f85,	16,	{0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x59, 0xf5, 0x5a, 0x80, 0x03, 0x7f} },
+{ 0x8f95,	16,	{0x01, 0x22, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x90, 0x57} },
+{ 0x8fa5,	16,	{0x24, 0xf9, 0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x90, 0xa7, 0x24, 0x14, 0x60, 0x03, 0x02} },
+{ 0x8fb5,	16,	{0x90, 0xeb, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94} },
+{ 0x8fc5,	16,	{0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x90, 0xeb, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x5a} },
+{ 0x8fd5,	16,	{0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15, 0x59, 0x4e, 0x70, 0x03, 0x02, 0x90, 0xeb, 0x90, 0x01} },
+{ 0x8fe5,	16,	{0x75, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01} },
+{ 0x8ff5,	16,	{0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x58, 0x82, 0x85} },
+{ 0x9005,	16,	{0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03} },
+{ 0x9015,	16,	{0x02, 0x90, 0xeb, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x90, 0xeb, 0x90} },
+{ 0x9025,	16,	{0x01, 0x76, 0xef, 0xf0, 0xe5, 0x5a, 0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15, 0x59, 0x4e, 0x70} },
+{ 0x9035,	16,	{0x03, 0x02, 0x90, 0xeb, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90} },
+{ 0x9045,	16,	{0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x9055,	16,	{0x80, 0xd2, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94} },
+{ 0x9065,	16,	{0x20, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x90, 0xeb, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00} },
+{ 0x9075,	16,	{0x50, 0x74, 0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x5a, 0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15} },
+{ 0x9085,	16,	{0x59, 0x4e, 0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90} },
+{ 0x9095,	16,	{0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x90a5,	16,	{0x80, 0xd5, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78} },
+{ 0x90b5,	16,	{0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x5a, 0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15, 0x59, 0x4e} },
+{ 0x90c5,	16,	{0x60, 0x24, 0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82, 0xf5} },
+{ 0x90d5,	16,	{0x83, 0xe0, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82} },
+{ 0x90e5,	16,	{0xf5, 0x83, 0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83} },
+{ 0x90f5,	13,	{0xa3, 0xa3, 0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x91, 0x36, 0x7f, 0x00} },
+{ 0x9102,	1,	{0x22} },
+{ 0x9103,	16,	{0x8e, 0x62, 0x8f, 0x63, 0x8c, 0x64, 0x8d, 0x65, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x63} },
+{ 0x9113,	16,	{0xe5, 0x63, 0xae, 0x62, 0x70, 0x02, 0x05, 0x62, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
+{ 0x9123,	16,	{0x65, 0xe5, 0x65, 0xac, 0x64, 0x70, 0x02, 0x05, 0x64, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x9133,	3,	{0x80, 0xd6, 0x22} },
+{ 0x9136,	6,	{0x8d, 0x5d, 0xab, 0x07, 0xaa, 0x06} },
+{ 0x913c,	16,	{0x75, 0x61, 0x40, 0x75, 0x60, 0x0d, 0x75, 0x5f, 0x03, 0x75, 0x5e, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
+{ 0x914c,	16,	{0x20, 0xe1, 0xf9, 0xaf, 0x61, 0xae, 0x60, 0xad, 0x5f, 0xac, 0x5e, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
+{ 0x915c,	16,	{0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
+{ 0x916c,	16,	{0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5d, 0x12, 0x91, 0x03, 0x90, 0x7f, 0xc3} },
+{ 0x917c,	8,	{0xe5, 0x5d, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x9184,	1,	{0x22} },
+{ 0x9185,	16,	{0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0xa3, 0xe5, 0x33, 0xf0, 0x90, 0x0a, 0xf5, 0xe4, 0x93, 0x90} },
+{ 0x9195,	16,	{0x01, 0x86, 0xf0, 0x90, 0x0a, 0xf6, 0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c} },
+{ 0x91a5,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01} },
+{ 0x91b5,	16,	{0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e, 0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84} },
+{ 0x91c5,	7,	{0x7d, 0x14, 0x12, 0x91, 0x36, 0x7f, 0x00} },
+{ 0x91cc,	1,	{0x22} },
+{ 0x91cd,	16,	{0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4e, 0x7b, 0x75, 0x4f, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
+{ 0x91dd,	16,	{0x4e, 0x51, 0x85, 0x4f, 0x52, 0xe5, 0x52, 0x24, 0x01, 0xf5, 0x56, 0xe4, 0x35, 0x51, 0xf5, 0x55} },
+{ 0x91ed,	16,	{0xe4, 0xf5, 0x50, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
+{ 0x91fd,	16,	{0x5b, 0x90, 0x92, 0x05, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x92, 0x29, 0x02, 0x92, 0x29, 0x02, 0x92} },
+{ 0x920d,	16,	{0x33, 0x02, 0x92, 0x3d, 0x02, 0x92, 0x3d, 0x02, 0x92, 0x3d, 0x02, 0x92, 0x51, 0x02, 0x92, 0x29} },
+{ 0x921d,	16,	{0x02, 0x92, 0x47, 0x02, 0x92, 0x29, 0x02, 0x92, 0x59, 0x02, 0x92, 0x29, 0xef, 0x64, 0x02, 0x60} },
+{ 0x922d,	16,	{0x2b, 0x75, 0x50, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x50, 0xff, 0x80, 0x1c} },
+{ 0x923d,	16,	{0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x50, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
+{ 0x924d,	16,	{0x50, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x50, 0xff, 0xe5, 0x50, 0x60, 0x15} },
+{ 0x925d,	16,	{0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
+{ 0x926d,	16,	{0x91, 0x36, 0xaf, 0x50, 0x22, 0xe4, 0xf5, 0x50, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0x14} },
+{ 0x927d,	16,	{0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x93, 0x9b, 0x90, 0x92, 0x8c, 0xf8, 0x28, 0x28, 0x73, 0x02} },
+{ 0x928d,	16,	{0x92, 0xb9, 0x02, 0x92, 0xc5, 0x02, 0x92, 0xd1, 0x02, 0x93, 0x1f, 0x02, 0x93, 0x2a, 0x02, 0x93} },
+{ 0x929d,	16,	{0x35, 0x02, 0x93, 0x40, 0x02, 0x93, 0x4b, 0x02, 0x93, 0x56, 0x02, 0x93, 0x61, 0x02, 0x93, 0x6c} },
+{ 0x92ad,	16,	{0x02, 0x93, 0x73, 0x02, 0x93, 0x9b, 0x02, 0x93, 0x7e, 0x02, 0x93, 0x89, 0xaf, 0x56, 0xae, 0x55} },
+{ 0x92bd,	16,	{0x12, 0x84, 0x41, 0x8f, 0x50, 0x02, 0x93, 0x9e, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x85, 0x61, 0x8f} },
+{ 0x92cd,	16,	{0x50, 0x02, 0x93, 0x9e, 0x85, 0x55, 0x53, 0x85, 0x56, 0x54, 0xe5, 0x54, 0x24, 0x01, 0xff, 0xe4} },
+{ 0x92dd,	16,	{0x35, 0x53, 0xfe, 0x12, 0x86, 0xbe, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x87, 0x51, 0x8f, 0x50, 0xef} },
+{ 0x92ed,	16,	{0x64, 0x01, 0x60, 0x03, 0x02, 0x93, 0x9e, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x87, 0xa6, 0x8f, 0x50} },
+{ 0x92fd,	16,	{0xe5, 0x50, 0x70, 0x03, 0x02, 0x93, 0x9e, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0, 0x75, 0xf0} },
+{ 0x930d,	16,	{0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x87, 0xa6, 0x02} },
+{ 0x931d,	16,	{0x93, 0x9e, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8c, 0x72, 0x8f, 0x50, 0x80, 0x74, 0xaf, 0x56, 0xae} },
+{ 0x932d,	16,	{0x55, 0x12, 0x8c, 0xf3, 0x8f, 0x50, 0x80, 0x69, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8d, 0x3c, 0x8f} },
+{ 0x933d,	16,	{0x50, 0x80, 0x5e, 0xaf, 0x4f, 0xae, 0x4e, 0x12, 0x8e, 0x65, 0x8f, 0x50, 0x80, 0x53, 0xaf, 0x56} },
+{ 0x934d,	16,	{0xae, 0x55, 0x12, 0x8b, 0x89, 0x8f, 0x50, 0x80, 0x48, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x86, 0x2d} },
+{ 0x935d,	16,	{0x8f, 0x50, 0x80, 0x3d, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8c, 0x2e, 0x8f, 0x50, 0x80, 0x32, 0x12} },
+{ 0x936d,	16,	{0x91, 0x85, 0x8f, 0x50, 0x80, 0x2b, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8d, 0x81, 0x8f, 0x50, 0x80} },
+{ 0x937d,	16,	{0x20, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8d, 0xa2, 0x8f, 0x50, 0x80, 0x15, 0xaf, 0x4f, 0xae, 0x4e} },
+{ 0x938d,	16,	{0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x91, 0x03, 0xe4, 0xf5, 0x50, 0x80, 0x03, 0x75, 0x50} },
+{ 0x939d,	16,	{0xff, 0xe5, 0x50, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51} },
+{ 0x93ad,	16,	{0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x91, 0x36, 0xaf} },
+{ 0x93bd,	16,	{0x50, 0x22, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
+{ 0x93cd,	16,	{0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x56, 0x82, 0x85} },
+{ 0x93dd,	16,	{0x55, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x91, 0x36} },
+{ 0x93ed,	4,	{0x8f, 0x50, 0xaf, 0x50} },
+{ 0x93f1,	1,	{0x22} },
+{ 0x93f2,	8,	{0x8f, 0x51, 0x8e, 0x50, 0x8d, 0x4f, 0x8c, 0x4e} },
+{ 0x93fa,	16,	{0x75, 0x58, 0x01, 0x75, 0x59, 0x9c, 0xe4, 0xf5, 0x57, 0xaf, 0x53, 0x15, 0x53, 0xef, 0x70, 0x03} },
+{ 0x940a,	16,	{0x02, 0x94, 0x90, 0xaf, 0x52, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x51} },
+{ 0x941a,	16,	{0xae, 0x50, 0xad, 0x4f, 0xac, 0x4e, 0x12, 0xa2, 0xed, 0xaf, 0x03, 0x8f, 0x56, 0xaf, 0x51, 0xae} },
+{ 0x942a,	16,	{0x50, 0xad, 0x4f, 0xac, 0x4e, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x52, 0xe4} },
+{ 0x943a,	16,	{0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
+{ 0x944a,	16,	{0x12, 0xa2, 0xed, 0x8f, 0x51, 0x8e, 0x50, 0x8d, 0x4f, 0x8c, 0x4e, 0xe5, 0x56, 0x24, 0x30, 0xf5} },
+{ 0x945a,	16,	{0x56, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x56, 0xf5, 0x56, 0x05, 0x59, 0xe5, 0x59} },
+{ 0x946a,	16,	{0xae, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x59, 0xe5} },
+{ 0x947a,	16,	{0x59, 0xae, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x56, 0xf0, 0x05} },
+{ 0x948a,	16,	{0x57, 0x05, 0x57, 0x02, 0x94, 0x03, 0xe5, 0x59, 0x15, 0x59, 0x70, 0x02, 0x15, 0x58, 0xaf, 0x57} },
+{ 0x949a,	16,	{0x15, 0x57, 0xef, 0x60, 0x23, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0xf5} },
+{ 0x94aa,	16,	{0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x55, 0xe5, 0x55, 0xac, 0x54, 0x70, 0x02, 0x05, 0x54, 0x14} },
+{ 0x94ba,	8,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
+{ 0x94c2,	1,	{0x22} },
+{ 0x94c3,	16,	{0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
+{ 0x94d3,	10,	{0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0x94dd,	16,	{0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
+{ 0x94ed,	16,	{0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
+{ 0x94fd,	16,	{0xe4, 0xef, 0x55, 0x34, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x950d,	16,	{0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
+{ 0x951d,	16,	{0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa2, 0x4d, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x952d,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x953d,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x954d,	1,	{0x22} },
+{ 0x954e,	16,	{0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x955e,	16,	{0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
+{ 0x956e,	16,	{0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
+{ 0x957e,	16,	{0xa1, 0xde, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa2, 0x4d, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x958e,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x959e,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x95ae,	1,	{0x22} },
+{ 0x95af,	16,	{0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x53, 0x7b, 0x75, 0x54} },
+{ 0x95bf,	16,	{0x80, 0xe5, 0x54, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x53, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x55, 0xf5} },
+{ 0x95cf,	16,	{0x56, 0x89, 0x57, 0xfe, 0x12, 0x95, 0x4e, 0xef, 0x60, 0x50, 0xab, 0x55, 0xaa, 0x56, 0xa9, 0x57} },
+{ 0x95df,	16,	{0x12, 0xa2, 0x07, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0xa2, 0x20, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
+{ 0x95ef,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
+{ 0x95ff,	16,	{0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
+{ 0x960f,	16,	{0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x34, 0x60, 0x0f, 0x85, 0x54, 0x82, 0x85, 0x53} },
+{ 0x961f,	10,	{0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
+{ 0x9629,	1,	{0x22} },
+{ 0x962a,	16,	{0x12, 0x95, 0xaf, 0xe4, 0xf5, 0x4e, 0x74, 0x3a, 0x25, 0x4e, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4f} },
+{ 0x963a,	16,	{0x74, 0xc5, 0x25, 0x4e, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4f, 0xff, 0xc4} },
+{ 0x964a,	16,	{0x54, 0x0f, 0xf5, 0x50, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4e, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
+{ 0x965a,	16,	{0x83, 0xe5, 0x4f, 0xf0, 0xaf, 0x4e, 0x7d, 0x01, 0xe5, 0x4f, 0x45, 0x50, 0xfb, 0x12, 0x94, 0xdd} },
+{ 0x966a,	16,	{0xef, 0x70, 0x05, 0x12, 0x95, 0xaf, 0x80, 0xec, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x967a,	16,	{0xb5, 0x12, 0x95, 0xaf, 0xe5, 0x3e, 0x60, 0x48, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e, 0x74, 0x01, 0xa8} },
+{ 0x968a,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4f, 0x55, 0x3e, 0x60, 0x29, 0xe5, 0x4e} },
+{ 0x969a,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x96aa,	16,	{0x16, 0xaf, 0x4e, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x94, 0xdd, 0xef, 0x70, 0x05, 0x12, 0x95, 0xaf} },
+{ 0x96ba,	16,	{0x80, 0xef, 0xe5, 0x4f, 0xf4, 0x52, 0x3e, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
+{ 0x96ca,	16,	{0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x97, 0xab, 0x74, 0x19, 0xf0, 0xe5, 0x33, 0xc3, 0x94} },
+{ 0x96da,	16,	{0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x51, 0x00, 0xf5, 0x52, 0x80, 0x09} },
+{ 0x96ea,	16,	{0x7f, 0x02, 0x12, 0x11, 0x27, 0x8e, 0x51, 0x8f, 0x52, 0xc3, 0xe5, 0x51, 0x64, 0x80, 0x94, 0x80} },
+{ 0x96fa,	16,	{0x40, 0xda, 0x90, 0x01, 0xbc, 0xe0, 0x65, 0x52, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e} },
+{ 0x970a,	16,	{0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4f, 0x90, 0x01, 0xbc} },
+{ 0x971a,	16,	{0xe0, 0x55, 0x4f, 0x60, 0x14, 0xaf, 0x4e, 0x7d, 0x08, 0xe5, 0x4f, 0x55, 0x52, 0xfb, 0x12, 0x94} },
+{ 0x972a,	16,	{0xdd, 0xef, 0x70, 0x05, 0x12, 0x95, 0xaf, 0x80, 0xec, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04} },
+{ 0x973a,	16,	{0x40, 0xcc, 0x90, 0x01, 0xbc, 0xe5, 0x52, 0xf0, 0xe4, 0xf5, 0x4e, 0xc2, 0xaf, 0x74, 0x36, 0x25} },
+{ 0x974a,	16,	{0x4e, 0xf8, 0xe6, 0xf5, 0x4f, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4f, 0x1e, 0xe5, 0x4f, 0x60, 0x11} },
+{ 0x975a,	16,	{0xaf, 0x4e, 0x7d, 0x02, 0xab, 0x4f, 0x12, 0x94, 0xdd, 0xef, 0x70, 0x05, 0x12, 0x95, 0xaf, 0x80} },
+{ 0x976a,	16,	{0xef, 0x74, 0x2d, 0x25, 0x4e, 0xf8, 0xe6, 0xf5, 0x4f, 0x74, 0xfc, 0x25, 0x4e, 0xf5, 0x82, 0xe4} },
+{ 0x977a,	16,	{0x34, 0x02, 0xf5, 0x83, 0xe0, 0x65, 0x4f, 0x60, 0x11, 0xaf, 0x4e, 0x7d, 0x04, 0xab, 0x4f, 0x12} },
+{ 0x978a,	16,	{0x94, 0xdd, 0xef, 0x70, 0x05, 0x12, 0x95, 0xaf, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4e, 0xf5, 0x82} },
+{ 0x979a,	16,	{0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe5, 0x4f, 0xf0, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x97aa,	4,	{0x9a, 0x12, 0x95, 0xaf} },
+{ 0x97ae,	1,	{0x22} },
+{ 0x97af,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x67, 0x02, 0x97, 0xf6} },
+{ 0x97bb,	16,	{0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
+{ 0x97cb,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
+{ 0x97db,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
+{ 0x97eb,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x98, 0x3b, 0xe4, 0x7e} },
+{ 0x97fb,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
+{ 0x980b,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
+{ 0x981b,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
+{ 0x982b,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
+{ 0x983b,	16,	{0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
+{ 0x984b,	16,	{0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
+{ 0x985b,	8,	{0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
+{ 0x9863,	1,	{0x00} },
+{ 0x9864,	8,	{0x8b, 0x59, 0x8a, 0x5a, 0x89, 0x5b, 0x8d, 0x5c} },
+{ 0x986c,	16,	{0xe4, 0xf5, 0x5d, 0xf5, 0x5e, 0xaf, 0x5c, 0x15, 0x5c, 0xef, 0x60, 0x36, 0xab, 0x59, 0x05, 0x5b} },
+{ 0x987c,	16,	{0xe5, 0x5b, 0xaa, 0x5a, 0x70, 0x02, 0x05, 0x5a, 0x14, 0xf9, 0x12, 0xa2, 0x07, 0xff, 0xe5, 0x5d} },
+{ 0x988c,	16,	{0xe5, 0x5e, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0x61, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
+{ 0x989c,	16,	{0x9e, 0xf5, 0x83, 0xe5, 0x5d, 0xff, 0xe4, 0x93, 0xf5, 0x5d, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x5e} },
+{ 0x98ac,	6,	{0x80, 0xc3, 0xae, 0x5d, 0xaf, 0x5e} },
+{ 0x98b2,	1,	{0x22} },
+{ 0x98b3,	11,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
+{ 0x98be,	16,	{0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
+{ 0x98ce,	16,	{0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
+{ 0x98de,	16,	{0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
+{ 0x98ee,	10,	{0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
+{ 0x98f8,	9,	{0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x9901,	2,	{0xa9, 0x03} },
+{ 0x9903,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
+{ 0x9913,	16,	{0x5c, 0x45, 0x5d, 0xf5, 0x5e, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x9923,	16,	{0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
+{ 0x9933,	16,	{0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x5e, 0xeb} },
+{ 0x9943,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x5e, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
+{ 0x9953,	16,	{0x05, 0x22, 0xe5, 0x5c, 0x5c, 0xfe, 0xe5, 0x5d, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
+{ 0x9963,	16,	{0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x9973,	16,	{0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x5c, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x5d, 0x22, 0x7f} },
+{ 0x9983,	1,	{0x00} },
+{ 0x9984,	1,	{0x22} },
+{ 0x9985,	16,	{0x75, 0x55, 0x02, 0x75, 0x56, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x56, 0x82, 0x85} },
+{ 0x9995,	16,	{0x55, 0x83, 0xa3, 0xe0, 0xff, 0x90, 0x03, 0x37, 0xf0, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0} },
+{ 0x99a5,	16,	{0x90, 0x03, 0x36, 0xf0, 0x90, 0x03, 0x38, 0x74, 0xff, 0xf0, 0x75, 0x57, 0x03, 0x75, 0x58, 0x39} },
+{ 0x99b5,	16,	{0xef, 0x14, 0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9e, 0x29, 0x90, 0x99, 0xc6, 0xf8, 0x28, 0x28} },
+{ 0x99c5,	16,	{0x73, 0x02, 0x99, 0xe7, 0x02, 0x9a, 0x86, 0x02, 0x9b, 0x8b, 0x02, 0x9b, 0xaa, 0x02, 0x9b, 0xaa} },
+{ 0x99d5,	16,	{0x02, 0x9c, 0x60, 0x02, 0x9c, 0x9b, 0x02, 0x9c, 0xc0, 0x02, 0x9d, 0x7e, 0x02, 0x9d, 0xae, 0x02} },
+{ 0x99e5,	16,	{0x9d, 0xda, 0xe4, 0xf5, 0x4e, 0xe5, 0x4e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} },
+{ 0x99f5,	16,	{0x34, 0x20, 0xaf, 0x82, 0xf5, 0x53, 0x8f, 0x54, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74} },
+{ 0x9a05,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4f, 0x80, 0x0d, 0x74} },
+{ 0x9a15,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4f, 0xe5, 0x54, 0x24, 0x07} },
+{ 0x9a25,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x53, 0xf5, 0x83, 0xe5, 0x4f, 0xf0, 0xe0, 0xf5, 0x50, 0x65, 0x4f, 0x60} },
+{ 0x9a35,	16,	{0x38, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xfd, 0x05, 0x58, 0xe5, 0x58, 0xaa, 0x57} },
+{ 0x9a45,	16,	{0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x58, 0xe5, 0x58, 0xac} },
+{ 0x9a55,	16,	{0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4f, 0xf0, 0x85, 0x58, 0x82} },
+{ 0x9a65,	16,	{0x85, 0x57, 0x83, 0xe5, 0x50, 0xf0, 0x02, 0x9e, 0x2f, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64} },
+{ 0x9a75,	16,	{0x02, 0x70, 0x87, 0x05, 0x4e, 0xe5, 0x4e, 0x64, 0x04, 0x60, 0x03, 0x02, 0x99, 0xea, 0x02, 0x9e} },
+{ 0x9a85,	16,	{0x2f, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e, 0xe4, 0xfd, 0x12, 0x83, 0x5a, 0x05, 0x4e, 0xe5, 0x4e, 0xd3} },
+{ 0x9a95,	16,	{0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x98, 0xf0, 0xa3, 0x74, 0xb3, 0xf0, 0xe4, 0xf5} },
+{ 0x9aa5,	16,	{0x50, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x53, 0x20, 0x75, 0x54, 0x00, 0xf5, 0x4e, 0xaf, 0x4e, 0x74} },
+{ 0x9ab5,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4f, 0x90, 0x01, 0xc4, 0xf0} },
+{ 0x9ac5,	16,	{0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xa3} },
+{ 0x9ad5,	16,	{0x74, 0x02, 0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4f, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02} },
+{ 0x9ae5,	16,	{0xa3, 0xe0, 0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xff, 0x05, 0x58, 0xe5, 0x58} },
+{ 0x9af5,	16,	{0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x58, 0x82} },
+{ 0x9b05,	16,	{0x85, 0x57, 0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x50, 0xff, 0x90, 0x01} },
+{ 0x9b15,	16,	{0xc4, 0xe0, 0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xfe, 0x05, 0x58} },
+{ 0x9b25,	16,	{0xe5, 0x58, 0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05} },
+{ 0x9b35,	16,	{0x58, 0xe5, 0x58, 0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x9b45,	16,	{0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe5, 0x4f, 0xf0, 0x75, 0x50, 0xff, 0xe5, 0x50, 0x70, 0x16} },
+{ 0x9b55,	16,	{0x74, 0x08, 0x25, 0x54, 0xf5, 0x54, 0xe4, 0x35, 0x53, 0xf5, 0x53, 0x05, 0x4e, 0xe5, 0x4e, 0x64} },
+{ 0x9b65,	16,	{0x04, 0x60, 0x03, 0x02, 0x9a, 0xb2, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e, 0x7d, 0x01, 0x12, 0x83, 0x5a} },
+{ 0x9b75,	16,	{0x05, 0x4e, 0xe5, 0x4e, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3} },
+{ 0x9b85,	16,	{0x74, 0x12, 0xf0, 0x02, 0x9e, 0x2f, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0, 0x14, 0xff, 0x74} },
+{ 0x9b95,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01} },
+{ 0x9ba5,	16,	{0xc4, 0xf0, 0x02, 0x9e, 0x2f, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4} },
+{ 0x9bb5,	16,	{0xf5, 0x50, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01} },
+{ 0x9bc5,	16,	{0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x58, 0x82, 0x85} },
+{ 0x9bd5,	16,	{0x57, 0x83, 0x74, 0xff, 0xf0, 0xf5, 0x50, 0xe5, 0x50, 0x60, 0x03, 0x02, 0x9e, 0x2f, 0x90, 0x01} },
+{ 0x9be5,	16,	{0xc0, 0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6} },
+{ 0x9bf5,	16,	{0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x51, 0x00} },
+{ 0x9c05,	16,	{0xf5, 0x52, 0x80, 0x09, 0x7f, 0x02, 0x12, 0x11, 0x27, 0x8e, 0x51, 0x8f, 0x52, 0xc3, 0xe5, 0x51} },
+{ 0x9c15,	16,	{0x64, 0x80, 0x94, 0x80, 0x40, 0xda, 0xe5, 0x52, 0x54, 0x0f, 0xf5, 0x50, 0x90, 0x02, 0xf7, 0xe0} },
+{ 0x9c25,	16,	{0x55, 0x50, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4f, 0x85, 0x56, 0x82, 0x85} },
+{ 0x9c35,	16,	{0x55, 0x83, 0xa3, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4f, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x9c45,	16,	{0x00, 0x8f, 0x4f, 0xe5, 0x4f, 0x70, 0x03, 0x02, 0x9e, 0x2f, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x85} },
+{ 0x9c55,	16,	{0x58, 0x82, 0x85, 0x57, 0x83, 0xe5, 0x50, 0xf0, 0x02, 0x9e, 0x2f, 0xe4, 0xff, 0xfd, 0x12, 0x83} },
+{ 0x9c65,	16,	{0x5a, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x53, 0x20, 0x75, 0x54, 0x00, 0x85, 0x54, 0x82, 0x85, 0x53} },
+{ 0x9c75,	16,	{0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0x74, 0x01} },
+{ 0x9c85,	16,	{0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f} },
+{ 0x9c95,	16,	{0xf0, 0xd2, 0x04, 0x02, 0x9e, 0x2f, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x53, 0x20, 0x75} },
+{ 0x9ca5,	16,	{0x54, 0x00, 0xe5, 0x54, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x53, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x9cb5,	16,	{0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x83, 0x5a, 0x02, 0x9e, 0x2f, 0xe4, 0xf5, 0x50, 0xf5, 0x4e} },
+{ 0x9cc5,	16,	{0xaf, 0x4e, 0xe4, 0xfd, 0x12, 0x83, 0x5a, 0xe5, 0x4e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5} },
+{ 0x9cd5,	16,	{0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x53, 0x8f, 0x54, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04} },
+{ 0x9ce5,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x4e, 0x7d, 0x01, 0x7b} },
+{ 0x9cf5,	16,	{0x01, 0x75, 0x5c, 0x80, 0x75, 0x5d, 0x40, 0x12, 0x99, 0x01, 0x8f, 0x50, 0xe5, 0x50, 0x70, 0x11} },
+{ 0x9d05,	16,	{0xaf, 0x4e, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x5c, 0x10, 0x75, 0x5d, 0x20, 0x12, 0x99, 0x01, 0x8f} },
+{ 0x9d15,	16,	{0x50, 0xe5, 0x50, 0x70, 0x10, 0xaf, 0x4e, 0x7d, 0x01, 0xfb, 0x75, 0x5c, 0x80, 0x75, 0x5d, 0x40} },
+{ 0x9d25,	16,	{0x12, 0x99, 0x01, 0x8f, 0x50, 0xe5, 0x50, 0x70, 0x10, 0xaf, 0x4e, 0x7d, 0x02, 0xfb, 0x75, 0x5c} },
+{ 0x9d35,	16,	{0x10, 0x75, 0x5d, 0x20, 0x12, 0x99, 0x01, 0x8f, 0x50, 0xaf, 0x4e, 0x7d, 0x01, 0x12, 0x83, 0x5a} },
+{ 0x9d45,	16,	{0xe5, 0x50, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xff, 0x05, 0x58, 0xe5} },
+{ 0x9d55,	16,	{0x58, 0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x58} },
+{ 0x9d65,	16,	{0x82, 0x85, 0x57, 0x83, 0xe5, 0x50, 0xf0, 0x02, 0x9e, 0x2f, 0x05, 0x4e, 0xe5, 0x4e, 0xd3, 0x94} },
+{ 0x9d75,	16,	{0x03, 0x50, 0x03, 0x02, 0x9c, 0xc5, 0x02, 0x9e, 0x2f, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9d85,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x9e, 0xf0, 0xa3, 0x74} },
+{ 0x9d95,	16,	{0x51, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x81, 0xd9, 0xef, 0x64, 0x08, 0x70, 0x03, 0x02, 0x9e} },
+{ 0x9da5,	16,	{0x2f, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9e, 0x2f, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9db5,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x57, 0xf0, 0xa3, 0xe5} },
+{ 0x9dc5,	16,	{0x58, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x5c, 0xe4, 0x90} },
+{ 0x9dd5,	16,	{0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x56, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x55, 0xfa, 0xa9, 0x07} },
+{ 0x9de5,	16,	{0x7b, 0x01, 0x7d, 0x10, 0x12, 0x98, 0x64, 0xef, 0x4e, 0x70, 0x32, 0x90, 0x03, 0x59, 0xf0, 0xa3} },
+{ 0x9df5,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x56, 0x24, 0x02, 0x90} },
+{ 0x9e05,	16,	{0x03, 0x60, 0xf0, 0xe4, 0x35, 0x55, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x81} },
+{ 0x9e15,	16,	{0xd9, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x0d, 0xe4, 0x90, 0x03} },
+{ 0x9e25,	16,	{0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3} },
+{ 0x9e35,	16,	{0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7e, 0x03, 0x7f} },
+{ 0x9e45,	11,	{0x35, 0x7d, 0x24, 0x12, 0x91, 0x36, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
+{ 0x9e50,	1,	{0x22} },
+{ 0x9e51,	16,	{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
+{ 0x9e61,	16,	{0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
+{ 0x9e71,	16,	{0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
+{ 0x9e81,	16,	{0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
+{ 0x9e91,	16,	{0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
+{ 0x9ea1,	16,	{0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
+{ 0x9eb1,	16,	{0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
+{ 0x9ec1,	16,	{0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
+{ 0x9ed1,	16,	{0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
+{ 0x9ee1,	16,	{0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
+{ 0x9ef1,	16,	{0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
+{ 0x9f01,	16,	{0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
+{ 0x9f11,	16,	{0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
+{ 0x9f21,	16,	{0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
+{ 0x9f31,	16,	{0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
+{ 0x9f41,	16,	{0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
+{ 0x9f51,	16,	{0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
+{ 0x9f61,	16,	{0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
+{ 0x9f71,	16,	{0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
+{ 0x9f81,	16,	{0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
+{ 0x9f91,	16,	{0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
+{ 0x9fa1,	16,	{0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
+{ 0x9fb1,	16,	{0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
+{ 0x9fc1,	16,	{0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
+{ 0x9fd1,	16,	{0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
+{ 0x9fe1,	16,	{0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
+{ 0x9ff1,	16,	{0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
+{ 0xa001,	16,	{0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
+{ 0xa011,	16,	{0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
+{ 0xa021,	16,	{0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
+{ 0xa031,	16,	{0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
+{ 0xa041,	16,	{0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
+{ 0xa051,	16,	{0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
+{ 0xa061,	16,	{0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
+{ 0xa071,	16,	{0xa1, 0x04, 0x74, 0x3a, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0xa1, 0x04, 0xef, 0x75, 0xf0} },
+{ 0xa081,	16,	{0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
+{ 0xa091,	16,	{0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
+{ 0xa0a1,	16,	{0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
+{ 0xa0b1,	16,	{0x12, 0xa2, 0x63, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
+{ 0xa0c1,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
+{ 0xa0d1,	16,	{0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
+{ 0xa0e1,	16,	{0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
+{ 0xa0f1,	16,	{0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
+{ 0xa101,	12,	{0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0xa0, 0x63} },
+{ 0xa10d,	1,	{0x22} },
+{ 0xa10e,	16,	{0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
+{ 0xa11e,	16,	{0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
+{ 0xa12e,	16,	{0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
+{ 0xa13e,	16,	{0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
+{ 0xa14e,	16,	{0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
+{ 0xa15e,	16,	{0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
+{ 0xa16e,	16,	{0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
+{ 0xa17e,	16,	{0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
+{ 0xa18e,	16,	{0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
+{ 0xa19e,	16,	{0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
+{ 0xa1ae,	16,	{0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
+{ 0xa1be,	16,	{0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
+{ 0xa1ce,	16,	{0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
+{ 0xa1de,	16,	{0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
+{ 0xa1ee,	16,	{0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
+{ 0xa1fe,	9,	{0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0xa1, 0x5e, 0x73} },
+{ 0xa207,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
+{ 0xa217,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa220,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
+{ 0xa230,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
+{ 0xa240,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa24d,	16,	{0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
+{ 0xa25d,	6,	{0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
+{ 0xa263,	16,	{0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
+{ 0xa273,	6,	{0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
+{ 0xa279,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
+{ 0xa289,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
+{ 0xa299,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
+{ 0xa2a9,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
+{ 0xa2b1,	16,	{0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
+{ 0xa2c1,	16,	{0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
+{ 0xa2d1,	16,	{0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
+{ 0xa2e1,	16,	{0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
+{ 0xa2f1,	16,	{0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
+{ 0xa301,	16,	{0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
+{ 0xa311,	16,	{0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
+{ 0xa321,	16,	{0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
+{ 0xa331,	16,	{0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
+{ 0xa341,	16,	{0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
+{ 0xa351,	16,	{0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
+{ 0xa361,	16,	{0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
+{ 0xa371,	14,	{0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
+{ 0xa37f,	16,	{0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
+{ 0xa38f,	1,	{0x22} },
+{ 0xa390,	16,	{0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
+{ 0xa3a0,	3,	{0xd8, 0xf1, 0x22} },
+{ 0xa3a3,	16,	{0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
+{ 0xa3b3,	7,	{0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
+{ 0xa3ba,	12,	{0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0xa3c6,	16,	{0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa3, 0xdd, 0x12, 0xa3, 0xdd, 0x12} },
+{ 0xa3d6,	16,	{0xa3, 0xdd, 0x12, 0xa3, 0xdd, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
+{ 0xa3e6,	16,	{0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
+{ 0xa3f6,	1,	{0x22} },
 { 0xffff,	0,	{0x00} }
 };
 
diff -Nru a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
--- a/drivers/usb/storage/datafab.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/storage/datafab.c	Fri Sep 27 14:51:05 2002
@@ -70,7 +70,7 @@
 	unsigned int act_len;	/* ignored */
 
 	if (len == 0)
-		return USB_STOR_TRANSPORT_GOOD;
+		return USB_STOR_XFER_GOOD;
 
 	US_DEBUGP("datafab_bulk_read:  len = %d\n", len);
 	return usb_storage_raw_bulk(us, SCSI_DATA_READ, data, len, &act_len);
@@ -82,7 +82,7 @@
 	unsigned int act_len;	/* ignored */
 
 	if (len == 0)
-		return USB_STOR_TRANSPORT_GOOD;
+		return USB_STOR_XFER_GOOD;
 
 	US_DEBUGP("datafab_bulk_write:  len = %d\n", len);
 	return usb_storage_raw_bulk(us, SCSI_DATA_WRITE, data, len, &act_len);
@@ -144,12 +144,12 @@
 
 		// send the read command
 		result = datafab_bulk_write(us, command, sizeof(command));
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
 		// read the result
 		result = datafab_bulk_read(us, ptr, len);
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
 		sectors -= thistime;
@@ -171,7 +171,7 @@
  leave:
 	if (use_sg)
 		kfree(buffer);
-	return result;
+	return USB_STOR_TRANSPORT_ERROR;
 }
 
 
@@ -243,17 +243,17 @@
 
 		// send the command
 		result = datafab_bulk_write(us, command, sizeof(command));
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
 		// send the data
 		result = datafab_bulk_write(us, ptr, len);
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
 		// read the result
 		result = datafab_bulk_read(us, reply, sizeof(reply));
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
 		if (reply[0] != 0x50 && reply[1] != 0) {
@@ -280,7 +280,7 @@
  leave:
 	if (use_sg)
 		kfree(buffer);
-	return result;
+	return USB_STOR_TRANSPORT_ERROR;
 }
 
 
@@ -308,11 +308,11 @@
 		command[5] = 0xa0;
 
 		rc = datafab_bulk_write(us, command, 8);
-		if (rc != USB_STOR_TRANSPORT_GOOD) 
-			return rc;
+		if (rc != USB_STOR_XFER_GOOD) 
+			return USB_STOR_TRANSPORT_ERROR;
 
 		rc = datafab_bulk_read(us, buf, sizeof(buf));
-		if (rc == USB_STOR_TRANSPORT_GOOD) {
+		if (rc == USB_STOR_XFER_GOOD) {
 			info->lun = 0;
 			return USB_STOR_TRANSPORT_GOOD;
 		}
@@ -320,11 +320,11 @@
 		command[5] = 0xb0;
 
 		rc = datafab_bulk_write(us, command, 8);
-		if (rc != USB_STOR_TRANSPORT_GOOD) 
-			return rc;
+		if (rc != USB_STOR_XFER_GOOD) 
+			return USB_STOR_TRANSPORT_ERROR;
 
 		rc = datafab_bulk_read(us, buf, sizeof(buf));
-		if (rc == USB_STOR_TRANSPORT_GOOD) {
+		if (rc == USB_STOR_XFER_GOOD) {
 			info->lun = 1;
 			return USB_STOR_TRANSPORT_GOOD;
 		}
@@ -332,7 +332,7 @@
 		wait_ms(20);
 	}
 
-	return USB_STOR_TRANSPORT_FAILED;
+	return USB_STOR_TRANSPORT_ERROR;
 }
 
 static int datafab_id_device(struct us_data *us,
@@ -358,22 +358,23 @@
 	command[5] += (info->lun << 4);
 
 	rc = datafab_bulk_write(us, command, 8);
-	if (rc != USB_STOR_TRANSPORT_GOOD) 
-		return rc;
+	if (rc != USB_STOR_XFER_GOOD) 
+		return USB_STOR_TRANSPORT_ERROR;
 
 	// we'll go ahead and extract the media capacity while we're here...
 	//
 	rc = datafab_bulk_read(us, reply, sizeof(reply));
-	if (rc == USB_STOR_TRANSPORT_GOOD) {
+	if (rc == USB_STOR_XFER_GOOD) {
 		// capacity is at word offset 57-58
 		//
 		info->sectors = ((u32)(reply[117]) << 24) | 
 				((u32)(reply[116]) << 16) |
 				((u32)(reply[115]) <<  8) | 
 				((u32)(reply[114])      );
+		return USB_STOR_TRANSPORT_GOOD;
 	}
 		
-	return rc;
+	return USB_STOR_TRANSPORT_ERROR;
 }
 
 
diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
--- a/drivers/usb/storage/freecom.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/storage/freecom.c	Fri Sep 27 14:51:05 2002
@@ -197,7 +197,7 @@
 		/* has the current command been aborted? */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("freecom_readdata(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 
                 return USB_STOR_TRANSPORT_ERROR;
@@ -238,7 +238,7 @@
 		/* has the current command been aborted? */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("freecom_writedata(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 
                 return USB_STOR_TRANSPORT_ERROR;
@@ -301,7 +301,7 @@
 		/* we canceled this transfer */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("freecom_transport(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 
                 return USB_STOR_TRANSPORT_ERROR;
@@ -316,7 +316,7 @@
 	/* we canceled this transfer */
 	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 		US_DEBUGP("freecom_transport(): transfer aborted\n");
-		return US_BULK_TRANSFER_ABORTED;
+		return USB_STOR_TRANSPORT_ABORTED;
 	}
 
         US_DEBUG(pdump ((void *) fst, partial));
@@ -354,7 +354,7 @@
 			/* we canceled this transfer */
 			if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 				US_DEBUGP("freecom_transport(): transfer aborted\n");
-				return US_BULK_TRANSFER_ABORTED;
+				return USB_STOR_TRANSPORT_ABORTED;
 			}
 
 			return USB_STOR_TRANSPORT_ERROR;
@@ -369,7 +369,7 @@
 		/* we canceled this transfer */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("freecom_transport(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 
 		US_DEBUG(pdump ((void *) fst, partial));
@@ -430,7 +430,7 @@
 
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
                         US_DEBUGP ("freecom_transport: transfer aborted\n");
-                        return US_BULK_TRANSFER_ABORTED;
+                        return USB_STOR_TRANSPORT_ABORTED;
                 }
                 if (partial != 4 || result != 0)
                         return USB_STOR_TRANSPORT_ERROR;
@@ -459,7 +459,7 @@
 
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
                         US_DEBUGP ("freecom_transport: transfer aborted\n");
-                        return US_BULK_TRANSFER_ABORTED;
+                        return USB_STOR_TRANSPORT_ABORTED;
                 }
                 if (partial != 4 || result != 0)
                         return USB_STOR_TRANSPORT_ERROR;
diff -Nru a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
--- a/drivers/usb/storage/jumpshot.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/usb/storage/jumpshot.c	Fri Sep 27 14:51:02 2002
@@ -65,7 +65,7 @@
 	unsigned int act_len;	/* ignored */
 
 	if (len == 0)
-		return USB_STOR_TRANSPORT_GOOD;
+		return USB_STOR_XFER_GOOD;
 
 	US_DEBUGP("jumpshot_bulk_read:  len = %d\n", len);
 	return usb_storage_raw_bulk(us, SCSI_DATA_READ, data, len, &act_len);
@@ -79,7 +79,7 @@
 	unsigned int act_len;	/* ignored */
 
 	if (len == 0)
-		return USB_STOR_TRANSPORT_GOOD;
+		return USB_STOR_XFER_GOOD;
 
 	US_DEBUGP("jumpshot_bulk_write:  len = %d\n", len);
 	return usb_storage_raw_bulk(us, SCSI_DATA_WRITE, data, len, &act_len);
@@ -168,7 +168,7 @@
 
 		// read the result
 		result = jumpshot_bulk_read(us, ptr, len);
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
 		US_DEBUGP("jumpshot_read_data:  %d bytes\n", len);
@@ -192,7 +192,7 @@
  leave:
 	if (use_sg)
 		kfree(buffer);
-	return result;
+	return USB_STOR_TRANSPORT_ERROR;
 }
 
 
@@ -253,7 +253,7 @@
 
 		// send the data
 		result = jumpshot_bulk_write(us, ptr, len);
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
 		// read the result.  apparently the bulk write can complete
@@ -288,7 +288,7 @@
  leave:
 	if (use_sg)
 		kfree(buffer);
-	return result;
+	return USB_STOR_TRANSPORT_ERROR;
 }
 
 static int jumpshot_id_device(struct us_data *us,
@@ -314,8 +314,8 @@
 
 	// read the reply
 	rc = jumpshot_bulk_read(us, reply, sizeof(reply));
-	if (rc != USB_STOR_TRANSPORT_GOOD)
-		return rc;
+	if (rc != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	info->sectors = ((u32)(reply[117]) << 24) |
 			((u32)(reply[116]) << 16) |
diff -Nru a/drivers/usb/storage/raw_bulk.c b/drivers/usb/storage/raw_bulk.c
--- a/drivers/usb/storage/raw_bulk.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/storage/raw_bulk.c	Fri Sep 27 14:51:05 2002
@@ -61,7 +61,7 @@
 	/* did we abort this command? */
 	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 		US_DEBUGP("usb_stor_send_control(): transfer aborted\n");
-		return US_BULK_TRANSFER_ABORTED;
+		return USB_STOR_TRANSPORT_ABORTED;
 	}
 
 	// Check the return code for the command.
@@ -70,7 +70,7 @@
 		/* a stall indicates a protocol error */
 		if (result == -EPIPE) {
 			US_DEBUGP("-- Stall on control pipe\n");
-			return USB_STOR_TRANSPORT_FAILED;
+			return USB_STOR_TRANSPORT_ERROR;
 		}
 
 		/* Uh oh... serious problem here */
@@ -100,14 +100,14 @@
 			  " pipe 0x%x, stalled at %d bytes\n",
 			  pipe, *act_len);
 		if (usb_stor_clear_halt(us, pipe) < 0)
-			return US_BULK_TRANSFER_FAILED;
-		/* return US_BULK_TRANSFER_SHORT; */
+			return USB_STOR_XFER_ERROR;
+		return USB_STOR_XFER_STALLED;
 	}
 
 	/* did we abort this command? */
 	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 		US_DEBUGP("usb_storage_raw_bulk(): transfer aborted\n");
-		return US_BULK_TRANSFER_ABORTED;
+		return USB_STOR_XFER_ABORTED;
 	}
 
 	if (result) {
@@ -122,13 +122,13 @@
 			US_DEBUGP("raw_bulk(): unknown error %d\n",
 				  result);
 
-		return US_BULK_TRANSFER_FAILED;
+		return USB_STOR_XFER_ERROR;
 	}
 
 	if (*act_len != len) {
 		US_DEBUGP("Warning: Transferred only %d of %d bytes\n",
 			  *act_len, len);
-		return US_BULK_TRANSFER_SHORT;
+		return USB_STOR_XFER_SHORT;
 	}
 
 #if 0
@@ -137,7 +137,7 @@
 		  *act_len, len);
 #endif
 
-	return US_BULK_TRANSFER_GOOD;
+	return USB_STOR_XFER_GOOD;
 }
 
 int
@@ -145,14 +145,14 @@
 			   unsigned char *data, unsigned int len,
 			   int use_sg) {
 
-	int result = USB_STOR_TRANSPORT_GOOD;
+	int result = USB_STOR_XFER_ERROR;
 	int transferred = 0;
 	int i;
 	struct scatterlist *sg;
 	unsigned int act_len;
 
 	if (len == 0)
-		return USB_STOR_TRANSPORT_GOOD;
+		return USB_STOR_XFER_GOOD;
 
 #if DEBUG_PRCT
 
@@ -196,7 +196,7 @@
 
 			result = usb_storage_raw_bulk(us, direction,
 						      buf, length, &act_len);
-			if (result != US_BULK_TRANSFER_GOOD)
+			if (result != USB_STOR_XFER_GOOD)
 				break;
 			transferred += length;
 		}
diff -Nru a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
--- a/drivers/usb/storage/sddr09.c	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/storage/sddr09.c	Fri Sep 27 14:51:05 2002
@@ -285,12 +285,14 @@
 	}
 
 	result = usb_storage_raw_bulk(us, SCSI_DATA_READ, sensebuf, buflen, &act_len);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("request sense bulk in failed\n");
-	else
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+	else {
 		US_DEBUGP("request sense worked\n");
-
-	return result;
+		return USB_STOR_TRANSPORT_GOOD;
+	}
 }
 
 /*
@@ -344,11 +346,12 @@
 	result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
 				       buf, bulklen, use_sg);
 
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transport in sddr09_read2%d %d\n",
 			  x, result);
-
-	return result;
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+	return USB_STOR_TRANSPORT_GOOD;
 }
 
 /*
@@ -510,11 +513,12 @@
 	result = usb_storage_bulk_transport(us, SCSI_DATA_WRITE,
 				       buf, bulklen, use_sg);
 
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transport in sddr09_writeX %d\n",
 			  result);
-
-	return result;
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+	return USB_STOR_TRANSPORT_GOOD;
 }
 
 /* erase address, write same address */
@@ -590,13 +594,14 @@
 
 	result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
 				       buf, bulklen, 0);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	kfree(buf);
+	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transport in sddr09_read_sg %d\n",
 			  result);
+		return USB_STOR_TRANSPORT_ERROR;
+	}
 
-	kfree(buf);
-
-	return result;
+	return USB_STOR_TRANSPORT_GOOD;
 }
 #endif
 
@@ -629,7 +634,8 @@
 	result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
 				       data, sizeof(data), 0);
 	*status = data[0];
-	return result;
+	return (result == USB_STOR_XFER_GOOD ?
+			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
 }
 
 static int
@@ -953,7 +959,8 @@
 	for (i = 0; i < 4; i++)
 		deviceID[i] = content[i];
 
-	return result;
+	return (result == USB_STOR_XFER_GOOD ?
+			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
 }
 
 static int
@@ -1549,7 +1556,8 @@
 					       srb->request_bufflen,
 					       srb->use_sg);
 
-		return result;
+		return (result == USB_STOR_XFER_GOOD ?
+			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
 	} 
 
 	return USB_STOR_TRANSPORT_GOOD;
diff -Nru a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
--- a/drivers/usb/storage/sddr55.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/storage/sddr55.c	Fri Sep 27 14:51:04 2002
@@ -101,16 +101,16 @@
 	US_DEBUGP("Result for send_command in status %d\n",
 		result);
 
-	if (result != US_BULK_TRANSFER_GOOD) {
+	if (result != USB_STOR_XFER_GOOD) {
 		set_sense_info (4, 0, 0);	/* hardware error */
-		return result;
+		return USB_STOR_TRANSPORT_ERROR;
 	}
 
 	result = sddr55_bulk_transport(us,
 		SCSI_DATA_READ, status,	4);
 
 	/* expect to get short transfer if no card fitted */
-	if (result == US_BULK_TRANSFER_SHORT) {
+	if (result == USB_STOR_XFER_SHORT || result == USB_STOR_XFER_STALLED) {
 		/* had a short transfer, no card inserted, free map memory */
 		if (info->lba_to_pba)
 			kfree(info->lba_to_pba);
@@ -123,12 +123,12 @@
 		info->force_read_only = 0;
 
 		set_sense_info (2, 0x3a, 0);	/* not ready, medium not present */
-		return result;
+		return USB_STOR_TRANSPORT_FAILED;
 	}
 
-	if (result != US_BULK_TRANSFER_GOOD) {
+	if (result != USB_STOR_XFER_GOOD) {
 		set_sense_info (4, 0, 0);	/* hardware error */
-		return result;
+		return USB_STOR_TRANSPORT_FAILED;
 	}
 	
 	/* check write protect status */
@@ -138,11 +138,12 @@
 	result = sddr55_bulk_transport(us,
 		SCSI_DATA_READ, status,	2);
 
-	if (result != US_BULK_TRANSFER_GOOD) {
+	if (result != USB_STOR_XFER_GOOD) {
 		set_sense_info (4, 0, 0);	/* hardware error */
 	}
 
-	return result;
+	return (result == USB_STOR_XFER_GOOD ?
+			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_FAILED);
 }
 
 
@@ -214,23 +215,29 @@
 			US_DEBUGP("Result for send_command in read_data %d\n",
 				result);
 
-			if (result != US_BULK_TRANSFER_GOOD)
+			if (result != USB_STOR_XFER_GOOD) {
+				result = USB_STOR_TRANSPORT_ERROR;
 				goto leave;
+			}
 
 			/* read data */
 			result = sddr55_bulk_transport(us,
 				SCSI_DATA_READ, ptr,
 				pages<<info->pageshift);
 
-			if (result != US_BULK_TRANSFER_GOOD)
+			if (result != USB_STOR_XFER_GOOD) {
+				result = USB_STOR_TRANSPORT_ERROR;
 				goto leave;
+			}
 
 			/* now read status */
 			result = sddr55_bulk_transport(us,
 				SCSI_DATA_READ, status, 2);
 
-			if (result != US_BULK_TRANSFER_GOOD)
+			if (result != USB_STOR_XFER_GOOD) {
+				result = USB_STOR_TRANSPORT_ERROR;
 				goto leave;
+			}
 
 			/* check status for error */
 			if (status[0] == 0xff && status[1] == 0x4) {
@@ -247,6 +254,7 @@
 	}
 
 	us_copy_to_sgbuf_all(buffer, len, content, use_sg);
+	result = USB_STOR_TRANSPORT_GOOD;
 
 leave:
 	if (use_sg)
@@ -374,12 +382,13 @@
 		result = sddr55_bulk_transport(us,
 			SCSI_DATA_WRITE, command, 8);
 
-		if (result != US_BULK_TRANSFER_GOOD) {
+		if (result != USB_STOR_XFER_GOOD) {
 			US_DEBUGP("Result for send_command in write_data %d\n",
 			result);
 
 			/* set_sense_info is superfluous here? */
 			set_sense_info (3, 0x3, 0);/* peripheral write error */
+			result = USB_STOR_TRANSPORT_FAILED;
 			goto leave;
 		}
 
@@ -388,24 +397,26 @@
 			SCSI_DATA_WRITE, ptr,
 			pages<<info->pageshift);
 
-		if (result != US_BULK_TRANSFER_GOOD) {
+		if (result != USB_STOR_XFER_GOOD) {
 			US_DEBUGP("Result for send_data in write_data %d\n",
 				  result);
 
 			/* set_sense_info is superfluous here? */
 			set_sense_info (3, 0x3, 0);/* peripheral write error */
+			result = USB_STOR_TRANSPORT_FAILED;
 			goto leave;
 		}
 
 		/* now read status */
 		result = sddr55_bulk_transport(us, SCSI_DATA_READ, status, 6);
 
-		if (result != US_BULK_TRANSFER_GOOD) {
+		if (result != USB_STOR_XFER_GOOD) {
 			US_DEBUGP("Result for get_status in write_data %d\n",
 				  result);
 
 			/* set_sense_info is superfluous here? */
 			set_sense_info (3, 0x3, 0);/* peripheral write error */
+			result = USB_STOR_TRANSPORT_FAILED;
 			goto leave;
 		}
 
@@ -446,6 +457,7 @@
 		sectors -= pages >> info->smallpageshift;
 		ptr += (pages << info->pageshift);
 	}
+	result = USB_STOR_TRANSPORT_GOOD;
 
  leave:
 	if (use_sg)
@@ -468,14 +480,14 @@
 	US_DEBUGP("Result of send_control for device ID is %d\n",
 		result);
 
-	if (result != US_BULK_TRANSFER_GOOD)
-		return result;
+	if (result != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	result = sddr55_bulk_transport(us,
 		SCSI_DATA_READ, content, 4);
 
-	if (result != US_BULK_TRANSFER_GOOD)
-		return result;
+	if (result != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	*manufacturerID = content[0];
 	*deviceID = content[1];
@@ -485,7 +497,7 @@
 			SCSI_DATA_READ, content, 2);
 	}
 
-	return result;
+	return USB_STOR_TRANSPORT_GOOD;
 }
 
 
@@ -510,7 +522,7 @@
 	US_DEBUGP("Result of read_deviceID is %d\n",
 		result);
 
-	if (result != US_BULK_TRANSFER_GOOD)
+	if (result != USB_STOR_XFER_GOOD)
 		return 0;
 
 	US_DEBUGP("Device ID = %02X\n", deviceID);
@@ -603,21 +615,21 @@
 
 	result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8);
 
-	if ( result != US_BULK_TRANSFER_GOOD) {
+	if ( result != USB_STOR_XFER_GOOD) {
 		kfree (buffer);
 		return -1;
 	}
 
 	result = sddr55_bulk_transport(us, SCSI_DATA_READ, buffer, numblocks * 2);
 
-	if ( result != US_BULK_TRANSFER_GOOD) {
+	if ( result != USB_STOR_XFER_GOOD) {
 		kfree (buffer);
 		return -1;
 	}
 
 	result = sddr55_bulk_transport(us, SCSI_DATA_READ, command, 2);
 
-	if ( result != US_BULK_TRANSFER_GOOD) {
+	if ( result != USB_STOR_XFER_GOOD) {
 		kfree (buffer);
 		return -1;
 	}
@@ -776,7 +788,7 @@
 	/* only check card status if the map isn't allocated, ie no card seen yet
 	 * or if it's been over half a second since we last accessed it
 	 */
-	if (info->lba_to_pba == NULL || jiffies > (info->last_access + HZ/2)) {
+	if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) {
 
 		/* check to see if a card is fitted */
 		result = sddr55_status (us);
diff -Nru a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
--- a/drivers/usb/storage/shuttle_usbat.c	Fri Sep 27 14:51:02 2002
+++ b/drivers/usb/storage/shuttle_usbat.c	Fri Sep 27 14:51:02 2002
@@ -153,7 +153,8 @@
 
 	result = usb_storage_bulk_transport(us, SCSI_DATA_READ, content, len, use_sg);
 
-	return result;
+	return (result == USB_STOR_XFER_GOOD ?
+			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
 }
 
 /*
@@ -234,8 +235,8 @@
 
 	result = usb_storage_bulk_transport(us, SCSI_DATA_WRITE, content, len, use_sg);
 
-	if (result != USB_STOR_TRANSPORT_GOOD)
-		return result;
+	if (result != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	return usbat_wait_not_busy(us, minutes);
 }
@@ -309,8 +310,8 @@
 				SCSI_DATA_WRITE, 
 				data, num_registers*2, 0);
 
-			if (result!=USB_STOR_TRANSPORT_GOOD)
-				return result;
+			if (result!=USB_STOR_XFER_GOOD)
+				return USB_STOR_TRANSPORT_ERROR;
 
 		}
 
@@ -341,7 +342,8 @@
 		 * transferred.
 		 */
 
-		if (result == US_BULK_TRANSFER_SHORT) {
+		if (result == USB_STOR_XFER_SHORT ||
+				result == USB_STOR_XFER_STALLED) {
 
 			/*
 			 * If we're reading and we stalled, then clear
@@ -373,8 +375,8 @@
 			US_DEBUGP("Redoing %s\n",
 			  direction==SCSI_DATA_WRITE ? "write" : "read");
 
-		} else if (result != US_BULK_TRANSFER_GOOD)
-			return result;
+		} else if (result != USB_STOR_XFER_GOOD)
+			return USB_STOR_TRANSPORT_ERROR;
 		else
 			return usbat_wait_not_busy(us, minutes);
 
@@ -425,8 +427,8 @@
 	result = usb_storage_bulk_transport(us,
 		SCSI_DATA_WRITE, data, num_registers*2, 0);
 
-	if (result != USB_STOR_TRANSPORT_GOOD)
-		return result;
+	if (result != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	return usbat_wait_not_busy(us, 0);
 }
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/storage/transport.c	Fri Sep 27 14:51:04 2002
@@ -572,36 +572,37 @@
 	if (result == -EPIPE) {
 		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
 		if (usb_stor_clear_halt(us, pipe) < 0)
-			return US_BULK_TRANSFER_FAILED;
+			return USB_STOR_XFER_ERROR;
+		return USB_STOR_XFER_STALLED;
 	}
 
 	/* did we abort this command? */
 	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 		US_DEBUGP("usb_stor_transfer_partial(): transfer aborted\n");
-		return US_BULK_TRANSFER_ABORTED;
-	}
-
-	/* did we send all the data? */
-	if (partial == length) {
-		US_DEBUGP("usb_stor_transfer_partial(): transfer complete\n");
-		return US_BULK_TRANSFER_GOOD;
+		return USB_STOR_XFER_ABORTED;
 	}
 
 	/* NAK - that means we've retried a few times already */
 	if (result == -ETIMEDOUT) {
 		US_DEBUGP("usb_stor_transfer_partial(): device NAKed\n");
-		return US_BULK_TRANSFER_FAILED;
+		return USB_STOR_XFER_ERROR;
 	}
 
 	/* the catch-all error case */
 	if (result) {
 		US_DEBUGP("usb_stor_transfer_partial(): unknown error\n");
-		return US_BULK_TRANSFER_FAILED;
+		return USB_STOR_XFER_ERROR;
+	}
+
+	/* did we send all the data? */
+	if (partial == length) {
+		US_DEBUGP("usb_stor_transfer_partial(): transfer complete\n");
+		return USB_STOR_XFER_GOOD;
 	}
 
 	/* no error code, so we must have transferred some data, 
 	 * just not all of it */
-	return US_BULK_TRANSFER_SHORT;
+	return USB_STOR_XFER_SHORT;
 }
 
 /*
@@ -739,7 +740,7 @@
 	 * Also, if we have a short transfer on a command that can't have
 	 * a short transfer, we're going to do this.
 	 */
-	if ((srb->result == US_BULK_TRANSFER_SHORT) &&
+	if ((srb->result == USB_STOR_XFER_SHORT) &&
 	    !((srb->cmnd[0] == REQUEST_SENSE) ||
 	      (srb->cmnd[0] == INQUIRY) ||
 	      (srb->cmnd[0] == MODE_SENSE) ||
@@ -858,6 +859,7 @@
  * This must be called with scsi_lock(us->srb->host) held */
 void usb_stor_abort_transport(struct us_data *us)
 {
+	struct Scsi_Host *host;
 	int state = atomic_read(&us->sm_state);
 
 	US_DEBUGP("usb_stor_abort_transport called\n");
@@ -869,7 +871,8 @@
 
 	/* set state to abort and release the lock */
 	atomic_set(&us->sm_state, US_STATE_ABORTING);
-	scsi_unlock(us->srb->host);
+	host = us->srb->host;
+	scsi_unlock(host);
 
 	/* If the state machine is blocked waiting for an URB or an IRQ,
 	 * let's wake it up */
@@ -891,8 +894,8 @@
 	/* Wait for the aborted command to finish */
 	wait_for_completion(&us->notify);
 
-	/* Reacquire the lock */
-	scsi_lock(us->srb->host);
+	/* Reacquire the lock: note that us->srb is now NULL */
+	scsi_lock(host);
 }
 
 /*
@@ -995,13 +998,13 @@
 	/* did we abort this command? */
 	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 		US_DEBUGP("usb_stor_control_msg(): transfer aborted\n");
-		return US_BULK_TRANSFER_ABORTED;
+		return USB_STOR_TRANSPORT_ABORTED;
 	}
 
 	/* a stall indicates a protocol error */
 	if (result == -EPIPE) {
 		US_DEBUGP("-- Stall on control pipe\n");
-		return USB_STOR_TRANSPORT_FAILED;
+		return USB_STOR_TRANSPORT_ERROR;
 	}
 
 	if (result < 0) {
@@ -1017,13 +1020,13 @@
 		US_DEBUGP("CBI data stage result is 0x%x\n", result);
 
 		/* report any errors */
-		if (result == US_BULK_TRANSFER_ABORTED) {
+		if (result == USB_STOR_XFER_ABORTED) {
 			clear_bit(US_FLIDX_IP_WANTED, &us->flags);
 			return USB_STOR_TRANSPORT_ABORTED;
 		}
-		if (result == US_BULK_TRANSFER_FAILED) {
+		if (result == USB_STOR_XFER_ERROR) {
 			clear_bit(US_FLIDX_IP_WANTED, &us->flags);
-			return USB_STOR_TRANSPORT_FAILED;
+			return USB_STOR_TRANSPORT_ERROR;
 		}
 	}
 
@@ -1103,13 +1106,13 @@
 		/* did we abort this command? */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("usb_stor_CB_transport(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 
 		/* a stall indicates a protocol error */
 		if (result == -EPIPE) {
 			US_DEBUGP("-- Stall on control pipe\n");
-			return USB_STOR_TRANSPORT_FAILED;
+			return USB_STOR_TRANSPORT_ERROR;
 		}
 
 		/* Uh oh... serious problem here */
@@ -1124,11 +1127,11 @@
 		US_DEBUGP("CB data stage result is 0x%x\n", result);
 
 		/* report any errors */
-		if (result == US_BULK_TRANSFER_ABORTED) {
+		if (result == USB_STOR_XFER_ABORTED) {
 			return USB_STOR_TRANSPORT_ABORTED;
 		}
-		if (result == US_BULK_TRANSFER_FAILED) {
-			return USB_STOR_TRANSPORT_FAILED;
+		if (result == USB_STOR_XFER_ERROR) {
+			return USB_STOR_TRANSPORT_ERROR;
 		}
 	}
 
@@ -1207,7 +1210,7 @@
 	/* did we abort this command? */
 	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 		US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-		return US_BULK_TRANSFER_ABORTED;
+		return USB_STOR_TRANSPORT_ABORTED;
 	}
 
 	/* if we stall, we need to clear it before we go on */
@@ -1218,7 +1221,7 @@
 		/* did we abort this command? */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 		if (result < 0)
 			return USB_STOR_TRANSPORT_ERROR;
@@ -1237,7 +1240,7 @@
 			US_DEBUGP("Bulk data transfer result 0x%x\n", result);
 
 			/* if it was aborted, we need to indicate that */
-			if (result == US_BULK_TRANSFER_ABORTED)
+			if (result == USB_STOR_XFER_ABORTED)
 				return USB_STOR_TRANSPORT_ABORTED;
 		}
 	}
@@ -1257,7 +1260,7 @@
 	/* did we abort this command? */
 	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 		US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-		return US_BULK_TRANSFER_ABORTED;
+		return USB_STOR_TRANSPORT_ABORTED;
 	}
 
 	/* did the attempt to read the CSW fail? */
@@ -1268,7 +1271,7 @@
 		/* did we abort this command? */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 		if (result < 0)
 			return USB_STOR_TRANSPORT_ERROR;
@@ -1281,7 +1284,7 @@
 		/* did we abort this command? */
 		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 			US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
+			return USB_STOR_TRANSPORT_ABORTED;
 		}
 
 		/* if it fails again, we need a reset and return an error*/
@@ -1292,7 +1295,7 @@
 			/* did we abort this command? */
 			if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
 				US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-				return US_BULK_TRANSFER_ABORTED;
+				return USB_STOR_TRANSPORT_ABORTED;
 			}
 			return USB_STOR_TRANSPORT_ERROR;
 		}
diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
--- a/drivers/usb/storage/transport.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/storage/transport.h	Fri Sep 27 14:51:04 2002
@@ -115,12 +115,13 @@
 #define US_BULK_GET_MAX_LUN	0xfe
 
 /*
- * usb_stor_transfer() return codes
+ * usb_stor_transfer() return codes, in order of severity
  */
-#define US_BULK_TRANSFER_GOOD		0  /* good transfer                 */
-#define US_BULK_TRANSFER_SHORT		1  /* transfered less than expected */
-#define US_BULK_TRANSFER_FAILED		2  /* transfer died in the middle   */
-#define US_BULK_TRANSFER_ABORTED	3  /* transfer canceled             */
+#define USB_STOR_XFER_GOOD		0  /* good transfer                 */
+#define USB_STOR_XFER_SHORT		1  /* transfered less than expected */
+#define USB_STOR_XFER_STALLED		2  /* endpoint stalled		    */
+#define USB_STOR_XFER_ERROR		3  /* transfer died in the middle   */
+#define USB_STOR_XFER_ABORTED		4  /* transfer canceled             */
 
 /*
  * Transport return codes
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h	Fri Sep 27 14:51:05 2002
+++ b/drivers/usb/storage/unusual_devs.h	Fri Sep 27 14:51:05 2002
@@ -331,8 +331,10 @@
  * Like the SIIG unit above, this unit needs an INQUIRY to ask for exactly
  * 36 bytes of data.  No more, no less. That is the only reason this entry
  * is needed.
- */
-UNUSUAL_DEV(  0x05e3, 0x0702, 0x0000, 0xffff,
+ *
+ * ST818 slim drives (rev 0.02) don't need special care.
+*/
+UNUSUAL_DEV(  0x05e3, 0x0702, 0x0000, 0x0001,
 		"EagleTec",
 		"External Hard Disk",
 		US_SC_SCSI, US_PR_BULK, NULL,
@@ -548,17 +550,22 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ),
 
-/* Submitted by Brian Hall <brihall@bigfoot.com>
+/* Submitted by Brian Hall <brihall@pcisys.net>
  * Needed for START_STOP flag */
 UNUSUAL_DEV(  0x0c76, 0x0003, 0x0100, 0x0100,
 		"JMTek",
 		"USBDrive",
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_START_STOP ),
+UNUSUAL_DEV(  0x0c76, 0x0005, 0x0100, 0x0100,
+		"JMTek",
+		"USBDrive",
+		US_SC_SCSI, US_PR_BULK, NULL,
+		US_FL_START_STOP ),
 
 /* Reported by Dan Pilone <pilone@slac.com>
  * The device needs the flags only.
- * Also reported by Brian Hall <brihall@bigfoot.com>, again for flags.
+ * Also reported by Brian Hall <brihall@pcisys.net>, again for flags.
  * I also suspect this device may have a broken serial number.
  */
 UNUSUAL_DEV(  0x1065, 0x2136, 0x0000, 0x9999,
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/usb/usb-skeleton.c	Fri Sep 27 14:51:04 2002
@@ -1,12 +1,11 @@
 /*
- * USB Skeleton driver - 0.7
+ * USB Skeleton driver - 0.8
  *
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License as
- *	published by the Free Software Foundation; either version 2 of
- *	the License, or (at your option) any later version.
+ *	published by the Free Software Foundation, version 2.
  *
  *
  * This driver is to be used as a skeleton driver to be able to create a
@@ -22,6 +21,8 @@
  *
  * History:
  *
+ * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device
+ *			driver.
  * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do
  *			not have both a bulk in and bulk out endpoint.
  *			Thanks to Holger Waechtler for the fix.
@@ -133,8 +134,8 @@
 static int skel_open		(struct inode *inode, struct file *file);
 static int skel_release		(struct inode *inode, struct file *file);
 	
-static void * skel_probe	(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);
-static void skel_disconnect	(struct usb_device *dev, void *ptr);
+static int skel_probe		(struct usb_interface *intf, const struct usb_device_id *id);
+static void skel_disconnect	(struct usb_interface *intf);
 
 static void skel_write_bulk_callback	(struct urb *urb);
 
@@ -509,10 +510,10 @@
  *	Called by the usb core when a new device is connected that it thinks
  *	this driver might be interested in.
  */
-static void * skel_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
+	struct usb_device *udev = interface_to_usbdev(interface);
 	struct usb_skel *dev = NULL;
-	struct usb_interface *interface;
 	struct usb_interface_descriptor *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
 	int minor;
@@ -525,7 +526,7 @@
 	/* See if the device offered us matches what we can accept */
 	if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) ||
 	    (udev->descriptor.idProduct != USB_SKEL_PRODUCT_ID)) {
-		return NULL;
+		return -ENODEV;
 	}
 
 	down (&minor_table_mutex);
@@ -545,8 +546,6 @@
 	memset (dev, 0x00, sizeof (*dev));
 	minor_table[minor] = dev;
 
-	interface = &udev->actconfig->interface[ifnum];
-
 	init_MUTEX (&dev->sem);
 	dev->udev = udev;
 	dev->interface = interface;
@@ -619,7 +618,11 @@
 
 exit:
 	up (&minor_table_mutex);
-	return dev;
+	if (dev) {
+		dev_set_drvdata (&interface->dev, dev);
+		return 0;
+	}
+	return -ENODEV;
 }
 
 
@@ -628,13 +631,17 @@
  *
  *	Called by the usb core when the device is removed from the system.
  */
-static void skel_disconnect(struct usb_device *udev, void *ptr)
+static void skel_disconnect(struct usb_interface *interface)
 {
 	struct usb_skel *dev;
 	int minor;
 
-	dev = (struct usb_skel *)ptr;
-	
+	dev = dev_get_drvdata (&interface->dev);
+	dev_set_drvdata (&interface->dev, NULL);
+
+	if (!dev)
+		return;
+
 	down (&minor_table_mutex);
 	down (&dev->sem);
 		
diff -Nru a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
--- a/drivers/video/matrox/matroxfb_DAC1064.c	Fri Sep 27 14:51:04 2002
+++ b/drivers/video/matrox/matroxfb_DAC1064.c	Fri Sep 27 14:51:04 2002
@@ -276,6 +276,7 @@
 	hw->MXoptionReg = mx;
 }
 
+#ifdef CONFIG_FB_MATROX_G450
 static void g450_set_plls(WPMINFO2) {
 	u_int32_t c2_ctl;
 	unsigned int pxc;
@@ -365,6 +366,7 @@
 		}
 	}
 }
+#endif
 
 void DAC1064_global_init(WPMINFO2) {
 	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
@@ -372,6 +374,7 @@
 	hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
 	hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
 	hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
+#ifdef CONFIG_FB_MATROX_G450
 	if (ACCESS_FBINFO(devflags.g450dac)) {
 		hw->DACreg[POS1064_XPWRCTRL] = 0x1F;	/* powerup everything */
 		hw->DACreg[POS1064_XOUTPUTCONN] = 0x00;	/* disable outputs */
@@ -420,7 +423,9 @@
 		}
 		/* Now set timming related variables... */
 		g450_set_plls(PMINFO2);
-	} else {
+	} else
+#endif
+	{
 		if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) {
 			hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
 			hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
@@ -621,6 +626,7 @@
 	.compute = m1064_compute,
 };
 
+#ifdef CONFIG_FB_MATROX_G450
 static int g450_compute(void* out, struct my_timming* m) {
 #define minfo ((struct matrox_fb_info*)out)
 	if (m->mnp < 0) {
@@ -637,6 +643,7 @@
 	.name	 = "Primary output",
 	.compute = g450_compute,
 };
+#endif
 
 #endif /* NEED_DAC1064 */
 
@@ -819,6 +826,7 @@
 #endif
 
 #ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G450
 static void g450_mclk_init(WPMINFO2) {
 	/* switch all clocks to PCI source */
 	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
@@ -936,6 +944,10 @@
 	
 	return;
 }
+#else
+static inline void g450_preinit(WPMINFO2) {
+}
+#endif
 
 static int MGAG100_preinit(WPMINFO2) {
 	static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
@@ -973,9 +985,12 @@
 	ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
 			? ACCESS_FBINFO(devflags.sgram) : 1;
 
+#ifdef CONFIG_FB_MATROX_G450
 	if (ACCESS_FBINFO(devflags.g450dac)) {
 		ACCESS_FBINFO(outputs[0]).output = &g450out;
-	} else {
+	} else
+#endif
+	{
 		ACCESS_FBINFO(outputs[0]).output = &m1064;
 	}
 	ACCESS_FBINFO(outputs[0]).src = MATROXFB_SRC_CRTC1;
diff -Nru a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
--- a/drivers/video/matrox/matroxfb_base.h	Fri Sep 27 14:51:04 2002
+++ b/drivers/video/matrox/matroxfb_base.h	Fri Sep 27 14:51:04 2002
@@ -105,7 +105,7 @@
 #endif
 #endif
 
-#if defined(__alpha__) || defined(__m68k__)
+#if defined(__alpha__) || defined(__mc68000__)
 #define READx_WORKS
 #define MEMCPYTOIO_WORKS
 #else
@@ -121,7 +121,7 @@
 #endif
 #endif
 
-#if defined(__m68k__)
+#if defined(__mc68000__)
 #define MAP_BUSTOVIRT
 #else
 #define MAP_IOREMAP
diff -Nru a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c	Fri Sep 27 14:51:04 2002
+++ b/fs/bio.c	Fri Sep 27 14:51:04 2002
@@ -322,6 +322,29 @@
 }
 
 /**
+ *	bio_get_nr_vecs		- return approx number of vecs
+ *	@bdev:  I/O target
+ *
+ *	Return the approximate number of pages we can send to this target.
+ *	There's no guarentee that you will be able to fit this number of pages
+ *	into a bio, it does not account for dynamic restrictions that vary
+ *	on offset.
+ */
+int bio_get_nr_vecs(struct block_device *bdev)
+{
+	request_queue_t *q = bdev_get_queue(bdev);
+	int nr_pages;
+
+	nr_pages = q->max_sectors >> (PAGE_SHIFT - 9);
+	if (nr_pages > q->max_phys_segments)
+		nr_pages = q->max_phys_segments;
+	if (nr_pages > q->max_hw_segments)
+		nr_pages = q->max_hw_segments;
+
+	return nr_pages;
+}
+
+/**
  *	bio_add_page	-	attempt to add page to bio
  *	@bio: destination bio
  *	@page: page to add
@@ -635,3 +658,4 @@
 EXPORT_SYMBOL(bio_phys_segments);
 EXPORT_SYMBOL(bio_hw_segments);
 EXPORT_SYMBOL(bio_add_page);
+EXPORT_SYMBOL(bio_get_nr_vecs);
diff -Nru a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c	Fri Sep 27 14:51:05 2002
+++ b/fs/block_dev.c	Fri Sep 27 14:51:05 2002
@@ -652,8 +652,6 @@
 			bdev->bd_offset = 0;
 			if (g)
 				sect = get_capacity(g);
-			else if (blk_size[major(dev)])
-				sect = blk_size[major(dev)][minor(dev)] << 1;
 			bd_set_size(bdev, (loff_t)sect << 9);
 			bdi = blk_get_backing_dev_info(bdev);
 			if (bdi == NULL)
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Fri Sep 27 14:51:04 2002
+++ b/fs/buffer.c	Fri Sep 27 14:51:04 2002
@@ -128,22 +128,18 @@
  */
 void __wait_on_buffer(struct buffer_head * bh)
 {
-	wait_queue_head_t *wq = bh_waitq_head(bh);
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
+	wait_queue_head_t *wqh = bh_waitq_head(bh);
+	DEFINE_WAIT(wait);
 
 	get_bh(bh);
-	add_wait_queue(wq, &wait);
 	do {
+		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
 		blk_run_queues();
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (!buffer_locked(bh))
-			break;
-		schedule();
+		if (buffer_locked(bh))
+			schedule();
 	} while (buffer_locked(bh));
-	tsk->state = TASK_RUNNING;
-	remove_wait_queue(wq, &wait);
 	put_bh(bh);
+	finish_wait(wqh, &wait);
 }
 
 static inline void
@@ -246,10 +242,12 @@
 }
 
 /*
- * sync everything.
+ * sync everything.  Start out by waking pdflush, because that writes back
+ * all queues in parallel.
  */
 asmlinkage long sys_sync(void)
 {
+	wakeup_bdflush(0);
 	sync_inodes(0);	/* All mappings and inodes, including block devices */
 	DQUOT_SYNC(NULL);
 	sync_supers();	/* Write the superblocks */
@@ -458,19 +456,17 @@
 }
 
 /*
- * FIXME: What is this function actually trying to do?  Why "zones[0]"?
- * Is it still correct/needed if/when blockdev mappings use GFP_HIGHUSER?
+ * Kick pdflush then try to free up some ZONE_NORMAL memory.
  */
 static void free_more_memory(void)
 {
 	struct zone *zone;
 
-	zone = contig_page_data.node_zonelists[GFP_NOFS & GFP_ZONEMASK].zones[0];
-
-	wakeup_bdflush();
-	try_to_free_pages(zone, GFP_NOFS, 0);
+	zone = contig_page_data.node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones[0];
+	wakeup_bdflush(1024);
 	blk_run_queues();
 	yield();
+	try_to_free_pages(zone, GFP_NOFS, 0);
 }
 
 /*
diff -Nru a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c	Fri Sep 27 14:51:03 2002
+++ b/fs/dcache.c	Fri Sep 27 14:51:03 2002
@@ -329,12 +329,11 @@
 void prune_dcache(int count)
 {
 	spin_lock(&dcache_lock);
-	for (;;) {
+	for (; count ; count--) {
 		struct dentry *dentry;
 		struct list_head *tmp;
 
 		tmp = dentry_unused.prev;
-
 		if (tmp == &dentry_unused)
 			break;
 		list_del_init(tmp);
@@ -349,12 +348,8 @@
 		dentry_stat.nr_unused--;
 
 		/* Unused dentry with a count? */
-		if (atomic_read(&dentry->d_count))
-			BUG();
-
+		BUG_ON(atomic_read(&dentry->d_count));
 		prune_one_dentry(dentry);
-		if (!--count)
-			break;
 	}
 	spin_unlock(&dcache_lock);
 }
@@ -573,19 +568,11 @@
 
 /*
  * This is called from kswapd when we think we need some
- * more memory, but aren't really sure how much. So we
- * carefully try to free a _bit_ of our dcache, but not
- * too much.
- *
- * Priority:
- *   1 - very urgent: shrink everything
- *  ...
- *   6 - base-level: try to shrink a bit.
+ * more memory. 
  */
-int shrink_dcache_memory(int priority, unsigned int gfp_mask)
+int shrink_dcache_memory(int ratio, unsigned int gfp_mask)
 {
-	int count = 0;
-
+	int entries = dentry_stat.nr_dentry / ratio + 1;
 	/*
 	 * Nasty deadlock avoidance.
 	 *
@@ -600,11 +587,8 @@
 	if (!(gfp_mask & __GFP_FS))
 		return 0;
 
-	count = dentry_stat.nr_unused / priority;
-
-	prune_dcache(count);
-	kmem_cache_shrink(dentry_cache);
-	return 0;
+	prune_dcache(entries);
+	return entries;
 }
 
 #define NAME_ALLOC_LEN(len)	((len+16) & ~15)
diff -Nru a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	Fri Sep 27 14:51:04 2002
+++ b/fs/direct-io.c	Fri Sep 27 14:51:04 2002
@@ -26,7 +26,7 @@
  * The largest-sized BIO which this code will assemble, in bytes.  Set this
  * to PAGE_SIZE if your drivers are broken.
  */
-#define DIO_BIO_MAX_SIZE BIO_MAX_SIZE
+#define DIO_BIO_MAX_SIZE (16*1024)
 
 /*
  * How many user pages to map in one call to get_user_pages().  This determines
diff -Nru a/fs/dquot.c b/fs/dquot.c
--- a/fs/dquot.c	Fri Sep 27 14:51:04 2002
+++ b/fs/dquot.c	Fri Sep 27 14:51:04 2002
@@ -480,26 +480,17 @@
 
 /*
  * This is called from kswapd when we think we need some
- * more memory, but aren't really sure how much. So we
- * carefully try to free a _bit_ of our dqcache, but not
- * too much.
- *
- * Priority:
- *   1 - very urgent: shrink everything
- *   ...
- *   6 - base-level: try to shrink a bit.
+ * more memory
  */
 
-int shrink_dqcache_memory(int priority, unsigned int gfp_mask)
+int shrink_dqcache_memory(int ratio, unsigned int gfp_mask)
 {
-	int count = 0;
+	int entries = dqstats.allocated_dquots / ratio + 1;
 
 	lock_kernel();
-	count = dqstats.free_dquots / priority;
-	prune_dqcache(count);
+	prune_dqcache(entries);
 	unlock_kernel();
-	kmem_cache_shrink(dquot_cachep);
-	return 0;
+	return entries;
 }
 
 /*
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Fri Sep 27 14:51:04 2002
+++ b/fs/exec.c	Fri Sep 27 14:51:04 2002
@@ -537,7 +537,7 @@
 	if (!newsig)
 		return -ENOMEM;
 
-	if (list_empty(&current->thread_group))
+	if (thread_group_empty(current))
 		goto out;
 	/*
 	 * Kill all other threads in the thread group:
@@ -607,21 +607,17 @@
 		ptrace = leader->ptrace;
 		parent = leader->parent;
 
-		ptrace_unlink(leader);
 		ptrace_unlink(current);
+		ptrace_unlink(leader);
 		remove_parent(current);
 		remove_parent(leader);
-		/*
-		 * Split up the last two remaining members of the
-		 * thread group:
-		 */
-		list_del_init(&leader->thread_group);
 
-		leader->pid = leader->tgid = current->pid;
-		current->pid = current->tgid;
+		switch_exec_pids(leader, current);
+
 		current->parent = current->real_parent = leader->real_parent;
 		leader->parent = leader->real_parent = child_reaper;
-		current->exit_signal = SIGCHLD;
+		current->group_leader = current;
+		leader->group_leader = leader;
 
 		add_parent(current, current->parent);
 		add_parent(leader, leader->parent);
@@ -631,15 +627,17 @@
 		}
 		
 		list_add_tail(&current->tasks, &init_task.tasks);
+		current->exit_signal = SIGCHLD;
 		state = leader->state;
+
 		write_unlock_irq(&tasklist_lock);
 
+		put_proc_dentry(proc_dentry1);
+		put_proc_dentry(proc_dentry2);
+
 		if (state != TASK_ZOMBIE)
 			BUG();
 		release_task(leader);
-
-		put_proc_dentry(proc_dentry1);
-		put_proc_dentry(proc_dentry2);
         }
 
 out:
@@ -661,7 +659,7 @@
 	if (atomic_dec_and_test(&oldsig->count))
 		kmem_cache_free(sigact_cachep, oldsig);
 
-	if (!list_empty(&current->thread_group))
+	if (!thread_group_empty(current))
 		BUG();
 	if (current->tgid != current->pid)
 		BUG();
diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
--- a/fs/ext2/ialloc.c	Fri Sep 27 14:51:04 2002
+++ b/fs/ext2/ialloc.c	Fri Sep 27 14:51:04 2002
@@ -16,9 +16,9 @@
 #include "ext2.h"
 #include <linux/quotaops.h>
 #include <linux/sched.h>
+#include <linux/backing-dev.h>
 #include <linux/buffer_head.h>
 
-
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
  */
@@ -169,6 +169,13 @@
 	unsigned long block;
 	struct buffer_head *bh;
 	struct ext2_group_desc * gdp;
+	struct backing_dev_info *bdi;
+
+	bdi = inode->i_mapping->backing_dev_info;
+	if (bdi_read_congested(bdi))
+		return;
+	if (bdi_write_congested(bdi))
+		return;
 
 	block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
 	gdp = ext2_get_group_desc(inode->i_sb, block_group, &bh);
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Fri Sep 27 14:51:04 2002
+++ b/fs/ext3/inode.c	Fri Sep 27 14:51:04 2002
@@ -1473,7 +1473,7 @@
 };
 
 /* For writeback mode, we can use mpage_writepages() */
-
+#if 0	/* Doesn't work for shared mappings */
 static int
 ext3_writepages(struct address_space *mapping, struct writeback_control *wbc)
 {
@@ -1486,12 +1486,12 @@
 		ret = err;
 	return ret;
 }
+#endif
 
 struct address_space_operations ext3_writeback_aops = {
 	.readpage	= ext3_readpage,	/* BKL not held.  Don't need */
 	.readpages	= ext3_readpages,	/* BKL not held.  Don't need */
 	.writepage	= ext3_writepage,	/* BKL not held.  We take it */
-	.writepages	= ext3_writepages,	/* BKL not held.  Don't need */
 	.sync_page	= block_sync_page,
 	.prepare_write	= ext3_prepare_write,	/* BKL not held.  We take it */
 	.commit_write	= ext3_commit_write,	/* BKL not held.  We take it */
diff -Nru a/fs/fs-writeback.c b/fs/fs-writeback.c
--- a/fs/fs-writeback.c	Fri Sep 27 14:51:04 2002
+++ b/fs/fs-writeback.c	Fri Sep 27 14:51:04 2002
@@ -220,44 +220,52 @@
  *
  * FIXME: this linear search could get expensive with many fileystems.  But
  * how to fix?  We need to go from an address_space to all inodes which share
- * a queue with that address_space.
+ * a queue with that address_space.  (Easy: have a global "dirty superblocks"
+ * list).
  *
  * The inodes to be written are parked on sb->s_io.  They are moved back onto
  * sb->s_dirty as they are selected for writing.  This way, none can be missed
  * on the writer throttling path, and we get decent balancing between many
- * thrlttled threads: we don't want them all piling up on __wait_on_inode.
+ * throlttled threads: we don't want them all piling up on __wait_on_inode.
  */
 static void
 sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
 {
-	struct list_head *tmp;
-	struct list_head *head;
 	const unsigned long start = jiffies;	/* livelock avoidance */
 
 	list_splice_init(&sb->s_dirty, &sb->s_io);
-	head = &sb->s_io;
-	while ((tmp = head->prev) != head) {
-		struct inode *inode = list_entry(tmp, struct inode, i_list);
+	while (!list_empty(&sb->s_io)) {
+		struct inode *inode = list_entry(sb->s_io.prev,
+						struct inode, i_list);
 		struct address_space *mapping = inode->i_mapping;
-		struct backing_dev_info *bdi;
+		struct backing_dev_info *bdi = mapping->backing_dev_info;
 		int really_sync;
 
-		if (wbc->bdi && mapping->backing_dev_info != wbc->bdi) {
+		if (wbc->nonblocking && bdi_write_congested(bdi)) {
+			wbc->encountered_congestion = 1;
 			if (sb != blockdev_superblock)
-				break;		/* inappropriate superblock */
+				break;		/* Skip a congested fs */
 			list_move(&inode->i_list, &sb->s_dirty);
-			continue;		/* not this blockdev */
+			continue;		/* Skip a congested blockdev */
+		}
+
+		if (wbc->bdi && bdi != wbc->bdi) {
+			if (sb != blockdev_superblock)
+				break;		/* fs has the wrong queue */
+			list_move(&inode->i_list, &sb->s_dirty);
+			continue;		/* blockdev has wrong queue */
 		}
 
 		/* Was this inode dirtied after sync_sb_inodes was called? */
 		if (time_after(mapping->dirtied_when, start))
 			break;
 
+		/* Was this inode dirtied too recently? */
 		if (wbc->older_than_this && time_after(mapping->dirtied_when,
 						*wbc->older_than_this))
-			goto out;
+			break;
 
-		bdi = mapping->backing_dev_info;
+		/* Is another pdflush already flushing this queue? */
 		if (current_is_pdflush() && !writeback_acquire(bdi))
 			break;
 
@@ -278,11 +286,7 @@
 		if (wbc->nr_to_write <= 0)
 			break;
 	}
-out:
-	/*
-	 * Leave any unwritten inodes on s_io.
-	 */
-	return;
+	return;		/* Leave any unwritten inodes on s_io */
 }
 
 /*
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	Fri Sep 27 14:51:05 2002
+++ b/fs/inode.c	Fri Sep 27 14:51:05 2002
@@ -386,10 +386,11 @@
 
 	count = 0;
 	entry = inode_unused.prev;
-	while (entry != &inode_unused)
-	{
+	for(; goal; goal--) {
 		struct list_head *tmp = entry;
 
+		if (entry == &inode_unused)
+			break;
 		entry = entry->prev;
 		inode = INODE(tmp);
 		if (inode->i_state & (I_FREEING|I_CLEAR|I_LOCK))
@@ -403,8 +404,6 @@
 		list_add(tmp, freeable);
 		inode->i_state |= I_FREEING;
 		count++;
-		if (!--goal)
-			break;
 	}
 	inodes_stat.nr_unused -= count;
 	spin_unlock(&inode_lock);
@@ -414,19 +413,11 @@
 
 /*
  * This is called from kswapd when we think we need some
- * more memory, but aren't really sure how much. So we
- * carefully try to free a _bit_ of our icache, but not
- * too much.
- *
- * Priority:
- *   1 - very urgent: shrink everything
- *  ...
- *   6 - base-level: try to shrink a bit.
+ * more memory. 
  */
-int shrink_icache_memory(int priority, int gfp_mask)
+int shrink_icache_memory(int ratio, unsigned int gfp_mask)
 {
-	int count = 0;
-
+	int entries = inodes_stat.nr_inodes / ratio + 1;
 	/*
 	 * Nasty deadlock avoidance..
 	 *
@@ -437,12 +428,10 @@
 	if (!(gfp_mask & __GFP_FS))
 		return 0;
 
-	count = inodes_stat.nr_unused / priority;
-
-	prune_icache(count);
-	kmem_cache_shrink(inode_cachep);
-	return 0;
+	prune_icache(entries);
+	return entries;
 }
+EXPORT_SYMBOL(shrink_icache_memory);
 
 /*
  * Called with the inode lock held.
diff -Nru a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
--- a/fs/jfs/jfs_dmap.c	Fri Sep 27 14:51:05 2002
+++ b/fs/jfs/jfs_dmap.c	Fri Sep 27 14:51:05 2002
@@ -648,7 +648,7 @@
 	agpref = bmp->db_agpref;
 	if ((atomic_read(&bmp->db_active[agpref]) == 0) &&
 	    (bmp->db_agfree[agpref] >= avgfree))
-		goto found;
+		goto unlock;
 
 	/* From the last preferred ag, find the next one with at least
 	 * average free space.
@@ -660,9 +660,12 @@
 		if (atomic_read(&bmp->db_active[agpref]))
 			/* open file is currently growing in this ag */
 			continue;
-		if (bmp->db_agfree[agpref] >= avgfree)
-			goto found;
-		else if (bmp->db_agfree[agpref] > hwm) {
+		if (bmp->db_agfree[agpref] >= avgfree) {
+			/* Return this one */
+			bmp->db_agpref = agpref;
+			goto unlock;
+		} else if (bmp->db_agfree[agpref] > hwm) {
+			/* Less than avg. freespace, but best so far */
 			hwm = bmp->db_agfree[agpref];
 			next_best = agpref;
 		}
@@ -673,12 +676,9 @@
 	 * next best
 	 */
 	if (next_best != -1)
-		agpref = next_best;
-
-	/* else agpref should be back to its original value */
-
-found:
-	bmp->db_agpref = agpref;
+		bmp->db_agpref = next_best;
+	/* else leave db_agpref unchanged */
+unlock:
 	BMAP_UNLOCK(bmp);
 
 	/* return the preferred group.
diff -Nru a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
--- a/fs/jfs/jfs_dtree.c	Fri Sep 27 14:51:03 2002
+++ b/fs/jfs/jfs_dtree.c	Fri Sep 27 14:51:03 2002
@@ -2831,6 +2831,86 @@
 }
 
 /*
+ *	add_missing_indices()
+ *
+ * function: Fix dtree page in which one or more entries has an invalid index.
+ *	     fsck.jfs should really fix this, but it currently does not.
+ *	     Called from jfs_readdir when bad index is detected.
+ */
+static void add_missing_indices(struct inode *inode, s64 bn)
+{
+	struct ldtentry *d;
+	struct dt_lock *dtlck;
+	int i;
+	uint index;
+	struct lv *lv;
+	struct metapage *mp;
+	dtpage_t *p;
+	int rc;
+	s8 *stbl;
+	tid_t tid;
+	struct tlock *tlck;
+
+	tid = txBegin(inode->i_sb, 0);
+
+	DT_GETPAGE(inode, bn, mp, PSIZE, p, rc);
+
+	if (rc) {
+		printk(KERN_ERR "DT_GETPAGE failed!\n");
+		goto end;
+	}
+	BT_MARK_DIRTY(mp, inode);
+
+	ASSERT(p->header.flag & BT_LEAF);
+
+	tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY);
+	dtlck = (struct dt_lock *) &tlck->lock;
+
+	stbl = DT_GETSTBL(p);
+	for (i = 0; i < p->header.nextindex; i++) {
+		d = (struct ldtentry *) &p->slot[stbl[i]];
+		index = le32_to_cpu(d->index);
+		if ((index < 2) || (index >= JFS_IP(inode)->next_index)) {
+			d->index = cpu_to_le32(add_index(tid, inode, bn, i));
+			if (dtlck->index >= dtlck->maxcnt)
+				dtlck = (struct dt_lock *) txLinelock(dtlck);
+			lv = dtlck->lv;
+			lv->offset = stbl[i];
+			lv->length = 1;
+			dtlck->index++;
+		}
+	}
+
+	DT_PUTPAGE(mp);
+	(void) txCommit(tid, 1, &inode, 0);
+end:
+	txEnd(tid);
+}
+
+/*
+ * Buffer to hold directory entry info while traversing a dtree page
+ * before being fed to the filldir function
+ */
+struct jfs_dirent {
+	loff_t position;
+	int ino;
+	u16 name_len;
+	char name[0];
+};
+
+/*
+ * function to determine next variable-sized jfs_dirent in buffer
+ */
+inline struct jfs_dirent *next_jfs_dirent(struct jfs_dirent *dirent)
+{
+	return (struct jfs_dirent *)
+		((char *)dirent +
+		 ((sizeof (struct jfs_dirent) + dirent->name_len + 1 +
+		   sizeof (loff_t) - 1) &
+		  ~(sizeof (loff_t) - 1)));
+}
+
+/*
  *	jfs_readdir()
  *
  * function: read directory entries sequentially
@@ -2846,11 +2926,12 @@
 	struct inode *ip = filp->f_dentry->d_inode;
 	struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab;
 	int rc = 0;
+	loff_t dtpos;	/* legacy OS/2 style position */
 	struct dtoffset {
 		s16 pn;
 		s16 index;
 		s32 unused;
-	} *dtoffset = (struct dtoffset *) &filp->f_pos;
+	} *dtoffset = (struct dtoffset *) &dtpos;
 	s64 bn;
 	struct metapage *mp;
 	dtpage_t *p;
@@ -2860,12 +2941,17 @@
 	int i, next;
 	struct ldtentry *d;
 	struct dtslot *t;
-	int d_namleft, d_namlen, len, outlen;
-	char *d_name, *name_ptr;
+	int d_namleft, len, outlen;
+	unsigned long dirent_buf;
+	char *name_ptr;
 	int dtlhdrdatalen;
 	u32 dir_index;
 	int do_index = 0;
 	uint loop_count = 0;
+	struct jfs_dirent *jfs_dirent;
+	int jfs_dirents;
+	int overflow, fix_page, page_fixed = 0;
+	static int unique_pos = 2;	/* If we can't fix broken index */
 
 	if (filp->f_pos == DIREND)
 		return 0;
@@ -2885,7 +2971,9 @@
 		if (dir_index > 1) {
 			struct dir_table_slot dirtab_slot;
 
-			if (dtEmpty(ip)) {
+			if (dtEmpty(ip) ||
+			    (dir_index >= JFS_IP(ip)->next_index)) {
+				/* Stale position.  Directory has shrunk */
 				filp->f_pos = DIREND;
 				return 0;
 			}
@@ -2963,13 +3051,15 @@
 		 */
 		dtlhdrdatalen = DTLHDRDATALEN_LEGACY;
 
-		if (filp->f_pos == 0) {
+		dtpos = filp->f_pos;
+		if (dtpos == 0) {
 			/* build "." entry */
 
 			if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino,
 				    DT_DIR))
 				return 0;
 			dtoffset->index = 1;
+			filp->f_pos = dtpos;
 		}
 
 		if (dtoffset->pn == 0) {
@@ -2985,6 +3075,7 @@
 			}
 			dtoffset->pn = 1;
 			dtoffset->index = 0;
+			filp->f_pos = dtpos;
 		}
 
 		if (dtEmpty(ip)) {
@@ -3009,32 +3100,72 @@
 		}
 	}
 
-	d_name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), GFP_NOFS);
-	if (d_name == NULL) {
+	dirent_buf = __get_free_page(GFP_KERNEL);
+	if (dirent_buf == 0) {
 		DT_PUTPAGE(mp);
-		jERROR(1, ("jfs_readdir: kmalloc failed!\n"));
+		jERROR(1, ("jfs_readdir: __get_free_page failed!\n"));
 		filp->f_pos = DIREND;
-		return 0;
+		return -ENOMEM;
 	}
+
 	while (1) {
+		jfs_dirent = (struct jfs_dirent *) dirent_buf;
+		jfs_dirents = 0;
+		overflow = fix_page = 0;
+
 		stbl = DT_GETSTBL(p);
 
 		for (i = index; i < p->header.nextindex; i++) {
 			d = (struct ldtentry *) & p->slot[stbl[i]];
 
+			if (((long) jfs_dirent + d->namlen + 1) >
+			    (dirent_buf + PSIZE)) {
+				/* DBCS codepages could overrun dirent_buf */
+				index = i;
+				overflow = 1;
+				break;
+			}
+
 			d_namleft = d->namlen;
-			name_ptr = d_name;
+			name_ptr = jfs_dirent->name;
+			jfs_dirent->ino = le32_to_cpu(d->inumber);
 
 			if (do_index) {
-				filp->f_pos = le32_to_cpu(d->index);
 				len = min(d_namleft, DTLHDRDATALEN);
-			} else
+				jfs_dirent->position = le32_to_cpu(d->index);
+				/*
+				 * d->index should always be valid, but it
+				 * isn't.  fsck.jfs doesn't create the
+				 * directory index for the lost+found
+				 * directory.  Rather than let it go,
+				 * we can try to fix it.
+				 */
+				if ((jfs_dirent->position < 2) ||
+				    (jfs_dirent->position >=
+				     JFS_IP(ip)->next_index)) {
+					if (!page_fixed && !isReadOnly(ip)) {
+						fix_page = 1;
+						/*
+						 * setting overflow and setting
+						 * index to i will cause the
+						 * same page to be processed
+						 * again starting here
+						 */
+						overflow = 1;
+						index = i;
+						break;
+					}
+					jfs_dirent->position = unique_pos++;
+				}
+			} else {
+				jfs_dirent->position = dtpos;
 				len = min(d_namleft, DTLHDRDATALEN_LEGACY);
+			}
 
 			/* copy the name of head/only segment */
 			outlen = jfs_strfromUCS_le(name_ptr, d->name, len,
 						   codepage);
-			d_namlen = outlen;
+			jfs_dirent->name_len = outlen;
 
 			/* copy name in the additional segment(s) */
 			next = d->next;
@@ -3053,56 +3184,66 @@
 				len = min(d_namleft, DTSLOTDATALEN);
 				outlen = jfs_strfromUCS_le(name_ptr, t->name,
 							   len, codepage);
-				d_namlen+= outlen;
+				jfs_dirent->name_len += outlen;
 
 				next = t->next;
 			}
 
-			if (filldir(dirent, d_name, d_namlen, filp->f_pos,
-				    le32_to_cpu(d->inumber), DT_UNKNOWN))
-				goto out;
+			jfs_dirents++;
+			jfs_dirent = next_jfs_dirent(jfs_dirent);
 skip_one:
 			if (!do_index)
 				dtoffset->index++;
 		}
 
-		/*
-		 * get next leaf page
-		 */
+		if (!overflow) {
+			/* Point to next leaf page */
+			if (p->header.flag & BT_ROOT)
+				bn = 0;
+			else {
+				bn = le64_to_cpu(p->header.next);
+				index = 0;
+				/* update offset (pn:index) for new page */
+				if (!do_index) {
+					dtoffset->pn++;
+					dtoffset->index = 0;
+				}
+			}
+			page_fixed = 0;
+		}
 
-		if (p->header.flag & BT_ROOT) {
-			filp->f_pos = DIREND;
-			break;
+		/* unpin previous leaf page */
+		DT_PUTPAGE(mp);
+
+		jfs_dirent = (struct jfs_dirent *) dirent_buf;
+		while (jfs_dirents--) {
+			filp->f_pos = jfs_dirent->position;
+			if (filldir(dirent, jfs_dirent->name,
+				    jfs_dirent->name_len, filp->f_pos,
+				    jfs_dirent->ino, DT_UNKNOWN))
+				goto out;
+			jfs_dirent = next_jfs_dirent(jfs_dirent);
 		}
 
-		bn = le64_to_cpu(p->header.next);
-		if (bn == 0) {
+		if (fix_page) {
+			add_missing_indices(ip, bn);
+			page_fixed = 1;
+		}
+
+		if (!overflow && (bn == 0)) {
 			filp->f_pos = DIREND;
 			break;
 		}
 
-		/* unpin previous leaf page */
-		DT_PUTPAGE(mp);
-
-		/* get next leaf page */
 		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
 		if (rc) {
-			kfree(d_name);
+			free_page(dirent_buf);
 			return -rc;
 		}
-
-		/* update offset (pn:index) for new page */
-		index = 0;
-		if (!do_index) {
-			dtoffset->pn++;
-			dtoffset->index = 0;
-		}
-
 	}
 
       out:
-	kfree(d_name);
-	DT_PUTPAGE(mp);
+	free_page(dirent_buf);
 
 	return rc;
 }
diff -Nru a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c	Fri Sep 27 14:51:03 2002
+++ b/fs/jfs/jfs_imap.c	Fri Sep 27 14:51:03 2002
@@ -365,11 +365,7 @@
 
 	if ((lengthPXD(&iagp->inoext[extno]) != imap->im_nbperiext) ||
 	    (addressPXD(&iagp->inoext[extno]) == 0)) {
-		jERROR(1, ("diRead: Bad inoext: 0x%lx, 0x%lx\n",
-			   (ulong) addressPXD(&iagp->inoext[extno]),
-			   (ulong) lengthPXD(&iagp->inoext[extno])));
 		release_metapage(mp);
-		updateSuper(ip->i_sb, FM_DIRTY);
 		return ESTALE;
 	}
 
@@ -416,12 +412,9 @@
 		jERROR(1, ("diRead: i_ino != di_number\n"));
 		updateSuper(ip->i_sb, FM_DIRTY);
 		rc = EIO;
-	} else if (le32_to_cpu(dp->di_nlink) == 0) {
-		jERROR(1,
-		       ("diRead: di_nlink is zero. ino=%ld\n", ip->i_ino));
-		updateSuper(ip->i_sb, FM_DIRTY);
+	} else if (le32_to_cpu(dp->di_nlink) == 0)
 		rc = ESTALE;
-	} else
+	else
 		/* copy the disk inode to the in-memory inode */
 		rc = copy_from_dinode(dp, ip);
 
diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
--- a/fs/jfs/jfs_logmgr.c	Fri Sep 27 14:51:04 2002
+++ b/fs/jfs/jfs_logmgr.c	Fri Sep 27 14:51:04 2002
@@ -1552,7 +1552,12 @@
 				memcpy(logsuper->active[i].uuid, NULL_UUID, 16);
 				break;
 			}
-		assert(i < MAX_ACTIVE);
+		if (i == MAX_ACTIVE) {
+			jERROR(1,("Somebody stomped on the journal!\n"));
+			lbmFree(bpsuper);
+			return EIO;
+		}
+		
 	}
 
 	/*
diff -Nru a/fs/locks.c b/fs/locks.c
--- a/fs/locks.c	Fri Sep 27 14:51:05 2002
+++ b/fs/locks.c	Fri Sep 27 14:51:05 2002
@@ -252,8 +252,8 @@
 		return -ENOMEM;
 
 	fl->fl_file = filp;
-	fl->fl_pid = current->pid;
-	fl->fl_flags = FL_FLOCK;
+	fl->fl_pid = current->tgid;
+	fl->fl_flags = (cmd & LOCK_NB) ? FL_FLOCK : FL_FLOCK | FL_SLEEP;
 	fl->fl_type = type;
 	fl->fl_end = OFFSET_MAX;
 	
@@ -308,7 +308,7 @@
 		fl->fl_end = OFFSET_MAX;
 	
 	fl->fl_owner = current->files;
-	fl->fl_pid = current->pid;
+	fl->fl_pid = current->tgid;
 	fl->fl_file = filp;
 	fl->fl_flags = FL_POSIX;
 	fl->fl_notify = NULL;
@@ -348,7 +348,7 @@
 		fl->fl_end = OFFSET_MAX;
 	
 	fl->fl_owner = current->files;
-	fl->fl_pid = current->pid;
+	fl->fl_pid = current->tgid;
 	fl->fl_file = filp;
 	fl->fl_flags = FL_POSIX;
 	fl->fl_notify = NULL;
@@ -377,7 +377,7 @@
 		return -ENOMEM;
 
 	fl->fl_owner = current->files;
-	fl->fl_pid = current->pid;
+	fl->fl_pid = current->tgid;
 
 	fl->fl_file = filp;
 	fl->fl_flags = FL_LEASE;
@@ -669,7 +669,7 @@
 	int error;
 
 	fl.fl_owner = current->files;
-	fl.fl_pid = current->pid;
+	fl.fl_pid = current->tgid;
 	fl.fl_file = filp;
 	fl.fl_flags = FL_POSIX | FL_ACCESS | FL_SLEEP;
 	fl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK;
@@ -1241,7 +1241,7 @@
 	*before = fl;
 	list_add(&fl->fl_link, &file_lock_list);
 
-	error = f_setown(filp, current->pid, 1);
+	error = f_setown(filp, current->tgid, 1);
 out_unlock:
 	unlock_kernel();
 	return error;
@@ -1459,10 +1459,8 @@
 		break;
 	}
 
-out:
-	if (error) {
-		locks_free_lock(file_lock);
-	}
+ out:
+	locks_free_lock(file_lock);
 	return error;
 }
 
@@ -1601,11 +1599,8 @@
 		break;
 	}
 
-
 out:
-	if (error) {
-		locks_free_lock(file_lock);
-	}
+	locks_free_lock(file_lock);
 	return error;
 }
 #endif /* BITS_PER_LONG == 32 */
@@ -1632,7 +1627,7 @@
 	lock.fl_start = 0;
 	lock.fl_end = OFFSET_MAX;
 	lock.fl_owner = owner;
-	lock.fl_pid = current->pid;
+	lock.fl_pid = current->tgid;
 	lock.fl_file = filp;
 
 	if (filp->f_op && filp->f_op->lock != NULL) {
diff -Nru a/fs/mpage.c b/fs/mpage.c
--- a/fs/mpage.c	Fri Sep 27 14:51:03 2002
+++ b/fs/mpage.c	Fri Sep 27 14:51:03 2002
@@ -22,6 +22,7 @@
 #include <linux/prefetch.h>
 #include <linux/mpage.h>
 #include <linux/writeback.h>
+#include <linux/backing-dev.h>
 #include <linux/pagevec.h>
 
 /*
@@ -522,6 +523,7 @@
 mpage_writepages(struct address_space *mapping,
 		struct writeback_control *wbc, get_block_t get_block)
 {
+	struct backing_dev_info *bdi = mapping->backing_dev_info;
 	struct bio *bio = NULL;
 	sector_t last_block_in_bio = 0;
 	int ret = 0;
@@ -530,6 +532,12 @@
 	struct pagevec pvec;
 	int (*writepage)(struct page *);
 
+	if (wbc->nonblocking && bdi_write_congested(bdi)) {
+		blk_run_queues();
+		wbc->encountered_congestion = 1;
+		return 0;
+	}
+
 	writepage = NULL;
 	if (get_block == NULL)
 		writepage = mapping->a_ops->writepage;
@@ -585,6 +593,11 @@
 			}
 			if (ret || (--(wbc->nr_to_write) <= 0))
 				done = 1;
+			if (wbc->nonblocking && bdi_write_congested(bdi)) {
+				blk_run_queues();
+				wbc->encountered_congestion = 1;
+				done = 1;
+			}
 		} else {
 			unlock_page(page);
 		}
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Fri Sep 27 14:51:04 2002
+++ b/fs/partitions/check.c	Fri Sep 27 14:51:04 2002
@@ -362,7 +362,7 @@
 		pos = devfs_generate_path(dev->disk_de, rname+3, sizeof(rname)-3);
 		if (pos >= 0) {
 			strncpy(rname + pos, "../", 3);
-			devfs_mk_symlink(devfs_handle, vname,
+			devfs_mk_symlink(cdroms, vname,
 					 DEVFS_FL_DEFAULT,
 					 rname + pos, &slave, NULL);
 			devfs_auto_unregister(dev->de, slave);
diff -Nru a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
--- a/fs/reiserfs/bitmap.c	Fri Sep 27 14:51:04 2002
+++ b/fs/reiserfs/bitmap.c	Fri Sep 27 14:51:04 2002
@@ -395,7 +395,7 @@
 
     REISERFS_SB(s)->s_alloc_options.bits = 0; /* clear default settings */
 
-    for (this_char = strsep (&options, ":"); this_char != NULL; ) {
+    while ( (this_char = strsep (&options, ":")) != NULL ) {
 	if ((value = strchr (this_char, '=')) != NULL)
 	    *value++ = 0;
 
diff -Nru a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c
--- a/fs/xfs/linux/xfs_aops.c	Fri Sep 27 14:51:05 2002
+++ b/fs/xfs/linux/xfs_aops.c	Fri Sep 27 14:51:05 2002
@@ -37,10 +37,38 @@
 #include <linux/iobuf.h>
 
 
-STATIC int linvfs_pb_bmap(struct inode *, loff_t, ssize_t,
-			  struct page_buf_bmap_s *, int);
 STATIC int delalloc_convert(struct inode *, struct page *, int, int);
 
+STATIC int
+map_blocks(
+	struct inode		*inode,
+	loff_t			offset,
+	ssize_t			count,
+	page_buf_bmap_t		*pbmapp,
+	int			flags)
+{
+	vnode_t			*vp = LINVFS_GET_VP(inode);
+	int			error, nmaps = 1;
+
+retry:
+	if (flags & PBF_FILE_ALLOCATE) {
+		VOP_STRATEGY(vp, offset, count, flags, NULL,
+				pbmapp, &nmaps, error);
+	} else {
+		VOP_BMAP(vp, offset, count, flags, NULL,
+				pbmapp, &nmaps, error);
+	}
+	if (flags & PBF_WRITE) {
+		if (unlikely((flags & PBF_DIRECT) && nmaps &&
+		    (pbmapp->pbm_flags & PBMF_DELAY))) {
+			flags = PBF_WRITE | PBF_FILE_ALLOCATE;
+			goto retry;
+		}
+		VMODIFY(vp);
+	}
+	return -error;
+}
+
 /*
  * match_offset_to_mapping
  * Finds the corresponding mapping in block @map array of the
@@ -195,7 +223,7 @@
 	page = find_get_page(mapping, index);
 	if (!page)
 		return 0;
-	if (TestSetPageLocked(page)) {
+	if (PageWriteback(page) || TestSetPageLocked(page)) {
 		page_cache_release(page);
 		return 0;
 	}
@@ -274,7 +302,7 @@
 	page = find_get_page(inode->i_mapping, index);
 	if (!page)
 		return NULL;
-	if (TestSetPageLocked(page)) {
+	if (PageWriteback(page) || TestSetPageLocked(page)) {
 		page_cache_release(page);
 		return NULL;
 	}
@@ -303,6 +331,7 @@
 
 	BUG_ON(PageWriteback(page));
 	SetPageWriteback(page);
+	clear_page_dirty(page);
 	unlock_page(page);
 
 	if (cnt) {
@@ -461,7 +490,7 @@
 
 		if (buffer_delay(bh)) {
 			if (!mp) {
-				err = linvfs_pb_bmap(inode, offset, len, &map,
+				err = map_blocks(inode, offset, len, &map,
 						PBF_WRITE|PBF_FILE_ALLOCATE);
 				if (err)
 					goto error;
@@ -487,7 +516,7 @@
 			if (!mp) {
 				size = probe_unmapped_cluster(inode, page,
 								bh, head);
-				err = linvfs_pb_bmap(inode, offset, size, &map,
+				err = map_blocks(inode, offset, size, &map,
 						PBF_WRITE|PBF_DIRECT);
 				if (err)
 					goto error;
@@ -662,36 +691,6 @@
 }
 
 STATIC int
-linvfs_pb_bmap(
-	struct inode		*inode,
-	loff_t			offset,
-	ssize_t			count,
-	page_buf_bmap_t		*pbmapp,
-	int			flags)
-{
-	vnode_t			*vp = LINVFS_GET_VP(inode);
-	int			error, nmaps = 1;
-
-retry:
-	if (flags & PBF_FILE_ALLOCATE) {
-		VOP_STRATEGY(vp, offset, count, flags, NULL,
-				pbmapp, &nmaps, error);
-	} else {
-		VOP_BMAP(vp, offset, count, flags, NULL,
-				pbmapp, &nmaps, error);
-	}
-	if (flags & PBF_WRITE) {
-		if (unlikely((flags & PBF_DIRECT) && nmaps &&
-		    (pbmapp->pbm_flags & PBMF_DELAY))) {
-			flags = PBF_WRITE | PBF_FILE_ALLOCATE;
-			goto retry;
-		}
-		VMODIFY(vp);
-	}
-	return -error;
-}
-
-STATIC int
 linvfs_bmap(
 	struct address_space	*mapping,
 	long			block)
@@ -714,11 +713,11 @@
 }
 
 STATIC int
-linvfs_read_full_page(
+linvfs_readpage(
 	struct file		*unused,
 	struct page		*page)
 {
-	return block_read_full_page(page, linvfs_get_block);
+	return mpage_readpage(page, linvfs_get_block);
 }
 
 STATIC int
@@ -759,7 +758,7 @@
 }
 
 STATIC int
-linvfs_write_full_page(
+linvfs_writepage(
 	struct page		*page)
 {
 	int			error;
@@ -801,118 +800,6 @@
 	}
 }
 
-#if 0
-/* Keeping this for now as an example of a better way of
- * doing O_DIRECT for XFS - the generic path has more
- * overhead than we want.
- */
-
-/*
- * Initiate I/O on a kiobuf of user memory
- */
-STATIC int
-linvfs_direct_IO(
-	int			rw,
-	struct inode		*inode,
-	struct kiobuf		*iobuf,
-	unsigned long		blocknr,
-	int			blocksize)
-{
-	struct page		**maplist;
-	size_t			page_offset;
-	page_buf_t		*pb;
-	page_buf_bmap_t		map;
-	int			error = 0;
-	int			pb_flags, map_flags, pg_index = 0;
-	size_t			length, total;
-	loff_t			offset;
-	size_t			map_size, size;
-
-	total = length = iobuf->length;
-	offset = blocknr;
-	offset <<= inode->i_blkbits;
-
-	maplist = iobuf->maplist;
-	page_offset = iobuf->offset;
-
-	map_flags = (rw ? PBF_WRITE : PBF_READ) | PBF_DIRECT;
-	pb_flags = (rw ? PBF_WRITE : PBF_READ) | PBF_FORCEIO | _PBF_LOCKABLE;
-	while (length) {
-		error = linvfs_pb_bmap(inode, offset, length, &map, map_flags);
-		if (error)
-			break;
-
-		map_size = map.pbm_bsize - map.pbm_delta;
-		size = min(map_size, length);
-		if (map.pbm_flags & PBMF_HOLE) {
-			size_t	zero_len = size;
-
-			if (rw == WRITE)
-				break;
-
-			/* Need to zero it all */
-			while (zero_len) {
-				struct page	*page;
-				size_t		pg_len;
-
-				pg_len = min((size_t)
-						(PAGE_CACHE_SIZE - page_offset),
-						zero_len);
-
-				page = maplist[pg_index];
-
-				memset(kmap(page) + page_offset, 0, pg_len);
-				flush_dcache_page(page);
-				kunmap(page);
-
-				zero_len -= pg_len;
-				if ((pg_len + page_offset) == PAGE_CACHE_SIZE) {
-					pg_index++;
-					page_offset = 0;
-				} else {
-					page_offset = (page_offset + pg_len) &
-							~PAGE_CACHE_MASK;
-				}
-			}
-		} else {
-			int	pg_count;
-
-			pg_count = (size + page_offset + PAGE_CACHE_SIZE - 1)
-					>> PAGE_CACHE_SHIFT;
-			if ((pb = pagebuf_lookup(map.pbm_target, inode, offset,
-						size, pb_flags)) == NULL) {
-				error = -ENOMEM;
-				break;
-			}
-			/* Need to hook up pagebuf to kiobuf pages */
-			pb->pb_pages = &maplist[pg_index];
-			pb->pb_offset = page_offset;
-			pb->pb_page_count = pg_count;
-
-			pb->pb_bn = map.pbm_bn + (map.pbm_delta >> 9);
-			error = pagebuf_iostart(pb, pb_flags);
-			pb->pb_flags &= ~_PBF_LOCKABLE;
-			pagebuf_rele(pb);
-			if (error != 0) {
-				if (error > 0)
-					error = -error;
-				break;
-			}
-
-			page_offset = (page_offset + size) & ~PAGE_CACHE_MASK;
-			if (page_offset)
-				pg_count--;
-			pg_index += pg_count;
-		}
-
-		offset += size;
-		length -= size;
-	}
-
-	return (error ? error : (int)(total - length));
-}
-#endif
-
 /*
  * This gets a page into cleanable state - page locked on entry
  * kept locked on exit. If the page is marked dirty we should
@@ -945,9 +832,9 @@
 
 
 struct address_space_operations linvfs_aops = {
-	.readpage		= linvfs_read_full_page,
+	.readpage		= linvfs_readpage,
 	.readpages		= linvfs_readpages,
-	.writepage		= linvfs_write_full_page,
+	.writepage		= linvfs_writepage,
 	.sync_page		= block_sync_page,
 	.releasepage		= linvfs_release_page,
 	.prepare_write		= linvfs_prepare_write,
diff -Nru a/fs/xfs/linux/xfs_file.c b/fs/xfs/linux/xfs_file.c
--- a/fs/xfs/linux/xfs_file.c	Fri Sep 27 14:51:04 2002
+++ b/fs/xfs/linux/xfs_file.c	Fri Sep 27 14:51:04 2002
@@ -40,70 +40,76 @@
 
 
 STATIC ssize_t
-linvfs_read(
-	struct file	*filp,
-	char		*buf,
-	size_t		size,
-	loff_t		*offset)
+linvfs_readv(
+	struct file		*filp,
+	const struct iovec	*iovp,
+	unsigned long		nr_segs,
+	loff_t			*ppos)
 {
-	vnode_t		*vp;
-	int		error;
+	vnode_t			*vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
+	int			error;
 
-	vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
-	ASSERT(vp);
+	VOP_READ(vp, filp, iovp, nr_segs, ppos, NULL, error);
 
-	VOP_READ(vp, filp, buf, size, offset, NULL, error);
-
-	return(error);
+	return error;
 }
 
 
 STATIC ssize_t
-linvfs_write(
-	struct file	*file,
-	const char	*buf,
-	size_t		count,
-	loff_t		*ppos)
+linvfs_writev(
+	struct file		*filp,
+	const struct iovec	*iovp,
+	unsigned long		nr_segs,
+	loff_t			*ppos)
 {
-	struct inode	*inode = file->f_dentry->d_inode;
-	loff_t		pos;
-	vnode_t		*vp;
-	int		err;	/* Use negative errors in this f'n */
-
-	if ((ssize_t) count < 0)
-		return -EINVAL;
-
-	if (!access_ok(VERIFY_READ, buf, count))
-		return -EFAULT;
-
-	pos = *ppos;
-	err = -EINVAL;
-	if (pos < 0)
-		goto out;
-
-	err = file->f_error;
-	if (err) {
-		file->f_error = 0;
-		goto out;
+	struct inode		*inode = filp->f_dentry->d_inode;
+	vnode_t			*vp = LINVFS_GET_VP(inode);
+	int			error = filp->f_error;
+
+	if (unlikely(error)) {
+		filp->f_error = 0;
+		return error;
 	}
 
-	vp = LINVFS_GET_VP(inode);
-	ASSERT(vp);
-
-	/* We allow multiple direct writers in, there is no
+	/*
+	 * We allow multiple direct writers in, there is no
 	 * potential call to vmtruncate in that path.
 	 */
-	if (!(file->f_flags & O_DIRECT))
+	if (filp->f_flags & O_DIRECT) {
+		VOP_WRITE(vp, filp, iovp, nr_segs, ppos, NULL, error);
+	} else {
 		down(&inode->i_sem);
+		VOP_WRITE(vp, filp, iovp, nr_segs, ppos, NULL, error);
+		up(&inode->i_sem);
+	}
 
-	VOP_WRITE(vp, file, buf, count, &pos, NULL, err);
-	*ppos = pos;
+	return error;
+}
 
-	if (!(file->f_flags & O_DIRECT))
-		up(&inode->i_sem);
-out:
 
-	return(err);
+STATIC ssize_t
+linvfs_read(
+	struct file		*filp,
+	char			*buf,
+	size_t			count,
+	loff_t			*ppos)
+{
+	struct iovec		iov = {buf, count};
+
+	return linvfs_readv(filp, &iov, 1, ppos);
+}
+
+
+STATIC ssize_t
+linvfs_write(
+	struct file		*file,
+	const char		*buf,
+	size_t			count,
+	loff_t			*ppos)
+{
+	struct iovec		iov = {(void *)buf, count};
+
+	return linvfs_writev(file, &iov, 1, ppos);
 }
 
 
@@ -312,6 +318,8 @@
 	.llseek		= generic_file_llseek,
 	.read		= linvfs_read,
 	.write		= linvfs_write,
+	.readv		= linvfs_readv,
+	.writev		= linvfs_writev,
 	.ioctl		= linvfs_ioctl,
 	.mmap		= linvfs_file_mmap,
 	.open		= linvfs_open,
diff -Nru a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
--- a/fs/xfs/linux/xfs_lrw.c	Fri Sep 27 14:51:02 2002
+++ b/fs/xfs/linux/xfs_lrw.c	Fri Sep 27 14:51:02 2002
@@ -124,36 +124,64 @@
 
 ssize_t			/* bytes read, or (-)  error */
 xfs_read(
-	bhv_desc_t	*bdp,
-	struct file	*file,
-	char		*buf,
-	size_t		size,
-	loff_t		*offset,
-	cred_t		*credp)
+	bhv_desc_t		*bdp,
+	struct file		*filp,
+	const struct iovec	*iovp,
+	unsigned long		segs,
+	loff_t			*offp,
+	cred_t			*credp)
 {
-	ssize_t		ret;
-	xfs_fsize_t	n;
-	xfs_inode_t	*ip;
-	xfs_mount_t	*mp;
+	size_t			size = 0;
+	ssize_t			ret;
+	xfs_fsize_t		n;
+	xfs_inode_t		*ip;
+	xfs_mount_t		*mp;
+	unsigned long		seg;
+	int			direct = filp->f_flags & O_DIRECT;
 
 	ip = XFS_BHVTOI(bdp);
 	mp = ip->i_mount;
 
 	XFS_STATS_INC(xfsstats.xs_read_calls);
 
-	if (file->f_flags & O_DIRECT) {
-		if (((__psint_t)buf & BBMASK) ||
-		    (*offset & mp->m_blockmask) ||
+	/* START copy & waste from filemap.c */
+	for (seg = 0; seg < segs; seg++) {
+		const struct iovec *iv = &iovp[seg];
+
+		/*
+		 * If any segment has a negative length, or the cumulative
+		 * length ever wraps negative then return -EINVAL.
+		 */
+		size += iv->iov_len;
+		if (unlikely((ssize_t)(size|iv->iov_len) < 0))
+			return XFS_ERROR(-EINVAL);
+		if (direct) {	/* XFS specific check */
+			if ((__psint_t)iv->iov_base & BBMASK) {
+				if (*offp == ip->i_d.di_size)
+					return 0;
+				return XFS_ERROR(-EINVAL);
+			}
+		}
+		if (access_ok(VERIFY_WRITE, iv->iov_base, iv->iov_len))
+			continue;
+		if (seg == 0)
+			return XFS_ERROR(-EFAULT);
+		segs = seg;
+		break;
+	}
+	/* END copy & waste from filemap.c */
+
+	if (direct) {
+		if ((*offp & mp->m_blockmask) ||
 		    (size & mp->m_blockmask)) {
-			if (*offset == ip->i_d.di_size) {
+			if (*offp == ip->i_d.di_size) {
 				return (0);
 			}
 			return -XFS_ERROR(EINVAL);
 		}
 	}
 
-
-	n = XFS_MAX_FILE_OFFSET - *offset;
+	n = XFS_MAX_FILE_OFFSET - *offp;
 	if ((n <= 0) || (size == 0))
 		return 0;
 
@@ -167,26 +195,24 @@
 	xfs_ilock(ip, XFS_IOLOCK_SHARED);
 
 	if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
-	    !(file->f_mode & FINVIS)) {
+	    !(filp->f_mode & FINVIS)) {
 		int error;
 		vrwlock_t locktype = VRWLOCK_READ;
 
-		error = xfs_dm_send_data_event(DM_EVENT_READ, bdp,
-					     *offset, size,
-					     FILP_DELAY_FLAG(file),
-					     &locktype);
+		error = xfs_dm_send_data_event(DM_EVENT_READ, bdp, *offp,
+				size, FILP_DELAY_FLAG(filp), &locktype);
 		if (error) {
 			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 			return -error;
 		}
 	}
 
-	ret = generic_file_read(file, buf, size, offset);
+	ret = generic_file_readv(filp, iovp, segs, offp);
 	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 
 	XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
 
-	if (!(file->f_mode & FINVIS))
+	if (!(filp->f_mode & FINVIS))
 		xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
 
 	return ret;
@@ -418,32 +444,57 @@
 
 ssize_t				/* bytes written, or (-) error */
 xfs_write(
-	bhv_desc_t	*bdp,
-	struct file	*file,
-	const char	*buf,
-	size_t		size,
-	loff_t		*offset,
-	cred_t		*credp)
+	bhv_desc_t		*bdp,
+	struct file		*file,
+	const struct iovec	*iovp,
+	unsigned long		segs,
+	loff_t			*offset,
+	cred_t			*credp)
 {
-	xfs_inode_t	*xip;
-	xfs_mount_t	*mp;
-	ssize_t		ret;
-	int		error = 0;
-	xfs_fsize_t	isize, new_size;
-	xfs_fsize_t	n, limit = XFS_MAX_FILE_OFFSET;
-	xfs_iocore_t	*io;
-	vnode_t		*vp;
-	struct iovec	iov;
-	int		iolock;
-	int		direct = file->f_flags & O_DIRECT;
-	int		eventsent = 0;
-	vrwlock_t	locktype;
+	size_t			size = 0;
+	xfs_inode_t		*xip;
+	xfs_mount_t		*mp;
+	ssize_t			ret;
+	int			error = 0;
+	xfs_fsize_t		isize, new_size;
+	xfs_fsize_t		n, limit = XFS_MAX_FILE_OFFSET;
+	xfs_iocore_t		*io;
+	vnode_t			*vp;
+	unsigned long		seg;
+	int			iolock;
+	int			direct = file->f_flags & O_DIRECT;
+	int			eventsent = 0;
+	vrwlock_t		locktype;
 
 	XFS_STATS_INC(xfsstats.xs_write_calls);
 
 	vp = BHV_TO_VNODE(bdp);
 	xip = XFS_BHVTOI(bdp);
 
+	/* START copy & waste from filemap.c */
+	for (seg = 0; seg < segs; seg++) {
+		const struct iovec *iv = &iovp[seg];
+
+		/*
+		 * If any segment has a negative length, or the cumulative
+		 * length ever wraps negative then return -EINVAL.
+		 */
+		size += iv->iov_len;
+		if (unlikely((ssize_t)(size|iv->iov_len) < 0))
+			return XFS_ERROR(-EINVAL);
+		if (direct) {	/* XFS specific check */
+			if ((__psint_t)iv->iov_base & BBMASK)
+				return XFS_ERROR(-EINVAL);
+		}
+		if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
+			continue;
+		if (seg == 0)
+			return XFS_ERROR(-EFAULT);
+		segs = seg;
+		break;
+	}
+	/* END copy & waste from filemap.c */
+
 	if (size == 0)
 		return 0;
 
@@ -457,9 +508,8 @@
 	}
 
 	if (direct) {
-		if (((__psint_t)buf & BBMASK) ||
-		    (*offset & mp->m_blockmask) ||
-		    (size  & mp->m_blockmask)) {
+		if ((*offset & mp->m_blockmask) ||
+		    (size & mp->m_blockmask)) {
 			return XFS_ERROR(-EINVAL);
 		}
 		iolock = XFS_IOLOCK_SHARED;
@@ -481,6 +531,7 @@
 		xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
 		return -EFBIG;
 	}
+
 	if (n < size)
 		size = n;
 
@@ -572,10 +623,7 @@
 		xfs_inval_cached_pages(vp, &xip->i_iocore, *offset, 1, 1);
 	}
 
-	iov.iov_base = (void *)buf;
-	iov.iov_len = size;
-
-	ret = generic_file_write_nolock(file, &iov, 1, offset);
+	ret = generic_file_write_nolock(file, iovp, segs, offset);
 
 	if ((ret == -ENOSPC) &&
 	    DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) &&
diff -Nru a/fs/xfs/linux/xfs_lrw.h b/fs/xfs/linux/xfs_lrw.h
--- a/fs/xfs/linux/xfs_lrw.h	Fri Sep 27 14:51:03 2002
+++ b/fs/xfs/linux/xfs_lrw.h	Fri Sep 27 14:51:03 2002
@@ -47,19 +47,19 @@
 extern int xfs_zero_eof (vnode_t *, struct xfs_iocore *, xfs_off_t,
 				xfs_fsize_t, xfs_fsize_t, struct pm *);
 extern ssize_t xfs_read (
-	struct bhv_desc	       *bdp,
-	struct file		*file,
-	char			*buf,
-	size_t			size,
-	loff_t			*offset,
-	struct cred	       *credp);
+	struct bhv_desc		*bdp,
+	struct file		*filp,
+	const struct iovec	*iovp,
+	unsigned long		segs,
+	loff_t			*offp,
+	struct cred		*credp);
 
 extern ssize_t xfs_write (
 	struct bhv_desc		*bdp,
-	struct file		*file,
-	const char		*buf,
-	size_t			size,
-	loff_t			*offset,
+	struct file		*filp,
+	const struct iovec	*iovp,
+	unsigned long		segs,
+	loff_t			*offp,
 	struct cred		*credp);
 
 extern int xfs_recover_read_only (xlog_t *);
diff -Nru a/fs/xfs/linux/xfs_vnode.h b/fs/xfs/linux/xfs_vnode.h
--- a/fs/xfs/linux/xfs_vnode.h	Fri Sep 27 14:51:05 2002
+++ b/fs/xfs/linux/xfs_vnode.h	Fri Sep 27 14:51:05 2002
@@ -56,10 +56,8 @@
 
 /*
  * MP locking protocols:
- *	v_flag, v_count				VN_LOCK/VN_UNLOCK
- *	v_vfsp					VN_LOCK/VN_UNLOCK
+ *	v_flag, v_vfsp				VN_LOCK/VN_UNLOCK
  *	v_type					read-only or fs-dependent
- *	v_list, v_hashp, v_hashn		freelist lock
  */
 typedef struct vnode {
 	__u32		v_flag;			/* vnode flags (see below) */
@@ -70,9 +68,9 @@
 
 	spinlock_t	v_lock;			/* don't use VLOCK on Linux */
 	struct inode	v_inode;		/* linux inode */
-#ifdef	CONFIG_XFS_VNODE_TRACING
+#ifdef CONFIG_XFS_VNODE_TRACING
 	struct ktrace	*v_trace;		/* trace header structure    */
-#endif	/* CONFIG_XFS_VNODE_TRACING */
+#endif
 } vnode_t;
 
 /*
@@ -170,7 +168,6 @@
 #define v_fops		v_bh.bh_first->bd_ops  /* ops for first behavior */
 
 
-union rval;
 struct uio;
 struct file;
 struct vattr;
@@ -178,9 +175,11 @@
 struct attrlist_cursor_kern;
 
 typedef int	(*vop_open_t)(bhv_desc_t *, struct cred *);
-typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct file *, char *, size_t,
+typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct file *,
+				const struct iovec *, unsigned long,
 				loff_t *, struct cred *);
-typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct file *, const char *, size_t,
+typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct file *,
+				const struct iovec *, unsigned long,
 				loff_t *, struct cred *);
 typedef int	(*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, unsigned int, unsigned long);
 typedef int	(*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
@@ -275,21 +274,16 @@
  */
 #define _VOP_(op, vp)	(*((vnodeops_t *)(vp)->v_fops)->op)
 
-/*
- * Be careful with VOP_OPEN, since we're holding the chain lock on the
- * original vnode and VOP_OPEN semantic allows the new vnode to be returned
- * in vpp. The practice of passing &vp for vpp just doesn't work.
- */
-#define VOP_READ(vp,file,buf,size,offset,cr,rv)				\
+#define VOP_READ(vp,file,iov,segs,offset,cr,rv)				\
 {									\
 	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
-	rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,buf,size,offset,cr); \
+	rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,cr); \
 	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
-#define VOP_WRITE(vp,file,buf,size,offset,cr,rv)			\
+#define VOP_WRITE(vp,file,iov,segs,offset,cr,rv)			\
 {									\
 	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
-	rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,buf,size,offset,cr);\
+	rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,cr);\
 	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_BMAP(vp,of,sz,rw,cr,b,n,rv)					\
diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
--- a/fs/xfs/pagebuf/page_buf.c	Fri Sep 27 14:51:02 2002
+++ b/fs/xfs/pagebuf/page_buf.c	Fri Sep 27 14:51:02 2002
@@ -55,11 +55,12 @@
 #include <linux/vmalloc.h>
 #include <linux/blkdev.h>
 #include <linux/bio.h>
-#include <asm/softirq.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 
+#include <support/debug.h>
 #include <support/kmem.h>
+
 #include "page_buf_internal.h"
 
 #define SECTOR_SHIFT	9
@@ -548,8 +549,8 @@
 			} else if (!PagePrivate(page)) {
 				unsigned long i, range = (offset + nbytes) >> SECTOR_SHIFT;
 
-				assert(blocksize < PAGE_CACHE_SIZE);
-				assert(!(pb->pb_flags & _PBF_PRIVATE_BH));
+				ASSERT(blocksize < PAGE_CACHE_SIZE);
+				ASSERT(!(pb->pb_flags & _PBF_PRIVATE_BH));
 				/*
 				 * In this case page->private holds a bitmap
 				 * of uptodate sectors (512) within the page
@@ -1317,8 +1318,8 @@
 		} else if (!PagePrivate(page)) {
 			unsigned int	j, range;
 
-			assert(blocksize < PAGE_CACHE_SIZE);
-			assert(!(pb->pb_flags & _PBF_PRIVATE_BH));
+			ASSERT(blocksize < PAGE_CACHE_SIZE);
+			ASSERT(!(pb->pb_flags & _PBF_PRIVATE_BH));
 
 			range = (bvec->bv_offset + bvec->bv_len)>>SECTOR_SHIFT;
 			for (j = bvec->bv_offset>>SECTOR_SHIFT; j < range; j++)
@@ -1607,7 +1608,7 @@
 
 	while (cboff < boff) {
 		pagebuf_segment(pb, &cboff, &page, &cpoff, &csize);
-		assert(((csize + cpoff) <= PAGE_CACHE_SIZE));
+		ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
 
 		switch (mode) {
 		case PBRW_ZERO:
diff -Nru a/fs/xfs/pagebuf/page_buf.h b/fs/xfs/pagebuf/page_buf.h
--- a/fs/xfs/pagebuf/page_buf.h	Fri Sep 27 14:51:02 2002
+++ b/fs/xfs/pagebuf/page_buf.h	Fri Sep 27 14:51:02 2002
@@ -378,13 +378,6 @@
 
 /* Reading and writing pages */
 
-extern int pagebuf_write_full_page(	/* write a page via pagebuf	*/
-		struct page *,		/* page to write		*/
-		int delalloc);		/* delalloc bh present		*/
-
-extern int pagebuf_release_page(	/* Attempt to convert a delalloc page */
-		struct page *);		/* page to release		*/
-
 extern void pagebuf_delwri_queue(page_buf_t *, int);
 extern void pagebuf_delwri_dequeue(page_buf_t *);
 
diff -Nru a/fs/xfs/pagebuf/page_buf_internal.h b/fs/xfs/pagebuf/page_buf_internal.h
--- a/fs/xfs/pagebuf/page_buf_internal.h	Fri Sep 27 14:51:04 2002
+++ b/fs/xfs/pagebuf/page_buf_internal.h	Fri Sep 27 14:51:04 2002
@@ -151,18 +151,6 @@
 
 #define PB_STATS_INC(count)	( count ++ )
 
-#undef assert
-#ifdef PAGEBUF_DEBUG
-# define assert(expr) \
-	if (!(expr)) {						\
-		printk("Assertion failed: %s\n%s::%s line %d\n",\
-		#expr,__FILE__,__FUNCTION__,__LINE__);		\
-		BUG();						\
-	}
-#else
-# define assert(x)	do { } while (0)
-#endif
-
 #ifndef STATIC
 # define STATIC static
 #endif
diff -Nru a/fs/xfs/pagebuf/page_buf_locking.c b/fs/xfs/pagebuf/page_buf_locking.c
--- a/fs/xfs/pagebuf/page_buf_locking.c	Fri Sep 27 14:51:04 2002
+++ b/fs/xfs/pagebuf/page_buf_locking.c	Fri Sep 27 14:51:04 2002
@@ -54,6 +54,8 @@
 #include <linux/init.h>
 #include <linux/major.h>
 
+#include <support/debug.h>
+
 #include "page_buf_internal.h"
 
 #ifndef EVMS_MAJOR
@@ -76,7 +78,7 @@
 {
 	int			locked;
 
-	assert(pb->pb_flags & _PBF_LOCKABLE);
+	ASSERT(pb->pb_flags & _PBF_LOCKABLE);
 
 	locked = down_trylock(&PBP(pb)->pb_sema) == 0;
 	if (locked) {
@@ -97,7 +99,7 @@
 pagebuf_lock_value(
 	page_buf_t		*pb)
 {
-	assert(pb->pb_flags & _PBF_LOCKABLE);
+	ASSERT(pb->pb_flags & _PBF_LOCKABLE);
 	return(atomic_read(&PBP(pb)->pb_sema.count));
 }
 
@@ -113,7 +115,7 @@
 pagebuf_lock(
 	page_buf_t		*pb)
 {
-	assert(pb->pb_flags & _PBF_LOCKABLE);
+	ASSERT(pb->pb_flags & _PBF_LOCKABLE);
 
 	PB_TRACE(pb, PB_TRACE_REC(lock), 0);
 	if (atomic_read(&PBP(pb)->pb_io_remaining))
@@ -219,7 +221,7 @@
 pagebuf_unlock(				/* unlock buffer		*/
 	page_buf_t		*pb)	/* buffer to unlock		*/
 {
-	assert(pb->pb_flags & _PBF_LOCKABLE);
+	ASSERT(pb->pb_flags & _PBF_LOCKABLE);
 	PB_CLEAR_OWNER(pb);
 	up(&PBP(pb)->pb_sema);
 	PB_TRACE(pb, PB_TRACE_REC(unlock), 0);
diff -Nru a/fs/xfs/support/time.h b/fs/xfs/support/time.h
--- a/fs/xfs/support/time.h	Fri Sep 27 14:51:05 2002
+++ b/fs/xfs/support/time.h	Fri Sep 27 14:51:05 2002
@@ -33,6 +33,7 @@
 #define __XFS_SUPPORT_TIME_H__
 
 #include <linux/sched.h>
+#include <linux/time.h>
 
 static inline void delay(long ticks)
 {
@@ -42,8 +43,11 @@
 
 static inline void nanotime(struct timespec *tvp)
 {
-	tvp->tv_sec = xtime.tv_sec;
-	tvp->tv_nsec = xtime.tv_nsec;
+	struct timeval tv;
+
+	do_gettimeofday(&tv);
+	tvp->tv_sec = tv.tv_sec;
+	tvp->tv_nsec = tv.tv_usec * 1000;
 }
 
 #endif /* __XFS_SUPPORT_TIME_H__ */
diff -Nru a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
--- a/fs/xfs/xfs_iget.c	Fri Sep 27 14:51:04 2002
+++ b/fs/xfs/xfs_iget.c	Fri Sep 27 14:51:04 2002
@@ -508,26 +508,6 @@
 
 
 /*
- * A 'special' interface to xfs_iget, where the
- * vnode is already allocated.
- */
-int
-xfs_vn_iget(
-	vfs_t		*vfsp,
-	struct vnode	*vp,
-	xfs_ino_t	ino)
-{
-	xfs_inode_t	*ip;
-	xfs_mount_t	*mp = XFS_BHVTOM(vfsp->vfs_fbhv);
-	int error;
-
-	error = xfs_iget_core(vp, mp, NULL, ino, 0, &ip, 0);
-
-	return error;
-}
-
-
-/*
  * Do the setup for the various locks within the incore inode.
  */
 void
diff -Nru a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
--- a/fs/xfs/xfs_inode.h	Fri Sep 27 14:51:05 2002
+++ b/fs/xfs/xfs_inode.h	Fri Sep 27 14:51:05 2002
@@ -490,7 +490,6 @@
 void		xfs_inode_lock_init(xfs_inode_t *, struct vnode *);
 int		xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
 			 uint, xfs_inode_t **, xfs_daddr_t);
-int		xfs_vn_iget(vfs_t *, struct vnode *, xfs_ino_t);
 void		xfs_iput(xfs_inode_t *, uint);
 void		xfs_iput_new(xfs_inode_t *, uint);
 void		xfs_ilock(xfs_inode_t *, uint);
diff -Nru a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
--- a/fs/xfs/xfs_mount.c	Fri Sep 27 14:51:04 2002
+++ b/fs/xfs/xfs_mount.c	Fri Sep 27 14:51:04 2002
@@ -789,16 +789,6 @@
 	}
 
 	/*
-	 * Disallow mount attempts with (IRIX) project quota enabled
-	 */
-	if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
-	    (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) {
-		cmn_err(CE_WARN, "XFS: IRIX project quota are enabled");
-		error = XFS_ERROR(ENOSYS);
-		goto error1;
-	}
-
-	/*
 	 * Initialize realtime fields in the mount structure
 	 */
 	if ((error = xfs_rtmount_init(mp))) {
diff -Nru a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
--- a/fs/xfs/xfs_rename.c	Fri Sep 27 14:51:04 2002
+++ b/fs/xfs/xfs_rename.c	Fri Sep 27 14:51:04 2002
@@ -91,7 +91,6 @@
 	int			error;
 	int			i, j;
 	uint			lock_mode;
-	uint			lookup_flags;
 	int			diff_dirs = (dp1 != dp2);
 
 	ip2 = NULL;
@@ -123,11 +122,7 @@
 		lock_mode = xfs_ilock_map_shared(dp2);
 	}
 
-	lookup_flags = DLF_IGET;
-	if (lock_mode == XFS_ILOCK_SHARED) {
-		lookup_flags |= DLF_LOCK_SHARED;
-	}
-	error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lookup_flags,
+	error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode,
 				   dentry2, &inum2, &ip2);
 	if (error == ENOENT) {		/* target does not need to exist. */
 		inum2 = 0;
diff -Nru a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
--- a/fs/xfs/xfs_utils.c	Fri Sep 27 14:51:05 2002
+++ b/fs/xfs/xfs_utils.c	Fri Sep 27 14:51:05 2002
@@ -64,52 +64,27 @@
 	return 0;
 }
 
-/*
- * Wrapper around xfs_dir_lookup.
- *
- * If DLF_IGET is set, then this routine will also return the inode.
- * Note that the inode will not be locked. Note, however, that the
- * vnode will have an additional reference in this case.
- */
 int
 xfs_dir_lookup_int(
 	bhv_desc_t		*dir_bdp,
-	int			flags,
+	uint			lock_mode,
 	struct dentry		*dentry,
 	xfs_ino_t		*inum,
 	xfs_inode_t		**ipp)
 {
 	vnode_t		*dir_vp;
 	xfs_inode_t	*dp;
-	char		*name = (char *) dentry->d_name.name;
-	int		name_len = dentry->d_name.len;
 	int		error;
-	int		do_iget;
-	uint		lock_mode;
-	bhv_desc_t	*bdp;
 
 	dir_vp = BHV_TO_VNODE(dir_bdp);
 	vn_trace_entry(dir_vp, "xfs_dir_lookup_int",
 		       (inst_t *)__return_address);
 
-	do_iget = flags & DLF_IGET;
-	error = 0;
-
-	if (flags & DLF_LOCK_SHARED) {
-		lock_mode = XFS_ILOCK_SHARED;
-	} else {
-		lock_mode = XFS_ILOCK_EXCL;
-	}
-
 	dp = XFS_BHVTOI(dir_bdp);
-	bdp = NULL;
-
-	/*
-	 * If all else fails, call the directory code.
-	 */
 
-	error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp, name, name_len, inum);
-	if (!error && do_iget) {
+	error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp,
+			(char *)dentry->d_name.name, dentry->d_name.len, inum);
+	if (!error) {
 		/*
 		 * Unlock the directory. We do this because we can't
 		 * hold the directory lock while doing the vn_get()
@@ -119,22 +94,12 @@
 		 * reservation in the inactive routine.
 		 */
 		xfs_iunlock(dp, lock_mode);
-
-		if (bdp) {
-			VN_RELE(BHV_TO_VNODE(bdp));
-			bdp = NULL;
-		}
-
 		error = xfs_iget(dp->i_mount, NULL, *inum, 0, ipp, 0);
-
 		xfs_ilock(dp, lock_mode);
 
 		if (error) {
 			*ipp = NULL;
-			return error;
-		}
-
-		if ((*ipp)->i_d.di_mode == 0) {
+		} else if ((*ipp)->i_d.di_mode == 0) {
 			/*
 			 * The inode has been freed.  Something is
 			 * wrong so just get out of here.
@@ -144,19 +109,7 @@
 			*ipp = NULL;
 			xfs_ilock(dp, lock_mode);
 			error = XFS_ERROR(ENOENT);
-		} else {
-			bdp = XFS_ITOBHV(*ipp);
-			bdp = NULL;
 		}
-	}
-	if (bdp) {
-		/* The only time we should get here is if the dir_lookup
-		 * failed.
-		 */
-		ASSERT(error);
-		xfs_iunlock(dp, lock_mode);
-		VN_RELE(BHV_TO_VNODE(bdp));
-		xfs_ilock(dp, lock_mode);
 	}
 	return error;
 }
diff -Nru a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
--- a/fs/xfs/xfs_utils.h	Fri Sep 27 14:51:05 2002
+++ b/fs/xfs/xfs_utils.h	Fri Sep 27 14:51:05 2002
@@ -37,9 +37,6 @@
 #define ITRACE(ip)	vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \
 				(inst_t *)__return_address)
 
-#define DLF_IGET	0x01	/* get entry inode if name lookup succeeds */
-#define DLF_LOCK_SHARED 0x02	/* directory locked shared */
-
 struct bhv_desc;
 struct cred;
 struct vnode;
@@ -63,7 +60,7 @@
 extern int
 xfs_dir_lookup_int(
 	struct bhv_desc		*dir_bdp,
-	int			flags,
+	uint			lock_mode,
 	struct dentry		*dentry,
 	xfs_ino_t		*inum,
 	struct xfs_inode	**ipp);
diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
--- a/fs/xfs/xfs_vfsops.c	Fri Sep 27 14:51:03 2002
+++ b/fs/xfs/xfs_vfsops.c	Fri Sep 27 14:51:03 2002
@@ -198,61 +198,17 @@
 }
 
 /*
- * xfs_cmountfs
- *
- * This function is the common mount file system function for XFS.
+ * xfs_start_flags
+ * 
+ * This function fills in xfs_mount_t fields based on mount args.
+ * Note: the superblock has _not_ yet been read in.
  */
 STATIC int
-xfs_cmountfs(
-	vfs_t		*vfsp,
-	dev_t		ddev,
-	dev_t		logdev,
-	dev_t		rtdev,
-	struct xfs_mount_args *ap,
-	struct cred	*cr)
+xfs_start_flags(
+	struct xfs_mount_args	*ap,
+	struct xfs_mount	*mp,
+	int			ronly)
 {
-	xfs_mount_t	*mp;
-	int		error = 0;
-
-
-	/*
-	 * Allocate VFS private data (xfs mount structure).
-	 */
-	mp = xfs_mount_init();
-
-	vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
-
-	/*
-	 * Open data, real time, and log devices now - order is important.
-	 */
-	mp->m_ddev_targp = pagebuf_lock_enable(ddev, 0);
-	if (IS_ERR(mp->m_ddev_targp)) {
-		error = PTR_ERR(mp->m_ddev_targp);
-		goto error2;
-	}
-
-	if (rtdev != 0) {
-		mp->m_rtdev_targp = 
-				pagebuf_lock_enable(rtdev, 1);
-		if (IS_ERR(mp->m_rtdev_targp)) {
-			error = PTR_ERR(mp->m_rtdev_targp);
-			pagebuf_lock_disable(mp->m_ddev_targp, 0);
-			goto error2;
-		}
-	}
-
-	if (logdev != ddev) {
-		mp->m_logdev_targp = 
-				pagebuf_lock_enable(logdev, 1);
-		if (IS_ERR(mp->m_logdev_targp)) {
-			error = PTR_ERR(mp->m_logdev_targp);
-			pagebuf_lock_disable(mp->m_ddev_targp, 1);
-			if (mp->m_rtdev_targp)
-				pagebuf_lock_disable(mp->m_rtdev_targp, 1);
-			goto error2;
-		}
-	}
-
 	/* Values are in BBs */
 	if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
 		/*
@@ -263,187 +219,155 @@
 		 */
 		mp->m_dalign = ap->sunit;
 		mp->m_swidth = ap->swidth;
-	} else {
-		mp->m_dalign = 0;
-		mp->m_swidth = 0;
 	}
 
-	if (logdev != 0) {
-		if (logdev == ddev) {
-			mp->m_logdev_targp = mp->m_ddev_targp;
-		} else {
-			/* Set the log device's block size */
-			set_blocksize(mp->m_logdev_targp->pbr_bdev, 512);
-		}
-
-		if (ap->logbufs != 0 && ap->logbufs != -1 &&
-		    (ap->logbufs < XLOG_NUM_ICLOGS ||
-		     ap->logbufs > XLOG_MAX_ICLOGS)) {
-			cmn_err(CE_WARN, 
-				"XFS: invalid logbufs value: %d [not %d-%d]\n",
-				ap->logbufs, XLOG_NUM_ICLOGS, XLOG_MAX_ICLOGS);
-			error = XFS_ERROR(EINVAL);
-			goto error3;
-		}
-		mp->m_logbufs = ap->logbufs;
-		if (ap->logbufsize != -1 &&
-		    ap->logbufsize != 16 * 1024 &&
-		    ap->logbufsize != 32 * 1024 &&
-		    ap->logbufsize != 64 * 1024 &&
-		    ap->logbufsize != 128 * 1024 &&
-		    ap->logbufsize != 256 * 1024) {
-			cmn_err(CE_WARN,
-		"XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]\n",
-				ap->logbufsize);
-			error = XFS_ERROR(EINVAL);
-			goto error3;
-		}
-		mp->m_logbsize = ap->logbufsize;
-		mp->m_fsname_len = strlen(ap->fsname) + 1;
-		mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
-		strcpy(mp->m_fsname, ap->fsname);
+	if (ap->logbufs != 0 && ap->logbufs != -1 &&
+	    (ap->logbufs < XLOG_NUM_ICLOGS ||
+	     ap->logbufs > XLOG_MAX_ICLOGS)) {
+		cmn_err(CE_WARN, 
+			"XFS: invalid logbufs value: %d [not %d-%d]\n",
+			ap->logbufs, XLOG_NUM_ICLOGS, XLOG_MAX_ICLOGS);
+		return XFS_ERROR(EINVAL);
 	}
-	if (rtdev != 0) {
-		if (rtdev == ddev || rtdev == logdev) {
-			cmn_err(CE_WARN,
-	"XFS: Cannot mount filesystem with identical rtdev and logdev.");
-			error = XFS_ERROR(EINVAL);
-			goto error3;
-		} else {
-			/* Set the realtime device's block size */
-			set_blocksize(mp->m_rtdev_targp->pbr_bdev, 512);
-		}
+	mp->m_logbufs = ap->logbufs;
+	if (ap->logbufsize != -1 &&
+	    ap->logbufsize != 16 * 1024 &&
+	    ap->logbufsize != 32 * 1024 &&
+	    ap->logbufsize != 64 * 1024 &&
+	    ap->logbufsize != 128 * 1024 &&
+	    ap->logbufsize != 256 * 1024) {
+		cmn_err(CE_WARN,
+	"XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]\n",
+			ap->logbufsize);
+		return XFS_ERROR(EINVAL);
 	}
+	mp->m_logbsize = ap->logbufsize;
+	mp->m_fsname_len = strlen(ap->fsname) + 1;
+	mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
+	strcpy(mp->m_fsname, ap->fsname);
 
 	/*
 	 * Pull in the 'wsync' and 'ino64' mount options before we do the real
 	 * work of mounting and recovery.  The arg pointer will
 	 * be NULL when we are being called from the root mount code.
 	 */
+	if (ap->flags & XFSMNT_WSYNC)
+		mp->m_flags |= XFS_MOUNT_WSYNC;
 #if XFS_BIG_FILESYSTEMS
-	mp->m_inoadd = 0;
-#endif
-	if (ap != NULL) {
-		if (ap->flags & XFSMNT_WSYNC)
-			mp->m_flags |= XFS_MOUNT_WSYNC;
-#if XFS_BIG_FILESYSTEMS
-		if (ap->flags & XFSMNT_INO64) {
-			mp->m_flags |= XFS_MOUNT_INO64;
-			mp->m_inoadd = XFS_INO64_OFFSET;
-		}
+	if (ap->flags & XFSMNT_INO64) {
+		mp->m_flags |= XFS_MOUNT_INO64;
+		mp->m_inoadd = XFS_INO64_OFFSET;
+	}
 #endif
-		if (ap->flags & XFSMNT_NOATIME)
-			mp->m_flags |= XFS_MOUNT_NOATIME;
+	if (ap->flags & XFSMNT_NOATIME)
+		mp->m_flags |= XFS_MOUNT_NOATIME;
 
-		if (ap->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA))
-			xfs_qm_mount_quotainit(mp, ap->flags);
+	if (ap->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA))
+		xfs_qm_mount_quotainit(mp, ap->flags);
 
-		if (ap->flags & XFSMNT_RETERR)
-			mp->m_flags |= XFS_MOUNT_RETERR;
+	if (ap->flags & XFSMNT_RETERR)
+		mp->m_flags |= XFS_MOUNT_RETERR;
 
-		if (ap->flags & XFSMNT_NOALIGN)
-			mp->m_flags |= XFS_MOUNT_NOALIGN;
-
-		if (ap->flags & XFSMNT_OSYNCISOSYNC)
-			mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
-
-		/* Default on Linux */
-		if ( 1 || ap->flags & XFSMNT_32BITINODES)
-			mp->m_flags |= XFS_MOUNT_32BITINODES;
-
-		if (ap->flags & XFSMNT_IRIXSGID)
-			mp->m_flags |= XFS_MOUNT_IRIXSGID;
-
-		if (ap->flags & XFSMNT_IOSIZE) {
-			if (ap->iosizelog > XFS_MAX_IO_LOG ||
-			    ap->iosizelog < XFS_MIN_IO_LOG) {
-				cmn_err(CE_WARN,
-			"XFS: invalid log iosize: %d [not %d-%d]",
-					ap->iosizelog, XFS_MIN_IO_LOG,
-					XFS_MAX_IO_LOG);
-				error = XFS_ERROR(EINVAL);
-				goto error3;
-			}
+	if (ap->flags & XFSMNT_NOALIGN)
+		mp->m_flags |= XFS_MOUNT_NOALIGN;
 
-			mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
-			mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
-		}
+	if (ap->flags & XFSMNT_OSYNCISOSYNC)
+		mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
 
-		/*
-		 * no recovery flag requires a read-only mount
-		 */
-		if (ap->flags & XFSMNT_NORECOVERY) {
-			if (!(vfsp->vfs_flag & VFS_RDONLY)) {
-				cmn_err(CE_WARN,
-		"XFS: tried to mount a FS read-write without recovery!");
-				error = XFS_ERROR(EINVAL);
-				goto error3;
-			}
-			mp->m_flags |= XFS_MOUNT_NORECOVERY;
+	/* Default on Linux */
+	if (1 || ap->flags & XFSMNT_32BITINODES)
+		mp->m_flags |= XFS_MOUNT_32BITINODES;
+
+	if (ap->flags & XFSMNT_IRIXSGID)
+		mp->m_flags |= XFS_MOUNT_IRIXSGID;
+
+	if (ap->flags & XFSMNT_IOSIZE) {
+		if (ap->iosizelog > XFS_MAX_IO_LOG ||
+		    ap->iosizelog < XFS_MIN_IO_LOG) {
+			cmn_err(CE_WARN,
+		"XFS: invalid log iosize: %d [not %d-%d]",
+				ap->iosizelog, XFS_MIN_IO_LOG,
+				XFS_MAX_IO_LOG);
+			return XFS_ERROR(EINVAL);
 		}
 
-		if (ap->flags & XFSMNT_NOUUID)
-			mp->m_flags |= XFS_MOUNT_NOUUID;
-		if (ap->flags & XFSMNT_NOLOGFLUSH)
-			mp->m_flags |= XFS_MOUNT_NOLOGFLUSH;
+		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
+		mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
 	}
 
 	/*
-	 * read in superblock to check read-only flags and shared
-	 * mount status
+	 * no recovery flag requires a read-only mount
 	 */
-	if ((error = xfs_readsb(mp)))
-		goto error3;
+	if (ap->flags & XFSMNT_NORECOVERY) {
+		if (!ronly) {
+			cmn_err(CE_WARN,
+	"XFS: tried to mount a FS read-write without recovery!");
+			return XFS_ERROR(EINVAL);
+		}
+		mp->m_flags |= XFS_MOUNT_NORECOVERY;
+	}
 
+	if (ap->flags & XFSMNT_NOUUID)
+		mp->m_flags |= XFS_MOUNT_NOUUID;
+	if (ap->flags & XFSMNT_NOLOGFLUSH)
+		mp->m_flags |= XFS_MOUNT_NOLOGFLUSH;
+
+	return 0;
+}
+
+/*
+ * This function fills in xfs_mount_t fields based on mount args.
+ * Note: the superblock _has_ now been read in.
+ */
+STATIC int
+xfs_finish_flags(
+	struct xfs_mount_args	*ap,
+	struct xfs_mount	*mp,
+	int			ronly)
+{
 	/* Fail a mount where the logbuf is smaller then the log stripe */
 	if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
 		if (((ap->logbufsize == -1) &&
 		     (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) ||
 		    (ap->logbufsize < mp->m_sb.sb_logsunit)) {
-			cmn_err(CE_WARN, "XFS: "
-				"logbuf size must be greater than or equal to log stripe size");
-			xfs_freesb(mp);
-			error = XFS_ERROR(EINVAL);
-			goto error3;
+			cmn_err(CE_WARN,
+	"XFS: logbuf size must be greater than or equal to log stripe size");
+			return XFS_ERROR(EINVAL);
 		}
 	} else {
 		/* Fail a mount if the logbuf is larger than 32K */
 		if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) {
-			cmn_err(CE_WARN, "XFS: "
-		"XFS: logbuf size for version 1 logs must be 16K or 32K");
-			xfs_freesb(mp);
-			error = XFS_ERROR(EINVAL);
-			goto error3;
+			cmn_err(CE_WARN,
+	"XFS: logbuf size for version 1 logs must be 16K or 32K");
+			return XFS_ERROR(EINVAL);
 		}
 	}
 
-	pagebuf_target_blocksize(mp->m_ddev_targp, mp->m_sb.sb_blocksize);
-	if (logdev != 0 && logdev != ddev)
-		pagebuf_target_blocksize(mp->m_logdev_targp, mp->m_sb.sb_blocksize);
-	if (rtdev != 0)
-		pagebuf_target_blocksize(mp->m_rtdev_targp, mp->m_sb.sb_blocksize);
-
 	/*
 	 * prohibit r/w mounts of read-only filesystems
 	 */
-	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) &&
-	    !(vfsp->vfs_flag & VFS_RDONLY)) {
-		cmn_err(CE_WARN, "XFS: "
-			"cannot mount a read-only filesystem as read-write");
-		error = XFS_ERROR(EROFS);
-		xfs_freesb(mp);
-		goto error3;
+	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) {
+		cmn_err(CE_WARN,
+	"XFS: cannot mount a read-only filesystem as read-write");
+		return XFS_ERROR(EROFS);
+	}
+
+	/*
+	 * disallow mount attempts with (IRIX) project quota enabled
+	 */
+	if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
+	    (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) {
+		cmn_err(CE_WARN,
+	"XFS: cannot mount a filesystem with IRIX project quota enabled");
+		return XFS_ERROR(ENOSYS);
 	}
 
 	/*
 	 * check for shared mount.
 	 */
-	if (ap && ap->flags & XFSMNT_SHARED) {
-		if (!XFS_SB_VERSION_HASSHARED(&mp->m_sb)) {
-			error = XFS_ERROR(EINVAL);
-			xfs_freesb(mp);
-			goto error3;
-		}
+	if (ap->flags & XFSMNT_SHARED) {
+		if (!XFS_SB_VERSION_HASSHARED(&mp->m_sb))
+			return XFS_ERROR(EINVAL);
 
 		/*
 		 * For IRIX 6.5, shared mounts must have the shared
@@ -451,32 +375,117 @@
 		 * field set, must be version 0 and can only be mounted
 		 * read-only.
 		 */
-		if (!(vfsp->vfs_flag & VFS_RDONLY) ||
-		    !(mp->m_sb.sb_flags & XFS_SBF_READONLY) ||
-		    mp->m_sb.sb_shared_vn != 0) {
-			error = XFS_ERROR(EINVAL);
-			xfs_freesb(mp);
-			goto error3;
-		}
+		if (!ronly || !(mp->m_sb.sb_flags & XFS_SBF_READONLY) ||
+		     (mp->m_sb.sb_shared_vn != 0))
+			return XFS_ERROR(EINVAL);
 
 		mp->m_flags |= XFS_MOUNT_SHARED;
 
 		/*
 		 * Shared XFS V0 can't deal with DMI.  Return EINVAL.
 		 */
-		if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI)) {
-			error = XFS_ERROR(EINVAL);
-			xfs_freesb(mp);
-			goto error3;
-		}
+		if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI))
+			return XFS_ERROR(EINVAL);
 	}
 
-	if ((error = xfs_mountfs(vfsp, mp, ddev, 0)) == 0)
-		return 0;
+	return 0;
+}
+
+/*
+ * xfs_cmountfs
+ *
+ * This function is the common mount file system function for XFS.
+ */
+STATIC int
+xfs_cmountfs(
+	vfs_t			*vfsp,
+	dev_t			ddev,
+	dev_t			logdev,
+	dev_t			rtdev,
+	struct xfs_mount_args	*ap,
+	struct cred		*cr)
+{
+	xfs_mount_t		*mp;
+	int			ronly = (vfsp->vfs_flag & VFS_RDONLY);
+	int			error = 0;
+
+	/*
+	 * Allocate VFS private data (xfs mount structure).
+	 */
+	mp = xfs_mount_init();
+
+	vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
 
 	/*
-	 * Be careful not to clobber the value of 'error' here.
+	 * Open data, real time, and log devices now - order is important.
 	 */
+	mp->m_ddev_targp = pagebuf_lock_enable(ddev, 0);
+	if (IS_ERR(mp->m_ddev_targp)) {
+		error = PTR_ERR(mp->m_ddev_targp);
+		goto error2;
+	}
+
+	if (rtdev != 0) {
+		mp->m_rtdev_targp = pagebuf_lock_enable(rtdev, 1);
+		if (IS_ERR(mp->m_rtdev_targp)) {
+			error = PTR_ERR(mp->m_rtdev_targp);
+			pagebuf_lock_disable(mp->m_ddev_targp, 0);
+			goto error2;
+		}
+
+		if (rtdev == ddev || rtdev == logdev) {
+			cmn_err(CE_WARN,
+	"XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
+			error = EINVAL;
+			pagebuf_lock_disable(mp->m_ddev_targp, 0);
+			goto error2;
+		}
+		
+		/* Set the realtime device's block size */
+		set_blocksize(mp->m_rtdev_targp->pbr_bdev, 512);
+	}
+
+	if (logdev != ddev) {
+		mp->m_logdev_targp = pagebuf_lock_enable(logdev, 1);
+		if (IS_ERR(mp->m_logdev_targp)) {
+			error = PTR_ERR(mp->m_logdev_targp);
+			pagebuf_lock_disable(mp->m_ddev_targp, 1);
+			if (mp->m_rtdev_targp)
+				pagebuf_lock_disable(mp->m_rtdev_targp, 1);
+			goto error2;
+		}
+
+		/* Set the log device's block size */
+		set_blocksize(mp->m_logdev_targp->pbr_bdev, 512);
+	} else {
+		mp->m_logdev_targp = mp->m_ddev_targp;
+	}
+	
+	if ((error = xfs_start_flags(ap, mp, ronly)))
+		goto error3;
+
+	if ((error = xfs_readsb(mp)))
+		goto error3;
+
+	if ((error = xfs_finish_flags(ap, mp, ronly))) {
+		xfs_freesb(mp);
+		goto error3;
+	}
+
+	pagebuf_target_blocksize(mp->m_ddev_targp, mp->m_sb.sb_blocksize);
+	if (logdev != 0 && logdev != ddev)
+		pagebuf_target_blocksize(mp->m_logdev_targp,
+					mp->m_sb.sb_blocksize);
+	if (rtdev != 0)
+		pagebuf_target_blocksize(mp->m_rtdev_targp,
+					mp->m_sb.sb_blocksize);
+
+	mp->m_cxfstype = XFS_CXFS_NOT;
+	error = xfs_mountfs(vfsp, mp, ddev, 0);
+	if (error)
+		goto error3;
+	return 0;
+
  error3:
 	/* It's impossible to get here before buftargs are filled */
 	xfs_binval(mp->m_ddev_targp);
diff -Nru a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
--- a/fs/xfs/xfs_vnodeops.c	Fri Sep 27 14:51:05 2002
+++ b/fs/xfs/xfs_vnodeops.c	Fri Sep 27 14:51:05 2002
@@ -1144,138 +1144,70 @@
 	 * (Note that xfs_inode_item_format() called at commit clears
 	 * the update_* fields.)
 	 */
-	if (!(flag & FSYNC_DATA)) {
-		xfs_ilock(ip, XFS_ILOCK_SHARED);
-
-		if (ip->i_update_core == 0)  {
-			/*
-			 * Timestamps/size haven't changed since last inode
-			 * flush or inode transaction commit.  That means
-			 * either nothing got written or a transaction
-			 * committed which caught the updates.	If the
-			 * latter happened and the transaction hasn't
-			 * hit the disk yet, the inode will be still
-			 * be pinned.  If it is, force the log.
-			 */
-			if (xfs_ipincount(ip) == 0)  {
-				xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-						XFS_ILOCK_SHARED);
-			} else	{
-				xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-						XFS_ILOCK_SHARED);
-				xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
-					      XFS_LOG_FORCE |
-					      ((flag & FSYNC_WAIT)
-					       ? XFS_LOG_SYNC : 0));
-			}
-			error = 0;
-		} else	{
-			/*
-			 * Kick off a transaction to log the inode
-			 * core to get the updates.  Make it
-			 * sync if FSYNC_WAIT is passed in (which
-			 * is done by everybody but specfs).  The
-			 * sync transaction will also force the log.
-			 */
-			xfs_iunlock(ip, XFS_ILOCK_SHARED);
-			tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
-			if ((error = xfs_trans_reserve(tp, 0,
-					XFS_FSYNC_TS_LOG_RES(ip->i_mount),
-					0, 0, 0)))  {
-				xfs_trans_cancel(tp, 0);
-				xfs_iunlock(ip, XFS_IOLOCK_EXCL);
-				return error;
-			}
-			xfs_ilock(ip, XFS_ILOCK_EXCL);
-
-			/*
-			 * Note - it's possible that we might have pushed
-			 * ourselves out of the way during trans_reserve
-			 * which would flush the inode.	 But there's no
-			 * guarantee that the inode buffer has actually
-			 * gone out yet (it's delwri).	Plus the buffer
-			 * could be pinned anyway if it's part of an
-			 * inode in another recent transaction.	 So we
-			 * play it safe and fire off the transaction anyway.
-			 */
-			xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
-			xfs_trans_ihold(tp, ip);
-			xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-			if (flag & FSYNC_WAIT)
-				xfs_trans_set_sync(tp);
-			error = xfs_trans_commit(tp, 0, NULL);
+	xfs_ilock(ip, XFS_ILOCK_SHARED);
 
-			xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
+	/* If we are flushing data then we care about update_size
+	 * being set, otherwise we care about update_core
+	 */
+	if ((flag & FSYNC_DATA) ?
+			(ip->i_update_size == 0) :
+			(ip->i_update_core == 0)) {
+		/*
+		 * Timestamps/size haven't changed since last inode
+		 * flush or inode transaction commit.  That means
+		 * either nothing got written or a transaction
+		 * committed which caught the updates.	If the
+		 * latter happened and the transaction hasn't
+		 * hit the disk yet, the inode will be still
+		 * be pinned.  If it is, force the log.
+		 */
+
+		xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED);
+
+		if (xfs_ipincount(ip)) {
+			xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
+				      XFS_LOG_FORCE |
+				      ((flag & FSYNC_WAIT)
+				       ? XFS_LOG_SYNC : 0));
+		}
+		error = 0;
+	} else	{
+		/*
+		 * Kick off a transaction to log the inode
+		 * core to get the updates.  Make it
+		 * sync if FSYNC_WAIT is passed in (which
+		 * is done by everybody but specfs).  The
+		 * sync transaction will also force the log.
+		 */
+		xfs_iunlock(ip, XFS_ILOCK_SHARED);
+		tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
+		if ((error = xfs_trans_reserve(tp, 0,
+				XFS_FSYNC_TS_LOG_RES(ip->i_mount),
+				0, 0, 0)))  {
+			xfs_trans_cancel(tp, 0);
+			xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+			return error;
 		}
-	} else {
-		/*
-		 * We don't care about the timestamps here.  We
-		 * only care about the size field growing on us
-		 * and forcing any space allocation transactions.
-		 * We have to flush changes to the size fields
-		 * otherwise we could write out data that
-		 * becomes inaccessible after a crash.
-		 */
-		xfs_ilock(ip, XFS_ILOCK_SHARED);
-
-		if (ip->i_update_size == 0)  {
-			/*
-			 * Force the log if the inode is pinned.
-			 * That ensures that all transactions committed
-			 * against the inode hit the disk.  This may do
-			 * too much work but it's safe.
-			 */
-			if (xfs_ipincount(ip) == 0)  {
-				xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-						XFS_ILOCK_SHARED);
-			} else	{
-				xfs_iunlock(ip, XFS_IOLOCK_EXCL |
-						XFS_ILOCK_SHARED);
-				xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
-					      XFS_LOG_FORCE |
-					      ((flag & FSYNC_WAIT)
-					       ? XFS_LOG_SYNC : 0));
-			}
-			error = 0;
-		} else	{
-			/*
-			 * Kick off a sync transaction to log the inode
-			 * core.  The transaction has to be sync since
-			 * we need these updates to guarantee that the
-			 * data written will be seen.  The sync
-			 * transaction will also force the log.
-			 */
-			xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
-			tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
-			if ((error = xfs_trans_reserve(tp, 0,
-					XFS_FSYNC_TS_LOG_RES(ip->i_mount),
-					0, 0, 0)))  {
-				xfs_trans_cancel(tp, 0);
-				xfs_iunlock(ip, XFS_IOLOCK_EXCL);
-				return error;
-			}
-			xfs_ilock(ip, XFS_ILOCK_EXCL);
+		xfs_ilock(ip, XFS_ILOCK_EXCL);
 
-			/*
-			 * Note - it's possible that we might have pushed
-			 * ourselves out of the way during trans_reserve
-			 * which would flush the inode.	 But there's no
-			 * guarantee that the inode buffer has actually
-			 * gone out yet (it's delwri).	Plus the buffer
-			 * could be pinned anyway if it's part of an
-			 * inode in another recent transaction.	 So we
-			 * play it safe and fire off the transaction anyway.
-			 */
-			xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
-			xfs_trans_ihold(tp, ip);
-			xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-			if (flag & FSYNC_WAIT)
-				xfs_trans_set_sync(tp);
-			error = xfs_trans_commit(tp, 0, NULL);
+		/*
+		 * Note - it's possible that we might have pushed
+		 * ourselves out of the way during trans_reserve
+		 * which would flush the inode.	 But there's no
+		 * guarantee that the inode buffer has actually
+		 * gone out yet (it's delwri).	Plus the buffer
+		 * could be pinned anyway if it's part of an
+		 * inode in another recent transaction.	 So we
+		 * play it safe and fire off the transaction anyway.
+		 */
+		xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
+		xfs_trans_ihold(tp, ip);
+		xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+		if (flag & FSYNC_WAIT)
+			xfs_trans_set_sync(tp);
+		error = xfs_trans_commit(tp, 0, NULL);
 
-			xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
-		}
+		xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
 	}
 	return error;
 }
@@ -1958,7 +1890,6 @@
 	xfs_ino_t		e_inum;
 	int			error;
 	uint			lock_mode;
-	uint			lookup_flags;
 	vnode_t			*dir_vp;
 
 	dir_vp = BHV_TO_VNODE(dir_bdp);
@@ -1971,12 +1902,7 @@
 		return XFS_ERROR(EIO);
 
 	lock_mode = xfs_ilock_map_shared(dp);
-
-	lookup_flags = DLF_IGET;
-	if (lock_mode == XFS_ILOCK_SHARED) {
-		lookup_flags |= DLF_LOCK_SHARED;
-	}
-	error = xfs_dir_lookup_int(dir_bdp, lookup_flags, dentry, &e_inum, &ip);
+	error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip);
 	if (error) {
 		xfs_iunlock_map_shared(dp, lock_mode);
 		return error;
diff -Nru a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
--- a/include/asm-alpha/hardirq.h	Fri Sep 27 14:51:03 2002
+++ b/include/asm-alpha/hardirq.h	Fri Sep 27 14:51:03 2002
@@ -74,9 +74,12 @@
 
 #define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
 
+
 #if CONFIG_PREEMPT
+#define in_atomic()	(preempt_count() != kernel_locked())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
+#define in_atomic()	(preempt_count() != 0)
 #define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 # endif
 #define irq_exit()						\
diff -Nru a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
--- a/include/asm-alpha/ide.h	Fri Sep 27 14:51:05 2002
+++ b/include/asm-alpha/ide.h	Fri Sep 27 14:51:05 2002
@@ -80,17 +80,6 @@
 #endif
 }
 
-#define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
-#define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
-#define ide_check_region(from,extent)		check_region((from), (extent))
-#define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
-#define ide_release_region(from,extent)		release_region((from), (extent))
-
-#define ide_ack_intr(hwif)		(1)
-#define ide_fix_driveid(id)		do {} while (0)
-#define ide_release_lock(lock)		do {} while (0)
-#define ide_get_lock(lock, hdlr, data)	do {} while (0)
-
 #endif /* __KERNEL__ */
 
 #endif /* __ASMalpha_IDE_H */
diff -Nru a/include/asm-alpha/rwsem.h b/include/asm-alpha/rwsem.h
--- a/include/asm-alpha/rwsem.h	Fri Sep 27 14:51:05 2002
+++ b/include/asm-alpha/rwsem.h	Fri Sep 27 14:51:05 2002
@@ -93,14 +93,16 @@
  */
 static inline int __down_read_trylock(struct rw_semaphore *sem)
 {
-	long res, tmp;
+	long old, new, res;
 
 	res = sem->count;
 	do {
-		tmp = res + RWSEM_ACTIVE_READ_BIAS;
-		if (tmp <= 0)
+		new = res + RWSEM_ACTIVE_READ_BIAS;
+		if (new <= 0)
 			break;
-	} while (cmpxchg(&sem->count, res, tmp) != res);
+		old = res;
+		res = cmpxchg(&sem->count, old, new);
+	} while (res != old);
 	return res >= 0 ? 1 : 0;
 }
 
diff -Nru a/include/asm-alpha/spinlock.h b/include/asm-alpha/spinlock.h
--- a/include/asm-alpha/spinlock.h	Fri Sep 27 14:51:04 2002
+++ b/include/asm-alpha/spinlock.h	Fri Sep 27 14:51:04 2002
@@ -100,6 +100,7 @@
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
 
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+#define rwlock_is_locked(x)	(*(volatile int *)(x) != 0)
 
 #if CONFIG_DEBUG_RWLOCK
 extern void _raw_write_lock(rwlock_t * lock);
diff -Nru a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
--- a/include/asm-alpha/unistd.h	Fri Sep 27 14:51:04 2002
+++ b/include/asm-alpha/unistd.h	Fri Sep 27 14:51:04 2002
@@ -331,6 +331,18 @@
 #define __NR_removexattr		391
 #define __NR_lremovexattr		392
 #define __NR_fremovexattr		393
+#define __NR_futex		394
+#define __NR_sched_setaffinity	395     
+#define __NR_sched_getaffinity	396
+#define __NR_tuxcall		397
+#define __NR_io_setup		398
+#define __NR_io_destroy		399
+#define __NR_io_getevents	400
+#define __NR_io_submit		401
+#define __NR_io_cancel		402
+#define __NR_alloc_hugepages	403
+#define __NR_free_hugepages	404
+#define __NR_exit_group		405
 
 
 #if defined(__GNUC__)
diff -Nru a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h
--- a/include/asm-i386/hardirq.h	Fri Sep 27 14:51:05 2002
+++ b/include/asm-i386/hardirq.h	Fri Sep 27 14:51:05 2002
@@ -97,6 +97,4 @@
   extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
-extern void show_stack(unsigned long * esp);
-
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-i386/io.h b/include/asm-i386/io.h
--- a/include/asm-i386/io.h	Fri Sep 27 14:51:04 2002
+++ b/include/asm-i386/io.h	Fri Sep 27 14:51:04 2002
@@ -40,7 +40,6 @@
 
 #define XQUAD_PORTIO_BASE 0xfe400000
 #define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
-#define XQUAD_PORTIO_LEN  0x80000  /* Only remapping first 2 quads */
 
 #ifdef __KERNEL__
 
diff -Nru a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
--- a/include/asm-i386/ptrace.h	Fri Sep 27 14:51:03 2002
+++ b/include/asm-i386/ptrace.h	Fri Sep 27 14:51:03 2002
@@ -57,7 +57,6 @@
 #ifdef __KERNEL__
 #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
 #define instruction_pointer(regs) ((regs)->eip)
-extern void show_regs(struct pt_regs *);
 #endif
 
 #endif
diff -Nru a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
--- a/include/asm-i386/semaphore.h	Fri Sep 27 14:51:03 2002
+++ b/include/asm-i386/semaphore.h	Fri Sep 27 14:51:03 2002
@@ -116,7 +116,7 @@
 #if WAITQUEUE_DEBUG
 	CHECK_MAGIC(sem->__magic);
 #endif
-
+	might_sleep();
 	__asm__ __volatile__(
 		"# atomic down operation\n\t"
 		LOCK "decl %0\n\t"     /* --sem->count */
@@ -142,7 +142,7 @@
 #if WAITQUEUE_DEBUG
 	CHECK_MAGIC(sem->__magic);
 #endif
-
+	might_sleep();
 	__asm__ __volatile__(
 		"# atomic interruptible down operation\n\t"
 		LOCK "decl %1\n\t"     /* --sem->count */
diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/acpi.h	Fri Sep 27 14:51:02 2002
@@ -228,6 +228,26 @@
 	ACPI_INTERRUPT_COUNT
 };
 
+#define	ACPI_SPACE_MEM		0
+
+struct acpi_gen_regaddr {
+	u8  space_id;
+	u8  bit_width;
+	u8  bit_offset;
+	u8  resv;
+	u32 addrl;
+	u32 addrh;
+} __attribute__ ((packed));
+
+struct acpi_table_hpet {
+	struct acpi_table_header header;
+	u32 id;
+	struct acpi_gen_regaddr addr;
+	u8 number;
+	u16 min_tick;
+	u8 page_protect;
+} __attribute__ ((packed));
+
 /*
  * System Resource Affinity Table (SRAT)
  *   see http://www.microsoft.com/hwdev/design/srat.htm
@@ -333,6 +353,7 @@
 	ACPI_SRAT,
 	ACPI_SSDT,
 	ACPI_SPMI,
+	ACPI_HPET,
 	ACPI_TABLE_COUNT
 };
 
diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h
--- a/include/linux/agp_backend.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/agp_backend.h	Fri Sep 27 14:51:05 2002
@@ -66,6 +66,7 @@
 	AMD_IRONGATE,
 	AMD_761,
 	AMD_762,
+	AMD_8151,
 	ALI_M1541,
 	ALI_M1621,
 	ALI_M1631,
@@ -161,7 +162,7 @@
  * 
  */
 
-extern void agp_copy_info(agp_kern_info *);
+extern int agp_copy_info(agp_kern_info *);
 
 /*
  * agp_copy_info :
@@ -257,7 +258,7 @@
 	void       (*enable)(u32);
 	int        (*acquire)(void);
 	void       (*release)(void);
-	void       (*copy_info)(agp_kern_info *);
+	int        (*copy_info)(agp_kern_info *);
 } drm_agp_t;
 
 extern const drm_agp_t *drm_agp_p;
diff -Nru a/include/linux/amifd.h b/include/linux/amifd.h
--- a/include/linux/amifd.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/amifd.h	Fri Sep 27 14:51:05 2002
@@ -55,6 +55,7 @@
     int busy;			/* true when drive is active */
     int dirty;			/* true when trackbuf is not on disk */
     int status;			/* current error code for unit */
+    struct gendisk disk;
 };
 #endif
 
diff -Nru a/include/linux/backing-dev.h b/include/linux/backing-dev.h
--- a/include/linux/backing-dev.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/backing-dev.h	Fri Sep 27 14:51:03 2002
@@ -8,11 +8,15 @@
 #ifndef _LINUX_BACKING_DEV_H
 #define _LINUX_BACKING_DEV_H
 
+#include <asm/atomic.h>
+
 /*
  * Bits in backing_dev_info.state
  */
 enum bdi_state {
 	BDI_pdflush,		/* A pdflush thread is working this device */
+	BDI_write_congested,	/* The write queue is getting full */
+	BDI_read_congested,	/* The read queue is getting full */
 	BDI_unused,		/* Available bits start here */
 };
 
@@ -27,5 +31,15 @@
 int writeback_acquire(struct backing_dev_info *bdi);
 int writeback_in_progress(struct backing_dev_info *bdi);
 void writeback_release(struct backing_dev_info *bdi);
+
+static inline int bdi_read_congested(struct backing_dev_info *bdi)
+{
+	return test_bit(BDI_read_congested, &bdi->state);
+}
+
+static inline int bdi_write_congested(struct backing_dev_info *bdi)
+{
+	return test_bit(BDI_write_congested, &bdi->state);
+}
 
 #endif		/* _LINUX_BACKING_DEV_H */
diff -Nru a/include/linux/bio.h b/include/linux/bio.h
--- a/include/linux/bio.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/bio.h	Fri Sep 27 14:51:05 2002
@@ -206,6 +206,7 @@
 extern inline void bio_init(struct bio *);
 
 extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
+extern int bio_get_nr_vecs(struct block_device *);
 
 #ifdef CONFIG_HIGHMEM
 /*
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/blkdev.h	Fri Sep 27 14:51:03 2002
@@ -345,8 +345,7 @@
 extern int blk_queue_init_tags(request_queue_t *, int);
 extern void blk_queue_free_tags(request_queue_t *);
 extern void blk_queue_invalidate_tags(request_queue_t *);
-
-extern int * blk_size[MAX_BLKDEV];	/* in units of 1024 bytes */
+extern void blk_congestion_wait(int rw, long timeout);
 
 #define MAX_PHYS_SEGMENTS 128
 #define MAX_HW_SEGMENTS 128
@@ -357,11 +356,6 @@
 #define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist)
 
 extern void drive_stat_acct(struct request *, int, int);
-
-static inline void blk_clear(int major)
-{
-	blk_size[major] = NULL;
-}
 
 static inline int queue_hardsect_size(request_queue_t *q)
 {
diff -Nru a/include/linux/brlock.h b/include/linux/brlock.h
--- a/include/linux/brlock.h	Fri Sep 27 14:51:04 2002
+++ b/include/linux/brlock.h	Fri Sep 27 14:51:04 2002
@@ -85,7 +85,8 @@
 	if (idx >= __BR_END)
 		__br_lock_usage_bug();
 
-	read_lock(&__brlock_array[smp_processor_id()][idx]);
+	preempt_disable();
+	_raw_read_lock(&__brlock_array[smp_processor_id()][idx]);
 }
 
 static inline void br_read_unlock (enum brlock_indices idx)
@@ -109,6 +110,7 @@
 	if (idx >= __BR_END)
 		__br_lock_usage_bug();
 
+	preempt_disable();
 	ctr = &__brlock_array[smp_processor_id()][idx];
 	lock = &__br_write_locks[idx].lock;
 again:
@@ -147,6 +149,7 @@
 
 	wmb();
 	(*ctr)--;
+	preempt_enable();
 }
 #endif /* __BRLOCK_USE_ATOMICS */
 
diff -Nru a/include/linux/buffer_head.h b/include/linux/buffer_head.h
--- a/include/linux/buffer_head.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/buffer_head.h	Fri Sep 27 14:51:02 2002
@@ -163,7 +163,6 @@
 void __brelse(struct buffer_head *);
 void __bforget(struct buffer_head *);
 struct buffer_head *__bread(struct block_device *, sector_t block, int size);
-void wakeup_bdflush(void);
 struct buffer_head *alloc_buffer_head(void);
 void free_buffer_head(struct buffer_head * bh);
 void FASTCALL(unlock_buffer(struct buffer_head *bh));
diff -Nru a/include/linux/cpu.h b/include/linux/cpu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/cpu.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,28 @@
+/*
+ * cpu.h - generic cpu defition
+ *
+ * This is mainly for topological representation. We define the 
+ * basic 'struct cpu' here, which can be embedded in per-arch 
+ * definitions of processors.
+ *
+ * Basic handling of the devices is done in drivers/base/cpu.c
+ * and system devices are handled in drivers/base/sys.c. 
+ *
+ * CPUs are exported via driverfs in the class/cpu/devices/
+ * directory. 
+ *
+ * Per-cpu interfaces can be implemented using a struct device_interface. 
+ * See the following for how to do this: 
+ * - drivers/base/intf.c 
+ * - Documentation/driver-model/interface.txt
+ *
+ */
+
+#include <linux/device.h>
+
+extern struct device_class cpu_devclass;
+
+struct cpu {
+	struct sys_device sysdev;
+};
+
diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h
--- a/include/linux/dcache.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/dcache.h	Fri Sep 27 14:51:05 2002
@@ -186,7 +186,7 @@
 extern void prune_dcache(int);
 
 /* icache memory management (defined in linux/fs/inode.c) */
-extern int shrink_icache_memory(int, int);
+extern int shrink_icache_memory(int, unsigned int);
 extern void prune_icache(int);
 
 /* quota cache memory management (defined in linux/fs/dquot.c) */
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/device.h	Fri Sep 27 14:51:05 2002
@@ -67,6 +67,8 @@
 
 	int		(*match)(struct device * dev, struct device_driver * drv);
 	struct device * (*add)	(struct device * parent, char * bus_id);
+	int		(*hotplug) (struct device *dev, char **envp, 
+				    int num_envp, char *buffer, int buffer_size);
 };
 
 
@@ -378,11 +380,41 @@
 extern void put_device(struct device * dev);
 
 /* drivers/base/sys.c */
-extern int register_sys_device(struct device * dev);
-extern void unregister_sys_device(struct device * dev);
+
+struct sys_root {
+	u32		id;
+	struct device 	dev;
+	struct device	sysdev;
+};
+
+extern int sys_register_root(struct sys_root *);
+extern void sys_unregister_root(struct sys_root *);
+
+
+struct sys_device {
+	char		* name;
+	u32		id;
+	struct sys_root	* root;
+	struct device	dev;
+};
+
+extern int sys_device_register(struct sys_device *);
+extern void sys_device_unregister(struct sys_device *);
+
+extern struct bus_type system_bus_type;
 
 /* drivers/base/platform.c */
-extern struct bus_type platform_bus;
+
+struct platform_device {
+	char		* name;
+	u32		id;
+	struct device	dev;
+};
+
+extern int platform_device_register(struct platform_device *);
+extern void platform_device_unregister(struct platform_device *);
+
+extern struct bus_type platform_bus_type;
 
 /* drivers/base/power.c */
 extern int device_suspend(u32 state, u32 level);
diff -Nru a/include/linux/elevator.h b/include/linux/elevator.h
--- a/include/linux/elevator.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/elevator.h	Fri Sep 27 14:51:02 2002
@@ -1,11 +1,13 @@
 #ifndef _LINUX_ELEVATOR_H
 #define _LINUX_ELEVATOR_H
 
-typedef int (elevator_merge_fn) (request_queue_t *, struct request **,
+typedef int (elevator_merge_fn) (request_queue_t *, struct list_head **,
 				 struct bio *);
 
 typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *);
 
+typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
+
 typedef struct request *(elevator_next_req_fn) (request_queue_t *);
 
 typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *);
@@ -19,6 +21,7 @@
 struct elevator_s
 {
 	elevator_merge_fn *elevator_merge_fn;
+	elevator_merged_fn *elevator_merged_fn;
 	elevator_merge_req_fn *elevator_merge_req_fn;
 
 	elevator_next_req_fn *elevator_next_req_fn;
@@ -39,9 +42,10 @@
  */
 extern void __elv_add_request(request_queue_t *, struct request *,
 			      struct list_head *);
-extern int elv_merge(request_queue_t *, struct request **, struct bio *);
+extern int elv_merge(request_queue_t *, struct list_head **, struct bio *);
 extern void elv_merge_requests(request_queue_t *, struct request *,
 			       struct request *);
+extern void elv_merged_request(request_queue_t *, struct request *);
 extern void elv_remove_request(request_queue_t *, struct request *);
 extern int elv_queue_empty(request_queue_t *);
 extern inline struct list_head *elv_get_sort_head(request_queue_t *, struct request *);
@@ -52,12 +56,10 @@
 extern elevator_t elevator_noop;
 
 /*
- * elevator linus. based on linus ideas of starvation control, using
- * sequencing to manage inserts and merges.
+ * deadline i/o scheduler. uses request time outs to prevent indefinite
+ * starvation
  */
-extern elevator_t elevator_linus;
-#define elv_linus_sequence(rq)	((long)(rq)->elevator_private)
-#define ELV_LINUS_SEEK_COST	16
+extern elevator_t iosched_deadline;
 
 /*
  * use the /proc/iosched interface, all the below is history ->
@@ -76,7 +78,7 @@
 extern inline int bio_rq_in_between(struct bio *, struct request *, struct list_head *);
 extern inline int elv_rq_merge_ok(struct request *, struct bio *);
 extern inline int elv_try_merge(struct request *, struct bio *);
-extern inline int elv_try_last_merge(request_queue_t *, struct request **, struct bio *);
+extern inline int elv_try_last_merge(request_queue_t *, struct bio *);
 
 /*
  * Return values from elevator merger
diff -Nru a/include/linux/elf.h b/include/linux/elf.h
--- a/include/linux/elf.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/elf.h	Fri Sep 27 14:51:03 2002
@@ -75,7 +75,7 @@
 
 #define EM_IA_64	50	/* HP/Intel IA-64 */
 
-#define EM_X8664	62	/* AMD x86-64 */
+#define EM_X86_64	62	/* AMD x86-64 */
 
 #define EM_S390		22	/* IBM S/390 */
 
diff -Nru a/include/linux/futex.h b/include/linux/futex.h
--- a/include/linux/futex.h	Fri Sep 27 14:51:04 2002
+++ b/include/linux/futex.h	Fri Sep 27 14:51:04 2002
@@ -6,6 +6,6 @@
 #define FUTEX_WAKE (1)
 #define FUTEX_FD (2)
 
-extern asmlinkage int sys_futex(void *uaddr, int op, int val, struct timespec *utime);
+extern asmlinkage int sys_futex(unsigned long uaddr, int op, int val, struct timespec *utime);
 
 #endif
diff -Nru a/include/linux/genhd.h b/include/linux/genhd.h
--- a/include/linux/genhd.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/genhd.h	Fri Sep 27 14:51:03 2002
@@ -109,6 +109,8 @@
 	disk->capacity = size;
 }
 
+extern struct device_class disk_devclass;
+
 #endif  /*  __KERNEL__  */
 
 #ifdef CONFIG_SOLARIS_X86_PARTITION
diff -Nru a/include/linux/init_task.h b/include/linux/init_task.h
--- a/include/linux/init_task.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/init_task.h	Fri Sep 27 14:51:03 2002
@@ -76,7 +76,6 @@
 	.children	= LIST_HEAD_INIT(tsk.children),			\
 	.sibling	= LIST_HEAD_INIT(tsk.sibling),			\
 	.group_leader	= &tsk,						\
-	.thread_group	= LIST_HEAD_INIT(tsk.thread_group),		\
 	.wait_chldexit	= __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\
 	.real_timer	= {						\
 		.function	= it_real_fn				\
diff -Nru a/include/linux/isdn.h b/include/linux/isdn.h
--- a/include/linux/isdn.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/isdn.h	Fri Sep 27 14:51:05 2002
@@ -245,12 +245,10 @@
 #define ISDN_TIMER_MODEMPLUS   2
 #define ISDN_TIMER_MODEMRING   4
 #define ISDN_TIMER_MODEMXMIT   8
-#define ISDN_TIMER_NETHANGUP  32
 #define ISDN_TIMER_CARRIER   256 /* Wait for Carrier */
 #define ISDN_TIMER_FAST      (ISDN_TIMER_MODEMREAD | ISDN_TIMER_MODEMPLUS | \
                               ISDN_TIMER_MODEMXMIT)
-#define ISDN_TIMER_SLOW      (ISDN_TIMER_MODEMRING | ISDN_TIMER_NETHANGUP | \
-                              ISDN_TIMER_CARRIER)
+#define ISDN_TIMER_SLOW      (ISDN_TIMER_MODEMRING | ISDN_TIMER_CARRIER)
 
 /* GLOBAL_FLAGS */
 #define ISDN_GLOBAL_STOPPED 1
@@ -267,10 +265,10 @@
 #define ISDN_NET_MAGIC      0x49344C02 /* for paranoia-checking             */
 
 /* Phone-list-element */
-typedef struct {
-  void *next;
-  char num[ISDN_MSNLEN];
-} isdn_net_phone;
+struct isdn_net_phone {
+	struct list_head list;
+	char num[ISDN_MSNLEN];
+};
 
 /*
    Principles when extending structures for generic encapsulation protocol
@@ -283,11 +281,13 @@
 
 /* Local interface-data */
 typedef struct isdn_net_local_s {
+  spinlock_t             lock;
   ulong                  magic;
   char                   name[10];     /* Name of device                   */
-  struct timer_list      dial_timer;   /* dial timeout                     */
+  struct timer_list      dial_timer;   /* dial events timer                */
   int                    dial_event;   /* event in case of timer expiry    */
   struct net_device_stats stats;       /* Ethernet Statistics              */
+  struct timer_list      hup_timer;    /* auto hangup timer                */
   int                    isdn_slot;    /* Index to isdn device/channel     */
   int			 ppp_slot;     /* PPPD device slot number          */
   int                    pre_device;   /* Preselected isdn-device          */
@@ -335,10 +335,10 @@
   ulong                  sqfull_stamp; /* Start-Time of overload           */
   ulong                  slavedelay;   /* Dynamic bundling delaytime       */
   int                    triggercps;   /* BogoCPS needed for trigger slave */
-  isdn_net_phone         *phone[2];    /* List of remote-phonenumbers      */
+  struct list_head       phone[2];     /* List of remote-phonenumbers      */
 				       /* phone[0] = Incoming Numbers      */
 				       /* phone[1] = Outgoing Numbers      */
-  isdn_net_phone         *dial;        /* Pointer to dialed number         */
+  int                    dial;         /* # of phone number just dialed    */
   struct net_device      *master;      /* Ptr to Master device for slaves  */
   struct net_device      *slave;       /* Ptr to Slave device for masters  */
   struct isdn_net_local_s *next;       /* Ptr to next link in bundle       */
diff -Nru a/include/linux/isdnif.h b/include/linux/isdnif.h
--- a/include/linux/isdnif.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/isdnif.h	Fri Sep 27 14:51:02 2002
@@ -275,7 +275,6 @@
 } setup_parm;
 
 
-#ifdef CONFIG_ISDN_TTY_FAX
 /* T.30 Fax G3 */
 
 #define FAXIDLEN 21
@@ -349,8 +348,6 @@
 #define ISDN_FAX_PHASE_C   	3
 #define ISDN_FAX_PHASE_D   	4
 #define ISDN_FAX_PHASE_E   	5
-
-#endif /* TTY_FAX */
 
 #define ISDN_FAX_CLASS1_FAE	0
 #define ISDN_FAX_CLASS1_FTS	1
diff -Nru a/include/linux/kallsyms.h b/include/linux/kallsyms.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/kallsyms.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,163 @@
+/* kallsyms headers
+   Copyright 2000 Keith Owens <kaos@ocs.com.au>
+
+   This file is part of the Linux modutils.  It is exported to kernel
+   space so debuggers can access the kallsyms data.
+
+   The kallsyms data contains all the non-stack symbols from a kernel
+   or a module.  The kernel symbols are held between __start___kallsyms
+   and __stop___kallsyms.  The symbols for a module are accessed via
+   the struct module chain which is based at module_list.
+
+   This program is free software; you can redistribute it 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.
+ */
+
+#ident "$Id: linux-2.4.9-kallsyms.patch,v 1.8 2002/02/11 18:34:53 arjanv Exp $"
+
+#ifndef MODUTILS_KALLSYMS_H
+#define MODUTILS_KALLSYMS_H 1
+
+/* Have to (re)define these ElfW entries here because external kallsyms
+ * code does not have access to modutils/include/obj.h.  This code is
+ * included from user spaces tools (modutils) and kernel, they need
+ * different includes.
+ */
+
+#ifndef ELFCLASS32
+#ifdef __KERNEL__
+#include <linux/elf.h>
+#else	/* __KERNEL__ */
+#include <elf.h>
+#endif	/* __KERNEL__ */
+#endif	/* ELFCLASS32 */
+
+#ifndef ELFCLASSM
+#define ELFCLASSM ELF_CLASS
+#endif
+
+#ifndef ElfW
+# if ELFCLASSM == ELFCLASS32
+#  define ElfW(x)  Elf32_ ## x
+#  define ELFW(x)  ELF32_ ## x
+# else
+#  define ElfW(x)  Elf64_ ## x
+#  define ELFW(x)  ELF64_ ## x
+# endif
+#endif
+
+/* Format of data in the kallsyms section.
+ * Most of the fields are small numbers but the total size and all
+ * offsets can be large so use the 32/64 bit types for these fields.
+ *
+ * Do not use sizeof() on these structures, modutils may be using extra
+ * fields.  Instead use the size fields in the header to access the
+ * other bits of data.
+ */  
+
+struct kallsyms_header {
+	int		size;		/* Size of this header */
+	ElfW(Word)	total_size;	/* Total size of kallsyms data */
+	int		sections;	/* Number of section entries */
+	ElfW(Off)	section_off;	/* Offset to first section entry */
+	int		section_size;	/* Size of one section entry */
+	int		symbols;	/* Number of symbol entries */
+	ElfW(Off)	symbol_off;	/* Offset to first symbol entry */
+	int		symbol_size;	/* Size of one symbol entry */
+	ElfW(Off)	string_off;	/* Offset to first string */
+	ElfW(Addr)	start;		/* Start address of first section */
+	ElfW(Addr)	end;		/* End address of last section */
+};
+
+struct kallsyms_section {
+	ElfW(Addr)	start;		/* Start address of section */
+	ElfW(Word)	size;		/* Size of this section */
+	ElfW(Off)	name_off;	/* Offset to section name */
+	ElfW(Word)	flags;		/* Flags from section */
+};
+
+struct kallsyms_symbol {
+	ElfW(Off)	section_off;	/* Offset to section that owns this symbol */
+	ElfW(Addr)	symbol_addr;	/* Address of symbol */
+	ElfW(Off)	name_off;	/* Offset to symbol name */
+};
+
+#define KALLSYMS_SEC_NAME "__kallsyms"
+#define KALLSYMS_IDX 2			/* obj_kallsyms creates kallsyms as section 2 */
+
+#define kallsyms_next_sec(h,s) \
+	((s) = (struct kallsyms_section *)((char *)(s) + (h)->section_size))
+#define kallsyms_next_sym(h,s) \
+	((s) = (struct kallsyms_symbol *)((char *)(s) + (h)->symbol_size))
+
+#ifdef CONFIG_KALLSYMS
+
+int kallsyms_symbol_to_address(
+	const char       *name,			/* Name to lookup */
+	unsigned long    *token,		/* Which module to start with */
+	const char      **mod_name,		/* Set to module name or "kernel" */
+	unsigned long    *mod_start,		/* Set to start address of module */
+	unsigned long    *mod_end,		/* Set to end address of module */
+	const char      **sec_name,		/* Set to section name */
+	unsigned long    *sec_start,		/* Set to start address of section */
+	unsigned long    *sec_end,		/* Set to end address of section */
+	const char      **sym_name,		/* Set to full symbol name */
+	unsigned long    *sym_start,		/* Set to start address of symbol */
+	unsigned long    *sym_end		/* Set to end address of symbol */
+	);
+
+int kallsyms_address_to_symbol(
+	unsigned long     address,		/* Address to lookup */
+	const char      **mod_name,		/* Set to module name */
+	unsigned long    *mod_start,		/* Set to start address of module */
+	unsigned long    *mod_end,		/* Set to end address of module */
+	const char      **sec_name,		/* Set to section name */
+	unsigned long    *sec_start,		/* Set to start address of section */
+	unsigned long    *sec_end,		/* Set to end address of section */
+	const char      **sym_name,		/* Set to full symbol name */
+	unsigned long    *sym_start,		/* Set to start address of symbol */
+	unsigned long    *sym_end		/* Set to end address of symbol */
+	);
+
+int kallsyms_sections(void *token,
+		      int (*callback)(void *,	/* token */
+		      	const char *,		/* module name */
+			const char *,		/* section name */
+			ElfW(Addr),		/* Section start */
+			ElfW(Addr),		/* Section end */
+			ElfW(Word)		/* Section flags */
+		      )
+		);
+
+#else
+
+static inline int kallsyms_address_to_symbol(
+	unsigned long     address,		/* Address to lookup */
+	const char      **mod_name,		/* Set to module name */
+	unsigned long    *mod_start,		/* Set to start address of module */
+	unsigned long    *mod_end,		/* Set to end address of module */
+	const char      **sec_name,		/* Set to section name */
+	unsigned long    *sec_start,		/* Set to start address of section */
+	unsigned long    *sec_end,		/* Set to end address of section */
+	const char      **sym_name,		/* Set to full symbol name */
+	unsigned long    *sym_start,		/* Set to start address of symbol */
+	unsigned long    *sym_end		/* Set to end address of symbol */
+	)
+{
+	return -ESRCH;
+}
+
+#endif
+
+#endif /* kallsyms.h */
diff -Nru a/include/linux/kernel.h b/include/linux/kernel.h
--- a/include/linux/kernel.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/kernel.h	Fri Sep 27 14:51:02 2002
@@ -40,6 +40,13 @@
 
 struct completion;
 
+#ifdef CONFIG_DEBUG_KERNEL
+void __might_sleep(char *file, int line);
+#define might_sleep() __might_sleep(__FILE__, __LINE__)
+#else
+#define might_sleep() do {} while(0)
+#endif
+
 extern struct notifier_block *panic_notifier_list;
 NORET_TYPE void panic(const char * fmt, ...)
 	__attribute__ ((NORET_AND format (printf, 1, 2)));
diff -Nru a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/list.h	Fri Sep 27 14:51:02 2002
@@ -196,7 +196,17 @@
 	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
         	pos = pos->next, prefetch(pos->next))
 
-#define list_for_each_noprefetch(pos, head) \
+/**
+ * __list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop counter.
+ * @head:	the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
 	for (pos = (head)->next; pos != (head); pos = pos->next)
 
 /**
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/mm.h	Fri Sep 27 14:51:03 2002
@@ -374,6 +374,7 @@
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
 
+extern struct page * follow_page(struct mm_struct *mm, unsigned long address, int write);
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
 		int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
 
@@ -524,6 +525,7 @@
 
 extern struct page * vmalloc_to_page(void *addr);
 extern unsigned long get_page_cache_size(void);
+extern unsigned int nr_used_zone_pages(void);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/module.h	Fri Sep 27 14:51:05 2002
@@ -10,6 +10,7 @@
 #include <linux/config.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/errno.h>
 
 #include <asm/atomic.h>
 
@@ -316,8 +317,6 @@
 #define MOD_DEC_USE_COUNT	do { } while (0)
 #define MOD_IN_USE		1
 
-extern struct module *module_list;
-
 #endif /* !__GENKSYMS__ */
 
 #endif /* MODULE */
@@ -504,6 +503,30 @@
 #define SET_MODULE_OWNER(some_struct) do { (some_struct)->owner = THIS_MODULE; } while (0)
 #else
 #define SET_MODULE_OWNER(some_struct) do { } while (0)
+#endif
+
+extern void print_modules(void);
+
+#if defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS)
+
+extern struct module *module_list;
+
+/*
+ * print_symbols takes a format string containing one %s.
+ * If support for resolving symbols is compiled in, the %s will
+ * be replaced by the closest symbol to the address and the entire
+ * string is printk()ed. Otherwise, nothing is printed.
+ */
+extern void print_symbol(const char *fmt, unsigned long address);
+
+#else
+
+static inline int
+print_symbol(const char *fmt, unsigned long address)
+{
+	return -ESRCH;
+}
+
 #endif
 
 #endif /* _LINUX_MODULE_H */
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/netdevice.h	Fri Sep 27 14:51:05 2002
@@ -514,9 +514,10 @@
 {
 	if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
 		unsigned long flags;
-		int cpu = smp_processor_id();
+		int cpu;
 
 		local_irq_save(flags);
+		cpu = smp_processor_id();
 		dev->next_sched = softnet_data[cpu].output_queue;
 		softnet_data[cpu].output_queue = dev;
 		cpu_raise_softirq(cpu, NET_TX_SOFTIRQ);
@@ -563,10 +564,11 @@
 static inline void dev_kfree_skb_irq(struct sk_buff *skb)
 {
 	if (atomic_dec_and_test(&skb->users)) {
-		int cpu =smp_processor_id();
+		int cpu;
 		unsigned long flags;
 
 		local_irq_save(flags);
+		cpu = smp_processor_id();
 		skb->next = softnet_data[cpu].completion_queue;
 		softnet_data[cpu].completion_queue = skb;
 		cpu_raise_softirq(cpu, NET_TX_SOFTIRQ);
@@ -726,9 +728,10 @@
 static inline void __netif_rx_schedule(struct net_device *dev)
 {
 	unsigned long flags;
-	int cpu = smp_processor_id();
+	int cpu;
 
 	local_irq_save(flags);
+	cpu = smp_processor_id();
 	dev_hold(dev);
 	list_add_tail(&dev->poll_list, &softnet_data[cpu].poll_list);
 	if (dev->quota < 0)
@@ -754,11 +757,12 @@
 {
 	if (netif_rx_schedule_prep(dev)) {
 		unsigned long flags;
-		int cpu = smp_processor_id();
+		int cpu;
 
 		dev->quota += undo;
 
 		local_irq_save(flags);
+		cpu = smp_processor_id();
 		list_add_tail(&dev->poll_list, &softnet_data[cpu].poll_list);
 		__cpu_raise_softirq(cpu, NET_RX_SOFTIRQ);
 		local_irq_restore(flags);
diff -Nru a/include/linux/netfilter_bridge/ebt_arp.h b/include/linux/netfilter_bridge/ebt_arp.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_arp.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,26 @@
+#ifndef __LINUX_BRIDGE_EBT_ARP_H
+#define __LINUX_BRIDGE_EBT_ARP_H
+
+#define EBT_ARP_OPCODE 0x01
+#define EBT_ARP_HTYPE 0x02
+#define EBT_ARP_PTYPE 0x04
+#define EBT_ARP_SRC_IP 0x08
+#define EBT_ARP_DST_IP 0x10
+#define EBT_ARP_MASK (EBT_ARP_OPCODE | EBT_ARP_HTYPE | EBT_ARP_PTYPE | \
+   EBT_ARP_SRC_IP | EBT_ARP_DST_IP)
+#define EBT_ARP_MATCH "arp"
+
+struct ebt_arp_info
+{
+	uint16_t htype;
+	uint16_t ptype;
+	uint16_t opcode;
+	uint32_t saddr;
+	uint32_t smsk;
+	uint32_t daddr;
+	uint32_t dmsk;
+	uint8_t  bitmask;
+	uint8_t  invflags;
+};
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebt_ip.h b/include/linux/netfilter_bridge/ebt_ip.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_ip.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,24 @@
+#ifndef __LINUX_BRIDGE_EBT_IP_H
+#define __LINUX_BRIDGE_EBT_IP_H
+
+#define EBT_IP_SOURCE 0x01
+#define EBT_IP_DEST 0x02
+#define EBT_IP_TOS 0x04
+#define EBT_IP_PROTO 0x08
+#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO)
+#define EBT_IP_MATCH "ip"
+
+// the same values are used for the invflags
+struct ebt_ip_info
+{
+	uint32_t saddr;
+	uint32_t daddr;
+	uint32_t smsk;
+	uint32_t dmsk;
+	uint8_t  tos;
+	uint8_t  protocol;
+	uint8_t  bitmask;
+	uint8_t  invflags;
+};
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebt_log.h b/include/linux/netfilter_bridge/ebt_log.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_log.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,17 @@
+#ifndef __LINUX_BRIDGE_EBT_LOG_H
+#define __LINUX_BRIDGE_EBT_LOG_H
+
+#define EBT_LOG_IP 0x01 // if the frame is made by ip, log the ip information
+#define EBT_LOG_ARP 0x02
+#define EBT_LOG_MASK (EBT_LOG_IP | EBT_LOG_ARP)
+#define EBT_LOG_PREFIX_SIZE 30
+#define EBT_LOG_WATCHER "log"
+
+struct ebt_log_info
+{
+	uint8_t loglevel;
+	uint8_t prefix[EBT_LOG_PREFIX_SIZE];
+	uint32_t bitmask;
+};
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebt_mark_m.h b/include/linux/netfilter_bridge/ebt_mark_m.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_mark_m.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,15 @@
+#ifndef __LINUX_BRIDGE_EBT_MARK_M_H
+#define __LINUX_BRIDGE_EBT_MARK_M_H
+
+#define EBT_MARK_AND 0x01
+#define EBT_MARK_OR 0x02
+#define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR)
+struct ebt_mark_m_info
+{
+	unsigned long mark, mask;
+	uint8_t invert;
+	uint8_t bitmask;
+};
+#define EBT_MARK_MATCH "mark_m"
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebt_mark_t.h b/include/linux/netfilter_bridge/ebt_mark_t.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_mark_t.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,12 @@
+#ifndef __LINUX_BRIDGE_EBT_MARK_T_H
+#define __LINUX_BRIDGE_EBT_MARK_T_H
+
+struct ebt_mark_t_info
+{
+	unsigned long mark;
+	// EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN
+	int target;
+};
+#define EBT_MARK_TARGET "mark"
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebt_nat.h b/include/linux/netfilter_bridge/ebt_nat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_nat.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,13 @@
+#ifndef __LINUX_BRIDGE_EBT_NAT_H
+#define __LINUX_BRIDGE_EBT_NAT_H
+
+struct ebt_nat_info
+{
+	unsigned char mac[ETH_ALEN];
+	// EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN
+	int target;
+};
+#define EBT_SNAT_TARGET "snat"
+#define EBT_DNAT_TARGET "dnat"
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebt_redirect.h b/include/linux/netfilter_bridge/ebt_redirect.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_redirect.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,11 @@
+#ifndef __LINUX_BRIDGE_EBT_REDIRECT_H
+#define __LINUX_BRIDGE_EBT_REDIRECT_H
+
+struct ebt_redirect_info
+{
+	// EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN
+	int target;
+};
+#define EBT_REDIRECT_TARGET "redirect"
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebt_vlan.h b/include/linux/netfilter_bridge/ebt_vlan.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebt_vlan.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,20 @@
+#ifndef __LINUX_BRIDGE_EBT_VLAN_H
+#define __LINUX_BRIDGE_EBT_VLAN_H
+
+#define EBT_VLAN_ID	0x01
+#define EBT_VLAN_PRIO	0x02
+#define EBT_VLAN_ENCAP	0x04
+#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP)
+#define EBT_VLAN_MATCH "vlan"
+
+struct ebt_vlan_info {
+	uint16_t id;		/* VLAN ID {1-4095} */
+	uint8_t prio;		/* VLAN User Priority {0-7} */
+	uint16_t encap;		/* VLAN Encapsulated frame code {0-65535} */
+	uint8_t bitmask;		/* Args bitmask bit 1=1 - ID arg,
+				   bit 2=1 User-Priority arg, bit 3=1 encap*/
+	uint8_t invflags;		/* Inverse bitmask  bit 1=1 - inversed ID arg, 
+				   bit 2=1 - inversed Pirority arg */
+};
+
+#endif
diff -Nru a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_bridge/ebtables.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,358 @@
+/*
+ *  ebtables
+ *
+ *	Authors:
+ *	Bart De Schuymer		<bart.de.schuymer@pandora.be>
+ *
+ *  ebtables.c,v 2.0, April, 2002
+ *
+ *  This code is stongly inspired on the iptables code which is
+ *  Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ */
+
+#ifndef __LINUX_BRIDGE_EFF_H
+#define __LINUX_BRIDGE_EFF_H
+#include <linux/if.h>
+#include <linux/netfilter_bridge.h>
+#include <linux/if_ether.h>
+
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+
+// [gs]etsockopt numbers
+#define EBT_BASE_CTL            128
+
+#define EBT_SO_SET_ENTRIES      (EBT_BASE_CTL)
+#define EBT_SO_SET_COUNTERS     (EBT_SO_SET_ENTRIES+1)
+#define EBT_SO_SET_MAX          (EBT_SO_SET_COUNTERS+1)
+
+#define EBT_SO_GET_INFO         (EBT_BASE_CTL)
+#define EBT_SO_GET_ENTRIES      (EBT_SO_GET_INFO+1)
+#define EBT_SO_GET_INIT_INFO    (EBT_SO_GET_ENTRIES+1)
+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
+#define EBT_SO_GET_MAX          (EBT_SO_GET_INIT_ENTRIES+1)
+
+// verdicts >0 are "branches"
+#define EBT_ACCEPT   -1
+#define EBT_DROP     -2
+#define EBT_CONTINUE -3
+#define EBT_RETURN   -4
+#define NUM_STANDARD_TARGETS   4
+
+// return values for match() functions
+#define EBT_MATCH 0
+#define EBT_NOMATCH 1
+
+struct ebt_counter
+{
+	uint64_t pcnt;
+};
+
+struct ebt_entries {
+	// this field is always set to zero
+	// See EBT_ENTRY_OR_ENTRIES.
+	// Must be same size as ebt_entry.bitmask
+	unsigned int distinguisher;
+	// the chain name
+	char name[EBT_CHAIN_MAXNAMELEN];
+	// counter offset for this chain
+	unsigned int counter_offset;
+	// one standard (accept, drop, return) per hook
+	int policy;
+	// nr. of entries
+	unsigned int nentries;
+	// entry list
+	char data[0];
+};
+
+// used for the bitmask of struct ebt_entry
+
+// This is a hack to make a difference between an ebt_entry struct and an
+// ebt_entries struct when traversing the entries from start to end.
+// Using this simplifies the code alot, while still being able to use
+// ebt_entries.
+// Contrary, iptables doesn't use something like ebt_entries and therefore uses
+// different techniques for naming the policy and such. So, iptables doesn't
+// need a hack like this.
+#define EBT_ENTRY_OR_ENTRIES 0x01
+// these are the normal masks
+#define EBT_NOPROTO 0x02
+#define EBT_802_3 0x04
+#define EBT_SOURCEMAC 0x08
+#define EBT_DESTMAC 0x10
+#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
+   | EBT_ENTRY_OR_ENTRIES)
+
+#define EBT_IPROTO 0x01
+#define EBT_IIN 0x02
+#define EBT_IOUT 0x04
+#define EBT_ISOURCE 0x8
+#define EBT_IDEST 0x10
+#define EBT_ILOGICALIN 0x20
+#define EBT_ILOGICALOUT 0x40
+#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
+   | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
+
+struct ebt_entry_match
+{
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct ebt_match *match;
+	} u;
+	// size of data
+	unsigned int match_size;
+	unsigned char data[0];
+};
+
+struct ebt_entry_watcher
+{
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct ebt_watcher *watcher;
+	} u;
+	// size of data
+	unsigned int watcher_size;
+	unsigned char data[0];
+};
+
+struct ebt_entry_target
+{
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct ebt_target *target;
+	} u;
+	// size of data
+	unsigned int target_size;
+	unsigned char data[0];
+};
+
+#define EBT_STANDARD_TARGET "standard"
+struct ebt_standard_target
+{
+	struct ebt_entry_target target;
+	int verdict;
+};
+
+// one entry
+struct ebt_entry {
+	// this needs to be the first field
+	unsigned int bitmask;
+	unsigned int invflags;
+	uint16_t ethproto;
+	// the physical in-dev
+	char in[IFNAMSIZ];
+	// the logical in-dev
+	char logical_in[IFNAMSIZ];
+	// the physical out-dev
+	char out[IFNAMSIZ];
+	// the logical out-dev
+	char logical_out[IFNAMSIZ];
+	unsigned char sourcemac[ETH_ALEN];
+	unsigned char sourcemsk[ETH_ALEN];
+	unsigned char destmac[ETH_ALEN];
+	unsigned char destmsk[ETH_ALEN];
+	// sizeof ebt_entry + matches
+	unsigned int watchers_offset;
+	// sizeof ebt_entry + matches + watchers
+	unsigned int target_offset;
+	// sizeof ebt_entry + matches + watchers + target
+	unsigned int next_offset;
+	unsigned char elems[0];
+};
+
+struct ebt_replace
+{
+	char name[EBT_TABLE_MAXNAMELEN];
+	unsigned int valid_hooks;
+	// nr of rules in the table
+	unsigned int nentries;
+	// total size of the entries
+	unsigned int entries_size;
+	// start of the chains
+	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+	// nr of counters userspace expects back
+	unsigned int num_counters;
+	// where the kernel will put the old counters
+	struct ebt_counter *counters;
+	char *entries;
+};
+
+#ifdef __KERNEL__
+
+struct ebt_match
+{
+	struct list_head list;
+	const char name[EBT_FUNCTION_MAXNAMELEN];
+	// 0 == it matches
+	int (*match)(const struct sk_buff *skb, const struct net_device *in,
+	   const struct net_device *out, const void *matchdata,
+	   unsigned int datalen);
+	// 0 == let it in
+	int (*check)(const char *tablename, unsigned int hookmask,
+	   const struct ebt_entry *e, void *matchdata, unsigned int datalen);
+	void (*destroy)(void *matchdata, unsigned int datalen);
+	struct module *me;
+};
+
+struct ebt_watcher
+{
+	struct list_head list;
+	const char name[EBT_FUNCTION_MAXNAMELEN];
+	void (*watcher)(const struct sk_buff *skb, const struct net_device *in,
+	   const struct net_device *out, const void *watcherdata,
+	   unsigned int datalen);
+	// 0 == let it in
+	int (*check)(const char *tablename, unsigned int hookmask,
+	   const struct ebt_entry *e, void *watcherdata, unsigned int datalen);
+	void (*destroy)(void *watcherdata, unsigned int datalen);
+	struct module *me;
+};
+
+struct ebt_target
+{
+	struct list_head list;
+	const char name[EBT_FUNCTION_MAXNAMELEN];
+	// returns one of the standard verdicts
+	int (*target)(struct sk_buff **pskb, unsigned int hooknr,
+	   const struct net_device *in, const struct net_device *out,
+	   const void *targetdata, unsigned int datalen);
+	// 0 == let it in
+	int (*check)(const char *tablename, unsigned int hookmask,
+	   const struct ebt_entry *e, void *targetdata, unsigned int datalen);
+	void (*destroy)(void *targetdata, unsigned int datalen);
+	struct module *me;
+};
+
+// used for jumping from and into user defined chains (udc)
+struct ebt_chainstack
+{
+	struct ebt_entries *chaininfo; // pointer to chain data
+	struct ebt_entry *e; // pointer to entry data
+	unsigned int n; // n'th entry
+};
+
+struct ebt_table_info
+{
+	// total size of the entries
+	unsigned int entries_size;
+	unsigned int nentries;
+	// pointers to the start of the chains
+	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+	// room to maintain the stack used for jumping from and into udc
+	struct ebt_chainstack **chainstack;
+	char *entries;
+	struct ebt_counter counters[0] ____cacheline_aligned;
+};
+
+struct ebt_table
+{
+	struct list_head list;
+	char name[EBT_TABLE_MAXNAMELEN];
+	struct ebt_replace *table;
+	unsigned int valid_hooks;
+	rwlock_t lock;
+	// e.g. could be the table explicitly only allows certain
+	// matches, targets, ... 0 == let it in
+	int (*check)(const struct ebt_table_info *info,
+	   unsigned int valid_hooks);
+	// the data used by the kernel
+	struct ebt_table_info *private;
+};
+
+extern int ebt_register_table(struct ebt_table *table);
+extern void ebt_unregister_table(struct ebt_table *table);
+extern int ebt_register_match(struct ebt_match *match);
+extern void ebt_unregister_match(struct ebt_match *match);
+extern int ebt_register_watcher(struct ebt_watcher *watcher);
+extern void ebt_unregister_watcher(struct ebt_watcher *watcher);
+extern int ebt_register_target(struct ebt_target *target);
+extern void ebt_unregister_target(struct ebt_target *target);
+extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   struct ebt_table *table);
+
+   // Used in the kernel match() functions
+#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
+// True if the hook mask denotes that the rule is in a base chain,
+// used in the check() functions
+#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS))
+// Clear the bit in the hook mask that tells if the rule is on a base chain
+#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS))
+// True if the target is not a standard target
+#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
+
+#endif /* __KERNEL__ */
+
+// blatently stolen from ip_tables.h
+// fn returns 0 to continue iteration
+#define EBT_MATCH_ITERATE(e, fn, args...)                   \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_match *__match;                    \
+	                                                    \
+	for (__i = sizeof(struct ebt_entry);                \
+	     __i < (e)->watchers_offset;                    \
+	     __i += __match->match_size +                   \
+	     sizeof(struct ebt_entry_match)) {              \
+		__match = (void *)(e) + __i;                \
+		                                            \
+		__ret = fn(__match , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->watchers_offset)            \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_WATCHER_ITERATE(e, fn, args...)                 \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_watcher *__watcher;                \
+	                                                    \
+	for (__i = e->watchers_offset;                      \
+	     __i < (e)->target_offset;                      \
+	     __i += __watcher->watcher_size +               \
+	     sizeof(struct ebt_entry_watcher)) {            \
+		__watcher = (void *)(e) + __i;              \
+		                                            \
+		__ret = fn(__watcher , ## args);            \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->target_offset)              \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_ENTRY_ITERATE(entries, size, fn, args...)       \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry *__entry;                          \
+	                                                    \
+	for (__i = 0; __i < (size);) {                      \
+		__entry = (void *)(entries) + __i;          \
+		__ret = fn(__entry , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+		if (__entry->bitmask != 0)                  \
+			__i += __entry->next_offset;        \
+		else                                        \
+			__i += sizeof(struct ebt_entries);  \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (size))                          \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#endif
diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h	Fri Sep 27 14:51:04 2002
+++ b/include/linux/page-flags.h	Fri Sep 27 14:51:04 2002
@@ -86,9 +86,9 @@
 
 #define mod_page_state(member, delta)					\
 	do {								\
-		preempt_disable();					\
-		page_states[smp_processor_id()].member += (delta);	\
-		preempt_enable();					\
+		int cpu = get_cpu();					\
+		page_states[cpu].member += (delta);			\
+		put_cpu();						\
 	} while (0)
 
 #define inc_page_state(member)	mod_page_state(member, 1UL)
diff -Nru a/include/linux/pagemap.h b/include/linux/pagemap.h
--- a/include/linux/pagemap.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/pagemap.h	Fri Sep 27 14:51:02 2002
@@ -74,9 +74,15 @@
 	inc_page_state(nr_pagecache);
 }
 
-extern void FASTCALL(lock_page(struct page *page));
+extern void FASTCALL(__lock_page(struct page *page));
 extern void FASTCALL(unlock_page(struct page *page));
 
+static inline void lock_page(struct page *page)
+{
+	if (TestSetPageLocked(page))
+		__lock_page(page);
+}
+	
 /*
  * This is exported only for wait_on_page_locked/wait_on_page_writeback.
  * Never use this directly!
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Fri Sep 27 14:51:04 2002
+++ b/include/linux/pci_ids.h	Fri Sep 27 14:51:04 2002
@@ -398,6 +398,7 @@
 #define PCI_DEVICE_ID_AMD_8111_LAN	0x7462
 #define PCI_DEVICE_ID_AMD_8111_IDE	0x7469
 #define PCI_DEVICE_ID_AMD_8111_AUDIO	0x746d
+#define PCI_DEVICE_ID_AMD_8151_0	0x7454
 
 #define PCI_VENDOR_ID_TRIDENT		0x1023
 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX	0x2000
diff -Nru a/include/linux/pid.h b/include/linux/pid.h
--- a/include/linux/pid.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/pid.h	Fri Sep 27 14:51:03 2002
@@ -4,6 +4,7 @@
 enum pid_type
 {
 	PIDTYPE_PID,
+	PIDTYPE_TGID,
 	PIDTYPE_PGID,
 	PIDTYPE_SID,
 	PIDTYPE_MAX
@@ -29,13 +30,12 @@
 	list_entry(elem, struct task_struct, pids[type].pid_chain)
 
 /*
- * attach_pid() must be called with the tasklist_lock write-held.
- *
- * It might unlock the tasklist_lock for allocation, so this
- * function must be called after installing all other links of
- * a new task.
+ * attach_pid() and link_pid() must be called with the tasklist_lock
+ * write-held.
  */
-extern int FASTCALL(attach_pid(struct task_struct *, enum pid_type, int));
+extern int FASTCALL(attach_pid(struct task_struct *task, enum pid_type type, int nr));
+
+extern void FASTCALL(link_pid(struct task_struct *task, struct pid_link *link, struct pid *pid));
 
 /*
  * detach_pid() must be called with the tasklist_lock write-held.
@@ -50,6 +50,7 @@
 
 extern int alloc_pidmap(void);
 extern void FASTCALL(free_pidmap(int));
+extern void switch_exec_pids(struct task_struct *leader, struct task_struct *thread);
 
 #define for_each_task_pid(who, type, task, elem, pid)		\
 	if ((pid = find_pid(type, who)))			\
diff -Nru a/include/linux/rwsem.h b/include/linux/rwsem.h
--- a/include/linux/rwsem.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/rwsem.h	Fri Sep 27 14:51:03 2002
@@ -40,6 +40,7 @@
  */
 static inline void down_read(struct rw_semaphore *sem)
 {
+	might_sleep();
 	rwsemtrace(sem,"Entering down_read");
 	__down_read(sem);
 	rwsemtrace(sem,"Leaving down_read");
@@ -62,6 +63,7 @@
  */
 static inline void down_write(struct rw_semaphore *sem)
 {
+	might_sleep();
 	rwsemtrace(sem,"Entering down_write");
 	__down_write(sem);
 	rwsemtrace(sem,"Leaving down_write");
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/sched.h	Fri Sep 27 14:51:03 2002
@@ -100,8 +100,9 @@
 #define TASK_RUNNING		0
 #define TASK_INTERRUPTIBLE	1
 #define TASK_UNINTERRUPTIBLE	2
-#define TASK_ZOMBIE		4
-#define TASK_STOPPED		8
+#define TASK_STOPPED		4
+#define TASK_ZOMBIE		8
+#define TASK_DEAD		16
 
 #define __set_task_state(tsk, state_value)		\
 	do { (tsk)->state = (state_value); } while (0)
@@ -151,7 +152,13 @@
 
 extern void sched_init(void);
 extern void init_idle(task_t *idle, int cpu);
+
 extern void show_state(void);
+extern void show_trace(unsigned long *stack);
+extern void show_stack(unsigned long *stack);
+extern void show_regs(struct pt_regs *);
+
+
 extern void cpu_init (void);
 extern void trap_init(void);
 extern void update_process_times(int user);
@@ -273,6 +280,7 @@
 #define INIT_USER (&root_user)
 
 typedef struct prio_array prio_array_t;
+struct backing_dev_info;
 
 struct task_struct {
 	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
@@ -327,7 +335,6 @@
 	struct list_head children;	/* list of my children */
 	struct list_head sibling;	/* linkage in my parent's children list */
 	struct task_struct *group_leader;
-	struct list_head thread_group;
 
 	/* PID/PID hash table linkage. */
 	struct pid_link pids[PIDTYPE_MAX];
@@ -398,6 +405,7 @@
 /* journalling filesystem info */
 	void *journal_info;
 	struct dentry *proc_dentry;
+	struct backing_dev_info *backing_dev_info;
 };
 
 extern void __put_task_struct(struct task_struct *tsk);
@@ -795,34 +803,19 @@
 #define while_each_thread(g, t) \
 	while ((t = next_thread(t)) != g)
 
-static inline task_t *next_thread(task_t *p)
-{
-	if (!p->sig)
-		BUG();
-#if CONFIG_SMP
-	if (!spin_is_locked(&p->sig->siglock) &&
-				!rwlock_is_locked(&tasklist_lock))
-		BUG();
-#endif
-	return list_entry((p)->thread_group.next, task_t, thread_group);
-}
+extern task_t * FASTCALL(next_thread(task_t *p));
 
-static inline task_t *prev_thread(task_t *p)
+#define thread_group_leader(p)	(p->pid == p->tgid)
+
+static inline int thread_group_empty(task_t *p)
 {
-	if (!p->sig)
-		BUG();
-#if CONFIG_SMP
-	if (!spin_is_locked(&p->sig->siglock) &&
-				!rwlock_is_locked(&tasklist_lock))
-		BUG();
-#endif
-	return list_entry((p)->thread_group.prev, task_t, thread_group);
-}
+	struct pid *pid = p->pids[PIDTYPE_TGID].pidptr;
 
-#define thread_group_leader(p)	(p->pid == p->tgid)
+	return pid->task_list.next->next == &pid->task_list;
+}
 
 #define delay_group_leader(p) \
-	(p->tgid == p->pid && !list_empty(&p->thread_group))
+		(thread_group_leader(p) && !thread_group_empty(p))
 
 extern void unhash_process(struct task_struct *p);
 
diff -Nru a/include/linux/smp.h b/include/linux/smp.h
--- a/include/linux/smp.h	Fri Sep 27 14:51:04 2002
+++ b/include/linux/smp.h	Fri Sep 27 14:51:04 2002
@@ -91,9 +91,10 @@
 static inline void smp_send_reschedule(int cpu) { }
 static inline void smp_send_reschedule_all(void) { }
 #define cpu_online_map				1
-#define cpu_online(cpu)				({ cpu; 1; })
+#define cpu_online(cpu)				({ BUG_ON((cpu) != 0); 1; })
 #define num_online_cpus()			1
 #define num_booting_cpus()			1
+#define cpu_possible(cpu)				({ BUG_ON((cpu) != 0); 1; })
 
 struct notifier_block;
 
diff -Nru a/include/linux/vcache.h b/include/linux/vcache.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/vcache.h	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,26 @@
+/*
+ * virtual => physical mapping cache support.
+ */
+#ifndef _LINUX_VCACHE_H
+#define _LINUX_VCACHE_H
+
+typedef struct vcache_s {
+	unsigned long address;
+	struct mm_struct *mm;
+	struct list_head hash_entry;
+	void (*callback)(struct vcache_s *data, struct page *new_page);
+} vcache_t;
+
+extern spinlock_t vcache_lock;
+
+extern void __attach_vcache(vcache_t *vcache,
+		unsigned long address,
+		struct mm_struct *mm,
+		void (*callback)(struct vcache_s *data, struct page *new_page));
+
+extern void detach_vcache(vcache_t *vcache);
+
+extern void invalidate_vcache(unsigned long address, struct mm_struct *mm,
+				struct page *new_page);
+
+#endif
diff -Nru a/include/linux/wait.h b/include/linux/wait.h
--- a/include/linux/wait.h	Fri Sep 27 14:51:02 2002
+++ b/include/linux/wait.h	Fri Sep 27 14:51:02 2002
@@ -119,6 +119,32 @@
 		_raced;						\
 	})
 
+/*
+ * Waitqueue's which are removed from the waitqueue_head at wakeup time
+ */
+void FASTCALL(prepare_to_wait(wait_queue_head_t *q,
+				wait_queue_t *wait, int state));
+void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q,
+				wait_queue_t *wait, int state));
+void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait));
+int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync);
+
+#define DEFINE_WAIT(name)						\
+	wait_queue_t name = {						\
+		.task		= current,				\
+		.func		= autoremove_wake_function,		\
+		.task_list	= {	.next = &name.task_list,	\
+					.prev = &name.task_list,	\
+				},					\
+	}
+
+#define init_wait(wait)							\
+	do {								\
+		wait->task = current;					\
+		wait->func = autoremove_wake_function;			\
+		INIT_LIST_HEAD(&wait->task_list);			\
+	} while (0)
+	
 #endif /* __KERNEL__ */
 
 #endif
diff -Nru a/include/linux/writeback.h b/include/linux/writeback.h
--- a/include/linux/writeback.h	Fri Sep 27 14:51:03 2002
+++ b/include/linux/writeback.h	Fri Sep 27 14:51:03 2002
@@ -43,6 +43,8 @@
 					   older than this */
 	long nr_to_write;		/* Write this many pages, and decrement
 					   this for each page written */
+	int nonblocking;		/* Don't get stuck on request queues */
+	int encountered_congestion;	/* An output: a queue is full */
 };
 	
 void writeback_inodes(struct writeback_control *wbc);
@@ -61,6 +63,8 @@
 /*
  * mm/page-writeback.c
  */
+int wakeup_bdflush(long nr_pages);
+
 /* These 5 are exported to sysctl. */
 extern int dirty_background_ratio;
 extern int dirty_async_ratio;
diff -Nru a/include/linux/x25.h b/include/linux/x25.h
--- a/include/linux/x25.h	Fri Sep 27 14:51:05 2002
+++ b/include/linux/x25.h	Fri Sep 27 14:51:05 2002
@@ -39,16 +39,16 @@
  * An X.121 address, it is held as ASCII text, null terminated, up to 15
  * digits and a null terminator.
  */
-typedef struct {
-	char		x25_addr[16];
-} x25_address;
+struct x25_address {
+	char x25_addr[16];
+};
 
 /*
  *	Linux X.25 Address structure, used for bind, and connect mostly.
  */
 struct sockaddr_x25 {
-	sa_family_t	sx25_family;		/* Must be AF_X25 */
-	x25_address	sx25_addr;		/* X.121 Address */
+	sa_family_t	   sx25_family;		/* Must be AF_X25 */
+	struct x25_address sx25_addr;		/* X.121 Address */
 };
 
 /*
@@ -78,9 +78,9 @@
  *	Routing table control structure.
  */
 struct x25_route_struct {
-	x25_address	address;
-	unsigned int	sigdigits;
-	char		device[200];
+	struct x25_address address;
+	unsigned int	   sigdigits;
+	char		   device[200];
 };
 
 /*
diff -Nru a/include/net/irda/irda-usb.h b/include/net/irda/irda-usb.h
--- a/include/net/irda/irda-usb.h	Fri Sep 27 14:51:05 2002
+++ b/include/net/irda/irda-usb.h	Fri Sep 27 14:51:05 2002
@@ -127,7 +127,7 @@
 struct irda_usb_cb {
 	struct irda_class_desc *irda_desc;
 	struct usb_device *usbdev;	/* init: probe_irda */
-	unsigned int ifnum;		/* Interface number of the USB dev. */
+	struct usb_interface *usbintf;	/* init: probe_irda */
 	int netopen;			/* Device is active for network */
 	int present;			/* Device is present on the bus */
 	__u32 capability;		/* Capability of the hardware */
diff -Nru a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h
--- a/include/net/llc_c_ac.h	Fri Sep 27 14:51:05 2002
+++ b/include/net/llc_c_ac.h	Fri Sep 27 14:51:05 2002
@@ -216,4 +216,6 @@
 extern void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data);
 extern void llc_conn_ack_tmr_cb(unsigned long timeout_data);
 extern void llc_conn_rej_tmr_cb(unsigned long timeout_data);
+
+extern void llc_conn_set_p_flag(struct sock *sk, u8 value);
 #endif /* LLC_C_AC_H */
diff -Nru a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h
--- a/include/net/llc_c_ev.h	Fri Sep 27 14:51:03 2002
+++ b/include/net/llc_c_ev.h	Fri Sep 27 14:51:03 2002
@@ -110,38 +110,14 @@
 #define LLC_CONN_EV_QFY_S_FLAG_EQ_0		11
 #define LLC_CONN_EV_QFY_INIT_P_F_CYCLE		12
 
-/* Event data interface; what is sent in an event package */
-/* Event LLC_CONN_EV_TYPE_SIMPLE interface */
-struct llc_conn_ev_simple_if {
-	u8 ev;
-};
-
-/* Event LLC_CONN_EV_TYPE_PRIM interface */
-struct llc_conn_ev_prim_if {
-	u8			  prim;  /* connect, disconnect, reset, ... */
-	u8			  type;  /* request, indicate, response, conf */
-	struct llc_prim_if_block *data;
-};
-
-/* Event LLC_CONN_EV_TYPE_PDU interface */
-struct llc_conn_ev_pdu_if {
-	u8 ev;
-	u8 reason;
-};
-
-union llc_conn_ev_if {
-	struct llc_conn_ev_simple_if  a;	/* 'a' for simple, easy ... */
-	struct llc_conn_ev_prim_if    prim;
-	struct llc_conn_ev_pdu_if     pdu;
-};
-
 struct llc_conn_state_ev {
-	u8			  type;
-	u8			  status;
-	u8			  flag;
-	struct llc_prim_if_block *ind_prim;
-	struct llc_prim_if_block *cfm_prim;
-	union llc_conn_ev_if	  data;
+	u8 type;
+	u8 prim;
+	u8 prim_type;
+	u8 reason;
+	u8 status;
+	u8 ind_prim;
+	u8 cfm_prim;
 };
 
 static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb)
diff -Nru a/include/net/llc_conn.h b/include/net/llc_conn.h
--- a/include/net/llc_conn.h	Fri Sep 27 14:51:05 2002
+++ b/include/net/llc_conn.h	Fri Sep 27 14:51:05 2002
@@ -66,18 +66,10 @@
 	u32		    rx_pdu_hdr;	   /* used for saving header of last pdu
 					      received and caused sending FRMR.
 					      Used for resending FRMR */
-#ifdef DEBUG_LLC_CONN_ALLOC
-	char *f_alloc,	/* function that allocated this connection */
-	     *f_free;	/* function that freed this connection */
-	int l_alloc,	/* line that allocated this connection */
-	    l_free;	/* line that freed this connection */
-#endif
 };
 
 #define llc_sk(__sk) ((struct llc_opt *)(__sk)->protinfo)
 
-struct llc_conn_state_ev;
-
 extern struct sock *llc_sk_alloc(int family, int priority);
 extern void llc_sk_free(struct sock *sk);
 
@@ -100,6 +92,9 @@
 					   struct llc_addr *laddr);
 extern struct sock *llc_lookup_listener(struct llc_sap *sap,
 					struct llc_addr *laddr);
+extern struct sock *llc_lookup_dgram(struct llc_sap *sap,
+				     struct llc_addr *laddr);
+extern void llc_save_primitive(struct sk_buff* skb, u8 prim);
 extern u8 llc_data_accept_state(u8 state);
 extern void llc_build_offset_table(void);
 #endif /* LLC_CONN_H */
diff -Nru a/include/net/llc_evnt.h b/include/net/llc_evnt.h
--- a/include/net/llc_evnt.h	Fri Sep 27 14:51:04 2002
+++ b/include/net/llc_evnt.h	Fri Sep 27 14:51:04 2002
@@ -31,30 +31,12 @@
 #define LLC_STATION_EV_RX_NULL_DSAP_TEST_C			8
 #define LLC_STATION_EV_DISABLE_REQ				9
 
-/* Interfaces for various types of supported events */
-struct llc_stat_ev_simple_if {
-	u8 ev;
-};
-
-struct llc_stat_ev_prim_if {
-	u8 prim; /* connect, disconnect, reset, ... */
-	u8 type; /* request, indicate, response, confirm */
-};
-
-struct llc_stat_ev_pdu_if {
-	u8 reason;
-};
-
-union llc_stat_ev_if {
-	struct llc_stat_ev_simple_if  a;	/* 'a' for simple, easy ... */
-	struct llc_stat_ev_prim_if    prim;
-	struct llc_stat_ev_pdu_if     pdu;
-};
-
 struct llc_station_state_ev {
-	u8		     type;
-	union llc_stat_ev_if data;
-	struct list_head     node; /* node in station->ev_q.list */
+	u8		 type;
+	u8		 prim;
+	u8		 prim_type;
+	u8		 reason;
+	struct list_head node; /* node in station->ev_q.list */
 };
 
 static __inline__ struct llc_station_state_ev *
diff -Nru a/include/net/llc_frame.h b/include/net/llc_frame.h
--- a/include/net/llc_frame.h	Fri Sep 27 14:51:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,98 +0,0 @@
-/* if_ether.h needed for definition of ETH_DATA_LEN and ETH_ALEN
- */
-#include "linux/if_ether.h"
-
-/* frame layout based on par3.2 "LLC PDU format"
- */
-typedef union {			/* pdu layout from pages 40 & 44 */
-    struct {			/* general header, all pdu types */
-	unsigned dsap : 8;	/* dest service access point */
-	unsigned ssap : 8;	/* source service access point */
-	unsigned f1 : 1;	/* I- U- or S- format id bits */
-	unsigned f2 : 1;
-	unsigned : 6;
-	unsigned : 8;
-   } pdu_hdr;
-   struct {
-        char dummy1[2];   	/* dsap + ssap */
-	char byte1;
-	char byte2;
-   } pdu_cntl;			/* unformatted control bytes */
-   struct {			/* header of an Information pdu */
-	unsigned char dummy2[2];
-	unsigned : 1;
-	unsigned ns : 7;
-	unsigned i_pflag : 1;   /* poll/final bit */
-	unsigned nr : 7;	/* N(R)  */	
-	unsigned char is_info[ ETH_DATA_LEN ];
-   }  i_hdr;
-   struct {			/* header of a Supervisory pdu */
- 	unsigned char dummy3[2];
-	unsigned : 2;
-	unsigned ss : 2;	/* supervisory function bits */
-	unsigned : 4;
-	unsigned s_pflag : 1;   /* poll/final bit  */
-	unsigned nr : 7;	/* N(R)  */
-   } s_hdr;
-
-/* when accessing the P/F bit or the N(R) field there's no need to distinguish
-   I pdus from S pdus i_pflag and s_pflag / i_nr and s_nr map to the same
-   physical location.
- */ 
-   struct {			/* header of an Unnumbered pdu */
-	unsigned char dummy4[2];
-	unsigned : 2;
-	unsigned mm1 : 2;	/* modifier function part1 */
-	unsigned u_pflag : 1;    /* P/F for U- pdus */
-	unsigned mm2 : 3;	/* modifier function part2 */
-	unsigned char u_info[ ETH_DATA_LEN-1];
-   } u_hdr;
-   struct {			/* mm field in an Unnumbered pdu */
-	unsigned char dummy5[2];
-	unsigned : 2;
-	unsigned mm : 6;	/* must be masked to get ridd of P/F !  */
-   } u_mm;
-   	 
-} frame_type, *frameptr;
-
-/* frame format test macros: */
-
-#define IS_UFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & ( (fr)->pdu_hdr.f2) )
-
-#define IS_IFRAME( fr ) ( !( (fr)->pdu_hdr.f1) )
-
-#define IS_SFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & !( (fr)->pdu_hdr.f2) )
-
-#define IS_RSP( fr ) ( fr->pdu_hdr.ssap & 0x01 )
-
-
-/* The transition table, the _encode tables and some tests in the
-   source code depend on the numeric order of these values.
-   Think twice before changing.
- */
-
-/* frame names for TYPE 2 operation: */
-#define I_CMD		0
-#define RR_CMD		1
-#define RNR_CMD		2
-#define REJ_CMD		3
-#define DISC_CMD	4
-#define SABME_CMD	5
-#define I_RSP		6
-#define RR_RSP		7
-#define RNR_RSP		8
-#define REJ_RSP		9
-#define UA_RSP		10
-#define DM_RSP		11
-#define FRMR_RSP	12
-
-/* junk frame name: */
-#define BAD_FRAME	13
-#define NO_FRAME	13
-
-/* frame names for TYPE 1 operation: */
-#define UI_CMD		14
-#define XID_CMD		15
-#define TEST_CMD	16
-#define XID_RSP		17
-#define TEST_RSP	18
diff -Nru a/include/net/llc_if.h b/include/net/llc_if.h
--- a/include/net/llc_if.h	Fri Sep 27 14:51:02 2002
+++ b/include/net/llc_if.h	Fri Sep 27 14:51:02 2002
@@ -17,17 +17,17 @@
 #include <linux/if_arp.h>
 #include <linux/llc.h>
 
-#define LLC_DATAUNIT_PRIM	0
-#define LLC_CONN_PRIM		1
-#define LLC_DATA_PRIM		2
-#define LLC_DISC_PRIM		3
-#define LLC_RESET_PRIM		4
-#define LLC_FLOWCONTROL_PRIM	5 /* Not supported at this time */
-#define LLC_DISABLE_PRIM	6
-#define LLC_XID_PRIM		7
-#define LLC_TEST_PRIM		8
-#define LLC_SAP_ACTIVATION      9
-#define LLC_SAP_DEACTIVATION   10
+#define LLC_DATAUNIT_PRIM	1
+#define LLC_CONN_PRIM		2
+#define LLC_DATA_PRIM		3
+#define LLC_DISC_PRIM		4
+#define LLC_RESET_PRIM		5
+#define LLC_FLOWCONTROL_PRIM	6 /* Not supported at this time */
+#define LLC_DISABLE_PRIM	7
+#define LLC_XID_PRIM		8
+#define LLC_TEST_PRIM		9
+#define LLC_SAP_ACTIVATION     10
+#define LLC_SAP_DEACTIVATION   11
 
 #define LLC_NBR_PRIMITIVES     11
 
@@ -67,67 +67,22 @@
 	u8 mac[IFHWADDRLEN];
 };
 
-struct llc_prim_reset {
-	struct sock *sk;
-	u16	     link;
-	u8	     reason;		/* used only by indicate */
-};
-
- /* Sending data in conection-less mode */
-struct llc_prim_unit_data {
-	struct llc_addr	saddr;
-	struct llc_addr	daddr;
-	u8		pri;
-	struct sk_buff *skb;		/* pointer to frame */
-	u8		lfb;		/* largest frame bit (TR) */
-};
-
-struct llc_prim_xid {
-	struct llc_addr saddr;
-	struct llc_addr daddr;
-	u8		pri;
-	struct sk_buff *skb;
-};
-
-struct llc_prim_test {
-	struct llc_addr	saddr;
-	struct llc_addr	daddr;
-	u8		pri;
-	struct sk_buff *skb;		/* pointer to frame */
-};
-
-union llc_u_prim_data {
-	struct llc_prim_reset	  res;
-	struct llc_prim_unit_data udata;	/* unit data */
-	struct llc_prim_xid	  xid;
-	struct llc_prim_test	  test;
-};
-
 struct llc_sap;
 
-/* Information block passed with all called primitives */
-struct llc_prim_if_block {
-	struct llc_sap	      *sap;
-	u8		       prim;
-	union llc_u_prim_data *data;
-};
-typedef int (*llc_prim_call_t)(struct llc_prim_if_block *prim_if);
-
-extern struct llc_sap *llc_sap_open(llc_prim_call_t network_indicate,
-				    llc_prim_call_t network_confirm, u8 lsap);
+extern struct llc_sap *llc_sap_open(u8 lsap,
+				    int (*func)(struct sk_buff *skb,
+						struct net_device *dev,
+						struct packet_type *pt));
 extern void llc_sap_close(struct llc_sap *sap);
 
 extern int llc_establish_connection(struct sock *sk, u8 *lmac,
 				    u8 *dmac, u8 dsap);
 extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
-extern void llc_build_and_send_ui_pkt(struct llc_sap *sap,
-				      struct sk_buff *skb,
+extern void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
 				      u8 *dmac, u8 dsap);
-extern void llc_build_and_send_xid_pkt(struct llc_sap *sap,
-				       struct sk_buff *skb,
+extern void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
 				       u8 *dmac, u8 dsap);
-extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
-					struct sk_buff *skb,
+extern void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
 					u8 *dmac, u8 dsap);
 extern int llc_send_disc(struct sock *sk);
 #endif /* LLC_IF_H */
diff -Nru a/include/net/llc_main.h b/include/net/llc_main.h
--- a/include/net/llc_main.h	Fri Sep 27 14:51:04 2002
+++ b/include/net/llc_main.h	Fri Sep 27 14:51:04 2002
@@ -43,7 +43,7 @@
 	u8			    maximum_retry;
 	u8			    mac_sa[6];
 	struct {
-		spinlock_t	    lock;
+		rwlock_t	    lock;
 		struct list_head    list;
 	} sap_list;
 	struct {
@@ -52,7 +52,6 @@
 	} ev_q;
 	struct sk_buff_head	    mac_pdu_q;
 };
-struct llc_station_state_ev;
 
 extern struct llc_sap *llc_sap_alloc(void);
 extern void llc_sap_save(struct llc_sap *sap);
diff -Nru a/include/net/llc_name.h b/include/net/llc_name.h
--- a/include/net/llc_name.h	Fri Sep 27 14:51:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,7 +0,0 @@
-char *frame_names[] =
-    {"I_CMD","RR_CMD","RNR_CMD","REJ_CMD","DISC_CMD",
-    "SABME_CMD","I_RSP","RR_RSP","RNR_RSP","REJ_RSP",
-    "UA_RSP","DM_RSP","FRMR_RSP","BAD_FRAME","UI_CMD",
-    "XID_CMD","TEST_CMD","XID_RSP","TEST_RSP"
-};
- 
diff -Nru a/include/net/llc_s_ev.h b/include/net/llc_s_ev.h
--- a/include/net/llc_s_ev.h	Fri Sep 27 14:51:03 2002
+++ b/include/net/llc_s_ev.h	Fri Sep 27 14:51:03 2002
@@ -34,37 +34,14 @@
 #define LLC_SAP_EV_RX_TEST_R		 9
 #define LLC_SAP_EV_DEACTIVATION_REQ	10
 
-/* Interfaces for various types of supported events */
-struct llc_sap_ev_simple_if {
-	u8 ev;
-};
-
-struct llc_prim_if_block;
-
-struct llc_sap_ev_prim_if {
-	u8			  prim; /* connect, disconnect, reset, ... */
-	u8			  type; /* request, indicate, response, conf */
-	struct llc_prim_if_block *data;
-};
-
-struct llc_sap_ev_pdu_if {
-	u8 ev;
-	u8 reason;
-};
-
-union llc_sap_ev_if {
-	struct llc_sap_ev_simple_if	a;	/* 'a' for simple, easy ... */
-	struct llc_sap_ev_prim_if	prim;
-	struct llc_sap_ev_pdu_if	pdu;
-};
-
-struct llc_prim_if_block;
-
 struct llc_sap_state_ev {
-	u8			  type;
-	u8			  ind_cfm_flag;
-	struct llc_prim_if_block *prim;
-	union llc_sap_ev_if	  data;
+	u8		prim;
+	u8		prim_type;
+	u8		type;
+	u8		reason;
+	u8		ind_cfm_flag;
+	struct llc_addr saddr;
+	struct llc_addr daddr;
 };
 
 static __inline__ struct llc_sap_state_ev *llc_sap_ev(struct sk_buff *skb)
diff -Nru a/include/net/llc_sap.h b/include/net/llc_sap.h
--- a/include/net/llc_sap.h	Fri Sep 27 14:51:02 2002
+++ b/include/net/llc_sap.h	Fri Sep 27 14:51:02 2002
@@ -12,36 +12,33 @@
  * See the GNU General Public License for more details.
  */
 #include <linux/skbuff.h>
+#include <net/llc_if.h>
 /**
  * struct llc_sap - Defines the SAP component
  *
+ * @station - station this sap belongs to
+ * @state - sap state
  * @p_bit - only lowest-order bit used
  * @f_bit - only lowest-order bit used
- * @ind - provided by network layer
- * @conf - provided by network layer
  * @laddr - SAP value in this 'lsap'
  * @node - entry in station sap_list
  * @sk_list - LLC sockets this one manages
- * @mac_pdu_q - PDUs ready to send to MAC
  */
 struct llc_sap {
-	struct llc_station	 *parent_station;
-	u8			 state;
-	u8			 p_bit;
-	u8			 f_bit;
-	llc_prim_call_t		 ind;
-	llc_prim_call_t		 conf;
-	struct llc_prim_if_block llc_ind_prim, llc_cfm_prim;
-	union llc_u_prim_data	 llc_ind_data_prim, llc_cfm_data_prim;
-	struct llc_addr		 laddr;
-	struct list_head	 node;
+	struct llc_station *station;
+	u8		    state;
+	u8		    p_bit;
+	u8		    f_bit;
+	int		    (*rcv_func)(struct sk_buff *skb,
+					struct net_device *dev,
+					struct packet_type *pt);
+	struct llc_addr	    laddr;
+	struct list_head    node;
 	struct {
-		spinlock_t	 lock;
-		struct list_head list;
+		rwlock_t    lock;
+		struct sock *list;
 	} sk_list;
-	struct sk_buff_head	 mac_pdu_q;
 };
-struct llc_sap_state_ev;
 
 extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk);
 extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk);
diff -Nru a/include/net/llc_state.h b/include/net/llc_state.h
--- a/include/net/llc_state.h	Fri Sep 27 14:51:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,4 +0,0 @@
-char *state_names[] = { 
-	"ADM","CONN","RESET_WAIT","RESET_CHECK","SETUP",
-	"RESET","D_CONN","ERROR","NORMAL"
-};
diff -Nru a/include/net/ndisc.h b/include/net/ndisc.h
--- a/include/net/ndisc.h	Fri Sep 27 14:51:05 2002
+++ b/include/net/ndisc.h	Fri Sep 27 14:51:05 2002
@@ -51,6 +51,25 @@
 	__u32			retrans_timer;
 };
 
+struct nd_opt_hdr {
+	__u8		nd_opt_type;
+	__u8		nd_opt_len;
+} __attribute__((__packed__));
+
+struct ndisc_options {
+	struct nd_opt_hdr *nd_opt_array[7];
+	struct nd_opt_hdr *nd_opt_piend;
+};
+
+#define nd_opts_src_lladdr	nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
+#define nd_opts_tgt_lladdr	nd_opt_array[ND_OPT_TARGET_LL_ADDR]
+#define nd_opts_pi		nd_opt_array[ND_OPT_PREFIX_INFO]
+#define nd_opts_pi_end		nd_opt_piend
+#define nd_opts_rh		nd_opt_array[ND_OPT_REDIRECT_HDR]
+#define nd_opts_mtu		nd_opt_array[ND_OPT_MTU]
+
+extern struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, struct nd_opt_hdr *end);
+extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, struct ndisc_options *ndopts);
 
 extern int			ndisc_init(struct net_proto_family *ops);
 
diff -Nru a/include/net/p8022.h b/include/net/p8022.h
--- a/include/net/p8022.h	Fri Sep 27 14:51:05 2002
+++ b/include/net/p8022.h	Fri Sep 27 14:51:05 2002
@@ -1,9 +1,10 @@
 #ifndef _NET_P8022_H
 #define _NET_P8022_H
-#include <net/llc_if.h>
-
-extern struct datalink_proto *register_8022_client(unsigned char type,
-			   int (*indicate)(struct llc_prim_if_block *prim));
+extern struct datalink_proto *
+	register_8022_client(unsigned char type,
+			     int (*func)(struct sk_buff *skb,
+					 struct net_device *dev,
+					 struct packet_type *pt));
 extern void unregister_8022_client(struct datalink_proto *proto);
 
 #endif
diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h
--- a/include/net/sctp/constants.h	Fri Sep 27 14:51:04 2002
+++ b/include/net/sctp/constants.h	Fri Sep 27 14:51:04 2002
@@ -112,6 +112,7 @@
 	SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
 	SCTP_EVENT_TIMEOUT_T3_RTX,
 	SCTP_EVENT_TIMEOUT_T4_RTO,
+	SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
 	SCTP_EVENT_TIMEOUT_HEARTBEAT,
 	SCTP_EVENT_TIMEOUT_SACK,
 	SCTP_EVENT_TIMEOUT_AUTOCLOSE,
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h	Fri Sep 27 14:51:03 2002
+++ b/include/net/sctp/sctp.h	Fri Sep 27 14:51:03 2002
@@ -114,7 +114,8 @@
 extern struct sock *sctp_get_ctl_sock(void);
 extern int sctp_copy_local_addr_list(sctp_protocol_t *, sctp_bind_addr_t *,
 				     sctp_scope_t, int priority, int flags);
-
+extern sctp_pf_t *sctp_get_pf_specific(int family);
+extern void sctp_set_pf_specific(int family, sctp_pf_t *);
 
 /*
  * sctp_socket.c
diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h
--- a/include/net/sctp/sm.h	Fri Sep 27 14:51:04 2002
+++ b/include/net/sctp/sm.h	Fri Sep 27 14:51:04 2002
@@ -107,6 +107,9 @@
 sctp_state_fn_t sctp_sf_do_9_1_abort;
 sctp_state_fn_t sctp_sf_cookie_wait_abort;
 sctp_state_fn_t sctp_sf_cookie_echoed_abort;
+sctp_state_fn_t sctp_sf_shutdown_pending_abort;
+sctp_state_fn_t sctp_sf_shutdown_sent_abort;
+sctp_state_fn_t sctp_sf_shutdown_ack_sent_abort;
 sctp_state_fn_t sctp_sf_do_5_1B_init;
 sctp_state_fn_t sctp_sf_do_5_1C_ack;
 sctp_state_fn_t sctp_sf_do_5_1D_ce;
@@ -119,6 +122,7 @@
 sctp_state_fn_t sctp_sf_operr_notify;
 sctp_state_fn_t sctp_sf_t1_timer_expire;
 sctp_state_fn_t sctp_sf_t2_timer_expire;
+sctp_state_fn_t sctp_sf_t5_timer_expire;
 sctp_state_fn_t sctp_sf_sendbeat_8_3;
 sctp_state_fn_t sctp_sf_beat_8_3;
 sctp_state_fn_t sctp_sf_backbeat_8_3;
@@ -134,6 +138,7 @@
 sctp_state_fn_t sctp_sf_do_5_2_1_siminit;
 sctp_state_fn_t sctp_sf_do_5_2_2_dupinit;
 sctp_state_fn_t sctp_sf_do_5_2_4_dupcook;
+sctp_state_fn_t sctp_sf_unk_chunk;
 
 /* Prototypes for primitive event state functions.  */
 sctp_state_fn_t sctp_sf_do_prm_asoc;
@@ -144,6 +149,9 @@
 sctp_state_fn_t sctp_sf_do_9_1_prm_abort;
 sctp_state_fn_t sctp_sf_cookie_wait_prm_abort;
 sctp_state_fn_t sctp_sf_cookie_echoed_prm_abort;
+sctp_state_fn_t sctp_sf_shutdown_pending_prm_abort;
+sctp_state_fn_t sctp_sf_shutdown_sent_prm_abort;
+sctp_state_fn_t sctp_sf_shutdown_ack_sent_prm_abort;
 sctp_state_fn_t sctp_sf_error_closed;
 sctp_state_fn_t sctp_sf_error_shutdown;
 sctp_state_fn_t sctp_sf_ignore_primitive;
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	Fri Sep 27 14:51:04 2002
+++ b/include/net/sctp/structs.h	Fri Sep 27 14:51:04 2002
@@ -255,6 +255,12 @@
 
 sctp_func_t *sctp_get_af_specific(const sockaddr_storage_t *address);
 
+/* Protocol family functions. */
+typedef struct sctp_pf {
+	void (*event_msgname)(sctp_ulpevent_t *, char *, int *);
+	void (*skb_msgname)(struct sk_buff *, char *, int *);
+} sctp_pf_t;
+
 /* SCTP Socket type: UDP or TCP style. */
 typedef enum {
 	SCTP_SOCKET_UDP = 0,
@@ -280,6 +286,7 @@
 	__u32 autoclose;
 	__u8 nodelay;
 	__u8 disable_fragments;
+	sctp_pf_t *pf;
 };
 
 
@@ -845,6 +852,7 @@
                                       sctp_outqueue_ohandler_force_t force);
 void sctp_outqueue_restart(sctp_outqueue_t *);
 void sctp_retransmit(sctp_outqueue_t *, sctp_transport_t *, __u8);
+void sctp_retransmit_mark(sctp_outqueue_t *, sctp_transport_t *, __u8);
 
 
 /* These bind address data fields common between endpoints and associations */
@@ -1128,6 +1136,11 @@
 		 */
 		sctp_transport_t *primary_path;
 
+		/* Cache the primary path address here, when we
+		 * need a an address for msg_name. 
+		 */
+		sockaddr_storage_t primary_addr;
+		
 		/* active_path
 		 *   The path that we are currently using to
 		 *   transmit new data and most control chunks.
@@ -1183,7 +1196,7 @@
 		int next_dup_tsn;
 
 		/* Do we need to sack the peer? */
-		int sack_needed;
+		uint8_t sack_needed;
 
 		/* These are capabilities which our peer advertised.  */
 		__u8	ecn_capable;     /* Can peer do ECN? */
diff -Nru a/include/net/x25.h b/include/net/x25.h
--- a/include/net/x25.h	Fri Sep 27 14:51:04 2002
+++ b/include/net/x25.h	Fri Sep 27 14:51:04 2002
@@ -103,9 +103,9 @@
 
 struct x25_route {
 	struct x25_route	*next;
-	x25_address		address;	/* Start of address range */
+	struct x25_address	address;	/* Start of address range */
 	unsigned int		sigdigits;	/* Number of sig digits */
-	struct net_device		*dev;		/* More than one for MLP */
+	struct net_device	*dev;		/* More than one for MLP */
 };
 
 struct x25_neigh {
@@ -120,7 +120,7 @@
 };
 
 typedef struct {
-	x25_address		source_addr, dest_addr;
+	struct x25_address	source_addr, dest_addr;
 	struct x25_neigh	*neighbour;
 	unsigned int		lci;
 	unsigned char		state, condition, qbitincl, intflag;
@@ -148,8 +148,10 @@
 extern int  sysctl_x25_clear_request_timeout;
 extern int  sysctl_x25_ack_holdback_timeout;
 
-extern int  x25_addr_ntoa(unsigned char *, x25_address *, x25_address *);
-extern int  x25_addr_aton(unsigned char *, x25_address *, x25_address *);
+extern int  x25_addr_ntoa(unsigned char *, struct x25_address *,
+			  struct x25_address *);
+extern int  x25_addr_aton(unsigned char *, struct x25_address *,
+			  struct x25_address *);
 extern unsigned int x25_new_lci(struct x25_neigh *);
 extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *);
 extern void x25_destroy_socket(struct sock *);
@@ -194,7 +196,7 @@
 extern void x25_enquiry_response(struct sock *);
 
 /* x25_route.c */
-extern struct net_device *x25_get_route(x25_address *);
+extern struct net_device *x25_get_route(struct x25_address *);
 extern struct net_device *x25_dev_get(char *);
 extern void x25_route_device_down(struct net_device *);
 extern int  x25_route_ioctl(unsigned int, void *);
diff -Nru a/kernel/Makefile b/kernel/Makefile
--- a/kernel/Makefile	Fri Sep 27 14:51:03 2002
+++ b/kernel/Makefile	Fri Sep 27 14:51:03 2002
@@ -3,7 +3,7 @@
 #
 
 export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
-		printk.o platform.o suspend.o dma.o
+	      printk.o platform.o suspend.o dma.o module.o
 
 obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
 	    module.o exit.o itimer.o time.o softirq.o resource.o \
@@ -14,6 +14,7 @@
 obj-$(CONFIG_SMP) += cpu.o
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += ksyms.o
+obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_PM) += pm.o
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Fri Sep 27 14:51:04 2002
+++ b/kernel/exit.c	Fri Sep 27 14:51:04 2002
@@ -32,15 +32,16 @@
 static struct dentry * __unhash_process(struct task_struct *p)
 {
 	struct dentry *proc_dentry;
+
 	nr_threads--;
 	detach_pid(p, PIDTYPE_PID);
+	detach_pid(p, PIDTYPE_TGID);
 	if (thread_group_leader(p)) {
 		detach_pid(p, PIDTYPE_PGID);
 		detach_pid(p, PIDTYPE_SID);
 	}
 
 	REMOVE_LINKS(p);
-	p->pid = 0;
 	proc_dentry = p->proc_dentry;
 	if (unlikely(proc_dentry != NULL)) {
 		spin_lock(&dcache_lock);
@@ -57,23 +58,32 @@
 void release_task(struct task_struct * p)
 {
 	struct dentry *proc_dentry;
+	task_t *leader;
 
-	if (p->state != TASK_ZOMBIE)
+	if (p->state < TASK_ZOMBIE)
 		BUG();
 	if (p != current)
 		wait_task_inactive(p);
 	atomic_dec(&p->user->processes);
 	security_ops->task_free_security(p);
 	free_uid(p->user);
-	if (unlikely(p->ptrace)) {
-		write_lock_irq(&tasklist_lock);
+	write_lock_irq(&tasklist_lock);
+	if (unlikely(p->ptrace))
 		__ptrace_unlink(p);
-		write_unlock_irq(&tasklist_lock);
-	}
 	BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
-	write_lock_irq(&tasklist_lock);
 	__exit_sighand(p);
 	proc_dentry = __unhash_process(p);
+
+	/*
+	 * If we are the last non-leader member of the thread
+	 * group, and the leader is zombie, then notify the
+	 * group leader's parent process. (if it wants notification.)
+	 */
+	leader = p->group_leader;
+	if (leader != p && thread_group_empty(leader) &&
+		    leader->state == TASK_ZOMBIE && leader->exit_signal != -1)
+		do_notify_parent(leader, leader->exit_signal);
+
 	p->parent->cutime += p->utime + p->cutime;
 	p->parent->cstime += p->stime + p->cstime;
 	p->parent->cmin_flt += p->min_flt + p->cmin_flt;
@@ -122,9 +132,14 @@
 	for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid)
 		if (p->session > 0) {
 			sid = p->session;
-			break;
+			goto out;
 		}
+	p = find_task_by_pid(pgrp);
+	if (p)
+		sid = p->session;
+out:
 	read_unlock(&tasklist_lock);
+	
 	return sid;
 }
 
@@ -145,7 +160,7 @@
 
 	for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
 		if (p == ignored_task
-				|| p->state == TASK_ZOMBIE 
+				|| p->state >= TASK_ZOMBIE 
 				|| p->real_parent->pid == 1)
 			continue;
 		if (p->real_parent->pgrp != pgrp
@@ -421,8 +436,11 @@
 
 static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_reaper)
 {
-	/* Make sure we're not reparenting to ourselves.  */
-	if (p == reaper)
+	/*
+	 * Make sure we're not reparenting to ourselves and that
+	 * the parent is not a zombie.
+	 */
+	if (p == reaper || reaper->state >= TASK_ZOMBIE)
 		p->real_parent = child_reaper;
 	else
 		p->real_parent = reaper;
@@ -612,7 +630,7 @@
 	tsk->flags |= PF_EXITING;
 	del_timer_sync(&tsk->real_timer);
 
-	if (unlikely(preempt_count()))
+	if (unlikely(in_atomic()))
 		printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
 				current->comm, current->pid,
 				preempt_count());
@@ -670,6 +688,25 @@
 	do_exit((error_code&0xff)<<8);
 }
 
+task_t *next_thread(task_t *p)
+{
+	struct pid_link *link = p->pids + PIDTYPE_TGID;
+	struct list_head *tmp, *head = &link->pidptr->task_list;
+
+#if CONFIG_SMP
+	if (!p->sig)
+		BUG();
+	if (!spin_is_locked(&p->sig->siglock) &&
+				!rwlock_is_locked(&tasklist_lock))
+		BUG();
+#endif
+	tmp = link->pid_chain.next;
+	if (tmp == head)
+		tmp = head->next;
+
+	return pid_task(tmp, PIDTYPE_TGID);
+}
+
 /*
  * this kills every thread in the thread group. Note that any externally
  * wait4()-ing process will get the correct exit code - even if this 
@@ -679,7 +716,7 @@
 {
 	unsigned int exit_code = (error_code & 0xff) << 8;
 
-	if (!list_empty(&current->thread_group)) {
+	if (!thread_group_empty(current)) {
 		struct signal_struct *sig = current->sig;
 
 		spin_lock_irq(&sig->siglock);
@@ -741,9 +778,10 @@
 
 asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
 {
-	int flag, retval;
 	DECLARE_WAITQUEUE(wait, current);
 	struct task_struct *tsk;
+	unsigned long state;
+	int flag, retval;
 
 	if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD|__WCLONE|__WALL))
 		return -EINVAL;
@@ -794,7 +832,15 @@
 				 */
 				if (ret == 2)
 					continue;
+				/*
+				 * Try to move the task's state to DEAD
+				 * only one thread is allowed to do this:
+				 */
+				state = xchg(&p->state, TASK_DEAD);
+				if (state != TASK_ZOMBIE)
+					continue;
 				read_unlock(&tasklist_lock);
+
 				retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
 				if (!retval && stat_addr) {
 					if (p->sig->group_exit)
@@ -802,13 +848,16 @@
 					else
 						retval = put_user(p->exit_code, stat_addr);
 				}
-				if (retval)
-					goto end_wait4; 
+				if (retval) {
+					p->state = TASK_ZOMBIE;
+					goto end_wait4;
+				}
 				retval = p->pid;
 				if (p->real_parent != p->parent) {
 					write_lock_irq(&tasklist_lock);
 					__ptrace_unlink(p);
 					do_notify_parent(p, SIGCHLD);
+					p->state = TASK_ZOMBIE;
 					write_unlock_irq(&tasklist_lock);
 				} else
 					release_task(p);
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Fri Sep 27 14:51:03 2002
+++ b/kernel/fork.c	Fri Sep 27 14:51:03 2002
@@ -62,13 +62,15 @@
 		free_thread_info(tsk->thread_info);
 		kmem_cache_free(task_struct_cachep,tsk);
 	} else {
-		int cpu = smp_processor_id();
+		int cpu = get_cpu();
 
-		tsk = xchg(task_cache + cpu, tsk);
+		tsk = task_cache[cpu];
 		if (tsk) {
 			free_thread_info(tsk->thread_info);
 			kmem_cache_free(task_struct_cachep,tsk);
 		}
+		task_cache[cpu] = current;
+		put_cpu();
 	}
 }
 
@@ -101,6 +103,52 @@
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
+void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
+{
+	unsigned long flags;
+
+	__set_current_state(state);
+	wait->flags &= ~WQ_FLAG_EXCLUSIVE;
+	spin_lock_irqsave(&q->lock, flags);
+	if (list_empty(&wait->task_list))
+		__add_wait_queue(q, wait);
+	spin_unlock_irqrestore(&q->lock, flags);
+}
+
+void
+prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)
+{
+	unsigned long flags;
+
+	__set_current_state(state);
+	wait->flags |= WQ_FLAG_EXCLUSIVE;
+	spin_lock_irqsave(&q->lock, flags);
+	if (list_empty(&wait->task_list))
+		__add_wait_queue_tail(q, wait);
+	spin_unlock_irqrestore(&q->lock, flags);
+}
+
+void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
+{
+	unsigned long flags;
+
+	__set_current_state(TASK_RUNNING);
+	if (!list_empty(&wait->task_list)) {
+		spin_lock_irqsave(&q->lock, flags);
+		list_del_init(&wait->task_list);
+		spin_unlock_irqrestore(&q->lock, flags);
+	}
+}
+
+int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync)
+{
+	int ret = default_wake_function(wait, mode, sync);
+
+	if (ret)
+		list_del_init(&wait->task_list);
+	return ret;
+}
+
 void __init fork_init(unsigned long mempages)
 {
 	/* create a slab on which task_structs can be allocated */
@@ -126,8 +174,11 @@
 {
 	struct task_struct *tsk;
 	struct thread_info *ti;
+	int cpu = get_cpu();
 
-	tsk = xchg(task_cache + smp_processor_id(), NULL);
+	tsk = task_cache[cpu];
+	task_cache[cpu] = NULL;
+	put_cpu();
 	if (!tsk) {
 		ti = alloc_thread_info();
 		if (!ti)
@@ -330,7 +381,7 @@
 		 * not set up a proper pointer then tough luck.
 		 */
 		put_user(0, tsk->user_tid);
-		sys_futex(tsk->user_tid, FUTEX_WAKE, 1, NULL);
+		sys_futex((unsigned long)tsk->user_tid, FUTEX_WAKE, 1, NULL);
 	}
 }
 
@@ -802,7 +853,6 @@
 	 */
 	p->tgid = p->pid;
 	p->group_leader = p;
-	INIT_LIST_HEAD(&p->thread_group);
 	INIT_LIST_HEAD(&p->ptrace_children);
 	INIT_LIST_HEAD(&p->ptrace_list);
 
@@ -830,7 +880,6 @@
 		}
 		p->tgid = current->tgid;
 		p->group_leader = current->group_leader;
-		list_add(&p->thread_group, &current->thread_group);
 		spin_unlock(&current->sig->siglock);
 	}
 
@@ -840,9 +889,11 @@
 
 	attach_pid(p, PIDTYPE_PID, p->pid);
 	if (thread_group_leader(p)) {
+		attach_pid(p, PIDTYPE_TGID, p->tgid);
 		attach_pid(p, PIDTYPE_PGID, p->pgrp);
 		attach_pid(p, PIDTYPE_SID, p->session);
-	}
+	} else
+		link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid);
 
 	nr_threads++;
 	write_unlock_irq(&tasklist_lock);
diff -Nru a/kernel/futex.c b/kernel/futex.c
--- a/kernel/futex.c	Fri Sep 27 14:51:03 2002
+++ b/kernel/futex.c	Fri Sep 27 14:51:03 2002
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/futex.h>
+#include <linux/vcache.h>
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/pagemap.h>
@@ -38,7 +39,6 @@
 #include <linux/poll.h>
 #include <linux/file.h>
 #include <linux/dcache.h>
-#include <asm/uaccess.h>
 
 /* Simple "sleep if unchanged" interface. */
 
@@ -55,9 +55,14 @@
 struct futex_q {
 	struct list_head list;
 	wait_queue_head_t waiters;
+
 	/* Page struct and offset within it. */
 	struct page *page;
 	unsigned int offset;
+
+	/* the virtual => physical cache */
+	vcache_t vcache;
+
 	/* For fd, sigio sent using these. */
 	int fd;
 	struct file *filp;
@@ -85,21 +90,43 @@
 		send_sigio(&q->filp->f_owner, q->fd, POLL_IN);
 }
 
+/* Get kernel address of the user page and pin it. */
+static struct page *pin_page(unsigned long page_start)
+{
+	struct mm_struct *mm = current->mm;
+	struct page *page = NULL;
+	int err;
+
+	down_read(&mm->mmap_sem);
+
+	err = get_user_pages(current, mm, page_start,
+			     1 /* one page */,
+			     0 /* not writable */,
+			     0 /* don't force */,
+			     &page,
+			     NULL /* don't return vmas */);
+	up_read(&mm->mmap_sem);
+	if (err < 0)
+		return ERR_PTR(err);
+	return page;
+}
+
 static inline void unpin_page(struct page *page)
 {
-	/* Avoid releasing the page which is on the LRU list.  I don't
-           know if this is correct, but it stops the BUG() in
-           __free_pages_ok(). */
 	page_cache_release(page);
 }
 
-static int futex_wake(struct list_head *head,
-		      struct page *page,
-		      unsigned int offset,
-		      int num)
+static int futex_wake(unsigned long uaddr, unsigned int offset, int num)
 {
-	struct list_head *i, *next;
-	int num_woken = 0;
+	struct list_head *i, *next, *head;
+	struct page *page;
+	int ret;
+
+	page = pin_page(uaddr - offset);
+	ret = IS_ERR(page);
+	if (ret)
+		goto out;
+	head = hash_futex(page, offset);
 
 	spin_lock(&futex_lock);
 	list_for_each_safe(i, next, head) {
@@ -108,36 +135,81 @@
 		if (this->page == page && this->offset == offset) {
 			list_del_init(i);
 			tell_waiter(this);
-			num_woken++;
-			if (num_woken >= num) break;
+			ret++;
+			if (ret >= num)
+				break;
 		}
 	}
 	spin_unlock(&futex_lock);
-	return num_woken;
+	unpin_page(page);
+out:
+	return ret;
+}
+
+static void futex_vcache_callback(vcache_t *vcache, struct page *new_page)
+{
+	struct futex_q *q = container_of(vcache, struct futex_q, vcache);
+	struct list_head *head = hash_futex(new_page, q->offset);
+
+	BUG_ON(list_empty(&q->list));
+
+	spin_lock(&futex_lock);
+
+	q->page = new_page;
+	list_del_init(&q->list);
+	list_add_tail(&q->list, head);
+
+	spin_unlock(&futex_lock);
 }
 
 /* Add at end to avoid starvation */
-static inline void queue_me(struct list_head *head,
+static inline int queue_me(struct list_head *head,
 			    struct futex_q *q,
 			    struct page *page,
 			    unsigned int offset,
 			    int fd,
-			    struct file *filp)
+			    struct file *filp,
+			    unsigned long uaddr)
 {
-	q->page = page;
+	struct page *tmp;
+	int ret = 0;
+
 	q->offset = offset;
 	q->fd = fd;
 	q->filp = filp;
 
+	spin_lock(&vcache_lock);
 	spin_lock(&futex_lock);
-	list_add_tail(&q->list, head);
+	spin_lock(&current->mm->page_table_lock);
+
+	/*
+	 * Has the mapping changed meanwhile?
+	 */
+	tmp = follow_page(current->mm, uaddr, 0);
+
+	if (tmp == page) {
+		q->page = page;
+		list_add_tail(&q->list, head);
+		/*
+		 * We register a futex callback to this virtual address,
+		 * to make sure a COW properly rehashes the futex-queue.
+		 */
+		__attach_vcache(&q->vcache, uaddr, current->mm, futex_vcache_callback);
+	} else
+		ret = 1;
+
+	spin_unlock(&current->mm->page_table_lock);
 	spin_unlock(&futex_lock);
+	spin_unlock(&vcache_lock);
+
+	return ret;
 }
 
 /* Return 1 if we were still queued (ie. 0 means we were woken) */
 static inline int unqueue_me(struct futex_q *q)
 {
 	int ret = 0;
+
 	spin_lock(&futex_lock);
 	if (!list_empty(&q->list)) {
 		list_del(&q->list);
@@ -147,46 +219,34 @@
 	return ret;
 }
 
-/* Get kernel address of the user page and pin it. */
-static struct page *pin_page(unsigned long page_start)
-{
-	struct mm_struct *mm = current->mm;
-	struct page *page;
-	int err;
-
-	down_read(&mm->mmap_sem);
-	err = get_user_pages(current, mm, page_start,
-			     1 /* one page */,
-			     0 /* writable not important */,
-			     0 /* don't force */,
-			     &page,
-			     NULL /* don't return vmas */);
-	up_read(&mm->mmap_sem);
-
-	if (err < 0)
-		return ERR_PTR(err);
-	return page;
-}
-
-static int futex_wait(struct list_head *head,
-		      struct page *page,
+static int futex_wait(unsigned long uaddr,
 		      int offset,
 		      int val,
-		      int *uaddr,
 		      unsigned long time)
 {
-	int curval;
-	struct futex_q q;
 	DECLARE_WAITQUEUE(wait, current);
-	int ret = 0;
+	struct list_head *head;
+	int ret = 0, curval;
+	struct page *page;
+	struct futex_q q;
+
+repeat_lookup:
+	page = pin_page(uaddr - offset);
+	ret = IS_ERR(page);
+	if (ret)
+		goto out;
+	head = hash_futex(page, offset);
 
 	set_current_state(TASK_INTERRUPTIBLE);
 	init_waitqueue_head(&q.waiters);
 	add_wait_queue(&q.waiters, &wait);
-	queue_me(head, &q, page, offset, -1, NULL);
+	if (queue_me(head, &q, page, offset, -1, NULL, uaddr)) {
+		unpin_page(page);
+		goto repeat_lookup;
+	}
 
 	/* Page is pinned, but may no longer be in this address space. */
-	if (get_user(curval, uaddr) != 0) {
+	if (get_user(curval, (int *)uaddr) != 0) {
 		ret = -EFAULT;
 		goto out;
 	}
@@ -204,11 +264,15 @@
 		ret = -EINTR;
 		goto out;
 	}
- out:
+out:
+	detach_vcache(&q.vcache);
 	set_current_state(TASK_RUNNING);
 	/* Were we woken up anyway? */
 	if (!unqueue_me(&q))
-		return 0;
+		ret = 0;
+	if (page)
+		unpin_page(page);
+
 	return ret;
 }
 
@@ -251,25 +315,26 @@
 
 /* Signal allows caller to avoid the race which would occur if they
    set the sigio stuff up afterwards. */
-static int futex_fd(struct list_head *head,
-		    struct page *page,
-		    int offset,
-		    int signal)
+static int futex_fd(unsigned long uaddr, int offset, int signal)
 {
-	int fd;
+	struct page *page = NULL;
+	struct list_head *head;
 	struct futex_q *q;
 	struct file *filp;
+	int ret;
 
+	ret = -EINVAL;
 	if (signal < 0 || signal > _NSIG)
-		return -EINVAL;
+		goto out;
 
-	fd = get_unused_fd();
-	if (fd < 0)
-		return fd;
+	ret = get_unused_fd();
+	if (ret < 0)
+		goto out;
 	filp = get_empty_filp();
 	if (!filp) {
-		put_unused_fd(fd);
-		return -ENFILE;
+		put_unused_fd(ret);
+		ret = -ENFILE;
+		goto out;
 	}
 	filp->f_op = &futex_fops;
 	filp->f_vfsmnt = mntget(futex_mnt);
@@ -280,37 +345,55 @@
 		
 		ret = f_setown(filp, current->tgid, 1);
 		if (ret) {
-			put_unused_fd(fd);
+			put_unused_fd(ret);
 			put_filp(filp);
-			return ret;
+			goto out;
 		}
 		filp->f_owner.signum = signal;
 	}
 
 	q = kmalloc(sizeof(*q), GFP_KERNEL);
 	if (!q) {
-		put_unused_fd(fd);
+		put_unused_fd(ret);
+		put_filp(filp);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+repeat_lookup:
+	page = pin_page(uaddr - offset);
+	ret = IS_ERR(page);
+	if (ret) {
+		put_unused_fd(ret);
 		put_filp(filp);
-		return -ENOMEM;
+		kfree(q);
+		page = NULL;
+		goto out;
 	}
+	head = hash_futex(page, offset);
 
 	/* Initialize queue structure, and add to hash table. */
 	filp->private_data = q;
 	init_waitqueue_head(&q->waiters);
-	queue_me(head, q, page, offset, fd, filp);
+	if (queue_me(head, q, page, offset, ret, filp, uaddr)) {
+		unpin_page(page);
+		goto repeat_lookup;
+	}
 
 	/* Now we map fd to filp, so userspace can access it */
-	fd_install(fd, filp);
-	return fd;
+	fd_install(ret, filp);
+	page = NULL;
+out:
+	if (page)
+		unpin_page(page);
+	return ret;
 }
 
-asmlinkage int sys_futex(void *uaddr, int op, int val, struct timespec *utime)
+asmlinkage int sys_futex(unsigned long uaddr, int op, int val, struct timespec *utime)
 {
-	int ret;
-	unsigned long pos_in_page;
-	struct list_head *head;
-	struct page *page;
 	unsigned long time = MAX_SCHEDULE_TIMEOUT;
+	unsigned long pos_in_page;
+	int ret;
 
 	if (utime) {
 		struct timespec t;
@@ -319,38 +402,27 @@
 		time = timespec_to_jiffies(&t) + 1;
 	}
 
-	pos_in_page = ((unsigned long)uaddr) % PAGE_SIZE;
+	pos_in_page = uaddr % PAGE_SIZE;
 
 	/* Must be "naturally" aligned, and not on page boundary. */
 	if ((pos_in_page % __alignof__(int)) != 0
 	    || pos_in_page + sizeof(int) > PAGE_SIZE)
 		return -EINVAL;
 
-	/* Simpler if it doesn't vanish underneath us. */
-	page = pin_page((unsigned long)uaddr - pos_in_page);
-	if (IS_ERR(page))
-		return PTR_ERR(page);
-
-	head = hash_futex(page, pos_in_page);
 	switch (op) {
 	case FUTEX_WAIT:
-		ret = futex_wait(head, page, pos_in_page, val, uaddr, time);
+		ret = futex_wait(uaddr, pos_in_page, val, time);
 		break;
 	case FUTEX_WAKE:
-		ret = futex_wake(head, page, pos_in_page, val);
+		ret = futex_wake(uaddr, pos_in_page, val);
 		break;
 	case FUTEX_FD:
 		/* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */
-		ret = futex_fd(head, page, pos_in_page, val);
-		if (ret >= 0)
-			/* Leave page pinned (attached to fd). */
-			return ret;
+		ret = futex_fd(uaddr, pos_in_page, val);
 		break;
 	default:
 		ret = -EINVAL;
 	}
-	unpin_page(page);
-
 	return ret;
 }
 
diff -Nru a/kernel/kallsyms.c b/kernel/kallsyms.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/kernel/kallsyms.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,227 @@
+/*
+ * kksymoops.c: in-kernel printing of symbolic oopses and stack traces.
+ *
+ *  Copyright 2000 Keith Owens <kaos@ocs.com.au> April 2000
+ *  Copyright 2002 Arjan van de Ven <arjanv@redhat.com>
+ *
+   This code uses the list of all kernel and module symbols to :-
+
+   * Find any non-stack symbol in a kernel or module.  Symbols do
+     not have to be exported for debugging.
+
+   * Convert an address to the module (or kernel) that owns it, the
+     section it is in and the nearest symbol.  This finds all non-stack
+     symbols, not just exported ones.
+
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+
+/* A symbol can appear in more than one module.  A token is used to
+ * restart the scan at the next module, set the token to 0 for the
+ * first scan of each symbol.
+ */
+
+int kallsyms_symbol_to_address(
+	const char	 *name,		/* Name to lookup */
+	unsigned long 	 *token,	/* Which module to start at */
+	const char	**mod_name,	/* Set to module name */
+	unsigned long 	 *mod_start,	/* Set to start address of module */
+	unsigned long 	 *mod_end,	/* Set to end address of module */
+	const char	**sec_name,	/* Set to section name */
+	unsigned long 	 *sec_start,	/* Set to start address of section */
+	unsigned long 	 *sec_end,	/* Set to end address of section */
+	const char	**sym_name,	/* Set to full symbol name */
+	unsigned long 	 *sym_start,	/* Set to start address of symbol */
+	unsigned long 	 *sym_end	/* Set to end address of symbol */
+	)
+{
+	const struct kallsyms_header	*ka_hdr = NULL;	/* stupid gcc */
+	const struct kallsyms_section	*ka_sec;
+	const struct kallsyms_symbol	*ka_sym = NULL;
+	const char			*ka_str = NULL;
+	const struct module *m;
+	int i = 0, l;
+	const char *p, *pt_R;
+	char *p2;
+
+	/* Restart? */
+	m = module_list;
+	if (token && *token) {
+		for (; m; m = m->next)
+			if ((unsigned long)m == *token)
+				break;
+		if (m)
+			m = m->next;
+	}
+
+	for (; m; m = m->next) {
+		if (!mod_member_present(m, kallsyms_start) || 
+		    !mod_member_present(m, kallsyms_end) ||
+		    m->kallsyms_start >= m->kallsyms_end)
+			continue;
+		ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
+		ka_sym = (struct kallsyms_symbol *)
+			((char *)(ka_hdr) + ka_hdr->symbol_off);
+		ka_str = 
+			((char *)(ka_hdr) + ka_hdr->string_off);
+		for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) {
+			p = ka_str + ka_sym->name_off;
+			if (strcmp(p, name) == 0)
+				break;
+			/* Unversioned requests match versioned names */
+			if (!(pt_R = strstr(p, "_R")))
+				continue;
+			l = strlen(pt_R);
+			if (l < 10)
+				continue;	/* Not _R.*xxxxxxxx */
+			(void)simple_strtoul(pt_R+l-8, &p2, 16);
+			if (*p2)
+				continue;	/* Not _R.*xxxxxxxx */
+			if (strncmp(p, name, pt_R-p) == 0)
+				break;	/* Match with version */
+		}
+		if (i < ka_hdr->symbols)
+			break;
+	}
+
+	if (token)
+		*token = (unsigned long)m;
+	if (!m)
+		return(0);	/* not found */
+
+	ka_sec = (const struct kallsyms_section *)
+		((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off);
+	*mod_name = m->name;
+	*mod_start = ka_hdr->start;
+	*mod_end = ka_hdr->end;
+	*sec_name = ka_sec->name_off + ka_str;
+	*sec_start = ka_sec->start;
+	*sec_end = ka_sec->start + ka_sec->size;
+	*sym_name = ka_sym->name_off + ka_str;
+	*sym_start = ka_sym->symbol_addr;
+	if (i < ka_hdr->symbols-1) {
+		const struct kallsyms_symbol *ka_symn = ka_sym;
+		kallsyms_next_sym(ka_hdr, ka_symn);
+		*sym_end = ka_symn->symbol_addr;
+	}
+	else
+		*sym_end = *sec_end;
+	return(1);
+}
+
+int kallsyms_address_to_symbol(
+	unsigned long	  address,	/* Address to lookup */
+	const char	**mod_name,	/* Set to module name */
+	unsigned long 	 *mod_start,	/* Set to start address of module */
+	unsigned long 	 *mod_end,	/* Set to end address of module */
+	const char	**sec_name,	/* Set to section name */
+	unsigned long 	 *sec_start,	/* Set to start address of section */
+	unsigned long 	 *sec_end,	/* Set to end address of section */
+	const char	**sym_name,	/* Set to full symbol name */
+	unsigned long 	 *sym_start,	/* Set to start address of symbol */
+	unsigned long 	 *sym_end	/* Set to end address of symbol */
+	)
+{
+	const struct kallsyms_header	*ka_hdr = NULL;	/* stupid gcc */
+	const struct kallsyms_section	*ka_sec = NULL;
+	const struct kallsyms_symbol	*ka_sym;
+	const char			*ka_str;
+	const struct module *m;
+	int i;
+	unsigned long end;
+
+	for (m = module_list; m; m = m->next) {
+	  
+		if (!mod_member_present(m, kallsyms_start) || 
+		    !mod_member_present(m, kallsyms_end) ||
+		    m->kallsyms_start >= m->kallsyms_end)
+			continue;
+		ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
+		ka_sec = (const struct kallsyms_section *)
+			((char *)ka_hdr + ka_hdr->section_off);
+		/* Is the address in any section in this module? */
+		for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) {
+			if (ka_sec->start <= address &&
+			    (ka_sec->start + ka_sec->size) > address)
+				break;
+		}
+		if (i < ka_hdr->sections)
+			break;	/* Found a matching section */
+	}
+
+	if (!m)
+		return(0);	/* not found */
+
+	ka_sym = (struct kallsyms_symbol *)
+		((char *)(ka_hdr) + ka_hdr->symbol_off);
+	ka_str = 
+		((char *)(ka_hdr) + ka_hdr->string_off);
+	*mod_name = m->name;
+	*mod_start = ka_hdr->start;
+	*mod_end = ka_hdr->end;
+	*sec_name = ka_sec->name_off + ka_str;
+	*sec_start = ka_sec->start;
+	*sec_end = ka_sec->start + ka_sec->size;
+	*sym_name = *sec_name;		/* In case we find no matching symbol */
+	*sym_start = *sec_start;
+	*sym_end = *sec_end;
+
+	for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) {
+		if (ka_sym->symbol_addr > address)
+			continue;
+		if (i < ka_hdr->symbols-1) {
+			const struct kallsyms_symbol *ka_symn = ka_sym;
+			kallsyms_next_sym(ka_hdr, ka_symn);
+			end = ka_symn->symbol_addr;
+		}
+		else
+			end = *sec_end;
+		if (end <= address)
+			continue;
+		if ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off
+		    != (char *)ka_sec)
+			continue;	/* wrong section */
+		*sym_name = ka_str + ka_sym->name_off;
+		*sym_start = ka_sym->symbol_addr;
+		*sym_end = end;
+		break;
+	}
+	return(1);
+}
+
+/* List all sections in all modules.  The callback routine is invoked with
+ * token, module name, section name, section start, section end, section flags.
+ */
+int kallsyms_sections(void *token,
+		      int (*callback)(void *, const char *, const char *, ElfW(Addr), ElfW(Addr), ElfW(Word)))
+{
+	const struct kallsyms_header	*ka_hdr = NULL;	/* stupid gcc */
+	const struct kallsyms_section	*ka_sec = NULL;
+	const char			*ka_str;
+	const struct module *m;
+	int i;
+
+	for (m = module_list; m; m = m->next) {
+		if (!mod_member_present(m, kallsyms_start) || 
+		    !mod_member_present(m, kallsyms_end) ||
+		    m->kallsyms_start >= m->kallsyms_end)
+			continue;
+		ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
+		ka_sec = (const struct kallsyms_section *) ((char *)ka_hdr + ka_hdr->section_off);
+		ka_str = ((char *)(ka_hdr) + ka_hdr->string_off);
+		for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) {
+			if (callback(
+				token,
+				*(m->name) ? m->name : "kernel",
+				ka_sec->name_off + ka_str,
+				ka_sec->start,
+				ka_sec->start + ka_sec->size,
+				ka_sec->flags))
+				return(0);
+		}
+	}
+	return(1);
+}
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Fri Sep 27 14:51:02 2002
+++ b/kernel/ksyms.c	Fri Sep 27 14:51:02 2002
@@ -335,7 +335,6 @@
 EXPORT_SYMBOL(tty_std_termios);
 
 /* block device driver support */
-EXPORT_SYMBOL(blk_size);
 EXPORT_SYMBOL(blk_dev);
 EXPORT_SYMBOL(bdev_read_only);
 EXPORT_SYMBOL(set_device_ro);
@@ -401,6 +400,10 @@
 EXPORT_SYMBOL(add_wait_queue);
 EXPORT_SYMBOL(add_wait_queue_exclusive);
 EXPORT_SYMBOL(remove_wait_queue);
+EXPORT_SYMBOL(prepare_to_wait);
+EXPORT_SYMBOL(prepare_to_wait_exclusive);
+EXPORT_SYMBOL(finish_wait);
+EXPORT_SYMBOL(autoremove_wake_function);
 
 /* completion handling */
 EXPORT_SYMBOL(wait_for_completion);
@@ -494,7 +497,9 @@
 EXPORT_SYMBOL(xtime);
 EXPORT_SYMBOL(do_gettimeofday);
 EXPORT_SYMBOL(do_settimeofday);
-
+#ifdef CONFIG_DEBUG_KERNEL
+EXPORT_SYMBOL(__might_sleep);
+#endif
 #if !defined(__ia64__)
 EXPORT_SYMBOL(loops_per_jiffy);
 #endif
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Fri Sep 27 14:51:03 2002
+++ b/kernel/module.c	Fri Sep 27 14:51:03 2002
@@ -3,6 +3,7 @@
 #include <linux/module.h>
 #include <asm/module.h>
 #include <asm/uaccess.h>
+#include <linux/kallsyms.h>
 #include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
 #include <asm/pgalloc.h>
@@ -39,8 +40,14 @@
 extern const struct exception_table_entry __start___ex_table[];
 extern const struct exception_table_entry __stop___ex_table[];
 
-extern const char __start___kallsyms[] __attribute__ ((weak));
-extern const char __stop___kallsyms[] __attribute__ ((weak));
+extern const char __start___kallsyms[] __attribute__((weak));
+extern const char __stop___kallsyms[] __attribute__((weak));
+
+/* modutils uses these exported symbols to figure out if
+   kallsyms support is present */
+
+EXPORT_SYMBOL(__start___kallsyms);
+EXPORT_SYMBOL(__stop___kallsyms);
 
 struct module kernel_module =
 {
@@ -1220,6 +1227,30 @@
 	.show	= s_show
 };
 
+#define MODLIST_SIZE 4096
+
+/*
+ * this function isn't smp safe but that's not really a problem; it's
+ * called from oops context only and any locking could actually prevent
+ * the oops from going out; the line that is generated is informational
+ * only and should NEVER prevent the real oops from going out. 
+ */
+void print_modules(void)
+{
+	static char modlist[MODLIST_SIZE];
+	struct module *this_mod;
+	int pos = 0;
+
+	this_mod = module_list;
+	while (this_mod) {
+		if (this_mod->name)
+			pos += snprintf(modlist+pos, MODLIST_SIZE-pos-1, 
+					"%s ", this_mod->name);
+		this_mod = this_mod->next;
+	}
+	printk("%s\n",modlist);
+}
+
 #else		/* CONFIG_MODULES */
 
 /* Dummy syscalls for people who don't want modules */
@@ -1265,4 +1296,81 @@
 	return 1;
 }
 
+void print_modules(void)
+{
+}
+
 #endif	/* CONFIG_MODULES */
+
+
+#if defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS)
+
+#define MAX_SYMBOL_SIZE 512
+
+static void
+address_to_exported_symbol(unsigned long address, const char **mod_name, 
+			   const char **sym_name, unsigned long *sym_start,
+			   unsigned long *sym_end)
+{
+	struct module *this_mod;
+	int i;
+
+	for (this_mod = module_list; this_mod; this_mod = this_mod->next) {
+		/* walk the symbol list of this module. Only symbols
+		   who's address is smaller than the searched for address
+		   are relevant; and only if it's better than the best so far */
+		for (i = 0; i < this_mod->nsyms; i++)
+			if ((this_mod->syms[i].value <= address) &&
+			    (*sym_start < this_mod->syms[i].value)) {
+				*sym_start = this_mod->syms[i].value;
+				*sym_name  = this_mod->syms[i].name;
+				*mod_name  = this_mod->name;
+				if (i + 1 < this_mod->nsyms)
+					*sym_end = this_mod->syms[i+1].value;
+				else
+					*sym_end = (unsigned long) this_mod + this_mod->size;
+			}
+	}
+}
+
+void
+print_symbol(const char *fmt, unsigned long address)
+{
+	/* static to not take up stackspace; if we race here too bad */
+	static char buffer[MAX_SYMBOL_SIZE];
+
+	const char *mod_name = NULL, *sec_name = NULL, *sym_name = NULL;
+	unsigned long mod_start, mod_end, sec_start, sec_end,
+		sym_start, sym_end;
+	char *tag = "";
+	
+	memset(buffer, 0, MAX_SYMBOL_SIZE);
+
+	sym_start = 0;
+	if (!kallsyms_address_to_symbol(address, &mod_name, &mod_start, &mod_end, &sec_name, &sec_start, &sec_end, &sym_name, &sym_start, &sym_end)) {
+		tag = "E ";
+		address_to_exported_symbol(address, &mod_name, &sym_name, &sym_start, &sym_end);
+	}
+
+	if (sym_start) {
+		if (*mod_name)
+		    snprintf(buffer, MAX_SYMBOL_SIZE - 1, "%s%s+%#x/%#x [%s]",
+			 tag, sym_name,
+			 (unsigned int)(address - sym_start),
+			 (unsigned int)(sym_end - sym_start),
+			 mod_name);
+		else
+		    snprintf(buffer, MAX_SYMBOL_SIZE - 1, "%s%s+%#x/%#x",
+			 tag, sym_name,
+			 (unsigned int)(address - sym_start),
+			 (unsigned int)(sym_end - sym_start));
+		printk(fmt, buffer);
+	}
+#if 0
+ else {
+		printk(fmt, "[unresolved]");
+	}
+#endif
+}
+
+#endif
diff -Nru a/kernel/pid.c b/kernel/pid.c
--- a/kernel/pid.c	Fri Sep 27 14:51:04 2002
+++ b/kernel/pid.c	Fri Sep 27 14:51:04 2002
@@ -53,6 +53,8 @@
 
 static pidmap_t *map_limit = pidmap_array + PIDMAP_ENTRIES;
 
+static spinlock_t pidmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+
 inline void free_pidmap(int pid)
 {
 	pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE;
@@ -77,8 +79,13 @@
 			 * Free the page if someone raced with us
 			 * installing it:
 			 */
-			if (cmpxchg(&map->page, NULL, (void *) page))
+			spin_lock(&pidmap_lock);
+			if (map->page)
 				free_page(page);
+			else
+				map->page = (void *)page;
+			spin_unlock(&pidmap_lock);
+
 			if (!map->page)
 				break;
 		}
@@ -142,7 +149,7 @@
 	struct list_head *elem, *bucket = &pid_hash[type][pid_hashfn(nr)];
 	struct pid *pid;
 
-	list_for_each_noprefetch(elem, bucket) {
+	__list_for_each(elem, bucket) {
 		pid = list_entry(elem, struct pid, hash_chain);
 		if (pid->nr == nr)
 			return pid;
@@ -150,6 +157,13 @@
 	return NULL;
 }
 
+void link_pid(task_t *task, struct pid_link *link, struct pid *pid)
+{
+	atomic_inc(&pid->count);
+	list_add_tail(&link->pid_chain, &pid->task_list);
+	link->pidptr = pid;
+}
+
 int attach_pid(task_t *task, enum pid_type type, int nr)
 {
 	struct pid *pid = find_pid(type, nr);
@@ -165,13 +179,13 @@
 		get_task_struct(task);
 		list_add(&pid->hash_chain, &pid_hash[type][pid_hashfn(nr)]);
 	}
-	list_add(&task->pids[type].pid_chain, &pid->task_list);
+	list_add_tail(&task->pids[type].pid_chain, &pid->task_list);
 	task->pids[type].pidptr = pid;
 
 	return 0;
 }
 
-void detach_pid(task_t *task, enum pid_type type)
+static inline int __detach_pid(task_t *task, enum pid_type type)
 {
 	struct pid_link *link = task->pids + type;
 	struct pid *pid = link->pidptr;
@@ -179,25 +193,69 @@
 
 	list_del(&link->pid_chain);
 	if (!atomic_dec_and_test(&pid->count))
-		return;
+		return 0;
 
 	nr = pid->nr;
 	list_del(&pid->hash_chain);
 	put_task_struct(pid->task);
 
+	return nr;
+}
+
+static void _detach_pid(task_t *task, enum pid_type type)
+{
+	__detach_pid(task, type);
+}
+
+void detach_pid(task_t *task, enum pid_type type)
+{
+	int nr = __detach_pid(task, type);
+
+	if (!nr)
+		return;
+
 	for (type = 0; type < PIDTYPE_MAX; ++type)
 		if (find_pid(type, nr))
 			return;
 	free_pidmap(nr);
 }
 
-extern task_t *find_task_by_pid(int nr)
+task_t *find_task_by_pid(int nr)
 {
 	struct pid *pid = find_pid(PIDTYPE_PID, nr);
 
 	if (!pid)
 		return NULL;
 	return pid_task(pid->task_list.next, PIDTYPE_PID);
+}
+
+/*
+ * This function switches the PIDs if a non-leader thread calls
+ * sys_execve() - this must be done without releasing the PID.
+ * (which a detach_pid() would eventually do.)
+ */
+void switch_exec_pids(task_t *leader, task_t *thread)
+{
+	_detach_pid(leader, PIDTYPE_PID);
+	_detach_pid(leader, PIDTYPE_TGID);
+	_detach_pid(leader, PIDTYPE_PGID);
+	_detach_pid(leader, PIDTYPE_SID);
+
+	_detach_pid(thread, PIDTYPE_PID);
+	_detach_pid(thread, PIDTYPE_TGID);
+
+	leader->pid = leader->tgid = thread->pid;
+	thread->pid = thread->tgid;
+
+	attach_pid(thread, PIDTYPE_PID, thread->pid);
+	attach_pid(thread, PIDTYPE_TGID, thread->tgid);
+	attach_pid(thread, PIDTYPE_PGID, thread->pgrp);
+	attach_pid(thread, PIDTYPE_SID, thread->session);
+
+	attach_pid(leader, PIDTYPE_PID, leader->pid);
+	attach_pid(leader, PIDTYPE_TGID, leader->tgid);
+	attach_pid(leader, PIDTYPE_PGID, leader->pgrp);
+	attach_pid(leader, PIDTYPE_SID, leader->session);
 }
 
 void __init pidhash_init(void)
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Fri Sep 27 14:51:05 2002
+++ b/kernel/sched.c	Fri Sep 27 14:51:05 2002
@@ -477,13 +477,15 @@
  */
 void sched_exit(task_t * p)
 {
-	local_irq_disable();
+	unsigned long flags;
+
+	local_irq_save(flags);
 	if (p->first_time_slice) {
 		p->parent->time_slice += p->time_slice;
 		if (unlikely(p->parent->time_slice > MAX_TIMESLICE))
 			p->parent->time_slice = MAX_TIMESLICE;
 	}
-	local_irq_enable();
+	local_irq_restore(flags);
 	/*
 	 * If the child was a (relative-) CPU hog then decrease
 	 * the sleep_avg of the parent as well.
@@ -2150,3 +2152,20 @@
 	enter_lazy_tlb(&init_mm, current, smp_processor_id());
 }
 
+#ifdef CONFIG_DEBUG_KERNEL
+void __might_sleep(char *file, int line)
+{
+#if defined(in_atomic)
+	static unsigned long prev_jiffy;	/* ratelimiting */
+
+	if (in_atomic()) {
+		if (time_before(jiffies, prev_jiffy + HZ))
+			return;
+		prev_jiffy = jiffies;
+		printk("Sleeping function called from illegal"
+				" context at %s:%d\n", file, line);
+		dump_stack();
+	}
+#endif
+}
+#endif
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Fri Sep 27 14:51:04 2002
+++ b/kernel/signal.c	Fri Sep 27 14:51:04 2002
@@ -254,7 +254,6 @@
 {
 	if (tsk == sig->curr_target)
 		sig->curr_target = next_thread(tsk);
-	list_del_init(&tsk->thread_group);
 }
 
 void remove_thread_group(struct task_struct *tsk, struct signal_struct *sig)
@@ -281,15 +280,13 @@
 		BUG();
 	spin_lock(&sig->siglock);
 	spin_lock(&tsk->sigmask_lock);
-	tsk->sig = NULL;
 	if (atomic_dec_and_test(&sig->count)) {
 		__remove_thread_group(tsk, sig);
+		tsk->sig = NULL;
 		spin_unlock(&sig->siglock);
 		flush_sigqueue(&sig->shared_pending);
 		kmem_cache_free(sigact_cachep, sig);
 	} else {
-		struct task_struct *leader = tsk->group_leader;
-
 		/*
 		 * If there is any task waiting for the group exit
 		 * then notify it:
@@ -298,24 +295,9 @@
 			wake_up_process(sig->group_exit_task);
 			sig->group_exit_task = NULL;
 		}
-		/*
-		 * If we are the last non-leader member of the thread
-		 * group, and the leader is zombie, then notify the
-		 * group leader's parent process.
-		 *
-		 * (subtle: here we also rely on the fact that if we are the
-		 *  thread group leader then we are not zombied yet.)
-		 */
-		if (atomic_read(&sig->count) == 1 &&
-					leader->state == TASK_ZOMBIE) {
-
-			__remove_thread_group(tsk, sig);
-			spin_unlock(&sig->siglock);
-			do_notify_parent(leader, leader->exit_signal);
-		} else {
-			__remove_thread_group(tsk, sig);
-			spin_unlock(&sig->siglock);
-		}
+		__remove_thread_group(tsk, sig);
+		tsk->sig = NULL;
+		spin_unlock(&sig->siglock);
 	}
 	clear_tsk_thread_flag(tsk,TIF_SIGPENDING);
 	flush_sigqueue(&tsk->pending);
@@ -853,7 +835,7 @@
 		p->sig->curr_target = p;
 
 	else for (;;) {
-		if (list_empty(&p->thread_group))
+		if (thread_group_empty(p))
 			BUG();
 		if (!tmp || tmp->tgid != p->tgid)
 			BUG();
@@ -882,17 +864,13 @@
 int __broadcast_thread_group(struct task_struct *p, int sig)
 {
 	struct task_struct *tmp;
-	struct list_head *entry;
+	struct list_head *l;
+	struct pid *pid;
 	int err = 0;
 
-	/* send a signal to the head of the list */
-	err = __force_sig_info(sig, p);
-
-	/* send a signal to all members of the list */
-	list_for_each(entry, &p->thread_group) {
-		tmp = list_entry(entry, task_t, thread_group);
+	for_each_task_pid(p->tgid, PIDTYPE_TGID, tmp, l, pid)
 		err = __force_sig_info(sig, tmp);
-	}
+
 	return err;
 }
 
@@ -909,7 +887,7 @@
 	spin_lock_irqsave(&p->sig->siglock, flags);
 
 	/* not a thread group - normal signal behavior */
-	if (list_empty(&p->thread_group) || !sig)
+	if (thread_group_empty(p) || !sig)
 		goto out_send;
 
 	if (sig_user_defined(p, sig)) {
@@ -1108,6 +1086,7 @@
  */
 static inline void wake_up_parent(struct task_struct *p)
 {
+	unsigned long flags;
 	struct task_struct *parent = p->parent, *tsk = parent;
 
 	/*
@@ -1117,14 +1096,14 @@
 		wake_up_interruptible(&tsk->wait_chldexit);
 		return;
 	}
-	spin_lock_irq(&parent->sig->siglock);
+	spin_lock_irqsave(&parent->sig->siglock, flags);
 	do {
 		wake_up_interruptible(&tsk->wait_chldexit);
 		tsk = next_thread(tsk);
 		if (tsk->sig != parent->sig)
 			BUG();
 	} while (tsk != parent);
-	spin_unlock_irq(&parent->sig->siglock);
+	spin_unlock_irqrestore(&parent->sig->siglock, flags);
 }
 
 /*
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Fri Sep 27 14:51:03 2002
+++ b/kernel/suspend.c	Fri Sep 27 14:51:03 2002
@@ -81,7 +81,6 @@
 #define TIMEOUT	(6 * HZ)			/* Timeout for stopping processes */
 #define ADDRESS(x) ((unsigned long) phys_to_virt(((x) << PAGE_SHIFT)))
 
-extern void wakeup_bdflush(void);
 extern int C_A_D;
 
 /* References to section boundaries */
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Fri Sep 27 14:51:03 2002
+++ b/kernel/timer.c	Fri Sep 27 14:51:03 2002
@@ -888,20 +888,6 @@
 	if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
 		return -EINVAL;
 
-
-	if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
-	    current->policy != SCHED_NORMAL)
-	{
-		/*
-		 * Short delay requests up to 2 ms will be handled with
-		 * high precision by a busy wait for all real-time processes.
-		 *
-		 * Its important on SMP not to do this holding locks.
-		 */
-		udelay((t.tv_nsec + 999) / 1000);
-		return 0;
-	}
-
 	expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
 
 	current->state = TASK_INTERRUPTIBLE;
diff -Nru a/mm/Makefile b/mm/Makefile
--- a/mm/Makefile	Fri Sep 27 14:51:04 2002
+++ b/mm/Makefile	Fri Sep 27 14:51:04 2002
@@ -9,6 +9,6 @@
 	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
 	    page_alloc.o swap_state.o swapfile.o numa.o oom_kill.o \
 	    shmem.o highmem.o mempool.o msync.o mincore.o readahead.o \
-	    pdflush.o page-writeback.o rmap.o madvise.o
+	    pdflush.o page-writeback.o rmap.o madvise.o vcache.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Fri Sep 27 14:51:04 2002
+++ b/mm/filemap.c	Fri Sep 27 14:51:04 2002
@@ -60,8 +60,8 @@
  *      ->swap_list_lock
  *        ->swap_device_lock	(exclusive_swap_page, others)
  *          ->mapping->page_lock
- *      ->inode_lock		(__mark_inode_dirty)
- *        ->sb_lock		(fs/fs-writeback.c)
+ *  ->inode_lock
+ *    ->sb_lock			(fs/fs-writeback.c)
  */
 
 /*
@@ -632,19 +632,15 @@
 void wait_on_page_bit(struct page *page, int bit_nr)
 {
 	wait_queue_head_t *waitqueue = page_waitqueue(page);
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
+	DEFINE_WAIT(wait);
 
-	add_wait_queue(waitqueue, &wait);
 	do {
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (!test_bit(bit_nr, &page->flags))
-			break;
+		prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
 		sync_page(page);
-		schedule();
+		if (test_bit(bit_nr, &page->flags))
+			schedule();
 	} while (test_bit(bit_nr, &page->flags));
-	__set_task_state(tsk, TASK_RUNNING);
-	remove_wait_queue(waitqueue, &wait);
+	finish_wait(waitqueue, &wait);
 }
 EXPORT_SYMBOL(wait_on_page_bit);
 
@@ -690,38 +686,27 @@
 EXPORT_SYMBOL(end_page_writeback);
 
 /*
- * Get a lock on the page, assuming we need to sleep
- * to get it..
+ * Get a lock on the page, assuming we need to sleep to get it.
+ *
+ * Ugly: running sync_page() in state TASK_UNINTERRUPTIBLE is scary.  If some
+ * random driver's requestfn sets TASK_RUNNING, we could busywait.  However
+ * chances are that on the second loop, the block layer's plug list is empty,
+ * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
  */
-static void __lock_page(struct page *page)
+void __lock_page(struct page *page)
 {
-	wait_queue_head_t *waitqueue = page_waitqueue(page);
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
+	wait_queue_head_t *wqh = page_waitqueue(page);
+	DEFINE_WAIT(wait);
 
-	add_wait_queue_exclusive(waitqueue, &wait);
-	for (;;) {
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (PageLocked(page)) {
-			sync_page(page);
+	while (TestSetPageLocked(page)) {
+		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
+		sync_page(page);
+		if (PageLocked(page))
 			schedule();
-		}
-		if (!TestSetPageLocked(page))
-			break;
 	}
-	__set_task_state(tsk, TASK_RUNNING);
-	remove_wait_queue(waitqueue, &wait);
-}
-
-/*
- * Get an exclusive lock on the page, optimistically
- * assuming it's not locked..
- */
-void lock_page(struct page *page)
-{
-	if (TestSetPageLocked(page))
-		__lock_page(page);
+	finish_wait(wqh, &wait);
 }
+EXPORT_SYMBOL(__lock_page);
 
 /*
  * a rather lightweight function, finding and getting a reference to a
@@ -1643,7 +1628,7 @@
 
 static inline int
 __filemap_copy_from_user_iovec(char *vaddr, 
-			const struct iovec *iov, size_t base, unsigned bytes)
+			const struct iovec *iov, size_t base, size_t bytes)
 {
 	int left = 0;
 
@@ -1662,7 +1647,7 @@
 
 static inline int
 filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
-			const struct iovec *iov, size_t base, unsigned bytes)
+			const struct iovec *iov, size_t base, size_t bytes)
 {
 	char *kaddr;
 	int left;
@@ -1679,7 +1664,7 @@
 }
 
 static inline void
-filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, unsigned bytes)
+filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
 {
 	const struct iovec *iov = *iovp;
 	size_t base = *basep;
@@ -1723,11 +1708,11 @@
 	struct page	*cached_page = NULL;
 	ssize_t		written;
 	int		err;
-	unsigned	bytes;
+	size_t		bytes;
 	time_t		time_now;
 	struct pagevec	lru_pvec;
 	const struct iovec *cur_iov = iov; /* current iovec */
-	unsigned	iov_base = 0;	   /* offset in the current iovec */
+	size_t		iov_base = 0;	   /* offset in the current iovec */
 	unsigned long	seg;
 	char		*buf;
 
@@ -1755,6 +1740,9 @@
 	if (unlikely(pos < 0))
 		return -EINVAL;
 
+	/* We can write back this queue in page reclaim */
+	current->backing_dev_info = mapping->backing_dev_info;
+
 	pagevec_init(&lru_pvec);
 
 	if (unlikely(file->f_error)) {
@@ -1959,6 +1947,7 @@
 	err = written ? written : status;
 out:
 	pagevec_lru_add(&lru_pvec);
+	current->backing_dev_info = 0;
 	return err;
 }
 
diff -Nru a/mm/highmem.c b/mm/highmem.c
--- a/mm/highmem.c	Fri Sep 27 14:51:04 2002
+++ b/mm/highmem.c	Fri Sep 27 14:51:04 2002
@@ -472,6 +472,7 @@
 {
 	int idx, type;
 
+	preempt_disable();
 	for (type = 0; type < KM_TYPE_NR; type++) {
 		idx = type + KM_TYPE_NR*smp_processor_id();
 		if (!pte_none(*(kmap_pte-idx))) {
@@ -479,6 +480,7 @@
 			BUG();
 		}
 	}
+	preempt_enable();
 }
 #endif
 
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Fri Sep 27 14:51:04 2002
+++ b/mm/memory.c	Fri Sep 27 14:51:04 2002
@@ -43,6 +43,7 @@
 #include <linux/iobuf.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
+#include <linux/vcache.h>
 
 #include <asm/pgalloc.h>
 #include <asm/rmap.h>
@@ -463,7 +464,7 @@
  * Do a quick page-table lookup for a single page.
  * mm->page_table_lock must be held.
  */
-static inline struct page *
+struct page *
 follow_page(struct mm_struct *mm, unsigned long address, int write) 
 {
 	pgd_t *pgd;
@@ -494,7 +495,7 @@
 	}
 
 out:
-	return 0;
+	return NULL;
 }
 
 /* 
@@ -973,6 +974,7 @@
 static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address, 
 		pte_t *page_table)
 {
+	invalidate_vcache(address, vma->vm_mm, new_page);
 	flush_page_to_ram(new_page);
 	flush_cache_page(vma, address);
 	establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
diff -Nru a/mm/mempool.c b/mm/mempool.c
--- a/mm/mempool.c	Fri Sep 27 14:51:04 2002
+++ b/mm/mempool.c	Fri Sep 27 14:51:04 2002
@@ -12,7 +12,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mempool.h>
-#include <linux/buffer_head.h>		/* for wakeup_bdflush() */
+#include <linux/writeback.h>
 
 static void add_element(mempool_t *pool, void *element)
 {
@@ -210,7 +210,7 @@
 	/*
 	 * Kick the VM at this point.
 	 */
-	wakeup_bdflush();
+	wakeup_bdflush(0);
 
 	spin_lock_irqsave(&pool->lock, flags);
 	if (likely(pool->curr_nr)) {
diff -Nru a/mm/mprotect.c b/mm/mprotect.c
--- a/mm/mprotect.c	Fri Sep 27 14:51:04 2002
+++ b/mm/mprotect.c	Fri Sep 27 14:51:04 2002
@@ -187,12 +187,17 @@
 		 * Try to merge with the previous vma.
 		 */
 		if (mprotect_attempt_merge(vma, *pprev, end, newflags))
-			return 0;
+			goto success;
 	} else {
 		error = split_vma(mm, vma, start, 1);
 		if (error)
 			goto fail;
 	}
+	/*
+	 * Unless it returns an error, this function always sets *pprev to
+	 * the first vma for which vma->vm_end >= end.
+	 */
+	*pprev = vma;
 
 	if (end != vma->vm_end) {
 		error = split_vma(mm, vma, end, 0);
@@ -204,7 +209,7 @@
 	vma->vm_flags = newflags;
 	vma->vm_page_prot = newprot;
 	spin_unlock(&mm->page_table_lock);
-
+success:
 	change_protection(vma, start, end, newprot);
 	return 0;
 
diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c
--- a/mm/page-writeback.c	Fri Sep 27 14:51:04 2002
+++ b/mm/page-writeback.c	Fri Sep 27 14:51:04 2002
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/sysrq.h>
 #include <linux/backing-dev.h>
+#include <linux/blkdev.h>
 #include <linux/mpage.h>
 #include <linux/notifier.h>
 #include <linux/smp.h>
@@ -172,33 +173,47 @@
 		.sync_mode	= WB_SYNC_NONE,
 		.older_than_this = NULL,
 		.nr_to_write	= 0,
+		.nonblocking	= 1,
 	};
 
 	CHECK_EMERGENCY_SYNC
 
 	background_thresh = (dirty_background_ratio * total_pages) / 100;
-
-	do {
+	for ( ; ; ) {
 		struct page_state ps;
+
 		get_page_state(&ps);
 		if (ps.nr_dirty < background_thresh && min_pages <= 0)
 			break;
+		wbc.encountered_congestion = 0;
 		wbc.nr_to_write = MAX_WRITEBACK_PAGES;
 		writeback_inodes(&wbc);
 		min_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
-	} while (wbc.nr_to_write <= 0);
+		if (wbc.nr_to_write == MAX_WRITEBACK_PAGES) {
+			/* Wrote nothing */
+			if (wbc.encountered_congestion)
+				blk_congestion_wait(WRITE, HZ/10);
+			else
+				break;
+		}
+	}
 	blk_run_queues();
 }
 
 /*
- * Start heavy writeback of everything.
+ * Start writeback of `nr_pages' pages.  If `nr_pages' is zero, write back
+ * the whole world.  Returns 0 if a pdflush thread was dispatched.  Returns
+ * -1 if all pdflush threads were busy.
  */
-void wakeup_bdflush(void)
+int wakeup_bdflush(long nr_pages)
 {
-	struct page_state ps;
+	if (nr_pages == 0) {
+		struct page_state ps;
 
-	get_page_state(&ps);
-	pdflush_operation(background_writeout, ps.nr_dirty);
+		get_page_state(&ps);
+		nr_pages = ps.nr_dirty;
+	}
+	return pdflush_operation(background_writeout, nr_pages);
 }
 
 static struct timer_list wb_timer;
@@ -223,25 +238,36 @@
 	unsigned long oldest_jif;
 	unsigned long start_jif;
 	unsigned long next_jif;
+	long nr_to_write;
 	struct page_state ps;
 	struct writeback_control wbc = {
 		.bdi		= NULL,
 		.sync_mode	= WB_SYNC_NONE,
 		.older_than_this = &oldest_jif,
 		.nr_to_write	= 0,
+		.nonblocking	= 1,
 	};
 
 	sync_supers();
-	get_page_state(&ps);
 
+	get_page_state(&ps);
 	oldest_jif = jiffies - (dirty_expire_centisecs * HZ) / 100;
 	start_jif = jiffies;
 	next_jif = start_jif + (dirty_writeback_centisecs * HZ) / 100;
-	wbc.nr_to_write = ps.nr_dirty;
-	writeback_inodes(&wbc);
+	nr_to_write = ps.nr_dirty;
+	while (nr_to_write > 0) {
+		wbc.encountered_congestion = 0;
+		wbc.nr_to_write = MAX_WRITEBACK_PAGES;
+		writeback_inodes(&wbc);
+		if (wbc.nr_to_write == MAX_WRITEBACK_PAGES) {
+			if (wbc.encountered_congestion)
+				blk_congestion_wait(WRITE, HZ);
+			else
+				break;	/* All the old data is written */
+		}
+		nr_to_write -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
+	}
 	blk_run_queues();
-	yield();
-
 	if (time_before(next_jif, jiffies + HZ))
 		next_jif = jiffies + HZ;
 	mod_timer(&wb_timer, next_jif);
@@ -493,7 +519,6 @@
 		buffer_error();
 
 	spin_lock(&mapping->private_lock);
-
 	if (page_has_buffers(page)) {
 		struct buffer_head *head = page_buffers(page);
 		struct buffer_head *bh = head;
@@ -506,6 +531,7 @@
 			bh = bh->b_this_page;
 		} while (bh != head);
 	}
+	spin_unlock(&mapping->private_lock);
 
 	if (!TestSetPageDirty(page)) {
 		write_lock(&mapping->page_lock);
@@ -519,7 +545,6 @@
 		__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
 	}
 	
-	spin_unlock(&mapping->private_lock);
 out:
 	return ret;
 }
@@ -576,3 +601,4 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(test_clear_page_dirty);
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	Fri Sep 27 14:51:03 2002
+++ b/mm/page_alloc.c	Fri Sep 27 14:51:03 2002
@@ -321,6 +321,9 @@
 	struct page * page;
 	int freed, i;
 
+	if (gfp_mask & __GFP_WAIT)
+		might_sleep();
+
 	KERNEL_STAT_ADD(pgalloc, 1<<order);
 
 	zones = zonelist->zones;  /* the list of zones suitable for gfp_mask */
@@ -477,6 +480,17 @@
 		sum += zone->free_pages;
 
 	return sum;
+}
+
+unsigned int nr_used_zone_pages(void)
+{
+	unsigned int pages = 0;
+	struct zone *zone;
+
+	for_each_zone(zone)
+		pages += zone->nr_active + zone->nr_inactive;
+
+	return pages;
 }
 
 static unsigned int nr_free_zone_pages(int offset)
diff -Nru a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c	Fri Sep 27 14:51:05 2002
+++ b/mm/pdflush.c	Fri Sep 27 14:51:05 2002
@@ -79,9 +79,9 @@
  */
 struct pdflush_work {
 	struct task_struct *who;	/* The thread */
-	void (*fn)(unsigned long);	/* A callback function for pdflush to work on */
-	unsigned long arg0;		/* An argument to the callback function */
-	struct list_head list;		/* On pdflush_list, when the thread is idle */
+	void (*fn)(unsigned long);	/* A callback function */
+	unsigned long arg0;		/* An argument to the callback */
+	struct list_head list;		/* On pdflush_list, when idle */
 	unsigned long when_i_went_to_sleep;
 };
 
@@ -99,24 +99,35 @@
 	current->flags |= PF_FLUSHER;
 	my_work->fn = NULL;
 	my_work->who = current;
+	INIT_LIST_HEAD(&my_work->list);
 
 	spin_lock_irq(&pdflush_lock);
 	nr_pdflush_threads++;
-//	printk("pdflush %d [%d] starts\n", nr_pdflush_threads, current->pid);
 	for ( ; ; ) {
 		struct pdflush_work *pdf;
 
-		list_add(&my_work->list, &pdflush_list);
-		my_work->when_i_went_to_sleep = jiffies;
 		set_current_state(TASK_INTERRUPTIBLE);
+		list_move(&my_work->list, &pdflush_list);
+		my_work->when_i_went_to_sleep = jiffies;
 		spin_unlock_irq(&pdflush_lock);
 
 		if (current->flags & PF_FREEZE)
 			refrigerator(PF_IOTHREAD);
 		schedule();
 
-		if (my_work->fn)
-			(*my_work->fn)(my_work->arg0);
+		spin_lock_irq(&pdflush_lock);
+		if (!list_empty(&my_work->list)) {
+			printk("pdflush: bogus wakeup!\n");
+			my_work->fn = NULL;
+			continue;
+		}
+		if (my_work->fn == NULL) {
+			printk("pdflush: NULL work function\n");
+			continue;
+		}
+		spin_unlock_irq(&pdflush_lock);
+
+		(*my_work->fn)(my_work->arg0);
 
 		/*
 		 * Thread creation: For how long have there been zero
@@ -132,6 +143,7 @@
 		}
 
 		spin_lock_irq(&pdflush_lock);
+		my_work->fn = NULL;
 
 		/*
 		 * Thread destruction: For how long has the sleepiest
@@ -143,13 +155,12 @@
 			continue;
 		pdf = list_entry(pdflush_list.prev, struct pdflush_work, list);
 		if (jiffies - pdf->when_i_went_to_sleep > 1 * HZ) {
-			pdf->when_i_went_to_sleep = jiffies;	/* Limit exit rate */
+			/* Limit exit rate */
+			pdf->when_i_went_to_sleep = jiffies;
 			break;					/* exeunt */
 		}
-		my_work->fn = NULL;
 	}
 	nr_pdflush_threads--;
-//	printk("pdflush %d [%d] ends\n", nr_pdflush_threads, current->pid);
 	spin_unlock_irq(&pdflush_lock);
 	return 0;
 }
@@ -191,11 +202,10 @@
 		list_del_init(&pdf->list);
 		if (list_empty(&pdflush_list))
 			last_empty_jifs = jiffies;
-		spin_unlock_irqrestore(&pdflush_lock, flags);
 		pdf->fn = fn;
 		pdf->arg0 = arg0;
-		wmb();			/* ? */
 		wake_up_process(pdf->who);
+		spin_unlock_irqrestore(&pdflush_lock, flags);
 	}
 	return ret;
 }
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	Fri Sep 27 14:51:05 2002
+++ b/mm/slab.c	Fri Sep 27 14:51:05 2002
@@ -1357,11 +1357,7 @@
 		cc_entry(cc)[cc->avail++] =
 				kmem_cache_alloc_one_tail(cachep, slabp);
 	}
-	/*
-	 * CAREFUL: do not enable preemption yet, the per-CPU
-	 * entries rely on us being atomic.
-	 */
-	_raw_spin_unlock(&cachep->spinlock);
+	spin_unlock(&cachep->spinlock);
 
 	if (cc->avail)
 		return cc_entry(cc)[--cc->avail];
@@ -1374,6 +1370,9 @@
 	unsigned long save_flags;
 	void* objp;
 
+	if (flags & __GFP_WAIT)
+		might_sleep();
+
 	kmem_cache_alloc_head(cachep, flags);
 try_again:
 	local_irq_save(save_flags);
@@ -1389,8 +1388,6 @@
 				STATS_INC_ALLOCMISS(cachep);
 				objp = kmem_cache_alloc_batch(cachep,flags);
 				local_irq_restore(save_flags);
-				/* end of non-preemptible region */
-				preempt_enable();
 				if (!objp)
 					goto alloc_new_slab_nolock;
 				return objp;
@@ -1502,7 +1499,11 @@
 		if (unlikely(!--slabp->inuse)) {
 			/* Was partial or full, now empty. */
 			list_del(&slabp->list);
-			list_add(&slabp->list, &cachep->slabs_free);
+/*			list_add(&slabp->list, &cachep->slabs_free); 		*/
+			if (unlikely(list_empty(&cachep->slabs_partial)))
+				list_add(&slabp->list, &cachep->slabs_partial);
+			else
+				kmem_slab_destroy(cachep, slabp);
 		} else if (unlikely(inuse == cachep->num)) {
 			/* Was full. */
 			list_del(&slabp->list);
@@ -1976,7 +1977,7 @@
 	}
 	list_for_each(q,&cachep->slabs_partial) {
 		slabp = list_entry(q, slab_t, list);
-		if (slabp->inuse == cachep->num || !slabp->inuse)
+		if (slabp->inuse == cachep->num)
 			BUG();
 		active_objs += slabp->inuse;
 		active_slabs++;
diff -Nru a/mm/swapfile.c b/mm/swapfile.c
--- a/mm/swapfile.c	Fri Sep 27 14:51:03 2002
+++ b/mm/swapfile.c	Fri Sep 27 14:51:03 2002
@@ -918,6 +918,26 @@
 	return ret;
 }
 
+#if 0	/* We don't need this yet */
+#include <linux/backing-dev.h>
+int page_queue_congested(struct page *page)
+{
+	struct backing_dev_info *bdi;
+
+	BUG_ON(!PageLocked(page));	/* It pins the swap_info_struct */
+
+	bdi = page->mapping->backing_dev_info;
+	if (PageSwapCache(page)) {
+		swp_entry_t entry = { .val = page->index };
+		struct swap_info_struct *sis;
+
+		sis = get_swap_info_struct(swp_type(entry));
+		bdi = sis->bdev->bd_inode->i_mapping->backing_dev_info;
+	}
+	return bdi_write_congested(bdi);
+}
+#endif
+
 asmlinkage long sys_swapoff(const char * specialfile)
 {
 	struct swap_info_struct * p = NULL;
diff -Nru a/mm/vcache.c b/mm/vcache.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/mm/vcache.c	Fri Sep 27 14:51:05 2002
@@ -0,0 +1,93 @@
+/*
+ *  linux/mm/vcache.c
+ *
+ *  virtual => physical page mapping cache. Users of this mechanism
+ *  register callbacks for a given (virt,mm,phys) page mapping, and
+ *  the kernel guarantees to call back when this mapping is invalidated.
+ *  (ie. upon COW or unmap.)
+ *
+ *  Started by Ingo Molnar, Copyright (C) 2002
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/hash.h>
+#include <linux/vcache.h>
+
+#define VCACHE_HASHBITS 8
+#define VCACHE_HASHSIZE (1 << VCACHE_HASHBITS)
+
+spinlock_t vcache_lock = SPIN_LOCK_UNLOCKED;
+
+static struct list_head hash[VCACHE_HASHSIZE];
+
+static struct list_head *hash_vcache(unsigned long address,
+					struct mm_struct *mm)
+{
+        return &hash[hash_long(address + (unsigned long)mm, VCACHE_HASHBITS)];
+}
+
+void __attach_vcache(vcache_t *vcache,
+		unsigned long address,
+		struct mm_struct *mm,
+		void (*callback)(struct vcache_s *data, struct page *new))
+{
+	struct list_head *hash_head;
+
+	address &= PAGE_MASK;
+	vcache->address = address;
+	vcache->mm = mm;
+	vcache->callback = callback;
+
+	hash_head = hash_vcache(address, mm);
+
+	list_add(&vcache->hash_entry, hash_head);
+}
+
+void detach_vcache(vcache_t *vcache)
+{
+	spin_lock(&vcache_lock);
+	list_del(&vcache->hash_entry);
+	spin_unlock(&vcache_lock);
+}
+
+void invalidate_vcache(unsigned long address, struct mm_struct *mm,
+				struct page *new_page)
+{
+	struct list_head *l, *hash_head;
+	vcache_t *vcache;
+
+	address &= PAGE_MASK;
+
+	hash_head = hash_vcache(address, mm);
+	/*
+	 * This is safe, because this path is called with the mm
+	 * semaphore read-held, and the add/remove path calls with the
+	 * mm semaphore write-held. So while other mm's might add new
+	 * entries in parallel, and *this* mm is locked out, so if the
+	 * list is empty now then we do not have to take the vcache
+	 * lock to see it's really empty.
+	 */
+	if (likely(list_empty(hash_head)))
+		return;
+
+	spin_lock(&vcache_lock);
+	list_for_each(l, hash_head) {
+		vcache = list_entry(l, vcache_t, hash_entry);
+		if (vcache->address != address || vcache->mm != mm)
+			continue;
+		vcache->callback(vcache, new_page);
+	}
+	spin_unlock(&vcache_lock);
+}
+
+static int __init vcache_init(void)
+{
+        unsigned int i;
+
+	for (i = 0; i < VCACHE_HASHSIZE; i++)
+		INIT_LIST_HEAD(hash + i);
+	return 0;
+}
+__initcall(vcache_init);
+
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	Fri Sep 27 14:51:03 2002
+++ b/mm/vmscan.c	Fri Sep 27 14:51:03 2002
@@ -21,9 +21,11 @@
 #include <linux/file.h>
 #include <linux/writeback.h>
 #include <linux/suspend.h>
+#include <linux/blkdev.h>
 #include <linux/buffer_head.h>		/* for try_to_release_page() */
 #include <linux/mm_inline.h>
 #include <linux/pagevec.h>
+#include <linux/backing-dev.h>
 #include <linux/rmap-locking.h>
 
 #include <asm/pgalloc.h>
@@ -32,11 +34,11 @@
 
 /*
  * The "priority" of VM scanning is how much of the queues we
- * will scan in one go. A value of 6 for DEF_PRIORITY implies
- * that we'll scan 1/64th of the queues ("queue_length >> 6")
+ * will scan in one go. A value of 12 for DEF_PRIORITY implies
+ * that we'll scan 1/4096th of the queues ("queue_length >> 12")
  * during a normal aging round.
  */
-#define DEF_PRIORITY (6)
+#define DEF_PRIORITY 12
 
 #ifdef ARCH_HAS_PREFETCH
 #define prefetch_prev_lru_page(_page, _base, _field)			\
@@ -68,6 +70,10 @@
 #define prefetchw_prev_lru_page(_page, _base, _field) do { } while (0)
 #endif
 
+#ifndef CONFIG_QUOTA
+#define shrink_dqcache_memory(ratio, gfp_mask) do { } while (0)
+#endif
+
 /* Must be called with page's pte_chain_lock held. */
 static inline int page_mapping_inuse(struct page * page)
 {
@@ -95,7 +101,7 @@
 
 static /* inline */ int
 shrink_list(struct list_head *page_list, int nr_pages,
-		unsigned int gfp_mask, int priority, int *max_scan)
+		unsigned int gfp_mask, int *max_scan, int *nr_mapped)
 {
 	struct address_space *mapping;
 	LIST_HEAD(ret_pages);
@@ -114,14 +120,29 @@
 		if (TestSetPageLocked(page))
 			goto keep;
 
+		/* Double the slab pressure for mapped and swapcache pages */
+		if (page_mapped(page) || PageSwapCache(page))
+			(*nr_mapped)++;
+
 		BUG_ON(PageActive(page));
 		may_enter_fs = (gfp_mask & __GFP_FS) ||
 				(PageSwapCache(page) && (gfp_mask & __GFP_IO));
+
+		/*
+		 * If the page is mapped into pagetables then wait on it, to
+		 * throttle this allocator to the rate at which we can clear
+		 * MAP_SHARED data.  This will also throttle against swapcache
+		 * writes.
+		 */
 		if (PageWriteback(page)) {
-			if (may_enter_fs)
-				wait_on_page_writeback(page);  /* throttling */
-			else
-				goto keep_locked;
+			if (may_enter_fs) {
+				if (page->pte.direct ||
+					page->mapping->backing_dev_info ==
+						current->backing_dev_info) {
+					wait_on_page_writeback(page);
+				}
+			}
+			goto keep_locked;
 		}
 
 		pte_chain_lock(page);
@@ -172,15 +193,43 @@
 		 * will write it.  So we're back to page-at-a-time writepage
 		 * in LRU order.
 		 */
-		if (PageDirty(page) && is_page_cache_freeable(page) &&
-					mapping && may_enter_fs) {
+		/*
+		 * If the page is dirty, only perform writeback if that write
+		 * will be non-blocking.  To prevent this allocation from being
+		 * stalled by pagecache activity.  But note that there may be
+		 * stalls if we need to run get_block().  We could test
+		 * PagePrivate for that.
+		 *
+		 * If this process is currently in generic_file_write() against
+		 * this page's queue, we can perform writeback even if that
+		 * will block.
+		 *
+		 * If the page is swapcache, write it back even if that would
+		 * block, for some throttling. This happens by accident, because
+		 * swap_backing_dev_info is bust: it doesn't reflect the
+		 * congestion state of the swapdevs.  Easy to fix, if needed.
+		 * See swapfile.c:page_queue_congested().
+		 */
+		if (PageDirty(page)) {
 			int (*writeback)(struct page *,
 					struct writeback_control *);
+			struct backing_dev_info *bdi;
 			const int cluster_size = SWAP_CLUSTER_MAX;
 			struct writeback_control wbc = {
 				.nr_to_write = cluster_size,
 			};
 
+			if (!is_page_cache_freeable(page))
+				goto keep_locked;
+			if (!mapping)
+				goto keep_locked;
+			if (!may_enter_fs)
+				goto keep_locked;
+			bdi = mapping->backing_dev_info;
+			if (bdi != current->backing_dev_info &&
+					bdi_write_congested(bdi))
+				goto keep_locked;
+
 			writeback = mapping->a_ops->vm_writeback;
 			if (writeback == NULL)
 				writeback = generic_vm_writeback;
@@ -279,7 +328,7 @@
  */
 static /* inline */ int
 shrink_cache(int nr_pages, struct zone *zone,
-		unsigned int gfp_mask, int priority, int max_scan)
+		unsigned int gfp_mask, int max_scan, int *nr_mapped)
 {
 	LIST_HEAD(page_list);
 	struct pagevec pvec;
@@ -298,11 +347,13 @@
 	spin_lock_irq(&zone->lru_lock);
 	while (max_scan > 0 && nr_pages > 0) {
 		struct page *page;
-		int n = 0;
+		int nr_taken = 0;
+		int nr_scan = 0;
 
-		while (n < nr_to_process && !list_empty(&zone->inactive_list)) {
+		while (nr_scan++ < nr_to_process &&
+				!list_empty(&zone->inactive_list)) {
 			page = list_entry(zone->inactive_list.prev,
-					struct page, lru);
+						struct page, lru);
 
 			prefetchw_prev_lru_page(page,
 						&zone->inactive_list, flags);
@@ -318,18 +369,18 @@
 			}
 			list_add(&page->lru, &page_list);
 			page_cache_get(page);
-			n++;
+			nr_taken++;
 		}
-		zone->nr_inactive -= n;
+		zone->nr_inactive -= nr_taken;
 		spin_unlock_irq(&zone->lru_lock);
 
-		if (list_empty(&page_list))
+		if (nr_taken == 0)
 			goto done;
 
-		max_scan -= n;
-		KERNEL_STAT_ADD(pgscan, n);
+		max_scan -= nr_scan;
+		KERNEL_STAT_ADD(pgscan, nr_scan);
 		nr_pages = shrink_list(&page_list, nr_pages,
-					gfp_mask, priority, &max_scan);
+				gfp_mask, &max_scan, nr_mapped);
 
 		if (nr_pages <= 0 && list_empty(&page_list))
 			goto done;
@@ -420,6 +471,15 @@
 			}
 			pte_chain_unlock(page);
 		}
+		/*
+		 * FIXME: need to consider page_count(page) here if/when we
+		 * reap orphaned pages via the LRU (Daniel's locking stuff)
+		 */
+		if (total_swap_pages == 0 && !page->mapping &&
+						!PagePrivate(page)) {
+			list_add(&page->lru, &l_active);
+			continue;
+		}
 		list_add(&page->lru, &l_inactive);
 		pgdeactivate++;
 	}
@@ -470,15 +530,10 @@
 }
 
 static /* inline */ int
-shrink_zone(struct zone *zone, int priority,
-	unsigned int gfp_mask, int nr_pages)
+shrink_zone(struct zone *zone, int max_scan,
+		unsigned int gfp_mask, int nr_pages, int *nr_mapped)
 {
 	unsigned long ratio;
-	int max_scan;
-
-	/* This is bogus for ZONE_HIGHMEM? */
-	if (kmem_cache_reap(gfp_mask) >= nr_pages)
-  		return 0;
 
 	/*
 	 * Try to keep the active list 2/3 of the size of the cache.  And
@@ -497,43 +552,66 @@
 		atomic_sub(SWAP_CLUSTER_MAX, &zone->refill_counter);
 		refill_inactive_zone(zone, SWAP_CLUSTER_MAX);
 	}
-
-	max_scan = zone->nr_inactive / priority;
-	nr_pages = shrink_cache(nr_pages, zone,
-				gfp_mask, priority, max_scan);
-
-	if (nr_pages <= 0)
-		return 0;
-
-	wakeup_bdflush();
-
-	shrink_dcache_memory(priority, gfp_mask);
-
-	/* After shrinking the dcache, get rid of unused inodes too .. */
-	shrink_icache_memory(1, gfp_mask);
-#ifdef CONFIG_QUOTA
-	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
-#endif
-
+	nr_pages = shrink_cache(nr_pages, zone, gfp_mask,
+				max_scan, nr_mapped);
 	return nr_pages;
 }
 
 static int
 shrink_caches(struct zone *classzone, int priority,
-		int gfp_mask, int nr_pages)
+		int *total_scanned, int gfp_mask, int nr_pages)
 {
 	struct zone *first_classzone;
 	struct zone *zone;
+	int ratio;
+	int nr_mapped = 0;
+	int pages = nr_used_zone_pages();
 
 	first_classzone = classzone->zone_pgdat->node_zones;
-	zone = classzone;
-	while (zone >= first_classzone && nr_pages > 0) {
-		if (zone->free_pages <= zone->pages_high) {
-			nr_pages = shrink_zone(zone, priority,
-					gfp_mask, nr_pages);
-		}
-		zone--;
+	for (zone = classzone; zone >= first_classzone; zone--) {
+		int max_scan;
+		int to_reclaim;
+		int unreclaimed;
+
+		to_reclaim = zone->pages_high - zone->free_pages;
+		if (to_reclaim < 0)
+			continue;	/* zone has enough memory */
+
+		if (to_reclaim > SWAP_CLUSTER_MAX)
+			to_reclaim = SWAP_CLUSTER_MAX;
+
+		if (to_reclaim < nr_pages)
+			to_reclaim = nr_pages;
+
+		/*
+		 * If we cannot reclaim `nr_pages' pages by scanning twice
+		 * that many pages then fall back to the next zone.
+		 */
+		max_scan = zone->nr_inactive >> priority;
+		if (max_scan < to_reclaim * 2)
+			max_scan = to_reclaim * 2;
+		unreclaimed = shrink_zone(zone, max_scan,
+				gfp_mask, to_reclaim, &nr_mapped);
+		nr_pages -= to_reclaim - unreclaimed;
+		*total_scanned += max_scan;
 	}
+
+	/*
+	 * Here we assume it costs one seek to replace a lru page and that
+	 * it also takes a seek to recreate a cache object.  With this in
+	 * mind we age equal percentages of the lru and ageable caches.
+	 * This should balance the seeks generated by these structures.
+	 *
+	 * NOTE: for now I do this for all zones.  If we find this is too
+	 * aggressive on large boxes we may want to exclude ZONE_HIGHMEM
+	 *
+	 * If we're encountering mapped pages on the LRU then increase the
+	 * pressure on slab to avoid swapping.
+	 */
+	ratio = (pages / (*total_scanned + nr_mapped + 1)) + 1;
+	shrink_dcache_memory(ratio, gfp_mask);
+	shrink_icache_memory(ratio, gfp_mask);
+	shrink_dqcache_memory(ratio, gfp_mask);
 	return nr_pages;
 }
 
@@ -564,12 +642,25 @@
 	KERNEL_STAT_INC(pageoutrun);
 
 	for (priority = DEF_PRIORITY; priority; priority--) {
-		nr_pages = shrink_caches(classzone, priority,
+		int total_scanned = 0;
+
+		nr_pages = shrink_caches(classzone, priority, &total_scanned,
 					gfp_mask, nr_pages);
 		if (nr_pages <= 0)
 			return 1;
+		if (total_scanned == 0)
+			return 1;	/* All zones had enough free memory */
 		if (!(gfp_mask & __GFP_FS))
-			break;
+			break;		/* Let the caller handle it */
+		/*
+		 * Try to write back as many pages as we just scanned.  Not
+		 * sure if that makes sense, but it's an attempt to avoid
+		 * creating IO storms unnecessarily
+		 */
+		wakeup_bdflush(total_scanned);
+
+		/* Take a nap, wait for some writeback to complete */
+		blk_congestion_wait(WRITE, HZ/4);
 	}
 	if (gfp_mask & __GFP_FS)
 		out_of_memory();
diff -Nru a/net/802/p8022.c b/net/802/p8022.c
--- a/net/802/p8022.c	Fri Sep 27 14:51:03 2002
+++ b/net/802/p8022.c	Fri Sep 27 14:51:03 2002
@@ -33,7 +33,9 @@
 }
 
 struct datalink_proto *register_8022_client(unsigned char type,
-			  int (*indicate)(struct llc_prim_if_block *prim))
+					    int (*func)(struct sk_buff *skb,
+							struct net_device *dev,
+							struct packet_type *pt))
 {
 	struct datalink_proto *proto;
 
@@ -42,7 +44,7 @@
 		proto->type[0]		= type;
 		proto->header_length	= 3;
 		proto->request		= p8022_request;
-		proto->sap = llc_sap_open(indicate, NULL, type);
+		proto->sap = llc_sap_open(type, func);
 		if (!proto->sap) {
 			kfree(proto);
 			proto = NULL;
diff -Nru a/net/802/psnap.c b/net/802/psnap.c
--- a/net/802/psnap.c	Fri Sep 27 14:51:05 2002
+++ b/net/802/psnap.c	Fri Sep 27 14:51:05 2002
@@ -51,32 +51,26 @@
 /*
  *	A SNAP packet has arrived
  */
-static int snap_indicate(struct llc_prim_if_block *prim)
+static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
+		    struct packet_type *pt)
 {
-	struct sk_buff *skb;
-	struct datalink_proto *proto;
 	int rc = 1;
-	static struct packet_type psnap_packet_type = {
+	struct datalink_proto *proto = find_snap_client(skb->h.raw);
+	static struct packet_type snap_packet_type = {
 		.type = __constant_htons(ETH_P_SNAP),
 	};
 
-	if (prim->prim != LLC_DATAUNIT_PRIM)
-		goto out;
-
-	skb = prim->data->udata.skb;
-	proto = find_snap_client(skb->h.raw);
-
 	if (proto) {
 		/* Pass the frame on. */
 		skb->h.raw  += 5;
 		skb_pull(skb, 5);
-		rc = proto->rcvfunc(skb, skb->dev, &psnap_packet_type);
+		rc = proto->rcvfunc(skb, dev, &snap_packet_type);
 	} else {
 		skb->sk = NULL;
 		kfree_skb(skb);
 		rc = 1;
 	}
-out:
+
 	return rc;
 }
 
@@ -99,7 +93,7 @@
 
 static int __init snap_init(void)
 {
-	snap_sap = llc_sap_open(snap_indicate, NULL, 0xAA);
+	snap_sap = llc_sap_open(0xAA, snap_rcv);
 
 	if (!snap_sap)
 		printk(KERN_CRIT "SNAP - unable to register with 802.2\n");
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Fri Sep 27 14:51:05 2002
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Fri Sep 27 14:51:05 2002
@@ -7,6 +7,7 @@
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#include <linux/string.h>
 
 #include <net/tcp.h>
 
diff -Nru a/net/ipv4/netfilter/ipchains_core.c b/net/ipv4/netfilter/ipchains_core.c
--- a/net/ipv4/netfilter/ipchains_core.c	Fri Sep 27 14:51:05 2002
+++ b/net/ipv4/netfilter/ipchains_core.c	Fri Sep 27 14:51:05 2002
@@ -1252,7 +1252,7 @@
 		return NULL;
 	}
 
-	fwkern = kmalloc(SIZEOF_STRUCT_IP_FW_KERNEL, GFP_KERNEL);
+	fwkern = kmalloc(SIZEOF_STRUCT_IP_FW_KERNEL, GFP_ATOMIC);
 	if (!fwkern) {
 		duprintf("convert_ipfw: kmalloc failed!\n");
 		*errno = ENOMEM;
diff -Nru a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
--- a/net/ipv4/netfilter/ipt_ULOG.c	Fri Sep 27 14:51:04 2002
+++ b/net/ipv4/netfilter/ipt_ULOG.c	Fri Sep 27 14:51:04 2002
@@ -50,7 +50,7 @@
 #include <linux/netfilter_ipv4/ipt_ULOG.h>
 #include <linux/netfilter_ipv4/lockhelp.h>
 #include <net/sock.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
diff -Nru a/net/ipv4/netfilter/ipt_unclean.c b/net/ipv4/netfilter/ipt_unclean.c
--- a/net/ipv4/netfilter/ipt_unclean.c	Fri Sep 27 14:51:04 2002
+++ b/net/ipv4/netfilter/ipt_unclean.c	Fri Sep 27 14:51:04 2002
@@ -211,7 +211,7 @@
 
 	/* Bad checksum?  Don't print, just say it's unclean. */
 	/* FIXME: SRC ROUTE packets won't match checksum --RR */
-	if (!more_frags && !embedded
+	if (!more_frags && !embedded && udph->check
 	    && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
 				 csum_partial((char *)udph, datalen, 0)) != 0)
 		return 0;
diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c	Fri Sep 27 14:51:04 2002
+++ b/net/ipv6/ndisc.c	Fri Sep 27 14:51:04 2002
@@ -159,6 +159,67 @@
 	return opt + space;
 }
 
+struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
+				     struct nd_opt_hdr *end)
+{
+	int type;
+	if (!cur || !end || cur >= end)
+		return NULL;
+	type = cur->nd_opt_type;
+	do {
+		cur = ((void *)cur) + (cur->nd_opt_len << 3);
+	} while(cur < end && cur->nd_opt_type != type);
+	return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
+}
+
+struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
+					  struct ndisc_options *ndopts)
+{
+	struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
+
+	if (!nd_opt || opt_len < 0 || !ndopts)
+		return NULL;
+	memset(ndopts, 0, sizeof(*ndopts));
+	while (opt_len) {
+		int l;
+		if (opt_len < sizeof(struct nd_opt_hdr))
+			return NULL;
+		l = nd_opt->nd_opt_len << 3;
+		if (opt_len < l || l == 0)
+			return NULL;
+		switch (nd_opt->nd_opt_type) {
+		case ND_OPT_SOURCE_LL_ADDR:
+		case ND_OPT_TARGET_LL_ADDR:
+		case ND_OPT_MTU:
+		case ND_OPT_REDIRECT_HDR:
+			if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
+				ND_PRINTK2((KERN_WARNING
+					    "ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
+					    nd_opt->nd_opt_type));
+			} else {
+				ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
+			}
+			break;
+		case ND_OPT_PREFIX_INFO:
+			ndopts->nd_opts_pi_end = nd_opt;
+			if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
+				ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
+			break;
+		default:
+			/*
+			 * Unknown options must be silently ignored,
+			 * to accomodate future extension to the protocol.
+			 */
+			ND_PRINTK2(KERN_WARNING
+				   "ndisc_parse_options(): ignored unsupported option; type=%d, len=%d\n",
+				   nd_opt->nd_opt_type, nd_opt->nd_opt_len);
+		}
+		opt_len -= l;
+		nd_opt = ((void *)nd_opt) + l;
+	}
+	return ndopts;
+}
+
 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
 {
 	switch (dev->type) {
@@ -489,27 +550,6 @@
 }
 		   
 
-static u8 * ndisc_find_option(u8 *opt, int opt_len, int len, int option)
-{
-	while (opt_len <= len) {
-		int l = opt[1]<<3;
-
-		if (opt[0] == option && l >= opt_len)
-			return opt + 2;
-
-		if (l == 0) {
-			if (net_ratelimit())
-			    printk(KERN_WARNING "ndisc: option has 0 len\n");
-			return NULL;
-		}
-
-		opt += l;
-		len -= l;
-	}
-	return NULL;
-}
-
-
 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
 {
 	/*
@@ -547,13 +587,6 @@
 	}
 }
 
-
-static void ndisc_update(struct neighbour *neigh, u8* opt, int len, int type)
-{
-	opt = ndisc_find_option(opt, neigh->dev->addr_len+2, len, type);
-	neigh_update(neigh, opt, NUD_STALE, 1, 1);
-}
-
 static void ndisc_router_discovery(struct sk_buff *skb)
 {
         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
@@ -561,6 +594,7 @@
 	struct inet6_dev *in6_dev;
 	struct rt6_info *rt;
 	int lifetime;
+	struct ndisc_options ndopts;
 	int optlen;
 
 	__u8 * opt = (__u8 *)(ra_msg + 1);
@@ -592,6 +626,13 @@
 		return;
 	}
 
+	if (!ndisc_parse_options(opt, optlen, &ndopts)) {
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING
+				   "ICMP6 RA: invalid ND option, ignored.\n");
+		return;
+	}
+
 	if (in6_dev->if_flags & IF_RS_SENT) {
 		/*
 		 *	flag that an RA was received after an RS was sent
@@ -675,63 +716,60 @@
 	 *	Process options.
 	 */
 
-        while (optlen > 0) {
-                int len = (opt[1] << 3);
+	if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
+		u8 *lladdr = NULL;
+		int lladdrlen;
+		if (ndopts.nd_opts_src_lladdr) {
+			lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
+			lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
+			if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
+				if (net_ratelimit())
+					ND_PRINTK2(KERN_WARNING
+						   "ICMP6 RA: Invalid lladdr length.\n");
+				goto out;
+			}
+		}
+		neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
+	}
 
-		if (len == 0) {
-			ND_PRINTK0("RA: opt has 0 len\n");
-			break;
+	if (ndopts.nd_opts_pi) {
+		struct nd_opt_hdr *p;
+		for (p = ndopts.nd_opts_pi;
+		     p;
+		     p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
+			addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
 		}
+	}
 
-                switch(*opt) {
-                case ND_OPT_SOURCE_LL_ADDR:
+	if (ndopts.nd_opts_mtu) {
+		u32 mtu;
 
-			if (rt == NULL)
-				break;
-			
-			if ((neigh = rt->rt6i_nexthop) != NULL &&
-			    skb->dev->addr_len + 2 >= len)
-				neigh_update(neigh, opt+2, NUD_STALE, 1, 1);
-			break;
+		memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
+		mtu = ntohl(mtu);
 
-                case ND_OPT_PREFIX_INFO:
-			addrconf_prefix_rcv(skb->dev, opt, len);
-                        break;
-
-                case ND_OPT_MTU:
-			{
-				int mtu;
-				
-				mtu = htonl(*(__u32 *)(opt+4));
-
-				if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
-					ND_PRINTK0("NDISC: router "
-						   "announcement with mtu = %d\n",
-						   mtu);
-					break;
-				}
+		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
+			if (net_ratelimit()) {
+				ND_PRINTK0("NDISC: router announcement with mtu = %d\n",
+					   mtu);
+			}
+		}
 
-				if (in6_dev->cnf.mtu6 != mtu) {
-					in6_dev->cnf.mtu6 = mtu;
+		if (in6_dev->cnf.mtu6 != mtu) {
+			in6_dev->cnf.mtu6 = mtu;
 
-					if (rt)
-						rt->u.dst.pmtu = mtu;
+			if (rt)
+				rt->u.dst.pmtu = mtu;
 
-					rt6_mtu_change(skb->dev, mtu);
-				}
-			}
-                        break;
-
-		case ND_OPT_TARGET_LL_ADDR:
-		case ND_OPT_REDIRECT_HDR:
-			ND_PRINTK0("got illegal option with RA");
-			break;
-		default:
-			ND_PRINTK0("unkown option in RA\n");
-                };
-                optlen -= len;
-                opt += len;
-        }
+			rt6_mtu_change(skb->dev, mtu);
+		}
+	}
+			
+	if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
+		if (net_ratelimit())
+			ND_PRINTK0(KERN_WARNING
+				   "ICMP6 RA: got illegal option with RA");
+	}
+out:
 	if (rt)
 		dst_release(&rt->u.dst);
 	in6_dev_put(in6_dev);
@@ -745,7 +783,10 @@
 	struct in6_addr *target;	/* new first hop to destination */
 	struct neighbour *neigh;
 	int on_link = 0;
+	struct ndisc_options ndopts;
 	int optlen;
+	u8 *lladdr = NULL;
+	int lladdrlen;
 
 	if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
 		if (net_ratelimit())
@@ -793,6 +834,24 @@
 	 *	first-hop router for the specified ICMP Destination Address.
 	 */
 		
+	if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING
+				   "ICMP6 Redirect: invalid ND options, rejected.\n");
+		in6_dev_put(in6_dev);
+		return;
+	}
+	if (ndopts.nd_opts_tgt_lladdr) {
+		lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
+		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
+		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
+			if (net_ratelimit())
+				ND_PRINTK2(KERN_WARNING
+					   "ICMP6 Redirect: invalid lladdr length.\n");
+			in6_dev_put(in6_dev);
+			return;
+		}
+	}
 	/* passed validation tests */
 
 	/*
@@ -801,7 +860,7 @@
 
 	neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
 	if (neigh) {
-		ndisc_update(neigh, (u8*)(dest + 1), optlen, ND_OPT_TARGET_LL_ADDR);
+		neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
 		if (neigh->nud_state&NUD_VALID)
 			rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
 		else
@@ -927,31 +986,6 @@
 	ICMP6_INC_STATS(Icmp6OutMsgs);
 }
 
-static __inline__ struct neighbour *
-ndisc_recv_ns(struct in6_addr *saddr, struct sk_buff *skb)
-{
-	u8 *opt;
-
-	opt = skb->h.raw;
-	opt += sizeof(struct nd_msg);
-	opt = ndisc_find_option(opt, skb->dev->addr_len+2, skb->tail - opt, ND_OPT_SOURCE_LL_ADDR);
-
-	return neigh_event_ns(&nd_tbl, opt, saddr, skb->dev);
-}
-
-static __inline__ int ndisc_recv_na(struct neighbour *neigh, struct sk_buff *skb)
-{
-	u8 *opt;
-	struct nd_msg *msg = (struct nd_msg*) skb->h.raw;
-
-	opt = ndisc_find_option(msg->opt, skb->dev->addr_len+2,
-				skb->tail - msg->opt, ND_OPT_TARGET_LL_ADDR);
-
-	return neigh_update(neigh, opt,
-			    msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
-			    msg->icmph.icmp6_override, 1);
-}
-
 static void pndisc_redo(struct sk_buff *skb)
 {
 	ndisc_rcv(skb);
@@ -983,13 +1017,15 @@
 		return 0;
 	}
 
-	/* XXX: RFC2461 Validation of [all ndisc messages]:
-	 *	All included ndisc options MUST be of non-zero length
-	 *	(Some checking in ndisc_find_option)
-	 */
-
 	switch (msg->icmph.icmp6_type) {
 	case NDISC_NEIGHBOUR_SOLICITATION:
+	    {
+		struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
+		u8 *lladdr = NULL;
+		int lladdrlen = 0;
+		u32 ndoptlen = skb->tail - msg->opt;
+		struct ndisc_options ndopts;
+
 		if (skb->len < sizeof(struct nd_msg)) {
 			if (net_ratelimit())
 				printk(KERN_WARNING "ICMP NS: packet too short\n");
@@ -1002,6 +1038,22 @@
 			return 0;
 		}
 
+		if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
+			if (net_ratelimit())
+				printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
+			return 0;
+		}
+
+		if (ndopts.nd_opts_src_lladdr) {
+			lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1);
+			lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
+			if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
+				if (net_ratelimit())
+					printk(KERN_WARNING "ICMP NS: bad lladdr length.\n");
+				return 0;
+			}
+		}
+
 		/* XXX: RFC2461 7.1.1:
 		 * 	If the IP source address is the unspecified address, there
 		 *	MUST NOT be source link-layer address option in the message.
@@ -1068,7 +1120,7 @@
 				 *	for the source adddress
 				 */
 
-				neigh = ndisc_recv_ns(saddr, skb);
+				neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, skb->dev);
 
 				if (neigh || !dev->hard_header) {
 					ndisc_send_na(dev, neigh, saddr, &ifp->addr, 
@@ -1098,7 +1150,8 @@
 					else
 						nd_tbl.stats.rcv_probes_ucast++;
 
-					neigh = ndisc_recv_ns(saddr, skb);
+					
+					neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, skb->dev);
 
 					if (neigh) {
 						ndisc_send_na(dev, neigh, saddr, &msg->target,
@@ -1118,8 +1171,16 @@
 			
 		}
 		return 0;
+	    }
 
 	case NDISC_NEIGHBOUR_ADVERTISEMENT:
+	    {
+		struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
+		u8 *lladdr = NULL;
+		int lladdrlen = 0;
+		u32 ndoptlen = skb->tail - msg->opt;
+		struct ndisc_options ndopts;
+
 		if (skb->len < sizeof(struct nd_msg)) {
 			if (net_ratelimit())
 				printk(KERN_WARNING "ICMP NA: packet too short\n");
@@ -1138,6 +1199,20 @@
 			return 0;
 		}
 		
+		if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
+			if (net_ratelimit())
+				printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
+			return 0;
+		}
+		if (ndopts.nd_opts_tgt_lladdr) {
+			lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
+			lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
+			if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
+				if (net_ratelimit())
+					printk(KERN_WARNING "NDISC NA: invalid lladdr length.\n");
+				return 0;
+			}
+		}
 		if ((ifp = ipv6_get_ifaddr(&msg->target, dev))) {
 			if (ifp->flags & IFA_F_TENTATIVE) {
 				addrconf_dad_failure(ifp);
@@ -1175,10 +1250,13 @@
 					neigh->flags |= NTF_ROUTER;
 			}
 
-			ndisc_recv_na(neigh, skb);
+			neigh_update(neigh, lladdr,
+				     msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
+				     msg->icmph.icmp6_override, 1);
 			neigh_release(neigh);
 		}
 		break;
+	    }
 
 	case NDISC_ROUTER_ADVERTISEMENT:
 		ndisc_router_discovery(skb);
diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
--- a/net/ipv6/netfilter/ip6_tables.c	Fri Sep 27 14:51:05 2002
+++ b/net/ipv6/netfilter/ip6_tables.c	Fri Sep 27 14:51:05 2002
@@ -1493,6 +1493,9 @@
 	duprintf("table->private->number = %u\n",
 		 table->private->number);
 
+	/* save number of initial entries */
+	table->private->initial_entries = table->private->number;
+
 	table->lock = RW_LOCK_UNLOCKED;
 	list_prepend(&ip6t_tables, table);
 
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	Fri Sep 27 14:51:03 2002
+++ b/net/ipv6/udp.c	Fri Sep 27 14:51:03 2002
@@ -50,6 +50,18 @@
 
 struct udp_mib udp_stats_in6[NR_CPUS*2];
 
+static __inline__ int udv6_rcv_saddr_equal(struct sock *sk, struct sock *sk2)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	int addr_type = ipv6_addr_type(&np->rcv_saddr);
+
+	return !inet_sk(sk2)->rcv_saddr || addr_type == IPV6_ADDR_ANY ||
+	       (sk2->family == AF_INET6 &&
+	        !ipv6_addr_cmp(&np->rcv_saddr, &inet6_sk(sk2)->rcv_saddr)) ||
+	       (addr_type == IPV6_ADDR_MAPPED && sk2->family == AF_INET &&
+		inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr);
+}
+
 /* Grrr, addr_type already calculated by caller, but I don't want
  * to add some silly "cookie" argument to this method just for that.
  */
@@ -98,25 +110,15 @@
 		udp_port_rover = snum = result;
 	} else {
 		struct sock *sk2;
-		struct ipv6_pinfo *np = inet6_sk(sk);
-		int addr_type = ipv6_addr_type(&np->rcv_saddr);
 
 		for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
 		     sk2 != NULL;
 		     sk2 = sk2->next) {
-			struct inet_opt *inet2 = inet_sk(sk2);
-			struct ipv6_pinfo *np2 = inet6_sk(sk2);
-
-			if (inet2->num == snum &&
+			if (inet_sk(sk2)->num == snum &&
 			    sk2 != sk &&
 			    sk2->bound_dev_if == sk->bound_dev_if &&
-			    (!inet2->rcv_saddr ||
-			     addr_type == IPV6_ADDR_ANY ||
-			     !ipv6_addr_cmp(&np->rcv_saddr, &np2->rcv_saddr) ||
-			     (addr_type == IPV6_ADDR_MAPPED &&
-			      sk2->family == AF_INET &&
-			      inet_sk(sk)->rcv_saddr == inet2->rcv_saddr)) &&
-			    (!sk2->reuse || !sk->reuse))
+			    (!sk2->reuse || !sk->reuse) &&
+			    udv6_rcv_saddr_equal(sk, sk2))
 				goto fail;
 		}
 	}
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	Fri Sep 27 14:51:03 2002
+++ b/net/ipx/af_ipx.c	Fri Sep 27 14:51:03 2002
@@ -2252,22 +2252,6 @@
 out:	return ret;
 }
 
-static int ipx_8022_indicate(struct llc_prim_if_block *prim)
-{
-	int rc = 1;
-	static struct packet_type p8022_packet_type = {
-		.type = __constant_htons(ETH_P_802_2),
-	};
-
-	if (prim->prim == LLC_DATAUNIT_PRIM) {
-		struct sk_buff *skb = prim->data->udata.skb;
-
-		rc = ipx_rcv(skb, skb->dev, &p8022_packet_type);
-	}
-						
-	return rc;
-}
-
 static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
 	struct scm_cookie *scm)
 {
@@ -2560,7 +2544,7 @@
 	else
 		printk(ipx_8023_err_msg);
 
-	p8022_datalink = register_8022_client(ipx_8022_type, ipx_8022_indicate);
+	p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv);
 	if (!p8022_datalink)
 		printk(ipx_llc_err_msg);
 
diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c
--- a/net/irda/af_irda.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/af_irda.c	Fri Sep 27 14:51:03 2002
@@ -85,7 +85,7 @@
 	struct sock *sk;
 	int err;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	self = (struct irda_sock *) instance;
 	ASSERT(self != NULL, return -1;);
@@ -95,7 +95,7 @@
 
 	err = sock_queue_rcv_skb(sk, skb);
 	if (err) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), error: no more mem!\n");
+		IRDA_DEBUG(1, "%s(), error: no more mem!\n", __FUNCTION__);
 		self->rx_flow = FLOW_STOP;
 
 		/* When we return error, TTP will need to requeue the skb */
@@ -119,7 +119,7 @@
 
 	self = (struct irda_sock *) instance;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	/* Don't care about it, but let's not leak it */
 	if(skb)
@@ -127,7 +127,8 @@
 
 	sk = self->sk;
 	if (sk == NULL) {
-		IRDA_DEBUG(0, __FUNCTION__ "(%p) : BUG : sk is NULL\n", self);
+		IRDA_DEBUG(0, "%s(%p) : BUG : sk is NULL\n",
+			   __FUNCTION__, self);
 		return;
 	}
 
@@ -183,7 +184,7 @@
 
 	self = (struct irda_sock *) instance;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	sk = self->sk;
 	if (sk == NULL)
@@ -215,7 +216,7 @@
 		self->max_data_size = irttp_get_max_seg_size(self->tsap);
 	};
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), max_data_size=%d\n",
+	IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
 		   self->max_data_size);
 
 	memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
@@ -242,7 +243,7 @@
 
 	self = (struct irda_sock *) instance;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	sk = self->sk;
 	if (sk == NULL)
@@ -274,7 +275,7 @@
 		self->max_data_size = irttp_get_max_seg_size(self->tsap);
 	};
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), max_data_size=%d\n",
+	IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
 		   self->max_data_size);
 
 	memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
@@ -293,13 +294,14 @@
 {
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 
 	skb = dev_alloc_skb(64);
 	if (skb == NULL) {
-		IRDA_DEBUG(0, __FUNCTION__ "() Unable to allocate sk_buff!\n");
+		IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n",
+			   __FUNCTION__);
 		return;
 	}
 
@@ -320,7 +322,7 @@
 	struct irda_sock *self;
 	struct sock *sk;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	self = (struct irda_sock *) instance;
 	ASSERT(self != NULL, return;);
@@ -330,17 +332,18 @@
 
 	switch (flow) {
 	case FLOW_STOP:
-		IRDA_DEBUG(1, __FUNCTION__ "(), IrTTP wants us to slow down\n");
+		IRDA_DEBUG(1, "%s(), IrTTP wants us to slow down\n",
+			   __FUNCTION__);
 		self->tx_flow = flow;
 		break;
 	case FLOW_START:
 		self->tx_flow = flow;
-		IRDA_DEBUG(1, __FUNCTION__
-			   "(), IrTTP wants us to start again\n");
+		IRDA_DEBUG(1, "%s(), IrTTP wants us to start again\n",
+			   __FUNCTION__);
 		wake_up_interruptible(sk->sleep);
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown flow command!\n");
+		IRDA_DEBUG(0, "%s(), Unknown flow command!\n", __FUNCTION__);
 		/* Unknown flow command, better stop */
 		self->tx_flow = flow;
 		break;
@@ -366,7 +369,7 @@
 		return;
 	}
 
-	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	/* We probably don't need to make any more queries */
 	iriap_close(self->iriap);
@@ -374,7 +377,7 @@
 
 	/* Check if request succeeded */
 	if (result != IAS_SUCCESS) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), IAS query failed! (%d)\n",
+		IRDA_DEBUG(1, "%s(), IAS query failed! (%d)\n", __FUNCTION__,
 			   result);
 
 		self->errno = result;	/* We really need it later */
@@ -408,7 +411,7 @@
 {
 	struct irda_sock *self;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	self = (struct irda_sock *) priv;
 	if (!self) {
@@ -445,7 +448,7 @@
 {
 	struct irda_sock *self;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	self = (struct irda_sock *) priv;
 	ASSERT(self != NULL, return;);
@@ -488,7 +491,8 @@
 	self->tsap = irttp_open_tsap(tsap_sel, DEFAULT_INITIAL_CREDIT,
 				     &notify);
 	if (self->tsap == NULL) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to allocate TSAP!\n");
+		IRDA_DEBUG(0, "%s(), Unable to allocate TSAP!\n",
+			   __FUNCTION__);
 		return -ENOMEM;
 	}
 	/* Remember which TSAP selector we actually got */
@@ -1066,7 +1070,7 @@
 	struct sock *sk;
 	struct irda_sock *self;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	/* Check for valid socket type */
 	switch (sock->type) {
@@ -1090,7 +1094,7 @@
 	}
 	memset(self, 0, sizeof(struct irda_sock));
 
-	IRDA_DEBUG(2, __FUNCTION__ "() : self is %p\n", self);
+	IRDA_DEBUG(2, "%s() : self is %p\n", __FUNCTION__, self);
 
 	init_waitqueue_head(&self->query_wait);
 
@@ -1152,7 +1156,7 @@
  */
 void irda_destroy_socket(struct irda_sock *self)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	ASSERT(self != NULL, return;);
 
@@ -1195,7 +1199,7 @@
 {
 	struct sock *sk = sock->sk;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
         if (sk == NULL)
 		return 0;
@@ -1264,7 +1268,7 @@
 	unsigned char *asmptr;
 	int err;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len);
+	IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
 
 	/* Note : socket.c set MSG_EOR on SEQPACKET sockets */
 	if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR))
@@ -1293,9 +1297,8 @@
 
 	/* 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,
-			   self->max_data_size);
+		IRDA_DEBUG(2, "%s(), Chopping frame from %d to %d bytes!\n",
+			   __FUNCTION__, len, self->max_data_size);
 		len = self->max_data_size;
 	}
 
@@ -1315,7 +1318,7 @@
 	 */
 	err = irttp_data_request(self->tsap, skb);
 	if (err) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), err=%d\n", err);
+		IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
 		return err;
 	}
 	/* Tell client how much data we actually sent */
@@ -1336,7 +1339,7 @@
 	struct sk_buff *skb;
 	int copied, err;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 
@@ -1349,9 +1352,8 @@
 	copied     = skb->len;
 
 	if (copied > size) {
-		IRDA_DEBUG(2, __FUNCTION__
-			   "(), Received truncated frame (%d < %d)!\n",
-			   copied, size);
+		IRDA_DEBUG(2, "%s(), Received truncated frame (%d < %d)!\n",
+			   __FUNCTION__, copied, size);
 		copied = size;
 		msg->msg_flags |= MSG_TRUNC;
 	}
@@ -1367,7 +1369,7 @@
 	 */
 	if (self->rx_flow == FLOW_STOP) {
 		if ((atomic_read(&sk->rmem_alloc) << 2) <= sk->rcvbuf) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), Starting IrTTP\n");
+			IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __FUNCTION__);
 			self->rx_flow = FLOW_START;
 			irttp_flow_request(self->tsap, FLOW_START);
 		}
@@ -1389,7 +1391,7 @@
 	int target = 1;
 	DECLARE_WAITQUEUE(waitq, current);
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 
@@ -1466,14 +1468,15 @@
 
 			/* put the skb back if we didn't use it up.. */
 			if (skb->len) {
-				IRDA_DEBUG(1, __FUNCTION__ "(), back on q!\n");
+				IRDA_DEBUG(1, "%s(), back on q!\n",
+					   __FUNCTION__);
 				skb_queue_head(&sk->receive_queue, skb);
 				break;
 			}
 
 			kfree_skb(skb);
 		} else {
-			IRDA_DEBUG(0, __FUNCTION__ "() questionable!?\n");
+			IRDA_DEBUG(0, "%s() questionable!?\n", __FUNCTION__);
 
 			/* put message back and return */
 			skb_queue_head(&sk->receive_queue, skb);
@@ -1489,7 +1492,7 @@
 	 */
 	if (self->rx_flow == FLOW_STOP) {
 		if ((atomic_read(&sk->rmem_alloc) << 2) <= sk->rcvbuf) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), Starting IrTTP\n");
+			IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __FUNCTION__);
 			self->rx_flow = FLOW_START;
 			irttp_flow_request(self->tsap, FLOW_START);
 		}
@@ -1514,7 +1517,7 @@
 	unsigned char *asmptr;
 	int err;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len);
+	IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
 
 	if (msg->msg_flags & ~MSG_DONTWAIT)
 		return -EINVAL;
@@ -1535,9 +1538,9 @@
 	 * 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,
-			   self->max_data_size);
+		IRDA_DEBUG(0, "%s(), Warning to much data! "
+			   "Chopping frame from %d to %d bytes!\n",
+			   __FUNCTION__, len, self->max_data_size);
 		len = self->max_data_size;
 	}
 
@@ -1548,7 +1551,7 @@
 
 	skb_reserve(skb, self->max_header_size);
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), appending user data\n");
+	IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
 	asmptr = skb->h.raw = skb_put(skb, len);
 	memcpy_fromiovec(asmptr, msg->msg_iov, len);
 
@@ -1558,7 +1561,7 @@
 	 */
 	err = irttp_udata_request(self->tsap, skb);
 	if (err) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), err=%d\n", err);
+		IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
 		return err;
 	}
 	return len;
@@ -1580,7 +1583,7 @@
 	unsigned char *asmptr;
 	int err;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len);
+	IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
 
 	if (msg->msg_flags & ~MSG_DONTWAIT)
 		return -EINVAL;
@@ -1598,9 +1601,9 @@
 	 * 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,
-			   self->max_data_size);
+		IRDA_DEBUG(0, "%s(), Warning to much data! "
+			   "Chopping frame from %d to %d bytes!\n",
+			   __FUNCTION__, len, self->max_data_size);
 		len = self->max_data_size;
 	}
 
@@ -1611,13 +1614,13 @@
 
 	skb_reserve(skb, self->max_header_size);
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), appending user data\n");
+	IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
 	asmptr = skb->h.raw = skb_put(skb, len);
 	memcpy_fromiovec(asmptr, msg->msg_iov, len);
 
 	err = irlmp_connless_data_request(self->lsap, skb);
 	if (err) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), err=%d\n", err);
+		IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
 		return err;
 	}
 	return len;
@@ -1634,7 +1637,7 @@
 
 	ASSERT(self != NULL, return -1;);
 
-	IRDA_DEBUG(1, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(1, "%s(%p)\n", __FUNCTION__, self);
 
 	sk->state       = TCP_CLOSE;
 	sk->shutdown   |= SEND_SHUTDOWN;
@@ -1669,7 +1672,7 @@
 	struct irda_sock *self = irda_sk(sk);
 	unsigned int mask;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	poll_wait(file, sk->sleep, wait);
 	mask = 0;
@@ -1678,7 +1681,7 @@
 	if (sk->err)
 		mask |= POLLERR;
 	if (sk->shutdown & RCV_SHUTDOWN) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), POLLHUP\n");
+		IRDA_DEBUG(0, "%s(), POLLHUP\n", __FUNCTION__);
 		mask |= POLLHUP;
 	}
 
@@ -1692,7 +1695,7 @@
 	switch (sk->type) {
 	case SOCK_STREAM:
 		if (sk->state == TCP_CLOSE) {
-			IRDA_DEBUG(0, __FUNCTION__ "(), POLLHUP\n");
+			IRDA_DEBUG(0, "%s(), POLLHUP\n", __FUNCTION__);
 			mask |= POLLHUP;
 		}
 
@@ -1728,7 +1731,7 @@
 {
 	struct sock *sk = sock->sk;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), cmd=%#x\n", cmd);
+	IRDA_DEBUG(4, "%s(), cmd=%#x\n", __FUNCTION__, cmd);
 
 	switch (cmd) {
 	case TIOCOUTQ: {
@@ -1775,7 +1778,7 @@
 	case SIOCSIFMETRIC:
 		return -EINVAL;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), doing device ioctl!\n");
+		IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__);
 		return dev_ioctl(cmd, (void *) arg);
 	}
 
@@ -1801,7 +1804,7 @@
 
 	ASSERT(self != NULL, return -1;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	if (level != SOL_IRLMP)
 		return -ENOPROTOOPT;
@@ -1963,8 +1966,7 @@
 
 		/* Check is the user space own the object */
 		if(ias_attr->value->owner != IAS_USER_ATTR) {
-			IRDA_DEBUG(1, __FUNCTION__
-				   "(), attempting to delete a kernel attribute\n");
+			IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __FUNCTION__);
 			kfree(ias_opt);
 			return -EPERM;
 		}
@@ -1982,8 +1984,8 @@
 
 		/* Only possible for a seqpacket service (TTP with SAR) */
 		if (sk->type != SOCK_SEQPACKET) {
-			IRDA_DEBUG(2, __FUNCTION__
-				   "(), setting max_sdu_size = %d\n", opt);
+			IRDA_DEBUG(2, "%s(), setting max_sdu_size = %d\n",
+				   __FUNCTION__, opt);
 			self->max_sdu_size_rx = opt;
 		} else {
 			WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n",
@@ -2099,7 +2101,7 @@
 	int err;
 	int offset, total;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(%p)\n", self);
+	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	if (level != SOL_IRLMP)
 		return -ENOPROTOOPT;
@@ -2356,8 +2358,7 @@
 		if (!self->cachediscovery) {
 			int ret = 0;
 
-			IRDA_DEBUG(1, __FUNCTION__
-				   "(), nothing discovered yet, going to sleep...\n");
+			IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __FUNCTION__);
 
 			/* Set watchdog timer to expire in <val> ms. */
 			self->errno = 0;
@@ -2375,15 +2376,14 @@
 			if(timer_pending(&(self->watchdog)))
 				del_timer(&(self->watchdog));
 
-			IRDA_DEBUG(1, __FUNCTION__
-				   "(), ...waking up !\n");
+			IRDA_DEBUG(1, "%s(), ...waking up !\n", __FUNCTION__);
 
 			if (ret != 0)
 				return ret;
 		}
 		else
-			IRDA_DEBUG(1, __FUNCTION__
-				   "(), found immediately !\n");
+			IRDA_DEBUG(1, "%s(), found immediately !\n",
+				   __FUNCTION__);
 
 		/* Tell IrLMP that we have been notified */
 		irlmp_update_client(self->ckey, self->mask, NULL, NULL, NULL);
diff -Nru a/net/irda/discovery.c b/net/irda/discovery.c
--- a/net/irda/discovery.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/discovery.c	Fri Sep 27 14:51:03 2002
@@ -108,7 +108,7 @@
 {
 	discovery_t *discovery;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	/*
 	 *  If log is missing this means that IrLAP was unable to perform the
@@ -150,7 +150,7 @@
 	discovery_t *discovery, *curr;
 	unsigned long flags;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	spin_lock_irqsave(&log->hb_spinlock, flags);
 
diff -Nru a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
--- a/net/irda/ircomm/ircomm_core.c	Fri Sep 27 14:51:02 2002
+++ b/net/irda/ircomm/ircomm_core.c	Fri Sep 27 14:51:02 2002
@@ -78,7 +78,7 @@
 
 void __exit ircomm_cleanup(void)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	hashbin_delete(ircomm, (FREE_FUNC) __ircomm_close);
 
@@ -98,7 +98,7 @@
 	struct ircomm_cb *self = NULL;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), service_type=0x%02x\n",
+	IRDA_DEBUG(2, "%s(), service_type=0x%02x\n", __FUNCTION__ ,
 		   service_type);
 
 	ASSERT(ircomm != NULL, return NULL;);
@@ -142,7 +142,7 @@
  */
 static int __ircomm_close(struct ircomm_cb *self)
 {
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	/* Disconnect link if any */
 	ircomm_do_event(self, IRCOMM_DISCONNECT_REQUEST, NULL, NULL);
@@ -178,7 +178,7 @@
 	ASSERT(self != NULL, return -EIO;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -EIO;);
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	entry = hashbin_remove(ircomm, self->line, NULL);
 
@@ -203,7 +203,7 @@
 	struct ircomm_info info;
 	int ret;
 
-	IRDA_DEBUG(2 , __FUNCTION__"()\n");
+	IRDA_DEBUG(2 , "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -232,7 +232,7 @@
 {
 	int clen = 0;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	/* Check if the packet contains data on the control channel */
 	if (skb->len > 0)
@@ -248,7 +248,7 @@
 						info->qos, info->max_data_size,
 						info->max_header_size, skb);
 	else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n");
+		IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
 		dev_kfree_skb(skb);
 	}
 }
@@ -266,7 +266,7 @@
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ret = ircomm_do_event(self, IRCOMM_CONNECT_RESPONSE, userdata, NULL);
 
@@ -284,7 +284,7 @@
 void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb,
 			    struct ircomm_info *info)
 {
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	if (self->notify.connect_confirm )
 		self->notify.connect_confirm(self->notify.instance,
@@ -292,7 +292,7 @@
 					     info->max_data_size,
 					     info->max_header_size, skb);
 	else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n");
+		IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
 		dev_kfree_skb(skb);
 	}
 }
@@ -307,7 +307,7 @@
 {
 	int ret;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -EFAULT;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -EFAULT;);
@@ -328,14 +328,14 @@
  */
 void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb)
 {	
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(skb->len > 0, return;);
 
 	if (self->notify.data_indication)
 		self->notify.data_indication(self->notify.instance, self, skb);
 	else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n");
+		IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
 		dev_kfree_skb(skb);
 	}
 }
@@ -368,8 +368,8 @@
 	if (skb->len)
 		ircomm_data_indication(self, skb);		
 	else {
-		IRDA_DEBUG(4, __FUNCTION__ 
-			   "(), data was control info only!\n");
+		IRDA_DEBUG(4, 
+			   "%s(), data was control info only!\n", __FUNCTION__ );
 		dev_kfree_skb(skb);
 	}
 }
@@ -384,7 +384,7 @@
 {
 	int ret;
 	
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -EFAULT;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -EFAULT;);
@@ -408,7 +408,7 @@
 {
 	struct sk_buff *ctrl_skb;
 
-	IRDA_DEBUG(2, __FUNCTION__"()\n");	
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );	
 
 	ctrl_skb = skb_clone(skb, GFP_ATOMIC);
 	if (!ctrl_skb)
@@ -422,7 +422,7 @@
 		self->notify.udata_indication(self->notify.instance, self, 
 					      ctrl_skb);
 	else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n");
+		IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
 		dev_kfree_skb(skb);
 	}
 }
@@ -438,7 +438,7 @@
 	struct ircomm_info info;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -459,7 +459,7 @@
 void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb,
 				  struct ircomm_info *info)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
        
 	ASSERT(info != NULL, return;);
 
@@ -467,7 +467,7 @@
 		self->notify.disconnect_indication(self->notify.instance, self,
 						   info->reason, skb);
 	} else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n");
+		IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
 		dev_kfree_skb(skb);
 	}
 }
@@ -480,7 +480,7 @@
  */
 void ircomm_flow_request(struct ircomm_cb *self, LOCAL_FLOW flow)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
diff -Nru a/net/irda/ircomm/ircomm_event.c b/net/irda/ircomm/ircomm_event.c
--- a/net/irda/ircomm/ircomm_event.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/ircomm/ircomm_event.c	Fri Sep 27 14:51:04 2002
@@ -107,7 +107,7 @@
 		ircomm_connect_indication(self, skb, info);
 		break;
 	default:
-		IRDA_DEBUG(4, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(4, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
@@ -139,7 +139,7 @@
 		ircomm_disconnect_indication(self, skb, info);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(0, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
@@ -174,7 +174,7 @@
 		ircomm_disconnect_indication(self, skb, info);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %s\n",
+		IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
 			   ircomm_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
@@ -218,7 +218,7 @@
 		ret = self->issue.disconnect_request(self, skb, info);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %s\n",
+		IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
 			   ircomm_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
@@ -236,7 +236,7 @@
 int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event,
 		    struct sk_buff *skb, struct ircomm_info *info) 
 {
-	IRDA_DEBUG(4, __FUNCTION__": state=%s, event=%s\n",
+	IRDA_DEBUG(4, "%s: state=%s, event=%s\n", __FUNCTION__ ,
 		   ircomm_state[self->state], ircomm_event[event]);
 
 	return (*state[self->state])(self, event, skb, info);
@@ -252,6 +252,6 @@
 {
 	self->state = state;
 	
-	IRDA_DEBUG(4, __FUNCTION__": next state=%s, service type=%d\n", 
+	IRDA_DEBUG(4, "%s: next state=%s, service type=%d\n", __FUNCTION__ , 
 		   ircomm_state[self->state], self->service_type);
 }
diff -Nru a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c
--- a/net/irda/ircomm/ircomm_lmp.c	Fri Sep 27 14:51:02 2002
+++ b/net/irda/ircomm/ircomm_lmp.c	Fri Sep 27 14:51:02 2002
@@ -50,7 +50,7 @@
 {
 	notify_t notify;
 	
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 	
         /* Register callbacks */
         irda_notify_init(&notify);
@@ -63,7 +63,7 @@
 
 	self->lsap = irlmp_open_lsap(LSAP_ANY, &notify, 0);
 	if (!self->lsap) {
-		IRDA_DEBUG(0,__FUNCTION__"failed to allocate tsap\n");
+		IRDA_DEBUG(0,"%sfailed to allocate tsap\n", __FUNCTION__ );
 		return -1;
 	}
 	self->slsap_sel = self->lsap->slsap_sel;
@@ -91,7 +91,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ret = irlmp_connect_request(self->lsap, info->dlsap_sel,
 				    info->saddr, info->daddr, NULL, userdata); 
@@ -109,7 +109,7 @@
 	struct sk_buff *skb;
 	int ret;
 
-	IRDA_DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 	
 	/* Any userdata supplied? */
 	if (userdata == NULL) {
@@ -140,7 +140,7 @@
         struct sk_buff *skb;
 	int ret;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
         if (!userdata) {
                 skb = dev_alloc_skb(64);
@@ -173,13 +173,13 @@
 
 	cb = (struct irda_skb_cb *) skb->cb;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
  
         line = cb->line;
 
 	self = (struct ircomm_cb *) hashbin_lock_find(ircomm, line, NULL);
         if (!self) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), didn't find myself\n");
+		IRDA_DEBUG(2, "%s(), didn't find myself\n", __FUNCTION__ );
                 return;
 	}
 
@@ -189,7 +189,7 @@
 	self->pkt_count--;
 
         if ((self->pkt_count < 2) && (self->flow_status == FLOW_STOP)) {
-                IRDA_DEBUG(2, __FUNCTION__ "(), asking TTY to start again!\n");
+                IRDA_DEBUG(2, "%s(), asking TTY to start again!\n", __FUNCTION__ );
                 self->flow_status = FLOW_START;
                 if (self->notify.flow_indication)
                         self->notify.flow_indication(self->notify.instance, 
@@ -215,12 +215,12 @@
 	
         cb->line = self->line;
 
-	IRDA_DEBUG(4, __FUNCTION__"(), sending frame\n");
+	IRDA_DEBUG(4, "%s(), sending frame\n", __FUNCTION__ );
 
 	skb->destructor = ircomm_lmp_flow_control;
 	
         if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), asking TTY to slow down!\n");
+		IRDA_DEBUG(2, "%s(), asking TTY to slow down!\n", __FUNCTION__ );
 	        self->flow_status = FLOW_STOP;
                 if (self->notify.flow_indication)
              	        self->notify.flow_indication(self->notify.instance, 
@@ -246,7 +246,7 @@
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -273,7 +273,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	IRDA_DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -303,7 +303,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *)instance;
 	struct ircomm_info info;
 
-	IRDA_DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -330,7 +330,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	IRDA_DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
diff -Nru a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c
--- a/net/irda/ircomm/ircomm_param.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/ircomm/ircomm_param.c	Fri Sep 27 14:51:04 2002
@@ -121,7 +121,7 @@
 	struct sk_buff *skb;
 	int count;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
@@ -162,7 +162,7 @@
 
 	spin_unlock_irqrestore(&self->spinlock, flags);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), skb->len=%d\n", skb->len);
+	IRDA_DEBUG(2, "%s(), skb->len=%d\n", __FUNCTION__ , skb->len);
 
 	if (flush) {
 		/* ircomm_tty_do_softint will take care of the rest */
@@ -197,11 +197,11 @@
 	/* Find all common service types */
 	service_type &= self->service_type;
 	if (!service_type) {
-		IRDA_DEBUG(2, __FUNCTION__
-			   "(), No common service type to use!\n");
+		IRDA_DEBUG(2, 
+			   "%s(), No common service type to use!\n", __FUNCTION__ );
 		return -1;
 	}
-	IRDA_DEBUG(0, __FUNCTION__ "(), services in common=%02x\n",
+	IRDA_DEBUG(0, "%s(), services in common=%02x\n", __FUNCTION__ ,
 		   service_type);
 
 	/*
@@ -216,7 +216,7 @@
 	else if (service_type & IRCOMM_3_WIRE_RAW)
 		self->settings.service_type = IRCOMM_3_WIRE_RAW;
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), resulting service type=0x%02x\n", 
+	IRDA_DEBUG(0, "%s(), resulting service type=0x%02x\n", __FUNCTION__ , 
 		   self->settings.service_type);
 
 	/* 
@@ -252,7 +252,7 @@
 	else {
 		self->settings.port_type = (__u8) param->pv.i;
 
-		IRDA_DEBUG(0, __FUNCTION__ "(), port type=%d\n", 
+		IRDA_DEBUG(0, "%s(), port type=%d\n", __FUNCTION__ , 
 			   self->settings.port_type);
 	}
 	return 0;
@@ -272,9 +272,9 @@
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
 	if (get) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), not imp!\n");
+		IRDA_DEBUG(0, "%s(), not imp!\n", __FUNCTION__ );
 	} else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), port-name=%s\n", param->pv.c);
+		IRDA_DEBUG(0, "%s(), port-name=%s\n", __FUNCTION__ , param->pv.c);
 		strncpy(self->settings.port_name, param->pv.c, 32);
 	}
 
@@ -299,7 +299,7 @@
 	else
 		self->settings.data_rate = param->pv.i;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), data rate = %d\n", param->pv.i);
+	IRDA_DEBUG(2, "%s(), data rate = %d\n", __FUNCTION__ , param->pv.i);
 
 	return 0;
 }
@@ -345,7 +345,7 @@
 	else
 		self->settings.flow_control = (__u8) param->pv.i;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), flow control = 0x%02x\n", (__u8) param->pv.i);
+	IRDA_DEBUG(1, "%s(), flow control = 0x%02x\n", __FUNCTION__ , (__u8) param->pv.i);
 
 	return 0;
 }
@@ -371,7 +371,7 @@
 		self->settings.xonxoff[1] = (__u16) param->pv.i >> 8;
 	}
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), XON/XOFF = 0x%02x,0x%02x\n", 
+	IRDA_DEBUG(0, "%s(), XON/XOFF = 0x%02x,0x%02x\n", __FUNCTION__ , 
 		   param->pv.i & 0xff, param->pv.i >> 8);
 
 	return 0;
@@ -398,7 +398,7 @@
 		self->settings.enqack[1] = (__u16) param->pv.i >> 8;
 	}
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), ENQ/ACK = 0x%02x,0x%02x\n",
+	IRDA_DEBUG(0, "%s(), ENQ/ACK = 0x%02x,0x%02x\n", __FUNCTION__ ,
 		   param->pv.i & 0xff, param->pv.i >> 8);
 
 	return 0;
@@ -413,7 +413,7 @@
 static int ircomm_param_line_status(void *instance, irda_param_t *param, 
 				    int get)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(), not impl.\n");
+	IRDA_DEBUG(2, "%s(), not impl.\n", __FUNCTION__ );
 
 	return 0;
 }
@@ -472,7 +472,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 	__u8 dce;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), dce = 0x%02x\n", (__u8) param->pv.i);
+	IRDA_DEBUG(1, "%s(), dce = 0x%02x\n", __FUNCTION__ , (__u8) param->pv.i);
 
 	dce = (__u8) param->pv.i;
 
@@ -484,7 +484,7 @@
 	/* Check if any of the settings have changed */
 	if (dce & 0x0f) {
 		if (dce & IRCOMM_DELTA_CTS) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), CTS \n");
+			IRDA_DEBUG(2, "%s(), CTS \n", __FUNCTION__ );
 		}
 	}
 
diff -Nru a/net/irda/ircomm/ircomm_ttp.c b/net/irda/ircomm/ircomm_ttp.c
--- a/net/irda/ircomm/ircomm_ttp.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/ircomm/ircomm_ttp.c	Fri Sep 27 14:51:05 2002
@@ -49,7 +49,7 @@
 {
 	notify_t notify;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	/* Register callbacks */
 	irda_notify_init(&notify);
@@ -64,7 +64,7 @@
 	self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
 				     &notify);
 	if (!self->tsap) {
-		IRDA_DEBUG(0, __FUNCTION__"failed to allocate tsap\n");
+		IRDA_DEBUG(0, "%sfailed to allocate tsap\n", __FUNCTION__ );
 		return -1;
 	}
 	self->slsap_sel = self->tsap->stsap_sel;
@@ -92,7 +92,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ret = irttp_connect_request(self->tsap, info->dlsap_sel,
 				    info->saddr, info->daddr, NULL, 
@@ -110,7 +110,7 @@
 {
 	int ret;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ret = irttp_connect_response(self->tsap, TTP_SAR_DISABLE, skb);
 
@@ -133,7 +133,7 @@
 
 	ASSERT(skb != NULL, return -1;);
 
-	IRDA_DEBUG(2, __FUNCTION__"(), clen=%d\n", clen);
+	IRDA_DEBUG(2, "%s(), clen=%d\n", __FUNCTION__ , clen);
 
 	/* 
 	 * Insert clen field, currently we either send data only, or control
@@ -164,7 +164,7 @@
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -184,7 +184,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -221,7 +221,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *)instance;
 	struct ircomm_info info;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -272,7 +272,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -292,7 +292,7 @@
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
diff -Nru a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
--- a/net/irda/ircomm/ircomm_tty.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/ircomm/ircomm_tty.c	Fri Sep 27 14:51:03 2002
@@ -143,7 +143,7 @@
 
 static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -164,7 +164,7 @@
 {
 	int ret;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");	
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );	
 
 	ret = tty_unregister_driver(&driver);
         if (ret) {
@@ -186,14 +186,14 @@
 	notify_t notify;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
 	/* Already open */
 	if (self->flags & ASYNC_INITIALIZED) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), already open so break out!\n");
+		IRDA_DEBUG(2, "%s(), already open so break out!\n", __FUNCTION__ );
 		return 0;
 	}
 
@@ -247,7 +247,7 @@
 	unsigned long	flags;
 	struct tty_struct *tty;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	tty = self->tty;
 
@@ -279,18 +279,18 @@
 			return -EBUSY;
 		self->flags |= ASYNC_NORMAL_ACTIVE;
 
-		IRDA_DEBUG(1, __FUNCTION__ "(), O_NONBLOCK requested!\n");
+		IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __FUNCTION__ );
 		return 0;
 	}
 
 	if (self->flags & ASYNC_CALLOUT_ACTIVE) {
 		if (self->normal_termios.c_cflag & CLOCAL) {
-			IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
+			IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __FUNCTION__ );
 			do_clocal = 1;
 		}
 	} else {
 		if (tty->termios->c_cflag & CLOCAL) {
-			IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
+			IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __FUNCTION__ );
 			do_clocal = 1;
 		}
 	}
@@ -395,7 +395,7 @@
 	unsigned long	flags;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	MOD_INC_USE_COUNT;
 	line = minor(tty->device) - tty->driver.minor_start;
@@ -452,7 +452,7 @@
 	self->tty = tty;
 	spin_unlock_irqrestore(&self->spinlock, flags);
 
-	IRDA_DEBUG(1, __FUNCTION__"(), %s%d, count = %d\n", tty->driver.name, 
+	IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __FUNCTION__ , tty->driver.name, 
 		   self->line, self->open_count);
 
 	/* Not really used by us, but lets do it anyway */
@@ -492,9 +492,9 @@
 		self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
 		self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */
 		self->settings.dce = IRCOMM_CTS | IRCOMM_CD; /* Default line settings */
-		IRDA_DEBUG(2, __FUNCTION__ "(), IrCOMM device\n");
+		IRDA_DEBUG(2, "%s(), IrCOMM device\n", __FUNCTION__ );
 	} else {
-		IRDA_DEBUG(2, __FUNCTION__ "(), IrLPT device\n");
+		IRDA_DEBUG(2, "%s(), IrLPT device\n", __FUNCTION__ );
 		self->service_type = IRCOMM_3_WIRE_RAW;
 		self->settings.service_type = IRCOMM_3_WIRE_RAW; /* Default */
 	}
@@ -506,8 +506,8 @@
 	ret = ircomm_tty_block_til_ready(self, filp);
 	if (ret) {
 		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
-		IRDA_DEBUG(2, __FUNCTION__ 
-		      "(), returning after block_til_ready with %d\n",
+		IRDA_DEBUG(2, 
+		      "%s(), returning after block_til_ready with %d\n", __FUNCTION__ ,
 		      ret);
 
 		return ret;
@@ -530,7 +530,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned long flags;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	if (!tty)
 		return;
@@ -544,7 +544,7 @@
 		MOD_DEC_USE_COUNT;
 		spin_unlock_irqrestore(&self->spinlock, flags);
 
-		IRDA_DEBUG(0, __FUNCTION__ "(), returning 1\n");
+		IRDA_DEBUG(0, "%s(), returning 1\n", __FUNCTION__ );
 		return;
 	}
 
@@ -556,8 +556,8 @@
 		 * one, we've got real problems, since it means the
 		 * serial port won't be shutdown.
 		 */
-		IRDA_DEBUG(0, __FUNCTION__ "(), bad serial port count; "
-			   "tty->count is 1, state->count is %d\n", 
+		IRDA_DEBUG(0, "%s(), bad serial port count; "
+			   "tty->count is 1, state->count is %d\n", __FUNCTION__ , 
 			   self->open_count);
 		self->open_count = 1;
 	}
@@ -571,7 +571,7 @@
 		MOD_DEC_USE_COUNT;
 		spin_unlock_irqrestore(&self->spinlock, flags);
 
-		IRDA_DEBUG(0, __FUNCTION__ "(), open count > 0\n");
+		IRDA_DEBUG(0, "%s(), open count > 0\n", __FUNCTION__ );
 		return;
 	}
 	self->flags |= ASYNC_CLOSING;
@@ -650,7 +650,7 @@
 	unsigned long flags;
 	struct sk_buff *skb, *ctrl_skb;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	if (!self || self->magic != IRCOMM_TTY_MAGIC)
 		return;
@@ -713,7 +713,7 @@
 	int len = 0;
 	int size;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), count=%d, hw_stopped=%d\n", count,
+	IRDA_DEBUG(2, "%s(), count=%d, hw_stopped=%d\n", __FUNCTION__ , count,
 		   tty->hw_stopped);
 
 	ASSERT(self != NULL, return -1;);
@@ -729,7 +729,7 @@
 	 * Jean II */
 	if (self->max_header_size == IRCOMM_TTY_HDR_UNITIALISED) {
 		/* TTY will retry */
-		IRDA_DEBUG(2, __FUNCTION__ "() : not initialised\n");
+		IRDA_DEBUG(2, "%s() : not initialised\n", __FUNCTION__ );
 		return len;
 	}
 
@@ -843,7 +843,7 @@
 			ret = self->max_data_size;
 		spin_unlock_irqrestore(&self->spinlock, flags);
 	}
-	IRDA_DEBUG(2, __FUNCTION__ "(), ret=%d\n", ret);
+	IRDA_DEBUG(2, "%s(), ret=%d\n", __FUNCTION__ , ret);
 
 	return ret;
 }
@@ -859,7 +859,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned long orig_jiffies, poll_time;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -891,7 +891,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -922,7 +922,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -937,7 +937,7 @@
 		self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS);
 
 		ircomm_param_request(self, IRCOMM_DTE, TRUE);
-		IRDA_DEBUG(1, __FUNCTION__"(), FLOW_START\n");
+		IRDA_DEBUG(1, "%s(), FLOW_START\n", __FUNCTION__ );
 	}
         ircomm_flow_request(self->ircomm, FLOW_START);
 }
@@ -974,7 +974,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 	
 	if (!(self->flags & ASYNC_INITIALIZED))
 		return;
@@ -1018,7 +1018,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned long	flags;
 
-	IRDA_DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -1047,7 +1047,7 @@
  */
 static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch)
 {
-	IRDA_DEBUG(0, __FUNCTION__"(), not impl\n");
+	IRDA_DEBUG(0, "%s(), not impl\n", __FUNCTION__ );
 }
 
 /*
@@ -1091,7 +1091,7 @@
 	struct tty_struct *tty;
 	int status;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -1104,8 +1104,8 @@
 		/*wake_up_interruptible(&self->delta_msr_wait);*/
 	}
 	if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
-		IRDA_DEBUG(2, __FUNCTION__ 
-			   "(), ircomm%d CD now %s...\n", self->line,
+		IRDA_DEBUG(2, 
+			   "%s(), ircomm%d CD now %s...\n", __FUNCTION__ , self->line,
 			   (status & IRCOMM_CD) ? "on" : "off");
 
 		if (status & IRCOMM_CD) {
@@ -1113,8 +1113,8 @@
 		} else if (!((self->flags & ASYNC_CALLOUT_ACTIVE) &&
 			   (self->flags & ASYNC_CALLOUT_NOHUP))) 
 		{
-			IRDA_DEBUG(2, __FUNCTION__ 
-				   "(), Doing serial hangup..\n");
+			IRDA_DEBUG(2, 
+				   "%s(), Doing serial hangup..\n", __FUNCTION__ );
 			if (tty)
 				tty_hangup(tty);
 
@@ -1125,8 +1125,8 @@
 	if (self->flags & ASYNC_CTS_FLOW) {
 		if (tty->hw_stopped) {
 			if (status & IRCOMM_CTS) {
-				IRDA_DEBUG(2, __FUNCTION__ 
-					   "(), CTS tx start...\n");
+				IRDA_DEBUG(2, 
+					   "%s(), CTS tx start...\n", __FUNCTION__ );
 				tty->hw_stopped = 0;
 				
 				/* Wake up processes blocked on open */
@@ -1138,8 +1138,8 @@
 			}
 		} else {
 			if (!(status & IRCOMM_CTS)) {
-				IRDA_DEBUG(2, __FUNCTION__ 
-					   "(), CTS tx stop...\n");
+				IRDA_DEBUG(2, 
+					   "%s(), CTS tx stop...\n", __FUNCTION__ );
 				tty->hw_stopped = 1;
 			}
 		}
@@ -1157,14 +1157,14 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 	ASSERT(skb != NULL, return -1;);
 
 	if (!self->tty) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), no tty!\n");
+		IRDA_DEBUG(0, "%s(), no tty!\n", __FUNCTION__ );
 		dev_kfree_skb(skb);
 		return 0;
 	}
@@ -1176,7 +1176,7 @@
 	 * params, we can just as well declare the hardware for running.
 	 */
 	if (self->tty->hw_stopped && (self->flow == FLOW_START)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), polling for line settings!\n");
+		IRDA_DEBUG(0, "%s(), polling for line settings!\n", __FUNCTION__ );
 		ircomm_param_request(self, IRCOMM_POLL, TRUE);
 
 		/* We can just as well declare the hardware for running */
@@ -1207,7 +1207,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 	int clen;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
@@ -1242,7 +1242,7 @@
 
 	switch (cmd) {
 	case FLOW_START:
-		IRDA_DEBUG(2, __FUNCTION__ "(), hw start!\n");
+		IRDA_DEBUG(2, "%s(), hw start!\n", __FUNCTION__ );
 		tty->hw_stopped = 0;
 
 		/* ircomm_tty_do_softint will take care of the rest */
@@ -1251,7 +1251,7 @@
 		break;
 	default:  /* If we get here, something is very wrong, better stop */
 	case FLOW_STOP:
-		IRDA_DEBUG(2, __FUNCTION__ "(), hw stopped!\n");
+		IRDA_DEBUG(2, "%s(), hw stopped!\n", __FUNCTION__ );
 		tty->hw_stopped = 1;
 		break;
 	}
diff -Nru a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
--- a/net/irda/ircomm/ircomm_tty_attach.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/ircomm/ircomm_tty_attach.c	Fri Sep 27 14:51:05 2002
@@ -126,14 +126,14 @@
  */
 int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
        	/* Check if somebody has already connected to us */
 	if (ircomm_is_connected(self->ircomm)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), already connected!\n");
+		IRDA_DEBUG(0, "%s(), already connected!\n", __FUNCTION__ );
 		return 0;
 	}
 
@@ -144,7 +144,7 @@
 
 	/* Check if somebody has already connected to us */
 	if (ircomm_is_connected(self->ircomm)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), already connected!\n");
+		IRDA_DEBUG(0, "%s(), already connected!\n", __FUNCTION__ );
 		return 0;
 	}
 
@@ -161,7 +161,7 @@
  */
 void ircomm_tty_detach_cable(struct ircomm_tty_cb *self)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -203,7 +203,7 @@
 	__u8 oct_seq[6];
 	__u16 hints;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -258,16 +258,16 @@
 	 * Set default values, but only if the application for some reason 
 	 * haven't set them already
 	 */
-	IRDA_DEBUG(2, __FUNCTION__ "(), data-rate = %d\n", 
+	IRDA_DEBUG(2, "%s(), data-rate = %d\n", __FUNCTION__ , 
 		   self->settings.data_rate);
 	if (!self->settings.data_rate)
 		self->settings.data_rate = 9600;
-	IRDA_DEBUG(2, __FUNCTION__ "(), data-format = %d\n", 
+	IRDA_DEBUG(2, "%s(), data-format = %d\n", __FUNCTION__ , 
 		   self->settings.data_format);
 	if (!self->settings.data_format)
 		self->settings.data_format = IRCOMM_WSIZE_8;  /* 8N1 */
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), flow-control = %d\n", 
+	IRDA_DEBUG(2, "%s(), flow-control = %d\n", __FUNCTION__ , 
 		   self->settings.flow_control);
 	/*self->settings.flow_control = IRCOMM_RTS_CTS_IN|IRCOMM_RTS_CTS_OUT;*/
 
@@ -312,7 +312,7 @@
 	struct ircomm_tty_cb *self;
 	struct ircomm_tty_info info;
 
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	/* Important note :
 	 * We need to drop all passive discoveries.
@@ -356,7 +356,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -386,7 +386,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) priv;
 
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -397,13 +397,13 @@
 
 	/* Check if request succeeded */
 	if (result != IAS_SUCCESS) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), got NULL value!\n");
+		IRDA_DEBUG(4, "%s(), got NULL value!\n", __FUNCTION__ );
 		return;
 	}
 
 	switch (value->type) {
  	case IAS_OCT_SEQ:
-		IRDA_DEBUG(2, __FUNCTION__"(), got octet sequence\n");
+		IRDA_DEBUG(2, "%s(), got octet sequence\n", __FUNCTION__ );
 
 		irda_param_extract_all(self, value->t.oct_seq, value->len,
 				       &ircomm_param_info);
@@ -413,21 +413,21 @@
 		break;
 	case IAS_INTEGER:
 		/* Got LSAP selector */	
-		IRDA_DEBUG(2, __FUNCTION__"(), got lsapsel = %d\n", 
+		IRDA_DEBUG(2, "%s(), got lsapsel = %d\n", __FUNCTION__ , 
 			   value->t.integer);
 
 		if (value->t.integer == -1) {
-			IRDA_DEBUG(0, __FUNCTION__"(), invalid value!\n");
+			IRDA_DEBUG(0, "%s(), invalid value!\n", __FUNCTION__ );
 		} else
 			self->dlsap_sel = value->t.integer;
 
 		ircomm_tty_do_event(self, IRCOMM_TTY_GOT_LSAPSEL, NULL, NULL);
 		break;
 	case IAS_MISSING:
-		IRDA_DEBUG(0, __FUNCTION__"(), got IAS_MISSING\n");
+		IRDA_DEBUG(0, "%s(), got IAS_MISSING\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__"(), got unknown type!\n");
+		IRDA_DEBUG(0, "%s(), got unknown type!\n", __FUNCTION__ );
 		break;
 	}
 	irias_delete_value(value);
@@ -447,7 +447,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -478,7 +478,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 	int clen;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -507,7 +507,7 @@
  */
 void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -524,10 +524,10 @@
 	 * line.  
 	 */
 	if ((self->flags & ASYNC_CTS_FLOW) && ((self->settings.dce & IRCOMM_CTS) == 0)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), waiting for CTS ...\n");
+		IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __FUNCTION__ );
 		return;
 	} else {
-		IRDA_DEBUG(2, __FUNCTION__ "(), starting hardware!\n");
+		IRDA_DEBUG(2, "%s(), starting hardware!\n", __FUNCTION__ );
 
 		self->tty->hw_stopped = 0;
 	
@@ -565,7 +565,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -586,7 +586,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+	IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
 		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 	switch (event) {
 	case IRCOMM_TTY_ATTACH_CABLE:
@@ -629,7 +629,7 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
@@ -649,7 +649,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+	IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
 		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
@@ -700,7 +700,7 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
@@ -720,7 +720,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+	IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
 		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
@@ -756,7 +756,7 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
@@ -776,7 +776,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+	IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
 		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
@@ -804,7 +804,7 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
@@ -824,7 +824,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+	IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
 		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
@@ -856,7 +856,7 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
@@ -893,13 +893,13 @@
 			self->settings.dce = IRCOMM_DELTA_CD;
 			ircomm_tty_check_modem_status(self);
 		} else {
-			IRDA_DEBUG(0, __FUNCTION__ "(), hanging up!\n");
+			IRDA_DEBUG(0, "%s(), hanging up!\n", __FUNCTION__ );
 			if (self->tty)
 				tty_hangup(self->tty);
 		}
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+		IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
 			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
@@ -918,7 +918,7 @@
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
-	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+	IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
 		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 	
 	return (*state[self->state])(self, event, skb, info);
@@ -937,7 +937,7 @@
 
 	self->state = state;
 	
-	IRDA_DEBUG(2, __FUNCTION__": next state=%s, service type=%d\n", 
+	IRDA_DEBUG(2, "%s: next state=%s, service type=%d\n", __FUNCTION__ , 
 		   ircomm_tty_state[self->state], self->service_type);
 }
 
diff -Nru a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
--- a/net/irda/ircomm/ircomm_tty_ioctl.c	Fri Sep 27 14:51:02 2002
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c	Fri Sep 27 14:51:02 2002
@@ -58,7 +58,7 @@
 	unsigned cflag, cval;
 	int baud;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	if (!self->tty || !self->tty->termios || !self->ircomm)
 		return;
@@ -151,7 +151,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned int cflag = tty->termios->c_cflag;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	if ((cflag == old_termios->c_cflag) && 
 	    (RELEVANT_IFLAG(tty->termios->c_iflag) == 
@@ -200,7 +200,7 @@
 {
 	unsigned int result;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	result =  ((self->settings.dte & IRCOMM_RTS) ? TIOCM_RTS : 0)
 		| ((self->settings.dte & IRCOMM_DTR) ? TIOCM_DTR : 0)
@@ -224,7 +224,7 @@
 	unsigned int arg;
 	__u8 old_rts, old_dtr;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
@@ -286,7 +286,7 @@
 	if (!retinfo)
 		return -EFAULT;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	memset(&info, 0, sizeof(info));
 	info.line = self->line;
@@ -322,7 +322,7 @@
 	struct serial_struct new_serial;
 	struct ircomm_tty_cb old_state, *state;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
 		return -EFAULT;
@@ -396,7 +396,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	int ret = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
 	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
@@ -425,7 +425,7 @@
 		break;
 
 	case TIOCGICOUNT:
-		IRDA_DEBUG(0, __FUNCTION__ "(), TIOCGICOUNT not impl!\n");
+		IRDA_DEBUG(0, "%s(), TIOCGICOUNT not impl!\n", __FUNCTION__ );
 #if 0
 		save_flags(flags); cli();
 		cnow = driver->icount;
diff -Nru a/net/irda/irda_device.c b/net/irda/irda_device.c
--- a/net/irda/irda_device.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irda_device.c	Fri Sep 27 14:51:04 2002
@@ -111,7 +111,7 @@
 
 void __exit irda_device_cleanup(void)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	hashbin_delete(tasks, (FREE_FUNC) __irda_task_delete);
 	hashbin_delete(dongles, NULL);
@@ -127,7 +127,7 @@
 {
 	struct irlap_cb *self;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(%s)\n", status ? "TRUE" : "FALSE");
+	IRDA_DEBUG(4, "%s(%s)\n", __FUNCTION__, status ? "TRUE" : "FALSE");
 
 	self = (struct irlap_cb *) dev->atalk_ptr;
 
@@ -152,7 +152,7 @@
 	struct if_irda_req req;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	if (!dev->do_ioctl) {
 		ERROR("%s: do_ioctl not impl. by device driver\n",
@@ -173,7 +173,7 @@
 	struct if_irda_req req;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	if (!dev->do_ioctl) {
 		ERROR("%s: do_ioctl not impl. by device driver\n",
@@ -199,7 +199,7 @@
 	struct if_irda_req req;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	if (!dev->do_ioctl) {
 		ERROR("%s: do_ioctl not impl. by device driver\n",
@@ -216,7 +216,7 @@
 
 void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(), state = %s\n", task_state[state]);
+	IRDA_DEBUG(2, "%s(), state = %s\n", __FUNCTION__, task_state[state]);
 
 	task->state = state;
 }
@@ -250,7 +250,7 @@
 	int count = 0;
 	int timeout;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(task != NULL, return -1;);
 	ASSERT(task->magic == IRDA_TASK_MAGIC, return -1;);
@@ -298,8 +298,8 @@
 				 irda_task_timer_expired);
 		finished = FALSE;
 	} else {
-		IRDA_DEBUG(0, __FUNCTION__
-			   "(), not finished, and no timeout!\n");
+		IRDA_DEBUG(0, "%s(), not finished, and no timeout!\n",
+			   __FUNCTION__);
 		finished = FALSE;
 	}
 
@@ -328,7 +328,7 @@
 	struct irda_task *task;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	task = kmalloc(sizeof(struct irda_task), GFP_ATOMIC);
 	if (!task)
@@ -365,7 +365,7 @@
 {
 	struct irda_task *task;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	task = (struct irda_task *) data;
 
@@ -517,7 +517,7 @@
 	struct if_irda_req req;
 	int ret;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
 	if (!dev->do_ioctl) {
 		ERROR("%s: set_raw_mode not impl. by device driver\n",
diff -Nru a/net/irda/iriap.c b/net/irda/iriap.c
--- a/net/irda/iriap.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/iriap.c	Fri Sep 27 14:51:03 2002
@@ -128,7 +128,7 @@
 	 */
 	server = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
 	if (!server) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), unable to open server\n");
+		IRDA_DEBUG(0, "%s(), unable to open server\n", __FUNCTION__);
 		return -1;
 	}
 	iriap_register_lsap(server, LSAP_IAS, IAS_SERVER);
@@ -160,7 +160,7 @@
 {
 	struct iriap_cb *self;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	self = kmalloc(sizeof(struct iriap_cb), GFP_ATOMIC);
 	if (!self) {
@@ -202,7 +202,7 @@
  */
 static void __iriap_close(struct iriap_cb *self)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -226,7 +226,7 @@
 {
 	struct iriap_cb *entry;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -246,7 +246,7 @@
 {
 	notify_t notify;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	irda_notify_init(&notify);
 	notify.connect_confirm       = iriap_connect_confirm;
@@ -281,7 +281,7 @@
 {
 	struct iriap_cb *self;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]);
+	IRDA_DEBUG(4, "%s(), reason=%s\n", __FUNCTION__, lmp_reasons[reason]);
 
 	self = (struct iriap_cb *) instance;
 
@@ -293,7 +293,7 @@
 	del_timer(&self->watchdog_timer);
 
 	if (self->mode == IAS_CLIENT) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), disconnect as client\n");
+		IRDA_DEBUG(4, "%s(), disconnect as client\n", __FUNCTION__);
 
 
 		iriap_do_client_event(self, IAP_LM_DISCONNECT_INDICATION,
@@ -306,7 +306,7 @@
 		if (self->confirm)
 			self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
 	} else {
-		IRDA_DEBUG(4, __FUNCTION__ "(), disconnect as server\n");
+		IRDA_DEBUG(4, "%s(), disconnect as server\n", __FUNCTION__);
 		iriap_do_server_event(self, IAP_LM_DISCONNECT_INDICATION,
 				      NULL);
 		iriap_close(self);
@@ -323,15 +323,15 @@
 {
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
 
 	skb = dev_alloc_skb(64);
 	if (skb == NULL) {
-		IRDA_DEBUG(0, __FUNCTION__
-		      "(), Could not allocate an sk_buff of length %d\n", 64);
+		IRDA_DEBUG(0, "%s(), Could not allocate an sk_buff of length %d\n", 
+			__FUNCTION__, 64);
 		return;
 	}
 
@@ -345,27 +345,27 @@
 
 void iriap_getinfobasedetails_request(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
+	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
 }
 
 void iriap_getinfobasedetails_confirm(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
+	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
 }
 
 void iriap_getobjects_request(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
+	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
 }
 
 void iriap_getobjects_confirm(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
+	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
 }
 
 void iriap_getvalue(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n");
+	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
 }
 
 /*
@@ -455,13 +455,13 @@
 	/* Get length, MSB first */
 	len = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len);
+	IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
 
 	/* Get object ID, MSB first */
 	obj_id = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2;
 
 	type = fp[n++];
-	IRDA_DEBUG(4, __FUNCTION__ "(), Value type = %d\n", type);
+	IRDA_DEBUG(4, "%s(), Value type = %d\n", __FUNCTION__, type);
 
 	switch (type) {
 	case IAS_INTEGER:
@@ -470,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, "%s(), lsap=%d\n", __FUNCTION__, value->t.integer);
 		break;
 	case IAS_STRING:
 		charset = fp[n++];
@@ -489,9 +489,8 @@
 /*		case CS_ISO_8859_9: */
 /*		case CS_UNICODE: */
 		default:
-			IRDA_DEBUG(0, __FUNCTION__
-				   "(), charset %s, not supported\n",
-				   ias_charset_types[charset]);
+			IRDA_DEBUG(0, "%s(), charset %s, not supported\n",
+				   __FUNCTION__, ias_charset_types[charset]);
 
 			/* Aborting, close connection! */
 			iriap_disconnect_request(self);
@@ -500,7 +499,7 @@
 			/* break; */
 		}
 		value_len = fp[n++];
-		IRDA_DEBUG(4, __FUNCTION__ "(), strlen=%d\n", value_len);
+		IRDA_DEBUG(4, "%s(), strlen=%d\n", __FUNCTION__, value_len);
 
 		/* Make sure the string is null-terminated */
 		fp[n+value_len] = 0x00;
@@ -530,7 +529,7 @@
 	if (self->confirm)
 		self->confirm(IAS_SUCCESS, obj_id, value, self->priv);
 	else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), missing handler!\n");
+		IRDA_DEBUG(0, "%s(), missing handler!\n", __FUNCTION__);
 		irias_delete_value(value);
 	}
 	dev_kfree_skb(skb);
@@ -550,7 +549,7 @@
 	__u32 tmp_be32, tmp_be16;
 	__u8 *fp;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -611,12 +610,12 @@
 		memcpy(fp+n, value->t.oct_seq, value->len); n+=value->len;
 		break;
 	case IAS_MISSING:
-		IRDA_DEBUG( 3, __FUNCTION__ ": sending IAS_MISSING\n");
+		IRDA_DEBUG( 3, "%s: sending IAS_MISSING\n", __FUNCTION__);
 		skb_put(skb, 1);
 		fp[n++] = value->type;
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), type not implemented!\n");
+		IRDA_DEBUG(0, "%s(), type not implemented!\n", __FUNCTION__);
 		break;
 	}
 	iriap_do_r_connect_event(self, IAP_CALL_RESPONSE, skb);
@@ -640,7 +639,7 @@
 	__u8 *fp;
 	int n;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -697,7 +696,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -728,7 +727,7 @@
 				    self->saddr, self->daddr,
 				    NULL, NULL);
 	if (ret < 0) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n");
+		IRDA_DEBUG(0, "%s(), connect failed!\n", __FUNCTION__);
 		self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
 	}
 }
@@ -773,7 +772,7 @@
 {
 	struct iriap_cb *self, *new;
 
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
 	self = (struct iriap_cb *) instance;
 
@@ -783,7 +782,7 @@
 	/* Start new server */
 	new = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
 	if (!new) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), open failed\n");
+		IRDA_DEBUG(0, "%s(), open failed\n", __FUNCTION__);
 		dev_kfree_skb(userdata);
 		return;
 	}
@@ -791,7 +790,7 @@
 	/* Now attach up the new "socket" */
 	new->lsap = irlmp_dup(self->lsap, new);
 	if (!new->lsap) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), dup failed!\n");
+		IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__);
 		return;
 	}
 
@@ -817,7 +816,7 @@
 	__u8  *frame;
 	__u8  opcode;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	self = (struct iriap_cb *) instance;
 
@@ -830,7 +829,7 @@
 
 	if (self->mode == IAS_SERVER) {
 		/* Call server */
-		IRDA_DEBUG(4, __FUNCTION__ "(), Calling server!\n");
+		IRDA_DEBUG(4, "%s(), Calling server!\n", __FUNCTION__);
 		iriap_do_r_connect_event(self, IAP_RECV_F_LST, skb);
 
 		return 0;
@@ -845,7 +844,7 @@
 
 	/* Check for ack frames since they don't contain any data */
 	if (opcode & IAP_ACK) {
-		IRDA_DEBUG(0, __FUNCTION__ "() Got ack frame!\n");
+		IRDA_DEBUG(0, "%s() Got ack frame!\n", __FUNCTION__);
 		dev_kfree_skb(skb);
 		return 0;
 	}
@@ -865,7 +864,7 @@
 			iriap_getvaluebyclass_confirm(self, skb);
 			break;
 		case IAS_CLASS_UNKNOWN:
-			IRDA_DEBUG(1, __FUNCTION__ "(), No such class!\n");
+			IRDA_DEBUG(1, "%s(), No such class!\n", __FUNCTION__);
 			/* Finished, close connection! */
 			iriap_disconnect_request(self);
 
@@ -879,7 +878,7 @@
 			dev_kfree_skb(skb);
 			break;
 		case IAS_ATTRIB_UNKNOWN:
-			IRDA_DEBUG(1, __FUNCTION__ "(), No such attribute!\n");
+			IRDA_DEBUG(1, "%s(), No such attribute!\n", __FUNCTION__);
 			/* Finished, close connection! */
 			iriap_disconnect_request(self);
 
@@ -895,7 +894,7 @@
 		}
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown op-code: %02x\n",
+		IRDA_DEBUG(0, "%s(), Unknown op-code: %02x\n", __FUNCTION__,
 			   opcode);
 		dev_kfree_skb(skb);
 		break;
@@ -914,7 +913,7 @@
 	__u8 *fp;
 	__u8 opcode;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
@@ -1021,8 +1020,8 @@
 				len += sprintf(buf+len, "missing\n");
 				break;
 			default:
-				IRDA_DEBUG(0, __FUNCTION__
-				      "(), Unknown value type!\n");
+				IRDA_DEBUG(0, "%s(), Unknown value type!\n",
+					   __FUNCTION__);
 				return -1;
 			}
 			len += sprintf(buf+len, "\n");
diff -Nru a/net/irda/iriap_event.c b/net/irda/iriap_event.c
--- a/net/irda/iriap_event.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/iriap_event.c	Fri Sep 27 14:51:05 2002
@@ -181,7 +181,7 @@
 	case IAP_LM_DISCONNECT_INDICATION:
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__"(), Unknown event %d\n", event);
+		IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
 		break;
 	}
 }
@@ -213,7 +213,7 @@
 		iriap_next_client_state(self, S_DISCONNECT);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
 		break;
 	}
 }
@@ -262,7 +262,7 @@
 		iriap_next_call_state(self, S_OUTSTANDING);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -278,7 +278,7 @@
 static void state_s_calling(struct iriap_cb *self, IRIAP_EVENT event,
 			    struct sk_buff *skb)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
 }
 
 /*
@@ -300,7 +300,7 @@
 		iriap_next_call_state(self, S_WAIT_FOR_CALL);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
 		break;
 	}
 }
@@ -313,7 +313,7 @@
 static void state_s_replying(struct iriap_cb *self, IRIAP_EVENT event,
 			     struct sk_buff *skb)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
 }
 
 /*
@@ -325,7 +325,7 @@
 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");
+	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
 }
 
 
@@ -338,7 +338,7 @@
 static void state_s_wait_active(struct iriap_cb *self, IRIAP_EVENT event,
 				struct sk_buff *skb)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
 }
 
 /**************************************************************************
@@ -385,7 +385,7 @@
 
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event %d\n", event);
+		IRDA_DEBUG(0, "%s(), unknown event %d\n", __FUNCTION__, event);
 		break;
 	}
 }
@@ -396,7 +396,7 @@
 static void state_r_call(struct iriap_cb *self, IRIAP_EVENT event,
 			 struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	switch (event) {
 	case IAP_LM_DISCONNECT_INDICATION:
@@ -405,7 +405,7 @@
 		iriap_next_r_connect_state(self, R_WAITING);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event!\n");
+		IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__);
 		break;
 	}
 }
@@ -420,13 +420,13 @@
 static void state_r_waiting(struct iriap_cb *self, IRIAP_EVENT event,
 			    struct sk_buff *skb)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
 }
 
 static void state_r_wait_active(struct iriap_cb *self, IRIAP_EVENT event,
 				struct sk_buff *skb)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
 }
 
 /*
@@ -438,7 +438,7 @@
 static void state_r_receiving(struct iriap_cb *self, IRIAP_EVENT event,
 			      struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	switch (event) {
 	case IAP_RECV_F_LST:
@@ -447,7 +447,7 @@
 		iriap_call_indication(self, skb);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event!\n");
+		IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__);
 		break;
 	}
 
@@ -462,12 +462,12 @@
 static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event,
 			    struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(skb != NULL, return;);
 
 	if (!self || self->magic != IAS_MAGIC) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), bad pointer self\n");
+		IRDA_DEBUG(0, "%s(), bad pointer self\n", __FUNCTION__);
 		return;
 	}
 
@@ -482,7 +482,7 @@
 		irlmp_data_request(self->lsap, skb);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event!\n");
+		IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__);
 		break;
 	}
 }
@@ -490,7 +490,7 @@
 static void state_r_returning(struct iriap_cb *self, IRIAP_EVENT event,
 			      struct sk_buff *skb)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), event=%d\n", event);
+	IRDA_DEBUG(0, "%s(), event=%d\n", __FUNCTION__, event);
 
 	switch (event) {
 	case IAP_RECV_F_LST:
diff -Nru a/net/irda/irias_object.c b/net/irda/irias_object.c
--- a/net/irda/irias_object.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/irias_object.c	Fri Sep 27 14:51:03 2002
@@ -79,12 +79,13 @@
 {
         struct ias_object *obj;
 
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
 	obj = (struct ias_object *) kmalloc(sizeof(struct ias_object),
 					    GFP_ATOMIC);
 	if (obj == NULL) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unable to allocate object!\n");
+		IRDA_DEBUG(0, "%s(), Unable to allocate object!\n",
+			   __FUNCTION__);
 		return NULL;
 	}
 	memset(obj, 0, sizeof( struct ias_object));
@@ -295,8 +296,8 @@
 	}
 
 	if ( attrib->value->type != new_value->type) {
-		IRDA_DEBUG( 0, __FUNCTION__
-		       "(), changing value type not allowed!\n");
+		IRDA_DEBUG( 0, "%s(), changing value type not allowed!\n",
+			    __FUNCTION__);
 		spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
 		return -1;
 	}
@@ -521,7 +522,7 @@
  */
 void irias_delete_value(struct ias_value *value)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(value != NULL, return;);
 
@@ -541,7 +542,7 @@
 			 kfree(value->t.oct_seq);
 		 break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown value type!\n");
+		IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
 		break;
 	}
 	kfree(value);
diff -Nru a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
--- a/net/irda/irlan/irlan_client.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irlan/irlan_client.c	Fri Sep 27 14:51:04 2002
@@ -71,7 +71,7 @@
 {
 	struct irlan_cb *self = (struct irlan_cb *) data;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -90,7 +90,7 @@
 
 void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	irda_start_timer(&self->client.kick_timer, timeout, (void *) self, 
 			 irlan_client_kick_timer_expired);
@@ -104,7 +104,7 @@
  */
 void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -116,7 +116,7 @@
 	if ((self->client.state != IRLAN_IDLE) || 
 	    (self->provider.access_type == ACCESS_DIRECT))
 	{
-			IRDA_DEBUG(0, __FUNCTION__ "(), already awake!\n");
+			IRDA_DEBUG(0, "%s(), already awake!\n", __FUNCTION__ );
 			return;
 	}
 
@@ -125,7 +125,7 @@
 	self->daddr = daddr;
 
 	if (self->disconnect_reason == LM_USER_REQUEST) {
-			IRDA_DEBUG(0, __FUNCTION__ "(), still stopped by user\n");
+			IRDA_DEBUG(0, "%s(), still stopped by user\n", __FUNCTION__ );
 			return;
 	}
 
@@ -152,7 +152,7 @@
 	struct irlan_cb *self;
 	__u32 saddr, daddr;
 	
-	IRDA_DEBUG(1, __FUNCTION__"()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__ );
 
 	ASSERT(irlan != NULL, return;);
 	ASSERT(discovery != NULL, return;);
@@ -174,7 +174,7 @@
 	if (self) {
 		ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-		IRDA_DEBUG(1, __FUNCTION__ "(), Found instance (%08x)!\n",
+		IRDA_DEBUG(1, "%s(), Found instance (%08x)!\n", __FUNCTION__ ,
 		      daddr);
 		
 		irlan_client_wakeup(self, saddr, daddr);
@@ -192,7 +192,7 @@
 {
 	struct irlan_cb *self;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	
 	self = (struct irlan_cb *) instance;
 	
@@ -203,7 +203,7 @@
 	irlan_do_client_event(self, IRLAN_DATA_INDICATION, skb); 
 
 	/* Ready for a new command */	
-	IRDA_DEBUG(2, __FUNCTION__ "(), clearing tx_busy\n");
+	IRDA_DEBUG(2, "%s(), clearing tx_busy\n", __FUNCTION__ );
 	self->client.tx_busy = FALSE;
 
 	/* Check if we have some queued commands waiting to be sent */
@@ -220,7 +220,7 @@
 	struct tsap_cb *tsap;
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), reason=%d\n", reason);
+	IRDA_DEBUG(4, "%s(), reason=%d\n", __FUNCTION__ , reason);
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -252,7 +252,7 @@
 	struct tsap_cb *tsap;
 	notify_t notify;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -272,7 +272,7 @@
 	
 	tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
 	if (!tsap) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
+		IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
 		return;
 	}
 	self->client.tsap_ctrl = tsap;
@@ -292,7 +292,7 @@
 {
 	struct irlan_cb *self;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	self = (struct irlan_cb *) instance;
 
@@ -318,7 +318,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 		
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -361,7 +361,7 @@
 
 	ASSERT(skb != NULL, return;);	
 	
-	IRDA_DEBUG(4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len);
+	IRDA_DEBUG(4, "%s() skb->len=%d\n", __FUNCTION__ , (int) skb->len);
 	
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -392,7 +392,7 @@
 	/* How many parameters? */
 	count = frame[1];
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), got %d parameters\n", count);
+	IRDA_DEBUG(4, "%s(), got %d parameters\n", __FUNCTION__ , count);
 	
 	ptr = frame+2;
 
@@ -400,7 +400,7 @@
  	for (i=0; i<count;i++) {
 		ret = irlan_extract_param(ptr, name, value, &val_len);
 		if (ret < 0) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
+			IRDA_DEBUG(2, "%s(), IrLAN, Error!\n", __FUNCTION__ );
 			break;
 		}
 		ptr += ret;
@@ -424,7 +424,7 @@
 	__u8 *bytes;
 	int i;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), parm=%s\n", param);
+	IRDA_DEBUG(4, "%s(), parm=%s\n", __FUNCTION__ , param);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -462,7 +462,7 @@
 		else if (strcmp(value, "HOSTED") == 0)
 			self->client.access_type = ACCESS_HOSTED;
 		else {
-			IRDA_DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
+			IRDA_DEBUG(2, "%s(), unknown access type!\n", __FUNCTION__ );
 		}
 	}
 	/* IRLAN version */
@@ -484,14 +484,14 @@
 		memcpy(&tmp_cpu, value, 2); /* Align value */
 		le16_to_cpus(&tmp_cpu);     /* Convert to host order */
 		self->client.recv_arb_val = tmp_cpu;
-		IRDA_DEBUG(2, __FUNCTION__ "(), receive arb val=%d\n", 
+		IRDA_DEBUG(2, "%s(), receive arb val=%d\n", __FUNCTION__ , 
 			   self->client.recv_arb_val);
 	}
 	if (strcmp(param, "MAX_FRAME") == 0) {
 		memcpy(&tmp_cpu, value, 2); /* Align value */
 		le16_to_cpus(&tmp_cpu);     /* Convert to host order */
 		self->client.max_frame = tmp_cpu;
-		IRDA_DEBUG(4, __FUNCTION__ "(), max frame=%d\n", 
+		IRDA_DEBUG(4, "%s(), max frame=%d\n", __FUNCTION__ , 
 			   self->client.max_frame);
 	}
 	 
@@ -526,7 +526,7 @@
 {
 	struct irlan_cb *self;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(priv != NULL, return;);
 
@@ -539,7 +539,7 @@
 
 	/* Check if request succeeded */
 	if (result != IAS_SUCCESS) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), got NULL value!\n");
+		IRDA_DEBUG(2, "%s(), got NULL value!\n", __FUNCTION__ );
 		irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, 
 				      NULL);
 		return;
@@ -557,7 +557,7 @@
 		irias_delete_value(value);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), unknown type!\n");
+		IRDA_DEBUG(2, "%s(), unknown type!\n", __FUNCTION__ );
 		break;
 	}
 	irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, NULL);
diff -Nru a/net/irda/irlan/irlan_client_event.c b/net/irda/irlan/irlan_client_event.c
--- a/net/irda/irlan/irlan_client_event.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/irlan/irlan_client_event.c	Fri Sep 27 14:51:03 2002
@@ -92,7 +92,7 @@
 static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -113,10 +113,10 @@
 					      "IrLAN", "IrDA:TinyTP:LsapSel");
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(4, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb) 
@@ -135,7 +135,7 @@
 static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event, 
 				    struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -153,7 +153,7 @@
 		irlan_next_client_state(self, IRLAN_CONN);
 		break;
 	case IRLAN_IAS_PROVIDER_NOT_AVAIL:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IAS_PROVIDER_NOT_AVAIL\n");
+		IRDA_DEBUG(2, "%s(), IAS_PROVIDER_NOT_AVAIL\n", __FUNCTION__ );
 		irlan_next_client_state(self, IRLAN_IDLE);
 
 		/* Give the client a kick! */
@@ -166,10 +166,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__"(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -188,7 +188,7 @@
 static int irlan_client_state_conn(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 	
@@ -203,10 +203,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -223,7 +223,7 @@
 static int irlan_client_state_info(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	
@@ -243,10 +243,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -265,7 +265,7 @@
 static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event, 
 				    struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 
@@ -280,10 +280,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -304,7 +304,7 @@
 {
 	struct qos_info qos;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 
@@ -343,7 +343,7 @@
 			irlan_next_client_state(self, IRLAN_DATA);
 			break;
 		default:
-			IRDA_DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
+			IRDA_DEBUG(2, "%s(), unknown access type!\n", __FUNCTION__ );
 			break;
 		}
 		break;
@@ -352,10 +352,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	
@@ -375,7 +375,7 @@
 static int irlan_client_state_wait(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 	
@@ -389,10 +389,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -406,7 +406,7 @@
 {
 	struct qos_info qos;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	
@@ -428,7 +428,7 @@
 		} else if (self->client.recv_arb_val >
 			   self->provider.send_arb_val) 
 		{
-			IRDA_DEBUG(2, __FUNCTION__ "(), lost the battle :-(\n");
+			IRDA_DEBUG(2, "%s(), lost the battle :-(\n", __FUNCTION__ );
 		}
 		break;
 	case IRLAN_DATA_CONNECT_INDICATION:
@@ -439,10 +439,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -461,7 +461,7 @@
 static int irlan_client_state_data(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -475,7 +475,7 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -493,7 +493,7 @@
 static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event, 
 				    struct sk_buff *skb) 
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	if (skb)
 		dev_kfree_skb(skb);
@@ -510,7 +510,7 @@
 static int irlan_client_state_sync(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	
 	if (skb)
 		dev_kfree_skb(skb);
diff -Nru a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
--- a/net/irda/irlan/irlan_common.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irlan/irlan_common.c	Fri Sep 27 14:51:04 2002
@@ -64,7 +64,8 @@
  *  Master structure
  */
 hashbin_t *irlan = NULL;
-static __u32 ckey, skey;
+static void *ckey;
+static void *skey;
 
 /* Module parameters */
 static int eth = 0; /* Use "eth" or "irlan" name for devices */
@@ -122,7 +123,7 @@
 	struct irlan_cb *new;
 	__u16 hints;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 	/* Allocate master structure */
 	irlan = hashbin_new(HB_LOCK);	/* protect from /proc */
 	if (irlan == NULL) {
@@ -133,7 +134,7 @@
 	create_proc_info_entry("irlan", 0, proc_irda, irlan_proc_read);
 #endif /* CONFIG_PROC_FS */
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	hints = irlmp_service_to_hint(S_LAN);
 
 	/* Register with IrLMP as a client */
@@ -157,7 +158,7 @@
 
 void __exit irlan_cleanup(void) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	irlmp_unregister_client(ckey);
 	irlmp_unregister_service(skey);
@@ -181,7 +182,7 @@
 {
 	int i=0;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	/* Check if we should call the device eth<x> or irlan<x> */
 	if (!eth) {
@@ -192,7 +193,7 @@
 	}
 	
 	if (register_netdev(&self->dev) != 0) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), register_netdev() failed!\n");
+		IRDA_DEBUG(2, "%s(), register_netdev() failed!\n", __FUNCTION__ );
 		return -1;
 	}
 	return 0;
@@ -208,7 +209,7 @@
 {
 	struct irlan_cb *self;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	ASSERT(irlan != NULL, return NULL;);
 
 	/* 
@@ -264,7 +265,7 @@
 {
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -301,7 +302,7 @@
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -390,7 +391,7 @@
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), reason=%d\n", reason);
+	IRDA_DEBUG(0, "%s(), reason=%d\n", __FUNCTION__ , reason);
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -409,19 +410,19 @@
 	
 	switch (reason) {
 	case LM_USER_REQUEST: /* User request */
-		IRDA_DEBUG(2, __FUNCTION__ "(), User requested\n");
+		IRDA_DEBUG(2, "%s(), User requested\n", __FUNCTION__ );
 		break;
 	case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unexpected IrLAP disconnect\n");
+		IRDA_DEBUG(2, "%s(), Unexpected IrLAP disconnect\n", __FUNCTION__ );
 		break;
 	case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
-		IRDA_DEBUG(2, __FUNCTION__ "(), IrLAP connect failed\n");
+		IRDA_DEBUG(2, "%s(), IrLAP connect failed\n", __FUNCTION__ );
 		break;
 	case LM_LAP_RESET:  /* IrLAP reset */
-		IRDA_DEBUG(2, __FUNCTION__ "(), IrLAP reset\n");
+		IRDA_DEBUG(2, "%s(), IrLAP reset\n", __FUNCTION__ );
 		break;
 	case LM_INIT_DISCONNECT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), IrLMP connect failed\n");
+		IRDA_DEBUG(2, "%s(), IrLMP connect failed\n", __FUNCTION__ );
 		break;
 	default:
 		ERROR("%s(), Unknown disconnect reason\n", __FUNCTION__);
@@ -446,7 +447,7 @@
 	struct tsap_cb *tsap;
 	notify_t notify;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -468,7 +469,7 @@
 
 	tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
 	if (!tsap) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
+		IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
 		return;
 	}
 	self->tsap_data = tsap;
@@ -482,7 +483,7 @@
 
 void irlan_close_tsaps(struct irlan_cb *self)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -572,7 +573,7 @@
 {
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	if (irda_lock(&self->client.tx_busy) == FALSE)
 		return -EBUSY;
@@ -591,7 +592,7 @@
 		dev_kfree_skb(skb);
 		return -1;
 	}
-	IRDA_DEBUG(2, __FUNCTION__ "(), sending ...\n");
+	IRDA_DEBUG(2, "%s(), sending ...\n", __FUNCTION__ );
 
 	return irttp_data_request(self->client.tsap_ctrl, skb);
 }
@@ -604,7 +605,7 @@
  */
 void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	/* Queue command */
 	skb_queue_tail(&self->client.txq, skb);
@@ -624,7 +625,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -656,7 +657,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -688,7 +689,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -727,7 +728,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);	
@@ -765,7 +766,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -804,7 +805,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -844,7 +845,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 		
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -879,7 +880,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -964,7 +965,7 @@
 	int n=0;
 	
 	if (skb == NULL) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), Got NULL skb\n");
+		IRDA_DEBUG(2, "%s(), Got NULL skb\n", __FUNCTION__ );
 		return 0;
 	}	
 
@@ -981,7 +982,7 @@
 		ASSERT(value_len > 0, return 0;);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown parameter type!\n");
+		IRDA_DEBUG(2, "%s(), Unknown parameter type!\n", __FUNCTION__ );
 		return 0;
 		break;
 	}
@@ -991,7 +992,7 @@
 
 	/* Make space for data */
 	if (skb_tailroom(skb) < (param_len+value_len+3)) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), No more space at end of skb\n");
+		IRDA_DEBUG(2, "%s(), No more space at end of skb\n", __FUNCTION__ );
 		return 0;
 	}	
 	skb_put(skb, param_len+value_len+3);
@@ -1038,13 +1039,13 @@
 	__u16 val_len;
 	int n=0;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	/* get length of parameter name (1 byte) */
 	name_len = buf[n++];
 	
 	if (name_len > 254) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), name_len > 254\n");
+		IRDA_DEBUG(2, "%s(), name_len > 254\n", __FUNCTION__ );
 		return -RSP_INVALID_COMMAND_FORMAT;
 	}
 	
@@ -1061,7 +1062,7 @@
 	le16_to_cpus(&val_len); n+=2;
 	
 	if (val_len > 1016) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), parameter length to long\n");
+		IRDA_DEBUG(2, "%s(), parameter length to long\n", __FUNCTION__ );
 		return -RSP_INVALID_COMMAND_FORMAT;
 	}
 	*len = val_len;
diff -Nru a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
--- a/net/irda/irlan/irlan_eth.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/irlan/irlan_eth.c	Fri Sep 27 14:51:03 2002
@@ -50,7 +50,7 @@
 {
 	struct irlan_cb *self;
 
-	IRDA_DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(dev != NULL, return -1;);
        
@@ -107,7 +107,7 @@
 {
 	struct irlan_cb *self;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
 	ASSERT(dev != NULL, return -1;);
 
@@ -143,7 +143,7 @@
 	struct irlan_cb *self = (struct irlan_cb *) dev->priv;
 	struct sk_buff *skb;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 	
 	/* Stop device */
 	netif_stop_queue(dev);
@@ -356,14 +356,14 @@
 
  	self = dev->priv; 
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
  	ASSERT(self != NULL, return;); 
  	ASSERT(self->magic == IRLAN_MAGIC, return;);
 
 	/* Check if data channel has been connected yet */
 	if (self->client.state != IRLAN_DATA) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), delaying!\n");
+		IRDA_DEBUG(1, "%s(), delaying!\n", __FUNCTION__ );
 		return;
 	}
 
@@ -373,20 +373,20 @@
 	} 
 	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) {
 		/* Disable promiscuous mode, use normal mode. */
-		IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
+		IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __FUNCTION__ );
 		/* hardware_set_filter(NULL); */
 
 		irlan_set_multicast_filter(self, TRUE);
 	}
 	else if (dev->mc_count) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
+		IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __FUNCTION__ );
 		/* Walk the address list, and load the filter */
 		/* hardware_set_filter(dev->mc_list); */
 
 		irlan_set_multicast_filter(self, TRUE);
 	}
 	else {
-		IRDA_DEBUG(4, __FUNCTION__ "(), Clearing multicast filter\n");
+		IRDA_DEBUG(4, "%s(), Clearing multicast filter\n", __FUNCTION__ );
 		irlan_set_multicast_filter(self, FALSE);
 	}
 
diff -Nru a/net/irda/irlan/irlan_event.c b/net/irda/irlan/irlan_event.c
--- a/net/irda/irlan/irlan_event.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/irlan/irlan_event.c	Fri Sep 27 14:51:05 2002
@@ -40,7 +40,7 @@
 
 void irlan_next_client_state(struct irlan_cb *self, IRLAN_STATE state) 
 {
-	IRDA_DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
+	IRDA_DEBUG(2, "%s(), %s\n", __FUNCTION__ , irlan_state[state]);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -50,7 +50,7 @@
 
 void irlan_next_provider_state(struct irlan_cb *self, IRLAN_STATE state) 
 {
-	IRDA_DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
+	IRDA_DEBUG(2, "%s(), %s\n", __FUNCTION__ , irlan_state[state]);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
diff -Nru a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c
--- a/net/irda/irlan/irlan_filter.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/irlan/irlan_filter.c	Fri Sep 27 14:51:05 2002
@@ -143,7 +143,7 @@
 {
 	__u8 *bytes;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	bytes = value;
 
@@ -156,7 +156,7 @@
 	 *  This is experimental!! DB.
 	 */
 	 if (strcmp(param, "MODE") == 0) {
-		IRDA_DEBUG(0, __FUNCTION__ "()\n");
+		IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 		self->use_udata = TRUE;
 		return;
 	}
diff -Nru a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
--- a/net/irda/irlan/irlan_provider.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irlan/irlan_provider.c	Fri Sep 27 14:51:04 2002
@@ -70,7 +70,7 @@
 	struct irlan_cb *self;
 	__u8 code;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	self = (struct irlan_cb *) instance;
 
@@ -99,15 +99,15 @@
 		irlan_do_provider_event(self, IRLAN_FILTER_CONFIG_CMD, skb);
 		break;
 	case CMD_RECONNECT_DATA_CHAN:
-		IRDA_DEBUG(2, __FUNCTION__"(), Got RECONNECT_DATA_CHAN command\n");
-		IRDA_DEBUG(2, __FUNCTION__"(), NOT IMPLEMENTED\n");
+		IRDA_DEBUG(2, "%s(), Got RECONNECT_DATA_CHAN command\n", __FUNCTION__ );
+		IRDA_DEBUG(2, "%s(), NOT IMPLEMENTED\n", __FUNCTION__ );
 		break;
 	case CMD_CLOSE_DATA_CHAN:
 		IRDA_DEBUG(2, "Got CLOSE_DATA_CHAN command!\n");
-		IRDA_DEBUG(2, __FUNCTION__"(), NOT IMPLEMENTED\n");
+		IRDA_DEBUG(2, "%s(), NOT IMPLEMENTED\n", __FUNCTION__ );
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown command!\n");
+		IRDA_DEBUG(2, "%s(), Unknown command!\n", __FUNCTION__ );
 		break;
 	}
 	return 0;
@@ -129,7 +129,7 @@
 	struct tsap_cb *tsap;
 	__u32 saddr, daddr;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -182,7 +182,7 @@
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), reason=%d\n", reason);
+	IRDA_DEBUG(4, "%s(), reason=%d\n", __FUNCTION__ , reason);
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -236,7 +236,7 @@
 	
 	ASSERT(skb != NULL, return -RSP_PROTOCOL_ERROR;);
 	
-	IRDA_DEBUG(4, __FUNCTION__ "(), skb->len=%d\n", (int)skb->len);
+	IRDA_DEBUG(4, "%s(), skb->len=%d\n", __FUNCTION__ , (int)skb->len);
 
 	ASSERT(self != NULL, return -RSP_PROTOCOL_ERROR;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -RSP_PROTOCOL_ERROR;);
@@ -266,7 +266,7 @@
  	for (i=0; i<count;i++) {
 		ret = irlan_extract_param(ptr, name, value, &val_len);
 		if (ret < 0) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
+			IRDA_DEBUG(2, "%s(), IrLAN, Error!\n", __FUNCTION__ );
 			break;
 		}
 		ptr+=ret;
@@ -291,7 +291,7 @@
 {
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -316,7 +316,7 @@
 			irlan_insert_string_param(skb, "MEDIA", "802.5");
 			break;
 		default:
-			IRDA_DEBUG(2, __FUNCTION__ "(), unknown media type!\n");
+			IRDA_DEBUG(2, "%s(), unknown media type!\n", __FUNCTION__ );
 			break;
 		}
 		irlan_insert_short_param(skb, "IRLAN_VER", 0x0101);
@@ -340,7 +340,7 @@
 			irlan_insert_string_param(skb, "ACCESS_TYPE", "HOSTED");
 			break;
 		default:
-			IRDA_DEBUG(2, __FUNCTION__ "(), Unknown access type\n");
+			IRDA_DEBUG(2, "%s(), Unknown access type\n", __FUNCTION__ );
 			break;
 		}
 		irlan_insert_short_param(skb, "MAX_FRAME", 0x05ee);
@@ -361,7 +361,7 @@
 		handle_filter_request(self, skb);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown command!\n");
+		IRDA_DEBUG(2, "%s(), Unknown command!\n", __FUNCTION__ );
 		break;
 	}
 
@@ -379,7 +379,7 @@
 	struct tsap_cb *tsap;
 	notify_t notify;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -400,7 +400,7 @@
 
 	tsap = irttp_open_tsap(LSAP_ANY, 1, &notify);
 	if (!tsap) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
+		IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
 		return -1;
 	}
 	self->provider.tsap_ctrl = tsap;
diff -Nru a/net/irda/irlan/irlan_provider_event.c b/net/irda/irlan/irlan_provider_event.c
--- a/net/irda/irlan/irlan_provider_event.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irlan/irlan_provider_event.c	Fri Sep 27 14:51:04 2002
@@ -72,7 +72,7 @@
 static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
 				     struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 	
@@ -82,7 +82,7 @@
 	     irlan_next_provider_state( self, IRLAN_INFO);
 	     break;
 	default:
-		IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(4, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -101,7 +101,7 @@
 {
 	int ret;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
 	ASSERT(self != NULL, return -1;);
 
@@ -147,7 +147,7 @@
 		irlan_next_provider_state(self, IRLAN_IDLE);
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG( 0, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -166,7 +166,7 @@
 static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event, 
 				     struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 
@@ -186,7 +186,7 @@
 		irlan_next_provider_state(self, IRLAN_IDLE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
@@ -205,7 +205,7 @@
 static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event, 
 				     struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -221,7 +221,7 @@
 		irlan_next_provider_state(self, IRLAN_IDLE);
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG( 0, "%s(), Unknown event %d\n", __FUNCTION__ , event);
 		break;
 	}
 	if (skb)
diff -Nru a/net/irda/irlap.c b/net/irda/irlap.c
--- a/net/irda/irlap.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/irlap.c	Fri Sep 27 14:51:05 2002
@@ -107,7 +107,7 @@
 {
 	struct irlap_cb *self;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	/* Initialize the irlap structure. */
 	self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);
@@ -210,7 +210,7 @@
 {
 	struct irlap_cb *lap;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -223,7 +223,7 @@
 	/* Be sure that we manage to remove ourself from the hash */
 	lap = hashbin_remove(irlap, self->saddr, NULL);
 	if (!lap) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Didn't find myself!\n");
+		IRDA_DEBUG(1, "%s(), Didn't find myself!\n", __FUNCTION__);
 		return;
 	}
 	__irlap_close(lap);
@@ -237,7 +237,7 @@
  */
 void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -257,7 +257,7 @@
  */
 void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	irlap_do_event(self, CONNECT_RESPONSE, skb, NULL);
 	kfree_skb(skb);
@@ -273,7 +273,7 @@
 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);
+	IRDA_DEBUG(3, "%s(), daddr=0x%08x\n", __FUNCTION__, daddr);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -300,7 +300,7 @@
  */
 void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -339,7 +339,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
 	       return;);
@@ -383,7 +383,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
 	       return;);
@@ -407,7 +407,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, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -428,7 +428,7 @@
  */
 void irlap_disconnect_request(struct irlap_cb *self)
 {
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -450,7 +450,7 @@
 		irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), disconnect pending!\n");
+		IRDA_DEBUG(2, "%s(), disconnect pending!\n", __FUNCTION__);
 		self->disconnect_pending = TRUE;
 		break;
 	}
@@ -464,7 +464,7 @@
  */
 void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]);
+	IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__, lap_reasons[reason]);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -474,7 +474,7 @@
 
 	switch (reason) {
 	case LAP_RESET_INDICATION:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Sending reset request!\n");
+		IRDA_DEBUG(1, "%s(), Sending reset request!\n", __FUNCTION__);
 		irlap_do_event(self, RESET_REQUEST, NULL, NULL);
 		break;
 	case LAP_NO_RESPONSE:	   /* FALLTROUGH */
@@ -503,7 +503,7 @@
 	ASSERT(self->magic == LAP_MAGIC, return;);
 	ASSERT(discovery != NULL, return;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
+	IRDA_DEBUG(4, "%s(), nslots = %d\n", __FUNCTION__, discovery->nslots);
 
 	ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||
 	       (discovery->nslots == 8) || (discovery->nslots == 16),
@@ -511,8 +511,8 @@
 
 	/* Discovery is only possible in NDM mode */
 	if (self->state != LAP_NDM) {
-		IRDA_DEBUG(4, __FUNCTION__
-			   "(), discovery only possible in NDM mode\n");
+		IRDA_DEBUG(4, "%s(), discovery only possible in NDM mode\n",
+			   __FUNCTION__);
 		irlap_discovery_confirm(self, NULL);
 		/* Note : in theory, if we are not in NDM, we could postpone
 		 * the discovery like we do for connection request.
@@ -584,7 +584,7 @@
  */
 void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -630,7 +630,7 @@
  */
 void irlap_reset_indication(struct irlap_cb *self)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -646,7 +646,7 @@
  */
 void irlap_reset_confirm(void)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 }
 
 /*
@@ -746,7 +746,7 @@
 {
 	/*  nr as expected?  */
 	if (nr == self->vs) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), expected!\n");
+		IRDA_DEBUG(4, "%s(), expected!\n", __FUNCTION__);
 		return NR_EXPECTED;
 	}
 
@@ -774,7 +774,7 @@
  */
 void irlap_initiate_connection_state(struct irlap_cb *self)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -857,7 +857,7 @@
 {
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), setting speed to %d\n", speed);
+	IRDA_DEBUG(0, "%s(), setting speed to %d\n", __FUNCTION__, speed);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -899,7 +899,7 @@
 	 *  user may not have set all of them.
 	 */
 	if (qos_user) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Found user specified QoS!\n");
+		IRDA_DEBUG(1, "%s(), Found user specified QoS!\n", __FUNCTION__);
 
 		if (qos_user->baud_rate.bits)
 			self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits;
@@ -929,7 +929,7 @@
  */
 void irlap_apply_default_connection_parameters(struct irlap_cb *self)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -992,7 +992,7 @@
  */
 void irlap_apply_connection_parameters(struct irlap_cb *self, int now)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
diff -Nru a/net/irda/irlap_event.c b/net/irda/irlap_event.c
--- a/net/irda/irlap_event.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irlap_event.c	Fri Sep 27 14:51:04 2002
@@ -218,7 +218,7 @@
 	} else
 		self->fast_RR = FALSE;
 
-	IRDA_DEBUG(3, __FUNCTION__ "(), timeout=%d (%ld)\n", timeout, jiffies);
+	IRDA_DEBUG(3, "%s(), timeout=%d (%ld)\n", __FUNCTION__, timeout, jiffies);
 #endif /* CONFIG_IRDA_FAST_RR */
 
 	if (timeout == 0)
@@ -242,7 +242,7 @@
 	if (!self || self->magic != LAP_MAGIC)
 		return;
 
-	IRDA_DEBUG(3, __FUNCTION__ "(), event = %s, state = %s\n",
+	IRDA_DEBUG(3, "%s(), event = %s, state = %s\n", __FUNCTION__,
 		   irlap_event[event], irlap_state[self->state]);
 
 	ret = (*state[self->state])(self, event, skb, info);
@@ -260,7 +260,7 @@
 		 * try to disconnect link if we send any data frames, since
 		 * that will change the state away form XMIT
 		 */
-		IRDA_DEBUG(2, __FUNCTION__ "() : queue len = %d\n",
+		IRDA_DEBUG(2, "%s() : queue len = %d\n", __FUNCTION__,
 			   skb_queue_len(&self->txq));
 
 		if (skb_queue_len(&self->txq)) {
@@ -354,8 +354,8 @@
 			/* Note : this will never happen, because we test
 			 * media busy in irlap_connect_request() and
 			 * postpone the event... - Jean II */
-			IRDA_DEBUG(0, __FUNCTION__
-				   "(), CONNECT_REQUEST: media busy!\n");
+			IRDA_DEBUG(0, "%s(), CONNECT_REQUEST: media busy!\n",
+				   __FUNCTION__);
 
 			/* Always switch state before calling upper layers */
 			irlap_next_state(self, LAP_NDM);
@@ -381,15 +381,15 @@
 
 			irlap_connect_indication(self, skb);
 		} else {
-			IRDA_DEBUG(0, __FUNCTION__ "(), SNRM frame does not "
-				   "contain an I field!\n");
+			IRDA_DEBUG(0, "%s(), SNRM frame does not "
+				   "contain an I field!\n", __FUNCTION__);
 		}
 		break;
 	case DISCOVERY_REQUEST:
 		ASSERT(info != NULL, return -1;);
 
 		if (self->media_busy) {
-			IRDA_DEBUG(0, __FUNCTION__ "(), media busy!\n");
+			IRDA_DEBUG(0, "%s(), media busy!\n", __FUNCTION__);
 			/* irlap->log.condition = MEDIA_BUSY; */
 
 			/* This will make IrLMP try again */
@@ -451,7 +451,7 @@
 		 * log (and post an event).
 		 * Jean II
 		 */
-			IRDA_DEBUG(1, __FUNCTION__ "(), Receiving final discovery request, missed the discovery slots :-(\n");
+			IRDA_DEBUG(1, "%s(), Receiving final discovery request, missed the discovery slots :-(\n", __FUNCTION__);
 
 			/* Last discovery request -> in the log */
 			irlap_discovery_indication(self, info->discovery);
@@ -527,8 +527,8 @@
 	case RECV_UI_FRAME:
 		/* Only accept broadcast frames in NDM mode */
 		if (info->caddr != CBROADCAST) {
-			IRDA_DEBUG(0, __FUNCTION__
-				   "(), not a broadcast frame!\n");
+			IRDA_DEBUG(0, "%s(), not a broadcast frame!\n",
+				   __FUNCTION__);
 		} else
 			irlap_unitdata_indication(self, skb);
 		break;
@@ -544,10 +544,10 @@
 		irlap_send_test_frame(self, CBROADCAST, info->daddr, skb);
 		break;
 	case RECV_TEST_RSP:
-		IRDA_DEBUG(0, __FUNCTION__ "() not implemented!\n");
+		IRDA_DEBUG(0, "%s() not implemented!\n", __FUNCTION__);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
+		IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
 			   irlap_event[event]);
 
 		ret = -1;
@@ -575,7 +575,7 @@
 		ASSERT(info != NULL, return -1;);
 		ASSERT(info->discovery != NULL, return -1;);
 
-		IRDA_DEBUG(4, __FUNCTION__ "(), daddr=%08x\n",
+		IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__,
 			   info->discovery->daddr);
 
 		if (!self->discovery_log) {
@@ -606,7 +606,7 @@
 
 		ASSERT(info != NULL, return -1;);
 
-		IRDA_DEBUG(1, __FUNCTION__ "(), Receiving discovery request (s = %d) while performing discovery :-(\n", info->s);
+		IRDA_DEBUG(1, "%s(), Receiving discovery request (s = %d) while performing discovery :-(\n", __FUNCTION__, info->s);
 
 		/* Last discovery request ? */
 		if (info->s == 0xff)
@@ -620,9 +620,8 @@
 		 * timing requirements.
 		 */
 		if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
-			IRDA_DEBUG(2, __FUNCTION__
-				   "(), device is slow to answer, "
-				   "waiting some more!\n");
+			IRDA_DEBUG(2, "%s(), device is slow to answer, "
+				   "waiting some more!\n", __FUNCTION__);
 			irlap_start_slot_timer(self, MSECS_TO_JIFFIES(10));
 			self->add_wait = TRUE;
 			return ret;
@@ -658,7 +657,7 @@
 		}
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
+		IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
 			   irlap_event[event]);
 
 		ret = -1;
@@ -680,15 +679,15 @@
 	discovery_t *discovery_rsp;
 	int ret=0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
 
 	switch (event) {
 	case QUERY_TIMER_EXPIRED:
-		IRDA_DEBUG(2, __FUNCTION__ "(), QUERY_TIMER_EXPIRED <%ld>\n",
-		      jiffies);
+		IRDA_DEBUG(2, "%s(), QUERY_TIMER_EXPIRED <%ld>\n",
+			   __FUNCTION__, jiffies);
 		irlap_next_state(self, LAP_NDM);
 		break;
 	case RECV_DISCOVERY_XID_CMD:
@@ -716,8 +715,8 @@
 		}
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
-			   irlap_event[event]);
+		IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __FUNCTION__,
+			   event, irlap_event[event]);
 
 		ret = -1;
 		break;
@@ -737,7 +736,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]);
+	IRDA_DEBUG(4, "%s(), event=%s\n", __FUNCTION__, irlap_event[ event]);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
@@ -797,20 +796,20 @@
 
 		break;
 	case RECV_DISCOVERY_XID_CMD:
-		IRDA_DEBUG(3, __FUNCTION__
-			   "(), event RECV_DISCOVER_XID_CMD!\n");
+		IRDA_DEBUG(3, "%s(), event RECV_DISCOVER_XID_CMD!\n",
+			   __FUNCTION__);
 		irlap_next_state(self, LAP_NDM);
 
 		break;
 	case DISCONNECT_REQUEST:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Disconnect request!\n");
+		IRDA_DEBUG(0, "%s(), Disconnect request!\n", __FUNCTION__);
 		irlap_send_dm_frame(self);
 		irlap_next_state( self, LAP_NDM);
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
-			   irlap_event[event]);
+		IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __FUNCTION__, 
+			   event, irlap_event[event]);
 
 		ret = -1;
 		break;
@@ -831,7 +830,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
@@ -860,7 +859,7 @@
 		self->retry_count++;
 		break;
 	case RECV_SNRM_CMD:
-		IRDA_DEBUG(4, __FUNCTION__ "(), SNRM battle!\n");
+		IRDA_DEBUG(4, "%s(), SNRM battle!\n", __FUNCTION__);
 
 		ASSERT(skb != NULL, return 0;);
 		ASSERT(info != NULL, return 0;);
@@ -941,8 +940,8 @@
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
-			   irlap_event[event]);
+		IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __FUNCTION__,
+			   event, irlap_event[event]);
 
 		ret = -1;
 		break;
@@ -959,7 +958,7 @@
 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");
+	IRDA_DEBUG( 0, "%s(), Unknown event\n", __FUNCTION__);
 
 	return -1;
 }
@@ -990,9 +989,8 @@
 			 *  speed and turn-around-time.
 			 */
 			if (skb->len > self->bytes_left) {
-				IRDA_DEBUG(4, __FUNCTION__
-					   "(), Not allowed to transmit more "
-					   "bytes!\n");
+				IRDA_DEBUG(4, "%s(), Not allowed to transmit"
+					   " more bytes!\n", __FUNCTION__);
 				skb_queue_head(&self->txq, skb_get(skb));
 				/*
 				 *  We should switch state to LAP_NRM_P, but
@@ -1030,8 +1028,8 @@
 			self->fast_RR = FALSE;
 #endif /* CONFIG_IRDA_FAST_RR */
 		} else {
-			IRDA_DEBUG(4, __FUNCTION__
-				   "(), Unable to send! remote busy?\n");
+			IRDA_DEBUG(4, "%s(), Unable to send! remote busy?\n",
+				   __FUNCTION__);
 			skb_queue_head(&self->txq, skb_get(skb));
 
 			/*
@@ -1042,8 +1040,8 @@
 		}
 		break;
 	case POLL_TIMER_EXPIRED:
-		IRDA_DEBUG(3, __FUNCTION__ "(), POLL_TIMER_EXPIRED (%ld)\n",
-			   jiffies);
+		IRDA_DEBUG(3, "%s(), POLL_TIMER_EXPIRED <%ld>\n",
+			    __FUNCTION__, jiffies);
 		irlap_send_rr_frame(self, CMD_FRAME);
 		/* Return to NRM properly - Jean II  */
 		self->window = self->window_size;
@@ -1068,8 +1066,8 @@
 		 * when we return... - Jean II */
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlap_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			   __FUNCTION__, irlap_event[event]);
 
 		ret = -EINVAL;
 		break;
@@ -1087,7 +1085,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
@@ -1122,7 +1120,7 @@
 		}
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(1, "%s(), Unknown event %d\n", __FUNCTION__, event);
 
 		ret = -1;
 		break;
@@ -1235,8 +1233,9 @@
 				/* Keep state */
 				irlap_next_state(self, LAP_NRM_P);
 			} else {
-				IRDA_DEBUG(4, __FUNCTION__
-				       "(), missing or duplicate frame!\n");
+				IRDA_DEBUG(4,
+				       "%s(), missing or duplicate frame!\n",
+					   __FUNCTION__);
 
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
@@ -1300,8 +1299,8 @@
 		if ((ns_status == NS_UNEXPECTED) &&
 		    (nr_status == NR_UNEXPECTED))
 		{
-			IRDA_DEBUG(4, __FUNCTION__
-				   "(), unexpected nr and ns!\n");
+			IRDA_DEBUG(4, "%s(), unexpected nr and ns!\n",
+				   __FUNCTION__);
 			if (info->pf) {
 				/* Resend rejected frames */
 				irlap_resend_rejected_frames(self, CMD_FRAME);
@@ -1340,10 +1339,9 @@
 			}
 			break;
 		}
-		IRDA_DEBUG(1, __FUNCTION__ "(), Not implemented!\n");
-		IRDA_DEBUG(1, __FUNCTION__
-		      "(), event=%s, ns_status=%d, nr_status=%d\n",
-		      irlap_event[ event], ns_status, nr_status);
+		IRDA_DEBUG(1, "%s(), Not implemented!\n", __FUNCTION__);
+		IRDA_DEBUG(1, "%s(), event=%s, ns_status=%d, nr_status=%d\n",
+		       __FUNCTION__, irlap_event[event], ns_status, nr_status);
 		break;
 	case RECV_UI_FRAME:
 		/* Poll bit cleared? */
@@ -1354,7 +1352,7 @@
 			del_timer(&self->final_timer);
 			irlap_data_indication(self, skb, TRUE);
 			irlap_next_state(self, LAP_XMIT_P);
-			printk("%s: RECV_UI_FRAME: next state %s\n", __FUNCTION__, irlap_state[self->state]);
+			IRDA_DEBUG(1, "%s: RECV_UI_FRAME: next state %s\n", __FUNCTION__, irlap_state[self->state]);
 			irlap_start_poll_timer(self, self->poll_timeout);
 		}
 		break;
@@ -1407,8 +1405,8 @@
 
 			irlap_next_state(self, LAP_NRM_P);
 		} else if (ret == NR_INVALID) {
-			IRDA_DEBUG(1, __FUNCTION__ "(), Received RR with "
-				   "invalid nr !\n");
+			IRDA_DEBUG(1, "%s(), Received RR with "
+				   "invalid nr !\n", __FUNCTION__);
 			del_timer(&self->final_timer);
 
 			irlap_next_state(self, LAP_RESET_WAIT);
@@ -1508,7 +1506,7 @@
 		irlap_start_final_timer(self, self->final_timeout);
 		break;
 	case RECV_RD_RSP:
-		IRDA_DEBUG(1, __FUNCTION__ "(), RECV_RD_RSP\n");
+		IRDA_DEBUG(1, "%s(), RECV_RD_RSP\n", __FUNCTION__);
 
 		irlap_flush_all_queues(self);
 		irlap_next_state(self, LAP_XMIT_P);
@@ -1516,8 +1514,8 @@
 		irlap_disconnect_request(self);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n",
-			   irlap_event[event]);
+		IRDA_DEBUG(1, "%s(), Unknown event %s\n",
+			    __FUNCTION__, irlap_event[event]);
 
 		ret = -1;
 		break;
@@ -1537,7 +1535,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]);
+	IRDA_DEBUG(3, "%s(), event = %s\n", __FUNCTION__, irlap_event[event]);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
@@ -1563,7 +1561,7 @@
 		irlap_next_state( self, LAP_PCLOSE);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
+		IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
 			   irlap_event[event]);
 
 		ret = -1;
@@ -1584,7 +1582,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]);
+	IRDA_DEBUG(3, "%s(), event = %s\n", __FUNCTION__, irlap_event[event]);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
@@ -1642,7 +1640,7 @@
 		 * state
 		 */
 		if (!info) {
-			IRDA_DEBUG(3, __FUNCTION__ "(), RECV_SNRM_CMD\n");
+			IRDA_DEBUG(3, "%s(), RECV_SNRM_CMD\n", __FUNCTION__);
 			irlap_initiate_connection_state(self);
 			irlap_wait_min_turn_around(self, &self->qos_tx);
 			irlap_send_ua_response_frame(self, &self->qos_rx);
@@ -1650,13 +1648,14 @@
 			irlap_start_wd_timer(self, self->wd_timeout);
 			irlap_next_state(self, LAP_NDM);
 		} else {
-			IRDA_DEBUG(0, __FUNCTION__
-				   "(), SNRM frame contained an I field!\n");
+			IRDA_DEBUG(0,
+				   "%s(), SNRM frame contained an I field!\n",
+				   __FUNCTION__);
 		}
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n",
-			   irlap_event[event]);
+		IRDA_DEBUG(1, "%s(), Unknown event %s\n",
+			   __FUNCTION__, irlap_event[event]);
 
 		ret = -1;
 		break;
@@ -1676,7 +1675,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[event]);
+	IRDA_DEBUG(4, "%s(), event=%s\n", __FUNCTION__, irlap_event[event]);
 
 	ASSERT(self != NULL, return -ENODEV;);
 	ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
@@ -1732,7 +1731,7 @@
 				ret = -EPROTO;
 			}
 		} else {
-			IRDA_DEBUG(2, __FUNCTION__ "(), Unable to send!\n");
+			IRDA_DEBUG(2, "%s(), Unable to send!\n", __FUNCTION__);
 			skb_queue_head(&self->txq, skb_get(skb));
 			ret = -EPROTO;
 		}
@@ -1748,7 +1747,7 @@
 		 * when we return... - Jean II */
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
+		IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
 			   irlap_event[event]);
 
 		ret = -EINVAL;
@@ -1771,7 +1770,7 @@
 	int nr_status;
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]);
+	IRDA_DEBUG(4, "%s(), event=%s\n", __FUNCTION__, irlap_event[ event]);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LAP_MAGIC, return -1;);
@@ -1779,8 +1778,9 @@
 	switch (event) {
 	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,
+		IRDA_DEBUG(4, "%s(), event=%s nr=%d, vs=%d, ns=%d, "
+			   "vr=%d, pf=%d\n", __FUNCTION__,
+			   irlap_event[event], info->nr,
 			   self->vs, info->ns, self->vr, info->pf);
 
 		self->retry_count = 0;
@@ -2012,21 +2012,22 @@
 			/* Keep state */
 			irlap_next_state(self, LAP_NRM_S);
 		} else {
-			IRDA_DEBUG(1, __FUNCTION__
-				   "(), invalid nr not implemented!\n");
+			IRDA_DEBUG(1, "%s(), invalid nr not implemented!\n",
+				   __FUNCTION__);
 		}
 		break;
 	case RECV_SNRM_CMD:
 		/* SNRM frame is not allowed to contain an I-field */
 		if (!info) {
 			del_timer(&self->wd_timer);
-			IRDA_DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n");
+			IRDA_DEBUG(1, "%s(), received SNRM cmd\n", __FUNCTION__);
 			irlap_next_state(self, LAP_RESET_CHECK);
 
 			irlap_reset_indication(self);
 		} else {
-			IRDA_DEBUG(0, __FUNCTION__
-				   "(), SNRM frame contained an I-field!\n");
+			IRDA_DEBUG(0,
+				   "%s(), SNRM frame contained an I-field!\n",
+				   __FUNCTION__);
 
 		}
 		break;
@@ -2058,7 +2059,7 @@
 		 *   which explain why we use (self->N2 / 2) here !!!
 		 * Jean II
 		 */
-		IRDA_DEBUG(1, __FUNCTION__ "(), retry_count = %d\n",
+		IRDA_DEBUG(1, "%s(), retry_count = %d\n", __FUNCTION__,
 			   self->retry_count);
 
 		if (self->retry_count < (self->N2 / 2)) {
@@ -2111,7 +2112,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, "%s(), Unknown event %d, (%s)\n", __FUNCTION__,
 			   event, irlap_event[event]);
 
 		ret = -EINVAL;
@@ -2128,7 +2129,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -ENODEV;);
 	ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
@@ -2166,7 +2167,7 @@
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
+		IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __FUNCTION__,
 			   event, irlap_event[event]);
 
 		ret = -EINVAL;
@@ -2182,7 +2183,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), event=%s\n", irlap_event[event]);
+	IRDA_DEBUG(1, "%s(), event=%s\n", __FUNCTION__, irlap_event[event]);
 
 	ASSERT(self != NULL, return -ENODEV;);
 	ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
@@ -2203,7 +2204,7 @@
 		irlap_next_state(self, LAP_SCLOSE);
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
+		IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __FUNCTION__,
 			   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	Fri Sep 27 14:51:03 2002
+++ b/net/irda/irlap_frame.c	Fri Sep 27 14:51:03 2002
@@ -167,8 +167,8 @@
 
 		/* Check if the new connection address is valid */
 		if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
-			IRDA_DEBUG(3, __FUNCTION__
-			      "(), invalid connection address!\n");
+			IRDA_DEBUG(3, "%s(), invalid connection address!\n",
+				   __FUNCTION__);
 			return;
 		}
 
@@ -178,7 +178,8 @@
 
 		/* Only accept if addressed directly to us */
 		if (info->saddr != self->saddr) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), not addressed to us!\n");
+			IRDA_DEBUG(2, "%s(), not addressed to us!\n",
+				   __FUNCTION__);
 			return;
 		}
 		irlap_do_event(self, RECV_SNRM_CMD, skb, info);
@@ -200,7 +201,7 @@
 	struct ua_frame *frame;
 	int ret;
 
-	IRDA_DEBUG(2, __FUNCTION__ "() <%ld>\n", jiffies);
+	IRDA_DEBUG(2, "%s() <%ld>\n", __FUNCTION__, jiffies);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -275,7 +276,7 @@
 	struct sk_buff *skb = NULL;
 	__u8 *frame;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -306,8 +307,8 @@
 	__u32 bcast = BROADCAST;
 	__u8 *info;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S,
-		   command);
+	IRDA_DEBUG(4, "%s(), s=%d, S=%d, command=%d\n", __FUNCTION__,
+		   s, S, command);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -398,7 +399,7 @@
 	__u8 *discovery_info;
 	char *text;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -410,8 +411,8 @@
 
 	/* Make sure frame is addressed to us */
 	if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
-		IRDA_DEBUG(0, __FUNCTION__
-			   "(), frame is not addressed to us!\n");
+		IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n",
+			   __FUNCTION__);
 		return;
 	}
 
@@ -425,7 +426,7 @@
 	discovery->saddr = self->saddr;
 	discovery->timestamp = jiffies;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", discovery->daddr);
+	IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__, discovery->daddr);
 
 	discovery_info = skb_pull(skb, sizeof(struct xid_frame));
 
@@ -476,8 +477,8 @@
 
 	/* Make sure frame is addressed to us */
 	if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
-		IRDA_DEBUG(0, __FUNCTION__
-			   "(), frame is not addressed to us!\n");
+		IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n",
+			   __FUNCTION__);
 		return;
 	}
 
@@ -642,7 +643,7 @@
 
 	frame[2] = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), vr=%d, %ld\n",self->vr, jiffies);
+	IRDA_DEBUG(4, "%s(), vr=%d, %ld\n", __FUNCTION__, self->vr, jiffies);
 
 	irlap_queue_xmit(self, skb);
 }
@@ -658,7 +659,7 @@
 {
 	info->nr = skb->data[1] >> 5;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), nr=%d, %ld\n", info->nr, jiffies);
+	IRDA_DEBUG(4, "%s(), nr=%d, %ld\n", __FUNCTION__, info->nr, jiffies);
 
 	if (command)
 		irlap_do_event(self, RECV_RNR_CMD, skb, info);
@@ -669,7 +670,7 @@
 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");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
 	info->nr = skb->data[1] >> 5;
 
@@ -683,7 +684,7 @@
 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");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
 	info->nr = skb->data[1] >> 5;
 
@@ -697,7 +698,7 @@
 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");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	/* Check if this is a command or a response frame */
 	if (command)
@@ -754,7 +755,7 @@
 
 		irlap_send_i_frame( self, tx_skb, CMD_FRAME);
 	} else {
-		IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n");
+		IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
 		irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
 		self->window -= 1;
 	}
@@ -803,7 +804,7 @@
 
 		irlap_send_i_frame(self, tx_skb, CMD_FRAME);
 	} else {
-		IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n");
+		IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
 
 		if (self->ack_required) {
 			irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
@@ -952,7 +953,7 @@
 		/* 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");
+			IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
 			return;
 		}
 		/* Unlink tx_skb from list */
@@ -987,7 +988,7 @@
 	 */
 	while (skb_queue_len( &self->txq) > 0) {
 
-		IRDA_DEBUG(0, __FUNCTION__ "(), sending additional frames!\n");
+		IRDA_DEBUG(0, "%s(), sending additional frames!\n", __FUNCTION__);
 		if ((skb_queue_len( &self->txq) > 0) &&
 		    (self->window > 0)) {
 			skb = skb_dequeue( &self->txq);
@@ -1032,7 +1033,7 @@
 		/* 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");
+			IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
 			return;
 		}
 		/* Unlink tx_skb from list */
@@ -1058,7 +1059,7 @@
 void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
 			 __u8 caddr, int command)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -1118,7 +1119,7 @@
 static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
 				struct irlap_info *info)
 {
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
 	info->pf = skb->data[1] & PF_BIT;      /* Final bit */
 
@@ -1137,7 +1138,7 @@
 	__u8 *frame;
 	int w, x, y, z;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
@@ -1226,15 +1227,15 @@
 {
 	struct test_frame *frame;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	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__
-				   "() test frame to short!\n");
+			IRDA_DEBUG(0, "%s() test frame to short!\n",
+				   __FUNCTION__);
 			return;
 		}
 
@@ -1296,7 +1297,8 @@
 
 	/*  First we check if this frame has a valid connection address */
 	if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), wrong connection address!\n");
+		IRDA_DEBUG(0, "%s(), wrong connection address!\n",
+			   __FUNCTION__);
 		goto out;
 	}
 	/*
diff -Nru a/net/irda/irlmp.c b/net/irda/irlmp.c
--- a/net/irda/irlmp.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/irlmp.c	Fri Sep 27 14:51:05 2002
@@ -75,7 +75,7 @@
  */
 int __init irlmp_init(void)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 	/* Initialize the irlmp structure. */
 	irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
 	if (irlmp == NULL)
@@ -190,7 +190,7 @@
  */
 static void __irlmp_close_lsap(struct lsap_cb *self)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
@@ -250,8 +250,9 @@
 				      NULL);
 	}
 	if (!lsap) {
-		IRDA_DEBUG(0, __FUNCTION__
-		     "(), Looks like somebody has removed me already!\n");
+		IRDA_DEBUG(0,
+		     "%s(), Looks like somebody has removed me already!\n",
+			   __FUNCTION__);
 		return;
 	}
 	__irlmp_close_lsap(self);
@@ -318,7 +319,7 @@
 {
 	struct lap_cb *link;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	link = hashbin_remove(irlmp->links, saddr, NULL);
 	if (link) {
@@ -351,9 +352,9 @@
 	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",
-	      self->slsap_sel, dlsap_sel, saddr, daddr);
+	IRDA_DEBUG(2,
+	      "%s(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n",
+	      __FUNCTION__, self->slsap_sel, dlsap_sel, saddr, daddr);
 
 	if (test_bit(0, &self->connected))
 		return -EISCONN;
@@ -394,7 +395,7 @@
 		if (daddr != DEV_ADDR_ANY)
 			discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
 		else {
-			IRDA_DEBUG(2, __FUNCTION__ "(), no daddr\n");
+			IRDA_DEBUG(2, "%s(), no daddr\n", __FUNCTION__);
 			discovery = (discovery_t *)
 				hashbin_get_first(irlmp->cachelog);
 		}
@@ -407,7 +408,7 @@
 	}
 	lap = hashbin_lock_find(irlmp->links, saddr, NULL);
 	if (lap == NULL) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to find a usable link!\n");
+		IRDA_DEBUG(1, "%s(), Unable to find a usable link!\n", __FUNCTION__);
 		return -EHOSTUNREACH;
 	}
 
@@ -421,13 +422,13 @@
 			 * disconnected yet (waiting for timeout in LAP).
 			 * Maybe we could give LAP a bit of help in this case.
 			 */
-			IRDA_DEBUG(0, __FUNCTION__ "(), sorry, but I'm waiting for LAP to timeout!\n");
+			IRDA_DEBUG(0, "%s(), sorry, but I'm waiting for LAP to timeout!\n", __FUNCTION__);
 			return -EAGAIN;
 		}
 
 		/* LAP is already connected to a different node, and LAP
 		 * can only talk to one node at a time */
-		IRDA_DEBUG(0, __FUNCTION__ "(), sorry, but link is busy!\n");
+		IRDA_DEBUG(0, "%s(), sorry, but link is busy!\n", __FUNCTION__);
 		return -EBUSY;
 	}
 
@@ -477,8 +478,8 @@
 	ASSERT(skb != NULL, return;);
 	ASSERT(self->lap != NULL, return;);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",
-		   self->slsap_sel, self->dlsap_sel);
+	IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
+		   __FUNCTION__, self->slsap_sel, self->dlsap_sel);
 
 	/* Note : self->lap is set in irlmp_link_data_indication(),
 	 * (case CONNECT_CMD:) because we have no way to set it here.
@@ -516,8 +517,8 @@
 
 	set_bit(0, &self->connected);	/* TRUE */
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",
-		   self->slsap_sel, self->dlsap_sel);
+	IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
+		   __FUNCTION__, self->slsap_sel, self->dlsap_sel);
 
 	/* Make room for MUX control header (3 bytes) */
 	ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return -1;);
@@ -539,7 +540,7 @@
 	int lap_header_size;
 	int max_seg_size;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(skb != NULL, return;);
 	ASSERT(self != NULL, return;);
@@ -552,8 +553,8 @@
 	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",
-		   max_header_size);
+	IRDA_DEBUG(2, "%s(), max_header_size=%d\n",
+		   __FUNCTION__, max_header_size);
 
 	/* Hide LMP_CONTROL_HEADER header from layer above */
 	skb_pull(skb, LMP_CONTROL_HEADER);
@@ -578,13 +579,13 @@
 	struct lsap_cb *new;
 	unsigned long flags;
 
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
 	spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
 
 	/* Only allowed to duplicate unconnected LSAP's */
 	if (!hashbin_find(irlmp->unconnected_lsaps, (long) orig, NULL)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), unable to find LSAP\n");
+		IRDA_DEBUG(0, "%s(), unable to find LSAP\n", __FUNCTION__);
 		spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock,
 				       flags);
 		return NULL;
@@ -592,7 +593,7 @@
 	/* Allocate a new instance */
 	new = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
 	if (!new)  {
-		IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n");
+		IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__);
 		spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock,
 				       flags);
 		return NULL;
@@ -639,7 +640,7 @@
 	 * and us that might mess up the hashbins below. This fixes it.
 	 * Jean II */
 	if (! test_and_clear_bit(0, &self->connected)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), already disconnected!\n");
+		IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__);
 		dev_kfree_skb(userdata);
 		return -1;
 	}
@@ -689,19 +690,19 @@
 {
 	struct lsap_cb *lsap;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]);
+	IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__, lmp_reasons[reason]);
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
 
-	IRDA_DEBUG(3, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",
-		   self->slsap_sel, self->dlsap_sel);
+	IRDA_DEBUG(3, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
+		   __FUNCTION__, self->slsap_sel, self->dlsap_sel);
 
 	/* Already disconnected ?
 	 * There is a race condition between irlmp_disconnect_request()
 	 * and us that might mess up the hashbins below. This fixes it.
 	 * Jean II */
 	if (! test_and_clear_bit(0, &self->connected)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), already disconnected!\n");
+		IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__);
 		if (userdata)
 			dev_kfree_skb(userdata);
 		return;
@@ -733,7 +734,7 @@
 		self->notify.disconnect_indication(self->notify.instance,
 						   self, reason, userdata);
 	else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), no handler\n");
+		IRDA_DEBUG(0, "%s(), no handler\n", __FUNCTION__);
 		if (userdata)
 			dev_kfree_skb(userdata);
 	}
@@ -936,7 +937,7 @@
 {
 	discovery_t *discovery;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	/* Check if client wants or not partial/selective log (optimisation) */
 	if (!client->disco_callback)
@@ -979,7 +980,7 @@
 	irlmp_client_t *client;
 	irlmp_client_t *client_next;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(log != NULL, return;);
 
@@ -1012,7 +1013,7 @@
 	irlmp_client_t *client;
 	irlmp_client_t *client_next;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(expiry != NULL, return;);
 
@@ -1038,7 +1039,7 @@
  */
 discovery_t *irlmp_get_discovery_response()
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(irlmp != NULL, return NULL;);
 
@@ -1098,7 +1099,7 @@
  */
 int irlmp_udata_request(struct lsap_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(skb != NULL, return -1;);
 
@@ -1117,7 +1118,7 @@
  */
 void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
@@ -1142,7 +1143,7 @@
 	struct sk_buff *clone_skb;
 	struct lap_cb *lap;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(skb != NULL, return -1;);
 
@@ -1185,7 +1186,7 @@
 #ifdef CONFIG_IRDA_ULTRA
 void irlmp_connless_data_indication(struct lsap_cb *self, struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
@@ -1204,7 +1205,7 @@
 
 void irlmp_status_request(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
 }
 
 /*
@@ -1232,7 +1233,7 @@
 			curr->notify.status_indication(curr->notify.instance,
 						       link, lock);
 		else
-			IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n");
+			IRDA_DEBUG(2, "%s(), no handler\n", __FUNCTION__);
 
 		curr = next;
 	}
@@ -1260,7 +1261,7 @@
 	/* Get the number of lsap. That's the only safe way to know
 	 * that we have looped around... - Jean II */
 	lsap_todo = HASHBIN_GET_SIZE(self->lsaps);
-	IRDA_DEBUG(4, __FUNCTION__ "() : %d lsaps to scan\n", lsap_todo);
+	IRDA_DEBUG(4, "%s() : %d lsaps to scan\n", __FUNCTION__, lsap_todo);
 
 	/* Poll lsap in order until the queue is full or until we
 	 * tried them all.
@@ -1279,14 +1280,14 @@
 		/* Uh-oh... Paranoia */
 		if(curr == NULL)
 			break;
-		IRDA_DEBUG(4, __FUNCTION__ "() : curr is %p, next was %p and is now %p, still %d to go - queue len = %d\n", curr, next, self->flow_next, lsap_todo, IRLAP_GET_TX_QUEUE_LEN(self->irlap));
+		IRDA_DEBUG(4, "%s() : curr is %p, next was %p and is now %p, still %d to go - queue len = %d\n", __FUNCTION__, curr, next, self->flow_next, lsap_todo, IRLAP_GET_TX_QUEUE_LEN(self->irlap));
 
 		/* Inform lsap user that it can send one more packet. */
 		if (curr->notify.flow_indication != NULL)
 			curr->notify.flow_indication(curr->notify.instance,
 						     curr, flow);
 		else
-			IRDA_DEBUG(1, __FUNCTION__ "(), no handler\n");
+			IRDA_DEBUG(1, "%s(), no handler\n", __FUNCTION__);
 	}
 }
 
@@ -1307,7 +1308,7 @@
 	 */
 	service = kmalloc(16, GFP_ATOMIC);
 	if (!service) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n");
+		IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 
@@ -1413,7 +1414,7 @@
 		hint.word = 0xffff;
 		break;
 	default:
-		IRDA_DEBUG( 1, __FUNCTION__ "(), Unknown service!\n");
+		IRDA_DEBUG( 1, "%s(), Unknown service!\n", __FUNCTION__);
 		break;
 	}
 	return hint.word;
@@ -1429,12 +1430,12 @@
 {
 	irlmp_service_t *service;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), hints = %04x\n", hints);
+	IRDA_DEBUG(4, "%s(), hints = %04x\n", __FUNCTION__, hints);
 
 	/* Make a new registration */
 	service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC);
 	if (!service) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n");
+		IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
 		return 0;
 	}
 	service->hints = hints;
@@ -1458,7 +1459,7 @@
 	irlmp_service_t *service;
 	unsigned long flags;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	if (!handle)
 		return -1;
@@ -1466,7 +1467,7 @@
 	/* Caller may call with invalid handle (it's legal) - Jean II */
 	service = hashbin_lock_find(irlmp->services, (long) handle, NULL);
 	if (!service) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown service!\n");
+		IRDA_DEBUG(1, "%s(), Unknown service!\n", __FUNCTION__);
 		return -1;
 	}
 
@@ -1502,13 +1503,13 @@
 {
 	irlmp_client_t *client;
 
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 	ASSERT(irlmp != NULL, return 0;);
 
 	/* Make a new registration */
 	client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC);
 	if (!client) {
-		IRDA_DEBUG( 1, __FUNCTION__ "(), Unable to kmalloc!\n");
+		IRDA_DEBUG( 1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
 		return 0;
 	}
 
@@ -1543,7 +1544,7 @@
 
 	client = hashbin_lock_find(irlmp->clients, (long) handle, NULL);
 	if (!client) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n");
+		IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__);
 		return -1;
 	}
 
@@ -1565,7 +1566,7 @@
 {
 	struct irlmp_client *client;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	if (!handle)
 		return -1;
@@ -1573,11 +1574,11 @@
 	/* Caller may call with invalid handle (it's legal) - Jean II */
 	client = hashbin_lock_find(irlmp->clients, (long) handle, NULL);
 	if (!client) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n");
+		IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__);
 		return -1;
 	}
 
-	IRDA_DEBUG( 4, __FUNCTION__ "(), removing client!\n");
+	IRDA_DEBUG(4, "%s(), removing client!\n", __FUNCTION__);
 	hashbin_remove_this(irlmp->clients, (irda_queue_t *) client);
 	kfree(client);
 
@@ -1599,7 +1600,7 @@
 	ASSERT(irlmp->magic == LMP_MAGIC, return TRUE;);
 	ASSERT(slsap_sel != LSAP_ANY, return TRUE;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 #ifdef CONFIG_IRDA_ULTRA
 	/* Accept all bindings to the connectionless LSAP */
@@ -1674,7 +1675,8 @@
 				return 0;
 		}
 	}
-	IRDA_DEBUG(4, __FUNCTION__ "(), next free lsap_sel=%02x\n", lsap_sel);
+	IRDA_DEBUG(4, "%s(), next free lsap_sel=%02x\n",
+		   __FUNCTION__, lsap_sel);
 
 	return lsap_sel;
 }
@@ -1692,26 +1694,26 @@
 
 	switch (lap_reason) {
 	case LAP_DISC_INDICATION: /* Received a disconnect request from peer */
-		IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_DISC_INDICATION\n");
+		IRDA_DEBUG( 1, "%s(), LAP_DISC_INDICATION\n", __FUNCTION__);
 		reason = LM_USER_REQUEST;
 		break;
 	case LAP_NO_RESPONSE:    /* To many retransmits without response */
-		IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_NO_RESPONSE\n");
+		IRDA_DEBUG( 1, "%s(), LAP_NO_RESPONSE\n", __FUNCTION__);
 		reason = LM_LAP_DISCONNECT;
 		break;
 	case LAP_RESET_INDICATION:
-		IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_RESET_INDICATION\n");
+		IRDA_DEBUG( 1, "%s(), LAP_RESET_INDICATION\n", __FUNCTION__);
 		reason = LM_LAP_RESET;
 		break;
 	case LAP_FOUND_NONE:
 	case LAP_MEDIA_BUSY:
 	case LAP_PRIMARY_CONFLICT:
-		IRDA_DEBUG(1, __FUNCTION__ "(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n");
+		IRDA_DEBUG(1, "%s(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n", __FUNCTION__);
 		reason = LM_CONNECT_FAILURE;
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__
-		      "(), Unknow IrLAP disconnect reason %d!\n", lap_reason);
+		IRDA_DEBUG(1, "%s(), Unknow IrLAP disconnect reason %d!\n",
+			   __FUNCTION__, lap_reason);
 		reason = LM_LAP_DISCONNECT;
 		break;
 	}
diff -Nru a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c
--- a/net/irda/irlmp_event.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/irlmp_event.c	Fri Sep 27 14:51:03 2002
@@ -121,7 +121,7 @@
 					IRLMP_STATE state)
 {
 	/*
-	IRDA_DEBUG(4, __FUNCTION__ "(), LMP LAP = %s\n", irlmp_state[state]);
+	IRDA_DEBUG(4, "%s(), LMP LAP = %s\n", __FUNCTION__, irlmp_state[state]);
 	*/
 	self->lap_state = state;
 }
@@ -131,7 +131,7 @@
 {
 	/*
 	ASSERT(self != NULL, return;);
-	IRDA_DEBUG(4, __FUNCTION__ "(), LMP LSAP = %s\n", irlsap_state[state]);
+	IRDA_DEBUG(4, "%s(), LMP LSAP = %s\n", __FUNCTION__, irlsap_state[state]);
 	*/
 	self->lsap_state = state;
 }
@@ -143,8 +143,8 @@
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
-		   irlmp_event[event], irlsap_state[ self->lsap_state]);
+	IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n",
+		__FUNCTION__, irlmp_event[event], irlsap_state[ self->lsap_state]);
 
 	return (*lsap_state[self->lsap_state]) (self, event, skb);
 }
@@ -161,7 +161,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
+	IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n", __FUNCTION__,
 		   irlmp_event[event],
 		   irlmp_state[self->lap_state]);
 
@@ -170,7 +170,7 @@
 
 void irlmp_discovery_timer_expired(void *data)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	/* We always cleanup the log (active & passive discovery) */
 	irlmp_do_expiry();
@@ -187,7 +187,7 @@
 {
 	struct lsap_cb *self = (struct lsap_cb *) data;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
@@ -199,7 +199,7 @@
 {
 	struct lap_cb *self = (struct lap_cb *) data;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
@@ -259,7 +259,7 @@
 static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
 				struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 	ASSERT(self->irlap != NULL, return;);
 
 	switch (event) {
@@ -279,7 +279,7 @@
 		irlap_connect_response(self->irlap, skb);
 		break;
 	case LM_LAP_CONNECT_REQUEST:
-		IRDA_DEBUG(4, __FUNCTION__ "() LS_CONNECT_REQUEST\n");
+		IRDA_DEBUG(4, "%s() LS_CONNECT_REQUEST\n", __FUNCTION__);
 
 		irlmp_next_lap_state(self, LAP_U_CONNECT);
 
@@ -287,14 +287,14 @@
 		irlap_connect_request(self->irlap, self->daddr, NULL, 0);
 		break;
 	case LM_LAP_DISCONNECT_INDICATION:
-		IRDA_DEBUG(4, __FUNCTION__
-			   "(), Error LM_LAP_DISCONNECT_INDICATION\n");
+		IRDA_DEBUG(4, "%s(), Error LM_LAP_DISCONNECT_INDICATION\n",
+			   __FUNCTION__);
 
 		irlmp_next_lap_state(self, LAP_STANDBY);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			   __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -311,7 +311,7 @@
 static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
 				  struct sk_buff *skb)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(), event=%s\n", irlmp_event[event]);
+	IRDA_DEBUG(2, "%s(), event=%s\n", __FUNCTION__, irlmp_event[event]);
 
 	switch (event) {
 	case LM_LAP_CONNECT_INDICATION:
@@ -331,7 +331,7 @@
 		 * the lsaps may already have gone. This avoid getting stuck
 		 * forever in LAP_ACTIVE state - Jean II */
 		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
-			IRDA_DEBUG(0, __FUNCTION__ "() NO LSAPs !\n");
+			IRDA_DEBUG(0, "%s() NO LSAPs !\n",  __FUNCTION__);
 			irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
 		}
 		break;
@@ -349,12 +349,12 @@
 		 * the lsaps may already have gone. This avoid getting stuck
 		 * forever in LAP_ACTIVE state - Jean II */
 		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
-			IRDA_DEBUG(0, __FUNCTION__ "() NO LSAPs !\n");
+			IRDA_DEBUG(0, "%s() NO LSAPs !\n",  __FUNCTION__);
 			irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
 		}
 		break;
 	case LM_LAP_DISCONNECT_INDICATION:
-		IRDA_DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_INDICATION\n");
+		IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_INDICATION\n",  __FUNCTION__);
 		irlmp_next_lap_state(self, LAP_STANDBY);
 
 		/* Send disconnect event to all LSAPs using this link */
@@ -362,7 +362,7 @@
 					LM_LAP_DISCONNECT_INDICATION);
 		break;
 	case LM_LAP_DISCONNECT_REQUEST:
-		IRDA_DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
+		IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_REQUEST\n",  __FUNCTION__);
 
 		/* One of the LSAP did timeout or was closed, if it was
 		 * the last one, try to get out of here - Jean II */
@@ -371,8 +371,8 @@
 		}
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			 __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -388,11 +388,11 @@
 static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
 			       struct sk_buff *skb)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	switch (event) {
 	case LM_LAP_CONNECT_REQUEST:
-		IRDA_DEBUG(4, __FUNCTION__ "(), LS_CONNECT_REQUEST\n");
+		IRDA_DEBUG(4, "%s(), LS_CONNECT_REQUEST\n", __FUNCTION__);
 
 		/*
 		 *  LAP connection allready active, just bounce back! Since we
@@ -466,8 +466,8 @@
 		irlmp_do_expiry();
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			 __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -491,7 +491,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
@@ -503,7 +503,7 @@
 		break;
 #endif /* CONFIG_IRDA_ULTRA */
 	case LM_CONNECT_REQUEST:
-		IRDA_DEBUG(4, __FUNCTION__ "(), LM_CONNECT_REQUEST\n");
+		IRDA_DEBUG(4, "%s(), LM_CONNECT_REQUEST\n", __FUNCTION__);
 
 		if (self->conn_skb) {
 			WARNING("%s: busy with another request!\n",
@@ -545,8 +545,8 @@
 		irlmp_start_watchdog_timer(self, 1*HZ);
 		break;
 	default:
-		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(2, "%s(), Unknown event %s\n",
+			   __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -566,7 +566,7 @@
 	struct lsap_cb *lsap;
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
@@ -597,15 +597,15 @@
 	case LM_WATCHDOG_TIMEOUT:
 		/* May happen, who knows...
 		 * Jean II */
-		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
+		IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n",  __FUNCTION__);
 
 		/* Disconnect, get out... - Jean II */
 		self->dlsap_sel = LSAP_ANY;
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			 __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -624,7 +624,7 @@
 {
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
@@ -634,17 +634,17 @@
 		/* Keep state */
 		break;
 	case LM_CONNECT_RESPONSE:
-		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, "
-			   "no indication issued yet\n");
+		IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
+			   "no indication issued yet\n",  __FUNCTION__);
 		/* Keep state */
 		break;
 	case LM_DISCONNECT_REQUEST:
-		IRDA_DEBUG(0, __FUNCTION__ "(), LM_DISCONNECT_REQUEST, "
-			   "not yet bound to IrLAP connection\n");
+		IRDA_DEBUG(0, "%s(), LM_DISCONNECT_REQUEST, "
+			   "not yet bound to IrLAP connection\n",  __FUNCTION__);
 		/* Keep state */
 		break;
 	case LM_LAP_CONNECT_CONFIRM:
-		IRDA_DEBUG(4, __FUNCTION__ "(), LS_CONNECT_CONFIRM\n");
+		IRDA_DEBUG(4, "%s(), LS_CONNECT_CONFIRM\n",  __FUNCTION__);
 		irlmp_next_lsap_state(self, LSAP_CONNECT);
 
 		skb = self->conn_skb;
@@ -656,7 +656,7 @@
 		/* Will happen in some rare cases because of a race condition.
 		 * Just make sure we don't stay there forever...
 		 * Jean II */
-		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
+		IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n",  __FUNCTION__);
 
 		/* Go back to disconnected mode, keep the socket waiting */
 		self->dlsap_sel = LSAP_ANY;
@@ -666,8 +666,8 @@
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			    __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -687,7 +687,7 @@
 	LM_REASON reason;
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
@@ -710,13 +710,13 @@
 		irlmp_udata_indication(self, skb);
 		break;
 	case LM_CONNECT_REQUEST:
-		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_REQUEST, "
-			   "error, LSAP already connected\n");
+		IRDA_DEBUG(0, "%s(), LM_CONNECT_REQUEST, "
+			   "error, LSAP already connected\n", __FUNCTION__);
 		/* Keep state */
 		break;
 	case LM_CONNECT_RESPONSE:
-		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, "
-			   "error, LSAP allready connected\n");
+		IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
+			   "error, LSAP allready connected\n", __FUNCTION__);
 		/* Keep state */
 		break;
 	case LM_DISCONNECT_REQUEST:
@@ -726,7 +726,8 @@
 
 		/* Try to close the LAP connection if its still there */
 		if (self->lap) {
-			IRDA_DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n");
+			IRDA_DEBUG(4, "%s(), trying to close IrLAP\n",
+				   __FUNCTION__);
 			irlmp_do_lap_event(self->lap,
 					   LM_LAP_DISCONNECT_REQUEST,
 					   NULL);
@@ -750,14 +751,14 @@
 		reason = skb->data[3];
 
 		 /* Try to close the LAP connection */
-		IRDA_DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n");
+		IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __FUNCTION__);
 		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
 
 		irlmp_disconnect_indication(self, reason, skb);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			    __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -781,7 +782,7 @@
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	switch (event) {
 	case LM_CONNECT_CONFIRM:
@@ -802,7 +803,7 @@
 		reason = skb->data[3];
 
 		 /* Try to close the LAP connection */
-		IRDA_DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n");
+		IRDA_DEBUG(4, "%s(), trying to close IrLAP\n",  __FUNCTION__);
 		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
 
 		irlmp_disconnect_indication(self, reason, skb);
@@ -820,7 +821,7 @@
 		irlmp_disconnect_indication(self, reason, skb);
 		break;
 	case LM_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
+		IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);
 
 		ASSERT(self->lap != NULL, return -1;);
 		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
@@ -829,8 +830,8 @@
 		irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			    __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
@@ -852,7 +853,7 @@
 	LM_REASON reason;
 	int ret = 0;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(irlmp != NULL, return -1;);
@@ -870,7 +871,7 @@
 		irlmp_next_lsap_state(self, LSAP_SETUP);
 		break;
 	case LM_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(0, __FUNCTION__ "() : WATCHDOG_TIMEOUT !\n");
+		IRDA_DEBUG(0, "%s() : WATCHDOG_TIMEOUT !\n",  __FUNCTION__);
 
 		ASSERT(self->lap != NULL, return -1;);
 		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
@@ -888,8 +889,8 @@
 		irlmp_disconnect_indication(self, reason, NULL);
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
-			   irlmp_event[event]);
+		IRDA_DEBUG(0, "%s(), Unknown event %s\n",
+			   __FUNCTION__, irlmp_event[event]);
 		if (skb)
 			dev_kfree_skb(skb);
 		break;
diff -Nru a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c
--- a/net/irda/irlmp_frame.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irlmp_frame.c	Fri Sep 27 14:51:04 2002
@@ -45,7 +45,7 @@
 	skb->data[1] = slsap;
 
 	if (expedited) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), sending expedited data\n");
+		IRDA_DEBUG(4, "%s(), sending expedited data\n", __FUNCTION__);
 		irlap_data_request(self->irlap, skb, TRUE);
 	} else
 		irlap_data_request(self->irlap, skb, FALSE);
@@ -61,7 +61,7 @@
 {
 	__u8 *frame;
 	
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
@@ -96,7 +96,7 @@
 	__u8   dlsap_sel;   /* Destination LSAP address */
 	__u8   *fp;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
@@ -116,9 +116,9 @@
 	 *  it in a different way than other established connections.
 	 */
 	if ((fp[0] & CONTROL_BIT) && (fp[2] == CONNECT_CMD)) {
-		IRDA_DEBUG(3, __FUNCTION__ "(), incoming connection, "
+		IRDA_DEBUG(3, "%s(), incoming connection, "
 			   "source LSAP=%d, dest LSAP=%d\n",
-			   slsap_sel, dlsap_sel);
+			   __FUNCTION__, slsap_sel, dlsap_sel);
 		
 		/* Try to find LSAP among the unconnected LSAPs */
 		lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, CONNECT_CMD,
@@ -126,7 +126,7 @@
 		
 		/* Maybe LSAP was already connected, so try one more time */
 		if (!lsap) {
-			IRDA_DEBUG(1, __FUNCTION__ "(), incoming connection for LSAP already connected\n");
+			IRDA_DEBUG(1, "%s(), incoming connection for LSAP already connected\n", __FUNCTION__);
 			lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, 0,
 					       self->lsaps);
 		}
@@ -136,14 +136,13 @@
 	
 	if (lsap == NULL) {
 		IRDA_DEBUG(2, "IrLMP, Sorry, no LSAP for received frame!\n");
-		IRDA_DEBUG(2, __FUNCTION__ 
-		      "(), slsap_sel = %02x, dlsap_sel = %02x\n", slsap_sel, 
-		      dlsap_sel);
+		IRDA_DEBUG(2, "%s(), slsap_sel = %02x, dlsap_sel = %02x\n",
+			   __FUNCTION__, slsap_sel, dlsap_sel);
 		if (fp[0] & CONTROL_BIT) {
-			IRDA_DEBUG(2, __FUNCTION__ 
-			      "(), received control frame %02x\n", fp[2]);
+			IRDA_DEBUG(2, "%s(), received control frame %02x\n",
+				   __FUNCTION__, fp[2]);
 		} else {
-			IRDA_DEBUG(2, __FUNCTION__ "(), received data frame\n");
+			IRDA_DEBUG(2, "%s(), received data frame\n", __FUNCTION__);
 		}
 		dev_kfree_skb(skb);
 		return;
@@ -162,8 +161,8 @@
 			irlmp_do_lsap_event(lsap, LM_CONNECT_CONFIRM, skb);
 			break;
 		case DISCONNECT:
-			IRDA_DEBUG(4, __FUNCTION__ 
-				   "(), Disconnect indication!\n");
+			IRDA_DEBUG(4, "%s(), Disconnect indication!\n",
+				   __FUNCTION__);
 			irlmp_do_lsap_event(lsap, LM_DISCONNECT_INDICATION, 
 					    skb);
 			break;
@@ -176,8 +175,8 @@
 			dev_kfree_skb(skb);
 			break;
 		default:
-			IRDA_DEBUG(0, __FUNCTION__ 
-				   "(), Unknown control frame %02x\n", fp[2]);
+			IRDA_DEBUG(0, "%s(), Unknown control frame %02x\n",
+				   __FUNCTION__, fp[2]);
 			dev_kfree_skb(skb);
 			break;
 		}
@@ -212,7 +211,7 @@
 	__u8   *fp;
 	unsigned long flags;
 	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
@@ -229,7 +228,8 @@
 	pid       = fp[2];
 	
 	if (pid & 0x80) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), extension in PID not supp!\n");
+		IRDA_DEBUG(0, "%s(), extension in PID not supp!\n",
+			   __FUNCTION__);
 		dev_kfree_skb(skb);
 
 		return;
@@ -237,7 +237,7 @@
 
 	/* Check if frame is addressed to the connectionless LSAP */
 	if ((slsap_sel != LSAP_CONNLESS) || (dlsap_sel != LSAP_CONNLESS)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), dropping frame!\n");
+		IRDA_DEBUG(0, "%s(), dropping frame!\n", __FUNCTION__);
 		dev_kfree_skb(skb);
 		
 		return;
@@ -263,7 +263,7 @@
 	if (lsap)
 		irlmp_connless_data_indication(lsap, skb);
 	else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), found no matching LSAP!\n");
+		IRDA_DEBUG(0, "%s(), found no matching LSAP!\n", __FUNCTION__);
 		dev_kfree_skb(skb);
 	}
 }
@@ -280,7 +280,7 @@
 				      LAP_REASON reason, 
 				      struct sk_buff *userdata)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(lap != NULL, return;);
 	ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
@@ -308,7 +308,7 @@
 				   __u32 daddr, struct qos_info *qos,
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	/* Copy QoS settings for this session */
 	self->qos = qos;
@@ -329,7 +329,7 @@
 void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos, 
 				struct sk_buff *userdata)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
@@ -397,7 +397,7 @@
  */
 void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log)
 {
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
diff -Nru a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
--- a/net/irda/irnet/irnet.h	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irnet/irnet.h	Fri Sep 27 14:51:04 2002
@@ -326,29 +326,29 @@
  * compiler will optimise away the if() in all cases.
  */
 /* All error messages (will show up in the normal logs) */
-#define DERROR(dbg, args...) \
+#define DERROR(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_INFO "irnet: " __FUNCTION__ "(): " args);}
+		printk(KERN_INFO "irnet: %s(): " format, __FUNCTION__ , ##args);}
 
 /* Normal debug message (will show up in /var/log/debug) */
-#define DEBUG(dbg, args...) \
+#define DEBUG(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_DEBUG "irnet: " __FUNCTION__ "(): " args);}
+		printk(KERN_DEBUG "irnet: %s(): " format, __FUNCTION__ , ##args);}
 
 /* Entering a function (trace) */
-#define DENTER(dbg, args...) \
+#define DENTER(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_DEBUG "irnet: ->" __FUNCTION__ args);}
+		printk(KERN_DEBUG "irnet: -> %s" format, __FUNCTION__ , ##args);}
 
 /* Entering and exiting a function in one go (trace) */
-#define DPASS(dbg, args...) \
+#define DPASS(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_DEBUG "irnet: <>" __FUNCTION__ args);}
+		printk(KERN_DEBUG "irnet: <>%s" format, __FUNCTION__ , ##args);}
 
 /* Exiting a function (trace) */
-#define DEXIT(dbg, args...) \
+#define DEXIT(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_DEBUG "irnet: <-" __FUNCTION__ "()" args);}
+		printk(KERN_DEBUG "irnet: <-%s()" format, __FUNCTION__ , ##args);}
 
 /* Exit a function with debug */
 #define DRETURN(ret, dbg, args...) \
@@ -434,7 +434,7 @@
 
   /* ------------------- IrLMP and IrIAS part ------------------- */
   /* Used for IrDA Discovery and socket name resolution */
-  __u32			ckey;		/* IrLMP client handle */
+  void *		ckey;		/* IrLMP client handle */
   __u16			mask;		/* Hint bits mask (filter discov.)*/
   int			nslots;		/* Number of slots for discovery */
 
diff -Nru a/net/irda/irnet/irnet_irda.h b/net/irda/irnet/irnet_irda.h
--- a/net/irda/irnet/irnet_irda.h	Fri Sep 27 14:51:03 2002
+++ b/net/irda/irnet/irnet_irda.h	Fri Sep 27 14:51:03 2002
@@ -53,7 +53,7 @@
    * reentrant, beware... So, we blindly protect all with spinlock */
 
   /* Handle for the hint bit advertised in IrLMP */
-  __u32			skey;
+  void *		skey;
 
   /* Server socket part */
   struct ias_object *	ias_obj;	/* Our service name + lsap in IAS */
diff -Nru a/net/irda/irqueue.c b/net/irda/irqueue.c
--- a/net/irda/irqueue.c	Fri Sep 27 14:51:03 2002
+++ b/net/irda/irqueue.c	Fri Sep 27 14:51:03 2002
@@ -231,7 +231,7 @@
 static void enqueue_first(irda_queue_t **queue, irda_queue_t* element)
 {
 	
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
 	/*
 	 * Check if queue is empty.
@@ -263,7 +263,7 @@
  */
 static void __enqueue_last( irda_queue_t **queue, irda_queue_t* element)
 {
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
 	/*
 	 * Check if queue is empty.
@@ -572,7 +572,7 @@
 	unsigned long flags = 0;
 	int bin;
 
-	IRDA_DEBUG( 4, __FUNCTION__"()\n");
+	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
 	ASSERT( hashbin != NULL, return;);
 	ASSERT( hashbin->magic == HB_MAGIC, return;);
@@ -689,7 +689,7 @@
 	unsigned long flags = 0;
 	irda_queue_t* entry;
 
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
 	ASSERT( hashbin != NULL, return NULL;);
 	ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
@@ -781,7 +781,7 @@
 	int	bin;
 	long	hashv;
 
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
 	ASSERT( hashbin != NULL, return NULL;);
 	ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
diff -Nru a/net/irda/irsyms.c b/net/irda/irsyms.c
--- a/net/irda/irsyms.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/irsyms.c	Fri Sep 27 14:51:05 2002
@@ -204,11 +204,11 @@
 	
         switch (event) {
 	case NETDEV_UP:
-		IRDA_DEBUG(3, __FUNCTION__ "(), NETDEV_UP\n");
+		IRDA_DEBUG(3, "%s(), NETDEV_UP\n", __FUNCTION__);
 		/* irda_dev_device_up(dev); */
 		break;
 	case NETDEV_DOWN:
-		IRDA_DEBUG(3, __FUNCTION__ "(), NETDEV_DOWN\n");
+		IRDA_DEBUG(3, "%s(), NETDEV_DOWN\n", __FUNCTION__);
 		/* irda_kill_by_device(dev); */
 		/* irda_rt_device_down(dev); */
 		/* irda_dev_device_down(dev); */
@@ -253,7 +253,7 @@
  */
 int __init irda_init(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
 	/* Lower layer of the stack */
  	irlmp_init();
diff -Nru a/net/irda/irttp.c b/net/irda/irttp.c
--- a/net/irda/irttp.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/irttp.c	Fri Sep 27 14:51:04 2002
@@ -162,7 +162,7 @@
 	if (!self || self->magic != TTP_TSAP_MAGIC)
 		return;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(instance=%p)\n", self);
+	IRDA_DEBUG(4, "%s(instance=%p)\n", __FUNCTION__, self);
 
 	/* Try to make some progress, especially on Tx side - Jean II */
 	irttp_run_rx_queue(self);
@@ -203,7 +203,7 @@
 {
 	struct sk_buff* skb;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
@@ -236,7 +236,7 @@
 	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, "%s(), self->rx_sdu_size=%d\n", __FUNCTION__,
 		   self->rx_sdu_size);
 
 	skb = dev_alloc_skb(TTP_HEADER + self->rx_sdu_size);
@@ -259,9 +259,10 @@
 
 		dev_kfree_skb(frag);
 	}
-	IRDA_DEBUG(2, __FUNCTION__ "(), frame len=%d\n", n);
+	IRDA_DEBUG(2, "%s(), frame len=%d\n",  __FUNCTION__, n);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), rx_sdu_size=%d\n", self->rx_sdu_size);
+	IRDA_DEBUG(2, "%s(), rx_sdu_size=%d\n",  __FUNCTION__,
+		   self->rx_sdu_size);
 	ASSERT(n <= self->rx_sdu_size, return NULL;);
 
 	/* Set the new length */
@@ -284,7 +285,7 @@
 	struct sk_buff *frag;
 	__u8 *frame;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
@@ -294,7 +295,7 @@
 	 *  Split frame into a number of segments
 	 */
 	while (skb->len > self->max_seg_size) {
-		IRDA_DEBUG(2, __FUNCTION__  "(), fragmenting ...\n");
+		IRDA_DEBUG(2, "%s(), fragmenting ...\n", __FUNCTION__);
 
 		/* Make new segment */
 		frag = dev_alloc_skb(self->max_seg_size+self->max_header_size);
@@ -318,7 +319,7 @@
 		skb_queue_tail(&self->tx_queue, frag);
 	}
 	/* Queue what is left of the original skb */
-	IRDA_DEBUG(2, __FUNCTION__  "(), queuing last segment\n");
+	IRDA_DEBUG(2, "%s(), queuing last segment\n", __FUNCTION__);
 
 	frame = skb_push(skb, TTP_HEADER);
 	frame[0] = 0x00; /* Clear more bit */
@@ -349,7 +350,7 @@
 	else
 		self->tx_max_sdu_size = param->pv.i;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), MaxSduSize=%d\n", param->pv.i);
+	IRDA_DEBUG(1, "%s(), MaxSduSize=%d\n", __FUNCTION__, param->pv.i);
 
 	return 0;
 }
@@ -377,13 +378,13 @@
 	 * JeanII */
 	if((stsap_sel != LSAP_ANY) &&
 	   ((stsap_sel < 0x01) || (stsap_sel >= 0x70))) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), invalid tsap!\n");
+		IRDA_DEBUG(0, "%s(), invalid tsap!\n", __FUNCTION__);
 		return NULL;
 	}
 
 	self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
 	if (self == NULL) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc!\n");
+		IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
 	memset(self, 0, sizeof(struct tsap_cb));
@@ -428,7 +429,7 @@
 	 *  the stsap_sel we have might not be valid anymore
 	 */
 	self->stsap_sel = lsap->slsap_sel;
-	IRDA_DEBUG(4, __FUNCTION__ "(), stsap_sel=%02x\n", self->stsap_sel);
+	IRDA_DEBUG(4, "%s(), stsap_sel=%02x\n", __FUNCTION__, self->stsap_sel);
 
 	self->notify = *notify;
 	self->lsap = lsap;
@@ -485,7 +486,7 @@
 {
 	struct tsap_cb *tsap;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
@@ -530,16 +531,18 @@
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
 	ASSERT(skb != NULL, return -1;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	/* Check that nothing bad happens */
 	if ((skb->len == 0) || (!self->connected)) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), No data, or not connected\n");
+		IRDA_DEBUG(1, "%s(), No data, or not connected\n",
+			   __FUNCTION__);
 		return -1;
 	}
 
 	if (skb->len > self->max_seg_size) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), UData is to large for IrLAP!\n");
+		IRDA_DEBUG(1, "%s(), UData is to large for IrLAP!\n",
+			   __FUNCTION__);
 		return -1;
 	}
 
@@ -563,7 +566,7 @@
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
 	ASSERT(skb != NULL, return -1;);
 
-	IRDA_DEBUG(2, __FUNCTION__ " : queue len = %d\n",
+	IRDA_DEBUG(2, "%s() : queue len = %d\n", __FUNCTION__,
 		   skb_queue_len(&self->tx_queue));
 
 	/* Check that nothing bad happens */
@@ -662,7 +665,8 @@
 	unsigned long flags;
 	int n;
 
-	IRDA_DEBUG(2, __FUNCTION__ "() : send_credit = %d, queue_len = %d\n",
+	IRDA_DEBUG(2, "%s() : send_credit = %d, queue_len = %d\n",
+		   __FUNCTION__,
 		   self->send_credit, skb_queue_len(&self->tx_queue));
 
 	/* Get exclusive access to the tx queue, otherwise don't touch it */
@@ -770,7 +774,8 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
+	IRDA_DEBUG(4, "%s() send=%d,avail=%d,remote=%d\n",
+		   __FUNCTION__,
 		   self->send_credit, self->avail_credit, self->remote_credit);
 
 	/* Give credit to peer */
@@ -818,7 +823,7 @@
 {
 	struct tsap_cb *self;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	self = (struct tsap_cb *) instance;
 
@@ -930,7 +935,7 @@
 {
 	struct tsap_cb *self;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	self = (struct tsap_cb *) instance;
 
@@ -944,7 +949,7 @@
 		self->notify.status_indication(self->notify.instance,
 					       link, lock);
 	else
-		IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n");
+		IRDA_DEBUG(2, "%s(), no handler\n", __FUNCTION__);
 }
 
 /*
@@ -962,7 +967,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
 
-	IRDA_DEBUG(4, __FUNCTION__ "(instance=%p)\n", self);
+	IRDA_DEBUG(4, "%s(instance=%p)\n", __FUNCTION__, self);
 
 	/* We are "polled" directly from LAP, and the LAP want to fill
 	 * its Tx window. We want to do our best to send it data, so that
@@ -1000,18 +1005,18 @@
  */
 void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
 
 	switch (flow) {
 	case FLOW_STOP:
-		IRDA_DEBUG(1, __FUNCTION__ "(), flow stop\n");
+		IRDA_DEBUG(1, "%s(), flow stop\n", __FUNCTION__);
 		self->rx_sdu_busy = TRUE;
 		break;
 	case FLOW_START:
-		IRDA_DEBUG(1, __FUNCTION__ "(), flow start\n");
+		IRDA_DEBUG(1, "%s(), flow start\n", __FUNCTION__);
 		self->rx_sdu_busy = FALSE;
 
 		/* Client say he can accept more data, try to free our
@@ -1020,7 +1025,7 @@
 
 		break;
 	default:
-		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown flow command!\n");
+		IRDA_DEBUG(1, "%s(), Unknown flow command!\n", __FUNCTION__);
 	}
 }
 
@@ -1039,7 +1044,7 @@
 	__u8 *frame;
 	__u8 n;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), max_sdu_size=%d\n", max_sdu_size);
+	IRDA_DEBUG(4, "%s(), max_sdu_size=%d\n", __FUNCTION__, max_sdu_size);
 
 	ASSERT(self != NULL, return -EBADR;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return -EBADR;);
@@ -1131,7 +1136,7 @@
 	__u8 plen;
 	__u8 n;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	self = (struct tsap_cb *) instance;
 
@@ -1155,7 +1160,7 @@
 
 	n = skb->data[0] & 0x7f;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), Initial send_credit=%d\n", n);
+	IRDA_DEBUG(4, "%s(), Initial send_credit=%d\n", __FUNCTION__, n);
 
 	self->send_credit = n;
 	self->tx_max_sdu_size = 0;
@@ -1186,10 +1191,11 @@
 		skb_pull(skb, IRDA_MIN(skb->len, plen+1));
 	}
 
-	IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
+	IRDA_DEBUG(4, "%s() send=%d,avail=%d,remote=%d\n", __FUNCTION__,
 	      self->send_credit, self->avail_credit, self->remote_credit);
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size);
+	IRDA_DEBUG(2, "%s(), MaxSduSize=%d\n", __FUNCTION__,
+		   self->tx_max_sdu_size);
 
 	if (self->notify.connect_confirm) {
 		self->notify.connect_confirm(self->notify.instance, self, qos,
@@ -1226,7 +1232,7 @@
 	self->max_seg_size = max_seg_size - TTP_HEADER;;
 	self->max_header_size = max_header_size+TTP_HEADER;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel);
+	IRDA_DEBUG(4, "%s(), TSAP sel=%02x\n", __FUNCTION__, self->stsap_sel);
 
 	/* Need to update dtsap_sel if its equal to LSAP_ANY */
 	self->dtsap_sel = lsap->dlsap_sel;
@@ -1288,7 +1294,7 @@
 	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, "%s(), Source TSAP selector=%02x\n", __FUNCTION__,
 		   self->stsap_sel);
 
 	/* Any userdata supplied? */
@@ -1367,14 +1373,14 @@
 	struct tsap_cb *new;
 	unsigned long flags;
 
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
 	/* Protect our access to the old tsap instance */
 	spin_lock_irqsave(&irttp->tsaps->hb_spinlock, flags);
 
 	/* Find the old instance */
 	if (!hashbin_find(irttp->tsaps, (int) orig, NULL)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), unable to find TSAP\n");
+		IRDA_DEBUG(0, "%s(), unable to find TSAP\n", __FUNCTION__);
 		spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
 		return NULL;
 	}
@@ -1382,7 +1388,7 @@
 	/* Allocate a new instance */
 	new = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
 	if (!new) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n");
+		IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__);
 		spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
 		return NULL;
 	}
@@ -1425,7 +1431,7 @@
 
 	/* Already disconnected? */
 	if (!self->connected) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), already disconnected!\n");
+		IRDA_DEBUG(4, "%s(), already disconnected!\n", __FUNCTION__);
 		if (userdata)
 			dev_kfree_skb(userdata);
 		return -1;
@@ -1437,7 +1443,8 @@
 	 * for following a disconnect_indication() (i.e. net_bh).
 	 * Jean II */
 	if(test_and_set_bit(0, &self->disconnect_pend)) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), disconnect already pending\n");
+		IRDA_DEBUG(0, "%s(), disconnect already pending\n",
+			   __FUNCTION__);
 		if (userdata)
 			dev_kfree_skb(userdata);
 
@@ -1456,7 +1463,7 @@
 			 *  disconnecting right now since the data will
 			 *  not have any usable connection to be sent on
 			 */
-			IRDA_DEBUG(1, __FUNCTION__  "High priority!!()\n" );
+			IRDA_DEBUG(1, "%s(): High priority!!()\n", __FUNCTION__);
 			irttp_flush_queues(self);
 		} else if (priority == P_NORMAL) {
 			/*
@@ -1477,7 +1484,7 @@
 	 * be sent at the LMP level (so even if the peer has its Tx queue
 	 * full of data). - Jean II */
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), Disconnecting ...\n");
+	IRDA_DEBUG(1, "%s(), Disconnecting ...\n", __FUNCTION__);
 	self->connected = FALSE;
 
 	if (!userdata) {
@@ -1511,7 +1518,7 @@
 {
 	struct tsap_cb *self;
 
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	self = (struct tsap_cb *) instance;
 
@@ -1571,7 +1578,7 @@
 	 * give an error back
 	 */
 	if (err == -ENOMEM) {
-		IRDA_DEBUG(0, __FUNCTION__ "() requeueing skb!\n");
+		IRDA_DEBUG(0, "%s() requeueing skb!\n", __FUNCTION__);
 
 		/* Make sure we take a break */
 		self->rx_sdu_busy = TRUE;
@@ -1596,7 +1603,7 @@
 	struct sk_buff *skb;
 	int more = 0;
 
-	IRDA_DEBUG(2, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
+	IRDA_DEBUG(2, "%s() send=%d,avail=%d,remote=%d\n", __FUNCTION__,
 		   self->send_credit, self->avail_credit, self->remote_credit);
 
 	/* Get exclusive access to the rx queue, otherwise don't touch it */
@@ -1636,7 +1643,8 @@
 			 *  limits of the maximum size of the rx_sdu
 			 */
 			if (self->rx_sdu_size <= self->rx_max_sdu_size) {
-				IRDA_DEBUG(4, __FUNCTION__ "(), queueing frag\n");
+				IRDA_DEBUG(4, "%s(), queueing frag\n",
+					   __FUNCTION__);
 				skb_queue_tail(&self->rx_fragments, skb);
 			} else {
 				/* Free the part of the SDU that is too big */
@@ -1666,7 +1674,7 @@
 			/* Now we can deliver the reassembled skb */
 			irttp_do_data_indication(self, skb);
 		} else {
-			IRDA_DEBUG(1, __FUNCTION__ "(), Truncated frame\n");
+			IRDA_DEBUG(1, "%s(), Truncated frame\n", __FUNCTION__);
 
 			/* Free the part of the SDU that is too big */
 			dev_kfree_skb(skb);
diff -Nru a/net/irda/parameters.c b/net/irda/parameters.c
--- a/net/irda/parameters.c	Fri Sep 27 14:51:04 2002
+++ b/net/irda/parameters.c	Fri Sep 27 14:51:04 2002
@@ -144,13 +144,13 @@
 	 */
 	if (p.pl == 0) {
 		if (p.pv.i < 0xff) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), using 1 byte\n");
+			IRDA_DEBUG(2, "%s(), using 1 byte\n", __FUNCTION__);
 			p.pl = 1;
 		} else if (p.pv.i < 0xffff) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), using 2 bytes\n");
+			IRDA_DEBUG(2, "%s(), using 2 bytes\n", __FUNCTION__);
 			p.pl = 2;
 		} else {
-			IRDA_DEBUG(2, __FUNCTION__ "(), using 4 bytes\n");
+			IRDA_DEBUG(2, "%s(), using 4 bytes\n", __FUNCTION__);
 			p.pl = 4; /* Default length */
 		}
 	}
@@ -159,7 +159,8 @@
 		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);
+	IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d, pi=%d\n", __FUNCTION__,
+		   p.pi, p.pl, p.pv.i);
 	switch (p.pl) {
 	case 1:
 		n += irda_param_pack(buf, "bbb", p.pi, p.pl, (__u8) p.pv.i);
@@ -252,7 +253,8 @@
 		return p.pl+2;
 	}
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), pi=%#x, pl=%d, pi=%d\n", p.pi, p.pl, p.pv.i);
+	IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d, pi=%d\n", __FUNCTION__,
+		   p.pi, p.pl, p.pv.i);
 	/* Call handler for this parameter */
 	err = (*func)(self, &p, PV_PUT);
 	if (err < 0)
@@ -271,12 +273,13 @@
 	irda_param_t p;
 	int err;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	p.pi = pi;     /* In case handler needs to know */
 	p.pl = buf[1]; /* Extract lenght of value */
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), pi=%#x, pl=%d\n", p.pi, p.pl);
+	IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __FUNCTION__,
+		   p.pi, p.pl);
 
 	/* Check if buffer is long enough for parsing */
 	if (len < (2+p.pl)) {
@@ -290,8 +293,8 @@
 	 * 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],
-	      (__u8) str[1]);
+	IRDA_DEBUG(2, "%s(), str=0x%02x 0x%02x\n", __FUNCTION__,
+		   (__u8) str[0], (__u8) str[1]);
 
 	/* Null terminate string */
 	str[p.pl+1] = '\0';
@@ -325,7 +328,7 @@
 		return -1;
 	}
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), not impl\n");
+	IRDA_DEBUG(0, "%s(), not impl\n", __FUNCTION__);
 
 	return p.pl+2; /* Extracted pl+2 bytes */
 }
@@ -447,8 +450,8 @@
 	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", pi);
+		IRDA_DEBUG(0, "%s(), no handler for parameter=0x%02x\n",
+			   __FUNCTION__, pi);
 
 		/* Skip this parameter */
 		return -1;
@@ -499,8 +502,8 @@
 	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]);
+		IRDA_DEBUG(0, "%s(), no handler for parameter=0x%02x\n",
+			   __FUNCTION__, buf[0]);
 
 		/* Skip this parameter */
 		return 2 + buf[n + 1];  /* Continue */
@@ -512,8 +515,8 @@
 	/* 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);
+	IRDA_DEBUG(3, "%s(), pi=[%d,%d], type=%d\n", __FUNCTION__,
+		   pi_major, pi_minor, type);
 
 	/*  Check if handler has been implemented */
 	if (!pi_minor_info->func) {
diff -Nru a/net/irda/qos.c b/net/irda/qos.c
--- a/net/irda/qos.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/qos.c	Fri Sep 27 14:51:05 2002
@@ -331,7 +331,7 @@
 	__u32 line_capacity;
 	int index;
 
-	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
 	/*
 	 * Make sure the mintt is sensible.
@@ -353,9 +353,9 @@
 	if ((qos->baud_rate.value < 115200) && 
 	    (qos->max_turn_time.value < 500))
 	{
-		IRDA_DEBUG(0, __FUNCTION__ 
-			   "(), adjusting max turn time from %d to 500 ms\n",
-			   qos->max_turn_time.value);
+		IRDA_DEBUG(0, 
+			   "%s(), adjusting max turn time from %d to 500 ms\n",
+			   __FUNCTION__, qos->max_turn_time.value);
 		qos->max_turn_time.value = 500;
 	}
 	
@@ -370,9 +370,8 @@
 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
 	while ((qos->data_size.value > line_capacity) && (index > 0)) {
 		qos->data_size.value = data_sizes[index--];
-		IRDA_DEBUG(2, __FUNCTION__ 
-			   "(), reducing data size to %d\n",
-			   qos->data_size.value);
+		IRDA_DEBUG(2, "%s(), reducing data size to %d\n",
+			   __FUNCTION__, qos->data_size.value);
 	}
 #else /* Use method described in section 6.6.11 of IrLAP */
 	while (irlap_requested_line_capacity(qos) > line_capacity) {
@@ -381,16 +380,15 @@
 		/* Must be able to send at least one frame */
 		if (qos->window_size.value > 1) {
 			qos->window_size.value--;
-			IRDA_DEBUG(2, __FUNCTION__ 
-				   "(), reducing window size to %d\n",
-				   qos->window_size.value);
+			IRDA_DEBUG(2, "%s(), reducing window size to %d\n",
+				   __FUNCTION__, qos->window_size.value);
 		} else if (index > 1) {
 			qos->data_size.value = data_sizes[index--];
-			IRDA_DEBUG(2, __FUNCTION__ 
-				   "(), reducing data size to %d\n",
-				   qos->data_size.value);
+			IRDA_DEBUG(2, "%s(), reducing data size to %d\n",
+				   __FUNCTION__, qos->data_size.value);
 		} else {
-			WARNING(__FUNCTION__ "(), nothing more we can do!\n");
+			WARNING("%s(), nothing more we can do!\n",
+				__FUNCTION__);
 		}
 	}
 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
@@ -519,8 +517,8 @@
 
 	if (get) {
 		param->pv.i = self->qos_rx.baud_rate.bits;
-		IRDA_DEBUG(2, __FUNCTION__ "(), baud rate = 0x%02x\n", 
-			   param->pv.i);		
+		IRDA_DEBUG(2, "%s(), baud rate = 0x%02x\n", 
+			   __FUNCTION__, param->pv.i);		
 	} else {
 		/* 
 		 *  Stations must agree on baud rate, so calculate
@@ -692,8 +690,8 @@
 	__u32 line_capacity;
 	int i,j;
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), speed=%d, max_turn_time=%d\n",
-		   speed, max_turn_time);
+	IRDA_DEBUG(2, "%s(), speed=%d, max_turn_time=%d\n",
+		   __FUNCTION__, speed, max_turn_time);
 
 	i = value_index(speed, baud_rates, 10);
 	j = value_index(max_turn_time, max_turn_times, 4);
@@ -703,8 +701,8 @@
 
 	line_capacity = max_line_capacities[i][j];
 
-	IRDA_DEBUG(2, __FUNCTION__ "(), line capacity=%d bytes\n", 
-		   line_capacity);
+	IRDA_DEBUG(2, "%s(), line capacity=%d bytes\n", 
+		   __FUNCTION__, line_capacity);
 	
 	return line_capacity;
 }
@@ -717,8 +715,8 @@
 		irlap_min_turn_time_in_bytes(qos->baud_rate.value, 
 					     qos->min_turn_time.value);
 	
-	IRDA_DEBUG(2, __FUNCTION__ "(), requested line capacity=%d\n",
-		   line_capacity);
+	IRDA_DEBUG(2, "%s(), requested line capacity=%d\n",
+		   __FUNCTION__, line_capacity);
 	
 	return line_capacity;			       		  
 }
diff -Nru a/net/irda/wrapper.c b/net/irda/wrapper.c
--- a/net/irda/wrapper.c	Fri Sep 27 14:51:05 2002
+++ b/net/irda/wrapper.c	Fri Sep 27 14:51:05 2002
@@ -93,16 +93,17 @@
 		 * Nothing to worry about, but we set the default number of
 		 * BOF's
 		 */
-		IRDA_DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n");
+		IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __FUNCTION__);
 		xbofs = 10;
 	} else
 		xbofs = cb->xbofs + cb->xbofs_delay;
 
-	IRDA_DEBUG(4, __FUNCTION__ "(), xbofs=%d\n", xbofs);
+	IRDA_DEBUG(4, "%s(), xbofs=%d\n", __FUNCTION__, xbofs);
 
 	/* Check that we never use more than 115 + 48 xbofs */
 	if (xbofs > 163) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), too many xbofs (%d)\n", xbofs);
+		IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __FUNCTION__,
+			   xbofs);
 		xbofs = 163;
 	}
 
@@ -265,7 +266,7 @@
 	case EOF:
 		/* Abort frame */
 		rx_buff->state = OUTSIDE_FRAME;
-		IRDA_DEBUG(1, __FUNCTION__ "(), abort frame\n");
+		IRDA_DEBUG(1, "%s(), abort frame\n", __FUNCTION__);
 		stats->rx_errors++;
 		stats->rx_frame_errors++;
 		break;
@@ -289,8 +290,8 @@
 {
 	switch (byte) {
 	case BOF: /* New frame? */
-		IRDA_DEBUG(1, __FUNCTION__
-			   "(), Discarding incomplete frame\n");
+		IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
+			   __FUNCTION__);
 		rx_buff->state = BEGIN_FRAME;
 		irda_device_set_media_busy(dev, TRUE);
 		break;
@@ -311,7 +312,8 @@
 			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
 			rx_buff->state = INSIDE_FRAME;
 		} else {
-			IRDA_DEBUG(1, __FUNCTION__ "(), rx buffer overflow\n");
+			IRDA_DEBUG(1, "%s(), rx buffer overflow\n",
+				   __FUNCTION__);
 			rx_buff->state = OUTSIDE_FRAME;
 		}
 		break;
@@ -332,8 +334,8 @@
 
 	switch (byte) {
 	case BOF: /* New frame? */
-		IRDA_DEBUG(1, __FUNCTION__
-			   "(), Discarding incomplete frame\n");
+		IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
+			   __FUNCTION__);
 		rx_buff->state = BEGIN_FRAME;
 		irda_device_set_media_busy(dev, TRUE);
 		break;
@@ -354,7 +356,7 @@
 			/* Wrong CRC, discard frame!  */
 			irda_device_set_media_busy(dev, TRUE);
 
-			IRDA_DEBUG(1, __FUNCTION__ "(), crc error\n");
+			IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__);
 			stats->rx_errors++;
 			stats->rx_crc_errors++;
 		}
@@ -364,8 +366,8 @@
 			rx_buff->data[rx_buff->len++] = byte;
 			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
 		} else {
-			IRDA_DEBUG(1, __FUNCTION__
-			      "(), Rx buffer overflow, aborting\n");
+			IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
+				   __FUNCTION__);
 			rx_buff->state = OUTSIDE_FRAME;
 		}
 		break;
diff -Nru a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
--- a/net/llc/llc_c_ac.c	Fri Sep 27 14:51:05 2002
+++ b/net/llc/llc_c_ac.c	Fri Sep 27 14:51:05 2002
@@ -65,9 +65,7 @@
 		llc_pdu_decode_sa(skb, llc->daddr.mac);
 		llc_pdu_decode_da(skb, llc->laddr.mac);
 		llc->dev = skb->dev;
-		/* FIXME: find better way to notify upper layer */
-		ev->flag     = LLC_CONN_PRIM + 1;
-		ev->ind_prim = (void *)1;
+		ev->ind_prim = LLC_CONN_PRIM;
 		rc = 0;
 	}
 	return rc;
@@ -77,8 +75,7 @@
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	ev->flag     = LLC_CONN_PRIM + 1;
-	ev->cfm_prim = (void *)1;
+	ev->cfm_prim = LLC_CONN_PRIM;
 	return 0;
 }
 
@@ -86,12 +83,7 @@
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	/*
-	 * FIXME: find better way to tell upper layer that the packet was
-	 * confirmed by the other endpoint
-	 */
-	ev->flag     = LLC_DATA_PRIM + 1;
-	ev->cfm_prim = (void *)1;
+	ev->cfm_prim = LLC_DATA_PRIM;
 	return 0;
 }
 
@@ -129,15 +121,8 @@
 		rc = 1;
 	}
 	if (!rc) {
-		/*
-		 * FIXME: ev needs reason field,
-		 * perhaps the ev->status is enough,
-		 * have to check,
-		 * better way to signal its a disc
-		 */
-		/* prim_data->disc.reason = reason; */
-		ev->flag     = LLC_DISC_PRIM + 1;
-		ev->ind_prim = (void *)1;
+		ev->reason   = reason;
+		ev->ind_prim = LLC_DISC_PRIM;
 	}
 	return rc;
 }
@@ -146,10 +131,8 @@
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	/* here we use the ev->status, humm */
-	/* prim_data->disc.reason = ev->status; */
-	ev->flag     = LLC_DISC_PRIM + 1;
-	ev->cfm_prim = (void *)1;
+	ev->reason   = ev->status;
+	ev->cfm_prim = LLC_DISC_PRIM;
 	return 0;
 }
 
@@ -191,18 +174,8 @@
 			break;
 	}
 	if (!rc) {
-		struct llc_sap *sap = llc->sap;
-		struct llc_prim_if_block *prim = &sap->llc_ind_prim;
-		union llc_u_prim_data *prim_data = prim->data;
-
-		prim_data->res.sk     = sk;
-		prim_data->res.reason = reason;
-		prim_data->res.link   = llc->link;
-		prim->data	      = prim_data;
-		prim->prim	      = LLC_RESET_PRIM;
-		prim->sap	      = sap;
-		ev->flag	      = 1;
-		ev->ind_prim	      = prim;
+		ev->reason   = reason;
+		ev->ind_prim = LLC_RESET_PRIM;
 	}
 	return rc;
 }
@@ -210,18 +183,9 @@
 int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-	struct llc_opt *llc = llc_sk(sk);
-	struct llc_sap *sap = llc->sap;
-	struct llc_prim_if_block *prim = &sap->llc_cfm_prim;
-	union llc_u_prim_data *prim_data = prim->data;
 
-	prim_data->res.sk   = sk;
-	prim_data->res.link = llc->link;
-	prim->data	    = prim_data;
-	prim->prim	    = LLC_RESET_PRIM;
-	prim->sap	    = sap;
-	ev->flag	    = 1;
-	ev->cfm_prim	    = prim;
+	ev->reason   = 0;
+	ev->cfm_prim = LLC_RESET_PRIM;
 	return 0;
 }
 
@@ -813,6 +777,16 @@
 	return rc;
 }
 
+void llc_conn_set_p_flag(struct sock *sk, u8 value)
+{
+	int state_changed = llc_sk(sk)->p_flag && !value;
+
+	llc_sk(sk)->p_flag = value;
+
+	if (state_changed)
+		sk->state_change(sk);
+}
+
 int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
 {
 	int rc = 1;
@@ -834,7 +808,8 @@
 		rc = 0;
 		llc_conn_send_pdu(sk, nskb);
 	}
-	llc->p_flag = p_bit;
+	llc_conn_set_p_flag(sk, p_bit);
+
 	return rc;
 }
 
@@ -897,7 +872,7 @@
 {
 	struct llc_opt *llc = llc_sk(sk);
 
-	llc->p_flag = 1;
+	llc_conn_set_p_flag(sk, 1);
 	mod_timer(&llc->pf_cycle_timer.timer,
 		  jiffies + llc->pf_cycle_timer.expire * HZ);
 	return 0;
@@ -1205,7 +1180,7 @@
 	struct llc_opt *llc = llc_sk(sk);
 
 	del_timer(&llc->pf_cycle_timer.timer);
-	llc->p_flag = 0;
+	llc_conn_set_p_flag(sk, 0);
 	return 0;
 }
 
@@ -1259,7 +1234,7 @@
 
 		llc_pdu_decode_pf_bit(skb, &f_bit);
 		if (f_bit) {
-			llc_sk(sk)->p_flag = 0;
+			llc_conn_set_p_flag(sk, 0);
 			llc_conn_ac_stop_p_timer(sk, skb);
 		}
 	}
@@ -1294,13 +1269,13 @@
 
 int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb)
 {
-	llc_sk(sk)->p_flag = 0;
+	llc_conn_set_p_flag(sk, 0);
 	return 0;
 }
 
 int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
 {
-	llc_sk(sk)->p_flag = 1;
+	llc_conn_set_p_flag(sk, 1);
 	return 0;
 }
 
diff -Nru a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
--- a/net/llc/llc_c_ev.c	Fri Sep 27 14:51:03 2002
+++ b/net/llc/llc_c_ev.c	Fri Sep 27 14:51:03 2002
@@ -101,48 +101,48 @@
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	return ev->data.prim.prim == LLC_CONN_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	return ev->prim == LLC_CONN_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
 int llc_conn_ev_conn_resp(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	return ev->data.prim.prim == LLC_CONN_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
+	return ev->prim == LLC_CONN_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
 }
 
 int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	return ev->data.prim.prim == LLC_DATA_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	return ev->prim == LLC_DATA_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
 int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	return ev->data.prim.prim == LLC_DISC_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	return ev->prim == LLC_DISC_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
 int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	return ev->data.prim.prim == LLC_RESET_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	return ev->prim == LLC_RESET_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
 int llc_conn_ev_rst_resp(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	return ev->data.prim.prim == LLC_RESET_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
+	return ev->prim == LLC_RESET_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
 }
 
 int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
@@ -150,7 +150,7 @@
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
-	       ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
+	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
 }
 
 int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
@@ -158,7 +158,7 @@
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
-	       ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
+	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
 }
 
 int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
@@ -666,7 +666,7 @@
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
-	       ev->data.a.ev == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
+	       ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
 }
 
 /* Event qualifier functions
diff -Nru a/net/llc/llc_conn.c b/net/llc/llc_conn.c
--- a/net/llc/llc_conn.c	Fri Sep 27 14:51:03 2002
+++ b/net/llc/llc_conn.c	Fri Sep 27 14:51:03 2002
@@ -39,22 +39,20 @@
 /* Offset table on connection states transition diagram */
 static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
 
-static void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
-			       u8 ua, u8 test, u8 xid)
+void llc_save_primitive(struct sk_buff* skb, u8 prim)
 {
-	struct llc_opt *llc = llc_sk(sk);
 	struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
 
        /* save primitive for use by the user. */
-	addr->sllc_family = sk->family;
+	addr->sllc_family = skb->sk->family;
 	addr->sllc_arphrd = skb->dev->type;
-	addr->sllc_test   = test;
-	addr->sllc_xid    = xid;
-	addr->sllc_ua     = ua;
-	addr->sllc_dsap   = llc->sap->laddr.lsap;
-	memcpy(addr->sllc_dmac, llc->laddr.mac, IFHWADDRLEN);
-	addr->sllc_ssap	  = llc->daddr.lsap;
-	memcpy(addr->sllc_smac, llc->daddr.mac, IFHWADDRLEN);
+	addr->sllc_test   = prim == LLC_TEST_PRIM;
+	addr->sllc_xid    = prim == LLC_XID_PRIM;
+	addr->sllc_ua     = prim == LLC_DATAUNIT_PRIM;
+	llc_pdu_decode_sa(skb, addr->sllc_smac);
+	llc_pdu_decode_da(skb, addr->sllc_dmac);
+	llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
+	llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
 }
 
 /**
@@ -69,110 +67,120 @@
  */
 int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 {
-	/* sending event to state machine */
-	int rc = llc_conn_service(sk, skb);
+	int rc;
 	struct llc_opt *llc = llc_sk(sk);
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-	u8 flag = ev->flag;
-	u8 status = ev->status;
-	struct llc_prim_if_block *ind_prim = ev->ind_prim;
-	struct llc_prim_if_block *cfm_prim = ev->cfm_prim;
 
-	/*
-	 * FIXME: this will vanish as soon I get rid of the last prim crap
-	 */
-	if (flag != LLC_DATA_PRIM + 1 && flag != LLC_CONN_PRIM + 1 &&
-	    flag != LLC_DISC_PRIM + 1)
-		llc_conn_free_ev(skb);
-	else if (ind_prim && cfm_prim)
-		skb_get(skb);
-	if (!flag)   /* indicate or confirm not required */
+	ev->ind_prim = ev->cfm_prim = 0;
+	rc = llc_conn_service(sk, skb); /* sending event to state machine */
+	if (rc) {
+		printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__);
+		goto out_kfree_skb;
+	}
+
+	if (!ev->ind_prim && !ev->cfm_prim) {   /* indicate or confirm not required */
+		if (!skb->list)
+			goto out_kfree_skb;
 		goto out;
-	rc = 0;
-	if (ind_prim) { /* indication required */
-		/*
-		 * FIXME: this will be saner as soon I get rid of the double
-		 *	  sock crap
-		 */
-		switch (flag) {
-		case LLC_DATA_PRIM + 1:
-			llc_save_primitive(sk, skb, 0, 0, 0);
-			if (sock_queue_rcv_skb(sk, skb)) {
-				/*
-				 * FIXME: have to sync the LLC state
-				 *        machine wrt mem usage with
-				 *        sk->{r,w}mem_alloc, will do
-				 *        this soon 8)
-				 */
-				printk(KERN_ERR
-				       "%s: sock_queue_rcv_skb failed!\n",
-				       __FUNCTION__);
-				kfree_skb(skb);
-			}
-			break;
-		case LLC_CONN_PRIM + 1: {
-			struct sock *parent = skb->sk;
+	}
 
-			skb->sk = sk;
-			skb_queue_tail(&parent->receive_queue, skb);
-			sk->state_change(parent);
+	if (ev->ind_prim && ev->cfm_prim)
+		skb_get(skb);
+
+	switch (ev->ind_prim) {
+	case LLC_DATA_PRIM:
+		llc_save_primitive(skb, LLC_DATA_PRIM);
+		if (sock_queue_rcv_skb(sk, skb)) {
+			/*
+			 * shouldn't happen
+			 */
+			printk(KERN_ERR "%s: sock_queue_rcv_skb failed!\n",
+			       __FUNCTION__);
+			kfree_skb(skb);
 		}
-			break;
-		case LLC_DISC_PRIM + 1:
-			sock_hold(sk);
-			if (sk->type == SOCK_STREAM && sk->state == TCP_ESTABLISHED) {
-				sk->shutdown       = SHUTDOWN_MASK;
-				sk->socket->state  = SS_UNCONNECTED;
-				sk->state          = TCP_CLOSE;
-				if (!sk->dead) {
-					sk->state_change(sk);
-					sk->dead = 1;
-				}
+		break;
+	case LLC_CONN_PRIM: {
+		struct sock *parent = skb->sk;
+
+		skb->sk = sk;
+		skb_queue_tail(&parent->receive_queue, skb);
+		sk->state_change(parent);
+	}
+		break;
+	case LLC_DISC_PRIM:
+		sock_hold(sk);
+		if (sk->type == SOCK_STREAM && sk->state == TCP_ESTABLISHED) {
+			sk->shutdown       = SHUTDOWN_MASK;
+			sk->socket->state  = SS_UNCONNECTED;
+			sk->state          = TCP_CLOSE;
+			if (!sk->dead) {
+				sk->state_change(sk);
+				sk->dead = 1;
 			}
+		}
+		kfree_skb(skb);
+		sock_put(sk);
+		break;
+	case LLC_RESET_PRIM:
+		/*
+		 * FIXME:
+		 * RESET is not being notified to upper layers for now
+		 */
+		printk(KERN_INFO "%s: received a reset ind!\n", __FUNCTION__);
+		kfree_skb(skb);
+		break;
+	default:
+		if (ev->ind_prim) {
+			printk(KERN_INFO "%s: received unknown %d prim!\n",
+				__FUNCTION__, ev->ind_prim);
 			kfree_skb(skb);
-			sock_put(sk);
-			break;
-		default:
-			llc->sap->ind(ind_prim);
 		}
+		/* No indication */
+		break;
 	}
-	if (!cfm_prim)  /* confirmation not required */
-		goto out;
-	/* FIXME: see FIXMEs above */
-	switch (flag) {
-	case LLC_DATA_PRIM + 1:
+
+	switch (ev->cfm_prim) {
+	case LLC_DATA_PRIM:
 		if (!llc_data_accept_state(llc->state))
-			/* In this state, we can send I pdu */
 			sk->write_space(sk);
 		else
 			rc = llc->failed_data_req = 1;
 		break;
-	case LLC_CONN_PRIM + 1:
-		if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT)
-			goto out_kfree_skb;
-		if (status) {
-			sk->socket->state = SS_UNCONNECTED;
-			sk->state         = TCP_CLOSE;
-		} else {
-			sk->socket->state = SS_CONNECTED;
-			sk->state         = TCP_ESTABLISHED;
+	case LLC_CONN_PRIM:
+		if (sk->type == SOCK_STREAM && sk->state == TCP_SYN_SENT) {
+			if (ev->status) {
+				sk->socket->state = SS_UNCONNECTED;
+				sk->state         = TCP_CLOSE;
+			} else {
+				sk->socket->state = SS_CONNECTED;
+				sk->state         = TCP_ESTABLISHED;
+			}
+			sk->state_change(sk);
 		}
-		sk->state_change(sk);
 		break;
-	case LLC_DISC_PRIM + 1:
+	case LLC_DISC_PRIM:
 		sock_hold(sk);
-		if (sk->type != SOCK_STREAM || sk->state != TCP_CLOSING) {
-			sock_put(sk);
-			goto out_kfree_skb;
+		if (sk->type == SOCK_STREAM && sk->state == TCP_CLOSING) {
+			sk->socket->state = SS_UNCONNECTED;
+			sk->state         = TCP_CLOSE;
+			sk->state_change(sk);
 		}
-		sk->socket->state = SS_UNCONNECTED;
-		sk->state         = TCP_CLOSE;
-		sk->state_change(sk);
 		sock_put(sk);
 		break;
+	case LLC_RESET_PRIM:
+		/*
+		 * FIXME:
+		 * RESET is not being notified to upper layers for now
+		 */
+		printk(KERN_INFO "%s: received a reset conf!\n", __FUNCTION__);
+		break;
 	default:
-		llc->sap->conf(cfm_prim);
-		goto out;
+		if (ev->cfm_prim) {
+			printk(KERN_INFO "%s: received unknown %d prim!\n",
+					__FUNCTION__, ev->cfm_prim);
+			break;
+		}
+		goto out; /* No confirmation */
 	}
 out_kfree_skb:
 	kfree_skb(skb);
@@ -200,9 +208,7 @@
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-	/* FIXME: indicate that we should send this to the upper layer */
-	ev->flag     = LLC_DATA_PRIM + 1;
-	ev->ind_prim = (void *)1;
+	ev->ind_prim = LLC_DATA_PRIM;
 }
 
 /**
@@ -357,12 +363,14 @@
 		/* free the frame that is bound to this event */
 		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-		if (LLC_PDU_TYPE_IS_I(pdu) || !ev->flag || !ev->ind_prim)
+		if (LLC_PDU_TYPE_IS_I(pdu) || !ev->ind_prim)
 			kfree_skb(skb);
 	} else if (ev->type == LLC_CONN_EV_TYPE_PRIM &&
-		   ev->data.prim.prim != LLC_DATA_PRIM)
+		   ev->prim != LLC_DATA_PRIM)
 		kfree_skb(skb);
-	else if (ev->type == LLC_CONN_EV_TYPE_P_TMR)
+	else if (ev->type == LLC_CONN_EV_TYPE_P_TMR ||
+		 ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ||
+		 ev->type == LLC_CONN_EV_TYPE_REJ_TMR)
 		kfree_skb(skb);
 }
 
@@ -378,16 +386,20 @@
 static int llc_conn_service(struct sock *sk, struct sk_buff *skb)
 {
 	int rc = 1;
+	struct llc_opt *llc = llc_sk(sk);
 	struct llc_conn_state_trans *trans;
 
-	if (llc_sk(sk)->state > NBR_CONN_STATES)
+	if (llc->state > NBR_CONN_STATES)
 		goto out;
 	rc = 0;
 	trans = llc_qualify_conn_ev(sk, skb);
 	if (trans) {
 		rc = llc_exec_conn_trans_actions(sk, trans, skb);
-		if (!rc && trans->next_state != NO_STATE_CHANGE)
-			llc_sk(sk)->state = trans->next_state;
+		if (!rc && trans->next_state != NO_STATE_CHANGE) {
+			llc->state = trans->next_state;
+			if (!llc_data_accept_state(llc->state))
+				sk->state_change(sk);
+		}
 	}
 out:
 	return rc;
@@ -481,27 +493,21 @@
 struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
 				    struct llc_addr *laddr)
 {
-	struct sock *rc = NULL;
-	struct list_head *entry;
+	struct sock *rc;
 
-	spin_lock_bh(&sap->sk_list.lock);
-	if (list_empty(&sap->sk_list.list))
-		goto out;
-	list_for_each(entry, &sap->sk_list.list) {
-		struct llc_opt *llc = list_entry(entry, struct llc_opt, node);
+	read_lock_bh(&sap->sk_list.lock);
+	for (rc = sap->sk_list.list; rc; rc = rc->next) {
+		struct llc_opt *llc = llc_sk(rc);
 
 		if (llc->laddr.lsap == laddr->lsap &&
 		    llc->daddr.lsap == daddr->lsap &&
 		    llc_mac_match(llc->laddr.mac, laddr->mac) &&
-		    llc_mac_match(llc->daddr.mac, daddr->mac)) {
-			rc = llc->sk;
+		    llc_mac_match(llc->daddr.mac, daddr->mac))
 			break;
-		}
 	}
 	if (rc)
 		sock_hold(rc);
-out:
-	spin_unlock_bh(&sap->sk_list.lock);
+	read_unlock_bh(&sap->sk_list.lock);
 	return rc;
 }
 
@@ -516,28 +522,49 @@
  */
 struct sock *llc_lookup_listener(struct llc_sap *sap, struct llc_addr *laddr)
 {
-	struct sock *rc = NULL;
-	struct list_head *entry;
+	struct sock *rc;
 
-	spin_lock_bh(&sap->sk_list.lock);
-	if (list_empty(&sap->sk_list.list))
-		goto out;
-	list_for_each(entry, &sap->sk_list.list) {
-		struct llc_opt *llc = list_entry(entry, struct llc_opt, node);
-
-		if (llc->sk->type != SOCK_STREAM || llc->sk->state != TCP_LISTEN ||
-		    llc->laddr.lsap != laddr->lsap ||
-		    !llc_mac_match(llc->laddr.mac, laddr->mac))
-			continue;
-		rc = llc->sk;
+	read_lock_bh(&sap->sk_list.lock);
+	for (rc = sap->sk_list.list; rc; rc = rc->next) {
+		struct llc_opt *llc = llc_sk(rc);
+
+		if (rc->type == SOCK_STREAM && rc->state == TCP_LISTEN &&
+		    llc->laddr.lsap == laddr->lsap &&
+		    llc_mac_match(llc->laddr.mac, laddr->mac))
+			break;
 	}
 	if (rc)
 		sock_hold(rc);
-out:
-	spin_unlock_bh(&sap->sk_list.lock);
+	read_unlock_bh(&sap->sk_list.lock);
 	return rc;
 }
 
+/**
+ *	llc_lookup_dgram - Finds dgram socket for the local sap/mac
+ *	@sap: SAP
+ *	@laddr: address of local LLC (MAC + SAP)
+ *
+ *	Search socket list of the SAP and finds connection using the local
+ *	mac, and local sap. Returns pointer for socket found, %NULL otherwise.
+ */
+struct sock *llc_lookup_dgram(struct llc_sap *sap, struct llc_addr *laddr)
+{
+	struct sock *rc;
+
+	read_lock_bh(&sap->sk_list.lock);
+	for (rc = sap->sk_list.list; rc; rc = rc->next) {
+		struct llc_opt *llc = llc_sk(rc);
+
+		if (rc->type == SOCK_DGRAM &&
+		    llc->laddr.lsap == laddr->lsap &&
+		    llc_mac_match(llc->laddr.mac, laddr->mac))
+			break;
+	}
+	if (rc)
+		sock_hold(rc);
+	read_unlock_bh(&sap->sk_list.lock);
+	return rc;
+}
 /**
  *	llc_data_accept_state - designates if in this state data can be sent.
  *	@state: state of connection.
diff -Nru a/net/llc/llc_evnt.c b/net/llc/llc_evnt.c
--- a/net/llc/llc_evnt.c	Fri Sep 27 14:51:03 2002
+++ b/net/llc/llc_evnt.c	Fri Sep 27 14:51:03 2002
@@ -29,7 +29,7 @@
 	struct llc_station_state_ev *ev = llc_station_ev(skb);	
 	
 	return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
-	       ev->data.a.ev ==
+	       ev->prim_type ==
 	       		      LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1;
 }
 
@@ -39,7 +39,7 @@
 	struct llc_station_state_ev *ev = llc_station_ev(skb);	
 	
 	return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
-	       ev->data.a.ev ==
+	       ev->prim_type ==
 			LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1;
 }
 
@@ -120,6 +120,6 @@
 	struct llc_station_state_ev *ev = llc_station_ev(skb);
 
 	return ev->type == LLC_STATION_EV_TYPE_PRIM &&
-	       ev->data.prim.prim == LLC_DISABLE_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	       ev->prim == LLC_DISABLE_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
diff -Nru a/net/llc/llc_if.c b/net/llc/llc_if.c
--- a/net/llc/llc_if.c	Fri Sep 27 14:51:04 2002
+++ b/net/llc/llc_if.c	Fri Sep 27 14:51:04 2002
@@ -30,17 +30,16 @@
 
 /**
  *	llc_sap_open - open interface to the upper layers.
- *	@nw_indicate: pointer to indicate function of upper layer.
- *	@nw_confirm: pointer to confirm function of upper layer.
  *	@lsap: SAP number.
- *	@sap: pointer to allocated SAP (output argument).
+ *	@func: rcv func for datalink protos
  *
  *	Interface function to upper layer. Each one who wants to get a SAP
  *	(for example NetBEUI) should call this function. Returns the opened
  *	SAP for success, NULL for failure.
  */
-struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate,
-			     llc_prim_call_t nw_confirm, u8 lsap)
+struct llc_sap *llc_sap_open(u8 lsap, int (*func)(struct sk_buff *skb,
+						  struct net_device *dev,
+						  struct packet_type *pt))
 {
 	/* verify this SAP is not already open; if so, return error */
 	struct llc_sap *sap;
@@ -57,9 +56,8 @@
 		goto err;
 	/* allocated a SAP; initialize it and clear out its memory pool */
 	sap->laddr.lsap = lsap;
-	sap->ind = nw_indicate;
-	sap->conf = nw_confirm;
-	sap->parent_station = llc_station_get();
+	sap->rcv_func	= func;
+	sap->station	= llc_station_get();
 	/* initialized SAP; add it to list of SAPs this station manages */
 	llc_sap_save(sap);
 out:
@@ -99,24 +97,16 @@
 void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
 			       u8 *dmac, u8 dsap)
 {
-	union llc_u_prim_data prim_data;
-	struct llc_prim_if_block prim;
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
-	prim.data = &prim_data;
-	prim.sap  = sap;
-	prim.prim = LLC_DATAUNIT_PRIM;
-
-	prim_data.udata.skb        = skb;
-	prim_data.udata.saddr.lsap = sap->laddr.lsap;
-	prim_data.udata.daddr.lsap = dsap;
-	memcpy(prim_data.udata.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
-	memcpy(prim_data.udata.daddr.mac, dmac, IFHWADDRLEN);
-
-	ev->type	   = LLC_SAP_EV_TYPE_PRIM;
-	ev->data.prim.prim = LLC_DATAUNIT_PRIM;
-	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
-	ev->data.prim.data = &prim;
+	ev->saddr.lsap = sap->laddr.lsap;
+	ev->daddr.lsap = dsap;
+	memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+	memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+
+	ev->type      = LLC_SAP_EV_TYPE_PRIM;
+	ev->prim      = LLC_DATAUNIT_PRIM;
+	ev->prim_type = LLC_PRIM_TYPE_REQ;
 	llc_sap_state_process(sap, skb);
 }
 
@@ -130,27 +120,19 @@
  *	This function is called when upper layer wants to send a TEST pdu.
  *	Returns 0 for success, 1 otherwise.
  */
-void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
-				 u8 *dmac, u8 dsap)
+void llc_build_and_send_test_pkt(struct llc_sap *sap, 
+				 struct sk_buff *skb, u8 *dmac, u8 dsap)
 {
-	union llc_u_prim_data prim_data;
-	struct llc_prim_if_block prim;
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
-	prim.data = &prim_data;
-	prim.sap  = sap;
-	prim.prim = LLC_TEST_PRIM;
-
-	prim_data.test.skb        = skb;
-	prim_data.test.saddr.lsap = sap->laddr.lsap;
-	prim_data.test.daddr.lsap = dsap;
-	memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
-	memcpy(prim_data.test.daddr.mac, dmac, IFHWADDRLEN);
+	ev->saddr.lsap = sap->laddr.lsap;
+	ev->daddr.lsap = dsap;
+	memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+	memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
 	
-	ev->type	   = LLC_SAP_EV_TYPE_PRIM;
-	ev->data.prim.prim = LLC_TEST_PRIM;
-	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
-	ev->data.prim.data = &prim;
+	ev->type      = LLC_SAP_EV_TYPE_PRIM;
+	ev->prim      = LLC_TEST_PRIM;
+	ev->prim_type = LLC_PRIM_TYPE_REQ;
 	llc_sap_state_process(sap, skb);
 }
 
@@ -167,24 +149,16 @@
 void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
 				u8 *dmac, u8 dsap)
 {
-	union llc_u_prim_data prim_data;
-	struct llc_prim_if_block prim;
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
-	prim.data = &prim_data;
-	prim.sap  = sap;
-	prim.prim = LLC_XID_PRIM;
-
-	prim_data.xid.skb        = skb;
-	prim_data.xid.saddr.lsap = sap->laddr.lsap;
-	prim_data.xid.daddr.lsap = dsap;
-	memcpy(prim_data.xid.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
-	memcpy(prim_data.xid.daddr.mac, dmac, IFHWADDRLEN);
-
-	ev->type	   = LLC_SAP_EV_TYPE_PRIM;
-	ev->data.prim.prim = LLC_XID_PRIM;
-	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
-	ev->data.prim.data = &prim;
+	ev->saddr.lsap = sap->laddr.lsap;
+	ev->daddr.lsap = dsap;
+	memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+	memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+
+	ev->type      = LLC_SAP_EV_TYPE_PRIM;
+	ev->prim      = LLC_XID_PRIM;
+	ev->prim_type = LLC_PRIM_TYPE_REQ;
 	llc_sap_state_process(sap, skb);
 }
 
@@ -219,11 +193,10 @@
 		goto out;
 	}
 	ev = llc_conn_ev(skb);
-	ev->type	    = LLC_CONN_EV_TYPE_PRIM;
-	ev->data.prim.prim  = LLC_DATA_PRIM;
-	ev->data.prim.type  = LLC_PRIM_TYPE_REQ;
-	ev->data.prim.data  = NULL;
-	skb->dev	    = llc->dev;
+	ev->type      = LLC_CONN_EV_TYPE_PRIM;
+	ev->prim      = LLC_DATA_PRIM;
+	ev->prim_type = LLC_PRIM_TYPE_REQ;
+	skb->dev      = llc->dev;
 	rc = llc_conn_state_process(sk, skb);
 out:
 	return rc;
@@ -268,10 +241,9 @@
 	if (skb) {
 		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-		ev->type	   = LLC_CONN_EV_TYPE_PRIM;
-		ev->data.prim.prim = LLC_CONN_PRIM;
-		ev->data.prim.type = LLC_PRIM_TYPE_REQ;
-		ev->data.prim.data = NULL;
+		ev->type      = LLC_CONN_EV_TYPE_PRIM;
+		ev->prim      = LLC_CONN_PRIM;
+		ev->prim_type = LLC_PRIM_TYPE_REQ;
 		rc = llc_conn_state_process(sk, skb);
 	}
 out_put:
@@ -306,12 +278,11 @@
 	skb = alloc_skb(0, GFP_ATOMIC);
 	if (!skb)
 		goto out;
-	sk->state	   = TCP_CLOSING;
-	ev		   = llc_conn_ev(skb);
-	ev->type	   = LLC_CONN_EV_TYPE_PRIM;
-	ev->data.prim.prim = LLC_DISC_PRIM;
-	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
-	ev->data.prim.data = NULL;
+	sk->state     = TCP_CLOSING;
+	ev	      = llc_conn_ev(skb);
+	ev->type      = LLC_CONN_EV_TYPE_PRIM;
+	ev->prim      = LLC_DISC_PRIM;
+	ev->prim_type = LLC_PRIM_TYPE_REQ;
 	rc = llc_conn_state_process(sk, skb);
 out:
 	sock_put(sk);
@@ -327,8 +298,7 @@
  *	it to connection component state machine. Returns 0 for success, 1
  *	otherwise.
  */
-int llc_build_and_send_reset_pkt(struct sock *sk,
-				 struct llc_prim_if_block *prim)
+int llc_build_and_send_reset_pkt(struct sock *sk)
 {
 	int rc = 1;
 	struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
@@ -336,10 +306,9 @@
 	if (skb) {
 		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
-		ev->type = LLC_CONN_EV_TYPE_PRIM;
-		ev->data.prim.prim = LLC_RESET_PRIM;
-		ev->data.prim.type = LLC_PRIM_TYPE_REQ;
-		ev->data.prim.data = prim;
+		ev->type      = LLC_CONN_EV_TYPE_PRIM;
+		ev->prim      = LLC_RESET_PRIM;
+		ev->prim_type = LLC_PRIM_TYPE_REQ;
 		rc = llc_conn_state_process(sk, skb);
 	}
 	return rc;
diff -Nru a/net/llc/llc_mac.c b/net/llc/llc_mac.c
--- a/net/llc/llc_mac.c	Fri Sep 27 14:51:05 2002
+++ b/net/llc/llc_mac.c	Fri Sep 27 14:51:05 2002
@@ -82,7 +82,7 @@
  *	data now), it queues this frame in the connection's backlog.
  */
 int llc_rcv(struct sk_buff *skb, struct net_device *dev,
-		 struct packet_type *pt)
+	    struct packet_type *pt)
 {
 	struct llc_sap *sap;
 	struct llc_pdu_sn *pdu;
@@ -113,8 +113,22 @@
 	}
 	llc_decode_pdu_type(skb, &dest);
 	if (dest == LLC_DEST_SAP) { /* type 1 services */
-		dprintk("%s: calling llc_sap_rcv!\n", __FUNCTION__);
-		llc_sap_rcv(sap, skb);
+		if (sap->rcv_func)
+			sap->rcv_func(skb, dev, pt);
+		else {
+			struct llc_addr laddr;
+			struct sock *sk;
+
+			llc_pdu_decode_da(skb, laddr.mac);
+			llc_pdu_decode_dsap(skb, &laddr.lsap);
+
+			sk = llc_lookup_dgram(sap, &laddr);
+			if (!sk)
+				goto drop;
+			skb->sk = sk;
+			llc_sap_rcv(sap, skb);
+			sock_put(sk);
+		}
 	} else if (dest == LLC_DEST_CONN) {
 		struct llc_addr saddr, daddr;
 		struct sock *sk;
@@ -216,8 +230,8 @@
 	struct llc_station *station = llc_station_get();
 	struct llc_station_state_ev *ev = llc_station_ev(skb);
 
-	ev->type            = LLC_STATION_EV_TYPE_PDU;
-	ev->data.pdu.reason = 0;
+	ev->type   = LLC_STATION_EV_TYPE_PDU;
+	ev->reason = 0;
 	llc_station_state_process(station, skb);
 }
 
@@ -236,8 +250,8 @@
 
 	if (!llc->dev)
 		llc->dev = skb->dev;
-	ev->type	    = LLC_CONN_EV_TYPE_PDU;
-	ev->data.pdu.reason = 0;
+	ev->type   = LLC_CONN_EV_TYPE_PDU;
+	ev->reason = 0;
 	return llc_conn_state_process(sk, skb);
 }
 
@@ -252,8 +266,8 @@
 {
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
-	ev->type	    = LLC_SAP_EV_TYPE_PDU;
-	ev->data.pdu.reason = 0;
+	ev->type   = LLC_SAP_EV_TYPE_PDU;
+	ev->reason = 0;
 	llc_sap_state_process(sap, skb);
 }
 
diff -Nru a/net/llc/llc_main.c b/net/llc/llc_main.c
--- a/net/llc/llc_main.c	Fri Sep 27 14:51:04 2002
+++ b/net/llc/llc_main.c	Fri Sep 27 14:51:04 2002
@@ -71,10 +71,6 @@
 		sap->state = LLC_SAP_STATE_ACTIVE;
 		memcpy(sap->laddr.mac, llc_main_station.mac_sa, ETH_ALEN);
 		spin_lock_init(&sap->sk_list.lock);
-		INIT_LIST_HEAD(&sap->sk_list.list);
-		skb_queue_head_init(&sap->mac_pdu_q);
-		sap->llc_ind_prim.data = &sap->llc_ind_data_prim;
-		sap->llc_cfm_prim.data = &sap->llc_cfm_data_prim;
 	}
 	return sap;
 }
@@ -88,12 +84,10 @@
  */
 void llc_free_sap(struct llc_sap *sap)
 {
-	struct llc_station *station = sap->parent_station;
-
 	llc_rtn_all_conns(sap);
-	spin_lock_bh(&station->sap_list.lock);
+	write_lock_bh(&sap->station->sap_list.lock);
 	list_del(&sap->node);
-	spin_unlock_bh(&station->sap_list.lock);
+	write_unlock_bh(&sap->station->sap_list.lock);
 	kfree(sap);
 }
 
@@ -105,9 +99,9 @@
  */
 void llc_sap_save(struct llc_sap *sap)
 {
-	spin_lock_bh(&llc_main_station.sap_list.lock);
+	write_lock_bh(&llc_main_station.sap_list.lock);
 	list_add_tail(&sap->node, &llc_main_station.sap_list.list);
-	spin_unlock_bh(&llc_main_station.sap_list.lock);
+	write_unlock_bh(&llc_main_station.sap_list.lock);
 }
 
 /**
@@ -122,7 +116,7 @@
 	struct llc_sap* sap = NULL;
 	struct list_head *entry;
 
-	spin_lock_bh(&llc_main_station.sap_list.lock);
+	read_lock_bh(&llc_main_station.sap_list.lock);
 	list_for_each(entry, &llc_main_station.sap_list.list) {
 		sap = list_entry(entry, struct llc_sap, node);
 		if (sap->laddr.lsap == sap_value)
@@ -130,7 +124,7 @@
 	}
 	if (entry == &llc_main_station.sap_list.list) /* not found */
 		sap = NULL;
-	spin_unlock_bh(&llc_main_station.sap_list.lock);
+	read_unlock_bh(&llc_main_station.sap_list.lock);
 	return sap;
 }
 
@@ -304,7 +298,7 @@
 	llc->remote_busy_flag	= 0;
 	llc->cause_flag		= 0;
 	llc->retry_count	= 0;
-	llc->p_flag		= 0;
+	llc_conn_set_p_flag(sk, 0);
 	llc->f_flag		= 0;
 	llc->s_flag		= 0;
 	llc->ack_pf		= 0;
@@ -328,20 +322,18 @@
 static int llc_rtn_all_conns(struct llc_sap *sap)
 {
 	int rc = 0;
-	struct list_head *entry, *tmp;
+	struct sock *sk;
 
-	spin_lock_bh(&sap->sk_list.lock);
-	if (list_empty(&sap->sk_list.list))
-		goto out;
-	list_for_each_safe(entry, tmp, &sap->sk_list.list) {
-		struct llc_opt *llc = list_entry(entry, struct llc_opt, node);
+	write_lock_bh(&sap->sk_list.lock);
+
+	for (sk = sap->sk_list.list; sk; sk = sk->next) {
+		llc_sk(sk)->state = LLC_CONN_STATE_TEMP;
 
-		llc->state = LLC_CONN_STATE_TEMP;
-		if (llc_send_disc(llc->sk))
+		if (llc_send_disc(sk))
 			rc = 1;
 	}
-out:
-	spin_unlock_bh(&sap->sk_list.lock);
+
+	write_unlock_bh(&sap->sk_list.lock);
 	return rc;
 }
 
@@ -564,19 +556,19 @@
 
 static int llc_proc_get_info(char *bf, char **start, off_t offset, int length)
 {
-	struct llc_opt *llc;
-	struct list_head *sap_entry, *llc_entry;
+	struct list_head *sap_entry;
+	struct sock *sk;
 	off_t begin = 0, pos = 0;
 	int len = 0;
 
-	spin_lock_bh(&llc_main_station.sap_list.lock);
+	read_lock_bh(&llc_main_station.sap_list.lock);
 	list_for_each(sap_entry, &llc_main_station.sap_list.list) {
 		struct llc_sap *sap = list_entry(sap_entry, struct llc_sap,
 						 node);
 
 		len += sprintf(bf + len, "lsap=%02X\n", sap->laddr.lsap);
-		spin_lock_bh(&sap->sk_list.lock);
-		if (list_empty(&sap->sk_list.list)) {
+		read_lock_bh(&sap->sk_list.lock);
+		if (!sap->sk_list.list) {
 			len += sprintf(bf + len, "no connections\n");
 			goto unlock;
 		}
@@ -584,8 +576,9 @@
 					 "dsap state      retr txw rxw "
 					 "pf ff sf df rs cs "
 					 "tack tpfc trs tbs blog busr\n");
-		list_for_each(llc_entry, &sap->sk_list.list) {
-			llc = list_entry(llc_entry, struct llc_opt, node);
+		for (sk = sap->sk_list.list; sk; sk = sk->next) {
+			struct llc_opt *llc = llc_sk(sk);
+
 			len += sprintf(bf + len, " %02X  %-10s %3d  %3d %3d "
 						 "%2d %2d %2d "
 						 "%2d %2d %2d "
@@ -600,11 +593,10 @@
 				       timer_pending(&llc->pf_cycle_timer.timer),
 				       timer_pending(&llc->rej_sent_timer.timer),
 				       timer_pending(&llc->busy_state_timer.timer),
-				       !!llc->sk->backlog.tail,
-				       llc->sk->lock.users);
+				       !!sk->backlog.tail, sk->lock.users);
 		}
 unlock:	
-		spin_unlock_bh(&sap->sk_list.lock);
+		read_unlock_bh(&sap->sk_list.lock);
 		pos = begin + len;
 		if (pos < offset) {
 			len = 0; /* Keep dumping into the buffer start */
@@ -613,7 +605,7 @@
 		if (pos > offset + length) /* We have dumped enough */
 			break;
 	}
-	spin_unlock_bh(&llc_main_station.sap_list.lock);
+	read_unlock_bh(&llc_main_station.sap_list.lock);
 
 	/* The data in question runs from begin to begin + len */
 	*start = bf + (offset - begin); /* Start of wanted data */
@@ -634,8 +626,8 @@
 };
 
 static char llc_banner[] __initdata =
-		KERN_INFO "LLC 2.0 by Procom, 1997, Arnaldo C. Melo, 2001\n"
-		KERN_INFO "NET4.0 IEEE 802.2 extended support\n";
+		KERN_INFO "LLC 2.0 by Procom, 1997, Arnaldo C. Melo, 2001, 2002\n"
+		KERN_INFO "NET 4.0 IEEE 802.2 extended support\n";
 static char llc_error_msg[] __initdata =
 		KERN_ERR "LLC install NOT successful.\n";
 
@@ -669,7 +661,7 @@
 	llc_main_station.maximum_retry	= 1;
 	llc_main_station.state		= LLC_STATION_STATE_DOWN;
 	ev->type	= LLC_STATION_EV_TYPE_SIMPLE;
-	ev->data.a.ev	= LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
+	ev->prim_type	= LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
 	rc = llc_station_next_state(&llc_main_station, skb);
 	proc_net_create("802.2", 0, llc_proc_get_info);
 	llc_ui_init();
@@ -695,5 +687,5 @@
 module_exit(llc_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001");
+MODULE_AUTHOR("Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001, 2002");
 MODULE_DESCRIPTION("LLC 2.0, NET4.0 IEEE 802.2 extended support");
diff -Nru a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
--- a/net/llc/llc_s_ac.c	Fri Sep 27 14:51:05 2002
+++ b/net/llc/llc_s_ac.c	Fri Sep 27 14:51:05 2002
@@ -51,14 +51,12 @@
 int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
 {
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
-	struct llc_prim_if_block *prim = ev->data.prim.data;
-	struct llc_prim_unit_data *prim_data = &prim->data->udata;
 	int rc;
 
-	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
-			    prim_data->daddr.lsap, LLC_PDU_CMD);
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+			    ev->daddr.lsap, LLC_PDU_CMD);
 	llc_pdu_init_as_ui_cmd(skb);
-	rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+	rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
 	if (!rc)
 		llc_sap_send_pdu(sap, skb);
 	return rc;
@@ -76,14 +74,12 @@
 int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
 {
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
-	struct llc_prim_if_block *prim = ev->data.prim.data;
-	struct llc_prim_xid *prim_data = &prim->data->xid;
 	int rc;
 
-	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
-			    prim_data->daddr.lsap, LLC_PDU_CMD);
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+			    ev->daddr.lsap, LLC_PDU_CMD);
 	llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
-	rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+	rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
 	if (!rc)
 		llc_sap_send_pdu(sap, skb);
 	return rc;
@@ -132,14 +128,12 @@
 int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
 {
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
-	struct llc_prim_if_block *prim = ev->data.prim.data;
-	struct llc_prim_test *prim_data = &prim->data->test;
 	int rc;
 
-	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
-			    prim_data->daddr.lsap, LLC_PDU_CMD);
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+			    ev->daddr.lsap, LLC_PDU_CMD);
 	llc_pdu_init_as_test_cmd(skb);
-	rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+	rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
 	if (!rc)
 		llc_sap_send_pdu(sap, skb);
 	return rc;
diff -Nru a/net/llc/llc_s_ev.c b/net/llc/llc_s_ev.c
--- a/net/llc/llc_s_ev.c	Fri Sep 27 14:51:03 2002
+++ b/net/llc/llc_s_ev.c	Fri Sep 27 14:51:03 2002
@@ -25,7 +25,7 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
 	return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
-	       ev->data.a.ev == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
+	       ev->prim_type == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
 }
 
 int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb)
@@ -43,8 +43,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
 	return ev->type == LLC_SAP_EV_TYPE_PRIM &&
-	       ev->data.prim.prim == LLC_DATAUNIT_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	       ev->prim == LLC_DATAUNIT_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 
 }
 
@@ -53,8 +53,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
 	return ev->type == LLC_SAP_EV_TYPE_PRIM &&
-	       ev->data.prim.prim == LLC_XID_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	       ev->prim == LLC_XID_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
 int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb)
@@ -82,8 +82,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
 	return ev->type == LLC_SAP_EV_TYPE_PRIM &&
-	       ev->data.prim.prim == LLC_TEST_PRIM &&
-	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+	       ev->prim == LLC_TEST_PRIM &&
+	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
 int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb)
@@ -111,5 +111,5 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
 	return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
-	       ev->data.a.ev == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
+	       ev->prim_type == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
 }
diff -Nru a/net/llc/llc_sap.c b/net/llc/llc_sap.c
--- a/net/llc/llc_sap.c	Fri Sep 27 14:51:05 2002
+++ b/net/llc/llc_sap.c	Fri Sep 27 14:51:05 2002
@@ -18,6 +18,7 @@
 #include <net/llc_s_ac.h>
 #include <net/llc_s_st.h>
 #include <net/sock.h>
+#include <linux/tcp.h>
 #include <net/llc_main.h>
 #include <net/llc_mac.h>
 #include <net/llc_pdu.h>
@@ -39,11 +40,15 @@
  */
 void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk)
 {
-	spin_lock_bh(&sap->sk_list.lock);
+	write_lock_bh(&sap->sk_list.lock);
 	llc_sk(sk)->sap = sap;
-	list_add_tail(&llc_sk(sk)->node, &sap->sk_list.list);
+	sk->next = sap->sk_list.list;
+	if (sk->next)
+		sap->sk_list.list->pprev = &sk->next;
+	sap->sk_list.list = sk;
+	sk->pprev = &sap->sk_list.list;
 	sock_hold(sk);
-	spin_unlock_bh(&sap->sk_list.lock);
+	write_unlock_bh(&sap->sk_list.lock);
 }
 
 /**
@@ -55,29 +60,54 @@
  */
 void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
 {
-	spin_lock_bh(&sap->sk_list.lock);
-	list_del(&llc_sk(sk)->node);
-	sock_put(sk);
-	spin_unlock_bh(&sap->sk_list.lock);
+	write_lock_bh(&sap->sk_list.lock);
+	if (sk->pprev) {
+		if (sk->next)
+			sk->next->pprev = sk->pprev;
+		*sk->pprev = sk->next;
+		sk->pprev  = NULL;
+		/*
+		 * This only makes sense if the socket was inserted on the
+		 * list, if sk->pprev is NULL it wasn't
+		 */
+		sock_put(sk);
+	}
+	write_unlock_bh(&sap->sk_list.lock);
 }
 
 /**
  *	llc_sap_state_process - sends event to SAP state machine
- *	@sap: pointer to SAP
+ *	@sap: sap to use
  *	@skb: pointer to occurred event
  *
  *	After executing actions of the event, upper layer will be indicated
- *	if needed(on receiving an UI frame).
+ *	if needed(on receiving an UI frame). sk can be null for the
+ *	datalink_proto case.
  */
 void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
 {
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
+	/*
+	 * We have to hold the skb, because llc_sap_next_state
+	 * will kfree it in the sending path and we need to
+	 * look at the skb->cb, where we encode llc_sap_state_ev.
+	 */
+	skb_get(skb);
+	ev->ind_cfm_flag = 0;
 	llc_sap_next_state(sap, skb);
-	if (ev->ind_cfm_flag == LLC_IND)
-		sap->ind(ev->prim);
-	else if (ev->type == LLC_SAP_EV_TYPE_PDU)
-		kfree_skb(skb);
+	if (ev->ind_cfm_flag == LLC_IND) {
+		if (skb->sk->state == TCP_LISTEN)
+			kfree_skb(skb);
+		else {
+			llc_save_primitive(skb, ev->prim);
+
+			/* queue skb to the user. */
+			if (sock_queue_rcv_skb(skb->sk, skb))
+				kfree_skb(skb);
+		}
+	} 
+	kfree_skb(skb);
 }
 
 /**
@@ -89,43 +119,17 @@
 {
 	struct llc_pdu_un *pdu;
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
-	struct llc_prim_if_block *prim = &sap->llc_ind_prim;
-	union llc_u_prim_data *prim_data = prim->data;
-	u8 lfb;
-
-	llc_pdu_decode_sa(skb, prim_data->udata.saddr.mac);
-	llc_pdu_decode_da(skb, prim_data->udata.daddr.mac);
-	llc_pdu_decode_dsap(skb, &prim_data->udata.daddr.lsap);
-	llc_pdu_decode_ssap(skb, &prim_data->udata.saddr.lsap);
-	prim_data->udata.pri = 0;
-	prim_data->udata.skb = skb;
+
 	pdu = llc_pdu_un_hdr(skb);
 	switch (LLC_U_PDU_RSP(pdu)) {
-		case LLC_1_PDU_CMD_TEST:
-			prim->prim = LLC_TEST_PRIM;
-			break;
-		case LLC_1_PDU_CMD_XID:
-			prim->prim = LLC_XID_PRIM;
-			break;
-		case LLC_1_PDU_CMD_UI:
-			if (skb->protocol == ntohs(ETH_P_TR_802_2)) {
-				if (((struct trh_hdr *)skb->mac.raw)->rcf) {
-					lfb = ntohs(((struct trh_hdr *)
-						    skb->mac.raw)->rcf) &
-						    0x0070;
-					prim_data->udata.lfb = lfb >> 4;
-				} else {
-					lfb = 0xFF;
-					prim_data->udata.lfb = 0xFF;
-				}
-			}
-			prim->prim = LLC_DATAUNIT_PRIM;
-			break;
+	case LLC_1_PDU_CMD_TEST:
+		ev->prim = LLC_TEST_PRIM;	break;
+	case LLC_1_PDU_CMD_XID:
+		ev->prim = LLC_XID_PRIM;	break;
+	case LLC_1_PDU_CMD_UI:
+		ev->prim = LLC_DATAUNIT_PRIM;	break;
 	}
-	prim->data = prim_data;
-	prim->sap = sap;
 	ev->ind_cfm_flag = LLC_IND;
-	ev->prim = prim;
 }
 
 /**
diff -Nru a/net/llc/llc_sock.c b/net/llc/llc_sock.c
--- a/net/llc/llc_sock.c	Fri Sep 27 14:51:02 2002
+++ b/net/llc/llc_sock.c	Fri Sep 27 14:51:02 2002
@@ -40,6 +40,7 @@
 #include <net/llc_pdu.h>
 #include <net/llc_conn.h>
 #include <net/llc_mac.h>
+#include <net/llc_main.h>
 #include <linux/llc.h>
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
@@ -50,11 +51,7 @@
 static u16 llc_ui_sap_link_no_max[256];
 static struct sockaddr_llc llc_ui_addrnull;
 static struct proto_ops llc_ui_ops;
-static struct sock *llc_ui_sockets;
-static rwlock_t llc_ui_sockets_lock = RW_LOCK_UNLOCKED;
 
-static int llc_ui_indicate(struct llc_prim_if_block *prim);
-static int llc_ui_confirm(struct llc_prim_if_block *prim);
 static int llc_ui_wait_for_conn(struct sock *sk, int timeout);
 static int llc_ui_wait_for_disc(struct sock *sk, int timeout);
 static int llc_ui_wait_for_data(struct sock *sk, int timeout);
@@ -144,168 +141,6 @@
 	return rc;
 }
 
-/**
- *	llc_ui_find_sap - returns sap struct that matches sap number specified
- *	@sap: Sap number to search for.
- *
- *	Search the local socket list and return the first instance of the sap
- *	structure which matches the sap number the user specified.
- *	Returns llc_sap upon match, %NULL otherwise.
- */
-static __inline__ struct llc_sap *llc_ui_find_sap(u8 sap)
-{
-	struct sock *sk;
-	struct llc_sap *s = NULL;
-
-	read_lock_bh(&llc_ui_sockets_lock);
-	for (sk = llc_ui_sockets; sk; sk = sk->next) {
-		struct llc_opt *llc = llc_sk(sk);
-
-		if (!llc->sap)
-			continue;
-		if (llc->sap->laddr.lsap == sap) {
-			s = llc->sap;
-			break;
-		}
-	}
-	read_unlock_bh(&llc_ui_sockets_lock);
-	return s;
-}
-
-static struct sock *__llc_ui_find_sk_by_exact(struct llc_addr *laddr,
-					      struct llc_addr *daddr)
-{
-	struct sock *sk;
-
-	for (sk = llc_ui_sockets; sk; sk = sk->next) {
-		struct llc_opt *llc = llc_sk(sk);
-
-		if (llc->addr.sllc_ssap == laddr->lsap &&
-		    llc->addr.sllc_dsap == daddr->lsap &&
-		    llc_mac_null(llc->addr.sllc_mmac) &&
-		    llc_mac_match(llc->addr.sllc_smac, laddr->mac) &&
-		    llc_mac_match(llc->addr.sllc_dmac, daddr->mac))
-			break;
-	}
-	return sk;
-}
-
-/**
- *	__llc_ui_find_sk_by_addr - return socket matching local mac + sap.
- *	@addr: Local address to match.
- *
- *	Search the local socket list and return the socket which has a matching
- *	local (mac + sap) address (allows null mac). This search will work on
- *	unconnected and connected sockets, though find_by_link_no is recommend
- *	for connected sockets.
- *	Returns sock upon match, %NULL otherwise.
- */
-static struct sock *__llc_ui_find_sk_by_addr(struct llc_addr *laddr,
-					     struct llc_addr *daddr,
-					     struct net_device *dev)
-{
-	struct sock *sk, *tmp_sk;
-
-	for (sk = llc_ui_sockets; sk; sk = sk->next) {
-		struct llc_opt *llc = llc_sk(sk);
-
-		if (llc->addr.sllc_ssap != laddr->lsap)
-			continue;
-		if (llc_mac_null(llc->addr.sllc_smac)) {
-			if (!llc_mac_null(llc->addr.sllc_mmac) &&
-			    !llc_mac_match(llc->addr.sllc_mmac,
-				    	   laddr->mac))
-				continue;
-			break;
-		}
-		if (dev && !llc_mac_null(llc->addr.sllc_mmac) &&
-		    llc_mac_match(llc->addr.sllc_mmac, laddr->mac) &&
-		    llc_mac_match(llc->addr.sllc_smac, dev->dev_addr))
-			break;
-		if (dev->flags & IFF_LOOPBACK)
-			break;
-		if (!llc_mac_match(llc->addr.sllc_smac, laddr->mac))
-			continue;
-		tmp_sk = __llc_ui_find_sk_by_exact(laddr, daddr);
-		if (tmp_sk) {
-			sk = tmp_sk;
-			break;
-		}
-		if (llc_mac_null(llc->addr.sllc_dmac))
-			break;
-	}
-	return sk;
-}
-
-static struct sock *llc_ui_find_sk_by_addr(struct llc_addr *addr,
-					   struct llc_addr *daddr,
-					   struct net_device *dev)
-{
-	struct sock *sk;
-
-	read_lock(&llc_ui_sockets_lock);
-	sk = __llc_ui_find_sk_by_addr(addr, daddr, dev);
-	if (sk)
-		sock_hold(sk);
-	read_unlock(&llc_ui_sockets_lock);
-	return sk;
-}
-
-static struct sock *llc_ui_bh_find_sk_by_addr(struct llc_addr *addr,
-					      struct llc_addr *daddr,
-					      struct net_device *dev)
-{
-	struct sock *sk;
-
-	read_lock_bh(&llc_ui_sockets_lock);
-	sk = __llc_ui_find_sk_by_addr(addr, daddr, dev);
-	if (sk)
-		sock_hold(sk);
-	read_unlock_bh(&llc_ui_sockets_lock);
-	return sk;
-}
-
-/**
- *	llc_ui_insert_socket - insert socket into list
- *	@sk: Socket to insert.
- *
- *	Insert a socket into the local llc socket list.
- */
-static __inline__ void llc_ui_insert_socket(struct sock *sk)
-{
-	write_lock_bh(&llc_ui_sockets_lock);
-	sk->next = llc_ui_sockets;
-	if (sk->next)
-		llc_ui_sockets->pprev = &sk->next;
-	llc_ui_sockets = sk;
-	sk->pprev = &llc_ui_sockets;
-	sock_hold(sk);
-	write_unlock_bh(&llc_ui_sockets_lock);
-}
-
-/**
- *	llc_ui_remove_socket - remove socket from list
- *	@sk: Socket to remove.
- *
- *	Remove a socket from the local llc socket list.
- */
-static __inline__ void llc_ui_remove_socket(struct sock *sk)
-{
-	write_lock_bh(&llc_ui_sockets_lock);
-	if (sk->pprev) {
-		if (sk->next)
-			sk->next->pprev = sk->pprev;
-		*sk->pprev = sk->next;
-		sk->pprev = NULL;
-		/*
-		 * This only makes sense if the socket was inserted on the
-		 * list, if sk->pprev is NULL it wasn't
-		 */
-		sock_put(sk);
-	}
-	write_unlock_bh(&llc_ui_sockets_lock);
-}
-
 static void llc_ui_sk_init(struct socket *sock, struct sock *sk)
 {
 	sk->type   = sock->type;
@@ -360,12 +195,10 @@
 		llc->laddr.lsap, llc->daddr.lsap);
 	if (!llc_send_disc(sk))
 		llc_ui_wait_for_disc(sk, sk->rcvtimeo);
-	if (!sk->zapped) {
+	if (!sk->zapped)
 		llc_sap_unassign_sock(llc->sap, sk);
-		llc_ui_remove_socket(sk);
-	}
 	release_sock(sk);
-	if (llc->sap && list_empty(&llc->sap->sk_list.list))
+	if (llc->sap && !llc->sap->sk_list.list)
 		llc_sap_close(llc->sap);
 	sock_put(sk);
 	llc_sk_free(sk);
@@ -388,7 +221,7 @@
 	while (tries < LLC_SAP_DYN_TRIES) {
 		for (i = llc_ui_sap_last_autoport;
 		     i < LLC_SAP_DYN_STOP; i += 2) {
-			sap = llc_ui_find_sap(i);
+			sap = llc_sap_find(i);
 			if (!sap) {
 				llc_ui_sap_last_autoport = i + 2;
 				goto out;
@@ -446,10 +279,9 @@
 		if (!addr->sllc_ssap)
 			goto out;
 	}
-	sap = llc_ui_find_sap(addr->sllc_ssap);
+	sap = llc_sap_find(addr->sllc_ssap);
 	if (!sap) {
-		sap = llc_sap_open(llc_ui_indicate, llc_ui_confirm,
-				   addr->sllc_ssap);
+		sap = llc_sap_open(addr->sllc_ssap, NULL);
 		rc = -EBUSY; /* some other network layer is using the sap */
 		if (!sap)
 			goto out;
@@ -472,7 +304,7 @@
 			memcpy(laddr.mac, addr->sllc_smac, IFHWADDRLEN);
 		laddr.lsap = addr->sllc_ssap;
 		rc = -EADDRINUSE; /* mac + sap clash. */
-		ask = llc_ui_bh_find_sk_by_addr(&laddr, &daddr, dev);
+		ask = llc_lookup_established(sap, &daddr, &laddr);
 		if (ask) {
 			sock_put(ask);
 			goto out;
@@ -484,7 +316,6 @@
 	llc->daddr.lsap = addr->sllc_dsap;
 	memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
 	memcpy(&llc->addr, addr, sizeof(llc->addr));
-	llc_ui_insert_socket(sk);
 	/* assign new connection to it's SAP */
 	llc_sap_assign_sock(sap, sk);
 	rc = sk->zapped = 0;
@@ -833,7 +664,6 @@
 	/* put original socket back into a clean listen state. */
 	sk->state = TCP_LISTEN;
 	sk->ack_backlog--;
-	llc_ui_insert_socket(newsk);
 	skb->sk = NULL;
 	dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
 		llc_sk(sk)->addr.sllc_ssap, newllc->addr.sllc_dsap);
@@ -1190,178 +1020,6 @@
 	return rc;
 }
 
-/**
- *	llc_ui_ind_test - handle TEST indication
- *	@prim: Primitive block provided by the llc layer.
- *
- *	handle TEST indication.
- */
-static void llc_ui_ind_test(struct llc_prim_if_block *prim)
-{
-	struct llc_prim_test *prim_data = &prim->data->test;
-	struct sk_buff *skb = prim_data->skb;
-	struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
-	struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
-						 &prim_data->saddr, skb->dev);
-	if (!sk)
-		goto out;
-	if (sk->state == TCP_LISTEN)
-		goto out_put;
-	/* save primitive for use by the user. */
-	addr->sllc_family = AF_LLC;
-	addr->sllc_arphrd = skb->dev->type;
-	addr->sllc_test   = 1;
-	addr->sllc_xid    = 0;
-	addr->sllc_ua     = 0;
-	addr->sllc_dsap = prim_data->daddr.lsap;
-	memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
-	addr->sllc_ssap = prim_data->saddr.lsap;
-	memcpy(addr->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN);
-	/* queue skb to the user. */
-	if (sock_queue_rcv_skb(sk, skb))
-		kfree_skb(skb);
-out_put:
-	sock_put(sk);
-out:;
-}
-
-/**
- *	llc_ui_ind_xid - handle XID indication
- *	@prim: Primitive block provided by the llc layer.
- *
- *	handle XID indication.
- */
-static void llc_ui_ind_xid(struct llc_prim_if_block *prim)
-{
-	struct llc_prim_xid *prim_data = &prim->data->xid;
-	struct sk_buff *skb = prim_data->skb;
-	struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
-	struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
-						 &prim_data->saddr, skb->dev);
-	if (!sk)
-		goto out;
-	if (sk->state == TCP_LISTEN)
-		goto out_put;
-	/* save primitive for use by the user. */
-	addr->sllc_family = AF_LLC;
-	addr->sllc_arphrd = 0;
-	addr->sllc_test   = 0;
-	addr->sllc_xid    = 1;
-	addr->sllc_ua     = 0;
-	addr->sllc_dsap = prim_data->daddr.lsap;
-	memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
-	addr->sllc_ssap = prim_data->saddr.lsap;
-	memcpy(addr->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN);
-	/* queue skb to the user. */
-	if (sock_queue_rcv_skb(sk, skb))
-		kfree_skb(skb);
-out_put:
-	sock_put(sk);
-out:;
-}
-
-/**
- *	llc_ui_ind_dataunit - handle DATAUNIT indication
- *	@prim: Primitive block provided by the llc layer.
- *
- *	handle DATAUNIT indication.
- */
-static void llc_ui_ind_dataunit(struct llc_prim_if_block *prim)
-{
-	struct llc_prim_unit_data *prim_data = &prim->data->udata;
-	struct sk_buff *skb = prim_data->skb;
-	struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
-	struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
-						 &prim_data->saddr, skb->dev);
-	if (!sk)
-		goto out;
-	if (sk->state == TCP_LISTEN)
-		goto out_put;
-	/* save primitive for use by the user. */
-	addr->sllc_family = AF_LLC;
-	addr->sllc_arphrd = skb->dev->type;
-	addr->sllc_test   = 0;
-	addr->sllc_xid    = 0;
-	addr->sllc_ua     = 1;
-	addr->sllc_dsap = prim_data->daddr.lsap;
-	memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
-	addr->sllc_ssap = prim_data->saddr.lsap;
-	memcpy(addr->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN);
-	/* queue skb to the user. */
-	if (sock_queue_rcv_skb(sk, skb))
-		kfree_skb(skb);
-out_put:
-	sock_put(sk);
-out:;
-}
-
-/**
- *	llc_ui_indicate - LLC user interface hook into the LLC layer.
- *	@prim: Primitive block provided by the llc layer.
- *
- *	LLC user interface hook into the LLC layer, every llc_ui sap references
- *	this function as its indicate handler.
- *	Always returns 0 to indicate reception of primitive.
- */
-static int llc_ui_indicate(struct llc_prim_if_block *prim)
-{
-	switch (prim->prim) {
-		case LLC_TEST_PRIM:
-			llc_ui_ind_test(prim);		break;
-		case LLC_XID_PRIM:
-			llc_ui_ind_xid(prim);		break;
-		case LLC_DATAUNIT_PRIM:
-			llc_ui_ind_dataunit(prim);	break;
-		case LLC_CONN_PRIM:
-			dprintk("%s: shouldn't happen, LLC_CONN_PRIM "
-				"is gone for ->ind()...\n", __FUNCTION__);
-			break;
-		case LLC_DATA_PRIM:
-			dprintk("%s: shouldn't happen, LLC_DATA_PRIM "
-				"is gone for ->ind()...\n", __FUNCTION__);
-			break;
-		case LLC_DISC_PRIM:
-			dprintk("%s: shouldn't happen, LLC_DISC_PRIM "
-				"is gone for ->ind()...\n", __FUNCTION__);
-			break;
-		case LLC_RESET_PRIM:
-		default:				break;
-	}
-	return 0;
-}
-
-/**
- *	llc_ui_confirm - LLC user interface hook into the LLC layer
- *	@prim: Primitive block provided by the llc layer.
- *
- *	LLC user interface hook into the LLC layer, every llc_ui sap references
- *	this function as its confirm handler.
- *	Always returns 0 to indicate reception of primitive.
- */
-static int llc_ui_confirm(struct llc_prim_if_block *prim)
-{
-	switch (prim->prim) {
-		case LLC_CONN_PRIM:
-			dprintk("%s: shouldn't happen, LLC_CONN_PRIM "
-				"is gone for ->conf()...\n", __FUNCTION__);
-			break;
-		case LLC_DATA_PRIM:
-			dprintk("%s: shouldn't happen, LLC_DATA_PRIM "
-				"is gone for ->conf()...\n", __FUNCTION__);
-			break;
-		case LLC_DISC_PRIM:
-			dprintk("%s: shouldn't happen, LLC_DISC_PRIM "
-				"is gone for ->conf()...\n", __FUNCTION__);
-			break;
-		case LLC_RESET_PRIM:			break;
-		default:
-			printk(KERN_ERR "%s: prim not supported%d\n", __FUNCTION__,
-			       prim->prim);
-			break;
-	}
-	return 0;
-}
-
 #ifdef CONFIG_PROC_FS
 #define MAC_FORMATTED_SIZE 17
 static void llc_ui_format_mac(char *bf, unsigned char *mac)
@@ -1384,18 +1042,25 @@
 {
 	off_t pos = 0;
 	off_t begin = 0;
-	struct sock *s;
+	struct llc_sap *sap;
+	struct sock *sk;
+	struct list_head *sap_entry;
+	struct llc_station *station = llc_station_get();
 	int len = sprintf(buffer, "SKt Mc local_mac_sap        "
 				  "remote_mac_sap       tx_queue rx_queue st uid "
 				  "link\n");
+
 	/* Output the LLC socket data for the /proc filesystem */
-	read_lock_bh(&llc_ui_sockets_lock);
-	for (s = llc_ui_sockets; s; s = s->next) {
-		struct llc_opt *llc = llc_sk(s);
-
-		len += sprintf(buffer + len, "%2X  %2X ", s->type,
-			       !llc_mac_null(llc->addr.sllc_mmac));
-		if (llc->sap) {
+	read_lock_bh(&station->sap_list.lock);
+	list_for_each(sap_entry, &station->sap_list.list) {
+		sap = list_entry(sap_entry, struct llc_sap, node);
+
+		read_lock_bh(&sap->sk_list.lock);
+		for (sk = sap->sk_list.list; sk; sk = sk->next) {
+			struct llc_opt *llc = llc_sk(sk);
+
+			len += sprintf(buffer + len, "%2X  %2X ", sk->type,
+				       !llc_mac_null(llc->addr.sllc_mmac));
 			if (llc->dev && llc_mac_null(llc->addr.sllc_mmac))
 				llc_ui_format_mac(buffer + len,
 						  llc->dev->dev_addr);
@@ -1408,30 +1073,31 @@
 						"00:00:00:00:00:00");
 			}
 			len += MAC_FORMATTED_SIZE;
-			len += sprintf(buffer + len, "@%02X ",
-					llc->sap->laddr.lsap);
-		} else
-			len += sprintf(buffer + len, "00:00:00:00:00:00@00 ");
-		llc_ui_format_mac(buffer + len, llc->addr.sllc_dmac);
-		len += MAC_FORMATTED_SIZE;
-		len += sprintf(buffer + len,
-				"@%02X %8d %8d %2d %-3d ",
-				llc->addr.sllc_dsap,
-				atomic_read(&s->wmem_alloc),
-				atomic_read(&s->rmem_alloc), s->state,
-				SOCK_INODE(s->socket)->i_uid);
-		len += sprintf(buffer + len, "%-4d\n", llc->link);
-		/* Are we still dumping unwanted data then discard the record */
-		pos = begin + len;
-
-		if (pos < offset) {
-			len = 0; /* Keep dumping into the buffer start */
-			begin = pos;
+			len += sprintf(buffer + len, "@%02X ", sap->laddr.lsap);
+			llc_ui_format_mac(buffer + len, llc->addr.sllc_dmac);
+			len += MAC_FORMATTED_SIZE;
+			len += sprintf(buffer + len,
+					"@%02X %8d %8d %2d %3d ",
+					llc->addr.sllc_dsap,
+					atomic_read(&sk->wmem_alloc),
+					atomic_read(&sk->rmem_alloc),
+					sk->state,
+					sk->socket ?
+					  SOCK_INODE(sk->socket)->i_uid : -1);
+			len += sprintf(buffer + len, "%4d\n", llc->link);
+			/* Are we still dumping unwanted data then discard the record */
+			pos = begin + len;
+
+			if (pos < offset) {
+				len = 0; /* Keep dumping into the buffer start */
+				begin = pos;
+			}
+			if (pos > offset + length) /* We have dumped enough */
+				break;
 		}
-		if (pos > offset + length) /* We have dumped enough */
-			break;
+		read_unlock_bh(&sap->sk_list.lock);
 	}
-	read_unlock_bh(&llc_ui_sockets_lock);
+	read_unlock_bh(&station->sap_list.lock);
 
 	/* The data in question runs from begin to begin + len */
 	*start = buffer + offset - begin; /* Start of wanted data */
@@ -1447,7 +1113,7 @@
 	.create = llc_ui_create,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(llc_ui_ops) = {
+static struct proto_ops llc_ui_ops = {
 	.family	     = PF_LLC,
 	.release     = llc_ui_release,
 	.bind	     = llc_ui_bind,
@@ -1466,9 +1132,6 @@
 	.mmap	     = sock_no_mmap,
 	.sendpage    = sock_no_sendpage,
 };
-
-#include <linux/smp_lock.h>
-SOCKOPS_WRAP(llc_ui, PF_LLC);
 
 static char llc_ui_banner[] __initdata =
 	KERN_INFO "NET4.0 IEEE 802.2 BSD sockets, Jay Schulist, 2001, Arnaldo C. Melo, 2002\n";
diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c
--- a/net/sched/sch_htb.c	Fri Sep 27 14:51:04 2002
+++ b/net/sched/sch_htb.c	Fri Sep 27 14:51:04 2002
@@ -1163,6 +1163,8 @@
 	skb_queue_head_init(&q->direct_queue);
 
 	q->direct_qlen = sch->dev->tx_queue_len;
+	if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */
+		q->direct_qlen = 2;
 	q->timer.function = htb_timer;
 	q->timer.data = (unsigned long)sch;
 
@@ -1429,6 +1431,10 @@
 	if (!rtab || !ctab) goto failure;
 
 	if (!cl) { /* new class */
+		/* check for valid classid */
+		if (!classid || TC_H_MAJ(classid^sch->handle) || htb_find(classid,sch))
+			goto failure;
+
 		/* check maximal depth */
 		if (parent && parent->parent && parent->parent->level < 2) {
 			printk(KERN_ERR "htb: tree is too deep\n");
diff -Nru a/net/sctp/adler32.c b/net/sctp/adler32.c
--- a/net/sctp/adler32.c	Fri Sep 27 14:51:05 2002
+++ b/net/sctp/adler32.c	Fri Sep 27 14:51:05 2002
@@ -96,7 +96,7 @@
 		 * one subtract at the MOST, since buf[n]
 		 * is a max of 255.
 		 */
-		if(s1 >= BASE)
+		if (s1 >= BASE)
 			s1 -= BASE;
 
 		/* s2 = (s2 + s1) % BASE */
diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/associola.c	Fri Sep 27 14:51:03 2002
@@ -66,7 +66,7 @@
 
 /* Allocate and initialize a new association */
 sctp_association_t *sctp_association_new(const sctp_endpoint_t *ep,
-					 const struct sock *sk, 
+					 const struct sock *sk,
 					 sctp_scope_t scope, int priority)
 {
 	sctp_association_t *asoc;
@@ -91,7 +91,7 @@
 
 /* Intialize a new association from provided memory. */
 sctp_association_t *sctp_association_init(sctp_association_t *asoc,
-					  const sctp_endpoint_t *ep, 
+					  const sctp_endpoint_t *ep,
 					  const struct sock *sk,
 					  sctp_scope_t scope, 
 					  int priority)
@@ -109,19 +109,19 @@
 	asoc->ep = (sctp_endpoint_t *)ep;
 	sctp_endpoint_hold(asoc->ep);
 
-	/* Hold the sock. */
+	/* Hold the sock.  */
 	asoc->base.sk = (struct sock *)sk;
 	sock_hold(asoc->base.sk);
 
-	/* Initialize the common base substructure. */
+	/* Initialize the common base substructure.  */
 	asoc->base.type = SCTP_EP_TYPE_ASSOCIATION;
 
-	/* Initialize the object handling fields. */
+	/* Initialize the object handling fields.  */
 	atomic_set(&asoc->base.refcnt, 1);
 	asoc->base.dead = 0;
 	asoc->base.malloced = 0;
 
-	/* Initialize the bind addr area. */
+	/* Initialize the bind addr area.  */
 	sctp_bind_addr_init(&asoc->base.bind_addr, ep->base.bind_addr.port);
 	asoc->base.addr_lock = RW_LOCK_UNLOCKED;
 
@@ -135,7 +135,7 @@
 	asoc->pmtu = 0;
 	asoc->frag_point = 0;
 
-	/* Initialize the default association max_retrans and RTO values. */
+	/* Initialize the default association max_retrans and RTO values.  */
 	asoc->max_retrans = ep->proto->max_retrans_association;
 	asoc->rto_initial = ep->proto->rto_initial;
 	asoc->rto_max = ep->proto->rto_max;
@@ -288,7 +288,6 @@
 	return NULL;
 }
 
-
 /* Free this association if possible.  There may still be users, so
  * the actual deallocation may be delayed.
  */
@@ -330,6 +329,11 @@
 			sctp_association_put(asoc);
 	}
 
+	/* Free peer's cached cookie. */
+	if (asoc->peer.cookie) {
+		kfree(asoc->peer.cookie);
+	}
+
 	/* Release the transport structures. */
 	list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
 		transport = list_entry(pos, sctp_transport_t, transports);
@@ -342,7 +346,6 @@
 	sctp_association_put(asoc);
 }
 
-
 /* Cleanup and free up an association. */
 static void sctp_association_destroy(sctp_association_t *asoc)
 {
@@ -383,12 +386,11 @@
 	};
 
 	/* Set the port if it has not been set yet.  */
-        if (0 == asoc->peer.port) {
-                asoc->peer.port = *port;
-        }
+	if (0 == asoc->peer.port) {
+		asoc->peer.port = *port;
+	}
 
-	SCTP_ASSERT(*port == asoc->peer.port, ":Invalid port\n",
-		    return NULL);
+	SCTP_ASSERT(*port == asoc->peer.port, ":Invalid port\n", return NULL);
 
 	/* Check to see if this is a duplicate. */
 	peer = sctp_assoc_lookup_paddr(asoc, addr);
@@ -461,11 +463,21 @@
 	sp = sctp_sk(asoc->base.sk);
 	peer->hb_interval = sp->paddrparam.spp_hbinterval * HZ;
 
-        /* Attach the remote transport to our asoc.  */
+	/* Attach the remote transport to our asoc.  */
 	list_add_tail(&peer->transports, &asoc->peer.transport_addr_list);
 
 	/* If we do not yet have a primary path, set one.  */
-        if (NULL == asoc->peer.primary_path) {
+	if (NULL == asoc->peer.primary_path) {
+		asoc->peer.primary_path = peer;
+		/* Set a default msg_name for events. */
+		memcpy(&asoc->peer.primary_addr, &peer->ipaddr,
+		       sizeof(sockaddr_storage_t));
+		asoc->peer.active_path = peer;
+		asoc->peer.retran_path = peer;
+	}
+
+	/* If we do not yet have a primary path, set one.  */
+	if (NULL == asoc->peer.primary_path) {
 		asoc->peer.primary_path = peer;
 		asoc->peer.active_path = peer;
 		asoc->peer.retran_path = peer;
@@ -617,7 +629,7 @@
 	asoc->next_tsn++;
 	asoc->unack_data++;
 
-        return retval;
+	return retval;
 }
 
 /* Allocate 'num' TSNs by incrementing the association's TSN by num. */
@@ -739,7 +751,7 @@
  * Note:  We are sly and return a shared, prealloced chunk.
  */
 sctp_chunk_t *sctp_get_ecne_prepend(sctp_association_t *asoc)
-{ 
+{
 	sctp_chunk_t *chunk;
 	int need_ecne;
 	__u32 lowest_tsn;
@@ -892,7 +904,7 @@
 
 		/* Check to see if the association is freed in response to 
 		 * the incoming chunk.  If so, get out of the while loop.
-		 */ 
+		 */
 		if (!sctp_id2assoc(sk, associd))
 			goto out;
 
@@ -967,7 +979,7 @@
 		 * and peer's streams.
 		 */
 		for (i = 0; i < SCTP_MAX_STREAM; i++) {
-			asoc->ssn[i]      = 0;
+			asoc->ssn[i] = 0;
 			asoc->ulpq.ssn[i] = 0;
 		}
 	} else {
diff -Nru a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
--- a/net/sctp/bind_addr.c	Fri Sep 27 14:51:05 2002
+++ b/net/sctp/bind_addr.c	Fri Sep 27 14:51:05 2002
@@ -1,43 +1,43 @@
 /* SCTP kernel reference Implementation
- * Copyright (c) Cisco 1999,2000 
- * Copyright (c) Motorola 1999,2000,2001 
+ * Copyright (c) Cisco 1999,2000
+ * Copyright (c) Motorola 1999,2000,2001
  * Copyright (c) International Business Machines Corp., 2001
  * Copyright (c) La Monte H.P. Yarroll 2001
  *
  * This file is part of the SCTP kernel reference implementation.
- * 
- * A collection class to handle the storage of transport addresses. 
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * A collection class to handle the storage of transport addresses.
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
  *    Jon Grimm             <jgrimm@us.ibm.com>
  *    Daisy Chang           <daisyc@us.ibm.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -83,7 +83,7 @@
 out:
 	if (error)
 		sctp_bind_addr_clean(dest);
-	
+
 	return error;
 }
 
@@ -356,7 +356,7 @@
 	case AF_INET:
 		/* According to the SCTP IPv4 address scoping document -
 		 * <draft-stewart-tsvwg-sctp-ipv4-00.txt>, the scope has
-		 * a heirarchy of 5 levels: 
+		 * a heirarchy of 5 levels:
 		 * Level 0 - unusable SCTP addresses
 		 * Level 1 - loopback address
 		 * Level 2 - link-local addresses
diff -Nru a/net/sctp/command.c b/net/sctp/command.c
--- a/net/sctp/command.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/command.c	Fri Sep 27 14:51:03 2002
@@ -1,39 +1,39 @@
 /* SCTP kernel reference Implementation Copyright (C) 1999-2001
  * Cisco, Motorola, and IBM
  * Copyright 2001 La Monte H.P. Yarroll
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These functions manipulate sctp command sequences.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson <karl@athena.chicago.il.us>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
diff -Nru a/net/sctp/debug.c b/net/sctp/debug.c
--- a/net/sctp/debug.c	Fri Sep 27 14:51:04 2002
+++ b/net/sctp/debug.c	Fri Sep 27 14:51:04 2002
@@ -198,6 +198,7 @@
 	"TIMEOUT_T2_SHUTDOWN",
 	"TIMEOUT_T3_RTX",
 	"TIMEOUT_T4_RTO",
+	"TIMEOUT_T5_SHUTDOWN_GUARD",
 	"TIMEOUT_HEARTBEAT",
 	"TIMEOUT_SACK",
 	"TIMEOUT_AUTOCLOSE",
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/endpointola.c	Fri Sep 27 14:51:03 2002
@@ -5,46 +5,46 @@
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
- * This abstraction represents an SCTP endpoint.   
+ *
+ * This abstraction represents an SCTP endpoint.
  *
  * This file is part of the implementation of the add-IP extension,
  * based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
  * for the SCTP kernel reference Implementation.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson <karl@athena.chicago.il.us>
  *    Jon Grimm <jgrimm@austin.ibm.com>
  *    Daisy Chang <daisyc@us.ibm.com>
  *    Dajiang Zhang <dajiang.zhang@nokia.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -92,15 +92,16 @@
 sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
 				    struct sock *sk, int priority)
 {
+	sctp_opt_t *sp = sctp_sk(sk);
 	memset(ep, 0, sizeof(sctp_endpoint_t));
 
 	/* Initialize the base structure. */
 	/* What type of endpoint are we?  */
 	ep->base.type = SCTP_EP_TYPE_SOCKET;
 
-        /* Initialize the basic object fields. */
+	/* Initialize the basic object fields. */
 	atomic_set(&ep->base.refcnt, 1);
-	ep->base.dead     = 0;
+	ep->base.dead = 0;
 	ep->base.malloced = 1;
 
 	/* Create an input queue.  */
@@ -129,22 +130,30 @@
 
 	/* Set up the base timeout information.  */
 	ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]
-		= SCTP_DEFAULT_TIMEOUT_T1_COOKIE;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]
-		= SCTP_DEFAULT_TIMEOUT_T1_INIT;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN]
-		= sctp_sk(sk)->rtoinfo.srto_initial;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = 
+		SCTP_DEFAULT_TIMEOUT_T1_COOKIE;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = 
+		SCTP_DEFAULT_TIMEOUT_T1_INIT;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = 
+		sp->rtoinfo.srto_initial;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = 0;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT]
-		= SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_SACK]
-		= SCTP_DEFAULT_TIMEOUT_SACK;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]
-		= sctp_sk(sk)->autoclose * HZ;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_PMTU_RAISE]
-		= SCTP_DEFAULT_TIMEOUT_PMTU_RAISE;
+
+	/* sctpimpguide-05 Section 2.12.2
+	 * If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
+	 * recommended value of 5 times 'RTO.Max'.
+	 */
+        ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
+		= 5 * sp->rtoinfo.srto_max;
+
+	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 
+		SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+		SCTP_DEFAULT_TIMEOUT_SACK;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = 
+		sp->autoclose * HZ;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_PMTU_RAISE] = 
+		SCTP_DEFAULT_TIMEOUT_PMTU_RAISE;
 
 	/* Set up the default send/receive buffer space.  */
 
@@ -251,9 +260,10 @@
  * We do a linear search of the associations for this endpoint.
  * We return the matching transport address too.
  */
-sctp_association_t *__sctp_endpoint_lookup_assoc(const sctp_endpoint_t *endpoint,
-						 const sockaddr_storage_t *paddr,
-						 sctp_transport_t **transport)
+sctp_association_t *__sctp_endpoint_lookup_assoc(
+	const sctp_endpoint_t *endpoint,
+	const sockaddr_storage_t *paddr,
+	sctp_transport_t **transport)
 {
 	int rport;
 	sctp_association_t *asoc;
@@ -310,7 +320,7 @@
 
 	asoc = NULL;
 	inqueue = &ep->base.inqueue;
-	sk      = ep->base.sk;
+	sk = ep->base.sk;
 
 	while (NULL != (chunk = sctp_pop_inqueue(inqueue))) {
 		subtype.chunk = chunk->chunk_hdr->type;
@@ -343,15 +353,15 @@
 		/* FIX ME We really would rather NOT have to use
 		 * GFP_ATOMIC.
 		 */
-                error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state,
+		error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state,
                                    ep, asoc, chunk, GFP_ATOMIC);
 
 		if (error != 0)
 			goto err_out;
 
-		/* Check to see if the endpoint is freed in response to 
+		/* Check to see if the endpoint is freed in response to
 		 * the incoming chunk. If so, get out of the while loop.
-		 */ 
+		 */
 		if (!sctp_sk(sk)->ep)
 			goto out;
 	}
@@ -360,10 +370,5 @@
 	/* Is this the right way to pass errors up to the ULP?  */
 	if (error)
 		ep->base.sk->err = -error;
-
 out:
 }
-
-
-
-
diff -Nru a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/input.c	Fri Sep 27 14:51:03 2002
@@ -5,43 +5,43 @@
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
- * These functions handle all input from the IP layer into SCTP. 
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * These functions handle all input from the IP layer into SCTP.
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson <karl@athena.chicago.il.us>
  *    Xingang Guo <xingang.guo@intel.com>
  *    Jon Grimm <jgrimm@us.ibm.com>
  *    Hui Huang <hui.huang@nokia.com>
  *    Daisy Chang <daisyc@us.ibm.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -57,7 +57,7 @@
 #include <net/sctp/sm.h>
 
 /* Forward declarations for internal helpers. */
-static int sctp_rcv_ootb(struct sk_buff *); 
+static int sctp_rcv_ootb(struct sk_buff *);
 sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const sockaddr_storage_t *laddr,
 				      const sockaddr_storage_t *paddr,
@@ -639,7 +639,7 @@
 /* Lookup an association for an inbound skb. */
 sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const sockaddr_storage_t *paddr,
-				      const sockaddr_storage_t *laddr, 
+				      const sockaddr_storage_t *laddr,
 				      sctp_transport_t **transportp)
 {
 	sctp_association_t *asoc;
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c	Fri Sep 27 14:51:04 2002
+++ b/net/sctp/ipv6.c	Fri Sep 27 14:51:04 2002
@@ -2,36 +2,36 @@
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
  * Copyright (c) 2002 International Business Machines, Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * SCTP over IPv6.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    Le Yanqun             <yanqun.le@nokia.com>
  *    Hui Huang		    <hui.huang@nokia.com>
  *    La Monte H.P. Yarroll <piggy@acm.org>
@@ -40,7 +40,7 @@
  *
  * Based on:
  *      linux/net/ipv6/tcp_ipv6.c
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -145,7 +145,7 @@
 			      IPV6_ADDR_LOOPBACK)) {
 				ipv6_addr_copy(&saddr, &np->daddr);
 			}
-		}			
+		}
 		fl.fl6_src = &saddr;
 	} else {
 		fl.fl6_src = &np->saddr;
@@ -177,7 +177,7 @@
 	if (dst) {
 		dst_mtu = dst->pmtu;
 		SCTP_DEBUG_PRINTK("sctp_v6_get_dst_mtu: "
-				  "ip6_route_output: dev:%s pmtu:%d\n", 
+				  "ip6_route_output: dev:%s pmtu:%d\n",
 				  dst->dev->name, dst_mtu);
 		dst_release(dst);
 	} else {
@@ -189,11 +189,85 @@
 	return dst_mtu;
 }
 
+/* Initialize a PF_INET6 socket msg_name. */
+static void sctp_inet6_msgname(char *msgname, int *addr_len)
+{
+	struct sockaddr_in6 *sin6;
+
+	sin6 = (struct sockaddr_in6 *)msgname;
+	sin6->sin6_family = AF_INET6;
+	sin6->sin6_flowinfo = 0;
+	sin6->sin6_scope_id = 0;
+	*addr_len = sizeof(struct sockaddr_in6);
+}
+
+/* Initialize a PF_INET msgname from a ulpevent. */
+static void sctp_inet6_event_msgname(sctp_ulpevent_t *event, char *msgname, int *addrlen)
+{
+	struct sockaddr_in6 *sin6, *sin6from;
+
+	if (msgname) {
+		sockaddr_storage_t *addr;
+
+		sctp_inet6_msgname(msgname, addrlen);
+		sin6 = (struct sockaddr_in6 *)msgname;
+		sin6->sin6_port = htons(event->asoc->peer.port);
+		addr = &event->asoc->peer.primary_addr;
+
+		/* Note: If we go to a common v6 format, this code
+		 * will change.
+		 */
+
+		/* Map ipv4 address into v4-mapped-on-v6 address.  */
+		if (AF_INET == addr->sa.sa_family) {
+			/* FIXME: Easy, but there was no way to test this
+			 * yet.
+			 */
+			return;
+		}
+
+		sin6from = &event->asoc->peer.primary_addr.v6;
+		ipv6_addr_copy(&sin6->sin6_addr, &sin6from->sin6_addr);
+	}
+}
+
+/* Initialize a msg_name from an inbound skb. */
+static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname,
+				   int *addr_len)
+{
+	struct sctphdr *sh;
+	struct sockaddr_in6 *sin6;
+
+	if (msgname) {
+		sctp_inet6_msgname(msgname, addr_len);
+		sin6 = (struct sockaddr_in6 *)msgname;
+		sh = (struct sctphdr *)skb->h.raw;
+		sin6->sin6_port = sh->source;
+
+		/* FIXME: Map ipv4 address into v4-mapped-on-v6 address. */
+		if (__constant_htons(ETH_P_IP) == skb->protocol) {
+			/* FIXME: Easy, but there was no way to test this
+			 * yet.
+			 */
+			return;
+		}
+
+		/* Otherwise, just copy the v6 address. */
+
+		ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
+		if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
+			struct inet6_skb_parm *opt =
+				(struct inet6_skb_parm *) skb->cb;
+			sin6->sin6_scope_id = opt->iif;
+		}
+	}
+}
+
 static struct proto_ops inet6_seqpacket_ops = {
 	.family     = PF_INET6,
 	.release    = inet6_release,
 	.bind       = inet6_bind,
-	.connect    = inet_dgram_connect,   
+	.connect    = inet_dgram_connect,
 	.socketpair = sock_no_socketpair,
 	.accept     = inet_accept,
 	.getname    = inet6_getname,
@@ -238,14 +312,21 @@
 	.sa_family       = AF_INET6,
 };
 
+static sctp_pf_t sctp_pf_inet6_specific = {
+	.event_msgname = sctp_inet6_event_msgname,
+	.skb_msgname   = sctp_inet6_skb_msgname,
+};
+
 /* Initialize IPv6 support and register with inet6 stack.  */
 int sctp_v6_init(void)
 {
 	/* Add SCTPv6 to inetsw6 linked list. */
 	inet6_register_protosw(&sctpv6_protosw);
-
 	/* Register inet6 protocol. */
 	inet6_add_protocol(&sctpv6_protocol);
+
+	/* Register the SCTP specfic PF_INET6 functions. */
+	sctp_set_pf_specific(PF_INET6, &sctp_pf_inet6_specific);
 
 	/* Fill in address family info.  */
 	INIT_LIST_HEAD(&sctp_ipv6_specific.list);
diff -Nru a/net/sctp/output.c b/net/sctp/output.c
--- a/net/sctp/output.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/output.c	Fri Sep 27 14:51:03 2002
@@ -2,41 +2,41 @@
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001 International Business Machines, Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These functions handle output processing.
- *  
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
  *    Jon Grimm             <jgrimm@austin.ibm.com>
  *    Sridhar Samudrala     <sri@us.ibm.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -48,7 +48,7 @@
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/init.h>
-#include <net/inet_ecn.h> 
+#include <net/inet_ecn.h>
 #include <net/icmp.h>
 
 #ifndef TEST_FRAME
@@ -113,7 +113,7 @@
 {
 	sctp_chunk_t *chunk;
 
-        while (NULL !=
+        while (NULL != 
 	       (chunk = (sctp_chunk_t *)skb_dequeue(&packet->chunks))) {
 		sctp_free_chunk(chunk);
 	}
@@ -129,7 +129,8 @@
  * as it can fit in the packet, but any more data that does not fit in this
  * packet can be sent only after receiving the COOKIE_ACK.
  */
-sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
+sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet,
+				       sctp_chunk_t *chunk)
 {
 	sctp_xmit_t retval;
 	int error = 0;
@@ -181,8 +182,8 @@
 		/* Both control chunks and data chunks with TSNs are
 		 * non-fragmentable.
 		 */
-		int fragmentable = sctp_chunk_is_data(chunk) 
-			&& (!chunk->has_tsn);
+		int fragmentable = sctp_chunk_is_data(chunk) && 
+			(!chunk->has_tsn);
 		if (packet_empty) {
 			if (fragmentable) {
 				retval = SCTP_XMIT_MUST_FRAG;
@@ -221,10 +222,8 @@
 	}
 
 	/* It is OK to send this chunk.  */
-	skb_queue_tail(&packet->chunks,
-		       (struct sk_buff *)chunk);
+	skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
 	packet->size += chunk_len;
-
 finish:
 	return retval;
 }
@@ -305,7 +304,7 @@
 			 */
 			if ((1 == chunk->num_times_sent) &&
 			    (!transport->rto_pending)) {
-				chunk->rtt_in_progress = 1;	
+				chunk->rtt_in_progress = 1;
 				transport->rto_pending = 1;
 			}
 			packet_has_data = 1;
@@ -337,9 +336,9 @@
 	}
 
 	/* Build the SCTP header.  */
-	sh = (struct sctphdr *) skb_push(nskb, sizeof(struct sctphdr));
-	sh->source		= htons(packet->source_port);
-	sh->dest		= htons(packet->destination_port);
+	sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
+	sh->source = htons(packet->source_port);
+	sh->dest   = htons(packet->destination_port);
 
 	/* From 6.8 Adler-32 Checksum Calculation:
 	 * After the packet is constructed (containing the SCTP common
@@ -349,8 +348,8 @@
 	 * 1) Fill in the proper Verification Tag in the SCTP common
 	 *    header and initialize the checksum field to 0's.
 	 */
-	sh->vtag	= htonl(packet->vtag);
-	sh->checksum	= 0;
+	sh->vtag     = htonl(packet->vtag);
+	sh->checksum = 0;
 
 	/* 2) Calculate the Adler-32 checksum of the whole packet,
 	 *    including the SCTP common header and all the
@@ -467,7 +466,8 @@
 }
 
 /* This private function handles the specifics of appending DATA chunks.  */
-static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *chunk)
+static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, 
+					   sctp_chunk_t *chunk)
 {
 	sctp_xmit_t retval = SCTP_XMIT_OK;
 	size_t datasize, rwnd, inflight;
@@ -502,12 +502,13 @@
 		}
 	}
 
-	/* sctpimpguide-05 2.14.2 D) When the time comes for the sender to
+	/* sctpimpguide-05 2.14.2
+	 * D) When the time comes for the sender to
 	 * transmit new DATA chunks, the protocol parameter Max.Burst MUST
 	 * first be applied to limit how many new DATA chunks may be sent.
 	 * The limit is applied by adjusting cwnd as follows:
-	 * 	if((flightsize + Max.Burst*MTU) < cwnd)
-	 *		cwnd = flightsize + Max.Burst*MTU
+	 * 	if ((flightsize + Max.Burst * MTU) < cwnd)
+	 *		cwnd = flightsize + Max.Burst * MTU
 	 */
 	max_burst_bytes = transport->asoc->max_burst * transport->asoc->pmtu;
 	if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
@@ -516,11 +517,11 @@
 				  "transport: %p, cwnd: %d, "
 				  "ssthresh: %d, flight_size: %d, "
 				  "pba: %d\n",
-				   __FUNCTION__, transport,
-				   transport->cwnd,
-				   transport->ssthresh,
-				   transport->flight_size,
-				   transport->partial_bytes_acked);
+				  __FUNCTION__, transport,
+				  transport->cwnd,
+				  transport->ssthresh,
+				  transport->flight_size,
+				  transport->partial_bytes_acked);
 	}
 
 	/* RFC 2960 6.1  Transmission of DATA Chunks
@@ -552,7 +553,3 @@
 finish:
 	return retval;
 }
-
-
-
-
diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/outqueue.c	Fri Sep 27 14:51:03 2002
@@ -196,23 +196,14 @@
 	return error;
 }
 
-/* Mark all the eligible packets on a transport for retransmission and force
- * one packet out.
- */
-void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
-		     __u8 fast_retransmit)
+/* Mark all the eligible packets on a transport for retransmission.  */
+void sctp_retransmit_mark(sctp_outqueue_t *q, sctp_transport_t *transport,
+			  __u8 fast_retransmit)
 {
 	struct list_head *lchunk;
 	sctp_chunk_t *chunk;
-	int error = 0;
 	struct list_head tlist;
 
-	if (fast_retransmit) {
-		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
-	} else {
-		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
-	}
-
 	INIT_LIST_HEAD(&tlist);
 
 	while (!list_empty(&transport->transmitted)) {
@@ -224,7 +215,7 @@
 		 * should be added to the retransmit queue.  If we are doing
 		 * retransmission due to a timeout, only the chunks that are
 		 * not yet acked should be added to the retransmit queue.
-		 */  
+		 */
 		if ((fast_retransmit && !chunk->fast_retransmit) ||
 		    (!fast_retransmit && chunk->tsn_gap_acked)) {
 			list_add_tail(lchunk, &tlist);
@@ -276,7 +267,26 @@
 			  transport->flight_size,
 			  transport->partial_bytes_acked);
 
+}
+
+/* Mark all the eligible packets on a transport for retransmission and force 
+ * one packet out.
+ */
+void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport, 
+		     __u8 fast_retransmit)
+{
+	int error = 0;
+
+	if (fast_retransmit) {
+		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
+	} else {
+		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
+	}
+
+	sctp_retransmit_mark(q, transport, fast_retransmit);
+
 	error = sctp_flush_outqueue(q, /* rtx_timeout */ 1);
+
 	if (error)
 		q->asoc->base.sk->err = -error;
 }
@@ -327,7 +337,7 @@
 		/* If a chunk has been tried for more than SCTP_DEF_MAX_SEND
 		 * times, discard it, and check the empty flag of the outqueue.
 		 *
-		 *		--xguo
+		 * --xguo
 		 */
 		if (chunk->snd_count > SCTP_DEF_MAX_SEND) {
 			sctp_free_chunk(chunk);
@@ -339,7 +349,7 @@
 
 		switch (status) {
 		case SCTP_XMIT_PMTU_FULL:
-			/* Send this packet. */
+			/* Send this packet.  */
 			if ((error = (*q->force_output)(pkt)) == 0)
 				*start_timer = 1;
 
@@ -370,8 +380,7 @@
 			/* The append was successful, so add this chunk to
 			 * the transmitted list.
 			 */
-			list_add_tail(lchunk,
-				      &transport->transmitted);
+			list_add_tail(lchunk, &transport->transmitted);
 			*start_timer = 1;
 			q->empty = 0;
 
@@ -389,8 +398,7 @@
  * chunk that is currently in the process of fragmentation.
  */
 void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos,
-		    sctp_packet_t *packet,
-		    sctp_chunk_t *frag, __u32 tsn)
+		    sctp_packet_t *packet, sctp_chunk_t *frag, __u32 tsn)
 {
 	sctp_transport_t *transport = packet->transport;
 	struct sk_buff_head *queue = &q->out;
@@ -407,7 +415,7 @@
 	if (!skb_queue_empty(queue)) {
 		SCTP_DEBUG_PRINTK("sctp_xmit_frag: q not empty. "
 				  "adding 0x%x to outqueue\n",
-				   ntohl(frag->subh.data_hdr->tsn));
+				  ntohl(frag->subh.data_hdr->tsn));
 		if (pos) {
 			skb_insert(pos, (struct sk_buff *) frag);
 		} else {
@@ -499,7 +507,8 @@
  * fragments.  It returns the first fragment with the frag_list field holding
  * the remaining fragments.
  */
-sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len)
+sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, 
+				  size_t max_frag_data_len)
 {
 	sctp_association_t *asoc = chunk->asoc;
 	void *data_ptr = chunk->subh.data_hdr;
@@ -519,7 +528,7 @@
 
 	/* Make the first fragment. */
 	first_frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len,
-					data_ptr, SCTP_DATA_FIRST_FRAG, ssn); 
+					data_ptr, SCTP_DATA_FIRST_FRAG, ssn);
 
 	if (!first_frag)
 		goto err;
@@ -533,11 +542,14 @@
 	/* Make the middle fragments. */
 	while (chunk_data_len > max_frag_data_len) {
 		frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len,
-					  data_ptr, SCTP_DATA_MIDDLE_FRAG, ssn);
+					  data_ptr, SCTP_DATA_MIDDLE_FRAG, 
+					  ssn);
 		if (!frag)
 			goto err;
 
-		/* Add the middle fragment to the first fragment's frag_list.  */
+		/* Add the middle fragment to the first fragment's 
+		 * frag_list.
+		 */
 		list_add_tail(&frag->frag_list, frag_list);
 
 		chunk_data_len -= max_frag_data_len;
@@ -641,7 +653,7 @@
 			 * chunk->transport, even it's inactive.
 			 */
 			if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT)
-				new_transport = asoc->peer.active_path;     
+				new_transport = asoc->peer.active_path;
 		}
 
 		/* Are we switching transports?
@@ -674,7 +686,7 @@
 			(void) (*q->build_output)(&singleton, chunk);
 			error = (*q->force_output)(&singleton);
 			if (error < 0)
-				return(error);
+				return error;
 			break;
 
 		case SCTP_CID_ABORT:
@@ -698,17 +710,17 @@
 
 		default:
 			/* We built a chunk with an illegal type! */
-			BUG();			
+			BUG();
 		};
 	}
 
 	/* Is it OK to send data chunks?  */
 	switch (asoc->state) {
 	case SCTP_STATE_COOKIE_ECHOED:
-		/* Only allow bundling, if this packet has a COOKIE-ECHO
+		/* Only allow bundling when this packet has a COOKIE-ECHO
 		 * chunk.
 		 */
-		if (packet && !packet->has_cookie_echo)
+		if (!packet || !packet->has_cookie_echo)
 			break;
 
 		/* fallthru */
@@ -748,6 +760,12 @@
 
 			if (start_timer)
 				sctp_transport_reset_timers(transport);
+
+			/* This can happen on COOKIE-ECHO resend.  Only
+			 * one chunk can get bundled with a COOKIE-ECHO.
+			 */
+			if (packet->has_cookie_echo)
+				goto sctp_flush_out;
 		}
 
 		/* Finally, transmit new packets.  */
@@ -809,12 +827,11 @@
 					  : "Illegal Chunk");
 
 			SCTP_DEBUG_PRINTK("TX TSN 0x%x skb->head "
-					  "%p skb->users %d.\n",
-					  ntohl(chunk->subh.data_hdr->tsn),
-					  chunk->skb ?chunk->skb->head : 0,
-					  chunk->skb ?
-					  atomic_read(&chunk->skb->users) :
-					  -1);
+					"%p skb->users %d.\n",
+					ntohl(chunk->subh.data_hdr->tsn),
+					chunk->skb ?chunk->skb->head : 0,
+					chunk->skb ?
+					atomic_read(&chunk->skb->users) : -1);
 
 			/* Add the chunk to the packet.  */
 			status = (*q->build_output)(packet, chunk);
@@ -826,8 +843,9 @@
 				 * the chunk back on the output queue.
 				 */
 				SCTP_DEBUG_PRINTK("sctp_flush_outqueue: could"
-				   "not transmit TSN: 0x%x, status: %d\n",
-				   ntohl(chunk->subh.data_hdr->tsn), status);
+					"not transmit TSN: 0x%x, status: %d\n",
+					ntohl(chunk->subh.data_hdr->tsn), 
+					status);
 				skb_queue_head(queue, (struct sk_buff *)chunk);
 				goto sctp_flush_out;
 				break;
@@ -836,7 +854,7 @@
 				sctp_chunk_t *frag;
 
 				frag = sctp_fragment_chunk(chunk,
-					  packet->transport->asoc->frag_point);
+					packet->transport->asoc->frag_point);
 				if (!frag) {
 					/* We could not fragment due to out of
 					 * memory condition. Free the original
@@ -857,7 +875,7 @@
 
 			default:
 				BUG();
-			};
+			}
 
 			/* BUG: We assume that the (*q->force_output())
 			 * call below will succeed all the time and add the
@@ -875,13 +893,19 @@
 			sctp_transport_reset_timers(transport);
 
 			q->empty = 0;
+
+			/* Only let one DATA chunk get bundled with a
+			 * COOKIE-ECHO chunk.
+			 */
+			if (packet->has_cookie_echo)
+				goto sctp_flush_out;
 		}
 		break;
 
 	default:
 		/* Do nothing.  */
-		break;
-	};
+		break;		
+	}
 
 sctp_flush_out:
 	/* Before returning, examine all the transports touched in
@@ -901,7 +925,7 @@
 		if (packet->size != SCTP_IP_OVERHEAD)
 			error = (*q->force_output)(packet);
 	}
-
+	
 	return error;
 }
 
@@ -986,8 +1010,7 @@
 	ctsn = q->asoc->ctsn_ack_point;
 
 	SCTP_DEBUG_PRINTK("%s: sack Cumulative TSN Ack is 0x%x.\n",
-			  __FUNCTION__,
-			  sack_ctsn);
+			  __FUNCTION__, sack_ctsn);
 	SCTP_DEBUG_PRINTK("%s: Cumulative TSN Ack of association "
 			  "%p is 0x%x.\n", __FUNCTION__, q->asoc, ctsn);
 
@@ -1114,8 +1137,9 @@
 				 * 6.3.1 C5) Karn's algorithm: RTT measurements
 				 * MUST NOT be made using packets that were
 				 * retransmitted (and thus for which it is
-				 * ambiguous whether the reply was for the first
-				 * instance of the packet or a later instance).
+				 * ambiguous whether the reply was for the 
+				 * first instance of the packet or a later 
+				 * instance).
 				 */
 			   	if ((!tchunk->tsn_gap_acked) &&
 				    (1 == tchunk->num_times_sent) &&
@@ -1150,15 +1174,15 @@
 				 * 'Stray DATA chunk(s)' record the highest TSN
 				 * reported as newly acknowledged, call this
 				 * value 'HighestTSNinSack'. A newly
-				 * acknowledged DATA chunk is one not previously
-				 * acknowledged in a SACK.
+				 * acknowledged DATA chunk is one not 
+				 * previously acknowledged in a SACK.
 				 *
 				 * When the SCTP sender of data receives a SACK
 				 * chunk that acknowledges, for the first time,
 				 * the receipt of a DATA chunk, all the still
-				 * unacknowledged DATA chunks whose TSN is older
-				 * than that newly acknowledged DATA chunk, are
-				 * qualified as 'Stray DATA chunks'.
+				 * unacknowledged DATA chunks whose TSN is 
+				 * older than that newly acknowledged DATA 
+				 * chunk, are qualified as 'Stray DATA chunks'.
 				 */
 				if (!tchunk->tsn_gap_acked) {
 					tchunk->tsn_gap_acked = 1;
@@ -1217,8 +1241,8 @@
 
 		} else {
 			if (tchunk->tsn_gap_acked) {
-				SCTP_DEBUG_PRINTK("%s: Receiver reneged on data "
-						  "TSN: 0x%x\n",
+				SCTP_DEBUG_PRINTK("%s: Receiver reneged on "
+						  "data TSN: 0x%x\n",
 						  __FUNCTION__,
 						  tsn);
 				tchunk->tsn_gap_acked = 0;
@@ -1227,10 +1251,11 @@
 
 				/* RFC 2960 6.3.2 Retransmission Timer Rules
 				 *
-				 * R4) Whenever a SACK is received missing a TSN
-				 * that was previously acknowledged via a Gap Ack
-				 * Block, start T3-rtx for the destination
-				 * address to which the DATA chunk was originally
+				 * R4) Whenever a SACK is received missing a 
+				 * TSN that was previously acknowledged via a 
+				 * Gap Ack Block, start T3-rtx for the 
+				 * destination address to which the DATA 
+				 * chunk was originally
 				 * transmitted if it is not already running.
 				 */
 				restart_timer = 1;
@@ -1306,10 +1331,11 @@
 			 * active if it is not so marked.
 			 */
 			if (!transport->state.active) {
-				sctp_assoc_control_transport(transport->asoc,
-							     transport,
-							     SCTP_TRANSPORT_UP,
-							     SCTP_RECEIVED_SACK);
+				sctp_assoc_control_transport(
+					transport->asoc,
+					transport,
+					SCTP_TRANSPORT_UP,
+					SCTP_RECEIVED_SACK);
 			}
 
 			sctp_transport_raise_cwnd(transport, sack_ctsn,
@@ -1398,8 +1424,7 @@
 
 		SCTP_DEBUG_PRINTK("%s: transport: %p, cwnd: %d, "
 				  "ssthresh: %d, flight_size: %d, pba: %d\n",
-				  __FUNCTION__,
-			  	  transport, transport->cwnd,
+				  __FUNCTION__, transport, transport->cwnd,
 			  	  transport->ssthresh, transport->flight_size,
 				  transport->partial_bytes_acked);
 	}
diff -Nru a/net/sctp/primitive.c b/net/sctp/primitive.c
--- a/net/sctp/primitive.c	Fri Sep 27 14:51:05 2002
+++ b/net/sctp/primitive.c	Fri Sep 27 14:51:05 2002
@@ -1,44 +1,44 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These functions implement the SCTP primitive functions from Section 10.
- * 
+ *
  * Note that the descriptions from the specification are USER level
  * functions--this file is the functions which populate the struct proto
  * for SCTP which is the BOTTOM of the sockets interface.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Narasimha Budihal     <narasimha@refcode.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c	Fri Sep 27 14:51:04 2002
+++ b/net/sctp/protocol.c	Fri Sep 27 14:51:04 2002
@@ -66,6 +66,9 @@
  */
 static struct socket *sctp_ctl_socket;
 
+static sctp_pf_t *sctp_pf_inet6_specific;
+static sctp_pf_t *sctp_pf_inet_specific;
+
 extern struct net_proto_family inet_family_ops;
 
 /* Return the address of the control sock. */
@@ -91,7 +94,7 @@
 void sctp_proc_exit(void)
 {
 	if (proc_net_sctp) {
-		proc_net_sctp= NULL;
+		proc_net_sctp = NULL;
 		remove_proc_entry("net/sctp", 0);
 	}
 }
@@ -135,7 +138,8 @@
  * the protocol structure.
  * FIXME: Make this an address family function.
  */
-static inline void sctp_v6_get_local_addr_list(sctp_protocol_t *proto, struct net_device *dev)
+static inline void sctp_v6_get_local_addr_list(sctp_protocol_t *proto, 
+					       struct net_device *dev)
 {
 #ifdef SCTP_V6_SUPPORT
 	/* FIXME: The testframe doesn't support this function. */
@@ -227,8 +231,8 @@
 	long flags __attribute__ ((unused));
 
 	sctp_spin_lock_irqsave(&proto->local_addr_lock, flags);
- 	list_for_each(pos, &proto->local_addr_list) {
- 		addr = list_entry(pos, struct sockaddr_storage_list, list);
+	list_for_each(pos, &proto->local_addr_list) {
+		addr = list_entry(pos, struct sockaddr_storage_list, list);
 		if (sctp_in_scope(&addr->a, scope)) {
 			/* Now that the address is in scope, check to see if
 			 * the address type is really supported by the local
@@ -239,8 +243,7 @@
 			    (((AF_INET6 == addr->a.sa.sa_family) &&
 			      (copy_flags & SCTP_ADDR6_ALLOWED) &&
 			      (copy_flags & SCTP_ADDR6_PEERSUPP)))) {
-				error = sctp_add_bind_addr(bp,
-							   &addr->a,
+				error = sctp_add_bind_addr(bp, &addr->a,
 							   priority);
 				if (error)
 					goto end_copy;
@@ -286,7 +289,8 @@
 /* Event handler for inet device events.
  * Basically, whenever there is an event, we re-build our local address list.
  */
-static int sctp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+static int sctp_netdev_event(struct notifier_block *this, unsigned long event,
+			     void *ptr)
 {
 	long flags __attribute__ ((unused));
 
@@ -312,8 +316,8 @@
 	err = sock_create(family, SOCK_SEQPACKET, IPPROTO_SCTP,
 			  &sctp_ctl_socket);
 	if (err < 0) {
-		printk(KERN_ERR 
-			"SCTP: Failed to create the SCTP control socket.\n");
+		printk(KERN_ERR
+		       "SCTP: Failed to create the SCTP control socket.\n");
 		return err;
 	}
 	sctp_ctl_socket->sk->allocation = GFP_ATOMIC;
@@ -347,6 +351,52 @@
 	return retval;
 }
 
+/* Common code to initialize a AF_INET msg_name. */
+static void sctp_inet_msgname(char *msgname, int *addr_len)
+{
+	struct sockaddr_in *sin;
+	
+	sin = (struct sockaddr_in *)msgname;
+	*addr_len = sizeof(struct sockaddr_in);
+	sin->sin_family = AF_INET;
+	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+}
+ 
+/* Copy the primary address of the peer primary address as the msg_name. */
+static void sctp_inet_event_msgname(sctp_ulpevent_t *event, char *msgname, int *addr_len)
+{
+	struct sockaddr_in *sin, *sinfrom;
+
+	if (msgname) {
+		sctp_inet_msgname(msgname, addr_len);
+		sin = (struct sockaddr_in *)msgname;
+		sinfrom = &event->asoc->peer.primary_addr.v4;
+		sin->sin_port = htons(event->asoc->peer.port);
+		sin->sin_addr.s_addr = sinfrom->sin_addr.s_addr;
+	}
+} 
+
+/* Initialize and copy out a msgname from an inbound skb. */
+static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *addr_len)
+{
+	struct sctphdr *sh; 
+	struct sockaddr_in *sin;
+
+	if (msgname) {
+		sctp_inet_msgname(msgname, addr_len);
+		sin = (struct sockaddr_in *)msgname;
+		sh = (struct sctphdr *)skb->h.raw;
+		sin->sin_port = sh->source;
+		sin->sin_addr.s_addr = skb->nh.iph->saddr;
+	}
+} 
+
+static sctp_pf_t sctp_pf_inet = {
+	.event_msgname = sctp_inet_event_msgname,
+	.skb_msgname = sctp_inet_skb_msgname,
+};
+
+
 /* Registration for netdev events.  */
 struct notifier_block sctp_netdev_notifier = {
 	.notifier_call = sctp_netdev_event,
@@ -403,6 +453,34 @@
 	.sa_family      = AF_INET,
 };
 
+sctp_pf_t *sctp_get_pf_specific(int family) {
+
+	switch (family) {
+	case PF_INET:
+		return sctp_pf_inet_specific;
+	case PF_INET6:
+		return sctp_pf_inet6_specific;
+	default:
+		return NULL;
+	}
+}
+
+/* Set the PF specific function table.  */
+void sctp_set_pf_specific(int family, sctp_pf_t *pf)
+{
+	switch (family) {
+	case PF_INET:
+		sctp_pf_inet_specific = pf;
+		break;
+	case PF_INET6:
+		sctp_pf_inet6_specific = pf;
+		break;
+	default:
+		BUG();
+		break;
+	}
+}
+
 /* Initialize the universe into something sensible.  */
 int sctp_init(void)
 {
@@ -421,9 +499,11 @@
 	/* Initialize object count debugging.  */
 	sctp_dbg_objcnt_init();
 
+	/* Initialize the SCTP specific PF functions. */
+	sctp_set_pf_specific(PF_INET, &sctp_pf_inet);
 	/*
-         * 14. Suggested SCTP Protocol Parameter Values
-         */
+	 * 14. Suggested SCTP Protocol Parameter Values
+	 */
 	/* The following protocol parameters are RECOMMENDED:  */
 	/* RTO.Initial              - 3  seconds */
 	sctp_proto.rto_initial		= SCTP_RTO_INITIAL;
@@ -468,7 +548,7 @@
 	sctp_proto.assoc_hashbucket = (sctp_hashbucket_t *)
 		kmalloc(4096 * sizeof(sctp_hashbucket_t), GFP_KERNEL);
 	if (!sctp_proto.assoc_hashbucket) {
-		printk (KERN_ERR "SCTP: Failed association hash alloc.\n");
+		printk(KERN_ERR "SCTP: Failed association hash alloc.\n");
 		status = -ENOMEM;
 		goto err_ahash_alloc;
 	}
@@ -482,7 +562,7 @@
 	sctp_proto.ep_hashbucket = (sctp_hashbucket_t *)
 		kmalloc(64 * sizeof(sctp_hashbucket_t), GFP_KERNEL);
 	if (!sctp_proto.ep_hashbucket) {
-		printk (KERN_ERR "SCTP: Failed endpoint_hash alloc.\n");
+		printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n");
 		status = -ENOMEM;
 		goto err_ehash_alloc;
 	}
@@ -497,7 +577,7 @@
 	sctp_proto.port_hashtable = (sctp_bind_hashbucket_t *)
 		kmalloc(4096 * sizeof(sctp_bind_hashbucket_t), GFP_KERNEL);
 	if (!sctp_proto.port_hashtable) {
-		printk (KERN_ERR "SCTP: Failed bind hash alloc.");
+		printk(KERN_ERR "SCTP: Failed bind hash alloc.");
 		status = -ENOMEM;
 		goto err_bhash_alloc;
 	}
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/sm_make_chunk.c	Fri Sep 27 14:51:03 2002
@@ -9,36 +9,36 @@
  * This file includes part of the implementation of the add-IP extension,
  * based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
  * for the SCTP kernel reference Implementation.
- * 
+ *
  * These functions work with the state functions in sctp_sm_statefuns.c
  * to implement the state operations.  These functions implement the
  * steps which require modifying existing data structures.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
  *    C. Robin              <chris@hundredacre.ac.uk>
@@ -73,7 +73,7 @@
  * support any address type.
  */
 static const sctp_supported_addrs_param_t sat_param = {
-	{           
+	{
 		SCTP_PARAM_SUPPORTED_ADDRESS_TYPES,
 		__constant_htons(SCTP_SAT_LEN),
 	},
@@ -204,7 +204,7 @@
 	 * PLEASE DO NOT FIXME [This version does not support Host Name.]
 	 */
 
-	retval = sctp_make_chunk(asoc, SCTP_CID_INIT, 0, chunksize); 
+	retval = sctp_make_chunk(asoc, SCTP_CID_INIT, 0, chunksize);
 	if (!retval)
 		goto nodata;
 
@@ -1204,7 +1204,7 @@
 
 	case 6:
 		asoc->c.peer_addr.v6.sin6_family     = AF_INET6;
-		asoc->c.peer_addr.v6.sin6_port 
+		asoc->c.peer_addr.v6.sin6_port
 			= ntohs(chunk->sctp_hdr->source);
 		asoc->c.peer_addr.v6.sin6_flowinfo = 0; /* BUG BUG BUG */
 		asoc->c.peer_addr.v6.sin6_addr = chunk->skb->nh.ipv6h->saddr;
@@ -1245,7 +1245,7 @@
 	 * functions simpler to write.
 	 */
 	if (bodysize % SCTP_COOKIE_MULTIPLE)
-		bodysize += SCTP_COOKIE_MULTIPLE 
+		bodysize += SCTP_COOKIE_MULTIPLE
 			- (bodysize % SCTP_COOKIE_MULTIPLE);
 	*cookie_len = headersize + bodysize;
 
@@ -1418,6 +1418,7 @@
 	__u8 *end;
 	sctp_transport_t *transport;
 	struct list_head *pos, *temp;
+	char *cookie;
 
 	/* We must include the address that the INIT packet came from.
 	 * This is the only address that matters for an INIT packet.
@@ -1437,7 +1438,7 @@
 	for (param.v = peer_init->init_hdr.params;
 	     param.v < end;
 	     param.v += WORD_ROUND(ntohs(param.p->length))) {
-		if (!sctp_process_param(asoc, param, peer_addr, cid, 
+		if (!sctp_process_param(asoc, param, peer_addr, cid,
 					priority))
                         goto clean_up;
 	}
@@ -1461,7 +1462,7 @@
 	 */
 	if (asoc->c.sinit_num_ostreams  >
 	    ntohs(peer_init->init_hdr.num_inbound_streams)) {
-		asoc->c.sinit_num_ostreams = 
+		asoc->c.sinit_num_ostreams =
 			ntohs(peer_init->init_hdr.num_inbound_streams);
 	}
 
@@ -1471,6 +1472,15 @@
 	/* Peer Rwnd   : Current calculated value of the peer's rwnd.  */
 	asoc->peer.rwnd = asoc->peer.i.a_rwnd;
 
+	/* Copy cookie in case we need to resend COOKIE-ECHO. */
+	cookie = asoc->peer.cookie;
+	if (cookie) {
+		asoc->peer.cookie = kmalloc(asoc->peer.cookie_len, priority);
+		if (!asoc->peer.cookie)
+			goto clean_up;
+		memcpy(asoc->peer.cookie, cookie, asoc->peer.cookie_len);
+	}
+
 	/* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily
 	 * high (for example, implementations MAY use the size of the receiver
 	 * advertised window).
@@ -1560,7 +1570,7 @@
 		break;
 
 	case SCTP_PARAM_HOST_NAME_ADDRESS:
-		SCTP_DEBUG_PRINTK("unimplmented SCTP_HOST_NAME_ADDRESS\n");
+		SCTP_DEBUG_PRINTK("unimplemented SCTP_HOST_NAME_ADDRESS\n");
 		break;
 
 	case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES:
@@ -1595,13 +1605,12 @@
 
 	case SCTP_PARAM_STATE_COOKIE:
 		asoc->peer.cookie_len =
-			ntohs(param.p->length) -
-			sizeof(sctp_paramhdr_t);
+			ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
 		asoc->peer.cookie = param.cookie->body;
 		break;
 
 	case SCTP_PARAM_HEATBEAT_INFO:
-		SCTP_DEBUG_PRINTK("unimplmented "
+		SCTP_DEBUG_PRINTK("unimplemented "
 				  "SCTP_PARAM_HEATBEAT_INFO\n");
 		break;
 
diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c	Fri Sep 27 14:51:04 2002
+++ b/net/sctp/sm_sideeffect.c	Fri Sep 27 14:51:04 2002
@@ -1,39 +1,39 @@
-/* SCTP kernel reference Implementation 
+/* SCTP kernel reference Implementation
  * Copyright (c) 1999 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001-2002 International Business Machines Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These functions work with the state functions in sctp_sm_statefuns.c
  * to implement that state operations.  These functions implement the
  * steps which require modifying existing data structures.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
  *    Jon Grimm             <jgrimm@austin.ibm.com>
@@ -119,7 +119,7 @@
 	       int priority)
 {
 	sctp_cmd_seq_t commands;
-	sctp_sm_table_entry_t *state_fn;        
+	sctp_sm_table_entry_t *state_fn;
 	sctp_disposition_t status;
 	int error = 0;
 	typedef const char *(printfn_t)(sctp_subtype_t);
@@ -253,6 +253,7 @@
 	sctp_chunk_t *new_obj;
 	sctp_chunk_t *chunk;
 	sctp_packet_t *packet;
+	struct list_head *pos;
 	struct timer_list *timer;
 	unsigned long timeout;
 	sctp_transport_t *t;
@@ -336,9 +337,8 @@
 
 		case SCTP_CMD_PEER_INIT:
 			/* Process a unified INIT from the peer.  */
-			sctp_cmd_process_init(commands,
-					      asoc, chunk, command->obj.ptr,
-					      priority);
+			sctp_cmd_process_init(commands, asoc, chunk,
+					      command->obj.ptr, priority);
 			break;
 
 		case SCTP_CMD_GEN_COOKIE_ECHO:
@@ -462,6 +462,7 @@
 			break;
 
 		case SCTP_CMD_INIT_RESTART:
+
 			/* Do the needed accounting and updates
 			 * associated with restarting an initialization
 			 * timer.
@@ -474,6 +475,15 @@
 					asoc->max_init_timeo;
 			}
 
+			/* If we've sent any data bundled with
+			 * COOKIE-ECHO we need to resend.
+			 */
+			list_for_each(pos, &asoc->peer.transport_addr_list) {
+				t = list_entry(pos, sctp_transport_t,
+					       transports);
+				sctp_retransmit_mark(&asoc->outqueue, t, 0);
+			}
+
 			sctp_add_cmd_sf(commands,
 					SCTP_CMD_TIMER_RESTART,
 					SCTP_TO(command->obj.to));
@@ -602,7 +612,7 @@
 {
 	sctp_chunk_t *repl;
 	sctp_transport_t *transport;
-			
+
 	/* Our previously transmitted packet ran into some congestion
 	 * so we should take action by reducing cwnd and ssthresh
 	 * and then ACK our peer that we we've done so by
@@ -716,7 +726,7 @@
 		error = sctp_push_outqueue(&asoc->outqueue, sack);
 
 		/* Stop the SACK timer.  */
-		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 
+		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 	}
 
@@ -785,7 +795,7 @@
 		if (!mod_timer(&transport->T3_rtx_timer, jiffies + (HZ/20)))
 			sctp_transport_hold(transport);
 		goto out_unlock;
-	} 
+	}
 
 	/* Is this transport really dead and just waiting around for
 	 * the timer to let go of the reference?
@@ -867,6 +877,14 @@
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN);
 }
 
+void sctp_generate_t5_shutdown_guard_event(unsigned long data)
+{
+        sctp_association_t *asoc = (sctp_association_t *)data;
+        sctp_generate_timeout_event(asoc,
+				    SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD);
+
+} /* sctp_generate_t5_shutdown_guard_event() */
+
 void sctp_generate_autoclose_event(unsigned long data)
 {
 	sctp_association_t *asoc = (sctp_association_t *) data;
@@ -890,7 +908,7 @@
 		if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20)))
 			sctp_transport_hold(transport);
 		goto out_unlock;
-	} 
+	}
 
 	/* Is this structure just waiting around for us to actually
 	 * get destroyed?
@@ -932,6 +950,7 @@
 	sctp_generate_t2_shutdown_event,
 	NULL,
 	NULL,
+	sctp_generate_t5_shutdown_guard_event,
 	sctp_generate_heartbeat_event,
 	sctp_generate_sack_event,
 	sctp_generate_autoclose_event,
@@ -1022,6 +1041,9 @@
 	if (event)
 		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
 				SCTP_ULPEVENT(event));
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+			SCTP_STATE(SCTP_STATE_CLOSED));
 
 	/* FIXME:  We need to handle data that could not be sent or was not
 	 * acked, if the user has enabled SEND_FAILED notifications.
diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/sm_statefuns.c	Fri Sep 27 14:51:03 2002
@@ -5,36 +5,36 @@
  * Copyright (c) 2002      Nokia Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * This is part of the SCTP Linux Kernel Reference Implementation.
  *
  * These are the state functions for the state machine.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
  *    Mathew Kotowsky       <kotowsky@sctp.org>
@@ -149,6 +149,9 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
 
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
+
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
 
@@ -161,35 +164,6 @@
 }
 
 /*
- * Discard the whole packet.
- *
- * Section: 8.4 2)
- *
- * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
- *    silently discard the OOTB packet and take no further action.
- *    Otherwise,
- *
- * Verification Tag: No verification necessary
- *
- * Inputs
- * (endpoint, asoc, chunk)
- *
- * Outputs
- * (asoc, reply_msg, msg_up, timers, counters)
- *
- * The return value is the disposition of the chunk.
- */
-sctp_disposition_t sctp_sf_pdiscard(const sctp_endpoint_t *ep,
-				    const sctp_association_t *asoc,
-				    const sctp_subtype_t type,
-				    void *arg,
-				    sctp_cmd_seq_t *commands)
-{
-	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
-	return SCTP_DISPOSITION_CONSUME;
-}
-
-/*
  * Respond to a normal INIT chunk.
  * We are the side that is being asked for an association.
  *
@@ -263,7 +237,7 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 
 	/*
-         * Note: After sending out INIT ACK with the State Cookie parameter,
+	 * Note:  After sending out INIT ACK with the State Cookie parameter,
 	 * "Z" MUST NOT allocate any resources, nor keep any states for the
 	 * new association.  Otherwise, "Z" will be vulnerable to resource
 	 * attacks.
@@ -324,7 +298,7 @@
 		return SCTP_DISPOSITION_VIOLATION;
 
 	/* Grab the INIT header.  */
-	chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;	
+	chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
 	init_tag = ntohl(chunk->subh.init_hdr->init_tag);
 
@@ -338,20 +312,17 @@
 		if (!reply)
 			goto nomem;
 
-		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
-				SCTP_CHUNK(reply));
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
 		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 				SCTP_STATE(SCTP_STATE_CLOSED));
-		sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
-				SCTP_NULL());
+		sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
 		return SCTP_DISPOSITION_DELETE_TCB;
 	}
 
 	/* Tag the variable length paramters.  Note that we never
 	 * convert the parameters in an INIT chunk.
 	 */
-	chunk->param_hdr.v =
-		skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
+	chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
 
 	initchunk = (sctp_init_chunk_t *) chunk->chunk_hdr;
 
@@ -428,7 +399,7 @@
 	 * control endpoint, responding with an ABORT.
 	 */
 	if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
-		return sctp_sf_ootb(ep, asoc, type, arg, commands); 
+		return sctp_sf_ootb(ep, asoc, type, arg, commands);
 
 	/* "Decode" the chunk.  We have no optional parameters so we
 	 * are in good shape.
@@ -460,8 +431,7 @@
 
 		case -SCTP_IERROR_BAD_SIG:
 		default:
-			return sctp_sf_pdiscard(ep, asoc, type,
-						arg, commands);
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 		};
 	}
 
@@ -560,7 +530,7 @@
 			SCTP_STATE(SCTP_STATE_ESTABLISHED));
 	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
 	if (asoc->autoclose)
-		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, 
+		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
 				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
 	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
 
@@ -625,8 +595,7 @@
 	if (!reply)
 		goto nomem;
 
-	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
-			SCTP_CHUNK(reply));
+	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
 
 	/* Set transport error counter and association error counter
 	 * when sending heartbeat.
@@ -751,7 +720,7 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
 	hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
-	from_addr = hbinfo->daddr;		
+	from_addr = hbinfo->daddr;
 	link = sctp_assoc_lookup_paddr(asoc, &from_addr);
 
 	/* This should never happen, but lets log it if so.  */
@@ -779,8 +748,7 @@
 	 * sent and mark the destination transport address as active if
 	 * it is not so marked.
 	 */
-	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_ON,
-			SCTP_TRANSPORT(link));
+	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_ON, SCTP_TRANSPORT(link));
 
 	return SCTP_DISPOSITION_CONSUME;
 }
@@ -810,7 +778,7 @@
 		break;
 
 	/* 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
-	 *   COOKIE-WAIT and SHUTDOWN-ACK-SENT
+	 * COOKIE-WAIT and SHUTDOWN-ACK-SENT
 	 */
 	default:
 		new_asoc->c.my_ttag   = asoc->c.my_vtag;
@@ -843,10 +811,10 @@
 	/* In this case, the peer may have restarted.  */
 	if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
 	    (asoc->c.peer_vtag != new_asoc->c.peer_vtag) &&
-	    (asoc->c.my_vtag   == new_asoc->c.my_ttag) &&
+	    (asoc->c.my_vtag == new_asoc->c.my_ttag) &&
 	    (asoc->c.peer_vtag == new_asoc->c.peer_ttag))
 		return 'A';
-	
+
 	/* Collision case D.
 	 * Note: Test case D first, otherwise it may be incorrectly
 	 * identified as second case of B if the value of the Tie_tag is
@@ -875,8 +843,10 @@
 /* Common helper routine for both duplicate and simulataneous INIT
  * chunk handling.
  */
-static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
-	const sctp_association_t *asoc, const sctp_subtype_t type,
+static sctp_disposition_t sctp_sf_do_unexpected_init(
+	const sctp_endpoint_t *ep,
+	const sctp_association_t *asoc, 
+	const sctp_subtype_t type,
 	void *arg, sctp_cmd_seq_t *commands)
 {
 	sctp_chunk_t *chunk = arg;
@@ -894,8 +864,7 @@
 	chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
 	/* Tag the variable length parameters.  */
-	chunk->param_hdr.v =
-		skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
+	chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
 
 	/*
 	 * Other parameters for the endpoint SHOULD be copied from the
@@ -912,10 +881,9 @@
 	 * Verification Tag and Peers Verification tag into a reserved
 	 * place (local tie-tag and per tie-tag) within the state cookie.
 	 */
-	sctp_process_init(new_asoc, chunk->chunk_hdr->type,
-			  sctp_source(chunk),
-			  (sctp_init_chunk_t *)chunk->chunk_hdr,
-			  GFP_ATOMIC);
+	sctp_process_init(new_asoc, chunk->chunk_hdr->type, sctp_source(chunk),
+			  (sctp_init_chunk_t *)chunk->chunk_hdr, GFP_ATOMIC);
+
 	sctp_tietags_populate(new_asoc, asoc);
 
 	/* B) "Z" shall respond immediately with an INIT ACK chunk.  */
@@ -927,7 +895,7 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 
 	/*
-         * Note: After sending out INIT ACK with the State Cookie parameter,
+	 * Note: After sending out INIT ACK with the State Cookie parameter,
 	 * "Z" MUST NOT allocate any resources for this new association.
 	 * Otherwise, "Z" will be vulnerable to resource attacks.
 	 */
@@ -1072,7 +1040,7 @@
 	list_for_each(pos, &new_asoc->peer.transport_addr_list) {
 		new_addr = list_entry(pos, sctp_transport_t, transports);
 		found = 1;
-		list_for_each_safe(pos2, temp,
+		list_for_each_safe(pos2, temp, 
 				   &asoc->peer.transport_addr_list) {
 			addr = list_entry(pos2, sctp_transport_t, transports);
 			if (!sctp_cmp_addr_exact(&new_addr->ipaddr,
@@ -1256,7 +1224,7 @@
 	if (SCTP_STATE_ESTABLISHED != asoc->state) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 				SCTP_STATE(SCTP_STATE_ESTABLISHED));
-		sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, 
+		sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,
 				SCTP_NULL());
 
 		/* RFC 2960 5.1 Normal Establishment of an Association
@@ -1323,10 +1291,9 @@
 	/* "Decode" the chunk.  We have no optional parameters so we
 	 * are in good shape.
 	 */
-        chunk->subh.cookie_hdr =
-		(sctp_signed_cookie_t *) chunk->skb->data;
-	skb_pull(chunk->skb,
-		 ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
+        chunk->subh.cookie_hdr = (sctp_signed_cookie_t *)chunk->skb->data;
+	skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - 
+		 sizeof(sctp_chunkhdr_t));
 
 	/* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
 	 * of a duplicate COOKIE ECHO match the Verification Tags of the
@@ -1335,25 +1302,24 @@
 	 */
 	new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error);
 
-        /* FIXME:
+	/* FIXME:
 	 * If the re-build failed, what is the proper error path
 	 * from here?
 	 *
 	 * [We should abort the association. --piggy]
 	 */
 	if (!new_asoc) {
-		 /* FIXME: Several errors are possible.  A bad cookie should
-		  * be silently discarded, but think about logging it too.
-		  */
-		 switch (error) {
-		 case -SCTP_IERROR_NOMEM:
-			 goto nomem;
-
-		 case -SCTP_IERROR_BAD_SIG:
-		 default:
-			 return sctp_sf_pdiscard(ep, asoc, type,
-						 arg, commands);
-		 };
+		/* FIXME: Several errors are possible.  A bad cookie should
+		 * be silently discarded, but think about logging it too.
+		 */
+		switch (error) {
+		case -SCTP_IERROR_NOMEM:
+			goto nomem;
+
+		case -SCTP_IERROR_BAD_SIG:
+		default:
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+		};
 	}
 
 	/* Compare the tie_tag in cookie with the verification tag of
@@ -1398,6 +1364,65 @@
 	return SCTP_DISPOSITION_NOMEM;
 }
 
+/*
+ * Process an ABORT.  (SHUTDOWN-PENDING state)
+ *
+ * See sctp_sf_do_9_1_abort().
+ */
+sctp_disposition_t sctp_sf_shutdown_pending_abort(const sctp_endpoint_t *ep,
+					const sctp_association_t *asoc,
+					const sctp_subtype_t type,
+					void *arg,
+					sctp_cmd_seq_t *commands)
+{
+
+	/* Stop the T5-shutdown guard timer.  */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
+
+	return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+}
+
+/*
+ * Process an ABORT.  (SHUTDOWN-SENT state)
+ *
+ * See sctp_sf_do_9_1_abort().
+ */
+sctp_disposition_t sctp_sf_shutdown_sent_abort(const sctp_endpoint_t *ep,
+					       const sctp_association_t *asoc,
+					       const sctp_subtype_t type,
+					       void *arg,
+					       sctp_cmd_seq_t *commands)
+{
+
+	/* Stop the T2-shutdown timer. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
+
+	/* Stop the T5-shutdown guard timer.  */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
+
+	return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+}
+
+/*
+ * Process an ABORT.  (SHUTDOWN-ACK-SENT state)
+ *
+ * See sctp_sf_do_9_1_abort().
+ */
+sctp_disposition_t sctp_sf_shutdown_ack_sent_abort(const sctp_endpoint_t *ep,
+						const sctp_association_t *asoc,
+						const sctp_subtype_t type,
+						void *arg,
+						sctp_cmd_seq_t *commands)
+{
+	/* The same T2 timer, so we should be able to use
+	 * common function with the SHUTDOWN-SENT state.
+	 */
+	return sctp_sf_shutdown_sent_abort(ep, asoc, type, arg, commands);
+}
+
 #if 0
 /*
  * Handle a Stale COOKIE Error
@@ -1442,7 +1467,7 @@
 	__u8 *addrs;
 	int addrs_len;
 	time_t rtt;
-	struct sctpCookiePreserve bht; 
+	struct sctpCookiePreserve bht;
 
 	/* If we have gotten too many failures, give up.  */
 	if (1 + asoc->counters[SctpCounterInits] > asoc->max_init_attempts) {
@@ -1540,11 +1565,8 @@
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	/* Check the verification tag.  */
-	/* BUG: WRITE ME. */
-	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-			SCTP_STATE(SCTP_STATE_CLOSED));
-	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
+	/* ASSOC_FAILED will DELETE_TCB. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
 
 	/* BUG?  This does not look complete... */
 	return SCTP_DISPOSITION_ABORT;
@@ -1561,15 +1583,19 @@
 					     void *arg,
 					     sctp_cmd_seq_t *commands)
 {
+	/* Check the verification tag.  */
+	/* BUG: WRITE ME. */
+
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
 
 	/* CMD_INIT_FAILED will DELETE_TCB. */
-	sctp_add_cmd_sf(commands,SCTP_CMD_INIT_FAILED, SCTP_NULL());
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_NULL());
 
-	return SCTP_DISPOSITION_DELETE_TCB;
+	/* BUG?  This does not look complete... */
+	return SCTP_DISPOSITION_ABORT;
 }
 
 /*
@@ -1585,70 +1611,9 @@
 {
 	/* There is a single T1 timer, so we should be able to use
 	 * common function with the COOKIE-WAIT state.
-	 */        
-	return sctp_sf_cookie_wait_abort(ep, asoc, type, arg, commands);
-}
-
-#if 0
-/*
- * Handle a shutdown timeout or INIT during a shutdown phase.
- *
- * Section: 9.2
- * If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
- * (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
- * transport addresses (either in the IP addresses or in the INIT chunk)
- * that belong to this association, it should discard the INIT chunk and
- * retransmit the SHUTDOWN ACK chunk.
- *...
- * While in SHUTDOWN-SENT state ... If the timer expires, the endpoint
- * must re-send the SHUTDOWN ACK.
- *
- * Verification Tag:  Neither the INIT nor the timeout will have a
- * valid verification tag, so it is safe to ignore.
- *
- * Inputs
- * (endpoint, asoc, chunk)
- *
- * Outputs
- * (asoc, reply_msg, msg_up, timers, counters)
- *
- * The return value is the disposition of the chunk.
- */
-sctp_disposition_t sctp_do_9_2_reshutack(const sctp_endpoint_t *ep,
-					 const sctp_association_t *asoc,
-					 const sctp_subtype_t type,
-					 void *arg,
-					 sctp_cmd_seq_t *commands)
-{
-	sctp_chunk_t *chunk = arg;
-
-	/* If this was a timeout (not an INIT), then do the counter
-	 * work.  We might need to just dump the association.
 	 */
-	if (!chunk) {
-		if (1 + asoc->counters[SctpCounterRetran] >
-		    asoc->maxRetrans) {
-			sctp_add_cmd(commands, SCTP_CMD_DELETE_TCB,
-				     SCTP_NULL());
-			return SCTP_DISPOSITION_DELETE_TCB;
-		}
-		retval->counters[0] = SCTP_COUNTER_INCR;
-		retval->counters[0] = SctpCounterRetran;
-		retval->counters[1] = 0;
-		retval->counters[1] = 0;
-	}
-
-	reply = sctp_make_shutdown_ack(asoc, chunk);
-	if (!reply)
-		goto nomem;
-
-	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
-	return SCTP_DISPOSITION_CONSUME;
-
-nomem:
-	return SCTP_DISPOSITION_NOMEM;
+	return sctp_sf_cookie_wait_abort(ep, asoc, type, arg, commands);
 }
-#endif /* 0 */
 
 /*
  * sctp_sf_do_9_2_shut
@@ -1694,7 +1659,7 @@
 	sctp_disposition_t disposition;
 
 	/* Convert the elaborate header.  */
-        sdh = (sctp_shutdownhdr_t *) chunk->skb->data;
+	sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
 	chunk->subh.shutdown_hdr = sdh;
 
@@ -1718,9 +1683,8 @@
 	disposition = SCTP_DISPOSITION_CONSUME;
 
 	if (sctp_outqueue_is_empty(&asoc->outqueue)) {
-		disposition =
-			sctp_sf_do_9_2_shutdown_ack(ep, asoc, type,
-						    arg, commands);
+		disposition = sctp_sf_do_9_2_shutdown_ack(ep, asoc, type,
+							  arg, commands);
 	}
 
 	/*  - verify, by checking the Cumulative TSN Ack field of the
@@ -1732,6 +1696,42 @@
 	return disposition;
 }
 
+/* RFC 2960 9.2
+ * If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
+ * (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
+ * transport addresses (either in the IP addresses or in the INIT chunk)
+ * that belong to this association, it should discard the INIT chunk and
+ * retransmit the SHUTDOWN ACK chunk.
+ */
+sctp_disposition_t sctp_sf_do_9_2_reshutack(const sctp_endpoint_t *ep,
+					    const sctp_association_t *asoc,
+					    const sctp_subtype_t type,
+					    void *arg,
+					    sctp_cmd_seq_t *commands)
+{
+	sctp_chunk_t *chunk = (sctp_chunk_t *) arg;
+	sctp_chunk_t *reply;
+
+	reply = sctp_make_shutdown_ack(asoc, chunk);
+	if (NULL == reply)
+		goto nomem;
+
+	/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
+	 * the T2-SHUTDOWN timer.
+	 */
+	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
+
+	/* and restart the T2-shutdown timer. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
+
+	return SCTP_DISPOSITION_CONSUME;
+nomem:
+	return SCTP_DISPOSITION_NOMEM;
+}
+
 /*
  * sctp_sf_do_ecn_cwr
  *
@@ -1780,7 +1780,7 @@
 
 	cwr->lowest_tsn = ntohl(cwr->lowest_tsn);
 
-	/* Does this CWR ack the last sent congestion notification? */ 
+	/* Does this CWR ack the last sent congestion notification? */
 	if (TSN_lte(asoc->last_ecne_tsn, cwr->lowest_tsn)) {
 		/* Stop sending ECNE. */
 		sctp_add_cmd_sf(commands,
@@ -1844,7 +1844,7 @@
 	if (TSN_lt(asoc->last_cwr_tsn, ecne->lowest_tsn)) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_ECN_ECNE,
 				SCTP_U32(ecne->lowest_tsn));
-	}	
+	}
 	return SCTP_DISPOSITION_CONSUME;
 }
 
@@ -1979,13 +1979,11 @@
 		 * processing the rest of the chunks in the packet.
 		 */
 		sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
-		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-				SCTP_STATE(SCTP_STATE_CLOSED));
-		sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
+		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
-	/* We are accepting this DATA chunk. */
+	/* We are accepting this DATA chunk.  */
 
 	/* Record the fact that we have received this TSN.  */
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
@@ -2029,7 +2027,7 @@
 	 *
 	 * The SCTP endpoint MUST always acknowledge the reception of
 	 * each valid DATA chunk.
-	 * 
+	 *
 	 * The guidelines on delayed acknowledgement algorithm
 	 * specified in  Section 4.2 of [RFC2581] SHOULD be followed.
 	 * Specifically, an acknowledgement SHOULD be generated for at
@@ -2142,7 +2140,7 @@
 	 */
 	if (!chunk->ecn_ce_done) {
 		chunk->ecn_ce_done = 1;
-		if (INET_ECN_is_ce(chunk->skb->nh.iph->tos)  &&
+		if (INET_ECN_is_ce(chunk->skb->nh.iph->tos) &&
 		    asoc->peer.ecn_capable) {
 			/* Do real work as sideffect. */
 			sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
@@ -2185,9 +2183,7 @@
 		 * processing the rest of the chunks in the packet.
 		 */
 		sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
-		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-				SCTP_STATE(SCTP_STATE_CLOSED));
-		sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
+		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
@@ -2296,14 +2292,12 @@
 	 */
 	if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
 		SCTP_DEBUG_PRINTK("ctsn %x\n", ctsn);
-		SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n",
-				  asoc->ctsn_ack_point);
+		SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n", asoc->ctsn_ack_point);
 		return SCTP_DISPOSITION_DISCARD;
 	}
 
 	/* Return this SACK for further processing.  */
-	sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
-			SCTP_SACKH(sackh));
+	sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh));
 
 	/* Note: We do the rest of the work on the PROCESS_SACK
 	 * sideeffect.
@@ -2410,7 +2404,8 @@
 	sctp_ulpevent_t *ev;
 
 	while (chunk->chunk_end > chunk->skb->data) {
-		ev = sctp_ulpevent_make_remote_error(asoc,chunk,0, GFP_ATOMIC);
+		ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0, 
+						     GFP_ATOMIC);
 		if (!ev)
 			goto nomem;
 
@@ -2464,6 +2459,9 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
 
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
+
 	/* ...send a SHUTDOWN COMPLETE chunk to its peer, */
 	reply = sctp_make_shutdown_complete(asoc, chunk);
 	if (!reply)
@@ -2524,7 +2522,7 @@
 	if (ootb_shut_ack)
 		sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
 	else
-	  	sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+		sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
 	return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 }
@@ -2616,6 +2614,148 @@
 nomem:
 	return SCTP_DISPOSITION_NOMEM;
 }
+/*
+ * Process an unknown chunk.
+ *
+ * Section: 3.2. Also, 2.1 in the implementor's guide.
+ *
+ * Chunk Types are encoded such that the highest-order two bits specify
+ * the action that must be taken if the processing endpoint does not
+ * recognize the Chunk Type.
+ *
+ * 00 - Stop processing this SCTP packet and discard it, do not process
+ *      any further chunks within it.
+ *
+ * 01 - Stop processing this SCTP packet and discard it, do not process
+ *      any further chunks within it, and report the unrecognized
+ *      chunk in an 'Unrecognized Chunk Type'.
+ *
+ * 10 - Skip this chunk and continue processing.
+ *
+ * 11 - Skip this chunk and continue processing, but report in an ERROR
+ *      Chunk using the 'Unrecognized Chunk Type' cause of error.
+ *
+ * The return value is the disposition of the chunk.
+ */
+sctp_disposition_t sctp_sf_unk_chunk(const sctp_endpoint_t *ep,
+				     const sctp_association_t *asoc,
+				     const sctp_subtype_t type,
+				     void *arg,
+				     sctp_cmd_seq_t *commands)
+{
+	sctp_chunk_t *unk_chunk = arg;
+	sctp_chunk_t *err_chunk;
+	sctp_chunkhdr_t *hdr;
+
+	SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
+
+	/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
+	 * that the value in the Verification Tag field of the
+	 * received SCTP packet matches its own Tag.  If the received
+	 * Verification Tag value does not match the receiver's own
+	 * tag value, the receiver shall silently discard the packet.
+	 */
+	if (ntohl(unk_chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	switch (type.chunk & SCTP_CID_ACTION_MASK) {
+	case SCTP_CID_ACTION_DISCARD:
+		/* Discard the packet.  */
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+		break;
+	case SCTP_CID_ACTION_DISCARD_ERR:
+		/* Discard the packet.  */
+		sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+		/* Generate an ERROR chunk as response. */
+		hdr = unk_chunk->chunk_hdr;
+		err_chunk = sctp_make_op_error(asoc, unk_chunk,
+					       SCTP_ERROR_UNKNOWN_CHUNK, hdr,
+					       WORD_ROUND(ntohs(hdr->length)));
+		if (err_chunk) {
+			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+					SCTP_CHUNK(err_chunk));
+		}
+		return SCTP_DISPOSITION_CONSUME;
+		break;
+	case SCTP_CID_ACTION_SKIP:
+		/* Skip the chunk.  */
+		return SCTP_DISPOSITION_DISCARD;
+		break;
+	case SCTP_CID_ACTION_SKIP_ERR:
+		/* Generate an ERROR chunk as response. */
+		hdr = unk_chunk->chunk_hdr;
+		err_chunk = sctp_make_op_error(asoc, unk_chunk,
+					       SCTP_ERROR_UNKNOWN_CHUNK, hdr,
+					       WORD_ROUND(ntohs(hdr->length)));
+		if (err_chunk) {
+			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+					SCTP_CHUNK(err_chunk));
+		}
+		/* Skip the chunk.  */
+		return SCTP_DISPOSITION_CONSUME;
+		break;
+	default:
+		break;
+	}
+
+	return SCTP_DISPOSITION_DISCARD;
+}
+
+/*
+ * Discard the chunk.
+ *
+ * Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
+ * [Too numerous to mention...]
+ * Verification Tag: No verification needed.
+ * Inputs
+ * (endpoint, asoc, chunk)
+ *
+ * Outputs
+ * (asoc, reply_msg, msg_up, timers, counters)
+ *
+ * The return value is the disposition of the chunk.
+ */
+sctp_disposition_t sctp_sf_discard_chunk(const sctp_endpoint_t *ep,
+					 const sctp_association_t *asoc,
+					 const sctp_subtype_t type,
+					 void *arg,
+					 sctp_cmd_seq_t *commands)
+{
+	SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
+	return SCTP_DISPOSITION_DISCARD;
+}
+
+/*
+ * Discard the whole packet.
+ *
+ * Section: 8.4 2)
+ *
+ * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
+ *    silently discard the OOTB packet and take no further action.
+ *    Otherwise,
+ *
+ * Verification Tag: No verification necessary
+ *
+ * Inputs
+ * (endpoint, asoc, chunk)
+ *
+ * Outputs
+ * (asoc, reply_msg, msg_up, timers, counters)
+ *
+ * The return value is the disposition of the chunk.
+ */
+sctp_disposition_t
+sctp_sf_pdiscard(const sctp_endpoint_t *ep,
+		 const sctp_association_t *asoc,
+		 const sctp_subtype_t type,
+		 void *arg,
+		 sctp_cmd_seq_t *commands)
+{
+	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
+
+	return SCTP_DISPOSITION_CONSUME;
+}
 
 #if 0
 /*
@@ -2821,7 +2961,7 @@
 	 * or else move the association allocation/init into this function.
 	 * The association structure is brand new before calling this
 	 * function, so would not be a sideeffect if the allocation
-	 * moved into this function.  --jgrimm 
+	 * moved into this function.  --jgrimm
 	 */
 	sctp_add_cmd_sf(commands, SCTP_CMD_SET_BIND_ADDR, (sctp_arg_t) bp);
 
@@ -2974,13 +3114,19 @@
 	 * if necessary to fill gaps.
 	 */
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-			SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));        
+			SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
+
+	/* sctpimpguide-05 Section 2.12.2
+	 * The sender of the SHUTDOWN MAY also start an overall guard timer
+	 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
+	 */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
 
 	disposition = SCTP_DISPOSITION_CONSUME;
 	if (sctp_outqueue_is_empty(&asoc->outqueue)) {
-		disposition =
-			sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
-						      arg, commands);
+		disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
+							    arg, commands);
 	}
 	return disposition;
 }
@@ -3034,7 +3180,7 @@
 	/* Generate ABORT chunk to send the peer.  */
 	abort = sctp_make_abort(asoc, NULL, 0);
 	if (!abort)
-        	retval = SCTP_DISPOSITION_NOMEM;
+		retval = SCTP_DISPOSITION_NOMEM;
 	else
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
 
@@ -3042,12 +3188,8 @@
 	 * TCB.  This is a departure from our typical NOMEM handling.
 	 */
 
-	/* Change to CLOSED state.  */
-	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-			SCTP_STATE(SCTP_STATE_CLOSED));
-
-	/* Delete the established association.  */
-	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
+	/* Delete the established association. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
 	return retval;
 }
 
@@ -3090,11 +3232,12 @@
  * Outputs
  * (timers)
  */
-sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(const sctp_endpoint_t *ep,
-						    const sctp_association_t *asoc,
-						    const sctp_subtype_t type,
-						    void *arg,
-						    sctp_cmd_seq_t *commands)
+sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(
+	const sctp_endpoint_t *ep,
+	const sctp_association_t *asoc,
+	const sctp_subtype_t type,
+	void *arg,
+	sctp_cmd_seq_t *commands)
 {
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
@@ -3134,7 +3277,7 @@
 }
 
 /*
- * sctp_cookie_wait_prm_abort
+ * sctp_sf_cookie_wait_prm_abort
  *
  * Section: 4 Note: 2
  * Verification Tag:
@@ -3148,19 +3291,41 @@
  * (timers)
  */
 sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep,
-						 const sctp_association_t *asoc,
-						 const sctp_subtype_t type,
-						 void *arg,
-						 sctp_cmd_seq_t *commands)
+					const sctp_association_t *asoc,
+					const sctp_subtype_t type,
+					void *arg,
+					sctp_cmd_seq_t *commands)
 {
+	sctp_chunk_t *abort;
+	sctp_disposition_t retval;
+
 	/* Stop T1-init timer */
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
-	return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
+	retval = SCTP_DISPOSITION_CONSUME;
+
+	/* Generate ABORT chunk to send the peer */
+	abort = sctp_make_abort(asoc, NULL, 0);
+	if (!abort)
+		retval = SCTP_DISPOSITION_NOMEM;
+	else
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+			SCTP_STATE(SCTP_STATE_CLOSED));
+
+	/* Even if we can't send the ABORT due to low memory delete the
+	 * TCB.  This is a departure from our typical NOMEM handling.
+	 */
+
+	/* Delete the established association. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_NULL());
+
+	return retval;
 }
 
 /*
- * sctp_cookie_echoed_prm_abort
+ * sctp_sf_cookie_echoed_prm_abort
  *
  * Section: 4 Note: 3
  * Verification Tag:
@@ -3174,10 +3339,10 @@
  * (timers)
  */
 sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(const sctp_endpoint_t *ep,
-						   const sctp_association_t *asoc,
-						   const sctp_subtype_t type,
-						   void *arg,
-						   sctp_cmd_seq_t *commands)
+						const sctp_association_t *asoc,
+						const sctp_subtype_t type,
+						void *arg,
+						sctp_cmd_seq_t *commands)
 {
 	/* There is a single T1 timer, so we should be able to use
 	 * common function with the COOKIE-WAIT state.
@@ -3186,6 +3351,87 @@
 }
 
 /*
+ * sctp_sf_shutdown_pending_prm_abort
+ *
+ * Inputs
+ * (endpoint, asoc)
+ *
+ * The RFC does not explicitly address this issue, but is the route through the
+ * state table when someone issues an abort while in SHUTDOWN-PENDING state.
+ *
+ * Outputs
+ * (timers)
+ */
+sctp_disposition_t sctp_sf_shutdown_pending_prm_abort(
+	const sctp_endpoint_t *ep,
+	const sctp_association_t *asoc,
+	const sctp_subtype_t type,
+	void *arg,
+	sctp_cmd_seq_t *commands)
+{
+	/* Stop the T5-shutdown guard timer.  */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
+
+	return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
+}
+
+/*
+ * sctp_sf_shutdown_sent_prm_abort
+ *
+ * Inputs
+ * (endpoint, asoc)
+ *
+ * The RFC does not explicitly address this issue, but is the route through the
+ * state table when someone issues an abort while in SHUTDOWN-SENT state.
+ *
+ * Outputs
+ * (timers)
+ */
+sctp_disposition_t sctp_sf_shutdown_sent_prm_abort(
+	const sctp_endpoint_t *ep,
+	const sctp_association_t *asoc,
+	const sctp_subtype_t type,
+	void *arg,
+	sctp_cmd_seq_t *commands)
+{
+	/* Stop the T2-shutdown timer.  */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
+
+	/* Stop the T5-shutdown guard timer.  */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
+
+	return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
+}
+
+/*
+ * sctp_sf_cookie_echoed_prm_abort
+ *
+ * Inputs
+ * (endpoint, asoc)
+ *
+ * The RFC does not explcitly address this issue, but is the route through the
+ * state table when someone issues an abort while in COOKIE_ECHOED state.
+ *
+ * Outputs
+ * (timers)
+ */
+sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort(
+	const sctp_endpoint_t *ep,
+	const sctp_association_t *asoc,
+	const sctp_subtype_t type,
+	void *arg,
+	sctp_cmd_seq_t *commands)
+{
+	/* The same T2 timer, so we should be able to use
+	 * common function with the SHUTDOWN-SENT state.
+	 */
+	return sctp_sf_shutdown_sent_prm_abort(ep, asoc, type, arg, commands);
+}
+
+/*
  * Ignore the primitive event
  *
  * The return value is the disposition of the primitive.
@@ -3218,10 +3464,10 @@
  * The return value is the disposition.
  */
 sctp_disposition_t sctp_sf_do_9_2_start_shutdown(const sctp_endpoint_t *ep,
-						 const sctp_association_t *asoc,
-						 const sctp_subtype_t type,
-						 void *arg,
-						 sctp_cmd_seq_t *commands)
+						const sctp_association_t *asoc,
+						const sctp_subtype_t type,
+						void *arg,
+						sctp_cmd_seq_t *commands)
 {
 	sctp_chunk_t *reply;
 
@@ -3236,7 +3482,7 @@
 
 	/* Set the transport for the SHUTDOWN chunk and the timeout for the
 	 * T2-shutdown timer.
-	 */ 
+	 */
 	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
 
 	/* It shall then start the T2-shutdown timer */
@@ -3322,8 +3568,7 @@
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	SCTP_DEBUG_PRINTK("The event other type %d is ignored\n",
-			  type.other);
+	SCTP_DEBUG_PRINTK("The event other type %d is ignored\n", type.other);
 	return SCTP_DISPOSITION_DISCARD;
 }
 
@@ -3413,7 +3658,7 @@
 				       void *arg,
 				       sctp_cmd_seq_t *commands)
 {
-        sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
+	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
 	return SCTP_DISPOSITION_CONSUME;
 }
 
@@ -3479,11 +3724,11 @@
 
 		if (!repl)
 			goto nomem;
-		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 
 		/* Issue a sideeffect to do the needed accounting. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
 				SCTP_TO(timer));
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 	} else {
 		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_NULL());
 		return SCTP_DISPOSITION_DELETE_TCB;
@@ -3559,16 +3804,44 @@
 	return SCTP_DISPOSITION_NOMEM;
 }
 
+/* sctpimpguide-05 Section 2.12.2
+ * The sender of the SHUTDOWN MAY also start an overall guard timer
+ * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
+ * At the expiration of this timer the sender SHOULD abort the association
+ * by sending an ABORT chunk.
+ */
+sctp_disposition_t sctp_sf_t5_timer_expire(const sctp_endpoint_t *ep,
+					   const sctp_association_t *asoc,
+					   const sctp_subtype_t type,
+					   void *arg,
+					   sctp_cmd_seq_t *commands)
+{
+	sctp_chunk_t *reply = NULL;
+
+	SCTP_DEBUG_PRINTK("Timer T5 expired.\n");
+
+	reply = sctp_make_abort(asoc, NULL, 0);
+	if (!reply)
+		goto nomem;
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
+	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+
+	return SCTP_DISPOSITION_DELETE_TCB;
+nomem:
+	return SCTP_DISPOSITION_NOMEM;
+}
+
 /* Handle expiration of AUTOCLOSE timer.  When the autoclose timer expires,
  * the association is automatically closed by starting the shutdown process.
  * The work that needs to be done is same as when SHUTDOWN is initiated by
  * the user.  So this routine looks same as sctp_sf_do_9_2_prm_shutdown().
  */
 sctp_disposition_t sctp_sf_autoclose_timer_expire(const sctp_endpoint_t *ep,
-						  const sctp_association_t *asoc,
-						  const sctp_subtype_t type,
-						  void *arg,
-						  sctp_cmd_seq_t *commands)
+						const sctp_association_t *asoc,
+						const sctp_subtype_t type,
+						void *arg,
+						sctp_cmd_seq_t *commands)
 {
 	int disposition;
 
@@ -3583,11 +3856,16 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
 
+	/* sctpimpguide-05 Section 2.12.2
+	 * The sender of the SHUTDOWN MAY also start an overall guard timer
+	 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
+ 	 */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
 	disposition = SCTP_DISPOSITION_CONSUME;
 	if (sctp_outqueue_is_empty(&asoc->outqueue)) {
-		disposition =
-			sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
-						      arg, commands);
+		disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
+							    arg, commands);
 	}
 	return disposition;
 }
@@ -3649,30 +3927,6 @@
 {
 	SCTP_DEBUG_PRINTK("Timer %d ignored.\n", type.chunk);
 	return SCTP_DISPOSITION_CONSUME;
-}
-
-/*
- * Discard the chunk.
- *
- * Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
- * [Too numerous to mention...]
- * Verification Tag: No verification needed.
- * Inputs
- * (endpoint, asoc, chunk)
- *
- * Outputs
- * (asoc, reply_msg, msg_up, timers, counters)
- *
- * The return value is the disposition of the chunk.
- */
-sctp_disposition_t sctp_sf_discard_chunk(const sctp_endpoint_t *ep,
-					 const sctp_association_t *asoc,
-					 const sctp_subtype_t type,
-					 void *arg,
-					 sctp_cmd_seq_t *commands)
-{
-	SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
-	return SCTP_DISPOSITION_DISCARD;
 }
 
 /********************************************************************
diff -Nru a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
--- a/net/sctp/sm_statetable.c	Fri Sep 27 14:51:04 2002
+++ b/net/sctp/sm_statetable.c	Fri Sep 27 14:51:04 2002
@@ -4,36 +4,36 @@
  * Copyright (c) 2001 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These are the state tables for the SCTP state machine.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
  *    Jon Grimm             <jgrimm@us.ibm.com>
@@ -48,9 +48,10 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-sctp_sm_table_entry_t nop = {fn: sctp_sf_discard_chunk,
-			     name: "sctp_sf_discard_chunk"};
-sctp_sm_table_entry_t bug = {fn: sctp_sf_bug, name: "sctp_sf_bug"};
+sctp_sm_table_entry_t bug = {
+	.fn = sctp_sf_bug, 
+	.name = "sctp_sf_bug"
+};
 
 #define DO_LOOKUP(_max, _type, _table) \
 	if ((event_subtype._type > (_max))) { \
@@ -58,9 +59,9 @@
 		       "sctp table %p possible attack:" \
 		       " event %d exceeds max %d\n", \
 		       _table, event_subtype._type, _max); \
-		return(&bug); \
+		return &bug; \
 	} \
-	return(&_table[event_subtype._type][(int)state]);
+	return &_table[event_subtype._type][(int)state];
 
 sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
 					    sctp_state_t state,
@@ -71,7 +72,7 @@
 		return sctp_chunk_event_lookup(event_subtype.chunk, state);
 		break;
 	case SCTP_EVENT_T_TIMEOUT:
-		DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
+		DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, 
 			  timeout_event_table);
 		break;
 
@@ -92,320 +93,323 @@
 
 #define TYPE_SCTP_DATA { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \
+	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_eat_data_6_2, name: "sctp_sf_eat_data_6_2"}, \
+	{.fn = sctp_sf_eat_data_6_2, .name = "sctp_sf_eat_data_6_2"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_eat_data_6_2, name: "sctp_sf_eat_data_6_2"}, \
+	{.fn = sctp_sf_eat_data_6_2, .name = "sctp_sf_eat_data_6_2"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_eat_data_fast_4_4, name: "sctp_sf_eat_data_fast_4_4"}, \
+	{.fn = sctp_sf_eat_data_fast_4_4, .name = "sctp_sf_eat_data_fast_4_4"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_DATA */
 
 #define TYPE_SCTP_INIT { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_do_5_1B_init, name: "sctp_sf_do_5_1B_init"}, \
+	{.fn = sctp_sf_do_5_1B_init, .name = "sctp_sf_do_5_1B_init"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_do_5_2_1_siminit, name: "sctp_sf_do_5_2_1_siminit"}, \
+	{.fn = sctp_sf_do_5_2_1_siminit, .name = "sctp_sf_do_5_2_1_siminit"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_do_5_2_1_siminit, name: "sctp_sf_do_5_2_1_siminit"}, \
+	{.fn = sctp_sf_do_5_2_1_siminit, .name = "sctp_sf_do_5_2_1_siminit"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \
+	{.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \
+	{.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \
+	{.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \
+	{.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_do_9_2_reshutack, .name = "sctp_sf_do_9_2_reshutack"}, \
 } /* TYPE_SCTP_INIT */
 
 #define TYPE_SCTP_INIT_ACK { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_do_5_1C_ack, name: "sctp_sf_do_5_1C_ack"}, \
+	{.fn = sctp_sf_do_5_1C_ack, .name = "sctp_sf_do_5_1C_ack"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_INIT_ACK */
 
 #define TYPE_SCTP_SACK { \
 	/*  SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \
+	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \
+	{.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \
+	{.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \
+	{.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \
+	{.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_SACK */
 
 #define TYPE_SCTP_HEARTBEAT { \
 	/*  SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \
+	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \
+	{.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \
+	{.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \
+	{.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \
+	{.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \
+	{.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
 	/* This should not happen, but we are nice.  */ \
-	{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \
+	{.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
 } /* TYPE_SCTP_HEARTBEAT */
 
 #define TYPE_SCTP_HEARTBEAT_ACK { \
 	/*  SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \
+	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \
+	{.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \
+	{.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \
+	{.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \
+	{.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \
+	{.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_HEARTBEAT_ACK */
 
 #define TYPE_SCTP_ABORT { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_pdiscard, name: "sctp_sf_pdiscard"}, \
+	{.fn = sctp_sf_pdiscard, .name = "sctp_sf_pdiscard"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_cookie_wait_abort, name: "sctp_sf_cookie_wait_abort"}, \
+	{.fn = sctp_sf_cookie_wait_abort, .name = "sctp_sf_cookie_wait_abort"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_cookie_echoed_abort, \
-	 name: "sctp_sf_cookie_echoed_abort"}, \
+	{.fn = sctp_sf_cookie_echoed_abort, \
+	 .name = "sctp_sf_cookie_echoed_abort"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
+	{.fn = sctp_sf_do_9_1_abort, .name = "sctp_sf_do_9_1_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
+	{.fn = sctp_sf_shutdown_pending_abort, \
+	.name = "sctp_sf_shutdown_pending_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
+	{.fn = sctp_sf_shutdown_sent_abort, \
+	.name = "sctp_sf_shutdown_sent_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
+	{.fn = sctp_sf_do_9_1_abort, .name = "sctp_sf_do_9_1_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
+	{.fn = sctp_sf_shutdown_ack_sent_abort, \
+	.name = "sctp_sf_shutdown_ack_sent_abort"}, \
 } /* TYPE_SCTP_ABORT */
 
 #define TYPE_SCTP_SHUTDOWN { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \
+	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_9_2_shutdown, name: "sctp_sf_do_9_2_shutdown"}, \
+	{.fn = sctp_sf_do_9_2_shutdown, .name = "sctp_sf_do_9_2_shutdown"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_9_2_shutdown_ack, \
-	 name: "sctp_sf_do_9_2_shutdown_ack"}, \
+	{.fn = sctp_sf_do_9_2_shutdown_ack, \
+	 .name = "sctp_sf_do_9_2_shutdown_ack"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_SHUTDOWN */
 
 #define TYPE_SCTP_SHUTDOWN_ACK { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \
+	{.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \
+	{.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_9_2_final, name: "sctp_sf_do_9_2_final"}, \
+	{.fn = sctp_sf_do_9_2_final, .name = "sctp_sf_do_9_2_final"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \
+	{.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_do_9_2_final, name: "sctp_sf_do_9_2_final"}, \
+	{.fn = sctp_sf_do_9_2_final, .name = "sctp_sf_do_9_2_final"}, \
 } /* TYPE_SCTP_SHUTDOWN_ACK */
 
 #define TYPE_SCTP_ERROR { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \
+	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_operr_notify, name: "sctp_sf_operr_notify"}, \
+	{.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_ERROR */
 
 #define TYPE_SCTP_COOKIE_ECHO { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_do_5_1D_ce, name: "sctp_sf_do_5_1D_ce"}, \
+	{.fn = sctp_sf_do_5_1D_ce, .name = "sctp_sf_do_5_1D_ce"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \
+	{.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \
+	{.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \
+	{.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \
+	{.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \
+	{.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \
+	{.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \
+	{.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
 } /* TYPE_SCTP_COOKIE_ECHO */
 
 #define TYPE_SCTP_COOKIE_ACK { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_do_5_1E_ca, name: "sctp_sf_do_5_1E_ca"}, \
+	{.fn = sctp_sf_do_5_1E_ca, .name = "sctp_sf_do_5_1E_ca"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_COOKIE_ACK */
 
 #define TYPE_SCTP_ECN_ECNE { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \
+	{.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \
+	{.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \
+	{.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \
+	{.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \
+	{.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 } /* TYPE_SCTP_ECN_ECNE */
 
 #define TYPE_SCTP_ECN_CWR { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_ecn_cwr, name: "sctp_sf_do_ecn_cwr"}, \
+	{.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_ecn_cwr, name: "sctp_sf_do_ecn_cwr"}, \
+	{.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_ecn_cwr, name: "sctp_sf_do_ecn_cwr"}, \
+	{.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 } /* TYPE_SCTP_ECN_CWR */
 
 #define TYPE_SCTP_SHUTDOWN_COMPLETE { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_do_4_C, name: "sctp_sf_do_4_C"}, \
+	{.fn = sctp_sf_do_4_C, .name = "sctp_sf_do_4_C"}, \
 } /* TYPE_SCTP_SHUTDOWN_COMPLETE */
 
 /* The primary index for this table is the chunk type.
@@ -434,397 +438,415 @@
 static sctp_sm_table_entry_t
 chunk_event_table_asconf[SCTP_STATE_NUM_STATES] = {
 	/* SCTP_STATE_EMPTY */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_CLOSED */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_COOKIE_WAIT */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_COOKIE_ECHOED */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
-
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_ESTABLISHED */
-	{fn: sctp_sf_discard_chunk,
-	 name: "sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"},
-
+	{.fn = sctp_sf_discard_chunk,
+	 .name = "sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"},
 	/* SCTP_STATE_SHUTDOWN_PENDING */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_SHUTDOWN_SENT */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 };	/* chunk asconf */
 
 static sctp_sm_table_entry_t
 chunk_event_table_asconf_ack[SCTP_STATE_NUM_STATES] = {
 	/* SCTP_STATE_EMPTY */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_CLOSED */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_COOKIE_WAIT */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_COOKIE_ECHOED */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
-
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_ESTABLISHED */
-	{fn: sctp_sf_discard_chunk,
-	 name: "sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"},
-
+	{.fn = sctp_sf_discard_chunk,
+	 .name = "sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"},
 	/* SCTP_STATE_SHUTDOWN_PENDING */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_SHUTDOWN_SENT */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */
-	{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"},
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
 };	/* chunk asconf_ack */
 
+static sctp_sm_table_entry_t
+chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
+	/* SCTP_STATE_EMPTY */
+	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"},
+	/* SCTP_STATE_CLOSED */
+	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"},
+	/* SCTP_STATE_COOKIE_WAIT */
+	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
+	/* SCTP_STATE_COOKIE_ECHOED */
+	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
+	/* SCTP_STATE_ESTABLISHED */
+	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
+	/* SCTP_STATE_SHUTDOWN_PENDING */
+	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
+	/* SCTP_STATE_SHUTDOWN_SENT */
+	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
+	/* SCTP_STATE_SHUTDOWN_RECEIVED */
+	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
+	/* SCTP_STATE_SHUTDOWN_ACK_SENT */
+	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
+};	/* chunk unknown */
+
 #define TYPE_SCTP_PRIMITIVE_INITIALIZE  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_INITIALIZE */
 
 #define TYPE_SCTP_PRIMITIVE_ASSOCIATE  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_do_prm_asoc, name: "sctp_sf_do_prm_asoc"}, \
+	{.fn = sctp_sf_do_prm_asoc, .name = "sctp_sf_do_prm_asoc"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */
 
 #define TYPE_SCTP_PRIMITIVE_SHUTDOWN  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_error_closed, name: "sctp_sf_error_closed"}, \
+	{.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_cookie_wait_prm_shutdown, \
-	 name: "sctp_sf_cookie_wait_prm_shutdown"}, \
+	{.fn = sctp_sf_cookie_wait_prm_shutdown, \
+	 .name = "sctp_sf_cookie_wait_prm_shutdown"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_cookie_echoed_prm_shutdown, \
+	{.fn = sctp_sf_cookie_echoed_prm_shutdown, \
 	 name:"sctp_sf_cookie_echoed_prm_shutdown"},\
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_9_2_prm_shutdown, \
-	 name: "sctp_sf_do_9_2_prm_shutdown"}, \
+	{.fn = sctp_sf_do_9_2_prm_shutdown, \
+	 .name = "sctp_sf_do_9_2_prm_shutdown"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \
+	{.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \
+	{.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \
+	{.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \
+	{.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
 } /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */
 
 #define TYPE_SCTP_PRIMITIVE_ABORT  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_error_closed, name: "sctp_sf_error_closed"}, \
+	{.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_cookie_wait_prm_abort, \
-	 name: "sctp_sf_cookie_wait_prm_abort"}, \
+	{.fn = sctp_sf_cookie_wait_prm_abort, \
+	.name = "sctp_sf_cookie_wait_prm_abort"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_cookie_echoed_prm_abort, \
-	 name: "sctp_sf_cookie_echoed_prm_abort"}, \
+	{.fn = sctp_sf_cookie_echoed_prm_abort, \
+	.name = "sctp_sf_cookie_echoed_prm_abort"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_9_1_prm_abort, \
-	 name: "sctp_sf_do_9_1_prm_abort"}, \
+	{.fn = sctp_sf_do_9_1_prm_abort, \
+	.name = "sctp_sf_do_9_1_prm_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_9_1_prm_abort, \
-	 name: "sctp_sf_do_9_1_prm_abort"}, \
+	{.fn = sctp_sf_shutdown_pending_prm_abort, \
+	.name = "sctp_sf_shutdown_pending_prm_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_9_1_prm_abort, \
-	 name: "sctp_sf_do_9_1_prm_abort"}, \
+	{.fn = sctp_sf_shutdown_sent_prm_abort, \
+	.name = "sctp_sf_shutdown_sent_prm_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_do_9_1_prm_abort, \
-	 name: "sctp_sf_do_9_1_prm_abort"}, \
+	{.fn = sctp_sf_do_9_1_prm_abort, \
+	.name = "sctp_sf_do_9_1_prm_abort"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_do_9_1_prm_abort, \
-	 name: "sctp_sf_do_9_1_prm_abort"}, \
+	{.fn = sctp_sf_shutdown_ack_sent_prm_abort, \
+	.name = "sctp_sf_shutdown_ack_sent_prm_abort"}, \
 } /* TYPE_SCTP_PRIMITIVE_ABORT */
 
 #define TYPE_SCTP_PRIMITIVE_SEND  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_error_closed, name: "sctp_sf_error_closed"}, \
+	{.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_do_prm_send, name: "sctp_sf_do_prm_send"}, \
+	{.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_do_prm_send, name: "sctp_sf_do_prm_send"}, \
+	{.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_prm_send, name: "sctp_sf_do_prm_send"}, \
+	{.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \
+	{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \
+	{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \
+	{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \
+	{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
 } /* TYPE_SCTP_PRIMITIVE_SEND */
 
 #define TYPE_SCTP_PRIMITIVE_SETPRIMARY  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_SETPRIMARY */
 
 #define TYPE_SCTP_PRIMITIVE_RECEIVE  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_RECEIVE */
 
 #define TYPE_SCTP_PRIMITIVE_STATUS  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_STATUS */
 
 #define TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT */
 
 #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
 
 #define TYPE_SCTP_PRIMITIVE_GETSRTTREPORT  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_GETSRTTREPORT */
 
 #define TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD */
 
 #define TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS */
 
 #define TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT */
 
 #define TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED */
 
 #define TYPE_SCTP_PRIMITIVE_DESTROY  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 } /* TYPE_SCTP_PRIMITIVE_DESTROY */
 
 /* The primary index for this table is the primitive type.
@@ -851,46 +873,46 @@
 
 #define TYPE_SCTP_OTHER_NO_PENDING_TSN  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_9_2_start_shutdown, \
-	 name: "sctp_do_9_2_start_shutdown"}, \
+	{.fn = sctp_sf_do_9_2_start_shutdown, \
+	 .name = "sctp_do_9_2_start_shutdown"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_do_9_2_shutdown_ack, \
-	 name: "sctp_sf_do_9_2_shutdown_ack"}, \
+	{.fn = sctp_sf_do_9_2_shutdown_ack, \
+	 .name = "sctp_sf_do_9_2_shutdown_ack"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 }
 
 #define TYPE_SCTP_OTHER_ICMP_UNREACHFRAG  { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 }
 
 sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
@@ -900,213 +922,234 @@
 
 #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_t1_timer_expire, name: "sctp_sf_t1_timer_expire"}, \
+	{.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_t1_timer_expire, name: "sctp_sf_t1_timer_expire"}, \
+	{.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_t2_timer_expire, name: "sctp_sf_t2_timer_expire"}, \
+	{.fn = sctp_sf_t2_timer_expire, .name = "sctp_sf_t2_timer_expire"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_t2_timer_expire, name: "sctp_sf_t2_timer_expire"}, \
+	{.fn = sctp_sf_t2_timer_expire, .name = "sctp_sf_t2_timer_expire"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \
+	{.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \
+	{.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \
+	{.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \
+	{.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_CLOSED */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_COOKIE_WAIT */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_COOKIE_ECHOED */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_ESTABLISHED */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_SHUTDOWN_PENDING */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_SHUTDOWN_SENT */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+}
+
+#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
+	/* SCTP_STATE_EMPTY */ \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_sendbeat_8_3, name: "sctp_sf_sendbeat_8_3"}, \
+	{.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_sendbeat_8_3, name: "sctp_sf_sendbeat_8_3"}, \
+	{.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_do_6_2_sack, name: "sctp_sf_do_6_2_sack"}, \
+	{.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_do_6_2_sack, name: "sctp_sf_do_6_2_sack"}, \
+	{.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_do_6_2_sack, name: "sctp_sf_do_6_2_sack"}, \
+	{.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_autoclose_timer_expire, \
-	 name: "sctp_sf_autoclose_timer_expire"}, \
+	{.fn = sctp_sf_autoclose_timer_expire, \
+	 .name = "sctp_sf_autoclose_timer_expire"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE { \
 	/* SCTP_STATE_EMPTY */ \
-	{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_CLOSED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
 }
 
 sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
@@ -1116,6 +1159,7 @@
 	TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
 	TYPE_SCTP_EVENT_TIMEOUT_T3_RTX,
 	TYPE_SCTP_EVENT_TIMEOUT_T4_RTO,
+	TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
 	TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT,
 	TYPE_SCTP_EVENT_TIMEOUT_SACK,
 	TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
@@ -1125,12 +1169,11 @@
 sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t state)
 {
 	if (state > SCTP_STATE_MAX)
-		BUG();
-	if (cid < 0)
-		return &nop;
+		return &bug;
 
-	if (cid <= SCTP_CID_BASE_MAX)
+	if (cid >= 0 && cid <= SCTP_CID_BASE_MAX) {
 		return &chunk_event_table[cid][state];
+	}
 
 	switch (cid) {
 	case SCTP_CID_ASCONF:
@@ -1139,8 +1182,6 @@
 	case SCTP_CID_ASCONF_ACK:
 		return &chunk_event_table_asconf_ack[state];
 	default:
-		return &nop;
-	};
-
-	return &nop;
+		return &chunk_event_table_unknown[state];
+	}
 }
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	Fri Sep 27 14:51:05 2002
+++ b/net/sctp/socket.c	Fri Sep 27 14:51:05 2002
@@ -1,8 +1,8 @@
 /* Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
- * Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001 Nokia, Inc.
+ * Copyright (c) 2001-2002 International Business Machines, Corp.
+ * Copyright (c) 2001-2002 Intel Corp.
+ * Copyright (c) 2001-2002 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
  * 
  * This file is part of the SCTP kernel reference Implementation
@@ -82,8 +82,6 @@
 static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p,
 				int msg_len);
 static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p);
-static inline void sctp_sk_memcpy_msgname(struct sock *sk, char * msgname,
-					  int *addr_len, struct sk_buff *skb);
 static inline void sctp_sk_addr_set(struct sock *,
 				    const sockaddr_storage_t *newaddr,
 				    sockaddr_storage_t *saveaddr);
@@ -121,7 +119,7 @@
 
 	/* Disallow binding twice. */
 	if (!sctp_sk(sk)->ep->base.bind_addr.port)
-		retval = sctp_do_bind(sk, (sockaddr_storage_t *)uaddr, 
+		retval = sctp_do_bind(sk, (sockaddr_storage_t *)uaddr,
 				      addr_len);
 	else
 		retval = -EINVAL;
@@ -317,7 +315,7 @@
 
 /* Unprotected by locks. Call only with socket lock sk->lock held! See
  * sctp_bindx() for a lock-protected call.
- */ 
+ */
 
 static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs, 
 			int addrcnt, int flags)
@@ -326,11 +324,11 @@
 
 	SCTP_DEBUG_PRINTK("__sctp_bindx(sk: %p, addrs: %p, addrcnt: %d, "
 			  "flags: %s)\n", sk, addrs, addrcnt,
-			  (BINDX_ADD_ADDR == flags)?"ADD":
-			  ((BINDX_REM_ADDR == flags)?"REM":"BOGUS"));
+			  (BINDX_ADD_ADDR == flags) ? "ADD" :
+			  ((BINDX_REM_ADDR == flags) ? "REM" : "BOGUS"));
 
 	switch (flags) {
-       	case BINDX_ADD_ADDR:
+	case BINDX_ADD_ADDR:
 		retval = sctp_bindx_add(sk, addrs, addrcnt);
 		break;
 
@@ -411,7 +409,7 @@
 				sctp_bindx_rem(sk, addrs, cnt);
 			return retval;
 		}
-        }
+	}
 
 	/* Notify the peer(s), assuming we have (an) association(s).
 	 * FIXME: for UDP, we have a 1-1-many mapping amongst sk, ep and asoc,
@@ -500,9 +498,8 @@
 		case AF_INET:
 			saveaddr = *((sockaddr_storage_t *)
 				     &addrs[cnt]);
-			saveaddr.v4.sin_port =
-				ntohs(saveaddr.v4.sin_port);
-			/* verify the port */
+			saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
+			/* Verify the port.  */
 			if (saveaddr.v4.sin_port != bp->port) {
 				retval = -EINVAL;
 				goto err_bindx_rem;
@@ -606,7 +603,8 @@
  *
  * Returns 0 if ok, <0 errno code on error.
  */
-static int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr_storage *addrs,
+static int sctp_setsockopt_bindx(struct sock* sk,
+				 struct sockaddr_storage *addrs,
 				 int addrssize, int op)
 {
 	struct sockaddr_storage *kaddrs;
@@ -614,8 +612,7 @@
 	size_t addrcnt;
 
 	SCTP_DEBUG_PRINTK("sctp_do_setsocktopt_bindx: sk %p addrs %p"
-			  " addrssize %d opt %d\n", sk, addrs,
-			  addrssize, op);
+			  " addrssize %d opt %d\n", sk, addrs, addrssize, op);
 
 	/* Do we have an integer number of structs sockaddr_storage?  */
 	if (unlikely(addrssize <= 0 ||
@@ -781,7 +778,7 @@
 
 		memcpy(&to, msg->msg_name, msg->msg_namelen);
 		SCTP_DEBUG_PRINTK("Just memcpy'd. msg_name is "
-				  "0x%x:%u.\n", 
+				  "0x%x:%u.\n",
 				  to.v4.sin_addr.s_addr, to.v4.sin_port);
 
 		to.v4.sin_port = ntohs(to.v4.sin_port);
@@ -823,14 +820,14 @@
 	} else {
 		/* For a peeled-off socket, ignore any associd specified by
 		 * the user with SNDRCVINFO.
-		 */ 
+		 */
 		if (SCTP_SOCKET_UDP_HIGH_BANDWIDTH == sp->type) {
 			if (list_empty(&ep->asocs)) {
 				err = -EINVAL;
 				goto out_unlock;
 			}
 			asoc = list_entry(ep->asocs.next, sctp_association_t,
-				          asocs);
+					  asocs);
 		} else if (associd) {
 			asoc = sctp_id2assoc(sk, associd);
 		}
@@ -851,7 +848,7 @@
 			goto out_unlock;
 		}
 		if (sinfo_flags & MSG_ABORT) {
-			SCTP_DEBUG_PRINTK("Aborting association: %p\n",asoc);
+			SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
 			sctp_primitive_ABORT(asoc, NULL);
 			err = 0;
 			goto out_unlock;
@@ -866,8 +863,7 @@
 		 * either the default or the user specified stream counts.
 		 */
 		if (sinfo) {
-			if (!sinit ||
-			    (sinit && !sinit->sinit_num_ostreams)) {
+			if (!sinit || (sinit && !sinit->sinit_num_ostreams)) {
 				/* Check against the defaults. */
 				if (sinfo->sinfo_stream >=
 				    sp->initmsg.sinit_num_ostreams) {
@@ -988,7 +984,7 @@
 		/* If the user didn't specify SNDRCVINFO, make up one with
 		 * some defaults.
 		 */
-		default_sinfo.sinfo_stream  = asoc->defaults.stream;
+		default_sinfo.sinfo_stream = asoc->defaults.stream;
 		default_sinfo.sinfo_ppid = asoc->defaults.ppid;
 		sinfo = &default_sinfo;
 	}
@@ -1011,7 +1007,7 @@
 	/* FIXME: This looks wrong so I'll comment out.
 	 * We should be able to use this same technique for
 	 * primary address override!  --jgrimm
-	 */ 
+	 */
 	/* If the user gave us an address, copy it in.  */
 	if (msg->msg_name) {
 		chunk->transport = sctp_assoc_lookup_paddr(asoc, &to);
@@ -1025,7 +1021,7 @@
 	/* Copy the message from the user.  */
 	err = sctp_user_addto_chunk(chunk, msg_len, msg->msg_iov);
 	if (err < 0)
-		goto out_free; 
+		goto out_free;
 
 	SCTP_DEBUG_PRINTK("Copied message to chunk: %p.\n", chunk);
 
@@ -1096,12 +1092,13 @@
  *  flags   - flags sent or received with the user message, see Section
  *            5 for complete description of the flags.
  */
-static struct sk_buff * sctp_skb_recv_datagram(struct sock *, int, int, int *);
+static struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
 
 static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
 			int noblock, int flags, int *addr_len)
 {
 	sctp_ulpevent_t *event = NULL;
+	sctp_opt_t *sp = sctp_sk(sk);
 	struct sk_buff *skb;
 	int copied;
 	int err = 0;
@@ -1147,19 +1144,16 @@
 	sock_recv_timestamp(msg, sk, skb);
 	if (sctp_ulpevent_is_notification(event)) {
 		msg->msg_flags |= MSG_NOTIFICATION;
+		sp->pf->event_msgname(event, msg->msg_name, addr_len);
 	} else {
-		/* Copy the address.  */
-		if (addr_len && msg->msg_name)
-			sctp_sk_memcpy_msgname(sk, msg->msg_name,
-						addr_len, skb);
+		sp->pf->skb_msgname(skb, msg->msg_name, addr_len);
 	}
 
 	/* Check if we allow SCTP_SNDRCVINFO. */
-	if (sctp_sk(sk)->subscribe.sctp_data_io_event)
+	if (sp->subscribe.sctp_data_io_event)
 		sctp_ulpevent_read_sndrcvinfo(event, msg);
-
 #if 0
-	/* FIXME: we should be calling IP layer too.  */
+	/* FIXME: we should be calling IP/IPv6 layers.  */
 	if (sk->protinfo.af_inet.cmsg_flags)
 		ip_cmsg_recv(msg, skb);
 #endif
@@ -1176,7 +1170,8 @@
 	return err;
 }
 
-static inline int sctp_setsockopt_disable_fragments(struct sock *sk, char *optval, int optlen)
+static inline int sctp_setsockopt_disable_fragments(struct sock *sk, 
+						    char *optval, int optlen)
 {
 	int val;
 
@@ -1191,7 +1186,8 @@
 	return 0;
 }
 
-static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval, int optlen)
+static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval, 
+					     int optlen)
 {
 	if (optlen != sizeof(struct sctp_event_subscribe))
 		return -EINVAL;
@@ -1200,7 +1196,8 @@
 	return 0;
 }
 
-static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval, int optlen)
+static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval, 
+					    int optlen)
 {
 	sctp_opt_t *sp = sctp_sk(sk);
 
@@ -1236,7 +1233,7 @@
 			   char *optval, int optlen)
 {
 	int retval = 0;
-	char * tmp;
+	char *tmp;
 	sctp_protocol_t *proto = sctp_get_protocol();
 	struct list_head *pos;
 	sctp_func_t *af;
@@ -1332,7 +1329,7 @@
 {
 	int error = -EOPNOTSUPP;
 
-	*err = error; 
+	*err = error;
 	return NULL;
 }
 
@@ -1356,19 +1353,9 @@
 
 	proto = sctp_get_protocol();
 
-	/* Create a per socket endpoint structure.  Even if we
-	 * change the data structure relationships, this may still
-	 * be useful for storing pre-connect address information.
-	 */
-        ep = sctp_endpoint_new(proto, sk, GFP_KERNEL);
-	if (!ep)
-		return -ENOMEM;
-
 	sp = sctp_sk(sk);
 
 	/* Initialize the SCTP per socket area.  */
-
-	sp->ep = ep;
 	sp->type = SCTP_SOCKET_UDP;
 
 	/* FIXME:  The next draft (04) of the SCTP Sockets Extensions
@@ -1425,6 +1412,16 @@
 	 * for UDP-style sockets only.
 	 */
 	sp->autoclose         = 0;
+	sp->pf = sctp_get_pf_specific(sk->family);
+	/* Create a per socket endpoint structure.  Even if we
+	 * change the data structure relationships, this may still
+	 * be useful for storing pre-connect address information.
+	 */
+	ep = sctp_endpoint_new(proto, sk, GFP_KERNEL);
+	if (NULL == ep)
+		return -ENOMEM;
+
+	sp->ep = ep;
 
 	SCTP_DBG_OBJCNT_INC(sock);
 	return 0;
@@ -1836,8 +1833,7 @@
 		case PF_INET6:
 			SCTP_V6(tmpaddr.v6.sin6_family = AF_INET6;
 				tmpaddr.v6.sin6_port = snum;
-				tmpaddr.v6.sin6_addr =
-				inet6_sk(sk)->rcv_saddr;
+				tmpaddr.v6.sin6_addr = inet6_sk(sk)->rcv_saddr;
 			)
 			break;
 
@@ -1855,7 +1851,7 @@
 		 * that this port/socket (sk) combination are already
 		 * in an endpoint.
 		 */
-		for( ; sk2 != NULL; sk2 = sk2->bind_next) {
+		for ( ; sk2 != NULL; sk2 = sk2->bind_next) {
 			sctp_endpoint_t *ep2;
 			ep2 = sctp_sk(sk2)->ep;
 
@@ -1887,7 +1883,7 @@
 	 * SO_REUSEADDR on this socket -sk-).
 	 */
 	if (pp->sk == NULL) {
-		pp->fastreuse = sk->reuse? 1 : 0;
+		pp->fastreuse = sk->reuse ? 1 : 0;
 	} else if (pp->fastreuse && sk->reuse == 0) {
 		pp->fastreuse = 0;
 	}
@@ -1974,7 +1970,7 @@
 	err = -EINVAL;
 	if (sock->state != SS_UNCONNECTED)
 		goto out;
-        switch (sock->type) {
+	switch (sock->type) {
 	case SOCK_SEQPACKET:
 		err = sctp_seqpacket_listen(sk, backlog);
 		break;
@@ -2073,7 +2069,7 @@
 		pp->sk = NULL;
 		if ((pp->next = head->chain) != NULL)
 			pp->next->pprev = &pp->next;
-		head->chain= pp;
+		head->chain = pp;
 		pp->pprev = &head->chain;
 	}
 	SCTP_DEBUG_PRINTK("sctp_bucket_create() ends, pp=%p\n", pp);
@@ -2127,7 +2123,7 @@
 	switch (sk->family) {
 	case PF_INET:
 		autoaddr.v4.sin_family = AF_INET;
-		autoaddr.v4.sin_addr.s_addr  = INADDR_ANY;
+		autoaddr.v4.sin_addr.s_addr = INADDR_ANY;
 		autoaddr.v4.sin_port = htons(inet_sk(sk)->num);
 		addr_len = sizeof(struct sockaddr_in);
 		break;
@@ -2202,7 +2198,7 @@
 			return -EINVAL;
 		}
 
-	        /* Should we parse this header or ignore?  */
+		/* Should we parse this header or ignore?  */
 		if (cmsg->cmsg_level != IPPROTO_SCTP)
 			continue;
 
@@ -2433,41 +2429,6 @@
 	return NULL;
 }
 
-/* Copy an approriately formatted address for msg_name.  */
-static inline void sctp_sk_memcpy_msgname(struct sock *sk, char * msgname,
-					  int *addr_len, struct sk_buff *skb)
-{
-	struct sockaddr_in *sin;
-	struct sockaddr_in6 *sin6 __attribute__ ((unused));
-	struct sctphdr *sh;
-
-	/* The sockets layer handles copying this out to user space.  */
-	switch (sk->family) {
-	case PF_INET:
-		sin = (struct sockaddr_in *)msgname;
-		if (addr_len)
-			*addr_len = sizeof(struct sockaddr_in);
-		sin->sin_family = AF_INET;
-		sh = (struct sctphdr *) skb->h.raw;
-		sin->sin_port = sh->source;
-		sin->sin_addr.s_addr = skb->nh.iph->saddr;
-		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-		break;
-
-	case PF_INET6:
-		SCTP_V6(
-			/* FIXME: Need v6 code here.   We should convert
-			 * V4 addresses to PF_INET6 format.  See ipv6/udp.c
-			 * for an example. --jgrimm
-			 */
-		);
-		break;
-
-	default: /* Should not get here. */
-		break;
-	};
-}
-
 static inline int sctp_sendmsg_verify_name(struct sock *sk, struct msghdr *msg)
 {
 	sockaddr_storage_t *sa;
@@ -2590,7 +2551,7 @@
 
 		/* Let another process have a go.  Since we are going
 		 * to sleep anyway.
-	 	 */
+		 */
 		sctp_release_sock(sk);
 		current_timeo = schedule_timeout(current_timeo);
 		sctp_lock_sock(sk);
diff -Nru a/net/sctp/transport.c b/net/sctp/transport.c
--- a/net/sctp/transport.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/transport.c	Fri Sep 27 14:51:03 2002
@@ -4,45 +4,45 @@
  * Copyright (c) 2001 International Business Machines Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 La Monte H.P. Yarroll
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * This module provides the abstraction for an SCTP tranport representing
- * a remote transport address.  For local transport addresses, we just use 
+ * a remote transport address.  For local transport addresses, we just use
  * sockaddr_storage_t.
  *
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson          <karl@athena.chicago.il.us>
  *    Jon Grimm             <jgrimm@us.ibm.com>
  *    Xingang Guo           <xingang.guo@intel.com>
  *    Hui Huang             <hui.huang@nokia.com>
  *    Sridhar Samudrala	    <sri@us.ibm.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -215,7 +215,7 @@
 		sctp_transport_destroy(transport);
 }
 
-/* Update transport's RTO based on the newly calculated RTT. */ 
+/* Update transport's RTO based on the newly calculated RTT. */
 void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt)
 {
 	sctp_protocol_t *proto = sctp_get_protocol();
@@ -263,7 +263,7 @@
 	 * seconds then it is rounded up to RTO.Min seconds.
 	 */
 	if (tp->rto < tp->asoc->rto_min)
-		tp->rto = tp->asoc->rto_min; 
+		tp->rto = tp->asoc->rto_min;
 
 	/* 6.3.1 C7) A maximum value may be placed on RTO provided it is
 	 * at least RTO.max seconds.
@@ -381,13 +381,13 @@
 		break;
 
 	case SCTP_LOWER_CWND_FAST_RTX:
-		/* RFC 2960 7.2.4 Adjust the ssthresh and cwnd of the 
-		 * destination address(es) to which the missing DATA chunks 
-		 * were last sent, according to the formula described in 
+		/* RFC 2960 7.2.4 Adjust the ssthresh and cwnd of the
+		 * destination address(es) to which the missing DATA chunks
+		 * were last sent, according to the formula described in
 		 * Section 7.2.3.
 	 	 *
-	 	 * RFC 2960 7.2.3, sctpimpguide-05 2.9.2 Upon detection of 
-		 * packet losses from SACK (see Section 7.2.4), An endpoint 
+	 	 * RFC 2960 7.2.3, sctpimpguide-05 2.9.2 Upon detection of
+		 * packet losses from SACK (see Section 7.2.4), An endpoint
 		 * should do the following:
 		 *      ssthresh = max(cwnd/2, 2*MTU)
 		 *      cwnd = ssthresh
diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c	Fri Sep 27 14:51:03 2002
+++ b/net/sctp/ulpevent.c	Fri Sep 27 14:51:03 2002
@@ -46,9 +46,10 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-static void sctp_rcvmsg_rfree(struct sk_buff *skb);
 static void sctp_ulpevent_set_owner_r(struct sk_buff *skb,
 				      sctp_association_t *asoc);
+static void
+sctp_ulpevent_set_owner(struct sk_buff *skb, const sctp_association_t *asoc);
 
 /* Create a new sctp_ulpevent.  */
 sctp_ulpevent_t *sctp_ulpevent_new(int size, int msg_flags, int priority)
@@ -123,14 +124,12 @@
 	struct sctp_assoc_change *sac;
 
 	event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
-				  MSG_NOTIFICATION,
-				  priority);
+				  MSG_NOTIFICATION, priority);
 	if (!event)
 		goto fail;
 
 	sac = (struct sctp_assoc_change *)
-		skb_put(event->parent,
-			sizeof(struct sctp_assoc_change));
+		skb_put(event->parent, sizeof(struct sctp_assoc_change));
 
 	/* Socket Extensions for SCTP
 	 * 5.3.1.1 SCTP_ASSOC_CHANGE
@@ -199,6 +198,7 @@
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
+	sctp_ulpevent_set_owner(event->parent, asoc);
 	sac->sac_assoc_id = sctp_assoc2id(asoc);
 
 	return event;
@@ -227,14 +227,12 @@
 	struct sctp_paddr_change  *spc;
 
 	event = sctp_ulpevent_new(sizeof(struct sctp_paddr_change),
-				  MSG_NOTIFICATION,
-				  priority);
+				  MSG_NOTIFICATION, priority);
 	if (!event)
 		goto fail;
 
 	spc = (struct sctp_paddr_change *)
-		skb_put(event->parent,
-			sizeof(struct sctp_paddr_change));
+		skb_put(event->parent, sizeof(struct sctp_paddr_change));
 
 	/* Sockets API Extensions for SCTP
 	 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
@@ -287,12 +285,13 @@
 	/* Socket Extensions for SCTP
 	 * 5.3.1.1 SCTP_ASSOC_CHANGE
 	 *
-	 * sac_assoc_id: sizeof (sctp_assoc_t)
+	 * spc_assoc_id: sizeof (sctp_assoc_t)
 	 *
 	 * The association id field, holds the identifier for the association.
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
+	sctp_ulpevent_set_owner(event->parent, asoc);
 	spc->spc_assoc_id = sctp_assoc2id(asoc);
 
 	/* Sockets API Extensions for SCTP
@@ -360,9 +359,8 @@
 
 	/* Embed the event fields inside the cloned skb.  */
 	event = (sctp_ulpevent_t *) skb->cb;
-	event = sctp_ulpevent_init(event,
-				   skb,
-				   MSG_NOTIFICATION);
+	event = sctp_ulpevent_init(event, skb, MSG_NOTIFICATION);
+
 	if (!event)
 		goto fail;
 
@@ -418,6 +416,7 @@
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
+	sctp_ulpevent_set_owner(event->parent, asoc);
 	sre->sre_assoc_id = sctp_assoc2id(asoc);
 
 	return event;
@@ -515,9 +514,7 @@
 	 * The original send information associated with the undelivered
 	 * message.
 	 */
-	memcpy(&ssf->ssf_info,
-	       &chunk->sinfo,
-	       sizeof(struct sctp_sndrcvinfo));
+	memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo));
 
 	/* Socket Extensions for SCTP
 	 * 5.3.1.4 SCTP_SEND_FAILED
@@ -528,8 +525,8 @@
 	 * same association identifier.  For TCP style socket, this field is
 	 * ignored.
 	 */
+	sctp_ulpevent_set_owner(event->parent, asoc);
 	ssf->ssf_assoc_id = sctp_assoc2id(asoc);
-
 	return event;
 
 fail:
@@ -541,22 +538,21 @@
  * Socket Extensions for SCTP - draft-01
  * 5.3.1.5 SCTP_SHUTDOWN_EVENT
  */
-sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *asoc,
-						   __u16 flags,
-						   int priority)
+sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(
+	const sctp_association_t *asoc,
+	__u16 flags,
+	int priority)
 {
 	sctp_ulpevent_t *event;
 	struct sctp_shutdown_event *sse;
 
 	event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
-				  MSG_NOTIFICATION,
-				  priority);
+				  MSG_NOTIFICATION, priority);
 	if (!event)
 		goto fail;
 
 	sse = (struct sctp_shutdown_event *)
-		skb_put(event->parent,
-			sizeof(struct sctp_shutdown_event));
+		skb_put(event->parent, sizeof(struct sctp_shutdown_event));
 
 	/* Socket Extensions for SCTP
 	 * 5.3.1.5 SCTP_SHUTDOWN_EVENT
@@ -591,6 +587,7 @@
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
+	sctp_ulpevent_set_owner(event->parent, asoc);
 	sse->sse_assoc_id = sctp_assoc2id(asoc);
 
 	return event;
@@ -607,8 +604,7 @@
  * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
  */
 sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
-					   sctp_chunk_t *chunk,
-					   int priority)
+					   sctp_chunk_t *chunk, int priority)
 {
 	sctp_ulpevent_t *event;
 	struct sctp_sndrcvinfo *info;
@@ -619,7 +615,7 @@
 	skb = skb_clone(chunk->skb, priority);
 	if (!skb)
 		goto fail;
-		
+
 	/* First calculate the padding, so we don't inadvertently
 	 * pass up the wrong length to the user.
 	 *
@@ -645,7 +641,7 @@
 	event = (sctp_ulpevent_t *) skb->cb;
 
 	/* Initialize event with flags 0.  */
-	event = sctp_ulpevent_init(event, skb, 0); 
+	event = sctp_ulpevent_init(event, skb, 0);
 	if (!event)
 		goto fail_init;
 
@@ -818,23 +814,33 @@
 		asoc->rwnd_over = skb->len - asoc->rwnd;
 		asoc->rwnd = 0;
 	}
-
 	SCTP_DEBUG_PRINTK("rwnd decreased by %d to (%u, %u)\n",
 			  skb->len, asoc->rwnd, asoc->rwnd_over);
 }
 
+/* A simple destructor to give up the reference to the association. */
+static void sctp_ulpevent_rfree(struct sk_buff *skb)
+{
+	sctp_ulpevent_t *event;	
+	
+	event = (sctp_ulpevent_t *)skb->cb;
+	sctp_association_put(event->asoc);
+}
 
+/* Hold the association in case the msg_name needs read out of 
+ * the association. 
+ */
+static void sctp_ulpevent_set_owner(struct sk_buff *skb,
+				    const sctp_association_t *asoc)
+{
+	sctp_ulpevent_t *event;
 
-
-
-
-
-
-
-
-
-
-
-
-
-
+	/* Cast away the const, as we are just wanting to
+	 * bump the reference count.
+	 */
+	sctp_association_hold((sctp_association_t *)asoc);
+	skb->sk = asoc->base.sk;
+	event = (sctp_ulpevent_t *)skb->cb;
+	event->asoc = (sctp_association_t *)asoc;
+	skb->destructor = sctp_ulpevent_rfree;
+}
diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c	Fri Sep 27 14:51:05 2002
+++ b/net/sctp/ulpqueue.c	Fri Sep 27 14:51:05 2002
@@ -5,38 +5,38 @@
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
- * 
+ *
  * This abstraction carries sctp events to the ULP (sockets).
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    Jon Grimm             <jgrimm@us.ibm.com>
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Sridhar Samudrala     <sri@us.ibm.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -131,7 +131,7 @@
 			    int priority)
 {
 	struct sk_buff_head temp;
-	sctp_data_chunk_t *hdr;	
+	sctp_data_chunk_t *hdr;
 	sctp_ulpevent_t *event;
 
 	hdr = (sctp_data_chunk_t *) chunk->chunk_hdr;
@@ -157,7 +157,7 @@
 
 		event = sctp_ulpqueue_order(ulpq, event);
 	}
-	
+
 	/* Send event to the ULP.  */
 	if (event)
 		sctp_ulpqueue_tail_event(ulpq, event);
@@ -449,7 +449,7 @@
 
 	/* Check if this message needs ordering.  */
 	if (SCTP_DATA_UNORDERED & event->chunk_flags)
-		return event;	       
+		return event;
 
 	/* Note: The stream ID must be verified before this routine.  */
 	sid = event->sndrcvinfo.sinfo_stream;
diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c	Fri Sep 27 14:51:05 2002
+++ b/net/x25/af_x25.c	Fri Sep 27 14:51:05 2002
@@ -1,8 +1,9 @@
 /*
  *	X.25 Packet Layer release 002
  *
- *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
- *	releases, misbehave and/or generally screw up. It might even work. 
+ *	This is ALPHA test software. This code may break your machine,
+ *	randomly fail to work with new releases, misbehave and/or generally
+ *	screw up. It might even work. 
  *
  *	This code REQUIRES 2.1.15 or higher
  *
@@ -68,9 +69,10 @@
 
 static struct proto_ops x25_proto_ops;
 
-static x25_address null_x25_address = {"               "};
+static struct x25_address null_x25_address = {"               "};
 
-int x25_addr_ntoa(unsigned char *p, x25_address *called_addr, x25_address *calling_addr)
+int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
+		  struct x25_address *calling_addr)
 {
 	int called_len, calling_len;
 	char *called, *calling;
@@ -101,13 +103,13 @@
 		}
 	}
 
-	*called  = '\0';
-	*calling = '\0';
+	*called = *calling = '\0';
 
 	return 1 + (called_len + calling_len + 1) / 2;
 }
 
-int x25_addr_aton(unsigned char *p, x25_address *called_addr, x25_address *calling_addr)
+int x25_addr_aton(unsigned char *p, struct x25_address *called_addr,
+		  struct x25_address *calling_addr)
 {
 	unsigned int called_len, calling_len;
 	char *called, *calling;
@@ -155,22 +157,16 @@
 	save_flags(flags);
 	cli();
 
-	if ((s = x25_list) == sk) {
+	if ((s = x25_list) == sk)
 		x25_list = s->next;
-		restore_flags(flags);
-		return;
-	}
-
-	while (s != NULL && s->next != NULL) {
+	else while (s && s->next) {
 		if (s->next == sk) {
 			s->next = sk->next;
-			restore_flags(flags);
-			return;
+			break;
 		}
 
 		s = s->next;
 	}
-
 	restore_flags(flags);
 }
 
@@ -181,7 +177,7 @@
 {
 	struct sock *s;
 
-	for (s = x25_list; s != NULL; s = s->next)
+	for (s = x25_list; s; s = s->next)
 		if (x25_sk(s)->neighbour && x25_sk(s)->neighbour->dev == dev)
 			x25_disconnect(s, ENETUNREACH, 0, 0);
 }
@@ -191,7 +187,7 @@
  */
 static int x25_device_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *)ptr;
+	struct net_device *dev = ptr;
 	struct x25_neigh *neigh;
 
 	if (dev->type == ARPHRD_X25
@@ -238,7 +234,7 @@
  *	Find a socket that wants to accept the Call Request we just
  *	received.
  */
-static struct sock *x25_find_listener(x25_address *addr)
+static struct sock *x25_find_listener(struct x25_address *addr)
 {
 	unsigned long flags;
 	struct sock *s;
@@ -246,17 +242,14 @@
 	save_flags(flags);
 	cli();
 
-	for (s = x25_list; s != NULL; s = s->next) {
+	for (s = x25_list; s; s = s->next)
 		if ((!strcmp(addr->x25_addr, x25_sk(s)->source_addr.x25_addr) ||
-		     strcmp(addr->x25_addr, null_x25_address.x25_addr) == 0) &&
-		     s->state == TCP_LISTEN) {
-			restore_flags(flags);
-			return s;
-		}
-	}
+		     !strcmp(addr->x25_addr, null_x25_address.x25_addr)) &&
+		     s->state == TCP_LISTEN)
+			break;
 
 	restore_flags(flags);
-	return NULL;
+	return s;
 }
 
 /*
@@ -270,15 +263,12 @@
 	save_flags(flags);
 	cli();
 
-	for (s = x25_list; s != NULL; s = s->next) {
-		if (x25_sk(s)->lci == lci && x25_sk(s)->neighbour == neigh) {
-			restore_flags(flags);
-			return s;
-		}
-	}
+	for (s = x25_list; s; s = s->next)
+		if (x25_sk(s)->lci == lci && x25_sk(s)->neighbour == neigh)
+			break;
 
 	restore_flags(flags);
-	return NULL;
+	return s;
 }
 
 /*
@@ -288,10 +278,11 @@
 {
 	unsigned int lci = 1;
 
-	while (x25_find_socket(lci, neigh) != NULL) {
-		lci++;
-		if (lci == 4096) return 0;
-	}
+	while (x25_find_socket(lci, neigh))
+		if (++lci == 4096) {
+			lci = 0;
+			break;
+		}
 
 	return lci;
 }
@@ -339,7 +330,7 @@
 		kfree_skb(skb);
 	}
 
-	if (atomic_read(&sk->wmem_alloc) != 0 || atomic_read(&sk->rmem_alloc) != 0) {
+	if (atomic_read(&sk->wmem_alloc) || atomic_read(&sk->rmem_alloc)) {
 		/* Defer: outstanding buffers */
 		init_timer(&sk->timer);
 		sk->timer.expires  = jiffies + 10 * HZ;
@@ -360,75 +351,71 @@
  */
 
 static int x25_setsockopt(struct socket *sock, int level, int optname,
-	char *optval, int optlen)
+			  char *optval, int optlen)
 {
-	struct sock *sk = sock->sk;
 	int opt;
+	struct sock *sk = sock->sk;
+	int rc = -ENOPROTOOPT;
 
-	if (level != SOL_X25)
-		return -ENOPROTOOPT;
+	if (level != SOL_X25 || optname != X25_QBITINCL)
+		goto out;
 
+	rc = -EINVAL;
 	if (optlen < sizeof(int))
-		return-EINVAL;
+		goto out;
 
+	rc = -EFAULT;
 	if (get_user(opt, (int *)optval))
-		return -EFAULT;
+		goto out;
 
-	switch (optname) {
-		case X25_QBITINCL:
-			x25_sk(sk)->qbitincl = opt ? 1 : 0;
-			return 0;
-
-		default:
-			return -ENOPROTOOPT;
-	}
+	x25_sk(sk)->qbitincl = !!opt;
+	rc = 0;
+out:
+	return rc;
 }
 
 static int x25_getsockopt(struct socket *sock, int level, int optname,
-	char *optval, int *optlen)
+			  char *optval, int *optlen)
 {
 	struct sock *sk = sock->sk;
-	int val = 0;
-	int len; 
+	int val, len, rc = -ENOPROTOOPT;
 	
-	if (level != SOL_X25)
-		return -ENOPROTOOPT;
+	if (level != SOL_X25 || optname != X25_QBITINCL)
+		goto out;
 
+	rc = -EFAULT;
 	if (get_user(len, optlen))
-		return -EFAULT;
-
-	switch (optname) {
-		case X25_QBITINCL:
-			val = x25_sk(sk)->qbitincl;
-			break;
-
-		default:
-			return -ENOPROTOOPT;
-	}
+		goto out;
 
 	len = min_t(unsigned int, len, sizeof(int));
 
+	rc = -EINVAL;
 	if (len < 0)
-		return -EINVAL;
+		goto out;
 		
+	rc = -EFAULT;
 	if (put_user(len, optlen))
-		return -EFAULT;
+		goto out;
 
-	return copy_to_user(optval, &val, len) ? -EFAULT : 0;
+	val = x25_sk(sk)->qbitincl;
+	rc = copy_to_user(optval, &val, len) ? -EFAULT : 0;
+out:
+	return rc;
 }
 
 static int x25_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
+	int rc = -EOPNOTSUPP;
 
 	if (sk->state != TCP_LISTEN) {
 		memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN);
 		sk->max_ack_backlog = backlog;
 		sk->state           = TCP_LISTEN;
-		return 0;
+		rc = 0;
 	}
 
-	return -EOPNOTSUPP;
+	return rc;
 }
 
 static struct sock *x25_alloc_socket(void)
@@ -445,7 +432,7 @@
 	if (!x25)
 		goto frees;
 
-	memset(x25, 0x00, sizeof(*x25));
+	memset(x25, 0, sizeof(*x25));
 
 	x25->sk = sk;
 
@@ -455,10 +442,13 @@
 	skb_queue_head_init(&x25->fragment_queue);
 	skb_queue_head_init(&x25->interrupt_in_queue);
 	skb_queue_head_init(&x25->interrupt_out_queue);
-out:	return sk;
-frees:	sk_free(sk);
+out:
+	return sk;
+frees:
+	sk_free(sk);
 	sk = NULL;
-decmod:	MOD_DEC_USE_COUNT;
+decmod:
+	MOD_DEC_USE_COUNT;
 	goto out;
 }
 
@@ -466,12 +456,14 @@
 {
 	struct sock *sk;
 	x25_cb *x25;
+	int rc = -ESOCKTNOSUPPORT;
 
-	if (sock->type != SOCK_SEQPACKET || protocol != 0)
-		return -ESOCKTNOSUPPORT;
+	if (sock->type != SOCK_SEQPACKET || protocol)
+		goto out;
 
+	rc = -ENOMEM;
 	if ((sk = x25_alloc_socket()) == NULL)
-		return -ENOMEM;
+		goto out;
 
 	x25 = x25_sk(sk);
 
@@ -495,20 +487,21 @@
 	x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
 	x25->facilities.throughput  = X25_DEFAULT_THROUGHPUT;
 	x25->facilities.reverse     = X25_DEFAULT_REVERSE;
-
-	return 0;
+	rc = 0;
+out:
+	return rc;
 }
 
 static struct sock *x25_make_new(struct sock *osk)
 {
-	struct sock *sk;
+	struct sock *sk = NULL;
 	x25_cb *x25, *ox25;
 
 	if (osk->type != SOCK_SEQPACKET)
-		return NULL;
+		goto out;
 
 	if ((sk = x25_alloc_socket()) == NULL)
-		return NULL;
+		goto out;
 
 	x25 = x25_sk(sk);
 
@@ -533,7 +526,7 @@
 	x25->qbitincl   = ox25->qbitincl;
 
 	init_timer(&x25->timer);
-
+out:
 	return sk;
 }
 
@@ -542,7 +535,8 @@
 	struct sock *sk = sock->sk;
 	x25_cb *x25;
 
-	if (sk == NULL) return 0;
+	if (!sk)
+		goto out;
 
 	x25 = x25_sk(sk);
 
@@ -567,14 +561,11 @@
 			sk->dead                = 1;
 			sk->destroy             = 1;
 			break;
-
-		default:
-			break;
 	}
 
 	sock->sk   = NULL;	
 	sk->socket = NULL;	/* Not used, but we should do this */
-
+out:
 	return 0;
 }
 
@@ -583,21 +574,14 @@
 	struct sock *sk = sock->sk;
 	struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
 
-	if (sk->zapped == 0)
-		return -EINVAL;
-
-	if (addr_len != sizeof(struct sockaddr_x25))
-		return -EINVAL;
-
-	if (addr->sx25_family != AF_X25)
+	if (!sk->zapped ||
+	    addr_len != sizeof(struct sockaddr_x25) ||
+	    addr->sx25_family != AF_X25)
 		return -EINVAL;
 
 	x25_sk(sk)->source_addr = addr->sx25_addr;
-
 	x25_insert_socket(sk);
-
 	sk->zapped = 0;
-
 	SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
 
 	return 0;
@@ -609,42 +593,49 @@
 	x25_cb *x25 = x25_sk(sk);
 	struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
 	struct net_device *dev;
+	int rc = 0;
 
 	if (sk->state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
 		sock->state = SS_CONNECTED;
-		return 0;	/* Connect completed during a ERESTARTSYS event */
+		goto out;	/* Connect completed during a ERESTARTSYS event */
 	}
 
+	rc = -ECONNREFUSED;
 	if (sk->state == TCP_CLOSE && sock->state == SS_CONNECTING) {
 		sock->state = SS_UNCONNECTED;
-		return -ECONNREFUSED;
+		goto out;
 	}
 
+	rc = -EISCONN;	/* No reconnect on a seqpacket socket */
 	if (sk->state == TCP_ESTABLISHED)
-		return -EISCONN;	/* No reconnect on a seqpacket socket */
+		goto out;
 
 	sk->state   = TCP_CLOSE;	
 	sock->state = SS_UNCONNECTED;
 
-	if (addr_len != sizeof(struct sockaddr_x25))
-		return -EINVAL;
-
-	if (addr->sx25_family != AF_X25)
-		return -EINVAL;
-
-	if ((dev = x25_get_route(&addr->sx25_addr)) == NULL)
-		return -ENETUNREACH;
-
-	if ((x25->neighbour = x25_get_neigh(dev)) == NULL)
-		return -ENETUNREACH;
+	rc = -EINVAL;
+	if (addr_len != sizeof(struct sockaddr_x25) ||
+	    addr->sx25_family != AF_X25)
+		goto out;
+
+	rc = -ENETUNREACH;
+	dev = x25_get_route(&addr->sx25_addr);
+	if (!dev)
+		goto out;
+
+	x25->neighbour = x25_get_neigh(dev);
+	if (!x25->neighbour)
+		goto out;
 
 	x25_limit_facilities(&x25->facilities, x25->neighbour);
 
-	if ((x25->lci = x25_new_lci(x25->neighbour)) == 0)
-		return -ENETUNREACH;
+	x25->lci = x25_new_lci(x25->neighbour);
+	if (!x25->lci)
+		goto out;
 
+	rc = -EINVAL;
 	if (sk->zapped)		/* Must bind first - autobinding does not work */
-		return -EINVAL;
+		goto out;
 
 	if (!strcmp(x25->source_addr.x25_addr, null_x25_address.x25_addr))
 		memset(&x25->source_addr, '\0', X25_ADDR_LEN);
@@ -663,49 +654,50 @@
 	x25_start_t21timer(sk);
 
 	/* Now the loop */
+	rc = -EINPROGRESS;
 	if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
-		return -EINPROGRESS;
+		goto out;
 
 	cli();	/* To avoid races on the sleep */
 
 	/*
 	 * A Clear Request or timeout or failed routing will go to closed.
 	 */
+	rc = -ERESTARTSYS;
 	while (sk->state == TCP_SYN_SENT) {
+		/* FIXME: going to sleep with interrupts disabled */
 		interruptible_sleep_on(sk->sleep);
-		if (signal_pending(current)) {
-			sti();
-			return -ERESTARTSYS;
-		}
+		if (signal_pending(current))
+			goto out_unlock;
 	}
 
 	if (sk->state != TCP_ESTABLISHED) {
-		sti();
 		sock->state = SS_UNCONNECTED;
-		return sock_error(sk);	/* Always set at this point */
+		rc = sock_error(sk);	/* Always set at this point */
+		goto out_unlock;
 	}
 
 	sock->state = SS_CONNECTED;
-
+	rc = 0;
+out_unlock:
 	sti();
-
-	return 0;
+out:
+	return rc;
 }
 	
 static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
 {
-	struct sock *sk;
+	struct sock *sk = sock->sk;
 	struct sock *newsk;
 	struct sk_buff *skb;
+	int rc = -EINVAL;
 
-	if ((sk = sock->sk) == NULL)
-		return -EINVAL;
+	if (!sk || sk->state != TCP_LISTEN)
+		goto out;
 
+	rc = -EOPNOTSUPP;
 	if (sk->type != SOCK_SEQPACKET)
-		return -EOPNOTSUPP;
-
-	if (sk->state != TCP_LISTEN)
-		return -EINVAL;
+		goto out;
 
 	/*
 	 *	The write queue this time is holding sockets ready to use
@@ -714,32 +706,35 @@
 	do {
 		cli();
 		if ((skb = skb_dequeue(&sk->receive_queue)) == NULL) {
-			if (flags & O_NONBLOCK) {
-				sti();
-				return -EWOULDBLOCK;
-			}
+			rc = -EWOULDBLOCK;
+			if (flags & O_NONBLOCK)
+				goto out_unlock;
+			/* FIXME: going to sleep with interrupts disabled */
 			interruptible_sleep_on(sk->sleep);
-			if (signal_pending(current)) {
-				sti();
-				return -ERESTARTSYS;
-			}
+			rc = -ERESTARTSYS;
+			if (signal_pending(current))
+				goto out_unlock;
 		}
-	} while (skb == NULL);
+	} while (!skb);
 
-	newsk = skb->sk;
-	newsk->pair = NULL;
+	newsk	      = skb->sk;
+	newsk->pair   = NULL;
 	newsk->socket = newsock;
-	newsk->sleep = &newsock->wait;
+	newsk->sleep  = &newsock->wait;
 	sti();
 
 	/* Now attach up the new socket */
 	skb->sk = NULL;
 	kfree_skb(skb);
 	sk->ack_backlog--;
-	newsock->sk = newsk;
+	newsock->sk    = newsk;
 	newsock->state = SS_CONNECTED;
-
-	return 0;
+	rc = 0;
+out:
+	return rc;
+out_unlock:
+	sti();
+	goto out;
 }
 
 static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
@@ -748,16 +743,15 @@
 	struct sock *sk = sock->sk;
 	x25_cb *x25 = x25_sk(sk);
 
-	if (peer != 0) {
+	if (peer) {
 		if (sk->state != TCP_ESTABLISHED)
 			return -ENOTCONN;
 		sx25->sx25_addr = x25->dest_addr;
-	} else {
+	} else
 		sx25->sx25_addr = x25->source_addr;
-	}
 
 	sx25->sx25_family = AF_X25;
-	*uaddr_len = sizeof(struct sockaddr_x25);
+	*uaddr_len = sizeof(*sx25);
 
 	return 0;
 }
@@ -767,9 +761,9 @@
 	struct sock *sk;
 	struct sock *make;
 	x25_cb *makex25;
-	x25_address source_addr, dest_addr;
+	struct x25_address source_addr, dest_addr;
 	struct x25_facilities facilities;
-	int len;
+	int len, rc;
 
 	/*
 	 *	Remove the LCI and frame type.
@@ -790,18 +784,14 @@
 	/*
 	 *	We can't accept the Call Request.
 	 */
-	if (sk == NULL || sk->ack_backlog == sk->max_ack_backlog) {
-		x25_transmit_clear_request(neigh, lci, 0x01);
-		return 0;
-	}
+	if (!sk || sk->ack_backlog == sk->max_ack_backlog)
+		goto out_clear_request;
 
 	/*
 	 *	Try to reach a compromise on the requested facilities.
 	 */
-	if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1) {
-		x25_transmit_clear_request(neigh, lci, 0x01);
-		return 0;
-	}
+	if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1)
+		goto out_clear_request;
 
 	/*
 	 * current neighbour/link might impose additional limits
@@ -813,10 +803,9 @@
 	/*
 	 *	Try to create a new socket.
 	 */
-	if ((make = x25_make_new(sk)) == NULL) {
-		x25_transmit_clear_request(neigh, lci, 0x01);
-		return 0;
-	}
+	make = x25_make_new(sk);
+	if (!make)
+		goto out_clear_request;
 
 	/*
 	 *	Remove the facilities, leaving any Call User Data.
@@ -857,8 +846,13 @@
 
 	if (!sk->dead)
 		sk->data_ready(sk, skb->len);
-
-	return 1;
+	rc = 1;
+out:
+	return rc;
+out_clear_request:
+	rc = 0;
+	x25_transmit_clear_request(neigh, lci, 0x01);
+	goto out;
 }
 
 static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
@@ -866,46 +860,53 @@
 	struct sock *sk = sock->sk;
 	x25_cb *x25 = x25_sk(sk);
 	struct sockaddr_x25 *usx25 = (struct sockaddr_x25 *)msg->msg_name;
-	int err;
 	struct sockaddr_x25 sx25;
 	struct sk_buff *skb;
 	unsigned char *asmptr;
-	int size, qbit = 0;
+	int noblock = msg->msg_flags & MSG_DONTWAIT;
+	int size, qbit = 0, rc = -EINVAL;
 
 	if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
-		return -EINVAL;
+		goto out;
 
 	/* we currently don't support segmented records at the user interface */
 	if (!(msg->msg_flags & (MSG_EOR|MSG_OOB)))
-		return -EINVAL;
+		goto out;
 
+	rc = -EADDRNOTAVAIL;
 	if (sk->zapped)
-		return -EADDRNOTAVAIL;
+		goto out;
 
+	rc = -EPIPE;
 	if (sk->shutdown & SEND_SHUTDOWN) {
 		send_sig(SIGPIPE, current, 0);
-		return -EPIPE;
+		goto out;
 	}
 
-	if (x25->neighbour == NULL)
-		return -ENETUNREACH;
+	rc = -ENETUNREACH;
+	if (!x25->neighbour)
+		goto out;
 
-	if (usx25 != NULL) {
+	if (usx25) {
+		rc = -EINVAL;
 		if (msg->msg_namelen < sizeof(sx25))
-			return -EINVAL;
-		sx25 = *usx25;
+			goto out;
+		memcpy(&sx25, usx25, sizeof(sx25));
+		rc = -EISCONN;
 		if (strcmp(x25->dest_addr.x25_addr, sx25.sx25_addr.x25_addr))
-			return -EISCONN;
+			goto out;
+		rc = -EINVAL;
 		if (sx25.sx25_family != AF_X25)
-			return -EINVAL;
+			goto out;
 	} else {
 		/*
 		 *	FIXME 1003.1g - if the socket is like this because
 		 *	it has become closed (not started closed) we ought
 		 *	to SIGPIPE, EPIPE;
 		 */
+		rc = -ENOTCONN;
 		if (sk->state != TCP_ESTABLISHED)
-			return -ENOTCONN;
+			goto out;
 
 		sx25.sx25_family = AF_X25;
 		sx25.sx25_addr   = x25->dest_addr;
@@ -921,8 +922,9 @@
 
 	size = len + X25_MAX_L2_LEN + X25_EXT_MIN_LEN;
 
-	if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
-		return err;
+	skb = sock_alloc_send_skb(sk, size, noblock, &rc);
+	if (!skb)
+		goto out;
 	X25_SKB_CB(skb)->flags = msg->msg_flags;
 
 	skb_reserve(skb, X25_MAX_L2_LEN + X25_EXT_MIN_LEN);
@@ -934,7 +936,9 @@
 
 	asmptr = skb->h.raw = skb_put(skb, len);
 
-	memcpy_fromiovec(asmptr, msg->msg_iov, len);
+	rc = memcpy_fromiovec(asmptr, msg->msg_iov, len);
+	if (rc)
+		goto out_kfree_skb;
 
 	/*
 	 *	If the Q BIT Include socket option is in force, the first
@@ -985,21 +989,18 @@
 	SOCK_DEBUG(sk, "x25_sendmsg: Built header.\n");
 	SOCK_DEBUG(sk, "x25_sendmsg: Transmitting buffer\n");
 
-	if (sk->state != TCP_ESTABLISHED) {
-		kfree_skb(skb);
-		return -ENOTCONN;
-	}
+	rc = -ENOTCONN;
+	if (sk->state != TCP_ESTABLISHED)
+		goto out_kfree_skb;
 
-	if (msg->msg_flags & MSG_OOB) {
+	if (msg->msg_flags & MSG_OOB)
 		skb_queue_tail(&x25->interrupt_out_queue, skb);
-	} else {
+	else {
 	        len = x25_output(sk, skb);
-		if(len<0){
+		if (len < 0)
 			kfree_skb(skb);
-		} else {
-			if (x25->qbitincl)
-				len++;
-		}
+		else if (x25->qbitincl)
+			len++;
 	}
 
 	/*
@@ -1019,12 +1020,17 @@
 	lock_sock(sk);
 	x25_kick(sk);
 	release_sock(sk);
-
-	return len;
+	rc = len;
+out:
+	return rc;
+out_kfree_skb:
+	kfree_skb(skb);
+	goto out;
 }
 
 
-static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
+static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size,
+		       int flags, struct scm_cookie *scm)
 {
 	struct sock *sk = sock->sk;
 	x25_cb *x25 = x25_sk(sk);
@@ -1032,18 +1038,19 @@
 	int copied, qbit;
 	struct sk_buff *skb;
 	unsigned char *asmptr;
-	int er;
+	int rc = -ENOTCONN;
 
 	/*
 	 * This works for seqpacket too. The receiver has ordered the queue for
 	 * us! We do one quick check first though
 	 */
 	if (sk->state != TCP_ESTABLISHED)
-		return -ENOTCONN;
+		goto out;
 
 	if (flags & MSG_OOB) {
+		rc = -EINVAL;
 		if (sk->urginline || !skb_peek(&x25->interrupt_in_queue))
-			return -EINVAL;
+			goto out;
 
 		skb = skb_dequeue(&x25->interrupt_in_queue);
 
@@ -1060,8 +1067,9 @@
 		msg->msg_flags |= MSG_OOB;
 	} else {
 		/* Now we can treat all alike */
-		if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &er)) == NULL)
-			return er;
+		skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &rc);
+		if (!skb)
+			goto out;
 
 		qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
 
@@ -1086,21 +1094,25 @@
 	/* Currently, each datagram always contains a complete record */ 
 	msg->msg_flags |= MSG_EOR;
 
-	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	if (rc)
+		goto out_free_dgram;
 
-	if (sx25 != NULL) {
+	if (sx25) {
 		sx25->sx25_family = AF_X25;
 		sx25->sx25_addr   = x25->dest_addr;
 	}
 
 	msg->msg_namelen = sizeof(struct sockaddr_x25);
 
-	skb_free_datagram(sk, skb);
 	lock_sock(sk);
 	x25_check_rbuf(sk);
 	release_sock(sk);
-
-	return copied;
+	rc = copied;
+out_free_dgram:
+	skb_free_datagram(sk, skb);
+out:
+	return rc;
 }
 
 
@@ -1108,6 +1120,7 @@
 {
 	struct sock *sk = sock->sk;
 	x25_cb *x25 = x25_sk(sk);
+	int rc;
 
 	switch (cmd) {
 		case TIOCOUTQ: {
@@ -1115,26 +1128,33 @@
 			amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
 			if (amount < 0)
 				amount = 0;
-			return put_user(amount, (unsigned int *)arg);
+			rc = put_user(amount, (unsigned int *)arg);
+			break;
 		}
 
 		case TIOCINQ: {
 			struct sk_buff *skb;
 			int amount = 0;
-			/* These two are safe on a single CPU system as only user tasks fiddle here */
+			/*
+			 * These two are safe on a single CPU system as
+			 * only user tasks fiddle here
+			 */
 			if ((skb = skb_peek(&sk->receive_queue)) != NULL)
 				amount = skb->len;
-			return put_user(amount, (unsigned int *)arg);
+			rc = put_user(amount, (unsigned int *)arg);
+			break;
 		}
 
 		case SIOCGSTAMP:
-			if (sk != NULL) {
-				if (sk->stamp.tv_sec == 0)
-					return -ENOENT;
-				return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
+			if (sk) {
+				rc = -ENOENT;
+				if (!sk->stamp.tv_sec)
+					break;
+				rc = copy_to_user((void *)arg, &sk->stamp,
+						  sizeof(struct timeval)) ? -EFAULT : 0;
 			}
-			return -EINVAL;
-
+			rc = -EINVAL;
+			break;
 		case SIOCGIFADDR:
 		case SIOCSIFADDR:
 		case SIOCGIFDSTADDR:
@@ -1145,74 +1165,90 @@
 		case SIOCSIFNETMASK:
 		case SIOCGIFMETRIC:
 		case SIOCSIFMETRIC:
-			return -EINVAL;
-
+			rc = -EINVAL;
+			break;
 		case SIOCADDRT:
 		case SIOCDELRT:
-			if (!capable(CAP_NET_ADMIN)) return -EPERM;
-			return x25_route_ioctl(cmd, (void *)arg);
-
+			rc = -EPERM;
+			if (!capable(CAP_NET_ADMIN))
+				break;
+			rc = x25_route_ioctl(cmd, (void *)arg);
+			break;
 		case SIOCX25GSUBSCRIP:
-			return x25_subscr_ioctl(cmd, (void *)arg);
-
+			rc = x25_subscr_ioctl(cmd, (void *)arg);
+			break;
 		case SIOCX25SSUBSCRIP:
-			if (!capable(CAP_NET_ADMIN)) return -EPERM;
-			return x25_subscr_ioctl(cmd, (void *)arg);
-
+			rc = -EPERM;
+			if (!capable(CAP_NET_ADMIN))
+				break;
+			rc = x25_subscr_ioctl(cmd, (void *)arg);
+			break;
 		case SIOCX25GFACILITIES: {
-			struct x25_facilities facilities;
-			facilities = x25->facilities;
-			return copy_to_user((void *)arg, &facilities, sizeof(facilities)) ? -EFAULT : 0;
+			struct x25_facilities fac = x25->facilities;
+			rc = copy_to_user((void *)arg, &fac, sizeof(fac)) ? -EFAULT : 0;
+			break;
 		}
 
 		case SIOCX25SFACILITIES: {
 			struct x25_facilities facilities;
+			rc = -EFAULT;
 			if (copy_from_user(&facilities, (void *)arg, sizeof(facilities)))
-				return -EFAULT;
+				break;
+			rc = -EINVAL;
 			if (sk->state != TCP_LISTEN && sk->state != TCP_CLOSE)
-				return -EINVAL;
-			if (facilities.pacsize_in < X25_PS16 || facilities.pacsize_in > X25_PS4096)
-				return -EINVAL;
-			if (facilities.pacsize_out < X25_PS16 || facilities.pacsize_out > X25_PS4096)
-				return -EINVAL;
-			if (facilities.winsize_in < 1 || facilities.winsize_in > 127)
-				return -EINVAL;
-			if (facilities.throughput < 0x03 || facilities.throughput > 0xDD)
-				return -EINVAL;
-			if (facilities.reverse != 0 && facilities.reverse != 1)
-				return -EINVAL;
+				break;
+			if (facilities.pacsize_in < X25_PS16 ||
+			    facilities.pacsize_in > X25_PS4096)
+				break;
+			if (facilities.pacsize_out < X25_PS16 ||
+			    facilities.pacsize_out > X25_PS4096)
+				break;
+			if (facilities.winsize_in < 1 ||
+			    facilities.winsize_in > 127)
+				break;
+			if (facilities.throughput < 0x03 ||
+			    facilities.throughput > 0xDD)
+				break;
+			if (facilities.reverse && facilities.reverse != 1)
+				break;
 			x25->facilities = facilities;
-			return 0;
+			rc = 0;
+			break;
 		}
 
 		case SIOCX25GCALLUSERDATA: {
-			struct x25_calluserdata calluserdata;
-			calluserdata = x25->calluserdata;
-			return copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata)) ? -EFAULT : 0;
+			struct x25_calluserdata cud = x25->calluserdata;
+			rc = copy_to_user((void *)arg, &cud, sizeof(cud)) ? -EFAULT : 0;
+			break;
 		}
 
 		case SIOCX25SCALLUSERDATA: {
 			struct x25_calluserdata calluserdata;
+
+			rc = -EFAULT;
 			if (copy_from_user(&calluserdata, (void *)arg, sizeof(calluserdata)))
-				return -EFAULT;
+				break;
+			rc = -EINVAL;
 			if (calluserdata.cudlength > X25_MAX_CUD_LEN)
-				return -EINVAL;
+				break;
 			x25->calluserdata = calluserdata;
-			return 0;
+			rc = 0;
+			break;
 		}
 
 		case SIOCX25GCAUSEDIAG: {
 			struct x25_causediag causediag;
 			causediag = x25->causediag;
-			return copy_to_user((void *)arg, &causediag, sizeof(causediag)) ? -EFAULT : 0;
+			rc = copy_to_user((void *)arg, &causediag, sizeof(causediag)) ? -EFAULT : 0;
+			break;
 		}
 
  		default:
-			return dev_ioctl(cmd, (void *)arg);
+			rc = dev_ioctl(cmd, (void *)arg);
+			break;
 	}
 
-	/*NOTREACHED*/
-	return 0;
+	return rc;
 }
 
 static int x25_get_info(char *buffer, char **start, off_t offset, int length)
@@ -1220,15 +1256,16 @@
 	struct sock *s;
 	struct net_device *dev;
 	const char *devname;
-	int len = 0;
+	int len;
 	off_t pos = 0;
 	off_t begin = 0;
 
 	cli();
 
-	len += sprintf(buffer, "dest_addr  src_addr   dev   lci st vs vr va   t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
+	len = sprintf(buffer, "dest_addr  src_addr   dev   lci st vs vr va   "
+			      "t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
 
-	for (s = x25_list; s != NULL; s = s->next) {
+	for (s = x25_list; s; s = s->next) {
 		x25_cb *x25 = x25_sk(s);
 
 		if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
@@ -1236,7 +1273,9 @@
 		else
 			devname = x25->neighbour->dev->name;
 
-		len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X  %d  %d  %d  %d %3lu %3lu %3lu %3lu %3lu %5d %5d %ld\n",
+		len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X  %d  %d  "
+					     "%d  %d %3lu %3lu %3lu %3lu %3lu "
+					     "%5d %5d %ld\n",
 			!x25->dest_addr.x25_addr[0] ? "*" :
 						x25->dest_addr.x25_addr,
 			!x25->source_addr.x25_addr[0] ? "*" :
@@ -1254,7 +1293,7 @@
 			x25->t23 / HZ,
 			atomic_read(&s->wmem_alloc),
 			atomic_read(&s->rmem_alloc),
-			s->socket != NULL ? SOCK_INODE(s->socket)->i_ino : 0L);
+			s->socket ? SOCK_INODE(s->socket)->i_ino : 0L);
 
 		pos = begin + len;
 
@@ -1272,9 +1311,10 @@
 	*start = buffer + (offset - begin);
 	len   -= (offset - begin);
 
-	if (len > length) len = length;
+	if (len > length)
+		len = length;
 
-	return(len);
+	return len;
 } 
 
 struct net_proto_family x25_family_ops = {
@@ -1308,22 +1348,21 @@
 
 
 static struct packet_type x25_packet_type = {
-	.type =		__constant_htons(ETH_P_X25),
-	.func =		x25_lapb_receive_frame,
+	.type =	__constant_htons(ETH_P_X25),
+	.func =	x25_lapb_receive_frame,
 };
 
 struct notifier_block x25_dev_notifier = {
-	.notifier_call =x25_device_event,
+	.notifier_call = x25_device_event,
 };
 
 void x25_kill_by_neigh(struct x25_neigh *neigh)
 {
 	struct sock *s;
 
-	for( s=x25_list; s != NULL; s=s->next){
+	for (s = x25_list; s; s = s->next)
 		if (x25_sk(s)->neighbour == neigh)
 			x25_disconnect(s, ENETUNREACH, 0, 0);
-	} 
 }
 
 static int __init x25_init(void)
@@ -1351,7 +1390,7 @@
 	 *	Register any pre existing devices.
 	 */
 	read_lock(&dev_base_lock);
-	for (dev = dev_base; dev != NULL; dev = dev->next) {
+	for (dev = dev_base; dev; dev = dev->next) {
 		if ((dev->flags & IFF_UP) && (dev->type == ARPHRD_X25
 #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
 					   || dev->type == ARPHRD_ETHER
diff -Nru a/net/x25/sysctl_net_x25.c b/net/x25/sysctl_net_x25.c
--- a/net/x25/sysctl_net_x25.c	Fri Sep 27 14:51:04 2002
+++ b/net/x25/sysctl_net_x25.c	Fri Sep 27 14:51:04 2002
@@ -13,38 +13,88 @@
 #include <linux/init.h>
 #include <net/x25.h>
 
-static int min_timer[] = {1   * HZ};
-static int max_timer[] = {300 * HZ};
+static int min_timer[] = {   1 * HZ };
+static int max_timer[] = { 300 * HZ };
 
 static struct ctl_table_header *x25_table_header;
 
-static ctl_table x25_table[] = {
-        {NET_X25_RESTART_REQUEST_TIMEOUT, "restart_request_timeout",
-         &sysctl_x25_restart_request_timeout, sizeof(int), 0644, NULL,
-         &proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer},
-        {NET_X25_CALL_REQUEST_TIMEOUT, "call_request_timeout",
-         &sysctl_x25_call_request_timeout, sizeof(int), 0644, NULL,
-         &proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer},
-        {NET_X25_RESET_REQUEST_TIMEOUT, "reset_request_timeout",
-         &sysctl_x25_reset_request_timeout, sizeof(int), 0644, NULL,
-         &proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer},
-        {NET_X25_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout",
-         &sysctl_x25_clear_request_timeout, sizeof(int), 0644, NULL,
-         &proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer},
-        {NET_X25_ACK_HOLD_BACK_TIMEOUT, "acknowledgement_hold_back_timeout",
-         &sysctl_x25_ack_holdback_timeout, sizeof(int), 0644, NULL,
-         &proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer},
-	{0}
+static struct ctl_table x25_table[] = {
+        {
+		.ctl_name =	NET_X25_RESTART_REQUEST_TIMEOUT,
+		.procname =	"restart_request_timeout",
+		.data =		&sysctl_x25_restart_request_timeout,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	&proc_dointvec_minmax,
+		.strategy =	&sysctl_intvec,
+		.extra1 =	&min_timer,
+		.extra2 =	&max_timer,
+	},
+        {
+		.ctl_name =	NET_X25_CALL_REQUEST_TIMEOUT,
+		.procname =	"call_request_timeout",
+		.data =		&sysctl_x25_call_request_timeout,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	&proc_dointvec_minmax,
+		.strategy =	&sysctl_intvec,
+		.extra1 =	&min_timer,
+		.extra2 =	&max_timer,
+	},
+        {
+		.ctl_name =	NET_X25_RESET_REQUEST_TIMEOUT,
+		.procname =	"reset_request_timeout",
+		.data =		&sysctl_x25_reset_request_timeout,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	&proc_dointvec_minmax,
+		.strategy =	&sysctl_intvec,
+		.extra1 =	&min_timer,
+		.extra2 =	&max_timer,
+	},
+        {
+		.ctl_name =	NET_X25_CLEAR_REQUEST_TIMEOUT,
+		.procname =	"clear_request_timeout",
+		.data =		&sysctl_x25_clear_request_timeout,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	&proc_dointvec_minmax,
+		.strategy =	&sysctl_intvec,
+		.extra1 =	&min_timer,
+		.extra2 =	&max_timer,
+	},
+        {
+		.ctl_name =	NET_X25_ACK_HOLD_BACK_TIMEOUT,
+		.procname =	"acknowledgement_hold_back_timeout",
+		.data =		&sysctl_x25_ack_holdback_timeout,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	&proc_dointvec_minmax,
+		.strategy =	&sysctl_intvec,
+		.extra1 =	&min_timer,
+		.extra2 =	&max_timer,
+	},
+	{ 0, },
 };
 
-static ctl_table x25_dir_table[] = {
-	{NET_X25, "x25", NULL, 0, 0555, x25_table},
-	{0}
+static struct ctl_table x25_dir_table[] = {
+	{
+		.ctl_name =	NET_X25,
+		.procname =	"x25",
+		.mode =		0555,
+		.child =	x25_table,
+	},
+	{ 0, },
 };
 
-static ctl_table x25_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, x25_dir_table},
-	{0}
+static struct ctl_table x25_root_table[] = {
+	{
+		.ctl_name =	CTL_NET,
+		.procname =	"net",
+		.mode =		0555,
+		.child =	x25_dir_table,
+	},
+	{ 0, },
 };
 
 void __init x25_register_sysctl(void)
diff -Nru a/net/x25/x25_in.c b/net/x25/x25_in.c
--- a/net/x25/x25_in.c	Fri Sep 27 14:51:05 2002
+++ b/net/x25/x25_in.c	Fri Sep 27 14:51:05 2002
@@ -1,8 +1,9 @@
 /*
  *	X.25 Packet Layer release 002
  *
- *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
- *	releases, misbehave and/or generally screw up. It might even work. 
+ *	This is ALPHA test software. This code may break your machine,
+ *	randomly fail to work with new releases, misbehave and/or generally
+ *	screw up. It might even work. 
  *
  *	This code REQUIRES 2.1.15 or higher
  *
@@ -86,7 +87,7 @@
 	skb_set_owner_r(skbn, sk);
 	skb_queue_tail(&sk->receive_queue, skbn);
 	if (!sk->dead)
-		sk->data_ready(sk,skbn->len);
+		sk->data_ready(sk, skbn->len);
 
 	return 0;
 }
@@ -98,7 +99,7 @@
  */
 static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
 {
-	x25_address source_addr, dest_addr;
+	struct x25_address source_addr, dest_addr;
 
 	switch (frametype) {
 		case X25_CALL_ACCEPTED: {
@@ -364,10 +365,10 @@
 
 int x25_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 {
-	int queued;
+	int queued = x25_process_rx_frame(sk, skb);
 
-	queued = x25_process_rx_frame(sk,skb);
-	if(!queued) kfree_skb(skb);
+	if (!queued)
+		kfree_skb(skb);
 
 	return 0;
 }
diff -Nru a/net/x25/x25_route.c b/net/x25/x25_route.c
--- a/net/x25/x25_route.c	Fri Sep 27 14:51:04 2002
+++ b/net/x25/x25_route.c	Fri Sep 27 14:51:04 2002
@@ -1,8 +1,9 @@
 /*
  *	X.25 Packet Layer release 002
  *
- *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
- *	releases, misbehave and/or generally screw up. It might even work. 
+ *	This is ALPHA test software. This code may break your machine,
+ *	randomly fail to work with new releases, misbehave and/or generally
+ *	screw up. It might even work. 
  *
  *	This code REQUIRES 2.1.15 or higher
  *
@@ -43,22 +44,27 @@
 #include <linux/init.h>
 #include <net/x25.h>
 
-static struct x25_route *x25_route_list /* = NULL initially */;
+static struct x25_route *x25_route_list; /* = NULL initially */
 
 /*
  *	Add a new route.
  */
-static int x25_add_route(x25_address *address, unsigned int sigdigits, struct net_device *dev)
+static int x25_add_route(struct x25_address *address, unsigned int sigdigits,
+			 struct net_device *dev)
 {
 	struct x25_route *x25_route;
 	unsigned long flags;
+	int rc = -EINVAL;
 
-	for (x25_route = x25_route_list; x25_route != NULL; x25_route = x25_route->next)
-		if (memcmp(&x25_route->address, address, sigdigits) == 0 && x25_route->sigdigits == sigdigits)
-			return -EINVAL;
-
-	if ((x25_route = kmalloc(sizeof(*x25_route), GFP_ATOMIC)) == NULL)
-		return -ENOMEM;
+	for (x25_route = x25_route_list; x25_route; x25_route = x25_route->next)
+		if (!memcmp(&x25_route->address, address, sigdigits) &&
+		    x25_route->sigdigits == sigdigits)
+			goto out;
+
+	x25_route = kmalloc(sizeof(*x25_route), GFP_ATOMIC);
+	rc = -ENOMEM;
+	if (!x25_route)
+		goto out;
 
 	strcpy(x25_route->address.x25_addr, "000000000000000");
 	memcpy(x25_route->address.x25_addr, address->x25_addr, sigdigits);
@@ -70,8 +76,9 @@
 	x25_route->next = x25_route_list;
 	x25_route_list  = x25_route;
 	restore_flags(flags);
-
-	return 0;
+	rc = 0;
+out:
+	return rc;
 }
 
 static void x25_remove_route(struct x25_route *x25_route)
@@ -85,36 +92,41 @@
 	if ((s = x25_route_list) == x25_route) {
 		x25_route_list = x25_route->next;
 		restore_flags(flags);
-		kfree(x25_route);
 		return;
 	}
 
-	while (s != NULL && s->next != NULL) {
+	while (s && s->next) {
 		if (s->next == x25_route) {
 			s->next = x25_route->next;
-			restore_flags(flags);
-			kfree(x25_route);
-			return;
+			goto out_kfree_route;
 		}
 
 		s = s->next;
 	}
-
+out:
 	restore_flags(flags);
+	return;
+out_kfree_route:
+	kfree(x25_route);
+	goto out;
 }
 
-static int x25_del_route(x25_address *address, unsigned int sigdigits, struct net_device *dev)
+static int x25_del_route(struct x25_address *address, unsigned int sigdigits,
+			 struct net_device *dev)
 {
-	struct x25_route *x25_route;
+	struct x25_route *x25_route = x25_route_list;
+	int rc = -EINVAL;
 
-	for (x25_route = x25_route_list; x25_route != NULL; x25_route = x25_route->next) {
-		if (memcmp(&x25_route->address, address, sigdigits) == 0 && x25_route->sigdigits == sigdigits && x25_route->dev == dev) {
+	for (; x25_route; x25_route = x25_route->next)
+		if (!memcmp(&x25_route->address, address, sigdigits) &&
+		    x25_route->sigdigits == sigdigits &&
+		    x25_route->dev == dev) {
 			x25_remove_route(x25_route);
-			return 0;
+			rc = 0;
+			break;
 		}
-	}
 
-	return -EINVAL;
+	return rc;
 }
 
 /*
@@ -124,7 +136,7 @@
 {
 	struct x25_route *route, *x25_route = x25_route_list;
 
-	while (x25_route != NULL) {
+	while (x25_route) {
 		route     = x25_route;
 		x25_route = x25_route->next;
 
@@ -138,42 +150,35 @@
  */
 struct net_device *x25_dev_get(char *devname)
 {
-	struct net_device *dev;
-
-	if ((dev = dev_get_by_name(devname)) == NULL)
-		return NULL;
+	struct net_device *dev = dev_get_by_name(devname);
 
-	if ((dev->flags & IFF_UP) && (dev->type == ARPHRD_X25
+	if (dev &&
+	    (!(dev->flags & IFF_UP) || (dev->type != ARPHRD_X25
 #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
-	   || dev->type == ARPHRD_ETHER
+					&& dev->type != ARPHRD_ETHER
 #endif
-	   ))
-		return dev;
+					)))
+		dev_put(dev);
 
-	dev_put(dev);
-
-	return NULL;
+	return dev;
 }
 
 /*
  *	Find a device given an X.25 address.
  */
-struct net_device *x25_get_route(x25_address *addr)
+struct net_device *x25_get_route(struct x25_address *addr)
 {
 	struct x25_route *route, *use = NULL;
 
-	for (route = x25_route_list; route != NULL; route = route->next) {
-		if (memcmp(&route->address, addr, route->sigdigits) == 0) {
-			if (use == NULL) {
+	for (route = x25_route_list; route; route = route->next)
+		if (!memcmp(&route->address, addr, route->sigdigits)) {
+			if (!use)
+				use = route;
+			else if (route->sigdigits > use->sigdigits)
 				use = route;
-			} else {
-				if (route->sigdigits > use->sigdigits)
-					use = route;
-			}
 		}
-	}
 
-	return (use != NULL) ? use->dev : NULL;
+	return use ? use->dev : NULL;
 }
 
 /*
@@ -183,55 +188,48 @@
 {
 	struct x25_route_struct x25_route;
 	struct net_device *dev;
-	int err;
+	int rc = -EINVAL;
 
-	switch (cmd) {
+	if (cmd != SIOCADDRT && cmd != SIOCDELRT)
+		goto out;
 
-		case SIOCADDRT:
-			if (copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct)))
-				return -EFAULT;
-			if (x25_route.sigdigits < 0 || x25_route.sigdigits > 15)
-				return -EINVAL;
-			if ((dev = x25_dev_get(x25_route.device)) == NULL)
-				return -EINVAL;
-			err = x25_add_route(&x25_route.address, x25_route.sigdigits, dev);
-			dev_put(dev);
-			return err;
-
-		case SIOCDELRT:
-			if (copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct)))
-				return -EFAULT;
-			if (x25_route.sigdigits < 0 || x25_route.sigdigits > 15)
-				return -EINVAL;
-			if ((dev = x25_dev_get(x25_route.device)) == NULL)
-				return -EINVAL;
-			err = x25_del_route(&x25_route.address, x25_route.sigdigits, dev);
-			dev_put(dev);
-			return err;
-
-		default:
-			return -EINVAL;
-	}
-
-	return 0;
+	rc = -EFAULT;
+	if (copy_from_user(&x25_route, arg, sizeof(x25_route)))
+		goto out;
+
+	rc = -EINVAL;
+	if (x25_route.sigdigits < 0 || x25_route.sigdigits > 15)
+		goto out;
+
+	dev = x25_dev_get(x25_route.device);
+	if (!dev)
+		goto out;
+
+	if (cmd == SIOCADDRT)
+		rc = x25_add_route(&x25_route.address, x25_route.sigdigits, dev);
+	else
+		rc = x25_del_route(&x25_route.address, x25_route.sigdigits, dev);
+	dev_put(dev);
+out:
+	return rc;
 }
 
 int x25_routes_get_info(char *buffer, char **start, off_t offset, int length)
 {
 	struct x25_route *x25_route;
-	int len     = 0;
+	int len;
 	off_t pos   = 0;
 	off_t begin = 0;
 
 	cli();
 
-	len += sprintf(buffer, "address          digits  device\n");
+	len = sprintf(buffer, "address          digits  device\n");
 
-	for (x25_route = x25_route_list; x25_route != NULL; x25_route = x25_route->next) {
+	for (x25_route = x25_route_list; x25_route; x25_route = x25_route->next) {
 		len += sprintf(buffer + len, "%-15s  %-6d  %-5s\n",
-			x25_route->address.x25_addr,
-			x25_route->sigdigits,
-			(x25_route->dev != NULL) ? x25_route->dev->name : "???");
+			       x25_route->address.x25_addr,
+			       x25_route->sigdigits,
+			       x25_route->dev ? x25_route->dev->name : "???");
 
 		pos = begin + len;
 
@@ -249,7 +247,8 @@
 	*start = buffer + (offset - begin);
 	len   -= (offset - begin);
 
-	if (len > length) len = length;
+	if (len > length)
+		len = length;
 
 	return len;
 } 
@@ -261,7 +260,7 @@
 {
 	struct x25_route *route, *x25_route = x25_route_list;
 
-	while (x25_route != NULL) {
+	while (x25_route) {
 		route     = x25_route;
 		x25_route = x25_route->next;
 
