]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.36 2.1.36
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:08 +0000 (15:13 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:08 +0000 (15:13 -0500)
242 files changed:
Documentation/Configure.help
arch/alpha/Makefile
arch/alpha/kernel/entry.S
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/signal.c
arch/alpha/kernel/traps.c
arch/alpha/mm/init.c
arch/alpha/vmlinux.lds
arch/i386/kernel/entry.S
arch/i386/kernel/head.S
arch/i386/mm/init.c
arch/m68k/amiga/retz3fb.c [new file with mode: 0644]
arch/m68k/amiga/retz3fb.h [new file with mode: 0644]
arch/m68k/kernel/entry.S
arch/sparc/kernel/irq.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/systbls.S
arch/sparc/kernel/time.c
arch/sparc/lib/Makefile
arch/sparc/lib/checksum.S
arch/sparc/lib/irqlock.S [new file with mode: 0644]
arch/sparc/lib/locks.S
arch/sparc/mm/Makefile
arch/sparc/mm/hypersparc.S
arch/sparc/mm/init.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/viking.S [new file with mode: 0644]
arch/sparc64/config.in
arch/sparc64/defconfig
arch/sparc64/kernel/Makefile
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/sparc64/lib/checksum.S
arch/sparc64/mm/init.c
drivers/block/Config.in
drivers/block/ide.c
drivers/block/triton.c
drivers/char/amigamouse.c
drivers/char/apm_bios.c
drivers/char/atarimouse.c
drivers/char/atixlmouse.c
drivers/char/busmouse.c
drivers/char/cyclades.c
drivers/char/digi_bios.h
drivers/char/digi_fep.h
drivers/char/dsp56k.c [new file with mode: 0644]
drivers/char/esp.c
drivers/char/istallion.c
drivers/char/keyb_m68k.c
drivers/char/keyboard.c
drivers/char/lp.c
drivers/char/misc.c
drivers/char/msbusmouse.c
drivers/char/pcwd.c
drivers/char/pcxx.c
drivers/char/psaux.c
drivers/char/pty.c
drivers/char/random.c
drivers/char/riscom8.c
drivers/char/rtc.c
drivers/char/serial.c
drivers/char/softdog.c
drivers/char/stallion.c
drivers/char/tty_io.c
drivers/char/vc_screen.c
drivers/char/wdt.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c523.c
drivers/net/3c59x.c
drivers/net/8390.c
drivers/net/a2065.c
drivers/net/ac3200.c
drivers/net/apricot.c
drivers/net/arcnet.c
drivers/net/ariadne.c
drivers/net/at1700.c
drivers/net/atari_bionet.c
drivers/net/atari_pamsnet.c
drivers/net/atarilance.c
drivers/net/atp.c
drivers/net/baycom.c
drivers/net/bpqether.c
drivers/net/cs89x0.c
drivers/net/de4x5.c
drivers/net/de600.c
drivers/net/de620.c
drivers/net/defxx.c
drivers/net/depca.c
drivers/net/dgrs.c
drivers/net/dgrs_firmware.c
drivers/net/dlci.c
drivers/net/dummy.c
drivers/net/e2100.c
drivers/net/eepro.c
drivers/net/eepro100.c
drivers/net/eql.c
drivers/net/es3210.c
drivers/net/eth16i.c
drivers/net/ewrk3.c
drivers/net/fmv18x.c
drivers/net/hdlcdrv.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/hp100.c
drivers/net/hydra.c
drivers/net/ibmtr.c
drivers/net/lance.c
drivers/net/lapbether.c
drivers/net/loopback.c
drivers/net/ltpc.c
drivers/net/mkiss.c
drivers/net/ne.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/pcnet32.c
drivers/net/pi2.c
drivers/net/plip.c
drivers/net/ppp.c
drivers/net/pt.c
drivers/net/scc.c
drivers/net/sdla.c
drivers/net/sdla_fr.c
drivers/net/sdla_ppp.c
drivers/net/sdla_x25.c
drivers/net/sdladrv.c
drivers/net/seeq8005.c
drivers/net/shaper.c
drivers/net/slhc.c
drivers/net/slip.c
drivers/net/smc-mca.c
drivers/net/smc-ultra.c
drivers/net/smc9194.c
drivers/net/tulip.c
drivers/net/tunnel.c
drivers/net/wd.c
drivers/net/x25_asy.c
drivers/net/znet.c
drivers/pci/pci.c
drivers/pnp/parport_init.c
drivers/sbus/char/creator.c [new file with mode: 0644]
drivers/sbus/char/linux_logo.h [deleted file]
drivers/sbus/char/sunkbd.c
drivers/scsi/53c7,8xx.c
drivers/scsi/AM53C974.c
drivers/scsi/BusLogic.c
drivers/scsi/NCR5380.c
drivers/scsi/NCR53c406a.c
drivers/scsi/advansys.c
drivers/scsi/aic7xxx.c
drivers/scsi/dtc.c
drivers/scsi/g_NCR5380.c
drivers/scsi/hosts.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/ncr53c8xx.h
drivers/scsi/pas16.c
drivers/scsi/scsi.c
drivers/scsi/t128.c
fs/binfmt_em86.c
fs/buffer.c
fs/dcache.c
fs/filesystems.c
fs/inode.c
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
include/asm-alpha/init.h
include/asm-alpha/processor.h
include/asm-alpha/softirq.h
include/asm-alpha/spinlock.h
include/asm-alpha/sysinfo.h [new file with mode: 0644]
include/asm-i386/pgtable.h
include/asm-i386/softirq.h
include/asm-i386/spinlock.h
include/asm-m68k/dsp56k.h [new file with mode: 0644]
include/asm-m68k/fpu.h [new file with mode: 0644]
include/asm-m68k/hardirq.h [new file with mode: 0644]
include/asm-m68k/namei.h [new file with mode: 0644]
include/asm-m68k/poll.h [new file with mode: 0644]
include/asm-m68k/smp_lock.h [new file with mode: 0644]
include/asm-m68k/softirq.h [new file with mode: 0644]
include/asm-m68k/spinlock.h [new file with mode: 0644]
include/asm-m68k/zorro.h [deleted file]
include/asm-sparc/hardirq.h
include/asm-sparc/irq.h
include/asm-sparc/linux_logo.h [new file with mode: 0644]
include/asm-sparc/mxcc.h
include/asm-sparc/smp_lock.h
include/asm-sparc/softirq.h
include/asm-sparc/spinlock.h
include/asm-sparc/system.h
include/asm-sparc/viking.h
include/asm-sparc64/linux_logo.h [new file with mode: 0644]
include/asm-sparc64/signal.h
include/asm-sparc64/softirq.h
include/asm-sparc64/spinlock.h
include/asm-sparc64/stat.h
include/asm-sparc64/unistd.h
include/linux/fs.h
include/linux/mm.h
include/linux/pagemap.h
include/linux/pci.h
include/linux/skbuff.h
include/linux/sysctl.h
include/linux/vmalloc.h
include/linux/zorro.h [new file with mode: 0644]
include/net/sock.h
include/net/tcp.h
init/main.c
kernel/exit.c
kernel/fork.c
kernel/info.c
kernel/itimer.c
kernel/ksyms.c
kernel/sched.c
kernel/signal.c
kernel/sys.c
kernel/time.c
mm/page_alloc.c
mm/swap.c
net/bridge/br.c
net/core/dev.c
net/core/net_alias.c
net/core/skbuff.c
net/core/sock.c
net/ethernet/eth.c
net/ipv4/icmp.c
net/ipv4/ip_fragment.c
net/ipv4/ip_sockglue.c
net/ipv4/proc.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv6/ipv6_sockglue.c
net/ipv6/proc.c
net/ipv6/tcp_ipv6.c

index f77cb06759a3aebae6ca7f590a665207f7cd209c..469fb2e020c358a2c3ea2676b40bab5c87bcf63f 100644 (file)
@@ -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
index a79a5056ea1263a901b46333f8f48eccf492becf..58fd5335462f4114f68ac169a228546ca926071d 100644 (file)
 
 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
 
index 5926dd25c242eedced1cc1a8c44a5ba58d8be50d..ef582b80e74a852d7f70fa5ce0a32e317d274d70 100644 (file)
@@ -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
index e2f9bf4c972d7cf78722114ab86f72aa476b9333..ef95764926cb4d5237413a778947d0457eff1963 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/sysinfo.h>
 
 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;
 }
index 38b32b203cca4046629ec36962609981c52c4b05..5c3eb79ef2cf0f529da598f47536db9c4bf77bd0 100644 (file)
@@ -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(&current->sigmask_lock);
        oldmask = current->blocked;
        current->blocked = mask & _BLOCKABLE;
+       spin_unlock_irq(&current->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 */
index eb4ce5cbd745115592f4a0e21848bff80165d288..02fa5a35d09072b7952bc22c39ac09c67f6de784 100644 (file)
@@ -16,6 +16,9 @@
 #include <asm/gentrap.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
+#include <asm/sysinfo.h>
+#include <asm/smp_lock.h>
+
 
 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", &regs, 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", &regs, 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();
+
                (&regs)->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("<sc %ld(%lx,%lx,%lx)>", 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);
index 35a325ffce4910968aee2b93985ff0cd600070f0..13e8e4ce4e85397f04c1f4c53593e3245e66648e 100644 (file)
@@ -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)
index f29ecfe1b73c23d2967f7e0971350c3c9533ddbc..2a5f00989718df998afca22ceb5bd4ea66f10f58 100644 (file)
@@ -1,50 +1,46 @@
-OUTPUT_FORMAT("ecoff-littlealpha")
+OUTPUT_FORMAT("elf64-alpha")
 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 = .;
+   . = 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) }
 }
index 9473705e64efdd06019833e8759c1e907c707606..84fe0c7fde6655c45ff4304821deec782ada8111 100644 (file)
@@ -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
index fc06be2b81d1ae6ec4d14ab4dad8052e1a11bdce..2bd095997eed7a883693c536f46b3220aa60d87d 100644 (file)
@@ -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 */
index 8ff11393a1fcefa96d0ccf88d0237914a24a176d..1736493382ac2ce565d33bb17dd7d92e3e211f59 100644 (file)
@@ -27,6 +27,8 @@
 #include <asm/pgtable.h>
 #include <asm/dma.h>
 
