## Automatically generated incremental diff
## From:   linux-2.2.19-pre6
## To:     linux-2.2.19-pre7
## Robot:  $Id: make-incremental-diff,v 1.6 2001/12/04 04:41:15 hpa Exp $

diff -urN linux-2.2.19-pre6/Documentation/rtc.txt linux/Documentation/rtc.txt
--- linux-2.2.19-pre6/Documentation/rtc.txt	Thu Jun  4 22:53:50 1998
+++ linux/Documentation/rtc.txt	Mon Dec  3 20:57:55 2001
@@ -56,7 +56,7 @@
 exclusive access to the device for your applications.
 
 The alarm and/or interrupt frequency are programmed into the RTC via
-various ioctl(2) calls as listed in ./include/linux/mc146818rtc.h
+various ioctl(2) calls as listed in ./include/linux/rtc.h
 Rather than write 50 pages describing the ioctl() and so on, it is
 perhaps more useful to include a small test program that demonstrates
 how to use them, and demonstrates the features of the driver. This is
@@ -81,7 +81,7 @@
  */
 
 #include <stdio.h>
-#include <linux/mc146818rtc.h>
+#include <linux/rtc.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
 #include <sys/types.h>
diff -urN linux-2.2.19-pre6/Makefile linux/Makefile
--- linux-2.2.19-pre6/Makefile	Mon Dec  3 20:57:29 2001
+++ linux/Makefile	Mon Dec  3 20:57:55 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 19
-EXTRAVERSION = pre6
+EXTRAVERSION = pre7
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -urN linux-2.2.19-pre6/arch/alpha/mm/extable.c linux/arch/alpha/mm/extable.c
--- linux-2.2.19-pre6/arch/alpha/mm/extable.c	Wed Jun  7 14:26:42 2000
+++ linux/arch/alpha/mm/extable.c	Mon Dec  3 20:57:55 2001
@@ -88,7 +88,7 @@
 	 */
 	ret = search_exception_table_without_gp(addr);
 	if (ret) {
-		printk(KERN_ALERT, "%s: [%lx] EX_TABLE search fail with"
+		printk(KERN_ALERT "%s: [%lx] EX_TABLE search fail with"
 		       "exc frame GP, success with raw GP\n",
 		       current->comm, addr);
 		return ret;
diff -urN linux-2.2.19-pre6/arch/arm/kernel/ptrace.c linux/arch/arm/kernel/ptrace.c
--- linux-2.2.19-pre6/arch/arm/kernel/ptrace.c	Mon Dec  3 20:57:35 2001
+++ linux/arch/arm/kernel/ptrace.c	Mon Dec  3 20:57:55 2001
@@ -516,196 +516,230 @@
 	    }
 	    break;
 	}
-printk ("=%08lX\n", alt);
-	if (alt != pc + 4)
-		child->tss.debug[nsaved++] = alt;
 
-	for (i = 0; i < nsaved; i++) {
-		res = read_long (child, child->tss.debug[i], &insn);
-		if (res >= 0) {
-			child->tss.debug[i + 2] = insn;
-			res = write_long (child, child->tss.debug[i], BREAKINST);
-		}
-		if (res < 0) {
-			child->tss.debug[4] = 0;
-			return res;
+	return alt;
+}
+
+static int
+add_breakpoint(struct task_struct *child, struct debug_info *dbg, unsigned long addr)
+{
+	int nr = dbg->nsaved;
+	int res = -EINVAL;
+
+	if (nr < 2) {
+		res = read_tsk_long(child, addr, &dbg->bp[nr].insn);
+		if (res == 0)
+			res = write_tsk_long(child, addr, BREAKINST);
+
+		if (res == 0) {
+			dbg->bp[nr].address = addr;
+			dbg->nsaved += 1;
 		}
+	} else
+		printk(KERN_DEBUG "add_breakpoint: too many breakpoints\n");
+
+	return res;
+}
+
+int ptrace_set_bpt(struct task_struct *child)
+{
+	unsigned long insn, pc;
+	int res;
+
+	pc = pc_pointer(get_stack_long(child, REG_PC));
+
+	res = read_long(child, pc, &insn);
+	if (!res) {
+		struct debug_info *dbg = &child->tss.debug;
+		unsigned long alt;
+
+		dbg->nsaved = 0;
+
+		alt = get_branch_address(child, pc, insn);
+
+		if (alt)
+			res = add_breakpoint(child, dbg, alt);
+
+		/*
+		 * Note that we ignore the result of setting the above
+		 * breakpoint since it may fail.  When it does, this is
+		 * not so much an error, but a forewarning that we will
+		 * be receiving a prefetch abort shortly.
+		 *
+		 * If we don't set this breakpoint here, then we can
+		 * loose control of the thread during single stepping.
+		 */
+		if (!alt || predicate(insn) != PREDICATE_ALWAYS)
+			res = add_breakpoint(child, dbg, pc + 4);
 	}
-	child->tss.debug[4] = nsaved;
-	return 0;
+
+	return res;
 }
 
-/* Ensure no single-step breakpoint is pending.  Returns non-zero
+/*
+ * Ensure no single-step breakpoint is pending.  Returns non-zero
  * value if child was being single-stepped.
  */
 int ptrace_cancel_bpt (struct task_struct *child)
 {
-	int i, nsaved = child->tss.debug[4];
+	struct debug_info *dbg = &child->tss.debug;
+	int i, nsaved = dbg->nsaved;
 
-	child->tss.debug[4] = 0;
+	dbg->nsaved = 0;
 
 	if (nsaved > 2) {
-		printk ("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
+		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
 		nsaved = 2;
 	}
-	for (i = 0; i < nsaved; i++)
-		write_long (child, child->tss.debug[i], child->tss.debug[i + 2]);
+
+	for (i = 0; i < nsaved; i++) {
+		unsigned long tmp;
+
+		read_tsk_long(child, dbg->bp[i].address, &tmp);
+		if (tmp != BREAKINST)
+			printk(KERN_ERR "ptrace_cancel_bpt: weirdness\n");
+		write_tsk_long(child, dbg->bp[i].address, dbg->bp[i].insn);
+	}
 	return nsaved != 0;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+static int do_ptrace(int request, struct task_struct *child, long addr, long data)
 {
-	struct task_struct *child;
+	unsigned long tmp;
 	int ret;
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->flags & PF_PTRACED)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->flags |= PF_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	if (pid == 1)		/* you may not mess with init */
-		goto out;
-	ret = -ESRCH;
-	if (!(child = find_task_by_pid(pid)))
-		goto out;
-	ret = -EPERM;
-	if (request == PTRACE_ATTACH) {
-		if (child == current)
-			goto out;
-		if ((child->dumpable != 1 ||
-		    (current->uid != child->euid) ||
-		    (current->uid != child->suid) ||
-		    (current->uid != child->uid) ||
-	 	    (current->gid != child->egid) ||
-	 	    (current->gid != child->sgid) ||
-	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
-			goto out;
-		/* the same process cannot be attached many times */
-		if (child->flags & PF_PTRACED)
-			goto out;
-		child->flags |= PF_PTRACED;
-		if (child->p_pptr != current) {
-			REMOVE_LINKS(child);
-			child->p_pptr = current;
-			SET_LINKS(child);
-		}
-		send_sig(SIGSTOP, child, 1);
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	if (!(child->flags & PF_PTRACED))
-		goto out;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out;
-	}
-	if (child->p_pptr != current)
-		goto out;
-
 	switch (request) {
-		case PTRACE_PEEKTEXT:				/* read word at location addr. */
-		case PTRACE_PEEKDATA: {
-			unsigned long tmp;
-
-			ret = read_long(child, addr, &tmp);
-			if (ret >= 0)
-				ret = put_user(tmp, (unsigned long *)data);
-			goto out;
-		}
-
-		case PTRACE_PEEKUSR: {				/* read the word at location addr in the USER area. */
-			unsigned long tmp;
+		/*
+		 * read word at location "addr" in the child process.
+		 */
+		case PTRACE_PEEKTEXT:
+		case PTRACE_PEEKDATA:
+			ret = read_tsk_long(child, addr, &tmp);
+			if (!ret)
+				ret = put_user(tmp, (unsigned long *) data);
+			break;
 
+		/*
+		 * read the word at location "addr" in the user registers.
+		 */
+		case PTRACE_PEEKUSR:
 			ret = -EIO;
 			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				goto out;
+				break;
 
 			tmp = 0;  /* Default return condition */
-			if (addr < sizeof (struct pt_regs))
+			if (addr < sizeof(struct pt_regs))
 				tmp = get_stack_long(child, (int)addr >> 2);
 			ret = put_user(tmp, (unsigned long *)data);
-			goto out;
-		}
+			break;
 
-		case PTRACE_POKETEXT:				/* write the word at location addr. */
+		/*
+		 * write the word at location addr.
+		 */
+		case PTRACE_POKETEXT:
 		case PTRACE_POKEDATA:
-			ret = write_long(child,addr,data);
-			goto out;
+			ret = write_tsk_long(child, addr, data);
+			break;
 
-		case PTRACE_POKEUSR:				/* write the word at location addr in the USER area */
+		/*
+		 * write the word at location addr in the user registers.
+		 */
+		case PTRACE_POKEUSR:
 			ret = -EIO;
 			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				goto out;
+				break;
 
-			if (addr < sizeof (struct pt_regs))
+			if (addr < sizeof(struct pt_regs))
 				ret = put_stack_long(child, (int)addr >> 2, data);
-			goto out;
+			break;
 
-		case PTRACE_SYSCALL:				/* continue and stop at next (return from) syscall */
-		case PTRACE_CONT:				/* restart after signal. */
+		/*
+		 * continue/restart and stop at next (return from) syscall
+		 */
+		case PTRACE_SYSCALL:
+		case PTRACE_CONT:
 			ret = -EIO;
 			if ((unsigned long) data > _NSIG)
-				goto out;
+				break;
 			if (request == PTRACE_SYSCALL)
 				child->flags |= PF_TRACESYS;
 			else
 				child->flags &= ~PF_TRACESYS;
 			child->exit_code = data;
-			wake_up_process (child);
 			/* make sure single-step breakpoint is gone. */
-			ptrace_cancel_bpt (child);
+			ptrace_cancel_bpt(child);
+			wake_up_process(child);
 			ret = 0;
-			goto out;
+			break;
 
-		/* make the child exit.  Best I can do is send it a sigkill.
+		/*
+		 * make the child exit.  Best I can do is send it a sigkill.
 		 * perhaps it should be put in the status that it wants to
 		 * exit.
 		 */
 		case PTRACE_KILL:
-			if (child->state == TASK_ZOMBIE)	/* already dead */
-				return 0;
-			wake_up_process (child);
+			/* already dead */
+			ret = 0;
+			if (child->state == TASK_ZOMBIE)
+				break;
 			child->exit_code = SIGKILL;
 			/* make sure single-step breakpoint is gone. */
-			ptrace_cancel_bpt (child);
+			ptrace_cancel_bpt(child);
+			wake_up_process(child);
 			ret = 0;
-			goto out;
+			break;
 
-		case PTRACE_SINGLESTEP:				/* execute single instruction. */
+		/*
+		 * execute single instruction.
+		 */
+		case PTRACE_SINGLESTEP:
 			ret = -EIO;
 			if ((unsigned long) data > _NSIG)
-				goto out;
-			child->tss.debug[4] = -1;
+				break;
+			child->tss.debug.nsaved = -1;
 			child->flags &= ~PF_TRACESYS;
-			wake_up_process(child);
 			child->exit_code = data;
 			/* give it a chance to run. */
+			wake_up_process(child);
 			ret = 0;
-			goto out;
-			
-		case PTRACE_GETREGS:
-		{	/* Get all gp regs from the child. */
-			unsigned char *stack;
+			break;
 
+		/*
+		 * detach a process that was attached.
+		 */
+		case PTRACE_DETACH:
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+			child->exit_code = data;
+			REMOVE_LINKS(child);
+			child->p_pptr = child->p_opptr;
+			SET_LINKS(child);
+			/* make sure single-step breakpoint is gone. */
+			ptrace_cancel_bpt (child);
+			wake_up_process (child);
 			ret = 0;
-			stack = (unsigned char *)((unsigned long)child + 8192 - sizeof(struct pt_regs));
-			if (copy_to_user((void *)data, stack,
+			break;
+
+		/*
+		 * Get all gp regs from the child.
+		 */
+		case PTRACE_GETREGS: {
+			struct pt_regs *regs = get_user_regs(child);
+
+			ret = 0;
+			if (copy_to_user((void *)data, regs,
 					 sizeof(struct pt_regs)))
 				ret = -EFAULT;
 
-			goto out;
-		};
+			break;
+		}
 
-		/* Set all gp regs in the child. */
-		case PTRACE_SETREGS:
-		{
+		/*
+		 * Set all gp regs in the child.
+		 */
+		case PTRACE_SETREGS: {
 			struct pt_regs newregs;
 
 			ret = -EFAULT;
@@ -783,7 +817,7 @@
 	if (request == PTRACE_ATTACH) {
 		if (child == current)
 			goto out;
-		if ((!child->dumpable ||
+		if ((child->dumpable != 1 ||
 		    (current->uid != child->euid) ||
 		    (current->uid != child->suid) ||
 		    (current->uid != child->uid) ||
diff -urN linux-2.2.19-pre6/arch/arm/vmlinux-armo.lds linux/arch/arm/vmlinux-armo.lds
--- linux-2.2.19-pre6/arch/arm/vmlinux-armo.lds	Sun Dec 10 16:49:41 2000
+++ linux/arch/arm/vmlinux-armo.lds	Wed Dec 31 16:00:00 1969
@@ -1,69 +0,0 @@
-/* ld script to make ARM Linux kernel
- * taken from the i386 version by Russell King
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- */
-OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
-  _text = .;			/* Text and read-only data */
-  .text : {
-	*(.text)
-	*(.fixup)
-	*(.gnu.warning)
-	} = 0x9090
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
-  .rodata : { *(.rodata) }
-  .kstrtab : { *(.kstrtab) }
-
-  . = ALIGN(16);		/* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  _etext = .;			/* End of text section */
-
-  . = ALIGN(8192);
-  .data : {			/* Data */
-	*(.init.task)
-	*(.data)
-	CONSTRUCTORS
-	}
-
-  _edata = .;			/* End of data section */
-
-  . = ALIGN(32768);		/* Init code and data */
-  __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
-  . = ALIGN(16);		/* __setup() commandline parameters */
-  __setup_start = .;
-  .setup.init : { *(.setup.init) }
-  __setup_end = .;
-  __initcall_start = .;		/* the init functions to be called */
-  .initcall.init : { *(.initcall.init) }
-  __initcall_end = .;
-  . = ALIGN(32768);
-  __init_end = .;
-
-
-  __bss_start = .;		/* BSS */
-  .bss : {
-	*(.bss)
-	}
-  _end = . ;
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-}
diff -urN linux-2.2.19-pre6/arch/arm/vmlinux-armv.lds linux/arch/arm/vmlinux-armv.lds
--- linux-2.2.19-pre6/arch/arm/vmlinux-armv.lds	Sun Dec 10 16:49:41 2000
+++ linux/arch/arm/vmlinux-armv.lds	Wed Dec 31 16:00:00 1969
@@ -1,70 +0,0 @@
-/* ld script to make ARM Linux kernel
- * taken from the i386 version by Russell King
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- */
-OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
-  _text = .;			/* Text and read-only data */
-  .text : {
-	*(.text)
-	*(.fixup)
-	*(.gnu.warning)
-	} = 0x9090
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
-  .rodata : { *(.rodata) }
-  .kstrtab : { *(.kstrtab) }
-
-  . = ALIGN(16);		/* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  _etext = .;			/* End of text section */
-
-  . = ALIGN(8192);
-  .data : {			/* Data */
-	*(.init.task)
-	*(.data)
-	CONSTRUCTORS
-	}
-
-  _edata = .;			/* End of data section */
-
-  . = ALIGN(4096);		/* Init code and data */
-  __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
-  . = ALIGN(16);		/* __setup() commandline parameters */
-  __setup_start = .;
-  .setup.init : { *(.setup.init) }
-  __setup_end = .;
- 
-  __initcall_start = .;		/* the init functions to be called */
-  .initcall.init : { *(.initcall.init) }
-  __initcall_end = .;
-  . = ALIGN(4096);
-  __init_end = .;
-
-
-  __bss_start = .;		/* BSS */
-  .bss : {
-	*(.bss)
-	}
-  _end = . ;
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-}
diff -urN linux-2.2.19-pre6/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- linux-2.2.19-pre6/arch/i386/kernel/setup.c	Mon Dec  3 20:57:35 2001
+++ linux/arch/i386/kernel/setup.c	Mon Dec  3 20:57:55 2001
@@ -1278,7 +1278,9 @@
 		wrmsr(0x1107, lv, hv);
 		/* Cyrix III */
 		c->x86_capability |= X86_FEATURE_CX8;
-		rdmsr(0x80000001, lv, hv);
+		
+		/* Check for 3dnow */
+		cpuid(0x80000001, &lv, &lv, &lv, &hv);
 		if(hv&(1<<31))
 			c->x86_capability |= X86_FEATURE_AMD3D;
 	}	
diff -urN linux-2.2.19-pre6/arch/sparc/defconfig linux/arch/sparc/defconfig
--- linux-2.2.19-pre6/arch/sparc/defconfig	Sun Dec 10 16:49:41 2000
+++ linux/arch/sparc/defconfig	Mon Dec  3 20:57:55 2001
@@ -284,6 +284,7 @@
 #
 CONFIG_BSD_DISKLABEL=y
 # CONFIG_MAC_PARTITION is not set
+# CONFIG_MINIX_SUBPARTITION is not set
 CONFIG_SMD_DISKLABEL=y
 CONFIG_SOLARIS_X86_PARTITION=y
 # CONFIG_UNIXWARE_DISKLABEL is not set
@@ -326,6 +327,7 @@
 # CONFIG_NLS_ISO8859_14 is not set
 # CONFIG_NLS_ISO8859_15 is not set
 # CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_RU is not set
 
 #
 # Watchdog
diff -urN linux-2.2.19-pre6/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- linux-2.2.19-pre6/arch/sparc64/defconfig	Sun Dec 10 16:49:41 2000
+++ linux/arch/sparc64/defconfig	Mon Dec  3 20:57:55 2001
@@ -19,7 +19,7 @@
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
-# CONFIG_SMP is not set
+CONFIG_SMP=y
 CONFIG_SPARC64=y
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
@@ -339,6 +339,7 @@
 #
 CONFIG_BSD_DISKLABEL=y
 # CONFIG_MAC_PARTITION is not set
+# CONFIG_MINIX_SUBPARTITION is not set
 CONFIG_SMD_DISKLABEL=y
 CONFIG_SOLARIS_X86_PARTITION=y
 # CONFIG_UNIXWARE_DISKLABEL is not set
@@ -381,6 +382,7 @@
 # CONFIG_NLS_ISO8859_14 is not set
 # CONFIG_NLS_ISO8859_15 is not set
 # CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_RU is not set
 
 #
 # Watchdog
diff -urN linux-2.2.19-pre6/arch/sparc64/kernel/binfmt_aout32.c linux/arch/sparc64/kernel/binfmt_aout32.c
--- linux-2.2.19-pre6/arch/sparc64/kernel/binfmt_aout32.c	Mon Aug  9 12:04:38 1999
+++ linux/arch/sparc64/kernel/binfmt_aout32.c	Mon Dec  3 20:57:55 2001
@@ -101,7 +101,7 @@
 #       define START_DATA(u)    (u.u_tsize)
 #       define START_STACK(u)   ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))
 
-	if (!current->dumpable || atomic_read(&current->mm->count) != 1)
+	if (current->dumpable != 1 || atomic_read(&current->mm->count) != 1)
 		return 0;
 	current->dumpable = 0;
 
diff -urN linux-2.2.19-pre6/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- linux-2.2.19-pre6/arch/sparc64/kernel/sparc64_ksyms.c	Sun Dec 10 16:49:41 2000
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Mon Dec  3 20:57:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.58.2.11 2000/10/25 21:17:44 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.58.2.13 2001/01/03 22:05:54 anton Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -167,6 +167,7 @@
 
 EXPORT_SYMBOL_PRIVATE(flushw_user);
 
+EXPORT_SYMBOL(flush_icache_range);
 EXPORT_SYMBOL(flush_dcache_page);
 
 EXPORT_SYMBOL(mstk48t02_regs);
@@ -209,6 +210,11 @@
 /* Should really be in linux/kernel/ksyms.c */
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(get_pmd_slow);
+EXPORT_SYMBOL(get_pte_slow);
+#ifndef CONFIG_SMP
+EXPORT_SYMBOL(pgt_quicklists);
+#endif
 
 /* math-emu wants this */
 EXPORT_SYMBOL(die_if_kernel);
diff -urN linux-2.2.19-pre6/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c
--- linux-2.2.19-pre6/arch/sparc64/kernel/sys_sunos32.c	Sun Dec 10 16:49:41 2000
+++ linux/arch/sparc64/kernel/sys_sunos32.c	Mon Dec  3 20:57:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.22.2.4 2000/09/16 14:15:15 davem Exp $
+/* $Id: sys_sunos32.c,v 1.22.2.5 2001/01/04 05:35:03 davem Exp $
  * sys_sunos32.c: SunOS binary compatability layer on sparc64.
  *
  * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -1168,6 +1168,7 @@
 			(current->tss.kregs->u_regs[UREG_FP] & 0xffffffffUL);
 		if(get_user(arg5, &sp->xxargs[0])) {
 			rval = -EFAULT;
+			kfree(kmbuf);
 			break;
 		}
 		set_fs(KERNEL_DS);
diff -urN linux-2.2.19-pre6/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- linux-2.2.19-pre6/arch/sparc64/mm/init.c	Wed May  3 17:16:32 2000
+++ linux/arch/sparc64/mm/init.c	Mon Dec  3 20:57:55 2001
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.127.2.8 2000/03/03 23:50:41 davem Exp $
+/*  $Id: init.c,v 1.127.2.9 2000/12/11 12:31:06 anton Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -87,6 +87,14 @@
         }
 #endif
         return freed;
+}
+
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+	unsigned long kaddr;
+
+	for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE)
+		flush_icache_page(__get_phys(kaddr));
 }
 
 /*
diff -urN linux-2.2.19-pre6/drivers/block/hd.c linux/drivers/block/hd.c
--- linux-2.2.19-pre6/drivers/block/hd.c	Sun Dec 10 16:49:41 2000
+++ linux/drivers/block/hd.c	Mon Dec  3 20:57:55 2001
@@ -703,12 +703,12 @@
 static void hd_geninit(struct gendisk *ignored)
 {
 	int drive;
-	unsigned long flags;
 
 #ifdef __i386__
 	if (!NR_HD) {
 		extern struct drive_info drive_info;
 		unsigned char *BIOS = (unsigned char *) &drive_info;
+		unsigned long flags;
 		int cmos_disks;
 
 		for (drive=0 ; drive<2 ; drive++) {
@@ -747,13 +747,15 @@
 		
 	*/
                 spin_lock_irqsave(&rtc_lock, flags);
-		if ((cmos_disks = CMOS_READ(0x12)) & 0xf0) {
+		cmos_disks = CMOS_READ(0x12);
+		spin_unlock_irqrestore(&rtc_lock, flags);
+
+		if (cmos_disks & 0xf0) {
 			if (cmos_disks & 0x0f)
 				NR_HD = 2;
 			else
 				NR_HD = 1;
 		}
-		spin_unlock_irqrestore(&rtc_lock, flags);
 	}
 #endif /* __i386__ */
 	for (drive=0 ; drive < NR_HD ; drive++) {
diff -urN linux-2.2.19-pre6/drivers/char/lp.c linux/drivers/char/lp.c
--- linux-2.2.19-pre6/drivers/char/lp.c	Wed Jun  7 14:26:42 2000
+++ linux/drivers/char/lp.c	Mon Dec  3 20:57:55 2001
@@ -307,32 +307,11 @@
 		/*
 		 * NOTE: if you run with irqs you _must_ use
 		 * `tunelp /dev/lp? -c 1' to be rasonable efficient!
+		 *
+		 * ..but beware that data corruption can happen that way. -Tim
 		 */
 		if (++count == LP_CHAR(minor))
-		{
-			if (irq_ok)
-			{
-				static int first_time = 1;
-				/*
-				 * The printer is using a buggy handshake, so
-				 * revert to polling to not overload the
-				 * machine and warn the user that its printer
-				 * could get optimized trusting the irq. -arca
-				 */
-				lp_table[minor].irq_missed = 1;
-				if (first_time)
-				{
-					first_time = 0;
-					printk(KERN_WARNING "lp%d: the "
-					       "printing could be optimized "
-					       "using the TRUST_IRQ flag, "
-					       "see the top of "
-					       "linux/drivers/char/lp.c\n",
-					       minor);
-				}
-			}
 			return 0;
-		}
 	}
 
 	w_dtr(minor, lpchar);
diff -urN linux-2.2.19-pre6/drivers/net/Config.in linux/drivers/net/Config.in
--- linux-2.2.19-pre6/drivers/net/Config.in	Mon Dec  3 20:57:36 2001
+++ linux/drivers/net/Config.in	Mon Dec  3 20:57:55 2001
@@ -367,7 +367,7 @@
 #
 # Xpeed drivers
 #
-tristate 'Xpeed X200/X300 DSL NIC support' CONFIG_XPEED
+dep_tristate 'Xpeed X200/X300 DSL NIC support' CONFIG_XPEED $CONFIG_PCI
 
 endmenu
 
diff -urN linux-2.2.19-pre6/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
--- linux-2.2.19-pre6/drivers/net/ne2k-pci.c	Mon Dec  3 20:57:36 2001
+++ linux/drivers/net/ne2k-pci.c	Mon Dec  3 20:57:55 2001
@@ -33,10 +33,9 @@
 */
 
 /* These identify the driver base version and may not be removed. */
-static const char version1[] =
-"ne2k-pci.c:v1.02 10/19/2000 D. Becker/P. Gortmaker\n";
-static const char version2[] =
-"  http://www.scyld.com/network/ne2k-pci.html\n";
+static const char* version =
+"ne2k-pci.c: v1.02 for Linux 2.2, 10/19/2000, D. Becker/P. Gortmaker,"
+" http://www.scyld.com/network/ne2k-pci.html";
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -159,8 +158,7 @@
 init_module(void)
 {
 	/* We must emit version information. */
-	if (debug)
-		printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
+	printk(KERN_INFO "%s\n", version);
 
 	if (ne2k_pci_probe(0)) {
 		printk(KERN_NOTICE "ne2k-pci.c: No useable cards found, driver NOT installed.\n");
@@ -243,7 +241,7 @@
 		{
 			static unsigned version_printed = 0;
 			if (version_printed++ == 0)
-				printk(KERN_INFO "%s %s", version1, version2);
+				printk(KERN_INFO "%s\n", version);
 		}
 #endif
 
diff -urN linux-2.2.19-pre6/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- linux-2.2.19-pre6/drivers/net/via-rhine.c	Mon Dec  3 20:57:36 2001
+++ linux/drivers/net/via-rhine.c	Mon Dec  3 20:57:55 2001
@@ -81,6 +81,7 @@
 #error  You must compile this driver with "-O".
 #endif
 
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff -urN linux-2.2.19-pre6/drivers/sbus/audio/cs4215.h linux/drivers/sbus/audio/cs4215.h
--- linux-2.2.19-pre6/drivers/sbus/audio/cs4215.h	Tue Jan  4 10:12:18 2000
+++ linux/drivers/sbus/audio/cs4215.h	Mon Dec  3 20:57:55 2001
@@ -105,7 +105,7 @@
 
 /* Time Slot 6, Output Setting  */
 #define CS4215_RO(v)	v	/* Right Output Attenuation 0x3f: -94.5 dB */
-#define CS4215_SE	(1<<6)	/* Line Out Enable */
+#define CS4215_SE	(1<<6)	/* Speaker Enable */
 #define CS4215_ADI	(1<<7)	/* A/D Data Invalid: Busy in calibration */
 
 /* Time Slot 7, Input Setting */
diff -urN linux-2.2.19-pre6/drivers/sbus/audio/dbri.c linux/drivers/sbus/audio/dbri.c
--- linux-2.2.19-pre6/drivers/sbus/audio/dbri.c	Wed May  3 17:16:44 2000
+++ linux/drivers/sbus/audio/dbri.c	Mon Dec  3 20:57:55 2001
@@ -1382,8 +1382,13 @@
 
         dbri->perchip_info.play.channels = 1;
         dbri->perchip_info.play.precision = 8;
-        dbri->perchip_info.play.gain = 128;
+        dbri->perchip_info.play.gain = (AUDIO_MAX_GAIN * 7 / 10);  /* 70% */
         dbri->perchip_info.play.balance = AUDIO_MID_BALANCE;
+        dbri->perchip_info.play.port = dbri->perchip_info.play.avail_ports =
+                AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT;
+        dbri->perchip_info.record.port = AUDIO_MICROPHONE;
+        dbri->perchip_info.record.avail_ports =
+                AUDIO_MICROPHONE | AUDIO_LINE_IN;
 }
 
 /* mmcodec_setgain(dbri, int muted)
@@ -1406,6 +1411,7 @@
         } else {
                 int left_gain = (dbri->perchip_info.play.gain / 4) % 64;
                 int right_gain = (dbri->perchip_info.play.gain / 4) % 64;
+		int outport = dbri->perchip_info.play.port;
 
                 if (dbri->perchip_info.play.balance < AUDIO_MID_BALANCE) {
                         right_gain *= dbri->perchip_info.play.balance;
@@ -1416,8 +1422,12 @@
                         left_gain /= AUDIO_MID_BALANCE;
                 }
 
-                dbri->mm.data[0] = CS4215_LE | CS4215_HE | (63 - left_gain);
-                dbri->mm.data[1] = CS4215_SE | (63 - right_gain);
+		dbri->mm.data[0] = (63 - left_gain);
+		if (outport & AUDIO_HEADPHONE) dbri->mm.data[0] |= CS4215_HE;
+		if (outport & AUDIO_LINE_OUT)  dbri->mm.data[0] |= CS4215_LE;
+		dbri->mm.data[1] = (63 - right_gain);
+		if (outport & AUDIO_SPEAKER)   dbri->mm.data[1] |= CS4215_SE;
+
         }
 
         xmit_fixed(dbri, 20, *(int *)dbri->mm.data);
@@ -1585,7 +1595,7 @@
                 dbri->mm.offset = chi_offsets[i];
                 if (mmcodec_setctrl(dbri) && dbri->mm.version != 0xff) {
                         dbri->perchip_info.play.balance = AUDIO_MID_BALANCE;
-                        dbri->perchip_info.play.gain = AUDIO_MAX_GAIN/2;
+                        dbri->perchip_info.play.gain = AUDIO_MAX_GAIN*7/10;
                         return 0;
                 }
         }
@@ -1936,32 +1946,52 @@
 
 static int dbri_set_output_port(struct sparcaudio_driver *drv, int port)
 {
-        return 0;
+	struct dbri *dbri = (struct dbri *) drv->private;
+
+	port &= dbri->perchip_info.play.avail_ports;
+	dbri->perchip_info.play.port = port;
+	mmcodec_setgain(dbri, 0);
+
+	return 0;
 }
 
 static int dbri_get_output_port(struct sparcaudio_driver *drv)
 {
-        return 0;
+	struct dbri *dbri = (struct dbri *) drv->private;
+
+	return dbri->perchip_info.play.port;
 }
 
 static int dbri_set_input_port(struct sparcaudio_driver *drv, int port)
 {
-        return 0;
+	struct dbri *dbri = (struct dbri *) drv->private;
+
+	port &= dbri->perchip_info.record.avail_ports;
+	dbri->perchip_info.record.port = port;
+	mmcodec_setgain(dbri, 0);
+
+	return 0;
 }
 
 static int dbri_get_input_port(struct sparcaudio_driver *drv)
 {
-        return 0;
+	struct dbri *dbri = (struct dbri *) drv->private;
+
+	return dbri->perchip_info.record.port;
 }
 
 static int dbri_get_output_ports(struct sparcaudio_driver *drv)
 {
-        return 0;
+	struct dbri *dbri = (struct dbri *) drv->private;
+
+	return dbri->perchip_info.play.avail_ports;
 }
 
 static int dbri_get_input_ports(struct sparcaudio_driver *drv)
 {
-        return 0;
+	struct dbri *dbri = (struct dbri *) drv->private;
+
+	return dbri->perchip_info.record.avail_ports;
 }
 
 /******************* sparcaudio midlevel - driver ID ********************/
diff -urN linux-2.2.19-pre6/drivers/sbus/char/zs.c linux/drivers/sbus/char/zs.c
--- linux-2.2.19-pre6/drivers/sbus/char/zs.c	Wed Jun  7 14:26:43 2000
+++ linux/drivers/sbus/char/zs.c	Mon Dec  3 20:57:55 2001
@@ -1,4 +1,4 @@
-/* $Id: zs.c,v 1.41.2.6 2000/04/17 05:46:05 davem Exp $
+/* $Id: zs.c,v 1.41.2.7 2001/01/03 08:07:04 ecd Exp $
  * zs.c: Zilog serial port driver for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -904,7 +904,6 @@
  */
 static void change_speed(struct sun_serial *info)
 {
-	unsigned short port;
 	unsigned cflag;
 	int	quot = 0;
 	int	i;
@@ -913,7 +912,7 @@
 	if (!info->tty || !info->tty->termios)
 		return;
 	cflag = info->tty->termios->c_cflag;
-	if (!(port = info->port))
+	if (!info->port)
 		return;
 	i = cflag & CBAUD;
 	if (cflag & CBAUDEX) {
@@ -1857,7 +1856,7 @@
 
 static void show_serial_version(void)
 {
-	char *revision = "$Revision: 1.41.2.6 $";
+	char *revision = "$Revision: 1.41.2.7 $";
 	char *version, *p;
 
 	version = strchr(revision, ' ');
diff -urN linux-2.2.19-pre6/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- linux-2.2.19-pre6/drivers/scsi/gdth.c	Mon Dec  3 20:57:36 2001
+++ linux/drivers/scsi/gdth.c	Mon Dec  3 20:57:55 2001
@@ -1837,6 +1837,7 @@
     register gdth_ha_str *ha;
     ushort cdev_cnt, i;
     ulong32 bus_no, drv_cnt, drv_no, j;
+    unsigned long flags;
     gdth_getch_str *chn;
     gdth_drlist_str *drl;
     gdth_iochan_str *ioc;
@@ -1861,6 +1862,7 @@
 #ifdef GDTH_RTC
     /* read realtime clock info, send to controller */
     /* 1. wait for the falling edge of update flag */
+    spin_lock_irqsave(&rtc_lock, flags)
     for (j = 0; j < 1000000; ++j)
         if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
             break;
@@ -1872,6 +1874,7 @@
         for (j = 0; j < 12; ++j) 
             rtc[j] = CMOS_READ(j);
     } while (rtc[0] != CMOS_READ(0));
+    spin_unlock_irqrestore(&rtc_lock, flags);
     TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0],
             *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]));
     /* 3. send to controller firmware */
diff -urN linux-2.2.19-pre6/drivers/scsi/ppa.h linux/drivers/scsi/ppa.h
--- linux-2.2.19-pre6/drivers/scsi/ppa.h	Mon Dec  3 20:57:36 2001
+++ linux/drivers/scsi/ppa.h	Mon Dec  3 20:57:55 2001
@@ -10,7 +10,7 @@
 #ifndef _PPA_H
 #define _PPA_H
 
-#define   PPA_VERSION   "2.04a (for Linux 2.2.x)"
+#define   PPA_VERSION   "2.07 (for Linux 2.2.x)"
 
 /* 
  * this driver has been hacked by Matteo Frigo (athena@theory.lcs.mit.edu)
@@ -60,6 +60,8 @@
  *  by Dr. Peter Cherriman and
  *     Oleg Makarenko <omakarenko@cyberplat.ru>
  *                                                      [2.04a]
+ *
+ * Fix kernel panic on scsi timeout, 2000-08-18		[2.07]
  */
 /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */
 
@@ -176,6 +178,7 @@
 		eh_device_reset_handler:	NULL,			\
 		eh_bus_reset_handler:		ppa_reset,		\
 		eh_host_reset_handler:		ppa_reset,		\
+		use_new_eh_code:		1,			\
 		bios_param:			ppa_biosparam,		\
 		this_id:			-1,			\
 		sg_tablesize:			SG_ALL,			\
diff -urN linux-2.2.19-pre6/drivers/sound/Makefile linux/drivers/sound/Makefile
--- linux-2.2.19-pre6/drivers/sound/Makefile	Mon Dec  3 20:57:36 2001
+++ linux/drivers/sound/Makefile	Mon Dec  3 20:57:55 2001
@@ -93,8 +93,8 @@
 obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
 obj-$(CONFIG_SOUND_ICH)		+= i810_audio.o ac97_codec.o
-obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
-obj-$(CONFIG_SOUND_MAESTRO3)	+= maestro3.o
+obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o ac97_codec.o
+obj-$(CONFIG_SOUND_MAESTRO3)	+= maestro3.o ac97_codec.o
 obj-$(CONFIG_SOUND_SONICVIBES)	+= sonicvibes.o
 obj-$(CONFIG_SOUND_TRIDENT)     += trident.o ac97_codec.o
 obj-$(CONFIG_SOUND_VIA82CXXX)	+= via82cxxx_audio.o ac97_codec.o
diff -urN linux-2.2.19-pre6/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- linux-2.2.19-pre6/drivers/sound/ymfpci.c	Mon Dec  3 20:57:38 2001
+++ linux/drivers/sound/ymfpci.c	Mon Dec  3 20:57:55 2001
@@ -1919,8 +1919,8 @@
 		case PCI_DEVICE_ID_YAMAHA_724F:
 		case PCI_DEVICE_ID_YAMAHA_740C:
 			v = 0x8800;
-			if ( mpuio >= 0 ) { v|= (mpuio<<4)&0x03; }
-			if ( oplio >= 0 ) { v|= (oplio&0x03); }
+			if ( mpuio >= 0 ) { v|= mpuio<<4; }
+			if ( oplio >= 0 ) { v|= oplio; }
 			pci_write_config_word(pcidev, PCIR_ELEGCTRL, v);
 			break;
 
diff -urN linux-2.2.19-pre6/drivers/usb/Config.in linux/drivers/usb/Config.in
--- linux-2.2.19-pre6/drivers/usb/Config.in	Mon Dec  3 20:57:38 2001
+++ linux/drivers/usb/Config.in	Mon Dec  3 20:57:55 2001
@@ -10,7 +10,6 @@
 
 comment 'Miscellaneous USB options'
    bool '  Preliminary USB device filesystem' CONFIG_USB_DEVICEFS
-   bool '  Support for hot-pluggable USB devices' CONFIG_HOTPLUG
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       bool '  Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH
    else
@@ -26,76 +25,51 @@
    fi
    dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
 
-comment 'USB Devices'
-   dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
-   dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
+   comment 'USB Device Class drivers'
    dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
+   dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Mass Storage support (EXPERIMENTAL)' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+   if [ "$CONFIG_USB_STORAGE" != "n" ]; then
+      bool '    USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG
+   fi
    dep_tristate '  USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
-   dep_tristate '  USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
-   if [ "$CONFIG_USB_SERIAL" != "n" ]; then
-      bool '    USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC $CONFIG_USB_SERIAL
-      dep_tristate '    USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
-      dep_tristate '    USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
-      if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-         dep_tristate '    USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL
-         dep_tristate '    USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL
-         dep_tristate '    USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL
-         dep_tristate '    USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL
-         if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then
-            bool '      USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28
-            bool '      USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X
-            bool '      USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19
-            bool '      USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X
-            bool '      USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W
-         fi
-         dep_tristate '    USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL
-         dep_tristate '    USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL
-         dep_tristate '    USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL
+   dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
+
+   comment 'USB Human Interface Devices (HID)'
+   if [ "$CONFIG_INPUT" = "n" ]; then
+      comment '  Input core support is needed for USB HID'
+   else
+      dep_tristate '  USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT
+      if [ "$CONFIG_USB_HID" != "y" ]; then
+         dep_tristate '  USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
+         dep_tristate '  USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
       fi
-      bool '    USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG $CONFIG_USB_SERIAL
+      dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
    fi
+
+   comment 'USB Imaging devices'
+   dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
+   dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
+   dep_tristate '  Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+
+   comment 'USB Multimedia devices'
    dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-	   dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB
-      dep_tristate '  USB Mass Storage support (EXPERIMENTAL)' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
-      if [ "$CONFIG_USB_STORAGE" != "n" ]; then
-         bool '    USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG
-      fi
-   fi
-#   dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
+   dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
    dep_tristate '  DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      dep_tristate '  PLUSB Prolific USB-Network driver (EXPERIMENTAL)' CONFIG_USB_PLUSB $CONFIG_USB $CONFIG_NET
-      dep_tristate '  USB ADMtek Pegasus-based device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET
-      dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB
-      dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV
-#      dep_tristate '  Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_SCSI
-      dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
-   fi
-   if [ "$CONFIG_NET" = "y" ]; then
-      dep_tristate '  Kawasaki USB-ethernet controller' CONFIG_USB_KAWETH $CONFIG_USB
-   fi
 
-comment 'USB HID'
-   dep_tristate '  USB Human Interface Device (HID) support' CONFIG_USB_HID $CONFIG_USB
-   if [ "$CONFIG_USB_HID" != "y" ]; then
-      dep_tristate '  USB HIDBP Keyboard support' CONFIG_USB_KBD $CONFIG_USB
-      dep_tristate '  USB HIDBP Mouse support' CONFIG_USB_MOUSE $CONFIG_USB
-   fi
-   dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB
-   dep_tristate '  Logitech WingMan Force joystick support' CONFIG_USB_WMFORCE $CONFIG_USB
-   if [ "$CONFIG_VT" = "y" ]; then
-      dep_tristate '  Keyboard support' CONFIG_INPUT_KEYBDEV $CONFIG_USB 
-   fi
-   dep_tristate '  Mouse support' CONFIG_INPUT_MOUSEDEV $CONFIG_USB
-   if [ "$CONFIG_INPUT_MOUSEDEV" != "n" ]; then
-      int '   Horizontal screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
-      int '   Vertical screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_Y 768
-   fi
-   dep_tristate '  Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_USB
-   dep_tristate '  Event interface support' CONFIG_INPUT_EVDEV $CONFIG_USB
+   comment 'USB Network adaptors'
+   dep_tristate '  Kawasaki USB-ethernet controller' CONFIG_USB_KAWETH $CONFIG_USB
+   dep_tristate '  PLUSB Prolific USB-Network driver (EXPERIMENTAL)' CONFIG_USB_PLUSB $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+
+   comment 'USB port drivers'
+#   dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
+   source drivers/usb/serial/Config.in
+
+   comment 'USB misc drivers'
+   dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
 fi
 
 endmenu
diff -urN linux-2.2.19-pre6/drivers/usb/audio.c linux/drivers/usb/audio.c
--- linux-2.2.19-pre6/drivers/usb/audio.c	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/audio.c	Mon Dec  3 20:57:55 2001
@@ -174,6 +174,7 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/sound.h>
 #include <linux/soundcard.h>
@@ -562,7 +563,8 @@
 		rem = db->dmasize - ptr;
 		if (pgrem > rem)
 			pgrem = rem;
-		copy_from_user_ret((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem, -EFAULT);
+		if (copy_from_user((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem))
+			return -EFAULT;
 		size -= pgrem;
 		(char *)buffer += pgrem;
 		ptr += pgrem;
@@ -586,7 +588,8 @@
 		rem = db->dmasize - ptr;
 		if (pgrem > rem)
 			pgrem = rem;
-		copy_to_user_ret(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem, -EFAULT);
+		if (copy_to_user(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem))
+			return -EFAULT;
 		size -= pgrem;
 		(char *)buffer += pgrem;
 		ptr += pgrem;
@@ -1957,10 +1960,13 @@
 static int usb_audio_release_mixdev(struct inode *inode, struct file *file)
 {
 	struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data;
-	struct usb_audio_state *s = ms->state;
+	struct usb_audio_state *s;
 
+	lock_kernel();
+	s = ms->state;
 	down(&open_sem);
 	release(s);
+	unlock_kernel();
 	return 0;
 }
 
@@ -2038,7 +2044,8 @@
 	ms->modcnt++;
 	switch (_IOC_NR(cmd)) {
 	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		return set_rec_src(ms, val);
 
 	default:
@@ -2048,7 +2055,8 @@
 		for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++);
 		if (j >= ms->numch)
 			return -EINVAL;
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		if (wrmixer(ms, j, val))
 			return -EIO;
 		return put_user(ms->ch[j].value, (int *)arg);
@@ -2295,20 +2303,24 @@
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
 	struct dmabuf *db;
-	int ret;
+	int ret = -EINVAL;
 
+	lock_kernel();
 	if (vma->vm_flags & VM_WRITE) {
 		if ((ret = prog_dmabuf_out(as)) != 0)
-			return ret;
+			goto out;
 		db = &as->usbout.dma;
 	} else if (vma->vm_flags & VM_READ) {
 		if ((ret = prog_dmabuf_in(as)) != 0)
-			return ret;
+			goto out;
 		db = &as->usbin.dma;
 	} else
-		return -EINVAL;
+		goto out;
 
-	return dmabuf_mmap(db,  vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot);
+	ret = dmabuf_mmap(db,  vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot);
+out:
+	unlock_kernel();
+	return ret;
 }
 
 static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2352,7 +2364,8 @@
 		return 0;
 
 	case SNDCTL_DSP_SPEED:
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		if (val >= 0) {
 			if (val < 4000)
 				val = 4000;
@@ -2370,7 +2383,8 @@
 		return 0;
 
 	case SNDCTL_DSP_CHANNELS:
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		if (val != 0) {
 			val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
 			if (val == 1)
@@ -2388,7 +2402,8 @@
 				AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, (int *)arg);
 
 	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		if (val != AFMT_QUERY) {
 			if (hweight32(val) != 1)
 				return -EINVAL;
@@ -2415,7 +2430,8 @@
 		return put_user(val, (int *)arg);
 
 	case SNDCTL_DSP_SETTRIGGER:
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		if (file->f_mode & FMODE_READ) {
 			if (val & PCM_ENABLE_INPUT) {
 				if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as)))
@@ -2509,7 +2525,8 @@
 		return put_user(as->usbin.dma.fragsize, (int *)arg);
 
 	case SNDCTL_DSP_SETFRAGMENT:
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		if (file->f_mode & FMODE_READ) {
 			as->usbin.dma.ossfragshift = val & 0xffff;
 			as->usbin.dma.ossmaxfrags = (val >> 16) & 0xffff;
@@ -2536,7 +2553,8 @@
 		if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) ||
 		    (file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision))
 			return -EINVAL;
-		get_user_ret(val, (int *)arg, -EFAULT);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		if (val != 1 && val != 2 && val != 4)
 			return -EINVAL;
 		if (file->f_mode & FMODE_READ)
@@ -2624,10 +2642,13 @@
 static int usb_audio_release(struct inode *inode, struct file *file)
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
-	struct usb_audio_state *s = as->state;
-	struct usb_device *dev = s->usbdev;
+	struct usb_audio_state *s;
+	struct usb_device *dev;
 	struct usb_interface *iface;
 
+	lock_kernel();
+	s = as->state;
+	dev = s->usbdev;
 	if (file->f_mode & FMODE_WRITE)
 		drain_out(as, file->f_flags & O_NONBLOCK);
 	down(&open_sem);
@@ -2652,6 +2673,7 @@
 	as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
 	release(s);
 	wake_up(&open_wait);
+	unlock_kernel();
 	return 0;
 }
 
@@ -2672,12 +2694,10 @@
 static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
 
 static struct usb_driver usb_audio_driver = {
-	"audio",
-	usb_audio_probe,
-	usb_audio_disconnect,
-	LIST_HEAD_INIT(usb_audio_driver.driver_list), 
-	NULL,
-	0
+	name:		"audio",
+	probe:		usb_audio_probe,
+	disconnect:	usb_audio_disconnect,
+	driver_list:	LIST_HEAD_INIT(usb_audio_driver.driver_list), 
 };
 
 static void *find_descriptor(void *descstart, unsigned int desclen, void *after, 
@@ -3641,6 +3661,7 @@
 #endif
 		return NULL;
 	}
+
 	/*
 	 * audiocontrol interface found
 	 * find which configuration number is active
@@ -3721,21 +3742,21 @@
 	wake_up(&open_wait);
 }
 
-int usb_audio_init(void)
+static int __init usb_audio_init(void)
 {
 	usb_register(&usb_audio_driver);
 	return 0;
 }
 
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_audio_init();
-}
 
-void cleanup_module(void)
+static void __exit usb_audio_cleanup(void)
 {
 	usb_deregister(&usb_audio_driver);
 }
 
-#endif
+module_init(usb_audio_init);
+module_exit(usb_audio_cleanup);
+
+MODULE_AUTHOR("Alan Cox <alan@lxorguk.ukuu.org.uk>, Thomas Sailer (sailer@ife.ee.ethz.ch)");
+MODULE_DESCRIPTION("USB Audio Class driver");
+
diff -urN linux-2.2.19-pre6/drivers/usb/devices.c linux/drivers/usb/devices.c
--- linux-2.2.19-pre6/drivers/usb/devices.c	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/devices.c	Mon Dec  3 20:57:55 2001
@@ -496,8 +496,10 @@
 	lock_kernel();
 	if (!st) {
 		st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
-		if (!st)
+		if (!st) {
+			unlock_kernel();
 			return POLLIN;
+		}
 		/*
 		 * need to prevent the module from being unloaded, since
 		 * proc_unregister does not call the release method and
diff -urN linux-2.2.19-pre6/drivers/usb/hid.c linux/drivers/usb/hid.c
--- linux-2.2.19-pre6/drivers/usb/hid.c	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/hid.c	Mon Dec  3 20:57:55 2001
@@ -856,7 +856,7 @@
 		case HID_UP_CONSUMER:	/* USB HUT v1.1, pages 56-62 */
 			
 			switch (usage->hid & HID_USAGE) {
-
+				case 0x000: usage->code = 0; break; 
 				case 0x034: usage->code = KEY_SLEEP;		break;
 				case 0x036: usage->code = BTN_MISC;		break;
 				case 0x08a: usage->code = KEY_WWW;		break;
@@ -981,6 +981,9 @@
 		input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));
 	}
 
+	if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UKNOWN */
+		return;
+
 	input_event(input, usage->type, usage->code, value);
 
 	if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
@@ -1231,6 +1234,7 @@
 	hid->urbout.transfer_buffer_length = hid->out[hid->outtail].dr.length;
 	hid->urbout.transfer_buffer = hid->out[hid->outtail].buffer;
 	hid->urbout.setup_packet = (void *) &(hid->out[hid->outtail].dr);
+	hid->urbout.dev = hid->dev;
 
 	if (usb_submit_urb(&hid->urbout)) {
 		err("usb_submit_urb(out) failed");
@@ -1288,7 +1292,9 @@
 	if (hid->open++)
 		return 0;
 
-	 if (usb_submit_urb(&hid->urb))
+	hid->urb.dev = hid->dev;
+
+	if (usb_submit_urb(&hid->urb))
 		return -EIO;
 
 	return 0;
diff -urN linux-2.2.19-pre6/drivers/usb/rio500.c linux/drivers/usb/rio500.c
--- linux-2.2.19-pre6/drivers/usb/rio500.c	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/rio500.c	Mon Dec  3 20:57:55 2001
@@ -36,6 +36,7 @@
 #include <linux/malloc.h>
 #include <linux/spinlock.h>
 #include <linux/usb.h>
+#include <linux/smp_lock.h>
 
 #include "rio500_usb.h"
 
@@ -57,6 +58,7 @@
         char *obuf, *ibuf;              /* transfer buffers */
         char bulk_in_ep, bulk_out_ep;   /* Endpoint assignments */
         wait_queue_head_t wait_q;       /* for timeouts */
+	struct semaphore lock;          /* general race avoidance */
 };
 
 static struct rio_usb_data rio_instance;
@@ -65,7 +67,10 @@
 {
 	struct rio_usb_data *rio = &rio_instance;
 
+	lock_kernel();
+
 	if (rio->isopen || !rio->present) {
+		unlock_kernel();
 		return -EBUSY;
 	}
 	rio->isopen = 1;
@@ -74,6 +79,8 @@
 
 	MOD_INC_USE_COUNT;
 
+	unlock_kernel();
+
 	info("Rio opened.");
 
 	return 0;
@@ -101,6 +108,7 @@
 	unsigned char *buffer;
 	int result, requesttype;
 	int retries;
+	int retval;
 
         /* Sanity check to make sure rio is connected, powered, etc */
         if ( rio == NULL ||
@@ -120,8 +128,10 @@
 		buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
 		if (buffer == NULL)
 			return -ENOMEM;
-		if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length))
+		if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
+			free_page((unsigned long) buffer);
 			return -EFAULT;
+		}
 
 		requesttype = rio_cmd.requesttype | USB_DIR_IN |
 		    USB_TYPE_VENDOR | USB_RECIP_DEVICE;
@@ -131,6 +141,7 @@
 		     rio_cmd.index, rio_cmd.length);
 		/* Send rio control message */
 		retries = 3;
+		down(&(rio->lock));
 		while (retries) {
 			result = usb_control_msg(rio->rio_dev,
 						 usb_rcvctrlpipe(rio-> rio_dev, 0),
@@ -151,8 +162,12 @@
 				     le32_to_cpu(result),
 				     le32_to_cpu(*((long *) buffer)));
 				if (copy_to_user(rio_cmd.buffer, buffer,
-						 rio_cmd.length))
-					return -EFAULT;
+						 rio_cmd.length)) {
+					up(&(rio->lock));
+					free_page((unsigned long) buffer);
+					retval = -EFAULT;
+					goto err_out;
+				}
 				retries = 0;
 			}
 
@@ -164,6 +179,7 @@
 			   be swapped at the app level */
 
 		}
+		up(&(rio->lock));
 		free_page((unsigned long) buffer);
 		break;
 
@@ -178,8 +194,10 @@
 		buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
 		if (buffer == NULL)
 			return -ENOMEM;
-		if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length))
+		if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) {
+			free_page((unsigned long)buffer);
 			return -EFAULT;
+		}
 
 		requesttype = rio_cmd.requesttype | USB_DIR_OUT |
 		    USB_TYPE_VENDOR | USB_RECIP_DEVICE;
@@ -188,6 +206,7 @@
 		     rio_cmd.index, rio_cmd.length);
 		/* Send rio control message */
 		retries = 3;
+		down(&(rio->lock));
 		while (retries) {
 			result = usb_control_msg(rio->rio_dev,
 						 usb_sndctrlpipe(rio-> rio_dev, 0),
@@ -211,6 +230,7 @@
 			}
 
 		}
+		up(&(rio->lock));
 		free_page((unsigned long) buffer);
 		break;
 
@@ -220,6 +240,10 @@
 	}
 
 	return 0;
+
+err_out:
+	up(&(rio->lock));
+	return retval;
 }
 
 static ssize_t
@@ -234,6 +258,7 @@
 
 	int result = 0;
 	int maxretry;
+	int errn = 0;
 
         /* Sanity check to make sure rio is connected, powered, etc */
         if ( rio == NULL ||
@@ -241,19 +266,26 @@
              rio->rio_dev == NULL )
           return -1;
 
+	down(&(rio->lock));
+
 	do {
 		unsigned long thistime;
 		char *obuf = rio->obuf;
 
 		thistime = copy_size =
 		    (count >= OBUF_SIZE) ? OBUF_SIZE : count;
-		if (copy_from_user(rio->obuf, buffer, copy_size))
-			return -EFAULT;
+		if (copy_from_user(rio->obuf, buffer, copy_size)) {
+			errn = -EFAULT;
+			goto error;
+		}
 		maxretry = 5;
 		while (thistime) {
-			if (!rio->rio_dev)
-				return -ENODEV;
+			if (!rio->rio_dev) {
+				errn = -ENODEV;
+				goto error;
+			}
 			if (signal_pending(current)) {
+				up(&(rio->lock));
 				return bytes_written ? bytes_written : -EINTR;
 			}
 
@@ -266,7 +298,8 @@
 
 			if (result == USB_ST_TIMEOUT) {	/* NAK - so hold for a while */
 				if (!maxretry--) {
-					return -ETIME;
+					errn = -ETIME;
+					goto error;
 				}
 				interruptible_sleep_on_timeout(&rio-> wait_q, NAK_TIMEOUT);
 				continue;
@@ -278,14 +311,21 @@
 		};
 		if (result) {
 			err("Write Whoops - %x", result);
-			return -EIO;
+			errn = -EIO;
+			goto error;
 		}
 		bytes_written += copy_size;
 		count -= copy_size;
 		buffer += copy_size;
 	} while (count > 0);
 
+	up(&(rio->lock));
+
 	return bytes_written ? bytes_written : -EIO;
+
+error:
+	up(&(rio->lock));
+	return errn;
 }
 
 static ssize_t
@@ -307,12 +347,17 @@
 
 	read_count = 0;
 
+	down(&(rio->lock));
+
 	while (count > 0) {
 		if (signal_pending(current)) {
+			up(&(rio->lock));
 			return read_count ? read_count : -EINTR;
 		}
-		if (!rio->rio_dev)
+		if (!rio->rio_dev) {
+			up(&(rio->lock));
 			return -ENODEV;
+		}
 		this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
 
 		result = usb_bulk_msg(rio->rio_dev,
@@ -327,6 +372,7 @@
 			count = this_read = partial;
 		} else if (result == USB_ST_TIMEOUT || result == 15) {	/* FIXME: 15 ??? */
 			if (!maxretry--) {
+				up(&(rio->lock));
 				err("read_rio: maxretry timeout");
 				return -ETIME;
 			}
@@ -334,21 +380,26 @@
 						       NAK_TIMEOUT);
 			continue;
 		} else if (result != USB_ST_DATAUNDERRUN) {
+			up(&(rio->lock));
 			err("Read Whoops - result:%u partial:%u this_read:%u",
 			     result, partial, this_read);
 			return -EIO;
 		} else {
+			up(&(rio->lock));
 			return (0);
 		}
 
 		if (this_read) {
-			if (copy_to_user(buffer, ibuf, this_read))
+			if (copy_to_user(buffer, ibuf, this_read)) {
+				up(&(rio->lock));
 				return -EFAULT;
+			}
 			count -= this_read;
 			read_count += this_read;
 			buffer += this_read;
 		}
 	}
+	up(&(rio->lock));
 	return read_count;
 }
 
@@ -383,6 +434,8 @@
 	}
 	dbg("probe_rio: ibuf address:%p", rio->ibuf);
 
+	init_MUTEX(&(rio->lock));
+
 	return rio;
 }
 
@@ -415,12 +468,11 @@
 
 static struct
 usb_driver rio_driver = {
-	"rio500",
-	probe_rio,
-	disconnect_rio,
-	{NULL, NULL},
-	&usb_rio_fops,
-	RIO_MINOR
+	name:		"rio500",
+	probe:		probe_rio,
+	disconnect:	disconnect_rio,
+	fops:		&usb_rio_fops,
+	minor:		RIO_MINOR,
 };
 
 int usb_rio_init(void)
diff -urN linux-2.2.19-pre6/drivers/usb/serial/Config.in linux/drivers/usb/serial/Config.in
--- linux-2.2.19-pre6/drivers/usb/serial/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/Config.in	Mon Dec  3 20:57:55 2001
@@ -0,0 +1,29 @@
+#
+# USB Serial device configuration
+#
+mainmenu_option next_comment
+comment 'USB Serial Converter support'
+
+tristate 'USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
+if [ "$CONFIG_USB_SERIAL" != "n" ]; then
+  bool '  USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG
+  bool '  USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC
+  dep_tristate '  USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
+  dep_tristate '  USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
+  dep_tristate '  USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then
+     bool '    USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28
+     bool '    USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X
+     bool '    USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19
+     bool '    USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X
+     bool '    USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W
+  fi
+  dep_tristate '  USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+fi
+
+endmenu
diff -urN linux-2.2.19-pre6/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- linux-2.2.19-pre6/drivers/usb/serial/ftdi_sio.c	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/serial/ftdi_sio.c	Mon Dec  3 20:57:55 2001
@@ -12,6 +12,28 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * See http://reality.sgi.com/bryder_wellington/ftdi_sio for upto date testing info
+ *     and extra documentation
+ *       
+ * (12/3/2000) Bill Ryder
+ *     Added support for 8U232AM device.
+ *     Moved PID and VIDs into header file only.
+ *     Turned on low-latency for the tty (device will do high baudrates)
+ *     Added shutdown routine to close files when device removed.
+ *     More debug and error message cleanups.
+ *     
+ *
+ * (11/13/2000) Bill Ryder
+ *     Added spinlock protected open code and close code.
+ *     Multiple opens work (sort of - see webpage mentioned above).
+ *     Cleaned up comments. Removed multiple PID/VID definitions.
+ *     Factorised cts/dtr code
+ *     Made use of __FUNCTION__ in dbg's
+ *      
+ * (10/05/2000) gkh
+ *	Fixed bug with urb->dev not being set properly, now that the usb
+ *	core needs it.
+ * 
  * (09/11/2000) gkh
  *	Removed DEBUG #ifdefs with call to usb_serial_debug_data
  *
@@ -20,11 +42,11 @@
  *	driver is a loadable module now.
  *
  * (04/04/2000) Bill Ryder 
- *         Fixed bugs in TCGET/TCSET ioctls (by removing them - they are 
- *             handled elsewhere in the serial driver chain).
+ *      Fixed bugs in TCGET/TCSET ioctls (by removing them - they are 
+ *        handled elsewhere in the tty io driver chain).
  *
  * (03/30/2000) Bill Ryder 
- *         Implemented lots of ioctls
+ *      Implemented lots of ioctls
  * 	Fixed a race condition in write
  * 	Changed some dbg's to errs
  *
@@ -36,6 +58,7 @@
 /* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */
 /* Thanx to FTDI for so kindly providing details of the protocol required */
 /*   to talk to the device */
+/* Thanx to gkh and the rest of the usb dev group for all code I have assimilated :-) */
 
 
 #include <linux/config.h>
@@ -64,11 +87,19 @@
 
 #include "ftdi_sio.h"
 
-#define FTDI_VENDOR_ID			0x0403
-#define FTDI_SIO_SERIAL_CONVERTER_ID	0x8372
 
+
+
+struct ftdi_private {
+	ftdi_type_t ftdi_type;
+	char last_status_byte; /* device sends this every 40ms when open */
+	
+	
+};
 /* function prototypes for a FTDI serial converter */
 static int  ftdi_sio_startup		(struct usb_serial *serial);
+static int  ftdi_8U232AM_startup	(struct usb_serial *serial);
+static void ftdi_sio_shutdown		(struct usb_serial *serial);
 static int  ftdi_sio_open		(struct usb_serial_port *port, struct file *filp);
 static void ftdi_sio_close		(struct usb_serial_port *port, struct file *filp);
 static int  ftdi_sio_write		(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
@@ -78,8 +109,9 @@
 static int  ftdi_sio_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 
 /* All of the device info needed for the FTDI SIO serial converter */
-static __u16	ftdi_vendor_id		= FTDI_VENDOR_ID;
-static __u16	ftdi_sio_product_id	= FTDI_SIO_SERIAL_CONVERTER_ID;
+static __u16	ftdi_vendor_id		= FTDI_VID;
+static __u16	ftdi_sio_product_id	= FTDI_SIO_PID;
+static __u16	ftdi_8U232AM_product_id	= FTDI_8U232AM_PID;
 struct usb_serial_device_type ftdi_sio_device = {
 	name:			"FTDI SIO",
 	idVendor:		&ftdi_vendor_id,	/* the FTDI vendor ID */
@@ -99,6 +131,29 @@
 	ioctl:			ftdi_sio_ioctl,
 	set_termios:		ftdi_sio_set_termios,
 	startup:		ftdi_sio_startup,
+        shutdown:               ftdi_sio_shutdown,
+};
+
+struct usb_serial_device_type ftdi_8U232AM_device = {
+	name:			"FTDI 8U232AM",
+	idVendor:		&ftdi_vendor_id,	/* the FTDI vendor ID */
+	idProduct:		&ftdi_8U232AM_product_id,
+	needs_interrupt_in:	DONT_CARE,
+	needs_bulk_in:		MUST_HAVE,
+	needs_bulk_out:		MUST_HAVE,
+	num_interrupt_in:	0,
+	num_bulk_in:		1,
+	num_bulk_out:		1,
+	num_ports:		1,
+	open:			ftdi_sio_open,
+	close:			ftdi_sio_close,
+	write:			ftdi_sio_write,
+	read_bulk_callback:	ftdi_sio_read_bulk_callback,
+	write_bulk_callback:	ftdi_sio_write_bulk_callback,
+	ioctl:			ftdi_sio_ioctl,
+	set_termios:		ftdi_sio_set_termios,
+	startup:		ftdi_8U232AM_startup,
+        shutdown:               ftdi_sio_shutdown,
 };
 
 
@@ -106,119 +161,151 @@
  * ***************************************************************************
  * FTDI SIO Serial Converter specific driver functions
  * ***************************************************************************
- *
- * Bill Ryder bryder@sgi.com of Silicon Graphics, Inc. did the FTDI_SIO code
- * Thanx to FTDI for so kindly providing details of the protocol required
- *   to talk to the device - http://www.ftdi.co.uk
- *
- * Tested as at this version - other stuff might work
- * 23 March 2000
- *     Works:
- *      Baudrates - 9600, 38400,19200, 57600, 115200  
- *      TIOCMBIC - TIOCM_DTR / TIOCM_RTS 
- *      TIOCMBIS - TIOCM_DTR / TIOCM_RTS 
- *      TIOCMSET - DTR on/RTSon  / DTR off, RTS off 
- *      no parity:CS8 even parity:CS7 odd parity:CS7 
- *      CRTSCTS flow control 
- *     
- *      Pilot-xfer zillions of times
- *  
- *      cu works with dir option 
- *
- *   Not Tested (ie might not work): 
- *      xon/xoff flow control 
- *      ppp (modem handling in general) 
- *
- *   KNOWN BUGS:
- *    Multiple Opens
- *    ==============
- *      Seems to have problem when opening an already open port, 
- *      Get I/O error on first attempt, then it lets you in. 
- *      Need to do proper usage counting - keep registered callbacks for first opener.
- *     
- *     Reproduce with: 
- *       cu -l /dev/ttyUSB0 dir 
- *       whilst cu is running do:
- *        stty -a < /dev/ttyUSB0  
- *
- *     from stty get: 'bash: /dev/ttyUSB0: Invalid argument ' 
- *     from cu get 
- *        write: Invalid argument 
- *    
- *    Initialisation Problem
- *    ======================
- *    Pilot transfer required me to run the serial_loopback program before it would work.
- *    Still working on this. See the webpage http://reality.sgi.com/bryder_wellington/ftdi_sio
- *
  */
 
 #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
 
-/* do some startup allocations not currently performed by usb_serial_probe() */
+/* utility functions to set and unset dtr and rts */
+#define HIGH 1
+#define LOW 0
+static int set_rts(struct usb_device *dev, 
+		   unsigned int pipe,
+		   int high_or_low)
+{
+	static char buf[1];
+	unsigned ftdi_high_or_low = (high_or_low? FTDI_SIO_SET_RTS_HIGH : 
+				FTDI_SIO_SET_RTS_LOW);
+	return(usb_control_msg(dev, pipe,
+			       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+			       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+			       ftdi_high_or_low, 0, 
+			       buf, 0, WDR_TIMEOUT));
+}
+static int set_dtr(struct usb_device *dev, 
+		   unsigned int pipe,
+		   int high_or_low)
+{
+	static char buf[1];
+	unsigned ftdi_high_or_low = (high_or_low? FTDI_SIO_SET_DTR_HIGH : 
+				FTDI_SIO_SET_DTR_LOW);
+	return(usb_control_msg(dev, pipe,
+			       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+			       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+			       ftdi_high_or_low, 0, 
+			       buf, 0, WDR_TIMEOUT));
+}
+
+
+
 static int ftdi_sio_startup (struct usb_serial *serial)
 {
+	struct ftdi_private *priv;
+	
 	init_waitqueue_head(&serial->port[0].write_wait);
 	
+	priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
+	if (!priv){
+		err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
+		return -ENOMEM;
+	}
+
+	priv->ftdi_type = sio;
+	
+	return (0);
+}
+
+
+static int ftdi_8U232AM_startup (struct usb_serial *serial)
+{
+	struct ftdi_private *priv;
+ 
+	init_waitqueue_head(&serial->port[0].write_wait);
+
+	priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
+	if (!priv){
+		err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
+		return -ENOMEM;
+	}
+
+	priv->ftdi_type = F8U232AM;
+	
 	return (0);
 }
 
+static void ftdi_sio_shutdown (struct usb_serial *serial)
+{
+	
+	dbg (__FUNCTION__);
+
+	/* Close ports if they are open */
+	while (serial->port[0].open_count > 0) {
+		ftdi_sio_close (&serial->port[0], NULL);
+	}
+	if (serial->port->private){
+		kfree(serial->port->private);
+		serial->port->private = NULL;
+	}
+}
+
+
+
 static int  ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
 { /* ftdi_sio_open */
 	struct termios tmp_termios;
 	struct usb_serial *serial = port->serial;
+	unsigned long flags;	/* Used for spinlock */
+	int result;
 	char buf[1]; /* Needed for the usb_control_msg I think */
 
-	dbg("ftdi_sio_open port %d", port->number);
-
-        /* FIXME - multiple concurrent opens cause trouble */
-	if (port->active) {
-		err ("port already open");
-		return -EINVAL;
-	}
-	port->active = 1; /* FIXME - For multiple open this should increment */
-
-	/* See ftdi_sio.h for description of what is reset */
-	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
-			FTDI_SIO_RESET_SIO, 
-			0, buf, 0, WDR_TIMEOUT);
-
-	/* Setup termios */
-	port->tty->termios->c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	dbg(__FUNCTION__);
 
+	spin_lock_irqsave (&port->port_lock, flags);
 	
-	ftdi_sio_set_termios(port, &tmp_termios);	
+	MOD_INC_USE_COUNT;
+	++port->open_count;
 
-	/* Disable flow control */
-	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
-			    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
-			    0, 0, 
-			    buf, 0, WDR_TIMEOUT) < 0) {
-		err("error from flowcontrol urb");
-		return(-EINVAL);
-	}	    
-
-	/* Turn on RTS and DTR since we are not flow controlling*/
-	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-			    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-			    (unsigned)FTDI_SIO_SET_DTR_HIGH, 0, 
-			    buf, 0, WDR_TIMEOUT) < 0) {
-		err("Error from DTR HIGH urb");
+	if (!port->active){
+		port->active = 1;
+
+		spin_unlock_irqrestore (&port->port_lock, flags);
+
+		/* do not allow a task to be queued to deliver received data */
+		port->tty->low_latency = 1;
+
+		/* No error checking for this (will get errors later anyway) */
+		/* See ftdi_sio.h for description of what is reset */
+		usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
+				FTDI_SIO_RESET_SIO, 
+				0, buf, 0, WDR_TIMEOUT);
+
+		/* Setup termios defaults. According to tty_io.c the 
+		   settings are driver specific */
+		port->tty->termios->c_cflag =
+			B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+
+		/* ftdi_sio_set_termios  will send usb control messages */
+		ftdi_sio_set_termios(port, &tmp_termios);	
+
+		/* Turn on RTS and DTR since we are not flow controlling by default */
+		if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0) {
+			err(__FUNCTION__ " Error from DTR HIGH urb");
+		}
+		if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0){
+			err(__FUNCTION__ " Error from RTS HIGH urb");
+		}
+	
+		/* Start reading from the device */
+		FILL_BULK_URB(port->read_urb, serial->dev, 
+			      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+			      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
+			      ftdi_sio_read_bulk_callback, port);
+		result = usb_submit_urb(port->read_urb);
+		if (result)
+			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+	} else { /* the port was already active - so no initialisation is done */
+		spin_unlock_irqrestore (&port->port_lock, flags);
 	}
-	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-			    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-			    (unsigned)FTDI_SIO_SET_RTS_HIGH, 0, 
-			    buf, 0, WDR_TIMEOUT) < 0) {
-		err("Error from RTS HIGH urb");
-	}
-	
-	/*Start reading from the device*/
-	if (usb_submit_urb(port->read_urb))
-		err("usb_submit_urb(read bulk) failed");
 
 	return (0);
 } /* ftdi_sio_open */
@@ -229,41 +316,52 @@
 	struct usb_serial *serial = port->serial;
 	unsigned int c_cflag = port->tty->termios->c_cflag;
 	char buf[1];
+	unsigned long flags;
 
-	dbg("ftdi_sio_close port %d", port->number);
-	
-	if (c_cflag & HUPCL){
-		/* Disable flow control */
-		if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
-				    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
-				    0, 0, 
-				    buf, 0, WDR_TIMEOUT) < 0) {
-			err("error from flowcontrol urb");
-		}	    
+	dbg( __FUNCTION__);
 
-		/* drop DTR */
- 		if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-				    (unsigned)FTDI_SIO_SET_DTR_LOW, 0, 
-				    buf, 0, WDR_TIMEOUT) < 0) {
-			err("Error from DTR LOW urb");
+	spin_lock_irqsave (&port->port_lock, flags);
+	--port->open_count;
+
+	if (port->open_count <= 0) {
+		spin_unlock_irqrestore (&port->port_lock, flags);
+		if (c_cflag & HUPCL){
+			/* Disable flow control */
+			if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+					    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
+					    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+					    0, 0, 
+					    buf, 0, WDR_TIMEOUT) < 0) {
+				err("error from flowcontrol urb");
+			}	    
+
+			/* drop DTR */
+			if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0), LOW) < 0){
+				err("Error from DTR LOW urb");
+			}
+			/* drop RTS */
+			if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0) {
+				err("Error from RTS LOW urb");
+			}	
+		} /* Note change no line is hupcl is off */
+
+		/* shutdown our bulk reads and writes */
+		usb_unlink_urb (port->write_urb);
+		usb_unlink_urb (port->read_urb);
+		port->active = 0;
+		port->open_count = 0;
+	} else {  
+		spin_unlock_irqrestore (&port->port_lock, flags);
+
+		/* Send a HUP if necessary */
+		if (!(port->tty->termios->c_cflag & CLOCAL)){
+			tty_hangup(port->tty);
 		}
-		/* drop RTS */
-		if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-				    (unsigned)FTDI_SIO_SET_RTS_LOW, 0, 
-				    buf, 0, WDR_TIMEOUT) < 0) {
-			err("Error from RTS LOW urb");
-		}	
+		
 	}
 
-	/* shutdown our bulk reads and writes */
-	usb_unlink_urb (port->write_urb);
-	usb_unlink_urb (port->read_urb);
-	port->active = 0;
+	MOD_DEC_USE_COUNT;
+
 } /* ftdi_sio_close */
 
 
@@ -277,32 +375,37 @@
 			   const unsigned char *buf, int count)
 { /* ftdi_sio_write */
 	struct usb_serial *serial = port->serial;
-	const int data_offset = 1;
+	struct ftdi_private *priv = (struct ftdi_private *)port->private;
+	int data_offset ;
 	int rc; 
+	int result;
 	DECLARE_WAITQUEUE(wait, current);
 	
-	dbg("ftdi_sio_serial_write port %d, %d bytes", port->number, count);
+	dbg(__FUNCTION__ " port %d, %d bytes", port->number, count);
 
 	if (count == 0) {
 		err("write request of 0 bytes");
 		return 0;
 	}
+	
+	if (priv->ftdi_type == sio){
+		data_offset = 1;
+	} else {
+		data_offset = 0;
+	}
+        dbg("data_offset set to %d",data_offset);
 
 	/* only do something if we have a bulk out endpoint */
 	if (serial->num_bulk_out) {
 		unsigned char *first_byte = port->write_urb->transfer_buffer;
 
 		/* Was seeing a race here, got a read callback, then write callback before
-		   hitting interuptible_sleep_on  - so wrapping in add_wait_queue stuff */
+		   hitting interuptible_sleep_on  - so wrapping in a wait_queue */
 
 		add_wait_queue(&port->write_wait, &wait);
 		set_current_state (TASK_INTERRUPTIBLE);
 		while (port->write_urb->status == -EINPROGRESS) {
-			dbg("ftdi_sio - write in progress - retrying");
-			if (0 /* file->f_flags & O_NONBLOCK */) {
-				rc = -EAGAIN;
-				goto err;
-			}
+			dbg(__FUNCTION__ " write in progress - retrying");
 			if (signal_pending(current)) {
 				current->state = TASK_RUNNING;
 				remove_wait_queue(&port->write_wait, &wait);
@@ -330,20 +433,28 @@
 			       buf, count - data_offset );
 		}  
 
-		/* Write the control byte at the front of the packet*/
 		first_byte = port->write_urb->transfer_buffer;
-		*first_byte = 1 | ((count-data_offset) << 2) ; 
+		if (data_offset > 0){
+			/* Write the control byte at the front of the packet*/
+			*first_byte = 1 | ((count-data_offset) << 2) ; 
+		}
 
-		dbg("Bytes: %d, Control Byte: 0o%03o",count, first_byte[0]);
+		dbg(__FUNCTION__ " Bytes: %d, First Byte: 0o%03o",count, first_byte[0]);
 		usb_serial_debug_data (__FILE__, __FUNCTION__, count, first_byte);
 		
 		/* send the data out the bulk port */
-		port->write_urb->transfer_buffer_length = count;
-
-		if (usb_submit_urb(port->write_urb))
-			err("usb_submit_urb(write bulk) failed");
+		FILL_BULK_URB(port->write_urb, serial->dev, 
+			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
+			      port->write_urb->transfer_buffer, count,
+			      ftdi_sio_write_bulk_callback, port);
+		
+		result = usb_submit_urb(port->write_urb);
+		if (result) {
+			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+			return 0;
+		}
 
-		dbg("write returning: %d", count - data_offset);
+		dbg(__FUNCTION__ " write returning: %d", count - data_offset);
 		return (count - data_offset);
 	}
 	
@@ -387,14 +498,16 @@
 static void ftdi_sio_read_bulk_callback (struct urb *urb)
 { /* ftdi_sio_serial_buld_callback */
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct ftdi_private *priv = (struct ftdi_private *)port->private;
 	struct usb_serial *serial;
        	struct tty_struct *tty = port->tty ;
        	unsigned char *data = urb->transfer_buffer;
 
 	const int data_offset = 2;
 	int i;
+	int result;
 
-	dbg("ftdi_sio read callback");
+	dbg(__FUNCTION__);
 
 	if (port_paranoia_check (port, "ftdi_sio_read_bulk_callback")) {
 		return;
@@ -404,10 +517,6 @@
 	if (serial_paranoia_check (serial, "ftdi_sio_read_bulk_callback")) {
 		return;
 	}
-	
-	/* TO DO -- check for hung up line and handle appropriately: */
-	/*   send hangup (need to find out how to do this) */
- 
 
 	if (urb->status) {
 		/* This will happen at close every time so it is a dbg not an err */
@@ -421,6 +530,14 @@
                 dbg("Just status");
         }
 
+	priv->last_status_byte = data[0]; /* this has modem control lines */
+
+	/* TO DO -- check for hung up line and handle appropriately: */
+	/*   send hangup  */
+	/* See acm.c - you do a tty_hangup  - eg tty_hangup(tty) */
+	/* if CD is dropped and the line is not CLOCAL then we should hangup */
+
+
 	if (urb->actual_length > data_offset) {
 		for (i = data_offset ; i < urb->actual_length ; ++i) {
 			tty_insert_flip_char(tty, data[i], 0);
@@ -429,12 +546,65 @@
 	}
 
 	/* Continue trying to always read  */
-	if (usb_submit_urb(urb))
-		err("failed resubmitting read urb");
+	FILL_BULK_URB(urb, serial->dev, 
+		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+		      urb->transfer_buffer, urb->transfer_buffer_length,
+		      ftdi_sio_read_bulk_callback, port);
+
+	result = usb_submit_urb(urb);
+	if (result)
+		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 
 	return;
 } /* ftdi_sio_serial_read_bulk_callback */
 
+
+__u16 translate_baudrate_to_ftdi(unsigned int cflag, ftdi_type_t ftdi_type) 
+{ /* translate_baudrate_to_ftdi */
+	
+	__u16 urb_value = ftdi_sio_b9600;
+
+	if (ftdi_type == sio){
+		switch(cflag & CBAUD){
+		case B0: break; /* ignored by this */
+		case B300: urb_value = ftdi_sio_b300; dbg("Set to 300"); break;
+		case B600: urb_value = ftdi_sio_b600; dbg("Set to 600") ; break;
+		case B1200: urb_value = ftdi_sio_b1200; dbg("Set to 1200") ; break;
+		case B2400: urb_value = ftdi_sio_b2400; dbg("Set to 2400") ; break;
+		case B4800: urb_value = ftdi_sio_b4800; dbg("Set to 4800") ; break;
+		case B9600: urb_value = ftdi_sio_b9600; dbg("Set to 9600") ; break;
+		case B19200: urb_value = ftdi_sio_b19200; dbg("Set to 19200") ; break;
+		case B38400: urb_value = ftdi_sio_b38400; dbg("Set to 38400") ; break;
+		case B57600: urb_value = ftdi_sio_b57600; dbg("Set to 57600") ; break;
+		case B115200: urb_value = ftdi_sio_b115200; dbg("Set to 115200") ; break;
+		default: dbg(__FUNCTION__ " FTDI_SIO does not support the baudrate (%d) requested",
+			     (cflag & CBAUD)); 
+		   break;
+		}
+	} else { /* it is 8U232AM */
+		switch(cflag & CBAUD){
+		case B0: break; /* ignored by this */
+		case B300: urb_value = ftdi_8U232AM_48MHz_b300; dbg("Set to 300"); break;
+		case B600: urb_value = ftdi_8U232AM_48MHz_b600; dbg("Set to 600") ; break;
+		case B1200: urb_value = ftdi_8U232AM_48MHz_b1200; dbg("Set to 1200") ; break;
+		case B2400: urb_value = ftdi_8U232AM_48MHz_b2400; dbg("Set to 2400") ; break;
+		case B4800: urb_value = ftdi_8U232AM_48MHz_b4800; dbg("Set to 4800") ; break;
+		case B9600: urb_value = ftdi_8U232AM_48MHz_b9600; dbg("Set to 9600") ; break;
+		case B19200: urb_value = ftdi_8U232AM_48MHz_b19200; dbg("Set to 19200") ; break;
+		case B38400: urb_value = ftdi_8U232AM_48MHz_b38400; dbg("Set to 38400") ; break;
+		case B57600: urb_value = ftdi_8U232AM_48MHz_b57600; dbg("Set to 57600") ; break;
+		case B115200: urb_value = ftdi_8U232AM_48MHz_b115200; dbg("Set to 115200") ; break;
+		case B230400: urb_value = ftdi_8U232AM_48MHz_b230400; dbg("Set to 230400") ; break;
+		case B460800: urb_value = ftdi_8U232AM_48MHz_b460800; dbg("Set to 460800") ; break;
+		case B921600: urb_value = ftdi_8U232AM_48MHz_b921600; dbg("Set to 921600") ; break;
+		default: dbg(__FUNCTION__ " The baudrate (%d) requested is not implemented",
+			     (cflag & CBAUD)); 
+		   break;
+		}
+	}
+	return(urb_value);
+}
+
 /* As I understand this - old_termios contains the original termios settings */
 /*  and tty->termios contains the new setting to be used */
 /* */
@@ -444,10 +614,12 @@
 { /* ftdi_sio_set_termios */
 	struct usb_serial *serial = port->serial;
 	unsigned int cflag = port->tty->termios->c_cflag;
-	__u16 urb_value; /* Will hold the new flags */
+	struct ftdi_private *priv = (struct ftdi_private *)port->private;	
+	__u16 urb_value; /* will hold the new flags */
 	char buf[1]; /* Perhaps I should dynamically alloc this? */
 	
-	dbg("ftdi_sio_set_termios port %d", port->number);
+	
+	dbg(__FUNCTION__);
 
 
 	/* FIXME -For this cut I don't care if the line is really changing or 
@@ -481,26 +653,12 @@
 			    FTDI_SIO_SET_DATA_REQUEST_TYPE,
 			    urb_value , 0,
 			    buf, 0, 100) < 0) {
-		err("FAILED to set databits/stopbits/parity");
+		err(__FUNCTION__ " FAILED to set databits/stopbits/parity");
 	}	   
 
 	/* Now do the baudrate */
-
-	switch(cflag & CBAUD){
-	case B0: break; /* Handled below */
-	case B300: urb_value = ftdi_sio_b300; dbg("Set to 300"); break;
-	case B600: urb_value = ftdi_sio_b600; dbg("Set to 600") ; break;
-	case B1200: urb_value = ftdi_sio_b1200; dbg("Set to 1200") ; break;
-	case B2400: urb_value = ftdi_sio_b2400; dbg("Set to 2400") ; break;
-	case B4800: urb_value = ftdi_sio_b4800; dbg("Set to 4800") ; break;
-	case B9600: urb_value = ftdi_sio_b9600; dbg("Set to 9600") ; break;
-	case B19200: urb_value = ftdi_sio_b19200; dbg("Set to 19200") ; break;
-	case B38400: urb_value = ftdi_sio_b38400; dbg("Set to 38400") ; break;
-	case B57600: urb_value = ftdi_sio_b57600; dbg("Set to 57600") ; break;
-	case B115200: urb_value = ftdi_sio_b115200; dbg("Set to 115200") ; break;
-	default: dbg("FTDI_SIO does not support the baudrate requested"); 
-		/* FIXME - how to return an error for this? */ break;
-	}
+	urb_value = translate_baudrate_to_ftdi((cflag & CBAUD), priv->ftdi_type);
+	
 	if ((cflag & CBAUD) == B0 ) {
 		/* Disable flow control */
 		if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
@@ -508,38 +666,31 @@
 				    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
 				    0, 0, 
 				    buf, 0, WDR_TIMEOUT) < 0) {
-			err("error from disable flowcontrol urb");
+			err(__FUNCTION__ " error from disable flowcontrol urb");
 		}	    
 		/* Drop RTS and DTR */
-		if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-				    (unsigned)FTDI_SIO_SET_DTR_LOW, 0, 
-				    buf, 0, WDR_TIMEOUT) < 0) {
-			err("Error from DTR LOW urb");
+		if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0){
+			err(__FUNCTION__ " Error from DTR LOW urb");
 		}
-		if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-				    (unsigned)FTDI_SIO_SET_RTS_LOW, 0, 
-				    buf, 0, WDR_TIMEOUT) < 0) {
-			err("Error from RTS LOW urb");
+		if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0){
+			err(__FUNCTION__ " Error from RTS LOW urb");
 		}	
 		
 	} else {
+		/* set the baudrate determined before */
 		if (usb_control_msg(serial->dev, 
 				    usb_sndctrlpipe(serial->dev, 0),
 				    FTDI_SIO_SET_BAUDRATE_REQUEST, 
 				    FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
 				    urb_value, 0, 
 				    buf, 0, 100) < 0) {
-			err("urb failed to set baurdrate");
+			err(__FUNCTION__ " urb failed to set baurdrate");
 		}
 	}
 	/* Set flow control */
 	/* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
 	if (cflag & CRTSCTS) {
-		dbg("Setting to CRTSCTS flow control");
+		dbg(__FUNCTION__ " Setting to CRTSCTS flow control");
 		if (usb_control_msg(serial->dev, 
 				    usb_sndctrlpipe(serial->dev, 0),
 				    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
@@ -550,9 +701,8 @@
 		}		
 		
 	} else { 
-		/* CHECK Assuming XON/XOFF handled by stack - not by device */
-		/* Disable flow control */
-		dbg("Turning off hardware flow control");
+		/* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
+		dbg(__FUNCTION__ " Turning off hardware flow control");
 		if (usb_control_msg(serial->dev, 
 				    usb_sndctrlpipe(serial->dev, 0),
 				    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
@@ -569,26 +719,38 @@
 static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
 {
 	struct usb_serial *serial = port->serial;
+	struct ftdi_private *priv = (struct ftdi_private *)port->private;
 	__u16 urb_value=0; /* Will hold the new flags */
 	char buf[1];
 	int  ret, mask;
 	
-	dbg("ftdi_sio_ioctl - cmd 0x%04x", cmd);
+	dbg(__FUNCTION__ " cmd 0x%04x", cmd);
 
 	/* Based on code from acm.c and others */
 	switch (cmd) {
 
 	case TIOCMGET:
-		dbg("TIOCMGET");
-		/* Request the status from the device */
-		if ((ret = usb_control_msg(serial->dev, 
-					   usb_rcvctrlpipe(serial->dev, 0),
-					   FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
-					   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
-					   0, 0, 
-					   buf, 1, HZ * 5)) < 0 ) {
-			dbg("Get not get modem status of device");
-			return(ret);
+		dbg(__FUNCTION__ " TIOCMGET");
+		/* The MODEM_STATUS_REQUEST works for the sio but not the 232 */
+		if (priv->ftdi_type == sio){
+			/* TO DECIDE - use the 40ms status packets or not? */
+			/*   PRO: No need to send urb */
+			/*   CON: Could be 40ms out of date */
+
+			/* Request the status from the device */
+			if ((ret = usb_control_msg(serial->dev, 
+						   usb_rcvctrlpipe(serial->dev, 0),
+						   FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
+						   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+						   0, 0, 
+						   buf, 1, WDR_TIMEOUT)) < 0 ) {
+				err(__FUNCTION__ " Could not get modem status of device - err: %d",
+				    ret);
+				return(ret);
+			}
+		} else {
+			/* This gets updated every 40ms - so just copy it in */
+			buf[0] = priv->last_status_byte;
 		}
 
 		return put_user((buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
@@ -599,51 +761,33 @@
 		break;
 
 	case TIOCMSET: /* Turns on and off the lines as specified by the mask */
-		dbg("TIOCMSET");
+		dbg(__FUNCTION__ " TIOCMSET");
 		if ((ret = get_user(mask, (unsigned long *) arg))) return ret;
-		urb_value = ((mask & TIOCM_DTR) ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW);
-		if ((ret = usb_control_msg(serial->dev, 
-				    usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-				    urb_value , 0,
-				    buf, 0, WDR_TIMEOUT)) < 0){
-			err("Urb to set DTR failed");
-			return(ret);
-		}
-		urb_value = ((mask & TIOCM_RTS) ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW);
-		if ((ret = usb_control_msg(serial->dev, 
-				    usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-				    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-				    urb_value , 0,
-				    buf, 0, WDR_TIMEOUT)) < 0){
-			err("Urb to set RTS failed");
-			return(ret);
-		}
+		urb_value = ((mask & TIOCM_DTR) ? HIGH : LOW);
+		if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),urb_value) < 0){
+			err("Error from DTR set urb (TIOCMSET)");
+		}
+		urb_value = ((mask & TIOCM_RTS) ? HIGH : LOW);
+		if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),urb_value) < 0){
+			err("Error from RTS set urb (TIOCMSET)");
+		}	
 		break;
 					
 	case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
-		dbg("TIOCMBIS");
+		dbg(__FUNCTION__ " TIOCMBIS");
  	        if ((ret = get_user(mask, (unsigned long *) arg))) return ret;
   	        if (mask & TIOCM_DTR){
-			if ((ret = usb_control_msg(serial->dev, 
-					    usb_sndctrlpipe(serial->dev, 0),
-					    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-					    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-					    FTDI_SIO_SET_DTR_HIGH , 0,
-					    buf, 0, WDR_TIMEOUT)) < 0){
+			if ((ret = set_dtr(serial->dev, 
+					   usb_sndctrlpipe(serial->dev, 0),
+					   HIGH)) < 0) {
 				err("Urb to set DTR failed");
 				return(ret);
-				}
 			}
-			if (mask & TIOCM_RTS) {
-			if ((ret = usb_control_msg(serial->dev, 
-					    usb_sndctrlpipe(serial->dev, 0),
-					    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-					    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-					    FTDI_SIO_SET_RTS_HIGH , 0,
-					    buf, 0, WDR_TIMEOUT)) < 0){
+		}
+		if (mask & TIOCM_RTS) {
+			if ((ret = set_rts(serial->dev, 
+					   usb_sndctrlpipe(serial->dev, 0),
+					   HIGH)) < 0){
 				err("Urb to set RTS failed");
 				return(ret);
 			}
@@ -651,26 +795,20 @@
 					break;
 
 	case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
-		dbg("TIOCMBIC");
+		dbg(__FUNCTION__ " TIOCMBIC");
  	        if ((ret = get_user(mask, (unsigned long *) arg))) return ret;
   	        if (mask & TIOCM_DTR){
-			if ((ret = usb_control_msg(serial->dev, 
-					    usb_sndctrlpipe(serial->dev, 0),
-					    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-					    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-					    FTDI_SIO_SET_DTR_LOW , 0,
-					    buf, 0, WDR_TIMEOUT)) < 0){
+			if ((ret = set_dtr(serial->dev, 
+					   usb_sndctrlpipe(serial->dev, 0),
+					   LOW)) < 0){
 				err("Urb to unset DTR failed");
 				return(ret);
 			}
 		}	
 		if (mask & TIOCM_RTS) {
-			if ((ret = usb_control_msg(serial->dev, 
-					       usb_sndctrlpipe(serial->dev, 0),
-					       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-					       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-					    FTDI_SIO_SET_RTS_LOW , 0,
-					    buf, 0, WDR_TIMEOUT)) < 0){
+			if ((ret = set_rts(serial->dev, 
+					   usb_sndctrlpipe(serial->dev, 0),
+					   LOW)) < 0){
 				err("Urb to unset RTS failed");
 				return(ret);
 			}
@@ -690,25 +828,28 @@
 	  /* This is not an error - turns out the higher layers will do 
 	   *  some ioctls itself (see comment above)
  	   */
-		dbg("ftdi_sio ioctl arg not supported - it was 0x%04x",cmd);
+		dbg(__FUNCTION__ " arg not supported - it was 0x%04x",cmd);
 		return(-ENOIOCTLCMD);
 		break;
 	}
-	dbg("ftdi_sio_ioctl returning 0");
 	return 0;
 } /* ftdi_sio_ioctl */
 
 
 static int __init ftdi_sio_init (void)
 {
+	dbg(__FUNCTION__);
 	usb_serial_register (&ftdi_sio_device);
+	usb_serial_register (&ftdi_8U232AM_device);
 	return 0;
 }
 
 
 static void __exit ftdi_sio_exit (void)
 {
+	dbg(__FUNCTION__);
 	usb_serial_deregister (&ftdi_sio_device);
+	usb_serial_deregister (&ftdi_8U232AM_device);
 }
 
 
@@ -716,4 +857,4 @@
 module_exit(ftdi_sio_exit);
 
 MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>");
-MODULE_DESCRIPTION("USB FTDI SIO driver");
+MODULE_DESCRIPTION("USB FTDI RS232 converters driver");
diff -urN linux-2.2.19-pre6/drivers/usb/serial/ftdi_sio.h linux/drivers/usb/serial/ftdi_sio.h
--- linux-2.2.19-pre6/drivers/usb/serial/ftdi_sio.h	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/serial/ftdi_sio.h	Mon Dec  3 20:57:55 2001
@@ -20,9 +20,9 @@
  */
 
 #define FTDI_VID	0x0403	/* Vendor Id */
-#define FTDI_SIO_PID	0x8372	/* Product Id */
+#define FTDI_SIO_PID	0x8372	/* Product Id SIO application of 8U100AX  */
+#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
 
-/* Vendor Request Interface */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
 #define FTDI_SIO_SET_FLOW_CTRL	2 /* Set flow control register */
@@ -86,6 +86,12 @@
  */
 
 typedef enum {
+	sio = 1,
+	F8U232AM = 2,
+} ftdi_type_t;
+
+
+typedef enum {
  ftdi_sio_b300 = 0, 
  ftdi_sio_b600 = 1, 
  ftdi_sio_b1200 = 2,
@@ -97,6 +103,38 @@
  ftdi_sio_b57600 = 8,
  ftdi_sio_b115200 = 9
 } FTDI_SIO_baudrate_t ;
+
+
+typedef enum {
+  ftdi_8U232AM_12MHz_b300 = 0x09c4,
+  ftdi_8U232AM_12MHz_b600 = 0x04E2,
+  ftdi_8U232AM_12MHz_b1200 = 0x0271,
+  ftdi_8U232AM_12MHz_b2400 = 0x4138,
+  ftdi_8U232AM_12MHz_b4800 = 0x809c,
+  ftdi_8U232AM_12MHz_b9600 = 0xc04e,
+  ftdi_8U232AM_12MHz_b19200 = 0x0027,
+  ftdi_8U232AM_12MHz_b38400 = 0x4013,
+  ftdi_8U232AM_12MHz_b57600 = 0x000d,
+  ftdi_8U232AM_12MHz_b115200 = 0x4006,
+  ftdi_8U232AM_12MHz_b230400 = 0x8003,
+} FTDI_8U232AM_12MHz_baudrate_t;
+/* Apparently all devices are 48MHz */
+typedef enum {
+  ftdi_8U232AM_48MHz_b300 = 0x2710,
+  ftdi_8U232AM_48MHz_b600 = 0x1388,
+  ftdi_8U232AM_48MHz_b1200 = 0x09c4,
+  ftdi_8U232AM_48MHz_b2400 = 0x04e2,
+  ftdi_8U232AM_48MHz_b4800 = 0x0271,
+  ftdi_8U232AM_48MHz_b9600 = 0x4138,
+  ftdi_8U232AM_48MHz_b19200 = 0x809c,
+  ftdi_8U232AM_48MHz_b38400 = 0xc04e,
+  ftdi_8U232AM_48MHz_b57600 = 0x0034,
+  ftdi_8U232AM_48MHz_b115200 = 0x001a,
+  ftdi_8U232AM_48MHz_b230400 = 0x000d,
+  ftdi_8U232AM_48MHz_b460800 = 0x4006,
+  ftdi_8U232AM_48MHz_b921600 = 0x8003,
+
+} FTDI_8U232AM_48MHz_baudrate_t;
 
 #define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA
 #define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40
diff -urN linux-2.2.19-pre6/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
--- linux-2.2.19-pre6/drivers/usb/serial/keyspan.c	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/serial/keyspan.c	Mon Dec  3 20:57:55 2001
@@ -19,21 +19,33 @@
   and Keyspan, Inc the manufacturers of the Keyspan USB-serial products.
   Thanks Guys :)
   
+  Thanks to Paulus for miscellaneous tidy ups, some largish chunks
+  of much nicer and/or completely new code and (perhaps most uniquely)
+  having the patience to sit down and explain why and where he'd changed
+  stuff. 
+  
   Tip 'o the hat to Linuxcare for supporting staff in their work on
   open source projects.
 
-  Wed Jul 19 14:00:42 EST 2000 gkh
-	Added module_init and module_exit functions to handle the fact that this
-	driver is a loadable module now.
-
-  Tue Jul 18 16:14:52 EST 2000 Hugh
-    Basic character input/output for USA-19 now mostly works,
-    fixed at 9600 baud for the moment.
-
+  Change History
+    Tue Oct 10 23:15:33 EST 2000 Hugh
+      Merged Paul's changes with my USA-49W mods.  Work in progress
+      still...
+  
+    Wed Jul 19 14:00:42 EST 2000 gkh
+      Added module_init and module_exit functions to handle the fact that
+      this driver is a loadable module now.
+ 
+    Tue Jul 18 16:14:52 EST 2000 Hugh
+      Basic character input/output for USA-19 now mostly works,
+      fixed at 9600 baud for the moment.
+
+    Sat Jul  8 11:11:48 EST 2000 Hugh
+      First public release - nothing works except the firmware upload.
+      Tested on PPC and x86 architectures, seems to behave...
 */
 
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -48,53 +60,130 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 
-#ifdef CONFIG_USB_SERIAL_DEBUG
+#define DEBUG
+/*  #ifdef CONFIG_USB_SERIAL_DEBUG */
 	#define DEBUG
-#else
-	#undef DEBUG
-#endif
+/*  #endif */
 #include <linux/usb.h>
 
 #include "usb-serial.h"
 #include "keyspan.h"
 
+#define INSTAT_BUFLEN	32
+#define GLOCONT_BUFLEN	64
+
 	/* Per device and per port private data */
 struct keyspan_serial_private {
-	struct urb	*in_urbs[8];
-	struct urb	*out_urbs[8];
-	char		out_buffer[64];
-	char		in_buffer[64];
+	/* number of active ports */
+	atomic_t	active_count;
+
+	const keyspan_device_details	*device_details;
+
+	urb_t		*instat_urb;
+	char		instat_buf[INSTAT_BUFLEN];
+
+	/* XXX this one probably will need a lock */
+	urb_t		*glocont_urb;
+	char		glocont_buf[GLOCONT_BUFLEN];
 };
 
 struct keyspan_port_private {
- 		/* Keep track of which output endpoint to use */
+	/* Keep track of which input & output endpoints to use */
+	int		in_flip;
 	int		out_flip;
 
-		/* Settings for the port */
+	/* Keep duplicate of device details in each port
+	   structure as well - simplifies some of the
+	   callback functions etc. */
+	const keyspan_device_details	*device_details;
+
+	/* Input endpoints and buffer for this port */
+	urb_t		*in_urbs[2];
+	char		in_buffer[2][64];
+	/* Output endpoints and buffer for this port */
+	urb_t		*out_urbs[2];
+	char		out_buffer[2][64];
+
+	/* Input ack endpoint */
+	urb_t		*inack_urb;
+	char		inack_buffer[1];
+
+	/* Output control endpoint */
+	urb_t		*outcont_urb;
+	char		outcont_buffer[64];
+
+	/* Settings for the port */
 	int		baud;
 	int		old_baud;
-	enum		{parity_none, parity_odd, parity_even} parity;
+	unsigned int	cflag;
 	enum		{flow_none, flow_cts, flow_xon} flow_control;
-	int		rts_state;
+	int		rts_state;	/* Handshaking pins (outputs) */
 	int		dtr_state;
+	int		cts_state;	/* Handshaking pins (inputs) */
+	int		dsr_state;
+	int		dcd_state;
+	int		ri_state;
 
+	unsigned long	tx_start_time[2];
+	int		resend_cont;	/* need to resend control packet */
 };
 
-
-	/* FIXME this will break if multiple physical interfaces used */
-static wait_queue_head_t	out_wait;
 	
-	/* Include Keyspan message headers (not both yet, need some tweaks
-	   to get clean build) */
-/*#include "keyspan_usa26msg.h"*/
+/* Include Keyspan message headers.  All current Keyspan Adapters
+   make use of one of three message formats which are referred
+   to as USA-26, USA-28 and USA-49 by Keyspan and within this driver. */
+#include "keyspan_usa26msg.h"
 #include "keyspan_usa28msg.h"
+#include "keyspan_usa49msg.h"
 	
-	/* If you don't get debugging output, uncomment the following
-	   two lines to enable cheat. */
-#undef 	dbg
-#define	dbg	printk
+/* If you don't get debugging output, uncomment the following
+   two lines to enable cheat. */
+#if 0
+  #undef 	dbg 
+  #define	dbg	printk 
+#endif
+
+static void keyspan_send_setup(struct usb_serial_port *port);
+
+/* Functions used by new usb-serial code. */
+int keyspan_init (void)
+{
+	usb_serial_register (&keyspan_usa18x_pre_device);
+	usb_serial_register (&keyspan_usa19_pre_device);
+	usb_serial_register (&keyspan_usa19w_pre_device);
+	usb_serial_register (&keyspan_usa28_pre_device);
+	usb_serial_register (&keyspan_usa28x_pre_device);
+	usb_serial_register (&keyspan_usa49w_pre_device);
+
+	usb_serial_register (&keyspan_usa18x_device);
+	usb_serial_register (&keyspan_usa19_device);
+	usb_serial_register (&keyspan_usa19w_device);
+	usb_serial_register (&keyspan_usa28_device);
+	usb_serial_register (&keyspan_usa28x_device);
+	usb_serial_register (&keyspan_usa49w_device);
+	return 0;
+}
+
+void keyspan_exit (void)
+{
+	usb_serial_deregister (&keyspan_usa18x_pre_device);
+	usb_serial_deregister (&keyspan_usa19_pre_device);
+	usb_serial_deregister (&keyspan_usa19w_pre_device);
+	usb_serial_deregister (&keyspan_usa28_pre_device);
+	usb_serial_deregister (&keyspan_usa28x_pre_device);
+	usb_serial_deregister (&keyspan_usa49w_pre_device);
+
+	usb_serial_deregister (&keyspan_usa18x_device);
+	usb_serial_deregister (&keyspan_usa19_device);
+	usb_serial_deregister (&keyspan_usa19w_device);
+	usb_serial_deregister (&keyspan_usa28_device);
+	usb_serial_deregister (&keyspan_usa28x_device);
+	usb_serial_deregister (&keyspan_usa49w_device);
+}
+
+module_init(keyspan_init);
+module_exit(keyspan_exit);
 
-	/* Functions - mostly stubs for now */
 static void keyspan_rx_throttle (struct usb_serial_port *port)
 {
 	dbg("keyspan_rx_throttle port %d", port->number);
@@ -116,180 +205,597 @@
 static void keyspan_set_termios (struct usb_serial_port *port, 
 				     struct termios *old_termios)
 {
-	dbg("keyspan_set_termios");
+	int				baud_rate;
+	struct keyspan_port_private 	*p_priv;
+	const keyspan_device_details	*d_details;
+	unsigned int 			cflag;
+
+	/*  dbg(__FUNCTION__ "."); */
+
+	p_priv = (struct keyspan_port_private *)(port->private);
+	d_details = p_priv->device_details;
+	cflag = port->tty->termios->c_cflag;
+
+	/* Baud rate calculation takes baud rate as an integer
+	   so other rates can be generated if desired. */
+	baud_rate = tty_get_baud_rate(port->tty);
+	/* If no match or invalid, don't change */		
+	if (baud_rate >= 0
+	    && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
+				NULL, NULL, NULL) == KEYSPAN_BAUD_RATE_OK) {
+		/* FIXME - more to do here to ensure rate changes cleanly */
+		p_priv->baud = baud_rate;
+	}
+
+	/* set CTS/RTS handshake etc. */
+	p_priv->cflag = cflag;
+	p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
+
+	keyspan_send_setup(port);
 }
 
 static int keyspan_ioctl(struct usb_serial_port *port, struct file *file,
 			     unsigned int cmd, unsigned long arg)
 {
-	unsigned int		value;
+	unsigned int			value, set;
+	struct keyspan_port_private 	*p_priv;
 
-	dbg("keyspan_ioctl_info");
+	p_priv = (struct keyspan_port_private *)(port->private);
 	
 	switch (cmd) {
 	case TIOCMGET:
-		value = TIOCM_DTR | TIOCM_RNG;
-		if (copy_to_user((unsigned int *)arg, &value, sizeof(int))) {
+		value = ((p_priv->rts_state) ? TIOCM_RTS : 0) |
+			((p_priv->dtr_state) ? TIOCM_DTR : 0) |
+			((p_priv->cts_state) ? TIOCM_CTS : 0) |
+			((p_priv->dsr_state) ? TIOCM_DSR : 0) |
+			((p_priv->dcd_state) ? TIOCM_CAR : 0) |
+			((p_priv->ri_state) ? TIOCM_RNG : 0); 
+
+		if (put_user(value, (unsigned int *) arg))
 			return -EFAULT;
-		}
-		else {
-			return 0;
-		}
-		
-	default:
-		return -ENOIOCTLCMD;
+		return 0;
+	
+	case TIOCMSET:
+		if (get_user(value, (unsigned int *) arg))
+			return -EFAULT;
+		p_priv->rts_state = ((value & TIOCM_RTS) ? 1 : 0);
+		p_priv->dtr_state = ((value & TIOCM_DTR) ? 1 : 0);
+		keyspan_send_setup(port);
+		return 0;
+
+	case TIOCMBIS:
+	case TIOCMBIC:
+		if (get_user(value, (unsigned int *) arg))
+			return -EFAULT;
+		set = (cmd == TIOCMBIS);
+		if (value & TIOCM_RTS)
+			p_priv->rts_state = set;
+		if (value & TIOCM_DTR)
+			p_priv->dtr_state = set;
+		keyspan_send_setup(port);
+		return 0;
 	}
 
 	return -ENOIOCTLCMD;
 }
 
+	/* Write function is generic for the three protocols used
+	   with only a minor change for usa49 required */
 static int keyspan_write(struct usb_serial_port *port, int from_user, 
-			     const unsigned char *buf, int count)
+			 const unsigned char *buf, int count)
 {
-	struct usb_serial 		*serial = port->serial;
-	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private 	*p_priv;
-	int				current_urb;
-	int				i;
+	const keyspan_device_details	*d_details;
+	int				flip;
+	int left, todo;
+	urb_t *this_urb;
+	int err;
 
-	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
-	
-	if (p_priv->out_flip == 0) {
-		current_urb = 0;
-		p_priv->out_flip = 1;
+	d_details = p_priv->device_details;
+
+#if 0
+	dbg(__FUNCTION__ " for port %d (%d chars [%x]), flip=%d",
+	    port->number, count, buf[0], p_priv->out_flip);
+#endif
+
+	for (left = count; left > 0; left -= todo) {
+		todo = left;
+		if (todo > 63)
+			todo = 63;
+
+		flip = p_priv->out_flip;
+	
+		/* Check we have a valid urb/endpoint before we use it... */
+		if ((this_urb = p_priv->out_urbs[flip]) == 0) {
+			/* no bulk out, so return 0 bytes written */
+			dbg(__FUNCTION__ " no output urb :(");
+			return count;
+		}
+
+		if (this_urb->status == -EINPROGRESS) {
+			if (this_urb->transfer_flags & USB_ASYNC_UNLINK)
+				break;
+			if (jiffies - p_priv->tx_start_time[flip] < 10 * HZ)
+				break;
+			this_urb->transfer_flags |= USB_ASYNC_UNLINK;
+			usb_unlink_urb(this_urb);
+			break;
+		}
+
+		/* First byte in buffer is "last flag" - unused so
+		   for now so set to zero */
+		((char *)this_urb->transfer_buffer)[0] = 0;
+
+		if (from_user) {
+			copy_from_user(this_urb->transfer_buffer + 1, buf, todo);
+		} else {
+			memcpy (this_urb->transfer_buffer + 1, buf, todo);
+		}
+		buf += todo;
+
+		/* send the data out the bulk port */
+		this_urb->transfer_buffer_length = todo + 1;
+
+		this_urb->transfer_flags &= ~USB_ASYNC_UNLINK;
+		this_urb->dev = port->serial->dev;
+		if ((err = usb_submit_urb(this_urb)) != 0) {
+			dbg("usb_submit_urb(write bulk) failed (%d)", err);
+		}
+		p_priv->tx_start_time[flip] = jiffies;
+
+		/* Flip for next time if usa26 or usa28 interface
+		   (not used on usa49) */
+		p_priv->out_flip = (flip + 1) & d_details->outdat_endp_flip;
 	}
-	else {
-		current_urb = 1;
-		p_priv->out_flip = 0;
+
+	return count - left;
+}
+
+static void	usa26_indat_callback(struct urb *urb)
+{
+	int			i, err;
+	int			endpoint;
+	struct usb_serial_port	*port;
+	struct tty_struct	*tty;
+	unsigned char 		*data = urb->transfer_buffer;
+
+	/*  dbg (__FUNCTION__); */
+
+	endpoint = usb_pipeendpoint(urb->pipe);
+
+	if (urb->status) {
+		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.",
+			      		urb->status, endpoint);
+		return;
 	}
 
-	dbg("keyspan_write called for port %d (%d) chars {", port->number, count);
-	for (i = 0; i < count ; i++) {
-		dbg("%02x ", buf[i]);
+	port = (struct usb_serial_port *) urb->context;
+	tty = port->tty;
+	if (urb->actual_length) {
+		if (data[0] == 0) {
+			/* no error on any byte */
+			for (i = 1; i < urb->actual_length ; ++i) {
+				tty_insert_flip_char(tty, data[i], 0);
+			}
+		} else {
+			/* some bytes had errors, every byte has status */
+			for (i = 0; i + 1 < urb->actual_length; i += 2) {
+				int stat = data[i], flag = 0;
+				if (stat & RXERROR_OVERRUN)
+					flag |= TTY_OVERRUN;
+				if (stat & RXERROR_FRAMING)
+					flag |= TTY_FRAME;
+				if (stat & RXERROR_PARITY)
+					flag |= TTY_PARITY;
+				/* XXX should handle break (0x10) */
+				tty_insert_flip_char(tty, data[i+1], flag);
+			}
+		}
+		tty_flip_buffer_push(tty);
+	}
+				
+		/* Resubmit urb so we continue receiving */
+	urb->dev = port->serial->dev;
+	if ((err = usb_submit_urb(urb)) != 0) {
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
 	}
-	dbg("}\n");
+	return;
+}
+
+	/* Outdat handling is common for usa26, usa28 and usa49 messages */
+static void	usa2x_outdat_callback(struct urb *urb)
+{
+	struct usb_serial_port *port;
+	struct keyspan_port_private *p_priv;
+
+	port = (struct usb_serial_port *) urb->context;
+	p_priv = (struct keyspan_port_private *)(port->private);
+	/*  dbg (__FUNCTION__ " urb %d", urb == p_priv->out_urbs[1]); */
 
-	if (count == 0) {
-		dbg("write request of 0 bytes");
-		return (0);
+	if (port->active) {
+		queue_task(&port->tqueue, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
 	}
+}
+
+static void	usa26_inack_callback(struct urb *urb)
+{
+	dbg (__FUNCTION__);
+	
+}
+
+static void	usa26_outcont_callback(struct urb *urb)
+{
+	struct usb_serial_port *port;
+	struct keyspan_port_private *p_priv;
+
+	port = (struct usb_serial_port *) urb->context;
+	p_priv = (struct keyspan_port_private *)(port->private);
+
+	if (p_priv->resend_cont) {
+		/*  dbg (__FUNCTION__ " sending setup"); */
+		keyspan_usa26_send_setup(port->serial, port);
+	}
+}
+
+static void	usa26_instat_callback(struct urb *urb)
+{
+	unsigned char 				*data = urb->transfer_buffer;
+	keyspan_usa26_portStatusMessage		*msg;
+	struct usb_serial			*serial;
+	struct usb_serial_port			*port;
+	struct keyspan_port_private	 	*p_priv;
+	int old_dcd_state, err;
+
+	serial = (struct usb_serial *) urb->context;
 
-		/* only send data if we have a bulk out endpoint */
-	if (s_priv->out_urbs[current_urb]) {
-		while (s_priv->out_urbs[current_urb]->status == -EINPROGRESS) {
-			dbg (__FUNCTION__ " INPROGRES\n");
-			interruptible_sleep_on(&out_wait);
-			if (signal_pending(current)) {
-				dbg (__FUNCTION__ " signal\n");
-				return (-ERESTARTSYS);
+	if (urb->status) {
+		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		return;
+	}
+	if (urb->actual_length != 9) {
+		dbg(__FUNCTION__ " %d byte report??", urb->actual_length);
+		goto exit;
+	}
+
+	msg = (keyspan_usa26_portStatusMessage *)data;
+
+#if 0
+	dbg(__FUNCTION__ " port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d",
+	    msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff,
+	    msg->_txXoff, msg->rxEnabled, msg->controlResponse);
+#endif
+
+	/* Now do something useful with the data */
+
+
+	/* Check port number from message and retrieve private data */	
+	if (msg->port >= serial->num_ports) {
+		dbg ("Unexpected port number %d", msg->port);
+		goto exit;
+	}
+	port = &serial->port[msg->port];
+	p_priv = (struct keyspan_port_private *)(port->private);
+	
+	/* Update handshaking pin state information */
+	old_dcd_state = p_priv->dcd_state;
+	p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
+	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
+	p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
+	p_priv->ri_state = ((msg->ri) ? 1 : 0);
+
+	if (port->tty && !C_CLOCAL(port->tty)
+	    && old_dcd_state != p_priv->dcd_state) {
+		if (old_dcd_state)
+			tty_hangup(port->tty);
+		/*  else */
+		/*	wake_up_interruptible(&p_priv->open_wait); */
+	}
+	
+exit:
+	/* Resubmit urb so we continue receiving */
+	urb->dev = serial->dev;
+	if ((err = usb_submit_urb(urb)) != 0) {
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+	}
+}
+
+static void	usa26_glocont_callback(struct urb *urb)
+{
+	dbg (__FUNCTION__);
+	
+}
+
+
+static void     usa28_indat_callback(struct urb *urb)
+{
+	int                     i, err;
+	struct usb_serial_port  *port;
+	struct tty_struct       *tty;
+	unsigned char           *data;
+	struct keyspan_port_private             *p_priv;
+
+	/*  dbg (__FUNCTION__); */
+
+	port = (struct usb_serial_port *) urb->context;
+	p_priv = (struct keyspan_port_private *)(port->private);
+	data = urb->transfer_buffer;
+
+	if (urb != p_priv->in_urbs[p_priv->in_flip])
+		return;
+
+	do {
+		if (urb->status) {
+			dbg(__FUNCTION__ "nonzero status: %x on endpoint
+%d.",
+			    urb->status, usb_pipeendpoint(urb->pipe));
+			return;
+		}
+
+		port = (struct usb_serial_port *) urb->context;
+		p_priv = (struct keyspan_port_private *)(port->private);
+		data = urb->transfer_buffer;
+
+		tty = port->tty;
+		if (urb->actual_length) {
+			for (i = 0; i < urb->actual_length ; ++i) {
+				tty_insert_flip_char(tty, data[i], 0);
 			}
+			tty_flip_buffer_push(tty);
 		}
-		/*if (s_priv->out_urbs[current_urb]->status == -EINPROGRESS) {
-			dbg ("already writing");
-			return (-EAGAIN);
-		}*/
-			/* First byte in buffer is "last flag" - unused so
-			   for now so set to zero */
-		memset(s_priv->out_urbs[current_urb]->transfer_buffer, 0, 1);
 
-		if (from_user) {
-			copy_from_user(s_priv->out_urbs[current_urb]->transfer_buffer + 1, buf, count);
+		/* Resubmit urb so we continue receiving */
+		urb->dev = port->serial->dev;
+		if ((err = usb_submit_urb(urb)) != 0) {
+			dbg(__FUNCTION__ "resubmit read urb failed. (%d)",
+err);
 		}
-		else {
-			memcpy (s_priv->out_urbs[current_urb]->transfer_buffer + 1, buf, count);
-		}  
+		p_priv->in_flip ^= 1;
 
-		/* send the data out the bulk port */
-		s_priv->out_urbs[current_urb]->transfer_buffer_length = count + 1;
+		urb = p_priv->in_urbs[p_priv->in_flip];
+	} while (urb->status != -EINPROGRESS);
+}
 
-		if (usb_submit_urb(s_priv->out_urbs[current_urb])) {
-			dbg("usb_submit_urb(write bulk) failed");
-		}
+static void	usa28_inack_callback(struct urb *urb)
+{
+	dbg (__FUNCTION__);
+}
+
+static void	usa28_outcont_callback(struct urb *urb)
+{
+	struct usb_serial_port *port;
+	struct keyspan_port_private *p_priv;
+
+	port = (struct usb_serial_port *) urb->context;
+	p_priv = (struct keyspan_port_private *)(port->private);
 
-		return (count);
+	if (p_priv->resend_cont) {
+		dbg (__FUNCTION__ " sending setup");
+		keyspan_usa28_send_setup(port->serial, port);
 	}
+}
+
+static void	usa28_instat_callback(struct urb *urb)
+{
+	int					err;
+	unsigned char 				*data = urb->transfer_buffer;
+	keyspan_usa28_portStatusMessage		*msg;
+	struct usb_serial			*serial;
+	struct usb_serial_port			*port;
+	struct keyspan_port_private	 	*p_priv;
+	int old_dcd_state;
+
+	serial = (struct usb_serial *) urb->context;
+
+	if (urb->status) {
+		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		return;
+	}
+
+	if (urb->actual_length != sizeof(struct keyspan_usa28_portStatusMessage)) {
+		dbg(__FUNCTION__ " bad length %d", urb->actual_length);
+		goto exit;
+	}
+
+	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x %x",
+	    data[0], data[1], data[2], data[3], data[4], data[5],
+	    data[6], data[7], data[8], data[9], data[10], data[11]);*/
 	
-	/* no bulk out, so return 0 bytes written */
-	return (0);
+		/* Now do something useful with the data */
+	msg = (keyspan_usa28_portStatusMessage *)data;
+
+
+		/* Check port number from message and retrieve private data */	
+	if (msg->port >= serial->num_ports) {
+		dbg ("Unexpected port number %d", msg->port);
+		goto exit;
+	}
+	port = &serial->port[msg->port];
+	p_priv = (struct keyspan_port_private *)(port->private);
+	
+	/* Update handshaking pin state information */
+	old_dcd_state = p_priv->dcd_state;
+	p_priv->cts_state = ((msg->cts) ? 1 : 0);
+	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
+	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
+	p_priv->ri_state = ((msg->ri) ? 1 : 0);
+
+	if (port->tty && !C_CLOCAL(port->tty)
+	    && old_dcd_state != p_priv->dcd_state) {
+		if (old_dcd_state)
+			tty_hangup(port->tty);
+		/*  else */
+		/*	wake_up_interruptible(&p_priv->open_wait); */
+	}
+
+exit:	
+		/* Resubmit urb so we continue receiving */
+	urb->dev = serial->dev;
+	if ((err = usb_submit_urb(urb)) != 0) {
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+	}
+}
+
+static void	usa28_glocont_callback(struct urb *urb)
+{
+	dbg (__FUNCTION__);
 }
 
 
-static void keyspan_write_bulk_callback (struct urb *urb)
+static void	usa49_glocont_callback(struct urb *urb)
 {
-	int		endpoint;
-	
-	endpoint = usb_pipeendpoint(urb->pipe);
+	struct usb_serial *serial;
+	struct usb_serial_port *port;
+	struct keyspan_port_private *p_priv;
+	int i;
 
-	dbg("keyspan_write_bulk_callback for endpoint %d\n", endpoint);
+	/*  dbg (__FUNCTION__); */
+
+	serial = (struct usb_serial *) urb->context;
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = &serial->port[i];
+		p_priv = (struct keyspan_port_private *)(port->private);
 
-		/* Only do wakeup if this callback is from one of the data
-		   endpoints.  */
-	if (endpoint == 2 || endpoint == 3) {
-		wake_up_interruptible(&out_wait);
+		if (p_priv->resend_cont) {
+			/*  dbg (__FUNCTION__ " sending setup"); */
+			keyspan_usa49_send_setup(serial, port);
+			break;
+		}
 	}
+}
+
+	/* This is actually called glostat in the Keyspan
+	   doco */
+static void	usa49_instat_callback(struct urb *urb)
+{
+	int					err;
+	unsigned char 				*data = urb->transfer_buffer;
+	keyspan_usa49_portStatusMessage		*msg;
+	struct usb_serial			*serial;
+	struct usb_serial_port			*port;
+	struct keyspan_port_private	 	*p_priv;
+	int old_dcd_state;
+
+	/*  dbg (__FUNCTION__); */
 
+	serial = (struct usb_serial *) urb->context;
+
+	if (urb->status) {
+		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		return;
+	}
+
+	if (urb->actual_length != sizeof(struct keyspan_usa49_portStatusMessage)) {
+		dbg(__FUNCTION__ " bad length %d", urb->actual_length);
+		goto exit;
+	}
+
+	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x",
+	    data[0], data[1], data[2], data[3], data[4], data[5],
+	    data[6], data[7], data[8], data[9], data[10]);*/
+	
+		/* Now do something useful with the data */
+	msg = (keyspan_usa49_portStatusMessage *)data;
+
+		/* Check port number from message and retrieve private data */	
+	if (msg->portNumber >= serial->num_ports) {
+		dbg ("Unexpected port number %d", msg->portNumber);
+		goto exit;
+	}
+	port = &serial->port[msg->portNumber];
+	p_priv = (struct keyspan_port_private *)(port->private);
+	
+	/* Update handshaking pin state information */
+	old_dcd_state = p_priv->dcd_state;
+	p_priv->cts_state = ((msg->cts) ? 1 : 0);
+	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
+	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
+	p_priv->ri_state = ((msg->ri) ? 1 : 0);
+
+	if (port->tty && !C_CLOCAL(port->tty)
+	    && old_dcd_state != p_priv->dcd_state) {
+		if (old_dcd_state)
+			tty_hangup(port->tty);
+		/*  else */
+		/*	wake_up_interruptible(&p_priv->open_wait); */
+	}
+
+exit:	
+		/* Resubmit urb so we continue receiving */
+	urb->dev = serial->dev;
+
+	if ((err = usb_submit_urb(urb)) != 0) {
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+	}
 }
 
+static void	usa49_inack_callback(struct urb *urb)
+{
+	dbg (__FUNCTION__);
+}
 
-static void keyspan_read_bulk_callback (struct urb *urb)
+static void	usa49_indat_callback(struct urb *urb)
 {
-	int			i;
+	int			i, err;
 	int			endpoint;
-	struct usb_serial	*serial;
 	struct usb_serial_port	*port;
 	struct tty_struct	*tty;
 	unsigned char 		*data = urb->transfer_buffer;
 
-	endpoint = usb_pipeendpoint(urb->pipe);
+	/*  dbg (__FUNCTION__); */
 
+	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (urb->status) {
-		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.\n",
+		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.",
 			      		urb->status, endpoint);
 		return;
 	}
 
-	switch (endpoint) {
-
-			/* If this is one of the data endpoints, stuff it's
-		   	   contents into the tty flip_buffer. */
-		case 1:
-		case 2: serial = (struct usb_serial *) urb->context;
-			port = &serial->port[0];
-			tty = port->tty;
-			if (urb->actual_length) {
-				for (i = 0; i < urb->actual_length ; ++i) {
-					 tty_insert_flip_char(tty, data[i], 0);
-				}
-				tty_flip_buffer_push(tty);
+	port = (struct usb_serial_port *) urb->context;
+	tty = port->tty;
+	if (urb->actual_length) {
+		if (data[0] == 0) {
+			/* no error on any byte */
+			for (i = 1; i < urb->actual_length ; ++i) {
+				tty_insert_flip_char(tty, data[i], 0);
 			}
-			break;
-
-			/* INACK endpoint */	
-		case 3: dbg(__FUNCTION__ " callback for INACK endpoint\n");
-			break;
-
-			/* INSTAT endpoint */
-		case 4: dbg(__FUNCTION__ " callback for INSTAT endpoint\n");
-			break;
-		
-		default:
-		       	dbg(__FUNCTION__ " callback for unknown endpoint!\n");
-			break;
+		} else {
+			/* some bytes had errors, every byte has status */
+			for (i = 0; i + 1 < urb->actual_length; i += 2) {
+				int stat = data[i], flag = 0;
+				if (stat & RXERROR_OVERRUN)
+					flag |= TTY_OVERRUN;
+				if (stat & RXERROR_FRAMING)
+					flag |= TTY_FRAME;
+				if (stat & RXERROR_PARITY)
+					flag |= TTY_PARITY;
+				/* XXX should handle break (0x10) */
+				tty_insert_flip_char(tty, data[i+1], flag);
+			}
+		}
+		tty_flip_buffer_push(tty);
 	}
 				
 		/* Resubmit urb so we continue receiving */
-	if (usb_submit_urb(urb)) {
-		dbg(__FUNCTION__ "resubmit read urb failed.\n");
+	urb->dev = port->serial->dev;
+	if ((err = usb_submit_urb(urb)) != 0) {
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
 	}
-	return;
-	
 }
 
+/* not used, usa-49 doesn't have per-port control endpoints */
+static void	usa49_outcont_callback(struct urb *urb)
+{
+	dbg (__FUNCTION__);
+}
+
+
+
 static int keyspan_write_room (struct usb_serial_port *port)
 {
-//	dbg("keyspan_write_room called\n");
+//	dbg("keyspan_write_room called");
 	return (32);
 
 }
@@ -306,62 +812,103 @@
 	struct keyspan_port_private 	*p_priv;
 	struct keyspan_serial_private 	*s_priv;
 	struct usb_serial 		*serial = port->serial;
-	int				i;
+	const keyspan_device_details	*d_details;
+	int				i, already_active, err;
+	unsigned long flags;
+	urb_t *urb;
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
+	d_details = s_priv->device_details;
 	
-	dbg("keyspan_open called.\n");
-	
-	if (port->active) {
-		dbg(__FUNCTION__ "port->active already true!\n");
-		return (-EINVAL);
-	}
+	/*  dbg("keyspan_open called."); */
+	MOD_INC_USE_COUNT;
 
-	p_priv = (struct keyspan_port_private *)(port->private);
-	
-	p_priv->out_flip = 0;
+	spin_lock_irqsave (&port->port_lock, flags);
+	++port->open_count;
+	already_active = port->active;
 	port->active = 1;
+	spin_unlock_irqrestore (&port->port_lock, flags);
 
-		/* Start reading from port */
-	for (i = 0; i < 4; i++) {
-		if (s_priv->in_urbs[i]) {
-			if (usb_submit_urb(s_priv->in_urbs[i])) {
-				dbg(__FUNCTION__ " submit in urb %d failed", i);
-			}
-		}
+	if (already_active)
+		return 0;
 
+	p_priv = (struct keyspan_port_private *)(port->private);
+
+	/* Set some sane defaults */
+	p_priv->baud = 9600;
+	p_priv->cflag = CREAD | CLOCAL;
+	p_priv->flow_control = flow_none;
+	p_priv->rts_state = 1;
+	p_priv->dtr_state = 1;
+
+	/* Start reading from endpoints */
+	for (i = 0; i < 2; i++) {
+		if ((urb = p_priv->in_urbs[i]) == NULL)
+			continue;
+		urb->dev = serial->dev;
+		if ((err = usb_submit_urb(urb)) != 0) {
+			dbg(__FUNCTION__ " submit urb %d failed (%d)", i, err);
+		}
 	}
-	
-	keyspan_usa19_send_setup(serial, port);
+/*    Now done in startup routine
+	if (atomic_inc_return(&s_priv->active_count) == 1) {
+		s_priv->instat_urb->dev = serial->dev;
+		if ((err = usb_submit_urb(s_priv->instat_urb)) != 0) {
+			dbg(__FUNCTION__ " submit instat urb failed %d", err);
+		}
+	}
+*/
+
+	keyspan_send_setup(port);
 
 	return (0);
 }
 
+static inline void stop_urb(urb_t *urb)
+{
+	if (urb && urb->status == -EINPROGRESS) {
+		urb->transfer_flags &= ~USB_ASYNC_UNLINK;
+		usb_unlink_urb(urb);
+	}
+}
 
 static void keyspan_close(struct usb_serial_port *port, struct file *filp)
 {
 	int			i;
 	struct usb_serial	*serial = port->serial; /* FIXME should so sanity check */
 	struct keyspan_serial_private 	*s_priv;
+	struct keyspan_port_private 	*p_priv;
+	unsigned long flags;
 
+	/*  dbg("keyspan_close called"); */
 	s_priv = (struct keyspan_serial_private *)(serial->private);
-	
-		/* Stop reading/writing urbs */
-	for (i = 0; i < 4; i++) {
-		if (s_priv->in_urbs[i]) {
-			usb_unlink_urb(s_priv->in_urbs[i]);
-		}
+	p_priv = (struct keyspan_port_private *)(port->private);
 
-	}
-	for (i = 0; i < 3; i++) {
-		if (s_priv->out_urbs[i]) {
-			usb_unlink_urb(s_priv->out_urbs[i]);
-		}
+	spin_lock_irqsave (&port->port_lock, flags);
 
+	if (--port->open_count <= 0) {
+		if (port->active) {
+			/* Stop reading/writing urbs */
+			stop_urb(p_priv->inack_urb);
+			stop_urb(p_priv->outcont_urb);
+			for (i = 0; i < 2; i++) {
+				stop_urb(p_priv->in_urbs[i]);
+				stop_urb(p_priv->out_urbs[i]);
+			}
+			/* Now done in shutdown 
+			if (atomic_dec_return(&s_priv->active_count) <= 0) {
+				stop_urb(s_priv->instat_urb);
+				stop_urb(s_priv->glocont_urb);
+			} */
+		}
+		port->active = 0;
+		port->open_count = 0;
+		port->tty = 0;
 	}
-	port->active = 0;
-	dbg("keyspan_close called\n");
+	spin_unlock_irqrestore (&port->port_lock, flags);
+
+	MOD_DEC_USE_COUNT;
 }
 
 
@@ -372,47 +919,59 @@
 	const struct ezusb_hex_record 	*record;
 	char				*fw_name;
 
-	dbg("Keyspan startup version %04x product %04x\n", serial->dev->descriptor.bcdDevice,
-		       					serial->dev->descriptor.idProduct); 
+	dbg("Keyspan startup version %04x product %04x",
+	    serial->dev->descriptor.bcdDevice,
+	    serial->dev->descriptor.idProduct); 
 	
 	if ((serial->dev->descriptor.bcdDevice & 0x8000) != 0x8000) {
-		dbg("Firmware already loaded.  Quitting.\n");
+		dbg("Firmware already loaded.  Quitting.");
 		return(1);
 	}
 
 		/* Select firmware image on the basis of idProduct */
 	switch (serial->dev->descriptor.idProduct) {
-		case 0x0101: record = &keyspan_usa28_firmware[0];
-			     fw_name = "USA28";
-			     break;
-			     
-		case 0x0102: record = &keyspan_usa28x_firmware[0];
-			     fw_name = "USA28X";
-			     break;
-
-		case 0x0103: record = &keyspan_usa19_firmware[0];
-			     fw_name = "USA19";
-			     break;
+	case 0x0101:
+		record = &keyspan_usa28_firmware[0];
+		fw_name = "USA28";
+		break;
+
+	case 0x0102:
+		record = &keyspan_usa28x_firmware[0];
+		fw_name = "USA28X";
+		break;
+
+	case 0x0103:
+		record = &keyspan_usa19_firmware[0];
+		fw_name = "USA19";
+		break;
 			     
-		case 0x0105: record = &keyspan_usa18x_firmware[0];
-			     fw_name = "USA18X";
-			     break;
+	case 0x0105:
+		record = &keyspan_usa18x_firmware[0];
+		fw_name = "USA18X";
+		break;
 			     
-		case 0x0106: record = &keyspan_usa19w_firmware[0];
-			     fw_name = "USA19W";
-			     break;
+	case 0x0106:
+		record = &keyspan_usa19w_firmware[0];
+		fw_name = "USA19W";
+		break;
 		
-		default:     record = NULL;
-			     fw_name = "Unknown";
-			     break;
+	case 0x0109:
+		record = &keyspan_usa49w_firmware[0];
+		fw_name = "USA49W";
+		break;
+
+	default:
+		record = NULL;
+		fw_name = "Unknown";
+		break;
 	}
 
 	if (record == NULL) {
-		err("Required keyspan firmware image (%s) unavailable.\n", fw_name);
+		err("Required keyspan firmware image (%s) unavailable.", fw_name);
 		return(1);
 	}
 
-	dbg("Uploading Keyspan %s firmware.\n", fw_name);
+	dbg("Uploading Keyspan %s firmware.", fw_name);
 
 		/* download the firmware image */
 	response = ezusb_set_reset(serial, 1);
@@ -434,72 +993,165 @@
 		   moment and the new device will bind to the real driver */
 	response = ezusb_set_reset(serial, 0);
 
-		/* we don't want this device to have a driver assigned to it. */
+	/* we don't want this device to have a driver assigned to it. */
 	return (1);
 }
 
-	/* USA-19 uses three output endpoints and four input
-	   endpoints.  First two output endpoints are for
-	   data (used in an alternating fashion), the third is
-	   output control.  First two input endpoints are for
-	   data (again alternating), the third is the ACK
-	   endpoint, the fourth is input status. */
-static void keyspan_usa19_setup_urbs(struct usb_serial *serial)
+/* Helper functions used by keyspan_setup_urbs */
+static urb_t *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
+				int dir, void *ctx, char *buf, int len,
+				void (*callback)(urb_t *))
+{
+	urb_t *urb;
+
+	if (endpoint == -1)
+		return NULL;		/* endpoint not needed */
+
+	/*  dbg (__FUNCTION__ " alloc for endpoint %d.", endpoint); */
+	urb = usb_alloc_urb(0);		/* No ISO */
+	if (urb == NULL) {
+		dbg (__FUNCTION__ " alloc for endpoint %d failed.", endpoint);
+		return NULL;
+	}
+
+		/* Fill URB using supplied data. */
+	FILL_BULK_URB(urb, serial->dev,
+		      usb_sndbulkpipe(serial->dev, endpoint) | dir,
+		      buf, len, callback, ctx);
+
+	return urb;
+}
+
+struct callbacks {
+	void	(*instat_callback)(urb_t *);
+	void	(*glocont_callback)(urb_t *);
+	void	(*indat_callback)(urb_t *);
+	void	(*outdat_callback)(urb_t *);
+	void	(*inack_callback)(urb_t *);
+	void	(*outcont_callback)(urb_t *);
+} keyspan_callbacks[] = {
+	{
+		/* msg_usa26 callbacks */
+		instat_callback: usa26_instat_callback,
+		glocont_callback: usa26_glocont_callback,
+		indat_callback: usa26_indat_callback,
+		outdat_callback: usa2x_outdat_callback,
+		inack_callback: usa26_inack_callback,
+		outcont_callback: usa26_outcont_callback,
+	}, {
+		/* msg_usa28 callbacks */
+		instat_callback: usa28_instat_callback,
+		glocont_callback: usa28_glocont_callback,
+		indat_callback: usa28_indat_callback,
+		outdat_callback: usa2x_outdat_callback,
+		inack_callback: usa28_inack_callback,
+		outcont_callback: usa28_outcont_callback,
+	}, {
+		/* msg_usa49 callbacks */
+		instat_callback: usa49_instat_callback,
+		glocont_callback: usa49_glocont_callback,
+		indat_callback: usa49_indat_callback,
+		outdat_callback: usa2x_outdat_callback,
+		inack_callback: usa49_inack_callback,
+		outcont_callback: usa49_outcont_callback,
+	}
+};
+
+	/* Generic setup urbs function that uses
+	   data in device_details */
+static void keyspan_setup_urbs(struct usb_serial *serial)
 {
+	int				i, j;
 	struct keyspan_serial_private 	*s_priv;
-	int			i;
+	const keyspan_device_details	*d_details;
+	struct usb_serial_port		*port;
+	struct keyspan_port_private	*p_priv;
+	struct callbacks		*cback;
+	int				endp;
+
+	/*  dbg (__FUNCTION__); */
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
+	d_details = s_priv->device_details;
 
-		/* Output urbs first */
-	dbg(__FUNCTION__ "Allocating output urbs.\n");
-	for (i = 0; i < 3; i++) {
-
-		s_priv->out_urbs[i] = usb_alloc_urb (0);	/* No ISO */
-		if (!s_priv->out_urbs[i]) {
-			dbg (__FUNCTION__ "Alloc for %d out urb failed.\n", i);
-			return;
-		}
+		/* Setup values for the various callback routines */
+	cback = &keyspan_callbacks[d_details->msg_format];
 
-		FILL_BULK_URB(s_priv->out_urbs[i], serial->dev, 
-			      usb_sndbulkpipe(serial->dev, i + 1),
-			      &s_priv->out_buffer[i], sizeof(s_priv->out_buffer[i]),
-			      keyspan_write_bulk_callback, 
-			      serial);
-	}
+		/* Allocate and set up urbs for each one that is in use, 
+		   starting with instat endpoints */
+	s_priv->instat_urb = keyspan_setup_urb
+		(serial, d_details->instat_endpoint, USB_DIR_IN,
+		 serial, s_priv->instat_buf, INSTAT_BUFLEN,
+		 cback->instat_callback);
+
+	s_priv->glocont_urb = keyspan_setup_urb
+		(serial, d_details->glocont_endpoint, USB_DIR_OUT,
+		 serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
+		 cback->glocont_callback);
 
-		/* Now input urbs */
-	dbg(__FUNCTION__ "Allocating input urbs.\n");
-	for (i = 0; i < 4; i++) {
-
-		s_priv->in_urbs[i] = usb_alloc_urb (0);	/* No ISO */
-		if (!s_priv->in_urbs[i]) {
-			dbg (__FUNCTION__ "Alloc for %d in urb failed.\n", i);
-			return;
+		/* Setup endpoints for each port specific thing */
+	for (i = 0; i < d_details->num_ports; i ++) {
+		port = &serial->port[i];
+		p_priv = (struct keyspan_port_private *)(port->private);
+
+		/* Do indat endpoints first, once for each flip */
+		endp = d_details->indat_endpoints[i];
+		for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) {
+			p_priv->in_urbs[j] = keyspan_setup_urb
+				(serial, endp, USB_DIR_IN, port,
+				 p_priv->in_buffer[j], 64,
+				 cback->indat_callback);
 		}
+		for (; j < 2; ++j)
+			p_priv->in_urbs[j] = NULL;
+
+		/* outdat endpoints also have flip */
+		endp = d_details->outdat_endpoints[i];
+		for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) {
+			p_priv->out_urbs[j] = keyspan_setup_urb
+				(serial, endp, USB_DIR_OUT, port,
+				 p_priv->out_buffer[j], 64,
+				 cback->outdat_callback);
+		}
+		for (; j < 2; ++j)
+			p_priv->out_urbs[j] = NULL;
+
+		/* inack endpoint */
+		p_priv->inack_urb = keyspan_setup_urb
+			(serial, d_details->inack_endpoints[i], USB_DIR_IN,
+			 port, p_priv->inack_buffer, 1, cback->inack_callback);
+
+		/* outcont endpoint */
+		p_priv->outcont_urb = keyspan_setup_urb
+			(serial, d_details->outcont_endpoints[i], USB_DIR_OUT,
+			 port, p_priv->outcont_buffer, 64,
+			 cback->outcont_callback);
+	}	
 
-		FILL_BULK_URB(s_priv->in_urbs[i], serial->dev, 
-			      usb_rcvbulkpipe(serial->dev, i + 0x81),
-			      &s_priv->in_buffer[i], sizeof(s_priv->in_buffer[i]),
-			      keyspan_read_bulk_callback, 
-			      serial);
-	}
-	
 }
 
-static int keyspan_usa19_calc_baud(u32 baud_rate, u8 *rate_hi, u8 *rate_low)
+/* usa19 function doesn't require prescaler */
+static int keyspan_usa19_calc_baud(u32 baud_rate, u32 baudclk,
+				   u8 *rate_hi, u8 *rate_low, u8 *prescaler)
 {
-	u32 b16,	/* baud rate times 16 (actual rate used internally) */
+	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
 		div,	/* divisor */	
 		cnt;	/* inverse of divisor (programmed into 8051) */
+		
 
 		/* prevent divide by zero...  */
 	if( (b16 = (baud_rate * 16L)) == 0) {
 		return (KEYSPAN_INVALID_BAUD_RATE);
 	}
 
+		/* Any "standard" rate over 57k6 is marginal on the USA-19
+		   as we run out of divisor resolution. */
+	if (baud_rate > 57600) {
+		return (KEYSPAN_INVALID_BAUD_RATE);
+	}
+
 		/* calculate the divisor and the counter (its inverse) */
-	if( (div = (USA19_BAUDCLK / b16)) == 0) {
+	if( (div = (baudclk / b16)) == 0) {
 		return (KEYSPAN_INVALID_BAUD_RATE);
 	}
 	else {
@@ -510,216 +1162,520 @@
 		return (KEYSPAN_INVALID_BAUD_RATE);
 	}
 
-		/* return the counter values */
-	*rate_low = (u8) (cnt & 0xff);
-	*rate_hi = (u8) ((cnt >> 8) & 0xff);
+		/* return the counter values if non-null */
+	if (rate_low) {
+		*rate_low = (u8) (cnt & 0xff);
+	}
+	if (rate_hi) {
+		*rate_hi = (u8) ((cnt >> 8) & 0xff);
+	}
+	if (rate_low && rate_hi) {
+		dbg (__FUNCTION__ " %d %02x %02x.", baud_rate, *rate_hi, *rate_low);
+	}
 	
-	dbg(__FUNCTION__ " Baud rate of %d is %02x %02x.\n", baud_rate, *rate_hi, *rate_low);
+	return (KEYSPAN_BAUD_RATE_OK);
+}
+
+static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk,
+				    u8 *rate_hi, u8 *rate_low, u8 *prescaler)
+{
+	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
+		clk,	/* clock with 13/8 prescaler */
+		div,	/* divisor using 13/8 prescaler */	
+		res,	/* resulting baud rate using 13/8 prescaler */
+		diff,	/* error using 13/8 prescaler */
+		smallest_diff;
+	u8	best_prescaler;
+	int	i;
+
+	/*  dbg (__FUNCTION__ " %d.", baud_rate); */
+
+		/* prevent divide by zero */
+	if( (b16 = baud_rate * 16L) == 0) {
+		return (KEYSPAN_INVALID_BAUD_RATE);
+	}
 
+		/* Calculate prescaler by trying them all and looking
+		   for best fit */
+		
+		/* start with largest possible difference */
+	smallest_diff = 0xffffffff;
+
+		/* 0 is an invalid prescaler, used as a flag */
+	best_prescaler = 0;
+
+	for(i = 8; i <= 0xff; ++i)
+	{
+		clk = (baudclk * 8) / (u32) i;
+		
+		if( (div = clk / b16) == 0) {
+			continue;
+		}
+
+		res = clk / div;
+		diff= (res > b16) ? (res-b16) : (b16-res);
+
+		if(diff < smallest_diff)
+		{
+			best_prescaler = i;
+			smallest_diff = diff;
+		}
+	}
+
+	if(best_prescaler == 0) {
+		return (KEYSPAN_INVALID_BAUD_RATE);
+	}
+
+	clk = (baudclk * 8) / (u32) best_prescaler;
+	div = clk / b16;
+
+		/* return the divisor and prescaler if non-null */
+	if (rate_low) {
+		*rate_low = (u8) (div & 0xff);
+	}
+	if (rate_hi) {
+		*rate_hi = (u8) ((div >> 8) & 0xff);
+	}
+	if (prescaler) {
+		*prescaler = best_prescaler;
+		/*  dbg(__FUNCTION__ " %d %d", *prescaler, div); */
+	}
 	return (KEYSPAN_BAUD_RATE_OK);
 }
 
-static int keyspan_usa19_send_setup(struct usb_serial *serial, struct usb_serial_port *port)
+static int keyspan_usa26_send_setup(struct usb_serial *serial,
+				    struct usb_serial_port *port)
 {
-	struct portControlMessage	msg;		
-	struct keyspan_serial_private 	*s_priv;
-	struct keyspan_port_private 	*p_priv;
+	struct keyspan_usa26_portControlMessage	msg;		
+	struct keyspan_serial_private 		*s_priv;
+	struct keyspan_port_private 		*p_priv;
+	const  keyspan_device_details		*d_details;
+	int 					outcont_urb;
+	urb_t *this_urb;
+	int err;
+
+	/*  dbg (__FUNCTION__); */
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
+	d_details = s_priv->device_details;
+
+	outcont_urb = d_details->outcont_endpoints[port->number];
+	this_urb = p_priv->outcont_urb;
+
+		/* Make sure we have an urb then send the message */
+	if (this_urb == NULL) {
+		dbg(__FUNCTION__ " oops no urb.");
+		return -1;
+	}
+
+	p_priv->resend_cont = 1;
+	if (this_urb->status == -EINPROGRESS) {
+		/*  dbg (__FUNCTION__ " already writing"); */
+		return(-1);
+	}
+
+	memset(&msg, 0, sizeof (struct keyspan_usa26_portControlMessage));
+	
+		/* Only set baud rate if it's changed */	
+	if (p_priv->old_baud != p_priv->baud) {
+		p_priv->old_baud = p_priv->baud;
+		msg.setClocking = 0xff;
+		if (d_details->calculate_baud_rate
+		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
+		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {
+			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",
+			    p_priv->baud);
+			msg.baudLo = 0;
+			msg.baudHi = 125;	/* Values for 9600 baud */
+			msg.prescaler = 10;
+		}
+		msg.setPrescaler = 0xff;
+	}
+
+	msg.lcr = USA_DATABITS_8 | STOPBITS_5678_1;
+	if (p_priv->cflag & PARENB) {
+		/* note USA_PARITY_NONE == 0 */
+		msg.lcr |= (p_priv->cflag & PARODD)?
+			USA_PARITY_ODD: USA_PARITY_EVEN;
+	}
+	msg.setLcr = 0xff;
 
-	//memset(msg, 0, sizeof (struct portControlMessage));
+	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
+	msg.xonFlowControl = 0;
+	msg.setFlowControl = 0xff;
+	
+	msg.forwardingLength = 1;
+	msg.xonChar = 17;
+	msg.xoffChar = 19;
+	
+	msg._txOn = 1;
+	msg._txOff = 0;
+	msg.txFlush = 0;
+	msg.txBreak = 0;
+	msg.rxOn = 1;
+	msg.rxOff = 0;
+	msg.rxFlush = 0;
+	msg.rxForward = 0;
+	/*msg.returnStatus = 1;
+	msg.resetDataToggle = 0xff;*/
+
+		/* Do handshaking outputs */	
+	msg.setTxTriState_setRts = 0xff;
+	msg.txTriState_rts = p_priv->rts_state;
+
+	msg.setHskoa_setDtr = 0xff;
+	msg.hskoa_dtr = p_priv->dtr_state;
 		
+	p_priv->resend_cont = 0;
+	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
+	
+	/* send the data out the device on control endpoint */
+	this_urb->transfer_buffer_length = sizeof(msg);
+
+	this_urb->dev = serial->dev;
+	if ((err = usb_submit_urb(this_urb)) != 0) {
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);
+	}
+#if 0
+	else {
+		dbg(__FUNCTION__ " usb_submit_urb(%d) OK %d bytes (end %d)",
+		    outcont_urb, this_urb->transfer_buffer_length,
+		    usb_pipeendpoint(this_urb->pipe));
+	}
+#endif
+
+	return (0);
+}
+
+static int keyspan_usa28_send_setup(struct usb_serial *serial,
+				    struct usb_serial_port *port)
+{
+	struct keyspan_usa28_portControlMessage	msg;		
+	struct keyspan_serial_private	 	*s_priv;
+	struct keyspan_port_private 		*p_priv;
+	const  keyspan_device_details		*d_details;
+	urb_t *this_urb;
+	int err;
+
+	s_priv = (struct keyspan_serial_private *)(serial->private);
+	p_priv = (struct keyspan_port_private *)(port->private);
+	d_details = s_priv->device_details;
+
+	/* only do something if we have a bulk out endpoint */
+	if ((this_urb = p_priv->outcont_urb) == NULL) {
+		dbg(__FUNCTION__ " oops no urb.");
+		return -1;
+	}
+
+	p_priv->resend_cont = 1;
+	if (this_urb->status == -EINPROGRESS) {
+		dbg (__FUNCTION__ " already writing");
+		return(-1);
+	}
+
+	memset(&msg, 0, sizeof (struct keyspan_usa28_portControlMessage));
+
 	msg.setBaudRate = 1;
-	if (keyspan_usa19_calc_baud(9600, &msg.baudHi, &msg.baudLo) ==
-		KEYSPAN_INVALID_BAUD_RATE ) {
-		dbg(__FUNCTION__ "Invalid baud rate requested %d.\n", 9600);
+	if (keyspan_usa19_calc_baud(p_priv->baud, d_details->baudclk,
+		&msg.baudHi, &msg.baudLo, NULL) == KEYSPAN_INVALID_BAUD_RATE ) {
+		dbg(__FUNCTION__ "Invalid baud rate requested %d.", 9600);
 		msg.baudLo = 0xff;
 		msg.baudHi = 0xb2;	/* Values for 9600 baud */
 	}
 
-		/* If parity is enabled, we must calculate it ourselves. */
-	if (p_priv->parity) {
-		msg.parity = 1;
+	/* If parity is enabled, we must calculate it ourselves. */
+	msg.parity = 0;		/* XXX for now */
+
+	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
+	msg.xonFlowControl = 0;
+
+	/* Do handshaking outputs, DTR is inverted relative to RTS */	
+	msg.rts = p_priv->rts_state;
+	msg.dtr = p_priv->dtr_state;
+
+	msg.forwardingLength = 1;
+	msg.forwardMs = 10;
+	msg.breakThreshold = 45;
+	msg.xonChar = 17;
+	msg.xoffChar = 19;
+
+	msg._txOn = 1;
+	msg._txOff = 0;
+	msg.txFlush = 0;
+	msg.txForceXoff = 0;
+	msg.txBreak = 0;
+	msg.rxOn = 1;
+	msg.rxOff = 0;
+	msg.rxFlush = 0;
+	msg.rxForward = 0;
+	/*msg.returnStatus = 1;
+	msg.resetDataToggle = 0xff;*/
+
+	p_priv->resend_cont = 0;
+	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
+
+	/* send the data out the device on control endpoint */
+	this_urb->transfer_buffer_length = sizeof(msg);
+
+	this_urb->dev = serial->dev;
+	if ((err = usb_submit_urb(this_urb)) != 0) {
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed");
 	}
+#if 0
 	else {
-		msg.parity = 0;
+		dbg(__FUNCTION__ " usb_submit_urb(setup) OK %d bytes",
+		    this_urb->transfer_buffer_length);
+	}
+#endif
+
+	return (0);
+}
+
+static int keyspan_usa49_send_setup(struct usb_serial *serial,
+				    struct usb_serial_port *port)
+{
+	struct keyspan_usa49_portControlMessage	msg;		
+	struct keyspan_serial_private 		*s_priv;
+	struct keyspan_port_private 		*p_priv;
+	const  keyspan_device_details		*d_details;
+	int 					glocont_urb;
+	urb_t *this_urb;
+	int err;
+
+	/*  dbg (__FUNCTION__); */
+
+	s_priv = (struct keyspan_serial_private *)(serial->private);
+	p_priv = (struct keyspan_port_private *)(port->private);
+	d_details = s_priv->device_details;
+
+	glocont_urb = d_details->glocont_endpoint;
+	this_urb = s_priv->glocont_urb;
+
+	/*  dbg(__FUNCTION__ " port %d\n", port->number); */
+
+		/* Make sure we have an urb then send the message */
+	if (this_urb == NULL) {
+		dbg(__FUNCTION__ " oops no urb for port %d.", port->number);
+		return -1;
+	}
+
+	p_priv->resend_cont = 1;
+	if (this_urb->status == -EINPROGRESS) {
+		/*  dbg (__FUNCTION__ " already writing"); */
+		return(-1);
+	}
+
+	memset(&msg, 0, sizeof (struct keyspan_usa49_portControlMessage));
+
+	msg.portNumber = port->number;
+	
+		/* Only set baud rate if it's changed */	
+	if (p_priv->old_baud != p_priv->baud) {
+		p_priv->old_baud = p_priv->baud;
+		msg.setClocking = 0xff;
+		if (d_details->calculate_baud_rate
+		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
+		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {
+			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",
+			    p_priv->baud);
+			msg.baudLo = 0;
+			msg.baudHi = 125;	/* Values for 9600 baud */
+			msg.prescaler = 10;
+		}
+		//msg.setPrescaler = 0xff;
 	}
 
-	msg.ctsFlowControl = 0;
+	msg.lcr = USA_DATABITS_8 | STOPBITS_5678_1;
+	if (p_priv->cflag & PARENB) {
+		/* note USA_PARITY_NONE == 0 */
+		msg.lcr |= (p_priv->cflag & PARODD)?
+			USA_PARITY_ODD: USA_PARITY_EVEN;
+	}
+	msg.setLcr = 0xff;
+
+	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
 	msg.xonFlowControl = 0;
-	msg.rts = 1;
-	msg.dtr = 0;
+	msg.setFlowControl = 0xff;
 	
 	msg.forwardingLength = 1;
-	msg.forwardMs = 10;
-	msg.breakThreshold = 45;
 	msg.xonChar = 17;
 	msg.xoffChar = 19;
 	
 	msg._txOn = 1;
 	msg._txOff = 0;
 	msg.txFlush = 0;
-	msg.txForceXoff = 0;
 	msg.txBreak = 0;
 	msg.rxOn = 1;
 	msg.rxOff = 0;
 	msg.rxFlush = 0;
 	msg.rxForward = 0;
-	msg.returnStatus = 1;
-	msg.resetDataToggle = 1;
+	msg.enablePort = 0xff;
+	msg.disablePort = 0;
+
+		/* Do handshaking outputs */	
+	msg.setRts = 0xff;
+	msg.rts = p_priv->rts_state;
 
+	msg.setDtr = 0xff;
+	msg.dtr = p_priv->dtr_state;
 		
-	/* only do something if we have a bulk out endpoint */
-	if (s_priv->out_urbs[2]) {
-		if (s_priv->out_urbs[2]->status == -EINPROGRESS) {
-			dbg (__FUNCTION__ " already writing");
-			return(-1);
-		}
-		memcpy (s_priv->out_urbs[2]->transfer_buffer, &msg, sizeof(msg));
+	p_priv->resend_cont = 0;
+	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
 	
-			/* send the data out the device on control endpoint */
-		s_priv->out_urbs[2]->transfer_buffer_length = sizeof(msg);
+	/* send the data out the device on control endpoint */
+	this_urb->transfer_buffer_length = sizeof(msg);
 
-		if (usb_submit_urb(s_priv->out_urbs[2])) {
-			dbg(__FUNCTION__ " usb_submit_urb(setup) failed\n");
-		}
-		else {
-			dbg(__FUNCTION__ " usb_submit_urb(setup) OK %d bytes\n", s_priv->out_urbs[2]->transfer_buffer_length);
-		}
-	
+	this_urb->dev = serial->dev;
+	if ((err = usb_submit_urb(this_urb)) != 0) {
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);
 	}
+#if 0
+	else {
+		dbg(__FUNCTION__ " usb_submit_urb(%d) OK %d bytes (end %d)",
+		    outcont_urb, this_urb->transfer_buffer_length,
+		    usb_pipeendpoint(this_urb->pipe));
+	}
+#endif
+
 	return (0);
 }
 
+static void keyspan_send_setup(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct keyspan_serial_private 	*s_priv;
+	const keyspan_device_details	*d_details;
+
+	s_priv = (struct keyspan_serial_private *)(serial->private);
+	d_details = s_priv->device_details;
 
-	/* Gets called by the "real" driver (ie once firmware is loaded
-	   and renumeration has taken place. */
+	switch (d_details->msg_format) {
+	case msg_usa26:
+		keyspan_usa26_send_setup(serial, port);
+		break;
+	case msg_usa28:
+		keyspan_usa28_send_setup(serial, port);
+		break;
+	case msg_usa49:
+		keyspan_usa49_send_setup(serial, port);
+		break;
+	}
+}
+
+/* Gets called by the "real" driver (ie once firmware is loaded
+   and renumeration has taken place. */
 static int keyspan_startup (struct usb_serial *serial)
 {
-	int			i;
-	struct usb_serial_port	*port;
+	int				i, err;
+	struct usb_serial_port		*port;
+	struct keyspan_serial_private 	*s_priv;
+	struct keyspan_port_private	*p_priv;
+	const keyspan_device_details	*d_details;
+
+	/*  dbg("keyspan_startup called."); */
 
-	dbg("keyspan_startup called.\n");
+	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
+		if (d_details->product_id == serial->dev->descriptor.idProduct)
+			break;
+	if (d_details == NULL) {
+		printk(KERN_ERR __FUNCTION__ ": unknown product id %x\n",
+		       serial->dev->descriptor.idProduct);
+		return 1;
+	}
 
-		/* Setup private data for serial driver */
-	serial->private = kmalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL);
+	/* Setup private data for serial driver */
+	serial->private = kmalloc(sizeof(struct keyspan_serial_private),
+				  GFP_KERNEL);
 	if (!serial->private) {
-		dbg(__FUNCTION__ "kmalloc for keyspan_serial_private failed!.\n");
+		dbg(__FUNCTION__ "kmalloc for keyspan_serial_private failed.");
 		return (1);
 	}
 	memset(serial->private, 0, sizeof(struct keyspan_serial_private));
+
+	s_priv = (struct keyspan_serial_private *)(serial->private);
+	s_priv->device_details = d_details;
 		
-	init_waitqueue_head(&out_wait);
-	
-		/* Now setup per port private data */
+	/* Now setup per port private data */
 	for (i = 0; i < serial->num_ports; i++) {
 		port = &serial->port[i];
-		port->private = kmalloc(sizeof(struct keyspan_port_private), GFP_KERNEL);
+		port->private = kmalloc(sizeof(struct keyspan_port_private),
+					GFP_KERNEL);
 		if (!port->private) {
-			dbg(__FUNCTION__ "kmalloc for keyspan_port_private (%d) failed!.\n", i);
+			dbg(__FUNCTION__ "kmalloc for keyspan_port_private (%d) failed!.", i);
 			return (1);
 		}
 		memset(port->private, 0, sizeof(struct keyspan_port_private));
+		p_priv = (struct keyspan_port_private *)(port->private);
+		p_priv->device_details = d_details;
 	}
 
-	
+	keyspan_setup_urbs(serial);
 
-	switch (serial->dev->descriptor.idProduct) {
-		case 0x0107:	keyspan_usa19_setup_urbs(serial);
-				//keyspan_send_usa19_setup(serial);
-				break;
-
-		default:	break;
+	s_priv->instat_urb->dev = serial->dev;
+	if ((err = usb_submit_urb(s_priv->instat_urb)) != 0) {
+		dbg(__FUNCTION__ " submit instat urb failed %d", err);
 	}
-
 			
 	return (0);
 }
 
 static void keyspan_shutdown (struct usb_serial *serial)
 {
-	int				i;
+	int				i, j;
 	struct usb_serial_port		*port;
 	struct keyspan_serial_private 	*s_priv;
+	struct keyspan_port_private	*p_priv;
 
-	dbg("keyspan_shutdown called freeing ");
+	/*  dbg("keyspan_shutdown called"); */
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 
-		/* Stop reading/writing urbs */
-	for (i = 0; i < 4; i++) {
-		if (s_priv->in_urbs[i]) {
-			usb_unlink_urb(s_priv->in_urbs[i]);
+	/* Stop reading/writing urbs */
+	stop_urb(s_priv->instat_urb);
+	stop_urb(s_priv->glocont_urb);
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = &serial->port[i];
+		p_priv = (struct keyspan_port_private *)(port->private);
+		stop_urb(p_priv->inack_urb);
+		stop_urb(p_priv->outcont_urb);
+		for (j = 0; j < 2; j++) {
+			stop_urb(p_priv->in_urbs[j]);
+			stop_urb(p_priv->out_urbs[j]);
 		}
-
 	}
-	for (i = 0; i < 3; i++) {
-		if (s_priv->out_urbs[i]) {
-			usb_unlink_urb(s_priv->out_urbs[i]);
-		}
 
-	}
-		/* Now free them */
-	for (i = 0; i < 7; i ++) {
-		if (s_priv->in_urbs[i] != NULL) {
-			dbg("in%d ", i);
-			usb_free_urb(s_priv->in_urbs[i]);
-		}
-		
-		if (s_priv->out_urbs[i] != NULL) {
-			dbg("out%d ", i);
-			usb_free_urb(s_priv->out_urbs[i]);
+	/* Now free them */
+	if (s_priv->instat_urb)
+		usb_free_urb(s_priv->instat_urb);
+	if (s_priv->glocont_urb)
+		usb_free_urb(s_priv->glocont_urb);
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = &serial->port[i];
+		p_priv = (struct keyspan_port_private *)(port->private);
+		if (p_priv->inack_urb)
+			usb_free_urb(p_priv->inack_urb);
+		if (p_priv->outcont_urb)
+			usb_free_urb(p_priv->outcont_urb);
+		for (j = 0; j < 2; j++) {
+			if (p_priv->in_urbs[j])
+				usb_free_urb(p_priv->in_urbs[j]);
+			if (p_priv->out_urbs[j])
+				usb_free_urb(p_priv->out_urbs[j]);
 		}
 	}
-	dbg("urbs.\n");
 
-	dbg("Freeing serial->private.\n");	
+	/*  dbg("Freeing serial->private."); */
 	kfree(serial->private);
 
-	dbg("Freeing port->private.\n");	
-		/* Now free per port private data */
+	/*  dbg("Freeing port->private."); */
+	/* Now free per port private data */
 	for (i = 0; i < serial->num_ports; i++) {
 		port = &serial->port[i];
+		while (port->open_count > 0) {
+			--port->open_count;
+			MOD_DEC_USE_COUNT;
+		}
 		kfree(port->private);
 	}
-	
 }
-
-
-static int __init keyspan_init (void)
-{
-	usb_serial_register (&keyspan_usa18x_pre_device);
-	usb_serial_register (&keyspan_usa19_pre_device);
-	usb_serial_register (&keyspan_usa19w_pre_device);
-	usb_serial_register (&keyspan_usa28_pre_device);
-	usb_serial_register (&keyspan_usa28x_pre_device);
-	usb_serial_register (&keyspan_usa18x_device);
-	usb_serial_register (&keyspan_usa19_device);
-	usb_serial_register (&keyspan_usa19w_device);
-	usb_serial_register (&keyspan_usa28_device);
-	usb_serial_register (&keyspan_usa28x_device);
-	return 0;
-}
-
-
-static void __exit keyspan_exit (void)
-{
-	usb_serial_deregister (&keyspan_usa18x_pre_device);
-	usb_serial_deregister (&keyspan_usa19_pre_device);
-	usb_serial_deregister (&keyspan_usa19w_pre_device);
-	usb_serial_deregister (&keyspan_usa28_pre_device);
-	usb_serial_deregister (&keyspan_usa28x_pre_device);
-	usb_serial_deregister (&keyspan_usa18x_device);
-	usb_serial_deregister (&keyspan_usa19_device);
-	usb_serial_deregister (&keyspan_usa19w_device);
-	usb_serial_deregister (&keyspan_usa28_device);
-	usb_serial_deregister (&keyspan_usa28x_device);
-}
-
-
-module_init(keyspan_init);
-module_exit(keyspan_exit);
-
-MODULE_AUTHOR("Hugh Blemings <hugh@linuxcare.com>");
-MODULE_DESCRIPTION("Keyspan USB to Serial Converter driver");
diff -urN linux-2.2.19-pre6/drivers/usb/serial/keyspan.h linux/drivers/usb/serial/keyspan.h
--- linux-2.2.19-pre6/drivers/usb/serial/keyspan.h	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/serial/keyspan.h	Mon Dec  3 20:57:55 2001
@@ -19,6 +19,11 @@
   and Keyspan, Inc the manufacturers of the Keyspan USB-serial products.
   Thanks Guys :)
   
+  Thanks to Paulus for miscellaneous tidy ups, some largish chunks
+  of much nicer and/or completely new code and (perhaps most uniquely)
+  having the patience to sit down and explain why and where he'd changed
+  stuff.
+
   Tip 'o the hat to Linuxcare for supporting staff in their work on
   open source projects.
   
@@ -41,12 +46,18 @@
 static void keyspan_rx_throttle		(struct usb_serial_port *port);
 static void keyspan_rx_unthrottle	(struct usb_serial_port *port);
 static int  keyspan_write_room		(struct usb_serial_port *port);
+
 static int  keyspan_write		(struct usb_serial_port *port,
 					 int from_user,
 					 const unsigned char *buf,
 					 int count);
+
+#if 0
 static void keyspan_write_bulk_callback (struct urb *urb);
-static void keyspan_read_bulk_callback  (struct urb *urb);
+#endif
+
+//static void keyspan_usa26_read_int_callback  (struct urb *urb);
+//static void keyspan_usa28_read_int_callback  (struct urb *urb);
 static int  keyspan_chars_in_buffer 	(struct usb_serial_port *port);
 static int  keyspan_ioctl		(struct usb_serial_port *port,
 					 struct file *file,
@@ -58,12 +69,20 @@
 					 int break_state);
 static int  keyspan_fake_startup	(struct usb_serial *serial);
 
-static int  keyspan_usa19_calc_baud	(u32 baud_rate, u8 *rate_hi, 
-					 u8 *rate_low);
-static void keyspan_usa19_setup_urbs	(struct usb_serial *serial);
-static int  keyspan_usa19_send_setup	(struct usb_serial *serial,
-					 struct usb_serial_port *port);
+static int  keyspan_usa19_calc_baud	(u32 baud_rate, u32 baudclk, 
+					 u8 *rate_hi, u8 *rate_low, u8 *prescaler);
+
+static int  keyspan_usa19w_calc_baud	(u32 baud_rate, u32 baudclk,
+					 u8 *rate_hi, u8 *rate_low, u8 *prescaler);
+
+//static void keyspan_usa19_setup_urbs	(struct usb_serial *serial);
 
+static int  keyspan_usa28_send_setup	(struct usb_serial *serial,
+					 struct usb_serial_port *port);
+static int  keyspan_usa26_send_setup	(struct usb_serial *serial,
+	       				 struct usb_serial_port *port);
+static int  keyspan_usa49_send_setup	(struct usb_serial *serial,
+					 struct usb_serial_port *port);
 
 	/* Functions from usbserial.c for ezusb firmware handling */
 extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit);
@@ -109,34 +128,186 @@
 	static const struct ezusb_hex_record *keyspan_usa19w_firmware = NULL;
 #endif
 
-
+#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA49W
+        #include "keyspan_usa49w_fw.h"
+#else
+	static const struct ezusb_hex_record *keyspan_usa49w_firmware = NULL;
+#endif
+	
 	/* Values used for baud rate calculation - device specific */
 #define	KEYSPAN_INVALID_BAUD_RATE		(-1)
 #define	KEYSPAN_BAUD_RATE_OK			(0)
-#define	USA19_BAUDCLK				(12000000L)
+#define	KEYSPAN_USA18X_BAUDCLK			(12000000L)	/* a guess */
+#define	KEYSPAN_USA19_BAUDCLK			(12000000L)
+#define	KEYSPAN_USA19W_BAUDCLK			(24000000L)
+#define	KEYSPAN_USA28X_BAUDCLK			(12000000L)
+#define	KEYSPAN_USA49W_BAUDCLK			(48000000L)
+
+	/* Some constants used to characterise each device. 
+	   There is a four port device due later in the year,
+	   we allow for it now in the following */
+#define		KEYSPAN_MAX_NUM_PORTS		(4)
+#define		KEYSPAN_MAX_FLIPS		(2)
+	
+typedef struct {
+	/* product ID value */
+	int	product_id;
+	
+	enum	{msg_usa26, msg_usa28, msg_usa49} msg_format;
+
+		/* Number of physical ports */
+	int	num_ports;
+
+		/* 1 if endpoint flipping used on input, 0 if not */
+	int	indat_endp_flip;
+
+		/* 1 if endpoint flipping used on output, 0 if not */
+	int 	outdat_endp_flip;
+
+		/* Table mapping input data endpoint IDs to physical
+		   port number and flip if used */
+	int	indat_endpoints[KEYSPAN_MAX_NUM_PORTS];
+
+		/* Same for output endpoints */
+	int	outdat_endpoints[KEYSPAN_MAX_NUM_PORTS];
+
+		/* Input acknowledge endpoints */
+	int	inack_endpoints[KEYSPAN_MAX_NUM_PORTS];
+
+		/* Output control endpoints */	
+	int	outcont_endpoints[KEYSPAN_MAX_NUM_PORTS];
+
+		/* Endpoint used for input status */
+	int	instat_endpoint;
+
+		/* Endpoint used for global control functions */
+	int	glocont_endpoint;	
+	
+	int	(*calculate_baud_rate) (u32 baud_rate, u32 baudclk,
+			u8 *rate_hi, u8 *rate_low, u8 *prescaler);
+	u32	baudclk;
+
+} keyspan_device_details; 
+
+	/* Now for each device type we setup the device detail
+	   structure with the appropriate information (provided
+	   in Keyspan's documentation) */
+
+static const keyspan_device_details usa18x_device_details = {
+	0x112,				/* product ID */
+       	msg_usa26, 			/* msg type*/
+	1,				/* num ports */
+	0,				/* indat endpoint flip */
+	1,				/* outdat endpoint flip */
+  	{0x81},				/* per port indat */
+  	{0x01},				/* per port outdat */
+	{0x85},				/* per port inack */
+	{0x05},				/* per port outcont */
+	0x87,				/* instat endpoint */
+	0x07,				/* glocont endpoint */
+	keyspan_usa19w_calc_baud,	/* calc baud rate */
+	KEYSPAN_USA18X_BAUDCLK		/* base baud clock */
+};
+
+static const keyspan_device_details usa19_device_details = {
+	0x107,				/* product ID */
+       	msg_usa28, 			/* msg type*/
+	1,				/* num ports */
+	1,				/* indat endpoint flip */
+	1,				/* outdat endpoint flip */
+  	{0x81},				/* per port indat */
+  	{0x01},				/* per port outdat */
+	{0x83},				/* per port inack */
+	{0x03},				/* per port outcont */
+	0x84,				/* instat endpoint */
+	-1,				/* glocont endpoint */
+	keyspan_usa19_calc_baud,	/* calc baud rate */
+	KEYSPAN_USA19_BAUDCLK		/* base baud clock */
+};
+
+static const keyspan_device_details usa19w_device_details = {
+	0x108,				/* product ID */
+       	msg_usa26, 			/* msg type*/
+	1,				/* num ports */
+	0,				/* indat endpoint flip */
+	1,				/* outdat endpoint flip */
+  	{0x81},				/* per port indat */
+  	{0x01},				/* per port outdat */
+	{0x85},				/* per port inack */
+	{0x05},				/* per port outcont */
+	0x87,				/* instat endpoint */
+	0x07,				/* glocont endpoint */
+	keyspan_usa19w_calc_baud,	/* calc baud rate */
+	KEYSPAN_USA19W_BAUDCLK		/* base baud clock */
+};
+
+static const keyspan_device_details usa28x_device_details = {
+	0x110,				/* product ID */
+       	msg_usa26, 			/* msg type*/
+	2,				/* num ports */
+	0,				/* indat endpoint flip */
+	1,				/* outdat endpoint flip */
+  	{0x81, 0x83},			/* per port indat */
+  	{0x01, 0x03},			/* per port outdat */
+	{0x85, 0x86},			/* per port inack */
+	{0x05, 0x06},			/* per port outcont */
+	0x87,				/* instat endpoint */
+	0x07,				/* glocont endpoint */
+	keyspan_usa19w_calc_baud,	/* calc baud rate */
+	KEYSPAN_USA28X_BAUDCLK
+};
+
+static const keyspan_device_details usa49w_device_details = {
+	0x010a,				/* product ID */
+       	msg_usa49, 			/* msg type*/
+	4,				/* num ports */
+	0,				/* indat endpoint flip */
+	0,				/* outdat endpoint flip */
+  	{ 0x81, 0x82, 0x83, 0x84},	/* per port indat */
+  	{ 0x01, 0x02, 0x03, 0x04},	/* per port outdat */
+	{-1, -1, -1, -1},		/* per port inack */
+	{-1, -1, -1, -1},		/* per port outcont */
+	0x87,				/* instat endpoint */
+	0x07,				/* glocont endpoint */
+	keyspan_usa19w_calc_baud,	/* calc baud rate */
+	KEYSPAN_USA49W_BAUDCLK
+};
+
+static const keyspan_device_details *keyspan_devices[] = {
+	&usa18x_device_details,
+	&usa19_device_details,
+	&usa19w_device_details,
+	&usa28x_device_details,
+	&usa49w_device_details,
+	NULL
+};
 
-	/* Device info for the Keyspan serial converter */
+	/* Device info for the Keyspan serial converter, used
+	   by the overall usb-serial probe function */
 #define KEYSPAN_VENDOR_ID			(0x06cd)
 static __u16	keyspan_vendor_id		= KEYSPAN_VENDOR_ID;
 
     /* Product IDs for the five products supported, pre-renumeration */
-static __u16	keyspan_usa18x_pre_product_id	= 0x0105;	
-static __u16	keyspan_usa19_pre_product_id	= 0x0103;	
-static __u16	keyspan_usa19w_pre_product_id	= 0x0106;	
-static __u16	keyspan_usa28_pre_product_id	= 0x0101;	
-static __u16	keyspan_usa28x_pre_product_id	= 0x0102;	
+static __u16	keyspan_usa18x_pre_product_id	= 0x0105;
+static __u16	keyspan_usa19_pre_product_id	= 0x0103;
+static __u16	keyspan_usa19w_pre_product_id	= 0x0106;
+static __u16	keyspan_usa28_pre_product_id	= 0x0101;
+static __u16	keyspan_usa28x_pre_product_id	= 0x0102;
+static __u16	keyspan_usa49w_pre_product_id	= 0x0109;
 
     /* Product IDs post-renumeration */
-static __u16	keyspan_usa18x_product_id	= 0x0112;	
-static __u16	keyspan_usa19_product_id	= 0x0107;	
-static __u16	keyspan_usa19w_product_id	= 0x0108;	
-static __u16	keyspan_usa28_product_id	= 0x010f;	
-static __u16	keyspan_usa28x_product_id	= 0x0110;	
+static __u16	keyspan_usa18x_product_id	= 0x0112;
+static __u16	keyspan_usa19_product_id	= 0x0107;
+static __u16	keyspan_usa19w_product_id	= 0x0108;
+static __u16	keyspan_usa28_product_id	= 0x010f;
+static __u16	keyspan_usa28x_product_id	= 0x0110;
+static __u16	keyspan_usa49w_product_id	= 0x010a;
+
 
     /* Structs for the devices, pre and post renumeration.
        These are incomplete at present - HAB 20000708  */
 struct usb_serial_device_type keyspan_usa18x_pre_device = {
-	name:			"Keyspan USA18X - (prerenumeration)",
+	name:			"Keyspan USA18X - (without firmware)",
 	idVendor:		&keyspan_vendor_id,
 	idProduct:		&keyspan_usa18x_pre_product_id,
 	needs_interrupt_in:	DONT_CARE,
@@ -150,7 +321,7 @@
 };
 
 struct usb_serial_device_type keyspan_usa19_pre_device = {
-	name:			"Keyspan USA19 - (prerenumeration)",
+	name:			"Keyspan USA19 - (without firmware)",
 	idVendor:		&keyspan_vendor_id,
 	idProduct:		&keyspan_usa19_pre_product_id,
 	needs_interrupt_in:	DONT_CARE,
@@ -165,7 +336,7 @@
 
 
 struct usb_serial_device_type keyspan_usa19w_pre_device = {
-	name:			"Keyspan USA19W - (prerenumeration)",
+	name:			"Keyspan USA19W - (without firmware)",
 	idVendor:		&keyspan_vendor_id,
 	idProduct:		&keyspan_usa19w_pre_product_id,
 	needs_interrupt_in:	DONT_CARE,
@@ -180,7 +351,7 @@
 
 
 struct usb_serial_device_type keyspan_usa28_pre_device = {
-	name:			"Keyspan USA28 - (prerenumeration)",
+	name:			"Keyspan USA28 - (without firmware)",
 	idVendor:		&keyspan_vendor_id,
 	idProduct:		&keyspan_usa28_pre_product_id,
 	needs_interrupt_in:	DONT_CARE,
@@ -194,7 +365,7 @@
 };
 
 struct usb_serial_device_type keyspan_usa28x_pre_device = {
-	name:			"Keyspan USA28X - (prerenumeration)",
+	name:			"Keyspan USA28X - (without firmware)",
 	idVendor:		&keyspan_vendor_id,
 	idProduct:		&keyspan_usa28x_pre_product_id,
 	needs_interrupt_in:	DONT_CARE,
@@ -207,23 +378,45 @@
 	startup:		keyspan_fake_startup	
 };
 
+struct usb_serial_device_type keyspan_usa49w_pre_device = {
+	name:			"Keyspan USA49W - (without firmware)",
+	idVendor:		&keyspan_vendor_id,
+	idProduct:		&keyspan_usa49w_pre_product_id,
+	needs_interrupt_in:	DONT_CARE,
+	needs_bulk_in:		DONT_CARE,
+	needs_bulk_out:		DONT_CARE,
+	num_interrupt_in:	NUM_DONT_CARE,
+	num_bulk_in:		NUM_DONT_CARE,
+	num_bulk_out:		NUM_DONT_CARE,
+	num_ports:		4,
+	startup:		keyspan_fake_startup	
+};
 
 struct usb_serial_device_type keyspan_usa18x_device = {
 	name:			"Keyspan USA18X",
 	idVendor:		&keyspan_vendor_id,
 	idProduct:		&keyspan_usa18x_product_id,
 	needs_interrupt_in:	DONT_CARE,	
-	needs_bulk_in:		DONT_CARE,
-	needs_bulk_out:		DONT_CARE,
+	needs_bulk_in:		MUST_HAVE,
+	needs_bulk_out:		MUST_HAVE,
 	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		NUM_DONT_CARE,
-	num_bulk_out:		NUM_DONT_CARE,
+	num_bulk_in:		3,
+	num_bulk_out:		4,
 	num_ports:		1,
 	open:			keyspan_open,
 	close:			keyspan_close,
+	write:			keyspan_write,
+	write_room:		keyspan_write_room,
+	//write_bulk_callback: 	Not used - we define our own herbs
+	//read_int_callback:	keyspan_usa26_read_int_callback,
+	chars_in_buffer:	keyspan_chars_in_buffer,
 	throttle:		keyspan_rx_throttle,
 	unthrottle:		keyspan_rx_unthrottle,
+	ioctl:			keyspan_ioctl,
 	set_termios:		keyspan_set_termios,
+	break_ctl:		keyspan_break_ctl,
+	startup:		keyspan_startup,
+	shutdown:		keyspan_shutdown,
 };
 
 struct usb_serial_device_type keyspan_usa19_device = {
@@ -241,8 +434,8 @@
 	close:			keyspan_close,
 	write:			keyspan_write,
 	write_room:		keyspan_write_room,
-	write_bulk_callback: 	keyspan_write_bulk_callback,
-	read_int_callback:	keyspan_read_bulk_callback,
+//	write_bulk_callback: 	keyspan_write_bulk_callback,
+//	read_int_callback:	keyspan_usa28_read_int_callback,
 	chars_in_buffer:	keyspan_chars_in_buffer,
 	throttle:		keyspan_rx_throttle,
 	unthrottle:		keyspan_rx_unthrottle,
@@ -259,17 +452,26 @@
 	idVendor:		&keyspan_vendor_id,
 	idProduct:		&keyspan_usa19w_product_id,
 	needs_interrupt_in:	DONT_CARE,	
-	needs_bulk_in:		DONT_CARE,
-	needs_bulk_out:		DONT_CARE,
+	needs_bulk_in:		MUST_HAVE,
+	needs_bulk_out:		MUST_HAVE,
 	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		NUM_DONT_CARE,
-	num_bulk_out:		NUM_DONT_CARE,
+	num_bulk_in:		3,
+	num_bulk_out:		4,
 	num_ports:		1,
 	open:			keyspan_open,
 	close:			keyspan_close,
+	write:			keyspan_write,
+	write_room:		keyspan_write_room,
+	//write_bulk_callback: 	Not used - we define our own herbs
+	//read_int_callback:	keyspan_usa26_read_int_callback,
+	chars_in_buffer:	keyspan_chars_in_buffer,
 	throttle:		keyspan_rx_throttle,
 	unthrottle:		keyspan_rx_unthrottle,
+	ioctl:			keyspan_ioctl,
 	set_termios:		keyspan_set_termios,
+	break_ctl:		keyspan_break_ctl,
+	startup:		keyspan_startup,
+	shutdown:		keyspan_shutdown,
 };
 
 
@@ -307,8 +509,8 @@
 	close:			keyspan_close,
 	write:			keyspan_write,
 	write_room:		keyspan_write_room,
-	write_bulk_callback: 	keyspan_write_bulk_callback,
-	read_int_callback:	keyspan_read_bulk_callback,
+//	write_bulk_callback: 	keyspan_write_bulk_callback,
+//	read_int_callback:	keyspan_usa26_read_int_callback,
 	chars_in_buffer:	keyspan_chars_in_buffer,
 	throttle:		keyspan_rx_throttle,
 	unthrottle:		keyspan_rx_unthrottle,
@@ -318,10 +520,35 @@
 	startup:		keyspan_startup,
 	shutdown:		keyspan_shutdown,
 
+};
 				
 
+struct usb_serial_device_type keyspan_usa49w_device = {
+	name:			"Keyspan USA49W",
+	idVendor:		&keyspan_vendor_id,
+	idProduct:		&keyspan_usa49w_product_id,
+	needs_interrupt_in:	DONT_CARE,	
+	needs_bulk_in:		MUST_HAVE,
+	needs_bulk_out:		MUST_HAVE,
+	num_interrupt_in:	NUM_DONT_CARE,
+	num_bulk_in:		5,
+	num_bulk_out:		5,
+	num_ports:		4,
+	open:			keyspan_open,
+	close:			keyspan_close,
+	write:			keyspan_write,
+	write_room:		keyspan_write_room,
+	//write_bulk_callback: 	Not used - we define our own herbs
+	//read_int_callback:	keyspan_usa26_read_int_callback,
+	chars_in_buffer:	keyspan_chars_in_buffer,
+	throttle:		keyspan_rx_throttle,
+	unthrottle:		keyspan_rx_unthrottle,
+	ioctl:			keyspan_ioctl,
+	set_termios:		keyspan_set_termios,
+	break_ctl:		keyspan_break_ctl,
+	startup:		keyspan_startup,
+	shutdown:		keyspan_shutdown,
 };
-
 
 
 #endif
diff -urN linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa26msg.h linux/drivers/usb/serial/keyspan_usa26msg.h
--- linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa26msg.h	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/serial/keyspan_usa26msg.h	Mon Dec  3 20:57:55 2001
@@ -92,16 +92,8 @@
 #ifndef	__USA26MSG__
 #define	__USA26MSG__
 
-#ifndef __stubs__
-#include "datadefs.h"
-#endif
 
-typedef struct txAckMessage
-{
-	u8	dummy;
-} txAckMessage;
-
-typedef struct portControlMessage
+typedef struct keyspan_usa26_portControlMessage
 {
 	/*
 		there are three types of "commands" sent in the control message:
@@ -172,7 +164,7 @@
 		returnStatus,	// BOTH: return current status (even if it hasn't changed)
 		resetDataToggle;// BOTH: reset data toggle state to DATA0
 	
-} portControlMessage;
+} keyspan_usa26_portControlMessage;
 
 // defines for bits in lcr
 #define	USA_DATABITS_5		0x00
@@ -190,7 +182,7 @@
 
 // all things called "StatusMessage" are sent on the status endpoint
 
-typedef struct portStatusMessage	// one for each port
+typedef struct keyspan_usa26_portStatusMessage	// one for each port
 {
 	u8	port,			// BOTH: 0=first, 1=second, other=see below
 		hskia_cts,		// USA26: reports HSKIA pin
@@ -203,7 +195,7 @@
 		_txXoff,		// port is in XOFF state (either host or RX XOFF)
 		rxEnabled,		// as configured by rxOn/rxOff 1=on, 0=off
 		controlResponse;// 1=a control message has been processed
-} portStatusMessage;
+} keyspan_usa26_portStatusMessage;
 
 // bits in RX data message when STAT byte is included
 #define	RXERROR_OVERRUN	0x02
@@ -211,28 +203,28 @@
 #define	RXERROR_FRAMING	0x08
 #define	RXERROR_BREAK	0x10
 
-typedef struct globalControlMessage
+typedef struct keyspan_usa26_globalControlMessage
 {
 	u8	sendGlobalStatus,	// 2=request for two status responses
 		resetStatusToggle,	// 1=reset global status toggle
 		resetStatusCount;	// a cycling value
-} globalControlMessage;
+} keyspan_usa26_globalControlMessage;
 
-typedef struct globalStatusMessage
+typedef struct keyspan_usa26_globalStatusMessage
 {
 	u8	port,				// 3
 		sendGlobalStatus,	// from request, decremented
 		resetStatusCount;	// as in request
-} globalStatusMessage;
+} keyspan_usa26_globalStatusMessage;
 
-typedef struct globalDebugMessage
+typedef struct keyspan_usa26_globalDebugMessage
 {
 	u8	port,				// 2
 		a,
 		b,
 		c,
 		d;
-} globalDebugMessage;
+} keyspan_usa26_globalDebugMessage;
 
 // ie: the maximum length of an EZUSB endpoint buffer
 #define	MAX_DATA_LEN			64
diff -urN linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa28msg.h linux/drivers/usb/serial/keyspan_usa28msg.h
--- linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa28msg.h	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/serial/keyspan_usa28msg.h	Mon Dec  3 20:57:55 2001
@@ -94,16 +94,8 @@
 #ifndef	__USA28MSG__
 #define	__USA28MSG__
 
-/*#ifndef STUBS
-#include "datadefs.h"
-#endif*/
 
-typedef struct txAckMessage
-{
-	u8	dummy;
-} txAckMessage;
-
-typedef struct portControlMessage
+typedef struct keyspan_usa28_portControlMessage
 {
 	/*
 		there are four types of "commands" sent in the control message:
@@ -153,9 +145,9 @@
 		returnStatus,	// return current status n times (1 or 2)
 		resetDataToggle;// reset data toggle state to DATA0
 	
-} portControlMessage;
+} keyspan_usa28_portControlMessage;
 
-typedef struct portStatusMessage
+typedef struct keyspan_usa28_portStatusMessage
 {
 	u8	port,			// 0=first, 1=second, 2=global (see below)
 		cts,
@@ -171,32 +163,32 @@
 		rxBreak,		// 1=we're in break state
 		rs232invalid,	// 1=no valid signals on rs-232 inputs
 		controlResponse;// 1=a control messages has been processed
-} portStatusMessage;
+} keyspan_usa28_portStatusMessage;
 
 // bit defines in txState
 #define	TX_OFF			0x01	// requested by host txOff command
 #define	TX_XOFF			0x02	// either real, or simulated by host
 
-typedef struct globalControlMessage
+typedef struct keyspan_usa28_globalControlMessage
 {
 	u8	sendGlobalStatus,	// 2=request for two status responses
 		resetStatusToggle,	// 1=reset global status toggle
 		resetStatusCount;	// a cycling value
-} globalControlMessage;
+} keyspan_usa28_globalControlMessage;
 
-typedef struct globalStatusMessage
+typedef struct keyspan_usa28_globalStatusMessage
 {
 	u8	port,				// 3
 		sendGlobalStatus,	// from request, decremented
 		resetStatusCount;	// as in request
-} globalStatusMessage;
+} keyspan_usa28_globalStatusMessage;
 
-typedef struct globalDebugMessage
+typedef struct keyspan_usa28_globalDebugMessage
 {
 	u8	port,				// 2
 		n,					// typically a count/status byte
 		b;					// typically a data byte
-} globalDebugMessage;
+} keyspan_usa28_globalDebugMessage;
 
 // ie: the maximum length of an EZUSB endpoint buffer
 #define	MAX_DATA_LEN			64
diff -urN linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa49msg.h linux/drivers/usb/serial/keyspan_usa49msg.h
--- linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa49msg.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/keyspan_usa49msg.h	Mon Dec  3 20:57:55 2001
@@ -0,0 +1,255 @@
+/*
+	usa49msg.h
+
+	Copyright (c) 1998-2000 InnoSys Incorporated.  All Rights Reserved
+	This file is available under a BSD-style copyright
+
+	Keyspan USB Async Firmware to run on Anchor EZ-USB
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are
+	met:
+
+	1. Redistributions of source code must retain this licence text
+   	without modification, this list of conditions, and the following
+   	disclaimer.  The following copyright notice must appear immediately at
+   	the beginning of all source files:
+
+        	Copyright (c) 1998-2000 InnoSys Incorporated.  All Rights Reserved
+
+        	This file is available under a BSD-style copyright
+
+	2. Redistributions in binary form must reproduce the above copyright
+   	notice, this list of conditions and the following disclaimer in the
+   	documentation and/or other materials provided with the distribution.
+
+	3. The name of InnoSys Incorprated may not be used to endorse or promote
+   	products derived from this software without specific prior written
+   	permission.
+
+	THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+	NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+	INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+	LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+	OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+	SUCH DAMAGE.    
+
+	4th revision: USA49W version
+
+	See usa26msg.h for description of message formats
+
+	Third revision: USA28X version (aka USA26)
+
+	Buffer formats for RX/TX data messages are not defined by
+	a structure, but are described here:
+
+	USB OUT (host -> USA26, transmit) messages contain a 
+	REQUEST_ACK indicator (set to 0xff to request an ACK at the 
+	completion of transmit; 0x00 otherwise), followed by data:
+
+		RQSTACK DAT DAT DAT ...
+
+	with a total data length of 63.
+
+	USB IN (USA26 -> host, receive) messages contain either a zero
+	flag (indicating no error in any data bytes):
+
+		00 DAT DAT DAT ...
+
+	for a total of 63 data bytes, or a non-zero status flag (indicating 
+	that all data bytes will be preceded by status flag):
+
+		STAT DAT STAT DAT STAT DAT ...
+
+	for a total of 32 data bytes.  The valid bits in the STAT bytes are:
+
+		OVERRUN	0x02
+		PARITY	0x04
+		FRAMING	0x08
+		BREAK	0x10
+
+	Notes:
+	
+	1.	a "no status" RX data message (first byte zero) can serve as
+		a "break off" indicator.
+	2.	a control message specifying disablePort will be answered
+		with a status message, but no further status will be sent
+		until a control messages with enablePort is sent
+
+	revision history:
+
+	1999feb10	add reportHskiaChanges to allow us to ignore them
+	1999feb10	add txAckThreshold for fast+loose throughput enhancement
+	1999mar30	beef up support for RX error reporting
+	1999apr14	add resetDataToggle to control message
+	2000jan04	merge with usa17msg.h
+	2000mar08	clone from usa26msg.h -> usa49msg.h
+	2000mar09	change to support 4 ports
+	2000may03	change external clocking to match USA-49W hardware
+	2000jun01	add extended BSD-style copyright text
+*/
+
+#ifndef	__USA49MSG__
+#define	__USA49MSG__
+
+
+/*
+	Host->device messages sent on the global control endpoint:
+
+	portNumber	message
+	----------	--------------------
+	0,1,2,3		portControlMessage
+	0x80		globalControlMessage
+*/
+
+typedef struct keyspan_usa49_portControlMessage
+{
+	/*
+		0.	0/1/2/3 	port control message follows
+			0x80 set	non-port control message follows
+	*/
+	u8	portNumber,
+
+	/*
+		there are three types of "commands" sent in the control message:
+
+		1.	configuration changes which must be requested by setting
+			the corresponding "set" flag (and should only be requested
+			when necessary, to reduce overhead on the USA26):
+	*/
+		setClocking,	// host requests baud rate be set
+		baudLo,			// host does baud divisor calculation
+		baudHi,			// baudHi is only used for first port (gives lower rates)
+		prescaler,		// specified as N/8; values 8-ff are valid
+						// must be set any time internal baud rate is set;
+		txClocking,		// 0=internal, 1=external/DSR
+		rxClocking,		// 0=internal, 1=external/DSR
+
+		setLcr,			// host requests lcr be set
+		lcr,			// use PARITY, STOPBITS, DATABITS below
+
+		setFlowControl,	// host requests flow control be set
+		ctsFlowControl,	// 1=use CTS flow control, 0=don't
+		xonFlowControl,	// 1=use XON/XOFF flow control, 0=don't
+		xonChar,		// specified in current character format
+		xoffChar,		// specified in current character format
+
+		setRts,			// host requests RTS output be set
+		rts,			// 1=active, 0=inactive
+
+		setDtr,			// host requests DTR output be set
+		dtr;			// 1=on, 0=off
+
+
+	/*
+		3.	configuration data which is simply used as is (no overhead,
+			but must be specified correctly in every host message).
+	*/
+	u8	forwardingLength,  // forward when this number of chars available
+		dsrFlowControl,	// 1=use DSR flow control, 0=don't
+		txAckThreshold,	// 0=not allowed, 1=normal, 2-255 deliver ACK faster
+		loopbackMode;	// 0=no loopback, 1=loopback enabled
+
+	/*
+		4.	commands which are flags only; these are processed in order
+			(so that, e.g., if both _txOn and _txOff flags are set, the
+			port ends in a TX_OFF state); any non-zero value is respected
+	*/
+	u8	_txOn,			// enable transmitting (and continue if there's data)
+		_txOff,			// stop transmitting
+		txFlush,		// toss outbound data
+		txBreak,		// turn on break (cleared by _txOn)
+		rxOn,			// turn on receiver
+		rxOff,			// turn off receiver
+		rxFlush,		// toss inbound data
+		rxForward,		// forward all inbound data, NOW (as if fwdLen==1)
+		returnStatus,	// return current status (even if it hasn't changed)
+		resetDataToggle,// reset data toggle state to DATA0
+		enablePort,		// start servicing port (move data, check status)
+		disablePort;	// stop servicing port (does implicit tx/rx flush/off)
+	
+} keyspan_usa49_portControlMessage;
+
+// defines for bits in lcr
+#define	USA_DATABITS_5		0x00
+#define	USA_DATABITS_6		0x01
+#define	USA_DATABITS_7		0x02
+#define	USA_DATABITS_8		0x03
+#define	STOPBITS_5678_1		0x00	// 1 stop bit for all byte sizes
+#define	STOPBITS_5_1p5		0x04	// 1.5 stop bits for 5-bit byte
+#define	STOPBITS_678_2		0x04	// 2 stop bits for 6/7/8-bit byte
+#define	USA_PARITY_NONE		0x00
+#define	USA_PARITY_ODD		0x08
+#define	USA_PARITY_EVEN		0x18
+#define	PARITY_1			0x28
+#define	PARITY_0			0x38
+
+typedef struct keyspan_usa49_globalControlMessage
+{
+	u8	portNumber,			// 0x80
+		sendGlobalStatus,	// 1/2=number of status responses requested
+		resetStatusToggle,	// 1=reset global status toggle
+		resetStatusCount,	// a cycling value
+		remoteWakeupEnable;	// 0x10=P1, 0x20=P2, 0x40=P3, 0x80=P3
+} keyspan_usa49_globalControlMessage;
+
+/*
+	Device->host messages send on the global status endpoint
+
+	portNumber			message
+	----------			--------------------
+	0x00,0x01,0x02,0x03	portStatusMessage
+	0x80				globalStatusMessage
+	0x81				globalDebugMessage
+*/
+
+typedef struct keyspan_usa49_portStatusMessage	// one for each port
+{
+	u8	portNumber,		// 0,1,2,3
+		cts,			// reports CTS pin
+		dcd,			// reports DCD pin
+		dsr,			// reports DSR pin
+		ri,				// reports RI pin
+		_txOff,			// transmit has been disabled (by host)
+		_txXoff,		// transmit is in XOFF state (either host or RX XOFF)
+		rxEnabled,		// as configured by rxOn/rxOff 1=on, 0=off
+		controlResponse,// 1=a control message has been processed
+		txAck,			// ACK (data TX complete)
+		rs232valid;		// RS-232 signal valid
+} keyspan_usa49_portStatusMessage;
+
+// bits in RX data message when STAT byte is included
+#define	RXERROR_OVERRUN	0x02
+#define	RXERROR_PARITY	0x04
+#define	RXERROR_FRAMING	0x08
+#define	RXERROR_BREAK	0x10
+
+typedef struct keyspan_usa49_globalStatusMessage
+{
+	u8	portNumber,			// 0x80=globalStatusMessage
+		sendGlobalStatus,	// from request, decremented
+		resetStatusCount;	// as in request
+} keyspan_usa49_globalStatusMessage;
+
+typedef struct keyspan_usa49_globalDebugMessage
+{
+	u8	portNumber,			// 0x81=globalDebugMessage
+		n,					// typically a count/status byte
+		b;					// typically a data byte
+} keyspan_usa49_globalDebugMessage;
+
+// ie: the maximum length of an EZUSB endpoint buffer
+#define	MAX_DATA_LEN			64
+
+// update status approx. 60 times a second (16.6666 ms)
+#define	STATUS_UPDATE_INTERVAL	16
+
+// status rationing tuning value (each port gets checked each n ms)
+#define	STATUS_RATION	10
+
+#endif
diff -urN linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa49w_fw.h linux/drivers/usb/serial/keyspan_usa49w_fw.h
--- linux-2.2.19-pre6/drivers/usb/serial/keyspan_usa49w_fw.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/keyspan_usa49w_fw.h	Mon Dec  3 20:57:55 2001
@@ -0,0 +1,457 @@
+/* keyspan_usa49w_fw.h
+  
+   Generated from Keyspan firmware image Thu Sep 28 09:13:26 2000 EST
+   This firmware is for the Keyspan USA-49W Serial Adaptor
+
+   "The firmware contained herein as keyspan_usa49w_fw.h is
+   Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated
+   ("Keyspan"), as an unpublished work.  This notice does not imply
+   unrestricted or public access to this firmware which is a trade secret of
+   Keyspan, and which may not be reproduced, used, sold or transferred to any
+   third party without Keyspan's prior written consent.  All Rights Reserved.
+
+   This firmware may not be modified and may only be used with the Keyspan 
+   USA-49W Serial Adapter.  Distribution and/or Modification of the
+   keyspan.c driver which includes this firmware, in whole or in part,
+   requires the inclusion of this statement."
+
+*/
+
+static const struct ezusb_hex_record keyspan_usa49w_firmware[] = {
+{ 0x0000,	3,	{0x02, 0x10, 0x36} },
+{ 0x0003,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
+{ 0x0013,	16,	{0x01, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
+{ 0x0023,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
+{ 0x0033,	3,	{0x02, 0x17, 0xf0} },
+{ 0x0036,	12,	{0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
+{ 0x0043,	3,	{0x02, 0x18, 0x00} },
+{ 0x0046,	16,	{0xe4, 0xff, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x27} },
+{ 0x0056,	16,	{0x24, 0x04, 0xfd, 0xe4, 0x35, 0x26, 0xfa, 0xa9, 0x05, 0x7b, 0x01, 0xef, 0x7c, 0x00, 0x29, 0xf9} },
+{ 0x0066,	16,	{0xec, 0x3a, 0xfa, 0xee, 0x12, 0x11, 0x90, 0x0f, 0xbf, 0x22, 0xd7, 0xe5, 0x27, 0x24, 0x05, 0xf5} },
+{ 0x0076,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x01, 0x4f, 0x7f, 0x01, 0xe5, 0x27} },
+{ 0x0086,	16,	{0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x15, 0x3d, 0xe5, 0x27} },
+{ 0x0096,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0x6c, 0xe5, 0x27} },
+{ 0x00a6,	16,	{0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x00, 0x03, 0xe5, 0x27} },
+{ 0x00b6,	16,	{0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x30, 0xf0, 0x7d, 0x04, 0x44} },
+{ 0x00c6,	16,	{0x20, 0xf0, 0xe5, 0x27, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x12} },
+{ 0x00d6,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xdf, 0xf0, 0x43} },
+{ 0x00e6,	16,	{0x05, 0xc0, 0xe5, 0x27, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x14} },
+{ 0x00f6,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xdf, 0xf0, 0x43} },
+{ 0x0106,	16,	{0x05, 0x0b, 0x80, 0x03, 0x43, 0x05, 0x02, 0x7f, 0x03, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x39} },
+{ 0x0116,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04} },
+{ 0x0126,	16,	{0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00} },
+{ 0x0136,	16,	{0xf0, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0146,	16,	{0xf5, 0x83, 0xe0, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
+{ 0x0156,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x32, 0xe5, 0x27, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0166,	16,	{0xf5, 0x83, 0xe0, 0x54, 0x3f, 0xff, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x0176,	16,	{0x83, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4} },
+{ 0x0186,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x0d, 0xf5, 0x82, 0xe4} },
+{ 0x0196,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x02, 0x6a, 0xe5, 0x27, 0x24, 0x17, 0xf5, 0x82} },
+{ 0x01a6,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x01b6,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4} },
+{ 0x01c6,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfb, 0xf0, 0xe4, 0xff, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82} },
+{ 0x01d6,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x0e, 0xf5, 0x82} },
+{ 0x01e6,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x01f6,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4} },
+{ 0x0206,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x0216,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x27, 0x24, 0x0f, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0226,	16,	{0xf5, 0x83, 0xe0, 0x60, 0x2f, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
+{ 0x0236,	16,	{0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x0246,	16,	{0xff, 0x12, 0x14, 0xdd, 0xe5, 0x27, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x0256,	16,	{0xff, 0x12, 0x15, 0x0d, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x0266,	16,	{0xff, 0x12, 0x14, 0xad, 0xe5, 0x27, 0x24, 0x14, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x0276,	16,	{0x60, 0x44, 0xe5, 0x27, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11} },
+{ 0x0286,	16,	{0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x80} },
+{ 0x0296,	16,	{0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xf0} },
+{ 0x02a6,	16,	{0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x02b6,	16,	{0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x12, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x02c6,	16,	{0x83, 0xe0, 0x60, 0x44, 0xe5, 0x27, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x02d6,	16,	{0x60, 0x11, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x02} },
+{ 0x02e6,	16,	{0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x02f6,	16,	{0xfd, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x0306,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x16, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x0316,	16,	{0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x27, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
+{ 0x0326,	16,	{0xef, 0xf0, 0xe5, 0x27, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe0} },
+{ 0x0336,	16,	{0x11, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x40, 0xf0} },
+{ 0x0346,	16,	{0x80, 0x0f, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xbf} },
+{ 0x0356,	16,	{0xf0, 0xe5, 0x27, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x27} },
+{ 0x0366,	16,	{0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x27, 0x24, 0x19, 0xf5} },
+{ 0x0376,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4} },
+{ 0x0386,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82} },
+{ 0x0396,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5} },
+{ 0x03a6,	16,	{0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5} },
+{ 0x03b6,	16,	{0x27, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x6b, 0xe5, 0x27, 0x24} },
+{ 0x03c6,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
+{ 0x03d6,	16,	{0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f} },
+{ 0x03e6,	16,	{0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0xfe} },
+{ 0x03f6,	16,	{0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x0406,	16,	{0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x2c, 0xf5, 0x82} },
+{ 0x0416,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x27, 0x24, 0x2b, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0426,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x0436,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x0446,	16,	{0x83, 0xe0, 0x60, 0x28, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x0456,	16,	{0x44, 0x02, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x2b, 0xf5, 0x82} },
+{ 0x0466,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x1c} },
+{ 0x0476,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82} },
+{ 0x0486,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x2c, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27} },
+{ 0x0496,	16,	{0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0} },
+{ 0x04a6,	16,	{0xe4, 0xff, 0x12, 0x14, 0x0c, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
+{ 0x04b6,	16,	{0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x04c6,	16,	{0x60, 0x27, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x40} },
+{ 0x04d6,	16,	{0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x04e6,	16,	{0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x1e, 0xf5, 0x82, 0xe4} },
+{ 0x04f6,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0506,	16,	{0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24} },
+{ 0x0516,	16,	{0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5} },
+{ 0x0526,	16,	{0x27, 0x24, 0x1f, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24} },
+{ 0x0536,	16,	{0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x27, 0x24, 0x32, 0xf5} },
+{ 0x0546,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15} },
+{ 0x0556,	16,	{0x3d, 0xe5, 0x27, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28} },
+{ 0x0566,	16,	{0x42, 0x25, 0xe5, 0x27, 0x24, 0x20, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e} },
+{ 0x0576,	16,	{0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x18, 0x90, 0x78} },
+{ 0x0586,	16,	{0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x0596,	16,	{0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x05a6,	16,	{0x83, 0xe0, 0x60, 0x0f, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x05b6,	16,	{0x44, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60} },
+{ 0x05c6,	16,	{0x1f, 0xe5, 0x27, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5} },
+{ 0x05d6,	16,	{0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
+{ 0x05e6,	16,	{0xe5, 0x27, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x12, 0x17} },
+{ 0x05f6,	16,	{0x4e, 0xe5, 0x27, 0x24, 0x24, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x1b, 0xe5} },
+{ 0x0606,	16,	{0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f} },
+{ 0x0616,	16,	{0x98, 0xe0, 0xff, 0xe5, 0x28, 0xf4, 0xfe, 0xef, 0x5e, 0xf0, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82} },
+{ 0x0626,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x16, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x0636,	14,	{0x26, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x28, 0xf0} },
+{ 0x0644,	1,	{0x22} },
+{ 0x0645,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x11, 0xa2, 0x07, 0x42, 0x00, 0x07, 0xb6, 0x01, 0x08, 0x22, 0x03} },
+{ 0x0655,	16,	{0x06, 0x68, 0x06, 0x07, 0x35, 0x08, 0x07, 0x2f, 0x09, 0x07, 0x17, 0x0a, 0x07, 0x26, 0x0b, 0x00} },
+{ 0x0665,	16,	{0x00, 0x08, 0x71, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x77, 0x24, 0x02} },
+{ 0x0675,	16,	{0x60, 0x03, 0x02, 0x07, 0x0d, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} },
+{ 0x0685,	16,	{0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0} },
+{ 0x0695,	16,	{0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe0, 0x04, 0x7f, 0x03, 0x80, 0x02, 0x7f, 0x02, 0x75, 0x82, 0x82} },
+{ 0x06a5,	16,	{0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x6d, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75} },
+{ 0x06b5,	16,	{0x83, 0x19, 0xf0, 0x75, 0x82, 0x5f, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19} },
+{ 0x06c5,	16,	{0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe1, 0x04, 0x7f, 0x64, 0x80, 0x02, 0x7f, 0x32, 0x75, 0x82} },
+{ 0x06d5,	16,	{0x1a, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f} },
+{ 0x06e5,	16,	{0xd5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x13, 0x54, 0xea, 0x49, 0x60} },
+{ 0x06f5,	16,	{0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f} },
+{ 0x0705,	16,	{0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02} },
+{ 0x0715,	16,	{0x08, 0x78, 0x90, 0x7f, 0x00, 0xe5, 0x0a, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08} },
+{ 0x0725,	16,	{0x78, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x0a, 0x02, 0x08, 0x78, 0x12, 0x0a, 0x6a, 0x02, 0x08, 0x78} },
+{ 0x0735,	16,	{0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xe8} },
+{ 0x0745,	16,	{0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33} },
+{ 0x0755,	16,	{0xff, 0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0} },
+{ 0x0765,	16,	{0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0} },
+{ 0x0775,	16,	{0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80} },
+{ 0x0785,	16,	{0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4} },
+{ 0x0795,	16,	{0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f} },
+{ 0x07a5,	16,	{0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08} },
+{ 0x07b5,	16,	{0x78, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x08, 0x78} },
+{ 0x07c5,	16,	{0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0} },
+{ 0x07d5,	16,	{0x44, 0x01, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0} },
+{ 0x07e5,	16,	{0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} },
+{ 0x07f5,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff} },
+{ 0x0805,	16,	{0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44} },
+{ 0x0815,	16,	{0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8} },
+{ 0x0825,	16,	{0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04} },
+{ 0x0835,	16,	{0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea} },
+{ 0x0845,	16,	{0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0} },
+{ 0x0855,	16,	{0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01} },
+{ 0x0865,	16,	{0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0} },
+{ 0x0875,	10,	{0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
+{ 0x087f,	1,	{0x22} },
+{ 0x0880,	16,	{0xe5, 0x23, 0x54, 0x0f, 0x70, 0x03, 0x02, 0x09, 0x5f, 0x12, 0x15, 0x9b, 0xef, 0x20, 0xe1, 0x63} },
+{ 0x0890,	16,	{0x12, 0x15, 0xf9, 0xef, 0x14, 0xf5, 0x1a, 0x12, 0x17, 0xc1, 0xef, 0x25, 0x1a, 0xff, 0xe4, 0x33} },
+{ 0x08a0,	16,	{0xfe, 0xc3, 0xef, 0x94, 0x80, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x47, 0x85, 0x27, 0x82, 0x85} },
+{ 0x08b0,	16,	{0x26, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5} },
+{ 0x08c0,	16,	{0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f} },
+{ 0x08d0,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0x85} },
+{ 0x08e0,	16,	{0x1a, 0x08, 0xef, 0x24, 0x01, 0xf5, 0x10, 0xe4, 0x3e, 0xf5, 0x0f, 0x12, 0x13, 0xd6, 0xe4, 0xff} },
+{ 0x08f0,	16,	{0x12, 0x14, 0x0c, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30} },
+{ 0x0900,	16,	{0xe7, 0x5d, 0x12, 0x17, 0xc1, 0xe5, 0x27, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
+{ 0x0910,	16,	{0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x48, 0xe5, 0x27, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0920,	16,	{0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
+{ 0x0930,	16,	{0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4} },
+{ 0x0940,	16,	{0xf0, 0xe5, 0x28, 0x42, 0x25, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x10, 0xe5, 0x27, 0x24, 0x26} },
+{ 0x0950,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xf5, 0x09, 0x80, 0x03, 0x12, 0x12, 0x3d, 0x12} },
+{ 0x0960,	16,	{0x15, 0xca, 0xef, 0x30, 0xe1, 0x03, 0x02, 0x0a, 0x69, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4} },
+{ 0x0970,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x80, 0xf0, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x0980,	16,	{0x26, 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x17, 0xcd, 0xee, 0x4f, 0xd0, 0x82} },
+{ 0x0990,	16,	{0xd0, 0x83, 0xf0, 0x12, 0x16, 0xd1, 0x8f, 0x1a, 0xe5, 0x27, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x09a0,	16,	{0x26, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x28, 0x12, 0x17, 0xa9, 0xef, 0x30, 0xe0} },
+{ 0x09b0,	16,	{0x21, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x20, 0xe7, 0x12} },
+{ 0x09c0,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x03, 0x02} },
+{ 0x09d0,	16,	{0x0a, 0x69, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfd} },
+{ 0x09e0,	16,	{0xf0, 0xe5, 0x1a, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
+{ 0x09f0,	16,	{0xe4, 0xf0, 0x22, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff} },
+{ 0x0a00,	16,	{0x30, 0xe7, 0x29, 0xe5, 0x1a, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x1a, 0x20, 0x85, 0x1a, 0x08} },
+{ 0x0a10,	16,	{0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0x8c, 0x0f, 0xf5, 0x10} },
+{ 0x0a20,	16,	{0x12, 0x13, 0x06, 0xe5, 0x1a, 0x25, 0xe0, 0xff, 0x12, 0x14, 0x42, 0x22, 0xe5, 0x1a, 0xd3, 0x94} },
+{ 0x0a30,	16,	{0x3f, 0x40, 0x03, 0x75, 0x1a, 0x3f, 0x85, 0x1a, 0x08, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3} },
+{ 0x0a40,	16,	{0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x85, 0x27, 0x82, 0x85, 0x26} },
+{ 0x0a50,	16,	{0x83, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x24, 0x01, 0xf5, 0x10, 0xe4, 0x3e, 0xf5, 0x0f, 0x12} },
+{ 0x0a60,	9,	{0x13, 0x95, 0xe5, 0x1a, 0x04, 0xff, 0x12, 0x14, 0x42} },
+{ 0x0a69,	1,	{0x22} },
+{ 0x0a6a,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4} },
+{ 0x0a7a,	16,	{0x90, 0x7f, 0x94, 0xf0, 0x90, 0x78, 0x4a, 0x04, 0xf0, 0xf5, 0x8e, 0x90, 0x7f, 0x95, 0x74, 0xc0} },
+{ 0x0a8a,	16,	{0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x1f, 0xf0, 0x90, 0x78, 0x43} },
+{ 0x0a9a,	16,	{0x74, 0xff, 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x9f, 0xf0, 0x90, 0x7f} },
+{ 0x0aaa,	16,	{0xde, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b} },
+{ 0x0aba,	16,	{0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x0e, 0xb3, 0x7e} },
+{ 0x0aca,	16,	{0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75} },
+{ 0x0ada,	16,	{0x28, 0x01, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0x7e} },
+{ 0x0aea,	16,	{0x7e, 0x7f, 0x40, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x40, 0xf0} },
+{ 0x0afa,	16,	{0x7e, 0x7e, 0x7f, 0x80, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3} },
+{ 0x0b0a,	16,	{0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x00, 0x90, 0x7f, 0x96} },
+{ 0x0b1a,	16,	{0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x0e, 0xb3, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c} },
+{ 0x0b2a,	16,	{0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0xe5, 0x27, 0x24, 0x26} },
+{ 0x0b3a,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x7e, 0x7d, 0x7f, 0xc0, 0x85, 0x27} },
+{ 0x0b4a,	16,	{0x82, 0x85, 0x26, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0xc0, 0xf0, 0x7e, 0x7e, 0x7f, 0x00, 0x85} },
+{ 0x0b5a,	16,	{0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0x7e, 0x7c} },
+{ 0x0b6a,	16,	{0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28} },
+{ 0x0b7a,	16,	{0x04, 0x12, 0x0e, 0xb3, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f} },
+{ 0x0b8a,	16,	{0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0b9a,	16,	{0xf5, 0x83, 0x74, 0x02, 0xf0, 0x7e, 0x7d, 0x7f, 0x40, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74} },
+{ 0x0baa,	16,	{0x7d, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7d, 0x7f, 0x80, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83} },
+{ 0x0bba,	16,	{0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c} },
+{ 0x0bca,	16,	{0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x0e, 0xb3, 0x7e} },
+{ 0x0bda,	16,	{0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75} },
+{ 0x0bea,	16,	{0x28, 0x08, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x03, 0xf0} },
+{ 0x0bfa,	16,	{0x7e, 0x7c, 0x7f, 0xc0, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74, 0x7c, 0xf0, 0xa3, 0x74, 0xc0} },
+{ 0x0c0a,	16,	{0xf0, 0x7e, 0x7d, 0x7f, 0x00, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0} },
+{ 0x0c1a,	7,	{0xa3, 0x74, 0x00, 0xf0, 0xd2, 0x02, 0x22} },
+{ 0x0c21,	16,	{0xe5, 0x22, 0x04, 0x54, 0x03, 0xf5, 0x22, 0x14, 0x60, 0x1f, 0x14, 0x60, 0x31, 0x14, 0x60, 0x43} },
+{ 0x0c31,	16,	{0x24, 0x03, 0x70, 0x52, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f} },
+{ 0x0c41,	16,	{0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x80, 0x3d, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c} },
+{ 0x0c51,	16,	{0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x80, 0x28, 0x7e, 0x7c} },
+{ 0x0c61,	16,	{0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28} },
+{ 0x0c71,	16,	{0x04, 0x80, 0x13, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96} },
+{ 0x0c81,	16,	{0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0xe5, 0x15, 0x55, 0x28, 0x70, 0x03, 0x02, 0x0d, 0xbf, 0xe5} },
+{ 0x0c91,	16,	{0x28, 0xf4, 0xff, 0x52, 0x15, 0xe5, 0x0b, 0x54, 0x7f, 0xfe, 0x70, 0x0f, 0xe5, 0x0d, 0x55, 0x28} },
+{ 0x0ca1,	16,	{0x60, 0x24, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x28, 0xf0, 0x80, 0x1b, 0xbe, 0x20, 0x18, 0xe5, 0x27} },
+{ 0x0cb1,	16,	{0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe3, 0x09, 0xe4, 0xf5, 0x0d} },
+{ 0x0cc1,	16,	{0x90, 0x7f, 0x98, 0xe0, 0x5f, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x0cd1,	16,	{0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe5, 0x27, 0x24, 0x34, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0ce1,	16,	{0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe0, 0x60, 0x03, 0x02, 0x0d, 0xbf, 0x74, 0x0a} },
+{ 0x0cf1,	16,	{0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0x01, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x2c, 0xf5, 0x82} },
+{ 0x0d01,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x1a, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
+{ 0x0d11,	16,	{0x12, 0x17, 0xd9, 0x8f, 0x1a, 0xe5, 0x27, 0x24, 0x27, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
+{ 0x0d21,	16,	{0xe0, 0xff, 0xe5, 0x1a, 0x54, 0x10, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
+{ 0x0d31,	16,	{0xe5, 0x27, 0x24, 0x28, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1a, 0x54} },
+{ 0x0d41,	16,	{0x80, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x29, 0xf5} },
+{ 0x0d51,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1a, 0x54, 0x20, 0xfe, 0x6f, 0x60, 0x15} },
+{ 0x0d61,	16,	{0xee, 0xf0, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe4} },
+{ 0x0d71,	16,	{0x04, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x24, 0x55, 0x28, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x2a} },
+{ 0x0d81,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x16, 0xe5, 0x1a, 0xf0, 0xe5, 0x27} },
+{ 0x0d91,	16,	{0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe5, 0x04, 0xe5, 0x28, 0x42} },
+{ 0x0da1,	16,	{0x25, 0xe5, 0x29, 0x55, 0x28, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x0db1,	14,	{0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x1a, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
+{ 0x0dbf,	1,	{0x22} },
+{ 0x0dc0,	16,	{0xe5, 0x09, 0x14, 0x60, 0x2a, 0x14, 0x60, 0x41, 0x14, 0x60, 0x58, 0x14, 0x60, 0x6f, 0x24, 0x04} },
+{ 0x0dd0,	16,	{0x60, 0x03, 0x02, 0x0e, 0x77, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90} },
+{ 0x0de0,	16,	{0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x01, 0x22, 0x7e} },
+{ 0x0df0,	16,	{0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75} },
+{ 0x0e00,	16,	{0x28, 0x02, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x02, 0x22, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c} },
+{ 0x0e10,	16,	{0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0x12, 0x12, 0x3d, 0x75} },
+{ 0x0e20,	16,	{0x09, 0x03, 0x22, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96} },
+{ 0x0e30,	16,	{0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x04, 0x22, 0x30, 0x04, 0x33} },
+{ 0x0e40,	16,	{0xc2, 0x04, 0x53, 0x25, 0xdf, 0xe4, 0xf5, 0x1a, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x11, 0x25, 0x1a} },
+{ 0x0e50,	16,	{0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0x4a, 0xff, 0x74, 0x80, 0x25, 0x1a, 0xf5, 0x82, 0xe4} },
+{ 0x0e60,	16,	{0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1a, 0xe5, 0x1a, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3} },
+{ 0x0e70,	16,	{0x74, 0x03, 0xf0, 0x75, 0x09, 0x05, 0x22, 0xe5, 0x17, 0x60, 0x34, 0xd5, 0x17, 0x03, 0x53, 0x25} },
+{ 0x0e80,	16,	{0xef, 0xe4, 0xf5, 0x1a, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x16, 0x25, 0x1a, 0xf9, 0xee, 0x34, 0x00} },
+{ 0x0e90,	16,	{0xfa, 0x12, 0x11, 0x4a, 0xff, 0x74, 0x80, 0x25, 0x1a, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83} },
+{ 0x0ea0,	16,	{0xef, 0xf0, 0x05, 0x1a, 0xe5, 0x1a, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4} },
+{ 0x0eb0,	2,	{0xf5, 0x09} },
+{ 0x0eb2,	1,	{0x22} },
+{ 0x0eb3,	16,	{0xe4, 0xf5, 0x19, 0x7e, 0x00, 0x7b, 0x01, 0xe5, 0x27, 0x25, 0x19, 0xf9, 0xee, 0x35, 0x26, 0xfa} },
+{ 0x0ec3,	16,	{0xe4, 0x12, 0x11, 0x90, 0x05, 0x19, 0xe5, 0x19, 0xb4, 0x3c, 0xe8, 0xe5, 0x27, 0x24, 0x35, 0xf5} },
+{ 0x0ed3,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5} },
+{ 0x0ee3,	16,	{0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00} },
+{ 0x0ef3,	16,	{0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x15, 0x3d, 0x7f, 0x10, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82} },
+{ 0x0f03,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0x12, 0x14, 0xad, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0} },
+{ 0x0f13,	16,	{0x7f, 0x01, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0x44} },
+{ 0x0f23,	16,	{0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5} },
+{ 0x0f33,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, 0xfd} },
+{ 0x0f43,	16,	{0x12, 0x15, 0x3d, 0xe4, 0xff, 0x7e, 0xa3, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
+{ 0x0f53,	16,	{0xf5, 0x83, 0xee, 0xf0, 0xfd, 0x12, 0x15, 0x3d, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0} },
+{ 0x0f63,	16,	{0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x15, 0x3d, 0x7f, 0x01, 0x12, 0x14, 0x78, 0x7f} },
+{ 0x0f73,	6,	{0x03, 0x7d, 0x07, 0x12, 0x15, 0x3d} },
+{ 0x0f79,	1,	{0x22} },
+{ 0x0f7a,	16,	{0x53, 0x25, 0x3f, 0x90, 0x7b, 0xf1, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26} },
+{ 0x0f8a,	16,	{0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x08, 0x80} },
+{ 0x0f9a,	16,	{0x90, 0x7c, 0x31, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27} },
+{ 0x0faa,	16,	{0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x08, 0x80, 0x90, 0x7c, 0x71} },
+{ 0x0fba,	16,	{0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f} },
+{ 0x0fca,	16,	{0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0x12, 0x08, 0x80, 0x90, 0x7c, 0xb1, 0xe0, 0x30, 0xe3} },
+{ 0x0fda,	16,	{0x16, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f} },
+{ 0x0fea,	16,	{0xf0, 0x75, 0x28, 0x08, 0x12, 0x08, 0x80, 0x05, 0x23, 0xe5, 0x23, 0x54, 0x0f, 0xf5, 0x19, 0x70} },
+{ 0x0ffa,	16,	{0x1f, 0x90, 0x78, 0x41, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf5, 0x29, 0x90, 0x78} },
+{ 0x100a,	16,	{0x41, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf4, 0xf5, 0x24, 0x12, 0x10, 0xc2, 0x22} },
+{ 0x101a,	16,	{0xe5, 0x19, 0xb4, 0x01, 0x04, 0x12, 0x0c, 0x21, 0x22, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x08} },
+{ 0x102a,	11,	{0xe5, 0x25, 0x60, 0x04, 0x12, 0x0d, 0xc0, 0x22, 0x12, 0x0c, 0x21} },
+{ 0x1035,	1,	{0x22} },
+{ 0x1036,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x29, 0x02, 0x10, 0x7d} },
+{ 0x1042,	16,	{0x02, 0x11, 0xc8, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
+{ 0x1052,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
+{ 0x1062,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
+{ 0x1072,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x17, 0x67, 0xe4, 0x7e} },
+{ 0x1082,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
+{ 0x1092,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
+{ 0x10a2,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
+{ 0x10b2,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
+{ 0x10c2,	16,	{0x90, 0x7f, 0xd2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0x49, 0x90, 0x7b, 0x40, 0xe0, 0x14, 0x60} },
+{ 0x10d2,	16,	{0x26, 0x14, 0x60, 0x3b, 0x14, 0x60, 0x50, 0x24, 0x83, 0x60, 0x64, 0x24, 0x80, 0x70, 0x63, 0x7e} },
+{ 0x10e2,	16,	{0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75} },
+{ 0x10f2,	16,	{0x28, 0x01, 0x12, 0x00, 0x46, 0x80, 0x4b, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27} },
+{ 0x1102,	16,	{0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x00, 0x46, 0x80, 0x33, 0x7e} },
+{ 0x1112,	16,	{0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75} },
+{ 0x1122,	16,	{0x28, 0x04, 0x12, 0x00, 0x46, 0x80, 0x1b, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27} },
+{ 0x1132,	16,	{0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x00, 0x46, 0x80, 0x03, 0x12} },
+{ 0x1142,	8,	{0x16, 0x56, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x22} },
+{ 0x114a,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
+{ 0x115a,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
+{ 0x1163,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
+{ 0x1173,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
+{ 0x1183,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
+{ 0x1190,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} },
+{ 0x11a0,	2,	{0xf3, 0x22} },
+{ 0x11a2,	16,	{0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} },
+{ 0x11b2,	16,	{0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} },
+{ 0x11c2,	6,	{0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} },
+{ 0x11c8,	16,	{0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x00, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8} },
+{ 0x11d8,	16,	{0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab} },
+{ 0x11e8,	16,	{0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x11f8,	16,	{0xaf, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x09, 0x12, 0x17} },
+{ 0x1208,	16,	{0x13, 0xc2, 0x01, 0xe4, 0xf5, 0x0e, 0xf5, 0x14, 0xc2, 0x07, 0xc2, 0x02, 0x90, 0x7f, 0xd8, 0xe0} },
+{ 0x1218,	16,	{0x65, 0x0b, 0x60, 0x06, 0x75, 0x15, 0x0f, 0xe0, 0xf5, 0x0b, 0x30, 0x02, 0x03, 0x12, 0x0f, 0x7a} },
+{ 0x1228,	16,	{0x30, 0x01, 0x07, 0xc2, 0x01, 0x12, 0x06, 0x45, 0x80, 0xe2, 0x30, 0x08, 0xdf, 0xc2, 0x08, 0x12} },
+{ 0x1238,	5,	{0x17, 0x95, 0x80, 0xd8, 0x22} },
+{ 0x123d,	16,	{0xe5, 0x25, 0x55, 0x28, 0x60, 0x6a, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x124d,	16,	{0x83, 0xe0, 0x70, 0x5c, 0xe5, 0x28, 0xf4, 0x52, 0x25, 0xe5, 0x27, 0x24, 0x26, 0xff, 0xe4, 0x35} },
+{ 0x125d,	16,	{0x26, 0xfe, 0xe4, 0xfd, 0x0f, 0xef, 0xaa, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8a, 0x83} },
+{ 0x126d,	16,	{0xe0, 0xfc, 0x74, 0x80, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0xbd} },
+{ 0x127d,	16,	{0x0b, 0xe2, 0x90, 0x7f, 0xc3, 0x74, 0x0b, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x128d,	16,	{0x26, 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xe5, 0x27, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x129d,	16,	{0x83, 0xe4, 0xf0, 0xe5, 0x27, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0} },
+{ 0x12ad,	1,	{0x22} },
+{ 0x12ae,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4} },
+{ 0x12be,	16,	{0x90, 0x78, 0x4a, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90} },
+{ 0x12ce,	16,	{0x7f, 0x97, 0xf0, 0xe5, 0x0c, 0x54, 0xf0, 0x44, 0x08, 0x90, 0x78, 0x41, 0xf0, 0xe4, 0x90, 0x7f} },
+{ 0x12de,	16,	{0x98, 0xf0, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98} },
+{ 0x12ee,	16,	{0xf0, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
+{ 0x12fe,	8,	{0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x22} },
+{ 0x1306,	16,	{0x8f, 0x1b, 0x05, 0x10, 0xe5, 0x10, 0xae, 0x0f, 0x70, 0x02, 0x05, 0x0f, 0x14, 0xf5, 0x82, 0x8e} },
+{ 0x1316,	16,	{0x83, 0xe5, 0x1b, 0xf0, 0x12, 0x17, 0xe5, 0x05, 0x10, 0xe5, 0x10, 0xac, 0x0f, 0x70, 0x02, 0x05} },
+{ 0x1326,	16,	{0x0f, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x1f, 0xe5, 0x27} },
+{ 0x1336,	16,	{0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12} },
+{ 0x1346,	14,	{0x17, 0xcd, 0x8f, 0x1b, 0xee, 0x4f, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x80, 0xb5, 0x22} },
+{ 0x1354,	2,	{0x8f, 0x19} },
+{ 0x1356,	16,	{0xe4, 0xf5, 0x1a, 0x75, 0x1b, 0xff, 0x75, 0x1c, 0x19, 0x75, 0x1d, 0x86, 0xab, 0x1b, 0xaa, 0x1c} },
+{ 0x1366,	16,	{0xa9, 0x1d, 0x90, 0x00, 0x01, 0x12, 0x11, 0x63, 0xb4, 0x03, 0x1d, 0xaf, 0x1a, 0x05, 0x1a, 0xef} },
+{ 0x1376,	16,	{0xb5, 0x19, 0x01, 0x22, 0x12, 0x11, 0x4a, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
+{ 0x1386,	14,	{0x1b, 0xff, 0xf5, 0x1c, 0x89, 0x1d, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x1394,	1,	{0x22} },
+{ 0x1395,	16,	{0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x78, 0x4f, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x50, 0xf0} },
+{ 0x13a5,	16,	{0xe5, 0x0f, 0x90, 0x78, 0x51, 0xf0, 0xae, 0x0f, 0xe5, 0x10, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78} },
+{ 0x13b5,	16,	{0x54, 0xe5, 0x08, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x10} },
+{ 0x13c5,	16,	{0xf0, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa} },
+{ 0x13d5,	1,	{0x22} },
+{ 0x13d6,	16,	{0xe4, 0x90, 0x78, 0x41, 0xf0, 0xe5, 0x0f, 0x90, 0x78, 0x4f, 0xf0, 0xae, 0x0f, 0xe5, 0x10, 0x90} },
+{ 0x13e6,	16,	{0x78, 0x50, 0xf0, 0x90, 0x78, 0x51, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78} },
+{ 0x13f6,	16,	{0x54, 0xe5, 0x08, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90} },
+{ 0x1406,	6,	{0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22} },
+{ 0x140c,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14} },
+{ 0x141c,	16,	{0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f} },
+{ 0x142c,	16,	{0xc9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xcb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xcd, 0xef} },
+{ 0x143c,	6,	{0xf0, 0xe5, 0x28, 0x42, 0x0d, 0x22} },
+{ 0x1442,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14} },
+{ 0x1452,	16,	{0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xb7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f} },
+{ 0x1462,	16,	{0xb9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xbb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xbd, 0xef} },
+{ 0x1472,	6,	{0xf0, 0xe5, 0x28, 0x42, 0x0d, 0x22} },
+{ 0x1478,	16,	{0xae, 0x07, 0xe4, 0xff, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
+{ 0x1488,	16,	{0x54, 0x7f, 0xfd, 0x12, 0x15, 0x3d, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xee} },
+{ 0x1498,	16,	{0xf0, 0xe4, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80} },
+{ 0x14a8,	5,	{0xfd, 0x12, 0x15, 0x3d, 0x22} },
+{ 0x14ad,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
+{ 0x14bd,	16,	{0x02, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
+{ 0x14cd,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
+{ 0x14dd,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
+{ 0x14ed,	16,	{0x04, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
+{ 0x14fd,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
+{ 0x150d,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
+{ 0x151d,	16,	{0x06, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
+{ 0x152d,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
+{ 0x153d,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
+{ 0x154d,	16,	{0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x07, 0xf0, 0x90, 0xc0} },
+{ 0x155d,	15,	{0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22} },
+{ 0x156c,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0xe4, 0x90, 0x78, 0x41} },
+{ 0x157c,	16,	{0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37} },
+{ 0x158c,	15,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
+{ 0x159b,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} },
+{ 0x15ab,	16,	{0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc8} },
+{ 0x15bb,	15,	{0xe0, 0xff, 0x22, 0x90, 0x7f, 0xca, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcc, 0xe0, 0xff, 0x22} },
+{ 0x15ca,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} },
+{ 0x15da,	16,	{0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xb6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xb8} },
+{ 0x15ea,	15,	{0xe0, 0xff, 0x22, 0x90, 0x7f, 0xba, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xbc, 0xe0, 0xff, 0x22} },
+{ 0x15f9,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} },
+{ 0x1609,	16,	{0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc9} },
+{ 0x1619,	15,	{0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcb, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcd, 0xe0, 0xff, 0x22} },
+{ 0x1628,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} },
+{ 0x1638,	16,	{0x05, 0x04, 0xc2, 0x05, 0x80, 0x02, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} },
+{ 0x1648,	14,	{0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x1656,	16,	{0x90, 0x7b, 0x41, 0xe0, 0xf5, 0x17, 0x43, 0x25, 0x10, 0xa3, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7} },
+{ 0x1666,	16,	{0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0x90, 0x7b, 0x43, 0xe0, 0xf5, 0x18, 0x30, 0x00, 0x07, 0xa3} },
+{ 0x1676,	10,	{0xe0, 0x54, 0xf0, 0xf5, 0x0c, 0x22, 0xe4, 0xf5, 0x0c, 0x22} },
+{ 0x1680,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} },
+{ 0x1690,	16,	{0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} },
+{ 0x16a0,	10,	{0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x16aa,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} },
+{ 0x16ba,	16,	{0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} },
+{ 0x16ca,	7,	{0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x16d1,	16,	{0x12, 0x17, 0xb5, 0xae, 0x07, 0x12, 0x17, 0xb5, 0xad, 0x07, 0xee, 0x6d, 0x60, 0x10, 0x12, 0x17} },
+{ 0x16e1,	16,	{0xb5, 0xae, 0x07, 0xee, 0x6d, 0x60, 0x07, 0x12, 0x17, 0xb5, 0xad, 0x07, 0x80, 0xec, 0xaf, 0x06} },
+{ 0x16f1,	1,	{0x22} },
+{ 0x16f2,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
+{ 0x1702,	1,	{0x22} },
+{ 0x1703,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
+{ 0x1713,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x04, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x09, 0x04, 0xe0, 0x44} },
+{ 0x1723,	16,	{0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x17, 0x34, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
+{ 0x1733,	1,	{0x22} },
+{ 0x1734,	16,	{0x8e, 0x19, 0x8f, 0x1a, 0xe5, 0x1a, 0x15, 0x1a, 0xae, 0x19, 0x70, 0x02, 0x15, 0x19, 0x4e, 0x60} },
+{ 0x1744,	10,	{0x08, 0x12, 0x16, 0xf2, 0x12, 0x16, 0xf2, 0x80, 0xeb, 0x22} },
+{ 0x174e,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x04, 0xff, 0x44, 0x10} },
+{ 0x175e,	9,	{0x90, 0x7f, 0xd7, 0xf0, 0xef, 0x44, 0x30, 0xf0, 0x22} },
+{ 0x1767,	16,	{0x03, 0x16, 0x80, 0x00, 0x00, 0x03, 0x11, 0x81, 0x00, 0x00, 0xc1, 0x85, 0xc1, 0x81, 0xc1, 0x08} },
+{ 0x1777,	7,	{0xc1, 0x00, 0xc1, 0x86, 0x01, 0x09, 0x00} },
+{ 0x177e,	1,	{0x00} },
+{ 0x177f,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x17, 0x34, 0x90, 0x7f} },
+{ 0x178f,	6,	{0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22} },
+{ 0x1795,	16,	{0x12, 0x12, 0xae, 0x12, 0x17, 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x03, 0x12, 0x17, 0x7f} },
+{ 0x17a5,	4,	{0x12, 0x0a, 0x6a, 0x22} },
+{ 0x17a9,	12,	{0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
+{ 0x17b5,	12,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
+{ 0x17c1,	12,	{0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
+{ 0x17cd,	12,	{0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
+{ 0x17d9,	12,	{0x90, 0x78, 0x41, 0x74, 0x06, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
+{ 0x17e5,	11,	{0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
+{ 0x17f0,	4,	{0x53, 0xd8, 0xef, 0x32} },
+{ 0x1800,	15,	{0x02, 0x16, 0xaa, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, 0x16, 0x80, 0x00, 0x02, 0x16, 0x28} },
+{ 0x1900,	16,	{0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x0a, 0x01, 0x00, 0x00, 0x01, 0x02} },
+{ 0x1910,	16,	{0x00, 0x04, 0x09, 0x02, 0x74, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e} },
+{ 0x1920,	16,	{0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} },
+{ 0x1930,	16,	{0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00} },
+{ 0x1940,	16,	{0x07, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} },
+{ 0x1950,	16,	{0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02} },
+{ 0x1960,	16,	{0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00} },
+{ 0x1970,	16,	{0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07} },
+{ 0x1980,	16,	{0x05, 0x87, 0x02, 0x40, 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00} },
+{ 0x1990,	16,	{0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00} },
+{ 0x19a0,	16,	{0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00} },
+{ 0x19b0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00} },
+{ 0x19c0,	16,	{0x6f, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} },
+{ 0x19d0,	16,	{0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00} },
+{ 0x19e0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00} },
+{ 0x19f0,	16,	{0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00} },
+{ 0x1a00,	10,	{0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00} },
+{ 0xffff,	0,	{0x00} }
+};
diff -urN linux-2.2.19-pre6/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h
--- linux-2.2.19-pre6/drivers/usb/serial/usb-serial.h	Sun Dec 10 16:49:43 2000
+++ linux/drivers/usb/serial/usb-serial.h	Mon Dec  3 20:57:55 2001
@@ -11,6 +11,11 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (10/05/2000) gkh
+ *	Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help
+ *	fix bug with urb->dev not being set properly, now that the usb core
+ *	needs it.
+ * 
  * (09/11/2000) gkh
  *	Added usb_serial_debug_data function to help get rid of #DEBUG in the
  *	drivers.
@@ -57,9 +62,11 @@
 
 	unsigned char *		interrupt_in_buffer;
 	struct urb *		interrupt_in_urb;
+	__u8			interrupt_in_endpointAddress;
 
 	unsigned char *		bulk_in_buffer;
 	struct urb *		read_urb;
+	__u8			bulk_in_endpointAddress;
 
 	unsigned char *		bulk_out_buffer;
 	int			bulk_out_size;
@@ -118,7 +125,9 @@
 	struct list_head	driver_list;
 	
 	/* function call to make before accepting driver */
-	int (*startup) (struct usb_serial *serial);	/* return 0 to continue initialization, anything else to abort */
+	/* return 0 to continue initialization, anything else to abort */
+	int (*startup) (struct usb_serial *serial);
+	
 	void (*shutdown) (struct usb_serial *serial);
 
 	/* serial function calls */
diff -urN linux-2.2.19-pre6/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- linux-2.2.19-pre6/drivers/usb/serial/usbserial.c	Mon Dec  3 20:57:38 2001
+++ linux/drivers/usb/serial/usbserial.c	Mon Dec  3 20:57:55 2001
@@ -15,6 +15,13 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (12/29/2000) gkh
+ *	Small NULL pointer initialization cleanup which saves a bit of disk image
+ *
+ * (10/05/2000) gkh
+ *	Fixed bug with urb->dev not being set properly, now that the usb
+ *	core needs it.
+ * 
  * (09/11/2000) gkh
  *	Removed DEBUG #ifdefs with call to usb_serial_debug_data
  *
@@ -327,7 +334,7 @@
 static struct tty_struct *	serial_tty[SERIAL_TTY_MINORS];
 static struct termios *		serial_termios[SERIAL_TTY_MINORS];
 static struct termios *		serial_termios_locked[SERIAL_TTY_MINORS];
-static struct usb_serial	*serial_table[SERIAL_TTY_MINORS] = {NULL, };
+static struct usb_serial	*serial_table[SERIAL_TTY_MINORS];	/* initially all NULL */
 
 LIST_HEAD(usb_serial_driver_list);
 
@@ -694,6 +701,7 @@
 {
 	struct usb_serial *serial = port->serial;
 	unsigned long flags;
+	int result;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
@@ -710,9 +718,17 @@
 
 		/* if we have a bulk interrupt, start reading from it */
 		if (serial->num_bulk_in) {
-			/*Start reading from the device*/
-			if (usb_submit_urb(port->read_urb))
-				dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed");
+			/* Start reading from the device */
+			FILL_BULK_URB(port->read_urb, serial->dev, 
+				      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+				      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
+				      ((serial->type->read_bulk_callback) ?
+				       serial->type->read_bulk_callback :
+				       generic_read_bulk_callback), 
+				      port);
+			result = usb_submit_urb(port->read_urb);
+			if (result)
+				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 		}
 	}
 	
@@ -752,6 +768,7 @@
 {
 	struct usb_serial *serial = port->serial;
 	unsigned long flags;
+	int result;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
@@ -779,11 +796,19 @@
 			memcpy (port->write_urb->transfer_buffer, buf, count);
 		}  
 
-		/* send the data out the bulk port */
-		port->write_urb->transfer_buffer_length = count;
+		/* set up our urb */
+		FILL_BULK_URB(port->write_urb, serial->dev, 
+			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
+			      port->write_urb->transfer_buffer, count,
+			      ((serial->type->write_bulk_callback) ? 
+			       serial->type->write_bulk_callback : 
+			       generic_write_bulk_callback), 
+			      port);
 
-		if (usb_submit_urb(port->write_urb)) {
-			dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed");
+		/* send the data out the bulk port */
+		result = usb_submit_urb(port->write_urb);
+		if (result) {
+			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 			spin_unlock_irqrestore (&port->port_lock, flags);
 			return 0;
 		}
@@ -836,6 +861,7 @@
 	struct tty_struct *tty;
 	unsigned char *data = urb->transfer_buffer;
 	int i;
+	int result;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
@@ -860,10 +886,16 @@
 	}
 
 	/* Continue trying to always read  */
-	if (usb_submit_urb(urb))
-		dbg(__FUNCTION__ " - failed resubmitting read urb");
-
-	return;
+	FILL_BULK_URB(port->read_urb, serial->dev, 
+		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
+		      ((serial->type->read_bulk_callback) ?
+		       serial->type->read_bulk_callback :
+		       generic_read_bulk_callback), 
+		      port);
+	result = usb_submit_urb(port->read_urb);
+	if (result)
+		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 }
 
 
@@ -1072,6 +1104,7 @@
 			goto probe_error;
 		}
 		buffer_size = endpoint->wMaxPacketSize;
+		port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
 		port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
 		if (!port->bulk_in_buffer) {
 			err("Couldn't allocate bulk_in_buffer");
@@ -1120,6 +1153,7 @@
 			goto probe_error;
 		}
 		buffer_size = endpoint->wMaxPacketSize;
+		port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
 		port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
 		if (!port->interrupt_in_buffer) {
 			err("Couldn't allocate interrupt_in_buffer");
@@ -1137,6 +1171,7 @@
 	/* we don't use num_ports here cauz some devices have more endpoint pairs than ports */
 	max_endpoints = MAX(num_bulk_in, num_bulk_out);
 	max_endpoints = MAX(max_endpoints, num_interrupt_in);
+	dbg (__FUNCTION__ " - setting up %d port structures for this device", max_endpoints);
 	for (i = 0; i < max_endpoints; ++i) {
 		port = &serial->port[i];
 		port->number = i + serial->minor;
diff -urN linux-2.2.19-pre6/fs/exec.c linux/fs/exec.c
--- linux-2.2.19-pre6/fs/exec.c	Mon Dec  3 20:57:38 2001
+++ linux/fs/exec.c	Mon Dec  3 20:57:55 2001
@@ -866,7 +866,7 @@
 		retval = search_binary_handler(&bprm,regs);
 
 	if(current->dumpable == 2)
-		current->dumpable = 0;
+		current->dumpable = 1;
 		
 	if (retval >= 0)
 		/* execve success */
diff -urN linux-2.2.19-pre6/fs/proc/array.c linux/fs/proc/array.c
--- linux-2.2.19-pre6/fs/proc/array.c	Sun Dec 10 16:49:44 2000
+++ linux/fs/proc/array.c	Mon Dec  3 20:57:56 2001
@@ -951,7 +951,7 @@
 			vsize += vma->vm_end - vma->vm_start;
 			vma = vma->vm_next;
 		}
-		if ((current->fsuid == tsk->euid && tsk->dumpable &&
+		if ((current->fsuid == tsk->euid && tsk->dumpable == 1 &&
 		    cap_issubset(tsk->cap_permitted, current->cap_permitted)) ||
 		    capable(CAP_DAC_OVERRIDE)) {
 			eip = KSTK_EIP(tsk);
@@ -1482,7 +1482,7 @@
 		case PROC_PID_CPU:
 			return 0;	
 	}
-	if((current->fsuid == euid && ok) || capable(CAP_DAC_OVERRIDE))
+	if((current->fsuid == euid && ok == 1) || capable(CAP_DAC_OVERRIDE))
 		return 0;
 	return 1;
 }
diff -urN linux-2.2.19-pre6/fs/proc/base.c linux/fs/proc/base.c
--- linux-2.2.19-pre6/fs/proc/base.c	Mon Aug 24 13:02:43 1998
+++ linux/fs/proc/base.c	Mon Dec  3 20:57:56 2001
@@ -66,7 +66,7 @@
 	if (fill && (p = find_task_by_pid(pid)) != NULL) {
 		uid_t uid = 0;
 		gid_t gid = 0;
-		if (p->dumpable || ino == PROC_PID_INO) {
+		if (p->dumpable == 1 || ino == PROC_PID_INO) {
 			uid = p->euid;
 			gid = p->egid;
 		}
diff -urN linux-2.2.19-pre6/fs/proc/inode.c linux/fs/proc/inode.c
--- linux-2.2.19-pre6/fs/proc/inode.c	Mon Sep  4 10:39:27 2000
+++ linux/fs/proc/inode.c	Mon Dec  3 20:57:56 2001
@@ -378,7 +378,7 @@
 		goto out_unlock;
 
 	ino &= 0x0000ffff;
-	if (ino == PROC_PID_INO || p->dumpable) {
+	if (ino == PROC_PID_INO || p->dumpable == 1) {
 		inode->i_uid = p->euid;
 		inode->i_gid = p->egid;
 	}
diff -urN linux-2.2.19-pre6/include/asm-sparc/asm_offsets.h linux/include/asm-sparc/asm_offsets.h
--- linux-2.2.19-pre6/include/asm-sparc/asm_offsets.h	Sun Dec 10 16:49:44 2000
+++ linux/include/asm-sparc/asm_offsets.h	Mon Dec  3 20:57:56 2001
@@ -40,153 +40,163 @@
 #define ASIZ_task_next_run	0x00000004
 #define AOFF_task_prev_run	0x00000040
 #define ASIZ_task_prev_run	0x00000004
-#define AOFF_task_binfmt	0x00000044
+#define AOFF_task_task_exclusive	0x00000044
+#define ASIZ_task_task_exclusive	0x00000004
+#define AOFF_task_binfmt	0x00000048
 #define ASIZ_task_binfmt	0x00000004
-#define AOFF_task_exit_code	0x00000048
+#define AOFF_task_exit_code	0x0000004c
 #define ASIZ_task_exit_code	0x00000004
-#define AOFF_task_exit_signal	0x0000004c
+#define AOFF_task_exit_signal	0x00000050
 #define ASIZ_task_exit_signal	0x00000004
-#define AOFF_task_pdeath_signal	0x00000050
+#define AOFF_task_pdeath_signal	0x00000054
 #define ASIZ_task_pdeath_signal	0x00000004
-#define AOFF_task_personality	0x00000054
+#define AOFF_task_personality	0x00000058
 #define ASIZ_task_personality	0x00000004
-#define AOFF_task_pid	0x0000005c
+#define AOFF_task_pid	0x00000060
 #define ASIZ_task_pid	0x00000004
-#define AOFF_task_pgrp	0x00000060
+#define AOFF_task_pgrp	0x00000064
 #define ASIZ_task_pgrp	0x00000004
-#define AOFF_task_tty_old_pgrp	0x00000064
+#define AOFF_task_tty_old_pgrp	0x00000068
 #define ASIZ_task_tty_old_pgrp	0x00000004
-#define AOFF_task_session	0x00000068
+#define AOFF_task_session	0x0000006c
 #define ASIZ_task_session	0x00000004
-#define AOFF_task_leader	0x0000006c
+#define AOFF_task_leader	0x00000070
 #define ASIZ_task_leader	0x00000004
-#define AOFF_task_p_opptr	0x00000070
+#define AOFF_task_p_opptr	0x00000074
 #define ASIZ_task_p_opptr	0x00000004
-#define AOFF_task_p_pptr	0x00000074
+#define AOFF_task_p_pptr	0x00000078
 #define ASIZ_task_p_pptr	0x00000004
-#define AOFF_task_p_cptr	0x00000078
+#define AOFF_task_p_cptr	0x0000007c
 #define ASIZ_task_p_cptr	0x00000004
-#define AOFF_task_p_ysptr	0x0000007c
+#define AOFF_task_p_ysptr	0x00000080
 #define ASIZ_task_p_ysptr	0x00000004
-#define AOFF_task_p_osptr	0x00000080
+#define AOFF_task_p_osptr	0x00000084
 #define ASIZ_task_p_osptr	0x00000004
-#define AOFF_task_pidhash_next	0x00000084
+#define AOFF_task_pidhash_next	0x00000088
 #define ASIZ_task_pidhash_next	0x00000004
-#define AOFF_task_pidhash_pprev	0x00000088
+#define AOFF_task_pidhash_pprev	0x0000008c
 #define ASIZ_task_pidhash_pprev	0x00000004
-#define AOFF_task_tarray_ptr	0x0000008c
+#define AOFF_task_tarray_ptr	0x00000090
 #define ASIZ_task_tarray_ptr	0x00000004
-#define AOFF_task_wait_chldexit	0x00000090
+#define AOFF_task_wait_chldexit	0x00000094
 #define ASIZ_task_wait_chldexit	0x00000004
-#define AOFF_task_vfork_sem	0x00000094
+#define AOFF_task_vfork_sem	0x00000098
 #define ASIZ_task_vfork_sem	0x00000004
-#define AOFF_task_policy	0x00000098
+#define AOFF_task_policy	0x0000009c
 #define ASIZ_task_policy	0x00000004
-#define AOFF_task_rt_priority	0x0000009c
+#define AOFF_task_rt_priority	0x000000a0
 #define ASIZ_task_rt_priority	0x00000004
-#define AOFF_task_it_real_value	0x000000a0
+#define AOFF_task_it_real_value	0x000000a4
 #define ASIZ_task_it_real_value	0x00000004
-#define AOFF_task_it_prof_value	0x000000a4
+#define AOFF_task_it_prof_value	0x000000a8
 #define ASIZ_task_it_prof_value	0x00000004
-#define AOFF_task_it_virt_value	0x000000a8
+#define AOFF_task_it_virt_value	0x000000ac
 #define ASIZ_task_it_virt_value	0x00000004
-#define AOFF_task_it_real_incr	0x000000ac
+#define AOFF_task_it_real_incr	0x000000b0
 #define ASIZ_task_it_real_incr	0x00000004
-#define AOFF_task_it_prof_incr	0x000000b0
+#define AOFF_task_it_prof_incr	0x000000b4
 #define ASIZ_task_it_prof_incr	0x00000004
-#define AOFF_task_it_virt_incr	0x000000b4
+#define AOFF_task_it_virt_incr	0x000000b8
 #define ASIZ_task_it_virt_incr	0x00000004
-#define AOFF_task_real_timer	0x000000b8
+#define AOFF_task_real_timer	0x000000bc
 #define ASIZ_task_real_timer	0x00000014
-#define AOFF_task_times	0x000000cc
+#define AOFF_task_times	0x000000d0
 #define ASIZ_task_times	0x00000010
-#define AOFF_task_start_time	0x000000dc
+#define AOFF_task_start_time	0x000000e0
 #define ASIZ_task_start_time	0x00000004
-#define AOFF_task_per_cpu_utime	0x000000e0
+#define AOFF_task_per_cpu_utime	0x000000e4
 #define ASIZ_task_per_cpu_utime	0x00000004
-#define AOFF_task_min_flt	0x000000e8
+#define AOFF_task_min_flt	0x000000ec
 #define ASIZ_task_min_flt	0x00000004
-#define AOFF_task_maj_flt	0x000000ec
+#define AOFF_task_maj_flt	0x000000f0
 #define ASIZ_task_maj_flt	0x00000004
-#define AOFF_task_nswap	0x000000f0
+#define AOFF_task_nswap	0x000000f4
 #define ASIZ_task_nswap	0x00000004
-#define AOFF_task_cmin_flt	0x000000f4
+#define AOFF_task_cmin_flt	0x000000f8
 #define ASIZ_task_cmin_flt	0x00000004
-#define AOFF_task_cmaj_flt	0x000000f8
+#define AOFF_task_cmaj_flt	0x000000fc
 #define ASIZ_task_cmaj_flt	0x00000004
-#define AOFF_task_cnswap	0x000000fc
+#define AOFF_task_cnswap	0x00000100
 #define ASIZ_task_cnswap	0x00000004
-#define AOFF_task_uid	0x00000102
+#define AOFF_task_uid	0x00000106
 #define ASIZ_task_uid	0x00000002
-#define AOFF_task_euid	0x00000104
+#define AOFF_task_euid	0x00000108
 #define ASIZ_task_euid	0x00000002
-#define AOFF_task_suid	0x00000106
+#define AOFF_task_suid	0x0000010a
 #define ASIZ_task_suid	0x00000002
-#define AOFF_task_fsuid	0x00000108
+#define AOFF_task_fsuid	0x0000010c
 #define ASIZ_task_fsuid	0x00000002
-#define AOFF_task_gid	0x0000010a
+#define AOFF_task_gid	0x0000010e
 #define ASIZ_task_gid	0x00000002
-#define AOFF_task_egid	0x0000010c
+#define AOFF_task_egid	0x00000110
 #define ASIZ_task_egid	0x00000002
-#define AOFF_task_sgid	0x0000010e
+#define AOFF_task_sgid	0x00000112
 #define ASIZ_task_sgid	0x00000002
-#define AOFF_task_fsgid	0x00000110
+#define AOFF_task_fsgid	0x00000114
 #define ASIZ_task_fsgid	0x00000002
-#define AOFF_task_ngroups	0x00000114
+#define AOFF_task_ngroups	0x00000118
 #define ASIZ_task_ngroups	0x00000004
-#define AOFF_task_groups	0x00000118
+#define AOFF_task_groups	0x0000011c
 #define ASIZ_task_groups	0x00000040
-#define AOFF_task_cap_effective	0x00000158
+#define AOFF_task_cap_effective	0x0000015c
 #define ASIZ_task_cap_effective	0x00000004
-#define AOFF_task_cap_inheritable	0x0000015c
+#define AOFF_task_cap_inheritable	0x00000160
 #define ASIZ_task_cap_inheritable	0x00000004
-#define AOFF_task_cap_permitted	0x00000160
+#define AOFF_task_cap_permitted	0x00000164
 #define ASIZ_task_cap_permitted	0x00000004
-#define AOFF_task_user	0x00000168
+#define AOFF_task_user	0x0000016c
 #define ASIZ_task_user	0x00000004
-#define AOFF_task_rlim	0x0000016c
+#define AOFF_task_rlim	0x00000170
 #define ASIZ_task_rlim	0x00000050
-#define AOFF_task_used_math	0x000001bc
+#define AOFF_task_used_math	0x000001c0
 #define ASIZ_task_used_math	0x00000002
-#define AOFF_task_comm	0x000001be
+#define AOFF_task_comm	0x000001c2
 #define ASIZ_task_comm	0x00000010
-#define AOFF_task_link_count	0x000001d0
+#define AOFF_task_link_count	0x000001d4
 #define ASIZ_task_link_count	0x00000004
-#define AOFF_task_tty	0x000001d4
+#define AOFF_task_tty	0x000001d8
 #define ASIZ_task_tty	0x00000004
-#define AOFF_task_semundo	0x000001d8
+#define AOFF_task_semundo	0x000001dc
 #define ASIZ_task_semundo	0x00000004
-#define AOFF_task_semsleeping	0x000001dc
+#define AOFF_task_semsleeping	0x000001e0
 #define ASIZ_task_semsleeping	0x00000004
-#define AOFF_task_tss	0x000001e0
+#define AOFF_task_tss	0x000001e8
 #define ASIZ_task_tss	0x00000388
-#define AOFF_task_fs	0x00000568
+#define AOFF_task_fs	0x00000570
 #define ASIZ_task_fs	0x00000004
-#define AOFF_task_files	0x0000056c
+#define AOFF_task_files	0x00000574
 #define ASIZ_task_files	0x00000004
-#define AOFF_task_mm	0x00000570
+#define AOFF_task_mm	0x00000578
 #define ASIZ_task_mm	0x00000004
-#define AOFF_task_sigmask_lock	0x00000574
+#define AOFF_task_local_pages	0x0000057c
+#define ASIZ_task_local_pages	0x00000008
+#define AOFF_task_allocation_order	0x00000584
+#define ASIZ_task_allocation_order	0x00000004
+#define AOFF_task_nr_local_pages	0x00000588
+#define ASIZ_task_nr_local_pages	0x00000004
+#define AOFF_task_fs_locks	0x0000058c
+#define ASIZ_task_fs_locks	0x00000004
+#define AOFF_task_sigmask_lock	0x00000590
 #define ASIZ_task_sigmask_lock	0x00000001
-#define AOFF_task_sig	0x00000578
+#define AOFF_task_sig	0x00000594
 #define ASIZ_task_sig	0x00000004
-#define AOFF_task_signal	0x0000057c
+#define AOFF_task_signal	0x00000598
 #define ASIZ_task_signal	0x00000008
-#define AOFF_task_blocked	0x00000584
+#define AOFF_task_blocked	0x000005a0
 #define ASIZ_task_blocked	0x00000008
-#define AOFF_task_sigqueue	0x0000058c
+#define AOFF_task_sigqueue	0x000005a8
 #define ASIZ_task_sigqueue	0x00000004
-#define AOFF_task_sigqueue_tail	0x00000590
+#define AOFF_task_sigqueue_tail	0x000005ac
 #define ASIZ_task_sigqueue_tail	0x00000004
-#define AOFF_task_sas_ss_sp	0x00000594
+#define AOFF_task_sas_ss_sp	0x000005b0
 #define ASIZ_task_sas_ss_sp	0x00000004
-#define AOFF_task_sas_ss_size	0x00000598
+#define AOFF_task_sas_ss_size	0x000005b4
 #define ASIZ_task_sas_ss_size	0x00000004
-#define AOFF_task_parent_exec_id	0x0000059c
+#define AOFF_task_parent_exec_id	0x000005b8
 #define ASIZ_task_parent_exec_id	0x00000004
-#define AOFF_task_self_exec_id	0x000005a0
+#define AOFF_task_self_exec_id	0x000005bc
 #define ASIZ_task_self_exec_id	0x00000004
-#define AOFF_task_oom_kill_try	0x000005a4
+#define AOFF_task_oom_kill_try	0x000005c0
 #define ASIZ_task_oom_kill_try	0x00000004
 #define AOFF_mm_mmap	0x00000000
 #define ASIZ_mm_mmap	0x00000004
@@ -321,153 +331,163 @@
 #define ASIZ_task_next_run	0x00000004
 #define AOFF_task_prev_run	0x00000040
 #define ASIZ_task_prev_run	0x00000004
-#define AOFF_task_binfmt	0x00000044
+#define AOFF_task_task_exclusive	0x00000044
+#define ASIZ_task_task_exclusive	0x00000004
+#define AOFF_task_binfmt	0x00000048
 #define ASIZ_task_binfmt	0x00000004
-#define AOFF_task_exit_code	0x00000048
+#define AOFF_task_exit_code	0x0000004c
 #define ASIZ_task_exit_code	0x00000004
-#define AOFF_task_exit_signal	0x0000004c
+#define AOFF_task_exit_signal	0x00000050
 #define ASIZ_task_exit_signal	0x00000004
-#define AOFF_task_pdeath_signal	0x00000050
+#define AOFF_task_pdeath_signal	0x00000054
 #define ASIZ_task_pdeath_signal	0x00000004
-#define AOFF_task_personality	0x00000054
+#define AOFF_task_personality	0x00000058
 #define ASIZ_task_personality	0x00000004
-#define AOFF_task_pid	0x0000005c
+#define AOFF_task_pid	0x00000060
 #define ASIZ_task_pid	0x00000004
-#define AOFF_task_pgrp	0x00000060
+#define AOFF_task_pgrp	0x00000064
 #define ASIZ_task_pgrp	0x00000004
-#define AOFF_task_tty_old_pgrp	0x00000064
+#define AOFF_task_tty_old_pgrp	0x00000068
 #define ASIZ_task_tty_old_pgrp	0x00000004
-#define AOFF_task_session	0x00000068
+#define AOFF_task_session	0x0000006c
 #define ASIZ_task_session	0x00000004
-#define AOFF_task_leader	0x0000006c
+#define AOFF_task_leader	0x00000070
 #define ASIZ_task_leader	0x00000004
-#define AOFF_task_p_opptr	0x00000070
+#define AOFF_task_p_opptr	0x00000074
 #define ASIZ_task_p_opptr	0x00000004
-#define AOFF_task_p_pptr	0x00000074
+#define AOFF_task_p_pptr	0x00000078
 #define ASIZ_task_p_pptr	0x00000004
-#define AOFF_task_p_cptr	0x00000078
+#define AOFF_task_p_cptr	0x0000007c
 #define ASIZ_task_p_cptr	0x00000004
-#define AOFF_task_p_ysptr	0x0000007c
+#define AOFF_task_p_ysptr	0x00000080
 #define ASIZ_task_p_ysptr	0x00000004
-#define AOFF_task_p_osptr	0x00000080
+#define AOFF_task_p_osptr	0x00000084
 #define ASIZ_task_p_osptr	0x00000004
-#define AOFF_task_pidhash_next	0x00000084
+#define AOFF_task_pidhash_next	0x00000088
 #define ASIZ_task_pidhash_next	0x00000004
-#define AOFF_task_pidhash_pprev	0x00000088
+#define AOFF_task_pidhash_pprev	0x0000008c
 #define ASIZ_task_pidhash_pprev	0x00000004
-#define AOFF_task_tarray_ptr	0x0000008c
+#define AOFF_task_tarray_ptr	0x00000090
 #define ASIZ_task_tarray_ptr	0x00000004
-#define AOFF_task_wait_chldexit	0x00000090
+#define AOFF_task_wait_chldexit	0x00000094
 #define ASIZ_task_wait_chldexit	0x00000004
-#define AOFF_task_vfork_sem	0x00000094
+#define AOFF_task_vfork_sem	0x00000098
 #define ASIZ_task_vfork_sem	0x00000004
-#define AOFF_task_policy	0x00000098
+#define AOFF_task_policy	0x0000009c
 #define ASIZ_task_policy	0x00000004
-#define AOFF_task_rt_priority	0x0000009c
+#define AOFF_task_rt_priority	0x000000a0
 #define ASIZ_task_rt_priority	0x00000004
-#define AOFF_task_it_real_value	0x000000a0
+#define AOFF_task_it_real_value	0x000000a4
 #define ASIZ_task_it_real_value	0x00000004
-#define AOFF_task_it_prof_value	0x000000a4
+#define AOFF_task_it_prof_value	0x000000a8
 #define ASIZ_task_it_prof_value	0x00000004
-#define AOFF_task_it_virt_value	0x000000a8
+#define AOFF_task_it_virt_value	0x000000ac
 #define ASIZ_task_it_virt_value	0x00000004
-#define AOFF_task_it_real_incr	0x000000ac
+#define AOFF_task_it_real_incr	0x000000b0
 #define ASIZ_task_it_real_incr	0x00000004
-#define AOFF_task_it_prof_incr	0x000000b0
+#define AOFF_task_it_prof_incr	0x000000b4
 #define ASIZ_task_it_prof_incr	0x00000004
-#define AOFF_task_it_virt_incr	0x000000b4
+#define AOFF_task_it_virt_incr	0x000000b8
 #define ASIZ_task_it_virt_incr	0x00000004
-#define AOFF_task_real_timer	0x000000b8
+#define AOFF_task_real_timer	0x000000bc
 #define ASIZ_task_real_timer	0x00000014
-#define AOFF_task_times	0x000000cc
+#define AOFF_task_times	0x000000d0
 #define ASIZ_task_times	0x00000010
-#define AOFF_task_start_time	0x000000dc
+#define AOFF_task_start_time	0x000000e0
 #define ASIZ_task_start_time	0x00000004
-#define AOFF_task_per_cpu_utime	0x000000e0
+#define AOFF_task_per_cpu_utime	0x000000e4
 #define ASIZ_task_per_cpu_utime	0x00000080
-#define AOFF_task_min_flt	0x000001e0
+#define AOFF_task_min_flt	0x000001e4
 #define ASIZ_task_min_flt	0x00000004
-#define AOFF_task_maj_flt	0x000001e4
+#define AOFF_task_maj_flt	0x000001e8
 #define ASIZ_task_maj_flt	0x00000004
-#define AOFF_task_nswap	0x000001e8
+#define AOFF_task_nswap	0x000001ec
 #define ASIZ_task_nswap	0x00000004
-#define AOFF_task_cmin_flt	0x000001ec
+#define AOFF_task_cmin_flt	0x000001f0
 #define ASIZ_task_cmin_flt	0x00000004
-#define AOFF_task_cmaj_flt	0x000001f0
+#define AOFF_task_cmaj_flt	0x000001f4
 #define ASIZ_task_cmaj_flt	0x00000004
-#define AOFF_task_cnswap	0x000001f4
+#define AOFF_task_cnswap	0x000001f8
 #define ASIZ_task_cnswap	0x00000004
-#define AOFF_task_uid	0x000001fa
+#define AOFF_task_uid	0x000001fe
 #define ASIZ_task_uid	0x00000002
-#define AOFF_task_euid	0x000001fc
+#define AOFF_task_euid	0x00000200
 #define ASIZ_task_euid	0x00000002
-#define AOFF_task_suid	0x000001fe
+#define AOFF_task_suid	0x00000202
 #define ASIZ_task_suid	0x00000002
-#define AOFF_task_fsuid	0x00000200
+#define AOFF_task_fsuid	0x00000204
 #define ASIZ_task_fsuid	0x00000002
-#define AOFF_task_gid	0x00000202
+#define AOFF_task_gid	0x00000206
 #define ASIZ_task_gid	0x00000002
-#define AOFF_task_egid	0x00000204
+#define AOFF_task_egid	0x00000208
 #define ASIZ_task_egid	0x00000002
-#define AOFF_task_sgid	0x00000206
+#define AOFF_task_sgid	0x0000020a
 #define ASIZ_task_sgid	0x00000002
-#define AOFF_task_fsgid	0x00000208
+#define AOFF_task_fsgid	0x0000020c
 #define ASIZ_task_fsgid	0x00000002
-#define AOFF_task_ngroups	0x0000020c
+#define AOFF_task_ngroups	0x00000210
 #define ASIZ_task_ngroups	0x00000004
-#define AOFF_task_groups	0x00000210
+#define AOFF_task_groups	0x00000214
 #define ASIZ_task_groups	0x00000040
-#define AOFF_task_cap_effective	0x00000250
+#define AOFF_task_cap_effective	0x00000254
 #define ASIZ_task_cap_effective	0x00000004
-#define AOFF_task_cap_inheritable	0x00000254
+#define AOFF_task_cap_inheritable	0x00000258
 #define ASIZ_task_cap_inheritable	0x00000004
-#define AOFF_task_cap_permitted	0x00000258
+#define AOFF_task_cap_permitted	0x0000025c
 #define ASIZ_task_cap_permitted	0x00000004
-#define AOFF_task_user	0x00000260
+#define AOFF_task_user	0x00000264
 #define ASIZ_task_user	0x00000004
-#define AOFF_task_rlim	0x00000264
+#define AOFF_task_rlim	0x00000268
 #define ASIZ_task_rlim	0x00000050
-#define AOFF_task_used_math	0x000002b4
+#define AOFF_task_used_math	0x000002b8
 #define ASIZ_task_used_math	0x00000002
-#define AOFF_task_comm	0x000002b6
+#define AOFF_task_comm	0x000002ba
 #define ASIZ_task_comm	0x00000010
-#define AOFF_task_link_count	0x000002c8
+#define AOFF_task_link_count	0x000002cc
 #define ASIZ_task_link_count	0x00000004
-#define AOFF_task_tty	0x000002cc
+#define AOFF_task_tty	0x000002d0
 #define ASIZ_task_tty	0x00000004
-#define AOFF_task_semundo	0x000002d0
+#define AOFF_task_semundo	0x000002d4
 #define ASIZ_task_semundo	0x00000004
-#define AOFF_task_semsleeping	0x000002d4
+#define AOFF_task_semsleeping	0x000002d8
 #define ASIZ_task_semsleeping	0x00000004
-#define AOFF_task_tss	0x000002d8
+#define AOFF_task_tss	0x000002e0
 #define ASIZ_task_tss	0x00000388
-#define AOFF_task_fs	0x00000660
+#define AOFF_task_fs	0x00000668
 #define ASIZ_task_fs	0x00000004
-#define AOFF_task_files	0x00000664
+#define AOFF_task_files	0x0000066c
 #define ASIZ_task_files	0x00000004
-#define AOFF_task_mm	0x00000668
+#define AOFF_task_mm	0x00000670
 #define ASIZ_task_mm	0x00000004
-#define AOFF_task_sigmask_lock	0x0000066c
+#define AOFF_task_local_pages	0x00000674
+#define ASIZ_task_local_pages	0x00000008
+#define AOFF_task_allocation_order	0x0000067c
+#define ASIZ_task_allocation_order	0x00000004
+#define AOFF_task_nr_local_pages	0x00000680
+#define ASIZ_task_nr_local_pages	0x00000004
+#define AOFF_task_fs_locks	0x00000684
+#define ASIZ_task_fs_locks	0x00000004
+#define AOFF_task_sigmask_lock	0x00000688
 #define ASIZ_task_sigmask_lock	0x00000001
-#define AOFF_task_sig	0x00000670
+#define AOFF_task_sig	0x0000068c
 #define ASIZ_task_sig	0x00000004
-#define AOFF_task_signal	0x00000674
+#define AOFF_task_signal	0x00000690
 #define ASIZ_task_signal	0x00000008
-#define AOFF_task_blocked	0x0000067c
+#define AOFF_task_blocked	0x00000698
 #define ASIZ_task_blocked	0x00000008
-#define AOFF_task_sigqueue	0x00000684
+#define AOFF_task_sigqueue	0x000006a0
 #define ASIZ_task_sigqueue	0x00000004
-#define AOFF_task_sigqueue_tail	0x00000688
+#define AOFF_task_sigqueue_tail	0x000006a4
 #define ASIZ_task_sigqueue_tail	0x00000004
-#define AOFF_task_sas_ss_sp	0x0000068c
+#define AOFF_task_sas_ss_sp	0x000006a8
 #define ASIZ_task_sas_ss_sp	0x00000004
-#define AOFF_task_sas_ss_size	0x00000690
+#define AOFF_task_sas_ss_size	0x000006ac
 #define ASIZ_task_sas_ss_size	0x00000004
-#define AOFF_task_parent_exec_id	0x00000694
+#define AOFF_task_parent_exec_id	0x000006b0
 #define ASIZ_task_parent_exec_id	0x00000004
-#define AOFF_task_self_exec_id	0x00000698
+#define AOFF_task_self_exec_id	0x000006b4
 #define ASIZ_task_self_exec_id	0x00000004
-#define AOFF_task_oom_kill_try	0x0000069c
+#define AOFF_task_oom_kill_try	0x000006b8
 #define ASIZ_task_oom_kill_try	0x00000004
 #define AOFF_mm_mmap	0x00000000
 #define ASIZ_mm_mmap	0x00000004
diff -urN linux-2.2.19-pre6/include/asm-sparc/audioio.h linux/include/asm-sparc/audioio.h
--- linux-2.2.19-pre6/include/asm-sparc/audioio.h	Wed Jun  7 14:26:44 2000
+++ linux/include/asm-sparc/audioio.h	Mon Dec  3 20:57:56 2001
@@ -432,6 +432,7 @@
 extern void sparcaudio_input_done(struct sparcaudio_driver *, int);
 extern int sparcaudio_init(void);
 extern int amd7930_init(void);
+extern int dbri_init(void);
 extern int cs4231_init(void);
 
 #endif
diff -urN linux-2.2.19-pre6/include/asm-sparc64/asm_offsets.h linux/include/asm-sparc64/asm_offsets.h
--- linux-2.2.19-pre6/include/asm-sparc64/asm_offsets.h	Wed May  3 17:16:51 2000
+++ linux/include/asm-sparc64/asm_offsets.h	Mon Dec  3 20:57:56 2001
@@ -40,155 +40,165 @@
 #define ASIZ_task_next_run	0x00000008
 #define AOFF_task_prev_run	0x00000070
 #define ASIZ_task_prev_run	0x00000008
-#define AOFF_task_binfmt	0x00000078
+#define AOFF_task_task_exclusive	0x00000078
+#define ASIZ_task_task_exclusive	0x00000004
+#define AOFF_task_binfmt	0x00000080
 #define ASIZ_task_binfmt	0x00000008
-#define AOFF_task_exit_code	0x00000080
+#define AOFF_task_exit_code	0x00000088
 #define ASIZ_task_exit_code	0x00000004
-#define AOFF_task_exit_signal	0x00000084
+#define AOFF_task_exit_signal	0x0000008c
 #define ASIZ_task_exit_signal	0x00000004
-#define AOFF_task_pdeath_signal	0x00000088
+#define AOFF_task_pdeath_signal	0x00000090
 #define ASIZ_task_pdeath_signal	0x00000004
-#define AOFF_task_personality	0x00000090
+#define AOFF_task_personality	0x00000098
 #define ASIZ_task_personality	0x00000008
-#define AOFF_task_pid	0x0000009c
+#define AOFF_task_pid	0x000000a4
 #define ASIZ_task_pid	0x00000004
-#define AOFF_task_pgrp	0x000000a0
+#define AOFF_task_pgrp	0x000000a8
 #define ASIZ_task_pgrp	0x00000004
-#define AOFF_task_tty_old_pgrp	0x000000a4
+#define AOFF_task_tty_old_pgrp	0x000000ac
 #define ASIZ_task_tty_old_pgrp	0x00000004
-#define AOFF_task_session	0x000000a8
+#define AOFF_task_session	0x000000b0
 #define ASIZ_task_session	0x00000004
-#define AOFF_task_leader	0x000000ac
+#define AOFF_task_leader	0x000000b4
 #define ASIZ_task_leader	0x00000004
-#define AOFF_task_p_opptr	0x000000b0
+#define AOFF_task_p_opptr	0x000000b8
 #define ASIZ_task_p_opptr	0x00000008
-#define AOFF_task_p_pptr	0x000000b8
+#define AOFF_task_p_pptr	0x000000c0
 #define ASIZ_task_p_pptr	0x00000008
-#define AOFF_task_p_cptr	0x000000c0
+#define AOFF_task_p_cptr	0x000000c8
 #define ASIZ_task_p_cptr	0x00000008
-#define AOFF_task_p_ysptr	0x000000c8
+#define AOFF_task_p_ysptr	0x000000d0
 #define ASIZ_task_p_ysptr	0x00000008
-#define AOFF_task_p_osptr	0x000000d0
+#define AOFF_task_p_osptr	0x000000d8
 #define ASIZ_task_p_osptr	0x00000008
-#define AOFF_task_pidhash_next	0x000000d8
+#define AOFF_task_pidhash_next	0x000000e0
 #define ASIZ_task_pidhash_next	0x00000008
-#define AOFF_task_pidhash_pprev	0x000000e0
+#define AOFF_task_pidhash_pprev	0x000000e8
 #define ASIZ_task_pidhash_pprev	0x00000008
-#define AOFF_task_tarray_ptr	0x000000e8
+#define AOFF_task_tarray_ptr	0x000000f0
 #define ASIZ_task_tarray_ptr	0x00000008
-#define AOFF_task_wait_chldexit	0x000000f0
+#define AOFF_task_wait_chldexit	0x000000f8
 #define ASIZ_task_wait_chldexit	0x00000008
-#define AOFF_task_vfork_sem	0x000000f8
+#define AOFF_task_vfork_sem	0x00000100
 #define ASIZ_task_vfork_sem	0x00000008
-#define AOFF_task_policy	0x00000100
+#define AOFF_task_policy	0x00000108
 #define ASIZ_task_policy	0x00000008
-#define AOFF_task_rt_priority	0x00000108
+#define AOFF_task_rt_priority	0x00000110
 #define ASIZ_task_rt_priority	0x00000008
-#define AOFF_task_it_real_value	0x00000110
+#define AOFF_task_it_real_value	0x00000118
 #define ASIZ_task_it_real_value	0x00000008
-#define AOFF_task_it_prof_value	0x00000118
+#define AOFF_task_it_prof_value	0x00000120
 #define ASIZ_task_it_prof_value	0x00000008
-#define AOFF_task_it_virt_value	0x00000120
+#define AOFF_task_it_virt_value	0x00000128
 #define ASIZ_task_it_virt_value	0x00000008
-#define AOFF_task_it_real_incr	0x00000128
+#define AOFF_task_it_real_incr	0x00000130
 #define ASIZ_task_it_real_incr	0x00000008
-#define AOFF_task_it_prof_incr	0x00000130
+#define AOFF_task_it_prof_incr	0x00000138
 #define ASIZ_task_it_prof_incr	0x00000008
-#define AOFF_task_it_virt_incr	0x00000138
+#define AOFF_task_it_virt_incr	0x00000140
 #define ASIZ_task_it_virt_incr	0x00000008
-#define AOFF_task_real_timer	0x00000140
+#define AOFF_task_real_timer	0x00000148
 #define ASIZ_task_real_timer	0x00000028
-#define AOFF_task_times	0x00000168
+#define AOFF_task_times	0x00000170
 #define ASIZ_task_times	0x00000020
-#define AOFF_task_start_time	0x00000188
+#define AOFF_task_start_time	0x00000190
 #define ASIZ_task_start_time	0x00000008
-#define AOFF_task_per_cpu_utime	0x00000190
+#define AOFF_task_per_cpu_utime	0x00000198
 #define ASIZ_task_per_cpu_utime	0x00000008
-#define AOFF_task_min_flt	0x000001a0
+#define AOFF_task_min_flt	0x000001a8
 #define ASIZ_task_min_flt	0x00000008
-#define AOFF_task_maj_flt	0x000001a8
+#define AOFF_task_maj_flt	0x000001b0
 #define ASIZ_task_maj_flt	0x00000008
-#define AOFF_task_nswap	0x000001b0
+#define AOFF_task_nswap	0x000001b8
 #define ASIZ_task_nswap	0x00000008
-#define AOFF_task_cmin_flt	0x000001b8
+#define AOFF_task_cmin_flt	0x000001c0
 #define ASIZ_task_cmin_flt	0x00000008
-#define AOFF_task_cmaj_flt	0x000001c0
+#define AOFF_task_cmaj_flt	0x000001c8
 #define ASIZ_task_cmaj_flt	0x00000008
-#define AOFF_task_cnswap	0x000001c8
+#define AOFF_task_cnswap	0x000001d0
 #define ASIZ_task_cnswap	0x00000008
-#define AOFF_task_uid	0x000001d4
+#define AOFF_task_uid	0x000001dc
 #define ASIZ_task_uid	0x00000004
-#define AOFF_task_euid	0x000001d8
+#define AOFF_task_euid	0x000001e0
 #define ASIZ_task_euid	0x00000004
-#define AOFF_task_suid	0x000001dc
+#define AOFF_task_suid	0x000001e4
 #define ASIZ_task_suid	0x00000004
-#define AOFF_task_fsuid	0x000001e0
+#define AOFF_task_fsuid	0x000001e8
 #define ASIZ_task_fsuid	0x00000004
-#define AOFF_task_gid	0x000001e4
+#define AOFF_task_gid	0x000001ec
 #define ASIZ_task_gid	0x00000004
-#define AOFF_task_egid	0x000001e8
+#define AOFF_task_egid	0x000001f0
 #define ASIZ_task_egid	0x00000004
-#define AOFF_task_sgid	0x000001ec
+#define AOFF_task_sgid	0x000001f4
 #define ASIZ_task_sgid	0x00000004
-#define AOFF_task_fsgid	0x000001f0
+#define AOFF_task_fsgid	0x000001f8
 #define ASIZ_task_fsgid	0x00000004
-#define AOFF_task_ngroups	0x000001f4
+#define AOFF_task_ngroups	0x000001fc
 #define ASIZ_task_ngroups	0x00000004
-#define AOFF_task_groups	0x000001f8
+#define AOFF_task_groups	0x00000200
 #define ASIZ_task_groups	0x00000080
-#define AOFF_task_cap_effective	0x00000278
+#define AOFF_task_cap_effective	0x00000280
 #define ASIZ_task_cap_effective	0x00000004
-#define AOFF_task_cap_inheritable	0x0000027c
+#define AOFF_task_cap_inheritable	0x00000284
 #define ASIZ_task_cap_inheritable	0x00000004
-#define AOFF_task_cap_permitted	0x00000280
+#define AOFF_task_cap_permitted	0x00000288
 #define ASIZ_task_cap_permitted	0x00000004
-#define AOFF_task_user	0x00000288
+#define AOFF_task_user	0x00000290
 #define ASIZ_task_user	0x00000008
-#define AOFF_task_rlim	0x00000290
+#define AOFF_task_rlim	0x00000298
 #define ASIZ_task_rlim	0x000000a0
-#define AOFF_task_used_math	0x00000330
+#define AOFF_task_used_math	0x00000338
 #define ASIZ_task_used_math	0x00000002
-#define AOFF_task_comm	0x00000332
+#define AOFF_task_comm	0x0000033a
 #define ASIZ_task_comm	0x00000010
-#define AOFF_task_link_count	0x00000344
+#define AOFF_task_link_count	0x0000034c
 #define ASIZ_task_link_count	0x00000004
-#define AOFF_task_tty	0x00000348
+#define AOFF_task_tty	0x00000350
 #define ASIZ_task_tty	0x00000008
-#define AOFF_task_semundo	0x00000350
+#define AOFF_task_semundo	0x00000358
 #define ASIZ_task_semundo	0x00000008
-#define AOFF_task_semsleeping	0x00000358
+#define AOFF_task_semsleeping	0x00000360
 #define ASIZ_task_semsleeping	0x00000008
-#define AOFF_task_tss	0x00000360
+#define AOFF_task_tss	0x00000370
 #define ASIZ_task_tss	0x00000470
-#define AOFF_task_fs	0x000007d0
+#define AOFF_task_fs	0x000007e0
 #define ASIZ_task_fs	0x00000008
-#define AOFF_task_files	0x000007d8
+#define AOFF_task_files	0x000007e8
 #define ASIZ_task_files	0x00000008
-#define AOFF_task_mm	0x000007e0
+#define AOFF_task_mm	0x000007f0
 #define ASIZ_task_mm	0x00000008
-#define AOFF_task_sigmask_lock	0x000007e8
+#define AOFF_task_local_pages	0x000007f8
+#define ASIZ_task_local_pages	0x00000010
+#define AOFF_task_allocation_order	0x00000808
+#define ASIZ_task_allocation_order	0x00000004
+#define AOFF_task_nr_local_pages	0x0000080c
+#define ASIZ_task_nr_local_pages	0x00000004
+#define AOFF_task_fs_locks	0x00000810
+#define ASIZ_task_fs_locks	0x00000004
+#define AOFF_task_sigmask_lock	0x00000814
 #define ASIZ_task_sigmask_lock	0x00000001
-#define AOFF_task_sig	0x000007f0
+#define AOFF_task_sig	0x00000818
 #define ASIZ_task_sig	0x00000008
-#define AOFF_task_signal	0x000007f8
+#define AOFF_task_signal	0x00000820
 #define ASIZ_task_signal	0x00000008
-#define AOFF_task_blocked	0x00000800
+#define AOFF_task_blocked	0x00000828
 #define ASIZ_task_blocked	0x00000008
-#define AOFF_task_sigqueue	0x00000808
+#define AOFF_task_sigqueue	0x00000830
 #define ASIZ_task_sigqueue	0x00000008
-#define AOFF_task_sigqueue_tail	0x00000810
+#define AOFF_task_sigqueue_tail	0x00000838
 #define ASIZ_task_sigqueue_tail	0x00000008
-#define AOFF_task_sas_ss_sp	0x00000818
+#define AOFF_task_sas_ss_sp	0x00000840
 #define ASIZ_task_sas_ss_sp	0x00000008
-#define AOFF_task_sas_ss_size	0x00000820
+#define AOFF_task_sas_ss_size	0x00000848
 #define ASIZ_task_sas_ss_size	0x00000008
-#define AOFF_task_parent_exec_id	0x00000828
+#define AOFF_task_parent_exec_id	0x00000850
 #define ASIZ_task_parent_exec_id	0x00000004
-#define AOFF_task_self_exec_id	0x0000082c
+#define AOFF_task_self_exec_id	0x00000854
 #define ASIZ_task_self_exec_id	0x00000004
-#define AOFF_task_oom_kill_try	0x00000830
+#define AOFF_task_oom_kill_try	0x00000858
 #define ASIZ_task_oom_kill_try	0x00000004
-#define ASIZ_task	0x00000840
+#define ASIZ_task	0x00000860
 #define AOFF_mm_mmap	0x00000000
 #define ASIZ_mm_mmap	0x00000008
 #define AOFF_mm_mmap_avl	0x00000008
@@ -332,155 +342,165 @@
 #define ASIZ_task_next_run	0x00000008
 #define AOFF_task_prev_run	0x00000070
 #define ASIZ_task_prev_run	0x00000008
-#define AOFF_task_binfmt	0x00000078
+#define AOFF_task_task_exclusive	0x00000078
+#define ASIZ_task_task_exclusive	0x00000004
+#define AOFF_task_binfmt	0x00000080
 #define ASIZ_task_binfmt	0x00000008
-#define AOFF_task_exit_code	0x00000080
+#define AOFF_task_exit_code	0x00000088
 #define ASIZ_task_exit_code	0x00000004
-#define AOFF_task_exit_signal	0x00000084
+#define AOFF_task_exit_signal	0x0000008c
 #define ASIZ_task_exit_signal	0x00000004
-#define AOFF_task_pdeath_signal	0x00000088
+#define AOFF_task_pdeath_signal	0x00000090
 #define ASIZ_task_pdeath_signal	0x00000004
-#define AOFF_task_personality	0x00000090
+#define AOFF_task_personality	0x00000098
 #define ASIZ_task_personality	0x00000008
-#define AOFF_task_pid	0x0000009c
+#define AOFF_task_pid	0x000000a4
 #define ASIZ_task_pid	0x00000004
-#define AOFF_task_pgrp	0x000000a0
+#define AOFF_task_pgrp	0x000000a8
 #define ASIZ_task_pgrp	0x00000004
-#define AOFF_task_tty_old_pgrp	0x000000a4
+#define AOFF_task_tty_old_pgrp	0x000000ac
 #define ASIZ_task_tty_old_pgrp	0x00000004
-#define AOFF_task_session	0x000000a8
+#define AOFF_task_session	0x000000b0
 #define ASIZ_task_session	0x00000004
-#define AOFF_task_leader	0x000000ac
+#define AOFF_task_leader	0x000000b4
 #define ASIZ_task_leader	0x00000004
-#define AOFF_task_p_opptr	0x000000b0
+#define AOFF_task_p_opptr	0x000000b8
 #define ASIZ_task_p_opptr	0x00000008
-#define AOFF_task_p_pptr	0x000000b8
+#define AOFF_task_p_pptr	0x000000c0
 #define ASIZ_task_p_pptr	0x00000008
-#define AOFF_task_p_cptr	0x000000c0
+#define AOFF_task_p_cptr	0x000000c8
 #define ASIZ_task_p_cptr	0x00000008
-#define AOFF_task_p_ysptr	0x000000c8
+#define AOFF_task_p_ysptr	0x000000d0
 #define ASIZ_task_p_ysptr	0x00000008
-#define AOFF_task_p_osptr	0x000000d0
+#define AOFF_task_p_osptr	0x000000d8
 #define ASIZ_task_p_osptr	0x00000008
-#define AOFF_task_pidhash_next	0x000000d8
+#define AOFF_task_pidhash_next	0x000000e0
 #define ASIZ_task_pidhash_next	0x00000008
-#define AOFF_task_pidhash_pprev	0x000000e0
+#define AOFF_task_pidhash_pprev	0x000000e8
 #define ASIZ_task_pidhash_pprev	0x00000008
-#define AOFF_task_tarray_ptr	0x000000e8
+#define AOFF_task_tarray_ptr	0x000000f0
 #define ASIZ_task_tarray_ptr	0x00000008
-#define AOFF_task_wait_chldexit	0x000000f0
+#define AOFF_task_wait_chldexit	0x000000f8
 #define ASIZ_task_wait_chldexit	0x00000008
-#define AOFF_task_vfork_sem	0x000000f8
+#define AOFF_task_vfork_sem	0x00000100
 #define ASIZ_task_vfork_sem	0x00000008
-#define AOFF_task_policy	0x00000100
+#define AOFF_task_policy	0x00000108
 #define ASIZ_task_policy	0x00000008
-#define AOFF_task_rt_priority	0x00000108
+#define AOFF_task_rt_priority	0x00000110
 #define ASIZ_task_rt_priority	0x00000008
-#define AOFF_task_it_real_value	0x00000110
+#define AOFF_task_it_real_value	0x00000118
 #define ASIZ_task_it_real_value	0x00000008
-#define AOFF_task_it_prof_value	0x00000118
+#define AOFF_task_it_prof_value	0x00000120
 #define ASIZ_task_it_prof_value	0x00000008
-#define AOFF_task_it_virt_value	0x00000120
+#define AOFF_task_it_virt_value	0x00000128
 #define ASIZ_task_it_virt_value	0x00000008
-#define AOFF_task_it_real_incr	0x00000128
+#define AOFF_task_it_real_incr	0x00000130
 #define ASIZ_task_it_real_incr	0x00000008
-#define AOFF_task_it_prof_incr	0x00000130
+#define AOFF_task_it_prof_incr	0x00000138
 #define ASIZ_task_it_prof_incr	0x00000008
-#define AOFF_task_it_virt_incr	0x00000138
+#define AOFF_task_it_virt_incr	0x00000140
 #define ASIZ_task_it_virt_incr	0x00000008
-#define AOFF_task_real_timer	0x00000140
+#define AOFF_task_real_timer	0x00000148
 #define ASIZ_task_real_timer	0x00000028
-#define AOFF_task_times	0x00000168
+#define AOFF_task_times	0x00000170
 #define ASIZ_task_times	0x00000020
-#define AOFF_task_start_time	0x00000188
+#define AOFF_task_start_time	0x00000190
 #define ASIZ_task_start_time	0x00000008
-#define AOFF_task_per_cpu_utime	0x00000190
+#define AOFF_task_per_cpu_utime	0x00000198
 #define ASIZ_task_per_cpu_utime	0x00000100
-#define AOFF_task_min_flt	0x00000390
+#define AOFF_task_min_flt	0x00000398
 #define ASIZ_task_min_flt	0x00000008
-#define AOFF_task_maj_flt	0x00000398
+#define AOFF_task_maj_flt	0x000003a0
 #define ASIZ_task_maj_flt	0x00000008
-#define AOFF_task_nswap	0x000003a0
+#define AOFF_task_nswap	0x000003a8
 #define ASIZ_task_nswap	0x00000008
-#define AOFF_task_cmin_flt	0x000003a8
+#define AOFF_task_cmin_flt	0x000003b0
 #define ASIZ_task_cmin_flt	0x00000008
-#define AOFF_task_cmaj_flt	0x000003b0
+#define AOFF_task_cmaj_flt	0x000003b8
 #define ASIZ_task_cmaj_flt	0x00000008
-#define AOFF_task_cnswap	0x000003b8
+#define AOFF_task_cnswap	0x000003c0
 #define ASIZ_task_cnswap	0x00000008
-#define AOFF_task_uid	0x000003c4
+#define AOFF_task_uid	0x000003cc
 #define ASIZ_task_uid	0x00000004
-#define AOFF_task_euid	0x000003c8
+#define AOFF_task_euid	0x000003d0
 #define ASIZ_task_euid	0x00000004
-#define AOFF_task_suid	0x000003cc
+#define AOFF_task_suid	0x000003d4
 #define ASIZ_task_suid	0x00000004
-#define AOFF_task_fsuid	0x000003d0
+#define AOFF_task_fsuid	0x000003d8
 #define ASIZ_task_fsuid	0x00000004
-#define AOFF_task_gid	0x000003d4
+#define AOFF_task_gid	0x000003dc
 #define ASIZ_task_gid	0x00000004
-#define AOFF_task_egid	0x000003d8
+#define AOFF_task_egid	0x000003e0
 #define ASIZ_task_egid	0x00000004
-#define AOFF_task_sgid	0x000003dc
+#define AOFF_task_sgid	0x000003e4
 #define ASIZ_task_sgid	0x00000004
-#define AOFF_task_fsgid	0x000003e0
+#define AOFF_task_fsgid	0x000003e8
 #define ASIZ_task_fsgid	0x00000004
-#define AOFF_task_ngroups	0x000003e4
+#define AOFF_task_ngroups	0x000003ec
 #define ASIZ_task_ngroups	0x00000004
-#define AOFF_task_groups	0x000003e8
+#define AOFF_task_groups	0x000003f0
 #define ASIZ_task_groups	0x00000080
-#define AOFF_task_cap_effective	0x00000468
+#define AOFF_task_cap_effective	0x00000470
 #define ASIZ_task_cap_effective	0x00000004
-#define AOFF_task_cap_inheritable	0x0000046c
+#define AOFF_task_cap_inheritable	0x00000474
 #define ASIZ_task_cap_inheritable	0x00000004
-#define AOFF_task_cap_permitted	0x00000470
+#define AOFF_task_cap_permitted	0x00000478
 #define ASIZ_task_cap_permitted	0x00000004
-#define AOFF_task_user	0x00000478
+#define AOFF_task_user	0x00000480
 #define ASIZ_task_user	0x00000008
-#define AOFF_task_rlim	0x00000480
+#define AOFF_task_rlim	0x00000488
 #define ASIZ_task_rlim	0x000000a0
-#define AOFF_task_used_math	0x00000520
+#define AOFF_task_used_math	0x00000528
 #define ASIZ_task_used_math	0x00000002
-#define AOFF_task_comm	0x00000522
+#define AOFF_task_comm	0x0000052a
 #define ASIZ_task_comm	0x00000010
-#define AOFF_task_link_count	0x00000534
+#define AOFF_task_link_count	0x0000053c
 #define ASIZ_task_link_count	0x00000004
-#define AOFF_task_tty	0x00000538
+#define AOFF_task_tty	0x00000540
 #define ASIZ_task_tty	0x00000008
-#define AOFF_task_semundo	0x00000540
+#define AOFF_task_semundo	0x00000548
 #define ASIZ_task_semundo	0x00000008
-#define AOFF_task_semsleeping	0x00000548
+#define AOFF_task_semsleeping	0x00000550
 #define ASIZ_task_semsleeping	0x00000008
-#define AOFF_task_tss	0x00000550
+#define AOFF_task_tss	0x00000560
 #define ASIZ_task_tss	0x00000470
-#define AOFF_task_fs	0x000009c0
+#define AOFF_task_fs	0x000009d0
 #define ASIZ_task_fs	0x00000008
-#define AOFF_task_files	0x000009c8
+#define AOFF_task_files	0x000009d8
 #define ASIZ_task_files	0x00000008
-#define AOFF_task_mm	0x000009d0
+#define AOFF_task_mm	0x000009e0
 #define ASIZ_task_mm	0x00000008
-#define AOFF_task_sigmask_lock	0x000009d8
+#define AOFF_task_local_pages	0x000009e8
+#define ASIZ_task_local_pages	0x00000010
+#define AOFF_task_allocation_order	0x000009f8
+#define ASIZ_task_allocation_order	0x00000004
+#define AOFF_task_nr_local_pages	0x000009fc
+#define ASIZ_task_nr_local_pages	0x00000004
+#define AOFF_task_fs_locks	0x00000a00
+#define ASIZ_task_fs_locks	0x00000004
+#define AOFF_task_sigmask_lock	0x00000a04
 #define ASIZ_task_sigmask_lock	0x00000001
-#define AOFF_task_sig	0x000009e0
+#define AOFF_task_sig	0x00000a08
 #define ASIZ_task_sig	0x00000008
-#define AOFF_task_signal	0x000009e8
+#define AOFF_task_signal	0x00000a10
 #define ASIZ_task_signal	0x00000008
-#define AOFF_task_blocked	0x000009f0
+#define AOFF_task_blocked	0x00000a18
 #define ASIZ_task_blocked	0x00000008
-#define AOFF_task_sigqueue	0x000009f8
+#define AOFF_task_sigqueue	0x00000a20
 #define ASIZ_task_sigqueue	0x00000008
-#define AOFF_task_sigqueue_tail	0x00000a00
+#define AOFF_task_sigqueue_tail	0x00000a28
 #define ASIZ_task_sigqueue_tail	0x00000008
-#define AOFF_task_sas_ss_sp	0x00000a08
+#define AOFF_task_sas_ss_sp	0x00000a30
 #define ASIZ_task_sas_ss_sp	0x00000008
-#define AOFF_task_sas_ss_size	0x00000a10
+#define AOFF_task_sas_ss_size	0x00000a38
 #define ASIZ_task_sas_ss_size	0x00000008
-#define AOFF_task_parent_exec_id	0x00000a18
+#define AOFF_task_parent_exec_id	0x00000a40
 #define ASIZ_task_parent_exec_id	0x00000004
-#define AOFF_task_self_exec_id	0x00000a1c
+#define AOFF_task_self_exec_id	0x00000a44
 #define ASIZ_task_self_exec_id	0x00000004
-#define AOFF_task_oom_kill_try	0x00000a20
+#define AOFF_task_oom_kill_try	0x00000a48
 #define ASIZ_task_oom_kill_try	0x00000004
-#define ASIZ_task	0x00000a30
+#define ASIZ_task	0x00000a50
 #define AOFF_mm_mmap	0x00000000
 #define ASIZ_mm_mmap	0x00000008
 #define AOFF_mm_mmap_avl	0x00000008
@@ -622,155 +642,165 @@
 #define ASIZ_task_next_run	0x00000008
 #define AOFF_task_prev_run	0x00000070
 #define ASIZ_task_prev_run	0x00000008
-#define AOFF_task_binfmt	0x00000078
+#define AOFF_task_task_exclusive	0x00000078
+#define ASIZ_task_task_exclusive	0x00000004
+#define AOFF_task_binfmt	0x00000080
 #define ASIZ_task_binfmt	0x00000008
-#define AOFF_task_exit_code	0x00000080
+#define AOFF_task_exit_code	0x00000088
 #define ASIZ_task_exit_code	0x00000004
-#define AOFF_task_exit_signal	0x00000084
+#define AOFF_task_exit_signal	0x0000008c
 #define ASIZ_task_exit_signal	0x00000004
-#define AOFF_task_pdeath_signal	0x00000088
+#define AOFF_task_pdeath_signal	0x00000090
 #define ASIZ_task_pdeath_signal	0x00000004
-#define AOFF_task_personality	0x00000090
+#define AOFF_task_personality	0x00000098
 #define ASIZ_task_personality	0x00000008
-#define AOFF_task_pid	0x0000009c
+#define AOFF_task_pid	0x000000a4
 #define ASIZ_task_pid	0x00000004
-#define AOFF_task_pgrp	0x000000a0
+#define AOFF_task_pgrp	0x000000a8
 #define ASIZ_task_pgrp	0x00000004
-#define AOFF_task_tty_old_pgrp	0x000000a4
+#define AOFF_task_tty_old_pgrp	0x000000ac
 #define ASIZ_task_tty_old_pgrp	0x00000004
-#define AOFF_task_session	0x000000a8
+#define AOFF_task_session	0x000000b0
 #define ASIZ_task_session	0x00000004
-#define AOFF_task_leader	0x000000ac
+#define AOFF_task_leader	0x000000b4
 #define ASIZ_task_leader	0x00000004
-#define AOFF_task_p_opptr	0x000000b0
+#define AOFF_task_p_opptr	0x000000b8
 #define ASIZ_task_p_opptr	0x00000008
-#define AOFF_task_p_pptr	0x000000b8
+#define AOFF_task_p_pptr	0x000000c0
 #define ASIZ_task_p_pptr	0x00000008
-#define AOFF_task_p_cptr	0x000000c0
+#define AOFF_task_p_cptr	0x000000c8
 #define ASIZ_task_p_cptr	0x00000008
-#define AOFF_task_p_ysptr	0x000000c8
+#define AOFF_task_p_ysptr	0x000000d0
 #define ASIZ_task_p_ysptr	0x00000008
-#define AOFF_task_p_osptr	0x000000d0
+#define AOFF_task_p_osptr	0x000000d8
 #define ASIZ_task_p_osptr	0x00000008
-#define AOFF_task_pidhash_next	0x000000d8
+#define AOFF_task_pidhash_next	0x000000e0
 #define ASIZ_task_pidhash_next	0x00000008
-#define AOFF_task_pidhash_pprev	0x000000e0
+#define AOFF_task_pidhash_pprev	0x000000e8
 #define ASIZ_task_pidhash_pprev	0x00000008
-#define AOFF_task_tarray_ptr	0x000000e8
+#define AOFF_task_tarray_ptr	0x000000f0
 #define ASIZ_task_tarray_ptr	0x00000008
-#define AOFF_task_wait_chldexit	0x000000f0
+#define AOFF_task_wait_chldexit	0x000000f8
 #define ASIZ_task_wait_chldexit	0x00000008
-#define AOFF_task_vfork_sem	0x000000f8
+#define AOFF_task_vfork_sem	0x00000100
 #define ASIZ_task_vfork_sem	0x00000008
-#define AOFF_task_policy	0x00000100
+#define AOFF_task_policy	0x00000108
 #define ASIZ_task_policy	0x00000008
-#define AOFF_task_rt_priority	0x00000108
+#define AOFF_task_rt_priority	0x00000110
 #define ASIZ_task_rt_priority	0x00000008
-#define AOFF_task_it_real_value	0x00000110
+#define AOFF_task_it_real_value	0x00000118
 #define ASIZ_task_it_real_value	0x00000008
-#define AOFF_task_it_prof_value	0x00000118
+#define AOFF_task_it_prof_value	0x00000120
 #define ASIZ_task_it_prof_value	0x00000008
-#define AOFF_task_it_virt_value	0x00000120
+#define AOFF_task_it_virt_value	0x00000128
 #define ASIZ_task_it_virt_value	0x00000008
-#define AOFF_task_it_real_incr	0x00000128
+#define AOFF_task_it_real_incr	0x00000130
 #define ASIZ_task_it_real_incr	0x00000008
-#define AOFF_task_it_prof_incr	0x00000130
+#define AOFF_task_it_prof_incr	0x00000138
 #define ASIZ_task_it_prof_incr	0x00000008
-#define AOFF_task_it_virt_incr	0x00000138
+#define AOFF_task_it_virt_incr	0x00000140
 #define ASIZ_task_it_virt_incr	0x00000008
-#define AOFF_task_real_timer	0x00000140
+#define AOFF_task_real_timer	0x00000148
 #define ASIZ_task_real_timer	0x00000028
-#define AOFF_task_times	0x00000168
+#define AOFF_task_times	0x00000170
 #define ASIZ_task_times	0x00000020
-#define AOFF_task_start_time	0x00000188
+#define AOFF_task_start_time	0x00000190
 #define ASIZ_task_start_time	0x00000008
-#define AOFF_task_per_cpu_utime	0x00000190
+#define AOFF_task_per_cpu_utime	0x00000198
 #define ASIZ_task_per_cpu_utime	0x00000100
-#define AOFF_task_min_flt	0x00000390
+#define AOFF_task_min_flt	0x00000398
 #define ASIZ_task_min_flt	0x00000008
-#define AOFF_task_maj_flt	0x00000398
+#define AOFF_task_maj_flt	0x000003a0
 #define ASIZ_task_maj_flt	0x00000008
-#define AOFF_task_nswap	0x000003a0
+#define AOFF_task_nswap	0x000003a8
 #define ASIZ_task_nswap	0x00000008
-#define AOFF_task_cmin_flt	0x000003a8
+#define AOFF_task_cmin_flt	0x000003b0
 #define ASIZ_task_cmin_flt	0x00000008
-#define AOFF_task_cmaj_flt	0x000003b0
+#define AOFF_task_cmaj_flt	0x000003b8
 #define ASIZ_task_cmaj_flt	0x00000008
-#define AOFF_task_cnswap	0x000003b8
+#define AOFF_task_cnswap	0x000003c0
 #define ASIZ_task_cnswap	0x00000008
-#define AOFF_task_uid	0x000003c4
+#define AOFF_task_uid	0x000003cc
 #define ASIZ_task_uid	0x00000004
-#define AOFF_task_euid	0x000003c8
+#define AOFF_task_euid	0x000003d0
 #define ASIZ_task_euid	0x00000004
-#define AOFF_task_suid	0x000003cc
+#define AOFF_task_suid	0x000003d4
 #define ASIZ_task_suid	0x00000004
-#define AOFF_task_fsuid	0x000003d0
+#define AOFF_task_fsuid	0x000003d8
 #define ASIZ_task_fsuid	0x00000004
-#define AOFF_task_gid	0x000003d4
+#define AOFF_task_gid	0x000003dc
 #define ASIZ_task_gid	0x00000004
-#define AOFF_task_egid	0x000003d8
+#define AOFF_task_egid	0x000003e0
 #define ASIZ_task_egid	0x00000004
-#define AOFF_task_sgid	0x000003dc
+#define AOFF_task_sgid	0x000003e4
 #define ASIZ_task_sgid	0x00000004
-#define AOFF_task_fsgid	0x000003e0
+#define AOFF_task_fsgid	0x000003e8
 #define ASIZ_task_fsgid	0x00000004
-#define AOFF_task_ngroups	0x000003e4
+#define AOFF_task_ngroups	0x000003ec
 #define ASIZ_task_ngroups	0x00000004
-#define AOFF_task_groups	0x000003e8
+#define AOFF_task_groups	0x000003f0
 #define ASIZ_task_groups	0x00000080
-#define AOFF_task_cap_effective	0x00000468
+#define AOFF_task_cap_effective	0x00000470
 #define ASIZ_task_cap_effective	0x00000004
-#define AOFF_task_cap_inheritable	0x0000046c
+#define AOFF_task_cap_inheritable	0x00000474
 #define ASIZ_task_cap_inheritable	0x00000004
-#define AOFF_task_cap_permitted	0x00000470
+#define AOFF_task_cap_permitted	0x00000478
 #define ASIZ_task_cap_permitted	0x00000004
-#define AOFF_task_user	0x00000478
+#define AOFF_task_user	0x00000480
 #define ASIZ_task_user	0x00000008
-#define AOFF_task_rlim	0x00000480
+#define AOFF_task_rlim	0x00000488
 #define ASIZ_task_rlim	0x000000a0
-#define AOFF_task_used_math	0x00000520
+#define AOFF_task_used_math	0x00000528
 #define ASIZ_task_used_math	0x00000002
-#define AOFF_task_comm	0x00000522
+#define AOFF_task_comm	0x0000052a
 #define ASIZ_task_comm	0x00000010
-#define AOFF_task_link_count	0x00000534
+#define AOFF_task_link_count	0x0000053c
 #define ASIZ_task_link_count	0x00000004
-#define AOFF_task_tty	0x00000538
+#define AOFF_task_tty	0x00000540
 #define ASIZ_task_tty	0x00000008
-#define AOFF_task_semundo	0x00000540
+#define AOFF_task_semundo	0x00000548
 #define ASIZ_task_semundo	0x00000008
-#define AOFF_task_semsleeping	0x00000548
+#define AOFF_task_semsleeping	0x00000550
 #define ASIZ_task_semsleeping	0x00000008
-#define AOFF_task_tss	0x00000550
+#define AOFF_task_tss	0x00000560
 #define ASIZ_task_tss	0x00000470
-#define AOFF_task_fs	0x000009c0
+#define AOFF_task_fs	0x000009d0
 #define ASIZ_task_fs	0x00000008
-#define AOFF_task_files	0x000009c8
+#define AOFF_task_files	0x000009d8
 #define ASIZ_task_files	0x00000008
-#define AOFF_task_mm	0x000009d0
+#define AOFF_task_mm	0x000009e0
 #define ASIZ_task_mm	0x00000008
-#define AOFF_task_sigmask_lock	0x000009d8
+#define AOFF_task_local_pages	0x000009e8
+#define ASIZ_task_local_pages	0x00000010
+#define AOFF_task_allocation_order	0x000009f8
+#define ASIZ_task_allocation_order	0x00000004
+#define AOFF_task_nr_local_pages	0x000009fc
+#define ASIZ_task_nr_local_pages	0x00000004
+#define AOFF_task_fs_locks	0x00000a00
+#define ASIZ_task_fs_locks	0x00000004
+#define AOFF_task_sigmask_lock	0x00000a04
 #define ASIZ_task_sigmask_lock	0x0000000c
-#define AOFF_task_sig	0x000009e8
+#define AOFF_task_sig	0x00000a10
 #define ASIZ_task_sig	0x00000008
-#define AOFF_task_signal	0x000009f0
+#define AOFF_task_signal	0x00000a18
 #define ASIZ_task_signal	0x00000008
-#define AOFF_task_blocked	0x000009f8
+#define AOFF_task_blocked	0x00000a20
 #define ASIZ_task_blocked	0x00000008
-#define AOFF_task_sigqueue	0x00000a00
+#define AOFF_task_sigqueue	0x00000a28
 #define ASIZ_task_sigqueue	0x00000008
-#define AOFF_task_sigqueue_tail	0x00000a08
+#define AOFF_task_sigqueue_tail	0x00000a30
 #define ASIZ_task_sigqueue_tail	0x00000008
-#define AOFF_task_sas_ss_sp	0x00000a10
+#define AOFF_task_sas_ss_sp	0x00000a38
 #define ASIZ_task_sas_ss_sp	0x00000008
-#define AOFF_task_sas_ss_size	0x00000a18
+#define AOFF_task_sas_ss_size	0x00000a40
 #define ASIZ_task_sas_ss_size	0x00000008
-#define AOFF_task_parent_exec_id	0x00000a20
+#define AOFF_task_parent_exec_id	0x00000a48
 #define ASIZ_task_parent_exec_id	0x00000004
-#define AOFF_task_self_exec_id	0x00000a24
+#define AOFF_task_self_exec_id	0x00000a4c
 #define ASIZ_task_self_exec_id	0x00000004
-#define AOFF_task_oom_kill_try	0x00000a28
+#define AOFF_task_oom_kill_try	0x00000a50
 #define ASIZ_task_oom_kill_try	0x00000004
-#define ASIZ_task	0x00000a30
+#define ASIZ_task	0x00000a60
 #define AOFF_mm_mmap	0x00000000
 #define ASIZ_mm_mmap	0x00000008
 #define AOFF_mm_mmap_avl	0x00000008
diff -urN linux-2.2.19-pre6/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h
--- linux-2.2.19-pre6/include/asm-sparc64/pgtable.h	Wed May  3 17:16:51 2000
+++ linux/include/asm-sparc64/pgtable.h	Mon Dec  3 20:57:56 2001
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.103.2.3 2000/02/27 04:44:47 davem Exp $
+/* $Id: pgtable.h,v 1.103.2.4 2000/12/11 12:31:06 anton Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -171,9 +171,15 @@
 #define flush_cache_range(mm, start, end)	flushw_user()
 #define flush_cache_page(vma, page)		flushw_user()
 
-/* These operations are unnecessary on the SpitFire since D-CACHE is write-through. */
-#define flush_icache_range(start, end)		do { } while (0)
+/* This is unnecessary on the SpitFire since D-CACHE is write-through. */
 #define flush_page_to_ram(page)			do { } while (0)
+
+/* 
+ * icache doesnt snoop local stores and we don't use block commit stores
+ * (which invalidate icache lines) during module load, so we need this.
+ */
+extern void flush_icache_range(unsigned long start, unsigned long end);
+
 extern void flush_dcache_page(unsigned long page);
 
 extern void __flush_dcache_range(unsigned long start, unsigned long end);
diff -urN linux-2.2.19-pre6/include/linux/mc146818rtc.h linux/include/linux/mc146818rtc.h
--- linux-2.2.19-pre6/include/linux/mc146818rtc.h	Sun Dec 10 16:49:44 2000
+++ linux/include/linux/mc146818rtc.h	Mon Dec  3 20:57:56 2001
@@ -11,6 +11,7 @@
 #ifndef _MC146818RTC_H
 #define _MC146818RTC_H
 #include <asm/io.h>
+#include <linux/rtc.h>
 
 #ifndef RTC_PORT
 #define RTC_PORT(x)	(0x70 + (x))
@@ -26,7 +27,9 @@
 outb_p((val),RTC_PORT(1)); \
 })
 
+#ifdef __KERNEL__
 extern spinlock_t rtc_lock;	/* You must hold this lock to use CMOS_* ops */
+#endif
 
 /**********************************************************************
  * register summary
@@ -107,45 +110,5 @@
 #ifndef BIN_TO_BCD
 #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
 #endif
-
-/*
- * The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel 
- * source is self contained, allowing cross-compiles, etc. etc.
- */
-
-struct rtc_time {
-	int tm_sec;
-	int tm_min;
-	int tm_hour;
-	int tm_mday;
-	int tm_mon;
-	int tm_year;
-	int tm_wday;
-	int tm_yday;
-	int tm_isdst;
-};
-
-/*
- * ioctl calls that are permitted to the /dev/rtc interface, if 
- * CONFIG_RTC was enabled.
- */
-
-#define RTC_AIE_ON	_IO('p', 0x01)	/* Alarm int. enable on		*/
-#define RTC_AIE_OFF	_IO('p', 0x02)	/* ... off			*/
-#define RTC_UIE_ON	_IO('p', 0x03)	/* Update int. enable on	*/
-#define RTC_UIE_OFF	_IO('p', 0x04)	/* ... off			*/
-#define RTC_PIE_ON	_IO('p', 0x05)	/* Periodic int. enable on	*/
-#define RTC_PIE_OFF	_IO('p', 0x06)	/* ... off			*/
-
-#define RTC_ALM_SET	_IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
-#define RTC_ALM_READ	_IOR('p', 0x08, struct rtc_time) /* Read alarm time */
-#define RTC_RD_TIME	_IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
-#define RTC_SET_TIME	_IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
-#define RTC_IRQP_READ	_IOR('p', 0x0b, unsigned long)	 /* Read IRQ rate   */
-#define RTC_IRQP_SET	_IOW('p', 0x0c, unsigned long)	 /* Set IRQ rate    */
-#define RTC_EPOCH_READ	_IOR('p', 0x0d, unsigned long)	 /* Read epoch      */
-#define RTC_EPOCH_SET	_IOW('p', 0x0e, unsigned long)	 /* Set epoch       */
-
 
 #endif /* _MC146818RTC_H */
diff -urN linux-2.2.19-pre6/include/linux/rtc.h linux/include/linux/rtc.h
--- linux-2.2.19-pre6/include/linux/rtc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/rtc.h	Mon Dec  3 20:57:56 2001
@@ -0,0 +1,43 @@
+#ifndef _LINUX_RTC_H
+#define _LINUX_RTC_H_
+
+
+/*
+ * The struct used to pass data via the following ioctl. Similar to the
+ * struct tm in <time.h>, but it needs to be here so that the kernel 
+ * source is self contained, allowing cross-compiles, etc. etc.
+ */
+
+struct rtc_time {
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+	int tm_isdst;
+};
+
+/*
+ * ioctls that are permitted to the /dev/rtc interface.
+ */
+
+#define RTC_AIE_ON	_IO('p', 0x01)	/* Alarm int. enable on		*/
+#define RTC_AIE_OFF	_IO('p', 0x02)	/* ... off			*/
+#define RTC_UIE_ON	_IO('p', 0x03)	/* Update int. enable on	*/
+#define RTC_UIE_OFF	_IO('p', 0x04)	/* ... off			*/
+#define RTC_PIE_ON	_IO('p', 0x05)	/* Periodic int. enable on	*/
+#define RTC_PIE_OFF	_IO('p', 0x06)	/* ... off			*/
+
+#define RTC_ALM_SET	_IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
+#define RTC_ALM_READ	_IOR('p', 0x08, struct rtc_time) /* Read alarm time */
+#define RTC_RD_TIME	_IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
+#define RTC_SET_TIME	_IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
+#define RTC_IRQP_READ	_IOR('p', 0x0b, unsigned long)	 /* Read IRQ rate   */
+#define RTC_IRQP_SET	_IOW('p', 0x0c, unsigned long)	 /* Set IRQ rate    */
+#define RTC_EPOCH_READ	_IOR('p', 0x0d, unsigned long)	 /* Read epoch      */
+#define RTC_EPOCH_SET	_IOW('p', 0x0e, unsigned long)	 /* Set epoch       */
+
+#endif /* _LINUX_RTC_H_ */
diff -urN linux-2.2.19-pre6/include/net/ip.h linux/include/net/ip.h
--- linux-2.2.19-pre6/include/net/ip.h	Sun Dec 10 16:49:44 2000
+++ linux/include/net/ip.h	Mon Dec  3 20:57:56 2001
@@ -172,7 +172,7 @@
 {
 	u16 check = iph->check;
 	check += __constant_htons(0x0100);
-	iph->check = check + (check>=0xFFFF);
+	iph->check = check + ((check>=0xFFFF) ? 1 : 0);
 	return --iph->ttl;
 }
 
diff -urN linux-2.2.19-pre6/init/main.c linux/init/main.c
--- linux-2.2.19-pre6/init/main.c	Mon Dec  3 20:57:38 2001
+++ linux/init/main.c	Mon Dec  3 20:57:56 2001
@@ -624,22 +624,22 @@
        { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
        { "dasdi", (DASD_MAJOR << MINORBITS) + (8 << 2) },
        { "dasdj", (DASD_MAJOR << MINORBITS) + (9 << 2) },
-       { "dasdk", (DASD_MAJOR << MINORBITS) + (11 << 2) },
-       { "dasdl", (DASD_MAJOR << MINORBITS) + (12 << 2) },
-       { "dasdm", (DASD_MAJOR << MINORBITS) + (13 << 2) },
-       { "dasdn", (DASD_MAJOR << MINORBITS) + (14 << 2) },
-       { "dasdo", (DASD_MAJOR << MINORBITS) + (15 << 2) },
-       { "dasdp", (DASD_MAJOR << MINORBITS) + (16 << 2) },
-       { "dasdq", (DASD_MAJOR << MINORBITS) + (17 << 2) },
-       { "dasdr", (DASD_MAJOR << MINORBITS) + (18 << 2) },
-       { "dasds", (DASD_MAJOR << MINORBITS) + (19 << 2) },
-       { "dasdt", (DASD_MAJOR << MINORBITS) + (20 << 2) },
-       { "dasdu", (DASD_MAJOR << MINORBITS) + (21 << 2) },
-       { "dasdv", (DASD_MAJOR << MINORBITS) + (22 << 2) },
-       { "dasdw", (DASD_MAJOR << MINORBITS) + (23 << 2) },
-       { "dasdx", (DASD_MAJOR << MINORBITS) + (24 << 2) },
-       { "dasdy", (DASD_MAJOR << MINORBITS) + (25 << 2) },
-       { "dasdz", (DASD_MAJOR << MINORBITS) + (26 << 2) },
+       { "dasdk", (DASD_MAJOR << MINORBITS) + (10 << 2) },
+       { "dasdl", (DASD_MAJOR << MINORBITS) + (11 << 2) },
+       { "dasdm", (DASD_MAJOR << MINORBITS) + (12 << 2) },
+       { "dasdn", (DASD_MAJOR << MINORBITS) + (13 << 2) },
+       { "dasdo", (DASD_MAJOR << MINORBITS) + (14 << 2) },
+       { "dasdp", (DASD_MAJOR << MINORBITS) + (15 << 2) },
+       { "dasdq", (DASD_MAJOR << MINORBITS) + (16 << 2) },
+       { "dasdr", (DASD_MAJOR << MINORBITS) + (17 << 2) },
+       { "dasds", (DASD_MAJOR << MINORBITS) + (18 << 2) },
+       { "dasdt", (DASD_MAJOR << MINORBITS) + (19 << 2) },
+       { "dasdu", (DASD_MAJOR << MINORBITS) + (20 << 2) },
+       { "dasdv", (DASD_MAJOR << MINORBITS) + (21 << 2) },
+       { "dasdw", (DASD_MAJOR << MINORBITS) + (22 << 2) },
+       { "dasdx", (DASD_MAJOR << MINORBITS) + (23 << 2) },
+       { "dasdy", (DASD_MAJOR << MINORBITS) + (24 << 2) },
+       { "dasdz", (DASD_MAJOR << MINORBITS) + (25 << 2) },
 #endif
 #ifdef CONFIG_BLK_DEV_XPRAM
        { "xpram0", (XPRAM_MAJOR << MINORBITS) },
diff -urN linux-2.2.19-pre6/net/core/dev.c linux/net/core/dev.c
--- linux-2.2.19-pre6/net/core/dev.c	Sun Dec 10 16:49:44 2000
+++ linux/net/core/dev.c	Mon Dec  3 20:57:56 2001
@@ -649,7 +649,7 @@
 
 
 /*=======================================================================
-			Receiver rotutines
+			Receiver routines
   =======================================================================*/
 
 int netdev_dropping = 0;
diff -urN linux-2.2.19-pre6/net/ipv4/ip_masq_raudio.c linux/net/ipv4/ip_masq_raudio.c
--- linux-2.2.19-pre6/net/ipv4/ip_masq_raudio.c	Tue Oct 27 09:57:19 1998
+++ linux/net/ipv4/ip_masq_raudio.c	Mon Dec  3 20:57:56 2001
@@ -169,7 +169,10 @@
         skb = *skb_p;
 	iph = skb->nh.iph;
         th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
-        data = (char *)&th[1];
+
+	/* Make sure we take into account the size of the TCP packet.  This is
+	 * because there may be TCP options in the TCP packet */
+	data = ((char *)&th[0]) + (th->doff * 4);
 
         data_limit = skb->h.raw + skb->len;
 
@@ -315,7 +318,10 @@
         skb = *skb_p;
 	iph = skb->nh.iph;
         th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
-        data = (char *)&th[1];
+
+	/* Make sure we take into account the size of the TCP packet.  This is
+	 * because there may be TCP options in the TCP packet */
+	data = ((char *)&th[0]) + (th->doff * 4);
 
         data_limit = skb->h.raw + skb->len;
 
diff -urN linux-2.2.19-pre6/scripts/kwhich linux/scripts/kwhich
--- linux-2.2.19-pre6/scripts/kwhich	Sun Dec 10 16:49:45 2000
+++ linux/scripts/kwhich	Mon Dec  3 20:57:56 2001
@@ -7,7 +7,7 @@
         exit 1
 fi
 
-IFS=:
+IFS=":$IFS"
 for cmd in $*
 do
         for path in $PATH
