## Automatically generated incremental diff
## From:   linux-2.5.73-bk5
## To:     linux-2.5.73-bk6
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.5.73-bk5/Makefile linux-2.5.73-bk6/Makefile
--- linux-2.5.73-bk5/Makefile	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/Makefile	2003-06-28 04:53:17.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 73
-EXTRAVERSION = -bk5
+EXTRAVERSION = -bk6
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.73-bk5/arch/alpha/Kconfig linux-2.5.73-bk6/arch/alpha/Kconfig
--- linux-2.5.73-bk5/arch/alpha/Kconfig	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/alpha/Kconfig	2003-06-28 04:53:17.000000000 -0700
@@ -679,42 +679,8 @@
 
 source "drivers/isdn/Kconfig"
 
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-	---help---
-	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-	  here, otherwise N. Read the CD-ROM-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about these CD-ROM drives. If you are unsure what you
-	  have, say Y and find out whether you have one of the following
-	  drives.
-
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
-	  exists. Especially in cases where you do not know exactly which kind
-	  of drive you have you should read there. Most of these drivers use a
-	  file drivers/cdrom/{driver_name}.h where you can define your
-	  interface parameters and switch some internal goodies.
-
-	  All these CD-ROM drivers are also usable as a module ( = code which
-	  can be inserted in and removed from the running kernel whenever you
-	  want). If you want to compile them as module, say M instead of Y and
-	  read <file:Documentation/modules.txt>.
-
-	  If you want to use any of these CD-ROM drivers, you also have to
-	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-	  answer will get "defaulted" for you if you enable any of the Linux
-	  CD-ROM drivers).
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
 source "drivers/input/Kconfig"
 
 source "drivers/char/Kconfig"
diff -urN linux-2.5.73-bk5/arch/cris/Kconfig linux-2.5.73-bk6/arch/cris/Kconfig
--- linux-2.5.73-bk5/arch/cris/Kconfig	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/cris/Kconfig	2003-06-28 04:53:17.000000000 -0700
@@ -549,42 +549,8 @@
 
 source "drivers/telephony/Kconfig"
 
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-	---help---
-	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-	  here, otherwise N. Read the CD-ROM-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about these CD-ROM drives. If you are unsure what you
-	  have, say Y and find out whether you have one of the following
-	  drives.
-
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
-	  exists. Especially in cases where you do not know exactly which kind
-	  of drive you have you should read there. Most of these drivers use a
-	  file drivers/cdrom/{driver_name}.h where you can define your
-	  interface parameters and switch some internal goodies.
-
-	  All these CD-ROM drivers are also usable as a module ( = code which
-	  can be inserted in and removed from the running kernel whenever you
-	  want). If you want to compile them as module, say M instead of Y and
-	  read <file:Documentation/modules.txt>.
-
-	  If you want to use any of these CD-ROM drivers, you also have to
-	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-	  answer will get "defaulted" for you if you enable any of the Linux
-	  CD-ROM drivers).
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
 #
 # input before char - char/joystick depends on it. As does USB.
 #
diff -urN linux-2.5.73-bk5/arch/i386/Kconfig linux-2.5.73-bk6/arch/i386/Kconfig
--- linux-2.5.73-bk5/arch/i386/Kconfig	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/i386/Kconfig	2003-06-28 04:53:17.000000000 -0700
@@ -1208,43 +1208,8 @@
 
 source "drivers/scsi/Kconfig"
 
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-	depends on ISA
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-	---help---
-	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-	  here, otherwise N. Read the CD-ROM-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about these CD-ROM drives. If you are unsure what you
-	  have, say Y and find out whether you have one of the following
-	  drives.
-
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
-	  exists. Especially in cases where you do not know exactly which kind
-	  of drive you have you should read there. Most of these drivers use a
-	  file drivers/cdrom/{driver_name}.h where you can define your
-	  interface parameters and switch some internal goodies.
-
-	  All these CD-ROM drivers are also usable as a module ( = code which
-	  can be inserted in and removed from the running kernel whenever you
-	  want). If you want to compile them as module, say M instead of Y and
-	  read <file:Documentation/modules.txt>.
-
-	  If you want to use any of these CD-ROM drivers, you also have to
-	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-	  answer will get "defaulted" for you if you enable any of the Linux
-	  CD-ROM drivers).
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
 source "drivers/md/Kconfig"
 
 source "drivers/message/fusion/Kconfig"
diff -urN linux-2.5.73-bk5/arch/i386/kernel/io_apic.c linux-2.5.73-bk6/arch/i386/kernel/io_apic.c
--- linux-2.5.73-bk5/arch/i386/kernel/io_apic.c	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/i386/kernel/io_apic.c	2003-06-28 04:53:17.000000000 -0700
@@ -1300,7 +1300,6 @@
 		reg_03.raw = io_apic_read(apic, 3);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
-	printk("\n");
 	printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
 	printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
 	printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
diff -urN linux-2.5.73-bk5/arch/ia64/Kconfig linux-2.5.73-bk6/arch/ia64/Kconfig
--- linux-2.5.73-bk5/arch/ia64/Kconfig	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/ia64/Kconfig	2003-06-28 04:53:17.000000000 -0700
@@ -568,42 +568,8 @@
 
 source "drivers/isdn/Kconfig"
 
-
-menu "CD-ROM drivers (not for SCSI or IDE/ATAPI drives)"
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-	---help---
-	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-	  here, otherwise N. Read the CD-ROM-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about these CD-ROM drives. If you are unsure what you
-	  have, say Y and find out whether you have one of the following
-	  drives.
-
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
-	  exists. Especially in cases where you do not know exactly which kind
-	  of drive you have you should read there. Most of these drivers use a
-	  file drivers/cdrom/{driver_name}.h where you can define your
-	  interface parameters and switch some internal goodies.
-
-	  All these CD-ROM drivers are also usable as a module ( = code which
-	  can be inserted in and removed from the running kernel whenever you
-	  want). If you want to compile them as module, say M instead of Y and
-	  read <file:Documentation/modules.txt>.
-
-	  If you want to use any of these CD-ROM drivers, you also have to
-	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-	  answer will get "defaulted" for you if you enable any of the Linux
-	  CD-ROM drivers).
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
 #
 # input before char - char/joystick depends on it. As does USB.
 #
diff -urN linux-2.5.73-bk5/arch/m68knommu/Kconfig linux-2.5.73-bk6/arch/m68knommu/Kconfig
--- linux-2.5.73-bk5/arch/m68knommu/Kconfig	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/m68knommu/Kconfig	2003-06-28 04:53:17.000000000 -0700
@@ -530,44 +530,8 @@
 
 source "drivers/scsi/Kconfig"
 
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-	depends on ISA
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-	---help---
-	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-	  here, otherwise N. Read the CD-ROM-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about these CD-ROM drives. If you are unsure what you
-	  have, say Y and find out whether you have one of the following
-	  drives.
-
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
-	  exists. Especially in cases where you do not know exactly which kind
-	  of drive you have you should read there. Most of these drivers use a
-	  file drivers/cdrom/{driver_name}.h where you can define your
-	  interface parameters and switch some internal goodies.
-
-	  All these CD-ROM drivers are also usable as a module ( = code which
-	  can be inserted in and removed from the running kernel whenever you
-	  want). If you want to compile them as module, say M instead of Y and
-	  read <file:Documentation/modules.txt>.
-
-	  If you want to use any of these CD-ROM drivers, you also have to
-	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-	  answer will get "defaulted" for you if you enable any of the Linux
-	  CD-ROM drivers).
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
-
 source "drivers/md/Kconfig"
 
 source "drivers/message/fusion/Kconfig"
diff -urN linux-2.5.73-bk5/arch/m68knommu/kernel/traps.c linux-2.5.73-bk6/arch/m68knommu/kernel/traps.c
--- linux-2.5.73-bk5/arch/m68knommu/kernel/traps.c	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk6/arch/m68knommu/kernel/traps.c	2003-06-28 04:53:17.000000000 -0700
@@ -82,7 +82,7 @@
 
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
-	show_stack((unsigned long *)fp);
+	show_stack(NULL, (unsigned long *)fp);
 	do_exit(SIGSEGV);
 }
 
@@ -106,7 +106,7 @@
 
 int kstack_depth_to_print = 48;
 
-void show_stack(unsigned long *esp)
+void show_stack(struct task_struct *task, unsigned long *esp)
 {
 	unsigned long *stack, *endstack, addr;
 	extern char _start, _etext;
diff -urN linux-2.5.73-bk5/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S linux-2.5.73-bk6/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S
--- linux-2.5.73-bk5/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S	2003-06-22 11:32:38.000000000 -0700
+++ linux-2.5.73-bk6/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S	2003-06-28 04:53:17.000000000 -0700
@@ -96,6 +96,7 @@
 	movec	%d0, %CACR			/* Enable cache */
 
 
+#ifdef CONFIG_ROMFS_FS
 	/*
 	 *	Move ROM filesystem above bss :-)
 	 */
@@ -117,6 +118,12 @@
 	cmp.l	%a0, %a2			/* Check if at end */
 	bne	_copy_romfs
 
+#else /* CONFIG_ROMFS_FS */
+	lea.l	_ebss, %a1
+	move.l	%a1, _ramstart
+#endif /* CONFIG_ROMFS_FS */
+
+
 	/*
 	 *	Zero out the bss region.
 	 */
diff -urN linux-2.5.73-bk5/arch/m68knommu/platform/5272/NETtel/crt0_ram.S linux-2.5.73-bk6/arch/m68knommu/platform/5272/NETtel/crt0_ram.S
--- linux-2.5.73-bk5/arch/m68knommu/platform/5272/NETtel/crt0_ram.S	2003-06-22 11:33:08.000000000 -0700
+++ linux-2.5.73-bk6/arch/m68knommu/platform/5272/NETtel/crt0_ram.S	2003-06-28 04:53:17.000000000 -0700
@@ -116,6 +116,8 @@
 	movec	%d0, %CACR			/* Enable cache */
 	nop
 
+
+#ifdef CONFIG_ROMFS_FS
 #ifdef CONFIG_ROMFS_FROM_ROM
 	/*
 	 *	check for an in RAM romfs
@@ -160,6 +162,12 @@
   done_romfs:
 #endif
 
+#else /* CONFIG_ROMFS_FS */
+	lea.l	_ebss, %a1
+	move.l	%a1, _ramstart
+#endif /* CONFIG_ROMFS_FS */
+
+
 	/*
 	 *	Zero out the bss region.
 	 */
diff -urN linux-2.5.73-bk5/arch/mips/Kconfig-shared linux-2.5.73-bk6/arch/mips/Kconfig-shared
--- linux-2.5.73-bk5/arch/mips/Kconfig-shared	2003-06-28 04:53:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/mips/Kconfig-shared	2003-06-28 04:53:17.000000000 -0700
@@ -1218,43 +1218,8 @@
 
 source "drivers/scsi/Kconfig"
 
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-	depends on ISA
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-	---help---
-	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-	  here, otherwise N. Read the CD-ROM-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about these CD-ROM drives. If you are unsure what you
-	  have, say Y and find out whether you have one of the following
-	  drives.
-
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
-	  exists. Especially in cases where you do not know exactly which kind
-	  of drive you have you should read there. Most of these drivers use a
-	  file drivers/cdrom/{driver_name}.h where you can define your
-	  interface parameters and switch some internal goodies.
-
-	  All these CD-ROM drivers are also usable as a module ( = code which
-	  can be inserted in and removed from the running kernel whenever you
-	  want). If you want to compile them as module, say M instead of Y and
-	  read <file:Documentation/modules.txt>.
-
-	  If you want to use any of these CD-ROM drivers, you also have to
-	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-	  answer will get "defaulted" for you if you enable any of the Linux
-	  CD-ROM drivers).
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
 source "drivers/md/Kconfig"
 
 source "drivers/message/fusion/Kconfig"
diff -urN linux-2.5.73-bk5/arch/ppc/Kconfig linux-2.5.73-bk6/arch/ppc/Kconfig
--- linux-2.5.73-bk5/arch/ppc/Kconfig	2003-06-28 04:53:13.000000000 -0700
+++ linux-2.5.73-bk6/arch/ppc/Kconfig	2003-06-28 04:53:17.000000000 -0700
@@ -1193,15 +1193,8 @@
 
 source "drivers/video/Kconfig"
 
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
 source "drivers/input/Kconfig"
 
 
diff -urN linux-2.5.73-bk5/arch/s390/defconfig linux-2.5.73-bk6/arch/s390/defconfig
--- linux-2.5.73-bk5/arch/s390/defconfig	2003-06-22 11:33:12.000000000 -0700
+++ linux-2.5.73-bk6/arch/s390/defconfig	2003-06-28 04:53:17.000000000 -0700
@@ -68,6 +68,11 @@
 # CONFIG_PCMCIA is not set
 
 #
+# Generic Driver Options
+#
+# CONFIG_FW_LOADER is not set
+
+#
 # SCSI support
 #
 # CONFIG_SCSI is not set
@@ -166,6 +171,7 @@
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_TUNNEL is not set
 # CONFIG_XFRM_USER is not set
 
 #
diff -urN linux-2.5.73-bk5/arch/s390/kernel/compat_ioctl.c linux-2.5.73-bk6/arch/s390/kernel/compat_ioctl.c
--- linux-2.5.73-bk5/arch/s390/kernel/compat_ioctl.c	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk6/arch/s390/kernel/compat_ioctl.c	2003-06-28 04:53:17.000000000 -0700
@@ -42,12 +42,15 @@
 #include <linux/random.h>
 #include <linux/raw.h>
 #include <linux/route.h>
+#include <linux/rtc.h>
 #include <linux/vt.h>
 #include <linux/watchdog.h>
 
 #include <linux/auto_fs.h>
+#include <linux/auto_fs4.h>
 #include <linux/devfs_fs.h>
 #include <linux/ext2_fs.h>
+#include <linux/ncp_fs.h>
 #include <linux/smb_fs.h>
 
 #include <linux/if_bonding.h>
diff -urN linux-2.5.73-bk5/arch/s390/kernel/compat_linux.c linux-2.5.73-bk6/arch/s390/kernel/compat_linux.c
--- linux-2.5.73-bk5/arch/s390/kernel/compat_linux.c	2003-06-22 11:33:08.000000000 -0700
+++ linux-2.5.73-bk6/arch/s390/kernel/compat_linux.c	2003-06-28 04:53:17.000000000 -0700
@@ -2193,7 +2193,6 @@
    sorts of things, like timeval and itimerval.  */
 
 extern struct timezone sys_tz;
-extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
 
 asmlinkage int sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
@@ -2210,13 +2209,27 @@
 	return 0;
 }
 
+static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+{
+	long usec;
+
+	if (!access_ok(VERIFY_READ, i, sizeof(*i)))
+		return -EFAULT;
+	if (__get_user(o->tv_sec, &i->tv_sec))
+		return -EFAULT;
+	if (__get_user(usec, &i->tv_usec))
+		return -EFAULT;
+	o->tv_nsec = usec * 1000;
+	return 0;
+}
+
 asmlinkage int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
-	struct timeval ktv;
+	struct timespec kts;
 	struct timezone ktz;
 
  	if (tv) {
-		if (get_tv32(&ktv, tv))
+		if (get_ts32(&kts, tv))
 			return -EFAULT;
 	}
 	if (tz) {
@@ -2224,7 +2237,7 @@
 			return -EFAULT;
 	}
 
-	return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
+	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
 }
 
 asmlinkage int sys_utimes(char *, struct timeval *);
diff -urN linux-2.5.73-bk5/arch/s390/kernel/smp.c linux-2.5.73-bk6/arch/s390/kernel/smp.c
--- linux-2.5.73-bk5/arch/s390/kernel/smp.c	2003-06-22 11:32:28.000000000 -0700
+++ linux-2.5.73-bk6/arch/s390/kernel/smp.c	2003-06-28 04:53:17.000000000 -0700
@@ -419,8 +419,6 @@
 	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
         current_thread_info()->cpu = 0;
         num_cpus = 1;
-	cpu_possible_map = 1;
-	cpu_online_map = 1;
         for (curr_cpu = 0;
              curr_cpu <= 65535 && num_cpus < max_cpus; curr_cpu++) {
                 if ((__u16) curr_cpu == boot_cpu_addr)
diff -urN linux-2.5.73-bk5/arch/s390/kernel/syscalls.S linux-2.5.73-bk6/arch/s390/kernel/syscalls.S
--- linux-2.5.73-bk5/arch/s390/kernel/syscalls.S	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk6/arch/s390/kernel/syscalls.S	2003-06-28 04:53:17.000000000 -0700
@@ -118,7 +118,7 @@
 SYSCALL(sys_newlstat,sys_newlstat,compat_sys_newlstat_wrapper)
 SYSCALL(sys_newfstat,sys_newfstat,compat_sys_newfstat_wrapper)
 NI_SYSCALL							/* old uname syscall */
-NI_SYSCALL							/* 110 iopl for i386 */
+NI_SYSCALL							/* reserved for sys_lookup_dcache */
 SYSCALL(sys_vhangup,sys_vhangup,sys_vhangup)
 NI_SYSCALL							/* old "idle" system call */
 NI_SYSCALL							/* vm86old for i386 */
diff -urN linux-2.5.73-bk5/arch/s390/kernel/traps.c linux-2.5.73-bk6/arch/s390/kernel/traps.c
--- linux-2.5.73-bk5/arch/s390/kernel/traps.c	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk6/arch/s390/kernel/traps.c	2003-06-28 04:53:17.000000000 -0700
@@ -78,7 +78,7 @@
 
 #endif /* CONFIG_ARCH_S390X */
 
-void show_trace(unsigned long * stack)
+void show_trace(struct task_struct *task, unsigned long * stack)
 {
 	unsigned long backchain, low_addr, high_addr, ret_addr;
 
@@ -109,10 +109,10 @@
 	 */
 	if (tsk->state == TASK_RUNNING)
 		return;
-	show_trace((unsigned long *) tsk->thread.ksp);
+	show_trace(tsk, (unsigned long *) tsk->thread.ksp);
 }
 
-void show_stack(unsigned long *sp)
+void show_stack(struct task_struct *task, unsigned long *sp)
 {
 	unsigned long *stack;
 	int i;
@@ -132,7 +132,7 @@
 		printk("%p ", (void *)*stack++);
 	}
 	printk("\n");
-	show_trace(sp);
+	show_trace(task, sp);
 }
 
 /*
@@ -140,7 +140,7 @@
  */
 void dump_stack(void)
 {
-	show_stack(0);
+	show_stack(current, 0);
 }
 
 void show_registers(struct pt_regs *regs)
diff -urN linux-2.5.73-bk5/arch/sh/Kconfig linux-2.5.73-bk6/arch/sh/Kconfig
--- linux-2.5.73-bk5/arch/sh/Kconfig	2003-06-28 04:53:13.000000000 -0700
+++ linux-2.5.73-bk6/arch/sh/Kconfig	2003-06-28 04:53:17.000000000 -0700
@@ -779,42 +779,8 @@
 
 source "drivers/scsi/Kconfig"
 
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-
-config CD_NO_IDESCSI
-	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-	---help---
-	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-	  here, otherwise N. Read the CD-ROM-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about these CD-ROM drives. If you are unsure what you
-	  have, say Y and find out whether you have one of the following
-	  drives.
-
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
-	  exists. Especially in cases where you do not know exactly which kind
-	  of drive you have you should read there. Most of these drivers use a
-	  file drivers/cdrom/{driver_name}.h where you can define your
-	  interface parameters and switch some internal goodies.
-
-	  All these CD-ROM drivers are also usable as a module ( = code which
-	  can be inserted in and removed from the running kernel whenever you
-	  want). If you want to compile them as module, say M instead of Y and
-	  read <file:Documentation/modules.txt>.
-
-	  If you want to use any of these CD-ROM drivers, you also have to
-	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-	  answer will get "defaulted" for you if you enable any of the Linux
-	  CD-ROM drivers).
-
 source "drivers/cdrom/Kconfig"
 
-endmenu
-
 source "drivers/md/Kconfig"
 
 source "drivers/ieee1394/Kconfig"
diff -urN linux-2.5.73-bk5/drivers/cdrom/Kconfig linux-2.5.73-bk6/drivers/cdrom/Kconfig
--- linux-2.5.73-bk5/drivers/cdrom/Kconfig	2003-06-22 11:33:11.000000000 -0700
+++ linux-2.5.73-bk6/drivers/cdrom/Kconfig	2003-06-28 04:53:18.000000000 -0700
@@ -1,6 +1,39 @@
 #
 # CDROM driver configuration
 #
+
+menu "Old CD-ROM drivers (not SCSI, not IDE)"
+	depends on ISA
+
+config CD_NO_IDESCSI
+	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
+	---help---
+	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
+	  here, otherwise N. Read the CD-ROM-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  Note that the answer to this question doesn't directly affect the
+	  kernel: saying N will just cause the configurator to skip all
+	  the questions about these CD-ROM drives. If you are unsure what you
+	  have, say Y and find out whether you have one of the following
+	  drives.
+
+	  For each of these drivers, a file Documentation/cdrom/{driver_name}
+	  exists. Especially in cases where you do not know exactly which kind
+	  of drive you have you should read there. Most of these drivers use a
+	  file drivers/cdrom/{driver_name}.h where you can define your
+	  interface parameters and switch some internal goodies.
+
+	  All these CD-ROM drivers are also usable as a module ( = code which
+	  can be inserted in and removed from the running kernel whenever you
+	  want). If you want to compile them as module, say M instead of Y and
+	  read <file:Documentation/modules.txt>.
+
+	  If you want to use any of these CD-ROM drivers, you also have to
+	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
+	  answer will get "defaulted" for you if you enable any of the Linux
+	  CD-ROM drivers).
+
 config AZTCD
 	tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM  CDROM support"
 	depends on CD_NO_IDESCSI
@@ -248,3 +281,4 @@
 	  The module will be called sonycd535. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
+endmenu
diff -urN linux-2.5.73-bk5/drivers/ide/ide-dma.c linux-2.5.73-bk6/drivers/ide/ide-dma.c
--- linux-2.5.73-bk5/drivers/ide/ide-dma.c	2003-06-22 11:32:46.000000000 -0700
+++ linux-2.5.73-bk6/drivers/ide/ide-dma.c	2003-06-28 04:53:18.000000000 -0700
@@ -248,8 +248,11 @@
 #if 1
 	if (sector_count > 256)
 		BUG();
-		
+
 	if (sector_count > 128) {
+#else
+	while (sector_count > 128) {
+#endif
 		memset(&sg[nents], 0, sizeof(*sg));
 		sg[nents].page = virt_to_page(virt_addr);
 		sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
@@ -263,22 +266,7 @@
 	sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
 	sg[nents].length =  sector_count  * SECTOR_SIZE;
 	nents++;
-#else
-        while (sector_count > 128) {
-		memset(&sg[nents], 0, sizeof(*sg));
-		sg[nents].address	= virt_to_page(virt_addr);
-		sg[nents].offset	= (unsigned long)virt_addr & ~PAGE_MASK;
-		sg[nents].length	= 128 * SECTOR_SIZE;
-		nents++;
-		virt_addr		= virt_addr + (128 * SECTOR_SIZE);
-		sector_count		-= 128;
-	};
-	memset(&sg[nents], 0, sizeof(*sg));
-	sg[nents].page		= virt_to_page(virt_addr);
-	sg[nents].offset	= (unsigned long) virt_addr & ~PAGE_MASK;
-	sg[nents].length	= sector_count * SECTOR_SIZE;
-	nents++;
-#endif
+
 	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
 }
 
@@ -523,8 +511,7 @@
 	if (HWIF(drive)->ide_dma_host_off(drive))
 		return 1;
 
-	if (drive->queue_setup)
-		HWIF(drive)->ide_dma_queued_off(drive);
+	HWIF(drive)->ide_dma_queued_off(drive);
 
 	return 0;
 }
@@ -585,8 +572,9 @@
 	if (HWIF(drive)->ide_dma_host_on(drive))
 		return 1;
 
-	if (drive->queue_setup)
-		HWIF(drive)->ide_dma_queued_on(drive);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
+	HWIF(drive)->ide_dma_queued_on(drive);
+#endif
 
 	return 0;
 }
diff -urN linux-2.5.73-bk5/drivers/ide/ide-io.c linux-2.5.73-bk6/drivers/ide/ide-io.c
--- linux-2.5.73-bk5/drivers/ide/ide-io.c	2003-06-22 11:33:08.000000000 -0700
+++ linux-2.5.73-bk6/drivers/ide/ide-io.c	2003-06-28 04:53:18.000000000 -0700
@@ -1264,7 +1264,7 @@
 #endif /* CONFIG_BLK_DEV_IDEPCI */
 		}
 		spin_unlock_irqrestore(&ide_lock, flags);
-		return IRQ_HANDLED;
+		return IRQ_NONE;
 	}
 	drive = hwgroup->drive;
 	if (!drive) {
@@ -1286,7 +1286,7 @@
 		 * enough advance overhead that the latter isn't a problem.
 		 */
 		spin_unlock_irqrestore(&ide_lock, flags);
-		return IRQ_HANDLED;
+		return IRQ_NONE;
 	}
 	if (!hwgroup->busy) {
 		hwgroup->busy = 1;	/* paranoia */
diff -urN linux-2.5.73-bk5/drivers/ide/ide-probe.c linux-2.5.73-bk6/drivers/ide/ide-probe.c
--- linux-2.5.73-bk5/drivers/ide/ide-probe.c	2003-06-22 11:32:56.000000000 -0700
+++ linux-2.5.73-bk6/drivers/ide/ide-probe.c	2003-06-28 04:53:18.000000000 -0700
@@ -634,64 +634,8 @@
 	return drive->present;
 }
 
-static int hwif_check_region(ide_hwif_t *hwif, unsigned long addr, int num)
-{
-	int err;
-	
-	if(hwif->mmio)
-		err = check_mem_region(addr, num);
-	else
-		err = check_region(addr, num);
-		
-	if(err)
-	{
-		printk("%s: %s resource 0x%lX-0x%lX not free.\n",
-			hwif->name, hwif->mmio?"MMIO":"I/O", addr, addr+num-1);
-	}
-	return err;
-}
-	
-
-/**
- *	hwif_check_regions	-	check resources for IDE
- *	@hwif: interface to use
- *
- *	Checks if all the needed resources for an interface are free
- *	providing the interface is PIO. Right now core IDE code does
- *	this work which is deeply wrong. MMIO leaves it to the controller
- *	driver, PIO will migrate this way over time
- */
- 
-static int hwif_check_regions (ide_hwif_t *hwif)
-{
-	u32 i		= 0;
-	int addr_errs	= 0;
-
-	if (hwif->mmio == 2)
-		return 0;
-	addr_errs  = hwif_check_region(hwif, hwif->io_ports[IDE_DATA_OFFSET], 1);
-	for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		addr_errs += hwif_check_region(hwif, hwif->io_ports[i], 1);
-	if (hwif->io_ports[IDE_CONTROL_OFFSET])
-		addr_errs += hwif_check_region(hwif, hwif->io_ports[IDE_CONTROL_OFFSET], 1);
-#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
-	if (hwif->io_ports[IDE_IRQ_OFFSET])
-		addr_errs += hwif_check_region(hwif, hwif->io_ports[IDE_IRQ_OFFSET], 1);
-#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
-	/* If any errors are return, we drop the hwif interface. */
-	hwif->straight8 = 0;
-	return(addr_errs);
-}
-
-//EXPORT_SYMBOL(hwif_check_regions);
-
-#define hwif_request_region(addr, num, name)	\
-	((hwif->mmio) ? request_mem_region((addr),(num),(name)) : request_region((addr),(num),(name)))
-
 static void hwif_register (ide_hwif_t *hwif)
 {
-	u32 i = 0;
-
 	/* register with global device tree */
 	strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE);
 	snprintf(hwif->gendev.name,DEVICE_NAME_SIZE,"IDE Controller");
@@ -701,24 +645,6 @@
 	else
 		hwif->gendev.parent = NULL; /* Would like to do = &device_legacy */
 	device_register(&hwif->gendev);
-
-	if (hwif->mmio == 2)
-		return;
-	if (hwif->io_ports[IDE_CONTROL_OFFSET])
-		hwif_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name);
-#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
-	if (hwif->io_ports[IDE_IRQ_OFFSET])
-		hwif_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name);
-#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
-	if (((unsigned long)hwif->io_ports[IDE_DATA_OFFSET] | 7) ==
-	    ((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) {
-		hwif_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name);
-		hwif->straight8 = 1;
-		return;
-	}
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		hwif_request_region(hwif->io_ports[i], 1, hwif->name);
 }
 
 //EXPORT_SYMBOL(hwif_register);
@@ -778,7 +704,7 @@
 #ifdef CONFIG_BLK_DEV_PDC4030
 	    (hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
 #endif /* CONFIG_BLK_DEV_PDC4030 */
-	    (hwif_check_regions(hwif))) {
+	    (ide_hwif_request_regions(hwif))) {
 		u16 msgout = 0;
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
 			ide_drive_t *drive = &hwif->drives[unit];
@@ -869,6 +795,11 @@
 	if (irqd)
 		enable_irq(irqd);
 
+	if (!hwif->present) {
+		ide_hwif_release_regions(hwif);
+		return;
+	}
+
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		ide_drive_t *drive = &hwif->drives[unit];
 		int enable_dma = 1;
@@ -983,7 +914,6 @@
 	 
 	blk_init_queue(q, do_ide_request, &ide_lock);
 	q->queuedata = HWGROUP(drive);
-	drive->queue_setup = 1;
 	blk_queue_segment_boundary(q, 0xffff);
 
 	if (!hwif->rqsize)
@@ -1005,10 +935,6 @@
 static void ide_init_drive(ide_drive_t *drive)
 {
 	ide_toggle_bounce(drive, 1);
-
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-	HWIF(drive)->ide_dma_queued_on(drive);
-#endif
 }
 
 /*
diff -urN linux-2.5.73-bk5/drivers/ide/ide-taskfile.c linux-2.5.73-bk6/drivers/ide/ide-taskfile.c
--- linux-2.5.73-bk5/drivers/ide/ide-taskfile.c	2003-06-22 11:32:29.000000000 -0700
+++ linux-2.5.73-bk6/drivers/ide/ide-taskfile.c	2003-06-28 04:53:18.000000000 -0700
@@ -954,6 +954,9 @@
 		return startstop;
 	}
 
+	if (!drive->unmask)
+		local_irq_disable();
+
 	return task_out_intr(drive);
 }
 EXPORT_SYMBOL(pre_task_out_intr);
@@ -1030,6 +1033,9 @@
 		return startstop;
 	}
 
+	if (!drive->unmask)
+		local_irq_disable();
+
 	return task_mulout_intr(drive);
 }
 EXPORT_SYMBOL(pre_task_mulout_intr);
@@ -1361,8 +1367,6 @@
 
 EXPORT_SYMBOL(ide_init_drive_taskfile);
 
-#if 1
-
 int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf)
 {
 	struct request rq;
@@ -1401,69 +1405,6 @@
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
-#else
-
-int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf)
-{
-	struct request *rq;
-	unsigned long flags;
-	ide_hwgroup_t *hwgroup = HWGROUP(drive);
-	struct list_head *queue_head = &drive->queue.queue_head;
-	DECLARE_COMPLETION(wait);
-
-	if (HWIF(drive)->chipset == ide_pdc4030 && buf != NULL)
-		return -ENOSYS; /* special drive cmds not supported */
-
-	memset(rq, 0, sizeof(*rq));
-	rq->flags = REQ_DRIVE_TASKFILE;
-	rq->buffer = buf;
-
-	/*
-	 * (ks) We transfer currently only whole sectors.
-	 * This is suffient for now.  But, it would be great,
-	 * if we would find a solution to transfer any size.
-	 * To support special commands like READ LONG.
-	 */
-	if (args->command_type != IDE_DRIVE_TASK_NO_DATA) {
-		if (data_size == 0) {
-			ata_nsector_t nsector;
-			nsector.b.low = args->hobRegister[IDE_NSECTOR_OFFSET_HOB];
-			nsector.b.high = args->tfRegister[IDE_NSECTOR_OFFSET];
-			rq.nr_sectors = nsector.all;
-		} else {
-			rq.nr_sectors = data_size / SECTOR_SIZE;
-		}
-		rq.current_nr_sectors = rq.nr_sectors;
-	//	rq.hard_cur_sectors = rq.nr_sectors;
-	}
-
-	if (args->tf_out_flags.all == 0) {
-		/*
-		 * clean up kernel settings for driver sanity, regardless.
-		 * except for discrete diag services.
-		 */
-		args->posthandler = ide_post_handler_parser(
-				(struct hd_drive_task_hdr *) args->tfRegister,
-				(struct hd_drive_hob_hdr *) args->hobRegister);
-	}
-	rq->special = args;
-	rq->errors = 0;
-	rq->rq_status = RQ_ACTIVE;
-	rq->rq_disk = drive->disk;
-	rq->waiting = &wait;
-
-	spin_lock_irqsave(&ide_lock, flags);
-	queue_head = queue_head->prev;
-	list_add(&rq->queue, queue_head);
-	ide_do_request(hwgroup, 0);
-	spin_unlock_irqrestore(&ide_lock, flags);
-
-	wait_for_completion(&wait);	/* wait for it to be serviced */
-	return rq->errors ? -EIO : 0;	/* return -EIO if errors */
-}
-
-#endif
-
 EXPORT_SYMBOL(ide_diag_taskfile);
 
 int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf)
diff -urN linux-2.5.73-bk5/drivers/ide/ide-tcq.c linux-2.5.73-bk6/drivers/ide/ide-tcq.c
--- linux-2.5.73-bk5/drivers/ide/ide-tcq.c	2003-06-22 11:33:35.000000000 -0700
+++ linux-2.5.73-bk6/drivers/ide/ide-tcq.c	2003-06-28 04:53:18.000000000 -0700
@@ -501,8 +501,10 @@
 	 * bit 14 and 1 must be set in word 83 of the device id to indicate
 	 * support for dma queued protocol, and bit 15 must be cleared
 	 */
-	if ((drive->id->command_set_2 & tcq_bits) ^ tcq_mask)
+	if ((drive->id->command_set_2 & tcq_bits) ^ tcq_mask) {
+		printk(KERN_INFO "%s: TCQ not supported\n", drive->name);
 		return -EIO;
+	}
 
 	args = kmalloc(sizeof(*args), GFP_ATOMIC);
 	if (!args)
