]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.19pre7 2.2.19pre7
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:23:10 +0000 (15:23 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:23:10 +0000 (15:23 -0500)
o Remove dead arm files (Russell King)
o Fix VIA rhine build failure for a few folks (Peter Monta)
o ARM ptrace fixes (Russell King)
o Fix ymfpci setup for legacy devices (Pete Zaitcev)
o xspeed dsl needs pci (Lars Holmberg)
o Typo fix (Dave Miller)
o Update ftdi usb serial driver (Greg Kroah-Hartman)
o Update keyspan usb serial drivers (Greg Kroah-Hartman)
o Sparc updates (Dave Miller)
o Remove incorrect lp printk (Tim Waugh)
o Fix ppa panic on timeout (Tim Waugh)
o Maestro3 needs ac97 codec (Oleg Krivosheev)
o Fix kwhich versus old bash (Pete Zaitcev)
o Fix ip checksum compiler behaviour assumption (Dave Miller)
o Fix real audio masq in presence of options (John Villalovos)
o ne2k-pci version printing tweaks (J. Magallon)
o Fix incorrect minors for some dasd devices as (Holger Smolinski)
root
o Fix alpha exception table printk     (Andrzej Krzysztofowicz)
o USB config updates (Greg Kroah-Hartman)
o USB audio driver updates (Greg Kroah-Hartman)
o Fix missing unlock_kernel in usbdev (Greg Kroah-Hartman)
o Update USB hid driver (Greg Kroah-Hartman)
o USB rio driver update (Greg Kroah-Hartman)
o Hopefully fix CyrixIII panic on boot (Ingo Oeser,
 H Peter Anvin)
o Further CMOS lock fixes, move ioctls (Paul Gortmaker)
o Dumpable should now work right again (Zack Weinberg,
 Alan Cox)

56 files changed:
Documentation/rtc.txt
Makefile
arch/alpha/mm/extable.c
arch/arm/kernel/ptrace.c
arch/arm/vmlinux-armo.lds [deleted file]
arch/arm/vmlinux-armv.lds [deleted file]
arch/i386/kernel/setup.c
arch/sparc/defconfig
arch/sparc64/defconfig
arch/sparc64/kernel/binfmt_aout32.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/mm/init.c
drivers/block/hd.c
drivers/char/lp.c
drivers/net/Config.in
drivers/net/ne2k-pci.c
drivers/net/via-rhine.c
drivers/sbus/audio/cs4215.h
drivers/sbus/audio/dbri.c
drivers/sbus/char/zs.c
drivers/scsi/gdth.c
drivers/scsi/ppa.h
drivers/sound/Makefile
drivers/sound/ymfpci.c
drivers/usb/Config.in
drivers/usb/audio.c
drivers/usb/devices.c
drivers/usb/hid.c
drivers/usb/rio500.c
drivers/usb/serial/Config.in [new file with mode: 0644]
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan.h
drivers/usb/serial/keyspan_usa26msg.h
drivers/usb/serial/keyspan_usa28msg.h
drivers/usb/serial/keyspan_usa49msg.h [new file with mode: 0644]
drivers/usb/serial/keyspan_usa49w_fw.h [new file with mode: 0644]
drivers/usb/serial/usb-serial.h
drivers/usb/serial/usbserial.c
fs/exec.c
fs/proc/array.c
fs/proc/base.c
fs/proc/inode.c
include/asm-sparc/asm_offsets.h
include/asm-sparc/audioio.h
include/asm-sparc64/asm_offsets.h
include/asm-sparc64/pgtable.h
include/linux/mc146818rtc.h
include/linux/rtc.h [new file with mode: 0644]
include/net/ip.h
init/main.c
net/core/dev.c
net/ipv4/ip_masq_raudio.c
scripts/kwhich

index 7718228ba5519563409c50702d070b9ea3d3e1b1..dc35d3edcfb11fc24e6d3d5bc9bf764b12494c4a 100644 (file)
@@ -56,7 +56,7 @@ whatever) then the kernel will keep its hands off the RTC, allowing you
 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 @@ that will be using this driver.
  */
 
 #include <stdio.h>
-#include <linux/mc146818rtc.h>
+#include <linux/rtc.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
 #include <sys/types.h>
index 65a84aaeb7d560ff915816d0f92ab4f690e0a143..b5b5838a30501afb19802c5a44c5b08a7607c861 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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/)
 