+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 (file)
index 0000000..4885e48
--- /dev/null
@@ -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 <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <linux/zorro.h>
+#include <asm/pgtable.h>
+
+#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, &current_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<<disp[con].var.bits_per_pixel, 0)))
+                       return err;
+       }
+       if (con == currcon)              /* current console? */
+               return(do_fb_set_cmap(cmap, &disp[con].var, kspc));
+       else
+               copy_cmap(cmap, &disp[con].cmap, kspc ? 0 : 1);
+       return 0;
+}
+
+
+/*
+ *    Pan or Wrap the Display
+ *
+ *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+
+static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con)
+{
+       return -EINVAL;
+}
+
+
+/*
+ *    RetinaZ3 Frame Buffer Specific ioctls
+ */
+
+static int retz3_fb_ioctl(struct inode *inode, struct file *file,
+                          unsigned int cmd, unsigned long arg, int con)
+{
+       return -EINVAL;
+}
+
+
+static struct fb_ops retz3_fb_ops = {
+   retz3_fb_get_fix, retz3_fb_get_var, retz3_fb_set_var, retz3_fb_get_cmap,
+   retz3_fb_set_cmap, retz3_fb_pan_display, retz3_fb_ioctl
+};
+
+
+int retz3_probe(void)
+{
+       z3_key = zorro_find(MANUF_MACROSYSTEMS2, PROD_RETINA_Z3, 0, 0);
+       return(z3_key);
+}
+
+
+void retz3_video_setup(char *options, int *ints)
+{
+       char *this_opt;
+       int i;
+
+       fb_info.fontname[0] = '\0';
+
+       if (!options || !*options)
+               return;
+
+       for (this_opt = strtok(options, ","); this_opt; 
+            this_opt = strtok(NULL, ",")){
+               if (!strcmp(this_opt, "inverse")) {
+                       z3fb_inverse = 1;
+                       for (i = 0; i < 16; i++) {
+                               red16[i] = ~red16[i];
+                               green16[i] = ~green16[i];
+                               blue16[i] = ~blue16[i];
+                       }
+               } else if (!strncmp(this_opt, "font:", 5))
+                       strcpy(fb_info.fontname, this_opt+5);
+               else
+                       z3fb_mode = get_video_mode(this_opt);
+       }
+}
+
+
+/*
+ *    Initialization
+ */
+
+struct fb_info *retz3_fb_init(long *mem_start)
+{
+       int err;
+       struct retz3_fb_par par;
+
+       memstart = mem_start;
+
+       fbhw = &retz3_switch;
+
+       err = register_framebuffer(retz3_fb_name, &node, &retz3_fb_ops,
+                                  NUM_TOTAL_MODES, retz3_fb_predefined);
+       if (err < 0)
+               panic("Cannot register frame buffer\n");
+
+       fbhw->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 <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <linux/zorro.h>
+#include <asm/pgtable.h>
+
+#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, &current_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<<disp[con].var.bits_per_pixel, 0)))
+                       return err;
+       }
+       if (con == currcon)              /* current console? */
+               return(do_fb_set_cmap(cmap, &disp[con].var, kspc));
+       else
+               copy_cmap(cmap, &disp[con].cmap, kspc ? 0 : 1);
+       return 0;
+}
+
+
+/*
+ *    Pan or Wrap the Display
+ *
+ *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+
+static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con)
+{
+       return -EINVAL;
+}
+
+
+/*
+ *    RetinaZ3 Frame Buffer Specific ioctls
+ */
+
+static int retz3_fb_ioctl(struct inode *inode, struct file *file,
+                          unsigned int cmd, unsigned long arg, int con)
+{
+       return -EINVAL;
+}
+
+
+static struct fb_ops retz3_fb_ops = {
+   retz3_fb_get_fix, retz3_fb_get_var, retz3_fb_set_var, retz3_fb_get_cmap,
+   retz3_fb_set_cmap, retz3_fb_pan_display, retz3_fb_ioctl
+};
+
+
+int retz3_probe(void)
+{
+       z3_key = zorro_find(MANUF_MACROSYSTEMS2, PROD_RETINA_Z3, 0, 0);
+       return(z3_key);
+}
+
+
+void retz3_video_setup(char *options, int *ints)
+{
+       char *this_opt;
+       int i;
+
+       fb_info.fontname[0] = '\0';
+
+       if (!options || !*options)
+               return;
+
+       for (this_opt = strtok(options, ","); this_opt; 
+            this_opt = strtok(NULL, ",")){
+               if (!strcmp(this_opt, "inverse")) {
+                       z3fb_inverse = 1;
+                       for (i = 0; i < 16; i++) {
+                               red16[i] = ~red16[i];
+                               green16[i] = ~green16[i];
+                               blue16[i] = ~blue16[i];
+                       }
+               } else if (!strncmp(this_opt, "font:", 5))
+                       strcpy(fb_info.fontname, this_opt+5);
+               else
+                       z3fb_mode = get_video_mode(this_opt);
+       }
+}
+
+
+/*
+ *    Initialization
+ */
+
+struct fb_info *retz3_fb_init(long *mem_start)
+{
+       int err;
+       struct retz3_fb_par par;
+
+       memstart = mem_start;
+
+       fbhw = &retz3_switch;
+
+       err = register_framebuffer(retz3_fb_name, &node, &retz3_fb_ops,
+                                  NUM_TOTAL_MODES, retz3_fb_predefined);
+       if (err < 0)
+               panic("Cannot register frame buffer\n");
+
+       fbhw->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 (file)
index 0000000..9ff2090
--- /dev/null
@@ -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 */
index cdd88eb9b9262ca1b058e180da903b4c248cee85..2cb35e67f7ae50b4e1b61ff5f8ec595d934d7857 100644 (file)
@@ -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
index 7206a6e1405db6d8fab04436ce2d6c23527adfc3..70042857fce675da8a9bdf53140a6aed2f1c5452 100644 (file)
@@ -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
index 9a6ea3d6cced16a4a40f7b77fd6152ac8f395ecb..645aafb35009c92b03a5063fe08979353085d8ac 100644 (file)
@@ -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
 
index 6c68ccc5e2f581392bb463841b1ccc6346c0d37d..61b41056b027362ed12e5789a52990edc8a42bed 100644 (file)
@@ -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. */
index 526dd0f28a09c6a162b19175597749486450241b..77401391e1b8dd927521867d101f471c7ccfb499 100644 (file)
@@ -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
index a7a67b8b2ea456a597999fd27b07b52e319f8adb..1bf49bf13de00ec0e02b490417a86474ace27beb 100644 (file)
@@ -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
index 90362edc564c6a615effa5ad24859278e2f4a477..2f0c78168bf0c692ab0494e77d3e96ed8dca5cc3 100644 (file)
@@ -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 (file)
index 0000000..db7dd26
--- /dev/null
@@ -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 <asm/psr.h>
+#include <asm/smp.h>
+
+       .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
index 79667533f3d7ac343ba5227a8126214785b14e37..e91efdc09a00745f683e68befd829c492533048d 100644 (file)
@@ -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)
index 1d778e3fd52bf469b8b3468d89c51d30d727340d..4ae57f18f7444564505270f8041cfc1ae8bdf897 100644 (file)
@@ -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
index fe7dfdf4f0ea211c882d0b73e636a1157406ae41..4e5a19301f4c5d378df4e1ab36da07a01e7d4fcb 100644 (file)
@@ -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
index d94b1c44ac2ab0c84aeb475a1752a36973360abc..3dd0e470f5b2ea17933eb68c099248ffc0af8b8f 100644 (file)
@@ -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)
index 7f4824222502463741b44bfdf3cfcfc2dbd1e56a..9d3afdbdf679a9ba947c34530f5b44a17037bd37 100644 (file)
@@ -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 (file)
index 0000000..f61aa43
--- /dev/null
@@ -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 <asm/ptrace.h>
+#include <asm/psr.h>
+#include <asm/asi.h>
+#include <asm/mxcc.h>
+#include <asm/page.h>
+#include <asm/pgtsrmmu.h>
+#include <asm/viking.h>
+#include <asm/cprefix.h>
+
+#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
index 42ed2db62f338f17168eb392df0d583ca09733fa..c8cdc0134a12c801f2becacd5c615da11836d151 100644 (file)
@@ -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
index 87592dcbf21fa4fe74f60700d40cf399f61c341e..9ecbf90b40087f545e2f06827beed6b6d0c7eda0 100644 (file)
@@ -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
index d2ef7d6d8cccb0490f6c6ef86358490c58e4b42a..d66fa06e7f20284b05b5647e46d19f0a7159f1da 100644 (file)
@@ -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
index 07d8717241949a249fa91cb1657350e9d81f5135..e9911daed2035ac21a30b152690093726fe5dd00 100644 (file)
@@ -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 <linux/shm.h>
 #include <linux/malloc.h>
 #include <linux/uio.h>
+#include <linux/nfs_fs.h>
+#include <linux/smb_fs.h>
+#include <linux/ncp_fs.h>
 
 #include <asm/types.h>
 #include <asm/poll.h>
@@ -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;
+}
index 3afd28cc90765f613b53833794a4e9cbc989543c..8ff04f02a93ed255bf85c8696486da5c676d4c1a 100644 (file)
@@ -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. */
index 29aba94bed978dc0b3ac381d4edb6fde805f2077..8a06003ee613fb5da2a2fbc466e1406220e568f2 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/errno.h>
 #include <asm/head.h>
 #include <asm/ptrace.h>
+#include <asm/asi.h>
 
 #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
index 72d2774b5f9e4a3481dac01c645a3c4d68368f6a..57ca5eb92b0a82f91a4ca43f0a2696185878e9f5 100644 (file)
@@ -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)
index 56052e31352482015ca5259177d5732dc304003b..59486adaad860aba5d8184b178ba1fb6c772527a 100644 (file)
@@ -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
index e39a0c16a5b0ead2fd32af109c805dfc91a9d051..ca9456479d17926a667dee168e2b7a883c319d23 100644 (file)
@@ -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);
index 735147d15f827a1077f7f947ed3c12019e961201..7956307c86d07ff335119ac2bc366c4b728b69af 100644 (file)
@@ -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".
  *
  *
  * 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" <reimer@doe.carleton.ca> for fixing the
  * problem with some (all?) ACER motherboards/BIOSs.
  *
+ * Thanks to "Benoit Poulot-Cazajous" <poulot@chorus.fr> 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 <linux/types.h>
@@ -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);
index 5f2d88a251547fa07a3313364c09e060d5171e38..602695c392382beb657beed670cbadde64c2a45d 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/miscdevice.h>
 #include <linux/random.h>
 #include <linux/poll.h>
+#include <linux/init.h>
 
 #include <asm/setup.h>
 #include <asm/system.h>
@@ -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;
index 6fd3c16dca9b1aa84307e30f060ee74145fee18b..bf7a04633a56235f52917ee6e3dce53c0d42fd91 100644 (file)
@@ -73,6 +73,7 @@
 #endif
 #include <linux/miscdevice.h>
 #include <linux/apm_bios.h>
+#include <linux/init.h>
 
 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;
index 9c7405effe4ae1c124f79f4206abc04df1c17e0c..18debb66b3452dda1d4419ba6a827a10b330a388 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/random.h>
 #include <linux/poll.h>
+#include <linux/init.h>
 
 #include <asm/setup.h>
 #include <asm/atarikb.h>