@@ -655,21 +657,24 @@
 
 int __ide_dma_queued_on(ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = HWIF(drive);
+
+	if (drive->media != ide_disk)
+		return 1;
 	if (!drive->using_dma)
 		return 1;
-	if (HWIF(drive)->chipset == ide_pdc4030)
+	if (hwif->chipset == ide_pdc4030)
 		return 1;
 	if (ide_tcq_check_blacklist(drive)) {
 		printk(KERN_WARNING "%s: tcq forbidden by blacklist\n",
 					drive->name);
 		return 1;
 	}
-	if (drive->next != drive) {
+	if (hwif->drives[0].present && hwif->drives[1].present) {
 		printk(KERN_WARNING "%s: only one drive on a channel supported"
 					" for tcq\n", drive->name);
 		return 1;
 	}
-
 	if (ata_pending_commands(drive)) {
 		printk(KERN_WARNING "ide-tcq; can't toggle tcq feature on "
 					"busy drive\n");
@@ -681,6 +686,8 @@
 
 int __ide_dma_queued_off(ide_drive_t *drive)
 {
+	if (drive->media != ide_disk)
+		return 1;
 	if (ata_pending_commands(drive)) {
 		printk("ide-tcq; can't toggle tcq feature on busy drive\n");
 		return 1;
diff -urN linux-2.5.73-bk5/drivers/ide/ide.c linux-2.5.73-bk6/drivers/ide/ide.c
--- linux-2.5.73-bk5/drivers/ide/ide.c	2003-06-28 04:53:13.000000000 -0700
+++ linux-2.5.73-bk6/drivers/ide/ide.c	2003-06-28 04:53:18.000000000 -0700
@@ -508,12 +508,87 @@
 };
 #endif
 
+static struct resource* hwif_request_region(ide_hwif_t *hwif,
+					    unsigned long addr, int num)
+{
+	struct resource *res;
+
+	if (hwif->mmio)
+		res = request_mem_region(addr, num, hwif->name);
+	else
+		res = request_region(addr, num, hwif->name);
+
+	if (!res)
+		printk(KERN_ERR "%s: %s resource 0x%lX-0x%lX not free.\n",
+				hwif->name, hwif->mmio ? "MMIO" : "I/O",
+				addr, addr+num-1);
+	return res;
+}
 
 #define hwif_release_region(addr, num) \
 	((hwif->mmio) ? release_mem_region((addr),(num)) : release_region((addr),(num)))
 
 /**
- *	hwif_unregister		-	free IDE resources
+ *	ide_hwif_request_regions - request resources for IDE
+ *	@hwif: interface to use
+ *
+ *	Requests all the needed resources for an interface.
+ *	Right now core IDE code does this work which is deeply wrong.
+ *	MMIO leaves it to the controller driver,
+ *	PIO will migrate this way over time.
+ */
+int ide_hwif_request_regions(ide_hwif_t *hwif)
+{
+	unsigned long addr;
+	unsigned int i;
+
+	if (hwif->mmio == 2)
+		return 0;
+	addr = hwif->io_ports[IDE_CONTROL_OFFSET];
+	if (addr && !hwif_request_region(hwif, addr, 1))
+		goto control_region_busy;
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
+	addr = hwif->io_ports[IDE_IRQ_OFFSET];
+	if (addr && !hwif_request_region(hwif, addr, 1))
+		goto irq_region_busy;
+#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
+	hwif->straight8 = 0;
+	addr = hwif->io_ports[IDE_DATA_OFFSET];
+	if ((addr | 7) == hwif->io_ports[IDE_STATUS_OFFSET]) {
+		if (!hwif_request_region(hwif, addr, 8))
+			goto data_region_busy;
+		hwif->straight8 = 1;
+		return 0;
+	}
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		addr = hwif->io_ports[i];
+		if (!hwif_request_region(hwif, addr, 1)) {
+			while (--i)
+				hwif_release_region(addr, 1);
+			goto data_region_busy;
+		}
+	}
+	return 0;
+
+data_region_busy:
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
+	addr = hwif->io_ports[IDE_IRQ_OFFSET];
+	if (addr)
+		hwif_release_region(addr, 1);
+irq_region_busy:
+#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
+	addr = hwif->io_ports[IDE_CONTROL_OFFSET];
+	if (addr)
+		hwif_release_region(addr, 1);
+control_region_busy:
+	/* If any errors are return, we drop the hwif interface. */
+	return -EBUSY;
+}
+
+EXPORT_SYMBOL(ide_hwif_request_regions);
+
+/**
+ *	ide_hwif_release_regions - free IDE resources
  *
  *	Note that we only release the standard ports,
  *	and do not even try to handle any extra ports
@@ -523,8 +598,7 @@
  *	importantly our caller should be doing this so we need to 
  *	restructure this as a helper function for drivers.
  */
- 
-void hwif_unregister (ide_hwif_t *hwif)
+void ide_hwif_release_regions(ide_hwif_t *hwif)
 {
 	u32 i = 0;
 
@@ -548,7 +622,7 @@
 	}
 }
 
-EXPORT_SYMBOL(hwif_unregister);
+EXPORT_SYMBOL(ide_hwif_release_regions);
 
 extern void init_hwif_data(unsigned int index);
 
@@ -635,7 +709,7 @@
 	 * and do not even try to handle any extra ports
 	 * allocated for weird IDE interface chipsets.
 	 */
-	hwif_unregister(hwif);
+	ide_hwif_release_regions(hwif);
 
 	/*
 	 * Remove us from the hwgroup, and free
@@ -2098,10 +2172,9 @@
 #ifdef CONFIG_BLK_DEV_IDEPCI
 				hwif->udma_four = 1;
 				goto done;
-#else /* !CONFIG_BLK_DEV_IDEPCI */
-				hwif->udma_four = 0;
+#else
 				goto bad_hwif;
-#endif /* CONFIG_BLK_DEV_IDEPCI */
+#endif
 			case -6: /* dma */
 				hwif->autodma = 1;
 				goto done;
@@ -2520,13 +2593,9 @@
  */
 int __init ide_init (void)
 {
-	static char banner_printed;
-	if (!banner_printed) {
-		printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
-		devfs_mk_dir("ide");
-		system_bus_speed = ide_system_bus_speed();
-		banner_printed = 1;
-	}
+	printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
+	devfs_mk_dir("ide");
+	system_bus_speed = ide_system_bus_speed();
 
 	bus_register(&ide_bus_type);
 
diff -urN linux-2.5.73-bk5/drivers/ieee1394/eth1394.c linux-2.5.73-bk6/drivers/ieee1394/eth1394.c
--- linux-2.5.73-bk5/drivers/ieee1394/eth1394.c	2003-06-28 04:53:13.000000000 -0700
+++ linux-2.5.73-bk6/drivers/ieee1394/eth1394.c	2003-06-28 04:53:18.000000000 -0700
@@ -400,9 +400,7 @@
 	/* Some constants */
 	dev->watchdog_timeo	= ETHER1394_TIMEOUT;
 	dev->flags		= IFF_BROADCAST | IFF_MULTICAST;
-        /* !! If data corruption or untrackable kernel panics occur, try
-         * removing NETIF_F_FRAGLIST !! */
-	dev->features		= NETIF_F_HIGHDMA | NETIF_F_FRAGLIST;
+	dev->features		= NETIF_F_HIGHDMA;
 	dev->addr_len		= ETH1394_ALEN;
 	dev->hard_header_len 	= ETH1394_HLEN;
 	dev->type		= ARPHRD_IEEE1394;
diff -urN linux-2.5.73-bk5/drivers/s390/block/dasd.c linux-2.5.73-bk6/drivers/s390/block/dasd.c
--- linux-2.5.73-bk5/drivers/s390/block/dasd.c	2003-06-22 11:32:43.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/dasd.c	2003-06-28 04:53:19.000000000 -0700
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.99 $
+ * $Revision: 1.101 $
  */
 
 #include <linux/config.h>
@@ -32,7 +32,7 @@
 /*
  * SECTION: Constant definitions to be used within this file
  */
-#define DASD_CHANQ_MAX_SIZE 5
+#define DASD_CHANQ_MAX_SIZE 4
 
 /*
  * SECTION: exported variables of dasd.c
@@ -803,24 +803,18 @@
  *  2) delayed start of request where start_IO failed with -EBUSY
  *  3) timeout for missing state change interrupts
  * The head of the ccw queue will have status DASD_CQR_IN_IO for 1),
- * DASD_CQR_QUEUED for 2) and DASD_CQR_PENDING for 3).
+ * DASD_CQR_QUEUED for 2) and 3).
  */
 static void
 dasd_timeout_device(unsigned long ptr)
 {
 	unsigned long flags;
 	struct dasd_device *device;
-	struct dasd_ccw_req *cqr;
 
 	device = (struct dasd_device *) ptr;
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	/* re-activate first request in queue */
-	if (!list_empty(&device->ccw_queue)) {
-		cqr = list_entry(device->ccw_queue.next,
-				 struct dasd_ccw_req, list);
-		if (cqr->status == DASD_CQR_PENDING)
-			cqr->status = DASD_CQR_QUEUED;
-	}
+        device->stopped &= ~DASD_STOPPED_PENDING;
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	dasd_schedule_bh(device);
 }
@@ -861,10 +855,6 @@
 
 /*
  *   Handles the state change pending interrupt.
- *   Search for the device related request queue and check if the first
- *   cqr in queue in in status 'DASD_CQR_PENDING'.
- *   If so the status is set to 'DASD_CQR_QUEUED' to reactivate
- *   the device.
  */
 static void
 do_state_change_pending(void *data)
@@ -874,29 +864,12 @@
 		struct dasd_device *device;
 	} *p;
 	struct dasd_device *device;
-	struct dasd_ccw_req *cqr;
 
 	p = data;
 	device = p->device;
 	DBF_EVENT(DBF_NOTICE, "State change Interrupt for bus_id %s",
 		  device->cdev->dev.bus_id);
-
-	spin_lock_irq(get_ccwdev_lock(device->cdev));
-	/* re-activate first request in queue */
-	if (!list_empty(&device->ccw_queue)) {
-		cqr = list_entry(device->ccw_queue.next,
-				 struct dasd_ccw_req, list);
-		if (cqr == NULL) {
-			MESSAGE (KERN_DEBUG,
-				 "got state change pending interrupt on"
-				 "an idle device: bus_id %s",
-				 device->cdev->dev.bus_id);
-			return;
-		}
-		if (cqr->status == DASD_CQR_PENDING)
-			cqr->status = DASD_CQR_QUEUED;
-	}
-	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+	device->stopped &= ~DASD_STOPPED_PENDING;
 	dasd_schedule_bh(device);
 	dasd_put_device(device);
 	kfree(p);
@@ -1036,7 +1009,8 @@
 		if (cqr->list.next != &device->ccw_queue) {
 			next = list_entry(cqr->list.next,
 					  struct dasd_ccw_req, list);
-			if (next->status == DASD_CQR_QUEUED) {
+			if ((next->status == DASD_CQR_QUEUED) &&
+			    (!device->stopped)) {
 				if (device->discipline->start_IO(next) == 0)
 					expires = next->expires;
 				else
@@ -1264,7 +1238,8 @@
 	if (list_empty(&device->ccw_queue))
 		return;
 	cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
-	if (cqr->status == DASD_CQR_QUEUED) {
+	if ((cqr->status == DASD_CQR_QUEUED) &&
+	    (!device->stopped)) {
 		/* try to start the first I/O that can be started */
 		rc = device->discipline->start_IO(cqr);
 		if (rc == 0)
diff -urN linux-2.5.73-bk5/drivers/s390/block/dasd_3990_erp.c linux-2.5.73-bk6/drivers/s390/block/dasd_3990_erp.c
--- linux-2.5.73-bk5/drivers/s390/block/dasd_3990_erp.c	2003-06-22 11:33:12.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/dasd_3990_erp.c	2003-06-28 04:53:19.000000000 -0700
@@ -5,7 +5,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
  *
- * $Revision: 1.24 $
+ * $Revision: 1.25 $
  */
 
 #include <linux/timer.h>
@@ -221,13 +221,6 @@
  *   Block the given device request queue to prevent from further
  *   processing until the started timer has expired or an related
  *   interrupt was received.
- *
- *  PARAMETER
- *   erp		request to be blocked
- *   expires		time to wait until restart (in jiffies) 
- *
- * RETURN VALUES
- *   void		
  */
 static void
 dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
@@ -238,7 +231,9 @@
 	DEV_MESSAGE(KERN_INFO, device,
 		    "blocking request queue for %is", expires);
 
-	erp->status = DASD_CQR_PENDING;
+	device->stopped |= DASD_STOPPED_PENDING;
+	erp->status = DASD_CQR_QUEUED;
+
 	dasd_set_timer(device, expires);
 }
 
@@ -453,9 +448,11 @@
 
 		if (sense[25] == 0x1D) {	/* state change pending */
 
-			DEV_MESSAGE(KERN_INFO, device, "%s",
-				    "waiting for state change pending " "int");
-
+			DEV_MESSAGE(KERN_INFO, device, 
+				    "waiting for state change pending "
+				    "interrupt, %d retries left",
+				    erp->retries);
+			
 			dasd_3990_erp_block_queue(erp, 30*HZ);
 
 		} else {
diff -urN linux-2.5.73-bk5/drivers/s390/block/dasd_eckd.c linux-2.5.73-bk6/drivers/s390/block/dasd_eckd.c
--- linux-2.5.73-bk5/drivers/s390/block/dasd_eckd.c	2003-06-22 11:32:28.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/dasd_eckd.c	2003-06-28 04:53:19.000000000 -0700
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.42 $
+ * $Revision: 1.46 $
  */
 
 #include <linux/config.h>
@@ -80,7 +80,13 @@
 static int
 dasd_eckd_probe (struct ccw_device *cdev)
 {
-	return dasd_generic_probe (cdev, &dasd_eckd_discipline);
+	int ret;
+
+	ret = dasd_generic_probe (cdev, &dasd_eckd_discipline);
+	if (ret)
+		return ret;
+	ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
+	return 0;
 }
 
 static int
@@ -204,7 +210,7 @@
                 data->ep_sys_time = get_clock ();
                 
                 de_ccw->count = sizeof (struct DE_eckd_data);
-                de_ccw->flags = CCW_FLAG_SLI;  
+                de_ccw->flags |= CCW_FLAG_SLI;  
         }
 
         return;
@@ -281,19 +287,11 @@
 	/* check for sequential prestage - enhance cylinder range */
 	if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
 	    data->attributes.operation == DASD_SEQ_ACCESS) {
-
-		if (end.cyl + private->attrib.nr_cyl < geo.cyl) {
+		
+		if (end.cyl + private->attrib.nr_cyl < geo.cyl) 
 			end.cyl += private->attrib.nr_cyl;
-			DBF_DEV_EVENT(DBF_NOTICE, device,
-				      "Enhanced DE Cylinder from  %x to %x",
-				      (totrk / geo.head), end.cyl);
-		} else {
+		else
 			end.cyl = (geo.cyl - 1);
-			DBF_DEV_EVENT(DBF_NOTICE, device,
-				      "Enhanced DE Cylinder from  %x to "
-				      "End of device %x",
-				      (totrk / geo.head), end.cyl);
-		}
 	}
 
 	data->beg_ext.cyl = beg.cyl;
@@ -512,12 +510,6 @@
 		    private->rdc_data.cu_type,
 		    private->rdc_data.cu_model.model);
 	return 0;
-
-        /* get characteristis via diag to determine the kind of
-	 * minidisk under VM needed beacause XRC is not support
-	 * by VM (jet). Can be removed as soon as VM supports XRC
-	 * FIXME: TBD ??? HUM
-	 */
 }
 
 static struct dasd_ccw_req *
@@ -1130,13 +1122,16 @@
 		return -ENODEV;
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
-				   1, 0, device);
+				   1, 32, device);
 	if (cqr == NULL) {
 		MESSAGE(KERN_WARNING, "%s",
 			"No memory to allocate initialization request");
 		return -ENOMEM;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
+        cqr->cpaddr->flags |= CCW_FLAG_SLI;
+        cqr->cpaddr->count = 32;
+	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
 	cqr->device = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * HZ;
@@ -1145,14 +1140,14 @@
 
 	rc = dasd_sleep_on_immediatly(cqr);
 
-	dasd_kfree_request(cqr, cqr->device);
+	dasd_sfree_request(cqr, cqr->device);
 	return rc;
 }
 
 /*
  * Reserve device ioctl.
  * Options are set to 'synchronous wait for interrupt' and
- * 'timeout the request'. This leads to an terminate IO if 
+ * 'timeout the request'. This leads to a terminate IO if 
  * the interrupt is outstanding for a certain time. 
  */
 static int
@@ -1170,14 +1165,16 @@
 		return -ENODEV;
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
-				   1, 0, device);
-
+				   1, 32, device);
 	if (cqr == NULL) {
 		MESSAGE(KERN_WARNING, "%s",
 			"No memory to allocate initialization request");
 		return -ENOMEM;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
+        cqr->cpaddr->flags |= CCW_FLAG_SLI;
+        cqr->cpaddr->count = 32;
+	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
 	cqr->device = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * HZ;
@@ -1186,11 +1183,7 @@
 
 	rc = dasd_sleep_on_immediatly(cqr);
 
-	if (rc == -EIO) {
-		/* Request got an error or has been timed out. */
-		dasd_eckd_release(bdev, no, args);
-	}
-	dasd_kfree_request(cqr, cqr->device);
+	dasd_sfree_request(cqr, cqr->device);
 	return rc;
 }
 
@@ -1214,13 +1207,16 @@
 		return -ENODEV;
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
-				   1, 0, device);
+				   1, 32, device);
 	if (cqr == NULL) {
 		MESSAGE(KERN_WARNING, "%s",
 			"No memory to allocate initialization request");
 		return -ENOMEM;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
+        cqr->cpaddr->flags |= CCW_FLAG_SLI;
+        cqr->cpaddr->count = 32;
+	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
 	cqr->device = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * HZ;
@@ -1229,11 +1225,7 @@
 
 	rc = dasd_sleep_on_immediatly(cqr);
 
-	if (rc == -EIO) {
-		/* Request got an error or has been timed out. */
-		dasd_eckd_release(bdev, no, args);
-	}
-	dasd_kfree_request(cqr, cqr->device);
+	dasd_sfree_request(cqr, cqr->device);
 	return rc;
 }
 
@@ -1330,17 +1322,13 @@
 
 	private = (struct dasd_eckd_private *) device->private;
 
-	DBF_DEV_EVENT(DBF_ERR, device,
-		      "cache operation mode got "
-		      "%x (%i cylinder prestage)",
-		      attrib.operation, attrib.nr_cyl);
-
 	private->attrib = attrib;
 
 	DBF_DEV_EVENT(DBF_ERR, device,
 		      "cache operation mode set to "
 		      "%x (%i cylinder prestage)",
 		      private->attrib.operation, private->attrib.nr_cyl);
+	
 	return 0;
 }
 
diff -urN linux-2.5.73-bk5/drivers/s390/block/dasd_erp.c linux-2.5.73-bk6/drivers/s390/block/dasd_erp.c
--- linux-2.5.73-bk5/drivers/s390/block/dasd_erp.c	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/dasd_erp.c	2003-06-28 04:53:19.000000000 -0700
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.9 $
+ * $Revision: 1.10 $
  */
 
 #include <linux/config.h>
@@ -86,48 +86,31 @@
 	atomic_dec(&device->ref_count);
 }
 
+
 /*
- * DESCRIPTION
- *   sets up the default-ERP struct dasd_ccw_req, namely one, which performs
- *   a TIC to the original channel program with a retry counter of 16
- *
- * PARAMETER
- *   cqr		failed CQR
- *
- * RETURN VALUES
- *   erp		CQR performing the ERP
+ * dasd_default_erp_action just retries the current cqr
  */
 struct dasd_ccw_req *
 dasd_default_erp_action(struct dasd_ccw_req * cqr)
 {
 	struct dasd_device *device;
-	struct dasd_ccw_req *erp;
 
-	MESSAGE(KERN_DEBUG, "%s", "Default ERP called... ");
 	device = cqr->device;
-	erp = dasd_alloc_erp_request((char *) &cqr->magic, 1, 0, device);
-	if (IS_ERR(erp)) {
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Unable to allocate request for default ERP");
-		cqr->status = DASD_CQR_FAILED;
-		cqr->stopclk = get_clock();
-		return cqr;
-	}
-
-	erp->cpaddr->cmd_code = CCW_CMD_TIC;
-	erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
-	erp->function = dasd_default_erp_action;
-	erp->refers = cqr;
-	erp->device = device;
-	erp->magic = cqr->magic;
-	erp->retries = 16;
-	erp->status = DASD_CQR_FILLED;
-
-	list_add(&erp->list, &device->ccw_queue);
-	erp->status = DASD_CQR_QUEUED;
-
-	return erp;
 
+        /* just retry - there is nothing to save ... I got no sense data.... */
+        if (cqr->retries > 0) {
+                DEV_MESSAGE (KERN_DEBUG, device, 
+                             "default ERP called (%i retries left)",
+                             cqr->retries);
+		cqr->status = DASD_CQR_QUEUED;
+        } else {
+                DEV_MESSAGE (KERN_WARNING, device, "%s",
+			     "default ERP called (NO retry left)");
+		
+		cqr->status = DASD_CQR_FAILED;
+		cqr->stopclk = get_clock ();
+        }
+        return cqr;
 }				/* end dasd_default_erp_action */
 
 /*
diff -urN linux-2.5.73-bk5/drivers/s390/block/dasd_fba.c linux-2.5.73-bk6/drivers/s390/block/dasd_fba.c
--- linux-2.5.73-bk5/drivers/s390/block/dasd_fba.c	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/dasd_fba.c	2003-06-28 04:53:19.000000000 -0700
@@ -4,7 +4,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.29 $
+ * $Revision: 1.30 $
  */
 
 #include <linux/config.h>
@@ -57,7 +57,13 @@
 static int
 dasd_fba_probe(struct ccw_device *cdev)
 {
-	return  dasd_generic_probe (cdev, &dasd_fba_discipline);
+	int ret;
+
+	ret = dasd_generic_probe (cdev, &dasd_fba_discipline);
+	if (ret)
+		return ret;
+	ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
+	return 0;
 }
 
 static int
diff -urN linux-2.5.73-bk5/drivers/s390/block/dasd_int.h linux-2.5.73-bk6/drivers/s390/block/dasd_int.h
--- linux-2.5.73-bk5/drivers/s390/block/dasd_int.h	2003-06-22 11:33:01.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/dasd_int.h	2003-06-28 04:53:19.000000000 -0700
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.40 $
+ * $Revision: 1.42 $
  */
 
 #ifndef DASD_INT_H
@@ -188,7 +188,6 @@
 #define DASD_CQR_DONE     0x03	/* request is completed successfully */
 #define DASD_CQR_ERROR    0x04	/* request is completed with error */
 #define DASD_CQR_FAILED   0x05	/* request is finally failed */
-#define DASD_CQR_PENDING  0x06  /* request is waiting for interrupt - ERP only */ 
 
 /* Signature for error recovery functions. */
 typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
@@ -279,6 +278,7 @@
 
 	/* Device state and target state. */
 	int state, target;
+	int stopped;		/* device (ccw_device_start) was stopped */
 
 	/* Open and reference count. */
         atomic_t ref_count;
@@ -306,6 +306,12 @@
 #endif
 };
 
+/* reasons why device (ccw_device_start) was stopped */
+#define DASD_STOPPED_NOT_ACC 1         /* not accessible */
+#define DASD_STOPPED_QUIESCE 2         /* Quiesced */
+#define DASD_STOPPED_PENDING 4         /* long busy */
+
+
 void dasd_put_device_wake(struct dasd_device *);
 
 /*
diff -urN linux-2.5.73-bk5/drivers/s390/block/dasd_ioctl.c linux-2.5.73-bk6/drivers/s390/block/dasd_ioctl.c
--- linux-2.5.73-bk5/drivers/s390/block/dasd_ioctl.c	2003-06-22 11:32:56.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/dasd_ioctl.c	2003-06-28 04:53:19.000000000 -0700
@@ -169,6 +169,58 @@
 }
 
 /*
+ * Quiesce device.
+ */
+static int
+dasd_ioctl_quiesce(struct block_device *bdev, int no, long args)
+{
+	struct dasd_device *device;
+	unsigned long flags;
+	
+	if (!capable (CAP_SYS_ADMIN))
+		return -EACCES;
+	
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
+	
+	DEV_MESSAGE (KERN_DEBUG, device, "%s",
+		     "Quiesce IO on device");
+	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+	device->stopped |= DASD_STOPPED_QUIESCE;
+	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+	return 0;
+}
+
+
+/*
+ * Quiesce device.
+ */
+static int
+dasd_ioctl_resume(struct block_device *bdev, int no, long args)
+{
+	struct dasd_device *device;
+	unsigned long flags;
+	
+	if (!capable (CAP_SYS_ADMIN)) 
+		return -EACCES;
+
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
+
+	DEV_MESSAGE (KERN_DEBUG, device, "%s",
+		     "resume IO on device");
+	
+	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+	device->stopped &= ~DASD_STOPPED_QUIESCE;
+	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+
+	dasd_schedule_bh (device);
+	return 0;
+}
+
+/*
  * performs formatting of _device_ according to _fdata_
  * Note: The discipline's format_function is assumed to deliver formatting
  * commands to format a single unit of the device. In terms of the ECKD
@@ -438,6 +490,8 @@
 {
 	{ BIODASDDISABLE, dasd_ioctl_disable },
 	{ BIODASDENABLE, dasd_ioctl_enable },
+	{ BIODASDQUIESCE, dasd_ioctl_quiesce },
+	{ BIODASDRESUME, dasd_ioctl_resume },
 	{ BIODASDFMT, dasd_ioctl_format },
 	{ BIODASDINFO, dasd_ioctl_information },
 	{ BIODASDINFO2, dasd_ioctl_information },
diff -urN linux-2.5.73-bk5/drivers/s390/block/xpram.c linux-2.5.73-bk6/drivers/s390/block/xpram.c
--- linux-2.5.73-bk5/drivers/s390/block/xpram.c	2003-06-22 11:33:04.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/block/xpram.c	2003-06-28 04:53:19.000000000 -0700
@@ -487,7 +487,7 @@
 	unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
 	devfs_remove("slram");
 	sys_device_unregister(&xpram_sys_device);
-	sysdev_class_unregister(&xpram_sys_class);
+	sysdev_class_unregister(&xpram_sysclass);
 }
 
 static int __init xpram_init(void)
@@ -511,7 +511,7 @@
 
 	rc = sys_device_register(&xpram_sys_device);
 	if (rc) {
-		sysdev_class_unregister(&xpram_syclass);
+		sysdev_class_unregister(&xpram_sysclass);
 		return rc;
 	}
 	rc = xpram_setup_blkdev();
diff -urN linux-2.5.73-bk5/drivers/s390/char/con3215.c linux-2.5.73-bk6/drivers/s390/char/con3215.c
--- linux-2.5.73-bk5/drivers/s390/char/con3215.c	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/char/con3215.c	2003-06-28 04:53:19.000000000 -0700
@@ -1215,6 +1215,7 @@
 		return ret;
 	}
 	tty3215_driver = driver;
+	return 0;
 }
 
 static void __exit
diff -urN linux-2.5.73-bk5/drivers/s390/char/tape_core.c linux-2.5.73-bk6/drivers/s390/char/tape_core.c
--- linux-2.5.73-bk5/drivers/s390/char/tape_core.c	2003-06-22 11:32:37.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/char/tape_core.c	2003-06-28 04:53:19.000000000 -0700
@@ -372,6 +372,8 @@
 	device->cdev = cdev;
 	cdev->handler = tape_do_irq;
 
+	ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
+
 	return 0;
 }
 
@@ -903,7 +905,7 @@
 {
 	tape_dbf_area = debug_register ( "tape", 1, 2, 3*sizeof(long));
 	debug_register_view(tape_dbf_area, &debug_sprintf_view);
-	DBF_EVENT(3, "tape init: ($Revision: 1.25 $)\n");
+	DBF_EVENT(3, "tape init: ($Revision: 1.26 $)\n");
 	tape_proc_init();
 	tapechar_init ();
 	tapeblock_init ();
@@ -928,7 +930,7 @@
 MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
 	      "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
 MODULE_DESCRIPTION("Linux on zSeries channel attached "
-		   "tape device driver ($Revision: 1.25 $)");
+		   "tape device driver ($Revision: 1.26 $)");
 
 module_init(tape_init);
 module_exit(tape_exit);
diff -urN linux-2.5.73-bk5/drivers/s390/cio/ccwgroup.c linux-2.5.73-bk6/drivers/s390/cio/ccwgroup.c
--- linux-2.5.73-bk5/drivers/s390/cio/ccwgroup.c	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/ccwgroup.c	2003-06-28 04:53:19.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/ccwgroup.c
  *  bus driver for ccwgroup
- *   $Revision: 1.6 $
+ *   $Revision: 1.7 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                       IBM Corporation
@@ -196,10 +196,12 @@
 
 	value = simple_strtoul(buf, 0, 0);
 
-	if (value)
+	if (value == 1)
 		ccwgroup_set_online(gdev);
-	else
+	else if (value == 0)
 		ccwgroup_set_offline(gdev);
+	else
+		return -EINVAL;
 
 	return count;
 }
@@ -211,7 +213,7 @@
 
 	online = (to_ccwgroupdev(dev)->state == CCWGROUP_ONLINE);
 
-	return sprintf(buf, online ? "1\n" : "0\n");
+	return sprintf(buf, online ? "yes\n" : "no\n");
 }
 
 static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);
diff -urN linux-2.5.73-bk5/drivers/s390/cio/chsc.c linux-2.5.73-bk6/drivers/s390/cio/chsc.c
--- linux-2.5.73-bk5/drivers/s390/cio/chsc.c	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/chsc.c	2003-06-28 04:53:19.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/chsc.c
  *   S/390 common I/O routines -- channel subsystem call
- *   $Revision: 1.69 $
+ *   $Revision: 1.73 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -322,10 +322,6 @@
 	sprintf(dbf_txt, "chpr%x", chpid);
 	CIO_TRACE_EVENT(2, dbf_txt);
 
-	/*
-	 * TODO: the chpid may be not the chpid with the link incident,
-	 * but the chpid the report came in through. How to handle???
-	 */
 	clear_bit(chpid, chpids);
 	if (!test_and_clear_bit(chpid, chpids_known))
 		return;	 /* we didn't know the chpid anyway */
@@ -469,9 +465,40 @@
 	free_page((unsigned long)page);
 }
 
+static int
+__get_chpid_from_lir(void *data)
+{
+	struct lir {
+		u8  iq;
+		u8  ic;
+		u16 sci;
+		/* incident-node descriptor */
+		u32 indesc[28];
+		/* attached-node descriptor */
+		u32 andesc[28];
+		/* incident-specific information */
+		u32 isinfo[28];
+	} *lir;
+
+	lir = (struct lir*) data;
+	if (!(lir->iq&0x80))
+		/* NULL link incident record */
+		return -EINVAL;
+	if (!(lir->indesc[0]&0xc0000000))
+		/* node descriptor not valid */
+		return -EINVAL;
+	if (!(lir->indesc[0]&0x10000000))
+		/* don't handle device-type nodes - FIXME */
+		return -EINVAL;
+	/* Byte 3 contains the chpid. Could also be CTCA, but we don't care */
+
+	return (u16) (lir->indesc[0]&0x000000ff);
+}
+
 static void
 do_process_crw(void *ignore)
 {
+	int chpid;
 	struct {
 		struct chsc_header request;
 		u32 reserved1;
@@ -487,10 +514,8 @@
 		u16 rsid;	/* reporting source id */
 		u32 reserved5;
 		u32 reserved6;
-		u32 ccdf;	/* content-code dependent field */
-		u32 reserved7;
-		u32 reserved8;
-		u32 reserved9;
+		u32 ccdf[96];	/* content-code dependent field */
+		/* ccdf has to be big enough for a link-incident record */
 	} *sei_area;
 
 	/*
@@ -560,9 +585,14 @@
 		case 1: /* link incident*/
 			CIO_CRW_EVENT(4, "chsc_process_crw: "
 				      "channel subsystem reports link incident,"
-				      " source is chpid %x\n", sei_area->rsid);
-			
-			s390_set_chpid_offline(sei_area->rsid);
+				      " reporting source is chpid %x\n",
+				      sei_area->rsid);
+			chpid = __get_chpid_from_lir(sei_area->ccdf);
+			if (chpid < 0)
+				CIO_CRW_EVENT(4, "%s: Invalid LIR, skipping\n",
+					      __FUNCTION__);
+			else
+				s390_set_chpid_offline(chpid);
 			break;
 			
 		case 2: /* i/o resource accessibiliy */
diff -urN linux-2.5.73-bk5/drivers/s390/cio/css.h linux-2.5.73-bk6/drivers/s390/cio/css.h
--- linux-2.5.73-bk5/drivers/s390/cio/css.h	2003-06-22 11:33:37.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/css.h	2003-06-28 04:53:19.000000000 -0700
@@ -72,9 +72,9 @@
 	struct {
 		unsigned int fast:1;	/* post with "channel end" */
 		unsigned int repall:1;	/* report every interrupt status */
+		unsigned int pgroup:1;  /* do path grouping */
 	} __attribute__ ((packed)) options;
 	struct {
-		unsigned int pgid_supp:1;   /* "path group ID" supported */
 		unsigned int pgid_single:1; /* use single path for Set PGID */
 		unsigned int esid:1;        /* Ext. SenseID supported by HW */
 		unsigned int dosense:1;	    /* delayed SENSE required */
diff -urN linux-2.5.73-bk5/drivers/s390/cio/device.c linux-2.5.73-bk6/drivers/s390/cio/device.c
--- linux-2.5.73-bk5/drivers/s390/cio/device.c	2003-06-22 11:33:04.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/device.c	2003-06-28 04:53:19.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/device.c
  *  bus driver for ccw devices
- *   $Revision: 1.54 $
+ *   $Revision: 1.57 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -298,20 +298,19 @@
 online_store (struct device *dev, const char *buf, size_t count)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
-	unsigned int value;
+	int i;
+	char *tmp;
 
 	if (!cdev->drv)
 		return count;
 
-	sscanf(buf, "%u", &value);
-
-	if (value) {
-		if (cdev->drv->set_online)
-			ccw_device_set_online(cdev);
-	} else {
-		if (cdev->drv->set_offline)
-			ccw_device_set_offline(cdev);
-	}
+	i = simple_strtoul(buf, &tmp, 16);
+	if (i == 0 && cdev->drv->set_online)
+		ccw_device_set_online(cdev);
+	else if (i == 1 && cdev->drv->set_offline)
+		ccw_device_set_offline(cdev);
+	else
+		return -EINVAL;
 
 	return count;
 }
@@ -405,11 +404,14 @@
  * This allows to trigger an unconditional reserve ccw to eckd dasds
  * (if the device is something else, there should be no problems more than
  * a command reject; we don't have any means of finding out the device's
- * type if it was boxed at ipl/attach).
+ * type if it was boxed at ipl/attach for older devices and under VM).
  */
 void
-ccw_device_add_stlck(struct ccw_device *cdev)
+ccw_device_add_stlck(void *data)
 {
+	struct ccw_device *cdev;
+
+	cdev = (struct ccw_device *)data;
 	device_create_file(&cdev->dev, &dev_attr_steal_lock);
 }
 
@@ -470,6 +472,8 @@
 	if (ret)
 		printk(KERN_WARNING "%s: could not add attributes to %04x\n",
 		       __func__, sch->irq);
+	if (cdev->private->state == DEV_STATE_BOXED)
+		device_create_file(&cdev->dev, &dev_attr_steal_lock);
 out:
 	put_device(&sch->dev);
 }
@@ -493,6 +497,8 @@
 		if (cdev->dev.release)
 			cdev->dev.release(&cdev->dev);
 		break;
+	case DEV_STATE_BOXED:
+		/* Device did not respond in time. */
 	case DEV_STATE_OFFLINE:
 		/* 
 		 * We can't register the device in interrupt context so
@@ -502,9 +508,6 @@
 			  io_subchannel_register, (void *) cdev);
 		queue_work(ccw_device_work, &cdev->private->kick_work);
 		break;
-	case DEV_STATE_BOXED:
-		/* Device did not respond in time. */
-		break;
 	}
 	if (atomic_dec_and_test(&ccw_device_init_count))
 		wake_up(&ccw_device_init_wq);
diff -urN linux-2.5.73-bk5/drivers/s390/cio/device.h linux-2.5.73-bk6/drivers/s390/cio/device.h
--- linux-2.5.73-bk5/drivers/s390/cio/device.h	2003-06-22 11:33:07.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/device.h	2003-06-28 04:53:19.000000000 -0700
@@ -95,7 +95,7 @@
 
 void ccw_device_call_handler(struct ccw_device *);
 
-void ccw_device_add_stlck(struct ccw_device *);
+void ccw_device_add_stlck(void *);
 int ccw_device_stlck(struct ccw_device *);
 
 /* qdio needs this. */
diff -urN linux-2.5.73-bk5/drivers/s390/cio/device_fsm.c linux-2.5.73-bk6/drivers/s390/cio/device_fsm.c
--- linux-2.5.73-bk5/drivers/s390/cio/device_fsm.c	2003-06-22 11:32:46.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/device_fsm.c	2003-06-28 04:53:19.000000000 -0700
@@ -132,11 +132,11 @@
 		CIO_DEBUG(KERN_WARNING, 2,
 			  "SenseID : boxed device %04X on subchannel %04X\n",
 			  sch->schib.pmcw.dev, sch->irq);
-		ccw_device_add_stlck(cdev);
 		break;
 	}
 	io_subchannel_recog_done(cdev);
-	wake_up(&cdev->private->wait_q);
+	if (state != DEV_STATE_NOT_OPER)
+		wake_up(&cdev->private->wait_q);
 }
 
 /*
@@ -159,22 +159,65 @@
 }
 
 /*
+ * Finished with online/offline processing.
+ */
+static void
+ccw_device_done(struct ccw_device *cdev, int state)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+
+	if (state != DEV_STATE_ONLINE)
+		cio_disable_subchannel(sch);
+
+	/* Reset device status. */
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+
+	cdev->private->state = state;
+
+
+	if (state == DEV_STATE_BOXED) {
+		CIO_DEBUG(KERN_WARNING, 2,
+			  "Boxed device %04X on subchannel %04X\n",
+			  sch->schib.pmcw.dev, sch->irq);
+		INIT_WORK(&cdev->private->kick_work,
+			  ccw_device_add_stlck, (void *) cdev);
+		queue_work(ccw_device_work, &cdev->private->kick_work);
+	}
+
+	wake_up(&cdev->private->wait_q);
+
+	if (state != DEV_STATE_ONLINE)
+		put_device (&cdev->dev);
+}
+
+/*
  * Function called from device_pgid.c after sense path ground has completed.
  */
 void
 ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
 {
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
 	switch (err) {
 	case 0:
-		cdev->private->state = DEV_STATE_SENSE_ID;
-		ccw_device_sense_id_start(cdev);
+		/* Start Path Group verification. */
+		sch->vpm = 0;	/* Start with no path groups set. */
+		cdev->private->state = DEV_STATE_VERIFY;
+		ccw_device_verify_start(cdev);
 		break;
 	case -ETIME:		/* Sense path group id stopped by timeout. */
 	case -EUSERS:		/* device is reserved for someone else. */
-		ccw_device_recog_done(cdev, DEV_STATE_BOXED);
+		ccw_device_done(cdev, DEV_STATE_BOXED);
+		break;
+	case -EOPNOTSUPP: /* path grouping not supported, just set online. */
+		cdev->private->options.pgroup = 0;
+		ccw_device_done(cdev, DEV_STATE_ONLINE);
 		break;
 	default:
-		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 		break;
 	}
 }
@@ -198,11 +241,15 @@
 	ccw_device_set_timeout(cdev, 60*HZ);
 
 	/*
-	 * First thing we should do is a sensePGID in order to find out how
-	 * we can proceed with the recognition process.
+	 * We used to start here with a sense pgid to find out whether a device
+	 * is locked by someone else. Unfortunately, the sense pgid command
+	 * code has other meanings on devices predating the path grouping
+	 * algorithm, so we start with sense id and box the device after an
+	 * timeout (or if sense pgid during path verification detects the device
+	 * is locked, as may happen on newer devices).
 	 */
-	cdev->private->state = DEV_STATE_SENSE_PGID;
-	ccw_device_sense_pgid_start(cdev);
+	cdev->private->state = DEV_STATE_SENSE_ID;
+	ccw_device_sense_id_start(cdev);
 	return 0;
 }
 
@@ -218,29 +265,6 @@
 		ccw_device_set_timeout(cdev, 3*HZ);
 }
 
-/*
- * Finished with online/offline processing.
- */
-static void
-ccw_device_done(struct ccw_device *cdev, int state)
-{
-	struct subchannel *sch;
-
-	sch = to_subchannel(cdev->dev.parent);
-
-	if (state != DEV_STATE_ONLINE)
-		cio_disable_subchannel(sch);
-
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-	cdev->private->state = state;
-
-	wake_up(&cdev->private->wait_q);
-
-	if (state != DEV_STATE_ONLINE)
-		put_device (&cdev->dev);
-}
 
 void
 ccw_device_verify_done(struct ccw_device *cdev, int err)
@@ -276,16 +300,15 @@
 		dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 		return -ENODEV;
 	}
-	/* Is Set Path Group supported? */
-	if (!cdev->private->flags.pgid_supp) {
+	/* Do we want to do path grouping? */
+	if (!cdev->private->options.pgroup) {
 		/* No, set state online immediately. */
 		ccw_device_done(cdev, DEV_STATE_ONLINE);
 		return 0;
 	}
-	/* Start Path Group verification. */
-	sch->vpm = 0;	/* Start with no path groups set. */
-	cdev->private->state = DEV_STATE_VERIFY;
-	ccw_device_verify_start(cdev);
+	/* Do a SensePGID first. */
+	cdev->private->state = DEV_STATE_SENSE_PGID;
+	ccw_device_sense_pgid_start(cdev);
 	return 0;
 }
 
@@ -321,8 +344,8 @@
 	}
 	if (sch->schib.scsw.actl != 0)
 		return -EBUSY;
