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

diff -urN linux-2.4.19-rc3/Makefile linux-2.4.19-rc4/Makefile
--- linux-2.4.19-rc3/Makefile	Wed Jul 31 15:10:12 2002
+++ linux-2.4.19-rc4/Makefile	Wed Jul 31 15:10:17 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 19
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.19-rc3/arch/alpha/kernel/osf_sys.c linux-2.4.19-rc4/arch/alpha/kernel/osf_sys.c
--- linux-2.4.19-rc3/arch/alpha/kernel/osf_sys.c	Wed Jul 31 15:10:12 2002
+++ linux-2.4.19-rc4/arch/alpha/kernel/osf_sys.c	Wed Jul 31 15:10:17 2002
@@ -219,8 +219,8 @@
 	 * isn't actually going to matter, as if the parent happens
 	 * to change we can happily return either of the pids.
 	 */
-	(&regs)->r20 = tsk->p_opptr->pid;
-	return tsk->pid;
+	(&regs)->r20 = tsk->p_opptr->tgid;
+	return tsk->tgid;
 }
 
 asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
diff -urN linux-2.4.19-rc3/arch/i386/kernel/i387.c linux-2.4.19-rc4/arch/i386/kernel/i387.c
--- linux-2.4.19-rc3/arch/i386/kernel/i387.c	Fri Feb 23 10:09:08 2001
+++ linux-2.4.19-rc4/arch/i386/kernel/i387.c	Wed Jul 31 15:10:17 2002
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/sched.h>
+#include <linux/init.h>
 #include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/math_emu.h>
@@ -24,6 +25,29 @@
 #define HAVE_HWFP 1
 #endif
 
+static union i387_union empty_fpu_state;
+
+void __init boot_init_fpu(void)
+{
+	memset(&empty_fpu_state, 0, sizeof(union i387_union));
+
+	if (!cpu_has_fxsr) {
+		empty_fpu_state.fsave.cwd = 0xffff037f;
+		empty_fpu_state.fsave.swd = 0xffff0000;
+		empty_fpu_state.fsave.twd = 0xffffffff;
+		empty_fpu_state.fsave.fos = 0xffff0000;
+	} else {
+		empty_fpu_state.fxsave.cwd = 0x37f;
+		if (cpu_has_xmm)
+			empty_fpu_state.fxsave.mxcsr = 0x1f80;
+	}
+}
+
+void load_empty_fpu(struct task_struct * tsk)
+{
+	memcpy(&tsk->thread.i387, &empty_fpu_state, sizeof(union i387_union));
+}
+
 /*
  * The _current_ task is using the FPU for the first time
  * so initialize it and set the mxcsr to its default
@@ -32,10 +56,10 @@
  */
 void init_fpu(void)
 {
-	__asm__("fninit");
-	if ( cpu_has_xmm )
-		load_mxcsr(0x1f80);
-		
+	if (cpu_has_fxsr)
+		asm volatile("fxrstor %0" : : "m" (empty_fpu_state.fxsave));
+	else
+		__asm__("fninit");
 	current->used_math = 1;
 }
 
diff -urN linux-2.4.19-rc3/arch/i386/kernel/ptrace.c linux-2.4.19-rc4/arch/i386/kernel/ptrace.c
--- linux-2.4.19-rc3/arch/i386/kernel/ptrace.c	Wed Nov 21 10:42:41 2001
+++ linux-2.4.19-rc4/arch/i386/kernel/ptrace.c	Wed Jul 31 15:10:17 2002
@@ -369,12 +369,8 @@
 			break;
 		}
 		ret = 0;
-		if ( !child->used_math ) {
-			/* Simulate an empty FPU. */
-			set_fpu_cwd(child, 0x037f);
-			set_fpu_swd(child, 0x0000);
-			set_fpu_twd(child, 0xffff);
-		}
+		if ( !child->used_math )
+			load_empty_fpu(child);
 		get_fpregs((struct user_i387_struct *)data, child);
 		break;
 	}
@@ -397,13 +393,8 @@
 			ret = -EIO;
 			break;
 		}
-		if ( !child->used_math ) {
-			/* Simulate an empty FPU. */
-			set_fpu_cwd(child, 0x037f);
-			set_fpu_swd(child, 0x0000);
-			set_fpu_twd(child, 0xffff);
-			set_fpu_mxcsr(child, 0x1f80);
-		}
+		if ( !child->used_math )
+			load_empty_fpu(child);
 		ret = get_fpxregs((struct user_fxsr_struct *)data, child);
 		break;
 	}
diff -urN linux-2.4.19-rc3/arch/i386/kernel/vm86.c linux-2.4.19-rc4/arch/i386/kernel/vm86.c
--- linux-2.4.19-rc3/arch/i386/kernel/vm86.c	Mon Feb 25 11:37:53 2002
+++ linux-2.4.19-rc4/arch/i386/kernel/vm86.c	Wed Jul 31 15:10:17 2002
@@ -2,7 +2,34 @@
  *  linux/kernel/vm86.c
  *
  *  Copyright (C) 1994  Linus Torvalds
+ *
+ *  29 dec 2001 - Fixed oopses caused by unchecked access to the vm86
+ *                stack - Manfred Spraul <manfreds@colorfullife.com>
+ *
+ *  22 mar 2002 - Manfred detected the stackfaults, but didn't handle
+ *                them correctly. Now the emulation will be in a
+ *                consistent state after stackfaults - Kasper Dupont
+ *                <kasperd@daimi.au.dk>
+ *
+ *  22 mar 2002 - Added missing clear_IF in set_vflags_* Kasper Dupont
+ *                <kasperd@daimi.au.dk>
+ *
+ *  ?? ??? 2002 - Fixed premature returns from handle_vm86_fault
+ *                caused by Kasper Dupont's changes - Stas Sergeev
+ *
+ *   4 apr 2002 - Fixed CHECK_IF_IN_TRAP broken by Stas' changes.
+ *                Kasper Dupont <kasperd@daimi.au.dk>
+ *
+ *   9 apr 2002 - Changed syntax of macros in handle_vm86_fault.
+ *                Kasper Dupont <kasperd@daimi.au.dk>
+ *
+ *   9 apr 2002 - Changed stack access macros to jump to a label
+ *                instead of returning to userspace. This simplifies
+ *                do_int, and is needed by handle_vm6_fault. Kasper
+ *                Dupont <kasperd@daimi.au.dk>
+ *   
  */
+
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -97,21 +124,22 @@
 	pte_t *pte;
 	int i;
 
+	spin_lock(&tsk->mm->page_table_lock);
 	pgd = pgd_offset(tsk->mm, 0xA0000);
 	if (pgd_none(*pgd))
-		return;
+		goto out;
 	if (pgd_bad(*pgd)) {
 		pgd_ERROR(*pgd);
 		pgd_clear(pgd);
-		return;
+		goto out;
 	}
 	pmd = pmd_offset(pgd, 0xA0000);
 	if (pmd_none(*pmd))
-		return;
+		goto out;
 	if (pmd_bad(*pmd)) {
 		pmd_ERROR(*pmd);
 		pmd_clear(pmd);
-		return;
+		goto out;
 	}
 	pte = pte_offset(pmd, 0xA0000);
 	for (i = 0; i < 32; i++) {
@@ -119,6 +147,8 @@
 			set_pte(pte, pte_wrprotect(*pte));
 		pte++;
 	}
+out:
+	spin_unlock(&tsk->mm->page_table_lock);
 	flush_tlb();
 }
 
@@ -290,12 +320,30 @@
 	regs->eflags &= ~TF_MASK;
 }
 
+static inline void clear_AC(struct kernel_vm86_regs * regs)
+{
+	regs->eflags &= ~AC_MASK;
+}
+
+/* It is correct to call set_IF(regs) from the set_vflags_*
+ * functions. However someone forgot to call clear_IF(regs)
+ * in the opposite case.
+ * After the command sequence CLI PUSHF STI POPF you should
+ * end up with interrups disabled, but you ended up with
+ * interrupts enabled.
+ *  ( I was testing my own changes, but the only bug I
+ *    could find was in a function I had not changed. )
+ * [KD]
+ */
+
 static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs)
 {
 	set_flags(VEFLAGS, eflags, current->thread.v86mask);
 	set_flags(regs->eflags, eflags, SAFE_MASK);
 	if (eflags & IF_MASK)
 		set_IF(regs);
+	else
+		clear_IF(regs);
 }
 
 static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs)
@@ -304,6 +352,8 @@
 	set_flags(regs->eflags, flags, SAFE_MASK);
 	if (flags & IF_MASK)
 		set_IF(regs);
+	else
+		clear_IF(regs);
 }
 
 static inline unsigned long get_vflags(struct kernel_vm86_regs * regs)
@@ -323,80 +373,90 @@
 	return nr;
 }
 