index acbc394cb6d7cc745b0c8597a4de2b92ebfedd13..4c203a6b1dbb264292892413daf87c34f2fe6714 100644 (file)
@@ -88,7 +88,7 @@ search_exception_table(unsigned long addr, unsigned long exc_gp)
         */
        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;
index 5db89cb39235d4c8bc77585d53f6ce074a7579b4..c4dcff21abb9b7ba128657fd5b8e04fede891700 100644 (file)
@@ -516,196 +516,230 @@ get_branch_address(struct task_struct *child, unsigned long pc, unsigned long in
            }
            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;
+                       break;
+
+               /*
+                * Get all gp regs from the child.
+                */
+               case PTRACE_GETREGS: {
+                       struct pt_regs *regs = get_user_regs(child);
 
                        ret = 0;
-                       stack = (unsigned char *)((unsigned long)child + 8192 - sizeof(struct pt_regs));
-                       if (copy_to_user((void *)data, stack,
+                       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 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
        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 --git a/arch/arm/vmlinux-armo.lds b/arch/arm/vmlinux-armo.lds
deleted file mode 100644 (file)
index 1e9d83d..0000000
+++ /dev/null
@@ -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 --git a/arch/arm/vmlinux-armv.lds b/arch/arm/vmlinux-armv.lds
deleted file mode 100644 (file)
index 4011664..0000000
+++ /dev/null
@@ -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) }
-}
index 2cfa87e5884064b5815296cce5acf54b6014b8f9..407813049c7a109f84e23656a0987fde61ec840a 100644 (file)
@@ -1278,7 +1278,9 @@ __initfunc(void setup_centaur(struct cpuinfo_x86 *c))
                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;
        }       
index 8aebe64385c09696ae3883897afc1e3be103310a..f6e142eba53973c822585bc2e639eb9d7531a390 100644 (file)
@@ -284,6 +284,7 @@ CONFIG_NCP_FS=m
 #
 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_DEFAULT="cp437"
 # 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
index 65690f506f38d52aafaabca288d441acaf52c668..bf0c838fb1ba3c6192d1154e90d4c2d3af2b13c5 100644 (file)
@@ -19,7 +19,7 @@ CONFIG_KMOD=y
 #
 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_NCP_FS=m
 #
 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_DEFAULT="cp437"
 # 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
index 98c533d88b578bdd39526874308d030e8b79fae4..c9e2d78c75615dc6ddb076aebfdc1249aa14166a 100644 (file)
@@ -101,7 +101,7 @@ do_aout32_core_dump(long signr, struct pt_regs * regs)
 #       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;
 
index 934ec309b5c7160b78928db54bdde2a1054d6904..31864444f5fbfa4152cf95a08f7f80b134cc242a 100644 (file)
@@ -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(disable_irq);
 
 EXPORT_SYMBOL_PRIVATE(flushw_user);
 
+EXPORT_SYMBOL(flush_icache_range);
 EXPORT_SYMBOL(flush_dcache_page);
 
 EXPORT_SYMBOL(mstk48t02_regs);