-	/* Is Set Path Group supported? */
-	if (!cdev->private->flags.pgid_supp) {
+	/* Are we doing path grouping? */
+	if (!cdev->private->options.pgroup) {
 		/* No, set state offline immediately. */
 		ccw_device_done(cdev, DEV_STATE_OFFLINE);
 		return 0;
@@ -643,9 +666,9 @@
 		[DEV_EVENT_VERIFY]	ccw_device_nop,
 	},
 	[DEV_STATE_SENSE_PGID] {
-		[DEV_EVENT_NOTOPER]	ccw_device_recog_notoper,
+		[DEV_EVENT_NOTOPER]	ccw_device_online_notoper,
 		[DEV_EVENT_INTERRUPT]	ccw_device_sense_pgid_irq,
-		[DEV_EVENT_TIMEOUT]	ccw_device_recog_timeout,
+		[DEV_EVENT_TIMEOUT]	ccw_device_onoff_timeout,
 		[DEV_EVENT_VERIFY]	ccw_device_nop,
 	},
 	[DEV_STATE_SENSE_ID] {
diff -urN linux-2.5.73-bk5/drivers/s390/cio/device_ops.c linux-2.5.73-bk6/drivers/s390/cio/device_ops.c
--- linux-2.5.73-bk5/drivers/s390/cio/device_ops.c	2003-06-22 11:33:04.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/device_ops.c	2003-06-28 04:53:19.000000000 -0700
@@ -37,6 +37,7 @@
 		return -EINVAL;
 	cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
 	cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
+	cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
 	return 0;
 }
 
diff -urN linux-2.5.73-bk5/drivers/s390/cio/device_pgid.c linux-2.5.73-bk6/drivers/s390/cio/device_pgid.c
--- linux-2.5.73-bk5/drivers/s390/cio/device_pgid.c	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/device_pgid.c	2003-06-28 04:53:19.000000000 -0700
@@ -84,7 +84,6 @@
 	cdev->private->state = DEV_STATE_SENSE_PGID;
 	cdev->private->imask = 0x80;
 	cdev->private->iretry = 5;
-	cdev->private->flags.pgid_supp = 0;
 	memset (&cdev->private->pgid, 0, sizeof (struct pgid));
 	ret = __ccw_device_sense_pgid_start(cdev);
 	if (ret)
@@ -165,14 +164,13 @@
 	switch (__ccw_device_check_sense_pgid(cdev)) {
 	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */
 	case 0:			/* Sense Path Group ID successful. */
-		cdev->private->flags.pgid_supp = 1;
 		opm = sch->schib.pmcw.pim &
 			sch->schib.pmcw.pam &
 			sch->schib.pmcw.pom;
 		for (i=0;i<8;i++) {
 			if (opm == (0x80 << i)) {
 				/* Don't group single path devices. */
-				cdev->private->flags.pgid_supp = 0;
+				cdev->private->options.pgroup = 0;
 				break;
 			}
 		}
@@ -181,7 +179,7 @@
 			       sizeof(struct pgid));
 		/* fall through. */
 	case -EOPNOTSUPP:	/* Sense Path Group ID not supported */
-		ccw_device_sense_pgid_done(cdev, 0);
+		ccw_device_sense_pgid_done(cdev, -EOPNOTSUPP);
 		break;
 	case -ETIME:		/* Sense path group id stopped by timeout. */
 		ccw_device_sense_pgid_done(cdev, -ETIME);
diff -urN linux-2.5.73-bk5/drivers/s390/cio/qdio.h linux-2.5.73-bk6/drivers/s390/cio/qdio.h
--- linux-2.5.73-bk5/drivers/s390/cio/qdio.h	2003-06-22 11:32:36.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/cio/qdio.h	2003-06-28 04:53:19.000000000 -0700
@@ -1,7 +1,7 @@
 #ifndef _CIO_QDIO_H
 #define _CIO_QDIO_H
 
-#define VERSION_CIO_QDIO_H "$Revision: 1.16 $"
+#define VERSION_CIO_QDIO_H "$Revision: 1.17 $"
 
 //#define QDIO_DBF_LIKE_HELL
 
@@ -21,7 +21,15 @@
 #define QDIO_TIMER_POLL_VALUE 1
 #define IQDIO_TIMER_POLL_VALUE 1
 
-#define IQDIO_FILL_LEVEL_TO_POLL (QDIO_MAX_BUFFERS_PER_Q*4/3)
+/*
+ * unfortunately this can't be (QDIO_MAX_BUFFERS_PER_Q*4/3) or so -- as
+ * we never know, whether we'll get initiative again, e.g. to give the
+ * transmit skb's back to the stack, however the stack may be waiting for
+ * them... therefore we define 4 as threshold to start polling (which
+ * will stop as soon as the asynchronous queue catches up)
+ * btw, this only applies to the asynchronous HiperSockets queue
+ */
+#define IQDIO_FILL_LEVEL_TO_POLL 4
 
 #define IQDIO_THININT_ISC 3
 #define IQDIO_DELAY_TARGET 0
diff -urN linux-2.5.73-bk5/drivers/s390/net/ctcmain.c linux-2.5.73-bk6/drivers/s390/net/ctcmain.c
--- linux-2.5.73-bk5/drivers/s390/net/ctcmain.c	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/net/ctcmain.c	2003-06-28 04:53:19.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.42 2003/05/23 17:45:57 felfert Exp $
+ * $Id: ctcmain.c,v 1.43 2003/05/27 11:34:23 mschwide Exp $
  *
  * CTC / ESCON network driver
  *
@@ -36,7 +36,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.42 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.43 $
  *
  */
 
@@ -272,7 +272,7 @@
 print_banner(void)
 {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.42 $";
+	char vbuf[] = "$Revision: 1.43 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -2752,7 +2752,7 @@
 	dev->type = ARPHRD_SLIP;
 	dev->tx_queue_len = 100;
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
-	SET_MODULE_OWNER(&tun->dev);
+	SET_MODULE_OWNER(dev);
 	return dev;
 }
 
diff -urN linux-2.5.73-bk5/drivers/s390/net/ctctty.c linux-2.5.73-bk6/drivers/s390/net/ctctty.c
--- linux-2.5.73-bk5/drivers/s390/net/ctctty.c	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/net/ctctty.c	2003-06-28 04:53:19.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * $Id: ctctty.c,v 1.11 2003/05/06 09:40:55 mschwide Exp $
+ * $Id: ctctty.c,v 1.12 2003/06/17 11:36:44 mschwide Exp $
  *
  * CTC / ESCON network driver, tty interface.
  *
diff -urN linux-2.5.73-bk5/drivers/s390/net/lcs.c linux-2.5.73-bk6/drivers/s390/net/lcs.c
--- linux-2.5.73-bk5/drivers/s390/net/lcs.c	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/net/lcs.c	2003-06-28 04:53:19.000000000 -0700
@@ -11,7 +11,7 @@
  *			  Frank Pavlic (pavlic@de.ibm.com) and
  *		 	  Martin Schwidefsky <schwidefsky@de.ibm.com>
  *
- *    $Revision: 1.51 $	 $Date: 2003/03/28 08:54:40 $
+ *    $Revision: 1.53 $	 $Date: 2003/06/17 11:36:45 $
  *
  * 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
@@ -58,7 +58,7 @@
 /**
  * initialization string for output
  */
-#define VERSION_LCS_C  "$Revision: 1.51 $"
+#define VERSION_LCS_C  "$Revision: 1.53 $"
 
 static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
 
@@ -1785,7 +1785,7 @@
 		dev->set_multicast_list = lcs_set_multicast_list;
 #endif
 	dev->get_stats = lcs_getstats;
-	SET_MODULE_OWNER(&tun->dev);
+	SET_MODULE_OWNER(dev);
 	if (register_netdev(dev) != 0)
 		goto out;
 	netif_stop_queue(dev);
diff -urN linux-2.5.73-bk5/drivers/s390/net/netiucv.c linux-2.5.73-bk6/drivers/s390/net/netiucv.c
--- linux-2.5.73-bk5/drivers/s390/net/netiucv.c	2003-06-22 11:32:56.000000000 -0700
+++ linux-2.5.73-bk6/drivers/s390/net/netiucv.c	2003-06-28 04:53:19.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.19 2003/04/08 16:00:17 mschwide Exp $
+ * $Id: netiucv.c,v 1.20 2003/05/27 11:34:24 mschwide Exp $
  *
  * IUCV network driver
  *
@@ -30,7 +30,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.19 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.20 $
  *
  */
 
@@ -1631,7 +1631,7 @@
 	dev->type                = ARPHRD_SLIP;
 	dev->tx_queue_len        = NETIUCV_QUEUELEN_DEFAULT;
 	dev->flags	         = IFF_POINTOPOINT | IFF_NOARP;
-	SET_MODULE_OWNER(&tun->dev);
+	SET_MODULE_OWNER(dev);
 	return dev;
 }
 
@@ -1717,7 +1717,7 @@
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.19 $";
+	char vbuf[] = "$Revision: 1.20 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
diff -urN linux-2.5.73-bk5/fs/buffer.c linux-2.5.73-bk6/fs/buffer.c
--- linux-2.5.73-bk5/fs/buffer.c	2003-06-22 11:32:56.000000000 -0700
+++ linux-2.5.73-bk6/fs/buffer.c	2003-06-28 04:53:19.000000000 -0700
@@ -1337,7 +1337,7 @@
 
 	check_irqs_on();
 	bh_lru_lock();
-	lru = &per_cpu(bh_lrus, smp_processor_id());
+	lru = &__get_cpu_var(bh_lrus);
 	if (lru->bhs[0] != bh) {
 		struct buffer_head *bhs[BH_LRU_SIZE];
 		int in;
@@ -1381,7 +1381,7 @@
 
 	check_irqs_on();
 	bh_lru_lock();
-	lru = &per_cpu(bh_lrus, smp_processor_id());
+	lru = &__get_cpu_var(bh_lrus);
 	for (i = 0; i < BH_LRU_SIZE; i++) {
 		struct buffer_head *bh = lru->bhs[i];
 
@@ -1474,15 +1474,14 @@
  */
 static void invalidate_bh_lru(void *arg)
 {
-	const int cpu = get_cpu();
-	struct bh_lru *b = &per_cpu(bh_lrus, cpu);
+	struct bh_lru *b = &get_cpu_var(bh_lrus);
 	int i;
 
 	for (i = 0; i < BH_LRU_SIZE; i++) {
 		brelse(b->bhs[i]);
 		b->bhs[i] = NULL;
 	}
-	put_cpu();
+	put_cpu_var(bh_lrus);
 }
 	
 static void invalidate_bh_lrus(void)
diff -urN linux-2.5.73-bk5/fs/compat_ioctl.c linux-2.5.73-bk6/fs/compat_ioctl.c
--- linux-2.5.73-bk5/fs/compat_ioctl.c	2003-06-22 11:33:18.000000000 -0700
+++ linux-2.5.73-bk6/fs/compat_ioctl.c	2003-06-28 04:53:19.000000000 -0700
@@ -1562,6 +1562,8 @@
 
 extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
 
+#ifdef CONFIG_VT
+
 static int vt_check(struct file *file)
 {
 	struct tty_struct *tty;
@@ -1693,6 +1695,8 @@
 	return 0;
 }
 
+#endif /* CONFIG_VT */
+
 static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	mm_segment_t old_fs = get_fs();
@@ -2398,11 +2402,13 @@
 HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
 #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
 HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
+#ifdef CONFIG_VT
 HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
 HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
 HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
 HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl)
 HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
+#endif
 HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl)
 HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl)
 HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl)
diff -urN linux-2.5.73-bk5/fs/lockd/svc.c linux-2.5.73-bk6/fs/lockd/svc.c
--- linux-2.5.73-bk5/fs/lockd/svc.c	2003-06-22 11:32:57.000000000 -0700
+++ linux-2.5.73-bk6/fs/lockd/svc.c	2003-06-28 04:53:19.000000000 -0700
@@ -34,7 +34,6 @@
 #include <linux/sunrpc/svcsock.h>
 #include <linux/lockd/lockd.h>
 #include <linux/nfs.h>
-#include <linux/suspend.h>
 
 #define NLMDBG_FACILITY		NLMDBG_SVC
 #define LOCKD_BUFSIZE		(1024 + NLMSVC_XDRSIZE)
@@ -122,8 +121,6 @@
 	while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) {
 		long timeout = MAX_SCHEDULE_TIMEOUT;
 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_IOTHREAD);
 		if (signalled()) {
 			flush_signals(current);
 			if (nlmsvc_ops) {
diff -urN linux-2.5.73-bk5/fs/nfsd/export.c linux-2.5.73-bk6/fs/nfsd/export.c
--- linux-2.5.73-bk5/fs/nfsd/export.c	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/fs/nfsd/export.c	2003-06-28 04:53:19.000000000 -0700
@@ -195,8 +195,7 @@
 
 static int expkey_show(struct seq_file *m,
 		       struct cache_detail *cd,
-		       struct cache_head *h,
-		       char *pbuf)
+		       struct cache_head *h)
 {
 	struct svc_expkey *ek ;
 
@@ -436,9 +435,8 @@
 static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong);
 
 static int svc_export_show(struct seq_file *m,
-		       struct cache_detail *cd,
-		       struct cache_head *h,
-		       char *pbuf)
+			   struct cache_detail *cd,
+			   struct cache_head *h)
 {
 	struct svc_export *exp ;
 
@@ -1028,17 +1026,11 @@
 		seq_printf(m, "%sanongid=%d", first++?",":"", anong);
 }
 
-static inline void mangle(struct seq_file *m, const char *s)
-{
-	seq_escape(m, s, " \t\n\\");
-}
-
 static int e_show(struct seq_file *m, void *p)
 {
 	struct cache_head *cp = p;
 	struct svc_export *exp = container_of(cp, struct svc_export, h);
 	svc_client *clp;
-	char *pbuf;
 
 	if (p == (void *)1) {
 		seq_puts(m, "# Version 1.1\n");
@@ -1051,17 +1043,7 @@
 	if (cache_check(&svc_export_cache, &exp->h, NULL))
 		return 0;
 	if (cache_put(&exp->h, &svc_export_cache)) BUG();
-	pbuf = m->private;
-	mangle(m, d_path(exp->ex_dentry, exp->ex_mnt,
-			 pbuf, PAGE_SIZE));
-
-	seq_putc(m, '\t');
-	mangle(m, clp->name);
-	seq_putc(m, '(');
-	exp_flags(m, exp->ex_flags, exp->ex_fsid, 
-		  exp->ex_anon_uid, exp->ex_anon_gid);
-	seq_puts(m, ")\n");
-	return 0;
+	return svc_export_show(m, &svc_export_cache, cp);
 }
 
 struct seq_operations nfs_exports_op = {
diff -urN linux-2.5.73-bk5/fs/nfsd/nfs4proc.c linux-2.5.73-bk6/fs/nfsd/nfs4proc.c
--- linux-2.5.73-bk5/fs/nfsd/nfs4proc.c	2003-06-22 11:33:35.000000000 -0700
+++ linux-2.5.73-bk6/fs/nfsd/nfs4proc.c	2003-06-28 04:53:19.000000000 -0700
@@ -55,12 +55,6 @@
 
 #define NFSDDBG_FACILITY		NFSDDBG_PROC
 
-static inline int
-nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
-{
-	return nfs_ok;
-}
-
 /* Note: The organization of the OPEN code seems a little strange; it
  * has been superfluously split into three routines, one of which is named
  * nfsd4_process_open2() even though there is no nfsd4_process_open1()!
@@ -140,10 +134,6 @@
 	status = nfsd4_process_open2(rqstp, current_fh, open);
 	if (status)
 		return status;
-	/*
-	 * To finish the open response, we just need to set the rflags.
-	 */
-	open->op_rflags = 0;
 	return 0;
 }
 
@@ -356,14 +346,51 @@
 static inline int
 nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
 {
+	struct nfs4_stateid *stp;
+	int status;
+
 	/* no need to check permission - this will be done in nfsd_read() */
 
 	if (read->rd_offset >= OFFSET_MAX)
 		return nfserr_inval;
 
+	nfsd4_lock_state();
+	status = nfs_ok;
+	/* For stateid -1, we don't check share reservations.  */
+	if (ONE_STATEID(&read->rd_stateid)) {
+		dprintk("NFSD: nfsd4_read: -1 stateid...\n");
+		goto out;
+	}
+	/*
+	* For stateid 0, the client doesn't have to have the file open, but
+	* we still check for share reservation conflicts. 
+	*/
+	if (ZERO_STATEID(&read->rd_stateid)) {
+		dprintk("NFSD: nfsd4_read: zero stateid...\n");
+		if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_READ))) {
+			dprintk("NFSD: nfsd4_read: conflicting share reservation!\n");
+			goto out;
+		}
+		status = nfs_ok;
+		goto out;
+	}
+	/* check stateid */
+	if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, 
+					CHECK_FH, &stp))) {
+		dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
+		goto out;
+	}
+	status = nfserr_openmode;
+	if (!(stp->st_share_access & NFS4_SHARE_ACCESS_READ)) {
+		dprintk("NFSD: nfsd4_read: file not opened for read!\n");
+		goto out;
+	}
+	status = nfs_ok;
+out:
+	nfsd4_unlock_state();
 	read->rd_rqstp = rqstp;
 	read->rd_fhp = current_fh;
-	return nfs_ok;
+	return status;
 }
 
 static inline int
@@ -425,28 +452,85 @@
 static inline int
 nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
 {
-	return nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, 0, (time_t)0);
+	struct nfs4_stateid *stp;
+	int status = nfs_ok;
+
+	if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
+
+		status = nfserr_bad_stateid;
+		if (ZERO_STATEID(&setattr->sa_stateid) || ONE_STATEID(&setattr->sa_stateid)) {
+			dprintk("NFSD: nfsd4_setattr: magic stateid!\n");
+			return status;
+		}
+
+		nfsd4_lock_state();
+		if ((status = nfs4_preprocess_stateid_op(current_fh, 
+						&setattr->sa_stateid, 
+						CHECK_FH, &stp))) {
+			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
+			goto out;
+		}
+		status = nfserr_openmode;
+		if (!(stp->st_share_access & NFS4_SHARE_ACCESS_WRITE)) {
+			dprintk("NFSD: nfsd4_setattr: not opened for write!\n");
+			goto out;
+		}
+		nfsd4_unlock_state();
+	}
+	return (nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, 0, (time_t)0));
+out:
+	nfsd4_unlock_state();
+	return status;
 }
 
 static inline int
 nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write)
 {
+	struct nfs4_stateid *stp;
+	stateid_t *stateid = &write->wr_stateid;
 	u32 *p;
+	int status = nfs_ok;
 
 	/* no need to check permission - this will be done in nfsd_write() */
 
 	if (write->wr_offset >= OFFSET_MAX)
 		return nfserr_inval;
 
+	nfsd4_lock_state();
+	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
+		dprintk("NFSD: nfsd4_write: zero stateid...\n");
+		if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_WRITE))) {
+			dprintk("NFSD: nfsd4_write: conflicting share reservation!\n");
+			goto out;
+		}
+		goto zero_stateid;
+	}
+	if ((status = nfs4_preprocess_stateid_op(current_fh, stateid, 
+					CHECK_FH, &stp))) {
+		dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
+		goto out;
+	}
+
+	status = nfserr_openmode;
+	if (!(stp->st_share_access & NFS4_SHARE_ACCESS_WRITE)) {
+		dprintk("NFSD: nfsd4_write: file not open for write!\n");
+		goto out;
+	}
+
+zero_stateid:
+	nfsd4_unlock_state();
 	write->wr_bytes_written = write->wr_buflen;
 	write->wr_how_written = write->wr_stable_how;
 	p = (u32 *)write->wr_verifier;
 	*p++ = nfssvc_boot.tv_sec;
 	*p++ = nfssvc_boot.tv_usec;
 
-	return nfsd_write(rqstp, current_fh, write->wr_offset,
+	return (nfsd_write(rqstp, current_fh, write->wr_offset,
 			  write->wr_vec, write->wr_vlen, write->wr_buflen,
-			  &write->wr_how_written);
+			  &write->wr_how_written));
+out:
+	nfsd4_unlock_state();
+	return status;
 }
 
 /* This routine never returns NFS_OK!  If there are no other errors, it
@@ -609,6 +693,12 @@
 		case OP_OPEN:
 			op->status = nfsd4_open(rqstp, &current_fh, &op->u.open);
 			break;
+		case OP_OPEN_CONFIRM:
+			op->status = nfsd4_open_confirm(rqstp, &current_fh, &op->u.open_confirm);
+			break;
+		case OP_OPEN_DOWNGRADE:
+			op->status = nfsd4_open_downgrade(rqstp, &current_fh, &op->u.open_downgrade);
+			break;
 		case OP_PUTFH:
 			op->status = nfsd4_putfh(rqstp, &current_fh, &op->u.putfh);
 			break;
diff -urN linux-2.5.73-bk5/fs/nfsd/nfs4state.c linux-2.5.73-bk6/fs/nfsd/nfs4state.c
--- linux-2.5.73-bk5/fs/nfsd/nfs4state.c	2003-06-22 11:33:00.000000000 -0700
+++ linux-2.5.73-bk6/fs/nfsd/nfs4state.c	2003-06-28 04:53:19.000000000 -0700
@@ -56,12 +56,20 @@
 static u32 current_ownerid = 0;
 static u32 current_fileid = 0;
 static u32 nfs4_init = 0;
+stateid_t zerostateid;             /* bits all 0 */
+stateid_t onestateid;              /* bits all 1 */
 
 /* debug counters */
 u32 list_add_perfile = 0; 
 u32 list_del_perfile = 0;
 u32 add_perclient = 0;
 u32 del_perclient = 0;
+u32 alloc_file = 0;
+u32 free_file = 0;
+u32 alloc_sowner = 0;
+u32 free_sowner = 0;
+u32 vfsopen = 0;
+u32 vfsclose = 0;
 
 /* Locking:
  *
@@ -71,6 +79,18 @@
  */
 static struct semaphore client_sema;
 
+void
+nfsd4_lock_state(void)
+{
+	down(&client_sema);
+}
+
+void
+nfsd4_unlock_state(void)
+{
+	up(&client_sema);
+}
+
 static inline u32
 opaque_hashval(const void *ptr, int nbytes)
 {
@@ -87,6 +107,8 @@
 /* forward declarations */
 static void release_stateowner(struct nfs4_stateowner *sop);
 static void release_stateid(struct nfs4_stateid *stp);
+static void release_file(struct nfs4_file *fp);
+
 
 /* 
  * SETCLIENTID state 
@@ -136,7 +158,8 @@
 {
 	if (clid->cl_boot == boot_time)
 		return 0;
-	printk("NFSD stale clientid (%08x/%08x)\n", clid->cl_boot, clid->cl_id);
+	dprintk("NFSD stale clientid (%08x/%08x)\n", 
+			clid->cl_boot, clid->cl_id);
 	return 1;
 }
 
@@ -294,6 +317,7 @@
 {
 	unsigned int strhashval;
 
+	dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
 	list_del_init(&clp->cl_strhash);
 	list_del_init(&clp->cl_idhash);
 	list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
@@ -646,20 +670,30 @@
 #define OWNER_HASH_SIZE             (1 << OWNER_HASH_BITS)
 #define OWNER_HASH_MASK             (OWNER_HASH_SIZE - 1)
 
+#define ownerid_hashval(id) \
+        ((id) & OWNER_HASH_MASK)
 #define ownerstr_hashval(clientid, ownername) \
         (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK)
 
+static struct list_head	ownerid_hashtbl[OWNER_HASH_SIZE];
 static struct list_head	ownerstr_hashtbl[OWNER_HASH_SIZE];
 
 /* hash table for nfs4_file */
 #define FILE_HASH_BITS                   8
 #define FILE_HASH_SIZE                  (1 << FILE_HASH_BITS)
 #define FILE_HASH_MASK                  (FILE_HASH_SIZE - 1)
+/* hash table for (open)nfs4_stateid */
+#define OPENSTATEID_HASH_BITS              10
+#define OPENSTATEID_HASH_SIZE              (1 << OPENSTATEID_HASH_BITS)
+#define OPENSTATEID_HASH_MASK              (OPENSTATEID_HASH_SIZE - 1)
 
 #define file_hashval(x) \
         ((unsigned int)((x)->dev + (x)->ino + (x)->generation) & FILE_HASH_MASK)
+#define openstateid_hashval(owner_id, file_id)  \
+        (((owner_id) + (file_id)) & OPENSTATEID_HASH_MASK)
 
 static struct list_head file_hashtbl[FILE_HASH_SIZE];
+static struct list_head openstateid_hashtbl[OPENSTATEID_HASH_SIZE];
 
 /* OPEN Share state helper functions */
 static inline struct nfs4_file *
@@ -671,6 +705,7 @@
 		list_add(&fp->fi_hash, &file_hashtbl[hashval]);
 		memcpy(&fp->fi_ino, ino, sizeof(nfs4_ino_desc_t));
 		fp->fi_id = current_fileid++;
+		alloc_file++;
 		return fp;
 	}
 	return (struct nfs4_file *)NULL;
@@ -689,8 +724,7 @@
 			if(!list_empty(&fp->fi_perfile)) {
 				printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
 			}
-			list_del_init(&fp->fi_hash);
-			kfree(fp);
+			release_file(fp);
 		}
 	}
 }
@@ -718,26 +752,31 @@
 		kfree(sop->so_owner.data);
 		kfree(sop);
 		sop = NULL;
+		free_sowner++;
 	}
 }
 
 static struct nfs4_stateowner *
 alloc_init_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
 	struct nfs4_stateowner *sop;
+	unsigned int idhashval;
 
 	if (!(sop = alloc_stateowner(&open->op_owner)))
 		return (struct nfs4_stateowner *)NULL;
+	idhashval = ownerid_hashval(current_ownerid);
+	INIT_LIST_HEAD(&sop->so_idhash);
 	INIT_LIST_HEAD(&sop->so_strhash);
 	INIT_LIST_HEAD(&sop->so_perclient);
 	INIT_LIST_HEAD(&sop->so_peropenstate);
+	list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
 	list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
 	list_add(&sop->so_perclient, &clp->cl_perclient);
 	add_perclient++;
 	sop->so_id = current_ownerid++;
 	sop->so_client = clp;
 	sop->so_seqid = open->op_seqid;
-	/* until open_confirm is coded, pretend it happened! */
-	sop->so_confirmed = 1;
+	sop->so_confirmed = 0;
+	alloc_sowner++;
 	return sop;
 }
 
@@ -746,6 +785,7 @@
 {
 	struct nfs4_stateid *stp;
 
+	list_del_init(&sop->so_idhash);
 	list_del_init(&sop->so_strhash);
 	list_del_init(&sop->so_perclient);
 	del_perclient++;
@@ -759,9 +799,12 @@
 
 static inline void
 init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
+	unsigned int hashval = openstateid_hashval(sop->so_id, fp->fi_id);
 
+	INIT_LIST_HEAD(&stp->st_hash);
 	INIT_LIST_HEAD(&stp->st_peropenstate);
 	INIT_LIST_HEAD(&stp->st_perfile);
+	list_add(&stp->st_hash, &openstateid_hashtbl[hashval]);
 	list_add(&stp->st_peropenstate, &sop->so_peropenstate);
 	list_add_perfile++;
 	list_add(&stp->st_perfile, &fp->fi_perfile);
@@ -778,11 +821,13 @@
 static void
 release_stateid(struct nfs4_stateid *stp) {
 
+	list_del_init(&stp->st_hash);
 	list_del_perfile++;
 	list_del_init(&stp->st_perfile);
 	list_del_init(&stp->st_peropenstate);
 	if(stp->st_vfs_set) {
 		nfsd_close(&stp->st_vfs_file);
+		vfsclose++;
 		dput(stp->st_vfs_file.f_dentry);
 		mntput(stp->st_vfs_file.f_vfsmnt);
 	}
@@ -791,6 +836,37 @@
 	stp = NULL;
 }
 
+static void
+release_file(struct nfs4_file *fp)
+{
+	free_file++;
+	list_del_init(&fp->fi_hash);
+	kfree(fp);
+}	
+
+void
+release_open_state(struct nfs4_stateid *stp)
+{
+	struct nfs4_stateowner *sop = stp->st_stateowner;
+	struct nfs4_file *fp = stp->st_file;
+
+	dprintk("NFSD: release_open_state\n");
+	release_stateid(stp);
+	/*
+	 * release unused nfs4_stateowners.
+	 * XXX will need to be placed  on an  open_stateid_lru list to be
+	 * released by the laundromat service after the lease period
+	 * to enable us to handle CLOSE replay
+	 */
+	if (sop->so_confirmed && list_empty(&sop->so_peropenstate)) {
+		release_stateowner(sop);
+	}
+	/* unused nfs4_file's are releseed. XXX slab cache? */
+	if (list_empty(&fp->fi_perfile)) {
+		release_file(fp);
+	}
+}
+
 static int
 cmp_owner_str(struct nfs4_stateowner *sop, struct nfsd4_open *open) {
 	return ((sop->so_owner.len == open->op_owner.len) && 
@@ -872,6 +948,30 @@
 	ino->generation = inode->i_generation;
 }
 
+int
+nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
+{
+	nfs4_ino_desc_t ino;
+	unsigned int fi_hashval;
+	struct nfs4_file *fp;
+	struct nfs4_stateid *stp;
+	struct list_head *pos, *next;
+
+	dprintk("NFSD: nfs4_share_conflict\n");
+
+	nfs4_init_ino(&ino, current_fh);
+	fi_hashval = file_hashval(&ino);
+	if (find_file(fi_hashval, &ino, &fp)) {
+	/* Search for conflicting share reservations */
+		list_for_each_safe(pos, next, &fp->fi_perfile) {
+			stp = list_entry(pos, struct nfs4_stateid, st_perfile);
+			if (stp->st_share_deny & deny_type)
+				return nfserr_share_denied;
+		}
+	}
+	return nfs_ok;
+}
+
 static inline int
 nfs4_file_upgrade(struct file *filp, unsigned int share_access)
 {
@@ -887,6 +987,15 @@
 	return nfs_ok;
 }
 
+static inline void
+nfs4_file_downgrade(struct file *filp, unsigned int share_access)
+{
+	if (share_access & NFS4_SHARE_ACCESS_WRITE) {
+		put_write_access(filp->f_dentry->d_inode);
+		filp->f_mode = FMODE_READ;
+	}
+}
+
 
 /*
  * nfsd4_process_open1()
@@ -981,7 +1090,6 @@
 	struct nfs4_stateid *stq, *stp = NULL;
 	int status;
 
-
 	status = nfserr_resource;
 	if (!sop)
 		goto out;
@@ -1026,6 +1134,7 @@
 			                      &stp->st_vfs_file)) != 0)
 			goto out_free;
 
+		vfsopen++;
 		dget(stp->st_vfs_file.f_dentry);
 		mntget(stp->st_vfs_file.f_vfsmnt);
 
@@ -1063,6 +1172,13 @@
 	open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
 	status = nfs_ok;
 out:
+	/*
+	* To finish the open response, we just need to set the rflags.
+	*/
+	open->op_rflags = 0;
+	if (!open->op_stateowner->so_confirmed)
+		open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
+
 	up(&client_sema); /*XXX need finer grained locking */
 	return status;
 out_free:
@@ -1154,6 +1270,326 @@
 	schedule_delayed_work(&laundromat_work, t*HZ);
 }
 
+/* search openstateid_hashtbl[] for stateid */
+struct nfs4_stateid *
+find_stateid(stateid_t *stid)
+{
+	struct list_head *pos, *next;
+	struct nfs4_stateid *local = NULL;
+	u32 st_id = stid->si_stateownerid;
+	u32 f_id = stid->si_fileid;
+	unsigned int hashval = openstateid_hashval(st_id, f_id);
+
+	list_for_each_safe(pos, next, &openstateid_hashtbl[hashval]) {
+		local = list_entry(pos, struct nfs4_stateid, st_hash);
+		if((local->st_stateid.si_stateownerid == st_id) &&
+		   (local->st_stateid.si_fileid == f_id))
+			return local;
+	}
+	return NULL;
+}
+
+/* search ownerid_hashtbl[] for stateid owner (stateid->si_stateownerid) */
+struct nfs4_stateowner *
+find_stateowner_id(u32 st_id) {
+	struct list_head *pos, *next;
+	struct nfs4_stateowner *local = NULL;
+	unsigned int hashval = ownerid_hashval(st_id);
+
+	list_for_each_safe(pos, next, &ownerid_hashtbl[hashval]) {
+		local = list_entry(pos, struct nfs4_stateowner, so_idhash);
+		if(local->so_id == st_id)
+			return local;
+	}
+	return NULL;
+}
+
+static inline int
+nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
+{
+	return (fhp->fh_dentry != stp->st_vfs_file.f_dentry);
+}
+
+static int
+STALE_STATEID(stateid_t *stateid)
+{
+	if (stateid->si_boot == boot_time)
+		return 0;
+	printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
+		stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
+		stateid->si_generation);
+	return 1;
+}
+
+
+/*
+* Checks for stateid operations
+*/
+int
+nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
+{
+	struct nfs4_stateid *stp;
+	int status;
+
+	dprintk("NFSD: preprocess_stateid_op:stateid = (%08x/%08x/%08x/%08x)\n",
+		stateid->si_boot, stateid->si_stateownerid, 
+		stateid->si_fileid, stateid->si_generation); 
+
+	*stpp = NULL;
+
+	/* STALE STATEID */
+	status = nfserr_stale_stateid;
+	if (STALE_STATEID(stateid)) 
+		goto out;
+
+	/* BAD STATEID */
+	status = nfserr_bad_stateid;
+	if (!(stp = find_stateid(stateid))) {
+		dprintk("NFSD: process stateid: no open stateid!\n");
+		goto out;
+	}
+	if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
+		dprintk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
+		goto out;
+	}
+	if (!stp->st_stateowner->so_confirmed) {
+		dprintk("process_stateid: lockowner not confirmed yet!\n");
+		goto out;
+	}
+	if (stateid->si_generation > stp->st_stateid.si_generation) {
+		dprintk("process_stateid: future stateid?!\n");
+		goto out;
+	}
+
+	/* OLD STATEID */
+	status = nfserr_old_stateid;
+	if (stateid->si_generation < stp->st_stateid.si_generation) {
+		dprintk("process_stateid: old stateid!\n");
+		goto out;
+	}
+	*stpp = stp;
+	status = nfs_ok;
+	renew_client(stp->st_stateowner->so_client);
+out:
+	return status;
+}
+
+
+/* 
+ * Checks for sequence id mutating operations. 
+ *
+ * XXX need to code replay cache logic
+ */
+int
+nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp)
+{
+	int status;
+	struct nfs4_stateid *stp;
+	struct nfs4_stateowner *sop;
+
+	dprintk("NFSD: preprocess_seqid_op: seqid=%d " 
+			"stateid = (%08x/%08x/%08x/%08x)\n", seqid,
+		stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
+		stateid->si_generation);
+			        
+	*stpp = NULL;
+	*sopp = NULL;
+
+	status = nfserr_bad_stateid;
+	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
+		printk("NFSD: preprocess_seqid_op: magic stateid!\n");
+		goto out;
+	}
+
+	status = nfserr_stale_stateid;
+	if (STALE_STATEID(stateid))
+		goto out;
+	/*
+	* We return BAD_STATEID if filehandle doesn't match stateid, 
+	* the confirmed flag is incorrecly set, or the generation 
+	* number is incorrect.  
+	* If there is no entry in the openfile table for this id, 
+	* we can't always return BAD_STATEID;
+	* this might be a retransmitted CLOSE which has arrived after 
+	* the openfile has been released.
+	*/
+	if (!(stp = find_stateid(stateid)))
+		goto no_nfs4_stateid;
+
+	status = nfserr_bad_stateid;
+
+	if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
+		printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
+		goto out;
+	}
+
+	*stpp = stp;
+	*sopp = sop = stp->st_stateowner;
+
+	/*
+	*  We now validate the seqid and stateid generation numbers.
+	*  For the moment, we ignore the possibility of 
+	*  generation number wraparound.
+	*/
+	if (seqid != sop->so_seqid + 1)
+		goto check_replay;
+
+	if (sop->so_confirmed) {
+		if (flags & CONFIRM) {
+			printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
+			goto out;
+		}
+	}
+	else {
+		if (!(flags & CONFIRM)) {
+			printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
+			goto out;
+		}
+	}
+	if (stateid->si_generation > stp->st_stateid.si_generation) {
+		printk("NFSD: preprocess_seqid_op: future stateid?!\n");
+		goto out;
+	}
+
+	status = nfserr_old_stateid;
+	if (stateid->si_generation < stp->st_stateid.si_generation) {
+		printk("NFSD: preprocess_seqid_op: old stateid!\n");
+		goto out;
+	}
+	/* XXX renew the client lease here */
+	status = nfs_ok;
+
+out:
+	return status;
+
+no_nfs4_stateid:
+
+	/*
+	* We determine whether this is a bad stateid or a replay, 
+	* starting by trying to look up the stateowner.
+	* If stateowner is not found - stateid is bad.
+	*/
+	if (!(sop = find_stateowner_id(stateid->si_stateownerid))) {
+		printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
+		status = nfserr_bad_stateid;
+		goto out;
+	}
+
+check_replay:
+	status = nfserr_bad_seqid;
+	if (seqid == sop->so_seqid) {
+		printk("NFSD: preprocess_seqid_op: retransmission?\n");
+		/* XXX will need to indicate replay to calling function here */
+	} else 
+		printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
+
+	goto out;
+}
+
+int
+nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
+{
+	int status;
+	struct nfs4_stateowner *sop;
+	struct nfs4_stateid *stp;
+
+	dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
+			current_fh->fh_dentry->d_name.len,
+			current_fh->fh_dentry->d_name.name);
+	oc->oc_stateowner = NULL;
+	down(&client_sema); /* XXX need finer grained locking */
+
+	if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
+					&oc->oc_req_stateid,
+					CHECK_FH | CONFIRM,
+					&oc->oc_stateowner, &stp)))
+		goto out; 
+
+	sop = oc->oc_stateowner;
+	sop->so_confirmed = 1;
+	update_stateid(&stp->st_stateid);
+	memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
+	/* XXX renew the client lease here */
+	dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " 
+		"stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid,
+		         stp->st_stateid.si_boot,
+		         stp->st_stateid.si_stateownerid,
+		         stp->st_stateid.si_fileid,
+		         stp->st_stateid.si_generation);
+	status = nfs_ok;
+out:
+	up(&client_sema);
+	return status;
+}
+int
+nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
+{
+	int status;
+	struct nfs4_stateid *stp;
+
+	dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 
+			current_fh->fh_dentry->d_name.len, 
+			current_fh->fh_dentry->d_name.name);
+
+	down(&client_sema); /* XXX need finer grained locking */
+	if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, 
+					&od->od_stateid, 
+					CHECK_FH, &od->od_stateowner, &stp)))
+		goto out; 
+
+	status = nfserr_inval;
+	if (od->od_share_access & ~stp->st_share_access) {
+		dprintk("NFSD:access not a subset current=%08x, desired=%08x\n", 
+			stp->st_share_access, od->od_share_access); 
+		goto out;
+	}
+	if (od->od_share_deny & ~stp->st_share_deny) {
+		dprintk("NFSD:deny not a subset current=%08x, desired=%08x\n", 
+			stp->st_share_deny, od->od_share_deny);
+		goto out;
+	}
+	nfs4_file_downgrade(&stp->st_vfs_file, 
+	stp->st_share_access & ~od->od_share_access);
+	stp->st_share_access = od->od_share_access;
+	stp->st_share_deny = od->od_share_deny;
+	update_stateid(&stp->st_stateid);
+	memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
+	status = nfs_ok;
+out:
+	up(&client_sema);
+	return status;
+}
+
+int
+nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
+{
+	int status;
+	struct nfs4_stateid *stp;
+
+	dprintk("NFSD: nfsd4_close on file %.*s\n", 
+			current_fh->fh_dentry->d_name.len, 
+			current_fh->fh_dentry->d_name.name);
+
+	down(&client_sema); /* XXX need finer grained locking */
+	if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, 
+					&close->cl_stateid, 
+					CHECK_FH, 
+					&close->cl_stateowner, &stp)))
+		goto out; 
+	/*
+	*  Return success, but first update the stateid.
+	*/
+	status = nfs_ok;
+	update_stateid(&stp->st_stateid);
+	memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
+
+	/* release_open_state() calls nfsd_close() if needed */
+	release_open_state(stp);
+out:
+	up(&client_sema);
+	return status;
+}
+
 void 
 nfs4_state_init(void)
 {
@@ -1172,7 +1608,14 @@
 	}
 	for (i = 0; i < OWNER_HASH_SIZE; i++) {
 		INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
+		INIT_LIST_HEAD(&ownerid_hashtbl[i]);
+	}
+	for (i = 0; i < OPENSTATEID_HASH_SIZE; i++) {
+		INIT_LIST_HEAD(&openstateid_hashtbl[i]);
 	}