@@ -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;
index 04382371a3899c44971465a998ee985e8c888113..c8a730a353055826fe849d60e60ba7f2f9b334c8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/miscdevice.h>
 #include <linux/random.h>
 #include <linux/poll.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -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;
 
index bae68d4ff1c3556a16b2e9cbd26aa13f333c30c3..d8b267095cd64a1210436447cc395606c5db54e2 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/random.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -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;
index 44b7c03ee770c2e1842f50a0784c3c4056b5edaa..0a1825ee8355409978c92be1f94753420ab4c668 100644 (file)
@@ -288,6 +288,7 @@ static char rcsid[] =
 #include <linux/kernel.h>
 #include <linux/bios32.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 
 #define small_delay(x) for(j=0;j<x;j++)k++;
 
@@ -2696,7 +2697,7 @@ cy_open(struct tty_struct *tty, struct file * filp)
  * number, and identifies which options were configured into this
  * driver.
  */
-static void
+static inline void
 show_version(void)
 {
     printk("Cyclom driver %s\n",rcsid);
@@ -2704,8 +2705,8 @@ show_version(void)
 
 /* initialize chips on card -- return number of valid
    chips (which is number of ports/4) */
-int
-cy_init_card(unsigned char *true_base_addr,int index)
+__initfunc(static int
+cy_init_card(unsigned char *true_base_addr,int index))
 {
   unsigned int chip_number;
   unsigned char* base_addr;
@@ -2785,8 +2786,8 @@ cy_init_card(unsigned char *true_base_addr,int index)
     If there are more cards with more ports than have been statically
     allocated above, a warning is printed and the extra ports are ignored.
  */
-int
-cy_init(void)
+__initfunc(int
+cy_init(void))
 {
   struct cyclades_port *info;
   struct cyclades_card *cinfo;
@@ -2941,13 +2942,17 @@ init_module(void)
 void
 cleanup_module(void)
 {
+    unsigned long flags;
     int i;
 
-
+    save_flags(flags);
+    cli();
+    remove_bh(CYCLADES_BH); 
     if (tty_unregister_driver(&cy_callout_driver))
            printk("Couldn't unregister Cyclom callout driver\n");
     if (tty_unregister_driver(&cy_serial_driver))
            printk("Couldn't unregister Cyclom serial driver\n");
+    restore_flags(flags);
 
     for (i = 0; i < NR_CARDS; i++) {
         if (cy_card[i].base_addr != 0)
@@ -2964,8 +2969,8 @@ cleanup_module(void)
  * sets global variables and return the number of ISA boards found.
  * ---------------------------------------------------------------------
  */
-int
-cy_detect_isa()
+__initfunc(int
+cy_detect_isa())
 {
   unsigned int         cy_isa_irq,nboard;
   unsigned char                *cy_isa_address;
@@ -3043,8 +3048,8 @@ cy_detect_isa()
  * sets global variables and return the number of PCI boards found.
  * ---------------------------------------------------------------------
  */
-int
-cy_detect_pci()
+__initfunc(int
+cy_detect_pci())
 {
 #ifdef CONFIG_PCI
   unsigned char                cyy_bus, cyy_dev_fn, cyy_rev_id;
index 496cbcaabe094b049e33dfeec3a1261e44df387a..93e4608bd722891df7d7f9ec9fa03af65c172c8f 100644 (file)
@@ -1,6 +1,6 @@
 /* DigiBoard PCXX Bios */
 
-static unsigned char pcxx_bios[] = {
+static unsigned char pcxx_bios[] __initdata = {
   0x28,0x43,0x29,0x20,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,
   0x74,0x20,0x31,0x39,0x39,0x34,0x2c,0x20,0x44,0x69,0x67,0x69,
   0x42,0x6f,0x61,0x72,0x64,0x20,0x49,0x6e,0x63,0x2e,0x00,0x00,
index 9abb75dd6329826662325dae8524c0f99ac38854..7a84759e812f3fc887b56340acbad1e59a1ee39d 100644 (file)
@@ -1,6 +1,6 @@
 /* DigiBoard PCXX Bios */
 
-static unsigned char pcxx_cook[] = {
+static unsigned char pcxx_cook[] __initdata = {
   0x4f,0x53,0x18,0x80,0xe9,0xbf,0x15,0x00,0x40,0x28,0x23,0x29,
   0x46,0x45,0x50,0x4f,0x53,0x20,0x37,0x2e,0x30,0x38,0x20,0x34,
   0x2f,0x32,0x30,0x2f,0x39,0x35,0x00,0x40,0x28,0x23,0x29,0x28,
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
new file mode 100644 (file)
index 0000000..dd035d5
--- /dev/null
@@ -0,0 +1,1150 @@
+/*
+ * The DSP56001 Device Driver, saviour of the Free World(tm)
+ *
+ * Authors: Fredrik Noring   <noring@lysator.liu.se>
+ *          lars brinkhoff   <f93labr@dd.chalmers.se>
+ *          Tomas Berndtsson <tobe@lysator.liu.se>
+ *
+ * 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/malloc.h>      /* for kmalloc() and kfree() */
+#include <linux/sched.h>       /* for struct wait_queue etc */
+#include <linux/major.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>       /* guess what */
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/atarihw.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>       /* For put_user and get_user */
+
+#include <asm/dsp56k.h>
+
+/* 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   <noring@lysator.liu.se>
+ *          lars brinkhoff   <f93labr@dd.chalmers.se>
+ *          Tomas Berndtsson <tobe@lysator.liu.se>
+ *
+ * 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/malloc.h>      /* for kmalloc() and kfree() */
+#include <linux/sched.h>       /* for struct wait_queue etc */
+#include <linux/major.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>       /* guess what */
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/atarihw.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>       /* For put_user and get_user */
+
+#include <asm/dsp56k.h>
+
+/* 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 */
index c6b6afce94b5bde3a13dccd446b7a5ae2173f554..c1eb47de0d6be2f75e5cb4ee4b323b87bcb0022c 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -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);
index 80caed3a0a5ce60ebf6ff357181a7a499ef0cb40..a0f2f10c5640b946c31d20a3247a7f9cca20a959 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/malloc.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -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);
 
index b9c5aa775a9404379b2d1ec9224abc2e8f3086ba..587d61a4b6ac7643dd8b2556b30fc8e20a290319 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/random.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/machdep.h>
@@ -848,7 +849,7 @@ static void kbd_bh(void)
        }
 }
 
-int kbd_init(void)
+__initfunc(int kbd_init(void))
 {
        int i;
        struct kbd_struct kbd0;
index 2c2414124a5c41f0104afdaffcd64e284d3ab398..54384d801369e42ba956cac2794ed79e0b244000 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/random.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 
@@ -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;
 
index dd8999244a47e014de14a00e62707a1fdf6715dd..7fd2f9b35a9bc16036bbce9f2977e2a2a2e5dfc9 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -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;
index ccd90a8be9351b2d99437dd3cea2d42fe0ff76fe..fd72f33d8447a4bd6c06eea5f9006e0464a2ede8 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/malloc.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/init.h>
 #ifdef CONFIG_APM
 #include <linux/apm_bios.h>
 #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
index 806e9a88e3fe0a8c8818bfe40413890abf51965d..b11730f70d561c0eb1cc646c0c8a225c96578d64 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/miscdevice.h>
 #include <linux/random.h>
 #include <linux/poll.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -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;
 
index 0eefd9a64b0323d5a455ee29f879de63051a1893..9a77783b366518dfa04febe1600e7ed015eb9f00 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/watchdog.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -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;
index 5cfcb589ddf7ce55c3e7d634aae538d097d4f3f2..c09c7dbbe0aaa082f64b06718c263c86b9a34f96 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/tty_driver.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 
 #ifndef MODULE
 #include <linux/ctype.h> /* 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;
index dcf38460d0c76dcd8f43d5333489f14119ccaac2..28239579c0124c18fdbbae1c0b0c9ed91057d521 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/miscdevice.h>
 #include <linux/random.h>
 #include <linux/poll.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -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 */
index 1b4532de5adb0a08b508c568409288a85e6cd0df..8f101539726ce5ec2a5638a7207ec4f74b064264 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/string.h>
 #include <linux/major.h>
 #include <linux/mm.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -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));
index 9620589904be42e56a39807017b85483ffa88b8a..3fb64b28d7aacf3cd9d2f14b7edd497966c60a21 100644 (file)
 #include <linux/malloc.h>
 #include <linux/random.h>
 #include <linux/poll.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -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;
index 1996ebeee69d283b6b7ece64a5adaf76163898d4..301babf81cdcdacbde824edf26cbbd7b9ea701a4 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/serial.h>
 #include <linux/fcntl.h>
 #include <linux/major.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 
@@ -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;
index bbe4d3cd966c2bc84dda44e2cba60ec591d34845..3235ebeaa7a36833c764e741296dfc162e41a814 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/mc146818rtc.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -531,7 +532,7 @@ static struct miscdevice rtc_dev=
        &rtc_fops
 };
 
-int rtc_init(void)
+__initfunc(int rtc_init(void))
 {
        unsigned long flags;
 
index 6c73a880bc635aa9931fb00ed64b2de4e7a29815..7c7d49ab3be9bf8b876207c390fc5782b85dd709 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -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);
index 7520137422659d4820f82df7b016337167fc41ac..d16227d83fa720b2a72b0af163d4f7e2dedee017 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/reboot.h>
+#include <linux/init.h>
 #include <asm/uaccess.h>
 
 #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);
index 9c2b5e984005ae16ee3979df7a04d351dfb3e44c..7ebb33c144e0fe4f01017589254e88c6d5b4253a 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/malloc.h>
 #include <linux/ioport.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -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);
 
index 86b441c4a07c6b976048bb4d6fb5f857755ed61e..0d0f0a4edb955c4dca2327cda87ecb0178beeecd 100644 (file)
@@ -71,6 +71,7 @@
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #endif
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -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!");
index 34b579e762ba6ef00402b44aa6dacadf64fc0be2..71f4e2f84d9c2992d54505a745d5fb1b9b4086ce 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
+#include <linux/init.h>
 #include <asm/uaccess.h>
 #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;
 
index 42a9ea2166a04e3b0c3adac463c758042cda99aa..e32131b6372a4047be68156cdcade3c8f08832b2 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <linux/init.h>
 
 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
index 9a29461b856b5dcd189a705b3509e9fd197bc368..d17ea2c93330ed2ea6a90adf0882885a06f49f8b 100644 (file)
@@ -102,12 +102,13 @@ static const char *version =
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 
 #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};
 
 \f
@@ -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];
index d0580f3b46556cafdc4944798344f35895a69dd9..aa69a74e6b56a024bb8a6621628755f26991fbf8 100644 (file)
@@ -42,6 +42,7 @@ static const char *version =
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -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;
index 49a11d4e956e08304d2aaf02a8decc48eeb00651..31a64990af0fd253e56c9736bd9e75db297d9440 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 
 #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;
index 819011b9fec9dbf70af49bbc3c2a3f5ef09ebd86..00038f96d1231f400dcf344b68a4716d68da36a8 100644 (file)
@@ -59,6 +59,7 @@ static const char *version =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/malloc.h>
+#include <linux/init.h>
 
 
 /* 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;
index 48208e26abccdfdaa007535d843f4aef5960981c..d3d941d20d940dbd985938a527eab1fcf1786fdf 100644 (file)
@@ -48,6 +48,7 @@ static char *version = "3c509.c:1.07 6/15/95 becker@cesdis.gsfc.nasa.gov\n";
 #include <linux/skbuff.h>
 #include <linux/config.h>      /* for CONFIG_MCA */
 #include <linux/delay.h>       /* for udelay() */
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -132,7 +133,7 @@ static void set_multicast_list(struct device *dev);
 
 \f
 
-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;
 
index 5fb047f3cf024106739b34cf27d63b80b0402c12..63c6240d314a0968fb4a426702d31f263d30bed8 100644 (file)
@@ -100,6 +100,7 @@ History:
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 
 #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;
index f66f30d1bb5f5f9512bdbcf36325a647f4aea739..69464b4e901735a120837a6b014831760427f496 100644 (file)
@@ -36,6 +36,7 @@ static char *version = "3c59x.c:v0.25 5/17/96 becker@cesdis.gsfc.nasa.gov\n";
 #include <linux/ioport.h>
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
+#include <linux/init.h>
 
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
@@ -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;
index c51f13074c993da1702ec4577a30e2ea34c14899..fbf67cb423b51f9b9b97a774eecdde7be8a4b666 100644 (file)
@@ -58,6 +58,7 @@ static const char *version =
 #include <linux/fcntl.h>
 #include <linux/in.h>
 #include <linux/interrupt.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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);
index 414afff85b1b1e16c082983b962509e1c2266647..b62102e7afa943dcc5faa58c63be55d2b30b69ff 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/malloc.h>
 #include <linux/string.h>
 #include <linux/config.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
index f70570ddf44d4159251b65dcdbf1246a3b27be3c..63af6498be2d619e6bd7381250eaa53721cf2ff0 100644 (file)
@@ -25,6 +25,7 @@ static const char *version =
 #include <linux/string.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -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;
 
index b839ae26fc8525415b6bc036cef4be94d2910c08..2a00c44818da19729cf8528523d772665fa19c28 100644 (file)
@@ -34,6 +34,7 @@ static const char *version = "apricot.c:v0.2 05/12/94\n";
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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
index cc5faa093b411540ea2d464309cce8a43433fed6..b25dd02c26bdd42a81a7adaaaf911e21a27905a5 100644 (file)
@@ -162,6 +162,7 @@ static const char *version =
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -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;
index 5dbd2985a76a6cc7da5889e6aaeee9a4c006c463..290b9761e4dd6064cb4f9d6c97de6f92f8a145d8 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/amigaints.h>
@@ -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;
index bd160c876cca267fc84e68a6056e6b3747cf8497..bd1f93846e33a2cd8cfd1165530774be007f5f88 100644 (file)
@@ -48,13 +48,14 @@ static const char *version =
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
 /* 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;
index f0b781bcf4875b463bbea150112f49147b76c7e1..dc761ab7cd93e7a8768d5093e33dbe90033079ec 100644 (file)
@@ -95,6 +95,7 @@ static char *version =
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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 */
index 72056f1b3197232f4bb7e91cafbac1cf019c39f2..bcf91beda56e0a64882b356ad646b17e8b5c0b01 100644 (file)
@@ -102,6 +102,7 @@ static char *version =
 
 #include <linux/delay.h>
 #include <linux/timer.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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;
index 9b8f4d45c1bee6e8e52098359ecc526bbb2a8b7e..bb08b8927ca4f655a0847b016d1e61ad5bee7058 100644 (file)
@@ -55,6 +55,7 @@ static char *version = "atarilance.c: v1.3 04/04/96 "
 #include <linux/errno.h>
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
+#include <linux/init.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -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;
index 4fdbed39dbba151e1e33d9347c65032dc05b1a84..41137411918a55037ddc7b798b7386f353a5e25f 100644 (file)
@@ -96,6 +96,7 @@ static const char *version =
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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;
index 5506c17509a110b63ccdb13943ab36fb913150dd..7569d66e736058dc60150de9eb00723b0fc35d52 100644 (file)
@@ -89,6 +89,7 @@
 #include <linux/netdevice.h>
 #include <linux/hdlcdrv.h>
 #include <linux/baycom.h>
+#include <linux/init.h>
 
 /* --------------------------------------------------------------------- */
 
@@ -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;
 
index 11e073a234b4c73386966588bb6f91f8873aab91..ca1bcc9c73a11f4920e3de133be82f8224491191 100644 (file)
@@ -82,6 +82,7 @@
 #include <linux/firewall.h>
 #include <linux/module.h>
 #include <linux/net_alias.h>
+#include <linux/init.h>
 
 #include <net/ip.h>
 #include <net/arp.h>
@@ -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;
 
index 2497ab88b7e4fc52a3ace150ebb9bb5fa2995e08..6a38177b6b65a44d25fcbf2038100a48b23acd67 100644 (file)
@@ -78,6 +78,7 @@ static char *version =
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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)
 
 
 \f
-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;
index fcf8cc1677a275ddaca33fda108aaa93d98c56f7..aae249ed0ae80e21538d0a3a2078978670f0d10e 100644 (file)
@@ -266,6 +266,7 @@ static const char *version = "de4x5.c:V0.5 97/1/30 davies@maniac.ultranet.com\n"
 #include <linux/bios32.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -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;
 
index 84d77f6a3ff19f4ba141e1459287f60b323045d1..700c95a754cf548c754003c6831984741be6cc7f 100644 (file)
@@ -103,6 +103,7 @@ static const char *version =
 #include <linux/ptrace.h>
 #include <asm/system.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/inet.h>
 #include <linux/netdevice.h>
@@ -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;
index dfcf54b7b6bbc413a0c251e9e9b4d82ee738ecfe..60bc9229dbf99fcb1c96382812101d22e3b27d8d 100644 (file)
@@ -131,6 +131,7 @@ static const char *version =
 #include <linux/ptrace.h>
 #include <asm/system.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/inet.h>
 #include <linux/netdevice.h>
@@ -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;
 
index fce95ff35593c04395e204ec9a3c53316fdb8347..5e50cbfa553241ce1888d56b9bf4a351b173c109 100644 (file)
@@ -215,6 +215,7 @@ static const char *version = "defxx.c:v1.04 09/16/96  Lawrence V. Stefani (stefa
 #include <linux/pci.h>
 #include <linux/bios32.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/byteorder.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
index c1c4a299ecfdd9b9bc19963f6b07fe574116971e..85cf704c546e4e221f503d4fbebf833b7cc9ae7b 100644 (file)
@@ -219,6 +219,7 @@ static const char *version = "depca.c:v0.43 96/8/16 davies@maniac.ultranet.com\n
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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
 
 \f
 
-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;
index b3806503093ca4adcb12c845d5b175c4be22235c..1a9d4882733c139217e000f2fd07f315f2e077e5 100644 (file)
@@ -88,6 +88,7 @@ static char *version = "$Id: dgrs.c,v 1.12 1996/12/21 13:43:58 rick Exp $";
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
@@ -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;
 
index f76bddb582c32c53a846e3c6524d59ef2511a169..8641eadd80647e3e0f467df4ab1937d426998b6a 100644 (file)
@@ -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,
index 953f02b28ab3ed86e99ef1dd3af0ea0b26134074..e42b0dcf45aa71fe861bd66a5b810aed4c962220 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -606,7 +607,7 @@ int dlci_init(struct device *dev)
        return(0);
 }
 
-int dlci_setup(void)
+__initfunc(int dlci_setup(void))
 {
        int i;
 
index 445b1d81fa23c682e845fe9b4cfebb67380e1197..814d798c55d38b7c482b37a4916b5fc8e60b02fc 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
index f68227ab1f792c8c240342770ecfe57938566464..4b6e67daf37ba3b29f96d605eff2ec38dbacba42 100644 (file)
@@ -43,6 +43,7 @@ static const char *version =
 #include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -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;
index 5719a7c1ca3dd17348c8b03c1e31ae5f45fe9175..72060c53b882d1dfec13b31b4b6ebd2ff7dbced8 100644 (file)
@@ -101,6 +101,7 @@ static const char *version =
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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;
index eb2690ff9e2f2297b4f5d4052db1752d6bbc207d..cf67f942bd582eda8baad22b29ebe1fb8d7c0cb0 100644 (file)
@@ -55,6 +55,7 @@ static int rxdmacount = 0;    /* Rx DMA length, 0 means no preemption. */
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+#include <linux/init.h>
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
 
index 17d27338138175c4a3567acb27df691941908062..820d5b42854e39a69d3b3cb00be8ef7c37ade451 100644 (file)
@@ -130,6 +130,7 @@ static const char *version =
 #include <asm/dma.h>
 #include <asm/uaccess.h>
 #include <linux/errno.h>              
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/if.h>
@@ -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; */
index f67e5a4a9e03023aa764fe40c54b55d7cbd976d4..96ffd43deba9c4c29e5b8c115d336aadca30299f 100644 (file)
@@ -53,6 +53,7 @@ static const char *version =
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -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;
index 2d0a2147ee9767be691e68d9d5a01620434ecdb3..24e449390065f5e7c44dc86648ec061798038b4f 100644 (file)
@@ -87,6 +87,7 @@ static char *version =
 #include <linux/malloc.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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;
index 17b5c9bdf4b2484b4190e9d28f53c4b45f15ad7c..3c37522510a19b17537467677333ec5fdb1c8169 100644 (file)
@@ -149,6 +149,7 @@ static const char *version = "ewrk3.c:v0.43 96/8/16 davies@maniac.ultranet.com\n
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -344,7 +345,7 @@ static int num_ewrk3s = 0, num_eth = 0;
 
 \f
 
-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;
index d95f1e29f23c5dc1b174d3c8ce482c6739cb03bb..7536a7e041412779319701ed95c53ba3b7228835 100644 (file)
@@ -46,6 +46,7 @@ static const char *version =
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -57,7 +58,7 @@ static const char *version =
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 
-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;
index 70039edfe199de867962091da260ca851e434b70..9098fdf2e611c928035569598a05e36580b8183a 100644 (file)
@@ -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++;
 }
index 635b9764add0f142e9f8d47d4c5dafe3c6043d7a..b7f85f735dbd58f915f238e8b83aabc8388a63fe 100644 (file)
@@ -30,6 +30,7 @@ static const char *version =
 #include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -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;
index 531d5f20f63d4b91077b7f25194019e64d1106b0..d57763e46ef226d2059df3fefc74a4e0c0937c87 100644 (file)
@@ -30,6 +30,7 @@ static const char *version =
 #include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -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};
 
 \f
 /*     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;
index c85e3b355b29cb38f7b6a6b2082a856daed70fcc..6a599dd602763f5e06c7129d49f6654b3f365237 100644 (file)
@@ -93,6 +93,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 
@@ -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;
index 20d82d2c2bbe9a321dc7f72cf358c944c5788974..ca0e019ce2ac08ef78b88dcad79e7e42a7f58726 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
index 8f2ffcca89d0e33ff74ac6529d34bdc591ad95e5..faedd45fad1df2f77f458d6ef14dfb0e0bf153de 100644 (file)
@@ -119,6 +119,7 @@ static char mcchannelid[] = {
 #include <linux/netdevice.h>
 #include <linux/trdevice.h>
 #include <linux/stddef.h>
+#include <linux/init.h>
 #include <net/checksum.h>
 
 #include <asm/io.h>
@@ -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;
 
index 4483a1fe9e9919f46d2d113cddd47a3d823c11cb..011d89189e0ac3c30c7ccb40a93a9fea9ccbaf07 100644 (file)
@@ -46,6 +46,7 @@ static const char *version = "lance.c:v1.09 Aug 20 1996 dplatt@3do.com, becker@c
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -54,7 +55,7 @@ static const char *version = "lance.c:v1.09 Aug 20 1996 dplatt@3do.com, becker@c
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-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;
index 0ddc6da5b2a02b193d9be5f6a73113ee0e07250c..3d980135204ed204ce1e2cbdc80cc2eee8b4fbc3 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/module.h>
 #include <linux/net_alias.h>
 #include <linux/lapb.h>
+#include <linux/init.h>
 
 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;
 }
index a9716d7f00d1ac74e4ff2b687e6064e81a7dbc6d..629f6a0caaad8fcb1117d139715a17ac3de8f279 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/in.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -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;
index 49f7dd618f940243d05b8b0de046f76b47dd7e60..8a4fae56084b4a3bb1dc4d451572c3afa5ee14e1 100644 (file)
@@ -201,6 +201,7 @@ static int debug=0;
 #include <asm/bitops.h>
 #include <asm/dma.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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<<irq;
 }
 
-int ltpc_probe(struct device *dev)
+__initfunc(int ltpc_probe(struct device *dev))
 {
        int err;
        unsigned char dma=0;
index 3ed1b8f6700d2d5559a272caba539cff50102156..6f772fd68feb970adba0e7077f72c51e3e149a2c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/major.h>
+#include <linux/init.h>
 
 #include <linux/timer.h>
 
@@ -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));
 
index cfeca28d3901c242e81711be73236e2b6b405983..7e02bf4f85ea520270eb52193b6db0db6d8e1f70 100644 (file)
@@ -41,6 +41,7 @@ static const char *version =
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/io.h>
 
@@ -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];
index 278957f317668154607009f9fdbdb61450503f71..746037adfe09922f2037ee27766375e6ce1380ae 100644 (file)
@@ -114,6 +114,7 @@ static int fifo=0x8;        /* don't change */
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 
@@ -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]) {
index 1cdd7b4cf6869a400bd3ad11611d5306ef6c7a0c..07a946d3b5aa222d5df54ae0ec5f3579f0deeb3b 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -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;
index 983a4da9535758c6c905bf6a09edbd997a0418c9..47bc60e7927da48faf5a408ce9f4e78ae9889e81 100644 (file)
@@ -26,6 +26,7 @@ static const char *version = "pcnet32.c:v0.23 8.2.97 tsbogend@alpha.franken.de\n
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -34,7 +35,7 @@ static const char *version = "pcnet32.c:v0.23 8.2.97 tsbogend@alpha.franken.de\n
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-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);
 
 \f
 
-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;
index cbd2cb7c9d8416f4c92acf47de82fdb8573991a2..347d6d9802bec00018b1267e0e48bc7adc935683 100644 (file)
 #include <linux/timer.h>
 #include <linux/if_arp.h>
 #include <linux/pi2.h>
+#include <linux/init.h>
 #include "z8530.h"
 #include <net/ax25.h>
 
@@ -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");
 
index 37484d1632db541529e937f2172aeab6fc07c1e2..25c33ab1ab10fe10db367a3c67fbc358dc7555d4 100644 (file)
@@ -95,6 +95,7 @@ static const char *version = "NET3 PLIP version 2.2-parport gniibe@mri.co.jp\n";
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/lp.h>
+#include <linux/init.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -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");
index fb351b974f97d9b7eebcd71876cb78590e622393..a1dbb50200a80d06ad215116ea6ee52a90e66c9b 100644 (file)
@@ -85,6 +85,7 @@
 #include <linux/skbuff.h>
 #include <linux/inet.h>
 #include <linux/ioctl.h>
+#include <linux/init.h>
 
 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;
index 3e6257d196cece95c0c33128040cb4543fbe7233..f6ef6db65d881749664c0663e1b0a440fa2cb17e 100644 (file)
@@ -92,6 +92,7 @@
 #include <linux/timer.h>
 #include <linux/if_arp.h>
 #include <linux/pt.h>
+#include <linux/init.h>
 #include "z8530.h"
 #include <net/ax25.h>
 
@@ -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)
index 83acf7fdd3daeee6dd19bf5d69a1562d675afe88..4e43e51614b11b3a5f6b40adbfbd6b2c6474d097 100644 (file)
 #include <linux/if_ether.h>
 #include <linux/if_arp.h>
 #include <linux/socket.h>
+#include <linux/init.h>
 
 #include <linux/scc.h>
 #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];
index bfddc7209aa0e4174b6da027557bf116c3a0e66b..f2762eef1486eea3bdcc58237ab1a42febaf07bd 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -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);
index 3083c025c29c578955f8d371282cfd26e7cef22d..79a493c2ca9b69b10edc378166ddc3fbcc9f8948 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/router.h>      /* WAN router definitions */
 #include <linux/wanpipe.h>     /* WANPIPE common user API definitions */
 #include <linux/if_arp.h>      /* ARPHRD_* defines */