@@ -209,6 +210,11 @@ EXPORT_SYMBOL(_sigpause_common);
 /* 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);
index 7841f94975ec9b3cee65b688b098cfdcbf1f2a2f..f61245392da35b914f4f8761db91854a2814a671 100644 (file)
@@ -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 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
                        (current->tss.kregs->u_regs[UREG_FP] & 0xffffffffUL);
                if(get_user(arg5, &sp->xxargs[0])) {
                        rval = -EFAULT;
+                       kfree(kmbuf);
                        break;
                }
                set_fs(KERNEL_DS);
index 8f35f237e60a8f4ccc9720a77c5c58fd9ba7e83f..63c6ad5f12104b66b19f6a114f685863e179c3bc 100644 (file)
@@ -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)
@@ -89,6 +89,14 @@ int do_check_pgt_cache(int low, int high)
         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));
+}
+
 /*
  * BAD_PAGE is the page that is used for page faults when linux
  * is out-of-memory. Older versions of linux just did a
index 4daaf76e69ab74987d1d65c68d1f924b2a6a9627..45e8fe86a836e3a06c3e3eebc47e5240ec81eda3 100644 (file)
@@ -703,12 +703,12 @@ static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 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 @@ static void hd_geninit(struct gendisk *ignored)
                
        */
                 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++) {
index a16a4896cc2920a52c68a2b6946daec0699ee426..54d5c8751a78eece81558b417bf9287402c72c7d 100644 (file)
@@ -307,32 +307,11 @@ static inline int lp_char(char lpchar, int minor)
                /*
                 * 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);
index 528c1900938e077e8965ca6be58ecbf415683a26..5c53b2b83d538d72e5bb100a6886f5801dc1ac59 100644 (file)
@@ -367,7 +367,7 @@ fi
 #
 # Xpeed drivers
 #
-tristate 'Xpeed X200/X300 DSL NIC support' CONFIG_XPEED
+dep_tristate 'Xpeed X200/X300 DSL NIC support' CONFIG_XPEED $CONFIG_PCI
 
 endmenu
 
index 38780ef045cc084f46c256721b5bb4afa0f28eb7..af5e5efaed62bad79a5e63f906ec471852f4e6f2 100644 (file)
 */
 
 /* 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 @@ int
 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 @@ __initfunc (int ne2k_pci_probe(struct device *dev))
                {
                        static unsigned version_printed = 0;
                        if (version_printed++ == 0)
-                               printk(KERN_INFO "%s %s", version1, version2);
+                               printk(KERN_INFO "%s\n", version);
                }
 #endif
 
index 7ad2863faddf834ade86c1e25060a5b4a533bb43..14ccde74757aace469da3f4fe5f6ca663a039e5a 100644 (file)
@@ -81,6 +81,7 @@ static const int multicast_filter_limit = 32;
 #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>
index de90e2f244b0c3e30e3109e1d3730b1b5296c649..e148279ee6e6690142667bb031a47c55806dddab 100644 (file)
@@ -105,7 +105,7 @@ static struct {
 
 /* 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 */
index 10307d9783fc244f6ad34e5bd08434089e83c8dd..5f4fb45c7012d88e28359c119d95cf971df1944d 100644 (file)
@@ -1382,8 +1382,13 @@ static void mmcodec_default(struct dbri *dbri)
 
         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 @@ static void mmcodec_setgain(struct dbri *dbri, int muted)
         } 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 @@ static void mmcodec_setgain(struct dbri *dbri, int muted)
                         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 @@ static int mmcodec_init(struct sparcaudio_driver *drv)
                 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_get_input_rate(struct sparcaudio_driver *drv)
 
 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 ********************/
index e254b7c0b7201d8c6234896af8e1773dd8cb4887..06fdd45a4c88c03825d39104c87dd459561727b2 100644 (file)
@@ -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 shutdown(struct sun_serial * info)
  */
 static void change_speed(struct sun_serial *info)
 {
-       unsigned short port;
        unsigned cflag;
        int     quot = 0;
        int     i;
@@ -913,7 +912,7 @@ static void change_speed(struct sun_serial *info)
        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 @@ int zs_open(struct tty_struct *tty, struct file * filp)
 
 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, ' ');
index b17785525333967cdb601c334282e25b0e1e0298..3b67b74d4579afe54890625b6665079462a83bfa 100644 (file)
@@ -1837,6 +1837,7 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
     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 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
 #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 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
         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 */
index e5af9603ffddd8abc31485917270d31b1da13fda..3e98d1aa1961674b07523a45e6c3814393b8e5ee 100644 (file)
@@ -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 @@ int ppa_biosparam(Disk *, kdev_t, int *);
                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,                 \
index 5e0c5c0a737d63089a212672a7144e3731bb9b77..ac8fb955737a6517cfce683b67e9d7a15fcdd7ad 100644 (file)
@@ -93,8 +93,8 @@ obj-$(CONFIG_SOUND_ES1371)    += es1371.o
 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
index b108fae3468edfaac67eb8a914e24e443b56f1e1..e8a6c522d056bc6195ac185ccfc751d4bc5cc51b 100644 (file)
@@ -1919,8 +1919,8 @@ static int ymfpci_setup_legacy( ymfpci_t *codec, struct pci_dev *pcidev )
                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;
 
index 20d52b2b7a34f8f79571938895e3064b29bd899b..450029cfe2e9bfde477c5bc1bd09d0b1fba9ab6d 100644 (file)
@@ -10,7 +10,6 @@ if [ ! "$CONFIG_USB" = "n" ]; then
 
 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 @@ comment 'USB Controllers'
    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