-/*
- * Boy are these ugly, but we need to do the correct 16-bit arithmetic.
- * Gcc makes a mess of it, so we do it inline and use non-obvious calling
- * conventions..
- */
-#define pushb(base, ptr, val) \
-__asm__ __volatile__( \
-	"decw %w0\n\t" \
-	"movb %2,0(%1,%0)" \
-	: "=r" (ptr) \
-	: "r" (base), "q" (val), "0" (ptr))
-
-#define pushw(base, ptr, val) \
-__asm__ __volatile__( \
-	"decw %w0\n\t" \
-	"movb %h2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"movb %b2,0(%1,%0)" \
-	: "=r" (ptr) \
-	: "r" (base), "q" (val), "0" (ptr))
-
-#define pushl(base, ptr, val) \
-__asm__ __volatile__( \
-	"decw %w0\n\t" \
-	"rorl $16,%2\n\t" \
-	"movb %h2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"movb %b2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"rorl $16,%2\n\t" \
-	"movb %h2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"movb %b2,0(%1,%0)" \
-	: "=r" (ptr) \
-	: "r" (base), "q" (val), "0" (ptr))
-
-#define popb(base, ptr) \
-({ unsigned long __res; \
-__asm__ __volatile__( \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0" \
-	: "=r" (ptr), "=r" (base), "=q" (__res) \
-	: "0" (ptr), "1" (base), "2" (0)); \
-__res; })
-
-#define popw(base, ptr) \
-({ unsigned long __res; \
-__asm__ __volatile__( \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0\n\t" \
-	"movb 0(%1,%0),%h2\n\t" \
-	"incw %w0" \
-	: "=r" (ptr), "=r" (base), "=q" (__res) \
-	: "0" (ptr), "1" (base), "2" (0)); \
-__res; })
-
-#define popl(base, ptr) \
-({ unsigned long __res; \
-__asm__ __volatile__( \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0\n\t" \
-	"movb 0(%1,%0),%h2\n\t" \
-	"incw %w0\n\t" \
-	"rorl $16,%2\n\t" \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0\n\t" \
-	"movb 0(%1,%0),%h2\n\t" \
-	"incw %w0\n\t" \
-	"rorl $16,%2" \
-	: "=r" (ptr), "=r" (base), "=q" (__res) \
-	: "0" (ptr), "1" (base)); \
-__res; })
+#define val_byte(val, n) (((__u8 *)&val)[n])
 
-static void do_int(struct kernel_vm86_regs *regs, int i, unsigned char * ssp, unsigned long sp)
+#define pushb(base, ptr, val, err_label) \
+	do { \
+		__u8 __val = val; \
+		ptr--; \
+		if (put_user(__val, base + ptr) < 0) \
+			goto err_label; \
+	} while(0)
+
+#define pushw(base, ptr, val, err_label) \
+	do { \
+		__u16 __val = val; \
+		ptr--; \
+		if (put_user(val_byte(__val, 1), base + ptr) < 0) \
+			goto err_label; \
+		ptr--; \
+		if (put_user(val_byte(__val, 0), base + ptr) < 0) \
+			goto err_label; \
+	} while(0)
+
+#define pushl(base, ptr, val, err_label) \
+	do { \
+		__u32 __val = val; \
+		ptr--; \
+		if (put_user(val_byte(__val, 3), base + ptr) < 0) \
+			goto err_label; \
+		ptr--; \
+		if (put_user(val_byte(__val, 2), base + ptr) < 0) \
+			goto err_label; \
+		ptr--; \
+		if (put_user(val_byte(__val, 1), base + ptr) < 0) \
+			goto err_label; \
+		ptr--; \
+		if (put_user(val_byte(__val, 0), base + ptr) < 0) \
+			goto err_label; \
+	} while(0)
+
+#define popb(base, ptr, err_label) \
+	({ \
+	 	__u8 __res; \
+		if (get_user(__res, base + ptr) < 0) \
+			goto err_label; \
+		ptr++; \
+		__res; \
+	})
+
+#define popw(base, ptr, err_label) \
+	({ \
+	 	__u16 __res; \
+		if (get_user(val_byte(__res, 0), base + ptr) < 0) \
+			goto err_label; \
+		ptr++; \
+		if (get_user(val_byte(__res, 1), base + ptr) < 0) \
+			goto err_label; \
+		ptr++; \
+		__res; \
+	})
+
+#define popl(base, ptr, err_label) \
+	({ \
+	 	__u32 __res; \
+		if (get_user(val_byte(__res, 0), base + ptr) < 0) \
+			goto err_label; \
+		ptr++; \
+		if (get_user(val_byte(__res, 1), base + ptr) < 0) \
+			goto err_label; \
+		ptr++; \
+		if (get_user(val_byte(__res, 2), base + ptr) < 0) \
+			goto err_label; \
+		ptr++; \
+		if (get_user(val_byte(__res, 3), base + ptr) < 0) \
+			goto err_label; \
+		ptr++; \
+		__res; \
+	})
+
+/* There are so many possible reasons for this function to return
+ * VM86_INTx, so adding another doesn't bother me. We can expect
+ * userspace programs to be able to handle it. (Getting a problem
+ * in userspace is always better than an Oops anyway.) [KD]
+ */
+static void do_int(struct kernel_vm86_regs *regs, int i,
+    unsigned char * ssp, unsigned short sp)
 {
 	unsigned long *intr_ptr, segoffs;
 
@@ -411,14 +471,15 @@
 		goto cannot_handle;
 	if ((segoffs >> 16) == BIOSSEG)
 		goto cannot_handle;
-	pushw(ssp, sp, get_vflags(regs));
-	pushw(ssp, sp, regs->cs);
-	pushw(ssp, sp, IP(regs));
+	pushw(ssp, sp, get_vflags(regs), cannot_handle);
+	pushw(ssp, sp, regs->cs, cannot_handle);
+	pushw(ssp, sp, IP(regs), cannot_handle);
 	regs->cs = segoffs >> 16;
 	SP(regs) -= 6;
 	IP(regs) = segoffs & 0xffff;
 	clear_TF(regs);
 	clear_IF(regs);
+	clear_AC(regs);
 	return;
 
 cannot_handle:
@@ -450,75 +511,80 @@
 
 void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
 {
-	unsigned char *csp, *ssp;
-	unsigned long ip, sp;
+	unsigned char *csp, *ssp, opcode;
+	unsigned short ip, sp;
+	int data32, pref_done;
 
 #define CHECK_IF_IN_TRAP \
 	if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \
-		pushw(ssp,sp,popw(ssp,sp) | TF_MASK);
-#define VM86_FAULT_RETURN \
+		newflags |= TF_MASK
+#define VM86_FAULT_RETURN do { \
 	if (VMPI.force_return_for_pic  && (VEFLAGS & (IF_MASK | VIF_MASK))) \
 		return_to_32bit(regs, VM86_PICRETURN); \
-	return;
+	return; } while (0)
 	                                   
 	csp = (unsigned char *) (regs->cs << 4);
 	ssp = (unsigned char *) (regs->ss << 4);
 	sp = SP(regs);
 	ip = IP(regs);
 
-	switch (popb(csp, ip)) {
-
-	/* operand size override */
-	case 0x66:
-		switch (popb(csp, ip)) {
-
-		/* pushfd */
-		case 0x9c:
-			SP(regs) -= 4;
-			IP(regs) += 2;
-			pushl(ssp, sp, get_vflags(regs));
-			VM86_FAULT_RETURN;
-
-		/* popfd */
-		case 0x9d:
-			SP(regs) += 4;
-			IP(regs) += 2;
-			CHECK_IF_IN_TRAP
-			set_vflags_long(popl(ssp, sp), regs);
-			VM86_FAULT_RETURN;
-
-		/* iretd */
-		case 0xcf:
-			SP(regs) += 12;
-			IP(regs) = (unsigned short)popl(ssp, sp);
-			regs->cs = (unsigned short)popl(ssp, sp);
-			CHECK_IF_IN_TRAP
-			set_vflags_long(popl(ssp, sp), regs);
-			VM86_FAULT_RETURN;
-		/* need this to avoid a fallthrough */
-		default:
-			return_to_32bit(regs, VM86_UNKNOWN);
+	data32 = 0;
+	pref_done = 0;
+	do {
+		switch (opcode = popb(csp, ip, simulate_sigsegv)) {
+			case 0x66:      /* 32-bit data */     data32=1; break;
+			case 0x67:      /* 32-bit address */  break;
+			case 0x2e:      /* CS */              break;
+			case 0x3e:      /* DS */              break;
+			case 0x26:      /* ES */              break;
+			case 0x36:      /* SS */              break;
+			case 0x65:      /* GS */              break;
+			case 0x64:      /* FS */              break;
+			case 0xf2:      /* repnz */	      break;
+			case 0xf3:      /* rep */             break;
+			default: pref_done = 1;
 		}
+	} while (!pref_done);
+
+	switch (opcode) {
 
 	/* pushf */
 	case 0x9c:
-		SP(regs) -= 2;
-		IP(regs)++;
-		pushw(ssp, sp, get_vflags(regs));
+		if (data32) {
+			pushl(ssp, sp, get_vflags(regs), simulate_sigsegv);
+			SP(regs) -= 4;
+		} else {
+			pushw(ssp, sp, get_vflags(regs), simulate_sigsegv);
+			SP(regs) -= 2;
+		}
+		IP(regs) = ip;
 		VM86_FAULT_RETURN;
 
 	/* popf */
 	case 0x9d:
-		SP(regs) += 2;
-		IP(regs)++;
-		CHECK_IF_IN_TRAP
-		set_vflags_short(popw(ssp, sp), regs);
+		{
+		unsigned long newflags;
+		if (data32) {
+			newflags=popl(ssp, sp, simulate_sigsegv);
+			SP(regs) += 4;
+		} else {
+			newflags = popw(ssp, sp, simulate_sigsegv);
+			SP(regs) += 2;
+		}
+		IP(regs) = ip;
+		CHECK_IF_IN_TRAP;
+		if (data32) {
+			set_vflags_long(newflags, regs);
+		} else {
+			set_vflags_short(newflags, regs);
+		}
 		VM86_FAULT_RETURN;
+		}
 
 	/* int xx */
 	case 0xcd: {
-	        int intno=popb(csp, ip);
-		IP(regs) += 2;
+	        int intno=popb(csp, ip, simulate_sigsegv);
+		IP(regs) = ip;
 		if (VMPI.vm86dbg_active) {
 			if ( (1 << (intno &7)) & VMPI.vm86dbg_intxxtab[intno >> 3] )
 				return_to_32bit(regs, VM86_INTx + (intno << 8));
@@ -529,16 +595,35 @@
 
 	/* iret */
 	case 0xcf:
-		SP(regs) += 6;
-		IP(regs) = popw(ssp, sp);
-		regs->cs = popw(ssp, sp);
-		CHECK_IF_IN_TRAP
-		set_vflags_short(popw(ssp, sp), regs);
+		{
+		unsigned long newip;
+		unsigned long newcs;
+		unsigned long newflags;
+		if (data32) {
+			newip=popl(ssp, sp, simulate_sigsegv);
+			newcs=popl(ssp, sp, simulate_sigsegv);
+			newflags=popl(ssp, sp, simulate_sigsegv);
+			SP(regs) += 12;
+		} else {
+			newip = popw(ssp, sp, simulate_sigsegv);
+			newcs = popw(ssp, sp, simulate_sigsegv);
+			newflags = popw(ssp, sp, simulate_sigsegv);
+			SP(regs) += 6;
+		}
+		IP(regs) = newip;
+		regs->cs = newcs;
+		CHECK_IF_IN_TRAP;
+		if (data32) {
+			set_vflags_long(newflags, regs);
+		} else {
+			set_vflags_short(newflags, regs);
+		}
 		VM86_FAULT_RETURN;
+		}
 
 	/* cli */
 	case 0xfa:
-		IP(regs)++;
+		IP(regs) = ip;
 		clear_IF(regs);
 		VM86_FAULT_RETURN;
 
@@ -550,13 +635,28 @@
 	 * Probably needs some horsing around with the TF flag. Aiee..
 	 */
 	case 0xfb:
-		IP(regs)++;
+		IP(regs) = ip;
 		set_IF(regs);
 		VM86_FAULT_RETURN;
 
 	default:
 		return_to_32bit(regs, VM86_UNKNOWN);
 	}
+
+	return;
+
+simulate_sigsegv:
+	/* FIXME: After a long discussion with Stas we finally
+	 *        agreed, that this is wrong. Here we should
+	 *        really send a SIGSEGV to the user program.
+	 *        But how do we create the correct context? We
+	 *        are inside a general protection fault handler
+	 *        and has just returned from a page fault handler.
+	 *        The correct context for the signal handler
+	 *        should be a mixture of the two, but how do we
+	 *        get the information? [KD]
+	 */
+	return_to_32bit(regs, VM86_UNKNOWN);
 }
 
 /* ---------------- vm86 special IRQ passing stuff ----------------- */
diff -urN linux-2.4.19-rc3/drivers/char/Config.in linux-2.4.19-rc4/drivers/char/Config.in
--- linux-2.4.19-rc3/drivers/char/Config.in	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/char/Config.in	Wed Jul 31 15:10:18 2002
@@ -251,7 +251,7 @@
 fi
 endmenu
 
-dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
+tristate '/dev/agpgart (AGP Support)' CONFIG_AGP
 if [ "$CONFIG_AGP" != "n" ]; then
    bool '  Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL
    bool '  Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810
diff -urN linux-2.4.19-rc3/drivers/ide/ide-pci.c linux-2.4.19-rc4/drivers/ide/ide-pci.c
--- linux-2.4.19-rc3/drivers/ide/ide-pci.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ide/ide-pci.c	Wed Jul 31 15:10:18 2002
@@ -402,7 +402,7 @@
 	{DEVID_VIA_IDE,	"VIA_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_MR_IDE,	"VP_IDE",	PCI_VIA82CXXX,	ATA66_VIA82CXXX,INIT_VIA82CXXX,	DMA_VIA82CXXX,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0 },
 	{DEVID_VP_IDE,	"VP_IDE",	PCI_VIA82CXXX,	ATA66_VIA82CXXX,INIT_VIA82CXXX,	DMA_VIA82CXXX,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0 },
-#ifdef CONFIG_PDC202XX_FORCE
+#ifndef CONFIG_PDC202XX_FORCE
         {DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	NULL,		INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
         {DEVID_PDC20262,"PDC20262",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	48 },
         {DEVID_PDC20265,"PDC20265",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	48 },
@@ -669,7 +669,7 @@
 	 */
 	pciirq = dev->irq;
 	
-#ifndef CONFIG_PDC202XX_FORCE
+#ifdef CONFIG_PDC202XX_FORCE
 	if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) {
 		/*
 		 * By rights we want to ignore Promise FastTrak and SuperTrak
diff -urN linux-2.4.19-rc3/drivers/ide/sis5513.c linux-2.4.19-rc4/drivers/ide/sis5513.c
--- linux-2.4.19-rc3/drivers/ide/sis5513.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ide/sis5513.c	Wed Jul 31 15:10:18 2002
@@ -169,13 +169,13 @@
 	unsigned char chipset_family;
 	unsigned char flags;
 } SiSHostChipInfo[] = {
-	{ "SiS750",	PCI_DEVICE_ID_SI_750,	ATA_100,	SIS5513_LATENCY },
-	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_100,	SIS5513_LATENCY },
+//	{ "SiS750",	PCI_DEVICE_ID_SI_750,	ATA_100,	SIS5513_LATENCY },
+//	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100a,	SIS5513_LATENCY },
-	{ "SiS650",	PCI_DEVICE_ID_SI_650,	ATA_100,	SIS5513_LATENCY },
-	{ "SiS645",	PCI_DEVICE_ID_SI_645,	ATA_100,	SIS5513_LATENCY },
+//	{ "SiS650",	PCI_DEVICE_ID_SI_650,	ATA_100,	SIS5513_LATENCY },
+//	{ "SiS645",	PCI_DEVICE_ID_SI_645,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS635",	PCI_DEVICE_ID_SI_635,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS640",	PCI_DEVICE_ID_SI_640,	ATA_66,		SIS5513_LATENCY },
 	{ "SiS630",	PCI_DEVICE_ID_SI_630,	ATA_66,		SIS5513_LATENCY },
diff -urN linux-2.4.19-rc3/drivers/ieee1394/Makefile linux-2.4.19-rc4/drivers/ieee1394/Makefile
--- linux-2.4.19-rc3/drivers/ieee1394/Makefile	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/Makefile	Wed Jul 31 15:10:18 2002
@@ -24,4 +24,4 @@
 include $(TOPDIR)/Rules.make
 
 ieee1394.o: $(ieee1394-objs)
-	$(LD) -r -o $@ $(ieee1394-objs)
+	$(LD) $(LDFLAGS) -r -o $@ $(ieee1394-objs)
diff -urN linux-2.4.19-rc3/drivers/ieee1394/amdtp.c linux-2.4.19-rc4/drivers/ieee1394/amdtp.c
--- linux-2.4.19-rc3/drivers/ieee1394/amdtp.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/amdtp.c	Wed Jul 31 15:10:18 2002
@@ -32,7 +32,7 @@
  * That is outside the scope of this driver, and furthermore it is not
  * really standardized yet.
  *
- * The Audio and Music Data Tranmission Protocol is avaiable at
+ * The Audio and Music Data Tranmission Protocol is available at
  *
  *     http://www.1394ta.org/Download/Technology/Specifications/2001/AM20Final-jf2.pdf
  *
@@ -89,9 +89,13 @@
 
 #define FMT_AMDTP 0x10
 #define FDF_AM824 0x00
-#define FDF_SFC_32KHZ  0x00 /* 32kHz */
-#define FDF_SFC_44K1HZ 0x01 /* 44.1kHz */
-#define FDF_SFC_48KHZ  0x02 /* 44.1kHz */
+#define FDF_SFC_32KHZ   0x00
+#define FDF_SFC_44K1HZ  0x01
+#define FDF_SFC_48KHZ   0x02
+#define FDF_SFC_88K2HZ  0x03
+#define FDF_SFC_96KHZ   0x04
+#define FDF_SFC_176K4HZ 0x05
+#define FDF_SFC_192KHZ  0x06
 
 struct descriptor_block {
 	struct output_more_immediate {
@@ -113,15 +117,42 @@
 struct packet {
 	struct descriptor_block *db;
 	dma_addr_t db_bus;
-	quadlet_t *payload;
+	struct iso_packet *payload;
 	dma_addr_t payload_bus;
 };
 
+#ifdef __BIG_ENDIAN_BITFIELD
+
+#error Big endian bitfields not tested
+
+#else
+
+struct iso_packet {
+	/* First quadlet */
+	unsigned int sid      : 6;
+	unsigned int eoh0     : 2;
+	unsigned int dbs      : 8;
+	unsigned int reserved : 2;
+	unsigned int sph      : 1;
+	unsigned int qpc      : 3;
+	unsigned int fn       : 2;
+	unsigned int dbc      : 8;
+
+	/* Second quadlet */
+	unsigned int fmt      : 6;
+	unsigned int eoh1     : 2;
+	unsigned int fdf      : 8;
+	unsigned int syt      : 16;
+
+	quadlet_t data[0];
+};
+
+#endif
+
 struct fraction {
 	int integer;
 	int numerator;
 	int denominator;
-	int counter;
 };
 
 #define PACKET_LIST_SIZE 256
@@ -148,6 +179,8 @@
 	int rate;
 	int dimension;
 	int fdf;
+	int mode;
+	int sample_format;
 	struct cmp_pcr *opcr;
 
 	/* Input samples are copied here. */
@@ -157,7 +190,7 @@
 	unsigned char dbc;
 	struct packet_list *current_packet_list;
 	int current_packet;
-	struct fraction packet_size_fraction;
+	struct fraction ready_samples, samples_per_cycle;
 
 	/* We use these to generate control bits when we are packing
 	 * iec958 data.
@@ -176,8 +209,7 @@
 	 * written back in the dma programs.
 	 */
 	atomic_t cycle_count, cycle_count2;
-	int cycle_offset;
-	struct fraction syt_fraction;
+	struct fraction cycle_offset, ticks_per_syt_offset;
 	int syt_interval;
 	int stale_count;
 
@@ -255,7 +287,7 @@
 		  OHCI1394_CONTEXT_WAKE);
 }
 
-void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx)
+void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous)
 {
 	u32 control;
 	int wait;
@@ -265,13 +297,15 @@
 		  OHCI1394_CONTEXT_RUN);
 	wmb();
 
-	for (wait = 0; wait < 5; wait++) {
-		control = reg_read(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16);
-		if ((control & OHCI1394_CONTEXT_ACTIVE) == 0)
-			break;
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+	if (synchronous) {
+		for (wait = 0; wait < 5; wait++) {
+			control = reg_read(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16);
+			if ((control & OHCI1394_CONTEXT_ACTIVE) == 0)
+				break;
+			
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		}
 	}
 }
 
@@ -297,6 +331,27 @@
 	return pl;
 }
 
+static void stream_start_dma(struct stream *s, struct packet_list *pl)
+{
+	u32 syt_cycle, cycle_count, start_cycle;
+
+	cycle_count = reg_read(s->host->host->hostdata,
+			       OHCI1394_IsochronousCycleTimer) >> 12;
+	syt_cycle = (pl->last_cycle_count - PACKET_LIST_SIZE + 1) & 0x0f;
+
+	/* We program the DMA controller to start transmission at
+	 * least 17 cycles from now - this happens when the lower four
+	 * bits of cycle_count is 0x0f and syt_cycle is 0, in this
+	 * case the start cycle is cycle_count - 15 + 32. */
+	start_cycle = (cycle_count & ~0x0f) + 32 + syt_cycle;
+	if ((start_cycle & 0x1fff) >= 8000)
+		start_cycle = start_cycle - 8000 + 0x2000;
+
+	ohci1394_start_it_ctx(s->host->ohci, s->iso_context,
+			      pl->packets[0].db_bus, 3,
+			      start_cycle & 0x7fff);
+}
+
 static void stream_put_dma_packet_list(struct stream *s,
 				       struct packet_list *pl)
 {
@@ -317,20 +372,8 @@
 		last->db->payload_desc.branch = pl->packets[0].db_bus | 3;
 		ohci1394_wake_it_ctx(s->host->ohci, s->iso_context);
 	}
-	else {
-		u32 syt, cycle_count;
-
-		cycle_count = reg_read(s->host->host->hostdata,
-				       OHCI1394_IsochronousCycleTimer) >> 12;
-		syt = (pl->packets[0].payload[1] >> 12) & 0x0f;
-		cycle_count = (cycle_count & ~0x0f) + 32 + syt;
-		if ((cycle_count & 0x1fff) >= 8000)
-			cycle_count = cycle_count - 8000 + 0x2000;
-
-		ohci1394_start_it_ctx(s->host->ohci, s->iso_context,
-				      pl->packets[0].db_bus, 3,
-				      cycle_count & 0x7fff);
-	}
+	else
+		stream_start_dma(s, pl);
 }
 
 static void stream_shift_packet_lists(struct stream *s)
@@ -430,17 +473,42 @@
 	f->integer = numerator / denominator;
 	f->numerator = numerator % denominator;
 	f->denominator = denominator;
-	f->counter = 0;
 }
 
-static int fraction_next_size(struct fraction *f)
+static __inline__ void fraction_add(struct fraction *dst,
+				    struct fraction *src1,
+				    struct fraction *src2)
+{
+	/* assert: src1->denominator == src2->denominator */
+
+	int sum, denom;
+
+	/* We use these two local variables to allow gcc to optimize
+	 * the division and the modulo into only one division. */
+
+	sum = src1->numerator + src2->numerator;
+	denom = src1->denominator;
+	dst->integer = src1->integer + src2->integer + sum / denom;
+	dst->numerator = sum % denom;
+	dst->denominator = denom;
+}
+
+static __inline__ void fraction_sub_int(struct fraction *dst,
+					struct fraction *src, int integer)
 {
-	return f->integer + ((f->counter + f->numerator) / f->denominator);
+	dst->integer = src->integer - integer;
+	dst->numerator = src->numerator;
+	dst->denominator = src->denominator;
 }
 
-static void fraction_inc(struct fraction *f)
+static __inline__ int fraction_floor(struct fraction *frac)
 {
-	f->counter = (f->counter + f->numerator) % f->denominator;
+	return frac->integer;
+}
+
+static __inline__ int fraction_ceil(struct fraction *frac)
+{
+	return frac->integer + (frac->numerator > 0 ? 1 : 0);
 }
 
 static void amdtp_irq_handler(int card, quadlet_t isoRecvIntEvent,
@@ -633,17 +701,33 @@
 	}
 }
 
+static void fill_payload_le16(struct stream *s, quadlet_t *data, int nevents)
+{
+	quadlet_t *event, sample, bits;
+	unsigned char *p;
+	int i, j;
+
+	for (i = 0, event = data; i < nevents; i++) {
+
+		for (j = 0; j < s->dimension; j++) {
+			p = buffer_get_bytes(s->input, 2);
+			sample = (p[1] << 16) | (p[0] << 8);
+			bits = get_header_bits(s, j, sample);
+			event[j] = cpu_to_be32((bits << 24) | sample);
+		}
+
+		event += s->dimension;
+		if (++s->iec958_frame_count == 192)
+			s->iec958_frame_count = 0;
+	}
+}
 
 static void fill_packet(struct stream *s, struct packet *packet, int nevents)
 {
-	int size, node_id, i, j;
-	quadlet_t *event;
-	unsigned char *p;
-	u32 control, sample, bits;
-	int syt_index, syt, next;
+	int syt_index, syt, size;
+	u32 control;
 
 	size = (nevents * s->dimension + 2) * sizeof(quadlet_t);
-	node_id = s->host->host->node_id & 0x3f;
 
 	/* Update DMA descriptors */
 	packet->db->payload_desc.status = 0;
@@ -656,41 +740,45 @@
 		(s->iso_channel << 8) | (TCODE_ISO_DATA << 4);
 	packet->db->header_desc.header[1] = size << 16;
 	
-	/* Fill cip header */
-	syt_index = s->dbc & (s->syt_interval - 1);
-	if (syt_index == 0 || syt_index + nevents > s->syt_interval) {
+	/* Calculate synchronization timestamp (syt). First we
+	 * determine syt_index, that is, the index in the packet of
+	 * the sample for which the timestamp is valid. */
+	syt_index = (s->syt_interval - s->dbc) & (s->syt_interval - 1);
+	if (syt_index < nevents) {
 		syt = ((atomic_read(&s->cycle_count) << 12) | 
-		       s->cycle_offset) & 0xffff;
-		next = fraction_next_size(&s->syt_fraction) + s->cycle_offset;
+		       s->cycle_offset.integer) & 0xffff;
+		fraction_add(&s->cycle_offset, 
+			     &s->cycle_offset, &s->ticks_per_syt_offset);
+
 		/* This next addition should be modulo 8000 (0x1f40),
 		 * but we only use the lower 4 bits of cycle_count, so
 		 * we dont need the modulo. */
-		atomic_add(next / 3072, &s->cycle_count);
-		s->cycle_offset = next % 3072;
-		fraction_inc(&s->syt_fraction);
+		atomic_add(s->cycle_offset.integer / 3072, &s->cycle_count);
+		s->cycle_offset.integer %= 3072;
 	}
-	else {
+	else
 		syt = 0xffff;
-		next = 0;
-	}
-	atomic_inc(&s->cycle_count2);
-
-	packet->payload[0] = cpu_to_be32((node_id << 24) | (s->dimension << 16) | s->dbc);
-	packet->payload[1] = cpu_to_be32((1 << 31) | (FMT_AMDTP << 24) | (s->fdf << 16) | syt);
-
-	/* Fill payload */
-	for (i = 0, event = &packet->payload[2]; i < nevents; i++) {
 
-		for (j = 0; j < s->dimension; j++) {
-			p = buffer_get_bytes(s->input, 2);
-			sample = (p[1] << 16) | (p[0] << 8);
-			bits = get_header_bits(s, j, sample);
-			event[j] = cpu_to_be32((bits << 24) | sample);
-		}
-
-		event += s->dimension;
-		if (++s->iec958_frame_count == 192)
-			s->iec958_frame_count = 0;
+	atomic_inc(&s->cycle_count2);
+	
+	/* Fill cip header */
+	packet->payload->eoh0 = 0;
+	packet->payload->sid = s->host->host->node_id & 0x3f;
+	packet->payload->dbs = s->dimension;
+	packet->payload->fn = 0;
+	packet->payload->qpc = 0;
+	packet->payload->sph = 0;
+	packet->payload->reserved = 0;
+	packet->payload->dbc = s->dbc;
+	packet->payload->eoh1 = 2;
+	packet->payload->fmt = FMT_AMDTP;
+	packet->payload->fdf = s->fdf;
+	packet->payload->syt = cpu_to_be16(syt);
+
+	switch (s->sample_format) {
+	case AMDTP_INPUT_LE16:
+		fill_payload_le16(s, packet->payload->data, nevents);
+		break;
 	}
 
 	s->dbc += nevents;
@@ -700,13 +788,44 @@
 {
 	struct packet *p;
 	int nevents;
+	struct fraction next;
+
+	/* The AMDTP specifies two transmission modes: blocking and
+	 * non-blocking.  In blocking mode you always transfer
+	 * syt_interval or zero samples, whereas in non-blocking mode
+	 * you send as many samples as you have available at transfer
+	 * time.
+	 *
+	 * The fraction samples_per_cycle specifies the number of
+	 * samples that become available per cycle.  We add this to
+	 * the fraction ready_samples, which specifies the number of
+	 * leftover samples from the previous transmission.  The sum,
+	 * stored in the fraction next, specifies the number of
+	 * samples available for transmission, and from this we
+	 * determine the number of samples to actually transmit.
+	 */
+
+	while (1) {
+		fraction_add(&next, &s->ready_samples, &s->samples_per_cycle);
+		if (s->mode == AMDTP_MODE_BLOCKING) {
+			if (fraction_floor(&next) >= s->syt_interval)
+				nevents = s->syt_interval;
+			else
+				nevents = 0;
+		}
+		else
+			nevents = fraction_floor(&next);
+
+		p = stream_current_packet(s);
+		if (s->input->length < nevents * s->dimension * 2 || p == NULL)
+			break;
 
-	while (nevents = fraction_next_size(&s->packet_size_fraction),
-	       p = stream_current_packet(s),
-	       nevents * s->dimension * 2 <= s->input->length && p != NULL) {
 		fill_packet(s, p, nevents);
-		fraction_inc(&s->packet_size_fraction);
 		stream_queue_packet(s);
+
+		/* Now that we have successfully queued the packet for
+		 * transmission, we update the fraction ready_samples. */
+		fraction_sub_int(&s->ready_samples, &next, nevents);
 	}
 }
 
@@ -714,9 +833,10 @@
 {
 	int max_nevents, max_packet_size, i;
 
-	max_nevents = s->packet_size_fraction.integer;
-	if (s->packet_size_fraction.numerator > 0)
-		max_nevents++;
+	if (s->mode == AMDTP_MODE_BLOCKING)
+		max_nevents = s->syt_interval;
+	else
+		max_nevents = fraction_ceil(&s->samples_per_cycle);
 
 	max_packet_size = max_nevents * s->dimension * 4 + 8;
 	s->packet_pool = pci_pool_create("packet pool", s->host->ohci->dev,
@@ -763,15 +883,20 @@
 		  plug->p2p_count, plug->channel);
 	s->iso_channel = plug->channel;
 	if (plug->p2p_count > 0) {
-		/* start streaming */
+		struct packet_list *pl;
+
+		pl = list_entry(s->dma_packet_lists.next, struct packet_list, link);
+		stream_start_dma(s, pl);
 	}
 	else {
-		/* stop streaming */
+		ohci1394_stop_it_ctx(s->host->ohci, s->iso_context, 0);
 	}
 }
 
 static int stream_configure(struct stream *s, int cmd, struct amdtp_ioctl *cfg)
 {
+	const int transfer_delay = 9000;
+
 	if (cfg->format <= AMDTP_FORMAT_IEC958_AC3)
 		s->format = cfg->format;
 	else
@@ -782,32 +907,59 @@
 		s->syt_interval = 8;
 		s->fdf = FDF_SFC_32KHZ;
 		s->iec958_rate_code = 0x0c;
-		s->rate = cfg->rate;
 		break;
 	case 44100:
 		s->syt_interval = 8;
 		s->fdf = FDF_SFC_44K1HZ;
 		s->iec958_rate_code = 0x00;
-		s->rate = cfg->rate;
 		break;
 	case 48000:
 		s->syt_interval = 8;
 		s->fdf = FDF_SFC_48KHZ;
 		s->iec958_rate_code = 0x04;
-		s->rate = cfg->rate;
 		break;
+	case 88200:
+		s->syt_interval = 16;
+		s->fdf = FDF_SFC_88K2HZ;
+		s->iec958_rate_code = 0x00;
+		break;
+	case 96000:
+		s->syt_interval = 16;
+		s->fdf = FDF_SFC_96KHZ;
+		s->iec958_rate_code = 0x00;
+		break;
+	case 176400:
+		s->syt_interval = 32;
+		s->fdf = FDF_SFC_176K4HZ;
+		s->iec958_rate_code = 0x00;
+		break;
+	case 192000:
+		s->syt_interval = 32;
+		s->fdf = FDF_SFC_192KHZ;
+		s->iec958_rate_code = 0x00;
+		break;
+
 	default:
 		return -EINVAL;
 	}
 
-	fraction_init(&s->packet_size_fraction, s->rate, 8000);
+	s->rate = cfg->rate;
+	fraction_init(&s->samples_per_cycle, s->rate, 8000);
+	fraction_init(&s->ready_samples, 0, 8000);
 
-	/* The syt_fraction is initialized to the number of ticks
-	 * between syt_interval events.  The number of ticks per
+	/* The ticks_per_syt_offset is initialized to the number of
+	 * ticks between syt_interval events.  The number of ticks per
 	 * second is 24.576e6, so the number of ticks between
 	 * syt_interval events is 24.576e6 * syt_interval / rate.
 	 */
-	fraction_init(&s->syt_fraction, 24576000 * s->syt_interval, s->rate);
+	fraction_init(&s->ticks_per_syt_offset,
+		      24576000 * s->syt_interval, s->rate);
+	fraction_init(&s->cycle_offset, (transfer_delay % 3072) * s->rate, s->rate);
+	atomic_set(&s->cycle_count, transfer_delay / 3072);
+	atomic_set(&s->cycle_count2, 0);
+
+	s->mode = cfg->mode;
+	s->sample_format = AMDTP_INPUT_LE16;
 
 	/* When using the AM824 raw subformat we can stream signals of
 	 * any dimension.  The IEC958 subformat, however, only
@@ -858,7 +1010,6 @@
 {
 	struct stream *s;
 	unsigned long flags;
-	const int transfer_delay = 8651; /* approx 352 us */
 
         s = kmalloc(sizeof(struct stream), SLAB_KERNEL);
         if (s == NULL)
@@ -873,10 +1024,6 @@
 		return NULL;
 	}
 
-	s->cycle_offset = transfer_delay % 3072;
-	atomic_set(&s->cycle_count, transfer_delay / 3072);
-	atomic_set(&s->cycle_count2, 0);
-
 	s->descriptor_pool = pci_pool_create("descriptor pool", host->ohci->dev,
 					     sizeof(struct descriptor_block),
 					     16, 0, SLAB_KERNEL);
@@ -920,7 +1067,7 @@
 	wait_event_interruptible(s->packet_list_wait, 
 				 list_empty(&s->dma_packet_lists));
 
-	ohci1394_stop_it_ctx(s->host->ohci, s->iso_context);
+	ohci1394_stop_it_ctx(s->host->ohci, s->iso_context, 1);
 	ohci1394_free_it_ctx(s->host->ohci, s->iso_context);
 
 	if (s->opcr != NULL)
@@ -996,8 +1143,8 @@
 
 	case AMDTP_IOC_PING:
 		HPSB_INFO("ping: offsetting timpestamps %ld ticks", arg);
-		new = s->cycle_offset + arg;
-		s->cycle_offset = new % 3072;
+		new = s->cycle_offset.integer + arg;
+		s->cycle_offset.integer = new % 3072;
 		atomic_add(new / 3072, &s->cycle_count);
 		return 0;
 
@@ -1044,11 +1191,11 @@
 
 static struct file_operations amdtp_fops =
 {
-	owner:		THIS_MODULE,
-	write:		amdtp_write,
-	ioctl:		amdtp_ioctl,
-	open:		amdtp_open,
-	release:	amdtp_release
+	.owner =	THIS_MODULE,
+	.write =	amdtp_write,
+	.ioctl =	amdtp_ioctl,
+	.open =		amdtp_open,
+	.release =	amdtp_release
 };
 
 /* IEEE1394 Subsystem functions */
@@ -1096,8 +1243,8 @@
 }
 
 static struct hpsb_highlevel_ops amdtp_highlevel_ops = {
-	add_host:	amdtp_add_host,
-	remove_host:	amdtp_remove_host,
+	.add_host =	amdtp_add_host,
+	.remove_host =	amdtp_remove_host,
 };
 
 /* Module interface */
diff -urN linux-2.4.19-rc3/drivers/ieee1394/amdtp.h linux-2.4.19-rc4/drivers/ieee1394/amdtp.h
--- linux-2.4.19-rc3/drivers/ieee1394/amdtp.h	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/amdtp.h	Wed Jul 31 15:10:18 2002
@@ -19,13 +19,24 @@
  * AMDTP_FORMAT_IEC958_AC3 will transmit the samples with the data bit
  * set, suitable for transmitting compressed AC-3 audio.
  *
- * The rate field specifies the transmission rate; supported values are
- * AMDTP_RATE_32KHZ, AMDTP_RATE_44K1HZ and AMDTP_RATE_48KHZ.
+ * The rate field specifies the transmission rate; supported values
+ * are 32000, 44100, 48000, 88200, 96000, 176400 and 192000.
  *
  * The dimension field specifies the dimension of the signal, that is,
  * the number of audio channels.  Only AMDTP_FORMAT_RAW supports
  * settings greater than 2.  
  *
+ * The mode field specifies which transmission mode to use. The AMDTP
+ * specifies two different transmission modes: blocking and
+ * non-blocking.  The blocking transmission mode always send a fixed
+ * number of samples, typically 8, 16 or 32.  To exactly match the
+ * transmission rate, the driver alternates between sending empty and
+ * non-empty packets.  In non-blocking mode, the driver transmits as
+ * small packets as possible.  For example, for a transmission rate of
+ * 44100Hz, the driver should send 5 41/80 samples in every cycle, but
+ * this is not possible so instead the driver alternates between
+ * sending 5 and 6 samples.
+ *
  * The last thing to specify is either the isochronous channel to use
  * or the output plug to connect to.  If you know what channel the
  * destination device will listen on, you can specify the channel
@@ -60,15 +71,20 @@
 };
 
 enum {
-	AMDTP_RATE_32KHZ,
-	AMDTP_RATE_44K1HZ,
-	AMDTP_RATE_48KHZ,
+	AMDTP_MODE_BLOCKING,
+	AMDTP_MODE_NON_BLOCKING,
+};
+
+enum {
+	AMDTP_INPUT_LE16,
+	AMDTP_INPUT_BE16,
 };
 
 struct amdtp_ioctl {
 	__u32 format;
 	__u32 rate;
 	__u32 dimension;
+	__u32 mode;
 	union { __u32 channel; __u32 plug; } u;
 };
 
diff -urN linux-2.4.19-rc3/drivers/ieee1394/cmp.c linux-2.4.19-rc4/drivers/ieee1394/cmp.c
--- linux-2.4.19-rc3/drivers/ieee1394/cmp.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/cmp.c	Wed Jul 31 15:10:18 2002
@@ -299,14 +299,14 @@
 
 
 static struct hpsb_highlevel_ops cmp_highlevel_ops = {
-	add_host:	cmp_add_host,
-	remove_host:	cmp_remove_host,
-        host_reset:	cmp_host_reset,
+	.add_host =	cmp_add_host,
+	.remove_host =	cmp_remove_host,
+        .host_reset =	cmp_host_reset,
 };
 
 static struct hpsb_address_ops pcr_ops = {
-        read: pcr_read,
-        lock: pcr_lock,
+	.read =	pcr_read,
+        .lock =	pcr_lock,
 };
 
 /* Module interface */
diff -urN linux-2.4.19-rc3/drivers/ieee1394/csr.c linux-2.4.19-rc4/drivers/ieee1394/csr.c
--- linux-2.4.19-rc3/drivers/ieee1394/csr.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/csr.c	Wed Jul 31 15:10:18 2002
@@ -402,23 +402,23 @@
 
 
 static struct hpsb_highlevel_ops csr_ops = {
-        add_host: add_host,
-        host_reset: host_reset,
+	.add_host =	add_host,
+        .host_reset =	host_reset,
 };
 
 
 static struct hpsb_address_ops map_ops = {
-        read: read_maps,
+        .read = read_maps,
 };
 
 static struct hpsb_address_ops fcp_ops = {
-        write: write_fcp,
+        .write = write_fcp,
 };
 
 static struct hpsb_address_ops reg_ops = {
-        read: read_regs,
-        write: write_regs,
-        lock: lock_regs,
+        .read = read_regs,
+        .write = write_regs,
+        .lock = lock_regs,
 };
 
 static struct hpsb_highlevel *hl;
diff -urN linux-2.4.19-rc3/drivers/ieee1394/dv1394-private.h linux-2.4.19-rc4/drivers/ieee1394/dv1394-private.h
--- linux-2.4.19-rc3/drivers/ieee1394/dv1394-private.h	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/dv1394-private.h	Wed Jul 31 15:10:18 2002
@@ -602,7 +602,7 @@
    calibrated against a Sony DSR-40 DVCAM deck */
 
 #define CIP_N_NTSC   68000000
-#define CIP_D_NTSC 1000000000
+#define CIP_D_NTSC 1068000000
 
 #define CIP_N_PAL  1
 #define CIP_D_PAL 16
diff -urN linux-2.4.19-rc3/drivers/ieee1394/dv1394.c linux-2.4.19-rc4/drivers/ieee1394/dv1394.c
--- linux-2.4.19-rc3/drivers/ieee1394/dv1394.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/dv1394.c	Wed Jul 31 15:10:18 2002
@@ -382,10 +382,10 @@
 		
 		/* is this an empty packet? */
 
-		if(video->cip_accum > video->cip_d) {
+		if(video->cip_accum > (video->cip_d - video->cip_n)) {
 			empty_packet = 1;
 			payload_size = 8;
-			video->cip_accum -= video->cip_d;
+			video->cip_accum -= (video->cip_d - video->cip_n);
 		} else {
 			payload_size = 488;
 			video->cip_accum += video->cip_n;
@@ -1467,7 +1467,7 @@
 }
 
 static struct vm_operations_struct dv1394_vm_ops = {
-	nopage: dv1394_nopage
+	.nopage = dv1394_nopage
 };
 
 /*
@@ -2547,15 +2547,15 @@
 
 static struct file_operations dv1394_fops=
 {
-	owner:		THIS_MODULE,
-	poll:           dv1394_poll,
-	ioctl:		dv1394_ioctl,
-	mmap:		dv1394_mmap,
-	open:		dv1394_open,
-	write:          dv1394_write,
-	read:           dv1394_read,
-	release:	dv1394_release,
-	fasync:         dv1394_fasync,
+	.owner =	THIS_MODULE,
+	.poll =         dv1394_poll,
+	.ioctl =	dv1394_ioctl,
+	.mmap =		dv1394_mmap,
+	.open =		dv1394_open,
+	.write =        dv1394_write,
+	.read =         dv1394_read,
+	.release =	dv1394_release,
+	.fasync =       dv1394_fasync,
 };
 
 
@@ -2764,8 +2764,10 @@
 		video->id |= mode;
 	else video->id |= 2 + mode;
 	
+#ifdef CONFIG_DEVFS_FS
 	if (dv1394_devfs_add_entry(video) < 0)
 			goto err_free;
+#endif
 
 	debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id);
 	
@@ -2788,7 +2790,9 @@
 		(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
 		(video->mode == MODE_RECEIVE ? "in" : "out")
 		);
+#ifdef CONFIG_DEVFS_FS
 	dv1394_devfs_del(buf);
+#endif
 #ifdef CONFIG_PROC_FS
 	dv1394_procfs_del(buf);
 #endif
@@ -2825,12 +2829,14 @@
 	spin_unlock_irqrestore(&dv1394_cards_lock, flags);
 
 	n = (video->id >> 2);
+#ifdef CONFIG_DEVFS_FS
 	snprintf(buf, sizeof(buf), "dv/host%d/NTSC", n);
 	dv1394_devfs_del(buf);
 	snprintf(buf, sizeof(buf), "dv/host%d/PAL", n);
 	dv1394_devfs_del(buf);
 	snprintf(buf, sizeof(buf), "dv/host%d", n);
 	dv1394_devfs_del(buf);
+#endif
 
 #ifdef CONFIG_PROC_FS
 	snprintf(buf, sizeof(buf), "dv/host%d/NTSC", n);
@@ -2867,6 +2873,7 @@
 }
 #endif
 
+#ifdef CONFIG_DEVFS_FS
 	devfs_entry = dv1394_devfs_find("dv");
 	if (devfs_entry != NULL) {
 		snprintf(buf, sizeof(buf), "host%d", ohci->id);
@@ -2874,6 +2881,7 @@
 		dv1394_devfs_add_dir("NTSC", devfs_entry, NULL);
 		dv1394_devfs_add_dir("PAL", devfs_entry, NULL);
 	}
+#endif
 	
 	dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
 	dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
@@ -3001,9 +3009,9 @@
 }
 
 static struct hpsb_highlevel_ops hl_ops = {
-	add_host:	dv1394_add_host,
-	remove_host:	dv1394_remove_host,
-	host_reset:     dv1394_host_reset,
+	.add_host =	dv1394_add_host,
+	.remove_host =	dv1394_remove_host,
+	.host_reset =   dv1394_host_reset,
 };
 
 
@@ -3018,7 +3026,9 @@
 {
 	hpsb_unregister_highlevel (hl_handle);
 	ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
+#ifdef CONFIG_DEVFS_FS
 	dv1394_devfs_del("dv");
+#endif
 #ifdef CONFIG_PROC_FS
 	dv1394_procfs_del("dv");
 #endif
@@ -3032,17 +3042,21 @@
 		return -EIO;
 	}
 
+#ifdef CONFIG_DEVFS_FS
 	if (dv1394_devfs_add_dir("dv", NULL, NULL) < 0) {
 		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/dv\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 		return -ENOMEM;
 	}
+#endif
 
 #ifdef CONFIG_PROC_FS
 	if (dv1394_procfs_add_dir("dv",NULL,NULL) < 0) {
 		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/dv\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
+#ifdef CONFIG_DEVFS_FS
 		dv1394_devfs_del("dv");
+#endif
 		return -ENOMEM;
 	}
 #endif
@@ -3051,7 +3065,9 @@
 	if (hl_handle == NULL) {
 		printk(KERN_ERR "dv1394: hpsb_register_highlevel failed\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
+#ifdef CONFIG_DEVFS_FS
 		dv1394_devfs_del("dv");
+#endif
 #ifdef CONFIG_PROC_FS
 		dv1394_procfs_del("dv");
 #endif
diff -urN linux-2.4.19-rc3/drivers/ieee1394/eth1394.c linux-2.4.19-rc4/drivers/ieee1394/eth1394.c
--- linux-2.4.19-rc3/drivers/ieee1394/eth1394.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/eth1394.c	Wed Jul 31 15:10:18 2002
@@ -702,14 +702,14 @@
 
 /* Function for incoming 1394 packets */
 static struct hpsb_address_ops addr_ops = {
-	write:		ether1394_write,
+	.write =	ether1394_write,
 };
 
 /* Ieee1394 highlevel driver functions */
 static struct hpsb_highlevel_ops hl_ops = {
-	add_host:	ether1394_add_host,
-	remove_host:	ether1394_remove_host,
-	host_reset:	ether1394_host_reset,
+	.add_host =	ether1394_add_host,
+	.remove_host =	ether1394_remove_host,
+	.host_reset =	ether1394_host_reset,
 };
 
 static int __init ether1394_init_module (void)
diff -urN linux-2.4.19-rc3/drivers/ieee1394/hosts.c linux-2.4.19-rc4/drivers/ieee1394/hosts.c
--- linux-2.4.19-rc3/drivers/ieee1394/hosts.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/hosts.c	Wed Jul 31 15:10:18 2002
@@ -39,8 +39,8 @@
 }
 
 static struct hpsb_host_operations dummy_ops = {
-        transmit_packet:  dummy_transmit_packet,
-        devctl:           dummy_devctl
+        .transmit_packet = dummy_transmit_packet,
+        .devctl =          dummy_devctl
 };
 
 /**
diff -urN linux-2.4.19-rc3/drivers/ieee1394/ieee1394_core.c linux-2.4.19-rc4/drivers/ieee1394/ieee1394_core.c
--- linux-2.4.19-rc3/drivers/ieee1394/ieee1394_core.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/ieee1394_core.c	Wed Jul 31 15:10:18 2002
@@ -811,8 +811,8 @@
 static int ieee1394_dispatch_open(struct inode *inode, struct file *file);
 
 static struct file_operations ieee1394_chardev_ops = {
-	owner:	THIS_MODULE,
-	open:	ieee1394_dispatch_open,
+	.owner =THIS_MODULE,
+	.open =	ieee1394_dispatch_open,
 };
 
 devfs_handle_t ieee1394_devfs_handle;
diff -urN linux-2.4.19-rc3/drivers/ieee1394/nodemgr.c linux-2.4.19-rc4/drivers/ieee1394/nodemgr.c
--- linux-2.4.19-rc3/drivers/ieee1394/nodemgr.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/nodemgr.c	Wed Jul 31 15:10:18 2002
@@ -45,18 +45,21 @@
  * a way that's easy to parse by the protocol interface.
  */
 
-static LIST_HEAD(node_list);
-static rwlock_t node_lock = RW_LOCK_UNLOCKED;
+/* The nodemgr maintains a number of data structures: the node list,
+ * the driver list, unit directory list and the host info list.  The
+ * first three lists are accessed from process context only: /proc
+ * readers, insmod and rmmod, and the nodemgr thread.  Access to these
+ * lists are serialized by means of the nodemgr_serialize mutex, which
+ * must be taken before accessing the structures and released
+ * afterwards.  The host info list is only accessed during insmod,
+ * rmmod and from interrupt and allways only for a short period of
+ * time, so a spinlock is used to protect this list.
+ */
 
+static DECLARE_MUTEX(nodemgr_serialize);
+static LIST_HEAD(node_list);
 static LIST_HEAD(driver_list);
-static rwlock_t driver_lock = RW_LOCK_UNLOCKED;
-
-/* The rwlock unit_directory_lock is always held when manipulating the
- * global unit_directory_list, but this also protects access to the
- * lists of unit directories stored in the protocol drivers.
- */
 static LIST_HEAD(unit_directory_list);
-static rwlock_t unit_directory_lock = RW_LOCK_UNLOCKED;
 
 static LIST_HEAD(host_info_list);
 static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
@@ -84,6 +87,9 @@
 	int len;
 	char *out = page;
 
+	if (down_interruptible(&nodemgr_serialize))
+		return -EINTR;
+
 	list_for_each(lh, &node_list) {
 		struct list_head *l;
 		int ud_count = 0;
@@ -148,6 +154,8 @@
 
 	}
 
+	up(&nodemgr_serialize);
+
 	len = out - page;
 	len -= off;
 	if (len < count) {
@@ -306,7 +314,6 @@
 					      nodeid_t nodeid, unsigned int generation)
 {
         struct node_entry *ne;
-        unsigned long flags;
 
 	ne = nodemgr_scan_root_directory (host, nodeid, generation);
         if (!ne) return NULL;
@@ -318,9 +325,7 @@
         ne->guid = guid;
 	ne->generation = generation;
 
-        write_lock_irqsave(&node_lock, flags);
         list_add_tail(&ne->list, &node_list);
-        write_unlock_irqrestore(&node_lock, flags);
 
 	nodemgr_process_config_rom (ne, busoptions);
 
@@ -758,11 +763,9 @@
 
 void hpsb_release_unit_directory(struct unit_directory *ud)
 {
-	unsigned long flags;
-
-	write_lock_irqsave(&unit_directory_lock, flags);
+	down(&nodemgr_serialize);
 	nodemgr_release_unit_directory(ud);
-	write_unlock_irqrestore(&unit_directory_lock, flags);
+	up(&nodemgr_serialize);
 }
 
 static void nodemgr_free_unit_directories(struct node_entry *ne)
@@ -852,13 +855,12 @@
 {
 	struct unit_directory *ud;
 	struct list_head *lh;
-	unsigned long flags;
 
-        write_lock_irqsave(&driver_lock, flags);
+	if (down_interruptible(&nodemgr_serialize))
+		return -EINTR;
+
 	list_add_tail(&driver->list, &driver_list);
-	write_unlock_irqrestore(&driver_lock, flags);
 
-	write_lock_irqsave(&unit_directory_lock, flags);
 	INIT_LIST_HEAD(&driver->unit_directories);
 	lh = unit_directory_list.next;
 	while (lh != &unit_directory_list) {
@@ -867,7 +869,8 @@
 		if (nodemgr_match_driver(driver, ud) && driver->probe(ud) == 0)
 			nodemgr_claim_unit_directory(ud, driver);
 	}
-	write_unlock_irqrestore(&unit_directory_lock, flags);
+
+	up(&nodemgr_serialize);
 
 	/*
 	 * Right now registration always succeeds, but maybe we should
@@ -881,13 +884,10 @@
 {
 	struct list_head *lh;
 	struct unit_directory *ud;
-	unsigned long flags;
 
-        write_lock_irqsave(&driver_lock, flags);
-	list_del(&driver->list);
-	write_unlock_irqrestore(&driver_lock, flags);
+	down(&nodemgr_serialize);
 
-	write_lock_irqsave(&unit_directory_lock, flags);
+	list_del(&driver->list);
 	lh = driver->unit_directories.next;
 	while (lh != &driver->unit_directories) {
 		ud = list_entry(lh, struct unit_directory, driver_list);
@@ -896,14 +896,13 @@
 			ud->driver->disconnect(ud);
 		nodemgr_release_unit_directory(ud);
 	}
-	write_unlock_irqrestore(&unit_directory_lock, flags);
+
+	up(&nodemgr_serialize);
 }
 
 static void nodemgr_process_config_rom(struct node_entry *ne, 
 				       quadlet_t busoptions)
 {
-	unsigned long flags;
-
 	ne->busopt.irmc		= (busoptions >> 31) & 1;
 	ne->busopt.cmc		= (busoptions >> 30) & 1;
 	ne->busopt.isc		= (busoptions >> 29) & 1;
@@ -929,11 +928,9 @@
 	 * thing.  If this was a new device, the call to
 	 * nodemgr_disconnect_drivers is a no-op and all is well.
 	 */
-	write_lock_irqsave(&unit_directory_lock, flags);
 	nodemgr_free_unit_directories(ne);
 	nodemgr_process_root_directory(ne);
 	nodemgr_bind_drivers(ne);
-	write_unlock_irqrestore(&unit_directory_lock, flags);
 }
 
 /*
@@ -1032,16 +1029,12 @@
 
 static void nodemgr_remove_node(struct node_entry *ne)
 {
-	unsigned long flags;
-
 	HPSB_DEBUG("%s removed: Node[" NODE_BUS_FMT "]  GUID[%016Lx]  [%s]",
 		   (ne->host->node_id == ne->nodeid) ? "Host" : "Device",
 		   NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid,
 		   ne->vendor_name ?: "Unknown");
 
-	write_lock_irqsave(&unit_directory_lock, flags);
 	nodemgr_free_unit_directories(ne);
-	write_unlock_irqrestore(&unit_directory_lock, flags);
 	list_del(&ne->list);
 	kfree(ne);
 
@@ -1077,7 +1070,7 @@
 	}
 
 	guid = ((u64)buffer[3] << 32) | buffer[4];
-	ne = hpsb_guid_get_entry(guid);
+	ne = find_entry_by_guid(guid);
 
 	if (!ne)
 		nodemgr_create_node(guid, buffer[2], host, nodeid, generation);
@@ -1089,13 +1082,11 @@
 
 static void nodemgr_node_probe_cleanup(struct hpsb_host *host, unsigned int generation)
 {
-	unsigned long flags;
 	struct list_head *lh, *next;
 	struct node_entry *ne;
 
 	/* Now check to see if we have any nodes that aren't referenced
 	 * any longer.  */
-	write_lock_irqsave(&node_lock, flags);
 	list_for_each_safe(lh, next, &node_list) {
 		ne = list_entry(lh, struct node_entry, list);
 
@@ -1110,7 +1101,6 @@
 		if (ne->generation != generation)
 			nodemgr_remove_node(ne);
 	}
-	write_unlock_irqrestore(&node_lock, flags);
 
 	return;
 }
@@ -1169,12 +1159,14 @@
 	daemonize();
 
 	strcpy(current->comm, "knodemgrd");
-
+	
 	/* Sit and wait for a signal to probe the nodes on the bus. This
 	 * happens when we get a bus reset. */
-	while (!down_interruptible(&hi->reset_sem))
+	while (!down_interruptible(&hi->reset_sem) &&
+	       !down_interruptible(&nodemgr_serialize)) {
 		nodemgr_node_probe(hi->host);
-
+		up(&nodemgr_serialize);
+	}
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 	HPSB_DEBUG ("NodeMgr: Exiting thread for %s", hi->host->driver->name);
 #endif
@@ -1184,24 +1176,22 @@
 
 struct node_entry *hpsb_guid_get_entry(u64 guid)
 {
-        unsigned long flags;
         struct node_entry *ne;
 
-        read_lock_irqsave(&node_lock, flags);
+	down(&nodemgr_serialize);
         ne = find_entry_by_guid(guid);
-        read_unlock_irqrestore(&node_lock, flags);
+	up(&nodemgr_serialize);
 
         return ne;
 }
 
 struct node_entry *hpsb_nodeid_get_entry(nodeid_t nodeid)
 {
-	unsigned long flags;
 	struct node_entry *ne;
 
-	read_lock_irqsave(&node_lock, flags);
+	down(&nodemgr_serialize);
 	ne = find_entry_by_nodeid(nodeid);
-	read_unlock_irqrestore(&node_lock, flags);
+	up(&nodemgr_serialize);
 
 	return ne;
 }
@@ -1309,17 +1299,14 @@
 		}
 	}
 
-	if (hi == NULL) {
-		HPSB_ERR ("NodeMgr: could not process reset of non-existent host");
-		goto done_reset_host;
-	}
-
+	if (hi != NULL)
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 	HPSB_DEBUG ("NodeMgr: Processing host reset for %s", host->driver->name);
 #endif
-	up(&hi->reset_sem);
+		up(&hi->reset_sem);
+	else
+		HPSB_ERR ("NodeMgr: could not process reset of non-existent host");
 
-done_reset_host:
 	spin_unlock_irqrestore (&host_info_lock, flags);
 
 	return;
@@ -1341,38 +1328,39 @@
 			break;
 		}
 	}
-
-	if (!hi)
-		HPSB_ERR ("NodeMgr: host %s does not exist, cannot remove",
-			  host->driver->name);
 	spin_unlock_irqrestore (&host_info_lock, flags);
 
+	if (hi) {
+		if (hi->pid >= 0) {
+			kill_proc(hi->pid, SIGTERM, 1);
+			wait_for_completion(&hi->exited);
+		}
+		kfree(hi);
+	}
+	else
+		HPSB_ERR("NodeMgr: host %s does not exist, cannot remove",
+			 host->driver->name);
+
+	down(&nodemgr_serialize);
+
 	/* Even if we fail the host_info part, remove all the node
 	 * entries.  */
-	write_lock_irqsave(&node_lock, flags);
 	list_for_each_safe(lh, next, &node_list) {
 		ne = list_entry(lh, struct node_entry, list);
 
 		if (ne->host == host)
 			nodemgr_remove_node(ne);
 	}
-	write_unlock_irqrestore(&node_lock, flags);
 
-	if (hi) {
-		if (hi->pid >= 0) {
-			kill_proc(hi->pid, SIGTERM, 1);
-			wait_for_completion(&hi->exited);
-		}
-		kfree(hi);
-	}
+	up(&nodemgr_serialize);
 
 	return;
 }
 
 static struct hpsb_highlevel_ops nodemgr_ops = {
-	add_host:	nodemgr_add_host,
-	host_reset:	nodemgr_host_reset,
-	remove_host:	nodemgr_remove_host,
+	.add_host =	nodemgr_add_host,
+	.host_reset =	nodemgr_host_reset,
+	.remove_host =	nodemgr_remove_host,
 };
 
 static struct hpsb_highlevel *hl;
diff -urN linux-2.4.19-rc3/drivers/ieee1394/ohci1394.c linux-2.4.19-rc4/drivers/ieee1394/ohci1394.c
--- linux-2.4.19-rc3/drivers/ieee1394/ohci1394.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/ohci1394.c	Wed Jul 31 15:10:18 2002
@@ -154,7 +154,7 @@
 printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 515 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 530 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 MODULE_PARM(attempt_root,"i");
@@ -2029,10 +2029,10 @@
 }
 
 static struct hpsb_host_operations ohci1394_ops = {
-	get_rom:		ohci_get_rom,
-	transmit_packet:	ohci_transmit,
-	devctl:			ohci_devctl,
-	hw_csr_reg:		ohci_hw_csr_reg,
+	.get_rom =		ohci_get_rom,
+	.transmit_packet =	ohci_transmit,
+	.devctl =		ohci_devctl,
+	.hw_csr_reg =		ohci_hw_csr_reg,
 };
 
 static struct hpsb_host_driver *ohci1394_driver;
@@ -2308,12 +2308,12 @@
 
 static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
 	{
-		class: 		PCI_CLASS_FIREWIRE_OHCI,
-		class_mask: 	0x00ffffff,
-		vendor:		PCI_ANY_ID,
-		device:		PCI_ANY_ID,
-		subvendor:	PCI_ANY_ID,
-		subdevice:	PCI_ANY_ID,
+		.class = 		PCI_CLASS_FIREWIRE_OHCI,
+		.class_mask = 	0x00ffffff,
+		.vendor =		PCI_ANY_ID,
+		.device =		PCI_ANY_ID,
+		.subvendor =	PCI_ANY_ID,
+		.subdevice =	PCI_ANY_ID,
 	},
 	{ 0, },
 };
@@ -2321,10 +2321,10 @@
 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
 
 static struct pci_driver ohci1394_pci_driver = {
-	name:		OHCI1394_DRIVER_NAME,
-	id_table:	ohci1394_pci_tbl,
-	probe:		ohci1394_pci_probe,
-	remove:		ohci1394_pci_remove,
+	.name =		OHCI1394_DRIVER_NAME,
+	.id_table =	ohci1394_pci_tbl,
+	.probe =	ohci1394_pci_probe,
+	.remove =	ohci1394_pci_remove,
 };
 
 
diff -urN linux-2.4.19-rc3/drivers/ieee1394/pcilynx.c linux-2.4.19-rc4/drivers/ieee1394/pcilynx.c
--- linux-2.4.19-rc3/drivers/ieee1394/pcilynx.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/pcilynx.c	Wed Jul 31 15:10:18 2002
@@ -693,13 +693,13 @@
 
 
 static struct file_operations aux_ops = {
-	owner:		THIS_MODULE,
-        read:           mem_read,
-        write:          mem_write,
-        poll:           aux_poll,
-        llseek:         mem_llseek,
-        open:           mem_open,
-        release:        mem_release,
+	.owner =	THIS_MODULE,
+        .read =         mem_read,
+        .write =        mem_write,
+        .poll =         aux_poll,
+        .llseek =       mem_llseek,
+        .open =         mem_open,
+        .release =      mem_release,
 };
 
 
@@ -1682,25 +1682,25 @@
 
 static struct pci_device_id pci_table[] __devinitdata = {
 	{
-                vendor:     PCI_VENDOR_ID_TI,
-                device:     PCI_DEVICE_ID_TI_PCILYNX,
-                subvendor:  PCI_ANY_ID,
-                subdevice:  PCI_ANY_ID,
+                .vendor =    PCI_VENDOR_ID_TI,
+                .device =    PCI_DEVICE_ID_TI_PCILYNX,
+                .subvendor = PCI_ANY_ID,
+                .subdevice = PCI_ANY_ID,
 	},
 	{ }			/* Terminating entry */
 };
 
 static struct pci_driver lynx_pci_driver = {
-        name:      PCILYNX_DRIVER_NAME,
-        id_table:  pci_table,
-        probe:     add_card,
-        remove:    __devexit_p(remove_card),
+        .name =     PCILYNX_DRIVER_NAME,
+        .id_table = pci_table,
+        .probe =    add_card,
+        .remove =   __devexit_p(remove_card),
 };
 
 static struct hpsb_host_operations lynx_ops = {
-        get_rom:          get_lynx_rom,
-        transmit_packet:  lynx_transmit,
-        devctl:           lynx_devctl,
+        .get_rom =         get_lynx_rom,
+        .transmit_packet = lynx_transmit,
+        .devctl =          lynx_devctl,
 };
 
 MODULE_AUTHOR("Andreas E. Bombe <andreas.bombe@munich.netsurf.de>");
diff -urN linux-2.4.19-rc3/drivers/ieee1394/raw1394.c linux-2.4.19-rc4/drivers/ieee1394/raw1394.c
--- linux-2.4.19-rc3/drivers/ieee1394/raw1394.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/raw1394.c	Wed Jul 31 15:10:18 2002
@@ -985,20 +985,20 @@
 }
 
 static struct hpsb_highlevel_ops hl_ops = {
-        add_host:     add_host,
-        remove_host:  remove_host,
-        host_reset:   host_reset,
-        iso_receive:  iso_receive,
-        fcp_request:  fcp_request,
+        .add_host =    add_host,
+        .remove_host = remove_host,
+        .host_reset =  host_reset,
+        .iso_receive = iso_receive,
+        .fcp_request = fcp_request,
 };
 
 static struct file_operations file_ops = {
-	owner:		THIS_MODULE,
-        read:		raw1394_read, 
-        write:		raw1394_write, 
-        poll:		raw1394_poll, 
-        open:		raw1394_open, 
-        release:	raw1394_release, 
+	.owner =	THIS_MODULE,
+        .read =		raw1394_read, 
+        .write =	raw1394_write, 
+        .poll =		raw1394_poll, 
+        .open =		raw1394_open, 
+        .release =	raw1394_release, 
 };
 
 static int __init init_raw1394(void)