+	memset(&zerostateid, 0, sizeof(stateid_t));
+	memset(&onestateid, ~0, sizeof(stateid_t));
+
 	INIT_LIST_HEAD(&client_lru);
 	init_MUTEX(&client_sema);
 	boot_time = get_seconds();
@@ -1206,6 +1649,12 @@
 			list_add_perfile, list_del_perfile);
 	dprintk("NFSD: add_perclient %d del_perclient %d\n",
 			add_perclient, del_perclient);
+	dprintk("NFSD: alloc_file %d free_file %d\n",
+			alloc_file, free_file);
+	dprintk("NFSD: alloc_sowner %d free_sowner %d\n",
+			alloc_sowner, free_sowner);
+	dprintk("NFSD: vfsopen %d vfsclose %d\n",
+			vfsopen, vfsclose);
 }
 
 void
diff -urN linux-2.5.73-bk5/fs/nfsd/nfs4xdr.c linux-2.5.73-bk6/fs/nfsd/nfs4xdr.c
--- linux-2.5.73-bk5/fs/nfsd/nfs4xdr.c	2003-06-22 11:33:10.000000000 -0700
+++ linux-2.5.73-bk6/fs/nfsd/nfs4xdr.c	2003-06-28 04:53:19.000000000 -0700
@@ -660,6 +660,34 @@
 }
 
 static int
+nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
+{
+	DECODE_HEAD;
+		    
+	READ_BUF(4 + sizeof(stateid_t));
+	READ32(open_conf->oc_req_stateid.si_generation);
+	COPYMEM(&open_conf->oc_req_stateid.si_opaque, sizeof(stateid_opaque_t));
+	READ32(open_conf->oc_seqid);
+						        
+	DECODE_TAIL;
+}
+
+static int
+nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
+{
+	DECODE_HEAD;
+		    
+	READ_BUF(4 + sizeof(stateid_t));
+	READ32(open_down->od_stateid.si_generation);
+	COPYMEM(&open_down->od_stateid.si_opaque, sizeof(stateid_opaque_t));
+	READ32(open_down->od_seqid);
+	READ32(open_down->od_share_access);
+	READ32(open_down->od_share_deny);
+						        
+	DECODE_TAIL;
+}
+
+static int
 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
 {
 	DECODE_HEAD;
@@ -953,6 +981,12 @@
 		case OP_OPEN:
 			op->status = nfsd4_decode_open(argp, &op->u.open);
 			break;
+		case OP_OPEN_CONFIRM:
+			op->status = nfsd4_decode_open_confirm(argp, &op->u.open_confirm);
+			break;
+		case OP_OPEN_DOWNGRADE:
+			op->status = nfsd4_decode_open_downgrade(argp, &op->u.open_downgrade);
+			break;
 		case OP_PUTFH:
 			op->status = nfsd4_decode_putfh(argp, &op->u.putfh);
 			break;
@@ -1057,6 +1091,21 @@
 } while (0)
 #define ADJUST_ARGS()		resp->p = p
 
+/*
+ * Routine for encoding the result of a
+ * "seqid-mutating" NFSv4 operation.  This is
+ * where seqids are incremented
+ */
+
+#define ENCODE_SEQID_OP_TAIL(stateowner)		\
+	BUG_ON(!stateowner);				\
+	if (seqid_mutating_err(nfserr) && stateowner) {	\
+		if (stateowner->so_confirmed)		\
+			stateowner->so_seqid++;		\
+	}						\
+	return nfserr;
+
+
 static u32 nfs4_ftypes[16] = {
         NF4BAD,  NF4FIFO, NF4CHR, NF4BAD,
         NF4DIR,  NF4BAD,  NF4BLK, NF4BAD,
@@ -1702,6 +1751,36 @@
 }
 
 static int
+nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc)
+{
+	ENCODE_HEAD;
+				        
+	if (!nfserr) {
+		RESERVE_SPACE(sizeof(stateid_t));
+		WRITE32(oc->oc_resp_stateid.si_generation);
+		WRITEMEM(&oc->oc_resp_stateid.si_opaque, sizeof(stateid_opaque_t));
+		ADJUST_ARGS();
+	}
+
+	ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
+}
+
+static int
+nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od)
+{
+	ENCODE_HEAD;
+				        
+	if (!nfserr) {
+		RESERVE_SPACE(sizeof(stateid_t));
+		WRITE32(od->od_stateid.si_generation);
+		WRITEMEM(&od->od_stateid.si_opaque, sizeof(stateid_opaque_t));
+		ADJUST_ARGS();
+	}
+
+	ENCODE_SEQID_OP_TAIL(od->od_stateowner);
+}
+
+static int
 nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read)
 {
 	u32 eof;
@@ -2013,6 +2092,12 @@
 	case OP_OPEN:
 		nfsd4_encode_open(resp, op->status, &op->u.open);
 		break;
+	case OP_OPEN_CONFIRM:
+		nfsd4_encode_open_confirm(resp, op->status, &op->u.open_confirm);
+		break;
+	case OP_OPEN_DOWNGRADE:
+		nfsd4_encode_open_downgrade(resp, op->status, &op->u.open_downgrade);
+		break;
 	case OP_PUTFH:
 		break;
 	case OP_PUTROOTFH:
diff -urN linux-2.5.73-bk5/fs/nfsd/nfsctl.c linux-2.5.73-bk6/fs/nfsd/nfsctl.c
--- linux-2.5.73-bk5/fs/nfsd/nfsctl.c	2003-06-22 11:32:35.000000000 -0700
+++ linux-2.5.73-bk6/fs/nfsd/nfsctl.c	2003-06-28 04:53:19.000000000 -0700
@@ -175,32 +175,14 @@
 extern struct seq_operations nfs_exports_op;
 static int exports_open(struct inode *inode, struct file *file)
 {
-	int res;
-	char *namebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (namebuf == NULL)
-		return -ENOMEM;
-
-	res = seq_open(file, &nfs_exports_op);
-	if (res)
-		kfree(namebuf);
-	else
-		((struct seq_file *)file->private_data)->private = namebuf;
-
-	return res;
-}
-static int exports_release(struct inode *inode, struct file *file)
-{
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	kfree(m->private);
-	m->private = NULL;
-	return seq_release(inode, file);
+	return seq_open(file, &nfs_exports_op);
 }
 
 static struct file_operations exports_operations = {
 	.open		= exports_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
-	.release	= exports_release,
+	.release	= seq_release,
 };
 
 /*----------------------------------------------------------------------------*/
diff -urN linux-2.5.73-bk5/include/asm-s390/ccwdev.h linux-2.5.73-bk6/include/asm-s390/ccwdev.h
--- linux-2.5.73-bk5/include/asm-s390/ccwdev.h	2003-06-22 11:33:15.000000000 -0700
+++ linux-2.5.73-bk6/include/asm-s390/ccwdev.h	2003-06-28 04:53:20.000000000 -0700
@@ -115,6 +115,8 @@
 #define CCWDEV_EARLY_NOTIFICATION	0x0001
 /* Report all interrupt conditions. */
 #define CCWDEV_REPORT_ALL	 	0x0002
+/* Try to perform path grouping. */
+#define CCWDEV_DO_PATHGROUP             0x0004
 
 /*
  * ccw_device_start()
diff -urN linux-2.5.73-bk5/include/asm-s390/compat.h linux-2.5.73-bk6/include/asm-s390/compat.h
--- linux-2.5.73-bk5/include/asm-s390/compat.h	2003-06-22 11:32:34.000000000 -0700
+++ linux-2.5.73-bk6/include/asm-s390/compat.h	2003-06-28 04:53:20.000000000 -0700
@@ -94,6 +94,7 @@
 	s32		f_ffree;
 	compat_fsid_t	f_fsid;
 	s32		f_namelen;
+	s32		f_frsize;
 	s32		f_spare[6];
 };
 
diff -urN linux-2.5.73-bk5/include/asm-s390/dasd.h linux-2.5.73-bk6/include/asm-s390/dasd.h
--- linux-2.5.73-bk5/include/asm-s390/dasd.h	2003-06-22 11:32:34.000000000 -0700
+++ linux-2.5.73-bk6/include/asm-s390/dasd.h	2003-06-28 04:53:20.000000000 -0700
@@ -8,16 +8,8 @@
  * any future changes wrt the API will result in a change of the APIVERSION reported
  * to userspace by the DASDAPIVER-ioctl
  *
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
  *
- * History of changes (starts July 2000)
- * 05/04/01 created by moving the kernel interface to drivers/s390/block/dasd_int.h
- * 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2)
- * 01/23/02 DASD_API_VERSION 3 - added BIODASDPSRD (and BIODASDENAPAV) IOCTL
- * 02/15/02 DASD_API_VERSION 4 - added BIODASDSATTR IOCTL
- * ##/##/## DASD_API_VERSION 5 - added boxed dasd support TOBEDONE
- * 21/06/02 DASD_API_VERSION 6 - fixed HDIO_GETGEO: geo.start is in sectors!
- *         
  */
 
 #ifndef DASD_H
@@ -226,6 +218,10 @@
 #define BIODASDSLCK    _IO(DASD_IOCTL_LETTER,4) /* steal lock */
 /* reset profiling information of a device */
 #define BIODASDPRRST   _IO(DASD_IOCTL_LETTER,5)
+/* Quiesce IO on device */
+#define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6) 
+/* Resume IO on device */
+#define BIODASDRESUME  _IO(DASD_IOCTL_LETTER,7) 
 
 
 /* retrieve API version number */
diff -urN linux-2.5.73-bk5/include/asm-s390/hardirq.h linux-2.5.73-bk6/include/asm-s390/hardirq.h
--- linux-2.5.73-bk5/include/asm-s390/hardirq.h	2003-06-22 11:33:35.000000000 -0700
+++ linux-2.5.73-bk6/include/asm-s390/hardirq.h	2003-06-28 04:53:20.000000000 -0700
@@ -105,6 +105,4 @@
   extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
-extern void show_stack(unsigned long * esp);
-
 #endif /* __ASM_HARDIRQ_H */
diff -urN linux-2.5.73-bk5/include/asm-s390/queue.h linux-2.5.73-bk6/include/asm-s390/queue.h
--- linux-2.5.73-bk5/include/asm-s390/queue.h	2003-06-22 11:33:04.000000000 -0700
+++ linux-2.5.73-bk6/include/asm-s390/queue.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,170 +0,0 @@
-/*
- *  include/asm-s390/queue.h
- *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- *
- *  A little set of queue utilies.
- */
-#ifndef __ASM_QUEUE_H
-#define __ASM_QUEUE_H
-#include <linux/stddef.h>
-
-typedef struct queue
-{
-	struct queue *next;	
-} queue;
-
-typedef queue list;
-
-typedef struct
-{
-	queue *head;
-	queue *tail;
-} qheader;
-
-static __inline__ void init_queue(qheader *qhead)
-{
-	memset(qhead,0,sizeof(*qhead));
-}
-
-static __inline__ void enqueue_tail(qheader *qhead,queue *member)
-{	
-	if(member)
-	{
-		queue *tail=qhead->tail;
-
-		if(tail)
-			tail->next=member;
-		else
-			
-			qhead->head=member;
-		qhead->tail=member;
-		member->next=NULL;
-	}
-} 
-
-static __inline__ queue *dequeue_head(qheader *qhead)
-{
-	queue *head=qhead->head,*next_head;
-
-	if(head)
-	{
-		next_head=head->next;
-		qhead->head=next_head;
-	        if(!next_head)
-			qhead->tail=NULL;
-	}
-	return(head);
-}
-
-static __inline__ void init_list(list **lhead)
-{
-	*lhead=NULL;
-}
-
-static __inline__ void add_to_list(list **lhead,list *member)
-{
-	member->next=*lhead;
-	*lhead=member;
-}
-
-static __inline__ list *remove_listhead(list **lhead)
-{
-	list *oldhead=*lhead;
-
-	if(oldhead)
-		*lhead=(*lhead)->next;
-	return(oldhead);
-}
-
-static __inline__ void add_to_list_tail(list **lhead,list *member)
-{
-	list *curr,*prev;
-	if(*lhead==NULL)
-		*lhead=member;
-	else
-	{
-		prev=*lhead;
-		for(curr=(*lhead)->next;curr!=NULL;curr=curr->next)
-			prev=curr;
-		prev->next=member;
-	}
-}
-static __inline__ void add_to_list_tail_null(list **lhead,list *member)
-{
-	member->next=NULL;
-	add_to_list_tail_null(lhead,member);
-}
-
-
-static __inline__ int is_in_list(list *lhead,list *member)
-{
-	list *curr;
-
-	for(curr=lhead;curr!=NULL;curr=curr->next)
-		if(curr==member)
-			return(1);
-	return(0);
-}
-
-static __inline__ int get_prev(list *lhead,list *member,list **prev)
-{
-	list *curr;
-
-	*prev=NULL;
-	for(curr=lhead;curr!=NULL;curr=curr->next)
-	{
-		if(curr==member)
-			return(1);
-		*prev=curr;
-	}
-	*prev=NULL;
-	return(0);
-}
-
-
-
-static __inline__ int remove_from_list(list **lhead,list *member)
-{
-	list *prev;
-
-	if(get_prev(*lhead,member,&prev))
-	{
-
-		if(prev)
-			prev->next=member->next;
-		else
-			*lhead=member->next;
-		return(1);
-	}
-	return(0);
-}
-
-static __inline__ int remove_from_queue(qheader *qhead,queue *member)
-{
-	queue *prev;
-
-	if(get_prev(qhead->head,(list *)member,(list **)&prev))
-	{
-
-		if(prev)
-		{
-			prev->next=member->next;
-			if(prev->next==NULL)
-				qhead->tail=prev;
-		}
-		else
-		{
-			if(qhead->head==qhead->tail)
-				qhead->tail=NULL;
-			qhead->head=member->next;
-		}
-		return(1);
-	}
-	return(0);
-}
-
-#endif /* __ASM_QUEUE_H */
-
diff -urN linux-2.5.73-bk5/include/asm-s390/statfs.h linux-2.5.73-bk6/include/asm-s390/statfs.h
--- linux-2.5.73-bk5/include/asm-s390/statfs.h	2003-06-22 11:33:34.000000000 -0700
+++ linux-2.5.73-bk6/include/asm-s390/statfs.h	2003-06-28 04:53:20.000000000 -0700
@@ -9,6 +9,10 @@
 #ifndef _S390_STATFS_H
 #define _S390_STATFS_H
 
+#ifndef __s390x__
+#include <asm-generic/statfs.h>
+#else
+
 #ifndef __KERNEL_STRICT_NAMES
 
 #include <linux/types.h>
@@ -17,19 +21,25 @@
 
 #endif
 
+/*
+ * This is ugly -- we're already 64-bit clean, so just duplicate the 
+ * definitions.
+ */
 struct statfs {
-#ifndef __s390x__
-	long f_type;
-	long f_bsize;
+	int  f_type;
+	int  f_bsize;
 	long f_blocks;
 	long f_bfree;
 	long f_bavail;
 	long f_files;
 	long f_ffree;
 	__kernel_fsid_t f_fsid;
-	long f_namelen;
-	long f_spare[6];
-#else /* __s390x__ */
+	int  f_namelen;
+	int  f_frsize;
+	int  f_spare[5];
+};
+
+struct statfs64 {
 	int  f_type;
 	int  f_bsize;
 	long f_blocks;
@@ -39,8 +49,9 @@
 	long f_ffree;
 	__kernel_fsid_t f_fsid;
 	int  f_namelen;
-	int  f_spare[6];
-#endif /* __s390x__ */
+	int  f_frsize;
+	int  f_spare[5];
 };
 
+#endif /* __s390x__ */
 #endif
diff -urN linux-2.5.73-bk5/include/linux/ide.h linux-2.5.73-bk6/include/linux/ide.h
--- linux-2.5.73-bk5/include/linux/ide.h	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/ide.h	2003-06-28 04:53:20.000000000 -0700
@@ -726,7 +726,6 @@
 	unsigned ata_flash	: 1;	/* 1=present, 0=default */
 	unsigned blocked        : 1;	/* 1=powermanagment told us not to do anything, so sleep nicely */
 	unsigned vdma		: 1;	/* 1=doing PIO over DMA 0=doing normal DMA */
-	unsigned queue_setup	: 1;
 	unsigned addressing;		/*      : 3;
 					 *  0=28-bit
 					 *  1=48-bit
@@ -1777,7 +1776,8 @@
 static inline void ide_release_dma(ide_hwif_t *drive) {;}
 #endif
 
-extern void hwif_unregister(ide_hwif_t *);
+extern int ide_hwif_request_regions(ide_hwif_t *hwif);
+extern void ide_hwif_release_regions(ide_hwif_t* hwif);
 extern void ide_unregister (unsigned int index);
 
 extern void export_ide_init_queue(ide_drive_t *);
diff -urN linux-2.5.73-bk5/include/linux/nfs.h linux-2.5.73-bk6/include/linux/nfs.h
--- linux-2.5.73-bk5/include/linux/nfs.h	2003-06-22 11:33:05.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/nfs.h	2003-06-28 04:53:20.000000000 -0700
@@ -100,7 +100,18 @@
 	NFSERR_RECLAIM_CONFLICT = 10035,/*       v4 */
 	NFSERR_BAD_XDR = 10036,		/*       v4 */
 	NFSERR_LOCKS_HELD = 10037,	/*       v4 */
-	NFSERR_REPLAY_ME = 10038	/*       v4 */
+	NFSERR_OPENMODE = 10038,       /*       v4 */
+	NFSERR_BADOWNER = 10039,       /*       v4 */
+	NFSERR_BADCHAR = 10040,        /*       v4 */
+	NFSERR_BADNAME = 10041,        /*       v4 */
+	NFSERR_BAD_RANGE = 10042,      /*       v4 */
+	NFSERR_LOCK_NOTSUPP = 10043,   /*       v4 */
+	NFSERR_OP_ILLEGAL = 10044,     /*       v4 */
+	NFSERR_DEADLOCK = 10045,       /*       v4 */
+	NFSERR_FILE_OPEN = 10046,      /*       v4 */
+	NFSERR_ADMIN_REVOKED = 10047,  /*       v4 */
+	NFSERR_CB_PATH_DOWN = 10048,   /*       v4 */
+	NFSERR_REPLAY_ME = 10049	/*       v4 */
 };
 
 /* NFSv2 file types - beware, these are not the same in NFSv3 */
diff -urN linux-2.5.73-bk5/include/linux/nfs4.h linux-2.5.73-bk6/include/linux/nfs4.h
--- linux-2.5.73-bk5/include/linux/nfs4.h	2003-06-22 11:32:45.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/nfs4.h	2003-06-28 04:53:20.000000000 -0700
@@ -35,6 +35,8 @@
 #define NFS4_SHARE_ACCESS_READ	0x0001
 #define NFS4_SHARE_ACCESS_WRITE	0x0002
 #define NFS4_SHARE_ACCESS_BOTH	0x0003
+#define NFS4_SHARE_DENY_READ	0x0001
+#define NFS4_SHARE_DENY_WRITE	0x0002
 
 #define NFS4_SET_TO_SERVER_TIME	0
 #define NFS4_SET_TO_CLIENT_TIME	1
diff -urN linux-2.5.73-bk5/include/linux/nfsd/nfsd.h linux-2.5.73-bk6/include/linux/nfsd/nfsd.h
--- linux-2.5.73-bk5/include/linux/nfsd/nfsd.h	2003-06-22 11:33:32.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/nfsd/nfsd.h	2003-06-28 04:53:20.000000000 -0700
@@ -189,6 +189,7 @@
 #define	nfserr_not_same		__constant_htonl(NFSERR_NOT_SAME)
 #define	nfserr_readdir_nospc	__constant_htonl(NFSERR_READDIR_NOSPC)
 #define	nfserr_bad_xdr		__constant_htonl(NFSERR_BAD_XDR)
+#define	nfserr_openmode		__constant_htonl(NFSERR_OPENMODE)
 
 /* error codes for internal use */
 /* if a request fails due to kmalloc failure, it gets dropped.
diff -urN linux-2.5.73-bk5/include/linux/nfsd/state.h linux-2.5.73-bk6/include/linux/nfsd/state.h
--- linux-2.5.73-bk5/include/linux/nfsd/state.h	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/nfsd/state.h	2003-06-28 04:53:20.000000000 -0700
@@ -59,6 +59,12 @@
 #define si_stateownerid   si_opaque.so_stateownerid
 #define si_fileid         si_opaque.so_fileid
 
+extern stateid_t zerostateid;
+extern stateid_t onestateid;
+
+#define ZERO_STATEID(stateid)       (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
+#define ONE_STATEID(stateid)        (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
+
 /*
  * struct nfs4_client - one per client.  Clientids live here.
  * 	o Each nfs4_client is hashed by clientid.
@@ -83,16 +89,12 @@
 	nfs4_verifier		cl_confirm;	/* generated by server */
 };
 
-extern time_t nfs4_laundromat(void);
-int nfsd4_renew(clientid_t *clid);
-
 static inline void
 update_stateid(stateid_t *stateid)
 {
-stateid->si_generation++;
+	stateid->si_generation++;
 }
 
-
 /*
 * nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner
 *
@@ -100,6 +102,7 @@
 *              reverences when we release a stateowner.
 */
 struct nfs4_stateowner {
+	struct list_head        so_idhash;   /* hash by so_id */
 	struct list_head        so_strhash;   /* hash by op_name */
 	struct list_head        so_perclient; /* nfs4_client->cl_perclient */
 	struct list_head        so_peropenstate; /* list: nfs4_stateid */
@@ -136,6 +139,7 @@
 */
 
 struct nfs4_stateid {
+	struct list_head              st_hash; /* openstateid_hashtbl[]*/
 	struct list_head              st_perfile; /* file_hashtbl[]*/
 	struct list_head              st_peropenstate; /* nfs4_stateowner->so_peropenstate */
 	struct nfs4_stateowner      * st_stateowner;
@@ -147,4 +151,22 @@
 	unsigned int                  st_share_deny;
 };
 
+/* flags for preprocess_seqid_op() */
+#define CHECK_FH                0x00000001
+#define CONFIRM                 0x00000002
+
+#define seqid_mutating_err(err)                       \
+	(((err) != nfserr_stale_clientid) &&    \
+	((err) != nfserr_bad_seqid) &&          \
+	((err) != nfserr_stale_stateid) &&      \
+	((err) != nfserr_bad_stateid))
+
+extern time_t nfs4_laundromat(void);
+extern int nfsd4_renew(clientid_t *clid);
+extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, 
+		stateid_t *stateid, int flags, struct nfs4_stateid **stpp);
+extern int nfs4_share_conflict(struct svc_fh *current_fh, 
+		unsigned int deny_type);
+extern void nfsd4_lock_state(void);
+extern void nfsd4_unlock_state(void);
 #endif   /* NFSD4_STATE_H */
diff -urN linux-2.5.73-bk5/include/linux/nfsd/xdr4.h linux-2.5.73-bk6/include/linux/nfsd/xdr4.h
--- linux-2.5.73-bk5/include/linux/nfsd/xdr4.h	2003-06-22 11:32:34.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/nfsd/xdr4.h	2003-06-28 04:53:20.000000000 -0700
@@ -68,6 +68,7 @@
 struct nfsd4_close {
 	u32		cl_seqid;           /* request */
 	stateid_t	cl_stateid;         /* request+response */
+	struct nfs4_stateowner * cl_stateowner;	/* response */
 };
 
 struct nfsd4_commit {
@@ -147,6 +148,22 @@
 #define op_iattr	u.iattr
 #define op_verf		u.verf
 
+struct nfsd4_open_confirm {
+	stateid_t	oc_req_stateid		/* request */;
+	u32		oc_seqid    		/* request */;
+	stateid_t	oc_resp_stateid		/* response */;
+	struct nfs4_stateowner * oc_stateowner;	/* response */
+};
+
+struct nfsd4_open_downgrade {
+	stateid_t       od_stateid;
+	u32             od_seqid;
+	u32             od_share_access;
+	u32             od_share_deny;
+	struct nfs4_stateowner *od_stateowner;
+};
+
+
 struct nfsd4_read {
 	stateid_t	rd_stateid;         /* request */
 	u64		rd_offset;          /* request */
@@ -252,6 +269,8 @@
 		struct nfsd4_lookup		lookup;
 		struct nfsd4_verify		nverify;
 		struct nfsd4_open		open;
+		struct nfsd4_open_confirm	open_confirm;
+		struct nfsd4_open_downgrade	open_downgrade;
 		struct nfsd4_putfh		putfh;
 		struct nfsd4_read		read;
 		struct nfsd4_readdir		readdir;
@@ -315,16 +334,27 @@
 }
 
 int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *);
-int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *, struct nfsd4_compoundargs *);
-int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *, struct nfsd4_compoundres *);
-
+int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *, 
+		struct nfsd4_compoundargs *);
+int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *, 
+		struct nfsd4_compoundres *);
 void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
 int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
-		       struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval);
-extern int nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid);
-extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm);
+		       struct dentry *dentry, u32 *buffer, int *countp, 
+		       u32 *bmval);
+extern int nfsd4_setclientid(struct svc_rqst *rqstp, 
+		struct nfsd4_setclientid *setclid);
+extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, 
+		struct nfsd4_setclientid_confirm *setclientid_confirm);
 extern int nfsd4_process_open1(struct nfsd4_open *open);
-extern int nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open);
+extern int nfsd4_process_open2(struct svc_rqst *rqstp, 
+		struct svc_fh *current_fh, struct nfsd4_open *open);
+extern int nfsd4_open_confirm(struct svc_rqst *rqstp, 
+		struct svc_fh *current_fh, struct nfsd4_open_confirm *oc);
+extern  int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
+		struct nfsd4_close *close);
+extern int nfsd4_open_downgrade(struct svc_rqst *rqstp, 
+		struct svc_fh *current_fh, struct nfsd4_open_downgrade *od);
 #endif
 
 /*
diff -urN linux-2.5.73-bk5/include/linux/rtnetlink.h linux-2.5.73-bk6/include/linux/rtnetlink.h
--- linux-2.5.73-bk5/include/linux/rtnetlink.h	2003-06-22 11:33:07.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/rtnetlink.h	2003-06-28 04:53:20.000000000 -0700
@@ -284,9 +284,17 @@
 #define RTAX_REORDERING RTAX_REORDERING
 	RTAX_HOPLIMIT,
 #define RTAX_HOPLIMIT RTAX_HOPLIMIT
+	RTAX_INITCWND,
+#define RTAX_INITCWND RTAX_INITCWND
+	RTAX_FEATURES,
+#define RTAX_FEATURES RTAX_FEATURES
 };
 
-#define RTAX_MAX RTAX_HOPLIMIT
+#define RTAX_MAX RTAX_FEATURES
+
+#define RTAX_FEATURE_ECN	0x00000001
+#define RTAX_FEATURE_SACK	0x00000002
+#define RTAX_FEATURE_TIMESTAMP	0x00000004
 
 struct rta_session
 {
diff -urN linux-2.5.73-bk5/include/linux/sunrpc/cache.h linux-2.5.73-bk6/include/linux/sunrpc/cache.h
--- linux-2.5.73-bk5/include/linux/sunrpc/cache.h	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/sunrpc/cache.h	2003-06-28 04:53:20.000000000 -0700
@@ -80,8 +80,7 @@
 
 	int			(*cache_show)(struct seq_file *m,
 					      struct cache_detail *cd,
-					      struct cache_head *h,
-					      char *pbuf);
+					      struct cache_head *h);
 
 	/* fields below this comment are for internal use
 	 * and should not be touched by cache owners
diff -urN linux-2.5.73-bk5/include/linux/xfrm.h linux-2.5.73-bk6/include/linux/xfrm.h
--- linux-2.5.73-bk5/include/linux/xfrm.h	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/include/linux/xfrm.h	2003-06-28 04:53:20.000000000 -0700
@@ -203,6 +203,7 @@
 struct xfrm_user_acquire {
 	struct xfrm_id			id;
 	xfrm_address_t			saddr;
+	struct xfrm_selector		sel;
 	struct xfrm_userpolicy_info	policy;
 	__u32				aalgos;
 	__u32				ealgos;
diff -urN linux-2.5.73-bk5/include/net/ndisc.h linux-2.5.73-bk6/include/net/ndisc.h
--- linux-2.5.73-bk5/include/net/ndisc.h	2003-06-22 11:33:07.000000000 -0700
+++ linux-2.5.73-bk6/include/net/ndisc.h	2003-06-28 04:53:20.000000000 -0700
@@ -56,20 +56,6 @@
 	__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 -urN linux-2.5.73-bk5/include/net/sctp/constants.h linux-2.5.73-bk6/include/net/sctp/constants.h
--- linux-2.5.73-bk5/include/net/sctp/constants.h	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk6/include/net/sctp/constants.h	2003-06-28 04:53:20.000000000 -0700
@@ -267,7 +267,8 @@
  * nearest power of 2.
  */
 enum { SCTP_MIN_PMTU = 576 };
-enum { SCTP_MAX_DUP_TSNS = 128 };
+enum { SCTP_MAX_DUP_TSNS = 16 };
+enum { SCTP_MAX_GABS = 16 };
 
 typedef enum {
 	SCTP_COUNTER_INIT_ERROR,
diff -urN linux-2.5.73-bk5/include/net/sctp/sctp.h linux-2.5.73-bk6/include/net/sctp/sctp.h
--- linux-2.5.73-bk5/include/net/sctp/sctp.h	2003-06-22 11:32:38.000000000 -0700
+++ linux-2.5.73-bk6/include/net/sctp/sctp.h	2003-06-28 04:53:20.000000000 -0700
@@ -39,6 +39,7 @@
  *    Daisy Chang           <daisyc@us.ibm.com>
  *    Sridhar Samudrala     <sri@us.ibm.com>
  *    Ardelle Fan           <ardelle.fan@intel.com>
+ *    Ryan Layer            <rmlayer@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.
@@ -311,6 +312,11 @@
 #else
 static inline void sctp_sysctl_register(void) { return; }
 static inline void sctp_sysctl_unregister(void) { return; }
+static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
+		void __user *oldval, size_t __user *oldlenp,
+		void __user *newval, size_t newlen, void **context) {
+	return -ENOSYS;
+}
 #endif
 
 /* Size of Supported Address Parameter for 'x' address types. */
@@ -470,7 +476,7 @@
 		    WORD_ROUND(ntohs(err->length));\
      err = (sctp_errhdr_t *)((void *)err + \
 	    WORD_ROUND(ntohs(err->length))))
-     
+
 /* Round an int up to the next multiple of 4.  */
 #define WORD_ROUND(s) (((s)+3)&~3)
 
@@ -592,7 +598,7 @@
 
 /* Is the association in this state? */
 #define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state))
-int static inline __sctp_state(const struct sctp_association *asoc, 
+int static inline __sctp_state(const struct sctp_association *asoc,
 			       sctp_state_t state)
 {
 	return asoc->state == state;
diff -urN linux-2.5.73-bk5/include/net/sctp/sla1.h linux-2.5.73-bk6/include/net/sctp/sla1.h
--- linux-2.5.73-bk5/include/net/sctp/sla1.h	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk6/include/net/sctp/sla1.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,80 +0,0 @@
-/* SCTP reference Implementation 
- * Copyright (C) 1999 Cisco, Inc. 
- * Copyright (C) 1999 Motorola, Inc.
- *
- * This file originates from Randy Stewart's SCTP reference Implementation.
- * 
- * 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.  
- * 
- * 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: 
- *    Randy Stewart <rstewar1@email.mot.com>
- *    Ken Morneau   <kmorneau@cisco.com> 
- *    Qiaobing Xie  <qxie1@email.mot.com>
- */
-
-#ifndef __SLA1_h__
-#define __SLA1_h__
-
-struct SLA_1_Context {
-	unsigned int A;
-	unsigned int B;
-	unsigned int C;
-	unsigned int D;
-	unsigned int E;
-	unsigned int H0;
-	unsigned int H1;
-	unsigned int H2;
-	unsigned int H3;
-	unsigned int H4;
-	unsigned int words[80];
-	unsigned int TEMP;
-
-	/* block I am collecting to process */
-	char SLAblock[64];
-
-	/* collected so far */
-	int howManyInBlock;
-	unsigned int runningTotal;
-};
-
-
-#define F1(B,C,D) (((B & C) | ((~B) & D)))       /* 0  <= t <= 19 */
-#define F2(B,C,D) (B ^ C ^ D)                   /* 20 <= t <= 39 */
-#define F3(B,C,D) ((B & C) | (B & D) | (C & D)) /* 40 <= t <= 59 */
-#define F4(B,C,D) (B ^ C ^ D)                   /*600 <= t <= 79 */
-/* circular shift */
-
-#define CSHIFT(A,B) ((B << A) | (B >> (32-A)))
-
-#define K1 0x5a827999       /* 0  <= t <= 19 */
-#define K2 0x6ed9eba1       /* 20 <= t <= 39 */
-#define K3 0x8f1bbcdc       /* 40 <= t <= 59 */
-#define K4 0xca62c1d6       /* 60 <= t <= 79 */
-
-#define H0INIT 0x67452301
-#define H1INIT 0xefcdab89
-#define H2INIT 0x98badcfe
-#define H3INIT 0x10325476
-#define H4INIT 0xc3d2e1f0
-
-extern void SLA1_Init(struct SLA_1_Context *);
-extern void SLA1_Process(struct SLA_1_Context *, const unsigned char *, int);
-extern void SLA1_Final(struct SLA_1_Context *, unsigned char *);
-
-#endif
diff -urN linux-2.5.73-bk5/include/net/sctp/sm.h linux-2.5.73-bk6/include/net/sctp/sm.h
--- linux-2.5.73-bk5/include/net/sctp/sm.h	2003-06-22 11:32:43.000000000 -0700
+++ linux-2.5.73-bk6/include/net/sctp/sm.h	2003-06-28 04:53:20.000000000 -0700
@@ -84,7 +84,7 @@
 typedef void (sctp_timer_event_t) (unsigned long);
 typedef struct {
 	sctp_state_fn_t *fn;
-	char *name;
+	const char *name;
 } sctp_sm_table_entry_t;
 
 /* A naming convention of "sctp_sf_xxx" applies to all the state functions
@@ -176,9 +176,6 @@
 sctp_state_fn_t sctp_sf_do_9_2_reshut;
 sctp_state_fn_t sctp_sf_do_9_2_shutack;
 
-sctp_state_fn_t lucky;
-sctp_state_fn_t other_stupid;
-
 /* Prototypes for timeout event state functions.  Not in use. */
 sctp_state_fn_t sctp_do_4_2_reinit;
 sctp_state_fn_t sctp_do_4_3_reecho;
@@ -193,9 +190,9 @@
 
 /* Prototypes for utility support functions.  */
 __u8 sctp_get_chunk_type(struct sctp_chunk *chunk);
-sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
-					    sctp_state_t state,
-					    sctp_subtype_t event_subtype);
+const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t,
+					    sctp_state_t,
+					    sctp_subtype_t);
 int sctp_chunk_iif(const struct sctp_chunk *);
 struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *,
 					     struct sctp_chunk *,
@@ -284,20 +281,13 @@
                       int gfp);
 
 /* 2nd level prototypes */
-int
-sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
-		     sctp_state_t state,
-		     struct sctp_endpoint *ep,
-		     struct sctp_association *asoc,
-		     void *event_arg,
-		     sctp_disposition_t status,
-		     sctp_cmd_seq_t *retval,
-		     int gfp);
+int sctp_cmd_interpreter(sctp_event_t, sctp_subtype_t, sctp_state_t,
+			 struct sctp_endpoint *, struct sctp_association *,
+			 void *event_arg, sctp_disposition_t,
+			 sctp_cmd_seq_t *retval, int gfp);
 
 
 int sctp_gen_sack(struct sctp_association *, int force, sctp_cmd_seq_t *);
-void sctp_do_TSNdup(struct sctp_association *, struct sctp_chunk *, long gap);
-
 void sctp_generate_t3_rtx_event(unsigned long peer);
 void sctp_generate_heartbeat_event(unsigned long peer);
 
@@ -311,7 +301,7 @@
 				      const struct sctp_chunk *);
 void sctp_ootb_pkt_free(struct sctp_packet *);
 
-sctp_cookie_param_t *
+struct sctp_cookie_param *
 sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
 		 const struct sctp_chunk *, int *cookie_len,
 		 const __u8 *, int addrs_len);
@@ -332,18 +322,18 @@
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
 /* 4th level prototypes */
-void sctp_param2sockaddr(union sctp_addr *addr, sctp_addr_param_t *,
+void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *,
 			 __u16 port, int iif);
 int sctp_addr2sockaddr(const union sctp_params, union sctp_addr *);
-int sockaddr2sctp_addr(const union sctp_addr *, sctp_addr_param_t *);
+int sockaddr2sctp_addr(const union sctp_addr *, union sctp_addr_param *);
 
 /* Extern declarations for major data structures.  */
-sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
-extern sctp_sm_table_entry_t
+const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
+extern const sctp_sm_table_entry_t
 primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
-extern sctp_sm_table_entry_t
+extern const sctp_sm_table_entry_t
 other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
-extern sctp_sm_table_entry_t
+extern const sctp_sm_table_entry_t
 timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
 extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];
 