index 96ff9ecc70bf1c368f9a04a1e60347b65f03598f..a2b3784dbf4b1cf2159662432e337095bdc60676 100644 (file)
 #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 @@ static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void *b
                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 @@ static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void *buffer
                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_open_mixdev(struct inode *inode, struct file *file)
 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 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
        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 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                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 @@ static int usb_audio_mmap(struct file *file, struct vm_area_struct *vma)
 {
        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 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                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 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                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 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                                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 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                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 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                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 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                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_open(struct inode *inode, struct file *file)
 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 @@ static int usb_audio_release(struct inode *inode, struct file *file)
        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_probe(struct usb_device *dev, unsigned int ifnum);
 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 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum)
 #endif
                return NULL;
        }
+
        /*
         * audiocontrol interface found
         * find which configuration number is active
@@ -3721,21 +3742,21 @@ static void usb_audio_disconnect(struct usb_device *dev, void *ptr)
        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");
+
index 70e0150cbfb50de67f8d15e874d917d892387b67..e2b53b45cd65ec46c98701ba1a6caa7429ce4b2e 100644 (file)
@@ -496,8 +496,10 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
        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
index 6339ba6f18d19b5b964f3ec606add315c8952032..8a5c22f8107ec06b5d02dbcb189ece492dd6f43f 100644 (file)
@@ -856,7 +856,7 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie
                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 @@ static void hid_process_event(struct input_dev *input, int *quirks, struct hid_f
                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 @@ static int hid_submit_out(struct hid_device *hid)
        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 @@ static int hid_open(struct input_dev *dev)
        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;
index 59c97376e45861301bb59b703c4e88db1aabf21c..635780888b4a2f8b26538c0d573958affecdff3e 100644 (file)
@@ -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 @@ struct rio_usb_data {
         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 @@ static int open_rio(struct inode *inode, struct file *file)
 {
        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 @@ static int open_rio(struct inode *inode, struct file *file)
 
        MOD_INC_USE_COUNT;
 
+       unlock_kernel();
+
        info("Rio opened.");
 
        return 0;
@@ -101,6 +108,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
        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 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                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 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                     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 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                                     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 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                           be swapped at the app level */
 
                }
+               up(&(rio->lock));
                free_page((unsigned long) buffer);
                break;
 
@@ -178,8 +194,10 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                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 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                     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 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                        }
 
                }
+               up(&(rio->lock));
                free_page((unsigned long) buffer);
                break;
 
@@ -220,6 +240,10 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
        }
 
        return 0;
+
+err_out:
+       up(&(rio->lock));
+       return retval;
 }
 
 static ssize_t
@@ -234,6 +258,7 @@ write_rio(struct file *file, const char *buffer,
 
        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 @@ write_rio(struct file *file, const char *buffer,
              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 @@ write_rio(struct file *file, const char *buffer,
 
                        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 @@ write_rio(struct file *file, const char *buffer,
                };
                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_rio(struct file *file, char *buffer, size_t count, loff_t * ppos)
 
        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 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos)
                        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 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos)
                                                       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 @@ static void *probe_rio(struct usb_device *dev, unsigned int ifnum)
        }
        dbg("probe_rio: ibuf address:%p", rio->ibuf);
 
+       init_MUTEX(&(rio->lock));
+
        return rio;
 }
 
@@ -415,12 +468,11 @@ file_operations usb_rio_fops = {
 
 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 --git a/drivers/usb/serial/Config.in b/drivers/usb/serial/Config.in
new file mode 100644 (file)
index 0000000..db77957
--- /dev/null
@@ -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
index 06c4a0506ea7504cceb876d5142ec0e4afb2b0cb..d3e8a92d01f6ed5868e0944ee74f791607d3dd2c 100644 (file)
  *
  * 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
  *
  *     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>
 
 #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 void ftdi_sio_set_termios     (struct usb_serial_port *port, struct termios *
 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 @@ struct usb_serial_device_type ftdi_sio_device = {
        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 @@ struct usb_serial_device_type ftdi_sio_device = {
  * ***************************************************************************
  * 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);
+       dbg(__FUNCTION__);
 
-        /* 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 */
+       spin_lock_irqsave (&port->port_lock, flags);
+       
+       MOD_INC_USE_COUNT;
+       ++port->open_count;
 
-       /* 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);
+       if (!port->active){
+               port->active = 1;
 
-       /* Setup termios */
-       port->tty->termios->c_cflag =
-               B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+               spin_unlock_irqrestore (&port->port_lock, flags);
 
-       
-       ftdi_sio_set_termios(port, &tmp_termios);       
+               /* do not allow a task to be queued to deliver received data */
+               port->tty->low_latency = 1;
 
-       /* 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 (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");
-       }
+               /* 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*/
-       if (usb_submit_urb(port->read_urb))
-               err("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,
+                             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);
+       }
 
        return (0);
 } /* ftdi_sio_open */
