From 564ea1ed169419ae44574df17b695f75b7f1b83e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:13:08 -0500 Subject: [PATCH] Import 2.1.36 --- Documentation/Configure.help | 13 +- arch/alpha/Makefile | 17 +- arch/alpha/kernel/entry.S | 2 +- arch/alpha/kernel/osf_sys.c | 82 +- arch/alpha/kernel/signal.c | 179 +- arch/alpha/kernel/traps.c | 384 +++- arch/alpha/mm/init.c | 16 +- arch/alpha/vmlinux.lds | 96 +- arch/i386/kernel/entry.S | 3 +- arch/i386/kernel/head.S | 7 +- arch/i386/mm/init.c | 82 +- arch/m68k/amiga/retz3fb.c | 3504 +++++++++++++++++++++++++++++++++++++ arch/m68k/amiga/retz3fb.h | 572 ++++++ arch/m68k/kernel/entry.S | 2 +- arch/sparc/kernel/irq.c | 182 +- arch/sparc/kernel/sparc_ksyms.c | 14 +- arch/sparc/kernel/systbls.S | 4 +- arch/sparc/kernel/time.c | 10 +- arch/sparc/lib/Makefile | 9 +- arch/sparc/lib/checksum.S | 4 +- arch/sparc/lib/irqlock.S | 185 ++ arch/sparc/lib/locks.S | 2 +- arch/sparc/mm/Makefile | 9 +- arch/sparc/mm/hypersparc.S | 9 +- arch/sparc/mm/init.c | 19 +- arch/sparc/mm/srmmu.c | 307 +--- arch/sparc/mm/viking.S | 267 +++ arch/sparc64/config.in | 7 +- arch/sparc64/defconfig | 1 + arch/sparc64/kernel/Makefile | 8 +- arch/sparc64/kernel/sys_sparc32.c | 489 +++++- arch/sparc64/kernel/systbls.S | 11 +- arch/sparc64/lib/checksum.S | 11 +- arch/sparc64/mm/init.c | 3 +- drivers/block/Config.in | 2 +- drivers/block/ide.c | 1 + drivers/block/triton.c | 28 +- drivers/char/amigamouse.c | 3 +- drivers/char/apm_bios.c | 7 +- drivers/char/atarimouse.c | 3 +- drivers/char/atixlmouse.c | 3 +- drivers/char/busmouse.c | 3 +- drivers/char/cyclades.c | 25 +- drivers/char/digi_bios.h | 2 +- drivers/char/digi_fep.h | 2 +- drivers/char/dsp56k.c | 1150 ++++++++++++ drivers/char/esp.c | 7 +- drivers/char/istallion.c | 27 +- drivers/char/keyb_m68k.c | 3 +- drivers/char/keyboard.c | 5 +- drivers/char/lp.c | 3 +- drivers/char/misc.c | 3 +- drivers/char/msbusmouse.c | 3 +- drivers/char/pcwd.c | 13 +- drivers/char/pcxx.c | 4 +- drivers/char/psaux.c | 5 +- drivers/char/pty.c | 3 +- drivers/char/random.c | 8 +- drivers/char/riscom8.c | 17 +- drivers/char/rtc.c | 3 +- drivers/char/serial.c | 6 +- drivers/char/softdog.c | 3 +- drivers/char/stallion.c | 25 +- drivers/char/tty_io.c | 3 +- drivers/char/vc_screen.c | 3 +- drivers/char/wdt.c | 23 +- drivers/net/3c501.c | 7 +- drivers/net/3c503.c | 15 +- drivers/net/3c505.c | 11 +- drivers/net/3c507.c | 7 +- drivers/net/3c509.c | 7 +- drivers/net/3c523.c | 19 +- drivers/net/3c59x.c | 13 +- drivers/net/8390.c | 3 +- drivers/net/a2065.c | 3 +- drivers/net/ac3200.c | 7 +- drivers/net/apricot.c | 5 +- drivers/net/arcnet.c | 13 +- drivers/net/ariadne.c | 3 +- drivers/net/at1700.c | 11 +- drivers/net/atari_bionet.c | 5 +- drivers/net/atari_pamsnet.c | 5 +- drivers/net/atarilance.c | 9 +- drivers/net/atp.c | 11 +- drivers/net/baycom.c | 5 +- drivers/net/bpqether.c | 3 +- drivers/net/cs89x0.c | 25 +- drivers/net/de4x5.c | 33 +- drivers/net/de600.c | 5 +- drivers/net/de620.c | 13 +- drivers/net/defxx.c | 21 +- drivers/net/depca.c | 37 +- drivers/net/dgrs.c | 27 +- drivers/net/dgrs_firmware.c | 2 +- drivers/net/dlci.c | 3 +- drivers/net/dummy.c | 5 +- drivers/net/e2100.c | 5 +- drivers/net/eepro.c | 9 +- drivers/net/eepro100.c | 9 +- drivers/net/eql.c | 3 +- drivers/net/es3210.c | 9 +- drivers/net/eth16i.c | 13 +- drivers/net/ewrk3.c | 31 +- drivers/net/fmv18x.c | 9 +- drivers/net/hdlcdrv.c | 1 - drivers/net/hp-plus.c | 7 +- drivers/net/hp.c | 11 +- drivers/net/hp100.c | 5 +- drivers/net/hydra.c | 3 +- drivers/net/ibmtr.c | 19 +- drivers/net/lance.c | 7 +- drivers/net/lapbether.c | 3 +- drivers/net/loopback.c | 3 +- drivers/net/ltpc.c | 5 +- drivers/net/mkiss.c | 5 +- drivers/net/ne.c | 15 +- drivers/net/ni52.c | 7 +- drivers/net/ni65.c | 9 +- drivers/net/pcnet32.c | 7 +- drivers/net/pi2.c | 10 +- drivers/net/plip.c | 74 +- drivers/net/ppp.c | 5 +- drivers/net/pt.c | 6 +- drivers/net/scc.c | 3 +- drivers/net/sdla.c | 10 +- drivers/net/sdla_fr.c | 3 +- drivers/net/sdla_ppp.c | 3 +- drivers/net/sdla_x25.c | 3 +- drivers/net/sdladrv.c | 4 +- drivers/net/seeq8005.c | 9 +- drivers/net/shaper.c | 3 +- drivers/net/slhc.c | 3 +- drivers/net/slip.c | 3 +- drivers/net/smc-mca.c | 3 +- drivers/net/smc-ultra.c | 7 +- drivers/net/smc9194.c | 11 +- drivers/net/tulip.c | 15 +- drivers/net/tunnel.c | 3 +- drivers/net/wd.c | 7 +- drivers/net/x25_asy.c | 3 +- drivers/net/znet.c | 3 +- drivers/pci/pci.c | 1 + drivers/pnp/parport_init.c | 2 +- drivers/sbus/char/creator.c | 98 ++ drivers/sbus/char/linux_logo.h | 1037 ----------- drivers/sbus/char/sunkbd.c | 2 +- drivers/scsi/53c7,8xx.c | 15 +- drivers/scsi/AM53C974.c | 13 +- drivers/scsi/BusLogic.c | 53 +- drivers/scsi/NCR5380.c | 12 +- drivers/scsi/NCR53c406a.c | 11 +- drivers/scsi/advansys.c | 99 +- drivers/scsi/aic7xxx.c | 1 + drivers/scsi/dtc.c | 15 +- drivers/scsi/g_NCR5380.c | 15 +- drivers/scsi/hosts.c | 3 +- drivers/scsi/ncr53c8xx.c | 2 +- drivers/scsi/ncr53c8xx.h | 2 +- drivers/scsi/pas16.c | 42 +- drivers/scsi/scsi.c | 3 +- drivers/scsi/t128.c | 18 +- fs/binfmt_em86.c | 2 + fs/buffer.c | 455 ++--- fs/dcache.c | 190 +- fs/filesystems.c | 34 +- fs/inode.c | 1312 +++++++------- fs/nfsd/nfsctl.c | 31 +- fs/nfsd/nfssvc.c | 4 +- include/asm-alpha/init.h | 15 +- include/asm-alpha/processor.h | 1 + include/asm-alpha/softirq.h | 6 + include/asm-alpha/spinlock.h | 48 +- include/asm-alpha/sysinfo.h | 36 + include/asm-i386/pgtable.h | 7 +- include/asm-i386/softirq.h | 6 + include/asm-i386/spinlock.h | 2 + include/asm-m68k/dsp56k.h | 70 + include/asm-m68k/fpu.h | 40 + include/asm-m68k/hardirq.h | 26 + include/asm-m68k/namei.h | 42 + include/asm-m68k/poll.h | 42 + include/asm-m68k/smp_lock.h | 28 + include/asm-m68k/softirq.h | 118 ++ include/asm-m68k/spinlock.h | 74 + include/asm-m68k/zorro.h | 577 ------ include/asm-sparc/hardirq.h | 5 +- include/asm-sparc/irq.h | 34 +- include/asm-sparc/linux_logo.h | 2090 ++++++++++++++++++++++ include/asm-sparc/mxcc.h | 6 +- include/asm-sparc/smp_lock.h | 13 - include/asm-sparc/softirq.h | 33 +- include/asm-sparc/spinlock.h | 70 +- include/asm-sparc/system.h | 96 +- include/asm-sparc/viking.h | 6 +- include/asm-sparc64/linux_logo.h | 2084 ++++++++++++++++++++++ include/asm-sparc64/signal.h | 8 +- include/asm-sparc64/softirq.h | 6 + include/asm-sparc64/spinlock.h | 28 + include/asm-sparc64/stat.h | 19 +- include/asm-sparc64/unistd.h | 4 +- include/linux/fs.h | 16 +- include/linux/mm.h | 2 +- include/linux/pagemap.h | 27 +- include/linux/pci.h | 1 + include/linux/skbuff.h | 29 +- include/linux/sysctl.h | 5 + include/linux/vmalloc.h | 4 +- include/linux/zorro.h | 1278 ++++++++++++++ include/net/sock.h | 78 +- include/net/tcp.h | 119 +- init/main.c | 2 +- kernel/exit.c | 23 +- kernel/fork.c | 10 +- kernel/info.c | 4 +- kernel/itimer.c | 43 +- kernel/ksyms.c | 7 + kernel/sched.c | 50 +- kernel/signal.c | 4 +- kernel/sys.c | 275 ++- kernel/time.c | 15 +- mm/page_alloc.c | 4 +- mm/swap.c | 6 +- net/bridge/br.c | 3 +- net/core/dev.c | 12 +- net/core/net_alias.c | 3 +- net/core/skbuff.c | 560 +----- net/core/sock.c | 6 - net/ethernet/eth.c | 1 - net/ipv4/icmp.c | 2 +- net/ipv4/ip_fragment.c | 1 - net/ipv4/ip_sockglue.c | 4 +- net/ipv4/proc.c | 2 +- net/ipv4/sysctl_net_ipv4.c | 21 + net/ipv4/tcp.c | 554 ++---- net/ipv4/tcp_input.c | 1406 +++++++-------- net/ipv4/tcp_ipv4.c | 354 ++-- net/ipv4/tcp_output.c | 654 +++---- net/ipv4/tcp_timer.c | 179 +- net/ipv4/udp.c | 10 +- net/ipv6/ipv6_sockglue.c | 6 +- net/ipv6/proc.c | 14 +- net/ipv6/tcp_ipv6.c | 144 +- 242 files changed, 16667 insertions(+), 7008 deletions(-) rewrite arch/alpha/vmlinux.lds (95%) create mode 100644 arch/m68k/amiga/retz3fb.c create mode 100644 arch/m68k/amiga/retz3fb.h create mode 100644 arch/sparc/lib/irqlock.S create mode 100644 arch/sparc/mm/viking.S create mode 100644 drivers/char/dsp56k.c create mode 100644 drivers/sbus/char/creator.c delete mode 100644 drivers/sbus/char/linux_logo.h rewrite fs/inode.c (78%) create mode 100644 include/asm-alpha/sysinfo.h create mode 100644 include/asm-m68k/dsp56k.h create mode 100644 include/asm-m68k/fpu.h create mode 100644 include/asm-m68k/hardirq.h create mode 100644 include/asm-m68k/namei.h create mode 100644 include/asm-m68k/poll.h create mode 100644 include/asm-m68k/smp_lock.h create mode 100644 include/asm-m68k/softirq.h create mode 100644 include/asm-m68k/spinlock.h delete mode 100644 include/asm-m68k/zorro.h create mode 100644 include/asm-sparc/linux_logo.h create mode 100644 include/asm-sparc64/linux_logo.h create mode 100644 include/linux/zorro.h diff --git a/Documentation/Configure.help b/Documentation/Configure.help index f77cb0675..469fb2e02 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -290,12 +290,13 @@ CONFIG_BLK_DEV_RZ1000 Intel 82371 PIIX (Triton I/II) DMA support CONFIG_BLK_DEV_TRITON If your PCI system uses an IDE harddrive (as opposed to SCSI, say) - and includes the Intel Triton I/II IDE interface chipset (i82371FB - or i82371SB), you will want to enable this option to allow use of - bus-mastering DMA data transfers. Read the comments at the beginning - of drivers/block/triton.c and Documentation/ide.txt. You can get - the latest version of the hdparm utility via ftp (user: anonymous) - from sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/; it is + and includes the Intel Triton I/II IDE interface chipset (i82371FB, + i82371SB or i82371AB), you will want to enable this option to allow + use of bus-mastering DMA data transfers. Read the comments at the + beginning of drivers/block/triton.c and Documentation/ide.txt. + You can get the latest version of the hdparm utility via + ftp (user: anonymous) from + sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/; it is used to tune your harddisk. It is safe to say Y to this question. Other IDE chipset support diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index a79a5056e..58fd53354 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -10,21 +10,8 @@ NM := nm -B -ifdef CONFIG_CROSSCOMPILE -# enable this for linking under OSF/1: -LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N -else - elf=$(shell if $(LD) --help | grep elf64alpha >/dev/null; then echo yes; fi) - ifeq ($(elf),yes) - LINKFLAGS = -static -Ttext 0xfffffc0000310000 -N - else - LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N - endif -# GNU gcc/cc1/as can use pipes instead of temporary files -CFLAGS := $(CFLAGS) -pipe -endif - -CFLAGS := $(CFLAGS) -mno-fp-regs -ffixed-8 +LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N +CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8 HEAD := arch/alpha/kernel/head.o diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 5926dd25c..ef582b80e 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -759,6 +759,6 @@ sys_call_table: .quad sys_setfsuid, sys_setfsgid, sys_ustat, sys_statfs, sys_fstatfs .quad sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler, sys_sched_yield .quad sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, do_entSys /* sys_afs_syscall */, sys_newuname - .quad sys_nanosleep, sys_mremap, do_entSys, sys_setresuid, sys_getresuid + .quad sys_nanosleep, sys_mremap, sys_nfsservctl, sys_setresuid, sys_getresuid .quad sys_pciconfig_read, sys_pciconfig_write, sys_query_module .quad do_entSys, do_entSys diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index e2f9bf4c9..ef9576492 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -33,6 +33,7 @@ #include #include #include +#include extern int do_mount(kdev_t, const char *, const char *, char *, int, void *); extern int do_pipe(int *); @@ -840,62 +841,91 @@ out: return err; } -asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer, unsigned long nbytes, +asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer, + unsigned long nbytes, int *start, void *arg) { extern unsigned long rdfpcr(void); - unsigned long fpcw; - unsigned long ret = -EOPNOTSUPP; + unsigned long w; - lock_kernel(); switch (op) { - case 45: /* GSI_IEEE_FP_CONTROL */ + case GSI_IEEE_FP_CONTROL: /* build and return current fp control word: */ - fpcw = current->tss.flags & IEEE_TRAP_ENABLE_MASK; - fpcw |= ((rdfpcr() >> 52) << 17) & IEEE_STATUS_MASK; - put_user(fpcw, (unsigned long *) buffer); - ret = 0; - break; - case 46: /* GSI_IEEE_STATE_AT_SIGNAL */ + w = current->tss.flags & IEEE_TRAP_ENABLE_MASK; + w |= ((rdfpcr() >> 52) << 17) & IEEE_STATUS_MASK; + if (put_user(w, (unsigned long *) buffer)) + return -EFAULT; + return 0; + + case GSI_IEEE_STATE_AT_SIGNAL: /* * Not sure anybody will ever use this weird stuff. These * ops can be used (under OSF/1) to set the fpcr that should * be used when a signal handler starts executing. */ break; + + case GSI_UACPROC: + w = (current->tss.flags >> UAC_SHIFT) & UAC_BITMASK; + if (put_user(w, (unsigned int *)buffer)) + return -EFAULT; + return 0; + default: break; } - unlock_kernel(); - return ret; + + return -EOPNOTSUPP; } -asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer, unsigned long nbytes, +asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer, + unsigned long nbytes, int *start, void *arg) { - unsigned long fpcw; - unsigned long ret = -EOPNOTSUPP; + unsigned long v, w, i; - lock_kernel(); switch (op) { - case 14: /* SSI_IEEE_FP_CONTROL */ + case SSI_IEEE_FP_CONTROL: /* update trap enable bits: */ - get_user(fpcw, (unsigned long *) buffer); + if (get_user(w, (unsigned long *) buffer)) + return -EFAULT; current->tss.flags &= ~IEEE_TRAP_ENABLE_MASK; - current->tss.flags |= (fpcw & IEEE_TRAP_ENABLE_MASK); - ret = 0; - break; - case 15: /* SSI_IEEE_STATE_AT_SIGNAL */ - case 16: /* SSI_IEEE_IGNORE_STATE_AT_SIGNAL */ + current->tss.flags |= (w & IEEE_TRAP_ENABLE_MASK); + return 0; + + case SSI_IEEE_STATE_AT_SIGNAL: + case SSI_IEEE_IGNORE_STATE_AT_SIGNAL: /* * Not sure anybody will ever use this weird stuff. These * ops can be used (under OSF/1) to set the fpcr that should * be used when a signal handler starts executing. */ + break; + + case SSI_NVPAIRS: + for (i = 0; i < nbytes; ++i) { + if (get_user(v, 2*i + (unsigned int *)buffer)) + return -EFAULT; + if (get_user(w, 2*i + 1 + (unsigned int *)buffer)) + return -EFAULT; + switch (v) { + case SSIN_UACPROC: + current->tss.flags &= + ~(UAC_BITMASK << UAC_SHIFT); + current->tss.flags |= + (w & UAC_BITMASK) << UAC_SHIFT; + break; + + default: + return -EOPNOTSUPP; + } + } + return 0; + default: break; } - unlock_kernel(); - return ret; + + return -EOPNOTSUPP; } diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 38b32b203..5c3eb79ef 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -80,18 +80,17 @@ asmlinkage int do_sigsuspend(unsigned long mask, struct pt_regs * regs, struct s { unsigned long oldmask; - lock_kernel(); + spin_lock_irq(¤t->sigmask_lock); oldmask = current->blocked; current->blocked = mask & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(oldmask,regs, sw, 0, 0)) - goto out; + if (do_signal(oldmask, regs, sw, 0, 0)) + return -EINTR; } -out: - unlock_kernel(); - return -EINTR; } /* @@ -104,60 +103,64 @@ asmlinkage void do_sigreturn(struct sigcontext * sc, int i; /* verify that it's a good sigcontext before using it */ - lock_kernel(); if (verify_area(VERIFY_READ, sc, sizeof(*sc))) - do_exit(SIGSEGV); - get_user(ps, &sc->sc_ps); - if (ps != 8) - do_exit(SIGSEGV); - get_user(mask, &sc->sc_mask); - if (mask & ~_BLOCKABLE) - do_exit(SIGSEGV); + goto give_sigsegv; + if (__get_user(ps, &sc->sc_ps) || ps != 8) + goto give_sigsegv; + if (__get_user(mask, &sc->sc_mask) || (mask & ~_BLOCKABLE)) + goto give_sigsegv; /* ok, looks fine, start restoring */ - get_user(usp, sc->sc_regs+30); + __get_user(usp, sc->sc_regs+30); wrusp(usp); - get_user(regs->pc, &sc->sc_pc); + __get_user(regs->pc, &sc->sc_pc); sw->r26 = (unsigned long) ret_from_sys_call; current->blocked = mask; - get_user(regs->r0, sc->sc_regs+0); - get_user(regs->r1, sc->sc_regs+1); - get_user(regs->r2, sc->sc_regs+2); - get_user(regs->r3, sc->sc_regs+3); - get_user(regs->r4, sc->sc_regs+4); - get_user(regs->r5, sc->sc_regs+5); - get_user(regs->r6, sc->sc_regs+6); - get_user(regs->r7, sc->sc_regs+7); - get_user(regs->r8, sc->sc_regs+8); - get_user(sw->r9, sc->sc_regs+9); - get_user(sw->r10, sc->sc_regs+10); - get_user(sw->r11, sc->sc_regs+11); - get_user(sw->r12, sc->sc_regs+12); - get_user(sw->r13, sc->sc_regs+13); - get_user(sw->r14, sc->sc_regs+14); - get_user(sw->r15, sc->sc_regs+15); - get_user(regs->r16, sc->sc_regs+16); - get_user(regs->r17, sc->sc_regs+17); - get_user(regs->r18, sc->sc_regs+18); - get_user(regs->r19, sc->sc_regs+19); - get_user(regs->r20, sc->sc_regs+20); - get_user(regs->r21, sc->sc_regs+21); - get_user(regs->r22, sc->sc_regs+22); - get_user(regs->r23, sc->sc_regs+23); - get_user(regs->r24, sc->sc_regs+24); - get_user(regs->r25, sc->sc_regs+25); - get_user(regs->r26, sc->sc_regs+26); - get_user(regs->r27, sc->sc_regs+27); - get_user(regs->r28, sc->sc_regs+28); - get_user(regs->gp, sc->sc_regs+29); + __get_user(regs->r0, sc->sc_regs+0); + __get_user(regs->r1, sc->sc_regs+1); + __get_user(regs->r2, sc->sc_regs+2); + __get_user(regs->r3, sc->sc_regs+3); + __get_user(regs->r4, sc->sc_regs+4); + __get_user(regs->r5, sc->sc_regs+5); + __get_user(regs->r6, sc->sc_regs+6); + __get_user(regs->r7, sc->sc_regs+7); + __get_user(regs->r8, sc->sc_regs+8); + __get_user(sw->r9, sc->sc_regs+9); + __get_user(sw->r10, sc->sc_regs+10); + __get_user(sw->r11, sc->sc_regs+11); + __get_user(sw->r12, sc->sc_regs+12); + __get_user(sw->r13, sc->sc_regs+13); + __get_user(sw->r14, sc->sc_regs+14); + __get_user(sw->r15, sc->sc_regs+15); + __get_user(regs->r16, sc->sc_regs+16); + __get_user(regs->r17, sc->sc_regs+17); + __get_user(regs->r18, sc->sc_regs+18); + __get_user(regs->r19, sc->sc_regs+19); + __get_user(regs->r20, sc->sc_regs+20); + __get_user(regs->r21, sc->sc_regs+21); + __get_user(regs->r22, sc->sc_regs+22); + __get_user(regs->r23, sc->sc_regs+23); + __get_user(regs->r24, sc->sc_regs+24); + __get_user(regs->r25, sc->sc_regs+25); + __get_user(regs->r26, sc->sc_regs+26); + __get_user(regs->r27, sc->sc_regs+27); + __get_user(regs->r28, sc->sc_regs+28); + __get_user(regs->gp, sc->sc_regs+29); for (i = 0; i < 31; i++) - get_user(sw->fp[i], sc->sc_fpregs+i); + __get_user(sw->fp[i], sc->sc_fpregs+i); /* send SIGTRAP if we're single-stepping: */ + lock_kernel(); if (ptrace_cancel_bpt (current)) send_sig(SIGTRAP, current, 1); unlock_kernel(); + return; + +give_sigsegv: + lock_kernel(); + do_exit(SIGSEGV); + unlock_kernel(); } /* @@ -181,46 +184,46 @@ static void setup_frame(struct sigaction * sa, wrusp((unsigned long) sc); - put_user(oldmask, &sc->sc_mask); - put_user(8, &sc->sc_ps); - put_user(regs->pc, &sc->sc_pc); - put_user(oldsp, sc->sc_regs+30); - - put_user(regs->r0 , sc->sc_regs+0); - put_user(regs->r1 , sc->sc_regs+1); - put_user(regs->r2 , sc->sc_regs+2); - put_user(regs->r3 , sc->sc_regs+3); - put_user(regs->r4 , sc->sc_regs+4); - put_user(regs->r5 , sc->sc_regs+5); - put_user(regs->r6 , sc->sc_regs+6); - put_user(regs->r7 , sc->sc_regs+7); - put_user(regs->r8 , sc->sc_regs+8); - put_user(sw->r9 , sc->sc_regs+9); - put_user(sw->r10 , sc->sc_regs+10); - put_user(sw->r11 , sc->sc_regs+11); - put_user(sw->r12 , sc->sc_regs+12); - put_user(sw->r13 , sc->sc_regs+13); - put_user(sw->r14 , sc->sc_regs+14); - put_user(sw->r15 , sc->sc_regs+15); - put_user(regs->r16, sc->sc_regs+16); - put_user(regs->r17, sc->sc_regs+17); - put_user(regs->r18, sc->sc_regs+18); - put_user(regs->r19, sc->sc_regs+19); - put_user(regs->r20, sc->sc_regs+20); - put_user(regs->r21, sc->sc_regs+21); - put_user(regs->r22, sc->sc_regs+22); - put_user(regs->r23, sc->sc_regs+23); - put_user(regs->r24, sc->sc_regs+24); - put_user(regs->r25, sc->sc_regs+25); - put_user(regs->r26, sc->sc_regs+26); - put_user(regs->r27, sc->sc_regs+27); - put_user(regs->r28, sc->sc_regs+28); - put_user(regs->gp , sc->sc_regs+29); + __put_user(oldmask, &sc->sc_mask); + __put_user(8, &sc->sc_ps); + __put_user(regs->pc, &sc->sc_pc); + __put_user(oldsp, sc->sc_regs+30); + + __put_user(regs->r0 , sc->sc_regs+0); + __put_user(regs->r1 , sc->sc_regs+1); + __put_user(regs->r2 , sc->sc_regs+2); + __put_user(regs->r3 , sc->sc_regs+3); + __put_user(regs->r4 , sc->sc_regs+4); + __put_user(regs->r5 , sc->sc_regs+5); + __put_user(regs->r6 , sc->sc_regs+6); + __put_user(regs->r7 , sc->sc_regs+7); + __put_user(regs->r8 , sc->sc_regs+8); + __put_user(sw->r9 , sc->sc_regs+9); + __put_user(sw->r10 , sc->sc_regs+10); + __put_user(sw->r11 , sc->sc_regs+11); + __put_user(sw->r12 , sc->sc_regs+12); + __put_user(sw->r13 , sc->sc_regs+13); + __put_user(sw->r14 , sc->sc_regs+14); + __put_user(sw->r15 , sc->sc_regs+15); + __put_user(regs->r16, sc->sc_regs+16); + __put_user(regs->r17, sc->sc_regs+17); + __put_user(regs->r18, sc->sc_regs+18); + __put_user(regs->r19, sc->sc_regs+19); + __put_user(regs->r20, sc->sc_regs+20); + __put_user(regs->r21, sc->sc_regs+21); + __put_user(regs->r22, sc->sc_regs+22); + __put_user(regs->r23, sc->sc_regs+23); + __put_user(regs->r24, sc->sc_regs+24); + __put_user(regs->r25, sc->sc_regs+25); + __put_user(regs->r26, sc->sc_regs+26); + __put_user(regs->r27, sc->sc_regs+27); + __put_user(regs->r28, sc->sc_regs+28); + __put_user(regs->gp , sc->sc_regs+29); for (i = 0; i < 31; i++) - put_user(sw->fp[i], sc->sc_fpregs+i); - put_user(regs->trap_a0, &sc->sc_traparg_a0); - put_user(regs->trap_a1, &sc->sc_traparg_a1); - put_user(regs->trap_a2, &sc->sc_traparg_a2); + __put_user(sw->fp[i], sc->sc_fpregs+i); + __put_user(regs->trap_a0, &sc->sc_traparg_a0); + __put_user(regs->trap_a1, &sc->sc_traparg_a1); + __put_user(regs->trap_a2, &sc->sc_traparg_a2); /* * The following is: @@ -231,8 +234,8 @@ static void setup_frame(struct sigaction * sa, * * ie, "sigreturn(stack-pointer)" */ - put_user(0x43ecf40047de0410, sc->sc_retcode+0); - put_user(0x0000000000000083, sc->sc_retcode+1); + __put_user(0x43ecf40047de0410, sc->sc_retcode+0); + __put_user(0x0000000000000083, sc->sc_retcode+1); imb(); /* "return" to the handler */ diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index eb4ce5cbd..02fa5a35d 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -16,6 +16,9 @@ #include #include #include +#include +#include + void die_if_kernel(char * str, struct pt_regs * regs, long err, unsigned long *r9_15) @@ -81,10 +84,13 @@ asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, return; /* emulation was successful */ } } + + lock_kernel(); printk("%s: arithmetic trap at %016lx: %02lx %016lx\n", current->comm, regs.pc, summary, write_mask); die_if_kernel("Arithmetic fault", ®s, 0, 0); force_sig(SIGFPE, current); + unlock_kernel(); } asmlinkage void do_entIF(unsigned long type, unsigned long a1, @@ -93,6 +99,7 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1, { extern int ptrace_cancel_bpt (struct task_struct *who); + lock_kernel(); die_if_kernel("Instruction fault", ®s, type, 0); switch (type) { case 0: /* breakpoint */ @@ -171,6 +178,7 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1, default: panic("do_entIF: unexpected instruction-fault type"); } + unlock_kernel(); } /* @@ -204,21 +212,10 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, unsigned long a3, unsigned long a4, unsigned long a5, struct allregs regs) { - static int cnt = 0; - static long last_time = 0; long error, tmp1, tmp2, tmp3, tmp4; unsigned long pc = regs.pc - 4; unsigned fixup; - if (cnt >= 5 && jiffies - last_time > 5*HZ) { - cnt = 0; - } - if (++cnt < 5) { - printk("kernel: unaligned trap at %016lx: %p %lx %ld\n", - pc, va, opcode, reg); - } - last_time = jiffies; - unaligned[0].count++; unaligned[0].va = (unsigned long) va; unaligned[0].pc = pc; @@ -228,7 +225,6 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, exception will we decide whether we should have caught it. */ switch (opcode) { -#ifdef __HAVE_CPU_BWX case 0x0c: /* ldwu */ __asm__ __volatile__( "1: ldq_u %1,0(%3)\n" @@ -248,7 +244,6 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, goto got_exception; una_reg(reg) = tmp1|tmp2; return; -#endif case 0x28: /* ldl */ __asm__ __volatile__( @@ -293,7 +288,6 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, /* Note that the store sequences do not indicate that they change memory because it _should_ be affecting nothing in this context. (Otherwise we have other, much larger, problems.) */ -#ifdef __HAVE_CPU_BWX case 0x0d: /* stw */ __asm__ __volatile__( "1: ldq_u %2,1(%5)\n" @@ -323,7 +317,6 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, if (error) goto got_exception; return; -#endif case 0x2c: /* stl */ __asm__ __volatile__( @@ -385,9 +378,12 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, goto got_exception; return; } + + lock_kernel(); printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n", pc, va, opcode, reg); do_exit(SIGSEGV); + unlock_kernel(); return; got_exception: @@ -396,17 +392,23 @@ got_exception: if ((fixup = search_exception_table(pc)) != 0) { unsigned long newpc; newpc = fixup_exception(una_reg, fixup, pc); + + lock_kernel(); printk("Forwarding unaligned exception at %lx (%lx)\n", pc, newpc); + unlock_kernel(); + (®s)->pc = newpc; return; } /* Yikes! No one to forward the exception to. */ + lock_kernel(); printk("%s: unhandled unaligned exception at pc=%lx ra=%lx" " (bad address = %p)\n", current->comm, pc, una_reg(26), va); do_exit(SIGSEGV); + unlock_kernel(); } /* @@ -466,50 +468,68 @@ static inline unsigned long s_reg_to_mem (unsigned long s_reg) * uses them as temporary storage for integer memory to memory copies. * However, we need to deal with stt/ldt and sts/lds only. */ -asmlinkage void do_entUnaUser(void * va, unsigned long opcode, unsigned long reg, - unsigned long * frame) + +#define OP_INT_MASK ( 1L << 0x28 | 1L << 0x2c /* ldl stl */ \ + | 1L << 0x29 | 1L << 0x2d /* ldq stq */ \ + | 1L << 0x0c | 1L << 0x0d ) /* ldwu stw */ + +#define OP_WRITE_MASK ( 1L << 0x26 | 1L << 0x27 /* sts stt */ \ + | 1L << 0x2c | 1L << 0x2d /* stl stq */ \ + | 1L << 0xd ) /* stw */ + +asmlinkage void do_entUnaUser(void * va, unsigned long opcode, + unsigned long reg, unsigned long * frame) { - long dir, size; - unsigned long *reg_addr, *pc_addr, usp, zero = 0; - static int cnt = 0; - static long last_time = 0; extern void alpha_write_fp_reg (unsigned long reg, unsigned long val); extern unsigned long alpha_read_fp_reg (unsigned long reg); - pc_addr = frame + 7 + 20 + 1; /* pc in PAL frame */ + static int cnt = 0; + static long last_time = 0; - if (cnt >= 5 && jiffies - last_time > 5*HZ) { - cnt = 0; - } - if (++cnt < 5) { - printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", - current->comm, current->pid, - *pc_addr - 4, va, opcode, reg); - } - last_time = jiffies; + unsigned long tmp1, tmp2, tmp3, tmp4; + unsigned long *reg_addr, *pc_addr, fake_reg; + unsigned long uac_bits; + long error; - ++unaligned[1].count; - unaligned[1].va = (unsigned long) va - 4; - unaligned[1].pc = *pc_addr; + pc_addr = frame + 7 + 20 + 1; /* pc in PAL frame */ - dir = VERIFY_READ; - if (opcode & 0x4) { - /* it's a stl, stq, stt, or sts */ - dir = VERIFY_WRITE; + /* Check the UAC bits to decide what the user wants us to do + with the unaliged access. */ + + uac_bits = (current->tss.flags >> UAC_SHIFT) & UAC_BITMASK; + if (!(uac_bits & UAC_NOPRINT)) { + if (cnt >= 5 && jiffies - last_time > 5*HZ) { + cnt = 0; + } + if (++cnt < 5) { + lock_kernel(); + printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", + current->comm, current->pid, + *pc_addr - 4, va, opcode, reg); + unlock_kernel(); + } + last_time = jiffies; } - size = 4; - if (opcode & 0x1) { - /* it's a quadword op */ - size = 8; + if (uac_bits & UAC_SIGBUS) { + goto give_sigbus; } - if (verify_area(dir, va, size)) { - *pc_addr -= 4; /* make pc point to faulting insn */ - force_sig(SIGSEGV, current); + if (uac_bits & UAC_NOFIX) { + /* Not sure why you'd want to use this, but... */ return; } + /* Don't bother reading ds in the access check since we already + know that this came from the user. Also rely on the fact that + the page at TASK_SIZE is unmapped and so can't be touched anyway. */ + if (!__access_ok((unsigned long)va, 0, USER_DS)) + goto give_sigsegv; + + ++unaligned[1].count; + unaligned[1].va = (unsigned long)va; + unaligned[1].pc = *pc_addr - 4; + reg_addr = frame; - if (opcode >= 0x28) { + if ((1L << opcode) & OP_INT_MASK) { /* it's an integer load/store */ switch (reg) { case 0: case 1: case 2: case 3: case 4: @@ -542,57 +562,249 @@ asmlinkage void do_entUnaUser(void * va, unsigned long opcode, unsigned long reg case 30: /* usp in PAL regs */ - usp = rdusp(); - reg_addr = &usp; + fake_reg = rdusp(); + reg_addr = &fake_reg; break; case 31: /* zero "register" */ - reg_addr = &zero; + fake_reg = 0; + reg_addr = &fake_reg; break; } } + /* We don't want to use the generic get/put unaligned macros as + we want to trap exceptions. Only if we actually get an + exception will we decide whether we should have caught it. */ + switch (opcode) { - case 0x22: /* lds */ - alpha_write_fp_reg(reg, s_mem_to_reg( - get_unaligned((unsigned int *)va))); - break; - case 0x26: /* sts */ - put_unaligned(s_reg_to_mem(alpha_read_fp_reg(reg)), - (unsigned int *)va); + case 0x0c: /* ldwu */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,1(%3)\n" + " extwl %1,%3,%1\n" + " extwh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + *reg_addr = tmp1|tmp2; break; - case 0x23: /* ldt */ - alpha_write_fp_reg(reg, get_unaligned((unsigned long *)va)); - break; - case 0x27: /* stt */ - put_unaligned(alpha_read_fp_reg(reg), (unsigned long *)va); - break; + case 0x22: /* lds */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,3(%3)\n" + " extll %1,%3,%1\n" + " extlh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + alpha_write_fp_reg(reg, s_mem_to_reg((int)(tmp1|tmp2))); + return; - case 0x28: /* ldl */ - *reg_addr = get_unaligned((int *)va); - break; - case 0x2c: /* stl */ - put_unaligned(*reg_addr, (int *)va); - break; + case 0x23: /* ldt */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,7(%3)\n" + " extql %1,%3,%1\n" + " extqh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + alpha_write_fp_reg(reg, tmp1|tmp2); + return; - case 0x29: /* ldq */ - *reg_addr = get_unaligned((long *)va); + case 0x28: /* ldl */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,3(%3)\n" + " extll %1,%3,%1\n" + " extlh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + *reg_addr = (int)(tmp1|tmp2); break; - case 0x2d: /* stq */ - put_unaligned(*reg_addr, (long *)va); + + case 0x29: /* ldq */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,7(%3)\n" + " extql %1,%3,%1\n" + " extqh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + *reg_addr = tmp1|tmp2; break; - default: - *pc_addr -= 4; /* make pc point to faulting insn */ - force_sig(SIGBUS, current); + /* Note that the store sequences do not indicate that they change + memory because it _should_ be affecting nothing in this context. + (Otherwise we have other, much larger, problems.) */ + case 0x0d: /* stw */ + __asm__ __volatile__( + "1: ldq_u %2,1(%5)\n" + "2: ldq_u %1,0(%5)\n" + " inswh %6,%5,%4\n" + " inswl %6,%5,%3\n" + " mskwh %2,%5,%2\n" + " mskwl %1,%5,%1\n" + " or %2,%4,%2\n" + " or %1,%3,%1\n" + "3: stq_u %2,1(%5)\n" + "4: stq_u %1,0(%5)\n" + "5:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %2,5b-1b(%0)\n" + " .gprel32 2b\n" + " lda %1,5b-2b(%0)\n" + " .gprel32 3b\n" + " lda $31,5b-3b(%0)\n" + " .gprel32 4b\n" + " lda $31,5b-4b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), + "=&r"(tmp3), "=&r"(tmp4) + : "r"(va), "r"(*reg_addr), "0"(0)); + if (error) + goto give_sigsegv; + return; + + case 0x26: /* sts */ + fake_reg = s_reg_to_mem(alpha_read_fp_reg(reg)); + reg_addr = &fake_reg; + /* FALLTHRU */ + + case 0x2c: /* stl */ + __asm__ __volatile__( + "1: ldq_u %2,3(%5)\n" + "2: ldq_u %1,0(%5)\n" + " inslh %6,%5,%4\n" + " insll %6,%5,%3\n" + " msklh %2,%5,%2\n" + " mskll %1,%5,%1\n" + " or %2,%4,%2\n" + " or %1,%3,%1\n" + "3: stq_u %2,3(%5)\n" + "4: stq_u %1,0(%5)\n" + "5:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %2,5b-1b(%0)\n" + " .gprel32 2b\n" + " lda %1,5b-2b(%0)\n" + " .gprel32 3b\n" + " lda $31,5b-3b(%0)\n" + " .gprel32 4b\n" + " lda $31,5b-4b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), + "=&r"(tmp3), "=&r"(tmp4) + : "r"(va), "r"(*reg_addr), "0"(0)); + if (error) + goto give_sigsegv; + return; + + case 0x27: /* stt */ + fake_reg = alpha_read_fp_reg(reg); + reg_addr = &fake_reg; + /* FALLTHRU */ + + case 0x2d: /* stq */ + __asm__ __volatile__( + "1: ldq_u %2,7(%5)\n" + "2: ldq_u %1,0(%5)\n" + " insqh %6,%5,%4\n" + " insql %6,%5,%3\n" + " mskqh %2,%5,%2\n" + " mskql %1,%5,%1\n" + " or %2,%4,%2\n" + " or %1,%3,%1\n" + "3: stq_u %2,7(%5)\n" + "4: stq_u %1,0(%5)\n" + "5:\n" + ".section __ex_table,\"a\"\n\t" + " .gprel32 1b\n" + " lda %2,5b-1b(%0)\n" + " .gprel32 2b\n" + " lda %1,5b-2b(%0)\n" + " .gprel32 3b\n" + " lda $31,5b-3b(%0)\n" + " .gprel32 4b\n" + " lda $31,5b-4b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), + "=&r"(tmp3), "=&r"(tmp4) + : "r"(va), "r"(*reg_addr), "0"(0)); + if (error) + goto give_sigsegv; return; - } - if (opcode >= 0x28 && reg == 30 && dir == VERIFY_WRITE) { - wrusp(usp); + default: + /* What instruction were you trying to use, exactly? */ + goto give_sigbus; } + + /* Only integer loads should get here; everyone else returns early. */ + if (reg == 30) + wrusp(fake_reg); + return; + +give_sigsegv: + *pc_addr -= 4; /* make pc point to faulting insn */ + lock_kernel(); + force_sig(SIGSEGV, current); + unlock_kernel(); + return; + +give_sigbus: + *pc_addr -= 4; + lock_kernel(); + force_sig(SIGBUS, current); + unlock_kernel(); + return; } /* @@ -610,8 +822,11 @@ asmlinkage long do_entSys(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { - if (regs.r0 != 112) + lock_kernel(); + /* Only report OSF system calls. */ + if (regs.r0 != 112 && regs.r0 < 300) printk("", regs.r0, a0, a1, a2); + unlock_kernel(); return -1; } @@ -621,16 +836,11 @@ extern asmlinkage void entArith(void); extern asmlinkage void entUna(void); extern asmlinkage void entSys(void); +register unsigned long gptr __asm__("$29"); + void trap_init(void) { - unsigned long gptr; - - /* - * Tell PAL-code what global pointer we want in the kernel.. - */ - __asm__("br %0,___tmp\n" - "___tmp:\tldgp %0,0(%0)" - : "=r" (gptr)); + /* Tell PAL-code what global pointer we want in the kernel. */ wrkgp(gptr); wrent(entArith, 1); diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 35a325ffc..13e8e4ce4 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -150,7 +150,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) start_mem = PAGE_ALIGN(start_mem); /* - * Mark the pages used by the kernel as reserved.. + * Mark the pages used by the kernel as reserved. */ tmp = KERNEL_START; while (tmp < start_mem) { @@ -171,9 +171,19 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) return; } -void free_initmem(void) +void free_initmem (void) { - /* To be written */ + extern char __init_begin, __init_end; + unsigned long addr; + + addr = (unsigned long)(&__init_begin); + for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { + mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); + atomic_set(&mem_map[MAP_NR(addr)].count, 1); + free_page(addr); + } + printk ("Freeing unused kernel memory: %dk freed\n", + (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) diff --git a/arch/alpha/vmlinux.lds b/arch/alpha/vmlinux.lds dissimilarity index 95% index f29ecfe1b..2a5f00989 100644 --- a/arch/alpha/vmlinux.lds +++ b/arch/alpha/vmlinux.lds @@ -1,50 +1,46 @@ -OUTPUT_FORMAT("ecoff-littlealpha") -ENTRY(__start) -SECTIONS -{ - .text 0xfffffc0000310000: { - _ftext = . ; - __istart = . ; - eprol = .; - *(.text) - __fstart = . ; - _etext = .; - } - .rdata : { - *(.rdata) - } - .pdata : { - _fpdata = .; - *(.pdata) - } - .data : { - _fdata = .; - *(.data) - CONSTRUCTORS - } - .xdata : { - *(.xdata) - } - _gp = ALIGN (16) + 0x8000; - .lit8 : { - *(.lit8) - } - .lita : { - *(.lita) - } - .sdata : { - *(.sdata) - } - _EDATA = .; - _FBSS = .; - .sbss : { - *(.sbss) - *(.scommon) - . = ALIGN(16); - } - .bss : { - *(.bss) - *(COMMON) - } - _end = .; -} +OUTPUT_FORMAT("elf64-alpha") +ENTRY(__start) +SECTIONS +{ + . = 0xfffffc0000310000; + _text = .; + .text : { *(.text) } + _etext = .; + + /* Exception table */ + . = ALIGN(16); + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + /* Kernel symbol table */ + . = ALIGN(8); + __start___ksymtab = .; + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + .kstrtab : { *(.kstrtab) } + + /* Startup code */ + . = ALIGN(8192); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(8192); + __init_end = .; + + /* Global data */ + _data = .; + .rodata : { *(.rodata) } + .data : { *(.data) CONSTRUCTORS } + .got : { *(.got) } + .sdata : { *(.sdata) } + _edata = .; + _bss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : { *(.bss) *(COMMON) } + _end = .; + + .mdebug 0 : { *(.mdebug) } + .note 0 : { *(.note) } + .comment 0 : { *(.comment) } +} diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 9473705e6..84fe0c7fd 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -524,6 +524,7 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_vm86) .long SYMBOL_NAME(sys_query_module) .long SYMBOL_NAME(sys_poll) - .rept NR_syscalls-168 + .long SYMBOL_NAME(sys_nfsservctl) + .rept NR_syscalls-169 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index fc06be2b8..2bd095997 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -38,15 +38,16 @@ startup_32: orw %bx,%bx jz 1f /* - * New page tables may be in 4Mbyte page mode + * New page tables may be in 4Mbyte page mode and may + * be using the global pages. */ #ifdef GAS_KNOWS_CR4 movl %cr4,%eax # Turn on 4Mb pages - orl $16,%eax + orl $16+128,%eax movl %eax,%cr4 #else .byte 0x0f,0x20,0xe0 - orl $16,%eax + orl $16+128,%eax .byte 0x0f,0x22,0xe0 #endif movl %eax,%cr3 /* flush TLB as per app note */ diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 8ff11393a..173649338 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -27,6 +27,8 @@ #include #include +const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n"; + extern void die_if_kernel(char *,struct pt_regs *,long); extern void show_net_buffers(void); @@ -102,6 +104,48 @@ extern unsigned long free_area_init(unsigned long, unsigned long); extern char _text, _etext, _edata, __bss_start, _end; extern char __init_begin, __init_end; +#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x0008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x0010 /* enable page size extensions */ +#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x0040 /* Machine check enable */ +#define X86_CR4_PGE 0x0080 /* enable global pages */ +#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ + +#define X86_FEATURE_FPU 0x0001 /* internal FPU */ +#define X86_FEATURE_VME 0x0002 /* vm86 extensions */ +#define X86_FEATURE_DE 0x0004 /* debugging extensions */ +#define X86_FEATURE_PSE 0x0008 /* Page size extensions */ +#define X86_FEATURE_TSC 0x0010 /* Time stamp counter */ +#define X86_FEATURE_MSR 0x0020 /* RDMSR/WRMSR */ +#define X86_FEATURE_PAE 0x0040 /* Physical address extension */ +#define X86_FEATURE_MCE 0x0080 /* Machine check exception */ +#define X86_FEATURE_CXS 0x0100 /* cmpxchg8 available */ +#define X86_FEATURE_APIC 0x0200 /* internal APIC */ +#define X86_FEATURE_10 0x0400 +#define X86_FEATURE_11 0x0800 +#define X86_FEATURE_MTRR 0x1000 /* memory type registers */ +#define X86_FEATURE_PGE 0x2000 /* Global page */ +#define X86_FEATURE_MCA 0x4000 /* Machine Check Architecture */ +#define X86_FEATURE_CMOV 0x8000 /* Cmov/fcomi */ + +#ifdef GAS_KNOWS_CR4 +#define read_cr4 "movl %%cr4,%%eax" +#define write_cr4 "movl %%eax,%%cr4" +#else +#define read_cr4 ".byte 0x0f,0x20,0xe0" +#define write_cr4 ".byte 0x0f,0x22,0xe0" +#endif + +#define set_in_cr4(x) \ +__asm__(read_cr4 "\n\t" \ + "orl %0,%%eax\n\t" \ + write_cr4 \ + : : "i" (x) \ + :"ax"); + /* * paging_init() sets up the page tables - note that the first 4MB are * already mapped by head.S. @@ -156,27 +200,25 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_ /* Map whole memory from 0xC0000000 */ while (address < end_mem) { - if (x86_capability & 8) { - /* - * If we're running on a Pentium CPU, we can use the 4MB - * page tables. - * - * The page tables we create span up to the next 4MB - * virtual memory boundary, but that's OK as we won't - * use that memory anyway. - */ -#ifdef GAS_KNOWS_CR4 - __asm__("movl %%cr4,%%eax\n\t" - "orl $16,%%eax\n\t" - "movl %%eax,%%cr4" - : : :"ax"); -#else - __asm__(".byte 0x0f,0x20,0xe0\n\t" - "orl $16,%%eax\n\t" - ".byte 0x0f,0x22,0xe0" - : : :"ax"); -#endif + /* + * If we're running on a Pentium CPU, we can use the 4MB + * page tables. + * + * The page tables we create span up to the next 4MB + * virtual memory boundary, but that's OK as we won't + * use that memory anyway. + */ + if (x86_capability & X86_FEATURE_PSE) { + unsigned long __pe; + + set_in_cr4(X86_CR4_PSE); wp_works_ok = 1; + __pe = _PAGE_TABLE + _PAGE_4M + __pa(address); + /* Make it "global" too if supported */ + if (x86_capability & X86_FEATURE_PGE) { + set_in_cr4(X86_CR4_PGE); + __pe += _PAGE_GLOBAL; + } pgd_val(pg_dir[768]) = _PAGE_TABLE + _PAGE_4M + __pa(address); pg_dir++; address += 4*1024*1024; diff --git a/arch/m68k/amiga/retz3fb.c b/arch/m68k/amiga/retz3fb.c new file mode 100644 index 000000000..4885e48f7 --- /dev/null +++ b/arch/m68k/amiga/retz3fb.c @@ -0,0 +1,3504 @@ +/* + * Linux/arch/m68k/amiga/retz3fb.c -- Low level implementation of the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * This file is based on the CyberVision64 frame buffer device and + * the generic Cirrus Logic driver. + * + * cyberfb.c: Copyright (C) 1996 Martin Apel, + * Geert Uytterhoeven + * clgen.c: Copyright (C) 1996 Frank Neumann + * + * History: + * - 22 Jan 97: Initial work + * - 14 Feb 97: Screen initialization works somewhat, still only + * 8-bit packed pixel is supported. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "retz3fb.h" + +/* #define DEBUG if(1) */ +#define DEBUG if(0) + +/* + * Reserve space for one pattern line. + * + * For the time being we only support 4MB boards! + */ + +#define PAT_MEM_SIZE 16*3 +#define PAT_MEM_OFF (4*1024*1024 - PAT_MEM_SIZE) + +#define arraysize(x) (sizeof(x)/sizeof(*(x))) + +struct retz3_fb_par { + int xres; + int yres; + int xres_vir; + int yres_vir; + int xoffset; + int yoffset; + int bpp; + + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + + int pixclock; + int left_margin; /* time from sync to picture */ + int right_margin; /* time from picture to sync */ + int upper_margin; /* time from sync to picture */ + int lower_margin; + int hsync_len; /* length of horizontal sync */ + int vsync_len; /* length of vertical sync */ + int vmode; +}; + +struct display_data { + long h_total; /* Horizontal Total */ + long h_sstart; /* Horizontal Sync Start */ + long h_sstop; /* Horizontal Sync Stop */ + long h_bstart; /* Horizontal Blank Start */ + long h_bstop; /* Horizontal Blank Stop */ + long h_dispend; /* Horizontal Display End */ + long v_total; /* Vertical Total */ + long v_sstart; /* Vertical Sync Start */ + long v_sstop; /* Vertical Sync Stop */ + long v_bstart; /* Vertical Blank Start */ + long v_bstop; /* Vertical Blank Stop */ + long v_dispend; /* Horizontal Display End */ +}; + +static struct retz3_fb_par current_par; + +static int current_par_valid = 0; +static int currcon = 0; + +static struct display disp[MAX_NR_CONSOLES]; +static struct fb_info fb_info; + +static int node; /* node of the /dev/fb?current file */ + + +/* + * Switch for Chipset Independency + */ + +static struct fb_hwswitch { + + /* Initialisation */ + + int (*init)(void); + + /* Display Control */ + + int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3_fb_par *par); + int (*decode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*encode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned + int *green, unsigned int *blue, unsigned int *transp); + int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int + green, unsigned int blue, unsigned int transp); + void (*blank)(int blank); +} *fbhw; + + +/* + * Frame Buffer Name + */ + +static char retz3_fb_name[16] = "RetinaZ3"; + + +static int z3_key = 0; +static unsigned char retz3_color_table [256][4]; +static unsigned long z3_mem; +static unsigned long z3_fbmem; +static unsigned long z3_size; +static volatile unsigned char *z3_regs; + +static long *memstart; + + +/* + * Predefined Video Mode Names + */ + +static char *retz3_fb_modenames[] = { + + /* + * Autodetect (Default) Video Mode + */ + + "default", + + /* + * Predefined Video Modes + */ + + "640x480", /* RetinaZ3 8 bpp */ + "800x600", /* RetinaZ3 8 bpp */ + "1024x768i", + "640x480-16", /* RetinaZ3 16 bpp */ + "640x480-24", /* RetinaZ3 24 bpp */ + + /* + * Dummy Video Modes + */ + + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + + /* + * User Defined Video Modes + * + * This doesn't work yet!! + */ + + "user0", "user1", "user2", "user3", + "user4", "user5", "user6", "user7" +}; + +/* + * A small info on how to convert XFree86 timing values into fb + * timings - by Frank Neumann: + * +An XFree86 mode line consists of the following fields: + "800x600" 50 800 856 976 1040 600 637 643 666 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + +The fields in the fb_var_screeninfo structure are: + unsigned long pixclock; * pixel clock in ps (pico seconds) * + unsigned long left_margin; * time from sync to picture * + unsigned long right_margin; * time from picture to sync * + unsigned long upper_margin; * time from sync to picture * + unsigned long lower_margin; + unsigned long hsync_len; * length of horizontal sync * + unsigned long vsync_len; * length of vertical sync * + +1) Pixelclock: + xfree: in MHz + fb: In Picoseconds (ps) + + pixclock = 1000000 / DCF + +2) horizontal timings: + left_margin = HFL - SH2 + right_margin = SH1 - HR + hsync_len = SH2 - SH1 + +3) vertical timings: + upper_margin = VFL - SV2 + lower_margin = SV1 - VR + vsync_len = SV2 - SV1 + +Good examples for VESA timings can be found in the XFree86 source tree, +under "programs/Xserver/hw/xfree86/doc/modeDB.txt". +*/ + +/* + * Predefined Video Mode Definitions + */ + +static struct fb_var_screeninfo retz3_fb_predefined[] = { + + /* + * Autodetect (Default) Video Mode + */ + + { 0, }, + + /* + * Predefined Video Modes + */ + + /* + * NB: it is very important to adjust the pixel-clock to the color-depth. + */ + + { + 640, 480, 640, 480, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 800 x 600, 8 bpp */ + 800, 600, 800, 600, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 1024 x 768, 8 bpp, interlaced */ + 1024, 768, 1024, 768, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 16, 0, + {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 24, 0, + {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + + /* + * Dummy Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, + + /* + * User Defined Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } +}; + + +#define NUM_TOTAL_MODES arraysize(retz3_fb_predefined) +#define NUM_PREDEF_MODES (5) + + +static int z3fb_inverse = 0; +static int z3fb_mode = 0; + + +/* + * Interface used by the world + */ + +int retz3_probe(void); +void retz3_video_setup(char *options, int *ints); + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con); +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con); +static int retz3_fb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, int con); + + +/* + * Interface to the low level console driver + */ + +struct fb_info *retz3_fb_init(long *mem_start); /* Through amiga_fb_init() */ +static int z3fb_switch(int con); +static int z3fb_updatevar(int con); +static void z3fb_blank(int blank); +static int z3fb_setcmap(struct fb_cmap *cmap, int con); + + +/* + * Accelerated Functions used by the low level console driver + */ + +void retz3_bitblt(struct fb_var_screeninfo *scr, + unsigned short curx, unsigned short cury, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask); +void retz3_fill(unsigned short x, unsigned short y, unsigned short + width, unsigned short height, unsigned short mode, + unsigned short color); + +/* + * Hardware Specific Routines + */ + +static int retz3_init(void); +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par); +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp); +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp); +static void retz3_blank(int blank); + + +/* + * Internal routines + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par); +static void retz3_fb_set_par(struct retz3_fb_par *par); +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); +static struct fb_cmap *get_default_colormap(int bpp); +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static void do_install_cmap(int con); +static void memcpy_fs(int fsfromto, void *to, void *from, int len); +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto); +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp); +static void retz3_fb_set_disp(int con); +static int get_video_mode(const char *name); + + +/* -------------------- Hardware specific routines -------------------------- */ + +static unsigned short find_fq(unsigned int freq) +{ + unsigned long f; + long tmp; + long prev = 0x7fffffff; + long n2, n1 = 3; + unsigned long m; + unsigned short res = 0; + + if (freq <= 31250000) + n2 = 3; + else if (freq <= 62500000) + n2 = 2; + else if (freq <= 125000000) + n2 = 1; + else if (freq <= 250000000) + n2 = 0; + else + return(0); + + + do { + f = freq >> (10 - n2); + + m = (f * n1) / (14318180/1024); + + if (m > 129) + break; + + tmp = (((m * 14318180) >> n2) / n1) - freq; + if (tmp < 0) + tmp = -tmp; + + if (tmp < prev) { + prev = tmp; + res = (((n2 << 5) | (n1-2)) << 8) | (m-2); + } + + } while ( (++n1) <= 21); + + return res; +} + + +static int retz3_set_video(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + float freq_f; + long freq; + + int xres, hfront, hsync, hback; + int yres, vfront, vsync, vback; + unsigned char tmp; + unsigned short best_freq; + struct display_data data; + + short clocksel = 0; /* Apparantly this is always zero */ + + int bpp = var->bits_per_pixel; + + /* + * XXX + */ + if (bpp == 24) + return 0; + + if ((bpp != 8) && (bpp != 16) && (bpp != 24)) + return -EFAULT; + + par->xoffset = 0; + par->yoffset = 0; + + xres = var->xres * bpp / 4; + hfront = var->right_margin * bpp / 4; + hsync = var->hsync_len * bpp / 4; + hback = var->left_margin * bpp / 4; + + if (var->vmode & FB_VMODE_DOUBLE) + { + yres = var->yres * 2; + vfront = var->lower_margin * 2; + vsync = var->vsync_len * 2; + vback = var->upper_margin * 2; + } + else if (var->vmode & FB_VMODE_INTERLACED) + { + yres = (var->yres + 1) / 2; + vfront = (var->lower_margin + 1) / 2; + vsync = (var->vsync_len + 1) / 2; + vback = (var->upper_margin + 1) / 2; + } + else + { + yres = var->yres; /* -1 ? */ + vfront = var->lower_margin; + vsync = var->vsync_len; + vback = var->upper_margin; + } + + data.h_total = (hback / 8) + (xres / 8) + + (hfront / 8) + (hsync / 8) - 1 /* + 1 */; + data.h_dispend = ((xres + bpp - 1)/ 8) - 1; + data.h_bstart = xres / 8 /* + 1 */; + + data.h_bstop = data.h_total+1 + 2 + 1; + data.h_sstart = (xres / 8) + (hfront / 8) + 1; + data.h_sstop = (xres / 8) + (hfront / 8) + (hsync / 8) + 1; + + data.v_total = yres + vfront + vsync + vback - 1; + + data.v_dispend = yres - 1; + data.v_bstart = yres; + + data.v_bstop = data.v_total; + data.v_sstart = yres + vfront - 1 - 2; + data.v_sstop = yres + vfront + vsync - 1; + +#if 0 /* testing */ + + printk("HBS: %i\n", data.h_bstart); + printk("HSS: %i\n", data.h_sstart); + printk("HSE: %i\n", data.h_sstop); + printk("HBE: %i\n", data.h_bstop); + printk("HT: %i\n", data.h_total); + + printk("hsync: %i\n", hsync); + printk("hfront: %i\n", hfront); + printk("hback: %i\n", hback); + + printk("VBS: %i\n", data.v_bstart); + printk("VSS: %i\n", data.v_sstart); + printk("VSE: %i\n", data.v_sstop); + printk("VBE: %i\n", data.v_bstop); + printk("VT: %i\n", data.v_total); + + printk("vsync: %i\n", vsync); + printk("vfront: %i\n", vfront); + printk("vback: %i\n", vback); +#endif + + if (data.v_total >= 1024) + printk("MAYDAY: v_total >= 1024; bailing out!\n"); + + reg_w(GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04)); + reg_w(GREG_FEATURE_CONTROL_W, 0x00); + + seq_w(SEQ_RESET, 0x00); + seq_w(SEQ_RESET, 0x03); /* reset sequencer logic */ + + /* + * CLOCKING_MODE bits: + * 2: This one is only set for certain text-modes, wonder if + * it may be for EGA-lines? (it was referred to as CLKDIV2) + * (The CL drivers sets it to 0x21 with the comment: + * FullBandwidth (video off) and 8/9 dot clock) + */ + seq_w(SEQ_CLOCKING_MODE, 0x01 | 0x00 /* 0x08 */); + + seq_w(SEQ_MAP_MASK, 0x0f); /* enable writing to plane 0-3 */ + seq_w(SEQ_CHAR_MAP_SELECT, 0x00); /* doesn't matter in gfx-mode */ + seq_w(SEQ_MEMORY_MODE, 0x06); /* CL driver says 0x0e for 256 col mode*/ + seq_w(SEQ_RESET, 0x01); + seq_w(SEQ_RESET, 0x03); + + seq_w(SEQ_EXTENDED_ENABLE, 0x05); + + seq_w(SEQ_CURSOR_CONTROL, 0x00); /* disable cursor */ + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_LINEAR_0, 0x4a); + seq_w(SEQ_LINEAR_1, 0x00); + + seq_w(SEQ_SEC_HOST_OFF_HI, 0x00); + seq_w(SEQ_SEC_HOST_OFF_LO, 0x00); + seq_w(SEQ_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); + + /* + * The lower 4 bits (0-3) are used to set the font-width for + * text-mode - DON'T try to set this for gfx-mode. + */ + seq_w(SEQ_EXT_CLOCK_MODE, 0x10); + seq_w(SEQ_EXT_VIDEO_ADDR, 0x03); + + /* + * Extended Pixel Control: + * bit 0: text-mode=0, gfx-mode=1 (Graphics Byte ?) + * bit 1: (Packed/Nibble Pixel Format ?) + * bit 4-5: depth, 0=1-8bpp, 1=9-16bpp, 2=17-24bpp + */ + seq_w(SEQ_EXT_PIXEL_CNTL, 0x01 | (((bpp / 8) - 1) << 4)); + + seq_w(SEQ_BUS_WIDTH_FEEDB, 0x04); + seq_w(SEQ_COLOR_EXP_WFG, 0x01); + seq_w(SEQ_COLOR_EXP_WBG, 0x00); + seq_w(SEQ_EXT_RW_CONTROL, 0x00); + seq_w(SEQ_MISC_FEATURE_SEL, (0x51 | (clocksel & 8))); + seq_w(SEQ_COLOR_KEY_CNTL, 0x40); + seq_w(SEQ_COLOR_KEY_MATCH0, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH1, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH2, 0x00); + seq_w(SEQ_CRC_CONTROL, 0x00); + seq_w(SEQ_PERF_SELECT, 0x10); + seq_w(SEQ_ACM_APERTURE_1, 0x00); + seq_w(SEQ_ACM_APERTURE_2, 0x30); + seq_w(SEQ_ACM_APERTURE_3, 0x00); + seq_w(SEQ_MEMORY_MAP_CNTL, 0x03); + + + /* unlock register CRT0..CRT7 */ + crt_w(CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20); + + /* Zuerst zu schreibende Werte nur per printk ausgeben */ + DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total); + crt_w(CRT_HOR_TOTAL, data.h_total & 0xff); + + DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend); + crt_w(CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff); + + DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart); + crt_w(CRT_START_HOR_BLANK, data.h_bstart & 0xff); + + DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32); + crt_w(CRT_END_HOR_BLANK, 0x80 | (data.h_bstop & 0x1f)); + + DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart); + crt_w(CRT_START_HOR_RETR, data.h_sstart & 0xff); + + tmp = (data.h_sstop & 0x1f); + if (data.h_bstop & 0x20) + tmp |= 0x80; + DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp); + crt_w(CRT_END_HOR_RETR, tmp); + + DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff); + crt_w(CRT_VER_TOTAL, (data.v_total & 0xff)); + + tmp = 0x10; /* LineCompare bit #9 */ + if (data.v_total & 256) + tmp |= 0x01; + if (data.v_dispend & 256) + tmp |= 0x02; + if (data.v_sstart & 256) + tmp |= 0x04; + if (data.v_bstart & 256) + tmp |= 0x08; + if (data.v_total & 512) + tmp |= 0x20; + if (data.v_dispend & 512) + tmp |= 0x40; + if (data.v_sstart & 512) + tmp |= 0x80; + DEBUG printk("CRT_OVERFLOW: %d\n", tmp); + crt_w(CRT_OVERFLOW, tmp); + + crt_w(CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */ + + tmp = 0x40; /* LineCompare bit #8 */ + if (data.v_bstart & 512) + tmp |= 0x20; + if (var->vmode & FB_VMODE_DOUBLE) + tmp |= 0x80; + DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp); + crt_w(CRT_MAX_SCAN_LINE, tmp); + + crt_w(CRT_CURSOR_START, 0x00); + crt_w(CRT_CURSOR_END, 8 & 0x1f); /* font height */ + + crt_w(CRT_START_ADDR_HIGH, 0x00); + crt_w(CRT_START_ADDR_LOW, 0x00); + + crt_w(CRT_CURSOR_LOC_HIGH, 0x00); + crt_w(CRT_CURSOR_LOC_LOW, 0x00); + + DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff); + crt_w(CRT_START_VER_RETR, (data.v_sstart & 0xff)); + +#if 1 + /* 5 refresh cycles per scanline */ + DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20)); +#else + DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32)); +#endif + DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff); + crt_w(CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff)); + + DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff); + crt_w(CRT_START_VER_BLANK, (data.v_bstart & 0xff)); + + DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff); + crt_w(CRT_END_VER_BLANK, (data.v_bstop & 0xff)); + + DEBUG printk("CRT_MODE_CONTROL: 0xe3\n"); + crt_w(CRT_MODE_CONTROL, 0xe3); + + DEBUG printk("CRT_LINE_COMPARE: 0xff\n"); + crt_w(CRT_LINE_COMPARE, 0xff); + + tmp = (var->xres_virtual / 8) * (bpp / 8); + crt_w(CRT_OFFSET, tmp); + + crt_w(CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */ + + tmp = 0x20; /* Enable extended end bits */ + if (data.h_total & 0x100) + tmp |= 0x01; + if ((data.h_dispend) & 0x100) + tmp |= 0x02; + if (data.h_bstart & 0x100) + tmp |= 0x04; + if (data.h_sstart & 0x100) + tmp |= 0x08; + if (var->vmode & FB_VMODE_INTERLACED) + tmp |= 0x10; + DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp); + crt_w(CRT_EXT_HOR_TIMING1, tmp); + + tmp = 0x00; + if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100) + tmp |= 0x10; + crt_w(CRT_EXT_START_ADDR, tmp); + + tmp = 0x00; + if (data.h_total & 0x200) + tmp |= 0x01; + if ((data.h_dispend) & 0x200) + tmp |= 0x02; + if (data.h_bstart & 0x200) + tmp |= 0x04; + if (data.h_sstart & 0x200) + tmp |= 0x08; + tmp |= ((data.h_bstop & 0xc0) >> 2); + tmp |= ((data.h_sstop & 0x60) << 1); + crt_w(CRT_EXT_HOR_TIMING2, tmp); + DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp); + + tmp = 0x10; /* Line compare bit 10 */ + if (data.v_total & 0x400) + tmp |= 0x01; + if ((data.v_dispend) & 0x400) + tmp |= 0x02; + if (data.v_bstart & 0x400) + tmp |= 0x04; + if (data.v_sstart & 0x400) + tmp |= 0x08; + tmp |= ((data.v_bstop & 0x300) >> 3); + if (data.v_sstop & 0x10) + tmp |= 0x80; + crt_w(CRT_EXT_VER_TIMING, tmp); + DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp); + + crt_w(CRT_MONITOR_POWER, 0x00); + + /* + * Convert from ps to Hz. + */ + freq_f = (1.0/(float)var->pixclock) * 1000000000; + freq = ((long)freq_f) * 1000; + + best_freq = find_fq(freq); + pll_w(0x02, best_freq); + best_freq = find_fq(61000000); + pll_w(0x0a, best_freq); + pll_w(0x0e, 0x22); + + gfx_w(GFX_SET_RESET, 0x00); + gfx_w(GFX_ENABLE_SET_RESET, 0x00); + gfx_w(GFX_COLOR_COMPARE, 0x00); + gfx_w(GFX_DATA_ROTATE, 0x00); + gfx_w(GFX_READ_MAP_SELECT, 0x00); + gfx_w(GFX_GRAPHICS_MODE, 0x00); + gfx_w(GFX_MISC, 0x05); + gfx_w(GFX_COLOR_XCARE, 0x0f); + gfx_w(GFX_BITMASK, 0xff); + + reg_r(ACT_ADDRESS_RESET); + attr_w(ACT_PALETTE0 , 0x00); + attr_w(ACT_PALETTE1 , 0x01); + attr_w(ACT_PALETTE2 , 0x02); + attr_w(ACT_PALETTE3 , 0x03); + attr_w(ACT_PALETTE4 , 0x04); + attr_w(ACT_PALETTE5 , 0x05); + attr_w(ACT_PALETTE6 , 0x06); + attr_w(ACT_PALETTE7 , 0x07); + attr_w(ACT_PALETTE8 , 0x08); + attr_w(ACT_PALETTE9 , 0x09); + attr_w(ACT_PALETTE10, 0x0a); + attr_w(ACT_PALETTE11, 0x0b); + attr_w(ACT_PALETTE12, 0x0c); + attr_w(ACT_PALETTE13, 0x0d); + attr_w(ACT_PALETTE14, 0x0e); + attr_w(ACT_PALETTE15, 0x0f); + reg_r(ACT_ADDRESS_RESET); + + attr_w(ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */ + + attr_w(ACT_OVERSCAN_COLOR, 0x00); + attr_w(ACT_COLOR_PLANE_ENA, 0x0f); + attr_w(ACT_HOR_PEL_PANNING, 0x00); + attr_w(ACT_COLOR_SELECT, 0x00); + + reg_r(ACT_ADDRESS_RESET); + reg_w(ACT_DATA, 0x20); + + reg_w(VDAC_MASK, 0xff); + + /* + * Extended palette adressing ??? + */ + switch (bpp){ + case 8: + reg_w(0x83c6, 0x00); + break; + case 16: + reg_w(0x83c6, 0x60); + break; + case 24: + reg_w(0x83c6, 0xe0); + break; + default: + printk("Illegal color-depth: %i\n", bpp); + } + + reg_w(VDAC_ADDRESS, 0x00); + + seq_w(SEQ_MAP_MASK, 0x0f ); + + return 0; +} + +/* + * Initialization + * + * Set the default video mode for this chipset. If a video mode was + * specified on the command line, it will override the default mode. + */ + +static int retz3_init(void) +{ + int i; +#if 0 + volatile unsigned long *CursorBase; +#endif + unsigned long board_addr, board_size; + struct ConfigDev *cd; + + cd = zorro_get_board (z3_key); + zorro_config_board (z3_key, 0); + board_addr = (unsigned long)cd->cd_BoardAddr; + board_size = (unsigned long)cd->cd_BoardSize; + + for (i = 0; i < 256; i++){ + for (i = 0; i < 256; i++){ + retz3_color_table [i][0] = i; + retz3_color_table [i][1] = i; + retz3_color_table [i][2] = i; + retz3_color_table [i][3] = 0; + } + } + + *memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + + z3_mem = kernel_map (board_addr, board_size, + KERNELMAP_NOCACHE_SER, memstart); + + z3_regs = (char*) z3_mem; + z3_fbmem = z3_mem + VIDEO_MEM_OFFSET; + + /* Get memory size - for now we asume its a 4MB board */ + + z3_size = 0x00400000; /* 4 MB */ + + memset ((char*)z3_fbmem, 0, z3_size); + + /* Disable hardware cursor */ + + seq_w(SEQ_CURSOR_Y_INDEX, 0x00); + + +#if 0 + /* Initialize hardware cursor */ + CursorBase = (unsigned long *)((char *)(z3_mem) + z3_size - 0x400); + for (i=0; i < 8; i++){ + *(CursorBase +(i*4)) = 0xffffff00; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } + for (i=8; i < 64; i++){ + *(CursorBase +(i*4)) = 0xffff0000; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } +#endif + + retz3_setcolreg (255, 56, 100, 160, 0); + retz3_setcolreg (254, 0, 0, 0, 0); + + return 0; +} + + +/* + * This function should fill in the `fix' structure based on the + * values in the `par' structure. + */ + +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par) +{ + int i; + + strcpy(fix->id, retz3_fb_name); + fix->smem_start = z3_fbmem; + fix->smem_len = z3_size; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->type_aux = 0; + if (par->bpp == 8) + fix->visual = FB_VISUAL_PSEUDOCOLOR; + else + fix->visual = FB_VISUAL_DIRECTCOLOR; + + fix->xpanstep = 0; + fix->ypanstep = 0; + fix->ywrapstep = 0; + fix->line_length = 0; + + for (i = 0; i < arraysize(fix->reserved); i++) + fix->reserved[i] = 0; + + return 0; +} + + +/* + * Get the video params out of `var'. If a value doesn't fit, round + * it up, if it's too big, return -EINVAL. + */ + +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + par->xres = var->xres; + par->yres = var->yres; + par->xres_vir = var->xres_virtual; + par->yres_vir = var->yres_virtual; + par->bpp = var->bits_per_pixel; + par->pixclock = var->pixclock; + par->vmode = var->vmode; + + par->red = var->red; + par->green = var->green; + par->blue = var->blue; + par->transp = var->transp; + + par->left_margin = var->left_margin; + par->right_margin = var->right_margin; + par->upper_margin = var->upper_margin; + par->lower_margin = var->lower_margin; + par->hsync_len = var->hsync_len; + par->vsync_len = var->vsync_len; + + return 0; +} + + +/* + * Fill the `var' structure based on the values in `par' and maybe + * other values read out of the hardware. + */ + +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + int i; + + var->xres = par->xres; + var->yres = par->yres; + var->xres_virtual = par->xres_vir; + var->yres_virtual = par->yres_vir; + var->xoffset = 0; + var->yoffset = 0; + + var->bits_per_pixel = par->bpp; + var->grayscale = 0; + + var->red = par->red; + var->green = par->green; + var->blue = par->blue; + var->transp = par->transp; + + var->nonstd = 0; + var->activate = 0; + + var->height = -1; + var->width = -1; + + var->accel = FB_ACCEL_RETINAZ3; + + var->pixclock = par->pixclock; + + var->sync = 0; /* ??? */ + var->left_margin = par->left_margin; + var->right_margin = par->right_margin; + var->upper_margin = par->upper_margin; + var->lower_margin = par->lower_margin; + var->hsync_len = par->hsync_len; + var->vsync_len = par->vsync_len; + + for (i = 0; i < arraysize(var->reserved); i++) + var->reserved[i] = 0; + + var->vmode = par->vmode; + return 0; +} + + +/* + * Set a single color register. The values supplied are already + * rounded down to the hardware's capabilities (according to the + * entries in the var structure). Return != 0 for invalid regno. + */ + +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp) +{ + /* We'll get to this */ + + if (regno > 255) + return 1; + + retz3_color_table [regno][0] = red & 0xff; + retz3_color_table [regno][1] = green & 0xff; + retz3_color_table [regno][2] = blue & 0xff; + retz3_color_table [regno][3] = transp; + + reg_w(VDAC_ADDRESS_W, regno); + reg_w(VDAC_DATA, (red & 0xff) >> 2); + reg_w(VDAC_DATA, (green & 0xff) >> 2); + reg_w(VDAC_DATA, (blue & 0xff) >> 2); + + return 0; +} + + +/* + * Read a single color register and split it into + * colors/transparent. Return != 0 for invalid regno. + */ + +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp) +{ + if (regno > 255) + return 1; + *red = retz3_color_table [regno][0]; + *green = retz3_color_table [regno][1]; + *blue = retz3_color_table [regno][2]; + *transp = retz3_color_table [regno][3]; + return 0; +} + + +/* + * (Un)Blank the screen + */ + +void retz3_blank(int blank) +{ + int i; + + if (blank) + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + } + else + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, retz3_color_table [i][0] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][1] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][2] >> 2); + } +} + + +void retz3_bitblt (struct fb_var_screeninfo *var, + unsigned short srcx, unsigned short srcy, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask) +{ + + volatile unsigned long *acm = (unsigned long *) (z3_mem + ACM_OFFSET); + unsigned long *pattern = (unsigned long *)(z3_fbmem + PAT_MEM_OFF); + + unsigned short mod; + unsigned long tmp; + unsigned long pat, src, dst; + unsigned char blt_status; + + int i, xres_virtual = var->xres_virtual; + short bpp = (var->bits_per_pixel & 0xff); + + if (bpp < 8) + bpp = 8; + + tmp = mask | (mask << 16); + +#if 0 + /* + * Check for blitter finished before we start messing with the + * pattern. + */ + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + }while ((blt_status & 1) == 0); +#endif + + i = 0; + do{ + *pattern++ = tmp; + }while(i++ < bpp/4); + + tmp = cmd << 8; + *(acm + ACM_RASTEROP_ROTATION/4) = tmp; + + mod = 0xc0c2; + + pat = 8 * PAT_MEM_OFF; + dst = bpp * (destx + desty * xres_virtual); + + /* + * Source is not set for clear. + */ + if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) { + src = bpp * (srcx + srcy * xres_virtual); + + if (destx > srcx) { + mod &= ~0x8000; + src += bpp * (width - 1); + dst += bpp * (width - 1); + pat += bpp * 2; + } + if (desty > srcy) { + mod &= ~0x4000; + src += bpp * (height - 1) * xres_virtual; + dst += bpp * (height - 1) * xres_virtual; + pat += bpp * 4; + } + + *(acm + ACM_SOURCE/4) = cpu_to_le32(src); + } + + *(acm + ACM_PATTERN/4) = cpu_to_le32(pat); + + *(acm + ACM_DESTINATION/4) = cpu_to_le32(dst); + + tmp = mod << 16; + *(acm + ACM_CONTROL/4) = tmp; + + tmp = width | (height << 16); + + *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp); + + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; + + /* + * No reason to wait for the blitter to finish, it is better + * just to check if it has finished before we use it again. + */ +#if 1 +#if 0 + while ((*(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)) & 1) == 0); +#else + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + } + while ((blt_status & 1) == 0); +#endif +#endif +} + +#if 0 +void retz3_fill (unsigned short x, unsigned short y, unsigned + short width, unsigned short height, + unsigned short mode, unsigned short color) +{ + +} +#endif + + +/************************************************************** + * Move cursor to x, y + */ +void retz3_MoveCursor (unsigned short x, unsigned short y) +{ + /* Guess we gotta deal with the cursor at some point */ +} + + +/* -------------------- Interfaces to hardware functions -------------------- */ + + +static struct fb_hwswitch retz3_switch = { + retz3_init, retz3_encode_fix, retz3_decode_var, retz3_encode_var, + retz3_getcolreg, retz3_setcolreg, retz3_blank +}; + + +/* -------------------- Generic routines ------------------------------------ */ + + +/* + * Fill the hardware's `par' structure. + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par) +{ + if (current_par_valid) + *par = current_par; + else + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], par); +} + + +static void retz3_fb_set_par(struct retz3_fb_par *par) +{ + current_par = *par; + current_par_valid = 1; +} + + +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) +{ + int err, activate; + struct retz3_fb_par par; + + if ((err = fbhw->decode_var(var, &par))) + return err; + activate = var->activate; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) + retz3_fb_set_par(&par); + fbhw->encode_var(var, &par); + var->activate = activate; + +#if 1 + retz3_set_video(var, ¤t_par); +#endif + return 0; +} + + +/* + * Default Colormaps + */ + +static unsigned short red16[] = + { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000, + 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff }; +static unsigned short green16[] = + { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000, + 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff }; +static unsigned short blue16[] = + { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, + 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff }; + + +static struct fb_cmap default_16_colors = + { 0, 16, red16, green16, blue16, NULL }; + + +static struct fb_cmap *get_default_colormap(int bpp) +{ + return &default_16_colors; +} + + +#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) +#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ + ((1<<(width))-1)) : 0)) + +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp)) + return 0; + hred = CNVT_FROMHW(hred, var->red.length); + hgreen = CNVT_FROMHW(hgreen, var->green.length); + hblue = CNVT_FROMHW(hblue, var->blue.length); + htransp = CNVT_FROMHW(htransp, var->transp.length); + if (kspc) { + *red = hred; + *green = hgreen; + *blue = hblue; + if (transp) + *transp = htransp; + } else { + put_user(hred, red); + put_user(hgreen, green); + put_user(hblue, blue); + if (transp) + put_user(htransp, transp); + } + red++; + green++; + blue++; + if (transp) + transp++; + } + return 0; +} + + +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (kspc) { + hred = *red; + hgreen = *green; + hblue = *blue; + htransp = transp ? *transp : 0; + } else { + get_user(hred, red); + get_user(hgreen, green); + get_user(hblue, blue); + if (transp) + get_user(htransp, transp); + else + htransp = 0; + } + hred = CNVT_TOHW(hred, var->red.length); + hgreen = CNVT_TOHW(hgreen, var->green.length); + hblue = CNVT_TOHW(hblue, var->blue.length); + htransp = CNVT_TOHW(htransp, var->transp.length); + red++; + green++; + blue++; + if (transp) + transp++; + if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp)) + return 0; + } + return 0; +} + + +static void do_install_cmap(int con) +{ + if (con != currcon) + return; + if (disp[con].cmap.len) + do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1); + else + do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + &disp[con].var, 1); +} + + +static void memcpy_fs(int fsfromto, void *to, void *from, int len) +{ + switch (fsfromto) { + case 0: + memcpy(to, from, len); + return; + case 1: + copy_from_user(to, from, len); + return; + case 2: + copy_to_user(to, from, len); + return; + } +} + + +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto) +{ + int size; + int tooff = 0, fromoff = 0; + + if (to->start > from->start) + fromoff = to->start-from->start; + else + tooff = from->start-to->start; + size = to->len-tooff; + if (size > from->len-fromoff) + size = from->len-fromoff; + if (size < 0) + return; + size *= sizeof(unsigned short); + memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size); + memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size); + memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size); + if (from->transp && to->transp) + memcpy_fs(fsfromto, to->transp+tooff, + from->transp+fromoff, size); +} + + +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp) +{ + int size = len*sizeof(unsigned short); + + if (cmap->len != len) { + if (cmap->red) + kfree(cmap->red); + if (cmap->green) + kfree(cmap->green); + if (cmap->blue) + kfree(cmap->blue); + if (cmap->transp) + kfree(cmap->transp); + cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; + cmap->len = 0; + if (!len) + return 0; + if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) + return -1; + if (transp) { + if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) + return -1; + } else + cmap->transp = NULL; + } + cmap->start = 0; + cmap->len = len; + copy_cmap(get_default_colormap(len), cmap, 0); + return 0; +} + + +/* + * Get the Fixed Part of the Display + */ + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) + retz3_fb_get_par(&par); + else + error = fbhw->decode_var(&disp[con].var, &par); + return(error ? error : fbhw->encode_fix(fix, &par)); +} + + +/* + * Get the User Defined Part of the Display + */ + +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) { + retz3_fb_get_par(&par); + error = fbhw->encode_var(var, &par); + } else + *var = disp[con].var; + return error; +} + + +static void retz3_fb_set_disp(int con) +{ + struct fb_fix_screeninfo fix; + + retz3_fb_get_fix(&fix, con); + if (con == -1) + con = 0; + disp[con].screen_base = (unsigned char *)fix.smem_start; + disp[con].visual = fix.visual; + disp[con].type = fix.type; + disp[con].type_aux = fix.type_aux; + disp[con].ypanstep = fix.ypanstep; + disp[con].ywrapstep = fix.ywrapstep; + disp[con].can_soft_blank = 1; + disp[con].inverse = z3fb_inverse; +} + + +/* + * Set the User Defined Part of the Display + */ + +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) +{ + int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp; + + if ((err = do_fb_set_var(var, con == currcon))) + return err; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { + oldxres = disp[con].var.xres; + oldyres = disp[con].var.yres; + oldvxres = disp[con].var.xres_virtual; + oldvyres = disp[con].var.yres_virtual; + oldbpp = disp[con].var.bits_per_pixel; + disp[con].var = *var; + if (oldxres != var->xres || oldyres != var->yres || + oldvxres != var->xres_virtual || + oldvyres != var->yres_virtual || + oldbpp != var->bits_per_pixel) { + retz3_fb_set_disp(con); + (*fb_info.changevar)(con); + alloc_cmap(&disp[con].cmap, 0, 0); + do_install_cmap(con); + } + } + var->activate = 0; + return 0; +} + + +/* + * Get the Colormap + */ + +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + if (con == currcon) /* current console? */ + return(do_fb_get_cmap(cmap, &disp[con].var, kspc)); + else if (disp[con].cmap.len) /* non default colormap? */ + copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2); + else + copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + cmap, kspc ? 0 : 2); + return 0; +} + + +/* + * Set the Colormap + */ + +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + int err; + + if (!disp[con].cmap.len) { /* no colormap allocated? */ + if ((err = alloc_cmap(&disp[con].cmap, + 1<init(); + + if (z3fb_mode == -1) + z3fb_mode = 1; + + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], &par); + fbhw->encode_var(&retz3_fb_predefined[0], &par); + + strcpy(fb_info.modename, retz3_fb_name); + fb_info.disp = disp; + fb_info.switch_con = &z3fb_switch; + fb_info.updatevar = &z3fb_updatevar; + fb_info.blank = &z3fb_blank; + fb_info.setcmap = &z3fb_setcmap; + + do_fb_set_var(&retz3_fb_predefined[0], 0); + retz3_fb_get_var(&disp[0].var, -1); + retz3_fb_set_disp(-1); + do_install_cmap(0); + + return &fb_info; +} + + +static int z3fb_switch(int con) +{ + /* Do we have to save the colormap? */ + if (disp[currcon].cmap.len) + do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1); + + do_fb_set_var(&disp[con].var, 1); + currcon = con; + /* Install new colormap */ + do_install_cmap(con); + return 0; +} + + +/* + * Update the `var' structure (called by fbcon.c) + * + * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. + * Since it's called by a kernel driver, no range checking is done. + */ + +static int z3fb_updatevar(int con) +{ + return 0; +} + + +/* + * Blank the display. + */ + +static void z3fb_blank(int blank) +{ + fbhw->blank(blank); +} + + +/* + * Set the colormap + */ + +static int z3fb_setcmap(struct fb_cmap *cmap, int con) +{ + return(retz3_fb_set_cmap(cmap, 1, con)); +} + + +/* + * Get a Video Mode + */ + +static int get_video_mode(const char *name) +{ + int i; + + for (i = 1; i <= NUM_PREDEF_MODES; i++) + if (!strcmp(name, retz3_fb_modenames[i])){ + retz3_fb_predefined[0] = retz3_fb_predefined[i]; + return i; + } + return -1; +} +/* + * Linux/arch/m68k/amiga/retz3fb.c -- Low level implementation of the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * This file is based on the CyberVision64 frame buffer device and + * the generic Cirrus Logic driver. + * + * cyberfb.c: Copyright (C) 1996 Martin Apel, + * Geert Uytterhoeven + * clgen.c: Copyright (C) 1996 Frank Neumann + * + * History: + * - 22 Jan 97: Initial work + * - 14 Feb 97: Screen initialization works somewhat, still only + * 8-bit packed pixel is supported. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "retz3fb.h" + +/* #define DEBUG if(1) */ +#define DEBUG if(0) + +/* + * Reserve space for one pattern line. + * + * For the time being we only support 4MB boards! + */ + +#define PAT_MEM_SIZE 16*3 +#define PAT_MEM_OFF (4*1024*1024 - PAT_MEM_SIZE) + +#define arraysize(x) (sizeof(x)/sizeof(*(x))) + +struct retz3_fb_par { + int xres; + int yres; + int xres_vir; + int yres_vir; + int xoffset; + int yoffset; + int bpp; + + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + + int pixclock; + int left_margin; /* time from sync to picture */ + int right_margin; /* time from picture to sync */ + int upper_margin; /* time from sync to picture */ + int lower_margin; + int hsync_len; /* length of horizontal sync */ + int vsync_len; /* length of vertical sync */ + int vmode; +}; + +struct display_data { + long h_total; /* Horizontal Total */ + long h_sstart; /* Horizontal Sync Start */ + long h_sstop; /* Horizontal Sync Stop */ + long h_bstart; /* Horizontal Blank Start */ + long h_bstop; /* Horizontal Blank Stop */ + long h_dispend; /* Horizontal Display End */ + long v_total; /* Vertical Total */ + long v_sstart; /* Vertical Sync Start */ + long v_sstop; /* Vertical Sync Stop */ + long v_bstart; /* Vertical Blank Start */ + long v_bstop; /* Vertical Blank Stop */ + long v_dispend; /* Horizontal Display End */ +}; + +static struct retz3_fb_par current_par; + +static int current_par_valid = 0; +static int currcon = 0; + +static struct display disp[MAX_NR_CONSOLES]; +static struct fb_info fb_info; + +static int node; /* node of the /dev/fb?current file */ + + +/* + * Switch for Chipset Independency + */ + +static struct fb_hwswitch { + + /* Initialisation */ + + int (*init)(void); + + /* Display Control */ + + int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3_fb_par *par); + int (*decode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*encode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned + int *green, unsigned int *blue, unsigned int *transp); + int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int + green, unsigned int blue, unsigned int transp); + void (*blank)(int blank); +} *fbhw; + + +/* + * Frame Buffer Name + */ + +static char retz3_fb_name[16] = "RetinaZ3"; + + +static int z3_key = 0; +static unsigned char retz3_color_table [256][4]; +static unsigned long z3_mem; +static unsigned long z3_fbmem; +static unsigned long z3_size; +static volatile unsigned char *z3_regs; + +static long *memstart; + + +/* + * Predefined Video Mode Names + */ + +static char *retz3_fb_modenames[] = { + + /* + * Autodetect (Default) Video Mode + */ + + "default", + + /* + * Predefined Video Modes + */ + + "640x480", /* RetinaZ3 8 bpp */ + "800x600", /* RetinaZ3 8 bpp */ + "1024x768i", + "640x480-16", /* RetinaZ3 16 bpp */ + "640x480-24", /* RetinaZ3 24 bpp */ + + /* + * Dummy Video Modes + */ + + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + + /* + * User Defined Video Modes + * + * This doesn't work yet!! + */ + + "user0", "user1", "user2", "user3", + "user4", "user5", "user6", "user7" +}; + +/* + * A small info on how to convert XFree86 timing values into fb + * timings - by Frank Neumann: + * +An XFree86 mode line consists of the following fields: + "800x600" 50 800 856 976 1040 600 637 643 666 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + +The fields in the fb_var_screeninfo structure are: + unsigned long pixclock; * pixel clock in ps (pico seconds) * + unsigned long left_margin; * time from sync to picture * + unsigned long right_margin; * time from picture to sync * + unsigned long upper_margin; * time from sync to picture * + unsigned long lower_margin; + unsigned long hsync_len; * length of horizontal sync * + unsigned long vsync_len; * length of vertical sync * + +1) Pixelclock: + xfree: in MHz + fb: In Picoseconds (ps) + + pixclock = 1000000 / DCF + +2) horizontal timings: + left_margin = HFL - SH2 + right_margin = SH1 - HR + hsync_len = SH2 - SH1 + +3) vertical timings: + upper_margin = VFL - SV2 + lower_margin = SV1 - VR + vsync_len = SV2 - SV1 + +Good examples for VESA timings can be found in the XFree86 source tree, +under "programs/Xserver/hw/xfree86/doc/modeDB.txt". +*/ + +/* + * Predefined Video Mode Definitions + */ + +static struct fb_var_screeninfo retz3_fb_predefined[] = { + + /* + * Autodetect (Default) Video Mode + */ + + { 0, }, + + /* + * Predefined Video Modes + */ + + /* + * NB: it is very important to adjust the pixel-clock to the color-depth. + */ + + { + 640, 480, 640, 480, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 800 x 600, 8 bpp */ + 800, 600, 800, 600, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 1024 x 768, 8 bpp, interlaced */ + 1024, 768, 1024, 768, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 16, 0, + {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 24, 0, + {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + + /* + * Dummy Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, + + /* + * User Defined Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } +}; + + +#define NUM_TOTAL_MODES arraysize(retz3_fb_predefined) +#define NUM_PREDEF_MODES (5) + + +static int z3fb_inverse = 0; +static int z3fb_mode = 0; + + +/* + * Interface used by the world + */ + +int retz3_probe(void); +void retz3_video_setup(char *options, int *ints); + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con); +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con); +static int retz3_fb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, int con); + + +/* + * Interface to the low level console driver + */ + +struct fb_info *retz3_fb_init(long *mem_start); /* Through amiga_fb_init() */ +static int z3fb_switch(int con); +static int z3fb_updatevar(int con); +static void z3fb_blank(int blank); +static int z3fb_setcmap(struct fb_cmap *cmap, int con); + + +/* + * Accelerated Functions used by the low level console driver + */ + +void retz3_bitblt(struct fb_var_screeninfo *scr, + unsigned short curx, unsigned short cury, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask); +void retz3_fill(unsigned short x, unsigned short y, unsigned short + width, unsigned short height, unsigned short mode, + unsigned short color); + +/* + * Hardware Specific Routines + */ + +static int retz3_init(void); +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par); +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp); +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp); +static void retz3_blank(int blank); + + +/* + * Internal routines + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par); +static void retz3_fb_set_par(struct retz3_fb_par *par); +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); +static struct fb_cmap *get_default_colormap(int bpp); +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static void do_install_cmap(int con); +static void memcpy_fs(int fsfromto, void *to, void *from, int len); +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto); +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp); +static void retz3_fb_set_disp(int con); +static int get_video_mode(const char *name); + + +/* -------------------- Hardware specific routines -------------------------- */ + +static unsigned short find_fq(unsigned int freq) +{ + unsigned long f; + long tmp; + long prev = 0x7fffffff; + long n2, n1 = 3; + unsigned long m; + unsigned short res = 0; + + if (freq <= 31250000) + n2 = 3; + else if (freq <= 62500000) + n2 = 2; + else if (freq <= 125000000) + n2 = 1; + else if (freq <= 250000000) + n2 = 0; + else + return(0); + + + do { + f = freq >> (10 - n2); + + m = (f * n1) / (14318180/1024); + + if (m > 129) + break; + + tmp = (((m * 14318180) >> n2) / n1) - freq; + if (tmp < 0) + tmp = -tmp; + + if (tmp < prev) { + prev = tmp; + res = (((n2 << 5) | (n1-2)) << 8) | (m-2); + } + + } while ( (++n1) <= 21); + + return res; +} + + +static int retz3_set_video(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + float freq_f; + long freq; + + int xres, hfront, hsync, hback; + int yres, vfront, vsync, vback; + unsigned char tmp; + unsigned short best_freq; + struct display_data data; + + short clocksel = 0; /* Apparantly this is always zero */ + + int bpp = var->bits_per_pixel; + + /* + * XXX + */ + if (bpp == 24) + return 0; + + if ((bpp != 8) && (bpp != 16) && (bpp != 24)) + return -EFAULT; + + par->xoffset = 0; + par->yoffset = 0; + + xres = var->xres * bpp / 4; + hfront = var->right_margin * bpp / 4; + hsync = var->hsync_len * bpp / 4; + hback = var->left_margin * bpp / 4; + + if (var->vmode & FB_VMODE_DOUBLE) + { + yres = var->yres * 2; + vfront = var->lower_margin * 2; + vsync = var->vsync_len * 2; + vback = var->upper_margin * 2; + } + else if (var->vmode & FB_VMODE_INTERLACED) + { + yres = (var->yres + 1) / 2; + vfront = (var->lower_margin + 1) / 2; + vsync = (var->vsync_len + 1) / 2; + vback = (var->upper_margin + 1) / 2; + } + else + { + yres = var->yres; /* -1 ? */ + vfront = var->lower_margin; + vsync = var->vsync_len; + vback = var->upper_margin; + } + + data.h_total = (hback / 8) + (xres / 8) + + (hfront / 8) + (hsync / 8) - 1 /* + 1 */; + data.h_dispend = ((xres + bpp - 1)/ 8) - 1; + data.h_bstart = xres / 8 /* + 1 */; + + data.h_bstop = data.h_total+1 + 2 + 1; + data.h_sstart = (xres / 8) + (hfront / 8) + 1; + data.h_sstop = (xres / 8) + (hfront / 8) + (hsync / 8) + 1; + + data.v_total = yres + vfront + vsync + vback - 1; + + data.v_dispend = yres - 1; + data.v_bstart = yres; + + data.v_bstop = data.v_total; + data.v_sstart = yres + vfront - 1 - 2; + data.v_sstop = yres + vfront + vsync - 1; + +#if 0 /* testing */ + + printk("HBS: %i\n", data.h_bstart); + printk("HSS: %i\n", data.h_sstart); + printk("HSE: %i\n", data.h_sstop); + printk("HBE: %i\n", data.h_bstop); + printk("HT: %i\n", data.h_total); + + printk("hsync: %i\n", hsync); + printk("hfront: %i\n", hfront); + printk("hback: %i\n", hback); + + printk("VBS: %i\n", data.v_bstart); + printk("VSS: %i\n", data.v_sstart); + printk("VSE: %i\n", data.v_sstop); + printk("VBE: %i\n", data.v_bstop); + printk("VT: %i\n", data.v_total); + + printk("vsync: %i\n", vsync); + printk("vfront: %i\n", vfront); + printk("vback: %i\n", vback); +#endif + + if (data.v_total >= 1024) + printk("MAYDAY: v_total >= 1024; bailing out!\n"); + + reg_w(GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04)); + reg_w(GREG_FEATURE_CONTROL_W, 0x00); + + seq_w(SEQ_RESET, 0x00); + seq_w(SEQ_RESET, 0x03); /* reset sequencer logic */ + + /* + * CLOCKING_MODE bits: + * 2: This one is only set for certain text-modes, wonder if + * it may be for EGA-lines? (it was referred to as CLKDIV2) + * (The CL drivers sets it to 0x21 with the comment: + * FullBandwidth (video off) and 8/9 dot clock) + */ + seq_w(SEQ_CLOCKING_MODE, 0x01 | 0x00 /* 0x08 */); + + seq_w(SEQ_MAP_MASK, 0x0f); /* enable writing to plane 0-3 */ + seq_w(SEQ_CHAR_MAP_SELECT, 0x00); /* doesn't matter in gfx-mode */ + seq_w(SEQ_MEMORY_MODE, 0x06); /* CL driver says 0x0e for 256 col mode*/ + seq_w(SEQ_RESET, 0x01); + seq_w(SEQ_RESET, 0x03); + + seq_w(SEQ_EXTENDED_ENABLE, 0x05); + + seq_w(SEQ_CURSOR_CONTROL, 0x00); /* disable cursor */ + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_LINEAR_0, 0x4a); + seq_w(SEQ_LINEAR_1, 0x00); + + seq_w(SEQ_SEC_HOST_OFF_HI, 0x00); + seq_w(SEQ_SEC_HOST_OFF_LO, 0x00); + seq_w(SEQ_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); + + /* + * The lower 4 bits (0-3) are used to set the font-width for + * text-mode - DON'T try to set this for gfx-mode. + */ + seq_w(SEQ_EXT_CLOCK_MODE, 0x10); + seq_w(SEQ_EXT_VIDEO_ADDR, 0x03); + + /* + * Extended Pixel Control: + * bit 0: text-mode=0, gfx-mode=1 (Graphics Byte ?) + * bit 1: (Packed/Nibble Pixel Format ?) + * bit 4-5: depth, 0=1-8bpp, 1=9-16bpp, 2=17-24bpp + */ + seq_w(SEQ_EXT_PIXEL_CNTL, 0x01 | (((bpp / 8) - 1) << 4)); + + seq_w(SEQ_BUS_WIDTH_FEEDB, 0x04); + seq_w(SEQ_COLOR_EXP_WFG, 0x01); + seq_w(SEQ_COLOR_EXP_WBG, 0x00); + seq_w(SEQ_EXT_RW_CONTROL, 0x00); + seq_w(SEQ_MISC_FEATURE_SEL, (0x51 | (clocksel & 8))); + seq_w(SEQ_COLOR_KEY_CNTL, 0x40); + seq_w(SEQ_COLOR_KEY_MATCH0, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH1, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH2, 0x00); + seq_w(SEQ_CRC_CONTROL, 0x00); + seq_w(SEQ_PERF_SELECT, 0x10); + seq_w(SEQ_ACM_APERTURE_1, 0x00); + seq_w(SEQ_ACM_APERTURE_2, 0x30); + seq_w(SEQ_ACM_APERTURE_3, 0x00); + seq_w(SEQ_MEMORY_MAP_CNTL, 0x03); + + + /* unlock register CRT0..CRT7 */ + crt_w(CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20); + + /* Zuerst zu schreibende Werte nur per printk ausgeben */ + DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total); + crt_w(CRT_HOR_TOTAL, data.h_total & 0xff); + + DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend); + crt_w(CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff); + + DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart); + crt_w(CRT_START_HOR_BLANK, data.h_bstart & 0xff); + + DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32); + crt_w(CRT_END_HOR_BLANK, 0x80 | (data.h_bstop & 0x1f)); + + DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart); + crt_w(CRT_START_HOR_RETR, data.h_sstart & 0xff); + + tmp = (data.h_sstop & 0x1f); + if (data.h_bstop & 0x20) + tmp |= 0x80; + DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp); + crt_w(CRT_END_HOR_RETR, tmp); + + DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff); + crt_w(CRT_VER_TOTAL, (data.v_total & 0xff)); + + tmp = 0x10; /* LineCompare bit #9 */ + if (data.v_total & 256) + tmp |= 0x01; + if (data.v_dispend & 256) + tmp |= 0x02; + if (data.v_sstart & 256) + tmp |= 0x04; + if (data.v_bstart & 256) + tmp |= 0x08; + if (data.v_total & 512) + tmp |= 0x20; + if (data.v_dispend & 512) + tmp |= 0x40; + if (data.v_sstart & 512) + tmp |= 0x80; + DEBUG printk("CRT_OVERFLOW: %d\n", tmp); + crt_w(CRT_OVERFLOW, tmp); + + crt_w(CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */ + + tmp = 0x40; /* LineCompare bit #8 */ + if (data.v_bstart & 512) + tmp |= 0x20; + if (var->vmode & FB_VMODE_DOUBLE) + tmp |= 0x80; + DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp); + crt_w(CRT_MAX_SCAN_LINE, tmp); + + crt_w(CRT_CURSOR_START, 0x00); + crt_w(CRT_CURSOR_END, 8 & 0x1f); /* font height */ + + crt_w(CRT_START_ADDR_HIGH, 0x00); + crt_w(CRT_START_ADDR_LOW, 0x00); + + crt_w(CRT_CURSOR_LOC_HIGH, 0x00); + crt_w(CRT_CURSOR_LOC_LOW, 0x00); + + DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff); + crt_w(CRT_START_VER_RETR, (data.v_sstart & 0xff)); + +#if 1 + /* 5 refresh cycles per scanline */ + DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20)); +#else + DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32)); +#endif + DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff); + crt_w(CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff)); + + DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff); + crt_w(CRT_START_VER_BLANK, (data.v_bstart & 0xff)); + + DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff); + crt_w(CRT_END_VER_BLANK, (data.v_bstop & 0xff)); + + DEBUG printk("CRT_MODE_CONTROL: 0xe3\n"); + crt_w(CRT_MODE_CONTROL, 0xe3); + + DEBUG printk("CRT_LINE_COMPARE: 0xff\n"); + crt_w(CRT_LINE_COMPARE, 0xff); + + tmp = (var->xres_virtual / 8) * (bpp / 8); + crt_w(CRT_OFFSET, tmp); + + crt_w(CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */ + + tmp = 0x20; /* Enable extended end bits */ + if (data.h_total & 0x100) + tmp |= 0x01; + if ((data.h_dispend) & 0x100) + tmp |= 0x02; + if (data.h_bstart & 0x100) + tmp |= 0x04; + if (data.h_sstart & 0x100) + tmp |= 0x08; + if (var->vmode & FB_VMODE_INTERLACED) + tmp |= 0x10; + DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp); + crt_w(CRT_EXT_HOR_TIMING1, tmp); + + tmp = 0x00; + if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100) + tmp |= 0x10; + crt_w(CRT_EXT_START_ADDR, tmp); + + tmp = 0x00; + if (data.h_total & 0x200) + tmp |= 0x01; + if ((data.h_dispend) & 0x200) + tmp |= 0x02; + if (data.h_bstart & 0x200) + tmp |= 0x04; + if (data.h_sstart & 0x200) + tmp |= 0x08; + tmp |= ((data.h_bstop & 0xc0) >> 2); + tmp |= ((data.h_sstop & 0x60) << 1); + crt_w(CRT_EXT_HOR_TIMING2, tmp); + DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp); + + tmp = 0x10; /* Line compare bit 10 */ + if (data.v_total & 0x400) + tmp |= 0x01; + if ((data.v_dispend) & 0x400) + tmp |= 0x02; + if (data.v_bstart & 0x400) + tmp |= 0x04; + if (data.v_sstart & 0x400) + tmp |= 0x08; + tmp |= ((data.v_bstop & 0x300) >> 3); + if (data.v_sstop & 0x10) + tmp |= 0x80; + crt_w(CRT_EXT_VER_TIMING, tmp); + DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp); + + crt_w(CRT_MONITOR_POWER, 0x00); + + /* + * Convert from ps to Hz. + */ + freq_f = (1.0/(float)var->pixclock) * 1000000000; + freq = ((long)freq_f) * 1000; + + best_freq = find_fq(freq); + pll_w(0x02, best_freq); + best_freq = find_fq(61000000); + pll_w(0x0a, best_freq); + pll_w(0x0e, 0x22); + + gfx_w(GFX_SET_RESET, 0x00); + gfx_w(GFX_ENABLE_SET_RESET, 0x00); + gfx_w(GFX_COLOR_COMPARE, 0x00); + gfx_w(GFX_DATA_ROTATE, 0x00); + gfx_w(GFX_READ_MAP_SELECT, 0x00); + gfx_w(GFX_GRAPHICS_MODE, 0x00); + gfx_w(GFX_MISC, 0x05); + gfx_w(GFX_COLOR_XCARE, 0x0f); + gfx_w(GFX_BITMASK, 0xff); + + reg_r(ACT_ADDRESS_RESET); + attr_w(ACT_PALETTE0 , 0x00); + attr_w(ACT_PALETTE1 , 0x01); + attr_w(ACT_PALETTE2 , 0x02); + attr_w(ACT_PALETTE3 , 0x03); + attr_w(ACT_PALETTE4 , 0x04); + attr_w(ACT_PALETTE5 , 0x05); + attr_w(ACT_PALETTE6 , 0x06); + attr_w(ACT_PALETTE7 , 0x07); + attr_w(ACT_PALETTE8 , 0x08); + attr_w(ACT_PALETTE9 , 0x09); + attr_w(ACT_PALETTE10, 0x0a); + attr_w(ACT_PALETTE11, 0x0b); + attr_w(ACT_PALETTE12, 0x0c); + attr_w(ACT_PALETTE13, 0x0d); + attr_w(ACT_PALETTE14, 0x0e); + attr_w(ACT_PALETTE15, 0x0f); + reg_r(ACT_ADDRESS_RESET); + + attr_w(ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */ + + attr_w(ACT_OVERSCAN_COLOR, 0x00); + attr_w(ACT_COLOR_PLANE_ENA, 0x0f); + attr_w(ACT_HOR_PEL_PANNING, 0x00); + attr_w(ACT_COLOR_SELECT, 0x00); + + reg_r(ACT_ADDRESS_RESET); + reg_w(ACT_DATA, 0x20); + + reg_w(VDAC_MASK, 0xff); + + /* + * Extended palette adressing ??? + */ + switch (bpp){ + case 8: + reg_w(0x83c6, 0x00); + break; + case 16: + reg_w(0x83c6, 0x60); + break; + case 24: + reg_w(0x83c6, 0xe0); + break; + default: + printk("Illegal color-depth: %i\n", bpp); + } + + reg_w(VDAC_ADDRESS, 0x00); + + seq_w(SEQ_MAP_MASK, 0x0f ); + + return 0; +} + +/* + * Initialization + * + * Set the default video mode for this chipset. If a video mode was + * specified on the command line, it will override the default mode. + */ + +static int retz3_init(void) +{ + int i; +#if 0 + volatile unsigned long *CursorBase; +#endif + unsigned long board_addr, board_size; + struct ConfigDev *cd; + + cd = zorro_get_board (z3_key); + zorro_config_board (z3_key, 0); + board_addr = (unsigned long)cd->cd_BoardAddr; + board_size = (unsigned long)cd->cd_BoardSize; + + for (i = 0; i < 256; i++){ + for (i = 0; i < 256; i++){ + retz3_color_table [i][0] = i; + retz3_color_table [i][1] = i; + retz3_color_table [i][2] = i; + retz3_color_table [i][3] = 0; + } + } + + *memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + + z3_mem = kernel_map (board_addr, board_size, + KERNELMAP_NOCACHE_SER, memstart); + + z3_regs = (char*) z3_mem; + z3_fbmem = z3_mem + VIDEO_MEM_OFFSET; + + /* Get memory size - for now we asume its a 4MB board */ + + z3_size = 0x00400000; /* 4 MB */ + + memset ((char*)z3_fbmem, 0, z3_size); + + /* Disable hardware cursor */ + + seq_w(SEQ_CURSOR_Y_INDEX, 0x00); + + +#if 0 + /* Initialize hardware cursor */ + CursorBase = (unsigned long *)((char *)(z3_mem) + z3_size - 0x400); + for (i=0; i < 8; i++){ + *(CursorBase +(i*4)) = 0xffffff00; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } + for (i=8; i < 64; i++){ + *(CursorBase +(i*4)) = 0xffff0000; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } +#endif + + retz3_setcolreg (255, 56, 100, 160, 0); + retz3_setcolreg (254, 0, 0, 0, 0); + + return 0; +} + + +/* + * This function should fill in the `fix' structure based on the + * values in the `par' structure. + */ + +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par) +{ + int i; + + strcpy(fix->id, retz3_fb_name); + fix->smem_start = z3_fbmem; + fix->smem_len = z3_size; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->type_aux = 0; + if (par->bpp == 8) + fix->visual = FB_VISUAL_PSEUDOCOLOR; + else + fix->visual = FB_VISUAL_DIRECTCOLOR; + + fix->xpanstep = 0; + fix->ypanstep = 0; + fix->ywrapstep = 0; + fix->line_length = 0; + + for (i = 0; i < arraysize(fix->reserved); i++) + fix->reserved[i] = 0; + + return 0; +} + + +/* + * Get the video params out of `var'. If a value doesn't fit, round + * it up, if it's too big, return -EINVAL. + */ + +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + par->xres = var->xres; + par->yres = var->yres; + par->xres_vir = var->xres_virtual; + par->yres_vir = var->yres_virtual; + par->bpp = var->bits_per_pixel; + par->pixclock = var->pixclock; + par->vmode = var->vmode; + + par->red = var->red; + par->green = var->green; + par->blue = var->blue; + par->transp = var->transp; + + par->left_margin = var->left_margin; + par->right_margin = var->right_margin; + par->upper_margin = var->upper_margin; + par->lower_margin = var->lower_margin; + par->hsync_len = var->hsync_len; + par->vsync_len = var->vsync_len; + + return 0; +} + + +/* + * Fill the `var' structure based on the values in `par' and maybe + * other values read out of the hardware. + */ + +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + int i; + + var->xres = par->xres; + var->yres = par->yres; + var->xres_virtual = par->xres_vir; + var->yres_virtual = par->yres_vir; + var->xoffset = 0; + var->yoffset = 0; + + var->bits_per_pixel = par->bpp; + var->grayscale = 0; + + var->red = par->red; + var->green = par->green; + var->blue = par->blue; + var->transp = par->transp; + + var->nonstd = 0; + var->activate = 0; + + var->height = -1; + var->width = -1; + + var->accel = FB_ACCEL_RETINAZ3; + + var->pixclock = par->pixclock; + + var->sync = 0; /* ??? */ + var->left_margin = par->left_margin; + var->right_margin = par->right_margin; + var->upper_margin = par->upper_margin; + var->lower_margin = par->lower_margin; + var->hsync_len = par->hsync_len; + var->vsync_len = par->vsync_len; + + for (i = 0; i < arraysize(var->reserved); i++) + var->reserved[i] = 0; + + var->vmode = par->vmode; + return 0; +} + + +/* + * Set a single color register. The values supplied are already + * rounded down to the hardware's capabilities (according to the + * entries in the var structure). Return != 0 for invalid regno. + */ + +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp) +{ + /* We'll get to this */ + + if (regno > 255) + return 1; + + retz3_color_table [regno][0] = red & 0xff; + retz3_color_table [regno][1] = green & 0xff; + retz3_color_table [regno][2] = blue & 0xff; + retz3_color_table [regno][3] = transp; + + reg_w(VDAC_ADDRESS_W, regno); + reg_w(VDAC_DATA, (red & 0xff) >> 2); + reg_w(VDAC_DATA, (green & 0xff) >> 2); + reg_w(VDAC_DATA, (blue & 0xff) >> 2); + + return 0; +} + + +/* + * Read a single color register and split it into + * colors/transparent. Return != 0 for invalid regno. + */ + +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp) +{ + if (regno > 255) + return 1; + *red = retz3_color_table [regno][0]; + *green = retz3_color_table [regno][1]; + *blue = retz3_color_table [regno][2]; + *transp = retz3_color_table [regno][3]; + return 0; +} + + +/* + * (Un)Blank the screen + */ + +void retz3_blank(int blank) +{ + int i; + + if (blank) + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + } + else + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, retz3_color_table [i][0] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][1] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][2] >> 2); + } +} + + +void retz3_bitblt (struct fb_var_screeninfo *var, + unsigned short srcx, unsigned short srcy, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask) +{ + + volatile unsigned long *acm = (unsigned long *) (z3_mem + ACM_OFFSET); + unsigned long *pattern = (unsigned long *)(z3_fbmem + PAT_MEM_OFF); + + unsigned short mod; + unsigned long tmp; + unsigned long pat, src, dst; + unsigned char blt_status; + + int i, xres_virtual = var->xres_virtual; + short bpp = (var->bits_per_pixel & 0xff); + + if (bpp < 8) + bpp = 8; + + tmp = mask | (mask << 16); + +#if 0 + /* + * Check for blitter finished before we start messing with the + * pattern. + */ + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + }while ((blt_status & 1) == 0); +#endif + + i = 0; + do{ + *pattern++ = tmp; + }while(i++ < bpp/4); + + tmp = cmd << 8; + *(acm + ACM_RASTEROP_ROTATION/4) = tmp; + + mod = 0xc0c2; + + pat = 8 * PAT_MEM_OFF; + dst = bpp * (destx + desty * xres_virtual); + + /* + * Source is not set for clear. + */ + if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) { + src = bpp * (srcx + srcy * xres_virtual); + + if (destx > srcx) { + mod &= ~0x8000; + src += bpp * (width - 1); + dst += bpp * (width - 1); + pat += bpp * 2; + } + if (desty > srcy) { + mod &= ~0x4000; + src += bpp * (height - 1) * xres_virtual; + dst += bpp * (height - 1) * xres_virtual; + pat += bpp * 4; + } + + *(acm + ACM_SOURCE/4) = cpu_to_le32(src); + } + + *(acm + ACM_PATTERN/4) = cpu_to_le32(pat); + + *(acm + ACM_DESTINATION/4) = cpu_to_le32(dst); + + tmp = mod << 16; + *(acm + ACM_CONTROL/4) = tmp; + + tmp = width | (height << 16); + + *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp); + + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; + + /* + * No reason to wait for the blitter to finish, it is better + * just to check if it has finished before we use it again. + */ +#if 1 +#if 0 + while ((*(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)) & 1) == 0); +#else + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + } + while ((blt_status & 1) == 0); +#endif +#endif +} + +#if 0 +void retz3_fill (unsigned short x, unsigned short y, unsigned + short width, unsigned short height, + unsigned short mode, unsigned short color) +{ + +} +#endif + + +/************************************************************** + * Move cursor to x, y + */ +void retz3_MoveCursor (unsigned short x, unsigned short y) +{ + /* Guess we gotta deal with the cursor at some point */ +} + + +/* -------------------- Interfaces to hardware functions -------------------- */ + + +static struct fb_hwswitch retz3_switch = { + retz3_init, retz3_encode_fix, retz3_decode_var, retz3_encode_var, + retz3_getcolreg, retz3_setcolreg, retz3_blank +}; + + +/* -------------------- Generic routines ------------------------------------ */ + + +/* + * Fill the hardware's `par' structure. + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par) +{ + if (current_par_valid) + *par = current_par; + else + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], par); +} + + +static void retz3_fb_set_par(struct retz3_fb_par *par) +{ + current_par = *par; + current_par_valid = 1; +} + + +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) +{ + int err, activate; + struct retz3_fb_par par; + + if ((err = fbhw->decode_var(var, &par))) + return err; + activate = var->activate; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) + retz3_fb_set_par(&par); + fbhw->encode_var(var, &par); + var->activate = activate; + +#if 1 + retz3_set_video(var, ¤t_par); +#endif + return 0; +} + + +/* + * Default Colormaps + */ + +static unsigned short red16[] = + { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000, + 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff }; +static unsigned short green16[] = + { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000, + 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff }; +static unsigned short blue16[] = + { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, + 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff }; + + +static struct fb_cmap default_16_colors = + { 0, 16, red16, green16, blue16, NULL }; + + +static struct fb_cmap *get_default_colormap(int bpp) +{ + return &default_16_colors; +} + + +#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) +#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ + ((1<<(width))-1)) : 0)) + +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp)) + return 0; + hred = CNVT_FROMHW(hred, var->red.length); + hgreen = CNVT_FROMHW(hgreen, var->green.length); + hblue = CNVT_FROMHW(hblue, var->blue.length); + htransp = CNVT_FROMHW(htransp, var->transp.length); + if (kspc) { + *red = hred; + *green = hgreen; + *blue = hblue; + if (transp) + *transp = htransp; + } else { + put_user(hred, red); + put_user(hgreen, green); + put_user(hblue, blue); + if (transp) + put_user(htransp, transp); + } + red++; + green++; + blue++; + if (transp) + transp++; + } + return 0; +} + + +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (kspc) { + hred = *red; + hgreen = *green; + hblue = *blue; + htransp = transp ? *transp : 0; + } else { + get_user(hred, red); + get_user(hgreen, green); + get_user(hblue, blue); + if (transp) + get_user(htransp, transp); + else + htransp = 0; + } + hred = CNVT_TOHW(hred, var->red.length); + hgreen = CNVT_TOHW(hgreen, var->green.length); + hblue = CNVT_TOHW(hblue, var->blue.length); + htransp = CNVT_TOHW(htransp, var->transp.length); + red++; + green++; + blue++; + if (transp) + transp++; + if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp)) + return 0; + } + return 0; +} + + +static void do_install_cmap(int con) +{ + if (con != currcon) + return; + if (disp[con].cmap.len) + do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1); + else + do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + &disp[con].var, 1); +} + + +static void memcpy_fs(int fsfromto, void *to, void *from, int len) +{ + switch (fsfromto) { + case 0: + memcpy(to, from, len); + return; + case 1: + copy_from_user(to, from, len); + return; + case 2: + copy_to_user(to, from, len); + return; + } +} + + +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto) +{ + int size; + int tooff = 0, fromoff = 0; + + if (to->start > from->start) + fromoff = to->start-from->start; + else + tooff = from->start-to->start; + size = to->len-tooff; + if (size > from->len-fromoff) + size = from->len-fromoff; + if (size < 0) + return; + size *= sizeof(unsigned short); + memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size); + memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size); + memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size); + if (from->transp && to->transp) + memcpy_fs(fsfromto, to->transp+tooff, + from->transp+fromoff, size); +} + + +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp) +{ + int size = len*sizeof(unsigned short); + + if (cmap->len != len) { + if (cmap->red) + kfree(cmap->red); + if (cmap->green) + kfree(cmap->green); + if (cmap->blue) + kfree(cmap->blue); + if (cmap->transp) + kfree(cmap->transp); + cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; + cmap->len = 0; + if (!len) + return 0; + if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) + return -1; + if (transp) { + if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) + return -1; + } else + cmap->transp = NULL; + } + cmap->start = 0; + cmap->len = len; + copy_cmap(get_default_colormap(len), cmap, 0); + return 0; +} + + +/* + * Get the Fixed Part of the Display + */ + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) + retz3_fb_get_par(&par); + else + error = fbhw->decode_var(&disp[con].var, &par); + return(error ? error : fbhw->encode_fix(fix, &par)); +} + + +/* + * Get the User Defined Part of the Display + */ + +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) { + retz3_fb_get_par(&par); + error = fbhw->encode_var(var, &par); + } else + *var = disp[con].var; + return error; +} + + +static void retz3_fb_set_disp(int con) +{ + struct fb_fix_screeninfo fix; + + retz3_fb_get_fix(&fix, con); + if (con == -1) + con = 0; + disp[con].screen_base = (unsigned char *)fix.smem_start; + disp[con].visual = fix.visual; + disp[con].type = fix.type; + disp[con].type_aux = fix.type_aux; + disp[con].ypanstep = fix.ypanstep; + disp[con].ywrapstep = fix.ywrapstep; + disp[con].can_soft_blank = 1; + disp[con].inverse = z3fb_inverse; +} + + +/* + * Set the User Defined Part of the Display + */ + +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) +{ + int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp; + + if ((err = do_fb_set_var(var, con == currcon))) + return err; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { + oldxres = disp[con].var.xres; + oldyres = disp[con].var.yres; + oldvxres = disp[con].var.xres_virtual; + oldvyres = disp[con].var.yres_virtual; + oldbpp = disp[con].var.bits_per_pixel; + disp[con].var = *var; + if (oldxres != var->xres || oldyres != var->yres || + oldvxres != var->xres_virtual || + oldvyres != var->yres_virtual || + oldbpp != var->bits_per_pixel) { + retz3_fb_set_disp(con); + (*fb_info.changevar)(con); + alloc_cmap(&disp[con].cmap, 0, 0); + do_install_cmap(con); + } + } + var->activate = 0; + return 0; +} + + +/* + * Get the Colormap + */ + +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + if (con == currcon) /* current console? */ + return(do_fb_get_cmap(cmap, &disp[con].var, kspc)); + else if (disp[con].cmap.len) /* non default colormap? */ + copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2); + else + copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + cmap, kspc ? 0 : 2); + return 0; +} + + +/* + * Set the Colormap + */ + +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + int err; + + if (!disp[con].cmap.len) { /* no colormap allocated? */ + if ((err = alloc_cmap(&disp[con].cmap, + 1<init(); + + if (z3fb_mode == -1) + z3fb_mode = 1; + + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], &par); + fbhw->encode_var(&retz3_fb_predefined[0], &par); + + strcpy(fb_info.modename, retz3_fb_name); + fb_info.disp = disp; + fb_info.switch_con = &z3fb_switch; + fb_info.updatevar = &z3fb_updatevar; + fb_info.blank = &z3fb_blank; + fb_info.setcmap = &z3fb_setcmap; + + do_fb_set_var(&retz3_fb_predefined[0], 0); + retz3_fb_get_var(&disp[0].var, -1); + retz3_fb_set_disp(-1); + do_install_cmap(0); + + return &fb_info; +} + + +static int z3fb_switch(int con) +{ + /* Do we have to save the colormap? */ + if (disp[currcon].cmap.len) + do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1); + + do_fb_set_var(&disp[con].var, 1); + currcon = con; + /* Install new colormap */ + do_install_cmap(con); + return 0; +} + + +/* + * Update the `var' structure (called by fbcon.c) + * + * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. + * Since it's called by a kernel driver, no range checking is done. + */ + +static int z3fb_updatevar(int con) +{ + return 0; +} + + +/* + * Blank the display. + */ + +static void z3fb_blank(int blank) +{ + fbhw->blank(blank); +} + + +/* + * Set the colormap + */ + +static int z3fb_setcmap(struct fb_cmap *cmap, int con) +{ + return(retz3_fb_set_cmap(cmap, 1, con)); +} + + +/* + * Get a Video Mode + */ + +static int get_video_mode(const char *name) +{ + int i; + + for (i = 1; i <= NUM_PREDEF_MODES; i++) + if (!strcmp(name, retz3_fb_modenames[i])){ + retz3_fb_predefined[0] = retz3_fb_predefined[i]; + return i; + } + return -1; +} diff --git a/arch/m68k/amiga/retz3fb.h b/arch/m68k/amiga/retz3fb.h new file mode 100644 index 000000000..9ff209060 --- /dev/null +++ b/arch/m68k/amiga/retz3fb.h @@ -0,0 +1,572 @@ +/* + * Linux/arch/m68k/amiga/retz3fb.h -- Defines and macros for the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * History: + * - 22 Jan 97: Initial work + * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Macros to read and write to registers. + */ +#define reg_w(reg,dat) (*(z3_regs + reg) = dat) +#define reg_r(reg) (*(z3_regs + reg)) + +/* + * Macro to access the sequencer. + */ +#define seq_w(sreg,sdat) \ + do{ reg_w(SEQ_IDX, sreg); reg_w(SEQ_DATA, sdat); } while(0) + +/* + * Macro to access the CRT controller. + */ +#define crt_w(creg,cdat) \ + do{ reg_w(CRT_IDX, creg); reg_w(CRT_DATA, cdat); } while(0) + +/* + * Macro to access the graphics controller. + */ +#define gfx_w(greg,gdat) \ + do{ reg_w(GFX_IDX, greg); reg_w(GFX_DATA, gdat); } while(0) + +/* + * Macro to access the attribute controller. + */ +#define attr_w(areg,adat) \ + do{ reg_w(ACT_IDX, areg); reg_w(ACT_DATA, adat); } while(0) + +/* + * Macro to access the pll. + */ +#define pll_w(preg,pdat) \ + do{ reg_w(PLL_IDX, preg); \ + reg_w(PLL_DATA, (pdat & 0xff)); \ + reg_w(PLL_DATA, (pdat >> 8));\ + } while(0) + +/* + * Offsets + */ +#define VIDEO_MEM_OFFSET 0x00c00000 +#define ACM_OFFSET 0x00b00000 + +/* + * Accelerator Control Menu + */ +#define ACM_PRIMARY_OFFSET 0x00 +#define ACM_SECONDARY_OFFSET 0x04 +#define ACM_MODE_CONTROL 0x08 +#define ACM_CURSOR_POSITION 0x0c +#define ACM_START_STATUS 0x30 +#define ACM_CONTROL 0x34 +#define ACM_RASTEROP_ROTATION 0x38 +#define ACM_BITMAP_DIMENSION 0x3c +#define ACM_DESTINATION 0x40 +#define ACM_SOURCE 0x44 +#define ACM_PATTERN 0x48 +#define ACM_FOREGROUND 0x4c +#define ACM_BACKGROUND 0x50 + +/* + * Video DAC addresses + */ +#define VDAC_ADDRESS 0x03c8 +#define VDAC_ADDRESS_W 0x03c8 +#define VDAC_ADDRESS_R 0x03c7 +#define VDAC_STATE 0x03c7 +#define VDAC_DATA 0x03c9 +#define VDAC_MASK 0x03c6 + +/* + * Sequencer + */ +#define SEQ_IDX 0x03c4 /* Sequencer Index */ +#define SEQ_DATA 0x03c5 +#define SEQ_RESET 0x00 +#define SEQ_CLOCKING_MODE 0x01 +#define SEQ_MAP_MASK 0x02 +#define SEQ_CHAR_MAP_SELECT 0x03 +#define SEQ_MEMORY_MODE 0x04 +#define SEQ_EXTENDED_ENABLE 0x05 /* NCR extensions */ +#define SEQ_UNKNOWN1 0x06 +#define SEQ_UNKNOWN2 0x07 +#define SEQ_CHIP_ID 0x08 +#define SEQ_UNKNOWN3 0x09 +#define SEQ_CURSOR_COLOR1 0x0a +#define SEQ_CURSOR_COLOR0 0x0b +#define SEQ_CURSOR_CONTROL 0x0c +#define SEQ_CURSOR_X_LOC_HI 0x0d +#define SEQ_CURSOR_X_LOC_LO 0x0e +#define SEQ_CURSOR_Y_LOC_HI 0x0f +#define SEQ_CURSOR_Y_LOC_LO 0x10 +#define SEQ_CURSOR_X_INDEX 0x11 +#define SEQ_CURSOR_Y_INDEX 0x12 +#define SEQ_CURSOR_STORE_HI 0x13 +#define SEQ_CURSOR_STORE_LO 0x14 +#define SEQ_CURSOR_ST_OFF_HI 0x15 +#define SEQ_CURSOR_ST_OFF_LO 0x16 +#define SEQ_CURSOR_PIXELMASK 0x17 +#define SEQ_PRIM_HOST_OFF_HI 0x18 +#define SEQ_PRIM_HOST_OFF_LO 0x19 +#define SEQ_LINEAR_0 0x1a +#define SEQ_LINEAR_1 0x1b +#define SEQ_SEC_HOST_OFF_HI 0x1c +#define SEQ_SEC_HOST_OFF_LO 0x1d +#define SEQ_EXTENDED_MEM_ENA 0x1e +#define SEQ_EXT_CLOCK_MODE 0x1f +#define SEQ_EXT_VIDEO_ADDR 0x20 +#define SEQ_EXT_PIXEL_CNTL 0x21 +#define SEQ_BUS_WIDTH_FEEDB 0x22 +#define SEQ_PERF_SELECT 0x23 +#define SEQ_COLOR_EXP_WFG 0x24 +#define SEQ_COLOR_EXP_WBG 0x25 +#define SEQ_EXT_RW_CONTROL 0x26 +#define SEQ_MISC_FEATURE_SEL 0x27 +#define SEQ_COLOR_KEY_CNTL 0x28 +#define SEQ_COLOR_KEY_MATCH0 0x29 +#define SEQ_COLOR_KEY_MATCH1 0x2a +#define SEQ_COLOR_KEY_MATCH2 0x2b +#define SEQ_UNKNOWN6 0x2c +#define SEQ_CRC_CONTROL 0x2d +#define SEQ_CRC_DATA_LOW 0x2e +#define SEQ_CRC_DATA_HIGH 0x2f +#define SEQ_MEMORY_MAP_CNTL 0x30 +#define SEQ_ACM_APERTURE_1 0x31 +#define SEQ_ACM_APERTURE_2 0x32 +#define SEQ_ACM_APERTURE_3 0x33 +#define SEQ_BIOS_UTILITY_0 0x3e +#define SEQ_BIOS_UTILITY_1 0x3f + +/* + * Graphics Controller + */ +#define GFX_IDX 0x03ce +#define GFX_DATA 0x03cf +#define GFX_SET_RESET 0x00 +#define GFX_ENABLE_SET_RESET 0x01 +#define GFX_COLOR_COMPARE 0x02 +#define GFX_DATA_ROTATE 0x03 +#define GFX_READ_MAP_SELECT 0x04 +#define GFX_GRAPHICS_MODE 0x05 +#define GFX_MISC 0x06 +#define GFX_COLOR_XCARE 0x07 +#define GFX_BITMASK 0x08 + +/* + * CRT Controller + */ +#define CRT_IDX 0x03d4 +#define CRT_DATA 0x03d5 +#define CRT_HOR_TOTAL 0x00 +#define CRT_HOR_DISP_ENA_END 0x01 +#define CRT_START_HOR_BLANK 0x02 +#define CRT_END_HOR_BLANK 0x03 +#define CRT_START_HOR_RETR 0x04 +#define CRT_END_HOR_RETR 0x05 +#define CRT_VER_TOTAL 0x06 +#define CRT_OVERFLOW 0x07 +#define CRT_PRESET_ROW_SCAN 0x08 +#define CRT_MAX_SCAN_LINE 0x09 +#define CRT_CURSOR_START 0x0a +#define CRT_CURSOR_END 0x0b +#define CRT_START_ADDR_HIGH 0x0c +#define CRT_START_ADDR_LOW 0x0d +#define CRT_CURSOR_LOC_HIGH 0x0e +#define CRT_CURSOR_LOC_LOW 0x0f +#define CRT_START_VER_RETR 0x10 +#define CRT_END_VER_RETR 0x11 +#define CRT_VER_DISP_ENA_END 0x12 +#define CRT_OFFSET 0x13 +#define CRT_UNDERLINE_LOC 0x14 +#define CRT_START_VER_BLANK 0x15 +#define CRT_END_VER_BLANK 0x16 +#define CRT_MODE_CONTROL 0x17 +#define CRT_LINE_COMPARE 0x18 +#define CRT_UNKNOWN1 0x19 +#define CRT_UNKNOWN2 0x1a +#define CRT_UNKNOWN3 0x1b +#define CRT_UNKNOWN4 0x1c +#define CRT_UNKNOWN5 0x1d +#define CRT_UNKNOWN6 0x1e +#define CRT_UNKNOWN7 0x1f +#define CRT_UNKNOWN8 0x20 +#define CRT_UNKNOWN9 0x21 +#define CRT_UNKNOWN10 0x22 +#define CRT_UNKNOWN11 0x23 +#define CRT_UNKNOWN12 0x24 +#define CRT_UNKNOWN13 0x25 +#define CRT_UNKNOWN14 0x26 +#define CRT_UNKNOWN15 0x27 +#define CRT_UNKNOWN16 0x28 +#define CRT_UNKNOWN17 0x29 +#define CRT_UNKNOWN18 0x2a +#define CRT_UNKNOWN19 0x2b +#define CRT_UNKNOWN20 0x2c +#define CRT_UNKNOWN21 0x2d +#define CRT_UNKNOWN22 0x2e +#define CRT_UNKNOWN23 0x2f +#define CRT_EXT_HOR_TIMING1 0x30 /* NCR crt extensions */ +#define CRT_EXT_START_ADDR 0x31 +#define CRT_EXT_HOR_TIMING2 0x32 +#define CRT_EXT_VER_TIMING 0x33 +#define CRT_MONITOR_POWER 0x34 + +/* + * General Registers + */ +#define GREG_STATUS0_R 0x03c2 +#define GREG_STATUS1_R 0x03da +#define GREG_MISC_OUTPUT_R 0x03cc +#define GREG_MISC_OUTPUT_W 0x03c2 +#define GREG_FEATURE_CONTROL_R 0x03ca +#define GREG_FEATURE_CONTROL_W 0x03da +#define GREG_POS 0x0102 + +/* + * Attribute Controller + */ +#define ACT_IDX 0x03C0 +#define ACT_ADDRESS_R 0x03C0 +#define ACT_DATA 0x03C0 +#define ACT_ADDRESS_RESET 0x03DA +#define ACT_PALETTE0 0x00 +#define ACT_PALETTE1 0x01 +#define ACT_PALETTE2 0x02 +#define ACT_PALETTE3 0x03 +#define ACT_PALETTE4 0x04 +#define ACT_PALETTE5 0x05 +#define ACT_PALETTE6 0x06 +#define ACT_PALETTE7 0x07 +#define ACT_PALETTE8 0x08 +#define ACT_PALETTE9 0x09 +#define ACT_PALETTE10 0x0A +#define ACT_PALETTE11 0x0B +#define ACT_PALETTE12 0x0C +#define ACT_PALETTE13 0x0D +#define ACT_PALETTE14 0x0E +#define ACT_PALETTE15 0x0F +#define ACT_ATTR_MODE_CNTL 0x10 +#define ACT_OVERSCAN_COLOR 0x11 +#define ACT_COLOR_PLANE_ENA 0x12 +#define ACT_HOR_PEL_PANNING 0x13 +#define ACT_COLOR_SELECT 0x14 + +/* + * PLL + */ +#define PLL_IDX 0x83c8 +#define PLL_DATA 0x83c9 + +/* + * Blitter operations + */ +#define Z3BLTclear 0x00 /* 0 */ +#define Z3BLTand 0x80 /* src AND dst */ +#define Z3BLTandReverse 0x40 /* src AND NOT dst */ +#define Z3BLTcopy 0xc0 /* src */ +#define Z3BLTandInverted 0x20 /* NOT src AND dst */ +#define Z3BLTnoop 0xa0 /* dst */ +#define Z3BLTxor 0x60 /* src XOR dst */ +#define Z3BLTor 0xe0 /* src OR dst */ +#define Z3BLTnor 0x10 /* NOT src AND NOT dst */ +#define Z3BLTequiv 0x90 /* NOT src XOR dst */ +#define Z3BLTinvert 0x50 /* NOT dst */ +#define Z3BLTorReverse 0xd0 /* src OR NOT dst */ +#define Z3BLTcopyInverted 0x30 /* NOT src */ +#define Z3BLTorInverted 0xb0 /* NOT src OR dst */ +#define Z3BLTnand 0x70 /* NOT src OR NOT dst */ +#define Z3BLTset 0xf0 /* 1 */ +/* + * Linux/arch/m68k/amiga/retz3fb.h -- Defines and macros for the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * History: + * - 22 Jan 97: Initial work + * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Macros to read and write to registers. + */ +#define reg_w(reg,dat) (*(z3_regs + reg) = dat) +#define reg_r(reg) (*(z3_regs + reg)) + +/* + * Macro to access the sequencer. + */ +#define seq_w(sreg,sdat) \ + do{ reg_w(SEQ_IDX, sreg); reg_w(SEQ_DATA, sdat); } while(0) + +/* + * Macro to access the CRT controller. + */ +#define crt_w(creg,cdat) \ + do{ reg_w(CRT_IDX, creg); reg_w(CRT_DATA, cdat); } while(0) + +/* + * Macro to access the graphics controller. + */ +#define gfx_w(greg,gdat) \ + do{ reg_w(GFX_IDX, greg); reg_w(GFX_DATA, gdat); } while(0) + +/* + * Macro to access the attribute controller. + */ +#define attr_w(areg,adat) \ + do{ reg_w(ACT_IDX, areg); reg_w(ACT_DATA, adat); } while(0) + +/* + * Macro to access the pll. + */ +#define pll_w(preg,pdat) \ + do{ reg_w(PLL_IDX, preg); \ + reg_w(PLL_DATA, (pdat & 0xff)); \ + reg_w(PLL_DATA, (pdat >> 8));\ + } while(0) + +/* + * Offsets + */ +#define VIDEO_MEM_OFFSET 0x00c00000 +#define ACM_OFFSET 0x00b00000 + +/* + * Accelerator Control Menu + */ +#define ACM_PRIMARY_OFFSET 0x00 +#define ACM_SECONDARY_OFFSET 0x04 +#define ACM_MODE_CONTROL 0x08 +#define ACM_CURSOR_POSITION 0x0c +#define ACM_START_STATUS 0x30 +#define ACM_CONTROL 0x34 +#define ACM_RASTEROP_ROTATION 0x38 +#define ACM_BITMAP_DIMENSION 0x3c +#define ACM_DESTINATION 0x40 +#define ACM_SOURCE 0x44 +#define ACM_PATTERN 0x48 +#define ACM_FOREGROUND 0x4c +#define ACM_BACKGROUND 0x50 + +/* + * Video DAC addresses + */ +#define VDAC_ADDRESS 0x03c8 +#define VDAC_ADDRESS_W 0x03c8 +#define VDAC_ADDRESS_R 0x03c7 +#define VDAC_STATE 0x03c7 +#define VDAC_DATA 0x03c9 +#define VDAC_MASK 0x03c6 + +/* + * Sequencer + */ +#define SEQ_IDX 0x03c4 /* Sequencer Index */ +#define SEQ_DATA 0x03c5 +#define SEQ_RESET 0x00 +#define SEQ_CLOCKING_MODE 0x01 +#define SEQ_MAP_MASK 0x02 +#define SEQ_CHAR_MAP_SELECT 0x03 +#define SEQ_MEMORY_MODE 0x04 +#define SEQ_EXTENDED_ENABLE 0x05 /* NCR extensions */ +#define SEQ_UNKNOWN1 0x06 +#define SEQ_UNKNOWN2 0x07 +#define SEQ_CHIP_ID 0x08 +#define SEQ_UNKNOWN3 0x09 +#define SEQ_CURSOR_COLOR1 0x0a +#define SEQ_CURSOR_COLOR0 0x0b +#define SEQ_CURSOR_CONTROL 0x0c +#define SEQ_CURSOR_X_LOC_HI 0x0d +#define SEQ_CURSOR_X_LOC_LO 0x0e +#define SEQ_CURSOR_Y_LOC_HI 0x0f +#define SEQ_CURSOR_Y_LOC_LO 0x10 +#define SEQ_CURSOR_X_INDEX 0x11 +#define SEQ_CURSOR_Y_INDEX 0x12 +#define SEQ_CURSOR_STORE_HI 0x13 +#define SEQ_CURSOR_STORE_LO 0x14 +#define SEQ_CURSOR_ST_OFF_HI 0x15 +#define SEQ_CURSOR_ST_OFF_LO 0x16 +#define SEQ_CURSOR_PIXELMASK 0x17 +#define SEQ_PRIM_HOST_OFF_HI 0x18 +#define SEQ_PRIM_HOST_OFF_LO 0x19 +#define SEQ_LINEAR_0 0x1a +#define SEQ_LINEAR_1 0x1b +#define SEQ_SEC_HOST_OFF_HI 0x1c +#define SEQ_SEC_HOST_OFF_LO 0x1d +#define SEQ_EXTENDED_MEM_ENA 0x1e +#define SEQ_EXT_CLOCK_MODE 0x1f +#define SEQ_EXT_VIDEO_ADDR 0x20 +#define SEQ_EXT_PIXEL_CNTL 0x21 +#define SEQ_BUS_WIDTH_FEEDB 0x22 +#define SEQ_PERF_SELECT 0x23 +#define SEQ_COLOR_EXP_WFG 0x24 +#define SEQ_COLOR_EXP_WBG 0x25 +#define SEQ_EXT_RW_CONTROL 0x26 +#define SEQ_MISC_FEATURE_SEL 0x27 +#define SEQ_COLOR_KEY_CNTL 0x28 +#define SEQ_COLOR_KEY_MATCH0 0x29 +#define SEQ_COLOR_KEY_MATCH1 0x2a +#define SEQ_COLOR_KEY_MATCH2 0x2b +#define SEQ_UNKNOWN6 0x2c +#define SEQ_CRC_CONTROL 0x2d +#define SEQ_CRC_DATA_LOW 0x2e +#define SEQ_CRC_DATA_HIGH 0x2f +#define SEQ_MEMORY_MAP_CNTL 0x30 +#define SEQ_ACM_APERTURE_1 0x31 +#define SEQ_ACM_APERTURE_2 0x32 +#define SEQ_ACM_APERTURE_3 0x33 +#define SEQ_BIOS_UTILITY_0 0x3e +#define SEQ_BIOS_UTILITY_1 0x3f + +/* + * Graphics Controller + */ +#define GFX_IDX 0x03ce +#define GFX_DATA 0x03cf +#define GFX_SET_RESET 0x00 +#define GFX_ENABLE_SET_RESET 0x01 +#define GFX_COLOR_COMPARE 0x02 +#define GFX_DATA_ROTATE 0x03 +#define GFX_READ_MAP_SELECT 0x04 +#define GFX_GRAPHICS_MODE 0x05 +#define GFX_MISC 0x06 +#define GFX_COLOR_XCARE 0x07 +#define GFX_BITMASK 0x08 + +/* + * CRT Controller + */ +#define CRT_IDX 0x03d4 +#define CRT_DATA 0x03d5 +#define CRT_HOR_TOTAL 0x00 +#define CRT_HOR_DISP_ENA_END 0x01 +#define CRT_START_HOR_BLANK 0x02 +#define CRT_END_HOR_BLANK 0x03 +#define CRT_START_HOR_RETR 0x04 +#define CRT_END_HOR_RETR 0x05 +#define CRT_VER_TOTAL 0x06 +#define CRT_OVERFLOW 0x07 +#define CRT_PRESET_ROW_SCAN 0x08 +#define CRT_MAX_SCAN_LINE 0x09 +#define CRT_CURSOR_START 0x0a +#define CRT_CURSOR_END 0x0b +#define CRT_START_ADDR_HIGH 0x0c +#define CRT_START_ADDR_LOW 0x0d +#define CRT_CURSOR_LOC_HIGH 0x0e +#define CRT_CURSOR_LOC_LOW 0x0f +#define CRT_START_VER_RETR 0x10 +#define CRT_END_VER_RETR 0x11 +#define CRT_VER_DISP_ENA_END 0x12 +#define CRT_OFFSET 0x13 +#define CRT_UNDERLINE_LOC 0x14 +#define CRT_START_VER_BLANK 0x15 +#define CRT_END_VER_BLANK 0x16 +#define CRT_MODE_CONTROL 0x17 +#define CRT_LINE_COMPARE 0x18 +#define CRT_UNKNOWN1 0x19 +#define CRT_UNKNOWN2 0x1a +#define CRT_UNKNOWN3 0x1b +#define CRT_UNKNOWN4 0x1c +#define CRT_UNKNOWN5 0x1d +#define CRT_UNKNOWN6 0x1e +#define CRT_UNKNOWN7 0x1f +#define CRT_UNKNOWN8 0x20 +#define CRT_UNKNOWN9 0x21 +#define CRT_UNKNOWN10 0x22 +#define CRT_UNKNOWN11 0x23 +#define CRT_UNKNOWN12 0x24 +#define CRT_UNKNOWN13 0x25 +#define CRT_UNKNOWN14 0x26 +#define CRT_UNKNOWN15 0x27 +#define CRT_UNKNOWN16 0x28 +#define CRT_UNKNOWN17 0x29 +#define CRT_UNKNOWN18 0x2a +#define CRT_UNKNOWN19 0x2b +#define CRT_UNKNOWN20 0x2c +#define CRT_UNKNOWN21 0x2d +#define CRT_UNKNOWN22 0x2e +#define CRT_UNKNOWN23 0x2f +#define CRT_EXT_HOR_TIMING1 0x30 /* NCR crt extensions */ +#define CRT_EXT_START_ADDR 0x31 +#define CRT_EXT_HOR_TIMING2 0x32 +#define CRT_EXT_VER_TIMING 0x33 +#define CRT_MONITOR_POWER 0x34 + +/* + * General Registers + */ +#define GREG_STATUS0_R 0x03c2 +#define GREG_STATUS1_R 0x03da +#define GREG_MISC_OUTPUT_R 0x03cc +#define GREG_MISC_OUTPUT_W 0x03c2 +#define GREG_FEATURE_CONTROL_R 0x03ca +#define GREG_FEATURE_CONTROL_W 0x03da +#define GREG_POS 0x0102 + +/* + * Attribute Controller + */ +#define ACT_IDX 0x03C0 +#define ACT_ADDRESS_R 0x03C0 +#define ACT_DATA 0x03C0 +#define ACT_ADDRESS_RESET 0x03DA +#define ACT_PALETTE0 0x00 +#define ACT_PALETTE1 0x01 +#define ACT_PALETTE2 0x02 +#define ACT_PALETTE3 0x03 +#define ACT_PALETTE4 0x04 +#define ACT_PALETTE5 0x05 +#define ACT_PALETTE6 0x06 +#define ACT_PALETTE7 0x07 +#define ACT_PALETTE8 0x08 +#define ACT_PALETTE9 0x09 +#define ACT_PALETTE10 0x0A +#define ACT_PALETTE11 0x0B +#define ACT_PALETTE12 0x0C +#define ACT_PALETTE13 0x0D +#define ACT_PALETTE14 0x0E +#define ACT_PALETTE15 0x0F +#define ACT_ATTR_MODE_CNTL 0x10 +#define ACT_OVERSCAN_COLOR 0x11 +#define ACT_COLOR_PLANE_ENA 0x12 +#define ACT_HOR_PEL_PANNING 0x13 +#define ACT_COLOR_SELECT 0x14 + +/* + * PLL + */ +#define PLL_IDX 0x83c8 +#define PLL_DATA 0x83c9 + +/* + * Blitter operations + */ +#define Z3BLTclear 0x00 /* 0 */ +#define Z3BLTand 0x80 /* src AND dst */ +#define Z3BLTandReverse 0x40 /* src AND NOT dst */ +#define Z3BLTcopy 0xc0 /* src */ +#define Z3BLTandInverted 0x20 /* NOT src AND dst */ +#define Z3BLTnoop 0xa0 /* dst */ +#define Z3BLTxor 0x60 /* src XOR dst */ +#define Z3BLTor 0xe0 /* src OR dst */ +#define Z3BLTnor 0x10 /* NOT src AND NOT dst */ +#define Z3BLTequiv 0x90 /* NOT src XOR dst */ +#define Z3BLTinvert 0x50 /* NOT dst */ +#define Z3BLTorReverse 0xd0 /* src OR NOT dst */ +#define Z3BLTcopyInverted 0x30 /* NOT src */ +#define Z3BLTorInverted 0xb0 /* NOT src OR dst */ +#define Z3BLTnand 0x70 /* NOT src OR NOT dst */ +#define Z3BLTset 0xf0 /* 1 */ diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index cdd88eb9b..2cb35e67f 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -668,7 +668,7 @@ SYMBOL_NAME_LABEL(sys_call_table) .long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */ .long SYMBOL_NAME(sys_query_module) .long SYMBOL_NAME(sys_poll) - .long SYMBOL_NAME(sys_ni_syscall) /* will be sys_nfsservctl */ + .long SYMBOL_NAME(sys_nfsservctl) .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index 7206a6e14..70042857f 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.68 1997/04/16 05:55:58 davem Exp $ +/* $Id: irq.c,v 1.72 1997/04/20 11:41:26 ecd Exp $ * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the * Sparc the IRQ's are basically 'cast in stone' * and you are supposed to probe the prom's device @@ -292,7 +292,11 @@ void free_irq(unsigned int irq, void *dev_id) /* Per-processor IRQ locking depth, both SMP and non-SMP code use this. */ unsigned int local_irq_count[NR_CPUS]; +#ifdef __SMP__ atomic_t __sparc_bh_counter = ATOMIC_INIT(0); +#else +int __sparc_bh_counter = 0; +#endif #ifdef __SMP__ /* SMP interrupt locking on Sparc. */ @@ -309,47 +313,8 @@ spinlock_t global_bh_lock = SPIN_LOCK_UNLOCKED; /* Global IRQ locking depth. */ atomic_t global_irq_count = ATOMIC_INIT(0); -#define irq_active(cpu) \ - (atomic_read(&global_irq_count) != local_irq_count[cpu]) - -static unsigned long previous_irqholder; - -#define INIT_STUCK 10000000 - -#define STUCK \ -if (!--stuck) { \ - printk("wait_on_irq CPU#%d stuck at %08lx, waiting for [%08lx:%x] " \ - "(local=[%d(%x:%x:%x:%x)], global=[%d:%x]) ", \ - cpu, where, previous_irqholder, global_irq_holder, \ - local_count, local_irq_count[0], local_irq_count[1], \ - local_irq_count[2], local_irq_count[3], \ - atomic_read(&global_irq_count), global_irq_lock); \ - printk("g[%d:%x]\n", atomic_read(&global_irq_count), global_irq_lock); \ - stuck = INIT_STUCK; \ -} - -static inline void wait_on_irq(int cpu, unsigned long where) -{ - int stuck = INIT_STUCK; - int local_count = local_irq_count[cpu]; - - while(local_count != atomic_read(&global_irq_count)) { - atomic_sub(local_count, &global_irq_count); - spin_unlock(&global_irq_lock); - while(1) { - STUCK; - if(atomic_read(&global_irq_count)) - continue; - if(global_irq_lock) - continue; - if(spin_trylock(&global_irq_lock)) - break; - } - atomic_add(local_count, &global_irq_count); - } -} - /* There has to be a better way. */ +/* XXX Must write faster version in irqlock.S -DaveM */ void synchronize_irq(void) { int cpu = smp_processor_id(); @@ -366,127 +331,6 @@ void synchronize_irq(void) } } -#undef INIT_STUCK -#define INIT_STUCK 10000000 - -#undef STUCK -#define STUCK \ -if (!--stuck) {printk("get_irqlock stuck at %08lx, waiting for %08lx\n", where, previous_irqholder); stuck = INIT_STUCK;} - -static inline void get_irqlock(int cpu, unsigned long where) -{ - int stuck = INIT_STUCK; - - if(!spin_trylock(&global_irq_lock)) { - if((unsigned char) cpu == global_irq_holder) - return; - do { - do { - STUCK; - barrier(); - } while(global_irq_lock); - } while(!spin_trylock(&global_irq_lock)); - } - wait_on_irq(cpu, where); - global_irq_holder = cpu; - previous_irqholder = where; -} - -void __global_cli(void) -{ - int cpu = smp_processor_id(); - unsigned long where; - - __asm__ __volatile__("mov %%i7, %0\n\t" : "=r" (where)); - __cli(); - get_irqlock(cpu, where); -} - -void __global_sti(void) -{ - release_irqlock(smp_processor_id()); - __sti(); -} - -/* Yes, I know this is broken, but for the time being... - * - * On Sparc we must differentiate between real local processor - * interrupts being disabled and global interrupt locking, this - * is so that interrupt handlers which call this stuff don't get - * interrupts turned back on when restore_flags() runs because - * our current drivers will be very surprised about this, yes I - * know they need to be fixed... -DaveM - */ -unsigned long __global_save_flags(void) -{ - unsigned long flags, retval = 0; - - __save_flags(flags); - if(global_irq_holder == (unsigned char) smp_processor_id()) - retval |= 1; - if(flags & PSR_PIL) - retval |= 2; - return retval; -} - -void __global_restore_flags(unsigned long flags) -{ - if(flags & 1) { - __global_cli(); - } else { - release_irqlock(smp_processor_id()); - - if(flags & 2) - __cli(); - else - __sti(); - } -} - -#undef INIT_STUCK -#define INIT_STUCK 200000000 - -#undef STUCK -#define STUCK \ -if (!--stuck) { \ - printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n", \ - irq, cpu, global_irq_holder); \ - stuck = INIT_STUCK; \ -} - -static void irq_enter(int cpu, int irq) -{ - extern void smp_irq_rotate(int cpu); - int stuck = INIT_STUCK; - -#ifdef __SMP_PROF__ - int_count[cpu][irq]++; -#endif - - smp_irq_rotate(cpu); - hardirq_enter(cpu); - while(global_irq_lock) { - if((unsigned char) cpu == global_irq_holder) { - printk("YEEEE Local interrupts enabled, global disabled\n"); - break; - } - STUCK; - barrier(); - } -} - -static void irq_exit(int cpu, int irq) -{ - __cli(); - hardirq_exit(cpu); - release_irqlock(cpu); -} - -#else /* !__SMP__ */ - -#define irq_enter(cpu, irq) (local_irq_count[cpu]++) -#define irq_exit(cpu, irq) (local_irq_count[cpu]--) - #endif /* __SMP__ */ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs) @@ -517,8 +361,16 @@ void handler_irq(int irq, struct pt_regs * regs) struct irqaction * action; unsigned int cpu_irq = irq & NR_IRQS; int cpu = smp_processor_id(); +#ifdef __SMP__ + extern void smp_irq_rotate(int cpu); +#endif disable_pil_irq(cpu_irq); +#ifdef __SMP__ + /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */ + if(irq < 10) + smp_irq_rotate(cpu); +#endif irq_enter(cpu, cpu_irq); action = *(cpu_irq + irq_action); kstat.interrupts[cpu_irq]++; @@ -543,7 +395,7 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) irq_enter(cpu, irq); floppy_interrupt(irq, dev_id, regs); irq_exit(cpu, irq); - disable_pil_irq(irq); + enable_pil_irq(irq); } #endif @@ -707,12 +559,12 @@ int request_irq(unsigned int irq, */ unsigned long probe_irq_on(void) { - return 0; + return 0; } int probe_irq_off(unsigned long mask) { - return 0; + return 0; } /* djhr diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 9a6ea3d6c..645aafb35 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.55 1997/04/17 03:28:56 davem Exp $ +/* $Id: sparc_ksyms.c,v 1.56 1997/04/18 05:44:35 davem Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -91,6 +91,14 @@ EXPORT_SYMBOL_PRIVATE(_rw_read_enter); EXPORT_SYMBOL_PRIVATE(_rw_read_exit); EXPORT_SYMBOL_PRIVATE(_rw_write_enter); EXPORT_SYMBOL(__sparc_bh_counter); +#ifdef __SMP__ +EXPORT_SYMBOL_PRIVATE(_irq_enter); +EXPORT_SYMBOL_PRIVATE(_irq_exit); +EXPORT_SYMBOL_PRIVATE(_global_restore_flags); +EXPORT_SYMBOL_PRIVATE(_global_sti); +EXPORT_SYMBOL_PRIVATE(_global_cli); +#endif + EXPORT_SYMBOL(page_offset); EXPORT_SYMBOL(stack_top); @@ -113,10 +121,6 @@ EXPORT_SYMBOL(global_irq_holder); EXPORT_SYMBOL(global_irq_lock); EXPORT_SYMBOL(global_bh_lock); EXPORT_SYMBOL(global_irq_count); -EXPORT_SYMBOL(__global_cli); -EXPORT_SYMBOL(__global_sti); -EXPORT_SYMBOL(__global_save_flags); -EXPORT_SYMBOL(__global_restore_flags); EXPORT_SYMBOL(synchronize_irq); #endif diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 6c68ccc5e..61b41056b 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.59 1997/02/14 03:12:54 davem Exp $ +/* $Id: systbls.S,v 1.60 1997/04/19 08:52:15 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -113,7 +113,7 @@ C_LABEL(sys_call_table): .long C_LABEL(sys_sched_rr_get_interval), C_LABEL(sys_nanosleep) /*250*/ .long C_LABEL(sys_mremap) .long C_LABEL(sys_sysctl) - .long C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nis_syscall) + .long C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nfsservctl) .long C_LABEL(sys_aplib), C_LABEL(sys_nis_syscall) /* Now the SunOS syscall table. */ diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 526dd0f28..77401391e 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.28 1997/04/15 09:01:10 davem Exp $ +/* $Id: time.c,v 1.29 1997/04/18 09:48:44 davem Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -308,11 +308,11 @@ void do_gettimeofday(struct timeval *tv) xor %o5, %o3, %o3 orcc %o2, %o3, %g0 bne 1b - subcc %o1, 0x0, %g0 - bpos 1f + cmp %o1, 0 + bge 1f srl %o1, 0xa, %o1 - sethi %hi(0x2710), %o3 - or %o3, %lo(0x2710), %o3 + sethi %hi(tick), %o3 + ld [%o3 + %lo(tick)], %o3 sethi %hi(0x1fffff), %o2 or %o2, %lo(0x1fffff), %o2 add %o5, %o3, %o5 diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index a7a67b8b2..1bf49bf13 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.22 1997/03/14 21:04:17 jj Exp $ +# $Id: Makefile,v 1.23 1997/04/18 05:44:39 davem Exp $ # Makefile for Sparc library files.. # @@ -9,6 +9,10 @@ OBJS = mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \ strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \ copy_user.o locks.o atomic.o bitops.o +ifdef SMP +OBJS += irqlock.o +endif + lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) sync @@ -54,6 +58,9 @@ atomic.o: atomic.S bitops.o: bitops.S $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o bitops.o bitops.S +irqlock.o: irqlock.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o irqlock.o irqlock.S + else locks.o: locks.S diff --git a/arch/sparc/lib/checksum.S b/arch/sparc/lib/checksum.S index 90362edc5..2f0c78168 100644 --- a/arch/sparc/lib/checksum.S +++ b/arch/sparc/lib/checksum.S @@ -471,8 +471,6 @@ ccslow: cmp %g1, 0 addx %g0, %g7, %o0 C_LABEL(__csum_partial_copy_end): - .section .fixup,#alloc,#execinstr - .align 4 /* We do these strange calculations for the csum_*_from_user case only, ie. * we only bother with faults on loads... */ @@ -568,6 +566,7 @@ C_LABEL(__csum_partial_copy_end): add %i1, %i2, %i1 2: mov %i1, %o0 +6: call C_LABEL(__bzero) mov %i3, %o1 1: @@ -579,3 +578,4 @@ C_LABEL(__csum_partial_copy_end): .section __ex_table,#alloc .align 4 .word 5b,2 + .word 6b,2 diff --git a/arch/sparc/lib/irqlock.S b/arch/sparc/lib/irqlock.S new file mode 100644 index 000000000..db7dd26c3 --- /dev/null +++ b/arch/sparc/lib/irqlock.S @@ -0,0 +1,185 @@ +/* $Id: irqlock.S,v 1.2 1997/04/19 04:33:37 davem Exp $ + * irqlock.S: High performance IRQ global locking and interrupt entry. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include + + .text + .align 4 + + /* This is incredibly insane... */ + .globl ___irq_enter +___irq_enter: + sethi %hi(local_irq_count), %g2 + sll %g1, 2, %g1 + or %g2, %lo(local_irq_count), %g2 + ld [%g2 + %g1], %g3 + sethi %hi(global_irq_count), %g5 + add %g3, 1, %g3 + or %g5, %lo(global_irq_count), %g5 + st %g3, [%g2 + %g1] +1: + ldstub [%g5 + 3], %g2 + orcc %g2, 0x0, %g0 + bne 1b + ld [%g5], %g3 + sra %g3, 8, %g3 + add %g3, 1, %g3 + sll %g3, 8, %g3 + st %g3, [%g5] + sethi %hi(global_irq_lock), %g1 + ldub [%g1 + %lo(global_irq_lock)], %g2 +1: + orcc %g2, 0x0, %g0 + bne,a 1b + ldub [%g1 + %lo(global_irq_lock)], %g2 +___irq_enter_out: + jmpl %o7, %g0 + mov %g4, %o7 + + .globl ___irq_exit +___irq_exit: + rd %psr, %g3 + sethi %hi(global_irq_count), %g1 + or %g3, PSR_PIL, %g3 + or %g1, %lo(global_irq_count), %g1 + wr %g3, 0x0, %psr + sethi %hi(local_irq_count), %g2 + sll %g7, 2, %g7 + or %g2, %lo(local_irq_count), %g2 + ld [%g2 + %g7], %g3 +1: + ldstub [%g1 + 3], %g5 + orcc %g5, 0x0, %g0 + bne 1b + ld [%g1], %g5 + sra %g5, 8, %g5 + sub %g5, 1, %g5 + sll %g5, 8, %g5 + st %g5, [%g1] + sub %g3, 1, %g3 + sethi %hi(global_irq_holder), %g1 + st %g3, [%g2 + %g7] + srl %g7, 2, %g7 + ldub [%g1 + %lo(global_irq_holder)], %g5 + cmp %g5, %g7 + bne ___irq_enter_out + mov NO_PROC_ID, %g2 + stb %g2, [%g1 + %lo(global_irq_holder)] + sethi %hi(global_irq_lock), %g5 + b ___irq_enter_out + stb %g0, [%g5 + %lo(global_irq_lock)] + + /* Weird calling conventions... %g7=flags, %g4=%prev_o7 + * Very clever for the __global_sti case, the inline which + * gets us here clears %g7 and it just works. + */ + .globl ___global_restore_flags, ___global_sti, ___global_cli +___global_restore_flags: + bne,a ___global_cli + rd %tbr, %g7 + rd %tbr, %g2 + +___global_sti: + sethi %hi(global_irq_holder), %g1 + sethi %hi(global_irq_lock), %g3 + srl %g2, 12, %g2 + ldub [%g1 + %lo(global_irq_holder)], %g5 + and %g2, 3, %g2 + cmp %g5, %g2 + bne 1f + mov NO_PROC_ID, %g5 + stb %g5, [%g1 + %lo(global_irq_holder)] + stb %g0, [%g3 + %lo(global_irq_lock)] +1: + rd %psr, %g3 + andcc %g7, 2, %g0 + bne,a 1f + or %g3, PSR_PIL, %g3 + andn %g3, PSR_PIL, %g3 +1: + wr %g3, 0x0, %psr + nop +__global_cli_out: ! All togther now... "fuuunnnnn" + retl + mov %g4, %o7 + +__spin_on_global_irq_lock: + orcc %g2, 0x0, %g0 + bne,a __spin_on_global_irq_lock + ldub [%g1], %g2 + b,a 1f + + /* This is a royal pain in the ass to make fast... 8-( */ +___global_cli: + sethi %hi(global_irq_lock), %g5 + srl %g7, 12, %g7 + sethi %hi(global_irq_holder), %g3 + and %g7, 3, %g7 + ldub [%g3 + %lo(global_irq_holder)], %g1 + rd %psr, %g2 + cmp %g1, %g7 + or %g2, PSR_PIL, %g2 + be __global_cli_out + wr %g2, 0x0, %psr ! XXX some sparcs may choke on this... + sethi %hi(local_irq_count), %g3 + or %g3, %lo(local_irq_count), %g3 + or %g5, %lo(global_irq_lock), %g1 +1: + ldstub [%g1], %g2 + orcc %g2, 0x0, %g0 + bne,a __spin_on_global_irq_lock + ldub [%g1], %g2 +__wait_on_irq: + sll %g7, 2, %g7 + ld [%g3 + %g7], %g2 + sethi %hi(global_irq_count), %g1 + or %g1, %lo(global_irq_count), %g1 + srl %g7, 2, %g7 + ld [%g1], %g5 + sra %g5, 8, %g5 +__wait_on_irq_loop: + cmp %g5, %g2 + sethi %hi(global_irq_holder), %g3 + be,a __global_cli_out ! Mamamia, Mamamia, this is the fast path + stb %g7, [%g3 + %lo(global_irq_holder)] +1: + ldstub [%g1 + 3], %g3 + orcc %g3, 0x0, %g0 + bne 1b + ld [%g1], %g3 + sra %g3, 8, %g3 + sub %g3, %g2, %g3 + sll %g3, 8, %g3 + st %g3, [%g1] + sethi %hi(global_irq_lock), %g3 + stb %g0, [%g3 + %lo(global_irq_lock)] +0: + ld [%g1], %g5 +9: + ldub [%g3 + %lo(global_irq_lock)], %g3 + sra %g5, 8, %g5 + orcc %g3, %g5, %g0 + bne 0b + sethi %hi(global_irq_lock), %g3 + ldstub [%g3 + %lo(global_irq_lock)], %g5 + orcc %g5, 0x0, %g0 + bne,a 9b + ld [%g1], %g5 +1: + ldstub [%g1 + 3], %g3 + orcc %g3, 0x0, %g0 + bne 1b + ld [%g1], %g3 + sra %g3, 8, %g3 + add %g3, %g2, %g5 + sll %g5, 8, %g3 + b __wait_on_irq_loop + st %g3, [%g1] + +#if 0 /* XXX I'm not delirious enough to debug this yet. */ + add %o7, (8 + (__wait_on_irq_loop - . - 4)), %o7 ! AIEEEEE +#endif diff --git a/arch/sparc/lib/locks.S b/arch/sparc/lib/locks.S index 79667533f..e91efdc09 100644 --- a/arch/sparc/lib/locks.S +++ b/arch/sparc/lib/locks.S @@ -1,4 +1,4 @@ -/* $Id: locks.S,v 1.11 1997/04/17 03:29:03 davem Exp $ +/* $Id: locks.S,v 1.12 1997/04/22 18:48:07 davem Exp $ * locks.S: SMP low-level lock primitives on Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 1d778e3fd..4ae57f18f 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.23 1997/03/10 09:16:52 davem Exp $ +# $Id: Makefile,v 1.24 1997/04/20 14:11:49 ecd Exp $ # Makefile for the linux Sparc-specific parts of the memory manager. # # Note! Dependencies are done automagically by 'make dep', which also @@ -8,10 +8,13 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := mm.o -O_OBJS := fault.o init.o sun4c.o srmmu.o hypersparc.o loadmmu.o \ - generic.o asyncd.o extable.o +O_OBJS := fault.o init.o sun4c.o srmmu.o hypersparc.o viking.o \ + loadmmu.o generic.o asyncd.o extable.o include $(TOPDIR)/Rules.make hypersparc.o: hypersparc.S $(CC) -D__ASSEMBLY__ -ansi -c -o hypersparc.o hypersparc.S + +viking.o: viking.S + $(CC) -D__ASSEMBLY__ -ansi -c -o viking.o viking.S diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S index fe7dfdf4f..4e5a19301 100644 --- a/arch/sparc/mm/hypersparc.S +++ b/arch/sparc/mm/hypersparc.S @@ -1,4 +1,4 @@ -/* $Id: hypersparc.S,v 1.3 1997/04/13 06:38:13 davem Exp $ +/* $Id: hypersparc.S,v 1.4 1997/04/19 04:33:39 davem Exp $ * hypersparc.S: High speed Hypersparc mmu/cache operations. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -271,10 +271,15 @@ hypersparc_flush_page_for_dma: retl nop + /* It was noted that at boot time a TLB flush all in a delay slot + * can deliver an illegal instruction to the processor if the timing + * is just right... + */ hypersparc_flush_tlb_all: mov 0x400, %g1 + sta %g0, [%g1] ASI_M_FLUSH_PROBE retl - sta %g0, [%g1] ASI_M_FLUSH_PROBE + nop hypersparc_flush_tlb_mm: mov SRMMU_CTX_REG, %g1 diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index d94b1c44a..3dd0e470f 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.48 1997/04/12 04:28:37 davem Exp $ +/* $Id: init.c,v 1.49 1997/04/17 21:49:31 jj Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -34,6 +34,9 @@ extern void show_net_buffers(void); struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; unsigned long sparc_unmapped_base; +/* References to section boundaries */ +extern char __init_begin, __init_end, etext; + /* * BAD_PAGE is the page that is used for page faults when linux * is out-of-memory. Older versions of linux just did a @@ -208,8 +211,8 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) { int codepages = 0; int datapages = 0; + int initpages = 0; unsigned long tmp2, addr; - extern char etext; /* Saves us work later. */ memset((void *) ZERO_PAGE, 0, PAGE_SIZE); @@ -237,7 +240,9 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) if(PageReserved(mem_map + MAP_NR(addr))) { if ((addr < (unsigned long) &etext) && (addr >= KERNBASE)) codepages++; - else if((addr < start_mem) && (addr >= KERNBASE)) + else if((addr >= (unsigned long)&__init_begin && addr < (unsigned long)&__init_end)) + initpages++; + else if((addr < start_mem) && (addr >= KERNBASE)) datapages++; continue; } @@ -252,10 +257,12 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) tmp2 = nr_free_pages << PAGE_SHIFT; - printk("Memory: %luk available (%dk kernel code, %dk data) [%08lx,%08lx]\n", + printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]\n", tmp2 >> 10, codepages << (PAGE_SHIFT-10), - datapages << (PAGE_SHIFT-10), PAGE_OFFSET, end_mem); + datapages << (PAGE_SHIFT-10), + initpages << (PAGE_SHIFT-10), + PAGE_OFFSET, end_mem); min_free_pages = nr_free_pages >> 7; if(min_free_pages < 16) @@ -266,7 +273,6 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) void free_initmem (void) { - extern char __init_begin, __init_end; unsigned long addr; addr = (unsigned long)(&__init_begin); @@ -275,7 +281,6 @@ void free_initmem (void) atomic_set(&mem_map[MAP_NR(addr)].count, 1); free_page(addr); } - printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 7f4824222..9d3afdbdf 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.135 1997/04/14 05:38:49 davem Exp $ +/* $Id: srmmu.c,v 1.136 1997/04/20 14:11:51 ecd Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -74,7 +74,10 @@ static char *srmmu_name; ctxd_t *srmmu_ctx_table_phys; ctxd_t *srmmu_context_table; -static struct srmmu_trans { +/* Don't change this without changing access to this + * in arch/sparc/mm/viking.S + */ +struct srmmu_trans { unsigned long vbase; unsigned long pbase; unsigned long size; @@ -705,7 +708,7 @@ static void srmmu_set_pte_nocache_cypress(pte_t *ptep, pte_t pteval) } while(line != page); } -static void srmmu_set_pte_nocache_nomxccvik(pte_t *ptep, pte_t pteval) +static void srmmu_set_pte_nocache_viking(pte_t *ptep, pte_t pteval) { unsigned long vaddr; int set; @@ -1083,255 +1086,6 @@ static void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) * with respect to cache coherency. */ -/* Viking flushes. For Sun's mainline MBUS processor it is pretty much - * a crappy mmu. The on-chip I&D caches only have full flushes, no fine - * grained cache invalidations. It only has these "flash clear" things - * just like the MicroSparcI. Added to this many revs of the chip are - * teaming with hardware buggery. Someday maybe we'll do direct - * diagnostic tag accesses for page level flushes as those should - * be painless and will increase performance due to the frequency of - * page level flushes. This is a must to _really_ flush the caches, - * crazy hardware ;-) - */ - -static void viking_flush_cache_all(void) -{ -} - -static void viking_flush_cache_mm(struct mm_struct *mm) -{ -} - -static void viking_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) -{ -} - -static void viking_flush_cache_page(struct vm_area_struct *vma, unsigned long page) -{ -} - -/* Non-mxcc vikings are copy-back but are pure-physical so no flushing. */ -static void viking_flush_page_to_ram(unsigned long page) -{ -} - -static void viking_mxcc_flush_chunk(unsigned long chunk) -{ -} - -/* All vikings have an icache which snoops the processor bus and is fully - * coherent with the dcache, so no flush is necessary at all. - */ -static void viking_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) -{ -} - -static void viking_mxcc_flush_page(unsigned long page) -{ - unsigned long ppage = srmmu_v2p(page & PAGE_MASK); - unsigned long paddr0, paddr1; - - if (ppage == 0xffffffffUL) - return; - - paddr0 = 0x10; /* Set cacheable bit. */ - paddr1 = ppage; - - /* Read the page's data through the stream registers, - * and write it back to memory. This will issue - * coherent write invalidates to all other caches, thus - * should also be sufficient in an MP system. - */ - __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t" - "or %%g0, %1, %%g3\n" - "1:\n\t" - "stda %%g2, [%2] %5\n\t" - "stda %%g2, [%3] %5\n\t" - "add %%g3, %4, %%g3\n\t" - "btst 0xfff, %%g3\n\t" - "bne 1b\n\t" - "nop\n\t" : : - "r" (paddr0), "r" (paddr1), - "r" (MXCC_SRCSTREAM), - "r" (MXCC_DESSTREAM), - "r" (MXCC_STREAM_SIZE), - "i" (ASI_M_MXCC) : "g2", "g3", "cc"); - - /* This was handcoded after a look at the gcc output from - * - * do { - * mxcc_set_stream_src(paddr); - * mxcc_set_stream_dst(paddr); - * paddr[1] += MXCC_STREAM_SIZE; - * } while (paddr[1] & ~PAGE_MASK); - */ -} - -static void viking_no_mxcc_flush_page(unsigned long page) -{ - unsigned long ppage = srmmu_v2p(page & PAGE_MASK); - int set, block; - unsigned long ptag[2]; - unsigned long vaddr; - int i; - - if (ppage == 0xffffffffUL) - return; - ppage >>= 12; - - for (set = 0; set < 128; set++) { - for (block = 0; block < 4; block++) { - - viking_get_dcache_ptag(set, block, ptag); - - if (ptag[1] != ppage) - continue; - if (!(ptag[0] & VIKING_PTAG_VALID)) - continue; - if (!(ptag[0] & VIKING_PTAG_DIRTY)) - continue; - - /* There was a great cache from TI - * with comfort as much as vi, - * 4 pages to flush, - * 4 pages, no rush, - * since anything else makes him die. - */ - vaddr = (KERNBASE + PAGE_SIZE) | (set << 5); - for (i = 0; i < 8; i++) { - __asm__ __volatile__ ("ld [%0], %%g2\n\t" : : - "r" (vaddr) : "g2"); - vaddr += PAGE_SIZE; - } - - /* Continue with next set. */ - break; - } - } -} - -static void viking_nomxcc_flush_chunk(unsigned long chunk) -{ - viking_no_mxcc_flush_page(chunk); -} - -/* Viking is IO cache coherent, but really only on MXCC. */ -static void viking_flush_page_for_dma(unsigned long page) -{ -} - -static void viking_flush_tlb_all(void) -{ - register int ctr asm("g5"); - - ctr = 0; - __asm__ __volatile__(" - 1: ld [%%g6 + %2], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp - 2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0" - : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc"); - srmmu_flush_whole_tlb(); - module_stats.invall++; -} - -static void viking_flush_tlb_mm(struct mm_struct *mm) -{ - register int ctr asm("g5"); - - FLUSH_BEGIN(mm) - ctr = 0; - __asm__ __volatile__(" -1: ld [%%g6 + %7], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp -2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0 - lda [%1] %4, %0 - sta %3, [%1] %4 - sta %%g0, [%2] %5 - sta %0, [%1] %4" - : "=&r" (ctr) - : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context), - "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE), "0" (ctr), - "i" (UWINMASK_OFFSET) - : "g4", "cc"); - module_stats.invmm++; - FLUSH_END -} - -static void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) -{ - register int ctr asm("g5"); - unsigned long size; - - FLUSH_BEGIN(mm) - ctr = 0; - __asm__ __volatile__(" - 1: ld [%%g6 + %2], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp - 2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0" - : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc"); - start &= SRMMU_PGDIR_MASK; - size = SRMMU_PGDIR_ALIGN(end) - start; - __asm__ __volatile__(" - lda [%0] %5, %%g5 - sta %1, [%0] %5 - 1: subcc %3, %4, %3 - bne 1b - sta %%g0, [%2 + %3] %6 - sta %%g5, [%0] %5" - : /* no outputs */ - : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (start | 0x200), - "r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS), - "i" (ASI_M_FLUSH_PROBE) - : "g5", "cc"); - module_stats.invrnge++; - FLUSH_END -} - -static void viking_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - register int ctr asm("g5"); - - FLUSH_BEGIN(mm) - ctr = 0; - __asm__ __volatile__(" - 1: ld [%%g6 + %2], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp - 2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0" - : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc"); - __asm__ __volatile__(" - lda [%0] %3, %%g5 - sta %1, [%0] %3 - sta %%g0, [%2] %4 - sta %%g5, [%0] %3" - : /* no outputs */ - : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK), - "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE) - : "g5"); - module_stats.invpg++; - FLUSH_END -} - /* Cypress flushes. */ static void cypress_flush_cache_all(void) { @@ -1576,6 +1330,27 @@ static void cypress_flush_tlb_page(struct vm_area_struct *vma, unsigned long pag FLUSH_END } +/* viking.S */ +extern void viking_flush_cache_all(void); +extern void viking_flush_cache_mm(struct mm_struct *mm); +extern void viking_flush_cache_range(struct mm_struct *mm, unsigned long start, + unsigned long end); +extern void viking_flush_cache_page(struct vm_area_struct *vma, + unsigned long page); +extern void viking_flush_page_to_ram(unsigned long page); +extern void viking_flush_page_for_dma(unsigned long page); +extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr); +extern void viking_flush_page(unsigned long page); +extern void viking_mxcc_flush_page(unsigned long page); +extern void viking_flush_chunk(unsigned long chunk); +extern void viking_mxcc_flush_chunk(unsigned long chunk); +extern void viking_flush_tlb_all(void); +extern void viking_flush_tlb_mm(struct mm_struct *mm); +extern void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end); +extern void viking_flush_tlb_page(struct vm_area_struct *vma, + unsigned long page); + /* hypersparc.S */ extern void hypersparc_flush_cache_all(void); extern void hypersparc_flush_cache_mm(struct mm_struct *mm); @@ -1608,9 +1383,9 @@ static void hypersparc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) } } -static void viking_no_mxcc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) +static void viking_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) { - viking_no_mxcc_flush_page((unsigned long)pgdp); + viking_flush_page((unsigned long)pgdp); if(tsk->mm->context != NO_CONTEXT) { flush_cache_mm(current->mm); ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp); @@ -1768,11 +1543,11 @@ unsigned long iommu_init(int iommund, unsigned long memory_start, viking_mxcc_flush_page(start); start += PAGE_SIZE; } - } else if(flush_page_for_dma == viking_no_mxcc_flush_page) { + } else if(flush_page_for_dma == viking_flush_page) { unsigned long start = (unsigned long) iommu->page_table; unsigned long end = (start + ptsize); while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -1809,11 +1584,11 @@ void iommu_sun4d_init(int sbi_node, struct linux_sbus *sbus) viking_mxcc_flush_page(start); start += PAGE_SIZE; } - } else if(flush_page_for_dma == viking_no_mxcc_flush_page) { + } else if(flush_page_for_dma == viking_flush_page) { unsigned long start = (unsigned long) iommu; unsigned long end = (start + 16 * PAGE_SIZE); while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -2029,11 +1804,11 @@ static void srmmu_map_dma_area(unsigned long addr, int len) viking_mxcc_flush_page(start); start += PAGE_SIZE; } - } else if(flush_page_for_dma == viking_no_mxcc_flush_page) { + } else if(flush_page_for_dma == viking_flush_page) { unsigned long start = ((unsigned long) iopte_first) & PAGE_MASK; unsigned long end = PAGE_ALIGN(((unsigned long) iopte)); while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -2449,12 +2224,12 @@ unsigned long srmmu_paging_init(unsigned long start_mem, unsigned long end_mem) start_mem = PAGE_ALIGN(mempool); flush_cache_all(); - if(flush_page_for_dma == viking_no_mxcc_flush_page) { + if(flush_page_for_dma == viking_flush_page) { unsigned long start = ptables_start; unsigned long end = start_mem; while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -2999,10 +2774,10 @@ __initfunc(static void init_viking(void)) msi_set_sync(); - set_pte = srmmu_set_pte_nocache_nomxccvik; - sparc_update_rootmmu_dir = viking_no_mxcc_update_rootmmu_dir; + set_pte = srmmu_set_pte_nocache_viking; + sparc_update_rootmmu_dir = viking_update_rootmmu_dir; - flush_chunk = viking_nomxcc_flush_chunk; /* local flush _only_ */ + flush_chunk = viking_flush_chunk; /* local flush _only_ */ /* We need this to make sure old viking takes no hits * on it's cache for dma snoops to workaround the @@ -3010,7 +2785,7 @@ __initfunc(static void init_viking(void)) * This is only necessary because of the new way in * which we use the IOMMU. */ - flush_page_for_dma = viking_no_mxcc_flush_page; + flush_page_for_dma = viking_flush_page; } else { srmmu_name = "TI Viking/MXCC"; viking_mxcc_present = 1; diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S new file mode 100644 index 000000000..f61aa4398 --- /dev/null +++ b/arch/sparc/mm/viking.S @@ -0,0 +1,267 @@ +/* $Id: viking.S,v 1.2 1997/04/20 21:21:49 ecd Exp $ + * viking.S: High speed Viking cache/mmu operations + * + * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define WINDOW_FLUSH(tmp1, tmp2) \ + mov 0, tmp1; \ +98: ld [%g6 + AOFF_task_tss + AOFF_thread_uwinmask], tmp2; \ + orcc %g0, tmp2, %g0; \ + add tmp1, 1, tmp1; \ + bne 98b; \ + save %sp, -64, %sp; \ +99: subcc tmp1, 1, tmp1; \ + bne 99b; \ + restore %g0, %g0, %g0; + + .text + .align 4 + + .globl viking_flush_cache_all, viking_flush_cache_mm + .globl viking_flush_cache_range, viking_flush_cache_page + .globl viking_flush_page, viking_mxcc_flush_page + .globl viking_flush_page_for_dma, viking_flush_page_to_ram + .globl viking_flush_chunk, viking_mxcc_flush_chunk + .globl viking_flush_sig_insns + .globl viking_flush_tlb_all, viking_flush_tlb_mm + .globl viking_flush_tlb_range, viking_flush_tlb_page + +viking_flush_page: +viking_flush_chunk: + sethi %hi(C_LABEL(srmmu_map)), %g2 + or %g2, %lo(C_LABEL(srmmu_map)), %g3 + ld [%g3 + 8], %g2 + cmp %g2, 0 + be 3f + and %o0, PAGE_MASK, %o0 + + ld [%g3], %o1 +1: + cmp %o1, %o0 + bgu,a 2f + add %g3, 0xc, %g3 + + add %o1, %g2, %g2 + cmp %g2, %o0 + bleu,a 2f + add %g3, 0xc, %g3 + + sub %o0, %o1, %g2 + ld [%g3 + 4], %o0 + add %g2, %o0, %g3 + b 4f + srl %g3, 12, %g1 ! ppage >> 12 + +2: + ld [%g3 + 8], %g2 + cmp %g2, 0 + bne,a 1b + ld [%g3], %o1 +3: + retl + nop + +4: + clr %o1 ! set counter, 0 - 127 + sethi %hi(KERNBASE + PAGE_SIZE - 0x80000000), %o3 + sethi %hi(0x80000000), %o4 + sethi %hi(VIKING_PTAG_VALID | VIKING_PTAG_DIRTY), %o5 + sethi %hi(PAGE_SIZE), %o0 + clr %o2 ! block counter, 0 - 3 +5: + sll %o1, 5, %g4 + or %g4, %o4, %g4 ! 0x80000000 | (set << 5) + + sll %o2, 26, %g5 ! block << 26 +6: + or %g5, %g4, %g5 + ldda [%g5] ASI_M_DATAC_TAG, %g2 + cmp %g3, %g1 ! ptag == ppage? + bne,a 7f + inc %o2 + + and %g2, %o5, %g3 ! ptag VALID and DIRTY? + cmp %g3, %o5 + bne,a 7f + inc %o2 + + add %g4, %o3, %g2 ! (KERNBASE + PAGE_SIZE) | (set << 5) + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + + b 8f + inc %o1 + +7: + cmp %o2, 3 + ble 6b + sll %o2, 26, %g5 ! block << 26 + + inc %o1 +8: + cmp %o1, 0x7f + ble 5b + clr %o2 + + retl + nop + + +viking_mxcc_flush_page: + sethi %hi(C_LABEL(srmmu_map)), %g2 + or %g2, %lo(C_LABEL(srmmu_map)), %g3 + ld [%g3 + 8], %g2 + cmp %g2, 0 + be 3f + and %o0, PAGE_MASK, %o0 + + ld [%g3], %o1 +1: + cmp %o1, %o0 + bgu,a 2f + add %g3, 0xc, %g3 + + add %o1, %g2, %g2 + cmp %g2, %o0 + bleu,a 2f + add %g3, 0xc, %g3 + + sub %o0, %o1, %g2 + ld [%g3 + 4], %o0 + add %g2, %o0, %g3 + sethi %hi(PAGE_SIZE), %g4 + b 4f + add %g3, %g4, %g3 ! ppage + PAGE_SIZE + +2: + ld [%g3 + 8], %g2 + cmp %g2, 0 + bne,a 1b + ld [%g3], %o1 +3: + retl + nop +4: + mov 0x10, %g2 ! set cacheable bit + sethi %hi(MXCC_SRCSTREAM), %o2 + or %o2, %lo(MXCC_SRCSTREAM), %o2 + sethi %hi(MXCC_DESSTREAM), %o3 + or %o3, %lo(MXCC_DESSTREAM), %o3 + +5: + sub %g3, MXCC_STREAM_SIZE, %g3 +6: + stda %g2, [%o2] ASI_M_MXCC + stda %g2, [%o3] ASI_M_MXCC + andncc %g3, PAGE_MASK, %g0 + bne 6b + sub %g3, MXCC_STREAM_SIZE, %g3 + + retl + nop + +viking_mxcc_flush_chunk: + retl + nop + +viking_flush_cache_all: +viking_flush_cache_mm: +viking_flush_cache_range: +viking_flush_cache_page: + retl + nop + +viking_flush_tlb_all: + WINDOW_FLUSH(%g4, %g5) + mov 0x400, %g1 + retl + sta %g0, [%g1] ASI_M_FLUSH_PROBE + +viking_flush_tlb_mm: + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o1 + lda [%g1] ASI_M_MMUREGS, %g5 +#ifndef __SMP__ + cmp %o1, -1 + be viking_flush_tlb_mm_out +#endif + WINDOW_FLUSH(%g2, %g3) + + mov 0x300, %g2 + sta %o1, [%g1] ASI_M_MMUREGS + sta %g0, [%g2] ASI_M_FLUSH_PROBE +viking_flush_tlb_mm_out: + retl + sta %g5, [%g1] ASI_M_MMUREGS + +viking_flush_tlb_range: + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +#ifndef __SMP__ + cmp %o3, -1 + be viking_flush_tlb_range_out +#endif + WINDOW_FLUSH(%g2, %g3) + + srl %o1, SRMMU_PGDIR_SHIFT, %o1 + sta %o3, [%g1] ASI_M_MMUREGS + sll %o1, SRMMU_PGDIR_SHIFT, %o1 + sethi %hi(1 << SRMMU_PGDIR_SHIFT), %o4 + add %o1, 0x200, %o1 + sta %g0, [%o1] ASI_M_FLUSH_PROBE +1: + add %o1, %o4, %o1 + cmp %o1, %o2 + blu,a 1b + sta %g0, [%o1] ASI_M_FLUSH_PROBE +viking_flush_tlb_range_out: + retl + sta %g5, [%g1] ASI_M_MMUREGS + +viking_flush_tlb_page: + ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + and %o1, PAGE_MASK, %o1 + lda [%g1] ASI_M_MMUREGS, %g5 +#ifndef __SMP__ + cmp %o3, -1 + be viking_flush_tlb_page_out +#endif + WINDOW_FLUSH(%g2, %g3) + + sta %o3, [%g1] ASI_M_MMUREGS + sta %g0, [%o1] ASI_M_FLUSH_PROBE +viking_flush_tlb_page_out: + retl + sta %g5, [%g1] ASI_M_MMUREGS + +viking_flush_page_to_ram: +viking_flush_page_for_dma: +viking_flush_sig_insns: + retl + nop diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index 42ed2db62..c8cdc0134 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.5 1997/04/10 17:06:08 jj Exp $ +# $Id: config.in,v 1.6 1997/04/17 20:35:42 jj Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -50,9 +50,12 @@ tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPE bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC bool 'Sysctl support' CONFIG_SYSCTL +bool 'Kernel support for Linux/Sparc 32bit binary compatibility' CONFIG_SPARC32_COMPAT tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF -tristate 'Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32 +if [ "$CONFIG_SPARC32_COMPAT" != "n" ]; then + tristate 'Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32 +fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA fi diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 87592dcbf..9ecbf90b4 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -50,6 +50,7 @@ TADPOLE_FB_WEITEK=y CONFIG_NET=y CONFIG_SYSVIPC=y CONFIG_SYSCTL=y +CONFIG_SPARC32_COMPAT=y CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_ELF32=y diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index d2ef7d6d8..d66fa06e7 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.15 1997/04/10 07:53:30 davem Exp $ +# $Id: Makefile,v 1.16 1997/04/17 20:35:37 jj Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -18,9 +18,13 @@ all: kernel.o head.o O_TARGET := kernel.o O_OBJS := etrap.o rtrap.o hack.o process.o setup.o cpu.o idprom.o \ systbls.o traps.o entry.o devices.o auxio.o ioport.o \ - irq.o time.o sys_sparc.o sys_sparc32.o signal32.o + irq.o time.o sys_sparc.o OX_OBJS := sparc64_ksyms.o +ifdef CONFIG_SPARC32_COMPAT + O_OBJS += sys_sparc32.o signal32.o +endif + ifdef CONFIG_BINFMT_ELF32 O_OBJS += sparcelf32.o endif diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 07d871724..e9911daed 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.6 1997/04/16 14:52:29 jj Exp $ +/* $Id: sys_sparc32.c,v 1.9 1997/04/21 08:34:24 jj Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include #include @@ -101,7 +104,6 @@ extern asmlinkage long sys_times(struct tms * tbuf); extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist); extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist); extern asmlinkage int sys_newuname(struct new_utsname * name); -extern asmlinkage int sys_uname(struct old_utsname * name); extern asmlinkage int sys_olduname(struct oldold_utsname * name); extern asmlinkage int sys_sethostname(char *name, int len); extern asmlinkage int sys_gethostname(char *name, int len); @@ -135,6 +137,7 @@ extern asmlinkage int sys_getsockopt(int fd, int level, int optname, char *optva extern asmlinkage int sys_sendmsg(int fd, struct msghdr *msg, unsigned flags); extern asmlinkage int sys_recvmsg(int fd, struct msghdr *msg, unsigned int flags); extern asmlinkage int sys_socketcall(int call, unsigned long *args); +extern asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp); asmlinkage int sys32_ioperm(u32 from, u32 num, int on) { @@ -668,53 +671,81 @@ asmlinkage long sys32_write(unsigned int fd, u32 buf, u32 count) return sys_write(fd, (const char *)A(buf), (unsigned long)count); } +struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; + asmlinkage long sys32_readv(u32 fd, u32 vector, u32 count) { - struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; struct iovec *v; + struct iovec vf[UIO_FASTIOV]; u32 i; long ret; unsigned long old_fs; if (!count) return 0; if (count > UIO_MAXIOV) return -EINVAL; - v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); if (!v) return -ENOMEM; + if (count <= UIO_FASTIOV) + v = vf; + else { + lock_kernel (); + v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); + if (!v) { + ret = -ENOMEM; + goto out; + } + } for (i = 0; i < count; i++) { if (__get_user ((unsigned long)(v[i].iov_base), &((((struct iovec32 *)A(vector))+i)->iov_base)) || __get_user (v[i].iov_len, &((((struct iovec32 *)A(vector))+i)->iov_len))) { - kfree (v); - return -EFAULT; + ret = -EFAULT; + goto out; } } old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_readv((unsigned long)fd, v, (unsigned long)count); set_fs (old_fs); - kfree (v); +out: + if (count > UIO_FASTIOV) { + kfree (v); + unlock_kernel (); + } return ret; } asmlinkage long sys32_writev(u32 fd, u32 vector, u32 count) { - struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; struct iovec *v; + struct iovec vf[UIO_FASTIOV]; u32 i; long ret; unsigned long old_fs; if (!count) return 0; if (count > UIO_MAXIOV) return -EINVAL; - v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); if (!v) return -ENOMEM; + if (count <= UIO_FASTIOV) + v = vf; + else { + lock_kernel (); + v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); + if (!v) { + ret = -ENOMEM; + goto out; + } + } for (i = 0; i < count; i++) { if (__get_user ((unsigned long)(v[i].iov_base), &((((struct iovec32 *)A(vector))+i)->iov_base)) || __get_user (v[i].iov_len, &((((struct iovec32 *)A(vector))+i)->iov_len))) { - kfree (v); - return -EFAULT; + ret = -EFAULT; + goto out; } } old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_writev((unsigned long)fd, v, (unsigned long)count); set_fs (old_fs); - kfree (v); +out: + if (count > UIO_FASTIOV) { + kfree (v); + unlock_kernel (); + } return ret; } @@ -991,9 +1022,9 @@ asmlinkage int sys32_sysfs(int option, ...) return ret; } -/* Continue here */ asmlinkage int sys32_ustat(dev_t dev, u32 ubuf) { + /* ustat is the same :)) */ return sys_ustat(dev, (struct ustat *)A(ubuf)); } @@ -1018,23 +1049,111 @@ asmlinkage int sys32_personality(u32 personality) return sys_personality((unsigned long)personality); } -asmlinkage int sys32_wait4(pid_t pid, u32 stat_addr, int options, u32 ru) -{ - return sys_wait4(pid, (unsigned int *)A(stat_addr), options, (struct rusage *)A(ru)); +struct rusage32 { + struct timeval ru_utime; + struct timeval ru_stime; + s32 ru_maxrss; + s32 ru_ixrss; + s32 ru_idrss; + s32 ru_isrss; + s32 ru_minflt; + s32 ru_majflt; + s32 ru_nswap; + s32 ru_inblock; + s32 ru_oublock; + s32 ru_msgsnd; + s32 ru_msgrcv; + s32 ru_nsignals; + s32 ru_nvcsw; + s32 ru_nivcsw; +}; + +static int put_rusage (u32 ru, struct rusage *r) +{ + if (put_user (r->ru_utime.tv_sec, &(((struct rusage32 *)A(ru))->ru_utime.tv_sec)) || + __put_user (r->ru_utime.tv_usec, &(((struct rusage32 *)A(ru))->ru_utime.tv_usec)) || + __put_user (r->ru_stime.tv_sec, &(((struct rusage32 *)A(ru))->ru_stime.tv_sec)) || + __put_user (r->ru_stime.tv_usec, &(((struct rusage32 *)A(ru))->ru_stime.tv_usec)) || + __put_user (r->ru_maxrss, &(((struct rusage32 *)A(ru))->ru_maxrss)) || + __put_user (r->ru_ixrss, &(((struct rusage32 *)A(ru))->ru_ixrss)) || + __put_user (r->ru_idrss, &(((struct rusage32 *)A(ru))->ru_idrss)) || + __put_user (r->ru_isrss, &(((struct rusage32 *)A(ru))->ru_isrss)) || + __put_user (r->ru_minflt, &(((struct rusage32 *)A(ru))->ru_minflt)) || + __put_user (r->ru_majflt, &(((struct rusage32 *)A(ru))->ru_majflt)) || + __put_user (r->ru_nswap, &(((struct rusage32 *)A(ru))->ru_nswap)) || + __put_user (r->ru_inblock, &(((struct rusage32 *)A(ru))->ru_inblock)) || + __put_user (r->ru_oublock, &(((struct rusage32 *)A(ru))->ru_oublock)) || + __put_user (r->ru_msgsnd, &(((struct rusage32 *)A(ru))->ru_msgsnd)) || + __put_user (r->ru_msgrcv, &(((struct rusage32 *)A(ru))->ru_msgrcv)) || + __put_user (r->ru_nsignals, &(((struct rusage32 *)A(ru))->ru_nsignals)) || + __put_user (r->ru_nvcsw, &(((struct rusage32 *)A(ru))->ru_nvcsw)) || + __put_user (r->ru_nivcsw, &(((struct rusage32 *)A(ru))->ru_nivcsw))) + return -EFAULT; + return 0; } -asmlinkage int sys32_waitpid(pid_t pid, u32 stat_addr, int options) +asmlinkage int sys32_wait4(__kernel_pid_t32 pid, u32 stat_addr, int options, u32 ru) +{ + if (!ru) + return sys_wait4(pid, (unsigned int *)A(stat_addr), options, NULL); + else { + struct rusage r; + int ret; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_wait4(pid, (unsigned int *)A(stat_addr), options, &r); + set_fs (old_fs); + if (put_rusage (ru, &r)) return -EFAULT; + return ret; + } +} + +asmlinkage int sys32_waitpid(__kernel_pid_t32 pid, u32 stat_addr, int options) { return sys_waitpid(pid, (unsigned int *)A(stat_addr), options); } +struct sysinfo32 { + s32 uptime; + u32 loads[3]; + u32 totalram; + u32 freeram; + u32 sharedram; + u32 bufferram; + u32 totalswap; + u32 freeswap; + unsigned short procs; + char _f[22]; +}; + asmlinkage int sys32_sysinfo(u32 info) { - return sys_sysinfo((struct sysinfo *)A(info)); + struct sysinfo s; + int ret; + unsigned long old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_sysinfo(&s); + set_fs (old_fs); + if (put_user (s.uptime, &(((struct sysinfo32 *)A(info))->uptime)) || + __put_user (s.loads[0], &(((struct sysinfo32 *)A(info))->loads[0])) || + __put_user (s.loads[1], &(((struct sysinfo32 *)A(info))->loads[1])) || + __put_user (s.loads[2], &(((struct sysinfo32 *)A(info))->loads[2])) || + __put_user (s.totalram, &(((struct sysinfo32 *)A(info))->totalram)) || + __put_user (s.freeram, &(((struct sysinfo32 *)A(info))->freeram)) || + __put_user (s.sharedram, &(((struct sysinfo32 *)A(info))->sharedram)) || + __put_user (s.bufferram, &(((struct sysinfo32 *)A(info))->bufferram)) || + __put_user (s.totalswap, &(((struct sysinfo32 *)A(info))->totalswap)) || + __put_user (s.freeswap, &(((struct sysinfo32 *)A(info))->freeswap)) || + __put_user (s.procs, &(((struct sysinfo32 *)A(info))->procs))) + return -EFAULT; + return ret; } asmlinkage int sys32_getitimer(int which, u32 value) { + /* itimerval is the same :)) */ return sys_getitimer(which, (struct itimerval *)A(value)); } @@ -1043,39 +1162,87 @@ asmlinkage int sys32_setitimer(int which, u32 value, u32 ovalue) return sys_setitimer(which, (struct itimerval *)A(value), (struct itimerval *)A(ovalue)); } -asmlinkage int sys32_sched_setscheduler(pid_t pid, int policy, u32 param) +asmlinkage int sys32_sched_setscheduler(__kernel_pid_t32 pid, int policy, u32 param) { + /* sched_param is the same :)) */ return sys_sched_setscheduler(pid, policy, (struct sched_param *)A(param)); } -asmlinkage int sys32_sched_setparam(pid_t pid, u32 param) +asmlinkage int sys32_sched_setparam(__kernel_pid_t32 pid, u32 param) { return sys_sched_setparam(pid, (struct sched_param *)A(param)); } -asmlinkage int sys32_sched_getparam(pid_t pid, u32 param) +asmlinkage int sys32_sched_getparam(__kernel_pid_t32 pid, u32 param) { return sys_sched_getparam(pid, (struct sched_param *)A(param)); } -asmlinkage int sys32_sched_rr_get_interval(pid_t pid, u32 interval) +struct timespec32 { + s32 tv_sec; + s32 tv_nsec; +}; + +asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, u32 interval) { - return sys_sched_rr_get_interval(pid, (struct timespec *)A(interval)); + struct timespec t; + int ret; + unsigned long old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_sched_rr_get_interval(pid, &t); + set_fs (old_fs); + if (put_user (t.tv_sec, &(((struct timespec32 *)A(interval))->tv_sec)) || + __put_user (t.tv_nsec, &(((struct timespec32 *)A(interval))->tv_nsec))) + return -EFAULT; + return ret; } asmlinkage int sys32_nanosleep(u32 rqtp, u32 rmtp) { - return sys_nanosleep((struct timespec *)A(rqtp), (struct timespec *)A(rmtp)); + struct timespec t; + int ret; + unsigned long old_fs = get_fs (); + + if (get_user (t.tv_sec, &(((struct timespec32 *)A(rqtp))->tv_sec)) || + __get_user (t.tv_nsec, &(((struct timespec32 *)A(rqtp))->tv_nsec))) + return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_nanosleep(&t, rmtp ? &t : NULL); + set_fs (old_fs); + if (rmtp && ret == -EINTR) { + if (__put_user (t.tv_sec, &(((struct timespec32 *)A(rmtp))->tv_sec)) || + __put_user (t.tv_nsec, &(((struct timespec32 *)A(rmtp))->tv_nsec))) + return -EFAULT; + } + return ret; } asmlinkage int sys32_sigprocmask(int how, u32 set, u32 oset) { - return sys_sigprocmask(how, (sigset_t *)A(set), (sigset_t *)A(oset)); + sigset_t s; + int ret; + unsigned long old_fs = get_fs(); + + if (set && get_user (s, (sigset_t32 *)A(set))) return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); + set_fs (old_fs); + if (oset && put_user (s, (sigset_t32 *)A(oset))) return -EFAULT; + return ret; } asmlinkage int sys32_sigpending(u32 set) { - return sys_sigpending((sigset_t *)A(set)); + sigset_t s; + int ret; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_sigpending(&s); + set_fs (old_fs); + if (put_user (s, (sigset_t32 *)A(set))) return -EFAULT; + return ret; } asmlinkage unsigned long sys32_signal(int signum, u32 handler) @@ -1095,34 +1262,84 @@ asmlinkage int sys32_acct(u32 name) asmlinkage int sys32_getresuid(u32 ruid, u32 euid, u32 suid) { - return sys_getresuid((uid_t *)A(ruid), (uid_t *)A(euid), (uid_t *)A(suid)); + uid_t a, b, c; + int ret; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_getresuid(&a, &b, &c); + set_fs (old_fs); + if (put_user (a, (__kernel_uid_t32 *)A(ruid)) || + put_user (b, (__kernel_uid_t32 *)A(euid)) || + put_user (c, (__kernel_uid_t32 *)A(suid))) + return -EFAULT; + return ret; } +struct tms32 { + __kernel_clock_t32 tms_utime; + __kernel_clock_t32 tms_stime; + __kernel_clock_t32 tms_cutime; + __kernel_clock_t32 tms_cstime; +}; + asmlinkage long sys32_times(u32 tbuf) { - return sys_times((struct tms *)A(tbuf)); + struct tms t; + long ret; + unsigned long old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_times(tbuf ? &t : NULL); + set_fs (old_fs); + if (tbuf && ( + put_user (t.tms_utime, &(((struct tms32 *)A(tbuf))->tms_utime)) || + __put_user (t.tms_stime, &(((struct tms32 *)A(tbuf))->tms_stime)) || + __put_user (t.tms_cutime, &(((struct tms32 *)A(tbuf))->tms_cutime)) || + __put_user (t.tms_cstime, &(((struct tms32 *)A(tbuf))->tms_cstime)))) + return -EFAULT; + return ret; } asmlinkage int sys32_getgroups(int gidsetsize, u32 grouplist) { - return sys_getgroups(gidsetsize, (gid_t *)A(grouplist)); + gid_t gl[NGROUPS]; + int ret, i; + unsigned long old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_getgroups(gidsetsize, gl); + set_fs (old_fs); + if (ret > 0 && ret <= NGROUPS) + for (i = 0; i < ret; i++, grouplist += sizeof(__kernel_gid_t32)) + if (__put_user (gl[i], (__kernel_gid_t32 *)A(grouplist))) + return -EFAULT; + return ret; } asmlinkage int sys32_setgroups(int gidsetsize, u32 grouplist) { - return sys_setgroups(gidsetsize, (gid_t *)A(grouplist)); + gid_t gl[NGROUPS]; + int ret, i; + unsigned long old_fs = get_fs (); + + if ((unsigned) gidsetsize > NGROUPS) + return -EINVAL; + for (i = 0; i < gidsetsize; i++, grouplist += sizeof(__kernel_gid_t32)) + if (__get_user (gl[i], (__kernel_gid_t32 *)A(grouplist))) + return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_setgroups(gidsetsize, gl); + set_fs (old_fs); + return ret; } asmlinkage int sys32_newuname(u32 name) { + /* utsname is the same :)) */ return sys_newuname((struct new_utsname *)A(name)); } -asmlinkage int sys32_uname(u32 name) -{ - return sys_uname((struct old_utsname *)A(name)); -} - asmlinkage int sys32_olduname(u32 name) { return sys_olduname((struct oldold_utsname *)A(name)); @@ -1143,19 +1360,54 @@ asmlinkage int sys32_setdomainname(u32 name, int len) return sys_setdomainname((char *)A(name), len); } +struct rlimit32 { + s32 rlim_cur; + s32 rlim_max; +}; + asmlinkage int sys32_getrlimit(unsigned int resource, u32 rlim) { - return sys_getrlimit(resource, (struct rlimit *)A(rlim)); + struct rlimit r; + int ret; + unsigned long old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_getrlimit(resource, &r); + set_fs (old_fs); + if (!ret && ( + put_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) || + __put_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max)))) + return -EFAULT; + return ret; } asmlinkage int sys32_setrlimit(unsigned int resource, u32 rlim) { - return sys_setrlimit(resource, (struct rlimit *)A(rlim)); + struct rlimit r; + int ret; + unsigned long old_fs = get_fs (); + + if (resource >= RLIM_NLIMITS) return -EINVAL; + if (get_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) || + __get_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max))) + return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_setrlimit(resource, &r); + set_fs (old_fs); + return ret; } asmlinkage int sys32_getrusage(int who, u32 ru) { - return sys_getrusage(who, (struct rusage *)A(ru)); + struct rusage r; + int ret; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_getrusage(who, &r); + set_fs (old_fs); + if (put_rusage (ru, &r)) return -EFAULT; + return ret; } asmlinkage int sys32_time(u32 tloc) @@ -1165,6 +1417,7 @@ asmlinkage int sys32_time(u32 tloc) asmlinkage int sys32_gettimeofday(u32 tv, u32 tz) { + /* both timeval and timezone are ok :)) */ return sys_gettimeofday((struct timeval *)A(tv), (struct timezone *)A(tz)); } @@ -1173,22 +1426,86 @@ asmlinkage int sys32_settimeofday(u32 tv, u32 tz) return sys_settimeofday((struct timeval *)A(tv), (struct timezone *)A(tz)); } +struct timex32 { + unsigned int modes; + s32 offset; + s32 freq; + s32 maxerror; + s32 esterror; + int status; + s32 constant; + s32 precision; + s32 tolerance; + struct timeval time; + s32 tick; + s32 ppsfreq; + s32 jitter; + int shift; + s32 stabil; + s32 jitcnt; + s32 calcnt; + s32 errcnt; + s32 stbcnt; + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; int :32; +}; + asmlinkage int sys32_adjtimex(u32 txc_p) { - return sys_adjtimex((struct timex *)A(txc_p)); + struct timex t; + int ret; + unsigned long old_fs = get_fs (); + + if (get_user (t.modes, &(((struct timex32 *)A(txc_p))->modes)) || + __get_user (t.offset, &(((struct timex32 *)A(txc_p))->offset)) || + __get_user (t.freq, &(((struct timex32 *)A(txc_p))->freq)) || + __get_user (t.maxerror, &(((struct timex32 *)A(txc_p))->maxerror)) || + __get_user (t.esterror, &(((struct timex32 *)A(txc_p))->esterror)) || + __get_user (t.status, &(((struct timex32 *)A(txc_p))->status)) || + __get_user (t.constant, &(((struct timex32 *)A(txc_p))->constant)) || + __get_user (t.tick, &(((struct timex32 *)A(txc_p))->tick)) || + __get_user (t.shift, &(((struct timex32 *)A(txc_p))->shift))) + return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_adjtimex(&t); + set_fs (old_fs); + if ((unsigned)ret >= 0 && ( + __put_user (t.modes, &(((struct timex32 *)A(txc_p))->modes)) || + __put_user (t.offset, &(((struct timex32 *)A(txc_p))->offset)) || + __put_user (t.freq, &(((struct timex32 *)A(txc_p))->freq)) || + __put_user (t.maxerror, &(((struct timex32 *)A(txc_p))->maxerror)) || + __put_user (t.esterror, &(((struct timex32 *)A(txc_p))->esterror)) || + __put_user (t.status, &(((struct timex32 *)A(txc_p))->status)) || + __put_user (t.constant, &(((struct timex32 *)A(txc_p))->constant)) || + __put_user (t.precision, &(((struct timex32 *)A(txc_p))->precision)) || + __put_user (t.tolerance, &(((struct timex32 *)A(txc_p))->tolerance)) || + __put_user (t.time.tv_sec, &(((struct timex32 *)A(txc_p))->time.tv_sec)) || + __put_user (t.time.tv_usec, &(((struct timex32 *)A(txc_p))->time.tv_usec)) || + __put_user (t.tick, &(((struct timex32 *)A(txc_p))->tick)) || + __put_user (t.ppsfreq, &(((struct timex32 *)A(txc_p))->ppsfreq)) || + __put_user (t.jitter, &(((struct timex32 *)A(txc_p))->jitter)) || + __put_user (t.shift, &(((struct timex32 *)A(txc_p))->shift)) || + __put_user (t.stabil, &(((struct timex32 *)A(txc_p))->stabil)) || + __put_user (t.jitcnt, &(((struct timex32 *)A(txc_p))->jitcnt)) || + __put_user (t.calcnt, &(((struct timex32 *)A(txc_p))->calcnt)) || + __put_user (t.errcnt, &(((struct timex32 *)A(txc_p))->errcnt)) || + __put_user (t.stbcnt, &(((struct timex32 *)A(txc_p))->stbcnt)))) + return -EFAULT; + return ret; } -asmlinkage int sys32_msync(u32 start, u32 len, int flags) +asmlinkage int sys32_msync(u32 start, __kernel_size_t32 len, int flags) { return sys_msync((unsigned long)start, (size_t)len, flags); } -asmlinkage int sys32_mlock(u32 start, u32 len) +asmlinkage int sys32_mlock(u32 start, __kernel_size_t32 len) { return sys_mlock((unsigned long)start, (size_t)len); } -asmlinkage int sys32_munlock(u32 start, u32 len) +asmlinkage int sys32_munlock(u32 start, __kernel_size_t32 len) { return sys_munlock((unsigned long)start, (size_t)len); } @@ -1198,12 +1515,12 @@ asmlinkage unsigned long sparc32_brk(u32 brk) return sys_brk((unsigned long)brk); } -asmlinkage int sys32_munmap(u32 addr, u32 len) +asmlinkage int sys32_munmap(u32 addr, __kernel_size_t32 len) { return sys_munmap((unsigned long)addr, (size_t)len); } -asmlinkage int sys32_mprotect(u32 start, u32 len, u32 prot) +asmlinkage int sys32_mprotect(u32 start, __kernel_size_t32 len, u32 prot) { return sys_mprotect((unsigned long)start, (size_t)len, (unsigned long)prot); } @@ -1225,6 +1542,7 @@ asmlinkage int sys32_swapon(u32 specialfile, int swap_flags) asmlinkage int sys32_bind(int fd, u32 umyaddr, int addrlen) { + /* sockaddr is the same :)) */ return sys_bind(fd, (struct sockaddr *)A(umyaddr), addrlen); } @@ -1248,28 +1566,31 @@ asmlinkage int sys32_getpeername(int fd, u32 usockaddr, u32 usockaddr_len) return sys_getpeername(fd, (struct sockaddr *)A(usockaddr), (int *)A(usockaddr_len)); } -asmlinkage int sys32_send(int fd, u32 buff, u32 len, unsigned flags) +asmlinkage int sys32_send(int fd, u32 buff, __kernel_size_t32 len, unsigned flags) { return sys_send(fd, (void *)A(buff), (size_t)len, flags); } -asmlinkage int sys32_sendto(int fd, u32 buff, u32 len, unsigned flags, u32 addr, int addr_len) +asmlinkage int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len, unsigned flags, u32 addr, int addr_len) { return sys_sendto(fd, (void *)A(buff), (size_t)len, flags, (struct sockaddr *)A(addr), addr_len); } -asmlinkage int sys32_recv(int fd, u32 ubuf, u32 size, unsigned flags) +asmlinkage int sys32_recv(int fd, u32 ubuf, __kernel_size_t32 size, unsigned flags) { return sys_recv(fd, (void *)A(ubuf), (size_t)size, flags); } -asmlinkage int sys32_recvfrom(int fd, u32 ubuf, u32 size, unsigned flags, u32 addr, u32 addr_len) +asmlinkage int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size, unsigned flags, u32 addr, u32 addr_len) { return sys_recvfrom(fd, (void *)A(ubuf), (size_t)size, flags, (struct sockaddr *)A(addr), (int *)A(addr_len)); } asmlinkage int sys32_setsockopt(int fd, int level, int optname, u32 optval, int optlen) { + /* XXX handle ip_fw32->ip_fw conversion for IP firewalling and accounting. + Do it using some macro in ip_sockglue.c + Other optval arguments are mostly just ints or 32<->64bit transparent */ return sys_setsockopt(fd, level, optname, (char *)A(optval), optlen); } @@ -1278,6 +1599,7 @@ asmlinkage int sys32_getsockopt(int fd, int level, int optname, u32 optval, u32 return sys_getsockopt(fd, level, optname, (char *)A(optval), (int *)A(optlen)); } +/* Continue here */ asmlinkage int sys32_sendmsg(int fd, u32 msg, unsigned flags) { return sys_sendmsg(fd, (struct msghdr *)A(msg), flags); @@ -1328,7 +1650,7 @@ asmlinkage int sparc32_sigaction (int signum, u32 action, u32 oldaction) if (oldaction) { err = -EFAULT; old_sa.sa_handler = (unsigned)(u64)(p->sa_handler); - old_sa.sa_mask = (sigset32_t)(p->sa_mask); + old_sa.sa_mask = (sigset_t32)(p->sa_mask); old_sa.sa_flags = (unsigned)(p->sa_flags); old_sa.sa_restorer = (unsigned)(u64)(p->sa_restorer); if (copy_to_user(A(oldaction), p, sizeof(struct sigaction32))) @@ -1348,3 +1670,72 @@ out: unlock_kernel(); return err; } + +asmlinkage int sys32_nfsservctl(int cmd, u32 argp, u32 resp) +{ + /* XXX handle argp and resp args */ + return sys_nfsservctl(cmd, (void *)A(argp), (void *)A(resp)); +} + +struct ncp_mount_data32 { + int version; + unsigned int ncp_fd; + __kernel_uid_t32 mounted_uid; + __kernel_pid_t32 wdog_pid; + unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; + unsigned int time_out; + unsigned int retry_count; + unsigned int flags; + __kernel_uid_t32 uid; + __kernel_gid_t32 gid; + __kernel_mode_t32 file_mode; + __kernel_mode_t32 dir_mode; +}; + +void *do_ncp_super_data_conv(void *raw_data) +{ + struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data; + struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data; + + n->dir_mode = n32->dir_mode; + n->file_mode = n32->file_mode; + n->gid = n32->gid; + n->uid = n32->uid; + memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int))); + n->wdog_pid = n32->wdog_pid; + n->mounted_uid = n32->mounted_uid; + return raw_data; +} + +struct smb_mount_data32 { + int version; + unsigned int fd; + __kernel_uid_t32 mounted_uid; + struct sockaddr_in addr; + char server_name[17]; + char client_name[17]; + char service[64]; + char root_path[64]; + char username[64]; + char password[64]; + char domain[64]; + unsigned short max_xmit; + __kernel_uid_t32 uid; + __kernel_gid_t32 gid; + __kernel_mode_t32 file_mode; + __kernel_mode_t32 dir_mode; +}; + +void *do_smb_super_data_conv(void *raw_data) +{ + struct smb_mount_data *s = (struct smb_mount_data *)raw_data; + struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data; + + s->dir_mode = s32->dir_mode; + s->file_mode = s32->file_mode; + s->gid = s32->gid; + s->uid = s32->uid; + memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr))); + s->mounted_uid = s32->mounted_uid; + return raw_data; +} diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 3afd28cc9..8ff04f02a 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -1,8 +1,9 @@ -/* $Id: systbls.S,v 1.6 1997/04/16 10:27:15 jj Exp $ +/* $Id: systbls.S,v 1.8 1997/04/21 08:34:23 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * * Based upon preliminary work which is: * @@ -66,7 +67,7 @@ sys_call_table32: .xword sys_nis_syscall, sys32_llseek, sys32_mlock, sys32_munlock, sys_mlockall /*240*/ .xword sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys_nis_syscall, sys_nis_syscall .xword sys_nis_syscall, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys_nanosleep -/*250*/ .xword sys32_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall +/*250*/ .xword sys32_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl .xword sys_aplib, sys_nis_syscall /* Now the 64-bit native Linux syscall table. */ @@ -114,8 +115,8 @@ sys_call_table: .xword sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_newuname /*190*/ .xword sys_init_module, sys_personality, sys_prof, sys_break, sys_lock .xword sys_mpx, sys_ulimit, sys_getppid, sparc_sigaction, sys_sgetmask -/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir - .xword sys_nis_syscall, sys_socketcall, sys_syslog, sys_olduname, sys_nis_syscall +/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, sys_nis_syscall + .xword sys_nis_syscall, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall /*210*/ .xword sys_idle, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo .xword sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex /*220*/ .xword sys_sigprocmask, sys_create_module, sys_delete_module, sys_get_kernel_syms, sys_getpgid @@ -124,7 +125,7 @@ sys_call_table: .xword sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .xword sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_nis_syscall, sys_nis_syscall .xword sys_nis_syscall, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/ .xword sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall +/*250*/ .xword sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl .xword sys_aplib, sys_nis_syscall /* Now the 32-bit SunOS syscall table. */ diff --git a/arch/sparc64/lib/checksum.S b/arch/sparc64/lib/checksum.S index 29aba94be..8a06003ee 100644 --- a/arch/sparc64/lib/checksum.S +++ b/arch/sparc64/lib/checksum.S @@ -16,6 +16,7 @@ #include #include #include +#include #define CSUM_BIGCHUNK(buf, offset, sum, t0, t1, t2, t3, t4, t5) \ ldd [buf + offset + 0x00], t0; \ @@ -547,22 +548,18 @@ __csum_partial_copy_end: brz,pn %i2, 2f mov %i0, %o1 mov %i1, %o0 -5: - call __memcpy + call __copy_from_user mov %i2, %o2 brnz,a,pn %o0, 2f add %i3, %i2, %i3 add %i1, %i2, %i1 2: mov %i1, %o0 - call __bzero + wr %%g0, ASI_S, %%asi + call __bzero_noasi mov %i3, %o1 1: ldx [%sp + STACK_BIAS + 264], %o2 ! struct_ptr of parent st %i5, [%o2] ret restore - - .section __ex_table,#alloc - .align 4 - .word 5b,2 diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 72d2774b5..57ca5eb92 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.23 1997/04/16 10:27:18 jj Exp $ +/* $Id: init.c,v 1.24 1997/04/17 21:49:41 jj Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -706,7 +706,6 @@ void free_initmem (void) atomic_set(&mem_map[MAP_NR(addr)].count, 1); free_page(addr); } - printk ("Freeing unused kernel memory: %dk freed\n", (unsigned)((&__init_end - &__init_begin) >> 10)); } void si_meminfo(struct sysinfo *val) diff --git a/drivers/block/Config.in b/drivers/block/Config.in index 56052e313..59486adaa 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -23,7 +23,7 @@ else fi if [ "$CONFIG_PCI" = "y" ]; then bool ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 - bool ' Intel PIIX/PIIX3 (Triton 430FX/HX/VX, 440FX) DMA support' CONFIG_BLK_DEV_TRITON + bool ' Intel PIIX/PIIX3/PIIX4 (Triton 430FX/HX/VX/TX, 440FX) DMA support' CONFIG_BLK_DEV_TRITON fi bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then diff --git a/drivers/block/ide.c b/drivers/block/ide.c index e39a0c16a..ca9456479 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -2602,6 +2602,7 @@ static void probe_for_hwifs (void) */ ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1); ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0); + ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0); #endif /* CONFIG_BLK_DEV_TRITON */ #ifdef CONFIG_BLK_DEV_OPTI621 ide_probe_pci (PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, &ide_init_opti621, 0); diff --git a/drivers/block/triton.c b/drivers/block/triton.c index 735147d15..7956307c8 100644 --- a/drivers/block/triton.c +++ b/drivers/block/triton.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/triton.c Version 2.00 March 9, 1997 + * linux/drivers/block/triton.c Version 2.10 April 22, 1997 * * Copyright (c) 1995-1997 Mark Lord * May be copied or modified under the terms of the GNU General Public License @@ -8,8 +8,8 @@ /* * This module provides support for the bus-master IDE DMA function * of the Intel PCI Triton chipset families, which use the PIIX (i82371FB, - * for the 430 FX chipset), and the enhanced PIIX3 (i82371SB for the 430 HX/VX - * and 440 chipsets). + * for the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and + * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset). * * "PIIX" stands for "PCI ISA IDE Xcellerator". * @@ -18,12 +18,12 @@ * * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). * - * Up to four drives may be enabled for DMA, and the PIIX/PIIX3 chips + * Up to four drives may be enabled for DMA, and the PIIX* chips * will arbitrate the PCI bus among them. Note that the PIIX/PIIX3 * provides a single "line buffer" for the BM IDE function, so performance of * multiple (two) drives doing DMA simultaneously will suffer somewhat, * as they contest for that resource bottleneck. This is handled transparently - * inside the PIIX/PIIX3. + * inside the PIIX/PIIX3. The PIIX4 does not have this problem. * * By default, DMA support is prepared for use, but is currently enabled only * for drives which support DMA mode2 (multi/single word), or which are @@ -60,6 +60,9 @@ * Thanks to "Christopher J. Reimer" for fixing the * problem with some (all?) ACER motherboards/BIOSs. * + * Thanks to "Benoit Poulot-Cazajous" for testing + * "TX" chipset compatibility and for providing patches for the "TX" chipset. + * * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports. */ #include @@ -342,7 +345,7 @@ static int config_drive_for_dma (ide_drive_t *drive) #ifdef DISPLAY_PIIX_TIMINGS /* * print_piix_drive_flags() displays the currently programmed options - * in the PIIX/PIIX3 for a given drive. + * in the PIIX/PIIX3/PIIX4 for a given drive. */ static void print_piix_drive_flags (const char *unit, byte dflags) { @@ -448,7 +451,13 @@ void ide_init_triton (byte bus, byte fn) if (pcibios_read_config_word(bus, fn, 0x02, &devid)) goto quit; - chipset = (devid == PCI_DEVICE_ID_INTEL_82371SB_1) ? "PIIX3" : "PIIX"; + + if (devid == PCI_DEVICE_ID_INTEL_82371AB) + chipset = "PIIX4"; + else if (devid == PCI_DEVICE_ID_INTEL_82371SB_1) + chipset = "PIIX3"; + else + chipset = "PIIX"; printk("%s: bus-master IDE device on PCI bus %d function %d\n", chipset, bus, fn); @@ -532,10 +541,11 @@ void ide_init_triton (byte bus, byte fn) piix_sidetim_t sidetim; byte sample = 5 - timing.sample; byte recovery = 4 - timing.recovery; - if (devid == PCI_DEVICE_ID_INTEL_82371SB_1 + if ((devid == PCI_DEVICE_ID_INTEL_82371SB_1 + || devid == PCI_DEVICE_ID_INTEL_82371AB) && timing.sidetim_enabled && !pcibios_read_config_byte(bus, fn, 0x44, (byte *) &sidetim)) - slave = ""; /* PIIX3 */ + slave = ""; /* PIIX3 and later */ else slave = "/slave"; /* PIIX, or PIIX3 in compatibility mode */ printk(" %s master%s: sample_CLKs=%d, recovery_CLKs=%d\n", hwif->name, slave, sample, recovery); diff --git a/drivers/char/amigamouse.c b/drivers/char/amigamouse.c index 5f2d88a25..602695c39 100644 --- a/drivers/char/amigamouse.c +++ b/drivers/char/amigamouse.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -308,7 +309,7 @@ static struct miscdevice amiga_mouse = { AMIGAMOUSE_MINOR, "amigamouse", &amiga_mouse_fops }; -int amiga_mouse_init(void) +__initfunc(int amiga_mouse_init(void)) { if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) return -ENODEV; diff --git a/drivers/char/apm_bios.c b/drivers/char/apm_bios.c index 6fd3c16dc..bf7a04633 100644 --- a/drivers/char/apm_bios.c +++ b/drivers/char/apm_bios.c @@ -73,6 +73,7 @@ #endif #include #include +#include EXPORT_SYMBOL(apm_register_callback); EXPORT_SYMBOL(apm_unregister_callback); @@ -451,7 +452,7 @@ static int apm_set_display_power_state(u_short state) #ifdef CONFIG_APM_DO_ENABLE /* Called by apm_setup if apm_enabled will be true. */ -static int apm_enable_power_management(void) +static inline int apm_enable_power_management(void) { u_short error; @@ -474,7 +475,7 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life) return APM_SUCCESS; } -static int apm_engage_power_management(u_short device) +static inline int apm_engage_power_management(u_short device) { u_short error; @@ -1059,7 +1060,7 @@ int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy) } #endif -void apm_bios_init(void) +__initfunc(void apm_bios_init(void)) { unsigned short bx; unsigned short cx; diff --git a/drivers/char/atarimouse.c b/drivers/char/atarimouse.c index 9c7405eff..18debb66b 100644 --- a/drivers/char/atarimouse.c +++ b/drivers/char/atarimouse.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -158,7 +159,7 @@ static struct miscdevice atari_mouse = { ATARIMOUSE_MINOR, "atarimouse", &atari_mouse_fops }; -int atari_mouse_init(void) +__initfunc(int atari_mouse_init(void)) { mouse.active = 0; mouse.ready = 0; diff --git a/drivers/char/atixlmouse.c b/drivers/char/atixlmouse.c index 04382371a..c8a730a35 100644 --- a/drivers/char/atixlmouse.c +++ b/drivers/char/atixlmouse.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -201,7 +202,7 @@ static struct miscdevice atixl_mouse = { }; -int atixl_busmouse_init(void) +__initfunc(int atixl_busmouse_init(void)) { unsigned char a,b,c; diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c index bae68d4ff..d8b267095 100644 --- a/drivers/char/busmouse.c +++ b/drivers/char/busmouse.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -246,7 +247,7 @@ static struct miscdevice bus_mouse = { LOGITECH_BUSMOUSE, "busmouse", &bus_mouse_fops }; -int bus_mouse_init(void) +__initfunc(int bus_mouse_init(void)) { if (check_region(LOGIBM_BASE, LOGIBM_EXTENT)) { mouse.present = 0; diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 44b7c03ee..0a1825ee8 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -288,6 +288,7 @@ static char rcsid[] = #include #include #include +#include #define small_delay(x) for(j=0;j + * lars brinkhoff + * Tomas Berndtsson + * + * First version May 1996 + * + * History: + * 97-01-29 Tomas Berndtsson, + * Integrated with Linux 2.1.21 kernel sources. + * 97-02-15 Tomas Berndtsson, + * Fixed for kernel 2.1.26 + * + * BUGS: + * Hmm... there must be something here :) + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include /* for kmalloc() and kfree() */ +#include /* for struct wait_queue etc */ +#include +#include +#include +#include /* guess what */ +#include +#include + +#include +#include +#include +#include /* For put_user and get_user */ + +#include + +/* minor devices */ +#define DSP56K_DEV_56001 0 /* The only device so far */ + +#define TIMEOUT 10 /* Host port timeout in number of tries */ +#define MAXIO 2048 /* Maximum number of words before sleep */ +#define DSP56K_MAX_BINARY_LENGTH (3*64*1024) + +#define DSP56K_TX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_TREQ +#define DSP56K_RX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_RREQ +#define DSP56K_TX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_TREQ +#define DSP56K_RX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_RREQ + +#define DSP56K_TRANSMIT (dsp56k_host_interface.isr & DSP56K_ISR_TXDE) +#define DSP56K_RECEIVE (dsp56k_host_interface.isr & DSP56K_ISR_RXDF) + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#define wait_some(n) \ +{ \ + current->state = TASK_INTERRUPTIBLE; \ + current->timeout = jiffies + n; \ + schedule(); \ +} + +#define handshake(count, maxio, timeout, ENABLE, f) \ +{ \ + long i, t, m; \ + while (count > 0) { \ + m = min(count, maxio); \ + for (i = 0; i < m; i++) { \ + for (t = 0; t < timeout && !ENABLE; t++) \ + wait_some(2); \ + if(!ENABLE) \ + return -EIO; \ + f; \ + } \ + count -= m; \ + if (m == maxio) wait_some(2); \ + } \ +} + +#define tx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_TRANSMIT; t++) \ + wait_some(1); \ + if(!DSP56K_TRANSMIT) { \ + return -EIO; \ + } \ +} + +#define rx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_RECEIVE; t++) \ + wait_some(1); \ + if(!DSP56K_RECEIVE) { \ + return -EIO; \ + } \ +} + +/* DSP56001 bootstrap code */ +static char bootstrap[] = { + 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4, + 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47, + 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00, + 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe, + 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0, + 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4, + 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01, + 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08, + 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46, + 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa, + 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00, + 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9, + 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80, + 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0, + 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4, + 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a, + 0xf0, 0x80, 0x00, 0x7e, 0xad}; +static int sizeof_bootstrap = 375; + + +static struct dsp56k_device { + int in_use; + long maxio, timeout; + int tx_wsize, rx_wsize; +} dsp56k; + +static int dsp56k_reset(void) +{ + u_char status; + + /* Power down the DSP */ + sound_ym.rd_data_reg_sel = 14; + status = sound_ym.rd_data_reg_sel & 0xef; + sound_ym.wd_data = status; + sound_ym.wd_data = status | 0x10; + + udelay(10); + + /* Power up the DSP */ + sound_ym.rd_data_reg_sel = 14; + sound_ym.wd_data = sound_ym.rd_data_reg_sel & 0xef; + + return 0; +} + +static int dsp56k_upload(u_char *bin, int len) +{ + int i; + u_char *p; + + dsp56k_reset(); + + p = bootstrap; + for (i = 0; i < sizeof_bootstrap/3; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = *p++; + dsp56k_host_interface.data.b[2] = *p++; + dsp56k_host_interface.data.b[3] = *p++; + } + for (; i < 512; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = 0; + dsp56k_host_interface.data.b[2] = 0; + dsp56k_host_interface.data.b[3] = 0; + } + + for (i = 0; i < len; i++) { + tx_wait(10); + get_user(dsp56k_host_interface.data.b[1], bin++); + get_user(dsp56k_host_interface.data.b[2], bin++); + get_user(dsp56k_host_interface.data.b[3], bin++); + } + + tx_wait(10); + dsp56k_host_interface.data.l = 3; /* Magic execute */ + + return 0; +} + +static long dsp56k_read(struct inode *inode, struct file *file, + char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.rx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[1], buf+n++); + put_user(dsp56k_host_interface.data.b[2], buf+n++); + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + return -EFAULT; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static long dsp56k_write(struct inode *inode, struct file *file, + const char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.tx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[1], buf+n++); + get_user(dsp56k_host_interface.data.b[2], buf+n++); + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + + return -EFAULT; + } + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static int dsp56k_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(cmd) { + case DSP56K_UPLOAD: + { + char *bin; + int r, len; + struct dsp56k_upload *binary = (struct dsp56k_upload *) arg; + + if(get_user(len, &binary->len) < 0) + return -EFAULT; + if(get_user(bin, &binary->bin) < 0) + return -EFAULT; + + if (len == 0) { + return -EINVAL; /* nothing to upload?!? */ + } + if (len > DSP56K_MAX_BINARY_LENGTH) { + return -EINVAL; + } + + r = dsp56k_upload(bin, len); + if (r < 0) { + return r; + } + + break; + } + case DSP56K_SET_TX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.tx_wsize = (int) arg; + break; + case DSP56K_SET_RX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.rx_wsize = (int) arg; + break; + case DSP56K_HOST_FLAGS: + { + int dir, out, status; + struct dsp56k_host_flags *hf = (struct dsp56k_host_flags*) arg; + + if(get_user(dir, &hf->dir) < 0) + return -EFAULT; + if(get_user(out, &hf->out) < 0) + return -EFAULT; + + if ((dir & 0x1) && (out & 0x1)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF0; + else if (dir & 0x1) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + if ((dir & 0x2) && (out & 0x2)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF1; + else if (dir & 0x2) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + status = 0; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF0) status |= 0x1; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF1) status |= 0x2; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF2) status |= 0x4; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF3) status |= 0x8; + + if(put_user(status, &hf->status) < 0) + return -EFAULT; + break; + } + case DSP56K_HOST_CMD: + if (arg > 31 || arg < 0) + return -EINVAL; + dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) | + DSP56K_CVR_HC); + break; + default: + return -EINVAL; + } + return 0; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +/* As of 2.1.26 this should be dsp56k_poll, + * but how do I then check device minor number? + * Do I need this function at all??? + */ +#ifdef 0 +static int dsp56k_select(struct inode *inode, struct file *file, int sel_type, + select_table *wait) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(sel_type) { + case SEL_IN: /* read */ + return 1; + case SEL_OUT: /* write */ + return 1; + default: + return 1; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} +#endif + +static int dsp56k_open(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + if (dsp56k.in_use) + return -EBUSY; + + dsp56k.in_use = 1; + dsp56k.timeout = TIMEOUT; + dsp56k.maxio = MAXIO; + dsp56k.rx_wsize = dsp56k.tx_wsize = 4; + + DSP56K_TX_INT_OFF; + DSP56K_RX_INT_OFF; + + /* Zero host flags */ + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + break; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif /* MODULE */ + + return 0; +} + +static void dsp56k_release(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + dsp56k.in_use = 0; + + break; + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return; + } + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif /* MODULE */ +} + +static struct file_operations dsp56k_fops = { + NULL, /* no special dsp56k_lseek */ + dsp56k_read, + dsp56k_write, + NULL, /* no special dsp56k_readdir */ + NULL, /* dsp56k_poll? */ + dsp56k_ioctl, + NULL, /* no special dsp56k_mmap */ + dsp56k_open, + dsp56k_release, + NULL, /* no special dsp56k_fsync */ + NULL, /* no special dsp56k_fasync */ + NULL, /* no special dsp56k_check_media_change */ + NULL /* no special dsp56k_revalidate */ +}; + + +/****** Init and module functions ******/ + +static int init_error = 0; + +void dsp56k_init(void) +{ + if(!ATARIHW_PRESENT(DSP56K)) { + init_error = 1; + printk("DSP56k driver: Hardware not present\n"); + return; + } + +#ifndef MODULE + if(register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops)) { + printk("DSP56k driver: Unable to register driver\n"); + return; + } +#endif /* !MODULE */ + + dsp56k.in_use = 0; + + printk("DSP56k driver installed\n"); +} + +#ifdef MODULE +int init_module(void) +{ + int r; + + init_error = 0; + dsp56k_init(); + if(init_error) + return -EPERM; + + r = register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops); + if(r) { + printk("DSP56k driver: Unable to register driver\n"); + return r; + } + + return 0; +} + +void cleanup_module(void) +{ + unregister_chrdev(DSP56K_MAJOR, "dsp56k"); +} +#endif /* MODULE */ +/* + * The DSP56001 Device Driver, saviour of the Free World(tm) + * + * Authors: Fredrik Noring + * lars brinkhoff + * Tomas Berndtsson + * + * First version May 1996 + * + * History: + * 97-01-29 Tomas Berndtsson, + * Integrated with Linux 2.1.21 kernel sources. + * 97-02-15 Tomas Berndtsson, + * Fixed for kernel 2.1.26 + * + * BUGS: + * Hmm... there must be something here :) + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include /* for kmalloc() and kfree() */ +#include /* for struct wait_queue etc */ +#include +#include +#include +#include /* guess what */ +#include +#include + +#include +#include +#include +#include /* For put_user and get_user */ + +#include + +/* minor devices */ +#define DSP56K_DEV_56001 0 /* The only device so far */ + +#define TIMEOUT 10 /* Host port timeout in number of tries */ +#define MAXIO 2048 /* Maximum number of words before sleep */ +#define DSP56K_MAX_BINARY_LENGTH (3*64*1024) + +#define DSP56K_TX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_TREQ +#define DSP56K_RX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_RREQ +#define DSP56K_TX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_TREQ +#define DSP56K_RX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_RREQ + +#define DSP56K_TRANSMIT (dsp56k_host_interface.isr & DSP56K_ISR_TXDE) +#define DSP56K_RECEIVE (dsp56k_host_interface.isr & DSP56K_ISR_RXDF) + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#define wait_some(n) \ +{ \ + current->state = TASK_INTERRUPTIBLE; \ + current->timeout = jiffies + n; \ + schedule(); \ +} + +#define handshake(count, maxio, timeout, ENABLE, f) \ +{ \ + long i, t, m; \ + while (count > 0) { \ + m = min(count, maxio); \ + for (i = 0; i < m; i++) { \ + for (t = 0; t < timeout && !ENABLE; t++) \ + wait_some(2); \ + if(!ENABLE) \ + return -EIO; \ + f; \ + } \ + count -= m; \ + if (m == maxio) wait_some(2); \ + } \ +} + +#define tx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_TRANSMIT; t++) \ + wait_some(1); \ + if(!DSP56K_TRANSMIT) { \ + return -EIO; \ + } \ +} + +#define rx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_RECEIVE; t++) \ + wait_some(1); \ + if(!DSP56K_RECEIVE) { \ + return -EIO; \ + } \ +} + +/* DSP56001 bootstrap code */ +static char bootstrap[] = { + 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4, + 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47, + 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00, + 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe, + 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0, + 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4, + 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01, + 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08, + 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46, + 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa, + 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00, + 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9, + 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80, + 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0, + 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4, + 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a, + 0xf0, 0x80, 0x00, 0x7e, 0xad}; +static int sizeof_bootstrap = 375; + + +static struct dsp56k_device { + int in_use; + long maxio, timeout; + int tx_wsize, rx_wsize; +} dsp56k; + +static int dsp56k_reset(void) +{ + u_char status; + + /* Power down the DSP */ + sound_ym.rd_data_reg_sel = 14; + status = sound_ym.rd_data_reg_sel & 0xef; + sound_ym.wd_data = status; + sound_ym.wd_data = status | 0x10; + + udelay(10); + + /* Power up the DSP */ + sound_ym.rd_data_reg_sel = 14; + sound_ym.wd_data = sound_ym.rd_data_reg_sel & 0xef; + + return 0; +} + +static int dsp56k_upload(u_char *bin, int len) +{ + int i; + u_char *p; + + dsp56k_reset(); + + p = bootstrap; + for (i = 0; i < sizeof_bootstrap/3; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = *p++; + dsp56k_host_interface.data.b[2] = *p++; + dsp56k_host_interface.data.b[3] = *p++; + } + for (; i < 512; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = 0; + dsp56k_host_interface.data.b[2] = 0; + dsp56k_host_interface.data.b[3] = 0; + } + + for (i = 0; i < len; i++) { + tx_wait(10); + get_user(dsp56k_host_interface.data.b[1], bin++); + get_user(dsp56k_host_interface.data.b[2], bin++); + get_user(dsp56k_host_interface.data.b[3], bin++); + } + + tx_wait(10); + dsp56k_host_interface.data.l = 3; /* Magic execute */ + + return 0; +} + +static long dsp56k_read(struct inode *inode, struct file *file, + char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.rx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[1], buf+n++); + put_user(dsp56k_host_interface.data.b[2], buf+n++); + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + return -EFAULT; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static long dsp56k_write(struct inode *inode, struct file *file, + const char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.tx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[1], buf+n++); + get_user(dsp56k_host_interface.data.b[2], buf+n++); + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + + return -EFAULT; + } + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static int dsp56k_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(cmd) { + case DSP56K_UPLOAD: + { + char *bin; + int r, len; + struct dsp56k_upload *binary = (struct dsp56k_upload *) arg; + + if(get_user(len, &binary->len) < 0) + return -EFAULT; + if(get_user(bin, &binary->bin) < 0) + return -EFAULT; + + if (len == 0) { + return -EINVAL; /* nothing to upload?!? */ + } + if (len > DSP56K_MAX_BINARY_LENGTH) { + return -EINVAL; + } + + r = dsp56k_upload(bin, len); + if (r < 0) { + return r; + } + + break; + } + case DSP56K_SET_TX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.tx_wsize = (int) arg; + break; + case DSP56K_SET_RX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.rx_wsize = (int) arg; + break; + case DSP56K_HOST_FLAGS: + { + int dir, out, status; + struct dsp56k_host_flags *hf = (struct dsp56k_host_flags*) arg; + + if(get_user(dir, &hf->dir) < 0) + return -EFAULT; + if(get_user(out, &hf->out) < 0) + return -EFAULT; + + if ((dir & 0x1) && (out & 0x1)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF0; + else if (dir & 0x1) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + if ((dir & 0x2) && (out & 0x2)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF1; + else if (dir & 0x2) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + status = 0; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF0) status |= 0x1; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF1) status |= 0x2; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF2) status |= 0x4; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF3) status |= 0x8; + + if(put_user(status, &hf->status) < 0) + return -EFAULT; + break; + } + case DSP56K_HOST_CMD: + if (arg > 31 || arg < 0) + return -EINVAL; + dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) | + DSP56K_CVR_HC); + break; + default: + return -EINVAL; + } + return 0; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +/* As of 2.1.26 this should be dsp56k_poll, + * but how do I then check device minor number? + * Do I need this function at all??? + */ +#ifdef 0 +static int dsp56k_select(struct inode *inode, struct file *file, int sel_type, + select_table *wait) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(sel_type) { + case SEL_IN: /* read */ + return 1; + case SEL_OUT: /* write */ + return 1; + default: + return 1; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} +#endif + +static int dsp56k_open(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + if (dsp56k.in_use) + return -EBUSY; + + dsp56k.in_use = 1; + dsp56k.timeout = TIMEOUT; + dsp56k.maxio = MAXIO; + dsp56k.rx_wsize = dsp56k.tx_wsize = 4; + + DSP56K_TX_INT_OFF; + DSP56K_RX_INT_OFF; + + /* Zero host flags */ + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + break; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif /* MODULE */ + + return 0; +} + +static void dsp56k_release(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + dsp56k.in_use = 0; + + break; + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return; + } + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif /* MODULE */ +} + +static struct file_operations dsp56k_fops = { + NULL, /* no special dsp56k_lseek */ + dsp56k_read, + dsp56k_write, + NULL, /* no special dsp56k_readdir */ + NULL, /* dsp56k_poll? */ + dsp56k_ioctl, + NULL, /* no special dsp56k_mmap */ + dsp56k_open, + dsp56k_release, + NULL, /* no special dsp56k_fsync */ + NULL, /* no special dsp56k_fasync */ + NULL, /* no special dsp56k_check_media_change */ + NULL /* no special dsp56k_revalidate */ +}; + + +/****** Init and module functions ******/ + +static int init_error = 0; + +void dsp56k_init(void) +{ + if(!ATARIHW_PRESENT(DSP56K)) { + init_error = 1; + printk("DSP56k driver: Hardware not present\n"); + return; + } + +#ifndef MODULE + if(register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops)) { + printk("DSP56k driver: Unable to register driver\n"); + return; + } +#endif /* !MODULE */ + + dsp56k.in_use = 0; + + printk("DSP56k driver installed\n"); +} + +#ifdef MODULE +int init_module(void) +{ + int r; + + init_error = 0; + dsp56k_init(); + if(init_error) + return -EPERM; + + r = register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops); + if(r) { + printk("DSP56k driver: Unable to register driver\n"); + return r; + } + + return 0; +} + +void cleanup_module(void) +{ + unregister_chrdev(DSP56K_MAJOR, "dsp56k"); +} +#endif /* MODULE */ diff --git a/drivers/char/esp.c b/drivers/char/esp.c index c6b6afce9..c1eb47de0 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -2312,7 +2313,8 @@ static int esp_open(struct tty_struct *tty, struct file * filp) * number, and identifies which options were configured into this * driver. */ -static void show_serial_version(void) + +static _INLINE_ void show_serial_version(void) { printk(KERN_INFO "%s version %s (DMA %u, trigger level %u)\n", serial_name, serial_version, dma, trigger); @@ -2380,7 +2382,7 @@ static _INLINE_ int autoconfig(struct esp_struct * info, int *region_start) /* * The serial driver boot-time initialization code! */ -int espserial_init(void) +__initfunc(int espserial_init(void)) { int i, offset; int region_start; @@ -2565,6 +2567,7 @@ void cleanup_module(void) /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ save_flags(flags); cli(); + remove_bh(ESP_BH); if ((e1 = tty_unregister_driver(&esp_driver))) printk("SERIAL: failed to unregister serial driver (%d)\n", e1); diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 80caed3a0..a0f2f10c5 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -540,13 +541,13 @@ static void stli_start(struct tty_struct *tty); static void stli_flushbuffer(struct tty_struct *tty); static void stli_hangup(struct tty_struct *tty); -static int stli_initbrds(void); +static inline int stli_initbrds(void); static int stli_brdinit(stlibrd_t *brdp); -static int stli_initecp(stlibrd_t *brdp); -static int stli_initonb(stlibrd_t *brdp); +static inline int stli_initecp(stlibrd_t *brdp); +static inline int stli_initonb(stlibrd_t *brdp); static int stli_eisamemprobe(stlibrd_t *brdp); -static int stli_findeisabrds(void); -static int stli_initports(stlibrd_t *brdp); +static inline int stli_findeisabrds(void); +static inline int stli_initports(stlibrd_t *brdp); static int stli_startbrd(stlibrd_t *brdp); static long stli_memread(struct inode *ip, struct file *fp, char *buf, unsigned long count); static long stli_memwrite(struct inode *ip, struct file *fp, const char *buf, unsigned long count); @@ -2781,7 +2782,7 @@ static long stli_mktiocm(unsigned long sigvalue) * we need to do here is set up the appropriate per port data structures. */ -static int stli_initports(stlibrd_t *brdp) +static inline int stli_initports(stlibrd_t *brdp) { stliport_t *portp; int i, panelnr, panelport; @@ -3335,7 +3336,7 @@ static void stli_stalreset(stlibrd_t *brdp) * board types. */ -static int stli_initecp(stlibrd_t *brdp) +static inline int stli_initecp(stlibrd_t *brdp) { cdkecpsig_t sig; cdkecpsig_t *sigsp; @@ -3472,7 +3473,7 @@ static int stli_initecp(stlibrd_t *brdp) * This handles only these board types. */ -static int stli_initonb(stlibrd_t *brdp) +static inline int stli_initonb(stlibrd_t *brdp) { cdkonbsig_t sig; cdkonbsig_t *sigsp; @@ -3737,7 +3738,7 @@ stli_donestartup: * Probe and initialize the specified board. */ -static int stli_brdinit(stlibrd_t *brdp) +__initfunc(static int stli_brdinit(stlibrd_t *brdp)) { #if DEBUG printk("stli_brdinit(brdp=%x)\n", (int) brdp); @@ -3791,7 +3792,7 @@ static int stli_brdinit(stlibrd_t *brdp) * might be. This is a bit if hack, but it is the best we can do. */ -static int stli_eisamemprobe(stlibrd_t *brdp) +__initfunc(static int stli_eisamemprobe(stlibrd_t *brdp)) { cdkecpsig_t ecpsig, *ecpsigp; cdkonbsig_t onbsig, *onbsigp; @@ -3890,7 +3891,7 @@ static int stli_eisamemprobe(stlibrd_t *brdp) * do is go probing around in the usual places hoping we can find it. */ -static int stli_findeisabrds() +static inline int stli_findeisabrds() { stlibrd_t *brdp; unsigned int iobase, eid; @@ -3979,7 +3980,7 @@ static int stli_findeisabrds() * can find. */ -static int stli_initbrds() +static inline int stli_initbrds() { stlibrd_t *brdp, *nxtbrdp; stlconf_t *confp; @@ -4471,7 +4472,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un /*****************************************************************************/ -int stli_init() +__initfunc(int stli_init()) { printk(KERN_INFO "%s: version %s\n", stli_drvname, stli_drvversion); diff --git a/drivers/char/keyb_m68k.c b/drivers/char/keyb_m68k.c index b9c5aa775..587d61a4b 100644 --- a/drivers/char/keyb_m68k.c +++ b/drivers/char/keyb_m68k.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -848,7 +849,7 @@ static void kbd_bh(void) } } -int kbd_init(void) +__initfunc(int kbd_init(void)) { int i; struct kbd_struct kbd0; diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 2c2414124..54384d801 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -1192,7 +1193,7 @@ static void kbd_bh(void) } } -int kbd_init(void) +__initfunc(int kbd_init(void)) { int i; struct kbd_struct kbd0; @@ -1306,7 +1307,7 @@ static void kbd_write(int address, int data) outb(data, address); /* write out the data*/ } -static int initialize_kbd(void) +__initfunc(static int initialize_kbd(void)) { unsigned long flags; diff --git a/drivers/char/lp.c b/drivers/char/lp.c index dd8999244..7fd2f9b35 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -678,7 +679,7 @@ static int inline lp_searchfor(int list[], int a) return 0; } -int lp_init(void) +__initfunc(int lp_init(void)) { int count = 0; struct parport *pb; diff --git a/drivers/char/misc.c b/drivers/char/misc.c index ccd90a8be..fd72f33d8 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef CONFIG_APM #include #endif @@ -184,7 +185,7 @@ EXPORT_SYMBOL(misc_deregister); static struct proc_dir_entry *proc_misc; #endif -int misc_init(void) +__initfunc(int misc_init(void)) { #ifndef MODULE #ifdef CONFIG_PROC_FS diff --git a/drivers/char/msbusmouse.c b/drivers/char/msbusmouse.c index 806e9a88e..b11730f70 100644 --- a/drivers/char/msbusmouse.c +++ b/drivers/char/msbusmouse.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -183,7 +184,7 @@ static struct miscdevice ms_bus_mouse = { MICROSOFT_BUSMOUSE, "msbusmouse", &ms_bus_mouse_fops }; -int ms_bus_mouse_init(void) +__initfunc(int ms_bus_mouse_init(void)) { int mse_byte, i; diff --git a/drivers/char/pcwd.c b/drivers/char/pcwd.c index 0eefd9a64..9a77783b3 100644 --- a/drivers/char/pcwd.c +++ b/drivers/char/pcwd.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -96,7 +97,7 @@ static int is_open, initial_status, supports_temp, mode_debug; * This routine checks the "current_readport" to see if the card lies there. * If it does, it returns accordingly. */ -static int pcwd_checkcard(void) +__initfunc(static int pcwd_checkcard(void)) { int card_dat, prev_card_dat, found = 0, count = 0, done = 0; @@ -400,13 +401,13 @@ static int pcwd_close(struct inode *ino, struct file *filep) return 0; } -static void get_support(void) +static inline void get_support(void) { if (inb(current_readport) != 0xF0) supports_temp = 1; } -static int get_revision(void) +static inline int get_revision(void) { if ((inb(current_readport + 2) == 0xFF) || (inb(current_readport + 3) == 0xFF)) @@ -415,7 +416,7 @@ static int get_revision(void) return(PCWD_REVISION_C); } -static int send_command(int cmd) +__initfunc(static int send_command(int cmd)) { int i; @@ -428,7 +429,7 @@ static int send_command(int cmd) return(i); } -static char *get_firmware(void) +static inline char *get_firmware(void) { int i, found = 0, count = 0, one, ten, hund, minor; char *ret; @@ -498,7 +499,7 @@ static struct miscdevice temp_miscdev = { #ifdef MODULE int init_module(void) #else -int pcwatchdog_init(void) +__initfunc(int pcwatchdog_init(void)) #endif { int i, found = 0; diff --git a/drivers/char/pcxx.c b/drivers/char/pcxx.c index 5cfcb589d..c09c7dbbe 100644 --- a/drivers/char/pcxx.c +++ b/drivers/char/pcxx.c @@ -69,6 +69,7 @@ #include #include #include +#include #ifndef MODULE #include /* We only need it for parsing the "digi="-line */ @@ -217,6 +218,7 @@ void cleanup_module() timer_active &= ~(1 << DIGI_TIMER); timer_table[DIGI_TIMER].fn = NULL; timer_table[DIGI_TIMER].expires = 0; + remove_bh(DIGI_BH); if ((e1 = tty_unregister_driver(&pcxe_driver))) printk("SERIAL: failed to unregister serial driver (%d)\n", e1); @@ -1084,7 +1086,7 @@ void pcxx_setup(char *str, int *ints) * function to initialize the driver with the given parameters, which are either * the default values from this file or the parameters given at boot. */ -int pcxe_init(void) +__initfunc(int pcxe_init(void)) { ulong memory_seg=0, memory_size=0; int lowwater, enabled_cards=0, i, crd, shrinkmem=0, topwin = 0xff00L, botwin=0x100L; diff --git a/drivers/char/psaux.c b/drivers/char/psaux.c index dcf38460d..28239579c 100644 --- a/drivers/char/psaux.c +++ b/drivers/char/psaux.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -529,7 +530,7 @@ static struct miscdevice psaux_mouse = { PSMOUSE_MINOR, "ps2aux", &psaux_fops }; -int psaux_init(void) +__initfunc(int psaux_init(void)) { int qp_found = 0; @@ -653,7 +654,7 @@ static inline unsigned char read_710(unsigned char index) * See if we can find a 82C710 device. Read mouse address. */ -static int probe_qp(void) +__initfunc(static int probe_qp(void)) { outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */ outb_p(0xaa, 0x3fa); /* Inverse of 55 */ diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 1b4532de5..8f1015397 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -224,7 +225,7 @@ static void pty_set_termios(struct tty_struct *tty, struct termios *old_termios) tty->termios->c_cflag |= (CS8 | CREAD); } -int pty_init(void) +__initfunc(int pty_init(void)) { memset(&pty_state, 0, sizeof(pty_state)); memset(&pty_driver, 0, sizeof(struct tty_driver)); diff --git a/drivers/char/random.c b/drivers/char/random.c index 962058990..3fb64b28d 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -234,6 +234,7 @@ #include #include #include +#include #include #include @@ -451,7 +452,7 @@ static void rand_clear_pool(void) init_std_data(&random_state); } -void rand_initialize(void) +__initfunc(void rand_initialize(void)) { int i; @@ -1388,8 +1389,9 @@ static inline unsigned long long get_clock_cnt(void) return (((unsigned long long) high << 31) | low); } -static void initialize_benchmark(struct random_benchmark *bench, - const char *descr, int unit) +__initfunc(static void +initialize_benchmark(struct random_benchmark *bench, + const char *descr, int unit)) { bench->times = 0; bench->accum = 0; diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 1996ebeee..301babf81 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -231,7 +232,7 @@ extern inline void rc_long_delay(unsigned long delay) } /* Reset and setup CD180 chip */ -static void rc_init_CD180(struct riscom_board const * bp) +__initfunc(static void rc_init_CD180(struct riscom_board const * bp)) { unsigned long flags; @@ -256,7 +257,7 @@ static void rc_init_CD180(struct riscom_board const * bp) } /* Main probing routine, also sets irq. */ -static int rc_probe(struct riscom_board *bp) +__initfunc(static int rc_probe(struct riscom_board *bp)) { unsigned char val1, val2; int irqs = 0; @@ -264,7 +265,7 @@ static int rc_probe(struct riscom_board *bp) bp->irq = 0; - if (rc_check_io_range(bp)) + if (rc_check_io_range(bp)) return 1; /* Are the I/O ports here ? */ @@ -1718,7 +1719,7 @@ static void do_softint(void *private_) } } -static int rc_init_drivers(void) +static inline int rc_init_drivers(void) { int error; int i; @@ -1799,9 +1800,15 @@ static int rc_init_drivers(void) static void rc_release_drivers(void) { + unsigned long flags; + + save_flags(flags); + cli(); + remove_bh(RISCOM8_BH); free_page((unsigned long)tmp_buf); tty_unregister_driver(&riscom_driver); tty_unregister_driver(&riscom_callout_driver); + restore_flags(flags); } #ifndef MODULE @@ -1830,7 +1837,7 @@ void riscom8_setup(char *str, int * ints) /* * This routine must be called by kernel at boot time */ -int riscom8_init(void) +__initfunc(int riscom8_init(void)) { int i; int found = 0; diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index bbe4d3cd9..3235ebeaa 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -531,7 +532,7 @@ static struct miscdevice rtc_dev= &rtc_fops }; -int rtc_init(void) +__initfunc(int rtc_init(void)) { unsigned long flags; diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 6c73a880b..7c7d49ab3 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -2917,7 +2918,7 @@ done: * number, and identifies which options were configured into this * driver. */ -static void show_serial_version(void) +static _INLINE_ void show_serial_version(void) { printk(KERN_INFO "%s version %s with", serial_name, serial_version); #ifdef CONFIG_HUB6 @@ -3216,7 +3217,7 @@ EXPORT_SYMBOL(unregister_serial); /* * The serial driver boot-time initialization code! */ -int rs_init(void) +__initfunc(int rs_init(void)) { int i; struct serial_state * state; @@ -3410,6 +3411,7 @@ void cleanup_module(void) timer_active &= ~(1 << RS_TIMER); timer_table[RS_TIMER].fn = NULL; timer_table[RS_TIMER].expires = 0; + remove_bh(SERIAL_BH); if ((e1 = tty_unregister_driver(&serial_driver))) printk("SERIAL: failed to unregister serial driver (%d)\n", e1); diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c index 752013742..d16227d83 100644 --- a/drivers/char/softdog.c +++ b/drivers/char/softdog.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #define WATCHDOG_MINOR 130 @@ -172,7 +173,7 @@ static struct miscdevice softdog_miscdev= &softdog_fops }; -void watchdog_init(void) +__initfunc(void watchdog_init(void)) { misc_register(&softdog_miscdev); init_timer(&watchdog_ticktock); diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 9c2b5e984..7ebb33c14 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -389,10 +390,10 @@ static void stl_flushbuffer(struct tty_struct *tty); static void stl_hangup(struct tty_struct *tty); static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); -static int stl_initbrds(void); +static inline int stl_initbrds(void); static int stl_brdinit(stlbrd_t *brdp); -static int stl_initeio(stlbrd_t *brdp); -static int stl_initech(stlbrd_t *brdp); +static inline int stl_initeio(stlbrd_t *brdp); +static inline int stl_initech(stlbrd_t *brdp); static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp); static int stl_mapirq(int irq); static void stl_getserial(stlport_t *portp, struct serial_struct *sp); @@ -414,7 +415,7 @@ static void *stl_memalloc(int len); static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); #ifdef CONFIG_PCI -static int stl_findpcibrds(void); +static inline int stl_findpcibrds(void); #endif /* @@ -1745,7 +1746,7 @@ static void stl_offintr(void *private) * interrupt across multiple boards. */ -static int stl_mapirq(int irq) +__initfunc(static int stl_mapirq(int irq)) { int rc, i; @@ -1775,7 +1776,7 @@ static int stl_mapirq(int irq) * Initialize all the ports on a panel. */ -static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) +__initfunc(static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)) { stlport_t *portp; int chipmask, i; @@ -1827,7 +1828,7 @@ static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) * Try to find and initialize an EasyIO board. */ -static int stl_initeio(stlbrd_t *brdp) +static inline int stl_initeio(stlbrd_t *brdp) { stlpanel_t *panelp; unsigned int status; @@ -1929,7 +1930,7 @@ static int stl_initeio(stlbrd_t *brdp) * dealing with all types of ECH board. */ -static int stl_initech(stlbrd_t *brdp) +static inline int stl_initech(stlbrd_t *brdp) { stlpanel_t *panelp; unsigned int status, nxtid, ioaddr, conflict; @@ -2096,7 +2097,7 @@ static int stl_initech(stlbrd_t *brdp) * since the initial search and setup is very different. */ -static int stl_brdinit(stlbrd_t *brdp) +__initfunc(static int stl_brdinit(stlbrd_t *brdp)) { int i; @@ -2141,7 +2142,7 @@ static int stl_brdinit(stlbrd_t *brdp) #ifdef CONFIG_PCI -static int stl_findpcibrds() +static inline int stl_findpcibrds() { stlbrd_t *brdp; unsigned char busnr, devnr, irq; @@ -2228,7 +2229,7 @@ static int stl_findpcibrds() * since the initial search and setup is too different. */ -static int stl_initbrds() +static inline int stl_initbrds() { stlbrd_t *brdp; stlconf_t *confp; @@ -2514,7 +2515,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns /*****************************************************************************/ -int stl_init(void) +__initfunc(int stl_init(void)) { printk(KERN_INFO "%s: version %s\n", stl_drvname, stl_drvversion); diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 86b441c4a..0d0f0a4ed 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -71,6 +71,7 @@ #ifdef CONFIG_PROC_FS #include #endif +#include #include #include @@ -1704,7 +1705,7 @@ static struct tty_driver dev_tty_driver, dev_console_driver; * Ok, now we can initialize the rest of the tty devices and can count * on memory allocations, interrupts etc.. */ -int tty_init(void) +__initfunc(int tty_init(void)) { if (sizeof(struct tty_struct) > PAGE_SIZE) panic("size of tty structure > PAGE_SIZE!"); diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 34b579e76..71f4e2f84 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "vt_kern.h" #include "selection.h" @@ -251,7 +252,7 @@ static struct file_operations vcs_fops = { NULL /* fsync */ }; -int vcs_init(void) +__initfunc(int vcs_init(void)) { int error; diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c index 42a9ea216..e32131b63 100644 --- a/drivers/char/wdt.c +++ b/drivers/char/wdt.c @@ -43,6 +43,7 @@ #include #include #include +#include static int wdt_is_open=0; @@ -352,22 +353,7 @@ static struct notifier_block wdt_notifier= #ifdef MODULE -int init_module(void) -{ - printk("WDT501-P module at %X(Interrupt %d)\n", io,irq); - if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL)) - { - printk("IRQ %d is not free.\n", irq); - return -EIO; - } - misc_register(&wdt_miscdev); -#ifdef CONFIG_WDT_501 - misc_register(&temp_miscdev); -#endif - request_region(io, 8, "wdt501"); - notifier_chain_register(&boot_notifier_list, &wdt_notifier); - return 0; -} +#define wdt_init init_module void cleanup_module(void) { @@ -380,9 +366,9 @@ void cleanup_module(void) free_irq(irq, NULL); } -#else +#endif -int wdt_init(void) +__initfunc(int wdt_init(void)) { printk("WDT500/501-P driver at %X(Interrupt %d)\n", io,irq); if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL)) @@ -399,4 +385,3 @@ int wdt_init(void) return 0; } -#endif diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 9a29461b8..d17ea2c93 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -102,12 +102,13 @@ static const char *version = #include #include #include +#include #define BLOCKOUT_2 /* A zero-terminated list of I/O addresses to be probed. The 3c501 can be at many locations, but here are the popular ones. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x280, 0x300, 0}; @@ -208,7 +209,7 @@ struct net_local struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist}; #else -int el1_probe(struct device *dev) +__initfunc(int el1_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -235,7 +236,7 @@ int el1_probe(struct device *dev) * The actual probe. */ -static int el1_probe1(struct device *dev, int ioaddr) +__initfunc(static int el1_probe1(struct device *dev, int ioaddr)) { const char *mname; /* Vendor name */ unsigned char station_addr[6]; diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index d0580f3b4..aa69a74e6 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -42,6 +42,7 @@ static const char *version = #include #include #include +#include #include #include @@ -56,7 +57,7 @@ int el2_pio_probe(struct device *dev); int el2_probe1(struct device *dev, int ioaddr); /* A zero-terminated list of I/O addresses to be probed in PIO mode. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0}; #define EL2_IO_EXTENT 16 @@ -89,8 +90,8 @@ static void el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, If the ethercard isn't found there is an optional probe for ethercard jumpered to programmed-I/O mode. */ -int -el2_probe(struct device *dev) +__initfunc(int +el2_probe(struct device *dev)) { int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0}; int base_addr = dev->base_addr; @@ -124,8 +125,8 @@ el2_probe(struct device *dev) #ifndef HAVE_DEVLIST /* Try all of the locations that aren't obviously empty. This touches a lot of locations, and is much riskier than the code above. */ -int -el2_pio_probe(struct device *dev) +__initfunc(int +el2_pio_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -150,8 +151,8 @@ el2_pio_probe(struct device *dev) /* Probe for the Etherlink II card at I/O port base IOADDR, returning non-zero on success. If found, set the station address and memory parameters in DEVICE. */ -int -el2_probe1(struct device *dev, int ioaddr) +__initfunc(int +el2_probe1(struct device *dev, int ioaddr)) { int i, iobase_reg, membase_reg, saved_406, wordlength; static unsigned version_printed = 0; diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 49a11d4e9..31a64990a 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -108,6 +108,7 @@ #include #include #include +#include #include "3c505.h" @@ -178,7 +179,7 @@ static const int elp_debug = 0; * Last element MUST BE 0! *****************************************************************/ -static const int addr_list[] = {0x300, 0x280, 0x310, 0}; +static const int addr_list[] __initdata = {0x300, 0x280, 0x310, 0}; /* Dma Memory related stuff */ @@ -1305,7 +1306,7 @@ static void elp_set_mc_list(struct device *dev) * ******************************************************/ -static void elp_init(struct device *dev) +static inline void elp_init(struct device *dev) { elp_device *adapter = dev->priv; @@ -1338,7 +1339,7 @@ static void elp_init(struct device *dev) * Called only by elp_autodetect ************************************************************/ -static int elp_sense(struct device *dev) +__initfunc(static int elp_sense(struct device *dev)) { int timeout; int addr = dev->base_addr; @@ -1405,7 +1406,7 @@ static int elp_sense(struct device *dev) * Called only by eplus_probe *************************************************************/ -static int elp_autodetect(struct device *dev) +__initfunc(static int elp_autodetect(struct device *dev)) { int idx = 0; @@ -1449,7 +1450,7 @@ static int elp_autodetect(struct device *dev) * work at all if it was in a weird state). */ -int elplus_probe(struct device *dev) +__initfunc(int elplus_probe(struct device *dev)) { elp_device *adapter; int i, tries, tries1, timeout, okay; diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 819011b9f..00038f96d 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -59,6 +59,7 @@ static const char *version = #include #include #include +#include /* use 0 for production, 1 for verification, 2..7 for debug */ @@ -68,7 +69,7 @@ static const char *version = static unsigned int net_debug = NET_DEBUG; /* A zero-terminated list of common I/O addresses to be probed. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x280, 0}; /* @@ -301,7 +302,7 @@ struct netdev_entry netcard_drv = device and return success. */ -int el16_probe(struct device *dev) +__initfunc(int el16_probe(struct device *dev)) { int base_addr = dev ? dev->base_addr : 0; int i; @@ -322,7 +323,7 @@ int el16_probe(struct device *dev) return ENODEV; } -int el16_probe1(struct device *dev, int ioaddr) +__initfunc(int el16_probe1(struct device *dev, int ioaddr)) { static unsigned char init_ID_done = 0, version_printed = 0; int i, irq, irqval; diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 48208e26a..d3d941d20 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -48,6 +48,7 @@ static char *version = "3c509.c:1.07 6/15/95 becker@cesdis.gsfc.nasa.gov\n"; #include #include /* for CONFIG_MCA */ #include /* for udelay() */ +#include #include #include @@ -132,7 +133,7 @@ static void set_multicast_list(struct device *dev); -int el3_probe(struct device *dev) +__initfunc(int el3_probe(struct device *dev)) { short lrs_state = 0xff, i; ushort ioaddr, irq, if_port; @@ -312,7 +313,7 @@ int el3_probe(struct device *dev) /* Read a word from the EEPROM using the regular EEPROM access register. Assume that we are in register window zero. */ -static ushort read_eeprom(short ioaddr, int index) +__initfunc(static ushort read_eeprom(short ioaddr, int index)) { outw(EEPROM_READ + index, ioaddr + 10); /* Pause for at least 162 us. for the read to take place. */ @@ -321,7 +322,7 @@ static ushort read_eeprom(short ioaddr, int index) } /* Read a word from the EEPROM when in the ISA ID probe state. */ -static ushort id_read_eeprom(int index) +__initfunc(static ushort id_read_eeprom(int index)) { int bit, word = 0; diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index 5fb047f3c..63c6240d3 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -100,6 +100,7 @@ History: #include #include #include +#include #include "3c523.h" @@ -115,9 +116,9 @@ History: /* Tables to which we can map values in the configuration registers. */ -static int irq_table[] = {12, 7, 3, 9}; -static int csr_table[] = {0x300, 0x1300, 0x2300, 0x3300}; -static int shm_table[] = {0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000}; +static int irq_table[] __initdata = {12, 7, 3, 9}; +static int csr_table[] __initdata = {0x300, 0x1300, 0x2300, 0x3300}; +static int shm_table[] __initdata = {0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000}; /******************* how to calculate the buffers ***************************** @@ -308,9 +309,9 @@ elmc_open(struct device *dev) { * Check to see if there's an 82586 out there. */ -static +__initfunc(static int -check586( struct device *dev, char *where, unsigned size) { +check586( struct device *dev, char *where, unsigned size)) { struct priv *p = (struct priv *) dev->priv; char *iscp_addrs[2]; int i = 0; @@ -382,8 +383,8 @@ alloc586( struct device *dev ) { } /*****************************************************************/ -static int -elmc_getinfo( char* buf, int slot, void* d ) { +__initfunc(static int +elmc_getinfo( char* buf, int slot, void* d )) { int len = 0; struct device* dev = (struct device*) d; int i; @@ -411,8 +412,8 @@ elmc_getinfo( char* buf, int slot, void* d ) { } /* elmc_getinfo() */ /*****************************************************************/ -int -elmc_probe(struct device *dev) { +__initfunc(int +elmc_probe(struct device *dev)) { static int slot = 0; int base_addr = dev ? dev->base_addr : 0; int irq = dev ? dev->irq : 0; diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index f66f30d1b..69464b4e9 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -36,6 +36,7 @@ static char *version = "3c59x.c:v0.25 5/17/96 becker@cesdis.gsfc.nasa.gov\n"; #include #include #include +#include #ifdef CONFIG_PCI #include @@ -84,7 +85,7 @@ static int vortex_debug = 1; #endif #ifdef CONFIG_PCI -static int product_ids[] = {0x5900, 0x5950, 0x5951, 0x5952, 0, 0}; +static int product_ids[] __initdata = {0x5900, 0x5950, 0x5951, 0x5952, 0, 0}; #endif static const char *product_names[] = { @@ -326,7 +327,7 @@ init_module(void) } #else -int tc59x_probe(struct device *dev) +__initfunc(int tc59x_probe(struct device *dev)) { int cards_found = 0; @@ -339,7 +340,7 @@ int tc59x_probe(struct device *dev) } #endif /* not MODULE */ -static int vortex_scan(struct device *dev) +__initfunc(static int vortex_scan(struct device *dev)) { int cards_found = 0; @@ -420,8 +421,8 @@ static int vortex_scan(struct device *dev) return cards_found; } -static int vortex_found_device(struct device *dev, int ioaddr, int irq, - int product_index, int options) +__initfunc(static int vortex_found_device(struct device *dev, int ioaddr, int irq, + int product_index, int options)) { struct vortex_private *vp; @@ -480,7 +481,7 @@ static int vortex_found_device(struct device *dev, int ioaddr, int irq, return 0; } -static int vortex_probe1(struct device *dev) +__initfunc(static int vortex_probe1(struct device *dev)) { int ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; diff --git a/drivers/net/8390.c b/drivers/net/8390.c index c51f13074..fbf67cb42 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -58,6 +58,7 @@ static const char *version = #include #include #include +#include #include #include @@ -771,7 +772,7 @@ static void set_multicast_list(struct device *dev) } /* Initialize the rest of the 8390 device structure. */ -int ethdev_init(struct device *dev) +__initfunc(int ethdev_init(struct device *dev)) { if (ei_debug > 1) printk(version); diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 414afff85..b62102e7a 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -734,7 +735,7 @@ static void lance_set_multicast (struct device *dev) } -int a2065_probe(struct device *dev) +__initfunc(int a2065_probe(struct device *dev)) { int key1, key2 = 0; struct ConfigDev *cd; diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index f70570ddf..63af6498b 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -25,6 +25,7 @@ static const char *version = #include #include #include +#include #include #include @@ -54,7 +55,7 @@ static const char *version = */ /* Decoding of the configuration register. */ -static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3}; +static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; static int addrmap[8] = {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 }; static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"}; @@ -88,7 +89,7 @@ static int ac_close_card(struct device *dev); or the unique value in the station address PROM. */ -int ac3200_probe(struct device *dev) +__initfunc(int ac3200_probe(struct device *dev)) { unsigned short ioaddr = dev->base_addr; @@ -111,7 +112,7 @@ int ac3200_probe(struct device *dev) return ENODEV; } -static int ac_probe1(int ioaddr, struct device *dev) +__initfunc(static int ac_probe1(int ioaddr, struct device *dev)) { int i; diff --git a/drivers/net/apricot.c b/drivers/net/apricot.c index b839ae26f..2a00c4481 100644 --- a/drivers/net/apricot.c +++ b/drivers/net/apricot.c @@ -34,6 +34,7 @@ static const char *version = "apricot.c:v0.2 05/12/94\n"; #include #include #include +#include #include #include @@ -675,7 +676,7 @@ static void print_eth(char *add) printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]); } -int apricot_probe(struct device *dev) +__initfunc(int apricot_probe(struct device *dev)) { int i; struct i596_private *lp; @@ -1001,7 +1002,7 @@ static void set_multicast_list(struct device *dev) } #ifdef HAVE_DEVLIST -static unsigned int apricot_portlist[] = {0x300, 0}; +static unsigned int apricot_portlist[] __initdata = {0x300, 0}; struct netdev_entry apricot_drv = {"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist}; #endif diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index cc5faa093..b25dd02c2 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -162,6 +162,7 @@ static const char *version = #include #include #include +#include #include #include @@ -711,7 +712,7 @@ void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,char *desc) * need to be passed a specific shmem address, IRQ, and node ID (stored in * dev->base_addr) */ -int arcnet_probe(struct device *dev) +__initfunc(int arcnet_probe(struct device *dev)) { BUGLVL(D_NORMAL) printk(version); BUGMSG(D_NORMAL,"Compiled for ARCnet RIM I (autoprobe disabled)\n"); @@ -749,11 +750,13 @@ int arcnet_probe(struct device *dev) * * FIXME: grab all devices in one shot and eliminate the big static array. */ -int arcnet_probe(struct device *dev) + +static int ports[(0x3f0 - 0x200) / 16 + 1] __initdata; +static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata; + +__initfunc(int arcnet_probe(struct device *dev)) { static int init_once = 0; - static int ports[(0x3f0 - 0x200) / 16 + 1]; - static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1]; static int numports=sizeof(ports)/sizeof(ports[0]), numshmems=sizeof(shmems)/sizeof(shmems[0]); @@ -1126,7 +1129,7 @@ int arcnet_probe(struct device *dev) /* Set up the struct device associated with this card. Called after * probing succeeds. */ -int arcnet_found(struct device *dev,int port,int airq, u_long shmem) +__initfunc(int arcnet_found(struct device *dev,int port,int airq, u_long shmem)) { u_long first_mirror,last_mirror; struct arcnet_local *lp; diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index 5dbd2985a..290b9761e 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -145,7 +146,7 @@ static void memcpyw(u_short *dest, u_short *src, int len) } -int ariadne_probe(struct device *dev) +__initfunc(int ariadne_probe(struct device *dev)) { int key; struct ConfigDev *cd; diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index bd160c876..bd1f93846 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -48,13 +48,14 @@ static const char *version = #include #include #include +#include #include #include #include /* This unusual address order is used to verify the CONFIG register. */ -static int at1700_probe_list[] = +static int at1700_probe_list[] __initdata = {0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -136,8 +137,8 @@ static void set_multicast_list(struct device *dev); struct netdev_entry at1700_drv = {"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list}; #else -int -at1700_probe(struct device *dev) +__initfunc(int +at1700_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -167,7 +168,7 @@ at1700_probe(struct device *dev) that can be done is checking a few bits and then diving right into an EEPROM read. */ -int at1700_probe1(struct device *dev, short ioaddr) +__initfunc(int at1700_probe1(struct device *dev, short ioaddr)) { char irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15}; unsigned int i, irq; @@ -275,7 +276,7 @@ int at1700_probe1(struct device *dev, short ioaddr) return 0; } -static int read_eeprom(int ioaddr, int location) +__initfunc(static int read_eeprom(int ioaddr, int location)) { int i; unsigned short retval = 0; diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c index f0b781bcf..dc761ab7c 100644 --- a/drivers/net/atari_bionet.c +++ b/drivers/net/atari_bionet.c @@ -95,6 +95,7 @@ static char *version = #include #include #include +#include #include #include @@ -321,8 +322,8 @@ end: /* Check for a network adaptor of this type, and return '0' if one exists. */ -int -bionet_probe(struct device *dev) { +__initfunc(int +bionet_probe(struct device *dev)) { unsigned char station_addr[6]; static unsigned version_printed = 0; static int no_more_found = 0; /* avoid "Probing for..." printed 4 times */ diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c index 72056f1b3..bcf91beda 100644 --- a/drivers/net/atari_pamsnet.c +++ b/drivers/net/atari_pamsnet.c @@ -102,6 +102,7 @@ static char *version = #include #include +#include #include #include @@ -560,8 +561,8 @@ bad: /* Check for a network adaptor of this type, and return '0' if one exists. */ -extern int -pamsnet_probe (dev) +__initfunc(extern int +pamsnet_probe (dev)) struct device *dev; { int i; diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 9b8f4d45c..bb08b8927 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -55,6 +55,7 @@ static char *version = "atarilance.c: v1.3 04/04/96 " #include #include #include +#include #include #include @@ -369,7 +370,7 @@ void *slow_memcpy( void *dst, const void *src, size_t len ) } -int atarilance_probe( struct device *dev ) +__initfunc(int atarilance_probe( struct device *dev )) { int i; static int found = 0; @@ -392,7 +393,7 @@ int atarilance_probe( struct device *dev ) /* Derived from hwreg_present() in atari/config.c: */ -static int addr_accessible( volatile void *regp, int wordflag, int writeflag ) +__initfunc(static int addr_accessible( volatile void *regp, int wordflag, int writeflag )) { int ret; long flags; @@ -442,8 +443,8 @@ static int addr_accessible( volatile void *regp, int wordflag, int writeflag ) } -static unsigned long lance_probe1( struct device *dev, - struct lance_addr *init_rec ) +__initfunc(static unsigned long lance_probe1( struct device *dev, + struct lance_addr *init_rec )) { volatile unsigned short *memaddr = (volatile unsigned short *)init_rec->memaddr; diff --git a/drivers/net/atp.c b/drivers/net/atp.c index 4fdbed39d..411374119 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -96,6 +96,7 @@ static const char *version = #include #include #include +#include #include #include @@ -149,8 +150,8 @@ static void set_multicast_list(struct device *dev); If dev->base_addr == 2, allocate space for the device and return success (detachable devices only). */ -int -atp_init(struct device *dev) +__initfunc(int +atp_init(struct device *dev)) { int *port, ports[] = {0x378, 0x278, 0x3bc, 0}; int base_addr = dev->base_addr; @@ -172,7 +173,7 @@ atp_init(struct device *dev) return ENODEV; } -static int atp_probe1(struct device *dev, short ioaddr) +__initfunc(static int atp_probe1(struct device *dev, short ioaddr)) { int saved_ctrl_reg, status; @@ -258,7 +259,7 @@ static int atp_probe1(struct device *dev, short ioaddr) } /* Read the station address PROM, usually a word-wide EEPROM. */ -static void get_node_ID(struct device *dev) +__initfunc(static void get_node_ID(struct device *dev)) { short ioaddr = dev->base_addr; int sa_offset = 0; @@ -290,7 +291,7 @@ static void get_node_ID(struct device *dev) * DO : _________X_______X */ -static unsigned short eeprom_op(short ioaddr, unsigned int cmd) +__initfunc(static unsigned short eeprom_op(short ioaddr, unsigned int cmd)) { unsigned eedata_out = 0; int num_bits = EE_CMD_SIZE; diff --git a/drivers/net/baycom.c b/drivers/net/baycom.c index 5506c1750..7569d66e7 100644 --- a/drivers/net/baycom.c +++ b/drivers/net/baycom.c @@ -89,6 +89,7 @@ #include #include #include +#include /* --------------------------------------------------------------------- */ @@ -936,7 +937,7 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, /* --------------------------------------------------------------------- */ -int baycom_init(void) +__initfunc(int baycom_init(void)) { int i, j, found = 0; char set_hw = 1; @@ -1038,7 +1039,7 @@ void cleanup_module(void) * * indicates sofware DCD */ -void baycom_setup(char *str, int *ints) +__initfunc(void baycom_setup(char *str, int *ints)) { int i; diff --git a/drivers/net/bpqether.c b/drivers/net/bpqether.c index 11e073a23..ca1bcc9c7 100644 --- a/drivers/net/bpqether.c +++ b/drivers/net/bpqether.c @@ -82,6 +82,7 @@ #include #include #include +#include #include #include @@ -632,7 +633,7 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi * Initialize driver. To be called from af_ax25 if not compiled as a * module */ -int bpq_init(void) +__initfunc(int bpq_init(void)) { struct device *dev; diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 2497ab88b..6a38177b6 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -78,6 +78,7 @@ static char *version = #include #include #include +#include #include #include @@ -86,7 +87,7 @@ static char *version = /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int net_debug = NET_DEBUG; @@ -145,8 +146,8 @@ static int set_mac_address(struct device *dev, void *addr); struct netdev_entry netcard_drv = {"netcard", cs89x0_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else -int -cs89x0_probe(struct device *dev) +__initfunc(int +cs89x0_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -195,8 +196,8 @@ writeword(struct device *dev, int portno, int value) outw(value, dev->base_addr + portno); } -static int -wait_eeprom_ready(struct device *dev) +__initfunc(static int +wait_eeprom_ready(struct device *dev)) { int timeout = jiffies; /* check to see if the EEPROM is ready, a timeout is used - @@ -208,8 +209,8 @@ wait_eeprom_ready(struct device *dev) return 0; } -int -get_eeprom_data(struct device *dev, int off, int len, int *buffer) +__initfunc(static int +get_eeprom_data(struct device *dev, int off, int len, int *buffer)) { int i; @@ -226,8 +227,8 @@ get_eeprom_data(struct device *dev, int off, int len, int *buffer) return 0; } -int -get_eeprom_cksum(int off, int len, int *buffer) +__initfunc(static int +get_eeprom_cksum(int off, int len, int *buffer)) { int i, cksum; @@ -244,7 +245,7 @@ get_eeprom_cksum(int off, int len, int *buffer) probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int cs89x0_probe1(struct device *dev, int ioaddr) +__initfunc(static int cs89x0_probe1(struct device *dev, int ioaddr)) { struct net_local *lp; static unsigned version_printed = 0; @@ -392,8 +393,8 @@ static int cs89x0_probe1(struct device *dev, int ioaddr) -void -reset_chip(struct device *dev) +__initfunc(void +reset_chip(struct device *dev)) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index fcf8cc167..aae249ed0 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -266,6 +266,7 @@ static const char *version = "de4x5.c:V0.5 97/1/30 davies@maniac.ultranet.com\n" #include #include #include +#include #include #include #include @@ -861,8 +862,8 @@ static int (*dc_infoblock[])(struct device *dev, u_char, u_char *) = { ** more info. Until I fix (un)register_netdevice() we won't be able to use it ** though. */ -int -de4x5_probe(struct device *dev) +__initfunc(int +de4x5_probe(struct device *dev)) { int status = -ENODEV; u_long iobase = dev->base_addr; @@ -882,8 +883,8 @@ de4x5_probe(struct device *dev) return status; } -static int -de4x5_hw_init(struct device *dev, u_long iobase) +__initfunc(static int +de4x5_hw_init(struct device *dev, u_long iobase)) { struct bus_type *lp = &bus; int i, status=0; @@ -1797,8 +1798,8 @@ SetMulticastFilter(struct device *dev) ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. Upto 15 EISA devices are supported. */ -static void -eisa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void +eisa_probe(struct device *dev, u_long ioaddr)) { int i, maxSlots, status, device; u_short vendor; @@ -1874,8 +1875,8 @@ eisa_probe(struct device *dev, u_long ioaddr) #define PCI_DEVICE (dev_num << 3) #define PCI_LAST_DEV 32 -static void -pci_probe(struct device *dev, u_long ioaddr) +__initfunc(static void +pci_probe(struct device *dev, u_long ioaddr)) { u_char irq; u_char pb, pbus, dev_num, dnum, dev_fn; @@ -1974,8 +1975,8 @@ pci_probe(struct device *dev, u_long ioaddr) ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * -alloc_device(struct device *dev, u_long iobase) +__initfunc(static struct device * +alloc_device(struct device *dev, u_long iobase)) { struct device *adev = NULL; int fixed = 0, new_dev = 0; @@ -2027,8 +2028,8 @@ alloc_device(struct device *dev, u_long iobase) ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +__initfunc(static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))) { struct device *new; @@ -2055,8 +2056,8 @@ insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) return new; } -static int -de4x5_dev_index(char *s) +__initfunc(static int +de4x5_dev_index(char *s)) { int i=0, j=0; @@ -2070,8 +2071,8 @@ de4x5_dev_index(char *s) return i; } -static void -link_modules(struct device *dev, struct device *tmp) +__initfunc(static void +link_modules(struct device *dev, struct device *tmp)) { struct device *p=dev; diff --git a/drivers/net/de600.c b/drivers/net/de600.c index 84d77f6a3..700c95a75 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -103,6 +103,7 @@ static const char *version = #include #include #include +#include #include #include @@ -624,8 +625,8 @@ de600_rx_intr(struct device *dev) */ } -int -de600_probe(struct device *dev) +__initfunc(int +de600_probe(struct device *dev)) { int i; static struct net_device_stats de600_netstats; diff --git a/drivers/net/de620.c b/drivers/net/de620.c index dfcf54b7b..60bc9229d 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -131,6 +131,7 @@ static const char *version = #include #include #include +#include #include #include @@ -822,8 +823,8 @@ adapter_init(struct device *dev) * * Check if there is a DE-620 connected */ -int -de620_probe(struct device *dev) +__initfunc(int +de620_probe(struct device *dev)) { static struct net_device_stats de620_netstats; int i; @@ -915,8 +916,8 @@ de620_probe(struct device *dev) */ #define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); -static unsigned short -ReadAWord(struct device *dev, int from) +__initfunc(static unsigned short +ReadAWord(struct device *dev, int from)) { unsigned short data; int nbits; @@ -958,8 +959,8 @@ ReadAWord(struct device *dev, int from) return data; } -static int -read_eeprom(struct device *dev) +__initfunc(static int +read_eeprom(struct device *dev)) { unsigned short wrd; diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index fce95ff35..5e50cbfa5 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -215,6 +215,7 @@ static const char *version = "defxx.c:v1.04 09/16/96 Lawrence V. Stefani (stefa #include #include #include +#include #include #include #include @@ -437,9 +438,9 @@ static inline void dfx_port_read_long( * the device structure. */ -int dfx_probe( +__initfunc(int dfx_probe( struct device *dev - ) + )) { int i; /* used in for loops */ @@ -636,10 +637,10 @@ int dfx_probe( * None */ -struct device *dfx_alloc_device( +__initfunc(struct device *dfx_alloc_device( struct device *dev, u16 iobase - ) + )) { struct device *tmp_dev; /* pointer to a device structure */ @@ -731,9 +732,9 @@ struct device *dfx_alloc_device( * enabled yet. */ -void dfx_bus_init( +__initfunc(void dfx_bus_init( struct device *dev - ) + )) { DFX_board_t *bp = (DFX_board_t *)dev->priv; @@ -865,9 +866,9 @@ void dfx_bus_init( * None */ -void dfx_bus_config_check( +__initfunc(void dfx_bus_config_check( DFX_board_t *bp - ) + )) { int status; /* return code from adapter port control call */ @@ -969,9 +970,9 @@ void dfx_bus_config_check( * returning from this routine. */ -int dfx_driver_init( +__initfunc(int dfx_driver_init( struct device *dev - ) + )) { DFX_board_t *bp = (DFX_board_t *)dev->priv; diff --git a/drivers/net/depca.c b/drivers/net/depca.c index c1c4a299e..85cf704c5 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -219,6 +219,7 @@ static const char *version = "depca.c:v0.43 96/8/16 davies@maniac.ultranet.com\n #include #include #include +#include #include #include #include @@ -418,9 +419,9 @@ int init_module(void); void cleanup_module(void); static int autoprobed = 1, loading_module = 1; # else -static u_char de1xx_irq[] = {2,3,4,5,7,9,0}; -static u_char de2xx_irq[] = {5,9,10,11,15,0}; -static u_char de422_irq[] = {5,9,10,11,0}; +static u_char de1xx_irq[] __initdata = {2,3,4,5,7,9,0}; +static u_char de2xx_irq[] __initdata = {5,9,10,11,15,0}; +static u_char de422_irq[] __initdata = {5,9,10,11,0}; static u_char *depca_irq; static int autoprobed = 0, loading_module = 0; #endif /* MODULE */ @@ -441,7 +442,7 @@ static char *adapter_name = '\0'; /* If no PROM when loadable module -int depca_probe(struct device *dev) +__initfunc(int depca_probe(struct device *dev)) { int tmp = num_depcas, status = -ENODEV; u_long iobase = dev->base_addr; @@ -471,8 +472,8 @@ int depca_probe(struct device *dev) return status; } -static int -depca_hw_init(struct device *dev, u_long ioaddr) +__initfunc(static int +depca_hw_init(struct device *dev, u_long ioaddr)) { struct depca_private *lp; int i, j, offset, netRAM, mem_len, status=0; @@ -1207,7 +1208,7 @@ static void SetMulticastFilter(struct device *dev) /* ** ISA bus I/O device probe */ -static void isa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void isa_probe(struct device *dev, u_long ioaddr)) { int i = num_depcas, maxSlots; s32 ports[] = DEPCA_IO_PORTS; @@ -1245,7 +1246,7 @@ static void isa_probe(struct device *dev, u_long ioaddr) ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. Upto 15 EISA devices are supported. */ -static void eisa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void eisa_probe(struct device *dev, u_long ioaddr)) { int i, maxSlots; u_long iobase; @@ -1291,8 +1292,8 @@ static void eisa_probe(struct device *dev, u_long ioaddr) ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * -alloc_device(struct device *dev, u_long iobase) +__initfunc(static struct device * +alloc_device(struct device *dev, u_long iobase)) { struct device *adev = NULL; int fixed = 0, new_dev = 0; @@ -1336,8 +1337,8 @@ alloc_device(struct device *dev, u_long iobase) ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +__initfunc(static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))) { struct device *new; @@ -1362,8 +1363,8 @@ insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) return dev; } -static int -depca_dev_index(char *s) +__initfunc(static int +depca_dev_index(char *s)) { int i=0, j=0; @@ -1382,7 +1383,7 @@ depca_dev_index(char *s) ** and Boot (readb) ROM. This will also give us a clue to the network RAM ** base address. */ -static void DepcaSignature(char *name, u_long paddr) +__initfunc(static void DepcaSignature(char *name, u_long paddr)) { u_int i,j,k; const char *signatures[] = DEPCA_SIGNATURE; @@ -1434,7 +1435,7 @@ static void DepcaSignature(char *name, u_long paddr) ** PROM address counter is correctly positioned at the start of the ** ethernet address for later read out. */ -static int DevicePresent(u_long ioaddr) +__initfunc(static int DevicePresent(u_long ioaddr)) { union { struct { @@ -1486,7 +1487,7 @@ static int DevicePresent(u_long ioaddr) ** reason: access the upper half of the PROM with x=0; access the lower half ** with x=1. */ -static int get_hw_addr(struct device *dev) +__initfunc(static int get_hw_addr(struct device *dev)) { u_long ioaddr = dev->base_addr; int i, k, tmp, status = 0; @@ -1574,7 +1575,7 @@ static int load_packet(struct device *dev, struct sk_buff *skb) /* ** Look for a particular board name in the EISA configuration space */ -static int EISA_signature(char *name, s32 eisa_id) +__initfunc(static int EISA_signature(char *name, s32 eisa_id)) { u_int i; const char *signatures[] = DEPCA_SIGNATURE; diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index b38065030..1a9d48827 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -88,6 +88,7 @@ static char *version = "$Id: dgrs.c,v 1.12 1996/12/21 13:43:58 rick Exp $"; #include #include #include +#include #include #include #include @@ -990,8 +991,8 @@ ack_intr: /* * Download the board firmware */ -static int -dgrs_download(struct device *dev0) +__initfunc(static int +dgrs_download(struct device *dev0)) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; int is; @@ -1149,8 +1150,8 @@ dgrs_download(struct device *dev0) /* * Probe (init) a board */ -int -dgrs_probe1(struct device *dev) +__initfunc(int +dgrs_probe1(struct device *dev)) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1223,8 +1224,8 @@ dgrs_probe1(struct device *dev) return (0); } -int -dgrs_initclone(struct device *dev) +__initfunc(int +dgrs_initclone(struct device *dev)) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1238,7 +1239,7 @@ dgrs_initclone(struct device *dev) return (0); } -static int +__initfunc(static int dgrs_found_device( struct device *dev, int io, @@ -1246,7 +1247,7 @@ dgrs_found_device( int irq, ulong plxreg, ulong plxdma -) +)) { DGRS_PRIV *priv; int i; @@ -1357,8 +1358,8 @@ dgrs_found_device( /* * Scan for all boards */ -static int -dgrs_scan(struct device *dev) +__initfunc(static int +dgrs_scan(struct device *dev)) { int cards_found = 0; uint io; @@ -1462,7 +1463,7 @@ dgrs_scan(struct device *dev) */ if (EISA_bus) { - static int is2iv[8] = { 0, 3, 5, 7, 10, 11, 12, 15 }; + static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 }; for (io = 0x1000; io < 0x9000; io += 0x1000) { @@ -1600,8 +1601,8 @@ cleanup_module(void) #else -int -dgrs_probe(struct device *dev) +__initfunc(int +dgrs_probe(struct device *dev)) { int cards_found; diff --git a/drivers/net/dgrs_firmware.c b/drivers/net/dgrs_firmware.c index f76bddb58..8641eadd8 100644 --- a/drivers/net/dgrs_firmware.c +++ b/drivers/net/dgrs_firmware.c @@ -1,7 +1,7 @@ int dgrs_firmnum = 550; char dgrs_firmver[] = "$Version$"; char dgrs_firmdate[] = "11/16/96 03:45:15"; -unsigned char dgrs_code[] = { +unsigned char dgrs_code[] __initdata = { 213,5,192,8,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,64,40,35,41, diff --git a/drivers/net/dlci.c b/drivers/net/dlci.c index 953f02b28..e42b0dcf4 100644 --- a/drivers/net/dlci.c +++ b/drivers/net/dlci.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -606,7 +607,7 @@ int dlci_init(struct device *dev) return(0); } -int dlci_setup(void) +__initfunc(int dlci_setup(void)) { int i; diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 445b1d81f..814d798c5 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +73,7 @@ static void set_multicast_list(struct device *dev) { } -int dummy_init(struct device *dev) +__initfunc(int dummy_init(struct device *dev)) { /* Initialize the device structure. */ dev->hard_start_xmit = dummy_xmit; @@ -115,7 +116,7 @@ static struct net_device_stats *dummy_get_stats(struct device *dev) #ifdef MODULE -static int dummy_probe(struct device *dev) +__initfunc(static int dummy_probe(struct device *dev)) { dummy_init(dev); return 0; diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index f68227ab1..4b6e67daf 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -43,6 +43,7 @@ static const char *version = #include #include #include +#include #include #include @@ -115,7 +116,7 @@ static int e21_close(struct device *dev); station address). */ -int e2100_probe(struct device *dev) +__initfunc(int e2100_probe(struct device *dev)) { int *port; int base_addr = dev->base_addr; @@ -135,7 +136,7 @@ int e2100_probe(struct device *dev) return ENODEV; } -int e21_probe1(struct device *dev, int ioaddr) +__initfunc(int e21_probe1(struct device *dev, int ioaddr)) { int i, status; unsigned char *station_addr = dev->dev_addr; diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 5719a7c1c..72060c53b 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -101,6 +101,7 @@ static const char *version = #include #include #include +#include #include #include @@ -109,7 +110,7 @@ static const char *version = /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int eepro_portlist[] = +static unsigned int eepro_portlist[] __initdata = { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0x360, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -305,8 +306,8 @@ buffer (transmit-buffer = 32K - receive-buffer). struct netdev_entry netcard_drv = {"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist}; #else -int -eepro_probe(struct device *dev) +__initfunc(int +eepro_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -332,7 +333,7 @@ eepro_probe(struct device *dev) probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -int eepro_probe1(struct device *dev, short ioaddr) +__initfunc(int eepro_probe1(struct device *dev, short ioaddr)) { unsigned short station_addr[6], id, counter; int i; diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index eb2690ff9..cf67f942b 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -55,6 +55,7 @@ static int rxdmacount = 0; /* Rx DMA length, 0 means no preemption. */ #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include @@ -458,7 +459,7 @@ static int debug = -1; /* The debug level */ static struct device *root_speedo_dev = NULL; #endif -int eepro100_init(struct device *dev) +__initfunc(int eepro100_init(struct device *dev)) { int cards_found = 0; @@ -521,7 +522,7 @@ int eepro100_init(struct device *dev) return cards_found; } -static void speedo_found1(struct device *dev, int ioaddr, int irq, int options) +__initfunc(static void speedo_found1(struct device *dev, int ioaddr, int irq, int options)) { static int did_version = 0; /* Already printed version info. */ struct speedo_private *sp; @@ -714,7 +715,7 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options) #define EE_READ_CMD (6 << 6) #define EE_ERASE_CMD (7 << 6) -static int read_eeprom(int ioaddr, int location) +__initfunc(static int read_eeprom(int ioaddr, int location)) { int i; unsigned short retval = 0; @@ -1710,7 +1711,7 @@ cleanup_module(void) } } #else /* not MODULE */ -int eepro100_probe(struct device *dev) +__initfunc(int eepro100_probe(struct device *dev)) { int cards_found = 0; diff --git a/drivers/net/eql.c b/drivers/net/eql.c index 17d273381..820d5b428 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -130,6 +130,7 @@ static const char *version = #include #include #include +#include #include #include @@ -208,7 +209,7 @@ static void eql_timer(unsigned long param); /* */ --------------------------------------------------------- */ -int eql_init(struct device *dev) +__initfunc(int eql_init(struct device *dev)) { static unsigned version_printed = 0; /* static unsigned num_masters = 0; */ diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c index f67e5a4a9..96ffd43de 100644 --- a/drivers/net/es3210.c +++ b/drivers/net/es3210.c @@ -53,6 +53,7 @@ static const char *version = #include #include #include +#include #include #include @@ -114,8 +115,8 @@ static void es_block_output(struct device *dev, int count, const unsigned char * #define ES_DEBUG 0 -static unsigned char lo_irq_map[] = {3, 4, 5, 6, 7, 9, 10}; -static unsigned char hi_irq_map[] = {11, 12, 0, 14, 0, 0, 0, 15}; +static unsigned char lo_irq_map[] __initdata = {3, 4, 5, 6, 7, 9, 10}; +static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15}; /* * Probe for the card. The best way is to read the EISA ID if it @@ -123,7 +124,7 @@ static unsigned char hi_irq_map[] = {11, 12, 0, 14, 0, 0, 0, 15}; * PROM for a match against the Racal-Interlan assigned value. */ -int es_probe(struct device *dev) +__initfunc(int es_probe(struct device *dev)) { unsigned short ioaddr = dev->base_addr; @@ -150,7 +151,7 @@ int es_probe(struct device *dev) return ENODEV; } -int es_probe1(struct device *dev, int ioaddr) +__initfunc(int es_probe1(struct device *dev, int ioaddr)) { int i; unsigned long eisa_id; diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 2d0a2147e..24e449390 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -87,6 +87,7 @@ static char *version = #include #include #include +#include #include #include @@ -275,22 +276,22 @@ static char *version = #define RESET ID_ROM_0 /* This is the I/O address list to be probed when seeking the card */ -static unsigned int eth16i_portlist[] = { +static unsigned int eth16i_portlist[] __initdata = { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 }; -static unsigned int eth32i_portlist[] = { +static unsigned int eth32i_portlist[] __initdata = { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 }; /* This is the Interrupt lookup table for Eth16i card */ -static unsigned int eth16i_irqmap[] = { +static unsigned int eth16i_irqmap[] __initdata = { 9, 10, 5, 15 }; /* This is the Interrupt lookup table for Eth32i card */ -static unsigned int eth32i_irqmap[] = { +static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15 }; @@ -350,7 +351,7 @@ static char *cardname = "ICL EtherTeam 16i/32"; {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; #else /* Not HAVE_DEVLIST */ -int eth16i_probe(struct device *dev) +__initfunc(int eth16i_probe(struct device *dev)) { int i; int ioaddr; @@ -384,7 +385,7 @@ int eth16i_probe(struct device *dev) } #endif /* Not HAVE_DEVLIST */ -static int eth16i_probe1(struct device *dev, short ioaddr) +__initfunc(static int eth16i_probe1(struct device *dev, short ioaddr)) { static unsigned version_printed = 0; unsigned int irq = 0; diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 17b5c9bdf..3c3752251 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -149,6 +149,7 @@ static const char *version = "ewrk3.c:v0.43 96/8/16 davies@maniac.ultranet.com\n #include #include #include +#include #include #include #include @@ -344,7 +345,7 @@ static int num_ewrk3s = 0, num_eth = 0; -int ewrk3_probe(struct device *dev) +__initfunc(int ewrk3_probe(struct device *dev)) { int tmp = num_ewrk3s, status = -ENODEV; u_long iobase = dev->base_addr; @@ -375,8 +376,8 @@ int ewrk3_probe(struct device *dev) return status; } -static int -ewrk3_hw_init(struct device *dev, u_long iobase) +__initfunc(static int +ewrk3_hw_init(struct device *dev, u_long iobase)) { struct ewrk3_private *lp; int i, status=0; @@ -1289,7 +1290,7 @@ static void SetMulticastFilter(struct device *dev) /* ** ISA bus I/O device probe */ -static void isa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void isa_probe(struct device *dev, u_long ioaddr)) { int i = num_ewrk3s, maxSlots; u_long iobase; @@ -1327,7 +1328,7 @@ static void isa_probe(struct device *dev, u_long ioaddr) ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. */ -static void eisa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void eisa_probe(struct device *dev, u_long ioaddr)) { int i, maxSlots; u_long iobase; @@ -1372,8 +1373,8 @@ static void eisa_probe(struct device *dev, u_long ioaddr) ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * -alloc_device(struct device *dev, u_long iobase) +__initfunc(static struct device * +alloc_device(struct device *dev, u_long iobase)) { struct device *adev = NULL; int fixed = 0, new_dev = 0; @@ -1417,8 +1418,8 @@ alloc_device(struct device *dev, u_long iobase) ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +__initfunc(static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))) { struct device *new; @@ -1443,8 +1444,8 @@ insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) return dev; } -static int -ewrk3_dev_index(char *s) +__initfunc(static int +ewrk3_dev_index(char *s)) { int i=0, j=0; @@ -1494,7 +1495,7 @@ static int Write_EEPROM(short data, u_long iobase, u_char eaddr) /* ** Look for a particular board name in the on-board EEPROM. */ -static void EthwrkSignature(char *name, char *eeprom_image) +__initfunc(static void EthwrkSignature(char *name, char *eeprom_image)) { u_long i,j,k; char *signatures[] = EWRK3_SIGNATURE; @@ -1531,7 +1532,7 @@ static void EthwrkSignature(char *name, char *eeprom_image) ** ethernet address for later read out. */ -static int DevicePresent(u_long iobase) +__initfunc(static int DevicePresent(u_long iobase)) { union { struct { @@ -1568,7 +1569,7 @@ static int DevicePresent(u_long iobase) return status; } -static u_char get_hw_addr(struct device *dev, u_char *eeprom_image, char chipType) +__initfunc(static u_char get_hw_addr(struct device *dev, u_char *eeprom_image, char chipType)) { int i, j, k; u_short chksum; @@ -1614,7 +1615,7 @@ static u_char get_hw_addr(struct device *dev, u_char *eeprom_image, char chipTyp /* ** Look for a particular board name in the EISA configuration space */ -static int EISA_signature(char *name, s32 eisa_id) +__initfunc(static int EISA_signature(char *name, s32 eisa_id)) { u_long i; char *signatures[] = EWRK3_SIGNATURE; diff --git a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c index d95f1e29f..7536a7e04 100644 --- a/drivers/net/fmv18x.c +++ b/drivers/net/fmv18x.c @@ -46,6 +46,7 @@ static const char *version = #include #include #include +#include #include #include #include @@ -57,7 +58,7 @@ static const char *version = #include #include -static int fmv18x_probe_list[] = +static int fmv18x_probe_list[] __initdata = {0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -129,8 +130,8 @@ static void set_multicast_list(struct device *dev); struct netdev_entry fmv18x_drv = {"fmv18x", fmv18x_probe1, FMV18X_IO_EXTENT, fmv18x_probe_list}; #else -int -fmv18x_probe(struct device *dev) +__initfunc(int +fmv18x_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -160,7 +161,7 @@ fmv18x_probe(struct device *dev) that can be done is checking a few bits and then diving right into MAC address check. */ -int fmv18x_probe1(struct device *dev, short ioaddr) +__initfunc(int fmv18x_probe1(struct device *dev, short ioaddr)) { char irqmap[4] = {3, 7, 10, 15}; unsigned int i, irq; diff --git a/drivers/net/hdlcdrv.c b/drivers/net/hdlcdrv.c index 70039edfe..9098fdf2e 100644 --- a/drivers/net/hdlcdrv.c +++ b/drivers/net/hdlcdrv.c @@ -277,7 +277,6 @@ static void hdlc_rx_flag(struct device *dev, struct hdlcdrv_state *s) memcpy(cp, s->hdlcrx.buffer, pkt_len - 1); skb->protocol = htons(ETH_P_AX25); skb->mac.raw = skb->data; - IS_SKB(skb); netif_rx(skb); s->stats.rx_packets++; } diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 635b9764a..b7f85f735 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -30,6 +30,7 @@ static const char *version = #include #include #include +#include #include #include @@ -38,7 +39,7 @@ static const char *version = #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int hpplus_portlist[] = +static unsigned int hpplus_portlist[] __initdata = {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0}; /* @@ -121,7 +122,7 @@ struct netdev_entry hpplus_drv = {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist}; #else -int hp_plus_probe(struct device *dev) +__initfunc(int hp_plus_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -144,7 +145,7 @@ int hp_plus_probe(struct device *dev) #endif /* Do the interesting part of the probe at a single address. */ -int hpp_probe1(struct device *dev, int ioaddr) +__initfunc(int hpp_probe1(struct device *dev, int ioaddr)) { int i; unsigned char checksum = 0; diff --git a/drivers/net/hp.c b/drivers/net/hp.c index 531d5f20f..d57763e46 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -30,6 +30,7 @@ static const char *version = #include #include #include +#include #include #include @@ -37,7 +38,7 @@ static const char *version = #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int hppclan_portlist[] = +static unsigned int hppclan_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0}; #define HP_IO_EXTENT 32 @@ -70,8 +71,8 @@ static void hp_block_output(struct device *dev, int count, static void hp_init_card(struct device *dev); /* The map from IRQ number to HP_CONFIGURE register setting. */ -/* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */ -static char irqmap[16] = { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0}; +/* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */ +static char irqmap[16] __initdata= { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0}; /* Probe for an HP LAN adaptor. @@ -82,7 +83,7 @@ struct netdev_entry netcard_drv = {"hp", hp_probe1, HP_IO_EXTENT, hppclan_portlist}; #else -int hp_probe(struct device *dev) +__initfunc(int hp_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -104,7 +105,7 @@ int hp_probe(struct device *dev) } #endif -int hp_probe1(struct device *dev, int ioaddr) +__initfunc(int hp_probe1(struct device *dev, int ioaddr)) { int i, board_id, wordmode; const char *name; diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index c85e3b355..6a599dd60 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -93,6 +93,7 @@ #include #include #include +#include #include #include @@ -209,7 +210,7 @@ static int hp100_down_vg_link( struct device *dev ); * probe functions */ -int hp100_probe( struct device *dev ) +__initfunc(int hp100_probe( struct device *dev )) { int base_addr = dev ? dev -> base_addr : 0; int ioaddr; @@ -297,7 +298,7 @@ int hp100_probe( struct device *dev ) return -ENODEV; } -static int hp100_probe1( struct device *dev, int ioaddr, int bus ) +__initfunc(static int hp100_probe1( struct device *dev, int ioaddr, int bus )) { int i; u_char uc, uc_1; diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index 20d82d2c2..ca0e019ce 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -156,7 +157,7 @@ static void memcpyw(u16 *dest, u16 *src, int len) #endif -int hydra_probe(struct device *dev) +__initfunc(int hydra_probe(struct device *dev)) { struct hydra_private *priv; u32 board; diff --git a/drivers/net/ibmtr.c b/drivers/net/ibmtr.c index 8f2ffcca8..faedd45fa 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/ibmtr.c @@ -119,6 +119,7 @@ static char mcchannelid[] = { #include #include #include +#include #include #include @@ -134,11 +135,11 @@ static char mcchannelid[] = { #if TR_NEWFORMAT /* this allows displaying full adapter information */ -const char *channel_def[] = { +const char *channel_def[] __initdata = { "ISA", "MCA", "ISA P&P" }; -char *adapter_def(char type) +__initfunc(char *adapter_def(char type)) { switch (type) { @@ -178,13 +179,13 @@ static struct net_device_stats * tok_get_stats(struct device *dev); void ibmtr_readlog(struct device *dev); void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev); -static unsigned int ibmtr_portlist[] = { +static unsigned int ibmtr_portlist[] __initdata = { 0xa20, 0xa24, 0 }; static __u32 ibmtr_mem_base = 0xd0000; -static void PrtChanID(char *pcid, short stride) +__initfunc(static void PrtChanID(char *pcid, short stride) ) { short i, j; for (i=0, j=0; i<24; i++, j+=stride) @@ -192,7 +193,7 @@ static void PrtChanID(char *pcid, short stride) printk("\n"); } -static void HWPrtChanID (__u32 pcid, short stride) +__initfunc(static void HWPrtChanID (__u32 pcid, short stride)) { short i, j; for (i=0, j=0; i<24; i++, j+=stride) @@ -213,7 +214,7 @@ static void HWPrtChanID (__u32 pcid, short stride) * which references it. */ -int ibmtr_probe(struct device *dev) +__initfunc(int ibmtr_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -252,7 +253,7 @@ int ibmtr_probe(struct device *dev) return -ENODEV; } -static int ibmtr_probe1(struct device *dev, int PIOaddr) +__initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr)) { unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0; __u32 t_mmio=0; @@ -597,7 +598,7 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr) /* query the adapter for the size of shared RAM */ -unsigned char get_sram_size(struct tok_info *adapt_info) +__initfunc(static unsigned char get_sram_size(struct tok_info *adapt_info)) { unsigned char avail_sram_code; @@ -617,7 +618,7 @@ unsigned char get_sram_size(struct tok_info *adapt_info) return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4); } -int trdev_init(struct device *dev) +__initfunc(static int trdev_init(struct device *dev)) { struct tok_info *ti=(struct tok_info *)dev->priv; diff --git a/drivers/net/lance.c b/drivers/net/lance.c index 4483a1fe9..011d89189 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -46,6 +46,7 @@ static const char *version = "lance.c:v1.09 Aug 20 1996 dplatt@3do.com, becker@c #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ static const char *version = "lance.c:v1.09 Aug 20 1996 dplatt@3do.com, becker@c #include #include -static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0}; +static unsigned int lance_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0}; void lance_probe1(int ioaddr); #ifdef HAVE_DEVLIST @@ -308,7 +309,7 @@ static void set_multicast_list(struct device *dev); before the memory management system is started, and thus well before the other probes. */ -int lance_init(void) +__initfunc(int lance_init(void)) { int *port; @@ -371,7 +372,7 @@ int lance_init(void) return 0; } -void lance_probe1(int ioaddr) +__initfunc(void lance_probe1(int ioaddr)) { struct device *dev; struct lance_private *lp; diff --git a/drivers/net/lapbether.c b/drivers/net/lapbether.c index 0ddc6da5b..3d9801352 100644 --- a/drivers/net/lapbether.c +++ b/drivers/net/lapbether.c @@ -47,6 +47,7 @@ #include #include #include +#include static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; @@ -410,7 +411,7 @@ static int lapbeth_close(struct device *dev) return 0; } -static int lapbeth_dev_init(struct device *dev) +__initfunc(static int lapbeth_dev_init(struct device *dev)) { return 0; } diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index a9716d7f0..629f6a0ca 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -114,7 +115,7 @@ static int loopback_open(struct device *dev) } /* Initialize the rest of the LOOPBACK device. */ -int loopback_init(struct device *dev) +__initfunc(int loopback_init(struct device *dev)) { dev->mtu = LOOPBACK_MTU; dev->tbusy = 0; diff --git a/drivers/net/ltpc.c b/drivers/net/ltpc.c index 49f7dd618..8a4fae560 100644 --- a/drivers/net/ltpc.c +++ b/drivers/net/ltpc.c @@ -201,6 +201,7 @@ static int debug=0; #include #include #include +#include #include #include @@ -956,12 +957,12 @@ static struct net_device_stats *ltpc_get_stats(struct device *dev) static unsigned short irqhitmask; -static void lt_probe_handler(int irq, void *dev_id, struct pt_regs *reg_ptr) +__initfunc(static void lt_probe_handler(int irq, void *dev_id, struct pt_regs *reg_ptr)) { irqhitmask |= 1< #include #include +#include #include @@ -816,7 +817,7 @@ static int ax_open_dev(struct device *dev) } /* Initialize AX25 control device -- register AX25 line discipline */ -int mkiss_init_ctrl_dev(void) +__initfunc(int mkiss_init_ctrl_dev(void)) { int status; @@ -1038,7 +1039,7 @@ static void mkiss_set_termios(struct tty_struct *tty, struct termios *old_termio /* * Init MKISS driver * */ /* ******************************************************************** */ -static int mkiss_init(void) +__initfunc(static int mkiss_init(void)) { memset(&mkiss_driver, 0, sizeof(struct tty_driver)); diff --git a/drivers/net/ne.c b/drivers/net/ne.c index cfeca28d3..7e02bf4f8 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -41,6 +41,7 @@ static const char *version = #include #include #include +#include #include #include @@ -64,14 +65,14 @@ static const char *version = /* A zero-terminated list of I/O addresses to be probed at boot. */ #ifndef MODULE -static unsigned int netcard_portlist[] = -{ 0x300, 0x280, 0x320, 0x340, 0x360, 0}; +static unsigned int netcard_portlist[] __initdata = +{ 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0}; #endif #ifdef CONFIG_PCI /* Ack! People are making PCI ne2000 clones! Oh the horror, the horror... */ static struct { unsigned short vendor, dev_id;} -pci_clone_list[] = { +pci_clone_list[] __initdata = { {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029}, {PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940}, {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000}, @@ -83,7 +84,7 @@ pci_clone_list[] = { #ifdef SUPPORT_NE_BAD_CLONES /* A list of bad clones that we none-the-less recognize. */ static struct { const char *name8, *name16; unsigned char SAprefix[4];} -bad_clone_list[] = { +bad_clone_list[] __initdata = { {"DE100", "DE200", {0x00, 0xDE, 0x01,}}, {"DE120", "DE220", {0x00, 0x80, 0xc8,}}, {"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh? */ @@ -166,7 +167,7 @@ struct netdev_entry netcard_drv = * the card. */ -int ne_probe(struct device *dev) +__initfunc(int ne_probe(struct device *dev)) { int base_addr = dev ? dev->base_addr : 0; @@ -198,7 +199,7 @@ int ne_probe(struct device *dev) #endif #ifdef CONFIG_PCI -static int ne_probe_pci(struct device *dev) +__initfunc(static int ne_probe_pci(struct device *dev)) { int i; @@ -240,7 +241,7 @@ static int ne_probe_pci(struct device *dev) } #endif /* CONFIG_PCI */ -static int ne_probe1(struct device *dev, int ioaddr) +__initfunc(static int ne_probe1(struct device *dev, int ioaddr)) { int i; unsigned char SA_prom[32]; diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index 278957f31..746037adf 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -114,6 +114,7 @@ static int fifo=0x8; /* don't change */ #include #include #include +#include #include #include @@ -359,7 +360,7 @@ void alloc586(struct device *dev) /********************************************** * probe the ni5210-card */ -int ni52_probe(struct device *dev) +__initfunc(int ni52_probe(struct device *dev)) { #ifndef MODULE int *port; @@ -410,7 +411,7 @@ int ni52_probe(struct device *dev) return ENODEV; } -static int ni52_probe1(struct device *dev,int ioaddr) +__initfunc(static int ni52_probe1(struct device *dev,int ioaddr)) { int i,size; @@ -455,7 +456,7 @@ static int ni52_probe1(struct device *dev,int ioaddr) else { static long memaddrs[] = { 0xc8000,0xca000,0xcc000,0xce000,0xd0000,0xd2000, - 0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 }; + 0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 }; for(i=0;;i++) { if(!memaddrs[i]) { diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c index 1cdd7b4cf..07a946d3b 100644 --- a/drivers/net/ni65.c +++ b/drivers/net/ni65.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -232,8 +233,8 @@ static void ni65_free_buffer(struct priv *p); static struct net_device_stats *ni65_get_stats(struct device *); static void set_multicast_list(struct device *dev); -static int irqtab[] = { 9,12,15,5 }; /* irq config-translate */ -static int dmatab[] = { 0,3,5,6,7 }; /* dma config-translate and autodetect */ +static int irqtab[] __initdata = { 9,12,15,5 }; /* irq config-translate */ +static int dmatab[] __initdata = { 0,3,5,6,7 }; /* dma config-translate and autodetect */ static int debuglevel = 1; @@ -327,7 +328,7 @@ static int ni65_close(struct device *dev) #ifdef MODULE static #endif -int ni65_probe(struct device *dev) +__initfunc(int ni65_probe(struct device *dev)) { int *port; static int ports[] = {0x360,0x300,0x320,0x340, 0}; @@ -349,7 +350,7 @@ int ni65_probe(struct device *dev) /* * this is the real card probe .. */ -static int ni65_probe1(struct device *dev,int ioaddr) +__initfunc(static int ni65_probe1(struct device *dev,int ioaddr)) { int i,j; struct priv *p; diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 983a4da95..47bc60e79 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -26,6 +26,7 @@ static const char *version = "pcnet32.c:v0.23 8.2.97 tsbogend@alpha.franken.de\n #include #include #include +#include #include #include #include @@ -34,7 +35,7 @@ static const char *version = "pcnet32.c:v0.23 8.2.97 tsbogend@alpha.franken.de\n #include #include -static unsigned int pcnet32_portlist[] = {0x300, 0x320, 0x340, 0x360, 0}; +static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0}; #ifdef PCNET32_DEBUG static int pcnet32_debug = PCNET32_DEBUG; @@ -168,7 +169,7 @@ static void pcnet32_set_multicast_list(struct device *dev); -int pcnet32_probe (struct device *dev) +__initfunc(int pcnet32_probe (struct device *dev)) { unsigned int ioaddr = dev ? dev->base_addr: 0; unsigned char irq_line = dev ? dev->irq : 0; @@ -246,7 +247,7 @@ int pcnet32_probe (struct device *dev) /* pcnet32_probe1 */ -int pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char irq_line, int shared) +__initfunc(static int pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char irq_line, int shared)) { struct pcnet32_private *lp; int i; diff --git a/drivers/net/pi2.c b/drivers/net/pi2.c index cbd2cb7c9..347d6d980 100644 --- a/drivers/net/pi2.c +++ b/drivers/net/pi2.c @@ -112,6 +112,7 @@ #include #include #include +#include #include "z8530.h" #include @@ -564,7 +565,6 @@ static void a_rxint(struct device *dev, struct pi_local *lp) pkt_len - 1); skb->protocol=htons(ETH_P_AX25); skb->mac.raw=skb->data; - IS_SKB(skb); netif_rx(skb); lp->stats.rx_packets++; } /* end good frame */ @@ -652,7 +652,6 @@ static void b_rxint(struct device *dev, struct pi_local *lp) memcpy(cfix, lp->rcvbuf->data, pkt_len - 1); skb->protocol=ntohs(ETH_P_AX25); skb->mac.raw=skb->data; - IS_SKB(skb); netif_rx(skb); lp->stats.rx_packets++; /* packet queued - initialize buffer for next frame */ @@ -933,7 +932,7 @@ static void b_exint(struct pi_local *lp) /* Probe for a PI card. */ /* This routine also initializes the timer chip */ -static int hw_probe(int ioaddr) +__initfunc(static int hw_probe(int ioaddr)) { int time = 1000; /* Number of milliseconds for test */ unsigned long start_time, end_time; @@ -1188,13 +1187,12 @@ static void chipset_init(struct device *dev) } -int pi_init(void) +__initfunc(int pi_init(void)) { int *port; int ioaddr = 0; int card_type = 0; - int ports[] = - {0x380, 0x300, 0x320, 0x340, 0x360, 0x3a0, 0}; + int ports[] = {0x380, 0x300, 0x320, 0x340, 0x360, 0x3a0, 0}; printk(KERN_INFO "PI: V0.8 ALPHA April 23 1995 David Perry (dp@hydra.carleton.ca)\n"); diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 37484d163..25c33ab1a 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -95,6 +95,7 @@ static const char *version = "NET3 PLIP version 2.2-parport gniibe@mri.co.jp\n"; #include #include #include +#include #include #include @@ -223,8 +224,8 @@ struct net_local { then calls us here. */ -int -plip_init_dev(struct device *dev, struct parport *pb) +__initfunc(int +plip_init_dev(struct device *dev, struct parport *pb)) { struct net_local *nl; struct ppd *pardev; @@ -1190,38 +1191,8 @@ plip_searchfor(int list[], int a) return 0; } -static int -plip_init_one(int i, struct parport *pb) -{ - if (i == PLIP_MAX) { - printk(KERN_ERR "plip: too many devices\n"); - return 1; - } - dev_plip[i] = kmalloc(sizeof(struct device), - GFP_KERNEL); - if (!dev_plip[i]) { - printk(KERN_ERR "plip: memory squeeze\n"); - return 1; - } - memset(dev_plip[i], 0, sizeof(struct device)); - dev_plip[i]->name = kmalloc(strlen("plipXXX"), GFP_KERNEL); - if (!dev_plip[i]->name) { - printk(KERN_ERR "plip: memory squeeze.\n"); - kfree(dev_plip[i]); - return 1; - } - sprintf(dev_plip[i]->name, "plip%d", i); - dev_plip[i]->priv = pb; - if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) { - kfree(dev_plip[i]->name); - kfree(dev_plip[i]); - return 1; - } - return 0; -} - -int -plip_init(void) +__initfunc(int +plip_init(void)) { struct parport *pb = parport_enumerate(); int devices=0; @@ -1237,17 +1208,38 @@ plip_init(void) /* When user feeds parameters, use them */ while (pb) { - if (pb->modes & PARPORT_MODE_SPP) { - if ((parport[0] == -1 && (!timid || !pb->devices)) || - plip_searchfor(parport, i)) { - if (plip_init_one(i, pb)) - continue; + if ((parport[0] == -1 && (!timid || !pb->devices)) || + plip_searchfor(parport, i)) { + if (i == PLIP_MAX) { + printk(KERN_ERR "plip: too many devices\n"); + break; + } + dev_plip[i] = kmalloc(sizeof(struct device), + GFP_KERNEL); + if (!dev_plip[i]) { + printk(KERN_ERR "plip: memory squeeze\n"); + break; + } + memset(dev_plip[i], 0, sizeof(struct device)); + dev_plip[i]->name = + kmalloc(strlen("plipXXX"), GFP_KERNEL); + if (!dev_plip[i]->name) { + printk(KERN_ERR "plip: memory squeeze.\n"); + kfree(dev_plip[i]); + break; + } + sprintf(dev_plip[i]->name, "plip%d", i); + dev_plip[i]->priv = pb; + if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) { + kfree(dev_plip[i]->name); + kfree(dev_plip[i]); + } else { devices++; } - i++; } + i++; pb = pb->next; - } + } if (devices == 0) { printk(KERN_INFO "plip: no devices registered\n"); diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c index fb351b974..a1dbb5020 100644 --- a/drivers/net/ppp.c +++ b/drivers/net/ppp.c @@ -85,6 +85,7 @@ #include #include #include +#include typedef struct sk_buff sk_buff; #define skb_data(skb) ((__u8 *) (skb)->data) @@ -334,8 +335,8 @@ extern inline __u8 * store_long (register __u8 *p, register int value) { * accessing the ppp protocol. */ -static int -ppp_first_time (void) +__initfunc(static int +ppp_first_time (void)) { static struct tty_ldisc ppp_ldisc; int status; diff --git a/drivers/net/pt.c b/drivers/net/pt.c index 3e6257d19..f6ef6db65 100644 --- a/drivers/net/pt.c +++ b/drivers/net/pt.c @@ -92,6 +92,7 @@ #include #include #include +#include #include "z8530.h" #include @@ -480,7 +481,7 @@ static void chipset_init(struct device *dev) -int pt_init(void) +__initfunc(int pt_init(void)) { int *port; int ioaddr = 0; @@ -542,7 +543,7 @@ int pt_init(void) /* * Probe for PT card. Also initialises the timers */ -static int hw_probe(int ioaddr) +__initfunc(static int hw_probe(int ioaddr)) { int time = 1000; /* Number of milliseconds to test */ int a = 1; @@ -1380,7 +1381,6 @@ static void pt_rxisr(struct device *dev) skb->protocol = ntohs(ETH_P_AX25); skb->mac.raw=skb->data; lp->stats.rx_bytes+=skb->len; - IS_SKB(skb); netif_rx(skb); lp->stats.rx_packets++; if (!lp->dmachan) diff --git a/drivers/net/scc.c b/drivers/net/scc.c index 83acf7fdd..4e43e5161 100644 --- a/drivers/net/scc.c +++ b/drivers/net/scc.c @@ -153,6 +153,7 @@ #include #include #include +#include #include #include "z8530.h" @@ -2153,7 +2154,7 @@ struct proc_dir_entry scc_proc_dir_entry = /* * Init SCC driver * */ /* ******************************************************************** */ -int scc_init (void) +__initfunc(int scc_init (void)) { int chip, chan, k, result; char devname[10]; diff --git a/drivers/net/sdla.c b/drivers/net/sdla.c index bfddc7209..f2762eef1 100644 --- a/drivers/net/sdla.c +++ b/drivers/net/sdla.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -64,9 +65,10 @@ static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux static const char* devname = "sdla"; -static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; +static unsigned int valid_port[] __initdata = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; -static unsigned int valid_mem[] = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, +static unsigned int valid_mem[] __initdata = { + 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000, 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000, @@ -1621,7 +1623,7 @@ static struct net_device_stats *sdla_stats(struct device *dev) return(&flp->stats); } -int sdla_init(struct device *dev) +__initfunc(int sdla_init(struct device *dev)) { struct frad_local *flp; @@ -1669,7 +1671,7 @@ int sdla_init(struct device *dev) return(0); } -void sdla_setup(void) +__initfunc(void sdla_setup(void)) { printk("%s.\n", version); register_frad(devname); diff --git a/drivers/net/sdla_fr.c b/drivers/net/sdla_fr.c index 3083c025c..79a493c2c 100644 --- a/drivers/net/sdla_fr.c +++ b/drivers/net/sdla_fr.c @@ -25,6 +25,7 @@ #include /* WAN router definitions */ #include /* WANPIPE common user API definitions */ #include /* ARPHRD_* defines */ +#include /* __initfunc et al. */ #include /* htons(), etc. */ #include /* for inb(), outb(), etc. */ @@ -135,7 +136,7 @@ static unsigned int hex_to_uint (unsigned char* str, int len); * Return: 0 o.k. * < 0 failure. */ -int wpf_init (sdla_t* card, wandev_conf_t* conf) +__initfunc(int wpf_init (sdla_t* card, wandev_conf_t* conf)) { union { diff --git a/drivers/net/sdla_ppp.c b/drivers/net/sdla_ppp.c index 9910a73c4..c6b1ce945 100644 --- a/drivers/net/sdla_ppp.c +++ b/drivers/net/sdla_ppp.c @@ -25,6 +25,7 @@ #include /* WAN router definitions */ #include /* WANPIPE common user API definitions */ #include /* ARPHRD_* defines */ +#include /* __initfunc et al. */ #include /* htons(), etc. */ #define _GNUC_ @@ -107,7 +108,7 @@ static unsigned char bps_to_speed_code (unsigned long bps); * Return: 0 o.k. * < 0 failure. */ -int wpp_init (sdla_t* card, wandev_conf_t* conf) +__initfunc(int wpp_init (sdla_t* card, wandev_conf_t* conf)) { union { diff --git a/drivers/net/sdla_x25.c b/drivers/net/sdla_x25.c index 116bee984..f6f540709 100644 --- a/drivers/net/sdla_x25.c +++ b/drivers/net/sdla_x25.c @@ -24,6 +24,7 @@ #include /* kmalloc(), kfree() */ #include /* WAN router definitions */ #include /* WANPIPE common user API definitions */ +#include /* __initfunc et al. */ #include /* htons(), etc. */ #define _GNUC_ @@ -168,7 +169,7 @@ static void parse_call_info (unsigned char* str, x25_call_info_t* info); * Return: 0 o.k. * < 0 failure. */ -int wpx_init (sdla_t* card, wandev_conf_t* conf) +__initfunc(int wpx_init (sdla_t* card, wandev_conf_t* conf)) { union { diff --git a/drivers/net/sdladrv.c b/drivers/net/sdladrv.c index d1f3bd051..500c5cb6d 100644 --- a/drivers/net/sdladrv.c +++ b/drivers/net/sdladrv.c @@ -90,6 +90,7 @@ #include /* for jiffies, HZ, etc. */ #include /* API definitions */ #include /* SDLA firmware module definitions */ +#include #include /* for inb(), outb(), etc. */ #define _INB(port) (inb(port)) #define _OUTB(port, byte) (outb((byte),(port))) @@ -289,7 +290,8 @@ static unsigned char s507_irqmask[] = #ifdef MODULE int init_module (void) #else -int wanpipe_init(void) +__initfunc(int wanpipe_init(void)) +#endif { printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE, copyright); diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index 524b4a312..397228647 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -40,6 +40,7 @@ static const char *version = #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ static const char *version = /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int seeq8005_portlist[] = +static unsigned int seeq8005_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -106,8 +107,8 @@ static inline void wait_for_buffer(struct device *dev); struct netdev_entry seeq8005_drv = {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist}; #else -int -seeq8005_probe(struct device *dev) +__initfunc(int +seeq8005_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -133,7 +134,7 @@ seeq8005_probe(struct device *dev) probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int seeq8005_probe1(struct device *dev, int ioaddr) +__initfunc(static int seeq8005_probe1(struct device *dev, int ioaddr)) { static unsigned version_printed = 0; int i,j; diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index ac95948df..a40f16599 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include "shaper.h" @@ -545,7 +546,7 @@ static struct shaper *shaper_alloc(struct device *dev) * Add a shaper device to the system */ -int shaper_probe(struct device *dev) +__initfunc(int shaper_probe(struct device *dev)) { /* * Set up the shaper. diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index 35d9335c4..7e946b78f 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -743,7 +744,7 @@ void cleanup_module(void) #else /* MODULE */ -void slhc_install(void) +__initfunc(void slhc_install(void)) { } diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 9b7aba32f..f091e38a4 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -70,6 +70,7 @@ #include #include #include +#include #include "slip.h" #ifdef CONFIG_INET #include @@ -1087,7 +1088,7 @@ static int sl_open_dev(struct device *dev) #ifdef MODULE static int slip_init_ctrl_dev(void) #else /* !MODULE */ -int slip_init_ctrl_dev(struct device *dummy) +__initfunc(int slip_init_ctrl_dev(struct device *dummy)) #endif /* !MODULE */ { int status; diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index 3188c8240..43872c529 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -66,7 +67,7 @@ static int ultramca_close_card(struct device *dev); #define EN0_ERWCNT 0x08 /* Early receive warning count. */ -int ultramca_probe(struct device *dev) +__initfunc(int ultramca_probe(struct device *dev)) { unsigned short ioaddr; unsigned char reg4, num_pages; diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index 506e8b80c..30c6b4907 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -53,6 +53,7 @@ static const char *version = #include #include #include +#include #include #include @@ -61,7 +62,7 @@ static const char *version = #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int ultra_portlist[] = +static unsigned int ultra_portlist[] __initdata = {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; int ultra_probe(struct device *dev); @@ -104,7 +105,7 @@ struct netdev_entry ultra_drv = {"ultra", ultra_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else -int ultra_probe(struct device *dev) +__initfunc(int ultra_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -126,7 +127,7 @@ int ultra_probe(struct device *dev) } #endif -int ultra_probe1(struct device *dev, int ioaddr) +__initfunc(int ultra_probe1(struct device *dev, int ioaddr)) { int i; int checksum = 0; diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index d879d3d13..5b3e9b73c 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -66,6 +66,7 @@ static const char *version = #include #include #include +#include #include #include #include @@ -108,7 +109,7 @@ static const char *version = .for a slightly different card, you can add it to the array. Keep in .mind that the array must end in zero. */ -static unsigned int smc_portlist[] = +static unsigned int smc_portlist[] __initdata = { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0}; @@ -750,7 +751,7 @@ static void smc_hardware_send_packet( struct device * dev ) | --------------------------------------------------------------------------- */ -int smc_init(struct device *dev) +__initfunc(int smc_init(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -795,7 +796,7 @@ int smc_init(struct device *dev) . interrupt, so an auto-detect routine can detect it, and find the IRQ, ------------------------------------------------------------------------ */ -int smc_findirq( int ioaddr ) +__initfunc(int smc_findirq( int ioaddr )) { int timeout = 20; @@ -877,7 +878,7 @@ int smc_findirq( int ioaddr ) .--------------------------------------------------------------------- */ -static int smc_probe( int ioaddr ) +__initfunc(static int smc_probe( int ioaddr )) { unsigned int bank; word revision_register; @@ -942,7 +943,7 @@ static int smc_probe( int ioaddr ) . o GRAB the region .----------------------------------------------------------------- */ -static int smc_initcard(struct device *dev, int ioaddr) +__initfunc(static int smc_initcard(struct device *dev, int ioaddr)) { int i; diff --git a/drivers/net/tulip.c b/drivers/net/tulip.c index 1b7a1abad..fe4cf2662 100644 --- a/drivers/net/tulip.c +++ b/drivers/net/tulip.c @@ -62,6 +62,7 @@ static char *version = #include #include #include +#include #include #include #include @@ -473,8 +474,8 @@ tio_sia_write(u32 ioaddr, u32 val13, u32 val14, u32 val15) card_type returns 1 if the card is 'etherarray' */ -static int -card_type(struct tulip_private *tp, int device_id, int vendor_id) +__initfunc(static int +card_type(struct tulip_private *tp, int device_id, int vendor_id)) { int n; @@ -488,8 +489,8 @@ card_type(struct tulip_private *tp, int device_id, int vendor_id) return(cardVendor[n].array ? 1: 0); } -static int -read_eeprom(int ioaddr, struct eeprom *eepp) +__initfunc(static int +read_eeprom(int ioaddr, struct eeprom *eepp)) { int i, n; unsigned short val = 0; @@ -1188,9 +1189,9 @@ static void set_multicast_list(struct device *dev) } } -int +__initfunc(int tulip_hwinit(struct device *dev, int ioaddr, - int irq, int device_id) + int irq, int device_id)) { /* See note below on the Znyx 315 etherarray. */ static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; @@ -1319,7 +1320,7 @@ tulip_hwinit(struct device *dev, int ioaddr, return(0); } -int tulip_probe(struct device *dev) +__initfunc(int tulip_probe(struct device *dev)) { static struct device *tulip_head=NULL; u_char pci_bus, pci_device_fn, pci_latency, pci_irq; diff --git a/drivers/net/tunnel.c b/drivers/net/tunnel.c index 7bf840fc1..dc7c08a07 100644 --- a/drivers/net/tunnel.c +++ b/drivers/net/tunnel.c @@ -64,6 +64,7 @@ #include #include #include +#include /*#define TUNNEL_DEBUG*/ @@ -213,7 +214,7 @@ static struct net_device_stats *tunnel_get_stats(struct device *dev) * The new tunnel device structure is passed to us. */ -int tunnel_init(struct device *dev) +__initfunc(int tunnel_init(struct device *dev)) { /* Oh, just say we're here, in case anyone cares */ static int tun_msg=0; diff --git a/drivers/net/wd.c b/drivers/net/wd.c index 77ac9e053..56e8bd5ab 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -33,6 +33,7 @@ static const char *version = #include #include #include +#include #include #include @@ -41,7 +42,7 @@ static const char *version = #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int wd_portlist[] = +static unsigned int wd_portlist[] __initdata = {0x300, 0x280, 0x380, 0x240, 0}; int wd_probe(struct device *dev); @@ -85,7 +86,7 @@ struct netdev_entry wd_drv = {"wd", wd_probe1, WD_IO_EXTENT, wd_portlist}; #else -int wd_probe(struct device *dev) +__initfunc(int wd_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -107,7 +108,7 @@ int wd_probe(struct device *dev) } #endif -int wd_probe1(struct device *dev, int ioaddr) +__initfunc(int wd_probe1(struct device *dev, int ioaddr)) { int i; int checksum = 0; diff --git a/drivers/net/x25_asy.c b/drivers/net/x25_asy.c index 74cbce666..21963477c 100644 --- a/drivers/net/x25_asy.c +++ b/drivers/net/x25_asy.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "x25_asy.h" typedef struct x25_ctrl { @@ -808,7 +809,7 @@ static int x25_asy_open_dev(struct device *dev) #ifdef MODULE static int x25_asy_init_ctrl_dev(void) #else /* !MODULE */ -int x25_asy_init_ctrl_dev(struct device *dummy) +__initfunc(int x25_asy_init_ctrl_dev(struct device *dummy)) #endif /* !MODULE */ { int status; diff --git a/drivers/net/znet.c b/drivers/net/znet.c index bea1771c6..eb198bc78 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -69,6 +69,7 @@ static const char *version = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n #include #include #include +#include #include #include #include @@ -199,7 +200,7 @@ static struct sigaction znet_sigaction = { &znet_interrupt, 0, 0, NULL, }; BIOS area. We just scan for the signature, and pull the vital parameters out of the structure. */ -int znet_probe(struct device *dev) +__initfunc(int znet_probe(struct device *dev)) { int i; struct netidblk *netinfo; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e10d0120c..8baf90212 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -261,6 +261,7 @@ struct pci_dev_info dev_info[] = { DEVICE( INTEL, INTEL_82371SB_1,"82371SB Natoma/Triton II PIIX3"), DEVICE( INTEL, INTEL_82371SB_2,"82371SB Natoma/Triton II PIIX3"), DEVICE( INTEL, INTEL_82437VX, "82437VX Triton II"), + DEVICE( INTEL, INTEL_82371AB, "82371AB 430TX PIIX4"), DEVICE( INTEL, INTEL_P6, "Orion P6"), DEVICE( KTI, KTI_ET32P2, "ET32P2"), DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"), diff --git a/drivers/pnp/parport_init.c b/drivers/pnp/parport_init.c index 672d2d86e..57574b6a5 100644 --- a/drivers/pnp/parport_init.c +++ b/drivers/pnp/parport_init.c @@ -746,7 +746,7 @@ int pnp_parport_init(void) if (io[0] == PARPORT_DISABLE) return 1; #ifdef CONFIG_PROC_FS - parport_proc_register(NULL); + parport_proc_init(); #endif /* Run probes to ensure parport does exist */ diff --git a/drivers/sbus/char/creator.c b/drivers/sbus/char/creator.c new file mode 100644 index 000000000..193a26190 --- /dev/null +++ b/drivers/sbus/char/creator.c @@ -0,0 +1,98 @@ +/* + * creator.c: Linux/Sun Ultra Creator console support. + * + * Copyright (C) 1997 MIguel de Icaza (miguel@nuclecu.unam.mx) + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../../char/vt_kern.h" +#include "../../char/selection.h" +#include "../../char/console_struct.h" +#include "fb.h" + +__initfunc(void creator_setup (fbinfo_t *fb, int slot, int con_node, unsigned long creator, int creator_io)) +{ + uint bases [2]; + unsigned long *p; + + if (!creator) { + prom_getproperty (con_node, "address", (char *) &bases[0], 4); + prom_printf ("Bases: %x %x\n", bases [0], bases [1]); + p = (unsigned long *) creator = bases[0]; + fb->base = creator; + fb->base = 0xff168000; + } + + fb->type.fb_cmsize = 256; + fb->mmap = 0; + fb->loadcmap = 0; + fb->setcursor = 0; + fb->setcursormap = 0; + fb->setcurshape = 0; + fb->ioctl = 0; + fb->switch_from_graph = 0; + fb->postsetup = sun_cg_postsetup; + fb->reset = 0; + fb->blank = 0; + fb->unblank = 0; + fb->type.fb_depth = 8; +} +/* + * creator.c: Linux/Sun Ultra Creator console support. + * + * Copyright (C) 1997 MIguel de Icaza (miguel@nuclecu.unam.mx) + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../../char/vt_kern.h" +#include "../../char/selection.h" +#include "../../char/console_struct.h" +#include "fb.h" + +__initfunc(void creator_setup (fbinfo_t *fb, int slot, int con_node, unsigned long creator, int creator_io)) +{ + uint bases [2]; + unsigned long *p; + + if (!creator) { + prom_getproperty (con_node, "address", (char *) &bases[0], 4); + prom_printf ("Bases: %x %x\n", bases [0], bases [1]); + p = (unsigned long *) creator = bases[0]; + fb->base = creator; + fb->base = 0xff168000; + } + + fb->type.fb_cmsize = 256; + fb->mmap = 0; + fb->loadcmap = 0; + fb->setcursor = 0; + fb->setcursormap = 0; + fb->setcurshape = 0; + fb->ioctl = 0; + fb->switch_from_graph = 0; + fb->postsetup = sun_cg_postsetup; + fb->reset = 0; + fb->blank = 0; + fb->unblank = 0; + fb->type.fb_depth = 8; +} diff --git a/drivers/sbus/char/linux_logo.h b/drivers/sbus/char/linux_logo.h deleted file mode 100644 index a66a2d6a8..000000000 --- a/drivers/sbus/char/linux_logo.h +++ /dev/null @@ -1,1037 +0,0 @@ -/* This is a linux logo to be displayed on boot. - * - * You can put anything here, but: - * LINUX_LOGO_COLORS has to be less than 224 - * image size has to be 80x80 - * values have to start from 0x20 - * (i.e. RGB(linux_logo_red[0], - * linux_logo_green[0], - * linux_logo_blue[0]) is color 0x20) - * BW image has to be 80x80 as well, with MS bit - * on the left - * Serial_console ascii image can be any size, - * but should contain %s to display the version - */ - -#include - -#define LINUX_LOGO_COLORS 221 - -unsigned char linux_logo_red[] __initdata = { - 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, - 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5, - 0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5, - 0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6, - 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD, - 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D, - 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, - 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, - 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03, - 0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6, - 0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2, - 0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A, - 0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4, - 0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2, - 0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC, - 0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC, - 0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7, - 0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3, - 0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4, - 0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4, - 0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87, - 0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78, - 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, - 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, - 0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E, - 0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B, - 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11, - 0x1D, 0x14, 0x06, 0x02, 0x00 -}; - -unsigned char linux_logo_green[] __initdata = { - 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, - 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3, - 0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9, - 0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6, - 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD, - 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95, - 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, - 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, - 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02, - 0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD, - 0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6, - 0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C, - 0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4, - 0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E, - 0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC, - 0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5, - 0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96, - 0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80, - 0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F, - 0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C, - 0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54, - 0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78, - 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, - 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, - 0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E, - 0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B, - 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D, - 0x1D, 0x14, 0x06, 0x02, 0x00 -}; - -unsigned char linux_logo_blue[] __initdata = { - 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE, - 0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5, - 0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84, - 0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6, - 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD, - 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87, - 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99, - 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, - 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7, - 0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77, - 0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59, - 0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E, - 0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14, - 0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D, - 0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14, - 0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08, - 0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E, - 0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E, - 0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20, - 0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06, - 0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17, - 0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78, - 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62, - 0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46, - 0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14, - 0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A, - 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09, - 0x1D, 0x14, 0x06, 0x02, 0x00 -}; - -unsigned char linux_logo[] __initdata = { - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, - 0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61, - 0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, - 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E, - 0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58, - 0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, - 0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C, - 0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A, - 0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52, - 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53, - 0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, - 0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49, - 0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B, - 0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, - 0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB, - 0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C, - 0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49, - 0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5, - 0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58, - 0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48, - 0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51, - 0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54, - 0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5, - 0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61, - 0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C, - 0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B, - 0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53, - 0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC, - 0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64, - 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59, - 0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48, - 0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51, - 0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61, - 0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63, - 0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48, - 0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51, - 0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52, - 0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB, - 0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B, - 0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53, - 0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53, - 0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC, - 0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F, - 0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61, - 0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57, - 0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D, - 0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, - 0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57, - 0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC, - 0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC, - 0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48, - 0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52, - 0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61, - 0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A, - 0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, - 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B, - 0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC, - 0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC, - 0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49, - 0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F, - 0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB, - 0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47, - 0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54, - 0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D, - 0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC, - 0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC, - 0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45, - 0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44, - 0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64, - 0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48, - 0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, - 0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D, - 0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC, - 0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA, - 0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55, - 0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45, - 0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D, - 0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B, - 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, - 0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A, - 0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC, - 0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8, - 0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD, - 0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A, - 0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56, - 0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, - 0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, - 0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54, - 0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC, - 0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB, - 0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27, - 0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34, - 0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F, - 0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E, - 0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60, - 0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51, - 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57, - 0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51, - 0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC, - 0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE, - 0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A, - 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30, - 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41, - 0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65, - 0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C, - 0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A, - 0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC, - 0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C, - 0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1, - 0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32, - 0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30, - 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41, - 0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC, - 0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A, - 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, - 0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E, - 0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC, - 0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88, - 0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB, - 0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33, - 0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31, - 0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E, - 0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63, - 0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49, - 0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, - 0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55, - 0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC, - 0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C, - 0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8, - 0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F, - 0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F, - 0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48, - 0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A, - 0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A, - 0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57, - 0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53, - 0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC, - 0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88, - 0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4, - 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E, - 0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47, - 0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D, - 0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58, - 0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55, - 0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC, - 0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E, - 0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9, - 0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73, - 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70, - 0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF, - 0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E, - 0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57, - 0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58, - 0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C, - 0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC, - 0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C, - 0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC, - 0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78, - 0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, - 0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1, - 0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C, - 0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D, - 0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58, - 0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E, - 0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC, - 0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8, - 0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42, - 0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73, - 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73, - 0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2, - 0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41, - 0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62, - 0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B, - 0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60, - 0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC, - 0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7, - 0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41, - 0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73, - 0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74, - 0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB, - 0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41, - 0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64, - 0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E, - 0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C, - 0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB, - 0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE, - 0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20, - 0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75, - 0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76, - 0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D, - 0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C, - 0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64, - 0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, - 0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58, - 0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC, - 0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81, - 0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23, - 0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76, - 0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76, - 0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48, - 0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40, - 0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61, - 0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C, - 0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52, - 0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB, - 0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E, - 0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22, - 0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8, - 0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, - 0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C, - 0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57, - 0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D, - 0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A, - 0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65, - 0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC, - 0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40, - 0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD, - 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47, - 0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF, - 0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A, - 0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57, - 0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5, - 0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C, - 0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26, - 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6, - 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52, - 0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9, - 0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42, - 0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51, - 0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6, - 0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21, - 0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7, - 0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93, - 0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D, - 0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF, - 0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40, - 0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52, - 0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1, - 0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21, - 0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8, - 0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93, - 0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40, - 0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0, - 0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F, - 0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59, - 0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E, - 0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23, - 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7, - 0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93, - 0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F, - 0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC, - 0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47, - 0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54, - 0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D, - 0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24, - 0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24, - 0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A, - 0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5, - 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93, - 0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60, - 0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC, - 0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47, - 0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B, - 0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D, - 0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28, - 0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D, - 0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD, - 0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93, - 0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7, - 0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44, - 0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45, - 0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B, - 0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D, - 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20, - 0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6, - 0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90, - 0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0, - 0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44, - 0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45, - 0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51, - 0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF, - 0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7, - 0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5, - 0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2, - 0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58, - 0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C, - 0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55, - 0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1, - 0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB, - 0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6, - 0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3, - 0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58, - 0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58, - 0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C, - 0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC, - 0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7, - 0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, - 0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0, - 0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58, - 0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60, - 0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60, - 0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB, - 0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7, - 0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7, - 0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE, - 0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B, - 0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61, - 0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64, - 0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC, - 0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8, - 0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5, - 0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C, - 0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E, - 0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62, - 0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC, - 0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB, - 0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7, - 0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5, - 0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57, - 0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47, - 0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60, - 0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0, - 0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0, - 0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8, - 0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6, - 0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57, - 0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B, - 0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C, - 0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3, - 0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB, - 0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8, - 0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7, - 0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57, - 0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C, - 0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58, - 0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1, - 0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC, - 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED, - 0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, - 0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58, - 0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60, - 0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56, - 0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0, - 0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC, - 0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6, - 0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, - 0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B, - 0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C, - 0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59, - 0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0, - 0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC, - 0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6, - 0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6, - 0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B, - 0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56, - 0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60, - 0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF, - 0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9, - 0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9, - 0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, - 0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52, - 0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B, - 0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD, - 0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE, - 0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65, - 0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6, - 0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D, - 0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58, - 0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F, - 0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4, - 0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE, - 0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0, - 0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D, - 0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57, - 0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40, - 0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9, - 0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE, - 0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC, - 0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9, - 0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38, - 0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52, - 0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40, - 0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC, - 0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF, - 0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99, - 0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6, - 0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, - 0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B, - 0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43, - 0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC, - 0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0, - 0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C, - 0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23, - 0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, - 0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49, - 0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A, - 0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC, - 0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2, - 0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94, - 0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA, - 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, - 0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E, - 0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D, - 0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC, - 0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4, - 0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B, - 0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23, - 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7, - 0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E, - 0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0, - 0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA, - 0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9, - 0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89, - 0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22, - 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA, - 0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2, - 0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E, - 0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA, - 0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA, - 0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6, - 0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97, - 0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D, - 0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, - 0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9, - 0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D, - 0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45, - 0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB, - 0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6, - 0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99, - 0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A, - 0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC, - 0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4, - 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C, - 0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47, - 0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD, - 0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4, - 0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A, - 0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98, - 0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC, - 0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23, - 0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4, - 0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89, - 0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B, - 0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD, - 0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0, - 0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0, - 0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A, - 0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC, - 0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, - 0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2, - 0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A, - 0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49, - 0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC, - 0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63, - 0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B, - 0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84, - 0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC, - 0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, - 0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99, - 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B, - 0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51, - 0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC, - 0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A, - 0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95, - 0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E, - 0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA, - 0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22, - 0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99, - 0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94, - 0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B, - 0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA, - 0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D, - 0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C, - 0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A, - 0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB, - 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23, - 0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99, - 0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E, - 0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87, - 0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3, - 0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48, - 0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94, - 0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95, - 0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6, - 0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40, - 0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99, - 0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95, - 0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98, - 0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC, - 0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45, - 0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89, - 0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C, - 0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4, - 0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23, - 0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99, - 0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87, - 0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC, - 0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58, - 0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40, - 0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94, - 0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B, - 0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6, - 0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20, - 0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C, - 0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94, - 0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE, - 0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C, - 0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41, - 0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98, - 0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C, - 0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6, - 0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B, - 0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B, - 0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0, - 0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62, - 0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44, - 0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6, - 0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89, - 0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8, - 0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99, - 0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98, - 0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1, - 0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB, - 0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49, - 0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA, - 0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2, - 0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA, - 0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2, - 0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0, - 0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF, - 0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD, - 0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52, - 0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA, - 0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA, - 0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1, - 0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8, - 0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0, - 0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9, - 0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD, - 0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53, - 0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56, - 0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0, - 0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9, - 0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0, - 0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3, - 0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF, - 0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2, - 0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3, - 0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE, - 0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56, - 0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57, - 0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC, - 0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA, - 0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4, - 0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3, - 0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1, - 0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6, - 0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE, - 0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD, - 0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58, - 0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D, - 0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47, - 0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6, - 0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4, - 0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5, - 0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9, - 0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC, - 0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3, - 0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64, - 0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C, - 0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A, - 0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A, - 0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0, - 0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE, - 0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6, - 0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6, - 0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE, - 0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5, - 0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E, - 0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D, - 0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E, - 0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E, - 0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8, - 0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5, - 0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1, - 0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60, - 0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9, - 0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5, - 0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47, - 0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E, - 0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45, - 0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51, - 0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB, - 0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0, - 0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D, - 0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0, - 0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5, - 0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2, - 0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D, - 0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60, - 0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45, - 0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63, - 0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7, - 0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3, - 0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E, - 0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2, - 0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0, - 0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC, - 0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C, - 0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61, - 0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45, - 0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2, - 0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3, - 0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2, - 0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47, - 0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2, - 0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E, - 0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3, - 0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63, - 0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62, - 0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49, - 0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3, - 0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF, - 0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2, - 0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58, - 0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE, - 0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B, - 0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4, - 0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE, - 0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62, - 0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A, - 0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5, - 0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE, - 0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3, - 0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53, - 0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3, - 0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48, - 0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3, - 0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF, - 0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57, -}; - -unsigned char linux_logo_bw[] __initdata = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, - 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, - 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, - 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, - 0x99, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xF3, 0xBC, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, - 0x19, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, - 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xC0, 0x21, 0xD8, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0xC0, 0x1F, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, - 0xC0, 0x7C, 0x04, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, - 0xE3, 0x80, 0x00, 0x7C, 0x40, 0x11, 0xFF, 0xFF, - 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0xD2, 0x29, - 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, - 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, - 0x00, 0x3F, 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, - 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x19, 0xFF, 0xFF, - 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1E, 0x80, 0x19, - 0xFF, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1E, - 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, - 0x00, 0x0F, 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, - 0xF8, 0x00, 0x00, 0x0E, 0x80, 0x11, 0xFF, 0xFF, - 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x06, 0x00, 0x11, - 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x06, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, - 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1, - 0xF0, 0x00, 0x00, 0x02, 0x80, 0x10, 0xFF, 0xFF, - 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x97, 0x10, - 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, - 0xDF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, - 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC7, - 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, - 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, - 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, - 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, - 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F, - 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, - 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0x18, - 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, - 0xA8, 0x11, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, - 0x00, 0x02, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x99, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, - 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x01, - 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, - 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, - 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x40, - 0x38, 0x00, 0x00, 0x00, 0xFE, 0x47, 0xFF, 0xFF, - 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x23, - 0xFF, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, - 0x78, 0x11, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, - 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, - 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, - 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, - 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, - 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, - 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, - 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, - 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, - 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, - 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, - 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, - 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, - 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, - 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, - 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, - 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, - 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, - 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, - 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, - 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -/* Painted by Johnny Stenback */ - -unsigned char *linux_serial_image __initdata = "\n" -" .u$e.\n" -" .$$$$$:S\n" -" $\"*$/\"*$$\n" -" $.`$ . ^F\n" -" 4k+#+T.$F\n" -" 4P+++\"$\"$\n" -" :R\"+ t$$B\n" -" ___# $$$\n" -" | | R$$k\n" -" dd. | Linux $!$\n" -" ddd | Sparc $9$F\n" -" '!!!!!$ !!#!`\n" -" !!!!!* .!!!!!`\n" -"'!!!!!!!W..e$$!!!!!!` %s\n" -" \"~^^~ ^~~^\n" -"\n"; diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c index 6c22f6ed0..87fb0fea4 100644 --- a/drivers/sbus/char/sunkbd.c +++ b/drivers/sbus/char/sunkbd.c @@ -1149,7 +1149,7 @@ static void sunkbd_kd_mksound(unsigned int hz, unsigned int ticks) extern void (*kd_mksound)(unsigned int hz, unsigned int ticks); -int kbd_init(void) +__initfunc(int kbd_init(void)) { int i, opt_node; struct kbd_struct kbd0; diff --git a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c index 025bd7e5b..3691108e6 100644 --- a/drivers/scsi/53c7,8xx.c +++ b/drivers/scsi/53c7,8xx.c @@ -253,6 +253,7 @@ typedef unsigned int u32; #include #include #include +#include #undef current #include "scsi.h" @@ -877,7 +878,7 @@ clock_to_ccf (int clock) { * Returns : 0 on success, -1 on failure. */ -static int +static inline int NCR53c7x0_init (struct Scsi_Host *host) { NCR53c7x0_local_declare(); int i, ccf, expected_ccf; @@ -1187,10 +1188,10 @@ NCR53c7x0_init (struct Scsi_Host *host) { * */ -static int +__initfunc(static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, u32 base, int io_port, int irq, int dma, int pci_valid, - unsigned char pci_bus, unsigned char pci_device_fn, long long options) { + unsigned char pci_bus, unsigned char pci_device_fn, long long options)) { struct Scsi_Host *instance; struct NCR53c7x0_hostdata *hostdata; char chip_str[80]; @@ -1400,9 +1401,9 @@ normal_init (Scsi_Host_Template *tpnt, int board, int chip, * */ -static int +__initfunc(static int ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip, - unsigned char bus, unsigned char device_fn, long long options) { + unsigned char bus, unsigned char device_fn, long long options)) { unsigned short vendor_id, device_id, command; #ifdef LINUX_1_2 unsigned long @@ -1539,8 +1540,8 @@ ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip, * */ -int -NCR53c7xx_detect(Scsi_Host_Template *tpnt) { +__initfunc(int +NCR53c7xx_detect(Scsi_Host_Template *tpnt)) { int i; int current_override; int count; /* Number of boards detected */ diff --git a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c index 7cb554bb0..0ea714166 100644 --- a/drivers/scsi/AM53C974.c +++ b/drivers/scsi/AM53C974.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -461,8 +462,8 @@ static void AM53C974_print_queues(struct Scsi_Host *instance); #endif /* AM53C974_DEBUG */ static void AM53C974_print(struct Scsi_Host *instance); static void AM53C974_keywait(void); -static int AM53C974_bios_detect(Scsi_Host_Template *tpnt); -static int AM53C974_nobios_detect(Scsi_Host_Template *tpnt); +static __inline__ int AM53C974_bios_detect(Scsi_Host_Template *tpnt); +static __inline__ int AM53C974_nobios_detect(Scsi_Host_Template *tpnt); static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config); static void AM53C974_config_after_reset(struct Scsi_Host *instance); static __inline__ void initialize_SCp(Scsi_Cmnd *cmd); @@ -739,7 +740,7 @@ if (ints[0] < 4) * * Returns : number of host adapters detected **************************************************************************/ -int AM53C974_bios_detect(Scsi_Host_Template *tpnt) +static __inline__ int AM53C974_bios_detect(Scsi_Host_Template *tpnt) { int count = 0; /* number of boards detected */ int pci_index; @@ -804,7 +805,7 @@ return (count); * * Origin: Robin Cutshaw (robin@xfree86.org) **************************************************************************/ -int AM53C974_nobios_detect(Scsi_Host_Template *tpnt) +static __inline__ int AM53C974_nobios_detect(Scsi_Host_Template *tpnt) { int count = 0; /* number of boards detected */ pci_config_t pci_config; @@ -902,7 +903,7 @@ return(count); * * Returns : number of host adapters detected **************************************************************************/ -int AM53C974_detect(Scsi_Host_Template *tpnt) +__initfunc(int AM53C974_detect(Scsi_Host_Template *tpnt)) { int count; /* number of boards detected */ @@ -931,7 +932,7 @@ return (count); * set up by the BIOS (as reflected by contents of register CNTLREG1). * This is the only BIOS assistance we need. **************************************************************************/ -static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config) +__initfunc(static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config)) { AM53C974_local_declare(); int i, j; diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index e69229b0a..7e5038efd 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -222,7 +223,8 @@ static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter) Host Adapter. */ -static boolean BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter)) { /* FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes. @@ -304,7 +306,8 @@ static boolean BusLogic_CreateCCB(BusLogic_HostAdapter_T *HostAdapter) BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter. */ -static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)) { int Allocated; for (Allocated = 0; Allocated < HostAdapter->InitialCCBs; Allocated++) @@ -417,8 +420,8 @@ static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB) structure for Host Adapter. */ -static boolean BusLogic_CreateTargetDeviceStatistics(BusLogic_HostAdapter_T - *HostAdapter) +__initfunc(static boolean +BusLogic_CreateTargetDeviceStatistics(BusLogic_HostAdapter_T *HostAdapter)) { HostAdapter->TargetDeviceStatistics = (BusLogic_TargetDeviceStatistics_T *) @@ -708,7 +711,7 @@ Done: only from the list of standard BusLogic MultiMaster ISA I/O Addresses. */ -static void BusLogic_InitializeProbeInfoListISA(void) +static inline void BusLogic_InitializeProbeInfoListISA(void) { int StandardAddressIndex; /* @@ -746,8 +749,9 @@ static void BusLogic_InitializeProbeInfoListISA(void) of increasing PCI Bus and Device Number. */ -static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList, - int ProbeInfoCount) +__initfunc(static void +BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList, + int ProbeInfoCount)) { int LastInterchange = ProbeInfoCount-1, Bound, j; while (LastInterchange > 0) @@ -781,7 +785,7 @@ static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList, I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found. */ -static int BusLogic_InitializeMultiMasterProbeInfo(void) +__initfunc(static int BusLogic_InitializeMultiMasterProbeInfo(void)) { boolean StandardAddressSeen[BusLogic_ISA_StandardAddressesCount]; BusLogic_ProbeInfo_T *PrimaryProbeInfo = @@ -1012,7 +1016,7 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) number of FlashPoint Host Adapters found. */ -static int BusLogic_InitializeFlashPointProbeInfo(void) +__initfunc(static int BusLogic_InitializeFlashPointProbeInfo(void)) { int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0; unsigned char Bus, DeviceFunction, IRQ_Channel; @@ -1119,7 +1123,7 @@ static int BusLogic_InitializeFlashPointProbeInfo(void) particular probe order. */ -static void BusLogic_InitializeProbeInfoList(void) +static inline void BusLogic_InitializeProbeInfoList(void) { /* If BusLogic_Setup has provided an I/O Address probe list, do not override @@ -1228,7 +1232,8 @@ static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter, BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter. */ -static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_StatusRegister_T StatusRegister; BusLogic_InterruptRegister_T InterruptRegister; @@ -1422,7 +1427,8 @@ static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T Host Adapter. It also determines the IRQ Channel for non-PCI Host Adapters. */ -static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_Configuration_T Configuration; BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation; @@ -1485,8 +1491,8 @@ static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter) from Host Adapter and initializes the Host Adapter structure. */ -static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T - *HostAdapter) +__initfunc(static boolean +BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_BoardID_T BoardID; BusLogic_Configuration_T Configuration; @@ -1999,8 +2005,8 @@ Common: Host Adapter. */ -static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T - *HostAdapter) +__initfunc(static boolean +BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T *HostAdapter)) { unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1; unsigned short SynchronousPermitted, FastPermitted; @@ -2225,7 +2231,8 @@ static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T Host Adapter. */ -static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_HostAdapter_T *FirstHostAdapter = BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel]; @@ -2311,7 +2318,8 @@ static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter) interrupts do not get through as a result. */ -static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)) { unsigned int InitialInterruptCount, FinalInterruptCount; int TestCount = 5, i; @@ -2600,9 +2608,10 @@ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T through explicit acquisition and release of the Host Adapter's Lock. */ -static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T - *HostAdapter, - SCSI_Host_T *Host) +__initfunc(static void +BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T + *HostAdapter, + SCSI_Host_T *Host)) { Host->max_id = HostAdapter->MaxTargetDevices; Host->max_lun = HostAdapter->MaxLogicalUnits; @@ -2673,7 +2682,7 @@ static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host, registered. */ -int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) +__initfunc(int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)) { int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0, ProbeIndex; char *MessageBuffer = NULL; diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 51c39e393..6ecc0f1aa 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -596,7 +596,7 @@ void NCR5380_timer_fn(void) { } #endif /* def USLEEP */ -static void NCR5380_all_init (void) { +static inline void NCR5380_all_init (void) { static int done = 0; if (!done) { #if (NDEBUG & NDEBUG_INIT) @@ -625,12 +625,12 @@ static void NCR5380_all_init (void) { */ -static int probe_irq; -static void probe_intr (int irq, void *dev_id, struct pt_regs * regs) { +static int probe_irq __initdata; +__initfunc(static void probe_intr (int irq, void *dev_id, struct pt_regs * regs)) { probe_irq = irq; }; -static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) { +__initfunc(static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible)) { NCR5380_local_declare(); struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; @@ -685,7 +685,7 @@ static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) { * Inputs : instance, pointer to this instance. Unused. */ -static void NCR5380_print_options (struct Scsi_Host *instance) { +__initfunc(static void NCR5380_print_options (struct Scsi_Host *instance)) { printk(" generic options" #ifdef AUTOPROBE_IRQ " AUTOPROBE_IRQ" @@ -900,7 +900,7 @@ char *lprint_opcode(int opcode, char *pos, char *buffer, int length) { * */ -static void NCR5380_init (struct Scsi_Host *instance, int flags) { +__initfunc(static void NCR5380_init (struct Scsi_Host *instance, int flags)) { NCR5380_local_declare(); int i, pass; unsigned long timeout; diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index 793f30608..e29af7ad8 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -238,7 +239,7 @@ struct signature { char *signature; int sig_offset; int sig_length; -} signatures[] = { +} signatures[] __initdata = { /* 1 2 3 4 5 6 */ /* 123456789012345678901234567890123456789012345678901234567890 */ { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82 }, @@ -458,8 +459,8 @@ static __inline__ int NCR53c406a_pio_write(unsigned char *request, } #endif USE_PIO -int -NCR53c406a_detect(Scsi_Host_Template * tpnt){ +__initfunc(int +NCR53c406a_detect(Scsi_Host_Template * tpnt)){ struct Scsi_Host *shpnt; #ifndef PORT_BASE int i; @@ -590,7 +591,7 @@ NCR53c406a_detect(Scsi_Host_Template * tpnt){ } /* called from init/main.c */ -void NCR53c406a_setup(char *str, int *ints) +__initfunc(void NCR53c406a_setup(char *str, int *ints)) { static size_t setup_idx = 0; size_t i; @@ -1011,7 +1012,7 @@ static void chip_init() outb(SYNC_MODE, SYNCOFF); /* synchronous mode */ } -void calc_port_addr() +__initfunc(void calc_port_addr()) { /* Control Register Set 0 */ TC_LSB = (port_base+0x00); diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 3659d6a25..a7cec9d06 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -542,6 +542,7 @@ #include #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) #include +#include #endif /* version >= v1.3.0 */ #include #include @@ -2953,8 +2954,8 @@ advansys_proc_info(char *buffer, char **start, off_t offset, int length, * it must not call SCSI mid-level functions including scsi_malloc() * and scsi_free(). */ -int -advansys_detect(Scsi_Host_Template *tpnt) +__initfunc(int +advansys_detect(Scsi_Host_Template *tpnt)) { static int detect_called = ASC_FALSE; int iop; @@ -5022,8 +5023,8 @@ asc_init_dev(ASC_DVC_VAR *asc_dvc_varp, Scsi_Cmnd *scp) /* * Search for an AdvanSys PCI device in the PCI configuration space. */ -STATIC int -asc_srch_pci_dev(PCI_DEVICE *pciDevice) +__initfunc(STATIC int +asc_srch_pci_dev(PCI_DEVICE *pciDevice)) { int ret; @@ -5059,8 +5060,8 @@ asc_srch_pci_dev(PCI_DEVICE *pciDevice) /* * Determine the access method to be used for 'pciDevice'. */ -STATIC uchar -asc_scan_method(void) +__initfunc(STATIC uchar +asc_scan_method(void)) { ushort data; PCI_DATA pciData; @@ -5089,8 +5090,8 @@ asc_scan_method(void) * * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND. */ -STATIC int -asc_pci_find_dev(PCI_DEVICE *pciDevice) +__initfunc(STATIC int +asc_pci_find_dev(PCI_DEVICE *pciDevice)) { PCI_DATA pciData; ushort vendorid, deviceid; @@ -5138,8 +5139,8 @@ asc_pci_find_dev(PCI_DEVICE *pciDevice) /* * Read PCI configuration data into 'pciConfig'. */ -STATIC void -asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig) +__initfunc(STATIC void +asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)) { PCI_DATA pciData; uchar counter; @@ -5168,8 +5169,8 @@ asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig) * * The configuration mechanism is checked for the correct access method. */ -STATIC ushort -asc_get_cfg_word(PCI_DATA *pciData) +__initfunc(STATIC ushort +asc_get_cfg_word(PCI_DATA *pciData)) { ushort tmp; ulong address; @@ -5249,8 +5250,8 @@ asc_get_cfg_word(PCI_DATA *pciData) * * The configuration mechanism is checked for the correct access method. */ -STATIC uchar -asc_get_cfg_byte(PCI_DATA *pciData) +__initfunc(STATIC uchar +asc_get_cfg_byte(PCI_DATA *pciData)) { uchar tmp; ulong address; @@ -5327,8 +5328,8 @@ asc_get_cfg_byte(PCI_DATA *pciData) /* * Write a byte to the PCI configuration space. */ -void -asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data) +__initfunc(void +asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)) { ulong tmpl; ulong address; @@ -6375,10 +6376,10 @@ DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords) /* * Read a PCI configuration byte. */ -uchar +__initfunc(uchar DvcReadPCIConfigByte( ASC_DVC_VAR asc_ptr_type *asc_dvc, - ushort offset ) + ushort offset )) { PCI_DATA pciData; @@ -6393,11 +6394,11 @@ DvcReadPCIConfigByte( /* * Write a PCI configuration byte. */ -void +__initfunc(void DvcWritePCIConfigByte( ASC_DVC_VAR asc_ptr_type *asc_dvc, ushort offset, - uchar byte_data ) + uchar byte_data )) { PCI_DATA pciData; @@ -6413,11 +6414,11 @@ DvcWritePCIConfigByte( * Return the BIOS address of the adapter at the specified * I/O port and with the specified bus type. */ -ushort +__initfunc(ushort AscGetChipBiosAddress( PortAddr iop_base, ushort bus_type - ) + )) { ushort cfg_lsw ; ushort bios_addr ; @@ -6927,11 +6928,11 @@ AscGetChipScsiCtrl( return (sc); } -uchar +__initfunc(uchar AscGetChipVersion( PortAddr iop_base, ushort bus_type -) +)) { if ((bus_type & ASC_IS_EISA) != 0) { PortAddr eisa_iop; @@ -6976,13 +6977,13 @@ AscGetChipBusType( return (0); } -ulong +__initfunc(ulong AscLoadMicroCode( PortAddr iop_base, ushort s_addr, ushort dosfar * mcode_buf, ushort mcode_size -) +)) { ulong chksum; ushort mcode_word_size; @@ -6999,10 +7000,10 @@ AscLoadMicroCode( return (chksum); } -int +__initfunc(int AscFindSignature( PortAddr iop_base -) +)) { ushort sig_word; if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) { @@ -7022,11 +7023,11 @@ PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8 }; -PortAddr +__initfunc(PortAddr AscSearchIOPortAddr( PortAddr iop_beg, ushort bus_type -) +)) { if (bus_type & ASC_IS_VL) { while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { @@ -7057,10 +7058,10 @@ AscSearchIOPortAddr( return (0); } -PortAddr +__initfunc(PortAddr AscSearchIOPortAddr11( PortAddr s_addr -) +)) { int i; PortAddr iop_base; @@ -7103,9 +7104,9 @@ uchar _hextbl_[16] = }; #endif -void +__initfunc(void AscSetISAPNPWaitForKey( - void) + void)) { outp(ASC_ISA_PNP_PORT_ADDR, 0x02); outp(ASC_ISA_PNP_PORT_WRITE, 0x02); @@ -7768,7 +7769,7 @@ AscScsiSetupCmdQ( return (0); } -uchar _mcode_buf[ ] = { +uchar _mcode_buf[ ] __initdata = { 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -9192,10 +9193,10 @@ DvcDelayNanoSecond( return; } -ulong +__initfunc(ulong AscGetEisaProductID( PortAddr iop_base -) +)) { PortAddr eisa_iop; ushort product_id_high, product_id_low; @@ -9207,10 +9208,10 @@ AscGetEisaProductID( return (product_id); } -PortAddr +__initfunc(PortAddr AscSearchIOPortAddrEISA( PortAddr iop_base -) +)) { ulong eisa_product_id; if (iop_base == 0) { @@ -9469,10 +9470,10 @@ AscGetIsaDmaSpeed( return (speed_value); } -ushort +__initfunc(ushort AscInitGetConfig( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { ushort warn_code; warn_code = 0; @@ -9500,10 +9501,10 @@ AscInitGetConfig( return (warn_code); } -ushort +__initfunc(ushort AscInitSetConfig( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { ushort warn_code; warn_code = 0; @@ -9519,10 +9520,10 @@ AscInitSetConfig( return (warn_code); } -ushort +__initfunc(ushort AscInitFromAscDvcVar( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { PortAddr iop_base; ushort cfg_msw; @@ -9603,10 +9604,10 @@ AscInitFromAscDvcVar( return (warn_code); } -ushort +__initfunc(ushort AscInitAsc1000Driver( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { ushort warn_code; PortAddr iop_base; @@ -9642,10 +9643,10 @@ AscInitAsc1000Driver( return (warn_code); } -ushort +__initfunc(ushort AscInitAscDvcVar( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { int i; PortAddr iop_base; diff --git a/drivers/scsi/aic7xxx.c b/drivers/scsi/aic7xxx.c index 1acc73f33..96e66defd 100644 --- a/drivers/scsi/aic7xxx.c +++ b/drivers/scsi/aic7xxx.c @@ -457,6 +457,7 @@ struct seeprom_config { * sections. */ #define PAUSE_SEQUENCER(p) \ + synchronize_irq(); \ outb(p->pause, HCNTRL + p->base); \ while ((inb(HCNTRL + p->base) & PAUSE) == 0) \ ; \ diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 081780cf8..f45c133d7 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -84,8 +84,9 @@ #include "NCR5380.h" #include "constants.h" #include "sd.h" -#include -#include +#include +#include +#include #define DTC_PUBLIC_RELEASE 2 @@ -145,9 +146,9 @@ static struct override { int irq; } overrides #ifdef OVERRIDE -[] = OVERRIDE; +[] __initdata = OVERRIDE; #else -[4] = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}}; +[4] __initdata = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}}; #endif #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) @@ -155,7 +156,7 @@ static struct override { static struct base { unsigned int address; int noauto; -} bases[] = {{0xcc000, 0}, {0xc8000, 0}, {0xdc000, 0}, {0xd8000, 0}}; +} bases[] __initdata = {{0xcc000, 0}, {0xc8000, 0}, {0xdc000, 0}, {0xd8000, 0}}; #define NO_BASES (sizeof (bases) / sizeof (struct base)) @@ -176,7 +177,7 @@ static const struct signature { * */ -void dtc_setup(char *str, int *ints) { +__initfunc(void dtc_setup(char *str, int *ints)) { static int commandline_current = 0; int i; if (ints[0] != 2) @@ -208,7 +209,7 @@ void dtc_setup(char *str, int *ints) { */ -int dtc_detect(Scsi_Host_Template * tpnt) { +__initfunc(int dtc_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0, current_base = 0; struct Scsi_Host *instance; unsigned int base; diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 9b1769e5b..96e4a0eca 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -103,7 +103,8 @@ #include "NCR5380.h" #include "constants.h" #include "sd.h" -#include +#include +#include struct proc_dir_entry proc_scsi_g_ncr5380 = { PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380", @@ -124,9 +125,9 @@ static struct override { int board; /* Use NCR53c400, Ricoh, etc. extensions ? */ } overrides #ifdef GENERIC_NCR5380_OVERRIDE - [] = GENERIC_NCR5380_OVERRIDE + [] __initdata = GENERIC_NCR5380_OVERRIDE #else - [1] = {{0,},}; + [1] __initdata = {{0,},}; #endif #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) @@ -142,7 +143,7 @@ static struct override { * */ -static void internal_setup(int board, char *str, int *ints) { +__initfunc(static void internal_setup(int board, char *str, int *ints)) { static int commandline_current = 0; switch (board) { case BOARD_NCR5380: @@ -178,7 +179,7 @@ static void internal_setup(int board, char *str, int *ints) { * equal to the number of ints. */ -void generic_NCR5380_setup (char *str, int *ints) { +__initfunc(void generic_NCR5380_setup (char *str, int *ints)) { internal_setup (BOARD_NCR5380, str, ints); } @@ -191,7 +192,7 @@ void generic_NCR5380_setup (char *str, int *ints) { * equal to the number of ints. */ -void generic_NCR53C400_setup (char *str, int *ints) { +__initfunc(void generic_NCR53C400_setup (char *str, int *ints)) { internal_setup (BOARD_NCR53C400, str, ints); } @@ -207,7 +208,7 @@ void generic_NCR53C400_setup (char *str, int *ints) { * */ -int generic_NCR5380_detect(Scsi_Host_Template * tpnt) { +__initfunc(int generic_NCR5380_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0; int count; int flags = 0; diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 795d1286d..0c1e2df31 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "scsi.h" @@ -433,7 +434,7 @@ scsi_register_device(struct Scsi_Device_Template * sdpnt) return 0; } -unsigned int scsi_init() +__initfunc(unsigned int scsi_init(void)) { static int called = 0; int i, pcount; diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index e737b812b..f82bb2aa4 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -1735,7 +1735,7 @@ static int ncr_debug = SCSI_NCR_DEBUG_FLAGS; static char *ncr_name (ncb_p np) { - static char name[10]; + static char name[16]; sprintf(name, "ncr53c%d-%d", np->chip, np->unit); return (name); } diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h index 7cfcc53c5..3c0c7fb03 100644 --- a/drivers/scsi/ncr53c8xx.h +++ b/drivers/scsi/ncr53c8xx.h @@ -45,7 +45,7 @@ /* ** Name and revision of the driver */ -#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.18e" +#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.18f" /* ** If SCSI_NCR_SETUP_SPECIAL_FEATURES is defined, diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index a08ff1e62..507080dd0 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -120,7 +120,8 @@ #include "constants.h" #include "sd.h" -#include +#include +#include struct proc_dir_entry proc_scsi_pas16 = { PROC_SCSI_PAS16, 5, "pas16", @@ -138,20 +139,21 @@ int scsi_irq_translate[] = * irq jumpers on the board). The first value in the array will be * assigned to logical board 0, the next to board 1, etc. */ -int default_irqs[] = { PAS16_DEFAULT_BOARD_1_IRQ, - PAS16_DEFAULT_BOARD_2_IRQ, - PAS16_DEFAULT_BOARD_3_IRQ, - PAS16_DEFAULT_BOARD_4_IRQ - }; +int default_irqs[] __initdata = + { PAS16_DEFAULT_BOARD_1_IRQ, + PAS16_DEFAULT_BOARD_2_IRQ, + PAS16_DEFAULT_BOARD_3_IRQ, + PAS16_DEFAULT_BOARD_4_IRQ + }; static struct override { unsigned short io_port; int irq; } overrides #ifdef PAS16_OVERRIDE - [] = PAS16_OVERRIDE; + [] __initdata = PAS16_OVERRIDE; #else - [4] = {{0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO}, + [4] __initdata = {{0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO}}; #endif @@ -160,11 +162,12 @@ static struct override { static struct base { unsigned short io_port; int noauto; -} bases[] = { {PAS16_DEFAULT_BASE_1, 0}, - {PAS16_DEFAULT_BASE_2, 0}, - {PAS16_DEFAULT_BASE_3, 0}, - {PAS16_DEFAULT_BASE_4, 0} - }; +} bases[] __initdata = + { {PAS16_DEFAULT_BASE_1, 0}, + {PAS16_DEFAULT_BASE_2, 0}, + {PAS16_DEFAULT_BASE_3, 0}, + {PAS16_DEFAULT_BASE_4, 0} + }; #define NO_BASES (sizeof (bases) / sizeof (struct base)) @@ -210,7 +213,8 @@ unsigned short pas16_offset[ 8 ] = * */ -void enable_board( int board_num, unsigned short port ) +__initfunc(static void + enable_board( int board_num, unsigned short port )) { outb( 0xbc + board_num, MASTER_ADDRESS_PTR ); outb( port >> 2, MASTER_ADDRESS_PTR ); @@ -229,7 +233,8 @@ void enable_board( int board_num, unsigned short port ) * */ -void init_board( unsigned short io_port, int irq, int force_irq ) +__initfunc (static void + init_board( unsigned short io_port, int irq, int force_irq )) { unsigned int tmp; unsigned int pas_irq_code; @@ -277,7 +282,8 @@ void init_board( unsigned short io_port, int irq, int force_irq ) * Returns : 0 if board not found, 1 if found. */ -int pas16_hw_detect( unsigned short board_num ) +__initfunc(static int + pas16_hw_detect( unsigned short board_num )) { unsigned char board_rev, tmp; unsigned short io_port = bases[ board_num ].io_port; @@ -336,7 +342,7 @@ int pas16_hw_detect( unsigned short board_num ) * */ -void pas16_setup(char *str, int *ints) { +__initfunc(void pas16_setup(char *str, int *ints)) { static int commandline_current = 0; int i; if (ints[0] != 2) @@ -367,7 +373,7 @@ void pas16_setup(char *str, int *ints) { * */ -int pas16_detect(Scsi_Host_Template * tpnt) { +__initfunc(int pas16_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0; static unsigned short current_base = 0; struct Scsi_Host *instance; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2d9ae7eae..9f851a277 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -2537,7 +2538,7 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt) * initialization, bus scanning, and sd/st initialization routines. */ -int scsi_dev_init(void) +__initfunc(int scsi_dev_init(void)) { Scsi_Device * SDpnt; struct Scsi_Host * shpnt; diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index c42de5fcb..a8a4a8934 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -118,7 +118,8 @@ #include "NCR5380.h" #include "constants.h" #include "sd.h" -#include +#include +#include struct proc_dir_entry proc_scsi_t128 = { PROC_SCSI_T128, 4, "t128", @@ -131,10 +132,10 @@ static struct override { int irq; } overrides #ifdef T128_OVERRIDE - [] = T128_OVERRIDE; + [] __initdata = T128_OVERRIDE; #else - [4] = {{NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, - {NULL,IRQ_AUTO}}; + [4] __initdata = {{NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, + {NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}}; #endif #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) @@ -142,7 +143,8 @@ static struct override { static struct base { unsigned char *address; int noauto; -} bases[] = {{(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0}, +} bases[] __initdata = { + {(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0}, {(unsigned char *) 0xdc000, 0}, {(unsigned char *) 0xd8000, 0}}; #define NO_BASES (sizeof (bases) / sizeof (struct base)) @@ -150,7 +152,7 @@ static struct base { static const struct signature { const char *string; int offset; -} signatures[] = { +} signatures[] __initdata = { {"TSROM: SCSI BIOS, Version 1.12", 0x36}, }; @@ -166,7 +168,7 @@ static const struct signature { * */ -void t128_setup(char *str, int *ints) { +__initfunc(void t128_setup(char *str, int *ints)) { static int commandline_current = 0; int i; if (ints[0] != 2) @@ -197,7 +199,7 @@ void t128_setup(char *str, int *ints) { * */ -int t128_detect(Scsi_Host_Template * tpnt) { +__initfunc(int t128_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0, current_base = 0; struct Scsi_Host *instance; unsigned char *base; diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c index e724ddd07..7bd71f212 100644 --- a/fs/binfmt_em86.c +++ b/fs/binfmt_em86.c @@ -14,6 +14,8 @@ #include #include #include +#include + #define EM86_INTERP "/usr/bin/em86" #define EM86_I_NAME "em86" diff --git a/fs/buffer.c b/fs/buffer.c index 43a40846e..27950290a 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -14,7 +14,12 @@ /* Start bdflush() with kernel_thread not syscall - Paul Gortmaker, 12/95 */ /* Removed a lot of unnecessary code and simplified things now that - the buffer cache isn't our primary cache - Andrew Tridgell 12/96 */ + * the buffer cache isn't our primary cache - Andrew Tridgell 12/96 + */ + +/* Speed up hash, lru, and free list operations. Use gfp() for allocating + * hash table, use SLAB cache for buffer heads. -DaveM + */ #include #include @@ -23,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +51,7 @@ static char buffersize_index[17] = #define MAX_UNUSED_BUFFERS 30 /* don't ever have more than this number of unused buffer heads */ #define HASH_PAGES 4 /* number of pages to use for the hash table */ +#define HASH_PAGES_ORDER 2 #define NR_HASH (HASH_PAGES*PAGE_SIZE/sizeof(struct buffer_head *)) #define HASH_MASK (NR_HASH-1) @@ -54,6 +61,8 @@ static struct buffer_head ** hash_table; static struct buffer_head * lru_list[NR_LIST] = {NULL, }; static struct buffer_head * free_list[NR_SIZES] = {NULL, }; +static kmem_cache_t *bh_cachep; + static struct buffer_head * unused_list = NULL; static struct buffer_head * reuse_list = NULL; static struct wait_queue * buffer_wait = NULL; @@ -65,7 +74,7 @@ static int nr_unused_buffer_heads = 0; static int refilled = 0; /* Set NZ when a buffer freelist is refilled this is used by the loop device */ -/* this is used by some architectures to estimate available memory */ +/* This is used by some architectures to estimate available memory. */ int buffermem = 0; /* Here is the parameter block for the bdflush process. If you add or @@ -76,8 +85,9 @@ static void wakeup_bdflush(int); #define N_PARAM 9 -/* the dummy values in this structure are left in there for compatibility - with old programs that play with the /proc entries */ +/* The dummy values in this structure are left in there for compatibility + * with old programs that play with the /proc entries. + */ union bdflush_param{ struct { int nfract; /* Percentage of buffer cache dirty to @@ -131,29 +141,31 @@ repeat: } /* Call sync_buffers with wait!=0 to ensure that the call does not - return until all buffer writes have completed. Sync() may return - before the writes have finished; fsync() may not. */ - + * return until all buffer writes have completed. Sync() may return + * before the writes have finished; fsync() may not. + */ /* Godamity-damn. Some buffers (bitmaps for filesystems) - spontaneously dirty themselves without ever brelse being called. - We will ultimately want to put these in a separate list, but for - now we search all of the lists for dirty buffers */ - + * spontaneously dirty themselves without ever brelse being called. + * We will ultimately want to put these in a separate list, but for + * now we search all of the lists for dirty buffers. + */ static int sync_buffers(kdev_t dev, int wait) { int i, retry, pass = 0, err = 0; struct buffer_head * bh, *next; /* One pass for no-wait, three for wait: - 0) write out all dirty, unlocked buffers; - 1) write out all dirty buffers, waiting if locked; - 2) wait for completion by waiting for all buffers to unlock. */ + * 0) write out all dirty, unlocked buffers; + * 1) write out all dirty buffers, waiting if locked; + * 2) wait for completion by waiting for all buffers to unlock. + */ do { retry = 0; repeat: - /* We search all lists as a failsafe mechanism, not because we expect - there to be dirty buffers on any of the other lists. */ + /* We search all lists as a failsafe mechanism, not because we expect + * there to be dirty buffers on any of the other lists. + */ bh = lru_list[BUF_DIRTY]; if (!bh) goto repeat2; @@ -167,7 +179,8 @@ repeat: continue; if (buffer_locked(bh)) { /* Buffer is locked; skip it unless wait is - requested AND pass > 0. */ + * requested AND pass > 0. + */ if (!wait || !pass) { retry = 1; continue; @@ -175,18 +188,27 @@ repeat: wait_on_buffer (bh); goto repeat; } + /* If an unlocked buffer is not uptodate, there has - been an IO error. Skip it. */ + * been an IO error. Skip it. + */ if (wait && buffer_req(bh) && !buffer_locked(bh) && !buffer_dirty(bh) && !buffer_uptodate(bh)) { err = 1; continue; } + /* Don't write clean buffers. Don't write ANY buffers - on the third pass. */ + * on the third pass. + */ if (!buffer_dirty(bh) || pass >= 2) continue; - /* don't bother about locked buffers */ + + /* Don't bother about locked buffers. + * + * XXX We checked if it was locked above and there is no + * XXX way we could have slept in between. -DaveM + */ if (buffer_locked(bh)) continue; bh->b_count++; @@ -212,7 +234,8 @@ repeat: continue; if (buffer_locked(bh)) { /* Buffer is locked; skip it unless wait is - requested AND pass > 0. */ + * requested AND pass > 0. + */ if (!wait || !pass) { retry = 1; continue; @@ -222,10 +245,11 @@ repeat: } } - /* If we are waiting for the sync to succeed, and if any dirty - blocks were written, then repeat; on the second pass, only - wait for buffers being written (do not pass to write any - more buffers on the second pass). */ + /* If we are waiting for the sync to succeed, and if any dirty + * blocks were written, then repeat; on the second pass, only + * wait for buffers being written (do not pass to write any + * more buffers on the second pass). + */ } while (wait && retry && ++pass<=2); return err; } @@ -330,13 +354,12 @@ void invalidate_buffers(kdev_t dev) static inline void remove_from_hash_queue(struct buffer_head * bh) { - if (bh->b_next) - bh->b_next->b_prev = bh->b_prev; - if (bh->b_prev) - bh->b_prev->b_next = bh->b_next; - if (hash(bh->b_dev,bh->b_blocknr) == bh) - hash(bh->b_dev,bh->b_blocknr) = bh->b_next; - bh->b_next = bh->b_prev = NULL; + if (bh->b_pprev) { + if(bh->b_next) + bh->b_next->b_pprev = bh->b_pprev; + *bh->b_pprev = bh->b_next; + bh->b_pprev = NULL; + } } static inline void remove_from_lru_list(struct buffer_head * bh) @@ -389,46 +412,49 @@ static inline void remove_from_queues(struct buffer_head * bh) static inline void put_last_lru(struct buffer_head * bh) { - if (!bh) - return; - if (bh == lru_list[bh->b_list]) { - lru_list[bh->b_list] = bh->b_next_free; - return; - } - if(bh->b_dev == B_FREE) - panic("Wrong block for lru list"); - remove_from_lru_list(bh); -/* add to back of free list */ + if (bh) { + struct buffer_head **bhp = &lru_list[bh->b_list]; - if(!lru_list[bh->b_list]) { - lru_list[bh->b_list] = bh; - lru_list[bh->b_list]->b_prev_free = bh; - } + if (bh == *bhp) { + *bhp = bh->b_next_free; + return; + } + + if(bh->b_dev == B_FREE) + panic("Wrong block for lru list"); + + /* Add to back of free list. */ + remove_from_lru_list(bh); + if(!*bhp) { + *bhp = bh; + (*bhp)->b_prev_free = bh; + } - bh->b_next_free = lru_list[bh->b_list]; - bh->b_prev_free = lru_list[bh->b_list]->b_prev_free; - lru_list[bh->b_list]->b_prev_free->b_next_free = bh; - lru_list[bh->b_list]->b_prev_free = bh; + bh->b_next_free = *bhp; + bh->b_prev_free = (*bhp)->b_prev_free; + (*bhp)->b_prev_free->b_next_free = bh; + (*bhp)->b_prev_free = bh; + } } static inline void put_last_free(struct buffer_head * bh) { - int isize; - if (!bh) - return; + if (bh) { + struct buffer_head **bhp = &free_list[BUFSIZE_INDEX(bh->b_size)]; - isize = BUFSIZE_INDEX(bh->b_size); - bh->b_dev = B_FREE; /* So it is obvious we are on the free list */ - /* add to back of free list */ - if(!free_list[isize]) { - free_list[isize] = bh; - bh->b_prev_free = bh; - } + bh->b_dev = B_FREE; /* So it is obvious we are on the free list. */ - bh->b_next_free = free_list[isize]; - bh->b_prev_free = free_list[isize]->b_prev_free; - free_list[isize]->b_prev_free->b_next_free = bh; - free_list[isize]->b_prev_free = bh; + /* Add to back of free list. */ + if(!*bhp) { + *bhp = bh; + bh->b_prev_free = bh; + } + + bh->b_next_free = *bhp; + bh->b_prev_free = (*bhp)->b_prev_free; + (*bhp)->b_prev_free->b_next_free = bh; + (*bhp)->b_prev_free = bh; + } } static inline void insert_into_queues(struct buffer_head * bh) @@ -436,28 +462,34 @@ static inline void insert_into_queues(struct buffer_head * bh) /* put at end of free list */ if(bh->b_dev == B_FREE) { put_last_free(bh); - return; - } - if(!lru_list[bh->b_list]) { - lru_list[bh->b_list] = bh; - bh->b_prev_free = bh; - } + } else { + struct buffer_head **bhp = &lru_list[bh->b_list]; - if (bh->b_next_free) panic("VFS: buffer LRU pointers corrupted"); - bh->b_next_free = lru_list[bh->b_list]; - bh->b_prev_free = lru_list[bh->b_list]->b_prev_free; - lru_list[bh->b_list]->b_prev_free->b_next_free = bh; - lru_list[bh->b_list]->b_prev_free = bh; - nr_buffers_type[bh->b_list]++; -/* put the buffer in new hash-queue if it has a device */ - bh->b_prev = NULL; - bh->b_next = NULL; - if (!(bh->b_dev)) - return; - bh->b_next = hash(bh->b_dev,bh->b_blocknr); - hash(bh->b_dev,bh->b_blocknr) = bh; - if (bh->b_next) - bh->b_next->b_prev = bh; + if(!*bhp) { + *bhp = bh; + bh->b_prev_free = bh; + } + + if (bh->b_next_free) + panic("VFS: buffer LRU pointers corrupted"); + + bh->b_next_free = *bhp; + bh->b_prev_free = (*bhp)->b_prev_free; + (*bhp)->b_prev_free->b_next_free = bh; + (*bhp)->b_prev_free = bh; + + nr_buffers_type[bh->b_list]++; + + /* Put the buffer in new hash-queue if it has a device. */ + if (bh->b_dev) { + struct buffer_head **bhp = &hash(bh->b_dev, bh->b_blocknr); + if((bh->b_next = *bhp) != NULL) + (*bhp)->b_pprev = &bh->b_next; + *bhp = bh; + bh->b_pprev = bhp; /* Exists in bh hashes. */ + } else + bh->b_pprev = NULL; /* Not in bh hashes. */ + } } static inline struct buffer_head * find_buffer(kdev_t dev, int block, int size) @@ -465,14 +497,14 @@ static inline struct buffer_head * find_buffer(kdev_t dev, int block, int size) struct buffer_head * tmp; for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next) - if (tmp->b_blocknr == block && tmp->b_dev == dev) + if (tmp->b_blocknr == block && tmp->b_dev == dev) { if (tmp->b_size == size) return tmp; - else { - printk("VFS: Wrong blocksize on device %s\n", - kdevname(dev)); - return NULL; - } + + printk("VFS: Wrong blocksize on device %s\n", + kdevname(dev)); + return NULL; + } return NULL; } @@ -492,8 +524,9 @@ struct buffer_head * get_hash_table(kdev_t dev, int block, int size) return NULL; bh->b_count++; wait_on_buffer(bh); - if (bh->b_dev == dev && bh->b_blocknr == block - && bh->b_size == size) + if (bh->b_dev == dev && + bh->b_blocknr == block && + bh->b_size == size) return bh; bh->b_count--; } @@ -501,27 +534,21 @@ struct buffer_head * get_hash_table(kdev_t dev, int block, int size) unsigned int get_hardblocksize(kdev_t dev) { - int blksize = 0; - - /* - * Get the hard sector size for the given device. If we don't know - * what it is, return 0. - */ - - if (hardsect_size[MAJOR(dev)] != NULL) - { - blksize = hardsect_size[MAJOR(dev)][MINOR(dev)]; - if (blksize != 0) - { - return blksize; + /* + * Get the hard sector size for the given device. If we don't know + * what it is, return 0. + */ + if (hardsect_size[MAJOR(dev)] != NULL) { + int blksize = hardsect_size[MAJOR(dev)][MINOR(dev)]; + if (blksize != 0) + return blksize; } - } - /* - * We don't know what the hardware sector size for this device is. - * Return 0 indicating that we don't know. - */ - return 0; + /* + * We don't know what the hardware sector size for this device is. + * Return 0 indicating that we don't know. + */ + return 0; } void set_blocksize(kdev_t dev, int size) @@ -550,13 +577,15 @@ void set_blocksize(kdev_t dev, int size) sync_buffers(dev, 2); blksize_size[MAJOR(dev)][MINOR(dev)] = size; - /* We need to be quite careful how we do this - we are moving entries - around on the free list, and we can get in a loop if we are not careful.*/ - + /* We need to be quite careful how we do this - we are moving entries + * around on the free list, and we can get in a loop if we are not careful. + */ for(nlist = 0; nlist < NR_LIST; nlist++) { bh = lru_list[nlist]; for (i = nr_buffers_type[nlist]*2 ; --i > 0 ; bh = bhnext) { - if(!bh) break; + if(!bh) + break; + bhnext = bh->b_next_free; if (bh->b_dev != dev) continue; @@ -575,12 +604,12 @@ void set_blocksize(kdev_t dev, int size) } } - -/* check if a buffer is OK to be reclaimed */ +/* Check if a buffer is OK to be reclaimed. */ static inline int can_reclaim(struct buffer_head *bh, int size) { - if (bh->b_count || - buffer_protected(bh) || buffer_locked(bh)) + if (bh->b_count || + buffer_protected(bh) || + buffer_locked(bh)) return 0; if (atomic_read(&mem_map[MAP_NR((unsigned long) bh->b_data)].count) != 1 || @@ -595,8 +624,9 @@ static inline int can_reclaim(struct buffer_head *bh, int size) return 1; } -/* find a candidate buffer to be reclaimed */ -static struct buffer_head *find_candidate(struct buffer_head *list,int *list_len,int size) +/* Find a candidate buffer to be reclaimed. */ +static struct buffer_head *find_candidate(struct buffer_head *list, + int *list_len, int size) { struct buffer_head *bh; @@ -604,19 +634,23 @@ static struct buffer_head *find_candidate(struct buffer_head *list,int *list_len bh && (*list_len) > 0; bh = bh->b_next_free, (*list_len)--) { if (size != bh->b_size) { - /* this provides a mechanism for freeing blocks - of other sizes, this is necessary now that we - no longer have the lav code. */ + /* This provides a mechanism for freeing blocks + * of other sizes, this is necessary now that we + * no longer have the lav code. + */ try_to_free_buffer(bh,&bh,1); + if (!bh) + break; continue; } if (buffer_locked(bh) && (bh->b_list == BUF_LOCKED || bh->b_list == BUF_LOCKED1)) { /* Buffers are written in the order they are placed - on the locked list. If we encounter a locked - buffer here, this means that the rest of them - are also locked */ + * on the locked list. If we encounter a locked + * buffer here, this means that the rest of them + * are also locked. + */ (*list_len) = 0; return NULL; } @@ -639,74 +673,81 @@ static void refill_freelist(int size) refilled = 1; /* If there are too many dirty buffers, we wake up the update process - now so as to ensure that there are still clean buffers available - for user processes to use (and dirty) */ + * now so as to ensure that there are still clean buffers available + * for user processes to use (and dirty). + */ - /* We are going to try to locate this much memory */ - needed =bdf_prm.b_un.nrefill * size; + /* We are going to try to locate this much memory. */ + needed = bdf_prm.b_un.nrefill * size; - while (nr_free_pages > min_free_pages*2 && needed > 0 && - grow_buffers(GFP_BUFFER, size)) { + while ((nr_free_pages > min_free_pages*2) && + (needed > 0) && + grow_buffers(GFP_BUFFER, size)) needed -= PAGE_SIZE; - } repeat: /* OK, we cannot grow the buffer cache, now try to get some - from the lru list */ - - /* First set the candidate pointers to usable buffers. This - should be quick nearly all of the time. */ + * from the lru list. + * + * First set the candidate pointers to usable buffers. This + * should be quick nearly all of the time. + */ - if(needed <= 0) return; + if(needed <= 0) + return; - for(i=0; ib_lru_time < best_time){ + for(i=0; ib_lru_time < best_time) { best_time = candidate[i]->b_lru_time; winner = i; } } - /* If we have a winner, use it, and then get a new candidate from that list */ + /* If we have a winner, use it, and then get a new candidate from that list. */ if(winner != UINT_MAX) { i = winner; while (needed>0 && (bh=candidate[i])) { candidate[i] = bh->b_next_free; - if(candidate[i] == bh) candidate[i] = NULL; /* Got last one */ + if(candidate[i] == bh) + candidate[i] = NULL; /* Got last one */ remove_from_queues(bh); bh->b_dev = B_FREE; put_last_free(bh); needed -= bh->b_size; buffers[i]--; - if(buffers[i] == 0) candidate[i] = NULL; + if(buffers[i] == 0) + candidate[i] = NULL; if (candidate[i] && !can_reclaim(candidate[i],size)) - candidate[i] = find_candidate(candidate[i],&buffers[i], size); + candidate[i] = find_candidate(candidate[i], + &buffers[i], size); } if (needed >= 0) goto repeat; } - if(needed <= 0) return; + if(needed <= 0) + return; /* Too bad, that was not enough. Try a little harder to grow some. */ - if (nr_free_pages > min_free_pages + 5) { if (grow_buffers(GFP_BUFFER, size)) { needed -= PAGE_SIZE; goto repeat; - }; + } } - /* and repeat until we find something good */ + /* And repeat until we find something good. */ if (!grow_buffers(GFP_ATOMIC, size)) wakeup_bdflush(1); needed -= PAGE_SIZE; @@ -729,8 +770,9 @@ struct buffer_head * getblk(kdev_t dev, int block, int size) int isize = BUFSIZE_INDEX(size); /* If there are too many dirty buffers, we wake up the update process - now so as to ensure that there are still clean buffers available - for user processes to use (and dirty) */ + * now so as to ensure that there are still clean buffers available + * for user processes to use (and dirty). + */ repeat: bh = get_hash_table(dev, block, size); if (bh) { @@ -743,9 +785,8 @@ repeat: return bh; } - while(!free_list[isize]) { + while(!free_list[isize]) refill_freelist(size); - } if (find_buffer(dev,block,size)) goto repeat; @@ -753,8 +794,9 @@ repeat: bh = free_list[isize]; remove_from_free_list(bh); -/* OK, FINALLY we know that this buffer is the only one of its kind, */ -/* and that it's unused (b_count=0), unlocked (buffer_locked=0), and clean */ + /* OK, FINALLY we know that this buffer is the only one of its kind, + * and that it's unused (b_count=0), unlocked (buffer_locked=0), and clean. + */ bh->b_count=1; bh->b_flushtime=0; bh->b_state=(1<b_flushtime || buf->b_flushtime > newtime) @@ -798,8 +840,9 @@ void refile_buffer(struct buffer_head * buf) dispose = BUF_LOCKED; else dispose = BUF_CLEAN; - if(dispose == BUF_CLEAN) buf->b_lru_time = jiffies; - if(dispose != buf->b_list) { + if(dispose == BUF_CLEAN) + buf->b_lru_time = jiffies; + if(dispose != buf->b_list) { if(dispose == BUF_DIRTY) buf->b_lru_time = jiffies; if(dispose == BUF_LOCKED && @@ -809,16 +852,21 @@ void refile_buffer(struct buffer_head * buf) buf->b_list = dispose; insert_into_queues(buf); if (dispose == BUF_DIRTY) { - /* This buffer is dirty, maybe we need to start flushing. */ - /* If too high a percentage of the buffers are dirty... */ - if (nr_buffers_type[BUF_DIRTY] > nr_buffers * bdf_prm.b_un.nfract/100) - wakeup_bdflush(0); - /* If this is a loop device, and - * more than half of the buffers are dirty... */ - /* (Prevents no-free-buffers deadlock with loop device.) */ - if (MAJOR(buf->b_dev) == LOOP_MAJOR && - nr_buffers_type[BUF_DIRTY]*2>nr_buffers) - wakeup_bdflush(1); + int too_many = (nr_buffers * bdf_prm.b_un.nfract/100); + + /* This buffer is dirty, maybe we need to start flushing. + * If too high a percentage of the buffers are dirty... + */ + if (nr_buffers_type[BUF_DIRTY] > too_many) + wakeup_bdflush(0); + + /* If this is a loop device, and + * more than half of the buffers are dirty... + * (Prevents no-free-buffers deadlock with loop device.) + */ + if (MAJOR(buf->b_dev) == LOOP_MAJOR && + nr_buffers_type[BUF_DIRTY]*2>nr_buffers) + wakeup_bdflush(1); } } } @@ -830,7 +878,7 @@ void __brelse(struct buffer_head * buf) { wait_on_buffer(buf); - /* If dirty, mark the time this buffer should be written back */ + /* If dirty, mark the time this buffer should be written back. */ set_writetime(buf, 0); refile_buffer(buf); @@ -929,13 +977,13 @@ struct buffer_head * breada(kdev_t dev, int block, int bufsize, else bhlist[j++] = bh; } - /* Request the read for these buffers, and then release them */ + /* Request the read for these buffers, and then release them. */ if (j>1) ll_rw_block(READA, (j-1), bhlist+1); for(i=1; i= MAX_UNUSED_BUFFERS) { nr_buffer_heads--; - kfree(bh); + kmem_cache_free(bh_cachep, bh); return; } memset(bh,0,sizeof(*bh)); @@ -963,23 +1011,17 @@ static void get_more_buffer_heads(void) struct buffer_head * bh; while (!unused_list) { - /* - * This is critical. We can't swap out pages to get + /* This is critical. We can't swap out pages to get * more buffer heads, because the swap-out may need - * more buffer-heads itself. Thus GFP_ATOMIC. + * more buffer-heads itself. Thus SLAB_ATOMIC. */ - /* we now use kmalloc() here instead of gfp as we want - to be able to easily release buffer heads - they - took up quite a bit of memory (tridge) */ - bh = (struct buffer_head *) kmalloc(sizeof(*bh),GFP_ATOMIC); - if (bh) { + if((bh = kmem_cache_alloc(bh_cachep, SLAB_ATOMIC)) != NULL) { put_unused_buffer_head(bh); nr_buffer_heads++; return; } - /* - * Uhhuh. We're _really_ low on memory. Now we just + /* Uhhuh. We're _really_ low on memory. Now we just * wait for old buffer heads to become free due to * finishing IO.. */ @@ -1414,12 +1456,11 @@ int try_to_free_buffer(struct buffer_head * bh, struct buffer_head ** bhp, p = tmp; tmp = tmp->b_this_page; nr_buffers--; - if (p == *bhp) - { - *bhp = p->b_prev_free; - if (p == *bhp) /* Was this the last in the list? */ - *bhp = NULL; - } + if (p == *bhp) { + *bhp = p->b_prev_free; + if (p == *bhp) /* Was this the last in the list? */ + *bhp = NULL; + } remove_from_queues(p); put_unused_buffer_head(p); } while (tmp != bh); @@ -1472,14 +1513,24 @@ void show_buffers(void) /* * allocate the hash table and init the free list + * Use gfp() for the hash table to decrease TLB misses, use + * SLAB cache for buffer heads. */ void buffer_init(void) { - hash_table = (struct buffer_head **)vmalloc(NR_HASH*sizeof(struct buffer_head *)); + hash_table = (struct buffer_head **) + __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER, 0); if (!hash_table) panic("Failed to allocate buffer hash table\n"); memset(hash_table,0,NR_HASH*sizeof(struct buffer_head *)); + bh_cachep = kmem_cache_create("buffer_head", + sizeof(struct buffer_head), + sizeof(unsigned long) * 4, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if(!bh_cachep) + panic("Cannot create buffer head SLAB cache\n"); + lru_list[BUF_CLEAN] = 0; grow_buffers(GFP_KERNEL, BLOCK_SIZE); } @@ -1745,21 +1796,3 @@ int bdflush(void * unused) } } } - - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 8 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -8 - * c-argdecl-indent: 8 - * c-label-offset: -8 - * c-continued-statement-offset: 8 - * c-continued-brace-offset: 0 - * End: - */ diff --git a/fs/dcache.c b/fs/dcache.c index 3f2361780..2dc317aad 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -4,6 +4,8 @@ * (C) Copyright 1994 Linus Torvalds */ +/* Speeded up searches a bit and threaded the mess. -DaveM */ + /* * The directory cache is a "two-level" cache, each level doing LRU on * its entries. Adding new entries puts them at the end of the LRU @@ -22,6 +24,9 @@ #include #include +#include + +spinlock_t dcache_lock = SPIN_LOCK_UNLOCKED; /* * Don't bother caching long names.. They just take up space in the cache, and @@ -30,18 +35,14 @@ */ #define DCACHE_NAME_LEN 15 #define DCACHE_SIZE 1024 -#define DCACHE_HASH_QUEUES 256 - -struct hash_list { - struct dir_cache_entry * next; - struct dir_cache_entry * prev; -}; +#define DCACHE_HASH_QUEUES 256 /* keep this a pow2 */ /* * The dir_cache_entry must be in this order: we do ugly things with the pointers */ struct dir_cache_entry { - struct hash_list h; + struct dir_cache_entry *next; + struct dir_cache_entry **pprev; kdev_t dc_dev; unsigned long dir; unsigned long version; @@ -68,13 +69,34 @@ static struct dir_cache_entry level2_cache[DCACHE_SIZE]; static struct dir_cache_entry * level1_head; static struct dir_cache_entry * level2_head; +/* The hash queues are layed out in a slightly different manner. */ +static struct dir_cache_entry *hash_table[DCACHE_HASH_QUEUES]; + +#define hash_fn(dev,dir,namehash) \ + ((HASHDEV(dev) ^ (dir) ^ (namehash)) & (DCACHE_HASH_QUEUES - 1)) + /* - * The hash-queues are also doubly-linked circular lists, but the head is - * itself on the doubly-linked list, not just a pointer to the first entry. + * Stupid name"hash" algorithm. Write something better if you want to, + * but I doubt it matters that much. */ -#define hash_fn(dev,dir,namehash) ((HASHDEV(dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES) +static unsigned long namehash(const char * name, int len) +{ + unsigned long hash = 0; -static struct hash_list hash_table[DCACHE_HASH_QUEUES]; + while ((len -= sizeof(unsigned long)) > 0) { + hash += get_unaligned((unsigned long *)name); + name += sizeof(unsigned long); + } + return hash + + (get_unaligned((unsigned long *)name) & + ~(~0UL << ((len + sizeof(unsigned long)) << 3))); +} + +static inline struct dir_cache_entry **get_hlist(struct inode *dir, + const char *name, int len) +{ + return hash_table + hash_fn(dir->i_dev, dir->i_ino, namehash(name, len)); +} static inline void remove_lru(struct dir_cache_entry * de) { @@ -106,78 +128,50 @@ static inline void update_lru(struct dir_cache_entry * de) } /* - * Stupid name"hash" algorithm. Write something better if you want to, - * but I doubt it matters that much - */ -static inline unsigned long namehash(const char * name, int len) -{ - if (len >= sizeof(unsigned long)) - return len + - get_unaligned((unsigned long *) name) + - get_unaligned((unsigned long *) (name + len - sizeof(unsigned long))); - return len + - ((const unsigned char *) name)[0]+ - ((const unsigned char *) name)[len-1]; -} - -/* * Hash queue manipulation. Look out for the casts.. + * + * What casts? 8-) -DaveM */ static inline void remove_hash(struct dir_cache_entry * de) { - struct dir_cache_entry * next = de->h.next; - - if (next) { - struct dir_cache_entry * prev = de->h.prev; - next->h.prev = prev; - prev->h.next = next; - de->h.next = NULL; + if(de->pprev) { + if(de->next) + de->next->pprev = de->pprev; + *de->pprev = de->next; + de->pprev = NULL; } } -static inline void add_hash(struct dir_cache_entry * de, struct hash_list * hash) +static inline void add_hash(struct dir_cache_entry * de, struct dir_cache_entry ** hash) { - struct dir_cache_entry * next = hash->next; - de->h.next = next; - de->h.prev = (struct dir_cache_entry *) hash; - next->h.prev = de; - hash->next = de; + if((de->next = *hash) != NULL) + (*hash)->pprev = &de->next; + *hash = de; + de->pprev = hash; } /* * Find a directory cache entry given all the necessary info. */ -static inline struct dir_cache_entry * find_entry(struct inode * dir, const char * name, int len, struct hash_list * hash) +static inline struct dir_cache_entry * find_entry(struct inode * dir, const char * name, int len, struct dir_cache_entry ** hash) { - struct dir_cache_entry * nextde = hash->next; - - for (;;) { - struct dir_cache_entry * de; + struct dir_cache_entry *de; - if (nextde == (struct dir_cache_entry *) hash) + for(de = *hash; de; de = de->next) + if((de->name_len == (unsigned char) len) && + (de->dc_dev == dir->i_dev) && + (de->dir == dir->i_ino) && + (de->version == dir->i_version) && + (!memcmp(de->name, name, len))) break; - de = nextde; - nextde = nextde->h.next; - if (de->name_len != (unsigned char) len) - continue; - if (de->dc_dev != dir->i_dev) - continue; - if (de->dir != dir->i_ino) - continue; - if (de->version != dir->i_version) - continue; - if (memcmp(de->name, name, len)) - continue; - return de; - } - return NULL; + return de; } /* * Move a successfully used entry to level2. If already at level2, * move it to the end of the LRU queue.. */ -static inline void move_to_level2(struct dir_cache_entry * old_de, struct hash_list * hash) +static inline void move_to_level2(struct dir_cache_entry * old_de, struct dir_cache_entry ** hash) { struct dir_cache_entry * de; @@ -194,43 +188,49 @@ static inline void move_to_level2(struct dir_cache_entry * old_de, struct hash_l int dcache_lookup(struct inode * dir, const char * name, int len, unsigned long * ino) { - struct hash_list * hash; - struct dir_cache_entry *de; - - if (len > DCACHE_NAME_LEN) - return 0; - hash = hash_table + hash_fn(dir->i_dev, dir->i_ino, namehash(name,len)); - de = find_entry(dir, name, len, hash); - if (!de) - return 0; - *ino = de->ino; - move_to_level2(de, hash); - return 1; + int ret = 0; + + if(len <= DCACHE_NAME_LEN) { + struct dir_cache_entry **hash = get_hlist(dir, name, len); + struct dir_cache_entry *de; + + spin_lock(&dcache_lock); + de = find_entry(dir, name, len, hash); + if(de) { + *ino = de->ino; + move_to_level2(de, hash); + ret = 1; + } + spin_unlock(&dcache_lock); + } + return ret; } void dcache_add(struct inode * dir, const char * name, int len, unsigned long ino) { - struct hash_list * hash; - struct dir_cache_entry *de; - - if (len > DCACHE_NAME_LEN) - return; - hash = hash_table + hash_fn(dir->i_dev, dir->i_ino, namehash(name,len)); - if ((de = find_entry(dir, name, len, hash)) != NULL) { - de->ino = ino; - update_lru(de); - return; + if (len <= DCACHE_NAME_LEN) { + struct dir_cache_entry **hash = get_hlist(dir, name, len); + struct dir_cache_entry *de; + + spin_lock(&dcache_lock); + de = find_entry(dir, name, len, hash); + if (de) { + de->ino = ino; + update_lru(de); + } else { + de = level1_head; + level1_head = de->next_lru; + remove_hash(de); + de->dc_dev = dir->i_dev; + de->dir = dir->i_ino; + de->version = dir->i_version; + de->ino = ino; + de->name_len = len; + memcpy(de->name, name, len); + add_hash(de, hash); + } + spin_unlock(&dcache_lock); } - de = level1_head; - level1_head = de->next_lru; - remove_hash(de); - de->dc_dev = dir->i_dev; - de->dir = dir->i_ino; - de->version = dir->i_version; - de->ino = ino; - de->name_len = len; - memcpy(de->name, name, len); - add_hash(de, hash); } unsigned long name_cache_init(unsigned long mem_start, unsigned long mem_end) @@ -270,7 +270,7 @@ unsigned long name_cache_init(unsigned long mem_start, unsigned long mem_end) * Empty hash queues.. */ for (i = 0 ; i < DCACHE_HASH_QUEUES ; i++) - hash_table[i].next = hash_table[i].next = - (struct dir_cache_entry *) &hash_table[i]; + hash_table[i] = NULL; + return mem_start; } diff --git a/fs/filesystems.c b/fs/filesystems.c index abefb471f..7d5b51ef1 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -27,6 +27,9 @@ #include #include #include +#ifdef CONFIG_KERNELD +#include +#endif extern void device_setup(void); extern void binfmt_setup(void); @@ -42,7 +45,7 @@ asmlinkage int sys_setup(void) if (!callable) goto out; callable = 0; - + device_setup(); binfmt_setup(); @@ -129,3 +132,32 @@ out: return err; } +#ifndef CONFIG_NFSD +#ifdef CONFIG_NFSD_MODULE +int (*do_nfsservctl)(int, void *, void *) = NULL; +#endif +int +asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp) +{ +#ifndef CONFIG_NFSD_MODULE + return -ENOSYS; +#else + int ret = -ENOSYS; + + lock_kernel(); + if (do_nfsservctl) { + ret = do_nfsservctl(cmd, argp, resp); + goto out; + } +#ifdef CONFIG_KERNELD + if (request_module ("nfsd") == 0) { + if (do_nfsservctl) + ret = do_nfsservctl(cmd, argp, resp); + } +#endif /* CONFIG_KERNELD */ +out: + unlock_kernel(); + return ret; +#endif /* CONFIG_NFSD_MODULE */ +} +#endif /* CONFIG_NFSD */ diff --git a/fs/inode.c b/fs/inode.c dissimilarity index 78% index 6390bb6c9..b1d9bda4e 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1,655 +1,657 @@ -/* - * linux/fs/inode.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include -#include -#include -#include -#include - -#include - -#define NR_IHASH 512 - -/* - * Be VERY careful when you access the inode hash table. There - * are some rather scary race conditions you need to take care of: - * - P1 tries to open file "xx", calls "iget()" with the proper - * inode number, but blocks because it's not on the list. - * - P2 deletes file "xx", gets the inode (which P1 has just read, - * but P1 hasn't woken up to the fact yet) - * - P2 iput()'s the inode, which now has i_nlink = 0 - * - P1 wakes up and has the inode, but now P2 has made that - * inode invalid (but P1 has no way of knowing that). - * - * The "updating" counter makes sure that when P1 blocks on the - * iget(), P2 can't delete the inode from under it because P2 - * will wait until P1 has been able to update the inode usage - * count so that the inode will stay in use until everybody has - * closed it.. - */ -static struct inode_hash_entry { - struct inode * inode; - int updating; -} hash_table[NR_IHASH]; - -static struct inode * first_inode; -static struct wait_queue * inode_wait = NULL; -/* Keep these next two contiguous in memory for sysctl.c */ -int nr_inodes = 0, nr_free_inodes = 0; -int max_inodes = NR_INODE; - -static inline int const hashfn(kdev_t dev, unsigned int i) -{ - return (HASHDEV(dev) ^ i) % NR_IHASH; -} - -static inline struct inode_hash_entry * const hash(kdev_t dev, int i) -{ - return hash_table + hashfn(dev, i); -} - -static inline void insert_inode_free(struct inode *inode) -{ - struct inode * prev, * next = first_inode; - - first_inode = inode; - prev = next->i_prev; - inode->i_next = next; - inode->i_prev = prev; - prev->i_next = inode; - next->i_prev = inode; -} - -static inline void remove_inode_free(struct inode *inode) -{ - if (first_inode == inode) - first_inode = first_inode->i_next; - if (inode->i_next) - inode->i_next->i_prev = inode->i_prev; - if (inode->i_prev) - inode->i_prev->i_next = inode->i_next; - inode->i_next = inode->i_prev = NULL; -} - -void insert_inode_hash(struct inode *inode) -{ - struct inode_hash_entry *h; - h = hash(inode->i_dev, inode->i_ino); - - inode->i_hash_next = h->inode; - inode->i_hash_prev = NULL; - if (inode->i_hash_next) - inode->i_hash_next->i_hash_prev = inode; - h->inode = inode; -} - -static inline void remove_inode_hash(struct inode *inode) -{ - struct inode_hash_entry *h; - h = hash(inode->i_dev, inode->i_ino); - - if (h->inode == inode) - h->inode = inode->i_hash_next; - if (inode->i_hash_next) - inode->i_hash_next->i_hash_prev = inode->i_hash_prev; - if (inode->i_hash_prev) - inode->i_hash_prev->i_hash_next = inode->i_hash_next; - inode->i_hash_prev = inode->i_hash_next = NULL; -} - -static inline void put_last_free(struct inode *inode) -{ - remove_inode_free(inode); - inode->i_prev = first_inode->i_prev; - inode->i_prev->i_next = inode; - inode->i_next = first_inode; - inode->i_next->i_prev = inode; -} - -int grow_inodes(void) -{ - struct inode * inode; - int i; - - if (!(inode = (struct inode*) get_free_page(GFP_KERNEL))) - return -ENOMEM; - - i=PAGE_SIZE / sizeof(struct inode); - nr_inodes += i; - nr_free_inodes += i; - - if (!first_inode) - inode->i_next = inode->i_prev = first_inode = inode++, i--; - - for ( ; i ; i-- ) - insert_inode_free(inode++); - return 0; -} - -unsigned long inode_init(unsigned long start, unsigned long end) -{ - memset(hash_table, 0, sizeof(hash_table)); - first_inode = NULL; - return start; -} - -static void __wait_on_inode(struct inode *); - -static inline void wait_on_inode(struct inode * inode) -{ - if (inode->i_lock) - __wait_on_inode(inode); -} - -static inline void lock_inode(struct inode * inode) -{ - wait_on_inode(inode); - inode->i_lock = 1; -} - -static inline void unlock_inode(struct inode * inode) -{ - inode->i_lock = 0; - wake_up(&inode->i_wait); -} - -/* - * Note that we don't want to disturb any wait-queues when we discard - * an inode. - * - * Argghh. Got bitten by a gcc problem with inlining: no way to tell - * the compiler that the inline asm function 'memset' changes 'inode'. - * I've been searching for the bug for days, and was getting desperate. - * Finally looked at the assembler output... Grrr. - * - * The solution is the weird use of 'volatile'. Ho humm. Have to report - * it to the gcc lists, and hope we can do this more cleanly some day.. - */ -void clear_inode(struct inode * inode) -{ - struct wait_queue * wait; - - inode->i_count++; - truncate_inode_pages(inode, 0); - wait_on_inode(inode); - if (IS_WRITABLE(inode)) { - if (inode->i_sb && inode->i_sb->dq_op) - inode->i_sb->dq_op->drop(inode); - } - remove_inode_hash(inode); - remove_inode_free(inode); - wait = ((volatile struct inode *) inode)->i_wait; - inode->i_count--; - if (inode->i_count) - nr_free_inodes++; - memset(inode,0,sizeof(*inode)); - ((volatile struct inode *) inode)->i_wait = wait; - insert_inode_free(inode); -} - -int fs_may_mount(kdev_t dev) -{ - struct inode * inode, * next; - int i; - - next = first_inode; - for (i = nr_inodes ; i > 0 ; i--) { - inode = next; - next = inode->i_next; /* clear_inode() changes the queues.. */ - if (inode->i_dev != dev) - continue; - if (inode->i_count || inode->i_dirt || inode->i_lock) - return 0; - clear_inode(inode); - } - return 1; -} - -int fs_may_umount(kdev_t dev, struct inode * mount_root) -{ - struct inode * inode; - int i; - - inode = first_inode; - for (i=0 ; i < nr_inodes ; i++, inode = inode->i_next) { - if (inode->i_dev != dev || !inode->i_count) - continue; - if (inode == mount_root && inode->i_count == - (inode->i_mount != inode ? 1 : 2)) - continue; - return 0; - } - return 1; -} - -int fs_may_remount_ro(kdev_t dev) -{ - struct file * file; - int i; - - /* Check that no files are currently opened for writing. */ - for (file = first_file, i=0; if_next) { - if (!file->f_count || !file->f_inode || - file->f_inode->i_dev != dev) - continue; - if (S_ISREG(file->f_inode->i_mode) && (file->f_mode & 2)) - return 0; - } - return 1; -} - -static void write_inode(struct inode * inode) -{ - if (!inode->i_dirt) - return; - wait_on_inode(inode); - if (!inode->i_dirt) - return; - if (!inode->i_sb || !inode->i_sb->s_op || !inode->i_sb->s_op->write_inode) { - inode->i_dirt = 0; - return; - } - inode->i_lock = 1; - inode->i_sb->s_op->write_inode(inode); - unlock_inode(inode); -} - -static inline void read_inode(struct inode * inode) -{ - lock_inode(inode); - if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->read_inode) - inode->i_sb->s_op->read_inode(inode); - unlock_inode(inode); -} - -/* POSIX UID/GID verification for setting inode attributes */ -int inode_change_ok(struct inode *inode, struct iattr *attr) -{ - /* - * If force is set do it anyway. - */ - - if (attr->ia_valid & ATTR_FORCE) - return 0; - - /* Make sure a caller can chown */ - if ((attr->ia_valid & ATTR_UID) && - (current->fsuid != inode->i_uid || - attr->ia_uid != inode->i_uid) && !fsuser()) - return -EPERM; - - /* Make sure caller can chgrp */ - if ((attr->ia_valid & ATTR_GID) && - (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) && - !fsuser()) - return -EPERM; - - /* Make sure a caller can chmod */ - if (attr->ia_valid & ATTR_MODE) { - if ((current->fsuid != inode->i_uid) && !fsuser()) - return -EPERM; - /* Also check the setgid bit! */ - if (!fsuser() && !in_group_p((attr->ia_valid & ATTR_GID) ? attr->ia_gid : - inode->i_gid)) - attr->ia_mode &= ~S_ISGID; - } - - /* Check for setting the inode time */ - if ((attr->ia_valid & ATTR_ATIME_SET) && - ((current->fsuid != inode->i_uid) && !fsuser())) - return -EPERM; - if ((attr->ia_valid & ATTR_MTIME_SET) && - ((current->fsuid != inode->i_uid) && !fsuser())) - return -EPERM; - return 0; -} - -/* - * Set the appropriate attributes from an attribute structure into - * the inode structure. - */ -void inode_setattr(struct inode *inode, struct iattr *attr) -{ - if (attr->ia_valid & ATTR_UID) - inode->i_uid = attr->ia_uid; - if (attr->ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; - if (attr->ia_valid & ATTR_SIZE) - inode->i_size = attr->ia_size; - if (attr->ia_valid & ATTR_ATIME) - inode->i_atime = attr->ia_atime; - if (attr->ia_valid & ATTR_MTIME) - inode->i_mtime = attr->ia_mtime; - if (attr->ia_valid & ATTR_CTIME) - inode->i_ctime = attr->ia_ctime; - if (attr->ia_valid & ATTR_MODE) { - inode->i_mode = attr->ia_mode; - if (!fsuser() && !in_group_p(inode->i_gid)) - inode->i_mode &= ~S_ISGID; - } - inode->i_dirt = 1; -} - -/* - * notify_change is called for inode-changing operations such as - * chown, chmod, utime, and truncate. It is guaranteed (unlike - * write_inode) to be called from the context of the user requesting - * the change. - */ - -int notify_change(struct inode * inode, struct iattr *attr) -{ - int retval; - - attr->ia_ctime = CURRENT_TIME; - if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME)) { - if (!(attr->ia_valid & ATTR_ATIME_SET)) - attr->ia_atime = attr->ia_ctime; - if (!(attr->ia_valid & ATTR_MTIME_SET)) - attr->ia_mtime = attr->ia_ctime; - } - - if (inode->i_sb && inode->i_sb->s_op && - inode->i_sb->s_op->notify_change) - return inode->i_sb->s_op->notify_change(inode, attr); - - if ((retval = inode_change_ok(inode, attr)) != 0) - return retval; - - inode_setattr(inode, attr); - return 0; -} - -/* - * bmap is needed for demand-loading and paging: if this function - * doesn't exist for a filesystem, then those things are impossible: - * executables cannot be run from the filesystem etc... - * - * This isn't as bad as it sounds: the read-routines might still work, - * so the filesystem would be otherwise ok (for example, you might have - * a DOS filesystem, which doesn't lend itself to bmap very well, but - * you could still transfer files to/from the filesystem) - */ -int bmap(struct inode * inode, int block) -{ - if (inode->i_op && inode->i_op->bmap) - return inode->i_op->bmap(inode,block); - return 0; -} - -void invalidate_inodes(kdev_t dev) -{ - struct inode * inode, * next; - int i; - - next = first_inode; - for(i = nr_inodes ; i > 0 ; i--) { - inode = next; - next = inode->i_next; /* clear_inode() changes the queues.. */ - if (inode->i_dev != dev) - continue; - if (inode->i_count || inode->i_dirt || inode->i_lock) { - printk("VFS: inode busy on removed device %s\n", - kdevname(dev)); - continue; - } - clear_inode(inode); - } -} - -void sync_inodes(kdev_t dev) -{ - int i; - struct inode * inode; - - inode = first_inode; - for(i = 0; i < nr_inodes*2; i++, inode = inode->i_next) { - if (dev && inode->i_dev != dev) - continue; - wait_on_inode(inode); - if (inode->i_dirt) - write_inode(inode); - } -} - -void iput(struct inode * inode) -{ - if (!inode) - return; - wait_on_inode(inode); - if (!inode->i_count) { - printk("VFS: iput: trying to free free inode\n"); - printk("VFS: device %s, inode %lu, mode=0%07o\n", - kdevname(inode->i_rdev), inode->i_ino, inode->i_mode); - return; - } - if (inode->i_pipe) - wake_up_interruptible(&PIPE_WAIT(*inode)); -repeat: - if (inode->i_count>1) { - inode->i_count--; - return; - } - - wake_up(&inode_wait); - if (inode->i_pipe) { - unsigned long page = (unsigned long) PIPE_BASE(*inode); - PIPE_BASE(*inode) = NULL; - free_page(page); - } - - if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) { - inode->i_sb->s_op->put_inode(inode); - if (!inode->i_nlink) - return; - } - - if (inode->i_dirt) { - write_inode(inode); /* we can sleep - so do again */ - wait_on_inode(inode); - goto repeat; - } - - if (IS_WRITABLE(inode)) { - if (inode->i_sb && inode->i_sb->dq_op) { - /* Here we can sleep also. Let's do it again - * Dmitry Gorodchanin 02/11/96 - */ - inode->i_lock = 1; - inode->i_sb->dq_op->drop(inode); - unlock_inode(inode); - goto repeat; - } - } - - inode->i_count--; - - if (inode->i_mmap) { - printk("iput: inode %lu on device %s still has mappings.\n", - inode->i_ino, kdevname(inode->i_dev)); - inode->i_mmap = NULL; - } - - nr_free_inodes++; - return; -} - -struct inode * get_empty_inode(void) -{ - static int ino = 0; - struct inode * inode, * best; - unsigned long badness; - int i; - - if (nr_inodes < max_inodes && nr_free_inodes < (nr_inodes >> 1)) - grow_inodes(); -repeat: - inode = first_inode; - best = NULL; - badness = 1000; - for (i = nr_inodes/2; i > 0; i--,inode = inode->i_next) { - if (!inode->i_count) { - unsigned long i = 999; - if (!(inode->i_lock | inode->i_dirt)) - i = inode->i_nrpages; - if (i < badness) { - best = inode; - if (!i) - goto found_good; - badness = i; - } - } - } - if (nr_inodes < max_inodes) { - if (grow_inodes() == 0) - goto repeat; - best = NULL; - } - if (!best) { - printk("VFS: No free inodes - contact Linus\n"); - sleep_on(&inode_wait); - goto repeat; - } - if (best->i_lock) { - wait_on_inode(best); - goto repeat; - } - if (best->i_dirt) { - write_inode(best); - goto repeat; - } - if (best->i_count) - goto repeat; -found_good: - clear_inode(best); - best->i_count = 1; - best->i_nlink = 1; - best->i_version = ++event; - sema_init(&best->i_sem, 1); - best->i_ino = ++ino; - best->i_dev = 0; - nr_free_inodes--; - if (nr_free_inodes < 0) { - printk ("VFS: get_empty_inode: bad free inode count.\n"); - nr_free_inodes = 0; - } - return best; -} - -struct inode * get_pipe_inode(void) -{ - struct inode * inode; - extern struct inode_operations pipe_inode_operations; - - if (!(inode = get_empty_inode())) - return NULL; - if (!(PIPE_BASE(*inode) = (char*) __get_free_page(GFP_USER))) { - iput(inode); - return NULL; - } - inode->i_op = &pipe_inode_operations; - inode->i_count = 2; /* sum of readers/writers */ - PIPE_WAIT(*inode) = NULL; - PIPE_START(*inode) = PIPE_LEN(*inode) = 0; - PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; - PIPE_LOCK(*inode) = 0; - inode->i_pipe = 1; - inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_blksize = PAGE_SIZE; - return inode; -} - -struct inode *__iget(struct super_block * sb, int nr, int crossmntp) -{ - static struct wait_queue * update_wait = NULL; - struct inode_hash_entry * h; - struct inode * inode; - struct inode * empty = NULL; - - if (!sb) - panic("VFS: iget with sb==NULL"); - h = hash(sb->s_dev, nr); -repeat: - for (inode = h->inode; inode ; inode = inode->i_hash_next) - if (inode->i_dev == sb->s_dev && inode->i_ino == nr) - goto found_it; - if (!empty) { - /* - * If we sleep here before we have found an inode - * we need to make sure nobody does anything bad - * to the inode while we sleep, because otherwise - * we may return an inode that is not valid any - * more when we wake up.. - */ - h->updating++; - empty = get_empty_inode(); - if (!--h->updating) - wake_up(&update_wait); - if (empty) - goto repeat; - return (NULL); - } - inode = empty; - inode->i_sb = sb; - inode->i_dev = sb->s_dev; - inode->i_ino = nr; - inode->i_flags = sb->s_flags; - put_last_free(inode); - insert_inode_hash(inode); - read_inode(inode); - goto return_it; - -found_it: - if (!inode->i_count) - nr_free_inodes--; - inode->i_count++; - wait_on_inode(inode); - if (inode->i_dev != sb->s_dev || inode->i_ino != nr) { - printk("Whee.. inode changed from under us. Tell Linus\n"); - iput(inode); - goto repeat; - } - if (crossmntp && inode->i_mount) { - struct inode * tmp = inode->i_mount; - tmp->i_count++; - iput(inode); - inode = tmp; - wait_on_inode(inode); - } - if (empty) - iput(empty); - -return_it: - while (h->updating) - sleep_on(&update_wait); - return inode; -} - -/* - * The "new" scheduling primitives (new as of 0.97 or so) allow this to - * be done without disabling interrupts (other than in the actual queue - * updating things: only a couple of 386 instructions). This should be - * much better for interrupt latency. - */ -static void __wait_on_inode(struct inode * inode) -{ - struct wait_queue wait = { current, NULL }; - - add_wait_queue(&inode->i_wait, &wait); -repeat: - current->state = TASK_UNINTERRUPTIBLE; - if (inode->i_lock) { - schedule(); - goto repeat; - } - remove_wait_queue(&inode->i_wait, &wait); - current->state = TASK_RUNNING; -} +/* + * linux/fs/inode.c: Keeping track of inodes. + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 1997 David S. Miller + */ + +#include +#include +#include +#include +#include + +int nr_inodes = 0, nr_free_inodes = 0; +int max_inodes = NR_INODE; + +#define INODE_HASHSZ 1024 + +static struct inode *inode_hash[INODE_HASHSZ]; + +/* All the details of hashing and lookup. */ +#define hashfn(dev, i) ((HASHDEV(dev) + ((i) ^ ((i) >> 10))) & (INODE_HASHSZ - 1)) + +__inline__ void insert_inode_hash(struct inode *inode) +{ + struct inode **htable = &inode_hash[hashfn(inode->i_dev, inode->i_ino)]; + if((inode->i_hash_next = *htable) != NULL) + (*htable)->i_hash_pprev = &inode->i_hash_next; + *htable = inode; + inode->i_hash_pprev = htable; +} + +#define hash_inode(inode) insert_inode_hash(inode) + +static inline void unhash_inode(struct inode *inode) +{ + if(inode->i_hash_pprev) { + if(inode->i_hash_next) + inode->i_hash_next->i_hash_pprev = inode->i_hash_pprev; + *(inode->i_hash_pprev) = inode->i_hash_next; + inode->i_hash_pprev = NULL; + } +} + +static inline struct inode *find_inode(unsigned int hashent, + kdev_t dev, unsigned long ino) +{ + struct inode *inode; + + for(inode = inode_hash[hashent]; inode; inode = inode->i_hash_next) + if(inode->i_dev == dev && inode->i_ino == ino) + break; + return inode; +} + +/* Free list queue and management. */ +static struct free_inode_queue { + struct inode *head; + struct inode **last; +} free_inodes = { NULL, &free_inodes.head }; + +static inline void put_inode_head(struct inode *inode) +{ + if((inode->i_next = free_inodes.head) != NULL) + free_inodes.head->i_pprev = &inode->i_next; + else + free_inodes.last = &inode->i_next; + free_inodes.head = inode; + inode->i_pprev = &free_inodes.head; + nr_free_inodes++; +} + +static inline void put_inode_last(struct inode *inode) +{ + inode->i_next = NULL; + inode->i_pprev = free_inodes.last; + *free_inodes.last = inode; + free_inodes.last = &inode->i_next; + nr_free_inodes++; +} + +static inline void remove_free_inode(struct inode *inode) +{ + if(inode->i_pprev) { + if(inode->i_next) + inode->i_next->i_pprev = inode->i_pprev; + else + free_inodes.last = inode->i_pprev; + *inode->i_pprev = inode->i_next; + inode->i_pprev = NULL; + nr_free_inodes--; + } +} + +/* This is the in-use queue, if i_count > 0 (as far as we can tell) + * the sucker is here. + */ +static struct inode *inuse_list = NULL; + +static inline void put_inuse(struct inode *inode) +{ + if((inode->i_next = inuse_list) != NULL) + inuse_list->i_pprev = &inode->i_next; + inuse_list = inode; + inode->i_pprev = &inuse_list; +} + +static inline void remove_inuse(struct inode *inode) +{ + if(inode->i_pprev) { + if(inode->i_next) + inode->i_next->i_pprev = inode->i_pprev; + *inode->i_pprev = inode->i_next; + inode->i_pprev = NULL; + } +} + +/* Locking and unlocking inodes, plus waiting for locks to clear. */ +static void __wait_on_inode(struct inode *); + +static inline void wait_on_inode(struct inode *inode) +{ + if(inode->i_lock) + __wait_on_inode(inode); +} + +static inline void lock_inode(struct inode *inode) +{ + if(inode->i_lock) + __wait_on_inode(inode); + inode->i_lock = 1; +} + +static inline void unlock_inode(struct inode *inode) +{ + inode->i_lock = 0; + wake_up(&inode->i_wait); +} + +static void __wait_on_inode(struct inode * inode) +{ + struct wait_queue wait = { current, NULL }; + + add_wait_queue(&inode->i_wait, &wait); +repeat: + current->state = TASK_UNINTERRUPTIBLE; + if (inode->i_lock) { + schedule(); + goto repeat; + } + remove_wait_queue(&inode->i_wait, &wait); + current->state = TASK_RUNNING; +} + +/* Clear an inode of all it's identity, this is exported to the world. */ +void clear_inode(struct inode *inode) +{ + struct wait_queue *wait; + + /* So we don't disappear. */ + inode->i_count++; + + truncate_inode_pages(inode, 0); + wait_on_inode(inode); + if(IS_WRITABLE(inode) && inode->i_sb && inode->i_sb->dq_op) + inode->i_sb->dq_op->drop(inode); + + if(--inode->i_count > 0) + remove_inuse(inode); + else + remove_free_inode(inode); + unhash_inode(inode); + wait = inode->i_wait; + memset(inode, 0, sizeof(*inode)); barrier(); + inode->i_wait = wait; + put_inode_head(inode); /* Pages zapped, put at the front. */ +} + +/* These check the validity of a mount/umount type operation, we essentially + * check if there are any inodes hanging around which prevent this operation + * from occurring. We also clear out clean inodes referencing this device. + */ +int fs_may_mount(kdev_t dev) +{ + struct inode *inode; + int pass = 0; + + inode = free_inodes.head; +repeat: + while(inode) { + struct inode *next = inode->i_next; + if(inode->i_dev != dev) + goto next; + if(inode->i_count || inode->i_dirt || inode->i_lock) + return 0; + clear_inode(inode); + next: + inode = next; + } + if(pass == 0) { + inode = inuse_list; + pass = 1; + goto repeat; + } + return 1; /* Tis' cool bro. */ +} + +int fs_may_umount(kdev_t dev, struct inode *iroot) +{ + struct inode *inode; + int pass = 0; + + inode = free_inodes.head; +repeat: + for(; inode; inode = inode->i_next) { + if(inode->i_dev != dev || !inode->i_count) + continue; + if(inode == iroot && + (inode->i_count == (inode->i_mount == inode ? 2 : 1))) + continue; + return 0; + } + if(pass == 0) { + inode = inuse_list; + pass = 1; + goto repeat; + } + return 1; /* Tis' cool bro. */ +} + +/* This belongs in file_table.c, not here... */ +int fs_may_remount_ro(kdev_t dev) +{ + struct file * file; + int i; + + /* Check that no files are currently opened for writing. */ + for (file = first_file, i=0; if_next) { + if (!file->f_count || !file->f_inode || + file->f_inode->i_dev != dev) + continue; + if (S_ISREG(file->f_inode->i_mode) && (file->f_mode & 2)) + return 0; + } + return 1; /* Tis' cool bro. */ +} + +/* Reading/writing inodes. */ +static void write_inode(struct inode *inode) +{ + if(inode->i_dirt) { + wait_on_inode(inode); + if(inode->i_dirt) { + if(inode->i_sb && + inode->i_sb->s_op && + inode->i_sb->s_op->write_inode) { + inode->i_lock = 1; + inode->i_sb->s_op->write_inode(inode); + unlock_inode(inode); + } else { + inode->i_dirt = 0; + } + } + } +} + +static inline void read_inode(struct inode *inode) +{ + if(inode->i_sb && + inode->i_sb->s_op && + inode->i_sb->s_op->read_inode) { + lock_inode(inode); + inode->i_sb->s_op->read_inode(inode); + unlock_inode(inode); + } +} + +int inode_change_ok(struct inode *inode, struct iattr *attr) +{ + if(!(attr->ia_valid & ATTR_FORCE)) { + unsigned short fsuid = current->fsuid; + uid_t iuid = inode->i_uid; + int not_fsuser = !fsuser(); + + if(((attr->ia_valid & ATTR_UID) && + ((fsuid != iuid) || + (attr->ia_uid != iuid)) && not_fsuser) || + + ((attr->ia_valid & ATTR_GID) && + (!in_group_p(attr->ia_gid) && + (attr->ia_gid != inode->i_gid))) || + + ((attr->ia_valid & (ATTR_ATIME_SET | ATTR_MTIME_SET)) && + (fsuid != iuid) && not_fsuser)) + return -EPERM; + + if(attr->ia_valid & ATTR_MODE) { + gid_t grp; + if(fsuid != iuid && not_fsuser) + return -EPERM; + grp = attr->ia_valid & ATTR_GID ? attr->ia_gid : inode->i_gid; + if(not_fsuser && !in_group_p(grp)) + attr->ia_mode &= ~S_ISGID; + } + } + return 0; +} + +void inode_setattr(struct inode *inode, struct iattr *attr) +{ + if (attr->ia_valid & ATTR_UID) + inode->i_uid = attr->ia_uid; + if (attr->ia_valid & ATTR_GID) + inode->i_gid = attr->ia_gid; + if (attr->ia_valid & ATTR_SIZE) + inode->i_size = attr->ia_size; + if (attr->ia_valid & ATTR_ATIME) + inode->i_atime = attr->ia_atime; + if (attr->ia_valid & ATTR_MTIME) + inode->i_mtime = attr->ia_mtime; + if (attr->ia_valid & ATTR_CTIME) + inode->i_ctime = attr->ia_ctime; + if (attr->ia_valid & ATTR_MODE) { + inode->i_mode = attr->ia_mode; + if (!fsuser() && !in_group_p(inode->i_gid)) + inode->i_mode &= ~S_ISGID; + } + inode->i_dirt = 1; +} + +int notify_change(struct inode *inode, struct iattr *attr) +{ + attr->ia_ctime = CURRENT_TIME; + if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME)) { + if (!(attr->ia_valid & ATTR_ATIME_SET)) + attr->ia_atime = attr->ia_ctime; + if (!(attr->ia_valid & ATTR_MTIME_SET)) + attr->ia_mtime = attr->ia_ctime; + } + + if (inode->i_sb && + inode->i_sb->s_op && + inode->i_sb->s_op->notify_change) + return inode->i_sb->s_op->notify_change(inode, attr); + + if(inode_change_ok(inode, attr) != 0) + return -EPERM; + + inode_setattr(inode, attr); + return 0; +} + +int bmap(struct inode *inode, int block) +{ + if(inode->i_op && inode->i_op->bmap) + return inode->i_op->bmap(inode, block); + return 0; +} + +void invalidate_inodes(kdev_t dev) +{ + struct inode *inode; + int pass = 0; + + inode = free_inodes.head; +repeat: + while(inode) { + struct inode *next = inode->i_next; + if(inode->i_dev != dev) + goto next; + clear_inode(inode); + next: + inode = next; + } + if(pass == 0) { + inode = inuse_list; + pass = 1; + goto repeat; + } +} + +void sync_inodes(kdev_t dev) +{ + struct inode *inode; + int pass = 0; + + inode = free_inodes.head; +repeat: + while(inode) { + struct inode *next = inode->i_next; + if(dev && inode->i_dev != dev) + goto next; + wait_on_inode(inode); + write_inode(inode); + next: + inode = next; + } + if(pass == 0) { + inode = inuse_list; + pass = 1; + goto repeat; + } +} + +static struct wait_queue *inode_wait, *update_wait; + +void iput(struct inode *inode) +{ + if(!inode) + return; + wait_on_inode(inode); + if(!inode->i_count) { + printk("VFS: Freeing free inode, tell DaveM\n"); + return; + } + if(inode->i_pipe) + wake_up_interruptible(&PIPE_WAIT(*inode)); +we_slept: + if(inode->i_count > 1) { + inode->i_count--; + } else { + wake_up(&inode_wait); + if(inode->i_pipe) { + free_page((unsigned long)PIPE_BASE(*inode)); + PIPE_BASE(*inode) = NULL; + } + if(inode->i_sb && + inode->i_sb->s_op && + inode->i_sb->s_op->put_inode) { + inode->i_sb->s_op->put_inode(inode); + if(!inode->i_nlink) + return; + } + if(inode->i_dirt) { + write_inode(inode); + wait_on_inode(inode); + goto we_slept; + } + if(IS_WRITABLE(inode) && + inode->i_sb && + inode->i_sb->dq_op) { + inode->i_lock = 1; + inode->i_sb->dq_op->drop(inode); + unlock_inode(inode); + goto we_slept; + } + /* There is a serious race leading to here, watch out. */ + if(--inode->i_count == 0) { + remove_inuse(inode); + put_inode_last(inode); /* Place at end of LRU free queue */ + } + } +} + +static kmem_cache_t *inode_cachep; + +static void grow_inodes(void) +{ + int i = 16; + + while(i--) { + struct inode *inode; + + inode = kmem_cache_alloc(inode_cachep, SLAB_KERNEL); + if(!inode) + return; + memset(inode, 0, sizeof(*inode)); + put_inode_head(inode); + nr_inodes++; + } +} + +/* We have to be really careful, it's really easy to run yourself into + * inefficient sequences of events. The first problem is that when you + * steal a non-referenced inode you run the risk of zaping a considerable + * number of page cache entries, which might get refernced once again. + * But if you are growing the inode set to quickly, you suck up ram + * and cause other problems. + * + * We approach the problem in the following way, we take two things into + * consideration. Firstly we take a look at how much we have "committed" + * to this inode already (i_nrpages), this accounts for the cost of getting + * those pages back if someone should reference that inode soon. We also + * attempt to factor in i_blocks, which says "how much of a problem could + * this potentially be". It still needs some tuning though. -DaveM + */ +#define BLOCK_FACTOR_SHIFT 5 /* It is not factored in as much. */ +static struct inode *find_best_candidate_weighted(struct inode *inode) +{ + struct inode *best = NULL; + + if(inode) { + unsigned long bestscore = 1000; + int limit = nr_free_inodes >> 2; + do { + if(!(inode->i_lock | inode->i_dirt)) { + int myscore = inode->i_nrpages; + + myscore += (inode->i_blocks >> BLOCK_FACTOR_SHIFT); + if(myscore < bestscore) { + bestscore = myscore; + best = inode; + } + } + inode = inode->i_next; + } while(inode && --limit); + } + return best; +} + +static inline struct inode *find_best_free(struct inode *inode) +{ + if(inode) { + int limit = nr_free_inodes >> 5; + do { + if(!inode->i_nrpages) + return inode; + inode = inode->i_next; + } while(inode && --limit); + } + return NULL; +} + +struct inode *get_empty_inode(void) +{ + static int ino = 0; + struct inode *inode; + +repeat: + inode = find_best_free(free_inodes.head); + if(!inode) + goto pressure; +got_it: + inode->i_count++; + truncate_inode_pages(inode, 0); + wait_on_inode(inode); + if(IS_WRITABLE(inode) && inode->i_sb && inode->i_sb->dq_op) + inode->i_sb->dq_op->drop(inode); + unhash_inode(inode); + remove_free_inode(inode); + + memset(inode, 0, sizeof(*inode)); + inode->i_count = 1; + inode->i_nlink = 1; + inode->i_version = ++event; + sema_init(&inode->i_sem, 1); + inode->i_ino = ++ino; + inode->i_dev = 0; + put_inuse(inode); + return inode; +pressure: + if(nr_inodes < max_inodes) { + grow_inodes(); + goto repeat; + } + inode = find_best_candidate_weighted(free_inodes.head); + if(!inode) { + printk("VFS: No free inodes, contact DaveM\n"); + sleep_on(&inode_wait); + goto repeat; + } + if(inode->i_lock) { + wait_on_inode(inode); + goto repeat; + } else if(inode->i_dirt) { + write_inode(inode); + goto repeat; + } + goto got_it; +} + +struct inode *get_pipe_inode(void) +{ + extern struct inode_operations pipe_inode_operations; + struct inode *inode = get_empty_inode(); + + if(inode) { + unsigned long page = __get_free_page(GFP_USER); + if(!page) { + iput(inode); + inode = NULL; + } else { + PIPE_BASE(*inode) = (char *) page; + inode->i_op = &pipe_inode_operations; + inode->i_count = 2; + PIPE_WAIT(*inode) = NULL; + PIPE_START(*inode) = PIPE_LEN(*inode) = 0; + PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; + PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; + PIPE_LOCK(*inode) = 0; + inode->i_pipe = 1; + inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_blksize = PAGE_SIZE; + } + } + return inode; +} + +static int inode_updating[INODE_HASHSZ]; + +struct inode *__iget(struct super_block *sb, int nr, int crossmntp) +{ + unsigned int hashent = hashfn(sb->s_dev, nr); + struct inode *inode, *empty = NULL; + +we_slept: + if((inode = find_inode(hashent, sb->s_dev, nr)) == NULL) { + if(empty == NULL) { + inode_updating[hashent]++; + empty = get_empty_inode(); + if(!--inode_updating[hashent]) + wake_up(&update_wait); + goto we_slept; + } + inode = empty; + inode->i_sb = sb; + inode->i_dev = sb->s_dev; + inode->i_ino = nr; + inode->i_flags = sb->s_flags; + hash_inode(inode); + read_inode(inode); + } else { + if(!inode->i_count++) { + remove_free_inode(inode); + put_inuse(inode); + } + wait_on_inode(inode); + if(crossmntp && inode->i_mount) { + struct inode *mp = inode->i_mount; + mp->i_count++; + iput(inode); + wait_on_inode(inode = mp); + } + if(empty) + iput(empty); + } + while(inode_updating[hashent]) + sleep_on(&update_wait); + return inode; +} + +void inode_init(void) +{ + int i; + + inode_cachep = kmem_cache_create("inode", sizeof(struct inode), + sizeof(unsigned long) * 4, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if(!inode_cachep) + panic("Cannot create inode SLAB cache\n"); + + for(i = 0; i < INODE_HASHSZ; i++) + inode_hash[i] = NULL; +} diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 4f35de9b5..c466321ed 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -35,6 +35,8 @@ # define copy_to_user memcpy_tofs # define access_ok !verify_area #endif +#include +#include extern long sys_call_table[]; @@ -126,20 +128,30 @@ nfsctl_getfh(struct nfsctl_fhparm *data, struct knfs_fh *res) return err; } +#ifdef CONFIG_NFSD +#define handle_sys_nfsservctl sys_nfsservctl +#endif + int -asmlinkage sys_nfsservctl(int cmd, struct nfsctl_arg *argp, union nfsctl_res *resp) +asmlinkage handle_sys_nfsservctl(int cmd, struct nfsctl_arg *argp, + union nfsctl_res *resp) { struct nfsctl_arg * arg = NULL; union nfsctl_res * res = NULL; int err; + lock_kernel (); if (!initialized) nfsd_init(); - if (!suser()) - return -EPERM; + if (!suser()) { + err = -EPERM; + goto done; + } if (!access_ok(VERIFY_READ, argp, sizeof(*argp)) - || (resp && !access_ok(VERIFY_WRITE, resp, sizeof(*resp)))) - return -EFAULT; + || (resp && !access_ok(VERIFY_WRITE, resp, sizeof(*resp)))) { + err = -EFAULT; + goto done; + } if (!(arg = kmalloc(sizeof(*arg), GFP_USER)) || (resp && !(res = kmalloc(sizeof(*res), GFP_USER)))) { err = -ENOMEM; /* ??? */ @@ -191,6 +203,7 @@ done: if (res) kfree(res); + unlock_kernel (); return err; } @@ -203,6 +216,8 @@ MODULE_AUTHOR("Olaf Kirch "); static unsigned long old_syscallvec; +extern int (*do_nfsservctl)(int, void *, void *); + /* * Initialize the module */ @@ -210,10 +225,8 @@ int init_module(void) { printk("Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); - - old_syscallvec = sys_call_table[__NR_nfsservctl]; - sys_call_table[__NR_nfsservctl] = (unsigned long) sys_nfsservctl; nfsd_init(); + do_nfsservctl = handle_sys_nfsservctl; return 0; } @@ -227,7 +240,7 @@ cleanup_module(void) printk("nfsd: nfsd busy, remove delayed\n"); return; } - sys_call_table[__NR_nfsservctl] = old_syscallvec; + do_nfsservctl = NULL; nfsd_export_shutdown(); nfsd_cache_shutdown(); #ifdef CONFIG_PROC_FS diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index a2cac539e..84d296834 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -116,7 +116,7 @@ nfsd(struct svc_rqst *rqstp) /* * The main request loop */ - do { + for (;;) { /* * Find a socket with data available and call its * recvfrom routine. @@ -150,7 +150,7 @@ nfsd(struct svc_rqst *rqstp) /* Unlock export hash tables */ exp_unlock(); - } while (err >= 0); + } if (err != -EINTR) { printk(KERN_WARNING "nfsd: terminating on error %d\n", -err); diff --git a/include/asm-alpha/init.h b/include/asm-alpha/init.h index 8eb924c18..7d769dfcd 100644 --- a/include/asm-alpha/init.h +++ b/include/asm-alpha/init.h @@ -1,14 +1,15 @@ #ifndef _ALPHA_INIT_H #define _ALPHA_INIT_H -/* Throwing the initialization code and data out is not supported yet... */ +#define __init __attribute__ ((__section__ (".text.init"))) +#define __initdata __attribute__ ((__section__ (".data.init"))) +#define __initfunc(__arginit) \ + __arginit __init; \ + __arginit -#define __init -#define __initdata -#define __initfunc(__arginit) __arginit /* For assembly routines */ -#define __INIT -#define __FINIT -#define __INITDATA +#define __INIT .section .text.init,"ax" +#define __FINIT .previous +#define __INITDATA .section .data.init,"a" #endif diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h index 0e664bb53..90829f270 100644 --- a/include/asm-alpha/processor.h +++ b/include/asm-alpha/processor.h @@ -42,6 +42,7 @@ struct thread_struct { /* the fields below are Linux-specific: */ /* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h) */ + /* bit 6..8: UAC bits (see sysinfo.h) */ unsigned long flags; /* perform syscall argument validation (get/set_fs) */ unsigned long fs; diff --git a/include/asm-alpha/softirq.h b/include/asm-alpha/softirq.h index 50d937152..fa8124c38 100644 --- a/include/asm-alpha/softirq.h +++ b/include/asm-alpha/softirq.h @@ -31,6 +31,12 @@ extern inline void init_bh(int nr, void (*routine)(void)) bh_mask |= 1 << nr; } +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + extern inline void mark_bh(int nr) { set_bit(nr, &bh_active); diff --git a/include/asm-alpha/spinlock.h b/include/asm-alpha/spinlock.h index aef56398e..9e58e0e4d 100644 --- a/include/asm-alpha/spinlock.h +++ b/include/asm-alpha/spinlock.h @@ -6,36 +6,43 @@ typedef struct { } spinlock_t; #define SPIN_LOCK_UNLOCKED { } -/* - * Basic spinlocks - one can enter at a time - */ - +#define spin_lock_init(lock) do { } while(0) #define spin_lock(lock) do { } while(0) #define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) #define spin_unlock(lock) do { } while(0) #define spin_lock_irq(lock) setipl(7) #define spin_unlock_irq(lock) setipl(0) + #define spin_lock_irqsave(lock, flags) swpipl(flags,7) #define spin_unlock_irqrestore(lock, flags) setipl(flags) /* - * Read-write locks: we can have multiple readers, but - * only one writer + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. */ - -#define read_lock(lock) do { } while(0) -#define read_unlock(lock) do { } while(0) -#define read_lock_irq(lock) setipl(7) -#define read_unlock_irq(lock) setipl(0) -#define read_lock_irqsave(lock, flags) swpipl(flags,7) -#define read_unlock_irqrestore(lock, flags) setipl(flags) - -#define write_lock(lock) do { } while(0) -#define write_unlock(lock) do { } while(0) -#define write_lock_irq(lock) setipl(7) -#define write_unlock_irq(lock) setipl(0) -#define write_lock_irqsave(lock, flags) swpipl(flags,7) -#define write_unlock_irqrestore(lock, flags) setipl(flags) +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) #else @@ -53,6 +60,7 @@ typedef struct { #define SPIN_LOCK_UNLOCKED { 0, 0 } #define spin_lock_init(lock) do { (lock)->lock = 0; (lock)->previous = 0; } while(0) +#define spin_unlock_wait(lock) do { barrier(); } while(((volatile spinlock_t *)lock)->lock) typedef struct { unsigned long a[100]; } __dummy_lock_t; #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) diff --git a/include/asm-alpha/sysinfo.h b/include/asm-alpha/sysinfo.h new file mode 100644 index 000000000..d43ce2af2 --- /dev/null +++ b/include/asm-alpha/sysinfo.h @@ -0,0 +1,36 @@ +/* + * include/asm-alpha/sysinfo.h + */ + +#ifndef __ASM_ALPHA_SYSINFO_H +#define __ASM_ALPHA_SYSINFO_H + +/* This defines the subset of the OSF/1 getsysinfo/setsysinfo calls + that we support. */ + +#define GSI_UACPROC 8 +#define GSI_IEEE_FP_CONTROL 45 +#define GSI_IEEE_STATE_AT_SIGNAL 46 + +#define SSI_NVPAIRS 1 +#define SSI_IEEE_FP_CONTROL 14 +#define SSI_IEEE_STATE_AT_SIGNAL 15 +#define SSI_IEEE_IGNORE_STATE_AT_SIGNAL 16 + +#define SSIN_UACPROC 6 + +#define UAC_BITMASK 7 +#define UAC_NOPRINT 1 +#define UAC_NOFIX 2 +#define UAC_SIGBUS 4 + + +#ifdef __KERNEL__ + +/* This is the shift that is applied to the UAC bits as stored in the + per-thread flags. */ +#define UAC_SHIFT 6 + +#endif + +#endif /* __ASM_ALPHA_SYSINFO_H */ diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 20e991e39..7d973530c 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -205,6 +205,7 @@ static inline void flush_tlb_range(struct mm_struct *mm, #define _PAGE_ACCESSED 0x020 #define _PAGE_DIRTY 0x040 #define _PAGE_4M 0x080 /* 4 MB page, Pentium+.. */ +#define _PAGE_GLOBAL 0x100 /* Global TLB entry PPro+ */ #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) @@ -374,6 +375,8 @@ extern inline void pte_free_kernel(pte_t * pte) free_page((unsigned long) pte); } +extern const char bad_pmd_string[]; + extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); @@ -390,7 +393,7 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) free_page((unsigned long) page); } if (pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + printk(bad_pmd_string, pmd_val(*pmd)); pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); return NULL; } @@ -443,7 +446,7 @@ freenew: } fix: - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + printk(bad_pmd_string, pmd_val(*pmd)); oom: pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE); return NULL; diff --git a/include/asm-i386/softirq.h b/include/asm-i386/softirq.h index 396f744a6..07a678435 100644 --- a/include/asm-i386/softirq.h +++ b/include/asm-i386/softirq.h @@ -14,6 +14,12 @@ extern inline void init_bh(int nr, void (*routine)(void)) bh_mask |= 1 << nr; } +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + extern inline void mark_bh(int nr) { set_bit(nr, &bh_active); diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index 03b18cb9c..27630b21d 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -12,6 +12,7 @@ typedef struct { } spinlock_t; #define spin_lock_init(lock) do { } while(0) #define spin_lock(lock) do { } while(0) #define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) #define spin_unlock(lock) do { } while(0) #define spin_lock_irq(lock) cli() #define spin_unlock_irq(lock) sti() @@ -69,6 +70,7 @@ typedef struct { #define SPIN_LOCK_UNLOCKED { 0, 0 } #define spin_lock_init(x) do { (x)->lock = 0; (x)->previous = 0; } while(0) +#define spin_unlock_wait(x) do { barrier(); } while(((volatile spinlock_t *)(x))->lock) typedef struct { unsigned long a[100]; } __dummy_lock_t; #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) diff --git a/include/asm-m68k/dsp56k.h b/include/asm-m68k/dsp56k.h new file mode 100644 index 000000000..e035055bc --- /dev/null +++ b/include/asm-m68k/dsp56k.h @@ -0,0 +1,70 @@ +/* + * linux/include/asm-m68k/dsp56k.h - defines and declarations for + * DSP56k device driver + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +/* Used for uploading DSP binary code */ +struct dsp56k_upload { + int len; + char *bin; +}; + +/* For the DSP host flags */ +struct dsp56k_host_flags { + int dir; /* Bit field. 1 = write output bit, 0 = do nothing. + * 0x0000 means reading only, 0x0011 means + * writing the bits stored in `out' on HF0 and HF1. + * Note that HF2 and HF3 can only be read. + */ + int out; /* Bit field like above. */ + int status; /* Host register's current state is returned */ +}; + +/* ioctl command codes */ +#define DSP56K_UPLOAD 1 /* Upload DSP binary program */ +#define DSP56K_SET_TX_WSIZE 2 /* Host transmit word size (1-4) */ +#define DSP56K_SET_RX_WSIZE 3 /* Host receive word size (1-4) */ +#define DSP56K_HOST_FLAGS 4 /* Host flag registers */ +#define DSP56K_HOST_CMD 5 /* Trig Host Command (0-31) */ +/* + * linux/include/asm-m68k/dsp56k.h - defines and declarations for + * DSP56k device driver + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +/* Used for uploading DSP binary code */ +struct dsp56k_upload { + int len; + char *bin; +}; + +/* For the DSP host flags */ +struct dsp56k_host_flags { + int dir; /* Bit field. 1 = write output bit, 0 = do nothing. + * 0x0000 means reading only, 0x0011 means + * writing the bits stored in `out' on HF0 and HF1. + * Note that HF2 and HF3 can only be read. + */ + int out; /* Bit field like above. */ + int status; /* Host register's current state is returned */ +}; + +/* ioctl command codes */ +#define DSP56K_UPLOAD 1 /* Upload DSP binary program */ +#define DSP56K_SET_TX_WSIZE 2 /* Host transmit word size (1-4) */ +#define DSP56K_SET_RX_WSIZE 3 /* Host receive word size (1-4) */ +#define DSP56K_HOST_FLAGS 4 /* Host flag registers */ +#define DSP56K_HOST_CMD 5 /* Trig Host Command (0-31) */ diff --git a/include/asm-m68k/fpu.h b/include/asm-m68k/fpu.h new file mode 100644 index 000000000..fc47dac02 --- /dev/null +++ b/include/asm-m68k/fpu.h @@ -0,0 +1,40 @@ +#ifndef __M68K_FPU_H +#define __M68K_FPU_H + +#include + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ + +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) +#define FPSTATESIZE (216/sizeof(unsigned char)) +#elif defined(CONFIG_M68040) +#define FPSTATESIZE (96/sizeof(unsigned char)) +#elif defined(CONFIG_M68060) +#define FPSTATESIZE (12/sizeof(unsigned char)) +#else +#define FPSTATESIZE error no_cpu_type_configured +#endif + +#endif /* __M68K_FPU_H */ +#ifndef __M68K_FPU_H +#define __M68K_FPU_H + +#include + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ + +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) +#define FPSTATESIZE (216/sizeof(unsigned char)) +#elif defined(CONFIG_M68040) +#define FPSTATESIZE (96/sizeof(unsigned char)) +#elif defined(CONFIG_M68060) +#define FPSTATESIZE (12/sizeof(unsigned char)) +#else +#define FPSTATESIZE error no_cpu_type_configured +#endif + +#endif /* __M68K_FPU_H */ diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h new file mode 100644 index 000000000..e9d0136c3 --- /dev/null +++ b/include/asm-m68k/hardirq.h @@ -0,0 +1,26 @@ +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +extern unsigned int local_irq_count[NR_CPUS]; +#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) + +#define hardirq_trylock(cpu) ((cpu)==0) /* always true */ +#define hardirq_endlock(cpu) do { } while (0) + +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) + +#endif +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +extern unsigned int local_irq_count[NR_CPUS]; +#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) + +#define hardirq_trylock(cpu) ((cpu)==0) /* always true */ +#define hardirq_endlock(cpu) do { } while (0) + +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) + +#endif diff --git a/include/asm-m68k/namei.h b/include/asm-m68k/namei.h new file mode 100644 index 000000000..516066f1a --- /dev/null +++ b/include/asm-m68k/namei.h @@ -0,0 +1,42 @@ +/* + * linux/include/asm-m68k/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __M68K_NAMEI_H +#define __M68K_NAMEI_H + +/* These dummy routines maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define translate_namei(pathname, base, follow_links, res_inode) \ + do { } while (0) + +#define translate_open_namei(pathname, flag, mode, res_inode, base) \ + do { } while (0) + +#endif +/* + * linux/include/asm-m68k/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __M68K_NAMEI_H +#define __M68K_NAMEI_H + +/* These dummy routines maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define translate_namei(pathname, base, follow_links, res_inode) \ + do { } while (0) + +#define translate_open_namei(pathname, flag, mode, res_inode, base) \ + do { } while (0) + +#endif diff --git a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h new file mode 100644 index 000000000..9b52915d0 --- /dev/null +++ b/include/asm-m68k/poll.h @@ -0,0 +1,42 @@ +#ifndef __m68k_POLL_H +#define __m68k_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif +#ifndef __m68k_POLL_H +#define __m68k_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff --git a/include/asm-m68k/smp_lock.h b/include/asm-m68k/smp_lock.h new file mode 100644 index 000000000..158de0988 --- /dev/null +++ b/include/asm-m68k/smp_lock.h @@ -0,0 +1,28 @@ +#ifndef __M68K_SMPLOCK_H +#define __M68K_SMPLOCK_H + +/* + * We don't do SMP so this is again one of these silly dummy files + * to keep the kernel source looking nice ;-(. + */ + +#define lock_kernel() do { } while(0) +#define unlock_kernel() do { } while(0) +#define release_kernel_lock(task, cpu, depth) ((depth) = 1) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) + +#endif +#ifndef __M68K_SMPLOCK_H +#define __M68K_SMPLOCK_H + +/* + * We don't do SMP so this is again one of these silly dummy files + * to keep the kernel source looking nice ;-(. + */ + +#define lock_kernel() do { } while(0) +#define unlock_kernel() do { } while(0) +#define release_kernel_lock(task, cpu, depth) ((depth) = 1) +#define reaquire_kernel_lock(task, cpu, depth) do { } while(0) + +#endif diff --git a/include/asm-m68k/softirq.h b/include/asm-m68k/softirq.h new file mode 100644 index 000000000..32f12c0d5 --- /dev/null +++ b/include/asm-m68k/softirq.h @@ -0,0 +1,118 @@ +#ifndef __M68K_SOFTIRQ_H +#define __M68K_SOFTIRQ_H + +/* + * Software interrupts.. no SMP here either. + */ +#define get_active_bhs() (bh_mask & bh_active) +#define clear_active_bhs(x) atomic_clear_mask((x),&bh_active) + +extern inline void init_bh(int nr, void (*routine)(void)) +{ + bh_base[nr] = routine; + bh_mask_count[nr] = 0; + bh_mask |= 1 << nr; +} + +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + +extern inline void mark_bh(int nr) +{ + set_bit(nr, &bh_active); +} + +/* + * These use a mask count to correctly handle + * nested disable/enable calls + */ +extern inline void disable_bh(int nr) +{ + bh_mask &= ~(1 << nr); + bh_mask_count[nr]++; +} + +extern inline void enable_bh(int nr) +{ + if (!--bh_mask_count[nr]) + bh_mask |= 1 << nr; +} + +extern int __m68k_bh_counter; + +extern inline void start_bh_atomic(void) +{ + __m68k_bh_counter++; + barrier(); +} + +extern inline void end_bh_atomic(void) +{ + barrier(); + __m68k_bh_counter--; +} + +/* These are for the irq's testing the lock */ +#define softirq_trylock() (__m68k_bh_counter ? 0 : (__m68k_bh_counter=1)) +#define softirq_endlock() (__m68k_bh_counter = 0) + +#endif +#ifndef __M68K_SOFTIRQ_H +#define __M68K_SOFTIRQ_H + +/* + * Software interrupts.. no SMP here either. + */ +#define get_active_bhs() (bh_mask & bh_active) +#define clear_active_bhs(x) atomic_clear_mask((x),&bh_active) + +extern inline void init_bh(int nr, void (*routine)(void)) +{ + bh_base[nr] = routine; + bh_mask_count[nr] = 0; + bh_mask |= 1 << nr; +} + +extern inline void mark_bh(int nr) +{ + set_bit(nr, &bh_active); +} + +/* + * These use a mask count to correctly handle + * nested disable/enable calls + */ +extern inline void disable_bh(int nr) +{ + bh_mask &= ~(1 << nr); + bh_mask_count[nr]++; +} + +extern inline void enable_bh(int nr) +{ + if (!--bh_mask_count[nr]) + bh_mask |= 1 << nr; +} + +extern int __m68k_bh_counter; + +extern inline void start_bh_atomic(void) +{ + __m68k_bh_counter++; + barrier(); +} + +extern inline void end_bh_atomic(void) +{ + barrier(); + __m68k_bh_counter--; +} + +/* These are for the irq's testing the lock */ +#define softirq_trylock() (__m68k_bh_counter ? 0 : (__m68k_bh_counter=1)) +#define softirq_endlock() (__m68k_bh_counter = 0) + +#endif diff --git a/include/asm-m68k/spinlock.h b/include/asm-m68k/spinlock.h new file mode 100644 index 000000000..cbae3d62d --- /dev/null +++ b/include/asm-m68k/spinlock.h @@ -0,0 +1,74 @@ +#ifndef __M68K_SPINLOCK_H +#define __M68K_SPINLOCK_H + +/* + * We don't do SMP on the m68k .... at least not yet. + */ + +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() + +#define spin_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define spin_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) + +#endif +#ifndef __M68K_SPINLOCK_H +#define __M68K_SPINLOCK_H + +/* + * We don't do SMP on the m68k .... at least not yet. + */ + +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() + +#define spin_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define spin_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + +#endif diff --git a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h deleted file mode 100644 index f3742cf88..000000000 --- a/include/asm-m68k/zorro.h +++ /dev/null @@ -1,577 +0,0 @@ -/* - * asm-m68k/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions - * - * Copyright (C) 1995 Geert Uytterhoeven - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#ifndef _M68K_ZORRO_H -#define _M68K_ZORRO_H - -#ifndef __ASSEMBLY__ - -/* - * Defined Board Manufacturers - * - * Please update arch/m68k/amiga/zorro.c if you make changes here - * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) - * and by looking at the NetBSD-Amiga kernel sources - */ - -#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ -#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ -#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ - -#define MANUF_KUPKE (0x00DD) /* Kupke */ -#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ - -#define MANUF_MEMPHIS (0x0100) /* Memphis */ -#define PROD_STORMBRINGER (0x00) /* Stormbringer */ - -#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ -#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ -#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ -#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ -#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ - -#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ -#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ -#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ -#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ -#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ -#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ -#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ -#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ -#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ -#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ -#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ -#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ -#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ -#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ -#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ -#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ -#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ -#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ - -#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ -#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ - -#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ -#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ - -#define MANUF_CARDCO (0x03EC) /* Cardco */ -#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ -#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ -#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ -#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ - -#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ -#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ - -#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ -#define PROD_AX2000 (0x01) /* AX2000 */ - -#define MANUF_ANAKIN (0x03F1) /* Anakin */ -#define PROD_EASYL (0x01) /* Easyl Tablet */ - -#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ -#define PROD_STARBOARD_II (0x00) /* StarBoard II */ -#define PROD_STARDRIVE (0x02) /* StarDrive */ -#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ -#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ -#define PROD_VXL_RAM (0x44) /* VXL RAM */ -#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ -#define PROD_MBX_1200 (0x81) /* MBX 1200 */ -#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ -#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ - -#define MANUF_ACCESS (0x03F4) /* Access Associates */ - -#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ - -#define MANUF_ASDG (0x03FF) /* ASDG */ -#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ -#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ -#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ -#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ - -#define MANUF_IMTRONICS (0x0404) /* Imtronics */ -#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ -#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ - -#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ -#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ - -#define MANUF_AMERISTAR (0x041D) /* Ameristar */ -#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ -#define PROD_A560 (0x09) /* Arcnet Card */ -#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ - -#define MANUF_SUPRA (0x0420) /* Supra */ -#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ -#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ -#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ -#define PROD_SUPRA_500RX (0x09) /* 500RX/2000 RAM */ -#define PROD_SUPRA_500RX_2 (0x0A) /* 500RX/2000 RAM */ -#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ -#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ -#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ -#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ - -#define MANUF_CSA (0x0422) /* CSA */ -#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ -#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ - -#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ -#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ - -#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ -#define PROD_BYTEBOX_A500 (0x00) /* A500 */ - -#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ - -#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ -#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ -#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ - -#define MANUF_GVP (0x07E1) /* Great Valley Products */ -#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ -#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ -#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ -#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ -#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ -#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ -#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works - for this product code also */ -#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ -#define PROD_GVP (0x0B) /* This code is used by a wide range of - GVP products - use the epc to - identify it correctly */ -#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ -#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ -#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ -#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ -#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ -/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ - -#define MANUF_SYNERGY (0x07E5) /* Synergy */ - -#define MANUF_XETEC (0x07E6) /* Xetec */ -#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ -#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ - -#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ -#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ -#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ -#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ -#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ -#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ - -#define MANUF_XEBEC (0x07EC) /* Xebec */ - -#define MANUF_SPIRIT (0x07F2) /* Spirit */ -#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ -#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ - -#define MANUF_BSC (0x07FE) /* BSC */ -#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ - -#define MANUF_BSC3 (0x0801) /* BSC */ -#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ -#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ - -#define MANUF_C_LTD (0x0802) /* C Ltd. */ -#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ -#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ - -#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ -#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ - -#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ -#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ - -#define MANUF_ICD (0x0817) /* ICD */ -#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ - -#define MANUF_KUPKE2 (0x0819) /* Kupke */ -#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ -#define PROD_GOLEM_BOX (0x03) /* Golem Box */ -#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ - -#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ -#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ - -#define MANUF_BSC2 (0x082C) /* BSC */ -#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ -#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ -#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ -#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ -#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ -#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ -#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ -#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ - -#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ -#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ -#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ - -#define MANUF_IMPULSE (0x0838) /* Impulse */ -#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ - -#define MANUF_IVS (0x0840) /* IVS */ -#define PROD_GRANDSLAM (0x04) /* GrandSlam RAM */ -#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ -#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ -#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ -#define PROD_META_4 (0x40) /* Meta-4 RAM */ -#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ - -#define MANUF_VECTOR (0x0841) /* Vector */ -#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ - -#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ -#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ -#define PROD_VISIONA_REG (0x02) -#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ -#define PROD_MERLIN_REG (0x04) - -#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ -#define PROD_AMIGANET (0x01) /* Amiganet Board */ - -#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ -#define PROD_AD516 (0x02) /* AD516 Audio */ - -#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ -#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ - -#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ -#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ -#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ - -#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ -#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ -#define PROD_GDA_1_REG (0x01) - -#define MANUF_ROCTEC (0x0860) /* RocTec */ -#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ -#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ - -#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ -#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ - -#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ -#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ - -#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ -#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ -#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ -#define PROD_MVD_819 (0x07) /* MVD 819 */ - -#define MANUF_DELACOMP (0x0873) /* DelaComp */ -#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ - -#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ -#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board (RAM) */ -#define PROD_DOMINO_REG (0x02) /* Domino Graphics Board (REG) */ -#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II Graphics Board */ -#define PROD_PICASSO_II_REG (0x0C) -#define PROD_PICASSO_II_REG_2 (0x0D) -#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ - -#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ -#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ -#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ - -#define MANUF_AMITRIX (0x0880) /* Amitrix */ -#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ -#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ - -#define MANUF_MTEC (0x0890) /* MTEC Germany */ -#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ -#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ -#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ - -#define MANUF_GVP2 (0x0891) /* Great Valley Products */ -#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ -#define PROD_SPECTRUM_REG (0x02) - -#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ -#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ -#define PROD_PICCOLO_REG (0x06) -#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ -#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ -#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ -#define PROD_SD64_REG (0x0B) - -#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ -#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ - -#define MANUF_ELBOX (0x089E) /* ElBox Computer */ -#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ - -#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ -#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ -#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ - -#define MANUF_MICRONIK (0x0A50) /* Micronik */ -#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ - -#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ -#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ -#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ - -#define MANUF_KUPKE3 (0x1248) /* Kupke */ -#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ - -#define MANUF_INFORMATION (0x157C) /* Information */ -#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ - -#define MANUF_VORTEX (0x2017) /* Vortex */ -#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ -#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ -#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ - -#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ -#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ -#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ - -#define MANUF_READYSOFT (0x2100) /* ReadySoft */ -#define PROD_AMAX (0x01) /* AMax II/IV */ - -#define MANUF_PHASE5 (0x2140) /* Phase5 */ -#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ -#define PROD_BLIZZARD (0x02) /* Blizzard */ -#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ -#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ -#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ -#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ -#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ -#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ -#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ -#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ -#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ - -#define MANUF_DPS (0x2169) /* DPS */ -#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ - -#define MANUF_APOLLO2 (0x2200) /* Apollo */ -#define PROD_A620 (0x00) /* A620 68020 Accelerator */ - -#define MANUF_APOLLO (0x2222) /* Apollo */ -#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ -#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ - -#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ -#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ - -#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ -#define PROD_MAESTRO (0x03) /* Maestro */ -#define PROD_VLAB (0x04) /* VLab */ -#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ -#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ -#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ -#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ -#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ -#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ -#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ - -#define MANUF_COMBITEC (0x6766) /* Combitec */ - -#define MANUF_SKI (0x8000) /* SKI Peripherals */ -#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ - -#define MANUF_CAMERON (0xAA01) /* Cameron */ -#define PROD_CAMERON_SCANNER (0x10) /* Scanner Interface */ - -#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ -#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ - - -/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ - -#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ -#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ - -#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ -#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ - -#define MANUF_VECTOR2 (0x07DB) /* Vector */ -#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ -#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ -#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ -#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ - - -/* - * GVP's identifies most of their product through the 'extended - * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK - * before the identification. - */ - -#define GVP_PRODMASK (0xf8) -#define GVP_SCSICLKMASK (0x01) - -enum GVP_ident { - GVP_GFORCE_040 = 0x20, - GVP_GFORCE_040_SCSI = 0x30, - GVP_A1291_SCSI = 0x40, - GVP_COMBO_R4 = 0x60, - GVP_COMBO_R4_SCSI = 0x70, - GVP_PHONEPAK = 0x78, - GVP_IOEXT = 0x98, - GVP_GFORCE_030 = 0xa0, - GVP_GFORCE_030_SCSI = 0xb0, - GVP_A530 = 0xc0, - GVP_A530_SCSI = 0xd0, - GVP_COMBO_R3 = 0xe0, - GVP_COMBO_R3_SCSI = 0xf0, - GVP_SERIESII = 0xf8, -}; - -enum GVP_flags { - GVP_IO = 0x01, - GVP_ACCEL = 0x02, - GVP_SCSI = 0x04, - GVP_24BITDMA = 0x08, - GVP_25BITDMA = 0x10, - GVP_NOBANK = 0x20, - GVP_14MHZ = 0x40, -}; - - -struct Node { - struct Node *ln_Succ; /* Pointer to next (successor) */ - struct Node *ln_Pred; /* Pointer to previous (predecessor) */ - u_char ln_Type; - char ln_Pri; /* Priority, for sorting */ - char *ln_Name; /* ID string, null terminated */ -}; - -struct ExpansionRom { - /* -First 16 bytes of the expansion ROM */ - u_char er_Type; /* Board type, size and flags */ - u_char er_Product; /* Product number, assigned by manufacturer */ - u_char er_Flags; /* Flags */ - u_char er_Reserved03; /* Must be zero ($ff inverted) */ - u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ - u_long er_SerialNumber; /* Available for use by manufacturer */ - u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ - u_char er_Reserved0c; - u_char er_Reserved0d; - u_char er_Reserved0e; - u_char er_Reserved0f; -}; - -/* er_Type board type bits */ -#define ERT_TYPEMASK 0xc0 -#define ERT_ZORROII 0xc0 -#define ERT_ZORROIII 0x80 - -/* other bits defined in er_Type */ -#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ -#define ERTF_MEMLIST (1<<5) - -struct ConfigDev { - struct Node cd_Node; - u_char cd_Flags; /* (read/write) */ - u_char cd_Pad; /* reserved */ - struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ - void *cd_BoardAddr; /* where in memory the board was placed */ - u_long cd_BoardSize; /* size of board in bytes */ - u_short cd_SlotAddr; /* which slot number (PRIVATE) */ - u_short cd_SlotSize; /* number of slots (PRIVATE) */ - void *cd_Driver; /* pointer to node of driver */ - struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ - u_long cd_Unused[4]; /* for whatever the driver wants */ -}; - -#else /* __ASSEMBLY__ */ - -LN_Succ = 0 -LN_Pred = LN_Succ+4 -LN_Type = LN_Pred+4 -LN_Pri = LN_Type+1 -LN_Name = LN_Pri+1 -LN_sizeof = LN_Name+4 - -ER_Type = 0 -ER_Product = ER_Type+1 -ER_Flags = ER_Product+1 -ER_Reserved03 = ER_Flags+1 -ER_Manufacturer = ER_Reserved03+1 -ER_SerialNumber = ER_Manufacturer+2 -ER_InitDiagVec = ER_SerialNumber+4 -ER_Reserved0c = ER_InitDiagVec+2 -ER_Reserved0d = ER_Reserved0c+1 -ER_Reserved0e = ER_Reserved0d+1 -ER_Reserved0f = ER_Reserved0e+1 -ER_sizeof = ER_Reserved0f+1 - -CD_Node = 0 -CD_Flags = CD_Node+LN_sizeof -CD_Pad = CD_Flags+1 -CD_Rom = CD_Pad+1 -CD_BoardAddr = CD_Rom+ER_sizeof -CD_BoardSize = CD_BoardAddr+4 -CD_SlotAddr = CD_BoardSize+4 -CD_SlotSize = CD_SlotAddr+2 -CD_Driver = CD_SlotSize+2 -CD_NextCD = CD_Driver+4 -CD_Unused = CD_NextCD+4 -CD_sizeof = CD_Unused+(4*4) - -#endif /* __ASSEMBLY__ */ - -#ifndef __ASSEMBLY__ - -#define ZORRO_NUM_AUTO 16 - -#ifdef __KERNEL__ - -extern int zorro_num_autocon; /* # of autoconfig devices found */ -extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; - - -/* - * Zorro Functions - */ - -extern int zorro_find(int manuf, int prod, int part, int index); -extern struct ConfigDev *zorro_get_board(int key); -extern void zorro_config_board(int key, int part); -extern void zorro_unconfig_board(int key, int part); - - -/* - * Bitmask indicating portions of available Zorro II RAM that are unused - * by the system. Every bit represents a 64K chunk, for a maximum of 8MB - * (128 chunks, physical 0x00200000-0x009fffff). - * - * If you want to use (= allocate) portions of this RAM, you should clear - * the corresponding bits. - */ - -extern u_long zorro_unused_z2ram[4]; - -#define Z2RAM_START (0x00200000) -#define Z2RAM_END (0x00a00000) -#define Z2RAM_SIZE (0x00800000) -#define Z2RAM_CHUNKSIZE (0x00010000) -#define Z2RAM_CHUNKMASK (0x0000ffff) -#define Z2RAM_CHUNKSHIFT (16) - - -/* - * Verbose Board Identification - */ - -extern void zorro_identify(void); -extern int zorro_get_list(char *buffer); - -#endif /* !__ASSEMBLY__ */ -#endif /* __KERNEL__ */ - -#endif /* __ASMm68K_ZORRO_H */ diff --git a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h index 2be22d14e..2d3f70bc6 100644 --- a/include/asm-sparc/hardirq.h +++ b/include/asm-sparc/hardirq.h @@ -10,12 +10,11 @@ extern unsigned int local_irq_count[NR_CPUS]; #define in_interrupt() (local_irq_count[smp_processor_id()] != 0) -#define hardirq_depth() (local_irq_count[smp_processor_id()]) #ifndef __SMP__ -#define hardirq_trylock(cpu) (++local_irq_count[cpu], (cpu)==0) -#define hardirq_endlock(cpu) (--local_irq_count[cpu]) +#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) +#define hardirq_endlock(cpu) do { } while(0) #define hardirq_enter(cpu) (local_irq_count[cpu]++) #define hardirq_exit(cpu) (local_irq_count[cpu]--) diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h index 87da95126..16c2ca5a1 100644 --- a/include/asm-sparc/irq.h +++ b/include/asm-sparc/irq.h @@ -1,4 +1,4 @@ -/* $Id: irq.h,v 1.16 1997/04/15 09:03:40 davem Exp $ +/* $Id: irq.h,v 1.17 1997/04/18 05:44:52 davem Exp $ * irq.h: IRQ registers on the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -13,6 +13,38 @@ #define NR_IRQS 15 +/* IRQ handler dispatch entry and exit. */ +#ifdef __SMP__ +extern __inline__ void irq_enter(int cpu, int irq) +{ + register int proc asm("g1"); + proc = cpu; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___irq_enter + add %%o7, 8, %%o7 +" : "=&r" (proc) + : "0" (proc) + : "g2", "g3", "g4", "g5", "memory", "cc"); +} + +extern __inline__ void irq_exit(int cpu, int irq) +{ + register int proc asm("g7"); + proc = cpu; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___irq_exit + add %%o7, 8, %%o7 +" : "=&r" (proc) + : "0" (proc) + : "g1", "g2", "g3", "g4", "g5", "memory", "cc"); +} +#else +#define irq_enter(cpu, irq) (local_irq_count[cpu]++) +#define irq_exit(cpu, irq) (local_irq_count[cpu]--) +#endif + /* Dave Redman (djhr@tadpole.co.uk) * changed these to function pointers.. it saves cycles and will allow * the irq dependencies to be split into different files at a later date diff --git a/include/asm-sparc/linux_logo.h b/include/asm-sparc/linux_logo.h new file mode 100644 index 000000000..4c323b49e --- /dev/null +++ b/include/asm-sparc/linux_logo.h @@ -0,0 +1,2090 @@ +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:24 jj Exp $ + * include/asm-sparc/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/SPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 221 + +unsigned char linux_logo_red[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5, + 0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5, + 0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03, + 0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6, + 0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2, + 0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A, + 0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4, + 0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2, + 0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC, + 0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC, + 0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7, + 0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3, + 0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4, + 0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4, + 0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87, + 0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E, + 0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_green[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3, + 0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9, + 0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02, + 0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD, + 0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6, + 0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C, + 0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4, + 0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E, + 0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC, + 0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5, + 0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96, + 0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80, + 0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F, + 0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C, + 0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54, + 0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E, + 0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_blue[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE, + 0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5, + 0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84, + 0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7, + 0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77, + 0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59, + 0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E, + 0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14, + 0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D, + 0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14, + 0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08, + 0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E, + 0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E, + 0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20, + 0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06, + 0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17, + 0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14, + 0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo[] __initdata = { + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61, + 0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E, + 0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58, + 0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C, + 0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A, + 0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52, + 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53, + 0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, + 0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49, + 0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B, + 0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, + 0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB, + 0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C, + 0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49, + 0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5, + 0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58, + 0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51, + 0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54, + 0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5, + 0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61, + 0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C, + 0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B, + 0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53, + 0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC, + 0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59, + 0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48, + 0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51, + 0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63, + 0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48, + 0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51, + 0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52, + 0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB, + 0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B, + 0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53, + 0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53, + 0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC, + 0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F, + 0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61, + 0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57, + 0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D, + 0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57, + 0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC, + 0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC, + 0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48, + 0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52, + 0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61, + 0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A, + 0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC, + 0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC, + 0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49, + 0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F, + 0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB, + 0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47, + 0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54, + 0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D, + 0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC, + 0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC, + 0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45, + 0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44, + 0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64, + 0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48, + 0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D, + 0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC, + 0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA, + 0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55, + 0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45, + 0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D, + 0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B, + 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A, + 0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC, + 0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8, + 0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD, + 0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A, + 0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56, + 0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, + 0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54, + 0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC, + 0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB, + 0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34, + 0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F, + 0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E, + 0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60, + 0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57, + 0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51, + 0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC, + 0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE, + 0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30, + 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41, + 0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65, + 0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C, + 0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A, + 0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC, + 0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C, + 0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1, + 0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32, + 0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30, + 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41, + 0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC, + 0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A, + 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, + 0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E, + 0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC, + 0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88, + 0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB, + 0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33, + 0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31, + 0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E, + 0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63, + 0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49, + 0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, + 0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55, + 0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC, + 0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C, + 0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8, + 0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F, + 0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F, + 0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48, + 0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A, + 0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A, + 0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57, + 0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53, + 0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC, + 0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88, + 0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E, + 0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47, + 0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D, + 0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58, + 0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55, + 0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC, + 0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E, + 0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9, + 0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73, + 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70, + 0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF, + 0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E, + 0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57, + 0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58, + 0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C, + 0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC, + 0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C, + 0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC, + 0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78, + 0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, + 0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1, + 0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C, + 0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D, + 0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58, + 0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E, + 0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC, + 0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8, + 0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42, + 0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73, + 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73, + 0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2, + 0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41, + 0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62, + 0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B, + 0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60, + 0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC, + 0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7, + 0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41, + 0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73, + 0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74, + 0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB, + 0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41, + 0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64, + 0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E, + 0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C, + 0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB, + 0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE, + 0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20, + 0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75, + 0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76, + 0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D, + 0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C, + 0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64, + 0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, + 0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58, + 0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC, + 0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81, + 0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23, + 0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76, + 0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76, + 0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48, + 0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40, + 0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61, + 0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C, + 0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52, + 0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB, + 0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E, + 0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8, + 0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, + 0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C, + 0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57, + 0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D, + 0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A, + 0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65, + 0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC, + 0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40, + 0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47, + 0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF, + 0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A, + 0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57, + 0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5, + 0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C, + 0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52, + 0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9, + 0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42, + 0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51, + 0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6, + 0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7, + 0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93, + 0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D, + 0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF, + 0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40, + 0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52, + 0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1, + 0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8, + 0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93, + 0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40, + 0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0, + 0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F, + 0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59, + 0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E, + 0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23, + 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7, + 0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93, + 0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F, + 0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC, + 0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47, + 0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54, + 0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D, + 0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24, + 0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24, + 0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A, + 0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5, + 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93, + 0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60, + 0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC, + 0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47, + 0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B, + 0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D, + 0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28, + 0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D, + 0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD, + 0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93, + 0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7, + 0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44, + 0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45, + 0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B, + 0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20, + 0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6, + 0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90, + 0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0, + 0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44, + 0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45, + 0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51, + 0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF, + 0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7, + 0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5, + 0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2, + 0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58, + 0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C, + 0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55, + 0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1, + 0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB, + 0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6, + 0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3, + 0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58, + 0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58, + 0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C, + 0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC, + 0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7, + 0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, + 0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0, + 0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58, + 0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60, + 0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60, + 0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB, + 0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7, + 0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7, + 0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE, + 0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B, + 0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61, + 0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64, + 0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC, + 0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8, + 0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5, + 0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C, + 0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E, + 0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62, + 0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC, + 0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB, + 0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7, + 0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5, + 0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57, + 0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47, + 0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60, + 0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0, + 0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0, + 0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8, + 0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6, + 0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57, + 0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B, + 0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C, + 0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3, + 0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB, + 0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8, + 0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7, + 0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57, + 0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C, + 0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58, + 0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1, + 0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC, + 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED, + 0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, + 0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58, + 0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60, + 0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56, + 0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0, + 0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC, + 0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6, + 0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, + 0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B, + 0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C, + 0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59, + 0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0, + 0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC, + 0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6, + 0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6, + 0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B, + 0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56, + 0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60, + 0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF, + 0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9, + 0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9, + 0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, + 0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52, + 0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B, + 0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD, + 0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE, + 0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65, + 0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6, + 0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D, + 0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58, + 0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F, + 0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4, + 0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE, + 0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0, + 0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D, + 0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57, + 0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40, + 0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9, + 0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE, + 0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC, + 0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9, + 0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38, + 0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52, + 0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40, + 0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF, + 0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99, + 0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6, + 0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, + 0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B, + 0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43, + 0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC, + 0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0, + 0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C, + 0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, + 0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49, + 0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A, + 0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2, + 0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94, + 0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, + 0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E, + 0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D, + 0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC, + 0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4, + 0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B, + 0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7, + 0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E, + 0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0, + 0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA, + 0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9, + 0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89, + 0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA, + 0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2, + 0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E, + 0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA, + 0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA, + 0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6, + 0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97, + 0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D, + 0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9, + 0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D, + 0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45, + 0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB, + 0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6, + 0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99, + 0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A, + 0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC, + 0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4, + 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C, + 0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47, + 0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD, + 0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4, + 0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A, + 0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98, + 0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC, + 0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4, + 0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89, + 0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B, + 0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD, + 0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0, + 0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0, + 0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A, + 0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC, + 0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2, + 0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A, + 0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49, + 0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC, + 0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63, + 0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B, + 0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84, + 0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC, + 0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99, + 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B, + 0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51, + 0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC, + 0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A, + 0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95, + 0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E, + 0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA, + 0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22, + 0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99, + 0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94, + 0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B, + 0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA, + 0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D, + 0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C, + 0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A, + 0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23, + 0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99, + 0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E, + 0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87, + 0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3, + 0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48, + 0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94, + 0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95, + 0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6, + 0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40, + 0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99, + 0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95, + 0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98, + 0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC, + 0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45, + 0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89, + 0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C, + 0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4, + 0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99, + 0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87, + 0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC, + 0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58, + 0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40, + 0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94, + 0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B, + 0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6, + 0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20, + 0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C, + 0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94, + 0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE, + 0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C, + 0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41, + 0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98, + 0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C, + 0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6, + 0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B, + 0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B, + 0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0, + 0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62, + 0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44, + 0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6, + 0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89, + 0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8, + 0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99, + 0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98, + 0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1, + 0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB, + 0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49, + 0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA, + 0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2, + 0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA, + 0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2, + 0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0, + 0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF, + 0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD, + 0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52, + 0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA, + 0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA, + 0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1, + 0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8, + 0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0, + 0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9, + 0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD, + 0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53, + 0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56, + 0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0, + 0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9, + 0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0, + 0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3, + 0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF, + 0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2, + 0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3, + 0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE, + 0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56, + 0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57, + 0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC, + 0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA, + 0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4, + 0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3, + 0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1, + 0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6, + 0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE, + 0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD, + 0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58, + 0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D, + 0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47, + 0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6, + 0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4, + 0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5, + 0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9, + 0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC, + 0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3, + 0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64, + 0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C, + 0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A, + 0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A, + 0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0, + 0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE, + 0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6, + 0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6, + 0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE, + 0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5, + 0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E, + 0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D, + 0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E, + 0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E, + 0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8, + 0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5, + 0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1, + 0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60, + 0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9, + 0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5, + 0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47, + 0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E, + 0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45, + 0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51, + 0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB, + 0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0, + 0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D, + 0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0, + 0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5, + 0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2, + 0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D, + 0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60, + 0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45, + 0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63, + 0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7, + 0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3, + 0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E, + 0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2, + 0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0, + 0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC, + 0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C, + 0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61, + 0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45, + 0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2, + 0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3, + 0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2, + 0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47, + 0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2, + 0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E, + 0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3, + 0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63, + 0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62, + 0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49, + 0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3, + 0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF, + 0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2, + 0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58, + 0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE, + 0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B, + 0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4, + 0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE, + 0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62, + 0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A, + 0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5, + 0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE, + 0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3, + 0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53, + 0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3, + 0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48, + 0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3, + 0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF, + 0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0xC0, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x04, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x40, 0x11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0xD2, 0x29, + 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x19, 0xFF, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1E, 0x80, 0x19, + 0xFF, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1E, + 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0E, 0x80, 0x11, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x06, 0x00, 0x11, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x06, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x02, 0x80, 0x10, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x97, 0x10, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xDF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0x18, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0xA8, 0x11, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x01, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x47, 0xFF, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x23, + 0xFF, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x11, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:24 jj Exp $ + * include/asm-sparc/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/SPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 221 + +unsigned char linux_logo_red[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5, + 0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5, + 0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03, + 0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6, + 0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2, + 0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A, + 0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4, + 0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2, + 0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC, + 0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC, + 0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7, + 0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3, + 0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4, + 0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4, + 0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87, + 0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E, + 0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_green[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3, + 0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9, + 0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02, + 0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD, + 0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6, + 0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C, + 0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4, + 0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E, + 0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC, + 0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5, + 0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96, + 0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80, + 0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F, + 0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C, + 0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54, + 0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E, + 0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_blue[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE, + 0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5, + 0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84, + 0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7, + 0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77, + 0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59, + 0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E, + 0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14, + 0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D, + 0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14, + 0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08, + 0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E, + 0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E, + 0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20, + 0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06, + 0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17, + 0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14, + 0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo[] __initdata = { + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61, + 0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E, + 0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58, + 0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C, + 0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A, + 0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52, + 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53, + 0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, + 0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49, + 0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B, + 0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, + 0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB, + 0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C, + 0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49, + 0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5, + 0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58, + 0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51, + 0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54, + 0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5, + 0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61, + 0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C, + 0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B, + 0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53, + 0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC, + 0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59, + 0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48, + 0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51, + 0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63, + 0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48, + 0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51, + 0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52, + 0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB, + 0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B, + 0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53, + 0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53, + 0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC, + 0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F, + 0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61, + 0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57, + 0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D, + 0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57, + 0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC, + 0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC, + 0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48, + 0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52, + 0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61, + 0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A, + 0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC, + 0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC, + 0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49, + 0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F, + 0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB, + 0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47, + 0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54, + 0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D, + 0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC, + 0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC, + 0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45, + 0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44, + 0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64, + 0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48, + 0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D, + 0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC, + 0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA, + 0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55, + 0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45, + 0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D, + 0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B, + 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A, + 0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC, + 0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8, + 0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD, + 0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A, + 0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56, + 0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, + 0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54, + 0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC, + 0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB, + 0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34, + 0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F, + 0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E, + 0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60, + 0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57, + 0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51, + 0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC, + 0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE, + 0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30, + 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41, + 0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65, + 0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C, + 0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A, + 0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC, + 0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C, + 0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1, + 0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32, + 0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30, + 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41, + 0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC, + 0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A, + 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, + 0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E, + 0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC, + 0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88, + 0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB, + 0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33, + 0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31, + 0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E, + 0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63, + 0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49, + 0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, + 0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55, + 0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC, + 0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C, + 0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8, + 0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F, + 0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F, + 0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48, + 0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A, + 0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A, + 0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57, + 0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53, + 0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC, + 0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88, + 0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E, + 0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47, + 0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D, + 0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58, + 0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55, + 0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC, + 0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E, + 0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9, + 0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73, + 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70, + 0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF, + 0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E, + 0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57, + 0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58, + 0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C, + 0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC, + 0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C, + 0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC, + 0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78, + 0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, + 0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1, + 0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C, + 0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D, + 0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58, + 0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E, + 0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC, + 0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8, + 0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42, + 0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73, + 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73, + 0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2, + 0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41, + 0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62, + 0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B, + 0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60, + 0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC, + 0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7, + 0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41, + 0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73, + 0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74, + 0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB, + 0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41, + 0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64, + 0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E, + 0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C, + 0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB, + 0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE, + 0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20, + 0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75, + 0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76, + 0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D, + 0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C, + 0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64, + 0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, + 0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58, + 0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC, + 0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81, + 0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23, + 0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76, + 0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76, + 0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48, + 0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40, + 0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61, + 0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C, + 0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52, + 0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB, + 0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E, + 0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8, + 0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, + 0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C, + 0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57, + 0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D, + 0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A, + 0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65, + 0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC, + 0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40, + 0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47, + 0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF, + 0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A, + 0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57, + 0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5, + 0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C, + 0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52, + 0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9, + 0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42, + 0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51, + 0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6, + 0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7, + 0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93, + 0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D, + 0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF, + 0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40, + 0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52, + 0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1, + 0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8, + 0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93, + 0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40, + 0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0, + 0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F, + 0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59, + 0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E, + 0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23, + 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7, + 0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93, + 0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F, + 0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC, + 0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47, + 0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54, + 0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D, + 0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24, + 0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24, + 0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A, + 0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5, + 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93, + 0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60, + 0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC, + 0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47, + 0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B, + 0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D, + 0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28, + 0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D, + 0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD, + 0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93, + 0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7, + 0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44, + 0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45, + 0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B, + 0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20, + 0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6, + 0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90, + 0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0, + 0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44, + 0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45, + 0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51, + 0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF, + 0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7, + 0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5, + 0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2, + 0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58, + 0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C, + 0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55, + 0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1, + 0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB, + 0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6, + 0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3, + 0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58, + 0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58, + 0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C, + 0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC, + 0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7, + 0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, + 0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0, + 0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58, + 0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60, + 0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60, + 0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB, + 0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7, + 0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7, + 0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE, + 0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B, + 0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61, + 0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64, + 0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC, + 0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8, + 0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5, + 0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C, + 0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E, + 0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62, + 0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC, + 0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB, + 0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7, + 0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5, + 0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57, + 0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47, + 0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60, + 0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0, + 0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0, + 0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8, + 0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6, + 0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57, + 0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B, + 0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C, + 0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3, + 0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB, + 0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8, + 0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7, + 0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57, + 0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C, + 0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58, + 0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1, + 0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC, + 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED, + 0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, + 0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58, + 0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60, + 0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56, + 0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0, + 0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC, + 0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6, + 0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, + 0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B, + 0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C, + 0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59, + 0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0, + 0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC, + 0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6, + 0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6, + 0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B, + 0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56, + 0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60, + 0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF, + 0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9, + 0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9, + 0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, + 0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52, + 0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B, + 0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD, + 0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE, + 0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65, + 0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6, + 0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D, + 0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58, + 0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F, + 0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4, + 0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE, + 0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0, + 0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D, + 0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57, + 0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40, + 0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9, + 0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE, + 0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC, + 0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9, + 0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38, + 0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52, + 0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40, + 0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF, + 0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99, + 0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6, + 0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, + 0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B, + 0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43, + 0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC, + 0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0, + 0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C, + 0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, + 0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49, + 0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A, + 0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2, + 0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94, + 0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, + 0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E, + 0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D, + 0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC, + 0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4, + 0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B, + 0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7, + 0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E, + 0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0, + 0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA, + 0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9, + 0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89, + 0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA, + 0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2, + 0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E, + 0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA, + 0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA, + 0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6, + 0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97, + 0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D, + 0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9, + 0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D, + 0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45, + 0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB, + 0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6, + 0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99, + 0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A, + 0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC, + 0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4, + 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C, + 0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47, + 0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD, + 0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4, + 0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A, + 0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98, + 0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC, + 0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4, + 0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89, + 0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B, + 0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD, + 0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0, + 0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0, + 0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A, + 0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC, + 0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2, + 0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A, + 0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49, + 0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC, + 0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63, + 0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B, + 0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84, + 0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC, + 0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99, + 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B, + 0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51, + 0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC, + 0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A, + 0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95, + 0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E, + 0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA, + 0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22, + 0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99, + 0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94, + 0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B, + 0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA, + 0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D, + 0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C, + 0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A, + 0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23, + 0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99, + 0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E, + 0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87, + 0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3, + 0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48, + 0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94, + 0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95, + 0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6, + 0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40, + 0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99, + 0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95, + 0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98, + 0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC, + 0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45, + 0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89, + 0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C, + 0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4, + 0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99, + 0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87, + 0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC, + 0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58, + 0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40, + 0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94, + 0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B, + 0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6, + 0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20, + 0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C, + 0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94, + 0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE, + 0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C, + 0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41, + 0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98, + 0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C, + 0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6, + 0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B, + 0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B, + 0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0, + 0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62, + 0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44, + 0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6, + 0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89, + 0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8, + 0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99, + 0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98, + 0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1, + 0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB, + 0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49, + 0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA, + 0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2, + 0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA, + 0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2, + 0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0, + 0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF, + 0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD, + 0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52, + 0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA, + 0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA, + 0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1, + 0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8, + 0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0, + 0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9, + 0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD, + 0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53, + 0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56, + 0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0, + 0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9, + 0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0, + 0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3, + 0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF, + 0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2, + 0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3, + 0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE, + 0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56, + 0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57, + 0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC, + 0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA, + 0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4, + 0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3, + 0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1, + 0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6, + 0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE, + 0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD, + 0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58, + 0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D, + 0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47, + 0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6, + 0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4, + 0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5, + 0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9, + 0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC, + 0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3, + 0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64, + 0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C, + 0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A, + 0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A, + 0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0, + 0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE, + 0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6, + 0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6, + 0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE, + 0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5, + 0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E, + 0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D, + 0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E, + 0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E, + 0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8, + 0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5, + 0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1, + 0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60, + 0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9, + 0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5, + 0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47, + 0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E, + 0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45, + 0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51, + 0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB, + 0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0, + 0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D, + 0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0, + 0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5, + 0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2, + 0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D, + 0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60, + 0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45, + 0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63, + 0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7, + 0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3, + 0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E, + 0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2, + 0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0, + 0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC, + 0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C, + 0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61, + 0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45, + 0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2, + 0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3, + 0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2, + 0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47, + 0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2, + 0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E, + 0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3, + 0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63, + 0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62, + 0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49, + 0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3, + 0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF, + 0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2, + 0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58, + 0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE, + 0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B, + 0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4, + 0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE, + 0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62, + 0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A, + 0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5, + 0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE, + 0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3, + 0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53, + 0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3, + 0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48, + 0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3, + 0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF, + 0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0xC0, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x04, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x40, 0x11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0xD2, 0x29, + 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x19, 0xFF, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1E, 0x80, 0x19, + 0xFF, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1E, + 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0E, 0x80, 0x11, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x06, 0x00, 0x11, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x06, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x02, 0x80, 0x10, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x97, 0x10, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xDF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0x18, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0xA8, 0x11, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x01, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x47, 0xFF, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x23, + 0xFF, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x11, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; diff --git a/include/asm-sparc/mxcc.h b/include/asm-sparc/mxcc.h index 87947bc0f..efe4e8431 100644 --- a/include/asm-sparc/mxcc.h +++ b/include/asm-sparc/mxcc.h @@ -1,4 +1,4 @@ -/* $Id: mxcc.h,v 1.6 1996/08/29 09:48:27 davem Exp $ +/* $Id: mxcc.h,v 1.7 1997/04/20 14:11:46 ecd Exp $ * mxcc.h: Definitions of the Viking MXCC registers * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -83,6 +83,8 @@ * MID: The moduleID of the cpu your read this from. */ +#ifndef __ASSEMBLY__ + extern __inline__ void mxcc_set_stream_src(unsigned long *paddr) { unsigned long data0 = paddr[0]; @@ -130,4 +132,6 @@ extern __inline__ void mxcc_set_creg(unsigned long mxcc_control) "i" (ASI_M_MXCC)); } +#endif /* !__ASSEMBLY__ */ + #endif /* !(_SPARC_MXCC_H) */ diff --git a/include/asm-sparc/smp_lock.h b/include/asm-sparc/smp_lock.h index 70860c404..4f0a8e5f4 100644 --- a/include/asm-sparc/smp_lock.h +++ b/include/asm-sparc/smp_lock.h @@ -63,19 +63,6 @@ extern __inline__ void lock_kernel(void) register int proc asm("g5"); klip = &klock_info; proc = smp_processor_id(); - -#if 1 /* Debugging */ - if(local_irq_count[proc]) { - __label__ l1; -l1: printk("lock from interrupt context at %p\n", &&l1); - } - if(proc == global_irq_holder) { - __label__ l2; -l2: printk("Ugh at %p\n", &&l2); - sti(); - } -#endif - __asm__ __volatile__(" mov %%o7, %%g4 call ___lock_kernel diff --git a/include/asm-sparc/softirq.h b/include/asm-sparc/softirq.h index 76cec1e71..41b72b40a 100644 --- a/include/asm-sparc/softirq.h +++ b/include/asm-sparc/softirq.h @@ -13,18 +13,17 @@ * is entirely private to an implementation, it should not be * referenced at all outside of this file. */ +#define get_active_bhs() (bh_mask & bh_active) + +#ifdef __SMP__ + extern atomic_t __sparc_bh_counter; -/* Linus, I'd _really_ like to get rid of this synchronize_irq() -DaveM */ #define start_bh_atomic() \ do { atomic_inc(&__sparc_bh_counter); synchronize_irq(); } while(0) #define end_bh_atomic() atomic_dec(&__sparc_bh_counter) -#define get_active_bhs() (bh_mask & bh_active) - -#ifdef __SMP__ - #include extern spinlock_t global_bh_lock; @@ -39,6 +38,15 @@ do { unsigned long flags; \ spin_unlock_irqrestore(&global_bh_lock, flags); \ } while(0) +#define remove_bh(nr) \ +do { unsigned long flags; \ + int ent = nr; \ + spin_lock_irqsave(&global_bh_lock, flags); \ + bh_base[ent] = NULL; \ + bh_mask &= ~(1 << ent); \ + spin_unlock_irqrestore(&global_bh_lock, flags); \ +} while(0) + #define mark_bh(nr) \ do { unsigned long flags; \ spin_lock_irqsave(&global_bh_lock, flags); \ @@ -83,10 +91,13 @@ do { unsigned long flags; \ #else /* !(__SMP__) */ -#define softirq_trylock() \ - (atomic_read(&__sparc_bh_counter) ? 0 : ((atomic_set(&__sparc_bh_counter,1)),1)) +extern int __sparc_bh_counter; -#define softirq_endlock() (atomic_set(&__sparc_bh_counter, 0)) +#define start_bh_atomic() do { __sparc_bh_counter++; barrier(); } while(0) +#define end_bh_atomic() do { barrier(); __sparc_bh_counter--; } while(0) + +#define softirq_trylock() (__sparc_bh_counter ? 0 : (__sparc_bh_counter=1)) +#define softirq_endlock() (__sparc_bh_counter = 0) #define clear_active_bhs(x) (bh_active &= ~(x)) #define init_bh(nr, routine) \ @@ -96,6 +107,12 @@ do { int ent = nr; \ bh_mask |= 1 << ent; \ } while(0) +#define remove_bh(nr) \ +do { int ent = nr; \ + bh_base[ent] = NULL; \ + bh_mask &= ~(1 << ent); \ +} while(0) + #define mark_bh(nr) (bh_active |= (1 << (nr))) #define disable_bh(nr) \ diff --git a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h index af6c5163f..877b7416a 100644 --- a/include/asm-sparc/spinlock.h +++ b/include/asm-sparc/spinlock.h @@ -16,6 +16,7 @@ typedef struct { } spinlock_t; #define spin_lock_init(lock) do { } while(0) #define spin_lock(lock) do { } while(0) #define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) #define spin_unlock(lock) do { } while(0) #define spin_lock_irq(lock) cli() #define spin_unlock_irq(lock) sti() @@ -58,21 +59,24 @@ typedef unsigned char spinlock_t; #define SPIN_LOCK_UNLOCKED 0 #define spin_lock_init(lock) (*(lock) = 0) +#define spin_unlock_wait(lock) do { barrier(); } while(*(volatile spinlock_t *)lock) extern __inline__ void spin_lock(spinlock_t *lock) { - register spinlock_t *lp asm("g1"); - lp = lock; __asm__ __volatile__(" - ldstub [%%g1], %%g2 +1: ldstub [%0], %%g2 orcc %%g2, 0x0, %%g0 - be 1f - mov %%o7, %%g4 - call ___spinlock_waitfor - ldub [%%g1], %%g2 -1:" : /* no outputs */ - : "r" (lp) - : "g2", "g4", "memory", "cc"); + bne,a 2f + ldub [%0], %%g2 + .text 2 +2: orcc %%g2, 0x0, %%g0 + bne,a 2b + ldub [%0], %%g2 + b,a 1b + .previous +" : /* no outputs */ + : "r" (lock) + : "g2", "memory", "cc"); } extern __inline__ int spin_trylock(spinlock_t *lock) @@ -92,22 +96,24 @@ extern __inline__ void spin_unlock(spinlock_t *lock) extern __inline__ void spin_lock_irq(spinlock_t *lock) { - register spinlock_t *lp asm("g1"); - lp = lock; __asm__ __volatile__(" rd %%psr, %%g2 or %%g2, %0, %%g2 wr %%g2, 0x0, %%psr nop; nop; nop; - ldstub [%%g1], %%g2 +1: ldstub [%1], %%g2 orcc %%g2, 0x0, %%g0 - be 1f - mov %%o7, %%g4 - call ___spinlock_waitfor - ldub [%%g1], %%g2 -1:" : /* No outputs */ - : "i" (PSR_PIL), "r" (lp) - : "g2", "g4", "memory", "cc"); + bne,a 2f + ldub [%1], %%g2 + .text 2 +2: orcc %%g2, 0x0, %%g0 + bne,a 2b + ldub [%1], %%g2 + b,a 1b + .previous +" : /* No outputs */ + : "i" (PSR_PIL), "r" (lock) + : "g2", "memory", "cc"); } extern __inline__ void spin_unlock_irq(spinlock_t *lock) @@ -131,16 +137,22 @@ do { \ "rd %%psr, %0\n\t" \ "or %0, %1, %%g2\n\t" \ "wr %%g2, 0x0, %%psr\n\t" \ - "nop; nop; nop;\n\t" \ - "ldstub [%%g1], %%g2\n\t" \ + "nop; nop; nop;\n" \ + "1:\n\t" \ + "ldstub [%2], %%g2\n\t" \ + "orcc %%g2, 0x0, %%g0\n\t" \ + "bne,a 2f\n\t" \ + " ldub [%2], %%g2\n\t" \ + ".text 2\n" \ + "2:\n\t" \ "orcc %%g2, 0x0, %%g0\n\t" \ - "be 1f\n\t" \ - " mov %%o7, %%g4\n\t" \ - "call ___spinlock_waitfor\n\t" \ - " ldub [%%g1], %%g2\n\t" \ -"1:" : "=r" (flags) \ - : "i" (PSR_PIL), "r" (lp) \ - : "g2", "g4", "memory", "cc"); \ + "bne,a 2b\n\t" \ + " ldub [%2], %%g2\n\t" \ + "b,a 1b\n\t" \ + ".previous\n" \ + : "=r" (flags) \ + : "i" (PSR_PIL), "r" (lock) \ + : "g2", "memory", "cc"); \ } while(0) extern __inline__ void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h index e4ecd6046..e1d33e436 100644 --- a/include/asm-sparc/system.h +++ b/include/asm-sparc/system.h @@ -1,4 +1,4 @@ -/* $Id: system.h,v 1.57 1997/04/15 09:03:45 davem Exp $ */ +/* $Id: system.h,v 1.58 1997/04/18 05:44:54 davem Exp $ */ #ifndef __SPARC_SYSTEM_H #define __SPARC_SYSTEM_H @@ -124,9 +124,7 @@ extern __inline__ void setipl(unsigned long __orig_psr) { __asm__ __volatile__(" wr %0, 0x0, %%psr - nop - nop - nop + nop; nop; nop " : /* no outputs */ : "r" (__orig_psr) : "memory", "cc"); @@ -138,14 +136,9 @@ extern __inline__ void __cli(void) __asm__ __volatile__(" rd %%psr, %0 - andcc %0, %1, %%g0 - bne 1f - nop - wr %0, %1, %%psr - nop - nop - nop -1: + or %0, %1, %0 + wr %0, 0x0, %%psr + nop; nop; nop " : "=r" (tmp) : "i" (PSR_PIL) : "memory"); @@ -157,14 +150,9 @@ extern __inline__ void __sti(void) __asm__ __volatile__(" rd %%psr, %0 - andcc %0, %1, %%g0 - be 1f - nop - wr %0, %1, %%psr - nop - nop - nop -1: + andn %0, %1, %0 + wr %0, 0x0, %%psr + nop; nop; nop " : "=r" (tmp) : "i" (PSR_PIL) : "memory"); @@ -189,7 +177,7 @@ extern __inline__ unsigned long swap_pil(unsigned long __new_psr) xorcc %1, %2, %%g0 be 1f nop - wr %0, %4, %%psr + wr %0, %4, %%psr nop nop nop @@ -207,38 +195,64 @@ extern __inline__ unsigned long read_psr_and_cli(void) __asm__ __volatile__(" rd %%psr, %0 - andcc %0, %1, %%g0 - bne 1f - nop - wr %0, %1, %%psr - nop - nop - nop -1: + or %0, %1, %%g1 + wr %%g1, 0x0, %%psr + nop; nop; nop " : "=r" (retval) : "i" (PSR_PIL) - : "memory"); + : "g1", "memory"); return retval; } -extern char spdeb_buf[256]; - #define __save_flags(flags) ((flags) = getipl()) #define __save_and_cli(flags) ((flags) = read_psr_and_cli()) #define __restore_flags(flags) setipl((flags)) #ifdef __SMP__ -extern void __global_cli(void); -extern void __global_sti(void); -extern unsigned long __global_save_flags(void); -extern void __global_restore_flags(unsigned long); -#define cli() __global_cli() -#define sti() __global_sti() -#define save_flags(x) ((x)=__global_save_flags()) -#define restore_flags(x) __global_restore_flags(x) -#define save_and_cli(x) do { (x)=__global_save_flags(); __global_cli(); } while(0) +/* Visit arch/sparc/lib/irqlock.S for all the fun details... */ +#define cli() __asm__ __volatile__("mov %%o7, %%g4\n\t" \ + "call ___global_cli\n\t" \ + " rd %%tbr, %%g7" : : \ + : "g1", "g2", "g3", "g4", "g5", "g7", \ + "memory", "cc") + +#define sti() \ +do { register unsigned long bits asm("g7"); \ + bits = 0; \ + __asm__ __volatile__("mov %%o7, %%g4\n\t" \ + "call ___global_sti\n\t" \ + " rd %%tbr, %%g2" \ + : /* no outputs */ \ + : "r" (bits) \ + : "g1", "g2", "g3", "g4", "g5", \ + "memory", "cc"); \ +} while(0) + +extern unsigned char global_irq_holder; + +#define save_flags(x) \ +do { int cpuid; \ + __asm__ __volatile__("rd %%tbr, %0; srl %0, 12, %0; and %0, 3, %0" \ + : "=r" (cpuid)); \ + ((x) = ((global_irq_holder == (unsigned char) cpuid) ? 1 : \ + ((getipl() & PSR_PIL) ? 2 : 0))); \ +} while(0) + +#define restore_flags(flags) \ +do { register unsigned long bits asm("g7"); \ + bits = flags; \ + __asm__ __volatile__("mov %%o7, %%g4\n\t" \ + "call ___global_restore_flags\n\t" \ + " andcc %%g7, 0x1, %%g0" \ + : "=&r" (bits) \ + : "0" (bits) \ + : "g1", "g2", "g3", "g4", "g5", \ + "memory", "cc"); \ +} while(0) + +#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0) #else diff --git a/include/asm-sparc/viking.h b/include/asm-sparc/viking.h index f678f702d..0312a2d55 100644 --- a/include/asm-sparc/viking.h +++ b/include/asm-sparc/viking.h @@ -1,4 +1,4 @@ -/* $Id: viking.h,v 1.18 1997/04/11 00:42:23 davem Exp $ +/* $Id: viking.h,v 1.19 1997/04/20 14:11:48 ecd Exp $ * viking.h: Defines specific to the GNU/Viking MBUS module. * This is SRMMU stuff. * @@ -108,6 +108,8 @@ #define VIKING_PTAG_DIRTY 0x00010000 /* Block has been modified */ #define VIKING_PTAG_SHARED 0x00000100 /* Shared with some other cache */ +#ifndef __ASSEMBLY__ + extern __inline__ void viking_flush_icache(void) { __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : @@ -235,4 +237,6 @@ extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr) return val; } +#endif /* !__ASSEMBLY__ */ + #endif /* !(_SPARC_VIKING_H) */ diff --git a/include/asm-sparc64/linux_logo.h b/include/asm-sparc64/linux_logo.h new file mode 100644 index 000000000..7787fb059 --- /dev/null +++ b/include/asm-sparc64/linux_logo.h @@ -0,0 +1,2084 @@ +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:37 jj Exp $ + * include/asm-sparc64/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/UltraSPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 215 + +unsigned char linux_logo_red[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xB0, + 0x0C, 0xB1, 0xD4, 0xCE, 0x04, 0x06, 0x16, 0xB6, + 0xCD, 0xB2, 0x42, 0x46, 0x4B, 0xA8, 0xF3, 0xCA, + 0xC5, 0x1C, 0xDC, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x8E, 0xCC, 0xA5, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x79, 0x68, 0x8D, 0xAF, 0xFC, 0x8E, 0x3E, + 0x6B, 0x11, 0x37, 0x79, 0x5C, 0x3C, 0x3F, 0x3C, + 0x48, 0x47, 0x3D, 0xB9, 0x62, 0xE1, 0x4D, 0x57, + 0x84, 0x78, 0xA6, 0x58, 0x99, 0xCD, 0xB7, 0xE3, + 0x6D, 0x5A, 0xAF, 0x79, 0x79, 0xF2, 0x42, 0x46, + 0xDD, 0x89, 0xC3, 0xF2, 0xF0, 0xE0, 0xD1, 0x90, + 0x76, 0x6B, 0x4A, 0xBE, 0xBD, 0xE3, 0xF6, 0xE9, + 0xEC, 0xE8, 0xEC, 0xC0, 0x66, 0x63, 0xCB, 0xAB, + 0x49, 0x5C, 0xAD, 0xD6, 0xEE, 0xF5, 0xF5, 0xE9, + 0x6E, 0x00, 0x69, 0x6A, 0xA1, 0x7A, 0xB4, 0xDE, + 0xF1, 0xF6, 0xDD, 0x00, 0x73, 0xDB, 0x4C, 0x53, + 0x6A, 0xF5, 0xF5, 0xD6, 0xC3, 0x6A, 0x4B, 0x4B, + 0x60, 0xF8, 0x9B, 0xD7, 0xD7, 0x71, 0xB3, 0xA4, + 0xCA, 0xAB, 0xB4, 0xB2, 0x76, 0xBA, 0x8B, 0xA0, + 0xA5, 0xEE, 0xE7, 0x67, 0x5F, 0x08, 0x94, 0xDB, + 0xE5, 0x4F, 0x00, 0x34, 0xEE, 0xEC, 0xE2, 0x48, + 0xF3, 0xEB, 0xF4, 0xF4, 0xEF, 0xD6, 0xB6, 0xE6, + 0xE6, 0xED, 0xE7, 0xE6, 0x3D, 0xE7, 0xCD, 0x44, + 0xEF, 0xEC, 0xF5, 0x66, 0xF3, 0xA9, 0x77, 0x58, + 0x75, 0x6C, 0x53, 0x24, 0xAC, 0x0D, 0x3C +}; + +unsigned char linux_logo_green[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xAD, + 0x0C, 0xB1, 0x92, 0xAB, 0x03, 0x06, 0x16, 0xB6, + 0xCD, 0x88, 0x42, 0x46, 0x4B, 0x94, 0xBB, 0xCA, + 0xC5, 0x1C, 0xAB, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x73, 0xCA, 0x91, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x5A, 0x49, 0x56, 0x6E, 0xFC, 0x6B, 0x3E, + 0x6B, 0x0D, 0x37, 0x79, 0x51, 0x44, 0x3F, 0x43, + 0x38, 0x3D, 0x48, 0xB9, 0x62, 0xA5, 0x47, 0x48, + 0x49, 0x4A, 0x97, 0x48, 0x81, 0x95, 0x8E, 0xE3, + 0x6D, 0x57, 0x51, 0x51, 0x47, 0xB2, 0x42, 0x46, + 0xDD, 0x5B, 0x87, 0xBE, 0xC7, 0xC8, 0x56, 0x75, + 0x5D, 0x4B, 0x4D, 0xBE, 0x85, 0xA6, 0xBC, 0xC7, + 0xCA, 0xCD, 0xCC, 0xA4, 0x53, 0x4D, 0x9F, 0x55, + 0x52, 0x5E, 0x75, 0x9C, 0xB6, 0xC3, 0xD7, 0xCC, + 0x55, 0x00, 0x6A, 0x59, 0x7D, 0x55, 0x7C, 0xA3, + 0xB7, 0xBF, 0xA5, 0x00, 0x67, 0xC6, 0x47, 0x54, + 0x46, 0xB8, 0xBE, 0xB2, 0x87, 0x52, 0x4B, 0x43, + 0x41, 0xF8, 0x69, 0x96, 0x9B, 0x66, 0xB0, 0x6C, + 0x8E, 0x81, 0xB4, 0x76, 0x76, 0xB9, 0x65, 0x77, + 0x6D, 0xED, 0xE7, 0x67, 0x5F, 0x06, 0x54, 0x6C, + 0xCB, 0x4F, 0x00, 0x2F, 0xC2, 0xB5, 0xB6, 0x30, + 0xC3, 0xAE, 0xC4, 0xCA, 0xC6, 0xB4, 0x7B, 0xAD, + 0xAD, 0xB6, 0xB6, 0xAD, 0x29, 0xAB, 0x93, 0x2E, + 0xBC, 0xBC, 0xC9, 0x53, 0xBF, 0x77, 0x54, 0x3B, + 0x4B, 0x3F, 0x39, 0x19, 0x76, 0x08, 0x2C +}; + +unsigned char linux_logo_blue[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0xD6, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x39, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xA7, + 0x0C, 0xB1, 0x58, 0x8A, 0x03, 0x07, 0x16, 0xB6, + 0xCD, 0x5A, 0x42, 0x46, 0x4F, 0x6F, 0x77, 0xCA, + 0xC5, 0x1C, 0x6F, 0xA5, 0xD4, 0xE6, 0xF5, 0xF3, + 0xC2, 0x4D, 0xD1, 0x64, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x49, 0x3C, 0x47, 0x45, 0xFE, 0x3B, 0x41, + 0x6B, 0x09, 0x37, 0x79, 0x39, 0x39, 0x3F, 0x42, + 0x3A, 0x42, 0x5F, 0xB9, 0x62, 0x4C, 0x39, 0x44, + 0x3B, 0x3A, 0xA0, 0x3D, 0x08, 0x08, 0x09, 0xDE, + 0x6D, 0x48, 0x3B, 0x3F, 0x42, 0xF3, 0x36, 0x3C, + 0xDD, 0x06, 0x16, 0x08, 0x13, 0x0A, 0x4B, 0x71, + 0x5D, 0x44, 0x47, 0xBE, 0x08, 0x0C, 0x0D, 0x0C, + 0x19, 0x29, 0x36, 0x06, 0x43, 0x44, 0xBA, 0x45, + 0x50, 0x58, 0x07, 0x07, 0x0D, 0x0E, 0x10, 0x50, + 0x06, 0x42, 0x40, 0x44, 0x79, 0x06, 0x06, 0x0C, + 0x08, 0x08, 0x07, 0x36, 0x4C, 0xE5, 0x42, 0x55, + 0x03, 0x0F, 0x12, 0x06, 0x07, 0x3C, 0x4B, 0x3D, + 0x01, 0xF8, 0x08, 0x0E, 0x0A, 0x69, 0xAC, 0x0C, + 0x0A, 0x27, 0xBB, 0x36, 0x76, 0xC0, 0x04, 0x08, + 0x08, 0xED, 0xEE, 0x68, 0x5F, 0xB2, 0x3B, 0x52, + 0xAC, 0x4F, 0x6F, 0x2D, 0x16, 0x08, 0x59, 0x04, + 0x13, 0x0E, 0x14, 0x17, 0x16, 0x2E, 0x08, 0x0D, + 0x11, 0x14, 0x0D, 0x06, 0x04, 0x08, 0x25, 0x8E, + 0x0E, 0x14, 0x25, 0x9B, 0x1C, 0x16, 0x78, 0x06, + 0x04, 0x03, 0x79, 0x8C, 0x0B, 0xC8, 0x48 +}; + +unsigned char linux_logo[] __initdata = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x22, 0x23, 0x24, 0x24, + 0x25, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x23, 0x23, + 0x23, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x26, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x26, 0x28, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x28, 0x28, 0x28, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x2C, 0x29, 0x29, 0x29, 0x28, + 0x28, 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2A, 0x2A, + 0x2A, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2D, 0x2E, 0x2F, 0x27, + 0x27, 0x26, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x28, + 0x28, 0x29, 0x29, 0x29, 0x29, 0x2C, 0x2C, 0x29, + 0x29, 0x29, 0x28, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x30, 0x31, 0x32, + 0x27, 0x27, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, + 0x20, 0x20, 0x2B, 0x2A, 0x28, 0x29, 0x29, 0x29, + 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x28, 0x2A, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x27, 0x27, 0x33, 0x25, 0x25, 0x24, 0x24, + 0x24, 0x24, 0x23, 0x21, 0x20, 0x20, 0x2B, 0x2A, + 0x28, 0x29, 0x29, 0x37, 0x2C, 0x2C, 0x29, 0x28, + 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2A, 0x2B, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x32, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x25, 0x24, 0x23, 0x21, + 0x20, 0x2B, 0x2A, 0x29, 0x29, 0x2C, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x38, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x23, 0x23, 0x24, 0x24, + 0x25, 0x25, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x24, 0x22, 0x20, 0x20, 0x2A, 0x28, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x23, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x21, 0x22, 0x24, 0x20, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x3A, 0x3B, 0x22, 0x20, 0x2A, 0x28, + 0x29, 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x20, 0x21, 0x22, 0x22, 0x23, 0x24, 0x27, + 0x27, 0x27, 0x3C, 0x36, 0x3C, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x3D, 0x3E, 0x32, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x39, 0x3F, 0x3F, + 0x39, 0x2C, 0x20, 0x20, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x40, 0x40, 0x41, 0x22, 0x20, + 0x2A, 0x28, 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x2A, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, + 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x22, 0x27, + 0x27, 0x3C, 0x3C, 0x3D, 0x42, 0x3C, 0x27, 0x27, + 0x3C, 0x27, 0x3C, 0x43, 0x44, 0x36, 0x42, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x28, 0x29, 0x2C, + 0x2C, 0x45, 0x20, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x46, 0x40, 0x47, 0x40, 0x47, 0x3A, 0x40, + 0x22, 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x2C, 0x29, + 0x28, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x20, 0x27, + 0x27, 0x44, 0x28, 0x24, 0x27, 0x2F, 0x3C, 0x27, + 0x27, 0x38, 0x24, 0x2C, 0x2C, 0x48, 0x49, 0x36, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x29, 0x29, + 0x4A, 0x20, 0x3A, 0x40, 0x47, 0x40, 0x47, 0x40, + 0x40, 0x47, 0x40, 0x40, 0x39, 0x39, 0x39, 0x4A, + 0x25, 0x24, 0x22, 0x2B, 0x28, 0x29, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x21, 0x20, 0x2B, 0x2A, 0x27, + 0x3D, 0x4B, 0x48, 0x4C, 0x2B, 0x3C, 0x27, 0x3C, + 0x3C, 0x23, 0x4D, 0x4E, 0x4F, 0x50, 0x33, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x39, 0x3F, 0x39, + 0x51, 0x20, 0x39, 0x39, 0x47, 0x40, 0x4D, 0x4D, + 0x40, 0x52, 0x4D, 0x40, 0x47, 0x40, 0x39, 0x39, + 0x53, 0x54, 0x25, 0x24, 0x20, 0x2A, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x2A, 0x2B, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x21, 0x20, 0x2B, 0x28, 0x2A, 0x20, 0x27, + 0x36, 0x4F, 0x55, 0x48, 0x56, 0x3D, 0x3C, 0x3C, + 0x32, 0x57, 0x56, 0x58, 0x49, 0x56, 0x56, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x20, 0x20, + 0x41, 0x39, 0x39, 0x3A, 0x59, 0x5A, 0x59, 0x5B, + 0x5C, 0x3A, 0x4D, 0x5D, 0x57, 0x39, 0x39, 0x4A, + 0x5E, 0x33, 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, + 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, + 0x20, 0x2B, 0x2A, 0x2A, 0x20, 0x22, 0x22, 0x27, + 0x5F, 0x2D, 0x3C, 0x60, 0x56, 0x54, 0x61, 0x49, + 0x35, 0x56, 0x34, 0x27, 0x62, 0x27, 0x56, 0x39, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x63, 0x54, + 0x40, 0x64, 0x65, 0x66, 0x67, 0x67, 0x68, 0x5F, + 0x2E, 0x69, 0x6A, 0x67, 0x5F, 0x3A, 0x39, 0x2C, + 0x53, 0x23, 0x25, 0x54, 0x33, 0x25, 0x23, 0x20, + 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, + 0x2B, 0x2A, 0x20, 0x22, 0x22, 0x21, 0x2B, 0x27, + 0x62, 0x36, 0x27, 0x33, 0x6B, 0x54, 0x3D, 0x3C, + 0x49, 0x57, 0x27, 0x27, 0x27, 0x27, 0x56, 0x57, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x6C, 0x31, 0x6D, + 0x64, 0x51, 0x6E, 0x2E, 0x2E, 0x6F, 0x5A, 0x70, + 0x70, 0x71, 0x72, 0x67, 0x67, 0x69, 0x73, 0x46, + 0x4A, 0x2A, 0x21, 0x25, 0x33, 0x54, 0x33, 0x24, + 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, + 0x2B, 0x22, 0x22, 0x22, 0x2B, 0x28, 0x2A, 0x27, + 0x27, 0x39, 0x3C, 0x3D, 0x45, 0x74, 0x75, 0x76, + 0x76, 0x45, 0x27, 0x27, 0x27, 0x27, 0x56, 0x77, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x78, 0x78, 0x5E, + 0x79, 0x7A, 0x7B, 0x6E, 0x5A, 0x5A, 0x70, 0x7C, + 0x70, 0x5B, 0x7D, 0x5A, 0x66, 0x7E, 0x7F, 0x79, + 0x48, 0x6B, 0x2C, 0x20, 0x24, 0x33, 0x54, 0x33, + 0x24, 0x21, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x21, + 0x22, 0x22, 0x20, 0x28, 0x2B, 0x20, 0x22, 0x27, + 0x27, 0x80, 0x27, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x74, 0x85, 0x84, 0x27, 0x3C, 0x4F, 0x4F, 0x66, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x23, 0x5E, + 0x64, 0x86, 0x79, 0x73, 0x87, 0x88, 0x7C, 0x5A, + 0x5A, 0x71, 0x7D, 0x71, 0x89, 0x79, 0x8A, 0x8A, + 0x51, 0x8B, 0x48, 0x39, 0x2A, 0x22, 0x33, 0x54, + 0x33, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x2C, 0x29, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x22, 0x23, + 0x21, 0x2A, 0x2A, 0x20, 0x21, 0x23, 0x25, 0x27, + 0x27, 0x55, 0x8C, 0x8D, 0x8E, 0x83, 0x8F, 0x90, + 0x91, 0x92, 0x92, 0x85, 0x85, 0x93, 0x51, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0x29, 0x51, + 0x79, 0x79, 0x94, 0x89, 0x89, 0x89, 0x5A, 0x95, + 0x64, 0x88, 0x96, 0x97, 0x7A, 0x73, 0x98, 0x98, + 0x99, 0x50, 0x50, 0x48, 0x6B, 0x28, 0x21, 0x25, + 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2B, 0x20, 0x22, 0x22, 0x20, + 0x2B, 0x2B, 0x20, 0x22, 0x24, 0x25, 0x33, 0x27, + 0x27, 0x9A, 0x9B, 0x9C, 0x9D, 0x83, 0x9E, 0x85, + 0x9F, 0x92, 0x85, 0x85, 0x85, 0x85, 0x92, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xA1, 0x47, 0xA2, + 0xA2, 0x94, 0xA3, 0x94, 0x95, 0x95, 0x73, 0x73, + 0x95, 0x87, 0xA4, 0x5B, 0x97, 0x7B, 0x88, 0x98, + 0xA2, 0x50, 0x48, 0x48, 0x48, 0x8B, 0x29, 0x20, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x2B, 0x2B, + 0x20, 0x21, 0x23, 0x24, 0x25, 0x25, 0x33, 0x27, + 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x8F, 0x90, 0x90, + 0x9F, 0x90, 0x85, 0x90, 0x85, 0x74, 0xAA, 0x81, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xAB, 0x40, 0xAC, + 0x79, 0xA3, 0x89, 0xAD, 0x95, 0x6F, 0xAE, 0xAE, + 0xAE, 0x5B, 0x59, 0x88, 0x7B, 0x89, 0x79, 0xAF, + 0xA2, 0x6B, 0x48, 0x48, 0x48, 0x48, 0x50, 0x2C, + 0x20, 0x24, 0x33, 0x54, 0x25, 0x22, 0x2A, 0x2A, + 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x23, 0x22, 0x2B, 0x20, 0x20, + 0x22, 0x23, 0x24, 0x25, 0x24, 0x24, 0x22, 0x27, + 0xB0, 0x8C, 0xAA, 0xB1, 0xB2, 0x84, 0x85, 0x9F, + 0x85, 0x85, 0x85, 0xB3, 0xB4, 0xAA, 0xAA, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0xB5, + 0xA3, 0xA3, 0xAC, 0x5D, 0xB6, 0xAE, 0xB7, 0x69, + 0x73, 0x5B, 0x88, 0x89, 0x95, 0x73, 0x99, 0x99, + 0x59, 0x2A, 0x39, 0x48, 0x48, 0x50, 0x48, 0x50, + 0x2C, 0x20, 0x24, 0x33, 0x54, 0x25, 0x21, 0x20, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x23, 0x21, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x24, 0x24, 0x23, 0x22, 0x20, 0x2A, 0x27, + 0x27, 0xB0, 0x8C, 0xA9, 0xB2, 0x9E, 0x91, 0x85, + 0x85, 0x93, 0xB8, 0x75, 0xAA, 0xA7, 0x8C, 0x27, + 0x27, 0x27, 0x33, 0x3C, 0x27, 0x27, 0x2C, 0x7B, + 0x55, 0x79, 0xA3, 0x5D, 0xB9, 0x43, 0x7F, 0x7E, + 0x5F, 0x5A, 0x5A, 0x95, 0x64, 0x73, 0x58, 0x64, + 0x5C, 0x25, 0x2B, 0x3F, 0x48, 0x48, 0x8B, 0x48, + 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x24, 0x22, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x23, 0x21, 0x20, 0x20, 0x20, 0x21, 0x22, + 0x24, 0x23, 0x22, 0x21, 0x2B, 0x20, 0x54, 0x27, + 0x27, 0x8B, 0x81, 0xA5, 0x93, 0x93, 0x74, 0xA5, + 0xBA, 0x75, 0xBB, 0xBC, 0xB4, 0x6D, 0x50, 0x6B, + 0x27, 0x27, 0x30, 0x33, 0x49, 0x27, 0x27, 0x5E, + 0x6F, 0x73, 0x94, 0xBD, 0x4E, 0x5D, 0x7F, 0x7F, + 0xB7, 0x68, 0x73, 0x6E, 0xB7, 0x7F, 0x95, 0x97, + 0x47, 0x63, 0x25, 0x20, 0x3F, 0x48, 0x8B, 0x8B, + 0x48, 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x25, + 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x21, + 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, + 0x22, 0x21, 0x20, 0x2A, 0x33, 0x30, 0x30, 0x27, + 0x27, 0x50, 0xBE, 0xBF, 0x9A, 0xB3, 0x9B, 0xBB, + 0xBB, 0xC0, 0x8C, 0xC1, 0x8B, 0xC2, 0x47, 0x8B, + 0x27, 0x27, 0x38, 0x63, 0x63, 0x27, 0x27, 0xC3, + 0xB5, 0x95, 0x72, 0x95, 0x6F, 0x69, 0x7E, 0x66, + 0x7E, 0x7F, 0x6E, 0x7E, 0x95, 0x95, 0x73, 0x70, + 0x30, 0x30, 0x30, 0x33, 0x20, 0x3F, 0x48, 0x8B, + 0x6B, 0x48, 0x50, 0x29, 0x21, 0x33, 0x54, 0x33, + 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x21, 0x21, 0x23, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, 0x22, + 0x20, 0x2B, 0x21, 0xC4, 0x30, 0x60, 0x30, 0x27, + 0x27, 0xC5, 0x8B, 0x39, 0xC6, 0xC7, 0xA6, 0xA6, + 0xC8, 0x9A, 0x3B, 0x39, 0x50, 0x56, 0x56, 0x4F, + 0x33, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x48, + 0x59, 0x94, 0x73, 0xAE, 0xB7, 0xB7, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x5A, 0x70, 0x7C, 0x71, 0xC3, + 0x63, 0x30, 0x60, 0x78, 0x54, 0x20, 0x6B, 0x48, + 0x6B, 0x6B, 0x50, 0x50, 0x29, 0x22, 0x33, 0x33, + 0x2A, 0x2B, 0x20, 0x20, 0x21, 0x22, 0x22, 0x22, + 0x21, 0x20, 0x20, 0x20, 0x24, 0x24, 0x20, 0x20, + 0x2B, 0x24, 0x30, 0x60, 0x60, 0x30, 0xAB, 0x27, + 0x27, 0x40, 0x4C, 0x50, 0x39, 0x87, 0xC3, 0x53, + 0x37, 0x48, 0x37, 0x48, 0xC9, 0x56, 0xB9, 0x56, + 0xCA, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x3C, + 0x51, 0x5A, 0x6E, 0xB7, 0xB7, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7F, 0xB7, 0x5A, 0x7C, 0x5B, 0x37, + 0x23, 0x63, 0x31, 0x6C, 0xCB, 0x63, 0x20, 0x6B, + 0x50, 0x3F, 0x39, 0x50, 0x8B, 0x28, 0x24, 0x24, + 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x22, 0x22, 0x21, + 0x20, 0x20, 0x20, 0x23, 0x23, 0x20, 0x20, 0x2B, + 0x33, 0x78, 0xCB, 0x60, 0x30, 0x22, 0x3D, 0x27, + 0x2F, 0x56, 0x4E, 0x8B, 0x6B, 0x39, 0x48, 0x8B, + 0x6B, 0x8B, 0x80, 0xC9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x34, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x48, 0xB5, 0xB7, 0xB7, 0x7E, 0x7E, 0x2E, 0x7E, + 0x7E, 0x7E, 0x7F, 0x7C, 0x65, 0x71, 0x3A, 0x48, + 0x2C, 0x24, 0x30, 0x6C, 0x34, 0x6C, 0xC4, 0x20, + 0x8B, 0x50, 0x39, 0x39, 0x48, 0x6B, 0x2B, 0x22, + 0x2B, 0x20, 0x21, 0x22, 0x23, 0x23, 0x22, 0x21, + 0x20, 0x2B, 0x23, 0x22, 0x20, 0x2B, 0x2B, 0x54, + 0x60, 0x31, 0xCB, 0x54, 0x20, 0x3D, 0x36, 0x27, + 0x4E, 0xB9, 0x56, 0x56, 0x8B, 0x6B, 0x50, 0x6B, + 0x40, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x56, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x7B, 0x6E, 0xB7, 0xB7, 0xB7, 0x7E, 0x7F, + 0xB7, 0xB7, 0x7F, 0x7E, 0x6F, 0x5B, 0x29, 0x2C, + 0x48, 0x39, 0x24, 0x60, 0x58, 0xAF, 0xCC, 0x63, + 0x20, 0x8B, 0x8B, 0x39, 0x39, 0x48, 0x3F, 0x28, + 0x20, 0x20, 0x22, 0x23, 0x23, 0x23, 0x22, 0x20, + 0x2B, 0x22, 0x22, 0x2B, 0x2B, 0x20, 0x54, 0xCB, + 0x31, 0xCB, 0x25, 0x20, 0x27, 0x27, 0x27, 0x48, + 0xB9, 0x56, 0xB9, 0x56, 0x4F, 0x48, 0x47, 0x57, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0x62, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x48, 0x6F, 0x69, 0xB7, 0xB7, 0xB7, 0x7F, + 0xB7, 0xB7, 0xB7, 0x73, 0x59, 0x50, 0x29, 0x2B, + 0x28, 0x8B, 0x39, 0x25, 0x31, 0x55, 0xB6, 0x34, + 0x63, 0x2B, 0x48, 0x6B, 0x2C, 0x39, 0x47, 0x6B, + 0x22, 0x22, 0x23, 0x24, 0x23, 0x22, 0x20, 0x2B, + 0x20, 0x22, 0x2A, 0x2B, 0x20, 0x33, 0xCB, 0x31, + 0x78, 0x24, 0x21, 0xCD, 0x27, 0x27, 0x27, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0xC9, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x41, 0x64, 0xB7, 0xB7, 0xB7, 0x7F, + 0x68, 0xB7, 0xAE, 0xA3, 0x23, 0x39, 0x8B, 0x2A, + 0x20, 0x20, 0x39, 0x6B, 0x25, 0xCC, 0x43, 0x43, + 0x34, 0x63, 0x2A, 0x48, 0x3F, 0x39, 0x6B, 0x6B, + 0x24, 0x23, 0x24, 0x24, 0x23, 0x21, 0x2B, 0x2B, + 0x22, 0x2B, 0x2B, 0x20, 0x24, 0x78, 0x31, 0x30, + 0x23, 0x21, 0x21, 0x27, 0x27, 0x27, 0x80, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x3C, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xCE, 0x8A, 0xAE, 0x6F, 0xB7, + 0x6F, 0x89, 0x71, 0x78, 0x63, 0x23, 0x39, 0x6B, + 0x2B, 0x20, 0x20, 0x2C, 0x6B, 0x25, 0x34, 0x42, + 0x42, 0x34, 0x54, 0x29, 0x48, 0x3F, 0x39, 0x3F, + 0x25, 0x24, 0x25, 0x24, 0x22, 0x20, 0x2A, 0x21, + 0x2B, 0x2A, 0x20, 0x22, 0x30, 0x60, 0x30, 0x22, + 0x21, 0x22, 0x27, 0x27, 0x27, 0x2D, 0x4C, 0x56, + 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0x56, 0x2E, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x40, 0x97, 0x95, 0x5A, 0x71, + 0x7C, 0xCE, 0x40, 0x60, 0x31, 0x30, 0x23, 0x3F, + 0x3F, 0x20, 0x20, 0x20, 0x29, 0x8B, 0x33, 0x58, + 0x66, 0x43, 0xCC, 0x25, 0x39, 0x50, 0x6B, 0x2C, + 0x33, 0x25, 0x25, 0x23, 0x20, 0x2A, 0x2B, 0x20, + 0x2A, 0x2B, 0x22, 0x54, 0x30, 0x30, 0x24, 0x22, + 0x21, 0x27, 0x27, 0x27, 0x27, 0xAF, 0x29, 0x4E, + 0x4F, 0xB9, 0x56, 0xB9, 0x4D, 0x4D, 0x77, 0xC9, + 0xB9, 0xB9, 0xB9, 0x56, 0xC9, 0x4D, 0x4D, 0x80, + 0x4C, 0x40, 0xC9, 0x4D, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0xCF, 0x97, 0x97, 0xCE, + 0x86, 0xD0, 0x54, 0x6C, 0x58, 0x34, 0x60, 0x23, + 0x6B, 0x39, 0x20, 0x20, 0x20, 0x28, 0x6B, 0x54, + 0xD1, 0x66, 0xB6, 0x60, 0x22, 0x6B, 0x8B, 0x2C, + 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, 0x20, 0x28, + 0x2B, 0x20, 0x25, 0xC4, 0x30, 0x25, 0x22, 0x21, + 0x26, 0x27, 0x27, 0x27, 0x27, 0x20, 0x4B, 0x52, + 0x80, 0x4F, 0xB9, 0x56, 0xB9, 0x80, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x4D, 0x80, 0x50, 0x48, + 0x50, 0x50, 0x50, 0x56, 0x3D, 0x27, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x3C, 0x46, 0xC3, 0x86, 0x86, + 0xD0, 0x39, 0x24, 0x6C, 0xD1, 0x43, 0x43, 0x6C, + 0x24, 0x6B, 0x2C, 0x20, 0x20, 0x20, 0x29, 0x39, + 0x63, 0xD1, 0x42, 0x55, 0xC4, 0x2B, 0x8B, 0x39, + 0x54, 0x25, 0x24, 0x20, 0x2A, 0x2A, 0x28, 0x28, + 0x20, 0x22, 0x54, 0x63, 0x25, 0x24, 0x22, 0x22, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x77, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xC9, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x4F, + 0x77, 0x47, 0x8B, 0x40, 0x56, 0x27, 0x27, 0x49, + 0x2D, 0x27, 0x27, 0x27, 0x39, 0x40, 0x39, 0x39, + 0x28, 0x3F, 0x39, 0x33, 0x58, 0x66, 0x35, 0x2E, + 0x58, 0x24, 0x8B, 0x29, 0x20, 0x20, 0x20, 0x39, + 0x29, 0x30, 0x55, 0xB6, 0xCC, 0x25, 0x29, 0x39, + 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2A, 0x29, 0x2B, + 0x22, 0x24, 0x54, 0x33, 0x25, 0x22, 0x2B, 0x54, + 0x27, 0x27, 0x62, 0x27, 0x30, 0x80, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4D, 0x8B, 0x77, 0x36, 0x27, 0x27, + 0x3C, 0x2F, 0x27, 0x27, 0x39, 0x39, 0x39, 0x47, + 0x20, 0x2B, 0x2C, 0x39, 0x33, 0xB6, 0x35, 0x35, + 0x35, 0xAF, 0x24, 0x48, 0x2A, 0x20, 0x20, 0x20, + 0x8B, 0x2B, 0x78, 0xAF, 0x58, 0x30, 0x21, 0x28, + 0x33, 0x25, 0x21, 0x28, 0x29, 0x29, 0x28, 0x20, + 0x24, 0x33, 0x54, 0x33, 0x23, 0x20, 0x24, 0xD2, + 0x27, 0x49, 0x27, 0x27, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0xC9, 0x50, 0x56, 0x27, 0x27, + 0x3D, 0x38, 0x3D, 0x27, 0x27, 0x47, 0x39, 0x39, + 0x28, 0x20, 0x20, 0x2A, 0x39, 0x54, 0x43, 0x35, + 0x35, 0x35, 0xAF, 0x23, 0x48, 0x2B, 0x20, 0x20, + 0x2B, 0x48, 0x22, 0x60, 0x34, 0xCB, 0x25, 0x21, + 0x33, 0x24, 0x2B, 0x29, 0x29, 0x29, 0x2B, 0x22, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x33, 0x27, + 0x27, 0x32, 0x27, 0x30, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0xC9, 0x4C, 0x36, 0x3C, + 0x62, 0x2F, 0x2E, 0x27, 0x27, 0x54, 0x47, 0x47, + 0x8B, 0x2B, 0x20, 0x20, 0x20, 0x3F, 0x54, 0x2E, + 0x35, 0x35, 0x35, 0x34, 0x21, 0x8B, 0x2A, 0x20, + 0x20, 0x2C, 0x6B, 0x25, 0x60, 0x60, 0x54, 0x23, + 0x25, 0x22, 0x2A, 0x2C, 0x29, 0x28, 0x20, 0x24, + 0x54, 0x63, 0x54, 0x24, 0x2B, 0x22, 0x24, 0x27, + 0x36, 0x27, 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x4C, 0x36, + 0x66, 0xD3, 0x27, 0x2F, 0x27, 0x54, 0x54, 0x27, + 0x26, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x63, + 0x35, 0x35, 0x35, 0x62, 0xCB, 0x2A, 0x3F, 0x28, + 0x2B, 0x2A, 0x50, 0x29, 0x33, 0x30, 0x54, 0x25, + 0x24, 0x20, 0x29, 0x2C, 0x2C, 0x2A, 0x21, 0x33, + 0xC4, 0xC4, 0x33, 0x21, 0x29, 0x22, 0x27, 0x27, + 0x99, 0x27, 0x31, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x3D, + 0x3D, 0x3C, 0x3C, 0x55, 0x54, 0x54, 0x54, 0x20, + 0x27, 0x2C, 0x39, 0x20, 0x20, 0x20, 0x20, 0x48, + 0x30, 0x62, 0x35, 0x35, 0x42, 0x54, 0x39, 0x39, + 0x2C, 0x28, 0x3F, 0x8B, 0x20, 0x33, 0x54, 0x24, + 0x22, 0x2B, 0x2C, 0x2C, 0x2C, 0x2B, 0x24, 0x54, + 0x30, 0xC4, 0x25, 0x2B, 0x28, 0x2B, 0x27, 0x3D, + 0x27, 0x27, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x27, + 0x20, 0x20, 0x20, 0x54, 0x54, 0x54, 0x54, 0x20, + 0x20, 0x2D, 0x2D, 0x29, 0x20, 0x20, 0x20, 0x20, + 0x48, 0x60, 0x66, 0x35, 0x62, 0x34, 0x22, 0x2C, + 0x2C, 0x3F, 0x6B, 0x48, 0x2C, 0x22, 0x23, 0x23, + 0x20, 0x2A, 0x2C, 0x29, 0x29, 0x20, 0x25, 0xC4, + 0x30, 0x54, 0x22, 0x29, 0x28, 0xD2, 0x27, 0x35, + 0x27, 0x49, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x4F, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x40, 0x20, + 0x20, 0x54, 0x54, 0x54, 0x20, 0x20, 0x20, 0x20, + 0x2D, 0x2D, 0x2D, 0x49, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6B, 0x6C, 0x42, 0x2E, 0xB6, 0x54, 0x28, + 0x29, 0x2C, 0x6B, 0x48, 0x3F, 0x2A, 0x20, 0x22, + 0x2B, 0x28, 0x2C, 0x28, 0x29, 0x20, 0x33, 0x30, + 0x30, 0x54, 0x20, 0x2C, 0x29, 0x27, 0x27, 0x3D, + 0x27, 0x40, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x63, 0x56, 0x54, 0x54, + 0x54, 0x54, 0x20, 0xD3, 0x45, 0x51, 0x51, 0x49, + 0x7C, 0x2D, 0x2D, 0x49, 0x49, 0x20, 0x20, 0x20, + 0x20, 0x2A, 0x2A, 0xCC, 0xB6, 0x8A, 0x60, 0x22, + 0x28, 0x29, 0x3F, 0x6B, 0x39, 0x29, 0x2B, 0x20, + 0x28, 0x2C, 0x28, 0x2A, 0x2A, 0x24, 0xC4, 0x30, + 0xC4, 0x33, 0x2B, 0x39, 0xCD, 0x27, 0x3C, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x63, 0x63, 0x49, 0x2D, 0x20, + 0x20, 0x2D, 0xD3, 0x49, 0x66, 0x2D, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x49, 0x8B, 0x2B, 0x20, + 0x20, 0x20, 0x39, 0x23, 0x6C, 0xAF, 0xCB, 0x23, + 0x28, 0x28, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x20, + 0x29, 0x39, 0x2B, 0x2B, 0x2B, 0x25, 0x78, 0xC4, + 0x63, 0x23, 0x29, 0x39, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x49, 0x2D, 0x49, 0x2D, 0x49, 0x2D, 0x2D, 0x2D, + 0x49, 0x49, 0x35, 0x49, 0x2D, 0x2D, 0x39, 0x28, + 0x20, 0x20, 0x2A, 0x28, 0x33, 0x60, 0xC4, 0x22, + 0x2C, 0x2A, 0x2A, 0x22, 0x23, 0x22, 0x20, 0x21, + 0x2C, 0x29, 0x20, 0x2B, 0x2B, 0x54, 0x30, 0xC4, + 0x63, 0x22, 0x2C, 0x27, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x61, 0x49, 0x2D, 0x49, 0x49, 0x2D, 0x2D, 0x49, + 0x49, 0x49, 0x2F, 0x49, 0x2D, 0x78, 0x29, 0x28, + 0x2C, 0x2A, 0x2B, 0x39, 0x2B, 0x25, 0x33, 0x20, + 0x2C, 0x20, 0x2A, 0x24, 0x54, 0x54, 0x23, 0x23, + 0x2C, 0x2A, 0x22, 0x2B, 0x20, 0x63, 0x30, 0x63, + 0xC4, 0x21, 0x39, 0x27, 0x27, 0x27, 0x35, 0x36, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x2D, 0x49, 0x49, 0x49, + 0x49, 0x27, 0x27, 0x2D, 0x38, 0x27, 0x36, 0x36, + 0x49, 0x27, 0x49, 0x2D, 0x2D, 0x44, 0x24, 0x2B, + 0x20, 0x2C, 0x3F, 0x6B, 0x2A, 0x20, 0x21, 0x28, + 0x2C, 0x20, 0x2B, 0x24, 0x30, 0xCB, 0x63, 0x54, + 0x28, 0x20, 0x24, 0x2B, 0x23, 0x78, 0xC4, 0x63, + 0x63, 0x2B, 0x3F, 0x27, 0x27, 0x27, 0x38, 0x33, + 0x3D, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x63, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x3D, 0x3D, 0x27, 0x27, 0x27, 0x2D, + 0x49, 0x49, 0x49, 0x2D, 0x62, 0x5F, 0xC4, 0x20, + 0x22, 0x2A, 0x6B, 0x8B, 0x2C, 0x2B, 0x2A, 0x3F, + 0x3F, 0x2A, 0x21, 0x21, 0xCB, 0x58, 0x6C, 0x60, + 0x20, 0x23, 0x24, 0x2A, 0x25, 0x78, 0x63, 0x63, + 0x54, 0x2A, 0x28, 0x27, 0x27, 0x27, 0x27, 0x62, + 0x3C, 0xB9, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x49, 0x2D, 0x2D, + 0x2D, 0x3D, 0x2F, 0x3C, 0x2D, 0x3C, 0x27, 0x38, + 0x2D, 0x49, 0x2D, 0x2D, 0xD1, 0x43, 0x30, 0x20, + 0x24, 0x21, 0x21, 0x21, 0x2B, 0x2A, 0x29, 0x8B, + 0x6B, 0x29, 0x2B, 0x2A, 0x30, 0x55, 0x55, 0x34, + 0x22, 0x23, 0x24, 0x29, 0x54, 0x30, 0x63, 0x63, + 0x25, 0x29, 0x22, 0x3C, 0xA5, 0xD4, 0xD5, 0x27, + 0x31, 0x56, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x2D, 0x2E, + 0x3E, 0x27, 0x27, 0x27, 0x27, 0x27, 0x36, 0x44, + 0x3C, 0x27, 0x2D, 0xC4, 0x78, 0xCC, 0x54, 0x2B, + 0x25, 0x24, 0x63, 0x60, 0x63, 0x24, 0x2A, 0x6B, + 0x3F, 0x39, 0x28, 0x21, 0x33, 0xB6, 0x44, 0x58, + 0x22, 0x23, 0x24, 0x2A, 0x30, 0x30, 0x63, 0x63, + 0x24, 0x39, 0x22, 0xBB, 0x9C, 0xB2, 0x9D, 0xA8, + 0x27, 0x8B, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0xD6, 0xD6, 0xD7, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x32, + 0x3D, 0x27, 0x39, 0x33, 0xC4, 0xC4, 0x22, 0x28, + 0x25, 0x54, 0x30, 0xD1, 0xD1, 0x60, 0x23, 0x6B, + 0x3F, 0x39, 0x2C, 0x2B, 0x20, 0x58, 0x8A, 0x58, + 0x22, 0x23, 0x23, 0x2B, 0x78, 0x30, 0xC4, 0xC4, + 0x23, 0x29, 0xBB, 0xBB, 0xD8, 0xB2, 0x9D, 0xA9, + 0xA9, 0x3C, 0x60, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xD9, 0x85, 0x85, 0x85, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2D, + 0xA0, 0x83, 0x2C, 0x21, 0x30, 0x33, 0x29, 0x29, + 0x21, 0x33, 0x54, 0x42, 0x66, 0x55, 0xC4, 0x29, + 0x8B, 0x2C, 0x39, 0x28, 0x29, 0x31, 0x44, 0x58, + 0x23, 0x23, 0x21, 0x20, 0x30, 0xC4, 0xC4, 0x30, + 0x21, 0x20, 0xBB, 0xBC, 0xDA, 0xDB, 0xDC, 0xB2, + 0x83, 0xB4, 0x3C, 0x2F, 0xB9, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0xA7, 0xD4, 0x85, 0x82, + 0x3C, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x61, + 0x9E, 0x90, 0xDD, 0x21, 0x33, 0x25, 0x2C, 0x39, + 0x2A, 0x24, 0x24, 0x42, 0x62, 0x43, 0x34, 0x22, + 0x50, 0x39, 0x2C, 0x2C, 0x2A, 0x54, 0xD1, 0x58, + 0x22, 0x22, 0x2B, 0x22, 0x30, 0xC4, 0x30, 0x60, + 0x20, 0xDE, 0xBB, 0xD9, 0x84, 0x84, 0xDF, 0xA9, + 0xDB, 0xDB, 0x61, 0x27, 0x38, 0x4D, 0x56, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0x8D, 0xD9, 0xD5, 0xA6, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0xBB, + 0x85, 0xDB, 0xDD, 0x21, 0x22, 0x22, 0x3F, 0x39, + 0x2C, 0x2B, 0x25, 0x34, 0x62, 0x66, 0xD1, 0xC4, + 0x6B, 0x39, 0x2C, 0x39, 0x29, 0x21, 0x58, 0xCC, + 0x22, 0x21, 0x29, 0x23, 0x30, 0x30, 0x30, 0x5E, + 0x82, 0xBB, 0xE0, 0xB1, 0xE1, 0x9C, 0xD4, 0xDC, + 0x9D, 0xA9, 0xE2, 0x27, 0x27, 0x27, 0x4D, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4C, 0x48, 0xA8, 0xA8, 0xE3, 0x8C, + 0xC6, 0x3C, 0x27, 0x27, 0x27, 0xE4, 0xA6, 0xE5, + 0x83, 0xA9, 0xE6, 0xAF, 0x54, 0x2B, 0x8B, 0x39, + 0x39, 0x29, 0x20, 0x54, 0x42, 0x42, 0xB6, 0xCC, + 0x2A, 0x29, 0x39, 0x39, 0x2C, 0x2C, 0xCC, 0xCC, + 0x22, 0x20, 0x39, 0xE7, 0xC0, 0xD9, 0xA7, 0xBC, + 0x8D, 0xAA, 0x9C, 0xE8, 0x9C, 0x9D, 0xD4, 0xD4, + 0xD8, 0xA9, 0x84, 0xC7, 0x27, 0x27, 0x27, 0x2A, + 0x56, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x48, 0x50, 0xAA, 0xE3, 0xE3, 0xC0, + 0xA6, 0x9A, 0xBA, 0xC8, 0x9A, 0xDE, 0x9B, 0xD5, + 0xE8, 0xD8, 0xD5, 0x2E, 0x58, 0x33, 0x6B, 0x39, + 0x2C, 0x39, 0x29, 0x28, 0xD1, 0x43, 0xB6, 0xAF, + 0x23, 0x28, 0x2C, 0x39, 0x39, 0x8B, 0x30, 0x31, + 0x21, 0x20, 0x3F, 0xBB, 0xDF, 0xDF, 0xD5, 0xA8, + 0xD5, 0x9C, 0x8E, 0xB2, 0x9D, 0xE9, 0xD4, 0xD8, + 0x90, 0xB2, 0xA9, 0x8F, 0x27, 0x27, 0x27, 0x27, + 0x2F, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0xB9, 0x48, 0x48, 0x75, 0xE3, 0xAA, 0xAA, + 0xC0, 0xB4, 0xB4, 0xB4, 0x75, 0x9B, 0xD9, 0x83, + 0x9D, 0x90, 0xDF, 0xDD, 0x8A, 0x31, 0x4B, 0x2C, + 0x2C, 0x29, 0x2C, 0x3F, 0x6C, 0x55, 0xD1, 0x55, + 0x54, 0x29, 0x28, 0x39, 0x39, 0x6B, 0x24, 0x60, + 0x20, 0x2B, 0x3F, 0xA7, 0xB1, 0x9D, 0xA9, 0x8E, + 0xE5, 0xE5, 0xDF, 0xE0, 0xA9, 0x9D, 0xDF, 0xDF, + 0xEA, 0x9D, 0xB2, 0x84, 0xAA, 0x27, 0x27, 0x27, + 0x27, 0x35, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x48, 0x48, 0xA6, 0x9B, 0xE3, 0xAA, + 0xAA, 0x9B, 0x9B, 0x9B, 0xAA, 0xE3, 0xD5, 0xD4, + 0x9D, 0xA9, 0xA9, 0x9D, 0xEB, 0xAF, 0x23, 0x28, + 0x2C, 0x29, 0x28, 0x39, 0x54, 0xCC, 0xAF, 0x55, + 0x30, 0x29, 0x2B, 0x2C, 0x39, 0x39, 0x2B, 0xC4, + 0x2B, 0x29, 0x39, 0xA7, 0x8E, 0x9D, 0x83, 0xE5, + 0xB1, 0xDB, 0xDC, 0xE0, 0xDC, 0x84, 0xE9, 0x84, + 0x83, 0xD4, 0xEC, 0x83, 0x8F, 0xE4, 0x27, 0x27, + 0x27, 0x27, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x40, 0x50, 0x9A, 0x75, 0xE3, 0xE3, + 0xE3, 0xD9, 0x8D, 0xAA, 0xD9, 0xA8, 0xB2, 0xDC, + 0xB2, 0x8D, 0x84, 0xEA, 0xB1, 0xEB, 0x54, 0x29, + 0x28, 0x2C, 0x2A, 0x28, 0x2B, 0x78, 0xCC, 0x58, + 0xCB, 0x20, 0x20, 0x29, 0x39, 0x39, 0x2C, 0x25, + 0x29, 0x2C, 0x39, 0xBB, 0xD9, 0xD9, 0x9D, 0x9D, + 0xB2, 0xB1, 0xD4, 0xDB, 0xB1, 0x9D, 0xD4, 0xEA, + 0xB1, 0x8D, 0xD8, 0x8E, 0x8F, 0xAA, 0x27, 0x27, + 0x27, 0x3D, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x47, 0xE4, 0xA6, 0x75, 0xAA, 0xA8, + 0x9C, 0x9C, 0xE1, 0x9C, 0x9C, 0x8E, 0xD8, 0x9D, + 0xA9, 0xDB, 0xA9, 0xDC, 0xD8, 0xDA, 0xD4, 0x2B, + 0x20, 0x2C, 0x28, 0x2A, 0x28, 0x63, 0x31, 0x58, + 0xCB, 0x24, 0x20, 0x2B, 0x2C, 0x39, 0x6B, 0x21, + 0x39, 0x6B, 0x2C, 0xC0, 0xE0, 0xB1, 0xB2, 0x9D, + 0x8E, 0xD8, 0xE0, 0xD9, 0x84, 0xDB, 0xD8, 0xB1, + 0x8E, 0xB2, 0xE2, 0x9C, 0x83, 0x9E, 0xBC, 0x3D, + 0xD3, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0x4F, 0x27, 0x61, 0xA6, 0x9B, 0xE3, 0xA9, + 0xE9, 0xD4, 0xDA, 0xDB, 0x8E, 0xE1, 0xE9, 0x8E, + 0xD4, 0xA8, 0xE0, 0x84, 0xE8, 0xB1, 0xDC, 0x9D, + 0x20, 0x29, 0x29, 0x2B, 0x2C, 0x54, 0x78, 0xCC, + 0x78, 0x33, 0x2A, 0x20, 0x29, 0x39, 0x50, 0x2A, + 0x6B, 0x8B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xA9, + 0xB2, 0xDC, 0x8E, 0xDC, 0xE1, 0xDA, 0xA9, 0x8E, + 0xEA, 0xE2, 0x83, 0xE8, 0x8E, 0x83, 0xE2, 0xED, + 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0xC9, 0x27, 0x27, 0xE4, 0xA6, 0x9B, 0xD5, 0xA8, + 0xD4, 0xB2, 0xD8, 0xDA, 0xD9, 0xE8, 0xE9, 0xE8, + 0xD8, 0xB1, 0xDA, 0xB2, 0xE9, 0x8E, 0xEC, 0xDA, + 0x22, 0x20, 0x39, 0x2B, 0x39, 0x24, 0xC4, 0x30, + 0x30, 0x54, 0x22, 0x29, 0x29, 0x39, 0x48, 0x2C, + 0x39, 0x6B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xB2, + 0xB2, 0x8E, 0xA9, 0xD8, 0xDA, 0xB1, 0xA9, 0xDA, + 0x9C, 0xDC, 0x8E, 0xD4, 0xE8, 0xE8, 0x8F, 0x9B, + 0x4F, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x6B, + 0x27, 0x27, 0x27, 0xD7, 0xDE, 0xAA, 0xE3, 0xA8, + 0xB2, 0xD5, 0xE5, 0x90, 0xE2, 0xA9, 0xE9, 0xB2, + 0xDA, 0xB2, 0xE1, 0xB2, 0xE9, 0x8E, 0xDA, 0xDF, + 0x78, 0x2A, 0x2C, 0x2A, 0x6B, 0x28, 0x23, 0x54, + 0x63, 0xC4, 0x33, 0x28, 0x2C, 0x39, 0x47, 0x39, + 0x28, 0x2C, 0x29, 0xBB, 0x8D, 0x83, 0xE9, 0xD4, + 0xB2, 0xE9, 0xE9, 0xE8, 0xD4, 0xD8, 0xD4, 0xA9, + 0xDA, 0xB2, 0xE9, 0xA8, 0xB2, 0xA8, 0xD5, 0xAA, + 0xC6, 0x56, 0x56, 0x56, 0x56, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0xC9, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0x9B, 0xE3, 0x8E, + 0x9D, 0x8E, 0xB2, 0xE8, 0xE8, 0x8E, 0xB2, 0xDA, + 0xB2, 0x8E, 0xEC, 0xB2, 0x8E, 0xB2, 0xBB, 0x58, + 0xAF, 0x33, 0x50, 0x39, 0x6B, 0x39, 0x29, 0x20, + 0x33, 0x30, 0x78, 0x23, 0x6B, 0x6B, 0x48, 0x6B, + 0x2B, 0x2A, 0x29, 0xBB, 0xE5, 0x9C, 0xB1, 0xB2, + 0xE5, 0x84, 0x8E, 0x9C, 0x84, 0xB2, 0xB2, 0x9D, + 0x84, 0xDF, 0xA9, 0x84, 0x8E, 0xA8, 0xE3, 0x9B, + 0xA6, 0xD7, 0x80, 0x4F, 0x56, 0x56, 0x56, 0x4F, + 0x4F, 0x4F, 0x4F, 0x2A, 0x2D, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0xAA, 0xD5, 0xA9, + 0x9D, 0xB2, 0x90, 0xEA, 0xE9, 0xE2, 0xE1, 0x8E, + 0xB2, 0x9D, 0x8E, 0xB1, 0xA7, 0xEE, 0x63, 0xD1, + 0x2E, 0xCC, 0x28, 0x48, 0x8B, 0x47, 0x6B, 0x28, + 0x23, 0x78, 0x6C, 0x54, 0x29, 0x50, 0x50, 0x6B, + 0x23, 0x20, 0xBB, 0xBC, 0xBB, 0x8D, 0xE3, 0xDF, + 0x9C, 0xA9, 0x8D, 0xA8, 0xD9, 0x90, 0x9D, 0xA9, + 0xDC, 0xA9, 0x83, 0xB2, 0xA9, 0xD4, 0xE3, 0x9B, + 0x8C, 0xEF, 0x27, 0x27, 0x27, 0x3C, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0x84, + 0x9D, 0x84, 0x90, 0xB1, 0xA9, 0x9C, 0xD9, 0xB1, + 0xB2, 0xEA, 0xBB, 0x51, 0x24, 0x30, 0x30, 0x42, + 0x66, 0x58, 0x24, 0x48, 0x50, 0x3F, 0x20, 0x25, + 0x22, 0x60, 0x34, 0x30, 0x20, 0x8B, 0x8B, 0x39, + 0x54, 0x24, 0x2B, 0xC0, 0xC0, 0xC0, 0xBB, 0x9B, + 0xBC, 0xAA, 0xAA, 0xE3, 0xE3, 0x9C, 0xB2, 0xD4, + 0x83, 0xD8, 0xE8, 0x83, 0x84, 0xE8, 0xE5, 0x75, + 0x9A, 0xF0, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0xA8, + 0xA9, 0xD8, 0x8E, 0xEA, 0xA8, 0x9C, 0xD9, 0xE0, + 0xC0, 0x5E, 0x2C, 0x20, 0x54, 0x60, 0x30, 0x66, + 0xB6, 0xCC, 0x63, 0x3F, 0x8B, 0x28, 0x22, 0x33, + 0x23, 0x31, 0xAF, 0x31, 0x22, 0x6B, 0x6B, 0x29, + 0x30, 0x54, 0x22, 0x89, 0xBA, 0xED, 0xA6, 0x8C, + 0xB4, 0xC0, 0xB4, 0x75, 0x75, 0x9B, 0x9B, 0xE5, + 0xA9, 0xD5, 0x8E, 0x8E, 0x9C, 0xE3, 0x75, 0x8C, + 0xC8, 0xF1, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF1, 0x9A, 0xB4, 0x9B, 0xE3, + 0xE3, 0xA8, 0xE3, 0xE5, 0xAA, 0xBC, 0xC0, 0x9A, + 0x26, 0x29, 0x20, 0x24, 0x63, 0x60, 0x54, 0x43, + 0x34, 0xCB, 0x30, 0x39, 0x2C, 0x20, 0x24, 0x54, + 0x22, 0x34, 0x34, 0x31, 0x24, 0x3F, 0x2C, 0x2B, + 0x31, 0x30, 0x25, 0x2A, 0x6B, 0x29, 0x20, 0xF2, + 0xBA, 0xBF, 0xC8, 0x9A, 0xA6, 0xA6, 0x8C, 0xB4, + 0x9B, 0xAA, 0xAA, 0xAA, 0x9B, 0x75, 0xDE, 0xBF, + 0x81, 0xEF, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xEF, 0xBA, 0x9A, 0xB4, 0x75, + 0x9B, 0x9B, 0x9B, 0xC0, 0xB4, 0x9A, 0xA5, 0xC4, + 0x30, 0x28, 0x22, 0x33, 0x30, 0x30, 0x23, 0x34, + 0x31, 0x30, 0xC4, 0x2C, 0x2B, 0x22, 0x33, 0x63, + 0x21, 0x58, 0x6C, 0x60, 0x25, 0x39, 0x28, 0x2B, + 0xCC, 0x6C, 0x63, 0x20, 0x6B, 0x28, 0x2B, 0x20, + 0x63, 0x43, 0xF3, 0xEF, 0xF0, 0x81, 0xBA, 0xF4, + 0xF4, 0xA6, 0xDE, 0x8C, 0xA6, 0x9A, 0xBA, 0x81, + 0xB0, 0xE4, 0xA1, 0x20, 0x20, 0x23, 0x31, 0xC4, + 0x30, 0x24, 0x33, 0x31, 0x31, 0x60, 0x43, 0x35, + 0x35, 0x55, 0x6C, 0xEF, 0x81, 0xC8, 0x9A, 0xA6, + 0xB4, 0xB4, 0x8C, 0xA6, 0xBA, 0x68, 0x30, 0x30, + 0x30, 0x2B, 0x25, 0x54, 0xC4, 0x54, 0x24, 0x78, + 0x63, 0x63, 0x30, 0x29, 0x21, 0x24, 0x54, 0x63, + 0x23, 0x34, 0xCB, 0x30, 0x25, 0x39, 0x20, 0x20, + 0x58, 0x34, 0x60, 0x23, 0x6B, 0x29, 0x28, 0x20, + 0x22, 0xB6, 0x42, 0xB6, 0x58, 0x54, 0xF5, 0xD7, + 0xA5, 0xBA, 0xBA, 0xBA, 0xBA, 0x81, 0xA5, 0xF1, + 0xE4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x31, 0x60, + 0x54, 0x28, 0x2B, 0x22, 0x33, 0x30, 0x43, 0x35, + 0x66, 0xD1, 0x34, 0xE4, 0xEF, 0x81, 0xC8, 0x9A, + 0x9A, 0xC8, 0xC8, 0x81, 0xF6, 0x31, 0x63, 0x31, + 0x78, 0x2B, 0x54, 0x63, 0x54, 0x24, 0x23, 0x54, + 0x63, 0x54, 0x63, 0x2C, 0x23, 0x33, 0x63, 0x54, + 0x25, 0x31, 0x78, 0x30, 0x25, 0x3F, 0x20, 0x20, + 0xAF, 0x58, 0xCC, 0x33, 0x39, 0x29, 0x29, 0x2A, + 0x29, 0x58, 0x43, 0x42, 0xD1, 0xCB, 0x2C, 0x2C, + 0x37, 0xCD, 0xEF, 0xB0, 0xF0, 0xB0, 0xEF, 0xE4, + 0x63, 0x20, 0x20, 0x2C, 0x2C, 0x21, 0xCB, 0x78, + 0x54, 0x39, 0x39, 0x28, 0x2B, 0x28, 0x2B, 0xCB, + 0x55, 0xB6, 0xD1, 0x28, 0xE4, 0xD7, 0xB8, 0xF0, + 0xA5, 0xB0, 0xEF, 0x26, 0x23, 0x54, 0x31, 0x58, + 0xCB, 0x20, 0x63, 0x63, 0x25, 0x2B, 0x54, 0x78, + 0x30, 0x63, 0x54, 0x28, 0x33, 0x63, 0x63, 0x33, + 0x54, 0x78, 0xC4, 0x30, 0x24, 0x2C, 0x22, 0x22, + 0x55, 0x55, 0x34, 0x30, 0x28, 0x2C, 0x29, 0x29, + 0x28, 0x30, 0xB6, 0x42, 0x43, 0x55, 0x22, 0x29, + 0x2C, 0x2B, 0x2B, 0x3F, 0xE4, 0xE4, 0x43, 0x66, + 0x30, 0x23, 0x24, 0x2A, 0x28, 0x2B, 0x54, 0x63, + 0x33, 0x39, 0x28, 0x20, 0x20, 0x20, 0x2B, 0x31, + 0x30, 0xD1, 0x43, 0x30, 0x39, 0x28, 0xE4, 0xE4, + 0xD7, 0xF5, 0x2B, 0x6B, 0x20, 0x30, 0x34, 0xD1, + 0x60, 0x23, 0x63, 0x54, 0x22, 0x47, 0x60, 0xCB, + 0xC4, 0xC4, 0x25, 0x22, 0x54, 0xC4, 0x63, 0x23, + 0xC4, 0xC4, 0x63, 0xC4, 0x23, 0x2A, 0x24, 0x22, + 0x55, 0x55, 0xAF, 0x6C, 0x22, 0x39, 0x2C, 0x39, + 0x28, 0x23, 0xD1, 0x43, 0x42, 0x8A, 0x63, 0x39, + 0x39, 0x2A, 0x20, 0x6B, 0x33, 0xCC, 0xD1, 0xB6, + 0x30, 0x24, 0x54, 0x63, 0x31, 0xCC, 0xCC, 0xCB, + 0xC4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x39, 0x30, + 0x30, 0x6C, 0x43, 0x43, 0x6C, 0x63, 0x25, 0x24, + 0x63, 0x63, 0x63, 0x25, 0x63, 0xCC, 0xD1, 0x34, + 0x63, 0x25, 0x54, 0x25, 0x2A, 0x28, 0x31, 0xCB, + 0x63, 0x78, 0x24, 0x33, 0xC4, 0xC4, 0x33, 0x2C, + 0xC4, 0x54, 0x54, 0x30, 0x21, 0x22, 0x25, 0x23, + 0x55, 0x55, 0xD1, 0x58, 0x33, 0x6B, 0x2C, 0x39, + 0x39, 0x39, 0x34, 0x43, 0x42, 0x43, 0xCC, 0x2B, + 0x28, 0x29, 0x20, 0x28, 0x21, 0x30, 0xCC, 0xAF, + 0x54, 0x23, 0xC4, 0x54, 0x58, 0x2E, 0x35, 0x42, + 0x55, 0x54, 0x8B, 0x2A, 0x20, 0x20, 0x28, 0x22, + 0x78, 0x30, 0xD1, 0x43, 0x44, 0x6C, 0xC4, 0xC4, + 0x60, 0x31, 0x31, 0x63, 0x6C, 0xAF, 0xCC, 0xCB, + 0x24, 0x25, 0x33, 0x23, 0x2C, 0x24, 0x31, 0x30, + 0x63, 0xC4, 0x21, 0x54, 0x30, 0x63, 0x24, 0x2A, + 0x54, 0x63, 0x54, 0xC4, 0x2B, 0x24, 0x33, 0x24, + 0x34, 0x55, 0xD1, 0x55, 0x30, 0x28, 0x29, 0x39, + 0x39, 0x8B, 0x63, 0x55, 0x42, 0x66, 0xB6, 0x25, + 0x29, 0x29, 0x29, 0x28, 0x2A, 0x54, 0x78, 0x6C, + 0x23, 0x20, 0x25, 0x30, 0xCB, 0x62, 0x35, 0x35, + 0x35, 0x44, 0x24, 0x6B, 0x29, 0x20, 0x2A, 0x39, + 0x28, 0x63, 0x34, 0xB6, 0x34, 0xCB, 0x63, 0x30, + 0x31, 0x31, 0x30, 0x30, 0xCC, 0x60, 0x63, 0xC4, + 0x20, 0x33, 0x25, 0x20, 0x48, 0x33, 0x30, 0x54, + 0x78, 0x54, 0x2B, 0x63, 0x30, 0x63, 0x23, 0x22, + 0x63, 0x63, 0x63, 0x33, 0x28, 0x25, 0x54, 0x24, + 0x78, 0xAF, 0xD1, 0xD1, 0xCC, 0x22, 0x39, 0x39, + 0x2C, 0x3F, 0x2B, 0x34, 0xB6, 0x43, 0x43, 0xC4, + 0x2B, 0x28, 0x39, 0x50, 0x2C, 0x24, 0x63, 0x78, + 0x21, 0x2C, 0x2A, 0x23, 0x54, 0xD1, 0x35, 0x35, + 0x35, 0x35, 0x55, 0x22, 0x39, 0x2C, 0x2C, 0x2C, + 0x20, 0x30, 0xCC, 0x6C, 0xCB, 0x30, 0x54, 0x30, + 0x78, 0x63, 0x78, 0x30, 0x54, 0x78, 0x30, 0x23, + 0x2B, 0x33, 0x24, 0x28, 0x39, 0x24, 0x54, 0x30, + 0x78, 0x33, 0x25, 0xC4, 0xC4, 0x33, 0x39, 0x25, + 0xC4, 0x63, 0xC4, 0x24, 0x20, 0x54, 0x54, 0x25, + 0x63, 0xCC, 0xD1, 0xB6, 0x55, 0x54, 0x39, 0x29, + 0x39, 0x2C, 0x6B, 0x30, 0xAF, 0xB6, 0xB6, 0x60, + 0x22, 0x2A, 0x2C, 0x39, 0x2C, 0x21, 0x54, 0x63, + 0x21, 0x50, 0x2C, 0x2C, 0x2B, 0x25, 0x62, 0x35, + 0x35, 0x35, 0x35, 0xCC, 0x2B, 0x29, 0x2B, 0x20, + 0x23, 0x25, 0xC4, 0x30, 0xC4, 0x63, 0x63, 0x63, + 0x63, 0x33, 0x24, 0x31, 0x31, 0x31, 0x54, 0x28, + 0x24, 0x25, 0x22, 0x6B, 0x28, 0x24, 0xC4, 0x78, + 0x30, 0x24, 0x63, 0xC4, 0x54, 0x23, 0x29, 0x63, + 0xC4, 0x54, 0xC4, 0x21, 0x24, 0x54, 0x54, 0x25, + 0x30, 0xCB, 0xD1, 0xB6, 0x55, 0x63, 0x28, 0x29, + 0x39, 0x39, 0x48, 0x33, 0x58, 0x44, 0xB6, 0x60, + 0x24, 0x20, 0x2B, 0x28, 0x2A, 0x22, 0x54, 0x63, + 0x21, 0x48, 0x2A, 0x2B, 0x39, 0x21, 0xB6, 0x35, + 0x35, 0x35, 0x35, 0x42, 0x23, 0x29, 0x2A, 0x2B, + 0x23, 0x25, 0x54, 0x54, 0x54, 0x63, 0x63, 0x30, + 0x25, 0x2B, 0x31, 0x31, 0x31, 0x31, 0x21, 0x2C, + 0x33, 0x25, 0x21, 0x39, 0x20, 0x25, 0x30, 0x78, + 0xC4, 0x23, 0xC4, 0x30, 0x54, 0x20, 0x28, 0x63, + 0x63, 0x63, 0x63, 0x20, 0x25, 0x54, 0x54, 0x20, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xC2, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0x90, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xA0, 0x00, + 0x8F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0x83, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0x1F, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0x3F, 0xF7, 0x8F, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0x7F, 0xF7, + 0xC7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0x6F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0x7F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0x7F, 0xE7, 0xEF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0x7B, 0xFF, + 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x7B, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x79, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x7C, 0xFF, 0xCF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0x77, 0xFF, + 0xDF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x3F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0xBF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x9F, 0xFF, 0x3F, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1F, 0x9F, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1F, + 0x8F, 0xFE, 0x7F, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0xC7, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0F, 0xF7, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x07, 0xFB, 0xF3, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x07, + 0xFD, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x03, 0xFE, 0x8F, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x03, 0xFE, 0x1F, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xBF, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFE, 0xBF, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x9F, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFE, 0x87, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFD, 0x33, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0xF3, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0x8B, 0xF9, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x27, 0xF8, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x07, 0xF8, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0x8F, 0xF8, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xE3, 0xF8, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xF8, 0x78, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x7F, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x20, + 0x7F, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x10, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:37 jj Exp $ + * include/asm-sparc64/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/UltraSPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 215 + +unsigned char linux_logo_red[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xB0, + 0x0C, 0xB1, 0xD4, 0xCE, 0x04, 0x06, 0x16, 0xB6, + 0xCD, 0xB2, 0x42, 0x46, 0x4B, 0xA8, 0xF3, 0xCA, + 0xC5, 0x1C, 0xDC, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x8E, 0xCC, 0xA5, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x79, 0x68, 0x8D, 0xAF, 0xFC, 0x8E, 0x3E, + 0x6B, 0x11, 0x37, 0x79, 0x5C, 0x3C, 0x3F, 0x3C, + 0x48, 0x47, 0x3D, 0xB9, 0x62, 0xE1, 0x4D, 0x57, + 0x84, 0x78, 0xA6, 0x58, 0x99, 0xCD, 0xB7, 0xE3, + 0x6D, 0x5A, 0xAF, 0x79, 0x79, 0xF2, 0x42, 0x46, + 0xDD, 0x89, 0xC3, 0xF2, 0xF0, 0xE0, 0xD1, 0x90, + 0x76, 0x6B, 0x4A, 0xBE, 0xBD, 0xE3, 0xF6, 0xE9, + 0xEC, 0xE8, 0xEC, 0xC0, 0x66, 0x63, 0xCB, 0xAB, + 0x49, 0x5C, 0xAD, 0xD6, 0xEE, 0xF5, 0xF5, 0xE9, + 0x6E, 0x00, 0x69, 0x6A, 0xA1, 0x7A, 0xB4, 0xDE, + 0xF1, 0xF6, 0xDD, 0x00, 0x73, 0xDB, 0x4C, 0x53, + 0x6A, 0xF5, 0xF5, 0xD6, 0xC3, 0x6A, 0x4B, 0x4B, + 0x60, 0xF8, 0x9B, 0xD7, 0xD7, 0x71, 0xB3, 0xA4, + 0xCA, 0xAB, 0xB4, 0xB2, 0x76, 0xBA, 0x8B, 0xA0, + 0xA5, 0xEE, 0xE7, 0x67, 0x5F, 0x08, 0x94, 0xDB, + 0xE5, 0x4F, 0x00, 0x34, 0xEE, 0xEC, 0xE2, 0x48, + 0xF3, 0xEB, 0xF4, 0xF4, 0xEF, 0xD6, 0xB6, 0xE6, + 0xE6, 0xED, 0xE7, 0xE6, 0x3D, 0xE7, 0xCD, 0x44, + 0xEF, 0xEC, 0xF5, 0x66, 0xF3, 0xA9, 0x77, 0x58, + 0x75, 0x6C, 0x53, 0x24, 0xAC, 0x0D, 0x3C +}; + +unsigned char linux_logo_green[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xAD, + 0x0C, 0xB1, 0x92, 0xAB, 0x03, 0x06, 0x16, 0xB6, + 0xCD, 0x88, 0x42, 0x46, 0x4B, 0x94, 0xBB, 0xCA, + 0xC5, 0x1C, 0xAB, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x73, 0xCA, 0x91, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x5A, 0x49, 0x56, 0x6E, 0xFC, 0x6B, 0x3E, + 0x6B, 0x0D, 0x37, 0x79, 0x51, 0x44, 0x3F, 0x43, + 0x38, 0x3D, 0x48, 0xB9, 0x62, 0xA5, 0x47, 0x48, + 0x49, 0x4A, 0x97, 0x48, 0x81, 0x95, 0x8E, 0xE3, + 0x6D, 0x57, 0x51, 0x51, 0x47, 0xB2, 0x42, 0x46, + 0xDD, 0x5B, 0x87, 0xBE, 0xC7, 0xC8, 0x56, 0x75, + 0x5D, 0x4B, 0x4D, 0xBE, 0x85, 0xA6, 0xBC, 0xC7, + 0xCA, 0xCD, 0xCC, 0xA4, 0x53, 0x4D, 0x9F, 0x55, + 0x52, 0x5E, 0x75, 0x9C, 0xB6, 0xC3, 0xD7, 0xCC, + 0x55, 0x00, 0x6A, 0x59, 0x7D, 0x55, 0x7C, 0xA3, + 0xB7, 0xBF, 0xA5, 0x00, 0x67, 0xC6, 0x47, 0x54, + 0x46, 0xB8, 0xBE, 0xB2, 0x87, 0x52, 0x4B, 0x43, + 0x41, 0xF8, 0x69, 0x96, 0x9B, 0x66, 0xB0, 0x6C, + 0x8E, 0x81, 0xB4, 0x76, 0x76, 0xB9, 0x65, 0x77, + 0x6D, 0xED, 0xE7, 0x67, 0x5F, 0x06, 0x54, 0x6C, + 0xCB, 0x4F, 0x00, 0x2F, 0xC2, 0xB5, 0xB6, 0x30, + 0xC3, 0xAE, 0xC4, 0xCA, 0xC6, 0xB4, 0x7B, 0xAD, + 0xAD, 0xB6, 0xB6, 0xAD, 0x29, 0xAB, 0x93, 0x2E, + 0xBC, 0xBC, 0xC9, 0x53, 0xBF, 0x77, 0x54, 0x3B, + 0x4B, 0x3F, 0x39, 0x19, 0x76, 0x08, 0x2C +}; + +unsigned char linux_logo_blue[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0xD6, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x39, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xA7, + 0x0C, 0xB1, 0x58, 0x8A, 0x03, 0x07, 0x16, 0xB6, + 0xCD, 0x5A, 0x42, 0x46, 0x4F, 0x6F, 0x77, 0xCA, + 0xC5, 0x1C, 0x6F, 0xA5, 0xD4, 0xE6, 0xF5, 0xF3, + 0xC2, 0x4D, 0xD1, 0x64, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x49, 0x3C, 0x47, 0x45, 0xFE, 0x3B, 0x41, + 0x6B, 0x09, 0x37, 0x79, 0x39, 0x39, 0x3F, 0x42, + 0x3A, 0x42, 0x5F, 0xB9, 0x62, 0x4C, 0x39, 0x44, + 0x3B, 0x3A, 0xA0, 0x3D, 0x08, 0x08, 0x09, 0xDE, + 0x6D, 0x48, 0x3B, 0x3F, 0x42, 0xF3, 0x36, 0x3C, + 0xDD, 0x06, 0x16, 0x08, 0x13, 0x0A, 0x4B, 0x71, + 0x5D, 0x44, 0x47, 0xBE, 0x08, 0x0C, 0x0D, 0x0C, + 0x19, 0x29, 0x36, 0x06, 0x43, 0x44, 0xBA, 0x45, + 0x50, 0x58, 0x07, 0x07, 0x0D, 0x0E, 0x10, 0x50, + 0x06, 0x42, 0x40, 0x44, 0x79, 0x06, 0x06, 0x0C, + 0x08, 0x08, 0x07, 0x36, 0x4C, 0xE5, 0x42, 0x55, + 0x03, 0x0F, 0x12, 0x06, 0x07, 0x3C, 0x4B, 0x3D, + 0x01, 0xF8, 0x08, 0x0E, 0x0A, 0x69, 0xAC, 0x0C, + 0x0A, 0x27, 0xBB, 0x36, 0x76, 0xC0, 0x04, 0x08, + 0x08, 0xED, 0xEE, 0x68, 0x5F, 0xB2, 0x3B, 0x52, + 0xAC, 0x4F, 0x6F, 0x2D, 0x16, 0x08, 0x59, 0x04, + 0x13, 0x0E, 0x14, 0x17, 0x16, 0x2E, 0x08, 0x0D, + 0x11, 0x14, 0x0D, 0x06, 0x04, 0x08, 0x25, 0x8E, + 0x0E, 0x14, 0x25, 0x9B, 0x1C, 0x16, 0x78, 0x06, + 0x04, 0x03, 0x79, 0x8C, 0x0B, 0xC8, 0x48 +}; + +unsigned char linux_logo[] __initdata = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x22, 0x23, 0x24, 0x24, + 0x25, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x23, 0x23, + 0x23, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x26, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x26, 0x28, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x28, 0x28, 0x28, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x2C, 0x29, 0x29, 0x29, 0x28, + 0x28, 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2A, 0x2A, + 0x2A, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2D, 0x2E, 0x2F, 0x27, + 0x27, 0x26, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x28, + 0x28, 0x29, 0x29, 0x29, 0x29, 0x2C, 0x2C, 0x29, + 0x29, 0x29, 0x28, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x30, 0x31, 0x32, + 0x27, 0x27, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, + 0x20, 0x20, 0x2B, 0x2A, 0x28, 0x29, 0x29, 0x29, + 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x28, 0x2A, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x27, 0x27, 0x33, 0x25, 0x25, 0x24, 0x24, + 0x24, 0x24, 0x23, 0x21, 0x20, 0x20, 0x2B, 0x2A, + 0x28, 0x29, 0x29, 0x37, 0x2C, 0x2C, 0x29, 0x28, + 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2A, 0x2B, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x32, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x25, 0x24, 0x23, 0x21, + 0x20, 0x2B, 0x2A, 0x29, 0x29, 0x2C, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x38, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x23, 0x23, 0x24, 0x24, + 0x25, 0x25, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x24, 0x22, 0x20, 0x20, 0x2A, 0x28, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x23, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x21, 0x22, 0x24, 0x20, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x3A, 0x3B, 0x22, 0x20, 0x2A, 0x28, + 0x29, 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x20, 0x21, 0x22, 0x22, 0x23, 0x24, 0x27, + 0x27, 0x27, 0x3C, 0x36, 0x3C, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x3D, 0x3E, 0x32, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x39, 0x3F, 0x3F, + 0x39, 0x2C, 0x20, 0x20, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x40, 0x40, 0x41, 0x22, 0x20, + 0x2A, 0x28, 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x2A, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, + 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x22, 0x27, + 0x27, 0x3C, 0x3C, 0x3D, 0x42, 0x3C, 0x27, 0x27, + 0x3C, 0x27, 0x3C, 0x43, 0x44, 0x36, 0x42, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x28, 0x29, 0x2C, + 0x2C, 0x45, 0x20, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x46, 0x40, 0x47, 0x40, 0x47, 0x3A, 0x40, + 0x22, 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x2C, 0x29, + 0x28, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x20, 0x27, + 0x27, 0x44, 0x28, 0x24, 0x27, 0x2F, 0x3C, 0x27, + 0x27, 0x38, 0x24, 0x2C, 0x2C, 0x48, 0x49, 0x36, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x29, 0x29, + 0x4A, 0x20, 0x3A, 0x40, 0x47, 0x40, 0x47, 0x40, + 0x40, 0x47, 0x40, 0x40, 0x39, 0x39, 0x39, 0x4A, + 0x25, 0x24, 0x22, 0x2B, 0x28, 0x29, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x21, 0x20, 0x2B, 0x2A, 0x27, + 0x3D, 0x4B, 0x48, 0x4C, 0x2B, 0x3C, 0x27, 0x3C, + 0x3C, 0x23, 0x4D, 0x4E, 0x4F, 0x50, 0x33, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x39, 0x3F, 0x39, + 0x51, 0x20, 0x39, 0x39, 0x47, 0x40, 0x4D, 0x4D, + 0x40, 0x52, 0x4D, 0x40, 0x47, 0x40, 0x39, 0x39, + 0x53, 0x54, 0x25, 0x24, 0x20, 0x2A, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x2A, 0x2B, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x21, 0x20, 0x2B, 0x28, 0x2A, 0x20, 0x27, + 0x36, 0x4F, 0x55, 0x48, 0x56, 0x3D, 0x3C, 0x3C, + 0x32, 0x57, 0x56, 0x58, 0x49, 0x56, 0x56, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x20, 0x20, + 0x41, 0x39, 0x39, 0x3A, 0x59, 0x5A, 0x59, 0x5B, + 0x5C, 0x3A, 0x4D, 0x5D, 0x57, 0x39, 0x39, 0x4A, + 0x5E, 0x33, 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, + 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, + 0x20, 0x2B, 0x2A, 0x2A, 0x20, 0x22, 0x22, 0x27, + 0x5F, 0x2D, 0x3C, 0x60, 0x56, 0x54, 0x61, 0x49, + 0x35, 0x56, 0x34, 0x27, 0x62, 0x27, 0x56, 0x39, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x63, 0x54, + 0x40, 0x64, 0x65, 0x66, 0x67, 0x67, 0x68, 0x5F, + 0x2E, 0x69, 0x6A, 0x67, 0x5F, 0x3A, 0x39, 0x2C, + 0x53, 0x23, 0x25, 0x54, 0x33, 0x25, 0x23, 0x20, + 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, + 0x2B, 0x2A, 0x20, 0x22, 0x22, 0x21, 0x2B, 0x27, + 0x62, 0x36, 0x27, 0x33, 0x6B, 0x54, 0x3D, 0x3C, + 0x49, 0x57, 0x27, 0x27, 0x27, 0x27, 0x56, 0x57, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x6C, 0x31, 0x6D, + 0x64, 0x51, 0x6E, 0x2E, 0x2E, 0x6F, 0x5A, 0x70, + 0x70, 0x71, 0x72, 0x67, 0x67, 0x69, 0x73, 0x46, + 0x4A, 0x2A, 0x21, 0x25, 0x33, 0x54, 0x33, 0x24, + 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, + 0x2B, 0x22, 0x22, 0x22, 0x2B, 0x28, 0x2A, 0x27, + 0x27, 0x39, 0x3C, 0x3D, 0x45, 0x74, 0x75, 0x76, + 0x76, 0x45, 0x27, 0x27, 0x27, 0x27, 0x56, 0x77, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x78, 0x78, 0x5E, + 0x79, 0x7A, 0x7B, 0x6E, 0x5A, 0x5A, 0x70, 0x7C, + 0x70, 0x5B, 0x7D, 0x5A, 0x66, 0x7E, 0x7F, 0x79, + 0x48, 0x6B, 0x2C, 0x20, 0x24, 0x33, 0x54, 0x33, + 0x24, 0x21, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x21, + 0x22, 0x22, 0x20, 0x28, 0x2B, 0x20, 0x22, 0x27, + 0x27, 0x80, 0x27, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x74, 0x85, 0x84, 0x27, 0x3C, 0x4F, 0x4F, 0x66, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x23, 0x5E, + 0x64, 0x86, 0x79, 0x73, 0x87, 0x88, 0x7C, 0x5A, + 0x5A, 0x71, 0x7D, 0x71, 0x89, 0x79, 0x8A, 0x8A, + 0x51, 0x8B, 0x48, 0x39, 0x2A, 0x22, 0x33, 0x54, + 0x33, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x2C, 0x29, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x22, 0x23, + 0x21, 0x2A, 0x2A, 0x20, 0x21, 0x23, 0x25, 0x27, + 0x27, 0x55, 0x8C, 0x8D, 0x8E, 0x83, 0x8F, 0x90, + 0x91, 0x92, 0x92, 0x85, 0x85, 0x93, 0x51, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0x29, 0x51, + 0x79, 0x79, 0x94, 0x89, 0x89, 0x89, 0x5A, 0x95, + 0x64, 0x88, 0x96, 0x97, 0x7A, 0x73, 0x98, 0x98, + 0x99, 0x50, 0x50, 0x48, 0x6B, 0x28, 0x21, 0x25, + 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2B, 0x20, 0x22, 0x22, 0x20, + 0x2B, 0x2B, 0x20, 0x22, 0x24, 0x25, 0x33, 0x27, + 0x27, 0x9A, 0x9B, 0x9C, 0x9D, 0x83, 0x9E, 0x85, + 0x9F, 0x92, 0x85, 0x85, 0x85, 0x85, 0x92, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xA1, 0x47, 0xA2, + 0xA2, 0x94, 0xA3, 0x94, 0x95, 0x95, 0x73, 0x73, + 0x95, 0x87, 0xA4, 0x5B, 0x97, 0x7B, 0x88, 0x98, + 0xA2, 0x50, 0x48, 0x48, 0x48, 0x8B, 0x29, 0x20, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x2B, 0x2B, + 0x20, 0x21, 0x23, 0x24, 0x25, 0x25, 0x33, 0x27, + 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x8F, 0x90, 0x90, + 0x9F, 0x90, 0x85, 0x90, 0x85, 0x74, 0xAA, 0x81, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xAB, 0x40, 0xAC, + 0x79, 0xA3, 0x89, 0xAD, 0x95, 0x6F, 0xAE, 0xAE, + 0xAE, 0x5B, 0x59, 0x88, 0x7B, 0x89, 0x79, 0xAF, + 0xA2, 0x6B, 0x48, 0x48, 0x48, 0x48, 0x50, 0x2C, + 0x20, 0x24, 0x33, 0x54, 0x25, 0x22, 0x2A, 0x2A, + 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x23, 0x22, 0x2B, 0x20, 0x20, + 0x22, 0x23, 0x24, 0x25, 0x24, 0x24, 0x22, 0x27, + 0xB0, 0x8C, 0xAA, 0xB1, 0xB2, 0x84, 0x85, 0x9F, + 0x85, 0x85, 0x85, 0xB3, 0xB4, 0xAA, 0xAA, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0xB5, + 0xA3, 0xA3, 0xAC, 0x5D, 0xB6, 0xAE, 0xB7, 0x69, + 0x73, 0x5B, 0x88, 0x89, 0x95, 0x73, 0x99, 0x99, + 0x59, 0x2A, 0x39, 0x48, 0x48, 0x50, 0x48, 0x50, + 0x2C, 0x20, 0x24, 0x33, 0x54, 0x25, 0x21, 0x20, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x23, 0x21, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x24, 0x24, 0x23, 0x22, 0x20, 0x2A, 0x27, + 0x27, 0xB0, 0x8C, 0xA9, 0xB2, 0x9E, 0x91, 0x85, + 0x85, 0x93, 0xB8, 0x75, 0xAA, 0xA7, 0x8C, 0x27, + 0x27, 0x27, 0x33, 0x3C, 0x27, 0x27, 0x2C, 0x7B, + 0x55, 0x79, 0xA3, 0x5D, 0xB9, 0x43, 0x7F, 0x7E, + 0x5F, 0x5A, 0x5A, 0x95, 0x64, 0x73, 0x58, 0x64, + 0x5C, 0x25, 0x2B, 0x3F, 0x48, 0x48, 0x8B, 0x48, + 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x24, 0x22, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x23, 0x21, 0x20, 0x20, 0x20, 0x21, 0x22, + 0x24, 0x23, 0x22, 0x21, 0x2B, 0x20, 0x54, 0x27, + 0x27, 0x8B, 0x81, 0xA5, 0x93, 0x93, 0x74, 0xA5, + 0xBA, 0x75, 0xBB, 0xBC, 0xB4, 0x6D, 0x50, 0x6B, + 0x27, 0x27, 0x30, 0x33, 0x49, 0x27, 0x27, 0x5E, + 0x6F, 0x73, 0x94, 0xBD, 0x4E, 0x5D, 0x7F, 0x7F, + 0xB7, 0x68, 0x73, 0x6E, 0xB7, 0x7F, 0x95, 0x97, + 0x47, 0x63, 0x25, 0x20, 0x3F, 0x48, 0x8B, 0x8B, + 0x48, 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x25, + 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x21, + 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, + 0x22, 0x21, 0x20, 0x2A, 0x33, 0x30, 0x30, 0x27, + 0x27, 0x50, 0xBE, 0xBF, 0x9A, 0xB3, 0x9B, 0xBB, + 0xBB, 0xC0, 0x8C, 0xC1, 0x8B, 0xC2, 0x47, 0x8B, + 0x27, 0x27, 0x38, 0x63, 0x63, 0x27, 0x27, 0xC3, + 0xB5, 0x95, 0x72, 0x95, 0x6F, 0x69, 0x7E, 0x66, + 0x7E, 0x7F, 0x6E, 0x7E, 0x95, 0x95, 0x73, 0x70, + 0x30, 0x30, 0x30, 0x33, 0x20, 0x3F, 0x48, 0x8B, + 0x6B, 0x48, 0x50, 0x29, 0x21, 0x33, 0x54, 0x33, + 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x21, 0x21, 0x23, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, 0x22, + 0x20, 0x2B, 0x21, 0xC4, 0x30, 0x60, 0x30, 0x27, + 0x27, 0xC5, 0x8B, 0x39, 0xC6, 0xC7, 0xA6, 0xA6, + 0xC8, 0x9A, 0x3B, 0x39, 0x50, 0x56, 0x56, 0x4F, + 0x33, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x48, + 0x59, 0x94, 0x73, 0xAE, 0xB7, 0xB7, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x5A, 0x70, 0x7C, 0x71, 0xC3, + 0x63, 0x30, 0x60, 0x78, 0x54, 0x20, 0x6B, 0x48, + 0x6B, 0x6B, 0x50, 0x50, 0x29, 0x22, 0x33, 0x33, + 0x2A, 0x2B, 0x20, 0x20, 0x21, 0x22, 0x22, 0x22, + 0x21, 0x20, 0x20, 0x20, 0x24, 0x24, 0x20, 0x20, + 0x2B, 0x24, 0x30, 0x60, 0x60, 0x30, 0xAB, 0x27, + 0x27, 0x40, 0x4C, 0x50, 0x39, 0x87, 0xC3, 0x53, + 0x37, 0x48, 0x37, 0x48, 0xC9, 0x56, 0xB9, 0x56, + 0xCA, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x3C, + 0x51, 0x5A, 0x6E, 0xB7, 0xB7, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7F, 0xB7, 0x5A, 0x7C, 0x5B, 0x37, + 0x23, 0x63, 0x31, 0x6C, 0xCB, 0x63, 0x20, 0x6B, + 0x50, 0x3F, 0x39, 0x50, 0x8B, 0x28, 0x24, 0x24, + 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x22, 0x22, 0x21, + 0x20, 0x20, 0x20, 0x23, 0x23, 0x20, 0x20, 0x2B, + 0x33, 0x78, 0xCB, 0x60, 0x30, 0x22, 0x3D, 0x27, + 0x2F, 0x56, 0x4E, 0x8B, 0x6B, 0x39, 0x48, 0x8B, + 0x6B, 0x8B, 0x80, 0xC9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x34, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x48, 0xB5, 0xB7, 0xB7, 0x7E, 0x7E, 0x2E, 0x7E, + 0x7E, 0x7E, 0x7F, 0x7C, 0x65, 0x71, 0x3A, 0x48, + 0x2C, 0x24, 0x30, 0x6C, 0x34, 0x6C, 0xC4, 0x20, + 0x8B, 0x50, 0x39, 0x39, 0x48, 0x6B, 0x2B, 0x22, + 0x2B, 0x20, 0x21, 0x22, 0x23, 0x23, 0x22, 0x21, + 0x20, 0x2B, 0x23, 0x22, 0x20, 0x2B, 0x2B, 0x54, + 0x60, 0x31, 0xCB, 0x54, 0x20, 0x3D, 0x36, 0x27, + 0x4E, 0xB9, 0x56, 0x56, 0x8B, 0x6B, 0x50, 0x6B, + 0x40, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x56, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x7B, 0x6E, 0xB7, 0xB7, 0xB7, 0x7E, 0x7F, + 0xB7, 0xB7, 0x7F, 0x7E, 0x6F, 0x5B, 0x29, 0x2C, + 0x48, 0x39, 0x24, 0x60, 0x58, 0xAF, 0xCC, 0x63, + 0x20, 0x8B, 0x8B, 0x39, 0x39, 0x48, 0x3F, 0x28, + 0x20, 0x20, 0x22, 0x23, 0x23, 0x23, 0x22, 0x20, + 0x2B, 0x22, 0x22, 0x2B, 0x2B, 0x20, 0x54, 0xCB, + 0x31, 0xCB, 0x25, 0x20, 0x27, 0x27, 0x27, 0x48, + 0xB9, 0x56, 0xB9, 0x56, 0x4F, 0x48, 0x47, 0x57, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0x62, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x48, 0x6F, 0x69, 0xB7, 0xB7, 0xB7, 0x7F, + 0xB7, 0xB7, 0xB7, 0x73, 0x59, 0x50, 0x29, 0x2B, + 0x28, 0x8B, 0x39, 0x25, 0x31, 0x55, 0xB6, 0x34, + 0x63, 0x2B, 0x48, 0x6B, 0x2C, 0x39, 0x47, 0x6B, + 0x22, 0x22, 0x23, 0x24, 0x23, 0x22, 0x20, 0x2B, + 0x20, 0x22, 0x2A, 0x2B, 0x20, 0x33, 0xCB, 0x31, + 0x78, 0x24, 0x21, 0xCD, 0x27, 0x27, 0x27, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0xC9, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x41, 0x64, 0xB7, 0xB7, 0xB7, 0x7F, + 0x68, 0xB7, 0xAE, 0xA3, 0x23, 0x39, 0x8B, 0x2A, + 0x20, 0x20, 0x39, 0x6B, 0x25, 0xCC, 0x43, 0x43, + 0x34, 0x63, 0x2A, 0x48, 0x3F, 0x39, 0x6B, 0x6B, + 0x24, 0x23, 0x24, 0x24, 0x23, 0x21, 0x2B, 0x2B, + 0x22, 0x2B, 0x2B, 0x20, 0x24, 0x78, 0x31, 0x30, + 0x23, 0x21, 0x21, 0x27, 0x27, 0x27, 0x80, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x3C, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xCE, 0x8A, 0xAE, 0x6F, 0xB7, + 0x6F, 0x89, 0x71, 0x78, 0x63, 0x23, 0x39, 0x6B, + 0x2B, 0x20, 0x20, 0x2C, 0x6B, 0x25, 0x34, 0x42, + 0x42, 0x34, 0x54, 0x29, 0x48, 0x3F, 0x39, 0x3F, + 0x25, 0x24, 0x25, 0x24, 0x22, 0x20, 0x2A, 0x21, + 0x2B, 0x2A, 0x20, 0x22, 0x30, 0x60, 0x30, 0x22, + 0x21, 0x22, 0x27, 0x27, 0x27, 0x2D, 0x4C, 0x56, + 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0x56, 0x2E, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x40, 0x97, 0x95, 0x5A, 0x71, + 0x7C, 0xCE, 0x40, 0x60, 0x31, 0x30, 0x23, 0x3F, + 0x3F, 0x20, 0x20, 0x20, 0x29, 0x8B, 0x33, 0x58, + 0x66, 0x43, 0xCC, 0x25, 0x39, 0x50, 0x6B, 0x2C, + 0x33, 0x25, 0x25, 0x23, 0x20, 0x2A, 0x2B, 0x20, + 0x2A, 0x2B, 0x22, 0x54, 0x30, 0x30, 0x24, 0x22, + 0x21, 0x27, 0x27, 0x27, 0x27, 0xAF, 0x29, 0x4E, + 0x4F, 0xB9, 0x56, 0xB9, 0x4D, 0x4D, 0x77, 0xC9, + 0xB9, 0xB9, 0xB9, 0x56, 0xC9, 0x4D, 0x4D, 0x80, + 0x4C, 0x40, 0xC9, 0x4D, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0xCF, 0x97, 0x97, 0xCE, + 0x86, 0xD0, 0x54, 0x6C, 0x58, 0x34, 0x60, 0x23, + 0x6B, 0x39, 0x20, 0x20, 0x20, 0x28, 0x6B, 0x54, + 0xD1, 0x66, 0xB6, 0x60, 0x22, 0x6B, 0x8B, 0x2C, + 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, 0x20, 0x28, + 0x2B, 0x20, 0x25, 0xC4, 0x30, 0x25, 0x22, 0x21, + 0x26, 0x27, 0x27, 0x27, 0x27, 0x20, 0x4B, 0x52, + 0x80, 0x4F, 0xB9, 0x56, 0xB9, 0x80, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x4D, 0x80, 0x50, 0x48, + 0x50, 0x50, 0x50, 0x56, 0x3D, 0x27, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x3C, 0x46, 0xC3, 0x86, 0x86, + 0xD0, 0x39, 0x24, 0x6C, 0xD1, 0x43, 0x43, 0x6C, + 0x24, 0x6B, 0x2C, 0x20, 0x20, 0x20, 0x29, 0x39, + 0x63, 0xD1, 0x42, 0x55, 0xC4, 0x2B, 0x8B, 0x39, + 0x54, 0x25, 0x24, 0x20, 0x2A, 0x2A, 0x28, 0x28, + 0x20, 0x22, 0x54, 0x63, 0x25, 0x24, 0x22, 0x22, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x77, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xC9, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x4F, + 0x77, 0x47, 0x8B, 0x40, 0x56, 0x27, 0x27, 0x49, + 0x2D, 0x27, 0x27, 0x27, 0x39, 0x40, 0x39, 0x39, + 0x28, 0x3F, 0x39, 0x33, 0x58, 0x66, 0x35, 0x2E, + 0x58, 0x24, 0x8B, 0x29, 0x20, 0x20, 0x20, 0x39, + 0x29, 0x30, 0x55, 0xB6, 0xCC, 0x25, 0x29, 0x39, + 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2A, 0x29, 0x2B, + 0x22, 0x24, 0x54, 0x33, 0x25, 0x22, 0x2B, 0x54, + 0x27, 0x27, 0x62, 0x27, 0x30, 0x80, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4D, 0x8B, 0x77, 0x36, 0x27, 0x27, + 0x3C, 0x2F, 0x27, 0x27, 0x39, 0x39, 0x39, 0x47, + 0x20, 0x2B, 0x2C, 0x39, 0x33, 0xB6, 0x35, 0x35, + 0x35, 0xAF, 0x24, 0x48, 0x2A, 0x20, 0x20, 0x20, + 0x8B, 0x2B, 0x78, 0xAF, 0x58, 0x30, 0x21, 0x28, + 0x33, 0x25, 0x21, 0x28, 0x29, 0x29, 0x28, 0x20, + 0x24, 0x33, 0x54, 0x33, 0x23, 0x20, 0x24, 0xD2, + 0x27, 0x49, 0x27, 0x27, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0xC9, 0x50, 0x56, 0x27, 0x27, + 0x3D, 0x38, 0x3D, 0x27, 0x27, 0x47, 0x39, 0x39, + 0x28, 0x20, 0x20, 0x2A, 0x39, 0x54, 0x43, 0x35, + 0x35, 0x35, 0xAF, 0x23, 0x48, 0x2B, 0x20, 0x20, + 0x2B, 0x48, 0x22, 0x60, 0x34, 0xCB, 0x25, 0x21, + 0x33, 0x24, 0x2B, 0x29, 0x29, 0x29, 0x2B, 0x22, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x33, 0x27, + 0x27, 0x32, 0x27, 0x30, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0xC9, 0x4C, 0x36, 0x3C, + 0x62, 0x2F, 0x2E, 0x27, 0x27, 0x54, 0x47, 0x47, + 0x8B, 0x2B, 0x20, 0x20, 0x20, 0x3F, 0x54, 0x2E, + 0x35, 0x35, 0x35, 0x34, 0x21, 0x8B, 0x2A, 0x20, + 0x20, 0x2C, 0x6B, 0x25, 0x60, 0x60, 0x54, 0x23, + 0x25, 0x22, 0x2A, 0x2C, 0x29, 0x28, 0x20, 0x24, + 0x54, 0x63, 0x54, 0x24, 0x2B, 0x22, 0x24, 0x27, + 0x36, 0x27, 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x4C, 0x36, + 0x66, 0xD3, 0x27, 0x2F, 0x27, 0x54, 0x54, 0x27, + 0x26, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x63, + 0x35, 0x35, 0x35, 0x62, 0xCB, 0x2A, 0x3F, 0x28, + 0x2B, 0x2A, 0x50, 0x29, 0x33, 0x30, 0x54, 0x25, + 0x24, 0x20, 0x29, 0x2C, 0x2C, 0x2A, 0x21, 0x33, + 0xC4, 0xC4, 0x33, 0x21, 0x29, 0x22, 0x27, 0x27, + 0x99, 0x27, 0x31, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x3D, + 0x3D, 0x3C, 0x3C, 0x55, 0x54, 0x54, 0x54, 0x20, + 0x27, 0x2C, 0x39, 0x20, 0x20, 0x20, 0x20, 0x48, + 0x30, 0x62, 0x35, 0x35, 0x42, 0x54, 0x39, 0x39, + 0x2C, 0x28, 0x3F, 0x8B, 0x20, 0x33, 0x54, 0x24, + 0x22, 0x2B, 0x2C, 0x2C, 0x2C, 0x2B, 0x24, 0x54, + 0x30, 0xC4, 0x25, 0x2B, 0x28, 0x2B, 0x27, 0x3D, + 0x27, 0x27, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x27, + 0x20, 0x20, 0x20, 0x54, 0x54, 0x54, 0x54, 0x20, + 0x20, 0x2D, 0x2D, 0x29, 0x20, 0x20, 0x20, 0x20, + 0x48, 0x60, 0x66, 0x35, 0x62, 0x34, 0x22, 0x2C, + 0x2C, 0x3F, 0x6B, 0x48, 0x2C, 0x22, 0x23, 0x23, + 0x20, 0x2A, 0x2C, 0x29, 0x29, 0x20, 0x25, 0xC4, + 0x30, 0x54, 0x22, 0x29, 0x28, 0xD2, 0x27, 0x35, + 0x27, 0x49, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x4F, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x40, 0x20, + 0x20, 0x54, 0x54, 0x54, 0x20, 0x20, 0x20, 0x20, + 0x2D, 0x2D, 0x2D, 0x49, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6B, 0x6C, 0x42, 0x2E, 0xB6, 0x54, 0x28, + 0x29, 0x2C, 0x6B, 0x48, 0x3F, 0x2A, 0x20, 0x22, + 0x2B, 0x28, 0x2C, 0x28, 0x29, 0x20, 0x33, 0x30, + 0x30, 0x54, 0x20, 0x2C, 0x29, 0x27, 0x27, 0x3D, + 0x27, 0x40, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x63, 0x56, 0x54, 0x54, + 0x54, 0x54, 0x20, 0xD3, 0x45, 0x51, 0x51, 0x49, + 0x7C, 0x2D, 0x2D, 0x49, 0x49, 0x20, 0x20, 0x20, + 0x20, 0x2A, 0x2A, 0xCC, 0xB6, 0x8A, 0x60, 0x22, + 0x28, 0x29, 0x3F, 0x6B, 0x39, 0x29, 0x2B, 0x20, + 0x28, 0x2C, 0x28, 0x2A, 0x2A, 0x24, 0xC4, 0x30, + 0xC4, 0x33, 0x2B, 0x39, 0xCD, 0x27, 0x3C, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x63, 0x63, 0x49, 0x2D, 0x20, + 0x20, 0x2D, 0xD3, 0x49, 0x66, 0x2D, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x49, 0x8B, 0x2B, 0x20, + 0x20, 0x20, 0x39, 0x23, 0x6C, 0xAF, 0xCB, 0x23, + 0x28, 0x28, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x20, + 0x29, 0x39, 0x2B, 0x2B, 0x2B, 0x25, 0x78, 0xC4, + 0x63, 0x23, 0x29, 0x39, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x49, 0x2D, 0x49, 0x2D, 0x49, 0x2D, 0x2D, 0x2D, + 0x49, 0x49, 0x35, 0x49, 0x2D, 0x2D, 0x39, 0x28, + 0x20, 0x20, 0x2A, 0x28, 0x33, 0x60, 0xC4, 0x22, + 0x2C, 0x2A, 0x2A, 0x22, 0x23, 0x22, 0x20, 0x21, + 0x2C, 0x29, 0x20, 0x2B, 0x2B, 0x54, 0x30, 0xC4, + 0x63, 0x22, 0x2C, 0x27, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x61, 0x49, 0x2D, 0x49, 0x49, 0x2D, 0x2D, 0x49, + 0x49, 0x49, 0x2F, 0x49, 0x2D, 0x78, 0x29, 0x28, + 0x2C, 0x2A, 0x2B, 0x39, 0x2B, 0x25, 0x33, 0x20, + 0x2C, 0x20, 0x2A, 0x24, 0x54, 0x54, 0x23, 0x23, + 0x2C, 0x2A, 0x22, 0x2B, 0x20, 0x63, 0x30, 0x63, + 0xC4, 0x21, 0x39, 0x27, 0x27, 0x27, 0x35, 0x36, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x2D, 0x49, 0x49, 0x49, + 0x49, 0x27, 0x27, 0x2D, 0x38, 0x27, 0x36, 0x36, + 0x49, 0x27, 0x49, 0x2D, 0x2D, 0x44, 0x24, 0x2B, + 0x20, 0x2C, 0x3F, 0x6B, 0x2A, 0x20, 0x21, 0x28, + 0x2C, 0x20, 0x2B, 0x24, 0x30, 0xCB, 0x63, 0x54, + 0x28, 0x20, 0x24, 0x2B, 0x23, 0x78, 0xC4, 0x63, + 0x63, 0x2B, 0x3F, 0x27, 0x27, 0x27, 0x38, 0x33, + 0x3D, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x63, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x3D, 0x3D, 0x27, 0x27, 0x27, 0x2D, + 0x49, 0x49, 0x49, 0x2D, 0x62, 0x5F, 0xC4, 0x20, + 0x22, 0x2A, 0x6B, 0x8B, 0x2C, 0x2B, 0x2A, 0x3F, + 0x3F, 0x2A, 0x21, 0x21, 0xCB, 0x58, 0x6C, 0x60, + 0x20, 0x23, 0x24, 0x2A, 0x25, 0x78, 0x63, 0x63, + 0x54, 0x2A, 0x28, 0x27, 0x27, 0x27, 0x27, 0x62, + 0x3C, 0xB9, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x49, 0x2D, 0x2D, + 0x2D, 0x3D, 0x2F, 0x3C, 0x2D, 0x3C, 0x27, 0x38, + 0x2D, 0x49, 0x2D, 0x2D, 0xD1, 0x43, 0x30, 0x20, + 0x24, 0x21, 0x21, 0x21, 0x2B, 0x2A, 0x29, 0x8B, + 0x6B, 0x29, 0x2B, 0x2A, 0x30, 0x55, 0x55, 0x34, + 0x22, 0x23, 0x24, 0x29, 0x54, 0x30, 0x63, 0x63, + 0x25, 0x29, 0x22, 0x3C, 0xA5, 0xD4, 0xD5, 0x27, + 0x31, 0x56, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x2D, 0x2E, + 0x3E, 0x27, 0x27, 0x27, 0x27, 0x27, 0x36, 0x44, + 0x3C, 0x27, 0x2D, 0xC4, 0x78, 0xCC, 0x54, 0x2B, + 0x25, 0x24, 0x63, 0x60, 0x63, 0x24, 0x2A, 0x6B, + 0x3F, 0x39, 0x28, 0x21, 0x33, 0xB6, 0x44, 0x58, + 0x22, 0x23, 0x24, 0x2A, 0x30, 0x30, 0x63, 0x63, + 0x24, 0x39, 0x22, 0xBB, 0x9C, 0xB2, 0x9D, 0xA8, + 0x27, 0x8B, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0xD6, 0xD6, 0xD7, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x32, + 0x3D, 0x27, 0x39, 0x33, 0xC4, 0xC4, 0x22, 0x28, + 0x25, 0x54, 0x30, 0xD1, 0xD1, 0x60, 0x23, 0x6B, + 0x3F, 0x39, 0x2C, 0x2B, 0x20, 0x58, 0x8A, 0x58, + 0x22, 0x23, 0x23, 0x2B, 0x78, 0x30, 0xC4, 0xC4, + 0x23, 0x29, 0xBB, 0xBB, 0xD8, 0xB2, 0x9D, 0xA9, + 0xA9, 0x3C, 0x60, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xD9, 0x85, 0x85, 0x85, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2D, + 0xA0, 0x83, 0x2C, 0x21, 0x30, 0x33, 0x29, 0x29, + 0x21, 0x33, 0x54, 0x42, 0x66, 0x55, 0xC4, 0x29, + 0x8B, 0x2C, 0x39, 0x28, 0x29, 0x31, 0x44, 0x58, + 0x23, 0x23, 0x21, 0x20, 0x30, 0xC4, 0xC4, 0x30, + 0x21, 0x20, 0xBB, 0xBC, 0xDA, 0xDB, 0xDC, 0xB2, + 0x83, 0xB4, 0x3C, 0x2F, 0xB9, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0xA7, 0xD4, 0x85, 0x82, + 0x3C, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x61, + 0x9E, 0x90, 0xDD, 0x21, 0x33, 0x25, 0x2C, 0x39, + 0x2A, 0x24, 0x24, 0x42, 0x62, 0x43, 0x34, 0x22, + 0x50, 0x39, 0x2C, 0x2C, 0x2A, 0x54, 0xD1, 0x58, + 0x22, 0x22, 0x2B, 0x22, 0x30, 0xC4, 0x30, 0x60, + 0x20, 0xDE, 0xBB, 0xD9, 0x84, 0x84, 0xDF, 0xA9, + 0xDB, 0xDB, 0x61, 0x27, 0x38, 0x4D, 0x56, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0x8D, 0xD9, 0xD5, 0xA6, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0xBB, + 0x85, 0xDB, 0xDD, 0x21, 0x22, 0x22, 0x3F, 0x39, + 0x2C, 0x2B, 0x25, 0x34, 0x62, 0x66, 0xD1, 0xC4, + 0x6B, 0x39, 0x2C, 0x39, 0x29, 0x21, 0x58, 0xCC, + 0x22, 0x21, 0x29, 0x23, 0x30, 0x30, 0x30, 0x5E, + 0x82, 0xBB, 0xE0, 0xB1, 0xE1, 0x9C, 0xD4, 0xDC, + 0x9D, 0xA9, 0xE2, 0x27, 0x27, 0x27, 0x4D, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4C, 0x48, 0xA8, 0xA8, 0xE3, 0x8C, + 0xC6, 0x3C, 0x27, 0x27, 0x27, 0xE4, 0xA6, 0xE5, + 0x83, 0xA9, 0xE6, 0xAF, 0x54, 0x2B, 0x8B, 0x39, + 0x39, 0x29, 0x20, 0x54, 0x42, 0x42, 0xB6, 0xCC, + 0x2A, 0x29, 0x39, 0x39, 0x2C, 0x2C, 0xCC, 0xCC, + 0x22, 0x20, 0x39, 0xE7, 0xC0, 0xD9, 0xA7, 0xBC, + 0x8D, 0xAA, 0x9C, 0xE8, 0x9C, 0x9D, 0xD4, 0xD4, + 0xD8, 0xA9, 0x84, 0xC7, 0x27, 0x27, 0x27, 0x2A, + 0x56, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x48, 0x50, 0xAA, 0xE3, 0xE3, 0xC0, + 0xA6, 0x9A, 0xBA, 0xC8, 0x9A, 0xDE, 0x9B, 0xD5, + 0xE8, 0xD8, 0xD5, 0x2E, 0x58, 0x33, 0x6B, 0x39, + 0x2C, 0x39, 0x29, 0x28, 0xD1, 0x43, 0xB6, 0xAF, + 0x23, 0x28, 0x2C, 0x39, 0x39, 0x8B, 0x30, 0x31, + 0x21, 0x20, 0x3F, 0xBB, 0xDF, 0xDF, 0xD5, 0xA8, + 0xD5, 0x9C, 0x8E, 0xB2, 0x9D, 0xE9, 0xD4, 0xD8, + 0x90, 0xB2, 0xA9, 0x8F, 0x27, 0x27, 0x27, 0x27, + 0x2F, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0xB9, 0x48, 0x48, 0x75, 0xE3, 0xAA, 0xAA, + 0xC0, 0xB4, 0xB4, 0xB4, 0x75, 0x9B, 0xD9, 0x83, + 0x9D, 0x90, 0xDF, 0xDD, 0x8A, 0x31, 0x4B, 0x2C, + 0x2C, 0x29, 0x2C, 0x3F, 0x6C, 0x55, 0xD1, 0x55, + 0x54, 0x29, 0x28, 0x39, 0x39, 0x6B, 0x24, 0x60, + 0x20, 0x2B, 0x3F, 0xA7, 0xB1, 0x9D, 0xA9, 0x8E, + 0xE5, 0xE5, 0xDF, 0xE0, 0xA9, 0x9D, 0xDF, 0xDF, + 0xEA, 0x9D, 0xB2, 0x84, 0xAA, 0x27, 0x27, 0x27, + 0x27, 0x35, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x48, 0x48, 0xA6, 0x9B, 0xE3, 0xAA, + 0xAA, 0x9B, 0x9B, 0x9B, 0xAA, 0xE3, 0xD5, 0xD4, + 0x9D, 0xA9, 0xA9, 0x9D, 0xEB, 0xAF, 0x23, 0x28, + 0x2C, 0x29, 0x28, 0x39, 0x54, 0xCC, 0xAF, 0x55, + 0x30, 0x29, 0x2B, 0x2C, 0x39, 0x39, 0x2B, 0xC4, + 0x2B, 0x29, 0x39, 0xA7, 0x8E, 0x9D, 0x83, 0xE5, + 0xB1, 0xDB, 0xDC, 0xE0, 0xDC, 0x84, 0xE9, 0x84, + 0x83, 0xD4, 0xEC, 0x83, 0x8F, 0xE4, 0x27, 0x27, + 0x27, 0x27, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x40, 0x50, 0x9A, 0x75, 0xE3, 0xE3, + 0xE3, 0xD9, 0x8D, 0xAA, 0xD9, 0xA8, 0xB2, 0xDC, + 0xB2, 0x8D, 0x84, 0xEA, 0xB1, 0xEB, 0x54, 0x29, + 0x28, 0x2C, 0x2A, 0x28, 0x2B, 0x78, 0xCC, 0x58, + 0xCB, 0x20, 0x20, 0x29, 0x39, 0x39, 0x2C, 0x25, + 0x29, 0x2C, 0x39, 0xBB, 0xD9, 0xD9, 0x9D, 0x9D, + 0xB2, 0xB1, 0xD4, 0xDB, 0xB1, 0x9D, 0xD4, 0xEA, + 0xB1, 0x8D, 0xD8, 0x8E, 0x8F, 0xAA, 0x27, 0x27, + 0x27, 0x3D, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x47, 0xE4, 0xA6, 0x75, 0xAA, 0xA8, + 0x9C, 0x9C, 0xE1, 0x9C, 0x9C, 0x8E, 0xD8, 0x9D, + 0xA9, 0xDB, 0xA9, 0xDC, 0xD8, 0xDA, 0xD4, 0x2B, + 0x20, 0x2C, 0x28, 0x2A, 0x28, 0x63, 0x31, 0x58, + 0xCB, 0x24, 0x20, 0x2B, 0x2C, 0x39, 0x6B, 0x21, + 0x39, 0x6B, 0x2C, 0xC0, 0xE0, 0xB1, 0xB2, 0x9D, + 0x8E, 0xD8, 0xE0, 0xD9, 0x84, 0xDB, 0xD8, 0xB1, + 0x8E, 0xB2, 0xE2, 0x9C, 0x83, 0x9E, 0xBC, 0x3D, + 0xD3, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0x4F, 0x27, 0x61, 0xA6, 0x9B, 0xE3, 0xA9, + 0xE9, 0xD4, 0xDA, 0xDB, 0x8E, 0xE1, 0xE9, 0x8E, + 0xD4, 0xA8, 0xE0, 0x84, 0xE8, 0xB1, 0xDC, 0x9D, + 0x20, 0x29, 0x29, 0x2B, 0x2C, 0x54, 0x78, 0xCC, + 0x78, 0x33, 0x2A, 0x20, 0x29, 0x39, 0x50, 0x2A, + 0x6B, 0x8B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xA9, + 0xB2, 0xDC, 0x8E, 0xDC, 0xE1, 0xDA, 0xA9, 0x8E, + 0xEA, 0xE2, 0x83, 0xE8, 0x8E, 0x83, 0xE2, 0xED, + 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0xC9, 0x27, 0x27, 0xE4, 0xA6, 0x9B, 0xD5, 0xA8, + 0xD4, 0xB2, 0xD8, 0xDA, 0xD9, 0xE8, 0xE9, 0xE8, + 0xD8, 0xB1, 0xDA, 0xB2, 0xE9, 0x8E, 0xEC, 0xDA, + 0x22, 0x20, 0x39, 0x2B, 0x39, 0x24, 0xC4, 0x30, + 0x30, 0x54, 0x22, 0x29, 0x29, 0x39, 0x48, 0x2C, + 0x39, 0x6B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xB2, + 0xB2, 0x8E, 0xA9, 0xD8, 0xDA, 0xB1, 0xA9, 0xDA, + 0x9C, 0xDC, 0x8E, 0xD4, 0xE8, 0xE8, 0x8F, 0x9B, + 0x4F, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x6B, + 0x27, 0x27, 0x27, 0xD7, 0xDE, 0xAA, 0xE3, 0xA8, + 0xB2, 0xD5, 0xE5, 0x90, 0xE2, 0xA9, 0xE9, 0xB2, + 0xDA, 0xB2, 0xE1, 0xB2, 0xE9, 0x8E, 0xDA, 0xDF, + 0x78, 0x2A, 0x2C, 0x2A, 0x6B, 0x28, 0x23, 0x54, + 0x63, 0xC4, 0x33, 0x28, 0x2C, 0x39, 0x47, 0x39, + 0x28, 0x2C, 0x29, 0xBB, 0x8D, 0x83, 0xE9, 0xD4, + 0xB2, 0xE9, 0xE9, 0xE8, 0xD4, 0xD8, 0xD4, 0xA9, + 0xDA, 0xB2, 0xE9, 0xA8, 0xB2, 0xA8, 0xD5, 0xAA, + 0xC6, 0x56, 0x56, 0x56, 0x56, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0xC9, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0x9B, 0xE3, 0x8E, + 0x9D, 0x8E, 0xB2, 0xE8, 0xE8, 0x8E, 0xB2, 0xDA, + 0xB2, 0x8E, 0xEC, 0xB2, 0x8E, 0xB2, 0xBB, 0x58, + 0xAF, 0x33, 0x50, 0x39, 0x6B, 0x39, 0x29, 0x20, + 0x33, 0x30, 0x78, 0x23, 0x6B, 0x6B, 0x48, 0x6B, + 0x2B, 0x2A, 0x29, 0xBB, 0xE5, 0x9C, 0xB1, 0xB2, + 0xE5, 0x84, 0x8E, 0x9C, 0x84, 0xB2, 0xB2, 0x9D, + 0x84, 0xDF, 0xA9, 0x84, 0x8E, 0xA8, 0xE3, 0x9B, + 0xA6, 0xD7, 0x80, 0x4F, 0x56, 0x56, 0x56, 0x4F, + 0x4F, 0x4F, 0x4F, 0x2A, 0x2D, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0xAA, 0xD5, 0xA9, + 0x9D, 0xB2, 0x90, 0xEA, 0xE9, 0xE2, 0xE1, 0x8E, + 0xB2, 0x9D, 0x8E, 0xB1, 0xA7, 0xEE, 0x63, 0xD1, + 0x2E, 0xCC, 0x28, 0x48, 0x8B, 0x47, 0x6B, 0x28, + 0x23, 0x78, 0x6C, 0x54, 0x29, 0x50, 0x50, 0x6B, + 0x23, 0x20, 0xBB, 0xBC, 0xBB, 0x8D, 0xE3, 0xDF, + 0x9C, 0xA9, 0x8D, 0xA8, 0xD9, 0x90, 0x9D, 0xA9, + 0xDC, 0xA9, 0x83, 0xB2, 0xA9, 0xD4, 0xE3, 0x9B, + 0x8C, 0xEF, 0x27, 0x27, 0x27, 0x3C, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0x84, + 0x9D, 0x84, 0x90, 0xB1, 0xA9, 0x9C, 0xD9, 0xB1, + 0xB2, 0xEA, 0xBB, 0x51, 0x24, 0x30, 0x30, 0x42, + 0x66, 0x58, 0x24, 0x48, 0x50, 0x3F, 0x20, 0x25, + 0x22, 0x60, 0x34, 0x30, 0x20, 0x8B, 0x8B, 0x39, + 0x54, 0x24, 0x2B, 0xC0, 0xC0, 0xC0, 0xBB, 0x9B, + 0xBC, 0xAA, 0xAA, 0xE3, 0xE3, 0x9C, 0xB2, 0xD4, + 0x83, 0xD8, 0xE8, 0x83, 0x84, 0xE8, 0xE5, 0x75, + 0x9A, 0xF0, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0xA8, + 0xA9, 0xD8, 0x8E, 0xEA, 0xA8, 0x9C, 0xD9, 0xE0, + 0xC0, 0x5E, 0x2C, 0x20, 0x54, 0x60, 0x30, 0x66, + 0xB6, 0xCC, 0x63, 0x3F, 0x8B, 0x28, 0x22, 0x33, + 0x23, 0x31, 0xAF, 0x31, 0x22, 0x6B, 0x6B, 0x29, + 0x30, 0x54, 0x22, 0x89, 0xBA, 0xED, 0xA6, 0x8C, + 0xB4, 0xC0, 0xB4, 0x75, 0x75, 0x9B, 0x9B, 0xE5, + 0xA9, 0xD5, 0x8E, 0x8E, 0x9C, 0xE3, 0x75, 0x8C, + 0xC8, 0xF1, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF1, 0x9A, 0xB4, 0x9B, 0xE3, + 0xE3, 0xA8, 0xE3, 0xE5, 0xAA, 0xBC, 0xC0, 0x9A, + 0x26, 0x29, 0x20, 0x24, 0x63, 0x60, 0x54, 0x43, + 0x34, 0xCB, 0x30, 0x39, 0x2C, 0x20, 0x24, 0x54, + 0x22, 0x34, 0x34, 0x31, 0x24, 0x3F, 0x2C, 0x2B, + 0x31, 0x30, 0x25, 0x2A, 0x6B, 0x29, 0x20, 0xF2, + 0xBA, 0xBF, 0xC8, 0x9A, 0xA6, 0xA6, 0x8C, 0xB4, + 0x9B, 0xAA, 0xAA, 0xAA, 0x9B, 0x75, 0xDE, 0xBF, + 0x81, 0xEF, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xEF, 0xBA, 0x9A, 0xB4, 0x75, + 0x9B, 0x9B, 0x9B, 0xC0, 0xB4, 0x9A, 0xA5, 0xC4, + 0x30, 0x28, 0x22, 0x33, 0x30, 0x30, 0x23, 0x34, + 0x31, 0x30, 0xC4, 0x2C, 0x2B, 0x22, 0x33, 0x63, + 0x21, 0x58, 0x6C, 0x60, 0x25, 0x39, 0x28, 0x2B, + 0xCC, 0x6C, 0x63, 0x20, 0x6B, 0x28, 0x2B, 0x20, + 0x63, 0x43, 0xF3, 0xEF, 0xF0, 0x81, 0xBA, 0xF4, + 0xF4, 0xA6, 0xDE, 0x8C, 0xA6, 0x9A, 0xBA, 0x81, + 0xB0, 0xE4, 0xA1, 0x20, 0x20, 0x23, 0x31, 0xC4, + 0x30, 0x24, 0x33, 0x31, 0x31, 0x60, 0x43, 0x35, + 0x35, 0x55, 0x6C, 0xEF, 0x81, 0xC8, 0x9A, 0xA6, + 0xB4, 0xB4, 0x8C, 0xA6, 0xBA, 0x68, 0x30, 0x30, + 0x30, 0x2B, 0x25, 0x54, 0xC4, 0x54, 0x24, 0x78, + 0x63, 0x63, 0x30, 0x29, 0x21, 0x24, 0x54, 0x63, + 0x23, 0x34, 0xCB, 0x30, 0x25, 0x39, 0x20, 0x20, + 0x58, 0x34, 0x60, 0x23, 0x6B, 0x29, 0x28, 0x20, + 0x22, 0xB6, 0x42, 0xB6, 0x58, 0x54, 0xF5, 0xD7, + 0xA5, 0xBA, 0xBA, 0xBA, 0xBA, 0x81, 0xA5, 0xF1, + 0xE4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x31, 0x60, + 0x54, 0x28, 0x2B, 0x22, 0x33, 0x30, 0x43, 0x35, + 0x66, 0xD1, 0x34, 0xE4, 0xEF, 0x81, 0xC8, 0x9A, + 0x9A, 0xC8, 0xC8, 0x81, 0xF6, 0x31, 0x63, 0x31, + 0x78, 0x2B, 0x54, 0x63, 0x54, 0x24, 0x23, 0x54, + 0x63, 0x54, 0x63, 0x2C, 0x23, 0x33, 0x63, 0x54, + 0x25, 0x31, 0x78, 0x30, 0x25, 0x3F, 0x20, 0x20, + 0xAF, 0x58, 0xCC, 0x33, 0x39, 0x29, 0x29, 0x2A, + 0x29, 0x58, 0x43, 0x42, 0xD1, 0xCB, 0x2C, 0x2C, + 0x37, 0xCD, 0xEF, 0xB0, 0xF0, 0xB0, 0xEF, 0xE4, + 0x63, 0x20, 0x20, 0x2C, 0x2C, 0x21, 0xCB, 0x78, + 0x54, 0x39, 0x39, 0x28, 0x2B, 0x28, 0x2B, 0xCB, + 0x55, 0xB6, 0xD1, 0x28, 0xE4, 0xD7, 0xB8, 0xF0, + 0xA5, 0xB0, 0xEF, 0x26, 0x23, 0x54, 0x31, 0x58, + 0xCB, 0x20, 0x63, 0x63, 0x25, 0x2B, 0x54, 0x78, + 0x30, 0x63, 0x54, 0x28, 0x33, 0x63, 0x63, 0x33, + 0x54, 0x78, 0xC4, 0x30, 0x24, 0x2C, 0x22, 0x22, + 0x55, 0x55, 0x34, 0x30, 0x28, 0x2C, 0x29, 0x29, + 0x28, 0x30, 0xB6, 0x42, 0x43, 0x55, 0x22, 0x29, + 0x2C, 0x2B, 0x2B, 0x3F, 0xE4, 0xE4, 0x43, 0x66, + 0x30, 0x23, 0x24, 0x2A, 0x28, 0x2B, 0x54, 0x63, + 0x33, 0x39, 0x28, 0x20, 0x20, 0x20, 0x2B, 0x31, + 0x30, 0xD1, 0x43, 0x30, 0x39, 0x28, 0xE4, 0xE4, + 0xD7, 0xF5, 0x2B, 0x6B, 0x20, 0x30, 0x34, 0xD1, + 0x60, 0x23, 0x63, 0x54, 0x22, 0x47, 0x60, 0xCB, + 0xC4, 0xC4, 0x25, 0x22, 0x54, 0xC4, 0x63, 0x23, + 0xC4, 0xC4, 0x63, 0xC4, 0x23, 0x2A, 0x24, 0x22, + 0x55, 0x55, 0xAF, 0x6C, 0x22, 0x39, 0x2C, 0x39, + 0x28, 0x23, 0xD1, 0x43, 0x42, 0x8A, 0x63, 0x39, + 0x39, 0x2A, 0x20, 0x6B, 0x33, 0xCC, 0xD1, 0xB6, + 0x30, 0x24, 0x54, 0x63, 0x31, 0xCC, 0xCC, 0xCB, + 0xC4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x39, 0x30, + 0x30, 0x6C, 0x43, 0x43, 0x6C, 0x63, 0x25, 0x24, + 0x63, 0x63, 0x63, 0x25, 0x63, 0xCC, 0xD1, 0x34, + 0x63, 0x25, 0x54, 0x25, 0x2A, 0x28, 0x31, 0xCB, + 0x63, 0x78, 0x24, 0x33, 0xC4, 0xC4, 0x33, 0x2C, + 0xC4, 0x54, 0x54, 0x30, 0x21, 0x22, 0x25, 0x23, + 0x55, 0x55, 0xD1, 0x58, 0x33, 0x6B, 0x2C, 0x39, + 0x39, 0x39, 0x34, 0x43, 0x42, 0x43, 0xCC, 0x2B, + 0x28, 0x29, 0x20, 0x28, 0x21, 0x30, 0xCC, 0xAF, + 0x54, 0x23, 0xC4, 0x54, 0x58, 0x2E, 0x35, 0x42, + 0x55, 0x54, 0x8B, 0x2A, 0x20, 0x20, 0x28, 0x22, + 0x78, 0x30, 0xD1, 0x43, 0x44, 0x6C, 0xC4, 0xC4, + 0x60, 0x31, 0x31, 0x63, 0x6C, 0xAF, 0xCC, 0xCB, + 0x24, 0x25, 0x33, 0x23, 0x2C, 0x24, 0x31, 0x30, + 0x63, 0xC4, 0x21, 0x54, 0x30, 0x63, 0x24, 0x2A, + 0x54, 0x63, 0x54, 0xC4, 0x2B, 0x24, 0x33, 0x24, + 0x34, 0x55, 0xD1, 0x55, 0x30, 0x28, 0x29, 0x39, + 0x39, 0x8B, 0x63, 0x55, 0x42, 0x66, 0xB6, 0x25, + 0x29, 0x29, 0x29, 0x28, 0x2A, 0x54, 0x78, 0x6C, + 0x23, 0x20, 0x25, 0x30, 0xCB, 0x62, 0x35, 0x35, + 0x35, 0x44, 0x24, 0x6B, 0x29, 0x20, 0x2A, 0x39, + 0x28, 0x63, 0x34, 0xB6, 0x34, 0xCB, 0x63, 0x30, + 0x31, 0x31, 0x30, 0x30, 0xCC, 0x60, 0x63, 0xC4, + 0x20, 0x33, 0x25, 0x20, 0x48, 0x33, 0x30, 0x54, + 0x78, 0x54, 0x2B, 0x63, 0x30, 0x63, 0x23, 0x22, + 0x63, 0x63, 0x63, 0x33, 0x28, 0x25, 0x54, 0x24, + 0x78, 0xAF, 0xD1, 0xD1, 0xCC, 0x22, 0x39, 0x39, + 0x2C, 0x3F, 0x2B, 0x34, 0xB6, 0x43, 0x43, 0xC4, + 0x2B, 0x28, 0x39, 0x50, 0x2C, 0x24, 0x63, 0x78, + 0x21, 0x2C, 0x2A, 0x23, 0x54, 0xD1, 0x35, 0x35, + 0x35, 0x35, 0x55, 0x22, 0x39, 0x2C, 0x2C, 0x2C, + 0x20, 0x30, 0xCC, 0x6C, 0xCB, 0x30, 0x54, 0x30, + 0x78, 0x63, 0x78, 0x30, 0x54, 0x78, 0x30, 0x23, + 0x2B, 0x33, 0x24, 0x28, 0x39, 0x24, 0x54, 0x30, + 0x78, 0x33, 0x25, 0xC4, 0xC4, 0x33, 0x39, 0x25, + 0xC4, 0x63, 0xC4, 0x24, 0x20, 0x54, 0x54, 0x25, + 0x63, 0xCC, 0xD1, 0xB6, 0x55, 0x54, 0x39, 0x29, + 0x39, 0x2C, 0x6B, 0x30, 0xAF, 0xB6, 0xB6, 0x60, + 0x22, 0x2A, 0x2C, 0x39, 0x2C, 0x21, 0x54, 0x63, + 0x21, 0x50, 0x2C, 0x2C, 0x2B, 0x25, 0x62, 0x35, + 0x35, 0x35, 0x35, 0xCC, 0x2B, 0x29, 0x2B, 0x20, + 0x23, 0x25, 0xC4, 0x30, 0xC4, 0x63, 0x63, 0x63, + 0x63, 0x33, 0x24, 0x31, 0x31, 0x31, 0x54, 0x28, + 0x24, 0x25, 0x22, 0x6B, 0x28, 0x24, 0xC4, 0x78, + 0x30, 0x24, 0x63, 0xC4, 0x54, 0x23, 0x29, 0x63, + 0xC4, 0x54, 0xC4, 0x21, 0x24, 0x54, 0x54, 0x25, + 0x30, 0xCB, 0xD1, 0xB6, 0x55, 0x63, 0x28, 0x29, + 0x39, 0x39, 0x48, 0x33, 0x58, 0x44, 0xB6, 0x60, + 0x24, 0x20, 0x2B, 0x28, 0x2A, 0x22, 0x54, 0x63, + 0x21, 0x48, 0x2A, 0x2B, 0x39, 0x21, 0xB6, 0x35, + 0x35, 0x35, 0x35, 0x42, 0x23, 0x29, 0x2A, 0x2B, + 0x23, 0x25, 0x54, 0x54, 0x54, 0x63, 0x63, 0x30, + 0x25, 0x2B, 0x31, 0x31, 0x31, 0x31, 0x21, 0x2C, + 0x33, 0x25, 0x21, 0x39, 0x20, 0x25, 0x30, 0x78, + 0xC4, 0x23, 0xC4, 0x30, 0x54, 0x20, 0x28, 0x63, + 0x63, 0x63, 0x63, 0x20, 0x25, 0x54, 0x54, 0x20, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xC2, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0x90, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xA0, 0x00, + 0x8F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0x83, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0x1F, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0x3F, 0xF7, 0x8F, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0x7F, 0xF7, + 0xC7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0x6F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0x7F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0x7F, 0xE7, 0xEF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0x7B, 0xFF, + 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x7B, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x79, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x7C, 0xFF, 0xCF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0x77, 0xFF, + 0xDF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x3F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0xBF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x9F, 0xFF, 0x3F, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1F, 0x9F, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1F, + 0x8F, 0xFE, 0x7F, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0xC7, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0F, 0xF7, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x07, 0xFB, 0xF3, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x07, + 0xFD, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x03, 0xFE, 0x8F, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x03, 0xFE, 0x1F, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xBF, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFE, 0xBF, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x9F, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFE, 0x87, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFD, 0x33, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0xF3, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0x8B, 0xF9, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x27, 0xF8, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x07, 0xF8, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0x8F, 0xF8, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xE3, 0xF8, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xF8, 0x78, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x7F, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x20, + 0x7F, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x10, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h index 8bfaeff9b..cd4503cc6 100644 --- a/include/asm-sparc64/signal.h +++ b/include/asm-sparc64/signal.h @@ -1,4 +1,4 @@ -/* $Id: signal.h,v 1.2 1997/03/03 16:51:57 jj Exp $ */ +/* $Id: signal.h,v 1.3 1997/04/18 14:34:47 jj Exp $ */ #ifndef _ASMSPARC64_SIGNAL_H #define _ASMSPARC64_SIGNAL_H @@ -83,7 +83,7 @@ #ifndef __ASSEMBLY__ typedef unsigned long sigset_t; -typedef unsigned int sigset32_t; +typedef unsigned int sigset_t32; #ifdef __KERNEL__ #include @@ -165,10 +165,8 @@ struct sigaction { struct sigaction32 { unsigned sa_handler; - sigset32_t sa_mask; + sigset_t32 sa_mask; unsigned int sa_flags; - - /* XXX 32-bit func ptr... */ unsigned sa_restorer; /* not used by Linux/SPARC yet */ }; diff --git a/include/asm-sparc64/softirq.h b/include/asm-sparc64/softirq.h index e50e95793..3e5d7cc72 100644 --- a/include/asm-sparc64/softirq.h +++ b/include/asm-sparc64/softirq.h @@ -34,6 +34,12 @@ do { int ent = nr; \ bh_mask |= 1 << ent; \ } while(0) +#define remove_bh(nr) \ +do { int ent = nr; \ + bh_base[ent] = NULL; \ + bh_mask &= ~(1 << ent); \ +} while(0) + #define mark_bh(nr) (bh_active |= (1 << (nr))) #define disable_bh(nr) \ diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h index 6b80857c2..dbb569f18 100644 --- a/include/asm-sparc64/spinlock.h +++ b/include/asm-sparc64/spinlock.h @@ -16,6 +16,7 @@ typedef struct { } spinlock_t; #define spin_lock_init(lock) do { } while(0) #define spin_lock(lock) do { } while(0) #define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) #define spin_unlock(lock) do { } while(0) #define spin_lock_irq(lock) cli() #define spin_unlock_irq(lock) sti() @@ -23,6 +24,33 @@ typedef struct { } spinlock_t; #define spin_lock_irqsave(lock, flags) save_and_cli(flags) #define spin_unlock_irqrestore(lock, flags) restore_flags(flags) +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) + #else /* !(__SMP__) */ #error SMP not supported on sparc64 #endif /* __SMP__ */ diff --git a/include/asm-sparc64/stat.h b/include/asm-sparc64/stat.h index 470f6f8e2..0d8322525 100644 --- a/include/asm-sparc64/stat.h +++ b/include/asm-sparc64/stat.h @@ -1,23 +1,9 @@ -/* $Id: stat.h,v 1.2 1997/04/16 14:52:34 jj Exp $ */ +/* $Id: stat.h,v 1.3 1997/04/18 14:34:43 jj Exp $ */ #ifndef _SPARC64_STAT_H #define _SPARC64_STAT_H #include -struct __old_kernel_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - struct stat32 { __kernel_dev_t32 st_dev; __kernel_ino_t32 st_ino; @@ -48,11 +34,8 @@ struct stat { dev_t st_rdev; off_t st_size; time_t st_atime; - unsigned long __unused1; time_t st_mtime; - unsigned long __unused2; time_t st_ctime; - unsigned long __unused3; off_t st_blksize; off_t st_blocks; unsigned long __unused4[2]; diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 31d086c6c..51750311c 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -1,4 +1,4 @@ -/* $Id: unistd.h,v 1.3 1997/04/10 23:32:51 davem Exp $ */ +/* $Id: unistd.h,v 1.4 1997/04/19 08:52:25 jj Exp $ */ #ifndef _SPARC64_UNISTD_H #define _SPARC64_UNISTD_H @@ -270,7 +270,7 @@ #define __NR__sysctl 251 #define __NR_getsid 252 #define __NR_fdatasync 253 -#define __NR_nfsctl 254 +#define __NR_nfsservctl 254 #define __NR_aplib 255 #define _syscall0(type,name) \ diff --git a/include/linux/fs.h b/include/linux/fs.h index c1dada8ee..85e04d184 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -36,7 +36,7 @@ /* And dynamically-tunable limits and defaults: */ extern int max_inodes, nr_inodes; extern int max_files, nr_files; -#define NR_INODE 3072 /* this should be bigger than NR_FILE */ +#define NR_INODE 4096 /* this should be bigger than NR_FILE */ #define NR_FILE 1024 /* this can well be larger on a larger system */ #define MAY_EXEC 1 @@ -128,7 +128,7 @@ extern int max_files, nr_files; #include extern void buffer_init(void); -extern unsigned long inode_init(unsigned long start, unsigned long end); +extern void inode_init(void); extern unsigned long file_table_init(unsigned long start, unsigned long end); extern unsigned long name_cache_init(unsigned long start, unsigned long end); @@ -179,7 +179,7 @@ struct buffer_head { unsigned long b_lru_time; /* Time when this buffer was * last used. */ struct wait_queue * b_wait; - struct buffer_head * b_prev; /* doubly linked list of hash-queue */ + struct buffer_head ** b_pprev; /* doubly linked list of hash-queue */ struct buffer_head * b_prev_free; /* doubly linked list of buffers */ struct buffer_head * b_reqnext; /* request queue */ }; @@ -270,8 +270,13 @@ struct iattr { #include struct inode { - kdev_t i_dev; + struct inode *i_hash_next; + struct inode **i_hash_pprev; + struct inode *i_next; + struct inode **i_pprev; unsigned long i_ino; + kdev_t i_dev; + unsigned short i_count; umode_t i_mode; nlink_t i_nlink; uid_t i_uid; @@ -293,11 +298,8 @@ struct inode { struct vm_area_struct *i_mmap; struct page *i_pages; struct dquot *i_dquot[MAXQUOTAS]; - struct inode *i_next, *i_prev; - struct inode *i_hash_next, *i_hash_prev; struct inode *i_bound_to, *i_bound_by; struct inode *i_mount; - unsigned short i_count; unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; diff --git a/include/linux/mm.h b/include/linux/mm.h index 64c5c344f..9572b3415 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -125,7 +125,7 @@ typedef struct page { unsigned dirty:16, age:8; struct wait_queue *wait; - struct page *prev_hash; + struct page **pprev_hash; struct buffer_head * buffers; unsigned long swap_unlock_entry; unsigned long map_nr; /* page->map_nr == page - mem_map */ diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 868874192..9af62e4a2 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -71,20 +71,12 @@ static inline struct page *find_page(struct inode * inode, unsigned long offset) static inline void remove_page_from_hash_queue(struct page * page) { - struct page **p; - struct page *next_hash, *prev_hash; - - next_hash = page->next_hash; - prev_hash = page->prev_hash; - page->next_hash = NULL; - page->prev_hash = NULL; - if (next_hash) - next_hash->prev_hash = prev_hash; - if (prev_hash) - prev_hash->next_hash = next_hash; - p = page_hash(page->inode,page->offset); - if (*p == page) - *p = next_hash; + if(page->pprev_hash) { + if(page->next_hash) + page->next_hash->pprev_hash = page->pprev_hash; + *page->pprev_hash = page->next_hash; + page->pprev_hash = NULL; + } page_cache_size--; } @@ -93,10 +85,10 @@ static inline void __add_page_to_hash_queue(struct page * page, struct page **p) page_cache_size++; set_bit(PG_referenced, &page->flags); page->age = PAGE_AGE_VALUE; - page->prev_hash = NULL; - if ((page->next_hash = *p) != NULL) - page->next_hash->prev_hash = page; + if((page->next_hash = *p) != NULL) + (*p)->pprev_hash = &page->next_hash; *p = page; + page->pprev_hash = p; } static inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long offset) @@ -104,7 +96,6 @@ static inline void add_page_to_hash_queue(struct page * page, struct inode * ino __add_page_to_hash_queue(page, page_hash(inode,offset)); } - static inline void remove_page_from_inode_queue(struct page * page) { struct inode * inode = page->inode; diff --git a/include/linux/pci.h b/include/linux/pci.h index cef9cc4b7..58c4e026b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -593,6 +593,7 @@ #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 #define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 #define PCI_DEVICE_ID_INTEL_82437VX 0x7030 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 #define PCI_DEVICE_ID_INTEL_P6 0x84c4 #define PCI_VENDOR_ID_KTI 0x8e2e diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index efdae3a91..86a5e6417 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -20,12 +20,9 @@ #include #include -#define CONFIG_SKB_CHECK 0 - #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ - #define FREE_READ 1 #define FREE_WRITE 0 @@ -39,9 +36,6 @@ struct sk_buff_head struct sk_buff * prev; __u32 qlen; /* Must be same length as a pointer for using debugging */ -#if CONFIG_SKB_CHECK - int magic_debug_cookie; -#endif }; struct sk_buff @@ -49,9 +43,6 @@ struct sk_buff struct sk_buff * next; /* Next buffer in list */ struct sk_buff * prev; /* Previous buffer in list */ struct sk_buff_head * list; /* List we are on */ -#if CONFIG_SKB_CHECK - int magic_debug_cookie; -#endif struct sock *sk; /* Socket we are owned by */ unsigned long when; /* used to compute rtt's */ struct timeval stamp; /* Time we arrived */ @@ -95,8 +86,7 @@ struct sk_buff unsigned int len; /* Length of actual data */ unsigned int csum; /* Checksum */ - volatile char acked, /* Are we acked ? */ - used, /* Are we in use ? */ + volatile char used, /* Are we in use ? */ arp; /* Has IP/ARP resolution finished */ unsigned char tries, /* Times tried */ inclone, /* Inline clone */ @@ -141,12 +131,6 @@ struct sk_buff #define SK_RMEM_MAX 32767 #endif -#if CONFIG_SKB_CHECK -#define SK_FREED_SKB 0x0DE2C0DE -#define SK_GOOD_SKB 0xDEC0DED1 -#define SK_HEAD_SKB 0x12231298 -#endif - #ifdef __KERNEL__ /* * Handling routines are only of interest to the kernel @@ -245,14 +229,6 @@ extern __inline__ __u32 skb_queue_len(struct sk_buff_head *list_) return(list_->qlen); } -#if CONFIG_SKB_CHECK -extern int skb_check(struct sk_buff *skb,int,int, char *); -#define IS_SKB(skb) skb_check((skb), 0, __LINE__,__FILE__) -#define IS_SKB_HEAD(skb) skb_check((skb), 1, __LINE__,__FILE__) -#else -#define IS_SKB(skb) -#define IS_SKB_HEAD(skb) - extern __inline__ void skb_queue_head_init(struct sk_buff_head *list) { list->prev = (struct sk_buff *)list; @@ -535,9 +511,6 @@ extern __inline__ void skb_orphan(struct sk_buff *skb) skb->sk = NULL; } - -#endif - extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err); extern unsigned int datagram_poll(struct socket *sock, poll_table *wait); extern int skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size); diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 604f99f1c..0e01fba0f 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -121,6 +121,11 @@ enum NET_IPV4_ARP_CHECK_INTERVAL, NET_IPV4_ARP_CONFIRM_INTERVAL, NET_IPV4_ARP_CONFIRM_TIMEOUT, + NET_IPV4_TCP_HOE_RETRANSMITS, + NET_IPV4_TCP_SACK, + NET_IPV4_TCP_TSACK, + NET_IPV4_TCP_TIMESTAMPS, + NET_IPV4_TCP_WINDOW_SCALING, NET_IPV4_TCP_VEGAS_CONG_AVOID, NET_IPV4_FORWARDING, NET_IPV4_DEFAULT_TTL, diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 703422ef6..fcc6ad09f 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -20,14 +20,16 @@ int vread(char *buf, char *addr, int count); extern inline void set_pgdir(unsigned long address, pgd_t entry) { -#ifndef __mc68000__ +#if !defined(__mc68000__) && !defined(__sparc_v9__) struct task_struct * p; + read_lock(&tasklist_lock); for_each_task(p) { if (!p->mm) continue; *pgd_offset(p->mm,address) = entry; } + read_unlock(&tasklist_lock); #endif } diff --git a/include/linux/zorro.h b/include/linux/zorro.h new file mode 100644 index 000000000..e19289877 --- /dev/null +++ b/include/linux/zorro.h @@ -0,0 +1,1278 @@ +/* + * linux/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions + * + * Copyright (C) 1995 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef __ZORRO_H +#define __ZORRO_H + +#ifndef __ASSEMBLY__ + +/* + * Defined Board Manufacturers + * + * Please update arch/m68k/amiga/zorro.c if you make changes here + * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) + * and by looking at the NetBSD-Amiga kernel sources + */ + +#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ +#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ +#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ + +#define MANUF_KUPKE (0x00DD) /* Kupke */ +#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ + +#define MANUF_MEMPHIS (0x0100) /* Memphis */ +#define PROD_STORMBRINGER (0x00) /* Stormbringer */ + +#define MANUF_3_STATE (0x0200) /* 3-State */ +#define PROD_MEGAMIX_2000 (0x02) /* Megamix 2000 RAM */ + +#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ +#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ +#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ +#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ + +#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ +#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ +#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ +#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ +#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ +#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ +#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ +#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ +#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ +#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ +#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ +#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ +#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ +#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ +#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ +#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ +#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ + +#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ +#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ + +#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ +#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ + +#define MANUF_CARDCO (0x03EC) /* Cardco */ +#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ +#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ +#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ +#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ + +#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ +#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ + +#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ +#define PROD_AX2000 (0x01) /* AX2000 */ + +#define MANUF_ANAKIN (0x03F1) /* Anakin */ +#define PROD_EASYL (0x01) /* Easyl Tablet */ + +#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ +#define PROD_STARBOARD_II (0x00) /* StarBoard II */ +#define PROD_STARDRIVE (0x02) /* StarDrive */ +#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ +#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ +#define PROD_DELTA_RAM (0x20) /* Delta Card RAM */ +#define PROD_8_STAR_RAM (0x40) /* 8-Star RAM */ +#define PROD_8_STAR (0x41) /* 8-Star */ +#define PROD_VXL_RAM (0x44) /* VXL RAM */ +#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ +#define PROD_DELTA (0x60) /* Delta Card */ +#define PROD_MBX_1200 (0x81) /* MBX 1200 */ +#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ +#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ + +#define MANUF_ACCESS (0x03F4) /* Access Associates */ + +#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ + +#define MANUF_ASDG (0x03FF) /* ASDG */ +#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ +#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ +#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ +#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ + +#define MANUF_IMTRONICS (0x0404) /* Imtronics */ +#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ +#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ + +#define MANUF_AMERISTAR (0x041D) /* Ameristar */ +#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ +#define PROD_A560 (0x09) /* Arcnet Card */ +#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ + +#define MANUF_SUPRA (0x0420) /* Supra */ +#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ +#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ +#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ +#define PROD_SUPRA_500XP (0x09) /* 500XP/2000 RAM */ +#define PROD_SUPRA_500RX (0x0A) /* 500RX/2000 RAM */ +#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ +#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ +#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ +#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ + +#define MANUF_CSA (0x0422) /* Computer Systems Ass. */ +#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ +#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ + +#define MANUF_MTEC2 (0x0502) /* M-Tech */ +#define PROD_AT500_2 (0x03) /* AT500 RAM */ + +#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ +#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ + +#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ +#define PROD_BYTEBOX_A500 (0x00) /* A500 */ + +#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ + +#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ +#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ +#define PROD_RAPID_FIRE (0x0F) /* Rapid Fire SCSI Controller */ +#define PROD_DKB_1202 (0x10) /* DKB 1202 RAM */ +#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ +#define PROD_WILDFIRE_060 (0x17) /* WildFire 060 Turbo Board */ +#define PROD_WILDFIRE_060_2 (0xFF) /* WildFire 060 Turbo Board */ + +#define MANUF_GVP (0x07E1) /* Great Valley Products */ +#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ +#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ +#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ +#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ +#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ +#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ +#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works + for this product code also */ +#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ +#define PROD_GVP (0x0B) /* This code is used by a wide range of + GVP products - use the epc to + identify it correctly */ +#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ +#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ +#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ +#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ +#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ +/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ + +#define MANUF_SYNERGY (0x07E5) /* Synergy */ + +#define MANUF_XETEC (0x07E6) /* Xetec */ +#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ +#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ + +#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ +#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ +#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ +#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ +#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ +#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ + +#define MANUF_XEBEC (0x07EC) /* Xebec */ + +#define MANUF_SPIRIT (0x07F2) /* Spirit */ +#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ +#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ + +#define MANUF_BSC (0x07FE) /* BSC */ +#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ + +#define MANUF_BSC3 (0x0801) /* BSC */ +#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ +#define PROD_ALF_2_SCSI_2 (0x02) /* ALF 2 SCSI Controller */ +#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ + +#define MANUF_C_LTD (0x0802) /* C Ltd. */ +#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ +#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ + +#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ +#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ + +#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ +#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ + +#define MANUF_ICD (0x0817) /* ICD */ +#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ + +#define MANUF_KUPKE2 (0x0819) /* Kupke */ +#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ +#define PROD_GOLEM_BOX (0x03) /* Golem Box */ +#define PROD_KUPKE_TURBO (0x04) /* 030/882 Turbo Board */ +#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ + +#define MANUF_GVP4 (0x081D) /* Great Valley Products */ +#define PROD_A2000_RAM8 (0x09) /* A2000-RAM8/2 */ + +#define MANUF_INTERWORKS_NET (0x081E) /* Interworks Network */ + +#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ +#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ + +#define MANUF_BSC2 (0x082C) /* BSC */ +#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ +#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ +#define PROD_ALPHA_RAM_1200 (0x07) /* Alpha RAM 1200 */ +#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ +#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ +#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ +#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ +#define PROD_BSC_FRAEMBUFFER (0x20) /* Framebuffer */ +#define PROD_GRAFFITI_RAM (0x21) /* Graffiti Graphics Board */ +#define PROD_GRAFFITI_REG (0x22) +#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ +#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ + +#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ +#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ +#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ + +#define MANUF_IMPULSE (0x0838) /* Impulse */ +#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ + +#define MANUF_IVS (0x0840) /* IVS */ +#define PROD_GRANDSLAM_PIC_2 (0x02) /* GrandSlam PIC 2 RAM */ +#define PROD_GRANDSLAM_PIC_1 (0x04) /* GrandSlam PIC 1 RAM */ +#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ +#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ +#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ +#define PROD_META_4 (0x40) /* Meta-4 RAM */ +#define PROD_WAVETOOLS (0xBF) /* Wavetools Sound Board */ +#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ +#define PROD_VECTOR_2 (0xF4) /* Vector SCSI Controller */ + +#define MANUF_VECTOR (0x0841) /* Vector */ +#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ + +#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ +#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ +#define PROD_VISIONA_REG (0x02) +#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ +#define PROD_MERLIN_REG (0x04) +#define PROD_MERLIN_REG_2 (0xC9) + +#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ +#define PROD_AMIGANET (0x01) /* Amiganet Board */ + +#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ +#define PROD_AD1012 (0x01) /* AD1012 Sound Board */ +#define PROD_AD516 (0x02) /* AD516 Sound Board */ +#define PROD_DD512 (0x03) /* DD512 Sound Board */ + +#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ +#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ + +#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ +#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ +#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ + +#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ +#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ +#define PROD_GDA_1_REG (0x01) + +#define MANUF_ROCTEC (0x0860) /* RocTec */ +#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ +#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ + +#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ +#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ + +#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ +#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ + +#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ +#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ +#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ +#define PROD_MVD_819 (0x07) /* MVD 819 */ + +#define MANUF_DELACOMP (0x0873) /* DelaComp */ +#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ + +#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ +#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board */ +#define PROD_DOMINO_REG (0x02) +#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II/II+ Graphics Board */ +#define PROD_PICASSO_II_REG (0x0C) +#define PROD_PICASSO_II_SEGM (0x0D) /* Picasso II/II+ (Segmented Mode) */ +#define PROD_PICASSO_IV (0x15) /* Picassio IV Graphics Board */ +#define PROD_PICASSO_IV_2 (0x16) +#define PROD_PICASSO_IV_3 (0x17) +#define PROD_PICASSO_IV_4 (0x18) +#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ + +#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ +#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ +#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ + +#define MANUF_AMITRIX (0x0880) /* Amitrix */ +#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ +#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ + +#define MANUF_ARMAX (0x0885) /* ArMax */ +#define PROD_OMNIBUS (0x00) /* OmniBus Graphics Board */ + +#define MANUF_NEWTEK (0x088F) /* NewTek */ +#define PROD_VIDEOTOASTER (0x00) /* VideoToaster */ + +#define MANUF_MTEC (0x0890) /* M-Tech Germany */ +#define PROD_AT500 (0x01) /* AT500 IDE Controller */ +#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ +#define PROD_MTEC_68020I (0x06) /* 68020i Turbo Board */ +#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ +#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ + +#define MANUF_GVP2 (0x0891) /* Great Valley Products */ +#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ +#define PROD_SPECTRUM_REG (0x02) + +#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ +#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ +#define PROD_PICCOLO_REG (0x06) +#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ +#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ +#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ +#define PROD_SD64_REG (0x0B) + +#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ +#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ + +#define MANUF_ELBOX (0x089E) /* ElBox Computer */ +#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ + +#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ +#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ +#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ + +#define MANUF_MICRONIK (0x0A50) /* Micronik */ +#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ + +#define MANUF_MEGA_MICRO (0x1000) /* MegaMicro */ +#define PROD_SCRAM_500_SCSI (0x03) /* SCRAM 500 SCSI Controller */ +#define PROD_SCRAM_500_RAM (0x04) /* SCRAM 500 RAM */ + +#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ +#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_KUPKE3 (0x1248) /* Kupke */ +#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ + +#define MANUF_ITH (0x1388) /* ITH */ +#define PROD_ISDN_MASTER_II (0x01) /* ISDN-Master II */ + +#define MANUF_VMC (0x1389) /* VMC */ +#define PROD_ISDN_BLASTER_Z2 (0x01) /* ISDN Blaster Z2 */ +#define PROD_HYPERCOM_4 (0x02) /* HyperCom 4 */ + +#define MANUF_INFORMATION (0x157C) /* Information */ +#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ + +#define MANUF_VORTEX (0x2017) /* Vortex */ +#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ +#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ +#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ + +#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ +#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ +#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ + +#define MANUF_READYSOFT (0x2100) /* ReadySoft */ +#define PROD_AMAX (0x01) /* AMax II/IV */ + +#define MANUF_PHASE5 (0x2140) /* Phase5 */ +#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ +#define PROD_BLIZZARD (0x02) /* Blizzard */ +#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ +#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ +#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ +#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ +#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ +#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ +#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ +#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ +#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ +#define PROD_CYBERVISION3D_PRT (0x32) /* CyberVision64-3D Prototype */ +#define PROD_CYBERVISION3D (0x43) /* CyberVision64-3D Graphics Board */ + +#define MANUF_DPS (0x2169) /* DPS */ +#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ + +#define MANUF_APOLLO2 (0x2200) /* Apollo */ +#define PROD_A620 (0x00) /* A620 68020 Accelerator */ +#define PROD_A620_2 (0x01) /* A620 68020 Accelerator */ + +#define MANUF_APOLLO (0x2222) /* Apollo */ +#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ +#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ + +#define MANUF_PETSOFF (0x38A5) /* Petsoff LP */ +#define PROD_DELFINA (0x00) /* Delfina DSP */ + +#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ +#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ + +#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ +#define PROD_MAESTRO (0x03) /* Maestro */ +#define PROD_VLAB (0x04) /* VLab */ +#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ +#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ +#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ +#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ +#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ +#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ +#define PROD_ALTAIS (0x13) /* Altais Graphics Board */ +#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ + +#define MANUF_COMBITEC (0x6766) /* Combitec */ + +#define MANUF_SKI (0x8000) /* SKI Peripherals */ +#define PROD_MAST_FIREBALL (0x08) /* M.A.S.T. Fireball SCSI Controller */ +#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ + +#define MANUF_CAMERON (0xAA01) /* Cameron */ +#define PROD_PERSONAL_A4 (0x10) /* Personal A4 */ + +#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ +#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ + + +/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ + +#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ +#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ + +#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ +#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ + +#define MANUF_VECTOR2 (0x07DB) /* Vector */ +#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ +#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ +#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ +#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ + + +/* + * GVP's identifies most of their product through the 'extended + * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK + * before the identification. + */ + +#define GVP_PRODMASK (0xf8) +#define GVP_SCSICLKMASK (0x01) + +enum GVP_ident { + GVP_GFORCE_040 = 0x20, + GVP_GFORCE_040_SCSI = 0x30, + GVP_A1291_SCSI = 0x40, + GVP_COMBO_R4 = 0x60, + GVP_COMBO_R4_SCSI = 0x70, + GVP_PHONEPAK = 0x78, + GVP_IOEXT = 0x98, + GVP_GFORCE_030 = 0xa0, + GVP_GFORCE_030_SCSI = 0xb0, + GVP_A530 = 0xc0, + GVP_A530_SCSI = 0xd0, + GVP_COMBO_R3 = 0xe0, + GVP_COMBO_R3_SCSI = 0xf0, + GVP_SERIESII = 0xf8, +}; + +enum GVP_flags { + GVP_IO = 0x01, + GVP_ACCEL = 0x02, + GVP_SCSI = 0x04, + GVP_24BITDMA = 0x08, + GVP_25BITDMA = 0x10, + GVP_NOBANK = 0x20, + GVP_14MHZ = 0x40, +}; + + +struct Node { + struct Node *ln_Succ; /* Pointer to next (successor) */ + struct Node *ln_Pred; /* Pointer to previous (predecessor) */ + u_char ln_Type; + char ln_Pri; /* Priority, for sorting */ + char *ln_Name; /* ID string, null terminated */ +}; + +struct ExpansionRom { + /* -First 16 bytes of the expansion ROM */ + u_char er_Type; /* Board type, size and flags */ + u_char er_Product; /* Product number, assigned by manufacturer */ + u_char er_Flags; /* Flags */ + u_char er_Reserved03; /* Must be zero ($ff inverted) */ + u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ + u_long er_SerialNumber; /* Available for use by manufacturer */ + u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ + u_char er_Reserved0c; + u_char er_Reserved0d; + u_char er_Reserved0e; + u_char er_Reserved0f; +}; + +/* er_Type board type bits */ +#define ERT_TYPEMASK 0xc0 +#define ERT_ZORROII 0xc0 +#define ERT_ZORROIII 0x80 + +/* other bits defined in er_Type */ +#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ +#define ERTF_MEMLIST (1<<5) + +struct ConfigDev { + struct Node cd_Node; + u_char cd_Flags; /* (read/write) */ + u_char cd_Pad; /* reserved */ + struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ + void *cd_BoardAddr; /* where in memory the board was placed */ + u_long cd_BoardSize; /* size of board in bytes */ + u_short cd_SlotAddr; /* which slot number (PRIVATE) */ + u_short cd_SlotSize; /* number of slots (PRIVATE) */ + void *cd_Driver; /* pointer to node of driver */ + struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ + u_long cd_Unused[4]; /* for whatever the driver wants */ +}; + +#else /* __ASSEMBLY__ */ + +LN_Succ = 0 +LN_Pred = LN_Succ+4 +LN_Type = LN_Pred+4 +LN_Pri = LN_Type+1 +LN_Name = LN_Pri+1 +LN_sizeof = LN_Name+4 + +ER_Type = 0 +ER_Product = ER_Type+1 +ER_Flags = ER_Product+1 +ER_Reserved03 = ER_Flags+1 +ER_Manufacturer = ER_Reserved03+1 +ER_SerialNumber = ER_Manufacturer+2 +ER_InitDiagVec = ER_SerialNumber+4 +ER_Reserved0c = ER_InitDiagVec+2 +ER_Reserved0d = ER_Reserved0c+1 +ER_Reserved0e = ER_Reserved0d+1 +ER_Reserved0f = ER_Reserved0e+1 +ER_sizeof = ER_Reserved0f+1 + +CD_Node = 0 +CD_Flags = CD_Node+LN_sizeof +CD_Pad = CD_Flags+1 +CD_Rom = CD_Pad+1 +CD_BoardAddr = CD_Rom+ER_sizeof +CD_BoardSize = CD_BoardAddr+4 +CD_SlotAddr = CD_BoardSize+4 +CD_SlotSize = CD_SlotAddr+2 +CD_Driver = CD_SlotSize+2 +CD_NextCD = CD_Driver+4 +CD_Unused = CD_NextCD+4 +CD_sizeof = CD_Unused+(4*4) + +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +#define ZORRO_NUM_AUTO 16 + +#ifdef __KERNEL__ + +extern int zorro_num_autocon; /* # of autoconfig devices found */ +extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; + + +/* + * Zorro Functions + */ + +extern int zorro_find(int manuf, int prod, int part, int index); +extern struct ConfigDev *zorro_get_board(int key); +extern void zorro_config_board(int key, int part); +extern void zorro_unconfig_board(int key, int part); + + +/* + * Bitmask indicating portions of available Zorro II RAM that are unused + * by the system. Every bit represents a 64K chunk, for a maximum of 8MB + * (128 chunks, physical 0x00200000-0x009fffff). + * + * If you want to use (= allocate) portions of this RAM, you should clear + * the corresponding bits. + */ + +extern u_long zorro_unused_z2ram[4]; + +#define Z2RAM_START (0x00200000) +#define Z2RAM_END (0x00a00000) +#define Z2RAM_SIZE (0x00800000) +#define Z2RAM_CHUNKSIZE (0x00010000) +#define Z2RAM_CHUNKMASK (0x0000ffff) +#define Z2RAM_CHUNKSHIFT (16) + + +/* + * Verbose Board Identification + */ + +extern void zorro_identify(void); +extern int zorro_get_list(char *buffer); + +#endif /* !__ASSEMBLY__ */ +#endif /* __KERNEL__ */ + +#endif /* __ZORRO_H */ +/* + * linux/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions + * + * Copyright (C) 1995 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef __ZORRO_H +#define __ZORRO_H + +#ifndef __ASSEMBLY__ + +/* + * Defined Board Manufacturers + * + * Please update arch/m68k/amiga/zorro.c if you make changes here + * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) + * and by looking at the NetBSD-Amiga kernel sources + */ + +#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ +#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ +#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ + +#define MANUF_KUPKE (0x00DD) /* Kupke */ +#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ + +#define MANUF_MEMPHIS (0x0100) /* Memphis */ +#define PROD_STORMBRINGER (0x00) /* Stormbringer */ + +#define MANUF_3_STATE (0x0200) /* 3-State */ +#define PROD_MEGAMIX_2000 (0x02) /* Megamix 2000 RAM */ + +#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ +#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ +#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ +#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ + +#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ +#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ +#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ +#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ +#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ +#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ +#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ +#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ +#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ +#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ +#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ +#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ +#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ +#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ +#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ +#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ +#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ + +#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ +#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ + +#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ +#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ + +#define MANUF_CARDCO (0x03EC) /* Cardco */ +#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ +#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ +#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ +#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ + +#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ +#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ + +#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ +#define PROD_AX2000 (0x01) /* AX2000 */ + +#define MANUF_ANAKIN (0x03F1) /* Anakin */ +#define PROD_EASYL (0x01) /* Easyl Tablet */ + +#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ +#define PROD_STARBOARD_II (0x00) /* StarBoard II */ +#define PROD_STARDRIVE (0x02) /* StarDrive */ +#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ +#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ +#define PROD_DELTA_RAM (0x20) /* Delta Card RAM */ +#define PROD_8_STAR_RAM (0x40) /* 8-Star RAM */ +#define PROD_8_STAR (0x41) /* 8-Star */ +#define PROD_VXL_RAM (0x44) /* VXL RAM */ +#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ +#define PROD_DELTA (0x60) /* Delta Card */ +#define PROD_MBX_1200 (0x81) /* MBX 1200 */ +#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ +#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ + +#define MANUF_ACCESS (0x03F4) /* Access Associates */ + +#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ + +#define MANUF_ASDG (0x03FF) /* ASDG */ +#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ +#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ +#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ +#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ + +#define MANUF_IMTRONICS (0x0404) /* Imtronics */ +#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ +#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ + +#define MANUF_AMERISTAR (0x041D) /* Ameristar */ +#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ +#define PROD_A560 (0x09) /* Arcnet Card */ +#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ + +#define MANUF_SUPRA (0x0420) /* Supra */ +#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ +#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ +#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ +#define PROD_SUPRA_500XP (0x09) /* 500XP/2000 RAM */ +#define PROD_SUPRA_500RX (0x0A) /* 500RX/2000 RAM */ +#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ +#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ +#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ +#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ + +#define MANUF_CSA (0x0422) /* Computer Systems Ass. */ +#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ +#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ + +#define MANUF_MTEC2 (0x0502) /* M-Tech */ +#define PROD_AT500_2 (0x03) /* AT500 RAM */ + +#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ +#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ + +#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ +#define PROD_BYTEBOX_A500 (0x00) /* A500 */ + +#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ + +#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ +#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ +#define PROD_RAPID_FIRE (0x0F) /* Rapid Fire SCSI Controller */ +#define PROD_DKB_1202 (0x10) /* DKB 1202 RAM */ +#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ +#define PROD_WILDFIRE_060 (0x17) /* WildFire 060 Turbo Board */ +#define PROD_WILDFIRE_060_2 (0xFF) /* WildFire 060 Turbo Board */ + +#define MANUF_GVP (0x07E1) /* Great Valley Products */ +#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ +#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ +#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ +#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ +#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ +#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ +#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works + for this product code also */ +#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ +#define PROD_GVP (0x0B) /* This code is used by a wide range of + GVP products - use the epc to + identify it correctly */ +#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ +#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ +#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ +#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ +#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ +/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ + +#define MANUF_SYNERGY (0x07E5) /* Synergy */ + +#define MANUF_XETEC (0x07E6) /* Xetec */ +#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ +#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ + +#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ +#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ +#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ +#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ +#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ +#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ + +#define MANUF_XEBEC (0x07EC) /* Xebec */ + +#define MANUF_SPIRIT (0x07F2) /* Spirit */ +#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ +#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ + +#define MANUF_BSC (0x07FE) /* BSC */ +#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ + +#define MANUF_BSC3 (0x0801) /* BSC */ +#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ +#define PROD_ALF_2_SCSI_2 (0x02) /* ALF 2 SCSI Controller */ +#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ + +#define MANUF_C_LTD (0x0802) /* C Ltd. */ +#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ +#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ + +#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ +#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ + +#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ +#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ + +#define MANUF_ICD (0x0817) /* ICD */ +#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ + +#define MANUF_KUPKE2 (0x0819) /* Kupke */ +#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ +#define PROD_GOLEM_BOX (0x03) /* Golem Box */ +#define PROD_KUPKE_TURBO (0x04) /* 030/882 Turbo Board */ +#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ + +#define MANUF_GVP4 (0x081D) /* Great Valley Products */ +#define PROD_A2000_RAM8 (0x09) /* A2000-RAM8/2 */ + +#define MANUF_INTERWORKS_NET (0x081E) /* Interworks Network */ + +#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ +#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ + +#define MANUF_BSC2 (0x082C) /* BSC */ +#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ +#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ +#define PROD_ALPHA_RAM_1200 (0x07) /* Alpha RAM 1200 */ +#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ +#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ +#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ +#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ +#define PROD_BSC_FRAEMBUFFER (0x20) /* Framebuffer */ +#define PROD_GRAFFITI_RAM (0x21) /* Graffiti Graphics Board */ +#define PROD_GRAFFITI_REG (0x22) +#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ +#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ + +#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ +#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ +#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ + +#define MANUF_IMPULSE (0x0838) /* Impulse */ +#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ + +#define MANUF_IVS (0x0840) /* IVS */ +#define PROD_GRANDSLAM_PIC_2 (0x02) /* GrandSlam PIC 2 RAM */ +#define PROD_GRANDSLAM_PIC_1 (0x04) /* GrandSlam PIC 1 RAM */ +#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ +#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ +#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ +#define PROD_META_4 (0x40) /* Meta-4 RAM */ +#define PROD_WAVETOOLS (0xBF) /* Wavetools Sound Board */ +#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ +#define PROD_VECTOR_2 (0xF4) /* Vector SCSI Controller */ + +#define MANUF_VECTOR (0x0841) /* Vector */ +#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ + +#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ +#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ +#define PROD_VISIONA_REG (0x02) +#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ +#define PROD_MERLIN_REG (0x04) +#define PROD_MERLIN_REG_2 (0xC9) + +#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ +#define PROD_AMIGANET (0x01) /* Amiganet Board */ + +#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ +#define PROD_AD1012 (0x01) /* AD1012 Sound Board */ +#define PROD_AD516 (0x02) /* AD516 Sound Board */ +#define PROD_DD512 (0x03) /* DD512 Sound Board */ + +#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ +#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ + +#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ +#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ +#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ + +#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ +#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ +#define PROD_GDA_1_REG (0x01) + +#define MANUF_ROCTEC (0x0860) /* RocTec */ +#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ +#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ + +#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ +#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ + +#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ +#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ + +#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ +#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ +#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ +#define PROD_MVD_819 (0x07) /* MVD 819 */ + +#define MANUF_DELACOMP (0x0873) /* DelaComp */ +#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ + +#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ +#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board */ +#define PROD_DOMINO_REG (0x02) +#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II/II+ Graphics Board */ +#define PROD_PICASSO_II_REG (0x0C) +#define PROD_PICASSO_II_SEGM (0x0D) /* Picasso II/II+ (Segmented Mode) */ +#define PROD_PICASSO_IV (0x15) /* Picassio IV Graphics Board */ +#define PROD_PICASSO_IV_2 (0x16) +#define PROD_PICASSO_IV_3 (0x17) +#define PROD_PICASSO_IV_4 (0x18) +#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ + +#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ +#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ +#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ + +#define MANUF_AMITRIX (0x0880) /* Amitrix */ +#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ +#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ + +#define MANUF_ARMAX (0x0885) /* ArMax */ +#define PROD_OMNIBUS (0x00) /* OmniBus Graphics Board */ + +#define MANUF_NEWTEK (0x088F) /* NewTek */ +#define PROD_VIDEOTOASTER (0x00) /* VideoToaster */ + +#define MANUF_MTEC (0x0890) /* M-Tech Germany */ +#define PROD_AT500 (0x01) /* AT500 IDE Controller */ +#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ +#define PROD_MTEC_68020I (0x06) /* 68020i Turbo Board */ +#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ +#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ + +#define MANUF_GVP2 (0x0891) /* Great Valley Products */ +#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ +#define PROD_SPECTRUM_REG (0x02) + +#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ +#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ +#define PROD_PICCOLO_REG (0x06) +#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ +#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ +#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ +#define PROD_SD64_REG (0x0B) + +#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ +#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ + +#define MANUF_ELBOX (0x089E) /* ElBox Computer */ +#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ + +#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ +#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ +#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ + +#define MANUF_MICRONIK (0x0A50) /* Micronik */ +#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ + +#define MANUF_MEGA_MICRO (0x1000) /* MegaMicro */ +#define PROD_SCRAM_500_SCSI (0x03) /* SCRAM 500 SCSI Controller */ +#define PROD_SCRAM_500_RAM (0x04) /* SCRAM 500 RAM */ + +#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ +#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_KUPKE3 (0x1248) /* Kupke */ +#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ + +#define MANUF_ITH (0x1388) /* ITH */ +#define PROD_ISDN_MASTER_II (0x01) /* ISDN-Master II */ + +#define MANUF_VMC (0x1389) /* VMC */ +#define PROD_ISDN_BLASTER_Z2 (0x01) /* ISDN Blaster Z2 */ +#define PROD_HYPERCOM_4 (0x02) /* HyperCom 4 */ + +#define MANUF_INFORMATION (0x157C) /* Information */ +#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ + +#define MANUF_VORTEX (0x2017) /* Vortex */ +#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ +#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ +#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ + +#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ +#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ +#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ + +#define MANUF_READYSOFT (0x2100) /* ReadySoft */ +#define PROD_AMAX (0x01) /* AMax II/IV */ + +#define MANUF_PHASE5 (0x2140) /* Phase5 */ +#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ +#define PROD_BLIZZARD (0x02) /* Blizzard */ +#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ +#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ +#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ +#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ +#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ +#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ +#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ +#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ +#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ +#define PROD_CYBERVISION3D_PRT (0x32) /* CyberVision64-3D Prototype */ +#define PROD_CYBERVISION3D (0x43) /* CyberVision64-3D Graphics Board */ + +#define MANUF_DPS (0x2169) /* DPS */ +#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ + +#define MANUF_APOLLO2 (0x2200) /* Apollo */ +#define PROD_A620 (0x00) /* A620 68020 Accelerator */ +#define PROD_A620_2 (0x01) /* A620 68020 Accelerator */ + +#define MANUF_APOLLO (0x2222) /* Apollo */ +#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ +#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ + +#define MANUF_PETSOFF (0x38A5) /* Petsoff LP */ +#define PROD_DELFINA (0x00) /* Delfina DSP */ + +#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ +#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ + +#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ +#define PROD_MAESTRO (0x03) /* Maestro */ +#define PROD_VLAB (0x04) /* VLab */ +#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ +#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ +#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ +#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ +#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ +#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ +#define PROD_ALTAIS (0x13) /* Altais Graphics Board */ +#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ + +#define MANUF_COMBITEC (0x6766) /* Combitec */ + +#define MANUF_SKI (0x8000) /* SKI Peripherals */ +#define PROD_MAST_FIREBALL (0x08) /* M.A.S.T. Fireball SCSI Controller */ +#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ + +#define MANUF_CAMERON (0xAA01) /* Cameron */ +#define PROD_PERSONAL_A4 (0x10) /* Personal A4 */ + +#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ +#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ + + +/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ + +#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ +#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ + +#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ +#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ + +#define MANUF_VECTOR2 (0x07DB) /* Vector */ +#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ +#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ +#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ +#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ + + +/* + * GVP's identifies most of their product through the 'extended + * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK + * before the identification. + */ + +#define GVP_PRODMASK (0xf8) +#define GVP_SCSICLKMASK (0x01) + +enum GVP_ident { + GVP_GFORCE_040 = 0x20, + GVP_GFORCE_040_SCSI = 0x30, + GVP_A1291_SCSI = 0x40, + GVP_COMBO_R4 = 0x60, + GVP_COMBO_R4_SCSI = 0x70, + GVP_PHONEPAK = 0x78, + GVP_IOEXT = 0x98, + GVP_GFORCE_030 = 0xa0, + GVP_GFORCE_030_SCSI = 0xb0, + GVP_A530 = 0xc0, + GVP_A530_SCSI = 0xd0, + GVP_COMBO_R3 = 0xe0, + GVP_COMBO_R3_SCSI = 0xf0, + GVP_SERIESII = 0xf8, +}; + +enum GVP_flags { + GVP_IO = 0x01, + GVP_ACCEL = 0x02, + GVP_SCSI = 0x04, + GVP_24BITDMA = 0x08, + GVP_25BITDMA = 0x10, + GVP_NOBANK = 0x20, + GVP_14MHZ = 0x40, +}; + + +struct Node { + struct Node *ln_Succ; /* Pointer to next (successor) */ + struct Node *ln_Pred; /* Pointer to previous (predecessor) */ + u_char ln_Type; + char ln_Pri; /* Priority, for sorting */ + char *ln_Name; /* ID string, null terminated */ +}; + +struct ExpansionRom { + /* -First 16 bytes of the expansion ROM */ + u_char er_Type; /* Board type, size and flags */ + u_char er_Product; /* Product number, assigned by manufacturer */ + u_char er_Flags; /* Flags */ + u_char er_Reserved03; /* Must be zero ($ff inverted) */ + u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ + u_long er_SerialNumber; /* Available for use by manufacturer */ + u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ + u_char er_Reserved0c; + u_char er_Reserved0d; + u_char er_Reserved0e; + u_char er_Reserved0f; +}; + +/* er_Type board type bits */ +#define ERT_TYPEMASK 0xc0 +#define ERT_ZORROII 0xc0 +#define ERT_ZORROIII 0x80 + +/* other bits defined in er_Type */ +#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ +#define ERTF_MEMLIST (1<<5) + +struct ConfigDev { + struct Node cd_Node; + u_char cd_Flags; /* (read/write) */ + u_char cd_Pad; /* reserved */ + struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ + void *cd_BoardAddr; /* where in memory the board was placed */ + u_long cd_BoardSize; /* size of board in bytes */ + u_short cd_SlotAddr; /* which slot number (PRIVATE) */ + u_short cd_SlotSize; /* number of slots (PRIVATE) */ + void *cd_Driver; /* pointer to node of driver */ + struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ + u_long cd_Unused[4]; /* for whatever the driver wants */ +}; + +#else /* __ASSEMBLY__ */ + +LN_Succ = 0 +LN_Pred = LN_Succ+4 +LN_Type = LN_Pred+4 +LN_Pri = LN_Type+1 +LN_Name = LN_Pri+1 +LN_sizeof = LN_Name+4 + +ER_Type = 0 +ER_Product = ER_Type+1 +ER_Flags = ER_Product+1 +ER_Reserved03 = ER_Flags+1 +ER_Manufacturer = ER_Reserved03+1 +ER_SerialNumber = ER_Manufacturer+2 +ER_InitDiagVec = ER_SerialNumber+4 +ER_Reserved0c = ER_InitDiagVec+2 +ER_Reserved0d = ER_Reserved0c+1 +ER_Reserved0e = ER_Reserved0d+1 +ER_Reserved0f = ER_Reserved0e+1 +ER_sizeof = ER_Reserved0f+1 + +CD_Node = 0 +CD_Flags = CD_Node+LN_sizeof +CD_Pad = CD_Flags+1 +CD_Rom = CD_Pad+1 +CD_BoardAddr = CD_Rom+ER_sizeof +CD_BoardSize = CD_BoardAddr+4 +CD_SlotAddr = CD_BoardSize+4 +CD_SlotSize = CD_SlotAddr+2 +CD_Driver = CD_SlotSize+2 +CD_NextCD = CD_Driver+4 +CD_Unused = CD_NextCD+4 +CD_sizeof = CD_Unused+(4*4) + +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +#define ZORRO_NUM_AUTO 16 + +#ifdef __KERNEL__ + +extern int zorro_num_autocon; /* # of autoconfig devices found */ +extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; + + +/* + * Zorro Functions + */ + +extern int zorro_find(int manuf, int prod, int part, int index); +extern struct ConfigDev *zorro_get_board(int key); +extern void zorro_config_board(int key, int part); +extern void zorro_unconfig_board(int key, int part); + + +/* + * Bitmask indicating portions of available Zorro II RAM that are unused + * by the system. Every bit represents a 64K chunk, for a maximum of 8MB + * (128 chunks, physical 0x00200000-0x009fffff). + * + * If you want to use (= allocate) portions of this RAM, you should clear + * the corresponding bits. + */ + +extern u_long zorro_unused_z2ram[4]; + +#define Z2RAM_START (0x00200000) +#define Z2RAM_END (0x00a00000) +#define Z2RAM_SIZE (0x00800000) +#define Z2RAM_CHUNKSIZE (0x00010000) +#define Z2RAM_CHUNKMASK (0x0000ffff) +#define Z2RAM_CHUNKSHIFT (16) + + +/* + * Verbose Board Identification + */ + +extern void zorro_identify(void); +extern int zorro_get_list(char *buffer); + +#endif /* !__ASSEMBLY__ */ +#endif /* __KERNEL__ */ + +#endif /* __ZORRO_H */ diff --git a/include/net/sock.h b/include/net/sock.h index 7e6c57f4c..61936854f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -179,6 +179,7 @@ struct raw6_opt { #endif /* IPV6 */ + struct tcp_opt { /* @@ -197,6 +198,7 @@ struct tcp_opt __u32 rcv_wup; /* rcv_nxt on last window update sent */ + __u32 fin_seq; /* XXX This one should go, we don't need it. -DaveM */ __u32 srtt; /* smothed round trip time << 3 */ __u32 mdev; /* medium deviation */ @@ -207,6 +209,28 @@ struct tcp_opt */ __u32 snd_cwnd; /* Sending congestion window */ __u32 snd_ssthresh; /* Slow start size threshold */ + __u16 snd_cwnd_cnt; + __u16 max_window; + +/* + * Options received (usually on last packet, some only on SYN packets). + */ + char tstamp_ok, /* TIMESTAMP seen on SYN packet */ + sack_ok; /* SACK_PERM seen on SYN packet */ + char saw_tstamp; /* Saw TIMESTAMP on last packet */ + __u16 in_mss; /* MSS option received from sender */ + __u8 snd_wscale; /* Window scaling received from sender */ + __u8 rcv_wscale; /* Window scaling to send to receiver */ + __u32 rcv_tsval; /* Time stamp value */ + __u32 rcv_tsecr; /* Time stamp echo reply */ + __u32 ts_recent; /* Time stamp to echo next */ + __u32 ts_recent_stamp;/* Time we stored ts_recent (for aging) */ + __u32 last_ack_sent; /* last ack we sent */ + int sacks; /* Number of SACK blocks if any */ + __u32 left_sack[4]; /* Left edges of blocks */ + __u32 right_sack[4]; /* Right edges of blocks */ + int tcp_header_len; /* Bytes of tcp header to send */ + /* * Timers used by the TCP protocol layer */ @@ -217,17 +241,21 @@ struct tcp_opt struct timer_list retransmit_timer; /* Resend (no ack) */ __u32 basertt; /* Vegas baseRTT */ + __u32 packets_out; /* Packets which are "in flight" */ + __u32 window_clamp; /* XXX Document this... -DaveM */ + __u8 pending; /* pending events */ __u8 delayed_acks; - __u8 dup_acks; + __u8 dup_acks; /* Consequetive duplicate acks seen from other end */ + __u8 retransmits; __u32 lrcvtime; /* timestamp of last received data packet */ __u32 rcv_tstamp; /* timestamp of last received packet */ __u32 iat_mdev; /* interarrival time medium deviation */ __u32 iat; /* interarrival time */ __u32 ato; /* delayed ack timeout */ + __u32 high_seq; /* highest sequence number sent by onset of congestion */ - __u32 high_seq; /* * new send pointers */ @@ -238,11 +266,6 @@ struct tcp_opt * fast retransmit */ /* - * pending events - */ - __u8 pending; - -/* * Header prediction flags * 0x5?10 << 16 + snd_wnd in net byte order */ @@ -252,6 +275,7 @@ struct tcp_opt __u32 probes_out; /* unanswered 0 window probes */ struct open_request *syn_wait_queue; + struct open_request **syn_wait_last; struct tcp_func *af_specific; }; @@ -311,29 +335,29 @@ struct sock atomic_t wmem_alloc; atomic_t rmem_alloc; unsigned long allocation; /* Allocation mode */ + + /* The following stuff should probably move to the tcp private area */ __u32 write_seq; __u32 copied_seq; - __u32 fin_seq; __u32 syn_seq; __u32 urg_seq; __u32 urg_data; + unsigned char delayed_acks; + /* End of block to move */ + int sock_readers; /* user count */ - unsigned char delayed_acks, - dup_acks; /* * Not all are volatile, but some are, so we * might as well say they all are. */ volatile char dead, urginline, - intr, done, reuse, keepopen, linger, destroy, - ack_timed, no_check, zapped, /* In ax25 & ipx means not linked */ broadcast, @@ -350,12 +374,7 @@ struct sock int hashent; struct sock *pair; - struct sk_buff * send_head; - struct sk_buff_head back_log; - struct sk_buff *partial; - struct timer_list partial_timer; - atomic_t retransmits; struct sk_buff_head write_queue, receive_queue, @@ -374,22 +393,14 @@ struct sock unsigned short max_unacked; - - unsigned short bytes_rcv; /* * mss is min(mtu, max_window) */ unsigned short mtu; /* mss negotiated in the syn's */ unsigned short mss; /* current eff. mss - can change */ unsigned short user_mss; /* mss requested by user in ioctl */ - unsigned short max_window; - unsigned long window_clamp; - unsigned int ssthresh; unsigned short num; - unsigned short cong_window; - unsigned short cong_count; - int packets_out; unsigned short shutdown; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) @@ -404,13 +415,7 @@ struct sock struct raw6_opt tp_raw; #endif } tp_pinfo; -/* - * currently backoff isn't used, but I'm maintaining it in case - * we want to go back to a backoff formula that needs it - */ -/* - unsigned short backoff; - */ + int err, err_soft; /* Soft holds errors that don't cause failure but are the cause of a persistent failure not just @@ -426,6 +431,7 @@ struct sock unsigned short type; unsigned char localroute; /* Route locally only */ struct ucred peercred; + /* What the user has tried to set with the security API */ short authentication; short encryption; @@ -471,10 +477,6 @@ struct sock int ip_tos; /* TOS */ unsigned ip_cmsg_flags; struct tcphdr dummy_th; - struct timer_list keepalive_timer; /* TCP keepalive hack */ - struct timer_list retransmit_timer; /* TCP retransmit timer */ - struct timer_list delack_timer; /* TCP delayed ack timer */ - int ip_xmit_timeout; /* Why the timeout is running */ struct ip_options *opt; unsigned char ip_hdrincl; /* Include headers ? */ __u8 ip_mc_ttl; /* Multicasting TTL */ @@ -491,8 +493,8 @@ struct sock int timeout; /* What are we waiting for? */ struct timer_list timer; /* This is the TIME_WAIT/receive timer - * when we are doing IP - */ + * when we are doing IP + */ struct timeval stamp; /* diff --git a/include/net/tcp.h b/include/net/tcp.h index a7b42c8db..3822b461f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -23,8 +23,11 @@ #include #include -/* This is for all connections with a full identity, no wildcards. */ -#define TCP_HTABLE_SIZE 256 +/* This is for all connections with a full identity, no wildcards. + * New scheme, half the table is for TIME_WAIT, the other half is + * for the rest. I'll experiment with dynamic table growth later. + */ +#define TCP_HTABLE_SIZE 1024 /* This is for listening sockets, thus all sockets which possess wildcards. */ #define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ @@ -52,9 +55,7 @@ static __inline__ int tcp_sk_bhashfn(struct sock *sk) return tcp_bhashfn(lport); } -/* These can have wildcards, don't try too hard. - * XXX deal with thousands of IP aliases for listening ports later - */ +/* These can have wildcards, don't try too hard. */ static __inline__ int tcp_lhashfn(unsigned short num) { return num & (TCP_LHTABLE_SIZE - 1); @@ -95,11 +96,13 @@ static __inline__ void tcp_sk_unbindify(struct sock *sk) /* * 40 is maximal IP options size - * 4 is TCP option size (MSS) + * 20 is the maximum TCP options size we can currently construct on a SYN. + * 40 is the maximum possible TCP options size. */ -#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 4 + MAX_HEADER + 15) +#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 20 + MAX_HEADER + 15) #define MAX_FIN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) +#define BASE_ACK_SIZE (NETHDR_SIZE + MAX_HEADER + 15) #define MAX_ACK_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) #define MAX_RESET_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) @@ -163,6 +166,8 @@ static __inline__ void tcp_sk_unbindify(struct sock *sk) * We don't use these yet, but they are for PAWS and big windows */ #define TCPOPT_WINDOW 3 /* Window scaling */ +#define TCPOPT_SACK_PERM 4 /* SACK Permitted */ +#define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ /* @@ -171,8 +176,15 @@ static __inline__ void tcp_sk_unbindify(struct sock *sk) #define TCPOLEN_MSS 4 #define TCPOLEN_WINDOW 3 +#define TCPOLEN_SACK_PERM 2 #define TCPOLEN_TIMESTAMP 10 +/* + * TCP option flags for parsed options. + */ + +#define TCPOPTF_SACK_PERM 1 +#define TCPOPTF_TIMESTAMP 2 /* * TCP Vegas constants @@ -206,11 +218,15 @@ struct tcp_v6_open_req { struct open_request { struct open_request *dl_next; - struct open_request *dl_prev; + struct open_request **dl_pprev; __u32 rcv_isn; __u32 snt_isn; __u16 rmt_port; __u16 mss; + __u8 snd_wscale; + char sack_ok; + char tstamp_ok; + __u32 ts_recent; unsigned long expires; int retrans; struct or_calltable *class; @@ -354,7 +370,7 @@ extern int tcp_recvmsg(struct sock *sk, int len, int nonblock, int flags, int *addr_len); -extern int tcp_parse_options(struct tcphdr *th); +extern void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp); /* * TCP v4 functions exported for the inet6 API @@ -511,9 +527,8 @@ static __inline__ void tcp_set_state(struct sock *sk, int state) switch (state) { case TCP_ESTABLISHED: - if (oldstate != TCP_ESTABLISHED) { + if (oldstate != TCP_ESTABLISHED) tcp_statistics.TcpCurrEstab++; - } break; case TCP_CLOSE: @@ -523,47 +538,68 @@ static __inline__ void tcp_set_state(struct sock *sk, int state) default: if (oldstate==TCP_ESTABLISHED) tcp_statistics.TcpCurrEstab--; + if (state == TCP_TIME_WAIT) + sk->prot->rehash(sk); } } -extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req) +/* + * Construct a tcp options header for a SYN or SYN_ACK packet. + * If this is every changed make sure to change the definition of + * MAX_SYN_SIZE to match the new maximum number of options that you + * can generate. + * FIXME: This is completely disgusting. + * This is probably a good candidate for a bit of assembly magic. + * It would be especially magical to compute the checksum for this + * stuff on the fly here. + */ +extern __inline__ int tcp_syn_build_options(struct sk_buff *skb, int mss, int sack, int ts, int wscale) { - if (req->dl_next == req) - { - tp->syn_wait_queue = NULL; - } - else - { - req->dl_prev->dl_next = req->dl_next; - req->dl_next->dl_prev = req->dl_prev; - - if (tp->syn_wait_queue == req) - { - tp->syn_wait_queue = req->dl_next; + int count = 4 + (wscale ? 4 : 0) + ((ts || sack) ? 4 : 0) + (ts ? 8 : 0); + unsigned char *optr = skb_put(skb,count); + __u32 *ptr = (__u32 *)optr; + + /* + * We always get an MSS option. + */ + *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); + if (ts) { + if (sack) { + *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(jiffies); /* TSVAL */ + *ptr++ = htonl(0); /* TSECR */ + } else { + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(jiffies); /* TSVAL */ + *ptr++ = htonl(0); /* TSECR */ } + } else if (sack) { + *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) + | (TCPOPT_NOP << 8) | TCPOPT_NOP); } - - req->dl_prev = req->dl_next = NULL; + if (wscale) + *ptr++ = htonl((TCPOPT_WINDOW << 24) | (TCPOLEN_WINDOW << 16) | wscale); + skb->csum = csum_partial(optr, count, 0); + return count; } -extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) +extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req) { - if (!tp->syn_wait_queue) - { - req->dl_next = req; - req->dl_prev = req; - tp->syn_wait_queue = req; - } + if(req->dl_next) + req->dl_next->dl_pprev = req->dl_pprev; else - { - struct open_request *list = tp->syn_wait_queue; - - req->dl_next = list; - req->dl_prev = list->dl_prev; - list->dl_prev->dl_next = req; - list->dl_prev = req; - } + tp->syn_wait_last = req->dl_pprev; + *req->dl_pprev = req->dl_next; +} +extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) +{ + req->dl_next = NULL; + req->dl_pprev = tp->syn_wait_last; + *tp->syn_wait_last = req; + tp->syn_wait_last = &req->dl_next; } extern void __tcp_inc_slow_timer(struct tcp_sl_timer *slt); @@ -587,4 +623,3 @@ extern __inline__ void tcp_dec_slow_timer(int timer) } #endif /* _TCP_H */ - diff --git a/init/main.c b/init/main.c index 00b292606..15ab2176e 100644 --- a/init/main.c +++ b/init/main.c @@ -896,7 +896,6 @@ __initfunc(asmlinkage void start_kernel(void)) memory_start = kmem_cache_init(memory_start, memory_end); sti(); calibrate_delay(); - memory_start = inode_init(memory_start,memory_end); memory_start = file_table_init(memory_start,memory_end); memory_start = name_cache_init(memory_start,memory_end); #ifdef CONFIG_BLK_DEV_INITRD @@ -913,6 +912,7 @@ __initfunc(asmlinkage void start_kernel(void)) kmem_cache_sizes_init(); vma_init(); buffer_init(); + inode_init(); sock_init(); #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD) ipc_init(); diff --git a/kernel/exit.c b/kernel/exit.c index 51e9de867..d6c43a625 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -136,6 +136,12 @@ void release(struct task_struct * p) } for (i=1 ; iprocessor != NO_PROC_ID) + barrier(); + spin_unlock_wait(&scheduler_lock); +#endif nr_tasks--; task[i] = NULL; REMOVE_LINKS(p); @@ -693,10 +699,10 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct if (options & ~(WNOHANG|WUNTRACED|__WCLONE)) return -EINVAL; - lock_kernel(); add_wait_queue(¤t->wait_chldexit,&wait); repeat: - flag = retval = 0; + flag = 0; + read_lock(&tasklist_lock); for (p = current->p_cptr ; p ; p = p->p_osptr) { if (pid>0) { if (p->pid != pid) @@ -718,23 +724,28 @@ repeat: continue; if (!(options & WUNTRACED) && !(p->flags & PF_PTRACED)) continue; + read_unlock(&tasklist_lock); if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); if (stat_addr) - put_user((p->exit_code << 8) | 0x7f, - stat_addr); + __put_user((p->exit_code << 8) | 0x7f, + stat_addr); p->exit_code = 0; retval = p->pid; goto end_wait4; case TASK_ZOMBIE: current->cutime += p->utime + p->cutime; current->cstime += p->stime + p->cstime; + read_unlock(&tasklist_lock); if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); if (stat_addr) - put_user(p->exit_code, stat_addr); + __put_user(p->exit_code, stat_addr); retval = p->pid; if (p->p_opptr != p->p_pptr) { + /* Note this grabs tasklist_lock + * as a writer... (twice!) + */ REMOVE_LINKS(p); p->p_pptr = p->p_opptr; SET_LINKS(p); @@ -749,6 +760,7 @@ repeat: continue; } } + read_unlock(&tasklist_lock); if (flag) { retval = 0; if (options & WNOHANG) @@ -763,7 +775,6 @@ repeat: retval = -ECHILD; end_wait4: remove_wait_queue(¤t->wait_chldexit,&wait); - unlock_kernel(); return retval; } diff --git a/kernel/fork.c b/kernel/fork.c index 7136a4eb9..6204ffeaf 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -47,11 +47,15 @@ static inline int find_empty_process(void) max_tasks--; /* count the new process.. */ if (max_tasks < nr_tasks) { struct task_struct *p; + read_lock(&tasklist_lock); for_each_task (p) { if (p->uid == current->uid) - if (--max_tasks < 0) + if (--max_tasks < 0) { + read_unlock(&tasklist_lock); return -EAGAIN; + } } + read_unlock(&tasklist_lock); } } for (i = 0 ; i < NR_TASKS ; i++) { @@ -67,6 +71,8 @@ static int get_pid(unsigned long flags) if (flags & CLONE_PID) return current->pid; + + read_lock(&tasklist_lock); repeat: if ((++last_pid) & 0xffff8000) last_pid=1; @@ -76,6 +82,8 @@ repeat: p->session == last_pid) goto repeat; } + read_unlock(&tasklist_lock); + return last_pid; } diff --git a/kernel/info.c b/kernel/info.c index 86894b951..ffaec7140 100644 --- a/kernel/info.c +++ b/kernel/info.c @@ -23,7 +23,7 @@ asmlinkage int sys_sysinfo(struct sysinfo *info) memset((char *)&val, 0, sizeof(struct sysinfo)); - lock_kernel(); + cli(); val.uptime = jiffies / HZ; val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); @@ -31,10 +31,10 @@ asmlinkage int sys_sysinfo(struct sysinfo *info) val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); val.procs = nr_tasks-1; + sti(); si_meminfo(&val); si_swapinfo(&val); - unlock_kernel(); if (copy_to_user(info, &val, sizeof(struct sysinfo))) return -EFAULT; diff --git a/kernel/itimer.c b/kernel/itimer.c index a4332afbe..479f660a0 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -43,7 +43,6 @@ static void jiffiestotv(unsigned long jiffies, struct timeval *value) { value->tv_usec = (jiffies % HZ) * (1000000 / HZ); value->tv_sec = jiffies / HZ; - return; } static int _getitimer(int which, struct itimerval *value) @@ -80,20 +79,18 @@ static int _getitimer(int which, struct itimerval *value) return 0; } +/* SMP: Only we modify our itimer values. */ asmlinkage int sys_getitimer(int which, struct itimerval *value) { int error = -EFAULT; struct itimerval get_buffer; - lock_kernel(); - if (!value) - goto out; - error = _getitimer(which, &get_buffer); - if (error) - goto out; - error = copy_to_user(value, &get_buffer, sizeof(get_buffer)) ? -EFAULT : 0; -out: - unlock_kernel(); + if (value) { + error = _getitimer(which, &get_buffer); + if (!error) + error = copy_to_user(value, &get_buffer, sizeof(get_buffer)) + ? -EFAULT : 0; + } return error; } @@ -155,31 +152,27 @@ int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue) return 0; } +/* SMP: Again, only we play with our itimers, and signals are SMP safe + * now so that is not an issue at all anymore. + */ asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) { - int error; struct itimerval set_buffer, get_buffer; + int error; - lock_kernel(); if (value) { - error = verify_area(VERIFY_READ, value, sizeof(*value)); - if (error) - goto out; - error = copy_from_user(&set_buffer, value, sizeof(set_buffer)); - if (error) { - error = -EFAULT; - goto out; - } + if(verify_area(VERIFY_READ, value, sizeof(*value))) + return -EFAULT; + if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) + return -EFAULT; } else memset((char *) &set_buffer, 0, sizeof(set_buffer)); error = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0); if (error || !ovalue) - goto out; + return error; if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer))) - error = -EFAULT; -out: - unlock_kernel(); - return error; + return -EFAULT; + return 0; } diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 3bade85fb..f5f202c8e 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -77,6 +77,9 @@ extern char *get_options(char *str, int *ints); extern void set_device_ro(int dev,int flag); extern struct file_operations * get_blkfops(unsigned int); extern int blkdev_release(struct inode * inode); +#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) +extern int (*do_nfsservctl)(int, void *, void *); +#endif extern void *sys_call_table; @@ -179,6 +182,10 @@ EXPORT_SYMBOL(posix_test_lock); EXPORT_SYMBOL(posix_block_lock); EXPORT_SYMBOL(posix_unblock_lock); +#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) +EXPORT_SYMBOL(do_nfsservctl); +#endif + /* device registration */ EXPORT_SYMBOL(register_chrdev); EXPORT_SYMBOL(unregister_chrdev); diff --git a/kernel/sched.c b/kernel/sched.c index fcf52c637..68be616be 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -414,10 +414,8 @@ asmlinkage void schedule(void) */ asmlinkage int sys_pause(void) { - lock_kernel(); current->state = TASK_INTERRUPTIBLE; schedule(); - unlock_kernel(); return -ERESTARTNOHAND; } @@ -1190,7 +1188,6 @@ asmlinkage unsigned int sys_alarm(unsigned int seconds) struct itimerval it_new, it_old; unsigned int oldalarm; - lock_kernel(); it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; it_new.it_value.tv_sec = seconds; it_new.it_value.tv_usec = 0; @@ -1200,7 +1197,6 @@ asmlinkage unsigned int sys_alarm(unsigned int seconds) /* And we'd better return too much than too little anyway */ if (it_old.it_value.tv_usec) oldalarm++; - unlock_kernel(); return oldalarm; } @@ -1348,13 +1344,15 @@ static struct task_struct *find_process_by_pid(pid_t pid) p = current; if (pid) { + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid == pid) goto found; } p = NULL; - } found: + read_unlock(&tasklist_lock); + } return p; } @@ -1410,64 +1408,42 @@ static int setscheduler(pid_t pid, int policy, asmlinkage int sys_sched_setscheduler(pid_t pid, int policy, struct sched_param *param) { - int ret; - - lock_kernel(); - ret = setscheduler(pid, policy, param); - unlock_kernel(); - return ret; + return setscheduler(pid, policy, param); } asmlinkage int sys_sched_setparam(pid_t pid, struct sched_param *param) { - int ret; - - lock_kernel(); - ret = setscheduler(pid, -1, param); - unlock_kernel(); - return ret; + return setscheduler(pid, -1, param); } asmlinkage int sys_sched_getscheduler(pid_t pid) { struct task_struct *p; - int ret = -EINVAL; - lock_kernel(); if (pid < 0) - goto out; + return -EINVAL; p = find_process_by_pid(pid); - ret = -ESRCH; if (!p) - goto out; + return -ESRCH; - ret = p->policy; -out: - unlock_kernel(); - return ret; + return p->policy; } asmlinkage int sys_sched_getparam(pid_t pid, struct sched_param *param) { struct task_struct *p; struct sched_param lp; - int ret = -EINVAL; - lock_kernel(); if (!param || pid < 0) - goto out; + return -EINVAL; p = find_process_by_pid(pid); - ret = -ESRCH; if (!p) - goto out; + return -ESRCH; lp.sched_priority = p->rt_priority; - ret = copy_to_user(param, &lp, sizeof(struct sched_param)) ? -EFAULT : 0; -out: - unlock_kernel(); - return ret; + return copy_to_user(param, &lp, sizeof(struct sched_param)) ? -EFAULT : 0; } asmlinkage int sys_sched_yield(void) @@ -1543,7 +1519,6 @@ static void jiffiestotimespec(unsigned long jiffies, struct timespec *value) { value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ); value->tv_sec = jiffies / HZ; - return; } asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp) @@ -1572,11 +1547,10 @@ asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp) } expire = timespectojiffies(&t) + (t.tv_sec || t.tv_nsec) + jiffies; - lock_kernel(); + current->timeout = expire; current->state = TASK_INTERRUPTIBLE; schedule(); - unlock_kernel(); if (expire > jiffies) { if (rmtp) { diff --git a/kernel/signal.c b/kernel/signal.c index e657381cf..f1c5990cb 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -95,9 +95,9 @@ asmlinkage int sys_sigpending(sigset_t *set) int ret; /* fill in "set" with signals pending but blocked. */ - lock_kernel(); + spin_lock_irq(¤t->sigmask_lock); ret = put_user(current->blocked & current->signal, set); - unlock_kernel(); + spin_unlock_irq(¤t->sigmask_lock); return ret; } diff --git a/kernel/sys.c b/kernel/sys.c index 2d55d19d9..934108fa8 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -87,12 +87,11 @@ static int proc_sel(struct task_struct *p, int which, int who) asmlinkage int sys_setpriority(int which, int who, int niceval) { struct task_struct *p; - int error = EINVAL; unsigned int priority; + int error; - lock_kernel(); if (which > 2 || which < 0) - goto out; + return -EINVAL; /* normalize: avoid signed division (rounding problems) */ error = ESRCH; @@ -109,6 +108,7 @@ asmlinkage int sys_setpriority(int which, int who, int niceval) priority = 1; } + read_lock(&tasklist_lock); for_each_task(p) { if (!proc_sel(p, which, who)) continue; @@ -124,8 +124,8 @@ asmlinkage int sys_setpriority(int which, int who, int niceval) else p->priority = priority; } -out: - unlock_kernel(); + read_unlock(&tasklist_lock); + return -error; } @@ -138,26 +138,23 @@ asmlinkage int sys_getpriority(int which, int who) { struct task_struct *p; long max_prio = -ESRCH; - int ret = -EINVAL; - lock_kernel(); if (which > 2 || which < 0) - goto out; + return -EINVAL; + read_lock(&tasklist_lock); for_each_task (p) { if (!proc_sel(p, which, who)) continue; if (p->priority > max_prio) max_prio = p->priority; } + read_unlock(&tasklist_lock); /* scale the priority from timeslice to 0..40 */ if (max_prio > 0) max_prio = (max_prio * 20 + DEF_PRIORITY/2) / DEF_PRIORITY; - ret = max_prio; -out: - unlock_kernel(); - return ret; + return max_prio; } #ifndef __alpha__ @@ -304,21 +301,22 @@ void ctrl_alt_del(void) * The general idea is that a program which uses just setregid() will be * 100% compatible with BSD. A program which uses just setgid() will be * 100% compatible with POSIX w/ Saved ID's. + * + * SMP: There are not races, the gid's are checked only by filesystem + * operations (as far as semantic preservation is concerned). */ asmlinkage int sys_setregid(gid_t rgid, gid_t egid) { int old_rgid = current->gid; int old_egid = current->egid; - int err = -EPERM; - lock_kernel(); if (rgid != (gid_t) -1) { if ((old_rgid == rgid) || (current->egid==rgid) || suser()) current->gid = rgid; else - goto out; + return -EPERM; } if (egid != (gid_t) -1) { if ((old_rgid == egid) || @@ -328,7 +326,7 @@ asmlinkage int sys_setregid(gid_t rgid, gid_t egid) current->fsgid = current->egid = egid; else { current->gid = old_rgid; - goto out; + return -EPERM; } } if (rgid != (gid_t) -1 || @@ -337,33 +335,28 @@ asmlinkage int sys_setregid(gid_t rgid, gid_t egid) current->fsgid = current->egid; if (current->egid != old_egid) current->dumpable = 0; - err = 0; -out: - unlock_kernel(); - return err; + return 0; } /* * setgid() is implemented like SysV w/ SAVED_IDS + * + * SMP: Same implicit races as above. */ asmlinkage int sys_setgid(gid_t gid) { int old_egid = current->egid; - int err = -EPERM; - lock_kernel(); if (suser()) current->gid = current->egid = current->sgid = current->fsgid = gid; else if ((gid == current->gid) || (gid == current->sgid)) current->egid = current->fsgid = gid; else - goto out; - err = 0; + return -EPERM; + if (current->egid != old_egid) current->dumpable = 0; -out: - unlock_kernel(); - return err; + return 0; } static char acct_active = 0; @@ -532,9 +525,7 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid) { int old_ruid; int old_euid; - int err = -EPERM; - lock_kernel(); old_ruid = current->uid; old_euid = current->euid; if (ruid != (uid_t) -1) { @@ -543,7 +534,7 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid) suser()) current->uid = ruid; else - goto out; + return -EPERM; } if (euid != (uid_t) -1) { if ((old_ruid == euid) || @@ -553,7 +544,7 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid) current->fsuid = current->euid = euid; else { current->uid = old_ruid; - goto out; + return -EPERM; } } if (ruid != (uid_t) -1 || @@ -562,10 +553,7 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid) current->fsuid = current->euid; if (current->euid != old_euid) current->dumpable = 0; - err = 0; -out: - unlock_kernel(); - return err; + return 0; } /* @@ -582,22 +570,17 @@ out: asmlinkage int sys_setuid(uid_t uid) { int old_euid = current->euid; - int retval = 0; - lock_kernel(); if (suser()) current->uid = current->euid = current->suid = current->fsuid = uid; else if ((uid == current->uid) || (uid == current->suid)) current->fsuid = current->euid = uid; - else { - retval = -EPERM; - goto out; - } + else + return -EPERM; + if (current->euid != old_euid) current->dumpable = 0; -out: - unlock_kernel(); - return retval; + return 0; } @@ -608,43 +591,37 @@ out: asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) { uid_t old_ruid, old_euid, old_suid; - int err = -EPERM; - lock_kernel(); old_ruid = current->uid; old_euid = current->euid; old_suid = current->suid; if ((ruid != (uid_t) -1) && (ruid != current->uid) && (ruid != current->euid) && (ruid != current->suid)) - goto out; + return -EPERM; if ((euid != (uid_t) -1) && (euid != current->uid) && (euid != current->euid) && (euid != current->suid)) - goto out; + return -EPERM; if ((suid != (uid_t) -1) && (suid != current->uid) && (suid != current->euid) && (suid != current->suid)) - goto out; + return -EPERM; if (ruid != (uid_t) -1) current->uid = ruid; if (euid != (uid_t) -1) current->euid = euid; if (suid != (uid_t) -1) current->suid = suid; - err = 0; -out: - unlock_kernel(); - return err; + return 0; } asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) { int retval; - lock_kernel(); if (!(retval = put_user(current->uid, ruid)) && !(retval = put_user(current->euid, euid))) retval = put_user(current->suid, suid); - unlock_kernel(); + return retval; } @@ -659,14 +636,13 @@ asmlinkage int sys_setfsuid(uid_t uid) { int old_fsuid; - lock_kernel(); old_fsuid = current->fsuid; if (uid == current->uid || uid == current->euid || uid == current->suid || uid == current->fsuid || suser()) current->fsuid = uid; if (current->fsuid != old_fsuid) current->dumpable = 0; - unlock_kernel(); + return old_fsuid; } @@ -677,14 +653,13 @@ asmlinkage int sys_setfsgid(gid_t gid) { int old_fsgid; - lock_kernel(); old_fsgid = current->fsgid; if (gid == current->gid || gid == current->egid || gid == current->sgid || gid == current->fsgid || suser()) current->fsgid = gid; if (current->fsgid != old_fsgid) current->dumpable = 0; - unlock_kernel(); + return old_fsgid; } @@ -727,21 +702,29 @@ asmlinkage int sys_setpgid(pid_t pid, pid_t pgid) struct task_struct * p; int err = -EINVAL; - lock_kernel(); if (!pid) pid = current->pid; if (!pgid) pgid = pid; if (pgid < 0) - goto out; + return -EINVAL; + + read_lock(&tasklist_lock); for_each_task(p) { - if (p->pid == pid) + if (p->pid == pid) { + /* NOTE: I haven't dropped tasklist_lock, this is + * on purpose. -DaveM + */ goto found_task; + } } - err = -ESRCH; - goto out; + read_unlock(&tasklist_lock); + return -ESRCH; found_task: + /* From this point forward we keep holding onto the tasklist lock + * so that our parent does not change from under us. -DaveM + */ err = -ESRCH; if (p->p_pptr == current || p->p_opptr == current) { err = -EPERM; @@ -769,30 +752,29 @@ ok_pgid: p->pgrp = pgid; err = 0; out: - unlock_kernel(); + /* All paths lead to here, thus we are safe. -DaveM */ + read_unlock(&tasklist_lock); return err; } asmlinkage int sys_getpgid(pid_t pid) { - struct task_struct * p; - int ret; - - lock_kernel(); if (!pid) { - ret = current->pgrp; + return current->pgrp; } else { + struct task_struct *p; + int ret = -ESRCH; + + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid == pid) { ret = p->pgrp; - goto out; + break; } } - ret = -ESRCH; + read_unlock(&tasklist_lock); + return ret; } -out: - unlock_kernel(); - return ret; } asmlinkage int sys_getpgrp(void) @@ -810,15 +792,15 @@ asmlinkage int sys_getsid(pid_t pid) if (!pid) { ret = current->session; } else { + ret = -ESRCH; + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid == pid) { ret = p->session; - goto out; + break; } } - ret = -ESRCH; -out: read_unlock(&tasklist_lock); } return ret; @@ -907,17 +889,11 @@ out: asmlinkage int sys_newuname(struct new_utsname * name) { - int err = -EFAULT; - - lock_kernel(); if (!name) - goto out; + return -EFAULT; if (copy_to_user(name,&system_utsname,sizeof *name)) - goto out; - err = 0; -out: - unlock_kernel(); - return err; + return -EFAULT; + return 0; } #ifndef __alpha__ @@ -926,26 +902,24 @@ out: * Move these to arch dependent dir since they are for * backward compatibility only? */ + +#ifndef __sparc__ asmlinkage int sys_uname(struct old_utsname * name) { - int error = -EFAULT; - - lock_kernel(); if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) - error = 0; - unlock_kernel(); - return error; + return 0; + return -EFAULT; } +#endif asmlinkage int sys_olduname(struct oldold_utsname * name) { - int error = -EFAULT; + int error; - lock_kernel(); if (!name) - goto out; + return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) - goto out; + return -EFAULT; error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error -= __put_user(0,name->sysname+__OLD_UTS_LEN); @@ -958,8 +932,7 @@ asmlinkage int sys_olduname(struct oldold_utsname * name) error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); error = __put_user(0,name->machine+__OLD_UTS_LEN); error = error ? -EFAULT : 0; -out: - unlock_kernel(); + return error; } @@ -967,39 +940,26 @@ out: asmlinkage int sys_sethostname(char *name, int len) { - int error = -EPERM; - - lock_kernel(); if (!suser()) - goto out; - error = -EINVAL; + return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) - goto out; - error = copy_from_user(system_utsname.nodename, name, len); - if (error) { - error = -EFAULT; - goto out; - } + return -EINVAL; + if(copy_from_user(system_utsname.nodename, name, len)) + return -EFAULT; system_utsname.nodename[len] = 0; -out: - unlock_kernel(); - return error; + return 0; } asmlinkage int sys_gethostname(char *name, int len) { - int i, err = -EINVAL; + int i; - lock_kernel(); if (len < 0) - goto out; - i = 1+strlen(system_utsname.nodename); + return -EINVAL; + i = 1 + strlen(system_utsname.nodename); if (i > len) i = len; - err = copy_to_user(name, system_utsname.nodename, i) ? -EFAULT : 0; -out: - unlock_kernel(); - return err; + return copy_to_user(name, system_utsname.nodename, i) ? -EFAULT : 0; } /* @@ -1008,66 +968,44 @@ out: */ asmlinkage int sys_setdomainname(char *name, int len) { - int error = -EPERM; - - lock_kernel(); if (!suser()) - goto out; - error = -EINVAL; + return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) - goto out; - error = copy_from_user(system_utsname.domainname, name, len); - if (error) - error = -EFAULT; - else - system_utsname.domainname[len] = 0; -out: - unlock_kernel(); - return error; + return -EINVAL; + if(copy_from_user(system_utsname.domainname, name, len)) + return -EFAULT; + system_utsname.domainname[len] = 0; + return 0; } asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim) { - int error; - - lock_kernel(); if (resource >= RLIM_NLIMITS) - error = -EINVAL; + return -EINVAL; else - error = copy_to_user(rlim, current->rlim + resource, sizeof(*rlim)) + return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim)) ? -EFAULT : 0; - unlock_kernel(); - return error; } asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim) { struct rlimit new_rlim, *old_rlim; - int err = -EINVAL; - lock_kernel(); if (resource >= RLIM_NLIMITS) - goto out; - err = copy_from_user(&new_rlim, rlim, sizeof(*rlim)); - if (err) { - err = -EFAULT; - goto out; - } + return -EINVAL; + if(copy_from_user(&new_rlim, rlim, sizeof(*rlim))) + return -EFAULT; old_rlim = current->rlim + resource; - err = -EPERM; if (((new_rlim.rlim_cur > old_rlim->rlim_max) || (new_rlim.rlim_max > old_rlim->rlim_max)) && !suser()) - goto out; + return -EPERM; if (resource == RLIMIT_NOFILE) { if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN) - goto out; + return -EPERM; } *old_rlim = new_rlim; - err = 0; -out: - unlock_kernel(); - return err; + return 0; } /* @@ -1077,13 +1015,18 @@ out: * make sense to do this. It will make moving the rest of the information * a lot simpler! (Which we're not doing right now because we're not * measuring them yet). + * + * This is SMP safe. Either we are called from sys_getrusage on ourselves + * below (we know we aren't going to exit/disappear and only we change our + * rusage counters), or we are called from wait4() on a process which is + * either stopped or zombied. In the zombied case the task won't get + * reaped till shortly after the call to getrusage(), in both cases the + * task being examined is in a frozen state so the counters won't change. */ int getrusage(struct task_struct *p, int who, struct rusage *ru) { struct rusage r; - int err; - lock_kernel(); memset((char *) &r, 0, sizeof(r)); switch (who) { case RUSAGE_SELF: @@ -1114,22 +1057,14 @@ int getrusage(struct task_struct *p, int who, struct rusage *ru) r.ru_nswap = p->nswap + p->cnswap; break; } - err = copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; - unlock_kernel(); - return err; + return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; } asmlinkage int sys_getrusage(int who, struct rusage *ru) { - int err = -EINVAL; - - lock_kernel(); if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) - goto out; - err = getrusage(current, who, ru); -out: - unlock_kernel(); - return err; + return -EINVAL; + return getrusage(current, who, ru); } asmlinkage int sys_umask(int mask) diff --git a/kernel/time.c b/kernel/time.c index 06762b2ed..d20fdbd98 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -167,20 +167,21 @@ asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz) if (tz) { if (copy_from_user(&new_tz, tz, sizeof(*tz))) return -EFAULT; - lock_kernel(); + + /* SMP safe, global irq locking makes it work. */ sys_tz = new_tz; if (firsttime) { firsttime = 0; if (!tv) warp_clock(); } - unlock_kernel(); } if (tv) { - lock_kernel(); + /* SMP safe, again the code in arch/foo/time.c should + * globally block out interrupts when it runs. + */ do_settimeofday(&new_tv); - unlock_kernel(); } return 0; } @@ -234,9 +235,7 @@ asmlinkage int sys_adjtimex(struct timex *txc_p) if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ) return -EINVAL; - lock_kernel(); - - cli(); + cli(); /* SMP: global cli() is enough protection. */ /* Save for later - semantics of adjtime is to return old value */ save_adjust = time_adjust; @@ -351,6 +350,6 @@ asmlinkage int sys_adjtimex(struct timex *txc_p) txc.stbcnt = pps_stbcnt; sti(); - unlock_kernel(); + return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state; } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 141aaace8..589f52815 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -276,8 +276,8 @@ unsigned long free_area_init(unsigned long start_mem, unsigned long end_mem) * with a minimum of 16 pages. This is totally arbitrary */ i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+7); - if (i < 16) - i = 16; + if (i < 48) + i = 48; min_free_pages = i; free_pages_low = i + (i>>1); free_pages_high = i + i; diff --git a/mm/swap.c b/mm/swap.c index 645cf09c1..7b6a0eb49 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -38,9 +38,9 @@ * * Keep these three variables contiguous for sysctl(2). */ -int min_free_pages = 20; -int free_pages_low = 30; -int free_pages_high = 40; +int min_free_pages = 48; +int free_pages_low = 72; +int free_pages_high = 96; /* We track the number of pages currently being asynchronously swapped out, so that we don't try to swap TOO many pages out at once */ diff --git a/net/bridge/br.c b/net/bridge/br.c index 67230ceed..7e8cd2a23 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -699,7 +700,7 @@ static void hold_timer_expiry(int port_no) /* (4.7.8) */ } /* (4.6.1.2.3) */ } -void br_init(void) +__initfunc(void br_init(void)) { /* (4.8.1) */ int port_no; diff --git a/net/core/dev.c b/net/core/dev.c index c6d84a0af..c02d4052e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -480,10 +480,6 @@ static void do_dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri) /* at the front or the back of the */ /* queue - front is a retransmit try */ -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif - /* * Negative priority is used to flag a frame that is being pulled from the * queue front as a retransmit attempt. It therefore goes back on the queue @@ -577,10 +573,6 @@ int dev_queue_xmit(struct sk_buff *skb) start_bh_atomic(); -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif - /* * If the address has not been resolved. Call the device header rebuilder. * This can cover all protocols and technically not just ARP either. @@ -677,9 +669,7 @@ void netif_rx(struct sk_buff *skb) /* * Add it to the "backlog" queue. */ -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif + skb_queue_tail(&backlog,skb); backlog_size++; diff --git a/net/core/net_alias.c b/net/core/net_alias.c index 147f31436..6a4a13167 100644 --- a/net/core/net_alias.c +++ b/net/core/net_alias.c @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -1359,7 +1360,7 @@ static struct proc_dir_entry proc_net_aliases = { * Net_alias initialisation called from net_dev_init(). */ -void net_alias_init(void) +__initfunc(void net_alias_init(void)) { /* diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 936e03c03..00a87e0e2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -87,509 +87,17 @@ void show_net_buffers(void) #endif } -#if CONFIG_SKB_CHECK - -/* - * Debugging paranoia. Used for debugging network stacks. - */ - -int skb_check(struct sk_buff *skb, int head, int line, char *file) -{ - if (head) { - if (skb->magic_debug_cookie != SK_HEAD_SKB) { - printk("File: %s Line %d, found a bad skb-head\n", - file,line); - return -1; - } - if (!skb->next || !skb->prev) { - printk("skb_check: head without next or prev\n"); - return -1; - } - if (skb->next->magic_debug_cookie != SK_HEAD_SKB - && skb->next->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad next head-skb member\n", - file,line); - return -1; - } - if (skb->prev->magic_debug_cookie != SK_HEAD_SKB - && skb->prev->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad prev head-skb member\n", - file,line); - return -1; - } - return 0; - } - if (skb->next != NULL && skb->next->magic_debug_cookie != SK_HEAD_SKB - && skb->next->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad next skb member\n", - file,line); - return -1; - } - if (skb->prev != NULL && skb->prev->magic_debug_cookie != SK_HEAD_SKB - && skb->prev->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad prev skb member\n", - file,line); - return -1; - } - - - if(skb->magic_debug_cookie==SK_FREED_SKB) - { - printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n", - file,line); - printk("skb=%p, real size=%d, free=%d\n", - skb,skb->truesize,skb->free); - return -1; - } - if(skb->magic_debug_cookie!=SK_GOOD_SKB) - { - printk("File: %s Line %d, passed a non skb!\n", file,line); - printk("skb=%p, real size=%d, free=%d\n", - skb,skb->truesize,skb->free); - return -1; - } - if(skb->head>skb->data) - { - printk("File: %s Line %d, head > data !\n", file,line); - printk("skb=%p, head=%p, data=%p\n", - skb,skb->head,skb->data); - return -1; - } - if(skb->tail>skb->end) - { - printk("File: %s Line %d, tail > end!\n", file,line); - printk("skb=%p, tail=%p, end=%p\n", - skb,skb->tail,skb->end); - return -1; - } - if(skb->data>skb->tail) - { - printk("File: %s Line %d, data > tail!\n", file,line); - printk("skb=%p, data=%p, tail=%p\n", - skb,skb->data,skb->tail); - return -1; - } - if(skb->tail-skb->data!=skb->len) - { - printk("File: %s Line %d, wrong length\n", file,line); - printk("skb=%p, data=%p, end=%p len=%ld\n", - skb,skb->data,skb->end,skb->len); - return -1; - } - if((unsigned long) skb->end > (unsigned long) skb) - { - printk("File: %s Line %d, control overrun\n", file,line); - printk("skb=%p, end=%p\n", - skb,skb->end); - return -1; - } - - /* Guess it might be acceptable then */ - return 0; -} -#endif - - -#if CONFIG_SKB_CHECK -void skb_queue_head_init(struct sk_buff_head *list) -{ - list->prev = (struct sk_buff *)list; - list->next = (struct sk_buff *)list; - list->qlen = 0; - list->magic_debug_cookie = SK_HEAD_SKB; -} - - -/* - * Insert an sk_buff at the start of a list. - */ -void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk) -{ - unsigned long flags; - struct sk_buff *list = (struct sk_buff *)list_; - - save_flags(flags); - cli(); - - IS_SKB(newsk); - IS_SKB_HEAD(list); - if (newsk->next || newsk->prev) - printk("Suspicious queue head: sk_buff on list!\n"); - - newsk->next = list->next; - newsk->prev = list; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - newsk->list = list_; - list_->qlen++; - - restore_flags(flags); -} - -void __skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk) -{ - struct sk_buff *list = (struct sk_buff *)list_; - - - IS_SKB(newsk); - IS_SKB_HEAD(list); - if (newsk->next || newsk->prev) - printk("Suspicious queue head: sk_buff on list!\n"); - - newsk->next = list->next; - newsk->prev = list; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - newsk->list = list_; - list_->qlen++; - -} - -/* - * Insert an sk_buff at the end of a list. - */ -void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk) -{ - unsigned long flags; - struct sk_buff *list = (struct sk_buff *)list_; - - save_flags(flags); - cli(); - - if (newsk->next || newsk->prev) - printk("Suspicious queue tail: sk_buff on list!\n"); - IS_SKB(newsk); - IS_SKB_HEAD(list); - - newsk->next = list; - newsk->prev = list->prev; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - - newsk->list = list_; - list_->qlen++; - - restore_flags(flags); -} - -void __skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk) -{ - struct sk_buff *list = (struct sk_buff *)list_; - - if (newsk->next || newsk->prev) - printk("Suspicious queue tail: sk_buff on list!\n"); - IS_SKB(newsk); - IS_SKB_HEAD(list); - - newsk->next = list; - newsk->prev = list->prev; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - - newsk->list = list_; - list_->qlen++; -} - -/* - * Remove an sk_buff from a list. This routine is also interrupt safe - * so you can grab read and free buffers as another process adds them. - */ - -struct sk_buff *skb_dequeue(struct sk_buff_head *list_) -{ - unsigned long flags; - struct sk_buff *result; - struct sk_buff *list = (struct sk_buff *)list_; - - save_flags(flags); - cli(); - - IS_SKB_HEAD(list); - - result = list->next; - if (result == list) { - restore_flags(flags); - return NULL; - } - - result->next->prev = list; - list->next = result->next; - - result->next = NULL; - result->prev = NULL; - list_->qlen--; - result->list = NULL; - - restore_flags(flags); - - IS_SKB(result); - return result; -} - -struct sk_buff *__skb_dequeue(struct sk_buff_head *list_) -{ - struct sk_buff *result; - struct sk_buff *list = (struct sk_buff *)list_; - - IS_SKB_HEAD(list); - - result = list->next; - if (result == list) { - return NULL; - } - - result->next->prev = list; - list->next = result->next; - - result->next = NULL; - result->prev = NULL; - list_->qlen--; - result->list = NULL; - - IS_SKB(result); - return result; -} - -/* - * Insert a packet before another one in a list. - */ -void skb_insert(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - IS_SKB(old); - IS_SKB(newsk); - - if(!old->next || !old->prev) - printk("insert before unlisted item!\n"); - if(newsk->next || newsk->prev) - printk("inserted item is already on a list.\n"); - - save_flags(flags); - cli(); - newsk->next = old; - newsk->prev = old->prev; - old->prev = newsk; - newsk->prev->next = newsk; - newsk->list = old->list; - newsk->list->qlen++; - - restore_flags(flags); -} - -/* - * Insert a packet before another one in a list. - */ - -void __skb_insert(struct sk_buff *newsk, - struct sk_buff * prev, struct sk_buff *next, - struct sk_buff_head * list) -{ - IS_SKB(prev); - IS_SKB(newsk); - IS_SKB(next); - - if(!prev->next || !prev->prev) - printk("insert after unlisted item!\n"); - if(!next->next || !next->prev) - printk("insert before unlisted item!\n"); - if(newsk->next || newsk->prev) - printk("inserted item is already on a list.\n"); - - newsk->next = next; - newsk->prev = prev; - next->prev = newsk; - prev->next = newsk; - newsk->list = list; - list->qlen++; - -} - -/* - * Place a packet after a given packet in a list. - */ -void skb_append(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - IS_SKB(old); - IS_SKB(newsk); - - if(!old->next || !old->prev) - printk("append before unlisted item!\n"); - if(newsk->next || newsk->prev) - printk("append item is already on a list.\n"); - - save_flags(flags); - cli(); - - newsk->prev = old; - newsk->next = old->next; - newsk->next->prev = newsk; - old->next = newsk; - newsk->list = old->list; - newsk->list->qlen++; - - restore_flags(flags); -} - -/* - * Remove an sk_buff from its list. Works even without knowing the list it - * is sitting on, which can be handy at times. It also means that THE LIST - * MUST EXIST when you unlink. Thus a list must have its contents unlinked - * _FIRST_. - */ -void skb_unlink(struct sk_buff *skb) -{ - unsigned long flags; - - save_flags(flags); - cli(); - - IS_SKB(skb); - - if(skb->list) - { - skb->list->qlen--; - skb->next->prev = skb->prev; - skb->prev->next = skb->next; - skb->next = NULL; - skb->prev = NULL; - skb->list = NULL; - } -#ifdef PARANOID_BUGHUNT_MODE /* This is legal but we sometimes want to watch it */ - else - printk("skb_unlink: not a linked element\n"); -#endif - restore_flags(flags); -} - -void __skb_unlink(struct sk_buff *skb) -{ - IS_SKB(skb); - - if(skb->list) - { - skb->list->qlen--; - skb->next->prev = skb->prev; - skb->prev->next = skb->next; - skb->next = NULL; - skb->prev = NULL; - skb->list = NULL; - } -#ifdef PARANOID_BUGHUNT_MODE /* This is legal but we sometimes want to watch it */ - else - printk("skb_unlink: not a linked element\n"); -#endif -} - -/* - * Add data to an sk_buff - */ - -unsigned char *skb_put(struct sk_buff *skb, unsigned int len) -{ - unsigned char *tmp=skb->tail; - IS_SKB(skb); - skb->tail+=len; - skb->len+=len; - IS_SKB(skb); - if(skb->tail>skb->end) - panic("skput:over: %p:%d", __builtin_return_address(0),len); - return tmp; -} - -unsigned char *skb_push(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - skb->data-=len; - skb->len+=len; - IS_SKB(skb); - if(skb->datahead) - panic("skpush:under: %p:%d", __builtin_return_address(0),len); - return skb->data; -} - -unsigned char * skb_pull(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - if(len>skb->len) - return 0; - skb->data+=len; - skb->len-=len; - return skb->data; -} - -int skb_headroom(struct sk_buff *skb) -{ - IS_SKB(skb); - return skb->data-skb->head; -} - -int skb_tailroom(struct sk_buff *skb) -{ - IS_SKB(skb); - return skb->end-skb->tail; -} - -void skb_reserve(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - skb->data+=len; - skb->tail+=len; - if(skb->tail>skb->end) - panic("sk_res: over"); - if(skb->datahead) - panic("sk_res: under"); - IS_SKB(skb); -} - -void skb_trim(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - if(skb->len>len) - { - skb->len=len; - skb->tail=skb->data+len; - } -} - - - -#endif - -/************************************************************************** - - Stuff below this point isn't debugging duplicates of the inlines - used for buffer handling - -***************************************************************************/ - /* * Free an sk_buff. Release anything attached to the buffer. */ void __kfree_skb(struct sk_buff *skb) { -#if CONFIG_SKB_CHECK - if (skb == NULL) - { - printk(KERN_CRIT "kfree_skb: skb = NULL (from %p)\n", - __builtin_return_address(0)); - return; - } - IS_SKB(skb); -#endif if (skb->list) - printk(KERN_WARNING "Warning: kfree_skb passed an skb still on a list (from %p).\n", - __builtin_return_address(0)); + printk(KERN_WARNING "Warning: kfree_skb passed an skb still " + "on a list (from %p).\n", __builtin_return_address(0)); dst_release(skb->dst); - if(skb->destructor) skb->destructor(skb); kfree_skbmem(skb); @@ -607,15 +115,14 @@ void __kfree_skb(struct sk_buff *skb) struct sk_buff *alloc_skb(unsigned int size,int priority) { struct sk_buff *skb; - int len; unsigned char *bptr; + int len; - if (in_interrupt() && priority!=GFP_ATOMIC) - { + if (in_interrupt() && priority!=GFP_ATOMIC) { static int count = 0; if (++count < 5) { - printk(KERN_ERR "alloc_skb called nonatomically from interrupt %p\n", - __builtin_return_address(0)); + printk(KERN_ERR "alloc_skb called nonatomically " + "from interrupt %p\n", __builtin_return_address(0)); priority = GFP_ATOMIC; } } @@ -625,25 +132,23 @@ struct sk_buff *alloc_skb(unsigned int size,int priority) * 'alignment mask'. */ - size=(size+15)&~15; /* Allow for alignments. Make a multiple of 16 bytes */ + /* Allow for alignments. Make a multiple of 16 bytes */ + size = (size + 15) & ~15; len = size; - size+=sizeof(struct sk_buff); /* And stick the control itself on the end */ + /* And stick the control itself on the end */ + size += sizeof(struct sk_buff); /* * Allocate some space */ - bptr=(unsigned char *)kmalloc(size,priority); - if (bptr == NULL) - { + bptr = kmalloc(size,priority); + if (bptr == NULL) { atomic_inc(&net_fails); return NULL; } -#ifdef PARANOID_BUGHUNT_MODE - if(skb->magic_debug_cookie == SK_GOOD_SKB) - printk("Kernel kmalloc handed us an existing skb (%p)\n",skb); -#endif + /* * Now we play a little game with the caches. Linux kmalloc is * a bit cache dumb, in fact its just about maximally non @@ -653,7 +158,7 @@ struct sk_buff *alloc_skb(unsigned int size,int priority) */ atomic_inc(&net_allocs); - skb=(struct sk_buff *)(bptr+size)-1; + skb = (struct sk_buff *)(bptr + size) - 1; atomic_set(&skb->count, 1); /* only one reference to this */ skb->data_skb = skb; /* and we're our own data skb */ @@ -672,16 +177,14 @@ struct sk_buff *alloc_skb(unsigned int size,int priority) memset(skb->cb, 0, sizeof(skb->cb)); skb->priority = SOPRI_NORMAL; atomic_inc(&net_skbcount); -#if CONFIG_SKB_CHECK - skb->magic_debug_cookie = SK_GOOD_SKB; -#endif atomic_set(&skb->users, 1); - /* Load the data pointers */ - skb->head=bptr; - skb->data=bptr; - skb->tail=bptr; - skb->end=bptr+len; - skb->len=0; + + /* Load the data pointers. */ + skb->head = bptr; + skb->data = bptr; + skb->tail = bptr; + skb->end = bptr + len; + skb->len = 0; skb->inclone = 0; return skb; } @@ -705,10 +208,7 @@ void kfree_skbmem(struct sk_buff *skb) /* don't do anything if somebody still uses us */ if (atomic_dec_and_test(&skb->count)) { - - int free_head; - - free_head = (skb->inclone != SKB_CLONE_INLINE); + int free_head = (skb->inclone != SKB_CLONE_INLINE); /* free the skb that contains the actual data if we've clone()'d */ if (skb->data_skb != skb) { @@ -730,16 +230,12 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int priority) struct sk_buff *n; int inbuff = 0; - IS_SKB(skb); - if (!skb->inclone && skb_tailroom(skb) >= sizeof(struct sk_buff)) - { + if (!skb->inclone && skb_tailroom(skb) >= sizeof(struct sk_buff)) { n = ((struct sk_buff *) skb->end) - 1; skb->end -= sizeof(struct sk_buff); skb->inclone = SKB_CLONE_ORIG; inbuff = SKB_CLONE_INLINE; - } - else - { + } else { n = kmalloc(sizeof(*n), priority); if (!n) return NULL; @@ -775,8 +271,6 @@ struct sk_buff *skb_copy(struct sk_buff *skb, int priority) * Allocate the copy buffer */ - IS_SKB(skb); - n=alloc_skb(skb->end - skb->head, priority); if(n==NULL) return NULL; @@ -806,7 +300,6 @@ struct sk_buff *skb_copy(struct sk_buff *skb, int priority) n->seq=skb->seq; n->end_seq=skb->end_seq; n->ack_seq=skb->ack_seq; - n->acked=skb->acked; memcpy(n->cb, skb->cb, sizeof(skb->cb)); n->used=skb->used; n->arp=skb->arp; @@ -816,7 +309,6 @@ struct sk_buff *skb_copy(struct sk_buff *skb, int priority) n->stamp=skb->stamp; n->destructor = NULL; n->security=skb->security; - IS_SKB(n); return n; } @@ -830,8 +322,6 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom) * Allocate the copy buffer */ - IS_SKB(skb); - n=alloc_skb(skb->truesize+newheadroom-headroom-sizeof(struct sk_buff), GFP_ATOMIC); if(n==NULL) return NULL; @@ -862,7 +352,6 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom) n->seq=skb->seq; n->end_seq=skb->end_seq; n->ack_seq=skb->ack_seq; - n->acked=skb->acked; n->used=skb->used; n->arp=skb->arp; n->tries=0; @@ -872,7 +361,6 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom) n->destructor = NULL; n->security=skb->security; - IS_SKB(n); return n; } diff --git a/net/core/sock.c b/net/core/sock.c index b512cd459..8c008c0f2 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -479,9 +479,6 @@ void sk_init(void) void sock_wfree(struct sk_buff *skb) { struct sock *sk = skb->sk; -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif #if 1 if (!sk) { printk(KERN_DEBUG "sock_wfree: sk==NULL\n"); @@ -497,9 +494,6 @@ void sock_wfree(struct sk_buff *skb) void sock_rfree(struct sk_buff *skb) { struct sock *sk = skb->sk; -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif #if 1 if (!sk) { printk(KERN_DEBUG "sock_rfree: sk==NULL\n"); diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index b03bea8f1..9f4477807 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -295,7 +295,6 @@ void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int struct iphdr *iph; int ip_length; - IS_SKB(dest); eth=(struct ethhdr *)src; if(eth->h_proto!=htons(ETH_P_IP)) { diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index b6db1eb7a..6b697d001 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -754,7 +754,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len) if(__ip_chk_addr(iph->daddr)==IS_BROADCAST) { printk("%s sent an invalid ICMP error to a broadcast.\n", - in_ntoa(iph->daddr)); + in_ntoa(skb->nh.iph->saddr)); kfree_skb(skb, FREE_READ); } diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 33c139663..bf549b047 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -177,7 +177,6 @@ static void ip_free(struct ipq *qp) while (fp != NULL) { xp = fp->next; - IS_SKB(fp->skb); frag_kfree_skb(fp->skb,FREE_READ); frag_kfree_s(fp, sizeof(struct ipfrag)); fp = xp; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index b05b10be7..1689159ed 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -296,10 +296,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt if (sk->ip_recverr && !val) { struct sk_buff *skb; /* Drain queued errors */ - while((skb=skb_dequeue(&sk->error_queue))!=NULL) { - IS_SKB(skb); + while((skb=skb_dequeue(&sk->error_queue))!=NULL) kfree_skb(skb, FREE_READ); - } } sk->ip_recverr = val?1:0; release_sock(sk); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 162981feb..e3b41e2ad 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -124,7 +124,7 @@ get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t of format==0?sp->write_seq-tp->snd_una:atomic_read(&sp->wmem_alloc), format==0?tp->rcv_nxt-sp->copied_seq:atomic_read(&sp->rmem_alloc), timer_active, timer_expires-jiffies, - (unsigned) atomic_read(&sp->retransmits), + tp->retransmits, sp->socket ? sp->socket->inode->i_uid:0, timer_active?sp->timeout:0, sp->socket ? sp->socket->inode->i_ino:0); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index a121ef5ae..84ba6578b 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -36,6 +36,12 @@ extern int sysctl_arp_confirm_interval; extern int sysctl_arp_confirm_timeout; extern int sysctl_tcp_cong_avoidance; +extern int sysctl_tcp_hoe_retransmits; +extern int sysctl_tcp_sack; +extern int sysctl_tcp_tsack; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; + extern int tcp_sysctl_congavoid(ctl_table *ctl, int write, struct file * filp, void *buffer, size_t *lenp); @@ -81,6 +87,21 @@ ctl_table ipv4_table[] = { {NET_IPV4_ARP_CONFIRM_TIMEOUT, "arp_confirm_timeout", &sysctl_arp_confirm_timeout, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_TCP_HOE_RETRANSMITS, "tcp_hoe_retransmits", + &sysctl_tcp_hoe_retransmits, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_TCP_SACK, "tcp_sack", + &sysctl_tcp_sack, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_TCP_TSACK, "tcp_tsack", + &sysctl_tcp_tsack, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_TCP_TIMESTAMPS, "tcp_timestamps", + &sysctl_tcp_timestamps, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_TCP_WINDOW_SCALING, "tcp_window_scaling", + &sysctl_tcp_window_scaling, sizeof(int), 0644, NULL, + &proc_dointvec}, {NET_IPV4_TCP_VEGAS_CONG_AVOID, "tcp_vegas_cong_avoid", &sysctl_tcp_cong_avoidance, sizeof(int), 0644, NULL, &tcp_sysctl_congavoid }, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8a48dff8d..420db4777 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.56 1997/04/16 09:18:42 davem Exp $ + * Version: $Id: tcp.c,v 1.61 1997/04/22 02:53:10 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -444,15 +444,14 @@ static struct open_request *tcp_find_established(struct tcp_opt *tp) { struct open_request *req = tp->syn_wait_queue; - if (!req) - return NULL; - do { + while(req) { if (req->sk && (req->sk->state == TCP_ESTABLISHED || req->sk->state >= TCP_FIN_WAIT1)) - return req; - } while ((req = req->dl_next) != tp->syn_wait_queue); - return NULL; + break; + req = req->dl_next; + } + return req; } /* @@ -466,9 +465,7 @@ static void tcp_close_pending (struct sock *sk) struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct open_request *req = tp->syn_wait_queue; - if (!req) - return; - do { + while(req) { struct open_request *iter; if (req->sk) @@ -481,9 +478,10 @@ static void tcp_close_pending (struct sock *sk) tcp_dec_slow_timer(TCP_SLT_SYNACK); sk->ack_backlog--; tcp_openreq_free(iter); - } while (req != tp->syn_wait_queue); + } tp->syn_wait_queue = NULL; + tp->syn_wait_last = &tp->syn_wait_queue; } /* @@ -518,8 +516,7 @@ static int tcp_readable(struct sock *sk) save_flags(flags); cli(); - if (sk == NULL || (skb = skb_peek(&sk->receive_queue)) == NULL) - { + if (sk == NULL || (skb = skb_peek(&sk->receive_queue)) == NULL) { restore_flags(flags); SOCK_DEBUG(sk, "empty\n"); return(0); @@ -528,32 +525,27 @@ static int tcp_readable(struct sock *sk) counted = sk->copied_seq; /* Where we are at the moment */ amount = 0; - /* - * Do until a push or until we are out of data. - */ - - do - { - /* Found a hole so stops here */ + /* Do until a push or until we are out of data. */ + do { + /* Found a hole so stops here. */ if (before(counted, skb->seq)) break; - /* - * Length - header but start from where we are up to - * avoid overlaps + + /* Length - header but start from where we are up to + * avoid overlaps. */ - sum = skb->len - (counted - skb->seq); + sum = skb->len - (counted - skb->seq); if (skb->h.th->syn) sum++; - if (sum > 0) - { - /* Add it up, move on */ + if (sum > 0) { + /* Add it up, move on. */ amount += sum; if (skb->h.th->syn) amount--; counted += sum; } - /* - * Don't count urg data ... but do it in the right place! + + /* Don't count urg data ... but do it in the right place! * Consider: "old_data (ptr is here) URG PUSH data" * The old code would stop at the first push because * it counted the urg (amount==1) and then does amount-- @@ -569,15 +561,14 @@ static int tcp_readable(struct sock *sk) * was correct. Mike */ - /* don't count urg data */ + /* Don't count urg data. */ if (skb->h.th->urg) amount--; #if 0 if (amount && skb->h.th->psh) break; #endif skb = skb->next; - } - while(skb != (struct sk_buff *)&sk->receive_queue); + } while(skb != (struct sk_buff *)&sk->receive_queue); restore_flags(flags); SOCK_DEBUG(sk, "got %lu bytes.\n",amount); @@ -619,18 +610,20 @@ unsigned int tcp_poll(struct socket *sock, poll_table *wait) mask = 0; if (sk->err) mask = POLLERR; - /* connected ? */ + /* Connected? */ if (sk->state != TCP_SYN_SENT && sk->state != TCP_SYN_RECV) { - if (sk->shutdown & RCV_SHUTDOWN) mask |= POLLHUP; - + if ((tp->rcv_nxt != sk->copied_seq) && (sk->urg_seq != sk->copied_seq || tp->rcv_nxt != sk->copied_seq+1 || sk->urginline || !sk->urg_data)) mask |= POLLIN | POLLRDNORM; + /* FIXME: this assumed sk->mtu is correctly maintained. + * I see no evidence this is the case. -- erics + */ if (!(sk->shutdown & SEND_SHUTDOWN) && (sock_wspace(sk) >= sk->mtu+128+sk->prot->max_header)) mask |= POLLOUT | POLLWRNORM; @@ -643,9 +636,7 @@ unsigned int tcp_poll(struct socket *sock, poll_table *wait) int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) { - switch(cmd) - { - + switch(cmd) { case TIOCINQ: #ifdef FIXME /* FIXME: */ case FIONREAD: @@ -676,28 +667,39 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) } default: return(-EINVAL); - } + }; } /* * This routine builds a generic TCP header. + * It also builds in the RFC1323 Timestamp. + * It can't (unfortunately) do SACK as well. */ -extern __inline int tcp_build_header(struct tcphdr *th, struct sock *sk, int push) +extern __inline void tcp_build_header(struct tcphdr *th, struct sock *sk, int push) { - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + memcpy(th,(void *) &(sk->dummy_th), sizeof(*th)); th->seq = htonl(sk->write_seq); - th->psh =(push == 0) ? 1 : 0; - - sk->bytes_rcv = 0; - sk->ack_timed = 0; th->ack_seq = htonl(tp->rcv_nxt); th->window = htons(tcp_select_window(sk)); - return(sizeof(*th)); + /* FIXME: could use the inline found in tcp_output.c as well. + * Probably that means we should move these up to an include file. --erics + */ + if (tp->tstamp_ok) { + __u32 *ptr = (__u32 *)(th+1); + *ptr++ = ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + /* FIXME: Not sure it's worth setting these here already, but I'm + * also not sure we replace them on all paths later. --erics + */ + *ptr++ = jiffies; + *ptr++ = tp->ts_recent; + } } /* @@ -708,9 +710,7 @@ static void wait_for_tcp_connect(struct sock * sk) release_sock(sk); cli(); if (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT && sk->err == 0) - { interruptible_sleep_on(sk->sleep); - } sti(); lock_sock(sk); } @@ -756,22 +756,15 @@ static int tcp_append_tail(struct sock *sk, struct sk_buff *skb, u8 *from, int fault; int copy; - /* - * Add more stuff to the end - * of the skb - */ - + /* Add more stuff to the end of the skb. */ copy = min(sk->mss - tcp_size, skb_tailroom(skb)); copy = min(copy, seglen); tcp_size += copy; fault = copy_from_user(skb->tail, from, copy); - if (fault) - { return -1; - } skb_put(skb, copy); skb->csum = csum_partial(skb->tail - tcp_size, tcp_size, 0); @@ -793,19 +786,12 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) int copied = 0; struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); - /* - * Wait for a connection to finish. - */ - while (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT) - { - if (copied) - return copied; - + /* Wait for a connection to finish. */ + while (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT) { if (sk->err) return sock_error(sk); - if (sk->state != TCP_SYN_SENT && sk->state != TCP_SYN_RECV) - { + if (sk->state != TCP_SYN_SENT && sk->state != TCP_SYN_RECV) { if (sk->keepopen) send_sig(SIGPIPE, current, 0); return -EPIPE; @@ -820,19 +806,14 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) wait_for_tcp_connect(sk); } - /* - * Ok commence sending - */ - - while(--iovlen >= 0) - { + /* Ok commence sending. */ + while(--iovlen >= 0) { int seglen=iov->iov_len; unsigned char * from=iov->iov_base; iov++; - while(seglen > 0) - { + while(seglen > 0) { unsigned int actual_win; int copy; int tmp; @@ -840,142 +821,110 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) if (err) return (err); - /* - * Stop on errors - */ - if (sk->err) - { + + /* Stop on errors. */ + if (sk->err) { if (copied) return copied; return sock_error(sk); } - /* - * Make sure that we are established. - */ - if (sk->shutdown & SEND_SHUTDOWN) - { + /* Make sure that we are established. */ + if (sk->shutdown & SEND_SHUTDOWN) { if (copied) return copied; send_sig(SIGPIPE,current,0); return -EPIPE; } - /* - * Now we need to check if we have a half built packet. - */ + /* Now we need to check if we have a half built packet. */ - /* if we have queued packets */ - if (tp->send_head && !(flags & MSG_OOB) ) - { + /* If we have queued packets.. */ + if (tp->send_head && !(flags & MSG_OOB)) { int tcp_size; /* Tail */ skb = sk->write_queue.prev; tcp_size = skb->tail - - (unsigned char *)(skb->h.th + 1); + ((unsigned char *)(skb->h.th) + tp->tcp_header_len); - /* - * This window_seq test is somewhat dangerous + /* printk("extending buffer\n"); */ + /* This window_seq test is somewhat dangerous * If the remote does SWS avoidance we should * queue the best we can if not we should in * fact send multiple packets... * a method for detecting this would be most * welcome */ - if (skb->end > skb->tail && sk->mss - tcp_size > 0 && - tp->snd_nxt < skb->end_seq) - { + tp->snd_nxt < skb->end_seq) { int tcopy; - + tcopy = tcp_append_tail(sk, skb, from, tcp_size, seglen); if (tcopy == -1) - { return -EFAULT; - } from += tcopy; copied += tcopy; seglen -= tcopy; - /* - * FIXME: if we're nagling we + /* FIXME: if we're nagling we * should send here. */ continue; } } - - /* - * We also need to worry about the window. - * If window < 1/2 the maximum window we've seen from this - * host, don't use it. This is sender side - * silly window prevention, as specified in RFC1122. - * (Note that this is different than earlier versions of - * SWS prevention, e.g. RFC813.). What we actually do is - * use the whole MSS. Since the results in the right - * edge of the packet being outside the window, it will - * be queued for later rather than sent. - */ - + /* We also need to worry about the window. + * If window < 1/2 the maximum window we've seen from this + * host, don't use it. This is sender side + * silly window prevention, as specified in RFC1122. + * (Note that this is different than earlier versions of + * SWS prevention, e.g. RFC813.). What we actually do is + * use the whole MSS. Since the results in the right + * edge of the packet being outside the window, it will + * be queued for later rather than sent. + */ copy = min(seglen, sk->mss); - actual_win = tp->snd_wnd - (tp->snd_nxt - tp->snd_una); if (copy > actual_win && - (((int) actual_win) >= (sk->max_window >> 1)) - && actual_win) - { + (((int) actual_win) >= (tp->max_window >> 1)) && + actual_win) copy = actual_win; - } - if (copy <= 0) - { + if (copy <= 0) { printk(KERN_DEBUG "sendmsg: copy < 0\n"); return -EIO; } - /* - * If sk->packets_out > 0 segment will be nagled - * else we kick it right away + /* If tp->packets_out > 0 segment will be nagled + * else we kick it right away. */ - tmp = MAX_HEADER + sk->prot->max_header + sizeof(struct sk_buff) + 15; - if (copy < min(sk->mss, sk->max_window >> 1) && - !(flags & MSG_OOB) && sk->packets_out) - { - tmp += min(sk->mss, sk->max_window); - } + if (copy < min(sk->mss, tp->max_window >> 1) && + !(flags & MSG_OOB) && tp->packets_out) + tmp += min(sk->mss, tp->max_window); else - { tmp += copy; - } skb = sock_wmalloc(sk, tmp, 0, GFP_KERNEL); - /* - * If we didn't get any memory, we need to sleep. - */ - - if (skb == NULL) - { + /* If we didn't get any memory, we need to sleep. */ + if (skb == NULL) { sk->socket->flags |= SO_NOSPACE; - if (flags&MSG_DONTWAIT) - { + if (flags&MSG_DONTWAIT) { if (copied) return copied; return -EAGAIN; } - if (current->signal & ~current->blocked) - { + if (current->signal & ~current->blocked) { if (copied) return copied; return -ERESTARTSYS; @@ -985,37 +934,25 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) continue; } - /* - * FIXME: we need to optimize this. + /* FIXME: we need to optimize this. * Perhaps some hints here would be good. */ - tmp = tp->af_specific->build_net_header(sk, skb); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(skb, FREE_WRITE); if (copied) return(copied); return(tmp); } - skb->h.th =(struct tcphdr *) - skb_put(skb,sizeof(struct tcphdr)); + skb->h.th =(struct tcphdr *) + skb_put(skb,tp->tcp_header_len); seglen -= copy; - tmp = tcp_build_header(skb->h.th, sk, seglen || iovlen); - - if (tmp < 0) - { - kfree_skb(skb, FREE_WRITE); - if (copied) - return(copied); - return(tmp); - } - - if (flags & MSG_OOB) - { + tcp_build_header(skb->h.th, sk, seglen || iovlen); + /* FIXME: still need to think about SACK options here. */ + + if (flags & MSG_OOB) { skb->h.th->urg = 1; skb->h.th->urg_ptr = ntohs(copy); } @@ -1027,7 +964,7 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) copied += copy; sk->write_seq += copy; - + tcp_send_skb(sk, skb); release_sock(sk); @@ -1043,9 +980,6 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) return copied; } - - - /* * Send an ack if one is backlogged at this point. Ought to merge * this with tcp_send_ack(). @@ -1054,18 +988,15 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) void tcp_read_wakeup(struct sock *sk) { - /* - * If we're closed, don't send an ack, or we'll get a RST + /* If we're closed, don't send an ack, or we'll get a RST * from the closed destination. */ - if ((sk->state == TCP_CLOSE) || (sk->state == TCP_TIME_WAIT)) return; tcp_send_ack(sk); } - /* * Handle reading urgent data. BSD has very simple semantics for * this, no blocking and very strange errors 8) @@ -1078,33 +1009,28 @@ static int tcp_recv_urg(struct sock * sk, int nonblock, int err=0; struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * No URG data to read - */ + /* No URG data to read. */ if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ) return -EINVAL; /* Yes this is right ! */ if (sk->err) return sock_error(sk); - if (sk->state == TCP_CLOSE || sk->done) - { - if (!sk->done) - { + if (sk->state == TCP_CLOSE || sk->done) { + if (!sk->done) { sk->done = 1; return 0; } return -ENOTCONN; } - if (sk->shutdown & RCV_SHUTDOWN) - { + if (sk->shutdown & RCV_SHUTDOWN) { sk->done = 1; return 0; } + lock_sock(sk); - if (sk->urg_data & URG_VALID) - { + if (sk->urg_data & URG_VALID) { char c = sk->urg_data; if (!(flags & MSG_PEEK)) sk->urg_data = URG_READ; @@ -1115,23 +1041,20 @@ static int tcp_recv_urg(struct sock * sk, int nonblock, msg->msg_flags|=MSG_TRUNC; if(msg->msg_name) - { tp->af_specific->addr2sockaddr(sk, (struct sockaddr *) msg->msg_name); - } + if(addr_len) *addr_len = tp->af_specific->sockaddr_len; - /* - * Read urgent data - */ + + /* Read urgent data. */ msg->msg_flags|=MSG_OOB; release_sock(sk); return err ? -EFAULT : 1; } release_sock(sk); - /* - * Fixed the recv(..., MSG_OOB) behaviour. BSD docs and + /* Fixed the recv(..., MSG_OOB) behaviour. BSD docs and * the available implementations agree in this case: * this call should never block, independent of the * blocking state of the socket. @@ -1148,7 +1071,7 @@ static int tcp_recv_urg(struct sock * sk, int nonblock, static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb) { - sk->delayed_acks++; + sk->tp_pinfo.af_tcp.delayed_acks++; __skb_unlink(skb, &sk->receive_queue); kfree_skb(skb, FREE_READ); @@ -1159,11 +1082,9 @@ static void cleanup_rbuf(struct sock *sk) { struct sk_buff *skb; - /* - * NOTE! The socket must be locked, so that we don't get + /* NOTE! The socket must be locked, so that we don't get * a messed-up receive queue. */ - while ((skb=skb_peek(&sk->receive_queue)) != NULL) { if (!skb->used || atomic_read(&skb->users)>1) break; @@ -1172,13 +1093,10 @@ static void cleanup_rbuf(struct sock *sk) SOCK_DEBUG(sk, "sk->rspace = %lu\n", sock_rspace(sk)); - /* - * We send a ACK if the sender is blocked - * else let tcp_data deal with the acking policy. + /* We send a ACK if the sender is blocked + * else let tcp_data deal with the acking policy. */ - - if (sk->delayed_acks) - { + if (sk->tp_pinfo.af_tcp.delayed_acks) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); __u32 rcv_wnd; @@ -1209,47 +1127,34 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, if (sk->state == TCP_LISTEN) return -ENOTCONN; - /* - * Urgent data needs to be handled specially. - */ - + /* Urgent data needs to be handled specially. */ if (flags & MSG_OOB) return tcp_recv_urg(sk, nonblock, msg, len, flags, addr_len); - /* - * Copying sequence to update. This is volatile to handle + /* Copying sequence to update. This is volatile to handle * the multi-reader case neatly (memcpy_to/fromfs might be * inline and thus not flush cached variables otherwise). */ - peek_seq = sk->copied_seq; seq = &sk->copied_seq; if (flags & MSG_PEEK) seq = &peek_seq; - /* - * Handle the POSIX bogosity MSG_WAITALL - */ - + /* Handle the POSIX bogosity MSG_WAITALL. */ if (flags & MSG_WAITALL) target=len; add_wait_queue(sk->sleep, &wait); lock_sock(sk); - while (len > 0) - { + while (len > 0) { struct sk_buff * skb; u32 offset; - /* - * Are we at urgent data? Stop if we have read anything. - */ - + /* Are we at urgent data? Stop if we have read anything. */ if (copied && sk->urg_data && sk->urg_seq == *seq) break; - /* - * We need to check signals first, to get correct SIGURG + /* We need to check signals first, to get correct SIGURG * handling. FIXME: Need to check this doesnt impact 1003.1g * and move it down to the bottom of the loop */ @@ -1262,20 +1167,16 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, break; } - /* - * Next get a buffer. - */ - + /* Next get a buffer. */ current->state = TASK_INTERRUPTIBLE; skb = skb_peek(&sk->receive_queue); - do - { + do { if (!skb) break; - /* - * now that we have two receive queues this - * shouldn't happen + + /* Now that we have two receive queues this + * shouldn't happen. */ if (before(*seq, skb->seq)) { printk(KERN_INFO "recvmsg bug: copied %X seq %X\n", @@ -1292,22 +1193,18 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, if (!(flags & MSG_PEEK)) skb->used = 1; skb = skb->next; - } - while (skb != (struct sk_buff *)&sk->receive_queue); + } while (skb != (struct sk_buff *)&sk->receive_queue); if (copied >= target) break; - if (sk->err && !(flags&MSG_PEEK)) - { + if (sk->err && !(flags&MSG_PEEK)) { copied = sock_error(sk); break; } - if (sk->state == TCP_CLOSE) - { - if (!sk->done) - { + if (sk->state == TCP_CLOSE) { + if (!sk->done) { sk->done = 1; break; } @@ -1315,14 +1212,12 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, break; } - if (sk->shutdown & RCV_SHUTDOWN) - { + if (sk->shutdown & RCV_SHUTDOWN) { sk->done = 1; break; } - if (nonblock) - { + if (nonblock) { copied = -EAGAIN; break; } @@ -1336,65 +1231,46 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, continue; found_ok_skb: - /* - * Lock the buffer. We can be fairly relaxed as + /* Lock the buffer. We can be fairly relaxed as * an interrupt will never steal a buffer we are * using unless I've missed something serious in * tcp_data. */ - atomic_inc(&skb->users); - /* - * Ok so how much can we use ? - */ - + /* Ok so how much can we use? */ used = skb->len - offset; if (len < used) used = len; - /* - * Do we have urgent data here? - */ - if (sk->urg_data) - { + /* Do we have urgent data here? */ + if (sk->urg_data) { u32 urg_offset = sk->urg_seq - *seq; - if (urg_offset < used) - { - if (!urg_offset) - { - if (!sk->urginline) - { + if (urg_offset < used) { + if (!urg_offset) { + if (!sk->urginline) { ++*seq; offset++; used--; } - } - else + } else used = urg_offset; } } - /* - * Copy it - We _MUST_ update *seq first so that we + /* Copy it - We _MUST_ update *seq first so that we * don't ever double read when we have dual readers */ - *seq += used; - /* - * This memcpy_toiovec can sleep. If it sleeps and we + /* This memcpy_toiovec can sleep. If it sleeps and we * do a second read it relies on the skb->users to avoid * a crash when cleanup_rbuf() gets called. */ - err = memcpy_toiovec(msg->msg_iov, ((unsigned char *)skb->h.th) + skb->h.th->doff*4 + offset, used); - if (err) - { - /* - * exception. bailout! - */ + if (err) { + /* Exception. Bailout! */ *seq -= err; atomic_dec(&skb->users); copied = -EFAULT; @@ -1404,12 +1280,10 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, copied += used; len -= used; - /* - * We now will not sleep again until we are finished + /* We now will not sleep again until we are finished * with skb. Sorry if you are doing the SMP port * but you'll just have to fix it neatly ;) */ - atomic_dec(&skb->users); if (after(sk->copied_seq,sk->urg_seq)) @@ -1417,11 +1291,9 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, if (used + offset < skb->len) continue; - /* - * Process the FIN. We may also need to handle PSH - * here and make it break out of MSG_WAITALL + /* Process the FIN. We may also need to handle PSH + * here and make it break out of MSG_WAITALL. */ - if (skb->h.th->fin) goto found_fin_ok; if (flags & MSG_PEEK) @@ -1436,35 +1308,28 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, if (flags & MSG_PEEK) break; - /* - * All is done - */ - + /* All is done. */ skb->used = 1; sk->shutdown |= RCV_SHUTDOWN; break; - } if(copied > 0 && msg->msg_name) - { tp->af_specific->addr2sockaddr(sk, (struct sockaddr *) msg->msg_name); - } + if(addr_len) *addr_len = tp->af_specific->sockaddr_len; remove_wait_queue(sk->sleep, &wait); current->state = TASK_RUNNING; - /* Clean up data we have read: This will do ACK frames */ + /* Clean up data we have read: This will do ACK frames. */ cleanup_rbuf(sk); release_sock(sk); return copied; } - - /* * State processing on a close. This implements the state shift for * sending our FIN frame. Note that we only send a FIN for some @@ -1476,8 +1341,7 @@ static int tcp_close_state(struct sock *sk, int dead) { int ns=TCP_CLOSE; int send_fin=0; - switch(sk->state) - { + switch(sk->state) { case TCP_SYN_SENT: /* No SYN back, no FIN needed */ break; case TCP_SYN_RECV: @@ -1498,12 +1362,11 @@ static int tcp_close_state(struct sock *sk, int dead) wait only for the ACK */ ns=TCP_LAST_ACK; send_fin=1; - } + }; tcp_set_state(sk,ns); - /* - * This is a (useful) BSD violating of the RFC. There is a + /* This is a (useful) BSD violating of the RFC. There is a * problem with TCP as specified in that the other end could * keep a socket open forever with no application left this end. * We use a 3 minute timeout (about the same as BSD) then kill @@ -1511,8 +1374,7 @@ static int tcp_close_state(struct sock *sk, int dead) * that we won't make the old 4*rto = almost no time - whoops * reset mistake. */ - if(dead && ns==TCP_FIN_WAIT2) - { + if(dead && ns==TCP_FIN_WAIT2) { int timer_active=del_timer(&sk->timer); if(timer_active) add_timer(&sk->timer); @@ -1530,50 +1392,29 @@ static int tcp_close_state(struct sock *sk, int dead) void tcp_shutdown(struct sock *sk, int how) { - /* - * We need to grab some memory, and put together a FIN, + /* We need to grab some memory, and put together a FIN, * and then put it into the queue to be sent. * Tim MacKenzie(tym@dibbler.cs.monash.edu.au) 4 Dec '92. */ - if (!(how & SEND_SHUTDOWN)) return; - /* - * If we've already sent a FIN, or it's a closed state - */ - - if (sk->state == TCP_FIN_WAIT1 || - sk->state == TCP_FIN_WAIT2 || - sk->state == TCP_CLOSING || - sk->state == TCP_LAST_ACK || - sk->state == TCP_TIME_WAIT || - sk->state == TCP_CLOSE || - sk->state == TCP_LISTEN - ) - { - return; - } - lock_sock(sk); - - /* - * flag that the sender has shutdown - */ - - sk->shutdown |= SEND_SHUTDOWN; - - /* - * Clear out any half completed packets. - */ + /* If we've already sent a FIN, or it's a closed state, skip this. */ + if (sk->state == TCP_ESTABLISHED || + sk->state == TCP_SYN_SENT || + sk->state == TCP_SYN_RECV || + sk->state == TCP_CLOSE_WAIT) { + lock_sock(sk); - /* - * FIN if needed - */ + /* Flag that the sender has shutdown. */ + sk->shutdown |= SEND_SHUTDOWN; - if (tcp_close_state(sk,0)) - tcp_send_fin(sk); + /* Clear out any half completed packets. FIN if needed. */ + if (tcp_close_state(sk,0)) + tcp_send_fin(sk); - release_sock(sk); + release_sock(sk); + } } @@ -1588,7 +1429,7 @@ static inline int closing(struct sock * sk) case TCP_CLOSING: case TCP_LAST_ACK: return 1; - } + }; return 0; } @@ -1597,16 +1438,12 @@ void tcp_close(struct sock *sk, unsigned long timeout) { struct sk_buff *skb; - /* - * We need to grab some memory, and put together a FIN, + /* We need to grab some memory, and put together a FIN, * and then put it into the queue to be sent. */ - lock_sock(sk); - - if(sk->state == TCP_LISTEN) - { - /* Special case */ + if(sk->state == TCP_LISTEN) { + /* Special case. */ tcp_set_state(sk, TCP_CLOSE); tcp_close_pending(sk); release_sock(sk); @@ -1621,37 +1458,27 @@ void tcp_close(struct sock *sk, unsigned long timeout) if (!sk->dead) sk->state_change(sk); - /* - * We need to flush the recv. buffs. We do this only on the + /* We need to flush the recv. buffs. We do this only on the * descriptor close, not protocol-sourced closes, because the * reader process may not have drained the data yet! */ - while((skb=skb_dequeue(&sk->receive_queue))!=NULL) kfree_skb(skb, FREE_READ); - - /* - * Timeout is not the same thing - however the code likes - * to send both the same way (sigh). + /* Timeout is not the same thing - however the code likes + * to send both the same way (sigh). */ - if (tcp_close_state(sk,1)==1) - { tcp_send_fin(sk); - } if (timeout) { cli(); release_sock(sk); current->timeout = timeout; - while(closing(sk) && current->timeout) - { + while(closing(sk) && current->timeout) { interruptible_sleep_on(sk->sleep); if (current->signal & ~current->blocked) - { break; - } } current->timeout=0; lock_sock(sk); @@ -1661,8 +1488,7 @@ void tcp_close(struct sock *sk, unsigned long timeout) /* Now that the socket is dead, if we are in the FIN_WAIT2 state * we may need to set up a timer. */ - if (sk->state==TCP_FIN_WAIT2) - { + if (sk->state==TCP_FIN_WAIT2) { int timer_active=del_timer(&sk->timer); if(timer_active) add_timer(&sk->timer); @@ -1677,7 +1503,6 @@ void tcp_close(struct sock *sk, unsigned long timeout) sk->prot->unhash(sk); } - /* * Wait for an incoming connection, avoid race * conditions. This must be called with the socket locked. @@ -1703,7 +1528,6 @@ static struct open_request * wait_for_connect(struct sock * sk) return req; } - /* * This will accept the next outstanding connection. * @@ -1751,7 +1575,6 @@ no_listen: goto out; } - /* * Socket option code for TCP. */ @@ -1772,11 +1595,9 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char *optval, if (get_user(val, (int *)optval)) return -EFAULT; - switch(optname) - { + switch(optname) { case TCP_MAXSEG: -/* - * values greater than interface MTU won't take effect. however at +/* values greater than interface MTU won't take effect. however at * the point when this call is done we typically don't yet know * which interface is going to be used */ @@ -1789,7 +1610,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char *optval, return 0; default: return(-ENOPROTOOPT); - } + }; } int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, @@ -1800,18 +1621,15 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, int len; if(level != SOL_TCP) - { return tp->af_specific->getsockopt(sk, level, optname, optval, optlen); - } if(get_user(len,optlen)) return -EFAULT; - len=min(len,sizeof(int)); + len = min(len,sizeof(int)); - switch(optname) - { + switch(optname) { case TCP_MAXSEG: val=sk->user_mss; break; @@ -1820,7 +1638,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, break; default: return(-ENOPROTOOPT); - } + }; if(put_user(len, optlen)) return -EFAULT; @@ -1832,13 +1650,9 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, void tcp_set_keepalive(struct sock *sk, int val) { if (!sk->keepopen && val) - { tcp_inc_slow_timer(TCP_SLT_KEEPALIVE); - } else if (sk->keepopen && !val) - { tcp_dec_slow_timer(TCP_SLT_KEEPALIVE); - } } void tcp_init(void) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9b5843268..ab2b1ef82 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.43 1997/04/16 09:18:47 davem Exp $ + * Version: $Id: tcp_input.c,v 1.50 1997/04/22 02:53:12 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -57,6 +57,12 @@ static void tcp_cong_avoid_vegas(struct sock *sk, u32 seq, u32 ack, u32 seq_rtt); int sysctl_tcp_cong_avoidance = 0; +int sysctl_tcp_hoe_retransmits = 0; +int sysctl_tcp_sack = 0; +int sysctl_tcp_tsack = 0; +int sysctl_tcp_timestamps = 0; +int sysctl_tcp_window_scaling = 0; + static tcp_sys_cong_ctl_t tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj; @@ -72,9 +78,7 @@ static void tcp_delack_estimator(struct tcp_opt *tp) { int m; - /* - * Delayed ACK time estimator. - */ + /* Delayed ACK time estimator. */ m = jiffies - tp->lrcvtime; @@ -83,12 +87,10 @@ static void tcp_delack_estimator(struct tcp_opt *tp) if (m < 0) return; - /* - * if the mesured value is bigger than + /* if the mesured value is bigger than * twice the round trip time ignore it. */ - if ((m << 2) <= tp->srtt) - { + if ((m << 2) <= tp->srtt) { m -= (tp->iat >> 3); tp->iat += m; @@ -102,18 +104,21 @@ static void tcp_delack_estimator(struct tcp_opt *tp) if (tp->ato < HZ/50) tp->ato = HZ/50; - } - else + } else tp->ato = 0; } -/* - * Called on frames that were known _not_ to have been - * retransmitted [see Karn/Partridge Proceedings SIGCOMM 87]. - * The algorithm is from the SIGCOMM 88 piece by Van Jacobson. +/* Called to compute a smoothed rtt estimate. The data fed to this + * routine either comes from timestamps, or from segments that were + * known _not_ to have been retransmitted [see Karn/Partridge + * Proceedings SIGCOMM 87]. The algorithm is from the SIGCOMM 88 + * piece by Van Jacobson. + * NOTE: the next three routines used to be one big routine. + * To save cycles in the RFC 1323 implementation it was better to break + * it up into three procedures. -- erics */ -extern __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) +static __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) { long m; /* @@ -122,8 +127,7 @@ extern __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) * are scaled versions of rtt and mean deviation. * This is designed to be as fast as possible * m stands for "measurement". - */ - /* + * * On a 1990 paper the rto value is changed to: * RTO = rtt + 4 * mdev */ @@ -140,44 +144,73 @@ extern __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) m -= (tp->mdev >> 2); /* similar update on mdev */ tp->mdev += m; /* mdev = 3/4 mdev + 1/4 new */ } else { - /* no previous measure. */ + /* no previous measure. */ tp->srtt = m<<3; /* take the measured time to be rtt */ tp->mdev = m<<2; /* make sure rto = 3*rtt */ } +} +/* Calculate rto without backoff. This is the second half of Van Jacobsons + * routine refered to above. + */ - /* - * Now update timeout. Note that this removes any backoff. - */ - +static __inline__ void tcp_set_rto(struct tcp_opt *tp) +{ tp->rto = (tp->srtt >> 3) + tp->mdev; tp->rto += (tp->rto >> 2) + (tp->rto >> (tp->snd_cwnd-1)); +} + +/* Keep the rto between HZ/5 and 120*HZ. 120*HZ is the upper bound + * on packet lifetime in the internet. We need the HZ/5 lower + * bound to behave correctly against BSD stacks with a fixed + * delayed ack. + * FIXME: It's not entirely clear this lower bound is the best + * way to avoid the problem. Is it possible to drop the lower + * bound and still avoid trouble with BSD stacks? Perhaps + * some modification to the RTO calculation that takes delayed + * ack bais into account? This needs serious thought. -- erics + */ +static __inline__ void tcp_bound_rto(struct tcp_opt *tp) +{ if (tp->rto > 120*HZ) tp->rto = 120*HZ; - - /* Was 1*HZ - keep .2 as minimum cos of the BSD delayed acks - * FIXME: It's not entirely clear this lower bound is the best - * way to avoid the problem. Is it possible to drop the lower - * bound and still avoid trouble with BSD stacks? Perhaps - * some modification to the RTO calculation that takes delayed - * ack bais into account? This needs serious thought. -- erics - */ if (tp->rto < HZ/5) tp->rto = HZ/5; +} + +/* WARNING: this must not be called if tp->saw_timestamp was false. */ + +extern __inline__ void tcp_replace_ts_recent(struct tcp_opt *tp, __u32 end_seq) +{ + /* From draft-ietf-tcplw-high-performance: the correct + * test is last_ack_sent <= end_seq. + * (RFC1323 stated last_ack_sent < end_seq.) + */ + if (!before(end_seq,tp->last_ack_sent)) { + tp->ts_recent = tp->rcv_tsval; + /* FIXME: need a corse timestamp. Days uptime + * would be good. + */ + tp->ts_recent_stamp = jiffies; + } +} - tp->backoff = 0; +extern __inline__ int tcp_paws_discard(struct tcp_opt *tp) +{ + /* FIXME: must check that ts_recent is not + * more than 24 days old here. Yuck. + */ + return (tp->rcv_tsval-tp->ts_recent < 0); } + static int __tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) { - u32 end_window; - - end_window = tp->rcv_wup + tp->rcv_wnd; + u32 end_window = tp->rcv_wup + tp->rcv_wnd; - if (tp->rcv_wnd) - { + if (tp->rcv_wnd) { if (!before(seq, tp->rcv_nxt) && before(seq, end_window)) return 1; @@ -196,9 +229,8 @@ static int __tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) extern __inline__ int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) { if (seq == tp->rcv_nxt) - { return (tp->rcv_wnd || (end_seq == seq)); - } + return __tcp_sequence(tp, seq, end_seq); } @@ -210,9 +242,8 @@ extern __inline__ int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) static int tcp_reset(struct sock *sk, struct sk_buff *skb) { sk->zapped = 1; - /* - * We want the right error as BSD sees it (and indeed as we do). - */ + + /* We want the right error as BSD sees it (and indeed as we do). */ switch (sk->state) { case TCP_TIME_WAIT: break; @@ -224,7 +255,7 @@ static int tcp_reset(struct sock *sk, struct sk_buff *skb) break; default: sk->err = ECONNRESET; - } + }; #ifdef CONFIG_TCP_RFC1337 /* * Time wait assassination protection [RFC1337] @@ -234,8 +265,7 @@ static int tcp_reset(struct sock *sk, struct sk_buff *skb) * Ian Heavens has since shown this is an inadequate fix for the protocol * bug in question. */ - if(sk->state!=TCP_TIME_WAIT) - { + if(sk->state!=TCP_TIME_WAIT) { tcp_set_state(sk,TCP_CLOSE); sk->shutdown = SHUTDOWN_MASK; } @@ -249,34 +279,30 @@ static int tcp_reset(struct sock *sk, struct sk_buff *skb) return(0); } - /* - * Look for tcp options. Parses everything but only knows about MSS. - * This routine is always called with the packet containing the SYN. - * However it may also be called with the ack to the SYN. So you - * can't assume this is always the SYN. It's always called after - * we have set up sk->mtu to our own MTU. - * - * We need at minimum to add PAWS support here. Possibly large windows - * as Linux gets deployed on 100Mb/sec networks. + * Look for tcp options. Normally only called on SYN and SYNACK packets. + * But, this can also be called on packets in the established flow when + * the fast version below fails. + * FIXME: surely this can be more efficient. -- erics */ -int tcp_parse_options(struct tcphdr *th) +void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp) { unsigned char *ptr; int length=(th->doff*4)-sizeof(struct tcphdr); - int mss = 0; ptr = (unsigned char *)(th + 1); + tp->sacks = 0; + tp->saw_tstamp = 0; - while(length>0) - { + while(length>0) { int opcode=*ptr++; int opsize=*ptr++; - switch(opcode) - { + if (length - opsize < 0) /* Don't parse partial options */ + break; + switch(opcode) { case TCPOPT_EOL: - return 0; + return; case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ length--; ptr--; /* the opsize=*ptr++ above was a mistake */ @@ -284,25 +310,86 @@ int tcp_parse_options(struct tcphdr *th) default: if(opsize<=2) /* Avoid silly options looping forever */ - return 0; - switch(opcode) - { + return; + switch(opcode) { case TCPOPT_MSS: - if(opsize==TCPOLEN_MSS && th->syn) - { - mss = ntohs(*(unsigned short *)ptr); - } + if(opsize==TCPOLEN_MSS && th->syn) { + tp->in_mss = ntohs(*(__u16 *)ptr); + if (tp->in_mss == 0) + tp->in_mss = 536; + } break; - /* Add other options here as people feel the urge to implement stuff like large windows */ + case TCPOPT_WINDOW: + if(opsize==TCPOLEN_WINDOW && th->syn) + if (sysctl_tcp_window_scaling) + tp->snd_wscale = *(__u8 *)ptr; + break; + case TCPOPT_SACK_PERM: + if(opsize==TCPOLEN_SACK_PERM && th->syn) + if (sysctl_tcp_sack) + tp->sack_ok = 1; + case TCPOPT_TIMESTAMP: + if(opsize==TCPOLEN_TIMESTAMP) { + /* Cheaper to set again then to + * test syn. Optimize this? + */ + if (sysctl_tcp_timestamps) + tp->tstamp_ok = 1; + tp->saw_tstamp = 1; + tp->rcv_tsval = ntohl(*(__u32 *)ptr); + tp->rcv_tsecr = ntohl(*(__u32 *)(ptr+4)); + } + break; + case TCPOPT_SACK: + tp->sacks = (opsize-2)>>3; + if (tp->sacks<<3 == opsize-2) { + int i; + for (i = 0; i < tp->sacks; i++) { + tp->left_sack[i] = ntohl(((__u32 *)ptr)[2*i]); + tp->right_sack[i] = ntohl(((__u32 *)ptr)[2*i+1]); + } + } else + tp->sacks = 0; } ptr+=opsize-2; length-=opsize; - } + }; } +} - return mss; +/* Fast parse options. This hopes to only see timestamps. + * If it is wrong it falls back on tcp_parse_option(). + * This should probably get extended for timestamps + SACK as well. + * Assembly code anyone? -- erics + */ +static __inline__ int tcp_fast_parse_options(struct tcphdr *th, struct tcp_opt *tp) +{ + if (tp->tcp_header_len == sizeof(struct tcphdr)) + return 0; + if (th->doff == sizeof(struct tcphdr)>>2) { + tp->saw_tstamp = 0; + tp->sacks = 0; + return 0; + } else if (th->doff == (sizeof(struct tcphdr)>>2)+3) { + __u32 *ptr = (__u32 *)(th + 1); + if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) { + tp->saw_tstamp = 1; + tp->sacks = 0; + tp->rcv_tsval = ntohl(*++ptr); + tp->rcv_tsecr = ntohl(*++ptr); + return 1; + } + } + tcp_parse_options(th,tp); + return 1; } +#if 0 + +/* + * This is the old fast retransmit code. It will go away eventually. -- erics + */ /* * See draft-stevens-tcpca-spec-01 for documentation. @@ -332,62 +419,170 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup) * The packet acked data after high_seq; */ - if (ack == tp->snd_una && sk->packets_out && (not_dup == 0)) - { - /* - * 1. When the third duplicate ack is received, set ssthresh - * to one half the current congestion window, but no less - * than two segments. Retransmit the missing segment. + if (ack == tp->snd_una && tp->packets_out && (not_dup == 0)) { + /* 1. When the third duplicate ack is received, set ssthresh + * to one half the current congestion window, but no less + * than two segments. Retransmit the missing segment. */ + if (tp->high_seq == 0 || after(ack, tp->high_seq)) { + tp->dup_acks++; - if (tp->high_seq == 0 || after(ack, tp->high_seq)) - { - sk->dup_acks++; - - if (sk->dup_acks == 3) - { - sk->ssthresh = max(tp->snd_cwnd >> 1, 2); - tp->snd_cwnd = sk->ssthresh + 3; + if (tp->dup_acks == 3) { + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd = tp->snd_ssthresh + 3; tcp_do_retransmit(sk, 0); - /* careful not to timeout just after fast + + /* Careful not to timeout just after fast * retransmit! */ - tcp_reset_xmit_timer(sk, TIME_RETRANS, - tp->rto); + tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); } } - /* - * 2. Each time another duplicate ACK arrives, increment - * cwnd by the segment size. [...] Transmit a packet... + /* 2. Each time another duplicate ACK arrives, increment + * cwnd by the segment size. [...] Transmit a packet... * - * Packet transmission will be done on normal flow processing - * since we're not in "retransmit mode" + * Packet transmission will be done on normal flow processing + * since we're not in "retransmit mode". */ - - if (sk->dup_acks >= 3) - { - sk->dup_acks++; + if (tp->dup_acks >= 3) { + tp->dup_acks++; tp->snd_cwnd++; } - } - else - { - /* - * 3. When the next ACK arrives that acknowledges new data, - * set cwnd to ssthresh + } else { + /* 3. When the next ACK arrives that acknowledges new data, + * set cwnd to ssthresh. */ - - if (sk->dup_acks >= 3) - { + if (tp->dup_acks >= 3) { tp->retrans_head = NULL; - tp->snd_cwnd = max(sk->ssthresh, 1); - atomic_set(&sk->retransmits, 0); + tp->snd_cwnd = max(tp->snd_ssthresh, 1); + tp->retransmits = 0; } - sk->dup_acks = 0; + tp->dup_acks = 0; + + /* FIXME: This is wrong if the new ack that arrives + * is below the value for high_seq. + */ tp->high_seq = 0; } } +#endif + +#define FLAG_DATA 0x01 +#define FLAG_WIN_UPDATE 0x02 +#define FLAG_DATA_ACKED 0x04 + +static __inline__ void clear_fast_retransmit(struct sock *sk) { + struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + if (tp->dup_acks > 3) { + tp->retrans_head = NULL; + tp->snd_cwnd = max(tp->snd_ssthresh, 1); + } + tp->dup_acks = 0; +} + +/* + * NOTE: This code assumes that tp->dup_acks gets cleared when a + * retransmit timer fires. + */ + +static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup) +{ + struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + + /* + * Note: If not_dup is set this implies we got a + * data carrying packet or a window update. + * This carries no new information about possible + * lost packets, so we have to ignore it for the purposes + * of counting duplicate acks. Ideally this does not imply we + * should stop our fast retransmit phase, more acks may come + * later without data to help us. Unfortunately this would make + * the code below much more complex. For now if I see such + * a packet I clear the fast retransmit phase. + */ + + if (ack == tp->snd_una && tp->packets_out && (not_dup == 0)) { + /* This is the standard reno style fast retransmit branch. */ + + /* 1. When the third duplicate ack is received, set ssthresh + * to one half the current congestion window, but no less + * than two segments. Retransmit the missing segment. + */ + if (tp->high_seq == 0 || after(ack, tp->high_seq)) { + tp->dup_acks++; + if (tp->dup_acks == 3) { + tp->dup_acks++; + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd = tp->snd_ssthresh + 3; + tp->high_seq = tp->snd_nxt; + tcp_do_retransmit(sk, 0); + tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + } + } + + /* 2. Each time another duplicate ACK arrives, increment + * cwnd by the segment size. [...] Transmit a packet... + * + * Packet transmission will be done on normal flow processing + * since we're not in "retransmit mode" + */ + if (tp->dup_acks > 3) + tp->snd_cwnd++; + } else if (tp->high_seq != 0) { + /* In this branch we deal with clearing the Floyd style + * block on duplicate fast retransmits, and if requested + * we do Hoe style secondary fast retransmits. + */ + if (!before(ack,tp->high_seq) || (not_dup&FLAG_DATA) != 0) { + /* Once we have acked all the packets up to high_seq + * we are done this fast retransmit phase. + * Alternatively data arrived. In this case we + * Have to abort the fast retransmit attempt. + * Note that we do want to accept a window + * update since this is expected with Hoe's algorithm. + */ + clear_fast_retransmit(sk); + + /* After we have cleared up to high_seq we can + * clear the Floyd style block. + */ + if (after(ack,tp->high_seq)) + tp->high_seq = 0; + } else if (tp->dup_acks >= 3) { + if (sysctl_tcp_hoe_retransmits) { + /* Hoe Style. We didn't ack the whole + * window. Take this as a cue that + * another packet was lost and retransmit it. + * Don't muck with the congestion window here. + * Note that we have to be careful not to + * act if this was a window update and it + * didn't ack new data, since this does + * not indicate a packet left the system. + * We can test this by just checking + * if ack changed from snd_una, since + * the only way to get here without changing + * advancing from snd_una is if this was a + * window update. + */ + if (ack != tp->snd_una && before(ack,tp->high_seq)) { + tcp_do_retransmit(sk, 0); + tcp_reset_xmit_timer(sk, TIME_RETRANS, + tp->rto); + } + } else { + /* Reno style. We didn't ack the whole + * window, now we have to drop out of + * fast retransmit and wait for a timeout. + */ + clear_fast_retransmit(sk); + } + } + } else { + /* Clear any aborted fast retransmit starts. */ + tp->dup_acks = 0; + } +} /* * TCP slow start and congestion avoidance in two flavors: @@ -401,24 +596,20 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup) static void tcp_cong_avoid_vegas(struct sock *sk, u32 seq, u32 ack, u32 seq_rtt) { - struct tcp_opt * tp; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); unsigned int actual, expected; unsigned int inv_rtt, inv_basertt, inv_basebd; u32 snt_bytes; - /* - * From: + /* From: * TCP Vegas: New Techniques for Congestion * Detection and Avoidance. * - * * Warning: This code is a scratch implementation taken * from the paper only. The code they distribute seams * to have improved several things over the initial spec. */ - tp = &(sk->tp_pinfo.af_tcp); - if (!seq_rtt) seq_rtt = 1; @@ -427,11 +618,8 @@ static void tcp_cong_avoid_vegas(struct sock *sk, u32 seq, u32 ack, else tp->basertt = seq_rtt; - /* - * - * actual = throughput for this segment. + /* actual = throughput for this segment. * expected = number_of_bytes in transit / BaseRTT - * */ snt_bytes = ack - seq; @@ -443,55 +631,36 @@ static void tcp_cong_avoid_vegas(struct sock *sk, u32 seq, u32 ack, expected = (tp->snd_nxt - tp->snd_una) * inv_basertt; + /* XXX sk->mss should move into tcp_opt as well -DaveM */ inv_basebd = sk->mss * inv_basertt; - /* - * Slow Start - */ - - if (tp->snd_cwnd < sk->ssthresh && + /* Slow Start */ + if (tp->snd_cwnd < tp->snd_ssthresh && (seq == tp->snd_nxt || - (expected - actual <= TCP_VEGAS_GAMMA * inv_basebd))) - { - /* - * "Vegas allows exponential growth only every other - * RTT" - */ - - if (sk->cong_count++) - { + (expected - actual <= TCP_VEGAS_GAMMA * inv_basebd))) { + /* "Vegas allows exponential growth only every other RTT" */ + if (tp->snd_cwnd_cnt++) { tp->snd_cwnd++; - sk->cong_count = 0; + tp->snd_cwnd_cnt = 0; } - } - else - { - /* - * Congestion Avoidance - */ - - if (expected - actual <= TCP_VEGAS_ALPHA * inv_basebd) - { + } else { + /* Congestion Avoidance */ + if (expected - actual <= TCP_VEGAS_ALPHA * inv_basebd) { /* Increase Linearly */ - - if (sk->cong_count++ >= tp->snd_cwnd) - { + if (tp->snd_cwnd_cnt++ >= tp->snd_cwnd) { tp->snd_cwnd++; - sk->cong_count = 0; + tp->snd_cwnd_cnt = 0; } } - if (expected - actual >= TCP_VEGAS_BETA * inv_basebd) - { + if (expected - actual >= TCP_VEGAS_BETA * inv_basebd) { /* Decrease Linearly */ - - if (sk->cong_count++ >= tp->snd_cwnd) - { + if (tp->snd_cwnd_cnt++ >= tp->snd_cwnd) { tp->snd_cwnd--; - sk->cong_count = 0; + tp->snd_cwnd_cnt = 0; } - /* Never less than 2 segments */ + /* Never less than 2 segments. */ if (tp->snd_cwnd < 2) tp->snd_cwnd = 2; } @@ -500,17 +669,16 @@ static void tcp_cong_avoid_vegas(struct sock *sk, u32 seq, u32 ack, static void tcp_cong_avoid_vanj(struct sock *sk, u32 seq, u32 ack, u32 seq_rtt) { - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * This is Jacobson's slow start and congestion avoidance. + /* This is Jacobson's slow start and congestion avoidance. * SIGCOMM '88, p. 328. Because we keep cong_window in * integral mss's, we can't do cwnd += 1 / cwnd. * Instead, maintain a counter and increment it once every * cwnd times. * FIXME: Check to be sure the mathematics works out right * on this trick when we have to reduce the congestion window. - * The cong_count has to be reset properly when reduction events + * The snd_cwnd_cnt has to be reset properly when reduction events * happen. * FIXME: What happens when the congestion window gets larger * than the maximum receiver window by some large factor @@ -520,38 +688,22 @@ static void tcp_cong_avoid_vanj(struct sock *sk, u32 seq, u32 ack, u32 seq_rtt) * be reduced to is not clear, since 1/2 the old window may * still be larger than the maximum sending rate we ever achieved. */ - - if (tp->snd_cwnd <= sk->ssthresh) - { - /* - * In "safe" area, increase - */ - + if (tp->snd_cwnd <= tp->snd_ssthresh) { + /* In "safe" area, increase. */ tp->snd_cwnd++; - } - else - { - /* - * In dangerous area, increase slowly. - * In theory this is - * tp->snd_cwnd += 1 / tp->snd_cwnd + } else { + /* In dangerous area, increase slowly. In theory this is + * tp->snd_cwnd += 1 / tp->snd_cwnd */ - - if (sk->cong_count >= tp->snd_cwnd) { - + if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { tp->snd_cwnd++; - sk->cong_count = 0; - } - else - sk->cong_count++; + tp->snd_cwnd_cnt = 0; + } else + tp->snd_cwnd_cnt++; } } -#define FLAG_DATA 0x01 -#define FLAG_WIN_UPDATE 0x02 -#define FLAG_DATA_ACKED 0x04 - static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq, __u32 *seq_rtt) { @@ -560,25 +712,18 @@ static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq, unsigned long now = jiffies; int acked = 0; - while((skb=skb_peek(&sk->write_queue)) && (skb != tp->send_head)) - { - + while((skb=skb_peek(&sk->write_queue)) && (skb != tp->send_head)) { #ifdef TCP_DEBUG /* Check for a bug. */ - if (skb->next != (struct sk_buff*) &sk->write_queue && after(skb->end_seq, skb->next->seq)) - { printk(KERN_DEBUG "INET: tcp_input.c: *** " "bug send_list out of order.\n"); - } #endif - /* - * If our packet is before the ack sequence we can - * discard it as it's confirmed to have arrived the - * other end. + /* If our packet is before the ack sequence we can + * discard it as it's confirmed to have arrived the + * other end. */ - if (after(skb->end_seq, ack)) break; @@ -591,7 +736,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq, * do packet "repackaging" for stacks that don't * like overlapping packets. */ - sk->packets_out--; + tp->packets_out--; *seq = skb->seq; *seq_rtt = now - skb->when; @@ -601,13 +746,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq, kfree_skb(skb, FREE_WRITE); } - if (acked) - { + if (acked) { tp->retrans_head = NULL; if (!sk->dead) sk->write_space(sk); } - return acked; } @@ -615,27 +758,18 @@ static void tcp_ack_probe(struct sock *sk, __u32 ack) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * Our probe was answered - */ + /* Our probe was answered. */ tp->probes_out = 0; - /* - * Was it a usable window open ? - */ + /* Was it a usable window open? */ /* should always be non-null */ if (tp->send_head != NULL && - !before (ack + tp->snd_wnd, tp->send_head->end_seq)) - { + !before (ack + tp->snd_wnd, tp->send_head->end_seq)) { tp->backoff = 0; tp->pending = 0; - tcp_clear_xmit_timer(sk, TIME_PROBE0); - - } - else - { + } else { tcp_reset_xmit_timer(sk, TIME_PROBE0, min(tp->rto << tp->backoff, 120*HZ)); } @@ -648,138 +782,126 @@ static void tcp_ack_probe(struct sock *sk, __u32 ack) static int tcp_ack(struct sock *sk, struct tcphdr *th, u32 ack_seq, u32 ack, int len) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int flag = 0; u32 seq = 0; u32 seq_rtt = 0; struct sk_buff *skb; - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - if(sk->zapped) return(1); /* Dead, can't ack any more so why bother */ if (tp->pending == TIME_KEEPOPEN) - { tp->probes_out = 0; - } tp->rcv_tstamp = jiffies; - /* - * If the ack is newer than sent or older than previous acks - * then we can probably ignore it. + /* If the ack is newer than sent or older than previous acks + * then we can probably ignore it. */ - if (after(ack, tp->snd_nxt) || before(ack, tp->snd_una)) goto uninteresting_ack; - /* - * If there is data set flag 1 - */ - - if (len != th->doff*4) - { + /* If there is data set flag 1 */ + if (len != th->doff*4) { flag |= FLAG_DATA; tcp_delack_estimator(tp); } - /* - * Update our send window - */ + /* Update our send window. */ - /* - * This is the window update code as per RFC 793 - * snd_wl{1,2} are used to prevent unordered - * segments from shrinking the window + /* This is the window update code as per RFC 793 + * snd_wl{1,2} are used to prevent unordered + * segments from shrinking the window */ - if (before(tp->snd_wl1, ack_seq) || - (tp->snd_wl1 == ack_seq && !after(tp->snd_wl2, ack))) - { - unsigned long nwin; + (tp->snd_wl1 == ack_seq && !after(tp->snd_wl2, ack))) { + unsigned long nwin = ntohs(th->window); - nwin = ntohs(th->window); - if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd)) - { + if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd)) { flag |= FLAG_WIN_UPDATE; tp->snd_wnd = nwin; tp->snd_wl1 = ack_seq; tp->snd_wl2 = ack; - if (nwin > sk->max_window) - sk->max_window = nwin; + if (nwin > tp->max_window) + tp->max_window = nwin; } } - /* - * We passed data and got it acked, remove any soft error - * log. Something worked... + /* We passed data and got it acked, remove any soft error + * log. Something worked... */ - sk->err_soft = 0; - /* - * If this ack opens up a zero window, clear backoff. It was - * being used to time the probes, and is probably far higher than - * it needs to be for normal retransmission. + /* If this ack opens up a zero window, clear backoff. It was + * being used to time the probes, and is probably far higher than + * it needs to be for normal retransmission. */ - if (tp->pending == TIME_PROBE0) - { tcp_ack_probe(sk, ack); - } - - /* - * See if we can take anything off of the retransmit queue. - */ + /* See if we can take anything off of the retransmit queue. */ if (tcp_clean_rtx_queue(sk, ack, &seq, &seq_rtt)) flag |= FLAG_DATA_ACKED; - - /* - * if we where retransmiting don't count rtt estimate - */ - - if (atomic_read(&sk->retransmits)) - { - if (sk->packets_out == 0) - atomic_set(&sk->retransmits, 0); - } - else - { - /* - * Note that we only reset backoff and rto in the - * rtt recomputation code. And that doesn't happen - * if there were retransmissions in effect. So the - * first new packet after the retransmissions is - * sent with the backoff still in effect. Not until - * we get an ack from a non-retransmitted packet do - * we reset the backoff and rto. This allows us to deal - * with a situation where the network delay has increased - * suddenly. I.e. Karn's algorithm. (SIGCOMM '87, p5.) + /* If we have a timestamp, we always do rtt estimates. */ + if (tp->saw_tstamp) { + /* Read draft-ietf-tcplw-high-performance before mucking + * with this code. (Superceeds RFC1323) */ - - if (flag & FLAG_DATA_ACKED) - { - tcp_rtt_estimator(tp, seq_rtt); - - (*tcp_sys_cong_ctl_f)(sk, seq, ack, seq_rtt); + seq_rtt = (jiffies-tp->rcv_tsecr); + tcp_rtt_estimator(tp, seq_rtt); + if (tp->retransmits) { + if (tp->packets_out == 0) { + tp->retransmits = 0; + tp->backoff = 0; + tcp_set_rto(tp); + } else { + /* Still retransmitting, use backoff */ + tcp_set_rto(tp); + tp->rto = tp->rto << tp->backoff; + } + } else { + tcp_set_rto(tp); + if (flag && FLAG_DATA_ACKED) + (*tcp_sys_cong_ctl_f)(sk, seq, ack, seq_rtt); + } + /* NOTE: safe here so long as cong_ctl doesn't use rto */ + tcp_bound_rto(tp); + } else { + /* If we were retransmiting don't count rtt estimate. */ + if (tp->retransmits) { + if (tp->packets_out == 0) + tp->retransmits = 0; + } else { + /* We don't have a timestamp. Can only use + * packets that are not retransmitted to determine + * rtt estimates. Also, we must not reset the + * backoff for rto until we get a non-retransmitted + * packet. This allows us to deal with a situation + * where the network delay has increased suddenly. + * I.e. Karn's algorithm. (SIGCOMM '87, p5.) + */ + if (flag & FLAG_DATA_ACKED) { + tp->backoff = 0; + tcp_rtt_estimator(tp, seq_rtt); + tcp_set_rto(tp); + tcp_bound_rto(tp); + (*tcp_sys_cong_ctl_f)(sk, seq, ack, seq_rtt); + } } } - if (sk->packets_out) - { - if (flag & FLAG_DATA_ACKED) - { + if (tp->packets_out) { + if (flag & FLAG_DATA_ACKED) { long when; skb = skb_peek(&sk->write_queue); when = tp->rto - (jiffies - skb->when); - /* - * FIXME: This assumes that when we are retransmitting + /* FIXME: This assumes that when we are retransmitting * we should only ever respond with one packet. * This means congestion windows should not grow * during recovery. In 2.0.X we allow the congestion @@ -791,36 +913,23 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, * we have to fix the call to congestion window * updates so that it works during retransmission. */ - - if (atomic_read(&sk->retransmits)) - { + if (tp->retransmits) { tp->retrans_head = NULL; - /* - * This is tricky. We are retransmiting a + + /* This is tricky. We are retransmiting a * segment of a window when congestion occured. */ tcp_do_retransmit(sk, 0); - tcp_reset_xmit_timer(sk, TIME_RETRANS, - tp->rto); - } - else + tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + } else tcp_reset_xmit_timer(sk, TIME_RETRANS, when); } - } - else + } else tcp_clear_xmit_timer(sk, TIME_RETRANS); - - /* FIXME: danger, if we just did a timeout and got the third - * ack on this packet, then this is going to send it again! - * [No. Floyd retransmit war check keeps this from happening. -- erics] - */ tcp_fast_retrans(sk, ack, (flag & (FLAG_DATA|FLAG_WIN_UPDATE))); - /* - * Remember the highest ack received. - */ - + /* Remember the highest ack received. */ tp->snd_una = ack; return 1; @@ -828,11 +937,9 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, uninteresting_ack: SOCK_DEBUG(sk, "Ack ignored %u %u\n", ack, tp->snd_nxt); - return 0; } - /* * Process the FIN bit. This now behaves as it is supposed to work * and the FIN takes effect when it is validly part of sequence @@ -846,53 +953,46 @@ uninteresting_ack: * close and we go into CLOSING (and later onto TIME-WAIT) * * If we are in FINWAIT-2, a received FIN moves us to TIME-WAIT. - * */ static int tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) { - sk->fin_seq = skb->end_seq; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* XXX This fin_seq thing should disappear... -DaveM */ + tp->fin_seq = skb->end_seq; tcp_send_ack(sk); - if (!sk->dead) - { + if (!sk->dead) { sk->state_change(sk); sock_wake_async(sk->socket, 1); } - switch(sk->state) - { + switch(sk->state) { case TCP_SYN_RECV: case TCP_SYN_SENT: case TCP_ESTABLISHED: - /* - * move to CLOSE_WAIT - */ - + /* Move to CLOSE_WAIT */ tcp_set_state(sk, TCP_CLOSE_WAIT); - if (th->rst) sk->shutdown = SHUTDOWN_MASK; break; case TCP_CLOSE_WAIT: case TCP_CLOSING: - /* - * received a retransmission of the FIN, do + /* Received a retransmission of the FIN, do * nothing. */ break; case TCP_TIME_WAIT: - /* - * received a retransmission of the FIN, + /* Received a retransmission of the FIN, * restart the TIME_WAIT timer. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); return(0); case TCP_FIN_WAIT1: - /* - * This case occurs when a simultaneous close + /* This case occurs when a simultaneous close * happens, we must ack the received FIN and * enter the CLOSING state. * @@ -902,47 +1002,39 @@ static int tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) * FIN lost hang). The TIME_WRITE code is already * correct for handling this timeout. */ - tcp_set_state(sk, TCP_CLOSING); break; case TCP_FIN_WAIT2: - /* - * received a FIN -- send ACK and enter TIME_WAIT - */ + /* Received a FIN -- send ACK and enter TIME_WAIT. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); - sk->shutdown|=SHUTDOWN_MASK; + sk->shutdown |= SHUTDOWN_MASK; tcp_set_state(sk,TCP_TIME_WAIT); break; case TCP_CLOSE: - /* - * already in CLOSE - */ + /* Already in CLOSE. */ break; default: + /* FIXME: Document whats happening in this case. -DaveM */ tcp_set_state(sk,TCP_LAST_ACK); /* Start the timers. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); return(0); - } + }; return(0); } - - - /* - * This one checks to see if we can put data from the - * out_of_order queue into the receive_queue - */ - -static void tcp_ofo_queue(struct sock *sk) +/* This one checks to see if we can put data from the + * out_of_order queue into the receive_queue. + */ +static void tcp_ofo_queue(struct sock *sk) { - struct sk_buff * skb; - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + /* FIXME: out_of_order_queue is a strong tcp_opt candidate... -DaveM */ while ((skb = skb_peek(&sk->out_of_order_queue))) { - if (after(skb->seq, tp->rcv_nxt)) break; @@ -950,106 +1042,59 @@ static void tcp_ofo_queue(struct sock *sk) SOCK_DEBUG(sk, "ofo packet was allready received \n"); skb_unlink(skb); kfree_skb(skb, FREE_READ); - continue; } SOCK_DEBUG(sk, "ofo requeuing : rcv_next %X seq %X - %X\n", tp->rcv_nxt, skb->seq, skb->end_seq); skb_unlink(skb); - skb_queue_tail(&sk->receive_queue, skb); - tp->rcv_nxt = skb->end_seq; } } static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) { - struct sk_buff * skb1; - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct sk_buff *skb1; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * Queue data for delivery to the user - * Packets in sequence go to the receive queue - * Out of sequence packets to out_of_order_queue + /* Queue data for delivery to the user. + * Packets in sequence go to the receive queue. + * Out of sequence packets to out_of_order_queue. */ - - if (skb->seq == tp->rcv_nxt) { - - /* - * Ok. In sequence. - */ - - + /* Ok. In sequence. */ +queue_and_out: skb_queue_tail(&sk->receive_queue, skb); - - tp->rcv_nxt = skb->end_seq; - tcp_ofo_queue(sk); - if (skb_queue_len(&sk->out_of_order_queue) == 0) tp->pred_flags = htonl((0x5010 << 16) | tp->snd_wnd); - return; } - /* - * Not in sequence - * either a retransmit or some packet got lost - */ - + /* Not in sequence, either a retransmit or some packet got lost. */ if (!after(skb->end_seq, tp->rcv_nxt)) { - - /* - * A retransmit. - * 2nd most common case. - * force an imediate ack - */ + /* A retransmit, 2nd most common case. Force an imediate ack. */ SOCK_DEBUG(sk, "retransmit received: seq %X\n", skb->seq); - sk->delayed_acks = MAX_DELAY_ACK; + tp->delayed_acks = MAX_DELAY_ACK; kfree_skb(skb, FREE_READ); - return; } - if (before(skb->seq, tp->rcv_nxt)) { - - /* - * Partial packet - * seq < rcv_next < end_seq - */ + /* Partial packet, seq < rcv_next < end_seq */ SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n", tp->rcv_nxt, skb->seq, skb->end_seq); - skb_queue_tail(&sk->receive_queue, skb); - - tp->rcv_nxt = skb->end_seq; - - tcp_ofo_queue(sk); - - if (skb_queue_len(&sk->out_of_order_queue) == 0) - tp->pred_flags = htonl((0x5010 << 16) | tp->snd_wnd); - - return; + goto queue_and_out; } - /* - * Ok. This is an out_of_order segment - */ - - /* Force an ack */ - - sk->delayed_acks = MAX_DELAY_ACK; - - /* - * disable header predition - */ + /* Ok. This is an out_of_order segment, force an ack. */ + tp->delayed_acks = MAX_DELAY_ACK; + /* Disable header predition. */ tp->pred_flags = 0; SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", @@ -1057,33 +1102,28 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) if (skb_peek(&sk->out_of_order_queue) == NULL) { skb_queue_head(&sk->out_of_order_queue,skb); - } - else + } else { for(skb1=sk->out_of_order_queue.prev; ; skb1 = skb1->prev) { - - /* allready there */ - if (skb->seq==skb1->seq && skb->len>=skb1->len) - { - skb_append(skb1,skb); + /* Already there. */ + if (skb->seq == skb1->seq && skb->len >= skb1->len) { + skb_append(skb1, skb); skb_unlink(skb1); - kfree_skb(skb1,FREE_READ); + kfree_skb(skb1, FREE_READ); break; } - if (after(skb->seq, skb1->seq)) - { + if (after(skb->seq, skb1->seq)) { skb_append(skb1,skb); break; } - /* - * See if we've hit the start. If so insert. - */ + /* See if we've hit the start. If so insert. */ if (skb1 == skb_peek(&sk->out_of_order_queue)) { skb_queue_head(&sk->out_of_order_queue,skb); break; } } + } } @@ -1096,48 +1136,33 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len) { struct tcphdr *th; - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); th = skb->h.th; - skb_pull(skb,th->doff*4); - skb_trim(skb,len-(th->doff*4)); + skb_pull(skb, th->doff*4); + skb_trim(skb, len - (th->doff*4)); if (skb->len == 0 && !th->fin) - { return(0); - } - - /* - * FIXME: don't accept data after the receved fin - */ - - /* - * The bytes in the receive read/assembly queue has increased. - * Needed for the low memory discard algorithm - */ - sk->bytes_rcv += skb->len; - - /* - * We no longer have anyone receiving data on this connection. + /* FIXME: don't accept data after the received fin. + * + * Would checking snd_seq against fin_seq be enough? + * If so, how do we handle that case exactly? -DaveM */ + /* We no longer have anyone receiving data on this connection. */ tcp_data_queue(sk, skb); - if (before(tp->rcv_nxt, sk->copied_seq)) - { + if (before(tp->rcv_nxt, sk->copied_seq)) { printk(KERN_DEBUG "*** tcp.c:tcp_data bug acked < copied\n"); tp->rcv_nxt = sk->copied_seq; } - sk->delayed_acks++; - - /* - * Now tell the user we may have some data. - */ + tp->delayed_acks++; - if (!sk->dead) - { + /* Now tell the user we may have some data. */ + if (!sk->dead) { SOCK_DEBUG(sk, "Data wakeup.\n"); sk->data_ready(sk,0); } @@ -1149,29 +1174,25 @@ static void tcp_data_snd_check(struct sock *sk) struct sk_buff *skb; struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); - if ((skb = tp->send_head)) - { + if ((skb = tp->send_head)) { if (!after(skb->end_seq, tp->snd_una + tp->snd_wnd) && - sk->packets_out < tp->snd_cwnd ) - { - /* - * Add more data to the send queue. - */ + tp->packets_out < tp->snd_cwnd ) { + /* Add more data to the send queue. */ + /* FIXME: the congestion window is checked - * again in tcp_write_xmit anyway?! + * again in tcp_write_xmit anyway?! -- erics + * + * I think it must, it bumps tp->packets_out for + * each packet it fires onto the wire. -DaveM */ - tcp_write_xmit(sk); if(!sk->dead) sk->write_space(sk); - } - else if (sk->packets_out == 0 && !tp->pending) - { - /* - * Data to queue but no room. - */ + } else if (tp->packets_out == 0 && !tp->pending) { + /* Data to queue but no room. */ + /* FIXME: Is it right to do a zero window probe into - * a congestion window limited window??? + * a congestion window limited window??? -- erics */ tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); } @@ -1180,32 +1201,25 @@ static void tcp_data_snd_check(struct sock *sk) static __inline__ void tcp_ack_snd_check(struct sock *sk) { - /* - * This also takes care of updating the window. - * This if statement needs to be simplified. + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* This also takes care of updating the window. + * This if statement needs to be simplified. * - * rules for delaying an ack: + * Rules for delaying an ack: * - delay time <= 0.5 HZ * - we don't have a window update to send * - must send at least every 2 full sized packets */ - - if (sk->delayed_acks == 0) - { - /* - * We sent a data segment already - */ + if (tp->delayed_acks == 0) { + /* We sent a data segment already. */ return; } - if (sk->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk)) - { + if (tp->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk)) tcp_send_ack(sk); - } else - { tcp_send_delayed_ack(sk, HZ/2); - } } /* @@ -1227,62 +1241,49 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th) ptr--; ptr += ntohl(th->seq); - /* ignore urgent data that we've already seen and read */ + /* Ignore urgent data that we've already seen and read. */ if (after(sk->copied_seq, ptr)) return; - /* do we already have a newer (or duplicate) urgent pointer? */ + /* Do we already have a newer (or duplicate) urgent pointer? */ if (sk->urg_data && !after(ptr, sk->urg_seq)) return; - /* tell the world about our new urgent pointer */ + /* Tell the world about our new urgent pointer. */ if (sk->proc != 0) { - if (sk->proc > 0) { + if (sk->proc > 0) kill_proc(sk->proc, SIGURG, 1); - } else { + else kill_pg(-sk->proc, SIGURG, 1); - } } - /* - * We may be adding urgent data when the last byte read was - * urgent. To do this requires some care. We cannot just ignore - * sk->copied_seq since we would read the last urgent byte again - * as data, nor can we alter copied_seq until this data arrives - * or we break the sematics of SIOCATMARK (and thus sockatmark()) + + /* We may be adding urgent data when the last byte read was + * urgent. To do this requires some care. We cannot just ignore + * sk->copied_seq since we would read the last urgent byte again + * as data, nor can we alter copied_seq until this data arrives + * or we break the sematics of SIOCATMARK (and thus sockatmark()) */ if (sk->urg_seq == sk->copied_seq) sk->copied_seq++; /* Move the copied sequence on correctly */ sk->urg_data = URG_NOTYET; sk->urg_seq = ptr; - /* disable header prediction */ + /* Disable header prediction. */ tp->pred_flags = 0; } -/* - * This is the 'fast' part of urgent handling. - */ - +/* This is the 'fast' part of urgent handling. */ static inline void tcp_urg(struct sock *sk, struct tcphdr *th, unsigned long len) { - /* - * Check if we get a new urgent pointer - normally not - */ - + /* Check if we get a new urgent pointer - normally not. */ if (th->urg) tcp_check_urg(sk,th); - /* - * Do we wait for any urgent data? - normally not - */ - + /* Do we wait for any urgent data? - normally not... */ if (sk->urg_data == URG_NOTYET) { - u32 ptr; + u32 ptr = sk->urg_seq - ntohl(th->seq) + (th->doff*4); - /* - * Is the urgent pointer pointing into this packet? - */ - ptr = sk->urg_seq - ntohl(th->seq) + th->doff*4; + /* Is the urgent pointer pointing into this packet? */ if (ptr < len) { sk->urg_data = URG_VALID | *(ptr + (unsigned char *) th); if (!sk->dead) @@ -1291,26 +1292,19 @@ static inline void tcp_urg(struct sock *sk, struct tcphdr *th, unsigned long len } } - static void prune_queue(struct sock *sk) { struct sk_buff * skb; - /* - * clean the out_of_order queue - */ - + /* Clean the out_of_order queue. */ while ((skb = skb_dequeue(&sk->out_of_order_queue))) - { kfree_skb(skb, FREE_READ); - } } - int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, struct tcphdr *th, __u16 len) { - struct tcp_opt *tp; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int queued = 0; u32 flg; @@ -1330,6 +1324,23 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, */ tp = &(sk->tp_pinfo.af_tcp); + + /* + * RFC1323: H1. Apply PAWS check first. + */ + if (tcp_fast_parse_options(th,tp)) { + if (tp->saw_tstamp) { + if (tcp_paws_discard(tp)) { + if (!th->rst) { + tcp_send_ack(sk); + kfree_skb(skb, FREE_READ); + return 0; + } + } + tcp_replace_ts_recent(tp,skb->end_seq); + } + } + flg = *(((u32 *)th) + 3); /* @@ -1340,53 +1351,39 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, * space for instance) */ - if (flg == tp->pred_flags && skb->seq == tp->rcv_nxt) - { - if (len <= sizeof(struct tcphdr)) - { - if (len == sizeof(struct tcphdr)) - { + if (flg == tp->pred_flags && skb->seq == tp->rcv_nxt) { + if (len <= th->doff*4) { + /* Bulk data transfer: sender */ + if (len == th->doff*4) { tcp_ack(sk, th, skb->seq, skb->ack_seq, len); tcp_data_snd_check(sk); } kfree_skb(skb, FREE_READ); return 0; - } - else if (skb->ack_seq == tp->snd_una) - { - /* - * Bulk data transfer: receiver - */ + } else if (skb->ack_seq == tp->snd_una) { + /* Bulk data transfer: receiver */ - skb_pull(skb,sizeof(struct tcphdr)); + skb_pull(skb,th->doff*4); skb_queue_tail(&sk->receive_queue, skb); tp->rcv_nxt = skb->end_seq; - sk->bytes_rcv += len - sizeof(struct tcphdr); - + sk->data_ready(sk, 0); tcp_delack_estimator(tp); - if (sk->delayed_acks++ == 0) - { + if (tp->delayed_acks++ == 0) tcp_send_delayed_ack(sk, HZ/2); - } else - { tcp_send_ack(sk); - } return 0; } } - if (!tcp_sequence(tp, skb->seq, skb->end_seq)) - { - if (!th->rst) - { - if (after(skb->seq, tp->rcv_nxt)) - { + if (!tcp_sequence(tp, skb->seq, skb->end_seq)) { + if (!th->rst) { + if (after(skb->seq, tp->rcv_nxt)) { SOCK_DEBUG(sk, "seq:%d end:%d wup:%d wnd:%d\n", skb->seq, skb->end_seq, tp->rcv_wup, tp->rcv_wnd); @@ -1397,68 +1394,45 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, } } - if(th->syn && skb->seq != sk->syn_seq) - { + if(th->syn && skb->seq != sk->syn_seq) { printk(KERN_DEBUG "syn in established state\n"); tcp_reset(sk, skb); kfree_skb(skb, FREE_READ); return 1; } - if(th->rst) - { + if(th->rst) { tcp_reset(sk,skb); kfree_skb(skb, FREE_READ); return 0; } if(th->ack) - { tcp_ack(sk, th, skb->seq, skb->ack_seq, len); - } - - /* - * Process urgent data - */ - + /* Process urgent data. */ tcp_urg(sk, th, len); - /* - * step 7: process the segment text - */ - - + /* step 7: process the segment text */ queued = tcp_data(skb, sk, len); - /* - * step 8: check the FIN bit - */ - + /* step 8: check the FIN bit */ if (th->fin) - { tcp_fin(skb, sk, th); - } tcp_data_snd_check(sk); tcp_ack_snd_check(sk); - /* - * If our receive queue has grown past its limits, - * try to prune away duplicates etc.. + /* If our receive queue has grown past its limits, + * try to prune away duplicates etc.. */ if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) prune_queue(sk); - /* - * And done - */ - if (!queued) kfree_skb(skb, FREE_READ); return 0; } - /* * This function implements the receiving procedure of RFC 793. @@ -1471,49 +1445,26 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int queued = 0; - int rcv_mss; - - /* - * state == CLOSED - * Hash lookup always fails, so no worries. -DaveM - */ + /* state == CLOSED, hash lookup always fails, so no worries. -DaveM */ switch (sk->state) { - - case TCP_LISTEN: - if (th->rst) goto discard; - /* - * These use the socket TOS.. + /* These use the socket TOS.. * might want to be the received TOS */ - if(th->ack) - { - /* - * send reset - */ - - return 1; - } - + return 1; /* send reset */ - if(th->syn) - { - int err; - __u32 isn; - - isn = tp->af_specific->init_sequence(sk, skb); - err = tp->af_specific->conn_request(sk, skb, opt, isn); + if(th->syn) { + __u32 isn = tp->af_specific->init_sequence(sk, skb); - if (err < 0) + if(tp->af_specific->conn_request(sk, skb, opt, isn) < 0) return 1; - /* - * Now we have several options: In theory there is + /* Now we have several options: In theory there is * nothing else in the frame. KA9Q has an option to * send data with the syn, BSD accepts data with the * syn up to the [to be] advertised window and @@ -1525,7 +1476,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, * Now that TTCP is starting to be used we ought to * queue this data. */ - return 0; } @@ -1533,47 +1483,36 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, break; case TCP_SYN_SENT: - - /* - * SYN sent means we have to look for a suitable ack and - * either reset for bad matches or go to connected. - * The SYN_SENT case is unusual and should - * not be in line code. [AC] + /* SYN sent means we have to look for a suitable ack and + * either reset for bad matches or go to connected. + * The SYN_SENT case is unusual and should + * not be in line code. [AC] */ - - if(th->ack) - { + if(th->ack) { tp->snd_wl1 = skb->seq; - /* We got an ack, but it's not a good ack */ - if(!tcp_ack(sk,th, skb->seq, skb->ack_seq, len)) - { + /* We got an ack, but it's not a good ack. */ + if(!tcp_ack(sk,th, skb->seq, skb->ack_seq, len)) { tcp_statistics.TcpAttemptFails++; return 1; } - if(th->rst) - { + if(th->rst) { tcp_reset(sk,skb); goto discard; } - if(!th->syn) - { - /* - * A valid ack from a different connection - * start. Shouldn't happen but cover it + if(!th->syn) { + /* A valid ack from a different connection + * start. Shouldn't happen but cover it. */ tcp_statistics.TcpAttemptFails++; return 1; } - /* - * Ok.. it's good. Set up sequence - * numbers and - * move to established. + /* Ok.. it's good. Set up sequence numbers and + * move to established. */ - tp->rcv_nxt = skb->seq+1; tp->rcv_wnd = 0; tp->rcv_wup = skb->seq+1; @@ -1582,39 +1521,53 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, tp->snd_wl1 = skb->seq; tp->snd_wl2 = skb->ack_seq; - sk->fin_seq = skb->seq; - tcp_send_ack(sk); + tp->fin_seq = skb->seq; tcp_set_state(sk, TCP_ESTABLISHED); - rcv_mss = tcp_parse_options(th); - - if (rcv_mss) - sk->mss = min(sk->mss, rcv_mss); + tcp_parse_options(th,tp); + /* FIXME: need to make room for SACK still */ + if (tp->tstamp_ok) { + tp->tcp_header_len = sizeof(struct tcphdr) + 12; /* FIXME: Define constant! */ + sk->dummy_th.doff += 3; /* reserve space of options */ + } else + tp->tcp_header_len = sizeof(struct tcphdr); + if (tp->saw_tstamp) { + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = jiffies; + } + + /* Can't be earlier, doff would be wrong. */ + tcp_send_ack(sk); + + if (tp->in_mss) + sk->mss = min(sk->mss, tp->in_mss); + + /* Take out space for tcp options. */ + sk->mss -= tp->tcp_header_len - sizeof(struct tcphdr); sk->dummy_th.dest = th->source; sk->copied_seq = tp->rcv_nxt; - if(!sk->dead) - { + if(!sk->dead) { sk->state_change(sk); sock_wake_async(sk->socket, 0); } /* Drop through step 6 */ goto step6; - } - else - { - if(th->syn && !th->rst) - { - /* - * the previous version of the code + } else { + if(th->syn && !th->rst) { + /* The previous version of the code * checked for "connecting to self" * here. that check is done now in - * tcp_connect + * tcp_connect. */ - tcp_set_state(sk, TCP_SYN_RECV); + tcp_parse_options(th,tp); + if (tp->saw_tstamp) { + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = jiffies; + } tp->rcv_nxt = skb->seq + 1; tp->rcv_wup = skb->seq + 1; @@ -1630,8 +1583,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, break; case TCP_TIME_WAIT: - /* - * RFC 1122: + /* RFC 1122: * "When a connection is [...] on TIME-WAIT state [...] * [a TCP] MAY accept a new SYN from the remote TCP to * reopen the connection directly, if it: @@ -1644,11 +1596,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, * (2) returns to TIME-WAIT state if the SYN turns out * to be an old duplicate". */ - - if (th->syn && !th->rst && after(skb->seq, tp->rcv_nxt)) - { + if (th->syn && !th->rst && after(skb->seq, tp->rcv_nxt)) { __u32 isn; - int err; skb_orphan(skb); sk->err = ECONNRESET; @@ -1664,50 +1613,53 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, skb_set_owner_r(skb, sk); tp = &sk->tp_pinfo.af_tcp; - - err = tp->af_specific->conn_request(sk, skb, opt, isn); - if (err < 0) + if(tp->af_specific->conn_request(sk, skb, opt, isn) < 0) return 1; - return 0; } break; - } - /* - * step 1: check sequence number + /* Parse the tcp_options present on this header. + * By this point we really only expect timestamps and SACKs. + * Note that this really has to be here and not later for PAWS + * (RFC1323) to work. */ + if (tcp_fast_parse_options(th,tp)) { + /* NOTE: assumes saw_tstamp is never set if we didn't + * negotiate the option. tcp_fast_parse_options() must + * guarantee this. + */ + if (tp->saw_tstamp) { + if (tcp_paws_discard(tp)) { + if (!th->rst) { + tcp_send_ack(sk); + goto discard; + } + } + tcp_replace_ts_recent(tp,skb->end_seq); + } + } - if (!tcp_sequence(tp, skb->seq, skb->end_seq)) - { - if (!th->rst) - { + /* step 1: check sequence number */ + if (!tcp_sequence(tp, skb->seq, skb->end_seq)) { + if (!th->rst) { tcp_send_ack(sk); goto discard; } } - - /* - * step 2: check RST bit - */ - - if(th->rst) - { + /* step 2: check RST bit */ + if(th->rst) { tcp_reset(sk,skb); goto discard; } - /* - * step 3: check security and precedence - * [ignored] - */ + /* step 3: check security and precedence [ignored] */ - /* - * step 4: + /* step 4: * * Check for a SYN, and ensure it matches the SYN we were * first sent. We have to handle the rather unusual (but valid) @@ -1723,24 +1675,18 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, * original syn. */ - if (th->syn && skb->seq!=sk->syn_seq) - { + if (th->syn && skb->seq!=sk->syn_seq) { tcp_reset(sk, skb); return 1; } - /* - * step 5: check the ACK field - */ - - if (th->ack) - { + /* step 5: check the ACK field */ + if (th->ack) { int acceptable = tcp_ack(sk,th,skb->seq, skb->ack_seq,len); switch(sk->state) { case TCP_SYN_RECV: - if (acceptable) - { + if (acceptable) { tcp_set_state(sk, TCP_ESTABLISHED); sk->dummy_th.dest=th->source; sk->copied_seq = tp->rcv_nxt; @@ -1753,15 +1699,12 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, tp->snd_wl1 = skb->seq; tp->snd_wl2 = skb->ack_seq; - } - else + } else return 1; break; case TCP_FIN_WAIT1: - - if (tp->snd_una == sk->write_seq) - { + if (tp->snd_una == sk->write_seq) { sk->shutdown |= SEND_SHUTDOWN; tcp_set_state(sk, TCP_FIN_WAIT2); if (!sk->dead) @@ -1770,17 +1713,12 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, break; case TCP_CLOSING: - if (tp->snd_una == sk->write_seq) - { tcp_time_wait(sk); - } break; case TCP_LAST_ACK: - - if (tp->snd_una == sk->write_seq) - { + if (tp->snd_una == sk->write_seq) { sk->shutdown = SHUTDOWN_MASK; tcp_set_state(sk,TCP_CLOSE); if (!sk->dead) @@ -1790,49 +1728,34 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, break; case TCP_TIME_WAIT: - /* - * keep us in TIME_WAIT until we stop getting + /* Keep us in TIME_WAIT until we stop getting * packets, reset the timeout. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); break; - } - } - else + } else goto discard; - step6: - - /* - * step 6: check the URG bit - */ - +step6: + /* step 6: check the URG bit */ tcp_urg(sk, th, len); - /* - * step 7: process the segment text - */ - + /* step 7: process the segment text */ switch (sk->state) { case TCP_CLOSE_WAIT: case TCP_CLOSING: - if (!before(skb->seq, sk->fin_seq)) + if (!before(skb->seq, tp->fin_seq)) break; case TCP_FIN_WAIT1: case TCP_FIN_WAIT2: - - /* - * RFC 793 says to queue data in this states, - * RFC 1122 says we MUST send a reset. - * BSD 4.4 also does reset. + /* RFC 793 says to queue data in these states, + * RFC 1122 says we MUST send a reset. + * BSD 4.4 also does reset. */ - - if ((sk->shutdown & RCV_SHUTDOWN) && sk->dead) - { - if (after(skb->end_seq - th->fin, tp->rcv_nxt)) - { + if ((sk->shutdown & RCV_SHUTDOWN) && sk->dead) { + if (after(skb->end_seq - th->fin, tp->rcv_nxt)) { tcp_reset(sk, skb); return 1; } @@ -1843,22 +1766,16 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, break; } - /* - * step 8: check the FIN bit - */ - + /* step 8: check the FIN bit */ if (th->fin) - { tcp_fin(skb, sk, th); - } tcp_data_snd_check(sk); tcp_ack_snd_check(sk); if (queued) return 0; - discard: - +discard: kfree_skb(skb, FREE_READ); return 0; } @@ -1871,19 +1788,18 @@ int tcp_sysctl_congavoid(ctl_table *ctl, int write, struct file * filp, retv = proc_dointvec(ctl, write, filp, buffer, lenp); - if (write) - { + if (write) { switch (sysctl_tcp_cong_avoidance) { - case 0: - tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj; - break; - case 1: - tcp_sys_cong_ctl_f = &tcp_cong_avoid_vegas; - break; - default: - retv = -EINVAL; - sysctl_tcp_cong_avoidance = val; - } + case 0: + tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj; + break; + case 1: + tcp_sys_cong_ctl_f = &tcp_cong_avoid_vegas; + break; + default: + retv = -EINVAL; + sysctl_tcp_cong_avoidance = val; + }; } return retv; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 7934dc69d..f4528f552 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.31 1997/04/16 09:18:50 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.39 1997/04/22 02:53:14 davem Exp $ * * IPv4 specific functions * @@ -27,6 +27,9 @@ * Changes: * David S. Miller : New socket lookup architecture. * This code is dedicated to John Dyson. + * David S. Miller : Change semantics of established hash, + * half is devoted to TIME_WAIT sockets + * and the rest go in the other half. */ #include @@ -41,6 +44,11 @@ #include +extern int sysctl_tcp_sack; +extern int sysctl_tcp_tsack; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; + static void tcp_v4_send_reset(struct sk_buff *skb); void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, @@ -49,12 +57,15 @@ void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, /* This is for sockets with full identity only. Sockets here will always * be without wildcards and will have the following invariant: * TCP_ESTABLISHED <= sk->state < TCP_CLOSE + * + * First half of the table is for sockets not in TIME_WAIT, second half + * is for TIME_WAIT sockets only. */ struct sock *tcp_established_hash[TCP_HTABLE_SIZE]; /* All sockets in TCP_LISTEN state will be in here. This is the only table * where wildcard'd TCP sockets can exist. Hash function here is just local - * port number. XXX Fix or we'll lose with thousands of IP aliases... + * port number. */ struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE]; @@ -66,7 +77,7 @@ struct sock *tcp_bound_hash[TCP_BHTABLE_SIZE]; static __inline__ int tcp_hashfn(__u32 laddr, __u16 lport, __u32 faddr, __u16 fport) { - return ((laddr ^ lport) ^ (faddr ^ fport)) & (TCP_HTABLE_SIZE - 1); + return ((laddr ^ lport) ^ (faddr ^ fport)) & ((TCP_HTABLE_SIZE/2) - 1); } static __inline__ int tcp_sk_hashfn(struct sock *sk) @@ -243,10 +254,14 @@ static void tcp_v4_rehash(struct sock *sk) if(state != TCP_CLOSE || !sk->dead) { struct sock **skp; - if(state == TCP_LISTEN) + if(state == TCP_LISTEN) { skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; - else - skp = &tcp_established_hash[tcp_sk_hashfn(sk)]; + } else { + int hash= tcp_sk_hashfn(sk); + if(state == TCP_TIME_WAIT) + hash += (TCP_HTABLE_SIZE/2); + skp = &tcp_established_hash[hash]; + } if((sk->next = *skp) != NULL) (*skp)->pprev = &sk->next; @@ -262,19 +277,13 @@ static void tcp_v4_rehash(struct sock *sk) * to specify the remote port nor the remote address for the * connection. So always assume those are both wildcarded * during the search since they can never be otherwise. - * - * XXX Later on, hash on both local port _and_ local address, - * XXX to handle a huge IP alias'd box. Keep in mind that - * XXX such a scheme will require us to run through the listener - * XXX hash twice, once for local addresses bound, and once for - * XXX the local address wildcarded (because the hash is different). */ -static struct sock *tcp_v4_lookup_longway(u32 daddr, unsigned short hnum) +static struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum) { - struct sock *sk = tcp_listening_hash[tcp_lhashfn(hnum)]; + struct sock *sk; struct sock *result = NULL; - for(; sk; sk = sk->next) { + for(sk = tcp_listening_hash[tcp_lhashfn(hnum)]; sk; sk = sk->next) { if(sk->num == hnum) { __u32 rcv_saddr = sk->rcv_saddr; @@ -296,19 +305,28 @@ static inline struct sock *__tcp_v4_lookup(struct tcphdr *th, { unsigned short hnum = ntohs(dport); struct sock *sk; + int hash = tcp_hashfn(daddr, hnum, saddr, sport); /* Optimize here for direct hit, only listening connections can * have wildcards anyways. It is assumed that this code only * gets called from within NET_BH. */ - sk = tcp_established_hash[tcp_hashfn(daddr, hnum, saddr, sport)]; - for(; sk; sk = sk->next) + for(sk = tcp_established_hash[hash]; sk; sk = sk->next) if(sk->daddr == saddr && /* remote address */ sk->dummy_th.dest == sport && /* remote port */ sk->num == hnum && /* local port */ sk->rcv_saddr == daddr) /* local address */ goto hit; /* You sunk my battleship! */ - sk = tcp_v4_lookup_longway(daddr, hnum); + + /* Must check for a TIME_WAIT'er before going to listener hash. */ + for(sk = tcp_established_hash[hash+(TCP_HTABLE_SIZE/2)]; sk; sk = sk->next) + if(sk->daddr == saddr && /* remote address */ + sk->dummy_th.dest == sport && /* remote port */ + sk->num == hnum && /* local port */ + sk->rcv_saddr == daddr) /* local address */ + goto hit; + + sk = tcp_v4_lookup_listener(daddr, hnum); hit: return sk; } @@ -417,13 +435,27 @@ static int tcp_unique_address(u32 saddr, u16 snum, u32 daddr, u16 dnum) sk->num == snum && /* local port */ sk->saddr == saddr) { /* local address */ retval = 0; - break; + goto out; + } + } + + /* Must check TIME_WAIT'ers too. */ + sk = tcp_established_hash[hashent + (TCP_HTABLE_SIZE/2)]; + for (; sk != NULL; sk = sk->next) { + if(sk->daddr == daddr && /* remote address */ + sk->dummy_th.dest == dnum && /* remote port */ + sk->num == snum && /* local port */ + sk->saddr == saddr) { /* local address */ + retval = 0; + goto out; } } +out: SOCKHASH_UNLOCK(); return retval; } + /* * This will initiate an outgoing connection. */ @@ -432,7 +464,6 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct sk_buff *buff; struct sk_buff *skb1; - unsigned char *ptr; int tmp; struct tcphdr *t1; struct rtable *rt; @@ -442,10 +473,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (sk->state != TCP_CLOSE) return(-EISCONN); - /* - * Don't allow a double connect. - */ - + /* Don't allow a double connect. */ if (sk->daddr) return -EINVAL; @@ -505,20 +533,14 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) sk->err = 0; buff = sock_wmalloc(sk, MAX_SYN_SIZE, 0, GFP_KERNEL); - if (buff == NULL) - { + if (buff == NULL) { release_sock(sk); return(-ENOBUFS); } - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = ip_build_header(buff, sk); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); release_sock(sk); return(-ENETUNREACH); @@ -535,11 +557,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) t1->ack = 0; t1->window = htons(512); t1->syn = 1; - t1->doff = 6; - - /* use 512 or whatever user asked for */ - sk->window_clamp=rt->u.dst.window; + /* Use 512 or whatever user asked for. */ + tp->window_clamp = rt->u.dst.window; sk->mtu = rt->u.dst.pmtu; if ((sk->ip_pmtudisc == IP_PMTUDISC_DONT || @@ -557,17 +577,13 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) sk->mss = (sk->mtu - sizeof(struct iphdr) - sizeof(struct tcphdr)); - /* - * Put in the TCP options to say MSS. - */ + tmp = tcp_syn_build_options(buff, sk->mss, sysctl_tcp_sack, + sysctl_tcp_timestamps, + sysctl_tcp_window_scaling?tp->rcv_wscale:0); + buff->csum = 0; + t1->doff = (sizeof(*t1)+ tmp)>>2; - ptr = skb_put(buff,4); - ptr[0] = TCPOPT_MSS; - ptr[1] = TCPOLEN_MSS; - ptr[2] = (sk->mss) >> 8; - ptr[3] = (sk->mss) & 0xff; - buff->csum = csum_partial(ptr, 4, 0); - tcp_v4_send_check(sk, t1, sizeof(struct tcphdr) + 4, buff); + tcp_v4_send_check(sk, t1, sizeof(struct tcphdr) + tmp, buff); tcp_set_state(sk,TCP_SYN_SENT); @@ -580,18 +596,18 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) tcp_init_xmit_timers(sk); - /* Now works the right way instead of a hacked initial setting */ - atomic_set(&sk->retransmits, 0); + /* Now works the right way instead of a hacked initial setting. */ + tp->retransmits = 0; skb_queue_tail(&sk->write_queue, buff); - sk->packets_out++; + tp->packets_out++; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); ip_queue_xmit(skb1); - /* Timer for repeating the SYN until an answer */ + /* Timer for repeating the SYN until an answer. */ tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); tcp_statistics.TcpActiveOpens++; tcp_statistics.TcpOutSegs++; @@ -604,10 +620,7 @@ static int tcp_v4_sendmsg(struct sock *sk, struct msghdr *msg, int len) { int retval = -EINVAL; - /* - * Do sanity checking for sendmsg/sendto/send - */ - + /* Do sanity checking for sendmsg/sendto/send. */ if (msg->msg_flags & ~(MSG_OOB|MSG_DONTROUTE|MSG_DONTWAIT)) goto out; if (msg->msg_name) { @@ -650,6 +663,7 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp) { struct iphdr *iph = (struct iphdr*)dp; struct tcphdr *th = (struct tcphdr*)(dp+(iph->ihl<<2)); + struct tcp_opt *tp; int type = skb->h.icmph->type; int code = skb->h.icmph->code; struct sock *sk; @@ -659,26 +673,23 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp) if (sk == NULL) return; - if (type == ICMP_SOURCE_QUENCH) - { - struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - - sk->ssthresh = max(tp->snd_cwnd >> 1, 2); - tp->snd_cwnd = sk->ssthresh + 3; + tp = &sk->tp_pinfo.af_tcp; + if (type == ICMP_SOURCE_QUENCH) { + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd = tp->snd_ssthresh; tp->high_seq = tp->snd_nxt; - return; } - if (type == ICMP_PARAMETERPROB) - { + if (type == ICMP_PARAMETERPROB) { sk->err=EPROTO; sk->error_report(sk); } + /* FIXME: What about the IP layer options size here? */ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { if (sk->ip_pmtudisc != IP_PMTUDISC_DONT) { - int new_mtu = sk->dst_cache->pmtu - sizeof(struct iphdr) - sizeof(struct tcphdr); + int new_mtu = sk->dst_cache->pmtu - sizeof(struct iphdr) - tp->tcp_header_len; if (new_mtu < sk->mss && new_mtu > 0) { sk->mss = new_mtu; } @@ -686,24 +697,18 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp) return; } - /* - * If we've already connected we will keep trying + /* If we've already connected we will keep trying * until we time out, or the user gives up. */ - - if (code <= NR_ICMP_UNREACH) - { - if(icmp_err_convert[code].fatal || sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) - { + if (code <= NR_ICMP_UNREACH) { + if(icmp_err_convert[code].fatal || sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) { sk->err = icmp_err_convert[code].errno; - if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) - { + if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) { tcp_statistics.TcpAttemptFails++; tcp_set_state(sk,TCP_CLOSE); sk->error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ } - } - else /* Only an error on timeout */ + } else /* Only an error on timeout */ sk->err_soft = icmp_err_convert[code].errno; } } @@ -714,7 +719,7 @@ void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, { th->check = 0; th->check = tcp_v4_check(th, len, sk->saddr, sk->daddr, - csum_partial((char *)th, sizeof(*th), skb->csum)); + csum_partial((char *)th, th->doff<<2, skb->csum)); } /* @@ -746,10 +751,7 @@ static void tcp_v4_send_reset(struct sk_buff *skb) skb1->h.th = th1 = (struct tcphdr *)skb_put(skb1, sizeof(struct tcphdr)); memset(th1, 0, sizeof(*th1)); - /* - * Swap the send and the receive. - */ - + /* Swap the send and the receive. */ th1->dest = th->source; th1->source = th->dest; th1->doff = sizeof(*th1)/4; @@ -768,6 +770,7 @@ static void tcp_v4_send_reset(struct sk_buff *skb) skb1->csum = csum_partial((u8 *) th1, sizeof(*th1), 0); th1->check = tcp_v4_check(th1, sizeof(*th1), skb1->nh.iph->saddr, skb1->nh.iph->daddr, skb1->csum); + /* FIXME: should this carry an options packet? */ ip_queue_xmit(skb1); tcp_statistics.TcpOutSegs++; } @@ -803,7 +806,7 @@ static void tcp_v4_send_synack(struct sock *sk, struct open_request *req) struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; struct sk_buff * skb; struct tcphdr *th; - unsigned char *ptr; + int tmp; int mss; skb = sock_wmalloc(sk, MAX_SYN_SIZE, 1, GFP_ATOMIC); @@ -821,6 +824,11 @@ static void tcp_v4_send_synack(struct sock *sk, struct open_request *req) mss = min(mss, sk->user_mss); skb->h.th = th = (struct tcphdr *) skb_put(skb, sizeof(struct tcphdr)); + /* Don't offer more than they did. + * This way we don't have to memorize who said what. + */ + req->mss = min(mss, req->mss); + /* Yuck, make this header setup more efficient... -DaveM */ memset(th, 0, sizeof(struct tcphdr)); th->syn = 1; @@ -831,20 +839,23 @@ static void tcp_v4_send_synack(struct sock *sk, struct open_request *req) skb->end_seq = skb->seq + 1; th->seq = ntohl(skb->seq); th->ack_seq = htonl(req->rcv_isn + 1); - th->doff = sizeof(*th)/4 + 1; th->window = ntohs(tp->rcv_wnd); - /* FIXME: csum_partial() of a four byte quantity is itself! -DaveM */ - ptr = skb_put(skb, TCPOLEN_MSS); - ptr[0] = TCPOPT_MSS; - ptr[1] = TCPOLEN_MSS; - ptr[2] = (mss >> 8) & 0xff; - ptr[3] = mss & 0xff; - skb->csum = csum_partial(ptr, TCPOLEN_MSS, 0); + /* XXX Partial csum of 4 byte quantity is itself! -DaveM + * Yes, but it's a bit harder to special case now. It's + * now computed inside the tcp_v4_send_check() to clean up + * updating the options fields in the mainline send code. + * If someone thinks this is really bad let me know and + * I'll try to do it a different way. -- erics + */ - th->check = tcp_v4_check(th, sizeof(*th) + TCPOLEN_MSS, + tmp = tcp_syn_build_options(skb, req->mss, req->sack_ok, req->tstamp_ok, + (req->snd_wscale)?tp->rcv_wscale:0); + skb->csum = 0; + th->doff = (sizeof(*th) + tmp)>>2; + th->check = tcp_v4_check(th, sizeof(*th) + tmp, req->af.v4_req.loc_addr, req->af.v4_req.rmt_addr, - csum_partial((char *)th, sizeof(*th), skb->csum)); + csum_partial((char *)th, sizeof(*th)+tmp, skb->csum)); ip_queue_xmit(skb); tcp_statistics.TcpOutSegs++; @@ -870,23 +881,21 @@ static int tcp_v4_syn_filter(struct sock *sk, struct sk_buff *skb, __u32 saddr) int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 isn) { struct ip_options *opt = (struct ip_options *) ptr; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct open_request *req; struct tcphdr *th = skb->h.th; __u32 saddr = skb->nh.iph->saddr; __u32 daddr = skb->nh.iph->daddr; - __u16 req_mss; /* If the socket is dead, don't accept the connection. */ - if (sk->dead) - { + if (sk->dead) { SOCK_DEBUG(sk, "Reset on %p: Connect on dead socket.\n",sk); tcp_statistics.TcpAttemptFails++; return -ENOTCONN; } if (sk->ack_backlog >= sk->max_ack_backlog || - tcp_v4_syn_filter(sk, skb, saddr)) - { + tcp_v4_syn_filter(sk, skb, saddr)) { SOCK_DEBUG(sk, "dropping syn ack:%d max:%d\n", sk->ack_backlog, sk->max_ack_backlog); #ifdef CONFIG_IP_TCPSF @@ -906,10 +915,17 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 i req->rcv_isn = skb->seq; req->snt_isn = isn; - req_mss = tcp_parse_options(th); - if (!req_mss) - req_mss = 536; - req->mss = req_mss; + tp->tstamp_ok = tp->sack_ok = tp->snd_wscale = 0; + tcp_parse_options(th,tp); + if (tp->saw_tstamp) { + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = jiffies; + } + req->mss = tp->in_mss; + req->tstamp_ok = tp->tstamp_ok; + req->sack_ok = tp->sack_ok; + req->snd_wscale = tp->snd_wscale; + req->ts_recent = tp->ts_recent; req->rmt_port = th->source; req->af.v4_req.loc_addr = daddr; req->af.v4_req.rmt_addr = saddr; @@ -968,12 +984,7 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, skb_queue_head_init(&newsk->out_of_order_queue); skb_queue_head_init(&newsk->error_queue); - /* - * Unused - */ - - newsk->send_head = NULL; - + /* Unused */ newtp = &(newsk->tp_pinfo.af_tcp); newtp->send_head = NULL; newtp->retrans_head = NULL; @@ -984,15 +995,10 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk->prot->init(newsk); - newsk->cong_count = 0; -#if 0 /* Don't mess up the initialization we did in the init routine! */ - newsk->ssthresh = 0; -#endif + newtp->snd_cwnd_cnt = 0; newtp->backoff = 0; - newsk->intr = 0; newsk->proc = 0; newsk->done = 0; - newsk->partial = NULL; newsk->pair = NULL; atomic_set(&newsk->wmem_alloc, 0); atomic_set(&newsk->rmem_alloc, 0); @@ -1004,24 +1010,23 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk->shutdown = 0; newsk->ack_backlog = 0; - newsk->fin_seq = req->rcv_isn; + newtp->fin_seq = req->rcv_isn; newsk->syn_seq = req->rcv_isn; newsk->state = TCP_SYN_RECV; newsk->timeout = 0; - newsk->ip_xmit_timeout = 0; newsk->write_seq = req->snt_isn; newtp->snd_wnd = ntohs(skb->h.th->window); - newsk->max_window = newtp->snd_wnd; + newtp->max_window = newtp->snd_wnd; newtp->snd_wl1 = req->rcv_isn; newtp->snd_wl2 = newsk->write_seq; newtp->snd_una = newsk->write_seq++; newtp->snd_nxt = newsk->write_seq; newsk->urg_data = 0; - newsk->packets_out = 0; - atomic_set(&newsk->retransmits, 0); + newtp->packets_out = 0; + newtp->retransmits = 0; newsk->linger=0; newsk->destroy = 0; init_timer(&newsk->timer); @@ -1034,7 +1039,7 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk->dummy_th.dest = req->rmt_port; newsk->sock_readers=0; - newtp->rcv_nxt = req->rcv_isn + 1; + newtp->last_ack_sent = newtp->rcv_nxt = req->rcv_isn + 1; newtp->rcv_wup = req->rcv_isn + 1; newsk->copied_seq = req->rcv_isn + 1; @@ -1044,9 +1049,7 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk->saddr = req->af.v4_req.loc_addr; newsk->rcv_saddr = req->af.v4_req.loc_addr; - /* - * options / mss / route_cache - */ + /* options / mss / route_cache */ newsk->opt = req->af.v4_req.opt; if (ip_route_output(&rt, newsk->opt && newsk->opt->srr ? newsk->opt->faddr : newsk->daddr, @@ -1057,19 +1060,34 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk->dst_cache = &rt->u.dst; - newsk->window_clamp = rt->u.dst.window; + newtp->window_clamp = rt->u.dst.window; snd_mss = rt->u.dst.pmtu; + /* FIXME: is mtu really the same as snd_mss? */ newsk->mtu = snd_mss; + /* FIXME: where does mtu get used after this? */ /* sanity check */ if (newsk->mtu < 64) newsk->mtu = 64; + newtp->sack_ok = req->sack_ok; + newtp->tstamp_ok = req->tstamp_ok; + newtp->snd_wscale = req->snd_wscale; + newtp->ts_recent = req->ts_recent; + newtp->ts_recent_stamp = jiffies; + if (newtp->tstamp_ok) { + newtp->tcp_header_len = sizeof(struct tcphdr) + 12; /* FIXME: define constant! */ + newsk->dummy_th.doff += 3; + } else { + newtp->tcp_header_len = sizeof(struct tcphdr); + } + snd_mss -= sizeof(struct iphdr) + sizeof(struct tcphdr); if (sk->user_mss) snd_mss = min(snd_mss, sk->user_mss); - newsk->mss = min(req->mss, snd_mss); + /* Make sure our mtu is adjusted for headers. */ + newsk->mss = min(req->mss, snd_mss) + sizeof(struct tcphdr) - newtp->tcp_header_len; tcp_v4_hash(newsk); add_to_prot_sklist(newsk); @@ -1085,10 +1103,10 @@ struct sock *tcp_v4_check_req(struct sock *sk, struct sk_buff *skb) * as we checked the user count on tcp_rcv and we're * running from a soft interrupt. */ - if (!req) + if(!req) return sk; - do { + while(req) { if (req->af.v4_req.rmt_addr == skb->nh.iph->saddr && req->af.v4_req.loc_addr == skb->nh.iph->daddr && req->rmt_port == skb->h.th->source) { @@ -1122,7 +1140,8 @@ struct sock *tcp_v4_check_req(struct sock *sk, struct sk_buff *skb) req->sk = sk; break; } - } while ((req = req->dl_next) != tp->syn_wait_queue); + req = req->dl_next; + } skb_orphan(skb); skb_set_owner_r(skb, sk); @@ -1146,20 +1165,13 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) goto ok; } - if (sk->state == TCP_LISTEN) - { + if (sk->state == TCP_LISTEN) { struct sock *nsk; - /* - * find possible connection requests - */ - + /* Find possible connection requests. */ nsk = tcp_v4_check_req(sk, skb); - if (nsk == NULL) - { goto discard_it; - } release_sock(sk); lock_sock(nsk); @@ -1173,9 +1185,7 @@ reset: tcp_v4_send_reset(skb); discard_it: - /* - * Discard frame - */ + /* Discard frame. */ kfree_skb(skb, FREE_READ); ok: @@ -1199,25 +1209,19 @@ int tcp_v4_rcv(struct sk_buff *skb, unsigned short len) if (skb->pkt_type!=PACKET_HOST) goto discard_it; - /* - * Pull up the IP header. - */ - + /* Pull up the IP header. */ skb_pull(skb, skb->h.raw-skb->data); - /* - * Try to use the device checksum if provided. - */ - - switch (skb->ip_summed) - { + /* Try to use the device checksum if provided. */ + switch (skb->ip_summed) { case CHECKSUM_NONE: skb->csum = csum_partial((char *)th, len, 0); case CHECKSUM_HW: if (tcp_v4_check(th,len,saddr,daddr,skb->csum)) { struct iphdr * iph = skb->nh.iph; - printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, len=%d/%d/%d\n", + printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, ack = %u, seq = %u, len=%d/%d/%d\n", saddr, ntohs(th->source), daddr, + ntohl(th->ack_seq), ntohl(th->seq), ntohs(th->dest), len, skb->len, ntohs(iph->tot_len)); goto discard_it; } @@ -1243,7 +1247,6 @@ int tcp_v4_rcv(struct sk_buff *skb, unsigned short len) skb->end_seq = skb->seq + th->syn + th->fin + len - th->doff*4; skb->ack_seq = ntohl(th->ack_seq); - skb->acked = 0; skb->used = 0; if (!sk->sock_readers) @@ -1256,9 +1259,7 @@ no_tcp_socket: tcp_v4_send_reset(skb); discard_it: - /* - * Discard frame - */ + /* Discard frame. */ kfree_skb(skb, FREE_READ); return 0; } @@ -1290,10 +1291,7 @@ int tcp_v4_rebuild_header(struct sock *sk, struct sk_buff *skb) skb->dst = &rt->u.dst; } - /* - * Discard the surplus MAC header - */ - + /* Discard the surplus MAC header. */ skb_pull(skb, skb->nh.raw-skb->data); iph = skb->nh.iph; @@ -1349,32 +1347,38 @@ static int tcp_v4_init_sock(struct sock *sk) tp->iat = (HZ/5) << 3; tp->rcv_wnd = 8192; + tp->tstamp_ok = 0; + tp->sack_ok = 0; + tp->in_mss = 0; + tp->snd_wscale = 0; + tp->sacks = 0; + tp->saw_tstamp = 0; /* * See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ tp->snd_cwnd = 1; - sk->ssthresh = 0x7fffffff; /* Infinity */ + tp->snd_ssthresh = 0x7fffffff; /* Infinity */ sk->priority = 1; sk->state = TCP_CLOSE; - /* this is how many unacked bytes we will accept for this socket. */ + /* This is how many unacked bytes we will accept for this socket. */ sk->max_unacked = 2048; /* needs to be at most 2 full packets. */ sk->max_ack_backlog = SOMAXCONN; sk->mtu = 576; sk->mss = 536; - /* - * Speed up by setting some standard state for the dummy_th. - */ - - sk->dummy_th.doff = sizeof(sk->dummy_th)/4; + /* Speed up by setting some standard state for the dummy_th. */ sk->dummy_th.ack=1; sk->dummy_th.doff=sizeof(struct tcphdr)>>2; + /* Init SYN queue. */ + tp->syn_wait_queue = NULL; + tp->syn_wait_last = &tp->syn_wait_queue; + sk->tp_pinfo.af_tcp.af_specific = &ipv4_specific; return 0; @@ -1387,27 +1391,15 @@ static int tcp_v4_destroy_sock(struct sock *sk) tcp_clear_xmit_timers(sk); if (sk->keepopen) - { tcp_dec_slow_timer(TCP_SLT_KEEPALIVE); - } - /* - * Cleanup up the write buffer. - */ - - while((skb = skb_dequeue(&sk->write_queue)) != NULL) { - IS_SKB(skb); + /* Cleanup up the write buffer. */ + while((skb = skb_dequeue(&sk->write_queue)) != NULL) kfree_skb(skb, FREE_WRITE); - } - - /* - * Cleans up our, hopefuly empty, out_of_order_queue - */ - while((skb = skb_dequeue(&sk->out_of_order_queue)) != NULL) { - IS_SKB(skb); + /* Cleans up our, hopefuly empty, out_of_order_queue. */ + while((skb = skb_dequeue(&sk->out_of_order_queue)) != NULL) kfree_skb(skb, FREE_READ); - } return 0; } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 57dac01ca..7f157abe2 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.35 1997/04/16 09:18:53 davem Exp $ + * Version: $Id: tcp_output.c,v 1.42 1997/04/22 01:06:33 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -34,14 +34,18 @@ #include -/* - * Get rid of any delayed acks, we sent one already.. - */ +extern int sysctl_tcp_sack; +extern int sysctl_tcp_tsack; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; + +/* Get rid of any delayed acks, we sent one already.. */ static __inline__ void clear_delayed_acks(struct sock * sk) { - sk->delayed_acks = 0; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + tp->delayed_acks = 0; sk->ack_backlog = 0; - sk->bytes_rcv = 0; tcp_clear_xmit_timer(sk, TIME_DACK); } @@ -50,12 +54,8 @@ static __inline__ void update_send_head(struct sock *sk) struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; tp->send_head = tp->send_head->next; - if (tp->send_head == (struct sk_buff *) &sk->write_queue) - { tp->send_head = NULL; - } - } static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb) @@ -64,8 +64,7 @@ static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb) int nagle_check = 1; int len; - /* - * RFC 1122 - section 4.2.3.4 + /* RFC 1122 - section 4.2.3.4 * * We must queue if * @@ -76,17 +75,41 @@ static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb) * c) We are retransmiting [Nagle] * d) We have too many packets 'in flight' */ - len = skb->end_seq - skb->seq; - - if (!sk->nonagle && len < (sk->mss >> 1) && sk->packets_out) - { + if (!sk->nonagle && len < (sk->mss >> 1) && tp->packets_out) nagle_check = 0; - } - return (nagle_check && sk->packets_out < tp->snd_cwnd && + return (nagle_check && tp->packets_out < tp->snd_cwnd && !after(skb->end_seq, tp->snd_una + tp->snd_wnd) && - atomic_read(&sk->retransmits) == 0); + tp->retransmits == 0); +} + +static __inline__ void tcp_build_options(__u32 *ptr, struct tcp_opt *tp) +{ + /* FIXME: We will still need to do SACK here. */ + if (tp->tstamp_ok) { + *ptr++ = ntohl((TCPOPT_NOP << 24) + | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) + | TCPOLEN_TIMESTAMP); + /* WARNING: If HZ is ever larger than 1000 on some system, + * then we will be violating RFC1323 here because our timestamps + * will be moving too fast. + * FIXME: code TCP so it uses at most ~ 1000 ticks a second? + * (I notice alpha is 1024 ticks now). -- erics + */ + *ptr++ = htonl(jiffies); + *ptr = htonl(tp->ts_recent); + } +} + +static __inline__ void tcp_update_options(__u32 *ptr, struct tcp_opt *tp) +{ + /* FIXME: We will still need to do SACK here. */ + if (tp->tstamp_ok) { + *++ptr = htonl(jiffies); + *++ptr = htonl(tp->ts_recent); + } } /* @@ -100,75 +123,56 @@ int tcp_send_skb(struct sock *sk, struct sk_buff *skb) struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int size; - /* - * length of packet (not counting length of pre-tcp headers) - */ - + /* Length of packet (not counting length of pre-tcp headers). */ size = skb->len - ((unsigned char *) th - skb->data); - /* - * Sanity check it.. - */ - - if (size < sizeof(struct tcphdr) || size > skb->len) - { - printk(KERN_DEBUG "tcp_send_skb: bad skb (skb = %p, data = %p, th = %p, len = %u)\n", - skb, skb->data, th, skb->len); + /* Sanity check it.. */ + if (size < sizeof(struct tcphdr) || size > skb->len) { + printk(KERN_DEBUG "tcp_send_skb: bad skb " + "(skb = %p, data = %p, th = %p, len = %u)\n", + skb, skb->data, th, skb->len); kfree_skb(skb, FREE_WRITE); return 0; } - /* - * If we have queued a header size packet.. (these crash a few - * tcp stacks if ack is not set) + /* If we have queued a header size packet.. (these crash a few + * tcp stacks if ack is not set) + * FIXME: What is the equivalent below when we have options? */ - - if (size == sizeof(struct tcphdr)) - { - /* - * If it's got a syn or fin discard - */ - if(!th->syn && !th->fin) - { + if (size == sizeof(struct tcphdr)) { + /* If it's got a syn or fin discard. */ + if(!th->syn && !th->fin) { printk(KERN_DEBUG "tcp_send_skb: attempt to queue a bogon.\n"); kfree_skb(skb,FREE_WRITE); return 0; } } - /* - * Actual processing. - */ + /* Actual processing. */ skb->seq = ntohl(th->seq); skb->end_seq = skb->seq + size - 4*th->doff; skb_queue_tail(&sk->write_queue, skb); - if (tp->send_head == NULL && tcp_snd_test(sk, skb)) - { + if (tp->send_head == NULL && tcp_snd_test(sk, skb)) { struct sk_buff * buff; - /* - * This is going straight out - */ - - th->ack_seq = htonl(tp->rcv_nxt); + /* This is going straight out. */ + tp->last_ack_sent = th->ack_seq = htonl(tp->rcv_nxt); th->window = htons(tcp_select_window(sk)); + tcp_update_options((__u32 *)(th+1),tp); tp->af_specific->send_check(sk, th, size, skb); buff = skb_clone(skb, GFP_KERNEL); - if (buff == NULL) - { goto queue; - } clear_delayed_acks(sk); skb_set_owner_w(buff, sk); tp->snd_nxt = skb->end_seq; - sk->packets_out++; + tp->packets_out++; skb->when = jiffies; @@ -182,19 +186,13 @@ int tcp_send_skb(struct sock *sk, struct sk_buff *skb) } queue: - /* - * Remember where we must start sending - */ - + /* Remember where we must start sending. */ if (tp->send_head == NULL) tp->send_head = skb; - - if (sk->packets_out == 0 && !tp->pending) - { + if (tp->packets_out == 0 && !tp->pending) { tp->pending = TIME_PROBE0; tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); } - return 0; } @@ -215,86 +213,61 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) th = skb->h.th; - /* size of new segment */ - nsize = skb->tail - ((unsigned char *) (th + 1)) - len; - - if (nsize <= 0) - { + /* Size of new segment. */ + nsize = skb->tail - ((unsigned char *)(th)+tp->tcp_header_len) - len; + if (nsize <= 0) { printk(KERN_DEBUG "tcp_fragment: bug size <= 0\n"); return -1; } - /* - * Get a new skb... force flag on - */ + /* Get a new skb... force flag on. */ buff = sock_wmalloc(sk, nsize + 128 + sk->prot->max_header + 15, 1, GFP_ATOMIC); - if (buff == NULL) return -1; - /* - * Put headers on the new packet - */ - + /* Put headers on the new packet. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); return -1; } - /* - * Move the TCP header over - */ - - nth = (struct tcphdr *) skb_put(buff, sizeof(*th)); - + /* Move the TCP header over. */ + nth = (struct tcphdr *) skb_put(buff, tp->tcp_header_len); buff->h.th = nth; + memcpy(nth, th, tp->tcp_header_len); + + /* FIXME: Make sure this gets tcp options right. */ - memcpy(nth, th, sizeof(*th)); - - /* - * Correct the new header - */ - + /* Correct the new header. */ buff->seq = skb->seq + len; buff->end_seq = skb->end_seq; nth->seq = htonl(buff->seq); nth->check = 0; - nth->doff = 5; + nth->doff = th->doff; /* urg data is always an headache */ - if (th->urg) - { - if (th->urg_ptr > len) - { + if (th->urg) { + if (th->urg_ptr > len) { th->urg = 0; nth->urg_ptr -= len; - } - else - { + } else { nth->urg = 0; } } - /* - * Copy TCP options and data start to our new buffer - */ - - buff->csum = csum_partial_copy(((u8 *)(th + 1)) + len, + /* Copy data tail to our new buffer. */ + buff->csum = csum_partial_copy(((u8 *)(th)+tp->tcp_header_len) + len, skb_put(buff, nsize), nsize, 0); - skb->end_seq -= nsize; - skb_trim(skb, skb->len - nsize); - /* remember to checksum this packet afterwards */ + /* Remember to checksum this packet afterwards. */ th->check = 0; - skb->csum = csum_partial((u8*) (th + 1), skb->tail - ((u8 *) (th + 1)), + skb->csum = csum_partial((u8*)(th) + tp->tcp_header_len, skb->tail - ((u8 *) (th)+tp->tcp_header_len), 0); skb_append(skb, buff); @@ -304,12 +277,10 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) static void tcp_wrxmit_prob(struct sock *sk, struct sk_buff *skb) { - /* - * This is acked data. We can discard it. This - * cannot currently occur. - */ + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - atomic_set(&sk->retransmits, 0); + /* This is acked data. We can discard it. This cannot currently occur. */ + tp->retransmits = 0; printk(KERN_DEBUG "tcp_write_xmit: bug skb in write queue\n"); @@ -329,17 +300,13 @@ static int tcp_wrxmit_frag(struct sock *sk, struct sk_buff *skb, int size) SOCK_DEBUG(sk, "tcp_write_xmit: frag needed size=%d mss=%d\n", size, sk->mss); - if (tcp_fragment(sk, skb, sk->mss)) - { + if (tcp_fragment(sk, skb, sk->mss)) { /* !tcp_frament Failed! */ tp->send_head = skb; - sk->packets_out--; + tp->packets_out--; return -1; - } - else - { - /* - * If tcp_fragment succeded then + } else { + /* If tcp_fragment succeded then * the send head is the resulting * fragment */ @@ -357,69 +324,52 @@ static int tcp_wrxmit_frag(struct sock *sk, struct sk_buff *skb, int size) void tcp_write_xmit(struct sock *sk) { struct sk_buff *skb; - struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); u16 rcv_wnd; int sent_pkts = 0; - /* - * The bytes will have to remain here. In time closedown will - * empty the write queue and all will be happy + /* The bytes will have to remain here. In time closedown will + * empty the write queue and all will be happy. */ - if(sk->zapped) return; - /* - * Anything on the transmit queue that fits the window can + /* Anything on the transmit queue that fits the window can * be added providing we are: * * a) following SWS avoidance [and Nagle algorithm] * b) not exceeding our congestion window. * c) not retransmiting [Nagle] */ - rcv_wnd = htons(tcp_select_window(sk)); - - while((skb = tp->send_head) && tcp_snd_test(sk, skb)) - { + while((skb = tp->send_head) && tcp_snd_test(sk, skb)) { struct tcphdr *th; struct sk_buff *buff; int size; - IS_SKB(skb); - - /* - * See if we really need to send the packet. - * (debugging code) - */ - - if (!after(skb->end_seq, tp->snd_una)) - { + /* See if we really need to send the packet. (debugging code) */ + if (!after(skb->end_seq, tp->snd_una)) { tcp_wrxmit_prob(sk, skb); continue; - } - + } - /* - * Put in the ack seq and window at this point rather + /* Put in the ack seq and window at this point rather * than earlier, in order to keep them monotonic. * We really want to avoid taking back window allocations. * That's legal, but RFC1122 says it's frowned on. * Ack and window will in general have changed since * this packet was put on the write queue. */ - th = skb->h.th; size = skb->len - (((unsigned char *) th) - skb->data); - - if (size - (th->doff << 2) > sk->mss) - { + if (size - (th->doff << 2) > sk->mss) { if (tcp_wrxmit_frag(sk, skb, size)) break; } - th->ack_seq = htonl(tp->rcv_nxt); + tp->last_ack_sent = th->ack_seq = htonl(tp->rcv_nxt); th->window = rcv_wnd; + tcp_update_options((__u32 *)(th+1),tp); tp->af_specific->send_check(sk, th, size, skb); @@ -430,18 +380,14 @@ void tcp_write_xmit(struct sock *sk) #endif buff = skb_clone(skb, GFP_ATOMIC); - if (buff == NULL) break; - /* - * Advance the send_head. This one is going out. - */ - + /* Advance the send_head. This one is going out. */ update_send_head(sk); clear_delayed_acks(sk); - sk->packets_out++; + tp->packets_out++; skb_set_owner_w(buff, sk); tp->snd_nxt = skb->end_seq; @@ -450,13 +396,10 @@ void tcp_write_xmit(struct sock *sk) sent_pkts = 1; tp->af_specific->queue_xmit(buff); - } if (sent_pkts && !tcp_timer_is_set(sk, TIME_RETRANS)) - { tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); - } } @@ -469,33 +412,25 @@ void tcp_write_xmit(struct sock *sk) * 2. We limit memory per socket */ - unsigned short tcp_select_window(struct sock *sk) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; int mss = sk->mss; long free_space = sock_rspace(sk); - long window; - long cur_win; - long usable; + long window, cur_win, usable; - - if (sk->window_clamp) - { - free_space = min(sk->window_clamp, free_space); - mss = min(sk->window_clamp, mss); + if (tp->window_clamp) { + free_space = min(tp->window_clamp, free_space); + mss = min(tp->window_clamp, mss); } - /* - * compute the actual window i.e. + /* compute the actual window i.e. * old_window - received_bytes_on_that_win */ - cur_win = tp->rcv_wup - (tp->rcv_nxt - tp->rcv_wnd); window = tp->rcv_wnd; - if ( cur_win < 0 ) - { + if (cur_win < 0) { cur_win = 0; printk(KERN_DEBUG "TSW: win < 0 w=%d 1=%u 2=%u\n", tp->rcv_wnd, tp->rcv_nxt, tp->rcv_wup); @@ -511,49 +446,33 @@ unsigned short tcp_select_window(struct sock *sk) * it MSS bytes */ - /* - * It would be a good idea if it didn't break header prediction. + /* It would be a good idea if it didn't break header prediction. * and BSD made the header predition standard... * It expects the same value in the header i.e. th->window to be * constant */ - usable = free_space - cur_win; if (usable < 0) - { usable = 0; - } - if ( window < usable ) - { - /* - * Window is not blocking the sender + if (window < usable) { + /* Window is not blocking the sender * and we have enought free space for it */ - if (cur_win > (sk->mss << 1)) goto out; } - - if (window >= usable) - { - /* - * We are offering too much, cut it down... + if (window >= usable) { + /* We are offering too much, cut it down... * but don't shrink the window */ - window = max(usable, cur_win); - } - else - { + } else { if ((usable - window) >= mss) - { window += mss; - } } - - out: +out: tp->rcv_wnd = window; tp->rcv_wup = tp->rcv_nxt; return window; @@ -561,6 +480,7 @@ unsigned short tcp_select_window(struct sock *sk) static int tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct tcphdr *th1, *th2; int size1, size2, avail; struct sk_buff *buff = skb->next; @@ -572,54 +492,35 @@ static int tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb) avail = skb_tailroom(skb); - /* - * size of tcp payload - */ - - size1 = skb->tail - (u8 *) (th1 + 1); + /* Size of TCP payload. */ + size1 = skb->tail - ((u8 *) (th1)+(th1->doff<<2)); th2 = buff->h.th; - - size2 = buff->tail - (u8 *) (th2 + 1); + size2 = buff->tail - ((u8 *) (th2)+(th2->doff<<2)); if (size2 > avail || size1 + size2 > sk->mss ) return -1; - /* - * ok. we will be able to collapse the packet - */ - + /* Ok. We will be able to collapse the packet. */ skb_unlink(buff); - memcpy(skb_put(skb, size2), ((char *) th2) + (th2->doff << 2), size2); - /* - * update sizes on original skb. both TCP and IP - */ - + /* Update sizes on original skb, both TCP and IP. */ skb->end_seq += size2; - - if (th2->urg) - { + if (th2->urg) { th1->urg = 1; th1->urg_ptr = th2->urg_ptr + size1; } - /* - * ... and off you go. - */ - + /* ... and off you go. */ kfree_skb(buff, FREE_WRITE); - sk->packets_out--; + tp->packets_out--; - /* - * Header checksum will be set by the retransmit procedure - * after calling rebuild header + /* Header checksum will be set by the retransmit procedure + * after calling rebuild header. */ - th1->check = 0; - skb->csum = csum_partial((u8*) (th1+1), size1 + size2, 0); - + skb->csum = csum_partial((u8*)(th1)+(th1->doff<<2), size1 + size2, 0); return 0; } @@ -643,17 +544,13 @@ void tcp_do_retransmit(struct sock *sk, int all) if (tp->retrans_head == tp->send_head) tp->retrans_head = NULL; - while ((skb = tp->retrans_head) != NULL) - { + while ((skb = tp->retrans_head) != NULL) { struct sk_buff *buff; struct tcphdr *th; int tcp_size; int size; - IS_SKB(skb); - - /* - * In general it's OK just to use the old packet. However we + /* In general it's OK just to use the old packet. However we * need to use the current ack and window fields. Urg and * urg_ptr could possibly stand to be updated as well, but we * don't keep the necessary data. That shouldn't be a problem, @@ -663,28 +560,23 @@ void tcp_do_retransmit(struct sock *sk, int all) th = skb->h.th; - tcp_size = skb->tail - ((unsigned char *) (th + 1)); + tcp_size = skb->tail - ((unsigned char *)(th)+tp->tcp_header_len); - if (tcp_size > sk->mss) - { - if (tcp_fragment(sk, skb, sk->mss)) - { + if (tcp_size > sk->mss) { + if (tcp_fragment(sk, skb, sk->mss)) { printk(KERN_DEBUG "tcp_fragment failed\n"); return; } - sk->packets_out++; + tp->packets_out++; } if (!th->syn && tcp_size < (sk->mss >> 1) && skb->next != tp->send_head && skb->next != (struct sk_buff *)&sk->write_queue) - { tcp_retrans_try_collapse(sk, skb); - } - if (tp->af_specific->rebuild_header(sk, skb)) - { + if (tp->af_specific->rebuild_header(sk, skb)) { #ifdef TCP_DEBUG printk(KERN_DEBUG "tcp_do_rebuild_header failed\n"); #endif @@ -693,12 +585,10 @@ void tcp_do_retransmit(struct sock *sk, int all) SOCK_DEBUG(sk, "retransmit sending\n"); - /* - * update ack and window - */ - - th->ack_seq = htonl(tp->rcv_nxt); + /* Update ack and window. */ + tp->last_ack_sent = th->ack_seq = htonl(tp->rcv_nxt); th->window = ntohs(tcp_select_window(sk)); + tcp_update_options((__u32 *)(th+1),tp); size = skb->tail - (unsigned char *) th; tp->af_specific->send_check(sk, th, size, skb); @@ -706,49 +596,32 @@ void tcp_do_retransmit(struct sock *sk, int all) skb->when = jiffies; buff = skb_clone(skb, GFP_ATOMIC); - if (buff == NULL) break; + skb_set_owner_w(buff, sk); clear_delayed_acks(sk); - tp->af_specific->queue_xmit(buff); - /* - * Count retransmissions - */ - + /* Count retransmissions. */ ct++; - sk->prot->retransmits++; /* ???: atomic_t necessary here? -DaveM */ + sk->prot->retransmits++; tcp_statistics.TcpRetransSegs++; - tp->high_seq = tp->snd_nxt; - - /* - * Only one retransmit requested. - */ - + /* Only one retransmit requested. */ if (!all) break; - /* - * This should cut it off before we send too many packets. - */ - + /* This should cut it off before we send too many packets. */ if (ct >= tp->snd_cwnd) break; - /* - * Advance the pointer - */ - + /* Advance the pointer. */ tp->retrans_head = skb->next; if ((tp->retrans_head == tp->send_head) || (tp->retrans_head == (struct sk_buff *) &sk->write_queue)) - { tp->retrans_head = NULL; - } } } @@ -764,53 +637,40 @@ void tcp_send_fin(struct sock *sk) struct sk_buff *buff; int tmp; - - buff = sock_wmalloc(sk, MAX_RESET_SIZE, 1, GFP_KERNEL); - - if (buff == NULL) - { - /* This is a disaster if it occurs */ + buff = sock_wmalloc(sk, BASE_ACK_SIZE + tp->tcp_header_len, 1, GFP_KERNEL); + if (buff == NULL) { + /* FIXME: This is a disaster if it occurs. */ printk(KERN_INFO "tcp_send_fin: Impossible malloc failure"); return; } - /* - * Administrivia - */ - + /* Administrivia. */ buff->csum = 0; - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { int t; - /* - * Finish anyway, treat this as a send that got lost. - * (Not good). + + /* FIXME: We must not throw this out. Eventually we must + * put a FIN into the queue, otherwise it never gets queued. */ - kfree_skb(buff, FREE_WRITE); sk->write_seq++; - t=del_timer(&sk->timer); - if(t) + t = del_timer(&sk->timer); + if (t) add_timer(&sk->timer); else tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); return; } - /* - * We ought to check if the end of the queue is a buffer and - * if so simply add the fin to that buffer, not send it ahead. + /* We ought to check if the end of the queue is a buffer and + * if so simply add the fin to that buffer, not send it ahead. */ - - t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr)); + t1 =(struct tcphdr *)skb_put(buff,tp->tcp_header_len); buff->h.th = t1; + tcp_build_options((__u32 *)(t1+1),tp); memcpy(t1, th, sizeof(*t1)); buff->seq = sk->write_seq; @@ -821,26 +681,19 @@ void tcp_send_fin(struct sock *sk) t1->window = htons(tcp_select_window(sk)); t1->fin = 1; - tp->af_specific->send_check(sk, t1, sizeof(*t1), buff); + tp->af_specific->send_check(sk, t1, tp->tcp_header_len, buff); - /* - * The fin can only be transmited after the data. - */ - + /* The fin can only be transmited after the data. */ skb_queue_tail(&sk->write_queue, buff); - - if (tp->send_head == NULL) - { + if (tp->send_head == NULL) { struct sk_buff *skb1; - sk->packets_out++; + tp->packets_out++; tp->snd_nxt = sk->write_seq; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); - - if (skb1) - { + if (skb1) { skb_set_owner_w(skb1, sk); tp->af_specific->queue_xmit(skb1); } @@ -856,20 +709,14 @@ int tcp_send_synack(struct sock *sk) struct sk_buff * skb; struct sk_buff * buff; struct tcphdr *th; - unsigned char *ptr; int tmp; skb = sock_wmalloc(sk, MAX_SYN_SIZE, 1, GFP_ATOMIC); - if (skb == NULL) - { return -ENOMEM; - } tmp = tp->af_specific->build_net_header(sk, skb); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(skb, FREE_WRITE); return tmp; } @@ -890,27 +737,23 @@ int tcp_send_synack(struct sock *sk) th->window = ntohs(tp->rcv_wnd); - th->ack_seq = htonl(tp->rcv_nxt); - th->doff = sizeof(*th)/4 + 1; + tp->last_ack_sent = th->ack_seq = htonl(tp->rcv_nxt); - ptr = skb_put(skb, TCPOLEN_MSS); - ptr[0] = TCPOPT_MSS; - ptr[1] = TCPOLEN_MSS; - ptr[2] = ((sk->mss) >> 8) & 0xff; - ptr[3] = (sk->mss) & 0xff; - skb->csum = csum_partial(ptr, TCPOLEN_MSS, 0); + tmp = tcp_syn_build_options(skb, sk->mss, + tp->sack_ok, tp->tstamp_ok, + tp->snd_wscale?tp->rcv_wscale:0); + skb->csum = 0; + th->doff = (sizeof(*th) + tmp)>>2; - tp->af_specific->send_check(sk, th, sizeof(*th)+4, skb); + tp->af_specific->send_check(sk, th, sizeof(*th)+tmp, skb); skb_queue_tail(&sk->write_queue, skb); buff = skb_clone(skb, GFP_ATOMIC); - - if (buff) - { + if (buff) { skb_set_owner_w(buff, sk); - sk->packets_out++; + tp->packets_out++; skb->when = jiffies; tp->af_specific->queue_xmit(buff); @@ -935,22 +778,19 @@ void tcp_send_delayed_ack(struct sock * sk, int max_timeout) struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; unsigned long timeout, now; - /* Calculate new timeout */ + /* Calculate new timeout. */ now = jiffies; timeout = tp->ato; - if (timeout > max_timeout || sk->bytes_rcv > (sk->mss << 2)) - { + if (timeout > max_timeout || + ((tp->rcv_nxt - tp->rcv_wup) > (sk->mss << 2))) timeout = now; - } else timeout += now; - /* Use new timeout only if there wasn't a older one earlier */ + /* Use new timeout only if there wasn't a older one earlier. */ if (!del_timer(&tp->delack_timer) || timeout < tp->delack_timer.expires) - { tp->delack_timer.expires = timeout; - } add_timer(&tp->delack_timer); } @@ -968,75 +808,53 @@ void tcp_send_ack(struct sock *sk) struct tcphdr *th; int tmp; - if(sk->zapped) - { - /* We have been reset, we may not send again */ - return; - } + return; /* We have been reset, we may not send again. */ - /* - * We need to grab some memory, and put together an ack, + /* We need to grab some memory, and put together an ack, * and then put it into the queue to be sent. + * FIXME: is it better to waste memory here and use a + * constant sized ACK? */ - - buff = sock_wmalloc(sk, MAX_ACK_SIZE, 1, GFP_ATOMIC); - if (buff == NULL) - { - /* - * Force it to send an ack. We don't have to do this - * (ACK is unreliable) but it's much better use of + buff = sock_wmalloc(sk, BASE_ACK_SIZE + tp->tcp_header_len, 1, GFP_ATOMIC); + if (buff == NULL) { + /* Force it to send an ack. We don't have to do this + * (ACK is unreliable) but it's much better use of * bandwidth on slow links to send a spare ack than - * resend packets. + * resend packets. */ - tcp_send_delayed_ack(sk, HZ/2); return; } clear_delayed_acks(sk); - /* - * Assemble a suitable TCP frame - */ - + /* Assemble a suitable TCP frame. */ buff->csum = 0; - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); return; } - th =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr)); - + th = (struct tcphdr *)skb_put(buff,tp->tcp_header_len); memcpy(th, &sk->dummy_th, sizeof(struct tcphdr)); + tcp_build_options((__u32 *)(th+1),tp); - /* - * Swap the send and the receive. - */ - + /* Swap the send and the receive. */ th->window = ntohs(tcp_select_window(sk)); th->seq = ntohl(tp->snd_nxt); - th->ack_seq = ntohl(tp->rcv_nxt); - - /* - * Fill in the packet and send it - */ + tp->last_ack_sent = th->ack_seq = ntohl(tp->rcv_nxt); - tp->af_specific->send_check(sk, th, sizeof(struct tcphdr), buff); + /* Fill in the packet and send it. */ + tp->af_specific->send_check(sk, th, tp->tcp_header_len, buff); SOCK_DEBUG(sk, "\rtcp_send_ack: seq %x ack %x\n", tp->snd_nxt, tp->rcv_nxt); tp->af_specific->queue_xmit(buff); - tcp_statistics.TcpOutSegs++; } @@ -1053,61 +871,44 @@ void tcp_write_wakeup(struct sock *sk) int tmp; if (sk->zapped) - return; /* After a valid reset we can send no more */ + return; /* After a valid reset we can send no more. */ - /* - * Write data can still be transmitted/retransmitted in the + /* Write data can still be transmitted/retransmitted in the * following states. If any other state is encountered, return. * [listen/close will never occur here anyway] */ - if (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT && sk->state != TCP_FIN_WAIT1 && sk->state != TCP_LAST_ACK && - sk->state != TCP_CLOSING - ) - { + sk->state != TCP_CLOSING) return; - } - - if (before(tp->snd_nxt, tp->snd_una + tp->snd_wnd) && - (skb=tp->send_head)) - { - /* - * We are probing the opening of a window - * but the window size is != 0 - * must have been a result SWS avoidance ( sender ) - */ + if (before(tp->snd_nxt, tp->snd_una + tp->snd_wnd) && (skb=tp->send_head)) { struct tcphdr *th; unsigned long win_size; + /* We are probing the opening of a window + * but the window size is != 0 + * must have been a result SWS avoidance ( sender ) + */ win_size = tp->snd_wnd - (tp->snd_nxt - tp->snd_una); - - if (win_size < skb->end_seq - skb->seq) - { - if (tcp_fragment(sk, skb, win_size)) - { + if (win_size < skb->end_seq - skb->seq) { + if (tcp_fragment(sk, skb, win_size)) { printk(KERN_DEBUG "tcp_write_wakeup: " "fragment failed\n"); return; } } - th = skb->h.th; - - tp->af_specific->send_check(sk, th, th->doff * 4 + win_size, - skb); - + tp->af_specific->send_check(sk, th, th->doff * 4 + win_size, skb); buff = skb_clone(skb, GFP_ATOMIC); if (buff == NULL) - { return; - } + skb_set_owner_w(buff, sk); - sk->packets_out++; + tp->packets_out++; clear_delayed_acks(sk); @@ -1115,36 +916,29 @@ void tcp_write_wakeup(struct sock *sk) tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); skb->when = jiffies; - update_send_head(sk); - tp->snd_nxt = skb->end_seq; - } - else - { - buff = sock_wmalloc(sk,MAX_ACK_SIZE, 1, GFP_ATOMIC); + } else { + buff = sock_wmalloc(sk, MAX_ACK_SIZE, 1, GFP_ATOMIC); if (buff == NULL) return; buff->csum = 0; - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); return; } t1 = (struct tcphdr *) skb_put(buff, sizeof(struct tcphdr)); memcpy(t1,(void *) &sk->dummy_th, sizeof(*t1)); + /* FIXME: should zero window probes have SACK and/or TIMESTAMP data? + * If so we have to tack them on here. + */ - /* - * Use a previous sequence. + /* Use a previous sequence. * This should cause the other end to send an ack. */ @@ -1153,13 +947,13 @@ void tcp_write_wakeup(struct sock *sk) t1->ack_seq = htonl(tp->rcv_nxt); t1->window = htons(tcp_select_window(sk)); + /* Value from dummy_th may be larger. */ + t1->doff = sizeof(struct tcphdr)/4; + tp->af_specific->send_check(sk, t1, sizeof(*t1), buff); } - /* - * Send it. - */ - + /* Send it. */ tp->af_specific->queue_xmit(buff); tcp_statistics.TcpOutSegs++; } @@ -1175,16 +969,12 @@ void tcp_send_probe0(struct sock *sk) struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); if (sk->zapped) - return; /* After a valid reset we can send no more */ - + return; /* After a valid reset we can send no more. */ tcp_write_wakeup(sk); - tp->pending = TIME_PROBE0; - tp->backoff++; tp->probes_out++; - tcp_reset_xmit_timer (sk, TIME_PROBE0, min(tp->rto << tp->backoff, 120*HZ)); } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 76f821d1d..365d3dac2 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -67,16 +67,14 @@ void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - if((long)when <= 0) - { + if((long)when <= 0) { printk(KERN_DEBUG "xmit_timer <= 0 - timer:%d when:%lx\n", what, when); when=HZ/50; } switch (what) { case TIME_RETRANS: - /* - * When seting the transmit timer the probe timer + /* When seting the transmit timer the probe timer * should not be set. * The delayed ack timer can be set if we are changing the * retransmit timer when removing acked frames. @@ -105,7 +103,7 @@ void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when) default: printk(KERN_DEBUG "bug: unknown timer value\n"); - } + }; } void tcp_clear_xmit_timer(struct sock *sk, int what) @@ -124,7 +122,7 @@ void tcp_clear_xmit_timer(struct sock *sk, int what) break; default: printk(KERN_DEBUG "bug: unknown timer value\n"); - } + }; } int tcp_timer_is_set(struct sock *sk, int what) @@ -143,7 +141,7 @@ int tcp_timer_is_set(struct sock *sk, int what) break; default: printk(KERN_DEBUG "bug: unknown timer value\n"); - } + }; return 0; } @@ -162,28 +160,25 @@ void tcp_clear_xmit_timers(struct sock *sk) static int tcp_write_timeout(struct sock *sk) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + /* * Look for a 'soft' timeout. */ if ((sk->state == TCP_ESTABLISHED && - atomic_read(&sk->retransmits) && - !(atomic_read(&sk->retransmits) & 7)) || - (sk->state != TCP_ESTABLISHED && - atomic_read(&sk->retransmits) > TCP_RETR1)) - { - /* - * Attempt to recover if arp has changed (unlikely!) or + + /* Eric, what the heck is this doing?!?! */ + tp->retransmits && !(tp->retransmits & 7)) || + + (sk->state != TCP_ESTABLISHED && tp->retransmits > TCP_RETR1)) { + /* Attempt to recover if arp has changed (unlikely!) or * a route has shifted (not supported prior to 1.3). */ ip_rt_advice((struct rtable**)&sk->dst_cache, 0); } - /* - * Have we tried to SYN too many times (repent repent 8)) - */ - - if(atomic_read(&sk->retransmits) > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT) - { + /* Have we tried to SYN too many times (repent repent 8)) */ + if(tp->retransmits > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT) { if(sk->err_soft) sk->err=sk->err_soft; else @@ -199,11 +194,9 @@ static int tcp_write_timeout(struct sock *sk) /* Don't FIN, we got nothing back */ return 0; } - /* - * Has it gone just too far ? - */ - if (atomic_read(&sk->retransmits) > TCP_RETR2) - { + + /* Has it gone just too far? */ + if (tp->retransmits > TCP_RETR2) { if(sk->err_soft) sk->err = sk->err_soft; else @@ -212,19 +205,12 @@ static int tcp_write_timeout(struct sock *sk) tcp_clear_xmit_timers(sk); - /* - * Time wait the socket - */ - if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING ) - { + /* Time wait the socket. */ + if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING) { tcp_set_state(sk,TCP_TIME_WAIT); tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); - } - else - { - /* - * Clean up time. - */ + } else { + /* Clean up time. */ tcp_set_state(sk, TCP_CLOSE); return 0; } @@ -238,14 +224,10 @@ void tcp_delack_timer(unsigned long data) { struct sock *sk = (struct sock*)data; if(sk->zapped) - { return; - } - if (sk->delayed_acks) - { + if (sk->tp_pinfo.af_tcp.delayed_acks) tcp_read_wakeup(sk); - } } void tcp_probe_timer(unsigned long data) { @@ -254,16 +236,10 @@ void tcp_probe_timer(unsigned long data) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; if(sk->zapped) - { return; - } - if (sk->sock_readers) - { - /* - * Try again in second - */ - + if (sk->sock_readers) { + /* Try again in second. */ tcp_reset_xmit_timer(sk, TIME_PROBE0, HZ); return; } @@ -273,28 +249,20 @@ void tcp_probe_timer(unsigned long data) { * FIXME: We ought not to do it, Solaris 2.5 actually has fixing * this behaviour in Solaris down as a bug fix. [AC] */ - if (tp->probes_out > TCP_RETR2) - { + if (tp->probes_out > TCP_RETR2) { if(sk->err_soft) sk->err = sk->err_soft; else sk->err = ETIMEDOUT; sk->error_report(sk); - /* - * Time wait the socket - */ + /* Time wait the socket. */ if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 - || sk->state == TCP_CLOSING ) - { + || sk->state == TCP_CLOSING) { tcp_set_state(sk, TCP_TIME_WAIT); tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); - } - else - { - /* - * Clean up time. - */ + } else { + /* Clean up time. */ tcp_set_state(sk, TCP_CLOSE); } } @@ -307,24 +275,19 @@ static __inline__ int tcp_keepopen_proc(struct sock *sk) int res = 0; if (sk->state == TCP_ESTABLISHED || sk->state == TCP_CLOSE_WAIT || - sk->state == TCP_FIN_WAIT2) - { + sk->state == TCP_FIN_WAIT2) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; __u32 elapsed = jiffies - tp->rcv_tstamp; - if (elapsed >= TCP_KEEPALIVE_TIME) - { - if (tp->probes_out > TCP_KEEPALIVE_PROBES) - { + if (elapsed >= TCP_KEEPALIVE_TIME) { + if (tp->probes_out > TCP_KEEPALIVE_PROBES) { if(sk->err_soft) sk->err = sk->err_soft; else sk->err = ETIMEDOUT; tcp_set_state(sk, TCP_CLOSE); - } - else - { + } else { tp->probes_out++; tp->pending = TIME_KEEPOPEN; tcp_write_wakeup(sk); @@ -354,6 +317,16 @@ static __inline__ int tcp_keepopen_proc(struct sock *sk) /* Keepopen's are only valid for "established" TCP's, nicely our listener * hash gets rid of most of the useless testing, so we run through a couple * of the established hash chains each clock tick. -DaveM + * + * And now, even more magic... TIME_WAIT TCP's cannot have keepalive probes + * going off for them, so we only need check the first half of the established + * hash table, even less testing under heavy load. + * + * I _really_ would rather do this by adding a new timer_struct to struct sock, + * and this way only those who set the keepalive option will get the overhead. + * The idea is you set it for 2 hours when the sock is first connected, when it + * does fire off (if at all, most sockets die earlier) you check for the keepalive + * option and also if the sock has been idle long enough to start probing. */ static void tcp_keepalive(unsigned long data) { @@ -361,7 +334,7 @@ static void tcp_keepalive(unsigned long data) int count = 0; int i; - for(i = chain_start; i < (chain_start + (TCP_HTABLE_SIZE >> 2)); i++) { + for(i = chain_start; i < (chain_start + ((TCP_HTABLE_SIZE/2) >> 2)); i++) { struct sock *sk = tcp_established_hash[i]; while(sk) { if(sk->keepopen) { @@ -373,7 +346,8 @@ static void tcp_keepalive(unsigned long data) } } out: - chain_start = ((chain_start + (TCP_HTABLE_SIZE>>2)) & (TCP_HTABLE_SIZE - 1)); + chain_start = ((chain_start + ((TCP_HTABLE_SIZE/2)>>2)) & + ((TCP_HTABLE_SIZE/2) - 1)); } /* @@ -394,48 +368,35 @@ void tcp_retransmit_timer(unsigned long data) struct sock *sk = (struct sock*)data; struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - /* - * We are reset. We will send no more retransmits. - */ - - if(sk->zapped) - { + /* We are reset. We will send no more retransmits. */ + if(sk->zapped) { tcp_clear_xmit_timer(sk, TIME_RETRANS); return; } lock_sock(sk); - /* - * Clear delay ack timer - */ - + /* Clear delay ack timer. */ tcp_clear_xmit_timer(sk, TIME_DACK); - /* - * Retransmission - */ - + /* Retransmission. */ tp->retrans_head = NULL; - - if (atomic_read(&sk->retransmits) == 0) - { - /* - * remember window where we lost + if (tp->retransmits == 0) { + /* remember window where we lost * "one half of the current window but at least 2 segments" */ - - sk->ssthresh = max(tp->snd_cwnd >> 1, 2); - sk->cong_count = 0; + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd_cnt = 0; tp->snd_cwnd = 1; } - atomic_inc(&sk->retransmits); + tp->retransmits++; + tp->dup_acks = 0; + tp->high_seq = tp->snd_nxt; tcp_do_retransmit(sk, 0); - /* - * Increase the timeout each time we retransmit. Note that + /* Increase the timeout each time we retransmit. Note that * we do not increase the rtt estimate. rto is initialized * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests * that doubling rto each time is the least we can get away with. @@ -450,8 +411,7 @@ void tcp_retransmit_timer(unsigned long data) * implemented ftp to mars will work nicely. We will have to fix * the 120 second clamps though! */ - - tp->backoff++; + tp->backoff++; /* FIXME: always same as retransmits? -- erics */ tp->rto = min(tp->rto << 1, 120*HZ); tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); @@ -521,7 +481,7 @@ static void tcp_syn_recv_timer(unsigned long data) conn->expires = now + timeo; tcp_synq_queue(tp, conn); } - } while (req != tp->syn_wait_queue); + } while (req); } sk = sk->next; } @@ -535,16 +495,13 @@ void tcp_sltimer_handler(unsigned long data) unsigned long now = jiffies; int i; - for (i=0; i < TCP_SLT_MAX; i++, slt++) - { - if (atomic_read(&slt->count)) - { + for (i=0; i < TCP_SLT_MAX; i++, slt++) { + if (atomic_read(&slt->count)) { long trigger; trigger = slt->period - ((long)(now - slt->last)); - if (trigger <= 0) - { + if (trigger <= 0) { (*slt->handler)((unsigned long) slt); slt->last = now; trigger = slt->period; @@ -553,8 +510,7 @@ void tcp_sltimer_handler(unsigned long data) } } - if (next != ~0UL) - { + if (next != ~0UL) { tcp_slow_timer.expires = now + next; add_timer(&tcp_slow_timer); } @@ -570,13 +526,10 @@ void __tcp_inc_slow_timer(struct tcp_sl_timer *slt) when = now + slt->period; if (del_timer(&tcp_slow_timer)) - { next = tcp_slow_timer.expires; - } + if (next && ((long)(next - when) < 0)) - { when = next; - } tcp_slow_timer.expires = when; add_timer(&tcp_slow_timer); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index de14fec11..9ca5f3045 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -446,10 +446,16 @@ void udp_err(struct sk_buff *skb, unsigned char *dp) kfree_skb(skb2, FREE_READ); } - if (type == ICMP_SOURCE_QUENCH) - { /* Slow down! */ + if (type == ICMP_SOURCE_QUENCH) { +#if 0 /* FIXME: If you check the rest of the code, this is a NOP! + * Someone figure out what we were trying to be doing + * here. Besides, cong_window is a TCP thing and thus + * I moved it out of normal sock and into tcp_opt. + */ + /* Slow down! */ if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2; +#endif return; } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 95b320f0f..88920bb73 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -7,7 +7,7 @@ * * Based on linux/net/ipv4/ip_sockglue.c * - * $Id: ipv6_sockglue.c,v 1.10 1997/04/15 09:06:33 davem Exp $ + * $Id: ipv6_sockglue.c,v 1.11 1997/04/20 09:44:33 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -53,7 +53,7 @@ struct ipv6_mib ipv6_statistics={0, }; struct packet_type ipv6_packet_type = { - 0, + __constant_htons(ETH_P_IPV6), NULL, /* All devices */ ipv6_rcv, NULL, @@ -241,8 +241,6 @@ extern void ipv6_sysctl_unregister(void); void ipv6_init(void) { - ipv6_packet_type.type = ntohs(ETH_P_IPV6); - dev_add_pack(&ipv6_packet_type); #if defined(MODULE) && defined(CONFIG_SYSCTL) diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 9064baa9f..b9b811e35 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -7,7 +7,7 @@ * PROC file system. This is very similar to the IPv4 version, * except it reports the sockets in the INET6 address family. * - * Version: $Id: proc.c,v 1.2 1997/04/12 04:32:55 davem Exp $ + * Version: $Id: proc.c,v 1.4 1997/04/20 22:50:44 schenk Exp $ * * Authors: David S. Miller (davem@caip.rutgers.edu) * @@ -61,15 +61,15 @@ static int get__netinfo6(struct proto *pro, char *buffer, int format, char **sta destp = ntohs(sp->dummy_th.dest); srcp = ntohs(sp->dummy_th.source); - timer_active1 = del_timer(&sp->retransmit_timer); + timer_active1 = del_timer(&tp->retransmit_timer); timer_active2 = del_timer(&sp->timer); - if(!timer_active1) sp->retransmit_timer.expires = 0; + if(!timer_active1) tp->retransmit_timer.expires = 0; if(!timer_active2) sp->timer.expires = 0; timer_active = 0; timer_expires = (unsigned) -1; - if(timer_active1 && sp->retransmit_timer.expires < timer_expires) { + if(timer_active1 && tp->retransmit_timer.expires < timer_expires) { timer_active = timer_active1; - timer_expires = sp->retransmit_timer.expires; + timer_expires = tp->retransmit_timer.expires; } if(timer_active2 && sp->timer.expires < timer_expires) { timer_active = timer_active2; @@ -86,12 +86,12 @@ static int get__netinfo6(struct proto *pro, char *buffer, int format, char **sta format==0?sp->write_seq-tp->snd_una:atomic_read(&sp->wmem_alloc), format==0?tp->rcv_nxt-sp->copied_seq:atomic_read(&sp->rmem_alloc), timer_active, timer_expires-jiffies, - (unsigned) atomic_read(&sp->retransmits), + tp->retransmits, sp->socket ? sp->socket->inode->i_uid:0, timer_active?sp->timeout:0, sp->socket ? sp->socket->inode->i_ino:0); - if(timer_active1) add_timer(&sp->retransmit_timer); + if(timer_active1) add_timer(&tp->retransmit_timer); if(timer_active2) add_timer(&sp->timer); len += sprintf(buffer+len, "%-148s\n", tmpbuf); if(len >= length) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 21a874ee3..5151013a7 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: tcp_ipv6.c,v 1.21 1997/04/16 09:19:01 davem Exp $ + * $Id: tcp_ipv6.c,v 1.27 1997/04/22 02:53:20 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -41,6 +41,10 @@ #include +extern int sysctl_tcp_sack; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; + static void tcp_v6_send_reset(struct in6_addr *saddr, struct in6_addr *daddr, struct tcphdr *th, struct proto *prot, @@ -65,7 +69,8 @@ static __inline__ int tcp_v6_hashfn(struct in6_addr *laddr, u16 lport, hashent ^= (laddr->s6_addr32[0] ^ laddr->s6_addr32[1]); hashent ^= (faddr->s6_addr32[0] ^ faddr->s6_addr32[1]); - return (hashent & (TCP_HTABLE_SIZE - 1)); + hashent ^= (faddr->s6_addr32[2] ^ faddr->s6_addr32[3]); + return (hashent & ((TCP_HTABLE_SIZE/2) - 1)); } static __inline__ int tcp_v6_sk_hashfn(struct sock *sk) @@ -166,11 +171,14 @@ static void tcp_v6_rehash(struct sock *sk) if(state != TCP_CLOSE) { struct sock **skp; - if(state == TCP_LISTEN) + if(state == TCP_LISTEN) { skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; - else - skp = &tcp_established_hash[tcp_v6_sk_hashfn(sk)]; - + } else { + int hash = tcp_v6_sk_hashfn(sk); + if(state == TCP_TIME_WAIT) + hash += (TCP_HTABLE_SIZE/2); + skp = &tcp_established_hash[hash]; + } if((sk->next = *skp) != NULL) (*skp)->pprev = &sk->next; *skp = sk; @@ -180,11 +188,12 @@ static void tcp_v6_rehash(struct sock *sk) SOCKHASH_UNLOCK(); } -static struct sock *tcp_v6_lookup_longway(struct in6_addr *daddr, unsigned short hnum) +static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned short hnum) { - struct sock *sk = tcp_listening_hash[tcp_lhashfn(hnum)]; + struct sock *sk; struct sock *result = NULL; + sk = tcp_listening_hash[tcp_lhashfn(hnum)]; for(; sk; sk = sk->next) { if((sk->num == hnum) && (sk->family == AF_INET6)) { struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; @@ -207,13 +216,13 @@ static inline struct sock *__tcp_v6_lookup(struct tcphdr *th, { unsigned short hnum = ntohs(dport); struct sock *sk; + int hash = tcp_v6_hashfn(daddr, hnum, saddr, sport); /* Optimize here for direct hit, only listening connections can * have wildcards anyways. It is assumed that this code only * gets called from within NET_BH. */ - sk = tcp_established_hash[tcp_v6_hashfn(daddr, hnum, saddr, sport)]; - for(; sk; sk = sk->next) + for(sk = tcp_established_hash[hash]; sk; sk = sk->next) /* For IPV6 do the cheaper port and family tests first. */ if(sk->num == hnum && /* local port */ sk->family == AF_INET6 && /* address family */ @@ -221,7 +230,17 @@ static inline struct sock *__tcp_v6_lookup(struct tcphdr *th, !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.daddr, saddr) && !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr, daddr)) goto hit; /* You sunk my battleship! */ - sk = tcp_v6_lookup_longway(daddr, hnum); + + /* Must check for a TIME_WAIT'er before going to listener hash. */ + for(sk = tcp_established_hash[hash+(TCP_HTABLE_SIZE/2)]; sk; sk = sk->next) + if(sk->num == hnum && /* local port */ + sk->family == AF_INET6 && /* address family */ + sk->dummy_th.dest == sport && /* remote port */ + !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.daddr, saddr) && + !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr, daddr)) + goto hit; + + sk = tcp_v6_lookup_listener(daddr, hnum); hit: return sk; } @@ -267,7 +286,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct tcphdr *th; struct sk_buff *buff; struct sk_buff *skb1; - __u8 *ptr; + int tmp; int addr_type; if (sk->state != TCP_CLOSE) @@ -369,6 +388,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ipv6_addr_copy(&np->saddr, saddr); } + /* FIXME: Need to do tcp_v6_unique_address() here! -DaveM */ + /* * Init variables */ @@ -413,9 +434,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, th->ack = 0; th->window = 2; th->syn = 1; - th->doff = 6; - sk->window_clamp = 0; + tp->window_clamp = 0; sk->mtu = dst->pmtu; sk->mss = sk->mtu - sizeof(struct ipv6hdr) - sizeof(struct tcphdr); @@ -424,14 +444,12 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, * Put in the TCP options to say MTU. */ - ptr = skb_put(buff,4); - ptr[0] = 2; - ptr[1] = 4; - ptr[2] = (sk->mss) >> 8; - ptr[3] = (sk->mss) & 0xff; - buff->csum = csum_partial(ptr, 4, 0); - - tcp_v6_send_check(sk, th, sizeof(struct tcphdr) + 4, buff); + tmp = tcp_syn_build_options(buff, sk->mss, sysctl_tcp_sack, + sysctl_tcp_timestamps, + sysctl_tcp_window_scaling?tp->rcv_wscale:0); + th->doff = sizeof(*th)/4 + (tmp>>2); + buff->csum = 0; + tcp_v6_send_check(sk, th, sizeof(struct tcphdr) + tmp, buff); tcp_set_state(sk, TCP_SYN_SENT); @@ -445,10 +463,10 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, tcp_init_xmit_timers(sk); - atomic_set(&sk->retransmits, 0); + tp->retransmits = 0; skb_queue_tail(&sk->write_queue, buff); - sk->packets_out++; + tp->packets_out++; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); skb_set_owner_w(skb1, sk); @@ -573,9 +591,9 @@ static void tcp_v6_send_synack(struct sock *sk, struct open_request *req) struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; struct sk_buff * skb; struct tcphdr *th; - unsigned char *ptr; struct dst_entry *dst; struct flowi fl; + int tmp; skb = sock_wmalloc(sk, MAX_SYN_SIZE, 1, GFP_ATOMIC); if (skb == NULL) @@ -615,17 +633,12 @@ static void tcp_v6_send_synack(struct sock *sk, struct open_request *req) th->window = ntohs(tp->rcv_wnd); - /* FIXME: csum_partial() of a four byte quantity is itself! -DaveM */ - ptr = skb_put(skb, TCPOLEN_MSS); - ptr[0] = TCPOPT_MSS; - ptr[1] = TCPOLEN_MSS; - ptr[2] = (dst->pmtu >> 8) & 0xff; - ptr[3] = dst->pmtu & 0xff; - skb->csum = csum_partial(ptr, TCPOLEN_MSS, 0); - - th->check = tcp_v6_check(th, sizeof(*th) + TCPOLEN_MSS, + tmp = tcp_syn_build_options(skb, sk->mss, req->sack_ok, req->tstamp_ok, + (req->snd_wscale)?tp->rcv_wscale:0); + th->doff = sizeof(*th)/4 + (tmp>>2); + th->check = tcp_v6_check(th, sizeof(*th) + tmp, &req->af.v6_req.loc_addr, &req->af.v6_req.rmt_addr, - csum_partial((char *)th, sizeof(*th), skb->csum)); + csum_partial((char *)th, sizeof(*th)+tmp, skb->csum)); ip6_dst_store(sk, dst); ip6_xmit(sk, skb, &fl, req->af.v6_req.opt); @@ -646,6 +659,7 @@ static struct or_calltable or_ipv6 = { static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 isn) { + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; struct open_request *req; __u16 req_mss; @@ -680,7 +694,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, req->rcv_isn = skb->seq; req->snt_isn = isn; - req_mss = tcp_parse_options(skb->h.th); + tcp_parse_options(skb->h.th,tp); + req_mss = tp->in_mss; if (!req_mss) req_mss = 536; req->mss = req_mss; @@ -714,7 +729,7 @@ static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, th->check = 0; th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, - csum_partial((char *)th, sizeof(*th), + csum_partial((char *)th, th->doff<<2, skb->csum)); } @@ -773,8 +788,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, * Unused */ - newsk->send_head = NULL; - newtp = &(newsk->tp_pinfo.af_tcp); np = &newsk->net_pinfo.af_inet6; @@ -787,13 +800,13 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk->prot->init(newsk); - newsk->cong_count = 0; - newsk->ssthresh = 0; + newtp->snd_cwnd_cnt = 0; +#if 0 /* Don't mess up the initialization we did in the init routine! */ + newtp->snd_ssthresh = 0; +#endif newtp->backoff = 0; - newsk->intr = 0; newsk->proc = 0; newsk->done = 0; - newsk->partial = NULL; newsk->pair = NULL; atomic_set(&newsk->wmem_alloc, 0); atomic_set(&newsk->rmem_alloc, 0); @@ -805,24 +818,23 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk->shutdown = 0; newsk->ack_backlog = 0; - newsk->fin_seq = req->rcv_isn; + newtp->fin_seq = req->rcv_isn; newsk->syn_seq = req->rcv_isn; newsk->state = TCP_SYN_RECV; newsk->timeout = 0; - newsk->ip_xmit_timeout = 0; newsk->write_seq = req->snt_isn; newtp->snd_wnd = ntohs(skb->h.th->window); - newsk->max_window = newtp->snd_wnd; + newtp->max_window = newtp->snd_wnd; newtp->snd_wl1 = req->rcv_isn; newtp->snd_wl2 = newsk->write_seq; newtp->snd_una = newsk->write_seq++; newtp->snd_nxt = newsk->write_seq; newsk->urg_data = 0; - newsk->packets_out = 0; - atomic_set(&newsk->retransmits, 0); + newtp->packets_out = 0; + newtp->retransmits = 0; newsk->linger=0; newsk->destroy = 0; init_timer(&newsk->timer); @@ -861,13 +873,25 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, ip6_dst_store(newsk, dst); + newtp->sack_ok = req->sack_ok; + newtp->tstamp_ok = req->tstamp_ok; + newtp->snd_wscale = req->snd_wscale; + newtp->ts_recent = req->ts_recent; + if (newtp->tstamp_ok) { + newtp->tcp_header_len = sizeof(struct tcphdr) + 12; /* FIXME: define the contant. */ + newsk->dummy_th.doff += 3; + } else { + newtp->tcp_header_len = sizeof(struct tcphdr); + } + if (dst->error) newsk->mtu = req->af.v6_req.dev->mtu; else newsk->mtu = dst->pmtu; - newsk->mss = min(req->mss, (newsk->mtu - sizeof(struct ipv6hdr) - - sizeof(struct tcphdr))); + newsk->mss = min(req->mss+sizeof(struct tcphdr)-newtp->tcp_header_len, + (newsk->mtu - sizeof(struct ipv6hdr) - newtp->tcp_header_len)); + /* XXX tp->window_clamp??? -DaveM */ newsk->daddr = LOOPBACK4_IPV6; newsk->saddr = LOOPBACK4_IPV6; @@ -957,7 +981,7 @@ struct sock *tcp_v6_check_req(struct sock *sk, struct sk_buff *skb) if (!req) return sk; - do { + while(req) { if (!ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr) && !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr) && req->rmt_port == skb->h.th->source) { @@ -994,7 +1018,8 @@ struct sock *tcp_v6_check_req(struct sock *sk, struct sk_buff *skb) req->sk = sk; break; } - } while ((req = req->dl_next) != tp->syn_wait_queue); + req = req->dl_next; + } return sk; } @@ -1057,7 +1082,6 @@ int tcp_v6_rcv(struct sk_buff *skb, struct device *dev, skb->end_seq = skb->seq + th->syn + th->fin + len - th->doff*4; skb->ack_seq = ntohl(th->ack_seq); - skb->acked = 0; skb->used = 0; } @@ -1286,7 +1310,7 @@ static int tcp_v6_init_sock(struct sock *sk) /* start with only sending one packet at a time. */ tp->snd_cwnd = 1; - sk->ssthresh = 0x7fffffff; + tp->snd_ssthresh = 0x7fffffff; sk->priority = 1; sk->state = TCP_CLOSE; @@ -1306,6 +1330,10 @@ static int tcp_v6_init_sock(struct sock *sk) sk->dummy_th.ack=1; sk->dummy_th.doff=sizeof(struct tcphdr)>>2; + /* Init SYN queue. */ + tp->syn_wait_queue = NULL; + tp->syn_wait_last = &tp->syn_wait_queue; + sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific; return 0; @@ -1325,19 +1353,15 @@ static int tcp_v6_destroy_sock(struct sock *sk) * Cleanup up the write buffer. */ - while((skb = skb_dequeue(&sk->write_queue)) != NULL) { - IS_SKB(skb); + while((skb = skb_dequeue(&sk->write_queue)) != NULL) kfree_skb(skb, FREE_WRITE); - } /* * Cleans up our, hopefuly empty, out_of_order_queue */ - while((skb = skb_dequeue(&sk->out_of_order_queue)) != NULL) { - IS_SKB(skb); + while((skb = skb_dequeue(&sk->out_of_order_queue)) != NULL) kfree_skb(skb, FREE_READ); - } /* * Release destination entry -- 2.11.4.GIT