+#include <linux/init.h>                /* __initfunc et al. */
 #include <asm/byteorder.h>     /* htons(), etc. */
 #include <asm/io.h>            /* 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
        {
index 9910a73c4811b9ebf914a4767b41610775b145ea..c6b1ce945f9b145bc57550b9f8aeef7fe055ed32 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/router.h>      /* WAN router definitions */
 #include <linux/wanpipe.h>     /* WANPIPE common user API definitions */
 #include <linux/if_arp.h>      /* ARPHRD_* defines */
+#include <linux/init.h>                /* __initfunc et al. */
 #include <asm/byteorder.h>     /* 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
        {
index 116bee984d40a5aff879aae9ee95f260f0f242f4..f6f540709ace85a9ccfa059758e9c92e97a63549 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/malloc.h>      /* kmalloc(), kfree() */
 #include <linux/router.h>      /* WAN router definitions */
 #include <linux/wanpipe.h>     /* WANPIPE common user API definitions */
+#include <linux/init.h>                /* __initfunc et al. */
 #include <asm/byteorder.h>     /* 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
        {
index d1f3bd051c84b1809a6b5209b34a8a2f72e6c649..500c5cb6d82f01e96cb3aa50b2755636a8241fb8 100644 (file)
@@ -90,6 +90,7 @@
 #include <linux/sched.h>       /* for jiffies, HZ, etc. */
 #include <linux/sdladrv.h>     /* API definitions */
 #include <linux/sdlasfm.h>     /* SDLA firmware module definitions */
+#include <linux/init.h>
 #include <asm/io.h>            /* 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);
index 524b4a312de64f8958e8e33a47ce4b9a428c2a3e..397228647e3882716af3d4039eed89c11b757dfe 100644 (file)
@@ -40,6 +40,7 @@ static const char *version =
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
index ac95948df858653b5ec6946840a4553866d7e7e0..a40f16599bd2628f9d485dc5e637e9e9972ba88d 100644 (file)
@@ -68,6 +68,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
+#include <linux/init.h>
 #include <net/dst.h>
 #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.
index 35d9335c409fb18758e621a492674e81ec4b2b72..7e946b78f2d9591af0bc879977d35e92dfac2aa0 100644 (file)
@@ -77,6 +77,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <linux/mm.h>
+#include <linux/init.h>
 #include <net/checksum.h>
 #include <net/slhc_vj.h>
 #include <asm/unaligned.h>
@@ -743,7 +744,7 @@ void cleanup_module(void)
 
 #else /* MODULE */
 
-void slhc_install(void)
+__initfunc(void slhc_install(void))
 {
 }
 
index 9b7aba32ff951ad62119c3f4cddcb863ab5a3cc0..f091e38a4f4b4ebcb7fae5df52ec2f32a6cb8571 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/if_slip.h>
+#include <linux/init.h>
 #include "slip.h"
 #ifdef CONFIG_INET
 #include <linux/ip.h>
@@ -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;
index 3188c8240badda92d7598f8ae7ba00fb10a831b8..43872c529a760e6a842c12dd1e51a954a13eeaa0 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -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;
index 506e8b80cc87d82cc28ff3dd3745383fa3a1ae71..30c6b49070eeefdbfcc78c9aaedaf379d0331586 100644 (file)
@@ -53,6 +53,7 @@ static const char *version =
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -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;
index d879d3d13c2b75ae09eb4745242b25a24d4f5c84..5b3e9b73ce58d454607fc0c7684b27bb1d0dea31 100644 (file)
@@ -66,6 +66,7 @@ static const char *version =
 #include <linux/malloc.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <linux/errno.h>
@@ -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;
 
index 1b7a1abad3b3d95f2d180949eb770a7774cf3543..fe4cf2662c3ca18e814c838a8f1e0d24adf1206c 100644 (file)
@@ -62,6 +62,7 @@ static char *version =
 #include <linux/pci.h>
 #include <linux/bios32.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <asm/byteorder.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
index 7bf840fc160f9fd2c179575aa90eab1581e927f1..dc7c08a074f0904dee5e268ec6400c32a48f57c2 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/in.h>
 #include <net/ip.h>
 #include <linux/if_arp.h>
+#include <linux/init.h>
 
 /*#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;
index 77ac9e05359f95ae9269e3944678a74b9a1ac1f2..56e8bd5ab2b79729f6fe2f69e5e652072d7a48b9 100644 (file)
@@ -33,6 +33,7 @@ static const char *version =
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -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;
index 74cbce666fa7b0073efae2cbc0206e57c2602150..21963477ca358ca81ccc244eaf86c5d3e9d97ecf 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/if_arp.h>
 #include <linux/x25.h>
 #include <linux/lapb.h>
+#include <linux/init.h>
 #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;
index bea1771c6ff678f3cb846bba216154b4df684690..eb198bc78a1cf1c50ff22988126a03c879b822aa 100644 (file)
@@ -69,6 +69,7 @@ static const char *version = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -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;
index e10d0120c9c49b59775e7192c1dccd440154bd64..8baf90212cf576aacf880f1eb6618179f9977200 100644 (file)
@@ -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"),
index 672d2d86ea88921e5db79be346342c440f7a25a5..57574b6a5c0bfd2de265ac4f08bcd94c25e09fde 100644 (file)
@@ -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 (file)
index 0000000..193a261
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * creator.c: Linux/Sun Ultra Creator console support.
+ *
+ * Copyright (C) 1997 MIguel de Icaza (miguel@nuclecu.unam.mx)
+ *
+ */
+#include <linux/kd.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/proc_fs.h>
+
+#include <asm/sbus.h>
+#include <asm/io.h>
+#include <asm/fbio.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+#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 <linux/kd.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/proc_fs.h>
+
+#include <asm/sbus.h>
+#include <asm/io.h>
+#include <asm/fbio.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+#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 (file)
index a66a2d6..0000000
+++ /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 <linux/init.h>
-
-#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 <jst@uwasa.fi> */
-
-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";
index 6c22f6ed0bc44601ff7954909424c98c1568bf20..87fb0fea49d3d95fb22d9e818d82fd89eeb7504f 100644 (file)
@@ -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;
index 025bd7e5b13a1f1dfb95adfca8635f4fd4246cd4..3691108e62f5b21dc75473fb08960692fe216604 100644 (file)
@@ -253,6 +253,7 @@ typedef unsigned int  u32;
 #include <linux/ioport.h>
 #include <linux/time.h>
 #include <linux/blk.h>
+#include <linux/init.h>
 #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 in
 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 */
index 7cb554bb0bf7f633a60d811767169743b0e51d90..0ea714166cdbc743fbb4a140ecffbbed154bddbc 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/blk.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -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;
index e69229b0afc291eac54beb4031b34a9e8fc69f2e..7e5038efd512643a5d3249ea275f47ecd853ee7d 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/stat.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+#include <linux/init.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/system.h>
@@ -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;
index 51c39e3938c075650c1ceee4d24a7a564f269298..6ecc0f1aa33bfb13f81cec9772b528e0a0d1675c 100644 (file)
@@ -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;
index 793f30608ba3662b9c28bfaf718d5b25bbc8c8b1..e29af7ad8556ac02f80273ad3a4ebaa151b9c9af 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/bitops.h>
@@ -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);
index 3659d6a2519e88a680b4cb457cea28f79be8ffe3..a7cec9d06802623f8968116c0e56d5b79b91dbd8 100644 (file)
 #include <linux/malloc.h>
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
 #include <linux/proc_fs.h>
+#include <linux/init.h>
 #endif /* version >= v1.3.0 */
 #include <asm/io.h>
 #include <asm/system.h>
@@ -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;
index 1acc73f33c68398e437955df1161848e3dd4e456..96e66defdd8a2a4bd7e4a48c1b5ae06db3bb98ca 100644 (file)
@@ -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)         \
     ;                                                  \
index 081780cf8f1deedd687b584b3deede241e6f6a48..f45c133d7a8edddb4904601461c67aeadef487b9 100644 (file)
@@ -84,8 +84,9 @@
 #include "NCR5380.h"
 #include "constants.h"
 #include "sd.h"
-#include<linux/stat.h>
-#include<linux/string.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/init.h>
 
 
 #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;
index 9b1769e5bcebe0f113edadbe1c712bb606435778..96e4a0ecab146307017993eb09694a5beaabcb93 100644 (file)
 #include "NCR5380.h"
 #include "constants.h"
 #include "sd.h"
-#include<linux/stat.h>
+#include <linux/stat.h>
+#include <linux/init.h>
 
 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;
index 795d1286ddd55eba7945ed372f1a9e2ae5f7fd78..0c1e2df31f193bd77404a40b2706fa9e6a2cf67e 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
+#include <linux/init.h>
 
 #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;
index e737b812b9284d4d7a09165f6df9df41c78443aa..f82bb2aa4817a3568ecad69ef3b111626e814e24 100644 (file)
@@ -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);
 }