@@ -229,41 +316,52 @@ static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
        struct usb_serial *serial = port->serial;
        unsigned int c_cflag = port->tty->termios->c_cflag;
        char buf[1];
-
-       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");
-               }           
-
-               /* 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");
+       unsigned long flags;
+
+       dbg( __FUNCTION__);
+
+       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 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user,
                           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 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user,
                               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_write_bulk_callback (struct urb *urb)
 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 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb)
        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 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb)
                 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 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb)
        }
 
        /* 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 @@ static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios *
 { /* 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 @@ static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios *
                            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 @@ static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios *
                                    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 @@ static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios *
                }               
                
        } 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 void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios *
 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 @@ static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, uns
                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 @@ static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, uns
                                        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 @@ static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, uns
          /* 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_init(ftdi_sio_init);
 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");
index fe5f545db327d6088b583bbf2b95dca8c208e7e2..626aeb6773150fcac63768cc645bde9bb033792f 100644 (file)
@@ -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 */
  * Data:           None
  */
 
+typedef enum {
+       sio = 1,
+       F8U232AM = 2,
+} ftdi_type_t;
+
+
 typedef enum {
  ftdi_sio_b300 = 0, 
  ftdi_sio_b600 = 1, 
@@ -98,6 +104,38 @@ typedef enum {
  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
 #define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8 )
index 7a1d02609a632b5bd6818aaa38e68d20319bc1ab..ace986765142dccb6951f1ad4960b9c0a6512660 100644 (file)
   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>
 #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_break_ctl (struct usb_serial_port *port, int break_state)
 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);
+       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;
        
-       if (p_priv->out_flip == 0) {
-               current_urb = 0;
-               p_priv->out_flip = 1;
+               /* 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;
+       }
+
+       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);
+       }
+       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 (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);
        }
+}
 
-       dbg("keyspan_write called for port %d (%d) chars {", port->number, count);
-       for (i = 0; i < count ; i++) {
-               dbg("%02x ", buf[i]);
+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;
+
+       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;
        }
-       dbg("}\n");
 
-       if (count == 0) {
-               dbg("write request of 0 bytes");
-               return (0);
+       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;
+               }
 
-               /* 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);
+               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 (__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);
+
+               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("keyspan_write_bulk_callback for endpoint %d\n", endpoint);
+       /*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;
 
-               /* Only do wakeup if this callback is from one of the data
-                  endpoints.  */
-       if (endpoint == 2 || endpoint == 3) {
-               wake_up_interruptible(&out_wait);
+               /* 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 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
        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 @@ static int keyspan_fake_startup (struct usb_serial *serial)
        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 @@ static int keyspan_fake_startup (struct usb_serial *serial)
                   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 *))
 {
-       struct keyspan_serial_private   *s_priv;
-       int                     i;
+       urb_t *urb;
 
-       s_priv = (struct keyspan_serial_private *)(serial->private);
+       if (endpoint == -1)
+               return NULL;            /* endpoint not needed */
 
-               /* Output urbs first */
-       dbg(__FUNCTION__ "Allocating output urbs.\n");
-       for (i = 0; i < 3; i++) {
+       /*  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;
+       }
 
-               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;
-               }
+               /* Fill URB using supplied data. */
+       FILL_BULK_URB(urb, serial->dev,
+                     usb_sndbulkpipe(serial->dev, endpoint) | dir,
+                     buf, len, callback, ctx);
+
+       return urb;
+}
 
-               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);
+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;
+       const keyspan_device_details    *d_details;
+       struct usb_serial_port          *port;
+       struct keyspan_port_private     *p_priv;
+       struct callbacks                *cback;
+       int                             endp;
 
-               /* Now input urbs */
-       dbg(__FUNCTION__ "Allocating input urbs.\n");
-       for (i = 0; i < 4; i++) {
+       /*  dbg (__FUNCTION__); */
 
-               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;
+       s_priv = (struct keyspan_serial_private *)(serial->private);
+       d_details = s_priv->device_details;
+
+               /* Setup values for the various callback routines */
+       cback = &keyspan_callbacks[d_details->msg_format];
+
+               /* 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);
+
+               /* 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 @@ static int keyspan_usa19_calc_baud(u32 baud_rate, u8 *rate_hi, u8 *rate_low)
                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 portControlMessage));
+       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;
+
+       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;
 
-       msg.ctsFlowControl = 0;
+       /*  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.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;
+
+       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. */
+/* 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;
        }
 
-       
-
-       switch (serial->dev->descriptor.idProduct) {
-               case 0x0107:    keyspan_usa19_setup_urbs(serial);
-                               //keyspan_send_usa19_setup(serial);
-                               break;
+       keyspan_setup_urbs(serial);
 
-               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");
index 6669461810f42d09156d8db1f09aba42c643843c..97f10cba542746a888cfaa58ffee9a72f253f66a 100644 (file)
   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_shutdown                (struct usb_serial *serial);
 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 @@ static void keyspan_break_ctl               (struct usb_serial_port *port,
                                         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 @@ struct ezusb_hex_record {
        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_usa18x_pre_device = {
 };
 
 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_usa19_pre_device = {
 
 
 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_usa19w_pre_device = {
 
 
 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_usa28_pre_device = {
 };
 
 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 @@ struct usb_serial_device_type keyspan_usa28x_pre_device = {
        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 @@ struct usb_serial_device_type keyspan_usa19_device = {
        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 @@ struct usb_serial_device_type keyspan_usa19w_device = {
        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 @@ struct usb_serial_device_type keyspan_usa28x_device = {
        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 @@ struct usb_serial_device_type keyspan_usa28x_device = {
        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
index 8f53c96e8158f47b87a21e8c5ab85b6a20edb7f9..403fd47adc29c7baa30ff3600a80b1e3fecf015a 100644 (file)
 #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 @@ typedef struct portControlMessage
                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 @@ typedef struct portControlMessage
 
 // 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 @@ typedef struct portStatusMessage    // one for each port
                _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 @@ typedef struct portStatusMessage  // one for each port
 #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
index 6378bc5b03f17e607c9dfdb106ab1a85fa491380..ad03c9c44e62dbec26916103ee99c8a718d32a07 100644 (file)
 #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 @@ typedef struct portControlMessage
                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 @@ typedef struct portStatusMessage
                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 --git a/drivers/usb/serial/keyspan_usa49msg.h b/drivers/usb/serial/keyspan_usa49msg.h
new file mode 100644 (file)
index 0000000..16ef105
--- /dev/null
@@ -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 --git a/drivers/usb/serial/keyspan_usa49w_fw.h b/drivers/usb/serial/keyspan_usa49w_fw.h
new file mode 100644 (file)
index 0000000..4e01712
--- /dev/null
@@ -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} }
+};
index b589decff93fd50da71690ab7f842011fa5fc36e..53ca79157c1c4ef404c65445c954915f71416013 100644 (file)
  *
  * 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 @@ struct usb_serial_port {
 
        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 usb_serial_device_type {
        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 */
index 506a1f702cf5606588f266e4bda5f269357e6a5a..a596681d7732fe1e95b47f7b813d10c66b53f3d0 100644 (file)
  *
  * 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_driver    serial_tty_driver;
 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 @@ static int generic_open (struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        unsigned long flags;
+       int result;
 
        if (port_paranoia_check (port, __FUNCTION__))
                return -ENODEV;
@@ -710,9 +718,17 @@ static int generic_open (struct usb_serial_port *port, struct file *filp)
 
                /* 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 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns
 {
        struct usb_serial *serial = port->serial;
        unsigned long flags;
+       int result;
 
        dbg(__FUNCTION__ " - port %d", port->number);
 
@@ -779,11 +796,19 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns
                        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 @@ static void generic_read_bulk_callback (struct urb *urb)
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int i;
+       int result;
 
        dbg(__FUNCTION__ " - port %d", port->number);
        
@@ -860,10 +886,16 @@ static void generic_read_bulk_callback (struct urb *urb)
        }
 
        /* 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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                        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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                        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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
        /* 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;
index 608afeb174e73746969e73c9e2e7175414eb1cfa..78aa59f29f45236694c5e26e1485df97fcef38b5 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -866,7 +866,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
                retval = search_binary_handler(&bprm,regs);
 
        if(current->dumpable == 2)
-               current->dumpable = 0;
+               current->dumpable = 1;
                
        if (retval >= 0)
                /* execve success */
index 98c7ec7b7a0127cffc841a36d19d1ce7ed924b72..4b0e9d95fa6492ea8ae6830616767e666606b9bf 100644 (file)
@@ -951,7 +951,7 @@ static int get_stat(int pid, char * buffer)
                        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 @@ static int process_unauthorized(int type, int pid)
                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;
 }
index c9b2d8649bf490370b69925ef43b0e0f65a5114e..dd1f06456b3a603c37c690a06fef21cc98fd54bd 100644 (file)
@@ -66,7 +66,7 @@ static void proc_pid_fill_inode(struct inode * inode, int fill)
        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;
                }
index 4b6ed72bb46e68e7e033be5bda54c97ad9feaf3f..29ed20b3bd5c9a41f4884e465eaac94885b70aab 100644 (file)
@@ -378,7 +378,7 @@ void proc_read_inode(struct inode * inode)
                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;
        }
index c8e5e25c736de711448c2090d8e2910869b5d290..b5abb16dc5902cb694b60eeb93c7f812f106079b 100644 (file)
 #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
 #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
index f784d8392338bd88509ba0807dae10d8db570db2..b5597c66f27fff78b0daaf3f0a2fac7c7c5fc464 100644 (file)
@@ -432,6 +432,7 @@ extern void sparcaudio_output_done(struct sparcaudio_driver *, int);
 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
index bd2b87f3517c3ffc30557f4d48ea61dd39a775de..1ef0bede2f602fce2ab5362fec049e5a912522a1 100644 (file)
 #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
 #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
 #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
index cca3d1303f30f135b7883f3d4a12ad894caa2580..61c6f15f0d6da72d0b291b1774f063512cf8820f 100644 (file)
@@ -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 @@ extern void *sparc_init_alloc(unsigned long *kbrk, unsigned long size);
 #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);
index fb24b8efb71708cf344f1b8afccb0cb8ed3dba6d..fdc80377a519a072ccd1454c14a93e97249c4c72 100644 (file)
@@ -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((addr),RTC_PORT(0)); \
 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
@@ -108,44 +111,4 @@ extern spinlock_t rtc_lock;        /* You must hold this lock to use CMOS_* ops */
 #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 --git a/include/linux/rtc.h b/include/linux/rtc.h
new file mode 100644 (file)
index 0000000..af61a15
--- /dev/null
@@ -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_ */
index f86259908919f4542d337d71c37c842b0dd2866e..47f7eeb94a022425d2f203e5c793fabda3cbdfbf 100644 (file)
@@ -172,7 +172,7 @@ int ip_decrease_ttl(struct iphdr *iph)
 {
        u16 check = iph->check;
        check += __constant_htons(0x0100);
-       iph->check = check + (check>=0xFFFF);
+       iph->check = check + ((check>=0xFFFF) ? 1 : 0);
        return --iph->ttl;
 }
 
index 2f4f06e2b733df234d6961aa9bfefd93538a3781..155476ec365e80a65fc93220f995247efaf2847f 100644 (file)
@@ -624,22 +624,22 @@ static struct dev_name_struct {
        { "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) },
index d7f2e31fe36b0488202c7af0f32e1fd43a605938..adfaae99d74acb5ae88763618c236b7b77ae5bc5 100644 (file)
@@ -649,7 +649,7 @@ int dev_queue_xmit(struct sk_buff *skb)
 
 
 /*=======================================================================
-                       Receiver rotutines
+                       Receiver routines
   =======================================================================*/
 
 int netdev_dropping = 0;
index ee3e276b9d8bd2c8e01a48cc566867244f7307c4..2d42a068bb900da306017b324ab9ea278c4ed4d6 100644 (file)
@@ -169,7 +169,10 @@ masq_raudio_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **
         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 @@ masq_rtsp_out (struct ip_masq_app *mapp,
         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;
 
index 032989c5a17d150baf6cb1b4466e8ea0ffd3f34f..66ff487a2fe310d29b2ed49046ccf540481a66a5 100644 (file)
@@ -7,7 +7,7 @@ then
         exit 1
 fi
 
-IFS=:
+IFS=":$IFS"
 for cmd in $*
 do
         for path in $PATH