diff -urN linux-2.4.19-rc3/drivers/ieee1394/sbp2.c linux-2.4.19-rc4/drivers/ieee1394/sbp2.c
--- linux-2.4.19-rc3/drivers/ieee1394/sbp2.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/sbp2.c	Wed Jul 31 15:10:18 2002
@@ -320,6 +320,7 @@
 #include <linux/blk.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/blk.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -350,7 +351,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-	"$Rev: 515 $ James Goodwin <jamesg@filanet.com>";
+	"$Rev: 530 $ James Goodwin <jamesg@filanet.com>";
 
 /*
  * Module load parameter definitions
@@ -422,16 +423,25 @@
 MODULE_PARM_DESC(sbp2_exclusive_login, "Exclusive login to sbp2 device (default = 1)");
 static int sbp2_exclusive_login = 1;
 
+/*
+ * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on if your sbp2 device
+ * is not properly handling the SCSI inquiry command. This hack makes the inquiry look more
+ * like a typical MS Windows inquiry.
+ */
+MODULE_PARM(sbp2_force_inquiry_hack,"i");
+MODULE_PARM_DESC(sbp2_force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
+static int sbp2_force_inquiry_hack = 0;
+
 
 /*
  * Export information about protocols/devices supported by this driver.
  */
 static struct ieee1394_device_id sbp2_id_table[] = {
 	{
-		match_flags:  IEEE1394_MATCH_SPECIFIER_ID |
+		.match_flags =IEEE1394_MATCH_SPECIFIER_ID |
 		              IEEE1394_MATCH_VERSION,
-		specifier_id: SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
-		version:      SBP2_SW_VERSION_ENTRY & 0xffffff
+		.specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
+		.version =    SBP2_SW_VERSION_ENTRY & 0xffffff
 	},
 	{ }
 };
@@ -506,14 +516,6 @@
 #endif
 
 /*
- * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on if your sbp2 device
- * is not properly handling the SCSI inquiry command. This hack makes the inquiry look more 
- * like a typical MS Windows inquiry.
- */
-
-/* #define SBP2_FORCE_36_BYTE_INQUIRY */
-
-/*
  * Globals
  */
 
@@ -526,29 +528,35 @@
 static struct hpsb_highlevel *sbp2_hl_handle = NULL;
 
 static struct hpsb_highlevel_ops sbp2_hl_ops = {
-	add_host:	sbp2_add_host,
-	remove_host:	sbp2_remove_host,
+	.add_host =	sbp2_add_host,
+	.remove_host =	sbp2_remove_host,
 };
 
 static struct hpsb_address_ops sbp2_ops = {
-	write: sbp2_handle_status_write
+	.write = sbp2_handle_status_write
 };
 
 #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
 static struct hpsb_address_ops sbp2_physdma_ops = {
-        read: sbp2_handle_physdma_read,
-        write: sbp2_handle_physdma_write,
+        .read = sbp2_handle_physdma_read,
+        .write = sbp2_handle_physdma_write,
 };
 #endif
 
 static struct hpsb_protocol_driver sbp2_driver = {
-	name:		"SBP2 Driver",
-	id_table: 	sbp2_id_table,
-	probe: 		sbp2_probe,
-	disconnect: 	sbp2_disconnect,
-	update: 	sbp2_update
+	.name =		"SBP2 Driver",
+	.id_table = 	sbp2_id_table,
+	.probe = 		sbp2_probe,
+	.disconnect = 	sbp2_disconnect,
+	.update = 	sbp2_update
 };
 
+/* List of device firmware's that require a forced 36 byte inquiry. Note
+ * the final 0x0 needs to be there for denoting end of list.  */
+static u32 sbp2_broken_inquiry_list[] = {
+	0x00002800,	/* Stefan Richter <richtest@bauwesen.tu-cottbus.de> */
+	0x0
+};
 
 /**************************************
  * General utility functions
@@ -1904,27 +1912,58 @@
 			break;
 
 		case SBP2_FIRMWARE_REVISION_KEY:
-			/*
-			 * Firmware revision (used to find broken
-			 * devices). If the vendor id is 0xa0b8
-			 * (Symbios vendor id), then we have a
-			 * bridge with 128KB max transfer size
-			 * limitation.
-			 */
+			/* Firmware revision */
 			scsi_id->sbp2_firmware_revision
 				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_firmware_revision = %x",
 				   (unsigned int) scsi_id->sbp2_firmware_revision);