diff -urN linux-2.5.73-bk5/include/net/sctp/structs.h linux-2.5.73-bk6/include/net/sctp/structs.h
--- linux-2.5.73-bk5/include/net/sctp/structs.h	2003-06-22 11:33:35.000000000 -0700
+++ linux-2.5.73-bk6/include/net/sctp/structs.h	2003-06-28 04:53:20.000000000 -0700
@@ -14,7 +14,7 @@
  *
  * 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.
  *
@@ -31,18 +31,20 @@
  *    http://www.sf.net/projects/lksctp
  *
  * Written or modified by:
- *    Randall Stewart       <randall@sctp.chicago.il.us>
- *    Ken Morneau           <kmorneau@cisco.com>
- *    Qiaobing Xie          <qxie1@email.mot.com>
+ *    Randall Stewart	    <randall@sctp.chicago.il.us>
+ *    Ken Morneau	    <kmorneau@cisco.com>
+ *    Qiaobing Xie	    <qxie1@email.mot.com>
  *    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>
+ *    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>
  *    Daisy Chang	    <daisyc@us.ibm.com>
- *    Dajiang Zhang         <dajiang.zhang@nokia.com>
- *    Ardelle Fan           <ardelle.fan@intel.com>
+ *    Dajiang Zhang	    <dajiang.zhang@nokia.com>
+ *    Ardelle Fan	    <ardelle.fan@intel.com>
+ *    Ryan Layer	    <rmlayer@us.ibm.com>
+ *    Anup Pemmaiah	    <pemmaiah@cc.usu.edu>
  *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -54,12 +56,12 @@
 #include <linux/time.h>		/* We get struct timespec.    */
 #include <linux/socket.h>	/* linux/in.h needs this!!    */
 #include <linux/in.h>		/* We get struct sockaddr_in. */
-#include <linux/in6.h>          /* We get struct in6_addr     */
+#include <linux/in6.h>		/* We get struct in6_addr     */
 #include <asm/param.h>		/* We get MAXHOSTNAMELEN.     */
 #include <asm/atomic.h>		/* This gets us atomic counters.  */
 #include <linux/skbuff.h>	/* We need sk_buff_head. */
-#include <linux/workqueue.h>	/* We need tq_struct.    */
-#include <linux/sctp.h>         /* We need sctp* header structs.  */
+#include <linux/workqueue.h>	/* We need tq_struct.	 */
+#include <linux/sctp.h>		/* We need sctp* header structs.  */
 
 /* A convenience structure for handling sockaddr structures.
  * We should wean ourselves off this.
@@ -93,11 +95,11 @@
 /* Structures useful for managing bind/connect. */
 
 struct sctp_bind_bucket {
-	unsigned short 	port;
+	unsigned short	port;
 	unsigned short	fastreuse;
 	struct sctp_bind_bucket *next;
 	struct sctp_bind_bucket **pprev;
-	struct hlist_head       sk_list;
+	struct hlist_head	owner;
 };
 
 struct sctp_bind_hashbucket {
@@ -118,11 +120,11 @@
 	 *
 	 * The following protocol parameters are RECOMMENDED:
 	 *
-	 * RTO.Initial              - 3  seconds
-	 * RTO.Min                  - 1  second
-	 * RTO.Max                 -  60 seconds
-	 * RTO.Alpha                - 1/8  (3 when converted to right shifts.)
-	 * RTO.Beta                 - 1/4  (2 when converted to right shifts.)
+	 * RTO.Initial		    - 3	 seconds
+	 * RTO.Min		    - 1	 second
+	 * RTO.Max		   -  60 seconds
+	 * RTO.Alpha		    - 1/8  (3 when converted to right shifts.)
+	 * RTO.Beta		    - 1/4  (2 when converted to right shifts.)
 	 */
 	__u32 rto_initial;
 	__u32 rto_min;
@@ -137,24 +139,24 @@
 	/* Max.Burst		    - 4 */
 	int max_burst;
 
-	/* Valid.Cookie.Life        - 60  seconds  */
+	/* Valid.Cookie.Life	    - 60  seconds  */
 	int valid_cookie_life;
 
 	/* Whether Cookie Preservative is enabled(1) or not(0) */
 	int cookie_preserve_enable;
 
 	/* Association.Max.Retrans  - 10 attempts
-	 * Path.Max.Retrans         - 5  attempts (per destination address)
-	 * Max.Init.Retransmits     - 8  attempts
+	 * Path.Max.Retrans	    - 5	 attempts (per destination address)
+	 * Max.Init.Retransmits	    - 8	 attempts
 	 */
 	int max_retrans_association;
 	int max_retrans_path;
 	int max_retrans_init;
 
-	/* HB.interval              - 30 seconds  */
+	/* HB.interval		    - 30 seconds  */
 	int hb_interval;
 
-	/* The following variables are implementation specific.  */
+	/* The following variables are implementation specific.	 */
 
 	/* Default initialization values to be applied to new associations. */
 	__u16 max_instreams;
@@ -173,7 +175,7 @@
 	int assoc_hashsize;
 	struct sctp_hashbucket *assoc_hashbucket;
 
-	/* This is the sctp port control hash.  */
+	/* This is the sctp port control hash.	*/
 	int port_hashsize;
 	int port_rover;
 	spinlock_t port_alloc_lock;  /* Protects port_rover. */
@@ -183,7 +185,7 @@
 	 * We actively maintain this complete list of interfaces on
 	 * the system by catching routing events.
 	 *
-	 * It is a list of struct sockaddr_storage_list.
+	 * It is a list of sctp_sockaddr_entry.
 	 */
 	struct list_head local_addr_list;
 	spinlock_t local_addr_lock;
@@ -223,12 +225,12 @@
 	int		(*sctp_xmit)	(struct sk_buff *skb,
 					 struct sctp_transport *,
 					 int ipfragok);
-	int 		(*setsockopt)	(struct sock *sk,
+	int		(*setsockopt)	(struct sock *sk,
 					 int level,
 					 int optname,
 					 char *optval,
 					 int optlen);
-	int 		(*getsockopt)	(struct sock *sk,
+	int		(*getsockopt)	(struct sock *sk,
 					 int level,
 					 int optname,
 					 char *optval,
@@ -236,37 +238,37 @@
 	struct dst_entry *(*get_dst)	(struct sctp_association *asoc,
 					 union sctp_addr *daddr,
 					 union sctp_addr *saddr);
-	void 		(*get_saddr)	(struct sctp_association *asoc,
+	void		(*get_saddr)	(struct sctp_association *asoc,
 					 struct dst_entry *dst,
 					 union sctp_addr *daddr,
-				 	 union sctp_addr *saddr);
-	void            (*copy_addrlist) (struct list_head *,
+					 union sctp_addr *saddr);
+	void		(*copy_addrlist) (struct list_head *,
 					  struct net_device *);
-	void            (*dst_saddr)    (union sctp_addr *saddr,
+	void		(*dst_saddr)	(union sctp_addr *saddr,
 					 struct dst_entry *dst,
 					 unsigned short port);
-	int             (*cmp_addr)     (const union sctp_addr *addr1,
+	int		(*cmp_addr)	(const union sctp_addr *addr1,
 					 const union sctp_addr *addr2);
-	void            (*addr_copy)    (union sctp_addr *dst,
+	void		(*addr_copy)	(union sctp_addr *dst,
 					 union sctp_addr *src);
-	void            (*from_skb)     (union sctp_addr *,
+	void		(*from_skb)	(union sctp_addr *,
 					 struct sk_buff *skb,
 					 int saddr);
-	void            (*from_sk)      (union sctp_addr *,
+	void		(*from_sk)	(union sctp_addr *,
 					 struct sock *sk);
-	void            (*to_sk_saddr)  (union sctp_addr *,
+	void		(*to_sk_saddr)	(union sctp_addr *,
 					 struct sock *sk);
-	void            (*to_sk_daddr)  (union sctp_addr *,
+	void		(*to_sk_daddr)	(union sctp_addr *,
 					 struct sock *sk);
-	int             (*addr_valid)   (union sctp_addr *);
-	sctp_scope_t    (*scope) (union sctp_addr *);
-	void            (*inaddr_any)   (union sctp_addr *, unsigned short);
-	int             (*is_any)       (const union sctp_addr *);
-	int             (*available)    (const union sctp_addr *);
-	int             (*skb_iif)      (const struct sk_buff *sk);
-	int             (*is_ce)        (const struct sk_buff *sk);
+	int		(*addr_valid)	(union sctp_addr *);
+	sctp_scope_t	(*scope) (union sctp_addr *);
+	void		(*inaddr_any)	(union sctp_addr *, unsigned short);
+	int		(*is_any)	(const union sctp_addr *);
+	int		(*available)	(const union sctp_addr *);
+	int		(*skb_iif)	(const struct sk_buff *sk);
+	int		(*is_ce)	(const struct sk_buff *sk);
 	void		(*seq_dump_addr)(struct seq_file *seq,
-		       			 union sctp_addr *addr);
+					 union sctp_addr *addr);
 	__u16		net_header_len;
 	int		sockaddr_len;
 	sa_family_t	sa_family;
@@ -325,6 +327,7 @@
 	struct sctp_rtoinfo rtoinfo;
 	struct sctp_paddrparams paddrparam;
 	struct sctp_event_subscribe subscribe;
+	struct sctp_assocparams assocparams;
 	int user_frag;
 	__u32 autoclose;
 	__u8 nodelay;
@@ -347,23 +350,23 @@
  *
  */
 
-typedef struct sctp_cookie {
+struct sctp_cookie {
+
+	/* My	       : Tag expected in every inbound packet and sent
+	 * Verification: in the INIT or INIT ACK chunk.
+	 * Tag	       :
+	 */
+	__u32 my_vtag;
+
+	/* Peer's      : Tag expected in every outbound packet except
+	 * Verification: in the INIT chunk.
+	 * Tag	       :
+	 */
+	__u32 peer_vtag;
 
-        /* My          : Tag expected in every inbound packet and sent
-         * Verification: in the INIT or INIT ACK chunk.
-         * Tag         :
-         */
-        __u32 my_vtag;
-
-        /* Peer's      : Tag expected in every outbound packet except
-         * Verification: in the INIT chunk.
-         * Tag         :
-         */
-        __u32 peer_vtag;
-
-        /* The rest of these are not from the spec, but really need to
-         * be in the cookie.
-         */
+	/* The rest of these are not from the spec, but really need to
+	 * be in the cookie.
+	 */
 
 	/* My Tie Tag  : Assist in discovering a restarting association. */
 	__u32 my_ttag;
@@ -371,8 +374,8 @@
 	/* Peer's Tie Tag: Assist in discovering a restarting association. */
 	__u32 peer_ttag;
 
-        /* When does this cookie expire? */
-        struct timeval expiration;
+	/* When does this cookie expire? */
+	struct timeval expiration;
 
 	/* Number of inbound/outbound streams which are set
 	 * and negotiated during the INIT process.
@@ -380,7 +383,7 @@
 	__u16 sinit_num_ostreams;
 	__u16 sinit_max_instreams;
 
-        /* This is the first sequence number I used.  */
+	/* This is the first sequence number I used.  */
 	__u32 initial_tsn;
 
 	/* This holds the originating address of the INIT packet.  */
@@ -393,38 +396,38 @@
 	 * the association TCB is re-constructed from the cookie.
 	 */
 	__u32 raw_addr_list_len;
-	sctp_init_chunk_t peer_init[0];
-} sctp_cookie_t;
+	struct sctp_init_chunk peer_init[0];
+};
 
 
 /* The format of our cookie that we send to our peer. */
-typedef struct sctp_signed_cookie {
+struct sctp_signed_cookie {
 	__u8 signature[SCTP_SECRET_SIZE];
-	sctp_cookie_t c;
-} sctp_signed_cookie_t;
+	struct sctp_cookie c;
+};
 
 /* This is another convenience type to allocate memory for address
  * params for the maximum size and pass such structures around
  * internally.
  */
-typedef union {
-	sctp_ipv4addr_param_t v4;
-	sctp_ipv6addr_param_t v6;
-} sctp_addr_param_t;
+union sctp_addr_param {
+	struct sctp_ipv4addr_param v4;
+	struct sctp_ipv6addr_param v6;
+};
 
 /* A convenience type to allow walking through the various
  * parameters and avoid casting all over the place.
  */
 union sctp_params {
 	void *v;
-	sctp_paramhdr_t *p;
-	sctp_cookie_preserve_param_t *life;
-	sctp_hostname_param_t *dns;
-	sctp_cookie_param_t *cookie;
-	sctp_supported_addrs_param_t *sat;
-	sctp_ipv4addr_param_t *v4;
-	sctp_ipv6addr_param_t *v6;
-	sctp_addr_param_t *addr;
+	struct sctp_paramhdr *p;
+	struct sctp_cookie_preserve_param *life;
+	struct sctp_hostname_param *dns;
+	struct sctp_cookie_param *cookie;
+	struct sctp_supported_addrs_param *sat;
+	struct sctp_ipv4addr_param *v4;
+	struct sctp_ipv6addr_param *v6;
+	union sctp_addr_param *addr;
 };
 
 /* RFC 2960.  Section 3.3.5 Heartbeat.
@@ -435,7 +438,7 @@
  *    HEARTBEAT is sent (see Section 8.3).
  */
 typedef struct sctp_sender_hb_info {
-	sctp_paramhdr_t param_hdr;
+	struct sctp_paramhdr param_hdr;
 	union sctp_addr daddr;
 	unsigned long sent_at;
 } sctp_sender_hb_info_t __attribute__((packed));
@@ -476,7 +479,7 @@
 	return stream->ssn[id];
 }
 
-/* Return the next SSN number for this stream.  */
+/* Return the next SSN number for this stream.	*/
 static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
 {
 	return stream->ssn[id]++;
@@ -555,23 +558,22 @@
 	union sctp_params param_hdr;
 	union {
 		__u8 *v;
-		sctp_datahdr_t *data_hdr;
-		sctp_inithdr_t *init_hdr;
-		sctp_sackhdr_t *sack_hdr;
-		sctp_heartbeathdr_t *hb_hdr;
-		sctp_sender_hb_info_t *hbs_hdr;
-		sctp_shutdownhdr_t *shutdown_hdr;
-		sctp_signed_cookie_t *cookie_hdr;
-		sctp_ecnehdr_t *ecne_hdr;
-		sctp_cwrhdr_t *ecn_cwr_hdr;
-		sctp_errhdr_t *err_hdr;
+		struct sctp_datahdr *data_hdr;
+		struct sctp_inithdr *init_hdr;
+		struct sctp_sackhdr *sack_hdr;
+		struct sctp_heartbeathdr *hb_hdr;
+		struct sctp_sender_hb_info *hbs_hdr;
+		struct sctp_shutdownhdr *shutdown_hdr;
+		struct sctp_signed_cookie *cookie_hdr;
+		struct sctp_ecnehdr *ecne_hdr;
+		struct sctp_cwrhdr *ecn_cwr_hdr;
+		struct sctp_errhdr *err_hdr;
 	} subh;
 
 	__u8 *chunk_end;
 
-	sctp_chunkhdr_t *chunk_hdr;
-
-	sctp_sctphdr_t  *sctp_hdr;
+	struct sctp_chunkhdr *chunk_hdr;
+	struct sctphdr *sctp_hdr;
 
 	/* This needs to be recoverable for SCTP_SEND_FAILED events. */
 	struct sctp_sndrcvinfo sinfo;
@@ -595,7 +597,7 @@
 
 	/* For an inbound chunk, this tells us where it came from.
 	 * For an outbound chunk, it tells us where we'd like it to
-	 * go.  It is NULL if we have no preference.
+	 * go.	It is NULL if we have no preference.
 	 */
 	struct sctp_transport *transport;
 
@@ -632,7 +634,7 @@
  * sin_port -- ordinary port number
  * sin_addr -- cast to either (struct in_addr) or (struct in6_addr)
  */
-struct sockaddr_storage_list {
+struct sctp_sockaddr_entry {
 	struct list_head list;
 	union sctp_addr a;
 };
@@ -685,22 +687,22 @@
 typedef int (sctp_outq_ehandler_t)(struct sctp_outq *);
 typedef struct sctp_packet *(sctp_outq_ohandler_init_t)
 	(struct sctp_packet *,
-         struct sctp_transport *,
-         __u16 sport,
-         __u16 dport);
+	 struct sctp_transport *,
+	 __u16 sport,
+	 __u16 dport);
 typedef struct sctp_packet *(sctp_outq_ohandler_config_t)
-        (struct sctp_packet *,
+	(struct sctp_packet *,
 	 __u32 vtag,
 	 int ecn_capable,
 	 sctp_packet_phandler_t *get_prepend_chunk);
 typedef sctp_xmit_t (sctp_outq_ohandler_t)(struct sctp_packet *,
-                                               struct sctp_chunk *);
+					       struct sctp_chunk *);
 typedef int (sctp_outq_ohandler_force_t)(struct sctp_packet *);
 
 sctp_outq_ohandler_init_t    sctp_packet_init;
 sctp_outq_ohandler_config_t  sctp_packet_config;
-sctp_outq_ohandler_t         sctp_packet_append_chunk;
-sctp_outq_ohandler_t         sctp_packet_transmit_chunk;
+sctp_outq_ohandler_t	     sctp_packet_append_chunk;
+sctp_outq_ohandler_t	     sctp_packet_transmit_chunk;
 sctp_outq_ohandler_force_t   sctp_packet_transmit;
 void sctp_packet_free(struct sctp_packet *);
 
@@ -710,19 +712,19 @@
  *
  * RFC2960 Section 1.4 Key Terms
  *
- *   o  Transport address:  A Transport Address is traditionally defined
- *      by Network Layer address, Transport Layer protocol and Transport
- *      Layer port number.  In the case of SCTP running over IP, a
- *      transport address is defined by the combination of an IP address
- *      and an SCTP port number (where SCTP is the Transport protocol).
+ *   o	Transport address:  A Transport Address is traditionally defined
+ *	by Network Layer address, Transport Layer protocol and Transport
+ *	Layer port number.  In the case of SCTP running over IP, a
+ *	transport address is defined by the combination of an IP address
+ *	and an SCTP port number (where SCTP is the Transport protocol).
  *
  * RFC2960 Section 7.1 SCTP Differences from TCP Congestion control
  *
- *   o  The sender keeps a separate congestion control parameter set for
- *      each of the destination addresses it can send to (not each
- *      source-destination pair but for each destination).  The parameters
- *      should decay if the address is not used for a long enough time
- *      period.
+ *   o	The sender keeps a separate congestion control parameter set for
+ *	each of the destination addresses it can send to (not each
+ *	source-destination pair but for each destination).  The parameters
+ *	should decay if the address is not used for a long enough time
+ *	period.
  *
  */
 struct sctp_transport {
@@ -731,12 +733,12 @@
 
 	/* Reference counting. */
 	atomic_t refcnt;
-	int      dead;
+	int	 dead;
 
 	/* This is the peer's IP address and port. */
 	union sctp_addr ipaddr;
 
-	/* These are the functions we call to handle LLP stuff.  */
+	/* These are the functions we call to handle LLP stuff.	 */
 	struct sctp_af *af_specific;
 
 	/* Which association do we belong to?  */
@@ -750,33 +752,33 @@
 	 * address list derived from the INIT or INIT ACK chunk, a
 	 * number of data elements needs to be maintained including:
 	 */
-	__u32 rtt;		/* This is the most recent RTT.  */
+	__u32 rtt;		/* This is the most recent RTT.	 */
 
-	/* RTO         : The current retransmission timeout value.  */
+	/* RTO	       : The current retransmission timeout value.  */
 	__u32 rto;
 
 	/* RTTVAR      : The current RTT variation.  */
 	__u32 rttvar;
 
-	/* SRTT        : The current smoothed round trip time.  */
+	/* SRTT	       : The current smoothed round trip time.	*/
 	__u32 srtt;
 
 	/* RTO-Pending : A flag used to track if one of the DATA
-	 *              chunks sent to this address is currently being
-	 *              used to compute a RTT. If this flag is 0,
-	 *              the next DATA chunk sent to this destination
-	 *              should be used to compute a RTT and this flag
-	 *              should be set. Every time the RTT
-	 *              calculation completes (i.e. the DATA chunk
-	 *              is SACK'd) clear this flag.
-         */
+	 *		chunks sent to this address is currently being
+	 *		used to compute a RTT. If this flag is 0,
+	 *		the next DATA chunk sent to this destination
+	 *		should be used to compute a RTT and this flag
+	 *		should be set. Every time the RTT
+	 *		calculation completes (i.e. the DATA chunk
+	 *		is SACK'd) clear this flag.
+	 */
 	int rto_pending;
 
 	/*
 	 * These are the congestion stats.
 	 */
-	/* cwnd        : The current congestion window.  */
-	__u32 cwnd;               /* This is the actual cwnd.  */
+	/* cwnd	       : The current congestion window.	 */
+	__u32 cwnd;		  /* This is the actual cwnd.  */
 
 	/* ssthresh    : The current slow start threshold value.  */
 	__u32 ssthresh;
@@ -789,7 +791,7 @@
 	/* Data that has been sent, but not acknowledged. */
 	__u32 flight_size;
 
-	/* PMTU       : The current known path MTU.  */
+	/* PMTU	      : The current known path MTU.  */
 	__u32 pmtu;
 
 	/* Destination */
@@ -819,23 +821,23 @@
 	unsigned long last_time_ecne_reduced;
 
 	/* active      : The current active state of this destination,
-	 *             :  i.e. DOWN, UP, etc.
+	 *	       :  i.e. DOWN, UP, etc.
 	 */
 	int active;
 
 	/* hb_allowed  : The current heartbeat state of this destination,
-	 *             :  i.e. ALLOW-HB, NO-HEARTBEAT, etc.
+	 *	       :  i.e. ALLOW-HB, NO-HEARTBEAT, etc.
 	 */
 	int hb_allowed;
 
 	/* These are the error stats for this destination.  */
 
-	/* Error count : The current error count for this destination.  */
+	/* Error count : The current error count for this destination.	*/
 	unsigned short error_count;
 
 	/* Error       : Current error threshold for this destination
 	 * Threshold   : i.e. what value marks the destination down if
-	 *             : errorCount reaches this value.
+	 *	       : errorCount reaches this value.
 	 */
 	unsigned short error_threshold;
 
@@ -845,7 +847,7 @@
 	 */
 	int max_retrans;
 
-	/* Per         : A timer used by each destination.
+	/* Per	       : A timer used by each destination.
 	 * Destination :
 	 * Timer       :
 	 *
@@ -874,10 +876,10 @@
 	/* State information saved for SFR_CACC algorithm. The key
 	 * idea in SFR_CACC is to maintain state at the sender on a
 	 * per-destination basis when a changeover happens.
-	 * 	char changeover_active;
-	 * 	char cycling_changeover;
-	 * 	__u32 next_tsn_at_change;
-	 * 	char cacc_saw_newack;
+	 *	char changeover_active;
+	 *	char cycling_changeover;
+	 *	__u32 next_tsn_at_change;
+	 *	char cacc_saw_newack;
 	 */
 	struct {
 		/* An unsigned integer, which stores the next TSN to be
@@ -938,7 +940,7 @@
 	 */
 	struct work_struct immediate;
 
-	int malloced;        /* Is this structure kfree()able?  */
+	int malloced;	     /* Is this structure kfree()able?	*/
 };
 
 struct sctp_inq *sctp_inq_new(void);
@@ -955,7 +957,7 @@
  * This structure covers sections 6.3, 6.4, 6.7, 6.8, 6.10, 7., 8.1,
  * and 8.2 of the v13 draft.
  *
- * It handles retransmissions.  The connection to the timeout portion
+ * It handles retransmissions.	The connection to the timeout portion
  * of the state machine is through sctp_..._timeout() and timeout_handler.
  *
  * If you feed it SACKs, it will eat them.
@@ -1001,7 +1003,7 @@
 	sctp_outq_ohandler_t	*build_output;
 	sctp_outq_ohandler_force_t	*force_output;
 
-	/* How many unackd bytes do we have in-flight?  */
+	/* How many unackd bytes do we have in-flight?	*/
 	__u32 outstanding_bytes;
 
 	/* Corked? */
@@ -1020,7 +1022,7 @@
 void sctp_outq_free(struct sctp_outq*);
 int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk);
 int sctp_outq_flush(struct sctp_outq *, int);
-int sctp_outq_sack(struct sctp_outq *, sctp_sackhdr_t *);
+int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *);
 int sctp_outq_is_empty(const struct sctp_outq *);
 int sctp_outq_set_output_handlers(struct sctp_outq *,
 				  sctp_outq_ohandler_init_t init,
@@ -1045,8 +1047,8 @@
 
 	/* RFC 2960 12.1 Parameters necessary for the SCTP instance
 	 *
-	 * SCTP Port:   The local SCTP port number the endpoint is
-	 * 		bound to.
+	 * SCTP Port:	The local SCTP port number the endpoint is
+	 *		bound to.
 	 */
 	__u16 port;
 
@@ -1058,7 +1060,7 @@
 	 */
 	struct list_head address_list;
 
-	int malloced;        /* Are we kfree()able?  */
+	int malloced;	     /* Are we kfree()able?  */
 };
 
 struct sctp_bind_addr *sctp_bind_addr_new(int gfp_mask);
@@ -1095,13 +1097,13 @@
  * local endpoint.
  * This common structure is useful for several purposes:
  *   1) Common interface for lookup routines.
- *      a) Subfunctions work for either endpoint or association
- *      b) Single interface to lookup allows hiding the lookup lock rather
- *         than acquiring it externally.
+ *	a) Subfunctions work for either endpoint or association
+ *	b) Single interface to lookup allows hiding the lookup lock rather
+ *	   than acquiring it externally.
  *   2) Common interface for the inbound chunk handling/state machine.
  *   3) Common object handling routines for reference counting, etc.
  *   4) Disentangle association lookup from endpoint lookup, where we
- *      do not have to find our endpoint to find our association.
+ *	do not have to find our endpoint to find our association.
  *
  */
 
@@ -1120,14 +1122,14 @@
 	 *   malloced - Do we need to kfree this object?
 	 */
 	atomic_t    refcnt;
-	char        dead;
-	char        malloced;
+	char	    dead;
+	char	    malloced;
 
 	/* What socket does this endpoint belong to?  */
 	struct sock *sk;
 
 	/* This is where we receive inbound chunks.  */
-	struct sctp_inq   inqueue;
+	struct sctp_inq	  inqueue;
 
 	/* This substructure includes the defining parameters of the
 	 * endpoint:
@@ -1165,22 +1167,22 @@
 	struct sctp_ep_common base;
 
 	/* Associations: A list of current associations and mappings
-	 *            to the data consumers for each association. This
-	 *            may be in the form of a hash table or other
-	 *            implementation dependent structure. The data
-	 *            consumers may be process identification
-	 *            information such as file descriptors, named pipe
-	 *            pointer, or table pointers dependent on how SCTP
-	 *            is implemented.
+	 *	      to the data consumers for each association. This
+	 *	      may be in the form of a hash table or other
+	 *	      implementation dependent structure. The data
+	 *	      consumers may be process identification
+	 *	      information such as file descriptors, named pipe
+	 *	      pointer, or table pointers dependent on how SCTP
+	 *	      is implemented.
 	 */
 	/* This is really a list of struct sctp_association entries. */
 	struct list_head asocs;
 
 	/* Secret Key: A secret key used by this endpoint to compute
-	 *            the MAC.  This SHOULD be a cryptographic quality
-	 *            random number with a sufficient length.
+	 *	      the MAC.	This SHOULD be a cryptographic quality
+	 *	      random number with a sufficient length.
 	 *	      Discussion in [RFC1750] can be helpful in
-	 * 	      selection of the key.
+	 *	      selection of the key.
 	 */
 	__u8 secret_key[SCTP_HOW_MANY_SECRETS][SCTP_SECRET_SIZE];
 	int current_key;
@@ -1190,7 +1192,7 @@
 	/* Default timeouts.  */
 	int timeouts[SCTP_NUM_TIMEOUT_TYPES];
 
-	/* Various thresholds.  */
+	/* Various thresholds.	*/
 
 	/* Name for debugging output... */
 	char *debug_name;
@@ -1267,11 +1269,11 @@
 	 */
 	__u32 eyecatcher;
 
-	/* This is our parent endpoint.  */
+	/* This is our parent endpoint.	 */
 	struct sctp_endpoint *ep;
 
 	/* These are those association elements needed in the cookie.  */
-	sctp_cookie_t c;
+	struct sctp_cookie c;
 
 	/* This is all information about our peer.  */
 	struct {
@@ -1283,11 +1285,11 @@
 
 		/* transport_addr_list
 		 *
-		 * Peer        : A list of SCTP transport addresses that the
+		 * Peer	       : A list of SCTP transport addresses that the
 		 * Transport   : peer is bound to. This information is derived
 		 * Address     : from the INIT or INIT ACK and is used to
-		 * List        : associate an inbound packet with a given
-		 *             : association. Normally this information is
+		 * List	       : associate an inbound packet with a given
+		 *	       : association. Normally this information is
 		 *	       : hashed or keyed for quick lookup and access
 		 *	       : of the TCB.
 		 *
@@ -1303,8 +1305,8 @@
 		/* primary_path
 		 *
 		 * Primary     : This is the current primary destination
-		 * Path        : transport address of the peer endpoint.  It
-		 *             : may also specify a source transport address
+		 * Path	       : transport address of the peer endpoint.  It
+		 *	       : may also specify a source transport address
 		 *	       : on this endpoint.
 		 *
 		 * All of these paths live on transport_addr_list.
@@ -1343,25 +1345,25 @@
 		/* Pointer to last transport I have sent on.  */
 		struct sctp_transport *last_sent_to;
 
-		/* This is the last transport I have received DATA on.  */
+		/* This is the last transport I have received DATA on.	*/
 		struct sctp_transport *last_data_from;
 
 		/*
 		 * Mapping  An array of bits or bytes indicating which out of
 		 * Array    order TSN's have been received (relative to the
-		 *          Last Rcvd TSN). If no gaps exist, i.e. no out of
-		 *          order packets have been received, this array
-		 *          will be set to all zero. This structure may be
-		 *          in the form of a circular buffer or bit array.
+		 *	    Last Rcvd TSN). If no gaps exist, i.e. no out of
+		 *	    order packets have been received, this array
+		 *	    will be set to all zero. This structure may be
+		 *	    in the form of a circular buffer or bit array.
 		 *
 		 * Last Rcvd   : This is the last TSN received in
 		 * TSN	       : sequence. This value is set initially by
-		 *             : taking the peer's Initial TSN, received in
-		 *             : the INIT or INIT ACK chunk, and subtracting
-		 *             : one from it.
+		 *	       : taking the peer's Initial TSN, received in
+		 *	       : the INIT or INIT ACK chunk, and subtracting
+		 *	       : one from it.
 		 *
 		 * Throughout most of the specification this is called the
-		 * "Cumulative TSN ACK Point".  In this case, we
+		 * "Cumulative TSN ACK Point".	In this case, we
 		 * ignore the advice in 12.2 in favour of the term
 		 * used in the bulk of the text.  This value is hidden
 		 * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn().
@@ -1370,13 +1372,13 @@
 		__u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)];
 
 		/* Do we need to sack the peer? */
-		__u8    sack_needed;
+		__u8	sack_needed;
 		/* These are capabilities which our peer advertised.  */
-		__u8	ecn_capable;     /* Can peer do ECN? */
-		__u8	ipv4_address;    /* Peer understands IPv4 addresses? */
-		__u8	ipv6_address;    /* Peer understands IPv6 addresses? */
+		__u8	ecn_capable;	 /* Can peer do ECN? */
+		__u8	ipv4_address;	 /* Peer understands IPv4 addresses? */
+		__u8	ipv6_address;	 /* Peer understands IPv6 addresses? */
 		__u8	hostname_address;/* Peer understands DNS addresses? */
-		sctp_inithdr_t i;
+		struct sctp_inithdr i;
 		int cookie_len;
 		void *cookie;
 
@@ -1387,22 +1389,19 @@
 
 	/* State       : A state variable indicating what state the
 	 *	       : association is in, i.e. COOKIE-WAIT,
-	 *             : COOKIE-ECHOED, ESTABLISHED, SHUTDOWN-PENDING,
-	 *             : SHUTDOWN-SENT, SHUTDOWN-RECEIVED, SHUTDOWN-ACK-SENT.
+	 *	       : COOKIE-ECHOED, ESTABLISHED, SHUTDOWN-PENDING,
+	 *	       : SHUTDOWN-SENT, SHUTDOWN-RECEIVED, SHUTDOWN-ACK-SENT.
 	 *
-	 *              Note: No "CLOSED" state is illustrated since if a
-	 *              association is "CLOSED" its TCB SHOULD be removed.
+	 *		Note: No "CLOSED" state is illustrated since if a
+	 *		association is "CLOSED" its TCB SHOULD be removed.
 	 *
-	 * 		In this implementation we DO have a CLOSED
+	 *		In this implementation we DO have a CLOSED
 	 *		state which is used during initiation and shutdown.
 	 *
-	 * 		State takes values from SCTP_STATE_*.
+	 *		State takes values from SCTP_STATE_*.
 	 */
 	sctp_state_t state;
 
-	/* When did we enter this state?  */
-	int state_timestamp;
-
 	/* The cookie life I award for any cookie.  */
 	struct timeval cookie_life;
 
@@ -1411,12 +1410,6 @@
 	 */
 	int overall_error_count;
 
-	/* Overall     : The threshold for this association that if
-	 * Error       : the Overall Error Count reaches will cause
-	 * Threshold   : this association to be torn down.
-	 */
-	int overall_error_threshold;
-
 	/* These are the association's initial, max, and min RTO values.
 	 * These values will be initialized by system defaults, but can
 	 * be modified via the SCTP_RTOINFO socket option.
@@ -1450,19 +1443,19 @@
 	struct sctp_transport *shutdown_last_sent_to;
 
 	/* Next TSN    : The next TSN number to be assigned to a new
-	 *             : DATA chunk.  This is sent in the INIT or INIT
-	 *             : ACK chunk to the peer and incremented each
-	 *             : time a DATA chunk is assigned a TSN
-	 *             : (normally just prior to transmit or during
+	 *	       : DATA chunk.  This is sent in the INIT or INIT
+	 *	       : ACK chunk to the peer and incremented each
+	 *	       : time a DATA chunk is assigned a TSN
+	 *	       : (normally just prior to transmit or during
 	 *	       : fragmentation).
 	 */
 	__u32 next_tsn;
 
 	/*
 	 * Last Rcvd   : This is the last TSN received in sequence.  This value
-	 * TSN         : is set initially by taking the peer's Initial TSN,
-	 *             : received in the INIT or INIT ACK chunk, and
-	 *             : subtracting one from it.
+	 * TSN	       : is set initially by taking the peer's Initial TSN,
+	 *	       : received in the INIT or INIT ACK chunk, and
+	 *	       : subtracting one from it.
 	 *
 	 * Most of RFC 2960 refers to this as the Cumulative TSN Ack Point.
 	 */
@@ -1502,7 +1495,7 @@
 	wait_queue_head_t	wait;
 
 	/* Association : The smallest PMTU discovered for all of the
-	 * PMTU        : peer's transport addresses.
+	 * PMTU	       : peer's transport addresses.
 	 */
 	__u32 pmtu;
 
@@ -1510,14 +1503,14 @@
 	__u32 frag_point;
 
 	/* Ack State   : This flag indicates if the next received
-	 *             : packet is to be responded to with a
-	 *             : SACK. This is initializedto 0.  When a packet
-	 *             : is received it is incremented. If this value
-	 *             : reaches 2 or more, a SACK is sent and the
-	 *             : value is reset to 0. Note: This is used only
-	 *             : when no DATA chunks are received out of
-	 *	       : order.  When DATA chunks are out of order,
-	 *             : SACK's are not delayed (see Section 6).
+	 *	       : packet is to be responded to with a
+	 *	       : SACK. This is initializedto 0.	 When a packet
+	 *	       : is received it is incremented. If this value
+	 *	       : reaches 2 or more, a SACK is sent and the
+	 *	       : value is reset to 0. Note: This is used only
+	 *	       : when no DATA chunks are received out of
+	 *	       : order.	 When DATA chunks are out of order,
+	 *	       : SACK's are not delayed (see Section 6).
 	 */
 	/* Do we need to send an ack?
 	 * When counters[SctpCounterAckState] is above 1 we do!
@@ -1531,7 +1524,7 @@
 	__u32 default_context;
 	__u32 default_timetolive;
 
-	/* This tracks outbound ssn for a given stream.  */
+	/* This tracks outbound ssn for a given stream.	 */
 	struct sctp_ssnmap *ssnmap;
 
 	/* All outbound chunks go through this structure.  */
@@ -1545,7 +1538,7 @@
 	/* Last TSN that caused an ECNE Chunk to be sent.  */
 	__u32 last_ecne_tsn;
 
-	/* Last TSN that caused a CWR Chunk to be sent.  */
+	/* Last TSN that caused a CWR Chunk to be sent.	 */
 	__u32 last_cwr_tsn;
 
 	/* How many duplicated TSNs have we seen?  */
@@ -1605,7 +1598,7 @@
 	 *
 	 * In defining the ASCONF Chunk transfer procedures, it is
 	 * essential that these transfers MUST NOT cause congestion
-	 * within the network.  To achieve this, we place these
+	 * within the network.	To achieve this, we place these
 	 * restrictions on the transfer of ASCONF Chunks:
 	 *
 	 * R1) One and only one ASCONF Chunk MAY be in transit and
@@ -1619,8 +1612,8 @@
 	 *
 	 *
 	 * [I really think this is EXACTLY the sort of intelligence
-	 *  which already resides in sctp_outq.  Please move this
-	 *  queue and its supporting logic down there.  --piggy]
+	 *  which already resides in sctp_outq.	 Please move this
+	 *  queue and its supporting logic down there.	--piggy]
 	 */
 	struct sk_buff_head addip_chunks;
 
@@ -1673,7 +1666,7 @@
 	return asoc;
 }
 
-/* These are function signatures for manipulating associations.  */
+/* These are function signatures for manipulating associations.	 */
 
 
 struct sctp_association *
@@ -1710,16 +1703,16 @@
 __u32 sctp_association_get_tsn_block(struct sctp_association *, int);
 
 void sctp_assoc_sync_pmtu(struct sctp_association *);
-void sctp_assoc_rwnd_increase(struct sctp_association *, int);
-void sctp_assoc_rwnd_decrease(struct sctp_association *, int);
+void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
+void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
 void sctp_assoc_set_primary(struct sctp_association *,
 			    struct sctp_transport *);
 int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, int);
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
-					 sctp_cookie_t *, int gfp);
+					 struct sctp_cookie*, int gfp);
 
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
-		        const union sctp_addr *ss2);
+			const union sctp_addr *ss2);
 struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc);
 struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc);
 