index 7cfcc53c5910bd256af65eb96f50b581b59d544a..3c0c7fb03751b3bface38b06657c6a274f54436b 100644 (file)
@@ -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,
index a08ff1e62d8f3ec95cfc298610043fdfac67970f..507080dd04de9344929189b8fae21a0355132a0a 100644 (file)
 #include "constants.h"
 #include "sd.h"
 
-#include<linux/stat.h>
+#include <linux/stat.h>
+#include <linux/init.h>
 
 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;
index 2d9ae7eaebdbce174c89384167d49262b3cf38ea..9f851a277f57ac4fd52b6cebee6625d8bb76063e 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/blk.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/irq.h>
@@ -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;
index c42de5fcb83008010efd2e91ede4c2f44b67a71a..a8a4a89345b3c857723756f571f6dfa183c3b6be 100644 (file)
 #include "NCR5380.h"
 #include "constants.h"
 #include "sd.h"
-#include<linux/stat.h>
+#include <linux/stat.h>
+#include <linux/init.h>
 
 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;
index e724ddd074b53346edc5530242db37f222b06673..7bd71f2129519816165163838d0f488d6e267a44 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/malloc.h>
 #include <linux/binfmts.h>
 #include <linux/elf.h>
+#include <linux/init.h>
+
 
 #define EM86_INTERP    "/usr/bin/em86"
 #define EM86_I_NAME    "em86"