-			if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
-			    SBP2_128KB_BROKEN_FIRMWARE) {
-				SBP2_WARN("warning: Bridge chipset supports 128KB max transfer size");
-			}
 			break;
 
 		default:
 			break;
 		}
 	}
+
+	/* This is the start of our broken device checking. We try to hack
+	 * around oddities and known defects.  */
+	scsi_id->workarounds = 0x0;
+
+	/* If the vendor id is 0xa0b8 (Symbios vendor id), then we have a
+	 * bridge with 128KB max transfer size limitation. For sanity, we
+	 * only voice this when the current sbp2_max_sectors setting
+	 * exceeds the 128k limit. By default, that is not the case.
+	 *
+	 * It would be really nice if we could detect this before the scsi
+	 * host gets initialized. That way we can down-force the
+	 * sbp2_max_sectors to account for it. That is not currently
+	 * possible.  */
+	if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
+			SBP2_128KB_BROKEN_FIRMWARE &&
+			(sbp2_max_sectors * 512) > (128 * 1024)) {
+		SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.",
+				NODE_BUS_ARGS(scsi_id->ne->nodeid));
+		SBP2_WARN("WARNING: Current sbp2_max_sectors setting is larger than 128KB (%d sectors)!",
+				sbp2_max_sectors);
+		scsi_id->workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER;
+	}
+
+	/* Check for a blacklisted set of devices that require us to force
+	 * a 36 byte host inquiry. This can be overriden as a module param
+	 * (to force all hosts).
+	 *
+	 * XXX If this does not detect your firmware as being defective,
+	 * but using the sbp2_force_inquiry_hack allows your device to
+	 * work, please submit the value of your firmware revision to the
+	 * linux1394-devel mailing list.  */
+	for (i = 0; sbp2_broken_inquiry_list[i]; i++) {
+		if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
+				sbp2_broken_inquiry_list[i]) {
+			SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround",
+					NODE_BUS_ARGS(scsi_id->ne->nodeid));
+			scsi_id->workarounds |= SBP2_BREAKAGE_INQUIRY_HACK;
+			break; // No need to continue.
+		}
+	}
 }
 
 /*
@@ -2401,11 +2440,10 @@
 	 * reject this inquiry command. Fix the request_bufflen. 
 	 */
 	if (*cmd == INQUIRY) {
-#ifdef SBP2_FORCE_36_BYTE_INQUIRY
-		request_bufflen = cmd[4] = 0x24;
-#else
-		request_bufflen = cmd[4];
-#endif
+		if (sbp2_force_inquiry_hack || scsi_id->workarounds & SBP2_BREAKAGE_INQUIRY_HACK)
+			request_bufflen = cmd[4] = 0x24;
+		else
+			request_bufflen = cmd[4];
 	}
 
 	/*
@@ -3133,7 +3171,14 @@
 	 * host controller currently registered, and for each of those
 	 * we register a scsi host with the scsi stack.
 	 */
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	spin_unlock_irq(&io_request_lock);
 	sbp2_init();
