diff -u --recursive --new-file v2.1.35/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.35/linux/Documentation/Changes Wed Apr 16 14:14:58 1997 +++ linux/Documentation/Changes Thu Apr 17 12:46:56 1997 @@ -29,7 +29,7 @@ Also, don't forget http://www.linuxhq.com/ for all your Linux kernel needs. -Last updated: April 15, 1997. +Last updated: April 17, 1997. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Minimal Requirements @@ -184,7 +184,7 @@ Binutils: ld -v Gnu C: gcc -v or gcc --version -Kbd: loadkeys -h +Kbd: dumpkeys -h Ld.so: ldd -v Libc: ls -l /lib/libc.so.* Libc++: ls -l /usr/lib/libg++.so.* @@ -249,7 +249,7 @@ The 2.1.34 release: ftp://ftp.redhat.com/pub/alphabits/modutils-2.1.34.tar.gz -ftp://ftp.kernel.org/pub/linux/kernel/modutils-2.1.34.tar.gz +ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.34.tar.gz Procps utilities ================ diff -u --recursive --new-file v2.1.35/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.35/linux/Documentation/Configure.help Wed Apr 16 14:14:58 1997 +++ linux/Documentation/Configure.help Tue Apr 22 15:32:00 1997 @@ -290,12 +290,13 @@ 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 @@ -3063,22 +3064,20 @@ Documentation/networking/net-modules.txt. The module will be called pt.o. -WaveLAN support +AT&T WaveLAN & DEC RoamAbout DS support CONFIG_WAVELAN - These are cards for wireless ethernet-like networking. Supported are - AT&T GIS and NCR WaveLAN cards. If you want to use a card of this - type under Linux, say Y and read the Ethernet-HOWTO, available via - ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. Some - more specific information is contained in - drivers/net/README.wavelan. This driver is also available as a - module ( = code which can be inserted in and removed from the - running kernel whenever you want). The module will be called - wavelan.o. If you want to compile it as a module, say M here and - read Documentation/modules.txt as well as - Documentation/networking/net-modules.txt. If you plan to use more - than one network card under linux, read the - Multiple-Ethernet-mini-HOWTO, available from - sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. + The Lucent Wavelan (formerly NCR and AT&T ; or DEC RoamAbout DS) + is a Radio LAN (wireless ethernet-like) at 900 MHz and 2.4 GHz. + This driver support the ISA version of the Wavelan. A driver for + the pcmcia hardware is available in David Hinds's pcmcia package. + This driver is fairly stable and may be compiled as a module + (wavelan.o). It implements many nice feature and the Wireless + Extensions (you must get the Wireless tools from the net). + For documentation, refer to : + o the wavelan man page, wireless tools man pages + o wavelan.p.h and the source code + o Ethernet-HOWTO, Multiple-Ethernet-mini-HOWTO, Module-HOWTO + o More documentation to come when I will have the time :-) HP PCLAN+ (27247B and 27252A) support CONFIG_HPLAN_PLUS diff -u --recursive --new-file v2.1.35/linux/Documentation/parport.txt linux/Documentation/parport.txt --- v2.1.35/linux/Documentation/parport.txt Sun Apr 13 10:18:20 1997 +++ linux/Documentation/parport.txt Thu Apr 17 14:48:53 1997 @@ -47,9 +47,13 @@ Also: * If you selected the device autoprobe at compile time, you can say -`lp=auto' on the kernel command line, and lp will create devices only -for those ports that seem to have printers attached. + `lp=auto' on the kernel command line, and lp will create devices + only for those ports that seem to have printers attached. * If you give PLIP the `timid' parameter, either with `plip=timid' on -the command line, or with `insmod plip timid=1' when using modules, it -will avoid any ports that seem to be in use by other devices. + the command line, or with `insmod plip timid=1' when using modules, + it will avoid any ports that seem to be in use by other devices. + + * If your BIOS allows you to engage "ECP mode", you may find that + your port's IRQ can be autoprobed, without having to specify any + parameters. diff -u --recursive --new-file v2.1.35/linux/Makefile linux/Makefile --- v2.1.35/linux/Makefile Wed Apr 16 14:14:59 1997 +++ linux/Makefile Thu Apr 17 14:48:53 1997 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 35 +SUBLEVEL = 36 ARCH := $(shell uname -m | sed s/i.86/i386/) @@ -118,7 +118,8 @@ FILESYSTEMS =fs/filesystems.a NETWORKS =net/network.a DRIVERS =drivers/block/block.a \ - drivers/char/char.a + drivers/char/char.a \ + drivers/pnp/pnp.a LIBS =$(TOPDIR)/lib/lib.a SUBDIRS =kernel drivers mm fs net ipc lib @@ -142,10 +143,6 @@ ifdef CONFIG_PCI DRIVERS := $(DRIVERS) drivers/pci/pci.a -endif - -ifdef CONFIG_PNP -DRIVERS := $(DRIVERS) drivers/pnp/pnp.a endif ifdef CONFIG_SBUS diff -u --recursive --new-file v2.1.35/linux/arch/alpha/Makefile linux/arch/alpha/Makefile --- v2.1.35/linux/arch/alpha/Makefile Mon Apr 7 11:35:28 1997 +++ linux/arch/alpha/Makefile Tue Apr 22 22:38:39 1997 @@ -10,21 +10,8 @@ NM := nm -B -ifdef CONFIG_CROSSCOMPILE -# enable this for linking under OSF/1: -LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N -else - elf=$(shell if $(LD) --help | grep elf64alpha >/dev/null; then echo yes; fi) - ifeq ($(elf),yes) - LINKFLAGS = -static -Ttext 0xfffffc0000310000 -N - else - LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N - endif -# GNU gcc/cc1/as can use pipes instead of temporary files -CFLAGS := $(CFLAGS) -pipe -endif - -CFLAGS := $(CFLAGS) -mno-fp-regs -ffixed-8 +LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N +CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8 HEAD := arch/alpha/kernel/head.o diff -u --recursive --new-file v2.1.35/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v2.1.35/linux/arch/alpha/kernel/entry.S Wed Apr 16 14:14:59 1997 +++ linux/arch/alpha/kernel/entry.S Tue Apr 22 22:49:38 1997 @@ -759,6 +759,6 @@ .quad sys_setfsuid, sys_setfsgid, sys_ustat, sys_statfs, sys_fstatfs .quad sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler, sys_sched_yield .quad sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, do_entSys /* sys_afs_syscall */, sys_newuname - .quad sys_nanosleep, sys_mremap, do_entSys, sys_setresuid, sys_getresuid + .quad sys_nanosleep, sys_mremap, sys_nfsservctl, sys_setresuid, sys_getresuid .quad sys_pciconfig_read, sys_pciconfig_write, sys_query_module .quad do_entSys, do_entSys diff -u --recursive --new-file v2.1.35/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- v2.1.35/linux/arch/alpha/kernel/osf_sys.c Tue Mar 4 10:25:23 1997 +++ linux/arch/alpha/kernel/osf_sys.c Tue Apr 22 22:38:40 1997 @@ -33,6 +33,7 @@ #include #include #include +#include extern int do_mount(kdev_t, const char *, const char *, char *, int, void *); extern int do_pipe(int *); @@ -171,7 +172,7 @@ int prio; /* - * We don't need to aquire the kernel lock here, because + * We don't need to acquire the kernel lock here, because * all of these operations are local. sys_getpriority * will get the lock as required.. */ @@ -193,7 +194,7 @@ } /* - * No need to aquire the kernel lock, we're local.. + * No need to acquire the kernel lock, we're local.. */ asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs) @@ -218,7 +219,7 @@ /* * This isn't strictly "local" any more and we should actually - * aquire the kernel lock. The "p_opptr" pointer might change + * acquire the kernel lock. The "p_opptr" pointer might change * if the parent goes away (or due to ptrace). But any race * isn't actually going to matter, as if the parent happens * to change we can happily return either of the pids. @@ -840,62 +841,91 @@ return err; } -asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer, unsigned long nbytes, +asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer, + unsigned long nbytes, int *start, void *arg) { extern unsigned long rdfpcr(void); - unsigned long fpcw; - unsigned long ret = -EOPNOTSUPP; + unsigned long w; - lock_kernel(); switch (op) { - case 45: /* GSI_IEEE_FP_CONTROL */ + case GSI_IEEE_FP_CONTROL: /* build and return current fp control word: */ - fpcw = current->tss.flags & IEEE_TRAP_ENABLE_MASK; - fpcw |= ((rdfpcr() >> 52) << 17) & IEEE_STATUS_MASK; - put_user(fpcw, (unsigned long *) buffer); - ret = 0; - break; - case 46: /* GSI_IEEE_STATE_AT_SIGNAL */ + w = current->tss.flags & IEEE_TRAP_ENABLE_MASK; + w |= ((rdfpcr() >> 52) << 17) & IEEE_STATUS_MASK; + if (put_user(w, (unsigned long *) buffer)) + return -EFAULT; + return 0; + + case GSI_IEEE_STATE_AT_SIGNAL: /* * Not sure anybody will ever use this weird stuff. These * ops can be used (under OSF/1) to set the fpcr that should * be used when a signal handler starts executing. */ break; + + case GSI_UACPROC: + w = (current->tss.flags >> UAC_SHIFT) & UAC_BITMASK; + if (put_user(w, (unsigned int *)buffer)) + return -EFAULT; + return 0; + default: break; } - unlock_kernel(); - return ret; + + return -EOPNOTSUPP; } -asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer, unsigned long nbytes, +asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer, + unsigned long nbytes, int *start, void *arg) { - unsigned long fpcw; - unsigned long ret = -EOPNOTSUPP; + unsigned long v, w, i; - lock_kernel(); switch (op) { - case 14: /* SSI_IEEE_FP_CONTROL */ + case SSI_IEEE_FP_CONTROL: /* update trap enable bits: */ - get_user(fpcw, (unsigned long *) buffer); + if (get_user(w, (unsigned long *) buffer)) + return -EFAULT; current->tss.flags &= ~IEEE_TRAP_ENABLE_MASK; - current->tss.flags |= (fpcw & IEEE_TRAP_ENABLE_MASK); - ret = 0; - break; - case 15: /* SSI_IEEE_STATE_AT_SIGNAL */ - case 16: /* SSI_IEEE_IGNORE_STATE_AT_SIGNAL */ + current->tss.flags |= (w & IEEE_TRAP_ENABLE_MASK); + return 0; + + case SSI_IEEE_STATE_AT_SIGNAL: + case SSI_IEEE_IGNORE_STATE_AT_SIGNAL: /* * Not sure anybody will ever use this weird stuff. These * ops can be used (under OSF/1) to set the fpcr that should * be used when a signal handler starts executing. */ + break; + + case SSI_NVPAIRS: + for (i = 0; i < nbytes; ++i) { + if (get_user(v, 2*i + (unsigned int *)buffer)) + return -EFAULT; + if (get_user(w, 2*i + 1 + (unsigned int *)buffer)) + return -EFAULT; + switch (v) { + case SSIN_UACPROC: + current->tss.flags &= + ~(UAC_BITMASK << UAC_SHIFT); + current->tss.flags |= + (w & UAC_BITMASK) << UAC_SHIFT; + break; + + default: + return -EOPNOTSUPP; + } + } + return 0; + default: break; } - unlock_kernel(); - return ret; + + return -EOPNOTSUPP; } diff -u --recursive --new-file v2.1.35/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.1.35/linux/arch/alpha/kernel/process.c Wed Apr 16 14:14:59 1997 +++ linux/arch/alpha/kernel/process.c Thu Apr 17 09:22:40 1997 @@ -39,7 +39,7 @@ #include /* - * No need to aquire the kernel lock, we're entirely local.. + * No need to acquire the kernel lock, we're entirely local.. */ asmlinkage int sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, diff -u --recursive --new-file v2.1.35/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c --- v2.1.35/linux/arch/alpha/kernel/signal.c Mon Apr 7 11:35:29 1997 +++ linux/arch/alpha/kernel/signal.c Tue Apr 22 22:38:40 1997 @@ -41,7 +41,7 @@ * We change the range to -1 .. 1 in order to let gcc easily * use the conditional move instructions. * - * Note that we don't need to aquire the kernel lock for SMP + * Note that we don't need to acquire the kernel lock for SMP * operation, as all of this is local to this thread. */ asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask, @@ -80,18 +80,17 @@ { unsigned long oldmask; - lock_kernel(); + spin_lock_irq(¤t->sigmask_lock); oldmask = current->blocked; current->blocked = mask & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(oldmask,regs, sw, 0, 0)) - goto out; + if (do_signal(oldmask, regs, sw, 0, 0)) + return -EINTR; } -out: - unlock_kernel(); - return -EINTR; } /* @@ -104,60 +103,64 @@ int i; /* verify that it's a good sigcontext before using it */ - lock_kernel(); if (verify_area(VERIFY_READ, sc, sizeof(*sc))) - do_exit(SIGSEGV); - get_user(ps, &sc->sc_ps); - if (ps != 8) - do_exit(SIGSEGV); - get_user(mask, &sc->sc_mask); - if (mask & ~_BLOCKABLE) - do_exit(SIGSEGV); + goto give_sigsegv; + if (__get_user(ps, &sc->sc_ps) || ps != 8) + goto give_sigsegv; + if (__get_user(mask, &sc->sc_mask) || (mask & ~_BLOCKABLE)) + goto give_sigsegv; /* ok, looks fine, start restoring */ - get_user(usp, sc->sc_regs+30); + __get_user(usp, sc->sc_regs+30); wrusp(usp); - get_user(regs->pc, &sc->sc_pc); + __get_user(regs->pc, &sc->sc_pc); sw->r26 = (unsigned long) ret_from_sys_call; current->blocked = mask; - get_user(regs->r0, sc->sc_regs+0); - get_user(regs->r1, sc->sc_regs+1); - get_user(regs->r2, sc->sc_regs+2); - get_user(regs->r3, sc->sc_regs+3); - get_user(regs->r4, sc->sc_regs+4); - get_user(regs->r5, sc->sc_regs+5); - get_user(regs->r6, sc->sc_regs+6); - get_user(regs->r7, sc->sc_regs+7); - get_user(regs->r8, sc->sc_regs+8); - get_user(sw->r9, sc->sc_regs+9); - get_user(sw->r10, sc->sc_regs+10); - get_user(sw->r11, sc->sc_regs+11); - get_user(sw->r12, sc->sc_regs+12); - get_user(sw->r13, sc->sc_regs+13); - get_user(sw->r14, sc->sc_regs+14); - get_user(sw->r15, sc->sc_regs+15); - get_user(regs->r16, sc->sc_regs+16); - get_user(regs->r17, sc->sc_regs+17); - get_user(regs->r18, sc->sc_regs+18); - get_user(regs->r19, sc->sc_regs+19); - get_user(regs->r20, sc->sc_regs+20); - get_user(regs->r21, sc->sc_regs+21); - get_user(regs->r22, sc->sc_regs+22); - get_user(regs->r23, sc->sc_regs+23); - get_user(regs->r24, sc->sc_regs+24); - get_user(regs->r25, sc->sc_regs+25); - get_user(regs->r26, sc->sc_regs+26); - get_user(regs->r27, sc->sc_regs+27); - get_user(regs->r28, sc->sc_regs+28); - get_user(regs->gp, sc->sc_regs+29); + __get_user(regs->r0, sc->sc_regs+0); + __get_user(regs->r1, sc->sc_regs+1); + __get_user(regs->r2, sc->sc_regs+2); + __get_user(regs->r3, sc->sc_regs+3); + __get_user(regs->r4, sc->sc_regs+4); + __get_user(regs->r5, sc->sc_regs+5); + __get_user(regs->r6, sc->sc_regs+6); + __get_user(regs->r7, sc->sc_regs+7); + __get_user(regs->r8, sc->sc_regs+8); + __get_user(sw->r9, sc->sc_regs+9); + __get_user(sw->r10, sc->sc_regs+10); + __get_user(sw->r11, sc->sc_regs+11); + __get_user(sw->r12, sc->sc_regs+12); + __get_user(sw->r13, sc->sc_regs+13); + __get_user(sw->r14, sc->sc_regs+14); + __get_user(sw->r15, sc->sc_regs+15); + __get_user(regs->r16, sc->sc_regs+16); + __get_user(regs->r17, sc->sc_regs+17); + __get_user(regs->r18, sc->sc_regs+18); + __get_user(regs->r19, sc->sc_regs+19); + __get_user(regs->r20, sc->sc_regs+20); + __get_user(regs->r21, sc->sc_regs+21); + __get_user(regs->r22, sc->sc_regs+22); + __get_user(regs->r23, sc->sc_regs+23); + __get_user(regs->r24, sc->sc_regs+24); + __get_user(regs->r25, sc->sc_regs+25); + __get_user(regs->r26, sc->sc_regs+26); + __get_user(regs->r27, sc->sc_regs+27); + __get_user(regs->r28, sc->sc_regs+28); + __get_user(regs->gp, sc->sc_regs+29); for (i = 0; i < 31; i++) - get_user(sw->fp[i], sc->sc_fpregs+i); + __get_user(sw->fp[i], sc->sc_fpregs+i); /* send SIGTRAP if we're single-stepping: */ + lock_kernel(); if (ptrace_cancel_bpt (current)) send_sig(SIGTRAP, current, 1); unlock_kernel(); + return; + +give_sigsegv: + lock_kernel(); + do_exit(SIGSEGV); + unlock_kernel(); } /* @@ -181,46 +184,46 @@ wrusp((unsigned long) sc); - put_user(oldmask, &sc->sc_mask); - put_user(8, &sc->sc_ps); - put_user(regs->pc, &sc->sc_pc); - put_user(oldsp, sc->sc_regs+30); - - put_user(regs->r0 , sc->sc_regs+0); - put_user(regs->r1 , sc->sc_regs+1); - put_user(regs->r2 , sc->sc_regs+2); - put_user(regs->r3 , sc->sc_regs+3); - put_user(regs->r4 , sc->sc_regs+4); - put_user(regs->r5 , sc->sc_regs+5); - put_user(regs->r6 , sc->sc_regs+6); - put_user(regs->r7 , sc->sc_regs+7); - put_user(regs->r8 , sc->sc_regs+8); - put_user(sw->r9 , sc->sc_regs+9); - put_user(sw->r10 , sc->sc_regs+10); - put_user(sw->r11 , sc->sc_regs+11); - put_user(sw->r12 , sc->sc_regs+12); - put_user(sw->r13 , sc->sc_regs+13); - put_user(sw->r14 , sc->sc_regs+14); - put_user(sw->r15 , sc->sc_regs+15); - put_user(regs->r16, sc->sc_regs+16); - put_user(regs->r17, sc->sc_regs+17); - put_user(regs->r18, sc->sc_regs+18); - put_user(regs->r19, sc->sc_regs+19); - put_user(regs->r20, sc->sc_regs+20); - put_user(regs->r21, sc->sc_regs+21); - put_user(regs->r22, sc->sc_regs+22); - put_user(regs->r23, sc->sc_regs+23); - put_user(regs->r24, sc->sc_regs+24); - put_user(regs->r25, sc->sc_regs+25); - put_user(regs->r26, sc->sc_regs+26); - put_user(regs->r27, sc->sc_regs+27); - put_user(regs->r28, sc->sc_regs+28); - put_user(regs->gp , sc->sc_regs+29); + __put_user(oldmask, &sc->sc_mask); + __put_user(8, &sc->sc_ps); + __put_user(regs->pc, &sc->sc_pc); + __put_user(oldsp, sc->sc_regs+30); + + __put_user(regs->r0 , sc->sc_regs+0); + __put_user(regs->r1 , sc->sc_regs+1); + __put_user(regs->r2 , sc->sc_regs+2); + __put_user(regs->r3 , sc->sc_regs+3); + __put_user(regs->r4 , sc->sc_regs+4); + __put_user(regs->r5 , sc->sc_regs+5); + __put_user(regs->r6 , sc->sc_regs+6); + __put_user(regs->r7 , sc->sc_regs+7); + __put_user(regs->r8 , sc->sc_regs+8); + __put_user(sw->r9 , sc->sc_regs+9); + __put_user(sw->r10 , sc->sc_regs+10); + __put_user(sw->r11 , sc->sc_regs+11); + __put_user(sw->r12 , sc->sc_regs+12); + __put_user(sw->r13 , sc->sc_regs+13); + __put_user(sw->r14 , sc->sc_regs+14); + __put_user(sw->r15 , sc->sc_regs+15); + __put_user(regs->r16, sc->sc_regs+16); + __put_user(regs->r17, sc->sc_regs+17); + __put_user(regs->r18, sc->sc_regs+18); + __put_user(regs->r19, sc->sc_regs+19); + __put_user(regs->r20, sc->sc_regs+20); + __put_user(regs->r21, sc->sc_regs+21); + __put_user(regs->r22, sc->sc_regs+22); + __put_user(regs->r23, sc->sc_regs+23); + __put_user(regs->r24, sc->sc_regs+24); + __put_user(regs->r25, sc->sc_regs+25); + __put_user(regs->r26, sc->sc_regs+26); + __put_user(regs->r27, sc->sc_regs+27); + __put_user(regs->r28, sc->sc_regs+28); + __put_user(regs->gp , sc->sc_regs+29); for (i = 0; i < 31; i++) - put_user(sw->fp[i], sc->sc_fpregs+i); - put_user(regs->trap_a0, &sc->sc_traparg_a0); - put_user(regs->trap_a1, &sc->sc_traparg_a1); - put_user(regs->trap_a2, &sc->sc_traparg_a2); + __put_user(sw->fp[i], sc->sc_fpregs+i); + __put_user(regs->trap_a0, &sc->sc_traparg_a0); + __put_user(regs->trap_a1, &sc->sc_traparg_a1); + __put_user(regs->trap_a2, &sc->sc_traparg_a2); /* * The following is: @@ -231,8 +234,8 @@ * * ie, "sigreturn(stack-pointer)" */ - put_user(0x43ecf40047de0410, sc->sc_retcode+0); - put_user(0x0000000000000083, sc->sc_retcode+1); + __put_user(0x43ecf40047de0410, sc->sc_retcode+0); + __put_user(0x0000000000000083, sc->sc_retcode+1); imb(); /* "return" to the handler */ diff -u --recursive --new-file v2.1.35/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c --- v2.1.35/linux/arch/alpha/kernel/traps.c Sun Feb 2 05:00:46 1997 +++ linux/arch/alpha/kernel/traps.c Tue Apr 22 22:38:40 1997 @@ -16,6 +16,9 @@ #include #include #include +#include +#include + void die_if_kernel(char * str, struct pt_regs * regs, long err, unsigned long *r9_15) @@ -81,10 +84,13 @@ return; /* emulation was successful */ } } + + lock_kernel(); printk("%s: arithmetic trap at %016lx: %02lx %016lx\n", current->comm, regs.pc, summary, write_mask); die_if_kernel("Arithmetic fault", ®s, 0, 0); force_sig(SIGFPE, current); + unlock_kernel(); } asmlinkage void do_entIF(unsigned long type, unsigned long a1, @@ -93,6 +99,7 @@ { extern int ptrace_cancel_bpt (struct task_struct *who); + lock_kernel(); die_if_kernel("Instruction fault", ®s, type, 0); switch (type) { case 0: /* breakpoint */ @@ -171,6 +178,7 @@ default: panic("do_entIF: unexpected instruction-fault type"); } + unlock_kernel(); } /* @@ -204,21 +212,10 @@ unsigned long a3, unsigned long a4, unsigned long a5, struct allregs regs) { - static int cnt = 0; - static long last_time = 0; long error, tmp1, tmp2, tmp3, tmp4; unsigned long pc = regs.pc - 4; unsigned fixup; - if (cnt >= 5 && jiffies - last_time > 5*HZ) { - cnt = 0; - } - if (++cnt < 5) { - printk("kernel: unaligned trap at %016lx: %p %lx %ld\n", - pc, va, opcode, reg); - } - last_time = jiffies; - unaligned[0].count++; unaligned[0].va = (unsigned long) va; unaligned[0].pc = pc; @@ -228,7 +225,6 @@ exception will we decide whether we should have caught it. */ switch (opcode) { -#ifdef __HAVE_CPU_BWX case 0x0c: /* ldwu */ __asm__ __volatile__( "1: ldq_u %1,0(%3)\n" @@ -248,7 +244,6 @@ goto got_exception; una_reg(reg) = tmp1|tmp2; return; -#endif case 0x28: /* ldl */ __asm__ __volatile__( @@ -293,7 +288,6 @@ /* Note that the store sequences do not indicate that they change memory because it _should_ be affecting nothing in this context. (Otherwise we have other, much larger, problems.) */ -#ifdef __HAVE_CPU_BWX case 0x0d: /* stw */ __asm__ __volatile__( "1: ldq_u %2,1(%5)\n" @@ -323,7 +317,6 @@ if (error) goto got_exception; return; -#endif case 0x2c: /* stl */ __asm__ __volatile__( @@ -385,9 +378,12 @@ goto got_exception; return; } + + lock_kernel(); printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n", pc, va, opcode, reg); do_exit(SIGSEGV); + unlock_kernel(); return; got_exception: @@ -396,17 +392,23 @@ if ((fixup = search_exception_table(pc)) != 0) { unsigned long newpc; newpc = fixup_exception(una_reg, fixup, pc); + + lock_kernel(); printk("Forwarding unaligned exception at %lx (%lx)\n", pc, newpc); + unlock_kernel(); + (®s)->pc = newpc; return; } /* Yikes! No one to forward the exception to. */ + lock_kernel(); printk("%s: unhandled unaligned exception at pc=%lx ra=%lx" " (bad address = %p)\n", current->comm, pc, una_reg(26), va); do_exit(SIGSEGV); + unlock_kernel(); } /* @@ -466,50 +468,68 @@ * 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); + static int cnt = 0; + static long last_time = 0; + + unsigned long tmp1, tmp2, tmp3, tmp4; + unsigned long *reg_addr, *pc_addr, fake_reg; + unsigned long uac_bits; + long error; + pc_addr = frame + 7 + 20 + 1; /* pc in PAL frame */ - if (cnt >= 5 && jiffies - last_time > 5*HZ) { - cnt = 0; + /* 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; } - if (++cnt < 5) { - printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", - current->comm, current->pid, - *pc_addr - 4, va, opcode, reg); + if (uac_bits & UAC_SIGBUS) { + goto give_sigbus; } - last_time = jiffies; - - ++unaligned[1].count; - unaligned[1].va = (unsigned long) va - 4; - unaligned[1].pc = *pc_addr; - - dir = VERIFY_READ; - if (opcode & 0x4) { - /* it's a stl, stq, stt, or sts */ - dir = VERIFY_WRITE; - } - size = 4; - if (opcode & 0x1) { - /* it's a quadword op */ - size = 8; - } - if (verify_area(dir, va, size)) { - *pc_addr -= 4; /* make pc point to faulting insn */ - force_sig(SIGSEGV, current); + if (uac_bits & UAC_NOFIX) { + /* Not sure why you'd want to use this, but... */ return; } + /* Don't bother reading ds in the access check since we already + know that this came from the user. Also rely on the fact that + the page at TASK_SIZE is unmapped and so can't be touched anyway. */ + if (!__access_ok((unsigned long)va, 0, USER_DS)) + goto give_sigsegv; + + ++unaligned[1].count; + unaligned[1].va = (unsigned long)va; + unaligned[1].pc = *pc_addr - 4; + reg_addr = frame; - if (opcode >= 0x28) { + if ((1L << opcode) & OP_INT_MASK) { /* it's an integer load/store */ switch (reg) { case 0: case 1: case 2: case 3: case 4: @@ -542,57 +562,249 @@ case 30: /* usp in PAL regs */ - usp = rdusp(); - reg_addr = &usp; + fake_reg = rdusp(); + reg_addr = &fake_reg; break; case 31: /* zero "register" */ - reg_addr = &zero; + fake_reg = 0; + reg_addr = &fake_reg; break; } } + /* We don't want to use the generic get/put unaligned macros as + we want to trap exceptions. Only if we actually get an + exception will we decide whether we should have caught it. */ + switch (opcode) { - case 0x22: /* lds */ - alpha_write_fp_reg(reg, s_mem_to_reg( - get_unaligned((unsigned int *)va))); - break; - case 0x26: /* sts */ - put_unaligned(s_reg_to_mem(alpha_read_fp_reg(reg)), - (unsigned int *)va); + case 0x0c: /* ldwu */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,1(%3)\n" + " extwl %1,%3,%1\n" + " extwh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + *reg_addr = tmp1|tmp2; break; - case 0x23: /* ldt */ - alpha_write_fp_reg(reg, get_unaligned((unsigned long *)va)); - break; - case 0x27: /* stt */ - put_unaligned(alpha_read_fp_reg(reg), (unsigned long *)va); - break; + case 0x22: /* lds */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,3(%3)\n" + " extll %1,%3,%1\n" + " extlh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + alpha_write_fp_reg(reg, s_mem_to_reg((int)(tmp1|tmp2))); + return; - case 0x28: /* ldl */ - *reg_addr = get_unaligned((int *)va); - break; - case 0x2c: /* stl */ - put_unaligned(*reg_addr, (int *)va); - break; + case 0x23: /* ldt */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,7(%3)\n" + " extql %1,%3,%1\n" + " extqh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + alpha_write_fp_reg(reg, tmp1|tmp2); + return; - case 0x29: /* ldq */ - *reg_addr = get_unaligned((long *)va); + case 0x28: /* ldl */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,3(%3)\n" + " extll %1,%3,%1\n" + " extlh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + *reg_addr = (int)(tmp1|tmp2); break; - case 0x2d: /* stq */ - put_unaligned(*reg_addr, (long *)va); + + case 0x29: /* ldq */ + __asm__ __volatile__( + "1: ldq_u %1,0(%3)\n" + "2: ldq_u %2,7(%3)\n" + " extql %1,%3,%1\n" + " extqh %2,%3,%2\n" + "3:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %1,3b-1b(%0)\n" + " .gprel32 2b\n" + " lda %2,3b-2b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) + : "r"(va), "0"(0)); + if (error) + goto give_sigsegv; + *reg_addr = tmp1|tmp2; break; - default: - *pc_addr -= 4; /* make pc point to faulting insn */ - force_sig(SIGBUS, current); + /* Note that the store sequences do not indicate that they change + memory because it _should_ be affecting nothing in this context. + (Otherwise we have other, much larger, problems.) */ + case 0x0d: /* stw */ + __asm__ __volatile__( + "1: ldq_u %2,1(%5)\n" + "2: ldq_u %1,0(%5)\n" + " inswh %6,%5,%4\n" + " inswl %6,%5,%3\n" + " mskwh %2,%5,%2\n" + " mskwl %1,%5,%1\n" + " or %2,%4,%2\n" + " or %1,%3,%1\n" + "3: stq_u %2,1(%5)\n" + "4: stq_u %1,0(%5)\n" + "5:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %2,5b-1b(%0)\n" + " .gprel32 2b\n" + " lda %1,5b-2b(%0)\n" + " .gprel32 3b\n" + " lda $31,5b-3b(%0)\n" + " .gprel32 4b\n" + " lda $31,5b-4b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), + "=&r"(tmp3), "=&r"(tmp4) + : "r"(va), "r"(*reg_addr), "0"(0)); + if (error) + goto give_sigsegv; + return; + + case 0x26: /* sts */ + fake_reg = s_reg_to_mem(alpha_read_fp_reg(reg)); + reg_addr = &fake_reg; + /* FALLTHRU */ + + case 0x2c: /* stl */ + __asm__ __volatile__( + "1: ldq_u %2,3(%5)\n" + "2: ldq_u %1,0(%5)\n" + " inslh %6,%5,%4\n" + " insll %6,%5,%3\n" + " msklh %2,%5,%2\n" + " mskll %1,%5,%1\n" + " or %2,%4,%2\n" + " or %1,%3,%1\n" + "3: stq_u %2,3(%5)\n" + "4: stq_u %1,0(%5)\n" + "5:\n" + ".section __ex_table,\"a\"\n" + " .gprel32 1b\n" + " lda %2,5b-1b(%0)\n" + " .gprel32 2b\n" + " lda %1,5b-2b(%0)\n" + " .gprel32 3b\n" + " lda $31,5b-3b(%0)\n" + " .gprel32 4b\n" + " lda $31,5b-4b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), + "=&r"(tmp3), "=&r"(tmp4) + : "r"(va), "r"(*reg_addr), "0"(0)); + if (error) + goto give_sigsegv; + return; + + case 0x27: /* stt */ + fake_reg = alpha_read_fp_reg(reg); + reg_addr = &fake_reg; + /* FALLTHRU */ + + case 0x2d: /* stq */ + __asm__ __volatile__( + "1: ldq_u %2,7(%5)\n" + "2: ldq_u %1,0(%5)\n" + " insqh %6,%5,%4\n" + " insql %6,%5,%3\n" + " mskqh %2,%5,%2\n" + " mskql %1,%5,%1\n" + " or %2,%4,%2\n" + " or %1,%3,%1\n" + "3: stq_u %2,7(%5)\n" + "4: stq_u %1,0(%5)\n" + "5:\n" + ".section __ex_table,\"a\"\n\t" + " .gprel32 1b\n" + " lda %2,5b-1b(%0)\n" + " .gprel32 2b\n" + " lda %1,5b-2b(%0)\n" + " .gprel32 3b\n" + " lda $31,5b-3b(%0)\n" + " .gprel32 4b\n" + " lda $31,5b-4b(%0)\n" + ".previous" + : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), + "=&r"(tmp3), "=&r"(tmp4) + : "r"(va), "r"(*reg_addr), "0"(0)); + if (error) + goto give_sigsegv; return; - } - if (opcode >= 0x28 && reg == 30 && dir == VERIFY_WRITE) { - wrusp(usp); + default: + /* What instruction were you trying to use, exactly? */ + goto give_sigbus; } + + /* Only integer loads should get here; everyone else returns early. */ + if (reg == 30) + wrusp(fake_reg); + return; + +give_sigsegv: + *pc_addr -= 4; /* make pc point to faulting insn */ + lock_kernel(); + force_sig(SIGSEGV, current); + unlock_kernel(); + return; + +give_sigbus: + *pc_addr -= 4; + lock_kernel(); + force_sig(SIGBUS, current); + unlock_kernel(); + return; } /* @@ -610,8 +822,11 @@ unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { - if (regs.r0 != 112) + lock_kernel(); + /* Only report OSF system calls. */ + if (regs.r0 != 112 && regs.r0 < 300) printk("", regs.r0, a0, a1, a2); + unlock_kernel(); return -1; } @@ -621,16 +836,11 @@ extern asmlinkage void entUna(void); extern asmlinkage void entSys(void); +register unsigned long gptr __asm__("$29"); + void trap_init(void) { - unsigned long gptr; - - /* - * Tell PAL-code what global pointer we want in the kernel.. - */ - __asm__("br %0,___tmp\n" - "___tmp:\tldgp %0,0(%0)" - : "=r" (gptr)); + /* Tell PAL-code what global pointer we want in the kernel. */ wrkgp(gptr); wrent(entArith, 1); diff -u --recursive --new-file v2.1.35/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c --- v2.1.35/linux/arch/alpha/mm/init.c Mon Apr 14 16:28:05 1997 +++ linux/arch/alpha/mm/init.c Tue Apr 22 22:38:40 1997 @@ -150,7 +150,7 @@ start_mem = PAGE_ALIGN(start_mem); /* - * Mark the pages used by the kernel as reserved.. + * Mark the pages used by the kernel as reserved. */ tmp = KERNEL_START; while (tmp < start_mem) { @@ -171,9 +171,19 @@ return; } -void free_initmem(void) +void free_initmem (void) { - /* To be written */ + extern char __init_begin, __init_end; + unsigned long addr; + + addr = (unsigned long)(&__init_begin); + for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { + mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); + atomic_set(&mem_map[MAP_NR(addr)].count, 1); + free_page(addr); + } + printk ("Freeing unused kernel memory: %dk freed\n", + (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) diff -u --recursive --new-file v2.1.35/linux/arch/alpha/vmlinux.lds linux/arch/alpha/vmlinux.lds --- v2.1.35/linux/arch/alpha/vmlinux.lds Fri Sep 15 01:23:05 1995 +++ linux/arch/alpha/vmlinux.lds Tue Apr 22 22:38:40 1997 @@ -1,50 +1,46 @@ -OUTPUT_FORMAT("ecoff-littlealpha") +OUTPUT_FORMAT("elf64-alpha") ENTRY(__start) SECTIONS { - .text 0xfffffc0000310000: { - _ftext = . ; - __istart = . ; - eprol = .; - *(.text) - __fstart = . ; - _etext = .; - } - .rdata : { - *(.rdata) - } - .pdata : { - _fpdata = .; - *(.pdata) - } - .data : { - _fdata = .; - *(.data) - CONSTRUCTORS - } - .xdata : { - *(.xdata) - } - _gp = ALIGN (16) + 0x8000; - .lit8 : { - *(.lit8) - } - .lita : { - *(.lita) - } - .sdata : { - *(.sdata) - } - _EDATA = .; - _FBSS = .; - .sbss : { - *(.sbss) - *(.scommon) - . = ALIGN(16); - } - .bss : { - *(.bss) - *(COMMON) - } - _end = .; + . = 0xfffffc0000310000; + _text = .; + .text : { *(.text) } + _etext = .; + + /* Exception table */ + . = ALIGN(16); + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + /* Kernel symbol table */ + . = ALIGN(8); + __start___ksymtab = .; + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + .kstrtab : { *(.kstrtab) } + + /* Startup code */ + . = ALIGN(8192); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(8192); + __init_end = .; + + /* Global data */ + _data = .; + .rodata : { *(.rodata) } + .data : { *(.data) CONSTRUCTORS } + .got : { *(.got) } + .sdata : { *(.sdata) } + _edata = .; + _bss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : { *(.bss) *(COMMON) } + _end = .; + + .mdebug 0 : { *(.mdebug) } + .note 0 : { *(.note) } + .comment 0 : { *(.comment) } } diff -u --recursive --new-file v2.1.35/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v2.1.35/linux/arch/i386/Makefile Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/Makefile Thu Apr 17 18:02:14 1997 @@ -21,7 +21,7 @@ CPP=$(CC) -E OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S LDFLAGS=-e stext -LINKFLAGS =-T arch/i386/vmlinux.lds $(LDFLAGS) +LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS) CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce diff -u --recursive --new-file v2.1.35/linux/arch/i386/boot/Makefile linux/arch/i386/boot/Makefile --- v2.1.35/linux/arch/i386/boot/Makefile Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/boot/Makefile Thu Apr 17 14:24:47 1997 @@ -40,8 +40,8 @@ cp $(TOPDIR)/System.map $(INSTALL_PATH)/ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi -install: $(CONFIGURE) zImage - sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" +install: $(CONFIGURE) $(BOOTIMAGE) + sh -x ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) $(BOOTIMAGE) $(TOPDIR)/System.map "$(INSTALL_PATH)" tools/build: tools/build.c $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.1.35/linux/arch/i386/kernel/bios32.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/bios32.c Wed Apr 16 14:53:37 1997 @@ -738,7 +738,7 @@ outb (0x00, 0xCFB); outb (0x00, 0xCF8); outb (0x00, 0xCFA); - if (inb (0xCF8) == 0x00 && inb (0xCFC) == 0x00) { + if (inb (0xCF8) == 0x00 && inb (0xCFB) == 0x00) { restore_flags(flags); printk("pcibios_init: Using configuration type 2\n"); return &pci_direct_conf2; diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v2.1.35/linux/arch/i386/kernel/entry.S Thu Mar 27 14:39:59 1997 +++ linux/arch/i386/kernel/entry.S Tue Apr 22 22:49:38 1997 @@ -524,6 +524,7 @@ .long SYMBOL_NAME(sys_vm86) .long SYMBOL_NAME(sys_query_module) .long SYMBOL_NAME(sys_poll) - .rept NR_syscalls-168 + .long SYMBOL_NAME(sys_nfsservctl) + .rept NR_syscalls-169 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- v2.1.35/linux/arch/i386/kernel/head.S Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/head.S Mon Apr 21 11:34:01 1997 @@ -38,15 +38,16 @@ orw %bx,%bx jz 1f /* - * New page tables may be in 4Mbyte page mode + * New page tables may be in 4Mbyte page mode and may + * be using the global pages. */ #ifdef GAS_KNOWS_CR4 movl %cr4,%eax # Turn on 4Mb pages - orl $16,%eax + orl $16+128,%eax movl %eax,%cr4 #else .byte 0x0f,0x20,0xe0 - orl $16,%eax + orl $16+128,%eax .byte 0x0f,0x22,0xe0 #endif movl %eax,%cr3 /* flush TLB as per app note */ diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.1.35/linux/arch/i386/kernel/i386_ksyms.c Sun Apr 13 10:18:20 1997 +++ linux/arch/i386/kernel/i386_ksyms.c Wed Apr 16 16:04:15 1997 @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -31,7 +32,7 @@ EXPORT_SYMBOL_NOVERS(__down_failed); EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); EXPORT_SYMBOL_NOVERS(__up_wakeup); - +EXPORT_SYMBOL(__intel_bh_counter); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); @@ -42,6 +43,13 @@ EXPORT_SYMBOL(active_kernel_processor); EXPORT_SYMBOL(smp_invalidate_needed); EXPORT_SYMBOL_NOVERS(__lock_kernel); + +/* Global SMP irq stuff */ +EXPORT_SYMBOL(global_irq_holder); +EXPORT_SYMBOL(__global_cli); +EXPORT_SYMBOL(__global_sti); +EXPORT_SYMBOL(__global_save_flags); +EXPORT_SYMBOL(__global_restore_flags); #endif #ifdef CONFIG_MCA diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.1.35/linux/arch/i386/kernel/irq.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/irq.c Wed Apr 16 16:52:23 1997 @@ -128,6 +128,11 @@ * other interrupts would have to avoid using the jiffies variable for delay * and interval timing operations to avoid hanging the system. */ + +#if NR_IRQS != 16 +#error make irq stub building NR_IRQS dependent and remove me. +#endif + BUILD_TIMER_IRQ(FIRST,0,0x01) BUILD_IRQ(FIRST,1,0x02) BUILD_IRQ(FIRST,2,0x04) @@ -231,7 +236,7 @@ int i, len = 0; struct irqaction * action; - for (i = 0 ; i < 16 ; i++) { + for (i = 0 ; i < NR_IRQS ; i++) { action = irq_action[i]; if (!action) continue; @@ -734,15 +739,9 @@ outb_p(LATCH & 0xff , 0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ - for (i = 0; i < 16 ; i++) + for (i = 0; i < NR_IRQS ; i++) set_intr_gate(0x20+i,bad_interrupt[i]); - /* - * This bit is a hack because we don't send timer messages to all - * processors yet. It has to be here .. it doesn't work if you put - * it down the bottom - assembler explodes 8) - */ - #ifdef __SMP__ /* * NOTE! The local APIC isn't very good at handling @@ -752,8 +751,19 @@ * want to spread these out a bit so that they don't * all fall in the same interrupt level */ + + /* + * The reschedule interrupt slowly changes it's functionality, + * while so far it was a kind of broadcasted timer interrupt, + * in the future it should become a CPU-to-CPU rescheduling IPI, + * driven by schedule() ? + * + * [ It has to be here .. it doesn't work if you put + * it down the bottom - assembler explodes 8) ] + */ /* IRQ '16' (trap 0x30) - IPI for rescheduling */ set_intr_gate(0x20+i, reschedule_interrupt); + /* IRQ '17' (trap 0x31) - IPI for invalidation */ set_intr_gate(0x21+i, invalidate_interrupt); diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h --- v2.1.35/linux/arch/i386/kernel/irq.h Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/irq.h Wed Apr 16 16:52:23 1997 @@ -266,4 +266,26 @@ UNBLK_##chip(mask) \ "jmp ret_from_intr\n"); +/* + * x86 profiling function, SMP safe. We might want to do this in + * assembly totally? + */ +static inline void x86_do_profile (unsigned long eip) +{ + if (prof_buffer && current->pid) { + extern int _stext; + eip -= (unsigned long) &_stext; + eip >>= prof_shift; + if (eip < prof_len) + atomic_inc((atomic_t *)&prof_buffer[eip]); + else + /* + * Dont ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + atomic_inc((atomic_t *)&prof_buffer[prof_len-1]); + } +} + #endif diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c --- v2.1.35/linux/arch/i386/kernel/ptrace.c Sun Jan 26 02:07:04 1997 +++ linux/arch/i386/kernel/ptrace.c Thu Apr 17 13:20:40 1997 @@ -584,10 +584,9 @@ asmlinkage void syscall_trace(void) { - lock_kernel(); if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS)) - goto out; + return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; notify_parent(current); @@ -597,9 +596,10 @@ * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ - if (current->exit_code) + if (current->exit_code) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= (1 << (current->exit_code - 1)); + spin_unlock_irq(¤t->sigmask_lock); + } current->exit_code = 0; -out: - unlock_kernel(); } diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- v2.1.35/linux/arch/i386/kernel/signal.c Sun Jan 26 02:07:04 1997 +++ linux/arch/i386/kernel/signal.c Thu Apr 17 13:20:40 1997 @@ -23,7 +23,9 @@ #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) -asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options); +asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, + int options, unsigned long *ru); + asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs); /* @@ -31,24 +33,21 @@ */ asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set) { + struct pt_regs * regs = (struct pt_regs *) &restart; unsigned long mask; - struct pt_regs * regs; - int res = -EINTR; - lock_kernel(); - regs = (struct pt_regs *) &restart; + spin_lock_irq(¤t->sigmask_lock); mask = current->blocked; current->blocked = set & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + regs->eax = -EINTR; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(mask,regs)) - goto out; + if (do_signal(mask, regs)) + return -EINTR; } -out: - unlock_kernel(); - return res; } static inline void restore_i387_hard(struct _fpstate *buf) @@ -108,9 +107,7 @@ __asm__("mov %w0,%%" #seg: :"r" (tmp)); } struct sigcontext * context; struct pt_regs * regs; - int res; - lock_kernel(); regs = (struct pt_regs *) &__unused; context = (struct sigcontext *) regs->esp; if (verify_area(VERIFY_READ, context, sizeof(*context))) @@ -136,11 +133,12 @@ goto badframe; restore_i387(buf); } - res = context->eax; - unlock_kernel(); - return res; + return context->eax; + badframe: + lock_kernel(); do_exit(SIGSEGV); + unlock_kernel(); } static inline struct _fpstate * save_i387_hard(struct _fpstate * buf) @@ -194,7 +192,7 @@ frame = (unsigned long *) sa->sa_restorer; frame -= 64; if (!access_ok(VERIFY_WRITE,frame,64*4)) - do_exit(SIGSEGV); + goto segv_and_exit; /* set up the "normal" stack seen by the signal handler (iBCS2) */ #define __CODE ((unsigned long)(frame+24)) @@ -206,7 +204,7 @@ We use __put_user() here because the access_ok() call was already done earlier. */ if (__put_user(__CODE,frame)) - do_exit(SIGSEGV); + goto segv_and_exit; if (current->exec_domain && current->exec_domain->signal_invmap) __put_user(current->exec_domain->signal_invmap[signr], frame+1); else @@ -259,6 +257,12 @@ regs->xcs = USER_CS; } regs->eflags &= ~TF_MASK; + return; + +segv_and_exit: + lock_kernel(); + do_exit(SIGSEGV); + unlock_kernel(); } /* @@ -292,8 +296,11 @@ if (sa->sa_flags & SA_ONESHOT) sa->sa_handler = NULL; - if (!(sa->sa_flags & SA_NOMASK)) + if (!(sa->sa_flags & SA_NOMASK)) { + spin_lock_irq(¤t->sigmask_lock); current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + } } /* @@ -310,9 +317,7 @@ unsigned long mask; unsigned long signr; struct sigaction * sa; - int res; - lock_kernel(); mask = ~current->blocked; while ((signr = current->signal & mask)) { /* @@ -322,6 +327,9 @@ */ struct task_struct *t=current; __asm__("bsf %3,%1\n\t" +#ifdef __SMP__ + "lock ; " +#endif "btrl %1,%0" :"=m" (t->signal),"=r" (signr) :"0" (t->signal), "1" (signr)); @@ -338,7 +346,9 @@ if (signr == SIGSTOP) continue; if (_S(signr) & current->blocked) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr); + spin_unlock_irq(¤t->sigmask_lock); continue; } sa = current->sig->action + signr - 1; @@ -347,7 +357,7 @@ if (signr != SIGCHLD) continue; /* check for SIGCHLD: it's special */ - while (sys_waitpid(-1,NULL,WNOHANG) > 0) + while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0) /* nothing */; continue; } @@ -380,14 +390,19 @@ } /* fall through */ default: + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr & 0x7f); + spin_unlock_irq(¤t->sigmask_lock); + current->flags |= PF_SIGNALED; + + lock_kernel(); /* 8-( */ do_exit(signr); + unlock_kernel(); } } handle_signal(signr, sa, oldmask, regs); - res = 1; - goto out; + return 1; } /* Did we come from a system call? */ @@ -400,8 +415,5 @@ regs->eip -= 2; } } - res = 0; -out: - unlock_kernel(); - return res; + return 0; } diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- v2.1.35/linux/arch/i386/kernel/smp.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/smp.c Wed Apr 16 16:52:23 1997 @@ -49,6 +49,9 @@ #include "irq.h" extern unsigned long start_kernel, _etext; +extern void update_one_process( struct task_struct *p, + unsigned long ticks, unsigned long user, + unsigned long system); void setup_APIC_clock (void); /* @@ -1307,37 +1310,6 @@ } /* - * Platform specific profiling function. - * it builds a 'prof_shift' resolution EIP distribution histogram - * - * it's SMP safe. - */ - -static inline void x86_do_profile (unsigned long eip) -{ - if (prof_buffer && current->pid) { - extern int _stext; - eip -= (unsigned long) &_stext; - eip >>= prof_shift; - if (eip < prof_len) - atomic_inc(&prof_buffer[eip]); - else - /* - * Dont ignore out-of-bounds EIP values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - atomic_inc(&prof_buffer[prof_len-1]); - } -} - -unsigned int prof_multiplier[NR_CPUS]; -unsigned int prof_counter[NR_CPUS]; - -extern void update_one_process( struct task_struct *p, - unsigned long ticks, unsigned long user, - unsigned long system); -/* * Local timer interrupt handler. It does both profiling and * process statistics/rescheduling. * @@ -1346,14 +1318,19 @@ * multiplier is 1 and it can be changed by writing a 4 bytes multiplier * value into /proc/profile. */ + +unsigned int prof_multiplier[NR_CPUS]; +unsigned int prof_counter[NR_CPUS]; + static inline void smp_local_timer_interrupt(struct pt_regs * regs) { int cpu = smp_processor_id(); + /* - * Both the profiling function and the statistics - * counters are SMP safe. We leave the APIC irq - * unacked while updating the profiling info, thus - * we cannot be interrupted by the same APIC interrupt. + * The profiling function is SMP safe. (nothing can mess + * around with "current", and the profiling counters are + * updated with atomic operations). This is especially + * useful with a profiling multiplier != 1 */ if (!user_mode(regs)) x86_do_profile (regs->eip); @@ -1363,13 +1340,10 @@ struct task_struct * p = current; /* - * We mess around with thread statistics, but - * since we are the CPU running it, we dont - * have to lock it. We assume that switch_to() - * protects 'current' against local irqs via __cli. - * - * kernel statistics counters are updated via atomic - * operations. + * After doing the above, we need to make like + * a normal interrupt - otherwise timer interrupts + * ignore the global interrupt lock, which is the + * WrongThing (tm) to do. */ if (user_mode(regs)) @@ -1377,7 +1351,9 @@ else system=1; + irq_enter(cpu, 0); if (p->pid) { + update_one_process(p, 1, user, system); p->counter -= 1; @@ -1386,25 +1362,21 @@ need_resched = 1; } if (p->priority < DEF_PRIORITY) - atomic_add (user, &kstat.cpu_nice); + kstat.cpu_nice += user; else - atomic_add (user, &kstat.cpu_user); + kstat.cpu_user += user; - atomic_add (system, &kstat.cpu_system); + kstat.cpu_system += system; } else { #ifdef __SMP_PROF__ if (test_bit(cpu,&smp_idle_map)) smp_idle_count[cpu]++; #endif - /* - * This is a hack until we have need_resched[] - */ - if (read_smp_counter(&smp_process_available)) - need_resched=1; } - prof_counter[cpu]=prof_multiplier[cpu]; + + irq_exit(cpu, 0); } #ifdef __SMP_PROF__ @@ -1432,8 +1404,6 @@ */ void smp_apic_timer_interrupt(struct pt_regs * regs) { - int cpu = smp_processor_id(); - /* * NOTE! We'd better ACK the irq immediately, * because timer handling can be slow, and we @@ -1442,15 +1412,7 @@ */ ack_APIC_irq (); - /* - * After doing the above, we need to make like - * a normal interrupt - otherwise timer interrupts - * ignore the global interrupt lock, which is the - * WrongThing (tm) to do. - */ - irq_enter(cpu, 0); smp_local_timer_interrupt(regs); - irq_exit(cpu, 0); } /* diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.1.35/linux/arch/i386/kernel/time.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/time.c Wed Apr 16 16:52:23 1997 @@ -33,6 +33,11 @@ #include #include +/* + * for x86_do_profile() + */ +#include "irq.h" + extern int setup_x86_irq(int, struct irqaction *); extern volatile unsigned long lost_ticks; @@ -364,29 +369,6 @@ /* last time the cmos clock got updated */ static long last_rtc_update = 0; - - -/* - * Move this to a header file - right now it shows - * up both here and in smp.c - */ -static inline void x86_do_profile (unsigned long eip) -{ - if (prof_buffer && current->pid) { - extern int _stext; - eip -= (unsigned long) &_stext; - eip >>= prof_shift; - if (eip < prof_len) - atomic_inc(&prof_buffer[eip]); - else - /* - * Dont ignore out-of-bounds EIP values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - atomic_inc(&prof_buffer[prof_len-1]); - } -} /* * timer_interrupt() needs to keep up the real-time clock, diff -u --recursive --new-file v2.1.35/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v2.1.35/linux/arch/i386/mm/init.c Wed Apr 16 14:15:00 1997 +++ linux/arch/i386/mm/init.c Tue Apr 22 22:44:18 1997 @@ -27,6 +27,8 @@ #include #include +const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n"; + extern void die_if_kernel(char *,struct pt_regs *,long); extern void show_net_buffers(void); @@ -102,6 +104,48 @@ extern char _text, _etext, _edata, __bss_start, _end; extern char __init_begin, __init_end; +#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x0008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x0010 /* enable page size extensions */ +#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x0040 /* Machine check enable */ +#define X86_CR4_PGE 0x0080 /* enable global pages */ +#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ + +#define X86_FEATURE_FPU 0x0001 /* internal FPU */ +#define X86_FEATURE_VME 0x0002 /* vm86 extensions */ +#define X86_FEATURE_DE 0x0004 /* debugging extensions */ +#define X86_FEATURE_PSE 0x0008 /* Page size extensions */ +#define X86_FEATURE_TSC 0x0010 /* Time stamp counter */ +#define X86_FEATURE_MSR 0x0020 /* RDMSR/WRMSR */ +#define X86_FEATURE_PAE 0x0040 /* Physical address extension */ +#define X86_FEATURE_MCE 0x0080 /* Machine check exception */ +#define X86_FEATURE_CXS 0x0100 /* cmpxchg8 available */ +#define X86_FEATURE_APIC 0x0200 /* internal APIC */ +#define X86_FEATURE_10 0x0400 +#define X86_FEATURE_11 0x0800 +#define X86_FEATURE_MTRR 0x1000 /* memory type registers */ +#define X86_FEATURE_PGE 0x2000 /* Global page */ +#define X86_FEATURE_MCA 0x4000 /* Machine Check Architecture */ +#define X86_FEATURE_CMOV 0x8000 /* Cmov/fcomi */ + +#ifdef GAS_KNOWS_CR4 +#define read_cr4 "movl %%cr4,%%eax" +#define write_cr4 "movl %%eax,%%cr4" +#else +#define read_cr4 ".byte 0x0f,0x20,0xe0" +#define write_cr4 ".byte 0x0f,0x22,0xe0" +#endif + +#define set_in_cr4(x) \ +__asm__(read_cr4 "\n\t" \ + "orl %0,%%eax\n\t" \ + write_cr4 \ + : : "i" (x) \ + :"ax"); + /* * paging_init() sets up the page tables - note that the first 4MB are * already mapped by head.S. @@ -156,27 +200,25 @@ /* 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; @@ -322,6 +364,7 @@ atomic_set(&mem_map[MAP_NR(addr)].count, 1); free_page(addr); } + printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) diff -u --recursive --new-file v2.1.35/linux/arch/m68k/Makefile linux/arch/m68k/Makefile --- v2.1.35/linux/arch/m68k/Makefile Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/Makefile Thu Apr 17 13:20:40 1997 @@ -36,7 +36,7 @@ LINKFLAGS = -Ttext 0x1000 -CFLAGS := $(CFLAGS) -pipe +CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce ifdef CONFIG_OPTIMIZE_040 CFLAGS := $(CFLAGS) -m68040 @@ -46,40 +46,46 @@ CFLAGS := $(CFLAGS) -m68020-40 endif +ifdef CONFIG_KGDB +# If configured for kgdb support, include debugging infos and keep the +# frame pointer +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g +endif + HEAD := arch/m68k/kernel/head.o SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib -ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES) +CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES) LIBS += arch/m68k/lib/lib.a ifdef CONFIG_AMIGA -ARCHIVES := $(ARCHIVES) arch/m68k/amiga/amiga.o +CORE_FILES := $(CORE_FILES) arch/m68k/amiga/amiga.o SUBDIRS := $(SUBDIRS) arch/m68k/amiga endif ifdef CONFIG_ATARI -ARCHIVES := $(ARCHIVES) arch/m68k/atari/atari.o +CORE_FILES := $(CORE_FILES) arch/m68k/atari/atari.o SUBDIRS := $(SUBDIRS) arch/m68k/atari endif ifdef CONFIG_MAC -ARCHIVES := $(ARCHIVES) arch/m68k/mac/mac.o +CORE_FILES := $(CORE_FILES) arch/m68k/mac/mac.o SUBDIRS := $(SUBDIRS) arch/m68k/mac endif ifdef CONFIG_VT # add in console.a after {amiga,atari}.o that need it -ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a +CORE_FILES := $(CORE_FILES) arch/m68k/console/console.a SUBDIRS := $(SUBDIRS) arch/m68k/console endif ifdef CONFIG_M68040 -ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o +CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040 endif ifdef CONFIG_M68060 -ARCHIVES := $(ARCHIVES) arch/m68k/ifpsp060/ifpsp.o +CORE_FILES := $(CORE_FILES) arch/m68k/ifpsp060/ifpsp.o SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060 endif @@ -92,10 +98,24 @@ cp System.map $(INSTALL_PATH)/System.map if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi -bootstrap: +zImage compressed: vmlinux.gz + +vmlinux.gz: vmlinux + +ifdef CONFIG_KGDB + cp vmlinux vmlinux.tmp + $(STRIP) vmlinux.tmp + gzip -9c vmlinux.tmp >vmlinux.gz + rm vmlinux.tmp +else + gzip -9c vmlinux >vmlinux.gz +endif + +bootstrap: dummy @$(MAKEBOOT) bootstrap archclean: + rm -f vmlinux.gz @$(MAKEBOOT) clean archdep: diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/Makefile linux/arch/m68k/amiga/Makefile --- v2.1.35/linux/arch/m68k/amiga/Makefile Fri Jan 3 01:33:25 1997 +++ linux/arch/m68k/amiga/Makefile Thu Apr 17 13:20:40 1997 @@ -16,4 +16,8 @@ O_OBJS := $(O_OBJS) cyberfb.o endif +ifdef CONFIG_FB_RETINAZ3 +O_OBJS := $(O_OBJS) retz3fb.o +endif + include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/amifb.c linux/arch/m68k/amiga/amifb.c --- v2.1.35/linux/arch/m68k/amiga/amifb.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/amifb.c Thu Apr 17 13:20:41 1997 @@ -1242,6 +1242,7 @@ static int amifbcon_switch(int con); static int amifbcon_updatevar(int con); static void amifbcon_blank(int blank); +static int amifbcon_setcmap(struct fb_cmap *cmap, int con); /* * Internal routines @@ -1315,7 +1316,15 @@ extern struct fb_info *Cyber_fb_init(long *mem_start); static int amifb_Cyber = 0; -#endif /* CONFIG_FB_CYBER */ +#endif + +#ifdef CONFIG_FB_RETINAZ3 /* RetinaZ3 */ +extern int retz3_probe(void); +extern void retz3_video_setup(char *options, int *ints); +extern struct fb_info *retz3_fb_init(long *mem_start); + +static int amifb_retz3 = 0; +#endif #ifdef CONFIG_GSP_RESOLVER /* DMI Resolver */ extern int resolver_probe(void); @@ -1323,7 +1332,7 @@ extern struct fb_info *resolver_fb_init(long *mem_start); static int amifb_resolver = 0; -#endif /* CONFIG_GSP_RESOLVER */ +#endif static struct fb_ops amiga_fb_ops = { amiga_fb_get_fix, amiga_fb_get_var, amiga_fb_set_var, amiga_fb_get_cmap, @@ -1347,7 +1356,15 @@ Cyber_video_setup(options, ints); return; } -#endif /* CONFIG_FB_CYBER */ +#endif +#ifdef CONFIG_FB_RETINAZ3 + if (options && *options) + if (!strncmp(options, "retz3", 5) && retz3_probe()) { + amifb_retz3 = 1; + retz3_video_setup(options, ints); + return; + } +#endif #ifdef CONFIG_GSP_RESOLVER if (options && *options) if (!strncmp(options, "resolver", 5) && resolver_probe()) { @@ -1797,7 +1814,14 @@ #ifdef CONFIG_FB_CYBER if (amifb_Cyber) return Cyber_fb_init(mem_start); -#endif /* CONFIG_FB_CYBER */ +#endif +#ifdef CONFIG_FB_RETINAZ3 + if (amifb_retz3){ + custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | + DMAF_BLITTER | DMAF_SPRITE; + return retz3_fb_init(mem_start); + } +#endif #ifdef CONFIG_GSP_RESOLVER if (amifb_resolver){ custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | @@ -1943,11 +1967,11 @@ check_default_mode(); - if (request_irq(IRQ3, amifb_interrupt, IRQ_FLG_LOCK, + if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, IRQ_FLG_LOCK, "fb vertb handler", NULL)) panic("Couldn't add vblank interrupt\n"); - ami_intena_vals[IRQ_IDX(IRQ_AMIGA_VERTB)] = IF_COPER; - ami_intena_vals[IRQ_IDX(IRQ_AMIGA_COPPER)] = 0; + ami_intena_vals[IRQ_AMIGA_VERTB] = IF_COPER; + ami_intena_vals[IRQ_AMIGA_COPPER] = 0; custom.intena = IF_VERTB; custom.intena = IF_SETCLR | IF_COPER; @@ -1957,6 +1981,7 @@ fb_info.switch_con = &amifbcon_switch; fb_info.updatevar = &amifbcon_updatevar; fb_info.blank = &amifbcon_blank; + fb_info.setcmap = &amifbcon_setcmap; amiga_fb_set_var(&amiga_fb_predefined[0], 0); @@ -1995,6 +2020,15 @@ do_blank = blank ? blank : -1; } + /* + * Set the colormap + */ + +static int amifbcon_setcmap(struct fb_cmap *cmap, int con) +{ + return(amiga_fb_set_cmap(cmap, 1, con)); +} + /* ---------------------------- Generic routines ---------------------------- */ static struct fb_cmap *get_default_colormap(int bpp) @@ -2213,10 +2247,11 @@ { u_short ints = custom.intreqr & custom.intenar; static struct irq_server server = {0, 0}; + unsigned long flags; if (ints & IF_BLIT) { custom.intreq = IF_BLIT; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_BLIT), fp); + amiga_do_irq(IRQ_AMIGA_BLIT, fp); } if (ints & IF_COPER) { @@ -2240,8 +2275,11 @@ ami_set_sprite(); } - if (get_vbpos() < down2(currentpar.diwstrt_v - 4)) + save_flags(flags); + cli(); + if (get_vbpos() < down2(currentpar.diwstrt_v - 6)) custom.copjmp2 = 0; + restore_flags(flags); if (do_blank) { ami_do_blank(); @@ -2252,7 +2290,7 @@ ami_reinit_copper(); do_vmode_full = 0; } - amiga_do_irq_list(IRQ_IDX(IRQ_AMIGA_VERTB), fp, &server); + amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server); } if (ints & IF_VERTB) { diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/amiga_ksyms.c linux/arch/m68k/amiga/amiga_ksyms.c --- v2.1.35/linux/arch/m68k/amiga/amiga_ksyms.c Fri Jan 3 01:33:25 1997 +++ linux/arch/m68k/amiga/amiga_ksyms.c Thu Apr 17 13:20:41 1997 @@ -1,6 +1,7 @@ -#include +#include #include -#include +#include +#include #include extern volatile u_short amiga_audio_min_period; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/amiints.c linux/arch/m68k/amiga/amiints.c --- v2.1.35/linux/arch/m68k/amiga/amiints.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/amiints.c Thu Apr 17 13:20:41 1997 @@ -172,12 +172,16 @@ return -ENXIO; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) - return cia_request_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB), + if (irq >= IRQ_AMIGA_AUTO) + return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler, + flags, devname, dev_id); + + if (irq >= IRQ_AMIGA_CIAB) + return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, handler, flags, devname, dev_id); - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) - return cia_request_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA), + if (irq >= IRQ_AMIGA_CIAA) + return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, handler, flags, devname, dev_id); if (ami_servers[irq]) { @@ -196,7 +200,7 @@ __FUNCTION__, irq, ami_irq_list[irq]->devname); return -EBUSY; } - if (flags & IRQ_FLG_REPLACE) { + if (!(flags & IRQ_FLG_REPLACE)) { printk("%s: %s can't replace IRQ %d from %s\n", __FUNCTION__, devname, irq, ami_irq_list[irq]->devname); return -EBUSY; @@ -209,7 +213,7 @@ } /* enable the interrupt */ - if (irq < IRQ_IDX(IRQ_AMIGA_PORTS) && !ami_ablecount[irq]) + if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) custom.intena = IF_SETCLR | ami_intena_vals[irq]; return 0; @@ -222,20 +226,23 @@ return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) { - cia_free_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB), dev_id); + if (irq >= IRQ_AMIGA_AUTO) + sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); + + if (irq >= IRQ_AMIGA_CIAB) { + cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id); return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) { - cia_free_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA), dev_id); + if (irq >= IRQ_AMIGA_CIAA) { + cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id); return; } if (ami_servers[irq]) { amiga_delete_irq(&ami_irq_list[irq], dev_id); /* if server list empty, disable the interrupt */ - if (!ami_irq_list[irq] && irq < IRQ_IDX(IRQ_AMIGA_PORTS)) + if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) custom.intena = ami_intena_vals[irq]; } else { if (ami_irq_list[irq]->dev_id != dev_id) @@ -267,15 +274,22 @@ if (--ami_ablecount[irq]) return; - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) { + /* No action for auto-vector interrupts */ + if (irq >= IRQ_AMIGA_AUTO){ + printk("%s: Trying to enable auto-vector IRQ %i\n", + __FUNCTION__, irq - IRQ_AMIGA_AUTO); + return; + } + + if (irq >= IRQ_AMIGA_CIAB) { cia_able_irq(&ciab_base, CIA_ICR_SETCLR | - (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB)))); + (1 << (irq - IRQ_AMIGA_CIAB))); return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) { + if (irq >= IRQ_AMIGA_CIAA) { cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | - (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA)))); + (1 << (irq - IRQ_AMIGA_CIAA))); return; } @@ -293,13 +307,20 @@ if (ami_ablecount[irq]++) return; - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) { - cia_able_irq(&ciab_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB))); + /* No action for auto-vector interrupts */ + if (irq >= IRQ_AMIGA_AUTO) { + printk("%s: Trying to disable auto-vector IRQ %i\n", + __FUNCTION__, irq - IRQ_AMIGA_AUTO); + return; + } + + if (irq >= IRQ_AMIGA_CIAB) { + cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) { - cia_able_irq(&ciaa_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA))); + if (irq >= IRQ_AMIGA_CIAA) { + cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); return; } @@ -310,13 +331,12 @@ inline void amiga_do_irq(int irq, struct pt_regs *fp) { kstat.interrupts[SYS_IRQS + irq]++; - ami_irq_list[irq]->handler(irq | IRQ_MACHSPEC, ami_irq_list[irq]->dev_id, fp); + ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); } void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) { irq_node_t *node, *slow_nodes; - int mach_irq = irq | IRQ_MACHSPEC; unsigned short flags; kstat.interrupts[SYS_IRQS + irq]++; @@ -326,7 +346,7 @@ for (node = ami_irq_list[irq]; node && (!(node->flags & IRQ_FLG_SLOW)); node = node->next) - node->handler(mach_irq, node->dev_id, fp); + node->handler(irq, node->dev_id, fp); custom.intreq = ami_intena_vals[irq]; if (!node) { server->count--; @@ -338,7 +358,7 @@ slow_nodes = node; for (;;) { for (; node; node = node->next) - node->handler(mach_irq, node->dev_id, fp); + node->handler(irq, node->dev_id, fp); /* if reentrance occured, serve slow handlers again */ custom.intena = ami_intena_vals[irq]; if (!server->reentrance) { @@ -363,19 +383,19 @@ /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { custom.intreq = IF_TBE; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_TBE), fp); + amiga_do_irq(IRQ_AMIGA_TBE, fp); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { custom.intreq = IF_DSKBLK; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKBLK), fp); + amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { custom.intreq = IF_SOFT; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_SOFT), fp); + amiga_do_irq(IRQ_AMIGA_SOFT, fp); } } @@ -387,18 +407,18 @@ /* if a blitter interrupt */ if (ints & IF_BLIT) { custom.intreq = IF_BLIT; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_BLIT), fp); + amiga_do_irq(IRQ_AMIGA_BLIT, fp); } /* if a copper interrupt */ if (ints & IF_COPER) { custom.intreq = IF_COPER; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_COPPER), fp); + amiga_do_irq(IRQ_AMIGA_COPPER, fp); } /* if a vertical blank interrupt */ if (ints & IF_VERTB) - amiga_do_irq_list(IRQ_IDX(IRQ_AMIGA_VERTB), fp, &server); + amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server); } static void ami_int4(int irq, void *dev_id, struct pt_regs *fp) @@ -408,25 +428,25 @@ /* if audio 0 interrupt */ if (ints & IF_AUD0) { custom.intreq = IF_AUD0; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD0), fp); + amiga_do_irq(IRQ_AMIGA_AUD0, fp); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { custom.intreq = IF_AUD1; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD1), fp); + amiga_do_irq(IRQ_AMIGA_AUD1, fp); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { custom.intreq = IF_AUD2; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD2), fp); + amiga_do_irq(IRQ_AMIGA_AUD2, fp); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { custom.intreq = IF_AUD3; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD3), fp); + amiga_do_irq(IRQ_AMIGA_AUD3, fp); } } @@ -437,13 +457,13 @@ /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { /* acknowledge of IF_RBF must be done by the serial interrupt */ - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_RBF), fp); + amiga_do_irq(IRQ_AMIGA_RBF, fp); } /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { custom.intreq = IF_DSKSYN; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKSYN), fp); + amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); } } diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/cia.c linux/arch/m68k/amiga/cia.c --- v2.1.35/linux/arch/m68k/amiga/cia.c Fri Nov 22 05:56:33 1996 +++ linux/arch/m68k/amiga/cia.c Thu Apr 17 13:20:41 1997 @@ -30,13 +30,13 @@ irq_handler_t irq_list[CIA_IRQS]; } ciaa_base = { &ciaa, 0, 0, IF_PORTS, - IRQ2, IRQ_AMIGA_CIAA, - IRQ_IDX(IRQ_AMIGA_PORTS), + IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA, + IRQ_AMIGA_PORTS, "CIAA handler", {0, 0} }, ciab_base = { &ciab, 0, 0, IF_EXTER, - IRQ6, IRQ_AMIGA_CIAB, - IRQ_IDX(IRQ_AMIGA_EXTER), + IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB, + IRQ_AMIGA_EXTER, "CIAB handler", {0, 0} }; @@ -95,14 +95,14 @@ if (!(base->irq_list[irq].flags & IRQ_FLG_STD)) { if (base->irq_list[irq].flags & IRQ_FLG_LOCK) { - printk("%s: IRQ %ld from %s is not replaceable\n", - __FUNCTION__, IRQ_IDX(base->cia_irq + irq), + printk("%s: IRQ %i from %s is not replaceable\n", + __FUNCTION__, base->cia_irq + irq, base->irq_list[irq].devname); return -EBUSY; } - if (flags & IRQ_FLG_REPLACE) { - printk("%s: %s can't replace IRQ %ld from %s\n", __FUNCTION__, - devname, IRQ_IDX(base->cia_irq + irq), + if (!(flags & IRQ_FLG_REPLACE)) { + printk("%s: %s can't replace IRQ %i from %s\n", __FUNCTION__, + devname, base->cia_irq + irq, base->irq_list[irq].devname); return -EBUSY; } @@ -122,8 +122,8 @@ void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id) { if (base->irq_list[irq].dev_id != dev_id) - printk("%s: removing probably wrong IRQ %ld from %s\n", - __FUNCTION__, IRQ_IDX(base->cia_irq + irq), + printk("%s: removing probably wrong IRQ %i from %s\n", + __FUNCTION__, base->cia_irq + irq, base->irq_list[irq].devname); base->irq_list[irq].handler = NULL; @@ -139,7 +139,7 @@ unsigned char ints; mach_irq = base->cia_irq; - irq = SYS_IRQS + IRQ_IDX(mach_irq); + irq = SYS_IRQS + mach_irq; ints = cia_set_irq(base, CIA_ICR_ALL); custom.intreq = base->int_mask; for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) { @@ -176,7 +176,7 @@ { int i, j, len = 0; - j = IRQ_IDX(base->cia_irq); + j = base->cia_irq; for (i = 0; i < CIA_IRQS; i++) { if (!(base->irq_list[i].flags & IRQ_FLG_STD)) { len += sprintf(buf+len, "cia %2d: %10d ", j + i, diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c --- v2.1.35/linux/arch/m68k/amiga/config.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/config.c Thu Apr 17 13:20:41 1997 @@ -29,7 +29,7 @@ #include #include #include -#include +#include u_long amiga_model; u_long amiga_eclock; @@ -56,7 +56,7 @@ extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *); extern int amiga_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); -extern int amiga_free_irq (unsigned int irq, void *dev_id); +extern void amiga_free_irq (unsigned int irq, void *dev_id); extern void amiga_enable_irq (unsigned int); extern void amiga_disable_irq (unsigned int); static void amiga_get_model(char *model); @@ -74,15 +74,20 @@ extern void amiga_floppy_setup(char *, int *); #endif static void amiga_reset (void); -static void amiga_waitbut(void); +static void amiga_wait_key(void); extern struct consw fb_con; extern struct fb_info *amiga_fb_init(long *); extern void zorro_init(void); -static void ami_savekmsg_init(void); -static void ami_mem_print(const char *b); +static void amiga_savekmsg_init(void); +static void amiga_mem_console_write(const char *b, unsigned int count); +static void amiga_serial_console_write(const char *s, unsigned int count); static void amiga_debug_init(void); + extern void amiga_video_setup(char *, int *); -extern void amiga_syms_export(void); + +static struct console amiga_console_driver = { + NULL, NULL, amiga_wait_key +}; extern void (*kd_mksound)(unsigned int, unsigned int); @@ -151,6 +156,8 @@ memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); + amiga_debug_init(); + printk("Amiga hardware found: "); if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) printk("[%s] ", amiga_models[amiga_model-AMI_500]); @@ -304,8 +311,8 @@ mach_default_handler = &amiga_default_handler; mach_request_irq = amiga_request_irq; mach_free_irq = amiga_free_irq; - mach_enable_irq = amiga_enable_irq; - mach_disable_irq = amiga_disable_irq; + enable_irq = amiga_enable_irq; + disable_irq = amiga_disable_irq; mach_get_model = amiga_get_model; mach_get_hardware_list = amiga_get_hardware_list; mach_get_irq_list = amiga_get_irq_list; @@ -329,18 +336,14 @@ mach_hwclk = amiga_hwclk; mach_set_clock_mmss = amiga_set_clock_mmss; - mach_mksound = amiga_mksound; #ifdef CONFIG_BLK_DEV_FD mach_floppy_init = amiga_floppy_init; mach_floppy_setup = amiga_floppy_setup; #endif mach_reset = amiga_reset; - waitbut = amiga_waitbut; conswitchp = &fb_con; mach_fb_init = amiga_fb_init; - mach_debug_init = amiga_debug_init; mach_video_setup = amiga_video_setup; - mach_syms_export = amiga_syms_export; kd_mksound = amiga_mksound; /* Fill in the clock values (based on the 700 kHz E-Clock) */ @@ -355,10 +358,6 @@ /* initialize chipram allocator */ amiga_chip_init (); - /* initialize only once here, not every time the debug level is raised */ - if (!strcmp( m68k_debug_device, "mem" )) - ami_savekmsg_init(); - /* * if it is an A3000, set the magic bit that forces * a hard rekick @@ -588,7 +587,7 @@ return 0; } -static void amiga_waitbut (void) +static void amiga_wait_key (void) { int i; @@ -614,33 +613,6 @@ } } -void ami_serial_print (const char *str) -{ - while (*str) { - if (*str == '\n') { - custom.serdat = (unsigned char)'\r' | 0x100; - while (!(custom.serdatr & 0x2000)) - ; - } - custom.serdat = (unsigned char)*str++ | 0x100; - while (!(custom.serdatr & 0x2000)) - ; - } -} - -static void amiga_debug_init (void) -{ - extern void (*debug_print_proc)(const char *); - - if (!strcmp( m68k_debug_device, "ser" )) { - /* no initialization required (?) */ - debug_print_proc = ami_serial_print; - } else if (!strcmp( m68k_debug_device, "mem" )) { - /* already initialized by config_amiga() (needed only once) */ - debug_print_proc = ami_mem_print; - } -} - void dbprintf(const char *fmt , ...) { static char buf[1024]; @@ -672,8 +644,10 @@ ("movel %0,%/d0\n\t" "andl #0xff000000,%/d0\n\t" "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ - ".long 0x4e7b0004\n\t" /* movec d0,itt0 */ - ".long 0x4e7b0006\n\t" /* movec d0,dtt0 */ + ".chip 68040\n\t" + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%dtt0\n\t" + ".chip 68k\n\t" "jmp %0@\n\t" : /* no outputs */ : "a" (jmp_addr040)); @@ -692,7 +666,9 @@ /* disable translation on '040 now */ __asm__ __volatile__ ("moveq #0,%/d0\n\t" - ".long 0x4e7b0003\n\t" /* movec d0,tc; disable MMU */ + ".chip 68040\n\t" + "movec %%d0,%%tc\n\t" /* disable MMU */ + ".chip 68k\n\t" : /* no outputs */ : /* no inputs */ : "d0"); @@ -718,12 +694,13 @@ } -extern void *amiga_chip_alloc(long size); + /* + * Debugging + */ #define SAVEKMSG_MAXMEM 128*1024 - #define SAVEKMSG_MAGIC1 0x53415645 /* 'SAVE' */ #define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ @@ -737,8 +714,15 @@ static struct savekmsg *savekmsg = NULL; +static void amiga_mem_console_write(const char *s, unsigned int count) +{ + if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { + memcpy(savekmsg->data+savekmsg->size, s, count); + savekmsg->size += count; + } +} -static void ami_savekmsg_init(void) +static void amiga_savekmsg_init(void) { savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM); savekmsg->magic1 = SAVEKMSG_MAGIC1; @@ -747,18 +731,87 @@ savekmsg->size = 0; } +static void amiga_serial_putc(char c) +{ + custom.serdat = (unsigned char)c | 0x100; + while (!(custom.serdatr & 0x2000)) + ; +} + +static void amiga_serial_console_write(const char *s, unsigned int count) +{ + while (count--) { + if (*s == '\n') + amiga_serial_putc('\r'); + amiga_serial_putc(*s++); + } +} + +#ifdef CONFIG_SERIAL_CONSOLE +void amiga_serial_puts(const char *s) +{ + amiga_serial_console_write(s, strlen(s)); +} -static void ami_mem_print(const char *b) +void amiga_serial_gets(char *s, int len) { - int len; + int ch, cnt = 0; - for (len = 0; b[len]; len++); - if (savekmsg->size+len <= SAVEKMSG_MAXMEM) { - memcpy(savekmsg->data+savekmsg->size, b, len); - savekmsg->size += len; + while (1) { + while (!(custom.intreqr & IF_RBF)) + barrier(); + ch = custom.serdatr & 0xff; + /* clear the interrupt, so that another character can be read */ + custom.intreq = IF_RBF; + + /* Check for backspace. */ + if (ch == 8 || ch == 127) { + if (cnt == 0) { + amiga_serial_putc('\007'); + continue; + } + cnt--; + amiga_serial_puts("\010 \010"); + continue; + } + + /* Check for enter. */ + if (ch == 10 || ch == 13) + break; + + /* See if line is too long. */ + if (cnt >= len + 1) { + amiga_serial_putc(7); + cnt--; + continue; + } + + /* Store and echo character. */ + s[cnt++] = ch; + amiga_serial_putc(ch); + } + /* Print enter. */ + amiga_serial_puts("\r\n"); + s[cnt] = 0; +} +#endif + +static void amiga_debug_init(void) +{ + if (!strcmp( m68k_debug_device, "ser" )) { + /* no initialization required (?) */ + amiga_console_driver.write = amiga_serial_console_write; + } else if (!strcmp( m68k_debug_device, "mem" )) { + amiga_savekmsg_init(); + amiga_console_driver.write = amiga_mem_console_write; } + register_console(&amiga_console_driver); } + + /* + * Amiga specific parts of /proc + */ static void amiga_get_model(char *model) { diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/cyberfb.c linux/arch/m68k/amiga/cyberfb.c --- v2.1.35/linux/arch/m68k/amiga/cyberfb.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/cyberfb.c Thu Apr 17 13:20:41 1997 @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include "s3blit.h" @@ -235,6 +235,7 @@ static int Cyberfb_switch(int con); static int Cyberfb_updatevar(int con); static void Cyberfb_blank(int blank); +static int Cyberfb_setcmap(struct fb_cmap *cmap, int con); /* @@ -1179,6 +1180,7 @@ fb_info.switch_con = &Cyberfb_switch; fb_info.updatevar = &Cyberfb_updatevar; fb_info.blank = &Cyberfb_blank; + fb_info.setcmap = &Cyberfb_setcmap; do_fb_set_var(&Cyber_fb_predefined[0], 1); Cyber_fb_get_var(&disp[0].var, -1); @@ -1222,6 +1224,16 @@ static void Cyberfb_blank(int blank) { fbhw->blank(blank); +} + + + /* + * Set the colormap + */ + +static int Cyberfb_setcmap(struct fb_cmap *cmap, int con) +{ + return(Cyber_fb_set_cmap(cmap, 1, con)); } diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/retz3fb.c linux/arch/m68k/amiga/retz3fb.c --- v2.1.35/linux/arch/m68k/amiga/retz3fb.c Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/amiga/retz3fb.c Tue Apr 22 22:45:15 1997 @@ -0,0 +1,3504 @@ +/* + * Linux/arch/m68k/amiga/retz3fb.c -- Low level implementation of the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * This file is based on the CyberVision64 frame buffer device and + * the generic Cirrus Logic driver. + * + * cyberfb.c: Copyright (C) 1996 Martin Apel, + * Geert Uytterhoeven + * clgen.c: Copyright (C) 1996 Frank Neumann + * + * History: + * - 22 Jan 97: Initial work + * - 14 Feb 97: Screen initialization works somewhat, still only + * 8-bit packed pixel is supported. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "retz3fb.h" + +/* #define DEBUG if(1) */ +#define DEBUG if(0) + +/* + * Reserve space for one pattern line. + * + * For the time being we only support 4MB boards! + */ + +#define PAT_MEM_SIZE 16*3 +#define PAT_MEM_OFF (4*1024*1024 - PAT_MEM_SIZE) + +#define arraysize(x) (sizeof(x)/sizeof(*(x))) + +struct retz3_fb_par { + int xres; + int yres; + int xres_vir; + int yres_vir; + int xoffset; + int yoffset; + int bpp; + + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + + int pixclock; + int left_margin; /* time from sync to picture */ + int right_margin; /* time from picture to sync */ + int upper_margin; /* time from sync to picture */ + int lower_margin; + int hsync_len; /* length of horizontal sync */ + int vsync_len; /* length of vertical sync */ + int vmode; +}; + +struct display_data { + long h_total; /* Horizontal Total */ + long h_sstart; /* Horizontal Sync Start */ + long h_sstop; /* Horizontal Sync Stop */ + long h_bstart; /* Horizontal Blank Start */ + long h_bstop; /* Horizontal Blank Stop */ + long h_dispend; /* Horizontal Display End */ + long v_total; /* Vertical Total */ + long v_sstart; /* Vertical Sync Start */ + long v_sstop; /* Vertical Sync Stop */ + long v_bstart; /* Vertical Blank Start */ + long v_bstop; /* Vertical Blank Stop */ + long v_dispend; /* Horizontal Display End */ +}; + +static struct retz3_fb_par current_par; + +static int current_par_valid = 0; +static int currcon = 0; + +static struct display disp[MAX_NR_CONSOLES]; +static struct fb_info fb_info; + +static int node; /* node of the /dev/fb?current file */ + + +/* + * Switch for Chipset Independency + */ + +static struct fb_hwswitch { + + /* Initialisation */ + + int (*init)(void); + + /* Display Control */ + + int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3_fb_par *par); + int (*decode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*encode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned + int *green, unsigned int *blue, unsigned int *transp); + int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int + green, unsigned int blue, unsigned int transp); + void (*blank)(int blank); +} *fbhw; + + +/* + * Frame Buffer Name + */ + +static char retz3_fb_name[16] = "RetinaZ3"; + + +static int z3_key = 0; +static unsigned char retz3_color_table [256][4]; +static unsigned long z3_mem; +static unsigned long z3_fbmem; +static unsigned long z3_size; +static volatile unsigned char *z3_regs; + +static long *memstart; + + +/* + * Predefined Video Mode Names + */ + +static char *retz3_fb_modenames[] = { + + /* + * Autodetect (Default) Video Mode + */ + + "default", + + /* + * Predefined Video Modes + */ + + "640x480", /* RetinaZ3 8 bpp */ + "800x600", /* RetinaZ3 8 bpp */ + "1024x768i", + "640x480-16", /* RetinaZ3 16 bpp */ + "640x480-24", /* RetinaZ3 24 bpp */ + + /* + * Dummy Video Modes + */ + + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + + /* + * User Defined Video Modes + * + * This doesn't work yet!! + */ + + "user0", "user1", "user2", "user3", + "user4", "user5", "user6", "user7" +}; + +/* + * A small info on how to convert XFree86 timing values into fb + * timings - by Frank Neumann: + * +An XFree86 mode line consists of the following fields: + "800x600" 50 800 856 976 1040 600 637 643 666 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + +The fields in the fb_var_screeninfo structure are: + unsigned long pixclock; * pixel clock in ps (pico seconds) * + unsigned long left_margin; * time from sync to picture * + unsigned long right_margin; * time from picture to sync * + unsigned long upper_margin; * time from sync to picture * + unsigned long lower_margin; + unsigned long hsync_len; * length of horizontal sync * + unsigned long vsync_len; * length of vertical sync * + +1) Pixelclock: + xfree: in MHz + fb: In Picoseconds (ps) + + pixclock = 1000000 / DCF + +2) horizontal timings: + left_margin = HFL - SH2 + right_margin = SH1 - HR + hsync_len = SH2 - SH1 + +3) vertical timings: + upper_margin = VFL - SV2 + lower_margin = SV1 - VR + vsync_len = SV2 - SV1 + +Good examples for VESA timings can be found in the XFree86 source tree, +under "programs/Xserver/hw/xfree86/doc/modeDB.txt". +*/ + +/* + * Predefined Video Mode Definitions + */ + +static struct fb_var_screeninfo retz3_fb_predefined[] = { + + /* + * Autodetect (Default) Video Mode + */ + + { 0, }, + + /* + * Predefined Video Modes + */ + + /* + * NB: it is very important to adjust the pixel-clock to the color-depth. + */ + + { + 640, 480, 640, 480, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 800 x 600, 8 bpp */ + 800, 600, 800, 600, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 1024 x 768, 8 bpp, interlaced */ + 1024, 768, 1024, 768, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 16, 0, + {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 24, 0, + {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + + /* + * Dummy Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, + + /* + * User Defined Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } +}; + + +#define NUM_TOTAL_MODES arraysize(retz3_fb_predefined) +#define NUM_PREDEF_MODES (5) + + +static int z3fb_inverse = 0; +static int z3fb_mode = 0; + + +/* + * Interface used by the world + */ + +int retz3_probe(void); +void retz3_video_setup(char *options, int *ints); + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con); +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con); +static int retz3_fb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, int con); + + +/* + * Interface to the low level console driver + */ + +struct fb_info *retz3_fb_init(long *mem_start); /* Through amiga_fb_init() */ +static int z3fb_switch(int con); +static int z3fb_updatevar(int con); +static void z3fb_blank(int blank); +static int z3fb_setcmap(struct fb_cmap *cmap, int con); + + +/* + * Accelerated Functions used by the low level console driver + */ + +void retz3_bitblt(struct fb_var_screeninfo *scr, + unsigned short curx, unsigned short cury, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask); +void retz3_fill(unsigned short x, unsigned short y, unsigned short + width, unsigned short height, unsigned short mode, + unsigned short color); + +/* + * Hardware Specific Routines + */ + +static int retz3_init(void); +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par); +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp); +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp); +static void retz3_blank(int blank); + + +/* + * Internal routines + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par); +static void retz3_fb_set_par(struct retz3_fb_par *par); +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); +static struct fb_cmap *get_default_colormap(int bpp); +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static void do_install_cmap(int con); +static void memcpy_fs(int fsfromto, void *to, void *from, int len); +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto); +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp); +static void retz3_fb_set_disp(int con); +static int get_video_mode(const char *name); + + +/* -------------------- Hardware specific routines -------------------------- */ + +static unsigned short find_fq(unsigned int freq) +{ + unsigned long f; + long tmp; + long prev = 0x7fffffff; + long n2, n1 = 3; + unsigned long m; + unsigned short res = 0; + + if (freq <= 31250000) + n2 = 3; + else if (freq <= 62500000) + n2 = 2; + else if (freq <= 125000000) + n2 = 1; + else if (freq <= 250000000) + n2 = 0; + else + return(0); + + + do { + f = freq >> (10 - n2); + + m = (f * n1) / (14318180/1024); + + if (m > 129) + break; + + tmp = (((m * 14318180) >> n2) / n1) - freq; + if (tmp < 0) + tmp = -tmp; + + if (tmp < prev) { + prev = tmp; + res = (((n2 << 5) | (n1-2)) << 8) | (m-2); + } + + } while ( (++n1) <= 21); + + return res; +} + + +static int retz3_set_video(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + float freq_f; + long freq; + + int xres, hfront, hsync, hback; + int yres, vfront, vsync, vback; + unsigned char tmp; + unsigned short best_freq; + struct display_data data; + + short clocksel = 0; /* Apparantly this is always zero */ + + int bpp = var->bits_per_pixel; + + /* + * XXX + */ + if (bpp == 24) + return 0; + + if ((bpp != 8) && (bpp != 16) && (bpp != 24)) + return -EFAULT; + + par->xoffset = 0; + par->yoffset = 0; + + xres = var->xres * bpp / 4; + hfront = var->right_margin * bpp / 4; + hsync = var->hsync_len * bpp / 4; + hback = var->left_margin * bpp / 4; + + if (var->vmode & FB_VMODE_DOUBLE) + { + yres = var->yres * 2; + vfront = var->lower_margin * 2; + vsync = var->vsync_len * 2; + vback = var->upper_margin * 2; + } + else if (var->vmode & FB_VMODE_INTERLACED) + { + yres = (var->yres + 1) / 2; + vfront = (var->lower_margin + 1) / 2; + vsync = (var->vsync_len + 1) / 2; + vback = (var->upper_margin + 1) / 2; + } + else + { + yres = var->yres; /* -1 ? */ + vfront = var->lower_margin; + vsync = var->vsync_len; + vback = var->upper_margin; + } + + data.h_total = (hback / 8) + (xres / 8) + + (hfront / 8) + (hsync / 8) - 1 /* + 1 */; + data.h_dispend = ((xres + bpp - 1)/ 8) - 1; + data.h_bstart = xres / 8 /* + 1 */; + + data.h_bstop = data.h_total+1 + 2 + 1; + data.h_sstart = (xres / 8) + (hfront / 8) + 1; + data.h_sstop = (xres / 8) + (hfront / 8) + (hsync / 8) + 1; + + data.v_total = yres + vfront + vsync + vback - 1; + + data.v_dispend = yres - 1; + data.v_bstart = yres; + + data.v_bstop = data.v_total; + data.v_sstart = yres + vfront - 1 - 2; + data.v_sstop = yres + vfront + vsync - 1; + +#if 0 /* testing */ + + printk("HBS: %i\n", data.h_bstart); + printk("HSS: %i\n", data.h_sstart); + printk("HSE: %i\n", data.h_sstop); + printk("HBE: %i\n", data.h_bstop); + printk("HT: %i\n", data.h_total); + + printk("hsync: %i\n", hsync); + printk("hfront: %i\n", hfront); + printk("hback: %i\n", hback); + + printk("VBS: %i\n", data.v_bstart); + printk("VSS: %i\n", data.v_sstart); + printk("VSE: %i\n", data.v_sstop); + printk("VBE: %i\n", data.v_bstop); + printk("VT: %i\n", data.v_total); + + printk("vsync: %i\n", vsync); + printk("vfront: %i\n", vfront); + printk("vback: %i\n", vback); +#endif + + if (data.v_total >= 1024) + printk("MAYDAY: v_total >= 1024; bailing out!\n"); + + reg_w(GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04)); + reg_w(GREG_FEATURE_CONTROL_W, 0x00); + + seq_w(SEQ_RESET, 0x00); + seq_w(SEQ_RESET, 0x03); /* reset sequencer logic */ + + /* + * CLOCKING_MODE bits: + * 2: This one is only set for certain text-modes, wonder if + * it may be for EGA-lines? (it was referred to as CLKDIV2) + * (The CL drivers sets it to 0x21 with the comment: + * FullBandwidth (video off) and 8/9 dot clock) + */ + seq_w(SEQ_CLOCKING_MODE, 0x01 | 0x00 /* 0x08 */); + + seq_w(SEQ_MAP_MASK, 0x0f); /* enable writing to plane 0-3 */ + seq_w(SEQ_CHAR_MAP_SELECT, 0x00); /* doesn't matter in gfx-mode */ + seq_w(SEQ_MEMORY_MODE, 0x06); /* CL driver says 0x0e for 256 col mode*/ + seq_w(SEQ_RESET, 0x01); + seq_w(SEQ_RESET, 0x03); + + seq_w(SEQ_EXTENDED_ENABLE, 0x05); + + seq_w(SEQ_CURSOR_CONTROL, 0x00); /* disable cursor */ + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_LINEAR_0, 0x4a); + seq_w(SEQ_LINEAR_1, 0x00); + + seq_w(SEQ_SEC_HOST_OFF_HI, 0x00); + seq_w(SEQ_SEC_HOST_OFF_LO, 0x00); + seq_w(SEQ_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); + + /* + * The lower 4 bits (0-3) are used to set the font-width for + * text-mode - DON'T try to set this for gfx-mode. + */ + seq_w(SEQ_EXT_CLOCK_MODE, 0x10); + seq_w(SEQ_EXT_VIDEO_ADDR, 0x03); + + /* + * Extended Pixel Control: + * bit 0: text-mode=0, gfx-mode=1 (Graphics Byte ?) + * bit 1: (Packed/Nibble Pixel Format ?) + * bit 4-5: depth, 0=1-8bpp, 1=9-16bpp, 2=17-24bpp + */ + seq_w(SEQ_EXT_PIXEL_CNTL, 0x01 | (((bpp / 8) - 1) << 4)); + + seq_w(SEQ_BUS_WIDTH_FEEDB, 0x04); + seq_w(SEQ_COLOR_EXP_WFG, 0x01); + seq_w(SEQ_COLOR_EXP_WBG, 0x00); + seq_w(SEQ_EXT_RW_CONTROL, 0x00); + seq_w(SEQ_MISC_FEATURE_SEL, (0x51 | (clocksel & 8))); + seq_w(SEQ_COLOR_KEY_CNTL, 0x40); + seq_w(SEQ_COLOR_KEY_MATCH0, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH1, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH2, 0x00); + seq_w(SEQ_CRC_CONTROL, 0x00); + seq_w(SEQ_PERF_SELECT, 0x10); + seq_w(SEQ_ACM_APERTURE_1, 0x00); + seq_w(SEQ_ACM_APERTURE_2, 0x30); + seq_w(SEQ_ACM_APERTURE_3, 0x00); + seq_w(SEQ_MEMORY_MAP_CNTL, 0x03); + + + /* unlock register CRT0..CRT7 */ + crt_w(CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20); + + /* Zuerst zu schreibende Werte nur per printk ausgeben */ + DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total); + crt_w(CRT_HOR_TOTAL, data.h_total & 0xff); + + DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend); + crt_w(CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff); + + DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart); + crt_w(CRT_START_HOR_BLANK, data.h_bstart & 0xff); + + DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32); + crt_w(CRT_END_HOR_BLANK, 0x80 | (data.h_bstop & 0x1f)); + + DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart); + crt_w(CRT_START_HOR_RETR, data.h_sstart & 0xff); + + tmp = (data.h_sstop & 0x1f); + if (data.h_bstop & 0x20) + tmp |= 0x80; + DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp); + crt_w(CRT_END_HOR_RETR, tmp); + + DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff); + crt_w(CRT_VER_TOTAL, (data.v_total & 0xff)); + + tmp = 0x10; /* LineCompare bit #9 */ + if (data.v_total & 256) + tmp |= 0x01; + if (data.v_dispend & 256) + tmp |= 0x02; + if (data.v_sstart & 256) + tmp |= 0x04; + if (data.v_bstart & 256) + tmp |= 0x08; + if (data.v_total & 512) + tmp |= 0x20; + if (data.v_dispend & 512) + tmp |= 0x40; + if (data.v_sstart & 512) + tmp |= 0x80; + DEBUG printk("CRT_OVERFLOW: %d\n", tmp); + crt_w(CRT_OVERFLOW, tmp); + + crt_w(CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */ + + tmp = 0x40; /* LineCompare bit #8 */ + if (data.v_bstart & 512) + tmp |= 0x20; + if (var->vmode & FB_VMODE_DOUBLE) + tmp |= 0x80; + DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp); + crt_w(CRT_MAX_SCAN_LINE, tmp); + + crt_w(CRT_CURSOR_START, 0x00); + crt_w(CRT_CURSOR_END, 8 & 0x1f); /* font height */ + + crt_w(CRT_START_ADDR_HIGH, 0x00); + crt_w(CRT_START_ADDR_LOW, 0x00); + + crt_w(CRT_CURSOR_LOC_HIGH, 0x00); + crt_w(CRT_CURSOR_LOC_LOW, 0x00); + + DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff); + crt_w(CRT_START_VER_RETR, (data.v_sstart & 0xff)); + +#if 1 + /* 5 refresh cycles per scanline */ + DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20)); +#else + DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32)); +#endif + DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff); + crt_w(CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff)); + + DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff); + crt_w(CRT_START_VER_BLANK, (data.v_bstart & 0xff)); + + DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff); + crt_w(CRT_END_VER_BLANK, (data.v_bstop & 0xff)); + + DEBUG printk("CRT_MODE_CONTROL: 0xe3\n"); + crt_w(CRT_MODE_CONTROL, 0xe3); + + DEBUG printk("CRT_LINE_COMPARE: 0xff\n"); + crt_w(CRT_LINE_COMPARE, 0xff); + + tmp = (var->xres_virtual / 8) * (bpp / 8); + crt_w(CRT_OFFSET, tmp); + + crt_w(CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */ + + tmp = 0x20; /* Enable extended end bits */ + if (data.h_total & 0x100) + tmp |= 0x01; + if ((data.h_dispend) & 0x100) + tmp |= 0x02; + if (data.h_bstart & 0x100) + tmp |= 0x04; + if (data.h_sstart & 0x100) + tmp |= 0x08; + if (var->vmode & FB_VMODE_INTERLACED) + tmp |= 0x10; + DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp); + crt_w(CRT_EXT_HOR_TIMING1, tmp); + + tmp = 0x00; + if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100) + tmp |= 0x10; + crt_w(CRT_EXT_START_ADDR, tmp); + + tmp = 0x00; + if (data.h_total & 0x200) + tmp |= 0x01; + if ((data.h_dispend) & 0x200) + tmp |= 0x02; + if (data.h_bstart & 0x200) + tmp |= 0x04; + if (data.h_sstart & 0x200) + tmp |= 0x08; + tmp |= ((data.h_bstop & 0xc0) >> 2); + tmp |= ((data.h_sstop & 0x60) << 1); + crt_w(CRT_EXT_HOR_TIMING2, tmp); + DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp); + + tmp = 0x10; /* Line compare bit 10 */ + if (data.v_total & 0x400) + tmp |= 0x01; + if ((data.v_dispend) & 0x400) + tmp |= 0x02; + if (data.v_bstart & 0x400) + tmp |= 0x04; + if (data.v_sstart & 0x400) + tmp |= 0x08; + tmp |= ((data.v_bstop & 0x300) >> 3); + if (data.v_sstop & 0x10) + tmp |= 0x80; + crt_w(CRT_EXT_VER_TIMING, tmp); + DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp); + + crt_w(CRT_MONITOR_POWER, 0x00); + + /* + * Convert from ps to Hz. + */ + freq_f = (1.0/(float)var->pixclock) * 1000000000; + freq = ((long)freq_f) * 1000; + + best_freq = find_fq(freq); + pll_w(0x02, best_freq); + best_freq = find_fq(61000000); + pll_w(0x0a, best_freq); + pll_w(0x0e, 0x22); + + gfx_w(GFX_SET_RESET, 0x00); + gfx_w(GFX_ENABLE_SET_RESET, 0x00); + gfx_w(GFX_COLOR_COMPARE, 0x00); + gfx_w(GFX_DATA_ROTATE, 0x00); + gfx_w(GFX_READ_MAP_SELECT, 0x00); + gfx_w(GFX_GRAPHICS_MODE, 0x00); + gfx_w(GFX_MISC, 0x05); + gfx_w(GFX_COLOR_XCARE, 0x0f); + gfx_w(GFX_BITMASK, 0xff); + + reg_r(ACT_ADDRESS_RESET); + attr_w(ACT_PALETTE0 , 0x00); + attr_w(ACT_PALETTE1 , 0x01); + attr_w(ACT_PALETTE2 , 0x02); + attr_w(ACT_PALETTE3 , 0x03); + attr_w(ACT_PALETTE4 , 0x04); + attr_w(ACT_PALETTE5 , 0x05); + attr_w(ACT_PALETTE6 , 0x06); + attr_w(ACT_PALETTE7 , 0x07); + attr_w(ACT_PALETTE8 , 0x08); + attr_w(ACT_PALETTE9 , 0x09); + attr_w(ACT_PALETTE10, 0x0a); + attr_w(ACT_PALETTE11, 0x0b); + attr_w(ACT_PALETTE12, 0x0c); + attr_w(ACT_PALETTE13, 0x0d); + attr_w(ACT_PALETTE14, 0x0e); + attr_w(ACT_PALETTE15, 0x0f); + reg_r(ACT_ADDRESS_RESET); + + attr_w(ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */ + + attr_w(ACT_OVERSCAN_COLOR, 0x00); + attr_w(ACT_COLOR_PLANE_ENA, 0x0f); + attr_w(ACT_HOR_PEL_PANNING, 0x00); + attr_w(ACT_COLOR_SELECT, 0x00); + + reg_r(ACT_ADDRESS_RESET); + reg_w(ACT_DATA, 0x20); + + reg_w(VDAC_MASK, 0xff); + + /* + * Extended palette adressing ??? + */ + switch (bpp){ + case 8: + reg_w(0x83c6, 0x00); + break; + case 16: + reg_w(0x83c6, 0x60); + break; + case 24: + reg_w(0x83c6, 0xe0); + break; + default: + printk("Illegal color-depth: %i\n", bpp); + } + + reg_w(VDAC_ADDRESS, 0x00); + + seq_w(SEQ_MAP_MASK, 0x0f ); + + return 0; +} + +/* + * Initialization + * + * Set the default video mode for this chipset. If a video mode was + * specified on the command line, it will override the default mode. + */ + +static int retz3_init(void) +{ + int i; +#if 0 + volatile unsigned long *CursorBase; +#endif + unsigned long board_addr, board_size; + struct ConfigDev *cd; + + cd = zorro_get_board (z3_key); + zorro_config_board (z3_key, 0); + board_addr = (unsigned long)cd->cd_BoardAddr; + board_size = (unsigned long)cd->cd_BoardSize; + + for (i = 0; i < 256; i++){ + for (i = 0; i < 256; i++){ + retz3_color_table [i][0] = i; + retz3_color_table [i][1] = i; + retz3_color_table [i][2] = i; + retz3_color_table [i][3] = 0; + } + } + + *memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + + z3_mem = kernel_map (board_addr, board_size, + KERNELMAP_NOCACHE_SER, memstart); + + z3_regs = (char*) z3_mem; + z3_fbmem = z3_mem + VIDEO_MEM_OFFSET; + + /* Get memory size - for now we asume its a 4MB board */ + + z3_size = 0x00400000; /* 4 MB */ + + memset ((char*)z3_fbmem, 0, z3_size); + + /* Disable hardware cursor */ + + seq_w(SEQ_CURSOR_Y_INDEX, 0x00); + + +#if 0 + /* Initialize hardware cursor */ + CursorBase = (unsigned long *)((char *)(z3_mem) + z3_size - 0x400); + for (i=0; i < 8; i++){ + *(CursorBase +(i*4)) = 0xffffff00; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } + for (i=8; i < 64; i++){ + *(CursorBase +(i*4)) = 0xffff0000; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } +#endif + + retz3_setcolreg (255, 56, 100, 160, 0); + retz3_setcolreg (254, 0, 0, 0, 0); + + return 0; +} + + +/* + * This function should fill in the `fix' structure based on the + * values in the `par' structure. + */ + +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par) +{ + int i; + + strcpy(fix->id, retz3_fb_name); + fix->smem_start = z3_fbmem; + fix->smem_len = z3_size; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->type_aux = 0; + if (par->bpp == 8) + fix->visual = FB_VISUAL_PSEUDOCOLOR; + else + fix->visual = FB_VISUAL_DIRECTCOLOR; + + fix->xpanstep = 0; + fix->ypanstep = 0; + fix->ywrapstep = 0; + fix->line_length = 0; + + for (i = 0; i < arraysize(fix->reserved); i++) + fix->reserved[i] = 0; + + return 0; +} + + +/* + * Get the video params out of `var'. If a value doesn't fit, round + * it up, if it's too big, return -EINVAL. + */ + +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + par->xres = var->xres; + par->yres = var->yres; + par->xres_vir = var->xres_virtual; + par->yres_vir = var->yres_virtual; + par->bpp = var->bits_per_pixel; + par->pixclock = var->pixclock; + par->vmode = var->vmode; + + par->red = var->red; + par->green = var->green; + par->blue = var->blue; + par->transp = var->transp; + + par->left_margin = var->left_margin; + par->right_margin = var->right_margin; + par->upper_margin = var->upper_margin; + par->lower_margin = var->lower_margin; + par->hsync_len = var->hsync_len; + par->vsync_len = var->vsync_len; + + return 0; +} + + +/* + * Fill the `var' structure based on the values in `par' and maybe + * other values read out of the hardware. + */ + +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + int i; + + var->xres = par->xres; + var->yres = par->yres; + var->xres_virtual = par->xres_vir; + var->yres_virtual = par->yres_vir; + var->xoffset = 0; + var->yoffset = 0; + + var->bits_per_pixel = par->bpp; + var->grayscale = 0; + + var->red = par->red; + var->green = par->green; + var->blue = par->blue; + var->transp = par->transp; + + var->nonstd = 0; + var->activate = 0; + + var->height = -1; + var->width = -1; + + var->accel = FB_ACCEL_RETINAZ3; + + var->pixclock = par->pixclock; + + var->sync = 0; /* ??? */ + var->left_margin = par->left_margin; + var->right_margin = par->right_margin; + var->upper_margin = par->upper_margin; + var->lower_margin = par->lower_margin; + var->hsync_len = par->hsync_len; + var->vsync_len = par->vsync_len; + + for (i = 0; i < arraysize(var->reserved); i++) + var->reserved[i] = 0; + + var->vmode = par->vmode; + return 0; +} + + +/* + * Set a single color register. The values supplied are already + * rounded down to the hardware's capabilities (according to the + * entries in the var structure). Return != 0 for invalid regno. + */ + +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp) +{ + /* We'll get to this */ + + if (regno > 255) + return 1; + + retz3_color_table [regno][0] = red & 0xff; + retz3_color_table [regno][1] = green & 0xff; + retz3_color_table [regno][2] = blue & 0xff; + retz3_color_table [regno][3] = transp; + + reg_w(VDAC_ADDRESS_W, regno); + reg_w(VDAC_DATA, (red & 0xff) >> 2); + reg_w(VDAC_DATA, (green & 0xff) >> 2); + reg_w(VDAC_DATA, (blue & 0xff) >> 2); + + return 0; +} + + +/* + * Read a single color register and split it into + * colors/transparent. Return != 0 for invalid regno. + */ + +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp) +{ + if (regno > 255) + return 1; + *red = retz3_color_table [regno][0]; + *green = retz3_color_table [regno][1]; + *blue = retz3_color_table [regno][2]; + *transp = retz3_color_table [regno][3]; + return 0; +} + + +/* + * (Un)Blank the screen + */ + +void retz3_blank(int blank) +{ + int i; + + if (blank) + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + } + else + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, retz3_color_table [i][0] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][1] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][2] >> 2); + } +} + + +void retz3_bitblt (struct fb_var_screeninfo *var, + unsigned short srcx, unsigned short srcy, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask) +{ + + volatile unsigned long *acm = (unsigned long *) (z3_mem + ACM_OFFSET); + unsigned long *pattern = (unsigned long *)(z3_fbmem + PAT_MEM_OFF); + + unsigned short mod; + unsigned long tmp; + unsigned long pat, src, dst; + unsigned char blt_status; + + int i, xres_virtual = var->xres_virtual; + short bpp = (var->bits_per_pixel & 0xff); + + if (bpp < 8) + bpp = 8; + + tmp = mask | (mask << 16); + +#if 0 + /* + * Check for blitter finished before we start messing with the + * pattern. + */ + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + }while ((blt_status & 1) == 0); +#endif + + i = 0; + do{ + *pattern++ = tmp; + }while(i++ < bpp/4); + + tmp = cmd << 8; + *(acm + ACM_RASTEROP_ROTATION/4) = tmp; + + mod = 0xc0c2; + + pat = 8 * PAT_MEM_OFF; + dst = bpp * (destx + desty * xres_virtual); + + /* + * Source is not set for clear. + */ + if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) { + src = bpp * (srcx + srcy * xres_virtual); + + if (destx > srcx) { + mod &= ~0x8000; + src += bpp * (width - 1); + dst += bpp * (width - 1); + pat += bpp * 2; + } + if (desty > srcy) { + mod &= ~0x4000; + src += bpp * (height - 1) * xres_virtual; + dst += bpp * (height - 1) * xres_virtual; + pat += bpp * 4; + } + + *(acm + ACM_SOURCE/4) = cpu_to_le32(src); + } + + *(acm + ACM_PATTERN/4) = cpu_to_le32(pat); + + *(acm + ACM_DESTINATION/4) = cpu_to_le32(dst); + + tmp = mod << 16; + *(acm + ACM_CONTROL/4) = tmp; + + tmp = width | (height << 16); + + *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp); + + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; + + /* + * No reason to wait for the blitter to finish, it is better + * just to check if it has finished before we use it again. + */ +#if 1 +#if 0 + while ((*(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)) & 1) == 0); +#else + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + } + while ((blt_status & 1) == 0); +#endif +#endif +} + +#if 0 +void retz3_fill (unsigned short x, unsigned short y, unsigned + short width, unsigned short height, + unsigned short mode, unsigned short color) +{ + +} +#endif + + +/************************************************************** + * Move cursor to x, y + */ +void retz3_MoveCursor (unsigned short x, unsigned short y) +{ + /* Guess we gotta deal with the cursor at some point */ +} + + +/* -------------------- Interfaces to hardware functions -------------------- */ + + +static struct fb_hwswitch retz3_switch = { + retz3_init, retz3_encode_fix, retz3_decode_var, retz3_encode_var, + retz3_getcolreg, retz3_setcolreg, retz3_blank +}; + + +/* -------------------- Generic routines ------------------------------------ */ + + +/* + * Fill the hardware's `par' structure. + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par) +{ + if (current_par_valid) + *par = current_par; + else + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], par); +} + + +static void retz3_fb_set_par(struct retz3_fb_par *par) +{ + current_par = *par; + current_par_valid = 1; +} + + +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) +{ + int err, activate; + struct retz3_fb_par par; + + if ((err = fbhw->decode_var(var, &par))) + return err; + activate = var->activate; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) + retz3_fb_set_par(&par); + fbhw->encode_var(var, &par); + var->activate = activate; + +#if 1 + retz3_set_video(var, ¤t_par); +#endif + return 0; +} + + +/* + * Default Colormaps + */ + +static unsigned short red16[] = + { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000, + 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff }; +static unsigned short green16[] = + { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000, + 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff }; +static unsigned short blue16[] = + { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, + 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff }; + + +static struct fb_cmap default_16_colors = + { 0, 16, red16, green16, blue16, NULL }; + + +static struct fb_cmap *get_default_colormap(int bpp) +{ + return &default_16_colors; +} + + +#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) +#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ + ((1<<(width))-1)) : 0)) + +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp)) + return 0; + hred = CNVT_FROMHW(hred, var->red.length); + hgreen = CNVT_FROMHW(hgreen, var->green.length); + hblue = CNVT_FROMHW(hblue, var->blue.length); + htransp = CNVT_FROMHW(htransp, var->transp.length); + if (kspc) { + *red = hred; + *green = hgreen; + *blue = hblue; + if (transp) + *transp = htransp; + } else { + put_user(hred, red); + put_user(hgreen, green); + put_user(hblue, blue); + if (transp) + put_user(htransp, transp); + } + red++; + green++; + blue++; + if (transp) + transp++; + } + return 0; +} + + +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (kspc) { + hred = *red; + hgreen = *green; + hblue = *blue; + htransp = transp ? *transp : 0; + } else { + get_user(hred, red); + get_user(hgreen, green); + get_user(hblue, blue); + if (transp) + get_user(htransp, transp); + else + htransp = 0; + } + hred = CNVT_TOHW(hred, var->red.length); + hgreen = CNVT_TOHW(hgreen, var->green.length); + hblue = CNVT_TOHW(hblue, var->blue.length); + htransp = CNVT_TOHW(htransp, var->transp.length); + red++; + green++; + blue++; + if (transp) + transp++; + if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp)) + return 0; + } + return 0; +} + + +static void do_install_cmap(int con) +{ + if (con != currcon) + return; + if (disp[con].cmap.len) + do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1); + else + do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + &disp[con].var, 1); +} + + +static void memcpy_fs(int fsfromto, void *to, void *from, int len) +{ + switch (fsfromto) { + case 0: + memcpy(to, from, len); + return; + case 1: + copy_from_user(to, from, len); + return; + case 2: + copy_to_user(to, from, len); + return; + } +} + + +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto) +{ + int size; + int tooff = 0, fromoff = 0; + + if (to->start > from->start) + fromoff = to->start-from->start; + else + tooff = from->start-to->start; + size = to->len-tooff; + if (size > from->len-fromoff) + size = from->len-fromoff; + if (size < 0) + return; + size *= sizeof(unsigned short); + memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size); + memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size); + memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size); + if (from->transp && to->transp) + memcpy_fs(fsfromto, to->transp+tooff, + from->transp+fromoff, size); +} + + +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp) +{ + int size = len*sizeof(unsigned short); + + if (cmap->len != len) { + if (cmap->red) + kfree(cmap->red); + if (cmap->green) + kfree(cmap->green); + if (cmap->blue) + kfree(cmap->blue); + if (cmap->transp) + kfree(cmap->transp); + cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; + cmap->len = 0; + if (!len) + return 0; + if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) + return -1; + if (transp) { + if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) + return -1; + } else + cmap->transp = NULL; + } + cmap->start = 0; + cmap->len = len; + copy_cmap(get_default_colormap(len), cmap, 0); + return 0; +} + + +/* + * Get the Fixed Part of the Display + */ + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) + retz3_fb_get_par(&par); + else + error = fbhw->decode_var(&disp[con].var, &par); + return(error ? error : fbhw->encode_fix(fix, &par)); +} + + +/* + * Get the User Defined Part of the Display + */ + +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) { + retz3_fb_get_par(&par); + error = fbhw->encode_var(var, &par); + } else + *var = disp[con].var; + return error; +} + + +static void retz3_fb_set_disp(int con) +{ + struct fb_fix_screeninfo fix; + + retz3_fb_get_fix(&fix, con); + if (con == -1) + con = 0; + disp[con].screen_base = (unsigned char *)fix.smem_start; + disp[con].visual = fix.visual; + disp[con].type = fix.type; + disp[con].type_aux = fix.type_aux; + disp[con].ypanstep = fix.ypanstep; + disp[con].ywrapstep = fix.ywrapstep; + disp[con].can_soft_blank = 1; + disp[con].inverse = z3fb_inverse; +} + + +/* + * Set the User Defined Part of the Display + */ + +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) +{ + int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp; + + if ((err = do_fb_set_var(var, con == currcon))) + return err; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { + oldxres = disp[con].var.xres; + oldyres = disp[con].var.yres; + oldvxres = disp[con].var.xres_virtual; + oldvyres = disp[con].var.yres_virtual; + oldbpp = disp[con].var.bits_per_pixel; + disp[con].var = *var; + if (oldxres != var->xres || oldyres != var->yres || + oldvxres != var->xres_virtual || + oldvyres != var->yres_virtual || + oldbpp != var->bits_per_pixel) { + retz3_fb_set_disp(con); + (*fb_info.changevar)(con); + alloc_cmap(&disp[con].cmap, 0, 0); + do_install_cmap(con); + } + } + var->activate = 0; + return 0; +} + + +/* + * Get the Colormap + */ + +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + if (con == currcon) /* current console? */ + return(do_fb_get_cmap(cmap, &disp[con].var, kspc)); + else if (disp[con].cmap.len) /* non default colormap? */ + copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2); + else + copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + cmap, kspc ? 0 : 2); + return 0; +} + + +/* + * Set the Colormap + */ + +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + int err; + + if (!disp[con].cmap.len) { /* no colormap allocated? */ + if ((err = alloc_cmap(&disp[con].cmap, + 1<init(); + + if (z3fb_mode == -1) + z3fb_mode = 1; + + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], &par); + fbhw->encode_var(&retz3_fb_predefined[0], &par); + + strcpy(fb_info.modename, retz3_fb_name); + fb_info.disp = disp; + fb_info.switch_con = &z3fb_switch; + fb_info.updatevar = &z3fb_updatevar; + fb_info.blank = &z3fb_blank; + fb_info.setcmap = &z3fb_setcmap; + + do_fb_set_var(&retz3_fb_predefined[0], 0); + retz3_fb_get_var(&disp[0].var, -1); + retz3_fb_set_disp(-1); + do_install_cmap(0); + + return &fb_info; +} + + +static int z3fb_switch(int con) +{ + /* Do we have to save the colormap? */ + if (disp[currcon].cmap.len) + do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1); + + do_fb_set_var(&disp[con].var, 1); + currcon = con; + /* Install new colormap */ + do_install_cmap(con); + return 0; +} + + +/* + * Update the `var' structure (called by fbcon.c) + * + * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. + * Since it's called by a kernel driver, no range checking is done. + */ + +static int z3fb_updatevar(int con) +{ + return 0; +} + + +/* + * Blank the display. + */ + +static void z3fb_blank(int blank) +{ + fbhw->blank(blank); +} + + +/* + * Set the colormap + */ + +static int z3fb_setcmap(struct fb_cmap *cmap, int con) +{ + return(retz3_fb_set_cmap(cmap, 1, con)); +} + + +/* + * Get a Video Mode + */ + +static int get_video_mode(const char *name) +{ + int i; + + for (i = 1; i <= NUM_PREDEF_MODES; i++) + if (!strcmp(name, retz3_fb_modenames[i])){ + retz3_fb_predefined[0] = retz3_fb_predefined[i]; + return i; + } + return -1; +} +/* + * Linux/arch/m68k/amiga/retz3fb.c -- Low level implementation of the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * This file is based on the CyberVision64 frame buffer device and + * the generic Cirrus Logic driver. + * + * cyberfb.c: Copyright (C) 1996 Martin Apel, + * Geert Uytterhoeven + * clgen.c: Copyright (C) 1996 Frank Neumann + * + * History: + * - 22 Jan 97: Initial work + * - 14 Feb 97: Screen initialization works somewhat, still only + * 8-bit packed pixel is supported. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "retz3fb.h" + +/* #define DEBUG if(1) */ +#define DEBUG if(0) + +/* + * Reserve space for one pattern line. + * + * For the time being we only support 4MB boards! + */ + +#define PAT_MEM_SIZE 16*3 +#define PAT_MEM_OFF (4*1024*1024 - PAT_MEM_SIZE) + +#define arraysize(x) (sizeof(x)/sizeof(*(x))) + +struct retz3_fb_par { + int xres; + int yres; + int xres_vir; + int yres_vir; + int xoffset; + int yoffset; + int bpp; + + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + + int pixclock; + int left_margin; /* time from sync to picture */ + int right_margin; /* time from picture to sync */ + int upper_margin; /* time from sync to picture */ + int lower_margin; + int hsync_len; /* length of horizontal sync */ + int vsync_len; /* length of vertical sync */ + int vmode; +}; + +struct display_data { + long h_total; /* Horizontal Total */ + long h_sstart; /* Horizontal Sync Start */ + long h_sstop; /* Horizontal Sync Stop */ + long h_bstart; /* Horizontal Blank Start */ + long h_bstop; /* Horizontal Blank Stop */ + long h_dispend; /* Horizontal Display End */ + long v_total; /* Vertical Total */ + long v_sstart; /* Vertical Sync Start */ + long v_sstop; /* Vertical Sync Stop */ + long v_bstart; /* Vertical Blank Start */ + long v_bstop; /* Vertical Blank Stop */ + long v_dispend; /* Horizontal Display End */ +}; + +static struct retz3_fb_par current_par; + +static int current_par_valid = 0; +static int currcon = 0; + +static struct display disp[MAX_NR_CONSOLES]; +static struct fb_info fb_info; + +static int node; /* node of the /dev/fb?current file */ + + +/* + * Switch for Chipset Independency + */ + +static struct fb_hwswitch { + + /* Initialisation */ + + int (*init)(void); + + /* Display Control */ + + int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3_fb_par *par); + int (*decode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*encode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned + int *green, unsigned int *blue, unsigned int *transp); + int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int + green, unsigned int blue, unsigned int transp); + void (*blank)(int blank); +} *fbhw; + + +/* + * Frame Buffer Name + */ + +static char retz3_fb_name[16] = "RetinaZ3"; + + +static int z3_key = 0; +static unsigned char retz3_color_table [256][4]; +static unsigned long z3_mem; +static unsigned long z3_fbmem; +static unsigned long z3_size; +static volatile unsigned char *z3_regs; + +static long *memstart; + + +/* + * Predefined Video Mode Names + */ + +static char *retz3_fb_modenames[] = { + + /* + * Autodetect (Default) Video Mode + */ + + "default", + + /* + * Predefined Video Modes + */ + + "640x480", /* RetinaZ3 8 bpp */ + "800x600", /* RetinaZ3 8 bpp */ + "1024x768i", + "640x480-16", /* RetinaZ3 16 bpp */ + "640x480-24", /* RetinaZ3 24 bpp */ + + /* + * Dummy Video Modes + */ + + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + + /* + * User Defined Video Modes + * + * This doesn't work yet!! + */ + + "user0", "user1", "user2", "user3", + "user4", "user5", "user6", "user7" +}; + +/* + * A small info on how to convert XFree86 timing values into fb + * timings - by Frank Neumann: + * +An XFree86 mode line consists of the following fields: + "800x600" 50 800 856 976 1040 600 637 643 666 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + +The fields in the fb_var_screeninfo structure are: + unsigned long pixclock; * pixel clock in ps (pico seconds) * + unsigned long left_margin; * time from sync to picture * + unsigned long right_margin; * time from picture to sync * + unsigned long upper_margin; * time from sync to picture * + unsigned long lower_margin; + unsigned long hsync_len; * length of horizontal sync * + unsigned long vsync_len; * length of vertical sync * + +1) Pixelclock: + xfree: in MHz + fb: In Picoseconds (ps) + + pixclock = 1000000 / DCF + +2) horizontal timings: + left_margin = HFL - SH2 + right_margin = SH1 - HR + hsync_len = SH2 - SH1 + +3) vertical timings: + upper_margin = VFL - SV2 + lower_margin = SV1 - VR + vsync_len = SV2 - SV1 + +Good examples for VESA timings can be found in the XFree86 source tree, +under "programs/Xserver/hw/xfree86/doc/modeDB.txt". +*/ + +/* + * Predefined Video Mode Definitions + */ + +static struct fb_var_screeninfo retz3_fb_predefined[] = { + + /* + * Autodetect (Default) Video Mode + */ + + { 0, }, + + /* + * Predefined Video Modes + */ + + /* + * NB: it is very important to adjust the pixel-clock to the color-depth. + */ + + { + 640, 480, 640, 480, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 800 x 600, 8 bpp */ + 800, 600, 800, 600, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + /* + ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + /* 1024 x 768, 8 bpp, interlaced */ + 1024, 768, 1024, 768, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 16, 0, + {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + { + 640, 480, 640, 480, 0, 0, 24, 0, + {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, + + /* + * Dummy Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, + { 0, }, { 0, }, + + /* + * User Defined Video Modes + */ + + { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } +}; + + +#define NUM_TOTAL_MODES arraysize(retz3_fb_predefined) +#define NUM_PREDEF_MODES (5) + + +static int z3fb_inverse = 0; +static int z3fb_mode = 0; + + +/* + * Interface used by the world + */ + +int retz3_probe(void); +void retz3_video_setup(char *options, int *ints); + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con); +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con); +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); +static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con); +static int retz3_fb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, int con); + + +/* + * Interface to the low level console driver + */ + +struct fb_info *retz3_fb_init(long *mem_start); /* Through amiga_fb_init() */ +static int z3fb_switch(int con); +static int z3fb_updatevar(int con); +static void z3fb_blank(int blank); +static int z3fb_setcmap(struct fb_cmap *cmap, int con); + + +/* + * Accelerated Functions used by the low level console driver + */ + +void retz3_bitblt(struct fb_var_screeninfo *scr, + unsigned short curx, unsigned short cury, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask); +void retz3_fill(unsigned short x, unsigned short y, unsigned short + width, unsigned short height, unsigned short mode, + unsigned short color); + +/* + * Hardware Specific Routines + */ + +static int retz3_init(void); +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par); +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par); +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp); +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp); +static void retz3_blank(int blank); + + +/* + * Internal routines + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par); +static void retz3_fb_set_par(struct retz3_fb_par *par); +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); +static struct fb_cmap *get_default_colormap(int bpp); +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc); +static void do_install_cmap(int con); +static void memcpy_fs(int fsfromto, void *to, void *from, int len); +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto); +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp); +static void retz3_fb_set_disp(int con); +static int get_video_mode(const char *name); + + +/* -------------------- Hardware specific routines -------------------------- */ + +static unsigned short find_fq(unsigned int freq) +{ + unsigned long f; + long tmp; + long prev = 0x7fffffff; + long n2, n1 = 3; + unsigned long m; + unsigned short res = 0; + + if (freq <= 31250000) + n2 = 3; + else if (freq <= 62500000) + n2 = 2; + else if (freq <= 125000000) + n2 = 1; + else if (freq <= 250000000) + n2 = 0; + else + return(0); + + + do { + f = freq >> (10 - n2); + + m = (f * n1) / (14318180/1024); + + if (m > 129) + break; + + tmp = (((m * 14318180) >> n2) / n1) - freq; + if (tmp < 0) + tmp = -tmp; + + if (tmp < prev) { + prev = tmp; + res = (((n2 << 5) | (n1-2)) << 8) | (m-2); + } + + } while ( (++n1) <= 21); + + return res; +} + + +static int retz3_set_video(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + float freq_f; + long freq; + + int xres, hfront, hsync, hback; + int yres, vfront, vsync, vback; + unsigned char tmp; + unsigned short best_freq; + struct display_data data; + + short clocksel = 0; /* Apparantly this is always zero */ + + int bpp = var->bits_per_pixel; + + /* + * XXX + */ + if (bpp == 24) + return 0; + + if ((bpp != 8) && (bpp != 16) && (bpp != 24)) + return -EFAULT; + + par->xoffset = 0; + par->yoffset = 0; + + xres = var->xres * bpp / 4; + hfront = var->right_margin * bpp / 4; + hsync = var->hsync_len * bpp / 4; + hback = var->left_margin * bpp / 4; + + if (var->vmode & FB_VMODE_DOUBLE) + { + yres = var->yres * 2; + vfront = var->lower_margin * 2; + vsync = var->vsync_len * 2; + vback = var->upper_margin * 2; + } + else if (var->vmode & FB_VMODE_INTERLACED) + { + yres = (var->yres + 1) / 2; + vfront = (var->lower_margin + 1) / 2; + vsync = (var->vsync_len + 1) / 2; + vback = (var->upper_margin + 1) / 2; + } + else + { + yres = var->yres; /* -1 ? */ + vfront = var->lower_margin; + vsync = var->vsync_len; + vback = var->upper_margin; + } + + data.h_total = (hback / 8) + (xres / 8) + + (hfront / 8) + (hsync / 8) - 1 /* + 1 */; + data.h_dispend = ((xres + bpp - 1)/ 8) - 1; + data.h_bstart = xres / 8 /* + 1 */; + + data.h_bstop = data.h_total+1 + 2 + 1; + data.h_sstart = (xres / 8) + (hfront / 8) + 1; + data.h_sstop = (xres / 8) + (hfront / 8) + (hsync / 8) + 1; + + data.v_total = yres + vfront + vsync + vback - 1; + + data.v_dispend = yres - 1; + data.v_bstart = yres; + + data.v_bstop = data.v_total; + data.v_sstart = yres + vfront - 1 - 2; + data.v_sstop = yres + vfront + vsync - 1; + +#if 0 /* testing */ + + printk("HBS: %i\n", data.h_bstart); + printk("HSS: %i\n", data.h_sstart); + printk("HSE: %i\n", data.h_sstop); + printk("HBE: %i\n", data.h_bstop); + printk("HT: %i\n", data.h_total); + + printk("hsync: %i\n", hsync); + printk("hfront: %i\n", hfront); + printk("hback: %i\n", hback); + + printk("VBS: %i\n", data.v_bstart); + printk("VSS: %i\n", data.v_sstart); + printk("VSE: %i\n", data.v_sstop); + printk("VBE: %i\n", data.v_bstop); + printk("VT: %i\n", data.v_total); + + printk("vsync: %i\n", vsync); + printk("vfront: %i\n", vfront); + printk("vback: %i\n", vback); +#endif + + if (data.v_total >= 1024) + printk("MAYDAY: v_total >= 1024; bailing out!\n"); + + reg_w(GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04)); + reg_w(GREG_FEATURE_CONTROL_W, 0x00); + + seq_w(SEQ_RESET, 0x00); + seq_w(SEQ_RESET, 0x03); /* reset sequencer logic */ + + /* + * CLOCKING_MODE bits: + * 2: This one is only set for certain text-modes, wonder if + * it may be for EGA-lines? (it was referred to as CLKDIV2) + * (The CL drivers sets it to 0x21 with the comment: + * FullBandwidth (video off) and 8/9 dot clock) + */ + seq_w(SEQ_CLOCKING_MODE, 0x01 | 0x00 /* 0x08 */); + + seq_w(SEQ_MAP_MASK, 0x0f); /* enable writing to plane 0-3 */ + seq_w(SEQ_CHAR_MAP_SELECT, 0x00); /* doesn't matter in gfx-mode */ + seq_w(SEQ_MEMORY_MODE, 0x06); /* CL driver says 0x0e for 256 col mode*/ + seq_w(SEQ_RESET, 0x01); + seq_w(SEQ_RESET, 0x03); + + seq_w(SEQ_EXTENDED_ENABLE, 0x05); + + seq_w(SEQ_CURSOR_CONTROL, 0x00); /* disable cursor */ + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); + seq_w(SEQ_LINEAR_0, 0x4a); + seq_w(SEQ_LINEAR_1, 0x00); + + seq_w(SEQ_SEC_HOST_OFF_HI, 0x00); + seq_w(SEQ_SEC_HOST_OFF_LO, 0x00); + seq_w(SEQ_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); + + /* + * The lower 4 bits (0-3) are used to set the font-width for + * text-mode - DON'T try to set this for gfx-mode. + */ + seq_w(SEQ_EXT_CLOCK_MODE, 0x10); + seq_w(SEQ_EXT_VIDEO_ADDR, 0x03); + + /* + * Extended Pixel Control: + * bit 0: text-mode=0, gfx-mode=1 (Graphics Byte ?) + * bit 1: (Packed/Nibble Pixel Format ?) + * bit 4-5: depth, 0=1-8bpp, 1=9-16bpp, 2=17-24bpp + */ + seq_w(SEQ_EXT_PIXEL_CNTL, 0x01 | (((bpp / 8) - 1) << 4)); + + seq_w(SEQ_BUS_WIDTH_FEEDB, 0x04); + seq_w(SEQ_COLOR_EXP_WFG, 0x01); + seq_w(SEQ_COLOR_EXP_WBG, 0x00); + seq_w(SEQ_EXT_RW_CONTROL, 0x00); + seq_w(SEQ_MISC_FEATURE_SEL, (0x51 | (clocksel & 8))); + seq_w(SEQ_COLOR_KEY_CNTL, 0x40); + seq_w(SEQ_COLOR_KEY_MATCH0, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH1, 0x00); + seq_w(SEQ_COLOR_KEY_MATCH2, 0x00); + seq_w(SEQ_CRC_CONTROL, 0x00); + seq_w(SEQ_PERF_SELECT, 0x10); + seq_w(SEQ_ACM_APERTURE_1, 0x00); + seq_w(SEQ_ACM_APERTURE_2, 0x30); + seq_w(SEQ_ACM_APERTURE_3, 0x00); + seq_w(SEQ_MEMORY_MAP_CNTL, 0x03); + + + /* unlock register CRT0..CRT7 */ + crt_w(CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20); + + /* Zuerst zu schreibende Werte nur per printk ausgeben */ + DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total); + crt_w(CRT_HOR_TOTAL, data.h_total & 0xff); + + DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend); + crt_w(CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff); + + DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart); + crt_w(CRT_START_HOR_BLANK, data.h_bstart & 0xff); + + DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32); + crt_w(CRT_END_HOR_BLANK, 0x80 | (data.h_bstop & 0x1f)); + + DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart); + crt_w(CRT_START_HOR_RETR, data.h_sstart & 0xff); + + tmp = (data.h_sstop & 0x1f); + if (data.h_bstop & 0x20) + tmp |= 0x80; + DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp); + crt_w(CRT_END_HOR_RETR, tmp); + + DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff); + crt_w(CRT_VER_TOTAL, (data.v_total & 0xff)); + + tmp = 0x10; /* LineCompare bit #9 */ + if (data.v_total & 256) + tmp |= 0x01; + if (data.v_dispend & 256) + tmp |= 0x02; + if (data.v_sstart & 256) + tmp |= 0x04; + if (data.v_bstart & 256) + tmp |= 0x08; + if (data.v_total & 512) + tmp |= 0x20; + if (data.v_dispend & 512) + tmp |= 0x40; + if (data.v_sstart & 512) + tmp |= 0x80; + DEBUG printk("CRT_OVERFLOW: %d\n", tmp); + crt_w(CRT_OVERFLOW, tmp); + + crt_w(CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */ + + tmp = 0x40; /* LineCompare bit #8 */ + if (data.v_bstart & 512) + tmp |= 0x20; + if (var->vmode & FB_VMODE_DOUBLE) + tmp |= 0x80; + DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp); + crt_w(CRT_MAX_SCAN_LINE, tmp); + + crt_w(CRT_CURSOR_START, 0x00); + crt_w(CRT_CURSOR_END, 8 & 0x1f); /* font height */ + + crt_w(CRT_START_ADDR_HIGH, 0x00); + crt_w(CRT_START_ADDR_LOW, 0x00); + + crt_w(CRT_CURSOR_LOC_HIGH, 0x00); + crt_w(CRT_CURSOR_LOC_LOW, 0x00); + + DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff); + crt_w(CRT_START_VER_RETR, (data.v_sstart & 0xff)); + +#if 1 + /* 5 refresh cycles per scanline */ + DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20)); +#else + DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16); + crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32)); +#endif + DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff); + crt_w(CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff)); + + DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff); + crt_w(CRT_START_VER_BLANK, (data.v_bstart & 0xff)); + + DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff); + crt_w(CRT_END_VER_BLANK, (data.v_bstop & 0xff)); + + DEBUG printk("CRT_MODE_CONTROL: 0xe3\n"); + crt_w(CRT_MODE_CONTROL, 0xe3); + + DEBUG printk("CRT_LINE_COMPARE: 0xff\n"); + crt_w(CRT_LINE_COMPARE, 0xff); + + tmp = (var->xres_virtual / 8) * (bpp / 8); + crt_w(CRT_OFFSET, tmp); + + crt_w(CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */ + + tmp = 0x20; /* Enable extended end bits */ + if (data.h_total & 0x100) + tmp |= 0x01; + if ((data.h_dispend) & 0x100) + tmp |= 0x02; + if (data.h_bstart & 0x100) + tmp |= 0x04; + if (data.h_sstart & 0x100) + tmp |= 0x08; + if (var->vmode & FB_VMODE_INTERLACED) + tmp |= 0x10; + DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp); + crt_w(CRT_EXT_HOR_TIMING1, tmp); + + tmp = 0x00; + if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100) + tmp |= 0x10; + crt_w(CRT_EXT_START_ADDR, tmp); + + tmp = 0x00; + if (data.h_total & 0x200) + tmp |= 0x01; + if ((data.h_dispend) & 0x200) + tmp |= 0x02; + if (data.h_bstart & 0x200) + tmp |= 0x04; + if (data.h_sstart & 0x200) + tmp |= 0x08; + tmp |= ((data.h_bstop & 0xc0) >> 2); + tmp |= ((data.h_sstop & 0x60) << 1); + crt_w(CRT_EXT_HOR_TIMING2, tmp); + DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp); + + tmp = 0x10; /* Line compare bit 10 */ + if (data.v_total & 0x400) + tmp |= 0x01; + if ((data.v_dispend) & 0x400) + tmp |= 0x02; + if (data.v_bstart & 0x400) + tmp |= 0x04; + if (data.v_sstart & 0x400) + tmp |= 0x08; + tmp |= ((data.v_bstop & 0x300) >> 3); + if (data.v_sstop & 0x10) + tmp |= 0x80; + crt_w(CRT_EXT_VER_TIMING, tmp); + DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp); + + crt_w(CRT_MONITOR_POWER, 0x00); + + /* + * Convert from ps to Hz. + */ + freq_f = (1.0/(float)var->pixclock) * 1000000000; + freq = ((long)freq_f) * 1000; + + best_freq = find_fq(freq); + pll_w(0x02, best_freq); + best_freq = find_fq(61000000); + pll_w(0x0a, best_freq); + pll_w(0x0e, 0x22); + + gfx_w(GFX_SET_RESET, 0x00); + gfx_w(GFX_ENABLE_SET_RESET, 0x00); + gfx_w(GFX_COLOR_COMPARE, 0x00); + gfx_w(GFX_DATA_ROTATE, 0x00); + gfx_w(GFX_READ_MAP_SELECT, 0x00); + gfx_w(GFX_GRAPHICS_MODE, 0x00); + gfx_w(GFX_MISC, 0x05); + gfx_w(GFX_COLOR_XCARE, 0x0f); + gfx_w(GFX_BITMASK, 0xff); + + reg_r(ACT_ADDRESS_RESET); + attr_w(ACT_PALETTE0 , 0x00); + attr_w(ACT_PALETTE1 , 0x01); + attr_w(ACT_PALETTE2 , 0x02); + attr_w(ACT_PALETTE3 , 0x03); + attr_w(ACT_PALETTE4 , 0x04); + attr_w(ACT_PALETTE5 , 0x05); + attr_w(ACT_PALETTE6 , 0x06); + attr_w(ACT_PALETTE7 , 0x07); + attr_w(ACT_PALETTE8 , 0x08); + attr_w(ACT_PALETTE9 , 0x09); + attr_w(ACT_PALETTE10, 0x0a); + attr_w(ACT_PALETTE11, 0x0b); + attr_w(ACT_PALETTE12, 0x0c); + attr_w(ACT_PALETTE13, 0x0d); + attr_w(ACT_PALETTE14, 0x0e); + attr_w(ACT_PALETTE15, 0x0f); + reg_r(ACT_ADDRESS_RESET); + + attr_w(ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */ + + attr_w(ACT_OVERSCAN_COLOR, 0x00); + attr_w(ACT_COLOR_PLANE_ENA, 0x0f); + attr_w(ACT_HOR_PEL_PANNING, 0x00); + attr_w(ACT_COLOR_SELECT, 0x00); + + reg_r(ACT_ADDRESS_RESET); + reg_w(ACT_DATA, 0x20); + + reg_w(VDAC_MASK, 0xff); + + /* + * Extended palette adressing ??? + */ + switch (bpp){ + case 8: + reg_w(0x83c6, 0x00); + break; + case 16: + reg_w(0x83c6, 0x60); + break; + case 24: + reg_w(0x83c6, 0xe0); + break; + default: + printk("Illegal color-depth: %i\n", bpp); + } + + reg_w(VDAC_ADDRESS, 0x00); + + seq_w(SEQ_MAP_MASK, 0x0f ); + + return 0; +} + +/* + * Initialization + * + * Set the default video mode for this chipset. If a video mode was + * specified on the command line, it will override the default mode. + */ + +static int retz3_init(void) +{ + int i; +#if 0 + volatile unsigned long *CursorBase; +#endif + unsigned long board_addr, board_size; + struct ConfigDev *cd; + + cd = zorro_get_board (z3_key); + zorro_config_board (z3_key, 0); + board_addr = (unsigned long)cd->cd_BoardAddr; + board_size = (unsigned long)cd->cd_BoardSize; + + for (i = 0; i < 256; i++){ + for (i = 0; i < 256; i++){ + retz3_color_table [i][0] = i; + retz3_color_table [i][1] = i; + retz3_color_table [i][2] = i; + retz3_color_table [i][3] = 0; + } + } + + *memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + + z3_mem = kernel_map (board_addr, board_size, + KERNELMAP_NOCACHE_SER, memstart); + + z3_regs = (char*) z3_mem; + z3_fbmem = z3_mem + VIDEO_MEM_OFFSET; + + /* Get memory size - for now we asume its a 4MB board */ + + z3_size = 0x00400000; /* 4 MB */ + + memset ((char*)z3_fbmem, 0, z3_size); + + /* Disable hardware cursor */ + + seq_w(SEQ_CURSOR_Y_INDEX, 0x00); + + +#if 0 + /* Initialize hardware cursor */ + CursorBase = (unsigned long *)((char *)(z3_mem) + z3_size - 0x400); + for (i=0; i < 8; i++){ + *(CursorBase +(i*4)) = 0xffffff00; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } + for (i=8; i < 64; i++){ + *(CursorBase +(i*4)) = 0xffff0000; + *(CursorBase+1+(i*4)) = 0xffff0000; + *(CursorBase+2+(i*4)) = 0xffff0000; + *(CursorBase+3+(i*4)) = 0xffff0000; + } +#endif + + retz3_setcolreg (255, 56, 100, 160, 0); + retz3_setcolreg (254, 0, 0, 0, 0); + + return 0; +} + + +/* + * This function should fill in the `fix' structure based on the + * values in the `par' structure. + */ + +static int retz3_encode_fix(struct fb_fix_screeninfo *fix, + struct retz3_fb_par *par) +{ + int i; + + strcpy(fix->id, retz3_fb_name); + fix->smem_start = z3_fbmem; + fix->smem_len = z3_size; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->type_aux = 0; + if (par->bpp == 8) + fix->visual = FB_VISUAL_PSEUDOCOLOR; + else + fix->visual = FB_VISUAL_DIRECTCOLOR; + + fix->xpanstep = 0; + fix->ypanstep = 0; + fix->ywrapstep = 0; + fix->line_length = 0; + + for (i = 0; i < arraysize(fix->reserved); i++) + fix->reserved[i] = 0; + + return 0; +} + + +/* + * Get the video params out of `var'. If a value doesn't fit, round + * it up, if it's too big, return -EINVAL. + */ + +static int retz3_decode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + par->xres = var->xres; + par->yres = var->yres; + par->xres_vir = var->xres_virtual; + par->yres_vir = var->yres_virtual; + par->bpp = var->bits_per_pixel; + par->pixclock = var->pixclock; + par->vmode = var->vmode; + + par->red = var->red; + par->green = var->green; + par->blue = var->blue; + par->transp = var->transp; + + par->left_margin = var->left_margin; + par->right_margin = var->right_margin; + par->upper_margin = var->upper_margin; + par->lower_margin = var->lower_margin; + par->hsync_len = var->hsync_len; + par->vsync_len = var->vsync_len; + + return 0; +} + + +/* + * Fill the `var' structure based on the values in `par' and maybe + * other values read out of the hardware. + */ + +static int retz3_encode_var(struct fb_var_screeninfo *var, + struct retz3_fb_par *par) +{ + int i; + + var->xres = par->xres; + var->yres = par->yres; + var->xres_virtual = par->xres_vir; + var->yres_virtual = par->yres_vir; + var->xoffset = 0; + var->yoffset = 0; + + var->bits_per_pixel = par->bpp; + var->grayscale = 0; + + var->red = par->red; + var->green = par->green; + var->blue = par->blue; + var->transp = par->transp; + + var->nonstd = 0; + var->activate = 0; + + var->height = -1; + var->width = -1; + + var->accel = FB_ACCEL_RETINAZ3; + + var->pixclock = par->pixclock; + + var->sync = 0; /* ??? */ + var->left_margin = par->left_margin; + var->right_margin = par->right_margin; + var->upper_margin = par->upper_margin; + var->lower_margin = par->lower_margin; + var->hsync_len = par->hsync_len; + var->vsync_len = par->vsync_len; + + for (i = 0; i < arraysize(var->reserved); i++) + var->reserved[i] = 0; + + var->vmode = par->vmode; + return 0; +} + + +/* + * Set a single color register. The values supplied are already + * rounded down to the hardware's capabilities (according to the + * entries in the var structure). Return != 0 for invalid regno. + */ + +static int retz3_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp) +{ + /* We'll get to this */ + + if (regno > 255) + return 1; + + retz3_color_table [regno][0] = red & 0xff; + retz3_color_table [regno][1] = green & 0xff; + retz3_color_table [regno][2] = blue & 0xff; + retz3_color_table [regno][3] = transp; + + reg_w(VDAC_ADDRESS_W, regno); + reg_w(VDAC_DATA, (red & 0xff) >> 2); + reg_w(VDAC_DATA, (green & 0xff) >> 2); + reg_w(VDAC_DATA, (blue & 0xff) >> 2); + + return 0; +} + + +/* + * Read a single color register and split it into + * colors/transparent. Return != 0 for invalid regno. + */ + +static int retz3_getcolreg(unsigned int regno, unsigned int *red, + unsigned int *green, unsigned int *blue, + unsigned int *transp) +{ + if (regno > 255) + return 1; + *red = retz3_color_table [regno][0]; + *green = retz3_color_table [regno][1]; + *blue = retz3_color_table [regno][2]; + *transp = retz3_color_table [regno][3]; + return 0; +} + + +/* + * (Un)Blank the screen + */ + +void retz3_blank(int blank) +{ + int i; + + if (blank) + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + reg_w(VDAC_DATA, 0); + } + else + for (i = 0; i < 256; i++){ + reg_w(VDAC_ADDRESS_W, i); + reg_w(VDAC_DATA, retz3_color_table [i][0] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][1] >> 2); + reg_w(VDAC_DATA, retz3_color_table [i][2] >> 2); + } +} + + +void retz3_bitblt (struct fb_var_screeninfo *var, + unsigned short srcx, unsigned short srcy, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask) +{ + + volatile unsigned long *acm = (unsigned long *) (z3_mem + ACM_OFFSET); + unsigned long *pattern = (unsigned long *)(z3_fbmem + PAT_MEM_OFF); + + unsigned short mod; + unsigned long tmp; + unsigned long pat, src, dst; + unsigned char blt_status; + + int i, xres_virtual = var->xres_virtual; + short bpp = (var->bits_per_pixel & 0xff); + + if (bpp < 8) + bpp = 8; + + tmp = mask | (mask << 16); + +#if 0 + /* + * Check for blitter finished before we start messing with the + * pattern. + */ + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + }while ((blt_status & 1) == 0); +#endif + + i = 0; + do{ + *pattern++ = tmp; + }while(i++ < bpp/4); + + tmp = cmd << 8; + *(acm + ACM_RASTEROP_ROTATION/4) = tmp; + + mod = 0xc0c2; + + pat = 8 * PAT_MEM_OFF; + dst = bpp * (destx + desty * xres_virtual); + + /* + * Source is not set for clear. + */ + if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) { + src = bpp * (srcx + srcy * xres_virtual); + + if (destx > srcx) { + mod &= ~0x8000; + src += bpp * (width - 1); + dst += bpp * (width - 1); + pat += bpp * 2; + } + if (desty > srcy) { + mod &= ~0x4000; + src += bpp * (height - 1) * xres_virtual; + dst += bpp * (height - 1) * xres_virtual; + pat += bpp * 4; + } + + *(acm + ACM_SOURCE/4) = cpu_to_le32(src); + } + + *(acm + ACM_PATTERN/4) = cpu_to_le32(pat); + + *(acm + ACM_DESTINATION/4) = cpu_to_le32(dst); + + tmp = mod << 16; + *(acm + ACM_CONTROL/4) = tmp; + + tmp = width | (height << 16); + + *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp); + + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; + *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; + + /* + * No reason to wait for the blitter to finish, it is better + * just to check if it has finished before we use it again. + */ +#if 1 +#if 0 + while ((*(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)) & 1) == 0); +#else + do{ + blt_status = *(((volatile unsigned char *)acm) + + (ACM_START_STATUS + 2)); + } + while ((blt_status & 1) == 0); +#endif +#endif +} + +#if 0 +void retz3_fill (unsigned short x, unsigned short y, unsigned + short width, unsigned short height, + unsigned short mode, unsigned short color) +{ + +} +#endif + + +/************************************************************** + * Move cursor to x, y + */ +void retz3_MoveCursor (unsigned short x, unsigned short y) +{ + /* Guess we gotta deal with the cursor at some point */ +} + + +/* -------------------- Interfaces to hardware functions -------------------- */ + + +static struct fb_hwswitch retz3_switch = { + retz3_init, retz3_encode_fix, retz3_decode_var, retz3_encode_var, + retz3_getcolreg, retz3_setcolreg, retz3_blank +}; + + +/* -------------------- Generic routines ------------------------------------ */ + + +/* + * Fill the hardware's `par' structure. + */ + +static void retz3_fb_get_par(struct retz3_fb_par *par) +{ + if (current_par_valid) + *par = current_par; + else + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], par); +} + + +static void retz3_fb_set_par(struct retz3_fb_par *par) +{ + current_par = *par; + current_par_valid = 1; +} + + +static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) +{ + int err, activate; + struct retz3_fb_par par; + + if ((err = fbhw->decode_var(var, &par))) + return err; + activate = var->activate; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) + retz3_fb_set_par(&par); + fbhw->encode_var(var, &par); + var->activate = activate; + +#if 1 + retz3_set_video(var, ¤t_par); +#endif + return 0; +} + + +/* + * Default Colormaps + */ + +static unsigned short red16[] = + { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000, + 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff }; +static unsigned short green16[] = + { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000, + 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff }; +static unsigned short blue16[] = + { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, + 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff }; + + +static struct fb_cmap default_16_colors = + { 0, 16, red16, green16, blue16, NULL }; + + +static struct fb_cmap *get_default_colormap(int bpp) +{ + return &default_16_colors; +} + + +#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) +#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ + ((1<<(width))-1)) : 0)) + +static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp)) + return 0; + hred = CNVT_FROMHW(hred, var->red.length); + hgreen = CNVT_FROMHW(hgreen, var->green.length); + hblue = CNVT_FROMHW(hblue, var->blue.length); + htransp = CNVT_FROMHW(htransp, var->transp.length); + if (kspc) { + *red = hred; + *green = hgreen; + *blue = hblue; + if (transp) + *transp = htransp; + } else { + put_user(hred, red); + put_user(hgreen, green); + put_user(hblue, blue); + if (transp) + put_user(htransp, transp); + } + red++; + green++; + blue++; + if (transp) + transp++; + } + return 0; +} + + +static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, + int kspc) +{ + int i, start; + unsigned short *red, *green, *blue, *transp; + unsigned int hred, hgreen, hblue, htransp; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0) + return -EINVAL; + for (i = 0; i < cmap->len; i++) { + if (kspc) { + hred = *red; + hgreen = *green; + hblue = *blue; + htransp = transp ? *transp : 0; + } else { + get_user(hred, red); + get_user(hgreen, green); + get_user(hblue, blue); + if (transp) + get_user(htransp, transp); + else + htransp = 0; + } + hred = CNVT_TOHW(hred, var->red.length); + hgreen = CNVT_TOHW(hgreen, var->green.length); + hblue = CNVT_TOHW(hblue, var->blue.length); + htransp = CNVT_TOHW(htransp, var->transp.length); + red++; + green++; + blue++; + if (transp) + transp++; + if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp)) + return 0; + } + return 0; +} + + +static void do_install_cmap(int con) +{ + if (con != currcon) + return; + if (disp[con].cmap.len) + do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1); + else + do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + &disp[con].var, 1); +} + + +static void memcpy_fs(int fsfromto, void *to, void *from, int len) +{ + switch (fsfromto) { + case 0: + memcpy(to, from, len); + return; + case 1: + copy_from_user(to, from, len); + return; + case 2: + copy_to_user(to, from, len); + return; + } +} + + +static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto) +{ + int size; + int tooff = 0, fromoff = 0; + + if (to->start > from->start) + fromoff = to->start-from->start; + else + tooff = from->start-to->start; + size = to->len-tooff; + if (size > from->len-fromoff) + size = from->len-fromoff; + if (size < 0) + return; + size *= sizeof(unsigned short); + memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size); + memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size); + memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size); + if (from->transp && to->transp) + memcpy_fs(fsfromto, to->transp+tooff, + from->transp+fromoff, size); +} + + +static int alloc_cmap(struct fb_cmap *cmap, int len, int transp) +{ + int size = len*sizeof(unsigned short); + + if (cmap->len != len) { + if (cmap->red) + kfree(cmap->red); + if (cmap->green) + kfree(cmap->green); + if (cmap->blue) + kfree(cmap->blue); + if (cmap->transp) + kfree(cmap->transp); + cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; + cmap->len = 0; + if (!len) + return 0; + if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) + return -1; + if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) + return -1; + if (transp) { + if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) + return -1; + } else + cmap->transp = NULL; + } + cmap->start = 0; + cmap->len = len; + copy_cmap(get_default_colormap(len), cmap, 0); + return 0; +} + + +/* + * Get the Fixed Part of the Display + */ + +static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) + retz3_fb_get_par(&par); + else + error = fbhw->decode_var(&disp[con].var, &par); + return(error ? error : fbhw->encode_fix(fix, &par)); +} + + +/* + * Get the User Defined Part of the Display + */ + +static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con) +{ + struct retz3_fb_par par; + int error = 0; + + if (con == -1) { + retz3_fb_get_par(&par); + error = fbhw->encode_var(var, &par); + } else + *var = disp[con].var; + return error; +} + + +static void retz3_fb_set_disp(int con) +{ + struct fb_fix_screeninfo fix; + + retz3_fb_get_fix(&fix, con); + if (con == -1) + con = 0; + disp[con].screen_base = (unsigned char *)fix.smem_start; + disp[con].visual = fix.visual; + disp[con].type = fix.type; + disp[con].type_aux = fix.type_aux; + disp[con].ypanstep = fix.ypanstep; + disp[con].ywrapstep = fix.ywrapstep; + disp[con].can_soft_blank = 1; + disp[con].inverse = z3fb_inverse; +} + + +/* + * Set the User Defined Part of the Display + */ + +static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) +{ + int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp; + + if ((err = do_fb_set_var(var, con == currcon))) + return err; + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { + oldxres = disp[con].var.xres; + oldyres = disp[con].var.yres; + oldvxres = disp[con].var.xres_virtual; + oldvyres = disp[con].var.yres_virtual; + oldbpp = disp[con].var.bits_per_pixel; + disp[con].var = *var; + if (oldxres != var->xres || oldyres != var->yres || + oldvxres != var->xres_virtual || + oldvyres != var->yres_virtual || + oldbpp != var->bits_per_pixel) { + retz3_fb_set_disp(con); + (*fb_info.changevar)(con); + alloc_cmap(&disp[con].cmap, 0, 0); + do_install_cmap(con); + } + } + var->activate = 0; + return 0; +} + + +/* + * Get the Colormap + */ + +static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + if (con == currcon) /* current console? */ + return(do_fb_get_cmap(cmap, &disp[con].var, kspc)); + else if (disp[con].cmap.len) /* non default colormap? */ + copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2); + else + copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), + cmap, kspc ? 0 : 2); + return 0; +} + + +/* + * Set the Colormap + */ + +static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) +{ + int err; + + if (!disp[con].cmap.len) { /* no colormap allocated? */ + if ((err = alloc_cmap(&disp[con].cmap, + 1<init(); + + if (z3fb_mode == -1) + z3fb_mode = 1; + + fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], &par); + fbhw->encode_var(&retz3_fb_predefined[0], &par); + + strcpy(fb_info.modename, retz3_fb_name); + fb_info.disp = disp; + fb_info.switch_con = &z3fb_switch; + fb_info.updatevar = &z3fb_updatevar; + fb_info.blank = &z3fb_blank; + fb_info.setcmap = &z3fb_setcmap; + + do_fb_set_var(&retz3_fb_predefined[0], 0); + retz3_fb_get_var(&disp[0].var, -1); + retz3_fb_set_disp(-1); + do_install_cmap(0); + + return &fb_info; +} + + +static int z3fb_switch(int con) +{ + /* Do we have to save the colormap? */ + if (disp[currcon].cmap.len) + do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1); + + do_fb_set_var(&disp[con].var, 1); + currcon = con; + /* Install new colormap */ + do_install_cmap(con); + return 0; +} + + +/* + * Update the `var' structure (called by fbcon.c) + * + * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. + * Since it's called by a kernel driver, no range checking is done. + */ + +static int z3fb_updatevar(int con) +{ + return 0; +} + + +/* + * Blank the display. + */ + +static void z3fb_blank(int blank) +{ + fbhw->blank(blank); +} + + +/* + * Set the colormap + */ + +static int z3fb_setcmap(struct fb_cmap *cmap, int con) +{ + return(retz3_fb_set_cmap(cmap, 1, con)); +} + + +/* + * Get a Video Mode + */ + +static int get_video_mode(const char *name) +{ + int i; + + for (i = 1; i <= NUM_PREDEF_MODES; i++) + if (!strcmp(name, retz3_fb_modenames[i])){ + retz3_fb_predefined[0] = retz3_fb_predefined[i]; + return i; + } + return -1; +} diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/retz3fb.h linux/arch/m68k/amiga/retz3fb.h --- v2.1.35/linux/arch/m68k/amiga/retz3fb.h Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/amiga/retz3fb.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,572 @@ +/* + * Linux/arch/m68k/amiga/retz3fb.h -- Defines and macros for the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * History: + * - 22 Jan 97: Initial work + * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Macros to read and write to registers. + */ +#define reg_w(reg,dat) (*(z3_regs + reg) = dat) +#define reg_r(reg) (*(z3_regs + reg)) + +/* + * Macro to access the sequencer. + */ +#define seq_w(sreg,sdat) \ + do{ reg_w(SEQ_IDX, sreg); reg_w(SEQ_DATA, sdat); } while(0) + +/* + * Macro to access the CRT controller. + */ +#define crt_w(creg,cdat) \ + do{ reg_w(CRT_IDX, creg); reg_w(CRT_DATA, cdat); } while(0) + +/* + * Macro to access the graphics controller. + */ +#define gfx_w(greg,gdat) \ + do{ reg_w(GFX_IDX, greg); reg_w(GFX_DATA, gdat); } while(0) + +/* + * Macro to access the attribute controller. + */ +#define attr_w(areg,adat) \ + do{ reg_w(ACT_IDX, areg); reg_w(ACT_DATA, adat); } while(0) + +/* + * Macro to access the pll. + */ +#define pll_w(preg,pdat) \ + do{ reg_w(PLL_IDX, preg); \ + reg_w(PLL_DATA, (pdat & 0xff)); \ + reg_w(PLL_DATA, (pdat >> 8));\ + } while(0) + +/* + * Offsets + */ +#define VIDEO_MEM_OFFSET 0x00c00000 +#define ACM_OFFSET 0x00b00000 + +/* + * Accelerator Control Menu + */ +#define ACM_PRIMARY_OFFSET 0x00 +#define ACM_SECONDARY_OFFSET 0x04 +#define ACM_MODE_CONTROL 0x08 +#define ACM_CURSOR_POSITION 0x0c +#define ACM_START_STATUS 0x30 +#define ACM_CONTROL 0x34 +#define ACM_RASTEROP_ROTATION 0x38 +#define ACM_BITMAP_DIMENSION 0x3c +#define ACM_DESTINATION 0x40 +#define ACM_SOURCE 0x44 +#define ACM_PATTERN 0x48 +#define ACM_FOREGROUND 0x4c +#define ACM_BACKGROUND 0x50 + +/* + * Video DAC addresses + */ +#define VDAC_ADDRESS 0x03c8 +#define VDAC_ADDRESS_W 0x03c8 +#define VDAC_ADDRESS_R 0x03c7 +#define VDAC_STATE 0x03c7 +#define VDAC_DATA 0x03c9 +#define VDAC_MASK 0x03c6 + +/* + * Sequencer + */ +#define SEQ_IDX 0x03c4 /* Sequencer Index */ +#define SEQ_DATA 0x03c5 +#define SEQ_RESET 0x00 +#define SEQ_CLOCKING_MODE 0x01 +#define SEQ_MAP_MASK 0x02 +#define SEQ_CHAR_MAP_SELECT 0x03 +#define SEQ_MEMORY_MODE 0x04 +#define SEQ_EXTENDED_ENABLE 0x05 /* NCR extensions */ +#define SEQ_UNKNOWN1 0x06 +#define SEQ_UNKNOWN2 0x07 +#define SEQ_CHIP_ID 0x08 +#define SEQ_UNKNOWN3 0x09 +#define SEQ_CURSOR_COLOR1 0x0a +#define SEQ_CURSOR_COLOR0 0x0b +#define SEQ_CURSOR_CONTROL 0x0c +#define SEQ_CURSOR_X_LOC_HI 0x0d +#define SEQ_CURSOR_X_LOC_LO 0x0e +#define SEQ_CURSOR_Y_LOC_HI 0x0f +#define SEQ_CURSOR_Y_LOC_LO 0x10 +#define SEQ_CURSOR_X_INDEX 0x11 +#define SEQ_CURSOR_Y_INDEX 0x12 +#define SEQ_CURSOR_STORE_HI 0x13 +#define SEQ_CURSOR_STORE_LO 0x14 +#define SEQ_CURSOR_ST_OFF_HI 0x15 +#define SEQ_CURSOR_ST_OFF_LO 0x16 +#define SEQ_CURSOR_PIXELMASK 0x17 +#define SEQ_PRIM_HOST_OFF_HI 0x18 +#define SEQ_PRIM_HOST_OFF_LO 0x19 +#define SEQ_LINEAR_0 0x1a +#define SEQ_LINEAR_1 0x1b +#define SEQ_SEC_HOST_OFF_HI 0x1c +#define SEQ_SEC_HOST_OFF_LO 0x1d +#define SEQ_EXTENDED_MEM_ENA 0x1e +#define SEQ_EXT_CLOCK_MODE 0x1f +#define SEQ_EXT_VIDEO_ADDR 0x20 +#define SEQ_EXT_PIXEL_CNTL 0x21 +#define SEQ_BUS_WIDTH_FEEDB 0x22 +#define SEQ_PERF_SELECT 0x23 +#define SEQ_COLOR_EXP_WFG 0x24 +#define SEQ_COLOR_EXP_WBG 0x25 +#define SEQ_EXT_RW_CONTROL 0x26 +#define SEQ_MISC_FEATURE_SEL 0x27 +#define SEQ_COLOR_KEY_CNTL 0x28 +#define SEQ_COLOR_KEY_MATCH0 0x29 +#define SEQ_COLOR_KEY_MATCH1 0x2a +#define SEQ_COLOR_KEY_MATCH2 0x2b +#define SEQ_UNKNOWN6 0x2c +#define SEQ_CRC_CONTROL 0x2d +#define SEQ_CRC_DATA_LOW 0x2e +#define SEQ_CRC_DATA_HIGH 0x2f +#define SEQ_MEMORY_MAP_CNTL 0x30 +#define SEQ_ACM_APERTURE_1 0x31 +#define SEQ_ACM_APERTURE_2 0x32 +#define SEQ_ACM_APERTURE_3 0x33 +#define SEQ_BIOS_UTILITY_0 0x3e +#define SEQ_BIOS_UTILITY_1 0x3f + +/* + * Graphics Controller + */ +#define GFX_IDX 0x03ce +#define GFX_DATA 0x03cf +#define GFX_SET_RESET 0x00 +#define GFX_ENABLE_SET_RESET 0x01 +#define GFX_COLOR_COMPARE 0x02 +#define GFX_DATA_ROTATE 0x03 +#define GFX_READ_MAP_SELECT 0x04 +#define GFX_GRAPHICS_MODE 0x05 +#define GFX_MISC 0x06 +#define GFX_COLOR_XCARE 0x07 +#define GFX_BITMASK 0x08 + +/* + * CRT Controller + */ +#define CRT_IDX 0x03d4 +#define CRT_DATA 0x03d5 +#define CRT_HOR_TOTAL 0x00 +#define CRT_HOR_DISP_ENA_END 0x01 +#define CRT_START_HOR_BLANK 0x02 +#define CRT_END_HOR_BLANK 0x03 +#define CRT_START_HOR_RETR 0x04 +#define CRT_END_HOR_RETR 0x05 +#define CRT_VER_TOTAL 0x06 +#define CRT_OVERFLOW 0x07 +#define CRT_PRESET_ROW_SCAN 0x08 +#define CRT_MAX_SCAN_LINE 0x09 +#define CRT_CURSOR_START 0x0a +#define CRT_CURSOR_END 0x0b +#define CRT_START_ADDR_HIGH 0x0c +#define CRT_START_ADDR_LOW 0x0d +#define CRT_CURSOR_LOC_HIGH 0x0e +#define CRT_CURSOR_LOC_LOW 0x0f +#define CRT_START_VER_RETR 0x10 +#define CRT_END_VER_RETR 0x11 +#define CRT_VER_DISP_ENA_END 0x12 +#define CRT_OFFSET 0x13 +#define CRT_UNDERLINE_LOC 0x14 +#define CRT_START_VER_BLANK 0x15 +#define CRT_END_VER_BLANK 0x16 +#define CRT_MODE_CONTROL 0x17 +#define CRT_LINE_COMPARE 0x18 +#define CRT_UNKNOWN1 0x19 +#define CRT_UNKNOWN2 0x1a +#define CRT_UNKNOWN3 0x1b +#define CRT_UNKNOWN4 0x1c +#define CRT_UNKNOWN5 0x1d +#define CRT_UNKNOWN6 0x1e +#define CRT_UNKNOWN7 0x1f +#define CRT_UNKNOWN8 0x20 +#define CRT_UNKNOWN9 0x21 +#define CRT_UNKNOWN10 0x22 +#define CRT_UNKNOWN11 0x23 +#define CRT_UNKNOWN12 0x24 +#define CRT_UNKNOWN13 0x25 +#define CRT_UNKNOWN14 0x26 +#define CRT_UNKNOWN15 0x27 +#define CRT_UNKNOWN16 0x28 +#define CRT_UNKNOWN17 0x29 +#define CRT_UNKNOWN18 0x2a +#define CRT_UNKNOWN19 0x2b +#define CRT_UNKNOWN20 0x2c +#define CRT_UNKNOWN21 0x2d +#define CRT_UNKNOWN22 0x2e +#define CRT_UNKNOWN23 0x2f +#define CRT_EXT_HOR_TIMING1 0x30 /* NCR crt extensions */ +#define CRT_EXT_START_ADDR 0x31 +#define CRT_EXT_HOR_TIMING2 0x32 +#define CRT_EXT_VER_TIMING 0x33 +#define CRT_MONITOR_POWER 0x34 + +/* + * General Registers + */ +#define GREG_STATUS0_R 0x03c2 +#define GREG_STATUS1_R 0x03da +#define GREG_MISC_OUTPUT_R 0x03cc +#define GREG_MISC_OUTPUT_W 0x03c2 +#define GREG_FEATURE_CONTROL_R 0x03ca +#define GREG_FEATURE_CONTROL_W 0x03da +#define GREG_POS 0x0102 + +/* + * Attribute Controller + */ +#define ACT_IDX 0x03C0 +#define ACT_ADDRESS_R 0x03C0 +#define ACT_DATA 0x03C0 +#define ACT_ADDRESS_RESET 0x03DA +#define ACT_PALETTE0 0x00 +#define ACT_PALETTE1 0x01 +#define ACT_PALETTE2 0x02 +#define ACT_PALETTE3 0x03 +#define ACT_PALETTE4 0x04 +#define ACT_PALETTE5 0x05 +#define ACT_PALETTE6 0x06 +#define ACT_PALETTE7 0x07 +#define ACT_PALETTE8 0x08 +#define ACT_PALETTE9 0x09 +#define ACT_PALETTE10 0x0A +#define ACT_PALETTE11 0x0B +#define ACT_PALETTE12 0x0C +#define ACT_PALETTE13 0x0D +#define ACT_PALETTE14 0x0E +#define ACT_PALETTE15 0x0F +#define ACT_ATTR_MODE_CNTL 0x10 +#define ACT_OVERSCAN_COLOR 0x11 +#define ACT_COLOR_PLANE_ENA 0x12 +#define ACT_HOR_PEL_PANNING 0x13 +#define ACT_COLOR_SELECT 0x14 + +/* + * PLL + */ +#define PLL_IDX 0x83c8 +#define PLL_DATA 0x83c9 + +/* + * Blitter operations + */ +#define Z3BLTclear 0x00 /* 0 */ +#define Z3BLTand 0x80 /* src AND dst */ +#define Z3BLTandReverse 0x40 /* src AND NOT dst */ +#define Z3BLTcopy 0xc0 /* src */ +#define Z3BLTandInverted 0x20 /* NOT src AND dst */ +#define Z3BLTnoop 0xa0 /* dst */ +#define Z3BLTxor 0x60 /* src XOR dst */ +#define Z3BLTor 0xe0 /* src OR dst */ +#define Z3BLTnor 0x10 /* NOT src AND NOT dst */ +#define Z3BLTequiv 0x90 /* NOT src XOR dst */ +#define Z3BLTinvert 0x50 /* NOT dst */ +#define Z3BLTorReverse 0xd0 /* src OR NOT dst */ +#define Z3BLTcopyInverted 0x30 /* NOT src */ +#define Z3BLTorInverted 0xb0 /* NOT src OR dst */ +#define Z3BLTnand 0x70 /* NOT src OR NOT dst */ +#define Z3BLTset 0xf0 /* 1 */ +/* + * Linux/arch/m68k/amiga/retz3fb.h -- Defines and macros for the + * RetinaZ3 frame buffer device + * + * Copyright (C) 1997 Jes Sorensen + * + * History: + * - 22 Jan 97: Initial work + * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Macros to read and write to registers. + */ +#define reg_w(reg,dat) (*(z3_regs + reg) = dat) +#define reg_r(reg) (*(z3_regs + reg)) + +/* + * Macro to access the sequencer. + */ +#define seq_w(sreg,sdat) \ + do{ reg_w(SEQ_IDX, sreg); reg_w(SEQ_DATA, sdat); } while(0) + +/* + * Macro to access the CRT controller. + */ +#define crt_w(creg,cdat) \ + do{ reg_w(CRT_IDX, creg); reg_w(CRT_DATA, cdat); } while(0) + +/* + * Macro to access the graphics controller. + */ +#define gfx_w(greg,gdat) \ + do{ reg_w(GFX_IDX, greg); reg_w(GFX_DATA, gdat); } while(0) + +/* + * Macro to access the attribute controller. + */ +#define attr_w(areg,adat) \ + do{ reg_w(ACT_IDX, areg); reg_w(ACT_DATA, adat); } while(0) + +/* + * Macro to access the pll. + */ +#define pll_w(preg,pdat) \ + do{ reg_w(PLL_IDX, preg); \ + reg_w(PLL_DATA, (pdat & 0xff)); \ + reg_w(PLL_DATA, (pdat >> 8));\ + } while(0) + +/* + * Offsets + */ +#define VIDEO_MEM_OFFSET 0x00c00000 +#define ACM_OFFSET 0x00b00000 + +/* + * Accelerator Control Menu + */ +#define ACM_PRIMARY_OFFSET 0x00 +#define ACM_SECONDARY_OFFSET 0x04 +#define ACM_MODE_CONTROL 0x08 +#define ACM_CURSOR_POSITION 0x0c +#define ACM_START_STATUS 0x30 +#define ACM_CONTROL 0x34 +#define ACM_RASTEROP_ROTATION 0x38 +#define ACM_BITMAP_DIMENSION 0x3c +#define ACM_DESTINATION 0x40 +#define ACM_SOURCE 0x44 +#define ACM_PATTERN 0x48 +#define ACM_FOREGROUND 0x4c +#define ACM_BACKGROUND 0x50 + +/* + * Video DAC addresses + */ +#define VDAC_ADDRESS 0x03c8 +#define VDAC_ADDRESS_W 0x03c8 +#define VDAC_ADDRESS_R 0x03c7 +#define VDAC_STATE 0x03c7 +#define VDAC_DATA 0x03c9 +#define VDAC_MASK 0x03c6 + +/* + * Sequencer + */ +#define SEQ_IDX 0x03c4 /* Sequencer Index */ +#define SEQ_DATA 0x03c5 +#define SEQ_RESET 0x00 +#define SEQ_CLOCKING_MODE 0x01 +#define SEQ_MAP_MASK 0x02 +#define SEQ_CHAR_MAP_SELECT 0x03 +#define SEQ_MEMORY_MODE 0x04 +#define SEQ_EXTENDED_ENABLE 0x05 /* NCR extensions */ +#define SEQ_UNKNOWN1 0x06 +#define SEQ_UNKNOWN2 0x07 +#define SEQ_CHIP_ID 0x08 +#define SEQ_UNKNOWN3 0x09 +#define SEQ_CURSOR_COLOR1 0x0a +#define SEQ_CURSOR_COLOR0 0x0b +#define SEQ_CURSOR_CONTROL 0x0c +#define SEQ_CURSOR_X_LOC_HI 0x0d +#define SEQ_CURSOR_X_LOC_LO 0x0e +#define SEQ_CURSOR_Y_LOC_HI 0x0f +#define SEQ_CURSOR_Y_LOC_LO 0x10 +#define SEQ_CURSOR_X_INDEX 0x11 +#define SEQ_CURSOR_Y_INDEX 0x12 +#define SEQ_CURSOR_STORE_HI 0x13 +#define SEQ_CURSOR_STORE_LO 0x14 +#define SEQ_CURSOR_ST_OFF_HI 0x15 +#define SEQ_CURSOR_ST_OFF_LO 0x16 +#define SEQ_CURSOR_PIXELMASK 0x17 +#define SEQ_PRIM_HOST_OFF_HI 0x18 +#define SEQ_PRIM_HOST_OFF_LO 0x19 +#define SEQ_LINEAR_0 0x1a +#define SEQ_LINEAR_1 0x1b +#define SEQ_SEC_HOST_OFF_HI 0x1c +#define SEQ_SEC_HOST_OFF_LO 0x1d +#define SEQ_EXTENDED_MEM_ENA 0x1e +#define SEQ_EXT_CLOCK_MODE 0x1f +#define SEQ_EXT_VIDEO_ADDR 0x20 +#define SEQ_EXT_PIXEL_CNTL 0x21 +#define SEQ_BUS_WIDTH_FEEDB 0x22 +#define SEQ_PERF_SELECT 0x23 +#define SEQ_COLOR_EXP_WFG 0x24 +#define SEQ_COLOR_EXP_WBG 0x25 +#define SEQ_EXT_RW_CONTROL 0x26 +#define SEQ_MISC_FEATURE_SEL 0x27 +#define SEQ_COLOR_KEY_CNTL 0x28 +#define SEQ_COLOR_KEY_MATCH0 0x29 +#define SEQ_COLOR_KEY_MATCH1 0x2a +#define SEQ_COLOR_KEY_MATCH2 0x2b +#define SEQ_UNKNOWN6 0x2c +#define SEQ_CRC_CONTROL 0x2d +#define SEQ_CRC_DATA_LOW 0x2e +#define SEQ_CRC_DATA_HIGH 0x2f +#define SEQ_MEMORY_MAP_CNTL 0x30 +#define SEQ_ACM_APERTURE_1 0x31 +#define SEQ_ACM_APERTURE_2 0x32 +#define SEQ_ACM_APERTURE_3 0x33 +#define SEQ_BIOS_UTILITY_0 0x3e +#define SEQ_BIOS_UTILITY_1 0x3f + +/* + * Graphics Controller + */ +#define GFX_IDX 0x03ce +#define GFX_DATA 0x03cf +#define GFX_SET_RESET 0x00 +#define GFX_ENABLE_SET_RESET 0x01 +#define GFX_COLOR_COMPARE 0x02 +#define GFX_DATA_ROTATE 0x03 +#define GFX_READ_MAP_SELECT 0x04 +#define GFX_GRAPHICS_MODE 0x05 +#define GFX_MISC 0x06 +#define GFX_COLOR_XCARE 0x07 +#define GFX_BITMASK 0x08 + +/* + * CRT Controller + */ +#define CRT_IDX 0x03d4 +#define CRT_DATA 0x03d5 +#define CRT_HOR_TOTAL 0x00 +#define CRT_HOR_DISP_ENA_END 0x01 +#define CRT_START_HOR_BLANK 0x02 +#define CRT_END_HOR_BLANK 0x03 +#define CRT_START_HOR_RETR 0x04 +#define CRT_END_HOR_RETR 0x05 +#define CRT_VER_TOTAL 0x06 +#define CRT_OVERFLOW 0x07 +#define CRT_PRESET_ROW_SCAN 0x08 +#define CRT_MAX_SCAN_LINE 0x09 +#define CRT_CURSOR_START 0x0a +#define CRT_CURSOR_END 0x0b +#define CRT_START_ADDR_HIGH 0x0c +#define CRT_START_ADDR_LOW 0x0d +#define CRT_CURSOR_LOC_HIGH 0x0e +#define CRT_CURSOR_LOC_LOW 0x0f +#define CRT_START_VER_RETR 0x10 +#define CRT_END_VER_RETR 0x11 +#define CRT_VER_DISP_ENA_END 0x12 +#define CRT_OFFSET 0x13 +#define CRT_UNDERLINE_LOC 0x14 +#define CRT_START_VER_BLANK 0x15 +#define CRT_END_VER_BLANK 0x16 +#define CRT_MODE_CONTROL 0x17 +#define CRT_LINE_COMPARE 0x18 +#define CRT_UNKNOWN1 0x19 +#define CRT_UNKNOWN2 0x1a +#define CRT_UNKNOWN3 0x1b +#define CRT_UNKNOWN4 0x1c +#define CRT_UNKNOWN5 0x1d +#define CRT_UNKNOWN6 0x1e +#define CRT_UNKNOWN7 0x1f +#define CRT_UNKNOWN8 0x20 +#define CRT_UNKNOWN9 0x21 +#define CRT_UNKNOWN10 0x22 +#define CRT_UNKNOWN11 0x23 +#define CRT_UNKNOWN12 0x24 +#define CRT_UNKNOWN13 0x25 +#define CRT_UNKNOWN14 0x26 +#define CRT_UNKNOWN15 0x27 +#define CRT_UNKNOWN16 0x28 +#define CRT_UNKNOWN17 0x29 +#define CRT_UNKNOWN18 0x2a +#define CRT_UNKNOWN19 0x2b +#define CRT_UNKNOWN20 0x2c +#define CRT_UNKNOWN21 0x2d +#define CRT_UNKNOWN22 0x2e +#define CRT_UNKNOWN23 0x2f +#define CRT_EXT_HOR_TIMING1 0x30 /* NCR crt extensions */ +#define CRT_EXT_START_ADDR 0x31 +#define CRT_EXT_HOR_TIMING2 0x32 +#define CRT_EXT_VER_TIMING 0x33 +#define CRT_MONITOR_POWER 0x34 + +/* + * General Registers + */ +#define GREG_STATUS0_R 0x03c2 +#define GREG_STATUS1_R 0x03da +#define GREG_MISC_OUTPUT_R 0x03cc +#define GREG_MISC_OUTPUT_W 0x03c2 +#define GREG_FEATURE_CONTROL_R 0x03ca +#define GREG_FEATURE_CONTROL_W 0x03da +#define GREG_POS 0x0102 + +/* + * Attribute Controller + */ +#define ACT_IDX 0x03C0 +#define ACT_ADDRESS_R 0x03C0 +#define ACT_DATA 0x03C0 +#define ACT_ADDRESS_RESET 0x03DA +#define ACT_PALETTE0 0x00 +#define ACT_PALETTE1 0x01 +#define ACT_PALETTE2 0x02 +#define ACT_PALETTE3 0x03 +#define ACT_PALETTE4 0x04 +#define ACT_PALETTE5 0x05 +#define ACT_PALETTE6 0x06 +#define ACT_PALETTE7 0x07 +#define ACT_PALETTE8 0x08 +#define ACT_PALETTE9 0x09 +#define ACT_PALETTE10 0x0A +#define ACT_PALETTE11 0x0B +#define ACT_PALETTE12 0x0C +#define ACT_PALETTE13 0x0D +#define ACT_PALETTE14 0x0E +#define ACT_PALETTE15 0x0F +#define ACT_ATTR_MODE_CNTL 0x10 +#define ACT_OVERSCAN_COLOR 0x11 +#define ACT_COLOR_PLANE_ENA 0x12 +#define ACT_HOR_PEL_PANNING 0x13 +#define ACT_COLOR_SELECT 0x14 + +/* + * PLL + */ +#define PLL_IDX 0x83c8 +#define PLL_DATA 0x83c9 + +/* + * Blitter operations + */ +#define Z3BLTclear 0x00 /* 0 */ +#define Z3BLTand 0x80 /* src AND dst */ +#define Z3BLTandReverse 0x40 /* src AND NOT dst */ +#define Z3BLTcopy 0xc0 /* src */ +#define Z3BLTandInverted 0x20 /* NOT src AND dst */ +#define Z3BLTnoop 0xa0 /* dst */ +#define Z3BLTxor 0x60 /* src XOR dst */ +#define Z3BLTor 0xe0 /* src OR dst */ +#define Z3BLTnor 0x10 /* NOT src AND NOT dst */ +#define Z3BLTequiv 0x90 /* NOT src XOR dst */ +#define Z3BLTinvert 0x50 /* NOT dst */ +#define Z3BLTorReverse 0xd0 /* src OR NOT dst */ +#define Z3BLTcopyInverted 0x30 /* NOT src */ +#define Z3BLTorInverted 0xb0 /* NOT src OR dst */ +#define Z3BLTnand 0x70 /* NOT src OR NOT dst */ +#define Z3BLTset 0xf0 /* 1 */ diff -u --recursive --new-file v2.1.35/linux/arch/m68k/amiga/zorro.c linux/arch/m68k/amiga/zorro.c --- v2.1.35/linux/arch/m68k/amiga/zorro.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/zorro.c Thu Apr 17 13:20:41 1997 @@ -16,7 +16,7 @@ #include #include #include -#include +#include #ifdef CONFIG_ZORRO @@ -82,6 +82,10 @@ PROD("Stormbringer", STORMBRINGER) END +BEGIN_PROD(3_STATE) + PROD("Megamix 2000 RAM", MEGAMIX_2000) +END + BEGIN_PROD(COMMODORE2) PROD("A2088 XT Bridgeboard", A2088) PROD("A2286 AT Bridgeboard", A2286) @@ -141,8 +145,12 @@ PROD("StarDrive", STARDRIVE) PROD("8-Up (Rev A)", 8_UP_A) PROD("8-Up (Rev Z)", 8_UP_Z) + PROD("Delta Card RAM", DELTA_RAM) + PROD("8-Star RAM", 8_STAR_RAM) + PROD("8-Star", 8_STAR) PROD("VXL RAM", VXL_RAM) PROD("VXL-30 Turbo Board", VXL_30) + PROD("Delta Card", DELTA) PROD("MBX 1200", MBX_1200) PROD("Hardframe 2000", HARDFRAME_2000) PROD("MBX 1200", MBX_1200_2) @@ -180,8 +188,8 @@ PROD("SupraDrive 4x4 SCSI Controller", SUPRADRIVE_4x4) PROD("2000 DMA HD", SUPRA_2000) PROD("500 HD/RAM", SUPRA_500) + PROD("500XP/2000 RAM", SUPRA_500XP) PROD("500RX/2000 RAM", SUPRA_500RX) - PROD("500RX/2000 RAM", SUPRA_500RX_2) PROD("2400zi Modem", SUPRA_2400ZI) PROD("Wordsync SCSI Controller", WORDSYNC) PROD("Wordsync II SCSI Controller", WORDSYNC_II) @@ -193,6 +201,10 @@ PROD("12 Gauge SCSI Controller", 12GAUGE) END +BEGIN_PROD(MTEC2) + PROD("AT500 RAM", AT500_2) +END + BEGIN_PROD(GVP3) PROD("Impact SCSI/Memory", IMPACT) END @@ -203,7 +215,11 @@ BEGIN_PROD(POWER_COMPUTING) PROD("DKB 3128 RAM", DKB_3128) + PROD("Rapid Fire SCSI Controller", RAPID_FIRE) + PROD("DKB 1202 RAM", DKB_1202) PROD("DKB Cobra / Viper II Turbo Board", VIPER_II_COBRA) + PROD("WildFire 060 Turbo Board", WILDFIRE_060) + PROD("WildFire 060 Turbo Board", WILDFIRE_060_2) END BEGIN_PROD(GVP) @@ -257,6 +273,9 @@ PROD("PP&S A500 68040 Turbo Board", PPS_A500_040) END +BEGIN_PROD(XEBEC) +END + BEGIN_PROD(SPIRIT) PROD("HDA 506 Harddisk", HDA_506) PROD("OctaByte RAM", OCTABYTE_RAM) @@ -268,6 +287,7 @@ BEGIN_PROD(BSC3) PROD("ALF 2 SCSI Controller", ALF_2_SCSI) + PROD("ALF 2 SCSI Controller", ALF_2_SCSI_2) PROD("ALF 3 SCSI Controller", ALF_3_SCSI_2) END @@ -291,9 +311,17 @@ BEGIN_PROD(KUPKE2) PROD("Golem SCSI-II Controller", KUPKE_SCSI_II) PROD("Golem Box", GOLEM_BOX) + PROD("030/882 Turbo Board", KUPKE_TURBO) PROD("Golem SCSI/AT Controller", KUPKE_SCSI_AT) END +BEGIN_PROD(GVP4) + PROD("A2000-RAM8/2", A2000_RAM8) +END + +BEGIN_PROD(INTERWORKS_NET) +END + BEGIN_PROD(HARDITAL) PROD("TQM 68030+68882 Turbo Board", TQM) END @@ -301,10 +329,14 @@ BEGIN_PROD(BSC2) PROD("Oktagon 2008 SCSI Controller", OKTAGON_SCSI) PROD("Tandem AT-2008/508 IDE Controller", TANDEM) + PROD("Alpha RAM 1200", ALPHA_RAM_1200) PROD("Oktagon 2008 RAM", OKTAGON_RAM) PROD("Alfa Data MultiFace I", MULTIFACE_I) PROD("Alfa Data MultiFace II", MULTIFACE_II) PROD("Alfa Data MultiFace III", MULTIFACE_III) + PROD("Framebuffer", BSC_FRAEMBUFFER) + PROD("Graffiti Graphics Board (RAM)", GRAFFITI_RAM) + PROD("Graffiti Graphics Board (REG)", GRAFFITI_REG) PROD("ISDN MasterCard", ISDN_MASTERCARD) PROD("ISDN MasterCard II", ISDN_MASTERCARD_2) END @@ -319,12 +351,15 @@ END BEGIN_PROD(IVS) - PROD("GrandSlam RAM", GRANDSLAM) + PROD("GrandSlam PIC 2 RAM", GRANDSLAM_PIC_2) + PROD("GrandSlam PIC 1 RAM", GRANDSLAM_PIC_1) PROD("OverDrive HD", IVS_OVERDRIVE) PROD("Trumpcard Classic SCSI Controller", TRUMPCARD_CLASSIC) PROD("Trumpcard Pro SCSI Controller", TRUMPCARD_PRO) PROD("Meta-4 RAM", META_4) + PROD("Wavetools Sound Board", WAVETOOLS) PROD("Vector SCSI Controller", VECTOR) + PROD("Vector SCSI Controller", VECTOR_2) END BEGIN_PROD(VECTOR) @@ -336,6 +371,7 @@ PROD("Visiona Graphics Board (REG)", VISIONA_REG) PROD("Merlin Graphics Board (RAM)", MERLIN_RAM) PROD("Merlin Graphics Board (REG)", MERLIN_REG) + PROD("Merlin Graphics Board (REG)", MERLIN_REG_2) END BEGIN_PROD(HYDRA_SYSTEMS) @@ -388,7 +424,11 @@ PROD("Domino Graphics Board (REG)", DOMINO_REG) PROD("Picasso II Graphics Board (RAM)", PICASSO_II_RAM) PROD("Picasso II Graphics Board (REG)", PICASSO_II_REG) - PROD("Picasso II Graphics Board (REG)", PICASSO_II_REG_2) + PROD("Picasso II/II+ Graphics Board (Segmented Mode)", PICASSO_II_SEGM) + PROD("Picassio IV Graphics Board", PICASSO_IV) + PROD("Picassio IV Graphics Board", PICASSO_IV_2) + PROD("Picassio IV Graphics Board", PICASSO_IV_3) + PROD("Picassio IV Graphics Board", PICASSO_IV_4) PROD("Ariadne Ethernet Card", ARIADNE) END @@ -402,8 +442,18 @@ PROD("CD-RAM Memory", AMITRIX_CD_RAM) END +BEGIN_PROD(ARMAX) + PROD("OmniBus Graphics Board", OMNIBUS) +END + +BEGIN_PROD(NEWTEK) + PROD("VideoToaster", VIDEOTOASTER) +END + BEGIN_PROD(MTEC) + PROD("AT500 IDE Controller", AT500) PROD("68030 Turbo Board", MTEC_68030) + PROD("68020i Turbo Board", MTEC_68020I) PROD("A1200 T68030/42 RTC Turbo Board", MTEC_T1230) PROD("8MB RAM", MTEC_RAM) END @@ -439,6 +489,11 @@ PROD("RCA 120 RAM", RCA_120) END +BEGIN_PROD(MEGA_MICRO) + PROD("SCRAM 500 SCSI Controller", SCRAM_500_SCSI) + PROD("SCRAM 500 RAM", SCRAM_500_RAM) +END + BEGIN_PROD(IMTRONICS2) PROD("Hurricane 2800 68030", HURRICANE_2800_3) PROD("Hurricane 2800 68030", HURRICANE_2800_4) @@ -448,6 +503,15 @@ PROD("Golem HD 3000", GOLEM_3000) END +BEGIN_PROD(ITH) + PROD("ISDN-Master II", ISDN_MASTER_II) +END + +BEGIN_PROD(VMC) + PROD("ISDN Blaster Z2", ISDN_BLASTER_Z2) + PROD("HyperCom 4", HYPERCOM_4) +END + BEGIN_PROD(INFORMATION) PROD("ISDN Engine I", ISDN_ENGINE_I) END @@ -479,6 +543,8 @@ PROD("Blizzard 2060 SCSI Controller", BLIZZARD_2060SCSI) PROD("CyberStorm Mk II", CYBERSTORM_II) PROD("CyberVision64 Graphics Board", CYBERVISION) + PROD("CyberVision64-3D Graphics Board Prototype)", CYBERVISION3D_PRT) + PROD("CyberVision64-3D Graphics Board", CYBERVISION3D) END BEGIN_PROD(DPS) @@ -487,6 +553,7 @@ BEGIN_PROD(APOLLO2) PROD("A620 68020 Accelerator", A620) + PROD("A620 68020 Accelerator", A620_2) END BEGIN_PROD(APOLLO) @@ -494,6 +561,10 @@ PROD("Turbo Board", APOLLO_TURBO) END +BEGIN_PROD(PETSOFF) + PROD("Delfina DSP", DELFINA) +END + BEGIN_PROD(UWE_GERLACH) PROD("RAM/ROM", UG_RAM_ROM) END @@ -507,6 +578,7 @@ PROD("Toccata Sound Board", TOCCATA) PROD("Retina Z3 Graphics Board", RETINA_Z3) PROD("VLab Motion", VLAB_MOTION) + PROD("Altais Graphics Board", ALTAIS) PROD("Falcon '040 Turbo Board", FALCON_040) END @@ -514,11 +586,12 @@ END BEGIN_PROD(SKI) + PROD("MAST Fireball SCSI Controller", MAST_FIREBALL) PROD("SCSI / Dual Serial", SKI_SCSI_SERIAL) END BEGIN_PROD(CAMERON) - PROD("Scanner Interface", CAMERON_SCANNER) + PROD("Personal A4", PERSONAL_A4) END BEGIN_PROD(REIS_WARE) @@ -530,6 +603,7 @@ MANUF("Pacific Peripherals", PACIFIC) MANUF("Kupke", KUPKE) MANUF("Memphis", MEMPHIS) + MANUF("3-State", 3_STATE) MANUF("Commodore", COMMODORE2) MANUF("Commodore", COMMODORE) MANUF("Commodore", COMMODORE3) @@ -546,7 +620,8 @@ MANUF("University of Lowell", UNIV_OF_LOWELL) MANUF("Ameristar", AMERISTAR) MANUF("Supra", SUPRA) - MANUF("CSA", CSA) + MANUF("Computer Systems Ass.", CSA) + MANUF("M-Tech", MTEC2) MANUF("Great Valley Products", GVP3) MANUF("ByteBox", BYTEBOX) MANUF("Power Computing", POWER_COMPUTING) @@ -554,6 +629,7 @@ MANUF("Synergy", SYNERGY) MANUF("Xetec", XETEC) MANUF("Progressive Peripherals", PPI) + MANUF("Xebec", XEBEC) MANUF("Spirit", SPIRIT) MANUF("BSC", BSC) MANUF("BSC", BSC3) @@ -562,6 +638,8 @@ MANUF("Checkpoint Technologies", CHECKPOINT) MANUF("ICD", ICD) MANUF("Kupke", KUPKE2) + MANUF("Great Valley Products", GVP4) + MANUF("Interworks Network", INTERWORKS_NET) MANUF("Hardital Synthesis", HARDITAL) MANUF("BSC", BSC2) MANUF("Advanced Systems & Software", ADV_SYS_SOFT) @@ -582,15 +660,20 @@ MANUF("Village Tronic", VILLAGE_TRONIC) MANUF("Utilities Unlimited", UTILITIES_ULTD) MANUF("Amitrix", AMITRIX) - MANUF("MTEC", MTEC) + MANUF("ArMax", ARMAX) + MANUF("NewTek", NEWTEK) + MANUF("M-Tech", MTEC) MANUF("Great Valley Products", GVP2) MANUF("Helfrich", HELFRICH2) MANUF("MacroSystems", MACROSYSTEMS) MANUF("ElBox Computer", ELBOX) MANUF("Harms Professional", HARMS_PROF) MANUF("Micronik", MICRONIK) + MANUF("MegaMicro", MEGA_MICRO) MANUF("Imtronics", IMTRONICS2) MANUF("Kupke", KUPKE3) + MANUF("ITH", ITH) + MANUF("VMC", VMC) MANUF("Information", INFORMATION) MANUF("Vortex", VORTEX) MANUF("DataFlyer", DATAFLYER) @@ -599,6 +682,7 @@ MANUF("DPS", DPS) MANUF("Apollo", APOLLO2) MANUF("Apollo", APOLLO) + MANUF("Petsoff LP", PETSOFF) MANUF("Uwe Gerlach", UWE_GERLACH) MANUF("MacroSystems", MACROSYSTEMS2) MANUF("Combitec", COMBITEC) @@ -758,7 +842,11 @@ identified = 1; break; } else { - epc = *(enum GVP_ident *)ZTWO_VADDR(addr+0x8000) & + /* + * The epc must be read as a short from the + * hardware. + */ + epc = *(unsigned short *)ZTWO_VADDR(addr+0x8000) & GVP_PRODMASK; for (k = 0; k < NUM_GVP_PROD; k++) if (Ext_Prod_GVP[k].ID == epc) { diff -u --recursive --new-file v2.1.35/linux/arch/m68k/atari/atafb.c linux/arch/m68k/atari/atafb.c --- v2.1.35/linux/arch/m68k/atari/atafb.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/atari/atafb.c Thu Apr 17 13:20:41 1997 @@ -2905,6 +2905,12 @@ do_install_cmap(currcon); } +static int +atafb_setcmap(struct fb_cmap *cmap, int con) +{ + return(atari_fb_set_cmap(cmap, 1, con)); +} + struct fb_info * atari_fb_init(long *mem_start) { @@ -2999,6 +3005,7 @@ fb_info.switch_con=&atafb_switch; fb_info.updatevar=&fb_update_var; fb_info.blank=&atafb_blank; + fb_info.setcmap=&atafb_setcmap; var=atari_fb_predefined+default_par-1; do_fb_set_var(var,1); strcat(fb_info.modename,fb_var_names[default_par-1][0]); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/atari/ataints.c linux/arch/m68k/atari/ataints.c --- v2.1.35/linux/arch/m68k/atari/ataints.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/atari/ataints.c Thu Apr 17 13:20:41 1997 @@ -56,9 +56,7 @@ * All interrupt source have an internal number (defined in * ): Autovector interrupts are 1..7, then follow ST-MFP, * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can - * be allocated by atari_register_vme_int(). Currently, all int source numbers - * have the IRQ_MACHSPEC bit set, to keep the general int handling functions - * in kernel/ints.c from them. + * be allocated by atari_register_vme_int(). * * Each interrupt can be of three types: * @@ -180,7 +178,7 @@ void atari_slow_irq_##n##_dummy (void) { \ __asm__ (ALIGN_STR "\n" \ SYMBOL_NAME_STR(atari_slow_irq_) #n "_handler:\t" \ -" addql #1,"SYMBOL_NAME_STR(intr_count)"\n" \ +" addql #1,"SYMBOL_NAME_STR(local_irq_count)"\n" \ SAVE_ALL "\n" \ " andb #~(1<<(" #n "&7))," /* mask this interrupt */ \ "("MFP_MK_BASE"+(((" #n "&8)^8)>>2)+((" #n "&16)<<3)):w\n" \ @@ -192,7 +190,7 @@ " lea "SYMBOL_NAME_STR(irq_handler)"+("#n"+8)*8,%%a0\n" \ " pea %%sp@\n" /* push addr of frame */ \ " movel %%a0@(4),%%sp@-\n" /* push handler data */ \ -" pea (" #n "+0x10000008)\n" /* push int number */ \ +" pea (" #n "+8)\n" /* push int number */ \ " movel %%a0@,%%a0\n" \ " jbsr %%a0@\n" /* call the handler */ \ " addql #8,%%sp\n" \ @@ -283,7 +281,7 @@ SYMBOL_NAME_STR(atari_fast_irq_handler) ": orw #0x700,%%sr /* disable all interrupts */ "SYMBOL_NAME_STR(atari_prio_irq_handler) ":\t - addql #1,"SYMBOL_NAME_STR(intr_count)"\n" + addql #1,"SYMBOL_NAME_STR(local_irq_count)"\n" SAVE_ALL " /* get vector number from stack frame and convert to source */ bfextu %%sp@(" FORMATVEC "){#4,#10},%%d0 @@ -296,7 +294,6 @@ lea %%a0@(%%d0:l:8),%%a0 pea %%sp@ /* push frame address */ movel %%a0@(4),%%sp@- /* push handler data */ - bset #28,%%d0 /* set MACHSPEC bit */ movel %%d0,%%sp@- /* push int number */ movel %%a0@,%%a0 jsr %%a0@ /* and call the handler */ @@ -587,14 +584,12 @@ return 0; free_vme_vec_bitmap |= 1 << i; - return (VME_SOURCE_BASE + i) | IRQ_MACHSPEC; + return (VME_SOURCE_BASE + i); } void atari_unregister_vme_int(unsigned long irq) { - irq &= ~IRQ_MACHSPEC; - if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { irq -= VME_SOURCE_BASE; free_vme_vec_bitmap &= ~(1 << irq); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/atari/atakeyb.c linux/arch/m68k/atari/atakeyb.c --- v2.1.35/linux/arch/m68k/atari/atakeyb.c Wed Sep 25 00:47:38 1996 +++ linux/arch/m68k/atari/atakeyb.c Thu Apr 17 13:20:41 1997 @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -40,6 +41,15 @@ /* Hook for mouse driver */ void (*atari_mouse_interrupt_hook) (char *); +/* variables for IKBD self test: */ + +/* state: 0: off; >0: in progress; >1: 0xf1 received */ +static volatile int ikbd_self_test; +/* timestamp when last received a char */ +static volatile unsigned long self_test_last_rcv; +/* bitmap of keys reported as broken */ +static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, }; + #define BREAK_MASK (0x80) /* @@ -331,12 +341,15 @@ { /* a very fast typist or a slow system, give a warning */ /* ...happens often if interrupts were disabled for too long */ - printk( "Keyboard overrun\n" ); + printk( KERN_DEBUG "Keyboard overrun\n" ); scancode = acia.key_data; /* Turn off autorepeating in case a break code has been lost */ del_timer( &atakeyb_rep_timer ); rep_scancode = 0; - if (IS_SYNC_CODE(scancode)) { + if (ikbd_self_test) + /* During self test, don't do resyncing, just process the code */ + goto interpret_scancode; + else if (IS_SYNC_CODE(scancode)) { /* This code seem already to be the start of a new packet or a * single scancode */ kb_state.state = KEYBOARD; @@ -386,10 +399,47 @@ kb_state.buf[0] = scancode; break; + case 0xF1: + /* during self-test, note that 0xf1 received */ + if (ikbd_self_test) { + ++ikbd_self_test; + self_test_last_rcv = jiffies; + break; + } + /* FALL THROUGH */ + default: break_flag = scancode & BREAK_MASK; scancode &= ~BREAK_MASK; + if (ikbd_self_test) { + /* Scancodes sent during the self-test stand for broken + * keys (keys being down). The code *should* be a break + * code, but nevertheless some AT keyboard interfaces send + * make codes instead. Therefore, simply ignore + * break_flag... + * */ + int keyval = ataplain_map[scancode], keytyp; + + set_bit( scancode, broken_keys ); + self_test_last_rcv = jiffies; + keyval = ataplain_map[scancode]; + keytyp = KTYP(keyval) - 0xf0; + keyval = KVAL(keyval); + + printk( KERN_WARNING "Key with scancode %d ", scancode ); + if (keytyp == KT_LATIN || keytyp == KT_LETTER) { + if (keyval < ' ') + printk( "('^%c') ", keyval + '@' ); + else + printk( "('%c') ", keyval ); + } + printk( "is broken -- will be ignored.\n" ); + break; + } + else if (test_bit( scancode, broken_keys )) + break; + if (break_flag) { del_timer( &atakeyb_rep_timer ); rep_scancode = 0; @@ -815,7 +865,18 @@ mfp.active_edge &= ~0x10; atari_turnon_irq(IRQ_MFP_ACIA); + ikbd_self_test = 1; ikbd_reset(); + /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's + * self-test is finished */ + self_test_last_rcv = jiffies; + while( jiffies < self_test_last_rcv + HZ/4 ) + barrier(); + /* if not incremented: no 0xf1 received */ + if (ikbd_self_test == 1) + printk( KERN_ERR "WARNING: keyboard self test failed!\n" ); + ikbd_self_test = 0; + ikbd_mouse_disable(); ikbd_joystick_disable(); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/atari/atari_ksyms.c linux/arch/m68k/atari/atari_ksyms.c --- v2.1.35/linux/arch/m68k/atari/atari_ksyms.c Fri Jan 3 01:33:25 1997 +++ linux/arch/m68k/atari/atari_ksyms.c Thu Apr 17 13:20:41 1997 @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,11 +9,12 @@ #include extern void atari_microwire_cmd( int cmd ); - +extern int atari_SCC_reset_done; EXPORT_SYMBOL(atari_mch_cookie); EXPORT_SYMBOL(atari_hw_present); EXPORT_SYMBOL(is_medusa); +EXPORT_SYMBOL(is_hades); EXPORT_SYMBOL(atari_register_vme_int); EXPORT_SYMBOL(atari_unregister_vme_int); EXPORT_SYMBOL(stdma_lock); @@ -23,7 +25,7 @@ EXPORT_SYMBOL(atari_mouse_buttons); EXPORT_SYMBOL(atari_mouse_interrupt_hook); EXPORT_SYMBOL(atari_MIDI_interrupt_hook); -EXPORT_SYMBOL(atari_mch_cookie); +EXPORT_SYMBOL(atari_SCC_reset_done); EXPORT_SYMBOL(ikbd_write); EXPORT_SYMBOL(ikbd_mouse_y0_top); EXPORT_SYMBOL(ikbd_mouse_thresh); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/atari/config.c linux/arch/m68k/atari/config.c --- v2.1.35/linux/arch/m68k/atari/config.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/atari/config.c Thu Apr 17 13:20:41 1997 @@ -45,9 +45,15 @@ #include #include +#ifdef CONFIG_KGDB +#include +#endif + u_long atari_mch_cookie; struct atari_hw_present atari_hw_present; +extern char m68k_debug_device[]; + static void atari_sched_init(void (*)(int, void *, struct pt_regs *)); /* atari specific keyboard functions */ extern int atari_keyb_init(void); @@ -57,7 +63,7 @@ extern void atari_init_IRQ (void); extern int atari_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); -extern int atari_free_irq (unsigned int irq, void *dev_id); +extern void atari_free_irq (unsigned int irq, void *dev_id); extern void atari_enable_irq (unsigned int); extern void atari_disable_irq (unsigned int); extern int atari_get_irq_list (char *buf); @@ -77,12 +83,17 @@ extern int atari_floppy_init (void); extern void atari_floppy_setup(char *, int *); #endif -static void atari_waitbut (void); extern struct consw fb_con; extern struct fb_info *atari_fb_init(long *); -static void atari_debug_init (void); +static void atari_debug_init(void); extern void atari_video_setup(char *, int *); -extern void atari_syms_export(void); + +static struct console atari_console_driver; + +/* Can be set somewhere, if a SCC master reset has already be done and should + * not be repeated; used by kgdb */ +int atari_SCC_reset_done = 0; + extern void (*kd_mksound)(unsigned int, unsigned int); @@ -240,6 +251,8 @@ { memset(&atari_hw_present, 0, sizeof(atari_hw_present)); + atari_debug_init(); + mach_sched_init = atari_sched_init; mach_keyb_init = atari_keyb_init; mach_kbdrate = atari_kbdrate; @@ -247,25 +260,21 @@ mach_init_IRQ = atari_init_IRQ; mach_request_irq = atari_request_irq; mach_free_irq = atari_free_irq; - mach_enable_irq = atari_enable_irq; - mach_disable_irq = atari_disable_irq; + enable_irq = atari_enable_irq; + disable_irq = atari_disable_irq; mach_get_model = atari_get_model; mach_get_hardware_list = atari_get_hardware_list; mach_get_irq_list = atari_get_irq_list; mach_gettimeoffset = atari_gettimeoffset; - mach_mksound = atari_mksound; mach_reset = atari_reset; #ifdef CONFIG_BLK_DEV_FD mach_floppy_init = atari_floppy_init; mach_floppy_setup = atari_floppy_setup; #endif conswitchp = &fb_con; - waitbut = atari_waitbut; mach_fb_init = atari_fb_init; mach_max_dma_address = 0xffffff; - mach_debug_init = atari_debug_init; mach_video_setup = atari_video_setup; - mach_syms_export = atari_syms_export; kd_mksound = atari_mksound; /* ++bjoern: @@ -273,7 +282,7 @@ */ printk( "Atari hardware found: " ); - if (is_medusa) { + if (is_medusa || is_hades) { /* There's no Atari video hardware on the Medusa, but all the * addresses below generate a DTACK so no bus error occurs! */ } @@ -315,7 +324,7 @@ ATARIHW_SET(SCSI_DMA); printk( "TT_SCSI_DMA " ); } - if (hwreg_present( &st_dma.dma_hi )) { + if (!is_hades && hwreg_present( &st_dma.dma_hi )) { ATARIHW_SET(STND_DMA); printk( "STND_DMA " ); } @@ -337,21 +346,25 @@ ATARIHW_SET(YM_2149); printk( "YM2149 " ); } - if (!is_medusa && hwreg_present( &tt_dmasnd.ctrl )) { + if (!is_medusa && !is_hades && hwreg_present( &tt_dmasnd.ctrl )) { ATARIHW_SET(PCM_8BIT); printk( "PCM " ); } - if (hwreg_present( (void *)(0xffff8940) )) { + if (!is_hades && hwreg_present( &codec.unused5 )) { ATARIHW_SET(CODEC); printk( "CODEC " ); } + if (hwreg_present( &dsp56k_host_interface.icr )) { + ATARIHW_SET(DSP56K); + printk( "DSP56K " ); + } if (hwreg_present( &tt_scc_dma.dma_ctrl ) && #if 0 /* This test sucks! Who knows some better? */ (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) && (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0) #else - !is_medusa + !is_medusa && !is_hades #endif ) { ATARIHW_SET(SCC_DMA); @@ -365,7 +378,12 @@ ATARIHW_SET( ST_ESCC ); printk( "ST_ESCC " ); } - if (hwreg_present( &tt_scu.sys_mask )) { + if (is_hades) + { + ATARIHW_SET( VME ); + printk( "VME " ); + } + else if (hwreg_present( &tt_scu.sys_mask )) { ATARIHW_SET(SCU); /* Assume a VME bus if there's a SCU */ ATARIHW_SET( VME ); @@ -375,7 +393,7 @@ ATARIHW_SET(ANALOG_JOY); printk( "ANALOG_JOY " ); } - if (hwreg_present( blitter.halftone )) { + if (!is_hades && hwreg_present( blitter.halftone )) { ATARIHW_SET(BLITTER); printk( "BLITTER " ); } @@ -384,7 +402,7 @@ printk( "IDE " ); } #if 1 /* This maybe wrong */ - if (!is_medusa && + if (!is_medusa && !is_hades && hwreg_present( &tt_microwire.data ) && hwreg_present( &tt_microwire.mask ) && (tt_microwire.mask = 0x7ff, @@ -402,20 +420,20 @@ mach_hwclk = atari_hwclk; mach_set_clock_mmss = atari_set_clock_mmss; } - if (hwreg_present( &mste_rtc.sec_ones)) { + if (!is_hades && hwreg_present( &mste_rtc.sec_ones)) { ATARIHW_SET(MSTE_CLK); printk( "MSTE_CLK "); mach_gettod = atari_mste_gettod; mach_hwclk = atari_mste_hwclk; mach_set_clock_mmss = atari_mste_set_clock_mmss; } - if (!is_medusa && + if (!is_medusa && !is_hades && hwreg_present( &dma_wd.fdc_speed ) && hwreg_write( &dma_wd.fdc_speed, 0 )) { ATARIHW_SET(FDCSPEED); printk( "FDC_SPEED "); } - if (!ATARIHW_PRESENT(ST_SCSI)) { + if (!is_hades && !ATARIHW_PRESENT(ST_SCSI)) { ATARIHW_SET(ACSI); printk( "ACSI " ); } @@ -426,9 +444,11 @@ * translation (the one that must not be turned off in * head.S...) */ - __asm__ volatile ("moveq #0,%/d0;" - ".long 0x4e7b0004;" /* movec d0,itt0 */ - ".long 0x4e7b0006;" /* movec d0,dtt0 */ + __asm__ volatile ("moveq #0,%/d0\n\t" + ".chip 68040\n\t" + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%dtt0\n\t" + ".chip 68k" : /* no outputs */ : /* no inputs */ : "d0"); @@ -452,13 +472,18 @@ tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache * inhibit, read and write, FDC mask = 3, * FDC val = 4 -> Supervisor only */ - __asm__ __volatile__ ( "pmove %0@,%/tt1" : : "a" (&tt1_val) ); + __asm__ __volatile__ ( ".chip 68030\n\t" + "pmove %0@,%/tt1\n\t" + ".chip 68k" + : : "a" (&tt1_val) ); } else { __asm__ __volatile__ ( "movel %0,%/d0\n\t" - ".long 0x4e7b0005\n\t" /* movec d0,itt1 */ - ".long 0x4e7b0007" /* movec d0,dtt1 */ + ".chip 68040\n\t" + "movec %%d0,%%itt1\n\t" + "movec %%d0,%%dtt1\n\t" + ".chip 68k" : : "g" (0xfe00a040) /* Translate 0xfexxxxxx, enable, * supervisor only, non-cacheable/ @@ -621,7 +646,7 @@ we use the fact that in head.S we have set up a mapping 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible in the last 16MB of the address space. */ - tos_version = is_medusa ? 0xfff : *(unsigned short *)0xFF000002; + tos_version = (is_medusa || is_hades) ? 0xfff : *(unsigned short *)0xFF000002; *yearp += (tos_version < 0x306) ? 70 : 68; } @@ -696,7 +721,7 @@ /* Tos version at Physical 2. See above for explanation why we cannot use PTOV(2). */ - tos_version = is_medusa ? 0xfff : *(unsigned short *)0xff000002; + tos_version = (is_medusa || is_hades) ? 0xfff : *(unsigned short *)0xff000002; ctrl = RTC_READ(RTC_CONTROL); /* control registers are * independent from the UIP */ @@ -875,13 +900,6 @@ return retval; } - -static void atari_waitbut (void) -{ - /* sorry, no-op */ -} - - static inline void ata_mfp_out (char c) { while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ @@ -889,12 +907,12 @@ mfp.usart_dta = c; } -void ata_mfp_print (const char *str) +static void atari_mfp_console_write (const char *str, unsigned int count) { - for( ; *str; ++str ) { + while (count--) { if (*str == '\n') ata_mfp_out( '\r' ); - ata_mfp_out( *str ); + ata_mfp_out( *str++ ); } } @@ -907,12 +925,12 @@ scc.cha_b_data = c; } -void ata_scc_print (const char *str) +static void atari_scc_console_write (const char *str, unsigned int count) { - for( ; *str; ++str ) { + while (count--) { if (*str == '\n') ata_scc_out( '\r' ); - ata_scc_out( *str ); + ata_scc_out( *str++ ); } } @@ -937,20 +955,20 @@ return( 1 ); } -void ata_par_print (const char *str) +static void atari_par_console_write (const char *str, unsigned int count) { static int printer_present = 1; if (!printer_present) return; - for( ; *str; ++str ) { + while (count--) { if (*str == '\n') if (!ata_par_out( '\r' )) { printer_present = 0; return; } - if (!ata_par_out( *str )) { + if (!ata_par_out( *str++ )) { printer_present = 0; return; } @@ -958,11 +976,14 @@ } -static void atari_debug_init( void ) +static void atari_debug_init(void) { - extern void (*debug_print_proc)(const char *); - extern char m68k_debug_device[]; - +#ifdef CONFIG_KGDB + /* if the m68k_debug_device is used by the GDB stub, do nothing here */ + if (kgdb_initialized) + return(NULL); +#endif + if (!strcmp( m68k_debug_device, "ser" )) { /* defaults to ser2 for a Falcon and ser1 otherwise */ strcpy( m68k_debug_device, @@ -979,7 +1000,7 @@ mfp.tim_dt_d = 2; /* 9600 bps */ mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ mfp.trn_stat |= 0x01; /* enable TX */ - debug_print_proc = ata_mfp_print; + atari_console_driver.write = atari_mfp_console_write; } else if (!strcmp( m68k_debug_device, "ser2" )) { /* SCC Modem2 serial port */ @@ -1005,7 +1026,7 @@ scc.cha_b_ctrl = *p++; MFPDELAY(); } - debug_print_proc = ata_scc_print; + atari_console_driver.write = atari_scc_console_write; } else if (!strcmp( m68k_debug_device, "par" )) { /* parallel printer */ @@ -1016,29 +1037,10 @@ sound_ym.wd_data = 0; /* no char */ sound_ym.rd_data_reg_sel = 14; /* select port A */ sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ - debug_print_proc = ata_par_print; - } - else - debug_print_proc = NULL; -} - - -void ata_serial_print (const char *str) -{ - int c; - - while (c = *str++, c != 0) - { - if (c == '\n') - { - while (!(mfp.trn_stat & (1 << 7))) - barrier (); - mfp.usart_dta = '\r'; - } - while (!(mfp.trn_stat & (1 << 7))) - barrier (); - mfp.usart_dta = c; + atari_console_driver.write = atari_par_console_write; } + if (atari_console_driver.write) + register_console(&atari_console_driver); } /* ++roman: @@ -1079,7 +1081,8 @@ /* On the Medusa, phys. 0x4 may contain garbage because it's no ROM. See above for explanation why we cannot use PTOV(4). */ - reset_addr = is_medusa ? 0xe00030 : *(unsigned long *) 0xff000004; + reset_addr = is_hades ? 0x7fe00030 : + (is_medusa ? 0xe00030 : *(unsigned long *) 0xff000004); acia.key_ctrl = ACIA_RESET; /* reset ACIA for switch off OverScan, if it's active */ @@ -1159,6 +1162,8 @@ if (is_medusa) /* Medusa has TT _MCH cookie */ strcat (model, "Medusa"); + else if (is_hades) + strcat(model, "Hades"); else strcat (model, "TT"); break; @@ -1215,6 +1220,7 @@ ATARIHW_ANNOUNCE(SCU, "System Control Unit"); ATARIHW_ANNOUNCE(BLITTER, "Blitter"); ATARIHW_ANNOUNCE(VME, "VME Bus"); + ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor"); return(len); } diff -u --recursive --new-file v2.1.35/linux/arch/m68k/atari/joystick.c linux/arch/m68k/atari/joystick.c --- v2.1.35/linux/arch/m68k/atari/joystick.c Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/atari/joystick.c Thu Apr 17 13:20:41 1997 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -90,30 +91,28 @@ char *buffer, unsigned long count) { int minor = DEVICE_NR(inode->i_rdev); - int i; if (count < 2) return -EINVAL; if (!joystick[minor].ready) return -EAGAIN; - put_user(joystick[minor].fire, buffer++); - put_user(joystick[minor].dir, buffer++); - for (i = 0; i < count; i++) - put_user(0, buffer++); joystick[minor].ready = 0; - - return i; + if (put_user(joystick[minor].fire, buffer++) || + put_user(joystick[minor].dir, buffer++)) + return -EFAULT; + if (count > 2) + if (clear_user(buffer, count - 2)) + return -EFAULT; + return count; } -static int joystick_select(struct inode *inode, struct file *file, int sel_type, select_table *wait) +static unsigned int joystick_poll(struct file *file, poll_table *wait) { - int minor = DEVICE_NR(inode->i_rdev); + int minor = DEVICE_NR(file->f_inode->i_rdev); - if (sel_type != SEL_IN) - return 0; + poll_wait(&joystick[minor].wait, wait); if (joystick[minor].ready) - return 1; - select_wait(&joystick[minor].wait, wait); + return POLLIN | POLLRDNORM; return 0; } @@ -122,7 +121,7 @@ read_joystick, write_joystick, NULL, /* joystick_readdir */ - joystick_select, + joystick_poll, NULL, /* joystick_ioctl */ NULL, /* joystick_mmap */ open_joystick, @@ -135,7 +134,7 @@ joystick[0].ready = joystick[1].ready = 0; joystick[0].wait = joystick[1].wait = NULL; - if (register_chrdev(MAJOR_NR, "joystick", &atari_joystick_fops)) + if (register_chrdev(MAJOR_NR, "Joystick", &atari_joystick_fops)) printk("unable to get major %d for joystick devices\n", MAJOR_NR); return 0; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/Makefile linux/arch/m68k/boot/Makefile --- v2.1.35/linux/arch/m68k/boot/Makefile Wed Sep 25 00:47:38 1996 +++ linux/arch/m68k/boot/Makefile Thu Apr 17 13:20:41 1997 @@ -8,14 +8,16 @@ ifdef CONFIG_AMIGA AMIGA_BOOTSTRAP = amiga_bootstrap AMIGA_BOOTOBJS := amiga/bootstrap.o amiga/linuxboot.o -AMIGA_HOSTCC = m68k-cbm-amigados-gcc -I$(TOPDIR)/include +AMIGA_HOSTCC = m68k-cbm-amigados-gcc +AMIGA_HOSTINC = -I$(TOPDIR)/include AMIGA_HOSTFLAGS=-m68030 -O2 -Wall -Dlinux endif ifdef CONFIG_ATARI ATARI_BOOTSTRAP = atari_bootstrap ATARI_BOOTOBJS := atari/bootstrap.o -ATARI_HOSTCC = m68k-mint-gcc -I$(TOPDIR)/include +ATARI_HOSTCC = m68k-mint-gcc +ATARI_HOSTINC = -I$(TOPDIR)/include ATARI_HOSTFLAGS = -m68030 -m68881 -Dlinux -O2 -Wall # BOOTP/TFTP support in bootstrap? @@ -36,27 +38,28 @@ ifdef CONFIG_ATARI atari_bootstrap: $(ATARI_BOOTOBJS) - $(ATARI_HOSTCC) $(ATARI_HOSTFLAGS) -o $@ $(ATARI_BOOTOBJS) + $(ATARI_HOSTCC) $(ATARI_HOSTINC) $(ATARI_HOSTFLAGS) -o $@ $(ATARI_BOOTOBJS) rm -f ../../../bootstrap ln $@ ../../../bootstrap endif ifdef CONFIG_AMIGA amiga_bootstrap: $(AMIGA_BOOTOBJS) - $(AMIGA_HOSTCC) $(AMIGA_HOSTFLAGS) -o $@ -s -noixemul $(AMIGA_BOOTOBJS) + $(AMIGA_HOSTCC) $(AMIGA_HOSTINC) $(AMIGA_HOSTFLAGS) -o $@ -s -noixemul $(AMIGA_BOOTOBJS) rm -f ../../../bootstrap ln $@ ../../../bootstrap endif $(AMIGA_BOOTOBJS): %.o: %.c - $(AMIGA_HOSTCC) $(AMIGA_HOSTFLAGS) -c $< -o $@ + $(AMIGA_HOSTCC) $(AMIGA_HOSTINC) $(AMIGA_HOSTFLAGS) -c $< -o $@ $(ATARI_BOOTOBJS): %.o: %.c - $(ATARI_HOSTCC) $(ATARI_HOSTFLAGS) -c $< -o $@ + $(ATARI_HOSTCC) $(ATARI_HOSTINC) $(ATARI_HOSTFLAGS) -c $< -o $@ bootstrap: $(AMIGA_BOOTSTRAP) $(ATARI_BOOTSTRAP) clean: - rm -f *.o amiga/*.o atari/*.o amiga_bootstrap atari_bootstrap + rm -f *.o amiga/*.o atari/*.o amiga_bootstrap atari_bootstrap \ + ../../../bootstrap dep: diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.c linux/arch/m68k/boot/amiga/bootstrap.c --- v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/bootstrap.c Thu Apr 17 13:20:41 1997 @@ -51,9 +51,8 @@ /* Library Bases */ +long __oslibversion = 36; extern const struct ExecBase *SysBase; -const struct ExpansionBase *ExpansionBase; -const struct GfxBase *GfxBase; static const char *memfile_name = NULL; @@ -80,24 +79,25 @@ static void Close(int fd); static int FileSize(const char *path); static void Sleep(u_long micros); -static int ModifyBootinfo(struct amiga_bootinfo *bi); static void Usage(void) { fprintf(stderr, - "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n" - "Usage: %s [options] [kernel command line]\n\n" - "Valid options are:\n" - " -h, --help Display this usage information\n" - " -k, --kernel file Use kernel image `file' (default is `vmlinux')\n" - " -r, --ramdisk file Use ramdisk image `file'\n" - " -d, --debug Enable debug mode\n" - " -b, --baud speed Set the serial port speed (default is 9600)\n" - " -m, --memfile file Use memory file `file'\n" - " -v, --keep-video Don't reset the video mode\n" - " -t, --model id Set the Amiga model to `id'\n\n", - ProgramName); + "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n" + "Usage: %s [options] [kernel command line]\n\n" + "Basic options:\n" + " -h, --help Display this usage information\n" + " -k, --kernel file Use kernel image `file' (default is `vmlinux')\n" + " -r, --ramdisk file Use ramdisk image `file'\n" + "Advanced options:\n" + " -d, --debug Enable debug mode\n" + " -b, --baud speed Set the serial port speed (default is 9600)\n" + " -m, --memfile file Use memory file `file'\n" + " -v, --keep-video Don't reset the video mode\n" + " -t, --model id Set the Amiga model to `id'\n" + " -p, --processor cfm Set the processor type to `cfm\n\n", + ProgramName); exit(EXIT_FAILURE); } @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) { int i; - int debugflag = 0, keep_video = 0; + int processor = 0, debugflag = 0, keep_video = 0; u_int baud = 0; const char *kernel_name = NULL; const char *ramdisk_name = NULL; @@ -117,17 +117,17 @@ if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) Usage(); else if (!strcmp(argv[0], "-k") || !strcmp(argv[0], "--kernel")) - if (--argc && !kernel_name) { - kernel_name = argv[1]; - argv++; - } else - Usage(); + if (--argc && !kernel_name) { + kernel_name = argv[1]; + argv++; + } else + Usage(); else if (!strcmp(argv[0], "-r") || !strcmp(argv[0], "--ramdisk")) - if (--argc && !ramdisk_name) { - ramdisk_name = argv[1]; - argv++; - } else - Usage(); + if (--argc && !ramdisk_name) { + ramdisk_name = argv[1]; + argv++; + } else + Usage(); else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--debug")) debugflag = 1; else if (!strcmp(argv[0], "-b") || !strcmp(argv[0], "--baud")) @@ -137,19 +137,25 @@ } else Usage(); else if (!strcmp(argv[0], "-m") || !strcmp(argv[0], "--memfile")) - if (--argc && !memfile_name) { - memfile_name = argv[1]; - argv++; - } else - Usage(); + if (--argc && !memfile_name) { + memfile_name = argv[1]; + argv++; + } else + Usage(); else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--keep-video")) keep_video = 1; else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--model")) - if (--argc && !model) { - model = atoi(argv[1]); - argv++; - } else - Usage(); + if (--argc && !model) { + model = atoi(argv[1]); + argv++; + } else + Usage(); + else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--processor")) + if (--argc && !processor) { + processor = atoi(argv[1]); + argv++; + } else + Usage(); else break; } @@ -158,22 +164,6 @@ SysBase = *(struct ExecBase **)4; - /* open Expansion Library */ - ExpansionBase = (struct ExpansionBase *)OpenLibrary("expansion.library", - 36); - if (!ExpansionBase) { - fputs("Unable to open expansion.library V36 or greater! Aborting...\n", - stderr); - exit(EXIT_FAILURE); - } - - /* open Graphics Library */ - GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0); - if (!GfxBase) { - fputs("Unable to open graphics.library! Aborting...\n", stderr); - exit(EXIT_FAILURE); - } - /* * Join command line options */ @@ -187,9 +177,52 @@ } } + memset(&args.bi, 0, sizeof(args.bi)); + if (processor) { + int cpu = processor/100%10; + int fpu = processor/10%10; + int mmu = processor%10; + if (cpu) + args.bi.cputype = 1<<(cpu-1); + if (fpu) + args.bi.fputype = 1<<(fpu-1); + if (mmu) + args.bi.mmutype = 1<<(mmu-1); + } + /* + * If we have a memory file, read the memory information from it + */ + if (memfile_name) { + FILE *fp; + int i; + + if ((fp = fopen(memfile_name, "r")) == NULL) { + perror("open memory file"); + fprintf(stderr, "Cannot open memory file %s\n", memfile_name); + return(FALSE); + } + + if (fscanf(fp, "%lu", &args.bi.chip_size) != 1) { + fprintf(stderr, "memory file does not contain chip memory size\n"); + fclose(fp); + return(FALSE); + } + + for (i = 0; i < NUM_MEMINFO; i++) + if (fscanf(fp, "%lx %lu", &args.bi.memory[i].addr, + &args.bi.memory[i].size) != 2) + break; + + fclose(fp); + args.bi.num_memory = i; + } + strncpy(args.bi.command_line, commandline, CL_SIZE); + args.bi.command_line[CL_SIZE-1] = '\0'; + if (model != AMI_UNKNOWN) + args.bi.model = model; + args.kernelname = kernel_name; args.ramdiskname = ramdisk_name; - args.commandline = commandline; args.debugflag = debugflag; args.keep_video = keep_video; args.reset_boards = 1; @@ -204,14 +237,10 @@ args.close = Close; args.filesize = FileSize; args.sleep = Sleep; - args.modify_bootinfo = ModifyBootinfo; /* Do The Right Stuff */ linuxboot(&args); - CloseLibrary((struct Library *)GfxBase); - CloseLibrary((struct Library *)ExpansionBase); - /* if we ever get here, something went wrong */ exit(EXIT_FAILURE); } @@ -224,6 +253,7 @@ static void Puts(const char *str) { fputs(str, stderr); + fflush(stderr); } static long GetChar(void) @@ -234,6 +264,7 @@ static void PutChar(char c) { fputc(c, stderr); + fflush(stderr); } static void Printf(const char *fmt, ...) @@ -243,6 +274,7 @@ va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); + fflush(stderr); } static int Open(const char *path) @@ -271,8 +303,8 @@ int fd, size = -1; if ((fd = open(path, O_RDONLY)) != -1) { - size = lseek(fd, 0, SEEK_END); - close(fd); + size = lseek(fd, 0, SEEK_END); + close(fd); } return(size); } @@ -298,47 +330,4 @@ } DeleteMsgPort(TimerPort); } -} - - -static int ModifyBootinfo(struct amiga_bootinfo *bi) -{ - /* - * if we have a memory file, read the memory information from it - */ - if (memfile_name) { - FILE *fp; - int i; - - if ((fp = fopen(memfile_name, "r")) == NULL) { - perror("open memory file"); - fprintf(stderr, "Cannot open memory file %s\n", memfile_name); - return(FALSE); - } - - if (fscanf(fp, "%lu", &bi->chip_size) != 1) { - fprintf(stderr, "memory file does not contain chip memory size\n"); - fclose(fp); - return(FALSE); - } - - for (i = 0; i < NUM_MEMINFO; i++) { - if (fscanf(fp, "%lx %lu", &bi->memory[i].addr, &bi->memory[i].size) - != 2) - break; - } - - fclose(fp); - - if (i != bi->num_memory && i > 0) - bi->num_memory = i; - } - - /* - * change the Amiga model, if necessary - */ - if (model != AMI_UNKNOWN) - bi->model = model; - - return(TRUE); } diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.h linux/arch/m68k/boot/amiga/bootstrap.h --- v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.h Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/bootstrap.h Thu Apr 17 13:20:41 1997 @@ -59,30 +59,6 @@ struct IORequest; -static __inline void CloseLibrary(struct Library *library) -{ - register const struct ExecBase *a6 __asm("a6") = SysBase; - register struct Library *a1 __asm("a1") = library; - __asm __volatile ("jsr a6@(-0x19e)" - : /* no output */ - : "r" (a6), "r" (a1) - : "a0","a1","d0","d1", "memory"); -} - -static __inline struct Library *OpenLibrary(char *libName, - unsigned long version) -{ - register struct Library * _res __asm("d0"); - register const struct ExecBase *a6 __asm("a6") = SysBase; - register u_char *a1 __asm("a1") = libName; - register unsigned long d0 __asm("d0") = version; - __asm __volatile ("jsr a6@(-0x228)" - : "=r" (_res) - : "r" (a6), "r" (a1), "r" (d0) - : "a0","a1","d0","d1", "memory"); - return _res; -} - static __inline char OpenDevice(u_char *devName, u_long unit, struct IORequest *ioRequest, u_long flags) { diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.c linux/arch/m68k/boot/amiga/linuxboot.c --- v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/linuxboot.c Thu Apr 17 13:20:42 1997 @@ -20,6 +20,24 @@ * 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. + * + * History: + * 03 Feb 1997 Implemented kernel decompression (Geert, based on Roman's + * code for ataboot) + * 30 Dec 1996 Reverted the CPU detection to the old scheme + * New boot parameter override scheme (Geert) + * 27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert) + * 9 Sep 1996 Rewritten option parsing + * New parameter passing to linuxboot() (linuxboot_args) + * (Geert) + * 18 Aug 1996 Updated for the new boot information structure (Geert) + * 10 Jan 1996 The real Linux/m68k boot code moved to linuxboot.[ch] + * (Geert) + * 11 Jul 1995 Support for ELF kernel (untested!) (Andreas) + * 7 Mar 1995 Memory block sizes are rounded to a multiple of 256K + * instead of 1M (Geert) + * 31 May 1994 Memory thrash problem solved (Geert) + * 11 May 1994 A3640 MapROM check (Geert) */ @@ -29,6 +47,8 @@ #define BOOTINFO_COMPAT_1_0 /* bootinfo interface version 1.0 compatible */ +/* support compressed kernels? */ +#define ZKERNEL #include #include @@ -60,7 +80,7 @@ static const struct linuxboot_args *linuxboot_args; /* Bootinfo */ -static struct amiga_bootinfo bi; +struct amiga_bootinfo bi; #ifdef BOOTINFO_COMPAT_1_0 static struct compat_bootinfo compat_bootinfo; @@ -75,7 +95,6 @@ #define kernelname linuxboot_args->kernelname #define ramdiskname linuxboot_args->ramdiskname -#define commandline linuxboot_args->commandline #define debugflag linuxboot_args->debugflag #define keep_video linuxboot_args->keep_video #define reset_boards linuxboot_args->reset_boards @@ -91,8 +110,6 @@ #define Close linuxboot_args->close #define FileSize linuxboot_args->filesize #define Sleep linuxboot_args->sleep -#define ModifyBootinfo linuxboot_args->modify_bootinfo - /* * Function Prototypes @@ -115,6 +132,16 @@ u_long kernel_size) __attribute__ ((noreturn)); asmlinkage u_long maprommed(void); asmlinkage u_long check346(void); +#ifdef ZKERNEL +static int load_zkernel(int fd); +static int KRead(int fd, void *buf, int cnt); +static int KSeek(int fd, int offset); +static int KClose(int fd); +#else +#define KRead Read +#define KSeek Seek +#define KClose Close +#endif /* @@ -174,7 +201,7 @@ u_long linuxboot(const struct linuxboot_args *args) { - int kfd = -1, rfd = -1, elf_kernel = 0; + int kfd = -1, rfd = -1, elf_kernel = 0, do_fast, do_chip; int i, j; const struct MemHeader *mnp; struct ConfigDev *cdp = NULL; @@ -196,38 +223,42 @@ Puts("\nLinux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n"); Puts("Copyright 1993,1994 by Hamish Macdonald and Greg Harp\n\n"); - memset(&bi, 0, sizeof(bi)); + /* Note: Initial values in bi override detected values */ + bi = args->bi; /* machine is Amiga */ bi.machtype = MACH_AMIGA; /* determine chipset */ - bi.chipset = get_chipset(); + if (!bi.chipset) + bi.chipset = get_chipset(); /* determine CPU, FPU and MMU type */ - get_processor(&bi.cputype, &bi.fputype, &bi.mmutype); + if (!bi.cputype) + get_processor(&bi.cputype, &bi.fputype, &bi.mmutype); /* determine Amiga model */ - bi.model = get_model(bi.chipset); + if (!bi.model) + bi.model = get_model(bi.chipset); model_mask = (bi.model != AMI_UNKNOWN) ? 1<cd_BoardAddr); - } + if (!bi.num_autocon) + for (i = 0; (cdp = (struct ConfigDev *)FindConfigDev(cdp, -1, -1)); i++) + if (bi.num_autocon < ZORRO_NUM_AUTO) + /* copy the contents of each structure into our boot info and + count this device */ + memcpy(&bi.autocon[bi.num_autocon++], cdp, + sizeof(struct ConfigDev)); + else + Printf("Warning: too many AutoConfig devices. Ignoring device at " + "0x%08lx\n", cdp->cd_BoardAddr); + do_fast = bi.num_memory ? 0 : 1; + do_chip = bi.chip_size ? 0 : 1; /* find out the memory in the system */ - bi.num_memory = 0; for (mnp = (struct MemHeader *)SysBase->MemList.lh_Head; mnp->mh_Node.ln_Succ; mnp = (struct MemHeader *)mnp->mh_Node.ln_Succ) { @@ -266,7 +297,7 @@ mh.mh_Lower = (void *)((u_long)mh.mh_Lower & 0xfffff000); /* if fast memory */ - if (mh.mh_Attributes & MEMF_FAST) { + if (do_fast && mh.mh_Attributes & MEMF_FAST) { /* set the size value to the size of this block and mask off to a 256K increment */ u_long size = ((u_long)mh.mh_Upper-(u_long)mh.mh_Lower)&0xfffc0000; @@ -279,30 +310,26 @@ bi.num_memory++; } else Printf("Warning: too many memory blocks. Ignoring block " - "of %ldK at 0x%08x\n", size>>10, + "of %ldK at 0x%08x\n", size>>10, (u_long)mh.mh_Lower); - } else if (mh.mh_Attributes & MEMF_CHIP) + } else if (do_chip && mh.mh_Attributes & MEMF_CHIP) /* if CHIP memory, record the size */ bi.chip_size = (u_long)mh.mh_Upper; } /* get info from ExecBase */ - bi.vblank = SysBase->VBlankFrequency; - bi.psfreq = SysBase->PowerSupplyFrequency; - bi.eclock = SysBase->ex_EClockFrequency; + if (!bi.vblank) + bi.vblank = SysBase->VBlankFrequency; + if (!bi.psfreq) + bi.psfreq = SysBase->PowerSupplyFrequency; + if (!bi.eclock) + bi.eclock = SysBase->ex_EClockFrequency; /* serial port */ - realbaud = baud ? baud : DEFAULT_BAUD; - bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1; - - /* copy command line options into the kernel command line */ - strncpy(bi.command_line, commandline, CL_SIZE); - bi.command_line[CL_SIZE-1] = '\0'; - - - /* modify the bootinfo, e.g. to change the memory configuration */ - if (ModifyBootinfo && !ModifyBootinfo(&bi)) - goto Fail; + if (!bi.serper) { + realbaud = baud ? baud : DEFAULT_BAUD; + bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1; + } /* display Amiga model */ if (bi.model >= first_amiga_model && bi.model <= last_amiga_model) @@ -347,7 +374,7 @@ } /* display the chipset */ - switch(bi.chipset) { + switch (bi.chipset) { case CS_STONEAGE: Puts(", old or unknown chipset"); break; @@ -457,11 +484,24 @@ Printf("Unable to open kernel file `%s'\n", kernelname); goto Fail; } - if (Read(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) { + if (KRead(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) { Puts("Unable to read exec header from kernel file\n"); goto Fail; } +#ifdef ZKERNEL + if (((unsigned char *)&kexec)[0] == 037 && + (((unsigned char *)&kexec)[1] == 0213 || + ((unsigned char *)&kexec)[1] == 0236)) { + /* That's a compressed kernel */ + Puts("Kernel is compressed\n"); + if (load_zkernel(kfd)) { + Puts("Decompression error -- aborting\n"); + goto Fail; + } + } +#endif + switch (N_MAGIC(kexec)) { case ZMAGIC: if (debugflag) @@ -479,8 +519,8 @@ default: /* Try to parse it as an ELF header */ - Seek(kfd, 0); - if ((Read(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) == + KSeek(kfd, 0); + if ((KRead(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) == sizeof(kexec_elf)) && (memcmp(&kexec_elf.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0)) { elf_kernel = 1; @@ -501,8 +541,8 @@ Puts("Unable to allocate memory for program headers\n"); goto Fail; } - Seek(kfd, kexec_elf.e_phoff); - if (Read(kfd, (void *)kernel_phdrs, + KSeek(kfd, kexec_elf.e_phoff); + if (KRead(kfd, (void *)kernel_phdrs, kexec_elf.e_phnum*sizeof(*kernel_phdrs)) != kexec_elf.e_phnum*sizeof(*kernel_phdrs)) { Puts("Unable to read program headers from kernel file\n"); @@ -557,32 +597,32 @@ /* read the text and data segments from the kernel image */ if (elf_kernel) for (i = 0; i < kexec_elf.e_phnum; i++) { - if (Seek(kfd, kernel_phdrs[i].p_offset) == -1) { + if (KSeek(kfd, kernel_phdrs[i].p_offset) == -1) { Printf("Failed to seek to segment %ld\n", i); goto Fail; } - if (Read(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE, - kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) { + if (KRead(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE, + kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) { Printf("Failed to read segment %ld\n", i); goto Fail; } } else { - if (Seek(kfd, text_offset) == -1) { + if (KSeek(kfd, text_offset) == -1) { Puts("Failed to seek to text\n"); goto Fail; } - if (Read(kfd, memptr, kexec.a_text) != kexec.a_text) { + if (KRead(kfd, memptr, kexec.a_text) != kexec.a_text) { Puts("Failed to read text\n"); goto Fail; } /* data follows immediately after text */ - if (Read(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) { + if (KRead(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) { Puts("Failed to read data\n"); goto Fail; } } - Close(kfd); + KClose(kfd); kfd = -1; /* Check kernel's bootinfo version */ @@ -706,7 +746,7 @@ /* Clean up and exit in case of a failure */ Fail: if (kfd != -1) - Close(kfd); + KClose(kfd); if (rfd != -1) Close(rfd); if (memptr) @@ -748,37 +788,17 @@ * Determine the CPU Type */ -/* Dectection of 68030 and up is unreliable, so we check ourself */ -/* Keep consistent with asm/setup.h! */ -/* 24.11.1996 Joerg Dorchain */ -asm( ".text\n" -ALIGN_STR "\n" -SYMBOL_NAME_STR(check346) ": - orw #0x700,%sr | disable ints - movec %vbr,%a0 | get vbr - movel %a0@(11*4),%a1 | save old trap vector (Line F) - movel #L1,%a0@(11*4) | set L1 as new vector - movel %sp,%d1 | save stack pointer - moveq #2,%d0 | value with exception (030) - .long 0xf6208000 | move16 %a0@+,%a0@+, the 030 test instruction - nop | clear instruction pipeline - movel %d1,%sp | restore stack pointer - movec %vbr,%a0 | get vbr again - moveq #4,%d0 | value with exception (040) - .word 0xf5c8 | plpar %a0@, the 040 test instruction - nop | clear instruction pipeline - moveq #8,%d0 | value if we come here -L1: movel %d1,%sp | restore stack pointer - movel %a1,%a0@(11*4) | restore vector - rte" -); - static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu) { - if (SysBase->AttnFlags & (AFF_68030|AFF_68040|AFF_68060)) - *cpu = Supervisor(check346); + *cpu = *fpu = 0; + if (SysBase->AttnFlags & AFF_68060) + *cpu = CPU_68060; + else if (SysBase->AttnFlags & AFF_68040) + *cpu = CPU_68040; + else if (SysBase->AttnFlags & AFF_68030) + *cpu = CPU_68030; else if (SysBase->AttnFlags & AFF_68020) - *cpu = CPU_68020; + *cpu = CPU_68020; if (*cpu == CPU_68040 || *cpu == CPU_68060) { if (SysBase->AttnFlags & AFF_FPU40) *fpu = *cpu; @@ -786,7 +806,7 @@ if (SysBase->AttnFlags & AFF_68882) *fpu = FPU_68882; else if (SysBase->AttnFlags & AFF_68881) - *cpu = FPU_68881; + *fpu = FPU_68881; } *mmu = *cpu; } @@ -806,7 +826,7 @@ else { if (debugflag) Puts(" Chipset: "); - switch(chipset) { + switch (chipset) { case CS_STONEAGE: if (debugflag) Puts("Old or unknown\n"); @@ -1361,7 +1381,7 @@ Disable(); *nic_cr = 0x21; /* nic command register: software reset etc. */ - while(((*nic_isr & 0x80) == 0) && --n) /* wait for reset to complete */ + while (((*nic_isr & 0x80) == 0) && --n) /* wait for reset to complete */ ; Enable(); @@ -1373,3 +1393,294 @@ #error reset_a2060: not yet implemented } #endif + + +#ifdef ZKERNEL + +#define ZFILE_CHUNK_BITS 16 /* chunk is 64 KB */ +#define ZFILE_CHUNK_SIZE (1 << ZFILE_CHUNK_BITS) +#define ZFILE_CHUNK_MASK (ZFILE_CHUNK_SIZE-1) +#define ZFILE_N_CHUNKS (2*1024*1024/ZFILE_CHUNK_SIZE) + +/* variables for storing the uncompressed data */ +static char *ZFile[ZFILE_N_CHUNKS]; +static int ZFileSize = 0; +static int ZFpos = 0; +static int Zwpos = 0; + +static int Zinfd = 0; /* fd of compressed file */ + +/* + * gzip declarations + */ + +#define OF(args) args + +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define INBUFSIZ 4096 +#define WSIZE 0x8000 /* window size--must be a power of two, and */ + /* at least 32K for zip's deflate method */ + +static uch *inbuf; +static uch *window; + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ +static int exit_code = 0; +static long bytes_out = 0; + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions (stubbed out) */ +#define Assert(cond,msg) +#define Trace(x) +#define Tracev(x) +#define Tracevv(x) +#define Tracec(c,x) +#define Tracecv(c,x) + +#define STATIC static + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +#define malloc(x) AllocVec(x, MEMF_FAST | MEMF_PUBLIC) +#define free(x) FreeVec(x) + +#ifdef LILO +#include "inflate.c" +#else +#include "../../../../lib/inflate.c" +#endif + +static void gzip_mark(void **ptr) +{ +} + +static void gzip_release(void **ptr) +{ +} + + +/* + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +static int fill_inbuf(void) +{ + if (exit_code) + return -1; + + insize = Read(Zinfd, inbuf, INBUFSIZ); + if (insize <= 0) + return -1; + + inptr = 1; + return(inbuf[0]); +} + +/* + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +static void flush_window(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + int chunk = Zwpos >> ZFILE_CHUNK_BITS; + + if (exit_code) + return; + + if (chunk >= ZFILE_N_CHUNKS) { + error("Compressed image too large! Aborting.\n"); + return; + } + if (!ZFile[chunk]) { + if (!(ZFile[chunk] = (char *)AllocMem(ZFILE_CHUNK_SIZE, + MEMF_FAST | MEMF_PUBLIC))) { + error("Out of memory for decompresing kernel image\n"); + return; + } + } + memcpy(ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt); + Zwpos += outcnt; + +#define DISPLAY_BITS 10 + if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0) + PutChar('.'); + + in = window; + for (n = 0; n < outcnt; n++) { + ch = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; +} + +static void error(char *x) +{ + Printf("\n%s", x); + exit_code = 1; +} + +static inline int call_sub(int (*func)(void), void *stackp) +{ + register int _res __asm("d0"); + register int (*a0)(void) __asm("a0") = func; + register int (*a1)(void) __asm("a1") = stackp; + + __asm __volatile ("movel sp,a2;" + "movel a1,sp;" + "jsr a0@;" + "movel a2,sp" + : "=r" (_res) + : "r" (a0), "r" (a1) + : "a0", "a1", "a2", "d0", "d1", "memory"); + return(_res); +} + +static int load_zkernel(int fd) +{ + int i, err = -1; +#define ZSTACKSIZE (16384) + u_long *zstack; + + for (i = 0; i < ZFILE_N_CHUNKS; ++i) + ZFile[i] = NULL; + Zinfd = fd; + Seek(fd, 0); + + if (!(inbuf = (uch *)AllocMem(INBUFSIZ, MEMF_FAST | MEMF_PUBLIC))) + Puts("Couldn't allocate gunzip buffer\n"); + else { + if (!(window = (uch *)AllocMem(WSIZE, MEMF_FAST | MEMF_PUBLIC))) + Puts("Couldn't allocate gunzip window\n"); + else { + if (!(zstack = (u_long *)AllocMem(ZSTACKSIZE, + MEMF_FAST | MEMF_PUBLIC))) + Puts("Couldn't allocate gunzip stack\n"); + else { + Puts("Uncompressing kernel image "); + makecrc(); + if (!(err = call_sub(gunzip, (char *)zstack+ZSTACKSIZE))) + Puts("done\n"); + ZFileSize = Zwpos; + FreeMem(zstack, ZSTACKSIZE); + } + FreeMem(window, WSIZE); + window = NULL; + } + FreeMem(inbuf, INBUFSIZ); + inbuf = NULL; + } + Close(Zinfd); /* input file not needed anymore */ + return(err); +} + + +/* Note about the read/lseek wrapper and its memory management: It assumes + * that all seeks are only forward, and thus data already read or skipped can + * be freed. This is true for current organization of bootstrap and kernels. + * Little exception: The struct kexec at the start of the file. After reading + * it, there may be a seek back to the end of the file. But this currently + * doesn't hurt. (Roman) + */ + +static int KRead(int fd, void *buf, int cnt) +{ + unsigned done = 0; + + if (!ZFileSize) + return(Read(fd, buf, cnt)); + + if (ZFpos + cnt > ZFileSize) + cnt = ZFileSize - ZFpos; + + while (cnt > 0) { + unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS; + unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS; + unsigned n = cnt; + + if (ZFpos + n > endchunk) + n = endchunk - ZFpos; + memcpy(buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n); + cnt -= n; + buf += n; + done += n; + ZFpos += n; + + if (ZFpos == endchunk) { + FreeMem(ZFile[chunk], ZFILE_CHUNK_SIZE); + ZFile[chunk] = NULL; + } + } + + return(done); +} + + +static int KSeek(int fd, int offset) +{ + unsigned oldpos, oldchunk, newchunk; + + if (!ZFileSize) + return(Seek(fd, offset)); + + oldpos = ZFpos; + ZFpos = offset; + if (ZFpos < 0) { + ZFpos = 0; + return(-1); + } else if (ZFpos > ZFileSize) { + ZFpos = ZFileSize; + return(-1); + } + + /* free memory of skipped-over data */ + oldchunk = oldpos >> ZFILE_CHUNK_BITS; + newchunk = ZFpos >> ZFILE_CHUNK_BITS; + while(oldchunk < newchunk) { + if (ZFile[oldchunk]) { + FreeMem(ZFile[oldchunk], ZFILE_CHUNK_SIZE); + ZFile[oldchunk] = NULL; + } + ++oldchunk; + } + return(ZFpos); +} + + +static void free_zfile(void) +{ + int i; + + for (i = 0; i < ZFILE_N_CHUNKS; ++i) + if (ZFile[i]) { + FreeMem(ZFile[i], ZFILE_CHUNK_SIZE); + ZFile[i] = NULL; + } +} + +static int KClose(int fd) +{ + if (ZFileSize) { + free_zfile(); + ZFileSize = 0; + } else + Close(fd); + return(0); +} +#endif /* ZKERNEL */ diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.h linux/arch/m68k/boot/amiga/linuxboot.h --- v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.h Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/linuxboot.h Thu Apr 17 13:20:42 1997 @@ -24,14 +24,14 @@ #include -#include +#include /* * Amiboot Version */ -#define AMIBOOT_VERSION "5.1" +#define AMIBOOT_VERSION "5.4" /* @@ -42,7 +42,7 @@ */ struct amiga_bootinfo { - u_long machtype; /* machine type */ + u_long machtype; /* machine type = MACH_AMIGA */ u_long cputype; /* system CPU */ u_long fputype; /* system FPU */ u_long mmutype; /* system MMU */ @@ -67,9 +67,9 @@ */ struct linuxboot_args { + struct amiga_bootinfo bi; /* Initial values override detected values */ const char *kernelname; const char *ramdiskname; - const char *commandline; int debugflag; int keep_video; int reset_boards; @@ -84,7 +84,6 @@ void (*close)(int fd); int (*filesize)(const char *path); void (*sleep)(u_long micros); - int (*modify_bootinfo)(struct amiga_bootinfo *bi); }; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/atari/bootp.c linux/arch/m68k/boot/atari/bootp.c --- v2.1.35/linux/arch/m68k/boot/atari/bootp.c Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/boot/atari/bootp.c Thu Apr 17 13:20:42 1997 @@ -203,18 +203,20 @@ /* get_remote_kernel(): * Perform all necessary steps to get the kernel image * from the boot server. If successfull (retval == 0), subsequent calls to - * kread() can access the data. + * kread() can access the data. Fatal errors (i.e., retrying is useless) + * return -2, others -1. */ int get_remote_kernel( const char *kname /* optional */ ) { char image_name[256]; - + int rv; + /* Check if a Ethernet interface is present and determine the Ethernet * address */ if (check_ethif() < 0) { printf( "No Ethernet interface found -- no remote boot possible.\n" ); - return( -1 ); + return( -2 ); } /* Do a BOOTP request to find out our IP address and the kernel image's @@ -223,23 +225,23 @@ strcpy( image_name, kname ); else *image_name = 0; - if (bootp( image_name ) < 0) - return( -1 ); + if ((rv = bootp( image_name )) < 0) + return( rv ); /* Now start a TFTP connection to receive the kernel image */ - if (tftp( image_name ) < 0) - return( -1 ); + if ((rv = tftp( image_name )) < 0) + return( rv ); return( 0 ); } -/* kread(), klseek(), kclose(): +/* ll_read(), ll_lseek(), ll_close(): * Functions for accessing the received kernel image like with read(), * lseek(), close(). */ -int kread( int fd, void *buf, unsigned cnt ) +int ll_read( int fd, void *buf, unsigned cnt ) { unsigned done = 0; @@ -261,18 +263,26 @@ buf += n; done += n; KFpos += n; + + if (KFpos == endchunk) { + free( KFile[chunk] ); + KFile[chunk] = NULL; + } } return( done ); } -int klseek( int fd, int where, int whence ) +int ll_lseek( int fd, int where, int whence ) { + unsigned oldpos, oldchunk, newchunk; + if (!KFileSize) return( lseek( fd, where, whence ) ); + oldpos = KFpos; switch( whence ) { case SEEK_SET: KFpos = where; @@ -295,11 +305,22 @@ return( -1 ); } + /* free memory of skipped-over data */ + oldchunk = oldpos >> KFILE_CHUNK_BITS; + newchunk = KFpos >> KFILE_CHUNK_BITS; + while( oldchunk < newchunk ) { + if (KFile[oldchunk]) { + free( KFile[oldchunk] ); + KFile[oldchunk] = NULL; + } + ++oldchunk; + } + return( KFpos ); } -int kclose( int fd ) +int ll_close( int fd ) { if (!KFileSize) @@ -382,7 +403,7 @@ } if (retry >= BOOTP_RETRYS) { printf( "No response from a bootp server\n" ); - return( -1 ); + return( -2 ); } ServerIPaddr = reply->bootp.siaddr; @@ -433,7 +454,7 @@ printf( "TFTP RREQ: %s\n", ErrStr[-err-1] ); if (--retries > 0) goto repeat_req; - return( -1 ); + return( err == ETIMEO ? -2 : -1 ); } retries = 5; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/atari/bootp.h linux/arch/m68k/boot/atari/bootp.h --- v2.1.35/linux/arch/m68k/boot/atari/bootp.h Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/boot/atari/bootp.h Thu Apr 17 13:20:42 1997 @@ -34,9 +34,9 @@ /***************************** Prototypes *****************************/ int get_remote_kernel( const char *kname ); -int kread( int fd, void *buf, unsigned cnt ); -int klseek( int fd, int where, int whence ); -int kclose( int fd ); +int ll_read( int fd, void *buf, unsigned cnt ); +int ll_lseek( int fd, int where, int whence ); +int ll_close( int fd ); /************************* End of Prototypes **************************/ diff -u --recursive --new-file v2.1.35/linux/arch/m68k/boot/atari/bootstrap.c linux/arch/m68k/boot/atari/bootstrap.c --- v2.1.35/linux/arch/m68k/boot/atari/bootstrap.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/atari/bootstrap.c Thu Apr 17 13:20:42 1997 @@ -8,6 +8,8 @@ ** for more details. ** ** History: +** 01 Feb 1997 Implemented kernel decompression (Roman) +** 28 Nov 1996 Fixed and tested previous change (James) ** 27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert) ** 12 Nov 1996 Fixed and tested previous change (Andreas) ** 18 Aug 1996 Updated for the new boot information structure (untested!) @@ -32,6 +34,8 @@ #define BOOTINFO_COMPAT_1_0 /* bootinfo interface version 1.0 compatible */ +/* support compressed kernels? */ +#define ZKERNEL #include #include @@ -159,6 +163,9 @@ * ...err! On the Afterburner040 (for the Falcon) it's the same... So we do * another test with 0x00ff82fe, that gives a bus error on the Falcon, but is * in the range where the Medusa always asserts DTACK. + * On the Hades address 0 is writeable as well and it asserts DTACK on + * address 0x00ff82fe. To test if the machine is a Hades, address 0xb0000000 + * is tested. On the Medusa this gives a bus error. */ int test_medusa( void ) @@ -177,7 +184,10 @@ "nop \n\t" "tstb 0x00ff82fe\n\t" "nop \n\t" - "moveq #1,%0\n" + "moveq #1,%0\n\t" + "tstb 0xb0000000\n\t" + "nop \n\t" + "moveq #0,%0\n" "Lberr:\t" "movel a1,sp\n\t" "movel a0,0x8" @@ -357,11 +367,21 @@ #ifdef USE_BOOTP # include "bootp.h" #else -# define kread read -# define klseek lseek -# define kclose close +# define ll_read read +# define ll_lseek lseek +# define ll_close close #endif +#ifdef ZKERNEL +static int load_zkernel( int fd ); +static int kread( int fd, void *buf, unsigned cnt ); +static int klseek( int fd, int where, int whence ); +static int kclose( int fd ); +#else +# define kread read +# define klseek lseek +# define kclose close +#endif /* ++andreas: this must be inline due to Super */ static inline void boot_exit (int) __attribute__ ((noreturn)); @@ -385,16 +405,18 @@ Elf32_Ehdr kexec_elf; Elf32_Phdr *kernel_phdrs = NULL; u_long start_mem, mem_size, rd_size, text_offset = 0, kernel_size; + int prefer_bootp = 1, kname_set = 0, n_knames; #ifdef USE_BOOTP - int prefer_bootp = 1, kname_set = 0; + int err; #endif + char kname_list[5][64]; void *bi_ptr; ramdisk_name = NULL; kernel_name = "vmlinux"; /* print the startup message */ - puts("\fLinux/68k Atari Bootstrap version 2.0" + puts("\fLinux/68k Atari Bootstrap version 2.2" #ifdef USE_BOOTP " (with BOOTP)" #endif @@ -410,11 +432,7 @@ bi.machtype = MACH_ATARI; /* check arguments */ -#ifdef USE_BOOTP while ((ch = getopt(argc, argv, "bdtsk:r:")) != EOF) -#else - while ((ch = getopt(argc, argv, "dtsk:r:")) != EOF) -#endif switch (ch) { case 'd': debugflag = 1; @@ -427,18 +445,14 @@ break; case 'k': kernel_name = optarg; -#ifdef USE_BOOTP kname_set = 1; -#endif break; case 'r': ramdisk_name = optarg; break; -#ifdef USE_BOOTP case 'b': prefer_bootp = 0; break; -#endif case '?': default: usage(); @@ -744,38 +758,60 @@ boot_exit(-1); #endif /* TEST */ + i = 0; #ifdef USE_BOOTP + if (!kname_set) + kname_list[i++][0] = '\0'; /* default kernel which BOOTP server says */ +#endif +#ifdef ZKERNEL + strcpy( kname_list[i], kernel_name ); + strcat( kname_list[i], ".gz" ); + ++i; +#endif + strcpy( kname_list[i++], kernel_name ); +#ifdef ZKERNEL + if (!kname_set) + strcpy( kname_list[i++], "vmlinuz" ); +#endif + n_knames = i; + kfd = -1; +#ifdef USE_BOOTP if (prefer_bootp) { - /* First try to get a remote kernel, then use a local kernel (if - * present) */ - if (get_remote_kernel( kname_set ? kernel_name : NULL ) < 0) { - printf( "\nremote boot failed; trying local kernel\n" ); - if ((kfd = open (kernel_name, O_RDONLY)) == -1) { - fprintf (stderr, "Unable to open kernel file %s\n", - kernel_name); - boot_exit (EXIT_FAILURE); - } + for( i = 0; i < n_knames; ++i ) { + if ((err = get_remote_kernel( kname_list[i] )) >= 0) + goto kernel_open; + if (err < -1) /* fatal error; retries don't help... */ + break; } + printf( "\nremote boot failed; trying local kernel\n" ); } - else { - /* Try BOOTP if local kernel cannot be opened */ - if ((kfd = open (kernel_name, O_RDONLY)) == -1) { - printf( "\nlocal kernel failed; trying remote boot\n" ); - if (get_remote_kernel( kname_set ? kernel_name : NULL ) < 0) { - fprintf (stderr, "Unable to remote boot and " - "to open kernel file %s\n", kernel_name); - boot_exit (EXIT_FAILURE); - } - } +#endif + for( i = 0; i < n_knames; ++i ) { + if ((kfd = open( kname_list[i], O_RDONLY )) != -1) + goto kernel_open; } -#else - /* open kernel executable and read exec header */ - if ((kfd = open (kernel_name, O_RDONLY)) == -1) { - fprintf (stderr, "Unable to open kernel file %s\n", kernel_name); - boot_exit (EXIT_FAILURE); +#ifdef USE_BOOTP + if (!prefer_bootp) { + printf( "\nlocal kernel failed; trying remote boot\n" ); + for( i = 0; i < n_knames; ++i ) { + if ((err = get_remote_kernel( kname_list[i] )) >= 0) + goto kernel_open; + if (err < -1) /* fatal error; retries don't help... */ + break; + } } #endif + fprintf( stderr, "Unable to open any kernel file\n(Tried " ); + for( i = 0; i < n_knames; ++i ) { + fprintf( stderr, "%s%s", kname_list[i], + i < n_knames-2 ? ", " : + i == n_knames-2 ? ", and " : + ")\n" ); + } + boot_exit( EXIT_FAILURE ); + + kernel_open: if (kread (kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) { @@ -783,6 +819,19 @@ boot_exit (EXIT_FAILURE); } +#ifdef ZKERNEL + if (((unsigned char *)&kexec)[0] == 037 && + (((unsigned char *)&kexec)[1] == 0213 || + ((unsigned char *)&kexec)[1] == 0236)) { + /* That's a compressed kernel */ + printf( "Kernel is compressed\n" ); + if (load_zkernel( kfd )) { + printf( "Decompression error -- aborting\n" ); + boot_exit( EXIT_FAILURE ); + } + } +#endif + switch (N_MAGIC(kexec)) { case ZMAGIC: text_offset = N_TXTOFF(kexec); @@ -847,18 +896,6 @@ } else bi.ramdisk.size = 0; - - rd_size = bi.ramdisk.size; - if (mem_size - rd_size < MB && bi.num_memory > 1) - /* If running low on ST ram load ramdisk into alternate ram. */ - bi.ramdisk.addr = (u_long) bi.memory[1].addr + bi.memory[1].size - rd_size; - else - /* Else hopefully there is enough ST ram. */ - bi.ramdisk.addr = (u_long)start_mem + mem_size - rd_size; - - /* create the bootinfo structure */ - if (!create_bootinfo()) - boot_exit (EXIT_FAILURE); /* calculate the total required amount of memory */ if (elf_kernel) @@ -885,6 +922,19 @@ } else kernel_size = kexec.a_text + kexec.a_data + kexec.a_bss; + + rd_size = bi.ramdisk.size; + if (rd_size + kernel_size > mem_size - MB/2 && bi.num_memory > 1) + /* If running low on ST ram load ramdisk into alternate ram. */ + bi.ramdisk.addr = (u_long) bi.memory[1].addr + bi.memory[1].size - rd_size; + else + /* Else hopefully there is enough ST ram. */ + bi.ramdisk.addr = (u_long)start_mem + mem_size - rd_size; + + /* create the bootinfo structure */ + if (!create_bootinfo()) + boot_exit (EXIT_FAILURE); + memreq = kernel_size + bi_size; #ifdef BOOTINFO_COMPAT_1_0 if (sizeof(compat_bootinfo) > bi_size) @@ -997,7 +1047,7 @@ if (debugflag) { if (bi.ramdisk.size) - printf ("RAM disk at %#lx, size is %ldK\n", + printf ("RAM disk at %#lx, size is %ld\n", (u_long)(memptr + memreq - rd_size), bi.ramdisk.size); @@ -1192,7 +1242,7 @@ static int add_bi_record(u_short tag, u_short size, const void *data) { struct bi_record *record; - u_int size2; + u_short size2; size2 = (sizeof(struct bi_record)+size+3)&-4; if (bi_size+size2+sizeof(bi_union.record.tag) > MAX_BI_SIZE) { @@ -1238,7 +1288,7 @@ else if (bi.cputype & CPU_68060) compat_bootinfo.cputype = COMPAT_CPU_68060; else { - Printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype); + printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype); return(0); } if (bi.fputype & FPU_68881) @@ -1250,12 +1300,12 @@ else if (bi.fputype & FPU_68060) compat_bootinfo.cputype |= COMPAT_FPU_68060; else { - Printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype); + printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype); return(0); } compat_bootinfo.num_memory = bi.num_memory; if (compat_bootinfo.num_memory > COMPAT_NUM_MEMINFO) { - Printf("Warning: using only %d blocks of memory\n", + printf("Warning: using only %d blocks of memory\n", COMPAT_NUM_MEMINFO); compat_bootinfo.num_memory = COMPAT_NUM_MEMINFO; } @@ -1278,3 +1328,275 @@ return(1); } #endif /* BOOTINFO_COMPAT_1_0 */ + + +#ifdef ZKERNEL + +#define ZFILE_CHUNK_BITS 16 /* chunk is 64 KB */ +#define ZFILE_CHUNK_SIZE (1 << ZFILE_CHUNK_BITS) +#define ZFILE_CHUNK_MASK (ZFILE_CHUNK_SIZE-1) +#define ZFILE_N_CHUNKS (2*1024*1024/ZFILE_CHUNK_SIZE) + +/* variables for storing the uncompressed data */ +static char *ZFile[ZFILE_N_CHUNKS]; +static int ZFileSize = 0; +static int ZFpos = 0; +static int Zwpos = 0; + +static int Zinfd = 0; /* fd of compressed file */ + +/* + * gzip declarations + */ + +#define OF(args) args + +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define INBUFSIZ 4096 +#define WSIZE 0x8000 /* window size--must be a power of two, and */ + /* at least 32K for zip's deflate method */ + +static uch *inbuf; +static uch *window; + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ +static int exit_code = 0; +static long bytes_out = 0; + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions (stubbed out) */ +#define Assert(cond,msg) +#define Trace(x) +#define Tracev(x) +#define Tracevv(x) +#define Tracec(c,x) +#define Tracecv(c,x) + +#define STATIC static + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +#include "../../../../lib/inflate.c" + +static void gzip_mark( void **ptr ) +{ +} + +static void gzip_release( void **ptr ) +{ +} + + +/* + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +static int fill_inbuf( void ) +{ + if (exit_code) + return -1; + + insize = ll_read( Zinfd, inbuf, INBUFSIZ ); + if (insize <= 0) + return -1; + + inptr = 1; + return( inbuf[0] ); +} + +/* + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +static void flush_window( void ) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + int chunk = Zwpos >> ZFILE_CHUNK_BITS; + + if (chunk >= ZFILE_N_CHUNKS) { + fprintf( stderr, "compressed image too large! Aborting.\n" ); + boot_exit( EXIT_FAILURE ); + } + if (!ZFile[chunk]) { + if (!(ZFile[chunk] = (char *)Malloc( ZFILE_CHUNK_SIZE ))) { + fprintf( stderr, "Out of memory for decompresing kernel image\n" ); + boot_exit( EXIT_FAILURE ); + } + } + memcpy( ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt ); + Zwpos += outcnt; + +#define DISPLAY_BITS 13 + if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0) { + printf( "." ); + fflush( stdout ); + } + + in = window; + for (n = 0; n < outcnt; n++) { + ch = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; +} + +static void error( char *x ) +{ + fprintf( stderr, "\n%s", x); + exit_code = 1; +} + +static int load_zkernel( int fd ) +{ + int i, err; + + for( i = 0; i < ZFILE_N_CHUNKS; ++i ) + ZFile[i] = NULL; + Zinfd = fd; + ll_lseek( fd, 0, SEEK_SET ); + + if (!(inbuf = (uch *)Malloc( INBUFSIZ ))) { + fprintf( stderr, "Couldn't allocate gunzip buffer\n" ); + boot_exit( EXIT_FAILURE ); + } + if (!(window = (uch *)Malloc( WSIZE ))) { + fprintf( stderr, "Couldn't allocate gunzip window\n" ); + boot_exit( EXIT_FAILURE ); + } + + printf( "Uncompressing kernel image " ); + fflush( stdout ); + makecrc(); + if (!(err = gunzip())) + printf( "done\n" ); + ZFileSize = Zwpos; + ll_close( Zinfd ); /* input file not needed anymore */ + + Mfree( inbuf ); + Mfree( window ); + return( err ); +} + +/* Note about the read/lseek wrapper and its memory management: It assumes + * that all seeks are only forward, and thus data already read or skipped can + * be freed. This is true for current organization of bootstrap and kernels. + * Little exception: The struct kexec at the start of the file. After reading + * it, there may be a seek back to the end of the file. But this currently + * doesn't hurt. Same considerations apply to the TFTP file buffers. (Roman) + */ + +static int kread( int fd, void *buf, unsigned cnt ) +{ + unsigned done = 0; + + if (!ZFileSize) + return( ll_read( fd, buf, cnt ) ); + + if (ZFpos + cnt > ZFileSize) + cnt = ZFileSize - ZFpos; + + while( cnt > 0 ) { + unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS; + unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS; + unsigned n = cnt; + + if (ZFpos + n > endchunk) + n = endchunk - ZFpos; + memcpy( buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n ); + cnt -= n; + buf += n; + done += n; + ZFpos += n; + + if (ZFpos == endchunk) { + Mfree( ZFile[chunk] ); + ZFile[chunk] = NULL; + } + } + + return( done ); +} + + +static int klseek( int fd, int where, int whence ) +{ + unsigned oldpos, oldchunk, newchunk; + + if (!ZFileSize) + return( ll_lseek( fd, where, whence ) ); + + oldpos = ZFpos; + switch( whence ) { + case SEEK_SET: + ZFpos = where; + break; + case SEEK_CUR: + ZFpos += where; + break; + case SEEK_END: + ZFpos = ZFileSize + where; + break; + default: + return( -1 ); + } + if (ZFpos < 0) { + ZFpos = 0; + return( -1 ); + } + else if (ZFpos > ZFileSize) { + ZFpos = ZFileSize; + return( -1 ); + } + + /* free memory of skipped-over data */ + oldchunk = oldpos >> ZFILE_CHUNK_BITS; + newchunk = ZFpos >> ZFILE_CHUNK_BITS; + while( oldchunk < newchunk ) { + if (ZFile[oldchunk]) { + Mfree( ZFile[oldchunk] ); + ZFile[oldchunk] = NULL; + } + ++oldchunk; + } + + return( ZFpos ); +} + + +static void free_zfile( void ) +{ + int i; + + for( i = 0; i < ZFILE_N_CHUNKS; ++i ) + if (ZFile[i]) Mfree( ZFile[i] ); +} + +static int kclose( int fd ) +{ + if (ZFileSize) { + free_zfile(); + return( 0 ); + } + else + return( ll_close( fd ) ); +} + + + +#endif /* ZKERNEL */ diff -u --recursive --new-file v2.1.35/linux/arch/m68k/config.in linux/arch/m68k/config.in --- v2.1.35/linux/arch/m68k/config.in Mon Apr 7 11:35:29 1997 +++ linux/arch/m68k/config.in Thu Apr 17 13:20:42 1997 @@ -58,6 +58,9 @@ bool 'Amiga ECS chipset support' CONFIG_AMIFB_ECS bool 'Amiga AGA chipset support' CONFIG_AMIFB_AGA bool 'Amiga Cybervision support' CONFIG_FB_CYBER + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3 + fi # bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP # if [ "$CONFIG_AMIGA_GSP" = "y" ]; then # bool 'DMI Resolver support' CONFIG_GSP_RESOLVER @@ -82,15 +85,15 @@ dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE fi if [ "$CONFIG_AMIGA" = "y" ]; then -tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM + tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM fi if [ "$CONFIG_ATARI" = "y" ]; then -tristate 'Atari ACSI support' CONFIG_ATARI_ACSI -if [ "$CONFIG_ATARI_ACSI" != "n" ]; then -comment 'Some devices (e.g. CD jukebox) support multiple LUNs' -bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN -dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI -fi + tristate 'Atari ACSI support' CONFIG_ATARI_ACSI + if [ "$CONFIG_ATARI_ACSI" != "n" ]; then + comment 'Some devices (e.g. CD jukebox) support multiple LUNs' + bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN + dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI + fi fi comment 'Additional Block Devices' @@ -138,17 +141,23 @@ comment 'SCSI low-level drivers' if [ "$CONFIG_AMIGA" = "y" ]; then -tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI -tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI -tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI -bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI -bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI -bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI -bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI + tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI + tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI + tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI + bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI + bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI + bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI + bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI + bool 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'A4000T SCSI support' CONFIG_A4000T_SCSI + bool 'A4091 SCSI support' CONFIG_A4091_SCSI + bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI + fi fi if [ "$CONFIG_ATARI" = "y" ]; then -dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI -bool 'Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY + dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI + bool 'Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY fi #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI endmenu @@ -202,6 +211,7 @@ define_bool CONFIG_VT y define_bool CONFIG_VT_CONSOLE y +define_bool CONFIG_FB_CONSOLE y tristate 'Parallel printer support' CONFIG_PRINTER if [ "$CONFIG_AMIGA" = "y" ]; then @@ -214,13 +224,26 @@ if [ "$CONFIG_ATARI" = "y" ]; then tristate 'Atari MFP serial support' CONFIG_ATARI_MFPSER tristate 'Atari SCC serial support' CONFIG_ATARI_SCC + if [ "$CONFIG_ATARI_SCC" = "y" -o "$CONFIG_ATARI_SCC" = "m" ]; then + bool 'Atari SCC serial DMA support' CONFIG_ATARI_SCC_DMA + fi tristate 'Atari MIDI serial support' CONFIG_ATARI_MIDI + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'Atari DSP56k support (EXPERIMENTAL)' CONFIG_ATARI_DSP56K + fi fi if [ "$CONFIG_AMIGA" = "y" ]; then tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL - bool 'GVP IO-Extender support' CONFIG_GVPIOEXT + tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT + dep_tristate 'GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT + dep_tristate 'GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY fi +if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \ + "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \ + "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" ]; then + bool 'Serial console support' CONFIG_SERIAL_CONSOLE +fi bool 'Support for user serial device modules' CONFIG_USERIAL bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then @@ -228,6 +251,9 @@ bool ' Software Watchdog' CONFIG_SOFT_WATCHDOG fi bool 'Support for user misc device modules' CONFIG_UMISC +if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" ]; then + define_bool CONFIG_ABSTRACT_CONSOLE y +fi endmenu mainmenu_option next_comment @@ -247,4 +273,5 @@ if [ "$CONFIG_PROFILE" = "y" ]; then int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 fi +bool 'Remote debugging support' CONFIG_KGDB endmenu diff -u --recursive --new-file v2.1.35/linux/arch/m68k/console/fbcon.c linux/arch/m68k/console/fbcon.c --- v2.1.35/linux/arch/m68k/console/fbcon.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/console/fbcon.c Thu Apr 17 13:20:42 1997 @@ -61,7 +61,7 @@ #endif #ifdef CONFIG_FB_CYBER #include "../amiga/s3blit.h" -#endif /* CONFIG_FB_CYBER */ +#endif #include #include #include @@ -70,7 +70,7 @@ #include #include "../../../drivers/char/vt_kern.h" /* vt_cons and vc_resize_con() */ - +#include "../../../drivers/char/console_struct.h" /* Import console_blanked from console.c */ @@ -95,6 +95,7 @@ #undef CONFIG_FBCON_24PACKED #undef CONFIG_FBCON_32PACKED #undef CONFIG_FBCON_CYBER +#undef CONFIG_FBCON_RETINAZ3 /* Monochrome is default */ @@ -117,7 +118,18 @@ #ifndef CONFIG_FBCON_CYBER #define CONFIG_FBCON_CYBER #endif -#endif /* CONFIG_FB_CYBER */ +#endif + +/* RetinaZ3 Graphics Board */ + +#ifdef CONFIG_FB_RETINAZ3 +#ifndef CONFIG_FBCON_RETINAZ3 +#define CONFIG_FBCON_RETINAZ3 +#endif +#ifndef CONFIG_FBCON_8PACKED +#define CONFIG_FBCON_8PACKED +#endif +#endif #endif /* CONFIG_AMIGA */ @@ -151,9 +163,9 @@ #undef CONFIG_FBCON_IPLAN2 #endif -#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_8PACKED) || \ - defined(CONFIG_FBCON_16PACKED) || defined(CONFIG_FBCON_24PACKED) || \ - defined(CONFIG_FBCON_32PACKED) +#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_RETINAZ3) || \ + defined(CONFIG_FBCON_8PACKED) || defined(CONFIG_FBCON_16PACKED) || \ + defined(CONFIG_FBCON_24PACKED) || defined(CONFIG_FBCON_32PACKED) #define CONFIG_FBCON_PACKED #else #undef CONFIG_FBCON_PACKED @@ -224,21 +236,24 @@ * Interface used by the world */ -static u_long fbcon_startup(u_long kmem_start, char **display_desc); +static u_long fbcon_startup(u_long kmem_start, const char **display_desc); static void fbcon_init(struct vc_data *conp); static int fbcon_deinit(struct vc_data *conp); static int fbcon_changevar(int con); static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height, int width); -static int fbcon_putc(struct vc_data *conp, int c, int y, int x); -static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y, - int x); +static int fbcon_putc(struct vc_data *conp, int c, int yy, int xx); +static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int yy, + int xx); static int fbcon_cursor(struct vc_data *conp, int mode); static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count); static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx, int height, int width); static int fbcon_switch(struct vc_data *conp); static int fbcon_blank(int blank); +static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data); +static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data); +static int fbcon_set_palette(struct vc_data *conp, unsigned char *table); /* @@ -264,14 +279,22 @@ u_long val2, u_long val3, u_long val4); static __inline__ void memmove_8p_col(void *d, void *s, int h, int bpr); static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2); -static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr); +static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, + int bpr); static __inline__ void memset_even_2p(void *d, size_t count, u_long val); static __inline__ void memmove_2p_col(void *d, void *s, int h, int bpr); static __inline__ u_short expand2w(u_char c); static __inline__ u_long expand2l(u_char c); static __inline__ u_short dup2w(u_char c); -static __inline__ int real_y(struct display *p, int y); +static __inline__ int real_y(struct display *p, int yy); static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp); +static __inline__ void updatescrollmode(struct display *p); +static __inline__ void ywrap_up(int unit, struct display *p, int count); +static __inline__ void ywrap_down(int unit, struct display *p, int count); +static __inline__ void ypan_up(int unit, struct vc_data *conp, + struct display *p, int count); +static __inline__ void ypan_down(int unit, struct vc_data *conp, + struct display *p, int count); static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx, int height, int width, u_int y_break); @@ -285,11 +308,11 @@ int height, int width); static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_mono(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_mono(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_mono(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_mono(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_mono(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_MONO */ @@ -302,11 +325,11 @@ int height, int width); static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_ilbm(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_ilbm(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_ILBM */ @@ -319,11 +342,11 @@ int height, int width); static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_plan(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_plan(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_plan(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_plan(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_plan(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_PLANES */ @@ -336,11 +359,11 @@ int height, int width); static void clear_2_plane(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_2_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_2_plane(struct display *display, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_2_plane(struct display *display, int xx, int yy); #endif /* CONFIG_FBCON_2PLANE */ @@ -353,11 +376,11 @@ int height, int width); static void clear_4_plane(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_4_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_4_plane(struct display *p, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_4_plane(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_4PLANE */ @@ -370,11 +393,11 @@ int height, int width); static void clear_8_plane(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_8_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_8_plane(struct display *display, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_8_plane(struct display *display, int xx, int yy); #endif /* CONFIG_FBCON_8PLANE */ @@ -387,11 +410,11 @@ int height, int width); static void clear_8_packed(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_8_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_8_packed(struct display *p, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_8_packed(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_8PACKED */ @@ -405,10 +428,10 @@ static void clear_16_packed(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); static void putc_16_packed(struct vc_data *conp, struct display *p, int c, - int y, int x); + int yy, int xx); static void putcs_16_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_16_packed(struct display *p, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_16_packed(struct display *p, int xx, int yy); #endif */ CONFIG_FBCON_8PACKED */ @@ -421,22 +444,38 @@ int height, int width); static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_cyber(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_cyber(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_cyber(struct display *p, int xx, int yy); extern void Cyber_WaitQueue(u_short fifo); extern void Cyber_WaitBlit(void); extern void Cyber_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty, u_short width, u_short height, u_short mode); -extern void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height, +extern void Cyber_RectFill(u_short xx, u_short yy, u_short width, u_short height, u_short mode, u_short color); -extern void Cyber_MoveCursor(u_short x, u_short y); +extern void Cyber_MoveCursor(u_short xx, u_short yy); #endif /* CONFIG_FBCON_CYBER */ +#ifdef CONFIG_FBCON_RETINAZ3 +static void clear_retz3(struct vc_data *conp, struct display *p, int + sy, int sx, int height, int width); +static void bmove_retz3(struct display *p, int sy, int sx, int dy, int dx, + int height, int width); +extern void retz3_bitblt(struct fb_var_screeninfo *scr, + unsigned short srcx, unsigned short srcy, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask); +static void putc_retz3(struct vc_data *conp, struct display *p, int c, + int yy, int xx); +static void putcs_retz3(struct vc_data *conp, struct display *p, const + char *s, int count, int yy, int xx); +static void rev_char_retz3(struct display *p, int xx, int yy); +#endif /* * `switch' for the Low Level Operations @@ -447,10 +486,10 @@ int width); void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); - void (*putc)(struct vc_data *conp, struct display *p, int c, int y, int x); + void (*putc)(struct vc_data *conp, struct display *p, int c, int yy, int xx); void (*putcs)(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); - void (*rev_char)(struct display *p, int x, int y); + int count, int yy, int xx); + void (*rev_char)(struct display *p, int xx, int yy); }; @@ -509,8 +548,15 @@ }; #endif /* CONFIG_FBCON_CYBER */ +#ifdef CONFIG_FBCON_RETINAZ3 +static struct display_switch dispsw_retz3 = { + bmove_retz3, clear_retz3, putc_retz3, + putcs_retz3, rev_char_retz3 +}; +#endif + -static u_long fbcon_startup(u_long kmem_start, char **display_desc) +static u_long fbcon_startup(u_long kmem_start, const char **display_desc) { int irqres = 0; @@ -566,6 +612,19 @@ } +static __inline__ void updatescrollmode(struct display *p) +{ + if (divides(p->ywrapstep, p->fontheight) && + divides(p->fontheight, p->var.yres_virtual)) + p->scrollmode = SCROLL_YWRAP; + else if (divides(p->ypanstep, p->fontheight) && + p->var.yres_virtual >= p->var.yres+p->fontheight) + p->scrollmode = SCROLL_YPAN; + else + p->scrollmode = SCROLL_YMOVE; +} + + static void fbcon_setup(int con, int setcol, int init) { struct display *p = &disp[con]; @@ -579,16 +638,12 @@ &p->fontdata) || p->fontwidth != 8) getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth, &p->fontheight, &p->fontdata); - if (p->fontwidth != 8) - panic("fbcon_setup: No support for fontwidth != 8"); - - if (divides(p->ywrapstep, p->fontheight) && divides(p->fontheight, p->var.yres_virtual)) - p->scrollmode = SCROLL_YWRAP; - else if (divides(p->ypanstep, p->fontheight) && - p->var.yres_virtual >= p->var.yres+p->fontheight) - p->scrollmode = SCROLL_YPAN; - else - p->scrollmode = SCROLL_YMOVE; + if (p->fontwidth != 8) { + /* ++Geert: changed from panic() to `correct and continue' */ + printk("fbcon_setup: No support for fontwidth != 8"); + p->fontwidth = 8; + } + updatescrollmode(p); nr_cols = p->var.xres/p->fontwidth; nr_rows = p->var.yres/p->fontheight; @@ -638,7 +693,8 @@ if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux != 2) { if (p->line_length) { p->next_line = p->line_length*p->var.bits_per_pixel; - p->next_plane = p->line_length; + p->next_plane = p->line_length +; } else { p->next_line = p->type_aux; p->next_plane = p->type_aux/p->var.bits_per_pixel; @@ -658,13 +714,18 @@ #endif /* CONFIG_FBCON_PLANES */ #ifdef CONFIG_FBCON_PACKED if (p->type == FB_TYPE_PACKED_PIXELS) { - p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3; + p->next_line = (p->var.xres_virtual*p->var.bits_per_pixel)>>3; p->next_plane = 0; #ifdef CONFIG_FBCON_CYBER if (p->var.accel == FB_ACCEL_CYBERVISION) p->dispsw = &dispsw_cyber; else -#endif /* CONFIG_FBCON_CYBER */ +#endif +#ifdef CONFIG_FBCON_RETINAZ3 + if (p->var.accel == FB_ACCEL_RETINAZ3) + p->dispsw = &dispsw_retz3; + else +#endif #ifdef CONFIG_FBCON_8PACKED if (p->var.bits_per_pixel == 8) p->dispsw = &dispsw_8_packed; @@ -1399,12 +1460,12 @@ * restriction is simplicity & efficiency at the moment. */ -static __inline__ int real_y(struct display *p, int y) +static __inline__ int real_y(struct display *p, int yy) { int rows = p->vrows; - y += p->yscroll; - return(y < rows ? y : y-rows); + yy += p->yscroll; + return(yy < rows ? yy : yy-rows); } @@ -1436,7 +1497,7 @@ } -static int fbcon_putc(struct vc_data *conp, int c, int y, int x) +static int fbcon_putc(struct vc_data *conp, int c, int yy, int xx) { int unit = conp->vc_num; struct display *p = &disp[unit]; @@ -1444,17 +1505,17 @@ if (!p->can_soft_blank && console_blanked) return(0); - if ((p->cursor_x == x) && (p->cursor_y == y)) + if ((p->cursor_x == xx) && (p->cursor_y == yy)) CURSOR_UNDRAWN(); - p->dispsw->putc(conp, p, c, real_y(p, y), x); + p->dispsw->putc(conp, p, c, real_y(p, yy), xx); return(0); } -static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y, - int x) +static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int yy, + int xx) { int unit = conp->vc_num; struct display *p = &disp[unit]; @@ -1462,10 +1523,10 @@ if (!p->can_soft_blank && console_blanked) return(0); - if ((p->cursor_y == y) && (x <= p->cursor_x) && (p->cursor_x < x+count)) + if ((p->cursor_y == yy) && (xx <= p->cursor_x) && (p->cursor_x < xx+count)) CURSOR_UNDRAWN(); - p->dispsw->putcs(conp, p, s, count, real_y(p, y), x); + p->dispsw->putcs(conp, p, s, count, real_y(p, yy), xx); return(0); } @@ -1520,6 +1581,62 @@ } +static __inline__ void ywrap_up(int unit, struct display *p, int count) +{ + p->yscroll += count; + if (p->yscroll >= p->vrows) /* Deal with wrap */ + p->yscroll -= p->vrows; + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode |= FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + +static __inline__ void ywrap_down(int unit, struct display *p, int count) +{ + p->yscroll -= count; + if (p->yscroll < 0) /* Deal with wrap */ + p->yscroll += p->vrows; + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode |= FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + +static __inline__ void ypan_up(int unit, struct vc_data *conp, + struct display *p, int count) +{ + p->yscroll += count; + if (p->yscroll+conp->vc_rows > p->vrows) { + p->dispsw->bmove(p, p->yscroll, 0, 0, 0, conp->vc_rows-count, + conp->vc_cols); + p->yscroll = 0; + } + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode &= ~FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + +static __inline__ void ypan_down(int unit, struct vc_data *conp, + struct display *p, int count) +{ + p->yscroll -= count; + if (p->yscroll < 0) { + p->yscroll = p->vrows-conp->vc_rows; + p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, conp->vc_rows-count, + conp->vc_cols); + } + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode &= ~FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count) { int unit = conp->vc_num; @@ -1536,84 +1653,98 @@ switch (dir) { case SM_UP: - if (t == 0 && b == conp->vc_rows && - vt_cons[unit]->vc_mode == KD_TEXT) { - if (count > conp->vc_rows) /* Maximum realistic size */ - count = conp->vc_rows; - switch (p->scrollmode) { - case SCROLL_YWRAP: - p->yscroll += count; - if (p->yscroll >= p->vrows) /* Deal with wrap */ - p->yscroll -= p->vrows; - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode |= FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YPAN: - p->yscroll += count; - if (p->yscroll+conp->vc_rows > p->vrows) { - p->dispsw->bmove(p, p->yscroll, 0, 0, 0, b-count, - conp->vc_cols); - p->yscroll = 0; - } - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode &= ~FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YMOVE: - p->dispsw->bmove(p, count, 0, 0, 0, b-count, conp->vc_cols); - break; - } - } else - fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols); - fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + if (count > conp->vc_rows) /* Maximum realistic size */ + count = conp->vc_rows; + if (vt_cons[unit]->vc_mode == KD_TEXT) + switch (p->scrollmode) { + case SCROLL_YWRAP: + if (b-t-count > 3*conp->vc_rows>>2) { + if (t > 0) + fbcon_bmove(conp, 0, 0, count, 0, t, conp->vc_cols); + ywrap_up(unit, p, count); + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b-count, 0, b, 0, conp->vc_rows-b, + conp->vc_cols); + } else + fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + break; + + case SCROLL_YPAN: + if (b-t-count > 3*conp->vc_rows>>2) { + if (t > 0) + fbcon_bmove(conp, 0, 0, count, 0, t, conp->vc_cols); + ypan_up(unit, conp, p, count); + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b-count, 0, b, 0, conp->vc_rows-b, + conp->vc_cols); + } else + fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + break; + + case SCROLL_YMOVE: + p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count, + conp->vc_cols); + p->dispsw->clear(conp, p, b-count, 0, count, conp->vc_cols); + break; + } + else { + fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols); + fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + } break; case SM_DOWN: - if (t == 0 && b == conp->vc_rows && - vt_cons[unit]->vc_mode == KD_TEXT) { - if (count > conp->vc_rows) /* Maximum realistic size */ - count = conp->vc_rows; - switch (p->scrollmode) { - case SCROLL_YWRAP: - p->yscroll -= count; - if (p->yscroll < 0) /* Deal with wrap */ - p->yscroll += p->vrows; - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode |= FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YPAN: - p->yscroll -= count; - if (p->yscroll < 0) { - p->yscroll = p->vrows-conp->vc_rows; - p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, b-count, - conp->vc_cols); - } - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode &= ~FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YMOVE: - p->dispsw->bmove(p, 0, 0, count, 0, b-count, conp->vc_cols); - break; - } - } else - fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols); - - /* Fixed bmove() should end Arno's frustration with copying? - * Confucius says: - * Man who copies in wrong direction, end up with trashed data - */ - fbcon_clear(conp, t, 0, count, conp->vc_cols); + if (count > conp->vc_rows) /* Maximum realistic size */ + count = conp->vc_rows; + if (vt_cons[unit]->vc_mode == KD_TEXT) + switch (p->scrollmode) { + case SCROLL_YWRAP: + if (b-t-count > 3*conp->vc_rows>>2) { + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b, 0, b-count, 0, conp->vc_rows-b, + conp->vc_cols); + ywrap_down(unit, p, count); + if (t > 0) + fbcon_bmove(conp, count, 0, 0, 0, t, conp->vc_cols); + } else + fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, t, 0, count, conp->vc_cols); + break; + + case SCROLL_YPAN: + if (b-t-count > 3*conp->vc_rows>>2) { + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b, 0, b-count, 0, conp->vc_rows-b, + conp->vc_cols); + ypan_down(unit, conp, p, count); + if (t > 0) + fbcon_bmove(conp, count, 0, 0, 0, t, conp->vc_cols); + } else + fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, t, 0, count, conp->vc_cols); + break; + + case SCROLL_YMOVE: + p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count, + conp->vc_cols); + p->dispsw->clear(conp, p, t, 0, count, conp->vc_cols); + break; + } + else { + /* + * Fixed bmove() should end Arno's frustration with copying? + * Confucius says: + * Man who copies in wrong direction, end up with trashed data + */ + fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols); + fbcon_clear(conp, t, 0, count, conp->vc_cols); + } break; case SM_LEFT: @@ -1832,14 +1963,7 @@ /* Adjust the virtual screen-size to fontheight*rows */ p->var.yres_virtual = (p->var.yres/h)*h; p->vrows = p->var.yres_virtual/h; - if (divides(p->ywrapstep, p->fontheight)) - p->scrollmode = SCROLL_YWRAP; - else if (divides(p->ypanstep, p->fontheight) && - p->var.yres_virtual >= p->var.yres+p->fontheight) - p->scrollmode = SCROLL_YPAN; - else - p->scrollmode = SCROLL_YMOVE; - + updatescrollmode(p); vc_resize_con( p->var.yres/h, p->var.xres/w, unit ); } else if (unit == fg_console) @@ -1854,6 +1978,38 @@ return( 0 ); } +static unsigned short palette_red[16]; +static unsigned short palette_green[16]; +static unsigned short palette_blue[16]; + +static struct fb_cmap palette_cmap = { + 0, 16, palette_red, palette_green, palette_blue, NULL +}; + +static int fbcon_set_palette(struct vc_data *conp, unsigned char *table) +{ + int unit = conp->vc_num; + struct display *p = &disp[unit]; + int i, j, k; + u_char val; + + if (!conp->vc_can_do_color || (!p->can_soft_blank && console_blanked)) + return(-EINVAL); + for (i = j = 0; i < 16; i++) { + k = table[i]; + val = conp->vc_palette[j++]; + palette_red[k] = (val<<8)|val; + val = conp->vc_palette[j++]; + palette_green[k] = (val<<8)|val; + val = conp->vc_palette[j++]; + palette_blue[k] = (val<<8)|val; + } + palette_cmap.len = 1<var.bits_per_pixel; + if (palette_cmap.len > 16) + palette_cmap.len = 16; + return(fb_info->setcmap(&palette_cmap, unit)); +} + /* ====================================================================== */ @@ -1882,8 +2038,8 @@ u_char *src, *dest; u_int rows; - if (sx == 0 && sy == 0 && width == p->next_line) { - src = p->screen_base; + if (sx == 0 && dx == 0 && width == p->next_line) { + src = p->screen_base+sy*p->fontheight*width; dest = p->screen_base+dy*p->fontheight*width; mymemmove(dest, src, height*p->fontheight*width); } else if (dy <= sy) { @@ -1928,28 +2084,28 @@ } -static void putc_mono(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_mono(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *cdat; - u_int rows, bold, reverse, underline; + u_int rows, bold, revs, underl; u_char d; c &= 0xff; - dest = p->screen_base+y*p->fontheight*p->next_line+x; + dest = p->screen_base + yy*p->fontheight*p->next_line + xx; cdat = p->fontdata+c*p->fontheight; bold = attr_bold(p,conp); - reverse = attr_reverse(p,conp); - underline = attr_underline(p,conp); + revs = attr_reverse(p,conp); + underl = attr_underline(p,conp); for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; else if (bold) d |= d>>1; - if (reverse) + if (revs) d = ~d; *dest = d; } @@ -1957,16 +2113,16 @@ static void putcs_mono(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest, *dest0, *cdat; - u_int rows, bold, reverse, underline; + u_int rows, bold, revs, underl; u_char c, d; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; bold = attr_bold(p,conp); - reverse = attr_reverse(p,conp); - underline = attr_underline(p,conp); + revs = attr_reverse(p,conp); + underl = attr_underline(p,conp); while (count--) { c = *s++; @@ -1974,11 +2130,11 @@ cdat = p->fontdata+c*p->fontheight; for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; else if (bold) d |= d>>1; - if (reverse) + if (revs) d = ~d; *dest = d; } @@ -1986,12 +2142,12 @@ } -static void rev_char_mono(struct display *p, int x, int y) +static void rev_char_mono(struct display *p, int xx, int yy) { u_char *dest; u_int rows; - dest = p->screen_base+y*p->fontheight*p->next_line+x; + dest = p->screen_base + yy*p->fontheight*p->next_line + xx; for (rows = p->fontheight; rows--; dest += p->next_line) *dest = ~*dest; } @@ -2017,8 +2173,9 @@ static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx, int height, int width) { - if (sx == 0 && sy == 0 && width == p->next_plane) - mymemmove(p->screen_base+dy*p->fontheight*p->next_line, p->screen_base, + if (sx == 0 && dx == 0 && width == p->next_plane) + mymemmove(p->screen_base+dy*p->fontheight*p->next_line, + p->screen_base+sy*p->fontheight*p->next_line, height*p->fontheight*p->next_line); else { u_char *src, *dest; @@ -2068,8 +2225,8 @@ } -static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *cdat; u_int rows, i; @@ -2078,7 +2235,7 @@ c &= 0xff; - dest = p->screen_base+y*p->fontheight*p->next_line+x; + dest = p->screen_base + yy*p->fontheight*p->next_line + xx; cdat = p->fontdata+c*p->fontheight; fg0 = attr_fgcol(p,conp); bg0 = attr_bgcol(p,conp); @@ -2114,14 +2271,14 @@ * address, to reduce the number of expensive Chip RAM * accesses. * - * Experiments on my A4000/040 revealed that this makes a console switch on a - * 640x400 screen with 256 colors about 3 times faster. + * Experiments on my A4000/040 revealed that this makes a console + * switch on a 640x400 screen with 256 colors about 3 times faster. * * Geert */ static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4; u_int rows, i; @@ -2129,15 +2286,15 @@ u_long d; int fg0, bg0, fg, bg; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; fg0 = attr_fgcol(p,conp); bg0 = attr_bgcol(p,conp); while (count--) - if (x&3 || count < 3) { /* Slow version */ + if (xx & 3 || count < 3) { /* Slow version */ c1 = *s++; dest = dest0++; - x++; + xx++; cdat1 = p->fontdata+c1*p->fontheight; for (rows = p->fontheight; rows--;) { @@ -2191,19 +2348,19 @@ } s += 4; dest0 += 4; - x += 4; + xx += 4; count -= 3; } } -static void rev_char_ilbm(struct display *p, int x, int y) +static void rev_char_ilbm(struct display *p, int xx, int yy) { u_char *dest, *dest0; u_int rows, i; int mask; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; mask = p->fgcol ^ p->bgcol; /* @@ -2239,8 +2396,8 @@ u_char *src, *dest, *src0, *dest0; u_int i, rows; - if (sx == 0 && sy == 0 && width == p->next_line) { - src = p->screen_base; + if (sx == 0 && dx == 0 && width == p->next_line) { + src = p->screen_base+sy*p->fontheight*width; dest = p->screen_base+dy*p->fontheight*width; for (i = p->var.bits_per_pixel; i--;) { mymemmove(dest, src, height*p->fontheight*width); @@ -2301,8 +2458,8 @@ } -static void putc_plan(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_plan(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *dest0, *cdat, *cdat0; u_int rows, i; @@ -2311,7 +2468,7 @@ c &= 0xff; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; cdat0 = p->fontdata+c*p->fontheight; fg = attr_fgcol(p,conp); bg = attr_bgcol(p,conp); @@ -2344,7 +2501,7 @@ */ static void putcs_plan(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest, *dest0, *dest1; u_char *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40; @@ -2353,15 +2510,15 @@ u_long d; int fg0, bg0, fg, bg; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; fg0 = attr_fgcol(p,conp); bg0 = attr_bgcol(p,conp); while (count--) - if (x&3 || count < 3) { /* Slow version */ + if (xx & 3 || count < 3) { /* Slow version */ c1 = *s++; dest1 = dest0++; - x++; + xx++; cdat10 = p->fontdata+c1*p->fontheight; fg = fg0; @@ -2424,19 +2581,19 @@ } s += 4; dest0 += 4; - x += 4; + xx += 4; count -= 3; } } -static void rev_char_plan(struct display *p, int x, int y) +static void rev_char_plan(struct display *p, int xx, int yy) { u_char *dest, *dest0; u_int rows, i; int mask; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; mask = p->fgcol ^ p->bgcol; /* @@ -2499,8 +2656,8 @@ * done with memmove() */ mymemmove(p->screen_base + dy * p->next_line * p->fontheight, - p->screen_base + sy * p->next_line * p->fontheight, - p->next_line * height * p->fontheight); + p->screen_base + sy * p->next_line * p->fontheight, + p->next_line * height * p->fontheight); } else { int rows, cols; u_char *src; @@ -2607,8 +2764,8 @@ int bytes = p->next_line; int lines = height * p->fontheight; ulong size; - u_long cval; - u_short pcval; + u_long cval; + u_short pcval; cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp))); @@ -2650,43 +2807,45 @@ } -static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_2_plane(struct vc_data *conp, struct display *p, int + c, int yy, int xx) { - u_char *dest; - u_char *cdat; - int rows; - int bytes = p->next_line; - ulong eorx, fgx, bgx, fdx; + u_char *dest; + u_char *cdat; + int rows; + int bytes = p->next_line; + ulong eorx, fgx, bgx, fdx; c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1); - cdat = p->fontdata + (c * p->fontheight); + dest = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*4 + (xx & 1); + cdat = p->fontdata + (c * p->fontheight); fgx = expand2w(COLOR_2P(attr_fgcol(p,conp))); bgx = expand2w(COLOR_2P(attr_bgcol(p,conp))); eorx = fgx ^ bgx; - for(rows = p->fontheight ; rows-- ; dest += bytes) { + for(rows = p->fontheight ; rows-- ; dest += bytes) { fdx = dup2w(*cdat++); __asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } } static void putcs_2_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *dest, *dest0; - u_char *cdat, c; - int rows; - int bytes; - ulong eorx, fgx, bgx, fdx; - - bytes = p->next_line; - dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1); + u_char *cdat, c; + int rows; + int bytes; + ulong eorx, fgx, bgx, fdx; + + bytes = p->next_line; + dest0 = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*4 + (xx & 1); fgx = expand2w(COLOR_2P(attr_fgcol(p,conp))); bgx = expand2w(COLOR_2P(attr_bgcol(p,conp))); eorx = fgx ^ bgx; @@ -2699,32 +2858,33 @@ for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) { fdx = dup2w(*cdat++); __asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } INC_2P(dest0); } } -static void rev_char_2_plane(struct display *p, int x, int y) +static void rev_char_2_plane(struct display *p, int xx, int yy) { - u_char *dest; - int j; - int bytes; + u_char *dest; + int j; + int bytes; - dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*4 + (x & 1); - j = p->fontheight; - bytes = p->next_line; - while (j--) - { - /* This should really obey the individual character's - * background and foreground colors instead of simply - * inverting. - */ - dest[0] = ~dest[0]; - dest[2] = ~dest[2]; - dest += bytes; - } + dest = p->screen_base + yy * p->fontheight * p->next_line + + (xx >> 1)*4 + (xx & 1); + j = p->fontheight; + bytes = p->next_line; + while (j--) + { + /* This should really obey the individual character's + * background and foreground colors instead of simply + * inverting. + */ + dest[0] = ~dest[0]; + dest[2] = ~dest[2]; + dest += bytes; + } } #endif /* CONFIG_FBCON_2PLANE */ @@ -2763,8 +2923,8 @@ * done with memmove() */ mymemmove(p->screen_base + dy * p->next_line * p->fontheight, - p->screen_base + sy * p->next_line * p->fontheight, - p->next_line * height * p->fontheight); + p->screen_base + sy * p->next_line * p->fontheight, + p->next_line * height * p->fontheight); } else { int rows, cols; u_char *src; @@ -2871,9 +3031,9 @@ int bytes = p->next_line; int lines = height * p->fontheight; ulong size; - u_long cval1, cval2, pcval; + u_long cval1, cval2, pcval; - expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2); + expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2); if (sx == 0 && width == bytes/4) { @@ -2913,43 +3073,45 @@ } -static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_4_plane(struct vc_data *conp, struct display *p, int + c, int yy, int xx) { u_char *dest; - u_char *cdat; - int rows; - int bytes = p->next_line; - ulong eorx, fgx, bgx, fdx; + u_char *cdat; + int rows; + int bytes = p->next_line; + ulong eorx, fgx, bgx, fdx; c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1); - cdat = p->fontdata + (c * p->fontheight); + dest = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*8 + (xx & 1); + cdat = p->fontdata + (c * p->fontheight); fgx = expand4l(attr_fgcol(p,conp)); bgx = expand4l(attr_bgcol(p,conp)); eorx = fgx ^ bgx; - for(rows = p->fontheight ; rows-- ; dest += bytes) { + for(rows = p->fontheight ; rows-- ; dest += bytes) { fdx = dup4l(*cdat++); __asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } } static void putcs_4_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *dest, *dest0; - u_char *cdat, c; - int rows; - int bytes; - ulong eorx, fgx, bgx, fdx; - - bytes = p->next_line; - dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1); + u_char *cdat, c; + int rows; + int bytes; + ulong eorx, fgx, bgx, fdx; + + bytes = p->next_line; + dest0 = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*8 + (xx & 1); fgx = expand4l(attr_fgcol(p,conp)); bgx = expand4l(attr_bgcol(p,conp)); eorx = fgx ^ bgx; @@ -2969,20 +3131,21 @@ for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) { fdx = dup4l(*cdat++); __asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } INC_4P(dest0); } } -static void rev_char_4_plane(struct display *p, int x, int y) +static void rev_char_4_plane(struct display *p, int xx, int yy) { u_char *dest; int j; int bytes; - dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*8 + (x & 1); + dest = p->screen_base + yy * p->fontheight * p->next_line + + (xx >> 1)*8 + (xx & 1); j = p->fontheight; bytes = p->next_line; @@ -3150,15 +3313,16 @@ int bytes = p->next_line; int lines = height * p->fontheight; ulong size; - u_long cval1, cval2, cval3, cval4, pcval1, pcval2; + u_long cval1, cval2, cval3, cval4, pcval1, pcval2; - expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4); + expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4); if (sx == 0 && width == bytes/8) { offset = sy * bytes * p->fontheight; size = lines * bytes; - memset_even_8p(p->screen_base+offset, size, cval1, cval2, cval3, cval4); + memset_even_8p(p->screen_base+offset, size, cval1, + cval2, cval3, cval4); } else { @@ -3193,48 +3357,50 @@ } -static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest; - u_char *cdat; - int rows; - int bytes = p->next_line; - ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; + u_char *cdat; + int rows; + int bytes = p->next_line; + ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1); - cdat = p->fontdata + (c * p->fontheight); + dest = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*16 + (xx & 1); + cdat = p->fontdata + (c * p->fontheight); expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2); expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2); eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2; - for(rows = p->fontheight ; rows-- ; dest += bytes) { + for(rows = p->fontheight ; rows-- ; dest += bytes) { fdx = dup4l(*cdat++); __asm__ __volatile__ ("movepl %1,%0@(0)\n\t" - "movepl %2,%0@(8)" - : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx1) ^ bgx1), - "d" ((fdx & eorx2) ^ bgx2) + "movepl %2,%0@(8)" + : /* no outputs */ + : "a" (dest), "d" ((fdx & eorx1) ^ bgx1), + "d" ((fdx & eorx2) ^ bgx2) ); } } static void putcs_8_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *dest, *dest0; - u_char *cdat, c; - int rows; - int bytes; - ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; - - bytes = p->next_line; - dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1); + u_char *cdat, c; + int rows; + int bytes; + ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; + + bytes = p->next_line; + dest0 = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*16 + (xx & 1); expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2); expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2); @@ -3267,30 +3433,31 @@ } -static void rev_char_8_plane(struct display *p, int x, int y) +static void rev_char_8_plane(struct display *p, int xx, int yy) { - u_char *dest; - int j; - int bytes; - - dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*16 + (x & 1); - j = p->fontheight; - bytes = p->next_line; + u_char *dest; + int j; + int bytes; - while (j--) - { - /* This should really obey the individual character's - * background and foreground colors instead of simply - * inverting. For 8 plane mode, only the lower 4 bits of the - * color are inverted, because only that color registers have - * been set up. - */ - dest[0] = ~dest[0]; - dest[2] = ~dest[2]; - dest[4] = ~dest[4]; - dest[6] = ~dest[6]; - dest += bytes; - } + dest = p->screen_base + yy * p->fontheight * p->next_line + + (xx >> 1)*16 + (xx & 1); + j = p->fontheight; + bytes = p->next_line; + + while (j--) + { + /* This should really obey the individual character's + * background and foreground colors instead of simply + * inverting. For 8 plane mode, only the lower 4 bits of the + * color are inverted, because only that color registers have + * been set up. + */ + dest[0] = ~dest[0]; + dest[2] = ~dest[2]; + dest[4] = ~dest[4]; + dest[6] = ~dest[6]; + dest += bytes; + } } #endif /* CONFIG_FBCON_8PLANE */ @@ -3378,8 +3545,8 @@ } -static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_8_packed(struct vc_data *conp, struct display *p, int c, + int yy, int xx) { u_char *dest,*cdat; int bytes=p->next_line,rows; @@ -3387,7 +3554,7 @@ c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + x * 8; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 8; cdat = p->fontdata + c * p->fontheight; fgx=attr_fgcol(p,conp); @@ -3408,13 +3575,13 @@ static void putcs_8_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *cdat, c, *dest, *dest0; int rows,bytes=p->next_line; u_long eorx, fgx, bgx; - dest0 = p->screen_base + y * p->fontheight * bytes + x * 8; + dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 8; fgx=attr_fgcol(p,conp); bgx=attr_bgcol(p,conp); fgx |= (fgx << 8); @@ -3437,12 +3604,12 @@ } -static void rev_char_8_packed(struct display *p, int x, int y) +static void rev_char_8_packed(struct display *p, int xx, int yy) { u_char *dest; int bytes=p->next_line, rows; - dest = p->screen_base + y * p->fontheight * bytes + x * 8; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 8; for (rows = p->fontheight ; rows-- ; dest += bytes) { ((u_long *)dest)[0] ^= 0x0f0f0f0f; ((u_long *)dest)[1] ^= 0x0f0f0f0f; @@ -3539,7 +3706,7 @@ static void putc_16_packed(struct vc_data *conp, struct display *p, int c, - int y, int x) + int yy, int xx) { u_char *dest,*cdat; int bytes=p->next_line,rows; @@ -3547,7 +3714,7 @@ c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + x * 16; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 16; cdat = p->fontdata + c * p->fontheight; fgx = attr_fgcol(p,conp); @@ -3573,13 +3740,13 @@ /* TODO */ static void putcs_16_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *cdat, c, *dest, *dest0; int rows,bytes=p->next_line; u_long eorx, fgx, bgx; - dest0 = p->screen_base + y * p->fontheight * bytes + x * 16; + dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 16; fgx = attr_fgcol(p,conp); fgx = packed16_cmap[fgx]; bgx = attr_bgcol(p,conp); @@ -3606,12 +3773,12 @@ } -static void rev_char_16_packed(struct display *p, int x, int y) +static void rev_char_16_packed(struct display *p, int xx, int yy) { u_char *dest; int bytes=p->next_line, rows; - dest = p->screen_base + y * p->fontheight * bytes + x * 16; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 16; for (rows = p->fontheight ; rows-- ; dest += bytes) { ((u_long *)dest)[0] ^= 0xffffffff; ((u_long *)dest)[1] ^= 0xffffffff; @@ -3641,87 +3808,90 @@ } -static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx, - int height, int width) +static void clear_cyber(struct vc_data *conp, struct display *p, int + sy, int sx, int height, int width) { - u_char bg; + unsigned char bg; sx *= 8; width *= 8; bg = attr_bgcol_ec(p,conp); - Cyber_RectFill((u_short)sx, (u_short)(sy*p->fontheight), (u_short)width, - (u_short)(height*p->fontheight), (u_short)S3_NEW, - (u_short)bg); + Cyber_RectFill((u_short)sx, + (u_short)(sy*p->fontheight), + (u_short)width, + (u_short)(height*p->fontheight), + (u_short)S3_NEW, + (u_short)bg); } -static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_cyber(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *cdat; u_long tmp; - u_int rows, reverse, underline; + u_int rows, revs, underl; u_char d; - u_char fg, bg; + u_char fg, bg; - c &= 0xff; + c &= 0xff; dest = p->screen_base+y*p->fontheight*p->next_line+8*x; cdat = p->fontdata+(c*p->fontheight); - fg = disp->fgcol; - bg = disp->bgcol; - reverse = conp->vc_reverse; - underline = conp->vc_underline; + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; Cyber_WaitBlit(); for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; - if (reverse) + if (revs) d = ~d; - tmp = ((d & 0x80) ? fg : bg) << 24; - tmp |= ((d & 0x40) ? fg : bg) << 16; - tmp |= ((d & 0x20) ? fg : bg) << 8; - tmp |= ((d & 0x10) ? fg : bg); - *((u_long*) dest) = tmp; - tmp = ((d & 0x8) ? fg : bg) << 24; - tmp |= ((d & 0x4) ? fg : bg) << 16; - tmp |= ((d & 0x2) ? fg : bg) << 8; - tmp |= ((d & 0x1) ? fg : bg); - *((u_long*) dest + 1) = tmp; + tmp = ((d & 0x80) ? fg : bg) << 24; + tmp |= ((d & 0x40) ? fg : bg) << 16; + tmp |= ((d & 0x20) ? fg : bg) << 8; + tmp |= ((d & 0x10) ? fg : bg); + *((u_long*) dest) = tmp; + tmp = ((d & 0x8) ? fg : bg) << 24; + tmp |= ((d & 0x4) ? fg : bg) << 16; + tmp |= ((d & 0x2) ? fg : bg) << 8; + tmp |= ((d & 0x1) ? fg : bg); + *((u_long*) dest + 1) = tmp; } } static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest, *dest0, *cdat; - u_long tmp; - u_int rows, reverse, underline; + u_long tmp; + u_int rows, revs, underl; u_char c, d; - u_char fg, bg; + u_char fg, bg; dest0 = p->screen_base+y*p->fontheight*p->next_line+8*x; - fg = disp->fgcol; - bg = disp->bgcol; - reverse = conp->vc_reverse; - underline = conp->vc_underline; + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; Cyber_WaitBlit(); while (count--) { c = *s++; dest = dest0; - dest0 += 8; + dest0 += 8; cdat = p->fontdata+(c*p->fontheight); for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; - if (reverse) + if (revs) d = ~d; tmp = ((d & 0x80) ? fg : bg) << 24; @@ -3739,32 +3909,208 @@ } -static void rev_char_cyber(struct display *p, int x, int y) +static void rev_char_cyber(struct display *p, int xx, int yy) { - u_char *dest; - u_int rows; - u_char fg, bg; + unsigned char *dest; + unsigned int rows; + unsigned char fg, bg; - fg = disp->fgcol; - bg = disp->bgcol; + fg = disp->fgcol; + bg = disp->bgcol; dest = p->screen_base+y*p->fontheight*p->next_line+8*x; Cyber_WaitBlit(); for (rows = p->fontheight; rows--; dest += p->next_line) { *dest = (*dest == fg) ? bg : fg; - *(dest+1) = (*(dest + 1) == fg) ? bg : fg; - *(dest+2) = (*(dest + 2) == fg) ? bg : fg; - *(dest+3) = (*(dest + 3) == fg) ? bg : fg; - *(dest+4) = (*(dest + 4) == fg) ? bg : fg; - *(dest+5) = (*(dest + 5) == fg) ? bg : fg; - *(dest+6) = (*(dest + 6) == fg) ? bg : fg; - *(dest+7) = (*(dest + 7) == fg) ? bg : fg; + *(dest+1) = (*(dest + 1) == fg) ? bg : fg; + *(dest+2) = (*(dest + 2) == fg) ? bg : fg; + *(dest+3) = (*(dest + 3) == fg) ? bg : fg; + *(dest+4) = (*(dest + 4) == fg) ? bg : fg; + *(dest+5) = (*(dest + 5) == fg) ? bg : fg; + *(dest+6) = (*(dest + 6) == fg) ? bg : fg; + *(dest+7) = (*(dest + 7) == fg) ? bg : fg; } } #endif /* CONFIG_FBCON_CYBER */ +#ifdef CONFIG_FBCON_RETINAZ3 + +/* + * RetinaZ3 (accelerated) + */ + +#define Z3BLTcopy 0xc0 +#define Z3BLTset 0xf0 + +static void clear_retz3(struct vc_data *conp, struct display *p, int + sy, int sx, int height, int width) +{ + unsigned short col; + int fontwidth = p->fontwidth; + + sx *= fontwidth; + width *= fontwidth; + + col = attr_bgcol_ec(p, conp); + col &= 0xff; + col |= (col << 8); + + retz3_bitblt(&p->var, + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)width, + (unsigned short)(height*p->fontheight), + Z3BLTset, + col); +} + +static void bmove_retz3(struct display *p, int sy, int sx, int dy, int dx, + int height, int width) +{ + int fontwidth = p->fontwidth; + + sx *= fontwidth; + dx *= fontwidth; + width *= fontwidth; + + retz3_bitblt(&p->var, + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)dx, + (unsigned short)(dy*p->fontheight), + (unsigned short)width, + (unsigned short)(height*p->fontheight), + Z3BLTcopy, + 0xffff); +} + +static void putc_retz3(struct vc_data *conp, struct display *p, + int c, int yy, int xx) +{ + unsigned char *dest, *cdat; + unsigned long tmp; + unsigned int rows, revs, underl, bytes; + unsigned char d; + unsigned char fg, bg; + + c &= 0xff; + + bytes = p->next_line; + + dest = p->screen_base + yy*p->fontheight*bytes + + xx*p->var.bits_per_pixel; + cdat = p->fontdata + c * p->fontheight; + + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; + + for (rows = p->fontheight; rows--; dest += bytes) { + d = *cdat++; + + if (underl && !rows) + d = 0xff; + if (revs) + d = ~d; + + tmp = ((d & 0x80) ? fg : bg) << 24; + tmp |= ((d & 0x40) ? fg : bg) << 16; + tmp |= ((d & 0x20) ? fg : bg) << 8; + tmp |= ((d & 0x10) ? fg : bg); + *((unsigned long*) dest) = tmp; + tmp = ((d & 0x8) ? fg : bg) << 24; + tmp |= ((d & 0x4) ? fg : bg) << 16; + tmp |= ((d & 0x2) ? fg : bg) << 8; + tmp |= ((d & 0x1) ? fg : bg); + *((unsigned long*) dest + 1) = tmp; + } +} + + +static void putcs_retz3(struct vc_data *conp, struct display *p, + const char *s, int count, int yy, int xx) +{ + unsigned char *dest, *dest0, *cdat; + unsigned long tmp; + unsigned int rows, revs, underl, bytes; + unsigned char c, d; + unsigned char fg, bg; + + bytes = p->next_line; + + dest0 = p->screen_base + yy*p->fontheight*bytes + + xx * p->var.bits_per_pixel; + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; + + while (count--) { + c = *s++; + dest = dest0; + dest0 += 8; + + cdat = p->fontdata + c * p->fontheight; + for (rows = p->fontheight; rows--; dest += bytes) { + d = *cdat++; + + if (underl && !rows) + d = 0xff; + if (revs) + d = ~d; + + tmp = ((d & 0x80) ? fg : bg) << 24; + tmp |= ((d & 0x40) ? fg : bg) << 16; + tmp |= ((d & 0x20) ? fg : bg) << 8; + tmp |= ((d & 0x10) ? fg : bg); + *((unsigned long*) dest) = tmp; + tmp = ((d & 0x8) ? fg : bg) << 24; + tmp |= ((d & 0x4) ? fg : bg) << 16; + tmp |= ((d & 0x2) ? fg : bg) << 8; + tmp |= ((d & 0x1) ? fg : bg); + *((unsigned long*) dest + 1) = tmp; + } + } +} + +static void rev_char_retz3(struct display *p, int xx, int yy) +{ + unsigned char *dest; + int bytes=p->next_line, rows; + unsigned int bpp, mask; + + bpp = p->var.bits_per_pixel; + + switch (bpp){ + case 8: + mask = 0x0f0f0f0f; + break; + case 16: + mask = 0xffffffff; + break; + case 24: + mask = 0xffffffff; /* ??? */ + break; + default: + printk("illegal depth for rev_char_retz3(), bpp = %i\n", bpp); + return; + } + + dest = p->screen_base + yy * p->fontheight * bytes + xx * bpp; + + for (rows = p->fontheight ; rows-- ; dest += bytes) { + ((unsigned long *)dest)[0] ^= mask; + ((unsigned long *)dest)[1] ^= mask; + } +} + +#endif + /* ====================================================================== */ /* @@ -3774,5 +4120,5 @@ struct consw fb_con = { fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc, fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch, - fbcon_blank, fbcon_get_font, fbcon_set_font + fbcon_blank, fbcon_get_font, fbcon_set_font, fbcon_set_palette }; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/console/txtcon.c linux/arch/m68k/console/txtcon.c --- v2.1.35/linux/arch/m68k/console/txtcon.c Sun May 19 21:54:26 1996 +++ linux/arch/m68k/console/txtcon.c Thu Apr 17 13:20:42 1997 @@ -22,7 +22,7 @@ * Interface used by the world */ -static u_long txtcon_startup(u_long kmem_start, char **display_desc); +static u_long txtcon_startup(u_long kmem_start, const char **display_desc); static void txtcon_init(struct vc_data *conp); static int txtcon_deinit(struct vc_data *conp); static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height, @@ -36,10 +36,12 @@ int height, int width); static int txtcon_switch(struct vc_data *conp); static int txtcon_blank(int blank); +static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data); +static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data); +static int txtcon_set_palette(struct vc_data *conp, unsigned char *table); - -static u_long txtcon_startup(u_long kmem_start, char **display_desc) +static u_long txtcon_startup(u_long kmem_start, const char **display_desc) { *display_desc = "Not yet implemented"; return(kmem_start); @@ -113,6 +115,24 @@ } +static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data) +{ + return(0); +} + + +static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data) +{ + return(0); +} + + +static int txtcon_set_palette(struct vc_data *conp, unsigned char *table) +{ + return(0); +} + + /* ====================================================================== */ /* @@ -122,6 +142,6 @@ struct consw txt_con = { txtcon_startup, txtcon_init, txtcon_deinit, txtcon_clear, txtcon_putc, txtcon_putcs, txtcon_cursor, txtcon_scroll, txtcon_bmove, txtcon_switch, - txtcon_blank + txtcon_blank, txtcon_get_font, txtcon_set_font, txtcon_set_palette }; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/defconfig linux/arch/m68k/defconfig --- v2.1.35/linux/arch/m68k/defconfig Mon Apr 7 11:35:29 1997 +++ linux/arch/m68k/defconfig Thu Apr 17 13:20:42 1997 @@ -46,6 +46,7 @@ CONFIG_AMIFB_ECS=y CONFIG_AMIFB_AGA=y # CONFIG_FB_CYBER is not set +# CONFIG_FB_RETINAZ3 is not set # CONFIG_AMIGA_GSP is not set # CONFIG_GSP_RESOLVER is not set # CONFIG_GSP_A2410 is not set @@ -79,9 +80,10 @@ # CONFIG_FIREWALL is not set # CONFIG_NET_ALIAS is not set CONFIG_INET=y -# CONFIG_IP_FORWARD is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ACCT is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set # # (it is safe to leave these untouched) @@ -123,18 +125,19 @@ # SCSI low-level drivers # CONFIG_A3000_SCSI=y -# CONFIG_A2091_SCSI is not set -# CONFIG_GVP11_SCSI is not set +CONFIG_A2091_SCSI=y +CONFIG_GVP11_SCSI=y # CONFIG_CYBERSTORM_SCSI is not set # CONFIG_CYBERSTORMII_SCSI is not set # CONFIG_BLZ2060_SCSI is not set # CONFIG_BLZ1230_SCSI is not set +# CONFIG_FASTLANE_SCSI is not set CONFIG_ATARI_SCSI=y # # Network device support # -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_SLIP is not set # CONFIG_PPP is not set @@ -164,6 +167,7 @@ # CONFIG_HPFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_UFS_FS is not set # @@ -176,6 +180,8 @@ CONFIG_ATARIMOUSE=y CONFIG_AMIGA_BUILTIN_SERIAL=y # CONFIG_GVPIOEXT is not set +# CONFIG_GVPIOEXT_LP is not set +# CONFIG_GVPIOEXT_PLIP is not set # CONFIG_MULTIFACE_III_TTY is not set # CONFIG_USERIAL is not set # CONFIG_WATCHDOG is not set diff -u --recursive --new-file v2.1.35/linux/arch/m68k/fpsp040/skeleton.S linux/arch/m68k/fpsp040/skeleton.S --- v2.1.35/linux/arch/m68k/fpsp040/skeleton.S Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/fpsp040/skeleton.S Thu Apr 17 13:20:42 1997 @@ -513,9 +513,12 @@ movel 12(%sp),%d0 | count subl #1,%d0 | dec count by 1 for dbra movel #1,%d1 - movec %d1,%DFC | set dfc for user data space + +| DFC is already set +| movec %d1,%DFC | set dfc for user data space moreout: moveb (%a0)+,%d1 | fetch supervisor byte +out_ea: movesb %d1,(%a1)+ | write user byte dbf %d0,moreout rts @@ -526,11 +529,24 @@ movel 12(%sp),%d0 | count subl #1,%d0 | dec count by 1 for dbra movel #1,%d1 - movec %d1,%SFC | set sfc for user space +| SFC is already set +| movec %d1,%SFC | set sfc for user space morein: +in_ea: movesb (%a0)+,%d1 | fetch user byte moveb %d1,(%a1)+ | write supervisor byte dbf %d0,morein rts + + .section .fixup,#alloc,#execinstr + .even +1: + jbra SYMBOL_NAME(fpsp040_die) + + .section __ex_table,#alloc + .align 4 + + .long in_ea,1b + .long out_ea,1b |end diff -u --recursive --new-file v2.1.35/linux/arch/m68k/ifpsp060/os.S linux/arch/m68k/ifpsp060/os.S --- v2.1.35/linux/arch/m68k/ifpsp060/os.S Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/ifpsp060/os.S Thu Apr 17 13:20:42 1997 @@ -153,7 +153,7 @@ btst #0x5,0x4(%a6) | check for supervisor state bnes dmrbs | supervisor dmrbu: clr.l %d0 | clear whole longword - movs.b (%a0),%d0 | fetch user byte +dmrbuae:movs.b (%a0),%d0 | fetch user byte bras dmrbr dmrbs: clr.l %d0 | clear whole longword move.b (%a0),%d0 | fetch super byte @@ -190,7 +190,7 @@ btst #0x5,0x4(%a6) | check for supervisor state bnes dmrws | supervisor dmrwu: clr.l %d0 | clear whole longword - movs.w (%a0), %d0 | fetch user word +dmrwuae:movs.w (%a0), %d0 | fetch user word bras dmrwr dmrws: clr.l %d0 | clear whole longword move.w (%a0), %d0 | fetch super word @@ -226,7 +226,8 @@ _060_imem_read_long: btst #0x5,0x4(%a6) | check for supervisor state bnes dmrls | supervisor -dmrlu: movs.l (%a0),%d0 | fetch user longword +dmrlu: +dmrluae:movs.l (%a0),%d0 | fetch user longword bras dmrlr dmrls: move.l (%a0),%d0 | fetch super longword dmrlr: clr.l %d1 | return success @@ -248,7 +249,8 @@ _060_dmem_write_byte: btst #0x5,0x4(%a6) | check for supervisor state bnes dmwbs | supervisor -dmwbu: movs.b %d0,(%a0) | store user byte +dmwbu: +dmwbuae:movs.b %d0,(%a0) | store user byte bras dmwbr dmwbs: move.b %d0,(%a0) | store super byte dmwbr: clr.l %d1 | return success @@ -270,7 +272,8 @@ _060_dmem_write_word: btst #0x5,0x4(%a6) | check for supervisor state bnes dmwws | supervisor -dmwwu: movs.w %d0,(%a0) | store user word +dmwwu: +dmwwuae:movs.w %d0,(%a0) | store user word bras dmwwr dmwws: move.w %d0,(%a0) | store super word dmwwr: clr.l %d1 | return success @@ -292,7 +295,8 @@ _060_dmem_write_long: btst #0x5,0x4(%a6) | check for supervisor state bnes dmwls | supervisor -dmwlu: movs.l %d0,(%a0) | store user longword +dmwlu: +dmwluae:movs.l %d0,(%a0) | store user longword bra dmwlr dmwls: move.l %d0,(%a0) | store super longword dmwlr: clr.l %d1 | return success @@ -322,9 +326,10 @@ subq.l #1,%d0 moreout: move.b (%a0)+,%d1 | fetch supervisor byte +copyoutae: movs.b %d1,(%a1)+ | store user byte dbra %d0,moreout | are we through yet? - moveq #0,%d0 | return success + moveq #0,%d0 | return success rts | @@ -337,11 +342,12 @@ move.l 12(%sp),%d0 | count subq.l #1,%d0 morein: +copyinae: movs.b (%a0)+,%d1 | fetch user byte move.b %d1,(%a1)+ | write supervisor byte subq.l #0x1,%d0 | are we through yet? dbra %d0,morein | are we through yet? - moveq #0,%d0 | return success + moveq #0,%d0 | return success rts |########################################################################### @@ -374,3 +380,22 @@ .global _060_real_access _060_real_access: bral SYMBOL_NAME(buserr) + + + +| Execption handling for movs access to illegal memory + .section .fixup,#alloc,#execinstr + .even +1: moveq #-1,%d1 + rts +.section __ex_table,#alloc + .align 4 + .long dmrbuae,1b + .long dmrwuae,1b + .long dmrluae,1b + .long dmwbuae,1b + .long dmwwuae,1b + .long dmwluae,1b + .long copyoutae,1b + .long copyinae,1b + .text diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/Makefile linux/arch/m68k/kernel/Makefile --- v2.1.35/linux/arch/m68k/kernel/Makefile Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/kernel/Makefile Thu Apr 17 13:20:42 1997 @@ -19,6 +19,10 @@ endif OX_OBJS := m68k_ksyms.o +ifdef CONFIG_KGDB +O_OBJS += kgdb.o +endif + head.o: head.S include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/console.c linux/arch/m68k/kernel/console.c --- v2.1.35/linux/arch/m68k/kernel/console.c Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/kernel/console.c Thu Apr 17 13:20:42 1997 @@ -20,7 +20,7 @@ * 'unsigned long con_init(unsigned long)' * 'int con_open(struct tty_struct *tty, struct file * filp)' * 'void con_write(struct tty_struct * tty)' - * 'void console_print(const char * b)' + * 'void vt_console_print(const char * b)' * 'void update_screen(int new_console)' * * 'void do_blank_screen(int)' @@ -103,11 +103,13 @@ * interrupt, as we use trap-gates. Hopefully all is well. */ +#include #include #include #include #include #include +#include #include #include #include @@ -127,6 +129,7 @@ #include "../../../drivers/char/vt_kern.h" #include "../../../drivers/char/consolemap.h" #include "../../../drivers/char/selection.h" +#include "../../../drivers/char/console_struct.h" #ifndef MIN @@ -146,12 +149,13 @@ static void save_cur(int currcons); static void blank_screen(void); static void unblank_screen(void); +static int con_open(struct tty_struct *, struct file *); extern void change_console(unsigned int); static inline void set_cursor(int currcons); static void reset_terminal(int currcons, int do_clear); extern void reset_vc(unsigned int new_console); extern void vt_init(void); -extern void register_console(void (*proc)(const char *)); +static void set_vesa_blanking(unsigned long arg); extern void vesa_blank(void); extern void vesa_unblank(void); extern void compute_shiftstate(void); @@ -170,6 +174,7 @@ static unsigned short console_charmask = 0x0ff; static unsigned short *vc_scrbuf[MAX_NR_CONSOLES]; +struct vc vc_cons [MAX_NR_CONSOLES]; /* used by kbd_bh - set by keyboard_interrupt */ int do_poke_blanked_console = 0; @@ -189,13 +194,6 @@ int want_console = -1; int kmsg_redirect = 0; -static struct vc { - struct vc_data *d; - - /* might add scrmem, vt_struct, kbd at some time, - to have everything in one place - the disadvantage - would be that vc_cons etc can no longer be static */ -} vc_cons [MAX_NR_CONSOLES]; struct consw *conswitchp; #define cols (vc_cons[currcons].d->vc_cols) @@ -270,8 +268,6 @@ #define vtnewvt (vt_cons[currcons]->vt_newvt) #endif -#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct)) - int vc_cons_allocated(unsigned int i) { return (i < MAX_NR_CONSOLES && vc_cons[i].d); @@ -621,8 +617,7 @@ return; } -static void scrup(int currcons, unsigned int t, unsigned int b, - int nr) +static void scrup(int currcons, unsigned int t, unsigned int b, int nr) { unsigned short *p; int i; @@ -636,10 +631,10 @@ p = video_mem_start + (b - nr) * cols; for (i = nr * cols; i > 0; i--) - *p++ = video_erase_char; + *p++ = video_erase_char; if (currcons != fg_console) - return; + return; /* * Arno: * Scrolling has now been moved to amicon.c where it should have @@ -812,8 +807,8 @@ if (!vpar) vpar++; - start=pos; - count=(vpar > cols-x) ? (cols-x) : vpar; + start = pos; + count = (vpar > cols-x) ? (cols-x) : vpar; if (currcons == fg_console) sw->con_clear(vc_cons[currcons].d,y,x,1,count); @@ -1008,7 +1003,7 @@ respond_string(buf, tty); } -/* invoked via ioctl(TIOCLINUX) */ +/* invoked via ioctl(TIOCLINUX) and through set_selection */ int mouse_reporting(void) { int currcons = fg_console; @@ -1309,12 +1304,12 @@ unsigned short *p = pos; for (i = cols - x - 2; i >= 0; i--) - p[i + 1] = p[i]; + p[i + 1] = p[i]; *pos = video_erase_char; need_wrap = 0; if (currcons != fg_console) - return; + return; /* Arno: * Move the remainder of the line (-1 character) one spot to the right @@ -1338,19 +1333,19 @@ p = pos + cols - x - nr; while (--p >= pos) - p[nr] = *p; + p[nr] = *p; for (i = 0; i < nr; i++) - *++p = video_erase_char; + *++p = video_erase_char; need_wrap = 0; if (currcons != fg_console) - return; + return; sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr, 1, cols - x - nr); while (nr--) - sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff, - y, x + nr); + sw->con_putc (vc_cons[currcons].d, + video_erase_char & 0x00ff, y, x + nr); } static void csi_L(int currcons, unsigned int nr) @@ -1645,9 +1640,9 @@ */ /* Only use this for the foreground console, - where we really draw the chars */ + where we really draw the chars */ - if (count > 2 && + if (count > 2 && !decim && !utf && currcons == fg_console) { static char putcs_buf[256]; char *p = putcs_buf; @@ -1660,13 +1655,11 @@ if (nextx == cols) { sw->con_putc(vc_cons[currcons].d, *putcs_buf, y, x); - pos--; + ((unsigned short *)pos)--; need_wrap = decawm; continue; } - /* TAB TAB TAB - Arghh!!!! */ - while (count) { enable_bh(CONSOLE_BH); @@ -2129,12 +2122,13 @@ /* DPC: New version of console_print using putcs */ -void console_print(const char * b) +#ifdef CONFIG_VT_CONSOLE +void vt_console_print(const char * b, unsigned int count) { int currcons = fg_console; unsigned char c; const char *start = b; - ushort count = 0; + ushort cnt = 0; ushort myx = x; static int printing = 0; @@ -2147,7 +2141,7 @@ if (!vc_cons_allocated(currcons)) { /* impossible */ - printk("console_print: tty %d not allocated ??\n", currcons+1); + printk("vt_console_print: tty %d not allocated ??\n", currcons+1); printing = 0; return; } @@ -2157,52 +2151,51 @@ /* Contrived structure to try to emulate original need_wrap behaviour * Problems caused when we have need_wrap set on '\n' character */ - - while ((c = *(b++)) != 0) { - if (c == 10 || c == 13 || c == 8 || need_wrap) { - if ((count = b - start - 1) > 0) { - sw->con_putcs(vc_cons[currcons].d, start, count , - y, x); - x += count; - if (need_wrap) - x--; - } - - if (c == 8) { /* backspace */ - bs(currcons); - start = b; - myx = x; - continue; + + while (count-- > 0) { + c = *(b++); + if (c == 10 || c == 13 || c == 8 || need_wrap) { + if ((cnt = b - start - 1) > 0) { + sw->con_putcs(vc_cons[currcons].d, + start, cnt, y, x); + x += cnt; + if (need_wrap) + x--; + } + + if (c == 8) { /* backspace */ + bs(currcons); + start = b; + myx = x; + continue; + } + if (c != 13) + lf(currcons); + cr(currcons); + + if (c == 10 || c == 13) { + start = b; myx = x; continue; + } + + start = b-1; myx = x; } - if (c != 13) - lf(currcons); - cr(currcons); - - if (c == 10 || c == 13) { - start = b; myx = x; continue; - } - - start = b-1; myx = x; - } - - *pos = c | (attr << 8); - if (myx == cols - 1) { - need_wrap = 1; - continue; - } - pos++; - myx++; + + *pos = c | (attr << 8); + if (myx == cols - 1) { + need_wrap = 1; + continue; + } + pos++; + myx++; } - if ((count = b - start -1) > 0) { - sw->con_putcs(vc_cons[currcons].d, start, count , - y, x); - x += count; - if (x == cols) - { - x--; - need_wrap = 1; - } + if ((cnt = b - start) > 0) { + sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x); + x += cnt; + if (x == cols){ + x--; + need_wrap = 1; + } } set_cursor(currcons); @@ -2210,6 +2203,18 @@ printing = 0; } +static int vt_console_device(void) +{ + return MKDEV(TTY_MAJOR, fg_console + 1); +} + +extern void keyboard_wait_for_keypress(void); + +struct console vt_console_driver = { + vt_console_print, do_unblank_screen, + keyboard_wait_for_keypress, vt_console_device +}; +#endif /* * con_throttle and con_unthrottle are only used for @@ -2280,7 +2285,7 @@ */ unsigned long con_init(unsigned long kmem_start) { - char *display_desc = "????"; + const char *display_desc = "????"; unsigned int currcons = 0; extern int serial_debug; @@ -2354,14 +2359,15 @@ printable = 1; /* If "serdebug" cmd line option was present, don't register for printk */ +#ifdef CONFIG_VT_CONSOLE if (!serial_debug) - register_console(console_print); + register_console(&vt_console_driver); printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n", can_do_color ? "colour":"mono", display_desc, cols,rows, MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES); - +#endif init_bh(CONSOLE_BH, console_bh); return kmem_start; } @@ -2527,7 +2533,7 @@ /* * Allocate the console screen memory. */ -int con_open(struct tty_struct *tty, struct file * filp) +static int con_open(struct tty_struct *tty, struct file * filp) { unsigned int currcons; int i; @@ -2664,7 +2670,7 @@ return -EINVAL; } -void set_vesa_blanking(int arg) +static void set_vesa_blanking(unsigned long arg) { char *argp = (char *)arg + 1; unsigned int mode; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S --- v2.1.35/linux/arch/m68k/kernel/entry.S Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/kernel/entry.S Tue Apr 22 22:49:38 1997 @@ -52,6 +52,10 @@ #include #include #include +#ifdef CONFIG_KGDB +#include +.globl SYMBOL_NAME(kgdb_registers) +#endif LENOSYS = 38 @@ -66,7 +70,7 @@ LTASK_FLAGS = 20 /* the following macro is used when enabling interrupts */ -#if defined(CONFIG_ATARI_ONLY) +#if defined(MACH_ATARI_ONLY) /* block out HSYNC on the atari */ #define ALLOWINT 0xfbff #define MAX_NOINT_IPL 3 @@ -87,11 +91,23 @@ * regs are a2-a6 and d6-d7 preserved by C code * the kernel doesn't mess with usp unless it needs to */ +#ifndef CONFIG_KGDB #define SAVE_ALL \ clrl %sp@-; /* stk_adj */ \ movel %d0,%sp@-; /* orig d0 */ \ movel %d0,%sp@-; /* d0 */ \ moveml %d1-%d5/%a0-%a1,%sp@- +#else +/* Need to save the "missing" registers for kgdb... + */ +#define SAVE_ALL \ + clrl %sp@-; /* stk_adj */ \ + movel %d0,%sp@-; /* orig d0 */ \ + movel %d0,%sp@-; /* d0 */ \ + moveml %d1-%d5/%a0-%a1,%sp@-; \ + moveml %d6-%d7,SYMBOL_NAME(kgdb_registers)+GDBOFFA_D6; \ + moveml %a2-%a6,SYMBOL_NAME(kgdb_registers)+GDBOFFA_A2 +#endif #define RESTORE_ALL \ moveml %sp@+,%a0-%a1/%d1-%d5; \ @@ -244,7 +260,7 @@ movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field | signifies that the stack frame | is NOT for syscall - addql #1,SYMBOL_NAME(intr_count) + addql #1,SYMBOL_NAME(local_irq_count) | put exception # in d0 bfextu %sp@(LFORMATVEC){#4,#10},%d0 @@ -255,27 +271,26 @@ SYMBOL_NAME_LABEL(ret_from_interrupt) /* check if we need to do software interrupts */ -1: - movel SYMBOL_NAME(intr_count),%d1 + movel SYMBOL_NAME(local_irq_count),%d1 subql #1,%d1 jne 4f - bfextu %sp@(LSR){#5,#3},%d0 | Check for nested interrupt. +#if 0 + bfextu %sp@(LSR){#5,#3},%d0 | Check for nested interrupt. #if MAX_NOINT_IPL > 0 cmpiw #MAX_NOINT_IPL,%d0 #endif jhi 4f -2: +#endif movel SYMBOL_NAME(bh_active),%d0 andl SYMBOL_NAME(bh_mask),%d0 - jne 3f + jeq 3f - clrl SYMBOL_NAME(intr_count) | deliver signals, reschedule etc.. - jra SYMBOL_NAME(ret_from_exception) -3: jbsr SYMBOL_NAME(do_bottom_half) - jbra 2b +3: + clrl SYMBOL_NAME(local_irq_count) + jra SYMBOL_NAME(ret_from_exception) 4: - movel %d1,SYMBOL_NAME(intr_count) + movel %d1,SYMBOL_NAME(local_irq_count) RESTORE_ALL @@ -339,8 +354,10 @@ /* save sr */ movew %sr,%a0@(LTSS_SR) +#if 0 /* disable interrupts */ oriw #0x0700,%sr +#endif /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ movec %sfc,%d0 @@ -361,18 +378,18 @@ fsave %a0@(LTSS_FPCTXT+27*4) #if defined(CONFIG_M68060) -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) btst #3,SYMBOL_NAME(m68k_cputype)+3 beqs 1f #endif /* The 060 FPU keeps status in bits 15-8 of the first longword */ tstb %a0@(LTSS_FPCTXT+27*4+2) jeq 3f -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) jra 2f #endif #endif /* CONFIG_M68060 */ -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) 1: tstb %a0@(LTSS_FPCTXT+27*4) jeq 3f #endif @@ -388,12 +405,12 @@ tstb %d2 jne 4f -#if defined(CONFIG_M68020_OR_M68030) && defined(CONFIG_M68040_OR_M68060) +#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060) /* 68040 or 68060 ? */ tstl SYMBOL_NAME(m68k_is040or060) bnes 1f #endif -#if defined(CONFIG_M68020_OR_M68030) +#if defined(CPU_M68020_OR_M68030) /* * switch address space */ @@ -407,11 +424,11 @@ pmove %a1@(LTSS_CRP),%crp #endif -#if defined(CONFIG_M68020_OR_M68030) && defined(CONFIG_M68040_OR_M68060) +#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060) jra 2f /* skip m68040 stuff */ 1: #endif -#if defined(CONFIG_M68040_OR_M68060) +#if defined(CPU_M68040_OR_M68060) /* * switch address space */ @@ -434,24 +451,24 @@ movec %d0,%cacr #endif /* CONFIG_M68060 */ .chip 68k -#endif /* CONFIG_M68040_OR_M68060 */ +#endif /* CPU_M68040_OR_M68060 */ 2: 4: /* restore floating point context */ #if defined(CONFIG_M68060) -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) btst #3,SYMBOL_NAME(m68k_cputype)+3 beqs 1f #endif /* The 060 FPU keeps status in bits 15-8 of the first longword */ tstb %a1@(LTSS_FPCTXT+27*4+2) jeq 3f -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) jra 2f #endif #endif /* CONFIG_M68060 */ -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) 1: tstb %a1@(LTSS_FPCTXT+27*4) jeq 3f #endif @@ -647,8 +664,11 @@ .long SYMBOL_NAME(sys_nanosleep) .long SYMBOL_NAME(sys_mremap) .long SYMBOL_NAME(sys_setresuid) - .long SYMBOL_NAME(sys_getresuid) + .long SYMBOL_NAME(sys_getresuid) /* 165 */ .long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */ + .long SYMBOL_NAME(sys_query_module) + .long SYMBOL_NAME(sys_poll) + .long SYMBOL_NAME(sys_nfsservctl) .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/head.S linux/arch/m68k/kernel/head.S --- v2.1.35/linux/arch/m68k/kernel/head.S Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/kernel/head.S Thu Apr 17 13:20:42 1997 @@ -73,6 +73,7 @@ .globl SYMBOL_NAME(kernel_pg_dir), SYMBOL_NAME(kpt) .globl SYMBOL_NAME(availmem), SYMBOL_NAME(is_medusa) +.globl SYMBOL_NAME(is_hades) .globl SYMBOL_NAME(m68k_pgtable_cachemode) .globl SYMBOL_NAME(kernel_pmd_table), SYMBOL_NAME(swapper_pg_dir) @@ -235,8 +236,58 @@ #endif /* + If running on an Atari, determine the I/O base of the + serial port and test if we are running on a Medusa or Hades. + This test is necessary here, because on the Hades the serial + port is only accessible in the high I/O memory area. + + The test whether it is a Medusa is done by writing to the byte at + phys. 0x0. This should result in a bus error on all other machines. + + ...should, but doesn't. The Afterburner040 for the Falcon has the + same behaviour (0x0..0x7 are no ROM shadow). So we have to do + another test to distinguish Medusa and AB040. This is a + read attempt for 0x00ff82fe phys. that should bus error on a Falcon + (+AB040), but is in the range where the Medusa always asserts DTACK. + + The test for the Hades is done by reading address 0xb0000000. This + should give a bus error on the Medusa. + */ + +#ifdef CONFIG_ATARI + is_not_atari(Lnotypetest) + + moveq #0,%d3 /* base addr for others: 0x00000000 */ + moveq #0,%d2 /* no Hades */ + movec %d3,%vbr + lea %pc@(Ltest_berr),%a0 + movel %a0,0x8 + movel %sp,%a0 + moveb 0x0,%d1 + clrb 0x0 + nop + moveb %d1,0x0 + nop + tstb 0x00ff82fe + nop + movel #0xff000000,%d3 /* Medusa base addr: 0xff000000 */ + tstb 0xb0000000 + nop + movel #0xff000000,%d2 /* Computer is a Hades */ + moveq #0,%d3 +Ltest_berr: + movel %a0,%sp + lea %pc@(SYMBOL_NAME(is_hades)),%a0 + movel %d2,%a0@ + lea %pc@(SYMBOL_NAME(is_medusa)),%a0 + movel %d3,%a0@ +Lnotypetest: +#endif + +/* * Initialize serial port */ + jbsr Lserial_init putr() @@ -491,35 +542,16 @@ For the Medusa it is better to map the I/O region transparently (i.e. 0xffxxxxxx -> 0xffxxxxxx), because some I/O registers are - accessible only in the high area. The test whether it is a Medusa - is done by writing to the byte at phys. 0x0. This should result - in a bus error on all other machines. + accessible only in the high area. - ...should, but doesn't. The Afterburner040 for the Falcon has the - same behaviour (0x0..0x7 are no ROM shadow). So we have to do - another test to distinguish Medusa and AB040. This is a - read attempt for 0x00ff82fe phys. that should bus error on a Falcon - (+AB040), but is in the range where the Medusa always asserts DTACK. + On the Hades all I/O registers are only accessible in the high + area. */ - moveq #0,%d3 /* base addr for others: 0x00000000 */ - movec %d3,%vbr - lea %pc@(Ltest_berr),%a0 - movel %a0,0x8 - movel %sp,%a0 - moveb 0x0,%d1 - clrb 0x0 - nop - moveb %d1,0x0 - nop - tstb 0x00ff82fe - nop - movel #0xff000000,%d3 /* Medusa base addr: 0xff000000 */ -Ltest_berr: - movel %a0,%sp - lea %pc@(SYMBOL_NAME(is_medusa)),%a0 - movel %d3,%a0@ - + movel %pc@(is_medusa),%d3 + bne 1f + movel %pc@(is_hades),%d3 +1: /* Let the root table point to the new pointer table */ lea %a4@(PTR_TABLE_SIZE<<2),%a4 movel %a4,%a0 @@ -979,19 +1011,20 @@ #ifdef CONFIG_ATARI cmpil #MACH_ATARI,%d4 jne 4f + movel %pc@(Liobase),%a1 #ifdef USE_PRINTER - bclr #0,LSTMFP_IERB - bclr #0,LSTMFP_DDR - moveb #LPSG_CONTROL,LPSG_SELECT - moveb #0xff,LPSG_WRITE - moveb #LPSG_IO_B,LPSG_SELECT - clrb LPSG_WRITE - moveb #LPSG_IO_A,LPSG_SELECT - moveb LPSG_READ,%d0 + bclr #0,%a1@(LSTMFP_IERB) + bclr #0,%a1@(LSTMFP_DDR) + moveb #LPSG_CONTROL,%a1@(LPSG_SELECT) + moveb #0xff,%a1@(LPSG_WRITE) + moveb #LPSG_IO_B,%a1@(LPSG_SELECT) + clrb %a1@(LPSG_WRITE) + moveb #LPSG_IO_A,%a1@(LPSG_SELECT) + moveb %a1@(LPSG_READ),%d0 bset #5,%d0 - moveb %d0,LPSG_WRITE + moveb %d0,%a1@(LPSG_WRITE) #elif defined(USE_SCC) - lea LSCC_CTRL_B,%a0 + lea %a1@(LSCC_CTRL_B),%a0 lea %pc@(scc_initable:w),%a1 2: moveb %a1@+,%d0 jmi 3f @@ -1000,12 +1033,12 @@ jra 2b 3: clrb %a0@ #elif defined(USE_MFP) - bclr #1,LMFP_TSR - moveb #0x88,LMFP_UCR - andb #0x70,LMFP_TDCDR - moveb #2,LMFP_TDDR - orb #1,LMFP_TDCDR - bset #1,LMFP_TSR + bclr #1,%a1@(LMFP_TSR) + moveb #0x88,%a1@(LMFP_UCR) + andb #0x70,%a1@(LMFP_TDCDR) + moveb #2,%a1@(LMFP_TDDR) + orb #1,%a1@(LMFP_TDCDR) + bset #1,%a1@(LMFP_TSR) #endif 4: #endif @@ -1140,6 +1173,8 @@ SYMBOL_NAME_LABEL(availmem) .long 0 SYMBOL_NAME_LABEL(is_medusa) + .long 0 +SYMBOL_NAME_LABEL(is_hades) .long 0 SYMBOL_NAME_LABEL(m68k_pgtable_cachemode) .long 0 diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/ints.c linux/arch/m68k/kernel/ints.c --- v2.1.35/linux/arch/m68k/kernel/ints.c Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/kernel/ints.c Thu Apr 17 13:20:42 1997 @@ -50,6 +50,24 @@ #define NUM_IRQ_NODES 100 static irq_node_t nodes[NUM_IRQ_NODES]; +unsigned int local_irq_count[NR_CPUS]; + +int __m68k_bh_counter; + +static void dummy_enable_irq(unsigned int irq); +static void dummy_disable_irq(unsigned int irq); +static int dummy_request_irq(unsigned int irq, + void (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +static void dummy_free_irq(unsigned int irq, void *dev_id); + +void (*enable_irq) (unsigned int) = dummy_enable_irq; +void (*disable_irq) (unsigned int) = dummy_disable_irq; + +int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *) = dummy_request_irq; +void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq; + /* * void init_IRQ(void) * @@ -92,14 +110,30 @@ return NULL; } -int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long flags, const char *devname, void *dev_id) +/* + * We will keep these functions until I have convinced Linus to move + * the declaration of them from include/linux/sched.h to + * include/asm/irq.h. + */ +int request_irq(unsigned int irq, + void (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + return mach_request_irq(irq, handler, flags, devname, dev_id); +} + +void free_irq(unsigned int irq, void *dev_id) { - if (irq & IRQ_MACHSPEC) - return mach_request_irq(IRQ_IDX(irq), handler, flags, devname, dev_id); + mach_free_irq(irq, dev_id); +} +int sys_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ if (irq < IRQ1 || irq > IRQ7) { - printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); + printk("%s: Incorrect IRQ %d from %s\n", + __FUNCTION__, irq, devname); return -ENXIO; } @@ -109,7 +143,7 @@ __FUNCTION__, irq, irq_list[irq].devname); return -EBUSY; } - if (flags & IRQ_FLG_REPLACE) { + if (!(flags & IRQ_FLG_REPLACE)) { printk("%s: %s can't replace IRQ %d from %s\n", __FUNCTION__, devname, irq, irq_list[irq].devname); return -EBUSY; @@ -122,13 +156,8 @@ return 0; } -void free_irq(unsigned int irq, void *dev_id) +void sys_free_irq(unsigned int irq, void *dev_id) { - if (irq & IRQ_MACHSPEC) { - mach_free_irq(IRQ_IDX(irq), dev_id); - return; - } - if (irq < IRQ1 || irq > IRQ7) { printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); return; @@ -157,31 +186,42 @@ return 0; } -void enable_irq(unsigned int irq) +static void dummy_enable_irq(unsigned int irq) { - if ((irq & IRQ_MACHSPEC) && mach_enable_irq) - mach_enable_irq(IRQ_IDX(irq)); + printk("calling uninitialized enable_irq()\n"); } -void disable_irq(unsigned int irq) +static void dummy_disable_irq(unsigned int irq) { - if ((irq & IRQ_MACHSPEC) && mach_disable_irq) - mach_disable_irq(IRQ_IDX(irq)); + printk("calling uninitialized disable_irq()\n"); +} + +static int dummy_request_irq(unsigned int irq, + void (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + printk("calling uninitialized request_irq()\n"); + return 0; +} + +static void dummy_free_irq(unsigned int irq, void *dev_id) +{ + printk("calling uninitialized disable_irq()\n"); } asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) { - if (vec < VEC_INT1 || vec > VEC_INT7) { + if (vec >= VEC_INT1 && vec <= VEC_INT7) { + vec -= VEC_SPUR; + kstat.interrupts[vec]++; + irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); + } else { if (mach_process_int) mach_process_int(vec, fp); else panic("Can't process interrupt vector %ld\n", vec); return; } - - vec -= VEC_SPUR; - kstat.interrupts[vec]++; - irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); } int get_irq_list(char *buf) diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c --- v2.1.35/linux/arch/m68k/kernel/m68k_ksyms.c Thu Mar 27 14:39:59 1997 +++ linux/arch/m68k/kernel/m68k_ksyms.c Thu Apr 17 13:20:42 1997 @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,6 +12,8 @@ #include #include #include +#include +#include asmlinkage long long __ashrdi3 (long long, int); extern char m68k_debug_device[]; @@ -31,13 +34,15 @@ EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(mm_end_of_chunk); EXPORT_SYMBOL(m68k_debug_device); -EXPORT_SYMBOL(request_irq); -EXPORT_SYMBOL(free_irq); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(local_irq_count); + +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy); /* The following are special because they're not called explicitly (the C compiler generates them). Fortunately, diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c --- v2.1.35/linux/arch/m68k/kernel/process.c Sun Jan 26 02:07:05 1997 +++ linux/arch/m68k/kernel/process.c Thu Apr 17 13:20:42 1997 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,7 @@ goto out; /* endless idle loop with no priority at all */ + current->priority = -100; current->counter = -100; for (;;) schedule(); @@ -52,12 +54,23 @@ return ret; } -void hard_reset_now(void) +void machine_restart(char * __unused) { if (mach_reset) mach_reset(); } +void machine_halt(void) +{ +} + +void machine_power_off(void) +{ +#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF) + apm_set_power_state(APM_STATE_OFF); +#endif +} + void show_regs(struct pt_regs * regs) { printk("\n"); @@ -169,7 +182,7 @@ /* Fill in the fpu structure for a core dump. */ -int dump_fpu (struct user_m68kfp_struct *fpu) +int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) { char fpustate[216]; @@ -207,7 +220,7 @@ if (dump->start_stack < TASK_SIZE) dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; - dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump))); + dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump); sw = ((struct switch_stack *)regs) - 1; dump->regs.d1 = regs->d1; dump->regs.d2 = regs->d2; @@ -230,7 +243,7 @@ dump->regs.pc = regs->pc; dump->regs.fmtvec = (regs->format << 12) | regs->vector; /* dump floating point stuff */ - dump->u_fpvalid = dump_fpu (&dump->m68kfp); + dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp); } /* diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c --- v2.1.35/linux/arch/m68k/kernel/ptrace.c Sun Jan 26 02:07:05 1997 +++ linux/arch/m68k/kernel/ptrace.c Thu Apr 17 13:20:43 1997 @@ -324,7 +324,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; - struct user * dummy = NULL; int ret; lock_kernel(); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/setup.c linux/arch/m68k/kernel/setup.c --- v2.1.35/linux/arch/m68k/kernel/setup.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/kernel/setup.c Thu Apr 17 13:20:43 1997 @@ -55,11 +55,6 @@ static char m68k_command_line[CL_SIZE]; char saved_command_line[CL_SIZE]; -/* setup some dummy routines */ -static void dummy_waitbut(void) -{ -} - void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)); /* machine dependent keyboard functions */ int (*mach_keyb_init) (void); @@ -68,11 +63,6 @@ /* machine dependent irq functions */ void (*mach_init_IRQ) (void); void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; -int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *), - unsigned long, const char *, void *); -int (*mach_free_irq) (unsigned int, void *); -void (*mach_enable_irq) (unsigned int) = NULL; -void (*mach_disable_irq) (unsigned int) = NULL; void (*mach_get_model) (char *model) = NULL; int (*mach_get_hardware_list) (char *buffer) = NULL; int (*mach_get_irq_list) (char *) = NULL; @@ -82,19 +72,15 @@ void (*mach_gettod) (int*, int*, int*, int*, int*, int*); int (*mach_hwclk) (int, struct hwclk_time*) = NULL; int (*mach_set_clock_mmss) (unsigned long) = NULL; -void (*mach_mksound)( unsigned int count, unsigned int ticks ); void (*mach_reset)( void ); -void (*waitbut)(void) = dummy_waitbut; struct fb_info *(*mach_fb_init)(long *); long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ -void (*mach_debug_init)(void); void (*mach_video_setup) (char *, int *); #ifdef CONFIG_BLK_DEV_FD int (*mach_floppy_init) (void) = NULL; void (*mach_floppy_setup) (char *, int *) = NULL; void (*mach_floppy_eject) (void) = NULL; #endif -void (*mach_syms_export)(void) = NULL; extern int amiga_parse_bootinfo(const struct bi_record *); extern int atari_parse_bootinfo(const struct bi_record *); @@ -105,10 +91,6 @@ extern void config_sun3(void); extern void config_apollo(void); -extern void register_console(void (*proc)(const char *)); -extern void ami_serial_print(const char *str); -extern void ata_serial_print(const char *str); - #define MASK_256K 0xfffc0000 @@ -166,12 +148,6 @@ extern int _etext, _edata, _end; int i; char *p, *q; - - /* machtype is set up by head.S, thus we know our gender */ - if (MACH_IS_AMIGA) - register_console(ami_serial_print); - if (MACH_IS_ATARI) - register_console(ata_serial_print); /* The bootinfo is located right after the kernel bss */ m68k_parse_bootinfo((const struct bi_record *)&_end); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/signal.c linux/arch/m68k/kernel/signal.c --- v2.1.35/linux/arch/m68k/kernel/signal.c Fri Jan 3 08:48:37 1997 +++ linux/arch/m68k/kernel/signal.c Thu Apr 17 13:20:43 1997 @@ -291,20 +291,23 @@ tframe = frame; /* return address points to code on stack */ - put_user((ulong)(frame+4), tframe); tframe++; + + if(put_user((ulong)(frame+4), tframe)) + do_exit(SIGSEGV); + tframe++; if (current->exec_domain && current->exec_domain->signal_invmap) - put_user(current->exec_domain->signal_invmap[signr], tframe); + __put_user(current->exec_domain->signal_invmap[signr], tframe); else - put_user(signr, tframe); + __put_user(signr, tframe); tframe++; - put_user(regs->vector, tframe); tframe++; + __put_user(regs->vector, tframe); tframe++; /* "scp" parameter. points to sigcontext */ - put_user((ulong)(frame+6), tframe); tframe++; + __put_user((ulong)(frame+6), tframe); tframe++; /* set up the return code... */ - put_user(0xdefc0014,tframe); tframe++; /* addaw #20,sp */ - put_user(0x70774e40,tframe); tframe++; /* moveq #119,d0; trap #0 */ + __put_user(0xdefc0014,tframe); tframe++; /* addaw #20,sp */ + __put_user(0x70774e40,tframe); tframe++; /* moveq #119,d0; trap #0 */ /* Flush caches so the instructions will be correctly executed. (MA) */ cache_push_v ((unsigned long)frame, (int)tframe - (int)frame); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/sys_m68k.c linux/arch/m68k/kernel/sys_m68k.c --- v2.1.35/linux/arch/m68k/kernel/sys_m68k.c Sun Jan 26 02:07:05 1997 +++ linux/arch/m68k/kernel/sys_m68k.c Thu Apr 17 13:20:43 1997 @@ -34,15 +34,11 @@ int error; lock_kernel(); - error = verify_area(VERIFY_WRITE,fildes,8); - if (error) - goto out; error = do_pipe(fd); - if (error) - goto out; - put_user(fd[0],0+fildes); - put_user(fd[1],1+fildes); -out: + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } unlock_kernel(); return error; } @@ -70,10 +66,10 @@ struct mmap_arg_struct a; lock_kernel(); - error = verify_area(VERIFY_READ, arg, sizeof(*arg)); - if (error) + error = -EFAULT; + if (copy_from_user(&a, arg, sizeof(a))) goto out; - copy_from_user(&a, arg, sizeof(a)); + if (!(a.flags & MAP_ANONYMOUS)) { error = -EBADF; if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd])) @@ -98,15 +94,11 @@ asmlinkage int old_select(struct sel_arg_struct *arg) { struct sel_arg_struct a; - int ret = -EFAULT; - lock_kernel(); if (copy_from_user(&a, arg, sizeof(a))) - goto out; - ret = sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); -out: - unlock_kernel(); - return ret; + return -EFAULT; + /* sys_select() does the appropriate kernel locking */ + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); } /* @@ -134,9 +126,8 @@ ret = -EINVAL; if (!ptr) goto out; - if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long)))) + if ((ret = get_user(fourth.__pad, (void **) ptr))) goto out; - get_user(fourth.__pad, (void **)ptr); ret = sys_semctl (first, second, third, fourth); goto out; } @@ -183,22 +174,13 @@ switch (version) { case 0: default: { ulong raddr; - if ((ret = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong)))) - goto out; ret = sys_shmat (first, (char *) ptr, second, &raddr); if (ret) goto out; - put_user (raddr, (ulong *) third); - ret = 0; - goto out; - } - case 1: /* iBCS2 emulator entry point */ - ret = -EINVAL; - if (get_fs() != get_ds()) - goto out; - ret = sys_shmat (first, (char *) ptr, second, (ulong *) third); + ret = put_user (raddr, (ulong *) third); goto out; } + } case SHMDT: ret = sys_shmdt ((char *)ptr); goto out; @@ -212,8 +194,7 @@ ret = -EINVAL; goto out; } - else - ret = -EINVAL; + ret = -EINVAL; out: unlock_kernel(); return ret; diff -u --recursive --new-file v2.1.35/linux/arch/m68k/kernel/traps.c linux/arch/m68k/kernel/traps.c --- v2.1.35/linux/arch/m68k/kernel/traps.c Fri Dec 20 01:19:59 1996 +++ linux/arch/m68k/kernel/traps.c Thu Apr 17 13:20:43 1997 @@ -29,11 +29,15 @@ #include #include +#include #include #include #include #include #include +#ifdef CONFIG_KGDB +#include +#endif /* assembler routines */ asmlinkage void system_call(void); @@ -140,10 +144,9 @@ { extern int console_loglevel; console_loglevel = 15; - mach_debug_init(); } -char *vec_names[] = { +static char *vec_names[] = { "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR", "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc", "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111", @@ -162,17 +165,17 @@ "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW", "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN", "FPCP UNSUPPORTED OPERATION", - "MMU CONFIGUATION ERROR" + "MMU CONFIGURATION ERROR" }; -char *space_names[] = { +static char *space_names[] = { "Space 0", "User Data", "User Program", "Space 3", "Space 4", "Super Data", "Super Program", "CPU" }; -extern void die_if_kernel(char *,struct pt_regs *,int); +void die_if_kernel(char *,struct pt_regs *,int); asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code); @@ -184,7 +187,7 @@ unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */ #ifdef DEBUG - printk("fslw=%#lx, fa=%#lx\n", ssw, fp->un.fmt4.effaddr); + printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr); #endif if (fslw & MMU060_BPE) { @@ -194,7 +197,7 @@ "movec %/d0,%/cacr" : : : "d0" ); /* return if there's no other error */ - if (!(fslw & MMU060_ERR_BITS)) + if ((!(fslw & MMU060_ERR_BITS)) && !(fslw & MMU060_SEE)) return; } @@ -209,8 +212,13 @@ if (fslw & MMU060_MA) addr = PAGE_ALIGN(addr); do_page_fault(&fp->ptregs, addr, errorcode); - } - else { + } else if (fslw & (MMU060_SEE)){ + /* Software Emulation Error. Probably an instruction + * using an unsupported addressing mode + */ + send_sig (SIGSEGV, current, 1); + } else { + printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr); printk( "68060 access error, fslw=%lx\n", fslw ); trap_c( fp ); } @@ -349,7 +357,7 @@ } #endif /* CONFIG_M68040 */ -#if defined(CONFIG_M68020_OR_M68030) +#if defined(CPU_M68020_OR_M68030) static inline void bus_error030 (struct frame *fp) { volatile unsigned short temp; @@ -628,7 +636,7 @@ asm volatile ("ploadr #2,%0@" : /* no outputs */ : "a" (addr)); } -#endif /* CONFIG_M68020_OR_M68030 */ +#endif /* CPU_M68020_OR_M68030 */ asmlinkage void buserr_c(struct frame *fp) { @@ -651,7 +659,7 @@ access_error040 (fp); break; #endif -#if defined (CONFIG_M68020_OR_M68030) +#if defined (CPU_M68020_OR_M68030) case 0xa: case 0xb: bus_error030 (fp); @@ -675,6 +683,11 @@ static void dump_stack(struct frame *fp) { +#ifdef CONFIG_KGDB + /* This will never return to here, if kgdb has been initialized. And if + * it returns from there, then to where the error happened... */ + enter_kgdb( &fp->ptregs ); +#else unsigned long *stack, *endstack, addr, module_start, module_end; extern char _start, _etext; int i; @@ -772,10 +785,15 @@ for (i = 0; i < 10; i++) printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]); printk ("\n"); +#endif } void bad_super_trap (struct frame *fp) { +#ifdef CONFIG_KGDB + /* Save the register dump if we'll enter kgdb anyways */ + if (!kgdb_initialized) { +#endif console_verbose(); if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0])) printk ("*** %s *** FORMAT=%X\n", @@ -805,6 +823,9 @@ fp->ptregs.pc); } printk ("Current process id is %d\n", current->pid); +#ifdef CONFIG_KGDB + } +#endif die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); } @@ -863,7 +884,7 @@ case VEC_FPOVER: case VEC_FPNAN: { - unsigned char fstate[216]; + unsigned char fstate[FPSTATESIZE]; __asm__ __volatile__ (".chip 68k/68881\n\t" "fsave %0@\n\t" @@ -905,9 +926,13 @@ if (!(fp->sr & PS_S)) return; +#ifdef CONFIG_KGDB + /* Save the register dump if we'll enter kgdb anyways */ + if (!kgdb_initialized) { +#endif console_verbose(); printk("%s: %08x\n",str,nr); - printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); + printk("PC: [<%08lx>]\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", fp->d0, fp->d1, fp->d2, fp->d3); printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", @@ -917,6 +942,18 @@ printk("Corrupted stack page\n"); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, current->kernel_stack_page); +#ifdef CONFIG_KGDB + } +#endif dump_stack((struct frame *)fp); + do_exit(SIGSEGV); +} + +/* + * This function is called if an error occur while accessing + * user-space from the fpsp040 code. + */ +asmlinkage void fpsp040_die(void) +{ do_exit(SIGSEGV); } diff -u --recursive --new-file v2.1.35/linux/arch/m68k/lib/checksum.c linux/arch/m68k/lib/checksum.c --- v2.1.35/linux/arch/m68k/lib/checksum.c Fri Jan 3 08:48:37 1997 +++ linux/arch/m68k/lib/checksum.c Thu Apr 17 13:20:43 1997 @@ -19,8 +19,8 @@ * (%1). Thanks to Roman Hodek for pointing this out. * B: GCC seems to mess up if one uses too many * data-registers to hold input values and one tries to - * specify d0 and d1 as scratch registers. Letting gcc choose these - * registers itself solves the problem. + * specify d0 and d1 as scratch registers. Letting gcc + * choose these registers itself solves the problem. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -124,13 +124,20 @@ /* - * copy from user space while checksumming, otherwise like csum_partial + * copy from user space while checksumming, with exception handling. */ unsigned int -csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum) +csum_partial_copy_from_user(const char *src, char *dst, int len, + int sum, int *csum_err) { + /* + * GCC doesn't like more than 10 operands for the asm + * statements so we have to use tmp2 for the error + * code. + */ unsigned long tmp1, tmp2; + __asm__("movel %2,%4\n\t" "btst #1,%4\n\t" /* Check alignment */ "jeq 2f\n\t" @@ -226,27 +233,49 @@ "6:\t" "addl %5,%0\n\t" /* now add rest long to sum */ "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "7:\n" + "addxl %5,%0\n\t" /* add X bit */ + "7:\t" + "clrl %5\n" /* no error - clear return value */ + "8:\n" + ".section .fixup,\"ax\"\n" + ".even\n" + "9:\t" + "moveq #-14,%5\n\t" /* -EFAULT, out of inputs to asm ;( */ + "jra 8b\n" + ".previous\n" ".section __ex_table,\"a\"\n" - ".long 10b,7b\n" - ".long 11b,7b\n" - ".long 12b,7b\n" - ".long 13b,7b\n" - ".long 14b,7b\n" - ".long 15b,7b\n" - ".long 16b,7b\n" - ".long 17b,7b\n" - ".long 18b,7b\n" - ".long 19b,7b\n" - ".long 20b,7b\n" - ".long 21b,7b\n" + ".long 10b,9b\n" + ".long 11b,9b\n" + ".long 12b,9b\n" + ".long 13b,9b\n" + ".long 14b,9b\n" + ".long 15b,9b\n" + ".long 16b,9b\n" + ".long 17b,9b\n" + ".long 18b,9b\n" + ".long 19b,9b\n" + ".long 20b,9b\n" + ".long 21b,9b\n" ".previous" : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), - "=&d" (tmp1), "=&d" (tmp2) + "=&d" (tmp1), "=d" (tmp2) : "0" (sum), "1" (len), "2" (src), "3" (dst) ); + + *csum_err = tmp2; + return(sum); +} + +/* + * This one will go away soon. + */ +unsigned int +csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum) +{ + int dummy; + + return csum_partial_copy_from_user(src, dst, len, sum, &dummy); } /* * copy from kernel space while checksumming, otherwise like csum_partial diff -u --recursive --new-file v2.1.35/linux/arch/m68k/lib/semaphore.S linux/arch/m68k/lib/semaphore.S --- v2.1.35/linux/arch/m68k/lib/semaphore.S Fri Nov 22 05:56:35 1996 +++ linux/arch/m68k/lib/semaphore.S Thu Apr 17 13:20:43 1997 @@ -9,18 +9,26 @@ #include /* - * "down_failed" is called with the eventual return address - * in %a0, and the address of the semaphore in %a1. We need - * to call "__down()", and then re-try until we succeed.. + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. */ ENTRY(__down_failed) moveml %a0/%d0/%d1,-(%sp) -1: movel %a1,-(%sp) + movel %a1,-(%sp) jbsr SYMBOL_NAME(__down) movel (%sp)+,%a1 - subql #1,(%a1) - jmi 1b movel (%sp)+,%d0 + movel (%sp)+,%d1 + rts + +ENTRY(__down_failed_interruptible) + movel %a0,-(%sp) + movel %d1,-(%sp) + movel %a1,-(%sp) + jbsr SYMBOL_NAME(__down_interruptible) + movel (%sp)+,%a1 movel (%sp)+,%d1 rts diff -u --recursive --new-file v2.1.35/linux/arch/m68k/mm/extable.c linux/arch/m68k/mm/extable.c --- v2.1.35/linux/arch/m68k/mm/extable.c Fri Dec 27 02:03:20 1996 +++ linux/arch/m68k/mm/extable.c Thu Apr 17 13:20:43 1997 @@ -46,7 +46,7 @@ if (mp->ex_table_start == NULL) continue; ret = search_one_table(mp->ex_table_start, - mp->ex_table_stop-1, addr); + mp->ex_table_end-1, addr); if (ret) return ret; } #endif diff -u --recursive --new-file v2.1.35/linux/arch/m68k/mm/fault.c linux/arch/m68k/mm/fault.c --- v2.1.35/linux/arch/m68k/mm/fault.c Sat Dec 21 04:24:02 1996 +++ linux/arch/m68k/mm/fault.c Thu Apr 17 13:20:43 1997 @@ -108,10 +108,7 @@ up(&mm->mmap_sem); /* Are we prepared to handle this fault? */ - if (CPU_IS_060 && regs->format == 4) - fault_pc = ((struct frame *)regs)->un.fmt4.pc; - else - fault_pc = regs->pc; + fault_pc = regs->pc; if ((fixup = search_exception_table(fault_pc)) != 0) { struct pt_regs *tregs; printk(KERN_DEBUG "Exception at [<%lx>] (%lx)\n", fault_pc, fixup); diff -u --recursive --new-file v2.1.35/linux/arch/m68k/mm/init.c linux/arch/m68k/mm/init.c --- v2.1.35/linux/arch/m68k/mm/init.c Mon Apr 14 16:28:06 1997 +++ linux/arch/m68k/mm/init.c Thu Apr 17 13:20:43 1997 @@ -109,6 +109,8 @@ else ptablep = (pte_t *)__get_free_page(GFP_KERNEL); + flush_page_to_ram((unsigned long) ptablep); + flush_tlb_kernel_page((unsigned long) ptablep); nocache_page ((unsigned long)ptablep); return ptablep; @@ -293,8 +295,6 @@ { int chunk; unsigned long mem_avail = 0; - /* pointer to page table for kernel stacks */ - extern unsigned long availmem; #ifdef DEBUG { @@ -324,21 +324,12 @@ for (chunk = 0; chunk < m68k_num_memory; chunk++) { mem_avail = map_chunk (m68k_memory[chunk].addr, - m68k_memory[chunk].size, &availmem); + m68k_memory[chunk].size, &start_mem); } flush_tlb_all(); #ifdef DEBUG printk ("memory available is %ldKB\n", mem_avail >> 10); -#endif - - /* - * virtual address after end of kernel - * "availmem" is setup by the code in head.S. - */ - start_mem = availmem; - -#ifdef DEBUG printk ("start_mem is %#lx\nvirtual_end is %#lx\n", start_mem, end_mem); #endif @@ -401,7 +392,7 @@ printk ("before free_area_init\n"); #endif - return free_area_init (start_mem, end_mem); + return PAGE_ALIGN(free_area_init (start_mem, end_mem)); } void mem_init(unsigned long start_mem, unsigned long end_mem) diff -u --recursive --new-file v2.1.35/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c --- v2.1.35/linux/arch/m68k/mm/memory.c Fri Dec 20 01:19:59 1996 +++ linux/arch/m68k/mm/memory.c Thu Apr 17 13:20:43 1997 @@ -63,11 +63,12 @@ return 0; } - if (!(dp->page = __get_free_page (GFP_KERNEL))) { + if (!(dp->page = get_free_page (GFP_KERNEL))) { kfree (dp); return 0; } + flush_tlb_kernel_page((unsigned long) dp->page); nocache_page (dp->page); dp->alloced = 0; @@ -210,10 +211,11 @@ return NULL; } if (!(page = kptr_pages.page[i])) { - if (!(page = (pmd_tablepage *)__get_free_page(GFP_KERNEL))) { + if (!(page = (pmd_tablepage *)get_free_page(GFP_KERNEL))) { printk("No space for kernel pointer table!\n"); return NULL; } + flush_tlb_kernel_page((unsigned long) page); nocache_page((u_long)(kptr_pages.page[i] = page)); } asm volatile("bfset %0@{%1,#1}" @@ -306,21 +308,31 @@ if (CPU_IS_030) { unsigned long ttreg; - asm volatile( "pmove %/tt0,%0@" : : "a" (&ttreg) ); + asm volatile( ".chip 68030\n\t" + "pmove %/tt0,%0@\n\t" + ".chip 68k" + : : "a" (&ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; - asm volatile( "pmove %/tt1,%0@" : : "a" (&ttreg) ); + asm volatile( ".chip 68030\n\t" + "pmove %/tt1,%0@\n\t" + ".chip 68k" + : : "a" (&ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; } - else { - register unsigned long ttreg __asm__( "d0" ); + else if (CPU_IS_040_OR_060) { + unsigned long ttreg; - asm volatile( ".long 0x4e7a0006" /* movec %dtt0,%d0 */ + asm volatile( ".chip 68040\n\t" + "movec %%dtt0,%0\n\t" + ".chip 68k" : "=d" (ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; - asm volatile( ".long 0x4e7a0007" /* movec %dtt1,%d0 */ + asm volatile( ".chip 68040\n\t" + "movec %%dtt1,%0\n\t" + ".chip 68k" : "=d" (ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; diff -u --recursive --new-file v2.1.35/linux/arch/sparc/defconfig linux/arch/sparc/defconfig --- v2.1.35/linux/arch/sparc/defconfig Mon Apr 14 16:28:06 1997 +++ linux/arch/sparc/defconfig Thu Apr 17 13:20:43 1997 @@ -145,7 +145,7 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S --- v2.1.35/linux/arch/sparc/kernel/entry.S Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/entry.S Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.137 1997/04/14 05:38:17 davem Exp $ +/* $Id: entry.S,v 1.138 1997/04/15 09:00:50 davem Exp $ * arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -301,15 +301,26 @@ mov %l7, %o0 ! irq level call C_LABEL(handler_irq) add %sp, REGWIN_SZ, %o1 ! pt_regs ptr - -#if 1 /* ndef __SMP__ */ /* You don't want to know... -DaveM */ wr %l0, PSR_ET, %psr WRITE_PAUSE -#endif RESTORE_ALL #ifdef __SMP__ + /* SMP per-cpu ticker interrupts are handled specially. */ +smp_ticker: + bne real_irq_continue + or %l0, PSR_PIL, %g2 + wr %g2, 0x0, %psr + WRITE_PAUSE + wr %g2, PSR_ET, %psr + WRITE_PAUSE + call C_LABEL(smp_percpu_timer_interrupt) + add %sp, REGWIN_SZ, %o0 + wr %l0, PSR_ET, %psr + WRITE_PAUSE + RESTORE_ALL + /* Here is where we check for possible SMP IPI passed to us * on some level other than 15 which is the NMI and only used * for cross calls. That has a seperate entry point below. @@ -322,8 +333,9 @@ sll %o3, 12, %o3 ld [%o5 + %o3], %o1 andcc %o1, %o4, %g0 - be real_irq_continue - cmp %l7, 13 + be,a smp_ticker + cmp %l7, 14 + cmp %l7, 13 add %o5, %o3, %o5 bne,a 1f sethi %hi(0x40000000), %o2 diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S --- v2.1.35/linux/arch/sparc/kernel/head.S Mon Mar 17 14:54:20 1997 +++ linux/arch/sparc/kernel/head.S Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.79 1997/03/04 16:26:31 jj Exp $ +/* $Id: head.S,v 1.81 1997/04/16 07:15:48 davem Exp $ * head.S: The initial boot code for the Sparc port of Linux. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c --- v2.1.35/linux/arch/sparc/kernel/irq.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/irq.c Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.66 1997/04/14 05:38:21 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 @@ -41,6 +41,10 @@ #include #include +#ifdef __SMP_PROF__ +extern volatile unsigned long smp_local_timer_ticks[1+NR_CPUS]; +#endif + /* * Dave Redman (djhr@tadpole.co.uk) * @@ -71,11 +75,11 @@ void (*disable_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic; void (*enable_pil_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic; void (*disable_pil_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic; -void (*clear_clock_irq)( void ) = irq_panic; -void (*clear_profile_irq)( void ) = irq_panic; -void (*load_profile_irq)( unsigned int ) = (void (*)(unsigned int)) irq_panic; -void (*init_timers)( void (*)(int, void *,struct pt_regs *)) = - (void (*)( void (*)(int, void *,struct pt_regs *))) irq_panic; +void (*clear_clock_irq)(void) = irq_panic; +void (*clear_profile_irq)(int) = (void (*)(int)) irq_panic; +void (*load_profile_irq)(int, unsigned int) = (void (*)(int, unsigned int)) irq_panic; +void (*init_timers)(void (*)(int, void *,struct pt_regs *)) = + (void (*)(void (*)(int, void *,struct pt_regs *))) irq_panic; #ifdef __SMP__ void (*set_cpu_int)(int, int); @@ -128,6 +132,109 @@ return len; } +#ifdef __SMP_PROF__ + +static unsigned int int_count[NR_CPUS][NR_IRQS] = {{0},}; + +extern unsigned int prof_multiplier[NR_CPUS]; +extern unsigned int prof_counter[NR_CPUS]; + +int get_smp_prof_list(char *buf) { + int i,j, len = 0; + struct irqaction * action; + unsigned long sum_spins = 0; + unsigned long sum_spins_syscall = 0; + unsigned long sum_spins_sys_idle = 0; + unsigned long sum_smp_idle_count = 0; + unsigned long sum_local_timer_ticks = 0; + + for (i=0;ihandler) + continue; + len += sprintf(buf+len, "%3d: %10d ", + i, kstat.interrupts[i]); + for (j=0;jflags & SA_INTERRUPT) ? '+' : ' ', + action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); + } + len+=sprintf(buf+len, "LCK: %10lu", + sum_spins); + + for (i=0;ihandler(irq, action->dev_id, regs); action = action->next; } while (action); - irq_exit(cpu, irq); + irq_exit(cpu, cpu_irq); enable_pil_irq(cpu_irq); } @@ -432,7 +395,7 @@ irq_enter(cpu, irq); floppy_interrupt(irq, dev_id, regs); irq_exit(cpu, irq); - disable_pil_irq(irq); + enable_pil_irq(irq); } #endif @@ -596,12 +559,12 @@ */ unsigned long probe_irq_on(void) { - return 0; + return 0; } int probe_irq_off(unsigned long mask) { - return 0; + return 0; } /* djhr diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c --- v2.1.35/linux/arch/sparc/kernel/ptrace.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/ptrace.c Thu Apr 17 13:20:43 1997 @@ -889,13 +889,12 @@ asmlinkage void syscall_trace(void) { - lock_kernel(); #ifdef DEBUG_PTRACE printk("%s [%d]: syscall_trace\n", current->comm, current->pid); #endif if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS)) - goto out; + return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; current->tss.flags ^= MAGIC_CONSTANT; @@ -911,9 +910,9 @@ current->pid, current->exit_code); #endif if (current->exit_code) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= (1 << (current->exit_code - 1)); + spin_unlock_irq(¤t->sigmask_lock); } current->exit_code = 0; -out: - unlock_kernel(); } diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c --- v2.1.35/linux/arch/sparc/kernel/signal.c Mon Mar 17 14:54:21 1997 +++ linux/arch/sparc/kernel/signal.c Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.72 1997/03/03 16:51:43 jj Exp $ +/* $Id: signal.c,v 1.73 1997/04/16 05:56:05 davem Exp $ * linux/arch/sparc/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -28,7 +28,8 @@ #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) -asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options); +asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, + int options, unsigned long *ru); extern void fpsave(unsigned long *fpregs, unsigned long *fsr, void *fpqueue, unsigned long *fpqdepth); @@ -85,12 +86,15 @@ * atomically swap in the new signal mask, and wait for a signal. * This is really tricky on the Sparc, watch out... */ -asmlinkage inline void _sigpause_common(unsigned int set, struct pt_regs *regs) +asmlinkage void _sigpause_common(unsigned int set, struct pt_regs *regs) { unsigned long mask; + spin_lock_irq(¤t->sigmask_lock); mask = current->blocked; current->blocked = set & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + regs->pc = regs->npc; regs->npc += 4; @@ -115,16 +119,12 @@ asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) { - lock_kernel(); _sigpause_common(set, regs); - unlock_kernel(); } asmlinkage void do_sigsuspend (struct pt_regs *regs) { - lock_kernel(); _sigpause_common(regs->u_regs[UREG_I0], regs); - unlock_kernel(); } @@ -159,26 +159,20 @@ struct new_signal_frame *sf; unsigned long up_psr, pc, npc, mask; - lock_kernel(); sf = (struct new_signal_frame *) regs->u_regs [UREG_FP]; /* 1. Make sure we are not getting garbage from the user */ - if (verify_area (VERIFY_READ, sf, sizeof (*sf))){ - do_exit (SIGSEGV); - goto out; - } - if (((uint) sf) & 3){ - do_exit (SIGSEGV); - goto out; - } + if (verify_area (VERIFY_READ, sf, sizeof (*sf))) + goto segv_and_exit; + + if (((uint) sf) & 3) + goto segv_and_exit; __get_user(pc, &sf->info.si_regs.pc); __get_user(npc, &sf->info.si_regs.npc); - if ((pc | npc) & 3) { - do_exit (SIGSEGV); - goto out; - } + if ((pc | npc) & 3) + goto segv_and_exit; /* 2. Restore the state */ up_psr = regs->psr; @@ -191,43 +185,55 @@ if (sf->fpu_save) restore_fpu_state(regs, sf->fpu_save); + /* This is pretty much atomic, no amount locking would prevent + * the races which exist anyways. + */ __get_user(mask, &sf->info.si_mask); current->blocked = (mask & _BLOCKABLE); -out: + return; + +segv_and_exit: + /* Ugh, we need to grab master lock in these rare cases ;-( */ + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); } asmlinkage void do_sigreturn(struct pt_regs *regs) { struct sigcontext *scptr; - unsigned long pc, npc, psr; + unsigned long pc, npc, psr, mask; - lock_kernel(); synchronize_user_stack(); - if (current->tss.new_signal){ - do_new_sigreturn (regs); - goto out; - } + + if (current->tss.new_signal) + return do_new_sigreturn (regs); + scptr = (struct sigcontext *) regs->u_regs[UREG_I0]; + /* Check sanity of the user arg. */ if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext)) || - (((unsigned long) scptr) & 3)) { - printk("%s [%d]: do_sigreturn, scptr is invalid at " - "pc<%08lx> scptr<%p>\n", - current->comm, current->pid, regs->pc, scptr); - do_exit(SIGSEGV); - } + (((unsigned long) scptr) & 3)) + goto segv_and_exit; + __get_user(pc, &scptr->sigc_pc); __get_user(npc, &scptr->sigc_npc); + if((pc | npc) & 3) - do_exit(SIGSEGV); /* Nice try. */ + goto segv_and_exit; + + /* This is pretty much atomic, no amount locking would prevent + * the races which exist anyways. + */ + __get_user(mask, &scptr->sigc_mask); + current->blocked = (mask & _BLOCKABLE); - __get_user(current->blocked, &scptr->sigc_mask); - current->blocked &= _BLOCKABLE; __get_user(current->tss.sstk_info.cur_status, &scptr->sigc_onstack); current->tss.sstk_info.cur_status &= 1; + regs->pc = pc; regs->npc = npc; + __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp); __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0); __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1); @@ -236,7 +242,12 @@ __get_user(psr, &scptr->sigc_psr); regs->psr &= ~(PSR_ICC); regs->psr |= (psr & PSR_ICC); -out: + return; + +segv_and_exit: + /* Ugh, we need to grab master lock in these rare cases ;-( */ + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); } @@ -252,9 +263,8 @@ return 0; } -static inline void -setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, - struct pt_regs *regs, int signr, unsigned long oldmask) +static void setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, + struct pt_regs *regs, int signr, unsigned long oldmask) { struct signal_sframe *sframep; struct sigcontext *sc; @@ -274,8 +284,7 @@ /* Don't change signal code and address, so that * post mortem debuggers can have a look. */ - do_exit(SIGILL); - return; + goto sigill_and_return; } sc = &sframep->sig_context; @@ -319,6 +328,13 @@ regs->u_regs[UREG_FP] = (unsigned long) sframep; regs->pc = (unsigned long) sa->sa_handler; regs->npc = (regs->pc + 4); + return; + +sigill_and_return: + /* Ugh, we need to grab master lock in these rare cases ;-( */ + lock_kernel(); + do_exit(SIGILL); + unlock_kernel(); } @@ -353,9 +369,8 @@ current->used_math = 0; } - -static inline void -new_setup_frame(struct sigaction *sa, struct pt_regs *regs, int signo, unsigned long oldmask) +static void new_setup_frame(struct sigaction *sa, struct pt_regs *regs, + int signo, unsigned long oldmask) { struct new_signal_frame *sf; int sigframe_size; @@ -369,16 +384,13 @@ sf = (struct new_signal_frame *)(regs->u_regs[UREG_FP] - sigframe_size); - if (invalid_frame_pointer (sf, sigframe_size)){ - do_exit(SIGILL); - return; - } + if (invalid_frame_pointer (sf, sigframe_size)) + goto sigill_and_return; - if (current->tss.w_saved != 0){ + if (current->tss.w_saved != 0) { printk ("%s [%d]: Invalid user stack frame for " "signal delivery.\n", current->comm, current->pid); - do_exit (SIGILL); - return; + goto sigill_and_return; } /* 2. Save the current process state */ @@ -411,6 +423,12 @@ /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); + return; + +sigill_and_return: + lock_kernel(); + do_exit(SIGILL); + unlock_kernel(); } @@ -435,8 +453,7 @@ #ifdef DEBUG_SIGNALS printk ("Invalid stack frame\n"); #endif - do_exit(SIGILL); - return; + goto sigill_and_return; } /* Start with a clean frame pointer and fill it */ @@ -525,23 +542,26 @@ regs->u_regs[UREG_I1] = (uint) si; regs->u_regs[UREG_I2] = (uint) uc; } + return; + +sigill_and_return: + lock_kernel(); + do_exit(SIGILL); + unlock_kernel(); } -asmlinkage int -svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs) +asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs) { svr4_gregset_t *gr; svr4_mcontext_t *mc; - int ret = -EFAULT; - lock_kernel(); synchronize_user_stack(); - if (current->tss.w_saved){ - printk ("Uh oh, w_saved is not zero (%ld)\n", current->tss.w_saved); - do_exit (SIGSEGV); - } + + if (current->tss.w_saved) + goto sigsegv_and_return; + if(clear_user(uc, sizeof (*uc))) - goto out; + return -EFAULT; /* Setup convenience variables */ mc = &uc->mcontext; @@ -568,58 +588,53 @@ /* The register file is not saved * we have already stuffed all of it with sync_user_stack */ - ret = 0; -out: + return 0; + +sigsegv_and_return: + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); - return ret; + return -EFAULT; } - /* Set the context for a svr4 application, this is Solaris way to sigreturn */ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs) { struct thread_struct *tp = ¤t->tss; svr4_gregset_t *gr; - unsigned long pc, npc, psr; - int ret = -EINTR; + unsigned long pc, npc, psr, mask; - lock_kernel(); /* Fixme: restore windows, or is this already taken care of in * svr4_setup_frame when sync_user_windows is done? */ flush_user_windows(); - if (tp->w_saved){ - printk ("Uh oh, w_saved is: 0x%lx\n", tp->w_saved); - do_exit(SIGSEGV); - goto out; - } - if (((uint) c) & 3){ - printk ("Unaligned structure passed\n"); - do_exit (SIGSEGV); - goto out; - } + if (tp->w_saved) + goto sigsegv_and_return; - if(!__access_ok((unsigned long)c, sizeof(*c))) { - /* Miguel, add nice debugging msg _here_. ;-) */ - do_exit(SIGSEGV); - goto out; - } + if (((uint) c) & 3) + goto sigsegv_and_return; + + if(!__access_ok((unsigned long)c, sizeof(*c))) + goto sigsegv_and_return; /* Check for valid PC and nPC */ gr = &c->mcontext.greg; __get_user(pc, &((*gr)[SVR4_PC])); __get_user(npc, &((*gr)[SVR4_NPC])); - if((pc | npc) & 3) { - printk ("setcontext, PC or nPC were bogus\n"); - do_exit (SIGSEGV); - goto out; - } + + if((pc | npc) & 3) + goto sigsegv_and_return; + /* Retrieve information from passed ucontext */ - /* note that nPC is ored a 1, this is used to inform entry.S */ - /* that we don't want it to mess with our PC and nPC */ - __get_user(current->blocked, &c->sigmask.sigbits [0]); - current->blocked &= _BLOCKABLE; + /* note that nPC is ored a 1, this is used to inform entry.S */ + /* that we don't want it to mess with our PC and nPC */ + + /* This is pretty much atomic, no amount locking would prevent + * the races which exist anyways. + */ + __get_user(mask, &c->sigmask.sigbits [0]); + current->blocked = (mask & _BLOCKABLE); regs->pc = pc; regs->npc = npc | 1; __get_user(regs->y, &((*gr) [SVR4_Y])); @@ -630,9 +645,13 @@ /* Restore g[1..7] and o[0..7] registers */ copy_from_user(®s->u_regs [UREG_G1], &(*gr)[SVR4_G1], sizeof (long) * 7); copy_from_user(®s->u_regs [UREG_I0], &(*gr)[SVR4_O0], sizeof (long) * 8); -out: + return 0; + +sigsegv_and_return: + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); - return ret; + return -EFAULT; } static inline void handle_signal(unsigned long signr, struct sigaction *sa, @@ -649,8 +668,11 @@ } if(sa->sa_flags & SA_ONESHOT) sa->sa_handler = NULL; - if(!(sa->sa_flags & SA_NOMASK)) + if(!(sa->sa_flags & SA_NOMASK)) { + spin_lock_irq(¤t->sigmask_lock); current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + } } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -683,17 +705,23 @@ unsigned long signr, mask = ~current->blocked; struct sigaction *sa; int svr4_signal = current->personality == PER_SVR4; - int ret; - lock_kernel(); while ((signr = current->signal & mask) != 0) { signr = ffz(~signr); - clear_bit(signr, ¤t->signal); + + spin_lock_irq(¤t->sigmask_lock); + current->signal &= ~(1 << signr); + spin_unlock_irq(¤t->sigmask_lock); + sa = current->sig->action + signr; signr++; if ((current->flags & PF_PTRACED) && signr != SIGKILL) { current->exit_code = signr; current->state = TASK_STOPPED; + + /* This happens to be SMP safe so no need to + * grab master kernel lock even in this case. + */ notify_parent(current); schedule(); if (!(signr = current->exit_code)) @@ -702,7 +730,9 @@ if (signr == SIGSTOP) continue; if (_S(signr) & current->blocked) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr); + spin_unlock_irq(¤t->sigmask_lock); continue; } sa = current->sig->action + signr - 1; @@ -710,7 +740,14 @@ if(sa->sa_handler == SIG_IGN) { if(signr != SIGCHLD) continue; - while(sys_waitpid(-1,NULL,WNOHANG) > 0); + + /* sys_wait4() grabs the master kernel lock, so + * we need not do so, that sucker should be + * threaded and would not be that difficult to + * do anyways. + */ + while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + ; continue; } if(sa->sa_handler == SIG_DFL) { @@ -721,6 +758,9 @@ continue; case SIGTSTP: case SIGTTIN: case SIGTTOU: + /* The operations performed by is_orphaned_pgrp() + * are protected by the tasklist_lock. + */ if (is_orphaned_pgrp(current->pgrp)) continue; @@ -729,6 +769,8 @@ continue; current->state = TASK_STOPPED; current->exit_code = signr; + + /* notify_parent() is SMP safe */ if(!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags & SA_NOCLDSTOP)) notify_parent(current); @@ -748,16 +790,21 @@ #endif /* fall through */ default: + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr & 0x7f); + spin_unlock_irq(¤t->sigmask_lock); + current->flags |= PF_SIGNALED; + + lock_kernel(); /* 8-( */ do_exit(signr); + unlock_kernel(); } } if(restart_syscall) syscall_restart(orig_i0, regs, sa); handle_signal(signr, sa, oldmask, regs, svr4_signal); - ret = 1; - goto out; + return 1; } if(restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || @@ -768,10 +815,7 @@ regs->pc -= 4; regs->npc -= 4; } - ret = 0; -out: - unlock_kernel(); - return ret; + return 0; } asmlinkage int diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/smp.c linux/arch/sparc/kernel/smp.c --- v2.1.35/linux/arch/sparc/kernel/smp.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/smp.c Tue Apr 15 21:47:23 1997 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -139,6 +140,8 @@ local_flush_tlb_all(); } +static void smp_setup_percpu_timer(void); + void smp_callin(void) { int cpuid = smp_processor_id(); @@ -146,6 +149,10 @@ local_flush_cache_all(); local_flush_tlb_all(); set_irq_udt(mid_xlate[boot_cpu_id]); + + /* Get our local ticker going. */ + smp_setup_percpu_timer(); + calibrate_delay(); smp_store_cpu_info(cpuid); local_flush_cache_all(); @@ -215,6 +222,7 @@ klock_info.akp = boot_cpu_id; smp_store_cpu_info(boot_cpu_id); set_irq_udt(mid_xlate[boot_cpu_id]); + smp_setup_percpu_timer(); local_flush_cache_all(); if(linux_num_cpus == 1) return; /* Not an MP box. */ @@ -506,4 +514,102 @@ __sti(); while(1) barrier(); +} + +/* Protects counters touched during level14 ticker */ +spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED; + +/* 32-bit Sparc specific profiling function. */ +static inline void sparc_do_profile(unsigned long pc) +{ + if(prof_buffer && current->pid) { + extern int _stext; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + + spin_lock(&ticker_lock); + if(pc < prof_len) + prof_buffer[pc]++; + else + prof_buffer[prof_len - 1]++; + spin_unlock(&ticker_lock); + } +} + +volatile unsigned long smp_local_timer_ticks[1+NR_CPUS]={0,}; + +unsigned int prof_multiplier[NR_CPUS]; +unsigned int prof_counter[NR_CPUS]; + +extern void update_one_process(struct task_struct *p, unsigned long ticks, + unsigned long user, unsigned long system); + +void smp_percpu_timer_interrupt(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + clear_profile_irq(mid_xlate[cpu]); + if(!user_mode(regs)) + sparc_do_profile(regs->pc); + if(!--prof_counter[cpu]) { + int user = user_mode(regs); + if(current->pid) { + update_one_process(current, 1, user, !user); + + if(--current->counter < 0) { + current->counter = 0; + need_resched = 1; + } + + spin_lock(&ticker_lock); + if(user) { + if(current->priority < DEF_PRIORITY) + kstat.cpu_nice++; + else + kstat.cpu_user++; + } else { + kstat.cpu_system++; + } + spin_unlock(&ticker_lock); + } + prof_counter[cpu] = prof_multiplier[cpu]; + } +#ifdef __SMP_PROF__ + smp_local_timer_ticks[cpu]++; +#endif +} + +extern unsigned int lvl14_resolution; + +static void smp_setup_percpu_timer(void) +{ + int cpu = smp_processor_id(); + + prof_counter[cpu] = prof_multiplier[cpu] = 1; + load_profile_irq(mid_xlate[cpu], lvl14_resolution); + + if(cpu == boot_cpu_id) + enable_pil_irq(14); +} + +int setup_profiling_timer(unsigned int multiplier) +{ + int i; + unsigned long flags; + + /* Prevent level14 ticker IRQ flooding. */ + if((!multiplier) || (lvl14_resolution / multiplier) < 500) + return -EINVAL; + + save_and_cli(flags); + for(i = 0; i < NR_CPUS; i++) { + if(cpu_present_map & (1 << i)) { + load_profile_irq(mid_xlate[i], lvl14_resolution / multiplier); + prof_multiplier[i] = multiplier; + } + } + restore_flags(flags); + + return 0; } diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c --- v2.1.35/linux/arch/sparc/kernel/sparc_ksyms.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/sparc_ksyms.c Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.54 1997/04/14 05:38:25 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) @@ -87,7 +87,18 @@ EXPORT_SYMBOL_PRIVATE(_lock_kernel); EXPORT_SYMBOL_PRIVATE(_unlock_kernel); EXPORT_SYMBOL_PRIVATE(_spinlock_waitfor); +EXPORT_SYMBOL_PRIVATE(_rw_read_enter); +EXPORT_SYMBOL_PRIVATE(_rw_read_exit); +EXPORT_SYMBOL_PRIVATE(_rw_write_enter); EXPORT_SYMBOL(__sparc_bh_counter); +#ifdef __SMP__ +EXPORT_SYMBOL_PRIVATE(_irq_enter); +EXPORT_SYMBOL_PRIVATE(_irq_exit); +EXPORT_SYMBOL_PRIVATE(_global_restore_flags); +EXPORT_SYMBOL_PRIVATE(_global_sti); +EXPORT_SYMBOL_PRIVATE(_global_cli); +#endif + EXPORT_SYMBOL(page_offset); EXPORT_SYMBOL(stack_top); @@ -110,10 +121,6 @@ EXPORT_SYMBOL(global_irq_lock); EXPORT_SYMBOL(global_bh_lock); EXPORT_SYMBOL(global_irq_count); -EXPORT_SYMBOL(__global_cli); -EXPORT_SYMBOL(__global_sti); -EXPORT_SYMBOL(__global_save_flags); -EXPORT_SYMBOL(__global_restore_flags); EXPORT_SYMBOL(synchronize_irq); #endif diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/sun4c_irq.c linux/arch/sparc/kernel/sun4c_irq.c --- v2.1.35/linux/arch/sparc/kernel/sun4c_irq.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/sun4c_irq.c Tue Apr 15 21:47:23 1997 @@ -111,12 +111,12 @@ clear_intr = sun4c_timers->timer_limit10; } -static void sun4c_clear_profile_irq(void) +static void sun4c_clear_profile_irq(int cpu) { /* Errm.. not sure how to do this.. */ } -static void sun4c_load_profile_irq(unsigned int limit) +static void sun4c_load_profile_irq(int cpu, unsigned int limit) { /* Errm.. not sure how to do this.. */ } diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/sun4m_irq.c linux/arch/sparc/kernel/sun4m_irq.c --- v2.1.35/linux/arch/sparc/kernel/sun4m_irq.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/sun4m_irq.c Thu Apr 17 13:20:43 1997 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -145,7 +146,7 @@ /*11*/ SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY, /*12*/ SUN4M_INT_SERIAL | SUN4M_INT_KBDMS, /*13*/ SUN4M_INT_AUDIO, -/*14*/ 0x00000000, +/*14*/ SUN4M_INT_E14, /*15*/ 0x00000000 }; @@ -196,37 +197,18 @@ clear_intr = sun4m_timers->l10_timer_limit; } -static void sun4m_clear_profile_irq(void) +static void sun4m_clear_profile_irq(int cpu) { volatile unsigned int clear; - clear = sun4m_timers->cpu_timers[0].l14_timer_limit; + clear = sun4m_timers->cpu_timers[cpu].l14_timer_limit; } -static void sun4m_load_profile_irq(unsigned int limit) +static void sun4m_load_profile_irq(int cpu, unsigned int limit) { - sun4m_timers->cpu_timers[0].l14_timer_limit = limit; + sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit; } -#if HANDLE_LVL14_IRQ -static void sun4m_lvl14_handler(int irq, void *dev_id, struct pt_regs * regs) -{ - volatile unsigned int clear; - - printk("CPU[%d]: TOOK A LEVEL14!\n", smp_processor_id()); - /* we do nothing with this at present - * this is purely to prevent OBP getting its mucky paws - * in linux. - */ - clear = sun4m_timers->cpu_timers[0].l14_timer_limit; /* clear interrupt */ - - /* reload with value, this allows on the fly retuning of the level14 - * timer - */ - sun4m_timers->cpu_timers[0].l14_timer_limit = lvl14_resolution; -} -#endif /* HANDLE_LVL14_IRQ */ - __initfunc(static void sun4m_init_timers(void (*counter_fn)(int, void *, struct pt_regs *))) { int reg_count, irq, cpu; @@ -282,13 +264,6 @@ prom_halt(); } - /* Can't cope with multiple CPUS yet so no level14 tick events */ -#if HANDLE_LVL14_IRQ - if (linux_num_cpus > 1) - claim_ticker14(NULL, PROFILE_IRQ, 0); - else - claim_ticker14(sun4m_lvl14_handler, PROFILE_IRQ, lvl14_resolution); -#endif /* HANDLE_LVL14_IRQ */ if(linux_num_cpus > 1) { for(cpu = 0; cpu < 4; cpu++) sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0; @@ -296,6 +271,25 @@ } else { sun4m_timers->cpu_timers[0].l14_timer_limit = 0; } +#ifdef __SMP__ + { + unsigned long flags; + extern unsigned long lvl14_save[4]; + struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; + + /* For SMP we use the level 14 ticker, however the bootup code + * has copied the firmwares level 14 vector into boot cpu's + * trap table, we must fix this now or we get squashed. + */ + __save_and_cli(flags); + trap_table->inst_one = lvl14_save[0]; + trap_table->inst_two = lvl14_save[1]; + trap_table->inst_three = lvl14_save[2]; + trap_table->inst_four = lvl14_save[3]; + local_flush_cache_all(); + __restore_flags(flags); + } +#endif } __initfunc(void sun4m_init_IRQ(void)) @@ -349,10 +343,6 @@ * Not sure, but writing here on SLAVIO systems may puke * so I don't do it unless there is more than 1 cpu. */ -#if 0 - printk("Warning:" - "sun4m multiple CPU interrupt code requires work\n"); -#endif irq_rcvreg = (unsigned long *) &sun4m_interrupts->undirected_target; sun4m_interrupts->undirected_target = 0; diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/sys_sparc.c linux/arch/sparc/kernel/sys_sparc.c --- v2.1.35/linux/arch/sparc/kernel/sys_sparc.c Sun Jan 26 02:07:08 1997 +++ linux/arch/sparc/kernel/sys_sparc.c Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.34 1997/01/06 06:52:35 davem Exp $ +/* $Id: sys_sparc.c,v 1.35 1997/04/16 05:56:09 davem Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that @@ -254,49 +254,45 @@ sparc_sigaction (int signum, const struct sigaction *action, struct sigaction *oldaction) { struct sigaction new_sa, *p; - int err = -EINVAL; - lock_kernel(); if(signum < 0) { current->tss.new_signal = 1; signum = -signum; } + if(signum<1 || signum>32) + return -EINVAL; - if (signum<1 || signum>32) - goto out; p = signum - 1 + current->sig->action; - if (action) { - err = verify_area(VERIFY_READ,action,sizeof(struct sigaction)); - if (err) - goto out; - err = -EINVAL; + if(action) { + if(verify_area(VERIFY_READ,action,sizeof(struct sigaction))) + return -EFAULT; if (signum==SIGKILL || signum==SIGSTOP) - goto out; - err = -EFAULT; + return -EINVAL; if(copy_from_user(&new_sa, action, sizeof(struct sigaction))) - goto out; + return -EFAULT; if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) { - err = verify_area(VERIFY_READ, new_sa.sa_handler, 1); - if (err) - goto out; + if(verify_area(VERIFY_READ, new_sa.sa_handler, 1)) + return -EFAULT; } } if (oldaction) { - err = -EFAULT; + /* In the clone() case we could copy half consistant + * state to the user, however this could sleep and + * deadlock us if we held the signal lock on SMP. So for + * now I take the easy way out and do no locking. + */ if (copy_to_user(oldaction, p, sizeof(struct sigaction))) - goto out; + return -EFAULT; } if (action) { + spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(signum); + spin_unlock_irq(¤t->sig->siglock); } - - err = 0; -out: - unlock_kernel(); - return err; + return 0; } #ifndef CONFIG_AP1000 diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c --- v2.1.35/linux/arch/sparc/kernel/sys_sunos.c Mon Mar 17 14:54:21 1997 +++ linux/arch/sparc/kernel/sys_sunos.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.77 1997/02/15 01:17:04 davem Exp $ +/* $Id: sys_sunos.c,v 1.78 1997/04/16 05:56:12 davem Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1184,39 +1184,39 @@ struct sigaction *oldaction) { struct sigaction new_sa, *p; - const int sigaction_size = sizeof (struct sigaction) - sizeof (void *); - int err = -EINVAL; + const int sigaction_size = sizeof (struct sigaction) - sizeof (void *); - lock_kernel(); current->personality |= PER_BSD; - - if (signum<1 || signum>32) - goto out; + if(signum < 1 || signum > 32) + return -EINVAL; p = signum - 1 + current->sig->action; - if (action) { - err = -EFAULT; + + if(action) { if(copy_from_user(&new_sa, action, sigaction_size)) - goto out; - err = -EINVAL; + return -EFAULT; if (signum==SIGKILL || signum==SIGSTOP) - goto out; + return -EINVAL; memset(&new_sa, 0, sizeof(struct sigaction)); - err = -EFAULT; if(copy_from_user(&new_sa, action, sigaction_size)) - goto out; + return -EFAULT; if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) { - err = verify_area(VERIFY_READ, new_sa.sa_handler, 1); - if (err) - goto out; + if(verify_area(VERIFY_READ, new_sa.sa_handler, 1)) + return -EFAULT; } new_sa.sa_flags ^= SUNOS_SV_INTERRUPT; } if (oldaction) { - err = -EFAULT; + /* In the clone() case we could copy half consistant + * state to the user, however this could sleep and + * deadlock us if we held the signal lock on SMP. So for + * now I take the easy way out and do no locking. + * But then again we don't support SunOS lwp's anyways ;-) + */ if (copy_to_user(oldaction, p, sigaction_size)) - goto out; + return -EFAULT; + if (oldaction->sa_flags & SA_RESTART) oldaction->sa_flags &= ~SA_RESTART; else @@ -1224,13 +1224,12 @@ } if (action) { + spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(signum); + spin_unlock_irq(¤t->sig->siglock); } - err = 0; -out: - unlock_kernel(); - return err; + return 0; } diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S --- v2.1.35/linux/arch/sparc/kernel/systbls.S Mon Mar 17 14:54:21 1997 +++ linux/arch/sparc/kernel/systbls.S Tue Apr 22 22:49:38 1997 @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.59 1997/02/14 03:12:54 davem Exp $ +/* $Id: systbls.S,v 1.60 1997/04/19 08:52:15 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -113,7 +113,7 @@ .long C_LABEL(sys_sched_rr_get_interval), C_LABEL(sys_nanosleep) /*250*/ .long C_LABEL(sys_mremap) .long C_LABEL(sys_sysctl) - .long C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nis_syscall) + .long C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nfsservctl) .long C_LABEL(sys_aplib), C_LABEL(sys_nis_syscall) /* Now the SunOS syscall table. */ diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/tick14.c linux/arch/sparc/kernel/tick14.c --- v2.1.35/linux/arch/sparc/kernel/tick14.c Sat Nov 9 00:11:50 1996 +++ linux/arch/sparc/kernel/tick14.c Tue Apr 15 21:47:23 1997 @@ -60,6 +60,8 @@ void claim_ticker14(void (*handler)(int, void *, struct pt_regs *), int irq_nr, unsigned int timeout ) { + int cpu = smp_processor_id(); + /* first we copy the obp handler instructions */ disable_irq(irq_nr); @@ -78,7 +80,7 @@ "counter14", NULL)) { install_linux_ticker(); - load_profile_irq(timeout); + load_profile_irq(cpu, timeout); enable_irq(irq_nr); } } diff -u --recursive --new-file v2.1.35/linux/arch/sparc/kernel/time.c linux/arch/sparc/kernel/time.c --- v2.1.35/linux/arch/sparc/kernel/time.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/time.c Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.27 1997/04/14 05:38:31 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) @@ -54,11 +54,6 @@ last_rtc_update = xtime.tv_sec; else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - -#ifdef __SMP__ - /* I really think it should not be done this way... -DaveM */ - smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); -#endif } /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. @@ -313,11 +308,11 @@ xor %o5, %o3, %o3 orcc %o2, %o3, %g0 bne 1b - subcc %o1, 0x0, %g0 - bpos 1f + cmp %o1, 0 + bge 1f srl %o1, 0xa, %o1 - sethi %hi(0x2710), %o3 - or %o3, %lo(0x2710), %o3 + sethi %hi(tick), %o3 + ld [%o3 + %lo(tick)], %o3 sethi %hi(0x1fffff), %o2 or %o2, %lo(0x1fffff), %o2 add %o5, %o3, %o5 diff -u --recursive --new-file v2.1.35/linux/arch/sparc/lib/Makefile linux/arch/sparc/lib/Makefile --- v2.1.35/linux/arch/sparc/lib/Makefile Thu Mar 27 14:39:59 1997 +++ linux/arch/sparc/lib/Makefile Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.22 1997/03/14 21:04:17 jj Exp $ +# $Id: Makefile,v 1.23 1997/04/18 05:44:39 davem Exp $ # Makefile for Sparc library files.. # @@ -9,6 +9,10 @@ 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 @@ -53,6 +57,9 @@ 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 diff -u --recursive --new-file v2.1.35/linux/arch/sparc/lib/checksum.S linux/arch/sparc/lib/checksum.S --- v2.1.35/linux/arch/sparc/lib/checksum.S Mon Mar 17 14:54:22 1997 +++ linux/arch/sparc/lib/checksum.S Tue Apr 22 22:39:12 1997 @@ -471,8 +471,6 @@ addx %g0, %g7, %o0 C_LABEL(__csum_partial_copy_end): - .section .fixup,#alloc,#execinstr - .align 4 /* We do these strange calculations for the csum_*_from_user case only, ie. * we only bother with faults on loads... */ @@ -568,6 +566,7 @@ add %i1, %i2, %i1 2: mov %i1, %o0 +6: call C_LABEL(__bzero) mov %i3, %o1 1: @@ -579,3 +578,4 @@ .section __ex_table,#alloc .align 4 .word 5b,2 + .word 6b,2 diff -u --recursive --new-file v2.1.35/linux/arch/sparc/lib/irqlock.S linux/arch/sparc/lib/irqlock.S --- v2.1.35/linux/arch/sparc/lib/irqlock.S Wed Dec 31 16:00:00 1969 +++ linux/arch/sparc/lib/irqlock.S Tue Apr 22 22:39:12 1997 @@ -0,0 +1,185 @@ +/* $Id: irqlock.S,v 1.2 1997/04/19 04:33:37 davem Exp $ + * irqlock.S: High performance IRQ global locking and interrupt entry. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include + + .text + .align 4 + + /* This is incredibly insane... */ + .globl ___irq_enter +___irq_enter: + sethi %hi(local_irq_count), %g2 + sll %g1, 2, %g1 + or %g2, %lo(local_irq_count), %g2 + ld [%g2 + %g1], %g3 + sethi %hi(global_irq_count), %g5 + add %g3, 1, %g3 + or %g5, %lo(global_irq_count), %g5 + st %g3, [%g2 + %g1] +1: + ldstub [%g5 + 3], %g2 + orcc %g2, 0x0, %g0 + bne 1b + ld [%g5], %g3 + sra %g3, 8, %g3 + add %g3, 1, %g3 + sll %g3, 8, %g3 + st %g3, [%g5] + sethi %hi(global_irq_lock), %g1 + ldub [%g1 + %lo(global_irq_lock)], %g2 +1: + orcc %g2, 0x0, %g0 + bne,a 1b + ldub [%g1 + %lo(global_irq_lock)], %g2 +___irq_enter_out: + jmpl %o7, %g0 + mov %g4, %o7 + + .globl ___irq_exit +___irq_exit: + rd %psr, %g3 + sethi %hi(global_irq_count), %g1 + or %g3, PSR_PIL, %g3 + or %g1, %lo(global_irq_count), %g1 + wr %g3, 0x0, %psr + sethi %hi(local_irq_count), %g2 + sll %g7, 2, %g7 + or %g2, %lo(local_irq_count), %g2 + ld [%g2 + %g7], %g3 +1: + ldstub [%g1 + 3], %g5 + orcc %g5, 0x0, %g0 + bne 1b + ld [%g1], %g5 + sra %g5, 8, %g5 + sub %g5, 1, %g5 + sll %g5, 8, %g5 + st %g5, [%g1] + sub %g3, 1, %g3 + sethi %hi(global_irq_holder), %g1 + st %g3, [%g2 + %g7] + srl %g7, 2, %g7 + ldub [%g1 + %lo(global_irq_holder)], %g5 + cmp %g5, %g7 + bne ___irq_enter_out + mov NO_PROC_ID, %g2 + stb %g2, [%g1 + %lo(global_irq_holder)] + sethi %hi(global_irq_lock), %g5 + b ___irq_enter_out + stb %g0, [%g5 + %lo(global_irq_lock)] + + /* Weird calling conventions... %g7=flags, %g4=%prev_o7 + * Very clever for the __global_sti case, the inline which + * gets us here clears %g7 and it just works. + */ + .globl ___global_restore_flags, ___global_sti, ___global_cli +___global_restore_flags: + bne,a ___global_cli + rd %tbr, %g7 + rd %tbr, %g2 + +___global_sti: + sethi %hi(global_irq_holder), %g1 + sethi %hi(global_irq_lock), %g3 + srl %g2, 12, %g2 + ldub [%g1 + %lo(global_irq_holder)], %g5 + and %g2, 3, %g2 + cmp %g5, %g2 + bne 1f + mov NO_PROC_ID, %g5 + stb %g5, [%g1 + %lo(global_irq_holder)] + stb %g0, [%g3 + %lo(global_irq_lock)] +1: + rd %psr, %g3 + andcc %g7, 2, %g0 + bne,a 1f + or %g3, PSR_PIL, %g3 + andn %g3, PSR_PIL, %g3 +1: + wr %g3, 0x0, %psr + nop +__global_cli_out: ! All togther now... "fuuunnnnn" + retl + mov %g4, %o7 + +__spin_on_global_irq_lock: + orcc %g2, 0x0, %g0 + bne,a __spin_on_global_irq_lock + ldub [%g1], %g2 + b,a 1f + + /* This is a royal pain in the ass to make fast... 8-( */ +___global_cli: + sethi %hi(global_irq_lock), %g5 + srl %g7, 12, %g7 + sethi %hi(global_irq_holder), %g3 + and %g7, 3, %g7 + ldub [%g3 + %lo(global_irq_holder)], %g1 + rd %psr, %g2 + cmp %g1, %g7 + or %g2, PSR_PIL, %g2 + be __global_cli_out + wr %g2, 0x0, %psr ! XXX some sparcs may choke on this... + sethi %hi(local_irq_count), %g3 + or %g3, %lo(local_irq_count), %g3 + or %g5, %lo(global_irq_lock), %g1 +1: + ldstub [%g1], %g2 + orcc %g2, 0x0, %g0 + bne,a __spin_on_global_irq_lock + ldub [%g1], %g2 +__wait_on_irq: + sll %g7, 2, %g7 + ld [%g3 + %g7], %g2 + sethi %hi(global_irq_count), %g1 + or %g1, %lo(global_irq_count), %g1 + srl %g7, 2, %g7 + ld [%g1], %g5 + sra %g5, 8, %g5 +__wait_on_irq_loop: + cmp %g5, %g2 + sethi %hi(global_irq_holder), %g3 + be,a __global_cli_out ! Mamamia, Mamamia, this is the fast path + stb %g7, [%g3 + %lo(global_irq_holder)] +1: + ldstub [%g1 + 3], %g3 + orcc %g3, 0x0, %g0 + bne 1b + ld [%g1], %g3 + sra %g3, 8, %g3 + sub %g3, %g2, %g3 + sll %g3, 8, %g3 + st %g3, [%g1] + sethi %hi(global_irq_lock), %g3 + stb %g0, [%g3 + %lo(global_irq_lock)] +0: + ld [%g1], %g5 +9: + ldub [%g3 + %lo(global_irq_lock)], %g3 + sra %g5, 8, %g5 + orcc %g3, %g5, %g0 + bne 0b + sethi %hi(global_irq_lock), %g3 + ldstub [%g3 + %lo(global_irq_lock)], %g5 + orcc %g5, 0x0, %g0 + bne,a 9b + ld [%g1], %g5 +1: + ldstub [%g1 + 3], %g3 + orcc %g3, 0x0, %g0 + bne 1b + ld [%g1], %g3 + sra %g3, 8, %g3 + add %g3, %g2, %g5 + sll %g5, 8, %g3 + b __wait_on_irq_loop + st %g3, [%g1] + +#if 0 /* XXX I'm not delirious enough to debug this yet. */ + add %o7, (8 + (__wait_on_irq_loop - . - 4)), %o7 ! AIEEEEE +#endif diff -u --recursive --new-file v2.1.35/linux/arch/sparc/lib/locks.S linux/arch/sparc/lib/locks.S --- v2.1.35/linux/arch/sparc/lib/locks.S Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc/lib/locks.S Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: locks.S,v 1.9 1997/04/14 05:38:41 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) @@ -7,6 +7,7 @@ #include #include #include +#include #include .text @@ -19,8 +20,8 @@ * itself in %g1, %g4 must be restored into %o7 when we return, * and the caller wants us to return to him at three instructions * previous to the call instruction which got us here. See how - * this is used in asm-sparc/smp_lock.h if what I just said - * confuses you to no end. + * this is used in asm/smp_lock.h and asm/spinlock.h if what I + * just said confuses you to no end. */ .globl ___spinlock_waitfor ___spinlock_waitfor: @@ -59,8 +60,8 @@ 9: jmpl %o7 + 0x8, %g0 mov %g4, %o7 - .globl ___lock_reaquire_kernel -___lock_reaquire_kernel: + .globl ___lock_reacquire_kernel +___lock_reacquire_kernel: rd %psr, %g3 or %g3, PSR_PIL, %g7 wr %g7, 0x0, %psr @@ -81,9 +82,6 @@ jmpl %o7 + 0x8, %g0 mov %g4, %o7 -#undef NO_PROC_ID -#define NO_PROC_ID 0xff - .globl ___unlock_kernel ___unlock_kernel: addcc %g2, 1, %g2 @@ -100,4 +98,65 @@ wr %g3, 0x0, %psr nop; nop; nop; 1: jmpl %o7 + 0x8, %g0 + mov %g4, %o7 + + /* Read/writer locks, as usual this is overly clever to make it + * as fast as possible. + */ + + /* caches... */ +___rw_read_enter_spin_on_wlock: + orcc %g2, 0x0, %g0 + be,a ___rw_read_enter + ldstub [%g1 + 3], %g2 + b ___rw_read_enter_spin_on_wlock + ldub [%g1 + 3], %g2 +___rw_write_enter_spin_on_wlock: + orcc %g2, 0x0, %g0 + be,a ___rw_write_enter + ldstub [%g1 + 3], %g2 + b ___rw_write_enter_spin_on_wlock + ldub [%g1 + 3], %g2 + + .globl ___rw_read_enter +___rw_read_enter: + orcc %g2, 0x0, %g0 + bne,a ___rw_read_enter_spin_on_wlock + ldub [%g1 + 3], %g2 +1: + ldstub [%g1 + 2], %g7 + orcc %g7, 0x0, %g0 + bne 1b + ldsh [%g1], %g2 + add %g2, 1, %g2 + sth %g2, [%g1] + sth %g0, [%g1 + 2] + retl + mov %g4, %o7 + + /* We must be careful here to not blow away wlock. */ + .globl ___rw_read_exit +___rw_read_exit_spin: + ldstub [%g1 + 2], %g2 +___rw_read_exit: + orcc %g2, 0x0, %g0 + bne ___rw_read_exit_spin + ldsh [%g1], %g7 + sub %g7, 1, %g7 + sth %g7, [%g1] + stb %g0, [%g1 + 2] + retl + mov %g4, %o7 + + .globl ___rw_write_enter +___rw_write_enter: + orcc %g2, 0x0, %g0 + bne,a ___rw_write_enter_spin_on_wlock + ldub [%g1 + 3], %g2 + ld [%g1], %g2 +1: + andncc %g2, 0xff, %g0 + bne,a 1b + ld [%g1], %g2 + retl mov %g4, %o7 diff -u --recursive --new-file v2.1.35/linux/arch/sparc/mm/Makefile linux/arch/sparc/mm/Makefile --- v2.1.35/linux/arch/sparc/mm/Makefile Thu Mar 27 14:39:59 1997 +++ linux/arch/sparc/mm/Makefile Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.23 1997/03/10 09:16:52 davem Exp $ +# $Id: Makefile,v 1.24 1997/04/20 14:11:49 ecd Exp $ # Makefile for the linux Sparc-specific parts of the memory manager. # # Note! Dependencies are done automagically by 'make dep', which also @@ -8,10 +8,13 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := mm.o -O_OBJS := fault.o init.o sun4c.o srmmu.o hypersparc.o loadmmu.o \ - generic.o asyncd.o extable.o +O_OBJS := fault.o init.o sun4c.o srmmu.o hypersparc.o viking.o \ + loadmmu.o generic.o asyncd.o extable.o include $(TOPDIR)/Rules.make hypersparc.o: hypersparc.S $(CC) -D__ASSEMBLY__ -ansi -c -o hypersparc.o hypersparc.S + +viking.o: viking.S + $(CC) -D__ASSEMBLY__ -ansi -c -o viking.o viking.S diff -u --recursive --new-file v2.1.35/linux/arch/sparc/mm/hypersparc.S linux/arch/sparc/mm/hypersparc.S --- v2.1.35/linux/arch/sparc/mm/hypersparc.S Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc/mm/hypersparc.S Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: hypersparc.S,v 1.3 1997/04/13 06:38:13 davem Exp $ +/* $Id: hypersparc.S,v 1.4 1997/04/19 04:33:39 davem Exp $ * hypersparc.S: High speed Hypersparc mmu/cache operations. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -271,10 +271,15 @@ retl nop + /* It was noted that at boot time a TLB flush all in a delay slot + * can deliver an illegal instruction to the processor if the timing + * is just right... + */ hypersparc_flush_tlb_all: mov 0x400, %g1 + sta %g0, [%g1] ASI_M_FLUSH_PROBE retl - sta %g0, [%g1] ASI_M_FLUSH_PROBE + nop hypersparc_flush_tlb_mm: mov SRMMU_CTX_REG, %g1 diff -u --recursive --new-file v2.1.35/linux/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c --- v2.1.35/linux/arch/sparc/mm/init.c Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc/mm/init.c Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.48 1997/04/12 04:28:37 davem Exp $ +/* $Id: init.c,v 1.49 1997/04/17 21:49:31 jj Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -34,6 +34,9 @@ struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; unsigned long sparc_unmapped_base; +/* References to section boundaries */ +extern char __init_begin, __init_end, etext; + /* * BAD_PAGE is the page that is used for page faults when linux * is out-of-memory. Older versions of linux just did a @@ -208,8 +211,8 @@ { int codepages = 0; int datapages = 0; + int initpages = 0; unsigned long tmp2, addr; - extern char etext; /* Saves us work later. */ memset((void *) ZERO_PAGE, 0, PAGE_SIZE); @@ -237,7 +240,9 @@ if(PageReserved(mem_map + MAP_NR(addr))) { if ((addr < (unsigned long) &etext) && (addr >= KERNBASE)) codepages++; - else if((addr < start_mem) && (addr >= KERNBASE)) + else if((addr >= (unsigned long)&__init_begin && addr < (unsigned long)&__init_end)) + initpages++; + else if((addr < start_mem) && (addr >= KERNBASE)) datapages++; continue; } @@ -252,10 +257,12 @@ tmp2 = nr_free_pages << PAGE_SHIFT; - printk("Memory: %luk available (%dk kernel code, %dk data) [%08lx,%08lx]\n", + printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]\n", tmp2 >> 10, codepages << (PAGE_SHIFT-10), - datapages << (PAGE_SHIFT-10), PAGE_OFFSET, end_mem); + datapages << (PAGE_SHIFT-10), + initpages << (PAGE_SHIFT-10), + PAGE_OFFSET, end_mem); min_free_pages = nr_free_pages >> 7; if(min_free_pages < 16) @@ -266,7 +273,6 @@ void free_initmem (void) { - extern char __init_begin, __init_end; unsigned long addr; addr = (unsigned long)(&__init_begin); @@ -275,7 +281,6 @@ atomic_set(&mem_map[MAP_NR(addr)].count, 1); free_page(addr); } - printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) diff -u --recursive --new-file v2.1.35/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c --- v2.1.35/linux/arch/sparc/mm/srmmu.c Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc/mm/srmmu.c Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.135 1997/04/14 05:38:49 davem Exp $ +/* $Id: srmmu.c,v 1.136 1997/04/20 14:11:51 ecd Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -74,7 +74,10 @@ ctxd_t *srmmu_ctx_table_phys; ctxd_t *srmmu_context_table; -static struct srmmu_trans { +/* Don't change this without changing access to this + * in arch/sparc/mm/viking.S + */ +struct srmmu_trans { unsigned long vbase; unsigned long pbase; unsigned long size; @@ -705,7 +708,7 @@ } while(line != page); } -static void srmmu_set_pte_nocache_nomxccvik(pte_t *ptep, pte_t pteval) +static void srmmu_set_pte_nocache_viking(pte_t *ptep, pte_t pteval) { unsigned long vaddr; int set; @@ -1083,255 +1086,6 @@ * with respect to cache coherency. */ -/* Viking flushes. For Sun's mainline MBUS processor it is pretty much - * a crappy mmu. The on-chip I&D caches only have full flushes, no fine - * grained cache invalidations. It only has these "flash clear" things - * just like the MicroSparcI. Added to this many revs of the chip are - * teaming with hardware buggery. Someday maybe we'll do direct - * diagnostic tag accesses for page level flushes as those should - * be painless and will increase performance due to the frequency of - * page level flushes. This is a must to _really_ flush the caches, - * crazy hardware ;-) - */ - -static void viking_flush_cache_all(void) -{ -} - -static void viking_flush_cache_mm(struct mm_struct *mm) -{ -} - -static void viking_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) -{ -} - -static void viking_flush_cache_page(struct vm_area_struct *vma, unsigned long page) -{ -} - -/* Non-mxcc vikings are copy-back but are pure-physical so no flushing. */ -static void viking_flush_page_to_ram(unsigned long page) -{ -} - -static void viking_mxcc_flush_chunk(unsigned long chunk) -{ -} - -/* All vikings have an icache which snoops the processor bus and is fully - * coherent with the dcache, so no flush is necessary at all. - */ -static void viking_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) -{ -} - -static void viking_mxcc_flush_page(unsigned long page) -{ - unsigned long ppage = srmmu_v2p(page & PAGE_MASK); - unsigned long paddr0, paddr1; - - if (ppage == 0xffffffffUL) - return; - - paddr0 = 0x10; /* Set cacheable bit. */ - paddr1 = ppage; - - /* Read the page's data through the stream registers, - * and write it back to memory. This will issue - * coherent write invalidates to all other caches, thus - * should also be sufficient in an MP system. - */ - __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t" - "or %%g0, %1, %%g3\n" - "1:\n\t" - "stda %%g2, [%2] %5\n\t" - "stda %%g2, [%3] %5\n\t" - "add %%g3, %4, %%g3\n\t" - "btst 0xfff, %%g3\n\t" - "bne 1b\n\t" - "nop\n\t" : : - "r" (paddr0), "r" (paddr1), - "r" (MXCC_SRCSTREAM), - "r" (MXCC_DESSTREAM), - "r" (MXCC_STREAM_SIZE), - "i" (ASI_M_MXCC) : "g2", "g3", "cc"); - - /* This was handcoded after a look at the gcc output from - * - * do { - * mxcc_set_stream_src(paddr); - * mxcc_set_stream_dst(paddr); - * paddr[1] += MXCC_STREAM_SIZE; - * } while (paddr[1] & ~PAGE_MASK); - */ -} - -static void viking_no_mxcc_flush_page(unsigned long page) -{ - unsigned long ppage = srmmu_v2p(page & PAGE_MASK); - int set, block; - unsigned long ptag[2]; - unsigned long vaddr; - int i; - - if (ppage == 0xffffffffUL) - return; - ppage >>= 12; - - for (set = 0; set < 128; set++) { - for (block = 0; block < 4; block++) { - - viking_get_dcache_ptag(set, block, ptag); - - if (ptag[1] != ppage) - continue; - if (!(ptag[0] & VIKING_PTAG_VALID)) - continue; - if (!(ptag[0] & VIKING_PTAG_DIRTY)) - continue; - - /* There was a great cache from TI - * with comfort as much as vi, - * 4 pages to flush, - * 4 pages, no rush, - * since anything else makes him die. - */ - vaddr = (KERNBASE + PAGE_SIZE) | (set << 5); - for (i = 0; i < 8; i++) { - __asm__ __volatile__ ("ld [%0], %%g2\n\t" : : - "r" (vaddr) : "g2"); - vaddr += PAGE_SIZE; - } - - /* Continue with next set. */ - break; - } - } -} - -static void viking_nomxcc_flush_chunk(unsigned long chunk) -{ - viking_no_mxcc_flush_page(chunk); -} - -/* Viking is IO cache coherent, but really only on MXCC. */ -static void viking_flush_page_for_dma(unsigned long page) -{ -} - -static void viking_flush_tlb_all(void) -{ - register int ctr asm("g5"); - - ctr = 0; - __asm__ __volatile__(" - 1: ld [%%g6 + %2], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp - 2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0" - : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc"); - srmmu_flush_whole_tlb(); - module_stats.invall++; -} - -static void viking_flush_tlb_mm(struct mm_struct *mm) -{ - register int ctr asm("g5"); - - FLUSH_BEGIN(mm) - ctr = 0; - __asm__ __volatile__(" -1: ld [%%g6 + %7], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp -2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0 - lda [%1] %4, %0 - sta %3, [%1] %4 - sta %%g0, [%2] %5 - sta %0, [%1] %4" - : "=&r" (ctr) - : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context), - "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE), "0" (ctr), - "i" (UWINMASK_OFFSET) - : "g4", "cc"); - module_stats.invmm++; - FLUSH_END -} - -static void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) -{ - register int ctr asm("g5"); - unsigned long size; - - FLUSH_BEGIN(mm) - ctr = 0; - __asm__ __volatile__(" - 1: ld [%%g6 + %2], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp - 2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0" - : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc"); - start &= SRMMU_PGDIR_MASK; - size = SRMMU_PGDIR_ALIGN(end) - start; - __asm__ __volatile__(" - lda [%0] %5, %%g5 - sta %1, [%0] %5 - 1: subcc %3, %4, %3 - bne 1b - sta %%g0, [%2 + %3] %6 - sta %%g5, [%0] %5" - : /* no outputs */ - : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (start | 0x200), - "r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS), - "i" (ASI_M_FLUSH_PROBE) - : "g5", "cc"); - module_stats.invrnge++; - FLUSH_END -} - -static void viking_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - register int ctr asm("g5"); - - FLUSH_BEGIN(mm) - ctr = 0; - __asm__ __volatile__(" - 1: ld [%%g6 + %2], %%g4 ! flush user windows - orcc %%g0, %%g4, %%g0 - add %0, 1, %0 - bne 1b - save %%sp, -64, %%sp - 2: subcc %0, 1, %0 - bne 2b - restore %%g0, %%g0, %%g0" - : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc"); - __asm__ __volatile__(" - lda [%0] %3, %%g5 - sta %1, [%0] %3 - sta %%g0, [%2] %4 - sta %%g5, [%0] %3" - : /* no outputs */ - : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK), - "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE) - : "g5"); - module_stats.invpg++; - FLUSH_END -} - /* Cypress flushes. */ static void cypress_flush_cache_all(void) { @@ -1576,6 +1330,27 @@ FLUSH_END } +/* viking.S */ +extern void viking_flush_cache_all(void); +extern void viking_flush_cache_mm(struct mm_struct *mm); +extern void viking_flush_cache_range(struct mm_struct *mm, unsigned long start, + unsigned long end); +extern void viking_flush_cache_page(struct vm_area_struct *vma, + unsigned long page); +extern void viking_flush_page_to_ram(unsigned long page); +extern void viking_flush_page_for_dma(unsigned long page); +extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr); +extern void viking_flush_page(unsigned long page); +extern void viking_mxcc_flush_page(unsigned long page); +extern void viking_flush_chunk(unsigned long chunk); +extern void viking_mxcc_flush_chunk(unsigned long chunk); +extern void viking_flush_tlb_all(void); +extern void viking_flush_tlb_mm(struct mm_struct *mm); +extern void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end); +extern void viking_flush_tlb_page(struct vm_area_struct *vma, + unsigned long page); + /* hypersparc.S */ extern void hypersparc_flush_cache_all(void); extern void hypersparc_flush_cache_mm(struct mm_struct *mm); @@ -1608,9 +1383,9 @@ } } -static void viking_no_mxcc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) +static void viking_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) { - viking_no_mxcc_flush_page((unsigned long)pgdp); + viking_flush_page((unsigned long)pgdp); if(tsk->mm->context != NO_CONTEXT) { flush_cache_mm(current->mm); ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp); @@ -1768,11 +1543,11 @@ viking_mxcc_flush_page(start); start += PAGE_SIZE; } - } else if(flush_page_for_dma == viking_no_mxcc_flush_page) { + } else if(flush_page_for_dma == viking_flush_page) { unsigned long start = (unsigned long) iommu->page_table; unsigned long end = (start + ptsize); while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -1809,11 +1584,11 @@ viking_mxcc_flush_page(start); start += PAGE_SIZE; } - } else if(flush_page_for_dma == viking_no_mxcc_flush_page) { + } else if(flush_page_for_dma == viking_flush_page) { unsigned long start = (unsigned long) iommu; unsigned long end = (start + 16 * PAGE_SIZE); while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -2029,11 +1804,11 @@ viking_mxcc_flush_page(start); start += PAGE_SIZE; } - } else if(flush_page_for_dma == viking_no_mxcc_flush_page) { + } else if(flush_page_for_dma == viking_flush_page) { unsigned long start = ((unsigned long) iopte_first) & PAGE_MASK; unsigned long end = PAGE_ALIGN(((unsigned long) iopte)); while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -2449,12 +2224,12 @@ start_mem = PAGE_ALIGN(mempool); flush_cache_all(); - if(flush_page_for_dma == viking_no_mxcc_flush_page) { + if(flush_page_for_dma == viking_flush_page) { unsigned long start = ptables_start; unsigned long end = start_mem; while(start < end) { - viking_no_mxcc_flush_page(start); + viking_flush_page(start); start += PAGE_SIZE; } } @@ -2999,10 +2774,10 @@ msi_set_sync(); - set_pte = srmmu_set_pte_nocache_nomxccvik; - sparc_update_rootmmu_dir = viking_no_mxcc_update_rootmmu_dir; + set_pte = srmmu_set_pte_nocache_viking; + sparc_update_rootmmu_dir = viking_update_rootmmu_dir; - flush_chunk = viking_nomxcc_flush_chunk; /* local flush _only_ */ + flush_chunk = viking_flush_chunk; /* local flush _only_ */ /* We need this to make sure old viking takes no hits * on it's cache for dma snoops to workaround the @@ -3010,7 +2785,7 @@ * This is only necessary because of the new way in * which we use the IOMMU. */ - flush_page_for_dma = viking_no_mxcc_flush_page; + flush_page_for_dma = viking_flush_page; } else { srmmu_name = "TI Viking/MXCC"; viking_mxcc_present = 1; diff -u --recursive --new-file v2.1.35/linux/arch/sparc/mm/viking.S linux/arch/sparc/mm/viking.S --- v2.1.35/linux/arch/sparc/mm/viking.S Wed Dec 31 16:00:00 1969 +++ linux/arch/sparc/mm/viking.S Tue Apr 22 22:39:12 1997 @@ -0,0 +1,267 @@ +/* $Id: viking.S,v 1.2 1997/04/20 21:21:49 ecd Exp $ + * viking.S: High speed Viking cache/mmu operations + * + * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define WINDOW_FLUSH(tmp1, tmp2) \ + mov 0, tmp1; \ +98: ld [%g6 + AOFF_task_tss + AOFF_thread_uwinmask], tmp2; \ + orcc %g0, tmp2, %g0; \ + add tmp1, 1, tmp1; \ + bne 98b; \ + save %sp, -64, %sp; \ +99: subcc tmp1, 1, tmp1; \ + bne 99b; \ + restore %g0, %g0, %g0; + + .text + .align 4 + + .globl viking_flush_cache_all, viking_flush_cache_mm + .globl viking_flush_cache_range, viking_flush_cache_page + .globl viking_flush_page, viking_mxcc_flush_page + .globl viking_flush_page_for_dma, viking_flush_page_to_ram + .globl viking_flush_chunk, viking_mxcc_flush_chunk + .globl viking_flush_sig_insns + .globl viking_flush_tlb_all, viking_flush_tlb_mm + .globl viking_flush_tlb_range, viking_flush_tlb_page + +viking_flush_page: +viking_flush_chunk: + sethi %hi(C_LABEL(srmmu_map)), %g2 + or %g2, %lo(C_LABEL(srmmu_map)), %g3 + ld [%g3 + 8], %g2 + cmp %g2, 0 + be 3f + and %o0, PAGE_MASK, %o0 + + ld [%g3], %o1 +1: + cmp %o1, %o0 + bgu,a 2f + add %g3, 0xc, %g3 + + add %o1, %g2, %g2 + cmp %g2, %o0 + bleu,a 2f + add %g3, 0xc, %g3 + + sub %o0, %o1, %g2 + ld [%g3 + 4], %o0 + add %g2, %o0, %g3 + b 4f + srl %g3, 12, %g1 ! ppage >> 12 + +2: + ld [%g3 + 8], %g2 + cmp %g2, 0 + bne,a 1b + ld [%g3], %o1 +3: + retl + nop + +4: + clr %o1 ! set counter, 0 - 127 + sethi %hi(KERNBASE + PAGE_SIZE - 0x80000000), %o3 + sethi %hi(0x80000000), %o4 + sethi %hi(VIKING_PTAG_VALID | VIKING_PTAG_DIRTY), %o5 + sethi %hi(PAGE_SIZE), %o0 + clr %o2 ! block counter, 0 - 3 +5: + sll %o1, 5, %g4 + or %g4, %o4, %g4 ! 0x80000000 | (set << 5) + + sll %o2, 26, %g5 ! block << 26 +6: + or %g5, %g4, %g5 + ldda [%g5] ASI_M_DATAC_TAG, %g2 + cmp %g3, %g1 ! ptag == ppage? + bne,a 7f + inc %o2 + + and %g2, %o5, %g3 ! ptag VALID and DIRTY? + cmp %g3, %o5 + bne,a 7f + inc %o2 + + add %g4, %o3, %g2 ! (KERNBASE + PAGE_SIZE) | (set << 5) + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + add %g2, %o0, %g2 + ld [%g2], %g3 + + b 8f + inc %o1 + +7: + cmp %o2, 3 + ble 6b + sll %o2, 26, %g5 ! block << 26 + + inc %o1 +8: + cmp %o1, 0x7f + ble 5b + clr %o2 + + retl + nop + + +viking_mxcc_flush_page: + sethi %hi(C_LABEL(srmmu_map)), %g2 + or %g2, %lo(C_LABEL(srmmu_map)), %g3 + ld [%g3 + 8], %g2 + cmp %g2, 0 + be 3f + and %o0, PAGE_MASK, %o0 + + ld [%g3], %o1 +1: + cmp %o1, %o0 + bgu,a 2f + add %g3, 0xc, %g3 + + add %o1, %g2, %g2 + cmp %g2, %o0 + bleu,a 2f + add %g3, 0xc, %g3 + + sub %o0, %o1, %g2 + ld [%g3 + 4], %o0 + add %g2, %o0, %g3 + sethi %hi(PAGE_SIZE), %g4 + b 4f + add %g3, %g4, %g3 ! ppage + PAGE_SIZE + +2: + ld [%g3 + 8], %g2 + cmp %g2, 0 + bne,a 1b + ld [%g3], %o1 +3: + retl + nop +4: + mov 0x10, %g2 ! set cacheable bit + sethi %hi(MXCC_SRCSTREAM), %o2 + or %o2, %lo(MXCC_SRCSTREAM), %o2 + sethi %hi(MXCC_DESSTREAM), %o3 + or %o3, %lo(MXCC_DESSTREAM), %o3 + +5: + sub %g3, MXCC_STREAM_SIZE, %g3 +6: + stda %g2, [%o2] ASI_M_MXCC + stda %g2, [%o3] ASI_M_MXCC + andncc %g3, PAGE_MASK, %g0 + bne 6b + sub %g3, MXCC_STREAM_SIZE, %g3 + + retl + nop + +viking_mxcc_flush_chunk: + retl + nop + +viking_flush_cache_all: +viking_flush_cache_mm: +viking_flush_cache_range: +viking_flush_cache_page: + retl + nop + +viking_flush_tlb_all: + WINDOW_FLUSH(%g4, %g5) + mov 0x400, %g1 + retl + sta %g0, [%g1] ASI_M_FLUSH_PROBE + +viking_flush_tlb_mm: + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o1 + lda [%g1] ASI_M_MMUREGS, %g5 +#ifndef __SMP__ + cmp %o1, -1 + be viking_flush_tlb_mm_out +#endif + WINDOW_FLUSH(%g2, %g3) + + mov 0x300, %g2 + sta %o1, [%g1] ASI_M_MMUREGS + sta %g0, [%g2] ASI_M_FLUSH_PROBE +viking_flush_tlb_mm_out: + retl + sta %g5, [%g1] ASI_M_MMUREGS + +viking_flush_tlb_range: + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +#ifndef __SMP__ + cmp %o3, -1 + be viking_flush_tlb_range_out +#endif + WINDOW_FLUSH(%g2, %g3) + + srl %o1, SRMMU_PGDIR_SHIFT, %o1 + sta %o3, [%g1] ASI_M_MMUREGS + sll %o1, SRMMU_PGDIR_SHIFT, %o1 + sethi %hi(1 << SRMMU_PGDIR_SHIFT), %o4 + add %o1, 0x200, %o1 + sta %g0, [%o1] ASI_M_FLUSH_PROBE +1: + add %o1, %o4, %o1 + cmp %o1, %o2 + blu,a 1b + sta %g0, [%o1] ASI_M_FLUSH_PROBE +viking_flush_tlb_range_out: + retl + sta %g5, [%g1] ASI_M_MMUREGS + +viking_flush_tlb_page: + ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + and %o1, PAGE_MASK, %o1 + lda [%g1] ASI_M_MMUREGS, %g5 +#ifndef __SMP__ + cmp %o3, -1 + be viking_flush_tlb_page_out +#endif + WINDOW_FLUSH(%g2, %g3) + + sta %o3, [%g1] ASI_M_MMUREGS + sta %g0, [%o1] ASI_M_FLUSH_PROBE +viking_flush_tlb_page_out: + retl + sta %g5, [%g1] ASI_M_MMUREGS + +viking_flush_page_to_ram: +viking_flush_page_for_dma: +viking_flush_sig_insns: + retl + nop diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/Makefile linux/arch/sparc64/Makefile --- v2.1.35/linux/arch/sparc64/Makefile Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc64/Makefile Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.14 1997/04/10 23:32:33 davem Exp $ +# $Id: Makefile,v 1.15 1997/04/14 17:04:49 jj Exp $ # sparc64/Makefile # # Makefile for the architecture dependent flags and dependencies on the @@ -24,7 +24,7 @@ # debugging of the kernel to get the proper debugging information. #CFLAGS := $(CFLAGS) -g -pipe -fcall-used-g5 -fcall-used-g7 -CFLAGS := $(CFLAGS) -pipe -fno-sibling-call \ +CFLAGS := $(CFLAGS) -pipe \ -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare LINKFLAGS = -T arch/sparc64/vmlinux.lds diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/config.in linux/arch/sparc64/config.in --- v2.1.35/linux/arch/sparc64/config.in Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc64/config.in Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.5 1997/04/10 17:06:08 jj Exp $ +# $Id: config.in,v 1.6 1997/04/17 20:35:42 jj Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -50,9 +50,12 @@ bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC bool 'Sysctl support' CONFIG_SYSCTL +bool 'Kernel support for Linux/Sparc 32bit binary compatibility' CONFIG_SPARC32_COMPAT tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF -tristate 'Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32 +if [ "$CONFIG_SPARC32_COMPAT" != "n" ]; then + tristate 'Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32 +fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA fi diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig --- v2.1.35/linux/arch/sparc64/defconfig Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc64/defconfig Tue Apr 22 22:39:12 1997 @@ -50,6 +50,7 @@ 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 @@ -107,7 +108,7 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/Makefile linux/arch/sparc64/kernel/Makefile --- v2.1.35/linux/arch/sparc64/kernel/Makefile Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc64/kernel/Makefile Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.15 1997/04/10 07:53:30 davem Exp $ +# $Id: Makefile,v 1.16 1997/04/17 20:35:37 jj Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -18,8 +18,12 @@ 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 diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/etrap.S linux/arch/sparc64/kernel/etrap.S --- v2.1.35/linux/arch/sparc64/kernel/etrap.S Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/etrap.S Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.10 1997/04/03 13:03:49 davem Exp $ +/* $Id: etrap.S,v 1.11 1997/04/14 17:04:45 jj Exp $ * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -19,9 +19,8 @@ etrap: rdpr %pil, %g4 etrap_irq: - rdpr %wstate, %g5 - sllx %g4, 20, %g4 rdpr %tstate, %g1 + sllx %g4, 20, %g4 rdpr %tpc, %g2 or %g1, %g4, %g1 rdpr %tnpc, %g3 @@ -39,6 +38,7 @@ * trap level until PRIMARY_CONTEXT is set to zero, else * we fall out of NUCLEUS too soon and crash hard. */ + rdpr %wstate, %g5 mov PRIMARY_CONTEXT, %g7 ldxa [%g7] ASI_DMMU, %g4 mov SECONDARY_CONTEXT, %g6 diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/idprom.c linux/arch/sparc64/kernel/idprom.c --- v2.1.35/linux/arch/sparc64/kernel/idprom.c Mon Dec 30 01:59:59 1996 +++ linux/arch/sparc64/kernel/idprom.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: idprom.c,v 1.1 1996/12/28 18:39:38 davem Exp $ +/* $Id: idprom.c,v 1.2 1997/04/17 02:28:10 miguel Exp $ * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. * @@ -34,14 +34,12 @@ idprom = &idprom_buffer; if (idprom->id_format != 0x01) { - prom_printf("IDPROM: Unknown format type!\n"); - prom_halt(); + prom_printf("IDPROM: Warning, unknown format type!\n"); } if (idprom->id_cksum != calc_idprom_cksum(idprom)) { - prom_printf("IDPROM: Checksum failure (nvram=%x, calc=%x)!\n", + prom_printf("IDPROM: Warning, checksum failure (nvram=%x, calc=%x)!\n", idprom->id_cksum, calc_idprom_cksum(idprom)); - prom_halt(); } printk("Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n", diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c --- v2.1.35/linux/arch/sparc64/kernel/irq.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/irq.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.11 1997/04/14 05:38:59 davem Exp $ +/* $Id: irq.c,v 1.12 1997/04/16 05:56:20 davem Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -382,7 +382,7 @@ /* Per-processor IRQ locking depth, both SMP and non-SMP code use this. */ unsigned int local_irq_count[NR_CPUS]; -atomic_t __sparc64_bh_counter; +atomic_t __sparc64_bh_counter = ATOMIC_INIT(0); #ifdef __SMP__ #error SMP not supported on sparc64 just yet diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c --- v2.1.35/linux/arch/sparc64/kernel/signal32.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/signal32.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.5 1997/04/07 18:57:09 jj Exp $ +/* $Id: signal32.c,v 1.6 1997/04/16 10:27:17 jj Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -32,7 +32,8 @@ #define synchronize_user_stack() do { } while (0) -asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options); +asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, + int options, unsigned long *ru); asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs, unsigned long orig_o0, int ret_from_syscall); @@ -85,12 +86,15 @@ * atomically swap in the new signal mask, and wait for a signal. * This is really tricky on the Sparc, watch out... */ -asmlinkage inline void _sigpause32_common(unsigned int set, struct pt_regs *regs) +asmlinkage void _sigpause32_common(unsigned int set, struct pt_regs *regs) { unsigned int mask; + spin_lock_irq(¤t->sigmask_lock); mask = current->blocked; current->blocked = set & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + regs->tpc = regs->tnpc; regs->tnpc += 4; @@ -115,16 +119,12 @@ asmlinkage void do_sigpause32(unsigned int set, struct pt_regs *regs) { - lock_kernel (); _sigpause32_common(set, regs); - unlock_kernel (); } asmlinkage void do_sigsuspend32(struct pt_regs *regs) { - lock_kernel (); _sigpause32_common(regs->u_regs[UREG_I0], regs); - unlock_kernel (); } @@ -158,15 +158,15 @@ sf = (struct new_signal_frame32 *) regs->u_regs [UREG_FP]; /* 1. Make sure we are not getting garbage from the user */ if (verify_area (VERIFY_READ, sf, sizeof (*sf))){ - do_exit (SIGSEGV); + goto segv; } if (((unsigned long) sf) & 3){ - do_exit (SIGSEGV); + goto segv; } get_user(pc, &sf->info.si_regs.pc); __get_user(npc, &sf->info.si_regs.npc); if ((pc | npc) & 3){ - do_exit (SIGSEGV); + goto segv; } regs->tpc = pc; regs->tnpc = npc; @@ -187,15 +187,18 @@ restore_fpu_state32(regs, &sf->fpu_state); __get_user(mask, &sf->info.si_mask); current->blocked = mask & _BLOCKABLE; - unlock_kernel(); + return; +segv: + lock_kernel(); + do_exit(SIGSEGV); } asmlinkage void do_sigreturn32(struct pt_regs *regs) { struct sigcontext32 *scptr; unsigned pc, npc, psr; + unsigned long mask; - lock_kernel (); synchronize_user_stack(); if (current->tss.new_signal) return do_new_sigreturn32(regs); @@ -204,18 +207,15 @@ /* Check sanity of the user arg. */ if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) || (((unsigned long) scptr) & 3)) { - printk("%s [%d]: do_sigreturn, scptr is invalid at " - "pc<%016lx> scptr<%p>\n", - current->comm, current->pid, regs->tpc, scptr); - do_exit(SIGSEGV); + goto segv; } __get_user(pc, &scptr->sigc_pc); __get_user(npc, &scptr->sigc_npc); if((pc | npc) & 3) - do_exit(SIGSEGV); /* Nice try. */ + goto segv; /* Nice try. */ - __get_user(current->blocked, &scptr->sigc_mask); - current->blocked &= _BLOCKABLE; + __get_user(mask, &scptr->sigc_mask); + current->blocked = (mask & _BLOCKABLE); __get_user(current->tss.sstk_info.cur_status, &scptr->sigc_onstack); current->tss.sstk_info.cur_status &= 1; regs->tpc = pc; @@ -228,7 +228,10 @@ __get_user(psr, &scptr->sigc_psr); regs->tstate &= ~(TSTATE_ICC); regs->tstate |= psr_to_tstate_icc(psr); - unlock_kernel (); + return; +segv: + lock_kernel (); + do_exit (SIGSEGV); } /* Checks if the fp is valid */ @@ -239,7 +242,7 @@ return 0; } -static inline void +static void setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, struct pt_regs *regs, int signr, unsigned long oldmask) { @@ -264,8 +267,8 @@ /* Don't change signal code and address, so that * post mortem debuggers can have a look. */ + lock_kernel (); do_exit(SIGILL); - return; } sc = &sframep->sig_context; @@ -358,15 +361,15 @@ sf = (struct new_signal_frame32 *)(regs->u_regs[UREG_FP] - sigframe_size); if (invalid_frame_pointer (sf, sigframe_size)){ + lock_kernel (); do_exit(SIGILL); - return; } if (current->tss.w_saved != 0){ printk ("%s[%d]: Invalid user stack frame for " "signal delivery.\n", current->comm, current->pid); + lock_kernel (); do_exit (SIGILL); - return; } /* 2. Save the current process state */ @@ -433,8 +436,8 @@ #ifdef DEBUG_SIGNALS printk ("Invalid stack frame\n"); #endif + lock_kernel (); do_exit(SIGILL); - return; } /* Start with a clean frame pointer and fill it */ @@ -705,7 +708,14 @@ if(sa->sa_handler == SIG_IGN) { if(signr != SIGCHLD) continue; - while(sys_waitpid(-1,NULL,WNOHANG) > 0); + + /* sys_wait4() grabs the master kernel lock, so + * we need not do so, that sucker should be + * threaded and would not be that difficult to + * do anyways. + */ + while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + ; continue; } if(sa->sa_handler == SIG_DFL) { diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c --- v2.1.35/linux/arch/sparc64/kernel/sparc64_ksyms.c Thu Mar 27 14:40:01 1997 +++ linux/arch/sparc64/kernel/sparc64_ksyms.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.3 1997/03/18 17:59:10 jj Exp $ +/* $Id: sparc64_ksyms.c,v 1.4 1997/04/14 17:04:43 jj Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -162,7 +162,8 @@ EXPORT_SYMBOL(__csum_partial_copy_sparc_generic); /* Moving data to/from userspace. */ -EXPORT_SYMBOL(__copy_user); +EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(__copy_from_user); EXPORT_SYMBOL(__strncpy_from_user); /* No version information on this, heavily used in inline asm, diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/sparcelf32.c linux/arch/sparc64/kernel/sparcelf32.c --- v2.1.35/linux/arch/sparc64/kernel/sparcelf32.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/sparcelf32.c Thu Apr 17 13:20:44 1997 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -156,20 +157,20 @@ sp -= argc+1; argv = (__u32 *) sp; if (!ibcs) { - __put_user(((__u32) envp),--sp); - __put_user(((__u32) argv),--sp); + __put_user(((__u32)(long) envp),--sp); + __put_user(((__u32)(long) argv),--sp); } __put_user((__u32)argc,--sp); current->mm->arg_start = (unsigned long) p; while (argc-->0) { - __put_user(((__u32)p),argv++); + __put_user(((__u32)(long)p),argv++); p += strlen_user(p); } __put_user(NULL, argv); current->mm->arg_end = current->mm->env_start = (unsigned long) p; while (envc-->0) { - __put_user(((__u32)p),envp++); + __put_user(((__u32)(long)p),envp++); p += strlen_user(p); } __put_user(NULL, envp); @@ -1108,7 +1109,7 @@ #else if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { - printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n", + printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); } else @@ -1255,7 +1256,7 @@ } #endif /* USE_ELF_CORE_DUMP */ -int init_elf32_binfmt(void) +__initfunc(int init_elf32_binfmt(void)) { return register_binfmt(&elf32_format); } diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c --- v2.1.35/linux/arch/sparc64/kernel/sys_sparc32.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/sys_sparc32.c Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.3 1997/04/09 08:25:17 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) @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -32,9 +38,6 @@ * produce warnings */ #define A(x) ((unsigned long)x) -/* FIXME: All struct * etc. stuff should be examined and proper structure conversions - * added ASAP -JJ */ - extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on); extern asmlinkage unsigned long sys_brk(unsigned long brk); extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off); @@ -69,7 +72,6 @@ extern asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count); extern asmlinkage long sys_readv(unsigned long fd, const struct iovec * vector, unsigned long count); extern asmlinkage long sys_writev(unsigned long fd, const struct iovec * vector, unsigned long count); -extern asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count); extern asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp); extern asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout); extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf); @@ -102,7 +104,6 @@ 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); @@ -136,12 +137,57 @@ 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_ioperm((unsigned long)from, (unsigned long)num, on); } +struct msgbuf32 { s32 mtype; char mtext[1]; }; + +struct ipc_perm32 +{ + key_t key; + __kernel_uid_t32 uid; + __kernel_gid_t32 gid; + __kernel_uid_t32 cuid; + __kernel_gid_t32 cgid; + __kernel_mode_t32 mode; + unsigned short seq; +}; + +struct msqid_ds32 +{ + struct ipc_perm32 msg_perm; + u32 msg_first; + u32 msg_last; + __kernel_time_t32 msg_stime; + __kernel_time_t32 msg_rtime; + __kernel_time_t32 msg_ctime; + u32 wwait; + u32 rwait; + unsigned short msg_cbytes; + unsigned short msg_qnum; + unsigned short msg_qbytes; + __kernel_ipc_pid_t32 msg_lspid; + __kernel_ipc_pid_t32 msg_lrpid; +}; + +struct shmid_ds32 { + struct ipc_perm32 shm_perm; + int shm_segsz; + __kernel_time_t32 shm_atime; + __kernel_time_t32 shm_dtime; + __kernel_time_t32 shm_ctime; + __kernel_ipc_pid_t32 shm_cpid; + __kernel_ipc_pid_t32 shm_lpid; + unsigned short shm_nattch; + unsigned short shm_npages; + u32 shm_pages; + u32 attaches; +}; + /* * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.. * @@ -184,32 +230,111 @@ if (call <= MSGCTL) switch (call) { case MSGSND: - /* XXX struct msgbuf has a long first :(( */ - err = sys_msgsnd (first, (struct msgbuf *) A(ptr), - second, third); + { + struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_KERNEL); + + if (!p) err = -ENOMEM; + else { + if (get_user(p->mtype, &(((struct msgbuf32 *)A(ptr))->mtype)) || + __copy_from_user(p->mtext, &(((struct msgbuf32 *)A(ptr))->mtext), second)) + err = -EFAULT; + else { + unsigned long old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_msgsnd (first, p, second, third); + set_fs (old_fs); + } + kfree (p); + } + } goto out; case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - err = -EINVAL; - if (!ptr) - goto out; - err = -EFAULT; - if(copy_from_user(&tmp,(struct ipc_kludge *) ptr, sizeof (tmp))) + { + struct msgbuf *p; + unsigned long old_fs; + + if (!version) { + struct ipc_kludge tmp; + err = -EINVAL; + if (!ptr) + goto out; + err = -EFAULT; + if(copy_from_user(&tmp,(struct ipc_kludge *)A(ptr), sizeof (tmp))) + goto out; + ptr = tmp.msgp; + fifth = tmp.msgtyp; + } + p = kmalloc (second + sizeof (struct msgbuf), GFP_KERNEL); + if (!p) { + err = -EFAULT; goto out; - err = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); - goto out; } - case 1: default: - err = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third); + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_msgrcv (first, p, second, fifth, third); + set_fs (old_fs); + if (put_user (p->mtype, &(((struct msgbuf32 *)A(ptr))->mtype)) || + __copy_to_user(&(((struct msgbuf32 *)A(ptr))->mtext), p->mtext, second)) + err = -EFAULT; + kfree (p); goto out; } case MSGGET: err = sys_msgget ((key_t) first, second); goto out; case MSGCTL: - err = sys_msgctl (first, second, (struct msqid_ds *) ptr); + { + struct msqid_ds m; + unsigned long old_fs; + + switch (second) { + case IPC_INFO: + case MSG_INFO: + /* struct msginfo is the same */ + case IPC_RMID: + /* and this doesn't care about ptr */ + err = sys_msgctl (first, second, (struct msqid_ds *)A(ptr)); + goto out; + + case IPC_SET: + if (get_user (m.msg_perm.uid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.uid)) || + __get_user (m.msg_perm.gid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.gid)) || + __get_user (m.msg_perm.mode, &(((struct msqid_ds32 *)A(ptr))->msg_perm.mode)) || + __get_user (m.msg_qbytes, &(((struct msqid_ds32 *)A(ptr))->msg_qbytes))) { + err = -EFAULT; + goto out; + } + default: + break; + } + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_msgctl (first, second, &m); + set_fs (old_fs); + switch (second) { + case MSG_STAT: + case IPC_STAT: + if (put_user (m.msg_perm.key, &(((struct msqid_ds32 *)A(ptr))->msg_perm.key)) || + __put_user (m.msg_perm.uid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.uid)) || + __put_user (m.msg_perm.gid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.gid)) || + __put_user (m.msg_perm.cuid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.cuid)) || + __put_user (m.msg_perm.cgid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.cgid)) || + __put_user (m.msg_perm.mode, &(((struct msqid_ds32 *)A(ptr))->msg_perm.mode)) || + __put_user (m.msg_perm.seq, &(((struct msqid_ds32 *)A(ptr))->msg_perm.seq)) || + __put_user (m.msg_stime, &(((struct msqid_ds32 *)A(ptr))->msg_stime)) || + __put_user (m.msg_rtime, &(((struct msqid_ds32 *)A(ptr))->msg_rtime)) || + __put_user (m.msg_ctime, &(((struct msqid_ds32 *)A(ptr))->msg_ctime)) || + __put_user (m.msg_cbytes, &(((struct msqid_ds32 *)A(ptr))->msg_cbytes)) || + __put_user (m.msg_qnum, &(((struct msqid_ds32 *)A(ptr))->msg_qnum)) || + __put_user (m.msg_qbytes, &(((struct msqid_ds32 *)A(ptr))->msg_qbytes)) || + __put_user (m.msg_lspid, &(((struct msqid_ds32 *)A(ptr))->msg_lspid)) || + __put_user (m.msg_lrpid, &(((struct msqid_ds32 *)A(ptr))->msg_lrpid))) + err = -EFAULT; + break; + default: + break; + } + } goto out; default: err = -EINVAL; @@ -220,28 +345,92 @@ case SHMAT: switch (version) { case 0: default: { - ulong raddr; - err = sys_shmat (first, (char *) ptr, second, &raddr); + unsigned long raddr; + err = sys_shmat (first, (char *)A(ptr), second, &raddr); if (err) goto out; err = -EFAULT; - if(put_user (raddr, (ulong *) third)) + if(put_user (raddr, ((u32 *)A(third)))) goto out; err = 0; goto out; } - case 1: /* iBCS2 emulator entry point */ - err = sys_shmat (first, (char *) ptr, second, (ulong *) third); + case 1: /* If iBCS2 should ever run, then for sure in 64bit mode, not 32bit... */ + err = -EINVAL; goto out; } case SHMDT: - err = sys_shmdt ((char *)ptr); + err = sys_shmdt ((char *)A(ptr)); goto out; case SHMGET: err = sys_shmget (first, second, third); goto out; case SHMCTL: - err = sys_shmctl (first, second, (struct shmid_ds *) ptr); + { + struct shmid_ds s; + unsigned long old_fs; + + switch (second) { + case IPC_INFO: + /* struct shminfo is the same */ + case SHM_LOCK: + case SHM_UNLOCK: + case IPC_RMID: + /* and these three aren't using ptr at all */ + err = sys_shmctl (first, second, (struct shmid_ds *)A(ptr)); + goto out; + + case IPC_SET: + if (get_user (s.shm_perm.uid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.uid)) || + __get_user (s.shm_perm.gid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.gid)) || + __get_user (s.shm_perm.mode, &(((struct shmid_ds32 *)A(ptr))->shm_perm.mode))) { + err = -EFAULT; + goto out; + } + default: + break; + } + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_shmctl (first, second, &s); + set_fs (old_fs); + switch (second) { + case SHM_INFO: + { + struct shm_info32 { int used_ids; u32 shm_tot; u32 shm_rss; u32 shm_swp; u32 swap_attempts; u32 swap_successes; }; + struct shm_info *si = (struct shm_info *)&s; + + if (put_user (si->used_ids, &(((struct shm_info32 *)A(ptr))->used_ids)) || + __put_user (si->shm_tot, &(((struct shm_info32 *)A(ptr))->shm_tot)) || + __put_user (si->shm_rss, &(((struct shm_info32 *)A(ptr))->shm_rss)) || + __put_user (si->shm_swp, &(((struct shm_info32 *)A(ptr))->shm_swp)) || + __put_user (si->swap_attempts, &(((struct shm_info32 *)A(ptr))->swap_attempts)) || + __put_user (si->swap_successes, &(((struct shm_info32 *)A(ptr))->swap_successes))) + err = -EFAULT; + } + break; + case SHM_STAT: + case IPC_STAT: + if (put_user (s.shm_perm.key, &(((struct shmid_ds32 *)A(ptr))->shm_perm.key)) || + __put_user (s.shm_perm.uid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.uid)) || + __put_user (s.shm_perm.gid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.gid)) || + __put_user (s.shm_perm.cuid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.cuid)) || + __put_user (s.shm_perm.cgid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.cgid)) || + __put_user (s.shm_perm.mode, &(((struct shmid_ds32 *)A(ptr))->shm_perm.mode)) || + __put_user (s.shm_perm.seq, &(((struct shmid_ds32 *)A(ptr))->shm_perm.seq)) || + __put_user (s.shm_atime, &(((struct shmid_ds32 *)A(ptr))->shm_atime)) || + __put_user (s.shm_dtime, &(((struct shmid_ds32 *)A(ptr))->shm_dtime)) || + __put_user (s.shm_ctime, &(((struct shmid_ds32 *)A(ptr))->shm_ctime)) || + __put_user (s.shm_segsz, &(((struct shmid_ds32 *)A(ptr))->shm_segsz)) || + __put_user (s.shm_nattch, &(((struct shmid_ds32 *)A(ptr))->shm_nattch)) || + __put_user (s.shm_lpid, &(((struct shmid_ds32 *)A(ptr))->shm_cpid)) || + __put_user (s.shm_cpid, &(((struct shmid_ds32 *)A(ptr))->shm_lpid))) + err = -EFAULT; + break; + default: + break; + } + } goto out; default: err = -EINVAL; @@ -272,15 +461,45 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, u32 arg) { - return sys_fcntl(fd, cmd, (unsigned long)arg); + switch (cmd) { + case F_GETLK: + case F_SETLK: + case F_SETLKW: + { + struct flock f; + unsigned long old_fs; + long ret; + + if (get_user (f.l_type, &(((struct flock32 *)A(arg))->l_type)) || + __get_user (f.l_whence, &(((struct flock32 *)A(arg))->l_whence)) || + __get_user (f.l_start, &(((struct flock32 *)A(arg))->l_start)) || + __get_user (f.l_len, &(((struct flock32 *)A(arg))->l_len)) || + __get_user (f.l_pid, &(((struct flock32 *)A(arg))->l_pid))) + return -EFAULT; + old_fs = get_fs(); set_fs (KERNEL_DS); + ret = sys_fcntl(fd, cmd, (unsigned long)&f); + set_fs (old_fs); + if (__put_user (f.l_type, &(((struct flock32 *)A(arg))->l_type)) || + __put_user (f.l_whence, &(((struct flock32 *)A(arg))->l_whence)) || + __put_user (f.l_start, &(((struct flock32 *)A(arg))->l_start)) || + __put_user (f.l_len, &(((struct flock32 *)A(arg))->l_len)) || + __put_user (f.l_pid, &(((struct flock32 *)A(arg))->l_pid))) + return -EFAULT; + return ret; + } + default: + return sys_fcntl(fd, cmd, (unsigned long)arg); + } } +/* Conversion of args should be probably done in all the locations where it is handled, + using if (current->tss.flags & SPARC_FLAG_32BIT */ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg) { return sys_ioctl(fd, cmd, (unsigned long)arg); } -asmlinkage int sys32_mknod(u32 filename, int mode, dev_t dev) +asmlinkage int sys32_mknod(u32 filename, int mode, __kernel_dev_t32 dev) { return sys_mknod((const char *)A(filename), mode, dev); } @@ -315,19 +534,52 @@ return sys_rename((const char *)A(oldname), (const char *)A(newname)); } +/* XXX: Play with the addr, it will be ugly :(( */ asmlinkage int sys32_quotactl(int cmd, u32 special, int id, u32 addr) { return sys_quotactl(cmd, (const char *)A(special), id, (caddr_t)A(addr)); } +static int put_statfs (u32 buf, struct statfs *s) +{ + if (put_user (s->f_type, &(((struct statfs32 *)A(buf))->f_type)) || + __put_user (s->f_bsize, &(((struct statfs32 *)A(buf))->f_bsize)) || + __put_user (s->f_blocks, &(((struct statfs32 *)A(buf))->f_blocks)) || + __put_user (s->f_bfree, &(((struct statfs32 *)A(buf))->f_bfree)) || + __put_user (s->f_bavail, &(((struct statfs32 *)A(buf))->f_bavail)) || + __put_user (s->f_files, &(((struct statfs32 *)A(buf))->f_files)) || + __put_user (s->f_ffree, &(((struct statfs32 *)A(buf))->f_ffree)) || + __put_user (s->f_namelen, &(((struct statfs32 *)A(buf))->f_namelen)) || + __put_user (s->f_fsid.val[0], &(((struct statfs32 *)A(buf))->f_fsid.val[0])) || + __put_user (s->f_fsid.val[1], &(((struct statfs32 *)A(buf))->f_fsid.val[1]))) + return -EFAULT; + return 0; +} + asmlinkage int sys32_statfs(u32 path, u32 buf) { - return sys_statfs((const char *)A(path), (struct statfs *)A(buf)); + int ret; + struct statfs s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_statfs((const char *)A(path), &s); + set_fs (old_fs); + if (put_statfs(buf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_fstatfs(unsigned int fd, u32 buf) { - return sys_fstatfs(fd, (struct statfs *)A(buf)); + int ret; + struct statfs s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_fstatfs(fd, &s); + set_fs (old_fs); + if (put_statfs(buf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_truncate(u32 path, u32 length) @@ -342,11 +594,24 @@ asmlinkage int sys32_utime(u32 filename, u32 times) { - return sys_utime((char *)A(filename), (struct utimbuf *)A(times)); + struct utimbuf32 { __kernel_time_t32 actime, modtime; }; + struct utimbuf t; + unsigned long old_fs; + int ret; + + if (get_user (t.actime, &(((struct utimbuf32 *)A(times))->actime)) || + __get_user (t.modtime, &(((struct utimbuf32 *)A(times))->modtime))) + return -EFAULT; + old_fs = get_fs(); + set_fs (KERNEL_DS); + ret = sys_utime((char *)A(filename), &t); + set_fs (old_fs); + return ret; } asmlinkage int sys32_utimes(u32 filename, u32 utimes) { + /* struct timeval is the same :)) */ return sys_utimes((char *)A(filename), (struct timeval *)A(utimes)); } @@ -365,12 +630,12 @@ return sys_chroot((const char *)A(filename)); } -asmlinkage int sys32_chmod(u32 filename, mode_t mode) +asmlinkage int sys32_chmod(u32 filename, __kernel_mode_t32 mode) { return sys_chmod((const char *)A(filename), mode); } -asmlinkage int sys32_chown(u32 filename, uid_t user, gid_t group) +asmlinkage int sys32_chown(u32 filename, __kernel_uid_t32 user, __kernel_gid_t32 group) { return sys_chown((const char *)A(filename), user, group); } @@ -392,6 +657,7 @@ asmlinkage int sys32_llseek(unsigned int fd, u32 offset_high, u32 offset_low, u32 result, unsigned int origin) { + /* loff_t is the same :)) */ return sys_llseek(fd, (unsigned long)offset_high, (unsigned long)offset_low, (loff_t *)A(result), origin); } @@ -405,24 +671,264 @@ 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) { - return sys_readv((unsigned long)fd, (const struct iovec *)A(vector), (unsigned long)count); + 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; + 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))) { + 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); +out: + if (count > UIO_FASTIOV) { + kfree (v); + unlock_kernel (); + } + return ret; } asmlinkage long sys32_writev(u32 fd, u32 vector, u32 count) { - return sys_writev((unsigned long)fd, (const struct iovec *)A(vector), (unsigned long)count); + 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; + 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))) { + 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); +out: + if (count > UIO_FASTIOV) { + kfree (v); + unlock_kernel (); + } + return ret; +} + +/* readdir & getdents */ + +#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) +#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) + +struct old_linux_dirent32 { + u32 d_ino; + u32 d_offset; + unsigned short d_namlen; + char d_name[1]; +}; + +struct readdir_callback32 { + struct old_linux_dirent32 * dirent; + int count; +}; + +static int fillonedir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino) +{ + struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; + struct old_linux_dirent32 * dirent; + + if (buf->count) + return -EINVAL; + buf->count++; + dirent = buf->dirent; + put_user(ino, &dirent->d_ino); + put_user(offset, &dirent->d_offset); + put_user(namlen, &dirent->d_namlen); + copy_to_user(dirent->d_name, name, namlen); + put_user(0, dirent->d_name + namlen); + return 0; +} + +asmlinkage int old32_readdir(unsigned int fd, u32 dirent, unsigned int count) +{ + int error = -EBADF; + struct file * file; + struct readdir_callback32 buf; + + lock_kernel(); + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) + goto out; + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + error = verify_area(VERIFY_WRITE, (void *)A(dirent), sizeof(struct old_linux_dirent32)); + if (error) + goto out; + buf.count = 0; + buf.dirent = (struct old_linux_dirent32 *)A(dirent); + error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir); + if (error < 0) + goto out; + error = buf.count; +out: + unlock_kernel(); + return error; +} + +struct linux_dirent32 { + u32 d_ino; + u32 d_off; + unsigned short d_reclen; + char d_name[1]; +}; + +struct getdents_callback32 { + struct linux_dirent32 * current_dir; + struct linux_dirent32 * previous; + int count; + int error; +}; + +static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino) +{ + struct linux_dirent32 * dirent; + struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf; + int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); + + buf->error = -EINVAL; /* only used if we fail.. */ + if (reclen > buf->count) + return -EINVAL; + dirent = buf->previous; + if (dirent) + put_user(offset, &dirent->d_off); + dirent = buf->current_dir; + buf->previous = dirent; + put_user(ino, &dirent->d_ino); + put_user(reclen, &dirent->d_reclen); + copy_to_user(dirent->d_name, name, namlen); + put_user(0, dirent->d_name + namlen); + ((char *) dirent) += reclen; + buf->current_dir = dirent; + buf->count -= reclen; + return 0; } asmlinkage int sys32_getdents(unsigned int fd, u32 dirent, unsigned int count) { - return sys_getdents(fd, (void *)A(dirent), count); + struct file * file; + struct linux_dirent32 * lastdirent; + struct getdents_callback32 buf; + int error = -EBADF; + + lock_kernel(); + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) + goto out; + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + error = verify_area(VERIFY_WRITE, (void *)A(dirent), count); + if (error) + goto out; + buf.current_dir = (struct linux_dirent32 *) A(dirent); + buf.previous = NULL; + buf.count = count; + buf.error = 0; + error = file->f_op->readdir(file->f_inode, file, &buf, filldir); + if (error < 0) + goto out; + lastdirent = buf.previous; + if (!lastdirent) { + error = buf.error; + } else { + put_user(file->f_pos, &lastdirent->d_off); + error = count - buf.count; + } +out: + unlock_kernel(); + return error; } +/* end of readdir & getdents */ + asmlinkage int sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp) { - return sys_select(n, (fd_set *)A(inp), (fd_set *)A(outp), (fd_set *)A(exp), (struct timeval *)A(tvp)); + unsigned long old_fs; + char *p; + u32 *q; + int i, ret = -EINVAL, nn; + u32 *Inp, *Outp, *Exp; + + if (n < 0 || n > PAGE_SIZE*2) return -EINVAL; + lock_kernel (); + p = (char *)__get_free_page (GFP_KERNEL); + if (!p) goto out; + q = (u32 *)p; + nn = (n + 8 * sizeof(unsigned long) - 1) / (8 * sizeof (unsigned long)); + Inp = (u32 *)A(inp); Outp = (u32 *)A(outp); Exp = (u32 *)A(exp); + ret = -EFAULT; + for (i = 0; i < ret; i++, Inp += 2, Outp += 2, Exp += 2, q += 2) { + if (__get_user (q[1], Inp) || + __get_user (q[0], Inp+1) || + __get_user (q[1+PAGE_SIZE/4], Outp) || + __get_user (q[PAGE_SIZE/4], Outp+1) || + __get_user (q[1+PAGE_SIZE/2], Exp) || + __get_user (q[PAGE_SIZE/2], Exp+1)) + goto out; + } + old_fs = get_fs (); + set_fs (KERNEL_DS); + ret = sys_select(n, (fd_set *)p, (fd_set *)(p + PAGE_SIZE/4), (fd_set *)(p + PAGE_SIZE/2), (struct timeval *)A(tvp)); + set_fs (old_fs); + q = (u32 *)p; + Inp = (u32 *)A(inp); Outp = (u32 *)A(outp); Exp = (u32 *)A(exp); + for (i = 0; i < ret; i++, Inp += 2, Outp += 2, Exp += 2, q += 2) { + if (__put_user (q[1], Inp) || + __put_user (q[0], Inp+1) || + __put_user (q[1+PAGE_SIZE/4], Outp) || + __put_user (q[PAGE_SIZE/4], Outp+1) || + __put_user (q[1+PAGE_SIZE/2], Exp) || + __put_user (q[PAGE_SIZE/2], Exp+1)) { + ret = -EFAULT; + goto out; + } + } +out: + free_page ((unsigned long)p); + return ret; } asmlinkage int sys32_poll(u32 ufds, unsigned int nfds, int timeout) @@ -430,19 +936,62 @@ return sys_poll((struct pollfd *)A(ufds), nfds, timeout); } +static inline int putstat(u32 statbuf, struct stat *s) +{ + if (put_user (s->st_dev, &(((struct stat32 *)A(statbuf))->st_dev)) || + __put_user (s->st_ino, &(((struct stat32 *)A(statbuf))->st_ino)) || + __put_user (s->st_mode, &(((struct stat32 *)A(statbuf))->st_mode)) || + __put_user (s->st_nlink, &(((struct stat32 *)A(statbuf))->st_nlink)) || + __put_user (s->st_uid, &(((struct stat32 *)A(statbuf))->st_uid)) || + __put_user (s->st_gid, &(((struct stat32 *)A(statbuf))->st_gid)) || + __put_user (s->st_rdev, &(((struct stat32 *)A(statbuf))->st_rdev)) || + __put_user (s->st_size, &(((struct stat32 *)A(statbuf))->st_size)) || + __put_user (s->st_atime, &(((struct stat32 *)A(statbuf))->st_atime)) || + __put_user (s->st_mtime, &(((struct stat32 *)A(statbuf))->st_mtime)) || + __put_user (s->st_ctime, &(((struct stat32 *)A(statbuf))->st_ctime)) || + __put_user (s->st_blksize, &(((struct stat32 *)A(statbuf))->st_blksize)) || + __put_user (s->st_blocks, &(((struct stat32 *)A(statbuf))->st_blocks))) + return -EFAULT; + return 0; +} + asmlinkage int sys32_newstat(u32 filename, u32 statbuf) { - return sys_newstat((char *)A(filename), (struct stat *)A(statbuf)); + int ret; + struct stat s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_newstat((char *)A(filename), &s); + set_fs (old_fs); + if (putstat (statbuf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_newlstat(u32 filename, u32 statbuf) { - return sys_newlstat((char *)A(filename), (struct stat *)A(statbuf)); + int ret; + struct stat s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_newlstat((char *)A(filename), &s); + set_fs (old_fs); + if (putstat (statbuf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_newfstat(unsigned int fd, u32 statbuf) { - return sys_newfstat(fd, (struct stat *)A(statbuf)); + int ret; + struct stat s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_newfstat(fd, &s); + set_fs (old_fs); + if (putstat (statbuf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_readlink(u32 path, u32 buf, int bufsiz) @@ -454,7 +1003,7 @@ { va_list args; unsigned int x; - int ret; + int ret = -EINVAL; va_start(args, option); switch (option) { @@ -475,6 +1024,7 @@ asmlinkage int sys32_ustat(dev_t dev, u32 ubuf) { + /* ustat is the same :)) */ return sys_ustat(dev, (struct ustat *)A(ubuf)); } @@ -499,23 +1049,111 @@ 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_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(pid_t pid, u32 stat_addr, int options) +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)); } @@ -524,39 +1162,87 @@ 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) @@ -576,34 +1262,84 @@ 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)); @@ -624,19 +1360,54 @@ 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) @@ -646,6 +1417,7 @@ 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)); } @@ -654,22 +1426,86 @@ 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); } @@ -679,12 +1515,12 @@ 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); } @@ -706,6 +1542,7 @@ asmlinkage int sys32_bind(int fd, u32 umyaddr, int addrlen) { + /* sockaddr is the same :)) */ return sys_bind(fd, (struct sockaddr *)A(umyaddr), addrlen); } @@ -729,28 +1566,31 @@ 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); } @@ -759,6 +1599,7 @@ 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); @@ -809,7 +1650,7 @@ 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))) @@ -828,4 +1669,73 @@ out: unlock_kernel(); return err; +} + +asmlinkage int sys32_nfsservctl(int cmd, u32 argp, u32 resp) +{ + /* XXX handle argp and resp args */ + return sys_nfsservctl(cmd, (void *)A(argp), (void *)A(resp)); +} + +struct ncp_mount_data32 { + int version; + unsigned int ncp_fd; + __kernel_uid_t32 mounted_uid; + __kernel_pid_t32 wdog_pid; + unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; + unsigned int time_out; + unsigned int retry_count; + unsigned int flags; + __kernel_uid_t32 uid; + __kernel_gid_t32 gid; + __kernel_mode_t32 file_mode; + __kernel_mode_t32 dir_mode; +}; + +void *do_ncp_super_data_conv(void *raw_data) +{ + struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data; + struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data; + + n->dir_mode = n32->dir_mode; + n->file_mode = n32->file_mode; + n->gid = n32->gid; + n->uid = n32->uid; + memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int))); + n->wdog_pid = n32->wdog_pid; + n->mounted_uid = n32->mounted_uid; + return raw_data; +} + +struct smb_mount_data32 { + int version; + unsigned int fd; + __kernel_uid_t32 mounted_uid; + struct sockaddr_in addr; + char server_name[17]; + char client_name[17]; + char service[64]; + char root_path[64]; + char username[64]; + char password[64]; + char domain[64]; + unsigned short max_xmit; + __kernel_uid_t32 uid; + __kernel_gid_t32 gid; + __kernel_mode_t32 file_mode; + __kernel_mode_t32 dir_mode; +}; + +void *do_smb_super_data_conv(void *raw_data) +{ + struct smb_mount_data *s = (struct smb_mount_data *)raw_data; + struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data; + + s->dir_mode = s32->dir_mode; + s->file_mode = s32->file_mode; + s->gid = s32->gid; + s->uid = s32->uid; + memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr))); + s->mounted_uid = s32->mounted_uid; + return raw_data; } diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S --- v2.1.35/linux/arch/sparc64/kernel/systbls.S Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/systbls.S Tue Apr 22 22:49:38 1997 @@ -1,8 +1,9 @@ -/* $Id: systbls.S,v 1.5 1997/04/09 08:25:16 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: * @@ -56,7 +57,7 @@ .xword sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_newuname /*190*/ .xword sys_nis_syscall, sys32_personality, sys_prof, sys_break, sys_lock .xword sys_mpx, sys_ulimit, sys_getppid, sparc32_sigaction, sys_sgetmask -/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys32_uselib, old_readdir +/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys32_uselib, old32_readdir .xword sys_nis_syscall, sys32_socketcall, sys32_syslog, sys32_olduname, sys_nis_syscall /*210*/ .xword sys_idle, sys_nis_syscall, sys32_waitpid, sys32_swapoff, sys32_sysinfo .xword sys32_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex @@ -66,7 +67,7 @@ .xword sys_nis_syscall, sys32_llseek, sys32_mlock, sys32_munlock, sys_mlockall /*240*/ .xword sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys_nis_syscall, sys_nis_syscall .xword sys_nis_syscall, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys_nanosleep -/*250*/ .xword sys32_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall +/*250*/ .xword sys32_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl .xword sys_aplib, sys_nis_syscall /* Now the 64-bit native Linux syscall table. */ @@ -114,8 +115,8 @@ .xword sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_newuname /*190*/ .xword sys_init_module, sys_personality, sys_prof, sys_break, sys_lock .xword sys_mpx, sys_ulimit, sys_getppid, sparc_sigaction, sys_sgetmask -/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir - .xword sys_nis_syscall, sys_socketcall, sys_syslog, sys_olduname, sys_nis_syscall +/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, sys_nis_syscall + .xword sys_nis_syscall, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall /*210*/ .xword sys_idle, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo .xword sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex /*220*/ .xword sys_sigprocmask, sys_create_module, sys_delete_module, sys_get_kernel_syms, sys_getpgid @@ -124,7 +125,7 @@ .xword sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .xword sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_nis_syscall, sys_nis_syscall .xword sys_nis_syscall, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/ .xword sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall +/*250*/ .xword sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl .xword sys_aplib, sys_nis_syscall /* Now the 32-bit SunOS syscall table. */ diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/lib/checksum.S linux/arch/sparc64/lib/checksum.S --- v2.1.35/linux/arch/sparc64/lib/checksum.S Mon Apr 14 16:28:10 1997 +++ linux/arch/sparc64/lib/checksum.S Tue Apr 22 22:39:12 1997 @@ -16,6 +16,7 @@ #include #include #include +#include #define CSUM_BIGCHUNK(buf, offset, sum, t0, t1, t2, t3, t4, t5) \ ldd [buf + offset + 0x00], t0; \ @@ -547,22 +548,18 @@ brz,pn %i2, 2f mov %i0, %o1 mov %i1, %o0 -5: - call __memcpy + call __copy_from_user mov %i2, %o2 brnz,a,pn %o0, 2f add %i3, %i2, %i3 add %i1, %i2, %i1 2: mov %i1, %o0 - call __bzero + wr %%g0, ASI_S, %%asi + call __bzero_noasi mov %i3, %o1 1: ldx [%sp + STACK_BIAS + 264], %o2 ! struct_ptr of parent st %i5, [%o2] ret restore - - .section __ex_table,#alloc - .align 4 - .word 5b,2 diff -u --recursive --new-file v2.1.35/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c --- v2.1.35/linux/arch/sparc64/mm/init.c Mon Apr 14 16:28:10 1997 +++ linux/arch/sparc64/mm/init.c Tue Apr 22 22:39:12 1997 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.22 1997/04/12 04:28:48 davem 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) @@ -32,6 +32,9 @@ unsigned long tlb_context_cache = CTX_FIRST_VERSION; +/* References to section boundaries */ +extern char __init_begin, __init_end, etext, __p1275_loc, __bss_start; + /* * BAD_PAGE is the page that is used for page faults when linux * is out-of-memory. Older versions of linux just did a @@ -268,6 +271,7 @@ char *mmu_info(void) { + /* XXX */ return "MMU Type: Spitfire\n\tFIXME: Write this\n"; } @@ -436,15 +440,6 @@ else pte = mk_pte_phys(physaddr, __pgprot(pg_iobits | __DIRTY_BITS)); -#if 0 - prom_printf("IOMAP: vaddr[%016lx]paddr[%016lx]ptep[%016lx]pte[%016lx])\n", - virt_addr, physaddr, (unsigned long) ptep, pte_val(pte)); - prom_printf("IOMAP: pgd[%016lx,%016lx]\n", - (unsigned long) pgdp, pgd_val(*pgdp)); - prom_printf("IOMAP: pmd[%016lx,%016lx]\n", - (unsigned long) pmdp, pmd_val(*pmdp)); -#endif - set_pte(ptep, pte); } @@ -462,6 +457,7 @@ pte_clear(ptep); } +#ifdef DEBUG_MMU void sparc_ultra_dump_itlb(void) { int slot; @@ -485,6 +481,7 @@ slot+1, spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1)); } } +#endif /* paging_init() sets up the page tables */ @@ -493,7 +490,6 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)) { - extern unsigned long __p1275_loc; extern unsigned long phys_base; extern void setup_tba(unsigned long kpgdir); extern void __bfill64(void *, unsigned long); @@ -637,9 +633,10 @@ { int codepages = 0; int datapages = 0; + int initpages = 0; + int prompages = 0; unsigned long tmp2, addr; unsigned long data_end; - extern char etext; end_mem &= PAGE_MASK; max_mapnr = MAP_NR(end_mem); @@ -665,6 +662,10 @@ if(PageReserved(mem_map + MAP_NR(addr))) { if ((addr < (unsigned long) &etext) && (addr >= PAGE_OFFSET)) codepages++; + else if((addr >= (unsigned long)&__init_begin && addr < (unsigned long)&__init_end)) + initpages++; + else if((addr >= (unsigned long)&__p1275_loc && addr < (unsigned long)&__bss_start)) + prompages++; else if((addr < data_end) && (addr >= PAGE_OFFSET)) datapages++; continue; @@ -680,26 +681,23 @@ tmp2 = nr_free_pages << PAGE_SHIFT; - printk("Memory: %luk available (%dk kernel code, %dk data) [%016lx,%016lx]\n", + printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %dk prom) [%016lx,%016lx]\n", tmp2 >> 10, codepages << (PAGE_SHIFT-10), - datapages << (PAGE_SHIFT-10), PAGE_OFFSET, end_mem); + datapages << (PAGE_SHIFT-10), + initpages << (PAGE_SHIFT-10), + prompages << (PAGE_SHIFT-10), + PAGE_OFFSET, end_mem); min_free_pages = nr_free_pages >> 7; if(min_free_pages < 16) min_free_pages = 16; free_pages_low = min_free_pages + (min_free_pages >> 1); free_pages_high = min_free_pages + min_free_pages; - -#if 0 - printk("Done in mem_init() halting\n"); - prom_cmdline(); -#endif } void free_initmem (void) { - extern char __init_begin, __init_end; unsigned long addr; addr = (unsigned long)(&__init_begin); @@ -708,7 +706,6 @@ atomic_set(&mem_map[MAP_NR(addr)].count, 1); free_page(addr); } - printk ("Freeing unused kernel memory: %dk freed\n", (unsigned)((&__init_end - &__init_begin) >> 10)); } void si_meminfo(struct sysinfo *val) diff -u --recursive --new-file v2.1.35/linux/drivers/Makefile linux/drivers/Makefile --- v2.1.35/linux/drivers/Makefile Sun Apr 13 10:18:20 1997 +++ linux/drivers/Makefile Thu Apr 17 14:48:53 1997 @@ -7,17 +7,12 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -SUB_DIRS := block char net #streams +SUB_DIRS := block char net pnp #streams MOD_SUB_DIRS := $(SUB_DIRS) sbus ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sbus sound cdrom isdn pnp ifdef CONFIG_PCI SUB_DIRS += pci -endif - -ifdef CONFIG_PNP -SUB_DIRS += pnp -MOD_SUB_DIRS += pnp endif ifdef CONFIG_SBUS diff -u --recursive --new-file v2.1.35/linux/drivers/block/Config.in linux/drivers/block/Config.in --- v2.1.35/linux/drivers/block/Config.in Thu Mar 27 14:40:02 1997 +++ linux/drivers/block/Config.in Tue Apr 22 15:32:00 1997 @@ -23,7 +23,7 @@ fi if [ "$CONFIG_PCI" = "y" ]; then bool ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 - bool ' Intel PIIX/PIIX3 (Triton 430FX/HX/VX, 440FX) DMA support' CONFIG_BLK_DEV_TRITON + bool ' Intel PIIX/PIIX3/PIIX4 (Triton 430FX/HX/VX/TX, 440FX) DMA support' CONFIG_BLK_DEV_TRITON fi bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then diff -u --recursive --new-file v2.1.35/linux/drivers/block/acsi.c linux/drivers/block/acsi.c --- v2.1.35/linux/drivers/block/acsi.c Fri Dec 20 01:19:59 1996 +++ linux/drivers/block/acsi.c Thu Apr 17 13:20:44 1997 @@ -43,8 +43,6 @@ * */ -#include - #define MAJOR_NR ACSI_MAJOR #include @@ -1127,9 +1125,8 @@ * ACSI disks... */ case BLKGETSIZE: /* Return device size */ - if (put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects, - (long *)arg)) - return -EFAULT; + return put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects, + (long *) arg); case BLKFLSBUF: if(!suser()) return -EACCES; if(!inode->i_rdev) return -EINVAL; @@ -1629,33 +1626,23 @@ return DEV_SUPPORTED; } -#ifdef CONFIG_ATARI_SLM_MODULE -void acsi_attach_SLMs( int (*attach_func)( int, int ) ); -#endif +EXPORT_SYMBOL(acsi_delay_start); +EXPORT_SYMBOL(acsi_delay_end); +EXPORT_SYMBOL(acsi_wait_for_IRQ); +EXPORT_SYMBOL(acsi_wait_for_noIRQ); +EXPORT_SYMBOL(acsicmd_nodma); +EXPORT_SYMBOL(acsi_getstatus); +EXPORT_SYMBOL(acsi_buffer); +EXPORT_SYMBOL(phys_acsi_buffer); -static struct symbol_table acsi_symbol_table = -{ -#include - - X(acsi_delay_start), - X(acsi_delay_end), - X(acsi_wait_for_IRQ), - X(acsi_wait_for_noIRQ), - X(acsicmd_nodma), - X(acsi_getstatus), - X(acsi_buffer), - X(phys_acsi_buffer), #ifdef CONFIG_ATARI_SLM_MODULE - X(acsi_extstatus), - X(acsi_end_extstatus), - X(acsi_extcmd), - X(acsi_attach_SLMs), -#endif +void acsi_attach_SLMs( int (*attach_func)( int, int ) ); -#include -}; +EXPORT_SYMBOL(acsi_extstatus); +EXPORT_SYMBOL(acsi_end_extstatus); +EXPORT_SYMBOL(acsi_extcmd); +EXPORT_SYMBOL(acsi_attach_SLMs); -#ifdef CONFIG_ATARI_SLM_MODULE /* to remember IDs of SLM devices, SLM module is loaded later * (index is target#, contents is lun#, -1 means "no SLM") */ int SLM_devices[8]; @@ -1751,7 +1738,6 @@ for( i = 0; i < (MAX_DEV << 4); i++ ) acsi_blocksizes[i] = 1024; blksize_size[MAJOR_NR] = acsi_blocksizes; - register_symtab (&acsi_symbol_table); } #ifdef CONFIG_ATARI_SLM_MODULE diff -u --recursive --new-file v2.1.35/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c --- v2.1.35/linux/drivers/block/amiflop.c Fri Apr 4 08:52:17 1997 +++ linux/drivers/block/amiflop.c Thu Apr 17 13:20:44 1997 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -401,6 +402,7 @@ restore_flags(flags); if (on_attempts == 0) { + on_attempts = -1; #if 0 printk (KERN_ERR "motor_on failed, turning motor off\n"); fd_motor_off (nr); @@ -1511,93 +1513,103 @@ int error; unsigned long flags; - switch(cmd) - { - case FDFMTBEG: - get_hw(drive); - if (fd_ref[drive] > 1) { - rel_hw(); - return -EBUSY; - } - fsync_dev(inode->i_rdev); - if (motor_on(drive) == 0) { - rel_hw(); - return -ENODEV; - } - if (fd_calibrate(drive) == 0) { - rel_hw(); - return -ENXIO; - } - floppy_off(drive); - rel_hw(); - break; - case FDFMTTRK: - if (param < unit[drive].type->tracks * unit[drive].type->heads) - { - get_fdc(drive); - get_hw(drive); - fd_select(drive); - if (fd_seek(drive,param)!=0) - { - savedtrack=param; - memset(trackdata,FD_FILL_BYTE,unit[drive].sects*512); - non_int_flush_track(drive); - } - floppy_off(drive); - rel_hw(); - rel_fdc(); - } - else - return -EINVAL; - break; - case FDFMTEND: - floppy_off(drive); - invalidate_inodes(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - break; - case FDGETPRM: - error = verify_area(VERIFY_WRITE, (void *)param, - sizeof(struct floppy_struct)); - if (error) - return error; - memset((void *)&getprm, 0, sizeof (getprm)); - getprm.track=unit[drive].type->tracks; - getprm.head=unit[drive].type->heads; - getprm.sect=unit[drive].sects; - getprm.size=unit[drive].blocks; - copy_to_user((void *)param,(void *)&getprm,sizeof(struct floppy_struct)); + switch(cmd){ + case HDIO_GETGEO: + { + struct hd_geometry loc; + loc.heads = unit[drive].type->heads; + loc.sectors = unit[drive].sects; + loc.cylinders = unit[drive].type->tracks; + loc.start = 0; + if ((error = copy_to_user((void *)param, (void *)&loc, + sizeof(struct hd_geometry)))) + return error; + break; + } + case FDFMTBEG: + get_hw(drive); + if (fd_ref[drive] > 1) { + rel_hw(); + return -EBUSY; + } + fsync_dev(inode->i_rdev); + if (motor_on(drive) == 0) { + rel_hw(); + return -ENODEV; + } + if (fd_calibrate(drive) == 0) { + rel_hw(); + return -ENXIO; + } + floppy_off(drive); + rel_hw(); + break; + case FDFMTTRK: + if (param < unit[drive].type->tracks * unit[drive].type->heads) + { + get_fdc(drive); + get_hw(drive); + fd_select(drive); + if (fd_seek(drive,param)!=0){ + savedtrack=param; + memset(trackdata, FD_FILL_BYTE, + unit[drive].sects*512); + non_int_flush_track(drive); + } + floppy_off(drive); + rel_hw(); + rel_fdc(); + } + else + return -EINVAL; + break; + case FDFMTEND: + floppy_off(drive); + invalidate_inodes(inode->i_rdev); + invalidate_buffers(inode->i_rdev); + break; + case FDGETPRM: + memset((void *)&getprm, 0, sizeof (getprm)); + getprm.track=unit[drive].type->tracks; + getprm.head=unit[drive].type->heads; + getprm.sect=unit[drive].sects; + getprm.size=unit[drive].blocks; + if ((error = copy_to_user((void *)param, + (void *)&getprm, + sizeof(struct floppy_struct)))) + return error; break; - case BLKGETSIZE: - if (put_user(unit[drive].blocks,(long *)param)) - return -EFAULT; - break; - case FDSETPRM: - case FDDEFPRM: - return -EINVAL; - case FDFLUSH: - save_flags(flags); - cli(); - if ((drive == selected) && (writepending)) { - del_timer (&flush_track_timer); - restore_flags(flags); - non_int_flush_track(selected); - } - else - restore_flags(flags); - break; + case BLKGETSIZE: + if (put_user(unit[drive].blocks,(long *)param)) + return -EFAULT; + break; + case FDSETPRM: + case FDDEFPRM: + return -EINVAL; + case FDFLUSH: + save_flags(flags); + cli(); + if ((drive == selected) && (writepending)) { + del_timer (&flush_track_timer); + restore_flags(flags); + non_int_flush_track(selected); + } + else + restore_flags(flags); + break; #ifdef RAW_IOCTL - case IOCTL_RAW_TRACK: - error = verify_area(VERIFY_WRITE, (void *)param, - unit[drive].type->read_size); - if (error) - return error; - copy_to_user((void *)param, raw_buf, unit[drive].type->read_size); - return unit[drive].type->read_size; + case IOCTL_RAW_TRACK: + error = copy_to_user((void *)param, raw_buf, + unit[drive].type->read_size); + if (error) + return error; + else + return unit[drive].type->read_size; #endif - default: - printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",cmd,drive); - return -ENOSYS; - } + default: + printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",cmd,drive); + return -ENOSYS; + } return 0; } diff -u --recursive --new-file v2.1.35/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c --- v2.1.35/linux/drivers/block/ataflop.c Fri Apr 4 08:52:17 1997 +++ linux/drivers/block/ataflop.c Thu Apr 17 13:20:44 1997 @@ -52,6 +52,9 @@ * Michael (MSch) 11/07/96: * - implemented FDSETPRM and FDDEFPRM ioctl * + * Andreas (97/03/19): + * - implemented missing BLK* ioctls + * * Things left to do: * - Formatting * - Maybe a better strategy for disk change detection (does anyone @@ -281,6 +284,7 @@ static unsigned long PhysDMABuffer; /* physical address */ static int UseTrackbuffer = -1; /* Do track buffering? */ +MODULE_PARM(UseTrackbuffer, "i"); unsigned char *TrackBuffer; /* buffer for reads */ static unsigned long PhysTrackBuffer; /* physical address */ @@ -305,6 +309,7 @@ static int IsFormatting = 0, FormatError; static int UserSteprate[FD_MAX_UNITS] = { -1, -1 }; +MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i"); /* Synchronization of FDC access. */ static volatile int fdc_busy = 0; @@ -405,7 +410,7 @@ static int fd_test_drive_present( int drive ); static void config_types( void ); static int floppy_open( struct inode *inode, struct file *filp ); -static void floppy_release( struct inode * inode, struct file * filp ); +static int floppy_release( struct inode * inode, struct file * filp ); /************************* End of Prototypes **************************/ @@ -1582,6 +1587,7 @@ drive &= 3; switch (cmd) { case FDGETPRM: + case BLKGETSIZE: if (type) { if (--type >= NUM_DISK_MINORS) return -ENODEV; @@ -1599,6 +1605,9 @@ else dtp = UDT; } + if (cmd == BLKGETSIZE) + return put_user(dtp->blocks, (long *)param); + memset((void *)&getprm, 0, sizeof(getprm)); getprm.size = dtp->blocks; getprm.sect = dtp->spt; @@ -1607,6 +1616,22 @@ getprm.stretch = dtp->stretch; if (copy_to_user((void *)param, &getprm, sizeof(getprm))) return -EFAULT; + return 0; + case BLKRASET: + if (!suser()) + return -EACCES; + if (param > 0xff) + return -EINVAL; + read_ahead[MAJOR(inode->i_rdev)] = param; + return 0; + case BLKRAGET: + return put_user(read_ahead[MAJOR(inode->i_rdev)], + (int *) param); + case BLKFLSBUF: + if (!suser()) + return -EACCES; + fsync_dev(inode->i_rdev); + invalidate_buffers(inode->i_rdev); return 0; } if (!IOCTL_ALLOWED) diff -u --recursive --new-file v2.1.35/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.1.35/linux/drivers/block/floppy.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/block/floppy.c Tue Apr 15 22:26:28 1997 @@ -1676,10 +1676,13 @@ } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2); } if (handler) { - if (in_interrupt()) - schedule_bh( (void *)(void *) handler); - else + if(softirq_trylock()) { + /* got the lock, call the handler immediately */ handler(); + softirq_endlock(); + } else + /* we interrupted a bottom half. Defer handler */ + schedule_bh( (void *)(void *) handler); } else FDCS->reset = 1; is_alive("normal interrupt end"); diff -u --recursive --new-file v2.1.35/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.1.35/linux/drivers/block/genhd.c Sun Apr 13 10:18:20 1997 +++ linux/drivers/block/genhd.c Thu Apr 17 13:20:44 1997 @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -739,7 +740,7 @@ } } -static void setup_dev(struct gendisk *dev) +static inline void setup_dev(struct gendisk *dev) { int i, drive; int end_minor = dev->max_nr * dev->max_p; @@ -762,7 +763,7 @@ } } -void device_setup(void) +__initfunc(void device_setup(void)) { extern void console_map_init(void); #ifdef CONFIG_PNP_PARPORT diff -u --recursive --new-file v2.1.35/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.1.35/linux/drivers/block/ide.c Fri Apr 4 08:52:17 1997 +++ linux/drivers/block/ide.c Tue Apr 22 15:32:00 1997 @@ -2602,6 +2602,7 @@ */ ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1); ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0); + ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0); #endif /* CONFIG_BLK_DEV_TRITON */ #ifdef CONFIG_BLK_DEV_OPTI621 ide_probe_pci (PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, &ide_init_opti621, 0); diff -u --recursive --new-file v2.1.35/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.1.35/linux/drivers/block/ll_rw_blk.c Thu Mar 27 14:40:02 1997 +++ linux/drivers/block/ll_rw_blk.c Thu Apr 17 13:20:44 1997 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -631,7 +632,7 @@ extern void bpcd_init( void ); #endif -int blk_dev_init(void) +__initfunc(int blk_dev_init(void)) { struct request * req; struct blk_dev_struct *dev; diff -u --recursive --new-file v2.1.35/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.1.35/linux/drivers/block/rd.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/block/rd.c Thu Apr 17 13:20:44 1997 @@ -200,7 +200,7 @@ { unsigned long i; - if (--initrd_users) return; + if (--initrd_users) return 0; for (i = initrd_start; i < initrd_end; i += PAGE_SIZE) free_page(i); initrd_start = 0; @@ -405,11 +405,11 @@ } /* Try ext2 */ - if (ext2sb->s_magic == EXT2_SUPER_MAGIC) { + if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { printk(KERN_NOTICE "RAMDISK: Ext2 filesystem found at block %d\n", start_block); - nblocks = ext2sb->s_blocks_count; + nblocks = le32_to_cpu(ext2sb->s_blocks_count); goto done; } diff -u --recursive --new-file v2.1.35/linux/drivers/block/triton.c linux/drivers/block/triton.c --- v2.1.35/linux/drivers/block/triton.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/block/triton.c Tue Apr 22 15:32:00 1997 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/triton.c Version 2.00 March 9, 1997 + * linux/drivers/block/triton.c Version 2.10 April 22, 1997 * * Copyright (c) 1995-1997 Mark Lord * May be copied or modified under the terms of the GNU General Public License @@ -8,8 +8,8 @@ /* * This module provides support for the bus-master IDE DMA function * of the Intel PCI Triton chipset families, which use the PIIX (i82371FB, - * for the 430 FX chipset), and the enhanced PIIX3 (i82371SB for the 430 HX/VX - * and 440 chipsets). + * for the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and + * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset). * * "PIIX" stands for "PCI ISA IDE Xcellerator". * @@ -18,12 +18,12 @@ * * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). * - * Up to four drives may be enabled for DMA, and the PIIX/PIIX3 chips + * Up to four drives may be enabled for DMA, and the PIIX* chips * will arbitrate the PCI bus among them. Note that the PIIX/PIIX3 * provides a single "line buffer" for the BM IDE function, so performance of * multiple (two) drives doing DMA simultaneously will suffer somewhat, * as they contest for that resource bottleneck. This is handled transparently - * inside the PIIX/PIIX3. + * inside the PIIX/PIIX3. The PIIX4 does not have this problem. * * By default, DMA support is prepared for use, but is currently enabled only * for drives which support DMA mode2 (multi/single word), or which are @@ -60,6 +60,9 @@ * Thanks to "Christopher J. Reimer" for fixing the * problem with some (all?) ACER motherboards/BIOSs. * + * Thanks to "Benoit Poulot-Cazajous" for testing + * "TX" chipset compatibility and for providing patches for the "TX" chipset. + * * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports. */ #include @@ -342,7 +345,7 @@ #ifdef DISPLAY_PIIX_TIMINGS /* * print_piix_drive_flags() displays the currently programmed options - * in the PIIX/PIIX3 for a given drive. + * in the PIIX/PIIX3/PIIX4 for a given drive. */ static void print_piix_drive_flags (const char *unit, byte dflags) { @@ -448,7 +451,13 @@ if (pcibios_read_config_word(bus, fn, 0x02, &devid)) goto quit; - chipset = (devid == PCI_DEVICE_ID_INTEL_82371SB_1) ? "PIIX3" : "PIIX"; + + if (devid == PCI_DEVICE_ID_INTEL_82371AB) + chipset = "PIIX4"; + else if (devid == PCI_DEVICE_ID_INTEL_82371SB_1) + chipset = "PIIX3"; + else + chipset = "PIIX"; printk("%s: bus-master IDE device on PCI bus %d function %d\n", chipset, bus, fn); @@ -532,10 +541,11 @@ piix_sidetim_t sidetim; byte sample = 5 - timing.sample; byte recovery = 4 - timing.recovery; - if (devid == PCI_DEVICE_ID_INTEL_82371SB_1 + if ((devid == PCI_DEVICE_ID_INTEL_82371SB_1 + || devid == PCI_DEVICE_ID_INTEL_82371AB) && timing.sidetim_enabled && !pcibios_read_config_byte(bus, fn, 0x44, (byte *) &sidetim)) - slave = ""; /* PIIX3 */ + slave = ""; /* PIIX3 and later */ else slave = "/slave"; /* PIIX, or PIIX3 in compatibility mode */ printk(" %s master%s: sample_CLKs=%d, recovery_CLKs=%d\n", hwif->name, slave, sample, recovery); diff -u --recursive --new-file v2.1.35/linux/drivers/block/z2ram.c linux/drivers/block/z2ram.c --- v2.1.35/linux/drivers/block/z2ram.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/block/z2ram.c Thu Apr 17 13:20:44 1997 @@ -36,7 +36,7 @@ #include #include #include -#include +#include #define TRUE (1) #define FALSE (0) diff -u --recursive --new-file v2.1.35/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.1.35/linux/drivers/char/Makefile Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/Makefile Thu Apr 17 13:20:45 1997 @@ -43,6 +43,16 @@ endif endif +ifeq ($(CONFIG_ATARI_DSP56K),y) +L_OBJS += dsp56k.o +S = y +else + ifeq ($(CONFIG_ATARI_DSP56K),m) + M_OBJS += dsp56k.o + SM = y + endif +endif + ifeq ($(CONFIG_DIGI),y) L_OBJS += pcxx.o else diff -u --recursive --new-file v2.1.35/linux/drivers/char/amigamouse.c linux/drivers/char/amigamouse.c --- v2.1.35/linux/drivers/char/amigamouse.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/amigamouse.c Tue Apr 22 22:42:47 1997 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -172,11 +173,11 @@ * close access to the mouse */ -static int close_mouse(struct inode * inode, struct file * file) +static int release_mouse(struct inode * inode, struct file * file) { fasync_mouse(inode, file, 0); if (--mouse.active) - return; + return 0; free_irq(IRQ_AMIGA_VERTB, mouse_interrupt); MSE_INT_OFF(); MOD_DEC_USE_COUNT; @@ -299,7 +300,7 @@ NULL, /* mouse_ioctl */ NULL, /* mouse_mmap */ open_mouse, - close_mouse, + release_mouse, NULL, fasync_mouse, }; @@ -308,7 +309,7 @@ AMIGAMOUSE_MINOR, "amigamouse", &amiga_mouse_fops }; -int amiga_mouse_init(void) +__initfunc(int amiga_mouse_init(void)) { if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) return -ENODEV; diff -u --recursive --new-file v2.1.35/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c --- v2.1.35/linux/drivers/char/apm_bios.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/apm_bios.c Tue Apr 22 22:42:47 1997 @@ -73,6 +73,7 @@ #endif #include #include +#include EXPORT_SYMBOL(apm_register_callback); EXPORT_SYMBOL(apm_unregister_callback); @@ -451,7 +452,7 @@ #ifdef CONFIG_APM_DO_ENABLE /* Called by apm_setup if apm_enabled will be true. */ -static int apm_enable_power_management(void) +static inline int apm_enable_power_management(void) { u_short error; @@ -474,7 +475,7 @@ return APM_SUCCESS; } -static int apm_engage_power_management(u_short device) +static inline int apm_engage_power_management(u_short device) { u_short error; @@ -1059,7 +1060,7 @@ } #endif -void apm_bios_init(void) +__initfunc(void apm_bios_init(void)) { unsigned short bx; unsigned short cx; diff -u --recursive --new-file v2.1.35/linux/drivers/char/atarimouse.c linux/drivers/char/atarimouse.c --- v2.1.35/linux/drivers/char/atarimouse.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/atarimouse.c Tue Apr 22 22:42:47 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,8 @@ #include static struct mouse_status mouse; -static int atari_mouse_x_threshold = 2, atari_mouse_y_threshold = 2; +static int mouse_threshold[2] = {2,2}; +MODULE_PARM(mouse_threshold, "2i"); extern int atari_mouse_buttons; static void atari_mouse_interrupt(char *buf) @@ -82,7 +84,7 @@ mouse.dx = mouse.dy = 0; atari_mouse_buttons = 0; ikbd_mouse_y0_top (); - ikbd_mouse_thresh (atari_mouse_x_threshold, atari_mouse_y_threshold); + ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]); ikbd_mouse_rel_pos(); MOD_INC_USE_COUNT; atari_mouse_interrupt_hook = atari_mouse_interrupt; @@ -99,12 +101,9 @@ char *buffer, unsigned long count) { int dx, dy, buttons; - int r; if (count < 3) return -EINVAL; - if ((r = verify_area(VERIFY_WRITE, buffer, count))) - return r; if (!mouse.ready) return -EAGAIN; /* ikbd_mouse_disable */ @@ -124,12 +123,14 @@ if (mouse.dx == 0 && mouse.dy == 0) mouse.ready = 0; /* ikbd_mouse_rel_pos(); */ - put_user(buttons | 0x80, buffer); - put_user((char) dx, buffer + 1); - put_user((char) dy, buffer + 2); - for (r = 3; r < count; r++) - put_user (0, buffer + r); - return r; + if (put_user(buttons | 0x80, buffer++) || + put_user((char) dx, buffer++) || + put_user((char) dy, buffer++)) + return -EFAULT; + if (count > 3) + if (clear_user(buffer, count - 3)) + return -EFAULT; + return count; } static unsigned int mouse_poll(struct file *file, poll_table *wait) @@ -158,7 +159,7 @@ ATARIMOUSE_MINOR, "atarimouse", &atari_mouse_fops }; -int atari_mouse_init(void) +__initfunc(int atari_mouse_init(void)) { mouse.active = 0; mouse.ready = 0; @@ -188,13 +189,13 @@ if (ints[1] < MIN_THRESHOLD || ints[1] > MAX_THRESHOLD) printk( "atari_mouse_setup: bad threshold value (ignored)\n" ); else { - atari_mouse_x_threshold = ints[1]; - atari_mouse_y_threshold = ints[1]; + mouse_threshold[0] = ints[1]; + mouse_threshold[1] = ints[1]; if (ints[0] > 1) { if (ints[2] < MIN_THRESHOLD || ints[2] > MAX_THRESHOLD) printk("atari_mouse_setup: bad threshold value (ignored)\n" ); else - atari_mouse_y_threshold = ints[2]; + mouse_threshold[1] = ints[2]; } } diff -u --recursive --new-file v2.1.35/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c --- v2.1.35/linux/drivers/char/atixlmouse.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/atixlmouse.c Tue Apr 22 22:42:47 1997 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -201,7 +202,7 @@ }; -int atixl_busmouse_init(void) +__initfunc(int atixl_busmouse_init(void)) { unsigned char a,b,c; diff -u --recursive --new-file v2.1.35/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v2.1.35/linux/drivers/char/busmouse.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/busmouse.c Tue Apr 22 22:42:47 1997 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -246,7 +247,7 @@ LOGITECH_BUSMOUSE, "busmouse", &bus_mouse_fops }; -int bus_mouse_init(void) +__initfunc(int bus_mouse_init(void)) { if (check_region(LOGIBM_BASE, LOGIBM_EXTENT)) { mouse.present = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c --- v2.1.35/linux/drivers/char/cyclades.c Sat Nov 30 00:48:33 1996 +++ linux/drivers/char/cyclades.c Tue Apr 22 22:42:47 1997 @@ -288,6 +288,7 @@ #include #include #include +#include #define small_delay(x) for(j=0;j + * lars brinkhoff + * Tomas Berndtsson + * + * First version May 1996 + * + * History: + * 97-01-29 Tomas Berndtsson, + * Integrated with Linux 2.1.21 kernel sources. + * 97-02-15 Tomas Berndtsson, + * Fixed for kernel 2.1.26 + * + * BUGS: + * Hmm... there must be something here :) + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include /* for kmalloc() and kfree() */ +#include /* for struct wait_queue etc */ +#include +#include +#include +#include /* guess what */ +#include +#include + +#include +#include +#include +#include /* For put_user and get_user */ + +#include + +/* minor devices */ +#define DSP56K_DEV_56001 0 /* The only device so far */ + +#define TIMEOUT 10 /* Host port timeout in number of tries */ +#define MAXIO 2048 /* Maximum number of words before sleep */ +#define DSP56K_MAX_BINARY_LENGTH (3*64*1024) + +#define DSP56K_TX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_TREQ +#define DSP56K_RX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_RREQ +#define DSP56K_TX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_TREQ +#define DSP56K_RX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_RREQ + +#define DSP56K_TRANSMIT (dsp56k_host_interface.isr & DSP56K_ISR_TXDE) +#define DSP56K_RECEIVE (dsp56k_host_interface.isr & DSP56K_ISR_RXDF) + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#define wait_some(n) \ +{ \ + current->state = TASK_INTERRUPTIBLE; \ + current->timeout = jiffies + n; \ + schedule(); \ +} + +#define handshake(count, maxio, timeout, ENABLE, f) \ +{ \ + long i, t, m; \ + while (count > 0) { \ + m = min(count, maxio); \ + for (i = 0; i < m; i++) { \ + for (t = 0; t < timeout && !ENABLE; t++) \ + wait_some(2); \ + if(!ENABLE) \ + return -EIO; \ + f; \ + } \ + count -= m; \ + if (m == maxio) wait_some(2); \ + } \ +} + +#define tx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_TRANSMIT; t++) \ + wait_some(1); \ + if(!DSP56K_TRANSMIT) { \ + return -EIO; \ + } \ +} + +#define rx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_RECEIVE; t++) \ + wait_some(1); \ + if(!DSP56K_RECEIVE) { \ + return -EIO; \ + } \ +} + +/* DSP56001 bootstrap code */ +static char bootstrap[] = { + 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4, + 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47, + 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00, + 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe, + 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0, + 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4, + 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01, + 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08, + 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46, + 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa, + 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00, + 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9, + 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80, + 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0, + 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4, + 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a, + 0xf0, 0x80, 0x00, 0x7e, 0xad}; +static int sizeof_bootstrap = 375; + + +static struct dsp56k_device { + int in_use; + long maxio, timeout; + int tx_wsize, rx_wsize; +} dsp56k; + +static int dsp56k_reset(void) +{ + u_char status; + + /* Power down the DSP */ + sound_ym.rd_data_reg_sel = 14; + status = sound_ym.rd_data_reg_sel & 0xef; + sound_ym.wd_data = status; + sound_ym.wd_data = status | 0x10; + + udelay(10); + + /* Power up the DSP */ + sound_ym.rd_data_reg_sel = 14; + sound_ym.wd_data = sound_ym.rd_data_reg_sel & 0xef; + + return 0; +} + +static int dsp56k_upload(u_char *bin, int len) +{ + int i; + u_char *p; + + dsp56k_reset(); + + p = bootstrap; + for (i = 0; i < sizeof_bootstrap/3; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = *p++; + dsp56k_host_interface.data.b[2] = *p++; + dsp56k_host_interface.data.b[3] = *p++; + } + for (; i < 512; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = 0; + dsp56k_host_interface.data.b[2] = 0; + dsp56k_host_interface.data.b[3] = 0; + } + + for (i = 0; i < len; i++) { + tx_wait(10); + get_user(dsp56k_host_interface.data.b[1], bin++); + get_user(dsp56k_host_interface.data.b[2], bin++); + get_user(dsp56k_host_interface.data.b[3], bin++); + } + + tx_wait(10); + dsp56k_host_interface.data.l = 3; /* Magic execute */ + + return 0; +} + +static long dsp56k_read(struct inode *inode, struct file *file, + char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.rx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[1], buf+n++); + put_user(dsp56k_host_interface.data.b[2], buf+n++); + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + return -EFAULT; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static long dsp56k_write(struct inode *inode, struct file *file, + const char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.tx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[1], buf+n++); + get_user(dsp56k_host_interface.data.b[2], buf+n++); + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + + return -EFAULT; + } + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static int dsp56k_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(cmd) { + case DSP56K_UPLOAD: + { + char *bin; + int r, len; + struct dsp56k_upload *binary = (struct dsp56k_upload *) arg; + + if(get_user(len, &binary->len) < 0) + return -EFAULT; + if(get_user(bin, &binary->bin) < 0) + return -EFAULT; + + if (len == 0) { + return -EINVAL; /* nothing to upload?!? */ + } + if (len > DSP56K_MAX_BINARY_LENGTH) { + return -EINVAL; + } + + r = dsp56k_upload(bin, len); + if (r < 0) { + return r; + } + + break; + } + case DSP56K_SET_TX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.tx_wsize = (int) arg; + break; + case DSP56K_SET_RX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.rx_wsize = (int) arg; + break; + case DSP56K_HOST_FLAGS: + { + int dir, out, status; + struct dsp56k_host_flags *hf = (struct dsp56k_host_flags*) arg; + + if(get_user(dir, &hf->dir) < 0) + return -EFAULT; + if(get_user(out, &hf->out) < 0) + return -EFAULT; + + if ((dir & 0x1) && (out & 0x1)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF0; + else if (dir & 0x1) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + if ((dir & 0x2) && (out & 0x2)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF1; + else if (dir & 0x2) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + status = 0; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF0) status |= 0x1; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF1) status |= 0x2; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF2) status |= 0x4; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF3) status |= 0x8; + + if(put_user(status, &hf->status) < 0) + return -EFAULT; + break; + } + case DSP56K_HOST_CMD: + if (arg > 31 || arg < 0) + return -EINVAL; + dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) | + DSP56K_CVR_HC); + break; + default: + return -EINVAL; + } + return 0; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +/* As of 2.1.26 this should be dsp56k_poll, + * but how do I then check device minor number? + * Do I need this function at all??? + */ +#ifdef 0 +static int dsp56k_select(struct inode *inode, struct file *file, int sel_type, + select_table *wait) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(sel_type) { + case SEL_IN: /* read */ + return 1; + case SEL_OUT: /* write */ + return 1; + default: + return 1; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} +#endif + +static int dsp56k_open(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + if (dsp56k.in_use) + return -EBUSY; + + dsp56k.in_use = 1; + dsp56k.timeout = TIMEOUT; + dsp56k.maxio = MAXIO; + dsp56k.rx_wsize = dsp56k.tx_wsize = 4; + + DSP56K_TX_INT_OFF; + DSP56K_RX_INT_OFF; + + /* Zero host flags */ + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + break; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif /* MODULE */ + + return 0; +} + +static void dsp56k_release(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + dsp56k.in_use = 0; + + break; + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return; + } + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif /* MODULE */ +} + +static struct file_operations dsp56k_fops = { + NULL, /* no special dsp56k_lseek */ + dsp56k_read, + dsp56k_write, + NULL, /* no special dsp56k_readdir */ + NULL, /* dsp56k_poll? */ + dsp56k_ioctl, + NULL, /* no special dsp56k_mmap */ + dsp56k_open, + dsp56k_release, + NULL, /* no special dsp56k_fsync */ + NULL, /* no special dsp56k_fasync */ + NULL, /* no special dsp56k_check_media_change */ + NULL /* no special dsp56k_revalidate */ +}; + + +/****** Init and module functions ******/ + +static int init_error = 0; + +void dsp56k_init(void) +{ + if(!ATARIHW_PRESENT(DSP56K)) { + init_error = 1; + printk("DSP56k driver: Hardware not present\n"); + return; + } + +#ifndef MODULE + if(register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops)) { + printk("DSP56k driver: Unable to register driver\n"); + return; + } +#endif /* !MODULE */ + + dsp56k.in_use = 0; + + printk("DSP56k driver installed\n"); +} + +#ifdef MODULE +int init_module(void) +{ + int r; + + init_error = 0; + dsp56k_init(); + if(init_error) + return -EPERM; + + r = register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops); + if(r) { + printk("DSP56k driver: Unable to register driver\n"); + return r; + } + + return 0; +} + +void cleanup_module(void) +{ + unregister_chrdev(DSP56K_MAJOR, "dsp56k"); +} +#endif /* MODULE */ +/* + * The DSP56001 Device Driver, saviour of the Free World(tm) + * + * Authors: Fredrik Noring + * lars brinkhoff + * Tomas Berndtsson + * + * First version May 1996 + * + * History: + * 97-01-29 Tomas Berndtsson, + * Integrated with Linux 2.1.21 kernel sources. + * 97-02-15 Tomas Berndtsson, + * Fixed for kernel 2.1.26 + * + * BUGS: + * Hmm... there must be something here :) + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include /* for kmalloc() and kfree() */ +#include /* for struct wait_queue etc */ +#include +#include +#include +#include /* guess what */ +#include +#include + +#include +#include +#include +#include /* For put_user and get_user */ + +#include + +/* minor devices */ +#define DSP56K_DEV_56001 0 /* The only device so far */ + +#define TIMEOUT 10 /* Host port timeout in number of tries */ +#define MAXIO 2048 /* Maximum number of words before sleep */ +#define DSP56K_MAX_BINARY_LENGTH (3*64*1024) + +#define DSP56K_TX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_TREQ +#define DSP56K_RX_INT_ON dsp56k_host_interface.icr |= DSP56K_ICR_RREQ +#define DSP56K_TX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_TREQ +#define DSP56K_RX_INT_OFF dsp56k_host_interface.icr &= ~DSP56K_ICR_RREQ + +#define DSP56K_TRANSMIT (dsp56k_host_interface.isr & DSP56K_ISR_TXDE) +#define DSP56K_RECEIVE (dsp56k_host_interface.isr & DSP56K_ISR_RXDF) + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#define wait_some(n) \ +{ \ + current->state = TASK_INTERRUPTIBLE; \ + current->timeout = jiffies + n; \ + schedule(); \ +} + +#define handshake(count, maxio, timeout, ENABLE, f) \ +{ \ + long i, t, m; \ + while (count > 0) { \ + m = min(count, maxio); \ + for (i = 0; i < m; i++) { \ + for (t = 0; t < timeout && !ENABLE; t++) \ + wait_some(2); \ + if(!ENABLE) \ + return -EIO; \ + f; \ + } \ + count -= m; \ + if (m == maxio) wait_some(2); \ + } \ +} + +#define tx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_TRANSMIT; t++) \ + wait_some(1); \ + if(!DSP56K_TRANSMIT) { \ + return -EIO; \ + } \ +} + +#define rx_wait(n) \ +{ \ + int t; \ + for(t = 0; t < n && !DSP56K_RECEIVE; t++) \ + wait_some(1); \ + if(!DSP56K_RECEIVE) { \ + return -EIO; \ + } \ +} + +/* DSP56001 bootstrap code */ +static char bootstrap[] = { + 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4, + 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47, + 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00, + 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe, + 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0, + 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4, + 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01, + 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08, + 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46, + 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa, + 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00, + 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9, + 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80, + 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a, + 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0, + 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4, + 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a, + 0xf0, 0x80, 0x00, 0x7e, 0xad}; +static int sizeof_bootstrap = 375; + + +static struct dsp56k_device { + int in_use; + long maxio, timeout; + int tx_wsize, rx_wsize; +} dsp56k; + +static int dsp56k_reset(void) +{ + u_char status; + + /* Power down the DSP */ + sound_ym.rd_data_reg_sel = 14; + status = sound_ym.rd_data_reg_sel & 0xef; + sound_ym.wd_data = status; + sound_ym.wd_data = status | 0x10; + + udelay(10); + + /* Power up the DSP */ + sound_ym.rd_data_reg_sel = 14; + sound_ym.wd_data = sound_ym.rd_data_reg_sel & 0xef; + + return 0; +} + +static int dsp56k_upload(u_char *bin, int len) +{ + int i; + u_char *p; + + dsp56k_reset(); + + p = bootstrap; + for (i = 0; i < sizeof_bootstrap/3; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = *p++; + dsp56k_host_interface.data.b[2] = *p++; + dsp56k_host_interface.data.b[3] = *p++; + } + for (; i < 512; i++) { + /* tx_wait(10); */ + dsp56k_host_interface.data.b[1] = 0; + dsp56k_host_interface.data.b[2] = 0; + dsp56k_host_interface.data.b[3] = 0; + } + + for (i = 0; i < len; i++) { + tx_wait(10); + get_user(dsp56k_host_interface.data.b[1], bin++); + get_user(dsp56k_host_interface.data.b[2], bin++); + get_user(dsp56k_host_interface.data.b[3], bin++); + } + + tx_wait(10); + dsp56k_host_interface.data.l = 3; /* Magic execute */ + + return 0; +} + +static long dsp56k_read(struct inode *inode, struct file *file, + char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.rx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.b[1], buf+n++); + put_user(dsp56k_host_interface.data.b[2], buf+n++); + put_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, + put_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + return -EFAULT; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static long dsp56k_write(struct inode *inode, struct file *file, + const char *buf, unsigned long count) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + { + long n; + + /* Don't do anything if nothing is to be done */ + if (!count) return 0; + + n = 0; + switch (dsp56k.tx_wsize) { + case 1: /* 8 bit */ + { + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return n; + } + case 2: /* 16 bit */ + { + short *data; + + count /= 2; + data = (short*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.w[1], data+n++)); + return 2*n; + } + case 3: /* 24 bit */ + { + count /= 3; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.b[1], buf+n++); + get_user(dsp56k_host_interface.data.b[2], buf+n++); + get_user(dsp56k_host_interface.data.b[3], buf+n++)); + return 3*n; + } + case 4: /* 32 bit */ + { + long *data; + + count /= 4; + data = (long*) buf; + handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, + get_user(dsp56k_host_interface.data.l, data+n++)); + return 4*n; + } + } + + return -EFAULT; + } + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +static int dsp56k_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(cmd) { + case DSP56K_UPLOAD: + { + char *bin; + int r, len; + struct dsp56k_upload *binary = (struct dsp56k_upload *) arg; + + if(get_user(len, &binary->len) < 0) + return -EFAULT; + if(get_user(bin, &binary->bin) < 0) + return -EFAULT; + + if (len == 0) { + return -EINVAL; /* nothing to upload?!? */ + } + if (len > DSP56K_MAX_BINARY_LENGTH) { + return -EINVAL; + } + + r = dsp56k_upload(bin, len); + if (r < 0) { + return r; + } + + break; + } + case DSP56K_SET_TX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.tx_wsize = (int) arg; + break; + case DSP56K_SET_RX_WSIZE: + if (arg > 4 || arg < 1) + return -EINVAL; + dsp56k.rx_wsize = (int) arg; + break; + case DSP56K_HOST_FLAGS: + { + int dir, out, status; + struct dsp56k_host_flags *hf = (struct dsp56k_host_flags*) arg; + + if(get_user(dir, &hf->dir) < 0) + return -EFAULT; + if(get_user(out, &hf->out) < 0) + return -EFAULT; + + if ((dir & 0x1) && (out & 0x1)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF0; + else if (dir & 0x1) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + if ((dir & 0x2) && (out & 0x2)) + dsp56k_host_interface.icr |= DSP56K_ICR_HF1; + else if (dir & 0x2) + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + status = 0; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF0) status |= 0x1; + if (dsp56k_host_interface.icr & DSP56K_ICR_HF1) status |= 0x2; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF2) status |= 0x4; + if (dsp56k_host_interface.isr & DSP56K_ISR_HF3) status |= 0x8; + + if(put_user(status, &hf->status) < 0) + return -EFAULT; + break; + } + case DSP56K_HOST_CMD: + if (arg > 31 || arg < 0) + return -EINVAL; + dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) | + DSP56K_CVR_HC); + break; + default: + return -EINVAL; + } + return 0; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} + +/* As of 2.1.26 this should be dsp56k_poll, + * but how do I then check device minor number? + * Do I need this function at all??? + */ +#ifdef 0 +static int dsp56k_select(struct inode *inode, struct file *file, int sel_type, + select_table *wait) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + switch(sel_type) { + case SEL_IN: /* read */ + return 1; + case SEL_OUT: /* write */ + return 1; + default: + return 1; + } + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } +} +#endif + +static int dsp56k_open(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + if (dsp56k.in_use) + return -EBUSY; + + dsp56k.in_use = 1; + dsp56k.timeout = TIMEOUT; + dsp56k.maxio = MAXIO; + dsp56k.rx_wsize = dsp56k.tx_wsize = 4; + + DSP56K_TX_INT_OFF; + DSP56K_RX_INT_OFF; + + /* Zero host flags */ + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF0; + dsp56k_host_interface.icr &= ~DSP56K_ICR_HF1; + + break; + + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return -ENXIO; + } + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif /* MODULE */ + + return 0; +} + +static void dsp56k_release(struct inode *inode, struct file *file) +{ + int dev = MINOR(inode->i_rdev) & 0x0f; + + switch(dev) + { + case DSP56K_DEV_56001: + + dsp56k.in_use = 0; + + break; + default: + printk("DSP56k driver: Unknown minor device: %d\n", dev); + return; + } + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif /* MODULE */ +} + +static struct file_operations dsp56k_fops = { + NULL, /* no special dsp56k_lseek */ + dsp56k_read, + dsp56k_write, + NULL, /* no special dsp56k_readdir */ + NULL, /* dsp56k_poll? */ + dsp56k_ioctl, + NULL, /* no special dsp56k_mmap */ + dsp56k_open, + dsp56k_release, + NULL, /* no special dsp56k_fsync */ + NULL, /* no special dsp56k_fasync */ + NULL, /* no special dsp56k_check_media_change */ + NULL /* no special dsp56k_revalidate */ +}; + + +/****** Init and module functions ******/ + +static int init_error = 0; + +void dsp56k_init(void) +{ + if(!ATARIHW_PRESENT(DSP56K)) { + init_error = 1; + printk("DSP56k driver: Hardware not present\n"); + return; + } + +#ifndef MODULE + if(register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops)) { + printk("DSP56k driver: Unable to register driver\n"); + return; + } +#endif /* !MODULE */ + + dsp56k.in_use = 0; + + printk("DSP56k driver installed\n"); +} + +#ifdef MODULE +int init_module(void) +{ + int r; + + init_error = 0; + dsp56k_init(); + if(init_error) + return -EPERM; + + r = register_chrdev(DSP56K_MAJOR, "dsp56k", &dsp56k_fops); + if(r) { + printk("DSP56k driver: Unable to register driver\n"); + return r; + } + + return 0; +} + +void cleanup_module(void) +{ + unregister_chrdev(DSP56K_MAJOR, "dsp56k"); +} +#endif /* MODULE */ diff -u --recursive --new-file v2.1.35/linux/drivers/char/esp.c linux/drivers/char/esp.c --- v2.1.35/linux/drivers/char/esp.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/esp.c Tue Apr 22 22:42:47 1997 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -2312,7 +2313,8 @@ * number, and identifies which options were configured into this * driver. */ -static void show_serial_version(void) + +static _INLINE_ void show_serial_version(void) { printk(KERN_INFO "%s version %s (DMA %u, trigger level %u)\n", serial_name, serial_version, dma, trigger); @@ -2380,7 +2382,7 @@ /* * The serial driver boot-time initialization code! */ -int espserial_init(void) +__initfunc(int espserial_init(void)) { int i, offset; int region_start; @@ -2565,6 +2567,7 @@ /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ save_flags(flags); cli(); + remove_bh(ESP_BH); if ((e1 = tty_unregister_driver(&esp_driver))) printk("SERIAL: failed to unregister serial driver (%d)\n", e1); diff -u --recursive --new-file v2.1.35/linux/drivers/char/istallion.c linux/drivers/char/istallion.c --- v2.1.35/linux/drivers/char/istallion.c Mon Mar 17 14:54:25 1997 +++ linux/drivers/char/istallion.c Tue Apr 22 22:42:47 1997 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -540,13 +541,13 @@ static void stli_flushbuffer(struct tty_struct *tty); static void stli_hangup(struct tty_struct *tty); -static int stli_initbrds(void); +static inline int stli_initbrds(void); static int stli_brdinit(stlibrd_t *brdp); -static int stli_initecp(stlibrd_t *brdp); -static int stli_initonb(stlibrd_t *brdp); +static inline int stli_initecp(stlibrd_t *brdp); +static inline int stli_initonb(stlibrd_t *brdp); static int stli_eisamemprobe(stlibrd_t *brdp); -static int stli_findeisabrds(void); -static int stli_initports(stlibrd_t *brdp); +static inline int stli_findeisabrds(void); +static inline int stli_initports(stlibrd_t *brdp); static int stli_startbrd(stlibrd_t *brdp); static long stli_memread(struct inode *ip, struct file *fp, char *buf, unsigned long count); static long stli_memwrite(struct inode *ip, struct file *fp, const char *buf, unsigned long count); @@ -2781,7 +2782,7 @@ * we need to do here is set up the appropriate per port data structures. */ -static int stli_initports(stlibrd_t *brdp) +static inline int stli_initports(stlibrd_t *brdp) { stliport_t *portp; int i, panelnr, panelport; @@ -3335,7 +3336,7 @@ * board types. */ -static int stli_initecp(stlibrd_t *brdp) +static inline int stli_initecp(stlibrd_t *brdp) { cdkecpsig_t sig; cdkecpsig_t *sigsp; @@ -3472,7 +3473,7 @@ * This handles only these board types. */ -static int stli_initonb(stlibrd_t *brdp) +static inline int stli_initonb(stlibrd_t *brdp) { cdkonbsig_t sig; cdkonbsig_t *sigsp; @@ -3737,7 +3738,7 @@ * Probe and initialize the specified board. */ -static int stli_brdinit(stlibrd_t *brdp) +__initfunc(static int stli_brdinit(stlibrd_t *brdp)) { #if DEBUG printk("stli_brdinit(brdp=%x)\n", (int) brdp); @@ -3791,7 +3792,7 @@ * might be. This is a bit if hack, but it is the best we can do. */ -static int stli_eisamemprobe(stlibrd_t *brdp) +__initfunc(static int stli_eisamemprobe(stlibrd_t *brdp)) { cdkecpsig_t ecpsig, *ecpsigp; cdkonbsig_t onbsig, *onbsigp; @@ -3890,7 +3891,7 @@ * do is go probing around in the usual places hoping we can find it. */ -static int stli_findeisabrds() +static inline int stli_findeisabrds() { stlibrd_t *brdp; unsigned int iobase, eid; @@ -3979,7 +3980,7 @@ * can find. */ -static int stli_initbrds() +static inline int stli_initbrds() { stlibrd_t *brdp, *nxtbrdp; stlconf_t *confp; @@ -4471,7 +4472,7 @@ /*****************************************************************************/ -int stli_init() +__initfunc(int stli_init()) { printk(KERN_INFO "%s: version %s\n", stli_drvname, stli_drvversion); diff -u --recursive --new-file v2.1.35/linux/drivers/char/keyb_m68k.c linux/drivers/char/keyb_m68k.c --- v2.1.35/linux/drivers/char/keyb_m68k.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/keyb_m68k.c Tue Apr 22 22:42:47 1997 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -848,7 +849,7 @@ } } -int kbd_init(void) +__initfunc(int kbd_init(void)) { int i; struct kbd_struct kbd0; diff -u --recursive --new-file v2.1.35/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v2.1.35/linux/drivers/char/keyboard.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/keyboard.c Tue Apr 22 22:42:47 1997 @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -1192,7 +1193,7 @@ } } -int kbd_init(void) +__initfunc(int kbd_init(void)) { int i; struct kbd_struct kbd0; @@ -1306,7 +1307,7 @@ outb(data, address); /* write out the data*/ } -static int initialize_kbd(void) +__initfunc(static int initialize_kbd(void)) { unsigned long flags; diff -u --recursive --new-file v2.1.35/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.1.35/linux/drivers/char/lp.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/char/lp.c Tue Apr 22 22:42:47 1997 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -678,7 +679,7 @@ return 0; } -int lp_init(void) +__initfunc(int lp_init(void)) { int count = 0; struct parport *pb; @@ -693,24 +694,27 @@ pb = parport_enumerate(); while (pb) { - if (parport[0] == -1 || lp_searchfor(parport, count) || - (parport[0] == -3 && - pb->probe_info.class == PARPORT_CLASS_PRINTER)) { - lp_table[count].dev = - parport_register_device(pb, dev_name, NULL, - lp_wakeup, - lp_interrupt, PARPORT_DEV_TRAN, - (void *) &lp_table[count]); - lp_table[count].flags |= LP_EXIST; - printk(KERN_INFO "lp%d: using %s at 0x%x, ", count, - pb->name, pb->base); - if (pb->irq == -1) - printk("polling.\n"); - else - printk("irq %d.\n", pb->irq); + /* We only understand PC-style ports. */ + if (pb->modes & PARPORT_MODE_SPP) { + if (parport[0] == -1 || lp_searchfor(parport, count) || + (parport[0] == -3 && + pb->probe_info.class == PARPORT_CLASS_PRINTER)) { + lp_table[count].dev = + parport_register_device(pb, dev_name, NULL, + lp_wakeup, + lp_interrupt, PARPORT_DEV_TRAN, + (void *) &lp_table[count]); + lp_table[count].flags |= LP_EXIST; + printk(KERN_INFO "lp%d: using %s at 0x%x, ", + count, pb->name, pb->base); + if (pb->irq == -1) + printk("polling.\n"); + else + printk("irq %d.\n", pb->irq); + } + if (++count == LP_NO) + break; } - if (++count == LP_NO) - break; pb = pb->next; } diff -u --recursive --new-file v2.1.35/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c --- v2.1.35/linux/drivers/char/lp_m68k.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/lp_m68k.c Thu Apr 17 13:20:45 1997 @@ -34,8 +34,8 @@ * */ -#include #include +#include #include #include #include @@ -139,40 +139,35 @@ static int lp_error; -void lp_interrupt(int irq, void *dummy, struct pt_regs *fp) +void lp_interrupt(int dev) { - unsigned long flags; - int dev; - - for (dev = 0; dev < MAX_LP; dev++) { - if ((lp_table[dev] != NULL) && (lp_table[dev]->lp_my_interrupt(dev) != 0)) - if (lp_table[dev]->do_print) - { - if (lp_table[dev]->copy_size) - { - save_flags(flags); - cli(); - if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) { - --lp_table[dev]->copy_size; - ++lp_table[dev]->bytes_written; - restore_flags(flags); - } - else - { - lp_table[dev]->do_print = 0; - restore_flags(flags); - lp_error = 1; - wake_up_interruptible(&lp_table[dev]->lp_wait_q); - } - } - else - { - lp_table[dev]->do_print = 0; - lp_error = 0; - wake_up_interruptible(&lp_table[dev]->lp_wait_q); - } + if (dev >= 0 && dev < MAX_LP && lp_table[dev]->do_print) + { + if (lp_table[dev]->copy_size) + { + unsigned long flags; + save_flags(flags); + cli(); + if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) { + --lp_table[dev]->copy_size; + ++lp_table[dev]->bytes_written; + restore_flags(flags); + } + else + { + lp_table[dev]->do_print = 0; + restore_flags(flags); + lp_error = 1; + wake_up_interruptible(&lp_table[dev]->lp_wait_q); + } + } + else + { + lp_table[dev]->do_print = 0; + lp_error = 0; + wake_up_interruptible(&lp_table[dev]->lp_wait_q); + } - } } } @@ -366,6 +361,7 @@ static int lp_open(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + int ret; if (dev >= MAX_LP) return -ENODEV; @@ -386,10 +382,14 @@ lp_table[dev]->flags |= LP_BUSY; - MOD_INC_USE_COUNT; - lp_table[dev]->lp_open(); - - return 0; + ret = lp_table[dev]->lp_open(dev); + if (ret != 0) { + lp_table[dev]->flags &= ~LP_BUSY; + } + else { + MOD_INC_USE_COUNT; + } + return ret; } static int lp_release(struct inode *inode, struct file *file) @@ -397,7 +397,7 @@ int dev =MINOR(inode->i_rdev); lp_table[dev]->flags &= ~LP_BUSY; - lp_table[dev]->lp_release(); + lp_table[dev]->lp_release(dev); MOD_DEC_USE_COUNT; return 0; } @@ -458,18 +458,12 @@ lp_release }; -#ifdef CONFIG_MODULES -static struct symbol_table parallel_syms = { -#include - X(lp_table), - X(lp_irq), - X(lp_interrupt), - X(lp_init), - X(register_parallel), - X(unregister_parallel), -#include -}; -#endif +EXPORT_SYMBOL(lp_table); +EXPORT_SYMBOL(lp_irq); +EXPORT_SYMBOL(lp_interrupt); +EXPORT_SYMBOL(lp_init); +EXPORT_SYMBOL(register_parallel); +EXPORT_SYMBOL(unregister_parallel); int lp_init(void) { @@ -482,14 +476,6 @@ printk(KERN_ERR "unable to get major %d for line printer\n", LP_MAJOR); return -ENXIO; } - -#ifdef CONFIG_MODULES - if (register_symtab(¶llel_syms)) { - unregister_chrdev(LP_MAJOR, "lp"); - printk(KERN_CRIT "unable to register parallel symtab\n"); - return -ENXIO; - } -#endif #if WHICH_DRIVER == FORCE_POLLING lp_irq = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.1.35/linux/drivers/char/mem.c Sat Jan 25 13:46:13 1997 +++ linux/drivers/char/mem.c Thu Apr 17 13:20:45 1997 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -491,7 +492,7 @@ NULL /* fsync */ }; -int chr_dev_init(void) +__initfunc(int chr_dev_init(void)) { if (register_chrdev(MEM_MAJOR,"mem",&memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); diff -u --recursive --new-file v2.1.35/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v2.1.35/linux/drivers/char/misc.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/misc.c Tue Apr 22 22:42:47 1997 @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef CONFIG_APM #include #endif @@ -184,7 +185,7 @@ static struct proc_dir_entry *proc_misc; #endif -int misc_init(void) +__initfunc(int misc_init(void)) { #ifndef MODULE #ifdef CONFIG_PROC_FS diff -u --recursive --new-file v2.1.35/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c --- v2.1.35/linux/drivers/char/msbusmouse.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/msbusmouse.c Tue Apr 22 22:42:47 1997 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -183,7 +184,7 @@ MICROSOFT_BUSMOUSE, "msbusmouse", &ms_bus_mouse_fops }; -int ms_bus_mouse_init(void) +__initfunc(int ms_bus_mouse_init(void)) { int mse_byte, i; diff -u --recursive --new-file v2.1.35/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c --- v2.1.35/linux/drivers/char/pcwd.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/pcwd.c Tue Apr 22 22:42:47 1997 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -96,7 +97,7 @@ * This routine checks the "current_readport" to see if the card lies there. * If it does, it returns accordingly. */ -static int pcwd_checkcard(void) +__initfunc(static int pcwd_checkcard(void)) { int card_dat, prev_card_dat, found = 0, count = 0, done = 0; @@ -400,13 +401,13 @@ return 0; } -static void get_support(void) +static inline void get_support(void) { if (inb(current_readport) != 0xF0) supports_temp = 1; } -static int get_revision(void) +static inline int get_revision(void) { if ((inb(current_readport + 2) == 0xFF) || (inb(current_readport + 3) == 0xFF)) @@ -415,7 +416,7 @@ return(PCWD_REVISION_C); } -static int send_command(int cmd) +__initfunc(static int send_command(int cmd)) { int i; @@ -428,7 +429,7 @@ return(i); } -static char *get_firmware(void) +static inline char *get_firmware(void) { int i, found = 0, count = 0, one, ten, hund, minor; char *ret; @@ -498,7 +499,7 @@ #ifdef MODULE int init_module(void) #else -int pcwatchdog_init(void) +__initfunc(int pcwatchdog_init(void)) #endif { int i, found = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/char/pcxx.c linux/drivers/char/pcxx.c --- v2.1.35/linux/drivers/char/pcxx.c Sun Apr 13 10:18:20 1997 +++ linux/drivers/char/pcxx.c Tue Apr 22 22:42:47 1997 @@ -69,6 +69,7 @@ #include #include #include +#include #ifndef MODULE #include /* We only need it for parsing the "digi="-line */ @@ -217,6 +218,7 @@ timer_active &= ~(1 << DIGI_TIMER); timer_table[DIGI_TIMER].fn = NULL; timer_table[DIGI_TIMER].expires = 0; + remove_bh(DIGI_BH); if ((e1 = tty_unregister_driver(&pcxe_driver))) printk("SERIAL: failed to unregister serial driver (%d)\n", e1); @@ -1084,7 +1086,7 @@ * function to initialize the driver with the given parameters, which are either * the default values from this file or the parameters given at boot. */ -int pcxe_init(void) +__initfunc(int pcxe_init(void)) { ulong memory_seg=0, memory_size=0; int lowwater, enabled_cards=0, i, crd, shrinkmem=0, topwin = 0xff00L, botwin=0x100L; diff -u --recursive --new-file v2.1.35/linux/drivers/char/psaux.c linux/drivers/char/psaux.c --- v2.1.35/linux/drivers/char/psaux.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/psaux.c Tue Apr 22 22:42:47 1997 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -529,7 +530,7 @@ PSMOUSE_MINOR, "ps2aux", &psaux_fops }; -int psaux_init(void) +__initfunc(int psaux_init(void)) { int qp_found = 0; @@ -653,7 +654,7 @@ * See if we can find a 82C710 device. Read mouse address. */ -static int probe_qp(void) +__initfunc(static int probe_qp(void)) { outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */ outb_p(0xaa, 0x3fa); /* Inverse of 55 */ diff -u --recursive --new-file v2.1.35/linux/drivers/char/pty.c linux/drivers/char/pty.c --- v2.1.35/linux/drivers/char/pty.c Tue Mar 4 10:25:23 1997 +++ linux/drivers/char/pty.c Tue Apr 22 22:42:47 1997 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -224,7 +225,7 @@ tty->termios->c_cflag |= (CS8 | CREAD); } -int pty_init(void) +__initfunc(int pty_init(void)) { memset(&pty_state, 0, sizeof(pty_state)); memset(&pty_driver, 0, sizeof(struct tty_driver)); diff -u --recursive --new-file v2.1.35/linux/drivers/char/random.c linux/drivers/char/random.c --- v2.1.35/linux/drivers/char/random.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/random.c Tue Apr 22 22:42:47 1997 @@ -234,6 +234,7 @@ #include #include #include +#include #include #include @@ -451,7 +452,7 @@ init_std_data(&random_state); } -void rand_initialize(void) +__initfunc(void rand_initialize(void)) { int i; @@ -1388,8 +1389,9 @@ return (((unsigned long long) high << 31) | low); } -static void initialize_benchmark(struct random_benchmark *bench, - const char *descr, int unit) +__initfunc(static void +initialize_benchmark(struct random_benchmark *bench, + const char *descr, int unit)) { bench->times = 0; bench->accum = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/char/riscom8.c linux/drivers/char/riscom8.c --- v2.1.35/linux/drivers/char/riscom8.c Fri Dec 27 02:03:22 1996 +++ linux/drivers/char/riscom8.c Tue Apr 22 22:42:47 1997 @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -231,7 +232,7 @@ } /* Reset and setup CD180 chip */ -static void rc_init_CD180(struct riscom_board const * bp) +__initfunc(static void rc_init_CD180(struct riscom_board const * bp)) { unsigned long flags; @@ -256,7 +257,7 @@ } /* Main probing routine, also sets irq. */ -static int rc_probe(struct riscom_board *bp) +__initfunc(static int rc_probe(struct riscom_board *bp)) { unsigned char val1, val2; int irqs = 0; @@ -264,7 +265,7 @@ bp->irq = 0; - if (rc_check_io_range(bp)) + if (rc_check_io_range(bp)) return 1; /* Are the I/O ports here ? */ @@ -1718,7 +1719,7 @@ } } -static int rc_init_drivers(void) +static inline int rc_init_drivers(void) { int error; int i; @@ -1799,9 +1800,15 @@ static void rc_release_drivers(void) { + unsigned long flags; + + save_flags(flags); + cli(); + remove_bh(RISCOM8_BH); free_page((unsigned long)tmp_buf); tty_unregister_driver(&riscom_driver); tty_unregister_driver(&riscom_callout_driver); + restore_flags(flags); } #ifndef MODULE @@ -1830,7 +1837,7 @@ /* * This routine must be called by kernel at boot time */ -int riscom8_init(void) +__initfunc(int riscom8_init(void)) { int i; int found = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/char/rtc.c linux/drivers/char/rtc.c --- v2.1.35/linux/drivers/char/rtc.c Wed Apr 16 14:15:00 1997 +++ linux/drivers/char/rtc.c Tue Apr 22 22:42:47 1997 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -531,7 +532,7 @@ &rtc_fops }; -int rtc_init(void) +__initfunc(int rtc_init(void)) { unsigned long flags; diff -u --recursive --new-file v2.1.35/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.1.35/linux/drivers/char/serial.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/serial.c Tue Apr 22 22:42:47 1997 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -2917,7 +2918,7 @@ * number, and identifies which options were configured into this * driver. */ -static void show_serial_version(void) +static _INLINE_ void show_serial_version(void) { printk(KERN_INFO "%s version %s with", serial_name, serial_version); #ifdef CONFIG_HUB6 @@ -3216,7 +3217,7 @@ /* * The serial driver boot-time initialization code! */ -int rs_init(void) +__initfunc(int rs_init(void)) { int i; struct serial_state * state; @@ -3410,6 +3411,7 @@ timer_active &= ~(1 << RS_TIMER); timer_table[RS_TIMER].fn = NULL; timer_table[RS_TIMER].expires = 0; + remove_bh(SERIAL_BH); if ((e1 = tty_unregister_driver(&serial_driver))) printk("SERIAL: failed to unregister serial driver (%d)\n", e1); diff -u --recursive --new-file v2.1.35/linux/drivers/char/softdog.c linux/drivers/char/softdog.c --- v2.1.35/linux/drivers/char/softdog.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/softdog.c Tue Apr 22 22:42:47 1997 @@ -34,6 +34,7 @@ #include #include #include +#include #include #define WATCHDOG_MINOR 130 @@ -172,7 +173,7 @@ &softdog_fops }; -void watchdog_init(void) +__initfunc(void watchdog_init(void)) { misc_register(&softdog_miscdev); init_timer(&watchdog_ticktock); diff -u --recursive --new-file v2.1.35/linux/drivers/char/stallion.c linux/drivers/char/stallion.c --- v2.1.35/linux/drivers/char/stallion.c Mon Mar 17 14:54:25 1997 +++ linux/drivers/char/stallion.c Tue Apr 22 22:42:47 1997 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -389,10 +390,10 @@ static void stl_hangup(struct tty_struct *tty); static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); -static int stl_initbrds(void); +static inline int stl_initbrds(void); static int stl_brdinit(stlbrd_t *brdp); -static int stl_initeio(stlbrd_t *brdp); -static int stl_initech(stlbrd_t *brdp); +static inline int stl_initeio(stlbrd_t *brdp); +static inline int stl_initech(stlbrd_t *brdp); static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp); static int stl_mapirq(int irq); static void stl_getserial(stlport_t *portp, struct serial_struct *sp); @@ -414,7 +415,7 @@ static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); #ifdef CONFIG_PCI -static int stl_findpcibrds(void); +static inline int stl_findpcibrds(void); #endif /* @@ -1745,7 +1746,7 @@ * interrupt across multiple boards. */ -static int stl_mapirq(int irq) +__initfunc(static int stl_mapirq(int irq)) { int rc, i; @@ -1775,7 +1776,7 @@ * Initialize all the ports on a panel. */ -static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) +__initfunc(static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)) { stlport_t *portp; int chipmask, i; @@ -1827,7 +1828,7 @@ * Try to find and initialize an EasyIO board. */ -static int stl_initeio(stlbrd_t *brdp) +static inline int stl_initeio(stlbrd_t *brdp) { stlpanel_t *panelp; unsigned int status; @@ -1929,7 +1930,7 @@ * dealing with all types of ECH board. */ -static int stl_initech(stlbrd_t *brdp) +static inline int stl_initech(stlbrd_t *brdp) { stlpanel_t *panelp; unsigned int status, nxtid, ioaddr, conflict; @@ -2096,7 +2097,7 @@ * since the initial search and setup is very different. */ -static int stl_brdinit(stlbrd_t *brdp) +__initfunc(static int stl_brdinit(stlbrd_t *brdp)) { int i; @@ -2141,7 +2142,7 @@ #ifdef CONFIG_PCI -static int stl_findpcibrds() +static inline int stl_findpcibrds() { stlbrd_t *brdp; unsigned char busnr, devnr, irq; @@ -2228,7 +2229,7 @@ * since the initial search and setup is too different. */ -static int stl_initbrds() +static inline int stl_initbrds() { stlbrd_t *brdp; stlconf_t *confp; @@ -2514,7 +2515,7 @@ /*****************************************************************************/ -int stl_init(void) +__initfunc(int stl_init(void)) { printk(KERN_INFO "%s: version %s\n", stl_drvname, stl_drvversion); diff -u --recursive --new-file v2.1.35/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.1.35/linux/drivers/char/tty_io.c Sun Apr 13 10:18:21 1997 +++ linux/drivers/char/tty_io.c Tue Apr 22 22:42:47 1997 @@ -71,6 +71,7 @@ #ifdef CONFIG_PROC_FS #include #endif +#include #include #include @@ -1704,7 +1705,7 @@ * Ok, now we can initialize the rest of the tty devices and can count * on memory allocations, interrupts etc.. */ -int tty_init(void) +__initfunc(int tty_init(void)) { if (sizeof(struct tty_struct) > PAGE_SIZE) panic("size of tty structure > PAGE_SIZE!"); diff -u --recursive --new-file v2.1.35/linux/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c --- v2.1.35/linux/drivers/char/vc_screen.c Sun Jan 26 02:07:17 1997 +++ linux/drivers/char/vc_screen.c Tue Apr 22 22:42:48 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "vt_kern.h" #include "selection.h" @@ -251,7 +252,7 @@ NULL /* fsync */ }; -int vcs_init(void) +__initfunc(int vcs_init(void)) { int error; diff -u --recursive --new-file v2.1.35/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.1.35/linux/drivers/char/vt.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/char/vt.c Thu Apr 17 09:20:38 1997 @@ -311,7 +311,7 @@ int sz; int delta; char *first_free, *fj, *fnw; - int j, k, i = 0; + int i, j, k; /* we mostly copy too much here (512bytes), but who cares ;) */ if (copy_from_user(&tmp, user_kdgkb, sizeof(struct kbsentry))) @@ -319,6 +319,7 @@ tmp.kb_string[sizeof(tmp.kb_string)-1] = '\0'; if (tmp.kb_func >= MAX_NR_FUNC) return -EINVAL; + i = tmp.kb_func; switch (cmd) { case KDGKBSENT: diff -u --recursive --new-file v2.1.35/linux/drivers/char/wdt.c linux/drivers/char/wdt.c --- v2.1.35/linux/drivers/char/wdt.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/wdt.c Tue Apr 22 22:42:48 1997 @@ -43,6 +43,7 @@ #include #include #include +#include static int wdt_is_open=0; @@ -352,22 +353,7 @@ #ifdef MODULE -int init_module(void) -{ - printk("WDT501-P module at %X(Interrupt %d)\n", io,irq); - if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL)) - { - printk("IRQ %d is not free.\n", irq); - return -EIO; - } - misc_register(&wdt_miscdev); -#ifdef CONFIG_WDT_501 - misc_register(&temp_miscdev); -#endif - request_region(io, 8, "wdt501"); - notifier_chain_register(&boot_notifier_list, &wdt_notifier); - return 0; -} +#define wdt_init init_module void cleanup_module(void) { @@ -380,9 +366,9 @@ free_irq(irq, NULL); } -#else +#endif -int wdt_init(void) +__initfunc(int wdt_init(void)) { printk("WDT500/501-P driver at %X(Interrupt %d)\n", io,irq); if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL)) @@ -399,4 +385,3 @@ return 0; } -#endif diff -u --recursive --new-file v2.1.35/linux/drivers/isdn/sc/init.c linux/drivers/isdn/sc/init.c --- v2.1.35/linux/drivers/isdn/sc/init.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/isdn/sc/init.c Thu Apr 17 09:23:17 1997 @@ -305,7 +305,7 @@ /* * No interrupt could be used */ - pr_debug("Failed to aquire an IRQ line\n"); + pr_debug("Failed to acquire an IRQ line\n"); continue; } diff -u --recursive --new-file v2.1.35/linux/drivers/net/3c501.c linux/drivers/net/3c501.c --- v2.1.35/linux/drivers/net/3c501.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/3c501.c Tue Apr 22 22:42:48 1997 @@ -102,12 +102,13 @@ #include #include #include +#include #define BLOCKOUT_2 /* A zero-terminated list of I/O addresses to be probed. The 3c501 can be at many locations, but here are the popular ones. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x280, 0x300, 0}; @@ -208,7 +209,7 @@ struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist}; #else -int el1_probe(struct device *dev) +__initfunc(int el1_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -235,7 +236,7 @@ * The actual probe. */ -static int el1_probe1(struct device *dev, int ioaddr) +__initfunc(static int el1_probe1(struct device *dev, int ioaddr)) { const char *mname; /* Vendor name */ unsigned char station_addr[6]; diff -u --recursive --new-file v2.1.35/linux/drivers/net/3c503.c linux/drivers/net/3c503.c --- v2.1.35/linux/drivers/net/3c503.c Tue Dec 31 00:29:59 1996 +++ linux/drivers/net/3c503.c Tue Apr 22 22:42:48 1997 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -56,7 +57,7 @@ int el2_probe1(struct device *dev, int ioaddr); /* A zero-terminated list of I/O addresses to be probed in PIO mode. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0}; #define EL2_IO_EXTENT 16 @@ -89,8 +90,8 @@ If the ethercard isn't found there is an optional probe for ethercard jumpered to programmed-I/O mode. */ -int -el2_probe(struct device *dev) +__initfunc(int +el2_probe(struct device *dev)) { int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0}; int base_addr = dev->base_addr; @@ -124,8 +125,8 @@ #ifndef HAVE_DEVLIST /* Try all of the locations that aren't obviously empty. This touches a lot of locations, and is much riskier than the code above. */ -int -el2_pio_probe(struct device *dev) +__initfunc(int +el2_pio_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -150,8 +151,8 @@ /* Probe for the Etherlink II card at I/O port base IOADDR, returning non-zero on success. If found, set the station address and memory parameters in DEVICE. */ -int -el2_probe1(struct device *dev, int ioaddr) +__initfunc(int +el2_probe1(struct device *dev, int ioaddr)) { int i, iobase_reg, membase_reg, saved_406, wordlength; static unsigned version_printed = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/3c505.c linux/drivers/net/3c505.c --- v2.1.35/linux/drivers/net/3c505.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/net/3c505.c Tue Apr 22 22:42:48 1997 @@ -108,6 +108,7 @@ #include #include #include +#include #include "3c505.h" @@ -178,7 +179,7 @@ * Last element MUST BE 0! *****************************************************************/ -static const int addr_list[] = {0x300, 0x280, 0x310, 0}; +static const int addr_list[] __initdata = {0x300, 0x280, 0x310, 0}; /* Dma Memory related stuff */ @@ -1305,7 +1306,7 @@ * ******************************************************/ -static void elp_init(struct device *dev) +static inline void elp_init(struct device *dev) { elp_device *adapter = dev->priv; @@ -1338,7 +1339,7 @@ * Called only by elp_autodetect ************************************************************/ -static int elp_sense(struct device *dev) +__initfunc(static int elp_sense(struct device *dev)) { int timeout; int addr = dev->base_addr; @@ -1405,7 +1406,7 @@ * Called only by eplus_probe *************************************************************/ -static int elp_autodetect(struct device *dev) +__initfunc(static int elp_autodetect(struct device *dev)) { int idx = 0; @@ -1449,7 +1450,7 @@ * work at all if it was in a weird state). */ -int elplus_probe(struct device *dev) +__initfunc(int elplus_probe(struct device *dev)) { elp_device *adapter; int i, tries, tries1, timeout, okay; diff -u --recursive --new-file v2.1.35/linux/drivers/net/3c507.c linux/drivers/net/3c507.c --- v2.1.35/linux/drivers/net/3c507.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/3c507.c Tue Apr 22 22:42:48 1997 @@ -59,6 +59,7 @@ #include #include #include +#include /* use 0 for production, 1 for verification, 2..7 for debug */ @@ -68,7 +69,7 @@ static unsigned int net_debug = NET_DEBUG; /* A zero-terminated list of common I/O addresses to be probed. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x280, 0}; /* @@ -301,7 +302,7 @@ device and return success. */ -int el16_probe(struct device *dev) +__initfunc(int el16_probe(struct device *dev)) { int base_addr = dev ? dev->base_addr : 0; int i; @@ -322,7 +323,7 @@ return ENODEV; } -int el16_probe1(struct device *dev, int ioaddr) +__initfunc(int el16_probe1(struct device *dev, int ioaddr)) { static unsigned char init_ID_done = 0, version_printed = 0; int i, irq, irqval; diff -u --recursive --new-file v2.1.35/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.1.35/linux/drivers/net/3c509.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/3c509.c Tue Apr 22 22:42:48 1997 @@ -48,6 +48,7 @@ #include #include /* for CONFIG_MCA */ #include /* for udelay() */ +#include #include #include @@ -132,7 +133,7 @@ -int el3_probe(struct device *dev) +__initfunc(int el3_probe(struct device *dev)) { short lrs_state = 0xff, i; ushort ioaddr, irq, if_port; @@ -312,7 +313,7 @@ /* Read a word from the EEPROM using the regular EEPROM access register. Assume that we are in register window zero. */ -static ushort read_eeprom(short ioaddr, int index) +__initfunc(static ushort read_eeprom(short ioaddr, int index)) { outw(EEPROM_READ + index, ioaddr + 10); /* Pause for at least 162 us. for the read to take place. */ @@ -321,7 +322,7 @@ } /* Read a word from the EEPROM when in the ISA ID probe state. */ -static ushort id_read_eeprom(int index) +__initfunc(static ushort id_read_eeprom(int index)) { int bit, word = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/3c523.c linux/drivers/net/3c523.c --- v2.1.35/linux/drivers/net/3c523.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/3c523.c Tue Apr 22 22:42:48 1997 @@ -100,6 +100,7 @@ #include #include #include +#include #include "3c523.h" @@ -115,9 +116,9 @@ /* Tables to which we can map values in the configuration registers. */ -static int irq_table[] = {12, 7, 3, 9}; -static int csr_table[] = {0x300, 0x1300, 0x2300, 0x3300}; -static int shm_table[] = {0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000}; +static int irq_table[] __initdata = {12, 7, 3, 9}; +static int csr_table[] __initdata = {0x300, 0x1300, 0x2300, 0x3300}; +static int shm_table[] __initdata = {0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000}; /******************* how to calculate the buffers ***************************** @@ -308,9 +309,9 @@ * Check to see if there's an 82586 out there. */ -static +__initfunc(static int -check586( struct device *dev, char *where, unsigned size) { +check586( struct device *dev, char *where, unsigned size)) { struct priv *p = (struct priv *) dev->priv; char *iscp_addrs[2]; int i = 0; @@ -382,8 +383,8 @@ } /*****************************************************************/ -static int -elmc_getinfo( char* buf, int slot, void* d ) { +__initfunc(static int +elmc_getinfo( char* buf, int slot, void* d )) { int len = 0; struct device* dev = (struct device*) d; int i; @@ -411,8 +412,8 @@ } /* elmc_getinfo() */ /*****************************************************************/ -int -elmc_probe(struct device *dev) { +__initfunc(int +elmc_probe(struct device *dev)) { static int slot = 0; int base_addr = dev ? dev->base_addr : 0; int irq = dev ? dev->irq : 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c --- v2.1.35/linux/drivers/net/3c59x.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/3c59x.c Tue Apr 22 22:42:48 1997 @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_PCI #include @@ -84,7 +85,7 @@ #endif #ifdef CONFIG_PCI -static int product_ids[] = {0x5900, 0x5950, 0x5951, 0x5952, 0, 0}; +static int product_ids[] __initdata = {0x5900, 0x5950, 0x5951, 0x5952, 0, 0}; #endif static const char *product_names[] = { @@ -326,7 +327,7 @@ } #else -int tc59x_probe(struct device *dev) +__initfunc(int tc59x_probe(struct device *dev)) { int cards_found = 0; @@ -339,7 +340,7 @@ } #endif /* not MODULE */ -static int vortex_scan(struct device *dev) +__initfunc(static int vortex_scan(struct device *dev)) { int cards_found = 0; @@ -420,8 +421,8 @@ return cards_found; } -static int vortex_found_device(struct device *dev, int ioaddr, int irq, - int product_index, int options) +__initfunc(static int vortex_found_device(struct device *dev, int ioaddr, int irq, + int product_index, int options)) { struct vortex_private *vp; @@ -480,7 +481,7 @@ return 0; } -static int vortex_probe1(struct device *dev) +__initfunc(static int vortex_probe1(struct device *dev)) { int ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; diff -u --recursive --new-file v2.1.35/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v2.1.35/linux/drivers/net/8390.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/8390.c Tue Apr 22 22:42:48 1997 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -771,7 +772,7 @@ } /* Initialize the rest of the 8390 device structure. */ -int ethdev_init(struct device *dev) +__initfunc(int ethdev_init(struct device *dev)) { if (ei_debug > 1) printk(version); diff -u --recursive --new-file v2.1.35/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.35/linux/drivers/net/Config.in Sun Apr 13 10:18:21 1997 +++ linux/drivers/net/Config.in Tue Apr 15 21:47:23 1997 @@ -73,7 +73,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 fi - + tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT tristate 'CS89x0 support' CONFIG_CS89x0 tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 diff -u --recursive --new-file v2.1.35/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.1.35/linux/drivers/net/Space.c Sun Apr 13 10:18:21 1997 +++ linux/drivers/net/Space.c Thu Apr 17 13:20:45 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #define NEXT_DEV NULL @@ -93,7 +94,7 @@ extern int de600_probe(struct device *); extern int de620_probe(struct device *); -static int ethif_probe(struct device *dev) +__initfunc(static int ethif_probe(struct device *dev)) { u_long base_addr = dev->base_addr; diff -u --recursive --new-file v2.1.35/linux/drivers/net/a2065.c linux/drivers/net/a2065.c --- v2.1.35/linux/drivers/net/a2065.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/a2065.c Tue Apr 22 22:42:48 1997 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -55,7 +56,7 @@ #include #include -#include +#include #include #include @@ -302,14 +303,16 @@ lp->stats.rx_errors++; continue; } else if (bits & LE_R1_ERR) { - /* Count only the end frame as a tx error, not the beginning */ + /* Count only the end frame as a rx error, + * not the beginning + */ if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; if (bits & LE_R1_EOP) lp->stats.rx_errors++; } else { - len = rd->mblength; + len = (rd->mblength & 0xfff) - 4; skb = dev_alloc_skb (len+2); if (skb == 0) { @@ -582,6 +585,16 @@ return status; } + if (skb == NULL) { + dev_tint (dev); + printk ("skb is NULL\n"); + return 0; + } + + if (skb->len <= 0) { + printk ("skb len is %d\n", skb->len); + return 0; + } /* Block a timer-based transmit from overlapping. */ #ifdef OLD_METHOD dev->tbusy = 1; @@ -698,18 +711,13 @@ struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_regs *ll = lp->ll; - char shown; - shown = 0; while (dev->tbusy) - if (!shown++) - printk ("Waiting for tbusy to go down\n"); + schedule(); set_bit (0, (void *) &dev->tbusy); - shown = 0; while (lp->tx_old != lp->tx_new) - if (!shown) - printk ("Waiting for buffer to empty\n"); + schedule(); ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; @@ -727,7 +735,7 @@ } -int a2065_probe(struct device *dev) +__initfunc(int a2065_probe(struct device *dev)) { int key1, key2 = 0; struct ConfigDev *cd; diff -u --recursive --new-file v2.1.35/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c --- v2.1.35/linux/drivers/net/ac3200.c Tue Dec 31 00:29:59 1996 +++ linux/drivers/net/ac3200.c Tue Apr 22 22:42:48 1997 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -54,7 +55,7 @@ */ /* Decoding of the configuration register. */ -static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3}; +static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; static int addrmap[8] = {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 }; static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"}; @@ -88,7 +89,7 @@ or the unique value in the station address PROM. */ -int ac3200_probe(struct device *dev) +__initfunc(int ac3200_probe(struct device *dev)) { unsigned short ioaddr = dev->base_addr; @@ -111,7 +112,7 @@ return ENODEV; } -static int ac_probe1(int ioaddr, struct device *dev) +__initfunc(static int ac_probe1(int ioaddr, struct device *dev)) { int i; diff -u --recursive --new-file v2.1.35/linux/drivers/net/apricot.c linux/drivers/net/apricot.c --- v2.1.35/linux/drivers/net/apricot.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/apricot.c Tue Apr 22 22:42:48 1997 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -675,7 +676,7 @@ printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]); } -int apricot_probe(struct device *dev) +__initfunc(int apricot_probe(struct device *dev)) { int i; struct i596_private *lp; @@ -1001,7 +1002,7 @@ } #ifdef HAVE_DEVLIST -static unsigned int apricot_portlist[] = {0x300, 0}; +static unsigned int apricot_portlist[] __initdata = {0x300, 0}; struct netdev_entry apricot_drv = {"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist}; #endif diff -u --recursive --new-file v2.1.35/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c --- v2.1.35/linux/drivers/net/arcnet.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/arcnet.c Tue Apr 22 22:42:48 1997 @@ -162,6 +162,7 @@ #include #include #include +#include #include #include @@ -711,7 +712,7 @@ * need to be passed a specific shmem address, IRQ, and node ID (stored in * dev->base_addr) */ -int arcnet_probe(struct device *dev) +__initfunc(int arcnet_probe(struct device *dev)) { BUGLVL(D_NORMAL) printk(version); BUGMSG(D_NORMAL,"Compiled for ARCnet RIM I (autoprobe disabled)\n"); @@ -749,11 +750,13 @@ * * FIXME: grab all devices in one shot and eliminate the big static array. */ -int arcnet_probe(struct device *dev) + +static int ports[(0x3f0 - 0x200) / 16 + 1] __initdata; +static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata; + +__initfunc(int arcnet_probe(struct device *dev)) { static int init_once = 0; - static int ports[(0x3f0 - 0x200) / 16 + 1]; - static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1]; static int numports=sizeof(ports)/sizeof(ports[0]), numshmems=sizeof(shmems)/sizeof(shmems[0]); @@ -1126,7 +1129,7 @@ /* Set up the struct device associated with this card. Called after * probing succeeds. */ -int arcnet_found(struct device *dev,int port,int airq, u_long shmem) +__initfunc(int arcnet_found(struct device *dev,int port,int airq, u_long shmem)) { u_long first_mirror,last_mirror; struct arcnet_local *lp; diff -u --recursive --new-file v2.1.35/linux/drivers/net/ariadne.c linux/drivers/net/ariadne.c --- v2.1.35/linux/drivers/net/ariadne.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/ariadne.c Tue Apr 22 22:42:48 1997 @@ -49,11 +49,12 @@ #include #include #include +#include #include #include #include -#include +#include #include #include @@ -145,7 +146,7 @@ } -int ariadne_probe(struct device *dev) +__initfunc(int ariadne_probe(struct device *dev)) { int key; struct ConfigDev *cd; @@ -365,7 +366,7 @@ if (ariadne_debug > 1) { printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name, board->Lance.RDP); - printk("%s: %d packets missed\n", dev->name, + printk("%s: %lu packets missed\n", dev->name, priv->stats.rx_missed_errors); } diff -u --recursive --new-file v2.1.35/linux/drivers/net/at1700.c linux/drivers/net/at1700.c --- v2.1.35/linux/drivers/net/at1700.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/at1700.c Tue Apr 22 22:42:48 1997 @@ -48,13 +48,14 @@ #include #include #include +#include #include #include #include /* This unusual address order is used to verify the CONFIG register. */ -static int at1700_probe_list[] = +static int at1700_probe_list[] __initdata = {0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -136,8 +137,8 @@ struct netdev_entry at1700_drv = {"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list}; #else -int -at1700_probe(struct device *dev) +__initfunc(int +at1700_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -167,7 +168,7 @@ that can be done is checking a few bits and then diving right into an EEPROM read. */ -int at1700_probe1(struct device *dev, short ioaddr) +__initfunc(int at1700_probe1(struct device *dev, short ioaddr)) { char irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15}; unsigned int i, irq; @@ -275,7 +276,7 @@ return 0; } -static int read_eeprom(int ioaddr, int location) +__initfunc(static int read_eeprom(int ioaddr, int location)) { int i; unsigned short retval = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c --- v2.1.35/linux/drivers/net/atari_bionet.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/atari_bionet.c Tue Apr 22 22:42:48 1997 @@ -80,12 +80,7 @@ static char *version = "bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n"; -#ifdef MODULE #include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif #include #include @@ -100,6 +95,7 @@ #include #include #include +#include #include #include @@ -326,8 +322,8 @@ /* 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 */ @@ -596,22 +592,13 @@ #ifdef MODULE -#include - -/* We should include the kernel identification string in the module. - */ -static char kernel_version[] = UTS_RELEASE; - -#undef NEXT_DEV -#define NEXT_DEV (&bio_dev) - static char bio_name[16]; static struct device bio_dev = { bio_name, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ 0, 0, /* base, irq */ - 0, 0, 0, NEXT_DEV, bionet_probe, + 0, 0, 0, NULL, bionet_probe, }; int diff -u --recursive --new-file v2.1.35/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c --- v2.1.35/linux/drivers/net/atari_pamsnet.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/atari_pamsnet.c Tue Apr 22 22:42:48 1997 @@ -77,12 +77,7 @@ static char *version = "pamsnet.c:v0.2beta 30-mar-96 (c) Torsten Lang.\n"; -#ifdef MODULE #include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif #include #include @@ -107,6 +102,7 @@ #include #include +#include #include #include @@ -565,8 +561,8 @@ /* 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; @@ -868,21 +864,12 @@ #ifdef MODULE -#include - -/* We should include the kernel identification string in the module. - */ -static char kernel_version[] = UTS_RELEASE; - -#undef NEXT_DEV -#define NEXT_DEV (&pam_dev) - static struct device pam_dev = { " ", /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ 0, 0, /* base, irq */ - 0, 0, 0, NEXT_DEV, pamsnet_probe, + 0, 0, 0, NULL, pamsnet_probe, }; int diff -u --recursive --new-file v2.1.35/linux/drivers/net/atarilance.c linux/drivers/net/atarilance.c --- v2.1.35/linux/drivers/net/atarilance.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/atarilance.c Tue Apr 22 22:42:48 1997 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -369,7 +370,7 @@ } -int atarilance_probe( struct device *dev ) +__initfunc(int atarilance_probe( struct device *dev )) { int i; static int found = 0; @@ -392,7 +393,7 @@ /* Derived from hwreg_present() in atari/config.c: */ -static int addr_accessible( volatile void *regp, int wordflag, int writeflag ) +__initfunc(static int addr_accessible( volatile void *regp, int wordflag, int writeflag )) { int ret; long flags; @@ -442,8 +443,8 @@ } -static unsigned long lance_probe1( struct device *dev, - struct lance_addr *init_rec ) +__initfunc(static unsigned long lance_probe1( struct device *dev, + struct lance_addr *init_rec )) { volatile unsigned short *memaddr = (volatile unsigned short *)init_rec->memaddr; diff -u --recursive --new-file v2.1.35/linux/drivers/net/atp.c linux/drivers/net/atp.c --- v2.1.35/linux/drivers/net/atp.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/atp.c Tue Apr 22 22:42:48 1997 @@ -96,6 +96,7 @@ #include #include #include +#include #include #include @@ -149,8 +150,8 @@ If dev->base_addr == 2, allocate space for the device and return success (detachable devices only). */ -int -atp_init(struct device *dev) +__initfunc(int +atp_init(struct device *dev)) { int *port, ports[] = {0x378, 0x278, 0x3bc, 0}; int base_addr = dev->base_addr; @@ -172,7 +173,7 @@ return ENODEV; } -static int atp_probe1(struct device *dev, short ioaddr) +__initfunc(static int atp_probe1(struct device *dev, short ioaddr)) { int saved_ctrl_reg, status; @@ -258,7 +259,7 @@ } /* Read the station address PROM, usually a word-wide EEPROM. */ -static void get_node_ID(struct device *dev) +__initfunc(static void get_node_ID(struct device *dev)) { short ioaddr = dev->base_addr; int sa_offset = 0; @@ -290,7 +291,7 @@ * DO : _________X_______X */ -static unsigned short eeprom_op(short ioaddr, unsigned int cmd) +__initfunc(static unsigned short eeprom_op(short ioaddr, unsigned int cmd)) { unsigned eedata_out = 0; int num_bits = EE_CMD_SIZE; diff -u --recursive --new-file v2.1.35/linux/drivers/net/baycom.c linux/drivers/net/baycom.c --- v2.1.35/linux/drivers/net/baycom.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/net/baycom.c Tue Apr 22 22:42:48 1997 @@ -89,6 +89,7 @@ #include #include #include +#include /* --------------------------------------------------------------------- */ @@ -936,7 +937,7 @@ /* --------------------------------------------------------------------- */ -int baycom_init(void) +__initfunc(int baycom_init(void)) { int i, j, found = 0; char set_hw = 1; @@ -1038,7 +1039,7 @@ * * indicates sofware DCD */ -void baycom_setup(char *str, int *ints) +__initfunc(void baycom_setup(char *str, int *ints)) { int i; diff -u --recursive --new-file v2.1.35/linux/drivers/net/bpqether.c linux/drivers/net/bpqether.c --- v2.1.35/linux/drivers/net/bpqether.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/bpqether.c Tue Apr 22 22:42:48 1997 @@ -82,6 +82,7 @@ #include #include #include +#include #include #include @@ -632,7 +633,7 @@ * Initialize driver. To be called from af_ax25 if not compiled as a * module */ -int bpq_init(void) +__initfunc(int bpq_init(void)) { struct device *dev; diff -u --recursive --new-file v2.1.35/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c --- v2.1.35/linux/drivers/net/cs89x0.c Mon Apr 7 11:35:29 1997 +++ linux/drivers/net/cs89x0.c Tue Apr 22 22:42:48 1997 @@ -78,6 +78,7 @@ #include #include #include +#include #include #include @@ -86,7 +87,7 @@ /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int netcard_portlist[] = +static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int net_debug = NET_DEBUG; @@ -145,8 +146,8 @@ struct netdev_entry netcard_drv = {"netcard", cs89x0_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else -int -cs89x0_probe(struct device *dev) +__initfunc(int +cs89x0_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -195,8 +196,8 @@ outw(value, dev->base_addr + portno); } -static int -wait_eeprom_ready(struct device *dev) +__initfunc(static int +wait_eeprom_ready(struct device *dev)) { int timeout = jiffies; /* check to see if the EEPROM is ready, a timeout is used - @@ -208,8 +209,8 @@ return 0; } -int -get_eeprom_data(struct device *dev, int off, int len, int *buffer) +__initfunc(static int +get_eeprom_data(struct device *dev, int off, int len, int *buffer)) { int i; @@ -226,8 +227,8 @@ return 0; } -int -get_eeprom_cksum(int off, int len, int *buffer) +__initfunc(static int +get_eeprom_cksum(int off, int len, int *buffer)) { int i, cksum; @@ -244,7 +245,7 @@ probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int cs89x0_probe1(struct device *dev, int ioaddr) +__initfunc(static int cs89x0_probe1(struct device *dev, int ioaddr)) { struct net_local *lp; static unsigned version_printed = 0; @@ -392,8 +393,8 @@ -void -reset_chip(struct device *dev) +__initfunc(void +reset_chip(struct device *dev)) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; diff -u --recursive --new-file v2.1.35/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v2.1.35/linux/drivers/net/de4x5.c Mon Apr 7 11:35:29 1997 +++ linux/drivers/net/de4x5.c Tue Apr 22 22:42:48 1997 @@ -266,6 +266,7 @@ #include #include #include +#include #include #include #include @@ -861,8 +862,8 @@ ** more info. Until I fix (un)register_netdevice() we won't be able to use it ** though. */ -int -de4x5_probe(struct device *dev) +__initfunc(int +de4x5_probe(struct device *dev)) { int status = -ENODEV; u_long iobase = dev->base_addr; @@ -882,8 +883,8 @@ return status; } -static int -de4x5_hw_init(struct device *dev, u_long iobase) +__initfunc(static int +de4x5_hw_init(struct device *dev, u_long iobase)) { struct bus_type *lp = &bus; int i, status=0; @@ -1797,8 +1798,8 @@ ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. Upto 15 EISA devices are supported. */ -static void -eisa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void +eisa_probe(struct device *dev, u_long ioaddr)) { int i, maxSlots, status, device; u_short vendor; @@ -1874,8 +1875,8 @@ #define PCI_DEVICE (dev_num << 3) #define PCI_LAST_DEV 32 -static void -pci_probe(struct device *dev, u_long ioaddr) +__initfunc(static void +pci_probe(struct device *dev, u_long ioaddr)) { u_char irq; u_char pb, pbus, dev_num, dnum, dev_fn; @@ -1974,8 +1975,8 @@ ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * -alloc_device(struct device *dev, u_long iobase) +__initfunc(static struct device * +alloc_device(struct device *dev, u_long iobase)) { struct device *adev = NULL; int fixed = 0, new_dev = 0; @@ -2027,8 +2028,8 @@ ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +__initfunc(static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))) { struct device *new; @@ -2055,8 +2056,8 @@ return new; } -static int -de4x5_dev_index(char *s) +__initfunc(static int +de4x5_dev_index(char *s)) { int i=0, j=0; @@ -2070,8 +2071,8 @@ return i; } -static void -link_modules(struct device *dev, struct device *tmp) +__initfunc(static void +link_modules(struct device *dev, struct device *tmp)) { struct device *p=dev; diff -u --recursive --new-file v2.1.35/linux/drivers/net/de600.c linux/drivers/net/de600.c --- v2.1.35/linux/drivers/net/de600.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/net/de600.c Tue Apr 22 22:42:48 1997 @@ -103,6 +103,7 @@ #include #include #include +#include #include #include @@ -624,8 +625,8 @@ */ } -int -de600_probe(struct device *dev) +__initfunc(int +de600_probe(struct device *dev)) { int i; static struct net_device_stats de600_netstats; diff -u --recursive --new-file v2.1.35/linux/drivers/net/de620.c linux/drivers/net/de620.c --- v2.1.35/linux/drivers/net/de620.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/de620.c Tue Apr 22 22:42:48 1997 @@ -131,6 +131,7 @@ #include #include #include +#include #include #include @@ -822,8 +823,8 @@ * * Check if there is a DE-620 connected */ -int -de620_probe(struct device *dev) +__initfunc(int +de620_probe(struct device *dev)) { static struct net_device_stats de620_netstats; int i; @@ -915,8 +916,8 @@ */ #define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); -static unsigned short -ReadAWord(struct device *dev, int from) +__initfunc(static unsigned short +ReadAWord(struct device *dev, int from)) { unsigned short data; int nbits; @@ -958,8 +959,8 @@ return data; } -static int -read_eeprom(struct device *dev) +__initfunc(static int +read_eeprom(struct device *dev)) { unsigned short wrd; diff -u --recursive --new-file v2.1.35/linux/drivers/net/defxx.c linux/drivers/net/defxx.c --- v2.1.35/linux/drivers/net/defxx.c Sun Feb 2 05:18:39 1997 +++ linux/drivers/net/defxx.c Tue Apr 22 22:42:48 1997 @@ -215,6 +215,7 @@ #include #include #include +#include #include #include #include @@ -437,9 +438,9 @@ * the device structure. */ -int dfx_probe( +__initfunc(int dfx_probe( struct device *dev - ) + )) { int i; /* used in for loops */ @@ -636,10 +637,10 @@ * None */ -struct device *dfx_alloc_device( +__initfunc(struct device *dfx_alloc_device( struct device *dev, u16 iobase - ) + )) { struct device *tmp_dev; /* pointer to a device structure */ @@ -731,9 +732,9 @@ * enabled yet. */ -void dfx_bus_init( +__initfunc(void dfx_bus_init( struct device *dev - ) + )) { DFX_board_t *bp = (DFX_board_t *)dev->priv; @@ -865,9 +866,9 @@ * None */ -void dfx_bus_config_check( +__initfunc(void dfx_bus_config_check( DFX_board_t *bp - ) + )) { int status; /* return code from adapter port control call */ @@ -969,9 +970,9 @@ * returning from this routine. */ -int dfx_driver_init( +__initfunc(int dfx_driver_init( struct device *dev - ) + )) { DFX_board_t *bp = (DFX_board_t *)dev->priv; diff -u --recursive --new-file v2.1.35/linux/drivers/net/depca.c linux/drivers/net/depca.c --- v2.1.35/linux/drivers/net/depca.c Sun Feb 2 05:18:39 1997 +++ linux/drivers/net/depca.c Tue Apr 22 22:42:48 1997 @@ -219,6 +219,7 @@ #include #include #include +#include #include #include #include @@ -418,9 +419,9 @@ void cleanup_module(void); static int autoprobed = 1, loading_module = 1; # else -static u_char de1xx_irq[] = {2,3,4,5,7,9,0}; -static u_char de2xx_irq[] = {5,9,10,11,15,0}; -static u_char de422_irq[] = {5,9,10,11,0}; +static u_char de1xx_irq[] __initdata = {2,3,4,5,7,9,0}; +static u_char de2xx_irq[] __initdata = {5,9,10,11,15,0}; +static u_char de422_irq[] __initdata = {5,9,10,11,0}; static u_char *depca_irq; static int autoprobed = 0, loading_module = 0; #endif /* MODULE */ @@ -441,7 +442,7 @@ -int depca_probe(struct device *dev) +__initfunc(int depca_probe(struct device *dev)) { int tmp = num_depcas, status = -ENODEV; u_long iobase = dev->base_addr; @@ -471,8 +472,8 @@ return status; } -static int -depca_hw_init(struct device *dev, u_long ioaddr) +__initfunc(static int +depca_hw_init(struct device *dev, u_long ioaddr)) { struct depca_private *lp; int i, j, offset, netRAM, mem_len, status=0; @@ -1207,7 +1208,7 @@ /* ** ISA bus I/O device probe */ -static void isa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void isa_probe(struct device *dev, u_long ioaddr)) { int i = num_depcas, maxSlots; s32 ports[] = DEPCA_IO_PORTS; @@ -1245,7 +1246,7 @@ ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. Upto 15 EISA devices are supported. */ -static void eisa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void eisa_probe(struct device *dev, u_long ioaddr)) { int i, maxSlots; u_long iobase; @@ -1291,8 +1292,8 @@ ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * -alloc_device(struct device *dev, u_long iobase) +__initfunc(static struct device * +alloc_device(struct device *dev, u_long iobase)) { struct device *adev = NULL; int fixed = 0, new_dev = 0; @@ -1336,8 +1337,8 @@ ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +__initfunc(static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))) { struct device *new; @@ -1362,8 +1363,8 @@ return dev; } -static int -depca_dev_index(char *s) +__initfunc(static int +depca_dev_index(char *s)) { int i=0, j=0; @@ -1382,7 +1383,7 @@ ** and Boot (readb) ROM. This will also give us a clue to the network RAM ** base address. */ -static void DepcaSignature(char *name, u_long paddr) +__initfunc(static void DepcaSignature(char *name, u_long paddr)) { u_int i,j,k; const char *signatures[] = DEPCA_SIGNATURE; @@ -1434,7 +1435,7 @@ ** PROM address counter is correctly positioned at the start of the ** ethernet address for later read out. */ -static int DevicePresent(u_long ioaddr) +__initfunc(static int DevicePresent(u_long ioaddr)) { union { struct { @@ -1486,7 +1487,7 @@ ** reason: access the upper half of the PROM with x=0; access the lower half ** with x=1. */ -static int get_hw_addr(struct device *dev) +__initfunc(static int get_hw_addr(struct device *dev)) { u_long ioaddr = dev->base_addr; int i, k, tmp, status = 0; @@ -1574,7 +1575,7 @@ /* ** Look for a particular board name in the EISA configuration space */ -static int EISA_signature(char *name, s32 eisa_id) +__initfunc(static int EISA_signature(char *name, s32 eisa_id)) { u_int i; const char *signatures[] = DEPCA_SIGNATURE; diff -u --recursive --new-file v2.1.35/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c --- v2.1.35/linux/drivers/net/dgrs.c Mon Feb 3 03:05:51 1997 +++ linux/drivers/net/dgrs.c Tue Apr 22 22:42:49 1997 @@ -88,6 +88,7 @@ #include #include #include +#include #include #include #include @@ -990,8 +991,8 @@ /* * Download the board firmware */ -static int -dgrs_download(struct device *dev0) +__initfunc(static int +dgrs_download(struct device *dev0)) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; int is; @@ -1149,8 +1150,8 @@ /* * Probe (init) a board */ -int -dgrs_probe1(struct device *dev) +__initfunc(int +dgrs_probe1(struct device *dev)) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1223,8 +1224,8 @@ return (0); } -int -dgrs_initclone(struct device *dev) +__initfunc(int +dgrs_initclone(struct device *dev)) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1238,7 +1239,7 @@ return (0); } -static int +__initfunc(static int dgrs_found_device( struct device *dev, int io, @@ -1246,7 +1247,7 @@ int irq, ulong plxreg, ulong plxdma -) +)) { DGRS_PRIV *priv; int i; @@ -1357,8 +1358,8 @@ /* * Scan for all boards */ -static int -dgrs_scan(struct device *dev) +__initfunc(static int +dgrs_scan(struct device *dev)) { int cards_found = 0; uint io; @@ -1462,7 +1463,7 @@ */ if (EISA_bus) { - static int is2iv[8] = { 0, 3, 5, 7, 10, 11, 12, 15 }; + static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 }; for (io = 0x1000; io < 0x9000; io += 0x1000) { @@ -1600,8 +1601,8 @@ #else -int -dgrs_probe(struct device *dev) +__initfunc(int +dgrs_probe(struct device *dev)) { int cards_found; diff -u --recursive --new-file v2.1.35/linux/drivers/net/dgrs_firmware.c linux/drivers/net/dgrs_firmware.c --- v2.1.35/linux/drivers/net/dgrs_firmware.c Sat Dec 21 07:23:21 1996 +++ linux/drivers/net/dgrs_firmware.c Tue Apr 22 22:42:49 1997 @@ -1,7 +1,7 @@ int dgrs_firmnum = 550; char dgrs_firmver[] = "$Version$"; char dgrs_firmdate[] = "11/16/96 03:45:15"; -unsigned char dgrs_code[] = { +unsigned char dgrs_code[] __initdata = { 213,5,192,8,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,64,40,35,41, diff -u --recursive --new-file v2.1.35/linux/drivers/net/dlci.c linux/drivers/net/dlci.c --- v2.1.35/linux/drivers/net/dlci.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/net/dlci.c Tue Apr 22 22:42:49 1997 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -606,7 +607,7 @@ return(0); } -int dlci_setup(void) +__initfunc(int dlci_setup(void)) { int i; diff -u --recursive --new-file v2.1.35/linux/drivers/net/dummy.c linux/drivers/net/dummy.c --- v2.1.35/linux/drivers/net/dummy.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/dummy.c Tue Apr 22 22:42:49 1997 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +73,7 @@ { } -int dummy_init(struct device *dev) +__initfunc(int dummy_init(struct device *dev)) { /* Initialize the device structure. */ dev->hard_start_xmit = dummy_xmit; @@ -115,7 +116,7 @@ #ifdef MODULE -static int dummy_probe(struct device *dev) +__initfunc(static int dummy_probe(struct device *dev)) { dummy_init(dev); return 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/e2100.c linux/drivers/net/e2100.c --- v2.1.35/linux/drivers/net/e2100.c Tue Dec 31 00:30:01 1996 +++ linux/drivers/net/e2100.c Tue Apr 22 22:42:49 1997 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -115,7 +116,7 @@ station address). */ -int e2100_probe(struct device *dev) +__initfunc(int e2100_probe(struct device *dev)) { int *port; int base_addr = dev->base_addr; @@ -135,7 +136,7 @@ return ENODEV; } -int e21_probe1(struct device *dev, int ioaddr) +__initfunc(int e21_probe1(struct device *dev, int ioaddr)) { int i, status; unsigned char *station_addr = dev->dev_addr; diff -u --recursive --new-file v2.1.35/linux/drivers/net/eepro.c linux/drivers/net/eepro.c --- v2.1.35/linux/drivers/net/eepro.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/eepro.c Tue Apr 22 22:42:49 1997 @@ -101,6 +101,7 @@ #include #include #include +#include #include #include @@ -109,7 +110,7 @@ /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int eepro_portlist[] = +static unsigned int eepro_portlist[] __initdata = { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0x360, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -305,8 +306,8 @@ struct netdev_entry netcard_drv = {"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist}; #else -int -eepro_probe(struct device *dev) +__initfunc(int +eepro_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -332,7 +333,7 @@ probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -int eepro_probe1(struct device *dev, short ioaddr) +__initfunc(int eepro_probe1(struct device *dev, short ioaddr)) { unsigned short station_addr[6], id, counter; int i; diff -u --recursive --new-file v2.1.35/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c --- v2.1.35/linux/drivers/net/eepro100.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/eepro100.c Tue Apr 22 22:42:49 1997 @@ -55,6 +55,7 @@ #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include @@ -458,7 +459,7 @@ static struct device *root_speedo_dev = NULL; #endif -int eepro100_init(struct device *dev) +__initfunc(int eepro100_init(struct device *dev)) { int cards_found = 0; @@ -521,7 +522,7 @@ return cards_found; } -static void speedo_found1(struct device *dev, int ioaddr, int irq, int options) +__initfunc(static void speedo_found1(struct device *dev, int ioaddr, int irq, int options)) { static int did_version = 0; /* Already printed version info. */ struct speedo_private *sp; @@ -714,7 +715,7 @@ #define EE_READ_CMD (6 << 6) #define EE_ERASE_CMD (7 << 6) -static int read_eeprom(int ioaddr, int location) +__initfunc(static int read_eeprom(int ioaddr, int location)) { int i; unsigned short retval = 0; @@ -1710,7 +1711,7 @@ } } #else /* not MODULE */ -int eepro100_probe(struct device *dev) +__initfunc(int eepro100_probe(struct device *dev)) { int cards_found = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c --- v2.1.35/linux/drivers/net/eexpress.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/eexpress.c Thu Apr 17 09:29:32 1997 @@ -4,6 +4,8 @@ * based on original code by Donald Becker, with changes by * Alan Cox and Pauline Middelink. * + * Support for 8-bit mode by Zoltan Szilagyi + * * Many modifications, and currently maintained, by * Philip Blundell */ @@ -16,12 +18,6 @@ * things seem to be getting better slowly. */ -/* It would be nice to seperate out all the 82586-specific code, so that it - * could be shared between drivers (as with 8390.c). But this would be quite - * a messy job. The main motivation for doing this would be to bring 3c507 - * support back up to scratch. - */ - /* If your card is confused about what sort of interface it has (eg it * persistently reports "10baseT" when none is fitted), running 'SOFTSET /BART' * or 'SOFTSET /LISA' from DOS seems to help. @@ -60,13 +56,28 @@ /* Known bugs: * - * - 8-bit mode is not supported, and makes things go wrong. - * - Multicast and promiscuous modes are not supported. * - The card seems to want to give us two interrupts every time something * happens, where just one would be better. - * - The statistics may not be getting reported properly. */ +/* + * + * Note by Zoltan Szilagyi 10-12-96: + * + * I've succeeded in eliminating the "CU wedged" messages, and hence the + * lockups, which were only occuring with cards running in 8-bit mode ("force + * 8-bit operation" in Intel's SoftSet utility). This version of the driver + * sets the 82586 and the ASIC to 8-bit mode at startup; it also stops the + * CU before submitting a packet for transmission, and then restarts it as soon + * as the process of handing the packet is complete. This is definitely an + * unnecessary slowdown if the card is running in 16-bit mode; therefore one + * should detect 16-bit vs 8-bit mode from the EEPROM settings and act + * accordingly. In 8-bit mode with this bugfix I'm getting about 150 K/s for + * ftp's, which is significantly better than I get in DOS, so the overhead of + * stopping and restarting the CU with each transmit is not prohibitive in + * practice. + */ + #include #include @@ -104,9 +115,11 @@ struct net_local { struct net_device_stats stats; + unsigned long last_tx; /* jiffies when last transmit started */ unsigned long init_time; /* jiffies when eexp_hw_init586 called */ unsigned short rx_first; /* first rx buf, same as RX_BUF_START */ unsigned short rx_last; /* last rx buf */ + unsigned short rx_ptr; /* first rx buf to look at */ unsigned short tx_head; /* next free tx buf */ unsigned short tx_reap; /* first in-use tx buf */ unsigned short tx_tail; /* previous tx buf to tx_head */ @@ -114,11 +127,13 @@ unsigned short last_tx_restart; /* set to tx_link when we restart the CU */ unsigned char started; - unsigned char promisc; unsigned short rx_buf_start; unsigned short rx_buf_end; unsigned short num_tx_bufs; unsigned short num_rx_bufs; + unsigned char width; /* 0 for 16bit, 1 for 8bit */ + unsigned char was_promisc; + unsigned char old_mc_count; }; /* This is the code and data that is downloaded to the EtherExpress card's @@ -126,11 +141,6 @@ */ static unsigned short start_code[] = { -/* 0xfff6 */ - 0x0000, /* set bus to 16 bits */ - 0x0000,0x0000, - 0x0000,0x0000, /* address of ISCP (lo,hi) */ - /* 0x0000 */ 0x0001, /* ISCP: busy - cleared after reset */ 0x0008,0x0000,0x0000, /* offset,address (lo,hi) of SCB */ @@ -144,9 +154,9 @@ 0x0000,0x0000, /* pad */ 0x0000,0x0000, -/* 0x0020 -- start of 82586 CU program */ -#define CONF_LINK 0x0020 - 0x0000,Cmd_Config, +/* 0x20 -- start of 82586 CU program */ +#define CONF_LINK 0x20 + 0x0000,Cmd_Config, 0x0032, /* link to next command */ 0x080c, /* 12 bytes follow : fifo threshold=8 */ 0x2e40, /* don't rx bad frames @@ -156,27 +166,43 @@ */ 0x6000, /* default backoff method & priority * interframe spacing = 0x60 */ - 0xf200, /* slot time=0x200 + 0xf200, /* slot time=0x200 * max collision retry = 0xf */ - 0x0000, /* no HDLC : normal CRC : enable broadcast +#define CONF_PROMISC 0x2e + 0x0000, /* no HDLC : normal CRC : enable broadcast * disable promiscuous/multicast modes */ 0x003c, /* minimum frame length = 60 octets) */ - 0x0000,Cmd_INT|Cmd_SetAddr, + 0x0000,Cmd_SetAddr, 0x003e, /* link to next command */ +#define CONF_HWADDR 0x38 0x0000,0x0000,0x0000, /* hardware address placed here */ - 0x0000,Cmd_TDR,0x0048, -/* 0x0044 -- TDR result placed here */ - 0x0000, 0x0000, - -/* Eventually, a set-multicast will go in here */ + 0x0000,Cmd_MCast, + 0x0076, /* link to next command */ +#define CONF_NR_MULTICAST 0x44 + 0x0000, /* number of multicast addresses */ +#define CONF_MULTICAST 0x46 + 0x0000, 0x0000, 0x0000, /* some addresses */ + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + +#define CONF_DIAG_RESULT 0x76 + 0x0000, Cmd_Diag, + 0x007c, /* link to next command */ + + 0x0000,Cmd_TDR|Cmd_INT, + 0x0084, +#define CONF_TDR_RESULT 0x82 + 0x0000, 0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */ - 0x0048, - - 0x0000 - + 0x0084 /* dummy link */ }; /* maps irq number to EtherExpress magic value */ @@ -213,6 +239,13 @@ static void eexp_hw_rxinit (struct device *dev); static void eexp_hw_init586 (struct device *dev); +static void eexp_setup_filter (struct device *dev); + +static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"}; +enum eexp_iftype {AUI=0, BNC=1, TPE=2}; + +#define STARTED_RU 2 +#define STARTED_CU 1 /* * Primitive hardware access functions. @@ -270,7 +303,8 @@ int express_probe(struct device *dev) { - unsigned short *port,ports[] = { 0x0300,0x0270,0x0320,0x0340,0 }; + unsigned short *port; + static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 }; unsigned short ioaddr = dev->base_addr; if (ioaddr&0xfe00) @@ -302,6 +336,7 @@ { int irq = dev->irq; unsigned short ioaddr = dev->base_addr; + struct net_local *lp = (struct net_local *)dev->priv; #if NET_DEBUG > 6 printk(KERN_DEBUG "%s: eexp_open()\n", dev->name); @@ -316,8 +351,16 @@ return -EAGAIN; request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"); + request_region(ioaddr+0x4000, 16, "EtherExpress shadow"); + request_region(ioaddr+0x8000, 16, "EtherExpress shadow"); + request_region(ioaddr+0xc000, 16, "EtherExpress shadow"); dev->tbusy = 0; dev->interrupt = 0; + + if (lp->width) { + printk("%s: forcing ASIC to 8-bit mode\n", dev->name); + outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config); + } eexp_hw_init586(dev); dev->start = 1; @@ -331,6 +374,7 @@ /* * close and disable the interface, leaving the 586 in reset. */ + static int eexp_close(struct device *dev) { unsigned short ioaddr = dev->base_addr; @@ -464,9 +508,23 @@ /* If dev->tbusy is set, all our tx buffers are full but the kernel * is calling us anyway. Check that nothing bad is happening. */ - if (dev->tbusy) - unstick_cu(dev); - + if (dev->tbusy) { + int status = scb_status(dev); + unstick_cu(dev); + if ((jiffies - lp->last_tx) < HZ) + return 1; + printk(KERN_INFO "%s: transmit timed out, %s?", dev->name, + (SCB_complete(status)?"lost interrupt": + "board on fire")); + lp->stats.tx_errors++; + dev->tbusy = 0; + lp->last_tx = jiffies; + if (!SCB_complete(status)) { + scb_command(dev, SCB_CUabort); + outb(0,dev->base_addr+SIGNAL_CA); + } + } + if (set_bit(0,(void *)&dev->tbusy)) { lp->stats.tx_dropped++; @@ -477,6 +535,8 @@ ETH_ZLEN; unsigned short *data = (unsigned short *)buf->data; + lp->stats.tx_bytes += length; + eexp_hw_tx_pio(dev,data,length); } dev_kfree_skb(buf, FREE_WRITE); @@ -491,11 +551,86 @@ * check to make sure we've not become wedged. */ +/* + * Handle an EtherExpress interrupt + * If we've finished initializing, start the RU and CU up. + * If we've already started, reap tx buffers, handle any received packets, + * check to make sure we've not become wedged. + */ + +static unsigned short eexp_start_irq(struct device *dev, + unsigned short status) +{ + unsigned short ack_cmd = SCB_ack(status); + struct net_local *lp = (struct net_local *)dev->priv; + unsigned short ioaddr = dev->base_addr; + if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) { + short diag_status, tdr_status; + while (SCB_CUstat(status)==2) + status = scb_status(dev); +#if NET_DEBUG > 4 + printk("%s: CU went non-active (status %04x)\n", + dev->name, status); +#endif + + outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR); + diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT)); + if (diag_status & 1<<11) { + printk(KERN_WARNING "%s: 82586 failed self-test\n", + dev->name); + } else if (!(diag_status & 1<<13)) { + printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name); + } + + outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR); + tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT)); + if (tdr_status & (TDR_SHORT|TDR_OPEN)) { + printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : ""); + } + else if (tdr_status & TDR_XCVRPROBLEM) { + printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name); + } + else if (tdr_status & TDR_LINKOK) { +#if NET_DEBUG > 4 + printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name); +#endif + } else { + printk("%s: TDR is ga-ga (status %04x)\n", dev->name, + tdr_status); + } + + lp->started |= STARTED_CU; + scb_wrcbl(dev, lp->tx_link); + /* if the RU isn't running, start it now */ + if (!(lp->started & STARTED_RU)) { + ack_cmd |= SCB_RUstart; + scb_wrrfa(dev, lp->rx_buf_start); + lp->rx_ptr = lp->rx_buf_start; + } + ack_cmd |= SCB_CUstart | 0x2000; + } + + if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4) + lp->started|=STARTED_RU; + + return ack_cmd; +} + +static void eexp_cmd_clear(struct device *dev) +{ + unsigned long int oldtime = jiffies; + while (scb_rdcmd(dev) && ((jiffies-oldtime)<10)); + if (scb_rdcmd(dev)) { + printk("%s: command didn't clear\n", dev->name); + } +} + static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs) { struct device *dev = irq2dev_map[irq]; struct net_local *lp; unsigned short ioaddr,status,ack_cmd; + unsigned short old_read_ptr, old_write_ptr; if (dev==NULL) { @@ -507,6 +642,9 @@ lp = (struct net_local *)dev->priv; ioaddr = dev->base_addr; + old_read_ptr = inw(ioaddr+READ_PTR); + old_write_ptr = inw(ioaddr+WRITE_PTR); + outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ); dev->interrupt = 1; @@ -517,75 +655,73 @@ printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status); #endif - ack_cmd = SCB_ack(status); + if (lp->started == (STARTED_CU | STARTED_RU)) { - if (lp->started==0 && SCB_complete(status)) - { - while (SCB_CUstat(status)==2) - status = scb_status(dev); -#if NET_DEBUG > 4 - printk(KERN_DEBUG "%s: CU went non-active (status = %08x)\n", - dev->name, status); -#endif + do { + eexp_cmd_clear(dev); - /* now get the TDR status */ - { - short tdr_status; - outw(0x40, dev->base_addr + SM_PTR); - tdr_status = inw(dev->base_addr + 0x8004); - if (tdr_status & TDR_SHORT) { - printk(KERN_WARNING "%s: TDR reports cable short at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : ""); - } - else if (tdr_status & TDR_OPEN) { - printk(KERN_WARNING "%s: TDR reports cable broken at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : ""); - } - else if (tdr_status & TDR_XCVRPROBLEM) { - printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name); - } -#if NET_DEBUG > 4 - else if (tdr_status & TDR_LINKOK) { - printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name); - } -#endif - } + ack_cmd = SCB_ack(status); + scb_command(dev, ack_cmd); + outb(0,ioaddr+SIGNAL_CA); - lp->started=1; - scb_wrcbl(dev, lp->tx_link); - scb_wrrfa(dev, lp->rx_buf_start); - ack_cmd |= SCB_CUstart | SCB_RUstart | 0x2000; - } - else if (lp->started) - { - unsigned short txstatus; - txstatus = eexp_hw_lasttxstat(dev); - } + eexp_cmd_clear(dev); - if (SCB_rxdframe(status)) - { - eexp_hw_rx_pio(dev); - } + if (SCB_complete(status)) { + if (!eexp_hw_lasttxstat(dev)) { + printk("%s: tx interrupt but no status\n", dev->name); + } + } + + if (SCB_rxdframe(status)) + eexp_hw_rx_pio(dev); - if ((lp->started&2)!=0 && SCB_RUstat(status)!=4) - { - printk(KERN_WARNING "%s: RU stopped: status %04x\n", - dev->name,status); - lp->stats.rx_errors++; - eexp_hw_rxinit(dev); - scb_wrrfa(dev, lp->rx_buf_start); - ack_cmd |= SCB_RUstart; + status = scb_status(dev); + } while (status & 0xc000); + + if (SCB_RUdead(status)) + { + printk(KERN_WARNING "%s: RU stopped: status %04x\n", + dev->name,status); +#if 0 + printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd); + outw(lp->cur_rfd, ioaddr+READ_PTR); + printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT)); + outw(lp->cur_rfd+6, ioaddr+READ_PTR); + printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT)); + outw(rbd, ioaddr+READ_PTR); + printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT)); + outw(rbd+8, ioaddr+READ_PTR); + printk("[%04x]\n", inw(ioaddr+DATAPORT)); +#endif + lp->stats.rx_errors++; +#if 1 + eexp_hw_rxinit(dev); +#else + lp->cur_rfd = lp->first_rfd; +#endif + scb_wrrfa(dev, lp->rx_buf_start); + scb_command(dev, SCB_RUstart); + outb(0,ioaddr+SIGNAL_CA); + } + } else { + if (status & 0x8000) + ack_cmd = eexp_start_irq(dev, status); + else + ack_cmd = SCB_ack(status); + scb_command(dev, ack_cmd); + outb(0,ioaddr+SIGNAL_CA); } - else if (lp->started==1 && SCB_RUstat(status)==4) - lp->started|=2; - scb_command(dev, ack_cmd); - outb(0,ioaddr+SIGNAL_CA); + eexp_cmd_clear(dev); - outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); + outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); dev->interrupt = 0; -#if NET_DEBUG > 6 - printk(KERN_DEBUG "%s: leaving eexp_irq()\n", dev->name); +#if NET_DEBUG > 6 + printk("%s: leaving eexp_irq()\n", dev->name); #endif + outw(old_read_ptr, ioaddr+READ_PTR); + outw(old_write_ptr, ioaddr+WRITE_PTR); return; } @@ -594,6 +730,25 @@ */ /* + * Set the cable type to use. + */ + +static void eexp_hw_set_interface(struct device *dev) +{ + unsigned char oldval = inb(dev->base_addr + 0x300e); + oldval &= ~0x82; + switch (dev->if_port) { + case TPE: + oldval |= 0x2; + case BNC: + oldval |= 0x80; + break; + } + outb(oldval, dev->base_addr+0x300e); + udelay(20000); +} + +/* * Check all the receive buffers, and hand any received packets * to the upper levels. Basic sanity check on each frame * descriptor, though we don't bother trying to fix broken ones. @@ -602,41 +757,49 @@ static void eexp_hw_rx_pio(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; - unsigned short rx_block = lp->rx_first; + unsigned short rx_block = lp->rx_ptr; unsigned short boguscount = lp->num_rx_bufs; unsigned short ioaddr = dev->base_addr; + unsigned short status; #if NET_DEBUG > 6 printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name); #endif - while (boguscount--) - { - unsigned short status, rfd_cmd, rx_next, pbuf, pkt_len; - + do { + unsigned short rfd_cmd, rx_next, pbuf, pkt_len; + outw(rx_block, ioaddr + READ_PTR); status = inw(ioaddr + DATAPORT); - rfd_cmd = inw(ioaddr + DATAPORT); - rx_next = inw(ioaddr + DATAPORT); - pbuf = inw(ioaddr + DATAPORT); if (FD_Done(status)) { + rfd_cmd = inw(ioaddr + DATAPORT); + rx_next = inw(ioaddr + DATAPORT); + pbuf = inw(ioaddr + DATAPORT); + outw(pbuf, ioaddr + READ_PTR); pkt_len = inw(ioaddr + DATAPORT); - if (rfd_cmd!=0x0000 || pbuf!=rx_block+0x16 - || (pkt_len & 0xc000)!=0xc000) + if (rfd_cmd!=0x0000) + { + printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n", + dev->name, rfd_cmd); + continue; + } + else if (pbuf!=rx_block+0x16) { - /* This should never happen. If it does, - * we almost certainly have a driver bug. - */ - printk(KERN_WARNING "%s: Rx frame at %04x corrupted, status %04x, cmd %04x, " - "next %04x, pbuf %04x, len %04x\n",dev->name,rx_block, - status,rfd_cmd,rx_next,pbuf,pkt_len); + printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n", + dev->name, rx_block+0x16, pbuf); continue; } - else if (!FD_OK(status)) + else if ((pkt_len & 0xc000)!=0xc000) + { + printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n", + dev->name, pkt_len & 0xc000); + continue; + } + else if (!FD_OK(status)) { lp->stats.rx_errors++; if (FD_CRC(status)) @@ -668,13 +831,15 @@ skb->protocol = eth_type_trans(skb,dev); netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes += pkt_len; } outw(rx_block, ioaddr+WRITE_PTR); outw(0, ioaddr+DATAPORT); outw(0, ioaddr+DATAPORT); + rx_block = rx_next; } - rx_block = rx_next; - } + } while (FD_Done(status) && boguscount--); + lp->rx_ptr = rx_block; } /* @@ -690,7 +855,17 @@ struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; - outw(lp->tx_head, ioaddr + WRITE_PTR); + if (lp->width) { + /* Stop the CU so that there is no chance that it + jumps off to a bogus address while we are writing the + pointer to the next transmit packet in 8-bit mode -- + this eliminates the "CU wedged" errors in 8-bit mode. + (Zoltan Szilagyi 10-12-96) */ + scb_command(dev, SCB_CUsuspend); + outw(0xFFFF, ioaddr+SIGNAL_CA); + } + + outw(lp->tx_head, ioaddr + WRITE_PTR); outw(0x0000, ioaddr + DATAPORT); outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT); @@ -719,6 +894,16 @@ lp->tx_head += TX_BUF_SIZE; if (lp->tx_head != lp->tx_reap) dev->tbusy = 0; + + if (lp->width) { + /* Restart the CU so that the packet can actually + be transmitted. (Zoltan Szilagyi 10-12-96) */ + scb_command(dev, SCB_CUresume); + outw(0xFFFF, ioaddr+SIGNAL_CA); + } + + lp->stats.tx_packets++; + lp->last_tx = jiffies; } /* @@ -731,14 +916,13 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr) { unsigned short hw_addr[3]; + unsigned char buswidth; unsigned int memory_size; - static char *ifmap[]={"AUI", "BNC", "RJ45"}; - enum iftype {AUI=0, BNC=1, TP=2}; int i; unsigned short xsum = 0; struct net_local *lp; - printk("%s: EtherExpress 16 at %#x",dev->name,ioaddr); + printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr); outb(ASIC_RST, ioaddr+EEPROM_Ctrl); outb(0, ioaddr+EEPROM_Ctrl); @@ -769,7 +953,7 @@ dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i]; { - char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0}; + static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0}; unsigned short setupval = eexp_hw_readeeprom(ioaddr,0); /* Use the IRQ from EEPROM if none was given */ @@ -777,7 +961,9 @@ dev->irq = irqmap[setupval>>13]; dev->if_port = !(setupval & 0x1000) ? AUI : - eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TP : BNC; + eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC; + + buswidth = !((setupval & 0x400) >> 10); } dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL); @@ -786,8 +972,11 @@ memset(dev->priv, 0, sizeof(struct net_local)); - printk("; using IRQ %d, %s connector", dev->irq,ifmap[dev->if_port]); - + printk("(IRQ %d, %s connector, %d-bit bus", dev->irq, + eexp_ifmap[dev->if_port], buswidth?8:16); + + eexp_hw_set_interface(dev); + /* Find out how much RAM we have on the card */ outw(0, dev->base_addr + WRITE_PTR); for (i = 0; i < 32768; i++) @@ -795,10 +984,10 @@ for (memory_size = 0; memory_size < 64; memory_size++) { - outw(memory_size<<10, dev->base_addr + WRITE_PTR); outw(memory_size<<10, dev->base_addr + READ_PTR); if (inw(dev->base_addr+DATAPORT)) break; + outw(memory_size<<10, dev->base_addr + WRITE_PTR); outw(memory_size | 0x5000, dev->base_addr+DATAPORT); outw(memory_size<<10, dev->base_addr + READ_PTR); if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000)) @@ -820,16 +1009,17 @@ case 32: lp->rx_buf_end += 0x4000; case 16: - printk(", %dk RAM.\n", memory_size); + printk(", %dk RAM)\n", memory_size); break; default: - printk("; bad memory size (%dk).\n", memory_size); + printk(") bad memory size (%dk).\n", memory_size); kfree(dev->priv); return ENODEV; break; } lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE); + lp->width = buswidth; dev->open = eexp_open; dev->stop = eexp_close; @@ -905,8 +1095,8 @@ do { - outw(tx_block, dev->base_addr + SM_PTR); - status = inw(SHADOW(tx_block)); + outw(tx_block & ~31, dev->base_addr + SM_PTR); + status = inw(dev->base_addr + SHADOW(tx_block)); if (!Stat_Done(status)) { lp->tx_link = tx_block; @@ -918,12 +1108,29 @@ lp->stats.collisions += Stat_NoColl(status); if (!Stat_OK(status)) { - if (Stat_Abort(status)) - lp->stats.tx_aborted_errors++; - if (Stat_TNoCar(status) || Stat_TNoCTS(status)) + char *whatsup = NULL; + lp->stats.tx_errors++; + if (Stat_Abort(status)) + lp->stats.tx_aborted_errors++; + if (Stat_TNoCar(status)) { + whatsup = "aborted, no carrier"; lp->stats.tx_carrier_errors++; - if (Stat_TNoDMA(status)) - lp->stats.tx_fifo_errors++; + } + if (Stat_TNoCTS(status)) { + whatsup = "aborted, lost CTS"; + lp->stats.tx_carrier_errors++; + } + if (Stat_TNoDMA(status)) { + whatsup = "FIFO underran"; + lp->stats.tx_fifo_errors++; + } + if (Stat_TXColl(status)) { + whatsup = "aborted, too many collisions"; + lp->stats.tx_aborted_errors++; + } + if (whatsup) + printk(KERN_INFO "%s: transmit %s\n", + dev->name, whatsup); } else lp->stats.tx_packets++; @@ -1043,7 +1250,7 @@ unsigned short ioaddr = dev->base_addr; lp->num_rx_bufs = 0; - lp->rx_first = rx_block; + lp->rx_first = lp->rx_ptr = rx_block; do { lp->num_rx_bufs++; @@ -1052,9 +1259,9 @@ outw(0, ioaddr + DATAPORT); outw(0, ioaddr+DATAPORT); outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT); - outw(rx_block + 0x16, ioaddr+DATAPORT); + outw(0xffff, ioaddr+DATAPORT); - outw(0xdead, ioaddr+DATAPORT); + outw(0x0000, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); @@ -1062,19 +1269,30 @@ outw(0xdead, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); - outw(0x8000, ioaddr+DATAPORT); - outw(0xffff, ioaddr+DATAPORT); + outw(0x0000, ioaddr+DATAPORT); + outw(rx_block + RX_BUF_SIZE + 0x16, ioaddr+DATAPORT); outw(rx_block + 0x20, ioaddr+DATAPORT); outw(0, ioaddr+DATAPORT); - outw(0x8000 | (RX_BUF_SIZE-0x20), ioaddr+DATAPORT); + outw(RX_BUF_SIZE-0x20, ioaddr+DATAPORT); lp->rx_last = rx_block; rx_block += RX_BUF_SIZE; } while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE); - outw(lp->rx_last + 4, ioaddr+WRITE_PTR); - outw(lp->rx_first, ioaddr+DATAPORT); + /* Make first Rx frame descriptor point to first Rx buffer + descriptor */ + outw(lp->rx_first + 6, ioaddr+WRITE_PTR); + outw(lp->rx_first + 0x16, ioaddr+DATAPORT); + + /* Close Rx frame descriptor ring */ + outw(lp->rx_last + 4, ioaddr+WRITE_PTR); + outw(lp->rx_first, ioaddr+DATAPORT); + + /* Close Rx buffer descriptor ring */ + outw(lp->rx_last + 0x16 + 2, ioaddr+WRITE_PTR); + outw(lp->rx_first + 0x16, ioaddr+DATAPORT); + } /* @@ -1083,6 +1301,7 @@ * us. We can't start the receive/transmission system up before we know that * the hardware is configured correctly. */ + static void eexp_hw_init586(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -1097,24 +1316,19 @@ set_loopback(dev); - /* Bash the startup code a bit */ - start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1): - (start_code[28] & ~1); - lp->promisc = dev->flags & IFF_PROMISC; - memcpy(&start_code[33], &dev->dev_addr[0], 6); - outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ); /* Download the startup code */ outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR); - outw(start_code[0], ioaddr + 0x8006); - outw(start_code[1], ioaddr + 0x8008); - outw(start_code[2], ioaddr + 0x800a); - outw(start_code[3], ioaddr + 0x800c); - outw(start_code[4], ioaddr + 0x800e); - for (i = 10; i < (sizeof(start_code)); i+=32) { + outw(lp->width?0x0001:0x0000, ioaddr + 0x8006); + outw(0x0000, ioaddr + 0x8008); + outw(0x0000, ioaddr + 0x800a); + outw(0x0000, ioaddr + 0x800c); + outw(0x0000, ioaddr + 0x800e); + + for (i = 0; i < (sizeof(start_code)); i+=32) { int j; - outw(i-10, ioaddr + SM_PTR); + outw(i, ioaddr + SM_PTR); for (j = 0; j < 16; j+=2) outw(start_code[(i+j)/2], ioaddr+0x4000+j); @@ -1123,6 +1337,24 @@ ioaddr+0x8000+j); } + /* Do we want promiscuous mode or multicast? */ + outw(CONF_PROMISC & ~31, ioaddr+SM_PTR); + i = inw(ioaddr+SHADOW(CONF_PROMISC)); + outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1), + ioaddr+SHADOW(CONF_PROMISC)); + lp->was_promisc = dev->flags & IFF_PROMISC; +#if 0 + eexp_setup_filter(dev); +#endif + + /* Write our hardware address */ + outw(CONF_HWADDR & ~31, ioaddr+SM_PTR); + outw(((unsigned short *)dev->dev_addr)[0], ioaddr+SHADOW(CONF_HWADDR)); + outw(((unsigned short *)dev->dev_addr)[1], + ioaddr+SHADOW(CONF_HWADDR+2)); + outw(((unsigned short *)dev->dev_addr)[2], + ioaddr+SHADOW(CONF_HWADDR+4)); + eexp_hw_txinit(dev); eexp_hw_rxinit(dev); @@ -1193,6 +1425,38 @@ return; } +static void eexp_setup_filter(struct device *dev) +{ + struct dev_mc_list *dmi = dev->mc_list; + unsigned short ioaddr = dev->base_addr; + int count = dev->mc_count; + int i; + if (count > 8) { + printk(KERN_INFO "%s: too many multicast addresses (%d)\n", + dev->name, count); + count = 8; + } + + outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR); + outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST)); + for (i = 0; i < count; i++) { + unsigned short *data = (unsigned short *)dmi->dmi_addr; + if (!dmi) { + printk(KERN_INFO "%s: too few multicast addresses\n", dev->name); + break; + } + if (dmi->dmi_addrlen != ETH_ALEN) { + printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name); + continue; + } + outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR); + outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i))); + outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR); + outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2)); + outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR); + outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4)); + } +} /* * Set or clear the multicast filter for this adaptor. @@ -1200,12 +1464,49 @@ static void eexp_set_multicast(struct device *dev) { + unsigned short ioaddr = dev->base_addr; + struct net_local *lp = (struct net_local *)dev->priv; + int kick = 0, i; + if ((dev->flags & IFF_PROMISC) != lp->was_promisc) { + outw(CONF_PROMISC & ~31, ioaddr+SM_PTR); + i = inw(ioaddr+SHADOW(CONF_PROMISC)); + outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1), + ioaddr+SHADOW(CONF_PROMISC)); + lp->was_promisc = dev->flags & IFF_PROMISC; + kick = 1; + } + if (!(dev->flags & IFF_PROMISC)) { + eexp_setup_filter(dev); + if (lp->old_mc_count != dev->mc_count) { + kick = 1; + lp->old_mc_count = dev->mc_count; + } + } + if (kick) { + unsigned long oj; + scb_command(dev, SCB_CUsuspend); + outb(0, ioaddr+SIGNAL_CA); + outb(0, ioaddr+SIGNAL_CA); +#if 0 + printk("%s: waiting for CU to go suspended\n", dev->name); +#endif + oj = jiffies; + while ((SCB_CUstat(scb_status(dev)) == 2) && + ((jiffies-oj) < 100)); + if (SCB_CUstat(scb_status(dev)) == 2) + printk("%s: warning, CU didn't stop\n", dev->name); + lp->started &= ~(STARTED_CU); + scb_wrcbl(dev, CONF_LINK); + scb_command(dev, SCB_CUstart); + outb(0, ioaddr+SIGNAL_CA); + } } /* * MODULE stuff */ + #ifdef MODULE #define EEXP_MAX_CARDS 4 /* max number of cards to support */ diff -u --recursive --new-file v2.1.35/linux/drivers/net/eql.c linux/drivers/net/eql.c --- v2.1.35/linux/drivers/net/eql.c Sun Feb 2 05:18:39 1997 +++ linux/drivers/net/eql.c Tue Apr 22 22:42:49 1997 @@ -130,6 +130,7 @@ #include #include #include +#include #include #include @@ -208,7 +209,7 @@ --------------------------------------------------------- */ -int eql_init(struct device *dev) +__initfunc(int eql_init(struct device *dev)) { static unsigned version_printed = 0; /* static unsigned num_masters = 0; */ diff -u --recursive --new-file v2.1.35/linux/drivers/net/es3210.c linux/drivers/net/es3210.c --- v2.1.35/linux/drivers/net/es3210.c Tue Dec 31 00:30:01 1996 +++ linux/drivers/net/es3210.c Tue Apr 22 22:42:49 1997 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -114,8 +115,8 @@ #define ES_DEBUG 0 -static unsigned char lo_irq_map[] = {3, 4, 5, 6, 7, 9, 10}; -static unsigned char hi_irq_map[] = {11, 12, 0, 14, 0, 0, 0, 15}; +static unsigned char lo_irq_map[] __initdata = {3, 4, 5, 6, 7, 9, 10}; +static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15}; /* * Probe for the card. The best way is to read the EISA ID if it @@ -123,7 +124,7 @@ * PROM for a match against the Racal-Interlan assigned value. */ -int es_probe(struct device *dev) +__initfunc(int es_probe(struct device *dev)) { unsigned short ioaddr = dev->base_addr; @@ -150,7 +151,7 @@ return ENODEV; } -int es_probe1(struct device *dev, int ioaddr) +__initfunc(int es_probe1(struct device *dev, int ioaddr)) { int i; unsigned long eisa_id; diff -u --recursive --new-file v2.1.35/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c --- v2.1.35/linux/drivers/net/eth16i.c Sun Feb 2 05:18:39 1997 +++ linux/drivers/net/eth16i.c Tue Apr 22 22:42:49 1997 @@ -87,6 +87,7 @@ #include #include #include +#include #include #include @@ -275,22 +276,22 @@ #define RESET ID_ROM_0 /* This is the I/O address list to be probed when seeking the card */ -static unsigned int eth16i_portlist[] = { +static unsigned int eth16i_portlist[] __initdata = { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 }; -static unsigned int eth32i_portlist[] = { +static unsigned int eth32i_portlist[] __initdata = { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 }; /* This is the Interrupt lookup table for Eth16i card */ -static unsigned int eth16i_irqmap[] = { +static unsigned int eth16i_irqmap[] __initdata = { 9, 10, 5, 15 }; /* This is the Interrupt lookup table for Eth32i card */ -static unsigned int eth32i_irqmap[] = { +static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15 }; @@ -350,7 +351,7 @@ {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; #else /* Not HAVE_DEVLIST */ -int eth16i_probe(struct device *dev) +__initfunc(int eth16i_probe(struct device *dev)) { int i; int ioaddr; @@ -384,7 +385,7 @@ } #endif /* Not HAVE_DEVLIST */ -static int eth16i_probe1(struct device *dev, short ioaddr) +__initfunc(static int eth16i_probe1(struct device *dev, short ioaddr)) { static unsigned version_printed = 0; unsigned int irq = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c --- v2.1.35/linux/drivers/net/ewrk3.c Sun Feb 2 05:18:40 1997 +++ linux/drivers/net/ewrk3.c Tue Apr 22 22:42:49 1997 @@ -149,6 +149,7 @@ #include #include #include +#include #include #include #include @@ -344,7 +345,7 @@ -int ewrk3_probe(struct device *dev) +__initfunc(int ewrk3_probe(struct device *dev)) { int tmp = num_ewrk3s, status = -ENODEV; u_long iobase = dev->base_addr; @@ -375,8 +376,8 @@ return status; } -static int -ewrk3_hw_init(struct device *dev, u_long iobase) +__initfunc(static int +ewrk3_hw_init(struct device *dev, u_long iobase)) { struct ewrk3_private *lp; int i, status=0; @@ -1289,7 +1290,7 @@ /* ** ISA bus I/O device probe */ -static void isa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void isa_probe(struct device *dev, u_long ioaddr)) { int i = num_ewrk3s, maxSlots; u_long iobase; @@ -1327,7 +1328,7 @@ ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. */ -static void eisa_probe(struct device *dev, u_long ioaddr) +__initfunc(static void eisa_probe(struct device *dev, u_long ioaddr)) { int i, maxSlots; u_long iobase; @@ -1372,8 +1373,8 @@ ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * -alloc_device(struct device *dev, u_long iobase) +__initfunc(static struct device * +alloc_device(struct device *dev, u_long iobase)) { struct device *adev = NULL; int fixed = 0, new_dev = 0; @@ -1417,8 +1418,8 @@ ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +__initfunc(static struct device * +insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))) { struct device *new; @@ -1443,8 +1444,8 @@ return dev; } -static int -ewrk3_dev_index(char *s) +__initfunc(static int +ewrk3_dev_index(char *s)) { int i=0, j=0; @@ -1494,7 +1495,7 @@ /* ** Look for a particular board name in the on-board EEPROM. */ -static void EthwrkSignature(char *name, char *eeprom_image) +__initfunc(static void EthwrkSignature(char *name, char *eeprom_image)) { u_long i,j,k; char *signatures[] = EWRK3_SIGNATURE; @@ -1531,7 +1532,7 @@ ** ethernet address for later read out. */ -static int DevicePresent(u_long iobase) +__initfunc(static int DevicePresent(u_long iobase)) { union { struct { @@ -1568,7 +1569,7 @@ return status; } -static u_char get_hw_addr(struct device *dev, u_char *eeprom_image, char chipType) +__initfunc(static u_char get_hw_addr(struct device *dev, u_char *eeprom_image, char chipType)) { int i, j, k; u_short chksum; @@ -1614,7 +1615,7 @@ /* ** Look for a particular board name in the EISA configuration space */ -static int EISA_signature(char *name, s32 eisa_id) +__initfunc(static int EISA_signature(char *name, s32 eisa_id)) { u_long i; char *signatures[] = EWRK3_SIGNATURE; diff -u --recursive --new-file v2.1.35/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c --- v2.1.35/linux/drivers/net/fmv18x.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/fmv18x.c Tue Apr 22 22:42:49 1997 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,7 @@ #include #include -static int fmv18x_probe_list[] = +static int fmv18x_probe_list[] __initdata = {0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -129,8 +130,8 @@ struct netdev_entry fmv18x_drv = {"fmv18x", fmv18x_probe1, FMV18X_IO_EXTENT, fmv18x_probe_list}; #else -int -fmv18x_probe(struct device *dev) +__initfunc(int +fmv18x_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -160,7 +161,7 @@ that can be done is checking a few bits and then diving right into MAC address check. */ -int fmv18x_probe1(struct device *dev, short ioaddr) +__initfunc(int fmv18x_probe1(struct device *dev, short ioaddr)) { char irqmap[4] = {3, 7, 10, 15}; unsigned int i, irq; diff -u --recursive --new-file v2.1.35/linux/drivers/net/hdlcdrv.c linux/drivers/net/hdlcdrv.c --- v2.1.35/linux/drivers/net/hdlcdrv.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/hdlcdrv.c Tue Apr 22 22:42:49 1997 @@ -277,7 +277,6 @@ memcpy(cp, s->hdlcrx.buffer, pkt_len - 1); skb->protocol = htons(ETH_P_AX25); skb->mac.raw = skb->data; - IS_SKB(skb); netif_rx(skb); s->stats.rx_packets++; } diff -u --recursive --new-file v2.1.35/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c --- v2.1.35/linux/drivers/net/hp-plus.c Tue Dec 31 00:30:01 1996 +++ linux/drivers/net/hp-plus.c Tue Apr 22 22:42:49 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,7 @@ #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int hpplus_portlist[] = +static unsigned int hpplus_portlist[] __initdata = {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0}; /* @@ -121,7 +122,7 @@ {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist}; #else -int hp_plus_probe(struct device *dev) +__initfunc(int hp_plus_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -144,7 +145,7 @@ #endif /* Do the interesting part of the probe at a single address. */ -int hpp_probe1(struct device *dev, int ioaddr) +__initfunc(int hpp_probe1(struct device *dev, int ioaddr)) { int i; unsigned char checksum = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/hp.c linux/drivers/net/hp.c --- v2.1.35/linux/drivers/net/hp.c Tue Dec 31 00:30:01 1996 +++ linux/drivers/net/hp.c Tue Apr 22 22:42:49 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int hppclan_portlist[] = +static unsigned int hppclan_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0}; #define HP_IO_EXTENT 32 @@ -70,8 +71,8 @@ static void hp_init_card(struct device *dev); /* The map from IRQ number to HP_CONFIGURE register setting. */ -/* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */ -static char irqmap[16] = { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0}; +/* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */ +static char irqmap[16] __initdata= { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0}; /* Probe for an HP LAN adaptor. @@ -82,7 +83,7 @@ {"hp", hp_probe1, HP_IO_EXTENT, hppclan_portlist}; #else -int hp_probe(struct device *dev) +__initfunc(int hp_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -104,7 +105,7 @@ } #endif -int hp_probe1(struct device *dev, int ioaddr) +__initfunc(int hp_probe1(struct device *dev, int ioaddr)) { int i, board_id, wordmode; const char *name; diff -u --recursive --new-file v2.1.35/linux/drivers/net/hp100.c linux/drivers/net/hp100.c --- v2.1.35/linux/drivers/net/hp100.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/hp100.c Tue Apr 22 22:42:49 1997 @@ -93,6 +93,7 @@ #include #include #include +#include #include #include @@ -209,7 +210,7 @@ * probe functions */ -int hp100_probe( struct device *dev ) +__initfunc(int hp100_probe( struct device *dev )) { int base_addr = dev ? dev -> base_addr : 0; int ioaddr; @@ -297,7 +298,7 @@ return -ENODEV; } -static int hp100_probe1( struct device *dev, int ioaddr, int bus ) +__initfunc(static int hp100_probe1( struct device *dev, int ioaddr, int bus )) { int i; u_char uc, uc_1; diff -u --recursive --new-file v2.1.35/linux/drivers/net/hydra.c linux/drivers/net/hydra.c --- v2.1.35/linux/drivers/net/hydra.c Sun Feb 2 05:18:40 1997 +++ linux/drivers/net/hydra.c Tue Apr 22 22:42:49 1997 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,7 @@ #include #include -#include +#include #include "hydra.h" @@ -156,7 +157,7 @@ #endif -int hydra_probe(struct device *dev) +__initfunc(int hydra_probe(struct device *dev)) { struct hydra_private *priv; u32 board; @@ -193,7 +194,9 @@ dev->stop = &hydra_close; dev->hard_start_xmit = &hydra_start_xmit; dev->get_stats = &hydra_get_stats; - dev->set_multicast_list = &hydra_set_multicast_list; +#ifdef HAVE_MULTICAST + dev->set_multicast_list = &set_multicast_list; +#endif /* * Cannot yet do multicast @@ -643,6 +646,7 @@ return(&priv->stats); } +#ifdef HAVE_MULTICAST static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) { struct hydra_private *priv = (struct hydra_private *)dev->priv; @@ -652,6 +656,7 @@ /* (personally i don't care about multicasts at all :) */ return; } +#endif #ifdef MODULE diff -u --recursive --new-file v2.1.35/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c --- v2.1.35/linux/drivers/net/ibmtr.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/ibmtr.c Tue Apr 22 22:42:49 1997 @@ -119,6 +119,7 @@ #include #include #include +#include #include #include @@ -134,11 +135,11 @@ #if TR_NEWFORMAT /* this allows displaying full adapter information */ -const char *channel_def[] = { +const char *channel_def[] __initdata = { "ISA", "MCA", "ISA P&P" }; -char *adapter_def(char type) +__initfunc(char *adapter_def(char type)) { switch (type) { @@ -178,13 +179,13 @@ void ibmtr_readlog(struct device *dev); void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev); -static unsigned int ibmtr_portlist[] = { +static unsigned int ibmtr_portlist[] __initdata = { 0xa20, 0xa24, 0 }; static __u32 ibmtr_mem_base = 0xd0000; -static void PrtChanID(char *pcid, short stride) +__initfunc(static void PrtChanID(char *pcid, short stride) ) { short i, j; for (i=0, j=0; i<24; i++, j+=stride) @@ -192,7 +193,7 @@ printk("\n"); } -static void HWPrtChanID (__u32 pcid, short stride) +__initfunc(static void HWPrtChanID (__u32 pcid, short stride)) { short i, j; for (i=0, j=0; i<24; i++, j+=stride) @@ -213,7 +214,7 @@ * which references it. */ -int ibmtr_probe(struct device *dev) +__initfunc(int ibmtr_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -252,7 +253,7 @@ return -ENODEV; } -static int ibmtr_probe1(struct device *dev, int PIOaddr) +__initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr)) { unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0; __u32 t_mmio=0; @@ -597,7 +598,7 @@ /* query the adapter for the size of shared RAM */ -unsigned char get_sram_size(struct tok_info *adapt_info) +__initfunc(static unsigned char get_sram_size(struct tok_info *adapt_info)) { unsigned char avail_sram_code; @@ -617,7 +618,7 @@ return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4); } -int trdev_init(struct device *dev) +__initfunc(static int trdev_init(struct device *dev)) { struct tok_info *ti=(struct tok_info *)dev->priv; diff -u --recursive --new-file v2.1.35/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v2.1.35/linux/drivers/net/lance.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/lance.c Tue Apr 22 22:42:49 1997 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ #include #include -static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0}; +static unsigned int lance_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0}; void lance_probe1(int ioaddr); #ifdef HAVE_DEVLIST @@ -308,7 +309,7 @@ before the memory management system is started, and thus well before the other probes. */ -int lance_init(void) +__initfunc(int lance_init(void)) { int *port; @@ -371,7 +372,7 @@ return 0; } -void lance_probe1(int ioaddr) +__initfunc(void lance_probe1(int ioaddr)) { struct device *dev; struct lance_private *lp; diff -u --recursive --new-file v2.1.35/linux/drivers/net/lapbether.c linux/drivers/net/lapbether.c --- v2.1.35/linux/drivers/net/lapbether.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/lapbether.c Tue Apr 22 22:42:49 1997 @@ -47,6 +47,7 @@ #include #include #include +#include static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; @@ -410,7 +411,7 @@ return 0; } -static int lapbeth_dev_init(struct device *dev) +__initfunc(static int lapbeth_dev_init(struct device *dev)) { return 0; } diff -u --recursive --new-file v2.1.35/linux/drivers/net/loopback.c linux/drivers/net/loopback.c --- v2.1.35/linux/drivers/net/loopback.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/loopback.c Tue Apr 22 22:42:49 1997 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -114,7 +115,7 @@ } /* Initialize the rest of the LOOPBACK device. */ -int loopback_init(struct device *dev) +__initfunc(int loopback_init(struct device *dev)) { dev->mtu = LOOPBACK_MTU; dev->tbusy = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c --- v2.1.35/linux/drivers/net/ltpc.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/ltpc.c Tue Apr 22 22:42:49 1997 @@ -201,6 +201,7 @@ #include #include #include +#include #include #include @@ -956,12 +957,12 @@ static unsigned short irqhitmask; -static void lt_probe_handler(int irq, void *dev_id, struct pt_regs *reg_ptr) +__initfunc(static void lt_probe_handler(int irq, void *dev_id, struct pt_regs *reg_ptr)) { irqhitmask |= 1< #include #include +#include #include @@ -816,7 +817,7 @@ } /* Initialize AX25 control device -- register AX25 line discipline */ -int mkiss_init_ctrl_dev(void) +__initfunc(int mkiss_init_ctrl_dev(void)) { int status; @@ -1038,7 +1039,7 @@ /* * Init MKISS driver * */ /* ******************************************************************** */ -static int mkiss_init(void) +__initfunc(static int mkiss_init(void)) { memset(&mkiss_driver, 0, sizeof(struct tty_driver)); diff -u --recursive --new-file v2.1.35/linux/drivers/net/myri_code.h linux/drivers/net/myri_code.h --- v2.1.35/linux/drivers/net/myri_code.h Thu Dec 19 01:03:34 1996 +++ linux/drivers/net/myri_code.h Thu Apr 17 13:20:45 1997 @@ -2,7 +2,7 @@ /* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */ static unsigned int lanai4_code_off = 0x0000; /* half-word offset */ -static unsigned char lanai4_code[76256] = { +static unsigned char lanai4_code[76256] __initdata = { 0xF2,0x0E, 0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, @@ -4775,7 +4775,7 @@ /* This is the LANai data */ static unsigned int lanai4_data_off = 0x94F0; /* half-word offset */ -static unsigned char lanai4_data[20472] = { +static unsigned char lanai4_data[20472] __initdata = { 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, diff -u --recursive --new-file v2.1.35/linux/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c --- v2.1.35/linux/drivers/net/myri_sbus.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/myri_sbus.c Thu Apr 17 13:20:45 1997 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -171,7 +172,7 @@ return 0; } -static int myri_load_lanai(struct myri_eth *mp) +static inline int myri_load_lanai(struct myri_eth *mp) { struct device *dev = mp->dev; struct myri_shmem *shmem = mp->shmem; @@ -893,7 +894,7 @@ } #endif -static int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num) +static inline int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num) { static unsigned version_printed = 0; struct myri_eth *mp; @@ -1105,7 +1106,7 @@ return 0; } -int myri_sbus_probe(struct device *dev) +__initfunc(int myri_sbus_probe(struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/ne.c linux/drivers/net/ne.c --- v2.1.35/linux/drivers/net/ne.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/net/ne.c Tue Apr 22 22:42:49 1997 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -64,14 +65,14 @@ /* A zero-terminated list of I/O addresses to be probed at boot. */ #ifndef MODULE -static unsigned int netcard_portlist[] = -{ 0x300, 0x280, 0x320, 0x340, 0x360, 0}; +static unsigned int netcard_portlist[] __initdata = +{ 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0}; #endif #ifdef CONFIG_PCI /* Ack! People are making PCI ne2000 clones! Oh the horror, the horror... */ static struct { unsigned short vendor, dev_id;} -pci_clone_list[] = { +pci_clone_list[] __initdata = { {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029}, {PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940}, {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000}, @@ -83,7 +84,7 @@ #ifdef SUPPORT_NE_BAD_CLONES /* A list of bad clones that we none-the-less recognize. */ static struct { const char *name8, *name16; unsigned char SAprefix[4];} -bad_clone_list[] = { +bad_clone_list[] __initdata = { {"DE100", "DE200", {0x00, 0xDE, 0x01,}}, {"DE120", "DE220", {0x00, 0x80, 0xc8,}}, {"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh? */ @@ -166,7 +167,7 @@ * the card. */ -int ne_probe(struct device *dev) +__initfunc(int ne_probe(struct device *dev)) { int base_addr = dev ? dev->base_addr : 0; @@ -198,7 +199,7 @@ #endif #ifdef CONFIG_PCI -static int ne_probe_pci(struct device *dev) +__initfunc(static int ne_probe_pci(struct device *dev)) { int i; @@ -240,7 +241,7 @@ } #endif /* CONFIG_PCI */ -static int ne_probe1(struct device *dev, int ioaddr) +__initfunc(static int ne_probe1(struct device *dev, int ioaddr)) { int i; unsigned char SA_prom[32]; diff -u --recursive --new-file v2.1.35/linux/drivers/net/ni52.c linux/drivers/net/ni52.c --- v2.1.35/linux/drivers/net/ni52.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/net/ni52.c Tue Apr 22 22:42:49 1997 @@ -114,6 +114,7 @@ #include #include #include +#include #include #include @@ -359,7 +360,7 @@ /********************************************** * probe the ni5210-card */ -int ni52_probe(struct device *dev) +__initfunc(int ni52_probe(struct device *dev)) { #ifndef MODULE int *port; @@ -410,7 +411,7 @@ return ENODEV; } -static int ni52_probe1(struct device *dev,int ioaddr) +__initfunc(static int ni52_probe1(struct device *dev,int ioaddr)) { int i,size; @@ -455,7 +456,7 @@ else { static long memaddrs[] = { 0xc8000,0xca000,0xcc000,0xce000,0xd0000,0xd2000, - 0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 }; + 0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 }; for(i=0;;i++) { if(!memaddrs[i]) { diff -u --recursive --new-file v2.1.35/linux/drivers/net/ni65.c linux/drivers/net/ni65.c --- v2.1.35/linux/drivers/net/ni65.c Sun Feb 2 05:18:40 1997 +++ linux/drivers/net/ni65.c Tue Apr 22 22:42:49 1997 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -232,8 +233,8 @@ static struct net_device_stats *ni65_get_stats(struct device *); static void set_multicast_list(struct device *dev); -static int irqtab[] = { 9,12,15,5 }; /* irq config-translate */ -static int dmatab[] = { 0,3,5,6,7 }; /* dma config-translate and autodetect */ +static int irqtab[] __initdata = { 9,12,15,5 }; /* irq config-translate */ +static int dmatab[] __initdata = { 0,3,5,6,7 }; /* dma config-translate and autodetect */ static int debuglevel = 1; @@ -327,7 +328,7 @@ #ifdef MODULE static #endif -int ni65_probe(struct device *dev) +__initfunc(int ni65_probe(struct device *dev)) { int *port; static int ports[] = {0x360,0x300,0x320,0x340, 0}; @@ -349,7 +350,7 @@ /* * this is the real card probe .. */ -static int ni65_probe1(struct device *dev,int ioaddr) +__initfunc(static int ni65_probe1(struct device *dev,int ioaddr)) { int i,j; struct priv *p; diff -u --recursive --new-file v2.1.35/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c --- v2.1.35/linux/drivers/net/pcnet32.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/pcnet32.c Tue Apr 22 22:42:49 1997 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,7 @@ #include #include -static unsigned int pcnet32_portlist[] = {0x300, 0x320, 0x340, 0x360, 0}; +static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0}; #ifdef PCNET32_DEBUG static int pcnet32_debug = PCNET32_DEBUG; @@ -168,7 +169,7 @@ -int pcnet32_probe (struct device *dev) +__initfunc(int pcnet32_probe (struct device *dev)) { unsigned int ioaddr = dev ? dev->base_addr: 0; unsigned char irq_line = dev ? dev->irq : 0; @@ -246,7 +247,7 @@ /* pcnet32_probe1 */ -int pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char irq_line, int shared) +__initfunc(static int pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char irq_line, int shared)) { struct pcnet32_private *lp; int i; diff -u --recursive --new-file v2.1.35/linux/drivers/net/pi2.c linux/drivers/net/pi2.c --- v2.1.35/linux/drivers/net/pi2.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/pi2.c Tue Apr 22 22:42:49 1997 @@ -112,6 +112,7 @@ #include #include #include +#include #include "z8530.h" #include @@ -564,7 +565,6 @@ pkt_len - 1); skb->protocol=htons(ETH_P_AX25); skb->mac.raw=skb->data; - IS_SKB(skb); netif_rx(skb); lp->stats.rx_packets++; } /* end good frame */ @@ -652,7 +652,6 @@ memcpy(cfix, lp->rcvbuf->data, pkt_len - 1); skb->protocol=ntohs(ETH_P_AX25); skb->mac.raw=skb->data; - IS_SKB(skb); netif_rx(skb); lp->stats.rx_packets++; /* packet queued - initialize buffer for next frame */ @@ -933,7 +932,7 @@ /* Probe for a PI card. */ /* This routine also initializes the timer chip */ -static int hw_probe(int ioaddr) +__initfunc(static int hw_probe(int ioaddr)) { int time = 1000; /* Number of milliseconds for test */ unsigned long start_time, end_time; @@ -1188,13 +1187,12 @@ } -int pi_init(void) +__initfunc(int pi_init(void)) { int *port; int ioaddr = 0; int card_type = 0; - int ports[] = - {0x380, 0x300, 0x320, 0x340, 0x360, 0x3a0, 0}; + int ports[] = {0x380, 0x300, 0x320, 0x340, 0x360, 0x3a0, 0}; printk(KERN_INFO "PI: V0.8 ALPHA April 23 1995 David Perry (dp@hydra.carleton.ca)\n"); diff -u --recursive --new-file v2.1.35/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.1.35/linux/drivers/net/plip.c Sun Apr 13 10:18:21 1997 +++ linux/drivers/net/plip.c Tue Apr 22 22:42:49 1997 @@ -1,4 +1,4 @@ -/* $Id: plip.c,v 1.1.1.1.2.6 1997/03/26 17:52:20 phil Exp $ */ +/* $Id: plip.c,v 1.3.6.2 1997/04/16 15:07:56 phil Exp $ */ /* PLIP: A parallel port "network" driver for Linux. */ /* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */ /* @@ -95,6 +95,7 @@ #include #include #include +#include #include #include @@ -223,8 +224,8 @@ then calls us here. */ -int -plip_init_dev(struct device *dev, struct parport *pb) +__initfunc(int +plip_init_dev(struct device *dev, struct parport *pb)) { struct net_local *nl; struct ppd *pardev; @@ -1190,8 +1191,8 @@ return 0; } -int -plip_init(void) +__initfunc(int +plip_init(void)) { struct parport *pb = parport_enumerate(); int devices=0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v2.1.35/linux/drivers/net/ppp.c Tue Mar 4 10:25:23 1997 +++ linux/drivers/net/ppp.c Tue Apr 22 22:42:50 1997 @@ -85,6 +85,7 @@ #include #include #include +#include typedef struct sk_buff sk_buff; #define skb_data(skb) ((__u8 *) (skb)->data) @@ -334,8 +335,8 @@ * accessing the ppp protocol. */ -static int -ppp_first_time (void) +__initfunc(static int +ppp_first_time (void)) { static struct tty_ldisc ppp_ldisc; int status; diff -u --recursive --new-file v2.1.35/linux/drivers/net/pt.c linux/drivers/net/pt.c --- v2.1.35/linux/drivers/net/pt.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/pt.c Tue Apr 22 22:42:50 1997 @@ -92,6 +92,7 @@ #include #include #include +#include #include "z8530.h" #include @@ -480,7 +481,7 @@ -int pt_init(void) +__initfunc(int pt_init(void)) { int *port; int ioaddr = 0; @@ -542,7 +543,7 @@ /* * Probe for PT card. Also initialises the timers */ -static int hw_probe(int ioaddr) +__initfunc(static int hw_probe(int ioaddr)) { int time = 1000; /* Number of milliseconds to test */ int a = 1; @@ -1380,7 +1381,6 @@ skb->protocol = ntohs(ETH_P_AX25); skb->mac.raw=skb->data; lp->stats.rx_bytes+=skb->len; - IS_SKB(skb); netif_rx(skb); lp->stats.rx_packets++; if (!lp->dmachan) diff -u --recursive --new-file v2.1.35/linux/drivers/net/scc.c linux/drivers/net/scc.c --- v2.1.35/linux/drivers/net/scc.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/scc.c Tue Apr 22 22:42:50 1997 @@ -153,6 +153,7 @@ #include #include #include +#include #include #include "z8530.h" @@ -2153,7 +2154,7 @@ /* * Init SCC driver * */ /* ******************************************************************** */ -int scc_init (void) +__initfunc(int scc_init (void)) { int chip, chan, k, result; char devname[10]; diff -u --recursive --new-file v2.1.35/linux/drivers/net/sdla.c linux/drivers/net/sdla.c --- v2.1.35/linux/drivers/net/sdla.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/net/sdla.c Tue Apr 22 22:42:50 1997 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -64,9 +65,10 @@ static const char* devname = "sdla"; -static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; +static unsigned int valid_port[] __initdata = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; -static unsigned int valid_mem[] = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, +static unsigned int valid_mem[] __initdata = { + 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000, 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000, @@ -1621,7 +1623,7 @@ return(&flp->stats); } -int sdla_init(struct device *dev) +__initfunc(int sdla_init(struct device *dev)) { struct frad_local *flp; @@ -1669,7 +1671,7 @@ return(0); } -void sdla_setup(void) +__initfunc(void sdla_setup(void)) { printk("%s.\n", version); register_frad(devname); diff -u --recursive --new-file v2.1.35/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c --- v2.1.35/linux/drivers/net/sdla_fr.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/sdla_fr.c Tue Apr 22 22:42:50 1997 @@ -25,6 +25,7 @@ #include /* WAN router definitions */ #include /* WANPIPE common user API definitions */ #include /* ARPHRD_* defines */ +#include /* __initfunc et al. */ #include /* htons(), etc. */ #include /* for inb(), outb(), etc. */ @@ -135,7 +136,7 @@ * Return: 0 o.k. * < 0 failure. */ -int wpf_init (sdla_t* card, wandev_conf_t* conf) +__initfunc(int wpf_init (sdla_t* card, wandev_conf_t* conf)) { union { diff -u --recursive --new-file v2.1.35/linux/drivers/net/sdla_ppp.c linux/drivers/net/sdla_ppp.c --- v2.1.35/linux/drivers/net/sdla_ppp.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/sdla_ppp.c Tue Apr 22 22:42:50 1997 @@ -25,6 +25,7 @@ #include /* WAN router definitions */ #include /* WANPIPE common user API definitions */ #include /* ARPHRD_* defines */ +#include /* __initfunc et al. */ #include /* htons(), etc. */ #define _GNUC_ @@ -107,7 +108,7 @@ * Return: 0 o.k. * < 0 failure. */ -int wpp_init (sdla_t* card, wandev_conf_t* conf) +__initfunc(int wpp_init (sdla_t* card, wandev_conf_t* conf)) { union { diff -u --recursive --new-file v2.1.35/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c --- v2.1.35/linux/drivers/net/sdla_x25.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/sdla_x25.c Tue Apr 22 22:42:50 1997 @@ -24,6 +24,7 @@ #include /* kmalloc(), kfree() */ #include /* WAN router definitions */ #include /* WANPIPE common user API definitions */ +#include /* __initfunc et al. */ #include /* htons(), etc. */ #define _GNUC_ @@ -168,7 +169,7 @@ * Return: 0 o.k. * < 0 failure. */ -int wpx_init (sdla_t* card, wandev_conf_t* conf) +__initfunc(int wpx_init (sdla_t* card, wandev_conf_t* conf)) { union { diff -u --recursive --new-file v2.1.35/linux/drivers/net/sdladrv.c linux/drivers/net/sdladrv.c --- v2.1.35/linux/drivers/net/sdladrv.c Sun Feb 2 05:18:41 1997 +++ linux/drivers/net/sdladrv.c Tue Apr 22 22:42:50 1997 @@ -90,6 +90,7 @@ #include /* for jiffies, HZ, etc. */ #include /* API definitions */ #include /* SDLA firmware module definitions */ +#include #include /* for inb(), outb(), etc. */ #define _INB(port) (inb(port)) #define _OUTB(port, byte) (outb((byte),(port))) @@ -289,7 +290,8 @@ #ifdef MODULE int init_module (void) #else -int wanpipe_init(void) +__initfunc(int wanpipe_init(void)) +#endif { printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE, copyright); diff -u --recursive --new-file v2.1.35/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c --- v2.1.35/linux/drivers/net/seeq8005.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/seeq8005.c Tue Apr 22 22:42:50 1997 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int seeq8005_portlist[] = +static unsigned int seeq8005_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0}; /* use 0 for production, 1 for verification, >2 for debug */ @@ -106,8 +107,8 @@ struct netdev_entry seeq8005_drv = {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist}; #else -int -seeq8005_probe(struct device *dev) +__initfunc(int +seeq8005_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -133,7 +134,7 @@ probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int seeq8005_probe1(struct device *dev, int ioaddr) +__initfunc(static int seeq8005_probe1(struct device *dev, int ioaddr)) { static unsigned version_printed = 0; int i,j; diff -u --recursive --new-file v2.1.35/linux/drivers/net/shaper.c linux/drivers/net/shaper.c --- v2.1.35/linux/drivers/net/shaper.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/shaper.c Tue Apr 22 22:42:50 1997 @@ -68,6 +68,7 @@ #include #include #include +#include #include #include "shaper.h" @@ -545,7 +546,7 @@ * Add a shaper device to the system */ -int shaper_probe(struct device *dev) +__initfunc(int shaper_probe(struct device *dev)) { /* * Set up the shaper. diff -u --recursive --new-file v2.1.35/linux/drivers/net/slhc.c linux/drivers/net/slhc.c --- v2.1.35/linux/drivers/net/slhc.c Fri Dec 27 02:03:23 1996 +++ linux/drivers/net/slhc.c Tue Apr 22 22:42:50 1997 @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -743,7 +744,7 @@ #else /* MODULE */ -void slhc_install(void) +__initfunc(void slhc_install(void)) { } diff -u --recursive --new-file v2.1.35/linux/drivers/net/slip.c linux/drivers/net/slip.c --- v2.1.35/linux/drivers/net/slip.c Fri Apr 4 08:52:22 1997 +++ linux/drivers/net/slip.c Tue Apr 22 22:42:50 1997 @@ -70,6 +70,7 @@ #include #include #include +#include #include "slip.h" #ifdef CONFIG_INET #include @@ -1087,7 +1088,7 @@ #ifdef MODULE static int slip_init_ctrl_dev(void) #else /* !MODULE */ -int slip_init_ctrl_dev(struct device *dummy) +__initfunc(int slip_init_ctrl_dev(struct device *dummy)) #endif /* !MODULE */ { int status; diff -u --recursive --new-file v2.1.35/linux/drivers/net/smc-mca.c linux/drivers/net/smc-mca.c --- v2.1.35/linux/drivers/net/smc-mca.c Sun Jan 19 05:47:25 1997 +++ linux/drivers/net/smc-mca.c Tue Apr 22 22:42:50 1997 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -66,7 +67,7 @@ #define EN0_ERWCNT 0x08 /* Early receive warning count. */ -int ultramca_probe(struct device *dev) +__initfunc(int ultramca_probe(struct device *dev)) { unsigned short ioaddr; unsigned char reg4, num_pages; diff -u --recursive --new-file v2.1.35/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c --- v2.1.35/linux/drivers/net/smc-ultra.c Mon Jan 13 22:58:19 1997 +++ linux/drivers/net/smc-ultra.c Tue Apr 22 22:42:50 1997 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -61,7 +62,7 @@ #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int ultra_portlist[] = +static unsigned int ultra_portlist[] __initdata = {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; int ultra_probe(struct device *dev); @@ -104,7 +105,7 @@ {"ultra", ultra_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else -int ultra_probe(struct device *dev) +__initfunc(int ultra_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -126,7 +127,7 @@ } #endif -int ultra_probe1(struct device *dev, int ioaddr) +__initfunc(int ultra_probe1(struct device *dev, int ioaddr)) { int i; int checksum = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c --- v2.1.35/linux/drivers/net/smc9194.c Fri Apr 4 08:52:22 1997 +++ linux/drivers/net/smc9194.c Tue Apr 22 22:42:50 1997 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,7 @@ .for a slightly different card, you can add it to the array. Keep in .mind that the array must end in zero. */ -static unsigned int smc_portlist[] = +static unsigned int smc_portlist[] __initdata = { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0}; @@ -750,7 +751,7 @@ | --------------------------------------------------------------------------- */ -int smc_init(struct device *dev) +__initfunc(int smc_init(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -795,7 +796,7 @@ . interrupt, so an auto-detect routine can detect it, and find the IRQ, ------------------------------------------------------------------------ */ -int smc_findirq( int ioaddr ) +__initfunc(int smc_findirq( int ioaddr )) { int timeout = 20; @@ -877,7 +878,7 @@ .--------------------------------------------------------------------- */ -static int smc_probe( int ioaddr ) +__initfunc(static int smc_probe( int ioaddr )) { unsigned int bank; word revision_register; @@ -942,7 +943,7 @@ . o GRAB the region .----------------------------------------------------------------- */ -static int smc_initcard(struct device *dev, int ioaddr) +__initfunc(static int smc_initcard(struct device *dev, int ioaddr)) { int i; diff -u --recursive --new-file v2.1.35/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c --- v2.1.35/linux/drivers/net/sunhme.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/sunhme.c Thu Apr 17 13:20:46 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -2058,7 +2059,7 @@ dev->tbusy = 0; } -static int happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev) +static inline int happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev) { static unsigned version_printed = 0; struct happy_meal *hp; @@ -2201,7 +2202,7 @@ return 0; } -int happy_meal_probe(struct device *dev) +__initfunc(int happy_meal_probe(struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c --- v2.1.35/linux/drivers/net/sunlance.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/sunlance.c Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: sunlance.c,v 1.61 1997/04/10 06:40:54 davem Exp $ +/* $Id: sunlance.c,v 1.62 1997/04/16 10:27:25 jj Exp $ * lance.c: Linux/Sparc/Lance driver * * Written 1995, 1996 by Miguel de Icaza @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -934,9 +935,10 @@ dev->tbusy = 0; } -int sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev, - struct Linux_SBus_DMA *ledma, - struct linux_sbus_device *lebuffer) +__initfunc(static int +sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev, + struct Linux_SBus_DMA *ledma, + struct linux_sbus_device *lebuffer)) { static unsigned version_printed = 0; int i; @@ -1097,7 +1099,7 @@ } /* On 4m, find the associated dma for the lance chip */ -static struct Linux_SBus_DMA * +static inline struct Linux_SBus_DMA * find_ledma (struct linux_sbus_device *dev) { struct Linux_SBus_DMA *p; @@ -1109,7 +1111,7 @@ } /* Find all the lance cards on the system and initialize them */ -int sparc_lance_probe (struct device *dev) +__initfunc(int sparc_lance_probe (struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/sunqe.c linux/drivers/net/sunqe.c --- v2.1.35/linux/drivers/net/sunqe.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/sunqe.c Thu Apr 17 13:20:46 1997 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -902,7 +903,7 @@ } /* Four QE's per QEC card. */ -static int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev) +static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev) { static unsigned version_printed = 0; struct device *qe_devs[4]; @@ -1149,7 +1150,7 @@ return res; } -int qec_probe(struct device *dev) +__initfunc(int qec_probe(struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v2.1.35/linux/drivers/net/tulip.c Sun Feb 2 05:18:42 1997 +++ linux/drivers/net/tulip.c Tue Apr 22 22:42:50 1997 @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -473,8 +474,8 @@ card_type returns 1 if the card is 'etherarray' */ -static int -card_type(struct tulip_private *tp, int device_id, int vendor_id) +__initfunc(static int +card_type(struct tulip_private *tp, int device_id, int vendor_id)) { int n; @@ -488,8 +489,8 @@ return(cardVendor[n].array ? 1: 0); } -static int -read_eeprom(int ioaddr, struct eeprom *eepp) +__initfunc(static int +read_eeprom(int ioaddr, struct eeprom *eepp)) { int i, n; unsigned short val = 0; @@ -1188,9 +1189,9 @@ } } -int +__initfunc(int tulip_hwinit(struct device *dev, int ioaddr, - int irq, int device_id) + int irq, int device_id)) { /* See note below on the Znyx 315 etherarray. */ static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; @@ -1319,7 +1320,7 @@ return(0); } -int tulip_probe(struct device *dev) +__initfunc(int tulip_probe(struct device *dev)) { static struct device *tulip_head=NULL; u_char pci_bus, pci_device_fn, pci_latency, pci_irq; diff -u --recursive --new-file v2.1.35/linux/drivers/net/tunnel.c linux/drivers/net/tunnel.c --- v2.1.35/linux/drivers/net/tunnel.c Fri Apr 4 08:52:22 1997 +++ linux/drivers/net/tunnel.c Tue Apr 22 22:42:50 1997 @@ -64,6 +64,7 @@ #include #include #include +#include /*#define TUNNEL_DEBUG*/ @@ -213,7 +214,7 @@ * The new tunnel device structure is passed to us. */ -int tunnel_init(struct device *dev) +__initfunc(int tunnel_init(struct device *dev)) { /* Oh, just say we're here, in case anyone cares */ static int tun_msg=0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c --- v2.1.35/linux/drivers/net/wavelan.c Fri Apr 4 08:52:22 1997 +++ linux/drivers/net/wavelan.c Thu Apr 17 14:40:36 1997 @@ -112,7 +112,7 @@ * Read from card's Host Adaptor Status Register. */ static inline u_short -hasr_read(u_short ioaddr) +hasr_read(u_long ioaddr) { return(inw(HASR(ioaddr))); } /* hasr_read */ @@ -122,7 +122,7 @@ * Write to card's Host Adapter Command Register. */ static inline void -hacr_write(u_short ioaddr, +hacr_write(u_long ioaddr, u_short hacr) { outw(hacr, HACR(ioaddr)); @@ -134,7 +134,7 @@ * those times when it is needed. */ static inline void -hacr_write_slow(u_short ioaddr, +hacr_write_slow(u_long ioaddr, u_short hacr) { hacr_write(ioaddr, hacr); @@ -147,7 +147,7 @@ * Set the channel attention bit. */ static inline void -set_chan_attn(u_short ioaddr, +set_chan_attn(u_long ioaddr, u_short hacr) { hacr_write(ioaddr, hacr | HACR_CA); @@ -158,7 +158,7 @@ * Reset, and then set host adaptor into default mode. */ static inline void -wv_hacr_reset(u_short ioaddr) +wv_hacr_reset(u_long ioaddr) { hacr_write_slow(ioaddr, HACR_RESET); hacr_write(ioaddr, HACR_DEFAULT); @@ -169,7 +169,7 @@ * Set the i/o transfer over the ISA bus to 8 bits mode */ static inline void -wv_16_off(u_short ioaddr, +wv_16_off(u_long ioaddr, u_short hacr) { hacr &= ~HACR_16BITS; @@ -181,7 +181,7 @@ * Set the i/o transfer over the ISA bus to 8 bits mode */ static inline void -wv_16_on(u_short ioaddr, +wv_16_on(u_long ioaddr, u_short hacr) { hacr |= HACR_16BITS; @@ -196,7 +196,7 @@ wv_ints_off(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_long x; x = wv_splhi(); @@ -215,7 +215,7 @@ wv_ints_on(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_long x; x = wv_splhi(); @@ -239,7 +239,7 @@ * Read bytes from the PSA. */ static void -psa_read(u_short ioaddr, +psa_read(u_long ioaddr, u_short hacr, int o, /* offset in PSA */ u_char * b, /* buffer to fill */ @@ -262,7 +262,7 @@ * Write the Paramter Storage Area to the WaveLAN card's memory */ static void -psa_write(u_short ioaddr, +psa_write(u_long ioaddr, u_short hacr, int o, /* Offset in psa */ u_char * b, /* Buffer in memory */ @@ -329,7 +329,7 @@ * Write 1 byte to the MMC. */ static inline void -mmc_out(u_short ioaddr, +mmc_out(u_long ioaddr, u_short o, u_char d) { @@ -347,7 +347,7 @@ * We start by the end because it is the way it should be ! */ static inline void -mmc_write(u_short ioaddr, +mmc_write(u_long ioaddr, u_char o, u_char * b, int n) @@ -365,7 +365,7 @@ * Optimised version for 1 byte, avoid using memory... */ static inline u_char -mmc_in(u_short ioaddr, +mmc_in(u_long ioaddr, u_short o) { while(inw(HASR(ioaddr)) & HASR_MMC_BUSY) @@ -386,7 +386,7 @@ * We start by the end because it is the way it should be ! */ static inline void -mmc_read(u_short ioaddr, +mmc_read(u_long ioaddr, u_char o, u_char * b, int n) @@ -400,11 +400,27 @@ /*------------------------------------------------------------------*/ /* + * Get the type of encryption available... + */ +static inline int +mmc_encr(u_long ioaddr) /* i/o port of the card */ +{ + int temp; + + temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail)); + if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES)) + return 0; + else + return temp; +} + +/*------------------------------------------------------------------*/ +/* * Wait for the frequency EEprom to complete a command... * I hope this one will be optimally inlined... */ static inline void -fee_wait(u_short ioaddr, /* i/o port of the card */ +fee_wait(u_long ioaddr, /* i/o port of the card */ int delay, /* Base delay to wait for */ int number) /* Number of time to wait */ { @@ -420,7 +436,7 @@ * Read bytes from the Frequency EEprom (frequency select cards). */ static void -fee_read(u_short ioaddr, /* i/o port of the card */ +fee_read(u_long ioaddr, /* i/o port of the card */ u_short o, /* destination offset */ u_short * b, /* data buffer */ int n) /* number of registers */ @@ -445,6 +461,8 @@ } } +#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ + /*------------------------------------------------------------------*/ /* * Write bytes from the Frequency EEprom (frequency select cards). @@ -453,7 +471,7 @@ * Jean II */ static void -fee_write(u_short ioaddr, /* i/o port of the card */ +fee_write(u_long ioaddr, /* i/o port of the card */ u_short o, /* destination offset */ u_short * b, /* data buffer */ int n) /* number of registers */ @@ -528,6 +546,7 @@ fee_wait(ioaddr, 10, 100); #endif /* EEPROM_IS_PROTECTED */ } +#endif /* WIRELESS_EXT */ /************************ I82586 SUBROUTINES *************************/ /* @@ -540,7 +559,7 @@ * Why inlining this function make it fail ??? */ static /*inline*/ void -obram_read(u_short ioaddr, +obram_read(u_long ioaddr, u_short o, u_char * b, int n) @@ -554,7 +573,7 @@ * Write bytes to the on-board RAM. */ static inline void -obram_write(u_short ioaddr, +obram_write(u_long ioaddr, u_short o, u_char * b, int n) @@ -571,7 +590,7 @@ wv_ack(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cs; int i; @@ -614,7 +633,7 @@ const char * str) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cmd; ach_t cb; int i; @@ -660,7 +679,7 @@ */ static inline int wv_config_complete(device * dev, - u_short ioaddr, + u_long ioaddr, net_local * lp) { unsigned short mcs_addr; @@ -722,7 +741,7 @@ */ static int wv_complete(device * dev, - u_short ioaddr, + u_long ioaddr, net_local * lp) { int nreaped = 0; @@ -992,7 +1011,7 @@ static void wv_mmc_show(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; mmr_t m; @@ -1077,7 +1096,7 @@ * Print the last block of the i82586 memory */ static void -wv_scb_show(unsigned short ioaddr) +wv_scb_show(u_long ioaddr) { scb_t scb; @@ -1162,7 +1181,7 @@ int i, u_short p) { - unsigned short ioaddr; + u_long ioaddr; ac_tx_t actx; ioaddr = dev->base_addr; @@ -1529,7 +1548,7 @@ * (called in wavelan_ioctl) */ static inline int -wv_set_frequency(u_short ioaddr, /* i/o port of the card */ +wv_set_frequency(u_long ioaddr, /* i/o port of the card */ iw_freq * frequency) { const int BAND_NUM = 10; /* Number of bands */ @@ -1550,7 +1569,7 @@ } /* Setting by channel (same as wfreqsel) */ - /* Warning : each channel is 11MHz wide, so some of the channels + /* Warning : each channel is 22MHz wide, so some of the channels * will interfere... */ if((frequency->e == 0) && (frequency->m >= 0) && (frequency->m < BAND_NUM)) @@ -1729,7 +1748,7 @@ * Give the list of available frequencies */ static inline int -wv_frequency_list(u_short ioaddr, /* i/o port of the card */ +wv_frequency_list(u_long ioaddr, /* i/o port of the card */ iw_freq * list, /* List of frequency to fill */ int max) /* Maximum number of frequencies */ { @@ -1826,7 +1845,7 @@ struct ifreq * rq, /* Data passed */ int cmd) /* Ioctl number */ { - unsigned short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; /* lp is not unused */ struct iwreq * wrq = (struct iwreq *) rq; psa_t psa; @@ -1866,9 +1885,7 @@ m.w.mmw_netw_id_h = (wrq->u.nwid.nwid & 0xFF00) >> 8; mmc_write(ioaddr, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2); - m.w.mmw_loopt_sel = 0x00; - mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m, - (unsigned char *)&m.w.mmw_loopt_sel, 1); + mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00); } else { @@ -1878,10 +1895,8 @@ (char *)&psa.psa_nwid_select - (char *)&psa, (unsigned char *)&psa.psa_nwid_select, 1); - /* Disable nwid in the mmc (no check) */ - m.w.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID; - mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m, - (unsigned char *)&m.w.mmw_loopt_sel, 1); + /* Disable nwid in the mmc (no filtering) */ + mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID); } break; @@ -1950,6 +1965,82 @@ wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F; break; + case SIOCSIWENCODE: + /* Set encryption key */ + if(!mmc_encr(ioaddr)) + { + ret = -EOPNOTSUPP; + break; + } + + if(wrq->u.encoding.method) + { /* enable encryption */ + int i; + long long key = wrq->u.encoding.code; + + for(i = 7; i >= 0; i--) + { + psa.psa_encryption_key[i] = key & 0xFF; + key >>= 8; + } + psa.psa_encryption_select = 1; + psa_write(ioaddr, lp->hacr, + (char *) &psa.psa_encryption_select - (char *) &psa, + (unsigned char *) &psa.psa_encryption_select, 8+1); + + mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), + MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE); + mmc_write(ioaddr, mmwoff(0, mmw_encr_key), + (unsigned char *) &psa.psa_encryption_key, 8); + } + else + { /* disable encryption */ + psa.psa_encryption_select = 0; + psa_write(ioaddr, lp->hacr, + (char *) &psa.psa_encryption_select - (char *) &psa, + (unsigned char *) &psa.psa_encryption_select, 1); + + mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0); + } + break; + + case SIOCGIWENCODE: + /* Read the encryption key */ + if(!mmc_encr(ioaddr)) + { + ret = -EOPNOTSUPP; + break; + } + + /* only super-user can see encryption key */ + if(!suser()) + { + ret = -EPERM; + break; + } + else + { + int i; + long long key = 0; + + psa_read(ioaddr, lp->hacr, + (char *) &psa.psa_encryption_select - (char *) &psa, + (unsigned char *) &psa.psa_encryption_select, 1+8); + for(i = 0; i < 8; i++) + { + key <<= 8; + key += psa.psa_encryption_key[i]; + } + wrq->u.encoding.code = key; + + /* encryption is enabled */ + if(psa.psa_encryption_select) + wrq->u.encoding.method = mmc_encr(ioaddr); + else + wrq->u.encoding.method = 0; + } + break; + case SIOCGIWRANGE: /* Basic checking... */ if(wrq->u.data.pointer != (caddr_t) 0) @@ -2207,7 +2298,7 @@ static iw_stats * wavelan_get_wireless_stats(device * dev) { - unsigned short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *) dev->priv; mmr_t m; iw_stats * wstats; @@ -2281,7 +2372,7 @@ int sksize) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; struct sk_buff * skb; #ifdef DEBUG_RX_TRACE @@ -2353,8 +2444,9 @@ */ netif_rx(skb); + /* Keep stats up to date */ lp->stats.rx_packets++; - lp->stats.rx_bytes+=sksize; + lp->stats.rx_bytes += skb->len; #ifdef DEBUG_RX_TRACE printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name); @@ -2370,7 +2462,7 @@ static inline void wv_receive(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; int nreaped = 0; @@ -2556,7 +2648,7 @@ short length) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; unsigned short txblock; unsigned short txpred; unsigned short tx_addr; @@ -2649,6 +2741,9 @@ (unsigned char *) &nop.nop_h.ac_link, sizeof(nop.nop_h.ac_link)); + /* Keep stats up to date */ + lp->stats.tx_bytes += length; + /* If watchdog not already active, activate it... */ if(lp->watchdog.prev == (timer_list *) NULL) { @@ -2701,20 +2796,6 @@ return 1; /* - * If some higher layer thinks we've missed - * a tx-done interrupt we are passed NULL. - * Caution: dev_tint() handles the cli()/sti() itself. - */ - if(skb == (struct sk_buff *)0) - { -#ifdef DEBUG_TX_ERROR - printk(KERN_INFO "%s: wavelan_packet_xmit(): skb == NULL\n", dev->name); -#endif - dev_tint(dev); - return 0; - } - - /* * Block a timer-based transmit from overlapping. * In other words, prevent reentering this routine. */ @@ -2761,7 +2842,7 @@ static inline int wv_mmc_init(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; psa_t psa; mmw_t m; @@ -2790,6 +2871,9 @@ /* As NWID is not set : no NWID checking */ psa.psa_nwid_select = 0; + /* Disable encryption */ + psa.psa_encryption_select = 0; + /* Set to standard values * 0x04 for AT, * 0x01 for MCA, @@ -2807,7 +2891,7 @@ #ifdef USE_PSA_CONFIG /* Write the psa */ psa_write(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa, - (unsigned char *)psa.psa_nwid, 3); + (unsigned char *)psa.psa_nwid, 4); psa_write(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa, (unsigned char *)&psa.psa_thr_pre_set, 1); psa_write(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa, @@ -2829,6 +2913,14 @@ else m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID; + memcpy(&m.mmw_encr_key, &psa.psa_encryption_key, + sizeof(m.mmw_encr_key)); + + if(psa.psa_encryption_select) + m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE; + else + m.mmw_encr_enable = 0; + m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F; m.mmw_quality_thr = psa.psa_quality_thr & 0x0F; @@ -2920,7 +3012,7 @@ wv_ru_start(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cs; fd_t fd; rbd_t rbd; @@ -3014,7 +3106,7 @@ wv_cu_start(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; int i; u_short txblock; u_short first_nop; @@ -3115,7 +3207,7 @@ wv_82586_start(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; scp_t scp; /* system configuration pointer */ iscp_t iscp; /* intermediate scp */ scb_t scb; /* system control block */ @@ -3245,7 +3337,7 @@ wv_82586_config(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; unsigned short txblock; unsigned short txpred; unsigned short tx_addr; @@ -3441,7 +3533,7 @@ wv_82586_stop(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cmd; #ifdef DEBUG_CONFIG_TRACE @@ -3476,7 +3568,7 @@ wv_hw_reset(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name, @@ -3521,7 +3613,7 @@ * (called in wavelan_probe() and init_module()) */ static int -wv_check_ioaddr(u_short ioaddr, +wv_check_ioaddr(u_long ioaddr, u_char * mac) { int i; /* Loop counter */ @@ -3568,7 +3660,7 @@ struct pt_regs * regs) { device * dev; - u_short ioaddr; + u_long ioaddr; net_local * lp; u_short hasr; u_short status; @@ -3715,7 +3807,7 @@ { device * dev; net_local * lp; - unsigned short ioaddr; + u_long ioaddr; unsigned long x; unsigned int nreaped; @@ -3910,7 +4002,7 @@ static int wavelan_config(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_char irq_mask; int irq; net_local * lp; diff -u --recursive --new-file v2.1.35/linux/drivers/net/wavelan.p.h linux/drivers/net/wavelan.p.h --- v2.1.35/linux/drivers/net/wavelan.p.h Mon Mar 17 14:54:27 1997 +++ linux/drivers/net/wavelan.p.h Thu Apr 17 14:40:36 1997 @@ -35,6 +35,12 @@ /* ------------------------ SPECIFIC NOTES ------------------------ */ /* + * wavelan.o is darn too big + * ------------------------- + * That's true ! There is a very simple way to reduce the driver + * object by 33% (yes !). Comment out the following line : + * #include + * * MAC address and hardware detection : * ---------------------------------- * The detection code of the wavelan chech that the first 3 @@ -80,14 +86,12 @@ * caracteristics of the hardware in a standard way and support for * applications for taking advantage of it (like Mobile IP). * - * By default, these wireless extensions are disabled, because they - * need a patch to the Linux Kernel. This simple patch may be found - * with the driver + some utilities to access those wireless - * extensions (iwconfig...). Hopefully, those wireless extensions will - * make their way in the kernel someday. + * You will need to enable the CONFIG_NET_RADIO define in the kernel + * configuration to enable the wireless extensions (this is the one + * giving access to the radio network device choice). * - * You also will need to enable the CONFIG_NET_RADIO in the kernel - * configuration to enable the wireless extensions. + * It might also be a good idea as well to fetch the wireless tools to + * configure the device and play a bit. */ /* ---------------------------- FILES ---------------------------- */ @@ -161,6 +165,7 @@ * Ajay Bakre (bakre@paul.rutgers.edu), * Donald Becker (becker@cesdis.gsfc.nasa.gov), * Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com), + * Brent Elphick , * Anders Klemets (klemets@it.kth.se), * Vladimir V. Kolpakov (w@stier.koenig.ru), * Marc Meertens (Marc.Meertens@Utrecht.NCR.com), @@ -185,6 +190,7 @@ * John Rosenberg (johnr@cs.usyd.edu.au), * George Rossi (george@phm.gov.au), * Arthur Scott (arthur@cs.usyd.edu.au), + * Stanislav Sinyagin * Peter Storey, * for their assistance and advice. * @@ -254,16 +260,22 @@ * - Update to wireless extensions changes * - Silly bug in card initial configuration (psa_conf_status) * - * Changes made for release in 2.1.27 : - * ---------------------------------- + * Changes made for release in 2.1.27 & 2.0.30 : + * ------------------------------------------- * - Small bug in debug code (probably not the last one...) * - Remove extern kerword for wavelan_probe() * - Level threshold is now a standard wireless extension (version 4 !) * - modules parameters types (new module interface) * + * Changes made for release in 2.1.36 : + * ---------------------------------- + * - byte count stats (courtesy of David Hinds) + * - Remove dev_tint stuff (courtesy of David Hinds) + * - Encryption setting from Brent Elphick (thanks a lot !) + * - 'ioaddr' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin) + * * Wishes & dreams : * --------------- - * - Encryption stuff * - Roaming */ @@ -347,7 +359,7 @@ /************************ CONSTANTS & MACROS ************************/ #ifdef DEBUG_VERSION_SHOW -static const char *version = "wavelan.c : v15 (wireless extensions) 12/2/97\n"; +static const char *version = "wavelan.c : v16 (wireless extensions) 17/4/97\n"; #endif /* Watchdog temporisation */ @@ -436,69 +448,65 @@ wv_psa_to_irq(u_char); /* ------------------- HOST ADAPTER SUBROUTINES ------------------- */ static inline u_short /* data */ - hasr_read(u_short); /* Read the host interface : base address */ + hasr_read(u_long); /* Read the host interface : base address */ static inline void - hacr_write(u_short, /* Write to host interface : base address */ + hacr_write(u_long, /* Write to host interface : base address */ u_short), /* data */ - hacr_write_slow(u_short, + hacr_write_slow(u_long, u_short), - set_chan_attn(u_short, /* ioaddr */ + set_chan_attn(u_long, /* ioaddr */ u_short), /* hacr */ - wv_hacr_reset(u_short), /* ioaddr */ - wv_16_off(u_short, /* ioaddr */ + wv_hacr_reset(u_long), /* ioaddr */ + wv_16_off(u_long, /* ioaddr */ u_short), /* hacr */ - wv_16_on(u_short, /* ioaddr */ + wv_16_on(u_long, /* ioaddr */ u_short), /* hacr */ wv_ints_off(device *), wv_ints_on(device *); /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ static void - psa_read(u_short, /* Read the Parameter Storage Area */ + psa_read(u_long, /* Read the Parameter Storage Area */ u_short, /* hacr */ int, /* offset in PSA */ u_char *, /* buffer to fill */ int), /* size to read */ - psa_write(u_short, /* Write to the PSA */ + psa_write(u_long, /* Write to the PSA */ u_short, /* hacr */ int, /* Offset in psa */ u_char *, /* Buffer in memory */ int); /* Length of buffer */ static inline void - mmc_out(u_short, /* Write 1 byte to the Modem Manag Control */ + mmc_out(u_long, /* Write 1 byte to the Modem Manag Control */ u_short, u_char), - mmc_write(u_short, /* Write n bytes to the MMC */ + mmc_write(u_long, /* Write n bytes to the MMC */ u_char, u_char *, int); static inline u_char /* Read 1 byte from the MMC */ - mmc_in(u_short, + mmc_in(u_long, u_short); static inline void - mmc_read(u_short, /* Read n bytes from the MMC */ + mmc_read(u_long, /* Read n bytes from the MMC */ u_char, u_char *, int), - fee_wait(u_short, /* Wait for frequency EEprom : base address */ + fee_wait(u_long, /* Wait for frequency EEprom : base address */ int, /* Base delay to wait for */ int); /* Number of time to wait */ static void - fee_read(u_short, /* Read the frequency EEprom : base address */ + fee_read(u_long, /* Read the frequency EEprom : base address */ u_short, /* destination offset */ u_short *, /* data buffer */ - int), /* number of registers */ - fee_write(u_short, /* Write to frequency EEprom : base address */ - u_short, /* destination offset */ - u_short *, /* data buffer */ - int); /* number of registers */ + int); /* number of registers */ /* ---------------------- I82586 SUBROUTINES ----------------------- */ static /*inline*/ void - obram_read(u_short, /* ioaddr */ + obram_read(u_long, /* ioaddr */ u_short, /* o */ u_char *, /* b */ int); /* n */ static inline void - obram_write(u_short, /* ioaddr */ + obram_write(u_long, /* ioaddr */ u_short, /* o */ u_char *, /* b */ int); /* n */ @@ -508,11 +516,11 @@ wv_synchronous_cmd(device *, const char *), wv_config_complete(device *, - u_short, + u_long, net_local *); static int wv_complete(device *, - u_short, + u_long, net_local *); static inline void wv_82586_reconfig(device *); @@ -554,7 +562,7 @@ wv_82586_stop(device *); static int wv_hw_reset(device *), /* Reset the wavelan hardware */ - wv_check_ioaddr(u_short, /* ioaddr */ + wv_check_ioaddr(u_long, /* ioaddr */ u_char *); /* mac address (read) */ /* ---------------------- INTERRUPT HANDLING ---------------------- */ static void diff -u --recursive --new-file v2.1.35/linux/drivers/net/wd.c linux/drivers/net/wd.c --- v2.1.35/linux/drivers/net/wd.c Tue Dec 31 00:30:05 1996 +++ linux/drivers/net/wd.c Tue Apr 22 22:42:50 1997 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,7 @@ #include "8390.h" /* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int wd_portlist[] = +static unsigned int wd_portlist[] __initdata = {0x300, 0x280, 0x380, 0x240, 0}; int wd_probe(struct device *dev); @@ -85,7 +86,7 @@ {"wd", wd_probe1, WD_IO_EXTENT, wd_portlist}; #else -int wd_probe(struct device *dev) +__initfunc(int wd_probe(struct device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -107,7 +108,7 @@ } #endif -int wd_probe1(struct device *dev, int ioaddr) +__initfunc(int wd_probe1(struct device *dev, int ioaddr)) { int i; int checksum = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/net/x25_asy.c linux/drivers/net/x25_asy.c --- v2.1.35/linux/drivers/net/x25_asy.c Fri Apr 4 08:52:22 1997 +++ linux/drivers/net/x25_asy.c Tue Apr 22 22:42:50 1997 @@ -24,6 +24,7 @@ #include #include #include +#include #include "x25_asy.h" typedef struct x25_ctrl { @@ -808,7 +809,7 @@ #ifdef MODULE static int x25_asy_init_ctrl_dev(void) #else /* !MODULE */ -int x25_asy_init_ctrl_dev(struct device *dummy) +__initfunc(int x25_asy_init_ctrl_dev(struct device *dummy)) #endif /* !MODULE */ { int status; diff -u --recursive --new-file v2.1.35/linux/drivers/net/znet.c linux/drivers/net/znet.c --- v2.1.35/linux/drivers/net/znet.c Sun Feb 2 05:18:43 1997 +++ linux/drivers/net/znet.c Tue Apr 22 22:42:50 1997 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -199,7 +200,7 @@ BIOS area. We just scan for the signature, and pull the vital parameters out of the structure. */ -int znet_probe(struct device *dev) +__initfunc(int znet_probe(struct device *dev)) { int i; struct netidblk *netinfo; diff -u --recursive --new-file v2.1.35/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.1.35/linux/drivers/pci/pci.c Fri Apr 4 08:52:22 1997 +++ linux/drivers/pci/pci.c Tue Apr 22 15:32:00 1997 @@ -261,6 +261,7 @@ DEVICE( INTEL, INTEL_82371SB_1,"82371SB Natoma/Triton II PIIX3"), DEVICE( INTEL, INTEL_82371SB_2,"82371SB Natoma/Triton II PIIX3"), DEVICE( INTEL, INTEL_82437VX, "82437VX Triton II"), + DEVICE( INTEL, INTEL_82371AB, "82371AB 430TX PIIX4"), DEVICE( INTEL, INTEL_P6, "Orion P6"), DEVICE( KTI, KTI_ET32P2, "ET32P2"), DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"), diff -u --recursive --new-file v2.1.35/linux/drivers/pnp/BUGS-parport linux/drivers/pnp/BUGS-parport --- v2.1.35/linux/drivers/pnp/BUGS-parport Sun Apr 13 10:18:21 1997 +++ linux/drivers/pnp/BUGS-parport Thu Apr 17 14:48:53 1997 @@ -1,8 +1,6 @@ Currently known (or at least suspected) bugs in parport: -o /proc/parport is buggy under 2.0.29 (ls /proc/parport/0 gives no such - file or directory). David has suggested a fix for this. [/proc/parport - has been temporarily taken out] +o /proc/parport is untested under 2.0.XX o SCSI aborts for PPA under 2.0.29 [reported by jmr]. Under investigation. diff -u --recursive --new-file v2.1.35/linux/drivers/pnp/Makefile linux/drivers/pnp/Makefile --- v2.1.35/linux/drivers/pnp/Makefile Sun Apr 13 10:18:21 1997 +++ linux/drivers/pnp/Makefile Thu Apr 17 14:48:53 1997 @@ -23,14 +23,20 @@ MIX_OBJS := ifeq ($(CONFIG_PNP_PARPORT),y) - L_OBJS += parport_share.o parport_procfs.o + L_OBJS += parport_share.o + ifeq ($(CONFIG_PROC_FS),y) + L_OBJS += parport_procfs.o + endif ifeq ($(CONFIG_PNP_PARPORT_AUTOPROBE),y) L_OBJS += parport_probe.o endif LX_OBJS += parport_init.o else ifeq ($(CONFIG_PNP_PARPORT),m) - MI_OBJS += parport_share.o parport_procfs.o + MI_OBJS += parport_share.o + ifneq ($(CONFIG_PROC_FS),n) + MI_OBJS += parport_procfs.o + endif ifeq ($(CONFIG_PNP_PARPORT_AUTOPROBE),y) MI_OBJS += parport_probe.o endif diff -u --recursive --new-file v2.1.35/linux/drivers/pnp/TODO-parport linux/drivers/pnp/TODO-parport --- v2.1.35/linux/drivers/pnp/TODO-parport Sun Apr 13 10:18:21 1997 +++ linux/drivers/pnp/TODO-parport Thu Apr 17 14:48:53 1997 @@ -2,31 +2,9 @@ 0. Fix the bugs (see BUGS-parport). -1. Write a /proc interface for parport. As a starting point, we could - probably have something like this: +1. Proper documentation. - /proc/parport/N/hardware - - Details of the port hardware - chipset, capabilities and so on. - Read-only. - - /proc/parport/N/irq - - IRQ number of the port. Read-write. - - /proc/parport/N/devices - - List of devices connected to this bus, with the currently active - one marked in some way. Probably you'd have the device in the - first column, and '*' (for the current device) or '-' (for a - lurker) in the second column. - - NOTE: The directory structure has been coded -- but the files are - missing ... - -2. Proper documentation. - -3. Overhaul lp.c: +2. Overhaul lp.c: a) It's a mess, and there is a lot of code duplication. @@ -40,4 +18,4 @@ bits when they have something to say. We should read out and deal with (maybe just log) whatever the printer wants to tell the world. -4. Assimilate more drivers. +3. Assimilate more drivers. diff -u --recursive --new-file v2.1.35/linux/drivers/pnp/parport_init.c linux/drivers/pnp/parport_init.c --- v2.1.35/linux/drivers/pnp/parport_init.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/pnp/parport_init.c Tue Apr 22 09:32:11 1997 @@ -1,4 +1,4 @@ -/* $Id: parport_init.c,v 1.1.2.4 1997/04/01 18:19:10 phil Exp $ +/* $Id: parport_init.c,v 1.3.2.4 1997/04/16 21:20:44 phil Exp $ * Parallel-port initialisation code. * * Authors: David Campbell @@ -26,8 +26,8 @@ #include "parport_ll_io.h" static int io[PARPORT_MAX] = { 0, }; -static int irq[PARPORT_MAX] = { -1, }; -static int dma[PARPORT_MAX] = { -1, }; +static int irq[PARPORT_MAX] = { PARPORT_IRQ_NONE, }; +static int dma[PARPORT_MAX] = { PARPORT_DMA_NONE, }; /****************************************************** * DMA detection section: @@ -76,7 +76,7 @@ return dma; } -static int parport_detect_dma_transfer(int dma,int size) +static int parport_detect_dma_transfer(int dma,int size,int *resid) { int i,n,retv; int count=0; @@ -88,10 +88,11 @@ clear_dma_ff(i); n = get_dma_residue(i); if (n != size) { + *resid = n; retv = i; if (count > 0) { retv = -1; /* Multiple DMA's */ - printk("Multiple DMA detected.\n"); + printk(KERN_ERR "parport: multiple DMA detected. Huh?\n"); } count++; } @@ -118,7 +119,7 @@ return dma; } -/* Only called if port support ECP mode. +/* Only called if port supports ECP mode. * * The only restriction on DMA channels is that it has to be * between 0 to 7 (inclusive). Used only in an ECP mode, DMAs are @@ -146,12 +147,11 @@ char *buff; retv = programmable_dma_support(pb); - if( retv != -1 ) + if (retv != -1) return retv; - buff = kmalloc(16, GFP_KERNEL | GFP_DMA); - if( !buff ){ - printk("parport: memory squezze\n"); + if (!(buff = kmalloc(2048, GFP_KERNEL | GFP_DMA))) { + printk(KERN_ERR "parport: memory squeeze\n"); return -1; } @@ -160,24 +160,26 @@ w_ecr(pb, 0xc0); /* ECP MODE */ w_ctr(pb, dsr_read ); - dma=parport_prepare_dma(buff,8); + dma=parport_prepare_dma(buff,1000); w_ecr(pb, 0xd8); /* ECP FIFO + enable DMA */ parport_enable_dma(dma); - udelay(30); /* Give some for DMA tranfer */ - retv = parport_detect_dma_transfer(dma,8); + udelay(500); /* Give some for DMA tranfer */ + retv = parport_detect_dma_transfer(dma,1000,&pb->speed); + pb->speed = pb->speed * 2000; /* 500uSec * 2000 = 1sec */ /* * National Semiconductors only supports DMA tranfers * in ECP MODE */ - if( retv == -1 ){ + if (retv == -1) { w_ecr(pb, 0x60); /* ECP MODE */ w_ctr(pb, dsr_read ); - dma=parport_prepare_dma(buff,8); + dma=parport_prepare_dma(buff,1000); w_ecr(pb, 0x68); /* ECP FIFO + enable DMA */ parport_enable_dma(dma); - udelay(30); /* Give some for DMA tranfer */ - retv = parport_detect_dma_transfer(dma,8); + udelay(500); /* Give some for DMA tranfer */ + retv = parport_detect_dma_transfer(dma,1000,&pb->speed); + pb->speed = pb->speed * 2000; /* 500uSec * 2000 = 1sec */ } kfree(buff); @@ -198,10 +200,10 @@ { int r; - if( !(r_str(pb) & 0x01) ) + if (!(r_str(pb) & 0x01)) return 1; - /* To clear timeout some chip requiere double read */ + /* To clear timeout some chips require double read */ r_str(pb); r = r_str(pb); w_str(pb, r | 0x01); /* Some reset by writing 1 */ @@ -213,23 +215,18 @@ /* - * Checks for por existence, all ports support SPP MODE + * Checks for port existence, all ports support SPP MODE */ static int parport_SPP_supported(struct parport *pb) { - int r,rr; - /* Do a simple read-write test to make sure the port exists. */ + w_dtr(pb, 0xaa); - r = r_dtr(pb); + if (r_dtr(pb) != 0xaa) return 0; w_dtr(pb, 0x55); - rr = r_dtr(pb); - - if (r != 0xaa || rr != 0x55) { - return 0; - } - + if (r_dtr(pb) != 0x55) return 0; + return PARPORT_MODE_SPP; } @@ -249,23 +246,20 @@ { int r; - if( pb->base == 0x3BC ) - return 0; - r= r_ctr(pb); - if( (r_ecr(pb) & 0x03) == (r & 0x03) ){ + if ((r_ecr(pb) & 0x03) == (r & 0x03)) { w_ctr(pb, r ^ 0x03 ); /* Toggle bits 0-1 */ r= r_ctr(pb); - if( (r_ecr(pb) & 0x03) == (r & 0x03) ) + if ((r_ecr(pb) & 0x03) == (r & 0x03)) return 0; /* Sure that no ECR register exists */ } - if( (r_ecr(pb) & 0x03 ) != 0x01 ) + if ((r_ecr(pb) & 0x03 ) != 0x01) return 0; w_ecr(pb,0x34); - if( r_ecr(pb) != 0x35 ) + if (r_ecr(pb) != 0x35) return 0; w_ecr(pb,pb->ecr); @@ -278,20 +272,22 @@ { int i; - if( !(pb->modes & PARPORT_MODE_ECR) ) + /* If there is no ECR, we have no hope of supporting ECP. */ + if (!(pb->modes & PARPORT_MODE_ECR)) return 0; + /* - * Usign LGS chipset it uses ECR register, but + * Using LGS chipset it uses ECR register, but * it doesn't support ECP or FIFO MODE */ - w_ecr(pb,0xc0); /* TEST FIFO */ - for( i=0 ; i < 1024 && (r_ecr(pb) & 0x01) ; i++ ) + w_ecr(pb, 0xc0); /* TEST FIFO */ + for (i=0; i < 1024 && (r_ecr(pb) & 0x01); i++) w_fifo(pb, 0xaa); - w_ecr(pb,pb->ecr); + w_ecr(pb, pb->ecr); - if( i >= 1024 ) + if (i == 1024) return 0; return PARPORT_MODE_ECP; @@ -311,11 +307,8 @@ */ static int parport_EPP_supported(struct parport *pb) { - if( pb->base == 0x3BC ) - return 0; - /* If EPP timeout bit clear then EPP available */ - if( !epp_clear_timeout(pb) ) + if (!epp_clear_timeout(pb)) return 0; /* No way to clear timeout */ w_ctr(pb, r_ctr(pb) | 0x20); @@ -325,7 +318,7 @@ r_epp(pb); udelay(30); /* Wait for possible EPP timeout */ - if( r_str(pb) & 0x01 ){ + if (r_str(pb) & 0x01) { epp_clear_timeout(pb); return PARPORT_MODE_EPP; } @@ -337,7 +330,7 @@ { int mode; - if( !(pb->modes & PARPORT_MODE_ECR) ) + if (!(pb->modes & PARPORT_MODE_ECR)) return 0; /* Search for SMC style EPP+ECP mode */ @@ -345,47 +338,55 @@ mode = parport_EPP_supported(pb); - w_ecr(pb,pb->ecr); + w_ecr(pb, pb->ecr); - if( mode ) + if (mode) return PARPORT_MODE_ECPEPP; return 0; } -/* Detect LP_PS2 support - * Bit 5 (0x20) sets the PS/2 data direction, setting this high - * allows us to read data from the data lines, old style SPP ports - * will return 0xff. This may not be reliable if there is a - * peripheral attached to the port. +/* Detect PS/2 support. + * + * Bit 5 (0x20) sets the PS/2 data direction; setting this high + * allows us to read data from the data lines. In theory we would get back + * 0xff but any peripheral attached to the port may drag some or all of the + * lines down to zero. So if we get back anything that isn't the contents + * of the data register we deem PS/2 support to be present. + * + * Some SPP ports have "half PS/2" ability - you can't turn off the line + * drivers, but an external peripheral with sufficiently beefy drivers of + * its own can overpower them and assert its own levels onto the bus, from + * where they can then be read back as normal. Ports with this property + * and the right type of device attached are likely to fail the SPP test, + * (as they will appear to have stuck bits) and so the fact that they might + * be misdetected here is rather academic. */ + static int parport_PS2_supported(struct parport *pb) { - int r,rr; - + int ok = 0; + epp_clear_timeout(pb); - w_ctr(pb, pb->ctr | 0x20); /* Tri-state the buffer */ + w_ctr(pb, pb->ctr | 0x20); /* try to tri-state the buffer */ - w_dtr(pb, 0xAA); - r = r_dtr(pb); - w_dtr(pb, 0x55); - rr = r_dtr(pb); - - w_ctr(pb, pb->ctr); /* Reset CTR register */ + if (r_dtr(pb) != 0x55) ok++; - if (r != 0xAA || rr != 0x55 ) - return PARPORT_MODE_PS2; + w_dtr(pb, 0xaa); + if (r_dtr(pb) != 0xaa) ok++; - return 0; + w_ctr(pb, pb->ctr); /* cancel input mode */ + + return ok?PARPORT_MODE_PS2:0; } static int parport_ECPPS2_supported(struct parport *pb) { int mode; - if( !(pb->modes & PARPORT_MODE_ECR) ) + if (!(pb->modes & PARPORT_MODE_ECR)) return 0; w_ecr(pb, 0x20); @@ -402,15 +403,19 @@ /****************************************************** * IRQ detection section: - */ -/* + * * This code is for detecting ECP interrupts (due to problems with the * monolithic interrupt probing routines). * * In short this is a voting system where the interrupt with the most * "votes" is the elected interrupt (it SHOULD work...) + * + * This is horribly x86-specific at the moment. I'm not convinced it + * belongs at all. */ + static int intr_vote[16]; + static void parport_vote_intr_func(int irq, void *dev_id, struct pt_regs *regs) { intr_vote[irq]++; @@ -434,17 +439,16 @@ static int close_intr_election(long tmp) { - long max_vote = 0; - int irq = -1; + int irq = PARPORT_IRQ_NONE; int i; /* We ignore the timer - irq 0 */ for (i = 1; i < 16; i++) if (tmp & (1 << i)) { - if (intr_vote[i] > max_vote) { - if (max_vote) - return -1; - max_vote = intr_vote[i]; + if (intr_vote[i]) { + if (irq != PARPORT_IRQ_NONE) + /* More than one interrupt */ + return PARPORT_IRQ_NONE; irq = i; } free_irq(i, intr_vote); @@ -488,7 +492,7 @@ irqs = open_intr_election(); w_ecr(pb, 0x00); /* Reset FIFO */ - w_ctr(pb, pb->ctr ); /* Force direction = 0 */ + w_ctr(pb, pb->ctr ); /* Force direction = 0 */ w_ecr(pb, 0xd0); /* TEST FIFO + nErrIntrEn */ /* If Full FIFO sure that WriteIntrThresold is generated */ @@ -497,8 +501,6 @@ } pb->irq = close_intr_election(irqs); - if (pb->irq == 0) - pb->irq = -1; /* No interrupt detected */ w_ecr(pb, pb->ecr); @@ -506,7 +508,7 @@ } /* - * It's called only if supports EPP on National Semiconductors + * This detection seems that only works in National Semiconductors * This doesn't work in SMC, LGS, and Winbond */ static int irq_probe_EPP(struct parport *pb) @@ -535,8 +537,6 @@ udelay(20); pb->irq = close_intr_election(irqs); - if (pb->irq == 0) - pb->irq = -1; /* No interrupt detected */ w_ctr(pb,pb->ctr); @@ -572,7 +572,7 @@ pb->irq = probe_irq_off(irqs); if (pb->irq <= 0) - pb->irq = -1; /* No interrupt detected */ + pb->irq = PARPORT_IRQ_NONE; /* No interrupt detected */ w_ctr(pb,pb->ctr); @@ -583,18 +583,18 @@ * such as sound cards and network cards seem to like using the * printer IRQs. * - * When LP_ECP is available we can autoprobe for IRQs. + * When ECP is available we can autoprobe for IRQs. * NOTE: If we can autoprobe it, we can register the IRQ. */ static int parport_irq_probe(struct parport *pb) { - if( pb->modes & PARPORT_MODE_ECR ) + if (pb->modes & PARPORT_MODE_ECR) pb->irq = programmable_irq_support(pb); - if( pb->modes & PARPORT_MODE_ECP ) + if (pb->modes & PARPORT_MODE_ECP) pb->irq = irq_probe_ECP(pb); - if( pb->irq == -1 && (pb->modes & PARPORT_MODE_ECPEPP)){ + if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_ECPEPP)) { w_ecr(pb,0x80); pb->irq = irq_probe_EPP(pb); w_ecr(pb,pb->ecr); @@ -602,12 +602,12 @@ epp_clear_timeout(pb); - if( pb->irq == -1 && (pb->modes & PARPORT_MODE_EPP)) + if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_EPP)) pb->irq = irq_probe_EPP(pb); epp_clear_timeout(pb); - if( pb->irq == -1 ) + if (pb->irq == PARPORT_IRQ_NONE) pb->irq = irq_probe_SPP(pb); return pb->irq; @@ -618,12 +618,12 @@ { /* Check some parameters */ if (dma < -2) { - printk("parport: Invalid DMA[%d] at base 0x%lx\n",dma,base); + printk(KERN_ERR "parport: Invalid DMA[%d] at base 0x%lx\n",dma,base); return 0; } if (irq < -2) { - printk("parport: Invalid IRQ[%d] at base 0x%lx\n",irq,base); + printk(KERN_ERR "parport: Invalid IRQ[%d] at base 0x%lx\n",irq,base); return 0; } @@ -643,7 +643,7 @@ pb->name = kmalloc(15, GFP_KERNEL); if (!pb->name) { - printk("parport: memory squeeze\n"); + printk(KERN_ERR "parport: memory squeeze\n"); return 0; } sprintf(pb->name, "parport%d", count); @@ -657,12 +657,15 @@ } pb->modes |= PARPORT_MODE_SPP; /* All ports support SPP mode. */ - pb->modes |= parport_ECR_present(pb); - pb->modes |= parport_ECP_supported(pb); pb->modes |= parport_PS2_supported(pb); - pb->modes |= parport_ECPPS2_supported(pb); - pb->modes |= parport_EPP_supported(pb); - pb->modes |= parport_ECPEPP_supported(pb); + + if (pb->base != 0x3bc) { + pb->modes |= parport_ECR_present(pb); + pb->modes |= parport_ECP_supported(pb); + pb->modes |= parport_ECPPS2_supported(pb); + pb->modes |= parport_EPP_supported(pb); + pb->modes |= parport_ECPEPP_supported(pb); + } /* Now register regions */ if ((pb->modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) && @@ -678,17 +681,17 @@ /* DMA check */ if (pb->modes & PARPORT_MODE_ECP) { - if (pb->dma == -1) + if (pb->dma == PARPORT_DMA_NONE) pb->dma = parport_dma_probe(pb); else if (pb->dma == -2) - pb->dma = -1; + pb->dma = PARPORT_DMA_NONE; } /* IRQ check */ - if (pb->irq == -1) + if (pb->irq == PARPORT_IRQ_NONE) pb->irq = parport_irq_probe(pb); else if (pb->irq == -2) - pb->irq = -1; + pb->irq = PARPORT_IRQ_NONE; return 1; } @@ -700,7 +703,7 @@ { if (ints[0] == 0 || ints[1] == 0) { /* Disable parport if "parport=" or "parport=0" in cmdline */ - io[0] = -2; + io[0] = PARPORT_DISABLE; return; } if (parport_setup_ptr < PARPORT_MAX) { @@ -738,17 +741,20 @@ struct parport *pb; printk(KERN_INFO "Parallel port sharing: %s\n", - "$Revision: 1.1.2.4 $"); + "$Revision: 1.3.2.4 $"); - if (io[0] == -2) return 1; + if (io[0] == PARPORT_DISABLE) return 1; - /* Register /proc/parport */ - parport_proc_register(NULL); +#ifdef CONFIG_PROC_FS + parport_proc_init(); +#endif /* Run probes to ensure parport does exist */ #define PORT(a,b,c) \ if ((pb = parport_register_port((a), (b), (c)))) \ parport_destroy(pb); + + if (io[0]) { /* If the user specified any ports, use them */ int i; @@ -757,16 +763,22 @@ } } else { /* Go for the standard ports. */ - PORT(0x378, -1, -1); - PORT(0x278, -1, -1); - PORT(0x3bc, -1, -1); + PORT(0x378, PARPORT_IRQ_NONE, PARPORT_DMA_NONE); + PORT(0x278, PARPORT_IRQ_NONE, PARPORT_DMA_NONE); + PORT(0x3bc, PARPORT_IRQ_NONE, PARPORT_DMA_NONE); #undef PORT } +#if defined(CONFIG_PNP_PARPORT_AUTOPROBE) || defined(CONFIG_PROC_FS) + for (pb = parport_enumerate(); pb; pb = pb->next) { #ifdef CONFIG_PNP_PARPORT_AUTOPROBE - for (pb = parport_enumerate(); pb; pb = pb->next) parport_probe_one(pb); #endif +#ifdef CONFIG_PROC_FS + parport_proc_register(pb); +#endif + } +#endif return 0; } @@ -784,7 +796,7 @@ kfree(port); } - parport_proc_unregister(NULL); + parport_proc_cleanup(); } #endif diff -u --recursive --new-file v2.1.35/linux/drivers/pnp/parport_procfs.c linux/drivers/pnp/parport_procfs.c --- v2.1.35/linux/drivers/pnp/parport_procfs.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/pnp/parport_procfs.c Thu Apr 17 14:48:53 1997 @@ -1,4 +1,4 @@ -/* $Id: parport_procfs.c,v 1.1.2.2 1997/03/26 17:50:36 phil Exp $ +/* $Id: parport_procfs.c,v 1.3.2.6 1997/04/16 21:30:38 phil Exp $ * Parallel port /proc interface code. * * Authors: David Campbell @@ -21,108 +21,320 @@ #include #include -#ifdef CONFIG_PROC_FS #include -#endif #include +#include "parport_ll_io.h" + +#undef PARPORT_INCLUDE_BENCH -#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED) +struct proc_dir_entry *base=NULL; -/************************************************/ -static long proc_readparport(struct inode * inode, struct file * file, - char * buf, unsigned long count) +void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs); + +static int irq_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) { - printk("proc_readparport\n"); - return 0; + int newirq; + struct parport *pp = (struct parport *)data; + + if (count > 4 ) /* more than 4 digits for a irq 0x?? 0?? ?? */ + return(-EOVERFLOW); + + if (buffer[0] < 32 || !strncmp(buffer, "none", 4)) { + newirq = PARPORT_IRQ_NONE; + } else { + if (buffer[0] == '0') { + if( buffer[1] == 'x' ) + newirq = simple_strtoul(&buffer[2],0,16); + else + newirq = simple_strtoul(&buffer[1],0,8); + } else { + newirq = simple_strtoul(buffer,0,10); + } + } + + if (pp->irq != PARPORT_IRQ_NONE && !(pp->flags & PARPORT_FLAG_COMA)) + free_irq(pp->irq, pp); + + pp->irq = newirq; + + if (pp->irq != PARPORT_IRQ_NONE && !(pp->flags & PARPORT_FLAG_COMA)) { + struct ppd *pd = pp->cad; + + if (pd == NULL) { + pd = pp->devices; + if (pd != NULL) + request_irq(pp->irq, pd->irq_func ? + pd->irq_func : + parport_null_intr_func, + SA_INTERRUPT, pd->name, pd->port); + } else { + request_irq(pp->irq, pd->irq_func ? pd->irq_func : + parport_null_intr_func, + SA_INTERRUPT, pp->name, pd->port); + } + } + + return count; } -static long proc_writeparport(struct inode * inode, struct file * file, - const char * buf, unsigned long count) +static int irq_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - printk("proc_writeparport\n"); + struct parport *pp = (struct parport *)data; + int len; - return 0; + if (pp->irq == PARPORT_IRQ_NONE) + len = sprintf(page, "none\n"); + else + len = sprintf(page, "%d\n", pp->irq); + + *start = 0; + *eof = 1; + return len; } -static long long proc_parportlseek(struct inode * inode, struct file * file, - long long offset, int orig) +static int devices_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - switch (orig) { - case 0: - file->f_pos = offset; - return(file->f_pos); - case 1: - file->f_pos += offset; - return(file->f_pos); - case 2: - return(-EINVAL); - default: - return(-EINVAL); - } -} - -static struct file_operations proc_dir_operations = { - proc_parportlseek, /* lseek */ - proc_readparport, /* read */ - proc_writeparport, /* write */ - proc_readdir, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -/************************************************/ -static struct inode_operations parport_proc_dir_inode_operations = { - &proc_dir_operations, /* default net directory file-ops */ - NULL, /* create */ - proc_lookup, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL /* permission */ -}; - -static struct proc_dir_entry proc_root_parport = { - PROC_PARPORT, 7, "parport", - S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, - 0, &parport_proc_dir_inode_operations, - NULL, NULL, - NULL, &proc_root, NULL, - NULL, NULL -}; + struct parport *pp = (struct parport *)data; + struct ppd *pd1; + int len=0; + + for (pd1 = pp->devices; pd1 ; pd1 = pd1->next) { + if (pd1 == pp->cad) + len += sprintf(page+len, "+"); + else + len += sprintf(page+len, " "); + + len += sprintf(page+len, "%s",pd1->name); + + if (pd1 == pp->lurker) + len += sprintf(page+len, " LURK"); + + len += sprintf(page+len,"\n"); + } + + *start = 0; + *eof = 1; + return len; +} + +static int hardware_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct parport *pp = (struct parport *)data; + int len=0; + + len += sprintf(page+len, "base:\t0x%x\n",pp->base); + if (pp->irq == PARPORT_IRQ_NONE) + len += sprintf(page+len, "irq:\tnone\n"); + else + len += sprintf(page+len, "irq:\t%d\n",pp->irq); + len += sprintf(page+len, "dma:\t%d\n",pp->dma); + + len += sprintf(page+len, "modes:\t"); + { +#define printmode(x) {if(pp->modes&PARPORT_MODE_##x){len+=sprintf(page+len,"%s%s",f?",":"",#x);f++;}} + int f = 0; + printmode(SPP); + printmode(PS2); + printmode(EPP); + printmode(ECP); + printmode(ECPEPP); + printmode(ECPPS2); +#undef printmode + } + len += sprintf(page+len, "\n"); + + len += sprintf(page+len, "mode:\t"); + if (pp->modes & PARPORT_MODE_ECR) { + switch (r_ecr(pp) >> 5) { + case 0: + len += sprintf(page+len, "SPP"); + if( pp->modes & PARPORT_MODE_PS2 ) + len += sprintf(page+len, ",PS2"); + if( pp->modes & PARPORT_MODE_EPP ) + len += sprintf(page+len, ",EPP"); + break; + case 1: + len += sprintf(page+len, "ECPPS2"); + break; + case 2: + len += sprintf(page+len, "DATAFIFO"); + break; + case 3: + len += sprintf(page+len, "ECP"); + break; + case 4: + len += sprintf(page+len, "ECPEPP"); + break; + case 5: + len += sprintf(page+len, "Reserved?"); + break; + case 6: + len += sprintf(page+len, "TEST"); + break; + case 7: + len += sprintf(page+len, "Configuration"); + break; + } + } else { + len += sprintf(page+len, "SPP"); + if (pp->modes & PARPORT_MODE_PS2) + len += sprintf(page+len, ",PS2"); + if (pp->modes & PARPORT_MODE_EPP) + len += sprintf(page+len, ",EPP"); + } + len += sprintf(page+len, "\n"); + +#if 0 + /* Now no detection, please fix with an external function */ + len += sprintf(page+len, "chipset:\tunknown\n"); #endif +#ifdef PARPORT_INCLUDE_BENCHMARK + if (pp->speed) + len += sprintf(page+len, "bench:\t%d Bytes/s\n",pp->speed); + else + len += sprintf(page+len, "bench:\tunknown\n"); +#endif + + *start = 0; + *eof = 1; + return len; +} + +static struct proc_dir_entry *new_proc_entry(const char *name, mode_t mode, + struct proc_dir_entry *parent, + unsigned short ino) +{ + struct proc_dir_entry *ent; + + ent = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL); + if (!ent) + return NULL; + memset(ent, 0, sizeof(struct proc_dir_entry)); + + if (mode == S_IFDIR) + mode |= S_IRUGO | S_IXUGO; + else if (mode == 0) + mode = S_IFREG | S_IRUGO; + + + ent->low_ino = ino; + ent->name = name; + ent->namelen = strlen(name); + ent->mode = mode; + if (S_ISDIR(mode)) + ent->nlink = 2; + else + ent->nlink = 1; + + proc_register(parent, ent); + + return ent; +} + + +int parport_proc_init() +{ + base = new_proc_entry("parport", S_IFDIR, &proc_root,PROC_PARPORT); + + if (base) + return 1; + else { + printk(KERN_ERR "parport: Error creating proc entry /proc/parport\n"); + return 0; + } +} + +int parport_proc_cleanup() +{ + if (base) + proc_unregister(&proc_root,base->low_ino); + + base = NULL; + + return 0; +} int parport_proc_register(struct parport *pp) { -#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED) - return proc_register(&proc_root, &proc_root_parport); -#else + struct proc_dir_entry *ent; + static int conta=0; + char *name; + + memset(&pp->pdir,0,sizeof(struct parport_dir)); + + if (!base) { + printk(KERN_ERR "parport: Error entry /proc/parport, not generated?\n"); + return 1; + } + + name = pp->pdir.name; + sprintf(name,"%d",conta++); + + ent = new_proc_entry(name, S_IFDIR, base,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s\n",name); + return 1; + } + pp->pdir.entry = ent; + + ent = new_proc_entry("irq", S_IFREG | S_IRUGO | S_IWUSR, pp->pdir.entry,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/irq\n",name); + return 1; + } + ent->read_proc = irq_read_proc; + ent->write_proc= irq_write_proc; + ent->data = pp; + pp->pdir.irq = ent; + + ent = new_proc_entry("devices", 0, pp->pdir.entry,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/devices\n",name); + return 1; + } + ent->read_proc = devices_read_proc; + ent->data = pp; + pp->pdir.devices = ent; + + ent = new_proc_entry("hardware", 0, pp->pdir.entry,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/hardware\n",name); + return 1; + } + ent->read_proc = hardware_read_proc; + ent->data = pp; + pp->pdir.hardware = ent; return 0; -#endif } -void parport_proc_unregister(struct parport *pp) +int parport_proc_unregister(struct parport *pp) { -#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED) - if( pp ){ - proc_unregister(&proc_root_parport, pp->proc_dir->low_ino); - kfree(pp->proc_dir); - }else{ - proc_unregister(&proc_root, proc_root_parport.low_ino); + if (pp->pdir.entry) { + if (pp->pdir.irq) { + proc_unregister(pp->pdir.entry, pp->pdir.irq->low_ino); + kfree(pp->pdir.irq); + } + + if (pp->pdir.devices) { + proc_unregister(pp->pdir.entry, + pp->pdir.devices->low_ino); + kfree(pp->pdir.devices); + } + + if (pp->pdir.hardware) { + proc_unregister(pp->pdir.entry, + pp->pdir.hardware->low_ino); + kfree(pp->pdir.hardware); + } + + proc_unregister(base, pp->pdir.entry->low_ino); + kfree(pp->pdir.entry); } -#endif + + return 0; } diff -u --recursive --new-file v2.1.35/linux/drivers/pnp/parport_share.c linux/drivers/pnp/parport_share.c --- v2.1.35/linux/drivers/pnp/parport_share.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/pnp/parport_share.c Thu Apr 17 14:48:53 1997 @@ -1,4 +1,4 @@ -/* $Id: parport_share.c,v 1.1.2.4 1997/04/01 18:19:11 phil Exp $ +/* $Id: parport_share.c,v 1.3.2.5 1997/04/16 21:20:44 phil Exp $ * Parallel-port resource manager code. * * Authors: David Campbell @@ -21,6 +21,8 @@ #include #include +#undef PARPORT_PARANOID + #include "parport_ll_io.h" static struct parport *portlist = NULL, *portlist_tail = NULL; @@ -36,7 +38,7 @@ return portlist; } -static void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) +void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) { /* NULL function - Does nothing */ return; @@ -85,7 +87,7 @@ } memcpy(tmp, &new, sizeof(struct parport)); - if (new.irq != -1) { + if (new.irq != PARPORT_IRQ_NONE) { if (request_irq(new.irq, parport_null_intr_func, SA_INTERRUPT, new.name, tmp) != 0) { printk(KERN_INFO "%s: unable to claim IRQ %d\n", @@ -197,11 +199,10 @@ return NULL; } } - if (port->irq != -1) { - if (request_irq(port->irq, - parport_null_intr_func, - SA_INTERRUPT, port->name, - port) != 0) { + if (port->irq != PARPORT_IRQ_NONE) { + if (request_irq(port->irq, parport_null_intr_func, + SA_INTERRUPT, port->name, + port) != 0) { release_region(port->base, port->size); if( port->modes & PARPORT_MODE_ECR ) release_region(port->base+0x400, 3); @@ -213,7 +214,6 @@ port->flags &= ~PARPORT_FLAG_COMA; } - tmp = kmalloc(sizeof(struct ppd), GFP_KERNEL); tmp->name = (char *) name; tmp->port = port; @@ -251,8 +251,7 @@ port = dev->port; if (port->cad == dev) { - printk(KERN_INFO "%s: refused to unregister currently active device %s\n", - port->name, dev->name); + printk(KERN_INFO "%s: refused to unregister currently active device %s\n", port->name, dev->name); return; } @@ -299,8 +298,9 @@ if (dev->port->modes & PARPORT_MODE_ECR) dev->port->cad->ecr = dev->port->ecr = r_ecr(dev->port); - dev->port->cad->ctr = dev->port->ctr = - r_ctr(dev->port); + if (dev->port->modes & PARPORT_MODE_SPP) + dev->port->cad->ctr = dev->port->ctr = + r_ctr(dev->port); } else return -EAGAIN; } @@ -326,7 +326,8 @@ /* Restore control registers */ if (dev->port->modes & PARPORT_MODE_ECR) if (dev->ecr != dev->port->ecr) w_ecr(dev->port, dev->ecr); - if (dev->ctr != dev->port->ctr) w_ctr(dev->port, dev->ctr); + if (dev->port->modes & PARPORT_MODE_SPP) + if (dev->ctr != dev->port->ctr) w_ctr(dev->port, dev->ctr); return 0; } @@ -337,8 +338,7 @@ /* Make sure that dev is the current device */ if (dev->port->cad != dev) { - printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", - dev->port->name, dev->name); + printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", dev->port->name, dev->name); return; } dev->port->cad = NULL; @@ -346,12 +346,13 @@ /* Save control registers */ if (dev->port->modes & PARPORT_MODE_ECR) dev->ecr = dev->port->ecr = r_ecr(dev->port); - dev->ctr = dev->port->ctr = r_ctr(dev->port); + if (dev->port->modes & PARPORT_MODE_SPP) + dev->ctr = dev->port->ctr = r_ctr(dev->port); if (dev->port->irq >= 0) { free_irq(dev->port->irq, dev->port); request_irq(dev->port->irq, parport_null_intr_func, - SA_INTERRUPT, dev->port->name, dev->port); + SA_INTERRUPT, dev->port->name, dev->port); } /* Walk the list, offering a wakeup callback to everybody other @@ -384,16 +385,22 @@ if (dev->port->lurker && (dev->port->lurker != dev)) { if (dev->port->lurker->wakeup) { dev->port->lurker->wakeup(dev->port->lurker->private); - return; + } +#ifdef PARPORT_PARANOID + else { /* can't happen */ + printk(KERN_DEBUG + "%s (%s): lurker's wakeup callback went away!\n", + dev->port->name, dev->name); } - printk(KERN_DEBUG - "%s (%s): lurker's wakeup callback went away!\n", - dev->port->name, dev->name); +#endif } } /* The following read funktions are an implementation of a status readback * and device id request confirming to IEEE1284-1994. + * + * These probably ought to go in some seperate file, so people like the SPARC + * don't have to pull them in. */ /* Wait for Status line(s) to change in 35 ms - see IEEE1284-1994 page 24 to diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/Config.in linux/drivers/sbus/char/Config.in --- v2.1.35/linux/drivers/sbus/char/Config.in Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/Config.in Thu Apr 17 13:20:46 1997 @@ -10,6 +10,7 @@ bool 'bwtwo support' SUN_FB_BWTWO bool 'leo/zx support' SUN_FB_LEO bool 'weitek P9X00 support' TADPOLE_FB_WEITEK + bool 'creator support' SUN_FB_CREATOR if [ "$TADPOLE_FB_WEITEK" = "n" ]; then fbs=$SUN_FB_CGSIX fbs=$fbs$SUN_FB_TCX @@ -34,6 +35,7 @@ define_bool SUN_FB_BWTWO y define_bool SUN_FB_LEO y define_bool TADPOLE_FB_WEITEK y + define_bool SUN_FB_CREATOR y fi comment 'Misc Linux/SPARC drivers' diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/Makefile linux/drivers/sbus/char/Makefile --- v2.1.35/linux/drivers/sbus/char/Makefile Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/Makefile Thu Apr 17 13:20:46 1997 @@ -31,6 +31,9 @@ ifdef TADPOLE_FB_WEITEK FB_OBJS += weitek.o endif +ifdef SUN_FB_CREATOR + FB_OBJS += creator.o +endif #ifdef SUN_FB_FAST_ONE # FB_OBJS += sun_8bit_fast1.o #endif diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c --- v2.1.35/linux/drivers/sbus/char/bpp.c Thu Mar 27 14:40:05 1997 +++ linux/drivers/sbus/char/bpp.c Thu Apr 17 13:20:46 1997 @@ -29,6 +29,7 @@ #endif #if defined(__sparc__) +# include # include /* udelay() */ # include /* OpenProm Library */ diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/bwtwo.c linux/drivers/sbus/char/bwtwo.c --- v2.1.35/linux/drivers/sbus/char/bwtwo.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/bwtwo.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: bwtwo.c,v 1.12 1997/04/10 03:02:40 davem Exp $ +/* $Id: bwtwo.c,v 1.13 1997/04/14 17:04:55 jj Exp $ * bwtwo.c: bwtwo console driver * * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -86,7 +86,7 @@ /* This routine should also map the register if asked for, * but we don't do that yet. */ - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); r = io_remap_page_range (vma->vm_start, map_offset, map_size, vma->vm_page_prot, fb->space); if (r) return -EAGAIN; @@ -143,10 +143,10 @@ 0x10, 0x20, 0 }; -__initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, unsigned long bwtwo, int bw2_io, +__initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, u32 bwtwo, int bw2_io, struct linux_sbus_device *sbdp)) { - printk ("bwtwo%d at 0x%8.8x\n", slot, (uint)bwtwo); + printk ("bwtwo%d at 0x%8.8x\n", slot, bwtwo); fb->type.fb_cmsize = 0; fb->mmap = bwtwo_mmap; fb->loadcmap = 0; @@ -156,7 +156,7 @@ fb->unblank = bwtwo_unblank; fb->info.bwtwo.regs = - sparc_alloc_io ((u32)(bwtwo + BWTWO_REGISTER_OFFSET), + sparc_alloc_io (bwtwo + BWTWO_REGISTER_OFFSET, 0, sizeof (struct bwtwo_regs), "bwtwo_regs", bw2_io, 0); @@ -201,7 +201,7 @@ } if(!fb->base) - fb->base = (unsigned long) sparc_alloc_io((u32)bwtwo, 0, + fb->base = (unsigned long) sparc_alloc_io(bwtwo, 0, ((fb->type.fb_depth*fb->type.fb_height*fb->type.fb_width)/8), "bwtwo_fbase", bw2_io, 0); diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/cgfourteen.c linux/drivers/sbus/char/cgfourteen.c --- v2.1.35/linux/drivers/sbus/char/cgfourteen.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/cgfourteen.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: cgfourteen.c,v 1.18 1997/03/24 17:44:27 jj Exp $ +/* $Id: cgfourteen.c,v 1.19 1997/04/14 17:04:57 jj Exp $ * cgfourteen.c: Sun SparcStation console support. * * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -183,22 +183,22 @@ printk ("Wee! They are mapping the register, report this to miguel@gnu.ai.mit.edu\n"); printk ("Mapping fb->info.regs!\n"); map_size = 0x7000; - map_offset = get_phys ((uint) fb->info.cg14.regs); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs); break; case CG3_MMAP_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); break; case MDI_PLANAR_X16_MAP: map_size = ram_size/2; - map_offset = get_phys ((uint) fb->base) | 0x2000000; + map_offset = get_phys ((unsigned long) fb->base) | 0x2000000; break; case MDI_PLANAR_C16_MAP: map_size = ram_size/2; - map_offset = get_phys ((uint) fb->base) | 0x2800000; + map_offset = get_phys ((unsigned long) fb->base) | 0x2800000; break; case MDI_CHUNKY_XBGR_MAP: @@ -208,50 +208,50 @@ case MDI_CHUNKY_BGR_MAP: map_size = ram_size; - map_offset = get_phys ((uint) fb->base) | 0x1000000; + map_offset = get_phys ((unsigned long) fb->base) | 0x1000000; break; case MDI_PLANAR_X32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3000000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3000000; break; case MDI_PLANAR_B32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3400000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3400000; break; case MDI_PLANAR_G32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3800000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3800000; break; case MDI_PLANAR_R32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3c00000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3c00000; break; case MDI_CURSOR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.cursor_regs); + map_offset = get_phys ((unsigned long) fb->info.cg14.cursor_regs); break; case CG14_REGS: printk ("Wee! They are mapping the register, report this to miguel@gnu.ai.mit.edu\n"); map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs); break; case CG14_XLUT: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs+0x3000); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x3000); break; case CG14_CLUT1: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs+0x4000); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x4000); break; case CG14_CLUT2: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs+0x5000); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x5000); break; default: @@ -424,11 +424,11 @@ *mcr = (*mcr & ~(CG14_MCR_PIXMODE_MASK)); } -__initfunc(void cg14_setup (fbinfo_t *fb, int slot, int con_node, unsigned long cg14, int cg14_io)) +__initfunc(void cg14_setup (fbinfo_t *fb, int slot, int con_node, u32 cg14, int cg14_io)) { struct cg14_info *cg14info; uint bases [2]; - uint cg14regs = 0; + unsigned long cg14regs = 0; struct cg14_regs *regs = 0; if (!cg14) { @@ -468,5 +468,5 @@ /* If the bit is turned on, the card has 8 mb of ram, otherwise just 4 */ cg14info->ramsize = (regs->vca & CG14_VCA_8MB_MASK ? 8 : 4) * 1024 * 1024; printk ("cgfourteen%d at 0x%8.8x with %d megs of RAM rev=%d, impl=%d\n", - slot, (uint)cg14, cg14info->ramsize/(1024*1024), regs->rev >> 4, regs->rev & 0xf); + slot, cg14, cg14info->ramsize/(1024*1024), regs->rev >> 4, regs->rev & 0xf); } diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/cgsix.c linux/drivers/sbus/char/cgsix.c --- v2.1.35/linux/drivers/sbus/char/cgsix.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/cgsix.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: cgsix.c,v 1.26 1997/04/10 03:02:40 davem Exp $ +/* $Id: cgsix.c,v 1.27 1997/04/14 17:04:55 jj Exp $ * cgsix.c: cgsix frame buffer driver * * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -264,17 +264,14 @@ map_size = PAGE_SIZE; map_offset = get_phys ((unsigned long)fb->info.cg6.bt); break; - case CG6_DHC: map_size = PAGE_SIZE * 40; map_offset = get_phys ((unsigned long)fb->info.cg6.dhc); break; - case CG6_ROM: map_size = PAGE_SIZE * 16; map_offset = get_phys ((unsigned long)fb->info.cg6.rom); break; - case CG6_RAM: map_size = size-page; map_offset = get_phys ((unsigned long) fb->base); @@ -422,12 +419,12 @@ cg6->bt->control |= 0x03 << 24; } -__initfunc(void cg6_setup (fbinfo_t *fb, int slot, unsigned long cg6, int cg6_io)) +__initfunc(void cg6_setup (fbinfo_t *fb, int slot, u32 cg6, int cg6_io)) { struct cg6_info *cg6info; unsigned int rev, cpu, conf; - printk ("cgsix%d at 0x%8.8x ", slot, (uint) cg6); + printk ("cgsix%d at 0x%8.8x ", slot, cg6); /* Fill in parameters we left out */ fb->type.fb_cmsize = 256; @@ -447,23 +444,23 @@ cg6info = (struct cg6_info *) &fb->info.cg6; /* Map the hardware registers */ - cg6info->bt = sparc_alloc_io ((u32)(cg6+CG6_BROOKTREE_OFFSET), 0, + cg6info->bt = sparc_alloc_io (cg6+CG6_BROOKTREE_OFFSET, 0, sizeof (struct bt_regs), "cgsix_dac", cg6_io, 0); - cg6info->fhc = sparc_alloc_io ((u32)(cg6+CG6_FHC_OFFSET), 0, + cg6info->fhc = sparc_alloc_io (cg6+CG6_FHC_OFFSET, 0, sizeof (int), "cgsix_fhc", cg6_io, 0); - cg6info->thc = sparc_alloc_io ((u32)(cg6+CG6_THC_OFFSET), 0, + cg6info->thc = sparc_alloc_io (cg6+CG6_THC_OFFSET, 0, sizeof (struct cg6_thc), "cgsix_thc", cg6_io, 0); - cg6info->tec = sparc_alloc_io ((u32)(cg6+CG6_TEC_OFFSET), 0, + cg6info->tec = sparc_alloc_io (cg6+CG6_TEC_OFFSET, 0, sizeof (struct cg6_tec), "cgsix_tec", cg6_io, 0); - cg6info->dhc = sparc_alloc_io ((u32)(cg6+CG6_DHC_OFFSET), 0, + cg6info->dhc = sparc_alloc_io (cg6+CG6_DHC_OFFSET, 0, 0x40000, "cgsix_dhc", cg6_io, 0); - cg6info->fbc = sparc_alloc_io ((u32)(cg6+CG6_FBC_OFFSET), 0, + cg6info->fbc = sparc_alloc_io (cg6+CG6_FBC_OFFSET, 0, 0x1000, "cgsix_fbc", cg6_io, 0); - cg6info->rom = sparc_alloc_io ((u32)(cg6+CG6_ROM_OFFSET), 0, + cg6info->rom = sparc_alloc_io (cg6+CG6_ROM_OFFSET, 0, 0x10000, "cgsix_rom", cg6_io, 0); if (!fb->base) { fb->base = (unsigned long) - sparc_alloc_io ((u32)(cg6+CG6_RAM_OFFSET), 0, + sparc_alloc_io (cg6+CG6_RAM_OFFSET, 0, fb->type.fb_size, "cgsix_ram", cg6_io, 0); } if (slot == sun_prom_console_id) diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/cgthree.c linux/drivers/sbus/char/cgthree.c --- v2.1.35/linux/drivers/sbus/char/cgthree.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/cgthree.c Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: cgthree.c,v 1.16 1997/04/10 03:02:41 davem Exp $ +/* $Id: cgthree.c,v 1.18 1997/04/16 17:51:09 jj Exp $ * cgtree.c: cg3 frame buffer driver * * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -109,7 +109,7 @@ switch (vma->vm_offset+page){ case CG3_MMAP_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); if (map_size > fb->type.fb_size) map_size = fb->type.fb_size; break; @@ -178,7 +178,7 @@ }; -__initfunc(void cg3_setup (fbinfo_t *fb, int slot, unsigned long cg3, int cg3_io, +__initfunc(void cg3_setup (fbinfo_t *fb, int slot, u32 cg3, int cg3_io, struct linux_sbus_device *sbdp)) { struct cg3_info *cg3info = (struct cg3_info *) &fb->info.cg3; @@ -200,10 +200,10 @@ } } } - printk ("cgRDI%d at 0x%8.8x\n", slot, (uint)cg3); + printk ("cgRDI%d at 0x%8.8x\n", slot, cg3); cg3info->cgrdi = 1; } else { - printk ("cgthree%d at 0x%8.8x\n", slot, (uint)cg3); + printk ("cgthree%d at 0x%8.8x\n", slot, cg3); cg3info->cgrdi = 0; } @@ -218,7 +218,7 @@ fb->unblank = cg3_unblank; /* Map the card registers */ - cg3info->regs = sparc_alloc_io ((u32)(cg3+CG3_REGS), 0, + cg3info->regs = sparc_alloc_io (cg3+CG3_REGS, 0, sizeof (struct cg3_regs),"cg3_regs", cg3_io, 0); if (!prom_getbool(sbdp->prom_node, "width")) { @@ -258,8 +258,8 @@ } if (!fb->base){ - fb->base=(uint) sparc_alloc_io ((u32)(cg3+CG3_RAM), 0, - fb->type.fb_size, "cg3_ram", cg3_io, 0); + fb->base=(unsigned long) sparc_alloc_io (cg3+CG3_RAM, 0, + fb->type.fb_size, "cg3_ram", cg3_io, 0); } } diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/creator.c linux/drivers/sbus/char/creator.c --- v2.1.35/linux/drivers/sbus/char/creator.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/sbus/char/creator.c Tue Apr 22 22:39:12 1997 @@ -0,0 +1,98 @@ +/* + * creator.c: Linux/Sun Ultra Creator console support. + * + * Copyright (C) 1997 MIguel de Icaza (miguel@nuclecu.unam.mx) + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../../char/vt_kern.h" +#include "../../char/selection.h" +#include "../../char/console_struct.h" +#include "fb.h" + +__initfunc(void creator_setup (fbinfo_t *fb, int slot, int con_node, unsigned long creator, int creator_io)) +{ + uint bases [2]; + unsigned long *p; + + if (!creator) { + prom_getproperty (con_node, "address", (char *) &bases[0], 4); + prom_printf ("Bases: %x %x\n", bases [0], bases [1]); + p = (unsigned long *) creator = bases[0]; + fb->base = creator; + fb->base = 0xff168000; + } + + fb->type.fb_cmsize = 256; + fb->mmap = 0; + fb->loadcmap = 0; + fb->setcursor = 0; + fb->setcursormap = 0; + fb->setcurshape = 0; + fb->ioctl = 0; + fb->switch_from_graph = 0; + fb->postsetup = sun_cg_postsetup; + fb->reset = 0; + fb->blank = 0; + fb->unblank = 0; + fb->type.fb_depth = 8; +} +/* + * creator.c: Linux/Sun Ultra Creator console support. + * + * Copyright (C) 1997 MIguel de Icaza (miguel@nuclecu.unam.mx) + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../../char/vt_kern.h" +#include "../../char/selection.h" +#include "../../char/console_struct.h" +#include "fb.h" + +__initfunc(void creator_setup (fbinfo_t *fb, int slot, int con_node, unsigned long creator, int creator_io)) +{ + uint bases [2]; + unsigned long *p; + + if (!creator) { + prom_getproperty (con_node, "address", (char *) &bases[0], 4); + prom_printf ("Bases: %x %x\n", bases [0], bases [1]); + p = (unsigned long *) creator = bases[0]; + fb->base = creator; + fb->base = 0xff168000; + } + + fb->type.fb_cmsize = 256; + fb->mmap = 0; + fb->loadcmap = 0; + fb->setcursor = 0; + fb->setcursormap = 0; + fb->setcurshape = 0; + fb->ioctl = 0; + fb->switch_from_graph = 0; + fb->postsetup = sun_cg_postsetup; + fb->reset = 0; + fb->blank = 0; + fb->unblank = 0; + fb->type.fb_depth = 8; +} diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/fb.h linux/drivers/sbus/char/fb.h --- v2.1.35/linux/drivers/sbus/char/fb.h Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/fb.h Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: fb.h,v 1.24 1997/03/24 17:44:15 jj Exp $ +/* $Id: fb.h,v 1.26 1997/04/17 02:29:33 miguel Exp $ * fb.h: contains the definitions of the structures that various sun * frame buffer can use to do console driver stuff. * @@ -183,8 +183,8 @@ extern int ints_per_line; /* used in the mmap routines */ -extern unsigned int get_phys (unsigned int addr); -extern int get_iospace (unsigned int addr); +extern unsigned int get_phys (unsigned long addr); +extern int get_iospace (unsigned long addr); extern void render_screen(void); extern void sun_hw_hide_cursor(void); @@ -197,12 +197,14 @@ #define FB_DEV(x) (MINOR(x) / 32) -extern void cg3_setup (fbinfo_t *, int, unsigned long, int, struct linux_sbus_device *); -extern void cg6_setup (fbinfo_t *, int, unsigned long, int); -extern void cg14_setup (fbinfo_t *, int, int, unsigned long, int); -extern void bwtwo_setup (fbinfo_t *, int, unsigned long, int, +extern void cg3_setup (fbinfo_t *, int, u32, int, struct linux_sbus_device *); +extern void cg6_setup (fbinfo_t *, int, u32, int); +extern void cg14_setup (fbinfo_t *, int, int, u32, int); +extern void bwtwo_setup (fbinfo_t *, int, u32, int, struct linux_sbus_device *); -extern void leo_setup (fbinfo_t *, int, unsigned long, int); -extern void tcx_setup (fbinfo_t *, int, int, unsigned long, struct linux_sbus_device *); +extern void leo_setup (fbinfo_t *, int, u32, int); +extern void tcx_setup (fbinfo_t *, int, int, u32, struct linux_sbus_device *); +extern void creator_setup (fbinfo_t *, int, int, unsigned long, int); +extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space); #endif __SPARC_FB_H_ diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/leo.c linux/drivers/sbus/char/leo.c --- v2.1.35/linux/drivers/sbus/char/leo.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/leo.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: leo.c,v 1.14 1997/04/10 17:06:09 jj Exp $ +/* $Id: leo.c,v 1.15 1997/04/14 17:04:54 jj Exp $ * leo.c: SUNW,leo 24/8bit frame buffer driver * * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -156,19 +156,19 @@ switch (vma->vm_offset+page){ case LEO_SS0_MAP: map_size = 0x800000; - map_offset = get_phys ((uint)fb->base); + map_offset = get_phys ((unsigned long)fb->base); break; case LEO_LC_SS0_USR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss0_usr); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss0_usr); break; case LEO_LD_SS0_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.ld_ss0); + map_offset = get_phys ((unsigned long)fb->info.leo.ld_ss0); break; case LEO_LX_CURSOR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.cursor); + map_offset = get_phys ((unsigned long)fb->info.leo.cursor); break; case LEO_SS1_MAP: map_size = 0x800000; @@ -176,11 +176,11 @@ break; case LEO_LC_SS1_USR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss1_usr); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss1_usr); break; case LEO_LD_SS1_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.ld_ss1); + map_offset = get_phys ((unsigned long)fb->info.leo.ld_ss1); break; case LEO_UNK_MAP: map_size = PAGE_SIZE; @@ -188,19 +188,19 @@ break; case LEO_LX_KRN_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lx_krn); + map_offset = get_phys ((unsigned long)fb->info.leo.lx_krn); break; case LEO_LC_SS0_KRN_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss0_krn); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss0_krn); break; case LEO_LC_SS1_KRN_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss1_krn); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss1_krn); break; case LEO_LD_GBL_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.ld_gbl); + map_offset = get_phys ((unsigned long)fb->info.leo.ld_gbl); break; case LEO_UNK2_MAP: map_size = 0x100000; @@ -509,14 +509,14 @@ return memory_start + (256*4*3) + 256 + 256*3; } -__initfunc(void leo_setup (fbinfo_t *fb, int slot, unsigned long leo, int leo_io)) +__initfunc(void leo_setup (fbinfo_t *fb, int slot, u32 leo, int leo_io)) { struct leo_info *leoinfo; int i; struct fb_wid_item wi; struct fb_wid_list wl; - printk ("leo%d at 0x%8.8x ", slot, (uint) leo); + printk ("leo%d at 0x%8.8x ", slot, leo); /* Fill in parameters we left out */ fb->type.fb_size = 0x800000; /* 8MB */ @@ -543,25 +543,25 @@ leoinfo->offset = leo; /* Map the hardware registers */ - leoinfo->lc_ss0_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS0_KRN), 0, + leoinfo->lc_ss0_krn = sparc_alloc_io(leo + LEO_OFF_LC_SS0_KRN, 0, PAGE_SIZE,"leo_lc_ss0_krn", fb->space, 0); - leoinfo->lc_ss0_usr = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS0_USR), 0, + leoinfo->lc_ss0_usr = sparc_alloc_io(leo + LEO_OFF_LC_SS0_USR, 0, PAGE_SIZE,"leo_lc_ss0_usr", fb->space, 0); - leoinfo->lc_ss1_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS1_KRN), 0, + leoinfo->lc_ss1_krn = sparc_alloc_io(leo + LEO_OFF_LC_SS1_KRN, 0, PAGE_SIZE,"leo_lc_ss1_krn", fb->space, 0); - leoinfo->lc_ss1_usr = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS1_USR), 0, + leoinfo->lc_ss1_usr = sparc_alloc_io(leo + LEO_OFF_LC_SS1_USR, 0, PAGE_SIZE,"leo_lc_ss1_usr", fb->space, 0); - leoinfo->ld_ss0 = sparc_alloc_io((u32)(leo + LEO_OFF_LD_SS0), 0, + leoinfo->ld_ss0 = sparc_alloc_io(leo + LEO_OFF_LD_SS0, 0, PAGE_SIZE,"leo_ld_ss0", fb->space, 0); - leoinfo->ld_ss1 = sparc_alloc_io((u32)(leo + LEO_OFF_LD_SS1), 0, + leoinfo->ld_ss1 = sparc_alloc_io(leo + LEO_OFF_LD_SS1, 0, PAGE_SIZE,"leo_ld_ss1", fb->space, 0); - leoinfo->ld_gbl = sparc_alloc_io((u32)(leo + LEO_OFF_LD_GBL), 0, + leoinfo->ld_gbl = sparc_alloc_io(leo + LEO_OFF_LD_GBL, 0, PAGE_SIZE,"leo_ld_gbl", fb->space, 0); - leoinfo->lx_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LX_KRN), 0, + leoinfo->lx_krn = sparc_alloc_io(leo + LEO_OFF_LX_KRN, 0, PAGE_SIZE,"leo_lx_krn", fb->space, 0); - leoinfo->cursor = sparc_alloc_io((u32)(leo + LEO_OFF_LX_CURSOR), 0, + leoinfo->cursor = sparc_alloc_io(leo + LEO_OFF_LX_CURSOR, 0, sizeof(struct leo_cursor),"leo_lx_crsr", fb->space, 0); - fb->base = (long)sparc_alloc_io((u32)(leo + LEO_OFF_SS0), 0, + fb->base = (long)sparc_alloc_io(leo + LEO_OFF_SS0, 0, 0x800000,"leo_ss0", fb->space, 0); leoinfo->ld_ss0->unk = 0xffff; diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/linux_logo.h linux/drivers/sbus/char/linux_logo.h --- v2.1.35/linux/drivers/sbus/char/linux_logo.h Fri Dec 13 01:37:32 1996 +++ linux/drivers/sbus/char/linux_logo.h Wed Dec 31 16:00:00 1969 @@ -1,1037 +0,0 @@ -/* This is a linux logo to be displayed on boot. - * - * You can put anything here, but: - * LINUX_LOGO_COLORS has to be less than 224 - * image size has to be 80x80 - * values have to start from 0x20 - * (i.e. RGB(linux_logo_red[0], - * linux_logo_green[0], - * linux_logo_blue[0]) is color 0x20) - * BW image has to be 80x80 as well, with MS bit - * on the left - * Serial_console ascii image can be any size, - * but should contain %s to display the version - */ - -#include - -#define LINUX_LOGO_COLORS 221 - -unsigned char linux_logo_red[] __initdata = { - 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, - 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5, - 0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5, - 0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6, - 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD, - 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D, - 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, - 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, - 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03, - 0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6, - 0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2, - 0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A, - 0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4, - 0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2, - 0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC, - 0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC, - 0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7, - 0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3, - 0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4, - 0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4, - 0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87, - 0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78, - 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, - 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, - 0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E, - 0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B, - 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11, - 0x1D, 0x14, 0x06, 0x02, 0x00 -}; - -unsigned char linux_logo_green[] __initdata = { - 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, - 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3, - 0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9, - 0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6, - 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD, - 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95, - 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, - 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, - 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02, - 0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD, - 0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6, - 0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C, - 0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4, - 0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E, - 0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC, - 0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5, - 0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96, - 0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80, - 0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F, - 0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C, - 0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54, - 0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78, - 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, - 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, - 0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E, - 0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B, - 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D, - 0x1D, 0x14, 0x06, 0x02, 0x00 -}; - -unsigned char linux_logo_blue[] __initdata = { - 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE, - 0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5, - 0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84, - 0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6, - 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD, - 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87, - 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99, - 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, - 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7, - 0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77, - 0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59, - 0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E, - 0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14, - 0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D, - 0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14, - 0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08, - 0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E, - 0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E, - 0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20, - 0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06, - 0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17, - 0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78, - 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62, - 0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46, - 0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14, - 0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A, - 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09, - 0x1D, 0x14, 0x06, 0x02, 0x00 -}; - -unsigned char linux_logo[] __initdata = { - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, - 0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61, - 0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, - 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E, - 0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58, - 0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, - 0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C, - 0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A, - 0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52, - 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53, - 0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, - 0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49, - 0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B, - 0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, - 0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB, - 0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C, - 0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49, - 0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5, - 0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58, - 0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48, - 0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51, - 0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54, - 0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5, - 0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61, - 0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C, - 0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B, - 0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53, - 0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC, - 0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64, - 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59, - 0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48, - 0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51, - 0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61, - 0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63, - 0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48, - 0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51, - 0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52, - 0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB, - 0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B, - 0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53, - 0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53, - 0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC, - 0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F, - 0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61, - 0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57, - 0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D, - 0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, - 0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57, - 0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC, - 0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC, - 0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48, - 0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52, - 0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61, - 0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A, - 0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, - 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B, - 0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC, - 0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC, - 0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49, - 0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F, - 0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB, - 0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47, - 0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54, - 0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D, - 0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC, - 0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC, - 0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45, - 0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44, - 0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64, - 0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48, - 0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, - 0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D, - 0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC, - 0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA, - 0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55, - 0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45, - 0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D, - 0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B, - 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, - 0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A, - 0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC, - 0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8, - 0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD, - 0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A, - 0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56, - 0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, - 0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, - 0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54, - 0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC, - 0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB, - 0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27, - 0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34, - 0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F, - 0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E, - 0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60, - 0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51, - 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57, - 0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51, - 0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC, - 0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE, - 0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A, - 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30, - 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41, - 0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65, - 0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C, - 0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A, - 0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC, - 0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C, - 0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1, - 0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32, - 0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30, - 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41, - 0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC, - 0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A, - 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, - 0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E, - 0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC, - 0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88, - 0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB, - 0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33, - 0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31, - 0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E, - 0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63, - 0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49, - 0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, - 0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55, - 0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC, - 0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C, - 0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8, - 0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F, - 0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F, - 0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48, - 0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A, - 0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A, - 0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57, - 0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53, - 0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC, - 0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88, - 0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4, - 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E, - 0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47, - 0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D, - 0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58, - 0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55, - 0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC, - 0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E, - 0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9, - 0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73, - 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70, - 0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF, - 0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E, - 0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57, - 0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58, - 0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C, - 0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC, - 0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C, - 0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC, - 0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78, - 0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, - 0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1, - 0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C, - 0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D, - 0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58, - 0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E, - 0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC, - 0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8, - 0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42, - 0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73, - 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73, - 0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2, - 0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41, - 0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62, - 0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B, - 0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60, - 0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC, - 0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7, - 0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41, - 0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73, - 0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74, - 0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB, - 0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41, - 0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64, - 0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E, - 0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C, - 0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB, - 0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE, - 0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20, - 0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75, - 0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76, - 0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D, - 0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C, - 0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64, - 0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, - 0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58, - 0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC, - 0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81, - 0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23, - 0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76, - 0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76, - 0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48, - 0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40, - 0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61, - 0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C, - 0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52, - 0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB, - 0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E, - 0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22, - 0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8, - 0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, - 0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C, - 0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57, - 0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D, - 0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A, - 0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65, - 0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC, - 0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40, - 0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD, - 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47, - 0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF, - 0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A, - 0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57, - 0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5, - 0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C, - 0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26, - 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6, - 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52, - 0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9, - 0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42, - 0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51, - 0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6, - 0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21, - 0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7, - 0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93, - 0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D, - 0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF, - 0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40, - 0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52, - 0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1, - 0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21, - 0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8, - 0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93, - 0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40, - 0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0, - 0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F, - 0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59, - 0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E, - 0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23, - 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7, - 0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93, - 0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F, - 0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC, - 0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47, - 0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54, - 0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D, - 0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24, - 0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24, - 0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A, - 0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5, - 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93, - 0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60, - 0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC, - 0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47, - 0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B, - 0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D, - 0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28, - 0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D, - 0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD, - 0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93, - 0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7, - 0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44, - 0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45, - 0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B, - 0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D, - 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20, - 0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6, - 0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90, - 0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0, - 0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44, - 0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45, - 0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51, - 0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF, - 0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7, - 0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5, - 0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2, - 0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58, - 0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C, - 0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55, - 0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1, - 0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB, - 0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6, - 0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3, - 0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58, - 0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58, - 0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C, - 0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC, - 0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7, - 0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, - 0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0, - 0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58, - 0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60, - 0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60, - 0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB, - 0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7, - 0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7, - 0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE, - 0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B, - 0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61, - 0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64, - 0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC, - 0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8, - 0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5, - 0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C, - 0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E, - 0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62, - 0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC, - 0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB, - 0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7, - 0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5, - 0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57, - 0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47, - 0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60, - 0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0, - 0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0, - 0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8, - 0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6, - 0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57, - 0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B, - 0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C, - 0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3, - 0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB, - 0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8, - 0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7, - 0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57, - 0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C, - 0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58, - 0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1, - 0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC, - 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED, - 0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, - 0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58, - 0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60, - 0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56, - 0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0, - 0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC, - 0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6, - 0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, - 0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B, - 0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C, - 0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59, - 0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0, - 0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC, - 0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6, - 0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6, - 0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B, - 0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56, - 0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60, - 0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF, - 0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9, - 0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9, - 0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, - 0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52, - 0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B, - 0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD, - 0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE, - 0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65, - 0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6, - 0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D, - 0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58, - 0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F, - 0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4, - 0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE, - 0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0, - 0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D, - 0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57, - 0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40, - 0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9, - 0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE, - 0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC, - 0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9, - 0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38, - 0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52, - 0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40, - 0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC, - 0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF, - 0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99, - 0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, - 0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6, - 0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, - 0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B, - 0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43, - 0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC, - 0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0, - 0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C, - 0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23, - 0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, - 0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49, - 0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A, - 0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC, - 0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2, - 0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94, - 0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA, - 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, - 0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E, - 0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D, - 0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC, - 0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4, - 0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B, - 0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23, - 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7, - 0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E, - 0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0, - 0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA, - 0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9, - 0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89, - 0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22, - 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA, - 0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2, - 0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E, - 0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA, - 0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA, - 0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6, - 0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97, - 0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D, - 0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, - 0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9, - 0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D, - 0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45, - 0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB, - 0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6, - 0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99, - 0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A, - 0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC, - 0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, - 0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4, - 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C, - 0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47, - 0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD, - 0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4, - 0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A, - 0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98, - 0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC, - 0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23, - 0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4, - 0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89, - 0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B, - 0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD, - 0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0, - 0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0, - 0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A, - 0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC, - 0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, - 0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2, - 0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A, - 0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49, - 0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC, - 0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63, - 0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B, - 0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84, - 0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC, - 0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, - 0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99, - 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B, - 0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51, - 0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC, - 0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A, - 0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95, - 0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E, - 0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA, - 0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22, - 0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99, - 0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94, - 0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B, - 0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA, - 0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D, - 0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C, - 0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A, - 0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB, - 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23, - 0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99, - 0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E, - 0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87, - 0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3, - 0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48, - 0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94, - 0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95, - 0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6, - 0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40, - 0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99, - 0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95, - 0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98, - 0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC, - 0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45, - 0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89, - 0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C, - 0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4, - 0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23, - 0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99, - 0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87, - 0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC, - 0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58, - 0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40, - 0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94, - 0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B, - 0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6, - 0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20, - 0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C, - 0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94, - 0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE, - 0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C, - 0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41, - 0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98, - 0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C, - 0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6, - 0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B, - 0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B, - 0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0, - 0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62, - 0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44, - 0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6, - 0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89, - 0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8, - 0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99, - 0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98, - 0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1, - 0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB, - 0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49, - 0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA, - 0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2, - 0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA, - 0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2, - 0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0, - 0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF, - 0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD, - 0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52, - 0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA, - 0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA, - 0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1, - 0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8, - 0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0, - 0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9, - 0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD, - 0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53, - 0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56, - 0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0, - 0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9, - 0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0, - 0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3, - 0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF, - 0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2, - 0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3, - 0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE, - 0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56, - 0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57, - 0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC, - 0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA, - 0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4, - 0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3, - 0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1, - 0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6, - 0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE, - 0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD, - 0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58, - 0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D, - 0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47, - 0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6, - 0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4, - 0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5, - 0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9, - 0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC, - 0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3, - 0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64, - 0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C, - 0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A, - 0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A, - 0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0, - 0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE, - 0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6, - 0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6, - 0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE, - 0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5, - 0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E, - 0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D, - 0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E, - 0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E, - 0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8, - 0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5, - 0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1, - 0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60, - 0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9, - 0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5, - 0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47, - 0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E, - 0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45, - 0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51, - 0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB, - 0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0, - 0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D, - 0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0, - 0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5, - 0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2, - 0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D, - 0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60, - 0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45, - 0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63, - 0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7, - 0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3, - 0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E, - 0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2, - 0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0, - 0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC, - 0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C, - 0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61, - 0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45, - 0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2, - 0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3, - 0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2, - 0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47, - 0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2, - 0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E, - 0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3, - 0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63, - 0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62, - 0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49, - 0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3, - 0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF, - 0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2, - 0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58, - 0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE, - 0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B, - 0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4, - 0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE, - 0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62, - 0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A, - 0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5, - 0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE, - 0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3, - 0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53, - 0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3, - 0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48, - 0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3, - 0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF, - 0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57, -}; - -unsigned char linux_logo_bw[] __initdata = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, - 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, - 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, - 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, - 0x99, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xF3, 0xBC, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, - 0x19, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, - 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF9, 0xC0, 0x21, 0xD8, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0xC0, 0x1F, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, - 0xC0, 0x7C, 0x04, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, - 0xE3, 0x80, 0x00, 0x7C, 0x40, 0x11, 0xFF, 0xFF, - 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0xD2, 0x29, - 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, - 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, - 0x00, 0x3F, 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, - 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x19, 0xFF, 0xFF, - 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1E, 0x80, 0x19, - 0xFF, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1E, - 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, - 0x00, 0x0F, 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, - 0xF8, 0x00, 0x00, 0x0E, 0x80, 0x11, 0xFF, 0xFF, - 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x06, 0x00, 0x11, - 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x06, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, - 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1, - 0xF0, 0x00, 0x00, 0x02, 0x80, 0x10, 0xFF, 0xFF, - 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x97, 0x10, - 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, - 0xDF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, - 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC7, - 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, - 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, - 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, - 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, - 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F, - 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, - 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0x18, - 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, - 0xA8, 0x11, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, - 0x00, 0x02, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x99, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, - 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x01, - 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, - 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, - 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x40, - 0x38, 0x00, 0x00, 0x00, 0xFE, 0x47, 0xFF, 0xFF, - 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x23, - 0xFF, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, - 0x78, 0x11, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, - 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, - 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, - 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, - 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, - 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, - 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, - 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, - 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, - 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, - 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, - 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, - 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, - 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, - 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, - 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, - 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, - 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, - 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, - 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, - 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -/* Painted by Johnny Stenback */ - -unsigned char *linux_serial_image __initdata = "\n" -" .u$e.\n" -" .$$$$$:S\n" -" $\"*$/\"*$$\n" -" $.`$ . ^F\n" -" 4k+#+T.$F\n" -" 4P+++\"$\"$\n" -" :R\"+ t$$B\n" -" ___# $$$\n" -" | | R$$k\n" -" dd. | Linux $!$\n" -" ddd | Sparc $9$F\n" -" '!!!!!$ !!#!`\n" -" !!!!!* .!!!!!`\n" -"'!!!!!!!W..e$$!!!!!!` %s\n" -" \"~^^~ ^~~^\n" -"\n"; diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/suncons.c linux/drivers/sbus/char/suncons.c --- v2.1.35/linux/drivers/sbus/char/suncons.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/suncons.c Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: suncons.c,v 1.58 1997/04/04 00:50:04 davem Exp $ +/* $Id: suncons.c,v 1.61 1997/04/17 02:29:36 miguel Exp $ * * suncons.c: Sun SparcStation console support. * @@ -87,7 +87,7 @@ #define cmapsz 8192 #include "suncons_font.h" -#include "linux_logo.h" +#include fbinfo_t *fbinfo; int fbinfos; @@ -382,7 +382,7 @@ count = video_num_columns * video_num_lines; contents = (unsigned short *) video_mem_base; - + for (;count--; contents++) sun_blitc (*contents, (unsigned long) contents); } @@ -434,11 +434,7 @@ putconsxy(0, q); ush = (unsigned short *) video_mem_base + video_num_columns * 2 + 20 + 11 * (linux_num_cpus - 1); -#ifdef __sparc_v9__ - p = "Linux/UltraSPARC version " UTS_RELEASE; -#else - p = "Linux/SPARC version " UTS_RELEASE; -#endif + p = linux_logo_banner; for (; *p; p++, ush++) { *ush = (attr << 8) + *p; sun_blitc (*ush, (unsigned long) ush); @@ -764,35 +760,15 @@ } unsigned int -get_phys (unsigned int addr) +get_phys (unsigned long addr) { - switch (sparc_cpu_model){ - case sun4c: - return sun4c_get_pte (addr) << PAGE_SHIFT; - case sun4m: - return ((srmmu_get_pte (addr) & 0xffffff00) << 4); - case sun4u: - /* FIXME: */ return 0; - default: - panic ("get_phys called for unsupported cpu model\n"); - return 0; - } + return __get_phys(addr); } int -get_iospace (unsigned int addr) +get_iospace (unsigned long addr) { - switch (sparc_cpu_model){ - case sun4c: - return -1; /* Don't check iospace on sun4c */ - case sun4m: - return (srmmu_get_pte (addr) >> 28); - case sun4u: - /* FIXME: */ return 0; - default: - panic ("get_iospace called for unsupported cpu model\n"); - return -1; - } + return __get_iospace(addr); } __initfunc(unsigned long sun_cg_postsetup(fbinfo_t *fb, unsigned long start_mem)) @@ -803,7 +779,7 @@ static char *known_cards [] __initdata = { "cgsix", "cgthree", "cgRDI", "cgthree+", "bwtwo", "SUNW,tcx", - "cgfourteen", "SUNW,leo", 0 + "cgfourteen", "SUNW,leo", "SUNW,ffb", 0 }; static char *v0_known_cards [] __initdata = { "cgsix", "cgthree", "cgRDI", "cgthree+", "bwtwo", 0 @@ -848,6 +824,16 @@ return n; } +__initfunc(static int creator_present (void)) +{ + int root, n; + + root = prom_getchild (prom_root_node); + if ((n = prom_searchsiblings (root, "SUNW,ffb")) == 0) + return 0; + return n; +} + __initfunc(static void sparc_framebuffer_setup(int primary, int con_node, int type, struct linux_sbus_device *sbdp, @@ -941,78 +927,86 @@ leo_setup (&fbinfo [n], n, base, io); break; #endif +#ifdef SUN_FB_CREATOR + case FBTYPE_CREATOR: + creator_setup (&fbinfo [n], n, con_node, base, io); + break; +#endif default: fbinfo [n].type.fb_type = FBTYPE_NOTYPE; return; } - if (!n) { - con_type = type; - con_height = fbinfo [n].type.fb_height; - con_width = fbinfo [n].type.fb_width; - con_depth = (type == FBTYPE_SUN2BW) ? 1 : 8; - for (i = 0; scr_def [i].depth; i++){ - if ((scr_def [i].resx != con_width) || - (scr_def [i].resy != con_height)) - continue; - if (scr_def [i].depth != con_depth) - continue; - x_margin = scr_def [i].x_margin; - y_margin = scr_def [i].y_margin; - chars_per_line = (con_width * con_depth) / 8; - skip_bytes = chars_per_line * y_margin + x_margin; - ints_per_line = chars_per_line / 4; - ints_per_cursor = 14 * ints_per_line; - bytes_per_row = CHAR_HEIGHT * chars_per_line; - ORIG_VIDEO_COLS = con_width / 8 - - 2 * x_margin / con_depth; - ORIG_VIDEO_LINES = (con_height - 2 * y_margin) / 16; - switch (chars_per_line) { - case 1280: - if (ORIG_VIDEO_COLS == 144) - color_fbuf_offset = - color_fbuf_offset_1280_144; - break; - case 1152: - if (ORIG_VIDEO_COLS == 128) - color_fbuf_offset = - color_fbuf_offset_1152_128; - break; - case 1024: - if (ORIG_VIDEO_COLS == 128) - color_fbuf_offset = - color_fbuf_offset_1024_128; - break; - case 800: - if (ORIG_VIDEO_COLS == 96) - color_fbuf_offset = - color_fbuf_offset_800_96; - break; - case 640: - if (ORIG_VIDEO_COLS == 80) - color_fbuf_offset = - color_fbuf_offset_640_80; - break; - } - break; - } - - if (!scr_def [i].depth){ - x_margin = y_margin = 0; - prom_printf ("console: unknown video resolution %dx%d," - " depth %d\n", - con_width, con_height, con_depth); - prom_halt (); - } - /* P3: I fear this strips 15inch 1024/768 PC-like - * monitors out. */ - if ((linebytes*8) / con_depth != con_width) { - prom_printf("console: unusual video, linebytes=%d, " - "width=%d, height=%d depth=%d\n", - linebytes, con_width, con_height, - con_depth); - prom_halt (); + if (n) + return; + + /* Code below here is just executed for the first frame buffer */ + con_type = type; + con_height = fbinfo [n].type.fb_height; + con_width = fbinfo [n].type.fb_width; + con_depth = (type == FBTYPE_SUN2BW) ? 1 : 8; + for (i = 0; scr_def [i].depth; i++){ + if ((scr_def [i].resx != con_width) || + (scr_def [i].resy != con_height)) + continue; + if (scr_def [i].depth != con_depth) + continue; + x_margin = scr_def [i].x_margin; + y_margin = scr_def [i].y_margin; + chars_per_line = (con_width * con_depth) / 8; + skip_bytes = chars_per_line * y_margin + x_margin; + ints_per_line = chars_per_line / 4; + ints_per_cursor = 14 * ints_per_line; + bytes_per_row = CHAR_HEIGHT * chars_per_line; + ORIG_VIDEO_COLS = con_width / 8 - + 2 * x_margin / con_depth; + ORIG_VIDEO_LINES = (con_height - 2 * y_margin) / 16; + switch (chars_per_line) { + case 1280: + if (ORIG_VIDEO_COLS == 144) + color_fbuf_offset = + color_fbuf_offset_1280_144; + break; + case 1152: + if (ORIG_VIDEO_COLS == 128) + color_fbuf_offset = + color_fbuf_offset_1152_128; + break; + case 1024: + if (ORIG_VIDEO_COLS == 128) + color_fbuf_offset = + color_fbuf_offset_1024_128; + break; + case 800: + if (ORIG_VIDEO_COLS == 96) + color_fbuf_offset = + color_fbuf_offset_800_96; + break; + case 640: + if (ORIG_VIDEO_COLS == 80) + color_fbuf_offset = + color_fbuf_offset_640_80; + break; } + break; + } + + if (!scr_def [i].depth){ + x_margin = y_margin = 0; + prom_printf ("console: unknown video resolution %dx%d," + " depth %d\n", + con_width, con_height, con_depth); + prom_halt (); + } + + /* P3: I fear this strips 15inch 1024/768 PC-like + * monitors out. */ + if ((linebytes*8) / con_depth != con_width) { + prom_printf("console: unusual video, linebytes=%d, " + "width=%d, height=%d depth=%d\n", + linebytes, con_width, con_height, + con_depth); + prom_halt (); } } @@ -1022,9 +1016,9 @@ char prop[16]; struct linux_sbus_device *sbdp, *sbdprom; struct linux_sbus *sbus; - int cg14 = 0; + int creator = 0, cg14 = 0; char prom_name[40]; - int type; + int type, card_found = 0; unsigned long con_base; u32 tmp; u32 prom_console_node = 0; @@ -1109,18 +1103,22 @@ break; } } - if (!sbdprom) /* I'm just wondering if this if shouldn't be deleted. - Is /obio/cgfourteen present only if /sbus/cgfourteen - is not? If so, then the test here should be deleted. - Otherwise, this comment should be deleted. */ - cg14 = cg14_present (); - if (!sbdprom && !cg14) { + if (sbdprom) + card_found = 1; + if (!card_found) + card_found = cg14 = cg14_present (); + if (!card_found){ + prom_printf ("Searching for a creator\n"); + card_found = creator = creator_present (); + } + if (!card_found){ prom_printf ("Could not find a known video card on this machine\n"); prom_halt (); } for_all_sbusdev(sbdp, sbus) { - if (!known_card (sbdp->prom_name, known_cards)) continue; + if (!known_card (sbdp->prom_name, known_cards)) + continue; con_node = sbdp->prom_node; prom_apply_sbus_ranges (sbdp->my_bus, &sbdp->reg_addrs [0], sbdp->num_registers, sbdp); @@ -1170,6 +1168,11 @@ sparc_framebuffer_setup (!sbdprom, cg14, FBTYPE_MDICOLOR, 0, 0, 0, prom_console_node == cg14, prom_searchsiblings (prom_getchild (prom_root_node), "obio")); + } + if (creator){ + sparc_framebuffer_setup (!sbdprom, creator, FBTYPE_CREATOR, + 0, 0, 0, prom_console_node == creator, + prom_getchild (prom_root_node)); } break; default: diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c --- v2.1.35/linux/drivers/sbus/char/sunkbd.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/sunkbd.c Tue Apr 22 22:39:21 1997 @@ -1149,7 +1149,7 @@ extern void (*kd_mksound)(unsigned int hz, unsigned int ticks); -int kbd_init(void) +__initfunc(int kbd_init(void)) { int i, opt_node; struct kbd_struct kbd0; diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/sunserial.c linux/drivers/sbus/char/sunserial.c --- v2.1.35/linux/drivers/sbus/char/sunserial.c Mon Apr 14 16:28:14 1997 +++ linux/drivers/sbus/char/sunserial.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: sunserial.c,v 1.37 1997/04/12 23:33:14 ecd Exp $ +/* $Id: sunserial.c,v 1.38 1997/04/14 17:05:00 jj Exp $ * serial.c: Serial port driver for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1857,7 +1857,7 @@ static void show_serial_version(void) { - char *revision = "$Revision: 1.37 $"; + char *revision = "$Revision: 1.38 $"; char *version, *p; version = strchr(revision, ' '); @@ -1991,7 +1991,7 @@ if(!vaddr[0]) panic("get_zs whee no serial chip mappable"); - return (struct sun_zslayout *) vaddr[0]; + return (struct sun_zslayout *)(unsigned long) vaddr[0]; } static inline void @@ -2541,7 +2541,7 @@ for (info = zs_chain, i=0; info; info = info->zs_next, i++) { info->magic = SERIAL_MAGIC; - info->port = (int) info->zs_channel; + info->port = (long) info->zs_channel; info->line = i; info->tty = 0; info->irq = zilog_irq; diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/tcx.c linux/drivers/sbus/char/tcx.c --- v2.1.35/linux/drivers/sbus/char/tcx.c Mon Apr 14 16:28:14 1997 +++ linux/drivers/sbus/char/tcx.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: tcx.c,v 1.11 1997/04/10 03:02:43 davem Exp $ +/* $Id: tcx.c,v 1.12 1997/04/14 17:04:51 jj Exp $ * tcx.c: SUNW,tcx 24/8bit frame buffer driver * * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -126,24 +126,24 @@ switch (vma->vm_offset+page){ case TCX_RAM8BIT: map_size = fb->type.fb_size; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); break; case TCX_TEC: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.tcx.tec); + map_offset = get_phys ((unsigned long)fb->info.tcx.tec); break; case TCX_BTREGS: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.tcx.bt); + map_offset = get_phys ((unsigned long)fb->info.tcx.bt); break; case TCX_THC: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.tcx.thc); + map_offset = get_phys ((unsigned long)fb->info.tcx.thc); break; case TCX_CONTROLPLANE: if (fb->info.tcx.tcx_cplane) { map_size = fb->info.tcx.tcx_sizes [TCX_CONTROLPLANE_OFFSET]; - map_offset = get_phys ((uint)fb->info.tcx.tcx_cplane); + map_offset = get_phys ((unsigned long)fb->info.tcx.tcx_cplane); } else map_size = 0; break; @@ -272,12 +272,12 @@ tcx->bt->control |= 0x03 << 24; } -__initfunc(void tcx_setup (fbinfo_t *fb, int slot, int node, unsigned long tcx, struct linux_sbus_device *sbdp)) +__initfunc(void tcx_setup (fbinfo_t *fb, int slot, int node, u32 tcx, struct linux_sbus_device *sbdp)) { struct tcx_info *tcxinfo; int i; - printk ("tcx%d at 0x%8.8x ", slot, (uint) tcx); + printk ("tcx%d at 0x%8.8x ", slot, tcx); /* Fill in parameters we left out */ fb->type.fb_cmsize = 256; diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/char/weitek.c linux/drivers/sbus/char/weitek.c --- v2.1.35/linux/drivers/sbus/char/weitek.c Mon Apr 14 16:28:15 1997 +++ linux/drivers/sbus/char/weitek.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: weitek.c,v 1.8 1997/03/24 17:44:26 jj Exp $ +/* $Id: weitek.c,v 1.9 1997/04/14 17:04:57 jj Exp $ * weitek.c: Tadpole P9100/P9000 console driver * * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk) @@ -54,13 +54,13 @@ switch (vma->vm_offset+page){ case WEITEK_VRAM_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); if (map_size > fb->type.fb_size) map_size = fb->type.fb_size; break; case WEITEK_GX_REG_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); if (map_size > fb->type.fb_size) map_size = fb->type.fb_size; break; @@ -95,11 +95,11 @@ } #endif -__initfunc(void weitek_setup(fbinfo_t *fb, int slot, unsigned long addr, int io)) +__initfunc(void weitek_setup(fbinfo_t *fb, int slot, u32 addr, int io)) { extern struct screen_info screen_info; - printk ("weitek%d at 0x%8.8x\n", slot, (uint)addr); + printk ("weitek%d at 0x%8.8x\n", slot, addr); /* Fill in parameters we left out */ fb->type.fb_type = FBTYPE_NOTSUN1; diff -u --recursive --new-file v2.1.35/linux/drivers/sbus/sbus.c linux/drivers/sbus/sbus.c --- v2.1.35/linux/drivers/sbus/sbus.c Mon Apr 14 16:28:15 1997 +++ linux/drivers/sbus/sbus.c Tue Apr 15 21:47:23 1997 @@ -74,10 +74,10 @@ sbus_dev->slot = sbus_dev->reg_addrs[0].which_io; sbus_dev->offset = base; sbus_dev->reg_addrs[0].phys_addr = - (char *) sbus_devaddr(sbus_dev->slot, base); + sbus_devaddr(sbus_dev->slot, base); for(grrr=1; grrrnum_registers; grrr++) { base = (unsigned long) sbus_dev->reg_addrs[grrr].phys_addr; - sbus_dev->reg_addrs[grrr].phys_addr = (char *) + sbus_dev->reg_addrs[grrr].phys_addr = sbus_devaddr(sbus_dev->slot, base); } /* That surely sucked */ diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c --- v2.1.35/linux/drivers/scsi/53c7,8xx.c Sun Oct 6 22:55:47 1996 +++ linux/drivers/scsi/53c7,8xx.c Tue Apr 22 22:42:50 1997 @@ -253,6 +253,7 @@ #include #include #include +#include #undef current #include "scsi.h" @@ -877,7 +878,7 @@ * Returns : 0 on success, -1 on failure. */ -static int +static inline int NCR53c7x0_init (struct Scsi_Host *host) { NCR53c7x0_local_declare(); int i, ccf, expected_ccf; @@ -1187,10 +1188,10 @@ * */ -static int +__initfunc(static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, u32 base, int io_port, int irq, int dma, int pci_valid, - unsigned char pci_bus, unsigned char pci_device_fn, long long options) { + unsigned char pci_bus, unsigned char pci_device_fn, long long options)) { struct Scsi_Host *instance; struct NCR53c7x0_hostdata *hostdata; char chip_str[80]; @@ -1400,9 +1401,9 @@ * */ -static int +__initfunc(static int ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip, - unsigned char bus, unsigned char device_fn, long long options) { + unsigned char bus, unsigned char device_fn, long long options)) { unsigned short vendor_id, device_id, command; #ifdef LINUX_1_2 unsigned long @@ -1539,8 +1540,8 @@ * */ -int -NCR53c7xx_detect(Scsi_Host_Template *tpnt) { +__initfunc(int +NCR53c7xx_detect(Scsi_Host_Template *tpnt)) { int i; int current_override; int count; /* Number of boards detected */ diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c --- v2.1.35/linux/drivers/scsi/AM53C974.c Mon Apr 7 11:35:29 1997 +++ linux/drivers/scsi/AM53C974.c Tue Apr 22 22:42:50 1997 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -461,8 +462,8 @@ #endif /* AM53C974_DEBUG */ static void AM53C974_print(struct Scsi_Host *instance); static void AM53C974_keywait(void); -static int AM53C974_bios_detect(Scsi_Host_Template *tpnt); -static int AM53C974_nobios_detect(Scsi_Host_Template *tpnt); +static __inline__ int AM53C974_bios_detect(Scsi_Host_Template *tpnt); +static __inline__ int AM53C974_nobios_detect(Scsi_Host_Template *tpnt); static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config); static void AM53C974_config_after_reset(struct Scsi_Host *instance); static __inline__ void initialize_SCp(Scsi_Cmnd *cmd); @@ -739,7 +740,7 @@ * * Returns : number of host adapters detected **************************************************************************/ -int AM53C974_bios_detect(Scsi_Host_Template *tpnt) +static __inline__ int AM53C974_bios_detect(Scsi_Host_Template *tpnt) { int count = 0; /* number of boards detected */ int pci_index; @@ -804,7 +805,7 @@ * * Origin: Robin Cutshaw (robin@xfree86.org) **************************************************************************/ -int AM53C974_nobios_detect(Scsi_Host_Template *tpnt) +static __inline__ int AM53C974_nobios_detect(Scsi_Host_Template *tpnt) { int count = 0; /* number of boards detected */ pci_config_t pci_config; @@ -902,7 +903,7 @@ * * Returns : number of host adapters detected **************************************************************************/ -int AM53C974_detect(Scsi_Host_Template *tpnt) +__initfunc(int AM53C974_detect(Scsi_Host_Template *tpnt)) { int count; /* number of boards detected */ @@ -931,7 +932,7 @@ * set up by the BIOS (as reflected by contents of register CNTLREG1). * This is the only BIOS assistance we need. **************************************************************************/ -static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config) +__initfunc(static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config)) { AM53C974_local_declare(); int i, j; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c --- v2.1.35/linux/drivers/scsi/BusLogic.c Fri Apr 4 08:52:23 1997 +++ linux/drivers/scsi/BusLogic.c Tue Apr 22 22:42:50 1997 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -222,7 +223,8 @@ Host Adapter. */ -static boolean BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter)) { /* FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes. @@ -304,7 +306,8 @@ BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter. */ -static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)) { int Allocated; for (Allocated = 0; Allocated < HostAdapter->InitialCCBs; Allocated++) @@ -417,8 +420,8 @@ structure for Host Adapter. */ -static boolean BusLogic_CreateTargetDeviceStatistics(BusLogic_HostAdapter_T - *HostAdapter) +__initfunc(static boolean +BusLogic_CreateTargetDeviceStatistics(BusLogic_HostAdapter_T *HostAdapter)) { HostAdapter->TargetDeviceStatistics = (BusLogic_TargetDeviceStatistics_T *) @@ -708,7 +711,7 @@ only from the list of standard BusLogic MultiMaster ISA I/O Addresses. */ -static void BusLogic_InitializeProbeInfoListISA(void) +static inline void BusLogic_InitializeProbeInfoListISA(void) { int StandardAddressIndex; /* @@ -746,8 +749,9 @@ of increasing PCI Bus and Device Number. */ -static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList, - int ProbeInfoCount) +__initfunc(static void +BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList, + int ProbeInfoCount)) { int LastInterchange = ProbeInfoCount-1, Bound, j; while (LastInterchange > 0) @@ -781,7 +785,7 @@ I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found. */ -static int BusLogic_InitializeMultiMasterProbeInfo(void) +__initfunc(static int BusLogic_InitializeMultiMasterProbeInfo(void)) { boolean StandardAddressSeen[BusLogic_ISA_StandardAddressesCount]; BusLogic_ProbeInfo_T *PrimaryProbeInfo = @@ -1012,7 +1016,7 @@ number of FlashPoint Host Adapters found. */ -static int BusLogic_InitializeFlashPointProbeInfo(void) +__initfunc(static int BusLogic_InitializeFlashPointProbeInfo(void)) { int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0; unsigned char Bus, DeviceFunction, IRQ_Channel; @@ -1119,7 +1123,7 @@ particular probe order. */ -static void BusLogic_InitializeProbeInfoList(void) +static inline void BusLogic_InitializeProbeInfoList(void) { /* If BusLogic_Setup has provided an I/O Address probe list, do not override @@ -1228,7 +1232,8 @@ BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter. */ -static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_StatusRegister_T StatusRegister; BusLogic_InterruptRegister_T InterruptRegister; @@ -1422,7 +1427,8 @@ Host Adapter. It also determines the IRQ Channel for non-PCI Host Adapters. */ -static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_Configuration_T Configuration; BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation; @@ -1485,8 +1491,8 @@ from Host Adapter and initializes the Host Adapter structure. */ -static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T - *HostAdapter) +__initfunc(static boolean +BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_BoardID_T BoardID; BusLogic_Configuration_T Configuration; @@ -1999,8 +2005,8 @@ Host Adapter. */ -static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T - *HostAdapter) +__initfunc(static boolean +BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T *HostAdapter)) { unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1; unsigned short SynchronousPermitted, FastPermitted; @@ -2225,7 +2231,8 @@ Host Adapter. */ -static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)) { BusLogic_HostAdapter_T *FirstHostAdapter = BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel]; @@ -2311,7 +2318,8 @@ interrupts do not get through as a result. */ -static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter) +__initfunc(static boolean +BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)) { unsigned int InitialInterruptCount, FinalInterruptCount; int TestCount = 5, i; @@ -2600,9 +2608,10 @@ through explicit acquisition and release of the Host Adapter's Lock. */ -static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T - *HostAdapter, - SCSI_Host_T *Host) +__initfunc(static void +BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T + *HostAdapter, + SCSI_Host_T *Host)) { Host->max_id = HostAdapter->MaxTargetDevices; Host->max_lun = HostAdapter->MaxLogicalUnits; @@ -2673,7 +2682,7 @@ registered. */ -int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) +__initfunc(int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)) { int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0, ProbeIndex; char *MessageBuffer = NULL; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c --- v2.1.35/linux/drivers/scsi/NCR5380.c Tue Oct 29 06:21:11 1996 +++ linux/drivers/scsi/NCR5380.c Tue Apr 22 22:42:51 1997 @@ -596,7 +596,7 @@ } #endif /* def USLEEP */ -static void NCR5380_all_init (void) { +static inline void NCR5380_all_init (void) { static int done = 0; if (!done) { #if (NDEBUG & NDEBUG_INIT) @@ -625,12 +625,12 @@ */ -static int probe_irq; -static void probe_intr (int irq, void *dev_id, struct pt_regs * regs) { +static int probe_irq __initdata; +__initfunc(static void probe_intr (int irq, void *dev_id, struct pt_regs * regs)) { probe_irq = irq; }; -static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) { +__initfunc(static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible)) { NCR5380_local_declare(); struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; @@ -685,7 +685,7 @@ * Inputs : instance, pointer to this instance. Unused. */ -static void NCR5380_print_options (struct Scsi_Host *instance) { +__initfunc(static void NCR5380_print_options (struct Scsi_Host *instance)) { printk(" generic options" #ifdef AUTOPROBE_IRQ " AUTOPROBE_IRQ" @@ -900,7 +900,7 @@ * */ -static void NCR5380_init (struct Scsi_Host *instance, int flags) { +__initfunc(static void NCR5380_init (struct Scsi_Host *instance, int flags)) { NCR5380_local_declare(); int i, pass; unsigned long timeout; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c --- v2.1.35/linux/drivers/scsi/NCR53c406a.c Fri Dec 27 02:03:23 1996 +++ linux/drivers/scsi/NCR53c406a.c Tue Apr 22 22:42:51 1997 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -238,7 +239,7 @@ char *signature; int sig_offset; int sig_length; -} signatures[] = { +} signatures[] __initdata = { /* 1 2 3 4 5 6 */ /* 123456789012345678901234567890123456789012345678901234567890 */ { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82 }, @@ -458,8 +459,8 @@ } #endif USE_PIO -int -NCR53c406a_detect(Scsi_Host_Template * tpnt){ +__initfunc(int +NCR53c406a_detect(Scsi_Host_Template * tpnt)){ struct Scsi_Host *shpnt; #ifndef PORT_BASE int i; @@ -590,7 +591,7 @@ } /* called from init/main.c */ -void NCR53c406a_setup(char *str, int *ints) +__initfunc(void NCR53c406a_setup(char *str, int *ints)) { static size_t setup_idx = 0; size_t i; @@ -1011,7 +1012,7 @@ outb(SYNC_MODE, SYNCOFF); /* synchronous mode */ } -void calc_port_addr() +__initfunc(void calc_port_addr()) { /* Control Register Set 0 */ TC_LSB = (port_base+0x00); diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/a2091.c linux/drivers/scsi/a2091.c --- v2.1.35/linux/drivers/scsi/a2091.c Fri Dec 20 01:20:01 1996 +++ linux/drivers/scsi/a2091.c Thu Apr 17 13:20:46 1997 @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include "scsi.h" @@ -211,7 +211,7 @@ address = cd->cd_BoardAddr; instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); instance->base = (unsigned char *)ZTWO_VADDR(address); - instance->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC; + instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = key; DMA(instance)->DAWR = DAWR_A2091; wd33c93_init(instance, (wd33c93_regs *)&(DMA(instance)->SASR), diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/a3000.c linux/drivers/scsi/a3000.c --- v2.1.35/linux/drivers/scsi/a3000.c Fri Dec 20 01:20:02 1996 +++ linux/drivers/scsi/a3000.c Thu Apr 17 13:20:46 1997 @@ -181,7 +181,7 @@ a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); a3000_host->base = (unsigned char *)ZTWO_VADDR(0xDD0000); - a3000_host->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC; + a3000_host->irq = IRQ_AMIGA_PORTS; DMA(a3000_host)->DAWR = DAWR_A3000; wd33c93_init(a3000_host, (wd33c93_regs *)&(DMA(a3000_host)->SASR), dma_setup, dma_stop, WD33C93_FS_12_15); diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c --- v2.1.35/linux/drivers/scsi/advansys.c Thu Nov 14 16:45:57 1996 +++ linux/drivers/scsi/advansys.c Tue Apr 22 22:42:51 1997 @@ -542,6 +542,7 @@ #include #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) #include +#include #endif /* version >= v1.3.0 */ #include #include @@ -2953,8 +2954,8 @@ * it must not call SCSI mid-level functions including scsi_malloc() * and scsi_free(). */ -int -advansys_detect(Scsi_Host_Template *tpnt) +__initfunc(int +advansys_detect(Scsi_Host_Template *tpnt)) { static int detect_called = ASC_FALSE; int iop; @@ -5022,8 +5023,8 @@ /* * Search for an AdvanSys PCI device in the PCI configuration space. */ -STATIC int -asc_srch_pci_dev(PCI_DEVICE *pciDevice) +__initfunc(STATIC int +asc_srch_pci_dev(PCI_DEVICE *pciDevice)) { int ret; @@ -5059,8 +5060,8 @@ /* * Determine the access method to be used for 'pciDevice'. */ -STATIC uchar -asc_scan_method(void) +__initfunc(STATIC uchar +asc_scan_method(void)) { ushort data; PCI_DATA pciData; @@ -5089,8 +5090,8 @@ * * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND. */ -STATIC int -asc_pci_find_dev(PCI_DEVICE *pciDevice) +__initfunc(STATIC int +asc_pci_find_dev(PCI_DEVICE *pciDevice)) { PCI_DATA pciData; ushort vendorid, deviceid; @@ -5138,8 +5139,8 @@ /* * Read PCI configuration data into 'pciConfig'. */ -STATIC void -asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig) +__initfunc(STATIC void +asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)) { PCI_DATA pciData; uchar counter; @@ -5168,8 +5169,8 @@ * * The configuration mechanism is checked for the correct access method. */ -STATIC ushort -asc_get_cfg_word(PCI_DATA *pciData) +__initfunc(STATIC ushort +asc_get_cfg_word(PCI_DATA *pciData)) { ushort tmp; ulong address; @@ -5249,8 +5250,8 @@ * * The configuration mechanism is checked for the correct access method. */ -STATIC uchar -asc_get_cfg_byte(PCI_DATA *pciData) +__initfunc(STATIC uchar +asc_get_cfg_byte(PCI_DATA *pciData)) { uchar tmp; ulong address; @@ -5327,8 +5328,8 @@ /* * Write a byte to the PCI configuration space. */ -void -asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data) +__initfunc(void +asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)) { ulong tmpl; ulong address; @@ -6375,10 +6376,10 @@ /* * Read a PCI configuration byte. */ -uchar +__initfunc(uchar DvcReadPCIConfigByte( ASC_DVC_VAR asc_ptr_type *asc_dvc, - ushort offset ) + ushort offset )) { PCI_DATA pciData; @@ -6393,11 +6394,11 @@ /* * Write a PCI configuration byte. */ -void +__initfunc(void DvcWritePCIConfigByte( ASC_DVC_VAR asc_ptr_type *asc_dvc, ushort offset, - uchar byte_data ) + uchar byte_data )) { PCI_DATA pciData; @@ -6413,11 +6414,11 @@ * Return the BIOS address of the adapter at the specified * I/O port and with the specified bus type. */ -ushort +__initfunc(ushort AscGetChipBiosAddress( PortAddr iop_base, ushort bus_type - ) + )) { ushort cfg_lsw ; ushort bios_addr ; @@ -6927,11 +6928,11 @@ return (sc); } -uchar +__initfunc(uchar AscGetChipVersion( PortAddr iop_base, ushort bus_type -) +)) { if ((bus_type & ASC_IS_EISA) != 0) { PortAddr eisa_iop; @@ -6976,13 +6977,13 @@ return (0); } -ulong +__initfunc(ulong AscLoadMicroCode( PortAddr iop_base, ushort s_addr, ushort dosfar * mcode_buf, ushort mcode_size -) +)) { ulong chksum; ushort mcode_word_size; @@ -6999,10 +7000,10 @@ return (chksum); } -int +__initfunc(int AscFindSignature( PortAddr iop_base -) +)) { ushort sig_word; if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) { @@ -7022,11 +7023,11 @@ ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8 }; -PortAddr +__initfunc(PortAddr AscSearchIOPortAddr( PortAddr iop_beg, ushort bus_type -) +)) { if (bus_type & ASC_IS_VL) { while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { @@ -7057,10 +7058,10 @@ return (0); } -PortAddr +__initfunc(PortAddr AscSearchIOPortAddr11( PortAddr s_addr -) +)) { int i; PortAddr iop_base; @@ -7103,9 +7104,9 @@ }; #endif -void +__initfunc(void AscSetISAPNPWaitForKey( - void) + void)) { outp(ASC_ISA_PNP_PORT_ADDR, 0x02); outp(ASC_ISA_PNP_PORT_WRITE, 0x02); @@ -7768,7 +7769,7 @@ return (0); } -uchar _mcode_buf[ ] = { +uchar _mcode_buf[ ] __initdata = { 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -9192,10 +9193,10 @@ return; } -ulong +__initfunc(ulong AscGetEisaProductID( PortAddr iop_base -) +)) { PortAddr eisa_iop; ushort product_id_high, product_id_low; @@ -9207,10 +9208,10 @@ return (product_id); } -PortAddr +__initfunc(PortAddr AscSearchIOPortAddrEISA( PortAddr iop_base -) +)) { ulong eisa_product_id; if (iop_base == 0) { @@ -9469,10 +9470,10 @@ return (speed_value); } -ushort +__initfunc(ushort AscInitGetConfig( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { ushort warn_code; warn_code = 0; @@ -9500,10 +9501,10 @@ return (warn_code); } -ushort +__initfunc(ushort AscInitSetConfig( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { ushort warn_code; warn_code = 0; @@ -9519,10 +9520,10 @@ return (warn_code); } -ushort +__initfunc(ushort AscInitFromAscDvcVar( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { PortAddr iop_base; ushort cfg_msw; @@ -9603,10 +9604,10 @@ return (warn_code); } -ushort +__initfunc(ushort AscInitAsc1000Driver( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { ushort warn_code; PortAddr iop_base; @@ -9642,10 +9643,10 @@ return (warn_code); } -ushort +__initfunc(ushort AscInitAscDvcVar( ASC_DVC_VAR asc_ptr_type * asc_dvc -) +)) { int i; PortAddr iop_base; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c --- v2.1.35/linux/drivers/scsi/aic7xxx.c Thu Mar 27 14:40:05 1997 +++ linux/drivers/scsi/aic7xxx.c Wed Apr 23 08:54:21 1997 @@ -457,6 +457,7 @@ * sections. */ #define PAUSE_SEQUENCER(p) \ + synchronize_irq(); \ outb(p->pause, HCNTRL + p->base); \ while ((inb(HCNTRL + p->base) & PAUSE) == 0) \ ; \ diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/atari_NCR5380.c linux/drivers/scsi/atari_NCR5380.c --- v2.1.35/linux/drivers/scsi/atari_NCR5380.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/atari_NCR5380.c Thu Apr 17 13:20:46 1997 @@ -753,10 +753,6 @@ pos += sprintf(pos, fmt , ## args); } while(0) static char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length); -static -char *lprint_command (unsigned char *cmd, char *pos, char *buffer, int len); -static -char *lprint_opcode(int opcode, char *pos, char *buffer, int length); #ifndef NCR5380_proc_info static @@ -769,6 +765,14 @@ struct NCR5380_hostdata *hostdata; Scsi_Cmnd *ptr; unsigned long flags; + off_t begin = 0; +#define check_offset() \ + do { \ + if (pos - buffer < offset - begin) { \ + begin += pos - buffer; \ + pos = buffer; \ + } \ + } while (0) for (instance = first_instance; instance && HOSTNO != hostno; instance = instance->next) @@ -781,58 +785,54 @@ return(-ENOSYS); /* Currently this is a no-op */ } SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE); + check_offset(); save_flags(flags); cli(); SPRINTF("NCR5380: coroutine is%s running.\n", main_running ? "" : "n't"); + check_offset(); if (!hostdata->connected) SPRINTF("scsi%d: no currently connected command\n", HOSTNO); else pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected, pos, buffer, length); SPRINTF("scsi%d: issue_queue\n", HOSTNO); - for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) + check_offset(); + for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); + check_offset(); + } SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); + check_offset(); for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; - ptr = NEXT(ptr)) + ptr = NEXT(ptr)) { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); + check_offset(); + } restore_flags(flags); - *start = buffer; - if (pos - buffer < offset) + *start = buffer + (offset - begin); + if (pos - buffer < offset - begin) return 0; - else if (pos - buffer - offset < length) - return pos - buffer - offset; + else if (pos - buffer - (offset - begin) < length) + return pos - buffer - (offset - begin); return length; } static char * lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length) { + int i, s; + unsigned char *command; SPRINTF("scsi%d: destination target %d, lun %d\n", H_NO(cmd), cmd->target, cmd->lun); SPRINTF(" command = "); - pos = lprint_command (cmd->cmnd, pos, buffer, length); - return (pos); -} - -static char * -lprint_command (unsigned char *command, char *pos, char *buffer, int length) -{ - int i, s; - pos = lprint_opcode(command[0], pos, buffer, length); + command = cmd->cmnd; + SPRINTF("%2d (0x%02x)", command[0], command[0]); for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) - SPRINTF("%02x ", command[i]); + SPRINTF(" %02x", command[i]); SPRINTF("\n"); - return(pos); -} - -static -char *lprint_opcode(int opcode, char *pos, char *buffer, int length) -{ - SPRINTF("%2d (0x%02x)", opcode, opcode); - return(pos); + return pos; } diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c --- v2.1.35/linux/drivers/scsi/atari_scsi.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/atari_scsi.c Thu Apr 17 13:20:46 1997 @@ -239,13 +239,18 @@ static int atari_read_overruns = 0; #endif -int setup_can_queue = -1; -int setup_cmd_per_lun = -1; -int setup_sg_tablesize = -1; +static int setup_can_queue = -1; +MODULE_PARM(setup_can_queue, "i"); +static int setup_cmd_per_lun = -1; +MODULE_PARM(setup_cmd_per_lun, "i"); +static int setup_sg_tablesize = -1; +MODULE_PARM(setup_sg_tablesize, "i"); #ifdef SUPPORT_TAGS -int setup_use_tagged_queuing = -1; +static int setup_use_tagged_queuing = -1; +MODULE_PARM(setup_use_tagged_queuing, "i"); #endif -int setup_hostid = -1; +static int setup_hostid = -1; +MODULE_PARM(setup_hostid, "i"); #if defined(REAL_DMA) @@ -660,7 +665,7 @@ if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; #endif - +#ifdef REAL_DMA /* If running on a Falcon and if there's TT-Ram (i.e., more than one * memory block, since there's always ST-Ram in a Falcon), then allocate a * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative @@ -673,10 +678,14 @@ atari_dma_phys_buffer = VTOP( atari_dma_buffer ); atari_dma_orig_addr = 0; } - +#endif instance = scsi_register (host, sizeof (struct NCR5380_hostdata)); atari_scsi_host = instance; - instance->irq = IS_A_TT() ? IRQ_TT_MFP_SCSI : IRQ_MFP_FSCSI; + /* Set irq to 0, to avoid that the mid-level code disables our interrupt + * during queue_command calls. This is completely unnecessary, and even + * worse causes bad problems on the Falcon, where the int is shared with + * IDE and floppy! */ + instance->irq = 0; atari_scsi_reset_boot(); NCR5380_init (instance, 0); @@ -693,8 +702,8 @@ tt_scsi_dma.dma_ctrl = 0; atari_dma_residual = 0; #endif /* REAL_DMA */ - - if (is_medusa) { +#ifdef REAL_DMA + if (is_medusa || is_hades) { /* While the read overruns (described by Drew Eckhardt in * NCR5380.c) never happened on TTs, they do in fact on the Medusa * (This was the cause why SCSI didn't work right for so long @@ -709,6 +718,7 @@ */ atari_read_overruns = 4; } +#endif } else { /* ! IS_A_TT */ diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/dtc.c linux/drivers/scsi/dtc.c --- v2.1.35/linux/drivers/scsi/dtc.c Mon Mar 17 14:54:29 1997 +++ linux/drivers/scsi/dtc.c Tue Apr 22 22:42:51 1997 @@ -84,8 +84,9 @@ #include "NCR5380.h" #include "constants.h" #include "sd.h" -#include -#include +#include +#include +#include #define DTC_PUBLIC_RELEASE 2 @@ -145,9 +146,9 @@ int irq; } overrides #ifdef OVERRIDE -[] = OVERRIDE; +[] __initdata = OVERRIDE; #else -[4] = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}}; +[4] __initdata = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}}; #endif #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) @@ -155,7 +156,7 @@ static struct base { unsigned int address; int noauto; -} bases[] = {{0xcc000, 0}, {0xc8000, 0}, {0xdc000, 0}, {0xd8000, 0}}; +} bases[] __initdata = {{0xcc000, 0}, {0xc8000, 0}, {0xdc000, 0}, {0xd8000, 0}}; #define NO_BASES (sizeof (bases) / sizeof (struct base)) @@ -176,7 +177,7 @@ * */ -void dtc_setup(char *str, int *ints) { +__initfunc(void dtc_setup(char *str, int *ints)) { static int commandline_current = 0; int i; if (ints[0] != 2) @@ -208,7 +209,7 @@ */ -int dtc_detect(Scsi_Host_Template * tpnt) { +__initfunc(int dtc_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0, current_base = 0; struct Scsi_Host *instance; unsigned int base; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/esp.c linux/drivers/scsi/esp.c --- v2.1.35/linux/drivers/scsi/esp.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/esp.c Thu Apr 17 13:20:47 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -639,7 +640,7 @@ /* Detecting ESP chips on the machine. This is the simple and easy * version. */ -int esp_detect(Scsi_Host_Template *tpnt) +__initfunc(int esp_detect(Scsi_Host_Template *tpnt)) { struct Sparc_ESP *esp, *elink; struct Scsi_Host *esp_host; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c --- v2.1.35/linux/drivers/scsi/g_NCR5380.c Mon Apr 7 11:35:29 1997 +++ linux/drivers/scsi/g_NCR5380.c Tue Apr 22 22:42:51 1997 @@ -103,7 +103,8 @@ #include "NCR5380.h" #include "constants.h" #include "sd.h" -#include +#include +#include struct proc_dir_entry proc_scsi_g_ncr5380 = { PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380", @@ -124,9 +125,9 @@ int board; /* Use NCR53c400, Ricoh, etc. extensions ? */ } overrides #ifdef GENERIC_NCR5380_OVERRIDE - [] = GENERIC_NCR5380_OVERRIDE + [] __initdata = GENERIC_NCR5380_OVERRIDE #else - [1] = {{0,},}; + [1] __initdata = {{0,},}; #endif #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) @@ -142,7 +143,7 @@ * */ -static void internal_setup(int board, char *str, int *ints) { +__initfunc(static void internal_setup(int board, char *str, int *ints)) { static int commandline_current = 0; switch (board) { case BOARD_NCR5380: @@ -178,7 +179,7 @@ * equal to the number of ints. */ -void generic_NCR5380_setup (char *str, int *ints) { +__initfunc(void generic_NCR5380_setup (char *str, int *ints)) { internal_setup (BOARD_NCR5380, str, ints); } @@ -191,7 +192,7 @@ * equal to the number of ints. */ -void generic_NCR53C400_setup (char *str, int *ints) { +__initfunc(void generic_NCR53C400_setup (char *str, int *ints)) { internal_setup (BOARD_NCR53C400, str, ints); } @@ -207,7 +208,7 @@ * */ -int generic_NCR5380_detect(Scsi_Host_Template * tpnt) { +__initfunc(int generic_NCR5380_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0; int count; int flags = 0; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/gvp11.c linux/drivers/scsi/gvp11.c --- v2.1.35/linux/drivers/scsi/gvp11.c Fri Dec 20 01:20:02 1996 +++ linux/drivers/scsi/gvp11.c Thu Apr 17 13:20:47 1997 @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include "scsi.h" @@ -204,7 +204,7 @@ struct Scsi_Host *instance; caddr_t address; enum GVP_ident epc; - int key; + int key = 0; struct ConfigDev *cd; if (!MACH_IS_AMIGA || called) @@ -214,9 +214,18 @@ tpnt->proc_dir = &proc_scsi_gvp11; tpnt->proc_info = &wd33c93_proc_info; - while ((key = zorro_find(MANUF_GVP, PROD_GVPIISCSI, 0, 0))) { + while ((key = zorro_find(MANUF_GVP, PROD_GVPIISCSI, 0, key))) { cd = zorro_get_board(key); address = cd->cd_BoardAddr; + + /* + * Rumors state that some GVP ram boards use the same product + * code as the SCSI controllers. Therefore if the board-size + * is not 64KB we asume it is a ram board and bail out. + */ + if (cd->cd_BoardSize != 0x10000) + continue; + /* check extended product code */ epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000); epc = epc & GVP_PRODMASK; @@ -237,7 +246,7 @@ instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); instance->base = (unsigned char *)ZTWO_VADDR(address); - instance->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC; + instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = key; if (gvp11_xfer_mask) @@ -307,11 +316,11 @@ int gvp11_release(struct Scsi_Host *instance) { #ifdef MODULE -DMA(instance)->CNTR = 0; -zorro_unconfig_board(instance->unique_id, 0); -if (--num_gvp11 == 0) - free_irq(IRQ_AMIGA_PORTS, gvp11_intr); - wd33c93_release(); + DMA(instance)->CNTR = 0; + zorro_unconfig_board(instance->unique_id, 0); + if (--num_gvp11 == 0) + free_irq(IRQ_AMIGA_PORTS, gvp11_intr); + wd33c93_release(); #endif -return 1; + return 1; } diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.1.35/linux/drivers/scsi/hosts.c Fri Dec 13 01:37:37 1996 +++ linux/drivers/scsi/hosts.c Tue Apr 22 22:42:51 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #include "scsi.h" @@ -433,7 +434,7 @@ return 0; } -unsigned int scsi_init() +__initfunc(unsigned int scsi_init(void)) { static int called = 0; int i, pcount; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.1.35/linux/drivers/scsi/ncr53c8xx.c Sun Apr 13 10:18:21 1997 +++ linux/drivers/scsi/ncr53c8xx.c Tue Apr 22 08:30:20 1997 @@ -40,7 +40,7 @@ */ /* -** 6 April 1997, version 1.18d +** 16 April 1997, version 1.18e ** ** Supported SCSI-II features: ** Synchronous negotiation @@ -1735,7 +1735,7 @@ 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); } @@ -4520,7 +4520,7 @@ ** **========================================================== */ -int ncr_reset_bus (Scsi_Cmnd *cmd) +int ncr_reset_bus (Scsi_Cmnd *cmd, int sync_reset) { struct Scsi_Host *host = cmd->host; /* Scsi_Device *device = cmd->device; */ @@ -4572,11 +4572,12 @@ */ ncr_wakeup(np, HS_RESET); /* - * If the involved command was not in a driver queue, and is - * not in the waiting list, complete it with DID_RESET status, + * If the involved command was not in a driver queue, and the + * scsi driver told us reset is synchronous, and the command is not + * currently in the waiting list, complete it with DID_RESET status, * in order to keep it alive. */ - if (!found && cmd && !remove_from_waiting_list(np, cmd)) { + if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) { cmd->result = ScsiResult(DID_RESET, 0); cmd->scsi_done(cmd); } @@ -6363,27 +6364,13 @@ ((INL(nc_dbc) & 0xf8000000) == SCR_WAIT_DISC)) { /* ** Unexpected data cycle while waiting for disconnect. - */ - if (INB(nc_sstat2) & LDSC) { - /* - ** It's an early reconnect. - ** Let's continue ... - */ - OUTONB (nc_dcntl, (STD|NOCOM)); - /* - ** info message - */ - printf ("%s: INFO: LDSC while IID.\n", - ncr_name (np)); - return; - }; - printf ("%s: target %d doesn't release the bus.\n", - ncr_name (np), (int)INB (nc_ctest0)&0x0f); - /* - ** return without restarting the NCR. - ** timeout will do the real work. - */ - return; + ** LDSC and CON bits may help in order to understand + ** what really happened. Print some info message and let + ** the reset function reset the BUS and the NCR. + */ + printf("%s:%d: data cycle while waiting for disconnect, LDSC=%d CON=%d\n", + ncr_name (np), (int)(INB(nc_ctest0)&0x0f), + (0!=(INB(nc_sstat2)&LDSC)), (0!=(INB(nc_scntl1)&ISCON))); }; /*---------------------------------------- @@ -7375,7 +7362,7 @@ /*========================================================== ** ** -** Aquire a control block +** Acquire a control block ** ** **========================================================== @@ -8617,25 +8604,93 @@ ** Linux entry point of reset() function */ -#if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,98) +#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS + int ncr53c8xx_reset(Scsi_Cmnd *cmd, unsigned int reset_flags) +{ + int sts; + unsigned long flags; + + printk("ncr53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n", + cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout); + + save_flags(flags); cli(); + + /* + * We have to just ignore reset requests in some situations. + */ +#if defined SCSI_RESET_NOT_RUNNING + if (cmd->serial_number != cmd->serial_number_at_timeout) { + sts = SCSI_RESET_NOT_RUNNING; + goto out; + } +#endif + /* + * If the mid-level driver told us reset is synchronous, it seems + * that we must call the done() callback for the involved command, + * even if this command was not queued to the low-level driver, + * before returning SCSI_RESET_SUCCESS. + */ + + sts = ncr_reset_bus(cmd, + (reset_flags & (SCSI_RESET_SYNCHRONOUS | SCSI_RESET_ASYNCHRONOUS)) == SCSI_RESET_SYNCHRONOUS); + /* + * Since we always reset the controller, when we return success, + * we add this information to the return code. + */ +#if defined SCSI_RESET_HOST_RESET + if (sts == SCSI_RESET_SUCCESS) + sts |= SCSI_RESET_HOST_RESET; +#endif + +out: + restore_flags(flags); + return sts; +} #else int ncr53c8xx_reset(Scsi_Cmnd *cmd) -#endif { printk("ncr53c8xx_reset: command pid %lu\n", cmd->pid); - return ncr_reset_bus(cmd); + return ncr_reset_bus(cmd, 1); } +#endif /* ** Linux entry point of abort() function */ +#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS + +int ncr53c8xx_abort(Scsi_Cmnd *cmd) +{ + int sts; + unsigned long flags; + + printk("ncr53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n", + cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout); + + save_flags(flags); cli(); + + /* + * We have to just ignore abort requests in some situations. + */ + if (cmd->serial_number != cmd->serial_number_at_timeout) { + sts = SCSI_ABORT_NOT_RUNNING; + goto out; + } + + sts = ncr_abort_command(cmd); +out: + restore_flags(flags); + return sts; +} +#else int ncr53c8xx_abort(Scsi_Cmnd *cmd) { printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid); return ncr_abort_command(cmd); } +#endif #ifdef MODULE int ncr53c8xx_release(struct Scsi_Host *host) diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h --- v2.1.35/linux/drivers/scsi/ncr53c8xx.h Sun Apr 13 10:18:21 1997 +++ linux/drivers/scsi/ncr53c8xx.h Wed Apr 23 11:01:37 1997 @@ -45,7 +45,7 @@ /* ** Name and revision of the driver */ -#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.18d" +#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.18f" /* ** If SCSI_NCR_SETUP_SPECIAL_FEATURES is defined, diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c --- v2.1.35/linux/drivers/scsi/pas16.c Mon May 6 02:26:11 1996 +++ linux/drivers/scsi/pas16.c Tue Apr 22 22:42:51 1997 @@ -120,7 +120,8 @@ #include "constants.h" #include "sd.h" -#include +#include +#include struct proc_dir_entry proc_scsi_pas16 = { PROC_SCSI_PAS16, 5, "pas16", @@ -138,20 +139,21 @@ * irq jumpers on the board). The first value in the array will be * assigned to logical board 0, the next to board 1, etc. */ -int default_irqs[] = { PAS16_DEFAULT_BOARD_1_IRQ, - PAS16_DEFAULT_BOARD_2_IRQ, - PAS16_DEFAULT_BOARD_3_IRQ, - PAS16_DEFAULT_BOARD_4_IRQ - }; +int default_irqs[] __initdata = + { PAS16_DEFAULT_BOARD_1_IRQ, + PAS16_DEFAULT_BOARD_2_IRQ, + PAS16_DEFAULT_BOARD_3_IRQ, + PAS16_DEFAULT_BOARD_4_IRQ + }; static struct override { unsigned short io_port; int irq; } overrides #ifdef PAS16_OVERRIDE - [] = PAS16_OVERRIDE; + [] __initdata = PAS16_OVERRIDE; #else - [4] = {{0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO}, + [4] __initdata = {{0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO}}; #endif @@ -160,11 +162,12 @@ static struct base { unsigned short io_port; int noauto; -} bases[] = { {PAS16_DEFAULT_BASE_1, 0}, - {PAS16_DEFAULT_BASE_2, 0}, - {PAS16_DEFAULT_BASE_3, 0}, - {PAS16_DEFAULT_BASE_4, 0} - }; +} bases[] __initdata = + { {PAS16_DEFAULT_BASE_1, 0}, + {PAS16_DEFAULT_BASE_2, 0}, + {PAS16_DEFAULT_BASE_3, 0}, + {PAS16_DEFAULT_BASE_4, 0} + }; #define NO_BASES (sizeof (bases) / sizeof (struct base)) @@ -210,7 +213,8 @@ * */ -void enable_board( int board_num, unsigned short port ) +__initfunc(static void + enable_board( int board_num, unsigned short port )) { outb( 0xbc + board_num, MASTER_ADDRESS_PTR ); outb( port >> 2, MASTER_ADDRESS_PTR ); @@ -229,7 +233,8 @@ * */ -void init_board( unsigned short io_port, int irq, int force_irq ) +__initfunc (static void + init_board( unsigned short io_port, int irq, int force_irq )) { unsigned int tmp; unsigned int pas_irq_code; @@ -277,7 +282,8 @@ * Returns : 0 if board not found, 1 if found. */ -int pas16_hw_detect( unsigned short board_num ) +__initfunc(static int + pas16_hw_detect( unsigned short board_num )) { unsigned char board_rev, tmp; unsigned short io_port = bases[ board_num ].io_port; @@ -336,7 +342,7 @@ * */ -void pas16_setup(char *str, int *ints) { +__initfunc(void pas16_setup(char *str, int *ints)) { static int commandline_current = 0; int i; if (ints[0] != 2) @@ -367,7 +373,7 @@ * */ -int pas16_detect(Scsi_Host_Template * tpnt) { +__initfunc(int pas16_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0; static unsigned short current_base = 0; struct Scsi_Host *instance; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c --- v2.1.35/linux/drivers/scsi/ppa.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/ppa.c Thu Apr 17 14:48:53 1997 @@ -1132,69 +1132,72 @@ nhosts = 0; for (i = 0; pb; i++, pb=pb->next) { - int modes; + int modes = pb->modes; - /* transfer global values here */ - if (ppa_speed >= 0) - ppa_hosts[i].speed = ppa_speed; - if (ppa_speed_fast >= 0) - ppa_hosts[i].speed_fast = ppa_speed_fast; + /* We only understand PC-style ports */ + if (modes & PARPORT_MODE_SPP) { - ppa_hosts[i].dev = - parport_register_device(pb, "ppa", NULL, ppa_wakeup, - NULL, PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]); - - /* Claim the bus so it remembers what we do to the control - * registers. [ CTR and ECP ] - */ - ppa_pb_claim(i); - w_ctr(i, 0x0c); - modes = ppa_hosts[i].dev->port->modes; - - ppa_hosts[i].mode = PPA_NIBBLE; - if (modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) { - ppa_hosts[i].mode = PPA_EPP_32; - printk("PPA: Parport [ EPP ]\n"); - } else if (modes & PARPORT_MODE_ECP) { - w_ecr(i, 0x20); - ppa_hosts[i].mode = PPA_PS2; - printk("PPA: Parport [ ECP in PS2 submode ]\n"); - } else if (modes & PARPORT_MODE_PS2) { - ppa_hosts[i].mode = PPA_PS2; - printk("PPA: Parport [ PS2 ]\n"); - } - /* Done configuration */ - ppa_pb_release(i); - - rs = ppa_init(i); - if (rs) { - parport_unregister_device(ppa_hosts[i].dev); - continue; - } - /* now the glue ... */ - switch (ppa_hosts[i].mode) { - case PPA_NIBBLE: - case PPA_PS2: - ports = 3; - break; - case PPA_EPP_8: - case PPA_EPP_16: - case PPA_EPP_32: - ports = 8; - break; - default: /* Never gets here */ - continue; + /* transfer global values here */ + if (ppa_speed >= 0) + ppa_hosts[i].speed = ppa_speed; + if (ppa_speed_fast >= 0) + ppa_hosts[i].speed_fast = ppa_speed_fast; + + ppa_hosts[i].dev = parport_register_device(pb, "ppa", + NULL, ppa_wakeup, NULL, + PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]); + + /* Claim the bus so it remembers what we do to the + * control registers. [ CTR and ECP ] + */ + ppa_pb_claim(i); + w_ctr(i, 0x0c); + + ppa_hosts[i].mode = PPA_NIBBLE; + if (modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) { + ppa_hosts[i].mode = PPA_EPP_32; + printk("PPA: Parport [ EPP ]\n"); + } else if (modes & PARPORT_MODE_ECP) { + w_ecr(i, 0x20); + ppa_hosts[i].mode = PPA_PS2; + printk("PPA: Parport [ ECP in PS2 submode ]\n"); + } else if (modes & PARPORT_MODE_PS2) { + ppa_hosts[i].mode = PPA_PS2; + printk("PPA: Parport [ PS2 ]\n"); + } + /* Done configuration */ + ppa_pb_release(i); + + rs = ppa_init(i); + if (rs) { + parport_unregister_device(ppa_hosts[i].dev); + continue; + } + /* now the glue ... */ + switch (ppa_hosts[i].mode) { + case PPA_NIBBLE: + case PPA_PS2: + ports = 3; + break; + case PPA_EPP_8: + case PPA_EPP_16: + case PPA_EPP_32: + ports = 8; + break; + default: /* Never gets here */ + continue; + } + + host->can_queue = PPA_CAN_QUEUE; + host->sg_tablesize = ppa_sg; + hreg = scsi_register(host, 0); + hreg->io_port = pb->base; + hreg->n_io_port = ports; + hreg->dma_channel = -1; + hreg->unique_id = i; + ppa_hosts[i].host = hreg->host_no; + nhosts++; } - - host->can_queue = PPA_CAN_QUEUE; - host->sg_tablesize = ppa_sg; - hreg = scsi_register(host, 0); - hreg->io_port = pb->base; - hreg->n_io_port = ports; - hreg->dma_channel = -1; - hreg->unique_id = i; - ppa_hosts[i].host = hreg->host_no; - nhosts++; } if (nhosts == 0) return 0; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c --- v2.1.35/linux/drivers/scsi/qlogicpti.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/qlogicpti.c Thu Apr 17 13:20:47 1997 @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -342,7 +343,7 @@ #define PTI_RESET_LIMIT 400 -static int qlogicpti_load_firmware(struct qlogicpti *qpti) +__initfunc(static int qlogicpti_load_firmware(struct qlogicpti *qpti)) { struct qlogicpti_regs *qregs = qpti->qregs; unsigned short csum = 0; @@ -561,7 +562,7 @@ static void qlogicpti_intr_handler(int irq, void *dev_id, struct pt_regs *regs); /* Detect all PTI Qlogic ISP's in the machine. */ -int qlogicpti_detect(Scsi_Host_Template *tpnt) +__initfunc(int qlogicpti_detect(Scsi_Host_Template *tpnt)) { struct qlogicpti *qpti, *qlink; struct Scsi_Host *qpti_host; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/qlogicpti_asm.c linux/drivers/scsi/qlogicpti_asm.c --- v2.1.35/linux/drivers/scsi/qlogicpti_asm.c Fri Dec 13 01:37:38 1996 +++ linux/drivers/scsi/qlogicpti_asm.c Thu Apr 17 13:20:47 1997 @@ -2,7 +2,7 @@ unsigned short risc_code_addr01 = 0x1000; -unsigned short risc_code01[] = { +unsigned short risc_code01[] __initdata = { 0x0078, 0x1030, 0x0000, 0x231f, 0x0000, 0x12ff, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.1.35/linux/drivers/scsi/scsi.c Mon Apr 7 11:35:30 1997 +++ linux/drivers/scsi/scsi.c Tue Apr 22 22:42:51 1997 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -2537,7 +2538,7 @@ * initialization, bus scanning, and sd/st initialization routines. */ -int scsi_dev_init(void) +__initfunc(int scsi_dev_init(void)) { Scsi_Device * SDpnt; struct Scsi_Host * shpnt; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c --- v2.1.35/linux/drivers/scsi/t128.c Mon Mar 17 14:54:30 1997 +++ linux/drivers/scsi/t128.c Tue Apr 22 22:42:51 1997 @@ -118,7 +118,8 @@ #include "NCR5380.h" #include "constants.h" #include "sd.h" -#include +#include +#include struct proc_dir_entry proc_scsi_t128 = { PROC_SCSI_T128, 4, "t128", @@ -131,10 +132,10 @@ int irq; } overrides #ifdef T128_OVERRIDE - [] = T128_OVERRIDE; + [] __initdata = T128_OVERRIDE; #else - [4] = {{NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, - {NULL,IRQ_AUTO}}; + [4] __initdata = {{NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, + {NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}}; #endif #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) @@ -142,7 +143,8 @@ static struct base { unsigned char *address; int noauto; -} bases[] = {{(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0}, +} bases[] __initdata = { + {(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0}, {(unsigned char *) 0xdc000, 0}, {(unsigned char *) 0xd8000, 0}}; #define NO_BASES (sizeof (bases) / sizeof (struct base)) @@ -150,7 +152,7 @@ static const struct signature { const char *string; int offset; -} signatures[] = { +} signatures[] __initdata = { {"TSROM: SCSI BIOS, Version 1.12", 0x36}, }; @@ -166,7 +168,7 @@ * */ -void t128_setup(char *str, int *ints) { +__initfunc(void t128_setup(char *str, int *ints)) { static int commandline_current = 0; int i; if (ints[0] != 2) @@ -197,7 +199,7 @@ * */ -int t128_detect(Scsi_Host_Template * tpnt) { +__initfunc(int t128_detect(Scsi_Host_Template * tpnt)) { static int current_override = 0, current_base = 0; struct Scsi_Host *instance; unsigned char *base; diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/wd33c93.c linux/drivers/scsi/wd33c93.c --- v2.1.35/linux/drivers/scsi/wd33c93.c Fri Dec 20 01:20:02 1996 +++ linux/drivers/scsi/wd33c93.c Thu Apr 17 13:20:47 1997 @@ -28,9 +28,9 @@ * * - Target Disconnection/Reconnection is now supported. Any * system with more than one device active on the SCSI bus - * will benefit from this. The driver defaults to what I'm - * 'adaptive disconnect' - meaning that each command is - * evaluated individually as to whether or not it should + * will benefit from this. The driver defaults to what I + * call 'adaptive disconnect' - meaning that each command + * is evaluated individually as to whether or not it should * be run with the option to disconnect/reselect (if the * device chooses), or as a "SCSI-bus-hog". * @@ -87,23 +87,19 @@ #include "hosts.h" -#define PROC_INTERFACE /* add code for /proc/scsi/wd33c93/xxx interface */ -#ifdef PROC_INTERFACE -#define PROC_STATISTICS /* add code for keeping various real time stats */ -#endif - -#define SYNC_DEBUG /* extra info on sync negotiation printed */ -#undef DEBUGGING_ON /* enable command-line debugging bitmask */ -#define DEBUG_DEFAULTS 0 /* default debugging bitmask */ - -#define WD33C93_VERSION "1.23" -#define WD33C93_DATE "04/Nov/1996" +#define WD33C93_VERSION "1.24" +#define WD33C93_DATE "29/Jan/1997" -#ifdef DEBUGGING_ON -#define DB(f,a) if (hostdata->args & (f)) a; -#else -#define DB(f,a) -#endif +/* + * Note - the following defines have been moved to 'wd33c93.h': + * + * PROC_INTERFACE + * PROC_STATISTICS + * SYNC_DEBUG + * DEBUGGING_ON + * DEBUG_DEFAULTS + * + */ #include "wd33c93.h" @@ -118,10 +114,11 @@ * keywords (lower case required) and arguments: * * - nosync:bitmask -bitmask is a byte where the 1st 7 bits correspond with - * the 7 possible SCSI devices. Set a bit to prevent sync - * negotiation on that device. To maintain backwards - * compatibility, a command-line such as "wd33c93=255" will - * be automatically translated to "wd33c93=nosync:0xff". + * the 7 possible SCSI devices. Set a bit to negotiate for + * asynchronous transfers on that device. To maintain + * backwards compatibility, a command-line such as + * "wd33c93=255" will be automatically translated to + * "wd33c93=nosync:0xff". * - nodma:x -x = 1 to disable DMA, x = 0 to enable it. Argument is * optional - if not present, same as "nodma:1". * - period:ns -ns is the minimum # of nanoseconds in a SCSI data transfer @@ -166,7 +163,7 @@ -inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num) +static inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num) { regp->SASR = reg_num; return(regp->SCMD); @@ -176,21 +173,21 @@ #define READ_AUX_STAT() (regp->SASR) -inline void write_wd33c93(wd33c93_regs *regp,uchar reg_num, uchar value) +static inline void write_wd33c93(wd33c93_regs *regp,uchar reg_num, uchar value) { regp->SASR = reg_num; regp->SCMD = value; } -inline void write_wd33c93_cmd(wd33c93_regs *regp, uchar cmd) +static inline void write_wd33c93_cmd(wd33c93_regs *regp, uchar cmd) { regp->SASR = WD_COMMAND; regp->SCMD = cmd; } -inline uchar read_1_byte(wd33c93_regs *regp) +static inline uchar read_1_byte(wd33c93_regs *regp) { uchar asr; uchar x = 0; @@ -206,7 +203,7 @@ } -void write_wd33c93_count(wd33c93_regs *regp,unsigned long value) +static void write_wd33c93_count(wd33c93_regs *regp,unsigned long value) { regp->SASR = WD_TRANSFER_COUNT_MSB; regp->SCMD = value >> 16; @@ -215,7 +212,7 @@ } -unsigned long read_wd33c93_count(wd33c93_regs *regp) +static unsigned long read_wd33c93_count(wd33c93_regs *regp) { unsigned long value; @@ -265,7 +262,7 @@ {1000,0x00}, {0, 0} }; -int round_period(unsigned int period) +static int round_period(unsigned int period) { int x; @@ -278,7 +275,7 @@ return 7; } -uchar calc_sync_xfer(unsigned int period, unsigned int offset) +static uchar calc_sync_xfer(unsigned int period, unsigned int offset) { uchar result; @@ -290,14 +287,13 @@ -void wd33c93_execute(struct Scsi_Host *instance); +static void wd33c93_execute(struct Scsi_Host *instance); int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { -struct WD33C93_hostdata *hostdata; -Scsi_Cmnd *tmp; - - disable_irq(cmd->host->irq); + struct WD33C93_hostdata *hostdata; + Scsi_Cmnd *tmp; + unsigned long flags; hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata; @@ -351,6 +347,9 @@ * sense data is not lost before REQUEST_SENSE executes. */ + save_flags(flags); + cli(); + if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) { cmd->host_scribble = (uchar *)hostdata->input_Q; hostdata->input_Q = cmd; @@ -370,7 +369,7 @@ DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid)) - enable_irq(cmd->host->irq); + restore_flags(flags); return 0; } @@ -381,15 +380,18 @@ * already connected, we give up immediately. Otherwise, look through * the input_Q, using the first command we find that's intended * for a currently non-busy target/lun. + * + * wd33c93_execute() is always called with interrupts disabled or from + * the wd33c93_intr itself, which means that a wd33c93 interrupt + * cannot occur while we are in here. */ -void wd33c93_execute (struct Scsi_Host *instance) +static void wd33c93_execute (struct Scsi_Host *instance) { struct WD33C93_hostdata *hostdata; wd33c93_regs *regp; Scsi_Cmnd *cmd, *prev; int i; - disable_irq(instance->irq); hostdata = (struct WD33C93_hostdata *)instance->hostdata; regp = hostdata->regp; @@ -399,7 +401,6 @@ DB(DB_EXECUTE,printk(")EX-0 ")) - enable_irq(instance->irq); return; } @@ -423,7 +424,6 @@ DB(DB_EXECUTE,printk(")EX-1 ")) - enable_irq(instance->irq); return; } @@ -500,6 +500,7 @@ #endif no: + write_wd33c93(regp, WD_SOURCE_ID, ((cmd->SCp.phase)?SRCID_ER:0)); write_wd33c93(regp, WD_TARGET_LUN, cmd->lun); @@ -525,17 +526,14 @@ * sync_xfer[] entry is initialized to the default/safe value. SS_UNSET * means that the parameters are undetermined as yet, and that we * need to send an SDTR message to this device after selection is - * complete. We set SS_FIRST to tell the interrupt routine to do so, - * unless we've been asked not to try synchronous transfers on this - * target (and _all_ luns within it): In this case we set SS_SET to - * make the defaults final. - */ - if (hostdata->sync_stat[cmd->target] == SS_UNSET) { - if (hostdata->no_sync & (1 << cmd->target)) - hostdata->sync_stat[cmd->target] = SS_SET; - else + * complete: We set SS_FIRST to tell the interrupt routine to do so. + * If we've been asked not to try synchronous transfers on this + * target (and _all_ luns within it), we'll still send the SDTR message + * later, but at that time we'll negotiate for async by specifying a + * sync fifo depth of 0. + */ + if (hostdata->sync_stat[cmd->target] == SS_UNSET) hostdata->sync_stat[cmd->target] = SS_FIRST; - } hostdata->state = S_SELECTING; write_wd33c93_count(regp,0); /* guarantee a DATA_PHASE interrupt */ write_wd33c93_cmd(regp, WD_CMD_SEL_ATN); @@ -600,13 +598,11 @@ */ DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid)) - - enable_irq(instance->irq); } -void transfer_pio(wd33c93_regs *regp, uchar *buf, int cnt, +static void transfer_pio(wd33c93_regs *regp, uchar *buf, int cnt, int data_in_dir, struct WD33C93_hostdata *hostdata) { uchar asr; @@ -642,7 +638,7 @@ -void transfer_bytes(wd33c93_regs *regp, Scsi_Cmnd *cmd, int data_in_dir) +static void transfer_bytes(wd33c93_regs *regp, Scsi_Cmnd *cmd, int data_in_dir) { struct WD33C93_hostdata *hostdata; unsigned long length; @@ -725,7 +721,7 @@ Scsi_Cmnd *patch, *cmd; wd33c93_regs *regp; uchar asr, sr, phs, id, lun, *ucp, msg; -unsigned long length; +unsigned long length, flags; hostdata = (struct WD33C93_hostdata *)instance->hostdata; regp = hostdata->regp; @@ -734,6 +730,8 @@ if (!(asr & ASR_INT) || (asr & ASR_BSY)) return; + save_flags(flags); + #ifdef PROC_STATISTICS hostdata->int_cnt++; #endif @@ -776,7 +774,6 @@ case CSR_TIMEOUT: DB(DB_INTR,printk("TIMEOUT")) - disable_irq(instance->irq); if (hostdata->state == S_RUNNING_LEVEL2) hostdata->connected = NULL; else { @@ -789,11 +786,22 @@ hostdata->state = S_UNCONNECTED; cmd->scsi_done(cmd); + /* From esp.c: + * There is a window of time within the scsi_done() path + * of execution where interrupts are turned back on full + * blast and left that way. During that time we could + * reconnect to a disconnected command, then we'd bomb + * out below. We could also end up executing two commands + * at _once_. ...just so you know why the restore_flags() + * is here... + */ + + restore_flags(flags); + /* We are not connected to a target - check to see if there * are commands waiting to be executed. */ - enable_irq(instance->irq); wd33c93_execute(instance); break; @@ -801,7 +809,6 @@ /* Note: this interrupt should not occur in a LEVEL2 command */ case CSR_SELECT: - disable_irq(instance->irq); DB(DB_INTR,printk("SELECT")) hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting; @@ -820,13 +827,23 @@ hostdata->sync_stat[cmd->target] = SS_WAITING; - /* tack on a 2nd message to ask about synchronous transfers */ +/* Tack on a 2nd message to ask about synchronous transfers. If we've + * been asked to do only asynchronous transfers on this device, we + * request a fifo depth of 0, which is equivalent to async - should + * solve the problems some people have had with GVP's Guru ROM. + */ hostdata->outgoing_msg[1] = EXTENDED_MESSAGE; hostdata->outgoing_msg[2] = 3; hostdata->outgoing_msg[3] = EXTENDED_SDTR; + if (hostdata->no_sync & (1 << cmd->target)) { + hostdata->outgoing_msg[4] = hostdata->default_sx_per/4; + hostdata->outgoing_msg[5] = 0; + } + else { hostdata->outgoing_msg[4] = OPTIMUM_SX_PER/4; hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF; + } hostdata->outgoing_len = 6; } else @@ -891,7 +908,6 @@ case CSR_SRV_REQ |PHS_MESS_IN: DB(DB_INTR,printk("MSG_IN=")) - disable_irq(instance->irq); msg = read_1_byte(regp); sr = read_wd33c93(regp, WD_SCSI_STATUS); /* clear interrupt */ @@ -1034,13 +1050,13 @@ write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK); hostdata->state = S_CONNECTED; } + restore_flags(flags); break; /* Note: this interrupt will occur only after a LEVEL2 command */ case CSR_SEL_XFER_DONE: - disable_irq(instance->irq); /* Make sure that reselection is enabled at this point - it may * have been turned off for the command that just completed. @@ -1065,7 +1081,7 @@ /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. */ - enable_irq(instance->irq); + restore_flags(flags); wd33c93_execute(instance); } else { @@ -1124,8 +1140,6 @@ * so we treat it as a normal command-complete-disconnect. */ - disable_irq(instance->irq); - /* Make sure that reselection is enabled at this point - it may * have been turned off for the command that just completed. */ @@ -1149,13 +1163,13 @@ /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. */ - enable_irq(instance->irq); + /* look above for comments on scsi_done() */ + restore_flags(flags); wd33c93_execute(instance); break; case CSR_DISC: - disable_irq(instance->irq); /* Make sure that reselection is enabled at this point - it may * have been turned off for the command that just completed. @@ -1177,6 +1191,7 @@ else if (cmd->SCp.Status != GOOD) cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); cmd->scsi_done(cmd); + restore_flags(flags); break; case S_PRE_TMP_DISC: case S_RUNNING_LEVEL2: @@ -1198,7 +1213,6 @@ /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. */ - enable_irq(instance->irq); wd33c93_execute(instance); break; @@ -1206,8 +1220,6 @@ case CSR_RESEL_AM: DB(DB_INTR,printk("RESEL")) - disable_irq(instance->irq); - /* First we have to make sure this reselection didn't */ /* happen during Arbitration/Selection of some other device. */ /* If yes, put losing command back on top of input_Q. */ @@ -1306,15 +1318,13 @@ printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs); } - enable_irq(instance->irq); - DB(DB_INTR,printk("} ")) } -void reset_wd33c93(struct Scsi_Host *instance) +static void reset_wd33c93(struct Scsi_Host *instance) { struct WD33C93_hostdata *hostdata; wd33c93_regs *regp; @@ -1595,7 +1605,7 @@ /* check_setup_strings() returns index if key found, 0 if not */ -int check_setup_strings(char *key, int *flags, int *val, char *buf) +static int check_setup_strings(char *key, int *flags, int *val, char *buf) { int x; char *cp; @@ -1724,16 +1734,17 @@ reset_wd33c93(instance); sti(); - printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d\n",instance->host_no, + printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",instance->host_no, (hostdata->chip==C_WD33C93)?"WD33c93": (hostdata->chip==C_WD33C93A)?"WD33c93A": (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown", hostdata->microcode,hostdata->no_sync,hostdata->no_dma); #ifdef DEBUGGING_ON - printk(" debug_flags=0x%02x setup_strings=",hostdata->args); + printk(" debug_flags=0x%02x\n",hostdata->args); #else - printk(" debugging=OFF setup_strings="); + printk(" debugging=OFF\n"); #endif + printk(" setup_strings="); for (i=0; iargs & (f)) a; +#else +#define DB(f,a) +#endif + #define uchar unsigned char @@ -231,13 +247,17 @@ uchar sync_stat[8]; /* status of sync negotiation per target */ uchar no_sync; /* bitmask: don't do sync on these targets */ uchar no_dma; /* set this flag to disable DMA */ +#ifdef PROC_INTERFACE uchar proc; /* bitmask: what's in proc output */ +#ifdef PROC_STATISTICS unsigned long cmd_cnt[8]; /* # of commands issued per target */ unsigned long int_cnt; /* # of interrupts serviced */ unsigned long pio_cnt; /* # of pio data transfers */ unsigned long dma_cnt; /* # of DMA data transfers */ unsigned long disc_allowed_cnt[8]; /* # of disconnects allowed per target */ unsigned long disc_done_cnt[8]; /* # of disconnects done per target*/ +#endif +#endif }; diff -u --recursive --new-file v2.1.35/linux/fs/affs/inode.c linux/fs/affs/inode.c --- v2.1.35/linux/fs/affs/inode.c Fri Dec 27 02:03:24 1996 +++ linux/fs/affs/inode.c Thu Apr 17 13:20:47 1997 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -987,8 +988,7 @@ NULL }; -int -init_affs_fs(void) +__initfunc(int init_affs_fs(void)) { return register_filesystem(&affs_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/autofs/init.c linux/fs/autofs/init.c --- v2.1.35/linux/fs/autofs/init.c Fri Apr 4 08:52:24 1997 +++ linux/fs/autofs/init.c Tue Apr 15 22:30:38 1997 @@ -10,7 +10,6 @@ * * ------------------------------------------------------------------------- */ -#include #include #include diff -u --recursive --new-file v2.1.35/linux/fs/binfmt_aout.c linux/fs/binfmt_aout.c --- v2.1.35/linux/fs/binfmt_aout.c Sun Jan 26 02:07:24 1997 +++ linux/fs/binfmt_aout.c Thu Apr 17 13:20:47 1997 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -89,7 +90,7 @@ # define START_DATA(u) (u.start_data) #elif defined(__sparc__) # define START_DATA(u) (u.u_tsize) -#elif defined(__i386__) +#elif defined(__i386__) || defined(__mc68000__) # define START_DATA(u) (u.u_tsize << PAGE_SHIFT) #endif #ifdef __sparc__ @@ -555,7 +556,8 @@ } -int init_aout_binfmt(void) { +__initfunc(int init_aout_binfmt(void)) +{ return register_binfmt(&aout_format); } diff -u --recursive --new-file v2.1.35/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- v2.1.35/linux/fs/binfmt_elf.c Sun Jan 26 02:07:30 1997 +++ linux/fs/binfmt_elf.c Thu Apr 17 13:20:47 1997 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1124,7 +1125,7 @@ #else if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { - printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n", + printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); } else @@ -1276,7 +1277,7 @@ } #endif /* USE_ELF_CORE_DUMP */ -int init_elf_binfmt(void) +__initfunc(int init_elf_binfmt(void)) { return register_binfmt(&elf_format); } diff -u --recursive --new-file v2.1.35/linux/fs/binfmt_em86.c linux/fs/binfmt_em86.c --- v2.1.35/linux/fs/binfmt_em86.c Mon Apr 14 16:28:17 1997 +++ linux/fs/binfmt_em86.c Tue Apr 22 22:42:51 1997 @@ -14,6 +14,8 @@ #include #include #include +#include + #define EM86_INTERP "/usr/bin/em86" #define EM86_I_NAME "em86" @@ -100,11 +102,12 @@ #ifndef MODULE NULL, 0, load_em86, NULL, NULL #else - NULL, &mod_use_count_, load_em86, NULL, NULL + NULL, &__this_module, load_em86, NULL, NULL #endif }; -int init_em86_binfmt(void) { +__initfunc(int init_em86_binfmt(void)) +{ return register_binfmt(&em86_format); } diff -u --recursive --new-file v2.1.35/linux/fs/binfmt_java.c linux/fs/binfmt_java.c --- v2.1.35/linux/fs/binfmt_java.c Sun Jan 26 02:07:30 1997 +++ linux/fs/binfmt_java.c Thu Apr 17 13:20:47 1997 @@ -13,6 +13,7 @@ #include #include #include +#include #define _PATH_JAVA "/usr/bin/java" #define _PATH_APPLET "/usr/bin/appletviewer" @@ -165,7 +166,8 @@ #endif }; -int init_java_binfmt(void) { +__initfunc(int init_java_binfmt(void)) +{ register_binfmt(&java_format); return register_binfmt(&applet_format); } diff -u --recursive --new-file v2.1.35/linux/fs/binfmt_script.c linux/fs/binfmt_script.c --- v2.1.35/linux/fs/binfmt_script.c Tue Jan 28 00:02:45 1997 +++ linux/fs/binfmt_script.c Thu Apr 17 13:20:47 1997 @@ -10,6 +10,7 @@ #include #include #include +#include static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs) { @@ -103,7 +104,8 @@ #endif }; -int init_script_binfmt(void) { +__initfunc(int init_script_binfmt(void)) +{ return register_binfmt(&script_format); } diff -u --recursive --new-file v2.1.35/linux/fs/buffer.c linux/fs/buffer.c --- v2.1.35/linux/fs/buffer.c Mon Apr 14 16:28:17 1997 +++ linux/fs/buffer.c Tue Apr 22 23:02:26 1997 @@ -14,7 +14,12 @@ /* Start bdflush() with kernel_thread not syscall - Paul Gortmaker, 12/95 */ /* Removed a lot of unnecessary code and simplified things now that - the buffer cache isn't our primary cache - Andrew Tridgell 12/96 */ + * the buffer cache isn't our primary cache - Andrew Tridgell 12/96 + */ + +/* Speed up hash, lru, and free list operations. Use gfp() for allocating + * hash table, use SLAB cache for buffer heads. -DaveM + */ #include #include @@ -23,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +51,7 @@ #define MAX_UNUSED_BUFFERS 30 /* don't ever have more than this number of unused buffer heads */ #define HASH_PAGES 4 /* number of pages to use for the hash table */ +#define HASH_PAGES_ORDER 2 #define NR_HASH (HASH_PAGES*PAGE_SIZE/sizeof(struct buffer_head *)) #define HASH_MASK (NR_HASH-1) @@ -54,6 +61,8 @@ static struct buffer_head * lru_list[NR_LIST] = {NULL, }; static struct buffer_head * free_list[NR_SIZES] = {NULL, }; +static kmem_cache_t *bh_cachep; + static struct buffer_head * unused_list = NULL; static struct buffer_head * reuse_list = NULL; static struct wait_queue * buffer_wait = NULL; @@ -65,7 +74,7 @@ static int refilled = 0; /* Set NZ when a buffer freelist is refilled this is used by the loop device */ -/* this is used by some architectures to estimate available memory */ +/* This is used by some architectures to estimate available memory. */ int buffermem = 0; /* Here is the parameter block for the bdflush process. If you add or @@ -76,8 +85,9 @@ #define N_PARAM 9 -/* the dummy values in this structure are left in there for compatibility - with old programs that play with the /proc entries */ +/* The dummy values in this structure are left in there for compatibility + * with old programs that play with the /proc entries. + */ union bdflush_param{ struct { int nfract; /* Percentage of buffer cache dirty to @@ -131,29 +141,31 @@ } /* Call sync_buffers with wait!=0 to ensure that the call does not - return until all buffer writes have completed. Sync() may return - before the writes have finished; fsync() may not. */ - + * return until all buffer writes have completed. Sync() may return + * before the writes have finished; fsync() may not. + */ /* Godamity-damn. Some buffers (bitmaps for filesystems) - spontaneously dirty themselves without ever brelse being called. - We will ultimately want to put these in a separate list, but for - now we search all of the lists for dirty buffers */ - + * spontaneously dirty themselves without ever brelse being called. + * We will ultimately want to put these in a separate list, but for + * now we search all of the lists for dirty buffers. + */ static int sync_buffers(kdev_t dev, int wait) { int i, retry, pass = 0, err = 0; struct buffer_head * bh, *next; /* One pass for no-wait, three for wait: - 0) write out all dirty, unlocked buffers; - 1) write out all dirty buffers, waiting if locked; - 2) wait for completion by waiting for all buffers to unlock. */ + * 0) write out all dirty, unlocked buffers; + * 1) write out all dirty buffers, waiting if locked; + * 2) wait for completion by waiting for all buffers to unlock. + */ do { retry = 0; repeat: - /* We search all lists as a failsafe mechanism, not because we expect - there to be dirty buffers on any of the other lists. */ + /* We search all lists as a failsafe mechanism, not because we expect + * there to be dirty buffers on any of the other lists. + */ bh = lru_list[BUF_DIRTY]; if (!bh) goto repeat2; @@ -167,7 +179,8 @@ continue; if (buffer_locked(bh)) { /* Buffer is locked; skip it unless wait is - requested AND pass > 0. */ + * requested AND pass > 0. + */ if (!wait || !pass) { retry = 1; continue; @@ -175,18 +188,27 @@ wait_on_buffer (bh); goto repeat; } + /* If an unlocked buffer is not uptodate, there has - been an IO error. Skip it. */ + * been an IO error. Skip it. + */ if (wait && buffer_req(bh) && !buffer_locked(bh) && !buffer_dirty(bh) && !buffer_uptodate(bh)) { err = 1; continue; } + /* Don't write clean buffers. Don't write ANY buffers - on the third pass. */ + * on the third pass. + */ if (!buffer_dirty(bh) || pass >= 2) continue; - /* don't bother about locked buffers */ + + /* Don't bother about locked buffers. + * + * XXX We checked if it was locked above and there is no + * XXX way we could have slept in between. -DaveM + */ if (buffer_locked(bh)) continue; bh->b_count++; @@ -212,7 +234,8 @@ continue; if (buffer_locked(bh)) { /* Buffer is locked; skip it unless wait is - requested AND pass > 0. */ + * requested AND pass > 0. + */ if (!wait || !pass) { retry = 1; continue; @@ -222,10 +245,11 @@ } } - /* If we are waiting for the sync to succeed, and if any dirty - blocks were written, then repeat; on the second pass, only - wait for buffers being written (do not pass to write any - more buffers on the second pass). */ + /* If we are waiting for the sync to succeed, and if any dirty + * blocks were written, then repeat; on the second pass, only + * wait for buffers being written (do not pass to write any + * more buffers on the second pass). + */ } while (wait && retry && ++pass<=2); return err; } @@ -330,13 +354,12 @@ static inline void remove_from_hash_queue(struct buffer_head * bh) { - if (bh->b_next) - bh->b_next->b_prev = bh->b_prev; - if (bh->b_prev) - bh->b_prev->b_next = bh->b_next; - if (hash(bh->b_dev,bh->b_blocknr) == bh) - hash(bh->b_dev,bh->b_blocknr) = bh->b_next; - bh->b_next = bh->b_prev = NULL; + if (bh->b_pprev) { + if(bh->b_next) + bh->b_next->b_pprev = bh->b_pprev; + *bh->b_pprev = bh->b_next; + bh->b_pprev = NULL; + } } static inline void remove_from_lru_list(struct buffer_head * bh) @@ -389,46 +412,49 @@ static inline void put_last_lru(struct buffer_head * bh) { - if (!bh) - return; - if (bh == lru_list[bh->b_list]) { - lru_list[bh->b_list] = bh->b_next_free; - return; - } - if(bh->b_dev == B_FREE) - panic("Wrong block for lru list"); - remove_from_lru_list(bh); -/* add to back of free list */ + if (bh) { + struct buffer_head **bhp = &lru_list[bh->b_list]; - if(!lru_list[bh->b_list]) { - lru_list[bh->b_list] = bh; - lru_list[bh->b_list]->b_prev_free = bh; - } + if (bh == *bhp) { + *bhp = bh->b_next_free; + return; + } + + if(bh->b_dev == B_FREE) + panic("Wrong block for lru list"); + + /* Add to back of free list. */ + remove_from_lru_list(bh); + if(!*bhp) { + *bhp = bh; + (*bhp)->b_prev_free = bh; + } - bh->b_next_free = lru_list[bh->b_list]; - bh->b_prev_free = lru_list[bh->b_list]->b_prev_free; - lru_list[bh->b_list]->b_prev_free->b_next_free = bh; - lru_list[bh->b_list]->b_prev_free = bh; + bh->b_next_free = *bhp; + bh->b_prev_free = (*bhp)->b_prev_free; + (*bhp)->b_prev_free->b_next_free = bh; + (*bhp)->b_prev_free = bh; + } } static inline void put_last_free(struct buffer_head * bh) { - int isize; - if (!bh) - return; + if (bh) { + struct buffer_head **bhp = &free_list[BUFSIZE_INDEX(bh->b_size)]; - isize = BUFSIZE_INDEX(bh->b_size); - bh->b_dev = B_FREE; /* So it is obvious we are on the free list */ - /* add to back of free list */ - if(!free_list[isize]) { - free_list[isize] = bh; - bh->b_prev_free = bh; - } + bh->b_dev = B_FREE; /* So it is obvious we are on the free list. */ - bh->b_next_free = free_list[isize]; - bh->b_prev_free = free_list[isize]->b_prev_free; - free_list[isize]->b_prev_free->b_next_free = bh; - free_list[isize]->b_prev_free = bh; + /* Add to back of free list. */ + if(!*bhp) { + *bhp = bh; + bh->b_prev_free = bh; + } + + bh->b_next_free = *bhp; + bh->b_prev_free = (*bhp)->b_prev_free; + (*bhp)->b_prev_free->b_next_free = bh; + (*bhp)->b_prev_free = bh; + } } static inline void insert_into_queues(struct buffer_head * bh) @@ -436,28 +462,34 @@ /* put at end of free list */ if(bh->b_dev == B_FREE) { put_last_free(bh); - return; - } - if(!lru_list[bh->b_list]) { - lru_list[bh->b_list] = bh; - bh->b_prev_free = bh; - } + } else { + struct buffer_head **bhp = &lru_list[bh->b_list]; - if (bh->b_next_free) panic("VFS: buffer LRU pointers corrupted"); - bh->b_next_free = lru_list[bh->b_list]; - bh->b_prev_free = lru_list[bh->b_list]->b_prev_free; - lru_list[bh->b_list]->b_prev_free->b_next_free = bh; - lru_list[bh->b_list]->b_prev_free = bh; - nr_buffers_type[bh->b_list]++; -/* put the buffer in new hash-queue if it has a device */ - bh->b_prev = NULL; - bh->b_next = NULL; - if (!(bh->b_dev)) - return; - bh->b_next = hash(bh->b_dev,bh->b_blocknr); - hash(bh->b_dev,bh->b_blocknr) = bh; - if (bh->b_next) - bh->b_next->b_prev = bh; + if(!*bhp) { + *bhp = bh; + bh->b_prev_free = bh; + } + + if (bh->b_next_free) + panic("VFS: buffer LRU pointers corrupted"); + + bh->b_next_free = *bhp; + bh->b_prev_free = (*bhp)->b_prev_free; + (*bhp)->b_prev_free->b_next_free = bh; + (*bhp)->b_prev_free = bh; + + nr_buffers_type[bh->b_list]++; + + /* Put the buffer in new hash-queue if it has a device. */ + if (bh->b_dev) { + struct buffer_head **bhp = &hash(bh->b_dev, bh->b_blocknr); + if((bh->b_next = *bhp) != NULL) + (*bhp)->b_pprev = &bh->b_next; + *bhp = bh; + bh->b_pprev = bhp; /* Exists in bh hashes. */ + } else + bh->b_pprev = NULL; /* Not in bh hashes. */ + } } static inline struct buffer_head * find_buffer(kdev_t dev, int block, int size) @@ -465,14 +497,14 @@ struct buffer_head * tmp; for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next) - if (tmp->b_blocknr == block && tmp->b_dev == dev) + if (tmp->b_blocknr == block && tmp->b_dev == dev) { if (tmp->b_size == size) return tmp; - else { - printk("VFS: Wrong blocksize on device %s\n", - kdevname(dev)); - return NULL; - } + + printk("VFS: Wrong blocksize on device %s\n", + kdevname(dev)); + return NULL; + } return NULL; } @@ -492,8 +524,9 @@ return NULL; bh->b_count++; wait_on_buffer(bh); - if (bh->b_dev == dev && bh->b_blocknr == block - && bh->b_size == size) + if (bh->b_dev == dev && + bh->b_blocknr == block && + bh->b_size == size) return bh; bh->b_count--; } @@ -501,27 +534,21 @@ unsigned int get_hardblocksize(kdev_t dev) { - int blksize = 0; - - /* - * Get the hard sector size for the given device. If we don't know - * what it is, return 0. - */ - - if (hardsect_size[MAJOR(dev)] != NULL) - { - blksize = hardsect_size[MAJOR(dev)][MINOR(dev)]; - if (blksize != 0) - { - return blksize; + /* + * Get the hard sector size for the given device. If we don't know + * what it is, return 0. + */ + if (hardsect_size[MAJOR(dev)] != NULL) { + int blksize = hardsect_size[MAJOR(dev)][MINOR(dev)]; + if (blksize != 0) + return blksize; } - } - /* - * We don't know what the hardware sector size for this device is. - * Return 0 indicating that we don't know. - */ - return 0; + /* + * We don't know what the hardware sector size for this device is. + * Return 0 indicating that we don't know. + */ + return 0; } void set_blocksize(kdev_t dev, int size) @@ -550,13 +577,15 @@ sync_buffers(dev, 2); blksize_size[MAJOR(dev)][MINOR(dev)] = size; - /* We need to be quite careful how we do this - we are moving entries - around on the free list, and we can get in a loop if we are not careful.*/ - + /* We need to be quite careful how we do this - we are moving entries + * around on the free list, and we can get in a loop if we are not careful. + */ for(nlist = 0; nlist < NR_LIST; nlist++) { bh = lru_list[nlist]; for (i = nr_buffers_type[nlist]*2 ; --i > 0 ; bh = bhnext) { - if(!bh) break; + if(!bh) + break; + bhnext = bh->b_next_free; if (bh->b_dev != dev) continue; @@ -575,12 +604,12 @@ } } - -/* check if a buffer is OK to be reclaimed */ +/* Check if a buffer is OK to be reclaimed. */ static inline int can_reclaim(struct buffer_head *bh, int size) { - if (bh->b_count || - buffer_protected(bh) || buffer_locked(bh)) + if (bh->b_count || + buffer_protected(bh) || + buffer_locked(bh)) return 0; if (atomic_read(&mem_map[MAP_NR((unsigned long) bh->b_data)].count) != 1 || @@ -595,8 +624,9 @@ return 1; } -/* find a candidate buffer to be reclaimed */ -static struct buffer_head *find_candidate(struct buffer_head *list,int *list_len,int size) +/* Find a candidate buffer to be reclaimed. */ +static struct buffer_head *find_candidate(struct buffer_head *list, + int *list_len, int size) { struct buffer_head *bh; @@ -604,19 +634,23 @@ bh && (*list_len) > 0; bh = bh->b_next_free, (*list_len)--) { if (size != bh->b_size) { - /* this provides a mechanism for freeing blocks - of other sizes, this is necessary now that we - no longer have the lav code. */ + /* This provides a mechanism for freeing blocks + * of other sizes, this is necessary now that we + * no longer have the lav code. + */ try_to_free_buffer(bh,&bh,1); + if (!bh) + break; continue; } if (buffer_locked(bh) && (bh->b_list == BUF_LOCKED || bh->b_list == BUF_LOCKED1)) { /* Buffers are written in the order they are placed - on the locked list. If we encounter a locked - buffer here, this means that the rest of them - are also locked */ + * on the locked list. If we encounter a locked + * buffer here, this means that the rest of them + * are also locked. + */ (*list_len) = 0; return NULL; } @@ -639,74 +673,81 @@ refilled = 1; /* If there are too many dirty buffers, we wake up the update process - now so as to ensure that there are still clean buffers available - for user processes to use (and dirty) */ + * now so as to ensure that there are still clean buffers available + * for user processes to use (and dirty). + */ - /* We are going to try to locate this much memory */ - needed =bdf_prm.b_un.nrefill * size; + /* We are going to try to locate this much memory. */ + needed = bdf_prm.b_un.nrefill * size; - while (nr_free_pages > min_free_pages*2 && needed > 0 && - grow_buffers(GFP_BUFFER, size)) { + while ((nr_free_pages > min_free_pages*2) && + (needed > 0) && + grow_buffers(GFP_BUFFER, size)) needed -= PAGE_SIZE; - } repeat: /* OK, we cannot grow the buffer cache, now try to get some - from the lru list */ - - /* First set the candidate pointers to usable buffers. This - should be quick nearly all of the time. */ + * from the lru list. + * + * First set the candidate pointers to usable buffers. This + * should be quick nearly all of the time. + */ - if(needed <= 0) return; + if(needed <= 0) + return; - for(i=0; ib_lru_time < best_time){ + for(i=0; ib_lru_time < best_time) { best_time = candidate[i]->b_lru_time; winner = i; } } - /* If we have a winner, use it, and then get a new candidate from that list */ + /* If we have a winner, use it, and then get a new candidate from that list. */ if(winner != UINT_MAX) { i = winner; while (needed>0 && (bh=candidate[i])) { candidate[i] = bh->b_next_free; - if(candidate[i] == bh) candidate[i] = NULL; /* Got last one */ + if(candidate[i] == bh) + candidate[i] = NULL; /* Got last one */ remove_from_queues(bh); bh->b_dev = B_FREE; put_last_free(bh); needed -= bh->b_size; buffers[i]--; - if(buffers[i] == 0) candidate[i] = NULL; + if(buffers[i] == 0) + candidate[i] = NULL; if (candidate[i] && !can_reclaim(candidate[i],size)) - candidate[i] = find_candidate(candidate[i],&buffers[i], size); + candidate[i] = find_candidate(candidate[i], + &buffers[i], size); } if (needed >= 0) goto repeat; } - if(needed <= 0) return; + if(needed <= 0) + return; /* Too bad, that was not enough. Try a little harder to grow some. */ - if (nr_free_pages > min_free_pages + 5) { if (grow_buffers(GFP_BUFFER, size)) { needed -= PAGE_SIZE; goto repeat; - }; + } } - /* and repeat until we find something good */ + /* And repeat until we find something good. */ if (!grow_buffers(GFP_ATOMIC, size)) wakeup_bdflush(1); needed -= PAGE_SIZE; @@ -729,8 +770,9 @@ int isize = BUFSIZE_INDEX(size); /* If there are too many dirty buffers, we wake up the update process - now so as to ensure that there are still clean buffers available - for user processes to use (and dirty) */ + * now so as to ensure that there are still clean buffers available + * for user processes to use (and dirty). + */ repeat: bh = get_hash_table(dev, block, size); if (bh) { @@ -743,9 +785,8 @@ return bh; } - while(!free_list[isize]) { + while(!free_list[isize]) refill_freelist(size); - } if (find_buffer(dev,block,size)) goto repeat; @@ -753,8 +794,9 @@ bh = free_list[isize]; remove_from_free_list(bh); -/* OK, FINALLY we know that this buffer is the only one of its kind, */ -/* and that it's unused (b_count=0), unlocked (buffer_locked=0), and clean */ + /* OK, FINALLY we know that this buffer is the only one of its kind, + * and that it's unused (b_count=0), unlocked (buffer_locked=0), and clean. + */ bh->b_count=1; bh->b_flushtime=0; bh->b_state=(1<b_flushtime || buf->b_flushtime > newtime) @@ -798,8 +840,9 @@ dispose = BUF_LOCKED; else dispose = BUF_CLEAN; - if(dispose == BUF_CLEAN) buf->b_lru_time = jiffies; - if(dispose != buf->b_list) { + if(dispose == BUF_CLEAN) + buf->b_lru_time = jiffies; + if(dispose != buf->b_list) { if(dispose == BUF_DIRTY) buf->b_lru_time = jiffies; if(dispose == BUF_LOCKED && @@ -809,16 +852,21 @@ buf->b_list = dispose; insert_into_queues(buf); if (dispose == BUF_DIRTY) { - /* This buffer is dirty, maybe we need to start flushing. */ - /* If too high a percentage of the buffers are dirty... */ - if (nr_buffers_type[BUF_DIRTY] > nr_buffers * bdf_prm.b_un.nfract/100) - wakeup_bdflush(0); - /* If this is a loop device, and - * more than half of the buffers are dirty... */ - /* (Prevents no-free-buffers deadlock with loop device.) */ - if (MAJOR(buf->b_dev) == LOOP_MAJOR && - nr_buffers_type[BUF_DIRTY]*2>nr_buffers) - wakeup_bdflush(1); + int too_many = (nr_buffers * bdf_prm.b_un.nfract/100); + + /* This buffer is dirty, maybe we need to start flushing. + * If too high a percentage of the buffers are dirty... + */ + if (nr_buffers_type[BUF_DIRTY] > too_many) + wakeup_bdflush(0); + + /* If this is a loop device, and + * more than half of the buffers are dirty... + * (Prevents no-free-buffers deadlock with loop device.) + */ + if (MAJOR(buf->b_dev) == LOOP_MAJOR && + nr_buffers_type[BUF_DIRTY]*2>nr_buffers) + wakeup_bdflush(1); } } } @@ -830,7 +878,7 @@ { wait_on_buffer(buf); - /* If dirty, mark the time this buffer should be written back */ + /* If dirty, mark the time this buffer should be written back. */ set_writetime(buf, 0); refile_buffer(buf); @@ -929,13 +977,13 @@ else bhlist[j++] = bh; } - /* Request the read for these buffers, and then release them */ + /* Request the read for these buffers, and then release them. */ if (j>1) ll_rw_block(READA, (j-1), bhlist+1); for(i=1; i= MAX_UNUSED_BUFFERS) { nr_buffer_heads--; - kfree(bh); + kmem_cache_free(bh_cachep, bh); return; } memset(bh,0,sizeof(*bh)); @@ -963,23 +1011,17 @@ struct buffer_head * bh; while (!unused_list) { - /* - * This is critical. We can't swap out pages to get + /* This is critical. We can't swap out pages to get * more buffer heads, because the swap-out may need - * more buffer-heads itself. Thus GFP_ATOMIC. + * more buffer-heads itself. Thus SLAB_ATOMIC. */ - /* we now use kmalloc() here instead of gfp as we want - to be able to easily release buffer heads - they - took up quite a bit of memory (tridge) */ - bh = (struct buffer_head *) kmalloc(sizeof(*bh),GFP_ATOMIC); - if (bh) { + if((bh = kmem_cache_alloc(bh_cachep, SLAB_ATOMIC)) != NULL) { put_unused_buffer_head(bh); nr_buffer_heads++; return; } - /* - * Uhhuh. We're _really_ low on memory. Now we just + /* Uhhuh. We're _really_ low on memory. Now we just * wait for old buffer heads to become free due to * finishing IO.. */ @@ -1414,12 +1456,11 @@ p = tmp; tmp = tmp->b_this_page; nr_buffers--; - if (p == *bhp) - { - *bhp = p->b_prev_free; - if (p == *bhp) /* Was this the last in the list? */ - *bhp = NULL; - } + if (p == *bhp) { + *bhp = p->b_prev_free; + if (p == *bhp) /* Was this the last in the list? */ + *bhp = NULL; + } remove_from_queues(p); put_unused_buffer_head(p); } while (tmp != bh); @@ -1472,14 +1513,24 @@ /* * allocate the hash table and init the free list + * Use gfp() for the hash table to decrease TLB misses, use + * SLAB cache for buffer heads. */ void buffer_init(void) { - hash_table = (struct buffer_head **)vmalloc(NR_HASH*sizeof(struct buffer_head *)); + hash_table = (struct buffer_head **) + __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER, 0); if (!hash_table) panic("Failed to allocate buffer hash table\n"); memset(hash_table,0,NR_HASH*sizeof(struct buffer_head *)); + bh_cachep = kmem_cache_create("buffer_head", + sizeof(struct buffer_head), + sizeof(unsigned long) * 4, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if(!bh_cachep) + panic("Cannot create buffer head SLAB cache\n"); + lru_list[BUF_CLEAN] = 0; grow_buffers(GFP_KERNEL, BLOCK_SIZE); } @@ -1745,21 +1796,3 @@ } } } - - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 8 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -8 - * c-argdecl-indent: 8 - * c-label-offset: -8 - * c-continued-statement-offset: 8 - * c-continued-brace-offset: 0 - * End: - */ diff -u --recursive --new-file v2.1.35/linux/fs/dcache.c linux/fs/dcache.c --- v2.1.35/linux/fs/dcache.c Thu Feb 27 10:57:31 1997 +++ linux/fs/dcache.c Wed Apr 23 10:54:35 1997 @@ -4,6 +4,8 @@ * (C) Copyright 1994 Linus Torvalds */ +/* Speeded up searches a bit and threaded the mess. -DaveM */ + /* * The directory cache is a "two-level" cache, each level doing LRU on * its entries. Adding new entries puts them at the end of the LRU @@ -22,6 +24,9 @@ #include #include +#include + +spinlock_t dcache_lock = SPIN_LOCK_UNLOCKED; /* * Don't bother caching long names.. They just take up space in the cache, and @@ -30,18 +35,14 @@ */ #define DCACHE_NAME_LEN 15 #define DCACHE_SIZE 1024 -#define DCACHE_HASH_QUEUES 256 - -struct hash_list { - struct dir_cache_entry * next; - struct dir_cache_entry * prev; -}; +#define DCACHE_HASH_QUEUES 256 /* keep this a pow2 */ /* * The dir_cache_entry must be in this order: we do ugly things with the pointers */ struct dir_cache_entry { - struct hash_list h; + struct dir_cache_entry *next; + struct dir_cache_entry **pprev; kdev_t dc_dev; unsigned long dir; unsigned long version; @@ -68,13 +69,34 @@ static struct dir_cache_entry * level1_head; static struct dir_cache_entry * level2_head; +/* The hash queues are layed out in a slightly different manner. */ +static struct dir_cache_entry *hash_table[DCACHE_HASH_QUEUES]; + +#define hash_fn(dev,dir,namehash) \ + ((HASHDEV(dev) ^ (dir) ^ (namehash)) & (DCACHE_HASH_QUEUES - 1)) + /* - * The hash-queues are also doubly-linked circular lists, but the head is - * itself on the doubly-linked list, not just a pointer to the first entry. + * Stupid name"hash" algorithm. Write something better if you want to, + * but I doubt it matters that much. */ -#define hash_fn(dev,dir,namehash) ((HASHDEV(dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES) +static unsigned long namehash(const char * name, int len) +{ + unsigned long hash = 0; -static struct hash_list hash_table[DCACHE_HASH_QUEUES]; + while ((len -= sizeof(unsigned long)) > 0) { + hash += get_unaligned((unsigned long *)name); + name += sizeof(unsigned long); + } + return hash + + (get_unaligned((unsigned long *)name) & + ~(~0UL << ((len + sizeof(unsigned long)) << 3))); +} + +static inline struct dir_cache_entry **get_hlist(struct inode *dir, + const char *name, int len) +{ + return hash_table + hash_fn(dir->i_dev, dir->i_ino, namehash(name, len)); +} static inline void remove_lru(struct dir_cache_entry * de) { @@ -106,78 +128,50 @@ } /* - * Stupid name"hash" algorithm. Write something better if you want to, - * but I doubt it matters that much - */ -static inline unsigned long namehash(const char * name, int len) -{ - if (len >= sizeof(unsigned long)) - return len + - get_unaligned((unsigned long *) name) + - get_unaligned((unsigned long *) (name + len - sizeof(unsigned long))); - return len + - ((const unsigned char *) name)[0]+ - ((const unsigned char *) name)[len-1]; -} - -/* * Hash queue manipulation. Look out for the casts.. + * + * What casts? 8-) -DaveM */ static inline void remove_hash(struct dir_cache_entry * de) { - struct dir_cache_entry * next = de->h.next; - - if (next) { - struct dir_cache_entry * prev = de->h.prev; - next->h.prev = prev; - prev->h.next = next; - de->h.next = NULL; + if(de->pprev) { + if(de->next) + de->next->pprev = de->pprev; + *de->pprev = de->next; + de->pprev = NULL; } } -static inline void add_hash(struct dir_cache_entry * de, struct hash_list * hash) +static inline void add_hash(struct dir_cache_entry * de, struct dir_cache_entry ** hash) { - struct dir_cache_entry * next = hash->next; - de->h.next = next; - de->h.prev = (struct dir_cache_entry *) hash; - next->h.prev = de; - hash->next = de; + if((de->next = *hash) != NULL) + (*hash)->pprev = &de->next; + *hash = de; + de->pprev = hash; } /* * Find a directory cache entry given all the necessary info. */ -static inline struct dir_cache_entry * find_entry(struct inode * dir, const char * name, int len, struct hash_list * hash) +static inline struct dir_cache_entry * find_entry(struct inode * dir, const char * name, int len, struct dir_cache_entry ** hash) { - struct dir_cache_entry * nextde = hash->next; - - for (;;) { - struct dir_cache_entry * de; + struct dir_cache_entry *de; - if (nextde == (struct dir_cache_entry *) hash) + for(de = *hash; de; de = de->next) + if((de->name_len == (unsigned char) len) && + (de->dc_dev == dir->i_dev) && + (de->dir == dir->i_ino) && + (de->version == dir->i_version) && + (!memcmp(de->name, name, len))) break; - de = nextde; - nextde = nextde->h.next; - if (de->name_len != (unsigned char) len) - continue; - if (de->dc_dev != dir->i_dev) - continue; - if (de->dir != dir->i_ino) - continue; - if (de->version != dir->i_version) - continue; - if (memcmp(de->name, name, len)) - continue; - return de; - } - return NULL; + return de; } /* * Move a successfully used entry to level2. If already at level2, * move it to the end of the LRU queue.. */ -static inline void move_to_level2(struct dir_cache_entry * old_de, struct hash_list * hash) +static inline void move_to_level2(struct dir_cache_entry * old_de, struct dir_cache_entry ** hash) { struct dir_cache_entry * de; @@ -194,43 +188,49 @@ int dcache_lookup(struct inode * dir, const char * name, int len, unsigned long * ino) { - struct hash_list * hash; - struct dir_cache_entry *de; + int ret = 0; - 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; + if(len <= DCACHE_NAME_LEN) { + struct dir_cache_entry **hash = get_hlist(dir, name, len); + struct dir_cache_entry *de; + + spin_lock(&dcache_lock); + de = find_entry(dir, name, len, hash); + if(de) { + *ino = de->ino; + move_to_level2(de, hash); + ret = 1; + } + spin_unlock(&dcache_lock); + } + return ret; } void dcache_add(struct inode * dir, const char * name, int len, unsigned long ino) { - struct hash_list * hash; - struct dir_cache_entry *de; - - if (len > DCACHE_NAME_LEN) - return; - hash = hash_table + hash_fn(dir->i_dev, dir->i_ino, namehash(name,len)); - if ((de = find_entry(dir, name, len, hash)) != NULL) { - de->ino = ino; - update_lru(de); - return; + if (len <= DCACHE_NAME_LEN) { + struct dir_cache_entry **hash = get_hlist(dir, name, len); + struct dir_cache_entry *de; + + spin_lock(&dcache_lock); + de = find_entry(dir, name, len, hash); + if (de) { + de->ino = ino; + update_lru(de); + } else { + de = level1_head; + level1_head = de->next_lru; + remove_hash(de); + de->dc_dev = dir->i_dev; + de->dir = dir->i_ino; + de->version = dir->i_version; + de->ino = ino; + de->name_len = len; + memcpy(de->name, name, len); + add_hash(de, hash); + } + spin_unlock(&dcache_lock); } - de = level1_head; - level1_head = de->next_lru; - remove_hash(de); - de->dc_dev = dir->i_dev; - de->dir = dir->i_ino; - de->version = dir->i_version; - de->ino = ino; - de->name_len = len; - memcpy(de->name, name, len); - add_hash(de, hash); } unsigned long name_cache_init(unsigned long mem_start, unsigned long mem_end) @@ -270,7 +270,7 @@ * Empty hash queues.. */ for (i = 0 ; i < DCACHE_HASH_QUEUES ; i++) - hash_table[i].next = hash_table[i].next = - (struct dir_cache_entry *) &hash_table[i]; + hash_table[i] = NULL; + return mem_start; } diff -u --recursive --new-file v2.1.35/linux/fs/exec.c linux/fs/exec.c --- v2.1.35/linux/fs/exec.c Mon Apr 14 16:28:17 1997 +++ linux/fs/exec.c Thu Apr 17 13:20:47 1997 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -65,7 +66,7 @@ static struct linux_binfmt *formats = (struct linux_binfmt *) NULL; -void binfmt_setup(void) +__initfunc(void binfmt_setup(void)) { #ifdef CONFIG_BINFMT_ELF init_elf_binfmt(); @@ -533,7 +534,7 @@ if (IS_NOSUID(bprm->inode) || (current->flags & PF_PTRACED) || (current->fs->count > 1) - || (current->sig->count > 1) + || (atomic_read(¤t->sig->count) > 1) || (current->files->count > 1)) { if (!suser()) return -EPERM; diff -u --recursive --new-file v2.1.35/linux/fs/ext2/super.c linux/fs/ext2/super.c --- v2.1.35/linux/fs/ext2/super.c Mon Apr 7 11:35:30 1997 +++ linux/fs/ext2/super.c Thu Apr 17 13:20:47 1997 @@ -33,6 +33,7 @@ #include #include #include +#include static char error_buf[1024]; @@ -727,7 +728,7 @@ ext2_read_super, "ext2", 1, NULL }; -int init_ext2_fs(void) +__initfunc(int init_ext2_fs(void)) { return register_filesystem(&ext2_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/filesystems.c linux/fs/filesystems.c --- v2.1.35/linux/fs/filesystems.c Mon Apr 7 11:35:30 1997 +++ linux/fs/filesystems.c Tue Apr 22 22:49:38 1997 @@ -27,6 +27,9 @@ #include #include #include +#ifdef CONFIG_KERNELD +#include +#endif extern void device_setup(void); extern void binfmt_setup(void); @@ -42,7 +45,7 @@ if (!callable) goto out; callable = 0; - + device_setup(); binfmt_setup(); @@ -129,3 +132,32 @@ return err; } +#ifndef CONFIG_NFSD +#ifdef CONFIG_NFSD_MODULE +int (*do_nfsservctl)(int, void *, void *) = NULL; +#endif +int +asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp) +{ +#ifndef CONFIG_NFSD_MODULE + return -ENOSYS; +#else + int ret = -ENOSYS; + + lock_kernel(); + if (do_nfsservctl) { + ret = do_nfsservctl(cmd, argp, resp); + goto out; + } +#ifdef CONFIG_KERNELD + if (request_module ("nfsd") == 0) { + if (do_nfsservctl) + ret = do_nfsservctl(cmd, argp, resp); + } +#endif /* CONFIG_KERNELD */ +out: + unlock_kernel(); + return ret; +#endif /* CONFIG_NFSD_MODULE */ +} +#endif /* CONFIG_NFSD */ diff -u --recursive --new-file v2.1.35/linux/fs/hpfs/hpfs_fs.c linux/fs/hpfs/hpfs_fs.c --- v2.1.35/linux/fs/hpfs/hpfs_fs.c Sun Jan 26 02:07:44 1997 +++ linux/fs/hpfs/hpfs_fs.c Thu Apr 17 13:20:47 1997 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1748,7 +1749,7 @@ hpfs_read_super, "hpfs", 1, NULL }; -int init_hpfs_fs(void) +__initfunc(int init_hpfs_fs(void)) { return register_filesystem(&hpfs_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/inode.c linux/fs/inode.c --- v2.1.35/linux/fs/inode.c Wed Apr 16 14:15:00 1997 +++ linux/fs/inode.c Tue Apr 22 23:02:26 1997 @@ -1,231 +1,234 @@ /* - * 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 -#include #include +#include #include +#include #include -#include - -#define NR_IHASH 512 - -/* - * Be VERY careful when you access the inode hash table. There - * are some rather scary race conditions you need to take care of: - * - P1 tries to open file "xx", calls "iget()" with the proper - * inode number, but blocks because it's not on the list. - * - P2 deletes file "xx", gets the inode (which P1 has just read, - * but P1 hasn't woken up to the fact yet) - * - P2 iput()'s the inode, which now has i_nlink = 0 - * - P1 wakes up and has the inode, but now P2 has made that - * inode invalid (but P1 has no way of knowing that). - * - * The "updating" counter makes sure that when P1 blocks on the - * iget(), P2 can't delete the inode from under it because P2 - * will wait until P1 has been able to update the inode usage - * count so that the inode will stay in use until everybody has - * closed it.. - */ -static struct inode_hash_entry { - struct inode * inode; - int updating; -} hash_table[NR_IHASH]; - -static struct inode * first_inode; -static struct wait_queue * inode_wait = NULL; -/* Keep these next two contiguous in memory for sysctl.c */ int nr_inodes = 0, nr_free_inodes = 0; int max_inodes = NR_INODE; -static inline int const hashfn(kdev_t dev, unsigned int i) -{ - return (HASHDEV(dev) ^ i) % NR_IHASH; -} +#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); - - 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; +/* Free list queue and management. */ +static struct free_inode_queue { + struct inode *head; + struct inode **last; +} free_inodes = { NULL, &free_inodes.head }; + +static inline void put_inode_head(struct inode *inode) +{ + if((inode->i_next = free_inodes.head) != NULL) + free_inodes.head->i_pprev = &inode->i_next; + else + free_inodes.last = &inode->i_next; + free_inodes.head = inode; + inode->i_pprev = &free_inodes.head; + nr_free_inodes++; } -static inline void put_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 = { 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; + 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; + } + if(pass == 0) { + inode = inuse_list; + pass = 1; + goto repeat; } - return 1; + return 1; /* Tis' cool bro. */ } -int fs_may_umount(kdev_t dev, struct inode * mount_root) +int fs_may_umount(kdev_t dev, struct inode *iroot) { - struct inode * inode; - int i; + struct inode *inode; + int pass = 0; - inode = first_inode; - for (i=0 ; i < nr_inodes ; i++, inode = inode->i_next) { - if (inode->i_dev != dev || !inode->i_count) + inode = free_inodes.head; +repeat: + for(; inode; inode = inode->i_next) { + if(inode->i_dev != dev || !inode->i_count) continue; - if (inode == mount_root && inode->i_count == - (inode->i_mount != inode ? 1 : 2)) + if(inode == iroot && + (inode->i_count == (inode->i_mount == inode ? 2 : 1))) continue; return 0; } - return 1; + if(pass == 0) { + inode = inuse_list; + pass = 1; + goto repeat; + } + return 1; /* Tis' cool bro. */ } +/* This belongs in file_table.c, not here... */ int fs_may_remount_ro(kdev_t dev) { struct file * file; @@ -239,79 +242,70 @@ 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; - - /* Make sure a caller can chown */ - if ((attr->ia_valid & ATTR_UID) && - (current->fsuid != inode->i_uid || - attr->ia_uid != inode->i_uid) && !fsuser()) - return -EPERM; - - /* Make sure caller can chgrp */ - if ((attr->ia_valid & ATTR_GID) && - (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) && - !fsuser()) - return -EPERM; + if(!(attr->ia_valid & ATTR_FORCE)) { + unsigned short fsuid = current->fsuid; + uid_t iuid = inode->i_uid; + int not_fsuser = !fsuser(); + + if(((attr->ia_valid & ATTR_UID) && + ((fsuid != iuid) || + (attr->ia_uid != iuid)) && not_fsuser) || + + ((attr->ia_valid & ATTR_GID) && + (!in_group_p(attr->ia_gid) && + (attr->ia_gid != inode->i_gid))) || - /* Make sure a caller can chmod */ - if (attr->ia_valid & ATTR_MODE) { - if ((current->fsuid != inode->i_uid) && !fsuser()) + ((attr->ia_valid & (ATTR_ATIME_SET | ATTR_MTIME_SET)) && + (fsuid != iuid) && not_fsuser)) return -EPERM; - /* Also check the setgid bit! */ - if (!fsuser() && !in_group_p((attr->ia_valid & ATTR_GID) ? attr->ia_gid : - inode->i_gid)) - attr->ia_mode &= ~S_ISGID; - } - /* Check for setting the inode time */ - if ((attr->ia_valid & ATTR_ATIME_SET) && - ((current->fsuid != inode->i_uid) && !fsuser())) - return -EPERM; - if ((attr->ia_valid & ATTR_MTIME_SET) && - ((current->fsuid != inode->i_uid) && !fsuser())) - return -EPERM; + if(attr->ia_valid & ATTR_MODE) { + gid_t grp; + if(fsuid != iuid && not_fsuser) + return -EPERM; + grp = attr->ia_valid & ATTR_GID ? attr->ia_gid : inode->i_gid; + if(not_fsuser && !in_group_p(grp)) + attr->ia_mode &= ~S_ISGID; + } + } return 0; } -/* - * Set the appropriate attributes from an attribute structure into - * the inode structure. - */ void inode_setattr(struct inode *inode, struct iattr *attr) { if (attr->ia_valid & ATTR_UID) @@ -334,17 +328,8 @@ inode->i_dirt = 1; } -/* - * notify_change is called for inode-changing operations such as - * chown, chmod, utime, and truncate. It is guaranteed (unlike - * write_inode) to be called from the context of the user requesting - * the change. - */ - -int notify_change(struct inode * inode, struct iattr *attr) +int notify_change(struct inode *inode, struct iattr *attr) { - int retval; - attr->ia_ctime = CURRENT_TIME; if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME)) { if (!(attr->ia_valid & ATTR_ATIME_SET)) @@ -353,303 +338,320 @@ 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) +static void grow_inodes(void) +{ + int i = 16; + + while(i--) { + struct inode *inode; + + inode = kmem_cache_alloc(inode_cachep, SLAB_KERNEL); + if(!inode) return; + memset(inode, 0, sizeof(*inode)); + put_inode_head(inode); + nr_inodes++; } +} - if (inode->i_dirt) { - write_inode(inode); /* we can sleep - so do again */ - wait_on_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 (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; - } + 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; + struct inode *inode = get_empty_inode(); - if (!(inode = get_empty_inode())) - return NULL; - if (!(PIPE_BASE(*inode) = (char*) __get_free_page(GFP_USER))) { - iput(inode); - return NULL; - } - inode->i_op = &pipe_inode_operations; - inode->i_count = 2; /* sum of readers/writers */ - PIPE_WAIT(*inode) = NULL; - PIPE_START(*inode) = PIPE_LEN(*inode) = 0; - PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; - PIPE_LOCK(*inode) = 0; - inode->i_pipe = 1; - inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_blksize = PAGE_SIZE; + if(inode) { + unsigned long page = __get_free_page(GFP_USER); + if(!page) { + iput(inode); + inode = NULL; + } else { + PIPE_BASE(*inode) = (char *) page; + inode->i_op = &pipe_inode_operations; + inode->i_count = 2; + PIPE_WAIT(*inode) = NULL; + PIPE_START(*inode) = PIPE_LEN(*inode) = 0; + PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; + PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; + PIPE_LOCK(*inode) = 0; + inode->i_pipe = 1; + inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_blksize = PAGE_SIZE; + } + } return inode; } -struct inode *__iget(struct super_block * sb, int nr, int crossmntp) +static int inode_updating[INODE_HASHSZ]; + +struct inode *__iget(struct super_block *sb, int nr, int crossmntp) { - static struct wait_queue * update_wait = NULL; - struct inode_hash_entry * h; - struct inode * inode; - struct inode * empty = NULL; - - if (!sb) - panic("VFS: iget with sb==NULL"); - h = hash(sb->s_dev, nr); -repeat: - for (inode = h->inode; inode ; inode = inode->i_hash_next) - if (inode->i_dev == sb->s_dev && inode->i_ino == nr) - goto found_it; - if (!empty) { - /* - * If we sleep here before we have found an inode - * we need to make sure nobody does anything bad - * to the inode while we sleep, because otherwise - * we may return an inode that is not valid any - * more when we wake up.. - */ - h->updating++; - empty = get_empty_inode(); - if (!--h->updating) - wake_up(&update_wait); - if (empty) - goto repeat; - return (NULL); - } - inode = empty; - inode->i_sb = sb; - inode->i_dev = sb->s_dev; - inode->i_ino = nr; - inode->i_flags = sb->s_flags; - put_last_free(inode); - insert_inode_hash(inode); - read_inode(inode); - goto return_it; + unsigned int hashent = hashfn(sb->s_dev, nr); + struct inode *inode, *empty = NULL; -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; +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; } diff -u --recursive --new-file v2.1.35/linux/fs/isofs/dir.c linux/fs/isofs/dir.c --- v2.1.35/linux/fs/isofs/dir.c Mon Apr 14 16:28:17 1997 +++ linux/fs/isofs/dir.c Thu Apr 17 09:28:01 1997 @@ -155,6 +155,11 @@ filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1)) + ISOFS_BLOCK_SIZE); offset = 0; + if( filp->f_pos >= inode->i_size ) + { + return 0; + } + block = isofs_bmap(inode, (filp->f_pos) >> bufbits); if (!block) return 0; diff -u --recursive --new-file v2.1.35/linux/fs/isofs/inode.c linux/fs/isofs/inode.c --- v2.1.35/linux/fs/isofs/inode.c Mon Apr 14 16:28:17 1997 +++ linux/fs/isofs/inode.c Thu Apr 17 13:20:47 1997 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -920,7 +921,7 @@ isofs_read_super, "iso9660", 1, NULL }; -int init_iso9660_fs(void) +__initfunc(int init_iso9660_fs(void)) { return register_filesystem(&iso9660_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/isofs/namei.c linux/fs/isofs/namei.c --- v2.1.35/linux/fs/isofs/namei.c Sat Nov 30 02:24:01 1996 +++ linux/fs/isofs/namei.c Thu Apr 17 09:28:01 1997 @@ -98,6 +98,12 @@ offset = 0; f_pos = ((f_pos & ~(ISOFS_BLOCK_SIZE - 1)) + ISOFS_BLOCK_SIZE); + + if( f_pos >= dir->i_size ) + { + return 0; + } + block = isofs_bmap(dir,f_pos>>bufbits); if (!block || !(bh = bread(dir->i_dev,block,bufsize))) return 0; diff -u --recursive --new-file v2.1.35/linux/fs/lockd/host.c linux/fs/lockd/host.c --- v2.1.35/linux/fs/lockd/host.c Mon Apr 7 11:35:30 1997 +++ linux/fs/lockd/host.c Tue Apr 15 21:47:24 1997 @@ -21,7 +21,7 @@ #define NLM_HOST_MAX 64 #define NLM_HOST_NRHASH 32 #define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1)) -#define NLM_PTRHASH(ptr) ((((u32) ptr) / 32) & (NLM_HOST_NRHASH-1)) +#define NLM_PTRHASH(ptr) ((((u32)(unsigned long) ptr) / 32) & (NLM_HOST_NRHASH-1)) #define NLM_HOST_REBIND (60 * HZ) #define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) #define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) @@ -81,8 +81,8 @@ return NULL; } - dprintk("lockd: nlm_lookup_host(%08lx, p=%d, v=%d)\n", - sin? ntohl(sin->sin_addr.s_addr) : 0, proto, version); + dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n", + (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version); if (clnt) hash = NLM_PTRHASH(clnt); @@ -164,8 +164,8 @@ struct rpc_clnt *clnt; struct rpc_xprt *xprt; - dprintk("lockd: nlm_bind_host(%08lx)\n", - ntohl(host->h_addr.sin_addr.s_addr)); + dprintk("lockd: nlm_bind_host(%08x)\n", + (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); /* Lock host handle */ down(&host->h_sema); diff -u --recursive --new-file v2.1.35/linux/fs/lockd/svc.c linux/fs/lockd/svc.c --- v2.1.35/linux/fs/lockd/svc.c Mon Apr 7 11:35:30 1997 +++ linux/fs/lockd/svc.c Tue Apr 15 21:47:24 1997 @@ -130,8 +130,8 @@ break; } - dprintk("lockd: request from %08lx\n", - ntohl(rqstp->rq_addr.sin_addr.s_addr)); + dprintk("lockd: request from %08x\n", + (unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr)); /* * Look up the NFS client handle. The handle is needed for diff -u --recursive --new-file v2.1.35/linux/fs/minix/inode.c linux/fs/minix/inode.c --- v2.1.35/linux/fs/minix/inode.c Fri Dec 27 02:03:25 1996 +++ linux/fs/minix/inode.c Thu Apr 17 13:20:47 1997 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -946,7 +947,7 @@ minix_read_super, "minix", 1, NULL }; -int init_minix_fs(void) +__initfunc(int init_minix_fs(void)) { return register_filesystem(&minix_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/msdos/msdosfs_syms.c linux/fs/msdos/msdosfs_syms.c --- v2.1.35/linux/fs/msdos/msdosfs_syms.c Thu Mar 27 14:40:06 1997 +++ linux/fs/msdos/msdosfs_syms.c Thu Apr 17 13:20:48 1997 @@ -10,6 +10,7 @@ #include #include +#include /* * Support for umsdos fs @@ -33,7 +34,7 @@ msdos_read_super, "msdos", 1, NULL }; -int init_msdos_fs(void) +__initfunc(int init_msdos_fs(void)) { return register_filesystem(&msdos_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.1.35/linux/fs/ncpfs/inode.c Fri Apr 4 08:52:24 1997 +++ linux/fs/ncpfs/inode.c Thu Apr 17 13:20:48 1997 @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_KERNELD #include #endif @@ -409,7 +410,7 @@ ncp_read_super, "ncpfs", 0, NULL }; -int init_ncp_fs(void) +__initfunc(int init_ncp_fs(void)) { return register_filesystem(&ncp_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.1.35/linux/fs/nfs/dir.c Mon Apr 7 11:35:30 1997 +++ linux/fs/nfs/dir.c Tue Apr 15 21:47:24 1997 @@ -206,7 +206,7 @@ } if (entry) { dfprintk(DIRCACHE, "NFS: found dircache entry %d\n", - cache - dircache); + (int)(cache - dircache)); cache->locked = 1; break; } @@ -223,7 +223,7 @@ goto again; } dfprintk(DIRCACHE, "NFS: using free dircache entry %d\n", - free - dircache); + (int)(free - dircache)); cache->cookie = cookie; cache->locked = 1; cache->valid = 0; @@ -298,7 +298,7 @@ ino_t ino = inode->i_ino; int i; - dfprintk(DIRCACHE, "NFS: invalidate dircache for %x/%ld\n", dev, ino); + dfprintk(DIRCACHE, "NFS: invalidate dircache for %x/%ld\n", dev, (long)ino); for (i = 0, cache = dircache; i < NFS_MAX_DIRCACHE; i++, cache++) { if (!cache->locked && cache->dev == dev && cache->ino == ino) cache->valid = 0; /* brute force */ @@ -445,7 +445,7 @@ return; dfprintk(LOOKUPCACHE, "NFS: lookup_cache_remove(%x/%ld)\n", - dev, fileid); + dev, (long)fileid); for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) { entry = nfs_lookup_cache + i; diff -u --recursive --new-file v2.1.35/linux/fs/nfs/mount_clnt.c linux/fs/nfs/mount_clnt.c --- v2.1.35/linux/fs/nfs/mount_clnt.c Mon Apr 14 16:28:17 1997 +++ linux/fs/nfs/mount_clnt.c Tue Apr 15 21:47:24 1997 @@ -49,8 +49,8 @@ char hostname[32]; int status; - dprintk("NFS: nfs_mount(%08lx:%s)\n", - ntohl(addr->sin_addr.s_addr), path); + dprintk("NFS: nfs_mount(%08x:%s)\n", + (unsigned)ntohl(addr->sin_addr.s_addr), path); strcpy(hostname, in_ntoa(addr->sin_addr.s_addr)); if (!(mnt_clnt = mnt_create(hostname, addr))) diff -u --recursive --new-file v2.1.35/linux/fs/nfs/nfs2xdr.c linux/fs/nfs/nfs2xdr.c --- v2.1.35/linux/fs/nfs/nfs2xdr.c Mon Apr 14 16:28:17 1997 +++ linux/fs/nfs/nfs2xdr.c Wed Apr 16 14:20:12 1997 @@ -222,7 +222,7 @@ struct iovec *iov = req->rq_rvec; int status, count, recvd, hdrlen; - dprintk("RPC: readres OK status %lx\n", ntohl(*p)); + dprintk("RPC: readres OK status %lx\n", (long)ntohl(*p)); if ((status = ntohl(*p++))) return -nfs_stat_to_errno(status); p = xdr_decode_fattr(p, res->fattr); @@ -414,9 +414,16 @@ } string -= len; if ((void *) (entry+1) > (void *) string) { + /* This may actually happen because an nfs_entry + * will take up more space than the XDR data. On + * 32bit machines that's due to 8byte alignment, + * on 64bit machines that's because the char * takes + * up 2 longs. + * + * THIS IS BAD! + */ printk(KERN_NOTICE "NFS: should not happen in %s!\n", - __FUNCTION__); - printk(KERN_NOTICE "NFS: len = %d, entry+1=%p, string=%p\n", len, entry+1, string); + __FUNCTION__); break; } @@ -464,7 +471,7 @@ { int status; - dprintk("RPC: attrstat status %lx\n", ntohl(*p)); + dprintk("RPC: attrstat status %lx\n", (long)ntohl(*p)); if ((status = ntohl(*p++))) return -nfs_stat_to_errno(status); xdr_decode_fattr(p, fattr); @@ -482,7 +489,7 @@ { int status; - dprintk("RPC: diropres status %lx\n", ntohl(*p)); + dprintk("RPC: diropres status %lx\n", (long)ntohl(*p)); if ((status = ntohl(*p++))) return -nfs_stat_to_errno(status); p = xdr_decode_fhandle(p, res->fh); diff -u --recursive --new-file v2.1.35/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c --- v2.1.35/linux/fs/nfsd/nfsctl.c Mon Apr 7 11:35:31 1997 +++ linux/fs/nfsd/nfsctl.c Tue Apr 22 22:49:38 1997 @@ -35,6 +35,8 @@ # define copy_to_user memcpy_tofs # define access_ok !verify_area #endif +#include +#include extern long sys_call_table[]; @@ -126,20 +128,30 @@ return err; } +#ifdef CONFIG_NFSD +#define handle_sys_nfsservctl sys_nfsservctl +#endif + int -asmlinkage sys_nfsservctl(int cmd, struct nfsctl_arg *argp, union nfsctl_res *resp) +asmlinkage handle_sys_nfsservctl(int cmd, struct nfsctl_arg *argp, + union nfsctl_res *resp) { struct nfsctl_arg * arg = NULL; union nfsctl_res * res = NULL; int err; + lock_kernel (); if (!initialized) nfsd_init(); - if (!suser()) - return -EPERM; + if (!suser()) { + err = -EPERM; + goto done; + } if (!access_ok(VERIFY_READ, argp, sizeof(*argp)) - || (resp && !access_ok(VERIFY_WRITE, resp, sizeof(*resp)))) - return -EFAULT; + || (resp && !access_ok(VERIFY_WRITE, resp, sizeof(*resp)))) { + err = -EFAULT; + goto done; + } if (!(arg = kmalloc(sizeof(*arg), GFP_USER)) || (resp && !(res = kmalloc(sizeof(*res), GFP_USER)))) { err = -ENOMEM; /* ??? */ @@ -191,6 +203,7 @@ if (res) kfree(res); + unlock_kernel (); return err; } @@ -203,6 +216,8 @@ static unsigned long old_syscallvec; +extern int (*do_nfsservctl)(int, void *, void *); + /* * Initialize the module */ @@ -210,10 +225,8 @@ init_module(void) { printk("Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); - - old_syscallvec = sys_call_table[__NR_nfsservctl]; - sys_call_table[__NR_nfsservctl] = (unsigned long) sys_nfsservctl; nfsd_init(); + do_nfsservctl = handle_sys_nfsservctl; return 0; } @@ -227,7 +240,7 @@ printk("nfsd: nfsd busy, remove delayed\n"); return; } - sys_call_table[__NR_nfsservctl] = old_syscallvec; + do_nfsservctl = NULL; nfsd_export_shutdown(); nfsd_cache_shutdown(); #ifdef CONFIG_PROC_FS diff -u --recursive --new-file v2.1.35/linux/fs/nfsd/nfssvc.c linux/fs/nfsd/nfssvc.c --- v2.1.35/linux/fs/nfsd/nfssvc.c Mon Apr 14 16:28:18 1997 +++ linux/fs/nfsd/nfssvc.c Tue Apr 22 22:49:38 1997 @@ -116,7 +116,7 @@ /* * The main request loop */ - do { + for (;;) { /* * Find a socket with data available and call its * recvfrom routine. @@ -150,7 +150,7 @@ /* Unlock export hash tables */ exp_unlock(); - } while (err >= 0); + } if (err != -EINTR) { printk(KERN_WARNING "nfsd: terminating on error %d\n", -err); diff -u --recursive --new-file v2.1.35/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c --- v2.1.35/linux/fs/nfsd/vfs.c Mon Apr 14 16:28:18 1997 +++ linux/fs/nfsd/vfs.c Tue Apr 15 21:47:24 1997 @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.35/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.1.35/linux/fs/proc/root.c Mon Apr 7 11:35:31 1997 +++ linux/fs/proc/root.c Wed Apr 16 10:55:21 1997 @@ -365,7 +365,7 @@ char tmp[30]; iput(inode); - len = 1 + sprintf(tmp, "%d", current->pid); + len = sprintf(tmp, "%d", current->pid); if (buflen < len) len = buflen; copy_to_user(buffer, tmp, len); diff -u --recursive --new-file v2.1.35/linux/fs/romfs/inode.c linux/fs/romfs/inode.c --- v2.1.35/linux/fs/romfs/inode.c Mon Apr 14 16:28:18 1997 +++ linux/fs/romfs/inode.c Thu Apr 17 13:20:48 1997 @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -640,8 +641,7 @@ romfs_read_super, "romfs", 1, NULL }; -int -init_romfs_fs(void) +__initfunc(int init_romfs_fs(void)) { return register_filesystem(&romfs_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.1.35/linux/fs/smbfs/inode.c Sun Jan 19 05:47:26 1997 +++ linux/fs/smbfs/inode.c Thu Apr 17 13:20:48 1997 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -432,8 +433,7 @@ smb_read_super, "smbfs", 0, NULL }; -int -init_smb_fs(void) +__initfunc(int init_smb_fs(void)) { return register_filesystem(&smb_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/sysv/inode.c linux/fs/sysv/inode.c --- v2.1.35/linux/fs/sysv/inode.c Fri Jan 3 01:33:26 1997 +++ linux/fs/sysv/inode.c Thu Apr 17 13:20:48 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -979,7 +980,7 @@ {sysv_read_super, "coherent", 1, NULL} }; -int init_sysv_fs(void) +__initfunc(int init_sysv_fs(void)) { int i; int ouch; diff -u --recursive --new-file v2.1.35/linux/fs/ufs/ufs_super.c linux/fs/ufs/ufs_super.c --- v2.1.35/linux/fs/ufs/ufs_super.c Sun Jan 26 02:07:46 1997 +++ linux/fs/ufs/ufs_super.c Thu Apr 17 13:20:48 1997 @@ -8,7 +8,7 @@ * * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * - * $Id: ufs_super.c,v 1.22 1997/01/16 14:17:41 davem Exp $ + * $Id: ufs_super.c,v 1.23 1997/04/16 04:53:39 tdyas Exp $ * */ @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -51,8 +52,7 @@ ufs_read_super, "ufs", 1, NULL }; -int -init_ufs_fs(void) +__initfunc(int init_ufs_fs(void)) { return(register_filesystem(&ufs_fs_type)); } diff -u --recursive --new-file v2.1.35/linux/fs/umsdos/inode.c linux/fs/umsdos/inode.c --- v2.1.35/linux/fs/umsdos/inode.c Fri Dec 27 02:03:26 1996 +++ linux/fs/umsdos/inode.c Thu Apr 17 13:20:48 1997 @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -499,7 +500,7 @@ UMSDOS_read_super, "umsdos", 1, NULL }; -int init_umsdos_fs(void) +__initfunc(int init_umsdos_fs(void)) { return register_filesystem(&umsdos_fs_type); } diff -u --recursive --new-file v2.1.35/linux/fs/vfat/namei.c linux/fs/vfat/namei.c --- v2.1.35/linux/fs/vfat/namei.c Fri Jan 3 01:33:26 1997 +++ linux/fs/vfat/namei.c Thu Apr 17 13:20:48 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -1587,7 +1588,7 @@ EXPORT_SYMBOL(vfat_read_inode); EXPORT_SYMBOL(vfat_lookup); -int init_vfat_fs(void) +__initfunc(int init_vfat_fs(void)) { return register_filesystem(&vfat_fs_type); } diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h --- v2.1.35/linux/include/asm-alpha/atomic.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-alpha/atomic.h Thu Apr 17 13:20:48 1997 @@ -15,7 +15,7 @@ typedef struct { int counter; } atomic_t; #endif -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/init.h linux/include/asm-alpha/init.h --- v2.1.35/linux/include/asm-alpha/init.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-alpha/init.h Tue Apr 22 22:38:40 1997 @@ -1,14 +1,15 @@ #ifndef _ALPHA_INIT_H #define _ALPHA_INIT_H -/* Throwing the initialization code and data out is not supported yet... */ +#define __init __attribute__ ((__section__ (".text.init"))) +#define __initdata __attribute__ ((__section__ (".data.init"))) +#define __initfunc(__arginit) \ + __arginit __init; \ + __arginit -#define __init -#define __initdata -#define __initfunc(__arginit) __arginit /* For assembly routines */ -#define __INIT -#define __FINIT -#define __INITDATA +#define __INIT .section .text.init,"ax" +#define __FINIT .previous +#define __INITDATA .section .data.init,"a" #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v2.1.35/linux/include/asm-alpha/processor.h Sun Jan 26 02:07:46 1997 +++ linux/include/asm-alpha/processor.h Tue Apr 22 22:38:40 1997 @@ -42,6 +42,7 @@ /* the fields below are Linux-specific: */ /* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h) */ + /* bit 6..8: UAC bits (see sysinfo.h) */ unsigned long flags; /* perform syscall argument validation (get/set_fs) */ unsigned long fs; diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h --- v2.1.35/linux/include/asm-alpha/semaphore.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-alpha/semaphore.h Thu Apr 17 13:20:48 1997 @@ -15,8 +15,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/smp_lock.h linux/include/asm-alpha/smp_lock.h --- v2.1.35/linux/include/asm-alpha/smp_lock.h Fri Apr 4 08:52:24 1997 +++ linux/include/asm-alpha/smp_lock.h Thu Apr 17 09:23:54 1997 @@ -6,7 +6,7 @@ #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) +#define reacquire_kernel_lock(task, cpu, depth) do { } while (0) #else diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h --- v2.1.35/linux/include/asm-alpha/softirq.h Mon Apr 14 16:28:18 1997 +++ linux/include/asm-alpha/softirq.h Tue Apr 22 22:38:40 1997 @@ -31,6 +31,12 @@ bh_mask |= 1 << nr; } +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + extern inline void mark_bh(int nr) { set_bit(nr, &bh_active); diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h --- v2.1.35/linux/include/asm-alpha/spinlock.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-alpha/spinlock.h Tue Apr 22 22:38:40 1997 @@ -9,6 +9,7 @@ #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) @@ -16,6 +17,33 @@ #define spin_lock_irqsave(lock, flags) swpipl(flags,7) #define spin_unlock_irqrestore(lock, flags) setipl(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 /* Simple spin lock operations. There are two variants, one clears IRQ's @@ -30,6 +58,9 @@ } spinlock_t; #define SPIN_LOCK_UNLOCKED { 0, 0 } + +#define spin_lock_init(lock) do { (lock)->lock = 0; (lock)->previous = 0; } while(0) +#define spin_unlock_wait(lock) do { barrier(); } while(((volatile spinlock_t *)lock)->lock) typedef struct { unsigned long a[100]; } __dummy_lock_t; #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) diff -u --recursive --new-file v2.1.35/linux/include/asm-alpha/sysinfo.h linux/include/asm-alpha/sysinfo.h --- v2.1.35/linux/include/asm-alpha/sysinfo.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/sysinfo.h Tue Apr 22 22:38:40 1997 @@ -0,0 +1,36 @@ +/* + * include/asm-alpha/sysinfo.h + */ + +#ifndef __ASM_ALPHA_SYSINFO_H +#define __ASM_ALPHA_SYSINFO_H + +/* This defines the subset of the OSF/1 getsysinfo/setsysinfo calls + that we support. */ + +#define GSI_UACPROC 8 +#define GSI_IEEE_FP_CONTROL 45 +#define GSI_IEEE_STATE_AT_SIGNAL 46 + +#define SSI_NVPAIRS 1 +#define SSI_IEEE_FP_CONTROL 14 +#define SSI_IEEE_STATE_AT_SIGNAL 15 +#define SSI_IEEE_IGNORE_STATE_AT_SIGNAL 16 + +#define SSIN_UACPROC 6 + +#define UAC_BITMASK 7 +#define UAC_NOPRINT 1 +#define UAC_NOFIX 2 +#define UAC_SIGBUS 4 + + +#ifdef __KERNEL__ + +/* This is the shift that is applied to the UAC bits as stored in the + per-thread flags. */ +#define UAC_SHIFT 6 + +#endif + +#endif /* __ASM_ALPHA_SYSINFO_H */ diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/atomic.h linux/include/asm-i386/atomic.h --- v2.1.35/linux/include/asm-i386/atomic.h Mon Apr 14 16:28:18 1997 +++ linux/include/asm-i386/atomic.h Thu Apr 17 13:20:48 1997 @@ -25,7 +25,7 @@ typedef struct { int counter; } atomic_t; #endif -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/init.h linux/include/asm-i386/init.h --- v2.1.35/linux/include/asm-i386/init.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-i386/init.h Thu Apr 17 13:20:48 1997 @@ -1,7 +1,6 @@ #ifndef _I386_INIT_H #define _I386_INIT_H -#ifndef MODULE #define __init __attribute__ ((__section__ (".text.init"))) #define __initdata __attribute__ ((__section__ (".data.init"))) #define __initfunc(__arginit) \ @@ -11,14 +10,5 @@ #define __INIT .section ".text.init",#alloc,#execinstr #define __FINIT .previous #define __INITDATA .section ".data.init",#alloc,#write -#else -#define __init -#define __initdata -#define __initfunc(__arginit) __arginit -/* For assembly routines */ -#define __INIT -#define __FINIT -#define __INITDATA -#endif #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h --- v2.1.35/linux/include/asm-i386/pgtable.h Thu Feb 6 02:53:43 1997 +++ linux/include/asm-i386/pgtable.h Wed Apr 23 11:00:45 1997 @@ -205,6 +205,7 @@ #define _PAGE_ACCESSED 0x020 #define _PAGE_DIRTY 0x040 #define _PAGE_4M 0x080 /* 4 MB page, Pentium+.. */ +#define _PAGE_GLOBAL 0x100 /* Global TLB entry PPro+ */ #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) @@ -374,6 +375,8 @@ free_page((unsigned long) pte); } +extern const char bad_pmd_string[]; + extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); @@ -390,7 +393,7 @@ free_page((unsigned long) page); } if (pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + printk(bad_pmd_string, pmd_val(*pmd)); pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); return NULL; } @@ -443,7 +446,7 @@ } fix: - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + printk(bad_pmd_string, pmd_val(*pmd)); oom: pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE); return NULL; diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h --- v2.1.35/linux/include/asm-i386/semaphore.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-i386/semaphore.h Thu Apr 17 13:20:48 1997 @@ -28,8 +28,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { 1 }, 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, 0, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL }) asmlinkage void __down_failed(void /* special register calling convention */); asmlinkage int __down_failed_interruptible(void /* params in registers */); diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h --- v2.1.35/linux/include/asm-i386/smp.h Thu Feb 27 10:57:31 1997 +++ linux/include/asm-i386/smp.h Tue Apr 15 21:47:24 1997 @@ -234,52 +234,6 @@ return GET_APIC_ID(*(unsigned long *)(apic_reg+APIC_ID)); } -/* These read/change the "processes available" counter in the scheduler. */ -extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr) -{ - int cpu = smp_processor_id(); - while(set_bit(31, ctr)) - { - while(test_bit(31,ctr)) - { - if(clear_bit(cpu,&smp_invalidate_needed)) - { - unsigned long tmpreg; - __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3" - : "=r" (tmpreg) : : "memory"); - set_bit(cpu,&cpu_callin_map[0]); - } - } - } - *ctr = (*ctr + 1); - clear_bit(31, ctr); -} - -extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr) -{ - int cpu = smp_processor_id(); - while(set_bit(31, ctr)) - { - while(test_bit(31,ctr)) - { - if(clear_bit(cpu,&smp_invalidate_needed)) - { - unsigned long tmpreg; - __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3" - : "=r" (tmpreg) : : "memory"); - set_bit(cpu,&cpu_callin_map[0]); - } - } - } - *ctr = (*ctr - 1); - clear_bit(31, ctr); -} - -extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr) -{ - return (*ctr & 0x7fffffff); -} - #endif /* !ASSEMBLY */ #define NO_PROC_ID 0xFF /* No processor magic marker */ diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/smp_lock.h linux/include/asm-i386/smp_lock.h --- v2.1.35/linux/include/asm-i386/smp_lock.h Fri Apr 4 08:52:25 1997 +++ linux/include/asm-i386/smp_lock.h Thu Apr 17 13:29:54 1997 @@ -8,7 +8,7 @@ #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) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) #else @@ -27,8 +27,8 @@ __sti(); \ } while (0) -/* Re-aquire the kernel lock */ -#define reaquire_kernel_lock(task, cpu, depth) \ +/* Re-acquire the kernel lock */ +#define reacquire_kernel_lock(task, cpu, depth) \ do { if (depth) __asm__ __volatile__( \ "cli\n\t" \ "movl $0f,%%eax\n\t" \ diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h --- v2.1.35/linux/include/asm-i386/softirq.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-i386/softirq.h Tue Apr 22 22:44:18 1997 @@ -14,6 +14,12 @@ bh_mask |= 1 << nr; } +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + extern inline void mark_bh(int nr) { set_bit(nr, &bh_active); diff -u --recursive --new-file v2.1.35/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h --- v2.1.35/linux/include/asm-i386/spinlock.h Thu Mar 27 14:40:06 1997 +++ linux/include/asm-i386/spinlock.h Tue Apr 22 23:23:36 1997 @@ -3,12 +3,16 @@ #ifndef __SMP__ +/* + * Your basic spinlocks, allowing only a single CPU anywhere + */ 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() @@ -18,9 +22,41 @@ #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) \ + do { save_flags(flags); cli(); } while (0) +#define read_unlock_irqrestore(lock, flags) \ + restore_flags(flags) +#define write_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define write_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + #else -/* Simple spin lock operations. There are two variants, one clears IRQ's +/* + * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. * * We make no fairness assumptions. They have a cost. @@ -33,6 +69,9 @@ #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)) @@ -91,6 +130,80 @@ #define spin_unlock_irqrestore(lock, flags) \ do { spin_unlock(lock); __restore_flags(flags); } while (0) + +/* + * 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 { + volatile unsigned int lock; + unsigned long previous; +} rwlock_t; + +#define RW_LOCK_UNLOCKED { 0, 0 } + +/* + * On x86, we implement read-write locks as a 32-bit counter + * with the high bit (sign) being the "write" bit. + * + * The inline assembly is non-obvious. Think about it. + */ +#define read_lock(rw) \ + asm volatile("\n1:\t" \ + "lock ; incl %0\n\t" \ + "js 2f\n" \ + ".text 2\n" \ + "2:\tlock ; decl %0\n" \ + "3:\tcmpl $0,%0\n\t" \ + "js 3b\n\t" \ + "jmp 1b\n" \ + ".text" \ + :"=m" (__dummy_lock(&(rw)->lock))) + +#define read_unlock(rw) \ + asm volatile("lock ; decl %0" \ + :"=m" (__dummy_lock(&(rw)->lock))) + +#define write_lock(rw) \ + asm volatile("\n1:\t" \ + "lock ; btsl $31,%0\n\t" \ + "jc 3f\n\t" \ + "testl $0x7fffffff,%0\n\t" \ + "jne 4f\n" \ + "2:\n" \ + ".text 2\n" \ + "3:\ttestl $-1,%0\n\t" \ + "js 3b\n\t" \ + "lock ; btsl $31,%0\n\t" \ + "jc 3b\n" \ + "4:\ttestl $0x7fffffff,%0\n\t" \ + "jne 4b\n\t" \ + "jmp 2b\n" \ + ".text" \ + :"=m" (__dummy_lock(&(rw)->lock))) + +#define write_unlock(rw) \ + asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock))) + +#define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0) +#define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0) +#define write_lock_irq(lock) do { __cli(); write_lock(lock); } while (0) +#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0) + +#define read_lock_irqsave(lock, flags) \ + do { __save_flags(flags); __cli(); read_lock(lock); } while (0) +#define read_unlock_irqrestore(lock, flags) \ + do { read_unlock(lock); __restore_flags(flags); } while (0) +#define write_lock_irqsave(lock, flags) \ + do { __save_flags(flags); __cli(); write_lock(lock); } while (0) +#define write_unlock_irqrestore(lock, flags) \ + do { write_unlock(lock); __restore_flags(flags); } while (0) #endif /* SMP */ #endif /* __ASM_SPINLOCK_H */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/amigaints.h linux/include/asm-m68k/amigaints.h --- v2.1.35/linux/include/asm-m68k/amigaints.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/amigaints.h Thu Apr 17 13:20:48 1997 @@ -18,53 +18,65 @@ ** */ -#define AMI_IRQS (24) +#define AUTO_IRQS (8) #define AMI_STD_IRQS (14) #define CIA_IRQS (5) +#define AMI_IRQS (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */ /* vertical blanking interrupt */ -#define IRQ_AMIGA_VERTB (IRQ_MACHSPEC | 0) +#define IRQ_AMIGA_VERTB 0 /* copper interrupt */ -#define IRQ_AMIGA_COPPER (IRQ_MACHSPEC | 1) +#define IRQ_AMIGA_COPPER 1 /* Audio interrupts */ -#define IRQ_AMIGA_AUD0 (IRQ_MACHSPEC | 2) -#define IRQ_AMIGA_AUD1 (IRQ_MACHSPEC | 3) -#define IRQ_AMIGA_AUD2 (IRQ_MACHSPEC | 4) -#define IRQ_AMIGA_AUD3 (IRQ_MACHSPEC | 5) +#define IRQ_AMIGA_AUD0 2 +#define IRQ_AMIGA_AUD1 3 +#define IRQ_AMIGA_AUD2 4 +#define IRQ_AMIGA_AUD3 5 /* Blitter done interrupt */ -#define IRQ_AMIGA_BLIT (IRQ_MACHSPEC | 6) +#define IRQ_AMIGA_BLIT 6 /* floppy disk interrupts */ -#define IRQ_AMIGA_DSKSYN (IRQ_MACHSPEC | 7) -#define IRQ_AMIGA_DSKBLK (IRQ_MACHSPEC | 8) +#define IRQ_AMIGA_DSKSYN 7 +#define IRQ_AMIGA_DSKBLK 8 /* builtin serial port interrupts */ -#define IRQ_AMIGA_RBF (IRQ_MACHSPEC | 9) -#define IRQ_AMIGA_TBE (IRQ_MACHSPEC | 10) +#define IRQ_AMIGA_RBF 9 +#define IRQ_AMIGA_TBE 10 /* software interrupts */ -#define IRQ_AMIGA_SOFT (IRQ_MACHSPEC | 11) +#define IRQ_AMIGA_SOFT 11 /* interrupts from external hardware */ -#define IRQ_AMIGA_PORTS (IRQ_MACHSPEC | 12) -#define IRQ_AMIGA_EXTER (IRQ_MACHSPEC | 13) +#define IRQ_AMIGA_PORTS 12 +#define IRQ_AMIGA_EXTER 13 /* CIA interrupt sources */ -#define IRQ_AMIGA_CIAA (IRQ_MACHSPEC | 14) -#define IRQ_AMIGA_CIAA_TA (IRQ_MACHSPEC | 14) -#define IRQ_AMIGA_CIAA_TB (IRQ_MACHSPEC | 15) -#define IRQ_AMIGA_CIAA_ALRM (IRQ_MACHSPEC | 16) -#define IRQ_AMIGA_CIAA_SP (IRQ_MACHSPEC | 17) -#define IRQ_AMIGA_CIAA_FLG (IRQ_MACHSPEC | 18) -#define IRQ_AMIGA_CIAB (IRQ_MACHSPEC | 19) -#define IRQ_AMIGA_CIAB_TA (IRQ_MACHSPEC | 19) -#define IRQ_AMIGA_CIAB_TB (IRQ_MACHSPEC | 20) -#define IRQ_AMIGA_CIAB_ALRM (IRQ_MACHSPEC | 21) -#define IRQ_AMIGA_CIAB_SP (IRQ_MACHSPEC | 22) -#define IRQ_AMIGA_CIAB_FLG (IRQ_MACHSPEC | 23) +#define IRQ_AMIGA_CIAA 14 +#define IRQ_AMIGA_CIAA_TA 14 +#define IRQ_AMIGA_CIAA_TB 15 +#define IRQ_AMIGA_CIAA_ALRM 16 +#define IRQ_AMIGA_CIAA_SP 17 +#define IRQ_AMIGA_CIAA_FLG 18 +#define IRQ_AMIGA_CIAB 19 +#define IRQ_AMIGA_CIAB_TA 19 +#define IRQ_AMIGA_CIAB_TB 20 +#define IRQ_AMIGA_CIAB_ALRM 21 +#define IRQ_AMIGA_CIAB_SP 22 +#define IRQ_AMIGA_CIAB_FLG 23 + +/* auto-vector interrupts */ +#define IRQ_AMIGA_AUTO 24 +#define IRQ_AMIGA_AUTO_0 24 /* This is just a dummy */ +#define IRQ_AMIGA_AUTO_1 25 +#define IRQ_AMIGA_AUTO_2 26 +#define IRQ_AMIGA_AUTO_3 27 +#define IRQ_AMIGA_AUTO_4 28 +#define IRQ_AMIGA_AUTO_5 29 +#define IRQ_AMIGA_AUTO_6 30 +#define IRQ_AMIGA_AUTO_7 31 #define IRQ_FLOPPY IRQ_AMIGA_DSKBLK diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/atarihw.h linux/include/asm-m68k/atarihw.h --- v2.1.35/linux/include/asm-m68k/atarihw.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/atarihw.h Thu Apr 17 13:20:48 1997 @@ -79,6 +79,7 @@ ATARIHW_DECLARE(SCU); /* System Control Unit */ ATARIHW_DECLARE(BLITTER); /* Blitter */ ATARIHW_DECLARE(VME); /* VME Bus */ + ATARIHW_DECLARE(DSP56K); /* DSP56k processor in Falcon */ }; extern struct atari_hw_present atari_hw_present; @@ -97,6 +98,7 @@ void atari_stram_free (void *); extern int is_medusa; +extern int is_hades; /* Do cache push/invalidate for DMA read/write. This function obeys the * snooping on some machines (Medusa) and processors: The Medusa itself can @@ -356,8 +358,8 @@ { u_char tracks; u_char input_source; -#define CODEC_SOURCE_MATRIX 1 -#define CODEC_SOURCE_ADC 2 +#define CODEC_SOURCE_ADC 1 +#define CODEC_SOURCE_MATRIX 2 u_char adc_source; #define ADC_SOURCE_RIGHT_PSG 1 #define ADC_SOURCE_LEFT_PSG 2 @@ -673,17 +675,28 @@ }; # define tt_dmasnd ((*(volatile struct TT_DMASND *)TT_DMASND_BAS)) -#define DMASND_CTRL_OFF 0x00 -#define DMASND_CTRL_ON 0x01 -#define DMASND_CTRL_REPEAT 0x02 -#define DMASND_MODE_MONO 0x80 -#define DMASND_MODE_STEREO 0x00 -#define DMASND_MODE_8BIT 0x00 -#define DMASND_MODE_16BIT 0x40 /* Falcon only */ -#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ -#define DMASND_MODE_12KHZ 0x01 -#define DMASND_MODE_25KHZ 0x02 -#define DMASND_MODE_50KHZ 0x03 +#define DMASND_MFP_INT_REPLAY 0x01 +#define DMASND_MFP_INT_RECORD 0x02 +#define DMASND_TIMERA_INT_REPLAY 0x04 +#define DMASND_TIMERA_INT_RECORD 0x08 + +#define DMASND_CTRL_OFF 0x00 +#define DMASND_CTRL_ON 0x01 +#define DMASND_CTRL_REPEAT 0x02 +#define DMASND_CTRL_RECORD_ON 0x10 +#define DMASND_CTRL_RECORD_OFF 0x00 +#define DMASND_CTRL_RECORD_REPEAT 0x20 +#define DMASND_CTRL_SELECT_REPLAY 0x00 +#define DMASND_CTRL_SELECT_RECORD 0x80 +#define DMASND_MODE_MONO 0x80 +#define DMASND_MODE_STEREO 0x00 +#define DMASND_MODE_8BIT 0x00 +#define DMASND_MODE_16BIT 0x40 /* Falcon only */ +#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ +#define DMASND_MODE_12KHZ 0x01 +#define DMASND_MODE_25KHZ 0x02 +#define DMASND_MODE_50KHZ 0x03 + #define DMASNDSetBase(bufstart) \ do { \ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/atariints.h linux/include/asm-m68k/atariints.h --- v2.1.35/linux/include/asm-m68k/atariints.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/atariints.h Thu Apr 17 13:20:48 1997 @@ -26,11 +26,11 @@ ** */ -#define STMFP_SOURCE_BASE 8 -#define TTMFP_SOURCE_BASE 24 -#define SCC_SOURCE_BASE 40 -#define VME_SOURCE_BASE 56 -#define VME_MAX_SOURCES 16 +#define STMFP_SOURCE_BASE 8 +#define TTMFP_SOURCE_BASE 24 +#define SCC_SOURCE_BASE 40 +#define VME_SOURCE_BASE 56 +#define VME_MAX_SOURCES 16 #define NUM_ATARI_SOURCES (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE) @@ -45,65 +45,65 @@ #define IRQ_TYPE_FAST 1 #define IRQ_TYPE_PRIO 2 -#define IRQ_SPURIOUS (IRQ_MACHSPEC | 0) +#define IRQ_SPURIOUS (0) /* auto-vector interrupts */ -#define IRQ_AUTO_1 (IRQ_MACHSPEC | 1) -#define IRQ_AUTO_2 (IRQ_MACHSPEC | 2) -#define IRQ_AUTO_3 (IRQ_MACHSPEC | 3) -#define IRQ_AUTO_4 (IRQ_MACHSPEC | 4) -#define IRQ_AUTO_5 (IRQ_MACHSPEC | 5) -#define IRQ_AUTO_6 (IRQ_MACHSPEC | 6) -#define IRQ_AUTO_7 (IRQ_MACHSPEC | 7) +#define IRQ_AUTO_1 (1) +#define IRQ_AUTO_2 (2) +#define IRQ_AUTO_3 (3) +#define IRQ_AUTO_4 (4) +#define IRQ_AUTO_5 (5) +#define IRQ_AUTO_6 (6) +#define IRQ_AUTO_7 (7) /* ST-MFP interrupts */ -#define IRQ_MFP_BUSY (IRQ_MACHSPEC | 8) -#define IRQ_MFP_DCD (IRQ_MACHSPEC | 9) -#define IRQ_MFP_CTS (IRQ_MACHSPEC | 10) -#define IRQ_MFP_GPU (IRQ_MACHSPEC | 11) -#define IRQ_MFP_TIMD (IRQ_MACHSPEC | 12) -#define IRQ_MFP_TIMC (IRQ_MACHSPEC | 13) -#define IRQ_MFP_ACIA (IRQ_MACHSPEC | 14) -#define IRQ_MFP_FDC (IRQ_MACHSPEC | 15) +#define IRQ_MFP_BUSY (8) +#define IRQ_MFP_DCD (9) +#define IRQ_MFP_CTS (10) +#define IRQ_MFP_GPU (11) +#define IRQ_MFP_TIMD (12) +#define IRQ_MFP_TIMC (13) +#define IRQ_MFP_ACIA (14) +#define IRQ_MFP_FDC (15) #define IRQ_MFP_ACSI IRQ_MFP_FDC #define IRQ_MFP_FSCSI IRQ_MFP_FDC #define IRQ_MFP_IDE IRQ_MFP_FDC -#define IRQ_MFP_TIMB (IRQ_MACHSPEC | 16) -#define IRQ_MFP_SERERR (IRQ_MACHSPEC | 17) -#define IRQ_MFP_SEREMPT (IRQ_MACHSPEC | 18) -#define IRQ_MFP_RECERR (IRQ_MACHSPEC | 19) -#define IRQ_MFP_RECFULL (IRQ_MACHSPEC | 20) -#define IRQ_MFP_TIMA (IRQ_MACHSPEC | 21) -#define IRQ_MFP_RI (IRQ_MACHSPEC | 22) -#define IRQ_MFP_MMD (IRQ_MACHSPEC | 23) +#define IRQ_MFP_TIMB (16) +#define IRQ_MFP_SERERR (17) +#define IRQ_MFP_SEREMPT (18) +#define IRQ_MFP_RECERR (19) +#define IRQ_MFP_RECFULL (20) +#define IRQ_MFP_TIMA (21) +#define IRQ_MFP_RI (22) +#define IRQ_MFP_MMD (23) /* TT-MFP interrupts */ -#define IRQ_TT_MFP_IO0 (IRQ_MACHSPEC | 24) -#define IRQ_TT_MFP_IO1 (IRQ_MACHSPEC | 25) -#define IRQ_TT_MFP_SCC (IRQ_MACHSPEC | 26) -#define IRQ_TT_MFP_RI (IRQ_MACHSPEC | 27) -#define IRQ_TT_MFP_TIMD (IRQ_MACHSPEC | 28) -#define IRQ_TT_MFP_TIMC (IRQ_MACHSPEC | 29) -#define IRQ_TT_MFP_DRVRDY (IRQ_MACHSPEC | 30) -#define IRQ_TT_MFP_SCSIDMA (IRQ_MACHSPEC | 31) -#define IRQ_TT_MFP_TIMB (IRQ_MACHSPEC | 32) -#define IRQ_TT_MFP_SERERR (IRQ_MACHSPEC | 33) -#define IRQ_TT_MFP_SEREMPT (IRQ_MACHSPEC | 34) -#define IRQ_TT_MFP_RECERR (IRQ_MACHSPEC | 35) -#define IRQ_TT_MFP_RECFULL (IRQ_MACHSPEC | 36) -#define IRQ_TT_MFP_TIMA (IRQ_MACHSPEC | 37) -#define IRQ_TT_MFP_RTC (IRQ_MACHSPEC | 38) -#define IRQ_TT_MFP_SCSI (IRQ_MACHSPEC | 39) +#define IRQ_TT_MFP_IO0 (24) +#define IRQ_TT_MFP_IO1 (25) +#define IRQ_TT_MFP_SCC (26) +#define IRQ_TT_MFP_RI (27) +#define IRQ_TT_MFP_TIMD (28) +#define IRQ_TT_MFP_TIMC (29) +#define IRQ_TT_MFP_DRVRDY (30) +#define IRQ_TT_MFP_SCSIDMA (31) +#define IRQ_TT_MFP_TIMB (32) +#define IRQ_TT_MFP_SERERR (33) +#define IRQ_TT_MFP_SEREMPT (34) +#define IRQ_TT_MFP_RECERR (35) +#define IRQ_TT_MFP_RECFULL (36) +#define IRQ_TT_MFP_TIMA (37) +#define IRQ_TT_MFP_RTC (38) +#define IRQ_TT_MFP_SCSI (39) /* SCC interrupts */ -#define IRQ_SCCB_TX (IRQ_MACHSPEC | 40) -#define IRQ_SCCB_STAT (IRQ_MACHSPEC | 42) -#define IRQ_SCCB_RX (IRQ_MACHSPEC | 44) -#define IRQ_SCCB_SPCOND (IRQ_MACHSPEC | 46) -#define IRQ_SCCA_TX (IRQ_MACHSPEC | 48) -#define IRQ_SCCA_STAT (IRQ_MACHSPEC | 50) -#define IRQ_SCCA_RX (IRQ_MACHSPEC | 52) -#define IRQ_SCCA_SPCOND (IRQ_MACHSPEC | 54) +#define IRQ_SCCB_TX (40) +#define IRQ_SCCB_STAT (42) +#define IRQ_SCCB_RX (44) +#define IRQ_SCCB_SPCOND (46) +#define IRQ_SCCA_TX (48) +#define IRQ_SCCA_STAT (50) +#define IRQ_SCCA_RX (52) +#define IRQ_SCCA_SPCOND (54) #define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ @@ -164,7 +164,6 @@ static inline void atari_enable_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; set_mfp_bit( irq, MFP_MASK ); } @@ -172,7 +171,6 @@ static inline void atari_disable_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; clear_mfp_bit( irq, MFP_MASK ); } @@ -185,7 +183,6 @@ extern inline void atari_turnon_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; set_mfp_bit( irq, MFP_ENABLE ); } @@ -193,7 +190,6 @@ extern inline void atari_turnoff_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; clear_mfp_bit( irq, MFP_ENABLE ); clear_mfp_bit( irq, MFP_PENDING ); @@ -202,7 +198,6 @@ extern inline void atari_clear_pending_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; clear_mfp_bit( irq, MFP_PENDING ); } @@ -210,7 +205,6 @@ extern inline int atari_irq_pending( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 ); return( get_mfp_bit( irq, MFP_PENDING ) ); } diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/atomic.h linux/include/asm-m68k/atomic.h --- v2.1.35/linux/include/asm-m68k/atomic.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-m68k/atomic.h Thu Apr 17 13:20:48 1997 @@ -14,7 +14,7 @@ #define ATOMIC_INIT { 0 } #define atomic_read(v) ((v)->counter) -#define atomic_set(v) (((v)->counter) = i) +#define atomic_set(v, i) (((v)->counter) = i) static __inline__ void atomic_add(int i, atomic_t *v) { @@ -26,21 +26,27 @@ __asm__ __volatile__("subl %1,%0" : : "m" (*v), "id" (i)); } -static __inline__ void atomic_inc(atomic_t *v) +static __inline__ void atomic_inc(volatile atomic_t *v) { __asm__ __volatile__("addql #1,%0" : : "m" (*v)); } -static __inline__ void atomic_dec(atomic_t *v) +static __inline__ void atomic_dec(volatile atomic_t *v) { __asm__ __volatile__("subql #1,%0" : : "m" (*v)); } -static __inline__ int atomic_dec_and_test(atomic_t *v) +static __inline__ int atomic_dec_and_test(volatile atomic_t *v) { char c; __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c) : "m" (*v)); return c != 0; } + +#define atomic_clear_mask(mask, v) \ + __asm__ __volatile__("andl %1,%0" : : "m" (*v), "id" (~(mask))) + +#define atomic_set_mask(mask, v) \ + __asm__ __volatile__("orl %1,%0" : : "m" (*v), "id" (mask)); #endif /* __ARCH_M68K_ATOMIC __ */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/bootinfo.h linux/include/asm-m68k/bootinfo.h --- v2.1.35/linux/include/asm-m68k/bootinfo.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/bootinfo.h Thu Apr 17 13:20:48 1997 @@ -141,8 +141,7 @@ #define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) #define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) -#include -#include +#include #define COMPAT_NUM_AUTO 16 diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/byteorder.h linux/include/asm-m68k/byteorder.h --- v2.1.35/linux/include/asm-m68k/byteorder.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/byteorder.h Thu Apr 17 13:20:48 1997 @@ -10,7 +10,6 @@ #endif #ifdef __KERNEL__ -#include #include /* diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/cache.h linux/include/asm-m68k/cache.h --- v2.1.35/linux/include/asm-m68k/cache.h Sun Jan 26 02:07:46 1997 +++ linux/include/asm-m68k/cache.h Thu Apr 17 13:20:48 1997 @@ -5,7 +5,7 @@ #define __ARCH_M68K_CACHE_H /* bytes per L1 cache line */ -#define L1_CACHE_BYTES 32 /* a guess */ +#define L1_CACHE_BYTES 16 #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/checksum.h linux/include/asm-m68k/checksum.h --- v2.1.35/linux/include/asm-m68k/checksum.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/checksum.h Thu Apr 17 13:20:48 1997 @@ -35,6 +35,9 @@ unsigned int csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum); +extern unsigned int +csum_partial_copy_from_user ( const char *src, char *dst, + int len, int sum, int *csum_err); /* * This is a version of ip_compute_csum() optimized for IP headers, diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/dsp56k.h linux/include/asm-m68k/dsp56k.h --- v2.1.35/linux/include/asm-m68k/dsp56k.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/dsp56k.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,70 @@ +/* + * linux/include/asm-m68k/dsp56k.h - defines and declarations for + * DSP56k device driver + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +/* Used for uploading DSP binary code */ +struct dsp56k_upload { + int len; + char *bin; +}; + +/* For the DSP host flags */ +struct dsp56k_host_flags { + int dir; /* Bit field. 1 = write output bit, 0 = do nothing. + * 0x0000 means reading only, 0x0011 means + * writing the bits stored in `out' on HF0 and HF1. + * Note that HF2 and HF3 can only be read. + */ + int out; /* Bit field like above. */ + int status; /* Host register's current state is returned */ +}; + +/* ioctl command codes */ +#define DSP56K_UPLOAD 1 /* Upload DSP binary program */ +#define DSP56K_SET_TX_WSIZE 2 /* Host transmit word size (1-4) */ +#define DSP56K_SET_RX_WSIZE 3 /* Host receive word size (1-4) */ +#define DSP56K_HOST_FLAGS 4 /* Host flag registers */ +#define DSP56K_HOST_CMD 5 /* Trig Host Command (0-31) */ +/* + * linux/include/asm-m68k/dsp56k.h - defines and declarations for + * DSP56k device driver + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +/* Used for uploading DSP binary code */ +struct dsp56k_upload { + int len; + char *bin; +}; + +/* For the DSP host flags */ +struct dsp56k_host_flags { + int dir; /* Bit field. 1 = write output bit, 0 = do nothing. + * 0x0000 means reading only, 0x0011 means + * writing the bits stored in `out' on HF0 and HF1. + * Note that HF2 and HF3 can only be read. + */ + int out; /* Bit field like above. */ + int status; /* Host register's current state is returned */ +}; + +/* ioctl command codes */ +#define DSP56K_UPLOAD 1 /* Upload DSP binary program */ +#define DSP56K_SET_TX_WSIZE 2 /* Host transmit word size (1-4) */ +#define DSP56K_SET_RX_WSIZE 3 /* Host receive word size (1-4) */ +#define DSP56K_HOST_FLAGS 4 /* Host flag registers */ +#define DSP56K_HOST_CMD 5 /* Trig Host Command (0-31) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/fpu.h linux/include/asm-m68k/fpu.h --- v2.1.35/linux/include/asm-m68k/fpu.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/fpu.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,40 @@ +#ifndef __M68K_FPU_H +#define __M68K_FPU_H + +#include + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ + +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) +#define FPSTATESIZE (216/sizeof(unsigned char)) +#elif defined(CONFIG_M68040) +#define FPSTATESIZE (96/sizeof(unsigned char)) +#elif defined(CONFIG_M68060) +#define FPSTATESIZE (12/sizeof(unsigned char)) +#else +#define FPSTATESIZE error no_cpu_type_configured +#endif + +#endif /* __M68K_FPU_H */ +#ifndef __M68K_FPU_H +#define __M68K_FPU_H + +#include + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ + +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) +#define FPSTATESIZE (216/sizeof(unsigned char)) +#elif defined(CONFIG_M68040) +#define FPSTATESIZE (96/sizeof(unsigned char)) +#elif defined(CONFIG_M68060) +#define FPSTATESIZE (12/sizeof(unsigned char)) +#else +#define FPSTATESIZE error no_cpu_type_configured +#endif + +#endif /* __M68K_FPU_H */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/hardirq.h linux/include/asm-m68k/hardirq.h --- v2.1.35/linux/include/asm-m68k/hardirq.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/hardirq.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,26 @@ +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +extern unsigned int local_irq_count[NR_CPUS]; +#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) + +#define hardirq_trylock(cpu) ((cpu)==0) /* always true */ +#define hardirq_endlock(cpu) do { } while (0) + +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) + +#endif +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +extern unsigned int local_irq_count[NR_CPUS]; +#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) + +#define hardirq_trylock(cpu) ((cpu)==0) /* always true */ +#define hardirq_endlock(cpu) do { } while (0) + +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) + +#endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/ide.h linux/include/asm-m68k/ide.h --- v2.1.35/linux/include/asm-m68k/ide.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-m68k/ide.h Thu Apr 17 13:20:49 1997 @@ -40,6 +40,7 @@ #endif /* CONFIG_AMIGA */ #ifdef CONFIG_ATARI +#include /* intr_count */ #include #include #include diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/ioctl.h linux/include/asm-m68k/ioctl.h --- v2.1.35/linux/include/asm-m68k/ioctl.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/ioctl.h Thu Apr 17 13:20:49 1997 @@ -1,4 +1,4 @@ -/* $Id: ioctl.h,v 1.1 1996/08/24 12:43:44 root Exp $ +/* $Id: ioctl.h,v 1.3 1997/04/16 15:10:07 jes Exp $ * * linux/ioctl.h for Linux by H.H. Bergman. */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/irq.h linux/include/asm-m68k/irq.h --- v2.1.35/linux/include/asm-m68k/irq.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/irq.h Thu Apr 17 13:20:49 1997 @@ -1,9 +1,6 @@ #ifndef _M68K_IRQ_H_ #define _M68K_IRQ_H_ -extern void disable_irq(unsigned int); -extern void enable_irq(unsigned int); - #include /* @@ -54,10 +51,24 @@ * Adding an interrupt service routine for a source with this bit * set indicates a special machine specific interrupt source. * The machine specific files define these sources. + * + * The IRQ_MACHSPEC bit is now gone - the only thing it did was to + * introduce unnecessary overhead. + * + * All interrupt handling is actually machine specific so it is better + * to use function pointers, as used by the Sparc port, and select the + * interrupt handling functions when initializing the kernel. This way + * we save some unnecessary overhead at run-time. + * 01/11/97 - Jes */ -#define IRQ_MACHSPEC (0x10000000L) -#define IRQ_IDX(irq) ((irq) & ~IRQ_MACHSPEC) +extern void (*enable_irq)(unsigned int); +extern void (*disable_irq)(unsigned int); + +extern int sys_request_irq(unsigned int, + void (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *); +extern void sys_free_irq(unsigned int, void *); /* * various flags for request_irq() diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/machdep.h linux/include/asm-m68k/machdep.h --- v2.1.35/linux/include/asm-m68k/machdep.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/machdep.h Thu Apr 17 13:20:49 1997 @@ -18,9 +18,7 @@ extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); -extern int (*mach_free_irq) (unsigned int irq, void *dev_id); -extern void (*mach_enable_irq) (unsigned int irq); -extern void (*mach_disable_irq) (unsigned int irq); +extern void (*mach_free_irq) (unsigned int irq, void *dev_id); extern void (*mach_get_model) (char *model); extern int (*mach_get_hardware_list) (char *buffer); extern int (*mach_get_irq_list) (char *buf); @@ -31,18 +29,14 @@ int *min, int *sec); extern int (*mach_hwclk)(int, struct hwclk_time*); extern int (*mach_set_clock_mmss)(unsigned long); -extern void (*mach_mksound)( unsigned int count, unsigned int ticks ); extern void (*mach_reset)( void ); extern int (*mach_floppy_init) (void); extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); extern void (*mach_hd_setup)(char *, int *); -extern void (*waitbut)(void); extern struct fb_info *(*mach_fb_init)(long *); extern long mach_max_dma_address; -extern void (*mach_debug_init)(void); extern void (*mach_video_setup)(char *, int *); extern void (*mach_floppy_setup)(char *, int *); extern void (*mach_floppy_eject)(void); -extern void (*mach_syms_export)(void); #endif /* _M68K_MACHDEP_H */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/namei.h linux/include/asm-m68k/namei.h --- v2.1.35/linux/include/asm-m68k/namei.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/namei.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,42 @@ +/* + * linux/include/asm-m68k/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __M68K_NAMEI_H +#define __M68K_NAMEI_H + +/* These dummy routines maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define translate_namei(pathname, base, follow_links, res_inode) \ + do { } while (0) + +#define translate_open_namei(pathname, flag, mode, res_inode, base) \ + do { } while (0) + +#endif +/* + * linux/include/asm-m68k/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __M68K_NAMEI_H +#define __M68K_NAMEI_H + +/* These dummy routines maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define translate_namei(pathname, base, follow_links, res_inode) \ + do { } while (0) + +#define translate_open_namei(pathname, flag, mode, res_inode, base) \ + do { } while (0) + +#endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/page.h linux/include/asm-m68k/page.h --- v2.1.35/linux/include/asm-m68k/page.h Fri Nov 22 05:56:36 1996 +++ linux/include/asm-m68k/page.h Thu Apr 17 13:20:50 1997 @@ -8,10 +8,58 @@ #ifdef __KERNEL__ +#include + #define STRICT_MM_TYPECHECKS +/* + * We don't need to check for alignment etc. + */ +#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060) +static inline void copy_page(unsigned long to, unsigned long from) +{ + unsigned long tmp; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %1@+,%0@+\n\t" + "move16 %1@+,%0@+\n\t" + ".chip 68k\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1) + ); +} + +static inline void clear_page(unsigned long page) +{ + unsigned long data, sp, tmp; + + sp = page; + + data = 0; + + *((unsigned long *)(page))++ = 0; + *((unsigned long *)(page))++ = 0; + *((unsigned long *)(page))++ = 0; + *((unsigned long *)(page))++ = 0; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %2@+,%0@+\n\t" + ".chip 68k\n\t" + "subqw #8,%2\n\t" + "subqw #8,%2\n\t" + "dbra %1,1b\n\t" + : "=a" (page), "=d" (tmp) + : "a" (sp), "0" (page), + "1" ((PAGE_SIZE - 16) / 16 - 1)); +} + +#else #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) +#endif #ifdef STRICT_MM_TYPECHECKS /* diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/pgtable.h linux/include/asm-m68k/pgtable.h --- v2.1.35/linux/include/asm-m68k/pgtable.h Fri Dec 20 01:20:03 1996 +++ linux/include/asm-m68k/pgtable.h Thu Apr 17 13:20:50 1997 @@ -10,6 +10,170 @@ * the m68k page table tree. */ +/* For virtual address to physical address conversion */ +extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); +extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); +#define VTOP(addr) (mm_vtop((unsigned long)(addr))) +#define PTOV(addr) (mm_ptov((unsigned long)(addr))) + +/* + * Cache handling functions + */ + +#define flush_icache() \ +do { \ + if (CPU_IS_040_OR_060) \ + asm __volatile__ ("nop\n\t" \ + ".chip 68040\n\t" \ + "cinva %%ic\n\t" \ + ".chip 68k"); \ + else { \ + unsigned long _tmp; \ + asm __volatile__ ("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "id" (FLUSH_I)); \ + } \ +} while (0) + +/* + * invalidate the cache for the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_clear (unsigned long paddr, int len); +/* + * push any dirty cache in the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_push (unsigned long paddr, int len); + +/* + * push and invalidate pages in the specified user virtual + * memory range. + */ +extern void cache_push_v (unsigned long vaddr, int len); + +/* cache code */ +#define FLUSH_I_AND_D (0x00000808) +#define FLUSH_I (0x00000008) + +/* This is needed whenever the virtual mapping of the current + process changes. */ +#define __flush_cache_all() \ + do { \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__ ("nop\n\t" \ + ".chip 68040\n\t" \ + "cpusha %dc\n\t" \ + ".chip 68k"); \ + else { \ + unsigned long _tmp; \ + __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ + } while (0) + +#define __flush_cache_030() \ + do { \ + if (CPU_IS_020_OR_030) { \ + unsigned long _tmp; \ + __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ + } while (0) + +#define flush_cache_all() __flush_cache_all() + +extern inline void flush_cache_mm(struct mm_struct *mm) +{ +#if FLUSH_VIRTUAL_CACHE_040 + if (mm == current->mm) __flush_cache_all(); +#else + if (mm == current->mm) __flush_cache_030(); +#endif +} + +extern inline void flush_cache_range(struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + if (mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(start, end-start); + else +#endif + __flush_cache_030(); + } +} + +extern inline void flush_cache_page(struct vm_area_struct *vma, + unsigned long vmaddr) +{ + if (vma->vm_mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(vmaddr, PAGE_SIZE); + else +#endif + __flush_cache_030(); + } +} + +/* Push the page at kernel virtual address and clear the icache */ +extern inline void flush_page_to_ram (unsigned long address) +{ + if (CPU_IS_040_OR_060) { + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushp %%dc,(%0)\n\t" + "cinvp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (VTOP(address))); + } + else { + unsigned long _tmp; + __asm volatile ("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (_tmp) + : "di" (FLUSH_I)); + } +} + +/* Push n pages at kernel virtual address and clear the icache */ +extern inline void flush_pages_to_ram (unsigned long address, int n) +{ + if (CPU_IS_040_OR_060) { + while (n--) { + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushp %%dc,(%0)\n\t" + "cinvp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (VTOP(address))); + address += PAGE_SIZE; + } + } + else { + unsigned long _tmp; + __asm volatile ("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (_tmp) + : "di" (FLUSH_I)); + } +} + /* * flush all atc entries (user-space entries only for the 680[46]0). */ @@ -31,7 +195,7 @@ ".chip 68k" : : "a" (addr)); } else - __asm__ __volatile__("pflush #0,#0,(%0)" : : "a" (addr)); + __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); } #define flush_tlb() __flush_tlb() @@ -69,17 +233,27 @@ __flush_tlb(); } +extern inline void flush_tlb_kernel_page(unsigned long addr) +{ + if (CPU_IS_040_OR_060) { + unsigned long old_fs = get_fs(); + set_fs(KERNEL_DS); + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); + set_fs(old_fs); + } else + __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); +} + /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available. */ #define set_pte(pteptr, pteval) \ do{ \ - *(pteptr) = (pteval); \ - if (CPU_IS_060) \ - __asm__ __volatile__(".chip 68060\n\t" \ - "pflusha\n\t" \ - ".chip 68k"); \ + *(pteptr) = (pteval); \ } while(0) @@ -160,9 +334,9 @@ * and initialized in head.S */ extern int m68k_pgtable_cachemode; -#if defined(CONFIG_M68040_OR_M68060_ONLY) +#if defined(CPU_M68040_OR_M68060_ONLY) #define mm_cachebits _PAGE_CACHE040 -#elif defined(CONFIG_M68020_OR_M68030_ONLY) +#elif defined(CPU_M68020_OR_M68030_ONLY) #define mm_cachebits 0 #else extern unsigned long mm_cachebits; @@ -234,12 +408,6 @@ #define PAGE_PTR(address) \ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) -/* For virtual address to physical address conversion */ -extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); -extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); -#define VTOP(addr) (mm_vtop((unsigned long)(addr))) -#define PTOV(addr) (mm_ptov((unsigned long)(addr))) - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. @@ -393,19 +561,17 @@ * if any. */ -extern inline void nocache_page (unsigned long vaddr) +/* Prior to calling these routines, the page should have been flushed + * from both the cache and ATC, or the CPU might not notice that the + * cache setting for the page has been changed. -jskov + */ +static inline void nocache_page (unsigned long vaddr) { if (CPU_IS_040_OR_060) { pgd_t *dir; pmd_t *pmdp; pte_t *ptep; - if(CPU_IS_060) - __asm__ __volatile__ (".chip 68060\n\t" - "cpushp (%0)\n\t" - ".chip 68k" - : : "a" (VTOP(vaddr))); - dir = pgd_offset_k(vaddr); pmdp = pmd_offset(dir,vaddr); ptep = pte_offset(pmdp,vaddr); @@ -447,6 +613,8 @@ if (pmd_none(*pmd)) { if (page) { memset((void *) page, 0, PAGE_SIZE); + flush_page_to_ram((unsigned long)page); + flush_tlb_kernel_page((unsigned long)page); nocache_page((unsigned long)page); pmd_set(pmd,page); return page + address; @@ -510,6 +678,7 @@ pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { + flush_tlb_kernel_page((unsigned long)page); nocache_page((unsigned long)page); pmd_set(pmd, page); return page + address; @@ -563,160 +732,6 @@ extern inline pgd_t * pgd_alloc(void) { return (pgd_t *)get_pointer_table (); -} - -#define flush_icache() \ -do { \ - if (CPU_IS_040_OR_060) \ - asm __volatile__ ("nop\n\t" \ - ".chip 68040\n\t" \ - "cinva %%ic\n\t" \ - ".chip 68k"); \ - else { \ - unsigned long _tmp; \ - asm __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "id" (FLUSH_I)); \ - } \ -} while (0) - -/* - * invalidate the cache for the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_clear (unsigned long paddr, int len); -/* - * push any dirty cache in the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_push (unsigned long paddr, int len); - -/* - * push and invalidate pages in the specified user virtual - * memory range. - */ -extern void cache_push_v (unsigned long vaddr, int len); - -/* cache code */ -#define FLUSH_I_AND_D (0x00000808) -#define FLUSH_I (0x00000008) - -/* This is needed whenever the virtual mapping of the current - process changes. */ -#define __flush_cache_all() \ - do { \ - if (CPU_IS_040_OR_060) \ - __asm__ __volatile__ ("nop\n\t" \ - ".chip 68040\n\t" \ - "cpusha %dc\n\t" \ - ".chip 68k"); \ - else { \ - unsigned long _tmp; \ - __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ - } while (0) - -#define __flush_cache_030() \ - do { \ - if (CPU_IS_020_OR_030) { \ - unsigned long _tmp; \ - __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ - } while (0) - -#define flush_cache_all() __flush_cache_all() - -extern inline void flush_cache_mm(struct mm_struct *mm) -{ -#if FLUSH_VIRTUAL_CACHE_040 - if (mm == current->mm) __flush_cache_all(); -#else - if (mm == current->mm) __flush_cache_030(); -#endif -} - -extern inline void flush_cache_range(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm == current->mm){ -#if FLUSH_VIRTUAL_CACHE_040 - if (CPU_IS_040_OR_060) - cache_push_v(start, end-start); - else -#endif - __flush_cache_030(); - } -} - -extern inline void flush_cache_page(struct vm_area_struct *vma, - unsigned long vmaddr) -{ - if (vma->vm_mm == current->mm){ -#if FLUSH_VIRTUAL_CACHE_040 - if (CPU_IS_040_OR_060) - cache_push_v(vmaddr, PAGE_SIZE); - else -#endif - __flush_cache_030(); - } -} - -/* Push the page at kernel virtual address and clear the icache */ -extern inline void flush_page_to_ram (unsigned long address) -{ - if (CPU_IS_040_OR_060) { - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%dc,(%0)\n\t" - "cinvp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (VTOP(address))); - } - else { - unsigned long _tmp; - __asm volatile ("movec %%cacr,%0\n\t" - "orw %1,%0\n\t" - "movec %0,%%cacr" - : "=&d" (_tmp) - : "di" (FLUSH_I)); - } -} - -/* Push n pages at kernel virtual address and clear the icache */ -extern inline void flush_pages_to_ram (unsigned long address, int n) -{ - if (CPU_IS_040_OR_060) { - while (n--) { - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%dc,(%0)\n\t" - "cinvp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (VTOP(address))); - address += PAGE_SIZE; - } - } - else { - unsigned long _tmp; - __asm volatile ("movec %%cacr,%0\n\t" - "orw %1,%0\n\t" - "movec %0,%%cacr" - : "=&d" (_tmp) - : "di" (FLUSH_I)); - } } /* diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/poll.h linux/include/asm-m68k/poll.h --- v2.1.35/linux/include/asm-m68k/poll.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/poll.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,42 @@ +#ifndef __m68k_POLL_H +#define __m68k_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif +#ifndef __m68k_POLL_H +#define __m68k_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h --- v2.1.35/linux/include/asm-m68k/processor.h Sun Jan 26 02:07:46 1997 +++ linux/include/asm-m68k/processor.h Thu Apr 17 13:20:50 1997 @@ -8,6 +8,7 @@ #define __ASM_M68K_PROCESSOR_H #include +#include /* * User space process size: 3.75GB. This is hardcoded into a few places, @@ -18,16 +19,13 @@ /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) +#define TASK_UNMAPPED_BASE 0xC0000000UL /* * Bus types */ #define EISA_bus 0 #define MCA_bus 0 - -/* MAX floating point unit state size (FSAVE/FRESTORE) */ -#define FPSTATESIZE (216/sizeof(unsigned char)) /* * if you change this structure, you must change the code and offsets diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/scatterlist.h linux/include/asm-m68k/scatterlist.h --- v2.1.35/linux/include/asm-m68k/scatterlist.h Mon Dec 30 03:01:10 1996 +++ linux/include/asm-m68k/scatterlist.h Thu Apr 17 13:20:50 1997 @@ -6,12 +6,9 @@ char * alt_address; /* Location of actual if address is a * dma indirect buffer. NULL otherwise */ unsigned int length; - -#ifdef __sparc__ - char * dvma_address; /* A place to hang host-specific addresses at. */ -#endif }; +/* This is bogus and should go away. */ #define ISA_DMA_THRESHOLD (0x00ffffff) #endif /* !(_M68K_SCATTERLIST_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/semaphore.h linux/include/asm-m68k/semaphore.h --- v2.1.35/linux/include/asm-m68k/semaphore.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-m68k/semaphore.h Thu Apr 17 13:20:50 1997 @@ -2,6 +2,8 @@ #define _M68K_SEMAPHORE_H #include +#include +#include /* * SMP- and interrupt-safe semaphores.. @@ -12,21 +14,27 @@ */ struct semaphore { - int count; - int waiting; + atomic_t count; + atomic_t waking; struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { 1, 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) +#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage int __down_failed_interruptible(void /* params in registers */); asmlinkage void __up_wakeup(void /* special register calling convention */); extern void __down(struct semaphore * sem); extern void __up(struct semaphore * sem); -#define sema_init(sem, val) ((sem)->count = val) +#define sema_init(sem, val) atomic_set(&((sem)->count), val) + +static inline void wake_one_more(struct semaphore * sem) +{ + atomic_inc(&sem->waking); +} static inline int waking_non_zero(struct semaphore *sem) { @@ -54,12 +62,34 @@ __asm__ __volatile__( "| atomic down operation\n\t" "lea %%pc@(1f),%%a0\n\t" - "subql #1,%0\n\t" + "subql #1,%0@\n\t" "jmi " SYMBOL_NAME_STR(__down_failed) "\n" "1:" : /* no outputs */ - : "m" (sem->count), "a" (sem1) + : "a" (sem1) : "%a0", "memory"); +} + +/* + * This version waits in interruptible state so that the waiting + * process can be killed. The down_failed_interruptible routine + * returns negative for signalled and zero for semaphore acquired. + */ +extern inline int down_interruptible(struct semaphore * sem) +{ + register int ret __asm__ ("%d0"); + register struct semaphore *sem1 __asm__ ("%a1") = sem; + __asm__ __volatile__( + "| atomic interruptible down operation\n\t" + "lea %%pc@(1f),%%a0\n\t" + "subql #1,%1@\n\t" + "jmi " SYMBOL_NAME_STR(__down_failed_interruptible) "\n\t" + "clrl %0\n" + "1:" + : "=d" (ret) + : "a" (sem1) + : "%d0", "%a0", "memory"); + return ret; } /* diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/serial.h linux/include/asm-m68k/serial.h --- v2.1.35/linux/include/asm-m68k/serial.h Fri Dec 20 01:20:03 1996 +++ linux/include/asm-m68k/serial.h Thu Apr 17 13:20:50 1997 @@ -171,7 +171,10 @@ */ struct serial_icounter_struct { int cts, dsr, rng, dcd; - int reserved[16]; + int rx, tx; + int frame, overrun, parity, brk; + int buf_overrun; + int reserved[9]; }; @@ -192,7 +195,9 @@ * Counters of the input lines (CTS, DSR, RI, CD) interrupts */ struct async_icount { - __u32 cts, dsr, rng, dcd; + __u32 cts, dsr, rng, dcd, tx, rx; + __u32 frame, parity, overrun, brk; + __u32 buf_overrun; }; struct async_struct { @@ -281,7 +286,7 @@ static __inline__ void rs_sched_event(struct async_struct *info, int event) { info->event |= 1 << event; - queue_task_irq(&info->tqueue, &tq_serial); + queue_task(&info->tqueue, &tq_serial); mark_bh(SERIAL_BH); } @@ -299,7 +304,8 @@ } *tty->flip.flag_buf_ptr++ = err; *tty->flip.char_buf_ptr++ = ch; - queue_task_irq(&tty->flip.tqueue, &tq_timer); + info->icount.rx++; + queue_task(&tty->flip.tqueue, &tq_timer); } static __inline__ int rs_get_tx_char( struct async_struct *info ) @@ -308,6 +314,7 @@ if (info->x_char) { ch = info->x_char; + info->icount.tx++; info->x_char = 0; return( ch ); } @@ -317,6 +324,7 @@ ch = info->xmit_buf[info->xmit_tail++]; info->xmit_tail &= SERIAL_XMIT_SIZE - 1; + info->icount.tx++; if (--info->xmit_cnt < WAKEUP_CHARS) rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); return( ch ); @@ -348,8 +356,7 @@ #ifdef SERIAL_DEBUG_OPEN printk("scheduling hangup..."); #endif - queue_task_irq(&info->tqueue_hangup, - &tq_scheduler); + queue_task(&info->tqueue_hangup, &tq_scheduler); } } } diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/setup.h linux/include/asm-m68k/setup.h --- v2.1.35/linux/include/asm-m68k/setup.h Fri Dec 20 01:20:03 1996 +++ linux/include/asm-m68k/setup.h Thu Apr 17 13:20:50 1997 @@ -48,7 +48,7 @@ #elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) # define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) #else -# define CONFIG_AMIGA_ONLY +# define MACH_AMIGA_ONLY # define MACH_IS_AMIGA (1) # define MACH_TYPE (MACH_AMIGA) #endif @@ -58,7 +58,7 @@ #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) # define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) #else -# define CONFIG_ATARI_ONLY +# define MACH_ATARI_ONLY # define MACH_IS_ATARI (1) # define MACH_TYPE (MACH_ATARI) #endif @@ -149,7 +149,7 @@ #elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) # define CPU_IS_020 (m68k_cputype & CPU_68020) #else -# define CONFIG_M68020_ONLY +# define CPU_M68020_ONLY # define CPU_IS_020 (1) #endif @@ -158,7 +158,7 @@ #elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) # define CPU_IS_030 (m68k_cputype & CPU_68030) #else -# define CONFIG_M68030_ONLY +# define CPU_M68030_ONLY # define CPU_IS_030 (1) #endif @@ -167,7 +167,7 @@ #elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) # define CPU_IS_040 (m68k_cputype & CPU_68040) #else -# define CONFIG_M68040_ONLY +# define CPU_M68040_ONLY # define CPU_IS_040 (1) #endif @@ -176,18 +176,18 @@ #elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) # define CPU_IS_060 (m68k_cputype & CPU_68060) #else -# define CONFIG_M68060_ONLY +# define CPU_M68060_ONLY # define CPU_IS_060 (1) #endif #if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) # define CPU_IS_020_OR_030 (0) #else -# define CONFIG_M68020_OR_M68030 +# define CPU_M68020_OR_M68030 # if defined(CONFIG_M68040) || defined(CONFIG_M68060) # define CPU_IS_020_OR_030 (!m68k_is040or060) # else -# define CONFIG_M68020_OR_M68030_ONLY +# define CPU_M68020_OR_M68030_ONLY # define CPU_IS_020_OR_030 (1) # endif #endif @@ -195,11 +195,11 @@ #if !defined(CONFIG_M68040) && !defined(CONFIG_M68060) # define CPU_IS_040_OR_060 (0) #else -# define CONFIG_M68040_OR_M68060 +# define CPU_M68040_OR_M68060 # if defined(CONFIG_M68020) || defined(CONFIG_M68030) # define CPU_IS_040_OR_060 (m68k_is040or060) # else -# define CONFIG_M68040_OR_M68060_ONLY +# define CPU_M68040_OR_M68060_ONLY # define CPU_IS_040_OR_060 (1) # endif #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/sigcontext.h linux/include/asm-m68k/sigcontext.h --- v2.1.35/linux/include/asm-m68k/sigcontext.h Fri Nov 22 05:56:36 1996 +++ linux/include/asm-m68k/sigcontext.h Thu Apr 17 13:20:50 1997 @@ -1,6 +1,8 @@ #ifndef _ASM_M68k_SIGCONTEXT_H #define _ASM_M68k_SIGCONTEXT_H +#include + struct sigcontext { unsigned long sc_mask; /* old sigmask */ unsigned long sc_usp; /* old user stack pointer */ @@ -13,7 +15,7 @@ unsigned short sc_formatvec; unsigned long sc_fpregs[2*3]; /* room for two fp registers */ unsigned long sc_fpcntl[3]; - unsigned char sc_fpstate[216]; + unsigned char sc_fpstate[FPSTATESIZE]; }; #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/smp_lock.h linux/include/asm-m68k/smp_lock.h --- v2.1.35/linux/include/asm-m68k/smp_lock.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/smp_lock.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,28 @@ +#ifndef __M68K_SMPLOCK_H +#define __M68K_SMPLOCK_H + +/* + * We don't do SMP so this is again one of these silly dummy files + * to keep the kernel source looking nice ;-(. + */ + +#define lock_kernel() do { } while(0) +#define unlock_kernel() do { } while(0) +#define release_kernel_lock(task, cpu, depth) ((depth) = 1) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) + +#endif +#ifndef __M68K_SMPLOCK_H +#define __M68K_SMPLOCK_H + +/* + * We don't do SMP so this is again one of these silly dummy files + * to keep the kernel source looking nice ;-(. + */ + +#define lock_kernel() do { } while(0) +#define unlock_kernel() do { } while(0) +#define release_kernel_lock(task, cpu, depth) ((depth) = 1) +#define reaquire_kernel_lock(task, cpu, depth) do { } while(0) + +#endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/softirq.h linux/include/asm-m68k/softirq.h --- v2.1.35/linux/include/asm-m68k/softirq.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/softirq.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,118 @@ +#ifndef __M68K_SOFTIRQ_H +#define __M68K_SOFTIRQ_H + +/* + * Software interrupts.. no SMP here either. + */ +#define get_active_bhs() (bh_mask & bh_active) +#define clear_active_bhs(x) atomic_clear_mask((x),&bh_active) + +extern inline void init_bh(int nr, void (*routine)(void)) +{ + bh_base[nr] = routine; + bh_mask_count[nr] = 0; + bh_mask |= 1 << nr; +} + +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + +extern inline void mark_bh(int nr) +{ + set_bit(nr, &bh_active); +} + +/* + * These use a mask count to correctly handle + * nested disable/enable calls + */ +extern inline void disable_bh(int nr) +{ + bh_mask &= ~(1 << nr); + bh_mask_count[nr]++; +} + +extern inline void enable_bh(int nr) +{ + if (!--bh_mask_count[nr]) + bh_mask |= 1 << nr; +} + +extern int __m68k_bh_counter; + +extern inline void start_bh_atomic(void) +{ + __m68k_bh_counter++; + barrier(); +} + +extern inline void end_bh_atomic(void) +{ + barrier(); + __m68k_bh_counter--; +} + +/* These are for the irq's testing the lock */ +#define softirq_trylock() (__m68k_bh_counter ? 0 : (__m68k_bh_counter=1)) +#define softirq_endlock() (__m68k_bh_counter = 0) + +#endif +#ifndef __M68K_SOFTIRQ_H +#define __M68K_SOFTIRQ_H + +/* + * Software interrupts.. no SMP here either. + */ +#define get_active_bhs() (bh_mask & bh_active) +#define clear_active_bhs(x) atomic_clear_mask((x),&bh_active) + +extern inline void init_bh(int nr, void (*routine)(void)) +{ + bh_base[nr] = routine; + bh_mask_count[nr] = 0; + bh_mask |= 1 << nr; +} + +extern inline void mark_bh(int nr) +{ + set_bit(nr, &bh_active); +} + +/* + * These use a mask count to correctly handle + * nested disable/enable calls + */ +extern inline void disable_bh(int nr) +{ + bh_mask &= ~(1 << nr); + bh_mask_count[nr]++; +} + +extern inline void enable_bh(int nr) +{ + if (!--bh_mask_count[nr]) + bh_mask |= 1 << nr; +} + +extern int __m68k_bh_counter; + +extern inline void start_bh_atomic(void) +{ + __m68k_bh_counter++; + barrier(); +} + +extern inline void end_bh_atomic(void) +{ + barrier(); + __m68k_bh_counter--; +} + +/* These are for the irq's testing the lock */ +#define softirq_trylock() (__m68k_bh_counter ? 0 : (__m68k_bh_counter=1)) +#define softirq_endlock() (__m68k_bh_counter = 0) + +#endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/spinlock.h linux/include/asm-m68k/spinlock.h --- v2.1.35/linux/include/asm-m68k/spinlock.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-m68k/spinlock.h Tue Apr 22 22:45:15 1997 @@ -0,0 +1,74 @@ +#ifndef __M68K_SPINLOCK_H +#define __M68K_SPINLOCK_H + +/* + * We don't do SMP on the m68k .... at least not yet. + */ + +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() + +#define spin_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define spin_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) + +#endif +#ifndef __M68K_SPINLOCK_H +#define __M68K_SPINLOCK_H + +/* + * We don't do SMP on the m68k .... at least not yet. + */ + +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() + +#define spin_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define spin_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + +#endif diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/system.h linux/include/asm-m68k/system.h --- v2.1.35/linux/include/asm-m68k/system.h Wed Sep 25 00:47:42 1996 +++ linux/include/asm-m68k/system.h Thu Apr 17 13:20:50 1997 @@ -65,21 +65,24 @@ #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC) /* block out HSYNC on the atari */ -#define sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") +#define __sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") #else /* portable version */ -#define sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") +#define __sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") #endif /* machine compilation types */ -#define cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") +#define __cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") #define nop() __asm__ __volatile__ ("nop"::) #define mb() __asm__ __volatile__ ("" : : :"memory") -#define save_flags(x) \ +#define __save_flags(x) \ __asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") -#define restore_flags(x) \ +#define __restore_flags(x) \ __asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") -#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) #ifndef CONFIG_RMW_INSNS static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/termbits.h linux/include/asm-m68k/termbits.h --- v2.1.35/linux/include/asm-m68k/termbits.h Wed May 8 00:32:41 1996 +++ linux/include/asm-m68k/termbits.h Thu Apr 17 13:20:50 1997 @@ -123,6 +123,7 @@ #define B230400 0010003 #define B460800 0010004 #define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ /* c_lflag bits */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/termios.h linux/include/asm-m68k/termios.h --- v2.1.35/linux/include/asm-m68k/termios.h Thu Mar 27 14:40:07 1997 +++ linux/include/asm-m68k/termios.h Thu Apr 17 13:20:50 1997 @@ -53,6 +53,7 @@ #define N_PPP 3 #define N_STRIP 4 #define N_AX25 5 +#define N_X25 6 /* X.25 async */ #ifdef __KERNEL__ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/uaccess.h linux/include/asm-m68k/uaccess.h --- v2.1.35/linux/include/asm-m68k/uaccess.h Fri Jan 3 08:48:37 1997 +++ linux/include/asm-m68k/uaccess.h Thu Apr 17 13:20:50 1997 @@ -714,6 +714,9 @@ __constant_copy_to_user(to, from, n) : \ __generic_copy_to_user(to, from, n)) +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) +#define __copy_to_user(to, from, n) copy_to_user(to, from, n) + /* * Copy a null terminated string from userspace. */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h --- v2.1.35/linux/include/asm-m68k/unistd.h Fri Apr 4 08:52:25 1997 +++ linux/include/asm-m68k/unistd.h Thu Apr 17 13:20:50 1997 @@ -171,7 +171,9 @@ #define __NR_mremap 163 #define __NR_setresuid 164 #define __NR_getresuid 165 -#define __NR_nfsservctl 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 /* user-visible error numbers are in the range -1 - -122: see */ @@ -179,7 +181,10 @@ #define __syscall_return(type, res) \ do { \ if ((unsigned long)(res) >= (unsigned long)(-125)) { \ - errno = -(res); \ + /* avoid using res which is declared to be in register d0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ res = -1; \ } \ return (type) (res); \ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/user.h linux/include/asm-m68k/user.h --- v2.1.35/linux/include/asm-m68k/user.h Fri Nov 22 05:56:36 1996 +++ linux/include/asm-m68k/user.h Thu Apr 17 13:20:50 1997 @@ -2,7 +2,7 @@ #define _M68K_USER_H #include -#include + /* Core file format: The core file is written in such a way that gdb can understand it and provide useful information to the user (under linux we use the 'trad-core' bfd). There are quite a number of @@ -74,7 +74,8 @@ esp register. */ long int signal; /* Signal that caused the core dump. */ int reserved; /* No longer used */ - struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ + struct user_regs_struct *u_ar0; + /* Used by gdb to help find the values for */ /* the registers. */ struct user_m68kfp_struct* u_fpstate; /* Math Co-processor pointer. */ unsigned long magic; /* To uniquely identify a core file */ diff -u --recursive --new-file v2.1.35/linux/include/asm-m68k/zorro.h linux/include/asm-m68k/zorro.h --- v2.1.35/linux/include/asm-m68k/zorro.h Fri Dec 20 01:20:03 1996 +++ linux/include/asm-m68k/zorro.h Wed Dec 31 16:00:00 1969 @@ -1,577 +0,0 @@ -/* - * asm-m68k/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions - * - * Copyright (C) 1995 Geert Uytterhoeven - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#ifndef _M68K_ZORRO_H -#define _M68K_ZORRO_H - -#ifndef __ASSEMBLY__ - -/* - * Defined Board Manufacturers - * - * Please update arch/m68k/amiga/zorro.c if you make changes here - * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) - * and by looking at the NetBSD-Amiga kernel sources - */ - -#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ -#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ -#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ - -#define MANUF_KUPKE (0x00DD) /* Kupke */ -#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ - -#define MANUF_MEMPHIS (0x0100) /* Memphis */ -#define PROD_STORMBRINGER (0x00) /* Stormbringer */ - -#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ -#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ -#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ -#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ -#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ - -#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ -#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ -#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ -#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ -#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ -#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ -#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ -#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ -#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ -#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ -#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ -#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ -#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ -#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ -#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ -#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ -#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ -#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ - -#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ -#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ - -#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ -#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ - -#define MANUF_CARDCO (0x03EC) /* Cardco */ -#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ -#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ -#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ -#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ - -#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ -#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ - -#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ -#define PROD_AX2000 (0x01) /* AX2000 */ - -#define MANUF_ANAKIN (0x03F1) /* Anakin */ -#define PROD_EASYL (0x01) /* Easyl Tablet */ - -#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ -#define PROD_STARBOARD_II (0x00) /* StarBoard II */ -#define PROD_STARDRIVE (0x02) /* StarDrive */ -#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ -#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ -#define PROD_VXL_RAM (0x44) /* VXL RAM */ -#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ -#define PROD_MBX_1200 (0x81) /* MBX 1200 */ -#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ -#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ - -#define MANUF_ACCESS (0x03F4) /* Access Associates */ - -#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ - -#define MANUF_ASDG (0x03FF) /* ASDG */ -#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ -#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ -#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ -#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ - -#define MANUF_IMTRONICS (0x0404) /* Imtronics */ -#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ -#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ - -#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ -#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ - -#define MANUF_AMERISTAR (0x041D) /* Ameristar */ -#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ -#define PROD_A560 (0x09) /* Arcnet Card */ -#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ - -#define MANUF_SUPRA (0x0420) /* Supra */ -#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ -#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ -#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ -#define PROD_SUPRA_500RX (0x09) /* 500RX/2000 RAM */ -#define PROD_SUPRA_500RX_2 (0x0A) /* 500RX/2000 RAM */ -#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ -#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ -#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ -#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ - -#define MANUF_CSA (0x0422) /* CSA */ -#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ -#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ - -#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ -#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ - -#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ -#define PROD_BYTEBOX_A500 (0x00) /* A500 */ - -#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ - -#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ -#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ -#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ - -#define MANUF_GVP (0x07E1) /* Great Valley Products */ -#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ -#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ -#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ -#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ -#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ -#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ -#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works - for this product code also */ -#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ -#define PROD_GVP (0x0B) /* This code is used by a wide range of - GVP products - use the epc to - identify it correctly */ -#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ -#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ -#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ -#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ -#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ -/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ - -#define MANUF_SYNERGY (0x07E5) /* Synergy */ - -#define MANUF_XETEC (0x07E6) /* Xetec */ -#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ -#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ - -#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ -#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ -#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ -#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ -#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ -#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ - -#define MANUF_XEBEC (0x07EC) /* Xebec */ - -#define MANUF_SPIRIT (0x07F2) /* Spirit */ -#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ -#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ - -#define MANUF_BSC (0x07FE) /* BSC */ -#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ - -#define MANUF_BSC3 (0x0801) /* BSC */ -#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ -#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ - -#define MANUF_C_LTD (0x0802) /* C Ltd. */ -#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ -#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ - -#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ -#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ - -#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ -#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ - -#define MANUF_ICD (0x0817) /* ICD */ -#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ - -#define MANUF_KUPKE2 (0x0819) /* Kupke */ -#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ -#define PROD_GOLEM_BOX (0x03) /* Golem Box */ -#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ - -#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ -#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ - -#define MANUF_BSC2 (0x082C) /* BSC */ -#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ -#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ -#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ -#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ -#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ -#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ -#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ -#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ - -#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ -#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ -#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ - -#define MANUF_IMPULSE (0x0838) /* Impulse */ -#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ - -#define MANUF_IVS (0x0840) /* IVS */ -#define PROD_GRANDSLAM (0x04) /* GrandSlam RAM */ -#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ -#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ -#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ -#define PROD_META_4 (0x40) /* Meta-4 RAM */ -#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ - -#define MANUF_VECTOR (0x0841) /* Vector */ -#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ - -#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ -#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ -#define PROD_VISIONA_REG (0x02) -#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ -#define PROD_MERLIN_REG (0x04) - -#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ -#define PROD_AMIGANET (0x01) /* Amiganet Board */ - -#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ -#define PROD_AD516 (0x02) /* AD516 Audio */ - -#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ -#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ - -#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ -#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ -#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ - -#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ -#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ -#define PROD_GDA_1_REG (0x01) - -#define MANUF_ROCTEC (0x0860) /* RocTec */ -#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ -#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ - -#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ -#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ - -#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ -#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ - -#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ -#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ -#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ -#define PROD_MVD_819 (0x07) /* MVD 819 */ - -#define MANUF_DELACOMP (0x0873) /* DelaComp */ -#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ - -#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ -#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board (RAM) */ -#define PROD_DOMINO_REG (0x02) /* Domino Graphics Board (REG) */ -#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II Graphics Board */ -#define PROD_PICASSO_II_REG (0x0C) -#define PROD_PICASSO_II_REG_2 (0x0D) -#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ - -#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ -#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ -#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ - -#define MANUF_AMITRIX (0x0880) /* Amitrix */ -#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ -#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ - -#define MANUF_MTEC (0x0890) /* MTEC Germany */ -#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ -#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ -#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ - -#define MANUF_GVP2 (0x0891) /* Great Valley Products */ -#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ -#define PROD_SPECTRUM_REG (0x02) - -#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ -#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ -#define PROD_PICCOLO_REG (0x06) -#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ -#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ -#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ -#define PROD_SD64_REG (0x0B) - -#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ -#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ - -#define MANUF_ELBOX (0x089E) /* ElBox Computer */ -#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ - -#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ -#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ -#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ - -#define MANUF_MICRONIK (0x0A50) /* Micronik */ -#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ - -#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ -#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ -#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ - -#define MANUF_KUPKE3 (0x1248) /* Kupke */ -#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ - -#define MANUF_INFORMATION (0x157C) /* Information */ -#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ - -#define MANUF_VORTEX (0x2017) /* Vortex */ -#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ -#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ -#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ - -#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ -#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ -#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ - -#define MANUF_READYSOFT (0x2100) /* ReadySoft */ -#define PROD_AMAX (0x01) /* AMax II/IV */ - -#define MANUF_PHASE5 (0x2140) /* Phase5 */ -#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ -#define PROD_BLIZZARD (0x02) /* Blizzard */ -#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ -#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ -#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ -#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ -#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ -#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ -#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ -#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ -#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ - -#define MANUF_DPS (0x2169) /* DPS */ -#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ - -#define MANUF_APOLLO2 (0x2200) /* Apollo */ -#define PROD_A620 (0x00) /* A620 68020 Accelerator */ - -#define MANUF_APOLLO (0x2222) /* Apollo */ -#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ -#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ - -#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ -#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ - -#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ -#define PROD_MAESTRO (0x03) /* Maestro */ -#define PROD_VLAB (0x04) /* VLab */ -#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ -#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ -#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ -#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ -#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ -#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ -#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ - -#define MANUF_COMBITEC (0x6766) /* Combitec */ - -#define MANUF_SKI (0x8000) /* SKI Peripherals */ -#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ - -#define MANUF_CAMERON (0xAA01) /* Cameron */ -#define PROD_CAMERON_SCANNER (0x10) /* Scanner Interface */ - -#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ -#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ - - -/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ - -#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ -#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ - -#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ -#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ - -#define MANUF_VECTOR2 (0x07DB) /* Vector */ -#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ -#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ -#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ -#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ - - -/* - * GVP's identifies most of their product through the 'extended - * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK - * before the identification. - */ - -#define GVP_PRODMASK (0xf8) -#define GVP_SCSICLKMASK (0x01) - -enum GVP_ident { - GVP_GFORCE_040 = 0x20, - GVP_GFORCE_040_SCSI = 0x30, - GVP_A1291_SCSI = 0x40, - GVP_COMBO_R4 = 0x60, - GVP_COMBO_R4_SCSI = 0x70, - GVP_PHONEPAK = 0x78, - GVP_IOEXT = 0x98, - GVP_GFORCE_030 = 0xa0, - GVP_GFORCE_030_SCSI = 0xb0, - GVP_A530 = 0xc0, - GVP_A530_SCSI = 0xd0, - GVP_COMBO_R3 = 0xe0, - GVP_COMBO_R3_SCSI = 0xf0, - GVP_SERIESII = 0xf8, -}; - -enum GVP_flags { - GVP_IO = 0x01, - GVP_ACCEL = 0x02, - GVP_SCSI = 0x04, - GVP_24BITDMA = 0x08, - GVP_25BITDMA = 0x10, - GVP_NOBANK = 0x20, - GVP_14MHZ = 0x40, -}; - - -struct Node { - struct Node *ln_Succ; /* Pointer to next (successor) */ - struct Node *ln_Pred; /* Pointer to previous (predecessor) */ - u_char ln_Type; - char ln_Pri; /* Priority, for sorting */ - char *ln_Name; /* ID string, null terminated */ -}; - -struct ExpansionRom { - /* -First 16 bytes of the expansion ROM */ - u_char er_Type; /* Board type, size and flags */ - u_char er_Product; /* Product number, assigned by manufacturer */ - u_char er_Flags; /* Flags */ - u_char er_Reserved03; /* Must be zero ($ff inverted) */ - u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ - u_long er_SerialNumber; /* Available for use by manufacturer */ - u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ - u_char er_Reserved0c; - u_char er_Reserved0d; - u_char er_Reserved0e; - u_char er_Reserved0f; -}; - -/* er_Type board type bits */ -#define ERT_TYPEMASK 0xc0 -#define ERT_ZORROII 0xc0 -#define ERT_ZORROIII 0x80 - -/* other bits defined in er_Type */ -#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ -#define ERTF_MEMLIST (1<<5) - -struct ConfigDev { - struct Node cd_Node; - u_char cd_Flags; /* (read/write) */ - u_char cd_Pad; /* reserved */ - struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ - void *cd_BoardAddr; /* where in memory the board was placed */ - u_long cd_BoardSize; /* size of board in bytes */ - u_short cd_SlotAddr; /* which slot number (PRIVATE) */ - u_short cd_SlotSize; /* number of slots (PRIVATE) */ - void *cd_Driver; /* pointer to node of driver */ - struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ - u_long cd_Unused[4]; /* for whatever the driver wants */ -}; - -#else /* __ASSEMBLY__ */ - -LN_Succ = 0 -LN_Pred = LN_Succ+4 -LN_Type = LN_Pred+4 -LN_Pri = LN_Type+1 -LN_Name = LN_Pri+1 -LN_sizeof = LN_Name+4 - -ER_Type = 0 -ER_Product = ER_Type+1 -ER_Flags = ER_Product+1 -ER_Reserved03 = ER_Flags+1 -ER_Manufacturer = ER_Reserved03+1 -ER_SerialNumber = ER_Manufacturer+2 -ER_InitDiagVec = ER_SerialNumber+4 -ER_Reserved0c = ER_InitDiagVec+2 -ER_Reserved0d = ER_Reserved0c+1 -ER_Reserved0e = ER_Reserved0d+1 -ER_Reserved0f = ER_Reserved0e+1 -ER_sizeof = ER_Reserved0f+1 - -CD_Node = 0 -CD_Flags = CD_Node+LN_sizeof -CD_Pad = CD_Flags+1 -CD_Rom = CD_Pad+1 -CD_BoardAddr = CD_Rom+ER_sizeof -CD_BoardSize = CD_BoardAddr+4 -CD_SlotAddr = CD_BoardSize+4 -CD_SlotSize = CD_SlotAddr+2 -CD_Driver = CD_SlotSize+2 -CD_NextCD = CD_Driver+4 -CD_Unused = CD_NextCD+4 -CD_sizeof = CD_Unused+(4*4) - -#endif /* __ASSEMBLY__ */ - -#ifndef __ASSEMBLY__ - -#define ZORRO_NUM_AUTO 16 - -#ifdef __KERNEL__ - -extern int zorro_num_autocon; /* # of autoconfig devices found */ -extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; - - -/* - * Zorro Functions - */ - -extern int zorro_find(int manuf, int prod, int part, int index); -extern struct ConfigDev *zorro_get_board(int key); -extern void zorro_config_board(int key, int part); -extern void zorro_unconfig_board(int key, int part); - - -/* - * Bitmask indicating portions of available Zorro II RAM that are unused - * by the system. Every bit represents a 64K chunk, for a maximum of 8MB - * (128 chunks, physical 0x00200000-0x009fffff). - * - * If you want to use (= allocate) portions of this RAM, you should clear - * the corresponding bits. - */ - -extern u_long zorro_unused_z2ram[4]; - -#define Z2RAM_START (0x00200000) -#define Z2RAM_END (0x00a00000) -#define Z2RAM_SIZE (0x00800000) -#define Z2RAM_CHUNKSIZE (0x00010000) -#define Z2RAM_CHUNKMASK (0x0000ffff) -#define Z2RAM_CHUNKSHIFT (16) - - -/* - * Verbose Board Identification - */ - -extern void zorro_identify(void); -extern int zorro_get_list(char *buffer); - -#endif /* !__ASSEMBLY__ */ -#endif /* __KERNEL__ */ - -#endif /* __ASMm68K_ZORRO_H */ diff -u --recursive --new-file v2.1.35/linux/include/asm-ppc/atomic.h linux/include/asm-ppc/atomic.h --- v2.1.35/linux/include/asm-ppc/atomic.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-ppc/atomic.h Thu Apr 17 13:20:51 1997 @@ -6,7 +6,7 @@ #define _ASM_PPC_ATOMIC_H_ typedef struct { int counter; } atomic_t; -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } /* * Make sure gcc doesn't try to be clever and move things around diff -u --recursive --new-file v2.1.35/linux/include/asm-ppc/semaphore.h linux/include/asm-ppc/semaphore.h --- v2.1.35/linux/include/asm-ppc/semaphore.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-ppc/semaphore.h Thu Apr 17 13:20:51 1997 @@ -9,8 +9,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { 1, 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern void __up(struct semaphore * sem); diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/atomic.h linux/include/asm-sparc/atomic.h --- v2.1.35/linux/include/asm-sparc/atomic.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-sparc/atomic.h Thu Apr 17 13:20:51 1997 @@ -13,7 +13,7 @@ typedef struct { int counter; } atomic_t; #endif -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i << 8) } #ifdef __KERNEL__ #include diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/errno.h linux/include/asm-sparc/errno.h --- v2.1.35/linux/include/asm-sparc/errno.h Sat Nov 9 00:29:22 1996 +++ linux/include/asm-sparc/errno.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: errno.h,v 1.5 1996/07/13 02:05:13 tridge Exp $ */ +/* $Id: errno.h,v 1.6 1997/04/15 09:03:38 davem Exp $ */ #ifndef _SPARC_ERRNO_H #define _SPARC_ERRNO_H @@ -129,5 +129,8 @@ #define EILSEQ 122 /* Illegal byte sequence */ #define ELIBMAX 123 /* Atmpt to link in too many shared libs */ #define ELIBSCN 124 /* .lib section in a.out corrupted */ + +#define ENOMEDIUM 125 /* No medium found */ +#define EMEDIUMTYPE 126 /* Wrong medium type */ #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/fbio.h linux/include/asm-sparc/fbio.h --- v2.1.35/linux/include/asm-sparc/fbio.h Sat Nov 9 00:29:23 1996 +++ linux/include/asm-sparc/fbio.h Thu Apr 17 13:20:51 1997 @@ -33,6 +33,9 @@ #define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ +/* Does not seem to be listed in the Sun file either */ +#define FBTYPE_CREATOR 22 + /* fbio ioctls */ /* Returned by FBIOGTYPE */ struct fbtype { diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/hardirq.h linux/include/asm-sparc/hardirq.h --- v2.1.35/linux/include/asm-sparc/hardirq.h Mon Apr 14 16:28:20 1997 +++ linux/include/asm-sparc/hardirq.h Tue Apr 22 22:39:21 1997 @@ -10,12 +10,11 @@ extern unsigned int local_irq_count[NR_CPUS]; #define in_interrupt() (local_irq_count[smp_processor_id()] != 0) -#define hardirq_depth() (local_irq_count[smp_processor_id()]) #ifndef __SMP__ -#define hardirq_trylock(cpu) (++local_irq_count[cpu], (cpu)==0) -#define hardirq_endlock(cpu) (--local_irq_count[cpu]) +#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) +#define hardirq_endlock(cpu) do { } while(0) #define hardirq_enter(cpu) (local_irq_count[cpu]++) #define hardirq_exit(cpu) (local_irq_count[cpu]--) diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/init.h linux/include/asm-sparc/init.h --- v2.1.35/linux/include/asm-sparc/init.h Thu Mar 27 14:40:07 1997 +++ linux/include/asm-sparc/init.h Thu Apr 17 13:20:51 1997 @@ -1,8 +1,7 @@ #ifndef _SPARC_INIT_H #define _SPARC_INIT_H -#ifndef __init -#if (defined (__svr4__) || defined (__ELF__)) && !defined (MODULE) +#if (defined (__svr4__) || defined (__ELF__)) #define __init __attribute__ ((__section__ (".text.init"))) #define __initdata __attribute__ ((__section__ (".data.init"))) #define __initfunc(__arginit) \ @@ -20,7 +19,6 @@ #define __INIT #define __FINIT #define __INITDATA -#endif #endif #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/irq.h linux/include/asm-sparc/irq.h --- v2.1.35/linux/include/asm-sparc/irq.h Mon Apr 14 16:28:20 1997 +++ linux/include/asm-sparc/irq.h Tue Apr 22 22:39:21 1997 @@ -1,4 +1,4 @@ -/* $Id: irq.h,v 1.15 1997/04/14 05:39:28 davem Exp $ +/* $Id: irq.h,v 1.17 1997/04/18 05:44:52 davem Exp $ * irq.h: IRQ registers on the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -13,6 +13,38 @@ #define NR_IRQS 15 +/* IRQ handler dispatch entry and exit. */ +#ifdef __SMP__ +extern __inline__ void irq_enter(int cpu, int irq) +{ + register int proc asm("g1"); + proc = cpu; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___irq_enter + add %%o7, 8, %%o7 +" : "=&r" (proc) + : "0" (proc) + : "g2", "g3", "g4", "g5", "memory", "cc"); +} + +extern __inline__ void irq_exit(int cpu, int irq) +{ + register int proc asm("g7"); + proc = cpu; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___irq_exit + add %%o7, 8, %%o7 +" : "=&r" (proc) + : "0" (proc) + : "g1", "g2", "g3", "g4", "g5", "memory", "cc"); +} +#else +#define irq_enter(cpu, irq) (local_irq_count[cpu]++) +#define irq_exit(cpu, irq) (local_irq_count[cpu]--) +#endif + /* Dave Redman (djhr@tadpole.co.uk) * changed these to function pointers.. it saves cycles and will allow * the irq dependencies to be split into different files at a later date @@ -22,9 +54,9 @@ extern void (*enable_irq)(unsigned int); extern void (*disable_pil_irq)(unsigned int); extern void (*enable_pil_irq)(unsigned int); -extern void (*clear_clock_irq)( void ); -extern void (*clear_profile_irq)( void ); -extern void (*load_profile_irq)( unsigned int timeout ); +extern void (*clear_clock_irq)(void); +extern void (*clear_profile_irq)(int); +extern void (*load_profile_irq)(int cpu, unsigned int timeout); extern void (*init_timers)(void (*lvl10_irq)(int, void *, struct pt_regs *)); extern void claim_ticker14(void (*irq_handler)(int, void *, struct pt_regs *), int irq, diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/linux_logo.h linux/include/asm-sparc/linux_logo.h --- v2.1.35/linux/include/asm-sparc/linux_logo.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-sparc/linux_logo.h Tue Apr 22 22:39:21 1997 @@ -0,0 +1,2090 @@ +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:24 jj Exp $ + * include/asm-sparc/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/SPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 221 + +unsigned char linux_logo_red[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5, + 0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5, + 0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03, + 0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6, + 0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2, + 0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A, + 0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4, + 0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2, + 0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC, + 0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC, + 0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7, + 0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3, + 0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4, + 0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4, + 0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87, + 0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E, + 0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_green[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3, + 0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9, + 0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02, + 0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD, + 0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6, + 0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C, + 0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4, + 0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E, + 0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC, + 0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5, + 0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96, + 0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80, + 0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F, + 0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C, + 0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54, + 0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E, + 0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_blue[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE, + 0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5, + 0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84, + 0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7, + 0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77, + 0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59, + 0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E, + 0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14, + 0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D, + 0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14, + 0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08, + 0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E, + 0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E, + 0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20, + 0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06, + 0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17, + 0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14, + 0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo[] __initdata = { + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61, + 0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E, + 0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58, + 0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C, + 0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A, + 0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52, + 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53, + 0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, + 0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49, + 0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B, + 0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, + 0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB, + 0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C, + 0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49, + 0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5, + 0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58, + 0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51, + 0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54, + 0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5, + 0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61, + 0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C, + 0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B, + 0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53, + 0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC, + 0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59, + 0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48, + 0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51, + 0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63, + 0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48, + 0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51, + 0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52, + 0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB, + 0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B, + 0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53, + 0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53, + 0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC, + 0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F, + 0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61, + 0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57, + 0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D, + 0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57, + 0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC, + 0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC, + 0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48, + 0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52, + 0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61, + 0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A, + 0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC, + 0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC, + 0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49, + 0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F, + 0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB, + 0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47, + 0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54, + 0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D, + 0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC, + 0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC, + 0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45, + 0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44, + 0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64, + 0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48, + 0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D, + 0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC, + 0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA, + 0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55, + 0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45, + 0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D, + 0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B, + 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A, + 0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC, + 0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8, + 0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD, + 0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A, + 0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56, + 0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, + 0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54, + 0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC, + 0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB, + 0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34, + 0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F, + 0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E, + 0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60, + 0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57, + 0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51, + 0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC, + 0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE, + 0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30, + 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41, + 0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65, + 0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C, + 0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A, + 0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC, + 0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C, + 0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1, + 0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32, + 0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30, + 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41, + 0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC, + 0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A, + 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, + 0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E, + 0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC, + 0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88, + 0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB, + 0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33, + 0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31, + 0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E, + 0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63, + 0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49, + 0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, + 0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55, + 0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC, + 0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C, + 0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8, + 0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F, + 0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F, + 0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48, + 0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A, + 0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A, + 0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57, + 0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53, + 0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC, + 0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88, + 0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E, + 0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47, + 0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D, + 0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58, + 0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55, + 0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC, + 0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E, + 0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9, + 0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73, + 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70, + 0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF, + 0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E, + 0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57, + 0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58, + 0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C, + 0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC, + 0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C, + 0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC, + 0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78, + 0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, + 0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1, + 0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C, + 0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D, + 0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58, + 0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E, + 0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC, + 0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8, + 0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42, + 0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73, + 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73, + 0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2, + 0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41, + 0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62, + 0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B, + 0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60, + 0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC, + 0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7, + 0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41, + 0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73, + 0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74, + 0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB, + 0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41, + 0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64, + 0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E, + 0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C, + 0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB, + 0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE, + 0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20, + 0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75, + 0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76, + 0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D, + 0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C, + 0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64, + 0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, + 0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58, + 0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC, + 0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81, + 0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23, + 0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76, + 0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76, + 0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48, + 0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40, + 0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61, + 0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C, + 0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52, + 0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB, + 0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E, + 0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8, + 0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, + 0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C, + 0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57, + 0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D, + 0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A, + 0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65, + 0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC, + 0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40, + 0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47, + 0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF, + 0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A, + 0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57, + 0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5, + 0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C, + 0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52, + 0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9, + 0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42, + 0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51, + 0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6, + 0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7, + 0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93, + 0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D, + 0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF, + 0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40, + 0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52, + 0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1, + 0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8, + 0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93, + 0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40, + 0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0, + 0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F, + 0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59, + 0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E, + 0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23, + 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7, + 0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93, + 0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F, + 0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC, + 0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47, + 0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54, + 0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D, + 0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24, + 0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24, + 0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A, + 0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5, + 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93, + 0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60, + 0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC, + 0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47, + 0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B, + 0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D, + 0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28, + 0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D, + 0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD, + 0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93, + 0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7, + 0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44, + 0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45, + 0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B, + 0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20, + 0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6, + 0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90, + 0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0, + 0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44, + 0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45, + 0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51, + 0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF, + 0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7, + 0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5, + 0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2, + 0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58, + 0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C, + 0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55, + 0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1, + 0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB, + 0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6, + 0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3, + 0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58, + 0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58, + 0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C, + 0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC, + 0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7, + 0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, + 0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0, + 0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58, + 0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60, + 0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60, + 0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB, + 0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7, + 0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7, + 0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE, + 0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B, + 0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61, + 0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64, + 0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC, + 0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8, + 0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5, + 0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C, + 0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E, + 0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62, + 0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC, + 0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB, + 0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7, + 0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5, + 0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57, + 0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47, + 0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60, + 0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0, + 0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0, + 0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8, + 0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6, + 0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57, + 0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B, + 0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C, + 0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3, + 0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB, + 0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8, + 0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7, + 0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57, + 0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C, + 0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58, + 0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1, + 0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC, + 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED, + 0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, + 0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58, + 0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60, + 0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56, + 0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0, + 0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC, + 0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6, + 0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, + 0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B, + 0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C, + 0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59, + 0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0, + 0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC, + 0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6, + 0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6, + 0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B, + 0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56, + 0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60, + 0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF, + 0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9, + 0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9, + 0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, + 0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52, + 0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B, + 0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD, + 0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE, + 0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65, + 0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6, + 0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D, + 0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58, + 0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F, + 0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4, + 0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE, + 0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0, + 0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D, + 0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57, + 0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40, + 0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9, + 0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE, + 0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC, + 0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9, + 0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38, + 0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52, + 0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40, + 0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF, + 0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99, + 0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6, + 0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, + 0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B, + 0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43, + 0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC, + 0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0, + 0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C, + 0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, + 0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49, + 0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A, + 0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2, + 0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94, + 0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, + 0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E, + 0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D, + 0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC, + 0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4, + 0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B, + 0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7, + 0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E, + 0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0, + 0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA, + 0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9, + 0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89, + 0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA, + 0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2, + 0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E, + 0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA, + 0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA, + 0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6, + 0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97, + 0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D, + 0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9, + 0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D, + 0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45, + 0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB, + 0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6, + 0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99, + 0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A, + 0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC, + 0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4, + 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C, + 0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47, + 0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD, + 0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4, + 0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A, + 0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98, + 0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC, + 0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4, + 0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89, + 0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B, + 0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD, + 0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0, + 0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0, + 0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A, + 0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC, + 0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2, + 0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A, + 0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49, + 0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC, + 0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63, + 0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B, + 0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84, + 0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC, + 0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99, + 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B, + 0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51, + 0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC, + 0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A, + 0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95, + 0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E, + 0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA, + 0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22, + 0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99, + 0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94, + 0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B, + 0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA, + 0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D, + 0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C, + 0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A, + 0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23, + 0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99, + 0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E, + 0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87, + 0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3, + 0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48, + 0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94, + 0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95, + 0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6, + 0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40, + 0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99, + 0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95, + 0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98, + 0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC, + 0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45, + 0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89, + 0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C, + 0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4, + 0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99, + 0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87, + 0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC, + 0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58, + 0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40, + 0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94, + 0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B, + 0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6, + 0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20, + 0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C, + 0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94, + 0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE, + 0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C, + 0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41, + 0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98, + 0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C, + 0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6, + 0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B, + 0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B, + 0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0, + 0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62, + 0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44, + 0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6, + 0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89, + 0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8, + 0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99, + 0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98, + 0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1, + 0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB, + 0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49, + 0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA, + 0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2, + 0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA, + 0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2, + 0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0, + 0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF, + 0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD, + 0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52, + 0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA, + 0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA, + 0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1, + 0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8, + 0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0, + 0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9, + 0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD, + 0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53, + 0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56, + 0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0, + 0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9, + 0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0, + 0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3, + 0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF, + 0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2, + 0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3, + 0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE, + 0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56, + 0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57, + 0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC, + 0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA, + 0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4, + 0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3, + 0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1, + 0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6, + 0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE, + 0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD, + 0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58, + 0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D, + 0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47, + 0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6, + 0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4, + 0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5, + 0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9, + 0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC, + 0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3, + 0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64, + 0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C, + 0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A, + 0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A, + 0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0, + 0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE, + 0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6, + 0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6, + 0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE, + 0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5, + 0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E, + 0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D, + 0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E, + 0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E, + 0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8, + 0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5, + 0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1, + 0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60, + 0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9, + 0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5, + 0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47, + 0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E, + 0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45, + 0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51, + 0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB, + 0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0, + 0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D, + 0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0, + 0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5, + 0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2, + 0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D, + 0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60, + 0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45, + 0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63, + 0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7, + 0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3, + 0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E, + 0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2, + 0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0, + 0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC, + 0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C, + 0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61, + 0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45, + 0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2, + 0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3, + 0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2, + 0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47, + 0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2, + 0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E, + 0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3, + 0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63, + 0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62, + 0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49, + 0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3, + 0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF, + 0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2, + 0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58, + 0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE, + 0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B, + 0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4, + 0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE, + 0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62, + 0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A, + 0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5, + 0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE, + 0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3, + 0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53, + 0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3, + 0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48, + 0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3, + 0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF, + 0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0xC0, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x04, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x40, 0x11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0xD2, 0x29, + 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x19, 0xFF, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1E, 0x80, 0x19, + 0xFF, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1E, + 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0E, 0x80, 0x11, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x06, 0x00, 0x11, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x06, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x02, 0x80, 0x10, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x97, 0x10, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xDF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0x18, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0xA8, 0x11, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x01, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x47, 0xFF, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x23, + 0xFF, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x11, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:24 jj Exp $ + * include/asm-sparc/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/SPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 221 + +unsigned char linux_logo_red[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5, + 0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5, + 0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03, + 0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6, + 0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2, + 0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A, + 0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4, + 0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2, + 0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC, + 0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC, + 0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7, + 0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3, + 0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4, + 0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4, + 0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87, + 0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E, + 0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_green[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3, + 0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9, + 0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02, + 0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD, + 0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6, + 0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C, + 0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4, + 0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E, + 0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC, + 0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5, + 0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96, + 0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80, + 0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F, + 0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C, + 0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54, + 0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E, + 0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_blue[] __initdata = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE, + 0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5, + 0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84, + 0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7, + 0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77, + 0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59, + 0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E, + 0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14, + 0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D, + 0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14, + 0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08, + 0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E, + 0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E, + 0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20, + 0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06, + 0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17, + 0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14, + 0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo[] __initdata = { + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61, + 0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E, + 0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58, + 0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C, + 0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A, + 0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52, + 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53, + 0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, + 0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49, + 0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B, + 0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, + 0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB, + 0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C, + 0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49, + 0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5, + 0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58, + 0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51, + 0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54, + 0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5, + 0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61, + 0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C, + 0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B, + 0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53, + 0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC, + 0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59, + 0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48, + 0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51, + 0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63, + 0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48, + 0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51, + 0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52, + 0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB, + 0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B, + 0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53, + 0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53, + 0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC, + 0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F, + 0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61, + 0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57, + 0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D, + 0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57, + 0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC, + 0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC, + 0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48, + 0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52, + 0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61, + 0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A, + 0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC, + 0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC, + 0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49, + 0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F, + 0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB, + 0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47, + 0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54, + 0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D, + 0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC, + 0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC, + 0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45, + 0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44, + 0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64, + 0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48, + 0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D, + 0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC, + 0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA, + 0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55, + 0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45, + 0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D, + 0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B, + 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A, + 0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC, + 0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8, + 0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD, + 0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A, + 0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56, + 0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, + 0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54, + 0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC, + 0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB, + 0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34, + 0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F, + 0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E, + 0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60, + 0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57, + 0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51, + 0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC, + 0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE, + 0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30, + 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41, + 0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65, + 0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C, + 0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A, + 0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC, + 0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C, + 0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1, + 0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32, + 0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30, + 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41, + 0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC, + 0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A, + 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, + 0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E, + 0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC, + 0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88, + 0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB, + 0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33, + 0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31, + 0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E, + 0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63, + 0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49, + 0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, + 0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55, + 0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC, + 0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C, + 0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8, + 0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F, + 0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F, + 0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48, + 0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A, + 0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A, + 0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57, + 0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53, + 0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC, + 0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88, + 0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E, + 0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47, + 0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D, + 0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58, + 0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55, + 0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC, + 0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E, + 0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9, + 0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73, + 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70, + 0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF, + 0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E, + 0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57, + 0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58, + 0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C, + 0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC, + 0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C, + 0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC, + 0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78, + 0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, + 0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1, + 0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C, + 0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D, + 0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58, + 0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E, + 0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC, + 0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8, + 0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42, + 0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73, + 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73, + 0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2, + 0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41, + 0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62, + 0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B, + 0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60, + 0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC, + 0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7, + 0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41, + 0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73, + 0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74, + 0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB, + 0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41, + 0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64, + 0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E, + 0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C, + 0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB, + 0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE, + 0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20, + 0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75, + 0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76, + 0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D, + 0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C, + 0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64, + 0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, + 0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58, + 0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC, + 0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81, + 0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23, + 0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76, + 0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76, + 0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48, + 0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40, + 0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61, + 0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C, + 0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52, + 0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB, + 0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E, + 0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8, + 0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, + 0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C, + 0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57, + 0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D, + 0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A, + 0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65, + 0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC, + 0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40, + 0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47, + 0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF, + 0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A, + 0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57, + 0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5, + 0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C, + 0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52, + 0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9, + 0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42, + 0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51, + 0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6, + 0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7, + 0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93, + 0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D, + 0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF, + 0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40, + 0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52, + 0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1, + 0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8, + 0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93, + 0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40, + 0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0, + 0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F, + 0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59, + 0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E, + 0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23, + 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7, + 0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93, + 0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F, + 0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC, + 0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47, + 0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54, + 0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D, + 0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24, + 0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24, + 0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A, + 0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5, + 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93, + 0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60, + 0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC, + 0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47, + 0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B, + 0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D, + 0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28, + 0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D, + 0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD, + 0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93, + 0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7, + 0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44, + 0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45, + 0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B, + 0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20, + 0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6, + 0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90, + 0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0, + 0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44, + 0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45, + 0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51, + 0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF, + 0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7, + 0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5, + 0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2, + 0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58, + 0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C, + 0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55, + 0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1, + 0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB, + 0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6, + 0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3, + 0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58, + 0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58, + 0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C, + 0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC, + 0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7, + 0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, + 0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0, + 0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58, + 0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60, + 0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60, + 0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB, + 0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7, + 0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7, + 0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE, + 0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B, + 0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61, + 0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64, + 0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC, + 0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8, + 0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5, + 0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C, + 0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E, + 0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62, + 0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC, + 0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB, + 0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7, + 0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5, + 0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57, + 0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47, + 0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60, + 0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0, + 0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0, + 0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8, + 0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6, + 0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57, + 0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B, + 0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C, + 0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3, + 0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB, + 0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8, + 0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7, + 0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57, + 0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C, + 0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58, + 0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1, + 0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC, + 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED, + 0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, + 0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58, + 0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60, + 0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56, + 0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0, + 0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC, + 0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6, + 0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, + 0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B, + 0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C, + 0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59, + 0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0, + 0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC, + 0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6, + 0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6, + 0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B, + 0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56, + 0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60, + 0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF, + 0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9, + 0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9, + 0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, + 0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52, + 0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B, + 0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD, + 0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE, + 0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65, + 0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6, + 0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D, + 0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58, + 0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F, + 0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4, + 0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE, + 0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0, + 0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D, + 0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57, + 0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40, + 0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9, + 0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE, + 0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC, + 0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9, + 0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38, + 0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52, + 0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40, + 0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF, + 0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99, + 0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6, + 0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, + 0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B, + 0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43, + 0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC, + 0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0, + 0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C, + 0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, + 0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49, + 0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A, + 0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2, + 0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94, + 0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, + 0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E, + 0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D, + 0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC, + 0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4, + 0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B, + 0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7, + 0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E, + 0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0, + 0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA, + 0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9, + 0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89, + 0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA, + 0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2, + 0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E, + 0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA, + 0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA, + 0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6, + 0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97, + 0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D, + 0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9, + 0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D, + 0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45, + 0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB, + 0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6, + 0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99, + 0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A, + 0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC, + 0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4, + 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C, + 0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47, + 0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD, + 0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4, + 0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A, + 0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98, + 0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC, + 0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4, + 0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89, + 0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B, + 0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD, + 0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0, + 0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0, + 0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A, + 0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC, + 0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2, + 0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A, + 0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49, + 0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC, + 0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63, + 0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B, + 0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84, + 0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC, + 0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99, + 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B, + 0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51, + 0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC, + 0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A, + 0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95, + 0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E, + 0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA, + 0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22, + 0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99, + 0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94, + 0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B, + 0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA, + 0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D, + 0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C, + 0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A, + 0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23, + 0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99, + 0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E, + 0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87, + 0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3, + 0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48, + 0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94, + 0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95, + 0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6, + 0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40, + 0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99, + 0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95, + 0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98, + 0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC, + 0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45, + 0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89, + 0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C, + 0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4, + 0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99, + 0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87, + 0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC, + 0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58, + 0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40, + 0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94, + 0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B, + 0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6, + 0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20, + 0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C, + 0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94, + 0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE, + 0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C, + 0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41, + 0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98, + 0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C, + 0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6, + 0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B, + 0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B, + 0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0, + 0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62, + 0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44, + 0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6, + 0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89, + 0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8, + 0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99, + 0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98, + 0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1, + 0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB, + 0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49, + 0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA, + 0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2, + 0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA, + 0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2, + 0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0, + 0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF, + 0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD, + 0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52, + 0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA, + 0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA, + 0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1, + 0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8, + 0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0, + 0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9, + 0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD, + 0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53, + 0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56, + 0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0, + 0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9, + 0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0, + 0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3, + 0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF, + 0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2, + 0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3, + 0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE, + 0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56, + 0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57, + 0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC, + 0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA, + 0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4, + 0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3, + 0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1, + 0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6, + 0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE, + 0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD, + 0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58, + 0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D, + 0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47, + 0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6, + 0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4, + 0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5, + 0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9, + 0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC, + 0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3, + 0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64, + 0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C, + 0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A, + 0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A, + 0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0, + 0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE, + 0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6, + 0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6, + 0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE, + 0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5, + 0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E, + 0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D, + 0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E, + 0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E, + 0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8, + 0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5, + 0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1, + 0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60, + 0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9, + 0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5, + 0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47, + 0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E, + 0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45, + 0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51, + 0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB, + 0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0, + 0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D, + 0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0, + 0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5, + 0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2, + 0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D, + 0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60, + 0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45, + 0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63, + 0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7, + 0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3, + 0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E, + 0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2, + 0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0, + 0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC, + 0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C, + 0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61, + 0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45, + 0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2, + 0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3, + 0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2, + 0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47, + 0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2, + 0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E, + 0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3, + 0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63, + 0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62, + 0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49, + 0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3, + 0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF, + 0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2, + 0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58, + 0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE, + 0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B, + 0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4, + 0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE, + 0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62, + 0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A, + 0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5, + 0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE, + 0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3, + 0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53, + 0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3, + 0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48, + 0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3, + 0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF, + 0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0xC0, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x04, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x40, 0x11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0xD2, 0x29, + 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x19, 0xFF, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1E, 0x80, 0x19, + 0xFF, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1E, + 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0E, 0x80, 0x11, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x06, 0x00, 0x11, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x06, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x02, 0x80, 0x10, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x97, 0x10, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xDF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0x18, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0xA8, 0x11, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x01, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x47, 0xFF, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x23, + 0xFF, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x11, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/mxcc.h linux/include/asm-sparc/mxcc.h --- v2.1.35/linux/include/asm-sparc/mxcc.h Sat Nov 9 00:29:47 1996 +++ linux/include/asm-sparc/mxcc.h Tue Apr 22 22:39:21 1997 @@ -1,4 +1,4 @@ -/* $Id: mxcc.h,v 1.6 1996/08/29 09:48:27 davem Exp $ +/* $Id: mxcc.h,v 1.7 1997/04/20 14:11:46 ecd Exp $ * mxcc.h: Definitions of the Viking MXCC registers * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -83,6 +83,8 @@ * MID: The moduleID of the cpu your read this from. */ +#ifndef __ASSEMBLY__ + extern __inline__ void mxcc_set_stream_src(unsigned long *paddr) { unsigned long data0 = paddr[0]; @@ -129,5 +131,7 @@ "r" (mxcc_control), "r" (MXCC_CREG), "i" (ASI_M_MXCC)); } + +#endif /* !__ASSEMBLY__ */ #endif /* !(_SPARC_MXCC_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/pgtable.h linux/include/asm-sparc/pgtable.h --- v2.1.35/linux/include/asm-sparc/pgtable.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/pgtable.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.59 1997/04/10 05:13:23 davem Exp $ */ +/* $Id: pgtable.h,v 1.60 1997/04/14 17:05:16 jj Exp $ */ #ifndef _SPARC_PGTABLE_H #define _SPARC_PGTABLE_H @@ -367,5 +367,31 @@ } #define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry) #define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry) + +extern __inline__ unsigned int +__get_phys (unsigned long addr) +{ + switch (sparc_cpu_model){ + case sun4c: + return sun4c_get_pte (addr) << PAGE_SHIFT; + case sun4m: + return ((srmmu_get_pte (addr) & 0xffffff00) << 4); + default: + return 0; + } +} + +extern __inline__ int +__get_iospace (unsigned long addr) +{ + switch (sparc_cpu_model){ + case sun4c: + return -1; /* Don't check iospace on sun4c */ + case sun4m: + return (srmmu_get_pte (addr) >> 28); + default: + return -1; + } +} #endif /* !(_SPARC_PGTABLE_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/semaphore.h linux/include/asm-sparc/semaphore.h --- v2.1.35/linux/include/asm-sparc/semaphore.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/semaphore.h Thu Apr 17 13:20:51 1997 @@ -13,8 +13,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { (1 << 8) }, { 0 }, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); @@ -22,6 +22,12 @@ #define sema_init(sem, val) atomic_set(&((sem)->count), val) +#define wake_one_more(sem) atomic_inc(&sem->waking); + +/* XXX Put this in raw assembler for SMP case so that the atomic_t + * XXX spinlock can allow this to be done without grabbing the IRQ + * XXX global lock. + */ static inline int waking_non_zero(struct semaphore *sem) { unsigned long flags; diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/smp.h linux/include/asm-sparc/smp.h --- v2.1.35/linux/include/asm-sparc/smp.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/smp.h Tue Apr 15 21:47:24 1997 @@ -96,48 +96,6 @@ return cpuid; } -extern __volatile__ int smp_process_available; - -extern __inline__ int smp_swap(volatile int *addr, int value) -{ - __asm__ __volatile__("swap [%2], %0\n\t" : - "=&r" (value) : - "0" (value), "r" (addr)); - return value; -} - -extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr) -{ - int tmp; - - while((tmp = smp_swap(ctr, -1)) == -1) - while(*ctr == -1) - ; - - *ctr = (tmp + 1); -} - -extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr) -{ - int tmp; - - while((tmp = smp_swap(ctr, -1)) == -1) - while(*ctr == -1) - ; - - *ctr = (tmp - 1); -} - -extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr) -{ - int value; - - while((value = *ctr) == -1) - ; - - return value; -} - #endif /* !(__ASSEMBLY__) */ /* Sparc specific messages. */ @@ -154,13 +112,13 @@ #define MBOX_IDLECPU2 0xFD #define MBOX_STOPCPU2 0xFE -#define NO_PROC_ID 0xFF - #define PROC_CHANGE_PENALTY 20 #define SMP_FROM_INT 1 #define SMP_FROM_SYSCALL 2 #endif /* !(__SMP__) */ + +#define NO_PROC_ID 0xFF #endif /* !(_SPARC_SMP_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/smp_lock.h linux/include/asm-sparc/smp_lock.h --- v2.1.35/linux/include/asm-sparc/smp_lock.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/smp_lock.h Tue Apr 22 22:39:21 1997 @@ -14,7 +14,7 @@ #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) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) #else @@ -34,7 +34,7 @@ } while(0) /* Do not fuck with this without consulting arch/sparc/lib/locks.S first! */ -#define reaquire_kernel_lock(task, cpu, depth) \ +#define reacquire_kernel_lock(task, cpu, depth) \ do { \ if(depth) { \ register struct klock_info *klip asm("g1"); \ @@ -42,7 +42,7 @@ klip = &klock_info; \ proc = cpu; \ __asm__ __volatile__("mov %%o7, %%g4\n\t" \ - "call ___lock_reaquire_kernel\n\t" \ + "call ___lock_reacquire_kernel\n\t" \ " mov %2, %%g2" \ : /* No outputs. */ \ : "r" (klip), "r" (proc), "r" (depth) \ @@ -63,19 +63,6 @@ register int proc asm("g5"); klip = &klock_info; proc = smp_processor_id(); - -#if 1 /* Debugging */ - if(local_irq_count[proc]) { - __label__ l1; -l1: printk("lock from interrupt context at %p\n", &&l1); - } - if(proc == global_irq_holder) { - __label__ l2; -l2: printk("Ugh at %p\n", &&l2); - sti(); - } -#endif - __asm__ __volatile__(" mov %%o7, %%g4 call ___lock_kernel diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/softirq.h linux/include/asm-sparc/softirq.h --- v2.1.35/linux/include/asm-sparc/softirq.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/softirq.h Tue Apr 22 22:39:21 1997 @@ -13,18 +13,17 @@ * is entirely private to an implementation, it should not be * referenced at all outside of this file. */ +#define get_active_bhs() (bh_mask & bh_active) + +#ifdef __SMP__ + extern atomic_t __sparc_bh_counter; -/* Linus, I'd _really_ like to get rid of this synchronize_irq() -DaveM */ #define start_bh_atomic() \ do { atomic_inc(&__sparc_bh_counter); synchronize_irq(); } while(0) #define end_bh_atomic() atomic_dec(&__sparc_bh_counter) -#define get_active_bhs() (bh_mask & bh_active) - -#ifdef __SMP__ - #include extern spinlock_t global_bh_lock; @@ -39,6 +38,15 @@ spin_unlock_irqrestore(&global_bh_lock, flags); \ } while(0) +#define remove_bh(nr) \ +do { unsigned long flags; \ + int ent = nr; \ + spin_lock_irqsave(&global_bh_lock, flags); \ + bh_base[ent] = NULL; \ + bh_mask &= ~(1 << ent); \ + spin_unlock_irqrestore(&global_bh_lock, flags); \ +} while(0) + #define mark_bh(nr) \ do { unsigned long flags; \ spin_lock_irqsave(&global_bh_lock, flags); \ @@ -83,10 +91,13 @@ #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) \ @@ -94,6 +105,12 @@ bh_base[ent] = routine; \ bh_mask_count[ent] = 0; \ 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))) diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/spinlock.h linux/include/asm-sparc/spinlock.h --- v2.1.35/linux/include/asm-sparc/spinlock.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/spinlock.h Tue Apr 22 22:39:21 1997 @@ -16,6 +16,7 @@ #define spin_lock_init(lock) do { } while(0) #define spin_lock(lock) do { } while(0) #define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) #define spin_unlock(lock) do { } while(0) #define spin_lock_irq(lock) cli() #define spin_unlock_irq(lock) sti() @@ -23,6 +24,33 @@ #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__) */ #include @@ -30,20 +58,25 @@ typedef unsigned char spinlock_t; #define SPIN_LOCK_UNLOCKED 0 +#define spin_lock_init(lock) (*(lock) = 0) +#define spin_unlock_wait(lock) do { barrier(); } while(*(volatile spinlock_t *)lock) + extern __inline__ void spin_lock(spinlock_t *lock) { - register spinlock_t *lp asm("g1"); - lp = lock; __asm__ __volatile__(" - ldstub [%%g1], %%g2 +1: ldstub [%0], %%g2 orcc %%g2, 0x0, %%g0 - be 1f - mov %%o7, %%g4 - call ___spinlock_waitfor - ldub [%%g1], %%g2 -1:" : /* no outputs */ - : "r" (lp) - : "g2", "g4", "memory", "cc"); + bne,a 2f + ldub [%0], %%g2 + .text 2 +2: orcc %%g2, 0x0, %%g0 + bne,a 2b + ldub [%0], %%g2 + b,a 1b + .previous +" : /* no outputs */ + : "r" (lock) + : "g2", "memory", "cc"); } extern __inline__ int spin_trylock(spinlock_t *lock) @@ -63,22 +96,24 @@ 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) @@ -102,16 +137,22 @@ "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" \ - "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 2f\n\t" \ + " ldub [%2], %%g2\n\t" \ + ".text 2\n" \ + "2:\n\t" \ + "orcc %%g2, 0x0, %%g0\n\t" \ + "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) @@ -124,6 +165,92 @@ : "r" (lock), "r" (flags) : "memory", "cc"); } + +/* 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. + * + * XXX This might create some problems with my dual spinlock + * XXX scheme, deadlocks etc. -DaveM + */ +typedef struct { volatile unsigned int lock; } rwlock_t; + +#define RW_LOCK_UNLOCKED { 0 } + +/* Sort of like atomic_t's on Sparc, but even more clever. + * + * ------------------------------------ + * | 16-bit counter | clock | wlock | rwlock_t + * ------------------------------------ + * 31 16 15 8 7 0 + * + * wlock signifies the one writer is in, the clock protects + * counter bumping, however a reader must acquire wlock + * before he can bump the counter on a read_lock(). + * Similarly a writer, once he has the wlock, must await + * for the top 24 bits to all clear before he can finish + * going in (this includes the clock of course). + * + * Unfortunately this scheme limits us to ~65,000 cpus. + */ +extern __inline__ void read_lock(rwlock_t *rw) +{ + register rwlock_t *lp asm("g1"); + lp = rw; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___rw_read_enter + ldstub [%%g1 + 3], %%g2 +" : /* no outputs */ + : "r" (lp) + : "g2", "g4", "g7", "memory", "cc"); +} + +extern __inline__ void read_unlock(rwlock_t *rw) +{ + register rwlock_t *lp asm("g1"); + lp = rw; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___rw_read_exit + ldstub [%%g1 + 2], %%g2 +" : /* no outputs */ + : "r" (lp) + : "g2", "g4", "g7", "memory", "cc"); +} + +extern __inline__ void write_lock(rwlock_t *rw) +{ + register rwlock_t *lp asm("g1"); + lp = rw; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___rw_write_enter + ldstub [%%g1 + 3], %%g2 +" : /* no outputs */ + : "r" (lp) + : "g2", "g4", "g7", "memory", "cc"); +} + +#define write_unlock(rw) do { (rw)->lock = 0; } while(0) +#define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0) +#define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0) +#define write_lock_irq(lock) do { __cli(); write_lock(lock); } while (0) +#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0) + +#define read_lock_irqsave(lock, flags) \ + do { __save_and_cli(flags); read_lock(lock); } while (0) +#define read_unlock_irqrestore(lock, flags) \ + do { read_unlock(lock); __restore_flags(flags); } while (0) +#define write_lock_irqsave(lock, flags) \ + do { __save_and_cli(flags); write_lock(lock); } while (0) +#define write_unlock_irqrestore(lock, flags) \ + do { write_unlock(lock); __restore_flags(flags); } while (0) #endif /* __SMP__ */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/system.h linux/include/asm-sparc/system.h --- v2.1.35/linux/include/asm-sparc/system.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/system.h Tue Apr 22 22:39:21 1997 @@ -1,4 +1,4 @@ -/* $Id: system.h,v 1.56 1997/04/14 05:39:30 davem Exp $ */ +/* $Id: system.h,v 1.58 1997/04/18 05:44:54 davem Exp $ */ #ifndef __SPARC_SYSTEM_H #define __SPARC_SYSTEM_H @@ -93,9 +93,7 @@ "rd %%wim, %%g5\n\t" \ "wr %%g4, 0x20, %%psr\n\t" \ "nop\n\t" \ - "mov %5, %%g7\n\t" \ "std %%g4, [%%g6 + %2]\n\t" \ - "st %%g7, [%%g6 + %6]\n\t" \ "ldd [%1 + %2], %%g4\n\t" \ "mov %1, %%g6\n\t" \ "st %1, [%0]\n\t" \ @@ -113,8 +111,7 @@ " nop\n\t" : : "r" (&(current_set[smp_processor_id()])), "r" (next), \ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpsr)), \ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)), \ - "r" (task_pc), "i" (255), \ - "i" ((const unsigned long)(&((struct task_struct *)0)->processor)) \ + "r" (task_pc) \ : "g1", "g2", "g3", "g4", "g5", "g7", "l2", "l3", \ "l4", "l5", "l6", "l7", "i0", "i1", "i2", "i3", "i4", "i5", "o0", "o1", "o2", \ "o3"); \ @@ -127,9 +124,7 @@ { __asm__ __volatile__(" wr %0, 0x0, %%psr - nop - nop - nop + nop; nop; nop " : /* no outputs */ : "r" (__orig_psr) : "memory", "cc"); @@ -141,14 +136,9 @@ __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"); @@ -160,14 +150,9 @@ __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"); @@ -192,7 +177,7 @@ xorcc %1, %2, %%g0 be 1f nop - wr %0, %4, %%psr + wr %0, %4, %%psr nop nop nop @@ -210,38 +195,64 @@ __asm__ __volatile__(" rd %%psr, %0 - andcc %0, %1, %%g0 - bne 1f - nop - wr %0, %1, %%psr - nop - nop - nop -1: + or %0, %1, %%g1 + wr %%g1, 0x0, %%psr + nop; nop; nop " : "=r" (retval) : "i" (PSR_PIL) - : "memory"); + : "g1", "memory"); return retval; } -extern char spdeb_buf[256]; - #define __save_flags(flags) ((flags) = getipl()) #define __save_and_cli(flags) ((flags) = read_psr_and_cli()) #define __restore_flags(flags) setipl((flags)) #ifdef __SMP__ -extern void __global_cli(void); -extern void __global_sti(void); -extern unsigned long __global_save_flags(void); -extern void __global_restore_flags(unsigned long); -#define cli() __global_cli() -#define sti() __global_sti() -#define save_flags(x) ((x)=__global_save_flags()) -#define restore_flags(x) __global_restore_flags(x) -#define save_and_cli(x) do { (x)=__global_save_flags(); __global_cli(); } while(0) +/* Visit arch/sparc/lib/irqlock.S for all the fun details... */ +#define cli() __asm__ __volatile__("mov %%o7, %%g4\n\t" \ + "call ___global_cli\n\t" \ + " rd %%tbr, %%g7" : : \ + : "g1", "g2", "g3", "g4", "g5", "g7", \ + "memory", "cc") + +#define sti() \ +do { register unsigned long bits asm("g7"); \ + bits = 0; \ + __asm__ __volatile__("mov %%o7, %%g4\n\t" \ + "call ___global_sti\n\t" \ + " rd %%tbr, %%g2" \ + : /* no outputs */ \ + : "r" (bits) \ + : "g1", "g2", "g3", "g4", "g5", \ + "memory", "cc"); \ +} while(0) + +extern unsigned char global_irq_holder; + +#define save_flags(x) \ +do { int cpuid; \ + __asm__ __volatile__("rd %%tbr, %0; srl %0, 12, %0; and %0, 3, %0" \ + : "=r" (cpuid)); \ + ((x) = ((global_irq_holder == (unsigned char) cpuid) ? 1 : \ + ((getipl() & PSR_PIL) ? 2 : 0))); \ +} while(0) + +#define restore_flags(flags) \ +do { register unsigned long bits asm("g7"); \ + bits = flags; \ + __asm__ __volatile__("mov %%o7, %%g4\n\t" \ + "call ___global_restore_flags\n\t" \ + " andcc %%g7, 0x1, %%g0" \ + : "=&r" (bits) \ + : "0" (bits) \ + : "g1", "g2", "g3", "g4", "g5", \ + "memory", "cc"); \ +} while(0) + +#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0) #else diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc/viking.h linux/include/asm-sparc/viking.h --- v2.1.35/linux/include/asm-sparc/viking.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/viking.h Tue Apr 22 22:39:21 1997 @@ -1,4 +1,4 @@ -/* $Id: viking.h,v 1.18 1997/04/11 00:42:23 davem Exp $ +/* $Id: viking.h,v 1.19 1997/04/20 14:11:48 ecd Exp $ * viking.h: Defines specific to the GNU/Viking MBUS module. * This is SRMMU stuff. * @@ -108,6 +108,8 @@ #define VIKING_PTAG_DIRTY 0x00010000 /* Block has been modified */ #define VIKING_PTAG_SHARED 0x00000100 /* Shared with some other cache */ +#ifndef __ASSEMBLY__ + extern __inline__ void viking_flush_icache(void) { __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : @@ -234,5 +236,7 @@ "r" (vaddr), "i" (ASI_M_FLUSH_PROBE)); return val; } + +#endif /* !__ASSEMBLY__ */ #endif /* !(_SPARC_VIKING_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/atomic.h linux/include/asm-sparc64/atomic.h --- v2.1.35/linux/include/asm-sparc64/atomic.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/atomic.h Thu Apr 17 13:20:51 1997 @@ -1,4 +1,4 @@ -/* $Id: atomic.h,v 1.13 1997/04/14 06:56:57 davem Exp $ +/* $Id: atomic.h,v 1.14 1997/04/16 05:57:06 davem Exp $ * atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * @@ -15,7 +15,7 @@ #define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x) typedef struct { int counter; } atomic_t; -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/errno.h linux/include/asm-sparc64/errno.h --- v2.1.35/linux/include/asm-sparc64/errno.h Fri Dec 13 01:37:41 1996 +++ linux/include/asm-sparc64/errno.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: errno.h,v 1.1 1996/11/20 15:27:39 davem Exp $ */ +/* $Id: errno.h,v 1.2 1997/04/15 12:46:11 jj Exp $ */ #ifndef _SPARC64_ERRNO_H #define _SPARC64_ERRNO_H @@ -129,5 +129,8 @@ #define EILSEQ 122 /* Illegal byte sequence */ #define ELIBMAX 123 /* Atmpt to link in too many shared libs */ #define ELIBSCN 124 /* .lib section in a.out corrupted */ + +#define ENOMEDIUM 125 /* No medium found */ +#define EMEDIUMTYPE 126 /* Wrong medium type */ #endif /* !(_SPARC64_ERRNO_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/fbio.h linux/include/asm-sparc64/fbio.h --- v2.1.35/linux/include/asm-sparc64/fbio.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/fbio.h Thu Apr 17 13:20:51 1997 @@ -33,6 +33,9 @@ #define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ +/* Does not seem to be listed in the Sun file either */ +#define FBTYPE_CREATOR 22 + /* fbio ioctls */ /* Returned by FBIOGTYPE */ struct fbtype { diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/fcntl.h linux/include/asm-sparc64/fcntl.h --- v2.1.35/linux/include/asm-sparc64/fcntl.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/fcntl.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: fcntl.h,v 1.2 1997/04/04 00:50:15 davem Exp $ */ +/* $Id: fcntl.h,v 1.3 1997/04/14 17:05:20 jj Exp $ */ #ifndef _SPARC64_FCNTL_H #define _SPARC64_FCNTL_H @@ -48,7 +48,6 @@ blocking */ #define LOCK_UN 8 /* remove lock */ -/* XXX 32-bit binary compatability item... -DaveM */ struct flock { short l_type; short l_whence; @@ -57,5 +56,16 @@ pid_t l_pid; short __unused; }; + +#ifdef __KERNEL__ +struct flock32 { + short l_type; + short l_whence; + __kernel_off_t32 l_start; + __kernel_off_t32 l_len; + __kernel_pid_t32 l_pid; + short __unused; +}; +#endif #endif /* !(_SPARC64_FCNTL_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/init.h linux/include/asm-sparc64/init.h --- v2.1.35/linux/include/asm-sparc64/init.h Thu Mar 27 14:40:09 1997 +++ linux/include/asm-sparc64/init.h Thu Apr 17 13:20:51 1997 @@ -1,9 +1,6 @@ -#ifndef _SPARC64_INIT_H -#define _SPARC64_INIT_H +#ifndef _SPARC_INIT_H +#define _SPARC_INIT_H -#ifndef __init -/* 'cause of buggy linker, we don't use this for now... */ -#if 0 && !defined (MODULE) #define __init __attribute__ ((__section__ (".text.init"))) #define __initdata __attribute__ ((__section__ (".data.init"))) #define __initfunc(__arginit) \ @@ -13,15 +10,5 @@ #define __INIT .section ".text.init",#alloc,#execinstr #define __FINIT .previous #define __INITDATA .section ".data.init",#alloc,#write -#else -#define __init -#define __initdata -#define __initfunc(__arginit) __arginit -/* For assembly routines */ -#define __INIT -#define __FINIT -#define __INITDATA -#endif -#endif #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/ipc.h linux/include/asm-sparc64/ipc.h --- v2.1.35/linux/include/asm-sparc64/ipc.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/ipc.h Tue Apr 15 21:47:24 1997 @@ -4,12 +4,11 @@ /* * These are used to wrap system calls on the sparc. * - * See arch/sparc64/kernel/sys_sparc.c for ugly details.. + * See arch/sparc64/kernel/sys_sparc32.c for ugly details.. */ -/* XXX 32-bit binary compatability... */ struct ipc_kludge { - struct msgbuf *msgp; - long msgtyp; + u32 msgp; + s32 msgtyp; }; #define SEMOP 1 @@ -24,6 +23,7 @@ #define SHMGET 23 #define SHMCTL 24 -#define IPCCALL(version,op) ((version)<<16 | (op)) +/* We don't need to maintain backward compatibility on 64bit, we've started fresh */ +#define IPCCALL(version,op) (op) #endif diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/linux_logo.h linux/include/asm-sparc64/linux_logo.h --- v2.1.35/linux/include/asm-sparc64/linux_logo.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-sparc64/linux_logo.h Tue Apr 22 22:39:21 1997 @@ -0,0 +1,2084 @@ +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:37 jj Exp $ + * include/asm-sparc64/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/UltraSPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 215 + +unsigned char linux_logo_red[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xB0, + 0x0C, 0xB1, 0xD4, 0xCE, 0x04, 0x06, 0x16, 0xB6, + 0xCD, 0xB2, 0x42, 0x46, 0x4B, 0xA8, 0xF3, 0xCA, + 0xC5, 0x1C, 0xDC, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x8E, 0xCC, 0xA5, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x79, 0x68, 0x8D, 0xAF, 0xFC, 0x8E, 0x3E, + 0x6B, 0x11, 0x37, 0x79, 0x5C, 0x3C, 0x3F, 0x3C, + 0x48, 0x47, 0x3D, 0xB9, 0x62, 0xE1, 0x4D, 0x57, + 0x84, 0x78, 0xA6, 0x58, 0x99, 0xCD, 0xB7, 0xE3, + 0x6D, 0x5A, 0xAF, 0x79, 0x79, 0xF2, 0x42, 0x46, + 0xDD, 0x89, 0xC3, 0xF2, 0xF0, 0xE0, 0xD1, 0x90, + 0x76, 0x6B, 0x4A, 0xBE, 0xBD, 0xE3, 0xF6, 0xE9, + 0xEC, 0xE8, 0xEC, 0xC0, 0x66, 0x63, 0xCB, 0xAB, + 0x49, 0x5C, 0xAD, 0xD6, 0xEE, 0xF5, 0xF5, 0xE9, + 0x6E, 0x00, 0x69, 0x6A, 0xA1, 0x7A, 0xB4, 0xDE, + 0xF1, 0xF6, 0xDD, 0x00, 0x73, 0xDB, 0x4C, 0x53, + 0x6A, 0xF5, 0xF5, 0xD6, 0xC3, 0x6A, 0x4B, 0x4B, + 0x60, 0xF8, 0x9B, 0xD7, 0xD7, 0x71, 0xB3, 0xA4, + 0xCA, 0xAB, 0xB4, 0xB2, 0x76, 0xBA, 0x8B, 0xA0, + 0xA5, 0xEE, 0xE7, 0x67, 0x5F, 0x08, 0x94, 0xDB, + 0xE5, 0x4F, 0x00, 0x34, 0xEE, 0xEC, 0xE2, 0x48, + 0xF3, 0xEB, 0xF4, 0xF4, 0xEF, 0xD6, 0xB6, 0xE6, + 0xE6, 0xED, 0xE7, 0xE6, 0x3D, 0xE7, 0xCD, 0x44, + 0xEF, 0xEC, 0xF5, 0x66, 0xF3, 0xA9, 0x77, 0x58, + 0x75, 0x6C, 0x53, 0x24, 0xAC, 0x0D, 0x3C +}; + +unsigned char linux_logo_green[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xAD, + 0x0C, 0xB1, 0x92, 0xAB, 0x03, 0x06, 0x16, 0xB6, + 0xCD, 0x88, 0x42, 0x46, 0x4B, 0x94, 0xBB, 0xCA, + 0xC5, 0x1C, 0xAB, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x73, 0xCA, 0x91, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x5A, 0x49, 0x56, 0x6E, 0xFC, 0x6B, 0x3E, + 0x6B, 0x0D, 0x37, 0x79, 0x51, 0x44, 0x3F, 0x43, + 0x38, 0x3D, 0x48, 0xB9, 0x62, 0xA5, 0x47, 0x48, + 0x49, 0x4A, 0x97, 0x48, 0x81, 0x95, 0x8E, 0xE3, + 0x6D, 0x57, 0x51, 0x51, 0x47, 0xB2, 0x42, 0x46, + 0xDD, 0x5B, 0x87, 0xBE, 0xC7, 0xC8, 0x56, 0x75, + 0x5D, 0x4B, 0x4D, 0xBE, 0x85, 0xA6, 0xBC, 0xC7, + 0xCA, 0xCD, 0xCC, 0xA4, 0x53, 0x4D, 0x9F, 0x55, + 0x52, 0x5E, 0x75, 0x9C, 0xB6, 0xC3, 0xD7, 0xCC, + 0x55, 0x00, 0x6A, 0x59, 0x7D, 0x55, 0x7C, 0xA3, + 0xB7, 0xBF, 0xA5, 0x00, 0x67, 0xC6, 0x47, 0x54, + 0x46, 0xB8, 0xBE, 0xB2, 0x87, 0x52, 0x4B, 0x43, + 0x41, 0xF8, 0x69, 0x96, 0x9B, 0x66, 0xB0, 0x6C, + 0x8E, 0x81, 0xB4, 0x76, 0x76, 0xB9, 0x65, 0x77, + 0x6D, 0xED, 0xE7, 0x67, 0x5F, 0x06, 0x54, 0x6C, + 0xCB, 0x4F, 0x00, 0x2F, 0xC2, 0xB5, 0xB6, 0x30, + 0xC3, 0xAE, 0xC4, 0xCA, 0xC6, 0xB4, 0x7B, 0xAD, + 0xAD, 0xB6, 0xB6, 0xAD, 0x29, 0xAB, 0x93, 0x2E, + 0xBC, 0xBC, 0xC9, 0x53, 0xBF, 0x77, 0x54, 0x3B, + 0x4B, 0x3F, 0x39, 0x19, 0x76, 0x08, 0x2C +}; + +unsigned char linux_logo_blue[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0xD6, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x39, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xA7, + 0x0C, 0xB1, 0x58, 0x8A, 0x03, 0x07, 0x16, 0xB6, + 0xCD, 0x5A, 0x42, 0x46, 0x4F, 0x6F, 0x77, 0xCA, + 0xC5, 0x1C, 0x6F, 0xA5, 0xD4, 0xE6, 0xF5, 0xF3, + 0xC2, 0x4D, 0xD1, 0x64, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x49, 0x3C, 0x47, 0x45, 0xFE, 0x3B, 0x41, + 0x6B, 0x09, 0x37, 0x79, 0x39, 0x39, 0x3F, 0x42, + 0x3A, 0x42, 0x5F, 0xB9, 0x62, 0x4C, 0x39, 0x44, + 0x3B, 0x3A, 0xA0, 0x3D, 0x08, 0x08, 0x09, 0xDE, + 0x6D, 0x48, 0x3B, 0x3F, 0x42, 0xF3, 0x36, 0x3C, + 0xDD, 0x06, 0x16, 0x08, 0x13, 0x0A, 0x4B, 0x71, + 0x5D, 0x44, 0x47, 0xBE, 0x08, 0x0C, 0x0D, 0x0C, + 0x19, 0x29, 0x36, 0x06, 0x43, 0x44, 0xBA, 0x45, + 0x50, 0x58, 0x07, 0x07, 0x0D, 0x0E, 0x10, 0x50, + 0x06, 0x42, 0x40, 0x44, 0x79, 0x06, 0x06, 0x0C, + 0x08, 0x08, 0x07, 0x36, 0x4C, 0xE5, 0x42, 0x55, + 0x03, 0x0F, 0x12, 0x06, 0x07, 0x3C, 0x4B, 0x3D, + 0x01, 0xF8, 0x08, 0x0E, 0x0A, 0x69, 0xAC, 0x0C, + 0x0A, 0x27, 0xBB, 0x36, 0x76, 0xC0, 0x04, 0x08, + 0x08, 0xED, 0xEE, 0x68, 0x5F, 0xB2, 0x3B, 0x52, + 0xAC, 0x4F, 0x6F, 0x2D, 0x16, 0x08, 0x59, 0x04, + 0x13, 0x0E, 0x14, 0x17, 0x16, 0x2E, 0x08, 0x0D, + 0x11, 0x14, 0x0D, 0x06, 0x04, 0x08, 0x25, 0x8E, + 0x0E, 0x14, 0x25, 0x9B, 0x1C, 0x16, 0x78, 0x06, + 0x04, 0x03, 0x79, 0x8C, 0x0B, 0xC8, 0x48 +}; + +unsigned char linux_logo[] __initdata = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x22, 0x23, 0x24, 0x24, + 0x25, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x23, 0x23, + 0x23, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x26, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x26, 0x28, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x28, 0x28, 0x28, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x2C, 0x29, 0x29, 0x29, 0x28, + 0x28, 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2A, 0x2A, + 0x2A, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2D, 0x2E, 0x2F, 0x27, + 0x27, 0x26, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x28, + 0x28, 0x29, 0x29, 0x29, 0x29, 0x2C, 0x2C, 0x29, + 0x29, 0x29, 0x28, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x30, 0x31, 0x32, + 0x27, 0x27, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, + 0x20, 0x20, 0x2B, 0x2A, 0x28, 0x29, 0x29, 0x29, + 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x28, 0x2A, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x27, 0x27, 0x33, 0x25, 0x25, 0x24, 0x24, + 0x24, 0x24, 0x23, 0x21, 0x20, 0x20, 0x2B, 0x2A, + 0x28, 0x29, 0x29, 0x37, 0x2C, 0x2C, 0x29, 0x28, + 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2A, 0x2B, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x32, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x25, 0x24, 0x23, 0x21, + 0x20, 0x2B, 0x2A, 0x29, 0x29, 0x2C, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x38, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x23, 0x23, 0x24, 0x24, + 0x25, 0x25, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x24, 0x22, 0x20, 0x20, 0x2A, 0x28, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x23, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x21, 0x22, 0x24, 0x20, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x3A, 0x3B, 0x22, 0x20, 0x2A, 0x28, + 0x29, 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x20, 0x21, 0x22, 0x22, 0x23, 0x24, 0x27, + 0x27, 0x27, 0x3C, 0x36, 0x3C, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x3D, 0x3E, 0x32, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x39, 0x3F, 0x3F, + 0x39, 0x2C, 0x20, 0x20, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x40, 0x40, 0x41, 0x22, 0x20, + 0x2A, 0x28, 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x2A, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, + 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x22, 0x27, + 0x27, 0x3C, 0x3C, 0x3D, 0x42, 0x3C, 0x27, 0x27, + 0x3C, 0x27, 0x3C, 0x43, 0x44, 0x36, 0x42, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x28, 0x29, 0x2C, + 0x2C, 0x45, 0x20, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x46, 0x40, 0x47, 0x40, 0x47, 0x3A, 0x40, + 0x22, 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x2C, 0x29, + 0x28, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x20, 0x27, + 0x27, 0x44, 0x28, 0x24, 0x27, 0x2F, 0x3C, 0x27, + 0x27, 0x38, 0x24, 0x2C, 0x2C, 0x48, 0x49, 0x36, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x29, 0x29, + 0x4A, 0x20, 0x3A, 0x40, 0x47, 0x40, 0x47, 0x40, + 0x40, 0x47, 0x40, 0x40, 0x39, 0x39, 0x39, 0x4A, + 0x25, 0x24, 0x22, 0x2B, 0x28, 0x29, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x21, 0x20, 0x2B, 0x2A, 0x27, + 0x3D, 0x4B, 0x48, 0x4C, 0x2B, 0x3C, 0x27, 0x3C, + 0x3C, 0x23, 0x4D, 0x4E, 0x4F, 0x50, 0x33, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x39, 0x3F, 0x39, + 0x51, 0x20, 0x39, 0x39, 0x47, 0x40, 0x4D, 0x4D, + 0x40, 0x52, 0x4D, 0x40, 0x47, 0x40, 0x39, 0x39, + 0x53, 0x54, 0x25, 0x24, 0x20, 0x2A, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x2A, 0x2B, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x21, 0x20, 0x2B, 0x28, 0x2A, 0x20, 0x27, + 0x36, 0x4F, 0x55, 0x48, 0x56, 0x3D, 0x3C, 0x3C, + 0x32, 0x57, 0x56, 0x58, 0x49, 0x56, 0x56, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x20, 0x20, + 0x41, 0x39, 0x39, 0x3A, 0x59, 0x5A, 0x59, 0x5B, + 0x5C, 0x3A, 0x4D, 0x5D, 0x57, 0x39, 0x39, 0x4A, + 0x5E, 0x33, 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, + 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, + 0x20, 0x2B, 0x2A, 0x2A, 0x20, 0x22, 0x22, 0x27, + 0x5F, 0x2D, 0x3C, 0x60, 0x56, 0x54, 0x61, 0x49, + 0x35, 0x56, 0x34, 0x27, 0x62, 0x27, 0x56, 0x39, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x63, 0x54, + 0x40, 0x64, 0x65, 0x66, 0x67, 0x67, 0x68, 0x5F, + 0x2E, 0x69, 0x6A, 0x67, 0x5F, 0x3A, 0x39, 0x2C, + 0x53, 0x23, 0x25, 0x54, 0x33, 0x25, 0x23, 0x20, + 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, + 0x2B, 0x2A, 0x20, 0x22, 0x22, 0x21, 0x2B, 0x27, + 0x62, 0x36, 0x27, 0x33, 0x6B, 0x54, 0x3D, 0x3C, + 0x49, 0x57, 0x27, 0x27, 0x27, 0x27, 0x56, 0x57, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x6C, 0x31, 0x6D, + 0x64, 0x51, 0x6E, 0x2E, 0x2E, 0x6F, 0x5A, 0x70, + 0x70, 0x71, 0x72, 0x67, 0x67, 0x69, 0x73, 0x46, + 0x4A, 0x2A, 0x21, 0x25, 0x33, 0x54, 0x33, 0x24, + 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, + 0x2B, 0x22, 0x22, 0x22, 0x2B, 0x28, 0x2A, 0x27, + 0x27, 0x39, 0x3C, 0x3D, 0x45, 0x74, 0x75, 0x76, + 0x76, 0x45, 0x27, 0x27, 0x27, 0x27, 0x56, 0x77, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x78, 0x78, 0x5E, + 0x79, 0x7A, 0x7B, 0x6E, 0x5A, 0x5A, 0x70, 0x7C, + 0x70, 0x5B, 0x7D, 0x5A, 0x66, 0x7E, 0x7F, 0x79, + 0x48, 0x6B, 0x2C, 0x20, 0x24, 0x33, 0x54, 0x33, + 0x24, 0x21, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x21, + 0x22, 0x22, 0x20, 0x28, 0x2B, 0x20, 0x22, 0x27, + 0x27, 0x80, 0x27, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x74, 0x85, 0x84, 0x27, 0x3C, 0x4F, 0x4F, 0x66, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x23, 0x5E, + 0x64, 0x86, 0x79, 0x73, 0x87, 0x88, 0x7C, 0x5A, + 0x5A, 0x71, 0x7D, 0x71, 0x89, 0x79, 0x8A, 0x8A, + 0x51, 0x8B, 0x48, 0x39, 0x2A, 0x22, 0x33, 0x54, + 0x33, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x2C, 0x29, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x22, 0x23, + 0x21, 0x2A, 0x2A, 0x20, 0x21, 0x23, 0x25, 0x27, + 0x27, 0x55, 0x8C, 0x8D, 0x8E, 0x83, 0x8F, 0x90, + 0x91, 0x92, 0x92, 0x85, 0x85, 0x93, 0x51, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0x29, 0x51, + 0x79, 0x79, 0x94, 0x89, 0x89, 0x89, 0x5A, 0x95, + 0x64, 0x88, 0x96, 0x97, 0x7A, 0x73, 0x98, 0x98, + 0x99, 0x50, 0x50, 0x48, 0x6B, 0x28, 0x21, 0x25, + 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2B, 0x20, 0x22, 0x22, 0x20, + 0x2B, 0x2B, 0x20, 0x22, 0x24, 0x25, 0x33, 0x27, + 0x27, 0x9A, 0x9B, 0x9C, 0x9D, 0x83, 0x9E, 0x85, + 0x9F, 0x92, 0x85, 0x85, 0x85, 0x85, 0x92, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xA1, 0x47, 0xA2, + 0xA2, 0x94, 0xA3, 0x94, 0x95, 0x95, 0x73, 0x73, + 0x95, 0x87, 0xA4, 0x5B, 0x97, 0x7B, 0x88, 0x98, + 0xA2, 0x50, 0x48, 0x48, 0x48, 0x8B, 0x29, 0x20, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x2B, 0x2B, + 0x20, 0x21, 0x23, 0x24, 0x25, 0x25, 0x33, 0x27, + 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x8F, 0x90, 0x90, + 0x9F, 0x90, 0x85, 0x90, 0x85, 0x74, 0xAA, 0x81, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xAB, 0x40, 0xAC, + 0x79, 0xA3, 0x89, 0xAD, 0x95, 0x6F, 0xAE, 0xAE, + 0xAE, 0x5B, 0x59, 0x88, 0x7B, 0x89, 0x79, 0xAF, + 0xA2, 0x6B, 0x48, 0x48, 0x48, 0x48, 0x50, 0x2C, + 0x20, 0x24, 0x33, 0x54, 0x25, 0x22, 0x2A, 0x2A, + 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x23, 0x22, 0x2B, 0x20, 0x20, + 0x22, 0x23, 0x24, 0x25, 0x24, 0x24, 0x22, 0x27, + 0xB0, 0x8C, 0xAA, 0xB1, 0xB2, 0x84, 0x85, 0x9F, + 0x85, 0x85, 0x85, 0xB3, 0xB4, 0xAA, 0xAA, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0xB5, + 0xA3, 0xA3, 0xAC, 0x5D, 0xB6, 0xAE, 0xB7, 0x69, + 0x73, 0x5B, 0x88, 0x89, 0x95, 0x73, 0x99, 0x99, + 0x59, 0x2A, 0x39, 0x48, 0x48, 0x50, 0x48, 0x50, + 0x2C, 0x20, 0x24, 0x33, 0x54, 0x25, 0x21, 0x20, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x23, 0x21, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x24, 0x24, 0x23, 0x22, 0x20, 0x2A, 0x27, + 0x27, 0xB0, 0x8C, 0xA9, 0xB2, 0x9E, 0x91, 0x85, + 0x85, 0x93, 0xB8, 0x75, 0xAA, 0xA7, 0x8C, 0x27, + 0x27, 0x27, 0x33, 0x3C, 0x27, 0x27, 0x2C, 0x7B, + 0x55, 0x79, 0xA3, 0x5D, 0xB9, 0x43, 0x7F, 0x7E, + 0x5F, 0x5A, 0x5A, 0x95, 0x64, 0x73, 0x58, 0x64, + 0x5C, 0x25, 0x2B, 0x3F, 0x48, 0x48, 0x8B, 0x48, + 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x24, 0x22, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x23, 0x21, 0x20, 0x20, 0x20, 0x21, 0x22, + 0x24, 0x23, 0x22, 0x21, 0x2B, 0x20, 0x54, 0x27, + 0x27, 0x8B, 0x81, 0xA5, 0x93, 0x93, 0x74, 0xA5, + 0xBA, 0x75, 0xBB, 0xBC, 0xB4, 0x6D, 0x50, 0x6B, + 0x27, 0x27, 0x30, 0x33, 0x49, 0x27, 0x27, 0x5E, + 0x6F, 0x73, 0x94, 0xBD, 0x4E, 0x5D, 0x7F, 0x7F, + 0xB7, 0x68, 0x73, 0x6E, 0xB7, 0x7F, 0x95, 0x97, + 0x47, 0x63, 0x25, 0x20, 0x3F, 0x48, 0x8B, 0x8B, + 0x48, 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x25, + 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x21, + 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, + 0x22, 0x21, 0x20, 0x2A, 0x33, 0x30, 0x30, 0x27, + 0x27, 0x50, 0xBE, 0xBF, 0x9A, 0xB3, 0x9B, 0xBB, + 0xBB, 0xC0, 0x8C, 0xC1, 0x8B, 0xC2, 0x47, 0x8B, + 0x27, 0x27, 0x38, 0x63, 0x63, 0x27, 0x27, 0xC3, + 0xB5, 0x95, 0x72, 0x95, 0x6F, 0x69, 0x7E, 0x66, + 0x7E, 0x7F, 0x6E, 0x7E, 0x95, 0x95, 0x73, 0x70, + 0x30, 0x30, 0x30, 0x33, 0x20, 0x3F, 0x48, 0x8B, + 0x6B, 0x48, 0x50, 0x29, 0x21, 0x33, 0x54, 0x33, + 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x21, 0x21, 0x23, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, 0x22, + 0x20, 0x2B, 0x21, 0xC4, 0x30, 0x60, 0x30, 0x27, + 0x27, 0xC5, 0x8B, 0x39, 0xC6, 0xC7, 0xA6, 0xA6, + 0xC8, 0x9A, 0x3B, 0x39, 0x50, 0x56, 0x56, 0x4F, + 0x33, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x48, + 0x59, 0x94, 0x73, 0xAE, 0xB7, 0xB7, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x5A, 0x70, 0x7C, 0x71, 0xC3, + 0x63, 0x30, 0x60, 0x78, 0x54, 0x20, 0x6B, 0x48, + 0x6B, 0x6B, 0x50, 0x50, 0x29, 0x22, 0x33, 0x33, + 0x2A, 0x2B, 0x20, 0x20, 0x21, 0x22, 0x22, 0x22, + 0x21, 0x20, 0x20, 0x20, 0x24, 0x24, 0x20, 0x20, + 0x2B, 0x24, 0x30, 0x60, 0x60, 0x30, 0xAB, 0x27, + 0x27, 0x40, 0x4C, 0x50, 0x39, 0x87, 0xC3, 0x53, + 0x37, 0x48, 0x37, 0x48, 0xC9, 0x56, 0xB9, 0x56, + 0xCA, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x3C, + 0x51, 0x5A, 0x6E, 0xB7, 0xB7, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7F, 0xB7, 0x5A, 0x7C, 0x5B, 0x37, + 0x23, 0x63, 0x31, 0x6C, 0xCB, 0x63, 0x20, 0x6B, + 0x50, 0x3F, 0x39, 0x50, 0x8B, 0x28, 0x24, 0x24, + 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x22, 0x22, 0x21, + 0x20, 0x20, 0x20, 0x23, 0x23, 0x20, 0x20, 0x2B, + 0x33, 0x78, 0xCB, 0x60, 0x30, 0x22, 0x3D, 0x27, + 0x2F, 0x56, 0x4E, 0x8B, 0x6B, 0x39, 0x48, 0x8B, + 0x6B, 0x8B, 0x80, 0xC9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x34, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x48, 0xB5, 0xB7, 0xB7, 0x7E, 0x7E, 0x2E, 0x7E, + 0x7E, 0x7E, 0x7F, 0x7C, 0x65, 0x71, 0x3A, 0x48, + 0x2C, 0x24, 0x30, 0x6C, 0x34, 0x6C, 0xC4, 0x20, + 0x8B, 0x50, 0x39, 0x39, 0x48, 0x6B, 0x2B, 0x22, + 0x2B, 0x20, 0x21, 0x22, 0x23, 0x23, 0x22, 0x21, + 0x20, 0x2B, 0x23, 0x22, 0x20, 0x2B, 0x2B, 0x54, + 0x60, 0x31, 0xCB, 0x54, 0x20, 0x3D, 0x36, 0x27, + 0x4E, 0xB9, 0x56, 0x56, 0x8B, 0x6B, 0x50, 0x6B, + 0x40, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x56, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x7B, 0x6E, 0xB7, 0xB7, 0xB7, 0x7E, 0x7F, + 0xB7, 0xB7, 0x7F, 0x7E, 0x6F, 0x5B, 0x29, 0x2C, + 0x48, 0x39, 0x24, 0x60, 0x58, 0xAF, 0xCC, 0x63, + 0x20, 0x8B, 0x8B, 0x39, 0x39, 0x48, 0x3F, 0x28, + 0x20, 0x20, 0x22, 0x23, 0x23, 0x23, 0x22, 0x20, + 0x2B, 0x22, 0x22, 0x2B, 0x2B, 0x20, 0x54, 0xCB, + 0x31, 0xCB, 0x25, 0x20, 0x27, 0x27, 0x27, 0x48, + 0xB9, 0x56, 0xB9, 0x56, 0x4F, 0x48, 0x47, 0x57, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0x62, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x48, 0x6F, 0x69, 0xB7, 0xB7, 0xB7, 0x7F, + 0xB7, 0xB7, 0xB7, 0x73, 0x59, 0x50, 0x29, 0x2B, + 0x28, 0x8B, 0x39, 0x25, 0x31, 0x55, 0xB6, 0x34, + 0x63, 0x2B, 0x48, 0x6B, 0x2C, 0x39, 0x47, 0x6B, + 0x22, 0x22, 0x23, 0x24, 0x23, 0x22, 0x20, 0x2B, + 0x20, 0x22, 0x2A, 0x2B, 0x20, 0x33, 0xCB, 0x31, + 0x78, 0x24, 0x21, 0xCD, 0x27, 0x27, 0x27, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0xC9, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x41, 0x64, 0xB7, 0xB7, 0xB7, 0x7F, + 0x68, 0xB7, 0xAE, 0xA3, 0x23, 0x39, 0x8B, 0x2A, + 0x20, 0x20, 0x39, 0x6B, 0x25, 0xCC, 0x43, 0x43, + 0x34, 0x63, 0x2A, 0x48, 0x3F, 0x39, 0x6B, 0x6B, + 0x24, 0x23, 0x24, 0x24, 0x23, 0x21, 0x2B, 0x2B, + 0x22, 0x2B, 0x2B, 0x20, 0x24, 0x78, 0x31, 0x30, + 0x23, 0x21, 0x21, 0x27, 0x27, 0x27, 0x80, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x3C, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xCE, 0x8A, 0xAE, 0x6F, 0xB7, + 0x6F, 0x89, 0x71, 0x78, 0x63, 0x23, 0x39, 0x6B, + 0x2B, 0x20, 0x20, 0x2C, 0x6B, 0x25, 0x34, 0x42, + 0x42, 0x34, 0x54, 0x29, 0x48, 0x3F, 0x39, 0x3F, + 0x25, 0x24, 0x25, 0x24, 0x22, 0x20, 0x2A, 0x21, + 0x2B, 0x2A, 0x20, 0x22, 0x30, 0x60, 0x30, 0x22, + 0x21, 0x22, 0x27, 0x27, 0x27, 0x2D, 0x4C, 0x56, + 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0x56, 0x2E, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x40, 0x97, 0x95, 0x5A, 0x71, + 0x7C, 0xCE, 0x40, 0x60, 0x31, 0x30, 0x23, 0x3F, + 0x3F, 0x20, 0x20, 0x20, 0x29, 0x8B, 0x33, 0x58, + 0x66, 0x43, 0xCC, 0x25, 0x39, 0x50, 0x6B, 0x2C, + 0x33, 0x25, 0x25, 0x23, 0x20, 0x2A, 0x2B, 0x20, + 0x2A, 0x2B, 0x22, 0x54, 0x30, 0x30, 0x24, 0x22, + 0x21, 0x27, 0x27, 0x27, 0x27, 0xAF, 0x29, 0x4E, + 0x4F, 0xB9, 0x56, 0xB9, 0x4D, 0x4D, 0x77, 0xC9, + 0xB9, 0xB9, 0xB9, 0x56, 0xC9, 0x4D, 0x4D, 0x80, + 0x4C, 0x40, 0xC9, 0x4D, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0xCF, 0x97, 0x97, 0xCE, + 0x86, 0xD0, 0x54, 0x6C, 0x58, 0x34, 0x60, 0x23, + 0x6B, 0x39, 0x20, 0x20, 0x20, 0x28, 0x6B, 0x54, + 0xD1, 0x66, 0xB6, 0x60, 0x22, 0x6B, 0x8B, 0x2C, + 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, 0x20, 0x28, + 0x2B, 0x20, 0x25, 0xC4, 0x30, 0x25, 0x22, 0x21, + 0x26, 0x27, 0x27, 0x27, 0x27, 0x20, 0x4B, 0x52, + 0x80, 0x4F, 0xB9, 0x56, 0xB9, 0x80, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x4D, 0x80, 0x50, 0x48, + 0x50, 0x50, 0x50, 0x56, 0x3D, 0x27, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x3C, 0x46, 0xC3, 0x86, 0x86, + 0xD0, 0x39, 0x24, 0x6C, 0xD1, 0x43, 0x43, 0x6C, + 0x24, 0x6B, 0x2C, 0x20, 0x20, 0x20, 0x29, 0x39, + 0x63, 0xD1, 0x42, 0x55, 0xC4, 0x2B, 0x8B, 0x39, + 0x54, 0x25, 0x24, 0x20, 0x2A, 0x2A, 0x28, 0x28, + 0x20, 0x22, 0x54, 0x63, 0x25, 0x24, 0x22, 0x22, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x77, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xC9, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x4F, + 0x77, 0x47, 0x8B, 0x40, 0x56, 0x27, 0x27, 0x49, + 0x2D, 0x27, 0x27, 0x27, 0x39, 0x40, 0x39, 0x39, + 0x28, 0x3F, 0x39, 0x33, 0x58, 0x66, 0x35, 0x2E, + 0x58, 0x24, 0x8B, 0x29, 0x20, 0x20, 0x20, 0x39, + 0x29, 0x30, 0x55, 0xB6, 0xCC, 0x25, 0x29, 0x39, + 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2A, 0x29, 0x2B, + 0x22, 0x24, 0x54, 0x33, 0x25, 0x22, 0x2B, 0x54, + 0x27, 0x27, 0x62, 0x27, 0x30, 0x80, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4D, 0x8B, 0x77, 0x36, 0x27, 0x27, + 0x3C, 0x2F, 0x27, 0x27, 0x39, 0x39, 0x39, 0x47, + 0x20, 0x2B, 0x2C, 0x39, 0x33, 0xB6, 0x35, 0x35, + 0x35, 0xAF, 0x24, 0x48, 0x2A, 0x20, 0x20, 0x20, + 0x8B, 0x2B, 0x78, 0xAF, 0x58, 0x30, 0x21, 0x28, + 0x33, 0x25, 0x21, 0x28, 0x29, 0x29, 0x28, 0x20, + 0x24, 0x33, 0x54, 0x33, 0x23, 0x20, 0x24, 0xD2, + 0x27, 0x49, 0x27, 0x27, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0xC9, 0x50, 0x56, 0x27, 0x27, + 0x3D, 0x38, 0x3D, 0x27, 0x27, 0x47, 0x39, 0x39, + 0x28, 0x20, 0x20, 0x2A, 0x39, 0x54, 0x43, 0x35, + 0x35, 0x35, 0xAF, 0x23, 0x48, 0x2B, 0x20, 0x20, + 0x2B, 0x48, 0x22, 0x60, 0x34, 0xCB, 0x25, 0x21, + 0x33, 0x24, 0x2B, 0x29, 0x29, 0x29, 0x2B, 0x22, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x33, 0x27, + 0x27, 0x32, 0x27, 0x30, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0xC9, 0x4C, 0x36, 0x3C, + 0x62, 0x2F, 0x2E, 0x27, 0x27, 0x54, 0x47, 0x47, + 0x8B, 0x2B, 0x20, 0x20, 0x20, 0x3F, 0x54, 0x2E, + 0x35, 0x35, 0x35, 0x34, 0x21, 0x8B, 0x2A, 0x20, + 0x20, 0x2C, 0x6B, 0x25, 0x60, 0x60, 0x54, 0x23, + 0x25, 0x22, 0x2A, 0x2C, 0x29, 0x28, 0x20, 0x24, + 0x54, 0x63, 0x54, 0x24, 0x2B, 0x22, 0x24, 0x27, + 0x36, 0x27, 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x4C, 0x36, + 0x66, 0xD3, 0x27, 0x2F, 0x27, 0x54, 0x54, 0x27, + 0x26, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x63, + 0x35, 0x35, 0x35, 0x62, 0xCB, 0x2A, 0x3F, 0x28, + 0x2B, 0x2A, 0x50, 0x29, 0x33, 0x30, 0x54, 0x25, + 0x24, 0x20, 0x29, 0x2C, 0x2C, 0x2A, 0x21, 0x33, + 0xC4, 0xC4, 0x33, 0x21, 0x29, 0x22, 0x27, 0x27, + 0x99, 0x27, 0x31, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x3D, + 0x3D, 0x3C, 0x3C, 0x55, 0x54, 0x54, 0x54, 0x20, + 0x27, 0x2C, 0x39, 0x20, 0x20, 0x20, 0x20, 0x48, + 0x30, 0x62, 0x35, 0x35, 0x42, 0x54, 0x39, 0x39, + 0x2C, 0x28, 0x3F, 0x8B, 0x20, 0x33, 0x54, 0x24, + 0x22, 0x2B, 0x2C, 0x2C, 0x2C, 0x2B, 0x24, 0x54, + 0x30, 0xC4, 0x25, 0x2B, 0x28, 0x2B, 0x27, 0x3D, + 0x27, 0x27, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x27, + 0x20, 0x20, 0x20, 0x54, 0x54, 0x54, 0x54, 0x20, + 0x20, 0x2D, 0x2D, 0x29, 0x20, 0x20, 0x20, 0x20, + 0x48, 0x60, 0x66, 0x35, 0x62, 0x34, 0x22, 0x2C, + 0x2C, 0x3F, 0x6B, 0x48, 0x2C, 0x22, 0x23, 0x23, + 0x20, 0x2A, 0x2C, 0x29, 0x29, 0x20, 0x25, 0xC4, + 0x30, 0x54, 0x22, 0x29, 0x28, 0xD2, 0x27, 0x35, + 0x27, 0x49, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x4F, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x40, 0x20, + 0x20, 0x54, 0x54, 0x54, 0x20, 0x20, 0x20, 0x20, + 0x2D, 0x2D, 0x2D, 0x49, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6B, 0x6C, 0x42, 0x2E, 0xB6, 0x54, 0x28, + 0x29, 0x2C, 0x6B, 0x48, 0x3F, 0x2A, 0x20, 0x22, + 0x2B, 0x28, 0x2C, 0x28, 0x29, 0x20, 0x33, 0x30, + 0x30, 0x54, 0x20, 0x2C, 0x29, 0x27, 0x27, 0x3D, + 0x27, 0x40, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x63, 0x56, 0x54, 0x54, + 0x54, 0x54, 0x20, 0xD3, 0x45, 0x51, 0x51, 0x49, + 0x7C, 0x2D, 0x2D, 0x49, 0x49, 0x20, 0x20, 0x20, + 0x20, 0x2A, 0x2A, 0xCC, 0xB6, 0x8A, 0x60, 0x22, + 0x28, 0x29, 0x3F, 0x6B, 0x39, 0x29, 0x2B, 0x20, + 0x28, 0x2C, 0x28, 0x2A, 0x2A, 0x24, 0xC4, 0x30, + 0xC4, 0x33, 0x2B, 0x39, 0xCD, 0x27, 0x3C, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x63, 0x63, 0x49, 0x2D, 0x20, + 0x20, 0x2D, 0xD3, 0x49, 0x66, 0x2D, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x49, 0x8B, 0x2B, 0x20, + 0x20, 0x20, 0x39, 0x23, 0x6C, 0xAF, 0xCB, 0x23, + 0x28, 0x28, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x20, + 0x29, 0x39, 0x2B, 0x2B, 0x2B, 0x25, 0x78, 0xC4, + 0x63, 0x23, 0x29, 0x39, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x49, 0x2D, 0x49, 0x2D, 0x49, 0x2D, 0x2D, 0x2D, + 0x49, 0x49, 0x35, 0x49, 0x2D, 0x2D, 0x39, 0x28, + 0x20, 0x20, 0x2A, 0x28, 0x33, 0x60, 0xC4, 0x22, + 0x2C, 0x2A, 0x2A, 0x22, 0x23, 0x22, 0x20, 0x21, + 0x2C, 0x29, 0x20, 0x2B, 0x2B, 0x54, 0x30, 0xC4, + 0x63, 0x22, 0x2C, 0x27, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x61, 0x49, 0x2D, 0x49, 0x49, 0x2D, 0x2D, 0x49, + 0x49, 0x49, 0x2F, 0x49, 0x2D, 0x78, 0x29, 0x28, + 0x2C, 0x2A, 0x2B, 0x39, 0x2B, 0x25, 0x33, 0x20, + 0x2C, 0x20, 0x2A, 0x24, 0x54, 0x54, 0x23, 0x23, + 0x2C, 0x2A, 0x22, 0x2B, 0x20, 0x63, 0x30, 0x63, + 0xC4, 0x21, 0x39, 0x27, 0x27, 0x27, 0x35, 0x36, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x2D, 0x49, 0x49, 0x49, + 0x49, 0x27, 0x27, 0x2D, 0x38, 0x27, 0x36, 0x36, + 0x49, 0x27, 0x49, 0x2D, 0x2D, 0x44, 0x24, 0x2B, + 0x20, 0x2C, 0x3F, 0x6B, 0x2A, 0x20, 0x21, 0x28, + 0x2C, 0x20, 0x2B, 0x24, 0x30, 0xCB, 0x63, 0x54, + 0x28, 0x20, 0x24, 0x2B, 0x23, 0x78, 0xC4, 0x63, + 0x63, 0x2B, 0x3F, 0x27, 0x27, 0x27, 0x38, 0x33, + 0x3D, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x63, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x3D, 0x3D, 0x27, 0x27, 0x27, 0x2D, + 0x49, 0x49, 0x49, 0x2D, 0x62, 0x5F, 0xC4, 0x20, + 0x22, 0x2A, 0x6B, 0x8B, 0x2C, 0x2B, 0x2A, 0x3F, + 0x3F, 0x2A, 0x21, 0x21, 0xCB, 0x58, 0x6C, 0x60, + 0x20, 0x23, 0x24, 0x2A, 0x25, 0x78, 0x63, 0x63, + 0x54, 0x2A, 0x28, 0x27, 0x27, 0x27, 0x27, 0x62, + 0x3C, 0xB9, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x49, 0x2D, 0x2D, + 0x2D, 0x3D, 0x2F, 0x3C, 0x2D, 0x3C, 0x27, 0x38, + 0x2D, 0x49, 0x2D, 0x2D, 0xD1, 0x43, 0x30, 0x20, + 0x24, 0x21, 0x21, 0x21, 0x2B, 0x2A, 0x29, 0x8B, + 0x6B, 0x29, 0x2B, 0x2A, 0x30, 0x55, 0x55, 0x34, + 0x22, 0x23, 0x24, 0x29, 0x54, 0x30, 0x63, 0x63, + 0x25, 0x29, 0x22, 0x3C, 0xA5, 0xD4, 0xD5, 0x27, + 0x31, 0x56, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x2D, 0x2E, + 0x3E, 0x27, 0x27, 0x27, 0x27, 0x27, 0x36, 0x44, + 0x3C, 0x27, 0x2D, 0xC4, 0x78, 0xCC, 0x54, 0x2B, + 0x25, 0x24, 0x63, 0x60, 0x63, 0x24, 0x2A, 0x6B, + 0x3F, 0x39, 0x28, 0x21, 0x33, 0xB6, 0x44, 0x58, + 0x22, 0x23, 0x24, 0x2A, 0x30, 0x30, 0x63, 0x63, + 0x24, 0x39, 0x22, 0xBB, 0x9C, 0xB2, 0x9D, 0xA8, + 0x27, 0x8B, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0xD6, 0xD6, 0xD7, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x32, + 0x3D, 0x27, 0x39, 0x33, 0xC4, 0xC4, 0x22, 0x28, + 0x25, 0x54, 0x30, 0xD1, 0xD1, 0x60, 0x23, 0x6B, + 0x3F, 0x39, 0x2C, 0x2B, 0x20, 0x58, 0x8A, 0x58, + 0x22, 0x23, 0x23, 0x2B, 0x78, 0x30, 0xC4, 0xC4, + 0x23, 0x29, 0xBB, 0xBB, 0xD8, 0xB2, 0x9D, 0xA9, + 0xA9, 0x3C, 0x60, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xD9, 0x85, 0x85, 0x85, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2D, + 0xA0, 0x83, 0x2C, 0x21, 0x30, 0x33, 0x29, 0x29, + 0x21, 0x33, 0x54, 0x42, 0x66, 0x55, 0xC4, 0x29, + 0x8B, 0x2C, 0x39, 0x28, 0x29, 0x31, 0x44, 0x58, + 0x23, 0x23, 0x21, 0x20, 0x30, 0xC4, 0xC4, 0x30, + 0x21, 0x20, 0xBB, 0xBC, 0xDA, 0xDB, 0xDC, 0xB2, + 0x83, 0xB4, 0x3C, 0x2F, 0xB9, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0xA7, 0xD4, 0x85, 0x82, + 0x3C, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x61, + 0x9E, 0x90, 0xDD, 0x21, 0x33, 0x25, 0x2C, 0x39, + 0x2A, 0x24, 0x24, 0x42, 0x62, 0x43, 0x34, 0x22, + 0x50, 0x39, 0x2C, 0x2C, 0x2A, 0x54, 0xD1, 0x58, + 0x22, 0x22, 0x2B, 0x22, 0x30, 0xC4, 0x30, 0x60, + 0x20, 0xDE, 0xBB, 0xD9, 0x84, 0x84, 0xDF, 0xA9, + 0xDB, 0xDB, 0x61, 0x27, 0x38, 0x4D, 0x56, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0x8D, 0xD9, 0xD5, 0xA6, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0xBB, + 0x85, 0xDB, 0xDD, 0x21, 0x22, 0x22, 0x3F, 0x39, + 0x2C, 0x2B, 0x25, 0x34, 0x62, 0x66, 0xD1, 0xC4, + 0x6B, 0x39, 0x2C, 0x39, 0x29, 0x21, 0x58, 0xCC, + 0x22, 0x21, 0x29, 0x23, 0x30, 0x30, 0x30, 0x5E, + 0x82, 0xBB, 0xE0, 0xB1, 0xE1, 0x9C, 0xD4, 0xDC, + 0x9D, 0xA9, 0xE2, 0x27, 0x27, 0x27, 0x4D, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4C, 0x48, 0xA8, 0xA8, 0xE3, 0x8C, + 0xC6, 0x3C, 0x27, 0x27, 0x27, 0xE4, 0xA6, 0xE5, + 0x83, 0xA9, 0xE6, 0xAF, 0x54, 0x2B, 0x8B, 0x39, + 0x39, 0x29, 0x20, 0x54, 0x42, 0x42, 0xB6, 0xCC, + 0x2A, 0x29, 0x39, 0x39, 0x2C, 0x2C, 0xCC, 0xCC, + 0x22, 0x20, 0x39, 0xE7, 0xC0, 0xD9, 0xA7, 0xBC, + 0x8D, 0xAA, 0x9C, 0xE8, 0x9C, 0x9D, 0xD4, 0xD4, + 0xD8, 0xA9, 0x84, 0xC7, 0x27, 0x27, 0x27, 0x2A, + 0x56, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x48, 0x50, 0xAA, 0xE3, 0xE3, 0xC0, + 0xA6, 0x9A, 0xBA, 0xC8, 0x9A, 0xDE, 0x9B, 0xD5, + 0xE8, 0xD8, 0xD5, 0x2E, 0x58, 0x33, 0x6B, 0x39, + 0x2C, 0x39, 0x29, 0x28, 0xD1, 0x43, 0xB6, 0xAF, + 0x23, 0x28, 0x2C, 0x39, 0x39, 0x8B, 0x30, 0x31, + 0x21, 0x20, 0x3F, 0xBB, 0xDF, 0xDF, 0xD5, 0xA8, + 0xD5, 0x9C, 0x8E, 0xB2, 0x9D, 0xE9, 0xD4, 0xD8, + 0x90, 0xB2, 0xA9, 0x8F, 0x27, 0x27, 0x27, 0x27, + 0x2F, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0xB9, 0x48, 0x48, 0x75, 0xE3, 0xAA, 0xAA, + 0xC0, 0xB4, 0xB4, 0xB4, 0x75, 0x9B, 0xD9, 0x83, + 0x9D, 0x90, 0xDF, 0xDD, 0x8A, 0x31, 0x4B, 0x2C, + 0x2C, 0x29, 0x2C, 0x3F, 0x6C, 0x55, 0xD1, 0x55, + 0x54, 0x29, 0x28, 0x39, 0x39, 0x6B, 0x24, 0x60, + 0x20, 0x2B, 0x3F, 0xA7, 0xB1, 0x9D, 0xA9, 0x8E, + 0xE5, 0xE5, 0xDF, 0xE0, 0xA9, 0x9D, 0xDF, 0xDF, + 0xEA, 0x9D, 0xB2, 0x84, 0xAA, 0x27, 0x27, 0x27, + 0x27, 0x35, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x48, 0x48, 0xA6, 0x9B, 0xE3, 0xAA, + 0xAA, 0x9B, 0x9B, 0x9B, 0xAA, 0xE3, 0xD5, 0xD4, + 0x9D, 0xA9, 0xA9, 0x9D, 0xEB, 0xAF, 0x23, 0x28, + 0x2C, 0x29, 0x28, 0x39, 0x54, 0xCC, 0xAF, 0x55, + 0x30, 0x29, 0x2B, 0x2C, 0x39, 0x39, 0x2B, 0xC4, + 0x2B, 0x29, 0x39, 0xA7, 0x8E, 0x9D, 0x83, 0xE5, + 0xB1, 0xDB, 0xDC, 0xE0, 0xDC, 0x84, 0xE9, 0x84, + 0x83, 0xD4, 0xEC, 0x83, 0x8F, 0xE4, 0x27, 0x27, + 0x27, 0x27, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x40, 0x50, 0x9A, 0x75, 0xE3, 0xE3, + 0xE3, 0xD9, 0x8D, 0xAA, 0xD9, 0xA8, 0xB2, 0xDC, + 0xB2, 0x8D, 0x84, 0xEA, 0xB1, 0xEB, 0x54, 0x29, + 0x28, 0x2C, 0x2A, 0x28, 0x2B, 0x78, 0xCC, 0x58, + 0xCB, 0x20, 0x20, 0x29, 0x39, 0x39, 0x2C, 0x25, + 0x29, 0x2C, 0x39, 0xBB, 0xD9, 0xD9, 0x9D, 0x9D, + 0xB2, 0xB1, 0xD4, 0xDB, 0xB1, 0x9D, 0xD4, 0xEA, + 0xB1, 0x8D, 0xD8, 0x8E, 0x8F, 0xAA, 0x27, 0x27, + 0x27, 0x3D, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x47, 0xE4, 0xA6, 0x75, 0xAA, 0xA8, + 0x9C, 0x9C, 0xE1, 0x9C, 0x9C, 0x8E, 0xD8, 0x9D, + 0xA9, 0xDB, 0xA9, 0xDC, 0xD8, 0xDA, 0xD4, 0x2B, + 0x20, 0x2C, 0x28, 0x2A, 0x28, 0x63, 0x31, 0x58, + 0xCB, 0x24, 0x20, 0x2B, 0x2C, 0x39, 0x6B, 0x21, + 0x39, 0x6B, 0x2C, 0xC0, 0xE0, 0xB1, 0xB2, 0x9D, + 0x8E, 0xD8, 0xE0, 0xD9, 0x84, 0xDB, 0xD8, 0xB1, + 0x8E, 0xB2, 0xE2, 0x9C, 0x83, 0x9E, 0xBC, 0x3D, + 0xD3, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0x4F, 0x27, 0x61, 0xA6, 0x9B, 0xE3, 0xA9, + 0xE9, 0xD4, 0xDA, 0xDB, 0x8E, 0xE1, 0xE9, 0x8E, + 0xD4, 0xA8, 0xE0, 0x84, 0xE8, 0xB1, 0xDC, 0x9D, + 0x20, 0x29, 0x29, 0x2B, 0x2C, 0x54, 0x78, 0xCC, + 0x78, 0x33, 0x2A, 0x20, 0x29, 0x39, 0x50, 0x2A, + 0x6B, 0x8B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xA9, + 0xB2, 0xDC, 0x8E, 0xDC, 0xE1, 0xDA, 0xA9, 0x8E, + 0xEA, 0xE2, 0x83, 0xE8, 0x8E, 0x83, 0xE2, 0xED, + 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0xC9, 0x27, 0x27, 0xE4, 0xA6, 0x9B, 0xD5, 0xA8, + 0xD4, 0xB2, 0xD8, 0xDA, 0xD9, 0xE8, 0xE9, 0xE8, + 0xD8, 0xB1, 0xDA, 0xB2, 0xE9, 0x8E, 0xEC, 0xDA, + 0x22, 0x20, 0x39, 0x2B, 0x39, 0x24, 0xC4, 0x30, + 0x30, 0x54, 0x22, 0x29, 0x29, 0x39, 0x48, 0x2C, + 0x39, 0x6B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xB2, + 0xB2, 0x8E, 0xA9, 0xD8, 0xDA, 0xB1, 0xA9, 0xDA, + 0x9C, 0xDC, 0x8E, 0xD4, 0xE8, 0xE8, 0x8F, 0x9B, + 0x4F, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x6B, + 0x27, 0x27, 0x27, 0xD7, 0xDE, 0xAA, 0xE3, 0xA8, + 0xB2, 0xD5, 0xE5, 0x90, 0xE2, 0xA9, 0xE9, 0xB2, + 0xDA, 0xB2, 0xE1, 0xB2, 0xE9, 0x8E, 0xDA, 0xDF, + 0x78, 0x2A, 0x2C, 0x2A, 0x6B, 0x28, 0x23, 0x54, + 0x63, 0xC4, 0x33, 0x28, 0x2C, 0x39, 0x47, 0x39, + 0x28, 0x2C, 0x29, 0xBB, 0x8D, 0x83, 0xE9, 0xD4, + 0xB2, 0xE9, 0xE9, 0xE8, 0xD4, 0xD8, 0xD4, 0xA9, + 0xDA, 0xB2, 0xE9, 0xA8, 0xB2, 0xA8, 0xD5, 0xAA, + 0xC6, 0x56, 0x56, 0x56, 0x56, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0xC9, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0x9B, 0xE3, 0x8E, + 0x9D, 0x8E, 0xB2, 0xE8, 0xE8, 0x8E, 0xB2, 0xDA, + 0xB2, 0x8E, 0xEC, 0xB2, 0x8E, 0xB2, 0xBB, 0x58, + 0xAF, 0x33, 0x50, 0x39, 0x6B, 0x39, 0x29, 0x20, + 0x33, 0x30, 0x78, 0x23, 0x6B, 0x6B, 0x48, 0x6B, + 0x2B, 0x2A, 0x29, 0xBB, 0xE5, 0x9C, 0xB1, 0xB2, + 0xE5, 0x84, 0x8E, 0x9C, 0x84, 0xB2, 0xB2, 0x9D, + 0x84, 0xDF, 0xA9, 0x84, 0x8E, 0xA8, 0xE3, 0x9B, + 0xA6, 0xD7, 0x80, 0x4F, 0x56, 0x56, 0x56, 0x4F, + 0x4F, 0x4F, 0x4F, 0x2A, 0x2D, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0xAA, 0xD5, 0xA9, + 0x9D, 0xB2, 0x90, 0xEA, 0xE9, 0xE2, 0xE1, 0x8E, + 0xB2, 0x9D, 0x8E, 0xB1, 0xA7, 0xEE, 0x63, 0xD1, + 0x2E, 0xCC, 0x28, 0x48, 0x8B, 0x47, 0x6B, 0x28, + 0x23, 0x78, 0x6C, 0x54, 0x29, 0x50, 0x50, 0x6B, + 0x23, 0x20, 0xBB, 0xBC, 0xBB, 0x8D, 0xE3, 0xDF, + 0x9C, 0xA9, 0x8D, 0xA8, 0xD9, 0x90, 0x9D, 0xA9, + 0xDC, 0xA9, 0x83, 0xB2, 0xA9, 0xD4, 0xE3, 0x9B, + 0x8C, 0xEF, 0x27, 0x27, 0x27, 0x3C, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0x84, + 0x9D, 0x84, 0x90, 0xB1, 0xA9, 0x9C, 0xD9, 0xB1, + 0xB2, 0xEA, 0xBB, 0x51, 0x24, 0x30, 0x30, 0x42, + 0x66, 0x58, 0x24, 0x48, 0x50, 0x3F, 0x20, 0x25, + 0x22, 0x60, 0x34, 0x30, 0x20, 0x8B, 0x8B, 0x39, + 0x54, 0x24, 0x2B, 0xC0, 0xC0, 0xC0, 0xBB, 0x9B, + 0xBC, 0xAA, 0xAA, 0xE3, 0xE3, 0x9C, 0xB2, 0xD4, + 0x83, 0xD8, 0xE8, 0x83, 0x84, 0xE8, 0xE5, 0x75, + 0x9A, 0xF0, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0xA8, + 0xA9, 0xD8, 0x8E, 0xEA, 0xA8, 0x9C, 0xD9, 0xE0, + 0xC0, 0x5E, 0x2C, 0x20, 0x54, 0x60, 0x30, 0x66, + 0xB6, 0xCC, 0x63, 0x3F, 0x8B, 0x28, 0x22, 0x33, + 0x23, 0x31, 0xAF, 0x31, 0x22, 0x6B, 0x6B, 0x29, + 0x30, 0x54, 0x22, 0x89, 0xBA, 0xED, 0xA6, 0x8C, + 0xB4, 0xC0, 0xB4, 0x75, 0x75, 0x9B, 0x9B, 0xE5, + 0xA9, 0xD5, 0x8E, 0x8E, 0x9C, 0xE3, 0x75, 0x8C, + 0xC8, 0xF1, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF1, 0x9A, 0xB4, 0x9B, 0xE3, + 0xE3, 0xA8, 0xE3, 0xE5, 0xAA, 0xBC, 0xC0, 0x9A, + 0x26, 0x29, 0x20, 0x24, 0x63, 0x60, 0x54, 0x43, + 0x34, 0xCB, 0x30, 0x39, 0x2C, 0x20, 0x24, 0x54, + 0x22, 0x34, 0x34, 0x31, 0x24, 0x3F, 0x2C, 0x2B, + 0x31, 0x30, 0x25, 0x2A, 0x6B, 0x29, 0x20, 0xF2, + 0xBA, 0xBF, 0xC8, 0x9A, 0xA6, 0xA6, 0x8C, 0xB4, + 0x9B, 0xAA, 0xAA, 0xAA, 0x9B, 0x75, 0xDE, 0xBF, + 0x81, 0xEF, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xEF, 0xBA, 0x9A, 0xB4, 0x75, + 0x9B, 0x9B, 0x9B, 0xC0, 0xB4, 0x9A, 0xA5, 0xC4, + 0x30, 0x28, 0x22, 0x33, 0x30, 0x30, 0x23, 0x34, + 0x31, 0x30, 0xC4, 0x2C, 0x2B, 0x22, 0x33, 0x63, + 0x21, 0x58, 0x6C, 0x60, 0x25, 0x39, 0x28, 0x2B, + 0xCC, 0x6C, 0x63, 0x20, 0x6B, 0x28, 0x2B, 0x20, + 0x63, 0x43, 0xF3, 0xEF, 0xF0, 0x81, 0xBA, 0xF4, + 0xF4, 0xA6, 0xDE, 0x8C, 0xA6, 0x9A, 0xBA, 0x81, + 0xB0, 0xE4, 0xA1, 0x20, 0x20, 0x23, 0x31, 0xC4, + 0x30, 0x24, 0x33, 0x31, 0x31, 0x60, 0x43, 0x35, + 0x35, 0x55, 0x6C, 0xEF, 0x81, 0xC8, 0x9A, 0xA6, + 0xB4, 0xB4, 0x8C, 0xA6, 0xBA, 0x68, 0x30, 0x30, + 0x30, 0x2B, 0x25, 0x54, 0xC4, 0x54, 0x24, 0x78, + 0x63, 0x63, 0x30, 0x29, 0x21, 0x24, 0x54, 0x63, + 0x23, 0x34, 0xCB, 0x30, 0x25, 0x39, 0x20, 0x20, + 0x58, 0x34, 0x60, 0x23, 0x6B, 0x29, 0x28, 0x20, + 0x22, 0xB6, 0x42, 0xB6, 0x58, 0x54, 0xF5, 0xD7, + 0xA5, 0xBA, 0xBA, 0xBA, 0xBA, 0x81, 0xA5, 0xF1, + 0xE4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x31, 0x60, + 0x54, 0x28, 0x2B, 0x22, 0x33, 0x30, 0x43, 0x35, + 0x66, 0xD1, 0x34, 0xE4, 0xEF, 0x81, 0xC8, 0x9A, + 0x9A, 0xC8, 0xC8, 0x81, 0xF6, 0x31, 0x63, 0x31, + 0x78, 0x2B, 0x54, 0x63, 0x54, 0x24, 0x23, 0x54, + 0x63, 0x54, 0x63, 0x2C, 0x23, 0x33, 0x63, 0x54, + 0x25, 0x31, 0x78, 0x30, 0x25, 0x3F, 0x20, 0x20, + 0xAF, 0x58, 0xCC, 0x33, 0x39, 0x29, 0x29, 0x2A, + 0x29, 0x58, 0x43, 0x42, 0xD1, 0xCB, 0x2C, 0x2C, + 0x37, 0xCD, 0xEF, 0xB0, 0xF0, 0xB0, 0xEF, 0xE4, + 0x63, 0x20, 0x20, 0x2C, 0x2C, 0x21, 0xCB, 0x78, + 0x54, 0x39, 0x39, 0x28, 0x2B, 0x28, 0x2B, 0xCB, + 0x55, 0xB6, 0xD1, 0x28, 0xE4, 0xD7, 0xB8, 0xF0, + 0xA5, 0xB0, 0xEF, 0x26, 0x23, 0x54, 0x31, 0x58, + 0xCB, 0x20, 0x63, 0x63, 0x25, 0x2B, 0x54, 0x78, + 0x30, 0x63, 0x54, 0x28, 0x33, 0x63, 0x63, 0x33, + 0x54, 0x78, 0xC4, 0x30, 0x24, 0x2C, 0x22, 0x22, + 0x55, 0x55, 0x34, 0x30, 0x28, 0x2C, 0x29, 0x29, + 0x28, 0x30, 0xB6, 0x42, 0x43, 0x55, 0x22, 0x29, + 0x2C, 0x2B, 0x2B, 0x3F, 0xE4, 0xE4, 0x43, 0x66, + 0x30, 0x23, 0x24, 0x2A, 0x28, 0x2B, 0x54, 0x63, + 0x33, 0x39, 0x28, 0x20, 0x20, 0x20, 0x2B, 0x31, + 0x30, 0xD1, 0x43, 0x30, 0x39, 0x28, 0xE4, 0xE4, + 0xD7, 0xF5, 0x2B, 0x6B, 0x20, 0x30, 0x34, 0xD1, + 0x60, 0x23, 0x63, 0x54, 0x22, 0x47, 0x60, 0xCB, + 0xC4, 0xC4, 0x25, 0x22, 0x54, 0xC4, 0x63, 0x23, + 0xC4, 0xC4, 0x63, 0xC4, 0x23, 0x2A, 0x24, 0x22, + 0x55, 0x55, 0xAF, 0x6C, 0x22, 0x39, 0x2C, 0x39, + 0x28, 0x23, 0xD1, 0x43, 0x42, 0x8A, 0x63, 0x39, + 0x39, 0x2A, 0x20, 0x6B, 0x33, 0xCC, 0xD1, 0xB6, + 0x30, 0x24, 0x54, 0x63, 0x31, 0xCC, 0xCC, 0xCB, + 0xC4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x39, 0x30, + 0x30, 0x6C, 0x43, 0x43, 0x6C, 0x63, 0x25, 0x24, + 0x63, 0x63, 0x63, 0x25, 0x63, 0xCC, 0xD1, 0x34, + 0x63, 0x25, 0x54, 0x25, 0x2A, 0x28, 0x31, 0xCB, + 0x63, 0x78, 0x24, 0x33, 0xC4, 0xC4, 0x33, 0x2C, + 0xC4, 0x54, 0x54, 0x30, 0x21, 0x22, 0x25, 0x23, + 0x55, 0x55, 0xD1, 0x58, 0x33, 0x6B, 0x2C, 0x39, + 0x39, 0x39, 0x34, 0x43, 0x42, 0x43, 0xCC, 0x2B, + 0x28, 0x29, 0x20, 0x28, 0x21, 0x30, 0xCC, 0xAF, + 0x54, 0x23, 0xC4, 0x54, 0x58, 0x2E, 0x35, 0x42, + 0x55, 0x54, 0x8B, 0x2A, 0x20, 0x20, 0x28, 0x22, + 0x78, 0x30, 0xD1, 0x43, 0x44, 0x6C, 0xC4, 0xC4, + 0x60, 0x31, 0x31, 0x63, 0x6C, 0xAF, 0xCC, 0xCB, + 0x24, 0x25, 0x33, 0x23, 0x2C, 0x24, 0x31, 0x30, + 0x63, 0xC4, 0x21, 0x54, 0x30, 0x63, 0x24, 0x2A, + 0x54, 0x63, 0x54, 0xC4, 0x2B, 0x24, 0x33, 0x24, + 0x34, 0x55, 0xD1, 0x55, 0x30, 0x28, 0x29, 0x39, + 0x39, 0x8B, 0x63, 0x55, 0x42, 0x66, 0xB6, 0x25, + 0x29, 0x29, 0x29, 0x28, 0x2A, 0x54, 0x78, 0x6C, + 0x23, 0x20, 0x25, 0x30, 0xCB, 0x62, 0x35, 0x35, + 0x35, 0x44, 0x24, 0x6B, 0x29, 0x20, 0x2A, 0x39, + 0x28, 0x63, 0x34, 0xB6, 0x34, 0xCB, 0x63, 0x30, + 0x31, 0x31, 0x30, 0x30, 0xCC, 0x60, 0x63, 0xC4, + 0x20, 0x33, 0x25, 0x20, 0x48, 0x33, 0x30, 0x54, + 0x78, 0x54, 0x2B, 0x63, 0x30, 0x63, 0x23, 0x22, + 0x63, 0x63, 0x63, 0x33, 0x28, 0x25, 0x54, 0x24, + 0x78, 0xAF, 0xD1, 0xD1, 0xCC, 0x22, 0x39, 0x39, + 0x2C, 0x3F, 0x2B, 0x34, 0xB6, 0x43, 0x43, 0xC4, + 0x2B, 0x28, 0x39, 0x50, 0x2C, 0x24, 0x63, 0x78, + 0x21, 0x2C, 0x2A, 0x23, 0x54, 0xD1, 0x35, 0x35, + 0x35, 0x35, 0x55, 0x22, 0x39, 0x2C, 0x2C, 0x2C, + 0x20, 0x30, 0xCC, 0x6C, 0xCB, 0x30, 0x54, 0x30, + 0x78, 0x63, 0x78, 0x30, 0x54, 0x78, 0x30, 0x23, + 0x2B, 0x33, 0x24, 0x28, 0x39, 0x24, 0x54, 0x30, + 0x78, 0x33, 0x25, 0xC4, 0xC4, 0x33, 0x39, 0x25, + 0xC4, 0x63, 0xC4, 0x24, 0x20, 0x54, 0x54, 0x25, + 0x63, 0xCC, 0xD1, 0xB6, 0x55, 0x54, 0x39, 0x29, + 0x39, 0x2C, 0x6B, 0x30, 0xAF, 0xB6, 0xB6, 0x60, + 0x22, 0x2A, 0x2C, 0x39, 0x2C, 0x21, 0x54, 0x63, + 0x21, 0x50, 0x2C, 0x2C, 0x2B, 0x25, 0x62, 0x35, + 0x35, 0x35, 0x35, 0xCC, 0x2B, 0x29, 0x2B, 0x20, + 0x23, 0x25, 0xC4, 0x30, 0xC4, 0x63, 0x63, 0x63, + 0x63, 0x33, 0x24, 0x31, 0x31, 0x31, 0x54, 0x28, + 0x24, 0x25, 0x22, 0x6B, 0x28, 0x24, 0xC4, 0x78, + 0x30, 0x24, 0x63, 0xC4, 0x54, 0x23, 0x29, 0x63, + 0xC4, 0x54, 0xC4, 0x21, 0x24, 0x54, 0x54, 0x25, + 0x30, 0xCB, 0xD1, 0xB6, 0x55, 0x63, 0x28, 0x29, + 0x39, 0x39, 0x48, 0x33, 0x58, 0x44, 0xB6, 0x60, + 0x24, 0x20, 0x2B, 0x28, 0x2A, 0x22, 0x54, 0x63, + 0x21, 0x48, 0x2A, 0x2B, 0x39, 0x21, 0xB6, 0x35, + 0x35, 0x35, 0x35, 0x42, 0x23, 0x29, 0x2A, 0x2B, + 0x23, 0x25, 0x54, 0x54, 0x54, 0x63, 0x63, 0x30, + 0x25, 0x2B, 0x31, 0x31, 0x31, 0x31, 0x21, 0x2C, + 0x33, 0x25, 0x21, 0x39, 0x20, 0x25, 0x30, 0x78, + 0xC4, 0x23, 0xC4, 0x30, 0x54, 0x20, 0x28, 0x63, + 0x63, 0x63, 0x63, 0x20, 0x25, 0x54, 0x54, 0x20, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xC2, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0x90, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xA0, 0x00, + 0x8F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0x83, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0x1F, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0x3F, 0xF7, 0x8F, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0x7F, 0xF7, + 0xC7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0x6F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0x7F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0x7F, 0xE7, 0xEF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0x7B, 0xFF, + 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x7B, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x79, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x7C, 0xFF, 0xCF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0x77, 0xFF, + 0xDF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x3F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0xBF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x9F, 0xFF, 0x3F, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1F, 0x9F, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1F, + 0x8F, 0xFE, 0x7F, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0xC7, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0F, 0xF7, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x07, 0xFB, 0xF3, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x07, + 0xFD, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x03, 0xFE, 0x8F, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x03, 0xFE, 0x1F, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xBF, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFE, 0xBF, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x9F, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFE, 0x87, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFD, 0x33, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0xF3, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0x8B, 0xF9, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x27, 0xF8, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x07, 0xF8, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0x8F, 0xF8, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xE3, 0xF8, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xF8, 0x78, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x7F, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x20, + 0x7F, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x10, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; +/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:37 jj Exp $ + * include/asm-sparc64/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/UltraSPARC version " UTS_RELEASE + +#define LINUX_LOGO_COLORS 215 + +unsigned char linux_logo_red[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xB0, + 0x0C, 0xB1, 0xD4, 0xCE, 0x04, 0x06, 0x16, 0xB6, + 0xCD, 0xB2, 0x42, 0x46, 0x4B, 0xA8, 0xF3, 0xCA, + 0xC5, 0x1C, 0xDC, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x8E, 0xCC, 0xA5, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x79, 0x68, 0x8D, 0xAF, 0xFC, 0x8E, 0x3E, + 0x6B, 0x11, 0x37, 0x79, 0x5C, 0x3C, 0x3F, 0x3C, + 0x48, 0x47, 0x3D, 0xB9, 0x62, 0xE1, 0x4D, 0x57, + 0x84, 0x78, 0xA6, 0x58, 0x99, 0xCD, 0xB7, 0xE3, + 0x6D, 0x5A, 0xAF, 0x79, 0x79, 0xF2, 0x42, 0x46, + 0xDD, 0x89, 0xC3, 0xF2, 0xF0, 0xE0, 0xD1, 0x90, + 0x76, 0x6B, 0x4A, 0xBE, 0xBD, 0xE3, 0xF6, 0xE9, + 0xEC, 0xE8, 0xEC, 0xC0, 0x66, 0x63, 0xCB, 0xAB, + 0x49, 0x5C, 0xAD, 0xD6, 0xEE, 0xF5, 0xF5, 0xE9, + 0x6E, 0x00, 0x69, 0x6A, 0xA1, 0x7A, 0xB4, 0xDE, + 0xF1, 0xF6, 0xDD, 0x00, 0x73, 0xDB, 0x4C, 0x53, + 0x6A, 0xF5, 0xF5, 0xD6, 0xC3, 0x6A, 0x4B, 0x4B, + 0x60, 0xF8, 0x9B, 0xD7, 0xD7, 0x71, 0xB3, 0xA4, + 0xCA, 0xAB, 0xB4, 0xB2, 0x76, 0xBA, 0x8B, 0xA0, + 0xA5, 0xEE, 0xE7, 0x67, 0x5F, 0x08, 0x94, 0xDB, + 0xE5, 0x4F, 0x00, 0x34, 0xEE, 0xEC, 0xE2, 0x48, + 0xF3, 0xEB, 0xF4, 0xF4, 0xEF, 0xD6, 0xB6, 0xE6, + 0xE6, 0xED, 0xE7, 0xE6, 0x3D, 0xE7, 0xCD, 0x44, + 0xEF, 0xEC, 0xF5, 0x66, 0xF3, 0xA9, 0x77, 0x58, + 0x75, 0x6C, 0x53, 0x24, 0xAC, 0x0D, 0x3C +}; + +unsigned char linux_logo_green[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0x02, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x3B, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xAD, + 0x0C, 0xB1, 0x92, 0xAB, 0x03, 0x06, 0x16, 0xB6, + 0xCD, 0x88, 0x42, 0x46, 0x4B, 0x94, 0xBB, 0xCA, + 0xC5, 0x1C, 0xAB, 0xA0, 0xD4, 0xE6, 0xED, 0xF3, + 0xC2, 0x73, 0xCA, 0x91, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x5A, 0x49, 0x56, 0x6E, 0xFC, 0x6B, 0x3E, + 0x6B, 0x0D, 0x37, 0x79, 0x51, 0x44, 0x3F, 0x43, + 0x38, 0x3D, 0x48, 0xB9, 0x62, 0xA5, 0x47, 0x48, + 0x49, 0x4A, 0x97, 0x48, 0x81, 0x95, 0x8E, 0xE3, + 0x6D, 0x57, 0x51, 0x51, 0x47, 0xB2, 0x42, 0x46, + 0xDD, 0x5B, 0x87, 0xBE, 0xC7, 0xC8, 0x56, 0x75, + 0x5D, 0x4B, 0x4D, 0xBE, 0x85, 0xA6, 0xBC, 0xC7, + 0xCA, 0xCD, 0xCC, 0xA4, 0x53, 0x4D, 0x9F, 0x55, + 0x52, 0x5E, 0x75, 0x9C, 0xB6, 0xC3, 0xD7, 0xCC, + 0x55, 0x00, 0x6A, 0x59, 0x7D, 0x55, 0x7C, 0xA3, + 0xB7, 0xBF, 0xA5, 0x00, 0x67, 0xC6, 0x47, 0x54, + 0x46, 0xB8, 0xBE, 0xB2, 0x87, 0x52, 0x4B, 0x43, + 0x41, 0xF8, 0x69, 0x96, 0x9B, 0x66, 0xB0, 0x6C, + 0x8E, 0x81, 0xB4, 0x76, 0x76, 0xB9, 0x65, 0x77, + 0x6D, 0xED, 0xE7, 0x67, 0x5F, 0x06, 0x54, 0x6C, + 0xCB, 0x4F, 0x00, 0x2F, 0xC2, 0xB5, 0xB6, 0x30, + 0xC3, 0xAE, 0xC4, 0xCA, 0xC6, 0xB4, 0x7B, 0xAD, + 0xAD, 0xB6, 0xB6, 0xAD, 0x29, 0xAB, 0x93, 0x2E, + 0xBC, 0xBC, 0xC9, 0x53, 0xBF, 0x77, 0x54, 0x3B, + 0x4B, 0x3F, 0x39, 0x19, 0x76, 0x08, 0x2C +}; + +unsigned char linux_logo_blue[] __initdata = { + 0x99, 0x95, 0x92, 0x8E, 0x8A, 0x86, 0xD6, 0x00, + 0xA5, 0xA9, 0xA2, 0x9E, 0xAD, 0x1B, 0x39, 0x25, + 0x71, 0x65, 0x2C, 0x82, 0x5B, 0x33, 0x13, 0xA7, + 0x0C, 0xB1, 0x58, 0x8A, 0x03, 0x07, 0x16, 0xB6, + 0xCD, 0x5A, 0x42, 0x46, 0x4F, 0x6F, 0x77, 0xCA, + 0xC5, 0x1C, 0x6F, 0xA5, 0xD4, 0xE6, 0xF5, 0xF3, + 0xC2, 0x4D, 0xD1, 0x64, 0x7E, 0x52, 0xF7, 0xE3, + 0x56, 0x49, 0x3C, 0x47, 0x45, 0xFE, 0x3B, 0x41, + 0x6B, 0x09, 0x37, 0x79, 0x39, 0x39, 0x3F, 0x42, + 0x3A, 0x42, 0x5F, 0xB9, 0x62, 0x4C, 0x39, 0x44, + 0x3B, 0x3A, 0xA0, 0x3D, 0x08, 0x08, 0x09, 0xDE, + 0x6D, 0x48, 0x3B, 0x3F, 0x42, 0xF3, 0x36, 0x3C, + 0xDD, 0x06, 0x16, 0x08, 0x13, 0x0A, 0x4B, 0x71, + 0x5D, 0x44, 0x47, 0xBE, 0x08, 0x0C, 0x0D, 0x0C, + 0x19, 0x29, 0x36, 0x06, 0x43, 0x44, 0xBA, 0x45, + 0x50, 0x58, 0x07, 0x07, 0x0D, 0x0E, 0x10, 0x50, + 0x06, 0x42, 0x40, 0x44, 0x79, 0x06, 0x06, 0x0C, + 0x08, 0x08, 0x07, 0x36, 0x4C, 0xE5, 0x42, 0x55, + 0x03, 0x0F, 0x12, 0x06, 0x07, 0x3C, 0x4B, 0x3D, + 0x01, 0xF8, 0x08, 0x0E, 0x0A, 0x69, 0xAC, 0x0C, + 0x0A, 0x27, 0xBB, 0x36, 0x76, 0xC0, 0x04, 0x08, + 0x08, 0xED, 0xEE, 0x68, 0x5F, 0xB2, 0x3B, 0x52, + 0xAC, 0x4F, 0x6F, 0x2D, 0x16, 0x08, 0x59, 0x04, + 0x13, 0x0E, 0x14, 0x17, 0x16, 0x2E, 0x08, 0x0D, + 0x11, 0x14, 0x0D, 0x06, 0x04, 0x08, 0x25, 0x8E, + 0x0E, 0x14, 0x25, 0x9B, 0x1C, 0x16, 0x78, 0x06, + 0x04, 0x03, 0x79, 0x8C, 0x0B, 0xC8, 0x48 +}; + +unsigned char linux_logo[] __initdata = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x22, 0x23, 0x24, 0x24, + 0x25, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x23, 0x23, + 0x23, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x26, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x26, 0x28, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x28, 0x28, 0x28, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x2C, 0x29, 0x29, 0x29, 0x28, + 0x28, 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2A, 0x2A, + 0x2A, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2D, 0x2E, 0x2F, 0x27, + 0x27, 0x26, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x28, + 0x28, 0x29, 0x29, 0x29, 0x29, 0x2C, 0x2C, 0x29, + 0x29, 0x29, 0x28, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x30, 0x31, 0x32, + 0x27, 0x27, 0x22, 0x22, 0x22, 0x22, 0x21, 0x20, + 0x20, 0x20, 0x2B, 0x2A, 0x28, 0x29, 0x29, 0x29, + 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x28, 0x2A, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x27, 0x27, 0x33, 0x25, 0x25, 0x24, 0x24, + 0x24, 0x24, 0x23, 0x21, 0x20, 0x20, 0x2B, 0x2A, + 0x28, 0x29, 0x29, 0x37, 0x2C, 0x2C, 0x29, 0x28, + 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2A, 0x2B, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2F, 0x32, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x25, 0x24, 0x23, 0x21, + 0x20, 0x2B, 0x2A, 0x29, 0x29, 0x2C, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x38, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x23, 0x23, 0x24, 0x24, + 0x25, 0x25, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x24, 0x22, 0x20, 0x20, 0x2A, 0x28, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x23, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x2A, 0x2A, 0x2B, 0x2B, + 0x20, 0x21, 0x22, 0x24, 0x20, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x3A, 0x3B, 0x22, 0x20, 0x2A, 0x28, + 0x29, 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x20, 0x21, 0x22, 0x22, 0x23, 0x24, 0x27, + 0x27, 0x27, 0x3C, 0x36, 0x3C, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x3D, 0x3E, 0x32, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x39, 0x3F, 0x3F, + 0x39, 0x2C, 0x20, 0x20, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x40, 0x40, 0x41, 0x22, 0x20, + 0x2A, 0x28, 0x2C, 0x2C, 0x2C, 0x29, 0x29, 0x2A, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, + 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x22, 0x27, + 0x27, 0x3C, 0x3C, 0x3D, 0x42, 0x3C, 0x27, 0x27, + 0x3C, 0x27, 0x3C, 0x43, 0x44, 0x36, 0x42, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x3D, 0x28, 0x29, 0x2C, + 0x2C, 0x45, 0x20, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x46, 0x40, 0x47, 0x40, 0x47, 0x3A, 0x40, + 0x22, 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x2C, 0x29, + 0x28, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2B, 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x20, 0x27, + 0x27, 0x44, 0x28, 0x24, 0x27, 0x2F, 0x3C, 0x27, + 0x27, 0x38, 0x24, 0x2C, 0x2C, 0x48, 0x49, 0x36, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x29, 0x29, + 0x4A, 0x20, 0x3A, 0x40, 0x47, 0x40, 0x47, 0x40, + 0x40, 0x47, 0x40, 0x40, 0x39, 0x39, 0x39, 0x4A, + 0x25, 0x24, 0x22, 0x2B, 0x28, 0x29, 0x2C, 0x2C, + 0x29, 0x28, 0x2A, 0x2B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x21, 0x20, 0x2B, 0x2A, 0x27, + 0x3D, 0x4B, 0x48, 0x4C, 0x2B, 0x3C, 0x27, 0x3C, + 0x3C, 0x23, 0x4D, 0x4E, 0x4F, 0x50, 0x33, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x39, 0x3F, 0x39, + 0x51, 0x20, 0x39, 0x39, 0x47, 0x40, 0x4D, 0x4D, + 0x40, 0x52, 0x4D, 0x40, 0x47, 0x40, 0x39, 0x39, + 0x53, 0x54, 0x25, 0x24, 0x20, 0x2A, 0x29, 0x2C, + 0x2C, 0x2C, 0x29, 0x2A, 0x2B, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x21, 0x20, 0x2B, 0x28, 0x2A, 0x20, 0x27, + 0x36, 0x4F, 0x55, 0x48, 0x56, 0x3D, 0x3C, 0x3C, + 0x32, 0x57, 0x56, 0x58, 0x49, 0x56, 0x56, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x20, 0x20, + 0x41, 0x39, 0x39, 0x3A, 0x59, 0x5A, 0x59, 0x5B, + 0x5C, 0x3A, 0x4D, 0x5D, 0x57, 0x39, 0x39, 0x4A, + 0x5E, 0x33, 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, + 0x2C, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, + 0x20, 0x2B, 0x2A, 0x2A, 0x20, 0x22, 0x22, 0x27, + 0x5F, 0x2D, 0x3C, 0x60, 0x56, 0x54, 0x61, 0x49, + 0x35, 0x56, 0x34, 0x27, 0x62, 0x27, 0x56, 0x39, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x63, 0x54, + 0x40, 0x64, 0x65, 0x66, 0x67, 0x67, 0x68, 0x5F, + 0x2E, 0x69, 0x6A, 0x67, 0x5F, 0x3A, 0x39, 0x2C, + 0x53, 0x23, 0x25, 0x54, 0x33, 0x25, 0x23, 0x20, + 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, + 0x2B, 0x2A, 0x20, 0x22, 0x22, 0x21, 0x2B, 0x27, + 0x62, 0x36, 0x27, 0x33, 0x6B, 0x54, 0x3D, 0x3C, + 0x49, 0x57, 0x27, 0x27, 0x27, 0x27, 0x56, 0x57, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x6C, 0x31, 0x6D, + 0x64, 0x51, 0x6E, 0x2E, 0x2E, 0x6F, 0x5A, 0x70, + 0x70, 0x71, 0x72, 0x67, 0x67, 0x69, 0x73, 0x46, + 0x4A, 0x2A, 0x21, 0x25, 0x33, 0x54, 0x33, 0x24, + 0x20, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, 0x2B, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, + 0x2B, 0x22, 0x22, 0x22, 0x2B, 0x28, 0x2A, 0x27, + 0x27, 0x39, 0x3C, 0x3D, 0x45, 0x74, 0x75, 0x76, + 0x76, 0x45, 0x27, 0x27, 0x27, 0x27, 0x56, 0x77, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x78, 0x78, 0x5E, + 0x79, 0x7A, 0x7B, 0x6E, 0x5A, 0x5A, 0x70, 0x7C, + 0x70, 0x5B, 0x7D, 0x5A, 0x66, 0x7E, 0x7F, 0x79, + 0x48, 0x6B, 0x2C, 0x20, 0x24, 0x33, 0x54, 0x33, + 0x24, 0x21, 0x2A, 0x29, 0x2C, 0x2C, 0x29, 0x28, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x21, + 0x22, 0x22, 0x20, 0x28, 0x2B, 0x20, 0x22, 0x27, + 0x27, 0x80, 0x27, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x74, 0x85, 0x84, 0x27, 0x3C, 0x4F, 0x4F, 0x66, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x22, 0x23, 0x5E, + 0x64, 0x86, 0x79, 0x73, 0x87, 0x88, 0x7C, 0x5A, + 0x5A, 0x71, 0x7D, 0x71, 0x89, 0x79, 0x8A, 0x8A, + 0x51, 0x8B, 0x48, 0x39, 0x2A, 0x22, 0x33, 0x54, + 0x33, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x2C, 0x29, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x20, 0x20, 0x2B, 0x2B, 0x22, 0x23, + 0x21, 0x2A, 0x2A, 0x20, 0x21, 0x23, 0x25, 0x27, + 0x27, 0x55, 0x8C, 0x8D, 0x8E, 0x83, 0x8F, 0x90, + 0x91, 0x92, 0x92, 0x85, 0x85, 0x93, 0x51, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0x29, 0x51, + 0x79, 0x79, 0x94, 0x89, 0x89, 0x89, 0x5A, 0x95, + 0x64, 0x88, 0x96, 0x97, 0x7A, 0x73, 0x98, 0x98, + 0x99, 0x50, 0x50, 0x48, 0x6B, 0x28, 0x21, 0x25, + 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2C, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2B, 0x20, 0x22, 0x22, 0x20, + 0x2B, 0x2B, 0x20, 0x22, 0x24, 0x25, 0x33, 0x27, + 0x27, 0x9A, 0x9B, 0x9C, 0x9D, 0x83, 0x9E, 0x85, + 0x9F, 0x92, 0x85, 0x85, 0x85, 0x85, 0x92, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xA1, 0x47, 0xA2, + 0xA2, 0x94, 0xA3, 0x94, 0x95, 0x95, 0x73, 0x73, + 0x95, 0x87, 0xA4, 0x5B, 0x97, 0x7B, 0x88, 0x98, + 0xA2, 0x50, 0x48, 0x48, 0x48, 0x8B, 0x29, 0x20, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x29, 0x29, + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x2B, 0x2B, + 0x20, 0x21, 0x23, 0x24, 0x25, 0x25, 0x33, 0x27, + 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x8F, 0x90, 0x90, + 0x9F, 0x90, 0x85, 0x90, 0x85, 0x74, 0xAA, 0x81, + 0x27, 0x27, 0x27, 0x27, 0x27, 0xAB, 0x40, 0xAC, + 0x79, 0xA3, 0x89, 0xAD, 0x95, 0x6F, 0xAE, 0xAE, + 0xAE, 0x5B, 0x59, 0x88, 0x7B, 0x89, 0x79, 0xAF, + 0xA2, 0x6B, 0x48, 0x48, 0x48, 0x48, 0x50, 0x2C, + 0x20, 0x24, 0x33, 0x54, 0x25, 0x22, 0x2A, 0x2A, + 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x23, 0x22, 0x2B, 0x20, 0x20, + 0x22, 0x23, 0x24, 0x25, 0x24, 0x24, 0x22, 0x27, + 0xB0, 0x8C, 0xAA, 0xB1, 0xB2, 0x84, 0x85, 0x9F, + 0x85, 0x85, 0x85, 0xB3, 0xB4, 0xAA, 0xAA, 0xA0, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2A, 0xB5, + 0xA3, 0xA3, 0xAC, 0x5D, 0xB6, 0xAE, 0xB7, 0x69, + 0x73, 0x5B, 0x88, 0x89, 0x95, 0x73, 0x99, 0x99, + 0x59, 0x2A, 0x39, 0x48, 0x48, 0x50, 0x48, 0x50, + 0x2C, 0x20, 0x24, 0x33, 0x54, 0x25, 0x21, 0x20, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x23, 0x21, 0x2B, 0x20, 0x20, 0x22, + 0x22, 0x24, 0x24, 0x23, 0x22, 0x20, 0x2A, 0x27, + 0x27, 0xB0, 0x8C, 0xA9, 0xB2, 0x9E, 0x91, 0x85, + 0x85, 0x93, 0xB8, 0x75, 0xAA, 0xA7, 0x8C, 0x27, + 0x27, 0x27, 0x33, 0x3C, 0x27, 0x27, 0x2C, 0x7B, + 0x55, 0x79, 0xA3, 0x5D, 0xB9, 0x43, 0x7F, 0x7E, + 0x5F, 0x5A, 0x5A, 0x95, 0x64, 0x73, 0x58, 0x64, + 0x5C, 0x25, 0x2B, 0x3F, 0x48, 0x48, 0x8B, 0x48, + 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x24, 0x22, + 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x23, 0x21, 0x20, 0x20, 0x20, 0x21, 0x22, + 0x24, 0x23, 0x22, 0x21, 0x2B, 0x20, 0x54, 0x27, + 0x27, 0x8B, 0x81, 0xA5, 0x93, 0x93, 0x74, 0xA5, + 0xBA, 0x75, 0xBB, 0xBC, 0xB4, 0x6D, 0x50, 0x6B, + 0x27, 0x27, 0x30, 0x33, 0x49, 0x27, 0x27, 0x5E, + 0x6F, 0x73, 0x94, 0xBD, 0x4E, 0x5D, 0x7F, 0x7F, + 0xB7, 0x68, 0x73, 0x6E, 0xB7, 0x7F, 0x95, 0x97, + 0x47, 0x63, 0x25, 0x20, 0x3F, 0x48, 0x8B, 0x8B, + 0x48, 0x48, 0x2C, 0x20, 0x25, 0x54, 0x33, 0x25, + 0x2B, 0x2B, 0x2B, 0x20, 0x20, 0x20, 0x21, 0x21, + 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, + 0x22, 0x21, 0x20, 0x2A, 0x33, 0x30, 0x30, 0x27, + 0x27, 0x50, 0xBE, 0xBF, 0x9A, 0xB3, 0x9B, 0xBB, + 0xBB, 0xC0, 0x8C, 0xC1, 0x8B, 0xC2, 0x47, 0x8B, + 0x27, 0x27, 0x38, 0x63, 0x63, 0x27, 0x27, 0xC3, + 0xB5, 0x95, 0x72, 0x95, 0x6F, 0x69, 0x7E, 0x66, + 0x7E, 0x7F, 0x6E, 0x7E, 0x95, 0x95, 0x73, 0x70, + 0x30, 0x30, 0x30, 0x33, 0x20, 0x3F, 0x48, 0x8B, + 0x6B, 0x48, 0x50, 0x29, 0x21, 0x33, 0x54, 0x33, + 0x2A, 0x2B, 0x2B, 0x20, 0x20, 0x21, 0x21, 0x23, + 0x21, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, 0x22, + 0x20, 0x2B, 0x21, 0xC4, 0x30, 0x60, 0x30, 0x27, + 0x27, 0xC5, 0x8B, 0x39, 0xC6, 0xC7, 0xA6, 0xA6, + 0xC8, 0x9A, 0x3B, 0x39, 0x50, 0x56, 0x56, 0x4F, + 0x33, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x48, + 0x59, 0x94, 0x73, 0xAE, 0xB7, 0xB7, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x5A, 0x70, 0x7C, 0x71, 0xC3, + 0x63, 0x30, 0x60, 0x78, 0x54, 0x20, 0x6B, 0x48, + 0x6B, 0x6B, 0x50, 0x50, 0x29, 0x22, 0x33, 0x33, + 0x2A, 0x2B, 0x20, 0x20, 0x21, 0x22, 0x22, 0x22, + 0x21, 0x20, 0x20, 0x20, 0x24, 0x24, 0x20, 0x20, + 0x2B, 0x24, 0x30, 0x60, 0x60, 0x30, 0xAB, 0x27, + 0x27, 0x40, 0x4C, 0x50, 0x39, 0x87, 0xC3, 0x53, + 0x37, 0x48, 0x37, 0x48, 0xC9, 0x56, 0xB9, 0x56, + 0xCA, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x3C, + 0x51, 0x5A, 0x6E, 0xB7, 0xB7, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7F, 0xB7, 0x5A, 0x7C, 0x5B, 0x37, + 0x23, 0x63, 0x31, 0x6C, 0xCB, 0x63, 0x20, 0x6B, + 0x50, 0x3F, 0x39, 0x50, 0x8B, 0x28, 0x24, 0x24, + 0x2B, 0x2B, 0x20, 0x21, 0x22, 0x22, 0x22, 0x21, + 0x20, 0x20, 0x20, 0x23, 0x23, 0x20, 0x20, 0x2B, + 0x33, 0x78, 0xCB, 0x60, 0x30, 0x22, 0x3D, 0x27, + 0x2F, 0x56, 0x4E, 0x8B, 0x6B, 0x39, 0x48, 0x8B, + 0x6B, 0x8B, 0x80, 0xC9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x34, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x48, 0xB5, 0xB7, 0xB7, 0x7E, 0x7E, 0x2E, 0x7E, + 0x7E, 0x7E, 0x7F, 0x7C, 0x65, 0x71, 0x3A, 0x48, + 0x2C, 0x24, 0x30, 0x6C, 0x34, 0x6C, 0xC4, 0x20, + 0x8B, 0x50, 0x39, 0x39, 0x48, 0x6B, 0x2B, 0x22, + 0x2B, 0x20, 0x21, 0x22, 0x23, 0x23, 0x22, 0x21, + 0x20, 0x2B, 0x23, 0x22, 0x20, 0x2B, 0x2B, 0x54, + 0x60, 0x31, 0xCB, 0x54, 0x20, 0x3D, 0x36, 0x27, + 0x4E, 0xB9, 0x56, 0x56, 0x8B, 0x6B, 0x50, 0x6B, + 0x40, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, + 0x56, 0x56, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x7B, 0x6E, 0xB7, 0xB7, 0xB7, 0x7E, 0x7F, + 0xB7, 0xB7, 0x7F, 0x7E, 0x6F, 0x5B, 0x29, 0x2C, + 0x48, 0x39, 0x24, 0x60, 0x58, 0xAF, 0xCC, 0x63, + 0x20, 0x8B, 0x8B, 0x39, 0x39, 0x48, 0x3F, 0x28, + 0x20, 0x20, 0x22, 0x23, 0x23, 0x23, 0x22, 0x20, + 0x2B, 0x22, 0x22, 0x2B, 0x2B, 0x20, 0x54, 0xCB, + 0x31, 0xCB, 0x25, 0x20, 0x27, 0x27, 0x27, 0x48, + 0xB9, 0x56, 0xB9, 0x56, 0x4F, 0x48, 0x47, 0x57, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0x62, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x48, 0x6F, 0x69, 0xB7, 0xB7, 0xB7, 0x7F, + 0xB7, 0xB7, 0xB7, 0x73, 0x59, 0x50, 0x29, 0x2B, + 0x28, 0x8B, 0x39, 0x25, 0x31, 0x55, 0xB6, 0x34, + 0x63, 0x2B, 0x48, 0x6B, 0x2C, 0x39, 0x47, 0x6B, + 0x22, 0x22, 0x23, 0x24, 0x23, 0x22, 0x20, 0x2B, + 0x20, 0x22, 0x2A, 0x2B, 0x20, 0x33, 0xCB, 0x31, + 0x78, 0x24, 0x21, 0xCD, 0x27, 0x27, 0x27, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0x56, 0xC9, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x41, 0x64, 0xB7, 0xB7, 0xB7, 0x7F, + 0x68, 0xB7, 0xAE, 0xA3, 0x23, 0x39, 0x8B, 0x2A, + 0x20, 0x20, 0x39, 0x6B, 0x25, 0xCC, 0x43, 0x43, + 0x34, 0x63, 0x2A, 0x48, 0x3F, 0x39, 0x6B, 0x6B, + 0x24, 0x23, 0x24, 0x24, 0x23, 0x21, 0x2B, 0x2B, + 0x22, 0x2B, 0x2B, 0x20, 0x24, 0x78, 0x31, 0x30, + 0x23, 0x21, 0x21, 0x27, 0x27, 0x27, 0x80, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, + 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x3C, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xCE, 0x8A, 0xAE, 0x6F, 0xB7, + 0x6F, 0x89, 0x71, 0x78, 0x63, 0x23, 0x39, 0x6B, + 0x2B, 0x20, 0x20, 0x2C, 0x6B, 0x25, 0x34, 0x42, + 0x42, 0x34, 0x54, 0x29, 0x48, 0x3F, 0x39, 0x3F, + 0x25, 0x24, 0x25, 0x24, 0x22, 0x20, 0x2A, 0x21, + 0x2B, 0x2A, 0x20, 0x22, 0x30, 0x60, 0x30, 0x22, + 0x21, 0x22, 0x27, 0x27, 0x27, 0x2D, 0x4C, 0x56, + 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0x56, 0x2E, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x40, 0x97, 0x95, 0x5A, 0x71, + 0x7C, 0xCE, 0x40, 0x60, 0x31, 0x30, 0x23, 0x3F, + 0x3F, 0x20, 0x20, 0x20, 0x29, 0x8B, 0x33, 0x58, + 0x66, 0x43, 0xCC, 0x25, 0x39, 0x50, 0x6B, 0x2C, + 0x33, 0x25, 0x25, 0x23, 0x20, 0x2A, 0x2B, 0x20, + 0x2A, 0x2B, 0x22, 0x54, 0x30, 0x30, 0x24, 0x22, + 0x21, 0x27, 0x27, 0x27, 0x27, 0xAF, 0x29, 0x4E, + 0x4F, 0xB9, 0x56, 0xB9, 0x4D, 0x4D, 0x77, 0xC9, + 0xB9, 0xB9, 0xB9, 0x56, 0xC9, 0x4D, 0x4D, 0x80, + 0x4C, 0x40, 0xC9, 0x4D, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0xCF, 0x97, 0x97, 0xCE, + 0x86, 0xD0, 0x54, 0x6C, 0x58, 0x34, 0x60, 0x23, + 0x6B, 0x39, 0x20, 0x20, 0x20, 0x28, 0x6B, 0x54, + 0xD1, 0x66, 0xB6, 0x60, 0x22, 0x6B, 0x8B, 0x2C, + 0x54, 0x33, 0x24, 0x22, 0x2B, 0x28, 0x20, 0x28, + 0x2B, 0x20, 0x25, 0xC4, 0x30, 0x25, 0x22, 0x21, + 0x26, 0x27, 0x27, 0x27, 0x27, 0x20, 0x4B, 0x52, + 0x80, 0x4F, 0xB9, 0x56, 0xB9, 0x80, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x4D, 0x80, 0x50, 0x48, + 0x50, 0x50, 0x50, 0x56, 0x3D, 0x27, 0x36, 0x27, + 0x27, 0x27, 0x27, 0x3C, 0x46, 0xC3, 0x86, 0x86, + 0xD0, 0x39, 0x24, 0x6C, 0xD1, 0x43, 0x43, 0x6C, + 0x24, 0x6B, 0x2C, 0x20, 0x20, 0x20, 0x29, 0x39, + 0x63, 0xD1, 0x42, 0x55, 0xC4, 0x2B, 0x8B, 0x39, + 0x54, 0x25, 0x24, 0x20, 0x2A, 0x2A, 0x28, 0x28, + 0x20, 0x22, 0x54, 0x63, 0x25, 0x24, 0x22, 0x22, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x77, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xC9, 0x56, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x4F, + 0x77, 0x47, 0x8B, 0x40, 0x56, 0x27, 0x27, 0x49, + 0x2D, 0x27, 0x27, 0x27, 0x39, 0x40, 0x39, 0x39, + 0x28, 0x3F, 0x39, 0x33, 0x58, 0x66, 0x35, 0x2E, + 0x58, 0x24, 0x8B, 0x29, 0x20, 0x20, 0x20, 0x39, + 0x29, 0x30, 0x55, 0xB6, 0xCC, 0x25, 0x29, 0x39, + 0x54, 0x25, 0x22, 0x2B, 0x29, 0x2A, 0x29, 0x2B, + 0x22, 0x24, 0x54, 0x33, 0x25, 0x22, 0x2B, 0x54, + 0x27, 0x27, 0x62, 0x27, 0x30, 0x80, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4D, 0x8B, 0x77, 0x36, 0x27, 0x27, + 0x3C, 0x2F, 0x27, 0x27, 0x39, 0x39, 0x39, 0x47, + 0x20, 0x2B, 0x2C, 0x39, 0x33, 0xB6, 0x35, 0x35, + 0x35, 0xAF, 0x24, 0x48, 0x2A, 0x20, 0x20, 0x20, + 0x8B, 0x2B, 0x78, 0xAF, 0x58, 0x30, 0x21, 0x28, + 0x33, 0x25, 0x21, 0x28, 0x29, 0x29, 0x28, 0x20, + 0x24, 0x33, 0x54, 0x33, 0x23, 0x20, 0x24, 0xD2, + 0x27, 0x49, 0x27, 0x27, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0xC9, 0x50, 0x56, 0x27, 0x27, + 0x3D, 0x38, 0x3D, 0x27, 0x27, 0x47, 0x39, 0x39, + 0x28, 0x20, 0x20, 0x2A, 0x39, 0x54, 0x43, 0x35, + 0x35, 0x35, 0xAF, 0x23, 0x48, 0x2B, 0x20, 0x20, + 0x2B, 0x48, 0x22, 0x60, 0x34, 0xCB, 0x25, 0x21, + 0x33, 0x24, 0x2B, 0x29, 0x29, 0x29, 0x2B, 0x22, + 0x25, 0x54, 0x54, 0x25, 0x22, 0x2B, 0x33, 0x27, + 0x27, 0x32, 0x27, 0x30, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0xC9, 0x4C, 0x36, 0x3C, + 0x62, 0x2F, 0x2E, 0x27, 0x27, 0x54, 0x47, 0x47, + 0x8B, 0x2B, 0x20, 0x20, 0x20, 0x3F, 0x54, 0x2E, + 0x35, 0x35, 0x35, 0x34, 0x21, 0x8B, 0x2A, 0x20, + 0x20, 0x2C, 0x6B, 0x25, 0x60, 0x60, 0x54, 0x23, + 0x25, 0x22, 0x2A, 0x2C, 0x29, 0x28, 0x20, 0x24, + 0x54, 0x63, 0x54, 0x24, 0x2B, 0x22, 0x24, 0x27, + 0x36, 0x27, 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x4C, 0x36, + 0x66, 0xD3, 0x27, 0x2F, 0x27, 0x54, 0x54, 0x27, + 0x26, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x63, + 0x35, 0x35, 0x35, 0x62, 0xCB, 0x2A, 0x3F, 0x28, + 0x2B, 0x2A, 0x50, 0x29, 0x33, 0x30, 0x54, 0x25, + 0x24, 0x20, 0x29, 0x2C, 0x2C, 0x2A, 0x21, 0x33, + 0xC4, 0xC4, 0x33, 0x21, 0x29, 0x22, 0x27, 0x27, + 0x99, 0x27, 0x31, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0x3D, + 0x3D, 0x3C, 0x3C, 0x55, 0x54, 0x54, 0x54, 0x20, + 0x27, 0x2C, 0x39, 0x20, 0x20, 0x20, 0x20, 0x48, + 0x30, 0x62, 0x35, 0x35, 0x42, 0x54, 0x39, 0x39, + 0x2C, 0x28, 0x3F, 0x8B, 0x20, 0x33, 0x54, 0x24, + 0x22, 0x2B, 0x2C, 0x2C, 0x2C, 0x2B, 0x24, 0x54, + 0x30, 0xC4, 0x25, 0x2B, 0x28, 0x2B, 0x27, 0x3D, + 0x27, 0x27, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x27, + 0x20, 0x20, 0x20, 0x54, 0x54, 0x54, 0x54, 0x20, + 0x20, 0x2D, 0x2D, 0x29, 0x20, 0x20, 0x20, 0x20, + 0x48, 0x60, 0x66, 0x35, 0x62, 0x34, 0x22, 0x2C, + 0x2C, 0x3F, 0x6B, 0x48, 0x2C, 0x22, 0x23, 0x23, + 0x20, 0x2A, 0x2C, 0x29, 0x29, 0x20, 0x25, 0xC4, + 0x30, 0x54, 0x22, 0x29, 0x28, 0xD2, 0x27, 0x35, + 0x27, 0x49, 0x56, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x4F, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0x40, 0x20, + 0x20, 0x54, 0x54, 0x54, 0x20, 0x20, 0x20, 0x20, + 0x2D, 0x2D, 0x2D, 0x49, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6B, 0x6C, 0x42, 0x2E, 0xB6, 0x54, 0x28, + 0x29, 0x2C, 0x6B, 0x48, 0x3F, 0x2A, 0x20, 0x22, + 0x2B, 0x28, 0x2C, 0x28, 0x29, 0x20, 0x33, 0x30, + 0x30, 0x54, 0x20, 0x2C, 0x29, 0x27, 0x27, 0x3D, + 0x27, 0x40, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x56, 0x63, 0x56, 0x54, 0x54, + 0x54, 0x54, 0x20, 0xD3, 0x45, 0x51, 0x51, 0x49, + 0x7C, 0x2D, 0x2D, 0x49, 0x49, 0x20, 0x20, 0x20, + 0x20, 0x2A, 0x2A, 0xCC, 0xB6, 0x8A, 0x60, 0x22, + 0x28, 0x29, 0x3F, 0x6B, 0x39, 0x29, 0x2B, 0x20, + 0x28, 0x2C, 0x28, 0x2A, 0x2A, 0x24, 0xC4, 0x30, + 0xC4, 0x33, 0x2B, 0x39, 0xCD, 0x27, 0x3C, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x4D, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x63, 0x63, 0x49, 0x2D, 0x20, + 0x20, 0x2D, 0xD3, 0x49, 0x66, 0x2D, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x49, 0x8B, 0x2B, 0x20, + 0x20, 0x20, 0x39, 0x23, 0x6C, 0xAF, 0xCB, 0x23, + 0x28, 0x28, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x20, + 0x29, 0x39, 0x2B, 0x2B, 0x2B, 0x25, 0x78, 0xC4, + 0x63, 0x23, 0x29, 0x39, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x4F, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x49, 0x2D, 0x49, 0x2D, 0x49, 0x2D, 0x2D, 0x2D, + 0x49, 0x49, 0x35, 0x49, 0x2D, 0x2D, 0x39, 0x28, + 0x20, 0x20, 0x2A, 0x28, 0x33, 0x60, 0xC4, 0x22, + 0x2C, 0x2A, 0x2A, 0x22, 0x23, 0x22, 0x20, 0x21, + 0x2C, 0x29, 0x20, 0x2B, 0x2B, 0x54, 0x30, 0xC4, + 0x63, 0x22, 0x2C, 0x27, 0x27, 0x27, 0x3D, 0x27, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x2D, 0x49, 0x2D, 0x49, + 0x61, 0x49, 0x2D, 0x49, 0x49, 0x2D, 0x2D, 0x49, + 0x49, 0x49, 0x2F, 0x49, 0x2D, 0x78, 0x29, 0x28, + 0x2C, 0x2A, 0x2B, 0x39, 0x2B, 0x25, 0x33, 0x20, + 0x2C, 0x20, 0x2A, 0x24, 0x54, 0x54, 0x23, 0x23, + 0x2C, 0x2A, 0x22, 0x2B, 0x20, 0x63, 0x30, 0x63, + 0xC4, 0x21, 0x39, 0x27, 0x27, 0x27, 0x35, 0x36, + 0x27, 0x56, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x2D, 0x49, 0x49, 0x49, + 0x49, 0x27, 0x27, 0x2D, 0x38, 0x27, 0x36, 0x36, + 0x49, 0x27, 0x49, 0x2D, 0x2D, 0x44, 0x24, 0x2B, + 0x20, 0x2C, 0x3F, 0x6B, 0x2A, 0x20, 0x21, 0x28, + 0x2C, 0x20, 0x2B, 0x24, 0x30, 0xCB, 0x63, 0x54, + 0x28, 0x20, 0x24, 0x2B, 0x23, 0x78, 0xC4, 0x63, + 0x63, 0x2B, 0x3F, 0x27, 0x27, 0x27, 0x38, 0x33, + 0x3D, 0xB9, 0x56, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x63, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x3D, 0x3D, 0x27, 0x27, 0x27, 0x2D, + 0x49, 0x49, 0x49, 0x2D, 0x62, 0x5F, 0xC4, 0x20, + 0x22, 0x2A, 0x6B, 0x8B, 0x2C, 0x2B, 0x2A, 0x3F, + 0x3F, 0x2A, 0x21, 0x21, 0xCB, 0x58, 0x6C, 0x60, + 0x20, 0x23, 0x24, 0x2A, 0x25, 0x78, 0x63, 0x63, + 0x54, 0x2A, 0x28, 0x27, 0x27, 0x27, 0x27, 0x62, + 0x3C, 0xB9, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x49, 0x2D, 0x2D, + 0x2D, 0x3D, 0x2F, 0x3C, 0x2D, 0x3C, 0x27, 0x38, + 0x2D, 0x49, 0x2D, 0x2D, 0xD1, 0x43, 0x30, 0x20, + 0x24, 0x21, 0x21, 0x21, 0x2B, 0x2A, 0x29, 0x8B, + 0x6B, 0x29, 0x2B, 0x2A, 0x30, 0x55, 0x55, 0x34, + 0x22, 0x23, 0x24, 0x29, 0x54, 0x30, 0x63, 0x63, + 0x25, 0x29, 0x22, 0x3C, 0xA5, 0xD4, 0xD5, 0x27, + 0x31, 0x56, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x2D, 0x2E, + 0x3E, 0x27, 0x27, 0x27, 0x27, 0x27, 0x36, 0x44, + 0x3C, 0x27, 0x2D, 0xC4, 0x78, 0xCC, 0x54, 0x2B, + 0x25, 0x24, 0x63, 0x60, 0x63, 0x24, 0x2A, 0x6B, + 0x3F, 0x39, 0x28, 0x21, 0x33, 0xB6, 0x44, 0x58, + 0x22, 0x23, 0x24, 0x2A, 0x30, 0x30, 0x63, 0x63, + 0x24, 0x39, 0x22, 0xBB, 0x9C, 0xB2, 0x9D, 0xA8, + 0x27, 0x8B, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0xD6, 0xD6, 0xD7, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x32, + 0x3D, 0x27, 0x39, 0x33, 0xC4, 0xC4, 0x22, 0x28, + 0x25, 0x54, 0x30, 0xD1, 0xD1, 0x60, 0x23, 0x6B, + 0x3F, 0x39, 0x2C, 0x2B, 0x20, 0x58, 0x8A, 0x58, + 0x22, 0x23, 0x23, 0x2B, 0x78, 0x30, 0xC4, 0xC4, + 0x23, 0x29, 0xBB, 0xBB, 0xD8, 0xB2, 0x9D, 0xA9, + 0xA9, 0x3C, 0x60, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0xB9, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0xB9, 0x56, 0xD9, 0x85, 0x85, 0x85, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2D, + 0xA0, 0x83, 0x2C, 0x21, 0x30, 0x33, 0x29, 0x29, + 0x21, 0x33, 0x54, 0x42, 0x66, 0x55, 0xC4, 0x29, + 0x8B, 0x2C, 0x39, 0x28, 0x29, 0x31, 0x44, 0x58, + 0x23, 0x23, 0x21, 0x20, 0x30, 0xC4, 0xC4, 0x30, + 0x21, 0x20, 0xBB, 0xBC, 0xDA, 0xDB, 0xDC, 0xB2, + 0x83, 0xB4, 0x3C, 0x2F, 0xB9, 0x56, 0x56, 0xB9, + 0x56, 0xB9, 0x56, 0x80, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0xA7, 0xD4, 0x85, 0x82, + 0x3C, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x61, + 0x9E, 0x90, 0xDD, 0x21, 0x33, 0x25, 0x2C, 0x39, + 0x2A, 0x24, 0x24, 0x42, 0x62, 0x43, 0x34, 0x22, + 0x50, 0x39, 0x2C, 0x2C, 0x2A, 0x54, 0xD1, 0x58, + 0x22, 0x22, 0x2B, 0x22, 0x30, 0xC4, 0x30, 0x60, + 0x20, 0xDE, 0xBB, 0xD9, 0x84, 0x84, 0xDF, 0xA9, + 0xDB, 0xDB, 0x61, 0x27, 0x38, 0x4D, 0x56, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x56, 0x56, 0x8D, 0xD9, 0xD5, 0xA6, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0xBB, + 0x85, 0xDB, 0xDD, 0x21, 0x22, 0x22, 0x3F, 0x39, + 0x2C, 0x2B, 0x25, 0x34, 0x62, 0x66, 0xD1, 0xC4, + 0x6B, 0x39, 0x2C, 0x39, 0x29, 0x21, 0x58, 0xCC, + 0x22, 0x21, 0x29, 0x23, 0x30, 0x30, 0x30, 0x5E, + 0x82, 0xBB, 0xE0, 0xB1, 0xE1, 0x9C, 0xD4, 0xDC, + 0x9D, 0xA9, 0xE2, 0x27, 0x27, 0x27, 0x4D, 0x56, + 0x56, 0xB9, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x4C, 0x48, 0xA8, 0xA8, 0xE3, 0x8C, + 0xC6, 0x3C, 0x27, 0x27, 0x27, 0xE4, 0xA6, 0xE5, + 0x83, 0xA9, 0xE6, 0xAF, 0x54, 0x2B, 0x8B, 0x39, + 0x39, 0x29, 0x20, 0x54, 0x42, 0x42, 0xB6, 0xCC, + 0x2A, 0x29, 0x39, 0x39, 0x2C, 0x2C, 0xCC, 0xCC, + 0x22, 0x20, 0x39, 0xE7, 0xC0, 0xD9, 0xA7, 0xBC, + 0x8D, 0xAA, 0x9C, 0xE8, 0x9C, 0x9D, 0xD4, 0xD4, + 0xD8, 0xA9, 0x84, 0xC7, 0x27, 0x27, 0x27, 0x2A, + 0x56, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x48, 0x50, 0xAA, 0xE3, 0xE3, 0xC0, + 0xA6, 0x9A, 0xBA, 0xC8, 0x9A, 0xDE, 0x9B, 0xD5, + 0xE8, 0xD8, 0xD5, 0x2E, 0x58, 0x33, 0x6B, 0x39, + 0x2C, 0x39, 0x29, 0x28, 0xD1, 0x43, 0xB6, 0xAF, + 0x23, 0x28, 0x2C, 0x39, 0x39, 0x8B, 0x30, 0x31, + 0x21, 0x20, 0x3F, 0xBB, 0xDF, 0xDF, 0xD5, 0xA8, + 0xD5, 0x9C, 0x8E, 0xB2, 0x9D, 0xE9, 0xD4, 0xD8, + 0x90, 0xB2, 0xA9, 0x8F, 0x27, 0x27, 0x27, 0x27, + 0x2F, 0x56, 0x56, 0xB9, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0xB9, 0x48, 0x48, 0x75, 0xE3, 0xAA, 0xAA, + 0xC0, 0xB4, 0xB4, 0xB4, 0x75, 0x9B, 0xD9, 0x83, + 0x9D, 0x90, 0xDF, 0xDD, 0x8A, 0x31, 0x4B, 0x2C, + 0x2C, 0x29, 0x2C, 0x3F, 0x6C, 0x55, 0xD1, 0x55, + 0x54, 0x29, 0x28, 0x39, 0x39, 0x6B, 0x24, 0x60, + 0x20, 0x2B, 0x3F, 0xA7, 0xB1, 0x9D, 0xA9, 0x8E, + 0xE5, 0xE5, 0xDF, 0xE0, 0xA9, 0x9D, 0xDF, 0xDF, + 0xEA, 0x9D, 0xB2, 0x84, 0xAA, 0x27, 0x27, 0x27, + 0x27, 0x35, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0xB9, 0x48, 0x48, 0xA6, 0x9B, 0xE3, 0xAA, + 0xAA, 0x9B, 0x9B, 0x9B, 0xAA, 0xE3, 0xD5, 0xD4, + 0x9D, 0xA9, 0xA9, 0x9D, 0xEB, 0xAF, 0x23, 0x28, + 0x2C, 0x29, 0x28, 0x39, 0x54, 0xCC, 0xAF, 0x55, + 0x30, 0x29, 0x2B, 0x2C, 0x39, 0x39, 0x2B, 0xC4, + 0x2B, 0x29, 0x39, 0xA7, 0x8E, 0x9D, 0x83, 0xE5, + 0xB1, 0xDB, 0xDC, 0xE0, 0xDC, 0x84, 0xE9, 0x84, + 0x83, 0xD4, 0xEC, 0x83, 0x8F, 0xE4, 0x27, 0x27, + 0x27, 0x27, 0x56, 0x56, 0x56, 0x56, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0xB9, 0x56, 0x40, 0x50, 0x9A, 0x75, 0xE3, 0xE3, + 0xE3, 0xD9, 0x8D, 0xAA, 0xD9, 0xA8, 0xB2, 0xDC, + 0xB2, 0x8D, 0x84, 0xEA, 0xB1, 0xEB, 0x54, 0x29, + 0x28, 0x2C, 0x2A, 0x28, 0x2B, 0x78, 0xCC, 0x58, + 0xCB, 0x20, 0x20, 0x29, 0x39, 0x39, 0x2C, 0x25, + 0x29, 0x2C, 0x39, 0xBB, 0xD9, 0xD9, 0x9D, 0x9D, + 0xB2, 0xB1, 0xD4, 0xDB, 0xB1, 0x9D, 0xD4, 0xEA, + 0xB1, 0x8D, 0xD8, 0x8E, 0x8F, 0xAA, 0x27, 0x27, + 0x27, 0x3D, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x47, 0xE4, 0xA6, 0x75, 0xAA, 0xA8, + 0x9C, 0x9C, 0xE1, 0x9C, 0x9C, 0x8E, 0xD8, 0x9D, + 0xA9, 0xDB, 0xA9, 0xDC, 0xD8, 0xDA, 0xD4, 0x2B, + 0x20, 0x2C, 0x28, 0x2A, 0x28, 0x63, 0x31, 0x58, + 0xCB, 0x24, 0x20, 0x2B, 0x2C, 0x39, 0x6B, 0x21, + 0x39, 0x6B, 0x2C, 0xC0, 0xE0, 0xB1, 0xB2, 0x9D, + 0x8E, 0xD8, 0xE0, 0xD9, 0x84, 0xDB, 0xD8, 0xB1, + 0x8E, 0xB2, 0xE2, 0x9C, 0x83, 0x9E, 0xBC, 0x3D, + 0xD3, 0x56, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0xB9, 0xB9, + 0x56, 0x4F, 0x27, 0x61, 0xA6, 0x9B, 0xE3, 0xA9, + 0xE9, 0xD4, 0xDA, 0xDB, 0x8E, 0xE1, 0xE9, 0x8E, + 0xD4, 0xA8, 0xE0, 0x84, 0xE8, 0xB1, 0xDC, 0x9D, + 0x20, 0x29, 0x29, 0x2B, 0x2C, 0x54, 0x78, 0xCC, + 0x78, 0x33, 0x2A, 0x20, 0x29, 0x39, 0x50, 0x2A, + 0x6B, 0x8B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xA9, + 0xB2, 0xDC, 0x8E, 0xDC, 0xE1, 0xDA, 0xA9, 0x8E, + 0xEA, 0xE2, 0x83, 0xE8, 0x8E, 0x83, 0xE2, 0xED, + 0xB9, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x56, 0xB9, + 0xC9, 0x27, 0x27, 0xE4, 0xA6, 0x9B, 0xD5, 0xA8, + 0xD4, 0xB2, 0xD8, 0xDA, 0xD9, 0xE8, 0xE9, 0xE8, + 0xD8, 0xB1, 0xDA, 0xB2, 0xE9, 0x8E, 0xEC, 0xDA, + 0x22, 0x20, 0x39, 0x2B, 0x39, 0x24, 0xC4, 0x30, + 0x30, 0x54, 0x22, 0x29, 0x29, 0x39, 0x48, 0x2C, + 0x39, 0x6B, 0x39, 0xC0, 0x8D, 0xB1, 0xE9, 0xB2, + 0xB2, 0x8E, 0xA9, 0xD8, 0xDA, 0xB1, 0xA9, 0xDA, + 0x9C, 0xDC, 0x8E, 0xD4, 0xE8, 0xE8, 0x8F, 0x9B, + 0x4F, 0xB9, 0x56, 0xB9, 0x56, 0xB9, 0xB9, 0xB9, + 0xB9, 0xB9, 0xB9, 0xB9, 0x56, 0x56, 0x4F, 0x6B, + 0x27, 0x27, 0x27, 0xD7, 0xDE, 0xAA, 0xE3, 0xA8, + 0xB2, 0xD5, 0xE5, 0x90, 0xE2, 0xA9, 0xE9, 0xB2, + 0xDA, 0xB2, 0xE1, 0xB2, 0xE9, 0x8E, 0xDA, 0xDF, + 0x78, 0x2A, 0x2C, 0x2A, 0x6B, 0x28, 0x23, 0x54, + 0x63, 0xC4, 0x33, 0x28, 0x2C, 0x39, 0x47, 0x39, + 0x28, 0x2C, 0x29, 0xBB, 0x8D, 0x83, 0xE9, 0xD4, + 0xB2, 0xE9, 0xE9, 0xE8, 0xD4, 0xD8, 0xD4, 0xA9, + 0xDA, 0xB2, 0xE9, 0xA8, 0xB2, 0xA8, 0xD5, 0xAA, + 0xC6, 0x56, 0x56, 0x56, 0x56, 0x56, 0xB9, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0xC9, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0x9B, 0xE3, 0x8E, + 0x9D, 0x8E, 0xB2, 0xE8, 0xE8, 0x8E, 0xB2, 0xDA, + 0xB2, 0x8E, 0xEC, 0xB2, 0x8E, 0xB2, 0xBB, 0x58, + 0xAF, 0x33, 0x50, 0x39, 0x6B, 0x39, 0x29, 0x20, + 0x33, 0x30, 0x78, 0x23, 0x6B, 0x6B, 0x48, 0x6B, + 0x2B, 0x2A, 0x29, 0xBB, 0xE5, 0x9C, 0xB1, 0xB2, + 0xE5, 0x84, 0x8E, 0x9C, 0x84, 0xB2, 0xB2, 0x9D, + 0x84, 0xDF, 0xA9, 0x84, 0x8E, 0xA8, 0xE3, 0x9B, + 0xA6, 0xD7, 0x80, 0x4F, 0x56, 0x56, 0x56, 0x4F, + 0x4F, 0x4F, 0x4F, 0x2A, 0x2D, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xB8, 0xB4, 0xAA, 0xD5, 0xA9, + 0x9D, 0xB2, 0x90, 0xEA, 0xE9, 0xE2, 0xE1, 0x8E, + 0xB2, 0x9D, 0x8E, 0xB1, 0xA7, 0xEE, 0x63, 0xD1, + 0x2E, 0xCC, 0x28, 0x48, 0x8B, 0x47, 0x6B, 0x28, + 0x23, 0x78, 0x6C, 0x54, 0x29, 0x50, 0x50, 0x6B, + 0x23, 0x20, 0xBB, 0xBC, 0xBB, 0x8D, 0xE3, 0xDF, + 0x9C, 0xA9, 0x8D, 0xA8, 0xD9, 0x90, 0x9D, 0xA9, + 0xDC, 0xA9, 0x83, 0xB2, 0xA9, 0xD4, 0xE3, 0x9B, + 0x8C, 0xEF, 0x27, 0x27, 0x27, 0x3C, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0x84, + 0x9D, 0x84, 0x90, 0xB1, 0xA9, 0x9C, 0xD9, 0xB1, + 0xB2, 0xEA, 0xBB, 0x51, 0x24, 0x30, 0x30, 0x42, + 0x66, 0x58, 0x24, 0x48, 0x50, 0x3F, 0x20, 0x25, + 0x22, 0x60, 0x34, 0x30, 0x20, 0x8B, 0x8B, 0x39, + 0x54, 0x24, 0x2B, 0xC0, 0xC0, 0xC0, 0xBB, 0x9B, + 0xBC, 0xAA, 0xAA, 0xE3, 0xE3, 0x9C, 0xB2, 0xD4, + 0x83, 0xD8, 0xE8, 0x83, 0x84, 0xE8, 0xE5, 0x75, + 0x9A, 0xF0, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF0, 0xB4, 0x9B, 0xE3, 0xA8, + 0xA9, 0xD8, 0x8E, 0xEA, 0xA8, 0x9C, 0xD9, 0xE0, + 0xC0, 0x5E, 0x2C, 0x20, 0x54, 0x60, 0x30, 0x66, + 0xB6, 0xCC, 0x63, 0x3F, 0x8B, 0x28, 0x22, 0x33, + 0x23, 0x31, 0xAF, 0x31, 0x22, 0x6B, 0x6B, 0x29, + 0x30, 0x54, 0x22, 0x89, 0xBA, 0xED, 0xA6, 0x8C, + 0xB4, 0xC0, 0xB4, 0x75, 0x75, 0x9B, 0x9B, 0xE5, + 0xA9, 0xD5, 0x8E, 0x8E, 0x9C, 0xE3, 0x75, 0x8C, + 0xC8, 0xF1, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xF1, 0x9A, 0xB4, 0x9B, 0xE3, + 0xE3, 0xA8, 0xE3, 0xE5, 0xAA, 0xBC, 0xC0, 0x9A, + 0x26, 0x29, 0x20, 0x24, 0x63, 0x60, 0x54, 0x43, + 0x34, 0xCB, 0x30, 0x39, 0x2C, 0x20, 0x24, 0x54, + 0x22, 0x34, 0x34, 0x31, 0x24, 0x3F, 0x2C, 0x2B, + 0x31, 0x30, 0x25, 0x2A, 0x6B, 0x29, 0x20, 0xF2, + 0xBA, 0xBF, 0xC8, 0x9A, 0xA6, 0xA6, 0x8C, 0xB4, + 0x9B, 0xAA, 0xAA, 0xAA, 0x9B, 0x75, 0xDE, 0xBF, + 0x81, 0xEF, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0xEF, 0xBA, 0x9A, 0xB4, 0x75, + 0x9B, 0x9B, 0x9B, 0xC0, 0xB4, 0x9A, 0xA5, 0xC4, + 0x30, 0x28, 0x22, 0x33, 0x30, 0x30, 0x23, 0x34, + 0x31, 0x30, 0xC4, 0x2C, 0x2B, 0x22, 0x33, 0x63, + 0x21, 0x58, 0x6C, 0x60, 0x25, 0x39, 0x28, 0x2B, + 0xCC, 0x6C, 0x63, 0x20, 0x6B, 0x28, 0x2B, 0x20, + 0x63, 0x43, 0xF3, 0xEF, 0xF0, 0x81, 0xBA, 0xF4, + 0xF4, 0xA6, 0xDE, 0x8C, 0xA6, 0x9A, 0xBA, 0x81, + 0xB0, 0xE4, 0xA1, 0x20, 0x20, 0x23, 0x31, 0xC4, + 0x30, 0x24, 0x33, 0x31, 0x31, 0x60, 0x43, 0x35, + 0x35, 0x55, 0x6C, 0xEF, 0x81, 0xC8, 0x9A, 0xA6, + 0xB4, 0xB4, 0x8C, 0xA6, 0xBA, 0x68, 0x30, 0x30, + 0x30, 0x2B, 0x25, 0x54, 0xC4, 0x54, 0x24, 0x78, + 0x63, 0x63, 0x30, 0x29, 0x21, 0x24, 0x54, 0x63, + 0x23, 0x34, 0xCB, 0x30, 0x25, 0x39, 0x20, 0x20, + 0x58, 0x34, 0x60, 0x23, 0x6B, 0x29, 0x28, 0x20, + 0x22, 0xB6, 0x42, 0xB6, 0x58, 0x54, 0xF5, 0xD7, + 0xA5, 0xBA, 0xBA, 0xBA, 0xBA, 0x81, 0xA5, 0xF1, + 0xE4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x31, 0x60, + 0x54, 0x28, 0x2B, 0x22, 0x33, 0x30, 0x43, 0x35, + 0x66, 0xD1, 0x34, 0xE4, 0xEF, 0x81, 0xC8, 0x9A, + 0x9A, 0xC8, 0xC8, 0x81, 0xF6, 0x31, 0x63, 0x31, + 0x78, 0x2B, 0x54, 0x63, 0x54, 0x24, 0x23, 0x54, + 0x63, 0x54, 0x63, 0x2C, 0x23, 0x33, 0x63, 0x54, + 0x25, 0x31, 0x78, 0x30, 0x25, 0x3F, 0x20, 0x20, + 0xAF, 0x58, 0xCC, 0x33, 0x39, 0x29, 0x29, 0x2A, + 0x29, 0x58, 0x43, 0x42, 0xD1, 0xCB, 0x2C, 0x2C, + 0x37, 0xCD, 0xEF, 0xB0, 0xF0, 0xB0, 0xEF, 0xE4, + 0x63, 0x20, 0x20, 0x2C, 0x2C, 0x21, 0xCB, 0x78, + 0x54, 0x39, 0x39, 0x28, 0x2B, 0x28, 0x2B, 0xCB, + 0x55, 0xB6, 0xD1, 0x28, 0xE4, 0xD7, 0xB8, 0xF0, + 0xA5, 0xB0, 0xEF, 0x26, 0x23, 0x54, 0x31, 0x58, + 0xCB, 0x20, 0x63, 0x63, 0x25, 0x2B, 0x54, 0x78, + 0x30, 0x63, 0x54, 0x28, 0x33, 0x63, 0x63, 0x33, + 0x54, 0x78, 0xC4, 0x30, 0x24, 0x2C, 0x22, 0x22, + 0x55, 0x55, 0x34, 0x30, 0x28, 0x2C, 0x29, 0x29, + 0x28, 0x30, 0xB6, 0x42, 0x43, 0x55, 0x22, 0x29, + 0x2C, 0x2B, 0x2B, 0x3F, 0xE4, 0xE4, 0x43, 0x66, + 0x30, 0x23, 0x24, 0x2A, 0x28, 0x2B, 0x54, 0x63, + 0x33, 0x39, 0x28, 0x20, 0x20, 0x20, 0x2B, 0x31, + 0x30, 0xD1, 0x43, 0x30, 0x39, 0x28, 0xE4, 0xE4, + 0xD7, 0xF5, 0x2B, 0x6B, 0x20, 0x30, 0x34, 0xD1, + 0x60, 0x23, 0x63, 0x54, 0x22, 0x47, 0x60, 0xCB, + 0xC4, 0xC4, 0x25, 0x22, 0x54, 0xC4, 0x63, 0x23, + 0xC4, 0xC4, 0x63, 0xC4, 0x23, 0x2A, 0x24, 0x22, + 0x55, 0x55, 0xAF, 0x6C, 0x22, 0x39, 0x2C, 0x39, + 0x28, 0x23, 0xD1, 0x43, 0x42, 0x8A, 0x63, 0x39, + 0x39, 0x2A, 0x20, 0x6B, 0x33, 0xCC, 0xD1, 0xB6, + 0x30, 0x24, 0x54, 0x63, 0x31, 0xCC, 0xCC, 0xCB, + 0xC4, 0x2A, 0x39, 0x20, 0x20, 0x20, 0x39, 0x30, + 0x30, 0x6C, 0x43, 0x43, 0x6C, 0x63, 0x25, 0x24, + 0x63, 0x63, 0x63, 0x25, 0x63, 0xCC, 0xD1, 0x34, + 0x63, 0x25, 0x54, 0x25, 0x2A, 0x28, 0x31, 0xCB, + 0x63, 0x78, 0x24, 0x33, 0xC4, 0xC4, 0x33, 0x2C, + 0xC4, 0x54, 0x54, 0x30, 0x21, 0x22, 0x25, 0x23, + 0x55, 0x55, 0xD1, 0x58, 0x33, 0x6B, 0x2C, 0x39, + 0x39, 0x39, 0x34, 0x43, 0x42, 0x43, 0xCC, 0x2B, + 0x28, 0x29, 0x20, 0x28, 0x21, 0x30, 0xCC, 0xAF, + 0x54, 0x23, 0xC4, 0x54, 0x58, 0x2E, 0x35, 0x42, + 0x55, 0x54, 0x8B, 0x2A, 0x20, 0x20, 0x28, 0x22, + 0x78, 0x30, 0xD1, 0x43, 0x44, 0x6C, 0xC4, 0xC4, + 0x60, 0x31, 0x31, 0x63, 0x6C, 0xAF, 0xCC, 0xCB, + 0x24, 0x25, 0x33, 0x23, 0x2C, 0x24, 0x31, 0x30, + 0x63, 0xC4, 0x21, 0x54, 0x30, 0x63, 0x24, 0x2A, + 0x54, 0x63, 0x54, 0xC4, 0x2B, 0x24, 0x33, 0x24, + 0x34, 0x55, 0xD1, 0x55, 0x30, 0x28, 0x29, 0x39, + 0x39, 0x8B, 0x63, 0x55, 0x42, 0x66, 0xB6, 0x25, + 0x29, 0x29, 0x29, 0x28, 0x2A, 0x54, 0x78, 0x6C, + 0x23, 0x20, 0x25, 0x30, 0xCB, 0x62, 0x35, 0x35, + 0x35, 0x44, 0x24, 0x6B, 0x29, 0x20, 0x2A, 0x39, + 0x28, 0x63, 0x34, 0xB6, 0x34, 0xCB, 0x63, 0x30, + 0x31, 0x31, 0x30, 0x30, 0xCC, 0x60, 0x63, 0xC4, + 0x20, 0x33, 0x25, 0x20, 0x48, 0x33, 0x30, 0x54, + 0x78, 0x54, 0x2B, 0x63, 0x30, 0x63, 0x23, 0x22, + 0x63, 0x63, 0x63, 0x33, 0x28, 0x25, 0x54, 0x24, + 0x78, 0xAF, 0xD1, 0xD1, 0xCC, 0x22, 0x39, 0x39, + 0x2C, 0x3F, 0x2B, 0x34, 0xB6, 0x43, 0x43, 0xC4, + 0x2B, 0x28, 0x39, 0x50, 0x2C, 0x24, 0x63, 0x78, + 0x21, 0x2C, 0x2A, 0x23, 0x54, 0xD1, 0x35, 0x35, + 0x35, 0x35, 0x55, 0x22, 0x39, 0x2C, 0x2C, 0x2C, + 0x20, 0x30, 0xCC, 0x6C, 0xCB, 0x30, 0x54, 0x30, + 0x78, 0x63, 0x78, 0x30, 0x54, 0x78, 0x30, 0x23, + 0x2B, 0x33, 0x24, 0x28, 0x39, 0x24, 0x54, 0x30, + 0x78, 0x33, 0x25, 0xC4, 0xC4, 0x33, 0x39, 0x25, + 0xC4, 0x63, 0xC4, 0x24, 0x20, 0x54, 0x54, 0x25, + 0x63, 0xCC, 0xD1, 0xB6, 0x55, 0x54, 0x39, 0x29, + 0x39, 0x2C, 0x6B, 0x30, 0xAF, 0xB6, 0xB6, 0x60, + 0x22, 0x2A, 0x2C, 0x39, 0x2C, 0x21, 0x54, 0x63, + 0x21, 0x50, 0x2C, 0x2C, 0x2B, 0x25, 0x62, 0x35, + 0x35, 0x35, 0x35, 0xCC, 0x2B, 0x29, 0x2B, 0x20, + 0x23, 0x25, 0xC4, 0x30, 0xC4, 0x63, 0x63, 0x63, + 0x63, 0x33, 0x24, 0x31, 0x31, 0x31, 0x54, 0x28, + 0x24, 0x25, 0x22, 0x6B, 0x28, 0x24, 0xC4, 0x78, + 0x30, 0x24, 0x63, 0xC4, 0x54, 0x23, 0x29, 0x63, + 0xC4, 0x54, 0xC4, 0x21, 0x24, 0x54, 0x54, 0x25, + 0x30, 0xCB, 0xD1, 0xB6, 0x55, 0x63, 0x28, 0x29, + 0x39, 0x39, 0x48, 0x33, 0x58, 0x44, 0xB6, 0x60, + 0x24, 0x20, 0x2B, 0x28, 0x2A, 0x22, 0x54, 0x63, + 0x21, 0x48, 0x2A, 0x2B, 0x39, 0x21, 0xB6, 0x35, + 0x35, 0x35, 0x35, 0x42, 0x23, 0x29, 0x2A, 0x2B, + 0x23, 0x25, 0x54, 0x54, 0x54, 0x63, 0x63, 0x30, + 0x25, 0x2B, 0x31, 0x31, 0x31, 0x31, 0x21, 0x2C, + 0x33, 0x25, 0x21, 0x39, 0x20, 0x25, 0x30, 0x78, + 0xC4, 0x23, 0xC4, 0x30, 0x54, 0x20, 0x28, 0x63, + 0x63, 0x63, 0x63, 0x20, 0x25, 0x54, 0x54, 0x20, +}; + +unsigned char linux_logo_bw[] __initdata = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9, + 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7, + 0x99, 0xF9, 0xC2, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF9, 0xF3, 0xBC, 0xF9, 0x90, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xA0, 0x00, + 0x8F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9, + 0x83, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, + 0x19, 0xF0, 0x1F, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x03, 0xF0, 0x3F, 0xF7, 0x8F, 0xFF, + 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0x7F, 0xF7, + 0xC7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, + 0x6F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, + 0x01, 0xF8, 0x7F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, + 0xF9, 0xC0, 0x21, 0xD8, 0x7F, 0xE7, 0xEF, 0xFF, + 0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0x7B, 0xFF, + 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4, + 0x7B, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C, + 0xC0, 0x7C, 0x79, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, + 0xE3, 0x80, 0x00, 0x7C, 0x7C, 0xFF, 0xCF, 0xFF, + 0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0x77, 0xFF, + 0xDF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F, + 0x3F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, + 0x00, 0x3F, 0xBF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x1F, 0x9F, 0xFF, 0x3F, 0xFF, + 0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1F, 0x9F, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1F, + 0x8F, 0xFE, 0x7F, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, + 0x00, 0x0F, 0xC7, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, + 0xF8, 0x00, 0x00, 0x0F, 0xF7, 0xF9, 0xFF, 0xFF, + 0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x07, 0xFB, 0xF3, + 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x07, + 0xFD, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00, + 0x00, 0x03, 0xFE, 0x8F, 0xFF, 0xFF, 0xFF, 0xF1, + 0xF0, 0x00, 0x00, 0x03, 0xFE, 0x1F, 0xFF, 0xFF, + 0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xBF, + 0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00, + 0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, + 0x00, 0x00, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xC7, + 0xC0, 0x00, 0x00, 0x01, 0xFE, 0xBF, 0xFF, 0xFF, + 0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x9F, + 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01, + 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, + 0x00, 0x01, 0xFE, 0x87, 0xFF, 0xFF, 0xFF, 0x9F, + 0x80, 0x00, 0x00, 0x01, 0xFD, 0x33, 0xFF, 0xFF, + 0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0xF3, + 0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03, + 0x8B, 0xF9, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00, + 0x00, 0x02, 0x27, 0xF8, 0xFF, 0xFF, 0xFF, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x07, 0xF8, 0xFF, 0xFF, + 0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0x8F, 0xF8, + 0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00, + 0xE3, 0xF8, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00, + 0x00, 0x00, 0xF8, 0x78, 0xFF, 0xFF, 0xC0, 0x40, + 0x38, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x7F, 0xFF, + 0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x20, + 0x7F, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x78, 0x10, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, + 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04, + 0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0, + 0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40, + 0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40, + 0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF, + 0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F, + 0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF, + 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07, + 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +/* Painted by Johnny Stenback */ + +unsigned char *linux_serial_image __initdata = "\n" +" .u$e.\n" +" .$$$$$:S\n" +" $\"*$/\"*$$\n" +" $.`$ . ^F\n" +" 4k+#+T.$F\n" +" 4P+++\"$\"$\n" +" :R\"+ t$$B\n" +" ___# $$$\n" +" | | R$$k\n" +" dd. | Linux $!$\n" +" ddd | Sparc $9$F\n" +" '!!!!!$ !!#!`\n" +" !!!!!* .!!!!!`\n" +"'!!!!!!!W..e$$!!!!!!` %s\n" +" \"~^^~ ^~~^\n" +"\n"; diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h --- v2.1.35/linux/include/asm-sparc64/pgtable.h Mon Apr 14 16:28:23 1997 +++ linux/include/asm-sparc64/pgtable.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.27 1997/04/10 23:32:46 davem Exp $ +/* $Id: pgtable.h,v 1.28 1997/04/14 17:05:19 jj Exp $ * pgtable.h: SpitFire page table operations. * * Copyright 1996 David S. Miller (davem@caip.rutgers.edu) @@ -672,6 +672,31 @@ #define SWP_TYPE(entry) (((entry>>PAGE_SHIFT) & 0xff)) #define SWP_OFFSET(entry) ((entry) >> (PAGE_SHIFT+8)) #define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset))) + +extern __inline__ unsigned long +sun4u_get_pte (unsigned long addr) +{ + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + pgdp = pgd_offset (current->mm, addr); + pmdp = pmd_offset (pgdp, addr); + ptep = pte_offset (pmdp, addr); + return pte_val (*ptep) & _PAGE_PADDR; +} + +extern __inline__ unsigned int +__get_phys (unsigned long addr) +{ + return (sun4u_get_pte (addr) & 0x0fffffff); +} + +extern __inline__ int +__get_iospace (unsigned long addr) +{ + return ((sun4u_get_pte (addr) & 0xf0000000) >> 28); +} #endif /* !(__ASSEMBLY__) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/posix_types.h linux/include/asm-sparc64/posix_types.h --- v2.1.35/linux/include/asm-sparc64/posix_types.h Mon Apr 14 16:28:23 1997 +++ linux/include/asm-sparc64/posix_types.h Tue Apr 15 21:47:24 1997 @@ -34,6 +34,27 @@ int val[2]; } __kernel_fsid_t; +/* Now 32bit compatibility types */ +typedef unsigned int __kernel_size_t32; +typedef int __kernel_ssize_t32; +typedef int __kernel_ptrdiff_t32; +typedef int __kernel_time_t32; +typedef int __kernel_clock_t32; +typedef int __kernel_pid_t32; +typedef unsigned short __kernel_ipc_pid_t32; +typedef unsigned short __kernel_uid_t32; +typedef unsigned short __kernel_gid_t32; +typedef unsigned short __kernel_dev_t32; +typedef unsigned int __kernel_ino_t32; +typedef unsigned short __kernel_mode_t32; +typedef unsigned short __kernel_umode_t32; +typedef short __kernel_nlink_t32; +typedef int __kernel_daddr_t32; +typedef int __kernel_off_t32; +typedef unsigned int __kernel_caddr_t32; +typedef long __kernel_loff_t32; +typedef __kernel_fsid_t __kernel_fsid_t32; + #undef __FD_SET static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) { diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h --- v2.1.35/linux/include/asm-sparc64/processor.h Mon Apr 14 16:28:23 1997 +++ linux/include/asm-sparc64/processor.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.20 1997/04/11 22:34:54 davem Exp $ +/* $Id: processor.h,v 1.21 1997/04/14 17:05:18 jj Exp $ * include/asm-sparc64/processor.h * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -132,6 +132,7 @@ "stx %%g0, [%0 + %2 + 0x68]\n\t" \ "stx %1, [%0 + %2 + 0x70]\n\t" \ "stx %%g0, [%0 + %2 + 0x78]\n\t" \ + "wrpr %%g0, 1, %%wstate\n\t" \ : \ : "r" (regs), "r" (sp - REGWIN_SZ), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ @@ -167,6 +168,7 @@ "stx %%g0, [%0 + %2 + 0x68]\n\t" \ "stx %1, [%0 + %2 + 0x70]\n\t" \ "stx %%g0, [%0 + %2 + 0x78]\n\t" \ + "wrpr %%g0, 2, %%wstate\n\t" \ : \ : "r" (regs), "r" (sp - REGWIN32_SZ), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])), \ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/semaphore.h linux/include/asm-sparc64/semaphore.h --- v2.1.35/linux/include/asm-sparc64/semaphore.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/semaphore.h Thu Apr 17 13:20:51 1997 @@ -2,8 +2,10 @@ #define _SPARC64_SEMAPHORE_H /* These are actually reasonable on the V9. */ +#ifdef __KERNEL__ #include +#include struct semaphore { atomic_t count; @@ -11,8 +13,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); @@ -20,6 +22,23 @@ #define sema_init(sem, val) atomic_set(&((sem)->count), val) +#define wake_one_more(sem) atomic_inc(&sem->waking); + +extern __inline__ int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int ret = 0; + + save_flags(flags); + cli(); + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 1; + } + restore_flags(flags); + return ret; +} + extern __inline__ void down(struct semaphore * sem) { if (atomic_dec_return(&sem->count) < 0) @@ -39,5 +58,7 @@ if (atomic_inc_return(&sem->count) <= 0) __up(sem); } + +#endif /* __KERNEL__ */ #endif /* !(_SPARC64_SEMAPHORE_H) */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/signal.h linux/include/asm-sparc64/signal.h --- v2.1.35/linux/include/asm-sparc64/signal.h Mon Mar 17 14:54:34 1997 +++ linux/include/asm-sparc64/signal.h Tue Apr 22 22:39:21 1997 @@ -1,4 +1,4 @@ -/* $Id: signal.h,v 1.2 1997/03/03 16:51:57 jj Exp $ */ +/* $Id: signal.h,v 1.3 1997/04/18 14:34:47 jj Exp $ */ #ifndef _ASMSPARC64_SIGNAL_H #define _ASMSPARC64_SIGNAL_H @@ -83,7 +83,7 @@ #ifndef __ASSEMBLY__ typedef unsigned long sigset_t; -typedef unsigned int sigset32_t; +typedef unsigned int sigset_t32; #ifdef __KERNEL__ #include @@ -165,10 +165,8 @@ struct sigaction32 { unsigned sa_handler; - sigset32_t sa_mask; + sigset_t32 sa_mask; unsigned int sa_flags; - - /* XXX 32-bit func ptr... */ unsigned sa_restorer; /* not used by Linux/SPARC yet */ }; diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/smp.h linux/include/asm-sparc64/smp.h --- v2.1.35/linux/include/asm-sparc64/smp.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/smp.h Tue Apr 15 21:47:24 1997 @@ -106,51 +106,6 @@ extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ -extern __volatile__ int smp_process_available; - -extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr) -{ - unsigned long temp0, temp1; - - __asm__ __volatile__(" - lduw [%2], %0 -1: - add %0, 1, %1 - cas [%2], %0, %1 - cmp %0, %1 - bne,a,pn %%icc, 1b - lduw [%2], %0 -2: - membar #StoreStore | #StoreLoad -" : "=&r" (temp0), "=&r" (temp1), "=r" (ctr) - : "ir" (i), "r" (ctr) - : "cc"); -} - -extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr) -{ - unsigned long temp0, temp1; - - __asm__ __volatile__(" - lduw [%2], %0 -1: - sub %0, 1, %1 - cas [%2], %0, %1 - cmp %0, %1 - bne,a,pn %%icc, 1b - lduw [%2], %0 -2: - membar #StoreStore | #StoreLoad -" : "=&r" (temp0), "=&r" (temp1), "=r" (ctr) - : "ir" (i), "r" (ctr) - : "cc"); -} - -extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr) -{ - return *ctr; -} - #endif /* !(__ASSEMBLY__) */ /* Sparc specific messages. */ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/smp_lock.h linux/include/asm-sparc64/smp_lock.h --- v2.1.35/linux/include/asm-sparc64/smp_lock.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/smp_lock.h Thu Apr 17 09:24:45 1997 @@ -15,7 +15,7 @@ #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) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) #else #error SMP on sparc64 not supported yet diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/softirq.h linux/include/asm-sparc64/softirq.h --- v2.1.35/linux/include/asm-sparc64/softirq.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/softirq.h Tue Apr 22 22:39:21 1997 @@ -34,6 +34,12 @@ bh_mask |= 1 << ent; \ } while(0) +#define remove_bh(nr) \ +do { int ent = nr; \ + bh_base[ent] = NULL; \ + bh_mask &= ~(1 << ent); \ +} while(0) + #define mark_bh(nr) (bh_active |= (1 << (nr))) #define disable_bh(nr) \ diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/spinlock.h linux/include/asm-sparc64/spinlock.h --- v2.1.35/linux/include/asm-sparc64/spinlock.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/spinlock.h Tue Apr 22 22:39:21 1997 @@ -16,12 +16,40 @@ #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 diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/stat.h linux/include/asm-sparc64/stat.h --- v2.1.35/linux/include/asm-sparc64/stat.h Mon Dec 30 02:00:03 1996 +++ linux/include/asm-sparc64/stat.h Tue Apr 22 22:39:21 1997 @@ -1,41 +1,26 @@ -/* $Id: stat.h,v 1.1 1996/12/26 14:22:31 davem Exp $ */ +/* $Id: stat.h,v 1.3 1997/04/18 14:34:43 jj Exp $ */ #ifndef _SPARC64_STAT_H #define _SPARC64_STAT_H #include -struct __old_kernel_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - -/* XXX Fix this for full backwards 32-bit compat. */ struct stat32 { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - short st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - off_t st_size; - time_t st_atime; - unsigned int __unused1; - time_t st_mtime; - unsigned int __unused2; - time_t st_ctime; - unsigned int __unused3; - off_t st_blksize; - off_t st_blocks; + __kernel_dev_t32 st_dev; + __kernel_ino_t32 st_ino; + __kernel_mode_t32 st_mode; + short st_nlink; + __kernel_uid_t32 st_uid; + __kernel_gid_t32 st_gid; + __kernel_dev_t32 st_rdev; + __kernel_off_t32 st_size; + __kernel_time_t32 st_atime; + unsigned int __unused1; + __kernel_time_t32 st_mtime; + unsigned int __unused2; + __kernel_time_t32 st_ctime; + unsigned int __unused3; + __kernel_off_t32 st_blksize; + __kernel_off_t32 st_blocks; unsigned int __unused4[2]; }; @@ -49,11 +34,8 @@ dev_t st_rdev; off_t st_size; time_t st_atime; - unsigned long __unused1; time_t st_mtime; - unsigned long __unused2; time_t st_ctime; - unsigned long __unused3; off_t st_blksize; off_t st_blocks; unsigned long __unused4[2]; diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/statfs.h linux/include/asm-sparc64/statfs.h --- v2.1.35/linux/include/asm-sparc64/statfs.h Mon Dec 30 02:00:03 1996 +++ linux/include/asm-sparc64/statfs.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: statfs.h,v 1.1 1996/12/26 14:22:40 davem Exp $ */ +/* $Id: statfs.h,v 1.2 1997/04/14 17:05:22 jj Exp $ */ #ifndef _SPARC64_STATFS_H #define _SPARC64_STATFS_H @@ -10,7 +10,6 @@ #endif -/* XXX Fix this for full backwards 32-bit compat. */ struct statfs32 { int f_type; int f_bsize; @@ -19,7 +18,7 @@ int f_bavail; int f_files; int f_ffree; - __kernel_fsid_t f_fsid; + __kernel_fsid_t32 f_fsid; int f_namelen; /* SunOS ignores this field. */ int f_spare[6]; }; diff -u --recursive --new-file v2.1.35/linux/include/asm-sparc64/unistd.h linux/include/asm-sparc64/unistd.h --- v2.1.35/linux/include/asm-sparc64/unistd.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/unistd.h Tue Apr 22 22:49:38 1997 @@ -1,4 +1,4 @@ -/* $Id: unistd.h,v 1.3 1997/04/10 23:32:51 davem Exp $ */ +/* $Id: unistd.h,v 1.4 1997/04/19 08:52:25 jj Exp $ */ #ifndef _SPARC64_UNISTD_H #define _SPARC64_UNISTD_H @@ -270,7 +270,7 @@ #define __NR__sysctl 251 #define __NR_getsid 252 #define __NR_fdatasync 253 -#define __NR_nfsctl 254 +#define __NR_nfsservctl 254 #define __NR_aplib 255 #define _syscall0(type,name) \ diff -u --recursive --new-file v2.1.35/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.35/linux/include/linux/fs.h Mon Apr 7 11:35:31 1997 +++ linux/include/linux/fs.h Wed Apr 23 11:00:45 1997 @@ -36,7 +36,7 @@ /* And dynamically-tunable limits and defaults: */ extern int max_inodes, nr_inodes; extern int max_files, nr_files; -#define NR_INODE 3072 /* this should be bigger than NR_FILE */ +#define NR_INODE 4096 /* this should be bigger than NR_FILE */ #define NR_FILE 1024 /* this can well be larger on a larger system */ #define MAY_EXEC 1 @@ -128,7 +128,7 @@ #include extern void buffer_init(void); -extern unsigned long inode_init(unsigned long start, unsigned long end); +extern void inode_init(void); extern unsigned long file_table_init(unsigned long start, unsigned long end); extern unsigned long name_cache_init(unsigned long start, unsigned long end); @@ -179,7 +179,7 @@ unsigned long b_lru_time; /* Time when this buffer was * last used. */ struct wait_queue * b_wait; - struct buffer_head * b_prev; /* doubly linked list of hash-queue */ + struct buffer_head ** b_pprev; /* doubly linked list of hash-queue */ struct buffer_head * b_prev_free; /* doubly linked list of buffers */ struct buffer_head * b_reqnext; /* request queue */ }; @@ -270,8 +270,13 @@ #include struct inode { - kdev_t i_dev; + struct inode *i_hash_next; + struct inode **i_hash_pprev; + struct inode *i_next; + struct inode **i_pprev; unsigned long i_ino; + kdev_t i_dev; + unsigned short i_count; umode_t i_mode; nlink_t i_nlink; uid_t i_uid; @@ -293,11 +298,8 @@ struct vm_area_struct *i_mmap; struct page *i_pages; struct dquot *i_dquot[MAXQUOTAS]; - struct inode *i_next, *i_prev; - struct inode *i_hash_next, *i_hash_prev; struct inode *i_bound_to, *i_bound_by; struct inode *i_mount; - unsigned short i_count; unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; diff -u --recursive --new-file v2.1.35/linux/include/linux/init.h linux/include/linux/init.h --- v2.1.35/linux/include/linux/init.h Thu Mar 27 14:40:10 1997 +++ linux/include/linux/init.h Thu Apr 17 13:20:51 1997 @@ -30,6 +30,22 @@ * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; */ +/* + * Disable the __initfunc macros if a file that is a part of a + * module attempts to use them. We do not want to interfere + * with module linking. + */ + +#ifndef MODULE #include +#else +#define __init +#define __initdata +#define __initfunc(__arginit) __arginit +/* For assembly routines */ +#define __INIT +#define __FINIT +#define __INITDATA +#endif #endif diff -u --recursive --new-file v2.1.35/linux/include/linux/mm.h linux/include/linux/mm.h --- v2.1.35/linux/include/linux/mm.h Thu Feb 6 02:53:33 1997 +++ linux/include/linux/mm.h Wed Apr 23 11:00:46 1997 @@ -125,7 +125,7 @@ unsigned dirty:16, age:8; struct wait_queue *wait; - struct page *prev_hash; + struct page **pprev_hash; struct buffer_head * buffers; unsigned long swap_unlock_entry; unsigned long map_nr; /* page->map_nr == page - mem_map */ diff -u --recursive --new-file v2.1.35/linux/include/linux/pagemap.h linux/include/linux/pagemap.h --- v2.1.35/linux/include/linux/pagemap.h Thu Feb 6 02:53:33 1997 +++ linux/include/linux/pagemap.h Wed Apr 23 11:00:46 1997 @@ -71,20 +71,12 @@ static inline void remove_page_from_hash_queue(struct page * page) { - struct page **p; - struct page *next_hash, *prev_hash; - - next_hash = page->next_hash; - prev_hash = page->prev_hash; - page->next_hash = NULL; - page->prev_hash = NULL; - if (next_hash) - next_hash->prev_hash = prev_hash; - if (prev_hash) - prev_hash->next_hash = next_hash; - p = page_hash(page->inode,page->offset); - if (*p == page) - *p = next_hash; + if(page->pprev_hash) { + if(page->next_hash) + page->next_hash->pprev_hash = page->pprev_hash; + *page->pprev_hash = page->next_hash; + page->pprev_hash = NULL; + } page_cache_size--; } @@ -93,17 +85,16 @@ 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) { diff -u --recursive --new-file v2.1.35/linux/include/linux/parport.h linux/include/linux/parport.h --- v2.1.35/linux/include/linux/parport.h Sun Apr 13 10:18:22 1997 +++ linux/include/linux/parport.h Wed Apr 23 11:01:37 1997 @@ -1,14 +1,20 @@ -/* $Id: parport.h,v 1.1.2.5 1997/03/29 21:08:31 phil Exp $ */ +/* $Id: parport.h,v 1.2.6.3 1997/04/16 21:21:03 phil Exp $ */ #ifndef _PARPORT_H_ #define _PARPORT_H_ #include #include +#include /* Maximum of 8 ports per machine */ #define PARPORT_MAX 8 +/* Magic numbers */ +#define PARPORT_IRQ_NONE -1 +#define PARPORT_DMA_NONE -1 +#define PARPORT_DISABLE -2 + /* Type classes for Plug-and-Play probe */ typedef enum { @@ -78,6 +84,14 @@ struct ppd *prev; }; +struct parport_dir{ + struct proc_dir_entry *entry; /* Directory /proc/parport/X */ + struct proc_dir_entry *irq; /* IRQ entry /proc/parport/X/irq */ + struct proc_dir_entry *devices; /* /proc/parport/X/devices */ + struct proc_dir_entry *hardware; /* /proc/parport/X/hardware */ + char name[4]; /* /proc/parport/"XXXX" */ +}; + /* A parallel port */ struct parport { unsigned int base; /* base address */ @@ -93,8 +107,9 @@ unsigned int ecr; /* ECP ECR register */ struct parport *next; unsigned int flags; - struct proc_dir_entry *proc_dir; + struct parport_dir pdir; struct parport_device_info probe_info; + int speed; /* Max Write in Bytes/s */ }; /* parport_register_port registers a new parallel port at the given address (if @@ -174,8 +189,10 @@ char); /* Prototypes from parport_procfs */ +extern int parport_proc_init(void); +extern int parport_proc_cleanup(void); extern int parport_proc_register(struct parport *pp); -extern void parport_proc_unregister(struct parport *pp); +extern int parport_proc_unregister(struct parport *pp); /* Prototypes from parport_ksyms.c */ extern void dec_parport_count(void); diff -u --recursive --new-file v2.1.35/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.1.35/linux/include/linux/pci.h Fri Apr 4 08:52:25 1997 +++ linux/include/linux/pci.h Wed Apr 23 08:18:20 1997 @@ -593,6 +593,7 @@ #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 #define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 #define PCI_DEVICE_ID_INTEL_82437VX 0x7030 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 #define PCI_DEVICE_ID_INTEL_P6 0x84c4 #define PCI_VENDOR_ID_KTI 0x8e2e diff -u --recursive --new-file v2.1.35/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.1.35/linux/include/linux/sched.h Wed Apr 16 14:15:00 1997 +++ linux/include/linux/sched.h Wed Apr 23 11:00:46 1997 @@ -112,8 +112,8 @@ * _adding_ to the beginning of the run-queue has * a separate lock). */ +extern rwlock_t tasklist_lock; extern spinlock_t scheduler_lock; -extern spinlock_t tasklist_lock; extern void sched_init(void); extern void show_state(void); @@ -174,14 +174,16 @@ &init_mmap, &init_mmap, MUTEX } struct signal_struct { - int count; - struct sigaction action[32]; + atomic_t count; + struct sigaction action[32]; + spinlock_t siglock; }; #define INIT_SIGNALS { \ - 1, \ - { {0,}, } } + ATOMIC_INIT(1), \ + { {0,}, }, \ + SPIN_LOCK_UNLOCKED } struct task_struct { /* these are hardcoded - don't touch */ @@ -261,6 +263,8 @@ int processor; int last_processor; int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */ + /* Spinlocks for various pieces or per-task state. */ + spinlock_t sigmask_lock; /* Protects signal and blocked */ }; /* @@ -471,11 +475,11 @@ p->nr++; } -#define REMOVE_LINKS(p) do { \ - spin_lock(&tasklist_lock); \ +#define REMOVE_LINKS(p) do { unsigned long flags; \ + write_lock_irqsave(&tasklist_lock, flags); \ (p)->next_task->prev_task = (p)->prev_task; \ (p)->prev_task->next_task = (p)->next_task; \ - spin_unlock(&tasklist_lock); \ + write_unlock_irqrestore(&tasklist_lock, flags); \ if ((p)->p_osptr) \ (p)->p_osptr->p_ysptr = (p)->p_ysptr; \ if ((p)->p_ysptr) \ @@ -484,13 +488,13 @@ (p)->p_pptr->p_cptr = (p)->p_osptr; \ } while (0) -#define SET_LINKS(p) do { \ - spin_lock(&tasklist_lock); \ +#define SET_LINKS(p) do { unsigned long flags; \ + write_lock_irqsave(&tasklist_lock, flags); \ (p)->next_task = &init_task; \ (p)->prev_task = init_task.prev_task; \ init_task.prev_task->next_task = (p); \ init_task.prev_task = (p); \ - spin_unlock(&tasklist_lock); \ + write_unlock_irqrestore(&tasklist_lock, flags); \ (p)->p_ysptr = NULL; \ if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \ (p)->p_osptr->p_ysptr = p; \ diff -u --recursive --new-file v2.1.35/linux/include/linux/skbuff.h linux/include/linux/skbuff.h --- v2.1.35/linux/include/linux/skbuff.h Mon Apr 14 16:28:26 1997 +++ linux/include/linux/skbuff.h Wed Apr 23 11:00:46 1997 @@ -20,12 +20,9 @@ #include #include -#define CONFIG_SKB_CHECK 0 - #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ - #define FREE_READ 1 #define FREE_WRITE 0 @@ -39,9 +36,6 @@ struct sk_buff * prev; __u32 qlen; /* Must be same length as a pointer for using debugging */ -#if CONFIG_SKB_CHECK - int magic_debug_cookie; -#endif }; struct sk_buff @@ -49,9 +43,6 @@ struct sk_buff * next; /* Next buffer in list */ struct sk_buff * prev; /* Previous buffer in list */ struct sk_buff_head * list; /* List we are on */ -#if CONFIG_SKB_CHECK - int magic_debug_cookie; -#endif struct sock *sk; /* Socket we are owned by */ unsigned long when; /* used to compute rtt's */ struct timeval stamp; /* Time we arrived */ @@ -95,8 +86,7 @@ unsigned int len; /* Length of actual data */ unsigned int csum; /* Checksum */ - volatile char acked, /* Are we acked ? */ - used, /* Are we in use ? */ + volatile char used, /* Are we in use ? */ arp; /* Has IP/ARP resolution finished */ unsigned char tries, /* Times tried */ inclone, /* Inline clone */ @@ -141,12 +131,6 @@ #define SK_RMEM_MAX 32767 #endif -#if CONFIG_SKB_CHECK -#define SK_FREED_SKB 0x0DE2C0DE -#define SK_GOOD_SKB 0xDEC0DED1 -#define SK_HEAD_SKB 0x12231298 -#endif - #ifdef __KERNEL__ /* * Handling routines are only of interest to the kernel @@ -245,14 +229,6 @@ 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; @@ -534,9 +510,6 @@ skb->destructor = NULL; 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); diff -u --recursive --new-file v2.1.35/linux/include/linux/sysctl.h linux/include/linux/sysctl.h --- v2.1.35/linux/include/linux/sysctl.h Mon Apr 7 11:35:32 1997 +++ linux/include/linux/sysctl.h Tue Apr 22 22:46:27 1997 @@ -121,6 +121,11 @@ NET_IPV4_ARP_CHECK_INTERVAL, NET_IPV4_ARP_CONFIRM_INTERVAL, NET_IPV4_ARP_CONFIRM_TIMEOUT, + NET_IPV4_TCP_HOE_RETRANSMITS, + NET_IPV4_TCP_SACK, + NET_IPV4_TCP_TSACK, + NET_IPV4_TCP_TIMESTAMPS, + NET_IPV4_TCP_WINDOW_SCALING, NET_IPV4_TCP_VEGAS_CONG_AVOID, NET_IPV4_FORWARDING, NET_IPV4_DEFAULT_TTL, diff -u --recursive --new-file v2.1.35/linux/include/linux/vmalloc.h linux/include/linux/vmalloc.h --- v2.1.35/linux/include/linux/vmalloc.h Thu Feb 6 02:53:43 1997 +++ linux/include/linux/vmalloc.h Wed Apr 23 11:00:46 1997 @@ -20,14 +20,16 @@ extern inline void set_pgdir(unsigned long address, pgd_t entry) { -#ifndef __mc68000__ +#if !defined(__mc68000__) && !defined(__sparc_v9__) struct task_struct * p; + read_lock(&tasklist_lock); for_each_task(p) { if (!p->mm) continue; *pgd_offset(p->mm,address) = entry; } + read_unlock(&tasklist_lock); #endif } diff -u --recursive --new-file v2.1.35/linux/include/linux/wireless.h linux/include/linux/wireless.h --- v2.1.35/linux/include/linux/wireless.h Mon Mar 17 14:54:35 1997 +++ linux/include/linux/wireless.h Thu Apr 17 14:40:36 1997 @@ -63,20 +63,25 @@ * (there is some stuff that will be added in the future...) * I just plan to increment with each new version. */ -#define WIRELESS_EXT 4 +#define WIRELESS_EXT 5 /* * Changes : * * V2 to V3 * -------- - * Alan Cox start some imcompatibles changes. I've integrated a bit more. + * Alan Cox start some incompatibles changes. I've integrated a bit more. * - Encryption renamed to Encode to avoid US regulation problems * - Frequency changed from float to struct to avoid problems on old 386 * * V3 to V4 * -------- * - Add sensitivity + * + * V4 to V5 + * -------- + * - Missing encoding definitions in range + * - Access points stuff */ /* -------------------------- IOCTL LIST -------------------------- */ @@ -103,11 +108,16 @@ #define SIOCSIWSPY 0x8B10 /* set spy addresses */ #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */ +/* Access Point manipulation */ +#define SIOCSIWAP 0x8B14 /* set access point hardware addresses */ +#define SIOCGIWAP 0x8B15 /* get access point hardware addresses */ +#define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */ + /* ------------------------- IOCTL STUFF ------------------------- */ /* The first and the last (range) */ #define SIOCIWFIRST 0x8B00 -#define SIOCIWLAST 0x8B13 +#define SIOCIWLAST 0x8B17 /* Even : get (world access), odd : set (root access) */ #define IW_IS_SET(cmd) (!((cmd) & 0x1)) @@ -185,6 +195,17 @@ __u32 misc; /* Others cases */ }; +/* + * Encoding information (setting and so on) + * Encoding might be hardware encryption, scrambing or others + */ +struct iw_encoding +{ + __u8 method; /* Algorithm number / key used */ + __u64 code; /* Data/key used for algorithm */ +}; + + /* ------------------------ WIRELESS STATS ------------------------ */ /* * Wireless statistics (used for /proc/net/wireless) @@ -234,13 +255,11 @@ * 0-1000 = channel * > 1000 = frequency in Hz */ - struct /* Encoding stuff */ - { - __u8 method; /* Algorithm number / off */ - __u64 code; /* Data used for algorithm */ - } encoding; + struct iw_encoding encoding; /* Encoding stuff */ - __u32 sensitivity; /* signal level threshold */ + __u32 sensitivity; /* signal level threshold */ + + struct sockaddr ap_addr; /* Access point address */ struct /* For all data bigger than 16 octets */ { @@ -275,16 +294,16 @@ __u16 num_channels; /* Number of channels [0; num - 1] */ __u8 num_frequency; /* Number of entry in the list */ struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ - /* Note : this frequency list doesn't need to fit channel numbers */ - /* Encoder stuff */ - /* signal level threshold range */ __u32 sensitivity; /* Quality of link & SNR stuff */ struct iw_quality max_qual; /* Quality of the link */ + + /* Encoder stuff */ + struct iw_encoding max_encoding; /* Encoding max range */ }; /* diff -u --recursive --new-file v2.1.35/linux/include/linux/zorro.h linux/include/linux/zorro.h --- v2.1.35/linux/include/linux/zorro.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/zorro.h Tue Apr 22 22:45:22 1997 @@ -0,0 +1,1278 @@ +/* + * linux/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions + * + * Copyright (C) 1995 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef __ZORRO_H +#define __ZORRO_H + +#ifndef __ASSEMBLY__ + +/* + * Defined Board Manufacturers + * + * Please update arch/m68k/amiga/zorro.c if you make changes here + * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) + * and by looking at the NetBSD-Amiga kernel sources + */ + +#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ +#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ +#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ + +#define MANUF_KUPKE (0x00DD) /* Kupke */ +#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ + +#define MANUF_MEMPHIS (0x0100) /* Memphis */ +#define PROD_STORMBRINGER (0x00) /* Stormbringer */ + +#define MANUF_3_STATE (0x0200) /* 3-State */ +#define PROD_MEGAMIX_2000 (0x02) /* Megamix 2000 RAM */ + +#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ +#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ +#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ +#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ + +#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ +#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ +#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ +#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ +#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ +#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ +#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ +#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ +#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ +#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ +#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ +#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ +#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ +#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ +#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ +#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ +#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ + +#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ +#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ + +#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ +#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ + +#define MANUF_CARDCO (0x03EC) /* Cardco */ +#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ +#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ +#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ +#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ + +#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ +#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ + +#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ +#define PROD_AX2000 (0x01) /* AX2000 */ + +#define MANUF_ANAKIN (0x03F1) /* Anakin */ +#define PROD_EASYL (0x01) /* Easyl Tablet */ + +#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ +#define PROD_STARBOARD_II (0x00) /* StarBoard II */ +#define PROD_STARDRIVE (0x02) /* StarDrive */ +#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ +#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ +#define PROD_DELTA_RAM (0x20) /* Delta Card RAM */ +#define PROD_8_STAR_RAM (0x40) /* 8-Star RAM */ +#define PROD_8_STAR (0x41) /* 8-Star */ +#define PROD_VXL_RAM (0x44) /* VXL RAM */ +#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ +#define PROD_DELTA (0x60) /* Delta Card */ +#define PROD_MBX_1200 (0x81) /* MBX 1200 */ +#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ +#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ + +#define MANUF_ACCESS (0x03F4) /* Access Associates */ + +#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ + +#define MANUF_ASDG (0x03FF) /* ASDG */ +#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ +#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ +#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ +#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ + +#define MANUF_IMTRONICS (0x0404) /* Imtronics */ +#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ +#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ + +#define MANUF_AMERISTAR (0x041D) /* Ameristar */ +#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ +#define PROD_A560 (0x09) /* Arcnet Card */ +#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ + +#define MANUF_SUPRA (0x0420) /* Supra */ +#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ +#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ +#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ +#define PROD_SUPRA_500XP (0x09) /* 500XP/2000 RAM */ +#define PROD_SUPRA_500RX (0x0A) /* 500RX/2000 RAM */ +#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ +#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ +#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ +#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ + +#define MANUF_CSA (0x0422) /* Computer Systems Ass. */ +#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ +#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ + +#define MANUF_MTEC2 (0x0502) /* M-Tech */ +#define PROD_AT500_2 (0x03) /* AT500 RAM */ + +#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ +#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ + +#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ +#define PROD_BYTEBOX_A500 (0x00) /* A500 */ + +#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ + +#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ +#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ +#define PROD_RAPID_FIRE (0x0F) /* Rapid Fire SCSI Controller */ +#define PROD_DKB_1202 (0x10) /* DKB 1202 RAM */ +#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ +#define PROD_WILDFIRE_060 (0x17) /* WildFire 060 Turbo Board */ +#define PROD_WILDFIRE_060_2 (0xFF) /* WildFire 060 Turbo Board */ + +#define MANUF_GVP (0x07E1) /* Great Valley Products */ +#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ +#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ +#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ +#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ +#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ +#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ +#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works + for this product code also */ +#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ +#define PROD_GVP (0x0B) /* This code is used by a wide range of + GVP products - use the epc to + identify it correctly */ +#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ +#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ +#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ +#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ +#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ +/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ + +#define MANUF_SYNERGY (0x07E5) /* Synergy */ + +#define MANUF_XETEC (0x07E6) /* Xetec */ +#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ +#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ + +#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ +#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ +#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ +#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ +#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ +#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ + +#define MANUF_XEBEC (0x07EC) /* Xebec */ + +#define MANUF_SPIRIT (0x07F2) /* Spirit */ +#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ +#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ + +#define MANUF_BSC (0x07FE) /* BSC */ +#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ + +#define MANUF_BSC3 (0x0801) /* BSC */ +#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ +#define PROD_ALF_2_SCSI_2 (0x02) /* ALF 2 SCSI Controller */ +#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ + +#define MANUF_C_LTD (0x0802) /* C Ltd. */ +#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ +#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ + +#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ +#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ + +#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ +#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ + +#define MANUF_ICD (0x0817) /* ICD */ +#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ + +#define MANUF_KUPKE2 (0x0819) /* Kupke */ +#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ +#define PROD_GOLEM_BOX (0x03) /* Golem Box */ +#define PROD_KUPKE_TURBO (0x04) /* 030/882 Turbo Board */ +#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ + +#define MANUF_GVP4 (0x081D) /* Great Valley Products */ +#define PROD_A2000_RAM8 (0x09) /* A2000-RAM8/2 */ + +#define MANUF_INTERWORKS_NET (0x081E) /* Interworks Network */ + +#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ +#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ + +#define MANUF_BSC2 (0x082C) /* BSC */ +#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ +#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ +#define PROD_ALPHA_RAM_1200 (0x07) /* Alpha RAM 1200 */ +#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ +#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ +#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ +#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ +#define PROD_BSC_FRAEMBUFFER (0x20) /* Framebuffer */ +#define PROD_GRAFFITI_RAM (0x21) /* Graffiti Graphics Board */ +#define PROD_GRAFFITI_REG (0x22) +#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ +#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ + +#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ +#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ +#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ + +#define MANUF_IMPULSE (0x0838) /* Impulse */ +#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ + +#define MANUF_IVS (0x0840) /* IVS */ +#define PROD_GRANDSLAM_PIC_2 (0x02) /* GrandSlam PIC 2 RAM */ +#define PROD_GRANDSLAM_PIC_1 (0x04) /* GrandSlam PIC 1 RAM */ +#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ +#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ +#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ +#define PROD_META_4 (0x40) /* Meta-4 RAM */ +#define PROD_WAVETOOLS (0xBF) /* Wavetools Sound Board */ +#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ +#define PROD_VECTOR_2 (0xF4) /* Vector SCSI Controller */ + +#define MANUF_VECTOR (0x0841) /* Vector */ +#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ + +#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ +#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ +#define PROD_VISIONA_REG (0x02) +#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ +#define PROD_MERLIN_REG (0x04) +#define PROD_MERLIN_REG_2 (0xC9) + +#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ +#define PROD_AMIGANET (0x01) /* Amiganet Board */ + +#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ +#define PROD_AD1012 (0x01) /* AD1012 Sound Board */ +#define PROD_AD516 (0x02) /* AD516 Sound Board */ +#define PROD_DD512 (0x03) /* DD512 Sound Board */ + +#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ +#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ + +#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ +#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ +#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ + +#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ +#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ +#define PROD_GDA_1_REG (0x01) + +#define MANUF_ROCTEC (0x0860) /* RocTec */ +#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ +#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ + +#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ +#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ + +#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ +#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ + +#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ +#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ +#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ +#define PROD_MVD_819 (0x07) /* MVD 819 */ + +#define MANUF_DELACOMP (0x0873) /* DelaComp */ +#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ + +#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ +#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board */ +#define PROD_DOMINO_REG (0x02) +#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II/II+ Graphics Board */ +#define PROD_PICASSO_II_REG (0x0C) +#define PROD_PICASSO_II_SEGM (0x0D) /* Picasso II/II+ (Segmented Mode) */ +#define PROD_PICASSO_IV (0x15) /* Picassio IV Graphics Board */ +#define PROD_PICASSO_IV_2 (0x16) +#define PROD_PICASSO_IV_3 (0x17) +#define PROD_PICASSO_IV_4 (0x18) +#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ + +#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ +#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ +#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ + +#define MANUF_AMITRIX (0x0880) /* Amitrix */ +#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ +#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ + +#define MANUF_ARMAX (0x0885) /* ArMax */ +#define PROD_OMNIBUS (0x00) /* OmniBus Graphics Board */ + +#define MANUF_NEWTEK (0x088F) /* NewTek */ +#define PROD_VIDEOTOASTER (0x00) /* VideoToaster */ + +#define MANUF_MTEC (0x0890) /* M-Tech Germany */ +#define PROD_AT500 (0x01) /* AT500 IDE Controller */ +#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ +#define PROD_MTEC_68020I (0x06) /* 68020i Turbo Board */ +#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ +#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ + +#define MANUF_GVP2 (0x0891) /* Great Valley Products */ +#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ +#define PROD_SPECTRUM_REG (0x02) + +#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ +#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ +#define PROD_PICCOLO_REG (0x06) +#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ +#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ +#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ +#define PROD_SD64_REG (0x0B) + +#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ +#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ + +#define MANUF_ELBOX (0x089E) /* ElBox Computer */ +#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ + +#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ +#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ +#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ + +#define MANUF_MICRONIK (0x0A50) /* Micronik */ +#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ + +#define MANUF_MEGA_MICRO (0x1000) /* MegaMicro */ +#define PROD_SCRAM_500_SCSI (0x03) /* SCRAM 500 SCSI Controller */ +#define PROD_SCRAM_500_RAM (0x04) /* SCRAM 500 RAM */ + +#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ +#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_KUPKE3 (0x1248) /* Kupke */ +#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ + +#define MANUF_ITH (0x1388) /* ITH */ +#define PROD_ISDN_MASTER_II (0x01) /* ISDN-Master II */ + +#define MANUF_VMC (0x1389) /* VMC */ +#define PROD_ISDN_BLASTER_Z2 (0x01) /* ISDN Blaster Z2 */ +#define PROD_HYPERCOM_4 (0x02) /* HyperCom 4 */ + +#define MANUF_INFORMATION (0x157C) /* Information */ +#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ + +#define MANUF_VORTEX (0x2017) /* Vortex */ +#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ +#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ +#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ + +#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ +#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ +#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ + +#define MANUF_READYSOFT (0x2100) /* ReadySoft */ +#define PROD_AMAX (0x01) /* AMax II/IV */ + +#define MANUF_PHASE5 (0x2140) /* Phase5 */ +#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ +#define PROD_BLIZZARD (0x02) /* Blizzard */ +#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ +#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ +#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ +#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ +#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ +#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ +#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ +#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ +#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ +#define PROD_CYBERVISION3D_PRT (0x32) /* CyberVision64-3D Prototype */ +#define PROD_CYBERVISION3D (0x43) /* CyberVision64-3D Graphics Board */ + +#define MANUF_DPS (0x2169) /* DPS */ +#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ + +#define MANUF_APOLLO2 (0x2200) /* Apollo */ +#define PROD_A620 (0x00) /* A620 68020 Accelerator */ +#define PROD_A620_2 (0x01) /* A620 68020 Accelerator */ + +#define MANUF_APOLLO (0x2222) /* Apollo */ +#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ +#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ + +#define MANUF_PETSOFF (0x38A5) /* Petsoff LP */ +#define PROD_DELFINA (0x00) /* Delfina DSP */ + +#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ +#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ + +#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ +#define PROD_MAESTRO (0x03) /* Maestro */ +#define PROD_VLAB (0x04) /* VLab */ +#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ +#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ +#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ +#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ +#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ +#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ +#define PROD_ALTAIS (0x13) /* Altais Graphics Board */ +#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ + +#define MANUF_COMBITEC (0x6766) /* Combitec */ + +#define MANUF_SKI (0x8000) /* SKI Peripherals */ +#define PROD_MAST_FIREBALL (0x08) /* M.A.S.T. Fireball SCSI Controller */ +#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ + +#define MANUF_CAMERON (0xAA01) /* Cameron */ +#define PROD_PERSONAL_A4 (0x10) /* Personal A4 */ + +#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ +#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ + + +/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ + +#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ +#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ + +#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ +#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ + +#define MANUF_VECTOR2 (0x07DB) /* Vector */ +#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ +#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ +#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ +#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ + + +/* + * GVP's identifies most of their product through the 'extended + * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK + * before the identification. + */ + +#define GVP_PRODMASK (0xf8) +#define GVP_SCSICLKMASK (0x01) + +enum GVP_ident { + GVP_GFORCE_040 = 0x20, + GVP_GFORCE_040_SCSI = 0x30, + GVP_A1291_SCSI = 0x40, + GVP_COMBO_R4 = 0x60, + GVP_COMBO_R4_SCSI = 0x70, + GVP_PHONEPAK = 0x78, + GVP_IOEXT = 0x98, + GVP_GFORCE_030 = 0xa0, + GVP_GFORCE_030_SCSI = 0xb0, + GVP_A530 = 0xc0, + GVP_A530_SCSI = 0xd0, + GVP_COMBO_R3 = 0xe0, + GVP_COMBO_R3_SCSI = 0xf0, + GVP_SERIESII = 0xf8, +}; + +enum GVP_flags { + GVP_IO = 0x01, + GVP_ACCEL = 0x02, + GVP_SCSI = 0x04, + GVP_24BITDMA = 0x08, + GVP_25BITDMA = 0x10, + GVP_NOBANK = 0x20, + GVP_14MHZ = 0x40, +}; + + +struct Node { + struct Node *ln_Succ; /* Pointer to next (successor) */ + struct Node *ln_Pred; /* Pointer to previous (predecessor) */ + u_char ln_Type; + char ln_Pri; /* Priority, for sorting */ + char *ln_Name; /* ID string, null terminated */ +}; + +struct ExpansionRom { + /* -First 16 bytes of the expansion ROM */ + u_char er_Type; /* Board type, size and flags */ + u_char er_Product; /* Product number, assigned by manufacturer */ + u_char er_Flags; /* Flags */ + u_char er_Reserved03; /* Must be zero ($ff inverted) */ + u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ + u_long er_SerialNumber; /* Available for use by manufacturer */ + u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ + u_char er_Reserved0c; + u_char er_Reserved0d; + u_char er_Reserved0e; + u_char er_Reserved0f; +}; + +/* er_Type board type bits */ +#define ERT_TYPEMASK 0xc0 +#define ERT_ZORROII 0xc0 +#define ERT_ZORROIII 0x80 + +/* other bits defined in er_Type */ +#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ +#define ERTF_MEMLIST (1<<5) + +struct ConfigDev { + struct Node cd_Node; + u_char cd_Flags; /* (read/write) */ + u_char cd_Pad; /* reserved */ + struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ + void *cd_BoardAddr; /* where in memory the board was placed */ + u_long cd_BoardSize; /* size of board in bytes */ + u_short cd_SlotAddr; /* which slot number (PRIVATE) */ + u_short cd_SlotSize; /* number of slots (PRIVATE) */ + void *cd_Driver; /* pointer to node of driver */ + struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ + u_long cd_Unused[4]; /* for whatever the driver wants */ +}; + +#else /* __ASSEMBLY__ */ + +LN_Succ = 0 +LN_Pred = LN_Succ+4 +LN_Type = LN_Pred+4 +LN_Pri = LN_Type+1 +LN_Name = LN_Pri+1 +LN_sizeof = LN_Name+4 + +ER_Type = 0 +ER_Product = ER_Type+1 +ER_Flags = ER_Product+1 +ER_Reserved03 = ER_Flags+1 +ER_Manufacturer = ER_Reserved03+1 +ER_SerialNumber = ER_Manufacturer+2 +ER_InitDiagVec = ER_SerialNumber+4 +ER_Reserved0c = ER_InitDiagVec+2 +ER_Reserved0d = ER_Reserved0c+1 +ER_Reserved0e = ER_Reserved0d+1 +ER_Reserved0f = ER_Reserved0e+1 +ER_sizeof = ER_Reserved0f+1 + +CD_Node = 0 +CD_Flags = CD_Node+LN_sizeof +CD_Pad = CD_Flags+1 +CD_Rom = CD_Pad+1 +CD_BoardAddr = CD_Rom+ER_sizeof +CD_BoardSize = CD_BoardAddr+4 +CD_SlotAddr = CD_BoardSize+4 +CD_SlotSize = CD_SlotAddr+2 +CD_Driver = CD_SlotSize+2 +CD_NextCD = CD_Driver+4 +CD_Unused = CD_NextCD+4 +CD_sizeof = CD_Unused+(4*4) + +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +#define ZORRO_NUM_AUTO 16 + +#ifdef __KERNEL__ + +extern int zorro_num_autocon; /* # of autoconfig devices found */ +extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; + + +/* + * Zorro Functions + */ + +extern int zorro_find(int manuf, int prod, int part, int index); +extern struct ConfigDev *zorro_get_board(int key); +extern void zorro_config_board(int key, int part); +extern void zorro_unconfig_board(int key, int part); + + +/* + * Bitmask indicating portions of available Zorro II RAM that are unused + * by the system. Every bit represents a 64K chunk, for a maximum of 8MB + * (128 chunks, physical 0x00200000-0x009fffff). + * + * If you want to use (= allocate) portions of this RAM, you should clear + * the corresponding bits. + */ + +extern u_long zorro_unused_z2ram[4]; + +#define Z2RAM_START (0x00200000) +#define Z2RAM_END (0x00a00000) +#define Z2RAM_SIZE (0x00800000) +#define Z2RAM_CHUNKSIZE (0x00010000) +#define Z2RAM_CHUNKMASK (0x0000ffff) +#define Z2RAM_CHUNKSHIFT (16) + + +/* + * Verbose Board Identification + */ + +extern void zorro_identify(void); +extern int zorro_get_list(char *buffer); + +#endif /* !__ASSEMBLY__ */ +#endif /* __KERNEL__ */ + +#endif /* __ZORRO_H */ +/* + * linux/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions + * + * Copyright (C) 1995 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef __ZORRO_H +#define __ZORRO_H + +#ifndef __ASSEMBLY__ + +/* + * Defined Board Manufacturers + * + * Please update arch/m68k/amiga/zorro.c if you make changes here + * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) + * and by looking at the NetBSD-Amiga kernel sources + */ + +#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ +#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ +#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ + +#define MANUF_KUPKE (0x00DD) /* Kupke */ +#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ + +#define MANUF_MEMPHIS (0x0100) /* Memphis */ +#define PROD_STORMBRINGER (0x00) /* Stormbringer */ + +#define MANUF_3_STATE (0x0200) /* 3-State */ +#define PROD_MEGAMIX_2000 (0x02) /* Megamix 2000 RAM */ + +#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ +#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ +#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ +#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ + +#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ +#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ +#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ +#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ +#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ +#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ +#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ +#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ +#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ +#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ +#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ +#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ +#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ +#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ +#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ +#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ +#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ + +#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ +#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ + +#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ +#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ + +#define MANUF_CARDCO (0x03EC) /* Cardco */ +#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ +#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ +#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ +#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ + +#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ +#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ + +#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ +#define PROD_AX2000 (0x01) /* AX2000 */ + +#define MANUF_ANAKIN (0x03F1) /* Anakin */ +#define PROD_EASYL (0x01) /* Easyl Tablet */ + +#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ +#define PROD_STARBOARD_II (0x00) /* StarBoard II */ +#define PROD_STARDRIVE (0x02) /* StarDrive */ +#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ +#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ +#define PROD_DELTA_RAM (0x20) /* Delta Card RAM */ +#define PROD_8_STAR_RAM (0x40) /* 8-Star RAM */ +#define PROD_8_STAR (0x41) /* 8-Star */ +#define PROD_VXL_RAM (0x44) /* VXL RAM */ +#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ +#define PROD_DELTA (0x60) /* Delta Card */ +#define PROD_MBX_1200 (0x81) /* MBX 1200 */ +#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ +#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ + +#define MANUF_ACCESS (0x03F4) /* Access Associates */ + +#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ + +#define MANUF_ASDG (0x03FF) /* ASDG */ +#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ +#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ +#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ +#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ + +#define MANUF_IMTRONICS (0x0404) /* Imtronics */ +#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ +#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ + +#define MANUF_AMERISTAR (0x041D) /* Ameristar */ +#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ +#define PROD_A560 (0x09) /* Arcnet Card */ +#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ + +#define MANUF_SUPRA (0x0420) /* Supra */ +#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ +#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ +#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ +#define PROD_SUPRA_500XP (0x09) /* 500XP/2000 RAM */ +#define PROD_SUPRA_500RX (0x0A) /* 500RX/2000 RAM */ +#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ +#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ +#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ +#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ + +#define MANUF_CSA (0x0422) /* Computer Systems Ass. */ +#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ +#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ + +#define MANUF_MTEC2 (0x0502) /* M-Tech */ +#define PROD_AT500_2 (0x03) /* AT500 RAM */ + +#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ +#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ + +#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ +#define PROD_BYTEBOX_A500 (0x00) /* A500 */ + +#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ + +#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ +#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ +#define PROD_RAPID_FIRE (0x0F) /* Rapid Fire SCSI Controller */ +#define PROD_DKB_1202 (0x10) /* DKB 1202 RAM */ +#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ +#define PROD_WILDFIRE_060 (0x17) /* WildFire 060 Turbo Board */ +#define PROD_WILDFIRE_060_2 (0xFF) /* WildFire 060 Turbo Board */ + +#define MANUF_GVP (0x07E1) /* Great Valley Products */ +#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ +#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ +#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ +#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ +#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ +#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ +#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works + for this product code also */ +#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ +#define PROD_GVP (0x0B) /* This code is used by a wide range of + GVP products - use the epc to + identify it correctly */ +#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ +#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ +#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ +#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ +#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ +/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ + +#define MANUF_SYNERGY (0x07E5) /* Synergy */ + +#define MANUF_XETEC (0x07E6) /* Xetec */ +#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ +#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ + +#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ +#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ +#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ +#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ +#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ +#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ + +#define MANUF_XEBEC (0x07EC) /* Xebec */ + +#define MANUF_SPIRIT (0x07F2) /* Spirit */ +#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ +#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ + +#define MANUF_BSC (0x07FE) /* BSC */ +#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ + +#define MANUF_BSC3 (0x0801) /* BSC */ +#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ +#define PROD_ALF_2_SCSI_2 (0x02) /* ALF 2 SCSI Controller */ +#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ + +#define MANUF_C_LTD (0x0802) /* C Ltd. */ +#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ +#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ + +#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ +#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ + +#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ +#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ + +#define MANUF_ICD (0x0817) /* ICD */ +#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ + +#define MANUF_KUPKE2 (0x0819) /* Kupke */ +#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ +#define PROD_GOLEM_BOX (0x03) /* Golem Box */ +#define PROD_KUPKE_TURBO (0x04) /* 030/882 Turbo Board */ +#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ + +#define MANUF_GVP4 (0x081D) /* Great Valley Products */ +#define PROD_A2000_RAM8 (0x09) /* A2000-RAM8/2 */ + +#define MANUF_INTERWORKS_NET (0x081E) /* Interworks Network */ + +#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ +#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ + +#define MANUF_BSC2 (0x082C) /* BSC */ +#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ +#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ +#define PROD_ALPHA_RAM_1200 (0x07) /* Alpha RAM 1200 */ +#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ +#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ +#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ +#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ +#define PROD_BSC_FRAEMBUFFER (0x20) /* Framebuffer */ +#define PROD_GRAFFITI_RAM (0x21) /* Graffiti Graphics Board */ +#define PROD_GRAFFITI_REG (0x22) +#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ +#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ + +#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ +#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ +#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ + +#define MANUF_IMPULSE (0x0838) /* Impulse */ +#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ + +#define MANUF_IVS (0x0840) /* IVS */ +#define PROD_GRANDSLAM_PIC_2 (0x02) /* GrandSlam PIC 2 RAM */ +#define PROD_GRANDSLAM_PIC_1 (0x04) /* GrandSlam PIC 1 RAM */ +#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ +#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ +#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ +#define PROD_META_4 (0x40) /* Meta-4 RAM */ +#define PROD_WAVETOOLS (0xBF) /* Wavetools Sound Board */ +#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ +#define PROD_VECTOR_2 (0xF4) /* Vector SCSI Controller */ + +#define MANUF_VECTOR (0x0841) /* Vector */ +#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ + +#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ +#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ +#define PROD_VISIONA_REG (0x02) +#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ +#define PROD_MERLIN_REG (0x04) +#define PROD_MERLIN_REG_2 (0xC9) + +#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ +#define PROD_AMIGANET (0x01) /* Amiganet Board */ + +#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ +#define PROD_AD1012 (0x01) /* AD1012 Sound Board */ +#define PROD_AD516 (0x02) /* AD516 Sound Board */ +#define PROD_DD512 (0x03) /* DD512 Sound Board */ + +#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ +#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ + +#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ +#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ +#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ + +#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ +#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ +#define PROD_GDA_1_REG (0x01) + +#define MANUF_ROCTEC (0x0860) /* RocTec */ +#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ +#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ + +#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ +#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ + +#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ +#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ + +#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ +#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ +#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ +#define PROD_MVD_819 (0x07) /* MVD 819 */ + +#define MANUF_DELACOMP (0x0873) /* DelaComp */ +#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ + +#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ +#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board */ +#define PROD_DOMINO_REG (0x02) +#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II/II+ Graphics Board */ +#define PROD_PICASSO_II_REG (0x0C) +#define PROD_PICASSO_II_SEGM (0x0D) /* Picasso II/II+ (Segmented Mode) */ +#define PROD_PICASSO_IV (0x15) /* Picassio IV Graphics Board */ +#define PROD_PICASSO_IV_2 (0x16) +#define PROD_PICASSO_IV_3 (0x17) +#define PROD_PICASSO_IV_4 (0x18) +#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ + +#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ +#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ +#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ + +#define MANUF_AMITRIX (0x0880) /* Amitrix */ +#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ +#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ + +#define MANUF_ARMAX (0x0885) /* ArMax */ +#define PROD_OMNIBUS (0x00) /* OmniBus Graphics Board */ + +#define MANUF_NEWTEK (0x088F) /* NewTek */ +#define PROD_VIDEOTOASTER (0x00) /* VideoToaster */ + +#define MANUF_MTEC (0x0890) /* M-Tech Germany */ +#define PROD_AT500 (0x01) /* AT500 IDE Controller */ +#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ +#define PROD_MTEC_68020I (0x06) /* 68020i Turbo Board */ +#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ +#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ + +#define MANUF_GVP2 (0x0891) /* Great Valley Products */ +#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ +#define PROD_SPECTRUM_REG (0x02) + +#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ +#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ +#define PROD_PICCOLO_REG (0x06) +#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ +#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ +#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ +#define PROD_SD64_REG (0x0B) + +#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ +#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ + +#define MANUF_ELBOX (0x089E) /* ElBox Computer */ +#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ + +#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ +#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ +#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ + +#define MANUF_MICRONIK (0x0A50) /* Micronik */ +#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ + +#define MANUF_MEGA_MICRO (0x1000) /* MegaMicro */ +#define PROD_SCRAM_500_SCSI (0x03) /* SCRAM 500 SCSI Controller */ +#define PROD_SCRAM_500_RAM (0x04) /* SCRAM 500 RAM */ + +#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ +#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_KUPKE3 (0x1248) /* Kupke */ +#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ + +#define MANUF_ITH (0x1388) /* ITH */ +#define PROD_ISDN_MASTER_II (0x01) /* ISDN-Master II */ + +#define MANUF_VMC (0x1389) /* VMC */ +#define PROD_ISDN_BLASTER_Z2 (0x01) /* ISDN Blaster Z2 */ +#define PROD_HYPERCOM_4 (0x02) /* HyperCom 4 */ + +#define MANUF_INFORMATION (0x157C) /* Information */ +#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ + +#define MANUF_VORTEX (0x2017) /* Vortex */ +#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ +#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ +#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ + +#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ +#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ +#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ + +#define MANUF_READYSOFT (0x2100) /* ReadySoft */ +#define PROD_AMAX (0x01) /* AMax II/IV */ + +#define MANUF_PHASE5 (0x2140) /* Phase5 */ +#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ +#define PROD_BLIZZARD (0x02) /* Blizzard */ +#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ +#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ +#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ +#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ +#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ +#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ +#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ +#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ +#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ +#define PROD_CYBERVISION3D_PRT (0x32) /* CyberVision64-3D Prototype */ +#define PROD_CYBERVISION3D (0x43) /* CyberVision64-3D Graphics Board */ + +#define MANUF_DPS (0x2169) /* DPS */ +#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ + +#define MANUF_APOLLO2 (0x2200) /* Apollo */ +#define PROD_A620 (0x00) /* A620 68020 Accelerator */ +#define PROD_A620_2 (0x01) /* A620 68020 Accelerator */ + +#define MANUF_APOLLO (0x2222) /* Apollo */ +#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ +#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ + +#define MANUF_PETSOFF (0x38A5) /* Petsoff LP */ +#define PROD_DELFINA (0x00) /* Delfina DSP */ + +#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ +#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ + +#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ +#define PROD_MAESTRO (0x03) /* Maestro */ +#define PROD_VLAB (0x04) /* VLab */ +#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ +#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ +#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ +#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ +#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ +#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ +#define PROD_ALTAIS (0x13) /* Altais Graphics Board */ +#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ + +#define MANUF_COMBITEC (0x6766) /* Combitec */ + +#define MANUF_SKI (0x8000) /* SKI Peripherals */ +#define PROD_MAST_FIREBALL (0x08) /* M.A.S.T. Fireball SCSI Controller */ +#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ + +#define MANUF_CAMERON (0xAA01) /* Cameron */ +#define PROD_PERSONAL_A4 (0x10) /* Personal A4 */ + +#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ +#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ + + +/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ + +#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ +#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ + +#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ +#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ + +#define MANUF_VECTOR2 (0x07DB) /* Vector */ +#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ +#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ +#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ +#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ + + +/* + * GVP's identifies most of their product through the 'extended + * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK + * before the identification. + */ + +#define GVP_PRODMASK (0xf8) +#define GVP_SCSICLKMASK (0x01) + +enum GVP_ident { + GVP_GFORCE_040 = 0x20, + GVP_GFORCE_040_SCSI = 0x30, + GVP_A1291_SCSI = 0x40, + GVP_COMBO_R4 = 0x60, + GVP_COMBO_R4_SCSI = 0x70, + GVP_PHONEPAK = 0x78, + GVP_IOEXT = 0x98, + GVP_GFORCE_030 = 0xa0, + GVP_GFORCE_030_SCSI = 0xb0, + GVP_A530 = 0xc0, + GVP_A530_SCSI = 0xd0, + GVP_COMBO_R3 = 0xe0, + GVP_COMBO_R3_SCSI = 0xf0, + GVP_SERIESII = 0xf8, +}; + +enum GVP_flags { + GVP_IO = 0x01, + GVP_ACCEL = 0x02, + GVP_SCSI = 0x04, + GVP_24BITDMA = 0x08, + GVP_25BITDMA = 0x10, + GVP_NOBANK = 0x20, + GVP_14MHZ = 0x40, +}; + + +struct Node { + struct Node *ln_Succ; /* Pointer to next (successor) */ + struct Node *ln_Pred; /* Pointer to previous (predecessor) */ + u_char ln_Type; + char ln_Pri; /* Priority, for sorting */ + char *ln_Name; /* ID string, null terminated */ +}; + +struct ExpansionRom { + /* -First 16 bytes of the expansion ROM */ + u_char er_Type; /* Board type, size and flags */ + u_char er_Product; /* Product number, assigned by manufacturer */ + u_char er_Flags; /* Flags */ + u_char er_Reserved03; /* Must be zero ($ff inverted) */ + u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ + u_long er_SerialNumber; /* Available for use by manufacturer */ + u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ + u_char er_Reserved0c; + u_char er_Reserved0d; + u_char er_Reserved0e; + u_char er_Reserved0f; +}; + +/* er_Type board type bits */ +#define ERT_TYPEMASK 0xc0 +#define ERT_ZORROII 0xc0 +#define ERT_ZORROIII 0x80 + +/* other bits defined in er_Type */ +#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ +#define ERTF_MEMLIST (1<<5) + +struct ConfigDev { + struct Node cd_Node; + u_char cd_Flags; /* (read/write) */ + u_char cd_Pad; /* reserved */ + struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ + void *cd_BoardAddr; /* where in memory the board was placed */ + u_long cd_BoardSize; /* size of board in bytes */ + u_short cd_SlotAddr; /* which slot number (PRIVATE) */ + u_short cd_SlotSize; /* number of slots (PRIVATE) */ + void *cd_Driver; /* pointer to node of driver */ + struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ + u_long cd_Unused[4]; /* for whatever the driver wants */ +}; + +#else /* __ASSEMBLY__ */ + +LN_Succ = 0 +LN_Pred = LN_Succ+4 +LN_Type = LN_Pred+4 +LN_Pri = LN_Type+1 +LN_Name = LN_Pri+1 +LN_sizeof = LN_Name+4 + +ER_Type = 0 +ER_Product = ER_Type+1 +ER_Flags = ER_Product+1 +ER_Reserved03 = ER_Flags+1 +ER_Manufacturer = ER_Reserved03+1 +ER_SerialNumber = ER_Manufacturer+2 +ER_InitDiagVec = ER_SerialNumber+4 +ER_Reserved0c = ER_InitDiagVec+2 +ER_Reserved0d = ER_Reserved0c+1 +ER_Reserved0e = ER_Reserved0d+1 +ER_Reserved0f = ER_Reserved0e+1 +ER_sizeof = ER_Reserved0f+1 + +CD_Node = 0 +CD_Flags = CD_Node+LN_sizeof +CD_Pad = CD_Flags+1 +CD_Rom = CD_Pad+1 +CD_BoardAddr = CD_Rom+ER_sizeof +CD_BoardSize = CD_BoardAddr+4 +CD_SlotAddr = CD_BoardSize+4 +CD_SlotSize = CD_SlotAddr+2 +CD_Driver = CD_SlotSize+2 +CD_NextCD = CD_Driver+4 +CD_Unused = CD_NextCD+4 +CD_sizeof = CD_Unused+(4*4) + +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +#define ZORRO_NUM_AUTO 16 + +#ifdef __KERNEL__ + +extern int zorro_num_autocon; /* # of autoconfig devices found */ +extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; + + +/* + * Zorro Functions + */ + +extern int zorro_find(int manuf, int prod, int part, int index); +extern struct ConfigDev *zorro_get_board(int key); +extern void zorro_config_board(int key, int part); +extern void zorro_unconfig_board(int key, int part); + + +/* + * Bitmask indicating portions of available Zorro II RAM that are unused + * by the system. Every bit represents a 64K chunk, for a maximum of 8MB + * (128 chunks, physical 0x00200000-0x009fffff). + * + * If you want to use (= allocate) portions of this RAM, you should clear + * the corresponding bits. + */ + +extern u_long zorro_unused_z2ram[4]; + +#define Z2RAM_START (0x00200000) +#define Z2RAM_END (0x00a00000) +#define Z2RAM_SIZE (0x00800000) +#define Z2RAM_CHUNKSIZE (0x00010000) +#define Z2RAM_CHUNKMASK (0x0000ffff) +#define Z2RAM_CHUNKSHIFT (16) + + +/* + * Verbose Board Identification + */ + +extern void zorro_identify(void); +extern int zorro_get_list(char *buffer); + +#endif /* !__ASSEMBLY__ */ +#endif /* __KERNEL__ */ + +#endif /* __ZORRO_H */ diff -u --recursive --new-file v2.1.35/linux/include/net/sock.h linux/include/net/sock.h --- v2.1.35/linux/include/net/sock.h Mon Apr 14 16:28:26 1997 +++ linux/include/net/sock.h Wed Apr 23 11:01:33 1997 @@ -179,6 +179,7 @@ #endif /* IPV6 */ + struct tcp_opt { /* @@ -197,6 +198,7 @@ __u32 rcv_wup; /* rcv_nxt on last window update sent */ + __u32 fin_seq; /* XXX This one should go, we don't need it. -DaveM */ __u32 srtt; /* smothed round trip time << 3 */ __u32 mdev; /* medium deviation */ @@ -207,6 +209,28 @@ */ __u32 snd_cwnd; /* Sending congestion window */ __u32 snd_ssthresh; /* Slow start size threshold */ + __u16 snd_cwnd_cnt; + __u16 max_window; + +/* + * Options received (usually on last packet, some only on SYN packets). + */ + char tstamp_ok, /* TIMESTAMP seen on SYN packet */ + sack_ok; /* SACK_PERM seen on SYN packet */ + char saw_tstamp; /* Saw TIMESTAMP on last packet */ + __u16 in_mss; /* MSS option received from sender */ + __u8 snd_wscale; /* Window scaling received from sender */ + __u8 rcv_wscale; /* Window scaling to send to receiver */ + __u32 rcv_tsval; /* Time stamp value */ + __u32 rcv_tsecr; /* Time stamp echo reply */ + __u32 ts_recent; /* Time stamp to echo next */ + __u32 ts_recent_stamp;/* Time we stored ts_recent (for aging) */ + __u32 last_ack_sent; /* last ack we sent */ + int sacks; /* Number of SACK blocks if any */ + __u32 left_sack[4]; /* Left edges of blocks */ + __u32 right_sack[4]; /* Right edges of blocks */ + int tcp_header_len; /* Bytes of tcp header to send */ + /* * Timers used by the TCP protocol layer */ @@ -217,17 +241,21 @@ struct timer_list retransmit_timer; /* Resend (no ack) */ __u32 basertt; /* Vegas baseRTT */ + __u32 packets_out; /* Packets which are "in flight" */ + __u32 window_clamp; /* XXX Document this... -DaveM */ + __u8 pending; /* pending events */ __u8 delayed_acks; - __u8 dup_acks; + __u8 dup_acks; /* Consequetive duplicate acks seen from other end */ + __u8 retransmits; __u32 lrcvtime; /* timestamp of last received data packet */ __u32 rcv_tstamp; /* timestamp of last received packet */ __u32 iat_mdev; /* interarrival time medium deviation */ __u32 iat; /* interarrival time */ __u32 ato; /* delayed ack timeout */ + __u32 high_seq; /* highest sequence number sent by onset of congestion */ - __u32 high_seq; /* * new send pointers */ @@ -238,11 +266,6 @@ * fast retransmit */ /* - * pending events - */ - __u8 pending; - -/* * Header prediction flags * 0x5?10 << 16 + snd_wnd in net byte order */ @@ -252,6 +275,7 @@ __u32 probes_out; /* unanswered 0 window probes */ struct open_request *syn_wait_queue; + struct open_request **syn_wait_last; struct tcp_func *af_specific; }; @@ -311,29 +335,29 @@ atomic_t wmem_alloc; atomic_t rmem_alloc; unsigned long allocation; /* Allocation mode */ + + /* The following stuff should probably move to the tcp private area */ __u32 write_seq; __u32 copied_seq; - __u32 fin_seq; __u32 syn_seq; __u32 urg_seq; __u32 urg_data; + unsigned char delayed_acks; + /* End of block to move */ + int sock_readers; /* user count */ - unsigned char delayed_acks, - dup_acks; /* * Not all are volatile, but some are, so we * might as well say they all are. */ volatile char dead, urginline, - intr, done, reuse, keepopen, linger, destroy, - ack_timed, no_check, zapped, /* In ax25 & ipx means not linked */ broadcast, @@ -350,12 +374,7 @@ int hashent; struct sock *pair; - struct sk_buff * send_head; - struct sk_buff_head back_log; - struct sk_buff *partial; - struct timer_list partial_timer; - atomic_t retransmits; struct sk_buff_head write_queue, receive_queue, @@ -374,22 +393,14 @@ 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; - atomic_t packets_out; unsigned short shutdown; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) @@ -404,13 +415,7 @@ struct raw6_opt tp_raw; #endif } tp_pinfo; -/* - * currently backoff isn't used, but I'm maintaining it in case - * we want to go back to a backoff formula that needs it - */ -/* - unsigned short backoff; - */ + int err, err_soft; /* Soft holds errors that don't cause failure but are the cause of a persistent failure not just @@ -426,6 +431,7 @@ unsigned short type; unsigned char localroute; /* Route locally only */ struct ucred peercred; + /* What the user has tried to set with the security API */ short authentication; short encryption; @@ -471,10 +477,6 @@ int ip_tos; /* TOS */ unsigned ip_cmsg_flags; struct tcphdr dummy_th; - struct timer_list keepalive_timer; /* TCP keepalive hack */ - struct timer_list retransmit_timer; /* TCP retransmit timer */ - struct timer_list delack_timer; /* TCP delayed ack timer */ - int ip_xmit_timeout; /* Why the timeout is running */ struct ip_options *opt; unsigned char ip_hdrincl; /* Include headers ? */ __u8 ip_mc_ttl; /* Multicasting TTL */ @@ -491,8 +493,8 @@ int timeout; /* What are we waiting for? */ struct timer_list timer; /* This is the TIME_WAIT/receive timer - * when we are doing IP - */ + * when we are doing IP + */ struct timeval stamp; /* diff -u --recursive --new-file v2.1.35/linux/include/net/tcp.h linux/include/net/tcp.h --- v2.1.35/linux/include/net/tcp.h Mon Apr 14 16:28:26 1997 +++ linux/include/net/tcp.h Wed Apr 23 11:03:11 1997 @@ -23,8 +23,11 @@ #include #include -/* This is for all connections with a full identity, no wildcards. */ -#define TCP_HTABLE_SIZE 256 +/* This is for all connections with a full identity, no wildcards. + * New scheme, half the table is for TIME_WAIT, the other half is + * for the rest. I'll experiment with dynamic table growth later. + */ +#define TCP_HTABLE_SIZE 1024 /* This is for listening sockets, thus all sockets which possess wildcards. */ #define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ @@ -52,9 +55,7 @@ return tcp_bhashfn(lport); } -/* These can have wildcards, don't try too hard. - * XXX deal with thousands of IP aliases for listening ports later - */ +/* These can have wildcards, don't try too hard. */ static __inline__ int tcp_lhashfn(unsigned short num) { return num & (TCP_LHTABLE_SIZE - 1); @@ -95,11 +96,13 @@ /* * 40 is maximal IP options size - * 4 is TCP option size (MSS) + * 20 is the maximum TCP options size we can currently construct on a SYN. + * 40 is the maximum possible TCP options size. */ -#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 4 + MAX_HEADER + 15) +#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 20 + MAX_HEADER + 15) #define MAX_FIN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) +#define BASE_ACK_SIZE (NETHDR_SIZE + MAX_HEADER + 15) #define MAX_ACK_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) #define MAX_RESET_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) @@ -163,6 +166,8 @@ * We don't use these yet, but they are for PAWS and big windows */ #define TCPOPT_WINDOW 3 /* Window scaling */ +#define TCPOPT_SACK_PERM 4 /* SACK Permitted */ +#define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ /* @@ -171,8 +176,15 @@ #define TCPOLEN_MSS 4 #define TCPOLEN_WINDOW 3 +#define TCPOLEN_SACK_PERM 2 #define TCPOLEN_TIMESTAMP 10 +/* + * TCP option flags for parsed options. + */ + +#define TCPOPTF_SACK_PERM 1 +#define TCPOPTF_TIMESTAMP 2 /* * TCP Vegas constants @@ -206,11 +218,15 @@ struct open_request { struct open_request *dl_next; - struct open_request *dl_prev; + struct open_request **dl_pprev; __u32 rcv_isn; __u32 snt_isn; __u16 rmt_port; __u16 mss; + __u8 snd_wscale; + char sack_ok; + char tstamp_ok; + __u32 ts_recent; unsigned long expires; int retrans; struct or_calltable *class; @@ -354,7 +370,7 @@ int len, int nonblock, int flags, int *addr_len); -extern int tcp_parse_options(struct tcphdr *th); +extern void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp); /* * TCP v4 functions exported for the inet6 API @@ -511,9 +527,8 @@ switch (state) { case TCP_ESTABLISHED: - if (oldstate != TCP_ESTABLISHED) { + if (oldstate != TCP_ESTABLISHED) tcp_statistics.TcpCurrEstab++; - } break; case TCP_CLOSE: @@ -523,47 +538,68 @@ 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) -{ - 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; +/* + * 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) +{ + int count = 4 + (wscale ? 4 : 0) + ((ts || sack) ? 4 : 0) + (ts ? 8 : 0); + unsigned char *optr = skb_put(skb,count); + __u32 *ptr = (__u32 *)optr; + + /* + * We always get an MSS option. + */ + *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); + if (ts) { + if (sack) { + *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(jiffies); /* TSVAL */ + *ptr++ = htonl(0); /* TSECR */ + } else { + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(jiffies); /* TSVAL */ + *ptr++ = htonl(0); /* TSECR */ } + } else if (sack) { + *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) + | (TCPOPT_NOP << 8) | TCPOPT_NOP); } - - req->dl_prev = req->dl_next = NULL; + if (wscale) + *ptr++ = htonl((TCPOPT_WINDOW << 24) | (TCPOLEN_WINDOW << 16) | wscale); + skb->csum = csum_partial(optr, count, 0); + return count; } -extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) +extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req) { - if (!tp->syn_wait_queue) - { - req->dl_next = req; - req->dl_prev = req; - tp->syn_wait_queue = req; - } + if(req->dl_next) + req->dl_next->dl_pprev = req->dl_pprev; else - { - struct open_request *list = tp->syn_wait_queue; - - req->dl_next = list; - req->dl_prev = list->dl_prev; - list->dl_prev->dl_next = req; - list->dl_prev = req; - } + tp->syn_wait_last = req->dl_pprev; + *req->dl_pprev = req->dl_next; +} +extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) +{ + req->dl_next = NULL; + req->dl_pprev = tp->syn_wait_last; + *tp->syn_wait_last = req; + tp->syn_wait_last = &req->dl_next; } extern void __tcp_inc_slow_timer(struct tcp_sl_timer *slt); @@ -587,4 +623,3 @@ } #endif /* _TCP_H */ - diff -u --recursive --new-file v2.1.35/linux/init/main.c linux/init/main.c --- v2.1.35/linux/init/main.c Wed Apr 16 14:15:00 1997 +++ linux/init/main.c Tue Apr 22 23:02:26 1997 @@ -896,7 +896,6 @@ memory_start = kmem_cache_init(memory_start, memory_end); sti(); calibrate_delay(); - memory_start = inode_init(memory_start,memory_end); memory_start = file_table_init(memory_start,memory_end); memory_start = name_cache_init(memory_start,memory_end); #ifdef CONFIG_BLK_DEV_INITRD @@ -913,6 +912,7 @@ kmem_cache_sizes_init(); vma_init(); buffer_init(); + inode_init(); sock_init(); #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD) ipc_init(); @@ -948,7 +948,7 @@ } #ifdef CONFIG_BLK_DEV_INITRD -__initfunc(static int do_linuxrc(void * shell)) +static int do_linuxrc(void * shell) { static char *argv[] = { "linuxrc", NULL, }; diff -u --recursive --new-file v2.1.35/linux/kernel/exit.c linux/kernel/exit.c --- v2.1.35/linux/kernel/exit.c Sun Apr 13 10:18:22 1997 +++ linux/kernel/exit.c Tue Apr 22 22:53:52 1997 @@ -41,18 +41,23 @@ * be handled immediately (ie non-blocked and untraced) * and that is ignored (either explicitly or by default) */ + spin_lock_irq(&p->sig->siglock); if (!(mask & p->blocked) && !(p->flags & PF_PTRACED)) { /* don't bother with ignored signals (but SIGCHLD is special) */ if (sa->sa_handler == SIG_IGN && sig != SIGCHLD) - return; + goto out; /* some signals are ignored by default.. (but SIGCONT already did its deed) */ if ((sa->sa_handler == SIG_DFL) && (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH || sig == SIGURG)) - return; + goto out; } + spin_lock(&p->sigmask_lock); p->signal |= mask; + spin_unlock(&p->sigmask_lock); if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked)) wake_up_process(p); +out: + spin_unlock_irq(&p->sig->siglock); } /* @@ -65,16 +70,23 @@ if (p->sig) { unsigned long mask = 1UL << sig; struct sigaction *sa = p->sig->action + sig; + + spin_lock_irq(&p->sig->siglock); + + spin_lock(&p->sigmask_lock); p->signal |= mask; p->blocked &= ~mask; + spin_unlock(&p->sigmask_lock); + if (sa->sa_handler == SIG_IGN) sa->sa_handler = SIG_DFL; if (p->state == TASK_INTERRUPTIBLE) wake_up_process(p); + + spin_unlock_irq(&p->sig->siglock); } } - int send_sig(unsigned long sig,struct task_struct * p,int priv) { if (!p || sig > 32) @@ -84,24 +96,23 @@ (current->uid ^ p->suid) && (current->uid ^ p->uid) && !suser()) return -EPERM; - if (!sig) - return 0; - /* - * Forget it if the process is already zombie'd. - */ - if (!p->sig) - return 0; - if ((sig == SIGKILL) || (sig == SIGCONT)) { - if (p->state == TASK_STOPPED) - wake_up_process(p); - p->exit_code = 0; - p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | - (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) ); - } - if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) - p->signal &= ~(1<<(SIGCONT-1)); - /* Actually generate the signal */ - generate(sig,p); + + if (sig && p->sig) { + spin_lock_irq(&p->sigmask_lock); + if ((sig == SIGKILL) || (sig == SIGCONT)) { + if (p->state == TASK_STOPPED) + wake_up_process(p); + p->exit_code = 0; + p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | + (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) ); + } + if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) + p->signal &= ~(1<<(SIGCONT-1)); + spin_unlock_irq(&p->sigmask_lock); + + /* Actually generate the signal */ + generate(sig,p); + } return 0; } @@ -125,6 +136,12 @@ } for (i=1 ; iprocessor != NO_PROC_ID) + barrier(); + spin_unlock_wait(&scheduler_lock); +#endif nr_tasks--; task[i] = NULL; REMOVE_LINKS(p); @@ -245,14 +262,18 @@ int fallback; fallback = -1; + read_lock(&tasklist_lock); for_each_task(p) { if (p->session <= 0) continue; - if (p->pgrp == pgrp) - return p->session; + if (p->pgrp == pgrp) { + fallback = p->session; + break; + } if (p->pid == pgrp) fallback = p->session; } + read_unlock(&tasklist_lock); return fallback; } @@ -262,21 +283,29 @@ */ int kill_pg(int pgrp, int sig, int priv) { - struct task_struct *p; - int err,retval = -ESRCH; - int found = 0; + int retval; - if (sig<0 || sig>32 || pgrp<=0) - return -EINVAL; - for_each_task(p) { - if (p->pgrp == pgrp) { - if ((err = send_sig(sig,p,priv)) != 0) - retval = err; - else - found++; + retval = -EINVAL; + if (sig >= 0 && sig <= 32 && pgrp > 0) { + struct task_struct *p; + int found = 0; + + retval = -ESRCH; + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pgrp == pgrp) { + int err = send_sig(sig,p,priv); + if (err != 0) + retval = err; + else + found++; + } } + read_unlock(&tasklist_lock); + if (found) + retval = 0; } - return(found ? 0 : retval); + return retval; } /* @@ -286,34 +315,51 @@ */ int kill_sl(int sess, int sig, int priv) { - struct task_struct *p; - int err,retval = -ESRCH; - int found = 0; + int retval; - if (sig<0 || sig>32 || sess<=0) - return -EINVAL; - for_each_task(p) { - if (p->session == sess && p->leader) { - if ((err = send_sig(sig,p,priv)) != 0) - retval = err; - else - found++; + retval = -EINVAL; + if (sig >= 0 && sig <= 32 && sess > 0) { + struct task_struct *p; + int found = 0; + + retval = -ESRCH; + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->leader && p->session == sess) { + int err = send_sig(sig,p,priv); + + if (err) + retval = err; + else + found++; + } } + read_unlock(&tasklist_lock); + if (found) + retval = 0; } - return(found ? 0 : retval); + return retval; } int kill_proc(int pid, int sig, int priv) { - struct task_struct *p; + int retval; - if (sig<0 || sig>32) - return -EINVAL; - for_each_task(p) { - if (p && p->pid == pid) - return send_sig(sig,p,priv); + retval = -EINVAL; + if (sig >= 0 && sig <= 32) { + struct task_struct *p; + + retval = -ESRCH; + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pid != pid) + continue; + retval = send_sig(sig,p,priv); + break; + } + read_unlock(&tasklist_lock); } - return(-ESRCH); + return retval; } /* @@ -322,34 +368,30 @@ */ asmlinkage int sys_kill(int pid,int sig) { - int err, retval = 0, count = 0; + if (!pid) + return kill_pg(current->pgrp,sig,0); - lock_kernel(); - if (!pid) { - err = kill_pg(current->pgrp,sig,0); - goto out; - } if (pid == -1) { + int retval = 0, count = 0; struct task_struct * p; + + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid > 1 && p != current) { + int err; ++count; if ((err = send_sig(sig,p,0)) != -EPERM) retval = err; } } - err = count ? retval : -ESRCH; - goto out; - } - if (pid < 0) { - err = kill_pg(-pid,sig,0); - goto out; + read_unlock(&tasklist_lock); + return count ? retval : -ESRCH; } + if (pid < 0) + return kill_pg(-pid,sig,0); + /* Normal kill */ - err = kill_proc(pid,sig,0); -out: - unlock_kernel(); - return err; + return kill_proc(pid,sig,0); } /* @@ -364,16 +406,20 @@ { struct task_struct *p; + read_lock(&tasklist_lock); for_each_task(p) { if ((p == ignored_task) || (p->pgrp != pgrp) || (p->state == TASK_ZOMBIE) || (p->p_pptr->pid == 1)) continue; if ((p->p_pptr->pgrp != pgrp) && - (p->p_pptr->session == p->session)) - return 0; + (p->p_pptr->session == p->session)) { + read_unlock(&tasklist_lock); + return 0; + } } - return(1); /* (sighing) "Often!" */ + read_unlock(&tasklist_lock); + return 1; /* (sighing) "Often!" */ } int is_orphaned_pgrp(int pgrp) @@ -383,21 +429,27 @@ static inline int has_stopped_jobs(int pgrp) { + int retval = 0; struct task_struct * p; + read_lock(&tasklist_lock); for_each_task(p) { if (p->pgrp != pgrp) continue; - if (p->state == TASK_STOPPED) - return(1); + if (p->state != TASK_STOPPED) + continue; + retval = 1; + break; } - return(0); + read_unlock(&tasklist_lock); + return retval; } static inline void forget_original_parent(struct task_struct * father) { struct task_struct * p; + read_lock(&tasklist_lock); for_each_task(p) { if (p->p_opptr == father) if (task[smp_num_cpus]) /* init */ @@ -405,6 +457,7 @@ else p->p_opptr = task[0]; } + read_unlock(&tasklist_lock); } static inline void close_files(struct files_struct * files) @@ -470,9 +523,8 @@ if (sig) { tsk->sig = NULL; - if (!--sig->count) { + if (atomic_dec_and_test(&sig->count)) kfree(sig); - } } } @@ -635,24 +687,22 @@ struct wait_queue wait = { current, NULL }; struct task_struct *p; - lock_kernel(); if (stat_addr) { - retval = verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr)); - if (retval) - goto out; + if(verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr))) + return -EFAULT; } if (ru) { - retval = verify_area(VERIFY_WRITE, ru, sizeof(*ru)); - if (retval) - goto out; + if(verify_area(VERIFY_WRITE, ru, sizeof(*ru))) + return -EFAULT; } - retval = -EINVAL; + if (options & ~(WNOHANG|WUNTRACED|__WCLONE)) - goto out; + return -EINVAL; add_wait_queue(¤t->wait_chldexit,&wait); repeat: - flag=0; + flag = 0; + read_lock(&tasklist_lock); for (p = current->p_cptr ; p ; p = p->p_osptr) { if (pid>0) { if (p->pid != pid) @@ -674,23 +724,28 @@ 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); @@ -705,6 +760,7 @@ continue; } } + read_unlock(&tasklist_lock); if (flag) { retval = 0; if (options & WNOHANG) @@ -719,8 +775,6 @@ retval = -ECHILD; end_wait4: remove_wait_queue(¤t->wait_chldexit,&wait); -out: - unlock_kernel(); return retval; } @@ -732,12 +786,7 @@ */ asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options) { - int ret; - - lock_kernel(); - ret = sys_wait4(pid, stat_addr, options, NULL); - unlock_kernel(); - return ret; + return sys_wait4(pid, stat_addr, options, NULL); } #endif diff -u --recursive --new-file v2.1.35/linux/kernel/fork.c linux/kernel/fork.c --- v2.1.35/linux/kernel/fork.c Sun Apr 13 10:18:22 1997 +++ linux/kernel/fork.c Tue Apr 22 22:53:52 1997 @@ -47,11 +47,15 @@ max_tasks--; /* count the new process.. */ if (max_tasks < nr_tasks) { struct task_struct *p; + read_lock(&tasklist_lock); for_each_task (p) { if (p->uid == current->uid) - if (--max_tasks < 0) + if (--max_tasks < 0) { + read_unlock(&tasklist_lock); return -EAGAIN; + } } + read_unlock(&tasklist_lock); } } for (i = 0 ; i < NR_TASKS ; i++) { @@ -67,6 +71,8 @@ if (flags & CLONE_PID) return current->pid; + + read_lock(&tasklist_lock); repeat: if ((++last_pid) & 0xffff8000) last_pid=1; @@ -76,6 +82,8 @@ p->session == last_pid) goto repeat; } + read_unlock(&tasklist_lock); + return last_pid; } @@ -203,13 +211,14 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) { if (clone_flags & CLONE_SIGHAND) { - current->sig->count++; + atomic_inc(¤t->sig->count); return 0; } tsk->sig = kmalloc(sizeof(*tsk->sig), GFP_KERNEL); if (!tsk->sig) return -1; - tsk->sig->count = 1; + spin_lock_init(&tsk->sig->siglock); + atomic_set(&tsk->sig->count, 1); memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action)); return 0; } diff -u --recursive --new-file v2.1.35/linux/kernel/info.c linux/kernel/info.c --- v2.1.35/linux/kernel/info.c Fri Apr 4 08:52:26 1997 +++ linux/kernel/info.c Tue Apr 22 22:53:52 1997 @@ -23,7 +23,7 @@ memset((char *)&val, 0, sizeof(struct sysinfo)); - lock_kernel(); + cli(); val.uptime = jiffies / HZ; val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); @@ -31,10 +31,10 @@ val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); val.procs = nr_tasks-1; + sti(); si_meminfo(&val); si_swapinfo(&val); - unlock_kernel(); if (copy_to_user(info, &val, sizeof(struct sysinfo))) return -EFAULT; diff -u --recursive --new-file v2.1.35/linux/kernel/itimer.c linux/kernel/itimer.c --- v2.1.35/linux/kernel/itimer.c Sun Jan 26 02:07:49 1997 +++ linux/kernel/itimer.c Tue Apr 22 22:53:52 1997 @@ -43,7 +43,6 @@ { value->tv_usec = (jiffies % HZ) * (1000000 / HZ); value->tv_sec = jiffies / HZ; - return; } static int _getitimer(int which, struct itimerval *value) @@ -80,20 +79,18 @@ return 0; } +/* SMP: Only we modify our itimer values. */ asmlinkage int sys_getitimer(int which, struct itimerval *value) { int error = -EFAULT; struct itimerval get_buffer; - lock_kernel(); - if (!value) - goto out; - error = _getitimer(which, &get_buffer); - if (error) - goto out; - error = copy_to_user(value, &get_buffer, sizeof(get_buffer)) ? -EFAULT : 0; -out: - unlock_kernel(); + if (value) { + error = _getitimer(which, &get_buffer); + if (!error) + error = copy_to_user(value, &get_buffer, sizeof(get_buffer)) + ? -EFAULT : 0; + } return error; } @@ -155,31 +152,27 @@ return 0; } +/* SMP: Again, only we play with our itimers, and signals are SMP safe + * now so that is not an issue at all anymore. + */ asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) { - int error; struct itimerval set_buffer, get_buffer; + int error; - lock_kernel(); if (value) { - error = verify_area(VERIFY_READ, value, sizeof(*value)); - if (error) - goto out; - error = copy_from_user(&set_buffer, value, sizeof(set_buffer)); - if (error) { - error = -EFAULT; - goto out; - } + if(verify_area(VERIFY_READ, value, sizeof(*value))) + return -EFAULT; + if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) + return -EFAULT; } else memset((char *) &set_buffer, 0, sizeof(set_buffer)); error = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0); if (error || !ovalue) - goto out; + return error; if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer))) - error = -EFAULT; -out: - unlock_kernel(); - return error; + return -EFAULT; + return 0; } diff -u --recursive --new-file v2.1.35/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.35/linux/kernel/ksyms.c Mon Apr 14 16:28:26 1997 +++ linux/kernel/ksyms.c Tue Apr 22 22:49:38 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,9 @@ 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; @@ -130,6 +134,10 @@ EXPORT_SYMBOL(num_physpages); EXPORT_SYMBOL(high_memory); EXPORT_SYMBOL(update_vm_cache); +EXPORT_SYMBOL(kmem_cache_create); +EXPORT_SYMBOL(kmem_cache_destroy); +EXPORT_SYMBOL(kmem_cache_alloc); +EXPORT_SYMBOL(kmem_cache_free); /* filesystem internal functions */ EXPORT_SYMBOL(getname); @@ -174,6 +182,10 @@ 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); @@ -258,7 +270,10 @@ EXPORT_SYMBOL(tq_scheduler); EXPORT_SYMBOL(timer_active); EXPORT_SYMBOL(timer_table); + #ifdef __SMP__ +/* Various random spinlocks we want to export */ +EXPORT_SYMBOL(tqueue_lock); EXPORT_SYMBOL(waitqueue_lock); #endif diff -u --recursive --new-file v2.1.35/linux/kernel/sched.c linux/kernel/sched.c --- v2.1.35/linux/kernel/sched.c Wed Apr 16 14:15:00 1997 +++ linux/kernel/sched.c Tue Apr 22 22:55:30 1997 @@ -126,22 +126,6 @@ (p->prev_run = init_task.prev_run)->next_run = p; p->next_run = &init_task; init_task.prev_run = p; -#if 0 /* def __SMP__ */ - /* this is safe only if called with cli()*/ - inc_smp_counter(&smp_process_available); - if ((0!=p->pid) && smp_threads_ready) - { - int i; - for (i=0;ipid) - { - smp_message_pass(cpu_logical_map[i], MSG_RESCHEDULE, 0L, 0); - break; - } - } - } -#endif } static inline void del_from_runqueue(struct task_struct * p) @@ -187,9 +171,7 @@ } /* - * The tasklist_lock protects the linked list of processes - * and doesn't need to be interrupt-safe as interrupts never - * use the task-list. + * The tasklist_lock protects the linked list of processes. * * The scheduler lock is protecting against multiple entry * into the scheduling code, and doesn't need to worry @@ -199,7 +181,7 @@ * The run-queue lock locks the parts that actually access * and change the run-queues, and have to be interrupt-safe. */ -spinlock_t tasklist_lock = SPIN_LOCK_UNLOCKED; +rwlock_t tasklist_lock = RW_LOCK_UNLOCKED; spinlock_t scheduler_lock = SPIN_LOCK_UNLOCKED; static spinlock_t runqueue_lock = SPIN_LOCK_UNLOCKED; @@ -391,10 +373,10 @@ /* Do we need to re-calculate counters? */ if (!c) { struct task_struct *p; - spin_lock(&tasklist_lock); + read_lock(&tasklist_lock); for_each_task(p) p->counter = (p->counter >> 1) + p->priority; - spin_unlock(&tasklist_lock); + read_unlock(&tasklist_lock); } } } @@ -421,7 +403,7 @@ } spin_unlock(&scheduler_lock); - reaquire_kernel_lock(prev, smp_processor_id(), lock_depth); + reacquire_kernel_lock(prev, smp_processor_id(), lock_depth); } #ifndef __alpha__ @@ -432,10 +414,8 @@ */ asmlinkage int sys_pause(void) { - lock_kernel(); current->state = TASK_INTERRUPTIBLE; schedule(); - unlock_kernel(); return -ERESTARTNOHAND; } @@ -1208,7 +1188,6 @@ 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; @@ -1218,7 +1197,6 @@ /* And we'd better return too much than too little anyway */ if (it_old.it_value.tv_usec) oldalarm++; - unlock_kernel(); return oldalarm; } @@ -1366,13 +1344,15 @@ 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; } @@ -1428,64 +1408,42 @@ 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) @@ -1561,7 +1519,6 @@ { value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ); value->tv_sec = jiffies / HZ; - return; } asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp) @@ -1590,11 +1547,10 @@ } expire = timespectojiffies(&t) + (t.tv_sec || t.tv_nsec) + jiffies; - lock_kernel(); + current->timeout = expire; current->state = TASK_INTERRUPTIBLE; schedule(); - unlock_kernel(); if (expire > jiffies) { if (rmtp) { diff -u --recursive --new-file v2.1.35/linux/kernel/signal.c linux/kernel/signal.c --- v2.1.35/linux/kernel/signal.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/signal.c Tue Apr 22 22:53:52 1997 @@ -31,6 +31,9 @@ * We don't need to get the kernel lock - this is all local to this * particular thread.. (and that's good, because this is _heavily_ * used by various programs) + * + * No SMP locking would prevent the inherent races present in this + * routine, thus we do not perform any locking at all. */ asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset) { @@ -38,9 +41,10 @@ if (set) { sigset_t new_set; - int error = get_user(new_set, set); - if (error) - return error; + + if(get_user(new_set, set)) + return -EFAULT; + new_set &= _BLOCKABLE; switch (how) { default: @@ -57,9 +61,8 @@ current->blocked = new_set; } if (oset) { - int error = put_user(old_set, oset); - if (error) - return error; + if(put_user(old_set, oset)) + return -EFAULT; } return 0; } @@ -69,21 +72,19 @@ */ asmlinkage int sys_sgetmask(void) { - int ret; - /* SMP safe */ - ret = current->blocked; - return ret; + return current->blocked; } asmlinkage int sys_ssetmask(int newmask) { int old; - lock_kernel(); + spin_lock_irq(¤t->sigmask_lock); old = current->blocked; current->blocked = newmask & _BLOCKABLE; - unlock_kernel(); + spin_unlock_irq(¤t->sigmask_lock); + return old; } @@ -94,9 +95,9 @@ 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; } @@ -114,22 +115,24 @@ * Note the silly behaviour of SIGCHLD: SIG_IGN means that the signal * isn't actually ignored, but does automatic child reaping, while * SIG_DFL is explicitly said by POSIX to force the signal to be ignored.. + * + * All callers of check_pending must be holding current->sig->siglock. */ inline void check_pending(int signum) { struct sigaction *p; p = signum - 1 + current->sig->action; + spin_lock(¤t->sigmask_lock); if (p->sa_handler == SIG_IGN) { current->signal &= ~_S(signum); - return; - } - if (p->sa_handler == SIG_DFL) { - if (signum != SIGCONT && signum != SIGCHLD && signum != SIGWINCH) - return; - current->signal &= ~_S(signum); - return; + } else if (p->sa_handler == SIG_DFL) { + if (signum == SIGCONT || + signum == SIGCHLD || + signum != SIGWINCH) + current->signal &= ~_S(signum); } + spin_unlock(¤t->sigmask_lock); } #ifndef __alpha__ @@ -138,30 +141,28 @@ */ asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler) { - unsigned long err; struct sigaction tmp; - lock_kernel(); - err = -EINVAL; if (signum<1 || signum>32) - goto out; + return -EINVAL; if (signum==SIGKILL || signum==SIGSTOP) - goto out; + return -EINVAL; if (handler != SIG_DFL && handler != SIG_IGN) { - err = verify_area(VERIFY_READ, handler, 1); - if (err) - goto out; + if(verify_area(VERIFY_READ, handler, 1)) + return -EFAULT; } + memset(&tmp, 0, sizeof(tmp)); tmp.sa_handler = handler; tmp.sa_flags = SA_ONESHOT | SA_NOMASK; + + spin_lock_irq(¤t->sig->siglock); handler = current->sig->action[signum-1].sa_handler; current->sig->action[signum-1] = tmp; check_pending(signum); - err = (unsigned long) handler; -out: - unlock_kernel(); - return err; + spin_unlock_irq(¤t->sig->siglock); + + return (unsigned long) handler; } #endif @@ -171,22 +172,33 @@ { struct sigaction new_sa, *p; - if (signum<1 || signum>32) + if (signum < 1 || signum > 32) return -EINVAL; + p = signum - 1 + current->sig->action; + if (action) { if (copy_from_user(&new_sa, action, sizeof(struct sigaction))) return -EFAULT; if (signum==SIGKILL || signum==SIGSTOP) return -EINVAL; } + if (oldaction) { + /* In the clone() case we could copy half consistant + * state to the user, however this could sleep and + * deadlock us if we held the signal lock on SMP. So for + * now I take the easy way out and do no locking. + */ if (copy_to_user(oldaction, p, sizeof(struct sigaction))) return -EFAULT; } + if (action) { + spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(signum); + spin_unlock_irq(¤t->sig->siglock); } return 0; } diff -u --recursive --new-file v2.1.35/linux/kernel/sys.c linux/kernel/sys.c --- v2.1.35/linux/kernel/sys.c Sun Apr 13 10:18:22 1997 +++ linux/kernel/sys.c Tue Apr 22 22:53:52 1997 @@ -87,12 +87,11 @@ asmlinkage int sys_setpriority(int which, int who, int niceval) { struct task_struct *p; - int error = EINVAL; unsigned int priority; + int error; - lock_kernel(); if (which > 2 || which < 0) - goto out; + return -EINVAL; /* normalize: avoid signed division (rounding problems) */ error = ESRCH; @@ -109,6 +108,7 @@ priority = 1; } + read_lock(&tasklist_lock); for_each_task(p) { if (!proc_sel(p, which, who)) continue; @@ -124,8 +124,8 @@ else p->priority = priority; } -out: - unlock_kernel(); + read_unlock(&tasklist_lock); + return -error; } @@ -138,26 +138,23 @@ { struct task_struct *p; long max_prio = -ESRCH; - int ret = -EINVAL; - lock_kernel(); if (which > 2 || which < 0) - goto out; + return -EINVAL; + read_lock(&tasklist_lock); for_each_task (p) { if (!proc_sel(p, which, who)) continue; if (p->priority > max_prio) max_prio = p->priority; } + read_unlock(&tasklist_lock); /* scale the priority from timeslice to 0..40 */ if (max_prio > 0) max_prio = (max_prio * 20 + DEF_PRIORITY/2) / DEF_PRIORITY; - ret = max_prio; -out: - unlock_kernel(); - return ret; + return max_prio; } #ifndef __alpha__ @@ -304,21 +301,22 @@ * The general idea is that a program which uses just setregid() will be * 100% compatible with BSD. A program which uses just setgid() will be * 100% compatible with POSIX w/ Saved ID's. + * + * SMP: There are not races, the gid's are checked only by filesystem + * operations (as far as semantic preservation is concerned). */ asmlinkage int sys_setregid(gid_t rgid, gid_t egid) { int old_rgid = current->gid; int old_egid = current->egid; - int err = -EPERM; - lock_kernel(); if (rgid != (gid_t) -1) { if ((old_rgid == rgid) || (current->egid==rgid) || suser()) current->gid = rgid; else - goto out; + return -EPERM; } if (egid != (gid_t) -1) { if ((old_rgid == egid) || @@ -328,7 +326,7 @@ current->fsgid = current->egid = egid; else { current->gid = old_rgid; - goto out; + return -EPERM; } } if (rgid != (gid_t) -1 || @@ -337,33 +335,28 @@ current->fsgid = current->egid; if (current->egid != old_egid) current->dumpable = 0; - err = 0; -out: - unlock_kernel(); - return err; + return 0; } /* * setgid() is implemented like SysV w/ SAVED_IDS + * + * SMP: Same implicit races as above. */ asmlinkage int sys_setgid(gid_t gid) { int old_egid = current->egid; - int err = -EPERM; - lock_kernel(); if (suser()) current->gid = current->egid = current->sgid = current->fsgid = gid; else if ((gid == current->gid) || (gid == current->sgid)) current->egid = current->fsgid = gid; else - goto out; - err = 0; + return -EPERM; + if (current->egid != old_egid) current->dumpable = 0; -out: - unlock_kernel(); - return err; + return 0; } static char acct_active = 0; @@ -532,9 +525,7 @@ { int old_ruid; int old_euid; - int err = -EPERM; - lock_kernel(); old_ruid = current->uid; old_euid = current->euid; if (ruid != (uid_t) -1) { @@ -543,7 +534,7 @@ suser()) current->uid = ruid; else - goto out; + return -EPERM; } if (euid != (uid_t) -1) { if ((old_ruid == euid) || @@ -553,7 +544,7 @@ current->fsuid = current->euid = euid; else { current->uid = old_ruid; - goto out; + return -EPERM; } } if (ruid != (uid_t) -1 || @@ -562,10 +553,7 @@ current->fsuid = current->euid; if (current->euid != old_euid) current->dumpable = 0; - err = 0; -out: - unlock_kernel(); - return err; + return 0; } /* @@ -582,22 +570,17 @@ asmlinkage int sys_setuid(uid_t uid) { int old_euid = current->euid; - int retval = 0; - lock_kernel(); if (suser()) current->uid = current->euid = current->suid = current->fsuid = uid; else if ((uid == current->uid) || (uid == current->suid)) current->fsuid = current->euid = uid; - else { - retval = -EPERM; - goto out; - } + else + return -EPERM; + if (current->euid != old_euid) current->dumpable = 0; -out: - unlock_kernel(); - return retval; + return 0; } @@ -608,43 +591,37 @@ asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) { uid_t old_ruid, old_euid, old_suid; - int err = -EPERM; - lock_kernel(); old_ruid = current->uid; old_euid = current->euid; old_suid = current->suid; if ((ruid != (uid_t) -1) && (ruid != current->uid) && (ruid != current->euid) && (ruid != current->suid)) - goto out; + return -EPERM; if ((euid != (uid_t) -1) && (euid != current->uid) && (euid != current->euid) && (euid != current->suid)) - goto out; + return -EPERM; if ((suid != (uid_t) -1) && (suid != current->uid) && (suid != current->euid) && (suid != current->suid)) - goto out; + return -EPERM; if (ruid != (uid_t) -1) current->uid = ruid; if (euid != (uid_t) -1) current->euid = euid; if (suid != (uid_t) -1) current->suid = suid; - err = 0; -out: - unlock_kernel(); - return err; + return 0; } asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) { int retval; - lock_kernel(); if (!(retval = put_user(current->uid, ruid)) && !(retval = put_user(current->euid, euid))) retval = put_user(current->suid, suid); - unlock_kernel(); + return retval; } @@ -659,14 +636,13 @@ { int old_fsuid; - lock_kernel(); old_fsuid = current->fsuid; if (uid == current->uid || uid == current->euid || uid == current->suid || uid == current->fsuid || suser()) current->fsuid = uid; if (current->fsuid != old_fsuid) current->dumpable = 0; - unlock_kernel(); + return old_fsuid; } @@ -677,14 +653,13 @@ { int old_fsgid; - lock_kernel(); old_fsgid = current->fsgid; if (gid == current->gid || gid == current->egid || gid == current->sgid || gid == current->fsgid || suser()) current->fsgid = gid; if (current->fsgid != old_fsgid) current->dumpable = 0; - unlock_kernel(); + return old_fsgid; } @@ -727,21 +702,29 @@ struct task_struct * p; int err = -EINVAL; - lock_kernel(); if (!pid) pid = current->pid; if (!pgid) pgid = pid; if (pgid < 0) - goto out; + return -EINVAL; + + read_lock(&tasklist_lock); for_each_task(p) { - if (p->pid == pid) + if (p->pid == pid) { + /* NOTE: I haven't dropped tasklist_lock, this is + * on purpose. -DaveM + */ goto found_task; + } } - err = -ESRCH; - goto out; + read_unlock(&tasklist_lock); + return -ESRCH; found_task: + /* From this point forward we keep holding onto the tasklist lock + * so that our parent does not change from under us. -DaveM + */ err = -ESRCH; if (p->p_pptr == current || p->p_opptr == current) { err = -EPERM; @@ -769,30 +752,29 @@ p->pgrp = pgid; err = 0; out: - unlock_kernel(); + /* All paths lead to here, thus we are safe. -DaveM */ + read_unlock(&tasklist_lock); return err; } asmlinkage int sys_getpgid(pid_t pid) { - struct task_struct * p; - int ret; - - lock_kernel(); if (!pid) { - ret = current->pgrp; + return current->pgrp; } else { + struct task_struct *p; + int ret = -ESRCH; + + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid == pid) { ret = p->pgrp; - goto out; + break; } } - ret = -ESRCH; + read_unlock(&tasklist_lock); + return ret; } -out: - unlock_kernel(); - return ret; } asmlinkage int sys_getpgrp(void) @@ -810,17 +792,16 @@ if (!pid) { ret = current->session; } else { - /* Walking the process table needs locks */ - lock_kernel(); + ret = -ESRCH; + + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid == pid) { ret = p->session; - goto out; + break; } } - ret = -ESRCH; -out: - unlock_kernel(); + read_unlock(&tasklist_lock); } return ret; } @@ -830,7 +811,7 @@ struct task_struct * p; int err = -EPERM; - lock_kernel(); + read_lock(&tasklist_lock); for_each_task(p) { if (p->pgrp == current->pid) goto out; @@ -842,7 +823,7 @@ current->tty_old_pgrp = 0; err = current->pgrp; out: - unlock_kernel(); + read_unlock(&tasklist_lock); return err; } @@ -908,17 +889,11 @@ 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__ @@ -927,26 +902,24 @@ * 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); @@ -959,8 +932,7 @@ 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; } @@ -968,39 +940,26 @@ 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; } /* @@ -1009,66 +968,44 @@ */ 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; } /* @@ -1078,13 +1015,18 @@ * 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: @@ -1115,22 +1057,14 @@ r.ru_nswap = p->nswap + p->cnswap; break; } - err = copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; - unlock_kernel(); - return err; + return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; } asmlinkage int sys_getrusage(int who, struct rusage *ru) { - int err = -EINVAL; - - lock_kernel(); if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) - goto out; - err = getrusage(current, who, ru); -out: - unlock_kernel(); - return err; + return -EINVAL; + return getrusage(current, who, ru); } asmlinkage int sys_umask(int mask) diff -u --recursive --new-file v2.1.35/linux/kernel/time.c linux/kernel/time.c --- v2.1.35/linux/kernel/time.c Fri Apr 4 08:52:26 1997 +++ linux/kernel/time.c Tue Apr 22 22:53:52 1997 @@ -167,20 +167,21 @@ if (tz) { if (copy_from_user(&new_tz, tz, sizeof(*tz))) return -EFAULT; - lock_kernel(); + + /* SMP safe, global irq locking makes it work. */ sys_tz = new_tz; if (firsttime) { firsttime = 0; if (!tv) warp_clock(); } - unlock_kernel(); } if (tv) { - lock_kernel(); + /* SMP safe, again the code in arch/foo/time.c should + * globally block out interrupts when it runs. + */ do_settimeofday(&new_tv); - unlock_kernel(); } return 0; } @@ -234,9 +235,7 @@ if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ) return -EINVAL; - lock_kernel(); - - cli(); + cli(); /* SMP: global cli() is enough protection. */ /* Save for later - semantics of adjtime is to return old value */ save_adjust = time_adjust; @@ -351,6 +350,6 @@ txc.stbcnt = pps_stbcnt; sti(); - unlock_kernel(); + return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state; } diff -u --recursive --new-file v2.1.35/linux/mm/page_alloc.c linux/mm/page_alloc.c --- v2.1.35/linux/mm/page_alloc.c Mon Apr 14 16:28:27 1997 +++ linux/mm/page_alloc.c Tue Apr 22 08:14:21 1997 @@ -276,8 +276,8 @@ * with a minimum of 16 pages. This is totally arbitrary */ i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+7); - if (i < 16) - i = 16; + if (i < 48) + i = 48; min_free_pages = i; free_pages_low = i + (i>>1); free_pages_high = i + i; diff -u --recursive --new-file v2.1.35/linux/mm/swap.c linux/mm/swap.c --- v2.1.35/linux/mm/swap.c Mon Apr 14 16:28:27 1997 +++ linux/mm/swap.c Tue Apr 22 08:14:21 1997 @@ -38,13 +38,13 @@ * * 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 */ -atomic_t nr_async_pages = ATOMIC_INIT; +atomic_t nr_async_pages = ATOMIC_INIT(0); /* * Constants for the page aging mechanism: the maximum age (actually, diff -u --recursive --new-file v2.1.35/linux/net/bridge/br.c linux/net/bridge/br.c --- v2.1.35/linux/net/bridge/br.c Thu Mar 27 14:40:14 1997 +++ linux/net/bridge/br.c Tue Apr 22 22:46:27 1997 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -699,7 +700,7 @@ } /* (4.6.1.2.3) */ } -void br_init(void) +__initfunc(void br_init(void)) { /* (4.8.1) */ int port_no; diff -u --recursive --new-file v2.1.35/linux/net/core/dev.c linux/net/core/dev.c --- v2.1.35/linux/net/core/dev.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/dev.c Tue Apr 22 22:46:27 1997 @@ -79,6 +79,7 @@ #include #include #include +#include #ifdef CONFIG_KERNELD #include #endif @@ -122,7 +123,7 @@ * Device list lock */ -atomic_t dev_lockct = ATOMIC_INIT; +atomic_t dev_lockct = ATOMIC_INIT(0); /* * Our notifier list @@ -479,10 +480,6 @@ /* 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 @@ -576,10 +573,6 @@ 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. @@ -676,9 +669,7 @@ /* * Add it to the "backlog" queue. */ -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif + skb_queue_tail(&backlog,skb); backlog_size++; @@ -1578,7 +1569,7 @@ #endif /* CONFIG_PROC_FS */ #endif /* CONFIG_NET_RADIO */ -int net_dev_init(void) +__initfunc(int net_dev_init(void)) { struct device *dev, **dp; diff -u --recursive --new-file v2.1.35/linux/net/core/dst.c linux/net/core/dst.c --- v2.1.35/linux/net/core/dst.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/dst.c Thu Apr 17 13:20:52 1997 @@ -20,7 +20,7 @@ #include struct dst_entry * dst_garbage_list; -atomic_t dst_total = ATOMIC_INIT; +atomic_t dst_total = ATOMIC_INIT(0); static unsigned long dst_gc_timer_expires; static unsigned long dst_gc_timer_inc = DST_GC_MAX; diff -u --recursive --new-file v2.1.35/linux/net/core/net_alias.c linux/net/core/net_alias.c --- v2.1.35/linux/net/core/net_alias.c Sun Jan 19 05:47:27 1997 +++ linux/net/core/net_alias.c Tue Apr 22 22:46:27 1997 @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -1359,7 +1360,7 @@ * Net_alias initialisation called from net_dev_init(). */ -void net_alias_init(void) +__initfunc(void net_alias_init(void)) { /* diff -u --recursive --new-file v2.1.35/linux/net/core/skbuff.c linux/net/core/skbuff.c --- v2.1.35/linux/net/core/skbuff.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/skbuff.c Tue Apr 22 22:46:27 1997 @@ -60,9 +60,9 @@ * Resource tracking variables */ -static atomic_t net_skbcount = ATOMIC_INIT; -static atomic_t net_allocs = ATOMIC_INIT; -static atomic_t net_fails = ATOMIC_INIT; +static atomic_t net_skbcount = ATOMIC_INIT(0); +static atomic_t net_allocs = ATOMIC_INIT(0); +static atomic_t net_fails = ATOMIC_INIT(0); extern atomic_t ip_frag_mem; @@ -87,509 +87,17 @@ #endif } -#if CONFIG_SKB_CHECK - -/* - * Debugging paranoia. Used for debugging network stacks. - */ - -int skb_check(struct sk_buff *skb, int head, int line, char *file) -{ - if (head) { - if (skb->magic_debug_cookie != SK_HEAD_SKB) { - printk("File: %s Line %d, found a bad skb-head\n", - file,line); - return -1; - } - if (!skb->next || !skb->prev) { - printk("skb_check: head without next or prev\n"); - return -1; - } - if (skb->next->magic_debug_cookie != SK_HEAD_SKB - && skb->next->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad next head-skb member\n", - file,line); - return -1; - } - if (skb->prev->magic_debug_cookie != SK_HEAD_SKB - && skb->prev->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad prev head-skb member\n", - file,line); - return -1; - } - return 0; - } - if (skb->next != NULL && skb->next->magic_debug_cookie != SK_HEAD_SKB - && skb->next->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad next skb member\n", - file,line); - return -1; - } - if (skb->prev != NULL && skb->prev->magic_debug_cookie != SK_HEAD_SKB - && skb->prev->magic_debug_cookie != SK_GOOD_SKB) { - printk("File: %s Line %d, bad prev skb member\n", - file,line); - return -1; - } - - - if(skb->magic_debug_cookie==SK_FREED_SKB) - { - printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n", - file,line); - printk("skb=%p, real size=%d, free=%d\n", - skb,skb->truesize,skb->free); - return -1; - } - if(skb->magic_debug_cookie!=SK_GOOD_SKB) - { - printk("File: %s Line %d, passed a non skb!\n", file,line); - printk("skb=%p, real size=%d, free=%d\n", - skb,skb->truesize,skb->free); - return -1; - } - if(skb->head>skb->data) - { - printk("File: %s Line %d, head > data !\n", file,line); - printk("skb=%p, head=%p, data=%p\n", - skb,skb->head,skb->data); - return -1; - } - if(skb->tail>skb->end) - { - printk("File: %s Line %d, tail > end!\n", file,line); - printk("skb=%p, tail=%p, end=%p\n", - skb,skb->tail,skb->end); - return -1; - } - if(skb->data>skb->tail) - { - printk("File: %s Line %d, data > tail!\n", file,line); - printk("skb=%p, data=%p, tail=%p\n", - skb,skb->data,skb->tail); - return -1; - } - if(skb->tail-skb->data!=skb->len) - { - printk("File: %s Line %d, wrong length\n", file,line); - printk("skb=%p, data=%p, end=%p len=%ld\n", - skb,skb->data,skb->end,skb->len); - return -1; - } - if((unsigned long) skb->end > (unsigned long) skb) - { - printk("File: %s Line %d, control overrun\n", file,line); - printk("skb=%p, end=%p\n", - skb,skb->end); - return -1; - } - - /* Guess it might be acceptable then */ - return 0; -} -#endif - - -#if CONFIG_SKB_CHECK -void skb_queue_head_init(struct sk_buff_head *list) -{ - list->prev = (struct sk_buff *)list; - list->next = (struct sk_buff *)list; - list->qlen = 0; - list->magic_debug_cookie = SK_HEAD_SKB; -} - - -/* - * Insert an sk_buff at the start of a list. - */ -void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk) -{ - unsigned long flags; - struct sk_buff *list = (struct sk_buff *)list_; - - save_flags(flags); - cli(); - - IS_SKB(newsk); - IS_SKB_HEAD(list); - if (newsk->next || newsk->prev) - printk("Suspicious queue head: sk_buff on list!\n"); - - newsk->next = list->next; - newsk->prev = list; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - newsk->list = list_; - list_->qlen++; - - restore_flags(flags); -} - -void __skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk) -{ - struct sk_buff *list = (struct sk_buff *)list_; - - - IS_SKB(newsk); - IS_SKB_HEAD(list); - if (newsk->next || newsk->prev) - printk("Suspicious queue head: sk_buff on list!\n"); - - newsk->next = list->next; - newsk->prev = list; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - newsk->list = list_; - list_->qlen++; - -} - -/* - * Insert an sk_buff at the end of a list. - */ -void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk) -{ - unsigned long flags; - struct sk_buff *list = (struct sk_buff *)list_; - - save_flags(flags); - cli(); - - if (newsk->next || newsk->prev) - printk("Suspicious queue tail: sk_buff on list!\n"); - IS_SKB(newsk); - IS_SKB_HEAD(list); - - newsk->next = list; - newsk->prev = list->prev; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - - newsk->list = list_; - list_->qlen++; - - restore_flags(flags); -} - -void __skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk) -{ - struct sk_buff *list = (struct sk_buff *)list_; - - if (newsk->next || newsk->prev) - printk("Suspicious queue tail: sk_buff on list!\n"); - IS_SKB(newsk); - IS_SKB_HEAD(list); - - newsk->next = list; - newsk->prev = list->prev; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - - newsk->list = list_; - list_->qlen++; -} - -/* - * Remove an sk_buff from a list. This routine is also interrupt safe - * so you can grab read and free buffers as another process adds them. - */ - -struct sk_buff *skb_dequeue(struct sk_buff_head *list_) -{ - unsigned long flags; - struct sk_buff *result; - struct sk_buff *list = (struct sk_buff *)list_; - - save_flags(flags); - cli(); - - IS_SKB_HEAD(list); - - result = list->next; - if (result == list) { - restore_flags(flags); - return NULL; - } - - result->next->prev = list; - list->next = result->next; - - result->next = NULL; - result->prev = NULL; - list_->qlen--; - result->list = NULL; - - restore_flags(flags); - - IS_SKB(result); - return result; -} - -struct sk_buff *__skb_dequeue(struct sk_buff_head *list_) -{ - struct sk_buff *result; - struct sk_buff *list = (struct sk_buff *)list_; - - IS_SKB_HEAD(list); - - result = list->next; - if (result == list) { - return NULL; - } - - result->next->prev = list; - list->next = result->next; - - result->next = NULL; - result->prev = NULL; - list_->qlen--; - result->list = NULL; - - IS_SKB(result); - return result; -} - -/* - * Insert a packet before another one in a list. - */ -void skb_insert(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - IS_SKB(old); - IS_SKB(newsk); - - if(!old->next || !old->prev) - printk("insert before unlisted item!\n"); - if(newsk->next || newsk->prev) - printk("inserted item is already on a list.\n"); - - save_flags(flags); - cli(); - newsk->next = old; - newsk->prev = old->prev; - old->prev = newsk; - newsk->prev->next = newsk; - newsk->list = old->list; - newsk->list->qlen++; - - restore_flags(flags); -} - -/* - * Insert a packet before another one in a list. - */ - -void __skb_insert(struct sk_buff *newsk, - struct sk_buff * prev, struct sk_buff *next, - struct sk_buff_head * list) -{ - IS_SKB(prev); - IS_SKB(newsk); - IS_SKB(next); - - if(!prev->next || !prev->prev) - printk("insert after unlisted item!\n"); - if(!next->next || !next->prev) - printk("insert before unlisted item!\n"); - if(newsk->next || newsk->prev) - printk("inserted item is already on a list.\n"); - - newsk->next = next; - newsk->prev = prev; - next->prev = newsk; - prev->next = newsk; - newsk->list = list; - list->qlen++; - -} - -/* - * Place a packet after a given packet in a list. - */ -void skb_append(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - IS_SKB(old); - IS_SKB(newsk); - - if(!old->next || !old->prev) - printk("append before unlisted item!\n"); - if(newsk->next || newsk->prev) - printk("append item is already on a list.\n"); - - save_flags(flags); - cli(); - - newsk->prev = old; - newsk->next = old->next; - newsk->next->prev = newsk; - old->next = newsk; - newsk->list = old->list; - newsk->list->qlen++; - - restore_flags(flags); -} - -/* - * Remove an sk_buff from its list. Works even without knowing the list it - * is sitting on, which can be handy at times. It also means that THE LIST - * MUST EXIST when you unlink. Thus a list must have its contents unlinked - * _FIRST_. - */ -void skb_unlink(struct sk_buff *skb) -{ - unsigned long flags; - - save_flags(flags); - cli(); - - IS_SKB(skb); - - if(skb->list) - { - skb->list->qlen--; - skb->next->prev = skb->prev; - skb->prev->next = skb->next; - skb->next = NULL; - skb->prev = NULL; - skb->list = NULL; - } -#ifdef PARANOID_BUGHUNT_MODE /* This is legal but we sometimes want to watch it */ - else - printk("skb_unlink: not a linked element\n"); -#endif - restore_flags(flags); -} - -void __skb_unlink(struct sk_buff *skb) -{ - IS_SKB(skb); - - if(skb->list) - { - skb->list->qlen--; - skb->next->prev = skb->prev; - skb->prev->next = skb->next; - skb->next = NULL; - skb->prev = NULL; - skb->list = NULL; - } -#ifdef PARANOID_BUGHUNT_MODE /* This is legal but we sometimes want to watch it */ - else - printk("skb_unlink: not a linked element\n"); -#endif -} - -/* - * Add data to an sk_buff - */ - -unsigned char *skb_put(struct sk_buff *skb, unsigned int len) -{ - unsigned char *tmp=skb->tail; - IS_SKB(skb); - skb->tail+=len; - skb->len+=len; - IS_SKB(skb); - if(skb->tail>skb->end) - panic("skput:over: %p:%d", __builtin_return_address(0),len); - return tmp; -} - -unsigned char *skb_push(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - skb->data-=len; - skb->len+=len; - IS_SKB(skb); - if(skb->datahead) - panic("skpush:under: %p:%d", __builtin_return_address(0),len); - return skb->data; -} - -unsigned char * skb_pull(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - if(len>skb->len) - return 0; - skb->data+=len; - skb->len-=len; - return skb->data; -} - -int skb_headroom(struct sk_buff *skb) -{ - IS_SKB(skb); - return skb->data-skb->head; -} - -int skb_tailroom(struct sk_buff *skb) -{ - IS_SKB(skb); - return skb->end-skb->tail; -} - -void skb_reserve(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - skb->data+=len; - skb->tail+=len; - if(skb->tail>skb->end) - panic("sk_res: over"); - if(skb->datahead) - panic("sk_res: under"); - IS_SKB(skb); -} - -void skb_trim(struct sk_buff *skb, unsigned int len) -{ - IS_SKB(skb); - if(skb->len>len) - { - skb->len=len; - skb->tail=skb->data+len; - } -} - - - -#endif - -/************************************************************************** - - Stuff below this point isn't debugging duplicates of the inlines - used for buffer handling - -***************************************************************************/ - /* * Free an sk_buff. Release anything attached to the buffer. */ void __kfree_skb(struct sk_buff *skb) { -#if CONFIG_SKB_CHECK - if (skb == NULL) - { - printk(KERN_CRIT "kfree_skb: skb = NULL (from %p)\n", - __builtin_return_address(0)); - return; - } - IS_SKB(skb); -#endif if (skb->list) - printk(KERN_WARNING "Warning: kfree_skb passed an skb still on a list (from %p).\n", - __builtin_return_address(0)); + printk(KERN_WARNING "Warning: kfree_skb passed an skb still " + "on a list (from %p).\n", __builtin_return_address(0)); dst_release(skb->dst); - if(skb->destructor) skb->destructor(skb); kfree_skbmem(skb); @@ -607,15 +115,14 @@ struct sk_buff *alloc_skb(unsigned int size,int priority) { struct sk_buff *skb; - int len; unsigned char *bptr; + int len; - if (in_interrupt() && priority!=GFP_ATOMIC) - { + if (in_interrupt() && priority!=GFP_ATOMIC) { static int count = 0; if (++count < 5) { - printk(KERN_ERR "alloc_skb called nonatomically from interrupt %p\n", - __builtin_return_address(0)); + printk(KERN_ERR "alloc_skb called nonatomically " + "from interrupt %p\n", __builtin_return_address(0)); priority = GFP_ATOMIC; } } @@ -625,25 +132,23 @@ * 'alignment mask'. */ - size=(size+15)&~15; /* Allow for alignments. Make a multiple of 16 bytes */ + /* Allow for alignments. Make a multiple of 16 bytes */ + size = (size + 15) & ~15; len = size; - size+=sizeof(struct sk_buff); /* And stick the control itself on the end */ + /* And stick the control itself on the end */ + size += sizeof(struct sk_buff); /* * Allocate some space */ - bptr=(unsigned char *)kmalloc(size,priority); - if (bptr == NULL) - { + bptr = kmalloc(size,priority); + if (bptr == NULL) { atomic_inc(&net_fails); return NULL; } -#ifdef PARANOID_BUGHUNT_MODE - if(skb->magic_debug_cookie == SK_GOOD_SKB) - printk("Kernel kmalloc handed us an existing skb (%p)\n",skb); -#endif + /* * Now we play a little game with the caches. Linux kmalloc is * a bit cache dumb, in fact its just about maximally non @@ -653,7 +158,7 @@ */ atomic_inc(&net_allocs); - skb=(struct sk_buff *)(bptr+size)-1; + skb = (struct sk_buff *)(bptr + size) - 1; atomic_set(&skb->count, 1); /* only one reference to this */ skb->data_skb = skb; /* and we're our own data skb */ @@ -672,16 +177,14 @@ memset(skb->cb, 0, sizeof(skb->cb)); skb->priority = SOPRI_NORMAL; atomic_inc(&net_skbcount); -#if CONFIG_SKB_CHECK - skb->magic_debug_cookie = SK_GOOD_SKB; -#endif atomic_set(&skb->users, 1); - /* Load the data pointers */ - skb->head=bptr; - skb->data=bptr; - skb->tail=bptr; - skb->end=bptr+len; - skb->len=0; + + /* Load the data pointers. */ + skb->head = bptr; + skb->data = bptr; + skb->tail = bptr; + skb->end = bptr + len; + skb->len = 0; skb->inclone = 0; return skb; } @@ -705,10 +208,7 @@ /* don't do anything if somebody still uses us */ if (atomic_dec_and_test(&skb->count)) { - - int free_head; - - free_head = (skb->inclone != SKB_CLONE_INLINE); + int free_head = (skb->inclone != SKB_CLONE_INLINE); /* free the skb that contains the actual data if we've clone()'d */ if (skb->data_skb != skb) { @@ -730,16 +230,12 @@ struct sk_buff *n; int inbuff = 0; - IS_SKB(skb); - if (!skb->inclone && skb_tailroom(skb) >= sizeof(struct sk_buff)) - { + if (!skb->inclone && skb_tailroom(skb) >= sizeof(struct sk_buff)) { n = ((struct sk_buff *) skb->end) - 1; skb->end -= sizeof(struct sk_buff); skb->inclone = SKB_CLONE_ORIG; inbuff = SKB_CLONE_INLINE; - } - else - { + } else { n = kmalloc(sizeof(*n), priority); if (!n) return NULL; @@ -775,8 +271,6 @@ * Allocate the copy buffer */ - IS_SKB(skb); - n=alloc_skb(skb->end - skb->head, priority); if(n==NULL) return NULL; @@ -806,7 +300,6 @@ n->seq=skb->seq; n->end_seq=skb->end_seq; n->ack_seq=skb->ack_seq; - n->acked=skb->acked; memcpy(n->cb, skb->cb, sizeof(skb->cb)); n->used=skb->used; n->arp=skb->arp; @@ -816,7 +309,6 @@ n->stamp=skb->stamp; n->destructor = NULL; n->security=skb->security; - IS_SKB(n); return n; } @@ -830,8 +322,6 @@ * Allocate the copy buffer */ - IS_SKB(skb); - n=alloc_skb(skb->truesize+newheadroom-headroom-sizeof(struct sk_buff), GFP_ATOMIC); if(n==NULL) return NULL; @@ -862,7 +352,6 @@ n->seq=skb->seq; n->end_seq=skb->end_seq; n->ack_seq=skb->ack_seq; - n->acked=skb->acked; n->used=skb->used; n->arp=skb->arp; n->tries=0; @@ -872,7 +361,6 @@ n->destructor = NULL; n->security=skb->security; - IS_SKB(n); return n; } diff -u --recursive --new-file v2.1.35/linux/net/core/sock.c linux/net/core/sock.c --- v2.1.35/linux/net/core/sock.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/sock.c Tue Apr 22 22:46:27 1997 @@ -189,7 +189,7 @@ * is best */ - if(val > SK_WMEM_MAX*2 || val < 2048) + if(val > SK_WMEM_MAX*2) return -EINVAL; /* * Once this is all 32bit values we can @@ -197,7 +197,7 @@ */ if(val > 65535) return -EINVAL; - sk->sndbuf = val; + sk->sndbuf = max(val,2048); /* * Wake up sending tasks if we * upped the value. @@ -206,12 +206,12 @@ break; case SO_RCVBUF: - if(val > SK_RMEM_MAX*2 || val < 256) + if(val > SK_RMEM_MAX*2) return -EINVAL; /* Can go soon: FIXME */ if(val > 65535) return -EINVAL; - sk->rcvbuf = val; + sk->rcvbuf = max(val,256); break; case SO_KEEPALIVE: @@ -479,9 +479,6 @@ void sock_wfree(struct sk_buff *skb) { struct sock *sk = skb->sk; -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif #if 1 if (!sk) { printk(KERN_DEBUG "sock_wfree: sk==NULL\n"); @@ -497,9 +494,6 @@ void sock_rfree(struct sk_buff *skb) { struct sock *sk = skb->sk; -#if CONFIG_SKB_CHECK - IS_SKB(skb); -#endif #if 1 if (!sk) { printk(KERN_DEBUG "sock_rfree: sk==NULL\n"); diff -u --recursive --new-file v2.1.35/linux/net/ethernet/eth.c linux/net/ethernet/eth.c --- v2.1.35/linux/net/ethernet/eth.c Thu Mar 27 14:40:15 1997 +++ linux/net/ethernet/eth.c Tue Apr 22 22:46:27 1997 @@ -295,7 +295,6 @@ struct iphdr *iph; int ip_length; - IS_SKB(dest); eth=(struct ethhdr *)src; if(eth->h_proto!=htons(ETH_P_IP)) { diff -u --recursive --new-file v2.1.35/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.1.35/linux/net/ipv4/arp.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/arp.c Thu Apr 17 13:20:52 1997 @@ -230,13 +230,6 @@ int sysctl_arp_dead_res_time = ARP_DEAD_RES_TIME; -/* This should be completely nuked... -DaveM */ -#if RT_CACHE_DEBUG >= 1 -#define ASSERT_BH() if (!in_interrupt()) printk(KERN_CRIT __FUNCTION__ " called from SPL=0\n"); -#else -#define ASSERT_BH() -#endif - static void arp_neigh_destroy(struct neighbour *neigh); /* @@ -251,8 +244,8 @@ }; -static atomic_t arp_size = ATOMIC_INIT; -static atomic_t arp_unres_size = ATOMIC_INIT; +static atomic_t arp_size = ATOMIC_INIT(0); +static atomic_t arp_unres_size = ATOMIC_INIT(0); #ifdef CONFIG_ARPD static int arpd_not_running; @@ -340,12 +333,9 @@ { struct sk_buff *skb; - ASSERT_BH(); - /* Release the list of `skb' pointers. */ while ((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL) kfree_skb(skb, FREE_WRITE); - return; } static void arp_free(struct arp_table **entryp) @@ -353,8 +343,6 @@ struct arp_table *entry = *entryp; *entryp = entry->u.next; - ASSERT_BH(); - if (!(entry->flags&ATF_PUBL)) { atomic_dec(&arp_size); if (!(entry->flags&ATF_COM)) @@ -373,8 +361,6 @@ struct arp_table *entry = (struct arp_table*)neigh; struct hh_cache *hh, *next; - ASSERT_BH(); - del_timer(&entry->timer); arp_purge_send_q(entry); @@ -877,11 +863,8 @@ { struct sk_buff *skb; - ASSERT_BH(); - - while((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL) { + while((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL) dev_queue_xmit(skb); - } } diff -u --recursive --new-file v2.1.35/linux/net/ipv4/fib.c linux/net/ipv4/fib.c --- v2.1.35/linux/net/ipv4/fib.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/fib.c Thu Apr 17 13:20:52 1997 @@ -117,7 +117,7 @@ */ static struct wait_queue *fib_wait; -static atomic_t fib_users = ATOMIC_INIT; +static atomic_t fib_users = ATOMIC_INIT(0); static void fib_lock(void) { diff -u --recursive --new-file v2.1.35/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c --- v2.1.35/linux/net/ipv4/icmp.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/icmp.c Tue Apr 22 22:46:27 1997 @@ -754,7 +754,7 @@ if(__ip_chk_addr(iph->daddr)==IS_BROADCAST) { printk("%s sent an invalid ICMP error to a broadcast.\n", - in_ntoa(iph->daddr)); + in_ntoa(skb->nh.iph->saddr)); kfree_skb(skb, FREE_READ); } diff -u --recursive --new-file v2.1.35/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c --- v2.1.35/linux/net/ipv4/ip_fragment.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/ip_fragment.c Tue Apr 22 22:46:27 1997 @@ -46,7 +46,7 @@ static struct ipq *ipqueue = NULL; /* IP fragment queue */ -atomic_t ip_frag_mem = ATOMIC_INIT; /* Memory used for fragments */ +atomic_t ip_frag_mem = ATOMIC_INIT(0); /* Memory used for fragments */ char *in_ntoa(unsigned long in); @@ -177,7 +177,6 @@ while (fp != NULL) { xp = fp->next; - IS_SKB(fp->skb); frag_kfree_skb(fp->skb,FREE_READ); frag_kfree_s(fp, sizeof(struct ipfrag)); fp = xp; diff -u --recursive --new-file v2.1.35/linux/net/ipv4/ip_sockglue.c linux/net/ipv4/ip_sockglue.c --- v2.1.35/linux/net/ipv4/ip_sockglue.c Tue Mar 4 10:25:27 1997 +++ linux/net/ipv4/ip_sockglue.c Tue Apr 22 22:46:27 1997 @@ -296,10 +296,8 @@ if (sk->ip_recverr && !val) { struct sk_buff *skb; /* Drain queued errors */ - while((skb=skb_dequeue(&sk->error_queue))!=NULL) { - IS_SKB(skb); + while((skb=skb_dequeue(&sk->error_queue))!=NULL) kfree_skb(skb, FREE_READ); - } } sk->ip_recverr = val?1:0; release_sock(sk); diff -u --recursive --new-file v2.1.35/linux/net/ipv4/proc.c linux/net/ipv4/proc.c --- v2.1.35/linux/net/ipv4/proc.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/proc.c Tue Apr 22 22:46:27 1997 @@ -124,7 +124,7 @@ format==0?sp->write_seq-tp->snd_una:atomic_read(&sp->wmem_alloc), format==0?tp->rcv_nxt-sp->copied_seq:atomic_read(&sp->rmem_alloc), timer_active, timer_expires-jiffies, - (unsigned) atomic_read(&sp->retransmits), + tp->retransmits, sp->socket ? sp->socket->inode->i_uid:0, timer_active?sp->timeout:0, sp->socket ? sp->socket->inode->i_ino:0); diff -u --recursive --new-file v2.1.35/linux/net/ipv4/route.c linux/net/ipv4/route.c --- v2.1.35/linux/net/ipv4/route.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/route.c Thu Apr 17 13:20:52 1997 @@ -111,7 +111,7 @@ * Route cache. */ -static atomic_t rt_cache_size = ATOMIC_INIT; +static atomic_t rt_cache_size = ATOMIC_INIT(0); static struct rtable *rt_hash_table[RT_HASH_DIVISOR]; static struct rtable * rt_intern_hash(unsigned hash, struct rtable * rth, u16 protocol); diff -u --recursive --new-file v2.1.35/linux/net/ipv4/sysctl_net_ipv4.c linux/net/ipv4/sysctl_net_ipv4.c --- v2.1.35/linux/net/ipv4/sysctl_net_ipv4.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/sysctl_net_ipv4.c Tue Apr 22 22:46:27 1997 @@ -36,6 +36,12 @@ 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); @@ -80,6 +86,21 @@ &proc_dointvec}, {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, diff -u --recursive --new-file v2.1.35/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- v2.1.35/linux/net/ipv4/tcp.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp.c Tue Apr 22 22:46:27 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.55 1997/04/13 10:31:45 davem Exp $ + * Version: $Id: tcp.c,v 1.61 1997/04/22 02:53:10 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -444,15 +444,14 @@ { struct open_request *req = tp->syn_wait_queue; - if (!req) - return NULL; - do { + while(req) { if (req->sk && (req->sk->state == TCP_ESTABLISHED || req->sk->state >= TCP_FIN_WAIT1)) - return req; - } while ((req = req->dl_next) != tp->syn_wait_queue); - return NULL; + break; + req = req->dl_next; + } + return req; } /* @@ -466,9 +465,7 @@ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct open_request *req = tp->syn_wait_queue; - if (!req) - return; - do { + while(req) { struct open_request *iter; if (req->sk) @@ -481,9 +478,10 @@ tcp_dec_slow_timer(TCP_SLT_SYNACK); sk->ack_backlog--; tcp_openreq_free(iter); - } while (req != tp->syn_wait_queue); + } tp->syn_wait_queue = NULL; + tp->syn_wait_last = &tp->syn_wait_queue; } /* @@ -518,8 +516,7 @@ save_flags(flags); cli(); - if (sk == NULL || (skb = skb_peek(&sk->receive_queue)) == NULL) - { + if (sk == NULL || (skb = skb_peek(&sk->receive_queue)) == NULL) { restore_flags(flags); SOCK_DEBUG(sk, "empty\n"); return(0); @@ -528,32 +525,27 @@ counted = sk->copied_seq; /* Where we are at the moment */ amount = 0; - /* - * Do until a push or until we are out of data. - */ - - do - { - /* Found a hole so stops here */ + /* Do until a push or until we are out of data. */ + do { + /* Found a hole so stops here. */ if (before(counted, skb->seq)) break; - /* - * Length - header but start from where we are up to - * avoid overlaps + + /* Length - header but start from where we are up to + * avoid overlaps. */ - sum = skb->len - (counted - skb->seq); + sum = skb->len - (counted - skb->seq); if (skb->h.th->syn) sum++; - if (sum > 0) - { - /* Add it up, move on */ + if (sum > 0) { + /* Add it up, move on. */ amount += sum; if (skb->h.th->syn) amount--; counted += sum; } - /* - * Don't count urg data ... but do it in the right place! + + /* Don't count urg data ... but do it in the right place! * Consider: "old_data (ptr is here) URG PUSH data" * The old code would stop at the first push because * it counted the urg (amount==1) and then does amount-- @@ -569,15 +561,14 @@ * was correct. Mike */ - /* don't count urg data */ + /* Don't count urg data. */ if (skb->h.th->urg) amount--; #if 0 if (amount && skb->h.th->psh) break; #endif skb = skb->next; - } - while(skb != (struct sk_buff *)&sk->receive_queue); + } while(skb != (struct sk_buff *)&sk->receive_queue); restore_flags(flags); SOCK_DEBUG(sk, "got %lu bytes.\n",amount); @@ -619,18 +610,20 @@ mask = 0; if (sk->err) mask = POLLERR; - /* connected ? */ + /* Connected? */ if (sk->state != TCP_SYN_SENT && sk->state != TCP_SYN_RECV) { - if (sk->shutdown & RCV_SHUTDOWN) mask |= POLLHUP; - + if ((tp->rcv_nxt != sk->copied_seq) && (sk->urg_seq != sk->copied_seq || tp->rcv_nxt != sk->copied_seq+1 || sk->urginline || !sk->urg_data)) mask |= POLLIN | POLLRDNORM; + /* FIXME: this assumed sk->mtu is correctly maintained. + * I see no evidence this is the case. -- erics + */ if (!(sk->shutdown & SEND_SHUTDOWN) && (sock_wspace(sk) >= sk->mtu+128+sk->prot->max_header)) mask |= POLLOUT | POLLWRNORM; @@ -643,9 +636,7 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) { - switch(cmd) - { - + switch(cmd) { case TIOCINQ: #ifdef FIXME /* FIXME: */ case FIONREAD: @@ -676,28 +667,39 @@ } default: return(-EINVAL); - } + }; } /* * This routine builds a generic TCP header. + * It also builds in the RFC1323 Timestamp. + * It can't (unfortunately) do SACK as well. */ -extern __inline int tcp_build_header(struct tcphdr *th, struct sock *sk, int push) +extern __inline void tcp_build_header(struct tcphdr *th, struct sock *sk, int push) { - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + memcpy(th,(void *) &(sk->dummy_th), sizeof(*th)); th->seq = htonl(sk->write_seq); - th->psh =(push == 0) ? 1 : 0; - - sk->bytes_rcv = 0; - sk->ack_timed = 0; th->ack_seq = htonl(tp->rcv_nxt); th->window = htons(tcp_select_window(sk)); - return(sizeof(*th)); + /* FIXME: could use the inline found in tcp_output.c as well. + * Probably that means we should move these up to an include file. --erics + */ + if (tp->tstamp_ok) { + __u32 *ptr = (__u32 *)(th+1); + *ptr++ = ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + /* FIXME: Not sure it's worth setting these here already, but I'm + * also not sure we replace them on all paths later. --erics + */ + *ptr++ = jiffies; + *ptr++ = tp->ts_recent; + } } /* @@ -708,9 +710,7 @@ release_sock(sk); cli(); if (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT && sk->err == 0) - { interruptible_sleep_on(sk->sleep); - } sti(); lock_sock(sk); } @@ -756,22 +756,15 @@ int fault; int copy; - /* - * Add more stuff to the end - * of the skb - */ - + /* Add more stuff to the end of the skb. */ copy = min(sk->mss - tcp_size, skb_tailroom(skb)); copy = min(copy, seglen); tcp_size += copy; fault = copy_from_user(skb->tail, from, copy); - if (fault) - { return -1; - } skb_put(skb, copy); skb->csum = csum_partial(skb->tail - tcp_size, tcp_size, 0); @@ -793,19 +786,12 @@ int copied = 0; struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); - /* - * Wait for a connection to finish. - */ - while (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT) - { - if (copied) - return copied; - + /* Wait for a connection to finish. */ + while (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT) { if (sk->err) return sock_error(sk); - if (sk->state != TCP_SYN_SENT && sk->state != TCP_SYN_RECV) - { + if (sk->state != TCP_SYN_SENT && sk->state != TCP_SYN_RECV) { if (sk->keepopen) send_sig(SIGPIPE, current, 0); return -EPIPE; @@ -820,19 +806,14 @@ wait_for_tcp_connect(sk); } - /* - * Ok commence sending - */ - - while(--iovlen >= 0) - { + /* Ok commence sending. */ + while(--iovlen >= 0) { int seglen=iov->iov_len; unsigned char * from=iov->iov_base; iov++; - while(seglen > 0) - { + while(seglen > 0) { unsigned int actual_win; int copy; int tmp; @@ -840,142 +821,110 @@ 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) && atomic_read(&sk->packets_out)) - { - tmp += min(sk->mss, sk->max_window); - } + if (copy < min(sk->mss, tp->max_window >> 1) && + !(flags & MSG_OOB) && tp->packets_out) + tmp += min(sk->mss, tp->max_window); else - { tmp += copy; - } skb = sock_wmalloc(sk, tmp, 0, GFP_KERNEL); - /* - * If we didn't get any memory, we need to sleep. - */ - - if (skb == NULL) - { + /* If we didn't get any memory, we need to sleep. */ + if (skb == NULL) { sk->socket->flags |= SO_NOSPACE; - if (flags&MSG_DONTWAIT) - { + if (flags&MSG_DONTWAIT) { if (copied) return copied; return -EAGAIN; } - if (current->signal & ~current->blocked) - { + if (current->signal & ~current->blocked) { if (copied) return copied; return -ERESTARTSYS; @@ -985,37 +934,25 @@ 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); + tcp_build_header(skb->h.th, sk, seglen || iovlen); + /* FIXME: still need to think about SACK options here. */ - if (tmp < 0) - { - kfree_skb(skb, FREE_WRITE); - if (copied) - return(copied); - return(tmp); - } - - if (flags & MSG_OOB) - { + if (flags & MSG_OOB) { skb->h.th->urg = 1; skb->h.th->urg_ptr = ntohs(copy); } @@ -1027,7 +964,7 @@ copied += copy; sk->write_seq += copy; - + tcp_send_skb(sk, skb); release_sock(sk); @@ -1043,9 +980,6 @@ return copied; } - - - /* * Send an ack if one is backlogged at this point. Ought to merge * this with tcp_send_ack(). @@ -1054,18 +988,15 @@ void tcp_read_wakeup(struct sock *sk) { - /* - * If we're closed, don't send an ack, or we'll get a RST + /* If we're closed, don't send an ack, or we'll get a RST * from the closed destination. */ - if ((sk->state == TCP_CLOSE) || (sk->state == TCP_TIME_WAIT)) return; tcp_send_ack(sk); } - /* * Handle reading urgent data. BSD has very simple semantics for * this, no blocking and very strange errors 8) @@ -1078,33 +1009,28 @@ int err=0; struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * No URG data to read - */ + /* No URG data to read. */ if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ) return -EINVAL; /* Yes this is right ! */ if (sk->err) return sock_error(sk); - if (sk->state == TCP_CLOSE || sk->done) - { - if (!sk->done) - { + if (sk->state == TCP_CLOSE || sk->done) { + if (!sk->done) { sk->done = 1; return 0; } return -ENOTCONN; } - if (sk->shutdown & RCV_SHUTDOWN) - { + if (sk->shutdown & RCV_SHUTDOWN) { sk->done = 1; return 0; } + lock_sock(sk); - if (sk->urg_data & URG_VALID) - { + if (sk->urg_data & URG_VALID) { char c = sk->urg_data; if (!(flags & MSG_PEEK)) sk->urg_data = URG_READ; @@ -1115,23 +1041,20 @@ msg->msg_flags|=MSG_TRUNC; if(msg->msg_name) - { tp->af_specific->addr2sockaddr(sk, (struct sockaddr *) msg->msg_name); - } + if(addr_len) *addr_len = tp->af_specific->sockaddr_len; - /* - * Read urgent data - */ + + /* Read urgent data. */ msg->msg_flags|=MSG_OOB; release_sock(sk); return err ? -EFAULT : 1; } release_sock(sk); - /* - * Fixed the recv(..., MSG_OOB) behaviour. BSD docs and + /* Fixed the recv(..., MSG_OOB) behaviour. BSD docs and * the available implementations agree in this case: * this call should never block, independent of the * blocking state of the socket. @@ -1148,7 +1071,7 @@ static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb) { - sk->delayed_acks++; + sk->tp_pinfo.af_tcp.delayed_acks++; __skb_unlink(skb, &sk->receive_queue); kfree_skb(skb, FREE_READ); @@ -1159,11 +1082,9 @@ { struct sk_buff *skb; - /* - * NOTE! The socket must be locked, so that we don't get + /* NOTE! The socket must be locked, so that we don't get * a messed-up receive queue. */ - while ((skb=skb_peek(&sk->receive_queue)) != NULL) { if (!skb->used || atomic_read(&skb->users)>1) break; @@ -1172,13 +1093,10 @@ SOCK_DEBUG(sk, "sk->rspace = %lu\n", sock_rspace(sk)); - /* - * We send a ACK if the sender is blocked - * else let tcp_data deal with the acking policy. + /* We send a ACK if the sender is blocked + * else let tcp_data deal with the acking policy. */ - - if (sk->delayed_acks) - { + if (sk->tp_pinfo.af_tcp.delayed_acks) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); __u32 rcv_wnd; @@ -1209,47 +1127,34 @@ if (sk->state == TCP_LISTEN) return -ENOTCONN; - /* - * Urgent data needs to be handled specially. - */ - + /* Urgent data needs to be handled specially. */ if (flags & MSG_OOB) return tcp_recv_urg(sk, nonblock, msg, len, flags, addr_len); - /* - * Copying sequence to update. This is volatile to handle + /* Copying sequence to update. This is volatile to handle * the multi-reader case neatly (memcpy_to/fromfs might be * inline and thus not flush cached variables otherwise). */ - peek_seq = sk->copied_seq; seq = &sk->copied_seq; if (flags & MSG_PEEK) seq = &peek_seq; - /* - * Handle the POSIX bogosity MSG_WAITALL - */ - + /* Handle the POSIX bogosity MSG_WAITALL. */ if (flags & MSG_WAITALL) target=len; add_wait_queue(sk->sleep, &wait); lock_sock(sk); - while (len > 0) - { + while (len > 0) { struct sk_buff * skb; u32 offset; - /* - * Are we at urgent data? Stop if we have read anything. - */ - + /* Are we at urgent data? Stop if we have read anything. */ if (copied && sk->urg_data && sk->urg_seq == *seq) break; - /* - * We need to check signals first, to get correct SIGURG + /* We need to check signals first, to get correct SIGURG * handling. FIXME: Need to check this doesnt impact 1003.1g * and move it down to the bottom of the loop */ @@ -1262,20 +1167,16 @@ break; } - /* - * Next get a buffer. - */ - + /* Next get a buffer. */ current->state = TASK_INTERRUPTIBLE; skb = skb_peek(&sk->receive_queue); - do - { + do { if (!skb) break; - /* - * now that we have two receive queues this - * shouldn't happen + + /* Now that we have two receive queues this + * shouldn't happen. */ if (before(*seq, skb->seq)) { printk(KERN_INFO "recvmsg bug: copied %X seq %X\n", @@ -1292,22 +1193,18 @@ if (!(flags & MSG_PEEK)) skb->used = 1; skb = skb->next; - } - while (skb != (struct sk_buff *)&sk->receive_queue); + } while (skb != (struct sk_buff *)&sk->receive_queue); if (copied >= target) break; - if (sk->err && !(flags&MSG_PEEK)) - { + if (sk->err && !(flags&MSG_PEEK)) { copied = sock_error(sk); break; } - if (sk->state == TCP_CLOSE) - { - if (!sk->done) - { + if (sk->state == TCP_CLOSE) { + if (!sk->done) { sk->done = 1; break; } @@ -1315,14 +1212,12 @@ break; } - if (sk->shutdown & RCV_SHUTDOWN) - { + if (sk->shutdown & RCV_SHUTDOWN) { sk->done = 1; break; } - if (nonblock) - { + if (nonblock) { copied = -EAGAIN; break; } @@ -1336,65 +1231,46 @@ continue; found_ok_skb: - /* - * Lock the buffer. We can be fairly relaxed as + /* Lock the buffer. We can be fairly relaxed as * an interrupt will never steal a buffer we are * using unless I've missed something serious in * tcp_data. */ - atomic_inc(&skb->users); - /* - * Ok so how much can we use ? - */ - + /* Ok so how much can we use? */ used = skb->len - offset; if (len < used) used = len; - /* - * Do we have urgent data here? - */ - if (sk->urg_data) - { + /* Do we have urgent data here? */ + if (sk->urg_data) { u32 urg_offset = sk->urg_seq - *seq; - if (urg_offset < used) - { - if (!urg_offset) - { - if (!sk->urginline) - { + if (urg_offset < used) { + if (!urg_offset) { + if (!sk->urginline) { ++*seq; offset++; used--; } - } - else + } else used = urg_offset; } } - /* - * Copy it - We _MUST_ update *seq first so that we + /* Copy it - We _MUST_ update *seq first so that we * don't ever double read when we have dual readers */ - *seq += used; - /* - * This memcpy_toiovec can sleep. If it sleeps and we + /* This memcpy_toiovec can sleep. If it sleeps and we * do a second read it relies on the skb->users to avoid * a crash when cleanup_rbuf() gets called. */ - err = memcpy_toiovec(msg->msg_iov, ((unsigned char *)skb->h.th) + skb->h.th->doff*4 + offset, used); - if (err) - { - /* - * exception. bailout! - */ + if (err) { + /* Exception. Bailout! */ *seq -= err; atomic_dec(&skb->users); copied = -EFAULT; @@ -1404,12 +1280,10 @@ copied += used; len -= used; - /* - * We now will not sleep again until we are finished + /* We now will not sleep again until we are finished * with skb. Sorry if you are doing the SMP port * but you'll just have to fix it neatly ;) */ - atomic_dec(&skb->users); if (after(sk->copied_seq,sk->urg_seq)) @@ -1417,11 +1291,9 @@ if (used + offset < skb->len) continue; - /* - * Process the FIN. We may also need to handle PSH - * here and make it break out of MSG_WAITALL + /* Process the FIN. We may also need to handle PSH + * here and make it break out of MSG_WAITALL. */ - if (skb->h.th->fin) goto found_fin_ok; if (flags & MSG_PEEK) @@ -1436,35 +1308,28 @@ if (flags & MSG_PEEK) break; - /* - * All is done - */ - + /* All is done. */ skb->used = 1; sk->shutdown |= RCV_SHUTDOWN; break; - } if(copied > 0 && msg->msg_name) - { tp->af_specific->addr2sockaddr(sk, (struct sockaddr *) msg->msg_name); - } + if(addr_len) *addr_len = tp->af_specific->sockaddr_len; remove_wait_queue(sk->sleep, &wait); current->state = TASK_RUNNING; - /* Clean up data we have read: This will do ACK frames */ + /* Clean up data we have read: This will do ACK frames. */ cleanup_rbuf(sk); release_sock(sk); return copied; } - - /* * State processing on a close. This implements the state shift for * sending our FIN frame. Note that we only send a FIN for some @@ -1476,8 +1341,7 @@ { int ns=TCP_CLOSE; int send_fin=0; - switch(sk->state) - { + switch(sk->state) { case TCP_SYN_SENT: /* No SYN back, no FIN needed */ break; case TCP_SYN_RECV: @@ -1498,12 +1362,11 @@ wait only for the ACK */ ns=TCP_LAST_ACK; send_fin=1; - } + }; tcp_set_state(sk,ns); - /* - * This is a (useful) BSD violating of the RFC. There is a + /* This is a (useful) BSD violating of the RFC. There is a * problem with TCP as specified in that the other end could * keep a socket open forever with no application left this end. * We use a 3 minute timeout (about the same as BSD) then kill @@ -1511,8 +1374,7 @@ * that we won't make the old 4*rto = almost no time - whoops * reset mistake. */ - if(dead && ns==TCP_FIN_WAIT2) - { + if(dead && ns==TCP_FIN_WAIT2) { int timer_active=del_timer(&sk->timer); if(timer_active) add_timer(&sk->timer); @@ -1530,50 +1392,29 @@ void tcp_shutdown(struct sock *sk, int how) { - /* - * We need to grab some memory, and put together a FIN, + /* We need to grab some memory, and put together a FIN, * and then put it into the queue to be sent. * Tim MacKenzie(tym@dibbler.cs.monash.edu.au) 4 Dec '92. */ - if (!(how & SEND_SHUTDOWN)) return; - /* - * If we've already sent a FIN, or it's a closed state - */ - - if (sk->state == TCP_FIN_WAIT1 || - sk->state == TCP_FIN_WAIT2 || - sk->state == TCP_CLOSING || - sk->state == TCP_LAST_ACK || - sk->state == TCP_TIME_WAIT || - sk->state == TCP_CLOSE || - sk->state == TCP_LISTEN - ) - { - return; - } - lock_sock(sk); - - /* - * flag that the sender has shutdown - */ - - sk->shutdown |= SEND_SHUTDOWN; - - /* - * Clear out any half completed packets. - */ + /* If we've already sent a FIN, or it's a closed state, skip this. */ + if (sk->state == TCP_ESTABLISHED || + sk->state == TCP_SYN_SENT || + sk->state == TCP_SYN_RECV || + sk->state == TCP_CLOSE_WAIT) { + lock_sock(sk); - /* - * FIN if needed - */ + /* Flag that the sender has shutdown. */ + sk->shutdown |= SEND_SHUTDOWN; - if (tcp_close_state(sk,0)) - tcp_send_fin(sk); + /* Clear out any half completed packets. FIN if needed. */ + if (tcp_close_state(sk,0)) + tcp_send_fin(sk); - release_sock(sk); + release_sock(sk); + } } @@ -1588,7 +1429,7 @@ case TCP_CLOSING: case TCP_LAST_ACK: return 1; - } + }; return 0; } @@ -1597,16 +1438,12 @@ { struct sk_buff *skb; - /* - * We need to grab some memory, and put together a FIN, + /* We need to grab some memory, and put together a FIN, * and then put it into the queue to be sent. */ - lock_sock(sk); - - if(sk->state == TCP_LISTEN) - { - /* Special case */ + if(sk->state == TCP_LISTEN) { + /* Special case. */ tcp_set_state(sk, TCP_CLOSE); tcp_close_pending(sk); release_sock(sk); @@ -1621,37 +1458,27 @@ if (!sk->dead) sk->state_change(sk); - /* - * We need to flush the recv. buffs. We do this only on the + /* We need to flush the recv. buffs. We do this only on the * descriptor close, not protocol-sourced closes, because the * reader process may not have drained the data yet! */ - while((skb=skb_dequeue(&sk->receive_queue))!=NULL) kfree_skb(skb, FREE_READ); - - /* - * Timeout is not the same thing - however the code likes - * to send both the same way (sigh). + /* Timeout is not the same thing - however the code likes + * to send both the same way (sigh). */ - if (tcp_close_state(sk,1)==1) - { tcp_send_fin(sk); - } if (timeout) { cli(); release_sock(sk); current->timeout = timeout; - while(closing(sk) && current->timeout) - { + while(closing(sk) && current->timeout) { interruptible_sleep_on(sk->sleep); if (current->signal & ~current->blocked) - { break; - } } current->timeout=0; lock_sock(sk); @@ -1661,8 +1488,7 @@ /* Now that the socket is dead, if we are in the FIN_WAIT2 state * we may need to set up a timer. */ - if (sk->state==TCP_FIN_WAIT2) - { + if (sk->state==TCP_FIN_WAIT2) { int timer_active=del_timer(&sk->timer); if(timer_active) add_timer(&sk->timer); @@ -1677,7 +1503,6 @@ sk->prot->unhash(sk); } - /* * Wait for an incoming connection, avoid race * conditions. This must be called with the socket locked. @@ -1703,7 +1528,6 @@ return req; } - /* * This will accept the next outstanding connection. * @@ -1751,7 +1575,6 @@ goto out; } - /* * Socket option code for TCP. */ @@ -1772,11 +1595,9 @@ if (get_user(val, (int *)optval)) return -EFAULT; - switch(optname) - { + switch(optname) { case TCP_MAXSEG: -/* - * values greater than interface MTU won't take effect. however at +/* values greater than interface MTU won't take effect. however at * the point when this call is done we typically don't yet know * which interface is going to be used */ @@ -1789,7 +1610,7 @@ return 0; default: return(-ENOPROTOOPT); - } + }; } int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, @@ -1800,18 +1621,15 @@ int len; if(level != SOL_TCP) - { return tp->af_specific->getsockopt(sk, level, optname, optval, optlen); - } if(get_user(len,optlen)) return -EFAULT; - len=min(len,sizeof(int)); + len = min(len,sizeof(int)); - switch(optname) - { + switch(optname) { case TCP_MAXSEG: val=sk->user_mss; break; @@ -1820,7 +1638,7 @@ break; default: return(-ENOPROTOOPT); - } + }; if(put_user(len, optlen)) return -EFAULT; @@ -1832,13 +1650,9 @@ void tcp_set_keepalive(struct sock *sk, int val) { if (!sk->keepopen && val) - { tcp_inc_slow_timer(TCP_SLT_KEEPALIVE); - } else if (sk->keepopen && !val) - { tcp_dec_slow_timer(TCP_SLT_KEEPALIVE); - } } void tcp_init(void) diff -u --recursive --new-file v2.1.35/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c --- v2.1.35/linux/net/ipv4/tcp_input.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_input.c Tue Apr 22 22:46:28 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.42 1997/04/12 04:32:24 davem Exp $ + * Version: $Id: tcp_input.c,v 1.50 1997/04/22 02:53:12 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -57,6 +57,12 @@ u32 seq_rtt); int sysctl_tcp_cong_avoidance = 0; +int sysctl_tcp_hoe_retransmits = 0; +int sysctl_tcp_sack = 0; +int sysctl_tcp_tsack = 0; +int sysctl_tcp_timestamps = 0; +int sysctl_tcp_window_scaling = 0; + static tcp_sys_cong_ctl_t tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj; @@ -72,9 +78,7 @@ { int m; - /* - * Delayed ACK time estimator. - */ + /* Delayed ACK time estimator. */ m = jiffies - tp->lrcvtime; @@ -83,12 +87,10 @@ if (m < 0) return; - /* - * if the mesured value is bigger than + /* if the mesured value is bigger than * twice the round trip time ignore it. */ - if ((m << 2) <= tp->srtt) - { + if ((m << 2) <= tp->srtt) { m -= (tp->iat >> 3); tp->iat += m; @@ -102,18 +104,21 @@ if (tp->ato < HZ/50) tp->ato = HZ/50; - } - else + } else tp->ato = 0; } -/* - * Called on frames that were known _not_ to have been - * retransmitted [see Karn/Partridge Proceedings SIGCOMM 87]. - * The algorithm is from the SIGCOMM 88 piece by Van Jacobson. +/* Called to compute a smoothed rtt estimate. The data fed to this + * routine either comes from timestamps, or from segments that were + * known _not_ to have been retransmitted [see Karn/Partridge + * Proceedings SIGCOMM 87]. The algorithm is from the SIGCOMM 88 + * piece by Van Jacobson. + * NOTE: the next three routines used to be one big routine. + * To save cycles in the RFC 1323 implementation it was better to break + * it up into three procedures. -- erics */ -extern __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) +static __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) { long m; /* @@ -122,8 +127,7 @@ * are scaled versions of rtt and mean deviation. * This is designed to be as fast as possible * m stands for "measurement". - */ - /* + * * On a 1990 paper the rto value is changed to: * RTO = rtt + 4 * mdev */ @@ -140,44 +144,73 @@ 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; + u32 end_window = tp->rcv_wup + tp->rcv_wnd; - end_window = tp->rcv_wup + tp->rcv_wnd; - - if (tp->rcv_wnd) - { + if (tp->rcv_wnd) { if (!before(seq, tp->rcv_nxt) && before(seq, end_window)) return 1; @@ -196,9 +229,8 @@ extern __inline__ int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) { if (seq == tp->rcv_nxt) - { return (tp->rcv_wnd || (end_seq == seq)); - } + return __tcp_sequence(tp, seq, end_seq); } @@ -210,9 +242,8 @@ static int tcp_reset(struct sock *sk, struct sk_buff *skb) { sk->zapped = 1; - /* - * We want the right error as BSD sees it (and indeed as we do). - */ + + /* We want the right error as BSD sees it (and indeed as we do). */ switch (sk->state) { case TCP_TIME_WAIT: break; @@ -224,7 +255,7 @@ break; default: sk->err = ECONNRESET; - } + }; #ifdef CONFIG_TCP_RFC1337 /* * Time wait assassination protection [RFC1337] @@ -234,8 +265,7 @@ * Ian Heavens has since shown this is an inadequate fix for the protocol * bug in question. */ - if(sk->state!=TCP_TIME_WAIT) - { + if(sk->state!=TCP_TIME_WAIT) { tcp_set_state(sk,TCP_CLOSE); sk->shutdown = SHUTDOWN_MASK; } @@ -249,34 +279,30 @@ return(0); } - /* - * Look for tcp options. Parses everything but only knows about MSS. - * This routine is always called with the packet containing the SYN. - * However it may also be called with the ack to the SYN. So you - * can't assume this is always the SYN. It's always called after - * we have set up sk->mtu to our own MTU. - * - * We need at minimum to add PAWS support here. Possibly large windows - * as Linux gets deployed on 100Mb/sec networks. + * Look for tcp options. Normally only called on SYN and SYNACK packets. + * But, this can also be called on packets in the established flow when + * the fast version below fails. + * FIXME: surely this can be more efficient. -- erics */ -int tcp_parse_options(struct tcphdr *th) +void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp) { unsigned char *ptr; int length=(th->doff*4)-sizeof(struct tcphdr); - int mss = 0; ptr = (unsigned char *)(th + 1); + tp->sacks = 0; + tp->saw_tstamp = 0; - while(length>0) - { + while(length>0) { int opcode=*ptr++; int opsize=*ptr++; - switch(opcode) - { + if (length - opsize < 0) /* Don't parse partial options */ + break; + switch(opcode) { case TCPOPT_EOL: - return 0; + return; case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ length--; ptr--; /* the opsize=*ptr++ above was a mistake */ @@ -284,25 +310,86 @@ default: if(opsize<=2) /* Avoid silly options looping forever */ - return 0; - switch(opcode) - { + return; + switch(opcode) { case TCPOPT_MSS: - if(opsize==TCPOLEN_MSS && th->syn) - { - mss = ntohs(*(unsigned short *)ptr); - } + if(opsize==TCPOLEN_MSS && th->syn) { + tp->in_mss = ntohs(*(__u16 *)ptr); + if (tp->in_mss == 0) + tp->in_mss = 536; + } break; - /* Add other options here as people feel the urge to implement stuff like large windows */ + case TCPOPT_WINDOW: + if(opsize==TCPOLEN_WINDOW && th->syn) + if (sysctl_tcp_window_scaling) + tp->snd_wscale = *(__u8 *)ptr; + break; + case TCPOPT_SACK_PERM: + if(opsize==TCPOLEN_SACK_PERM && th->syn) + if (sysctl_tcp_sack) + tp->sack_ok = 1; + case TCPOPT_TIMESTAMP: + if(opsize==TCPOLEN_TIMESTAMP) { + /* Cheaper to set again then to + * test syn. Optimize this? + */ + if (sysctl_tcp_timestamps) + tp->tstamp_ok = 1; + tp->saw_tstamp = 1; + tp->rcv_tsval = ntohl(*(__u32 *)ptr); + tp->rcv_tsecr = ntohl(*(__u32 *)(ptr+4)); + } + break; + case TCPOPT_SACK: + tp->sacks = (opsize-2)>>3; + if (tp->sacks<<3 == opsize-2) { + int i; + for (i = 0; i < tp->sacks; i++) { + tp->left_sack[i] = ntohl(((__u32 *)ptr)[2*i]); + tp->right_sack[i] = ntohl(((__u32 *)ptr)[2*i+1]); + } + } else + tp->sacks = 0; } ptr+=opsize-2; length-=opsize; - } + }; } +} - return mss; +/* Fast parse options. This hopes to only see timestamps. + * If it is wrong it falls back on tcp_parse_option(). + * This should probably get extended for timestamps + SACK as well. + * Assembly code anyone? -- erics + */ +static __inline__ int tcp_fast_parse_options(struct tcphdr *th, struct tcp_opt *tp) +{ + if (tp->tcp_header_len == sizeof(struct tcphdr)) + return 0; + if (th->doff == sizeof(struct tcphdr)>>2) { + tp->saw_tstamp = 0; + tp->sacks = 0; + return 0; + } else if (th->doff == (sizeof(struct tcphdr)>>2)+3) { + __u32 *ptr = (__u32 *)(th + 1); + if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) { + tp->saw_tstamp = 1; + tp->sacks = 0; + tp->rcv_tsval = ntohl(*++ptr); + tp->rcv_tsecr = ntohl(*++ptr); + return 1; + } + } + tcp_parse_options(th,tp); + return 1; } +#if 0 + +/* + * This is the old fast retransmit code. It will go away eventually. -- erics + */ /* * See draft-stevens-tcpca-spec-01 for documentation. @@ -332,62 +419,170 @@ * The packet acked data after high_seq; */ - if (ack == tp->snd_una && atomic_read(&sk->packets_out) && (not_dup == 0)) - { - /* - * 1. When the third duplicate ack is received, set ssthresh - * to one half the current congestion window, but no less - * than two segments. Retransmit the missing segment. + if (ack == tp->snd_una && tp->packets_out && (not_dup == 0)) { + /* 1. When the third duplicate ack is received, set ssthresh + * to one half the current congestion window, but no less + * than two segments. Retransmit the missing segment. */ + if (tp->high_seq == 0 || after(ack, tp->high_seq)) { + tp->dup_acks++; - if (tp->high_seq == 0 || after(ack, tp->high_seq)) - { - sk->dup_acks++; - - if (sk->dup_acks == 3) - { - sk->ssthresh = max(tp->snd_cwnd >> 1, 2); - tp->snd_cwnd = sk->ssthresh + 3; + if (tp->dup_acks == 3) { + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd = tp->snd_ssthresh + 3; tcp_do_retransmit(sk, 0); - /* careful not to timeout just after fast + + /* Careful not to timeout just after fast * retransmit! */ - tcp_reset_xmit_timer(sk, TIME_RETRANS, - tp->rto); + tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); } } - /* - * 2. Each time another duplicate ACK arrives, increment - * cwnd by the segment size. [...] Transmit a packet... + /* 2. Each time another duplicate ACK arrives, increment + * cwnd by the segment size. [...] Transmit a packet... * - * Packet transmission will be done on normal flow processing - * since we're not in "retransmit mode" + * Packet transmission will be done on normal flow processing + * since we're not in "retransmit mode". */ - - if (sk->dup_acks >= 3) - { - sk->dup_acks++; + if (tp->dup_acks >= 3) { + tp->dup_acks++; tp->snd_cwnd++; } - } - else - { - /* - * 3. When the next ACK arrives that acknowledges new data, - * set cwnd to ssthresh + } else { + /* 3. When the next ACK arrives that acknowledges new data, + * set cwnd to ssthresh. */ - - if (sk->dup_acks >= 3) - { + if (tp->dup_acks >= 3) { tp->retrans_head = NULL; - tp->snd_cwnd = max(sk->ssthresh, 1); - atomic_set(&sk->retransmits, 0); + tp->snd_cwnd = max(tp->snd_ssthresh, 1); + tp->retransmits = 0; } - sk->dup_acks = 0; + tp->dup_acks = 0; + + /* FIXME: This is wrong if the new ack that arrives + * is below the value for high_seq. + */ tp->high_seq = 0; } } +#endif + +#define FLAG_DATA 0x01 +#define FLAG_WIN_UPDATE 0x02 +#define FLAG_DATA_ACKED 0x04 + +static __inline__ void clear_fast_retransmit(struct sock *sk) { + struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + if (tp->dup_acks > 3) { + tp->retrans_head = NULL; + tp->snd_cwnd = max(tp->snd_ssthresh, 1); + } + tp->dup_acks = 0; +} + +/* + * NOTE: This code assumes that tp->dup_acks gets cleared when a + * retransmit timer fires. + */ + +static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup) +{ + struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + + /* + * Note: If not_dup is set this implies we got a + * data carrying packet or a window update. + * This carries no new information about possible + * lost packets, so we have to ignore it for the purposes + * of counting duplicate acks. Ideally this does not imply we + * should stop our fast retransmit phase, more acks may come + * later without data to help us. Unfortunately this would make + * the code below much more complex. For now if I see such + * a packet I clear the fast retransmit phase. + */ + + if (ack == tp->snd_una && tp->packets_out && (not_dup == 0)) { + /* This is the standard reno style fast retransmit branch. */ + + /* 1. When the third duplicate ack is received, set ssthresh + * to one half the current congestion window, but no less + * than two segments. Retransmit the missing segment. + */ + if (tp->high_seq == 0 || after(ack, tp->high_seq)) { + tp->dup_acks++; + if (tp->dup_acks == 3) { + tp->dup_acks++; + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd = tp->snd_ssthresh + 3; + tp->high_seq = tp->snd_nxt; + tcp_do_retransmit(sk, 0); + tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + } + } + + /* 2. Each time another duplicate ACK arrives, increment + * cwnd by the segment size. [...] Transmit a packet... + * + * Packet transmission will be done on normal flow processing + * since we're not in "retransmit mode" + */ + if (tp->dup_acks > 3) + tp->snd_cwnd++; + } else if (tp->high_seq != 0) { + /* In this branch we deal with clearing the Floyd style + * block on duplicate fast retransmits, and if requested + * we do Hoe style secondary fast retransmits. + */ + if (!before(ack,tp->high_seq) || (not_dup&FLAG_DATA) != 0) { + /* Once we have acked all the packets up to high_seq + * we are done this fast retransmit phase. + * Alternatively data arrived. In this case we + * Have to abort the fast retransmit attempt. + * Note that we do want to accept a window + * update since this is expected with Hoe's algorithm. + */ + clear_fast_retransmit(sk); + + /* After we have cleared up to high_seq we can + * clear the Floyd style block. + */ + if (after(ack,tp->high_seq)) + tp->high_seq = 0; + } else if (tp->dup_acks >= 3) { + if (sysctl_tcp_hoe_retransmits) { + /* Hoe Style. We didn't ack the whole + * window. Take this as a cue that + * another packet was lost and retransmit it. + * Don't muck with the congestion window here. + * Note that we have to be careful not to + * act if this was a window update and it + * didn't ack new data, since this does + * not indicate a packet left the system. + * We can test this by just checking + * if ack changed from snd_una, since + * the only way to get here without changing + * advancing from snd_una is if this was a + * window update. + */ + if (ack != tp->snd_una && before(ack,tp->high_seq)) { + tcp_do_retransmit(sk, 0); + tcp_reset_xmit_timer(sk, TIME_RETRANS, + tp->rto); + } + } else { + /* Reno style. We didn't ack the whole + * window, now we have to drop out of + * fast retransmit and wait for a timeout. + */ + clear_fast_retransmit(sk); + } + } + } else { + /* Clear any aborted fast retransmit starts. */ + tp->dup_acks = 0; + } +} /* * TCP slow start and congestion avoidance in two flavors: @@ -401,24 +596,20 @@ static void tcp_cong_avoid_vegas(struct sock *sk, u32 seq, u32 ack, u32 seq_rtt) { - struct tcp_opt * tp; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); unsigned int actual, expected; unsigned int inv_rtt, inv_basertt, inv_basebd; u32 snt_bytes; - /* - * From: + /* From: * TCP Vegas: New Techniques for Congestion * Detection and Avoidance. * - * * Warning: This code is a scratch implementation taken * from the paper only. The code they distribute seams * to have improved several things over the initial spec. */ - tp = &(sk->tp_pinfo.af_tcp); - if (!seq_rtt) seq_rtt = 1; @@ -427,11 +618,8 @@ else tp->basertt = seq_rtt; - /* - * - * actual = throughput for this segment. + /* actual = throughput for this segment. * expected = number_of_bytes in transit / BaseRTT - * */ snt_bytes = ack - seq; @@ -443,55 +631,36 @@ expected = (tp->snd_nxt - tp->snd_una) * inv_basertt; + /* XXX sk->mss should move into tcp_opt as well -DaveM */ inv_basebd = sk->mss * inv_basertt; - /* - * Slow Start - */ - - if (tp->snd_cwnd < sk->ssthresh && + /* Slow Start */ + if (tp->snd_cwnd < tp->snd_ssthresh && (seq == tp->snd_nxt || - (expected - actual <= TCP_VEGAS_GAMMA * inv_basebd))) - { - /* - * "Vegas allows exponential growth only every other - * RTT" - */ - - if (sk->cong_count++) - { + (expected - actual <= TCP_VEGAS_GAMMA * inv_basebd))) { + /* "Vegas allows exponential growth only every other RTT" */ + if (tp->snd_cwnd_cnt++) { tp->snd_cwnd++; - sk->cong_count = 0; + tp->snd_cwnd_cnt = 0; } - } - else - { - /* - * Congestion Avoidance - */ - - if (expected - actual <= TCP_VEGAS_ALPHA * inv_basebd) - { + } else { + /* Congestion Avoidance */ + if (expected - actual <= TCP_VEGAS_ALPHA * inv_basebd) { /* Increase Linearly */ - - if (sk->cong_count++ >= tp->snd_cwnd) - { + if (tp->snd_cwnd_cnt++ >= tp->snd_cwnd) { tp->snd_cwnd++; - sk->cong_count = 0; + tp->snd_cwnd_cnt = 0; } } - if (expected - actual >= TCP_VEGAS_BETA * inv_basebd) - { + if (expected - actual >= TCP_VEGAS_BETA * inv_basebd) { /* Decrease Linearly */ - - if (sk->cong_count++ >= tp->snd_cwnd) - { + if (tp->snd_cwnd_cnt++ >= tp->snd_cwnd) { tp->snd_cwnd--; - sk->cong_count = 0; + tp->snd_cwnd_cnt = 0; } - /* Never less than 2 segments */ + /* Never less than 2 segments. */ if (tp->snd_cwnd < 2) tp->snd_cwnd = 2; } @@ -500,17 +669,16 @@ static void tcp_cong_avoid_vanj(struct sock *sk, u32 seq, u32 ack, u32 seq_rtt) { - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * This is Jacobson's slow start and congestion avoidance. + /* This is Jacobson's slow start and congestion avoidance. * SIGCOMM '88, p. 328. Because we keep cong_window in * integral mss's, we can't do cwnd += 1 / cwnd. * Instead, maintain a counter and increment it once every * cwnd times. * FIXME: Check to be sure the mathematics works out right * on this trick when we have to reduce the congestion window. - * The cong_count has to be reset properly when reduction events + * The snd_cwnd_cnt has to be reset properly when reduction events * happen. * FIXME: What happens when the congestion window gets larger * than the maximum receiver window by some large factor @@ -520,38 +688,22 @@ * be reduced to is not clear, since 1/2 the old window may * still be larger than the maximum sending rate we ever achieved. */ - - if (tp->snd_cwnd <= sk->ssthresh) - { - /* - * In "safe" area, increase - */ - + if (tp->snd_cwnd <= tp->snd_ssthresh) { + /* In "safe" area, increase. */ tp->snd_cwnd++; - } - else - { - /* - * In dangerous area, increase slowly. - * In theory this is - * tp->snd_cwnd += 1 / tp->snd_cwnd + } else { + /* In dangerous area, increase slowly. In theory this is + * tp->snd_cwnd += 1 / tp->snd_cwnd */ - - if (sk->cong_count >= tp->snd_cwnd) { - + if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { tp->snd_cwnd++; - sk->cong_count = 0; - } - else - sk->cong_count++; + tp->snd_cwnd_cnt = 0; + } else + tp->snd_cwnd_cnt++; } } -#define FLAG_DATA 0x01 -#define FLAG_WIN_UPDATE 0x02 -#define FLAG_DATA_ACKED 0x04 - static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq, __u32 *seq_rtt) { @@ -560,25 +712,18 @@ unsigned long now = jiffies; int acked = 0; - while((skb=skb_peek(&sk->write_queue)) && (skb != tp->send_head)) - { - + while((skb=skb_peek(&sk->write_queue)) && (skb != tp->send_head)) { #ifdef TCP_DEBUG /* Check for a bug. */ - if (skb->next != (struct sk_buff*) &sk->write_queue && after(skb->end_seq, skb->next->seq)) - { printk(KERN_DEBUG "INET: tcp_input.c: *** " "bug send_list out of order.\n"); - } #endif - /* - * If our packet is before the ack sequence we can - * discard it as it's confirmed to have arrived the - * other end. + /* If our packet is before the ack sequence we can + * discard it as it's confirmed to have arrived the + * other end. */ - if (after(skb->end_seq, ack)) break; @@ -591,7 +736,7 @@ * do packet "repackaging" for stacks that don't * like overlapping packets. */ - atomic_dec(&sk->packets_out); + tp->packets_out--; *seq = skb->seq; *seq_rtt = now - skb->when; @@ -601,13 +746,11 @@ kfree_skb(skb, FREE_WRITE); } - if (acked) - { + if (acked) { tp->retrans_head = NULL; if (!sk->dead) sk->write_space(sk); } - return acked; } @@ -615,27 +758,18 @@ { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * Our probe was answered - */ + /* Our probe was answered. */ tp->probes_out = 0; - /* - * Was it a usable window open ? - */ + /* Was it a usable window open? */ /* should always be non-null */ if (tp->send_head != NULL && - !before (ack + tp->snd_wnd, tp->send_head->end_seq)) - { + !before (ack + tp->snd_wnd, tp->send_head->end_seq)) { tp->backoff = 0; tp->pending = 0; - tcp_clear_xmit_timer(sk, TIME_PROBE0); - - } - else - { + } else { tcp_reset_xmit_timer(sk, TIME_PROBE0, min(tp->rto << tp->backoff, 120*HZ)); } @@ -648,138 +782,126 @@ static 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; - - nwin = ntohs(th->window); - if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd)) - { + (tp->snd_wl1 == ack_seq && !after(tp->snd_wl2, ack))) { + unsigned long nwin = ntohs(th->window); + + 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 (atomic_read(&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 (atomic_read(&sk->packets_out)) - { - if (flag & FLAG_DATA_ACKED) - { + if (tp->packets_out) { + if (flag & FLAG_DATA_ACKED) { long when; skb = skb_peek(&sk->write_queue); when = tp->rto - (jiffies - skb->when); - /* - * FIXME: This assumes that when we are retransmitting + /* FIXME: This assumes that when we are retransmitting * we should only ever respond with one packet. * This means congestion windows should not grow * during recovery. In 2.0.X we allow the congestion @@ -791,36 +913,23 @@ * we have to fix the call to congestion window * updates so that it works during retransmission. */ - - if (atomic_read(&sk->retransmits)) - { + if (tp->retransmits) { tp->retrans_head = NULL; - /* - * This is tricky. We are retransmiting a + + /* This is tricky. We are retransmiting a * segment of a window when congestion occured. */ tcp_do_retransmit(sk, 0); - tcp_reset_xmit_timer(sk, TIME_RETRANS, - tp->rto); - } - else + tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + } else tcp_reset_xmit_timer(sk, TIME_RETRANS, when); } - } - else + } else tcp_clear_xmit_timer(sk, TIME_RETRANS); - - /* FIXME: danger, if we just did a timeout and got the third - * ack on this packet, then this is going to send it again! - * [No. Floyd retransmit war check keeps this from happening. -- erics] - */ tcp_fast_retrans(sk, ack, (flag & (FLAG_DATA|FLAG_WIN_UPDATE))); - /* - * Remember the highest ack received. - */ - + /* Remember the highest ack received. */ tp->snd_una = ack; return 1; @@ -828,11 +937,9 @@ uninteresting_ack: SOCK_DEBUG(sk, "Ack ignored %u %u\n", ack, tp->snd_nxt); - return 0; } - /* * Process the FIN bit. This now behaves as it is supposed to work * and the FIN takes effect when it is validly part of sequence @@ -846,53 +953,46 @@ * close and we go into CLOSING (and later onto TIME-WAIT) * * If we are in FINWAIT-2, a received FIN moves us to TIME-WAIT. - * */ static int tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) { - sk->fin_seq = skb->end_seq; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* XXX This fin_seq thing should disappear... -DaveM */ + tp->fin_seq = skb->end_seq; tcp_send_ack(sk); - if (!sk->dead) - { + if (!sk->dead) { sk->state_change(sk); sock_wake_async(sk->socket, 1); } - switch(sk->state) - { + switch(sk->state) { case TCP_SYN_RECV: case TCP_SYN_SENT: case TCP_ESTABLISHED: - /* - * move to CLOSE_WAIT - */ - + /* Move to CLOSE_WAIT */ tcp_set_state(sk, TCP_CLOSE_WAIT); - if (th->rst) sk->shutdown = SHUTDOWN_MASK; break; case TCP_CLOSE_WAIT: case TCP_CLOSING: - /* - * received a retransmission of the FIN, do + /* Received a retransmission of the FIN, do * nothing. */ break; case TCP_TIME_WAIT: - /* - * received a retransmission of the FIN, + /* Received a retransmission of the FIN, * restart the TIME_WAIT timer. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); return(0); case TCP_FIN_WAIT1: - /* - * This case occurs when a simultaneous close + /* This case occurs when a simultaneous close * happens, we must ack the received FIN and * enter the CLOSING state. * @@ -902,47 +1002,39 @@ * FIN lost hang). The TIME_WRITE code is already * correct for handling this timeout. */ - tcp_set_state(sk, TCP_CLOSING); break; case TCP_FIN_WAIT2: - /* - * received a FIN -- send ACK and enter TIME_WAIT - */ + /* Received a FIN -- send ACK and enter TIME_WAIT. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); - sk->shutdown|=SHUTDOWN_MASK; + sk->shutdown |= SHUTDOWN_MASK; tcp_set_state(sk,TCP_TIME_WAIT); break; case TCP_CLOSE: - /* - * already in CLOSE - */ + /* Already in CLOSE. */ break; default: + /* FIXME: Document whats happening in this case. -DaveM */ tcp_set_state(sk,TCP_LAST_ACK); /* Start the timers. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); return(0); - } + }; return(0); } - - - /* - * This one checks to see if we can put data from the - * out_of_order queue into the receive_queue - */ - -static void tcp_ofo_queue(struct sock *sk) +/* This one checks to see if we can put data from the + * out_of_order queue into the receive_queue. + */ +static void tcp_ofo_queue(struct sock *sk) { - struct sk_buff * skb; - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + /* FIXME: out_of_order_queue is a strong tcp_opt candidate... -DaveM */ while ((skb = skb_peek(&sk->out_of_order_queue))) { - if (after(skb->seq, tp->rcv_nxt)) break; @@ -950,106 +1042,59 @@ SOCK_DEBUG(sk, "ofo packet was allready received \n"); skb_unlink(skb); kfree_skb(skb, FREE_READ); - continue; } SOCK_DEBUG(sk, "ofo requeuing : rcv_next %X seq %X - %X\n", tp->rcv_nxt, skb->seq, skb->end_seq); skb_unlink(skb); - skb_queue_tail(&sk->receive_queue, skb); - tp->rcv_nxt = skb->end_seq; } } static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) { - struct sk_buff * skb1; - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct sk_buff *skb1; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* - * Queue data for delivery to the user - * Packets in sequence go to the receive queue - * Out of sequence packets to out_of_order_queue + /* Queue data for delivery to the user. + * Packets in sequence go to the receive queue. + * Out of sequence packets to out_of_order_queue. */ - - if (skb->seq == tp->rcv_nxt) { - - /* - * Ok. In sequence. - */ - - + /* Ok. In sequence. */ +queue_and_out: skb_queue_tail(&sk->receive_queue, skb); - - tp->rcv_nxt = skb->end_seq; - tcp_ofo_queue(sk); - if (skb_queue_len(&sk->out_of_order_queue) == 0) tp->pred_flags = htonl((0x5010 << 16) | tp->snd_wnd); - return; } - /* - * Not in sequence - * either a retransmit or some packet got lost - */ - + /* Not in sequence, either a retransmit or some packet got lost. */ if (!after(skb->end_seq, tp->rcv_nxt)) { - - /* - * A retransmit. - * 2nd most common case. - * force an imediate ack - */ + /* A retransmit, 2nd most common case. Force an imediate ack. */ SOCK_DEBUG(sk, "retransmit received: seq %X\n", skb->seq); - sk->delayed_acks = MAX_DELAY_ACK; + tp->delayed_acks = MAX_DELAY_ACK; kfree_skb(skb, FREE_READ); - return; } - if (before(skb->seq, tp->rcv_nxt)) { - - /* - * Partial packet - * seq < rcv_next < end_seq - */ + /* Partial packet, seq < rcv_next < end_seq */ SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n", tp->rcv_nxt, skb->seq, skb->end_seq); - skb_queue_tail(&sk->receive_queue, skb); - - tp->rcv_nxt = skb->end_seq; - - tcp_ofo_queue(sk); - - if (skb_queue_len(&sk->out_of_order_queue) == 0) - tp->pred_flags = htonl((0x5010 << 16) | tp->snd_wnd); - - return; + goto queue_and_out; } - /* - * Ok. This is an out_of_order segment - */ - - /* Force an ack */ - - sk->delayed_acks = MAX_DELAY_ACK; - - /* - * disable header predition - */ + /* Ok. This is an out_of_order segment, force an ack. */ + tp->delayed_acks = MAX_DELAY_ACK; + /* Disable header predition. */ tp->pred_flags = 0; SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", @@ -1057,33 +1102,28 @@ if (skb_peek(&sk->out_of_order_queue) == NULL) { skb_queue_head(&sk->out_of_order_queue,skb); - } - else + } else { for(skb1=sk->out_of_order_queue.prev; ; skb1 = skb1->prev) { - - /* allready there */ - if (skb->seq==skb1->seq && skb->len>=skb1->len) - { - skb_append(skb1,skb); + /* Already there. */ + if (skb->seq == skb1->seq && skb->len >= skb1->len) { + skb_append(skb1, skb); skb_unlink(skb1); - kfree_skb(skb1,FREE_READ); + kfree_skb(skb1, FREE_READ); break; } - if (after(skb->seq, skb1->seq)) - { + if (after(skb->seq, skb1->seq)) { skb_append(skb1,skb); break; } - /* - * See if we've hit the start. If so insert. - */ + /* See if we've hit the start. If so insert. */ if (skb1 == skb_peek(&sk->out_of_order_queue)) { skb_queue_head(&sk->out_of_order_queue,skb); break; } } + } } @@ -1096,48 +1136,33 @@ static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len) { struct tcphdr *th; - struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp); + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); th = skb->h.th; - skb_pull(skb,th->doff*4); - skb_trim(skb,len-(th->doff*4)); + skb_pull(skb, th->doff*4); + skb_trim(skb, len - (th->doff*4)); if (skb->len == 0 && !th->fin) - { return(0); - } - /* - * FIXME: don't accept data after the receved fin - */ - - /* - * The bytes in the receive read/assembly queue has increased. - * Needed for the low memory discard algorithm - */ - - sk->bytes_rcv += skb->len; - - /* - * We no longer have anyone receiving data on this connection. + /* FIXME: don't accept data after the received fin. + * + * Would checking snd_seq against fin_seq be enough? + * If so, how do we handle that case exactly? -DaveM */ + /* We no longer have anyone receiving data on this connection. */ tcp_data_queue(sk, skb); - if (before(tp->rcv_nxt, sk->copied_seq)) - { + if (before(tp->rcv_nxt, sk->copied_seq)) { printk(KERN_DEBUG "*** tcp.c:tcp_data bug acked < copied\n"); tp->rcv_nxt = sk->copied_seq; } - sk->delayed_acks++; - - /* - * Now tell the user we may have some data. - */ + tp->delayed_acks++; - if (!sk->dead) - { + /* Now tell the user we may have some data. */ + if (!sk->dead) { SOCK_DEBUG(sk, "Data wakeup.\n"); sk->data_ready(sk,0); } @@ -1149,29 +1174,25 @@ 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) && - atomic_read(&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 (atomic_read(&sk->packets_out) == 0 && !tp->pending) - { - /* - * Data to queue but no room. - */ + } else if (tp->packets_out == 0 && !tp->pending) { + /* Data to queue but no room. */ + /* FIXME: Is it right to do a zero window probe into - * a congestion window limited window??? + * a congestion window limited window??? -- erics */ tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); } @@ -1180,32 +1201,25 @@ static __inline__ void tcp_ack_snd_check(struct sock *sk) { - /* - * This also takes care of updating the window. - * This if statement needs to be simplified. + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* This also takes care of updating the window. + * This if statement needs to be simplified. * - * rules for delaying an ack: + * Rules for delaying an ack: * - delay time <= 0.5 HZ * - we don't have a window update to send * - must send at least every 2 full sized packets */ - - if (sk->delayed_acks == 0) - { - /* - * We sent a data segment already - */ + if (tp->delayed_acks == 0) { + /* We sent a data segment already. */ return; } - if (sk->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk)) - { + if (tp->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk)) tcp_send_ack(sk); - } else - { tcp_send_delayed_ack(sk, HZ/2); - } } /* @@ -1227,62 +1241,49 @@ ptr--; ptr += ntohl(th->seq); - /* ignore urgent data that we've already seen and read */ + /* Ignore urgent data that we've already seen and read. */ if (after(sk->copied_seq, ptr)) return; - /* do we already have a newer (or duplicate) urgent pointer? */ + /* Do we already have a newer (or duplicate) urgent pointer? */ if (sk->urg_data && !after(ptr, sk->urg_seq)) return; - /* tell the world about our new urgent pointer */ + /* Tell the world about our new urgent pointer. */ if (sk->proc != 0) { - if (sk->proc > 0) { + if (sk->proc > 0) kill_proc(sk->proc, SIGURG, 1); - } else { + else kill_pg(-sk->proc, SIGURG, 1); - } } - /* - * We may be adding urgent data when the last byte read was - * urgent. To do this requires some care. We cannot just ignore - * sk->copied_seq since we would read the last urgent byte again - * as data, nor can we alter copied_seq until this data arrives - * or we break the sematics of SIOCATMARK (and thus sockatmark()) + + /* We may be adding urgent data when the last byte read was + * urgent. To do this requires some care. We cannot just ignore + * sk->copied_seq since we would read the last urgent byte again + * as data, nor can we alter copied_seq until this data arrives + * or we break the sematics of SIOCATMARK (and thus sockatmark()) */ if (sk->urg_seq == sk->copied_seq) sk->copied_seq++; /* Move the copied sequence on correctly */ sk->urg_data = URG_NOTYET; sk->urg_seq = ptr; - /* disable header prediction */ + /* Disable header prediction. */ tp->pred_flags = 0; } -/* - * This is the 'fast' part of urgent handling. - */ - +/* This is the 'fast' part of urgent handling. */ static inline void tcp_urg(struct sock *sk, struct tcphdr *th, unsigned long len) { - /* - * Check if we get a new urgent pointer - normally not - */ - + /* Check if we get a new urgent pointer - normally not. */ if (th->urg) tcp_check_urg(sk,th); - /* - * Do we wait for any urgent data? - normally not - */ - + /* Do we wait for any urgent data? - normally not... */ if (sk->urg_data == URG_NOTYET) { - u32 ptr; + u32 ptr = sk->urg_seq - ntohl(th->seq) + (th->doff*4); - /* - * Is the urgent pointer pointing into this packet? - */ - ptr = sk->urg_seq - ntohl(th->seq) + th->doff*4; + /* Is the urgent pointer pointing into this packet? */ if (ptr < len) { sk->urg_data = URG_VALID | *(ptr + (unsigned char *) th); if (!sk->dead) @@ -1291,26 +1292,19 @@ } } - static void prune_queue(struct sock *sk) { struct sk_buff * skb; - /* - * clean the out_of_order queue - */ - + /* Clean the out_of_order queue. */ while ((skb = skb_dequeue(&sk->out_of_order_queue))) - { kfree_skb(skb, FREE_READ); - } } - int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, struct tcphdr *th, __u16 len) { - struct tcp_opt *tp; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int queued = 0; u32 flg; @@ -1330,6 +1324,23 @@ */ tp = &(sk->tp_pinfo.af_tcp); + + /* + * RFC1323: H1. Apply PAWS check first. + */ + if (tcp_fast_parse_options(th,tp)) { + if (tp->saw_tstamp) { + if (tcp_paws_discard(tp)) { + if (!th->rst) { + tcp_send_ack(sk); + kfree_skb(skb, FREE_READ); + return 0; + } + } + tcp_replace_ts_recent(tp,skb->end_seq); + } + } + flg = *(((u32 *)th) + 3); /* @@ -1340,53 +1351,39 @@ * space for instance) */ - if (flg == tp->pred_flags && skb->seq == tp->rcv_nxt) - { - if (len <= sizeof(struct tcphdr)) - { - if (len == sizeof(struct tcphdr)) - { + if (flg == tp->pred_flags && skb->seq == tp->rcv_nxt) { + if (len <= th->doff*4) { + /* Bulk data transfer: sender */ + if (len == th->doff*4) { tcp_ack(sk, th, skb->seq, skb->ack_seq, len); tcp_data_snd_check(sk); } kfree_skb(skb, FREE_READ); return 0; - } - else if (skb->ack_seq == tp->snd_una) - { - /* - * Bulk data transfer: receiver - */ + } else if (skb->ack_seq == tp->snd_una) { + /* Bulk data transfer: receiver */ - skb_pull(skb,sizeof(struct tcphdr)); + skb_pull(skb,th->doff*4); skb_queue_tail(&sk->receive_queue, skb); tp->rcv_nxt = skb->end_seq; - sk->bytes_rcv += len - sizeof(struct tcphdr); - + sk->data_ready(sk, 0); tcp_delack_estimator(tp); - if (sk->delayed_acks++ == 0) - { + if (tp->delayed_acks++ == 0) tcp_send_delayed_ack(sk, HZ/2); - } else - { tcp_send_ack(sk); - } return 0; } } - if (!tcp_sequence(tp, skb->seq, skb->end_seq)) - { - if (!th->rst) - { - if (after(skb->seq, tp->rcv_nxt)) - { + if (!tcp_sequence(tp, skb->seq, skb->end_seq)) { + if (!th->rst) { + if (after(skb->seq, tp->rcv_nxt)) { SOCK_DEBUG(sk, "seq:%d end:%d wup:%d wnd:%d\n", skb->seq, skb->end_seq, tp->rcv_wup, tp->rcv_wnd); @@ -1397,68 +1394,45 @@ } } - if(th->syn && skb->seq != sk->syn_seq) - { + if(th->syn && skb->seq != sk->syn_seq) { printk(KERN_DEBUG "syn in established state\n"); tcp_reset(sk, skb); kfree_skb(skb, FREE_READ); return 1; } - if(th->rst) - { + if(th->rst) { tcp_reset(sk,skb); kfree_skb(skb, FREE_READ); return 0; } if(th->ack) - { tcp_ack(sk, th, skb->seq, skb->ack_seq, len); - } - - /* - * Process urgent data - */ - + /* Process urgent data. */ tcp_urg(sk, th, len); - /* - * step 7: process the segment text - */ - - + /* step 7: process the segment text */ queued = tcp_data(skb, sk, len); - /* - * step 8: check the FIN bit - */ - + /* step 8: check the FIN bit */ if (th->fin) - { tcp_fin(skb, sk, th); - } tcp_data_snd_check(sk); tcp_ack_snd_check(sk); - /* - * If our receive queue has grown past its limits, - * try to prune away duplicates etc.. + /* If our receive queue has grown past its limits, + * try to prune away duplicates etc.. */ if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) prune_queue(sk); - /* - * And done - */ - if (!queued) kfree_skb(skb, FREE_READ); return 0; } - /* * This function implements the receiving procedure of RFC 793. @@ -1471,49 +1445,26 @@ { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int queued = 0; - int rcv_mss; - - /* - * state == CLOSED - * Hash lookup always fails, so no worries. -DaveM - */ + /* state == CLOSED, hash lookup always fails, so no worries. -DaveM */ switch (sk->state) { - - case TCP_LISTEN: - if (th->rst) goto discard; - /* - * These use the socket TOS.. + /* These use the socket TOS.. * might want to be the received TOS */ - if(th->ack) - { - /* - * send reset - */ - - return 1; - } + return 1; /* send reset */ - - if(th->syn) - { - int err; - __u32 isn; - - isn = tp->af_specific->init_sequence(sk, skb); - err = tp->af_specific->conn_request(sk, skb, opt, isn); + if(th->syn) { + __u32 isn = tp->af_specific->init_sequence(sk, skb); - if (err < 0) + if(tp->af_specific->conn_request(sk, skb, opt, isn) < 0) return 1; - /* - * Now we have several options: In theory there is + /* Now we have several options: In theory there is * nothing else in the frame. KA9Q has an option to * send data with the syn, BSD accepts data with the * syn up to the [to be] advertised window and @@ -1525,7 +1476,6 @@ * Now that TTCP is starting to be used we ought to * queue this data. */ - return 0; } @@ -1533,47 +1483,36 @@ break; case TCP_SYN_SENT: - - /* - * SYN sent means we have to look for a suitable ack and - * either reset for bad matches or go to connected. - * The SYN_SENT case is unusual and should - * not be in line code. [AC] + /* SYN sent means we have to look for a suitable ack and + * either reset for bad matches or go to connected. + * The SYN_SENT case is unusual and should + * not be in line code. [AC] */ - - if(th->ack) - { + if(th->ack) { tp->snd_wl1 = skb->seq; - /* We got an ack, but it's not a good ack */ - if(!tcp_ack(sk,th, skb->seq, skb->ack_seq, len)) - { + /* We got an ack, but it's not a good ack. */ + if(!tcp_ack(sk,th, skb->seq, skb->ack_seq, len)) { tcp_statistics.TcpAttemptFails++; return 1; } - if(th->rst) - { + if(th->rst) { tcp_reset(sk,skb); goto discard; } - if(!th->syn) - { - /* - * A valid ack from a different connection - * start. Shouldn't happen but cover it + if(!th->syn) { + /* A valid ack from a different connection + * start. Shouldn't happen but cover it. */ tcp_statistics.TcpAttemptFails++; return 1; } - /* - * Ok.. it's good. Set up sequence - * numbers and - * move to established. + /* Ok.. it's good. Set up sequence numbers and + * move to established. */ - tp->rcv_nxt = skb->seq+1; tp->rcv_wnd = 0; tp->rcv_wup = skb->seq+1; @@ -1582,39 +1521,53 @@ tp->snd_wl1 = skb->seq; tp->snd_wl2 = skb->ack_seq; - sk->fin_seq = skb->seq; - tcp_send_ack(sk); + tp->fin_seq = skb->seq; tcp_set_state(sk, TCP_ESTABLISHED); - rcv_mss = tcp_parse_options(th); - - if (rcv_mss) - sk->mss = min(sk->mss, rcv_mss); + tcp_parse_options(th,tp); + /* FIXME: need to make room for SACK still */ + if (tp->tstamp_ok) { + tp->tcp_header_len = sizeof(struct tcphdr) + 12; /* FIXME: Define constant! */ + sk->dummy_th.doff += 3; /* reserve space of options */ + } else + tp->tcp_header_len = sizeof(struct tcphdr); + if (tp->saw_tstamp) { + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = jiffies; + } + + /* Can't be earlier, doff would be wrong. */ + tcp_send_ack(sk); + + if (tp->in_mss) + sk->mss = min(sk->mss, tp->in_mss); + + /* Take out space for tcp options. */ + sk->mss -= tp->tcp_header_len - sizeof(struct tcphdr); sk->dummy_th.dest = th->source; sk->copied_seq = tp->rcv_nxt; - if(!sk->dead) - { + if(!sk->dead) { sk->state_change(sk); sock_wake_async(sk->socket, 0); } /* Drop through step 6 */ goto step6; - } - else - { - if(th->syn && !th->rst) - { - /* - * the previous version of the code + } else { + if(th->syn && !th->rst) { + /* The previous version of the code * checked for "connecting to self" * here. that check is done now in - * tcp_connect + * tcp_connect. */ - tcp_set_state(sk, TCP_SYN_RECV); + tcp_parse_options(th,tp); + if (tp->saw_tstamp) { + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = jiffies; + } tp->rcv_nxt = skb->seq + 1; tp->rcv_wup = skb->seq + 1; @@ -1630,8 +1583,7 @@ break; case TCP_TIME_WAIT: - /* - * RFC 1122: + /* RFC 1122: * "When a connection is [...] on TIME-WAIT state [...] * [a TCP] MAY accept a new SYN from the remote TCP to * reopen the connection directly, if it: @@ -1644,11 +1596,8 @@ * (2) returns to TIME-WAIT state if the SYN turns out * to be an old duplicate". */ - - if (th->syn && !th->rst && after(skb->seq, tp->rcv_nxt)) - { + if (th->syn && !th->rst && after(skb->seq, tp->rcv_nxt)) { __u32 isn; - int err; skb_orphan(skb); sk->err = ECONNRESET; @@ -1664,50 +1613,53 @@ skb_set_owner_r(skb, sk); tp = &sk->tp_pinfo.af_tcp; - - err = tp->af_specific->conn_request(sk, skb, opt, isn); - if (err < 0) + if(tp->af_specific->conn_request(sk, skb, opt, isn) < 0) return 1; - return 0; } break; - } - /* - * step 1: check sequence number - */ + /* Parse the tcp_options present on this header. + * By this point we really only expect timestamps and SACKs. + * Note that this really has to be here and not later for PAWS + * (RFC1323) to work. + */ + if (tcp_fast_parse_options(th,tp)) { + /* NOTE: assumes saw_tstamp is never set if we didn't + * negotiate the option. tcp_fast_parse_options() must + * guarantee this. + */ + if (tp->saw_tstamp) { + if (tcp_paws_discard(tp)) { + if (!th->rst) { + tcp_send_ack(sk); + goto discard; + } + } + tcp_replace_ts_recent(tp,skb->end_seq); + } + } - if (!tcp_sequence(tp, skb->seq, skb->end_seq)) - { - if (!th->rst) - { + /* step 1: check sequence number */ + if (!tcp_sequence(tp, skb->seq, skb->end_seq)) { + if (!th->rst) { tcp_send_ack(sk); goto discard; } } - - /* - * step 2: check RST bit - */ - - if(th->rst) - { + /* step 2: check RST bit */ + if(th->rst) { tcp_reset(sk,skb); goto discard; } - /* - * step 3: check security and precedence - * [ignored] - */ + /* step 3: check security and precedence [ignored] */ - /* - * step 4: + /* step 4: * * Check for a SYN, and ensure it matches the SYN we were * first sent. We have to handle the rather unusual (but valid) @@ -1723,24 +1675,18 @@ * original syn. */ - if (th->syn && skb->seq!=sk->syn_seq) - { + if (th->syn && skb->seq!=sk->syn_seq) { tcp_reset(sk, skb); return 1; } - /* - * step 5: check the ACK field - */ - - if (th->ack) - { + /* step 5: check the ACK field */ + if (th->ack) { int acceptable = tcp_ack(sk,th,skb->seq, skb->ack_seq,len); switch(sk->state) { case TCP_SYN_RECV: - if (acceptable) - { + if (acceptable) { tcp_set_state(sk, TCP_ESTABLISHED); sk->dummy_th.dest=th->source; sk->copied_seq = tp->rcv_nxt; @@ -1753,15 +1699,12 @@ tp->snd_wl1 = skb->seq; tp->snd_wl2 = skb->ack_seq; - } - else + } else return 1; break; case TCP_FIN_WAIT1: - - if (tp->snd_una == sk->write_seq) - { + if (tp->snd_una == sk->write_seq) { sk->shutdown |= SEND_SHUTDOWN; tcp_set_state(sk, TCP_FIN_WAIT2); if (!sk->dead) @@ -1770,17 +1713,12 @@ break; case TCP_CLOSING: - if (tp->snd_una == sk->write_seq) - { tcp_time_wait(sk); - } break; case TCP_LAST_ACK: - - if (tp->snd_una == sk->write_seq) - { + if (tp->snd_una == sk->write_seq) { sk->shutdown = SHUTDOWN_MASK; tcp_set_state(sk,TCP_CLOSE); if (!sk->dead) @@ -1790,49 +1728,34 @@ break; case TCP_TIME_WAIT: - /* - * keep us in TIME_WAIT until we stop getting + /* Keep us in TIME_WAIT until we stop getting * packets, reset the timeout. */ tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); break; - } - } - else + } else goto discard; - step6: - - /* - * step 6: check the URG bit - */ - +step6: + /* step 6: check the URG bit */ tcp_urg(sk, th, len); - /* - * step 7: process the segment text - */ - + /* step 7: process the segment text */ switch (sk->state) { case TCP_CLOSE_WAIT: case TCP_CLOSING: - if (!before(skb->seq, sk->fin_seq)) + if (!before(skb->seq, tp->fin_seq)) break; case TCP_FIN_WAIT1: case TCP_FIN_WAIT2: - - /* - * RFC 793 says to queue data in this states, - * RFC 1122 says we MUST send a reset. - * BSD 4.4 also does reset. + /* RFC 793 says to queue data in these states, + * RFC 1122 says we MUST send a reset. + * BSD 4.4 also does reset. */ - - if ((sk->shutdown & RCV_SHUTDOWN) && sk->dead) - { - if (after(skb->end_seq - th->fin, tp->rcv_nxt)) - { + if ((sk->shutdown & RCV_SHUTDOWN) && sk->dead) { + if (after(skb->end_seq - th->fin, tp->rcv_nxt)) { tcp_reset(sk, skb); return 1; } @@ -1843,22 +1766,16 @@ break; } - /* - * step 8: check the FIN bit - */ - + /* step 8: check the FIN bit */ if (th->fin) - { tcp_fin(skb, sk, th); - } tcp_data_snd_check(sk); tcp_ack_snd_check(sk); if (queued) return 0; - discard: - +discard: kfree_skb(skb, FREE_READ); return 0; } @@ -1871,19 +1788,18 @@ retv = proc_dointvec(ctl, write, filp, buffer, lenp); - if (write) - { + if (write) { switch (sysctl_tcp_cong_avoidance) { - case 0: - tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj; - break; - case 1: - tcp_sys_cong_ctl_f = &tcp_cong_avoid_vegas; - break; - default: - retv = -EINVAL; - sysctl_tcp_cong_avoidance = val; - } + case 0: + tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj; + break; + case 1: + tcp_sys_cong_ctl_f = &tcp_cong_avoid_vegas; + break; + default: + retv = -EINVAL; + sysctl_tcp_cong_avoidance = val; + }; } return retv; diff -u --recursive --new-file v2.1.35/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c --- v2.1.35/linux/net/ipv4/tcp_ipv4.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_ipv4.c Tue Apr 22 22:46:28 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.30 1997/04/13 10:31:44 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.39 1997/04/22 02:53:14 davem Exp $ * * IPv4 specific functions * @@ -27,6 +27,9 @@ * Changes: * David S. Miller : New socket lookup architecture. * This code is dedicated to John Dyson. + * David S. Miller : Change semantics of established hash, + * half is devoted to TIME_WAIT sockets + * and the rest go in the other half. */ #include @@ -41,6 +44,11 @@ #include +extern int sysctl_tcp_sack; +extern int sysctl_tcp_tsack; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; + static void tcp_v4_send_reset(struct sk_buff *skb); void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, @@ -49,12 +57,15 @@ /* This is for sockets with full identity only. Sockets here will always * be without wildcards and will have the following invariant: * TCP_ESTABLISHED <= sk->state < TCP_CLOSE + * + * First half of the table is for sockets not in TIME_WAIT, second half + * is for TIME_WAIT sockets only. */ struct sock *tcp_established_hash[TCP_HTABLE_SIZE]; /* All sockets in TCP_LISTEN state will be in here. This is the only table * where wildcard'd TCP sockets can exist. Hash function here is just local - * port number. XXX Fix or we'll lose with thousands of IP aliases... + * port number. */ struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE]; @@ -66,7 +77,7 @@ static __inline__ int tcp_hashfn(__u32 laddr, __u16 lport, __u32 faddr, __u16 fport) { - return ((laddr ^ lport) ^ (faddr ^ fport)) & (TCP_HTABLE_SIZE - 1); + return ((laddr ^ lport) ^ (faddr ^ fport)) & ((TCP_HTABLE_SIZE/2) - 1); } static __inline__ int tcp_sk_hashfn(struct sock *sk) @@ -243,10 +254,14 @@ if(state != TCP_CLOSE || !sk->dead) { struct sock **skp; - if(state == TCP_LISTEN) + if(state == TCP_LISTEN) { skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; - else - skp = &tcp_established_hash[tcp_sk_hashfn(sk)]; + } else { + int hash= tcp_sk_hashfn(sk); + if(state == TCP_TIME_WAIT) + hash += (TCP_HTABLE_SIZE/2); + skp = &tcp_established_hash[hash]; + } if((sk->next = *skp) != NULL) (*skp)->pprev = &sk->next; @@ -262,19 +277,13 @@ * to specify the remote port nor the remote address for the * connection. So always assume those are both wildcarded * during the search since they can never be otherwise. - * - * XXX Later on, hash on both local port _and_ local address, - * XXX to handle a huge IP alias'd box. Keep in mind that - * XXX such a scheme will require us to run through the listener - * XXX hash twice, once for local addresses bound, and once for - * XXX the local address wildcarded (because the hash is different). */ -static struct sock *tcp_v4_lookup_longway(u32 daddr, unsigned short hnum) +static struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum) { - struct sock *sk = tcp_listening_hash[tcp_lhashfn(hnum)]; + struct sock *sk; struct sock *result = NULL; - for(; sk; sk = sk->next) { + for(sk = tcp_listening_hash[tcp_lhashfn(hnum)]; sk; sk = sk->next) { if(sk->num == hnum) { __u32 rcv_saddr = sk->rcv_saddr; @@ -296,19 +305,28 @@ { unsigned short hnum = ntohs(dport); struct sock *sk; + int hash = tcp_hashfn(daddr, hnum, saddr, sport); /* Optimize here for direct hit, only listening connections can * have wildcards anyways. It is assumed that this code only * gets called from within NET_BH. */ - sk = tcp_established_hash[tcp_hashfn(daddr, hnum, saddr, sport)]; - for(; sk; sk = sk->next) + for(sk = tcp_established_hash[hash]; sk; sk = sk->next) if(sk->daddr == saddr && /* remote address */ sk->dummy_th.dest == sport && /* remote port */ sk->num == hnum && /* local port */ sk->rcv_saddr == daddr) /* local address */ goto hit; /* You sunk my battleship! */ - sk = tcp_v4_lookup_longway(daddr, hnum); + + /* Must check for a TIME_WAIT'er before going to listener hash. */ + for(sk = tcp_established_hash[hash+(TCP_HTABLE_SIZE/2)]; sk; sk = sk->next) + if(sk->daddr == saddr && /* remote address */ + sk->dummy_th.dest == sport && /* remote port */ + sk->num == hnum && /* local port */ + sk->rcv_saddr == daddr) /* local address */ + goto hit; + + sk = tcp_v4_lookup_listener(daddr, hnum); hit: return sk; } @@ -417,13 +435,27 @@ sk->num == snum && /* local port */ sk->saddr == saddr) { /* local address */ retval = 0; - break; + goto out; + } + } + + /* Must check TIME_WAIT'ers too. */ + sk = tcp_established_hash[hashent + (TCP_HTABLE_SIZE/2)]; + for (; sk != NULL; sk = sk->next) { + if(sk->daddr == daddr && /* remote address */ + sk->dummy_th.dest == dnum && /* remote port */ + sk->num == snum && /* local port */ + sk->saddr == saddr) { /* local address */ + retval = 0; + goto out; } } +out: SOCKHASH_UNLOCK(); return retval; } + /* * This will initiate an outgoing connection. */ @@ -432,7 +464,6 @@ { struct sk_buff *buff; struct sk_buff *skb1; - unsigned char *ptr; int tmp; struct tcphdr *t1; struct rtable *rt; @@ -442,10 +473,7 @@ if (sk->state != TCP_CLOSE) return(-EISCONN); - /* - * Don't allow a double connect. - */ - + /* Don't allow a double connect. */ if (sk->daddr) return -EINVAL; @@ -505,20 +533,14 @@ sk->err = 0; buff = sock_wmalloc(sk, MAX_SYN_SIZE, 0, GFP_KERNEL); - if (buff == NULL) - { + if (buff == NULL) { release_sock(sk); return(-ENOBUFS); } - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = ip_build_header(buff, sk); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); release_sock(sk); return(-ENETUNREACH); @@ -535,11 +557,9 @@ t1->ack = 0; t1->window = htons(512); t1->syn = 1; - t1->doff = 6; - /* use 512 or whatever user asked for */ - - sk->window_clamp=rt->u.dst.window; + /* Use 512 or whatever user asked for. */ + tp->window_clamp = rt->u.dst.window; sk->mtu = rt->u.dst.pmtu; if ((sk->ip_pmtudisc == IP_PMTUDISC_DONT || @@ -557,17 +577,13 @@ sk->mss = (sk->mtu - sizeof(struct iphdr) - sizeof(struct tcphdr)); - /* - * Put in the TCP options to say MSS. - */ + tmp = tcp_syn_build_options(buff, sk->mss, sysctl_tcp_sack, + sysctl_tcp_timestamps, + sysctl_tcp_window_scaling?tp->rcv_wscale:0); + buff->csum = 0; + t1->doff = (sizeof(*t1)+ tmp)>>2; - ptr = skb_put(buff,4); - ptr[0] = TCPOPT_MSS; - ptr[1] = TCPOLEN_MSS; - ptr[2] = (sk->mss) >> 8; - ptr[3] = (sk->mss) & 0xff; - buff->csum = csum_partial(ptr, 4, 0); - tcp_v4_send_check(sk, t1, sizeof(struct tcphdr) + 4, buff); + tcp_v4_send_check(sk, t1, sizeof(struct tcphdr) + tmp, buff); tcp_set_state(sk,TCP_SYN_SENT); @@ -580,18 +596,18 @@ 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); - atomic_inc(&sk->packets_out); + tp->packets_out++; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); ip_queue_xmit(skb1); - /* Timer for repeating the SYN until an answer */ + /* Timer for repeating the SYN until an answer. */ tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); tcp_statistics.TcpActiveOpens++; tcp_statistics.TcpOutSegs++; @@ -604,10 +620,7 @@ { int retval = -EINVAL; - /* - * Do sanity checking for sendmsg/sendto/send - */ - + /* Do sanity checking for sendmsg/sendto/send. */ if (msg->msg_flags & ~(MSG_OOB|MSG_DONTROUTE|MSG_DONTWAIT)) goto out; if (msg->msg_name) { @@ -650,6 +663,7 @@ { struct iphdr *iph = (struct iphdr*)dp; struct tcphdr *th = (struct tcphdr*)(dp+(iph->ihl<<2)); + struct tcp_opt *tp; int type = skb->h.icmph->type; int code = skb->h.icmph->code; struct sock *sk; @@ -659,26 +673,23 @@ if (sk == NULL) return; - if (type == ICMP_SOURCE_QUENCH) - { - struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - - sk->ssthresh = max(tp->snd_cwnd >> 1, 2); - tp->snd_cwnd = sk->ssthresh + 3; + tp = &sk->tp_pinfo.af_tcp; + if (type == ICMP_SOURCE_QUENCH) { + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd = tp->snd_ssthresh; tp->high_seq = tp->snd_nxt; - return; } - if (type == ICMP_PARAMETERPROB) - { + if (type == ICMP_PARAMETERPROB) { sk->err=EPROTO; sk->error_report(sk); } + /* FIXME: What about the IP layer options size here? */ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { if (sk->ip_pmtudisc != IP_PMTUDISC_DONT) { - int new_mtu = sk->dst_cache->pmtu - sizeof(struct iphdr) - sizeof(struct tcphdr); + int new_mtu = sk->dst_cache->pmtu - sizeof(struct iphdr) - tp->tcp_header_len; if (new_mtu < sk->mss && new_mtu > 0) { sk->mss = new_mtu; } @@ -686,24 +697,18 @@ return; } - /* - * If we've already connected we will keep trying + /* If we've already connected we will keep trying * until we time out, or the user gives up. */ - - if (code <= NR_ICMP_UNREACH) - { - if(icmp_err_convert[code].fatal || sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) - { + if (code <= NR_ICMP_UNREACH) { + if(icmp_err_convert[code].fatal || sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) { sk->err = icmp_err_convert[code].errno; - if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) - { + if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) { tcp_statistics.TcpAttemptFails++; tcp_set_state(sk,TCP_CLOSE); sk->error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ } - } - else /* Only an error on timeout */ + } else /* Only an error on timeout */ sk->err_soft = icmp_err_convert[code].errno; } } @@ -714,7 +719,7 @@ { th->check = 0; th->check = tcp_v4_check(th, len, sk->saddr, sk->daddr, - csum_partial((char *)th, sizeof(*th), skb->csum)); + csum_partial((char *)th, th->doff<<2, skb->csum)); } /* @@ -746,10 +751,7 @@ skb1->h.th = th1 = (struct tcphdr *)skb_put(skb1, sizeof(struct tcphdr)); memset(th1, 0, sizeof(*th1)); - /* - * Swap the send and the receive. - */ - + /* Swap the send and the receive. */ th1->dest = th->source; th1->source = th->dest; th1->doff = sizeof(*th1)/4; @@ -768,6 +770,7 @@ skb1->csum = csum_partial((u8 *) th1, sizeof(*th1), 0); th1->check = tcp_v4_check(th1, sizeof(*th1), skb1->nh.iph->saddr, skb1->nh.iph->daddr, skb1->csum); + /* FIXME: should this carry an options packet? */ ip_queue_xmit(skb1); tcp_statistics.TcpOutSegs++; } @@ -803,7 +806,7 @@ 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); @@ -816,11 +819,16 @@ return; } - mss = (skb->dst->pmtu - sizeof(struct iphdr) + sizeof(struct tcphdr)); + mss = (skb->dst->pmtu - sizeof(struct iphdr) - sizeof(struct tcphdr)); if (sk->user_mss) mss = min(mss, sk->user_mss); skb->h.th = th = (struct tcphdr *) skb_put(skb, sizeof(struct tcphdr)); + /* Don't offer more than they did. + * This way we don't have to memorize who said what. + */ + req->mss = min(mss, req->mss); + /* Yuck, make this header setup more efficient... -DaveM */ memset(th, 0, sizeof(struct tcphdr)); th->syn = 1; @@ -831,20 +839,23 @@ skb->end_seq = skb->seq + 1; th->seq = ntohl(skb->seq); th->ack_seq = htonl(req->rcv_isn + 1); - th->doff = sizeof(*th)/4 + 1; th->window = ntohs(tp->rcv_wnd); - /* FIXME: csum_partial() of a four byte quantity is itself! -DaveM */ - ptr = skb_put(skb, TCPOLEN_MSS); - ptr[0] = TCPOPT_MSS; - ptr[1] = TCPOLEN_MSS; - ptr[2] = (mss >> 8) & 0xff; - ptr[3] = mss & 0xff; - skb->csum = csum_partial(ptr, TCPOLEN_MSS, 0); + /* XXX Partial csum of 4 byte quantity is itself! -DaveM + * Yes, but it's a bit harder to special case now. It's + * now computed inside the tcp_v4_send_check() to clean up + * updating the options fields in the mainline send code. + * If someone thinks this is really bad let me know and + * I'll try to do it a different way. -- erics + */ - th->check = tcp_v4_check(th, sizeof(*th) + TCPOLEN_MSS, + tmp = tcp_syn_build_options(skb, req->mss, req->sack_ok, req->tstamp_ok, + (req->snd_wscale)?tp->rcv_wscale:0); + skb->csum = 0; + th->doff = (sizeof(*th) + tmp)>>2; + th->check = tcp_v4_check(th, sizeof(*th) + tmp, req->af.v4_req.loc_addr, req->af.v4_req.rmt_addr, - csum_partial((char *)th, sizeof(*th), skb->csum)); + csum_partial((char *)th, sizeof(*th)+tmp, skb->csum)); ip_queue_xmit(skb); tcp_statistics.TcpOutSegs++; @@ -870,23 +881,21 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 isn) { struct ip_options *opt = (struct ip_options *) ptr; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct open_request *req; struct tcphdr *th = skb->h.th; __u32 saddr = skb->nh.iph->saddr; __u32 daddr = skb->nh.iph->daddr; - __u16 req_mss; /* If the socket is dead, don't accept the connection. */ - if (sk->dead) - { + if (sk->dead) { SOCK_DEBUG(sk, "Reset on %p: Connect on dead socket.\n",sk); tcp_statistics.TcpAttemptFails++; return -ENOTCONN; } if (sk->ack_backlog >= sk->max_ack_backlog || - tcp_v4_syn_filter(sk, skb, saddr)) - { + tcp_v4_syn_filter(sk, skb, saddr)) { SOCK_DEBUG(sk, "dropping syn ack:%d max:%d\n", sk->ack_backlog, sk->max_ack_backlog); #ifdef CONFIG_IP_TCPSF @@ -906,10 +915,17 @@ req->rcv_isn = skb->seq; req->snt_isn = isn; - req_mss = tcp_parse_options(th); - if (!req_mss) - req_mss = 536; - req->mss = req_mss; + tp->tstamp_ok = tp->sack_ok = tp->snd_wscale = 0; + tcp_parse_options(th,tp); + if (tp->saw_tstamp) { + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = jiffies; + } + req->mss = tp->in_mss; + req->tstamp_ok = tp->tstamp_ok; + req->sack_ok = tp->sack_ok; + req->snd_wscale = tp->snd_wscale; + req->ts_recent = tp->ts_recent; req->rmt_port = th->source; req->af.v4_req.loc_addr = daddr; req->af.v4_req.rmt_addr = saddr; @@ -968,12 +984,7 @@ skb_queue_head_init(&newsk->out_of_order_queue); skb_queue_head_init(&newsk->error_queue); - /* - * Unused - */ - - newsk->send_head = NULL; - + /* Unused */ newtp = &(newsk->tp_pinfo.af_tcp); newtp->send_head = NULL; newtp->retrans_head = NULL; @@ -984,15 +995,10 @@ newsk->prot->init(newsk); - newsk->cong_count = 0; -#if 0 /* Don't mess up the initialization we did in the init routine! */ - newsk->ssthresh = 0; -#endif + newtp->snd_cwnd_cnt = 0; newtp->backoff = 0; - newsk->intr = 0; newsk->proc = 0; newsk->done = 0; - newsk->partial = NULL; newsk->pair = NULL; atomic_set(&newsk->wmem_alloc, 0); atomic_set(&newsk->rmem_alloc, 0); @@ -1004,24 +1010,23 @@ 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; - atomic_set(&newsk->packets_out, 0); - atomic_set(&newsk->retransmits, 0); + newtp->packets_out = 0; + newtp->retransmits = 0; newsk->linger=0; newsk->destroy = 0; init_timer(&newsk->timer); @@ -1034,7 +1039,7 @@ newsk->dummy_th.dest = req->rmt_port; newsk->sock_readers=0; - newtp->rcv_nxt = req->rcv_isn + 1; + newtp->last_ack_sent = newtp->rcv_nxt = req->rcv_isn + 1; newtp->rcv_wup = req->rcv_isn + 1; newsk->copied_seq = req->rcv_isn + 1; @@ -1044,9 +1049,7 @@ newsk->saddr = req->af.v4_req.loc_addr; newsk->rcv_saddr = req->af.v4_req.loc_addr; - /* - * options / mss / route_cache - */ + /* options / mss / route_cache */ newsk->opt = req->af.v4_req.opt; if (ip_route_output(&rt, newsk->opt && newsk->opt->srr ? newsk->opt->faddr : newsk->daddr, @@ -1057,19 +1060,34 @@ newsk->dst_cache = &rt->u.dst; - newsk->window_clamp = rt->u.dst.window; + newtp->window_clamp = rt->u.dst.window; snd_mss = rt->u.dst.pmtu; + /* FIXME: is mtu really the same as snd_mss? */ newsk->mtu = snd_mss; + /* FIXME: where does mtu get used after this? */ /* sanity check */ if (newsk->mtu < 64) newsk->mtu = 64; + newtp->sack_ok = req->sack_ok; + newtp->tstamp_ok = req->tstamp_ok; + newtp->snd_wscale = req->snd_wscale; + newtp->ts_recent = req->ts_recent; + newtp->ts_recent_stamp = jiffies; + if (newtp->tstamp_ok) { + newtp->tcp_header_len = sizeof(struct tcphdr) + 12; /* FIXME: define constant! */ + newsk->dummy_th.doff += 3; + } else { + newtp->tcp_header_len = sizeof(struct tcphdr); + } + snd_mss -= sizeof(struct iphdr) + sizeof(struct tcphdr); if (sk->user_mss) snd_mss = min(snd_mss, sk->user_mss); - newsk->mss = min(req->mss, snd_mss); + /* Make sure our mtu is adjusted for headers. */ + newsk->mss = min(req->mss, snd_mss) + sizeof(struct tcphdr) - newtp->tcp_header_len; tcp_v4_hash(newsk); add_to_prot_sklist(newsk); @@ -1085,10 +1103,10 @@ * as we checked the user count on tcp_rcv and we're * running from a soft interrupt. */ - if (!req) + if(!req) return sk; - do { + while(req) { if (req->af.v4_req.rmt_addr == skb->nh.iph->saddr && req->af.v4_req.loc_addr == skb->nh.iph->daddr && req->rmt_port == skb->h.th->source) { @@ -1122,7 +1140,8 @@ req->sk = sk; break; } - } while ((req = req->dl_next) != tp->syn_wait_queue); + req = req->dl_next; + } skb_orphan(skb); skb_set_owner_r(skb, sk); @@ -1146,20 +1165,13 @@ goto ok; } - if (sk->state == TCP_LISTEN) - { + if (sk->state == TCP_LISTEN) { struct sock *nsk; - /* - * find possible connection requests - */ - + /* Find possible connection requests. */ nsk = tcp_v4_check_req(sk, skb); - if (nsk == NULL) - { goto discard_it; - } release_sock(sk); lock_sock(nsk); @@ -1173,9 +1185,7 @@ tcp_v4_send_reset(skb); discard_it: - /* - * Discard frame - */ + /* Discard frame. */ kfree_skb(skb, FREE_READ); ok: @@ -1199,25 +1209,19 @@ if (skb->pkt_type!=PACKET_HOST) goto discard_it; - /* - * Pull up the IP header. - */ - + /* Pull up the IP header. */ skb_pull(skb, skb->h.raw-skb->data); - /* - * Try to use the device checksum if provided. - */ - - switch (skb->ip_summed) - { + /* Try to use the device checksum if provided. */ + switch (skb->ip_summed) { case CHECKSUM_NONE: skb->csum = csum_partial((char *)th, len, 0); case CHECKSUM_HW: if (tcp_v4_check(th,len,saddr,daddr,skb->csum)) { struct iphdr * iph = skb->nh.iph; - printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, len=%d/%d/%d\n", + printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, ack = %u, seq = %u, len=%d/%d/%d\n", saddr, ntohs(th->source), daddr, + ntohl(th->ack_seq), ntohl(th->seq), ntohs(th->dest), len, skb->len, ntohs(iph->tot_len)); goto discard_it; } @@ -1243,7 +1247,6 @@ skb->end_seq = skb->seq + th->syn + th->fin + len - th->doff*4; skb->ack_seq = ntohl(th->ack_seq); - skb->acked = 0; skb->used = 0; if (!sk->sock_readers) @@ -1256,9 +1259,7 @@ tcp_v4_send_reset(skb); discard_it: - /* - * Discard frame - */ + /* Discard frame. */ kfree_skb(skb, FREE_READ); return 0; } @@ -1290,10 +1291,7 @@ skb->dst = &rt->u.dst; } - /* - * Discard the surplus MAC header - */ - + /* Discard the surplus MAC header. */ skb_pull(skb, skb->nh.raw-skb->data); iph = skb->nh.iph; @@ -1349,32 +1347,38 @@ tp->iat = (HZ/5) << 3; tp->rcv_wnd = 8192; + tp->tstamp_ok = 0; + tp->sack_ok = 0; + tp->in_mss = 0; + tp->snd_wscale = 0; + tp->sacks = 0; + tp->saw_tstamp = 0; /* * See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ tp->snd_cwnd = 1; - sk->ssthresh = 0x7fffffff; /* Infinity */ + tp->snd_ssthresh = 0x7fffffff; /* Infinity */ sk->priority = 1; sk->state = TCP_CLOSE; - /* this is how many unacked bytes we will accept for this socket. */ + /* This is how many unacked bytes we will accept for this socket. */ sk->max_unacked = 2048; /* needs to be at most 2 full packets. */ sk->max_ack_backlog = SOMAXCONN; sk->mtu = 576; sk->mss = 536; - /* - * Speed up by setting some standard state for the dummy_th. - */ - - sk->dummy_th.doff = sizeof(sk->dummy_th)/4; + /* Speed up by setting some standard state for the dummy_th. */ sk->dummy_th.ack=1; sk->dummy_th.doff=sizeof(struct tcphdr)>>2; + /* Init SYN queue. */ + tp->syn_wait_queue = NULL; + tp->syn_wait_last = &tp->syn_wait_queue; + sk->tp_pinfo.af_tcp.af_specific = &ipv4_specific; return 0; @@ -1387,27 +1391,15 @@ tcp_clear_xmit_timers(sk); if (sk->keepopen) - { tcp_dec_slow_timer(TCP_SLT_KEEPALIVE); - } - /* - * Cleanup up the write buffer. - */ - - while((skb = skb_dequeue(&sk->write_queue)) != NULL) { - IS_SKB(skb); + /* Cleanup up the write buffer. */ + while((skb = skb_dequeue(&sk->write_queue)) != NULL) kfree_skb(skb, FREE_WRITE); - } - - /* - * Cleans up our, hopefuly empty, out_of_order_queue - */ - while((skb = skb_dequeue(&sk->out_of_order_queue)) != NULL) { - IS_SKB(skb); + /* Cleans up our, hopefuly empty, out_of_order_queue. */ + while((skb = skb_dequeue(&sk->out_of_order_queue)) != NULL) kfree_skb(skb, FREE_READ); - } return 0; } diff -u --recursive --new-file v2.1.35/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c --- v2.1.35/linux/net/ipv4/tcp_output.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_output.c Tue Apr 22 22:46:28 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.34 1997/04/12 04:32:33 davem Exp $ + * Version: $Id: tcp_output.c,v 1.42 1997/04/22 01:06:33 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -34,14 +34,18 @@ #include -/* - * Get rid of any delayed acks, we sent one already.. - */ +extern int sysctl_tcp_sack; +extern int sysctl_tcp_tsack; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; + +/* Get rid of any delayed acks, we sent one already.. */ static __inline__ void clear_delayed_acks(struct sock * sk) { - sk->delayed_acks = 0; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + tp->delayed_acks = 0; sk->ack_backlog = 0; - sk->bytes_rcv = 0; tcp_clear_xmit_timer(sk, TIME_DACK); } @@ -50,12 +54,8 @@ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; tp->send_head = tp->send_head->next; - if (tp->send_head == (struct sk_buff *) &sk->write_queue) - { tp->send_head = NULL; - } - } static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb) @@ -64,8 +64,7 @@ int nagle_check = 1; int len; - /* - * RFC 1122 - section 4.2.3.4 + /* RFC 1122 - section 4.2.3.4 * * We must queue if * @@ -76,17 +75,41 @@ * 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) && atomic_read(&sk->packets_out)) - { + if (!sk->nonagle && len < (sk->mss >> 1) && tp->packets_out) nagle_check = 0; - } - return (nagle_check && atomic_read(&sk->packets_out) < tp->snd_cwnd && + return (nagle_check && tp->packets_out < tp->snd_cwnd && !after(skb->end_seq, tp->snd_una + tp->snd_wnd) && - atomic_read(&sk->retransmits) == 0); + tp->retransmits == 0); +} + +static __inline__ void tcp_build_options(__u32 *ptr, struct tcp_opt *tp) +{ + /* FIXME: We will still need to do SACK here. */ + if (tp->tstamp_ok) { + *ptr++ = ntohl((TCPOPT_NOP << 24) + | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) + | TCPOLEN_TIMESTAMP); + /* WARNING: If HZ is ever larger than 1000 on some system, + * then we will be violating RFC1323 here because our timestamps + * will be moving too fast. + * FIXME: code TCP so it uses at most ~ 1000 ticks a second? + * (I notice alpha is 1024 ticks now). -- erics + */ + *ptr++ = htonl(jiffies); + *ptr = htonl(tp->ts_recent); + } +} + +static __inline__ void tcp_update_options(__u32 *ptr, struct tcp_opt *tp) +{ + /* FIXME: We will still need to do SACK here. */ + if (tp->tstamp_ok) { + *++ptr = htonl(jiffies); + *++ptr = htonl(tp->ts_recent); + } } /* @@ -100,75 +123,56 @@ 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 (size == sizeof(struct tcphdr)) - { - /* - * If it's got a syn or fin discard - */ - if(!th->syn && !th->fin) - { + /* 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) { 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; - atomic_inc(&sk->packets_out); + tp->packets_out++; skb->when = jiffies; @@ -182,19 +186,13 @@ } queue: - /* - * Remember where we must start sending - */ - + /* Remember where we must start sending. */ if (tp->send_head == NULL) tp->send_head = skb; - - if (atomic_read(&sk->packets_out) == 0 && !tp->pending) - { + if (tp->packets_out == 0 && !tp->pending) { tp->pending = TIME_PROBE0; tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); } - return 0; } @@ -215,86 +213,61 @@ th = skb->h.th; - /* size of new segment */ - nsize = skb->tail - ((unsigned char *) (th + 1)) - len; - - if (nsize <= 0) - { + /* Size of new segment. */ + nsize = skb->tail - ((unsigned char *)(th)+tp->tcp_header_len) - len; + if (nsize <= 0) { printk(KERN_DEBUG "tcp_fragment: bug size <= 0\n"); return -1; } - /* - * Get a new skb... force flag on - */ + /* Get a new skb... force flag on. */ buff = sock_wmalloc(sk, nsize + 128 + sk->prot->max_header + 15, 1, GFP_ATOMIC); - if (buff == NULL) return -1; - /* - * Put headers on the new packet - */ - + /* Put headers on the new packet. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); return -1; } - /* - * Move the TCP header over - */ - - nth = (struct tcphdr *) skb_put(buff, sizeof(*th)); - + /* Move the TCP header over. */ + nth = (struct tcphdr *) skb_put(buff, tp->tcp_header_len); buff->h.th = nth; + memcpy(nth, th, tp->tcp_header_len); + + /* FIXME: Make sure this gets tcp options right. */ - memcpy(nth, th, sizeof(*th)); - - /* - * Correct the new header - */ - + /* Correct the new header. */ buff->seq = skb->seq + len; buff->end_seq = skb->end_seq; nth->seq = htonl(buff->seq); nth->check = 0; - nth->doff = 5; + nth->doff = th->doff; /* urg data is always an headache */ - if (th->urg) - { - if (th->urg_ptr > len) - { + if (th->urg) { + if (th->urg_ptr > len) { th->urg = 0; nth->urg_ptr -= len; - } - else - { + } else { nth->urg = 0; } } - /* - * Copy TCP options and data start to our new buffer - */ - - buff->csum = csum_partial_copy(((u8 *)(th + 1)) + len, + /* Copy data tail to our new buffer. */ + buff->csum = csum_partial_copy(((u8 *)(th)+tp->tcp_header_len) + len, skb_put(buff, nsize), nsize, 0); - skb->end_seq -= nsize; - skb_trim(skb, skb->len - nsize); - /* remember to checksum this packet afterwards */ + /* Remember to checksum this packet afterwards. */ th->check = 0; - skb->csum = csum_partial((u8*) (th + 1), skb->tail - ((u8 *) (th + 1)), + skb->csum = csum_partial((u8*)(th) + tp->tcp_header_len, skb->tail - ((u8 *) (th)+tp->tcp_header_len), 0); skb_append(skb, buff); @@ -304,12 +277,10 @@ static void tcp_wrxmit_prob(struct sock *sk, struct sk_buff *skb) { - /* - * This is acked data. We can discard it. This - * cannot currently occur. - */ + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - atomic_set(&sk->retransmits, 0); + /* This is acked data. We can discard it. This cannot currently occur. */ + tp->retransmits = 0; printk(KERN_DEBUG "tcp_write_xmit: bug skb in write queue\n"); @@ -329,17 +300,13 @@ 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; - atomic_dec(&sk->packets_out); + tp->packets_out--; return -1; - } - else - { - /* - * If tcp_fragment succeded then + } else { + /* If tcp_fragment succeded then * the send head is the resulting * fragment */ @@ -357,69 +324,52 @@ void tcp_write_xmit(struct sock *sk) { struct sk_buff *skb; - struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); u16 rcv_wnd; int sent_pkts = 0; - /* - * The bytes will have to remain here. In time closedown will - * empty the write queue and all will be happy + /* The bytes will have to remain here. In time closedown will + * empty the write queue and all will be happy. */ - if(sk->zapped) return; - /* - * Anything on the transmit queue that fits the window can + /* Anything on the transmit queue that fits the window can * be added providing we are: * * a) following SWS avoidance [and Nagle algorithm] * b) not exceeding our congestion window. * c) not retransmiting [Nagle] */ - rcv_wnd = htons(tcp_select_window(sk)); - - while((skb = tp->send_head) && tcp_snd_test(sk, skb)) - { + while((skb = tp->send_head) && tcp_snd_test(sk, skb)) { struct tcphdr *th; struct sk_buff *buff; int size; - IS_SKB(skb); - - /* - * See if we really need to send the packet. - * (debugging code) - */ - - if (!after(skb->end_seq, tp->snd_una)) - { + /* See if we really need to send the packet. (debugging code) */ + if (!after(skb->end_seq, tp->snd_una)) { tcp_wrxmit_prob(sk, skb); continue; - } - + } - /* - * Put in the ack seq and window at this point rather + /* Put in the ack seq and window at this point rather * than earlier, in order to keep them monotonic. * We really want to avoid taking back window allocations. * That's legal, but RFC1122 says it's frowned on. * Ack and window will in general have changed since * this packet was put on the write queue. */ - th = skb->h.th; size = skb->len - (((unsigned char *) th) - skb->data); - - if (size - (th->doff << 2) > sk->mss) - { + if (size - (th->doff << 2) > sk->mss) { if (tcp_wrxmit_frag(sk, skb, size)) break; } - th->ack_seq = htonl(tp->rcv_nxt); + tp->last_ack_sent = th->ack_seq = htonl(tp->rcv_nxt); th->window = rcv_wnd; + tcp_update_options((__u32 *)(th+1),tp); tp->af_specific->send_check(sk, th, size, skb); @@ -430,18 +380,14 @@ #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); - atomic_inc(&sk->packets_out); + tp->packets_out++; skb_set_owner_w(buff, sk); tp->snd_nxt = skb->end_seq; @@ -450,13 +396,10 @@ sent_pkts = 1; tp->af_specific->queue_xmit(buff); - } if (sent_pkts && !tcp_timer_is_set(sk, TIME_RETRANS)) - { tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); - } } @@ -469,33 +412,25 @@ * 2. We limit memory per socket */ - unsigned short tcp_select_window(struct sock *sk) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; int mss = sk->mss; long free_space = sock_rspace(sk); - long window; - long cur_win; - long usable; + long window, cur_win, usable; - - if (sk->window_clamp) - { - free_space = min(sk->window_clamp, free_space); - mss = min(sk->window_clamp, mss); + if (tp->window_clamp) { + free_space = min(tp->window_clamp, free_space); + mss = min(tp->window_clamp, mss); } - /* - * compute the actual window i.e. + /* compute the actual window i.e. * old_window - received_bytes_on_that_win */ - cur_win = tp->rcv_wup - (tp->rcv_nxt - tp->rcv_wnd); window = tp->rcv_wnd; - if ( cur_win < 0 ) - { + if (cur_win < 0) { cur_win = 0; printk(KERN_DEBUG "TSW: win < 0 w=%d 1=%u 2=%u\n", tp->rcv_wnd, tp->rcv_nxt, tp->rcv_wup); @@ -511,49 +446,33 @@ * it MSS bytes */ - /* - * It would be a good idea if it didn't break header prediction. + /* It would be a good idea if it didn't break header prediction. * and BSD made the header predition standard... * It expects the same value in the header i.e. th->window to be * constant */ - usable = free_space - cur_win; if (usable < 0) - { usable = 0; - } - if ( window < usable ) - { - /* - * Window is not blocking the sender + if (window < usable) { + /* Window is not blocking the sender * and we have enought free space for it */ - if (cur_win > (sk->mss << 1)) goto out; } - - if (window >= usable) - { - /* - * We are offering too much, cut it down... + if (window >= usable) { + /* We are offering too much, cut it down... * but don't shrink the window */ - window = max(usable, cur_win); - } - else - { + } else { if ((usable - window) >= mss) - { window += mss; - } } - - out: +out: tp->rcv_wnd = window; tp->rcv_wup = tp->rcv_nxt; return window; @@ -561,6 +480,7 @@ static int tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct tcphdr *th1, *th2; int size1, size2, avail; struct sk_buff *buff = skb->next; @@ -572,54 +492,35 @@ 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); - atomic_dec(&sk->packets_out); + tp->packets_out--; - /* - * Header checksum will be set by the retransmit procedure - * after calling rebuild header + /* Header checksum will be set by the retransmit procedure + * after calling rebuild header. */ - th1->check = 0; - skb->csum = csum_partial((u8*) (th1+1), size1 + size2, 0); - + skb->csum = csum_partial((u8*)(th1)+(th1->doff<<2), size1 + size2, 0); return 0; } @@ -643,17 +544,13 @@ if (tp->retrans_head == tp->send_head) tp->retrans_head = NULL; - while ((skb = tp->retrans_head) != NULL) - { + while ((skb = tp->retrans_head) != NULL) { struct sk_buff *buff; struct tcphdr *th; int tcp_size; int size; - IS_SKB(skb); - - /* - * In general it's OK just to use the old packet. However we + /* In general it's OK just to use the old packet. However we * need to use the current ack and window fields. Urg and * urg_ptr could possibly stand to be updated as well, but we * don't keep the necessary data. That shouldn't be a problem, @@ -663,28 +560,23 @@ 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; } - atomic_inc(&sk->packets_out); + tp->packets_out++; } if (!th->syn && tcp_size < (sk->mss >> 1) && skb->next != tp->send_head && skb->next != (struct sk_buff *)&sk->write_queue) - { tcp_retrans_try_collapse(sk, skb); - } - if (tp->af_specific->rebuild_header(sk, skb)) - { + if (tp->af_specific->rebuild_header(sk, skb)) { #ifdef TCP_DEBUG printk(KERN_DEBUG "tcp_do_rebuild_header failed\n"); #endif @@ -693,12 +585,10 @@ SOCK_DEBUG(sk, "retransmit sending\n"); - /* - * update ack and window - */ - - th->ack_seq = htonl(tp->rcv_nxt); + /* Update ack and window. */ + tp->last_ack_sent = th->ack_seq = htonl(tp->rcv_nxt); th->window = ntohs(tcp_select_window(sk)); + tcp_update_options((__u32 *)(th+1),tp); size = skb->tail - (unsigned char *) th; tp->af_specific->send_check(sk, th, size, skb); @@ -706,49 +596,32 @@ skb->when = jiffies; buff = skb_clone(skb, GFP_ATOMIC); - if (buff == NULL) break; + skb_set_owner_w(buff, sk); clear_delayed_acks(sk); - tp->af_specific->queue_xmit(buff); - /* - * Count retransmissions - */ - + /* Count retransmissions. */ ct++; - sk->prot->retransmits++; /* ???: atomic_t necessary here? -DaveM */ + sk->prot->retransmits++; tcp_statistics.TcpRetransSegs++; - tp->high_seq = tp->snd_nxt; - - /* - * Only one retransmit requested. - */ - + /* Only one retransmit requested. */ if (!all) break; - /* - * This should cut it off before we send too many packets. - */ - + /* This should cut it off before we send too many packets. */ if (ct >= tp->snd_cwnd) break; - /* - * Advance the pointer - */ - + /* Advance the pointer. */ tp->retrans_head = skb->next; if ((tp->retrans_head == tp->send_head) || (tp->retrans_head == (struct sk_buff *) &sk->write_queue)) - { tp->retrans_head = NULL; - } } } @@ -764,53 +637,40 @@ struct sk_buff *buff; int tmp; - - buff = sock_wmalloc(sk, MAX_RESET_SIZE, 1, GFP_KERNEL); - - if (buff == NULL) - { - /* This is a disaster if it occurs */ + buff = sock_wmalloc(sk, BASE_ACK_SIZE + tp->tcp_header_len, 1, GFP_KERNEL); + if (buff == NULL) { + /* FIXME: This is a disaster if it occurs. */ printk(KERN_INFO "tcp_send_fin: Impossible malloc failure"); return; } - /* - * Administrivia - */ - + /* Administrivia. */ buff->csum = 0; - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { int t; - /* - * Finish anyway, treat this as a send that got lost. - * (Not good). + + /* FIXME: We must not throw this out. Eventually we must + * put a FIN into the queue, otherwise it never gets queued. */ - kfree_skb(buff, FREE_WRITE); sk->write_seq++; - t=del_timer(&sk->timer); - if(t) + t = del_timer(&sk->timer); + if (t) add_timer(&sk->timer); else tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); return; } - /* - * We ought to check if the end of the queue is a buffer and - * if so simply add the fin to that buffer, not send it ahead. + /* We ought to check if the end of the queue is a buffer and + * if so simply add the fin to that buffer, not send it ahead. */ - - t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr)); + t1 =(struct tcphdr *)skb_put(buff,tp->tcp_header_len); buff->h.th = t1; + tcp_build_options((__u32 *)(t1+1),tp); memcpy(t1, th, sizeof(*t1)); buff->seq = sk->write_seq; @@ -821,26 +681,19 @@ 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; - atomic_inc(&sk->packets_out); + tp->packets_out++; tp->snd_nxt = sk->write_seq; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); - - if (skb1) - { + if (skb1) { skb_set_owner_w(skb1, sk); tp->af_specific->queue_xmit(skb1); } @@ -856,20 +709,14 @@ struct sk_buff * skb; struct sk_buff * buff; struct tcphdr *th; - unsigned char *ptr; int tmp; skb = sock_wmalloc(sk, MAX_SYN_SIZE, 1, GFP_ATOMIC); - if (skb == NULL) - { return -ENOMEM; - } tmp = tp->af_specific->build_net_header(sk, skb); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(skb, FREE_WRITE); return tmp; } @@ -890,27 +737,23 @@ 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); - atomic_inc(&sk->packets_out); + tp->packets_out++; skb->when = jiffies; tp->af_specific->queue_xmit(buff); @@ -935,22 +778,19 @@ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; unsigned long timeout, now; - /* Calculate new timeout */ + /* Calculate new timeout. */ now = jiffies; timeout = tp->ato; - if (timeout > max_timeout || sk->bytes_rcv > (sk->mss << 2)) - { + if (timeout > max_timeout || + ((tp->rcv_nxt - tp->rcv_wup) > (sk->mss << 2))) timeout = now; - } else timeout += now; - /* Use new timeout only if there wasn't a older one earlier */ + /* Use new timeout only if there wasn't a older one earlier. */ if (!del_timer(&tp->delack_timer) || timeout < tp->delack_timer.expires) - { tp->delack_timer.expires = timeout; - } add_timer(&tp->delack_timer); } @@ -968,75 +808,53 @@ struct tcphdr *th; int tmp; - if(sk->zapped) - { - /* We have been reset, we may not send again */ - return; - } + return; /* We have been reset, we may not send again. */ - /* - * We need to grab some memory, and put together an ack, + /* We need to grab some memory, and put together an ack, * and then put it into the queue to be sent. + * FIXME: is it better to waste memory here and use a + * constant sized ACK? */ - - buff = sock_wmalloc(sk, MAX_ACK_SIZE, 1, GFP_ATOMIC); - if (buff == NULL) - { - /* - * Force it to send an ack. We don't have to do this - * (ACK is unreliable) but it's much better use of + buff = sock_wmalloc(sk, BASE_ACK_SIZE + tp->tcp_header_len, 1, GFP_ATOMIC); + if (buff == NULL) { + /* Force it to send an ack. We don't have to do this + * (ACK is unreliable) but it's much better use of * bandwidth on slow links to send a spare ack than - * resend packets. + * resend packets. */ - tcp_send_delayed_ack(sk, HZ/2); return; } clear_delayed_acks(sk); - /* - * Assemble a suitable TCP frame - */ - + /* Assemble a suitable TCP frame. */ buff->csum = 0; - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); return; } - th =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr)); - + th = (struct tcphdr *)skb_put(buff,tp->tcp_header_len); memcpy(th, &sk->dummy_th, sizeof(struct tcphdr)); + tcp_build_options((__u32 *)(th+1),tp); - /* - * Swap the send and the receive. - */ - + /* Swap the send and the receive. */ th->window = ntohs(tcp_select_window(sk)); th->seq = ntohl(tp->snd_nxt); - th->ack_seq = ntohl(tp->rcv_nxt); - - /* - * Fill in the packet and send it - */ + tp->last_ack_sent = th->ack_seq = ntohl(tp->rcv_nxt); - tp->af_specific->send_check(sk, th, sizeof(struct tcphdr), buff); + /* Fill in the packet and send it. */ + tp->af_specific->send_check(sk, th, tp->tcp_header_len, buff); SOCK_DEBUG(sk, "\rtcp_send_ack: seq %x ack %x\n", tp->snd_nxt, tp->rcv_nxt); tp->af_specific->queue_xmit(buff); - tcp_statistics.TcpOutSegs++; } @@ -1053,61 +871,44 @@ 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); - atomic_inc(&sk->packets_out); + tp->packets_out++; clear_delayed_acks(sk); @@ -1115,36 +916,29 @@ tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); skb->when = jiffies; - update_send_head(sk); - tp->snd_nxt = skb->end_seq; - } - else - { - buff = sock_wmalloc(sk,MAX_ACK_SIZE, 1, GFP_ATOMIC); + } else { + buff = sock_wmalloc(sk, MAX_ACK_SIZE, 1, GFP_ATOMIC); if (buff == NULL) return; buff->csum = 0; - /* - * Put in the IP header and routing stuff. - */ - + /* Put in the IP header and routing stuff. */ tmp = tp->af_specific->build_net_header(sk, buff); - - if (tmp < 0) - { + if (tmp < 0) { kfree_skb(buff, FREE_WRITE); return; } t1 = (struct tcphdr *) skb_put(buff, sizeof(struct tcphdr)); memcpy(t1,(void *) &sk->dummy_th, sizeof(*t1)); + /* FIXME: should zero window probes have SACK and/or TIMESTAMP data? + * If so we have to tack them on here. + */ - /* - * Use a previous sequence. + /* Use a previous sequence. * This should cause the other end to send an ack. */ @@ -1153,13 +947,13 @@ t1->ack_seq = htonl(tp->rcv_nxt); t1->window = htons(tcp_select_window(sk)); + /* Value from dummy_th may be larger. */ + t1->doff = sizeof(struct tcphdr)/4; + tp->af_specific->send_check(sk, t1, sizeof(*t1), buff); } - /* - * Send it. - */ - + /* Send it. */ tp->af_specific->queue_xmit(buff); tcp_statistics.TcpOutSegs++; } @@ -1175,16 +969,12 @@ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); if (sk->zapped) - return; /* After a valid reset we can send no more */ - + return; /* After a valid reset we can send no more. */ tcp_write_wakeup(sk); - tp->pending = TIME_PROBE0; - tp->backoff++; tp->probes_out++; - tcp_reset_xmit_timer (sk, TIME_PROBE0, min(tp->rto << tp->backoff, 120*HZ)); } diff -u --recursive --new-file v2.1.35/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c --- v2.1.35/linux/net/ipv4/tcp_timer.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_timer.c Tue Apr 22 22:46:28 1997 @@ -34,8 +34,8 @@ struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX] = { - {ATOMIC_INIT, TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK */ - {ATOMIC_INIT, TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive} /* KEEPALIVE */ + {ATOMIC_INIT(0), TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK */ + {ATOMIC_INIT(0), TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive} /* KEEPALIVE */ }; /* @@ -67,16 +67,14 @@ { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - if((long)when <= 0) - { + if((long)when <= 0) { printk(KERN_DEBUG "xmit_timer <= 0 - timer:%d when:%lx\n", what, when); when=HZ/50; } switch (what) { case TIME_RETRANS: - /* - * When seting the transmit timer the probe timer + /* When seting the transmit timer the probe timer * should not be set. * The delayed ack timer can be set if we are changing the * retransmit timer when removing acked frames. @@ -105,7 +103,7 @@ default: printk(KERN_DEBUG "bug: unknown timer value\n"); - } + }; } void tcp_clear_xmit_timer(struct sock *sk, int what) @@ -124,7 +122,7 @@ break; default: printk(KERN_DEBUG "bug: unknown timer value\n"); - } + }; } int tcp_timer_is_set(struct sock *sk, int what) @@ -143,7 +141,7 @@ break; default: printk(KERN_DEBUG "bug: unknown timer value\n"); - } + }; return 0; } @@ -162,28 +160,25 @@ static int tcp_write_timeout(struct sock *sk) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + /* * Look for a 'soft' timeout. */ if ((sk->state == TCP_ESTABLISHED && - atomic_read(&sk->retransmits) && - !(atomic_read(&sk->retransmits) & 7)) || - (sk->state != TCP_ESTABLISHED && - atomic_read(&sk->retransmits) > TCP_RETR1)) - { - /* - * Attempt to recover if arp has changed (unlikely!) or + + /* Eric, what the heck is this doing?!?! */ + tp->retransmits && !(tp->retransmits & 7)) || + + (sk->state != TCP_ESTABLISHED && tp->retransmits > TCP_RETR1)) { + /* Attempt to recover if arp has changed (unlikely!) or * a route has shifted (not supported prior to 1.3). */ ip_rt_advice((struct rtable**)&sk->dst_cache, 0); } - /* - * Have we tried to SYN too many times (repent repent 8)) - */ - - if(atomic_read(&sk->retransmits) > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT) - { + /* Have we tried to SYN too many times (repent repent 8)) */ + if(tp->retransmits > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT) { if(sk->err_soft) sk->err=sk->err_soft; else @@ -199,11 +194,9 @@ /* Don't FIN, we got nothing back */ return 0; } - /* - * Has it gone just too far ? - */ - if (atomic_read(&sk->retransmits) > TCP_RETR2) - { + + /* Has it gone just too far? */ + if (tp->retransmits > TCP_RETR2) { if(sk->err_soft) sk->err = sk->err_soft; else @@ -212,19 +205,12 @@ tcp_clear_xmit_timers(sk); - /* - * Time wait the socket - */ - if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING ) - { + /* Time wait the socket. */ + if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING) { tcp_set_state(sk,TCP_TIME_WAIT); tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); - } - else - { - /* - * Clean up time. - */ + } else { + /* Clean up time. */ tcp_set_state(sk, TCP_CLOSE); return 0; } @@ -238,14 +224,10 @@ struct sock *sk = (struct sock*)data; if(sk->zapped) - { return; - } - if (sk->delayed_acks) - { + if (sk->tp_pinfo.af_tcp.delayed_acks) tcp_read_wakeup(sk); - } } void tcp_probe_timer(unsigned long data) { @@ -254,16 +236,10 @@ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; if(sk->zapped) - { return; - } - if (sk->sock_readers) - { - /* - * Try again in second - */ - + if (sk->sock_readers) { + /* Try again in second. */ tcp_reset_xmit_timer(sk, TIME_PROBE0, HZ); return; } @@ -273,28 +249,20 @@ * FIXME: We ought not to do it, Solaris 2.5 actually has fixing * this behaviour in Solaris down as a bug fix. [AC] */ - if (tp->probes_out > TCP_RETR2) - { + if (tp->probes_out > TCP_RETR2) { if(sk->err_soft) sk->err = sk->err_soft; else sk->err = ETIMEDOUT; sk->error_report(sk); - /* - * Time wait the socket - */ + /* Time wait the socket. */ if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 - || sk->state == TCP_CLOSING ) - { + || sk->state == TCP_CLOSING) { tcp_set_state(sk, TCP_TIME_WAIT); tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); - } - else - { - /* - * Clean up time. - */ + } else { + /* Clean up time. */ tcp_set_state(sk, TCP_CLOSE); } } @@ -307,24 +275,19 @@ int res = 0; if (sk->state == TCP_ESTABLISHED || sk->state == TCP_CLOSE_WAIT || - sk->state == TCP_FIN_WAIT2) - { + sk->state == TCP_FIN_WAIT2) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; __u32 elapsed = jiffies - tp->rcv_tstamp; - if (elapsed >= TCP_KEEPALIVE_TIME) - { - if (tp->probes_out > TCP_KEEPALIVE_PROBES) - { + if (elapsed >= TCP_KEEPALIVE_TIME) { + if (tp->probes_out > TCP_KEEPALIVE_PROBES) { if(sk->err_soft) sk->err = sk->err_soft; else sk->err = ETIMEDOUT; tcp_set_state(sk, TCP_CLOSE); - } - else - { + } else { tp->probes_out++; tp->pending = TIME_KEEPOPEN; tcp_write_wakeup(sk); @@ -354,6 +317,16 @@ /* Keepopen's are only valid for "established" TCP's, nicely our listener * hash gets rid of most of the useless testing, so we run through a couple * of the established hash chains each clock tick. -DaveM + * + * And now, even more magic... TIME_WAIT TCP's cannot have keepalive probes + * going off for them, so we only need check the first half of the established + * hash table, even less testing under heavy load. + * + * I _really_ would rather do this by adding a new timer_struct to struct sock, + * and this way only those who set the keepalive option will get the overhead. + * The idea is you set it for 2 hours when the sock is first connected, when it + * does fire off (if at all, most sockets die earlier) you check for the keepalive + * option and also if the sock has been idle long enough to start probing. */ static void tcp_keepalive(unsigned long data) { @@ -361,7 +334,7 @@ int count = 0; int i; - for(i = chain_start; i < (chain_start + (TCP_HTABLE_SIZE >> 2)); i++) { + for(i = chain_start; i < (chain_start + ((TCP_HTABLE_SIZE/2) >> 2)); i++) { struct sock *sk = tcp_established_hash[i]; while(sk) { if(sk->keepopen) { @@ -373,7 +346,8 @@ } } out: - chain_start = ((chain_start + (TCP_HTABLE_SIZE>>2)) & (TCP_HTABLE_SIZE - 1)); + chain_start = ((chain_start + ((TCP_HTABLE_SIZE/2)>>2)) & + ((TCP_HTABLE_SIZE/2) - 1)); } /* @@ -394,48 +368,35 @@ struct sock *sk = (struct sock*)data; struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - /* - * We are reset. We will send no more retransmits. - */ - - if(sk->zapped) - { + /* We are reset. We will send no more retransmits. */ + if(sk->zapped) { tcp_clear_xmit_timer(sk, TIME_RETRANS); return; } lock_sock(sk); - /* - * Clear delay ack timer - */ - + /* Clear delay ack timer. */ tcp_clear_xmit_timer(sk, TIME_DACK); - /* - * Retransmission - */ - + /* Retransmission. */ tp->retrans_head = NULL; - - if (atomic_read(&sk->retransmits) == 0) - { - /* - * remember window where we lost + if (tp->retransmits == 0) { + /* remember window where we lost * "one half of the current window but at least 2 segments" */ - - sk->ssthresh = max(tp->snd_cwnd >> 1, 2); - sk->cong_count = 0; + tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2); + tp->snd_cwnd_cnt = 0; tp->snd_cwnd = 1; } - atomic_inc(&sk->retransmits); + tp->retransmits++; + tp->dup_acks = 0; + tp->high_seq = tp->snd_nxt; tcp_do_retransmit(sk, 0); - /* - * Increase the timeout each time we retransmit. Note that + /* Increase the timeout each time we retransmit. Note that * we do not increase the rtt estimate. rto is initialized * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests * that doubling rto each time is the least we can get away with. @@ -450,8 +411,7 @@ * implemented ftp to mars will work nicely. We will have to fix * the 120 second clamps though! */ - - tp->backoff++; + tp->backoff++; /* FIXME: always same as retransmits? -- erics */ tp->rto = min(tp->rto << 1, 120*HZ); tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); @@ -521,7 +481,7 @@ conn->expires = now + timeo; tcp_synq_queue(tp, conn); } - } while (req != tp->syn_wait_queue); + } while (req); } sk = sk->next; } @@ -535,16 +495,13 @@ unsigned long now = jiffies; int i; - for (i=0; i < TCP_SLT_MAX; i++, slt++) - { - if (atomic_read(&slt->count)) - { + for (i=0; i < TCP_SLT_MAX; i++, slt++) { + if (atomic_read(&slt->count)) { long trigger; trigger = slt->period - ((long)(now - slt->last)); - if (trigger <= 0) - { + if (trigger <= 0) { (*slt->handler)((unsigned long) slt); slt->last = now; trigger = slt->period; @@ -553,8 +510,7 @@ } } - if (next != ~0UL) - { + if (next != ~0UL) { tcp_slow_timer.expires = now + next; add_timer(&tcp_slow_timer); } @@ -570,13 +526,10 @@ when = now + slt->period; if (del_timer(&tcp_slow_timer)) - { next = tcp_slow_timer.expires; - } + if (next && ((long)(next - when) < 0)) - { when = next; - } tcp_slow_timer.expires = when; add_timer(&tcp_slow_timer); diff -u --recursive --new-file v2.1.35/linux/net/ipv4/udp.c linux/net/ipv4/udp.c --- v2.1.35/linux/net/ipv4/udp.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/udp.c Tue Apr 22 22:46:28 1997 @@ -446,10 +446,16 @@ kfree_skb(skb2, FREE_READ); } - if (type == ICMP_SOURCE_QUENCH) - { /* Slow down! */ + if (type == ICMP_SOURCE_QUENCH) { +#if 0 /* FIXME: If you check the rest of the code, this is a NOP! + * Someone figure out what we were trying to be doing + * here. Besides, cong_window is a TCP thing and thus + * I moved it out of normal sock and into tcp_opt. + */ + /* Slow down! */ if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2; +#endif return; } diff -u --recursive --new-file v2.1.35/linux/net/ipv6/addrconf.c linux/net/ipv6/addrconf.c --- v2.1.35/linux/net/ipv6/addrconf.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/addrconf.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: addrconf.c,v 1.16 1997/04/12 04:32:44 davem Exp $ + * $Id: addrconf.c,v 1.18 1997/04/16 05:58:03 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -69,7 +69,7 @@ */ struct inet6_dev *inet6_dev_lst[IN6_ADDR_HSIZE]; -static atomic_t addr_list_lock = ATOMIC_INIT; +static atomic_t addr_list_lock = ATOMIC_INIT(0); void addrconf_verify(unsigned long); diff -u --recursive --new-file v2.1.35/linux/net/ipv6/ipv6_sockglue.c linux/net/ipv6/ipv6_sockglue.c --- v2.1.35/linux/net/ipv6/ipv6_sockglue.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/ipv6_sockglue.c Tue Apr 22 22:46:28 1997 @@ -7,7 +7,7 @@ * * Based on linux/net/ipv4/ip_sockglue.c * - * $Id: ipv6_sockglue.c,v 1.9 1997/04/07 06:55:51 davem Exp $ + * $Id: ipv6_sockglue.c,v 1.11 1997/04/20 09:44:33 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -53,7 +53,7 @@ struct ipv6_mib ipv6_statistics={0, }; struct packet_type ipv6_packet_type = { - 0, + __constant_htons(ETH_P_IPV6), NULL, /* All devices */ ipv6_rcv, NULL, @@ -241,8 +241,6 @@ void ipv6_init(void) { - ipv6_packet_type.type = ntohs(ETH_P_IPV6); - dev_add_pack(&ipv6_packet_type); #if defined(MODULE) && defined(CONFIG_SYSCTL) diff -u --recursive --new-file v2.1.35/linux/net/ipv6/proc.c linux/net/ipv6/proc.c --- v2.1.35/linux/net/ipv6/proc.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/proc.c Tue Apr 22 22:46:28 1997 @@ -7,7 +7,7 @@ * PROC file system. This is very similar to the IPv4 version, * except it reports the sockets in the INET6 address family. * - * Version: $Id: proc.c,v 1.2 1997/04/12 04:32:55 davem Exp $ + * Version: $Id: proc.c,v 1.4 1997/04/20 22:50:44 schenk Exp $ * * Authors: David S. Miller (davem@caip.rutgers.edu) * @@ -61,15 +61,15 @@ destp = ntohs(sp->dummy_th.dest); srcp = ntohs(sp->dummy_th.source); - timer_active1 = del_timer(&sp->retransmit_timer); + timer_active1 = del_timer(&tp->retransmit_timer); timer_active2 = del_timer(&sp->timer); - if(!timer_active1) sp->retransmit_timer.expires = 0; + if(!timer_active1) tp->retransmit_timer.expires = 0; if(!timer_active2) sp->timer.expires = 0; timer_active = 0; timer_expires = (unsigned) -1; - if(timer_active1 && sp->retransmit_timer.expires < timer_expires) { + if(timer_active1 && tp->retransmit_timer.expires < timer_expires) { timer_active = timer_active1; - timer_expires = sp->retransmit_timer.expires; + timer_expires = tp->retransmit_timer.expires; } if(timer_active2 && sp->timer.expires < timer_expires) { timer_active = timer_active2; @@ -86,12 +86,12 @@ format==0?sp->write_seq-tp->snd_una:atomic_read(&sp->wmem_alloc), format==0?tp->rcv_nxt-sp->copied_seq:atomic_read(&sp->rmem_alloc), timer_active, timer_expires-jiffies, - (unsigned) atomic_read(&sp->retransmits), + tp->retransmits, sp->socket ? sp->socket->inode->i_uid:0, timer_active?sp->timeout:0, sp->socket ? sp->socket->inode->i_ino:0); - if(timer_active1) add_timer(&sp->retransmit_timer); + if(timer_active1) add_timer(&tp->retransmit_timer); if(timer_active2) add_timer(&sp->timer); len += sprintf(buffer+len, "%-148s\n", tmpbuf); if(len >= length) diff -u --recursive --new-file v2.1.35/linux/net/ipv6/route.c linux/net/ipv6/route.c --- v2.1.35/linux/net/ipv6/route.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/route.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: route.c,v 1.10 1997/04/12 04:32:57 davem Exp $ + * $Id: route.c,v 1.11 1997/04/16 05:58:05 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -62,7 +62,7 @@ }; struct rt6_info ip6_null_entry = { - {{NULL, ATOMIC_INIT, ATOMIC_INIT, NULL, + {{NULL, ATOMIC_INIT(0), ATOMIC_INIT(0), NULL, 0, 0, 0, 0, 0, 0, 0, 0, -ENETUNREACH, NULL, NULL, ip6_pkt_discard, ip6_pkt_discard, &ip6_dst_ops}}, NULL, {{{0}}}, 256, RTF_REJECT|RTF_NONEXTHOP, ~0UL, @@ -93,7 +93,7 @@ #define ip6_rt_policy (0) #endif -static atomic_t rt6_tbl_lock = ATOMIC_INIT; +static atomic_t rt6_tbl_lock = ATOMIC_INIT(0); static int rt6_bh_mask = 0; #define RT_BH_REQUEST 1 diff -u --recursive --new-file v2.1.35/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c --- v2.1.35/linux/net/ipv6/tcp_ipv6.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/tcp_ipv6.c Tue Apr 22 22:46:28 1997 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: tcp_ipv6.c,v 1.20 1997/04/13 10:31:48 davem Exp $ + * $Id: tcp_ipv6.c,v 1.27 1997/04/22 02:53:20 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -41,6 +41,10 @@ #include +extern int sysctl_tcp_sack; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; + static void tcp_v6_send_reset(struct in6_addr *saddr, struct in6_addr *daddr, struct tcphdr *th, struct proto *prot, @@ -65,7 +69,8 @@ hashent ^= (laddr->s6_addr32[0] ^ laddr->s6_addr32[1]); hashent ^= (faddr->s6_addr32[0] ^ faddr->s6_addr32[1]); - return (hashent & (TCP_HTABLE_SIZE - 1)); + hashent ^= (faddr->s6_addr32[2] ^ faddr->s6_addr32[3]); + return (hashent & ((TCP_HTABLE_SIZE/2) - 1)); } static __inline__ int tcp_v6_sk_hashfn(struct sock *sk) @@ -166,11 +171,14 @@ if(state != TCP_CLOSE) { struct sock **skp; - if(state == TCP_LISTEN) + if(state == TCP_LISTEN) { skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; - else - skp = &tcp_established_hash[tcp_v6_sk_hashfn(sk)]; - + } else { + int hash = tcp_v6_sk_hashfn(sk); + if(state == TCP_TIME_WAIT) + hash += (TCP_HTABLE_SIZE/2); + skp = &tcp_established_hash[hash]; + } if((sk->next = *skp) != NULL) (*skp)->pprev = &sk->next; *skp = sk; @@ -180,11 +188,12 @@ SOCKHASH_UNLOCK(); } -static struct sock *tcp_v6_lookup_longway(struct in6_addr *daddr, unsigned short hnum) +static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned short hnum) { - struct sock *sk = tcp_listening_hash[tcp_lhashfn(hnum)]; + struct sock *sk; struct sock *result = NULL; + sk = tcp_listening_hash[tcp_lhashfn(hnum)]; for(; sk; sk = sk->next) { if((sk->num == hnum) && (sk->family == AF_INET6)) { struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; @@ -207,13 +216,13 @@ { unsigned short hnum = ntohs(dport); struct sock *sk; + int hash = tcp_v6_hashfn(daddr, hnum, saddr, sport); /* Optimize here for direct hit, only listening connections can * have wildcards anyways. It is assumed that this code only * gets called from within NET_BH. */ - sk = tcp_established_hash[tcp_v6_hashfn(daddr, hnum, saddr, sport)]; - for(; sk; sk = sk->next) + for(sk = tcp_established_hash[hash]; sk; sk = sk->next) /* For IPV6 do the cheaper port and family tests first. */ if(sk->num == hnum && /* local port */ sk->family == AF_INET6 && /* address family */ @@ -221,7 +230,17 @@ !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.daddr, saddr) && !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr, daddr)) goto hit; /* You sunk my battleship! */ - sk = tcp_v6_lookup_longway(daddr, hnum); + + /* Must check for a TIME_WAIT'er before going to listener hash. */ + for(sk = tcp_established_hash[hash+(TCP_HTABLE_SIZE/2)]; sk; sk = sk->next) + if(sk->num == hnum && /* local port */ + sk->family == AF_INET6 && /* address family */ + sk->dummy_th.dest == sport && /* remote port */ + !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.daddr, saddr) && + !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr, daddr)) + goto hit; + + sk = tcp_v6_lookup_listener(daddr, hnum); hit: return sk; } @@ -267,7 +286,7 @@ struct tcphdr *th; struct sk_buff *buff; struct sk_buff *skb1; - __u8 *ptr; + int tmp; int addr_type; if (sk->state != TCP_CLOSE) @@ -369,6 +388,8 @@ ipv6_addr_copy(&np->saddr, saddr); } + /* FIXME: Need to do tcp_v6_unique_address() here! -DaveM */ + /* * Init variables */ @@ -413,9 +434,8 @@ th->ack = 0; th->window = 2; th->syn = 1; - th->doff = 6; - sk->window_clamp = 0; + tp->window_clamp = 0; sk->mtu = dst->pmtu; sk->mss = sk->mtu - sizeof(struct ipv6hdr) - sizeof(struct tcphdr); @@ -424,14 +444,12 @@ * Put in the TCP options to say MTU. */ - ptr = skb_put(buff,4); - ptr[0] = 2; - ptr[1] = 4; - ptr[2] = (sk->mss) >> 8; - ptr[3] = (sk->mss) & 0xff; - buff->csum = csum_partial(ptr, 4, 0); - - tcp_v6_send_check(sk, th, sizeof(struct tcphdr) + 4, buff); + tmp = tcp_syn_build_options(buff, sk->mss, sysctl_tcp_sack, + sysctl_tcp_timestamps, + sysctl_tcp_window_scaling?tp->rcv_wscale:0); + th->doff = sizeof(*th)/4 + (tmp>>2); + buff->csum = 0; + tcp_v6_send_check(sk, th, sizeof(struct tcphdr) + tmp, buff); tcp_set_state(sk, TCP_SYN_SENT); @@ -445,10 +463,10 @@ tcp_init_xmit_timers(sk); - atomic_set(&sk->retransmits, 0); + tp->retransmits = 0; skb_queue_tail(&sk->write_queue, buff); - atomic_inc(&sk->packets_out); + tp->packets_out++; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); skb_set_owner_w(skb1, sk); @@ -573,9 +591,9 @@ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; struct sk_buff * skb; struct tcphdr *th; - unsigned char *ptr; struct dst_entry *dst; struct flowi fl; + int tmp; skb = sock_wmalloc(sk, MAX_SYN_SIZE, 1, GFP_ATOMIC); if (skb == NULL) @@ -615,17 +633,12 @@ th->window = ntohs(tp->rcv_wnd); - /* FIXME: csum_partial() of a four byte quantity is itself! -DaveM */ - ptr = skb_put(skb, TCPOLEN_MSS); - ptr[0] = TCPOPT_MSS; - ptr[1] = TCPOLEN_MSS; - ptr[2] = (dst->pmtu >> 8) & 0xff; - ptr[3] = dst->pmtu & 0xff; - skb->csum = csum_partial(ptr, TCPOLEN_MSS, 0); - - th->check = tcp_v6_check(th, sizeof(*th) + TCPOLEN_MSS, + tmp = tcp_syn_build_options(skb, sk->mss, req->sack_ok, req->tstamp_ok, + (req->snd_wscale)?tp->rcv_wscale:0); + th->doff = sizeof(*th)/4 + (tmp>>2); + th->check = tcp_v6_check(th, sizeof(*th) + tmp, &req->af.v6_req.loc_addr, &req->af.v6_req.rmt_addr, - csum_partial((char *)th, sizeof(*th), skb->csum)); + csum_partial((char *)th, sizeof(*th)+tmp, skb->csum)); ip6_dst_store(sk, dst); ip6_xmit(sk, skb, &fl, req->af.v6_req.opt); @@ -646,6 +659,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 isn) { + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; struct open_request *req; __u16 req_mss; @@ -680,7 +694,8 @@ req->rcv_isn = skb->seq; req->snt_isn = isn; - req_mss = tcp_parse_options(skb->h.th); + tcp_parse_options(skb->h.th,tp); + req_mss = tp->in_mss; if (!req_mss) req_mss = 536; req->mss = req_mss; @@ -714,7 +729,7 @@ th->check = 0; th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, - csum_partial((char *)th, sizeof(*th), + csum_partial((char *)th, th->doff<<2, skb->csum)); } @@ -773,8 +788,6 @@ * Unused */ - newsk->send_head = NULL; - newtp = &(newsk->tp_pinfo.af_tcp); np = &newsk->net_pinfo.af_inet6; @@ -787,13 +800,13 @@ newsk->prot->init(newsk); - newsk->cong_count = 0; - newsk->ssthresh = 0; + newtp->snd_cwnd_cnt = 0; +#if 0 /* Don't mess up the initialization we did in the init routine! */ + newtp->snd_ssthresh = 0; +#endif newtp->backoff = 0; - newsk->intr = 0; newsk->proc = 0; newsk->done = 0; - newsk->partial = NULL; newsk->pair = NULL; atomic_set(&newsk->wmem_alloc, 0); atomic_set(&newsk->rmem_alloc, 0); @@ -805,24 +818,23 @@ 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; - atomic_set(&newsk->packets_out, 0); - atomic_set(&newsk->retransmits, 0); + newtp->packets_out = 0; + newtp->retransmits = 0; newsk->linger=0; newsk->destroy = 0; init_timer(&newsk->timer); @@ -861,13 +873,25 @@ ip6_dst_store(newsk, dst); + newtp->sack_ok = req->sack_ok; + newtp->tstamp_ok = req->tstamp_ok; + newtp->snd_wscale = req->snd_wscale; + newtp->ts_recent = req->ts_recent; + if (newtp->tstamp_ok) { + newtp->tcp_header_len = sizeof(struct tcphdr) + 12; /* FIXME: define the contant. */ + newsk->dummy_th.doff += 3; + } else { + newtp->tcp_header_len = sizeof(struct tcphdr); + } + if (dst->error) newsk->mtu = req->af.v6_req.dev->mtu; else newsk->mtu = dst->pmtu; - newsk->mss = min(req->mss, (newsk->mtu - sizeof(struct ipv6hdr) - - sizeof(struct tcphdr))); + newsk->mss = min(req->mss+sizeof(struct tcphdr)-newtp->tcp_header_len, + (newsk->mtu - sizeof(struct ipv6hdr) - newtp->tcp_header_len)); + /* XXX tp->window_clamp??? -DaveM */ newsk->daddr = LOOPBACK4_IPV6; newsk->saddr = LOOPBACK4_IPV6; @@ -957,7 +981,7 @@ if (!req) return sk; - do { + while(req) { if (!ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr) && !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr) && req->rmt_port == skb->h.th->source) { @@ -994,7 +1018,8 @@ req->sk = sk; break; } - } while ((req = req->dl_next) != tp->syn_wait_queue); + req = req->dl_next; + } return sk; } @@ -1057,7 +1082,6 @@ skb->end_seq = skb->seq + th->syn + th->fin + len - th->doff*4; skb->ack_seq = ntohl(th->ack_seq); - skb->acked = 0; skb->used = 0; } @@ -1286,7 +1310,7 @@ /* start with only sending one packet at a time. */ tp->snd_cwnd = 1; - sk->ssthresh = 0x7fffffff; + tp->snd_ssthresh = 0x7fffffff; sk->priority = 1; sk->state = TCP_CLOSE; @@ -1306,6 +1330,10 @@ sk->dummy_th.ack=1; sk->dummy_th.doff=sizeof(struct tcphdr)>>2; + /* Init SYN queue. */ + tp->syn_wait_queue = NULL; + tp->syn_wait_last = &tp->syn_wait_queue; + sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific; return 0; @@ -1325,19 +1353,15 @@ * 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 diff -u --recursive --new-file v2.1.35/linux/net/unix/af_unix.c linux/net/unix/af_unix.c --- v2.1.35/linux/net/unix/af_unix.c Mon Apr 14 16:28:29 1997 +++ linux/net/unix/af_unix.c Fri Apr 18 10:53:54 1997 @@ -936,6 +936,7 @@ if (scm->fp) unix_attach_fds(scm, skb); + skb->h.raw = skb->data; memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); other = unix_peer(sk);