index 43a40846edff84ab0510a5789289a88969009970..27950290aec9bccdd5434f6701dc533f0e5be348 100644 (file)
 /* 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 <linux/sched.h>
 #include <linux/kernel.h>
@@ -23,6 +28,7 @@
 #include <linux/locks.h>
 #include <linux/errno.h>
 #include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
 #include <linux/swapctl.h>
@@ -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; i<BUF_DIRTY; i++){
+       for(i=0; i<BUF_DIRTY; i++) {
                buffers[i] = nr_buffers_type[i];
                candidate[i] = find_candidate(lru_list[i], &buffers[i], size);
        }
        
-       /* Now see which candidate wins the election */
+       /* Now see which candidate wins the election. */
        
        winner = best_time = UINT_MAX;  
-       for(i=0; i<BUF_DIRTY; i++){
-               if(!candidate[i]) continue;
-               if(candidate[i]->b_lru_time < best_time){
+       for(i=0; i<BUF_DIRTY; i++) {
+               if(!candidate[i])
+                       continue;
+               if(candidate[i]->b_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<<BH_Touched);
@@ -769,7 +811,7 @@ void set_writetime(struct buffer_head * buf, int flag)
        int newtime;
 
        if (buffer_dirty(buf)) {
-               /* Move buffer to dirty list if jiffies is clear */
+               /* Move buffer to dirty list if jiffies is clear. */
                newtime = jiffies + (flag ? bdf_prm.b_un.age_super : 
                                     bdf_prm.b_un.age_buffer);
                if(!buf->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<j; i++)
                brelse(bhlist[i]);
 
-       /* Wait for this buffer, and then continue on */
+       /* Wait for this buffer, and then continue on. */
        bh = bhlist[0];
        wait_on_buffer(bh);
        if (buffer_uptodate(bh))
@@ -948,7 +996,7 @@ static void put_unused_buffer_head(struct buffer_head * bh)
 {
        if (nr_unused_buffer_heads >= 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:
- */
index 3f2361780eebbfb371a0f483f489c98c0ac4e00f..2dc317aad8361f95162f311059bf696b030a9704 100644 (file)
@@ -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 <linux/string.h>
 
 #include <asm/unaligned.h>
+#include <asm/spinlock.h>
+
+spinlock_t dcache_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * Don't bother caching long names.. They just take up space in the cache, and
  */
 #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)
 {
@@ -105,79 +127,51 @@ 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;
 }
index abefb471fff6e378b251471dcb22185d60911730..7d5b51ef1c778352b78af19645bf971eb2f32120 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/major.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#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 */
index 6390bb6c983d0b3ab58fd9b4a00db8dbc2c883b5..b1d9bda4e15ba2f869981439c1c94ee866984c84 100644 (file)
 /*
- *  linux/fs/inode.c
+ * linux/fs/inode.c: Keeping track of inodes.
  *
- *  Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1997 David S. Miller
  */
 
-#include <linux/stat.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
-#include <asm/system.h>
-
-#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;
-}
+#define INODE_HASHSZ   1024
 
-static inline struct inode_hash_entry * const hash(kdev_t dev, int i)
-{
-       return hash_table + hashfn(dev, i);
-}
+static struct inode *inode_hash[INODE_HASHSZ];
 
-static inline void insert_inode_free(struct inode *inode)
-{
-       struct inode * prev, * next = first_inode;
+/* All the details of hashing and lookup. */
+#define hashfn(dev, i) ((HASHDEV(dev) + ((i) ^ ((i) >> 10))) & (INODE_HASHSZ - 1))
 
-       first_inode = inode;
-       prev = next->i_prev;
-       inode->i_next = next;
-       inode->i_prev = prev;
-       prev->i_next = inode;
-       next->i_prev = inode;
+__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;
 }
 
-static inline void remove_inode_free(struct inode *inode)
+#define hash_inode(inode) insert_inode_hash(inode)
+
+static inline void unhash_inode(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;
+       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;
+       }
 }
 
-void insert_inode_hash(struct inode *inode)
+static inline struct inode *find_inode(unsigned int hashent,
+                                      kdev_t dev, unsigned long ino)
 {
-       struct inode_hash_entry *h;
-       h = hash(inode->i_dev, inode->i_ino);
+       struct inode *inode;
 
-       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;
+       for(inode = inode_hash[hashent]; inode; inode = inode->i_hash_next)
+               if(inode->i_dev == dev && inode->i_ino == ino)
+                       break;
+       return inode;
 }
 
-static inline void remove_inode_hash(struct inode *inode)
-{
-       struct inode_hash_entry *h;
-       h = hash(inode->i_dev, inode->i_ino);
+/* Free list queue and management. */
+static struct free_inode_queue {
+       struct inode *head;
+       struct inode **last;
+} free_inodes = { NULL, &free_inodes.head };
 
-       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_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_last_free(struct inode *inode)
+static inline void put_inode_last(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;
+       inode->i_next = NULL;
+       inode->i_pprev = free_inodes.last;
+       *free_inodes.last = inode;
+       free_inodes.last = &inode->i_next;
+       nr_free_inodes++;
 }
 
-int grow_inodes(void)
+static inline void remove_free_inode(struct inode *inode)
 {
-       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(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--;
+       }
+}
 
-       if (!first_inode)
-               inode->i_next = inode->i_prev = first_inode = inode++, i--;
+/* 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;
 
-       for ( ; i ; i-- )
-               insert_inode_free(inode++);
-       return 0;
+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;
 }
 
-unsigned long inode_init(unsigned long start, unsigned long end)
+static inline void remove_inuse(struct inode *inode)
 {
-       memset(hash_table, 0, sizeof(hash_table));
-       first_inode = NULL;
-       return start;
+       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)
+static inline void wait_on_inode(struct inode *inode)
 {
-       if (inode->i_lock)
+       if(inode->i_lock)
                __wait_on_inode(inode);
 }
 
-static inline void lock_inode(struct inode * inode)
+static inline void lock_inode(struct inode *inode)
 {
-       wait_on_inode(inode);
+       if(inode->i_lock)
+               __wait_on_inode(inode);
        inode->i_lock = 1;
 }
 
-static inline void unlock_inode(struct inode * inode)
+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)
+static void __wait_on_inode(struct inode * inode)
 {
-       struct wait_queue * wait;
+       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)) {
-               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);
+       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, * next;
-       int i;
+       struct inode *inode;
+       int pass = 0;
 
-       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)
+       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;
        }
-       return 1;
+       if(pass == 0) {
+               inode = inuse_list;
+               pass = 1;
+               goto repeat;
+       }
+       return 1; /* Tis' cool bro. */
 }
 
-int fs_may_umount(kdev_t dev, struct inode * mount_root)
+int fs_may_umount(kdev_t dev, struct inode *iroot)
 {
-       struct inode * inode;
-       int i;
+       struct inode *inode;
+       int pass = 0;
 
-       inode = first_inode;
-       for (i=0 ; i < nr_inodes ; i++, inode = inode->i_next) {
-               if (inode->i_dev != dev || !inode->i_count)
+       inode = free_inodes.head;
+repeat:
+       for(; inode; 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))
+               if(inode == iroot &&
+                  (inode->i_count == (inode->i_mount == inode ? 2 : 1)))
                        continue;
                return 0;
        }
-       return 1;
+       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;
@@ -239,79 +242,70 @@ int fs_may_remount_ro(kdev_t dev)
                if (S_ISREG(file->f_inode->i_mode) && (file->f_mode & 2))
                        return 0;
        }
-       return 1;
+       return 1; /* Tis' cool bro. */
 }
 
-static void write_inode(struct inode * inode)
+/* Reading/writing inodes. */
+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;
+       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;
+                       }
+               }
        }