+	spin_lock_irq(&io_request_lock);
+#else
+	sbp2_init();
+#endif
 
 	/* We return the number of hosts registered. */
 	return scsi_driver_template.present;
@@ -3179,23 +3224,23 @@
 
 /* SCSI host template */
 static Scsi_Host_Template scsi_driver_template = {
-	name:			"IEEE-1394 SBP-2 protocol driver",
-	info:			sbp2scsi_info,
-	detect:			sbp2scsi_detect,
-	queuecommand:		sbp2scsi_queuecommand,
-	eh_abort_handler:	sbp2scsi_abort,
-	eh_device_reset_handler:sbp2scsi_reset,
-	eh_bus_reset_handler:	sbp2scsi_reset,
-	eh_host_reset_handler:	sbp2scsi_reset,
-	bios_param:		sbp2scsi_biosparam,
-	this_id:		-1,
-	sg_tablesize:		SBP2_MAX_SG_ELEMENTS,
-	use_clustering:		SBP2_CLUSTERING,
+	.name =			"IEEE-1394 SBP-2 protocol driver",
+	.info =			sbp2scsi_info,
+	.detect =		sbp2scsi_detect,
+	.queuecommand =		sbp2scsi_queuecommand,
+	.eh_abort_handler =	sbp2scsi_abort,
+	.eh_device_reset_handler =sbp2scsi_reset,
+	.eh_bus_reset_handler =	sbp2scsi_reset,
+	.eh_host_reset_handler =sbp2scsi_reset,
+	.bios_param =		sbp2scsi_biosparam,
+	.this_id =		-1,
+	.sg_tablesize =		SBP2_MAX_SG_ELEMENTS,
+	.use_clustering =	SBP2_CLUSTERING,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	use_new_eh_code:	TRUE,
+	.use_new_eh_code =	TRUE,
 #endif
-	emulated:		1,
-	proc_name:	SBP2_DEVICE_NAME,
+	.emulated =		1,
+	.proc_name =	SBP2_DEVICE_NAME,
 };
 
 static int sbp2_module_init(void)