diff -urN linux-2.5.73-bk5/include/net/sctp/tsnmap.h linux-2.5.73-bk6/include/net/sctp/tsnmap.h
--- linux-2.5.73-bk5/include/net/sctp/tsnmap.h	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk6/include/net/sctp/tsnmap.h	2003-06-28 04:53:20.000000000 -0700
@@ -1,5 +1,8 @@
-/* SCTP kernel reference Implementation Copyright (C) 1999-2001
- * Cisco, Motorola, Intel, and International Business Machines Corp.
+/* SCTP kernel reference Implementation
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
+ * Copyright (c) 2001 Intel Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
  *
@@ -97,13 +100,16 @@
 	/* Data chunks pending receipt. used by SCTP_STATUS sockopt */
 	__u16 pending_data;
 
-	/* We record duplicate TSNs here.  We clear this after
+	/* Record duplicate TSNs here.  We clear this after
 	 * every SACK.  Store up to SCTP_MAX_DUP_TSNS worth of
 	 * information.
 	 */
 	__u32 dup_tsns[SCTP_MAX_DUP_TSNS];
 	__u16 num_dup_tsns;
 
+	/* Record gap ack block information here.  */
+	struct sctp_gap_ack_block gabs[SCTP_MAX_GABS];
+
 	int malloced;
 
 	__u8 raw_map[0];
@@ -140,12 +146,18 @@
 void sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn);
 
 /* Retrieve the Cumulative TSN ACK Point.  */
-__u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *);
+static inline __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map)
+{
+	return map->cumulative_tsn_ack_point;
+}
 
 /* Retrieve the highest TSN we've seen.  */
-__u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *);
+static inline __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map)
+{
+	return map->max_tsn_seen;
+}
 
-/* How many Duplicate TSNs are stored? */
+/* How many duplicate TSNs are stored? */
 static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map)
 {
 	return map->num_dup_tsns;
@@ -158,6 +170,27 @@
 	return map->dup_tsns;
 }
 
+/* How many gap ack blocks do we have recorded? */
+__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map);
+
+/* Refresh the count on pending data. */
+__u16 sctp_tsnmap_pending(struct sctp_tsnmap *map);
+
+/* Return pointer to gap ack blocks as needed by SACK. */
+static inline struct sctp_gap_ack_block *sctp_tsnmap_get_gabs(struct sctp_tsnmap *map)
+{
+	return map->gabs;
+}
+
+/* Is there a gap in the TSN map?  */
+static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
+{
+	int has_gap;
+
+	has_gap = (map->cumulative_tsn_ack_point != map->max_tsn_seen);
+	return has_gap;
+}
+
 /* Mark a duplicate TSN.  Note:  limit the storage of duplicate TSN
  * information.
  */
diff -urN linux-2.5.73-bk5/include/net/sctp/user.h linux-2.5.73-bk6/include/net/sctp/user.h
--- linux-2.5.73-bk5/include/net/sctp/user.h	2003-06-22 11:32:30.000000000 -0700
+++ linux-2.5.73-bk6/include/net/sctp/user.h	2003-06-28 04:53:20.000000000 -0700
@@ -40,6 +40,7 @@
  *    Karl Knutson             <karl@athena.chicago.il.us>
  *    Jon Grimm                <jgrimm@us.ibm.com>
  *    Daisy Chang              <daisyc@us.ibm.com>
+ *    Ryan Layer               <rmlayer@us.ibm.com>
  * 
  * 
  * Any bugs reported given to us we will try to fix... any fixes shared will
@@ -517,11 +518,14 @@
  */
 
 struct sctp_assocparams {
-	__u16		sasoc_asocmaxrxt;
 	sctp_assoc_t	sasoc_assoc_id;
+	__u16		sasoc_asocmaxrxt;
+	__u16		sasoc_number_peer_destinations;
+	__u32		sasoc_peer_rwnd;
+	__u32		sasoc_local_rwnd;
+	__u32		sasoc_cookie_life;
 };
 
-
 /*
  * 7.1.9 Set Primary Address (SCTP_SET_PRIMARY_ADDR)
  *
diff -urN linux-2.5.73-bk5/include/net/tcp.h linux-2.5.73-bk6/include/net/tcp.h
--- linux-2.5.73-bk5/include/net/tcp.h	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk6/include/net/tcp.h	2003-06-28 04:53:20.000000000 -0700
@@ -1244,7 +1244,7 @@
 	}
 }
 
-extern __u32 tcp_init_cwnd(struct tcp_opt *tp);
+extern __u32 tcp_init_cwnd(struct tcp_opt *tp, struct dst_entry *dst);
 
 /* Slow start with delack produces 3 packets of burst, so that
  * it is safe "de facto".
diff -urN linux-2.5.73-bk5/kernel/exit.c linux-2.5.73-bk6/kernel/exit.c
--- linux-2.5.73-bk5/kernel/exit.c	2003-06-22 11:33:15.000000000 -0700
+++ linux-2.5.73-bk6/kernel/exit.c	2003-06-28 04:53:20.000000000 -0700
@@ -41,7 +41,7 @@
 		detach_pid(p, PIDTYPE_PGID);
 		detach_pid(p, PIDTYPE_SID);
 		if (p->pid)
-			per_cpu(process_counts, smp_processor_id())--;
+			__get_cpu_var(process_counts)--;
 	}
 
 	REMOVE_LINKS(p);
diff -urN linux-2.5.73-bk5/kernel/fork.c linux-2.5.73-bk6/kernel/fork.c
--- linux-2.5.73-bk5/kernel/fork.c	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk6/kernel/fork.c	2003-06-28 04:53:20.000000000 -0700
@@ -1006,7 +1006,7 @@
 		attach_pid(p, PIDTYPE_PGID, p->pgrp);
 		attach_pid(p, PIDTYPE_SID, p->session);
 		if (p->pid)
-			per_cpu(process_counts, smp_processor_id())++;
+			__get_cpu_var(process_counts)++;
 	} else
 		link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid);
 
diff -urN linux-2.5.73-bk5/kernel/timer.c linux-2.5.73-bk6/kernel/timer.c
--- linux-2.5.73-bk5/kernel/timer.c	2003-06-22 11:33:10.000000000 -0700
+++ linux-2.5.73-bk6/kernel/timer.c	2003-06-28 04:53:20.000000000 -0700
@@ -156,8 +156,7 @@
  */
 void add_timer(struct timer_list *timer)
 {
-	int cpu = get_cpu();
-	tvec_base_t *base = &per_cpu(tvec_bases, cpu);
+	tvec_base_t *base = &get_cpu_var(tvec_bases);
   	unsigned long flags;
   
   	BUG_ON(timer_pending(timer) || !timer->function);
@@ -168,7 +167,7 @@
 	internal_add_timer(base, timer);
 	timer->base = base;
 	spin_unlock_irqrestore(&base->lock, flags);
-	put_cpu();
+	put_cpu_var(tvec_bases);
 }
 
 /***
@@ -231,7 +230,7 @@
 		return 1;
 
 	spin_lock_irqsave(&timer->lock, flags);
-	new_base = &per_cpu(tvec_bases, smp_processor_id());
+	new_base = &__get_cpu_var(tvec_bases);
 repeat:
 	old_base = timer->base;
 
@@ -789,7 +788,7 @@
  */
 static void run_timer_softirq(struct softirq_action *h)
 {
-	tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id());
+	tvec_base_t *base = &__get_cpu_var(tvec_bases);
 
 	if (time_after_eq(jiffies, base->timer_jiffies))
 		__run_timers(base);
diff -urN linux-2.5.73-bk5/mm/page-writeback.c linux-2.5.73-bk6/mm/page-writeback.c
--- linux-2.5.73-bk5/mm/page-writeback.c	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk6/mm/page-writeback.c	2003-06-28 04:53:20.000000000 -0700
@@ -213,21 +213,19 @@
 void balance_dirty_pages_ratelimited(struct address_space *mapping)
 {
 	static DEFINE_PER_CPU(int, ratelimits) = 0;
-	int cpu;
 	long ratelimit;
 
 	ratelimit = ratelimit_pages;
 	if (dirty_exceeded)
 		ratelimit = 8;
 
-	cpu = get_cpu();
-	if (per_cpu(ratelimits, cpu)++ >= ratelimit) {
-		per_cpu(ratelimits, cpu) = 0;
-		put_cpu();
+	if (get_cpu_var(ratelimits)++ >= ratelimit) {
+		__get_cpu_var(ratelimits) = 0;
+		put_cpu_var(ratelimits);
 		balance_dirty_pages(mapping);
 		return;
 	}
-	put_cpu();
+	put_cpu_var(ratelimits);
 }
 
 /*
diff -urN linux-2.5.73-bk5/mm/rmap.c linux-2.5.73-bk6/mm/rmap.c
--- linux-2.5.73-bk5/mm/rmap.c	2003-06-22 11:33:17.000000000 -0700
+++ linux-2.5.73-bk6/mm/rmap.c	2003-06-28 04:53:20.000000000 -0700
@@ -477,16 +477,15 @@
  */
 void __pte_chain_free(struct pte_chain *pte_chain)
 {
-	int cpu = get_cpu();
 	struct pte_chain **pte_chainp;
 
+	pte_chainp = &get_cpu_var(local_pte_chain);
 	if (pte_chain->next_and_idx)
 		pte_chain->next_and_idx = 0;
-	pte_chainp = &per_cpu(local_pte_chain, cpu);
 	if (*pte_chainp)
 		kmem_cache_free(pte_chain_cache, *pte_chainp);
 	*pte_chainp = pte_chain;
-	put_cpu();
+	put_cpu_var(local_pte_chain);
 }
 
 /*
@@ -501,21 +500,19 @@
  */
 struct pte_chain *pte_chain_alloc(int gfp_flags)
 {
-	int cpu;
 	struct pte_chain *ret;
 	struct pte_chain **pte_chainp;
 
 	if (gfp_flags & __GFP_WAIT)
 		might_sleep();
 
-	cpu = get_cpu();
-	pte_chainp = &per_cpu(local_pte_chain, cpu);
+	pte_chainp = &get_cpu_var(local_pte_chain);
 	if (*pte_chainp) {
 		ret = *pte_chainp;
 		*pte_chainp = NULL;
-		put_cpu();
+		put_cpu_var(local_pte_chain);
 	} else {
-		put_cpu();
+		put_cpu_var(local_pte_chain);
 		ret = kmem_cache_alloc(pte_chain_cache, gfp_flags);
 	}
 	return ret;
diff -urN linux-2.5.73-bk5/mm/swap.c linux-2.5.73-bk6/mm/swap.c
--- linux-2.5.73-bk5/mm/swap.c	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk6/mm/swap.c	2003-06-28 04:53:20.000000000 -0700
@@ -112,35 +112,34 @@
 
 void lru_cache_add(struct page *page)
 {
-	struct pagevec *pvec = &per_cpu(lru_add_pvecs, get_cpu());
+	struct pagevec *pvec = &get_cpu_var(lru_add_pvecs);
 
 	page_cache_get(page);
 	if (!pagevec_add(pvec, page))
 		__pagevec_lru_add(pvec);
-	put_cpu();
+	put_cpu_var(lru_add_pvecs);
 }
 
 void lru_cache_add_active(struct page *page)
 {
-	struct pagevec *pvec = &per_cpu(lru_add_active_pvecs, get_cpu());
+	struct pagevec *pvec = &get_cpu_var(lru_add_active_pvecs);
 
 	page_cache_get(page);
 	if (!pagevec_add(pvec, page))
 		__pagevec_lru_add_active(pvec);
-	put_cpu();
+	put_cpu_var(lru_add_active_pvecs);
 }
 
 void lru_add_drain(void)
 {
-	int cpu = get_cpu();
-	struct pagevec *pvec = &per_cpu(lru_add_pvecs, cpu);
+	struct pagevec *pvec = &get_cpu_var(lru_add_pvecs);
 
 	if (pagevec_count(pvec))
 		__pagevec_lru_add(pvec);
-	pvec = &per_cpu(lru_add_active_pvecs, cpu);
+	pvec = &__get_cpu_var(lru_add_active_pvecs);
 	if (pagevec_count(pvec))
 		__pagevec_lru_add_active(pvec);
-	put_cpu();
+	put_cpu_var(lru_add_pvecs);
 }
 
 /*
diff -urN linux-2.5.73-bk5/net/ax25/sysctl_net_ax25.c linux-2.5.73-bk6/net/ax25/sysctl_net_ax25.c
--- linux-2.5.73-bk5/net/ax25/sysctl_net_ax25.c	2003-06-22 11:33:17.000000000 -0700
+++ linux-2.5.73-bk6/net/ax25/sysctl_net_ax25.c	2003-06-28 04:53:20.000000000 -0700
@@ -36,7 +36,6 @@
 	{
 		.ctl_name	= NET_AX25,
 		.procname	= "ax25",
-		.maxlen		= 0,
 		.mode		= 0555,
 	},
 	{ .ctl_name = 0 }
@@ -46,7 +45,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ax25_dir_table
 	},
diff -urN linux-2.5.73-bk5/net/ipv4/icmp.c linux-2.5.73-bk6/net/ipv4/icmp.c
--- linux-2.5.73-bk5/net/ipv4/icmp.c	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/net/ipv4/icmp.c	2003-06-28 04:53:20.000000000 -0700
@@ -228,7 +228,7 @@
  *	On SMP we have one ICMP socket per-cpu.
  */
 static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
-#define icmp_socket	per_cpu(__icmp_socket, smp_processor_id())
+#define icmp_socket	__get_cpu_var(__icmp_socket)
 
 static __inline__ void icmp_xmit_lock(void)
 {
diff -urN linux-2.5.73-bk5/net/ipv4/tcp_input.c linux-2.5.73-bk6/net/ipv4/tcp_input.c
--- linux-2.5.73-bk5/net/ipv4/tcp_input.c	2003-06-22 11:33:05.000000000 -0700
+++ linux-2.5.73-bk6/net/ipv4/tcp_input.c	2003-06-28 04:53:21.000000000 -0700
@@ -598,25 +598,17 @@
 	}
 }
 
-/* Increase initial CWND conservatively: if estimated
- * RTT is low enough (<20msec) or if we have some preset ssthresh.
- *
- * Numbers are taken from RFC2414.
- */
-__u32 tcp_init_cwnd(struct tcp_opt *tp)
+/* Numbers are taken from RFC2414.  */
+__u32 tcp_init_cwnd(struct tcp_opt *tp, struct dst_entry *dst)
 {
-	__u32 cwnd;
-
-	if (tp->mss_cache > 1460)
-		return 2;
-
-	cwnd = (tp->mss_cache > 1095) ? 3 : 4;
-
-	if (!tp->srtt || (tp->snd_ssthresh >= 0xFFFF && tp->srtt > ((HZ/50)<<3)))
-		cwnd = 2;
-	else if (cwnd > tp->snd_ssthresh)
-		cwnd = tp->snd_ssthresh;
+	__u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
 
+	if (!cwnd) {
+		if (tp->mss_cache > 1460)
+			cwnd = 2;
+		else
+			cwnd = (tp->mss_cache > 1095) ? 3 : 4;
+	}
 	return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
 }
 
@@ -675,7 +667,7 @@
 	tcp_bound_rto(tp);
 	if (tp->rto < TCP_TIMEOUT_INIT && !tp->saw_tstamp)
 		goto reset;
-	tp->snd_cwnd = tcp_init_cwnd(tp);
+	tp->snd_cwnd = tcp_init_cwnd(tp, dst);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 	return;
 
diff -urN linux-2.5.73-bk5/net/ipv4/tcp_minisocks.c linux-2.5.73-bk6/net/ipv4/tcp_minisocks.c
--- linux-2.5.73-bk5/net/ipv4/tcp_minisocks.c	2003-06-22 11:33:06.000000000 -0700
+++ linux-2.5.73-bk6/net/ipv4/tcp_minisocks.c	2003-06-28 04:53:21.000000000 -0700
@@ -23,6 +23,7 @@
 #include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
+#include <linux/workqueue.h>
 #include <net/tcp.h>
 #include <net/inet_common.h>
 #include <net/xfrm.h>
@@ -407,15 +408,22 @@
 #define TCP_TWKILL_SLOTS	8	/* Please keep this a power of 2. */
 #define TCP_TWKILL_PERIOD	(TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS)
 
+#define TCP_TWKILL_QUOTA	100
+
 static struct hlist_head tcp_tw_death_row[TCP_TWKILL_SLOTS];
 static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED;
 static struct timer_list tcp_tw_timer = TIMER_INITIALIZER(tcp_twkill, 0, 0);
+static void twkill_work(void *);
+static DECLARE_WORK(tcp_twkill_work, twkill_work, NULL);
+static u32 twkill_thread_slots;
 
-static void tcp_twkill(unsigned long dummy)
+/* Returns non-zero if quota exceeded.  */
+static int tcp_do_twkill_work(int slot, unsigned int quota)
 {
 	struct tcp_tw_bucket *tw;
 	struct hlist_node *node, *safe;
-	int killed = 0;
+	unsigned int killed;
+	int ret;
 
 	/* NOTE: compare this to previous version where lock
 	 * was released after detaching chain. It was racy,
@@ -423,30 +431,86 @@
 	 * in 2.3 (with netfilter), and with softnet it is common, because
 	 * soft irqs are not sequenced.
 	 */
-	spin_lock(&tw_death_lock);
-
-	if (tcp_tw_count == 0)
-		goto out;
-
+	killed = 0;
+	ret = 0;
 	tw_for_each_inmate(tw, node, safe,
-			   &tcp_tw_death_row[tcp_tw_death_row_slot]) {
+			   &tcp_tw_death_row[slot]) {
 		__tw_del_dead_node(tw);
 		spin_unlock(&tw_death_lock);
 		tcp_timewait_kill(tw);
 		tcp_tw_put(tw);
 		killed++;
 		spin_lock(&tw_death_lock);
+		if (killed > quota) {
+			ret = 1;
+			break;
+		}
 	}
-	tcp_tw_death_row_slot =
-		((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1));
 
-	if ((tcp_tw_count -= killed) != 0)
-		mod_timer(&tcp_tw_timer, jiffies+TCP_TWKILL_PERIOD);
+	tcp_tw_count -= killed;
 	NET_ADD_STATS_BH(TimeWaited, killed);
+
+	return ret;
+}
+
+static void tcp_twkill(unsigned long dummy)
+{
+	int need_timer, ret;
+
+	spin_lock(&tw_death_lock);
+
+	if (tcp_tw_count == 0)
+		goto out;
+
+	need_timer = 0;
+	ret = tcp_do_twkill_work(tcp_tw_death_row_slot, TCP_TWKILL_QUOTA);
+	if (ret) {
+		twkill_thread_slots |= (1 << tcp_tw_death_row_slot);
+		mb();
+		schedule_work(&tcp_twkill_work);
+		need_timer = 1;
+	} else {
+		/* We purged the entire slot, anything left?  */
+		if (tcp_tw_count)
+			need_timer = 1;
+	}
+	tcp_tw_death_row_slot =
+		((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1));
+	if (need_timer)
+		mod_timer(&tcp_tw_timer, jiffies + TCP_TWKILL_PERIOD);
 out:
 	spin_unlock(&tw_death_lock);
 }
 
+extern void twkill_slots_invalid(void);
+
+static void twkill_work(void *dummy)
+{
+	int i;
+
+	if ((TCP_TWKILL_SLOTS - 1) > (sizeof(twkill_thread_slots) * 8))
+		twkill_slots_invalid();
+
+	while (twkill_thread_slots) {
+		spin_lock_bh(&tw_death_lock);
+		for (i = 0; i < TCP_TWKILL_SLOTS; i++) {
+			if (!(twkill_thread_slots & (1 << i)))
+				continue;
+
+			while (tcp_do_twkill_work(i, TCP_TWKILL_QUOTA) != 0) {
+				if (need_resched()) {
+					spin_unlock_bh(&tw_death_lock);
+					schedule();
+					spin_lock_bh(&tw_death_lock);
+				}
+			}
+
+			twkill_thread_slots &= ~(1 << i);
+		}
+		spin_unlock_bh(&tw_death_lock);
+	}
+}
+
 /* These are always called from BH context.  See callers in
  * tcp_input.c to verify this.
  */
diff -urN linux-2.5.73-bk5/net/ipv4/tcp_output.c linux-2.5.73-bk6/net/ipv4/tcp_output.c
--- linux-2.5.73-bk5/net/ipv4/tcp_output.c	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk6/net/ipv4/tcp_output.c	2003-06-28 04:53:21.000000000 -0700
@@ -99,10 +99,10 @@
 
 /* RFC2861. Reset CWND after idle period longer RTO to "restart window".
  * This is the first part of cwnd validation mechanism. */
-static void tcp_cwnd_restart(struct tcp_opt *tp)
+static void tcp_cwnd_restart(struct tcp_opt *tp, struct dst_entry *dst)
 {
 	s32 delta = tcp_time_stamp - tp->lsndtime;
-	u32 restart_cwnd = tcp_init_cwnd(tp);
+	u32 restart_cwnd = tcp_init_cwnd(tp, dst);
 	u32 cwnd = tp->snd_cwnd;
 
 	tp->snd_ssthresh = tcp_current_ssthresh(tp);
@@ -115,12 +115,12 @@
 	tp->snd_cwnd_used = 0;
 }
 
-static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb)
+static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb, struct sock *sk)
 {
 	u32 now = tcp_time_stamp;
 
 	if (!tp->packets_out && (s32)(now - tp->lsndtime) > tp->rto)
-		tcp_cwnd_restart(tp);
+		tcp_cwnd_restart(tp, __sk_dst_get(sk));
 
 	tp->lsndtime = now;
 
@@ -272,7 +272,7 @@
 			tcp_event_ack_sent(sk);
 
 		if (skb->len != tcp_header_size)
-			tcp_event_data_sent(tp, skb);
+			tcp_event_data_sent(tp, skb, sk);
 
 		TCP_INC_STATS(TcpOutSegs);
 
diff -urN linux-2.5.73-bk5/net/ipv6/ip6_output.c linux-2.5.73-bk6/net/ipv6/ip6_output.c
--- linux-2.5.73-bk5/net/ipv6/ip6_output.c	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/net/ipv6/ip6_output.c	2003-06-28 04:53:21.000000000 -0700
@@ -939,7 +939,7 @@
 	mtu = dst_pmtu(&rt->u.dst) - hlen - sizeof(struct frag_hdr);
 
 	if (skb_shinfo(skb)->frag_list) {
-		int first_len = 0;
+		int first_len = skb_pagelen(skb);
 
 		if (first_len - hlen > mtu ||
 		    ((first_len - hlen) & 7) ||
diff -urN linux-2.5.73-bk5/net/ipv6/ndisc.c linux-2.5.73-bk6/net/ipv6/ndisc.c
--- linux-2.5.73-bk5/net/ipv6/ndisc.c	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/net/ipv6/ndisc.c	2003-06-28 04:53:21.000000000 -0700
@@ -144,6 +144,19 @@
 	.gc_thresh3 =	1024,
 };
 
+/* ND options */
+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]
+
 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
 
 static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
@@ -160,8 +173,8 @@
 	return opt + space;
 }
 
-struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
-				     struct nd_opt_hdr *end)
+static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
+					    struct nd_opt_hdr *end)
 {
 	int type;
 	if (!cur || !end || cur >= end)
@@ -173,8 +186,8 @@
 	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)
+static 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;
 
@@ -375,7 +388,7 @@
  *	Send a Neighbour Advertisement
  */
 
-int ndisc_output(struct sk_buff *skb)
+static int ndisc_output(struct sk_buff *skb)
 {
 	if (skb) {
 		struct neighbour *neigh = (skb->dst ? skb->dst->neighbour : NULL);
@@ -701,7 +714,7 @@
 	}
 }
 
-void ndisc_recv_ns(struct sk_buff *skb)
+static void ndisc_recv_ns(struct sk_buff *skb)
 {
 	struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
 	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
@@ -908,7 +921,7 @@
 	return;
 }
 
-void ndisc_recv_na(struct sk_buff *skb)
+static void ndisc_recv_na(struct sk_buff *skb)
 {
 	struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
 	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
diff -urN linux-2.5.73-bk5/net/ipv6/sysctl_net_ipv6.c linux-2.5.73-bk6/net/ipv6/sysctl_net_ipv6.c
--- linux-2.5.73-bk5/net/ipv6/sysctl_net_ipv6.c	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk6/net/ipv6/sysctl_net_ipv6.c	2003-06-28 04:53:21.000000000 -0700
@@ -86,7 +86,6 @@
 	{
 		.ctl_name	= NET_IPV6,
 		.procname	= "ipv6",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ipv6_table
 	},
@@ -97,7 +96,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ipv6_net_table
 	},
diff -urN linux-2.5.73-bk5/net/netrom/sysctl_net_netrom.c linux-2.5.73-bk6/net/netrom/sysctl_net_netrom.c
--- linux-2.5.73-bk5/net/netrom/sysctl_net_netrom.c	2003-06-22 11:32:37.000000000 -0700
+++ linux-2.5.73-bk6/net/netrom/sysctl_net_netrom.c	2003-06-28 04:53:21.000000000 -0700
@@ -162,7 +162,6 @@
 	{
 		.ctl_name	= NET_NETROM,
 		.procname	= "netrom",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= nr_table
 	},
@@ -173,7 +172,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= nr_dir_table
 	},
diff -urN linux-2.5.73-bk5/net/rose/sysctl_net_rose.c linux-2.5.73-bk6/net/rose/sysctl_net_rose.c
--- linux-2.5.73-bk5/net/rose/sysctl_net_rose.c	2003-06-22 11:32:27.000000000 -0700
+++ linux-2.5.73-bk6/net/rose/sysctl_net_rose.c	2003-06-28 04:53:21.000000000 -0700
@@ -142,7 +142,6 @@
 	{
 		.ctl_name	= NET_ROSE,
 		.procname	= "rose",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= rose_table
 	},
@@ -153,7 +152,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= rose_dir_table
 	},
diff -urN linux-2.5.73-bk5/net/rxrpc/sysctl.c linux-2.5.73-bk6/net/rxrpc/sysctl.c
--- linux-2.5.73-bk5/net/rxrpc/sysctl.c	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk6/net/rxrpc/sysctl.c	2003-06-28 04:53:21.000000000 -0700
@@ -68,7 +68,6 @@
 	{
 		.ctl_name	= 1,
 		.procname	= "rxrpc",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= rxrpc_sysctl_table
 	},
diff -urN linux-2.5.73-bk5/net/sctp/associola.c linux-2.5.73-bk6/net/sctp/associola.c
--- linux-2.5.73-bk5/net/sctp/associola.c	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/associola.c	2003-06-28 04:53:21.000000000 -0700
@@ -41,6 +41,7 @@
  *    Hui Huang             <hui.huang@nokia.com>
  *    Sridhar Samudrala	    <sri@us.ibm.com>
  *    Daisy Chang	    <daisyc@us.ibm.com>
+ *    Ryan Layer	    <rmlayer@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.
@@ -125,23 +126,24 @@
 	asoc->base.addr_lock = RW_LOCK_UNLOCKED;
 
 	asoc->state = SCTP_STATE_CLOSED;
-	asoc->state_timestamp = jiffies;
-
-	/* Set things that have constant value.  */
-	asoc->cookie_life.tv_sec = sctp_valid_cookie_life / HZ;
-	asoc->cookie_life.tv_usec = (sctp_valid_cookie_life % HZ) *
-					1000000L / HZ;
 
+	/* Set these values from the socket values, a conversion between
+	 * millsecons to seconds/microseconds must also be done.
+	 */
+	asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000;
+	asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000)
+					* 1000;
 	asoc->pmtu = 0;
 	asoc->frag_point = 0;
 
-	/* Initialize the default association max_retrans and RTO values.  */
-	asoc->max_retrans = sctp_max_retrans_association;
-	asoc->rto_initial = sctp_rto_initial;
-	asoc->rto_max = sctp_rto_max;
-	asoc->rto_min = sctp_rto_min;
+	/* Set the association max_retrans and RTO values from the
+	 * socket values.
+	 */
+	asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
+	asoc->rto_initial = sp->rtoinfo.srto_initial * HZ / 1000;
+	asoc->rto_max = sp->rtoinfo.srto_max * HZ / 1000;
+	asoc->rto_min = sp->rtoinfo.srto_min * HZ / 1000;
 
-	asoc->overall_error_threshold = asoc->max_retrans;
 	asoc->overall_error_count = 0;
 
 	/* Initialize the maximum mumber of new data packets that can be sent
@@ -164,7 +166,8 @@
 	asoc->c.sinit_max_instreams = sp->initmsg.sinit_max_instreams;
 	asoc->c.sinit_num_ostreams  = sp->initmsg.sinit_num_ostreams;
 	asoc->max_init_attempts	= sp->initmsg.sinit_max_attempts;
-	asoc->max_init_timeo    = sp->initmsg.sinit_max_init_timeo * HZ;
+
+	asoc->max_init_timeo    = sp->initmsg.sinit_max_init_timeo * HZ / 1000;
 
 	/* Allocate storage for the ssnmap after the inbound and outbound
 	 * streams have been negotiated during Init.
@@ -281,7 +284,7 @@
 	asoc->default_flags = sp->default_flags;
 	asoc->default_context = sp->default_context;
 	asoc->default_timetolive = sp->default_timetolive;
-	
+
 	return asoc;
 
 fail_init:
@@ -384,7 +387,7 @@
 	if (transport->active)
 		asoc->peer.active_path = transport;
 
-	/* 
+	/*
 	 * SFR-CACC algorithm:
 	 * Upon the receipt of a request to change the primary
 	 * destination address, on the data structure for the new
@@ -491,9 +494,14 @@
 	/* Initialize the peer's heartbeat interval based on the
 	 * sock configured value.
 	 */
-
 	peer->hb_interval = sp->paddrparam.spp_hbinterval * HZ;
 
+	/* Set the path max_retrans.  */
+	peer->max_retrans = asoc->max_retrans;
+
+	/* Set the transport's RTO.initial value */
+	peer->rto = asoc->rto_initial;
+
 	/* Attach the remote transport to our asoc.  */
 	list_add_tail(&peer->transports, &asoc->peer.transport_addr_list);
 
@@ -793,6 +801,26 @@
 	return transport;
 }
 
+/*  Is this a live association structure. */
+int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc)
+{
+
+	/* First, verify that this is a kernel address. */
+	if (!sctp_is_valid_kaddr((unsigned long) asoc))
+		return 0;
+
+	/* Verify that this _is_ an sctp_association
+	 * data structure and if so, that the socket matches.
+	 */
+	if (SCTP_ASSOC_EYECATCHER != asoc->eyecatcher)
+		return 0;
+	if (asoc->base.sk != sk)
+		return 0;
+
+	/* The association is valid. */
+	return 1;
+}
+
 /* Do delayed input processing.  This is scheduled by sctp_rcv(). */
 static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
 {
@@ -801,7 +829,6 @@
 	struct sock *sk;
 	struct sctp_inq *inqueue;
 	int state, subtype;
-	sctp_assoc_t associd = sctp_assoc2id(asoc);
 	int error = 0;
 
 	/* The association should be held so we should be safe. */
@@ -831,7 +858,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))
+		if (!sctp_assoc_valid(sk, asoc))
 			break;
 
 		/* If there is an error on chunk, discard this packet. */
@@ -1033,7 +1060,7 @@
 }
 
 /* Increase asoc's rwnd by len and send any window update SACK if needed. */
-void sctp_assoc_rwnd_increase(struct sctp_association *asoc, int len)
+void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned len)
 {
 	struct sctp_chunk *sack;
 	struct timer_list *timer;
@@ -1079,7 +1106,7 @@
 }
 
 /* Decrease asoc's rwnd by len. */
-void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, int len)
+void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len)
 {
 	SCTP_ASSERT(asoc->rwnd, "rwnd zero", return);
 	SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return);
@@ -1119,11 +1146,11 @@
 
 /* Build the association's bind address list from the cookie.  */
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc,
-					 sctp_cookie_t *cookie, int gfp)
+					 struct sctp_cookie *cookie, int gfp)
 {
 	int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length);
 	int var_size3 = cookie->raw_addr_list_len;
-	__u8 *raw = (__u8 *)cookie + sizeof(sctp_cookie_t) + var_size2;
+	__u8 *raw = (__u8 *)cookie + sizeof(struct sctp_cookie) + var_size2;
 
 	return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw, var_size3,
 				      asoc->ep->base.bind_addr.port, gfp);