-       inode->i_lock = 1;      
-       inode->i_sb->s_op->write_inode(inode);
-       unlock_inode(inode);
 }
 
-static inline void read_inode(struct 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)
+       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);
+               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;
+       if(!(attr->ia_valid & ATTR_FORCE)) {
+               unsigned short fsuid = current->fsuid;
+               uid_t iuid = inode->i_uid;
+               int not_fsuser = !fsuser();
 
-       /* 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;
+               if(((attr->ia_valid & ATTR_UID) &&
+                   ((fsuid != iuid) ||
+                    (attr->ia_uid != iuid)) && not_fsuser)     ||
 
-       /* 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;
+                  ((attr->ia_valid & ATTR_GID) &&
+                   (!in_group_p(attr->ia_gid) &&
+                    (attr->ia_gid != inode->i_gid)))           ||
 
-       /* Make sure a caller can chmod */
-       if (attr->ia_valid & ATTR_MODE) {
-               if ((current->fsuid != inode->i_uid) && !fsuser())
+                  ((attr->ia_valid & (ATTR_ATIME_SET | ATTR_MTIME_SET)) &&
+                   (fsuid != iuid) && not_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;
+               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;
 }
 
-/*
- * 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)
@@ -334,17 +328,8 @@ void inode_setattr(struct inode *inode, struct iattr *attr)
        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 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))
@@ -353,303 +338,320 @@ int notify_change(struct inode * inode, struct iattr *attr)
                        attr->ia_mtime = attr->ia_ctime;
        }
 
-       if (inode->i_sb && inode->i_sb->s_op  &&
+       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;
+       if(inode_change_ok(inode, attr) != 0)
+               return -EPERM;
 
        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)
+int bmap(struct inode *inode, int block)
 {
-       if (inode->i_op && inode->i_op->bmap)
-               return inode->i_op->bmap(inode,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;
+       struct inode *inode;
+       int pass = 0;
 
-       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;
-               }
+       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)
 {
-       int i;
-       struct inode * inode;
+       struct inode *inode;
+       int pass = 0;
 
-       inode = first_inode;
-       for(i = 0; i < nr_inodes*2; i++, inode = inode->i_next) {
-               if (dev && inode->i_dev != dev)
-                       continue;
+       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);
-               if (inode->i_dirt)
-                       write_inode(inode);
+               write_inode(inode);
+       next:
+               inode = next;
+       }
+       if(pass == 0) {
+               inode = inuse_list;
+               pass = 1;
+               goto repeat;
        }
 }
 
-void iput(struct inode * inode)
+static struct wait_queue *inode_wait, *update_wait;
+
+void iput(struct inode *inode)
 {
-       if (!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);
+       if(!inode->i_count) {
+               printk("VFS: Freeing free inode, tell DaveM\n");
                return;
        }
-       if (inode->i_pipe)
+       if(inode->i_pipe)
                wake_up_interruptible(&PIPE_WAIT(*inode));
-repeat:
-       if (inode->i_count>1) {
+we_slept:
+       if(inode->i_count > 1) {
                inode->i_count--;
-               return;
+       } 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 */
+               }
        }
+}
 
-       wake_up(&inode_wait);
-       if (inode->i_pipe) {
-               unsigned long page = (unsigned long) PIPE_BASE(*inode);
-               PIPE_BASE(*inode) = NULL;
-               free_page(page);
-       }
+static kmem_cache_t *inode_cachep;
 
-       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;
-       }
+static void grow_inodes(void)
+{
+       int i = 16;
 
-       if (inode->i_dirt) {
-               write_inode(inode);     /* we can sleep - so do again */
-               wait_on_inode(inode);
-               goto repeat;
+       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++;
        }
+}
 
-       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;
-               }
+/* 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);
        }
-       
-       inode->i_count--;
+       return best;
+}
 
-       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;
+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);
        }
-
-       nr_free_inodes++;
-       return;
+       return NULL;
 }
 
-struct inode * get_empty_inode(void)
+struct inode *get_empty_inode(void)
 {
        static int ino = 0;
-       struct inode * inode, * best;
-       unsigned long badness;
-       int i;
+       struct inode *inode;
 
-       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);
+       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;
        }
-       if (best->i_lock) {
-               wait_on_inode(best);
+       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 (best->i_dirt) {
-               write_inode(best);
+       if(inode->i_lock) {
+               wait_on_inode(inode);
                goto repeat;
-       }
-       if (best->i_count)
+       } else if(inode->i_dirt) {
+               write_inode(inode);
                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;
+       goto got_it;
 }
 
-struct inode * get_pipe_inode(void)
+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;
+       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;
+               }
        }
-       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;
+static int inode_updating[INODE_HASHSZ];
 
-       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;
+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);
        }
-       if (empty)
-               iput(empty);
-
-return_it:
-       while (h->updating)
+       while(inode_updating[hashent])
                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)
+void inode_init(void)
 {
-       struct wait_queue wait = { current, NULL };
+       int i;
 
-       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;
+       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;
 }
index 4f35de9b5d509f68397a6e4e06d5778e27b49756..c466321ed9308dd7a00af5fa7ec1ef1b25496fb6 100644 (file)
@@ -35,6 +35,8 @@
 # define copy_to_user          memcpy_tofs
 # define access_ok             !verify_area
 #endif
+#include <asm/smp.h>
+#include <asm/smp_lock.h>
 
 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 <okir@monad.swb.de>");
 
 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
index a2cac539e18d37f35439214f464d0a2cfd52511a..84d296834d6dced3fe2a4331bafc980a0a02446c 100644 (file)
@@ -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);
index 8eb924c18f5fcf70d864ef0a67a607ef9c613991..7d769dfcd0fc20f93a1c889ed0ba097c9c18536e 100644 (file)
@@ -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
index 0e664bb536e1dd5c4a2cf21c03862bf2db981a2c..90829f270eaaddd785d4d617a8f71f14c9f1166f 100644 (file)
@@ -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;
index 50d93715282470449dcdec43cc9cdfd861b09f11..fa8124c3866c2f830c86eceff7da1be36a59a919 100644 (file)
@@ -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);
index aef56398ec00abc3a1a1cd4f47ca4b3d07ecfb08..9e58e0e4de280ea3d3fc78670e27332004e078fd 100644 (file)
@@ -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 (file)
index 0000000..d43ce2a
--- /dev/null
@@ -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 */
index 20e991e39228945074c0030b4b507f847b19896a..7d973530c47ae6b848d55d394e77b4b7731c442d 100644 (file)
@@ -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;
index 396f744a6144bf028b89f276b80066ec0b9be8c2..07a6784354b7f6fb36656d33941866ed8a128aa4 100644 (file)
@@ -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);
index 03b18cb9c2254952489cb57f87973f4fab9f716a..27630b21d880f582bcd3ff8a1789bfdf8b741d28 100644 (file)
@@ -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 (file)
index 0000000..e035055
--- /dev/null
@@ -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 (file)
index 0000000..fc47dac
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __M68K_FPU_H
+#define __M68K_FPU_H
+
+#include <linux/config.h>
+
+/*
+ * 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 <linux/config.h>
+
+/*
+ * 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 (file)
index 0000000..e9d0136
--- /dev/null
@@ -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 (file)
index 0000000..516066f
--- /dev/null
@@ -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 (file)
index 0000000..9b52915
--- /dev/null
@@ -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 (file)
index 0000000..158de09
--- /dev/null
@@ -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 (file)
index 0000000..32f12c0
--- /dev/null
@@ -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 (file)
index 0000000..cbae3d6
--- /dev/null
@@ -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 (file)
index f3742cf..0000000
+++ /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 */
index 2be22d14e7a4927c037b5d5f360e6da691c070ba..2d3f70bc6ffccadb2d43ad70a6dc1f7f7183f19f 100644 (file)
 
 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]--)
index 87da9512682a8daa2314e30b8820cb0abe3f656f..16c2ca5a107c9efbf3233e31011e15edc2c7b39c 100644 (file)
@@ -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)
 
 #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 (file)
index 0000000..4c323b4
--- /dev/null
@@ -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 <linux/init.h>
+#include <linux/version.h>
+
+#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 <jst@uwasa.fi> */
+
+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 <linux/init.h>
+#include <linux/version.h>
+
+#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 <jst@uwasa.fi> */
+
+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";
index 87947bc0f673fba948791f96340b12cc6632c60c..efe4e843122dd84b1c3f108ed44bd0b913ec2f4a 100644 (file)
@@ -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) */
index 70860c40471523abf17857240e43a27cd6aee562..4f0a8e5f4720889c7b80712522baa644184fcd08 100644 (file)
@@ -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
index 76cec1e71635dcccfaa75a83b9473437e9a0f7fc..41b72b40aa2da8135bc07564a1799aaf057bacdd 100644 (file)
  * 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 <asm/spinlock.h>
 
 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)         \