diff -urN linux-2.4.19-rc3/drivers/ieee1394/sbp2.h linux-2.4.19-rc4/drivers/ieee1394/sbp2.h
--- linux-2.4.19-rc3/drivers/ieee1394/sbp2.h	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/sbp2.h	Wed Jul 31 15:10:18 2002
@@ -357,6 +357,10 @@
 
 };
 
+/* A list of flags for detected oddities and brokeness. */
+#define SBP2_BREAKAGE_128K_MAX_TRANSFER		0x1
+#define SBP2_BREAKAGE_INQUIRY_HACK		0x2
+
 /*
  * Information needed on a per scsi id basis (one for each sbp2 device)
  */
@@ -412,6 +416,9 @@
 
 	/* Node entry, as retrieved from NodeMgr entries */
 	struct node_entry *ne;
+
+	/* Device specific workarounds/brokeness */
+	u32 workarounds;
 };
 
 /*
diff -urN linux-2.4.19-rc3/drivers/ieee1394/video1394.c linux-2.4.19-rc4/drivers/ieee1394/video1394.c
--- linux-2.4.19-rc3/drivers/ieee1394/video1394.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/ieee1394/video1394.c	Wed Jul 31 15:10:18 2002
@@ -1368,11 +1368,11 @@
 
 static struct file_operations video1394_fops=
 {
-	owner:		THIS_MODULE,
-	ioctl:		video1394_ioctl,
-	mmap:		video1394_mmap,
-	open:		video1394_open,
-	release:	video1394_release
+	.owner =	THIS_MODULE,
+	.ioctl =	video1394_ioctl,
+	.mmap =		video1394_mmap,
+	.open =		video1394_open,
+	.release =	video1394_release
 };
 
 static int video1394_init(struct ti_ohci *ohci)
@@ -1460,8 +1460,8 @@
 }
 
 static struct hpsb_highlevel_ops hl_ops = {
-	add_host:	video1394_add_host,
-	remove_host:	video1394_remove_host,
+	.add_host =	video1394_add_host,
+	.remove_host =	video1394_remove_host,
 };
 
 MODULE_AUTHOR("Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>");
diff -urN linux-2.4.19-rc3/drivers/media/video/stradis.c linux-2.4.19-rc4/drivers/media/video/stradis.c
--- linux-2.4.19-rc3/drivers/media/video/stradis.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/media/video/stradis.c	Wed Jul 31 15:10:19 2002
@@ -1454,6 +1454,9 @@
 				if (copy_from_user(saa->dmavid2, vw.clips,
 						   VIDEO_CLIPMAP_SIZE))
 					return -EFAULT;
+			}
+			else if (vw.clipcount > 16384) {
+				return -EINVAL;
 			} else if (vw.clipcount > 0) {
 				if ((vcp = vmalloc(sizeof(struct video_clip) *
 					        (vw.clipcount))) == NULL)
diff -urN linux-2.4.19-rc3/drivers/net/Config.in linux-2.4.19-rc4/drivers/net/Config.in
--- linux-2.4.19-rc3/drivers/net/Config.in	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/net/Config.in	Wed Jul 31 15:10:19 2002
@@ -223,7 +223,7 @@
       tristate '  Baget AMD LANCE support' CONFIG_BAGETLANCE
    fi
    if [ "$CONFIG_NEC_OSPREY" = "y" ]; then
-      bool '  Memory-mapped onboard NE2000-compatible ethernet' CONFIG_NE2000
+      tristate '  Memory-mapped onboard NE2000-compatible ethernet' CONFIG_NE2000
    fi
 fi
 
diff -urN linux-2.4.19-rc3/drivers/net/ewrk3.c linux-2.4.19-rc4/drivers/net/ewrk3.c
--- linux-2.4.19-rc3/drivers/net/ewrk3.c	Wed Jul 31 15:10:13 2002
+++ linux-2.4.19-rc4/drivers/net/ewrk3.c	Wed Jul 31 15:10:19 2002
@@ -1711,6 +1711,11 @@
 		break;
 	case EWRK3_SET_MCA:	/* Set a multicast address */
 		if (capable(CAP_NET_ADMIN)) {
+			if (ioc->len > 1024)
+			{
+				status = -EINVAL;
+				break;
+			}
 			if (copy_from_user(tmp->addr, ioc->data, ETH_ALEN * ioc->len)) {
 				status = -EFAULT;
 				break;
diff -urN linux-2.4.19-rc3/drivers/net/natsemi.c linux-2.4.19-rc4/drivers/net/natsemi.c
--- linux-2.4.19-rc3/drivers/net/natsemi.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/drivers/net/natsemi.c	Wed Jul 31 15:10:19 2002
@@ -1963,6 +1963,9 @@
 		if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
 			return -EFAULT;
 		
+		if (eeprom.offset > eeprom.offset+eeprom.len)
+			return -EINVAL;
+			
 		if ((eeprom.offset+eeprom.len) > NATSEMI_EEPROM_SIZE) {
 			eeprom.len = NATSEMI_EEPROM_SIZE-eeprom.offset;
 		}
diff -urN linux-2.4.19-rc3/drivers/s390/block/dasd.c linux-2.4.19-rc4/drivers/s390/block/dasd.c
--- linux-2.4.19-rc3/drivers/s390/block/dasd.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/drivers/s390/block/dasd.c	Wed Jul 31 15:10:19 2002
@@ -3797,12 +3797,16 @@
 dasd_devices_write (struct file *file, const char *user_buf,
 		    size_t user_len, loff_t * offset)
 {
-	char *buffer = vmalloc (user_len+1);
+	char *buffer;
 	int off = 0;
 	char *temp;
 	dasd_range_t range;
         int features;
 
+	if (user_len > PAGE_SIZE)
+		return -EINVAL;
+		
+	buffer = vmalloc (user_len+1);
 	if (buffer == NULL)
 		return -ENOMEM;
 	if (copy_from_user (buffer, user_buf, user_len)) {
diff -urN linux-2.4.19-rc3/drivers/sbus/char/openprom.c linux-2.4.19-rc4/drivers/sbus/char/openprom.c
--- linux-2.4.19-rc3/drivers/sbus/char/openprom.c	Wed Oct 10 23:42:47 2001
+++ linux-2.4.19-rc4/drivers/sbus/char/openprom.c	Wed Jul 31 15:10:19 2002
@@ -334,6 +334,9 @@
 {
 	char *tmp;
 
+	if ((int)len < 0 || (int)(len + 1) < 0)
+		return -EINVAL;
+
 	tmp = kmalloc(len + 1, GFP_KERNEL);
 	if (!tmp)
 		return -ENOMEM;
diff -urN linux-2.4.19-rc3/drivers/usb/catc.c linux-2.4.19-rc4/drivers/usb/catc.c
--- linux-2.4.19-rc3/drivers/usb/catc.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/drivers/usb/catc.c	Wed Jul 31 15:10:19 2002
@@ -673,9 +673,16 @@
 	}
 
 	catc = kmalloc(sizeof(struct catc), GFP_KERNEL);
+	if (!catc)
+		return NULL;
+
 	memset(catc, 0, sizeof(struct catc));
 
 	netdev = init_etherdev(0, 0);
+	if (!netdev) {
+		kfree(catc);
+		return NULL;
+	}
 
 	netdev->open = catc_open;
 	netdev->hard_start_xmit = catc_hard_start_xmit;
diff -urN linux-2.4.19-rc3/drivers/usb/devices.c linux-2.4.19-rc4/drivers/usb/devices.c
--- linux-2.4.19-rc3/drivers/usb/devices.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/drivers/usb/devices.c	Wed Jul 31 15:10:19 2002
@@ -573,8 +573,10 @@
 		bus = list_entry(buslist, struct usb_bus, bus_list);
 		/* recurse through all children of the root hub */
 		ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
-		if (ret < 0)
+		if (ret < 0) {
+			up(&usb_bus_list_lock);
 			return ret;
+		}
 		total_written += ret;
 	}
 	up (&usb_bus_list_lock);
diff -urN linux-2.4.19-rc3/drivers/usb/printer.c linux-2.4.19-rc4/drivers/usb/printer.c
--- linux-2.4.19-rc3/drivers/usb/printer.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/drivers/usb/printer.c	Wed Jul 31 15:10:19 2002
@@ -616,7 +616,11 @@
 							 (count - writecount) : USBLP_BUF_SIZE;
 
 		if (copy_from_user(usblp->writeurb.transfer_buffer, buffer + writecount,
-				usblp->writeurb.transfer_buffer_length)) return -EFAULT;
+				usblp->writeurb.transfer_buffer_length))
+		{
+			up(&usblp->sem);
+			return writecount?writecount:-EFAULT;
+		}
 
 		usblp->writeurb.dev = usblp->dev;
 		usb_submit_urb(&usblp->writeurb);
diff -urN linux-2.4.19-rc3/drivers/usb/rio500.c linux-2.4.19-rc4/drivers/usb/rio500.c
--- linux-2.4.19-rc3/drivers/usb/rio500.c	Fri Sep 14 14:04:07 2001
+++ linux-2.4.19-rc4/drivers/usb/rio500.c	Wed Jul 31 15:10:19 2002
@@ -141,7 +141,7 @@
 			retval = -EFAULT;
 			goto err_out;
 		}
