From 75641d0781dbc7f55938b33c8ac796141d97c19d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:23:10 -0500 Subject: [PATCH] Linux 2.2.19pre7 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) --- Documentation/rtc.txt | 4 +- Makefile | 2 +- arch/alpha/mm/extable.c | 2 +- arch/arm/kernel/ptrace.c | 284 ++-- arch/arm/vmlinux-armo.lds | 69 - arch/arm/vmlinux-armv.lds | 70 - arch/i386/kernel/setup.c | 4 +- arch/sparc/defconfig | 2 + arch/sparc64/defconfig | 4 +- arch/sparc64/kernel/binfmt_aout32.c | 2 +- arch/sparc64/kernel/sparc64_ksyms.c | 8 +- arch/sparc64/kernel/sys_sunos32.c | 3 +- arch/sparc64/mm/init.c | 10 +- drivers/block/hd.c | 8 +- drivers/char/lp.c | 25 +- drivers/net/Config.in | 2 +- drivers/net/ne2k-pci.c | 12 +- drivers/net/via-rhine.c | 1 + drivers/sbus/audio/cs4215.h | 2 +- drivers/sbus/audio/dbri.c | 50 +- drivers/sbus/char/zs.c | 7 +- drivers/scsi/gdth.c | 3 + drivers/scsi/ppa.h | 5 +- drivers/sound/Makefile | 4 +- drivers/sound/ymfpci.c | 4 +- drivers/usb/Config.in | 100 +- drivers/usb/audio.c | 85 +- drivers/usb/devices.c | 4 +- drivers/usb/hid.c | 10 +- drivers/usb/rio500.c | 88 +- drivers/usb/serial/Config.in | 29 + drivers/usb/serial/ftdi_sio.c | 643 +++++---- drivers/usb/serial/ftdi_sio.h | 42 +- drivers/usb/serial/keyspan.c | 1674 +++++++++++++++++++----- drivers/usb/serial/keyspan.h | 301 ++++- drivers/usb/serial/keyspan_usa26msg.h | 28 +- drivers/usb/serial/keyspan_usa28msg.h | 28 +- drivers/usb/serial/keyspan_usa49msg.h | 255 ++++ drivers/usb/serial/keyspan_usa49w_fw.h | 457 +++++++ drivers/usb/serial/usb-serial.h | 11 +- drivers/usb/serial/usbserial.c | 59 +- fs/exec.c | 2 +- fs/proc/array.c | 4 +- fs/proc/base.c | 2 +- fs/proc/inode.c | 2 +- include/asm-sparc/asm_offsets.h | 316 ++--- include/asm-sparc/audioio.h | 1 + include/asm-sparc64/asm_offsets.h | 480 +++---- include/asm-sparc64/pgtable.h | 12 +- include/linux/mc146818rtc.h | 43 +- include/linux/rtc.h | 43 + include/net/ip.h | 2 +- init/main.c | 32 +- net/core/dev.c | 2 +- net/ipv4/ip_masq_raudio.c | 10 +- scripts/kwhich | 2 +- 56 files changed, 3770 insertions(+), 1584 deletions(-) delete mode 100644 arch/arm/vmlinux-armo.lds delete mode 100644 arch/arm/vmlinux-armv.lds create mode 100644 drivers/usb/serial/Config.in create mode 100644 drivers/usb/serial/keyspan_usa49msg.h create mode 100644 drivers/usb/serial/keyspan_usa49w_fw.h create mode 100644 include/linux/rtc.h diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt index 7718228ba551..dc35d3edcfb1 100644 --- a/Documentation/rtc.txt +++ b/Documentation/rtc.txt @@ -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 -#include +#include #include #include #include diff --git a/Makefile b/Makefile index 65a84aaeb7d5..b5b5838a3050 100644 --- 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/) diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c index acbc394cb6d7..4c203a6b1dbb 100644 --- a/arch/alpha/mm/extable.c +++ b/arch/alpha/mm/extable.c @@ -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; diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 5db89cb39235..c4dcff21abb9 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -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 index 1e9d83d9f492..000000000000 --- a/arch/arm/vmlinux-armo.lds +++ /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 - */ -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 index 4011664094c9..000000000000 --- a/arch/arm/vmlinux-armv.lds +++ /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 - */ -OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ - .rodata : { *(.rodata) } - .kstrtab : { *(.kstrtab) } - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - _etext = .; /* End of text section */ - - . = ALIGN(8192); - .data : { /* Data */ - *(.init.task) - *(.data) - CONSTRUCTORS - } - - _edata = .; /* End of data section */ - - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(16); /* __setup() commandline parameters */ - __setup_start = .; - .setup.init : { *(.setup.init) } - __setup_end = .; - - __initcall_start = .; /* the init functions to be called */ - .initcall.init : { *(.initcall.init) } - __initcall_end = .; - . = ALIGN(4096); - __init_end = .; - - - __bss_start = .; /* BSS */ - .bss : { - *(.bss) - } - _end = . ; - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 2cfa87e58840..407813049c7a 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -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; } diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index 8aebe64385c0..f6e142eba539 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -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 diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 65690f506f38..bf0c838fb1ba 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -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 diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index 98c533d88b57..c9e2d78c7561 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -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(¤t->mm->count) != 1) + if (current->dumpable != 1 || atomic_read(¤t->mm->count) != 1) return 0; current->dumpable = 0; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 934ec309b5c7..31864444f5fb 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -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); diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 7841f94975ec..f61245392da3 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -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); diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 8f35f237e60a..63c6ad5f1210 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -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 diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 4daaf76e69ab..45e8fe86a836 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -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++) { diff --git a/drivers/char/lp.c b/drivers/char/lp.c index a16a4896cc29..54d5c8751a78 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -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); diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 528c1900938e..5c53b2b83d53 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -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 diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index 38780ef045cc..af5e5efaed62 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -33,10 +33,9 @@ */ /* These identify the driver base version and may not be removed. */ -static const char version1[] = -"ne2k-pci.c:v1.02 10/19/2000 D. Becker/P. Gortmaker\n"; -static const char version2[] = -" http://www.scyld.com/network/ne2k-pci.html\n"; +static const char* version = +"ne2k-pci.c: v1.02 for Linux 2.2, 10/19/2000, D. Becker/P. Gortmaker," +" http://www.scyld.com/network/ne2k-pci.html"; #include #include @@ -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 diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 7ad2863faddf..14ccde74757a 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -81,6 +81,7 @@ static const int multicast_filter_limit = 32; #error You must compile this driver with "-O". #endif +#include #include #include #include diff --git a/drivers/sbus/audio/cs4215.h b/drivers/sbus/audio/cs4215.h index de90e2f244b0..e148279ee6e6 100644 --- a/drivers/sbus/audio/cs4215.h +++ b/drivers/sbus/audio/cs4215.h @@ -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 */ diff --git a/drivers/sbus/audio/dbri.c b/drivers/sbus/audio/dbri.c index 10307d9783fc..5f4fb45c7012 100644 --- a/drivers/sbus/audio/dbri.c +++ b/drivers/sbus/audio/dbri.c @@ -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 ********************/ diff --git a/drivers/sbus/char/zs.c b/drivers/sbus/char/zs.c index e254b7c0b720..06fdd45a4c88 100644 --- a/drivers/sbus/char/zs.c +++ b/drivers/sbus/char/zs.c @@ -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, ' '); diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index b17785525333..3b67b74d4579 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -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 */ diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h index e5af9603ffdd..3e98d1aa1961 100644 --- a/drivers/scsi/ppa.h +++ b/drivers/scsi/ppa.h @@ -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 * [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, \ diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index 5e0c5c0a737d..ac8fb955737a 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -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 diff --git a/drivers/sound/ymfpci.c b/drivers/sound/ymfpci.c index b108fae3468e..e8a6c522d056 100644 --- a/drivers/sound/ymfpci.c +++ b/drivers/sound/ymfpci.c @@ -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; diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in index 20d52b2b7a34..450029cfe2e9 100644 --- a/drivers/usb/Config.in +++ b/drivers/usb/Config.in @@ -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 diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c index 96ff9ecc70bf..a2b3784dbf4b 100644 --- a/drivers/usb/audio.c +++ b/drivers/usb/audio.c @@ -174,6 +174,7 @@ #include #include #include +#include #include #include #include @@ -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 , Thomas Sailer (sailer@ife.ee.ethz.ch)"); +MODULE_DESCRIPTION("USB Audio Class driver"); + diff --git a/drivers/usb/devices.c b/drivers/usb/devices.c index 70e0150cbfb5..e2b53b45cd65 100644 --- a/drivers/usb/devices.c +++ b/drivers/usb/devices.c @@ -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 diff --git a/drivers/usb/hid.c b/drivers/usb/hid.c index 6339ba6f18d1..8a5c22f8107e 100644 --- a/drivers/usb/hid.c +++ b/drivers/usb/hid.c @@ -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; diff --git a/drivers/usb/rio500.c b/drivers/usb/rio500.c index 59c97376e458..635780888b4a 100644 --- a/drivers/usb/rio500.c +++ b/drivers/usb/rio500.c @@ -36,6 +36,7 @@ #include #include #include +#include #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 index 000000000000..db77957a9782 --- /dev/null +++ b/drivers/usb/serial/Config.in @@ -0,0 +1,29 @@ +# +# USB Serial device configuration +# +mainmenu_option next_comment +comment 'USB Serial Converter support' + +tristate 'USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB +if [ "$CONFIG_USB_SERIAL" != "n" ]; then + bool ' USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG + bool ' USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC + dep_tristate ' USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL + dep_tristate ' USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL + dep_tristate ' USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL + dep_tristate ' USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL + dep_tristate ' USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL + dep_tristate ' USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL + dep_tristate ' USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL + dep_tristate ' USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL + if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then + bool ' USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28 + bool ' USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X + bool ' USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19 + bool ' USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X + bool ' USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W + fi + dep_tristate ' USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL +fi + +endmenu diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 06c4a0506ea7..d3e8a92d01f6 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -12,6 +12,28 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * See http://reality.sgi.com/bryder_wellington/ftdi_sio for upto date testing info + * and extra documentation + * + * (12/3/2000) Bill Ryder + * Added support for 8U232AM device. + * Moved PID and VIDs into header file only. + * Turned on low-latency for the tty (device will do high baudrates) + * Added shutdown routine to close files when device removed. + * More debug and error message cleanups. + * + * + * (11/13/2000) Bill Ryder + * Added spinlock protected open code and close code. + * Multiple opens work (sort of - see webpage mentioned above). + * Cleaned up comments. Removed multiple PID/VID definitions. + * Factorised cts/dtr code + * Made use of __FUNCTION__ in dbg's + * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * * (09/11/2000) gkh * Removed DEBUG #ifdefs with call to usb_serial_debug_data * @@ -20,11 +42,11 @@ * driver is a loadable module now. * * (04/04/2000) Bill Ryder - * Fixed bugs in TCGET/TCSET ioctls (by removing them - they are - * handled elsewhere in the serial driver chain). + * Fixed bugs in TCGET/TCSET ioctls (by removing them - they are + * handled elsewhere in the tty io driver chain). * * (03/30/2000) Bill Ryder - * Implemented lots of ioctls + * Implemented lots of ioctls * Fixed a race condition in write * Changed some dbg's to errs * @@ -36,6 +58,7 @@ /* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */ /* Thanx to FTDI for so kindly providing details of the protocol required */ /* to talk to the device */ +/* Thanx to gkh and the rest of the usb dev group for all code I have assimilated :-) */ #include @@ -64,11 +87,19 @@ #include "ftdi_sio.h" -#define FTDI_VENDOR_ID 0x0403 -#define FTDI_SIO_SERIAL_CONVERTER_ID 0x8372 + + +struct ftdi_private { + ftdi_type_t ftdi_type; + char last_status_byte; /* device sends this every 40ms when open */ + + +}; /* function prototypes for a FTDI serial converter */ static int ftdi_sio_startup (struct usb_serial *serial); +static int ftdi_8U232AM_startup (struct usb_serial *serial); +static void ftdi_sio_shutdown (struct usb_serial *serial); static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp); static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp); static int ftdi_sio_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); @@ -78,8 +109,9 @@ static 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 , Bill Ryder "); -MODULE_DESCRIPTION("USB FTDI SIO driver"); +MODULE_DESCRIPTION("USB FTDI RS232 converters driver"); diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index fe5f545db327..626aeb677315 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -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 */ @@ -85,6 +85,12 @@ * 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 ) diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7a1d02609a63..ace986765142 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -19,21 +19,33 @@ and Keyspan, Inc the manufacturers of the Keyspan USB-serial products. Thanks Guys :) + Thanks to Paulus for miscellaneous tidy ups, some largish chunks + of much nicer and/or completely new code and (perhaps most uniquely) + having the patience to sit down and explain why and where he'd changed + stuff. + Tip 'o the hat to Linuxcare for supporting staff in their work on open source projects. - Wed Jul 19 14:00:42 EST 2000 gkh - Added module_init and module_exit functions to handle the fact that this - driver is a loadable module now. - - Tue Jul 18 16:14:52 EST 2000 Hugh - Basic character input/output for USA-19 now mostly works, - fixed at 9600 baud for the moment. + Change History + Tue Oct 10 23:15:33 EST 2000 Hugh + Merged Paul's changes with my USA-49W mods. Work in progress + still... + + Wed Jul 19 14:00:42 EST 2000 gkh + Added module_init and module_exit functions to handle the fact that + this driver is a loadable module now. + + Tue Jul 18 16:14:52 EST 2000 Hugh + Basic character input/output for USA-19 now mostly works, + fixed at 9600 baud for the moment. + Sat Jul 8 11:11:48 EST 2000 Hugh + First public release - nothing works except the firmware upload. + Tested on PPC and x86 architectures, seems to behave... */ -#include #include #include #include @@ -48,53 +60,130 @@ #include #include -#ifdef CONFIG_USB_SERIAL_DEBUG +#define DEBUG +/* #ifdef CONFIG_USB_SERIAL_DEBUG */ #define DEBUG -#else - #undef DEBUG -#endif +/* #endif */ #include #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 "); -MODULE_DESCRIPTION("Keyspan USB to Serial Converter driver"); diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 6669461810f4..97f10cba5427 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -19,6 +19,11 @@ and Keyspan, Inc the manufacturers of the Keyspan USB-serial products. Thanks Guys :) + Thanks to Paulus for miscellaneous tidy ups, some largish chunks + of much nicer and/or completely new code and (perhaps most uniquely) + having the patience to sit down and explain why and where he'd changed + stuff. + Tip 'o the hat to Linuxcare for supporting staff in their work on open source projects. @@ -41,12 +46,18 @@ static void keyspan_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 diff --git a/drivers/usb/serial/keyspan_usa26msg.h b/drivers/usb/serial/keyspan_usa26msg.h index 8f53c96e8158..403fd47adc29 100644 --- a/drivers/usb/serial/keyspan_usa26msg.h +++ b/drivers/usb/serial/keyspan_usa26msg.h @@ -92,16 +92,8 @@ #ifndef __USA26MSG__ #define __USA26MSG__ -#ifndef __stubs__ -#include "datadefs.h" -#endif - -typedef struct txAckMessage -{ - u8 dummy; -} txAckMessage; -typedef struct portControlMessage +typedef struct keyspan_usa26_portControlMessage { /* there are three types of "commands" sent in the control message: @@ -172,7 +164,7 @@ 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 diff --git a/drivers/usb/serial/keyspan_usa28msg.h b/drivers/usb/serial/keyspan_usa28msg.h index 6378bc5b03f1..ad03c9c44e62 100644 --- a/drivers/usb/serial/keyspan_usa28msg.h +++ b/drivers/usb/serial/keyspan_usa28msg.h @@ -94,16 +94,8 @@ #ifndef __USA28MSG__ #define __USA28MSG__ -/*#ifndef STUBS -#include "datadefs.h" -#endif*/ -typedef struct txAckMessage -{ - u8 dummy; -} txAckMessage; - -typedef struct portControlMessage +typedef struct keyspan_usa28_portControlMessage { /* there are four types of "commands" sent in the control message: @@ -153,9 +145,9 @@ 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 index 000000000000..16ef1057e999 --- /dev/null +++ b/drivers/usb/serial/keyspan_usa49msg.h @@ -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 index 000000000000..4e01712f1931 --- /dev/null +++ b/drivers/usb/serial/keyspan_usa49w_fw.h @@ -0,0 +1,457 @@ +/* keyspan_usa49w_fw.h + + Generated from Keyspan firmware image Thu Sep 28 09:13:26 2000 EST + This firmware is for the Keyspan USA-49W Serial Adaptor + + "The firmware contained herein as keyspan_usa49w_fw.h is + Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated + ("Keyspan"), as an unpublished work. This notice does not imply + unrestricted or public access to this firmware which is a trade secret of + Keyspan, and which may not be reproduced, used, sold or transferred to any + third party without Keyspan's prior written consent. All Rights Reserved. + + This firmware may not be modified and may only be used with the Keyspan + USA-49W Serial Adapter. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in part, + requires the inclusion of this statement." + +*/ + +static const struct ezusb_hex_record keyspan_usa49w_firmware[] = { +{ 0x0000, 3, {0x02, 0x10, 0x36} }, +{ 0x0003, 16, {0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} }, +{ 0x0013, 16, {0x01, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} }, +{ 0x0023, 16, {0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} }, +{ 0x0033, 3, {0x02, 0x17, 0xf0} }, +{ 0x0036, 12, {0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} }, +{ 0x0043, 3, {0x02, 0x18, 0x00} }, +{ 0x0046, 16, {0xe4, 0xff, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x27} }, +{ 0x0056, 16, {0x24, 0x04, 0xfd, 0xe4, 0x35, 0x26, 0xfa, 0xa9, 0x05, 0x7b, 0x01, 0xef, 0x7c, 0x00, 0x29, 0xf9} }, +{ 0x0066, 16, {0xec, 0x3a, 0xfa, 0xee, 0x12, 0x11, 0x90, 0x0f, 0xbf, 0x22, 0xd7, 0xe5, 0x27, 0x24, 0x05, 0xf5} }, +{ 0x0076, 16, {0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x01, 0x4f, 0x7f, 0x01, 0xe5, 0x27} }, +{ 0x0086, 16, {0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x15, 0x3d, 0xe5, 0x27} }, +{ 0x0096, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0x6c, 0xe5, 0x27} }, +{ 0x00a6, 16, {0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x00, 0x03, 0xe5, 0x27} }, +{ 0x00b6, 16, {0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x30, 0xf0, 0x7d, 0x04, 0x44} }, +{ 0x00c6, 16, {0x20, 0xf0, 0xe5, 0x27, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x12} }, +{ 0x00d6, 16, {0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xdf, 0xf0, 0x43} }, +{ 0x00e6, 16, {0x05, 0xc0, 0xe5, 0x27, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x14} }, +{ 0x00f6, 16, {0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xdf, 0xf0, 0x43} }, +{ 0x0106, 16, {0x05, 0x0b, 0x80, 0x03, 0x43, 0x05, 0x02, 0x7f, 0x03, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x39} }, +{ 0x0116, 16, {0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04} }, +{ 0x0126, 16, {0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00} }, +{ 0x0136, 16, {0xf0, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0146, 16, {0xf5, 0x83, 0xe0, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x0b, 0xf5, 0x82, 0xe4} }, +{ 0x0156, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x32, 0xe5, 0x27, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0166, 16, {0xf5, 0x83, 0xe0, 0x54, 0x3f, 0xff, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x0176, 16, {0x83, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4} }, +{ 0x0186, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x0d, 0xf5, 0x82, 0xe4} }, +{ 0x0196, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x02, 0x6a, 0xe5, 0x27, 0x24, 0x17, 0xf5, 0x82} }, +{ 0x01a6, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x01b6, 16, {0x26, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4} }, +{ 0x01c6, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfb, 0xf0, 0xe4, 0xff, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82} }, +{ 0x01d6, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x0e, 0xf5, 0x82} }, +{ 0x01e6, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x01f6, 16, {0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4} }, +{ 0x0206, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x0216, 16, {0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x27, 0x24, 0x0f, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0226, 16, {0xf5, 0x83, 0xe0, 0x60, 0x2f, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} }, +{ 0x0236, 16, {0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x0246, 16, {0xff, 0x12, 0x14, 0xdd, 0xe5, 0x27, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x0256, 16, {0xff, 0x12, 0x15, 0x0d, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x0266, 16, {0xff, 0x12, 0x14, 0xad, 0xe5, 0x27, 0x24, 0x14, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x0276, 16, {0x60, 0x44, 0xe5, 0x27, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11} }, +{ 0x0286, 16, {0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x80} }, +{ 0x0296, 16, {0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xf0} }, +{ 0x02a6, 16, {0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x02b6, 16, {0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x12, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x02c6, 16, {0x83, 0xe0, 0x60, 0x44, 0xe5, 0x27, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x02d6, 16, {0x60, 0x11, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x02} }, +{ 0x02e6, 16, {0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x02f6, 16, {0xfd, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x0306, 16, {0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x16, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x0316, 16, {0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x27, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} }, +{ 0x0326, 16, {0xef, 0xf0, 0xe5, 0x27, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe0} }, +{ 0x0336, 16, {0x11, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x40, 0xf0} }, +{ 0x0346, 16, {0x80, 0x0f, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xbf} }, +{ 0x0356, 16, {0xf0, 0xe5, 0x27, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x27} }, +{ 0x0366, 16, {0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x27, 0x24, 0x19, 0xf5} }, +{ 0x0376, 16, {0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4} }, +{ 0x0386, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82} }, +{ 0x0396, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5} }, +{ 0x03a6, 16, {0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5} }, +{ 0x03b6, 16, {0x27, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x6b, 0xe5, 0x27, 0x24} }, +{ 0x03c6, 16, {0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} }, +{ 0x03d6, 16, {0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f} }, +{ 0x03e6, 16, {0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0xfe} }, +{ 0x03f6, 16, {0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x0406, 16, {0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x2c, 0xf5, 0x82} }, +{ 0x0416, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x27, 0x24, 0x2b, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0426, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x0436, 16, {0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x0446, 16, {0x83, 0xe0, 0x60, 0x28, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x0456, 16, {0x44, 0x02, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x2b, 0xf5, 0x82} }, +{ 0x0466, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x1c} }, +{ 0x0476, 16, {0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82} }, +{ 0x0486, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x2c, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27} }, +{ 0x0496, 16, {0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0} }, +{ 0x04a6, 16, {0xe4, 0xff, 0x12, 0x14, 0x0c, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} }, +{ 0x04b6, 16, {0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x04c6, 16, {0x60, 0x27, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x40} }, +{ 0x04d6, 16, {0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x04e6, 16, {0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x1e, 0xf5, 0x82, 0xe4} }, +{ 0x04f6, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0506, 16, {0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24} }, +{ 0x0516, 16, {0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5} }, +{ 0x0526, 16, {0x27, 0x24, 0x1f, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24} }, +{ 0x0536, 16, {0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x27, 0x24, 0x32, 0xf5} }, +{ 0x0546, 16, {0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15} }, +{ 0x0556, 16, {0x3d, 0xe5, 0x27, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28} }, +{ 0x0566, 16, {0x42, 0x25, 0xe5, 0x27, 0x24, 0x20, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e} }, +{ 0x0576, 16, {0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x18, 0x90, 0x78} }, +{ 0x0586, 16, {0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x0596, 16, {0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x05a6, 16, {0x83, 0xe0, 0x60, 0x0f, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x05b6, 16, {0x44, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60} }, +{ 0x05c6, 16, {0x1f, 0xe5, 0x27, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5} }, +{ 0x05d6, 16, {0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28, 0x42, 0x25} }, +{ 0x05e6, 16, {0xe5, 0x27, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x12, 0x17} }, +{ 0x05f6, 16, {0x4e, 0xe5, 0x27, 0x24, 0x24, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x1b, 0xe5} }, +{ 0x0606, 16, {0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f} }, +{ 0x0616, 16, {0x98, 0xe0, 0xff, 0xe5, 0x28, 0xf4, 0xfe, 0xef, 0x5e, 0xf0, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82} }, +{ 0x0626, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x16, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x0636, 14, {0x26, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x28, 0xf0} }, +{ 0x0644, 1, {0x22} }, +{ 0x0645, 16, {0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x11, 0xa2, 0x07, 0x42, 0x00, 0x07, 0xb6, 0x01, 0x08, 0x22, 0x03} }, +{ 0x0655, 16, {0x06, 0x68, 0x06, 0x07, 0x35, 0x08, 0x07, 0x2f, 0x09, 0x07, 0x17, 0x0a, 0x07, 0x26, 0x0b, 0x00} }, +{ 0x0665, 16, {0x00, 0x08, 0x71, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x77, 0x24, 0x02} }, +{ 0x0675, 16, {0x60, 0x03, 0x02, 0x07, 0x0d, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} }, +{ 0x0685, 16, {0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0} }, +{ 0x0695, 16, {0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe0, 0x04, 0x7f, 0x03, 0x80, 0x02, 0x7f, 0x02, 0x75, 0x82, 0x82} }, +{ 0x06a5, 16, {0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x6d, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75} }, +{ 0x06b5, 16, {0x83, 0x19, 0xf0, 0x75, 0x82, 0x5f, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19} }, +{ 0x06c5, 16, {0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe1, 0x04, 0x7f, 0x64, 0x80, 0x02, 0x7f, 0x32, 0x75, 0x82} }, +{ 0x06d5, 16, {0x1a, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f} }, +{ 0x06e5, 16, {0xd5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x13, 0x54, 0xea, 0x49, 0x60} }, +{ 0x06f5, 16, {0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f} }, +{ 0x0705, 16, {0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02} }, +{ 0x0715, 16, {0x08, 0x78, 0x90, 0x7f, 0x00, 0xe5, 0x0a, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08} }, +{ 0x0725, 16, {0x78, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x0a, 0x02, 0x08, 0x78, 0x12, 0x0a, 0x6a, 0x02, 0x08, 0x78} }, +{ 0x0735, 16, {0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xe8} }, +{ 0x0745, 16, {0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33} }, +{ 0x0755, 16, {0xff, 0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0} }, +{ 0x0765, 16, {0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0} }, +{ 0x0775, 16, {0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80} }, +{ 0x0785, 16, {0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4} }, +{ 0x0795, 16, {0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f} }, +{ 0x07a5, 16, {0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08} }, +{ 0x07b5, 16, {0x78, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x08, 0x78} }, +{ 0x07c5, 16, {0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0} }, +{ 0x07d5, 16, {0x44, 0x01, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0} }, +{ 0x07e5, 16, {0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} }, +{ 0x07f5, 16, {0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff} }, +{ 0x0805, 16, {0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44} }, +{ 0x0815, 16, {0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8} }, +{ 0x0825, 16, {0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04} }, +{ 0x0835, 16, {0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea} }, +{ 0x0845, 16, {0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0} }, +{ 0x0855, 16, {0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01} }, +{ 0x0865, 16, {0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0} }, +{ 0x0875, 10, {0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} }, +{ 0x087f, 1, {0x22} }, +{ 0x0880, 16, {0xe5, 0x23, 0x54, 0x0f, 0x70, 0x03, 0x02, 0x09, 0x5f, 0x12, 0x15, 0x9b, 0xef, 0x20, 0xe1, 0x63} }, +{ 0x0890, 16, {0x12, 0x15, 0xf9, 0xef, 0x14, 0xf5, 0x1a, 0x12, 0x17, 0xc1, 0xef, 0x25, 0x1a, 0xff, 0xe4, 0x33} }, +{ 0x08a0, 16, {0xfe, 0xc3, 0xef, 0x94, 0x80, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x47, 0x85, 0x27, 0x82, 0x85} }, +{ 0x08b0, 16, {0x26, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5} }, +{ 0x08c0, 16, {0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f} }, +{ 0x08d0, 16, {0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0x85} }, +{ 0x08e0, 16, {0x1a, 0x08, 0xef, 0x24, 0x01, 0xf5, 0x10, 0xe4, 0x3e, 0xf5, 0x0f, 0x12, 0x13, 0xd6, 0xe4, 0xff} }, +{ 0x08f0, 16, {0x12, 0x14, 0x0c, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30} }, +{ 0x0900, 16, {0xe7, 0x5d, 0x12, 0x17, 0xc1, 0xe5, 0x27, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} }, +{ 0x0910, 16, {0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x48, 0xe5, 0x27, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0920, 16, {0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} }, +{ 0x0930, 16, {0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4} }, +{ 0x0940, 16, {0xf0, 0xe5, 0x28, 0x42, 0x25, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x10, 0xe5, 0x27, 0x24, 0x26} }, +{ 0x0950, 16, {0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xf5, 0x09, 0x80, 0x03, 0x12, 0x12, 0x3d, 0x12} }, +{ 0x0960, 16, {0x15, 0xca, 0xef, 0x30, 0xe1, 0x03, 0x02, 0x0a, 0x69, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4} }, +{ 0x0970, 16, {0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x80, 0xf0, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x0980, 16, {0x26, 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x17, 0xcd, 0xee, 0x4f, 0xd0, 0x82} }, +{ 0x0990, 16, {0xd0, 0x83, 0xf0, 0x12, 0x16, 0xd1, 0x8f, 0x1a, 0xe5, 0x27, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x09a0, 16, {0x26, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x28, 0x12, 0x17, 0xa9, 0xef, 0x30, 0xe0} }, +{ 0x09b0, 16, {0x21, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x20, 0xe7, 0x12} }, +{ 0x09c0, 16, {0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x03, 0x02} }, +{ 0x09d0, 16, {0x0a, 0x69, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfd} }, +{ 0x09e0, 16, {0xf0, 0xe5, 0x1a, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} }, +{ 0x09f0, 16, {0xe4, 0xf0, 0x22, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff} }, +{ 0x0a00, 16, {0x30, 0xe7, 0x29, 0xe5, 0x1a, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x1a, 0x20, 0x85, 0x1a, 0x08} }, +{ 0x0a10, 16, {0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0x8c, 0x0f, 0xf5, 0x10} }, +{ 0x0a20, 16, {0x12, 0x13, 0x06, 0xe5, 0x1a, 0x25, 0xe0, 0xff, 0x12, 0x14, 0x42, 0x22, 0xe5, 0x1a, 0xd3, 0x94} }, +{ 0x0a30, 16, {0x3f, 0x40, 0x03, 0x75, 0x1a, 0x3f, 0x85, 0x1a, 0x08, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3} }, +{ 0x0a40, 16, {0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x85, 0x27, 0x82, 0x85, 0x26} }, +{ 0x0a50, 16, {0x83, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x24, 0x01, 0xf5, 0x10, 0xe4, 0x3e, 0xf5, 0x0f, 0x12} }, +{ 0x0a60, 9, {0x13, 0x95, 0xe5, 0x1a, 0x04, 0xff, 0x12, 0x14, 0x42} }, +{ 0x0a69, 1, {0x22} }, +{ 0x0a6a, 16, {0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4} }, +{ 0x0a7a, 16, {0x90, 0x7f, 0x94, 0xf0, 0x90, 0x78, 0x4a, 0x04, 0xf0, 0xf5, 0x8e, 0x90, 0x7f, 0x95, 0x74, 0xc0} }, +{ 0x0a8a, 16, {0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x1f, 0xf0, 0x90, 0x78, 0x43} }, +{ 0x0a9a, 16, {0x74, 0xff, 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x9f, 0xf0, 0x90, 0x7f} }, +{ 0x0aaa, 16, {0xde, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b} }, +{ 0x0aba, 16, {0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x0e, 0xb3, 0x7e} }, +{ 0x0aca, 16, {0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75} }, +{ 0x0ada, 16, {0x28, 0x01, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0x7e} }, +{ 0x0aea, 16, {0x7e, 0x7f, 0x40, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x40, 0xf0} }, +{ 0x0afa, 16, {0x7e, 0x7e, 0x7f, 0x80, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3} }, +{ 0x0b0a, 16, {0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x00, 0x90, 0x7f, 0x96} }, +{ 0x0b1a, 16, {0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x0e, 0xb3, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c} }, +{ 0x0b2a, 16, {0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0xe5, 0x27, 0x24, 0x26} }, +{ 0x0b3a, 16, {0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x7e, 0x7d, 0x7f, 0xc0, 0x85, 0x27} }, +{ 0x0b4a, 16, {0x82, 0x85, 0x26, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0xc0, 0xf0, 0x7e, 0x7e, 0x7f, 0x00, 0x85} }, +{ 0x0b5a, 16, {0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0x7e, 0x7c} }, +{ 0x0b6a, 16, {0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28} }, +{ 0x0b7a, 16, {0x04, 0x12, 0x0e, 0xb3, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f} }, +{ 0x0b8a, 16, {0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0b9a, 16, {0xf5, 0x83, 0x74, 0x02, 0xf0, 0x7e, 0x7d, 0x7f, 0x40, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74} }, +{ 0x0baa, 16, {0x7d, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7d, 0x7f, 0x80, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83} }, +{ 0x0bba, 16, {0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c} }, +{ 0x0bca, 16, {0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x0e, 0xb3, 0x7e} }, +{ 0x0bda, 16, {0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75} }, +{ 0x0bea, 16, {0x28, 0x08, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x03, 0xf0} }, +{ 0x0bfa, 16, {0x7e, 0x7c, 0x7f, 0xc0, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74, 0x7c, 0xf0, 0xa3, 0x74, 0xc0} }, +{ 0x0c0a, 16, {0xf0, 0x7e, 0x7d, 0x7f, 0x00, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0} }, +{ 0x0c1a, 7, {0xa3, 0x74, 0x00, 0xf0, 0xd2, 0x02, 0x22} }, +{ 0x0c21, 16, {0xe5, 0x22, 0x04, 0x54, 0x03, 0xf5, 0x22, 0x14, 0x60, 0x1f, 0x14, 0x60, 0x31, 0x14, 0x60, 0x43} }, +{ 0x0c31, 16, {0x24, 0x03, 0x70, 0x52, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f} }, +{ 0x0c41, 16, {0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x80, 0x3d, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c} }, +{ 0x0c51, 16, {0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x80, 0x28, 0x7e, 0x7c} }, +{ 0x0c61, 16, {0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28} }, +{ 0x0c71, 16, {0x04, 0x80, 0x13, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96} }, +{ 0x0c81, 16, {0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0xe5, 0x15, 0x55, 0x28, 0x70, 0x03, 0x02, 0x0d, 0xbf, 0xe5} }, +{ 0x0c91, 16, {0x28, 0xf4, 0xff, 0x52, 0x15, 0xe5, 0x0b, 0x54, 0x7f, 0xfe, 0x70, 0x0f, 0xe5, 0x0d, 0x55, 0x28} }, +{ 0x0ca1, 16, {0x60, 0x24, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x28, 0xf0, 0x80, 0x1b, 0xbe, 0x20, 0x18, 0xe5, 0x27} }, +{ 0x0cb1, 16, {0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe3, 0x09, 0xe4, 0xf5, 0x0d} }, +{ 0x0cc1, 16, {0x90, 0x7f, 0x98, 0xe0, 0x5f, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x0cd1, 16, {0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe5, 0x27, 0x24, 0x34, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0ce1, 16, {0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe0, 0x60, 0x03, 0x02, 0x0d, 0xbf, 0x74, 0x0a} }, +{ 0x0cf1, 16, {0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0x01, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x2c, 0xf5, 0x82} }, +{ 0x0d01, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x1a, 0xf0, 0xe5, 0x28, 0x42, 0x25} }, +{ 0x0d11, 16, {0x12, 0x17, 0xd9, 0x8f, 0x1a, 0xe5, 0x27, 0x24, 0x27, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} }, +{ 0x0d21, 16, {0xe0, 0xff, 0xe5, 0x1a, 0x54, 0x10, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x28, 0x42, 0x25} }, +{ 0x0d31, 16, {0xe5, 0x27, 0x24, 0x28, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1a, 0x54} }, +{ 0x0d41, 16, {0x80, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x29, 0xf5} }, +{ 0x0d51, 16, {0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1a, 0x54, 0x20, 0xfe, 0x6f, 0x60, 0x15} }, +{ 0x0d61, 16, {0xee, 0xf0, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe4} }, +{ 0x0d71, 16, {0x04, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x24, 0x55, 0x28, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x2a} }, +{ 0x0d81, 16, {0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x16, 0xe5, 0x1a, 0xf0, 0xe5, 0x27} }, +{ 0x0d91, 16, {0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe5, 0x04, 0xe5, 0x28, 0x42} }, +{ 0x0da1, 16, {0x25, 0xe5, 0x29, 0x55, 0x28, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x0db1, 14, {0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x1a, 0xf0, 0xe5, 0x28, 0x42, 0x25} }, +{ 0x0dbf, 1, {0x22} }, +{ 0x0dc0, 16, {0xe5, 0x09, 0x14, 0x60, 0x2a, 0x14, 0x60, 0x41, 0x14, 0x60, 0x58, 0x14, 0x60, 0x6f, 0x24, 0x04} }, +{ 0x0dd0, 16, {0x60, 0x03, 0x02, 0x0e, 0x77, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90} }, +{ 0x0de0, 16, {0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x01, 0x22, 0x7e} }, +{ 0x0df0, 16, {0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75} }, +{ 0x0e00, 16, {0x28, 0x02, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x02, 0x22, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c} }, +{ 0x0e10, 16, {0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0x12, 0x12, 0x3d, 0x75} }, +{ 0x0e20, 16, {0x09, 0x03, 0x22, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96} }, +{ 0x0e30, 16, {0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x04, 0x22, 0x30, 0x04, 0x33} }, +{ 0x0e40, 16, {0xc2, 0x04, 0x53, 0x25, 0xdf, 0xe4, 0xf5, 0x1a, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x11, 0x25, 0x1a} }, +{ 0x0e50, 16, {0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0x4a, 0xff, 0x74, 0x80, 0x25, 0x1a, 0xf5, 0x82, 0xe4} }, +{ 0x0e60, 16, {0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1a, 0xe5, 0x1a, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3} }, +{ 0x0e70, 16, {0x74, 0x03, 0xf0, 0x75, 0x09, 0x05, 0x22, 0xe5, 0x17, 0x60, 0x34, 0xd5, 0x17, 0x03, 0x53, 0x25} }, +{ 0x0e80, 16, {0xef, 0xe4, 0xf5, 0x1a, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x16, 0x25, 0x1a, 0xf9, 0xee, 0x34, 0x00} }, +{ 0x0e90, 16, {0xfa, 0x12, 0x11, 0x4a, 0xff, 0x74, 0x80, 0x25, 0x1a, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83} }, +{ 0x0ea0, 16, {0xef, 0xf0, 0x05, 0x1a, 0xe5, 0x1a, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4} }, +{ 0x0eb0, 2, {0xf5, 0x09} }, +{ 0x0eb2, 1, {0x22} }, +{ 0x0eb3, 16, {0xe4, 0xf5, 0x19, 0x7e, 0x00, 0x7b, 0x01, 0xe5, 0x27, 0x25, 0x19, 0xf9, 0xee, 0x35, 0x26, 0xfa} }, +{ 0x0ec3, 16, {0xe4, 0x12, 0x11, 0x90, 0x05, 0x19, 0xe5, 0x19, 0xb4, 0x3c, 0xe8, 0xe5, 0x27, 0x24, 0x35, 0xf5} }, +{ 0x0ed3, 16, {0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5} }, +{ 0x0ee3, 16, {0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00} }, +{ 0x0ef3, 16, {0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x15, 0x3d, 0x7f, 0x10, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82} }, +{ 0x0f03, 16, {0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0x12, 0x14, 0xad, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0} }, +{ 0x0f13, 16, {0x7f, 0x01, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0x44} }, +{ 0x0f23, 16, {0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5} }, +{ 0x0f33, 16, {0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, 0xfd} }, +{ 0x0f43, 16, {0x12, 0x15, 0x3d, 0xe4, 0xff, 0x7e, 0xa3, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26} }, +{ 0x0f53, 16, {0xf5, 0x83, 0xee, 0xf0, 0xfd, 0x12, 0x15, 0x3d, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0} }, +{ 0x0f63, 16, {0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x15, 0x3d, 0x7f, 0x01, 0x12, 0x14, 0x78, 0x7f} }, +{ 0x0f73, 6, {0x03, 0x7d, 0x07, 0x12, 0x15, 0x3d} }, +{ 0x0f79, 1, {0x22} }, +{ 0x0f7a, 16, {0x53, 0x25, 0x3f, 0x90, 0x7b, 0xf1, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26} }, +{ 0x0f8a, 16, {0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x08, 0x80} }, +{ 0x0f9a, 16, {0x90, 0x7c, 0x31, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27} }, +{ 0x0faa, 16, {0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x08, 0x80, 0x90, 0x7c, 0x71} }, +{ 0x0fba, 16, {0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f} }, +{ 0x0fca, 16, {0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0x12, 0x08, 0x80, 0x90, 0x7c, 0xb1, 0xe0, 0x30, 0xe3} }, +{ 0x0fda, 16, {0x16, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f} }, +{ 0x0fea, 16, {0xf0, 0x75, 0x28, 0x08, 0x12, 0x08, 0x80, 0x05, 0x23, 0xe5, 0x23, 0x54, 0x0f, 0xf5, 0x19, 0x70} }, +{ 0x0ffa, 16, {0x1f, 0x90, 0x78, 0x41, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf5, 0x29, 0x90, 0x78} }, +{ 0x100a, 16, {0x41, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf4, 0xf5, 0x24, 0x12, 0x10, 0xc2, 0x22} }, +{ 0x101a, 16, {0xe5, 0x19, 0xb4, 0x01, 0x04, 0x12, 0x0c, 0x21, 0x22, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x08} }, +{ 0x102a, 11, {0xe5, 0x25, 0x60, 0x04, 0x12, 0x0d, 0xc0, 0x22, 0x12, 0x0c, 0x21} }, +{ 0x1035, 1, {0x22} }, +{ 0x1036, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x29, 0x02, 0x10, 0x7d} }, +{ 0x1042, 16, {0x02, 0x11, 0xc8, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, +{ 0x1052, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, +{ 0x1062, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, +{ 0x1072, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x17, 0x67, 0xe4, 0x7e} }, +{ 0x1082, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, +{ 0x1092, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, +{ 0x10a2, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, +{ 0x10b2, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, +{ 0x10c2, 16, {0x90, 0x7f, 0xd2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0x49, 0x90, 0x7b, 0x40, 0xe0, 0x14, 0x60} }, +{ 0x10d2, 16, {0x26, 0x14, 0x60, 0x3b, 0x14, 0x60, 0x50, 0x24, 0x83, 0x60, 0x64, 0x24, 0x80, 0x70, 0x63, 0x7e} }, +{ 0x10e2, 16, {0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75} }, +{ 0x10f2, 16, {0x28, 0x01, 0x12, 0x00, 0x46, 0x80, 0x4b, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27} }, +{ 0x1102, 16, {0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x00, 0x46, 0x80, 0x33, 0x7e} }, +{ 0x1112, 16, {0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75} }, +{ 0x1122, 16, {0x28, 0x04, 0x12, 0x00, 0x46, 0x80, 0x1b, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27} }, +{ 0x1132, 16, {0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x00, 0x46, 0x80, 0x03, 0x12} }, +{ 0x1142, 8, {0x16, 0x56, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x22} }, +{ 0x114a, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, +{ 0x115a, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, +{ 0x1163, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, +{ 0x1173, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, +{ 0x1183, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, +{ 0x1190, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} }, +{ 0x11a0, 2, {0xf3, 0x22} }, +{ 0x11a2, 16, {0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} }, +{ 0x11b2, 16, {0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} }, +{ 0x11c2, 6, {0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} }, +{ 0x11c8, 16, {0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x00, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8} }, +{ 0x11d8, 16, {0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab} }, +{ 0x11e8, 16, {0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} }, +{ 0x11f8, 16, {0xaf, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x09, 0x12, 0x17} }, +{ 0x1208, 16, {0x13, 0xc2, 0x01, 0xe4, 0xf5, 0x0e, 0xf5, 0x14, 0xc2, 0x07, 0xc2, 0x02, 0x90, 0x7f, 0xd8, 0xe0} }, +{ 0x1218, 16, {0x65, 0x0b, 0x60, 0x06, 0x75, 0x15, 0x0f, 0xe0, 0xf5, 0x0b, 0x30, 0x02, 0x03, 0x12, 0x0f, 0x7a} }, +{ 0x1228, 16, {0x30, 0x01, 0x07, 0xc2, 0x01, 0x12, 0x06, 0x45, 0x80, 0xe2, 0x30, 0x08, 0xdf, 0xc2, 0x08, 0x12} }, +{ 0x1238, 5, {0x17, 0x95, 0x80, 0xd8, 0x22} }, +{ 0x123d, 16, {0xe5, 0x25, 0x55, 0x28, 0x60, 0x6a, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x124d, 16, {0x83, 0xe0, 0x70, 0x5c, 0xe5, 0x28, 0xf4, 0x52, 0x25, 0xe5, 0x27, 0x24, 0x26, 0xff, 0xe4, 0x35} }, +{ 0x125d, 16, {0x26, 0xfe, 0xe4, 0xfd, 0x0f, 0xef, 0xaa, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8a, 0x83} }, +{ 0x126d, 16, {0xe0, 0xfc, 0x74, 0x80, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0xbd} }, +{ 0x127d, 16, {0x0b, 0xe2, 0x90, 0x7f, 0xc3, 0x74, 0x0b, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x128d, 16, {0x26, 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xe5, 0x27, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x129d, 16, {0x83, 0xe4, 0xf0, 0xe5, 0x27, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0} }, +{ 0x12ad, 1, {0x22} }, +{ 0x12ae, 16, {0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4} }, +{ 0x12be, 16, {0x90, 0x78, 0x4a, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90} }, +{ 0x12ce, 16, {0x7f, 0x97, 0xf0, 0xe5, 0x0c, 0x54, 0xf0, 0x44, 0x08, 0x90, 0x78, 0x41, 0xf0, 0xe4, 0x90, 0x7f} }, +{ 0x12de, 16, {0x98, 0xf0, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98} }, +{ 0x12ee, 16, {0xf0, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} }, +{ 0x12fe, 8, {0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x22} }, +{ 0x1306, 16, {0x8f, 0x1b, 0x05, 0x10, 0xe5, 0x10, 0xae, 0x0f, 0x70, 0x02, 0x05, 0x0f, 0x14, 0xf5, 0x82, 0x8e} }, +{ 0x1316, 16, {0x83, 0xe5, 0x1b, 0xf0, 0x12, 0x17, 0xe5, 0x05, 0x10, 0xe5, 0x10, 0xac, 0x0f, 0x70, 0x02, 0x05} }, +{ 0x1326, 16, {0x0f, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x1f, 0xe5, 0x27} }, +{ 0x1336, 16, {0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12} }, +{ 0x1346, 14, {0x17, 0xcd, 0x8f, 0x1b, 0xee, 0x4f, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x80, 0xb5, 0x22} }, +{ 0x1354, 2, {0x8f, 0x19} }, +{ 0x1356, 16, {0xe4, 0xf5, 0x1a, 0x75, 0x1b, 0xff, 0x75, 0x1c, 0x19, 0x75, 0x1d, 0x86, 0xab, 0x1b, 0xaa, 0x1c} }, +{ 0x1366, 16, {0xa9, 0x1d, 0x90, 0x00, 0x01, 0x12, 0x11, 0x63, 0xb4, 0x03, 0x1d, 0xaf, 0x1a, 0x05, 0x1a, 0xef} }, +{ 0x1376, 16, {0xb5, 0x19, 0x01, 0x22, 0x12, 0x11, 0x4a, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, +{ 0x1386, 14, {0x1b, 0xff, 0xf5, 0x1c, 0x89, 0x1d, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, +{ 0x1394, 1, {0x22} }, +{ 0x1395, 16, {0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x78, 0x4f, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x50, 0xf0} }, +{ 0x13a5, 16, {0xe5, 0x0f, 0x90, 0x78, 0x51, 0xf0, 0xae, 0x0f, 0xe5, 0x10, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78} }, +{ 0x13b5, 16, {0x54, 0xe5, 0x08, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x10} }, +{ 0x13c5, 16, {0xf0, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa} }, +{ 0x13d5, 1, {0x22} }, +{ 0x13d6, 16, {0xe4, 0x90, 0x78, 0x41, 0xf0, 0xe5, 0x0f, 0x90, 0x78, 0x4f, 0xf0, 0xae, 0x0f, 0xe5, 0x10, 0x90} }, +{ 0x13e6, 16, {0x78, 0x50, 0xf0, 0x90, 0x78, 0x51, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78} }, +{ 0x13f6, 16, {0x54, 0xe5, 0x08, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90} }, +{ 0x1406, 6, {0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22} }, +{ 0x140c, 16, {0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14} }, +{ 0x141c, 16, {0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f} }, +{ 0x142c, 16, {0xc9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xcb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xcd, 0xef} }, +{ 0x143c, 6, {0xf0, 0xe5, 0x28, 0x42, 0x0d, 0x22} }, +{ 0x1442, 16, {0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14} }, +{ 0x1452, 16, {0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xb7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f} }, +{ 0x1462, 16, {0xb9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xbb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xbd, 0xef} }, +{ 0x1472, 6, {0xf0, 0xe5, 0x28, 0x42, 0x0d, 0x22} }, +{ 0x1478, 16, {0xae, 0x07, 0xe4, 0xff, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} }, +{ 0x1488, 16, {0x54, 0x7f, 0xfd, 0x12, 0x15, 0x3d, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xee} }, +{ 0x1498, 16, {0xf0, 0xe4, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80} }, +{ 0x14a8, 5, {0xfd, 0x12, 0x15, 0x3d, 0x22} }, +{ 0x14ad, 16, {0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} }, +{ 0x14bd, 16, {0x02, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} }, +{ 0x14cd, 16, {0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} }, +{ 0x14dd, 16, {0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} }, +{ 0x14ed, 16, {0x04, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} }, +{ 0x14fd, 16, {0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} }, +{ 0x150d, 16, {0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} }, +{ 0x151d, 16, {0x06, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} }, +{ 0x152d, 16, {0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} }, +{ 0x153d, 16, {0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} }, +{ 0x154d, 16, {0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x07, 0xf0, 0x90, 0xc0} }, +{ 0x155d, 15, {0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22} }, +{ 0x156c, 16, {0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0xe4, 0x90, 0x78, 0x41} }, +{ 0x157c, 16, {0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37} }, +{ 0x158c, 15, {0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} }, +{ 0x159b, 16, {0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} }, +{ 0x15ab, 16, {0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc8} }, +{ 0x15bb, 15, {0xe0, 0xff, 0x22, 0x90, 0x7f, 0xca, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcc, 0xe0, 0xff, 0x22} }, +{ 0x15ca, 16, {0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} }, +{ 0x15da, 16, {0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xb6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xb8} }, +{ 0x15ea, 15, {0xe0, 0xff, 0x22, 0x90, 0x7f, 0xba, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xbc, 0xe0, 0xff, 0x22} }, +{ 0x15f9, 16, {0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} }, +{ 0x1609, 16, {0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc9} }, +{ 0x1619, 15, {0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcb, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcd, 0xe0, 0xff, 0x22} }, +{ 0x1628, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} }, +{ 0x1638, 16, {0x05, 0x04, 0xc2, 0x05, 0x80, 0x02, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} }, +{ 0x1648, 14, {0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x1656, 16, {0x90, 0x7b, 0x41, 0xe0, 0xf5, 0x17, 0x43, 0x25, 0x10, 0xa3, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7} }, +{ 0x1666, 16, {0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0x90, 0x7b, 0x43, 0xe0, 0xf5, 0x18, 0x30, 0x00, 0x07, 0xa3} }, +{ 0x1676, 10, {0xe0, 0x54, 0xf0, 0xf5, 0x0c, 0x22, 0xe4, 0xf5, 0x0c, 0x22} }, +{ 0x1680, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} }, +{ 0x1690, 16, {0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} }, +{ 0x16a0, 10, {0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x16aa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} }, +{ 0x16ba, 16, {0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} }, +{ 0x16ca, 7, {0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x16d1, 16, {0x12, 0x17, 0xb5, 0xae, 0x07, 0x12, 0x17, 0xb5, 0xad, 0x07, 0xee, 0x6d, 0x60, 0x10, 0x12, 0x17} }, +{ 0x16e1, 16, {0xb5, 0xae, 0x07, 0xee, 0x6d, 0x60, 0x07, 0x12, 0x17, 0xb5, 0xad, 0x07, 0x80, 0xec, 0xaf, 0x06} }, +{ 0x16f1, 1, {0x22} }, +{ 0x16f2, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, +{ 0x1702, 1, {0x22} }, +{ 0x1703, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} }, +{ 0x1713, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x04, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x09, 0x04, 0xe0, 0x44} }, +{ 0x1723, 16, {0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x17, 0x34, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, +{ 0x1733, 1, {0x22} }, +{ 0x1734, 16, {0x8e, 0x19, 0x8f, 0x1a, 0xe5, 0x1a, 0x15, 0x1a, 0xae, 0x19, 0x70, 0x02, 0x15, 0x19, 0x4e, 0x60} }, +{ 0x1744, 10, {0x08, 0x12, 0x16, 0xf2, 0x12, 0x16, 0xf2, 0x80, 0xeb, 0x22} }, +{ 0x174e, 16, {0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x04, 0xff, 0x44, 0x10} }, +{ 0x175e, 9, {0x90, 0x7f, 0xd7, 0xf0, 0xef, 0x44, 0x30, 0xf0, 0x22} }, +{ 0x1767, 16, {0x03, 0x16, 0x80, 0x00, 0x00, 0x03, 0x11, 0x81, 0x00, 0x00, 0xc1, 0x85, 0xc1, 0x81, 0xc1, 0x08} }, +{ 0x1777, 7, {0xc1, 0x00, 0xc1, 0x86, 0x01, 0x09, 0x00} }, +{ 0x177e, 1, {0x00} }, +{ 0x177f, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x17, 0x34, 0x90, 0x7f} }, +{ 0x178f, 6, {0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22} }, +{ 0x1795, 16, {0x12, 0x12, 0xae, 0x12, 0x17, 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x03, 0x12, 0x17, 0x7f} }, +{ 0x17a5, 4, {0x12, 0x0a, 0x6a, 0x22} }, +{ 0x17a9, 12, {0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} }, +{ 0x17b5, 12, {0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} }, +{ 0x17c1, 12, {0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} }, +{ 0x17cd, 12, {0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} }, +{ 0x17d9, 12, {0x90, 0x78, 0x41, 0x74, 0x06, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} }, +{ 0x17e5, 11, {0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} }, +{ 0x17f0, 4, {0x53, 0xd8, 0xef, 0x32} }, +{ 0x1800, 15, {0x02, 0x16, 0xaa, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, 0x16, 0x80, 0x00, 0x02, 0x16, 0x28} }, +{ 0x1900, 16, {0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x0a, 0x01, 0x00, 0x00, 0x01, 0x02} }, +{ 0x1910, 16, {0x00, 0x04, 0x09, 0x02, 0x74, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e} }, +{ 0x1920, 16, {0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} }, +{ 0x1930, 16, {0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00} }, +{ 0x1940, 16, {0x07, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} }, +{ 0x1950, 16, {0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02} }, +{ 0x1960, 16, {0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00} }, +{ 0x1970, 16, {0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07} }, +{ 0x1980, 16, {0x05, 0x87, 0x02, 0x40, 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00} }, +{ 0x1990, 16, {0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00} }, +{ 0x19a0, 16, {0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00} }, +{ 0x19b0, 16, {0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00} }, +{ 0x19c0, 16, {0x6f, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} }, +{ 0x19d0, 16, {0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00} }, +{ 0x19e0, 16, {0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00} }, +{ 0x19f0, 16, {0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00} }, +{ 0x1a00, 10, {0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00} }, +{ 0xffff, 0, {0x00} } +}; diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index b589decff93f..53ca79157c1c 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -11,6 +11,11 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (10/05/2000) gkh + * Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help + * fix bug with urb->dev not being set properly, now that the usb core + * needs it. + * * (09/11/2000) gkh * Added usb_serial_debug_data function to help get rid of #DEBUG in the * drivers. @@ -57,9 +62,11 @@ 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 */ diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index 506a1f702cf5..a596681d7732 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -15,6 +15,13 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (12/29/2000) gkh + * Small NULL pointer initialization cleanup which saves a bit of disk image + * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * * (09/11/2000) gkh * Removed DEBUG #ifdefs with call to usb_serial_debug_data * @@ -327,7 +334,7 @@ static struct tty_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; diff --git a/fs/exec.c b/fs/exec.c index 608afeb174e7..78aa59f29f45 100644 --- 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 */ diff --git a/fs/proc/array.c b/fs/proc/array.c index 98c7ec7b7a01..4b0e9d95fa64 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -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; } diff --git a/fs/proc/base.c b/fs/proc/base.c index c9b2d8649bf4..dd1f06456b3a 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -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; } diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 4b6ed72bb46e..29ed20b3bd5c 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -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; } diff --git a/include/asm-sparc/asm_offsets.h b/include/asm-sparc/asm_offsets.h index c8e5e25c736d..b5abb16dc590 100644 --- a/include/asm-sparc/asm_offsets.h +++ b/include/asm-sparc/asm_offsets.h @@ -40,153 +40,163 @@ #define ASIZ_task_next_run 0x00000004 #define AOFF_task_prev_run 0x00000040 #define ASIZ_task_prev_run 0x00000004 -#define AOFF_task_binfmt 0x00000044 +#define AOFF_task_task_exclusive 0x00000044 +#define ASIZ_task_task_exclusive 0x00000004 +#define AOFF_task_binfmt 0x00000048 #define ASIZ_task_binfmt 0x00000004 -#define AOFF_task_exit_code 0x00000048 +#define AOFF_task_exit_code 0x0000004c #define ASIZ_task_exit_code 0x00000004 -#define AOFF_task_exit_signal 0x0000004c +#define AOFF_task_exit_signal 0x00000050 #define ASIZ_task_exit_signal 0x00000004 -#define AOFF_task_pdeath_signal 0x00000050 +#define AOFF_task_pdeath_signal 0x00000054 #define ASIZ_task_pdeath_signal 0x00000004 -#define AOFF_task_personality 0x00000054 +#define AOFF_task_personality 0x00000058 #define ASIZ_task_personality 0x00000004 -#define AOFF_task_pid 0x0000005c +#define AOFF_task_pid 0x00000060 #define ASIZ_task_pid 0x00000004 -#define AOFF_task_pgrp 0x00000060 +#define AOFF_task_pgrp 0x00000064 #define ASIZ_task_pgrp 0x00000004 -#define AOFF_task_tty_old_pgrp 0x00000064 +#define AOFF_task_tty_old_pgrp 0x00000068 #define ASIZ_task_tty_old_pgrp 0x00000004 -#define AOFF_task_session 0x00000068 +#define AOFF_task_session 0x0000006c #define ASIZ_task_session 0x00000004 -#define AOFF_task_leader 0x0000006c +#define AOFF_task_leader 0x00000070 #define ASIZ_task_leader 0x00000004 -#define AOFF_task_p_opptr 0x00000070 +#define AOFF_task_p_opptr 0x00000074 #define ASIZ_task_p_opptr 0x00000004 -#define AOFF_task_p_pptr 0x00000074 +#define AOFF_task_p_pptr 0x00000078 #define ASIZ_task_p_pptr 0x00000004 -#define AOFF_task_p_cptr 0x00000078 +#define AOFF_task_p_cptr 0x0000007c #define ASIZ_task_p_cptr 0x00000004 -#define AOFF_task_p_ysptr 0x0000007c +#define AOFF_task_p_ysptr 0x00000080 #define ASIZ_task_p_ysptr 0x00000004 -#define AOFF_task_p_osptr 0x00000080 +#define AOFF_task_p_osptr 0x00000084 #define ASIZ_task_p_osptr 0x00000004 -#define AOFF_task_pidhash_next 0x00000084 +#define AOFF_task_pidhash_next 0x00000088 #define ASIZ_task_pidhash_next 0x00000004 -#define AOFF_task_pidhash_pprev 0x00000088 +#define AOFF_task_pidhash_pprev 0x0000008c #define ASIZ_task_pidhash_pprev 0x00000004 -#define AOFF_task_tarray_ptr 0x0000008c +#define AOFF_task_tarray_ptr 0x00000090 #define ASIZ_task_tarray_ptr 0x00000004 -#define AOFF_task_wait_chldexit 0x00000090 +#define AOFF_task_wait_chldexit 0x00000094 #define ASIZ_task_wait_chldexit 0x00000004 -#define AOFF_task_vfork_sem 0x00000094 +#define AOFF_task_vfork_sem 0x00000098 #define ASIZ_task_vfork_sem 0x00000004 -#define AOFF_task_policy 0x00000098 +#define AOFF_task_policy 0x0000009c #define ASIZ_task_policy 0x00000004 -#define AOFF_task_rt_priority 0x0000009c +#define AOFF_task_rt_priority 0x000000a0 #define ASIZ_task_rt_priority 0x00000004 -#define AOFF_task_it_real_value 0x000000a0 +#define AOFF_task_it_real_value 0x000000a4 #define ASIZ_task_it_real_value 0x00000004 -#define AOFF_task_it_prof_value 0x000000a4 +#define AOFF_task_it_prof_value 0x000000a8 #define ASIZ_task_it_prof_value 0x00000004 -#define AOFF_task_it_virt_value 0x000000a8 +#define AOFF_task_it_virt_value 0x000000ac #define ASIZ_task_it_virt_value 0x00000004 -#define AOFF_task_it_real_incr 0x000000ac +#define AOFF_task_it_real_incr 0x000000b0 #define ASIZ_task_it_real_incr 0x00000004 -#define AOFF_task_it_prof_incr 0x000000b0 +#define AOFF_task_it_prof_incr 0x000000b4 #define ASIZ_task_it_prof_incr 0x00000004 -#define AOFF_task_it_virt_incr 0x000000b4 +#define AOFF_task_it_virt_incr 0x000000b8 #define ASIZ_task_it_virt_incr 0x00000004 -#define AOFF_task_real_timer 0x000000b8 +#define AOFF_task_real_timer 0x000000bc #define ASIZ_task_real_timer 0x00000014 -#define AOFF_task_times 0x000000cc +#define AOFF_task_times 0x000000d0 #define ASIZ_task_times 0x00000010 -#define AOFF_task_start_time 0x000000dc +#define AOFF_task_start_time 0x000000e0 #define ASIZ_task_start_time 0x00000004 -#define AOFF_task_per_cpu_utime 0x000000e0 +#define AOFF_task_per_cpu_utime 0x000000e4 #define ASIZ_task_per_cpu_utime 0x00000004 -#define AOFF_task_min_flt 0x000000e8 +#define AOFF_task_min_flt 0x000000ec #define ASIZ_task_min_flt 0x00000004 -#define AOFF_task_maj_flt 0x000000ec +#define AOFF_task_maj_flt 0x000000f0 #define ASIZ_task_maj_flt 0x00000004 -#define AOFF_task_nswap 0x000000f0 +#define AOFF_task_nswap 0x000000f4 #define ASIZ_task_nswap 0x00000004 -#define AOFF_task_cmin_flt 0x000000f4 +#define AOFF_task_cmin_flt 0x000000f8 #define ASIZ_task_cmin_flt 0x00000004 -#define AOFF_task_cmaj_flt 0x000000f8 +#define AOFF_task_cmaj_flt 0x000000fc #define ASIZ_task_cmaj_flt 0x00000004 -#define AOFF_task_cnswap 0x000000fc +#define AOFF_task_cnswap 0x00000100 #define ASIZ_task_cnswap 0x00000004 -#define AOFF_task_uid 0x00000102 +#define AOFF_task_uid 0x00000106 #define ASIZ_task_uid 0x00000002 -#define AOFF_task_euid 0x00000104 +#define AOFF_task_euid 0x00000108 #define ASIZ_task_euid 0x00000002 -#define AOFF_task_suid 0x00000106 +#define AOFF_task_suid 0x0000010a #define ASIZ_task_suid 0x00000002 -#define AOFF_task_fsuid 0x00000108 +#define AOFF_task_fsuid 0x0000010c #define ASIZ_task_fsuid 0x00000002 -#define AOFF_task_gid 0x0000010a +#define AOFF_task_gid 0x0000010e #define ASIZ_task_gid 0x00000002 -#define AOFF_task_egid 0x0000010c +#define AOFF_task_egid 0x00000110 #define ASIZ_task_egid 0x00000002 -#define AOFF_task_sgid 0x0000010e +#define AOFF_task_sgid 0x00000112 #define ASIZ_task_sgid 0x00000002 -#define AOFF_task_fsgid 0x00000110 +#define AOFF_task_fsgid 0x00000114 #define ASIZ_task_fsgid 0x00000002 -#define AOFF_task_ngroups 0x00000114 +#define AOFF_task_ngroups 0x00000118 #define ASIZ_task_ngroups 0x00000004 -#define AOFF_task_groups 0x00000118 +#define AOFF_task_groups 0x0000011c #define ASIZ_task_groups 0x00000040 -#define AOFF_task_cap_effective 0x00000158 +#define AOFF_task_cap_effective 0x0000015c #define ASIZ_task_cap_effective 0x00000004 -#define AOFF_task_cap_inheritable 0x0000015c +#define AOFF_task_cap_inheritable 0x00000160 #define ASIZ_task_cap_inheritable 0x00000004 -#define AOFF_task_cap_permitted 0x00000160 +#define AOFF_task_cap_permitted 0x00000164 #define ASIZ_task_cap_permitted 0x00000004 -#define AOFF_task_user 0x00000168 +#define AOFF_task_user 0x0000016c #define ASIZ_task_user 0x00000004 -#define AOFF_task_rlim 0x0000016c +#define AOFF_task_rlim 0x00000170 #define ASIZ_task_rlim 0x00000050 -#define AOFF_task_used_math 0x000001bc +#define AOFF_task_used_math 0x000001c0 #define ASIZ_task_used_math 0x00000002 -#define AOFF_task_comm 0x000001be +#define AOFF_task_comm 0x000001c2 #define ASIZ_task_comm 0x00000010 -#define AOFF_task_link_count 0x000001d0 +#define AOFF_task_link_count 0x000001d4 #define ASIZ_task_link_count 0x00000004 -#define AOFF_task_tty 0x000001d4 +#define AOFF_task_tty 0x000001d8 #define ASIZ_task_tty 0x00000004 -#define AOFF_task_semundo 0x000001d8 +#define AOFF_task_semundo 0x000001dc #define ASIZ_task_semundo 0x00000004 -#define AOFF_task_semsleeping 0x000001dc +#define AOFF_task_semsleeping 0x000001e0 #define ASIZ_task_semsleeping 0x00000004 -#define AOFF_task_tss 0x000001e0 +#define AOFF_task_tss 0x000001e8 #define ASIZ_task_tss 0x00000388 -#define AOFF_task_fs 0x00000568 +#define AOFF_task_fs 0x00000570 #define ASIZ_task_fs 0x00000004 -#define AOFF_task_files 0x0000056c +#define AOFF_task_files 0x00000574 #define ASIZ_task_files 0x00000004 -#define AOFF_task_mm 0x00000570 +#define AOFF_task_mm 0x00000578 #define ASIZ_task_mm 0x00000004 -#define AOFF_task_sigmask_lock 0x00000574 +#define AOFF_task_local_pages 0x0000057c +#define ASIZ_task_local_pages 0x00000008 +#define AOFF_task_allocation_order 0x00000584 +#define ASIZ_task_allocation_order 0x00000004 +#define AOFF_task_nr_local_pages 0x00000588 +#define ASIZ_task_nr_local_pages 0x00000004 +#define AOFF_task_fs_locks 0x0000058c +#define ASIZ_task_fs_locks 0x00000004 +#define AOFF_task_sigmask_lock 0x00000590 #define ASIZ_task_sigmask_lock 0x00000001 -#define AOFF_task_sig 0x00000578 +#define AOFF_task_sig 0x00000594 #define ASIZ_task_sig 0x00000004 -#define AOFF_task_signal 0x0000057c +#define AOFF_task_signal 0x00000598 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x00000584 +#define AOFF_task_blocked 0x000005a0 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x0000058c +#define AOFF_task_sigqueue 0x000005a8 #define ASIZ_task_sigqueue 0x00000004 -#define AOFF_task_sigqueue_tail 0x00000590 +#define AOFF_task_sigqueue_tail 0x000005ac #define ASIZ_task_sigqueue_tail 0x00000004 -#define AOFF_task_sas_ss_sp 0x00000594 +#define AOFF_task_sas_ss_sp 0x000005b0 #define ASIZ_task_sas_ss_sp 0x00000004 -#define AOFF_task_sas_ss_size 0x00000598 +#define AOFF_task_sas_ss_size 0x000005b4 #define ASIZ_task_sas_ss_size 0x00000004 -#define AOFF_task_parent_exec_id 0x0000059c +#define AOFF_task_parent_exec_id 0x000005b8 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x000005a0 +#define AOFF_task_self_exec_id 0x000005bc #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_oom_kill_try 0x000005a4 +#define AOFF_task_oom_kill_try 0x000005c0 #define ASIZ_task_oom_kill_try 0x00000004 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000004 @@ -321,153 +331,163 @@ #define ASIZ_task_next_run 0x00000004 #define AOFF_task_prev_run 0x00000040 #define ASIZ_task_prev_run 0x00000004 -#define AOFF_task_binfmt 0x00000044 +#define AOFF_task_task_exclusive 0x00000044 +#define ASIZ_task_task_exclusive 0x00000004 +#define AOFF_task_binfmt 0x00000048 #define ASIZ_task_binfmt 0x00000004 -#define AOFF_task_exit_code 0x00000048 +#define AOFF_task_exit_code 0x0000004c #define ASIZ_task_exit_code 0x00000004 -#define AOFF_task_exit_signal 0x0000004c +#define AOFF_task_exit_signal 0x00000050 #define ASIZ_task_exit_signal 0x00000004 -#define AOFF_task_pdeath_signal 0x00000050 +#define AOFF_task_pdeath_signal 0x00000054 #define ASIZ_task_pdeath_signal 0x00000004 -#define AOFF_task_personality 0x00000054 +#define AOFF_task_personality 0x00000058 #define ASIZ_task_personality 0x00000004 -#define AOFF_task_pid 0x0000005c +#define AOFF_task_pid 0x00000060 #define ASIZ_task_pid 0x00000004 -#define AOFF_task_pgrp 0x00000060 +#define AOFF_task_pgrp 0x00000064 #define ASIZ_task_pgrp 0x00000004 -#define AOFF_task_tty_old_pgrp 0x00000064 +#define AOFF_task_tty_old_pgrp 0x00000068 #define ASIZ_task_tty_old_pgrp 0x00000004 -#define AOFF_task_session 0x00000068 +#define AOFF_task_session 0x0000006c #define ASIZ_task_session 0x00000004 -#define AOFF_task_leader 0x0000006c +#define AOFF_task_leader 0x00000070 #define ASIZ_task_leader 0x00000004 -#define AOFF_task_p_opptr 0x00000070 +#define AOFF_task_p_opptr 0x00000074 #define ASIZ_task_p_opptr 0x00000004 -#define AOFF_task_p_pptr 0x00000074 +#define AOFF_task_p_pptr 0x00000078 #define ASIZ_task_p_pptr 0x00000004 -#define AOFF_task_p_cptr 0x00000078 +#define AOFF_task_p_cptr 0x0000007c #define ASIZ_task_p_cptr 0x00000004 -#define AOFF_task_p_ysptr 0x0000007c +#define AOFF_task_p_ysptr 0x00000080 #define ASIZ_task_p_ysptr 0x00000004 -#define AOFF_task_p_osptr 0x00000080 +#define AOFF_task_p_osptr 0x00000084 #define ASIZ_task_p_osptr 0x00000004 -#define AOFF_task_pidhash_next 0x00000084 +#define AOFF_task_pidhash_next 0x00000088 #define ASIZ_task_pidhash_next 0x00000004 -#define AOFF_task_pidhash_pprev 0x00000088 +#define AOFF_task_pidhash_pprev 0x0000008c #define ASIZ_task_pidhash_pprev 0x00000004 -#define AOFF_task_tarray_ptr 0x0000008c +#define AOFF_task_tarray_ptr 0x00000090 #define ASIZ_task_tarray_ptr 0x00000004 -#define AOFF_task_wait_chldexit 0x00000090 +#define AOFF_task_wait_chldexit 0x00000094 #define ASIZ_task_wait_chldexit 0x00000004 -#define AOFF_task_vfork_sem 0x00000094 +#define AOFF_task_vfork_sem 0x00000098 #define ASIZ_task_vfork_sem 0x00000004 -#define AOFF_task_policy 0x00000098 +#define AOFF_task_policy 0x0000009c #define ASIZ_task_policy 0x00000004 -#define AOFF_task_rt_priority 0x0000009c +#define AOFF_task_rt_priority 0x000000a0 #define ASIZ_task_rt_priority 0x00000004 -#define AOFF_task_it_real_value 0x000000a0 +#define AOFF_task_it_real_value 0x000000a4 #define ASIZ_task_it_real_value 0x00000004 -#define AOFF_task_it_prof_value 0x000000a4 +#define AOFF_task_it_prof_value 0x000000a8 #define ASIZ_task_it_prof_value 0x00000004 -#define AOFF_task_it_virt_value 0x000000a8 +#define AOFF_task_it_virt_value 0x000000ac #define ASIZ_task_it_virt_value 0x00000004 -#define AOFF_task_it_real_incr 0x000000ac +#define AOFF_task_it_real_incr 0x000000b0 #define ASIZ_task_it_real_incr 0x00000004 -#define AOFF_task_it_prof_incr 0x000000b0 +#define AOFF_task_it_prof_incr 0x000000b4 #define ASIZ_task_it_prof_incr 0x00000004 -#define AOFF_task_it_virt_incr 0x000000b4 +#define AOFF_task_it_virt_incr 0x000000b8 #define ASIZ_task_it_virt_incr 0x00000004 -#define AOFF_task_real_timer 0x000000b8 +#define AOFF_task_real_timer 0x000000bc #define ASIZ_task_real_timer 0x00000014 -#define AOFF_task_times 0x000000cc +#define AOFF_task_times 0x000000d0 #define ASIZ_task_times 0x00000010 -#define AOFF_task_start_time 0x000000dc +#define AOFF_task_start_time 0x000000e0 #define ASIZ_task_start_time 0x00000004 -#define AOFF_task_per_cpu_utime 0x000000e0 +#define AOFF_task_per_cpu_utime 0x000000e4 #define ASIZ_task_per_cpu_utime 0x00000080 -#define AOFF_task_min_flt 0x000001e0 +#define AOFF_task_min_flt 0x000001e4 #define ASIZ_task_min_flt 0x00000004 -#define AOFF_task_maj_flt 0x000001e4 +#define AOFF_task_maj_flt 0x000001e8 #define ASIZ_task_maj_flt 0x00000004 -#define AOFF_task_nswap 0x000001e8 +#define AOFF_task_nswap 0x000001ec #define ASIZ_task_nswap 0x00000004 -#define AOFF_task_cmin_flt 0x000001ec +#define AOFF_task_cmin_flt 0x000001f0 #define ASIZ_task_cmin_flt 0x00000004 -#define AOFF_task_cmaj_flt 0x000001f0 +#define AOFF_task_cmaj_flt 0x000001f4 #define ASIZ_task_cmaj_flt 0x00000004 -#define AOFF_task_cnswap 0x000001f4 +#define AOFF_task_cnswap 0x000001f8 #define ASIZ_task_cnswap 0x00000004 -#define AOFF_task_uid 0x000001fa +#define AOFF_task_uid 0x000001fe #define ASIZ_task_uid 0x00000002 -#define AOFF_task_euid 0x000001fc +#define AOFF_task_euid 0x00000200 #define ASIZ_task_euid 0x00000002 -#define AOFF_task_suid 0x000001fe +#define AOFF_task_suid 0x00000202 #define ASIZ_task_suid 0x00000002 -#define AOFF_task_fsuid 0x00000200 +#define AOFF_task_fsuid 0x00000204 #define ASIZ_task_fsuid 0x00000002 -#define AOFF_task_gid 0x00000202 +#define AOFF_task_gid 0x00000206 #define ASIZ_task_gid 0x00000002 -#define AOFF_task_egid 0x00000204 +#define AOFF_task_egid 0x00000208 #define ASIZ_task_egid 0x00000002 -#define AOFF_task_sgid 0x00000206 +#define AOFF_task_sgid 0x0000020a #define ASIZ_task_sgid 0x00000002 -#define AOFF_task_fsgid 0x00000208 +#define AOFF_task_fsgid 0x0000020c #define ASIZ_task_fsgid 0x00000002 -#define AOFF_task_ngroups 0x0000020c +#define AOFF_task_ngroups 0x00000210 #define ASIZ_task_ngroups 0x00000004 -#define AOFF_task_groups 0x00000210 +#define AOFF_task_groups 0x00000214 #define ASIZ_task_groups 0x00000040 -#define AOFF_task_cap_effective 0x00000250 +#define AOFF_task_cap_effective 0x00000254 #define ASIZ_task_cap_effective 0x00000004 -#define AOFF_task_cap_inheritable 0x00000254 +#define AOFF_task_cap_inheritable 0x00000258 #define ASIZ_task_cap_inheritable 0x00000004 -#define AOFF_task_cap_permitted 0x00000258 +#define AOFF_task_cap_permitted 0x0000025c #define ASIZ_task_cap_permitted 0x00000004 -#define AOFF_task_user 0x00000260 +#define AOFF_task_user 0x00000264 #define ASIZ_task_user 0x00000004 -#define AOFF_task_rlim 0x00000264 +#define AOFF_task_rlim 0x00000268 #define ASIZ_task_rlim 0x00000050 -#define AOFF_task_used_math 0x000002b4 +#define AOFF_task_used_math 0x000002b8 #define ASIZ_task_used_math 0x00000002 -#define AOFF_task_comm 0x000002b6 +#define AOFF_task_comm 0x000002ba #define ASIZ_task_comm 0x00000010 -#define AOFF_task_link_count 0x000002c8 +#define AOFF_task_link_count 0x000002cc #define ASIZ_task_link_count 0x00000004 -#define AOFF_task_tty 0x000002cc +#define AOFF_task_tty 0x000002d0 #define ASIZ_task_tty 0x00000004 -#define AOFF_task_semundo 0x000002d0 +#define AOFF_task_semundo 0x000002d4 #define ASIZ_task_semundo 0x00000004 -#define AOFF_task_semsleeping 0x000002d4 +#define AOFF_task_semsleeping 0x000002d8 #define ASIZ_task_semsleeping 0x00000004 -#define AOFF_task_tss 0x000002d8 +#define AOFF_task_tss 0x000002e0 #define ASIZ_task_tss 0x00000388 -#define AOFF_task_fs 0x00000660 +#define AOFF_task_fs 0x00000668 #define ASIZ_task_fs 0x00000004 -#define AOFF_task_files 0x00000664 +#define AOFF_task_files 0x0000066c #define ASIZ_task_files 0x00000004 -#define AOFF_task_mm 0x00000668 +#define AOFF_task_mm 0x00000670 #define ASIZ_task_mm 0x00000004 -#define AOFF_task_sigmask_lock 0x0000066c +#define AOFF_task_local_pages 0x00000674 +#define ASIZ_task_local_pages 0x00000008 +#define AOFF_task_allocation_order 0x0000067c +#define ASIZ_task_allocation_order 0x00000004 +#define AOFF_task_nr_local_pages 0x00000680 +#define ASIZ_task_nr_local_pages 0x00000004 +#define AOFF_task_fs_locks 0x00000684 +#define ASIZ_task_fs_locks 0x00000004 +#define AOFF_task_sigmask_lock 0x00000688 #define ASIZ_task_sigmask_lock 0x00000001 -#define AOFF_task_sig 0x00000670 +#define AOFF_task_sig 0x0000068c #define ASIZ_task_sig 0x00000004 -#define AOFF_task_signal 0x00000674 +#define AOFF_task_signal 0x00000690 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x0000067c +#define AOFF_task_blocked 0x00000698 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x00000684 +#define AOFF_task_sigqueue 0x000006a0 #define ASIZ_task_sigqueue 0x00000004 -#define AOFF_task_sigqueue_tail 0x00000688 +#define AOFF_task_sigqueue_tail 0x000006a4 #define ASIZ_task_sigqueue_tail 0x00000004 -#define AOFF_task_sas_ss_sp 0x0000068c +#define AOFF_task_sas_ss_sp 0x000006a8 #define ASIZ_task_sas_ss_sp 0x00000004 -#define AOFF_task_sas_ss_size 0x00000690 +#define AOFF_task_sas_ss_size 0x000006ac #define ASIZ_task_sas_ss_size 0x00000004 -#define AOFF_task_parent_exec_id 0x00000694 +#define AOFF_task_parent_exec_id 0x000006b0 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x00000698 +#define AOFF_task_self_exec_id 0x000006b4 #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_oom_kill_try 0x0000069c +#define AOFF_task_oom_kill_try 0x000006b8 #define ASIZ_task_oom_kill_try 0x00000004 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000004 diff --git a/include/asm-sparc/audioio.h b/include/asm-sparc/audioio.h index f784d8392338..b5597c66f27f 100644 --- a/include/asm-sparc/audioio.h +++ b/include/asm-sparc/audioio.h @@ -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 diff --git a/include/asm-sparc64/asm_offsets.h b/include/asm-sparc64/asm_offsets.h index bd2b87f3517c..1ef0bede2f60 100644 --- a/include/asm-sparc64/asm_offsets.h +++ b/include/asm-sparc64/asm_offsets.h @@ -40,155 +40,165 @@ #define ASIZ_task_next_run 0x00000008 #define AOFF_task_prev_run 0x00000070 #define ASIZ_task_prev_run 0x00000008 -#define AOFF_task_binfmt 0x00000078 +#define AOFF_task_task_exclusive 0x00000078 +#define ASIZ_task_task_exclusive 0x00000004 +#define AOFF_task_binfmt 0x00000080 #define ASIZ_task_binfmt 0x00000008 -#define AOFF_task_exit_code 0x00000080 +#define AOFF_task_exit_code 0x00000088 #define ASIZ_task_exit_code 0x00000004 -#define AOFF_task_exit_signal 0x00000084 +#define AOFF_task_exit_signal 0x0000008c #define ASIZ_task_exit_signal 0x00000004 -#define AOFF_task_pdeath_signal 0x00000088 +#define AOFF_task_pdeath_signal 0x00000090 #define ASIZ_task_pdeath_signal 0x00000004 -#define AOFF_task_personality 0x00000090 +#define AOFF_task_personality 0x00000098 #define ASIZ_task_personality 0x00000008 -#define AOFF_task_pid 0x0000009c +#define AOFF_task_pid 0x000000a4 #define ASIZ_task_pid 0x00000004 -#define AOFF_task_pgrp 0x000000a0 +#define AOFF_task_pgrp 0x000000a8 #define ASIZ_task_pgrp 0x00000004 -#define AOFF_task_tty_old_pgrp 0x000000a4 +#define AOFF_task_tty_old_pgrp 0x000000ac #define ASIZ_task_tty_old_pgrp 0x00000004 -#define AOFF_task_session 0x000000a8 +#define AOFF_task_session 0x000000b0 #define ASIZ_task_session 0x00000004 -#define AOFF_task_leader 0x000000ac +#define AOFF_task_leader 0x000000b4 #define ASIZ_task_leader 0x00000004 -#define AOFF_task_p_opptr 0x000000b0 +#define AOFF_task_p_opptr 0x000000b8 #define ASIZ_task_p_opptr 0x00000008 -#define AOFF_task_p_pptr 0x000000b8 +#define AOFF_task_p_pptr 0x000000c0 #define ASIZ_task_p_pptr 0x00000008 -#define AOFF_task_p_cptr 0x000000c0 +#define AOFF_task_p_cptr 0x000000c8 #define ASIZ_task_p_cptr 0x00000008 -#define AOFF_task_p_ysptr 0x000000c8 +#define AOFF_task_p_ysptr 0x000000d0 #define ASIZ_task_p_ysptr 0x00000008 -#define AOFF_task_p_osptr 0x000000d0 +#define AOFF_task_p_osptr 0x000000d8 #define ASIZ_task_p_osptr 0x00000008 -#define AOFF_task_pidhash_next 0x000000d8 +#define AOFF_task_pidhash_next 0x000000e0 #define ASIZ_task_pidhash_next 0x00000008 -#define AOFF_task_pidhash_pprev 0x000000e0 +#define AOFF_task_pidhash_pprev 0x000000e8 #define ASIZ_task_pidhash_pprev 0x00000008 -#define AOFF_task_tarray_ptr 0x000000e8 +#define AOFF_task_tarray_ptr 0x000000f0 #define ASIZ_task_tarray_ptr 0x00000008 -#define AOFF_task_wait_chldexit 0x000000f0 +#define AOFF_task_wait_chldexit 0x000000f8 #define ASIZ_task_wait_chldexit 0x00000008 -#define AOFF_task_vfork_sem 0x000000f8 +#define AOFF_task_vfork_sem 0x00000100 #define ASIZ_task_vfork_sem 0x00000008 -#define AOFF_task_policy 0x00000100 +#define AOFF_task_policy 0x00000108 #define ASIZ_task_policy 0x00000008 -#define AOFF_task_rt_priority 0x00000108 +#define AOFF_task_rt_priority 0x00000110 #define ASIZ_task_rt_priority 0x00000008 -#define AOFF_task_it_real_value 0x00000110 +#define AOFF_task_it_real_value 0x00000118 #define ASIZ_task_it_real_value 0x00000008 -#define AOFF_task_it_prof_value 0x00000118 +#define AOFF_task_it_prof_value 0x00000120 #define ASIZ_task_it_prof_value 0x00000008 -#define AOFF_task_it_virt_value 0x00000120 +#define AOFF_task_it_virt_value 0x00000128 #define ASIZ_task_it_virt_value 0x00000008 -#define AOFF_task_it_real_incr 0x00000128 +#define AOFF_task_it_real_incr 0x00000130 #define ASIZ_task_it_real_incr 0x00000008 -#define AOFF_task_it_prof_incr 0x00000130 +#define AOFF_task_it_prof_incr 0x00000138 #define ASIZ_task_it_prof_incr 0x00000008 -#define AOFF_task_it_virt_incr 0x00000138 +#define AOFF_task_it_virt_incr 0x00000140 #define ASIZ_task_it_virt_incr 0x00000008 -#define AOFF_task_real_timer 0x00000140 +#define AOFF_task_real_timer 0x00000148 #define ASIZ_task_real_timer 0x00000028 -#define AOFF_task_times 0x00000168 +#define AOFF_task_times 0x00000170 #define ASIZ_task_times 0x00000020 -#define AOFF_task_start_time 0x00000188 +#define AOFF_task_start_time 0x00000190 #define ASIZ_task_start_time 0x00000008 -#define AOFF_task_per_cpu_utime 0x00000190 +#define AOFF_task_per_cpu_utime 0x00000198 #define ASIZ_task_per_cpu_utime 0x00000008 -#define AOFF_task_min_flt 0x000001a0 +#define AOFF_task_min_flt 0x000001a8 #define ASIZ_task_min_flt 0x00000008 -#define AOFF_task_maj_flt 0x000001a8 +#define AOFF_task_maj_flt 0x000001b0 #define ASIZ_task_maj_flt 0x00000008 -#define AOFF_task_nswap 0x000001b0 +#define AOFF_task_nswap 0x000001b8 #define ASIZ_task_nswap 0x00000008 -#define AOFF_task_cmin_flt 0x000001b8 +#define AOFF_task_cmin_flt 0x000001c0 #define ASIZ_task_cmin_flt 0x00000008 -#define AOFF_task_cmaj_flt 0x000001c0 +#define AOFF_task_cmaj_flt 0x000001c8 #define ASIZ_task_cmaj_flt 0x00000008 -#define AOFF_task_cnswap 0x000001c8 +#define AOFF_task_cnswap 0x000001d0 #define ASIZ_task_cnswap 0x00000008 -#define AOFF_task_uid 0x000001d4 +#define AOFF_task_uid 0x000001dc #define ASIZ_task_uid 0x00000004 -#define AOFF_task_euid 0x000001d8 +#define AOFF_task_euid 0x000001e0 #define ASIZ_task_euid 0x00000004 -#define AOFF_task_suid 0x000001dc +#define AOFF_task_suid 0x000001e4 #define ASIZ_task_suid 0x00000004 -#define AOFF_task_fsuid 0x000001e0 +#define AOFF_task_fsuid 0x000001e8 #define ASIZ_task_fsuid 0x00000004 -#define AOFF_task_gid 0x000001e4 +#define AOFF_task_gid 0x000001ec #define ASIZ_task_gid 0x00000004 -#define AOFF_task_egid 0x000001e8 +#define AOFF_task_egid 0x000001f0 #define ASIZ_task_egid 0x00000004 -#define AOFF_task_sgid 0x000001ec +#define AOFF_task_sgid 0x000001f4 #define ASIZ_task_sgid 0x00000004 -#define AOFF_task_fsgid 0x000001f0 +#define AOFF_task_fsgid 0x000001f8 #define ASIZ_task_fsgid 0x00000004 -#define AOFF_task_ngroups 0x000001f4 +#define AOFF_task_ngroups 0x000001fc #define ASIZ_task_ngroups 0x00000004 -#define AOFF_task_groups 0x000001f8 +#define AOFF_task_groups 0x00000200 #define ASIZ_task_groups 0x00000080 -#define AOFF_task_cap_effective 0x00000278 +#define AOFF_task_cap_effective 0x00000280 #define ASIZ_task_cap_effective 0x00000004 -#define AOFF_task_cap_inheritable 0x0000027c +#define AOFF_task_cap_inheritable 0x00000284 #define ASIZ_task_cap_inheritable 0x00000004 -#define AOFF_task_cap_permitted 0x00000280 +#define AOFF_task_cap_permitted 0x00000288 #define ASIZ_task_cap_permitted 0x00000004 -#define AOFF_task_user 0x00000288 +#define AOFF_task_user 0x00000290 #define ASIZ_task_user 0x00000008 -#define AOFF_task_rlim 0x00000290 +#define AOFF_task_rlim 0x00000298 #define ASIZ_task_rlim 0x000000a0 -#define AOFF_task_used_math 0x00000330 +#define AOFF_task_used_math 0x00000338 #define ASIZ_task_used_math 0x00000002 -#define AOFF_task_comm 0x00000332 +#define AOFF_task_comm 0x0000033a #define ASIZ_task_comm 0x00000010 -#define AOFF_task_link_count 0x00000344 +#define AOFF_task_link_count 0x0000034c #define ASIZ_task_link_count 0x00000004 -#define AOFF_task_tty 0x00000348 +#define AOFF_task_tty 0x00000350 #define ASIZ_task_tty 0x00000008 -#define AOFF_task_semundo 0x00000350 +#define AOFF_task_semundo 0x00000358 #define ASIZ_task_semundo 0x00000008 -#define AOFF_task_semsleeping 0x00000358 +#define AOFF_task_semsleeping 0x00000360 #define ASIZ_task_semsleeping 0x00000008 -#define AOFF_task_tss 0x00000360 +#define AOFF_task_tss 0x00000370 #define ASIZ_task_tss 0x00000470 -#define AOFF_task_fs 0x000007d0 +#define AOFF_task_fs 0x000007e0 #define ASIZ_task_fs 0x00000008 -#define AOFF_task_files 0x000007d8 +#define AOFF_task_files 0x000007e8 #define ASIZ_task_files 0x00000008 -#define AOFF_task_mm 0x000007e0 +#define AOFF_task_mm 0x000007f0 #define ASIZ_task_mm 0x00000008 -#define AOFF_task_sigmask_lock 0x000007e8 +#define AOFF_task_local_pages 0x000007f8 +#define ASIZ_task_local_pages 0x00000010 +#define AOFF_task_allocation_order 0x00000808 +#define ASIZ_task_allocation_order 0x00000004 +#define AOFF_task_nr_local_pages 0x0000080c +#define ASIZ_task_nr_local_pages 0x00000004 +#define AOFF_task_fs_locks 0x00000810 +#define ASIZ_task_fs_locks 0x00000004 +#define AOFF_task_sigmask_lock 0x00000814 #define ASIZ_task_sigmask_lock 0x00000001 -#define AOFF_task_sig 0x000007f0 +#define AOFF_task_sig 0x00000818 #define ASIZ_task_sig 0x00000008 -#define AOFF_task_signal 0x000007f8 +#define AOFF_task_signal 0x00000820 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x00000800 +#define AOFF_task_blocked 0x00000828 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x00000808 +#define AOFF_task_sigqueue 0x00000830 #define ASIZ_task_sigqueue 0x00000008 -#define AOFF_task_sigqueue_tail 0x00000810 +#define AOFF_task_sigqueue_tail 0x00000838 #define ASIZ_task_sigqueue_tail 0x00000008 -#define AOFF_task_sas_ss_sp 0x00000818 +#define AOFF_task_sas_ss_sp 0x00000840 #define ASIZ_task_sas_ss_sp 0x00000008 -#define AOFF_task_sas_ss_size 0x00000820 +#define AOFF_task_sas_ss_size 0x00000848 #define ASIZ_task_sas_ss_size 0x00000008 -#define AOFF_task_parent_exec_id 0x00000828 +#define AOFF_task_parent_exec_id 0x00000850 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x0000082c +#define AOFF_task_self_exec_id 0x00000854 #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_oom_kill_try 0x00000830 +#define AOFF_task_oom_kill_try 0x00000858 #define ASIZ_task_oom_kill_try 0x00000004 -#define ASIZ_task 0x00000840 +#define ASIZ_task 0x00000860 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 @@ -332,155 +342,165 @@ #define ASIZ_task_next_run 0x00000008 #define AOFF_task_prev_run 0x00000070 #define ASIZ_task_prev_run 0x00000008 -#define AOFF_task_binfmt 0x00000078 +#define AOFF_task_task_exclusive 0x00000078 +#define ASIZ_task_task_exclusive 0x00000004 +#define AOFF_task_binfmt 0x00000080 #define ASIZ_task_binfmt 0x00000008 -#define AOFF_task_exit_code 0x00000080 +#define AOFF_task_exit_code 0x00000088 #define ASIZ_task_exit_code 0x00000004 -#define AOFF_task_exit_signal 0x00000084 +#define AOFF_task_exit_signal 0x0000008c #define ASIZ_task_exit_signal 0x00000004 -#define AOFF_task_pdeath_signal 0x00000088 +#define AOFF_task_pdeath_signal 0x00000090 #define ASIZ_task_pdeath_signal 0x00000004 -#define AOFF_task_personality 0x00000090 +#define AOFF_task_personality 0x00000098 #define ASIZ_task_personality 0x00000008 -#define AOFF_task_pid 0x0000009c +#define AOFF_task_pid 0x000000a4 #define ASIZ_task_pid 0x00000004 -#define AOFF_task_pgrp 0x000000a0 +#define AOFF_task_pgrp 0x000000a8 #define ASIZ_task_pgrp 0x00000004 -#define AOFF_task_tty_old_pgrp 0x000000a4 +#define AOFF_task_tty_old_pgrp 0x000000ac #define ASIZ_task_tty_old_pgrp 0x00000004 -#define AOFF_task_session 0x000000a8 +#define AOFF_task_session 0x000000b0 #define ASIZ_task_session 0x00000004 -#define AOFF_task_leader 0x000000ac +#define AOFF_task_leader 0x000000b4 #define ASIZ_task_leader 0x00000004 -#define AOFF_task_p_opptr 0x000000b0 +#define AOFF_task_p_opptr 0x000000b8 #define ASIZ_task_p_opptr 0x00000008 -#define AOFF_task_p_pptr 0x000000b8 +#define AOFF_task_p_pptr 0x000000c0 #define ASIZ_task_p_pptr 0x00000008 -#define AOFF_task_p_cptr 0x000000c0 +#define AOFF_task_p_cptr 0x000000c8 #define ASIZ_task_p_cptr 0x00000008 -#define AOFF_task_p_ysptr 0x000000c8 +#define AOFF_task_p_ysptr 0x000000d0 #define ASIZ_task_p_ysptr 0x00000008 -#define AOFF_task_p_osptr 0x000000d0 +#define AOFF_task_p_osptr 0x000000d8 #define ASIZ_task_p_osptr 0x00000008 -#define AOFF_task_pidhash_next 0x000000d8 +#define AOFF_task_pidhash_next 0x000000e0 #define ASIZ_task_pidhash_next 0x00000008 -#define AOFF_task_pidhash_pprev 0x000000e0 +#define AOFF_task_pidhash_pprev 0x000000e8 #define ASIZ_task_pidhash_pprev 0x00000008 -#define AOFF_task_tarray_ptr 0x000000e8 +#define AOFF_task_tarray_ptr 0x000000f0 #define ASIZ_task_tarray_ptr 0x00000008 -#define AOFF_task_wait_chldexit 0x000000f0 +#define AOFF_task_wait_chldexit 0x000000f8 #define ASIZ_task_wait_chldexit 0x00000008 -#define AOFF_task_vfork_sem 0x000000f8 +#define AOFF_task_vfork_sem 0x00000100 #define ASIZ_task_vfork_sem 0x00000008 -#define AOFF_task_policy 0x00000100 +#define AOFF_task_policy 0x00000108 #define ASIZ_task_policy 0x00000008 -#define AOFF_task_rt_priority 0x00000108 +#define AOFF_task_rt_priority 0x00000110 #define ASIZ_task_rt_priority 0x00000008 -#define AOFF_task_it_real_value 0x00000110 +#define AOFF_task_it_real_value 0x00000118 #define ASIZ_task_it_real_value 0x00000008 -#define AOFF_task_it_prof_value 0x00000118 +#define AOFF_task_it_prof_value 0x00000120 #define ASIZ_task_it_prof_value 0x00000008 -#define AOFF_task_it_virt_value 0x00000120 +#define AOFF_task_it_virt_value 0x00000128 #define ASIZ_task_it_virt_value 0x00000008 -#define AOFF_task_it_real_incr 0x00000128 +#define AOFF_task_it_real_incr 0x00000130 #define ASIZ_task_it_real_incr 0x00000008 -#define AOFF_task_it_prof_incr 0x00000130 +#define AOFF_task_it_prof_incr 0x00000138 #define ASIZ_task_it_prof_incr 0x00000008 -#define AOFF_task_it_virt_incr 0x00000138 +#define AOFF_task_it_virt_incr 0x00000140 #define ASIZ_task_it_virt_incr 0x00000008 -#define AOFF_task_real_timer 0x00000140 +#define AOFF_task_real_timer 0x00000148 #define ASIZ_task_real_timer 0x00000028 -#define AOFF_task_times 0x00000168 +#define AOFF_task_times 0x00000170 #define ASIZ_task_times 0x00000020 -#define AOFF_task_start_time 0x00000188 +#define AOFF_task_start_time 0x00000190 #define ASIZ_task_start_time 0x00000008 -#define AOFF_task_per_cpu_utime 0x00000190 +#define AOFF_task_per_cpu_utime 0x00000198 #define ASIZ_task_per_cpu_utime 0x00000100 -#define AOFF_task_min_flt 0x00000390 +#define AOFF_task_min_flt 0x00000398 #define ASIZ_task_min_flt 0x00000008 -#define AOFF_task_maj_flt 0x00000398 +#define AOFF_task_maj_flt 0x000003a0 #define ASIZ_task_maj_flt 0x00000008 -#define AOFF_task_nswap 0x000003a0 +#define AOFF_task_nswap 0x000003a8 #define ASIZ_task_nswap 0x00000008 -#define AOFF_task_cmin_flt 0x000003a8 +#define AOFF_task_cmin_flt 0x000003b0 #define ASIZ_task_cmin_flt 0x00000008 -#define AOFF_task_cmaj_flt 0x000003b0 +#define AOFF_task_cmaj_flt 0x000003b8 #define ASIZ_task_cmaj_flt 0x00000008 -#define AOFF_task_cnswap 0x000003b8 +#define AOFF_task_cnswap 0x000003c0 #define ASIZ_task_cnswap 0x00000008 -#define AOFF_task_uid 0x000003c4 +#define AOFF_task_uid 0x000003cc #define ASIZ_task_uid 0x00000004 -#define AOFF_task_euid 0x000003c8 +#define AOFF_task_euid 0x000003d0 #define ASIZ_task_euid 0x00000004 -#define AOFF_task_suid 0x000003cc +#define AOFF_task_suid 0x000003d4 #define ASIZ_task_suid 0x00000004 -#define AOFF_task_fsuid 0x000003d0 +#define AOFF_task_fsuid 0x000003d8 #define ASIZ_task_fsuid 0x00000004 -#define AOFF_task_gid 0x000003d4 +#define AOFF_task_gid 0x000003dc #define ASIZ_task_gid 0x00000004 -#define AOFF_task_egid 0x000003d8 +#define AOFF_task_egid 0x000003e0 #define ASIZ_task_egid 0x00000004 -#define AOFF_task_sgid 0x000003dc +#define AOFF_task_sgid 0x000003e4 #define ASIZ_task_sgid 0x00000004 -#define AOFF_task_fsgid 0x000003e0 +#define AOFF_task_fsgid 0x000003e8 #define ASIZ_task_fsgid 0x00000004 -#define AOFF_task_ngroups 0x000003e4 +#define AOFF_task_ngroups 0x000003ec #define ASIZ_task_ngroups 0x00000004 -#define AOFF_task_groups 0x000003e8 +#define AOFF_task_groups 0x000003f0 #define ASIZ_task_groups 0x00000080 -#define AOFF_task_cap_effective 0x00000468 +#define AOFF_task_cap_effective 0x00000470 #define ASIZ_task_cap_effective 0x00000004 -#define AOFF_task_cap_inheritable 0x0000046c +#define AOFF_task_cap_inheritable 0x00000474 #define ASIZ_task_cap_inheritable 0x00000004 -#define AOFF_task_cap_permitted 0x00000470 +#define AOFF_task_cap_permitted 0x00000478 #define ASIZ_task_cap_permitted 0x00000004 -#define AOFF_task_user 0x00000478 +#define AOFF_task_user 0x00000480 #define ASIZ_task_user 0x00000008 -#define AOFF_task_rlim 0x00000480 +#define AOFF_task_rlim 0x00000488 #define ASIZ_task_rlim 0x000000a0 -#define AOFF_task_used_math 0x00000520 +#define AOFF_task_used_math 0x00000528 #define ASIZ_task_used_math 0x00000002 -#define AOFF_task_comm 0x00000522 +#define AOFF_task_comm 0x0000052a #define ASIZ_task_comm 0x00000010 -#define AOFF_task_link_count 0x00000534 +#define AOFF_task_link_count 0x0000053c #define ASIZ_task_link_count 0x00000004 -#define AOFF_task_tty 0x00000538 +#define AOFF_task_tty 0x00000540 #define ASIZ_task_tty 0x00000008 -#define AOFF_task_semundo 0x00000540 +#define AOFF_task_semundo 0x00000548 #define ASIZ_task_semundo 0x00000008 -#define AOFF_task_semsleeping 0x00000548 +#define AOFF_task_semsleeping 0x00000550 #define ASIZ_task_semsleeping 0x00000008 -#define AOFF_task_tss 0x00000550 +#define AOFF_task_tss 0x00000560 #define ASIZ_task_tss 0x00000470 -#define AOFF_task_fs 0x000009c0 +#define AOFF_task_fs 0x000009d0 #define ASIZ_task_fs 0x00000008 -#define AOFF_task_files 0x000009c8 +#define AOFF_task_files 0x000009d8 #define ASIZ_task_files 0x00000008 -#define AOFF_task_mm 0x000009d0 +#define AOFF_task_mm 0x000009e0 #define ASIZ_task_mm 0x00000008 -#define AOFF_task_sigmask_lock 0x000009d8 +#define AOFF_task_local_pages 0x000009e8 +#define ASIZ_task_local_pages 0x00000010 +#define AOFF_task_allocation_order 0x000009f8 +#define ASIZ_task_allocation_order 0x00000004 +#define AOFF_task_nr_local_pages 0x000009fc +#define ASIZ_task_nr_local_pages 0x00000004 +#define AOFF_task_fs_locks 0x00000a00 +#define ASIZ_task_fs_locks 0x00000004 +#define AOFF_task_sigmask_lock 0x00000a04 #define ASIZ_task_sigmask_lock 0x00000001 -#define AOFF_task_sig 0x000009e0 +#define AOFF_task_sig 0x00000a08 #define ASIZ_task_sig 0x00000008 -#define AOFF_task_signal 0x000009e8 +#define AOFF_task_signal 0x00000a10 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x000009f0 +#define AOFF_task_blocked 0x00000a18 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x000009f8 +#define AOFF_task_sigqueue 0x00000a20 #define ASIZ_task_sigqueue 0x00000008 -#define AOFF_task_sigqueue_tail 0x00000a00 +#define AOFF_task_sigqueue_tail 0x00000a28 #define ASIZ_task_sigqueue_tail 0x00000008 -#define AOFF_task_sas_ss_sp 0x00000a08 +#define AOFF_task_sas_ss_sp 0x00000a30 #define ASIZ_task_sas_ss_sp 0x00000008 -#define AOFF_task_sas_ss_size 0x00000a10 +#define AOFF_task_sas_ss_size 0x00000a38 #define ASIZ_task_sas_ss_size 0x00000008 -#define AOFF_task_parent_exec_id 0x00000a18 +#define AOFF_task_parent_exec_id 0x00000a40 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x00000a1c +#define AOFF_task_self_exec_id 0x00000a44 #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_oom_kill_try 0x00000a20 +#define AOFF_task_oom_kill_try 0x00000a48 #define ASIZ_task_oom_kill_try 0x00000004 -#define ASIZ_task 0x00000a30 +#define ASIZ_task 0x00000a50 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 @@ -622,155 +642,165 @@ #define ASIZ_task_next_run 0x00000008 #define AOFF_task_prev_run 0x00000070 #define ASIZ_task_prev_run 0x00000008 -#define AOFF_task_binfmt 0x00000078 +#define AOFF_task_task_exclusive 0x00000078 +#define ASIZ_task_task_exclusive 0x00000004 +#define AOFF_task_binfmt 0x00000080 #define ASIZ_task_binfmt 0x00000008 -#define AOFF_task_exit_code 0x00000080 +#define AOFF_task_exit_code 0x00000088 #define ASIZ_task_exit_code 0x00000004 -#define AOFF_task_exit_signal 0x00000084 +#define AOFF_task_exit_signal 0x0000008c #define ASIZ_task_exit_signal 0x00000004 -#define AOFF_task_pdeath_signal 0x00000088 +#define AOFF_task_pdeath_signal 0x00000090 #define ASIZ_task_pdeath_signal 0x00000004 -#define AOFF_task_personality 0x00000090 +#define AOFF_task_personality 0x00000098 #define ASIZ_task_personality 0x00000008 -#define AOFF_task_pid 0x0000009c +#define AOFF_task_pid 0x000000a4 #define ASIZ_task_pid 0x00000004 -#define AOFF_task_pgrp 0x000000a0 +#define AOFF_task_pgrp 0x000000a8 #define ASIZ_task_pgrp 0x00000004 -#define AOFF_task_tty_old_pgrp 0x000000a4 +#define AOFF_task_tty_old_pgrp 0x000000ac #define ASIZ_task_tty_old_pgrp 0x00000004 -#define AOFF_task_session 0x000000a8 +#define AOFF_task_session 0x000000b0 #define ASIZ_task_session 0x00000004 -#define AOFF_task_leader 0x000000ac +#define AOFF_task_leader 0x000000b4 #define ASIZ_task_leader 0x00000004 -#define AOFF_task_p_opptr 0x000000b0 +#define AOFF_task_p_opptr 0x000000b8 #define ASIZ_task_p_opptr 0x00000008 -#define AOFF_task_p_pptr 0x000000b8 +#define AOFF_task_p_pptr 0x000000c0 #define ASIZ_task_p_pptr 0x00000008 -#define AOFF_task_p_cptr 0x000000c0 +#define AOFF_task_p_cptr 0x000000c8 #define ASIZ_task_p_cptr 0x00000008 -#define AOFF_task_p_ysptr 0x000000c8 +#define AOFF_task_p_ysptr 0x000000d0 #define ASIZ_task_p_ysptr 0x00000008 -#define AOFF_task_p_osptr 0x000000d0 +#define AOFF_task_p_osptr 0x000000d8 #define ASIZ_task_p_osptr 0x00000008 -#define AOFF_task_pidhash_next 0x000000d8 +#define AOFF_task_pidhash_next 0x000000e0 #define ASIZ_task_pidhash_next 0x00000008 -#define AOFF_task_pidhash_pprev 0x000000e0 +#define AOFF_task_pidhash_pprev 0x000000e8 #define ASIZ_task_pidhash_pprev 0x00000008 -#define AOFF_task_tarray_ptr 0x000000e8 +#define AOFF_task_tarray_ptr 0x000000f0 #define ASIZ_task_tarray_ptr 0x00000008 -#define AOFF_task_wait_chldexit 0x000000f0 +#define AOFF_task_wait_chldexit 0x000000f8 #define ASIZ_task_wait_chldexit 0x00000008 -#define AOFF_task_vfork_sem 0x000000f8 +#define AOFF_task_vfork_sem 0x00000100 #define ASIZ_task_vfork_sem 0x00000008 -#define AOFF_task_policy 0x00000100 +#define AOFF_task_policy 0x00000108 #define ASIZ_task_policy 0x00000008 -#define AOFF_task_rt_priority 0x00000108 +#define AOFF_task_rt_priority 0x00000110 #define ASIZ_task_rt_priority 0x00000008 -#define AOFF_task_it_real_value 0x00000110 +#define AOFF_task_it_real_value 0x00000118 #define ASIZ_task_it_real_value 0x00000008 -#define AOFF_task_it_prof_value 0x00000118 +#define AOFF_task_it_prof_value 0x00000120 #define ASIZ_task_it_prof_value 0x00000008 -#define AOFF_task_it_virt_value 0x00000120 +#define AOFF_task_it_virt_value 0x00000128 #define ASIZ_task_it_virt_value 0x00000008 -#define AOFF_task_it_real_incr 0x00000128 +#define AOFF_task_it_real_incr 0x00000130 #define ASIZ_task_it_real_incr 0x00000008 -#define AOFF_task_it_prof_incr 0x00000130 +#define AOFF_task_it_prof_incr 0x00000138 #define ASIZ_task_it_prof_incr 0x00000008 -#define AOFF_task_it_virt_incr 0x00000138 +#define AOFF_task_it_virt_incr 0x00000140 #define ASIZ_task_it_virt_incr 0x00000008 -#define AOFF_task_real_timer 0x00000140 +#define AOFF_task_real_timer 0x00000148 #define ASIZ_task_real_timer 0x00000028 -#define AOFF_task_times 0x00000168 +#define AOFF_task_times 0x00000170 #define ASIZ_task_times 0x00000020 -#define AOFF_task_start_time 0x00000188 +#define AOFF_task_start_time 0x00000190 #define ASIZ_task_start_time 0x00000008 -#define AOFF_task_per_cpu_utime 0x00000190 +#define AOFF_task_per_cpu_utime 0x00000198 #define ASIZ_task_per_cpu_utime 0x00000100 -#define AOFF_task_min_flt 0x00000390 +#define AOFF_task_min_flt 0x00000398 #define ASIZ_task_min_flt 0x00000008 -#define AOFF_task_maj_flt 0x00000398 +#define AOFF_task_maj_flt 0x000003a0 #define ASIZ_task_maj_flt 0x00000008 -#define AOFF_task_nswap 0x000003a0 +#define AOFF_task_nswap 0x000003a8 #define ASIZ_task_nswap 0x00000008 -#define AOFF_task_cmin_flt 0x000003a8 +#define AOFF_task_cmin_flt 0x000003b0 #define ASIZ_task_cmin_flt 0x00000008 -#define AOFF_task_cmaj_flt 0x000003b0 +#define AOFF_task_cmaj_flt 0x000003b8 #define ASIZ_task_cmaj_flt 0x00000008 -#define AOFF_task_cnswap 0x000003b8 +#define AOFF_task_cnswap 0x000003c0 #define ASIZ_task_cnswap 0x00000008 -#define AOFF_task_uid 0x000003c4 +#define AOFF_task_uid 0x000003cc #define ASIZ_task_uid 0x00000004 -#define AOFF_task_euid 0x000003c8 +#define AOFF_task_euid 0x000003d0 #define ASIZ_task_euid 0x00000004 -#define AOFF_task_suid 0x000003cc +#define AOFF_task_suid 0x000003d4 #define ASIZ_task_suid 0x00000004 -#define AOFF_task_fsuid 0x000003d0 +#define AOFF_task_fsuid 0x000003d8 #define ASIZ_task_fsuid 0x00000004 -#define AOFF_task_gid 0x000003d4 +#define AOFF_task_gid 0x000003dc #define ASIZ_task_gid 0x00000004 -#define AOFF_task_egid 0x000003d8 +#define AOFF_task_egid 0x000003e0 #define ASIZ_task_egid 0x00000004 -#define AOFF_task_sgid 0x000003dc +#define AOFF_task_sgid 0x000003e4 #define ASIZ_task_sgid 0x00000004 -#define AOFF_task_fsgid 0x000003e0 +#define AOFF_task_fsgid 0x000003e8 #define ASIZ_task_fsgid 0x00000004 -#define AOFF_task_ngroups 0x000003e4 +#define AOFF_task_ngroups 0x000003ec #define ASIZ_task_ngroups 0x00000004 -#define AOFF_task_groups 0x000003e8 +#define AOFF_task_groups 0x000003f0 #define ASIZ_task_groups 0x00000080 -#define AOFF_task_cap_effective 0x00000468 +#define AOFF_task_cap_effective 0x00000470 #define ASIZ_task_cap_effective 0x00000004 -#define AOFF_task_cap_inheritable 0x0000046c +#define AOFF_task_cap_inheritable 0x00000474 #define ASIZ_task_cap_inheritable 0x00000004 -#define AOFF_task_cap_permitted 0x00000470 +#define AOFF_task_cap_permitted 0x00000478 #define ASIZ_task_cap_permitted 0x00000004 -#define AOFF_task_user 0x00000478 +#define AOFF_task_user 0x00000480 #define ASIZ_task_user 0x00000008 -#define AOFF_task_rlim 0x00000480 +#define AOFF_task_rlim 0x00000488 #define ASIZ_task_rlim 0x000000a0 -#define AOFF_task_used_math 0x00000520 +#define AOFF_task_used_math 0x00000528 #define ASIZ_task_used_math 0x00000002 -#define AOFF_task_comm 0x00000522 +#define AOFF_task_comm 0x0000052a #define ASIZ_task_comm 0x00000010 -#define AOFF_task_link_count 0x00000534 +#define AOFF_task_link_count 0x0000053c #define ASIZ_task_link_count 0x00000004 -#define AOFF_task_tty 0x00000538 +#define AOFF_task_tty 0x00000540 #define ASIZ_task_tty 0x00000008 -#define AOFF_task_semundo 0x00000540 +#define AOFF_task_semundo 0x00000548 #define ASIZ_task_semundo 0x00000008 -#define AOFF_task_semsleeping 0x00000548 +#define AOFF_task_semsleeping 0x00000550 #define ASIZ_task_semsleeping 0x00000008 -#define AOFF_task_tss 0x00000550 +#define AOFF_task_tss 0x00000560 #define ASIZ_task_tss 0x00000470 -#define AOFF_task_fs 0x000009c0 +#define AOFF_task_fs 0x000009d0 #define ASIZ_task_fs 0x00000008 -#define AOFF_task_files 0x000009c8 +#define AOFF_task_files 0x000009d8 #define ASIZ_task_files 0x00000008 -#define AOFF_task_mm 0x000009d0 +#define AOFF_task_mm 0x000009e0 #define ASIZ_task_mm 0x00000008 -#define AOFF_task_sigmask_lock 0x000009d8 +#define AOFF_task_local_pages 0x000009e8 +#define ASIZ_task_local_pages 0x00000010 +#define AOFF_task_allocation_order 0x000009f8 +#define ASIZ_task_allocation_order 0x00000004 +#define AOFF_task_nr_local_pages 0x000009fc +#define ASIZ_task_nr_local_pages 0x00000004 +#define AOFF_task_fs_locks 0x00000a00 +#define ASIZ_task_fs_locks 0x00000004 +#define AOFF_task_sigmask_lock 0x00000a04 #define ASIZ_task_sigmask_lock 0x0000000c -#define AOFF_task_sig 0x000009e8 +#define AOFF_task_sig 0x00000a10 #define ASIZ_task_sig 0x00000008 -#define AOFF_task_signal 0x000009f0 +#define AOFF_task_signal 0x00000a18 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x000009f8 +#define AOFF_task_blocked 0x00000a20 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x00000a00 +#define AOFF_task_sigqueue 0x00000a28 #define ASIZ_task_sigqueue 0x00000008 -#define AOFF_task_sigqueue_tail 0x00000a08 +#define AOFF_task_sigqueue_tail 0x00000a30 #define ASIZ_task_sigqueue_tail 0x00000008 -#define AOFF_task_sas_ss_sp 0x00000a10 +#define AOFF_task_sas_ss_sp 0x00000a38 #define ASIZ_task_sas_ss_sp 0x00000008 -#define AOFF_task_sas_ss_size 0x00000a18 +#define AOFF_task_sas_ss_size 0x00000a40 #define ASIZ_task_sas_ss_size 0x00000008 -#define AOFF_task_parent_exec_id 0x00000a20 +#define AOFF_task_parent_exec_id 0x00000a48 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x00000a24 +#define AOFF_task_self_exec_id 0x00000a4c #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_oom_kill_try 0x00000a28 +#define AOFF_task_oom_kill_try 0x00000a50 #define ASIZ_task_oom_kill_try 0x00000004 -#define ASIZ_task 0x00000a30 +#define ASIZ_task 0x00000a60 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index cca3d1303f30..61c6f15f0d6d 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -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); diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h index fb24b8efb717..fdc80377a519 100644 --- a/include/linux/mc146818rtc.h +++ b/include/linux/mc146818rtc.h @@ -11,6 +11,7 @@ #ifndef _MC146818RTC_H #define _MC146818RTC_H #include +#include #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 , 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 index 000000000000..af61a1510f5c --- /dev/null +++ b/include/linux/rtc.h @@ -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 , but it needs to be here so that the kernel + * source is self contained, allowing cross-compiles, etc. etc. + */ + +struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +/* + * ioctls that are permitted to the /dev/rtc interface. + */ + +#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */ +#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */ +#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */ +#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */ +#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */ +#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */ + +#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */ +#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */ +#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */ +#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */ +#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */ +#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */ +#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */ +#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */ + +#endif /* _LINUX_RTC_H_ */ diff --git a/include/net/ip.h b/include/net/ip.h index f86259908919..47f7eeb94a02 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -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; } diff --git a/init/main.c b/init/main.c index 2f4f06e2b733..155476ec365e 100644 --- a/init/main.c +++ b/init/main.c @@ -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) }, diff --git a/net/core/dev.c b/net/core/dev.c index d7f2e31fe36b..adfaae99d74a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -649,7 +649,7 @@ int dev_queue_xmit(struct sk_buff *skb) /*======================================================================= - Receiver rotutines + Receiver routines =======================================================================*/ int netdev_dropping = 0; diff --git a/net/ipv4/ip_masq_raudio.c b/net/ipv4/ip_masq_raudio.c index ee3e276b9d8b..2d42a068bb90 100644 --- a/net/ipv4/ip_masq_raudio.c +++ b/net/ipv4/ip_masq_raudio.c @@ -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; diff --git a/scripts/kwhich b/scripts/kwhich index 032989c5a17d..66ff487a2fe3 100644 --- a/scripts/kwhich +++ b/scripts/kwhich @@ -7,7 +7,7 @@ then exit 1 fi -IFS=: +IFS=":$IFS" for cmd in $* do for path in $PATH -- 2.39.5