index af6c5163f20effae4d7276985d819752a88d959f..877b7416a15bbe235b839ebc602d18b783d1ee17 100644 (file)
@@ -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)
index e4ecd60465838a0041509878f446a9fae67df930..e1d33e436138b317f1df1ff335b91e1271e929b2 100644 (file)
@@ -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
 
index f678f702dcee676ba0592a1b122f0cb30c67c5d6..0312a2d557a9200a17681778d2decf3757383150 100644 (file)
@@ -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.
  *
 #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 (file)
index 0000000..7787fb0
--- /dev/null
@@ -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 <linux/init.h>
+#include <linux/version.h>
+
+#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 <jst@uwasa.fi> */
+
+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 <linux/init.h>
+#include <linux/version.h>
+
+#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 <jst@uwasa.fi> */
+
+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";
index 8bfaeff9b66e2b8e1f7f8b650a451e3019c43069..cd4503cc67c932a7cb361c7be2edb7facf2d2579 100644 (file)
@@ -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 <asm/sigcontext.h>
@@ -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 */
 };
 
index e50e957939d7342651a87d2d80340c09cc4d94cb..3e5d7cc72a4a1ebe261fd0248e3c40381e038c10 100644 (file)
@@ -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)         \
index 6b80857c25add012cbadce3f9b460aa0eb9cec46..dbb569f1813409294aa579926103397fc1fd074d 100644 (file)
@@ -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__ */
index 470f6f8e205598b17f8e21909b5477d1511796f0..0d832252564b573cbe8cbaff61ada1c624f2d8b1 100644 (file)
@@ -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 <linux/types.h>
 
-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];
index 31d086c6cb54eaedc07a600d57c1c538e383960b..51750311c9de6624bfe4656bb0330318d67b4bc2 100644 (file)
@@ -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
 
 #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) \
index c1dada8eeb636aef33be5ca03cfd35963976ffd9..85e04d184807fa51594d62a667399830a8534245 100644 (file)
@@ -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 <asm/bitops.h>
 
 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 <linux/quota.h>
 
 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;
index 64c5c344f1de8e452b90e38aea60e0cf8a246a16..9572b3415de965e01dfbc81e3c7146ccc056553a 100644 (file)
@@ -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 */
index 8688741923077d01a0843960a6c453a582b8cabf..9af62e4a2f9b73e8f8cfda759e8d7a0739e07674 100644 (file)
@@ -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;
index cef9cc4b7f1d33b375757de31f11ba6b5e2b6a97..58c4e026b58d586462b273868de27fe14f403a60 100644 (file)
 #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
index efdae3a917ca52b7e6be45871ec45757112e2c05..86a5e64171eefd2ef34b6eebb550091a7ce14358 100644 (file)
 #include <asm/atomic.h>
 #include <asm/types.h>
 
-#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);
index 604f99f1cdd45a3343a258a376c2b6a9cae26457..0e01fba0fe72874672f639f379ade550b1e9fae9 100644 (file)
@@ -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,
index 703422ef62309ca71e57138f90da3a029e0ae058..fcc6ad09f2718e8d5280eb6df94425c655f586e3 100644 (file)
@@ -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 (file)
index 0000000..e192898
--- /dev/null
@@ -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 */
index 7e6c57f4c99de0b55677df1f6a2b80b92afa2005..61936854f74a4a6ecea10b2e49850c99fa28b636 100644 (file)
@@ -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
  */
@@ -237,11 +265,6 @@ struct tcp_opt
                                                 * write queue if we are doing
                                                 * 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;
 
  /*
index a7b42c8db7aa87b960a37318b03dfe29eea8741f..3822b461f2ede81c4a041c915dbc47c56459b6a4 100644 (file)
 #include <linux/slab.h>
 #include <net/checksum.h>
 
-/* 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 */
-
index 00b29260609b4eb55164ce3438cf5d31bd7353c6..15ab2176e75d3f1db5d2e478a03a46cb374dfb0d 100644 (file)
@@ -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();
index 51e9de867b0d3098723092235fca85edb76d658c..d6c43a625565a32628cfd5f5c97b566c95bdb2ad 100644 (file)
@@ -136,6 +136,12 @@ void release(struct task_struct * p)
        }
        for (i=1 ; i<NR_TASKS ; i++)
                if (task[i] == p) {
+#ifdef __SMP__
+                       /* FIXME! Cheesy, but kills the window... -DaveM */
+                       while(p->processor != 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(&current->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(&current->wait_chldexit,&wait);
-       unlock_kernel();
        return retval;
 }
 
index 7136a4eb9456f361b793d6e7fe8be28b6319286c..6204ffeaffe4c436c6b89943d2f646647419a426 100644 (file)
@@ -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;
 }
 
index 86894b951d992c25b429a788700aa2eb43e419ba..ffaec7140e78e85f3333701727b851cb382906e4 100644 (file)
@@ -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;
index a4332afbecf70303d37d949c091da861df9c9d6d..479f660a0dde98cd9f78e81858f233a523ba4534 100644 (file)
@@ -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;
 }
index 3bade85fb4d18594394f5cacc1b9edc0aff1bc9c..f5f202c8e7e27a7bb0b571378bb3947a6651f4f8 100644 (file)
@@ -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);
index fcf52c63779d5e5e368840e56b239265683b25a6..68be616be61d3c08b7c507f6dc8435c86a6dce15 100644 (file)
@@ -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) {
index e657381cff4b03c0696a31a0436cb0f48e44a6fd..f1c5990cb3814d4dce74b68b4bea49c6f99253ee 100644 (file)
@@ -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(&current->sigmask_lock);
        ret = put_user(current->blocked & current->signal, set);
-       unlock_kernel();
+       spin_unlock_irq(&current->sigmask_lock);
        return ret;
 }
 
index 2d55d19d9dd1b290271189360d4f0b4b62300977..934108fa83f855567e8874d243c1b6c1ab3e8c07 100644 (file)
@@ -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)
index 06762b2ed1a4e9a2e3d3b8eecfed39882899a5b1..d20fdbd98a974b1a3ed138b46fe5cfd80a26842f 100644 (file)
@@ -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;
 }
index 141aaace852ba4bfd90b13bfc203eb8bfa3c5885..589f52815b8304a5f82f7a7dea290c8ff63a1520 100644 (file)
@@ -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;
index 645cf09c19b367569eb0de879ec671011a6a37e6..7b6a0eb49f14dbbe1d3f4a8ba5b0ffe3df224724 100644 (file)
--- 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 */
index 67230ceed7bce16b71920ba7ccf12fb7d04b9ef4..7e8cd2a23e5f932eeaae74f6227097ef4646228a 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/string.h>
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
+#include <linux/init.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <net/br.h>
@@ -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;
 
index c6d84a0af4dcc4a6b55a501d5732052812043202..c02d4052e0298ab571c6e089f5ec030ee45ffe77 100644 (file)
@@ -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++;
   
index 147f31436379be96567f2f1ae934babd23a2593c..6a4a13167e56cb2cb7fbdcabb98b4d932cfd245f 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/in.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/init.h>
 
 #include <linux/net_alias.h>
 
@@ -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))
 {
 
        /*
index 936e03c03fcc6b103d538cd0eba6ed455d8ed671..00a87e0e2da112d21b4eaa9e504b6acde80f2748 100644 (file)
@@ -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->data<skb->head)
-               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->data<skb->head)
-               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;
 }
   
index b512cd459e39dcc091bb99028535c67f2756e3d9..8c008c0f25313182df7bbf3dff5ec4edc7a77afd 100644 (file)
@@ -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");
index b03bea8f1ca4275cdcd79a041b7d8790941c3b26..9f4477807655ea60d45faf70bcefb5ec834a6d44 100644 (file)
@@ -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))
        {
index b6db1eb7a6d967809fba877ecc64aeb941e134fd..6b697d00110d7fe46d2e811856e9040497cb3c35 100644 (file)
@@ -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);
        }
 
index 33c139663605cb08becc58de91b6e10a24676061..bf549b0475c18d56a40832a63a60afc6f716ca59 100644 (file)
@@ -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;
index b05b10be7b7cd62c3c9823146f62258ec0891eff..1689159ed7068ddb8fdf00c1c532fb1ae83b6169 100644 (file)
@@ -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);
index 162981feb8381fc01a397309c21ef89a79d1bf66..e3b41e2ad54d180b93bf25f9e78bd70f3a68e40c 100644 (file)
@@ -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);
index a121ef5ae9a369d4c4194c54ae637e5a1a785016..84ba6578b2cc4e16042a0d743a9776f414c1b188 100644 (file)
@@ -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 },
index 8a48dff8da77dc11e85c463e617297d14a3bb827..420db4777ec981d88a2bc83b85fee20a47204612 100644 (file)
@@ -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, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -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 <pall@rz.uni-karlsruhe.de>
                 */
 
-               /* 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)
index 9b584326829f49198be57fa1ff6ae844433fa410..ab2b1ef82f28d980b948afc765453c43e8bfd271 100644 (file)
@@ -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, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -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;
index 7934dc69dcbed8c4f052a5764d843270200a7fa9..f4528f5526d4d121a8c38ebe875e66d95f8c4cbd 100644 (file)
@@ -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 <linux/config.h>
 
 #include <asm/segment.h>
 
+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;
 }
index 57dac01cad5be1bb1bcf8d81b4b9e94203c71656..7f157abe267cfda2365741d9ff8b2e66cc058e8d 100644 (file)
@@ -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, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 
 #include <net/tcp.h>
 
-/*
- *     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));
 }
index 76f821d1dd7b466a25997dd50298d68b5b8e4617..365d3dac2055f0aa6fe3b1506a313c58f25ad4ca 100644 (file)
@@ -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);
index de14fec113e82355bee0ec5e64c0b981980521ba..9ca5f3045c3fd8515d137d423a5e4c7c9e9b4a1c 100644 (file)
@@ -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;
        }
 
index 95b320f0fdc94c0731093b3daf1a3e924b2cd9b4..88920bb732bad56e8947363897704ee74dee6aab 100644 (file)
@@ -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)
index 9064baa9fde96892b76abe7757f75e72024a6777..b9b811e35a4f432a9a0fb3794cb28419521426d8 100644 (file)
@@ -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)
index 21a874ee33cc5e6c1e6f90a79226cfd9b63060e7..5151013a72333859669f625e4e00d6c9d62b46ca 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $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
 
 #include <asm/uaccess.h>
 
+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