-		if (rio_cmd.length > PAGE_SIZE) {
+		if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
 			retval = -EINVAL;
 			goto err_out;
 		}
@@ -211,7 +211,7 @@
 			retval = -EFAULT;
 			goto err_out;
 		}
-		if (rio_cmd.length > PAGE_SIZE) {
+		if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
 			retval = -EINVAL;
 			goto err_out;
 		}
diff -urN linux-2.4.19-rc3/drivers/usb/usbvideo.c linux-2.4.19-rc4/drivers/usb/usbvideo.c
--- linux-2.4.19-rc3/drivers/usb/usbvideo.c	Wed Oct 10 23:42:46 2001
+++ linux-2.4.19-rc4/drivers/usb/usbvideo.c	Wed Jul 31 15:10:19 2002
@@ -1737,6 +1737,12 @@
 	 * have - even if the application wants more. That would be
 	 * a big security embarassment!
 	 */
+	 
+	if (count + frame->seqRead_Index < count)
+	{
+		count = -EINVAL;
+		goto read_done;
+	}
 	if ((count + frame->seqRead_Index) > frame->seqRead_Length)
 		count = frame->seqRead_Length - frame->seqRead_Index;
 
diff -urN linux-2.4.19-rc3/drivers/video/fbcon.c linux-2.4.19-rc4/drivers/video/fbcon.c
--- linux-2.4.19-rc3/drivers/video/fbcon.c	Mon Feb 25 11:38:07 2002
+++ linux-2.4.19-rc4/drivers/video/fbcon.c	Wed Jul 31 15:10:19 2002
@@ -2417,7 +2417,7 @@
 		else
 		    dst = fb + y1*line + x/8;
 		for( x1 = 0; x1 < LOGO_LINE; ++x1 )
-		    fb_writeb(fb_readb(src++) ^ inverse, dst++);
+		    fb_writeb(*src++ ^ inverse, dst++);
 	    }
 	    done = 1;
 	}
diff -urN linux-2.4.19-rc3/fs/coda/file.c linux-2.4.19-rc4/fs/coda/file.c
--- linux-2.4.19-rc3/fs/coda/file.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/fs/coda/file.c	Wed Jul 31 15:10:20 2002
@@ -233,7 +233,6 @@
 			coda_inode->i_mapping = &coda_inode->i_data;
 	}
 
-	coda_inode->i_mapping = &coda_inode->i_data;
 	fput(cfi->cfi_container);
 
 	kfree(coda_file->private_data);
