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
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
.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
#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 *);
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;
}
{
unsigned long oldmask;
- lock_kernel();
+ spin_lock_irq(¤t->sigmask_lock);
oldmask = current->blocked;
current->blocked = mask & _BLOCKABLE;
+ spin_unlock_irq(¤t->sigmask_lock);
+
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(oldmask,regs, sw, 0, 0))
- goto out;
+ if (do_signal(oldmask, regs, sw, 0, 0))
+ return -EINTR;
}
-out:
- unlock_kernel();
- return -EINTR;
}
/*
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();
}
/*
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:
*
* 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 */
#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)
return; /* emulation was successful */
}
}
+
+ lock_kernel();
printk("%s: arithmetic trap at %016lx: %02lx %016lx\n",
current->comm, regs.pc, summary, write_mask);
die_if_kernel("Arithmetic fault", ®s, 0, 0);
force_sig(SIGFPE, current);
+ unlock_kernel();
}
asmlinkage void do_entIF(unsigned long type, unsigned long a1,
{
extern int ptrace_cancel_bpt (struct task_struct *who);
+ lock_kernel();
die_if_kernel("Instruction fault", ®s, type, 0);
switch (type) {
case 0: /* breakpoint */
default:
panic("do_entIF: unexpected instruction-fault type");
}
+ unlock_kernel();
}
/*
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;
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"
goto got_exception;
una_reg(reg) = tmp1|tmp2;
return;
-#endif
case 0x28: /* ldl */
__asm__ __volatile__(
/* 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"
if (error)
goto got_exception;
return;
-#endif
case 0x2c: /* stl */
__asm__ __volatile__(
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:
if ((fixup = search_exception_table(pc)) != 0) {
unsigned long newpc;
newpc = fixup_exception(una_reg, fixup, pc);
+
+ lock_kernel();
printk("Forwarding unaligned exception at %lx (%lx)\n",
pc, newpc);
+ unlock_kernel();
+
(®s)->pc = newpc;
return;
}
/* Yikes! No one to forward the exception to. */
+ lock_kernel();
printk("%s: unhandled unaligned exception at pc=%lx ra=%lx"
" (bad address = %p)\n", current->comm,
pc, una_reg(26), va);
do_exit(SIGSEGV);
+ unlock_kernel();
}
/*
* 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:
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;
}
/*
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;
}
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);
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) {
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)
-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) }
}
.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
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 */
#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);
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.
/* 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;
--- /dev/null
+/*
+ * 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, ¤t_par);
+#endif
+ return 0;
+}
+
+
+/*
+ * Default Colormaps
+ */
+
+static unsigned short red16[] =
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000,
+ 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff };
+static unsigned short green16[] =
+ { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000,
+ 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff };
+static unsigned short blue16[] =
+ { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000,
+ 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff };
+
+
+static struct fb_cmap default_16_colors =
+ { 0, 16, red16, green16, blue16, NULL };
+
+
+static struct fb_cmap *get_default_colormap(int bpp)
+{
+ return &default_16_colors;
+}
+
+
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16)
+#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \
+ ((1<<(width))-1)) : 0))
+
+static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+ int kspc)
+{
+ int i, start;
+ unsigned short *red, *green, *blue, *transp;
+ unsigned int hred, hgreen, hblue, htransp;
+
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ start = cmap->start;
+
+ if (start < 0)
+ return -EINVAL;
+ for (i = 0; i < cmap->len; i++) {
+ if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
+ return 0;
+ hred = CNVT_FROMHW(hred, var->red.length);
+ hgreen = CNVT_FROMHW(hgreen, var->green.length);
+ hblue = CNVT_FROMHW(hblue, var->blue.length);
+ htransp = CNVT_FROMHW(htransp, var->transp.length);
+ if (kspc) {
+ *red = hred;
+ *green = hgreen;
+ *blue = hblue;
+ if (transp)
+ *transp = htransp;
+ } else {
+ put_user(hred, red);
+ put_user(hgreen, green);
+ put_user(hblue, blue);
+ if (transp)
+ put_user(htransp, transp);
+ }
+ red++;
+ green++;
+ blue++;
+ if (transp)
+ transp++;
+ }
+ return 0;
+}
+
+
+static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+ int kspc)
+{
+ int i, start;
+ unsigned short *red, *green, *blue, *transp;
+ unsigned int hred, hgreen, hblue, htransp;
+
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ start = cmap->start;
+
+ if (start < 0)
+ return -EINVAL;
+ for (i = 0; i < cmap->len; i++) {
+ if (kspc) {
+ hred = *red;
+ hgreen = *green;
+ hblue = *blue;
+ htransp = transp ? *transp : 0;
+ } else {
+ get_user(hred, red);
+ get_user(hgreen, green);
+ get_user(hblue, blue);
+ if (transp)
+ get_user(htransp, transp);
+ else
+ htransp = 0;
+ }
+ hred = CNVT_TOHW(hred, var->red.length);
+ hgreen = CNVT_TOHW(hgreen, var->green.length);
+ hblue = CNVT_TOHW(hblue, var->blue.length);
+ htransp = CNVT_TOHW(htransp, var->transp.length);
+ red++;
+ green++;
+ blue++;
+ if (transp)
+ transp++;
+ if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp))
+ return 0;
+ }
+ return 0;
+}
+
+
+static void do_install_cmap(int con)
+{
+ if (con != currcon)
+ return;
+ if (disp[con].cmap.len)
+ do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1);
+ else
+ do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel),
+ &disp[con].var, 1);
+}
+
+
+static void memcpy_fs(int fsfromto, void *to, void *from, int len)
+{
+ switch (fsfromto) {
+ case 0:
+ memcpy(to, from, len);
+ return;
+ case 1:
+ copy_from_user(to, from, len);
+ return;
+ case 2:
+ copy_to_user(to, from, len);
+ return;
+ }
+}
+
+
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+{
+ int size;
+ int tooff = 0, fromoff = 0;
+
+ if (to->start > from->start)
+ fromoff = to->start-from->start;
+ else
+ tooff = from->start-to->start;
+ size = to->len-tooff;
+ if (size > from->len-fromoff)
+ size = from->len-fromoff;
+ if (size < 0)
+ return;
+ size *= sizeof(unsigned short);
+ memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
+ memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
+ memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
+ if (from->transp && to->transp)
+ memcpy_fs(fsfromto, to->transp+tooff,
+ from->transp+fromoff, size);
+}
+
+
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+ int size = len*sizeof(unsigned short);
+
+ if (cmap->len != len) {
+ if (cmap->red)
+ kfree(cmap->red);
+ if (cmap->green)
+ kfree(cmap->green);
+ if (cmap->blue)
+ kfree(cmap->blue);
+ if (cmap->transp)
+ kfree(cmap->transp);
+ cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+ cmap->len = 0;
+ if (!len)
+ return 0;
+ if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ if (transp) {
+ if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ } else
+ cmap->transp = NULL;
+ }
+ cmap->start = 0;
+ cmap->len = len;
+ copy_cmap(get_default_colormap(len), cmap, 0);
+ return 0;
+}
+
+
+/*
+ * Get the Fixed Part of the Display
+ */
+
+static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+{
+ struct retz3_fb_par par;
+ int error = 0;
+
+ if (con == -1)
+ retz3_fb_get_par(&par);
+ else
+ error = fbhw->decode_var(&disp[con].var, &par);
+ return(error ? error : fbhw->encode_fix(fix, &par));
+}
+
+
+/*
+ * Get the User Defined Part of the Display
+ */
+
+static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con)
+{
+ struct retz3_fb_par par;
+ int error = 0;
+
+ if (con == -1) {
+ retz3_fb_get_par(&par);
+ error = fbhw->encode_var(var, &par);
+ } else
+ *var = disp[con].var;
+ return error;
+}
+
+
+static void retz3_fb_set_disp(int con)
+{
+ struct fb_fix_screeninfo fix;
+
+ retz3_fb_get_fix(&fix, con);
+ if (con == -1)
+ con = 0;
+ disp[con].screen_base = (unsigned char *)fix.smem_start;
+ disp[con].visual = fix.visual;
+ disp[con].type = fix.type;
+ disp[con].type_aux = fix.type_aux;
+ disp[con].ypanstep = fix.ypanstep;
+ disp[con].ywrapstep = fix.ywrapstep;
+ disp[con].can_soft_blank = 1;
+ disp[con].inverse = z3fb_inverse;
+}
+
+
+/*
+ * Set the User Defined Part of the Display
+ */
+
+static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con)
+{
+ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+ if ((err = do_fb_set_var(var, con == currcon)))
+ return err;
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+ oldxres = disp[con].var.xres;
+ oldyres = disp[con].var.yres;
+ oldvxres = disp[con].var.xres_virtual;
+ oldvyres = disp[con].var.yres_virtual;
+ oldbpp = disp[con].var.bits_per_pixel;
+ disp[con].var = *var;
+ if (oldxres != var->xres || oldyres != var->yres ||
+ oldvxres != var->xres_virtual ||
+ oldvyres != var->yres_virtual ||
+ oldbpp != var->bits_per_pixel) {
+ retz3_fb_set_disp(con);
+ (*fb_info.changevar)(con);
+ alloc_cmap(&disp[con].cmap, 0, 0);
+ do_install_cmap(con);
+ }
+ }
+ var->activate = 0;
+ return 0;
+}
+
+
+/*
+ * Get the Colormap
+ */
+
+static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+ if (con == currcon) /* current console? */
+ return(do_fb_get_cmap(cmap, &disp[con].var, kspc));
+ else if (disp[con].cmap.len) /* non default colormap? */
+ copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel),
+ cmap, kspc ? 0 : 2);
+ return 0;
+}
+
+
+/*
+ * Set the Colormap
+ */
+
+static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+ int err;
+
+ if (!disp[con].cmap.len) { /* no colormap allocated? */
+ if ((err = alloc_cmap(&disp[con].cmap,
+ 1<<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, ¤t_par);
+#endif
+ return 0;
+}
+
+
+/*
+ * Default Colormaps
+ */
+
+static unsigned short red16[] =
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000,
+ 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff };
+static unsigned short green16[] =
+ { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000,
+ 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff };
+static unsigned short blue16[] =
+ { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000,
+ 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff };
+
+
+static struct fb_cmap default_16_colors =
+ { 0, 16, red16, green16, blue16, NULL };
+
+
+static struct fb_cmap *get_default_colormap(int bpp)
+{
+ return &default_16_colors;
+}
+
+
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16)
+#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \
+ ((1<<(width))-1)) : 0))
+
+static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+ int kspc)
+{
+ int i, start;
+ unsigned short *red, *green, *blue, *transp;
+ unsigned int hred, hgreen, hblue, htransp;
+
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ start = cmap->start;
+
+ if (start < 0)
+ return -EINVAL;
+ for (i = 0; i < cmap->len; i++) {
+ if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
+ return 0;
+ hred = CNVT_FROMHW(hred, var->red.length);
+ hgreen = CNVT_FROMHW(hgreen, var->green.length);
+ hblue = CNVT_FROMHW(hblue, var->blue.length);
+ htransp = CNVT_FROMHW(htransp, var->transp.length);
+ if (kspc) {
+ *red = hred;
+ *green = hgreen;
+ *blue = hblue;
+ if (transp)
+ *transp = htransp;
+ } else {
+ put_user(hred, red);
+ put_user(hgreen, green);
+ put_user(hblue, blue);
+ if (transp)
+ put_user(htransp, transp);
+ }
+ red++;
+ green++;
+ blue++;
+ if (transp)
+ transp++;
+ }
+ return 0;
+}
+
+
+static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+ int kspc)
+{
+ int i, start;
+ unsigned short *red, *green, *blue, *transp;
+ unsigned int hred, hgreen, hblue, htransp;
+
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ start = cmap->start;
+
+ if (start < 0)
+ return -EINVAL;
+ for (i = 0; i < cmap->len; i++) {
+ if (kspc) {
+ hred = *red;
+ hgreen = *green;
+ hblue = *blue;
+ htransp = transp ? *transp : 0;
+ } else {
+ get_user(hred, red);
+ get_user(hgreen, green);
+ get_user(hblue, blue);
+ if (transp)
+ get_user(htransp, transp);
+ else
+ htransp = 0;
+ }
+ hred = CNVT_TOHW(hred, var->red.length);
+ hgreen = CNVT_TOHW(hgreen, var->green.length);
+ hblue = CNVT_TOHW(hblue, var->blue.length);
+ htransp = CNVT_TOHW(htransp, var->transp.length);
+ red++;
+ green++;
+ blue++;
+ if (transp)
+ transp++;
+ if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp))
+ return 0;
+ }
+ return 0;
+}
+
+
+static void do_install_cmap(int con)
+{
+ if (con != currcon)
+ return;
+ if (disp[con].cmap.len)
+ do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1);
+ else
+ do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel),
+ &disp[con].var, 1);
+}
+
+
+static void memcpy_fs(int fsfromto, void *to, void *from, int len)
+{
+ switch (fsfromto) {
+ case 0:
+ memcpy(to, from, len);
+ return;
+ case 1:
+ copy_from_user(to, from, len);
+ return;
+ case 2:
+ copy_to_user(to, from, len);
+ return;
+ }
+}
+
+
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+{
+ int size;
+ int tooff = 0, fromoff = 0;
+
+ if (to->start > from->start)
+ fromoff = to->start-from->start;
+ else
+ tooff = from->start-to->start;
+ size = to->len-tooff;
+ if (size > from->len-fromoff)
+ size = from->len-fromoff;
+ if (size < 0)
+ return;
+ size *= sizeof(unsigned short);
+ memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
+ memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
+ memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
+ if (from->transp && to->transp)
+ memcpy_fs(fsfromto, to->transp+tooff,
+ from->transp+fromoff, size);
+}
+
+
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+ int size = len*sizeof(unsigned short);
+
+ if (cmap->len != len) {
+ if (cmap->red)
+ kfree(cmap->red);
+ if (cmap->green)
+ kfree(cmap->green);
+ if (cmap->blue)
+ kfree(cmap->blue);
+ if (cmap->transp)
+ kfree(cmap->transp);
+ cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+ cmap->len = 0;
+ if (!len)
+ return 0;
+ if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ if (transp) {
+ if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+ return -1;
+ } else
+ cmap->transp = NULL;
+ }
+ cmap->start = 0;
+ cmap->len = len;
+ copy_cmap(get_default_colormap(len), cmap, 0);
+ return 0;
+}
+
+
+/*
+ * Get the Fixed Part of the Display
+ */
+
+static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+{
+ struct retz3_fb_par par;
+ int error = 0;
+
+ if (con == -1)
+ retz3_fb_get_par(&par);
+ else
+ error = fbhw->decode_var(&disp[con].var, &par);
+ return(error ? error : fbhw->encode_fix(fix, &par));
+}
+
+
+/*
+ * Get the User Defined Part of the Display
+ */
+
+static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con)
+{
+ struct retz3_fb_par par;
+ int error = 0;
+
+ if (con == -1) {
+ retz3_fb_get_par(&par);
+ error = fbhw->encode_var(var, &par);
+ } else
+ *var = disp[con].var;
+ return error;
+}
+
+
+static void retz3_fb_set_disp(int con)
+{
+ struct fb_fix_screeninfo fix;
+
+ retz3_fb_get_fix(&fix, con);
+ if (con == -1)
+ con = 0;
+ disp[con].screen_base = (unsigned char *)fix.smem_start;
+ disp[con].visual = fix.visual;
+ disp[con].type = fix.type;
+ disp[con].type_aux = fix.type_aux;
+ disp[con].ypanstep = fix.ypanstep;
+ disp[con].ywrapstep = fix.ywrapstep;
+ disp[con].can_soft_blank = 1;
+ disp[con].inverse = z3fb_inverse;
+}
+
+
+/*
+ * Set the User Defined Part of the Display
+ */
+
+static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con)
+{
+ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+ if ((err = do_fb_set_var(var, con == currcon)))
+ return err;
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+ oldxres = disp[con].var.xres;
+ oldyres = disp[con].var.yres;
+ oldvxres = disp[con].var.xres_virtual;
+ oldvyres = disp[con].var.yres_virtual;
+ oldbpp = disp[con].var.bits_per_pixel;
+ disp[con].var = *var;
+ if (oldxres != var->xres || oldyres != var->yres ||
+ oldvxres != var->xres_virtual ||
+ oldvyres != var->yres_virtual ||
+ oldbpp != var->bits_per_pixel) {
+ retz3_fb_set_disp(con);
+ (*fb_info.changevar)(con);
+ alloc_cmap(&disp[con].cmap, 0, 0);
+ do_install_cmap(con);
+ }
+ }
+ var->activate = 0;
+ return 0;
+}
+
+
+/*
+ * Get the Colormap
+ */
+
+static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+ if (con == currcon) /* current console? */
+ return(do_fb_get_cmap(cmap, &disp[con].var, kspc));
+ else if (disp[con].cmap.len) /* non default colormap? */
+ copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel),
+ cmap, kspc ? 0 : 2);
+ return 0;
+}
+
+
+/*
+ * Set the Colormap
+ */
+
+static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+ int err;
+
+ if (!disp[con].cmap.len) { /* no colormap allocated? */
+ if ((err = alloc_cmap(&disp[con].cmap,
+ 1<<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;
+}
--- /dev/null
+/*
+ * 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 */
.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
-/* $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
/* 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. */
/* 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();
}
}
-#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)
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]++;
irq_enter(cpu, irq);
floppy_interrupt(irq, dev_id, regs);
irq_exit(cpu, irq);
- disable_pil_irq(irq);
+ enable_pil_irq(irq);
}
#endif
*/
unsigned long probe_irq_on(void)
{
- return 0;
+ return 0;
}
int probe_irq_off(unsigned long mask)
{
- return 0;
+ return 0;
}
/* djhr
-/* $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)
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);
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
-/* $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.
*
.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. */
-/* $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)
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
-# $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..
#
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
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
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... */
add %i1, %i2, %i1
2:
mov %i1, %o0
+6:
call C_LABEL(__bzero)
mov %i3, %o1
1:
.section __ex_table,#alloc
.align 4
.word 5b,2
+ .word 6b,2
--- /dev/null
+/* $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
-/* $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)
-# $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
# 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
-/* $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)
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
-/* $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)
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
{
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);
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;
}
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)
void free_initmem (void)
{
- extern char __init_begin, __init_end;
unsigned long addr;
addr = (unsigned long)(&__init_begin);
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)
-/* $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)
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;
} 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;
* 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)
{
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);
}
}
-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);
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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
* 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;
--- /dev/null
+/* $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
-# $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.
#
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
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
-# $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
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
-/* $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)
#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>
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);
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)
{
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;
}
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));
}
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));
}
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)
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));
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)
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));
}
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);
}
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);
}
asmlinkage int sys32_bind(int fd, u32 umyaddr, int addrlen)
{
+ /* sockaddr is the same :)) */
return sys_bind(fd, (struct sockaddr *)A(umyaddr), addrlen);
}
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);
}
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);
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)))
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;
+}
-/* $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:
*
.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. */
.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
.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. */
#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; \
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
-/* $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)
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)
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
*/
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);
/*
- * 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
/*
* 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
* 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>
#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)
{
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);
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);
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/poll.h>
+#include <linux/init.h>
#include <asm/setup.h>
#include <asm/system.h>
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;
#endif
#include <linux/miscdevice.h>
#include <linux/apm_bios.h>
+#include <linux/init.h>
EXPORT_SYMBOL(apm_register_callback);
EXPORT_SYMBOL(apm_unregister_callback);
#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;
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;
}
#endif
-void apm_bios_init(void)
+__initfunc(void apm_bios_init(void))
{
unsigned short bx;
unsigned short cx;
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/poll.h>
+#include <linux/init.h>
#include <asm/setup.h>
#include <asm/atarikb.h>
ATARIMOUSE_MINOR, "atarimouse", &atari_mouse_fops
};
-int atari_mouse_init(void)
+__initfunc(int atari_mouse_init(void))
{
mouse.active = 0;
mouse.ready = 0;
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/poll.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
};
-int atixl_busmouse_init(void)
+__initfunc(int atixl_busmouse_init(void))
{
unsigned char a,b,c;
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/ioport.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
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;
#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++;
* number, and identifies which options were configured into this
* driver.
*/
-static void
+static inline void
show_version(void)
{
printk("Cyclom driver %s\n",rcsid);
/* 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;
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;
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)
* 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;
* 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;
/* 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,
/* 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,
--- /dev/null
+/*
+ * 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 */
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/io.h>
* 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);
/*
* The serial driver boot-time initialization code!
*/
-int espserial_init(void)
+__initfunc(int espserial_init(void))
{
int i, offset;
int region_start;
/* 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);
#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>
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);
* 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;
* board types.
*/
-static int stli_initecp(stlibrd_t *brdp)
+static inline int stli_initecp(stlibrd_t *brdp)
{
cdkecpsig_t sig;
cdkecpsig_t *sigsp;
* 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;
* 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);
* 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;
* 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;
* can find.
*/
-static int stli_initbrds()
+static inline int stli_initbrds()
{
stlibrd_t *brdp, *nxtbrdp;
stlconf_t *confp;
/*****************************************************************************/
-int stli_init()
+__initfunc(int stli_init())
{
printk(KERN_INFO "%s: version %s\n", stli_drvname, stli_drvversion);
#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>
}
}
-int kbd_init(void)
+__initfunc(int kbd_init(void))
{
int i;
struct kbd_struct kbd0;
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/random.h>
+#include <linux/init.h>
#include <asm/bitops.h>
}
}
-int kbd_init(void)
+__initfunc(int kbd_init(void))
{
int i;
struct kbd_struct kbd0;
outb(data, address); /* write out the data*/
}
-static int initialize_kbd(void)
+__initfunc(static int initialize_kbd(void))
{
unsigned long flags;
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
return 0;
}
-int lp_init(void)
+__initfunc(int lp_init(void))
{
int count = 0;
struct parport *pb;
#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
static struct proc_dir_entry *proc_misc;
#endif
-int misc_init(void)
+__initfunc(int misc_init(void))
{
#ifndef MODULE
#ifdef CONFIG_PROC_FS
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/poll.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
MICROSOFT_BUSMOUSE, "msbusmouse", &ms_bus_mouse_fops
};
-int ms_bus_mouse_init(void)
+__initfunc(int ms_bus_mouse_init(void))
{
int mse_byte, i;
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/watchdog.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>
* 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;
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))
return(PCWD_REVISION_C);
}
-static int send_command(int cmd)
+__initfunc(static int send_command(int cmd))
{
int i;
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;
#ifdef MODULE
int init_module(void)
#else
-int pcwatchdog_init(void)
+__initfunc(int pcwatchdog_init(void))
#endif
{
int i, found = 0;
#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 */
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);
* 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;
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/poll.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
PSMOUSE_MINOR, "ps2aux", &psaux_fops
};
-int psaux_init(void)
+__initfunc(int psaux_init(void))
{
int qp_found = 0;
* 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 */
#include <linux/string.h>
#include <linux/major.h>
#include <linux/mm.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/system.h>
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));
#include <linux/malloc.h>
#include <linux/random.h>
#include <linux/poll.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
init_std_data(&random_state);
}
-void rand_initialize(void)
+__initfunc(void rand_initialize(void))
{
int i;
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;
#include <linux/serial.h>
#include <linux/fcntl.h>
#include <linux/major.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
}
/* 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;
}
/* 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;
bp->irq = 0;
- if (rc_check_io_range(bp))
+ if (rc_check_io_range(bp))
return 1;
/* Are the I/O ports here ? */
}
}
-static int rc_init_drivers(void)
+static inline int rc_init_drivers(void)
{
int error;
int i;
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
/*
* This routine must be called by kernel at boot time
*/
-int riscom8_init(void)
+__initfunc(int riscom8_init(void))
{
int i;
int found = 0;
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/mc146818rtc.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
&rtc_fops
};
-int rtc_init(void)
+__initfunc(int rtc_init(void))
{
unsigned long flags;
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/malloc.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/io.h>
* 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
/*
* The serial driver boot-time initialization code!
*/
-int rs_init(void)
+__initfunc(int rs_init(void))
{
int i;
struct serial_state * state;
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);
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
#define WATCHDOG_MINOR 130
&softdog_fops
};
-void watchdog_init(void)
+__initfunc(void watchdog_init(void))
{
misc_register(&softdog_miscdev);
init_timer(&watchdog_ticktock);
#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>
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);
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
/*
* interrupt across multiple boards.
*/
-static int stl_mapirq(int irq)
+__initfunc(static int stl_mapirq(int irq))
{
int rc, i;
* 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;
* 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;
* 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;
* 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;
#ifdef CONFIG_PCI
-static int stl_findpcibrds()
+static inline int stl_findpcibrds()
{
stlbrd_t *brdp;
unsigned char busnr, devnr, irq;
* since the initial search and setup is too different.
*/
-static int stl_initbrds()
+static inline int stl_initbrds()
{
stlbrd_t *brdp;
stlconf_t *confp;
/*****************************************************************************/
-int stl_init(void)
+__initfunc(int stl_init(void))
{
printk(KERN_INFO "%s: version %s\n", stl_drvname, stl_drvversion);
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#endif
+#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/system.h>
* 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!");
#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"
NULL /* fsync */
};
-int vcs_init(void)
+__initfunc(int vcs_init(void))
{
int error;
#include <asm/system.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
+#include <linux/init.h>
static int wdt_is_open=0;
#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)
{
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))
return 0;
}
-#endif
#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
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;
* 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];
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/system.h>
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
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;
#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;
/* 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;
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/init.h>
#include "3c505.h"
* 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 */
*
******************************************************/
-static void elp_init(struct device *dev)
+static inline void elp_init(struct device *dev)
{
elp_device *adapter = dev->priv;
* 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;
* Called only by eplus_probe
*************************************************************/
-static int elp_autodetect(struct device *dev)
+__initfunc(static int elp_autodetect(struct device *dev))
{
int idx = 0;
* 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;
#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 */
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};
/*
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;
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;
#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>
\f
-int el3_probe(struct device *dev)
+__initfunc(int el3_probe(struct device *dev))
{
short lrs_state = 0xff, i;
ushort ioaddr, irq, if_port;
/* 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. */
}
/* 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;
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/init.h>
#include "3c523.h"
/*
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 *****************************
* 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;
}
/*****************************************************************/
-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;
} /* 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;
#include <linux/ioport.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#ifdef CONFIG_PCI
#include <linux/pci.h>
#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[] = {
}
#else
-int tc59x_probe(struct device *dev)
+__initfunc(int tc59x_probe(struct device *dev))
{
int cards_found = 0;
}
#endif /* not MODULE */
-static int vortex_scan(struct device *dev)
+__initfunc(static int vortex_scan(struct device *dev))
{
int cards_found = 0;
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;
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;
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
}
/* 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);
#include <linux/malloc.h>
#include <linux/string.h>
#include <linux/config.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#include <asm/io.h>
}
-int a2065_probe(struct device *dev)
+__initfunc(int a2065_probe(struct device *dev))
{
int key1, key2 = 0;
struct ConfigDev *cd;
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/io.h>
*/
/* 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"};
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;
return ENODEV;
}
-static int ac_probe1(int ioaddr, struct device *dev)
+__initfunc(static int ac_probe1(int ioaddr, struct device *dev))
{
int i;
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#include <asm/io.h>
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;
}
#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
#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>
* 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");
*
* 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]);
/* 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;
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/skbuff.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#include <asm/amigaints.h>
}
-int ariadne_probe(struct device *dev)
+__initfunc(int ariadne_probe(struct device *dev))
{
int key;
struct ConfigDev *cd;
#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 */
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;
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;
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;
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/timer.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
/* 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 */
#include <linux/delay.h>
#include <linux/timer.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
/* 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;
#include <linux/errno.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#include <asm/setup.h>
#include <asm/irq.h>
}
-int atarilance_probe( struct device *dev )
+__initfunc(int atarilance_probe( struct device *dev ))
{ int i;
static int found = 0;
/* 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;
}
-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;
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
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;
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;
}
/* 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;
* 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;
#include <linux/netdevice.h>
#include <linux/hdlcdrv.h>
#include <linux/baycom.h>
+#include <linux/init.h>
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
-int baycom_init(void)
+__initfunc(int baycom_init(void))
{
int i, j, found = 0;
char set_hw = 1;
* * indicates sofware DCD
*/
-void baycom_setup(char *str, int *ints)
+__initfunc(void baycom_setup(char *str, int *ints))
{
int i;
#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>
* 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;
#include <asm/bitops.h>
#include <asm/io.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
/* 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;
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;
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 -
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;
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;
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;
\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;
#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>
** 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;
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;
** 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;
#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;
** 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;
** 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;
return new;
}
-static int
-de4x5_dev_index(char *s)
+__initfunc(static int
+de4x5_dev_index(char *s))
{
int i=0, j=0;
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;
#include <linux/ptrace.h>
#include <asm/system.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
*/
}
-int
-de600_probe(struct device *dev)
+__initfunc(int
+de600_probe(struct device *dev))
{
int i;
static struct net_device_stats de600_netstats;
#include <linux/ptrace.h>
#include <asm/system.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
*
* 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;
*/
#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;
return data;
}
-static int
-read_eeprom(struct device *dev)
+__initfunc(static int
+read_eeprom(struct device *dev))
{
unsigned short wrd;
#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>
* the device structure.
*/
-int dfx_probe(
+__initfunc(int dfx_probe(
struct device *dev
- )
+ ))
{
int i; /* used in for loops */
* 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 */
* enabled yet.
*/
-void dfx_bus_init(
+__initfunc(void dfx_bus_init(
struct device *dev
- )
+ ))
{
DFX_board_t *bp = (DFX_board_t *)dev->priv;
* 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 */
* 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;
#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>
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 */
\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;
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;
/*
** 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;
** 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;
** 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;
** 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;
return dev;
}
-static int
-depca_dev_index(char *s)
+__initfunc(static int
+depca_dev_index(char *s))
{
int i=0, j=0;
** 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;
** 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 {
** 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;
/*
** 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;
#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>
/*
* 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;
/*
* 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;
return (0);
}
-int
-dgrs_initclone(struct device *dev)
+__initfunc(int
+dgrs_initclone(struct device *dev))
{
DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv;
int i;
return (0);
}
-static int
+__initfunc(static int
dgrs_found_device(
struct device *dev,
int io,
int irq,
ulong plxreg,
ulong plxdma
-)
+))
{
DGRS_PRIV *priv;
int i;
/*
* 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;
*/
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)
{
#else
-int
-dgrs_probe(struct device *dev)
+__initfunc(int
+dgrs_probe(struct device *dev))
{
int cards_found;
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,
#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>
return(0);
}
-int dlci_setup(void)
+__initfunc(int dlci_setup(void))
{
int i;
#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>
{
}
-int dummy_init(struct device *dev)
+__initfunc(int dummy_init(struct device *dev))
{
/* Initialize the device structure. */
dev->hard_start_xmit = dummy_xmit;
#ifdef MODULE
-static int dummy_probe(struct device *dev)
+__initfunc(static int dummy_probe(struct device *dev))
{
dummy_init(dev);
return 0;
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/system.h>
station address).
*/
-int e2100_probe(struct device *dev)
+__initfunc(int e2100_probe(struct device *dev))
{
int *port;
int base_addr = dev->base_addr;
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;
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
/* 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 */
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;
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;
#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>
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;
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;
#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;
}
}
#else /* not MODULE */
-int eepro100_probe(struct device *dev)
+__initfunc(int eepro100_probe(struct device *dev))
{
int cards_found = 0;
#include <asm/dma.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/if.h>
---------------------------------------------------------
*/
-int eql_init(struct device *dev)
+__initfunc(int eql_init(struct device *dev))
{
static unsigned version_printed = 0;
/* static unsigned num_masters = 0; */
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/system.h>
#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
* 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;
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;
#include <linux/malloc.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#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
};
{"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;
}
#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;
#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>
\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;
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;
/*
** 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;
** 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;
** 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;
** 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;
return dev;
}
-static int
-ewrk3_dev_index(char *s)
+__initfunc(static int
+ewrk3_dev_index(char *s))
{
int i=0, j=0;
/*
** 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;
** ethernet address for later read out.
*/
-static int DevicePresent(u_long iobase)
+__initfunc(static int DevicePresent(u_long iobase))
{
union {
struct {
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;
/*
** 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;
#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>
#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 */
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;
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;
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++;
}
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/io.h>
#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};
/*
{"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;
#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;
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/io.h>
#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
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.
{"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;
}
#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;
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/bios32.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#include <asm/io.h>
* 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;
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;
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#include <asm/io.h>
#endif
-int hydra_probe(struct device *dev)
+__initfunc(int hydra_probe(struct device *dev))
{
struct hydra_private *priv;
u32 board;
#include <linux/netdevice.h>
#include <linux/trdevice.h>
#include <linux/stddef.h>
+#include <linux/init.h>
#include <net/checksum.h>
#include <asm/io.h>
#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)
{
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)
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)
* 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;
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;
/* 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;
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;
#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>
#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
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;
return 0;
}
-void lance_probe1(int ioaddr)
+__initfunc(void lance_probe1(int ioaddr))
{
struct device *dev;
struct lance_private *lp;
#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};
return 0;
}
-static int lapbeth_dev_init(struct device *dev)
+__initfunc(static int lapbeth_dev_init(struct device *dev))
{
return 0;
}
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/in.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
}
/* 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;
#include <asm/bitops.h>
#include <asm/dma.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
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;
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/major.h>
+#include <linux/init.h>
#include <linux/timer.h>
}
/* Initialize AX25 control device -- register AX25 line discipline */
-int mkiss_init_ctrl_dev(void)
+__initfunc(int mkiss_init_ctrl_dev(void))
{
int status;
/* * Init MKISS driver * */
/* ******************************************************************** */
-static int mkiss_init(void)
+__initfunc(static int mkiss_init(void))
{
memset(&mkiss_driver, 0, sizeof(struct tty_driver));
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/bios32.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/io.h>
/* 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},
#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? */
* the card.
*/
-int ne_probe(struct device *dev)
+__initfunc(int ne_probe(struct device *dev))
{
int base_addr = dev ? dev->base_addr : 0;
#endif
#ifdef CONFIG_PCI
-static int ne_probe_pci(struct device *dev)
+__initfunc(static int ne_probe_pci(struct device *dev))
{
int i;
}
#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];
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#include <asm/io.h>
/**********************************************
* probe the ni5210-card
*/
-int ni52_probe(struct device *dev)
+__initfunc(int ni52_probe(struct device *dev))
{
#ifndef MODULE
int *port;
return ENODEV;
}
-static int ni52_probe1(struct device *dev,int ioaddr)
+__initfunc(static int ni52_probe1(struct device *dev,int ioaddr))
{
int i,size;
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]) {
#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>
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;
#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};
/*
* 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;
#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>
#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;
\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;
/* 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;
#include <linux/timer.h>
#include <linux/if_arp.h>
#include <linux/pi2.h>
+#include <linux/init.h>
#include "z8530.h"
#include <net/ax25.h>
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 */
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 */
/* 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;
}
-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");
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/lp.h>
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
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;
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;
/* 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");
#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)
* 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;
#include <linux/timer.h>
#include <linux/if_arp.h>
#include <linux/pt.h>
+#include <linux/init.h>
#include "z8530.h"
#include <net/ax25.h>
-int pt_init(void)
+__initfunc(int pt_init(void))
{
int *port;
int ioaddr = 0;
/*
* 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;
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)
#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"
/* * Init SCC driver * */
/* ******************************************************************** */
-int scc_init (void)
+__initfunc(int scc_init (void))
{
int chip, chan, k, result;
char devname[10];
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/bitops.h>
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,
return(&flp->stats);
}
-int sdla_init(struct device *dev)
+__initfunc(int sdla_init(struct device *dev))
{
struct frad_local *flp;
return(0);
}
-void sdla_setup(void)
+__initfunc(void sdla_setup(void))
{
printk("%s.\n", version);
register_frad(devname);
#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. */
* 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
{
#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_
* 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
{
#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_
* 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
{
#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)))
#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);
#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>
/* 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 */
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;
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;
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
+#include <linux/init.h>
#include <net/dst.h>
#include "shaper.h"
* Add a shaper device to the system
*/
-int shaper_probe(struct device *dev)
+__initfunc(int shaper_probe(struct device *dev))
{
/*
* Set up the shaper.
#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>
#else /* MODULE */
-void slhc_install(void)
+__initfunc(void slhc_install(void))
{
}
#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>
#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;
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/system.h>
#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;
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/system.h>
#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);
{"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;
}
#endif
-int ultra_probe1(struct device *dev, int ioaddr)
+__initfunc(int ultra_probe1(struct device *dev, int ioaddr))
{
int i;
int checksum = 0;
#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>
.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};
|
---------------------------------------------------------------------------
*/
-int smc_init(struct device *dev)
+__initfunc(int smc_init(struct device *dev))
{
int i;
int base_addr = dev ? dev->base_addr : 0;
. 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;
.---------------------------------------------------------------------
*/
-static int smc_probe( int ioaddr )
+__initfunc(static int smc_probe( int ioaddr ))
{
unsigned int bank;
word revision_register;
. 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;
#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>
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;
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;
}
}
-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'};
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;
#include <linux/in.h>
#include <net/ip.h>
#include <linux/if_arp.h>
+#include <linux/init.h>
/*#define TUNNEL_DEBUG*/
* 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;
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/system.h>
#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);
{"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;
}
#endif
-int wd_probe1(struct device *dev, int ioaddr)
+__initfunc(int wd_probe1(struct device *dev, int ioaddr))
{
int i;
int checksum = 0;
#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 {
#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;
#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>
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;
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"),
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 */
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/* 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";
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;
#include <linux/ioport.h>
#include <linux/time.h>
#include <linux/blk.h>
+#include <linux/init.h>
#undef current
#include "scsi.h"
* Returns : 0 on success, -1 on failure.
*/
-static int
+static inline int
NCR53c7x0_init (struct Scsi_Host *host) {
NCR53c7x0_local_declare();
int i, ccf, expected_ccf;
*
*/
-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];
*
*/
-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
*
*/
-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 */
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/blk.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/system.h>
#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);
*
* 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;
*
* 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;
*
* 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 */
* 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;
#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>
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.
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++)
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 *)
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;
/*
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)
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 =
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;
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
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;
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;
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;
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;
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];
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;
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;
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;
}
#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)
*/
-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;
* 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"
*
*/
-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;
#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>
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 },
}
#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;
}
/* 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;
outb(SYNC_MODE, SYNCOFF); /* synchronous mode */
}
-void calc_port_addr()
+__initfunc(void calc_port_addr())
{
/* Control Register Set 0 */
TC_LSB = (port_base+0x00);
#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>
* 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;
/*
* 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;
/*
* 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;
*
* 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;
/*
* 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;
*
* 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;
*
* 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;
/*
* 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;
/*
* Read a PCI configuration byte.
*/
-uchar
+__initfunc(uchar
DvcReadPCIConfigByte(
ASC_DVC_VAR asc_ptr_type *asc_dvc,
- ushort offset )
+ ushort offset ))
{
PCI_DATA pciData;
/*
* 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;
* 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 ;
return (sc);
}
-uchar
+__initfunc(uchar
AscGetChipVersion(
PortAddr iop_base,
ushort bus_type
-)
+))
{
if ((bus_type & ASC_IS_EISA) != 0) {
PortAddr eisa_iop;
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;
return (chksum);
}
-int
+__initfunc(int
AscFindSignature(
PortAddr iop_base
-)
+))
{
ushort sig_word;
if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
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) {
return (0);
}
-PortAddr
+__initfunc(PortAddr
AscSearchIOPortAddr11(
PortAddr s_addr
-)
+))
{
int i;
PortAddr iop_base;
};
#endif
-void
+__initfunc(void
AscSetISAPNPWaitForKey(
- void)
+ void))
{
outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
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,
return;
}
-ulong
+__initfunc(ulong
AscGetEisaProductID(
PortAddr iop_base
-)
+))
{
PortAddr eisa_iop;
ushort product_id_high, product_id_low;
return (product_id);
}
-PortAddr
+__initfunc(PortAddr
AscSearchIOPortAddrEISA(
PortAddr iop_base
-)
+))
{
ulong eisa_product_id;
if (iop_base == 0) {
return (speed_value);
}
-ushort
+__initfunc(ushort
AscInitGetConfig(
ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
+))
{
ushort warn_code;
warn_code = 0;
return (warn_code);
}
-ushort
+__initfunc(ushort
AscInitSetConfig(
ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
+))
{
ushort warn_code;
warn_code = 0;
return (warn_code);
}
-ushort
+__initfunc(ushort
AscInitFromAscDvcVar(
ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
+))
{
PortAddr iop_base;
ushort cfg_msw;
return (warn_code);
}
-ushort
+__initfunc(ushort
AscInitAsc1000Driver(
ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
+))
{
ushort warn_code;
PortAddr iop_base;
return (warn_code);
}
-ushort
+__initfunc(ushort
AscInitAscDvcVar(
ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
+))
{
int i;
PortAddr iop_base;
* sections.
*/
#define PAUSE_SEQUENCER(p) \
+ synchronize_irq(); \
outb(p->pause, HCNTRL + p->base); \
while ((inb(HCNTRL + p->base) & PAUSE) == 0) \
; \
#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
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))
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))
*
*/
-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)
*/
-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;
#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",
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))
*
*/
-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:
* 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);
}
* 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);
}
*
*/
-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;
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
+#include <linux/init.h>
#include "scsi.h"
return 0;
}
-unsigned int scsi_init()
+__initfunc(unsigned int scsi_init(void))
{
static int called = 0;
int i, pcount;
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);
}
/*
** 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,
#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",
* 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
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))
*
*/
-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 );
*
*/
-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;
* 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;
*
*/
-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)
*
*/
-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;
#include <linux/blk.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/irq.h>
* 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;
#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",
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))
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))
static const struct signature {
const char *string;
int offset;
-} signatures[] = {
+} signatures[] __initdata = {
{"TSROM: SCSI BIOS, Version 1.12", 0x36},
};
*
*/
-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)
*
*/
-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;
#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"
/* 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>
#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>
#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)
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;
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
#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
}
/* 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;
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;
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++;
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;
}
}
- /* 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;
}
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)
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)
/* 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)
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;
}
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--;
}
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)
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;
}
}
-
-/* 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 ||
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;
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;
}
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;
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) {
return bh;
}
- while(!free_list[isize]) {
+ while(!free_list[isize])
refill_freelist(size);
- }
if (find_buffer(dev,block,size))
goto 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);
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)
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 &&
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);
}
}
}
{
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);
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))
{
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));
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..
*/
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);
/*
* 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);
}
}
}
}
-
-
-/*
- * 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:
- */
* (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
#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;
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)
{
}
}
-/*
- * 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;
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)
* 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;
}
#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);
if (!callable)
goto out;
callable = 0;
-
+
device_setup();
binfmt_setup();
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 */
/*
- * 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;
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)
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))
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;
}
# 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[];
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; /* ??? */
if (res)
kfree(res);
+ unlock_kernel ();
return err;
}
static unsigned long old_syscallvec;
+extern int (*do_nfsservctl)(int, void *, void *);
+
/*
* Initialize the module
*/
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;
}
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
/*
* The main request loop
*/
- do {
+ for (;;) {
/*
* Find a socket with data available and call its
* recvfrom routine.
/* Unlock export hash tables */
exp_unlock();
- } while (err >= 0);
+ }
if (err != -EINTR) {
printk(KERN_WARNING "nfsd: terminating on error %d\n", -err);
#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
/* 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;
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);
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
#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))
--- /dev/null
+/*
+ * 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 */
#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)
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);
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;
}
}
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;
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);
#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_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))
--- /dev/null
+/*
+ * 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) */
--- /dev/null
+#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 */
--- /dev/null
+#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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
+++ /dev/null
-/*
- * 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 */
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]--)
-/* $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
--- /dev/null
+/* $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";
-/* $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)
* 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];
"i" (ASI_M_MXCC));
}
+#endif /* !__ASSEMBLY__ */
+
#endif /* !(_SPARC_MXCC_H) */
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
* 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;
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); \
#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) \
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) \
#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_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)
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)
"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)
-/* $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
{
__asm__ __volatile__("
wr %0, 0x0, %%psr
- nop
- nop
- nop
+ nop; nop; nop
" : /* no outputs */
: "r" (__orig_psr)
: "memory", "cc");
__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");
__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");
xorcc %1, %2, %%g0
be 1f
nop
- wr %0, %4, %%psr
+ wr %0, %4, %%psr
nop
nop
nop
__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
-/* $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" : :
return val;
}
+#endif /* !__ASSEMBLY__ */
+
#endif /* !(_SPARC_VIKING_H) */
--- /dev/null
+/* $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";
-/* $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
#ifndef __ASSEMBLY__
typedef unsigned long sigset_t;
-typedef unsigned int sigset32_t;
+typedef unsigned int sigset_t32;
#ifdef __KERNEL__
#include <asm/sigcontext.h>
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 */
};
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) \
#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) 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__ */
-/* $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;
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];
-/* $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) \
/* 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
#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);
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 */
};
#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;
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;
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 */
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--;
}
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)
__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;
#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
#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
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
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 */
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 */
#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
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;
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);
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,
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
}
--- /dev/null
+/*
+ * 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 */
#endif /* IPV6 */
+
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 */
*/
__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
*/
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
*/
* write queue if we are doing
* fast retransmit
*/
-/*
- * pending events
- */
- __u8 pending;
-
/*
* Header prediction flags
* 0x5?10 << 16 + snd_wnd in net byte order
__u32 probes_out; /* unanswered 0 window probes */
struct open_request *syn_wait_queue;
+ struct open_request **syn_wait_last;
struct tcp_func *af_specific;
};
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,
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,
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)
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
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;
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 */
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;
/*
#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. */
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);
/*
* 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)
* 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 */
/*
#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
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;
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
switch (state) {
case TCP_ESTABLISHED:
- if (oldstate != TCP_ESTABLISHED) {
+ if (oldstate != TCP_ESTABLISHED)
tcp_statistics.TcpCurrEstab++;
- }
break;
case TCP_CLOSE:
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);
}
#endif /* _TCP_H */
-
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
kmem_cache_sizes_init();
vma_init();
buffer_init();
+ inode_init();
sock_init();
#if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
ipc_init();
}
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);
if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
return -EINVAL;
- lock_kernel();
add_wait_queue(¤t->wait_chldexit,&wait);
repeat:
- flag = retval = 0;
+ flag = 0;
+ read_lock(&tasklist_lock);
for (p = current->p_cptr ; p ; p = p->p_osptr) {
if (pid>0) {
if (p->pid != pid)
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);
continue;
}
}
+ read_unlock(&tasklist_lock);
if (flag) {
retval = 0;
if (options & WNOHANG)
retval = -ECHILD;
end_wait4:
remove_wait_queue(¤t->wait_chldexit,&wait);
- unlock_kernel();
return retval;
}
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++) {
if (flags & CLONE_PID)
return current->pid;
+
+ read_lock(&tasklist_lock);
repeat:
if ((++last_pid) & 0xffff8000)
last_pid=1;
p->session == last_pid)
goto repeat;
}
+ read_unlock(&tasklist_lock);
+
return last_pid;
}
memset((char *)&val, 0, sizeof(struct sysinfo));
- lock_kernel();
+ cli();
val.uptime = jiffies / HZ;
val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
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;
{
value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
value->tv_sec = jiffies / HZ;
- return;
}
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;
}
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;
}
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;
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);
*/
asmlinkage int sys_pause(void)
{
- lock_kernel();
current->state = TASK_INTERRUPTIBLE;
schedule();
- unlock_kernel();
return -ERESTARTNOHAND;
}
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;
/* And we'd better return too much than too little anyway */
if (it_old.it_value.tv_usec)
oldalarm++;
- unlock_kernel();
return oldalarm;
}
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;
}
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)
{
value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ);
value->tv_sec = jiffies / HZ;
- return;
}
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) {
int ret;
/* fill in "set" with signals pending but blocked. */
- lock_kernel();
+ spin_lock_irq(¤t->sigmask_lock);
ret = put_user(current->blocked & current->signal, set);
- unlock_kernel();
+ spin_unlock_irq(¤t->sigmask_lock);
return ret;
}
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;
priority = 1;
}
+ read_lock(&tasklist_lock);
for_each_task(p) {
if (!proc_sel(p, which, who))
continue;
else
p->priority = priority;
}
-out:
- unlock_kernel();
+ read_unlock(&tasklist_lock);
+
return -error;
}
{
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__
* 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) ||
current->fsgid = current->egid = egid;
else {
current->gid = old_rgid;
- goto out;
+ return -EPERM;
}
}
if (rgid != (gid_t) -1 ||
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;
{
int old_ruid;
int old_euid;
- int err = -EPERM;
- lock_kernel();
old_ruid = current->uid;
old_euid = current->euid;
if (ruid != (uid_t) -1) {
suser())
current->uid = ruid;
else
- goto out;
+ return -EPERM;
}
if (euid != (uid_t) -1) {
if ((old_ruid == euid) ||
current->fsuid = current->euid = euid;
else {
current->uid = old_ruid;
- goto out;
+ return -EPERM;
}
}
if (ruid != (uid_t) -1 ||
current->fsuid = current->euid;
if (current->euid != old_euid)
current->dumpable = 0;
- err = 0;
-out:
- unlock_kernel();
- return err;
+ return 0;
}
/*
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;
}
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;
}
{
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;
}
{
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;
}
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;
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)
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;
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__
* 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);
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;
}
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;
}
/*
*/
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;
}
/*
* 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:
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)
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;
}
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;
txc.stbcnt = pps_stbcnt;
sti();
- unlock_kernel();
+
return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state;
}
* 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;
*
* 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 */
#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>
} /* (4.6.1.2.3) */
}
-void br_init(void)
+__initfunc(void br_init(void))
{ /* (4.8.1) */
int port_no;
/* 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
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.
/*
* Add it to the "backlog" queue.
*/
-#if CONFIG_SKB_CHECK
- IS_SKB(skb);
-#endif
+
skb_queue_tail(&backlog,skb);
backlog_size++;
#include <linux/in.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/init.h>
#include <linux/net_alias.h>
* Net_alias initialisation called from net_dev_init().
*/
-void net_alias_init(void)
+__initfunc(void net_alias_init(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);
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;
}
}
* '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
*/
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 */
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;
}
/* 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) {
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;
* Allocate the copy buffer
*/
- IS_SKB(skb);
-
n=alloc_skb(skb->end - skb->head, priority);
if(n==NULL)
return NULL;
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;
n->stamp=skb->stamp;
n->destructor = NULL;
n->security=skb->security;
- IS_SKB(n);
return n;
}
* 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;
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;
n->destructor = NULL;
n->security=skb->security;
- IS_SKB(n);
return n;
}
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");
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");
struct iphdr *iph;
int ip_length;
- IS_SKB(dest);
eth=(struct ethhdr *)src;
if(eth->h_proto!=htons(ETH_P_IP))
{
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);
}
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;
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);
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);
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);
{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 },
*
* 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>
{
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;
}
/*
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)
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;
}
/*
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);
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--
* 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);
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;
int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
- switch(cmd)
- {
-
+ switch(cmd) {
case TIOCINQ:
#ifdef FIXME /* FIXME: */
case FIONREAD:
}
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;
+ }
}
/*
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);
}
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);
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;
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;
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;
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);
}
copied += copy;
sk->write_seq += copy;
-
+
tcp_send_skb(sk, skb);
release_sock(sk);
return copied;
}
-
-
-
/*
* Send an ack if one is backlogged at this point. Ought to merge
* this with tcp_send_ack().
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)
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;
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.
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);
{
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;
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;
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
*/
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",
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;
}
break;
}
- if (sk->shutdown & RCV_SHUTDOWN)
- {
+ if (sk->shutdown & RCV_SHUTDOWN) {
sk->done = 1;
break;
}
- if (nonblock)
- {
+ if (nonblock) {
copied = -EAGAIN;
break;
}
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;
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))
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)
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
{
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:
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
* 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);
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);
+ }
}
case TCP_CLOSING:
case TCP_LAST_ACK:
return 1;
- }
+ };
return 0;
}
{
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);
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);
/* 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);
sk->prot->unhash(sk);
}
-
/*
* Wait for an incoming connection, avoid race
* conditions. This must be called with the socket locked.
return req;
}
-
/*
* This will accept the next outstanding connection.
*
goto out;
}
-
/*
* Socket option code for TCP.
*/
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
*/
return 0;
default:
return(-ENOPROTOOPT);
- }
+ };
}
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;
break;
default:
return(-ENOPROTOOPT);
- }
+ };
if(put_user(len, optlen))
return -EFAULT;
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)
*
* 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>
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;
{
int m;
- /*
- * Delayed ACK time estimator.
- */
+ /* Delayed ACK time estimator. */
m = jiffies - tp->lrcvtime;
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;
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;
/*
* 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
*/
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;
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);
}
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;
break;
default:
sk->err = ECONNRESET;
- }
+ };
#ifdef CONFIG_TCP_RFC1337
/*
* Time wait assassination protection [RFC1337]
* 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;
}
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 */
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.
* 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:
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;
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;
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;
}
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
* 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)
{
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;
* 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;
kfree_skb(skb, FREE_WRITE);
}
- if (acked)
- {
+ if (acked) {
tp->retrans_head = NULL;
if (!sk->dead)
sk->write_space(sk);
}
-
return acked;
}
{
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));
}
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
* 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;
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
* 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.
*
* 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;
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",
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;
}
}
+ }
}
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);
}
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);
}
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);
- }
}
/*
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)
}
}
-
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;
*/
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);
/*
* 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);
}
}
- 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.
{
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
* Now that TTCP is starting to be used we ought to
* queue this data.
*/
-
return 0;
}
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;
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;
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:
* (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;
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)
* 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;
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)
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)
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;
}
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;
}
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;
*
* 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
*
* 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,
/* 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];
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)
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;
* 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;
{
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;
}
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.
*/
{
struct sk_buff *buff;
struct sk_buff *skb1;
- unsigned char *ptr;
int tmp;
struct tcphdr *t1;
struct rtable *rt;
if (sk->state != TCP_CLOSE)
return(-EISCONN);
- /*
- * Don't allow a double connect.
- */
-
+ /* Don't allow a double connect. */
if (sk->daddr)
return -EINVAL;
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);
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 ||
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);
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++;
{
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) {
{
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;
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;
}
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;
}
}
{
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));
}
/*
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;
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++;
}
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);
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;
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++;
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
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;
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;
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);
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);
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;
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,
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);
* 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) {
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);
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);
tcp_v4_send_reset(skb);
discard_it:
- /*
- * Discard frame
- */
+ /* Discard frame. */
kfree_skb(skb, FREE_READ);
ok:
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;
}
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)
tcp_v4_send_reset(skb);
discard_it:
- /*
- * Discard frame
- */
+ /* Discard frame. */
kfree_skb(skb, FREE_READ);
return 0;
}
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;
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;
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;
}
*
* 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);
}
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)
int nagle_check = 1;
int len;
- /*
- * RFC 1122 - section 4.2.3.4
+ /* RFC 1122 - section 4.2.3.4
*
* We must queue if
*
* 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);
+ }
}
/*
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;
}
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;
}
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);
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");
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
*/
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);
#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;
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);
- }
}
* 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);
* 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;
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;
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;
}
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,
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
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);
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;
- }
}
}
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;
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);
}
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;
}
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);
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);
}
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++;
}
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);
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.
*/
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++;
}
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));
}
{
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.
default:
printk(KERN_DEBUG "bug: unknown timer value\n");
- }
+ };
}
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)
break;
default:
printk(KERN_DEBUG "bug: unknown timer value\n");
- }
+ };
return 0;
}
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
/* 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
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;
}
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) {
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;
}
* 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);
}
}
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);
/* 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)
{
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) {
}
}
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));
}
/*
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.
* 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);
conn->expires = now + timeo;
tcp_synq_queue(tp, conn);
}
- } while (req != tp->syn_wait_queue);
+ } while (req);
}
sk = sk->next;
}
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;
}
}
- if (next != ~0UL)
- {
+ if (next != ~0UL) {
tcp_slow_timer.expires = now + next;
add_timer(&tcp_slow_timer);
}
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);
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;
}
*
* 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
struct ipv6_mib ipv6_statistics={0, };
struct packet_type ipv6_packet_type =
{
- 0,
+ __constant_htons(ETH_P_IPV6),
NULL, /* All devices */
ipv6_rcv,
NULL,
void ipv6_init(void)
{
- ipv6_packet_type.type = ntohs(ETH_P_IPV6);
-
dev_add_pack(&ipv6_packet_type);
#if defined(MODULE) && defined(CONFIG_SYSCTL)
* 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)
*
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;
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)
* 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,
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)
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;
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;
{
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 */
!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;
}
struct tcphdr *th;
struct sk_buff *buff;
struct sk_buff *skb1;
- __u8 *ptr;
+ int tmp;
int addr_type;
if (sk->state != TCP_CLOSE)
ipv6_addr_copy(&np->saddr, saddr);
}
+ /* FIXME: Need to do tcp_v6_unique_address() here! -DaveM */
+
/*
* Init variables
*/
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);
* 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);
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);
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)
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);
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;
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;
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));
}
* Unused
*/
- newsk->send_head = NULL;
-
newtp = &(newsk->tp_pinfo.af_tcp);
np = &newsk->net_pinfo.af_inet6;
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);
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);
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;
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) {
req->sk = sk;
break;
}
- } while ((req = req->dl_next) != tp->syn_wait_queue);
+ req = req->dl_next;
+ }
return sk;
}
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;
}
/* 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;
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;
* 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