diff -urN linux-2.5.73-bk5/net/sctp/bind_addr.c linux-2.5.73-bk6/net/sctp/bind_addr.c
--- linux-2.5.73-bk5/net/sctp/bind_addr.c	2003-06-22 11:33:12.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/bind_addr.c	2003-06-28 04:53:21.000000000 -0700
@@ -65,7 +65,7 @@
 			const struct sctp_bind_addr *src,
 			sctp_scope_t scope, int gfp, int flags)
 {
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 	struct list_head *pos;
 	int error = 0;
 
@@ -74,7 +74,7 @@
 
 	/* Extract the addresses which are relevant for this scope.  */
 	list_for_each(pos, &src->address_list) {
-		addr = list_entry(pos, struct sockaddr_storage_list, list);
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		error = sctp_copy_one_addr(dest, &addr->a, scope,
 					   gfp, flags);
 		if (error < 0)
@@ -87,7 +87,7 @@
 	 */
 	if (list_empty(&dest->address_list) && (SCTP_SCOPE_GLOBAL == scope)) {
 		list_for_each(pos, &src->address_list) {
-			addr = list_entry(pos, struct sockaddr_storage_list,
+			addr = list_entry(pos, struct sctp_sockaddr_entry,
 					  list);
 			error = sctp_copy_one_addr(dest, &addr->a,
 						   SCTP_SCOPE_LINK, gfp,
@@ -135,12 +135,12 @@
 /* Dispose of the address list. */
 static void sctp_bind_addr_clean(struct sctp_bind_addr *bp)
 {
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 	struct list_head *pos, *temp;
 
 	/* Empty the bind address list. */
 	list_for_each_safe(pos, temp, &bp->address_list) {
-		addr = list_entry(pos, struct sockaddr_storage_list, list);
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		list_del(pos);
 		kfree(addr);
 		SCTP_DBG_OBJCNT_DEC(addr);
@@ -163,14 +163,14 @@
 int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
 		       int gfp)
 {
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 
 	/* Add the address to the bind address list.  */
-	addr = t_new(struct sockaddr_storage_list, gfp);
+	addr = t_new(struct sctp_sockaddr_entry, gfp);
 	if (!addr)
 		return -ENOMEM;
 
-	addr->a = *new;
+	memcpy(&addr->a, new, sizeof(*new));
 
 	/* Fix up the port if it has not yet been set.
 	 * Both v4 and v6 have the port at the same offset.
@@ -191,10 +191,10 @@
 int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
 {
 	struct list_head *pos, *temp;
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 
 	list_for_each_safe(pos, temp, &bp->address_list) {
-		addr = list_entry(pos, struct sockaddr_storage_list, list);
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		if (sctp_cmp_addr_exact(&addr->a, del_addr)) {
 			/* Found the exact match. */
 			list_del(pos);
@@ -219,22 +219,22 @@
 	union sctp_params addrparms;
 	union sctp_params retval;
 	int addrparms_len;
-	sctp_addr_param_t rawaddr;
+	union sctp_addr_param rawaddr;
 	int len;
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 	struct list_head *pos;
 	addrparms_len = 0;
 	len = 0;
 
 	/* Allocate enough memory at once. */
 	list_for_each(pos, &bp->address_list) {
-		len += sizeof(sctp_addr_param_t);
+		len += sizeof(union sctp_addr_param);
 	}
 
 	/* Don't even bother embedding an address if there
 	 * is only one.
 	 */
-	if (len == sizeof(sctp_addr_param_t)) {
+	if (len == sizeof(union sctp_addr_param)) {
 		retval.v = NULL;
 		goto end_raw;
 	}
@@ -246,7 +246,7 @@
 	addrparms = retval;
 
 	list_for_each(pos, &bp->address_list) {
-		addr = list_entry(pos, struct sockaddr_storage_list, list);
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		len = sockaddr2sctp_addr(&addr->a, &rawaddr);
 		memcpy(addrparms.v, &rawaddr, len);
 		addrparms.v += len;
@@ -265,16 +265,16 @@
 int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
 			   int addrs_len, __u16 port, int gfp)
 {
-	sctp_addr_param_t *rawaddr;
-	sctp_paramhdr_t *param;
+	union sctp_addr_param *rawaddr;
+	struct sctp_paramhdr *param;
 	union sctp_addr addr;
 	int retval = 0;
 	int len;
 
 	/* Convert the raw address to standard address format */
 	while (addrs_len) {
-		param = (sctp_paramhdr_t *)raw_addr_list;
-		rawaddr = (sctp_addr_param_t *)raw_addr_list;
+		param = (struct sctp_paramhdr *)raw_addr_list;
+		rawaddr = (union sctp_addr_param *)raw_addr_list;
 
 		switch (param->type) {
 		case SCTP_PARAM_IPV4_ADDRESS:
@@ -312,11 +312,11 @@
 			 const union sctp_addr *addr,
 			 struct sctp_opt *opt)
 {
-	struct sockaddr_storage_list *laddr;
+	struct sctp_sockaddr_entry *laddr;
 	struct list_head *pos;
 
 	list_for_each(pos, &bp->address_list) {
-		laddr = list_entry(pos, struct sockaddr_storage_list, list);
+		laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		if (opt->pf->cmp_addr(&laddr->a, addr, opt))
  			return 1;
 	}
diff -urN linux-2.5.73-bk5/net/sctp/endpointola.c linux-2.5.73-bk6/net/sctp/endpointola.c
--- linux-2.5.73-bk5/net/sctp/endpointola.c	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/endpointola.c	2003-06-28 04:53:21.000000000 -0700
@@ -129,7 +129,7 @@
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
 		SCTP_DEFAULT_TIMEOUT_T1_INIT;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] =
-		sp->rtoinfo.srto_initial;
+		sp->rtoinfo.srto_initial * HZ / 1000;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
 
 	/* sctpimpguide-05 Section 2.12.2
@@ -137,7 +137,7 @@
 	 * recommended value of 5 times 'RTO.Max'.
 	 */
         ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
-		= 5 * sp->rtoinfo.srto_max;
+		= 5 * (sp->rtoinfo.srto_max * HZ / 1000);
 
 	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] =
 		SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
@@ -313,13 +313,13 @@
 				const union sctp_addr *paddr)
 {
 	struct list_head *pos;
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 	struct sctp_bind_addr *bp;
 
 	sctp_read_lock(&ep->base.addr_lock);
 	bp = &ep->base.bind_addr;
 	list_for_each(pos, &bp->address_list) {
-		addr = list_entry(pos, struct sockaddr_storage_list, list);
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		if (sctp_has_association(&addr->a, paddr)) {
 			sctp_read_unlock(&ep->base.addr_lock);
 			return 1;
diff -urN linux-2.5.73-bk5/net/sctp/hashdriver.c linux-2.5.73-bk6/net/sctp/hashdriver.c
--- linux-2.5.73-bk5/net/sctp/hashdriver.c	2003-06-22 11:33:09.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/hashdriver.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,128 +0,0 @@
-/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola
- * 
- * This file origiantes from Randy Stewart's SCTP reference Implementation.
- * 
- * 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 
- * 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.  
- * 
- * 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: 
- *    Randy Stewart  rstewar1@email.mot.com
- *    Ken Morneau    kmorneau@cisco.com
- *    Qiaobing Xie   qxie1@email.mot.com
- * 
- * Any bugs reported given to us we will try to fix... any fixes shared will
- * be incorperated into the next SCTP release.
- * 
- * There are still LOTS of bugs in this code... I always run on the motto
- * "it is a wonder any code ever works :)"
- */
-
-#include <linux/types.h>
-#include <asm/string.h>
-#include <net/sctp/sctp.h>
-#include <net/sctp/sla1.h>
-
-/* SCTP Main driver.
- * passing a two pointers and two lengths,
- * returning a digest pointer filled. The md5 code
- * was taken directly from the RFC (2104) so to understand it
- * you may want to go look at the RFC referenced in the
- * SCTP spec. We did modify this code to either user OUR
- * implementation of SLA1 or the MD5 that comes from its
- * RFC. SLA1 may have IPR issues so you need to check in
- * to this if you wish to use it... Or at least that is
- * what the FIP-180.1 web page says.
- */
-
-void sctp_hash_digest(const char *key, const int in_key_len,
-		      const char *text, const int text_len,
-		      __u8 *digest)
-{
-	int key_len = in_key_len;
-	struct SLA_1_Context context;
-
-	__u8 k_ipad[65];	/* inner padding -
-				 * key XORd with ipad
-				 */
-	__u8 k_opad[65];	/* outer padding -
-				 * key XORd with opad
-				 */
-	__u8 tk[20];
-	int i;
-
-	/* if key is longer than 64 bytes reset it to key=MD5(key) */
-	if (key_len > 64) {
-		struct SLA_1_Context tctx;
-
-		SLA1_Init(&tctx);
-		SLA1_Process(&tctx, key, key_len);
-		SLA1_Final(&tctx,tk);
-		key = tk;
-		key_len = 20;
-        }
-
-	/*
-	 * the HMAC_MD5 transform looks like:
-	 *
-	 * MD5(K XOR opad, MD5(K XOR ipad, text))
-	 *
-	 * where K is an n byte key
-	 * ipad is the byte 0x36 repeated 64 times
-	 * opad is the byte 0x5c repeated 64 times
-	 * and text is the data being protected
-	 */
-
-	/* start out by storing key in pads */
-	memset(k_ipad, 0, sizeof k_ipad);
-	memset(k_opad, 0, sizeof k_opad);
-	memcpy(k_ipad, key, key_len);
-	memcpy(k_opad, key, key_len);
-
-	/* XOR key with ipad and opad values */
-	for (i = 0; i < 64; i++) {
-		k_ipad[i] ^= 0x36;
-		k_opad[i] ^= 0x5c;
-	}
-
-	/* perform inner hash */
-	SLA1_Init(&context);                     /* init context for 1st
-						  * pass
-						  */
-	SLA1_Process(&context, k_ipad, 64);      /* start with inner pad */
-	SLA1_Process(&context, text, text_len);  /* then text of datagram */
-	SLA1_Final(&context,digest);             /* finish up 1st pass */
-
-	/*
-         * perform outer hash
-         */
-	SLA1_Init(&context);                   /* init context for 2nd
-						* pass
-						*/
-	SLA1_Process(&context, k_opad, 64);     /* start with outer pad */
-	SLA1_Process(&context, digest, 20);     /* then results of 1st
-						 * hash
-						 */
-	SLA1_Final(&context, digest);          /* finish up 2nd pass */
-}
-
diff -urN linux-2.5.73-bk5/net/sctp/ipv6.c linux-2.5.73-bk6/net/sctp/ipv6.c
--- linux-2.5.73-bk5/net/sctp/ipv6.c	2003-06-22 11:32:56.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/ipv6.c	2003-06-28 04:53:21.000000000 -0700
@@ -248,7 +248,7 @@
 {
 	struct sctp_bind_addr *bp;
 	rwlock_t *addr_lock;
-	struct sockaddr_storage_list *laddr;
+	struct sctp_sockaddr_entry *laddr;
 	struct list_head *pos;
 	sctp_scope_t scope;
 	union sctp_addr *baddr = NULL;
@@ -277,7 +277,7 @@
 	 */
 	sctp_read_lock(addr_lock);
 	list_for_each(pos, &bp->address_list) {
-		laddr = list_entry(pos, struct sockaddr_storage_list, list);
+		laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		if ((laddr->a.sa.sa_family == AF_INET6) &&
 		    (scope <= sctp_scope(&laddr->a))) {
 			bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
@@ -309,7 +309,7 @@
 {
 	struct inet6_dev *in6_dev;
 	struct inet6_ifaddr *ifp;
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 
 	read_lock(&addrconf_lock);
 	if ((in6_dev = __in6_dev_get(dev)) == NULL) {
@@ -320,7 +320,7 @@
 	read_lock(&in6_dev->lock);
 	for (ifp = in6_dev->addr_list; ifp; ifp = ifp->if_next) {
 		/* Add the address to the local list.  */
-		addr = t_new(struct sockaddr_storage_list, GFP_ATOMIC);
+		addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC);
 		if (addr) {
 			addr->a.v6.sin6_family = AF_INET6;
 			addr->a.v6.sin6_port = 0;
diff -urN linux-2.5.73-bk5/net/sctp/outqueue.c linux-2.5.73-bk6/net/sctp/outqueue.c
--- linux-2.5.73-bk5/net/sctp/outqueue.c	2003-06-22 11:32:39.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/outqueue.c	2003-06-28 04:53:21.000000000 -0700
@@ -1012,7 +1012,7 @@
 	__u32 sack_ctsn, ctsn, tsn;
 	__u32 highest_tsn, highest_new_tsn;
 	__u32 sack_a_rwnd;
-	int outstanding;
+	unsigned outstanding;
 	struct sctp_transport *primary = asoc->peer.primary_path;
 	int count_of_newacks = 0;
 
diff -urN linux-2.5.73-bk5/net/sctp/proc.c linux-2.5.73-bk6/net/sctp/proc.c
--- linux-2.5.73-bk5/net/sctp/proc.c	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/proc.c	2003-06-28 04:53:21.000000000 -0700
@@ -133,12 +133,12 @@
 static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb)
 {
 	struct list_head *pos;
-	struct sockaddr_storage_list *laddr;
+	struct sctp_sockaddr_entry *laddr;
 	union sctp_addr *addr;
 	struct sctp_af *af;
 
 	list_for_each(pos, &epb->bind_addr.address_list) {
-		laddr = list_entry(pos, struct sockaddr_storage_list, list);
+		laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		addr = (union sctp_addr *)&laddr->a;
 		af = sctp_get_af_specific(addr->sa.sa_family);
 		af->seq_dump_addr(seq, addr);
diff -urN linux-2.5.73-bk5/net/sctp/protocol.c linux-2.5.73-bk6/net/sctp/protocol.c
--- linux-2.5.73-bk5/net/sctp/protocol.c	2003-06-22 11:32:56.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/protocol.c	2003-06-28 04:53:21.000000000 -0700
@@ -143,7 +143,7 @@
 {
 	struct in_device *in_dev;
 	struct in_ifaddr *ifa;
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 
 	read_lock(&inetdev_lock);
 	if ((in_dev = __in_dev_get(dev)) == NULL) {
@@ -154,7 +154,7 @@
 	read_lock(&in_dev->lock);
 	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
 		/* Add the address to the local list.  */
-		addr = t_new(struct sockaddr_storage_list, GFP_ATOMIC);
+		addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC);
 		if (addr) {
 			addr->a.v4.sin_family = AF_INET;
 			addr->a.v4.sin_port = 0;
@@ -198,11 +198,11 @@
 /* Free the existing local addresses.  */
 static void __sctp_free_local_addr_list(void)
 {
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 	struct list_head *pos, *temp;
 
 	list_for_each_safe(pos, temp, &sctp_local_addr_list) {
-		addr = list_entry(pos, struct sockaddr_storage_list, list);
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		list_del(pos);
 		kfree(addr);
 	}
@@ -222,14 +222,14 @@
 int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
 			      int gfp, int copy_flags)
 {
-	struct sockaddr_storage_list *addr;
+	struct sctp_sockaddr_entry *addr;
 	int error = 0;
 	struct list_head *pos;
 	unsigned long flags;
 
 	sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
 	list_for_each(pos, &sctp_local_addr_list) {
-		addr = list_entry(pos, struct sockaddr_storage_list, list);
+		addr = list_entry(pos, struct sctp_sockaddr_entry, 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
@@ -412,7 +412,7 @@
 	struct flowi fl;
 	struct sctp_bind_addr *bp;
 	rwlock_t *addr_lock;
-	struct sockaddr_storage_list *laddr;
+	struct sctp_sockaddr_entry *laddr;
 	struct list_head *pos;
 	struct dst_entry *dst = NULL;
 	union sctp_addr dst_saddr;
@@ -447,7 +447,7 @@
 		 */
 		sctp_read_lock(addr_lock);
 		list_for_each(pos, &bp->address_list) {
-			laddr = list_entry(pos, struct sockaddr_storage_list,
+			laddr = list_entry(pos, struct sctp_sockaddr_entry,
 					   list);
 			sctp_v4_dst_saddr(&dst_saddr, dst, bp->port);
 			if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
@@ -467,7 +467,7 @@
 	 */
 	sctp_read_lock(addr_lock);
 	list_for_each(pos, &bp->address_list) {
-		laddr = list_entry(pos, struct sockaddr_storage_list, list);
+		laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
 
 		if (AF_INET == laddr->a.sa.sa_family) {
 			fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
diff -urN linux-2.5.73-bk5/net/sctp/sla1.c linux-2.5.73-bk6/net/sctp/sla1.c
--- linux-2.5.73-bk5/net/sctp/sla1.c	2003-06-22 11:32:44.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/sla1.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,281 +0,0 @@
-/* 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
- * 
- * (It's really SHA-1 but Hey I was tired when I created this 
- * file, and on a plane to France :-)
- * 
- * 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 
- * 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.  
- * 
- * 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: 
- *    Randall Stewart <rstewar1@email.mot.com>
- *    kmorneau@cisco.com
- *    qxie1@email.mot.com
- *
- * Based on:
- *    Randy Stewart, et al. SCTP Reference Implementation which is licenced
- *    under the GPL. 
- * 
- * Any bugs reported given to us we will try to fix... any fixes shared will
- * be incorporated into the next SCTP release.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <asm/string.h>		/* for memcpy */
-#include <linux/sched.h>	/* dead chicken for in.h */
-#include <linux/in.h>		/* for htonl and ntohl */
-
-#include <net/sctp/sla1.h>
-
-void SLA1_Init(struct SLA_1_Context *ctx)
-{
-	/* Init the SLA-1 context structure.  */
-	ctx->A = 0;
-	ctx->B = 0;
-	ctx->C = 0;
-	ctx->D = 0;
-	ctx->E = 0;
-	ctx->H0 = H0INIT;
-	ctx->H1 = H1INIT;
-	ctx->H2 = H2INIT;
-	ctx->H3 = H3INIT;
-	ctx->H4 = H4INIT;
-	ctx->TEMP = 0;
-	memset(ctx->words, 0, sizeof(ctx->words));
-	ctx->howManyInBlock = 0;
-	ctx->runningTotal = 0;
-}
-
-void SLA1processABlock(struct SLA_1_Context *ctx,unsigned int *block)
-{
-	int i;
-	/* init the W0-W15 to the block of words being
-	 * hashed.
-	 */
-	/* step a) */
-
-	for (i = 0; i < 16; i++)
-		ctx->words[i] = ntohl(block[i]);
-
-	/* now init the rest based on the SLA-1 formula, step b) */
-	for (i = 16; i < 80; i++)
-		ctx->words[i] =
-			CSHIFT(1, ((ctx->words[(i-3)]) ^
-				   (ctx->words[(i-8)]) ^
-				   (ctx->words[(i-14)]) ^
-				   (ctx->words[(i-16)])));
-
-	/* step c) */
-	ctx->A = ctx->H0;
-	ctx->B = ctx->H1;
-	ctx->C = ctx->H2;
-	ctx->D = ctx->H3;
-	ctx->E = ctx->H4;
-
-	/* step d) */
-	for (i = 0; i < 80; i++) {
-		if (i < 20) {
-			ctx->TEMP = ((CSHIFT(5, ctx->A)) +
-				     (F1(ctx->B, ctx->C, ctx->D)) +
-				     (ctx->E) +
-				     ctx->words[i] +
-				     K1
-				);
-		} else if (i < 40) {
-			ctx->TEMP = ((CSHIFT(5, ctx->A)) +
-				     (F2(ctx->B, ctx->C, ctx->D)) +
-				     (ctx->E) +
-				     (ctx->words[i]) +
-				     K2
-				);
-		} else if (i < 60) {
-			ctx->TEMP = ((CSHIFT(5, ctx->A)) +
-				     (F3(ctx->B, ctx->C, ctx->D)) +
-				     (ctx->E) +
-				     (ctx->words[i]) +
-				     K3
-				);
-		} else {
-			ctx->TEMP = ((CSHIFT(5, ctx->A)) +
-				     (F4(ctx->B, ctx->C, ctx->D)) +
-				     (ctx->E) +
-				     (ctx->words[i]) +
-				     K4
-				);
-		}
-		ctx->E = ctx->D;
-		ctx->D = ctx->C;
-		ctx->C = CSHIFT(30, ctx->B);
-		ctx->B = ctx->A;
-		ctx->A = ctx->TEMP;
-	}
-
-	/* step e) */
-	ctx->H0 = (ctx->H0) + (ctx->A);
-	ctx->H1 = (ctx->H1) + (ctx->B);
-	ctx->H2 = (ctx->H2) + (ctx->C);
-	ctx->H3 = (ctx->H3) + (ctx->D);
-	ctx->H4 = (ctx->H4) + (ctx->E);
-}
-
-void SLA1_Process(struct SLA_1_Context *ctx, const unsigned char *ptr, int siz)
-{
-	int numberLeft, leftToFill;
-
-	numberLeft = siz;
-	while (numberLeft > 0) {
-		leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock;
-		if (leftToFill > numberLeft) {
-			/* can only partially fill up this one */
-			memcpy(&ctx->SLAblock[ctx->howManyInBlock],
-			       ptr, numberLeft);
-			ctx->howManyInBlock += siz;
-			ctx->runningTotal += siz;
-			break;
-		} else {
-			/* block is now full, process it */
-			memcpy(&ctx->SLAblock[ctx->howManyInBlock],
-			       ptr, leftToFill);
-			SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
-			numberLeft -= leftToFill;
-			ctx->runningTotal += leftToFill;
-			ctx->howManyInBlock = 0;
-		}
-	}
-}
-
-void SLA1_Final(struct SLA_1_Context *ctx, unsigned char *digestBuf)
-{
-	/* if any left in block fill with padding
-	 * and process. Then transfer the digest to
-	 * the pointer. At the last block some special
-	 * rules need to apply. We must add a 1 bit
-	 * following the message, then we pad with
-	 * 0's. The total size is encoded as a 64 bit
-	 * number at the end. Now if the last buffer has
-	 * more than 55 octets in it we cannot fit
-	 * the 64 bit number + 10000000 pad on the end
-	 * and must add the 10000000 pad, pad the rest
-	 * of the message with 0's and then create a
-	 * all 0 message with just the 64 bit size
-	 * at the end and run this block through by itself.
-	 * Also the 64 bit int must be in network byte
-	 * order.
-	 */
-	int i, leftToFill;
-	unsigned int *ptr;
-
-	if (ctx->howManyInBlock > 55) {
-		/* special case, we need to process two
-		 * blocks here. One for the current stuff
-		 * plus possibly the pad. The other for
-		 * the size.
-		 */
-		leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock;
-		if (leftToFill == 0) {
-			/* Should not really happen but I am paranoid */
-			/* Not paranoid enough!  It is possible for leftToFill
-			 * to become negative!  AAA!!!!  This is another reason
-			 * to pick MD5 :-)...
-			 */
-			SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
-			/* init last block, a bit different then the rest :-) */
-			ctx->SLAblock[0] = 0x80;
-			for (i = 1; i < sizeof(ctx->SLAblock); i++) {
-				ctx->SLAblock[i] = 0x0;
-			}
-		} else if (leftToFill == 1) {
-			ctx->SLAblock[ctx->howManyInBlock] = 0x80;
-			SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
-			/* init last block */
-			memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock));
-		} else {
-			ctx->SLAblock[ctx->howManyInBlock] = 0x80;
-			for (i = (ctx->howManyInBlock + 1);
-			     i < sizeof(ctx->SLAblock);
-			     i++) {
-				ctx->SLAblock[i] = 0x0;
-			}
-			SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
-			/* init last block */
-			memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock));
-		}
-		/* This is in bits so multiply by 8 */
-		ctx->runningTotal *= 8;
-		ptr = (unsigned int *) &ctx->SLAblock[60];
-		*ptr = htonl(ctx->runningTotal);
-		SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
-	} else {
-		/* easy case, we just pad this
-		 * message to size - end with 0
-		 * add the magic 0x80 to the next
-		 * word and then put the network byte
-		 * order size in the last spot and
-		 * process the block.
-		 */
-		ctx->SLAblock[ctx->howManyInBlock] = 0x80;
-		for (i = (ctx->howManyInBlock + 1);
-		     i < sizeof(ctx->SLAblock);
-		     i++) {
-			ctx->SLAblock[i] = 0x0;
-		}
-		/* get last int spot */
-		ctx->runningTotal *= 8;
-		ptr = (unsigned int *) &ctx->SLAblock[60];
-		*ptr = htonl(ctx->runningTotal);
-		SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
-	}
-	/* Now at this point all we need do is transfer the
-	 * digest back to the user
-	 */
-	digestBuf[3] = (ctx->H0 & 0xff);
-	digestBuf[2] = ((ctx->H0 >> 8) & 0xff);
-	digestBuf[1] = ((ctx->H0 >> 16) & 0xff);
-	digestBuf[0] = ((ctx->H0 >> 24) & 0xff);
-
-	digestBuf[7] = (ctx->H1 & 0xff);
-	digestBuf[6] = ((ctx->H1 >> 8) & 0xff);
-	digestBuf[5] = ((ctx->H1 >> 16) & 0xff);
-	digestBuf[4] = ((ctx->H1 >> 24) & 0xff);
-
-	digestBuf[11] = (ctx->H2 & 0xff);
-	digestBuf[10] = ((ctx->H2 >> 8) & 0xff);
-	digestBuf[9] = ((ctx->H2 >> 16) & 0xff);
-	digestBuf[8] = ((ctx->H2 >> 24) & 0xff);
-
-	digestBuf[15] = (ctx->H3 & 0xff);
-	digestBuf[14] = ((ctx->H3 >> 8) & 0xff);
-	digestBuf[13] = ((ctx->H3 >> 16) & 0xff);
-	digestBuf[12] = ((ctx->H3 >> 24) & 0xff);
-
-	digestBuf[19] = (ctx->H4 & 0xff);
-	digestBuf[18] = ((ctx->H4 >> 8) & 0xff);
-	digestBuf[17] = ((ctx->H4 >> 16) & 0xff);
-	digestBuf[16] = ((ctx->H4 >> 24) & 0xff);
-}
diff -urN linux-2.5.73-bk5/net/sctp/sm_make_chunk.c linux-2.5.73-bk6/net/sctp/sm_make_chunk.c
--- linux-2.5.73-bk5/net/sctp/sm_make_chunk.c	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/sm_make_chunk.c	2003-06-28 04:53:21.000000000 -0700
@@ -589,27 +589,17 @@
 struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
 {
 	struct sctp_chunk *retval;
-	sctp_sackhdr_t sack;
-	sctp_gap_ack_block_t gab;
-	int length;
+	struct sctp_sackhdr sack;
+	int len;
 	__u32 ctsn;
-	struct sctp_tsnmap_iter iter;
 	__u16 num_gabs, num_dup_tsns;
 	struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
 
 	ctsn = sctp_tsnmap_get_ctsn(map);
-	SCTP_DEBUG_PRINTK("sackCTSNAck sent is 0x%x.\n", ctsn);
-
-	/* Count the number of Gap Ack Blocks.  */
-	num_gabs = 0;
-
-	if (sctp_tsnmap_has_gap(map)) {
-		sctp_tsnmap_iter_init(map, &iter);
-		while (sctp_tsnmap_next_gap_ack(map, &iter,
-						&gab.start, &gab.end))
-			num_gabs++;
-	}
+	SCTP_DEBUG_PRINTK("sackCTSNAck sent:  0x%x.\n", ctsn);
 
+	/* How much room is needed in the chunk? */
+	num_gabs = sctp_tsnmap_num_gabs(map);
 	num_dup_tsns = sctp_tsnmap_num_dups(map);
 
 	/* Initialize the SACK header.  */
@@ -618,12 +608,12 @@
 	sack.num_gap_ack_blocks     = htons(num_gabs);
 	sack.num_dup_tsns           = htons(num_dup_tsns);
 
-	length = sizeof(sack)
-		+ sizeof(sctp_gap_ack_block_t) * num_gabs
+	len = sizeof(sack)
+		+ sizeof(struct sctp_gap_ack_block) * num_gabs
 		+ sizeof(__u32) * num_dup_tsns;
 
 	/* Create the chunk.  */
-	retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, length);
+	retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, len);
 	if (!retval)
 		goto nodata;
 
@@ -662,21 +652,15 @@
 	retval->subh.sack_hdr =
 		sctp_addto_chunk(retval, sizeof(sack), &sack);
 
-	/* Put the Gap Ack Blocks into the chunk.  */
-	if (num_gabs) {
-		sctp_tsnmap_iter_init(map, &iter);
-		while(sctp_tsnmap_next_gap_ack(map, &iter,
-					       &gab.start, &gab.end)) {
-			gab.start = htons(gab.start);
-			gab.end = htons(gab.end);
-			sctp_addto_chunk(retval, sizeof(sctp_gap_ack_block_t),
-					 &gab);
-		}
-	}
-
-	/* Register the duplicates.  */
-	sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns,
-			 sctp_tsnmap_get_dups(map));
+	/* Add the gap ack block information.   */
+	if (num_gabs)
+		sctp_addto_chunk(retval, sizeof(__u32) * num_gabs,
+				 sctp_tsnmap_get_gabs(map));
+
+	/* Add the duplicate TSN information.  */
+	if (num_dup_tsns)
+		sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns,
+				 sctp_tsnmap_get_dups(map));
 
 nodata:
 	return retval;
@@ -1275,14 +1259,14 @@
 				      const __u8 *raw_addrs, int addrs_len)
 {
 	sctp_cookie_param_t *retval;
-	sctp_signed_cookie_t *cookie;
+	struct sctp_signed_cookie *cookie;
 	struct scatterlist sg;
 	int headersize, bodysize;
 	unsigned int keylen;
 	char *key;
 
 	headersize = sizeof(sctp_paramhdr_t) + SCTP_SECRET_SIZE;
-	bodysize = sizeof(sctp_cookie_t)
+	bodysize = sizeof(struct sctp_cookie)
 		+ ntohs(init_chunk->chunk_hdr->length) + addrs_len;
 
 	/* Pad out the cookie to a multiple to make the signature
@@ -1304,7 +1288,7 @@
 	 * out on the network.
 	 */
 	memset(retval, 0x00, *cookie_len);
-	cookie = (sctp_signed_cookie_t *) retval->body;
+	cookie = (struct sctp_signed_cookie *) retval->body;
 
 	/* Set up the parameter header.  */
 	retval->p.type = SCTP_PARAM_STATE_COOKIE;
@@ -1351,26 +1335,26 @@
 	int *error, struct sctp_chunk **errp)
 {
 	struct sctp_association *retval = NULL;
-	sctp_signed_cookie_t *cookie;
-	sctp_cookie_t *bear_cookie;
+	struct sctp_signed_cookie *cookie;
+	struct sctp_cookie *bear_cookie;
 	int headersize, bodysize, fixed_size;
 	__u8 digest[SCTP_SIGNATURE_SIZE];
 	struct scatterlist sg;
-	unsigned int keylen;
+	unsigned int keylen, len;
 	char *key;
 	sctp_scope_t scope;
 	struct sk_buff *skb = chunk->skb;
 
 	headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE;
 	bodysize = ntohs(chunk->chunk_hdr->length) - headersize;
-	fixed_size = headersize + sizeof(sctp_cookie_t);
+	fixed_size = headersize + sizeof(struct sctp_cookie);
 
 	/* Verify that the chunk looks like it even has a cookie.
 	 * There must be enough room for our cookie and our peer's
 	 * INIT chunk.
 	 */
-	if (ntohs(chunk->chunk_hdr->length) <
-	    (fixed_size + sizeof(sctp_chunkhdr_t)))
+	len = ntohs(chunk->chunk_hdr->length);
+	if (len < fixed_size + sizeof(struct sctp_chunkhdr))
 		goto malformed;
 
 	/* Verify that the cookie has been padded out. */
@@ -1454,7 +1438,7 @@
 	retval->peer.port = ntohs(chunk->sctp_hdr->source);
 
 	/* Populate the association from the cookie.  */
-	retval->c = *bear_cookie;
+	memcpy(&retval->c, bear_cookie, sizeof(*bear_cookie));
 
 	if (sctp_assoc_set_bind_addr_from_cookie(retval, bear_cookie,
 						 GFP_ATOMIC) < 0) {
@@ -2022,7 +2006,7 @@
  ********************************************************************/
 
 /* Convert from an SCTP IP parameter to a union sctp_addr.  */
-void sctp_param2sockaddr(union sctp_addr *addr, sctp_addr_param_t *param,
+void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *param,
 			 __u16 port, int iif)
 {
 	switch(param->v4.param_hdr.type) {
@@ -2073,7 +2057,7 @@
 /* Convert a sockaddr_in to an IP address in an SCTP param.
  * Returns len if a valid conversion was possible.
  */
-int sockaddr2sctp_addr(const union sctp_addr *sa, sctp_addr_param_t *p)
+int sockaddr2sctp_addr(const union sctp_addr *sa, union sctp_addr_param *p)
 {
 	int len = 0;
 
diff -urN linux-2.5.73-bk5/net/sctp/sm_sideeffect.c linux-2.5.73-bk6/net/sctp/sm_sideeffect.c
--- linux-2.5.73-bk5/net/sctp/sm_sideeffect.c	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/sm_sideeffect.c	2003-06-28 04:53:21.000000000 -0700
@@ -608,13 +608,13 @@
 }
 
 /* Helper function to change the state of an association. */
-static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, struct sctp_association *asoc,
+static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, 
+			       struct sctp_association *asoc,
 			       sctp_state_t state)
 {
 	struct sock *sk = asoc->base.sk;
 
 	asoc->state = state;
-	asoc->state_timestamp = jiffies;
 
 	if (sctp_style(sk, TCP)) {
 		/* Change the sk->sk_state of a TCP-style socket that has 
@@ -702,7 +702,7 @@
 	       int gfp)
 {
 	sctp_cmd_seq_t commands;
-	sctp_sm_table_entry_t *state_fn;
+	const sctp_sm_table_entry_t *state_fn;
 	sctp_disposition_t status;
 	int error = 0;
 	typedef const char *(printfn_t)(sctp_subtype_t);
diff -urN linux-2.5.73-bk5/net/sctp/sm_statefuns.c linux-2.5.73-bk6/net/sctp/sm_statefuns.c
--- linux-2.5.73-bk5/net/sctp/sm_statefuns.c	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/sm_statefuns.c	2003-06-28 04:53:21.000000000 -0700
@@ -45,6 +45,7 @@
  *    Dajiang Zhang 	    <dajiang.zhang@nokia.com>
  *    Daisy Chang	    <daisyc@us.ibm.com>
  *    Ardelle Fan	    <ardelle.fan@intel.com>
+ *    Ryan Layer	    <rmlayer@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.
@@ -537,7 +538,7 @@
 	 * are in good shape.
 	 */
         chunk->subh.cookie_hdr =
-		(sctp_signed_cookie_t *)chunk->skb->data;
+		(struct sctp_signed_cookie *)chunk->skb->data;
 	skb_pull(chunk->skb,
 		 ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
 
@@ -738,7 +739,7 @@
 {
 	struct sctp_transport *transport = (struct sctp_transport *) arg;
 
-	if (asoc->overall_error_count > asoc->overall_error_threshold) {
+	if (asoc->overall_error_count > asoc->max_retrans) {
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
 				SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -924,16 +925,16 @@
 {
 	int len;
 	struct sctp_packet *pkt;
-	sctp_addr_param_t *addrparm;
-	sctp_errhdr_t *errhdr;
+	union sctp_addr_param *addrparm;
+	struct sctp_errhdr *errhdr;
 	struct sctp_endpoint *ep;
-	char buffer[sizeof(sctp_errhdr_t) + sizeof(sctp_addr_param_t)];
+	char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)];
 
 	/* Build the error on the stack.   We are way to malloc crazy
 	 * throughout the code today.
 	 */
-	errhdr = (sctp_errhdr_t *)buffer;
-	addrparm = (sctp_addr_param_t *)errhdr->variable;
+	errhdr = (struct sctp_errhdr *)buffer;
+	addrparm = (union sctp_addr_param *)errhdr->variable;
 
 	/* Copy into a parm format. */
 	len = sockaddr2sctp_addr(ssa, addrparm);
@@ -1618,7 +1619,7 @@
 	/* "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;
+        chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
 	skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
 		 sizeof(sctp_chunkhdr_t));
 
@@ -1866,7 +1867,7 @@
 	 * yield a higher probability of success on the reattempt.
 	 */
 	stale = ntohl(*(suseconds_t *)((u8 *)err + sizeof(sctp_errhdr_t)));
-	stale = stale << 1 / 1000;
+	stale = (stale * 2) / 1000;
 
 	bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE;
 	bht.param_hdr.length = htons(sizeof(bht));
@@ -1947,22 +1948,23 @@
 					sctp_cmd_seq_t *commands)
 {
 	struct sctp_chunk *chunk = arg;
+	unsigned len;
 	__u16 error = SCTP_ERROR_NO_ERROR;
 
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-	if (chunk && (ntohs(chunk->chunk_hdr->length) >=
-			(sizeof(struct sctp_chunkhdr) +
-			sizeof(struct sctp_errhdr))))
+	/* Check that chunk header looks valid.  */
+	len = ntohs(chunk->chunk_hdr->length);
+	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
 		error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
+
  	/* ASSOC_FAILED will DELETE_TCB. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
 	SCTP_INC_STATS(SctpAborteds);
 	SCTP_DEC_STATS(SctpCurrEstab);
 
-	/* BUG?  This does not look complete... */
 	return SCTP_DISPOSITION_ABORT;
 }
 
@@ -1978,6 +1980,7 @@
 				     sctp_cmd_seq_t *commands)
 {
 	struct sctp_chunk *chunk = arg;
+	unsigned len;
 	__u16 error = SCTP_ERROR_NO_ERROR;
 
 	if (!sctp_vtag_verify_either(chunk, asoc))
@@ -1989,9 +1992,9 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
 
-	if (chunk && (ntohs(chunk->chunk_hdr->length) >=
-			(sizeof(struct sctp_chunkhdr) +
-			sizeof(struct sctp_errhdr))))
+	/* Check that chunk header looks valid.  */
+	len = ntohs(chunk->chunk_hdr->length);
+	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
 		error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
 	/* CMD_INIT_FAILED will DELETE_TCB. */
@@ -3201,82 +3204,6 @@
 	return SCTP_DISPOSITION_CONSUME;
 }
 
-#if 0
-/*
- * We did something stupid but got lucky.  Namely, we sent a HEARTBEAT
- * before the association was all the way up and we did NOT get an
- * ABORT.
- *
- * Log the fact and then process normally.
- *
- * Section: Not specified
- * Verification Tag:  8.5 Verification Tag [Normal verification]
- * Inputs
- * (endpoint, asoc, chunk)
- *
- * Outputs
- * (asoc, reply_msg, msg_up, timers, counters)
- *
- * The return value is the disposition of the chunk.
- */
-sctp_disposition_t lucky(const struct sctp_endpoint *ep,
-			 const struct sctp_association *asoc,
-			 const sctp_subtype_t type,
-			 void *arg,
-			 sctp_cmd_seq_t *commands)
-{
-	struct sctp_chunk *chunk = arg;
-
-	/* 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 (chunk->sctp_hdr->vtag != asoc->c.my_vtag)
-		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
-	return SCTP_DISPOSITION_CONSUME;
-
-nomem:
-	return SCTP_DISPOSITION_NOMEM;
-}
-#endif /* 0 */
-
-#if 0
-/*
- * The other end is doing something very stupid.  We'll ignore them
- * after logging their idiocy. :-)
- *
- * Section: Not specified
- * Verification Tag:  8.5 Verification Tag [Normal verification]
- * Inputs
- * (endpoint, asoc, chunk)
- *
- * Outputs
- * (asoc, reply_msg, msg_up, timers, counters)
- *
- * The return value is the disposition of the chunk.
- */
-sctp_disposition_t other_stupid(const struct sctp_endpoint *ep,
-				const struct sctp_association *asoc,
-				const sctp_subtype_t type,
-				void *arg,
-				sctp_cmd_seq_t *commands)
-{
-	struct sctp_chunk *chunk = arg;
-
-	/* 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 (chunk->sctp_hdr->vtag != asoc->c.my_vtag)
-		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
-	return SCTP_DISPOSITION_CONSUME;
-
-nomem:
-	return SCTP_DISPOSITION_NOMEM;
-}
-#endif /* 0 */
 
 /*
  * The other end is violating protocol.
@@ -4070,7 +3997,7 @@
 {
 	struct sctp_transport *transport = arg;
 
-	if (asoc->overall_error_count >= asoc->overall_error_threshold) {
+	if (asoc->overall_error_count >= asoc->max_retrans) {
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
 				SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4241,7 +4168,7 @@
 	struct sctp_chunk *reply = NULL;
 
 	SCTP_DEBUG_PRINTK("Timer T2 expired.\n");
-	if (asoc->overall_error_count >= asoc->overall_error_threshold) {
+	if (asoc->overall_error_count >= asoc->max_retrans) {
 		/* Note:  CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
 				SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4500,13 +4427,21 @@
 	if (asoc) {
 		vtag = asoc->peer.i.init_tag;
 	} else {
-		/* Special case the INIT as there is no vtag yet. */
-		if (SCTP_CID_INIT == chunk->chunk_hdr->type) {
+		/* Special case the INIT and stale COOKIE_ECHO as there is no
+		 * vtag yet.
+		 */
+		switch(chunk->chunk_hdr->type) {
+		case SCTP_CID_INIT:
+		{
 			sctp_init_chunk_t *init;
+
 			init = (sctp_init_chunk_t *)chunk->chunk_hdr;
 			vtag = ntohl(init->init_hdr.init_tag);
-		} else {
+			break;
+		}
+		default:	
 			vtag = ntohl(chunk->sctp_hdr->vtag);
+			break;
 		}
 	}
 
@@ -4557,6 +4492,12 @@
 	if (err_chunk) {
 		packet = sctp_ootb_pkt_new(asoc, chunk);
 		if (packet) {
+			struct sctp_signed_cookie *cookie;
+
+			/* Override the OOTB vtag from the cookie. */
+			cookie = chunk->subh.cookie_hdr;
+			packet->vtag = cookie->c.peer_vtag;
+			
 			/* Set the skb to the belonging sock for accounting. */
 			err_chunk->skb->sk = ep->base.sk;
 			sctp_packet_append_chunk(packet, err_chunk);
diff -urN linux-2.5.73-bk5/net/sctp/sm_statetable.c linux-2.5.73-bk6/net/sctp/sm_statetable.c
--- linux-2.5.73-bk5/net/sctp/sm_statetable.c	2003-06-22 11:33:33.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/sm_statetable.c	2003-06-28 04:53:21.000000000 -0700
@@ -49,7 +49,7 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-static sctp_sm_table_entry_t bug = {
+static const sctp_sm_table_entry_t bug = {
 	.fn = sctp_sf_bug, 
 	.name = "sctp_sf_bug"
 };
@@ -64,9 +64,9 @@
 	} \
 	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,
-					    sctp_subtype_t event_subtype)
+const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
+						  sctp_state_t state,
+						  sctp_subtype_t event_subtype)
 {
 	switch (event_type) {
 	case SCTP_EVENT_T_CHUNK:
@@ -418,7 +418,7 @@
  *
  * For base protocol (RFC 2960).
  */
-sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_DATA,
 	TYPE_SCTP_INIT,
 	TYPE_SCTP_INIT_ACK,
@@ -437,7 +437,7 @@
 }; /* state_fn_t chunk_event_table[][] */
 
 
-static sctp_sm_table_entry_t
+static const sctp_sm_table_entry_t
 chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
 	/* SCTP_STATE_EMPTY */
 	{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"},
@@ -586,7 +586,7 @@
 /* The primary index for this table is the primitive type.
  * The secondary index for this table is the state.
  */
-sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
+const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_PRIMITIVE_ASSOCIATE,
 	TYPE_SCTP_PRIMITIVE_SHUTDOWN,
 	TYPE_SCTP_PRIMITIVE_ABORT,
@@ -617,7 +617,7 @@
 	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 }
 
-sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
+const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_OTHER_NO_PENDING_TSN,
 };
 
@@ -811,7 +811,7 @@
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
-sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
+const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_EVENT_TIMEOUT_NONE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_INIT,
@@ -823,7 +823,8 @@
 	TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
 };
 
-sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t state)
+const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, 
+						     sctp_state_t state)
 {
 	if (state > SCTP_STATE_MAX)
 		return &bug;
diff -urN linux-2.5.73-bk5/net/sctp/socket.c linux-2.5.73-bk6/net/sctp/socket.c
--- linux-2.5.73-bk5/net/sctp/socket.c	2003-06-22 11:33:37.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/socket.c	2003-06-28 04:53:21.000000000 -0700
@@ -48,6 +48,8 @@
  *    Sridhar Samudrala     <samudrala@us.ibm.com>
  *    Inaky Perez-Gonzalez  <inaky.gonzalez@intel.com>
  *    Ardelle Fan	    <ardelle.fan@intel.com>
+ *    Ryan Layer	    <rmlayer@us.ibm.com>
+ *    Anup Pemmaiah         <pemmaiah@cc.usu.edu>
  *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -100,6 +102,7 @@
 static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
 
 extern kmem_cache_t *sctp_bucket_cachep;
+extern int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc);
 
 /* Look up the association by its id.  If this is not a UDP-style
  * socket, the ID field is always ignored.
@@ -110,32 +113,24 @@
 
 	/* If this is not a UDP-style socket, assoc id should be ignored. */
 	if (!sctp_style(sk, UDP)) {
-		/* Return NULL if the socket state is not ESTABLISHED. It 
+		/* Return NULL if the socket state is not ESTABLISHED. It
 		 * could be a TCP-style listening socket or a socket which
 		 * hasn't yet called connect() to establish an association.
 		 */
 		if (!sctp_sstate(sk, ESTABLISHED))
 			return NULL;
 
-		/* Get the first and the only association from the list. */ 
+		/* Get the first and the only association from the list. */
 		if (!list_empty(&sctp_sk(sk)->ep->asocs))
 			asoc = list_entry(sctp_sk(sk)->ep->asocs.next,
 					  struct sctp_association, asocs);
 		return asoc;
 	}
 
-	/* First, verify that this is a kernel address. */
-	if (sctp_is_valid_kaddr((unsigned long) id)) {
-		struct sctp_association *temp;
-
-		/* Verify that this _is_ an sctp_association
-		 * data structure and if so, that the socket matches.
-		 */
-		temp = (struct sctp_association *)id;
-		if ((SCTP_ASSOC_EYECATCHER == temp->eyecatcher) &&
-		    (temp->base.sk == sk))
-			asoc = temp;
-	}
+	/* Otherwise this is a UDP-style socket. */
+	asoc = (struct sctp_association *)id;
+	if (!sctp_assoc_valid(sk, asoc))
+		return NULL;
 
 	return asoc;
 }
@@ -1456,7 +1451,7 @@
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
  *                     considered unreachable.
- */ 
+ */
 static int sctp_setsockopt_peer_addr_params(struct sock *sk,
 					    char *optval, int optlen)
 {
@@ -1625,6 +1620,110 @@
 }
 
 /*
+ *
+ * 7.1.1 SCTP_RTOINFO
+ *
+ * The protocol parameters used to initialize and bound retransmission
+ * timeout (RTO) are tunable. sctp_rtoinfo structure is used to access
+ * and modify these parameters.
+ * All parameters are time values, in milliseconds.  A value of 0, when
+ * modifying the parameters, indicates that the current value should not
+ * be changed.
+ *
+ */
+static int sctp_setsockopt_rtoinfo(struct sock *sk, char *optval, int optlen) {
+	struct sctp_rtoinfo rtoinfo;
+	struct sctp_association *asoc;
+
+	if (optlen != sizeof (struct sctp_rtoinfo))
+		return -EINVAL;
+
+	if (copy_from_user(&rtoinfo, optval, optlen))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id);
+
+	/* Set the values to the specific association */
+	if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	if (asoc) {
+		if (rtoinfo.srto_initial != 0)
+			asoc->rto_initial = rtoinfo.srto_initial * HZ / 1000;
+		if (rtoinfo.srto_max != 0)
+			asoc->rto_max = rtoinfo.srto_max * HZ / 1000;
+		if (rtoinfo.srto_min != 0)
+			asoc->rto_min = rtoinfo.srto_min * HZ / 1000;
+	} else {
+		/* If there is no association or the association-id = 0
+		 * set the values to the endpoint.
+		 */
+		struct sctp_opt *sp = sctp_sk(sk);
+
+		if (rtoinfo.srto_initial != 0)
+			sp->rtoinfo.srto_initial = rtoinfo.srto_initial;
+		if (rtoinfo.srto_max != 0)
+			sp->rtoinfo.srto_max = rtoinfo.srto_max;
+		if (rtoinfo.srto_min != 0)
+			sp->rtoinfo.srto_min = rtoinfo.srto_min;
+	}
+
+	return 0;
+}
+
+/*
+ *
+ * 7.1.2 SCTP_ASSOCINFO
+ *
+ * This option is used to tune the the maximum retransmission attempts
+ * of the association.
+ * Returns an error if the new association retransmission value is
+ * greater than the sum of the retransmission value  of the peer.
+ * See [SCTP] for more information.
+ *
+ */
+static int sctp_setsockopt_assocrtx(struct sock *sk, char *optval,
+				int optlen) {
+
+	struct sctp_assocparams assocparams;
+	struct sctp_association *asoc;
+
+	if (optlen != sizeof(struct sctp_assocparams))
+		return -EINVAL;
+	if (copy_from_user(&assocparams, optval, optlen))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id);
+
+	if (!asoc && assocparams.sasoc_assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	/* Set the values to the specific association */
+	if (asoc) {
+		if (assocparams.sasoc_asocmaxrxt != 0)
+			asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
+		if (assocparams.sasoc_cookie_life != 0) {
+			asoc->cookie_life.tv_sec =
+					assocparams.sasoc_cookie_life / 1000;
+			asoc->cookie_life.tv_usec =
+					(assocparams.sasoc_cookie_life % 1000)
+					* 1000;
+		}
+	} else {
+		/* Set the values to the endpoint */
+		struct sctp_opt *sp = sctp_sk(sk);
+
+		if (assocparams.sasoc_asocmaxrxt != 0)
+			sp->assocparams.sasoc_asocmaxrxt =
+						assocparams.sasoc_asocmaxrxt;
+		if (assocparams.sasoc_cookie_life != 0)
+			sp->assocparams.sasoc_cookie_life =
+						assocparams.sasoc_cookie_life;
+	}
+	return 0;
+}
+
+/*
  * 7.1.16 Set/clear IPv4 mapped addresses (SCTP_I_WANT_MAPPED_V4_ADDR)
  *
  * This socket option is a boolean flag which turns on or off mapped V4
@@ -1771,6 +1870,12 @@
 	case SCTP_NODELAY:
 		retval = sctp_setsockopt_nodelay(sk, optval, optlen);
 		break;
+	case SCTP_RTOINFO:
+		retval = sctp_setsockopt_rtoinfo(sk, optval, optlen);
+		break;
+	case SCTP_ASSOCRTXINFO:
+		retval = sctp_setsockopt_assocrtx(sk, optval, optlen);
+		break;
 	case SCTP_I_WANT_MAPPED_V4_ADDR:
 		retval = sctp_setsockopt_mappedv4(sk, optval, optlen);
 		break;
@@ -2027,15 +2132,25 @@
 	sp->initmsg.sinit_num_ostreams   = sctp_max_outstreams;
 	sp->initmsg.sinit_max_instreams  = sctp_max_instreams;
 	sp->initmsg.sinit_max_attempts   = sctp_max_retrans_init;
-	sp->initmsg.sinit_max_init_timeo = sctp_rto_max / HZ;
+	sp->initmsg.sinit_max_init_timeo = (sctp_rto_max / HZ) * 1000;
 
 	/* Initialize default RTO related parameters.  These parameters can
 	 * be modified for with the SCTP_RTOINFO socket option.
 	 * FIXME: These are not used yet.
 	 */
-	sp->rtoinfo.srto_initial = sctp_rto_initial;
-	sp->rtoinfo.srto_max     = sctp_rto_max;
-	sp->rtoinfo.srto_min     = sctp_rto_min;
+	sp->rtoinfo.srto_initial = (sctp_rto_initial / HZ) * 1000;
+	sp->rtoinfo.srto_max     = (sctp_rto_max / HZ) * 1000;
+	sp->rtoinfo.srto_min     = (sctp_rto_min / HZ) * 1000;
+
+	/* Initialize default association related parameters. These parameters
+	 * can be modified with the SCTP_ASSOCINFO socket option.
+	 */
+	sp->assocparams.sasoc_asocmaxrxt = sctp_max_retrans_association;
+	sp->assocparams.sasoc_number_peer_destinations = 0;
+	sp->assocparams.sasoc_peer_rwnd = 0;
+	sp->assocparams.sasoc_local_rwnd = 0;
+	sp->assocparams.sasoc_cookie_life = (sctp_valid_cookie_life / HZ)
+					* 1000;
 
 	/* Initialize default event subscriptions.
 	 * the struct sock is initialized to zero, so only
@@ -2050,7 +2165,7 @@
 	/* Default Peer Address Parameters.  These defaults can
 	 * be modified via SCTP_SET_PEER_ADDR_PARAMS
 	 */
-	sp->paddrparam.spp_hbinterval = sctp_hb_interval / HZ;
+	sp->paddrparam.spp_hbinterval = (sctp_hb_interval / HZ) * 1000;
 	sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path;
 
 	/* If enabled no SCTP message fragmentation will be performed.
@@ -2182,7 +2297,8 @@
 	status.sstat_state = asoc->state;
 	status.sstat_rwnd =  asoc->peer.rwnd;
 	status.sstat_unackdata = asoc->unack_data;
-	status.sstat_penddata = asoc->peer.tsn_map.pending_data;
+
+	status.sstat_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map);
 	status.sstat_instrms = asoc->c.sinit_max_instreams;
 	status.sstat_outstrms = asoc->c.sinit_num_ostreams;
 	/* Just in time frag_point update. */
@@ -2196,7 +2312,7 @@
 	status.sstat_primary.spinfo_state = transport->active;
 	status.sstat_primary.spinfo_cwnd = transport->cwnd;
 	status.sstat_primary.spinfo_srtt = transport->srtt;
-	status.sstat_primary.spinfo_rto = transport->rto;
+	status.sstat_primary.spinfo_rto = (transport->rto / HZ) * 1000;
 	status.sstat_primary.spinfo_mtu = transport->pmtu;
 
 	if (put_user(len, optlen)) {
@@ -2251,7 +2367,7 @@
 	pinfo.spinfo_state = transport->active;
 	pinfo.spinfo_cwnd = transport->cwnd;
 	pinfo.spinfo_srtt = transport->srtt;
-	pinfo.spinfo_rto = transport->rto;
+	pinfo.spinfo_rto = (transport->rto / HZ) * 1000;
 	pinfo.spinfo_mtu = transport->pmtu;
 
 	if (put_user(len, optlen)) {
@@ -2430,7 +2546,7 @@
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
  *                     considered unreachable.
- */ 
+ */
 static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
 						char *optval, int *optlen)
 {
@@ -2607,7 +2723,7 @@
 	struct list_head *pos;
 	int cnt = 0;
 	struct sctp_getaddrs getaddrs;
-	struct sockaddr_storage_list *from;
+	struct sctp_sockaddr_entry *from;
 	struct sockaddr_storage *to;
 
 	if (len != sizeof(struct sctp_getaddrs))
@@ -2635,7 +2751,7 @@
 	to = getaddrs.addrs;
 	list_for_each(pos, &bp->address_list) {
 		from = list_entry(pos,
-				struct sockaddr_storage_list,
+				struct sctp_sockaddr_entry,
 				list);
 		if (copy_to_user(to, &from->a, sizeof(from->a)))
 			return -EFAULT;
@@ -2763,6 +2879,127 @@
 		return -EFAULT;
 	return 0;
 }
+
+/*
+ *
+ * 7.1.1 SCTP_RTOINFO
+ *
+ * The protocol parameters used to initialize and bound retransmission
+ * timeout (RTO) are tunable. sctp_rtoinfo structure is used to access
+ * and modify these parameters.
+ * All parameters are time values, in milliseconds.  A value of 0, when
+ * modifying the parameters, indicates that the current value should not
+ * be changed.
+ *
+ */
+static int sctp_getsockopt_rtoinfo(struct sock *sk, int len, char *optval,
+				int *optlen) {
+	struct sctp_rtoinfo rtoinfo;
+	struct sctp_association *asoc;
+
+	if (len != sizeof (struct sctp_rtoinfo))
+		return -EINVAL;
+
+	if (copy_from_user(&rtoinfo, optval, sizeof (struct sctp_rtoinfo)))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id);
+
+	if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	/* Values corresponding to the specific association. */
+	if (asoc) {
+		rtoinfo.srto_initial = (asoc->rto_initial / HZ) * 1000;
+		rtoinfo.srto_max = (asoc->rto_max / HZ) * 1000;
+		rtoinfo.srto_min = (asoc->rto_min / HZ) * 1000;
+	} else {
+		/* Values corresponding to the endpoint. */
+		struct sctp_opt *sp = sctp_sk(sk);
+
+		rtoinfo.srto_initial = sp->rtoinfo.srto_initial;
+		rtoinfo.srto_max = sp->rtoinfo.srto_max;
+		rtoinfo.srto_min = sp->rtoinfo.srto_min;
+	}
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+
+	if (copy_to_user(optval, &rtoinfo, len))
+		return -EFAULT;
+
+	return 0;
+}
+
+/*
+ *
+ * 7.1.2 SCTP_ASSOCINFO
+ *
+ * This option is used to tune the the maximum retransmission attempts
+ * of the association.
+ * Returns an error if the new association retransmission value is
+ * greater than the sum of the retransmission value  of the peer.
+ * See [SCTP] for more information.
+ *
+ */
+static int sctp_getsockopt_assocrtx(struct sock *sk, int len, char *optval,
+				int *optlen) {
+
+	struct sctp_assocparams assocparams;
+	struct sctp_association *asoc;
+	struct list_head *pos;
+	int cnt = 0;
+
+	if (len != sizeof (struct sctp_assocparams))
+		return -EINVAL;
+
+	if (copy_from_user(&assocparams, optval,
+			sizeof (struct sctp_assocparams)))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id);
+
+	if (!asoc && assocparams.sasoc_assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	/* Values correspoinding to the specific association */
+	if (assocparams.sasoc_assoc_id != 0) {
+		assocparams.sasoc_asocmaxrxt = asoc->max_retrans;
+		assocparams.sasoc_peer_rwnd = asoc->peer.rwnd;
+		assocparams.sasoc_local_rwnd = asoc->a_rwnd;
+		assocparams.sasoc_cookie_life = (asoc->cookie_life.tv_sec
+						* 1000) +
+						(asoc->cookie_life.tv_usec
+						/ 1000);
+
+		list_for_each(pos, &asoc->peer.transport_addr_list) {
+			cnt ++;
+		}
+
+		assocparams.sasoc_number_peer_destinations = cnt;
+	} else {
+		/* Values corresponding to the endpoint */
+		struct sctp_opt *sp = sctp_sk(sk);
+
+		assocparams.sasoc_asocmaxrxt = sp->assocparams.sasoc_asocmaxrxt;
+		assocparams.sasoc_peer_rwnd = sp->assocparams.sasoc_peer_rwnd;
+		assocparams.sasoc_local_rwnd = sp->assocparams.sasoc_local_rwnd;
+		assocparams.sasoc_cookie_life =
+					sp->assocparams.sasoc_cookie_life;
+		assocparams.sasoc_number_peer_destinations =
+					sp->assocparams.
+					sasoc_number_peer_destinations;
+	}
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+
+	if (copy_to_user(optval, &assocparams, len))
+		return -EFAULT;
+
+	return 0;
+}
+
 /*
  * 7.1.16 Set/clear IPv4 mapped addresses (SCTP_I_WANT_MAPPED_V4_ADDR)
  *
@@ -2896,6 +3133,12 @@
 	case SCTP_NODELAY:
 		retval = sctp_getsockopt_nodelay(sk, len, optval, optlen);
 		break;
+	case SCTP_RTOINFO:
+		retval = sctp_getsockopt_rtoinfo(sk, len, optval, optlen);
+		break;
+	case SCTP_ASSOCRTXINFO:
+		retval = sctp_getsockopt_assocrtx(sk, len, optval, optlen);
+		break;
 	case SCTP_I_WANT_MAPPED_V4_ADDR:
 		retval = sctp_getsockopt_mappedv4(sk, len, optval, optlen);
 		break;
@@ -2952,7 +3195,6 @@
 	snum = addr->v4.sin_port;
 
 	SCTP_DEBUG_PRINTK("sctp_get_port() begins, snum=%d\n", snum);
-
 	sctp_local_bh_disable();
 
 	if (snum == 0) {
@@ -2999,7 +3241,6 @@
 		 * mutex.
 		 */
 		snum = rover;
-		pp = NULL;
 	} else {
 		/* We are given an specific port number; we verify
 		 * that it is not being used. If it is used, we will
@@ -3011,23 +3252,23 @@
 		sctp_spin_lock(&head->lock);
 		for (pp = head->chain; pp; pp = pp->next) {
 			if (pp->port == snum)
-				break;
+				goto pp_found;
 		}
 	}
-
-
-	if (pp && !hlist_empty(&pp->sk_list)) {
+	pp = NULL;
+	goto pp_not_found;
+pp_found:
+	if (!hlist_empty(&pp->owner)) {
 		/* We had a port hash table hit - there is an
 		 * available port (pp != NULL) and it is being
-		 * used by other socket (pp->sk_list not empty); that other
+		 * used by other socket (pp->owner not empty); that other
 		 * socket is going to be sk2.
 		 */
 		int reuse = sk->sk_reuse;
 		struct sock *sk2;
 		struct hlist_node *node;
 
-		SCTP_DEBUG_PRINTK("sctp_get_port() found a "
-				  "possible match\n");
+		SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
 		if (pp->fastreuse && sk->sk_reuse)
 			goto success;
 
@@ -3041,7 +3282,7 @@
 		 * that this port/socket (sk) combination are already
 		 * in an endpoint.
 		 */
-		sk_for_each_bound(sk2, node, &pp->sk_list) {
+		sk_for_each_bound(sk2, node, &pp->owner) {
 			struct sctp_endpoint *ep2;
 			ep2 = sctp_sk(sk2)->ep;
 
@@ -3056,10 +3297,9 @@
 		}
 		SCTP_DEBUG_PRINTK("sctp_get_port(): Found a match\n");
 	}
-
+pp_not_found:
 	/* If there was a hash table miss, create a new port.  */
 	ret = 1;
-
 	if (!pp && !(pp = sctp_bucket_create(head, snum)))
 		goto fail_unlock;
 
@@ -3067,7 +3307,7 @@
 	 * if sk->sk_reuse is too (that is, if the caller requested
 	 * SO_REUSEADDR on this socket -sk-).
 	 */
-	if (hlist_empty(&pp->sk_list))
+	if (hlist_empty(&pp->owner))
 		pp->fastreuse = sk->sk_reuse ? 1 : 0;
 	else if (pp->fastreuse && !sk->sk_reuse)
 		pp->fastreuse = 0;
@@ -3079,7 +3319,7 @@
 success:
 	inet_sk(sk)->num = snum;
 	if (!sctp_sk(sk)->bind_hash) {
-		sk_add_bind_node(sk, &pp->sk_list);
+		sk_add_bind_node(sk, &pp->owner);
 		sctp_sk(sk)->bind_hash = pp;
 	}
 	ret = 0;
@@ -3089,8 +3329,6 @@
 
 fail:
 	sctp_local_bh_enable();
-
-	SCTP_DEBUG_PRINTK("sctp_get_port() ends, ret=%d\n", ret);
 	addr->v4.sin_port = htons(addr->v4.sin_port);
 	return ret;
 }
@@ -3316,7 +3554,7 @@
 	if (pp) {
 		pp->port = snum;
 		pp->fastreuse = 0;
-		INIT_HLIST_HEAD(&pp->sk_list);
+		INIT_HLIST_HEAD(&pp->owner);
 		if ((pp->next = head->chain) != NULL)
 			pp->next->pprev = &pp->next;
 		head->chain = pp;
@@ -3328,7 +3566,7 @@
 /* Caller must hold hashbucket lock for this tb with local BH disabled */
 static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
 {
-	if (hlist_empty(&pp->sk_list)) {
+	if (hlist_empty(&pp->owner)) {
 		if (pp->next)
 			pp->next->pprev = pp->pprev;
 		*(pp->pprev) = pp->next;
@@ -3337,8 +3575,8 @@
 	}
 }
 
-/* FIXME: Comments! */
-static __inline__ void __sctp_put_port(struct sock *sk)
+/* Release this socket's reference to a local port.  */
+static inline void __sctp_put_port(struct sock *sk)
 {
 	struct sctp_bind_hashbucket *head =
 		&sctp_port_hashtable[sctp_phashfn(inet_sk(sk)->num)];
@@ -3942,6 +4180,7 @@
 {
 	struct sctp_opt *oldsp = sctp_sk(oldsk);
 	struct sctp_opt *newsp = sctp_sk(newsk);
+	struct sctp_bind_bucket *pp; /* hash list port iterator */
 	struct sctp_endpoint *newep = newsp->ep;
 	struct sk_buff *skb, *tmp;
 	struct sctp_ulpevent *event;
@@ -3951,7 +4190,8 @@
 	 */
 	newsk->sk_sndbuf = oldsk->sk_sndbuf;
 	newsk->sk_rcvbuf = oldsk->sk_rcvbuf;
-	*newsp = *oldsp;
+	/* Brute force copy old sctp opt. */
+	memcpy(newsp, oldsp, sizeof(struct sctp_opt));
 
 	/* Restore the ep value that was overwritten with the above structure
 	 * copy.
@@ -3959,6 +4199,12 @@
 	newsp->ep = newep;
 	newsp->hmac = NULL;
 
+	/* Hook this new socket in to the bind_hash list. */
+	pp = sctp_sk(oldsk)->bind_hash;
+	sk_add_bind_node(newsk, &pp->owner);
+	sctp_sk(newsk)->bind_hash = pp;
+	inet_sk(newsk)->num = inet_sk(oldsk)->num;
+
 	/* Move any messages in the old socket's receive queue that are for the
 	 * peeled off association to the new socket's receive queue.
 	 */
diff -urN linux-2.5.73-bk5/net/sctp/sysctl.c linux-2.5.73-bk6/net/sctp/sysctl.c
--- linux-2.5.73-bk5/net/sctp/sysctl.c	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/sysctl.c	2003-06-28 04:53:21.000000000 -0700
@@ -1,39 +1,40 @@
-/* SCTP kernel reference Implementation 
+/* SCTP kernel reference Implementation
  * Copyright (c) 2002 International Business Machines Corp.
  * Copyright (c) 2002 Intel Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
- * Sysctl related interfaces for SCTP. 
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * Sysctl related interfaces for 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:
  *    Mingqin Liu           <liuming@us.ibm.com>
  *    Jon Grimm             <jgrimm@us.ibm.com>
  *    Ardelle Fan           <ardelle.fan@intel.com>
+ *    Ryan Layer            <rmlayer@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.
@@ -42,42 +43,54 @@
 #include <net/sctp/structs.h>
 #include <linux/sysctl.h>
 
+static ctl_handler sctp_sysctl_jiffies_ms;
+static long rto_timer_min = 0;
+static long rto_timer_max = 86400000; /* One day */
+
 static ctl_table sctp_table[] = {
 	{
 		.ctl_name	= NET_SCTP_RTO_INITIAL,
 		.procname	= "rto_initial",
 		.data		= &sctp_rto_initial,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(long),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
-		.strategy	= &sysctl_jiffies
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &rto_timer_min,
+		.extra2         = &rto_timer_max
 	},
 	{
 		.ctl_name	= NET_SCTP_RTO_MIN,
 		.procname	= "rto_min",
 		.data		= &sctp_rto_min,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(long),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
-		.strategy	= &sysctl_jiffies
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &rto_timer_min,
+		.extra2         = &rto_timer_max
 	},
 	{
 		.ctl_name	= NET_SCTP_RTO_MAX,
 		.procname	= "rto_max",
 		.data		= &sctp_rto_max,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(long),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
-		.strategy	= &sysctl_jiffies
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &rto_timer_min,
+		.extra2         = &rto_timer_max
 	},
 	{
 		.ctl_name	= NET_SCTP_VALID_COOKIE_LIFE,
 		.procname	= "valid_cookie_life",
 		.data		= &sctp_valid_cookie_life,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(long),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
-		.strategy	= &sysctl_jiffies
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &rto_timer_min,
+		.extra2         = &rto_timer_max
 	},
 	{
 		.ctl_name	= NET_SCTP_MAX_BURST,
@@ -115,19 +128,23 @@
 		.ctl_name	= NET_SCTP_HB_INTERVAL,
 		.procname	= "hb_interval",
 		.data		= &sctp_hb_interval,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(long),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
-		.strategy	= &sysctl_jiffies
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &rto_timer_min,
+		.extra2         = &rto_timer_max
 	},
 	{
 		.ctl_name	= NET_SCTP_PRESERVE_ENABLE,
 		.procname	= "cookie_preserve_enable",
 		.data		= &sctp_cookie_preserve_enable,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(long),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
-		.strategy	= &sysctl_jiffies
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &rto_timer_min,
+		.extra2         = &rto_timer_max
 	},
 	{
 		.ctl_name	= NET_SCTP_RTO_ALPHA,
@@ -152,7 +169,6 @@
 	{
 		.ctl_name	= NET_SCTP,
 		.procname	= "sctp",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= sctp_table
 	},
@@ -163,7 +179,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= sctp_net_table
 	},
@@ -183,3 +198,37 @@
 {
 	unregister_sysctl_table(sctp_sysctl_header);
 }
+
+/* Strategy function to convert jiffies to milliseconds.  */
+static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
+		void __user *oldval, size_t __user *oldlenp,
+		void __user *newval, size_t newlen, void **context) {
+
+	if (oldval) {
+		size_t olen;
+
+		if (oldlenp) {
+			if (get_user(olen, oldlenp))
+				return -EFAULT;
+
+			if (olen != sizeof (int))
+				return -EINVAL;
+		}
+		if (put_user((*(int *)(table->data) / HZ) * 1000,
+			(int *)oldval) ||
+		    (oldlenp && put_user(sizeof (int), oldlenp)))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		int new;
+
+		if (newlen != sizeof (int))
+			return -EINVAL;
+
+		if (get_user(new, (int *)newval))
+			return -EFAULT;
+
+		*(int *)(table->data) = (new * HZ) * 1000;
+	}
+	return 1;
+}
diff -urN linux-2.5.73-bk5/net/sctp/tsnmap.c linux-2.5.73-bk6/net/sctp/tsnmap.c
--- linux-2.5.73-bk5/net/sctp/tsnmap.c	2003-06-22 11:33:32.000000000 -0700
+++ linux-2.5.73-bk6/net/sctp/tsnmap.c	2003-06-28 04:53:21.000000000 -0700
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
@@ -46,7 +46,6 @@
 #include <net/sctp/sm.h>
 
 static void sctp_tsnmap_update(struct sctp_tsnmap *map);
-static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map);
 static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
 				     __u16 len, __u16 base,
 				     int *started, __u16 *start,
@@ -92,7 +91,6 @@
 	map->cumulative_tsn_ack_point = initial_tsn - 1;
 	map->max_tsn_seen = map->cumulative_tsn_ack_point;
 	map->malloced = 0;
-	map->pending_data = 0;
 	map->num_dup_tsns = 0;
 
 	return map;
@@ -135,14 +133,6 @@
 	return dup;
 }
 
-/* Is there a gap in the TSN map?  */
-int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
-{
-	int has_gap;
-
-	has_gap = (map->cumulative_tsn_ack_point != map->max_tsn_seen);
-	return has_gap;
-}
 
 /* Mark this TSN as seen.  */
 void sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn)
@@ -176,21 +166,6 @@
 	sctp_tsnmap_update(map);
 }
 
-void sctp_tsnmap_report_dup(struct sctp_tsnmap *map, __u32 tsn)
-{
-}
-
-/* Retrieve the Cumulative TSN Ack Point. */
-__u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map)
-{
-	return map->cumulative_tsn_ack_point;
-}
-
-/* Retrieve the highest TSN we've seen.  */
-__u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map)
-{
-	return map->max_tsn_seen;
-}
 
 /* Dispose of a tsnmap.  */
 void sctp_tsnmap_free(struct sctp_tsnmap *map)
@@ -219,6 +194,10 @@
 	/* We haven't found a gap yet.  */
 	started = ended = 0;
 
+	/* If there are no more gap acks possible, get out fast.  */
+	if (TSN_lte(map->max_tsn_seen, iter->start))
+		return 0;
+
 	/* Search the first mapping array.  */
 	if (iter->start - map->base_tsn < map->len) {
 
@@ -304,10 +283,11 @@
 	} while (map->tsn_map[ctsn - map->base_tsn]);
 
 	map->cumulative_tsn_ack_point = ctsn - 1; /* Back up one. */
-	sctp_tsnmap_update_pending_data(map);
 }
 
-static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map)
+/* How many data chunks  are we missing from our peer?
+ */
+__u16 sctp_tsnmap_pending(struct sctp_tsnmap *map)
 {
 	__u32 cum_tsn = map->cumulative_tsn_ack_point;
 	__u32 max_tsn = map->max_tsn_seen;
@@ -339,7 +319,7 @@
 	}
 
 out:
-	map->pending_data = pending_data;
+	return pending_data;
 }
 
 /* This is a private helper for finding Gap Ack Blocks.  It searches a
@@ -359,6 +339,8 @@
 	 * early if we have found the end of the Gap Ack Block.
 	 */
 
+	/* Also, stop looking past the maximum TSN seen. */
+
 	/* Look for the start. */
 	if (!(*started)) {
 		for (; i < len; i++) {
@@ -404,3 +386,26 @@
 	else
 		map->overflow_map[gap - map->len] = 0;
 }
+
+/* How many gap ack blocks do we have recorded? */
+__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map)
+{
+	struct sctp_tsnmap_iter iter;
+	int gabs = 0;
+
+	/* Refresh the gap ack information. */
+	if (sctp_tsnmap_has_gap(map)) {
+		sctp_tsnmap_iter_init(map, &iter);
+		while (sctp_tsnmap_next_gap_ack(map, &iter,
+						&map->gabs[gabs].start,
+						&map->gabs[gabs].end)) {
+
+			map->gabs[gabs].start = htons(map->gabs[gabs].start);
+			map->gabs[gabs].end = htons(map->gabs[gabs].end);
+			gabs++;
+			if (gabs >= SCTP_MAX_GABS)
+				break;
+		}
+	}
+	return gabs;
+}
diff -urN linux-2.5.73-bk5/net/sunrpc/cache.c linux-2.5.73-bk6/net/sunrpc/cache.c
--- linux-2.5.73-bk5/net/sunrpc/cache.c	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/net/sunrpc/cache.c	2003-06-28 04:53:21.000000000 -0700
@@ -1018,7 +1018,6 @@
 
 struct handle {
 	struct cache_detail *cd;
-	char 		    *pbuf;
 };
 
 static void *c_start(struct seq_file *m, loff_t *pos)
@@ -1087,10 +1086,9 @@
 {
 	struct cache_head *cp = p;
 	struct cache_detail *cd = ((struct handle*)m->private)->cd;
-	char *pbuf = ((struct handle*)m->private)->pbuf;
 
 	if (p == (void *)1)
-		return cd->cache_show(m, cd, NULL, pbuf);
+		return cd->cache_show(m, cd, NULL);
 
 	ifdebug(CACHE)
 		seq_printf(m, "# expiry=%ld refcnt=%d\n",
@@ -1102,7 +1100,7 @@
 	else
 		cache_put(cp, cd);
 
-	return cd->cache_show(m, cd, cp, pbuf);
+	return cd->cache_show(m, cd, cp);
 }
 
 struct seq_operations cache_content_op = {
@@ -1115,26 +1113,19 @@
 static int content_open(struct inode *inode, struct file *file)
 {
 	int res;
-	char *namebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	struct handle *han;
 	struct cache_detail *cd = PDE(inode)->data;
 
-	if (namebuf == NULL)
-		return -ENOMEM;
-
 	han = kmalloc(sizeof(*han), GFP_KERNEL);
-	if (han == NULL) {
-		kfree(namebuf);
+	if (han == NULL)
 		return -ENOMEM;
-	}
-	han->pbuf = namebuf;
+
 	han->cd = cd;
 
 	res = seq_open(file, &cache_content_op);
-	if (res) {
-		kfree(namebuf);
+	if (res)
 		kfree(han);
-	} else
+	else
 		((struct seq_file *)file->private_data)->private = han;
 
 	return res;
@@ -1143,7 +1134,6 @@
 {
 	struct seq_file *m = (struct seq_file *)file->private_data;
 	struct handle *han = m->private;
-	kfree(han->pbuf);
 	kfree(han);
 	m->private = NULL;
 	return seq_release(inode, file);
diff -urN linux-2.5.73-bk5/net/sunrpc/svcauth_unix.c linux-2.5.73-bk6/net/sunrpc/svcauth_unix.c
--- linux-2.5.73-bk5/net/sunrpc/svcauth_unix.c	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/net/sunrpc/svcauth_unix.c	2003-06-28 04:53:21.000000000 -0700
@@ -215,8 +215,7 @@
 
 static int ip_map_show(struct seq_file *m,
 		       struct cache_detail *cd,
-		       struct cache_head *h,
-		       char *pbuf)
+		       struct cache_head *h)
 {
 	struct ip_map *im;
 	struct in_addr addr;
diff -urN linux-2.5.73-bk5/net/sunrpc/svcsock.c linux-2.5.73-bk6/net/sunrpc/svcsock.c
--- linux-2.5.73-bk5/net/sunrpc/svcsock.c	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk6/net/sunrpc/svcsock.c	2003-06-28 04:53:21.000000000 -0700
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/suspend.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -1190,6 +1191,9 @@
 
 		schedule_timeout(timeout);
 
+		if (current->flags & PF_FREEZE)
+			refrigerator(PF_IOTHREAD);
+
 		spin_lock_bh(&serv->sv_lock);
 		remove_wait_queue(&rqstp->rq_wait, &wait);
 
diff -urN linux-2.5.73-bk5/net/sunrpc/sysctl.c linux-2.5.73-bk6/net/sunrpc/sysctl.c
--- linux-2.5.73-bk5/net/sunrpc/sysctl.c	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk6/net/sunrpc/sysctl.c	2003-06-28 04:53:21.000000000 -0700
@@ -155,7 +155,6 @@
 	{
 		.ctl_name	= CTL_SUNRPC,
 		.procname	= "sunrpc",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= debug_table
 	},
diff -urN linux-2.5.73-bk5/net/unix/sysctl_net_unix.c linux-2.5.73-bk6/net/unix/sysctl_net_unix.c
--- linux-2.5.73-bk5/net/unix/sysctl_net_unix.c	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk6/net/unix/sysctl_net_unix.c	2003-06-28 04:53:21.000000000 -0700
@@ -30,7 +30,6 @@
 	{
 		.ctl_name	= NET_UNIX,
 		.procname	= "unix",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= unix_table
 	},
@@ -41,7 +40,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= unix_net_table
 	},
diff -urN linux-2.5.73-bk5/net/xfrm/xfrm_user.c linux-2.5.73-bk6/net/xfrm/xfrm_user.c
--- linux-2.5.73-bk5/net/xfrm/xfrm_user.c	2003-06-28 04:53:14.000000000 -0700
+++ linux-2.5.73-bk6/net/xfrm/xfrm_user.c	2003-06-28 04:53:21.000000000 -0700
@@ -560,7 +560,7 @@
 	}
 }
 
-static int copy_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma)
+static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma)
 {
 	struct rtattr *rt = xfrma[XFRMA_TMPL-1];
 	struct xfrm_user_tmpl *utmpl;
@@ -616,7 +616,7 @@
 	}
 
 	copy_from_user_policy(xp, p);
-	err = copy_user_tmpl(xp, xfrma);
+	err = copy_from_user_tmpl(xp, xfrma);
 	if (err) {
 		*errp = err;
 		kfree(xp);
@@ -653,6 +653,38 @@
 	return 0;
 }
 
+static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb)
+{
+	struct xfrm_user_tmpl vec[XFRM_MAX_DEPTH];
+	int i;
+
+	if (xp->xfrm_nr == 0)
+		return 0;
+
+	for (i = 0; i < xp->xfrm_nr; i++) {
+		struct xfrm_user_tmpl *up = &vec[i];
+		struct xfrm_tmpl *kp = &xp->xfrm_vec[i];
+
+		memcpy(&up->id, &kp->id, sizeof(up->id));
+		memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr));
+		up->reqid = kp->reqid;
+		up->mode = kp->mode;
+		up->share = kp->share;
+		up->optional = kp->optional;
+		up->aalgos = kp->aalgos;
+		up->ealgos = kp->ealgos;
+		up->calgos = kp->calgos;
+	}
+	RTA_PUT(skb, XFRMA_TMPL,
+		(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr),
+		vec);
+
+	return 0;
+
+rtattr_failure:
+	return -1;
+}
+
 static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
 {
 	struct xfrm_dump_info *sp = ptr;
@@ -672,29 +704,8 @@
 	nlh->nlmsg_flags = 0;
 
 	copy_to_user_policy(xp, p, dir);
-
-	if (xp->xfrm_nr) {
-		struct xfrm_user_tmpl vec[XFRM_MAX_DEPTH];
-		int i;
-
-		for (i = 0; i < xp->xfrm_nr; i++) {
-			struct xfrm_user_tmpl *up = &vec[i];
-			struct xfrm_tmpl *kp = &xp->xfrm_vec[i];
-
-			memcpy(&up->id, &kp->id, sizeof(up->id));
-			memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr));
-			up->reqid = kp->reqid;
-			up->mode = kp->mode;
-			up->share = kp->share;
-			up->optional = kp->optional;
-			up->aalgos = kp->aalgos;
-			up->ealgos = kp->ealgos;
-			up->calgos = kp->calgos;
-		}
-		RTA_PUT(skb, XFRMA_TMPL,
-			(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr),
-			vec);
-	}
+	if (copy_to_user_tmpl(xp, skb) < 0)
+		goto nlmsg_failure;
 
 	nlh->nlmsg_len = skb->tail - b;
 out:
@@ -702,7 +713,6 @@
 	return 0;
 
 nlmsg_failure:
-rtattr_failure:
 	skb_trim(skb, b - skb->data);
 	return -1;
 }
@@ -1011,12 +1021,16 @@
 
 	memcpy(&ua->id, &x->id, sizeof(ua->id));
 	memcpy(&ua->saddr, &x->props.saddr, sizeof(ua->saddr));
+	memcpy(&ua->sel, &x->sel, sizeof(ua->sel));
 	copy_to_user_policy(xp, &ua->policy, dir);
 	ua->aalgos = xt->aalgos;
 	ua->ealgos = xt->ealgos;
 	ua->calgos = xt->calgos;
 	ua->seq = x->km.seq = seq;
 
+	if (copy_to_user_tmpl(xp, skb) < 0)
+		goto nlmsg_failure;
+
 	nlh->nlmsg_len = skb->tail - b;
 	return skb->len;
 
@@ -1029,8 +1043,12 @@
 			     struct xfrm_policy *xp, int dir)
 {
 	struct sk_buff *skb;
+	size_t len;
 
-	skb = alloc_skb(sizeof(struct xfrm_user_acquire) + 16, GFP_ATOMIC);
+	len = RTA_LENGTH(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
+	len = RTA_ALIGN(len);
+	len += NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)));
+	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