diff -urN linux-2.4.19-rc3/fs/intermezzo/kml.c linux-2.4.19-rc4/fs/intermezzo/kml.c
--- linux-2.4.19-rc3/fs/intermezzo/kml.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/fs/intermezzo/kml.c	Wed Jul 31 15:10:20 2002
@@ -20,9 +20,9 @@
 {
         struct {
                 char *volname;
-                int   namelen;  
+                unsigned int namelen;  
                 char *recbuf;
-                int   reclen;     /* int   newpos; */
+                unsigned int reclen;     /* int   newpos; */
         } input;
         struct kml_fsdata *kml_fsdata = NULL;
         struct presto_file_set *fset = NULL;
@@ -36,6 +36,12 @@
                 return -EFAULT;
         }
 
+	if (input.namelen > PATH_MAX)
+	{
+		EXIT;
+		return -EINVAL;
+	}
+		
         if (input.reclen > kml_fsdata->kml_maxsize)
                 return -ENOMEM; /* we'll find solution to this in the future */
 
@@ -75,9 +81,9 @@
 {
         struct {
                 char *volname;
-                int   namelen;  
+                unsigned int namelen;  
                 char *path;
-                int pathlen;
+                unsigned int pathlen;
                 int recno;
                 int offset;
                 int len;
@@ -95,6 +101,13 @@
                 EXIT;
                 return -EFAULT;
         }
+        
+        if(input.namelen > PATH_MAX || input.pathlen > PATH_MAX)
+        {
+        	EXIT;
+        	return -EFAULT;
+        }
+        
         PRESTO_ALLOC(path, char *, input.namelen + 1);
         if ( !path ) {
                 EXIT;
@@ -145,7 +158,7 @@
         /* Free KML buffer and related volume info */
         struct {
                 char *volname;
-                int   namelen;  
+                unsigned int namelen;  
 #if 0
                 int   count; 
                 int   newpos; 
@@ -162,6 +175,12 @@
                return -EFAULT;
         }
 
+	if (input.namelen > PATH_MAX)
+	{
+		EXIT;
+		return -EFAULT;
+	}
+	
         PRESTO_ALLOC(path, char *, input.namelen + 1);
         if ( !path ) {
                 EXIT;
diff -urN linux-2.4.19-rc3/fs/intermezzo/psdev.c linux-2.4.19-rc4/fs/intermezzo/psdev.c
--- linux-2.4.19-rc3/fs/intermezzo/psdev.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/fs/intermezzo/psdev.c	Wed Jul 31 15:10:20 2002
@@ -350,13 +350,19 @@
                 char *path;
                 struct {
                         char *path;
-                        int   path_len;
+                        unsigned int path_len;
                 } input;
 
                 if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
                         return -EFAULT;
                 }
+                
+                if(input.path_len > PATH_MAX)
+                {
+                	EXIT;
+                	return -EINVAL;
+                }
 
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
                 if ( !path ) {
@@ -389,13 +395,18 @@
                 char *path;
                 struct {
                         char *path;
-                        int   path_len;
+                        unsigned int path_len;
                 } input;
 
                 if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
                         return -EFAULT;
                 }
+                
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
 
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
                 if ( !path ) {
@@ -426,7 +437,7 @@
                 struct {
                         __u64 size;
                         char *path;
-                        int   path_len;
+                        unsigned int path_len;
                 } input;
 
                 if (copy_from_user(&input, (char *)arg, sizeof(input))) {
@@ -434,6 +445,11 @@
                         return -EFAULT;
                 }
 
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
                 if ( !path ) {
                         EXIT;
@@ -474,7 +490,7 @@
                 struct {
                         __u64 recno;
                         char *path;
-                        int   path_len;
+                        unsigned int path_len;
                 } input;
 
                 if (copy_from_user(&input, (char *)arg, sizeof(input))) {
@@ -482,6 +498,11 @@
                         return -EFAULT;
                 }
 
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
                 if ( !path ) {
                         EXIT;
@@ -525,9 +546,9 @@
                 char *path;
                 struct {
                         char *path;
-                        int   path_len;
+                        unsigned int path_len;
                         char *name;
-                        int   name_len;
+                        unsigned int name_len;
                         int   id;
                         int   flags;
                 } input;
@@ -537,6 +558,16 @@
                         return -EFAULT;
                 }
 
+                if(input.name_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+                
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
                 if ( !path ) {
                         EXIT;
@@ -926,6 +957,12 @@
                         EXIT;
                         return -EFAULT;
                 }
+
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
                 user_path = input.path;
 
                 PRESTO_ALLOC(input.path, char *, input.path_len + 1);
@@ -967,6 +1004,12 @@
                         EXIT;
                         return -EFAULT;
                 }
+
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
                 user_path = input.path;
 
                 PRESTO_ALLOC(input.path, char *, input.path_len + 1);
@@ -1004,6 +1047,12 @@
                         EXIT;
                         return -EFAULT;
                 }
+
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
                 user_path = input.path;
 
                 PRESTO_ALLOC(input.path, char *, input.path_len + 1);
@@ -1038,6 +1087,12 @@
                         EXIT;
                         return -EFAULT;
                 }
+
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
                 user_path = input.path;
 
                 PRESTO_ALLOC(input.path, char *, input.path_len + 1);
@@ -1067,7 +1122,7 @@
                         int  mark_what;
                         int  and_flag;
                         int  or_flag;
-                        int path_len;
+                        unsigned int path_len;
                         char *path;
                 } input;
 
@@ -1075,6 +1130,12 @@
                         EXIT;
                         return -EFAULT;
                 }
+
+                if(input.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
+
                 user_path = input.path;
 
                 PRESTO_ALLOC(input.path, char *, input.path_len + 1);
@@ -1167,7 +1228,7 @@
                 char *user_path;
                 struct {
                         int  cookie;
-                        int path_len;
+                        unsigned int path_len;
                         char *path;
                 } permit;
                 
@@ -1175,6 +1236,11 @@
                         EXIT;
                         return -EFAULT;
 		}
+
+                if(permit.path_len > PATH_MAX) {
+                	EXIT;
+                	return -EINVAL;
+                }
                 user_path = permit.path;
                 
                 PRESTO_ALLOC(permit.path, char *, permit.path_len + 1);
diff -urN linux-2.4.19-rc3/fs/intermezzo/super.c linux-2.4.19-rc4/fs/intermezzo/super.c
--- linux-2.4.19-rc3/fs/intermezzo/super.c	Mon Feb 25 11:38:08 2002
+++ linux-2.4.19-rc4/fs/intermezzo/super.c	Wed Jul 31 15:10:20 2002
@@ -404,7 +404,7 @@
 
         cache = presto_find_cache(sb->s_dev);
         if (!cache) {
-                printk(__FUNCTION__ ": cannot find cache on remount\n");
+                printk( "%s: cannot find cache on remount\n", __FUNCTION__);
                 err = -ENODEV;
                 EXIT;
                 goto out_err;
diff -urN linux-2.4.19-rc3/fs/intermezzo/vfs.c linux-2.4.19-rc4/fs/intermezzo/vfs.c
--- linux-2.4.19-rc3/fs/intermezzo/vfs.c	Mon Feb 25 11:38:08 2002
+++ linux-2.4.19-rc4/fs/intermezzo/vfs.c	Wed Jul 31 15:10:20 2002
@@ -1969,8 +1969,8 @@
          * just turn off the flag and ignore it.
          */
         if (flags & O_CREAT) {
-                printk(KERN_WARNING __FUNCTION__
-                       ": create file by inode number (%ld) not allowed\n",ino);
+                printk(KERN_WARNING "%s: create file by inode number (%ld) not allowed\n",
+                	__FUNCTION__, ino);
                 EXIT;
                 return -EACCES;
         }
diff -urN linux-2.4.19-rc3/fs/namei.c linux-2.4.19-rc4/fs/namei.c
--- linux-2.4.19-rc3/fs/namei.c	Wed Jul 31 15:10:14 2002
+++ linux-2.4.19-rc4/fs/namei.c	Wed Jul 31 15:10:20 2002
@@ -1372,14 +1372,18 @@
 static void d_unhash(struct dentry *dentry)
 {
 	dget(dentry);
+	spin_lock(&dcache_lock);
 	switch (atomic_read(&dentry->d_count)) {
 	default:
+		spin_unlock(&dcache_lock);
 		shrink_dcache_parent(dentry);
+		spin_lock(&dcache_lock);
 		if (atomic_read(&dentry->d_count) != 2)
 			break;
 	case 2:
-		d_drop(dentry);
+		list_del_init(&dentry->d_hash);
 	}
+	spin_unlock(&dcache_lock);
 }
 
 int vfs_rmdir(struct inode *dir, struct dentry *dentry)
diff -urN linux-2.4.19-rc3/fs/proc/generic.c linux-2.4.19-rc4/fs/proc/generic.c
--- linux-2.4.19-rc3/fs/proc/generic.c	Fri Sep  7 10:53:59 2001
+++ linux-2.4.19-rc4/fs/proc/generic.c	Wed Jul 31 15:10:20 2002
@@ -138,24 +138,26 @@
 
 
 static loff_t
-proc_file_lseek(struct file * file, loff_t offset, int orig)
+proc_file_lseek(struct file * file, loff_t offset, int origin)
 {
-    switch (orig) {
-    case 0:
-	if (offset < 0)
-	    return -EINVAL;    
-	file->f_pos = offset;
-	return(file->f_pos);
-    case 1:
-	if (offset + file->f_pos < 0)
-	    return -EINVAL;    
-	file->f_pos += offset;
-	return(file->f_pos);
-    case 2:
-	return(-EINVAL);
-    default:
-	return(-EINVAL);
-    }
+	long long retval;
+
+	switch (origin) {
+		case 2:
+			offset += file->f_dentry->d_inode->i_size;
+			break;
+		case 1:
+			offset += file->f_pos;
+	}
+	retval = -EINVAL;
+	if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
+		if (offset != file->f_pos) {
+			file->f_pos = offset;
+			file->f_reada = 0;
+		}
+		retval = offset;
+	}
+	return retval;
 }
 
 /*
diff -urN linux-2.4.19-rc3/include/asm-i386/bugs.h linux-2.4.19-rc4/include/asm-i386/bugs.h
--- linux-2.4.19-rc3/include/asm-i386/bugs.h	Thu Nov 22 11:46:17 2001
+++ linux-2.4.19-rc4/include/asm-i386/bugs.h	Wed Jul 31 15:10:20 2002
@@ -204,7 +204,10 @@
 
 static void __init check_bugs(void)
 {
+	extern void __init boot_init_fpu(void);
+
 	identify_cpu(&boot_cpu_data);
+	boot_init_fpu();
 #ifndef CONFIG_SMP
 	printk("CPU: ");
 	print_cpu_info(&boot_cpu_data);
diff -urN linux-2.4.19-rc3/include/asm-i386/i387.h linux-2.4.19-rc4/include/asm-i386/i387.h
--- linux-2.4.19-rc3/include/asm-i386/i387.h	Thu Nov 22 11:48:58 2001
+++ linux-2.4.19-rc4/include/asm-i386/i387.h	Wed Jul 31 15:10:20 2002
@@ -76,6 +76,7 @@
 			struct task_struct *tsk );
 extern int set_fpxregs( struct task_struct *tsk,
 			struct user_fxsr_struct *buf );
+extern void load_empty_fpu(struct task_struct *);
 
 /*
  * FPU state for core dumps...
diff -urN linux-2.4.19-rc3/include/asm-i386/processor.h linux-2.4.19-rc4/include/asm-i386/processor.h
--- linux-2.4.19-rc3/include/asm-i386/processor.h	Wed Jul 31 15:10:15 2002
+++ linux-2.4.19-rc4/include/asm-i386/processor.h	Wed Jul 31 15:10:20 2002
@@ -381,7 +381,7 @@
 /* virtual 86 mode info */
 	struct vm86_struct	* vm86_info;
 	unsigned long		screen_bitmap;
-	unsigned long		v86flags, v86mask, v86mode, saved_esp0;
+	unsigned long		v86flags, v86mask, saved_esp0;
 /* IO permissions */
 	int		ioperm;
 	unsigned long	io_bitmap[IO_BITMAP_SIZE+1];
@@ -393,7 +393,7 @@
 	{ [0 ... 7] = 0 },	/* debugging registers */	\
 	0, 0, 0,						\
 	{ { 0, }, },		/* 387 state */			\
-	0,0,0,0,0,0,						\
+	0,0,0,0,0,						\
 	0,{~0,}			/* io permissions */		\
 }
 
diff -urN linux-2.4.19-rc3/include/linux/module.h linux-2.4.19-rc4/include/linux/module.h
--- linux-2.4.19-rc3/include/linux/module.h	Thu Nov 22 11:46:19 2001
+++ linux-2.4.19-rc4/include/linux/module.h	Wed Jul 31 15:10:20 2002
@@ -263,6 +263,7 @@
  * software modules
  *
  *	"GPL"				[GNU Public License v2 or later]
+ *	"GPL v2"			[GNU Public License v2]
  *	"GPL and additional rights"	[GNU Public License v2 rights and more]
  *	"Dual BSD/GPL"			[GNU Public License v2 or BSD license choice]
  *	"Dual MPL/GPL"			[GNU Public License v2 or Mozilla license choice]
diff -urN linux-2.4.19-rc3/net/ipv4/route.c linux-2.4.19-rc4/net/ipv4/route.c
--- linux-2.4.19-rc3/net/ipv4/route.c	Wed Jul 31 15:10:15 2002
+++ linux-2.4.19-rc4/net/ipv4/route.c	Wed Jul 31 15:10:21 2002
@@ -2426,6 +2426,11 @@
 	if ((offset & 3) || (length & 3))
 		return -EIO;
 
+	if (offset >= sizeof(struct ip_rt_acct) * 256) {
+		*eof = 1;
+		return 0;
+	}
+
 	if (offset + length >= sizeof(struct ip_rt_acct) * 256) {
 		length = sizeof(struct ip_rt_acct) * 256 - offset;
 		*eof = 1;
