diff -u --recursive --new-file v2.1.36/linux/Documentation/00-INDEX linux/Documentation/00-INDEX --- v2.1.36/linux/Documentation/00-INDEX Wed Jan 15 18:46:05 1997 +++ linux/Documentation/00-INDEX Tue Apr 29 11:45:43 1997 @@ -26,6 +26,8 @@ - plain ASCII listing of all the nodes in /dev/ with major minor #'s digiboard.txt - info on the Digiboard PC/X{i,e,eve} multiport boards. +digiepca.txt + - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards. exception.txt - how linux v2.1 handles exceptions without verify_area etc. ez.txt diff -u --recursive --new-file v2.1.36/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.36/linux/Documentation/Changes Wed Apr 23 19:01:13 1997 +++ linux/Documentation/Changes Thu Apr 24 10:49:59 1997 @@ -29,7 +29,7 @@ Also, don't forget http://www.linuxhq.com/ for all your Linux kernel needs. -Last updated: April 17, 1997. +Last updated: April 24, 1997. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Minimal Requirements @@ -45,11 +45,11 @@ - Dynamic Linker (ld.so) 1.8.5 - Linux C++ Library 2.7.2.1 - Procps 1.01 -- Mount 2.6e +- Mount 2.6g - Net-tools 1.32-alpha - Loadlin 1.6a - Sh-utils 1.16 -- Autofs 970409 +- Autofs 0.2.2 - NFS 0.4.21 Upgrade notes @@ -295,14 +295,14 @@ Mount ===== -The 2.6e release: -ftp://ftp.win.tue.nl/pub/linux/util/mount-2.6e.tar.gz +The 2.6g release: +ftp://ftp.win.tue.nl/pub/linux/util/mount-2.6g.tar.gz Autofs ====== -The 970409 release: -ftp://ftp.kernel.org/pub/linux/daemons/autofs/autofs-970409.tar.gz +The 0.2.2 release: +ftp://ftp.kernel.org/pub/linux/daemons/autofs/autofs-0.2.2.tar.gz NFS === diff -u --recursive --new-file v2.1.36/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.36/linux/Documentation/Configure.help Wed Apr 23 19:01:14 1997 +++ linux/Documentation/Configure.help Tue Apr 29 11:45:43 1997 @@ -4036,6 +4036,16 @@ N here so that they can use the serial port for modem, mouse or some other device. +Digi Intl. epca support +CONFIG_DIGIEPCA + This is a driver for Digi Internationals Xx, Xeve, and Xem + series of cards. This driver supports the original PC (ISA) boards as + well as PCI, and EISA. If you have a card like this, say Y here and read + the file Documentation/digiepca.txt. NOTE: This driver is seperate from + the driver written and copyrighted by Troy De Jongh. Because they both + attempt (In some cases) to access the same hardware only one of these + drivers (CONFIG_DIGIEPCA or CONFIG_DIGI) should be selected. + Digiboard PC/Xx Support CONFIG_DIGI This is a driver for the Digiboard PC/Xe, PC/Xi, and PC/Xeve cards @@ -5317,7 +5327,7 @@ # LocalWords: mgetty sendfax gert greenie muc lowlevel Lasermate LanManager io # LocalWords: OOPSes trackball binghamton mobileip ncr IOMAPPED settags ns ser # LocalWords: setsync NEGO MPARITY autotuning prefetch PIIX cdwrite utils rc -# LocalWords: PCWATCHDOG berkprod bitgate boldt ucsb jf kyoto jp euc Tetsuyasu +# LocalWords: PCWATCHDOG berkprod bitgate boldt ucsb jf kyoto jp euc Tetsuyasu # LocalWords: YAMADA tetsu cauchy nslab ntt nevod perm su doc kaf kheops wsc # LocalWords: traduc Bourgin dbourgin helptext menuconfig kfill READMEs HOWTOs # LocalWords: IDEDISK IDEFLOPPY EIDE firewalls QMAGIC ZMAGIC LocalWords opti diff -u --recursive --new-file v2.1.36/linux/Documentation/digiepca.txt linux/Documentation/digiepca.txt --- v2.1.36/linux/Documentation/digiepca.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/digiepca.txt Tue Apr 29 11:45:43 1997 @@ -0,0 +1,96 @@ +The Digi Intl. epca driver. +---------------------------- +The Digi Intl. epca driver for Linux supports the following boards: + +Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve +Digi EISA/Xem, PCI/Xem, PCI/Xr + +Limitations: +------------ +Currently the driver only autoprobes for supported PCI boards. + +The Linux MAKEDEV command does not support generating the Digiboard +Devices. Users executing digiConfig to setup EISA and PC series cards +will have their device nodes automaticly constructed (cud?? for ~CLOCAL, +and ttyD?? for CLOCAL). Users wishing to boot their board from the LILO +prompt, or those users booting PCI cards may use buildDIGI to construct +the necessary nodes. + +Notes: +------ +This driver may be configured via LILO. For users who have already configured +their driver using digiConfig, configuring from lilo will override previous +settings. Multiple boards may be configured by issuing multiple LILO command +lines. For examples see the bottom of this document. + +Device names start at 0 and continue up. Beware of this as previous Digi +drivers started device names with 1. + +PCI boards are auto-detected and configured by the driver. PCI boards will +be allocated device numbers (internally) begining with the lowest PCI slot +first. In other words a PCI card in slot 3 will always have higher device +nodes than a PCI card in slot 1. + +LILO config examples: +--------------------- +Using LILO's APPEND command, a string of comma separated identifiers or +integers can be used to configure supported boards. The six values in order +are: + + Enable/Disable this card or Override, + Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2), + EISA/Xem (3), PC/64Xe (4), PC/Xi (5), + Enable/Disable alternate pin arrangement, + Number of ports on this card, + I/O Port where card is configured (in HEX if using string identifiers), + Base of memory window (in HEX if using string identifiers), + +NOTE : PCI boards are auto-detected and configured. Do not attempt to +configure PCI boards with the LILO append comand. If you wish to override +previous configuration data (As set by digiConfig), but you do not wish to +configure any specific card (Example if there are PCI cards in the system) +the following override command will accomplish this: +-> append="digi=2" + +Samples: + append="digiepca=E,PC/Xe,D,16,200,D0000" + or + append="digi=1,0,0,16,512,851968" + +Supporting Tools: +----------------- +Supporting tools include digiDload, digiConfig, buildPCI, and ditty. See +/usr/src/linux/Documentation/README.epca.dir/user.doc for more details. Note, +this driver REQUIRES that digiDload be executed prior to it being used. +Failure to do this will result in an ENODEV error. + +The latest version of the tool package is available at: +ftp://ftp.dgii.com/drivers/linux/released/async/ + +Documentation: +-------------- +Complete documentation for this product may be found in the tool package. + +Sources of information and support: +----------------------------------- +Digi Intl. support site for this product: +-> digilnux@dgii.com + +Related information and information concerning other drivers supporting +Digi Intl. products: + +-> FTP: ftp://dgii.com +-> Webpage: http://www.dgii.com +-> Webpage: http://private.fuller.edu/clameter/digi.html +-> Mailing List: digiboard@list.fuller.edu Note write e-mail to subscribe + common ListServ commands will not work. + +Acknowledgments: +---------------- +Much of this work (And even text) was derived from a similar document +supporting the original public domain DigiBoard driver Copyright (C) +1994,1995 Troy De Jongh. Many thanks to Christoph Lameter +(clameter@fuller.edu) and Mike McLagan (mike.mclagan@linux.org) who authored +and contributed to the original document. + + diff -u --recursive --new-file v2.1.36/linux/MAINTAINERS linux/MAINTAINERS --- v2.1.36/linux/MAINTAINERS Sun Apr 13 10:18:20 1997 +++ linux/MAINTAINERS Tue Apr 29 11:45:43 1997 @@ -342,6 +342,13 @@ L: digiboard@list.fuller.edu S: Maintained +DIGI INTL. EPCA DRIVER: +P: Daniel Taylor +M: support@dgii.com +M: digilnux@dgii.com +L: digiboard@list.fuller.edu +S: Maintained + RISCOM8 DRIVER: P: Dmitry Gorodchanin M: begemot@bgm.rosprint.net diff -u --recursive --new-file v2.1.36/linux/Makefile linux/Makefile --- v2.1.36/linux/Makefile Wed Apr 23 19:01:14 1997 +++ linux/Makefile Wed Apr 23 19:02:21 1997 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 36 +SUBLEVEL = 37 ARCH := $(shell uname -m | sed s/i.86/i386/) diff -u --recursive --new-file v2.1.36/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.1.36/linux/arch/alpha/kernel/process.c Wed Apr 23 19:01:14 1997 +++ linux/arch/alpha/kernel/process.c Sun Apr 27 09:58:44 1997 @@ -39,6 +39,22 @@ #include /* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ +static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, }; +unsigned long init_user_stack[1024] = { STACK_MAGIC, }; +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; + +struct mm_struct init_mm = INIT_MM; +struct task_struct init_task = INIT_TASK; + +/* * No need to acquire the kernel lock, we're entirely local.. */ asmlinkage int sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2, diff -u --recursive --new-file v2.1.36/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c --- v2.1.36/linux/arch/alpha/kernel/ptrace.c Sun Jan 26 03:40:45 1997 +++ linux/arch/alpha/kernel/ptrace.c Sun Apr 27 15:08:01 1997 @@ -107,19 +107,6 @@ static long zero; - -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * Get contents of register REGNO in task TASK. */ @@ -507,7 +494,7 @@ if (pid == 1) /* you may not mess with init */ goto out; ret = -ESRCH; - if (!(child = get_task(pid))) + if (!(child = find_task_by_pid(pid))) goto out; if (request == PTRACE_ATTACH) { ret = -EPERM; diff -u --recursive --new-file v2.1.36/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v2.1.36/linux/arch/i386/Makefile Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/Makefile Sun Apr 27 16:38:18 1997 @@ -45,7 +45,7 @@ CFLAGS := $(CFLAGS) -D__SMP__ endif -HEAD := arch/i386/kernel/head.o +HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o SUBDIRS := $(SUBDIRS) arch/i386/kernel arch/i386/mm arch/i386/lib CORE_FILES := arch/i386/kernel/kernel.o arch/i386/mm/mm.o $(CORE_FILES) diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v2.1.36/linux/arch/i386/kernel/Makefile Sun Jan 26 02:07:04 1997 +++ linux/arch/i386/kernel/Makefile Sun Apr 27 16:38:00 1997 @@ -15,7 +15,7 @@ $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o endif -all: kernel.o head.o +all: kernel.o head.o init_task.o O_TARGET := kernel.o O_OBJS := process.o signal.o entry.o traps.o irq.o vm86.o bios32.o \ diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v2.1.36/linux/arch/i386/kernel/entry.S Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/entry.S Tue Apr 29 09:11:59 1997 @@ -110,62 +110,45 @@ addl $4,%esp; \ iret -#ifdef __SMP__ -/* Get the processor ID multiplied by 4 */ -#define GET_PROCESSOR_OFFSET(reg) \ - movl SYMBOL_NAME(apic_reg), reg; \ - movl 32(reg), reg; \ - shrl $22, reg; \ - andl $0x3C, reg; - -#define GET_CURRENT(reg) \ - GET_PROCESSOR_OFFSET(reg) \ - movl SYMBOL_NAME(current_set)(reg),reg - -#else - #define GET_CURRENT(reg) \ - movl SYMBOL_NAME(current_set),reg - -#endif + movl %esp, reg; \ + andl $-8192, reg; ENTRY(lcall7) pushfl # We get a different stack layout with call gates, pushl %eax # which has to be cleaned up later.. SAVE_ALL - GET_CURRENT(%ebx) movl EIP(%esp),%eax # due to call gates, this is eflags, not eip.. movl CS(%esp),%edx # this is eip.. movl EFLAGS(%esp),%ecx # and this is cs.. movl %eax,EFLAGS(%esp) # movl %edx,EIP(%esp) # Now we move them to their "normal" places movl %ecx,CS(%esp) # - movl %esp,%eax - GET_CURRENT(%edx) - pushl %eax - movl exec_domain(%edx),%edx # Get the execution domain + movl %esp,%ebx + pushl %ebx + andl $-8192,%ebx # GET_CURRENT + movl exec_domain(%ebx),%edx # Get the execution domain movl 4(%edx),%edx # Get the lcall7 handler for the domain call *%edx popl %eax jmp ret_from_sys_call + #ifdef __SMP__ ALIGN .globl ret_from_smpfork ret_from_smpfork: + GET_CURRENT(%ebx) btrl $0, SYMBOL_NAME(scheduler_lock) jmp ret_from_sys_call #endif /* __SMP__ */ - ALIGN -handle_bottom_half: - pushl $2f - jmp SYMBOL_NAME(do_bottom_half) - - ALIGN -reschedule: - pushl $ret_from_sys_call - jmp SYMBOL_NAME(schedule) # test +/* + * Return to user mode is not as complex as all this looks, + * but we want the default path for a system call return to + * go as quickly as possible which is why some of this is + * less clear than it otherwise should be. + */ ENTRY(system_call) pushl %eax # save orig_eax @@ -180,16 +163,11 @@ ALIGN .globl ret_from_sys_call .globl ret_from_intr -ret_from_intr: ret_from_sys_call: - GET_CURRENT(%ebx) movl SYMBOL_NAME(bh_mask),%eax andl SYMBOL_NAME(bh_active),%eax jne handle_bottom_half -2: movl EFLAGS(%esp),%eax # mix EFLAGS and CS - movb CS(%esp),%al - testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor? - je 1f +ret_with_reschedule: cmpl $0,SYMBOL_NAME(need_resched) jne reschedule movl blocked(%ebx),%eax @@ -197,7 +175,6 @@ notl %eax andl signal(%ebx),%eax jne signal_return -1: RESTORE_ALL ALIGN signal_return: @@ -230,6 +207,30 @@ movl $-ENOSYS,EAX(%esp) jmp ret_from_sys_call + ALIGN +ret_from_exception: + movl SYMBOL_NAME(bh_mask),%eax + andl SYMBOL_NAME(bh_active),%eax + jne handle_bottom_half + ALIGN +ret_from_intr: + GET_CURRENT(%ebx) + movl EFLAGS(%esp),%eax # mix EFLAGS and CS + movb CS(%esp),%al + testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor? + jne ret_with_reschedule + RESTORE_ALL + + ALIGN +handle_bottom_half: + pushl $ret_from_intr + jmp SYMBOL_NAME(do_bottom_half) + + ALIGN +reschedule: + pushl $ret_from_sys_call + jmp SYMBOL_NAME(schedule) # test + ENTRY(divide_error) pushl $0 # no error code @@ -260,7 +261,7 @@ GET_CURRENT(%ebx) call *%ecx addl $8,%esp - jmp ret_from_sys_call + jmp ret_from_exception ENTRY(coprocessor_error) pushl $0 @@ -271,7 +272,7 @@ pushl $-1 # mark this as an int SAVE_ALL GET_CURRENT(%ebx) - pushl $ret_from_sys_call + pushl $ret_from_exception movl %cr0,%eax testl $0x4,%eax # EM (math emulation bit) je SYMBOL_NAME(math_state_restore) diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- v2.1.36/linux/arch/i386/kernel/head.S Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/head.S Tue Apr 29 11:51:38 1997 @@ -39,19 +39,21 @@ jz 1f /* * New page tables may be in 4Mbyte page mode and may - * be using the global pages. + * be using the global pages. + * + * NOTE! We have to correct for the fact that we're + * not yet offset 0xC0000000.. */ +#define cr4_bits mmu_cr4_features-0xC0000000 #ifdef GAS_KNOWS_CR4 movl %cr4,%eax # Turn on 4Mb pages - orl $16+128,%eax + orl cr4_bits,%eax movl %eax,%cr4 #else .byte 0x0f,0x20,0xe0 - orl $16+128,%eax + orl cr4_bits,%eax .byte 0x0f,0x22,0xe0 #endif - movl %eax,%cr3 /* flush TLB as per app note */ - movl %cr0,%eax #endif /* * Setup paging (the tables are already set up, just switch them on) @@ -305,15 +307,53 @@ jne rp_sidt ret +stack_start: + .long SYMBOL_NAME(init_task_union)+8192 + .long KERNEL_DS + +/* This is the default interrupt "handler" :-) */ +int_msg: + .asciz "Unknown interrupt\n" + ALIGN +ignore_int: + cld + pushl %eax + pushl %ecx + pushl %edx + push %ds + movl $(KERNEL_DS),%eax + mov %ax,%ds + mov %ax,%es + mov %ax,%fs + pushl $int_msg + call SYMBOL_NAME(printk) + popl %eax + pop %ds + popl %edx + popl %ecx + popl %eax + iret + +/* + * The interrupt descriptor table has room for 256 idt's + */ + ALIGN +.word 0 +idt_descr: + .word 256*8-1 # idt contains 256 entries + .long SYMBOL_NAME(idt) + + ALIGN +.word 0 +gdt_descr: +#ifdef CONFIG_APM + .word (11+2*NR_TASKS)*8-1 +#else + .word (8+2*NR_TASKS)*8-1 +#endif + .long SYMBOL_NAME(gdt) /* - * page 0 is made non-existent, so that kernel NULL pointer references get - * caught. Thus the swapper page directory has been moved to 0x101000 - * with the introduction of the compressed boot code. Theoretically, - * the original design of overlaying the startup code with the swapper - * page directory is still possible --- it would reduce the size of the kernel - * by 2-3k. This would be a good thing to do at some point..... - * * This is initialized to create a identity-mapping at 0-4M (for bootup * purposes) and another mapping of the 0-4M area at virtual address * 0xC0000000. @@ -471,63 +511,29 @@ ENTRY(empty_zero_page) .org 0x6000 - -stack_start: - .long SYMBOL_NAME(init_user_stack)+4096 - .long KERNEL_DS - -/* This is the default interrupt "handler" :-) */ -int_msg: - .asciz "Unknown interrupt\n" - ALIGN -ignore_int: - cld - pushl %eax - pushl %ecx - pushl %edx - push %ds - push %es - push %fs - movl $(KERNEL_DS),%eax - mov %ax,%ds - mov %ax,%es - mov %ax,%fs - pushl $int_msg - call SYMBOL_NAME(printk) - popl %eax - pop %fs - pop %es - pop %ds - popl %edx - popl %ecx - popl %eax - iret +ENTRY(this_must_match_init_task) /* - * The interrupt descriptor table has room for 256 idt's + * This starts the data section. Note that the above is all + * in the text section because it has alignment requirements + * that we cannot fulfill any other way. */ - ALIGN -.word 0 -idt_descr: - .word 256*8-1 # idt contains 256 entries - .long SYMBOL_NAME(idt) +.data +ALIGN +/* 256 quadwords - 2048 bytes of idt */ ENTRY(idt) .fill 256,8,0 # idt is uninitialized - ALIGN -.word 0 -gdt_descr: -#ifdef CONFIG_APM - .word (11+2*NR_TASKS)*8-1 -#else - .word (8+2*NR_TASKS)*8-1 -#endif - .long SYMBOL_NAME(gdt) - /* * This gdt setup gives the kernel a 1GB address space at virtual * address 0xC0000000 - space enough for expansion, I hope. + * + * This contains up to 8192 quadwords depending on NR_TASKS - 64kB of + * gdt entries. Ugh. + * + * NOTE! Make sure the gdt descriptor in head.S matches this if you + * change anything. */ ENTRY(gdt) .quad 0x0000000000000000 /* NULL descriptor */ diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.1.36/linux/arch/i386/kernel/i386_ksyms.c Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/i386_ksyms.c Tue Apr 29 10:00:14 1997 @@ -39,12 +39,13 @@ #ifdef __SMP__ EXPORT_SYMBOL(apic_reg); /* Needed internally for the I386 inlines */ EXPORT_SYMBOL(cpu_data); -EXPORT_SYMBOL(kernel_flag); -EXPORT_SYMBOL(active_kernel_processor); +EXPORT_SYMBOL_NOVERS(kernel_flag); +EXPORT_SYMBOL_NOVERS(active_kernel_processor); EXPORT_SYMBOL(smp_invalidate_needed); EXPORT_SYMBOL_NOVERS(__lock_kernel); /* Global SMP irq stuff */ +EXPORT_SYMBOL(synchronize_irq); EXPORT_SYMBOL(global_irq_holder); EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_sti); diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/init_task.c linux/arch/i386/kernel/init_task.c --- v2.1.36/linux/arch/i386/kernel/init_task.c Wed Dec 31 16:00:00 1969 +++ linux/arch/i386/kernel/init_task.c Sun Apr 27 16:40:09 1997 @@ -0,0 +1,22 @@ +#include +#include + +#include + +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; +struct mm_struct init_mm = INIT_MM; + +/* + * Initial task structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + * + * The things we do for performance.. + */ +union task_union init_task_union __attribute__((__section__(".text"))) = { INIT_TASK }; diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.1.36/linux/arch/i386/kernel/irq.c Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/irq.c Tue Apr 29 11:05:52 1997 @@ -44,8 +44,8 @@ #define CR0_NE 32 -static unsigned char cache_21 = 0xff; -static unsigned char cache_A1 = 0xff; +/* This contains the irq mask for both irq controllers */ +static unsigned long cached_irq_mask = 0xffff; unsigned int local_irq_count[NR_CPUS]; #ifdef __SMP__ @@ -58,32 +58,33 @@ static unsigned int int_count[NR_CPUS][NR_IRQS] = {{0},}; #endif -static inline void mask_irq(unsigned int irq_nr) +static inline void ack_irq(int irq_nr) { - unsigned char mask; + if (irq_nr & 8) { + outb(0x20,0xA0); + } + outb(0x20,0x20); +} - mask = 1 << (irq_nr & 7); - if (irq_nr < 8) { - cache_21 |= mask; - outb(cache_21,0x21); +static inline void set_irq_mask(int irq_nr) +{ + if (irq_nr & 8) { + outb(cached_irq_mask>>8,0xA1); } else { - cache_A1 |= mask; - outb(cache_A1,0xA1); + outb(cached_irq_mask,0x21); } +} + +static inline void mask_irq(unsigned int irq_nr) +{ + set_bit(irq_nr, &cached_irq_mask); + set_irq_mask(irq_nr); } static inline void unmask_irq(unsigned int irq_nr) { - unsigned char mask; - - mask = ~(1 << (irq_nr & 7)); - if (irq_nr < 8) { - cache_21 &= mask; - outb(cache_21,0x21); - } else { - cache_A1 &= mask; - outb(cache_A1,0xA1); - } + clear_bit(irq_nr, &cached_irq_mask); + set_irq_mask(irq_nr); } void disable_irq(unsigned int irq_nr) @@ -93,6 +94,7 @@ save_flags(flags); cli(); mask_irq(irq_nr); + synchronize_irq(); restore_flags(flags); } @@ -133,7 +135,8 @@ #error make irq stub building NR_IRQS dependent and remove me. #endif -BUILD_TIMER_IRQ(FIRST,0,0x01) +BUILD_COMMON_IRQ() +BUILD_IRQ(FIRST,0,0x01) BUILD_IRQ(FIRST,1,0x02) BUILD_IRQ(FIRST,2,0x04) BUILD_IRQ(FIRST,3,0x08) @@ -157,10 +160,6 @@ BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt) #endif -/* - * Pointers to the low-level handlers: first the general ones, then the - * fast ones, then the bad ones. - */ static void (*interrupt[17])(void) = { IRQ0_interrupt, IRQ1_interrupt, IRQ2_interrupt, IRQ3_interrupt, IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt, @@ -168,28 +167,6 @@ IRQ12_interrupt, IRQ13_interrupt, IRQ14_interrupt, IRQ15_interrupt }; -static void (*fast_interrupt[16])(void) = { - fast_IRQ0_interrupt, fast_IRQ1_interrupt, - fast_IRQ2_interrupt, fast_IRQ3_interrupt, - fast_IRQ4_interrupt, fast_IRQ5_interrupt, - fast_IRQ6_interrupt, fast_IRQ7_interrupt, - fast_IRQ8_interrupt, fast_IRQ9_interrupt, - fast_IRQ10_interrupt, fast_IRQ11_interrupt, - fast_IRQ12_interrupt, fast_IRQ13_interrupt, - fast_IRQ14_interrupt, fast_IRQ15_interrupt -}; - -static void (*bad_interrupt[16])(void) = { - bad_IRQ0_interrupt, bad_IRQ1_interrupt, - bad_IRQ2_interrupt, bad_IRQ3_interrupt, - bad_IRQ4_interrupt, bad_IRQ5_interrupt, - bad_IRQ6_interrupt, bad_IRQ7_interrupt, - bad_IRQ8_interrupt, bad_IRQ9_interrupt, - bad_IRQ10_interrupt, bad_IRQ11_interrupt, - bad_IRQ12_interrupt, bad_IRQ13_interrupt, - bad_IRQ14_interrupt, bad_IRQ15_interrupt -}; - /* * Initial irq handlers. */ @@ -240,14 +217,10 @@ action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %10u %c %s", - i, kstat.interrupts[i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); + len += sprintf(buf+len, "%2d: %10u %s", + i, kstat.interrupts[i], 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, ", %s", action->name); } len += sprintf(buf+len, "\n"); } @@ -298,13 +271,9 @@ for (j=0;jflags & SA_INTERRUPT) ? '+' : ' ', - action->name); + len += sprintf(buf+len, " %s", 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, ", %s", action->name); } len += sprintf(buf+len, "\n"); } @@ -519,7 +488,8 @@ { switch (flags) { case 0: - __global_sti(); + release_irqlock(smp_processor_id()); + __sti(); break; case 1: __global_cli(); @@ -533,56 +503,48 @@ #endif /* - * do_IRQ handles IRQ's that have been installed without the - * SA_INTERRUPT flag: it uses the full signal-handling return - * and runs with other interrupts enabled. All relatively slow - * IRQ's should use this format: notably the keyboard/timer - * routines. + * do_IRQ handles all normal device IRQ's (the special + * SMP cross-CPU interrupts have their own specific + * handlers). */ -asmlinkage void do_IRQ(int irq, struct pt_regs * regs) +asmlinkage void do_IRQ(struct pt_regs regs) { + int irq = regs.orig_eax & 0xff; struct irqaction * action; - int do_random, cpu = smp_processor_id(); + int status, cpu = smp_processor_id(); irq_enter(cpu, irq); + mask_irq(irq); + ack_irq(irq); kstat.interrupts[irq]++; - /* slow interrupts run with interrupts enabled */ - __sti(); + /* Return with this interrupt masked if no action */ + status = 0; action = *(irq + irq_action); - do_random = 0; - while (action) { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - irq_exit(cpu, irq); -} - -/* - * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return - * stuff - the handler is also running with interrupts disabled unless - * it explicitly enables them later. - */ -asmlinkage void do_fast_IRQ(int irq) -{ - struct irqaction * action; - int do_random, cpu = smp_processor_id(); + if (action) { + do { + status |= action->flags; + action->handler(irq, action->dev_id, ®s); + action = action->next; + } while (action); + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); - irq_enter(cpu, irq); - kstat.interrupts[irq]++; - action = *(irq + irq_action); - do_random = 0; - while (action) { - do_random |= action->flags; - action->handler(irq, action->dev_id, NULL); - action = action->next; + __cli(); + unmask_irq(irq); } - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); + irq_exit(cpu, irq); + /* + * This should be conditional: we should really get + * a return code from the irq handler to tell us + * whether the handler wants us to do software bottom + * half handling or not.. + */ + if (1) { + if (bh_active & bh_mask) + do_bottom_half(); + } } int setup_x86_irq(int irq, struct irqaction * new) @@ -597,10 +559,6 @@ if (!(old->flags & new->flags & SA_SHIRQ)) return -EBUSY; - /* Can't share interrupts unless both are same type */ - if ((old->flags ^ new->flags) & SA_INTERRUPT) - return -EBUSY; - /* add new interrupt at end of irq queue */ do { p = &old->next; @@ -617,10 +575,7 @@ *p = new; if (!shared) { - if (new->flags & SA_INTERRUPT) - set_intr_gate(0x20+irq,fast_interrupt[irq]); - else - set_intr_gate(0x20+irq,interrupt[irq]); + set_intr_gate(0x20+irq,interrupt[irq]); unmask_irq(irq); } restore_flags(flags); @@ -676,10 +631,6 @@ save_flags(flags); cli(); *p = action->next; - if (!irq[irq_action]) { - mask_irq(irq); - set_intr_gate(0x20+irq,bad_interrupt[irq]); - } restore_flags(flags); kfree(action); return; @@ -689,7 +640,7 @@ unsigned long probe_irq_on (void) { - unsigned int i, irqs = 0, irqmask; + unsigned int i, irqs = 0; unsigned long delay; /* first, enable any unassigned irqs */ @@ -705,19 +656,17 @@ /* about 100ms delay */; /* now filter out any obviously spurious interrupts */ - irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; - return irqs & ~irqmask; + return irqs & ~cached_irq_mask; } int probe_irq_off (unsigned long irqs) { - unsigned int i, irqmask; + unsigned int i; - irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; #ifdef DEBUG - printk("probe_irq_off: irqs=0x%04lx irqmask=0x%04x\n", irqs, irqmask); + printk("probe_irq_off: irqs=0x%04lx irqmask=0x%04x\n", irqs, cached_irq_mask); #endif - irqs &= irqmask; + irqs &= cached_irq_mask; if (!irqs) return 0; i = ffz(~irqs); @@ -740,7 +689,7 @@ outb(LATCH >> 8 , 0x40); /* MSB */ for (i = 0; i < NR_IRQS ; i++) - set_intr_gate(0x20+i,bad_interrupt[i]); + set_intr_gate(0x20+i,interrupt[i]); #ifdef __SMP__ /* diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h --- v2.1.36/linux/arch/i386/kernel/irq.h Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/irq.h Tue Apr 29 11:40:18 1997 @@ -33,7 +33,6 @@ static inline void irq_exit(int cpu, int irq) { - __cli(); hardirq_exit(cpu); release_irqlock(cpu); } @@ -64,18 +63,8 @@ "mov %dx,%es\n\t" /* - * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers, - * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't - * call the routines that do signal handling etc on return, and can have - * more relaxed register-saving etc. They are also atomic, and are thus - * suited for small, fast interrupts like the serial lines or the harddisk - * drivers, which don't actually need signal handling etc. - * - * Also note that we actually save only those registers that are used in - * C subroutines (%eax, %edx and %ecx), so if you do something weird, - * you're on your own. The only segments that are saved (not counting the - * automatic stack and code segment handling) are %ds and %es, and they - * point to kernel space. No messing around with %fs here. + * These are used just for the "bad" interrupt handlers, + * which just clear the mask and return.. */ #define SAVE_MOST \ "cld\n\t" \ @@ -96,92 +85,13 @@ "pop %es\n\t" \ "iret" -/* - * Some fast irq handlers might want to access saved registers (mostly - * cs or flags) - */ - -struct fast_irq_regs { - long ecx; - long edx; - long eax; - int xds; - int xes; - long eip; - int xcs; - long eflags; - long esp; - int xss; -}; - -/* - * The "inb" instructions are not needed, but seem to change the timings - * a bit - without them it seems that the harddisk driver won't work on - * all hardware. Arghh. - */ -#define ACK_FIRST(mask,nr) \ - "inb $0x21,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_21)"\n\t" \ - "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \ - "outb %al,$0x21\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tmovb $0x20,%al\n\t" \ - "outb %al,$0x20\n\t" - -#define ACK_SECOND(mask,nr) \ - "inb $0xA1,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_A1)"\n\t" \ - "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \ - "outb %al,$0xA1\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tmovb $0x20,%al\n\t" \ - "outb %al,$0xA0\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\toutb %al,$0x20\n\t" - -#define UNBLK_FIRST(mask) \ - "inb $0x21,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \ - "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \ - "outb %al,$0x21\n\t" - -#define UNBLK_SECOND(mask) \ - "inb $0xA1,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \ - "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \ - "outb %al,$0xA1\n\t" - #define IRQ_NAME2(nr) nr##_interrupt(void) #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) -#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr) #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr) -#ifdef __SMP__ - #define GET_CURRENT \ - "movl "SYMBOL_NAME_STR(apic_reg)", %ebx\n\t" \ - "movl 32(%ebx), %ebx\n\t" \ - "shrl $22,%ebx\n\t" \ - "andl $0x3C,%ebx\n\t" \ - "movl " SYMBOL_NAME_STR(current_set) "(,%ebx),%ebx\n\t" - -#else - -#define GET_CURRENT \ - "movl " SYMBOL_NAME_STR(current_set) ",%ebx\n\t" - -#endif + "movl %esp, %ebx\n\t" \ + "andl $-8192, %ebx\n\t" #ifdef __SMP__ @@ -205,66 +115,30 @@ "\n"__ALIGN_STR"\n" \ SYMBOL_NAME_STR(x) ":\n\t" \ "pushl $-1\n\t" \ - SAVE_ALL \ - "movl %esp,%eax\n\t" \ - "pushl %eax\n\t" \ + SAVE_ALL \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ - "addl $4,%esp\n\t" \ + "addl $4,%esp\n\t" \ "jmp ret_from_intr\n"); #endif /* __SMP__ */ -#define BUILD_IRQ(chip,nr,mask) \ -asmlinkage void IRQ_NAME(nr); \ -asmlinkage void FAST_IRQ_NAME(nr); \ -asmlinkage void BAD_IRQ_NAME(nr); \ +#define BUILD_COMMON_IRQ() \ __asm__( \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ - "pushl $-"#nr"-2\n\t" \ + "\n" __ALIGN_STR"\n" \ + "common_interrupt:\n\t" \ SAVE_ALL \ - ACK_##chip(mask,(nr&7)) \ - "movl %esp,%eax\n\t" \ - "pushl %eax\n\t" \ - "pushl $" #nr "\n\t" \ - "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ - "addl $8,%esp\n\t" \ - UNBLK_##chip(mask) \ - "jmp ret_from_intr\n" \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \ - SAVE_MOST \ - ACK_##chip(mask,(nr&7)) \ - "pushl $" #nr "\n\t" \ - "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \ - "addl $4,%esp\n\t" \ - UNBLK_##chip(mask) \ - RESTORE_MOST \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \ - SAVE_MOST \ - ACK_##chip(mask,(nr&7)) \ - RESTORE_MOST); - -#define BUILD_TIMER_IRQ(chip,nr,mask) \ + "pushl $ret_from_intr\n\t" \ + "jmp "SYMBOL_NAME_STR(do_IRQ)); + +#define BUILD_IRQ(chip,nr,mask) \ asmlinkage void IRQ_NAME(nr); \ -asmlinkage void FAST_IRQ_NAME(nr); \ -asmlinkage void BAD_IRQ_NAME(nr); \ __asm__( \ "\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \ -SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ - "pushl $-"#nr"-2\n\t" \ - SAVE_ALL \ - ACK_##chip(mask,(nr&7)) \ - "movl %esp,%eax\n\t" \ - "pushl %eax\n\t" \ - "pushl $" #nr "\n\t" \ - "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ - "addl $8,%esp\n\t" \ - UNBLK_##chip(mask) \ - "jmp ret_from_intr\n"); + "pushl $"#nr"-256\n\t" \ + "jmp common_interrupt"); /* * x86 profiling function, SMP safe. We might want to do this in diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.1.36/linux/arch/i386/kernel/process.c Sun Apr 13 10:18:20 1997 +++ linux/arch/i386/kernel/process.c Mon Apr 28 20:44:18 1997 @@ -149,7 +149,8 @@ current->priority = -100; while(1) { - if(cpu_data[smp_processor_id()].hlt_works_ok && !hlt_counter && !need_resched) + if(cpu_data[hard_smp_processor_id()].hlt_works_ok && + !hlt_counter && !need_resched) __asm("hlt"); /* * tq_scheduler currently assumes we're running in a process @@ -324,11 +325,14 @@ pg0 [0] = 7; - /* Use `swapper_pg_dir' as our page directory. Don't bother with - `SET_PAGE_DIR' because interrupts are disabled and we're rebooting. - This instruction flushes the TLB. */ + /* + * Use `swapper_pg_dir' as our page directory. We bother with + * `SET_PAGE_DIR' because although might be rebooting, but if we change + * the way we set root page dir in the future, then we wont break a + * seldom used feature ;) + */ - __asm__ __volatile__ ("movl %0,%%cr3" : : "a" (swapper_pg_dir) : "memory"); + SET_PAGE_DIR(current,swapper_pg_dir); /* Write 0x1234 to absolute memory location 0x472. The BIOS reads this on booting to tell it to "Bypass memory test (also warm @@ -473,6 +477,8 @@ int i; struct pt_regs * childregs; + p->tss.tr = _TSS(nr); + p->tss.ldt = _LDT(nr); p->tss.es = KERNEL_DS; p->tss.cs = KERNEL_CS; p->tss.ss = KERNEL_DS; @@ -480,9 +486,8 @@ p->tss.fs = USER_DS; p->tss.gs = USER_DS; p->tss.ss0 = KERNEL_DS; - p->tss.esp0 = p->kernel_stack_page + PAGE_SIZE; - p->tss.tr = _TSS(nr); - childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; + p->tss.esp0 = 2*PAGE_SIZE + (unsigned long) p; + childregs = ((struct pt_regs *) (p->tss.esp0)) - 1; p->tss.esp = (unsigned long) childregs; #ifdef __SMP__ p->tss.eip = (unsigned long) ret_from_smpfork; @@ -496,7 +501,6 @@ childregs->eax = 0; childregs->esp = esp; p->tss.back_link = 0; - p->tss.ldt = _LDT(nr); if (p->ldt) { p->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); if (p->ldt != NULL) @@ -512,6 +516,7 @@ p->tss.io_bitmap[i] = ~0; if (last_task_used_math == current) __asm__("clts ; fnsave %0 ; frstor %0":"=m" (p->tss.i387)); + return 0; } diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c --- v2.1.36/linux/arch/i386/kernel/ptrace.c Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/ptrace.c Sun Apr 27 15:08:01 1997 @@ -34,18 +34,6 @@ */ #define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs)) -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * this routine will get a word off of the processes privileged stack. * the offset is how far from the base addr as stored in the TSS. @@ -381,7 +369,7 @@ if (pid == 1) /* you may not mess with init */ goto out; ret = -ESRCH; - if (!(child = get_task(pid))) + if (!(child = find_task_by_pid(pid))) goto out; ret = -EPERM; if (request == PTRACE_ATTACH) { diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- v2.1.36/linux/arch/i386/kernel/signal.c Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/signal.c Sat Apr 26 17:20:40 1997 @@ -318,6 +318,14 @@ unsigned long signr; struct sigaction * sa; + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if ((regs->xcs & 3) != 3) + return 1; mask = ~current->blocked; while ((signr = current->signal & mask)) { /* diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- v2.1.36/linux/arch/i386/kernel/smp.c Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/kernel/smp.c Tue Apr 29 10:50:30 1997 @@ -1,5 +1,5 @@ /* - * Intel MP v1.1/v1.4 specification support routines for multi-pentium + * Intel MP v1.1/v1.4 specification support routines for multi-pentium * hosts. * * (c) 1995 Alan Cox, CymruNET Ltd @@ -46,14 +46,15 @@ #include #include +#define __KERNEL_SYSCALLS__ +#include + #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); - + unsigned long ticks, unsigned long user, + unsigned long system); /* * Some notes on processor bugs: * @@ -67,7 +68,7 @@ * Pentium * There is a marginal case where REP MOVS on 100MHz SMP * machines with B stepping processors can fail. XXX should provide - * an L1cache=Writethrough or L1cache=off option. + * an L1cache=Writethrough or L1cache=off option. * * B stepping CPU's may hang. There are hardware work arounds * for this. We warn about it in case your board doesnt have the work @@ -91,12 +92,12 @@ * If this sounds worrying believe me these bugs are ___RARE___ and * there's about nothing of note with C stepping upwards. */ - - + + /* * Why isn't this somewhere standard ?? */ - + extern __inline int max(int a,int b) { if(a>b) @@ -129,7 +130,6 @@ unsigned long nlong = 0; /* dummy used for apic_reg address + 0x20 */ unsigned char *apic_reg=((unsigned char *)(&nlong))-0x20;/* Later set to the ioremap() of the APIC */ unsigned long apic_retval; /* Just debugging the assembler.. */ -unsigned char *kernel_stacks[NR_CPUS]; /* Kernel stack pointers for CPU's (debugging) */ static volatile unsigned char smp_cpu_in_msg[NR_CPUS]; /* True if this processor is sending an IPI */ @@ -195,10 +195,10 @@ apic_write(APIC_EOI, 0); } -/* +/* * Checksum an MP configuration block. */ - + static int mpf_checksum(unsigned char *mp, int len) { int sum=0; @@ -210,7 +210,7 @@ /* * Processor encoding in an MP configuration block */ - + static char *mpc_family(int family,int model) { static char n[32]; @@ -274,11 +274,11 @@ /* set the local APIC address */ apic_addr = (unsigned long)phys_to_virt((unsigned long)mpc->mpc_lapic); - + /* * Now process the configuration blocks. */ - + while(countmpc_length) { switch(*mpt) @@ -290,13 +290,13 @@ if(m->mpc_cpuflag&CPU_ENABLED) { printk("Processor #%d %s APIC version %d\n", - m->mpc_apicid, + m->mpc_apicid, mpc_family((m->mpc_cpufeature& CPU_FAMILY_MASK)>>8, (m->mpc_cpufeature& CPU_MODEL_MASK)>>4), m->mpc_apicver); -#ifdef SMP_DEBUG +#ifdef SMP_DEBUG if(m->mpc_featureflag&(1<<0)) printk(" Floating point unit present.\n"); if(m->mpc_featureflag&(1<<7)) @@ -305,7 +305,7 @@ printk(" 64 bit compare & exchange supported.\n"); if(m->mpc_featureflag&(1<<9)) printk(" Internal APIC present.\n"); -#endif +#endif if(m->mpc_cpuflag&CPU_BOOTPROCESSOR) { SMP_PRINTK((" Bootup CPU\n")); @@ -313,10 +313,10 @@ } else /* Boot CPU already counted */ num_processors++; - + if(m->mpc_apicid>NR_CPUS) printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS); - else + else { cpu_present_map|=(1<mpc_apicid); apic_version[m->mpc_apicid]=m->mpc_apicver; @@ -337,7 +337,7 @@ str)); mpt+=sizeof(*m); count+=sizeof(*m); - break; + break; } case MP_IOAPIC: { @@ -346,20 +346,20 @@ if(m->mpc_flags&MPC_APIC_USABLE) { apics++; - printk("I/O APIC #%d Version %d at 0x%lX.\n", - m->mpc_apicid,m->mpc_apicver, - m->mpc_apicaddr); - io_apic_addr = (unsigned long)phys_to_virt(m->mpc_apicaddr); - } - mpt+=sizeof(*m); - count+=sizeof(*m); - break; + printk("I/O APIC #%d Version %d at 0x%lX.\n", + m->mpc_apicid,m->mpc_apicver, + m->mpc_apicaddr); + io_apic_addr = (unsigned long)phys_to_virt(m->mpc_apicaddr); + } + mpt+=sizeof(*m); + count+=sizeof(*m); + break; } case MP_INTSRC: { struct mpc_config_intsrc *m= (struct mpc_config_intsrc *)mpt; - + mpt+=sizeof(*m); count+=sizeof(*m); break; @@ -376,29 +376,29 @@ } if(apics>1) printk("Warning: Multiple APIC's not supported.\n"); - return num_processors; + return num_processors; } /* * Scan the memory blocks for an SMP configuration block. */ - + __initfunc(int smp_scan_config(unsigned long base, unsigned long length)) { unsigned long *bp=phys_to_virt(base); struct intel_mp_floating *mpf; - + SMP_PRINTK(("Scan SMP from %p for %ld bytes.\n", bp,length)); if(sizeof(*mpf)!=16) printk("Error: MPF size\n"); - + while(length>0) { if(*bp==SMP_MAGIC_IDENT) { mpf=(struct intel_mp_floating *)bp; - if(mpf->mpf_length==1 && + if(mpf->mpf_length==1 && !mpf_checksum((unsigned char *)bp,16) && (mpf->mpf_specification == 1 || mpf->mpf_specification == 4) ) @@ -433,7 +433,7 @@ * We know that page 0 is not * used. Steal it for now! */ - + cfg=pg0[0]; pg0[0] = (apic_addr | 7); local_flush_tlb(); @@ -451,7 +451,7 @@ * * END OF HACK END OF HACK END OF HACK END OF HACK END OF HACK * - */ + */ /* * 2 CPUs, numbered 0 & 1. */ @@ -513,6 +513,7 @@ nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */ cpu_logical_map[0] = boot_cpu_id; global_irq_holder = boot_cpu_id; + current->processor = boot_cpu_id; printk("Processors: %d\n", num_processors); /* @@ -540,7 +541,7 @@ * bootstrap into the page concerned. The caller * has made sure it's suitably aligned. */ - + __initfunc(static void install_trampoline(unsigned char *mp)) { memcpy(mp, trampoline_data, trampoline_end - trampoline_data); @@ -552,7 +553,7 @@ * the kernel stacks at 4K, 8K, 12K... currently (0-03FF is preserved for SMM and * other things). */ - + __initfunc(unsigned long smp_alloc_memory(unsigned long mem_base)) { int size=(num_processors-1)*PAGE_SIZE; /* Number of stacks needed */ @@ -561,7 +562,7 @@ * Our stacks have to be below the 1Mb line, and mem_base on entry * is 4K aligned. */ - + if(virt_to_phys((void *)(mem_base+size))>=0x9F000) panic("smp_alloc_memory: Insufficient low memory for kernel stacks 0x%lx.\n", mem_base); kstack_base=(void *)mem_base; @@ -569,26 +570,12 @@ kstack_end=(void *)mem_base; return mem_base; } - -/* - * Hand out stacks one at a time. - */ - -__initfunc(static void *get_kernel_stack(void)) -{ - void *stack=kstack_base; - if(kstack_base>=kstack_end) - return NULL; - kstack_base+=PAGE_SIZE; - return stack; -} - /* * The bootstrap kernel entry code has set these up. Save them for * a given CPU */ - + __initfunc(void smp_store_cpu_info(int id)) { struct cpuinfo_x86 *c=&cpu_data[id]; @@ -615,7 +602,7 @@ * fired off. This allows the BP to have everything in order [we hope]. * At the end of this all the AP's will hit the system scheduling and off * we go. Each AP will load the system gdt's and jump through the kernel - * init into idle(). At this point the scheduler will one day take over + * init into idle(). At this point the scheduler will one day take over * and give them jobs to do. smp_callin is a standard routine * we use to track CPU's as they power up. */ @@ -634,74 +621,270 @@ extern void calibrate_delay(void); int cpuid=GET_APIC_ID(apic_read(APIC_ID)); unsigned long l; - + /* * Activate our APIC */ - - SMP_PRINTK(("CALLIN %d\n",smp_processor_id())); + + SMP_PRINTK(("CALLIN %d %d\n",hard_smp_processor_id(), smp_processor_id())); l=apic_read(APIC_SPIV); l|=(1<<8); /* Enable */ apic_write(APIC_SPIV,l); /* - * Set up our APIC timer. + * Set up our APIC timer. */ setup_APIC_clock (); sti(); /* * Get our bogomips. - */ + */ calibrate_delay(); SMP_PRINTK(("Stack at about %p\n",&cpuid)); - + /* * Save our processor parameters */ smp_store_cpu_info(cpuid); + /* * Allow the master to continue. - */ + */ set_bit(cpuid, (unsigned long *)&cpu_callin_map[0]); +} + +static int cpucount = 0; + +extern int cpu_idle(void * unused); + +/* + * Activate a secondary processor. + */ +__initfunc(int start_secondary(void *unused)) +{ + trap_init(); + init_IRQ(); + smp_callin(); + cpu_idle(NULL); +} + +/* + * Everything has been set up for the secondary + * CPU's - they just need to reload everything + * from the task structude + */ +__initfunc(void initialize_secondary(void)) +{ + struct thread_struct * p = ¤t->tss; + /* - * Until we are ready for SMP scheduling + * We don't actually need to load the full TSS, + * just the stack pointer and the eip. */ - load_ldt(0); - local_flush_tlb(); - - while (cpu_number_map[cpuid] == -1) - barrier(); + asm volatile("ltr %%ax": :"a" (p->tr)); + asm volatile( + "movl %0,%%esp\n\t" + "jmp *%1" + : + :"r" (p->esp),"r" (p->eip)); +} - while(!task[cpuid] || current_set[cpuid] != task[cpu_number_map[cpuid]]) - barrier(); +__initfunc(static void do_boot_cpu(int i)) +{ + unsigned long cfg; + pgd_t maincfg; + void *stack; + struct task_struct *idle; + unsigned long send_status, accept_status; + int timeout, num_starts, j; - local_flush_tlb(); - load_TR(cpu_number_map[cpuid]); + /* + * We need an idle process for each processor. + */ - while(!smp_commenced) - barrier(); - + kernel_thread(start_secondary, NULL, CLONE_PID); + cpucount++; + + idle = task[cpucount]; + if (!idle) + panic("No idle process for CPU %d\n", i); + + idle->processor = i; + cpu_logical_map[cpucount] = i; + cpu_number_map[i] = cpucount; + + /* This MUST be in the low 1MB range. That's ok, we're cool */ + stack = (void *) (4096+(char *)idle); + install_trampoline(stack); + + printk("Booting processor %d stack %p: ",i,stack); /* So we set what's up */ + + /* + * This grunge runs the startup process for + * the targeted processor. + */ + + SMP_PRINTK(("Setting warm reset code and vector.\n")); + + CMOS_WRITE(0xa, 0xf); local_flush_tlb(); + SMP_PRINTK(("1.\n")); + *((volatile unsigned short *) phys_to_virt(0x469)) = ((unsigned long)stack)>>4; + SMP_PRINTK(("2.\n")); + *((volatile unsigned short *) phys_to_virt(0x467)) = 0; + SMP_PRINTK(("3.\n")); + + maincfg=swapper_pg_dir[0]; + ((unsigned long *)swapper_pg_dir)[0]=0x102007; + + /* + * Be paranoid about clearing APIC errors. + */ + + if ( apic_version[i] & 0xF0 ) + { + apic_write(APIC_ESR, 0); + accept_status = (apic_read(APIC_ESR) & 0xEF); + } + + /* + * Status is now clean + */ - SMP_PRINTK(("Commenced..\n")); + send_status = 0; + accept_status = 0; + + /* + * Starting actual IPI sequence... + */ + + SMP_PRINTK(("Asserting INIT.\n")); + + /* + * Turn INIT on + */ + + cfg=apic_read(APIC_ICR2); + cfg&=0x00FFFFFF; + apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ + cfg=apic_read(APIC_ICR); + cfg&=~0xCDFFF; /* Clear bits */ + cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG + | APIC_DEST_ASSERT | APIC_DEST_DM_INIT); + apic_write(APIC_ICR, cfg); /* Send IPI */ + + udelay(200); + SMP_PRINTK(("Deasserting INIT.\n")); + + cfg=apic_read(APIC_ICR2); + cfg&=0x00FFFFFF; + apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ + cfg=apic_read(APIC_ICR); + cfg&=~0xCDFFF; /* Clear bits */ + cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG + | APIC_DEST_DM_INIT); + apic_write(APIC_ICR, cfg); /* Send IPI */ + + /* + * Should we send STARTUP IPIs ? + * + * Determine this based on the APIC version. + * If we don't have an integrated APIC, don't + * send the STARTUP IPIs. + */ + + if ( apic_version[i] & 0xF0 ) + num_starts = 2; + else + num_starts = 0; + + /* + * Run STARTUP IPI loop. + */ + + for (j = 1; !(send_status || accept_status) + && (j <= num_starts) ; j++) + { + SMP_PRINTK(("Sending STARTUP #%d.\n",j)); + apic_write(APIC_ESR, 0); + SMP_PRINTK(("After apic_write.\n")); + + /* + * STARTUP IPI + */ + + cfg=apic_read(APIC_ICR2); + cfg&=0x00FFFFFF; + apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ + cfg=apic_read(APIC_ICR); + cfg&=~0xCDFFF; /* Clear bits */ + cfg |= (APIC_DEST_FIELD + | APIC_DEST_DM_STARTUP + | (virt_to_phys(stack) >> 12)); /* Boot on the stack */ + SMP_PRINTK(("Before start apic_write.\n")); + apic_write(APIC_ICR, cfg); /* Kick the second */ + + SMP_PRINTK(("Startup point 1.\n")); + timeout = 0; + do { + SMP_PRINTK(("Sleeping.\n")); udelay(1000000); + udelay(10); + } while ( (send_status = (apic_read(APIC_ICR) & 0x1000)) + && (timeout++ < 1000)); + udelay(200); + accept_status = (apic_read(APIC_ESR) & 0xEF); + } + SMP_PRINTK(("After Startup.\n")); + + if (send_status) /* APIC never delivered?? */ + printk("APIC never delivered???\n"); + if (accept_status) /* Send accept error */ + printk("APIC delivery error (%lx).\n", accept_status); + + if( !(send_status || accept_status) ) + { + for(timeout=0;timeout<50000;timeout++) + { + if(cpu_callin_map[0]&(1< cpucount+1)) { - unsigned long send_status, accept_status; - int timeout, num_starts, j; - - /* - * We need a kernel stack for each processor. - */ - - stack=get_kernel_stack(); /* We allocated these earlier */ - if(stack==NULL) - panic("No memory for processor stacks.\n"); - - kernel_stacks[i]=(void *)phys_to_virt((unsigned long)stack); - install_trampoline(stack); - - printk("Booting processor %d stack %p: ",i,stack); /* So we set what's up */ - - /* - * This grunge runs the startup process for - * the targeted processor. - */ - - SMP_PRINTK(("Setting warm reset code and vector.\n")); - - /* - * Install a writable page 0 entry. - */ - - cfg=pg0[0]; - - CMOS_WRITE(0xa, 0xf); - pg0[0]=7; - local_flush_tlb(); - SMP_PRINTK(("1.\n")); - *((volatile unsigned short *) phys_to_virt(0x469)) = ((unsigned long)stack)>>4; - SMP_PRINTK(("2.\n")); - *((volatile unsigned short *) phys_to_virt(0x467)) = 0; - SMP_PRINTK(("3.\n")); - - /* - * Protect it again - */ - - pg0[0]= cfg; - local_flush_tlb(); - - /* walken modif - * enable mapping of the first 4M at virtual - * address zero - */ - - maincfg=swapper_pg_dir[0]; - ((unsigned long *)swapper_pg_dir)[0]=0x102007; - - /* no need to local_flush_tlb : - we are setting this up for the slave processor ! */ - - /* - * Be paranoid about clearing APIC errors. - */ - - if ( apic_version[i] & 0xF0 ) - { - apic_write(APIC_ESR, 0); - accept_status = (apic_read(APIC_ESR) & 0xEF); - } - - /* - * Status is now clean - */ - - send_status = 0; - accept_status = 0; - - /* - * Starting actual IPI sequence... - */ - - SMP_PRINTK(("Asserting INIT.\n")); - - /* - * Turn INIT on - */ - - cfg=apic_read(APIC_ICR2); - cfg&=0x00FFFFFF; - apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ - cfg=apic_read(APIC_ICR); - cfg&=~0xCDFFF; /* Clear bits */ - cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG - | APIC_DEST_ASSERT | APIC_DEST_DM_INIT); - apic_write(APIC_ICR, cfg); /* Send IPI */ - - udelay(200); - SMP_PRINTK(("Deasserting INIT.\n")); - - cfg=apic_read(APIC_ICR2); - cfg&=0x00FFFFFF; - apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ - cfg=apic_read(APIC_ICR); - cfg&=~0xCDFFF; /* Clear bits */ - cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG - | APIC_DEST_DM_INIT); - apic_write(APIC_ICR, cfg); /* Send IPI */ - - /* - * Should we send STARTUP IPIs ? - * - * Determine this based on the APIC version. - * If we don't have an integrated APIC, don't - * send the STARTUP IPIs. - */ - - if ( apic_version[i] & 0xF0 ) - num_starts = 2; - else - num_starts = 0; - - /* - * Run STARTUP IPI loop. - */ - - for (j = 1; !(send_status || accept_status) - && (j <= num_starts) ; j++) - { - SMP_PRINTK(("Sending STARTUP #%d.\n",j)); - - apic_write(APIC_ESR, 0); - SMP_PRINTK(("After apic_write.\n")); - - /* - * STARTUP IPI - */ - - cfg=apic_read(APIC_ICR2); - cfg&=0x00FFFFFF; - apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ - cfg=apic_read(APIC_ICR); - cfg&=~0xCDFFF; /* Clear bits */ - cfg |= (APIC_DEST_FIELD - | APIC_DEST_DM_STARTUP - | (((int)virt_to_phys(stack)) >> 12)); /* Boot on the stack */ - SMP_PRINTK(("Before start apic_write.\n")); - apic_write(APIC_ICR, cfg); /* Kick the second */ - - SMP_PRINTK(("Startup point 1.\n")); - timeout = 0; - do { - SMP_PRINTK(("Sleeping.\n")); udelay(1000000); - udelay(10); - } while ( (send_status = (apic_read(APIC_ICR) & 0x1000)) - && (timeout++ < 1000)); - udelay(200); - - accept_status = (apic_read(APIC_ESR) & 0xEF); - } - SMP_PRINTK(("After Startup.\n")); - - if (send_status) /* APIC never delivered?? */ - printk("APIC never delivered???\n"); - if (accept_status) /* Send accept error */ - printk("APIC delivery error (%lx).\n", accept_status); - - if( !(send_status || accept_status) ) - { - for(timeout=0;timeout<50000;timeout++) - { - if(cpu_callin_map[0]&(1< #include #include +#include #include #include @@ -379,11 +380,15 @@ do_timer(regs); /* * In the SMP case we use the local APIC timer interrupt to do the - * profiling. + * profiling, except when we simulate SMP mode on a uniprocessor + * system, in that case we have to call the local interrupt handler. */ #ifndef __SMP__ if (!user_mode(regs)) x86_do_profile(regs->eip); +#else + if (!smp_found_config) + smp_local_timer_interrupt(regs); #endif /* diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/trampoline.S linux/arch/i386/kernel/trampoline.S --- v2.1.36/linux/arch/i386/kernel/trampoline.S Sun Jan 26 02:07:04 1997 +++ linux/arch/i386/kernel/trampoline.S Mon Apr 28 16:03:29 1997 @@ -21,13 +21,9 @@ * and IP is zero. Thus, data addresses need to be absolute * (no relocation) and are taken with regard to r_base. * - * On the transition to protected mode, this page appears at - * address 8192, so protected mode addresses are with regard - * to p_base. - * * If you work on this file, check the object module with objdump * --full-contents --reloc to make sure there are no relocation - * entries. + * entries except for the gdt one.. */ #include @@ -39,14 +35,13 @@ ENTRY(trampoline_data) r_base = . -p_base = . - 8192 mov %cs, %ax # Code and data in the same place mov %ax, %ds mov %ax, %cx # Pass stack info to the 32bit boot shl $4, %cx # Segment -> Offset - add $4096, %cx # End of page is wanted + add $1024, %cx # Don't overwrite end of page (filled in by kernel_thread) mov $1, %bx # Flag an SMP trampoline cli # We should be safe anyway @@ -71,37 +66,7 @@ gdt_48: .word 0x0800 # gdt limit = 2048, 256 GDT entries - .word gdt - p_base, 0x0 # gdt base = gdt (first SMP CPU) - # we load the others with first table - # saves rewriting gdt_48 for each -gdt: - .word 0, 0, 0, 0 # dummy - - .word 0, 0, 0, 0 # unused - -# walken modif - - .word 0xFFFF # 4 Gb - (0x100000*0x1000 = 4Gb) - .word 0x0000 # base address = 0 - .word 0x9A00 # code read / exec - .word 0x00CF # granularity = 4096, 386 (+5th nibble of limit) - - .word 0xFFFF # 4 Gb - (0x100000*0x1000 = 4Gb) - .word 0x0000 # base address = 0 - .word 0x9200 # data read / write - .word 0x00CF # granularity = 4096, 386 (+5th nibble of limit) - -# walken modif - -# .word 0x07FF # 8 Mb - limit = 2047 (2048 * 4096 = 8 Mb) -# .word 0x0000 # base address = 0 -# .word 0x9A00 # code read / exec -# .word 0x00C0 # granularity = 4096, 386 - -# .word 0x07FF # 8 Mb - limit = 2047 (2048 * 4096 = 8 Mb) -# .word 0x0000 # base address = 0 -# .word 0x9200 # data read / write -# .word 0x00C0 # granularity = 4096, 386 + .long gdt-0xc0000000 # gdt base = gdt (first SMP CPU) .globl SYMBOL_NAME(trampoline_end) SYMBOL_NAME_LABEL(trampoline_end) diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.1.36/linux/arch/i386/kernel/traps.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/traps.c Mon Apr 28 20:45:18 1997 @@ -27,6 +27,7 @@ #include #include #include +#include asmlinkage int system_call(void); asmlinkage void lcall7(void); @@ -138,10 +139,8 @@ printk("ds: %04x es: %04x ss: %04x\n", regs->xds & 0xffff, regs->xes & 0xffff, ss); store_TR(i); - if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page) - printk("Corrupted stack page\n"); printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)\nStack: ", - current->comm, current->pid, 0xffff & i, current->kernel_stack_page); + current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current); stack = (unsigned long *) esp; for(i=0; i < kstack_depth_to_print; i++) { if (((long) stack & 4095) == 0) @@ -181,13 +180,19 @@ printk("\n"); } +spinlock_t die_lock; + /*static*/ void die_if_kernel(const char * str, struct pt_regs * regs, long err) { if ((regs->eflags & VM_MASK) || (3 & regs->xcs) == 3) return; console_verbose(); + spin_lock_irq(&die_lock); printk("%s: %04lx\n", str, err & 0xffff); show_registers(regs); +do { int i=2000000000; while (i) i--; } while (0); +do { int i=2000000000; while (i) i--; } while (0); + spin_unlock_irq(&die_lock); do_exit(SIGSEGV); } @@ -237,7 +242,6 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code) { - printk("NMI\n"); show_registers(regs); #ifdef CONFIG_SMP_NMI_INVAL smp_flush_tlb_rcv(); #else diff -u --recursive --new-file v2.1.36/linux/arch/i386/kernel/vm86.c linux/arch/i386/kernel/vm86.c --- v2.1.36/linux/arch/i386/kernel/vm86.c Thu Feb 27 10:57:29 1997 +++ linux/arch/i386/kernel/vm86.c Mon Apr 28 20:46:56 1997 @@ -81,8 +81,8 @@ printk("vm86: could not access userspace vm86_info\n"); do_exit(SIGSEGV); } - current->tss.esp0 = current->saved_kernel_stack; - current->saved_kernel_stack = 0; + current->tss.esp0 = current->tss.saved_esp0; + current->tss.saved_esp0 = 0; ret = KVM86->regs32; unlock_kernel(); return ret; @@ -137,7 +137,7 @@ lock_kernel(); tsk = current; - if (tsk->saved_kernel_stack) + if (tsk->tss.saved_esp0) goto out; tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, @@ -187,7 +187,7 @@ /* we come here only for functions VM86_ENTER, VM86_ENTER_NO_BYPASS */ ret = -EPERM; - if (tsk->saved_kernel_stack) + if (tsk->tss.saved_esp0) goto out; tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, @@ -247,7 +247,7 @@ * Save old state, set default return value (%eax) to 0 */ info->regs32->eax = 0; - tsk->saved_kernel_stack = tsk->tss.esp0; + tsk->tss.saved_esp0 = tsk->tss.esp0; tsk->tss.esp0 = (unsigned long) &info->VM86_TSS_ESP0; tsk->tss.screen_bitmap = info->screen_bitmap; @@ -601,11 +601,17 @@ static inline int task_valid(struct task_struct *tsk) { struct task_struct *p; + int ret = 0; + read_lock(&tasklist_lock); for_each_task(p) { - if ((p == tsk) && (p->sig)) return 1; + if ((p == tsk) && (p->sig)) { + ret = 1; + break; + } } - return 0; + read_unlock(&tasklist_lock); + return ret; } static inline void handle_irq_zombies(void) diff -u --recursive --new-file v2.1.36/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c --- v2.1.36/linux/arch/i386/mm/fault.c Sun Apr 13 10:18:20 1997 +++ linux/arch/i386/mm/fault.c Sun Apr 27 10:16:30 1997 @@ -169,7 +169,10 @@ /* Are we prepared to handle this fault? */ if ((fixup = search_exception_table(regs->eip)) != 0) { - printk(KERN_DEBUG "Exception at [<%lx>] (%lx)\n", regs->eip, fixup); + printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", + current->comm, + regs->eip, + fixup); regs->eip = fixup; goto out; } diff -u --recursive --new-file v2.1.36/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v2.1.36/linux/arch/i386/mm/init.c Wed Apr 23 19:01:14 1997 +++ linux/arch/i386/mm/init.c Sat Apr 26 10:40:16 1997 @@ -139,12 +139,23 @@ #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"); +/* + * Save the cr4 feature set we're using (ie + * Pentium 4MB enable and PPro Global page + * enable), so that any CPU's that boot up + * after us can get the correct flags. + */ +unsigned long mmu_cr4_features __initdata = 0; + +static inline void set_in_cr4(unsigned long mask) +{ + mmu_cr4_features |= mask; + __asm__(read_cr4 "\n\t" + "orl %0,%%eax\n\t" + write_cr4 + : : "irg" (mask) + :"ax"); +} /* * paging_init() sets up the page tables - note that the first 4MB are diff -u --recursive --new-file v2.1.36/linux/arch/m68k/amiga/retz3fb.c linux/arch/m68k/amiga/retz3fb.c --- v2.1.36/linux/arch/m68k/amiga/retz3fb.c Wed Apr 23 19:01:14 1997 +++ linux/arch/m68k/amiga/retz3fb.c Sun Apr 27 15:13:50 1997 @@ -1750,1755 +1750,3 @@ } 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.36/linux/arch/m68k/amiga/retz3fb.h linux/arch/m68k/amiga/retz3fb.h --- v2.1.36/linux/arch/m68k/amiga/retz3fb.h Wed Apr 23 19:01:14 1997 +++ linux/arch/m68k/amiga/retz3fb.h Sun Apr 27 15:13:50 1997 @@ -284,289 +284,3 @@ #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.36/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c --- v2.1.36/linux/arch/m68k/kernel/process.c Wed Apr 23 19:01:15 1997 +++ linux/arch/m68k/kernel/process.c Sun Apr 27 09:58:44 1997 @@ -30,6 +30,22 @@ #include #include +/* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ +static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, }; +unsigned long init_user_stack[1024] = { STACK_MAGIC, }; +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; + +struct mm_struct init_mm = INIT_MM; +struct task_struct init_task = INIT_TASK; + asmlinkage void ret_from_exception(void); /* diff -u --recursive --new-file v2.1.36/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c --- v2.1.36/linux/arch/m68k/kernel/ptrace.c Wed Apr 23 19:01:15 1997 +++ linux/arch/m68k/kernel/ptrace.c Sun Apr 27 15:08:01 1997 @@ -52,18 +52,6 @@ PT_REG(orig_d0), PT_REG(sr), PT_REG(pc), }; -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * Get contents of register REGNO in task TASK. */ @@ -340,7 +328,7 @@ if (pid == 1) /* you may not mess with init */ goto out; ret = -ESRCH; - if (!(child = get_task(pid))) + if (!(child = find_task_by_pid(pid))) goto out; ret = -EPERM; if (request == PTRACE_ATTACH) { diff -u --recursive --new-file v2.1.36/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c --- v2.1.36/linux/arch/mips/kernel/process.c Thu Dec 19 06:48:08 1996 +++ linux/arch/mips/kernel/process.c Sun Apr 27 09:58:44 1997 @@ -29,6 +29,22 @@ #include #include +/* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ +static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, }; +unsigned long init_user_stack[1024] = { STACK_MAGIC, }; +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; + +struct mm_struct init_mm = INIT_MM; +struct task_struct init_task = INIT_TASK; + asmlinkage void ret_from_sys_call(void); /* diff -u --recursive --new-file v2.1.36/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c --- v2.1.36/linux/arch/mips/kernel/ptrace.c Wed Dec 13 02:39:44 1995 +++ linux/arch/mips/kernel/ptrace.c Sun Apr 27 15:08:01 1997 @@ -33,18 +33,6 @@ */ #define MAGICNUMBER 68 -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * this routine will get a word off of the processes privileged stack. * the offset is how far from the base addr as stored in the TSS. @@ -295,7 +283,7 @@ } if (pid == 1) /* you may not mess with init */ return -EPERM; - if (!(child = get_task(pid))) + if (!(child = find_task_by_pid(pid))) return -ESRCH; if (request == PTRACE_ATTACH) { if (child == current) diff -u --recursive --new-file v2.1.36/linux/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h --- v2.1.36/linux/arch/mips/kernel/syscalls.h Wed Dec 13 02:39:44 1995 +++ linux/arch/mips/kernel/syscalls.h Sun Apr 27 15:08:01 1997 @@ -174,3 +174,4 @@ SYS(sys_munlock, 2) /* 4155 */ SYS(sys_mlockall, 1) SYS(sys_munlockall, 0) +SYS(sys_nfsservctl, 3) diff -u --recursive --new-file v2.1.36/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c --- v2.1.36/linux/arch/mips/kernel/traps.c Wed Dec 13 02:39:44 1995 +++ linux/arch/mips/kernel/traps.c Sun Apr 27 15:08:01 1997 @@ -178,6 +178,7 @@ void do_ades(struct pt_regs *regs) { + struct task_struct *p; unsigned long pc = regs->cp0_epc; int i; @@ -187,12 +188,14 @@ return; } while(1); - for(i=0; ipid >= 2) - { - printk("Process %d\n", task[i]->pid); - dump_list_process(task[i], pc); + read_lock(&tasklist_lock); + for_each_task(p) { + if(p->pid >= 2) { + printk("Process %d\n", p->pid); + dump_list_process(p, pc); } + } + read_unlock(&tasklist_lock); show_regs(regs); dump_tlb_nonwired(); send_sig(SIGSEGV, current, 1); @@ -251,14 +254,16 @@ void do_ri(struct pt_regs *regs) { + struct task_struct *p; int i; - for(i=0; ipid >= 2) - { - printk("Process %d\n", task[i]->pid); - dump_list_process(task[i], 0x7ffff000); + read_lock(&tasklist_lock); + for_each_task(p) { + if(p->pid >= 2) { + printk("Process %d\n", p->pid); + dump_list_process(p, 0x7ffff000); } + } show_regs(regs); while(1); send_sig(SIGILL, current, 1); diff -u --recursive --new-file v2.1.36/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S --- v2.1.36/linux/arch/ppc/kernel/misc.S Wed Dec 18 00:49:52 1996 +++ linux/arch/ppc/kernel/misc.S Sun Apr 27 15:08:01 1997 @@ -855,5 +855,6 @@ .long sys_mremap .long SYMBOL_NAME(sys_setresuid) .long SYMBOL_NAME(sys_getresuid) - .space (NR_syscalls-165)*4 + .long SYMBOL_NAME(sys_nfsservctl) + .space (NR_syscalls-166)*4 diff -u --recursive --new-file v2.1.36/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c --- v2.1.36/linux/arch/ppc/kernel/process.c Sun Jan 26 02:07:05 1997 +++ linux/arch/ppc/kernel/process.c Sun Apr 27 09:58:44 1997 @@ -29,6 +29,24 @@ #include #include + +/* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ +static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, }; +unsigned long init_user_stack[1024] = { STACK_MAGIC, }; +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; + +struct mm_struct init_mm = INIT_MM; +struct task_struct init_task = INIT_TASK; + + int dump_fpu(void); void hard_reset_now(void); void switch_to(struct task_struct *, struct task_struct *); diff -u --recursive --new-file v2.1.36/linux/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c --- v2.1.36/linux/arch/ppc/kernel/ptrace.c Sun Jan 26 02:07:05 1997 +++ linux/arch/ppc/kernel/ptrace.c Sun Apr 27 15:08:01 1997 @@ -42,18 +42,6 @@ static int regoff[] = { }; -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * Get contents of register REGNO in task TASK. */ @@ -394,7 +382,7 @@ if (pid == 1) /* you may not mess with init */ goto out; ret = -ESRCH; - if (!(child = get_task(pid))) + if (!(child = find_task_by_pid(pid))) goto out; ret = -EPERM; if (request == PTRACE_ATTACH) { diff -u --recursive --new-file v2.1.36/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c --- v2.1.36/linux/arch/ppc/mm/init.c Mon Apr 14 16:28:06 1997 +++ linux/arch/ppc/mm/init.c Sun Apr 27 15:08:01 1997 @@ -58,69 +58,62 @@ void show_mem(void) { - unsigned long i,free = 0,total = 0,reserved = 0; - unsigned long shared = 0; - PTE *ptr; - unsigned long full = 0, overflow = 0; - unsigned int ti; + struct task_struct *p; + unsigned long i,free = 0,total = 0,reserved = 0; + unsigned long shared = 0; + PTE *ptr; + unsigned long full = 0, overflow = 0; + unsigned int ti; - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); - i = MAP_NR(high_memory); - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (!atomic_read(&mem_map[i].count)) - free++; - else - shared += atomic_read(&mem_map[i].count) - 1; - } - printk("%lu pages of RAM\n",total); - printk("%lu free pages\n",free); - printk("%lu reserved pages\n",reserved); - printk("%lu pages shared\n",shared); - show_buffers(); + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + i = MAP_NR(high_memory); + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (!atomic_read(&mem_map[i].count)) + free++; + else + shared += atomic_read(&mem_map[i].count) - 1; + } + printk("%lu pages of RAM\n",total); + printk("%lu free pages\n",free); + printk("%lu reserved pages\n",reserved); + printk("%lu pages shared\n",shared); + show_buffers(); #ifdef CONFIG_NET - show_net_buffers(); + show_net_buffers(); #endif #ifdef HASHSTATS - printk("Hash Hits %u entries (buckets)\n",(Hash_size/sizeof(struct _PTE))/8); - for ( i = 0; i < (Hash_size/sizeof(struct _PTE))/8; i++ ) - { - if ( hashhits[i] >= 20 ) - { - printk("[%lu] \t %lu\n", i,hashhits[i]); - } - } + printk("Hash Hits %u entries (buckets)\n",(Hash_size/sizeof(struct _PTE))/8); + for ( i = 0; i < (Hash_size/sizeof(struct _PTE))/8; i++ ) { + if ( hashhits[i] >= 20 ) + printk("[%lu] \t %lu\n", i,hashhits[i]); + } #endif - for ( ptr = Hash ; ptr <= Hash+Hash_size ; ptr++) - { - if (ptr->v) - { - full++; - if (ptr->h == 1) - overflow++; - } - } - printk("Hash Table: %dkB Buckets: %dk PTEs: %d/%d (%%%d full) %d overflowed\n", - Hash_size>>10, (Hash_size/(sizeof(PTE)*8)) >> 10, - full,Hash_size/sizeof(PTE), - (full*100)/(Hash_size/sizeof(PTE)), - overflow); - printk(" Task context vsid0\n"); - for ( ti = 0; ti < NR_TASKS ; ti++ ); - { - if ( task[ti] ) - { - printk("%5d %8x %8x\n", - task[ti]->pid,task[ti]->mm->context, - ((SEGREG *)task[ti]->tss.segs)[0].vsid); - } - } - + for ( ptr = Hash ; ptr <= Hash+Hash_size ; ptr++) { + if (ptr->v) { + full++; + if (ptr->h == 1) + overflow++; + } + } + printk("Hash Table: %dkB Buckets: %dk PTEs: %d/%d (%%%d full) %d overflowed\n", + Hash_size>>10, (Hash_size/(sizeof(PTE)*8)) >> 10, + full,Hash_size/sizeof(PTE), + (full*100)/(Hash_size/sizeof(PTE)), + overflow); + printk(" Task context vsid0\n"); + read_lock(&tasklist_lock); + for_each_task(p) { + printk("%5d %8x %8x\n", + p->pid,p->mm->context, + ((SEGREG *)p->tss.segs)[0].vsid); + } + read_unlock(&tasklist_lock); } extern unsigned long free_area_init(unsigned long, unsigned long); diff -u --recursive --new-file v2.1.36/linux/arch/sparc/ap1000/bnet.c linux/arch/sparc/ap1000/bnet.c --- v2.1.36/linux/arch/sparc/ap1000/bnet.c Sun Jan 26 02:07:06 1997 +++ linux/arch/sparc/ap1000/bnet.c Sun Apr 27 15:08:01 1997 @@ -872,12 +872,12 @@ len = req->size - sizeof(*req); if (len == 0) { int pid = req->data[1]; - for_each_task(p) - if (p->pid == pid) { - send_sig(sig,p,1); - return; - } - printk("cell %d: no task with pid %d\n",mpp_cid(),pid); + p = find_task_by_pid(pid); + + if(p) + send_sig(sig, p, 1); + else + printk("cell %d: no task with pid %d\n",mpp_cid(),pid); return; } @@ -889,9 +889,11 @@ read_bif(name,len); name[len] = 0; + read_lock(&tasklist_lock); for_each_task(p) if (strcmp(name,p->comm) == 0) send_sig(sig,p,1); + read_unlock(&tasklist_lock); } diff -u --recursive --new-file v2.1.36/linux/arch/sparc/ap1000/hw.c linux/arch/sparc/ap1000/hw.c --- v2.1.36/linux/arch/sparc/ap1000/hw.c Sun Jan 26 02:07:06 1997 +++ linux/arch/sparc/ap1000/hw.c Sun Apr 27 15:08:01 1997 @@ -86,14 +86,21 @@ static void show_ptasks(void) { extern struct task_struct *task[]; + struct task_struct *p; int i; int count=0; - for (i=MPP_TASK_BASE;itarray_ptr; + + if(tp >= &task[MPP_TASK_BASE]) { + show_task(p); count++; } + } + read_unlock(&tasklist_lock); + if (count == 0) printk("no parallel tasks on cell %d\n",mpp_cid()); } @@ -101,14 +108,18 @@ static void show_utasks(void) { extern struct task_struct *task[]; + struct task_struct *p; int i; int count=0; - for (i=0;iuid > 1) { + read_lock(&tasklist_lock); + for_each_task(p) { + if(p->uid > 1) { show_task(task[i]); count++; } + } + read_unlock(&tasklist_lock); if (count == 0) printk("no user tasks on cell %d\n",mpp_cid()); @@ -118,15 +129,19 @@ static void show_otasks(void) { extern struct task_struct *task[]; + struct task_struct *p; int i; int count=0; extern int ap_current_uid; - for (i=0;iuid == ap_current_uid) { + read_lock(&tasklist_lock); + for_each_task(p) { + if(p->uid == ap_current_uid) { show_task(task[i]); count++; } + } + read_unlock(&tasklist_lock); if (count == 0) printk("no tasks on cell %d\n",mpp_cid()); diff -u --recursive --new-file v2.1.36/linux/arch/sparc/ap1000/mpp.c linux/arch/sparc/ap1000/mpp.c --- v2.1.36/linux/arch/sparc/ap1000/mpp.c Sun Jan 26 02:07:06 1997 +++ linux/arch/sparc/ap1000/mpp.c Sun Apr 27 15:08:01 1997 @@ -66,6 +66,7 @@ if (block_parallel_tasks) return -1000; + /* XXX task[] fixme */ if (last_task && last_task != tsk->taskid && task[last_task] && !msc_switch_ok()) return -1000; diff -u --recursive --new-file v2.1.36/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c --- v2.1.36/linux/arch/sparc/kernel/process.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/process.c Sun Apr 27 09:58:44 1997 @@ -39,6 +39,22 @@ #include #include +/* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ +static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, }; +unsigned long init_user_stack[1024] = { STACK_MAGIC, }; +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; + +struct mm_struct init_mm = INIT_MM; +struct task_struct init_task = INIT_TASK; + extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *); #ifndef __SMP__ diff -u --recursive --new-file v2.1.36/linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c --- v2.1.36/linux/arch/sparc/kernel/ptrace.c Wed Apr 23 19:01:16 1997 +++ linux/arch/sparc/kernel/ptrace.c Sun Apr 27 15:08:01 1997 @@ -24,18 +24,6 @@ #define MAGIC_CONSTANT 0x80000000 -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * This routine gets a long from any process space by following the page * tables. NOTE! You should check that the long isn't on a page boundary, @@ -533,7 +521,7 @@ goto out; } #endif - if(!(child = get_task(pid))) { + if(!(child = find_task_by_pid(pid))) { pt_error_return(regs, ESRCH); goto out; } diff -u --recursive --new-file v2.1.36/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c --- v2.1.36/linux/arch/sparc/kernel/sys_sunos.c Wed Apr 23 19:01:16 1997 +++ linux/arch/sparc/kernel/sys_sunos.c Sun Apr 27 15:08:01 1997 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.78 1997/04/16 05:56:12 davem Exp $ +/* $Id: sys_sunos.c,v 1.79 1997/04/23 23:01:15 ecd Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1031,7 +1032,48 @@ unlock_kernel(); return ret; } - + +extern asmlinkage int sys_msgget (key_t key, int msgflg); +extern asmlinkage int sys_msgrcv (int msqid, struct msgbuf *msgp, + size_t msgsz, long msgtyp, int msgflg); +extern asmlinkage int sys_msgsnd (int msqid, struct msgbuf *msgp, + size_t msgsz, int msgflg); +extern asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf); + +asmlinkage int sunos_msgsys(int op, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4) +{ + struct sparc_stackf *sp; + unsigned long arg5; + int rval; + + lock_kernel(); + switch(op) { + case 0: + rval = sys_msgget((key_t)arg1, (int)arg2); + break; + case 1: + rval = sys_msgctl((int)arg1, (int)arg2, + (struct msqid_ds *)arg3); + break; + case 2: + sp = (struct sparc_stackf *)current->tss.kregs->u_regs[UREG_FP]; + arg5 = sp->xxargs[0]; + rval = sys_msgrcv((int)arg1, (struct msgbuf *)arg2, + (size_t)arg3, (long)arg4, (int)arg5); + break; + case 3: + rval = sys_msgsnd((int)arg1, (struct msgbuf *)arg2, + (size_t)arg3, (int)arg4); + break; + default: + rval = -EINVAL; + break; + } + unlock_kernel(); + return rval; +} + extern asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr); extern asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf); extern asmlinkage int sys_shmdt (char *shmaddr); diff -u --recursive --new-file v2.1.36/linux/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S --- v2.1.36/linux/arch/sparc/kernel/systbls.S Wed Apr 23 19:01:16 1997 +++ linux/arch/sparc/kernel/systbls.S Sun Apr 27 15:08:01 1997 @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.60 1997/04/19 08:52:15 jj Exp $ +/* $Id: systbls.S,v 1.62 1997/04/23 23:01:08 ecd Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -106,15 +106,26 @@ .long C_LABEL(sys_nis_syscall), C_LABEL(sys_stime), C_LABEL(sys_nis_syscall) .long C_LABEL(sys_nis_syscall), C_LABEL(sys_llseek) /* "We are the Knights of the Forest of Ni!!" */ - .long C_LABEL(sys_mlock), C_LABEL(sys_munlock), C_LABEL(sys_mlockall) - .long C_LABEL(sys_munlockall), C_LABEL(sys_sched_setparam) - .long C_LABEL(sys_sched_getparam), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall) - .long C_LABEL(sys_nis_syscall), C_LABEL(sys_sched_get_priority_max), C_LABEL(sys_sched_get_priority_min) - .long C_LABEL(sys_sched_rr_get_interval), C_LABEL(sys_nanosleep) + .long C_LABEL(sys_mlock) + .long C_LABEL(sys_munlock) + .long C_LABEL(sys_mlockall) +/*240*/ .long C_LABEL(sys_munlockall) + .long C_LABEL(sys_sched_setparam) + .long C_LABEL(sys_sched_getparam) + .long C_LABEL(sys_sched_setscheduler) + .long C_LABEL(sys_sched_getscheduler) +/*245*/ .long C_LABEL(sys_sched_yield) + .long C_LABEL(sys_sched_get_priority_max) + .long C_LABEL(sys_sched_get_priority_min) + .long C_LABEL(sys_sched_rr_get_interval) + .long 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_nfsservctl) - .long C_LABEL(sys_aplib), C_LABEL(sys_nis_syscall) + .long C_LABEL(sys_getsid) + .long C_LABEL(sys_fdatasync) + .long C_LABEL(sys_nfsservctl) +/*255*/ .long C_LABEL(sys_aplib) + .long C_LABEL(sys_nis_syscall) /* Now the SunOS syscall table. */ @@ -179,7 +190,7 @@ .long C_LABEL(sunos_getdomainname), C_LABEL(sys_setdomainname) .long C_LABEL(sunos_nosys), C_LABEL(sys_quotactl), C_LABEL(sunos_nosys) .long C_LABEL(sunos_mount), C_LABEL(sys_ustat), C_LABEL(sunos_semsys) - .long C_LABEL(sunos_nosys), C_LABEL(sunos_shmsys), C_LABEL(sunos_audit) + .long C_LABEL(sunos_msgsys), C_LABEL(sunos_shmsys), C_LABEL(sunos_audit) .long C_LABEL(sunos_nosys), C_LABEL(sunos_getdents), C_LABEL(sys_setsid) .long C_LABEL(sys_fchdir), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys) .long C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys) diff -u --recursive --new-file v2.1.36/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c --- v2.1.36/linux/arch/sparc64/kernel/process.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/process.c Sun Apr 27 09:58:44 1997 @@ -37,6 +37,22 @@ #include #include +/* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ +static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, }; +unsigned long init_user_stack[1024] = { STACK_MAGIC, }; +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; + +struct mm_struct init_mm = INIT_MM; +struct task_struct init_task = INIT_TASK; + #ifndef __SMP__ /* diff -u --recursive --new-file v2.1.36/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c --- v2.1.36/linux/drivers/block/ide-disk.c Wed Dec 11 06:45:54 1996 +++ linux/drivers/block/ide-disk.c Sun Apr 27 19:59:02 1997 @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -59,6 +58,7 @@ #include #include #include +#include #include #include diff -u --recursive --new-file v2.1.36/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c --- v2.1.36/linux/drivers/block/ide-probe.c Sat Jan 25 10:51:17 1997 +++ linux/drivers/block/ide-probe.c Sun Apr 27 19:59:02 1997 @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include @@ -58,6 +57,7 @@ #include #include #include +#include #include #include diff -u --recursive --new-file v2.1.36/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.1.36/linux/drivers/block/ide.c Wed Apr 23 19:01:17 1997 +++ linux/drivers/block/ide.c Sun Apr 27 19:59:03 1997 @@ -294,7 +294,6 @@ #include #include #include -#include #include #include #include @@ -307,6 +306,7 @@ #include #include #include +#include #include #include diff -u --recursive --new-file v2.1.36/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.1.36/linux/drivers/char/Config.in Sun Apr 13 10:18:20 1997 +++ linux/drivers/char/Config.in Tue Apr 29 11:45:43 1997 @@ -19,7 +19,10 @@ fi bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then - tristate 'Digiboard PC/Xx Support' CONFIG_DIGI + tristate 'Digiboard Intelligent Async Support' CONFIG_DIGIEPCA + if [ "$CONFIG_DIGIEPCA" = "n" ]; then + tristate 'Digiboard PC/Xx Support' CONFIG_DIGI + fi tristate 'Cyclades async mux support' CONFIG_CYCLADES bool 'Stallion multiport serial support' CONFIG_STALDRV if [ "$CONFIG_STALDRV" = "y" ]; then diff -u --recursive --new-file v2.1.36/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.1.36/linux/drivers/char/Makefile Wed Apr 23 19:01:17 1997 +++ linux/drivers/char/Makefile Tue Apr 29 11:45:43 1997 @@ -61,6 +61,14 @@ endif endif +ifeq ($(CONFIG_DIGIEPCA),y) +L_OBJS += epca.o +else + ifeq ($(CONFIG_DIGIEPCA),m) + M_OBJS += epca.o + endif +endif + ifeq ($(CONFIG_CYCLADES),y) L_OBJS += cyclades.o else diff -u --recursive --new-file v2.1.36/linux/drivers/char/README.epca linux/drivers/char/README.epca --- v2.1.36/linux/drivers/char/README.epca Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/README.epca Tue Apr 29 11:45:43 1997 @@ -0,0 +1,506 @@ +user.doc +Digi International driver package for the PC/Xe, PC/Xi, PC/Xr, PC/Xem as well +the EISA and PCI variants of these boards where applicable. +Copyright (C) 1996 Digi International. Written by Ronnie Sanford digilnux@dgii.com + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (At your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not write to the Free Software Foundation, Inc., + 675 Mass Ave, Cambridge, MA 02139, USA. + + +This document describes the software used with the Digi/Linux driver package. +The four user programs listed below are described in this document: + + 1. digiConfig -> Application that configures the Digi driver. + + 2. digiDload -> Application which initializes the Digi hardware. + + 3. buildPCI -> Application which provides the user a method of + building device nodes for PCI devices. + + 4. ditty -> Application which provides the user a method of + configuring terminal options on Digi hardware. + + + +-------------------------------------------------------------------------- +1. Configuring driver/kernel for Digi products +-------------------------------------------------------------------------- + + The Digi driver must be configured each time Digi hardware is added + or removed. There are two supported methods of doing this. The + first method configures the driver dynamically at boot time but requires + the user to utilize the lilo loader. This method is the preffered method + as it does not require the rebuilding of the kernel. In order to use lilo + to configure Digi boards at boot time an appropriate append command should + be added to /etc/lilo.conf below the appropriate label decleration. + See footer 4. The append commands format is a string of comma seperated + identifiers or integers used to configure supported boards. These six + values in order are: + + Enable/Disable this card or Override, + Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2), + EISA/Xem (3), PC/Xe (64K) (4), PC/Xi (5). + Enable/Disable alternate pin arrangement, + Number of ports on this card, + I/O Port where card is configured (in HEX if using string identifiers), + Base of memory window (in HEX if using string identifiers) + + A sample append command is given below which if used would configure and + enable a PC/Xe with 8 ports, at i/o address 200, memory address 0xd0000 + with alt pin turned off. The lilo.conf file should look like this: + + image = /vmlinuz + root = /dev/hda2 + label = vmlinuz + append="digiepca=E,PC/Xe,D,8,200,D0000" + + likewise the below will perform the same function: + + image = /vmlinuz + root = /dev/hda2 + label = vmlinuz + append="digiepca=1,0,0,8,512,851968" + + Note: + + PCI boards are auto-detected and configured (Hence their codes are + not given here). Do not attempt to configure PCI boards with the lilo + append command. + + If configuration data has been specified by using digiConfig (Described + below), and you wish to override this configuration using lilo without + specifying a specific card (Example if there are PCI cards in the system) + the following override command will accomplish this: + + -> append="digiepca=2" + + If lilo is not enabled, the second method of configuring Digi hardware + will have to be used. digiConfig is an application that can be used + to inform the system of any additions, deletions, or modifications + involving Digi hardware. To use this method the operator executes + digiConfig anytime an EISA or ISA card is added that he wishes to use. + This routine is also used to remove cards from the system, and to modify + parameters of those cards already present in the system. Upon being + executed digiConfig modifies files accessed by the Digi driver. To make + these changes permanent; the operating system must be recompiled. After + the operating system has been recompiled and booted, the changes made with + digiConfig will be introduced to the user. This program MUST be executed + every time Digi EISA/ISA hardware configuration changes. Note, it is not + necessary to execute digiConfig in order to configure the Digi PCI cards. + These cards are self-identifying and will be recognized by the driver. + They cannot be displayed using digiConfig nor will digiConfig build the + device nodes their device nodes. See footer 1. + + To execute digiConfig; simply type: digiConfig + + The application will query you for the type, memory address, port + address, number of ports, alt pin disposition and status of each board + that exist on the system. Note, currently this driver only supports + PC/Xe, PC/Xeve, PC/Xi, PC/Xr, and PC/Xem as well as their EISA and PCI + implementations if applicable. All supported cards (Other than PCI) that + are present should be registered via digiConfig. See footer 2. + + After all cards have been configured select exit. The system will then + inform you if any changes have been made, and ask you if it is okay to + make these changes permanent. If the data entered is correct, select okay. + Selecting cancel will prevent the changes from becoming active. digiConfig + can then be re-executed to configure the system again. + +-------------------------------------------------------------------------- +2. Initializing Digi hardware with digiDload +-------------------------------------------------------------------------- + + digiDload is the application executed after the Digi driver has been + loaded. It is responsible for initializing the hardware and leaving + it in a state such that the Digi board may be operated by the user. + The application may be placed anywhere on the path, but its related + support files must be located in /etc/digi. The related files are: + + sxfep.bin + sxbios.bin + xxfep.bin + xxbios.bin + + The format for this command is "digiDload [v]". If given the "v" + option turns on verbosity. If not given the application runs in quite + mode. To execute the program simply type: + + digiDload + + Upon completion digiDload will generate the below message: + + "digiDload complete: Card initialized" + + At this point the card is configured and ready for normal usage. See + technotes.doc for information on how how ports are determined and + assigned. + +-------------------------------------------------------------------------- +3. Build PCI device nodes with buildPCI +-------------------------------------------------------------------------- + + buildPCI is an application useful for building the necessary device nodes + for Digi PCI cards. It is reccomended that this tool be used because the + current digiConfig application does not provide this function for PCI cards + (Though it does build device nodes for non-PCI cards). To use this program + execute the following:first install the driver, and execute digiDload (See above). After digiDload + has sucessfully loaded, execute the following: + + buildPCI + + Where arg1 is the number of ports connected to Digi cards that are not PCI + (As shown by the digiConfig utility), and arg2 is the number of ports + connected to Digi cards that are PCI. + + Note, buildPCI only has to be ran once to build the necessary device + nodes. Though this program may be executed at anytime, we reccomend + delaying execution until the first time you install the package and after + digiDload has been executed. + +-------------------------------------------------------------------------- +4. Setting Terminal Options with ditty +-------------------------------------------------------------------------- + +ditty is a utility program that sets and displays the terminal options +for Digi intelligent serial products. See man ditty for detailed information. + + +Footnotes: + +1. The 1.2.x kernel does not provide a method of mapping the high + addresses (Normally higher than RAM) associated with PCI. For this + reason, this driver disables PCI support while running under the 1.2.x + kernels. + +2. PCI cards should not and cannot be registered with digiConfig. After + the driver has been loaded buildPCI may be executed to construct the + necessary device nodes. This step is not necessary for system not + having Digi PCI cards. + +3. This is because we forsee a time when buildPCI may auto-detect the + available Digi PCI cards and this would only work if the program is + executed after digiDload. + +4. A complete example is given in install.doc. + +-------------CHANGES-------------------- + +All changes should be recorded here. All changes should be explained in +verbose detail. +----------------------------------------------------------------------- +Programmer : Ronnie Sanford +Date : June 1, 1996 +Description (Verbose) : Initial release of driver package. +Files affected : all +Release version : 1.0.0f (BETA) +----------------------------------------------------------------------- +----------------------------------------------------------------------- +Programmer : Ronnie Sanford +Date : August 7, 1996 +Description (Verbose) : Made several modifications to provide PCI and EISA + support: + + 1. We now allocate the termios structures based on + the maximum number of channels that COULD be + available to the system. We no longer use the + number of channels declared in epcaconfig.h + (NBDEVS) as the total channel number. This is + because this value does not represent channels + available to potential PCI cards. This new + larger value is also passed back to the os in + the num field of tty_driver. + + 2. Added code to copy the previous board structure + (Now called static_boards) into a new local + copy of the boards structure. This has been + done so that PCI cards may be added to this + board array and later referenced (And even + queried.). + + 3. Added code to pc_init that checks for supported + PCI cards. If found this code initializes a new + entry into the drivers local board structure + with the PCI cards address, and type, etc.. It + also bumps the card count (num_cards). + + 4. Modified code in post_fep_init so that when this + routine is executed the number of ports supported + by a particular PCI card will be determined and + loaded into the board structure. It would be + much better if this code was placed in pc_init + (Because we could then report to the os the true + number of ports available; not just the max), but + since the card has to be booted to determine the + number of ports it supports, we are forced to do it + after DIGI_INIT has called post_fep_init. In the + future we may attempt to read the num ports + attached directly (address 0x1ac). + + 5. Added board types to epca.h in support of various + PCI boards (Some of which do not exist yet). + Added procedures for these boards throughout the + code. Note, windowing is not necessary for PCI + boards. + + 6. Added code supporting the EISA/XEM. This included + modifying epca.h with the new board type and + adding this type into the driver. The EISA/XEM + is basically identical to the PC/XEM, other than + it's base address does not have to be (And cannot + be configured directly). + + 7. Modified digiConfig to prompt for EISA/XEM cards. + +Files affected : epca.c, epca.h, digi1.h, digiConfig +Release version : 1.0.0g (BETA) +----------------------------------------------------------------------- +----------------------------------------------------------------------- +Programmer : Ronnie Sanford +Date : August 21, 1996 +Description (Verbose) : Made the following modifications: + + 1. A problem affecting hard flow control was found + in the termios2digi_h routine. Specifically, + when the user activated hard flow control using + the CRTSCTS specification, the values used to + program hard flow control on the board were + incorrect. The solution was to change a line + that read "res |= ((ch->m_dtr) | (ch->m_rts));" + to "res |= ((ch->m_cts) | (ch->m_rts));" This + line only applies if cflag & CRTSCTS. Special + thanks to Matt Robinson (matt@mania.com.au) who + found and fixed this problem. + + 2. In previous betas the cud device was set to CLOCAL + on driver boot up. Likewise the ttyD device was + set to ~CLOCAL. This has been fixed in this driver. + Now ttyD is CLOCAL and cud is ~CLOCAL. The fix + for this can be found in pc_init. + + 3. In ditty.c many changes were made to eliminate bugs + and warning messages. Two ioctl calls were eliminated + as well a problem involving using the returned baud + index to determine the drivers baud rate. Newer + Linux kernels support higher baud rates by using + 0x1000 bit. When the returned value (ored with + 0x1000) was used to reference our fbaud table a + serious memory problem occured. This has been fixed. + + 4. Added a request_region call to post_fep_init. This + should cause the i/o ports being used to be + registered with proc. + + 5. Modified digiConfig to set all cud and ttyD devices + to read/write all permission. + + 6. Developed a new apps called buildPCI that provides + an easy way to build device nodes for PCI cards. + + 7. Modified user.doc and technotes.doc document the + use of buildPCI. + +Files affected : epca.c, ditty.c, digiConfig, user.doc, technotes.doc +Release version : 1.0.0 (Official release) +----------------------------------------------------------------------- +Programmer : Ronnie Sanford +Date : August 21, 1996 +Description (Verbose) : Made the following modifications: + + 1. Removed code from pc_close which closes the + drivers line discipline and restores its original + line discipline. This is currently unecessary, + though future fast cook enhancements may require + this. + + 2. Removed code in block_til_ready that set the + asyncflags to either ASYNC_CALLOUT_ACTIVE, or + ASYNC_NORMAL_ACTIVE. This code was redundant + as it already existed in block_til_ready. + + 3. Added code in block_til_ready to cause a return + prior to schedule being called if the device + was a CALLOUT device. CALLOUT devices never + block on CD. (This was a serious bug that + prevented the CALLOUT devices (ttyD) from + functioning properly in some instances. + + Make a change in the MODEMCHG_IND case of doevent + such that it does not require ASYNC_CALLOUT_ACTIVE + or ASYNC_NORMAL_ACTIVE to be set in order to + unblock an open (Using wait_interruptible). + + Thanks to Mike McLagan (mike.mclagan@linux.org) + for diagnosing and fixing this problem. + + 4. Made changes to the disposition of CLOCAL on + both SERIAL NORMAL and CALLOUT devices. Both + device types now have CLOCAL active at default. + This may be changed with a stty command. + + 5. Made changes to digiConfig such that it checks + major.h (If valid) for the correct major + numbers to use. + +Files affected : epca.c, digiConfig +Release version : 1.0.1a + + +----------------------------------------------------------------------- +Programmer : Ronnie Sanford +Date : September 17, 1996 +Description (Verbose) : Made the following modifications: + + 1. Modified pc_open such that it no longer checks + the cflag value returned by termios2digi_c for + CLOCAL. Digi hardware does not use this value + and thus termios2digi_c rightly screens this + value out. This driver checks for CLOCAL using + the drivers cflag value as known by the Linux OS. + (The value passed into termios2digi_c) + + 2. Modified termios2digi_c to screen out the + CBAUDEX in CBAUD. This error caused parity to + automaticaly be enabled on at higher baud rates. + + + 3. Added the "disable_bh()" call to the shutdown + subroutine. Hopefully this will allow the driver + to correctly clean up after itself when used as a + module. + + 4. Added support for the PC/XI and 64K PC/XE cards. + This involved primarily modifying digiDload to + initialize and boot the new cards; however + driver modifications were also required to + provide the proper windowing for the newly + supported cards. (Code was also added to + determine the memory segment of the XI card as + that card may have more than 64K. Currently + digiDload assumes a 64K XI card.) + + 5. Added subroutine called epca_setup that can be + called during LILO boot up. This provides the + user an easy way to change cards; without + running digiConfig and without recompiling the + kernel. Added code in pc_init and pc_open to + support the epca_setup routine. pc_init checks + the liloconfig flag (Which is set by epca_setup) + to determine if the driver is using the LILO + arguments. If not pc_init loads the board data + found in epcaconfig.h; if so it DOESN'T load + epcaconfig data depending on epca_setup to handle + board configuration. pc_open has been modified + such that it checks to insure that no errors + occured during the LILO boot process. If a + user attempts to boot the driver (via. LILO) + with incorrect data, the open will fail. + + 6. Modified the windowing routines pcxe_rxwinon + and pcxe_txwinon routines. A bug existed such + that those routines checked to see if the rxwin + and txwin flags were reset. If so they assumed + the board was an XI or 64K XE. Furthermore since + these flags were never initialized in our driver + sometimes they were 0 and therefore caused a + memory fault (Or at least a window overrun). This + code has been removed since the pcxe shares + nothing in common with the 64K XI and XE. + + 7. Added code in pc_init to set the memory_seg for + the various boards. This code was necessary to + correct a bug in the PCXE, PCXEVE code where + receive and transmit pointers were being calculated + from an uninitialized variable (memory_seg). + + 8. Modified digiConfig to allow 64K PC/XI and 64K + PC/XE cards to be configured. + + 9. Made changes to support the new 2.1.x development + kernel. In particular this required changing all + references to vremap to ioremap. + + 10. Modified digiConfig such that it now generates + node names corresponding to their internal + as opposed to the label on the port itself. Nodes + (ttyD?? and cud??) now start at 0. Example: + ttyD0 and cud0 represent port 1 on any supported + Digi product. A similar change has been made + in buildPCI.c. + + 12. At the early portion of post_fep_init if a PCI + card is detected a warning message could be given + incorrectly if 64 ports were attached to a PCI + card. The below line : + + epcaassert(bd->numports > 64,"PCI returned a invalid number of ports"); + + was changed to : + + epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports"); + + Remember that epcaassert checks for NOT true. + Special thanks to Daniel Taylor for fixing this. + + 13. Modified the epcaparam routine. In version 100 + and 101a there was a line that looked like the + below: + + if (ch->omodem != mval) + + The problem with this line was that the first time + through omodem was not initialized. Secondly, since + many TIOC commands did not alter mval (They use + a different variable) changes made by these commands + could be lost. This line was changed to: + + mval ^= ch->modemfake & (mval ^ ch->modem); + + if (ch->omodem ^ mval) + + 14. Modified digiConfig in such a way that it checks + the version number of the kernel and if it finds + a 2.x.x kernel or higher it reads the necessary + major numbers for cud and ttyD devices from major.h. + This was also done in prior versions but these + versions required a #define which identified the + kernel as a version which did not have major numbers + assigned to Digi systems. This #define is no + longer required allowing the same source tree for + multiple kernel releases. + + 15. Used macros to replace kernel specific calls such + as put_fs_long, get_fs_long, put_user, and get_user + the kernel version is now detected and the macro + is defined as to correspond with the kernel it + is being compiled into. Again this was done to + allow one source tree for multiple kernel releases. + + 16. Added support for the new 2.1.x development kernels + to digiInstall. + +Files affected : epca.c, digiConfig +Release version : 1.1.0 +----------------------------------------------------------------------- +Programmer : Daniel Taylor +Date : April 25, 1997 +Description (Verbose) : Updated driver: + 1. Fixed DCD bug. (&tq_scheduler) + 2. Removed BH handler code, as it was only handling + hangups, and not being called for that. + 3. Namespace cleanup (DIGI_TIMER2 => DIGI_TIMER) + 4. Updated to 2.1.36, removed #ifdefs for earlier + kernel revisions. +Files affected : epca.c +Release version : 1.1.1 (BETA) +----------------------------------------------------------------------- diff -u --recursive --new-file v2.1.36/linux/drivers/char/dsp56k.c linux/drivers/char/dsp56k.c --- v2.1.36/linux/drivers/char/dsp56k.c Wed Apr 23 19:01:17 1997 +++ linux/drivers/char/dsp56k.c Sun Apr 27 15:13:50 1997 @@ -573,578 +573,3 @@ 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.36/linux/drivers/char/epca.c linux/drivers/char/epca.c --- v2.1.36/linux/drivers/char/epca.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/epca.c Tue Apr 29 11:45:43 1997 @@ -0,0 +1,4313 @@ +/* + + + Copyright (C) 1996 Digi International. + + For technical support please email digiLinux@dgii.com or + call Digi tech support at (612) 912-3456 + + Much of this design and code came from epca.c which was + copyright (C) 1994, 1995 Troy De Jongh, and subsquently + modified by David Nugent, Christoph Lameter, Mike McLagan. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +--------------------------------------------------------------------------- */ +/* See README.epca for change history --DAT*/ + + +#ifdef MODVERSIONS +#define MODULE +#endif + +/* ----------------------------------------------------------------------- + This way modules should work regardless if they defined MODULE or + MODVERSIONS. (MODVERSIONS is for the newer kernels ... +-------------------------------------------------------------------------- */ + +#ifdef MODULE +#include +#endif /* MODULE */ + +#include + +#define NEW_MODULES + +#ifdef NEW_MODULES +#ifdef MODVERSIONS +#include +#endif /* MODVERSIONS */ +#endif /* NEW_MODULES */ + +#ifdef MODULE +#include +#endif /* MODULE */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef MODULE +#ifndef NEW_MODULES +char kernel_version[]=UTS_RELEASE; +#endif /* NEW_MODULE */ +#endif /* MODULE */ + + +#ifdef CONFIG_PCI +#define ENABLE_PCI +#endif /* CONFIG_PCI */ + + + +#include +#define putUser(arg1, arg2) put_user(arg1, (unsigned long *)arg2) +#define getUser(arg1, arg2) get_user(arg1, (unsigned int *)arg2) + + + +#ifdef ENABLE_PCI +#include +#include +#include +#endif /* ENABLE_PCI */ + +#include +#include +#include +#include + +/* ---------------------- Begin defines ------------------------ */ + +#define VERSION "1.1.0" + +/* This major needs to be submitted to Linux to join the majors list */ + +#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */ + + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAXCARDS 7 +#define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg) + +/* ----------------- Begin global definitions ------------------- */ + +static char mesg[100]; +static int pc_refcount, nbdevs = 0, num_cards = 0, liloconfig = 0; +static int digi_poller_inhibited = 1 ; + +static int setup_error_code = 0; +static int invalid_lilo_config = 0; + +/* ----------------------------------------------------------------------- + MAXBOARDS is typically 12, but ISA and EISA cards are restricted to + 7 below. +--------------------------------------------------------------------------*/ +static struct board_info boards[7]; + + +/* ------------- Begin structures used for driver registeration ---------- */ + +struct tty_driver pc_driver; +struct tty_driver pc_callout; +struct tty_driver pc_info; + +/* The below structures are used to initialize the tty_driver structures. */ + +/* ------------------------------------------------------------------------- + Note : MAX_ALLOC is currently limited to 0x100. This restriction is + placed on us by Linux not Digi. +----------------------------------------------------------------------------*/ +static struct tty_struct *pc_table[MAX_ALLOC]; +static struct termios *pc_termios[MAX_ALLOC]; +static struct termios *pc_termios_locked[MAX_ALLOC]; + + +/* ------------------ Begin Digi specific structures -------------------- */ + +/* ------------------------------------------------------------------------ + digi_channels represents an array of structures that keep track of + each channel of the Digi product. Information such as transmit and + receive pointers, termio data, and signal definitions (DTR, CTS, etc ...) + are stored here. This structure is NOT used to overlay the cards + physical channel structure. +-------------------------------------------------------------------------- */ + +static struct channel digi_channels[MAX_ALLOC]; + +/* ------------------------------------------------------------------------ + card_ptr is an array used to hold the address of the + first channel structure of each card. This array will hold + the addresses of various channels located in digi_channels. +-------------------------------------------------------------------------- */ +static struct channel *card_ptr[MAXCARDS]; + +/* ---------------------- Begin function prototypes --------------------- */ + +/* ---------------------------------------------------------------------- + Begin generic memory functions. These functions will be alias + (point at) more specific functions dependant on the board being + configured. +----------------------------------------------------------------------- */ + + +#ifdef MODULE +int init_module(void); +void cleanup_module(void); +#endif /* MODULE */ + +static inline void memwinon(struct board_info *b, unsigned int win); +static inline void memwinoff(struct board_info *b, unsigned int win); +static inline void globalwinon(struct channel *ch); +static inline void rxwinon(struct channel *ch); +static inline void txwinon(struct channel *ch); +static inline void memoff(struct channel *ch); +static inline void assertgwinon(struct channel *ch); +static inline void assertmemoff(struct channel *ch); + +/* ---- Begin more 'specific' memory functions for cx_like products --- */ + +static inline void pcxem_memwinon(struct board_info *b, unsigned int win); +static inline void pcxem_memwinoff(struct board_info *b, unsigned int win); +static inline void pcxem_globalwinon(struct channel *ch); +static inline void pcxem_rxwinon(struct channel *ch); +static inline void pcxem_txwinon(struct channel *ch); +static inline void pcxem_memoff(struct channel *ch); + +/* ------ Begin more 'specific' memory functions for the pcxe ------- */ + +static inline void pcxe_memwinon(struct board_info *b, unsigned int win); +static inline void pcxe_memwinoff(struct board_info *b, unsigned int win); +static inline void pcxe_globalwinon(struct channel *ch); +static inline void pcxe_rxwinon(struct channel *ch); +static inline void pcxe_txwinon(struct channel *ch); +static inline void pcxe_memoff(struct channel *ch); + +/* ---- Begin more 'specific' memory functions for the pc64xe and pcxi ---- */ +/* Note : pc64xe and pcxi share the same windowing routines */ + +static inline void pcxi_memwinon(struct board_info *b, unsigned int win); +static inline void pcxi_memwinoff(struct board_info *b, unsigned int win); +static inline void pcxi_globalwinon(struct channel *ch); +static inline void pcxi_rxwinon(struct channel *ch); +static inline void pcxi_txwinon(struct channel *ch); +static inline void pcxi_memoff(struct channel *ch); + +/* - Begin 'specific' do nothing memory functions needed for some cards - */ + +static inline void dummy_memwinon(struct board_info *b, unsigned int win); +static inline void dummy_memwinoff(struct board_info *b, unsigned int win); +static inline void dummy_globalwinon(struct channel *ch); +static inline void dummy_rxwinon(struct channel *ch); +static inline void dummy_txwinon(struct channel *ch); +static inline void dummy_memoff(struct channel *ch); +static inline void dummy_assertgwinon(struct channel *ch); +static inline void dummy_assertmemoff(struct channel *ch); + +/* ------------------- Begin declare functions ----------------------- */ + +static inline struct channel *verifyChannel(register struct tty_struct *); +static inline void pc_sched_event(struct channel *, int); +static void epca_error(int, char *); +static void pc_close(struct tty_struct *, struct file *); +static void shutdown(struct channel *); +static void pc_hangup(struct tty_struct *); +static void pc_put_char(struct tty_struct *, unsigned char); +static int pc_write_room(struct tty_struct *); +static int pc_chars_in_buffer(struct tty_struct *); +static void pc_flush_buffer(struct tty_struct *); +static void pc_flush_chars(struct tty_struct *); +static int block_til_ready(struct tty_struct *, struct file *, + struct channel *); +static int pc_open(struct tty_struct *, struct file *); +static void post_fep_init(unsigned int crd); +static void epcapoll(unsigned long); +static void doevent(int); +static void fepcmd(struct channel *, int, int, int, int, int); +static unsigned termios2digi_h(struct channel *ch, unsigned); +static unsigned termios2digi_i(struct channel *ch, unsigned); +static unsigned termios2digi_c(struct channel *ch, unsigned); +static void epcaparam(struct tty_struct *, struct channel *); +static void receive_data(struct channel *); +static int pc_ioctl(struct tty_struct *, struct file *, + unsigned int, unsigned long); +static void pc_set_termios(struct tty_struct *, struct termios *); +static void do_softint(void *); +static void pc_stop(struct tty_struct *); +static void pc_start(struct tty_struct *); +static void pc_throttle(struct tty_struct * tty); +static void pc_unthrottle(struct tty_struct *tty); +static void digi_send_break(struct channel *ch, int msec); +static void setup_empty_event(struct tty_struct *tty, struct channel *ch); +void epca_setup(char *, int *); +void console_print(const char *); + +static int get_termio(struct tty_struct *, struct termio *); +static int pc_write(struct tty_struct *, int, const unsigned char *, int); +int pc_init(void); + +#ifdef ENABLE_PCI +static int init_PCI(int); +static int get_PCI_configuration(char, char, unsigned int *, unsigned int *, + unsigned int *, unsigned int *, + unsigned int *, unsigned int *); +#endif /* ENABLE_PCI */ + + +/* ------------------------------------------------------------------ + Table of functions for each board to handle memory. Mantaining + parallelism is a *very* good idea here. The idea is for the + runtime code to blindly call these functions, not knowing/caring + about the underlying hardware. This stuff should contain no + conditionals; if more functionality is needed a different entry + should be established. These calls are the interface calls and + are the only functions that should be accessed. Anyone caught + making direct calls deserves what they get. +-------------------------------------------------------------------- */ + +static inline void memwinon(struct board_info *b, unsigned int win) +{ + (b->memwinon)(b, win); +} + +static inline void memwinoff(struct board_info *b, unsigned int win) +{ + (b->memwinoff)(b, win); +} + +static inline void globalwinon(struct channel *ch) +{ + (ch->board->globalwinon)(ch); +} + +static inline void rxwinon(struct channel *ch) +{ + (ch->board->rxwinon)(ch); +} + +static inline void txwinon(struct channel *ch) +{ + (ch->board->txwinon)(ch); +} + +static inline void memoff(struct channel *ch) +{ + (ch->board->memoff)(ch); +} +static inline void assertgwinon(struct channel *ch) +{ + (ch->board->assertgwinon)(ch); +} + +static inline void assertmemoff(struct channel *ch) +{ + (ch->board->assertmemoff)(ch); +} + +/* --------------------------------------------------------- + PCXEM windowing is the same as that used in the PCXR + and CX series cards. +------------------------------------------------------------ */ + +static inline void pcxem_memwinon(struct board_info *b, unsigned int win) +{ + outb_p(FEPWIN|win, (int)b->port + 1); +} + +static inline void pcxem_memwinoff(struct board_info *b, unsigned int win) +{ + outb_p(0, (int)b->port + 1); +} + +static inline void pcxem_globalwinon(struct channel *ch) +{ + outb_p( FEPWIN, (int)ch->board->port + 1); +} + +static inline void pcxem_rxwinon(struct channel *ch) +{ + outb_p(ch->rxwin, (int)ch->board->port + 1); +} + +static inline void pcxem_txwinon(struct channel *ch) +{ + outb_p(ch->txwin, (int)ch->board->port + 1); +} + +static inline void pcxem_memoff(struct channel *ch) +{ + outb_p(0, (int)ch->board->port + 1); +} + +/* ----------------- Begin pcxe memory window stuff ------------------ */ + +static inline void pcxe_memwinon(struct board_info *b, unsigned int win) +{ + outb_p(FEPWIN | win, (int)b->port + 1); +} + +static inline void pcxe_memwinoff(struct board_info *b, unsigned int win) +{ + outb_p(inb((int)b->port) & ~FEPMEM, + (int)b->port + 1); + outb_p(0, (int)b->port + 1); +} + +static inline void pcxe_globalwinon(struct channel *ch) +{ + outb_p( FEPWIN, (int)ch->board->port + 1); +} + +static inline void pcxe_rxwinon(struct channel *ch) +{ + outb_p(ch->rxwin, (int)ch->board->port + 1); +} + +static inline void pcxe_txwinon(struct channel *ch) +{ + outb_p(ch->txwin, (int)ch->board->port + 1); +} + +static inline void pcxe_memoff(struct channel *ch) +{ + outb_p(0, (int)ch->board->port); + outb_p(0, (int)ch->board->port + 1); +} + +/* ------------- Begin pc64xe and pcxi memory window stuff -------------- */ + +static inline void pcxi_memwinon(struct board_info *b, unsigned int win) +{ + outb_p(inb((int)b->port) | FEPMEM, (int)b->port); +} + +static inline void pcxi_memwinoff(struct board_info *b, unsigned int win) +{ + outb_p(inb((int)b->port) & ~FEPMEM, (int)b->port); +} + +static inline void pcxi_globalwinon(struct channel *ch) +{ + outb_p(FEPMEM, (int)ch->board->port); +} + +static inline void pcxi_rxwinon(struct channel *ch) +{ + outb_p(FEPMEM, (int)ch->board->port); +} + +static inline void pcxi_txwinon(struct channel *ch) +{ + outb_p(FEPMEM, (int)ch->board->port); +} + +static inline void pcxi_memoff(struct channel *ch) +{ + outb_p(0, (int)ch->board->port); +} + +static inline void pcxi_assertgwinon(struct channel *ch) +{ + epcaassert(inb((int)ch->board->port) & FEPMEM, "Global memory off"); +} + +static inline void pcxi_assertmemoff(struct channel *ch) +{ + epcaassert(!(inb((int)ch->board->port) & FEPMEM), "Memory on"); +} + + +/* ---------------------------------------------------------------------- + Not all of the cards need specific memory windowing routines. Some + cards (Such as PCI) needs no windowing routines at all. We provide + these do nothing routines so that the same code base can be used. + The driver will ALWAYS call a windowing routine if it thinks it needs + to; regardless of the card. However, dependant on the card the routine + may or may not do anything. +---------------------------------------------------------------------------*/ + +static inline void dummy_memwinon(struct board_info *b, unsigned int win) +{ +} + +static inline void dummy_memwinoff(struct board_info *b, unsigned int win) +{ +} + +static inline void dummy_globalwinon(struct channel *ch) +{ +} + +static inline void dummy_rxwinon(struct channel *ch) +{ +} + +static inline void dummy_txwinon(struct channel *ch) +{ +} + +static inline void dummy_memoff(struct channel *ch) +{ +} + +static inline void dummy_assertgwinon(struct channel *ch) +{ +} + +static inline void dummy_assertmemoff(struct channel *ch) +{ +} + +/* ----------------- Begin verifyChannel function ----------------------- */ +static inline struct channel *verifyChannel(register struct tty_struct *tty) +{ /* Begin verifyChannel */ + + /* -------------------------------------------------------------------- + This routine basically provides a sanity check. It insures that + the channel returned is within the proper range of addresses as + well as properly initialized. If some bogus info gets passed in + through tty->driver_data this should catch it. + --------------------------------------------------------------------- */ + + if (tty) + { /* Begin if tty */ + + register struct channel *ch = (struct channel *)tty->driver_data; + + if ((ch >= &digi_channels[0]) && (ch < &digi_channels[nbdevs])) + { + if (ch->magic == EPCA_MAGIC) + return ch; + } + + } /* End if tty */ + + /* Else return a NULL for invalid */ + return NULL; + +} /* End verifyChannel */ + +/* ------------------ Begin pc_sched_event ------------------------- */ + +static inline void pc_sched_event(struct channel *ch, int event) +{ /* Begin pc_sched_event */ + + + /* ---------------------------------------------------------------------- + We call this to schedule interrupt processing on some event. The + kernel sees our request and calls the related routine in OUR driver. + -------------------------------------------------------------------------*/ + + ch->event |= 1 << event; + queue_task(&ch->tqueue, &tq_scheduler); + + +} /* End pc_sched_event */ + +/* ------------------ Begin epca_error ------------------------- */ + +static void epca_error(int line, char *msg) +{ /* Begin epca_error */ + + printk(KERN_ERR "epca_error (Digi): line = %d %s\n",line,msg); + return; + +} /* End epca_error */ + +/* ------------------ Begin pc_close ------------------------- */ +static void pc_close(struct tty_struct * tty, struct file * filp) +{ /* Begin pc_close */ + + struct channel *ch; + unsigned long flags; + + if (tty->driver.subtype == SERIAL_TYPE_INFO) + { + return; + } + + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { /* Begin if ch != NULL */ + + save_flags(flags); + cli(); + + if (tty_hung_up_p(filp)) + { + restore_flags(flags); + return; + } + + /* Check to see if the channel is open more than once */ + if (ch->count-- > 1) + { /* Begin channel is open more than once */ + + /* ------------------------------------------------------------- + Return without doing anything. Someone might still be using + the channel. + ---------------------------------------------------------------- */ + + restore_flags(flags); + return; + } /* End channel is open more than once */ + + /* Port open only once go ahead with shutdown & reset */ + + if (ch->count < 0) + { + ch->count = 0; + } + + /* --------------------------------------------------------------- + Let the rest of the driver know the channel is being closed. + This becomes important if an open is attempted before close + is finished. + ------------------------------------------------------------------ */ + + ch->asyncflags |= ASYNC_CLOSING; + + /* ------------------------------------------------------------- + Save the termios structure, since this port may have + separate termios for callout and dialin. + --------------------------------------------------------------- */ + + if (ch->asyncflags & ASYNC_NORMAL_ACTIVE) + ch->normal_termios = *tty->termios; + + if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE) + ch->callout_termios = *tty->termios; + + tty->closing = 1; + + if (ch->asyncflags & ASYNC_INITIALIZED) + { + /* Setup an event to indicate when the transmit buffer empties */ + setup_empty_event(tty, ch); + tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ + } + + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + + shutdown(ch); + tty->closing = 0; + ch->event = 0; + ch->tty = NULL; + + if (ch->blocked_open) + { /* Begin if blocked_open */ + + if (ch->close_delay) + { + current->state = TASK_INTERRUPTIBLE; + current->timeout = jiffies + ch->close_delay; + schedule(); + } + + wake_up_interruptible(&ch->open_wait); + + } /* End if blocked_open */ + + ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | + ASYNC_CALLOUT_ACTIVE | ASYNC_CLOSING); + wake_up_interruptible(&ch->close_wait); + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif + + restore_flags(flags); + + } /* End if ch != NULL */ + +} /* End pc_close */ + +/* ------------------ Begin shutdown ------------------------- */ + +static void shutdown(struct channel *ch) +{ /* Begin shutdown */ + + unsigned long flags; + struct tty_struct *tty; + volatile struct board_chan *bc; + + if (!(ch->asyncflags & ASYNC_INITIALIZED)) + return; + + save_flags(flags); + cli(); + globalwinon(ch); + + bc = ch->brdchan; + + /* ------------------------------------------------------------------ + In order for an event to be generated on the receipt of data the + idata flag must be set. Since we are shutting down, this is not + necessary clear this flag. + --------------------------------------------------------------------- */ + + if (bc) + bc->idata = 0; + + tty = ch->tty; + + /* ---------------------------------------------------------------- + If we're a modem control device and HUPCL is on, drop RTS & DTR. + ------------------------------------------------------------------ */ + + if (tty->termios->c_cflag & HUPCL) + { + ch->omodem &= ~(ch->m_rts | ch->m_dtr); + fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1); + } + + memoff(ch); + + /* ------------------------------------------------------------------ + The channel has officialy been closed. The next time it is opened + it will have to reinitialized. Set a flag to indicate this. + ---------------------------------------------------------------------- */ + + /* Prevent future Digi programmed interrupts from coming active */ + + ch->asyncflags &= ~ASYNC_INITIALIZED; + restore_flags(flags); + +} /* End shutdown */ + +/* ------------------ Begin pc_hangup ------------------------- */ + +static void pc_hangup(struct tty_struct *tty) +{ /* Begin pc_hangup */ + + struct channel *ch; + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { /* Begin if ch != NULL */ + + unsigned long flags; + + save_flags(flags); + cli(); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + + shutdown(ch); + +#ifdef MODULE + if (ch->count) + MOD_DEC_USE_COUNT; +#endif /* MODULE */ + + + ch->tty = NULL; + ch->event = 0; + ch->count = 0; + restore_flags(flags); + ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | ASYNC_CALLOUT_ACTIVE); + wake_up_interruptible(&ch->open_wait); + + } /* End if ch != NULL */ + +} /* End pc_hangup */ + +/* ------------------ Begin pc_write ------------------------- */ + +static int pc_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int bytesAvailable) +{ /* Begin pc_write */ + + register unsigned int head, tail; + register int dataLen; + register int size; + register int amountCopied; + + + struct channel *ch; + unsigned long flags; + int remain; + volatile struct board_chan *bc; + + + /* ---------------------------------------------------------------- + pc_write is primarily called directly by the kernel routine + tty_write (Though it can also be called by put_char) found in + tty_io.c. pc_write is passed a line discipline buffer where + the data to be written out is stored. The line discipline + implementation itself is done at the kernel level and is not + brought into the driver. + ------------------------------------------------------------------- */ + + /* Stop users from hurting themselves on control minor */ + + if (tty->driver.subtype == SERIAL_TYPE_INFO) + { + return (0) ; + } + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) == NULL) + return 0; + + /* Make a pointer to the channel data structure found on the board. */ + + bc = ch->brdchan; + size = ch->txbufsize; + + if (from_user) + { /* Begin from_user */ + + save_flags(flags); + cli(); + + globalwinon(ch); + + /* ----------------------------------------------------------------- + Anding against size will wrap the pointer back to its begining + position if it is necessary. This will only work if size is + a power of 2 which should always be the case. Size is determined + by the cards on board FEP/OS. + -------------------------------------------------------------------- */ + + /* head refers to the next empty location in which data may be stored */ + + head = bc->tin & (size - 1); + + /* tail refers to the next data byte to be transmitted */ + + tail = bc->tout; + + /* Consider changing this to a do statement to make sure */ + + if (tail != bc->tout) + tail = bc->tout; + + /* ------------------------------------------------------------------ + Anding against size will wrap the pointer back to its begining + position if it is necessary. This will only work if size is + a power of 2 which should always be the case. Size is determined + by the cards on board FEP/OS. + --------------------------------------------------------------------- */ + + tail &= (size - 1); + + /* ----------------------------------------------------------------- + Two situations can affect how space in the transmit buffer + is calculated. You can have a situation where the transmit + in pointer (tin) head has wrapped around and actually has a + lower address than the transmit out pointer (tout) tail; or + the transmit in pointer (tin) head will not be wrapped around + yet, and have a higher address than the transmit out pointer + (tout) tail. Obviously space available in the transmit buffer + is calculated differently for each case. + + Example 1: + + Consider a 10 byte buffer where head is a pointer to the next + empty location in the buffer and tail is a pointer to the next + byte to transmit. In this example head will not have wrapped + around and therefore head > tail. + + 0 1 2 3 4 5 6 7 8 9 + tail head + + The above diagram shows that buffer locations 2,3,4,5 and 6 have + data to be transmited, while head points at the next empty + location. To calculate how much space is available first we have + to determine if the head pointer (tin) has wrapped. To do this + compare the head pointer to the tail pointer, If head is equal + or greater than tail; then it has not wrapped; and the space may + be calculated by subtracting tail from head and then subtracting + that value from the buffers size. A one is subtracted from the + new value to indicate how much space is available between the + head pointer and end of buffer; as well as the space between the + begining of the buffer and the tail. If the head is not greater + or equal to the tail this indicates that the head has wrapped + around to the begining of the buffer. To calculate the space + available in this case simply subtract head from tail. This new + value minus one represents the space available betwwen the head + and tail pointers. In this example head (7) is greater than tail (2) + and therefore has not wrapped around. We find the space by first + subtracting tail from head (7-2=5). We then subtract this value + from the buffer size of ten and subtract one (10-5-1=4). The space + remaining is 4 bytes. + + Example 2: + + Consider a 10 byte buffer where head is a pointer to the next + empty location in the buffer and tail is a pointer to the next + byte to transmit. In this example head will wrapped around and + therefore head < tail. + + 0 1 2 3 4 5 6 7 8 9 + head tail + + The above diagram shows that buffer locations 7,8,9,0 and 1 have + data to be transmited, while head points at the next empty + location. To find the space available we compare head to tail. If + head is not equal to, or greater than tail this indicates that head + has wrapped around. In this case head (2) is not equal to, or + greater than tail (7) and therefore has already wrapped around. To + calculate the available space between the two pointers we subtract + head from tail (7-2=5). We then subtract one from this new value + (5-1=4). We have 5 bytes empty remaining in the buffer. Unlike the + previous example these five bytes are located between the head and + tail pointers. + + ----------------------------------------------------------------------- */ + + dataLen = (head >= tail) ? (size - (head - tail) - 1) : (tail - head - 1); + + /* ---------------------------------------------------------------------- + In this case bytesAvailable has been passed into pc_write and + represents the amount of data that needs to be written. dataLen + represents the amount of space available on the card. Whichever + value is smaller will be the amount actually written. + bytesAvailable will then take on this newly calculated value. + ---------------------------------------------------------------------- */ + + bytesAvailable = MIN(dataLen, bytesAvailable); + + /* First we read the data in from the file system into a temp buffer */ + + if (bytesAvailable) + { /* Begin bytesAvailable */ + + /* Can the user buffer be accessed at the moment ? */ + if (verify_area(VERIFY_READ, (char*)buf, bytesAvailable)) + bytesAvailable = 0; /* Can't do; try again later */ + else /* Evidently it can, began transmission */ + { /* Begin if area verified */ + /* --------------------------------------------------------------- + The below function reads data from user memory. This routine + can not be used in an interrupt routine. (Because it may + generate a page fault) It can only be called while we can the + user context is accessible. + + The prototype is : + inline void copy_from_user(void * to, const void * from, + unsigned long count); + + You must include + I also think (Check hackers guide) that optimization must + be turned ON. (Which sounds strange to me...) + + Remember copy_from_user WILL generate a page fault if the + user memory being accessed has been swapped out. This can + cause this routine to temporarily sleep while this page + fault is occuring. + + ----------------------------------------------------------------- */ + + copy_from_user(ch->tmp_buf, buf, bytesAvailable); + + } /* End if area verified */ + + } /* End bytesAvailable */ + + /* ------------------------------------------------------------------ + Set buf to this address for the moment. tmp_buf was allocated in + post_fep_init. + --------------------------------------------------------------------- */ + buf = ch->tmp_buf; + memoff(ch); + restore_flags(flags); + + } /* End from_user */ + + /* All data is now local */ + + amountCopied = 0; + save_flags(flags); + cli(); + + globalwinon(ch); + + head = bc->tin & (size - 1); + tail = bc->tout; + + if (tail != bc->tout) + tail = bc->tout; + tail &= (size - 1); + + /* If head >= tail, head has not wrapped around. */ + if (head >= tail) + { /* Begin head has not wrapped */ + + /* --------------------------------------------------------------- + remain (much like dataLen above) represents the total amount of + space available on the card for data. Here dataLen represents + the space existing between the head pointer and the end of + buffer. This is important because a memcpy cannot be told to + automatically wrap around when it hits the buffer end. + ------------------------------------------------------------------ */ + + dataLen = size - head; + remain = size - (head - tail) - 1; + + } /* End head has not wrapped */ + else + { /* Begin head has wrapped around */ + + remain = tail - head - 1; + dataLen = remain; + + } /* End head has wrapped around */ + + /* ------------------------------------------------------------------- + Check the space on the card. If we have more data than + space; reduce the amount of data to fit the space. + ---------------------------------------------------------------------- */ + + bytesAvailable = MIN(remain, bytesAvailable); + + txwinon(ch); + while (bytesAvailable > 0) + { /* Begin while there is data to copy onto card */ + + /* ----------------------------------------------------------------- + If head is not wrapped, the below will make sure the first + data copy fills to the end of card buffer. + ------------------------------------------------------------------- */ + + dataLen = MIN(bytesAvailable, dataLen); + memcpy(ch->txptr + head, buf, dataLen); + buf += dataLen; + head += dataLen; + amountCopied += dataLen; + bytesAvailable -= dataLen; + + if (head >= size) + { + head = 0; + dataLen = tail; + } + + } /* End while there is data to copy onto card */ + + ch->statusflags |= TXBUSY; + globalwinon(ch); + bc->tin = head; + + if ((ch->statusflags & LOWWAIT) == 0) + { + ch->statusflags |= LOWWAIT; + bc->ilow = 1; + } + memoff(ch); + restore_flags(flags); + + return(amountCopied); + +} /* End pc_write */ + +/* ------------------ Begin pc_put_char ------------------------- */ + +static void pc_put_char(struct tty_struct *tty, unsigned char c) +{ /* Begin pc_put_char */ + + + pc_write(tty, 0, &c, 1); + return; + +} /* End pc_put_char */ + +/* ------------------ Begin pc_write_room ------------------------- */ + +static int pc_write_room(struct tty_struct *tty) +{ /* Begin pc_write_room */ + + int remain; + struct channel *ch; + unsigned long flags; + unsigned int head, tail; + volatile struct board_chan *bc; + + remain = 0; + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { + save_flags(flags); + cli(); + globalwinon(ch); + + bc = ch->brdchan; + head = bc->tin & (ch->txbufsize - 1); + tail = bc->tout; + + if (tail != bc->tout) + tail = bc->tout; + /* Wrap tail if necessary */ + tail &= (ch->txbufsize - 1); + + if ((remain = tail - head - 1) < 0 ) + remain += ch->txbufsize; + + if (remain && (ch->statusflags & LOWWAIT) == 0) + { + ch->statusflags |= LOWWAIT; + bc->ilow = 1; + } + memoff(ch); + restore_flags(flags); + } + + /* Return how much room is left on card */ + return remain; + +} /* End pc_write_room */ + +/* ------------------ Begin pc_chars_in_buffer ---------------------- */ + +static int pc_chars_in_buffer(struct tty_struct *tty) +{ /* Begin pc_chars_in_buffer */ + + int chars; + unsigned int ctail, head, tail; + int remain; + unsigned long flags; + struct channel *ch; + volatile struct board_chan *bc; + + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) == NULL) + return(0); + + save_flags(flags); + cli(); + globalwinon(ch); + + bc = ch->brdchan; + tail = bc->tout; + head = bc->tin; + ctail = ch->mailbox->cout; + + if (tail == head && ch->mailbox->cin == ctail && bc->tbusy == 0) + chars = 0; + else + { /* Begin if some space on the card has been used */ + + head = bc->tin & (ch->txbufsize - 1); + tail &= (ch->txbufsize - 1); + + /* -------------------------------------------------------------- + The logic here is basically opposite of the above pc_write_room + here we are finding the amount of bytes in the buffer filled. + Not the amount of bytes empty. + ------------------------------------------------------------------- */ + + if ((remain = tail - head - 1) < 0 ) + remain += ch->txbufsize; + + chars = (int)(ch->txbufsize - remain); + + /* ------------------------------------------------------------- + Make it possible to wakeup anything waiting for output + in tty_ioctl.c, etc. + + If not already set. Setup an event to indicate when the + transmit buffer empties + ----------------------------------------------------------------- */ + + if (!(ch->statusflags & EMPTYWAIT)) + setup_empty_event(tty,ch); + + } /* End if some space on the card has been used */ + + memoff(ch); + restore_flags(flags); + + /* Return number of characters residing on card. */ + return(chars); + +} /* End pc_chars_in_buffer */ + +/* ------------------ Begin pc_flush_buffer ---------------------- */ + +static void pc_flush_buffer(struct tty_struct *tty) +{ /* Begin pc_flush_buffer */ + + unsigned int tail; + unsigned long flags; + struct channel *ch; + volatile struct board_chan *bc; + + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) == NULL) + return; + + save_flags(flags); + cli(); + + globalwinon(ch); + + bc = ch->brdchan; + tail = bc->tout; + + /* Have FEP move tout pointer; effectively flushing transmit buffer */ + + fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0); + + memoff(ch); + restore_flags(flags); + + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + +} /* End pc_flush_buffer */ + +/* ------------------ Begin pc_flush_chars ---------------------- */ + +static void pc_flush_chars(struct tty_struct *tty) +{ /* Begin pc_flush_chars */ + + struct channel * ch; + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { + unsigned long flags; + + save_flags(flags); + cli(); + + /* ---------------------------------------------------------------- + If not already set and the transmitter is busy setup an event + to indicate when the transmit empties. + ------------------------------------------------------------------- */ + + if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT)) + setup_empty_event(tty,ch); + + restore_flags(flags); + } + +} /* End pc_flush_chars */ + +/* ------------------ Begin block_til_ready ---------------------- */ + +static int block_til_ready(struct tty_struct *tty, + struct file *filp, struct channel *ch) +{ /* Begin block_til_ready */ + + struct wait_queue wait = {current, NULL}; + int retval, do_clocal = 0; + unsigned long flags; + + + if (tty_hung_up_p(filp)) + { + if (ch->asyncflags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; + return(retval); + } + + /* ----------------------------------------------------------------- + If the device is in the middle of being closed, then block + until it's done, and then try again. + -------------------------------------------------------------------- */ + if (ch->asyncflags & ASYNC_CLOSING) + { + interruptible_sleep_on(&ch->close_wait); + + if (ch->asyncflags & ASYNC_HUP_NOTIFY) + return -EAGAIN; + else + return -ERESTARTSYS; + } + + /* ----------------------------------------------------------------- + If this is a callout device, then just make sure the normal + device isn't being used. + -------------------------------------------------------------------- */ + + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) + { /* A cud device has been opened */ + if (ch->asyncflags & ASYNC_NORMAL_ACTIVE) + return -EBUSY; + + if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) && + (ch->asyncflags & ASYNC_SESSION_LOCKOUT) && + (ch->session != current->session)) + return -EBUSY; + + if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) && + (ch->asyncflags & ASYNC_PGRP_LOCKOUT) && + (ch->pgrp != current->pgrp)) + return -EBUSY; + + ch->asyncflags |= ASYNC_CALLOUT_ACTIVE; + + return 0; + } /* End a cud device has been opened */ + + if (filp->f_flags & O_NONBLOCK) + { + /* ----------------------------------------------------------------- + If non-blocking mode is set, then make the check up front + and then exit. + -------------------------------------------------------------------- */ + + if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE) + return -EBUSY; + + ch->asyncflags |= ASYNC_NORMAL_ACTIVE; + + return 0; + } + + + if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE) + { + if (ch->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } + else + { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* Block waiting for the carrier detect and the line to become free */ + + retval = 0; + add_wait_queue(&ch->open_wait, &wait); + save_flags(flags); + cli(); + + + /* We dec count so that pc_close will know when to free things */ + if (!tty_hung_up_p(filp)) + ch->count--; + + restore_flags(flags); + + ch->blocked_open++; + + while(1) + { /* Begin forever while */ + + current->state = TASK_INTERRUPTIBLE; + + if (tty_hung_up_p(filp) || + !(ch->asyncflags & ASYNC_INITIALIZED)) + { + if (ch->asyncflags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; + break; + } + + if (!(ch->asyncflags & ASYNC_CLOSING) && + !(ch->asyncflags & ASYNC_CALLOUT_ACTIVE) && + (do_clocal || (ch->imodem & ch->dcd))) + break; + + if (current->signal & ~current->blocked) + { + retval = -ERESTARTSYS; + break; + } + + /* --------------------------------------------------------------- + Allow someone else to be scheduled. We will occasionaly go + through this loop until one of the above conditions change. + The below schedule call will allow other processes to enter and + prevent this loop from hogging the cpu. + ------------------------------------------------------------------ */ + schedule(); + + } /* End forever while */ + + current->state = TASK_RUNNING; + remove_wait_queue(&ch->open_wait, &wait); + cli(); + if (!tty_hung_up_p(filp)) + ch->count++; + restore_flags(flags); + + ch->blocked_open--; + + if (retval) + return retval; + + ch->asyncflags |= ASYNC_NORMAL_ACTIVE; + + return 0; + +} /* End block_til_ready */ + +/* ------------------ Begin pc_open ---------------------- */ + +static int pc_open(struct tty_struct *tty, struct file * filp) +{ /* Begin pc_open */ + + struct channel *ch; + unsigned long flags; + int line, retval, boardnum; + volatile struct board_chan *bc; + volatile unsigned int head; + + /* Nothing "real" happens in open of control device */ + + if (tty->driver.subtype == SERIAL_TYPE_INFO) + { + return (0) ; + } + + line = MINOR(tty->device) - tty->driver.minor_start; + if (line < 0 || line >= nbdevs) + { + printk(KERN_ERR " - pc_open : line out of range in pc_open\n"); + tty->driver_data = NULL; + return(-ENODEV); + } + +#ifdef MODULE + + MOD_INC_USE_COUNT; + +#endif + + ch = &digi_channels[line]; + boardnum = ch->boardnum; + + /* Check status of board configured in system. */ + + /* ----------------------------------------------------------------- + I check to see if the epca_setup routine detected an user error. + It might be better to put this in pc_init, but for the moment it + goes here. + ---------------------------------------------------------------------- */ + + if (invalid_lilo_config) + { + if (setup_error_code & INVALID_BOARD_TYPE) + printk(KERN_ERR " - pc_open: Invalid board type specified in LILO command\n"); + + if (setup_error_code & INVALID_NUM_PORTS) + printk(KERN_ERR " - pc_open: Invalid number of ports specified in LILO command\n"); + + if (setup_error_code & INVALID_MEM_BASE) + printk(KERN_ERR " - pc_open: Invalid board memory address specified in LILO command\n"); + + if (setup_error_code & INVALID_PORT_BASE) + printk(KERN_ERR " - pc_open: Invalid board port address specified in LILO command\n"); + + if (setup_error_code & INVALID_BOARD_STATUS) + printk(KERN_ERR " - pc_open: Invalid board status specified in LILO command\n"); + + if (setup_error_code & INVALID_ALTPIN) + printk(KERN_ERR " - pc_open: Invalid board altpin specified in LILO command\n"); + + tty->driver_data = NULL; /* Mark this device as 'down' */ + return(-ENODEV); + } + + if ((boardnum >= num_cards) || (boards[boardnum].status == DISABLED)) + { + tty->driver_data = NULL; /* Mark this device as 'down' */ + return(-ENODEV); + } + + if (( bc = ch->brdchan) == 0) + { + tty->driver_data = NULL; + return(-ENODEV); + } + + /* ------------------------------------------------------------------ + Every time a channel is opened, increment a counter. This is + necessary because we do not wish to flush and shutdown the channel + until the last app holding the channel open, closes it. + --------------------------------------------------------------------- */ + + ch->count++; + + /* ---------------------------------------------------------------- + Set a kernel structures pointer to our local channel + structure. This way we can get to it when passed only + a tty struct. + ------------------------------------------------------------------ */ + + tty->driver_data = ch; + + /* ---------------------------------------------------------------- + If this is the first time the channel has been opened, initialize + the tty->termios struct otherwise let pc_close handle it. + -------------------------------------------------------------------- */ + + /* Should this be here except for SPLIT termios ? */ + if (ch->count == 1) + { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = ch->normal_termios; + else + *tty->termios = ch->callout_termios; + } + + ch->session = current->session; + ch->pgrp = current->pgrp; + + save_flags(flags); + cli(); + + globalwinon(ch); + ch->statusflags = 0; + + /* Save boards current modem status */ + ch->imodem = bc->mstat; + + /* ---------------------------------------------------------------- + Set receive head and tail ptrs to each other. This indicates + no data available to read. + ----------------------------------------------------------------- */ + head = bc->rin; + bc->rout = head; + + /* Set the channels associated tty structure */ + ch->tty = tty; + + /* ----------------------------------------------------------------- + The below routine generally sets up parity, baud, flow control + issues, etc.... It effect both control flags and input flags. + -------------------------------------------------------------------- */ + epcaparam(tty,ch); + + ch->asyncflags |= ASYNC_INITIALIZED; + memoff(ch); + + restore_flags(flags); + + retval = block_til_ready(tty, filp, ch); + if (retval) + { + return retval; + } + + /* ------------------------------------------------------------- + Set this again in case a hangup set it to zero while this + open() was waiting for the line... + --------------------------------------------------------------- */ + ch->tty = tty; + + save_flags(flags); + cli(); + globalwinon(ch); + + /* Enable Digi Data events */ + bc->idata = 1; + + memoff(ch); + restore_flags(flags); + + return 0; + +} /* End pc_open */ + +#ifdef MODULE +/* -------------------- Begin init_module ---------------------- */ +int init_module() +{ /* Begin init_module */ + + unsigned long flags; + + save_flags(flags); + cli(); + + pc_init(); + + restore_flags(flags); + + return(0); +} /* End init_module */ + +#endif +#ifdef MODULE +/* -------------------- Begin cleanup_module ---------------------- */ +void cleanup_module() +{ /* Begin cleanup_module */ + + int count, crd; + struct board_info *bd; + struct channel *ch; + unsigned long flags; + + + save_flags(flags); + cli(); + + timer_table[DIGI_TIMER].fn = 0; + + if ((tty_unregister_driver(&pc_driver)) || + (tty_unregister_driver(&pc_callout))) + { + printk(KERN_WARNING " - DIGI : cleanup_module failed to un-register tty driver\n"); + restore_flags(flags); + return; + } + + for (crd = 0; crd < num_cards; crd++) + { /* Begin for each card */ + + bd = &boards[crd]; + + if (!bd) + { /* Begin sanity check */ + printk(KERN_ERR " - Digi : cleanup_module failed\n"); + return; + } /* End sanity check */ + + ch = card_ptr[crd]; + + for (count = 0; count < bd->numports; count++, ch++) + { /* Begin for each port */ + + if (ch) + { + if (ch->tty) + tty_hangup(ch->tty); + kfree_s(ch->tmp_buf, ch->txbufsize); + } + + } /* End for each port */ + } /* End for each card */ + + + restore_flags(flags); + +} /* End cleanup_module */ +#endif /* MODULE */ + +/* ------------------ Begin pc_init ---------------------- */ + +int pc_init(void) +{ /* Begin pc_init */ + + /* ---------------------------------------------------------------- + pc_init is called by the operating system during boot up prior to + any open calls being made. In the older versions of Linux (Prior + to 2.0.0) an entry is made into tty_io.c. A pointer to the last + memory location (from kernel space) used (kmem_start) is passed + to pc_init. It is pc_inits responsibility to modify this value + for any memory that the Digi driver might need and then return + this value to the operating system. For example if the driver + wishes to allocate 1K of kernel memory, pc_init would return + (kmem_start + 1024). This memory (Between kmem_start and kmem_start + + 1024) would then be available for use exclusively by the driver. + In this case our driver does not allocate any of this kernel + memory. + ------------------------------------------------------------------*/ + + ulong flags, save_loops_per_sec; + int crd; + struct board_info *bd; + unsigned char board_id = 0; + + +#ifdef ENABLE_PCI + int pci_boards_found, pci_count; + + pci_count = 0; +#endif /* ENABLE_PCI */ + + /* ----------------------------------------------------------------------- + If epca_setup has not been ran by LILO set num_cards to defaults; copy + board structure defined by digiConfig into drivers board structure. + Note : If LILO has ran epca_setup then epca_setup will handle defining + num_cards as well as copying the data into the board structure. + -------------------------------------------------------------------------- */ + if (!liloconfig) + { /* Begin driver has been configured via. epcaconfig */ + + nbdevs = NBDEVS; + num_cards = NUMCARDS; + memcpy((void *)&boards, (void *)&static_boards, + (sizeof(struct board_info) * NUMCARDS)); + } /* End driver has been configured via. epcaconfig */ + + /* ----------------------------------------------------------------- + Note : If lilo was used to configure the driver and the + ignore epcaconfig option was choosen (digiepca=2) then + nbdevs and num_cards will equal 0 at this point. This is + okay; PCI cards will still be picked up if detected. + --------------------------------------------------------------------- */ + + /* ----------------------------------------------------------- + Set up interrupt, we will worry about memory allocation in + post_fep_init. + --------------------------------------------------------------- */ + + + printk(KERN_INFO "DIGI epca driver version %s loaded.\n",VERSION); + +#ifdef ENABLE_PCI + + /* ------------------------------------------------------------------ + NOTE : This code assumes that the number of ports found in + the boards array is correct. This could be wrong if + the card in question is PCI (And therefore has no ports + entry in the boards structure.) The rest of the + information will be valid for PCI because the begining + of pc_init scans for PCI and determines i/o and base + memory addresses. I am not sure if it is possible to + read the number of ports supported by the card prior to + it being booted (Since that is the state it is in when + pc_init is run). Because it is not possible to query the + number of supported ports until after the card has booted; + we are required to calculate the card_ptrs as the card is + is initialized (Inside post_fep_init). The negative thing + about this approach is that digiDload's call to GET_INFO + will have a bad port value. (Since this is called prior + to post_fep_init.) + + --------------------------------------------------------------------- */ + + pci_boards_found = 0; + if (pcibios_present()) + { + if(num_cards < MAXBOARDS) + pci_boards_found += init_PCI(num_cards); + num_cards += pci_boards_found; + } + else + { + printk(KERN_ERR " - No PCI BIOS found\n"); + } + +#endif /* ENABLE_PCI */ + + memset(&pc_driver, 0, sizeof(struct tty_driver)); + memset(&pc_callout, 0, sizeof(struct tty_driver)); + memset(&pc_info, 0, sizeof(struct tty_driver)); + + pc_driver.magic = TTY_DRIVER_MAGIC; + pc_driver.name = "ttyD"; + pc_driver.major = DIGI_MAJOR; + pc_driver.minor_start = 0; + pc_driver.num = MAX_ALLOC; + pc_driver.type = TTY_DRIVER_TYPE_SERIAL; + pc_driver.subtype = SERIAL_TYPE_NORMAL; + pc_driver.init_termios = tty_std_termios; + pc_driver.init_termios.c_iflag = 0; + pc_driver.init_termios.c_oflag = 0; + + pc_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; + pc_driver.init_termios.c_lflag = 0; + pc_driver.flags = TTY_DRIVER_REAL_RAW; + pc_driver.refcount = &pc_refcount; + pc_driver.table = pc_table; + + /* pc_termios is an array of pointers pointing at termios structs */ + /* The below should get the first pointer */ + pc_driver.termios = pc_termios; + pc_driver.termios_locked = pc_termios_locked; + + /* ------------------------------------------------------------------ + Setup entry points for the driver. These are primarily called by + the kernel in tty_io.c and n_tty.c + --------------------------------------------------------------------- */ + + pc_driver.open = pc_open; + pc_driver.close = pc_close; + pc_driver.write = pc_write; + pc_driver.write_room = pc_write_room; + pc_driver.flush_buffer = pc_flush_buffer; + pc_driver.chars_in_buffer = pc_chars_in_buffer; + pc_driver.flush_chars = pc_flush_chars; + pc_driver.put_char = pc_put_char; + pc_driver.ioctl = pc_ioctl; + pc_driver.set_termios = pc_set_termios; + pc_driver.stop = pc_stop; + pc_driver.start = pc_start; + pc_driver.throttle = pc_throttle; + pc_driver.unthrottle = pc_unthrottle; + pc_driver.hangup = pc_hangup; + pc_callout = pc_driver; + + pc_callout.name = "cud"; + pc_callout.major = DIGICU_MAJOR; + pc_callout.minor_start = 0; + pc_callout.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; + pc_callout.subtype = SERIAL_TYPE_CALLOUT; + + pc_info = pc_driver; + pc_info.name = "digiCtl"; + pc_info.major = DIGIINFOMAJOR; + pc_info.minor_start = 0; + pc_info.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; + pc_info.subtype = SERIAL_TYPE_INFO; + + + /* --------------------------------------------------------------------- + loops_per_sec hasn't been set at this point :-(, so fake it out... + I set it, so that I can use the __delay() function. + ------------------------------------------------------------------------ */ + save_loops_per_sec = loops_per_sec; + loops_per_sec = 13L * 500000L; + + save_flags(flags); + cli(); + + for (crd = 0; crd < num_cards; crd++) + { /* Begin for each card */ + + /* ------------------------------------------------------------------ + This is where the appropriate memory handlers for the hardware is + set. Everything at runtime blindly jumps through these vectors. + ---------------------------------------------------------------------- */ + + /* defined in epcaconfig.h */ + bd = &boards[crd]; + + switch (bd->type) + { /* Begin switch on bd->type {board type} */ + case PCXEM: + case EISAXEM: + bd->memwinon = pcxem_memwinon ; + bd->memwinoff = pcxem_memwinoff ; + bd->globalwinon = pcxem_globalwinon ; + bd->txwinon = pcxem_txwinon ; + bd->rxwinon = pcxem_rxwinon ; + bd->memoff = pcxem_memoff ; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; + + case PCIXEM: + case PCIXRJ: + case PCIXR: + bd->memwinon = dummy_memwinon; + bd->memwinoff = dummy_memwinoff; + bd->globalwinon = dummy_globalwinon; + bd->txwinon = dummy_txwinon; + bd->rxwinon = dummy_rxwinon; + bd->memoff = dummy_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; + + case PCXE: + case PCXEVE: + + bd->memwinon = pcxe_memwinon; + bd->memwinoff = pcxe_memwinoff; + bd->globalwinon = pcxe_globalwinon; + bd->txwinon = pcxe_txwinon; + bd->rxwinon = pcxe_rxwinon; + bd->memoff = pcxe_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; + + case PCXI: + case PC64XE: + + bd->memwinon = pcxi_memwinon; + bd->memwinoff = pcxi_memwinoff; + bd->globalwinon = pcxi_globalwinon; + bd->txwinon = pcxi_txwinon; + bd->rxwinon = pcxi_rxwinon; + bd->memoff = pcxi_memoff; + bd->assertgwinon = pcxi_assertgwinon; + bd->assertmemoff = pcxi_assertmemoff; + break; + + default: + break; + + } /* End switch on bd->type */ + + /* --------------------------------------------------------------- + Some cards need a memory segment to be defined for use in + transmit and receive windowing operations. These boards + are listed in the below switch. In the case of the XI the + amount of memory on the board is variable so the memory_seg + is also variable. This code determines what they segment + should be. + ----------------------------------------------------------------- */ + + switch (bd->type) + { /* Begin switch on bd->type {board type} */ + + case PCXE: + case PCXEVE: + case PC64XE: + bd->memory_seg = 0xf000; + break; + + case PCXI: + board_id = inb((int)bd->port); + if ((board_id & 0x1) == 0x1) + { /* Begin its an XI card */ + + /* Is it a 64K board */ + if ((board_id & 0x30) == 0) + bd->memory_seg = 0xf000; + + /* Is it a 128K board */ + if ((board_id & 0x30) == 0x10) + bd->memory_seg = 0xe000; + + /* Is is a 256K board */ + if ((board_id & 0x30) == 0x20) + bd->memory_seg = 0xc000; + + /* Is it a 512K board */ + if ((board_id & 0x30) == 0x30) + bd->memory_seg = 0x8000; + + } /* End it is an XI card */ + else + { + printk(KERN_ERR " - Board at 0x%x doesn't appear to be an XI\n",(int)bd->port); + } + break; + + } /* End switch on bd->type */ + + } /* End for each card */ + + if (tty_register_driver(&pc_driver)) + panic("Couldn't register Digi PC/ driver"); + + if (tty_register_driver(&pc_callout)) + panic("Couldn't register Digi PC/ callout"); + + if (tty_register_driver(&pc_info)) + panic("Couldn't register Digi PC/ info "); + + loops_per_sec = save_loops_per_sec; /* reset it to what it should be */ + + /* ------------------------------------------------------------------- + Start up the poller to check for events on all enabled boards + ---------------------------------------------------------------------- */ + + timer_table[DIGI_TIMER].fn = (void *)epcapoll; + timer_table[DIGI_TIMER].expires = 0; + + restore_flags(flags); + + timer_active |= 1 << DIGI_TIMER; + return 0; + +} /* End pc_init */ + +/* ------------------ Begin post_fep_init ---------------------- */ + +static void post_fep_init(unsigned int crd) +{ /* Begin post_fep_init */ + + int i; + unchar *memaddr; + volatile struct global_data *gd; + struct board_info *bd; + volatile struct board_chan *bc; + struct channel *ch; + int shrinkmem = 0, lowwater ; + + /* ------------------------------------------------------------- + This call is made by the user via. the ioctl call DIGI_INIT. + It is resposible for setting up all the card specific stuff. + ---------------------------------------------------------------- */ + bd = &boards[crd]; + + /* ----------------------------------------------------------------- + If this is a PCI board, get the port info. Remember PCI cards + do not have entries into the epcaconfig.h file, so we can't get + the number of ports from it. Unfortunetly, this means that anyone + doing a DIGI_GETINFO before the board has booted will get an invalid + number of ports returned (It should return 0). Calls to DIGI_GETINFO + after DIGI_INIT has been called will return the proper values. + ------------------------------------------------------------------- */ + + if (bd->type >= PCIXEM) /* If the board in question is PCI */ + { /* Begin get PCI number of ports */ + + /* -------------------------------------------------------------------- + Below we use XEMPORTS as a memory offset regardless of which PCI + card it is. This is because all of the supported PCI cards have + the same memory offset for the channel data. This will have to be + changed if we ever develop a PCI/XE card. NOTE : The FEP manual + states that the port offset is 0xC22 as opposed to 0xC02. This is + only true for PC/XE, and PC/XI cards; not for the XEM, or CX series. + On the PCI cards the number of ports is determined by reading a + ID PROM located in the box attached to the card. The card can then + determine the index the id to determine the number of ports available. + (FYI - The id should be located at 0x1ac (And may use up to 4 bytes + if the box in question is a XEM or CX)). + ------------------------------------------------------------------------ */ + + bd->numports = (unsigned short)*(unsigned char *)bus_to_virt((unsigned long) + (bd->re_map_membase + XEMPORTS)); + + + epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports"); + nbdevs += (bd->numports); + + } /* End get PCI number of ports */ + + if (crd != 0) + card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports; + else + card_ptr[crd] = &digi_channels[crd]; /* <- For card 0 only */ + + ch = card_ptr[crd]; + + + epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range"); + + if (bd->membase < (unsigned char *)0x100000) + memaddr = (unchar *) bd->membase; + else /* Else get special mapped memory above RAM */ + memaddr = (unchar *)bd->re_map_membase; + + /* + The below command is necessary because newer kernels (2.1.x and + up) do not have a 1:1 virtual to physical mapping. The below + call adjust for that. + */ + + memaddr = (unsigned char *)bus_to_virt((unsigned long)memaddr); + + /* ----------------------------------------------------------------- + The below assignment will set bc to point at the BEGINING of + the cards channel structures. For 1 card there will be between + 8 and 64 of these structures. + -------------------------------------------------------------------- */ + + bc = (volatile struct board_chan *)((ulong)memaddr + CHANSTRUCT); + + /* ------------------------------------------------------------------- + The below assignment will set gd to point at the BEGINING of + global memory address 0xc00. The first data in that global + memory actually starts at address 0xc1a. The command in + pointer begins at 0xd10. + ---------------------------------------------------------------------- */ + + gd = (volatile struct global_data *)((ulong)memaddr + GLOBAL); + + /* -------------------------------------------------------------------- + XEPORTS (address 0xc22) points at the number of channels the + card supports. (For 64XE, XI, XEM, and XR use 0xc02) + ----------------------------------------------------------------------- */ + + if (((bd->type == PCXEVE) | (bd->type == PCXE)) && + (*(ushort *)((ulong)memaddr + XEPORTS) < 3)) + shrinkmem = 1; + if (bd->type < PCIXEM) + request_region((int)bd->port, 4, board_desc[bd->type]); + + memwinon(bd, 0); + + /* -------------------------------------------------------------------- + Remember ch is the main drivers channels structure, while bc is + the cards channel structure. + ------------------------------------------------------------------------ */ + + /* For every port on the card do ..... */ + + for (i = 0; i < bd->numports; i++, ch++, bc++) + { /* Begin for each port */ + + ch->brdchan = bc; + ch->mailbox = gd; + ch->tqueue.routine = do_softint; + ch->tqueue.data = ch; + ch->board = &boards[crd]; + + switch (bd->type) + { /* Begin switch bd->type */ + + /* ---------------------------------------------------------------- + Since some of the boards use different bitmaps for their + control signals we cannot hard code these values and retain + portability. We virtualize this data here. + ------------------------------------------------------------------- */ + case EISAXEM: + case PCXEM: + case PCIXEM: + case PCIXRJ: + case PCIXR: + ch->m_rts = 0x02 ; + ch->m_dcd = 0x80 ; + ch->m_dsr = 0x20 ; + ch->m_cts = 0x10 ; + ch->m_ri = 0x40 ; + ch->m_dtr = 0x01 ; + break; + + case PCXE: + case PCXEVE: + case PCXI: + case PC64XE: + ch->m_rts = 0x02 ; + ch->m_dcd = 0x08 ; + ch->m_dsr = 0x10 ; + ch->m_cts = 0x20 ; + ch->m_ri = 0x40 ; + ch->m_dtr = 0x80 ; + break; + + } /* End switch bd->type */ + + if (boards[crd].altpin) + { + ch->dsr = ch->m_dcd; + ch->dcd = ch->m_dsr; + ch->digiext.digi_flags |= DIGI_ALTPIN; + } + else + { + ch->dcd = ch->m_dcd; + ch->dsr = ch->m_dsr; + } + + ch->boardnum = crd; + ch->channelnum = i; + ch->magic = EPCA_MAGIC; + ch->tty = 0; + + if (shrinkmem) + { + fepcmd(ch, SETBUFFER, 32, 0, 0, 0); + shrinkmem = 0; + } + + switch (bd->type) + { /* Begin switch bd->type */ + + case PCIXEM: + case PCIXRJ: + case PCIXR: + /* Cover all the 2MEG cards */ + ch->txptr = memaddr + (((bc->tseg) << 4) & 0x1fffff); + ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x1fffff); + ch->txwin = FEPWIN | ((bc->tseg) >> 11); + ch->rxwin = FEPWIN | ((bc->rseg) >> 11); + break; + + case PCXEM: + case EISAXEM: + /* Cover all the 32K windowed cards */ + /* Mask equal to window size - 1 */ + ch->txptr = memaddr + (((bc->tseg) << 4) & 0x7fff); + ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x7fff); + ch->txwin = FEPWIN | ((bc->tseg) >> 11); + ch->rxwin = FEPWIN | ((bc->rseg) >> 11); + break; + + case PCXEVE: + case PCXE: + ch->txptr = memaddr + (((bc->tseg - bd->memory_seg) << 4) & 0x1fff); + ch->txwin = FEPWIN | ((bc->tseg - bd->memory_seg) >> 9); + ch->rxptr = memaddr + (((bc->rseg - bd->memory_seg) << 4) & 0x1fff); + ch->rxwin = FEPWIN | ((bc->rseg - bd->memory_seg) >>9 ); + break; + + case PCXI: + case PC64XE: + ch->txptr = memaddr + ((bc->tseg - bd->memory_seg) << 4); + ch->rxptr = memaddr + ((bc->rseg - bd->memory_seg) << 4); + ch->txwin = ch->rxwin = 0; + break; + + } /* End switch bd->type */ + + ch->txbufhead = 0; + ch->txbufsize = bc->tmax + 1; + + ch->rxbufhead = 0; + ch->rxbufsize = bc->rmax + 1; + + lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2); + + /* Set transmitter low water mark */ + fepcmd(ch, STXLWATER, lowwater, 0, 10, 0); + + /* Set receiver low water mark */ + + fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0); + + /* Set receiver high water mark */ + + fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0); + + bc->edelay = 100; + bc->idata = 1; + + ch->startc = bc->startc; + ch->stopc = bc->stopc; + ch->startca = bc->startca; + ch->stopca = bc->stopca; + + ch->fepcflag = 0; + ch->fepiflag = 0; + ch->fepoflag = 0; + ch->fepstartc = 0; + ch->fepstopc = 0; + ch->fepstartca = 0; + ch->fepstopca = 0; + + ch->close_delay = 50; + ch->count = 0; + ch->blocked_open = 0; + ch->callout_termios = pc_callout.init_termios; + ch->normal_termios = pc_driver.init_termios; + ch->open_wait = 0; + ch->close_wait = 0; + ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL); + if (!(ch->tmp_buf)) + { + printk(KERN_ERR "POST FEP INIT : kmalloc failed for port 0x%x\n",i); + + } + memset((void *)ch->tmp_buf,0,ch->txbufsize); + } /* End for each port */ + + printk(KERN_INFO + "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", + VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports); + sprintf(mesg, + "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", + VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports); + console_print(mesg); + + memwinoff(bd, 0); + +} /* End post_fep_init */ + +/* --------------------- Begin epcapoll ------------------------ */ + +static void epcapoll(unsigned long ignored) +{ /* Begin epcapoll */ + + unsigned long flags; + int crd; + volatile unsigned int head, tail; + struct channel *ch; + struct board_info *bd; + + /* ------------------------------------------------------------------- + This routine is called upon every timer interrupt. Even though + the Digi series cards are capable of generating interupts this + method of non-looping polling is more efficient. This routine + checks for card generated events (Such as receive data, are transmit + buffer empty) and acts on those events. + ----------------------------------------------------------------------- */ + + save_flags(flags); + cli(); + + for (crd = 0; crd < num_cards; crd++) + { /* Begin for each card */ + + bd = &boards[crd]; + ch = card_ptr[crd]; + + if ((bd->status == DISABLED) || digi_poller_inhibited) + continue; /* Begin loop next interation */ + + /* ----------------------------------------------------------- + assertmemoff is not needed here; indeed it is an empty subroutine. + It is being kept because future boards may need this as well as + some legacy boards. + ---------------------------------------------------------------- */ + + assertmemoff(ch); + + globalwinon(ch); + + /* --------------------------------------------------------------- + In this case head and tail actually refer to the event queue not + the transmit or receive queue. + ------------------------------------------------------------------- */ + + head = ch->mailbox->ein; + tail = ch->mailbox->eout; + + /* If head isn't equal to tail we have an event */ + + if (head != tail) + doevent(crd); + + memoff(ch); + + } /* End for each card */ + + timer_table[DIGI_TIMER].fn = (void *)epcapoll; + timer_table[DIGI_TIMER].expires = jiffies + (HZ / 25); + timer_active |= 1 << DIGI_TIMER; + + restore_flags(flags); + +} /* End epcapoll */ + +/* --------------------- Begin doevent ------------------------ */ + +static void doevent(int crd) +{ /* Begin doevent */ + + volatile unchar *eventbuf; + struct channel *ch, *chan0; + static struct tty_struct *tty; + volatile struct board_info *bd; + volatile struct board_chan *bc; + register volatile unsigned int tail, head; + register int event, channel; + register int mstat, lstat; + + /* ------------------------------------------------------------------- + This subroutine is called by epcapoll when an event is detected + in the event queue. This routine responds to those events. + --------------------------------------------------------------------- */ + + bd = &boards[crd]; + + chan0 = card_ptr[crd]; + epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range"); + + assertgwinon(chan0); + + while ((tail = chan0->mailbox->eout) != (head = chan0->mailbox->ein)) + { /* Begin while something in event queue */ + + assertgwinon(chan0); + + if (bd->membase < (unsigned char *)0x100000) + eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->membase + tail + ISTART)); + else + { + eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->re_map_membase + tail + ISTART)); + } + + /* Get the channel the event occured on */ + channel = eventbuf[0]; + + /* Get the actual event code that occured */ + event = eventbuf[1]; + + /* ---------------------------------------------------------------- + The two assignments below get the current modem status (mstat) + and the previous modem status (lstat). These are useful becuase + an event could signal a change in modem signals itself. + ------------------------------------------------------------------- */ + + mstat = eventbuf[2]; + lstat = eventbuf[3]; + + ch = chan0 + channel; + + if ((unsigned)channel >= bd->numports || !ch) + { + if (channel >= bd->numports) + ch = chan0; + bc = ch->brdchan; + goto next; + } + + if ((bc = ch->brdchan) == NULL) + goto next; + + if (event & DATA_IND) + { /* Begin DATA_IND */ + + receive_data(ch); + assertgwinon(ch); + + } /* End DATA_IND */ + else + if (event & MODEMCHG_IND) + { /* Begin MODEMCHG_IND */ + + /* A modem signal change has been indicated */ + + ch->imodem = mstat; + + if (ch->asyncflags & ASYNC_CHECK_CD) + { + if (mstat & ch->dcd) /* We are now receiving dcd */ + wake_up_interruptible(&ch->open_wait); + else + pc_sched_event(ch, EPCA_EVENT_HANGUP); /* No dcd; hangup */ + } + + } /* End MODEMCHG_IND */ + + tty = ch->tty; + if (tty) + { /* Begin if valid tty */ + + if (event & BREAK_IND) + { /* Begin if BREAK_IND */ + + /* A break has been indicated */ + + tty->flip.count++; + *tty->flip.flag_buf_ptr++ = TTY_BREAK; + + *tty->flip.char_buf_ptr++ = 0; + + tty_schedule_flip(tty); + + } /* End if BREAK_IND */ + else + if (event & LOWTX_IND) + { /* Begin LOWTX_IND */ + + if (ch->statusflags & LOWWAIT) + { /* Begin if LOWWAIT */ + + ch->statusflags &= ~LOWWAIT; + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); + + } /* End if LOWWAIT */ + + } /* End LOWTX_IND */ + else + if (event & EMPTYTX_IND) + { /* Begin EMPTYTX_IND */ + + /* This event is generated by setup_empty_event */ + + ch->statusflags &= ~TXBUSY; + if (ch->statusflags & EMPTYWAIT) + { /* Begin if EMPTYWAIT */ + + ch->statusflags &= ~EMPTYWAIT; + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + + wake_up_interruptible(&tty->write_wait); + + } /* End if EMPTYWAIT */ + + } /* End EMPTYTX_IND */ + + } /* End if valid tty */ + + + next: + globalwinon(ch); + + if (!bc) + printk(KERN_ERR " - bc == NULL in doevent!\n"); + else + bc->idata = 1; + + chan0->mailbox->eout = (tail + 4) & (IMAX - ISTART - 4); + globalwinon(chan0); + + } /* End while something in event queue */ + +} /* End doevent */ + +/* --------------------- Begin fepcmd ------------------------ */ + +static void fepcmd(struct channel *ch, int cmd, int word_or_byte, + int byte2, int ncmds, int bytecmd) +{ /* Begin fepcmd */ + + unchar *memaddr; + unsigned int head, cmdTail, cmdStart, cmdMax; + long count; + int n; + + /* This is the routine in which commands may be passed to the card. */ + + if (ch->board->status == DISABLED) + { + return; + } + + assertgwinon(ch); + + /* Remember head (As well as max) is just an offset not a base addr */ + head = ch->mailbox->cin; + + /* cmdStart is a base address */ + cmdStart = ch->mailbox->cstart; + + /* ------------------------------------------------------------------ + We do the addition below because we do not want a max pointer + relative to cmdStart. We want a max pointer that points at the + physical end of the command queue. + -------------------------------------------------------------------- */ + + cmdMax = (cmdStart + 4 + (ch->mailbox->cmax)); + + if (ch->board->membase < (unsigned char *)0x100000) + memaddr = ch->board->membase; + else + memaddr = ch->board->re_map_membase; + + /* + The below command is necessary because newer kernels (2.1.x and + up) do not have a 1:1 virtual to physical mapping. The below + call adjust for that. + */ + + memaddr = (unsigned char *)bus_to_virt((unsigned long)memaddr); + + if (head >= (cmdMax - cmdStart) || (head & 03)) + { + printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", __LINE__, + cmd, head); + printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", __LINE__, + cmdMax, cmdStart); + return; + } + + if (bytecmd) + { + *(volatile unchar *)(memaddr + head + cmdStart + 0) = (unchar)cmd; + + *(volatile unchar *)(memaddr + head + cmdStart + 1) = (unchar)ch->channelnum; + /* Below word_or_byte is bits to set */ + *(volatile unchar *)(memaddr + head + cmdStart + 2) = (unchar)word_or_byte; + /* Below byte2 is bits to reset */ + *(volatile unchar *)(memaddr + head + cmdStart + 3) = (unchar)byte2; + + } + else + { + *(volatile unchar *)(memaddr + head + cmdStart + 0) = (unchar)cmd; + *(volatile unchar *)(memaddr + head + cmdStart + 1) = (unchar)ch->channelnum; + *(volatile ushort*)(memaddr + head + cmdStart + 2) = (ushort)word_or_byte; + } + + head = (head + 4) & (cmdMax - cmdStart - 4); + ch->mailbox->cin = head; + + count = FEPTIMEOUT; + + for (;;) + { /* Begin forever loop */ + + count--; + if (count == 0) + { + printk(KERN_ERR " - Fep not responding in fepcmd()\n"); + return; + } + + head = ch->mailbox->cin; + cmdTail = ch->mailbox->cout; + + n = (head - cmdTail) & (cmdMax - cmdStart - 4); + + /* ---------------------------------------------------------- + Basically this will break when the FEP acknowledges the + command by incrementing cmdTail (Making it equal to head). + ------------------------------------------------------------- */ + + if (n <= ncmds * (sizeof(short) * 4)) + break; /* Well nearly forever :-) */ + + } /* End forever loop */ + +} /* End fepcmd */ + +/* --------------------------------------------------------------------- + Digi products use fields in their channels structures that are very + similar to the c_cflag and c_iflag fields typically found in UNIX + termios structures. The below three routines allow mappings + between these hardware "flags" and their respective Linux flags. +------------------------------------------------------------------------- */ + +/* --------------------- Begin termios2digi_h -------------------- */ + +static unsigned termios2digi_h(struct channel *ch, unsigned cflag) +{ /* Begin termios2digi_h */ + + unsigned res = 0; + + if (cflag & CRTSCTS) + { + ch->digiext.digi_flags |= (RTSPACE | CTSPACE); + res |= ((ch->m_cts) | (ch->m_rts)); + } + + if (ch->digiext.digi_flags & RTSPACE) + res |= ch->m_rts; + + if (ch->digiext.digi_flags & DTRPACE) + res |= ch->m_dtr; + + if (ch->digiext.digi_flags & CTSPACE) + res |= ch->m_cts; + + if (ch->digiext.digi_flags & DSRPACE) + res |= ch->dsr; + + if (ch->digiext.digi_flags & DCDPACE) + res |= ch->dcd; + + if (res & (ch->m_rts)) + ch->digiext.digi_flags |= RTSPACE; + + if (res & (ch->m_cts)) + ch->digiext.digi_flags |= CTSPACE; + + return res; + +} /* End termios2digi_h */ + +/* --------------------- Begin termios2digi_i -------------------- */ +static unsigned termios2digi_i(struct channel *ch, unsigned iflag) +{ /* Begin termios2digi_i */ + + unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | + INPCK | ISTRIP|IXON|IXANY|IXOFF); + + if (ch->digiext.digi_flags & DIGI_AIXON) + res |= IAIXON; + return res; + +} /* End termios2digi_i */ + +/* --------------------- Begin termios2digi_c -------------------- */ + +static unsigned termios2digi_c(struct channel *ch, unsigned cflag) +{ /* Begin termios2digi_c */ + + unsigned res = 0; + +#ifdef SPEED_HACK + /* CL: HACK to force 115200 at 38400 and 57600 at 19200 Baud */ + if ((cflag & CBAUD)== B38400) cflag=cflag - B38400 + B115200; + if ((cflag & CBAUD)== B19200) cflag=cflag - B19200 + B57600; +#endif /* SPEED_HACK */ + + if (cflag & CBAUDEX) + { /* Begin detected CBAUDEX */ + + ch->digiext.digi_flags |= DIGI_FAST; + + /* ------------------------------------------------------------- + HUPCL bit is used by FEP to indicate fast baud + table is to be used. + ----------------------------------------------------------------- */ + + res |= FEP_HUPCL; + + } /* End detected CBAUDEX */ + else ch->digiext.digi_flags &= ~DIGI_FAST; + + /* ------------------------------------------------------------------- + CBAUD has bit position 0x1000 set these days to indicate Linux + baud rate remap. Digi hardware can't handle the bit assignment. + (We use a different bit assignment for high speed.). Clear this + bit out. + ---------------------------------------------------------------------- */ + res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE); + + /* ------------------------------------------------------------- + This gets a little confusing. The Digi cards have their own + representation of c_cflags controling baud rate. For the most + part this is identical to the Linux implementation. However; + Digi supports one rate (76800) that Linux doesn't. This means + that the c_cflag entry that would normally mean 76800 for Digi + actually means 115200 under Linux. Without the below mapping, + a stty 115200 would only drive the board at 76800. Since + the rate 230400 is also found after 76800, the same problem afflicts + us when we choose a rate of 230400. Without the below modificiation + stty 230400 would actually give us 115200. + + There are two additional differences. The Linux value for CLOCAL + (0x800; 0004000) has no meaning to the Digi hardware. Also in + later releases of Linux; the CBAUD define has CBAUDEX (0x1000; + 0010000) ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX + should be checked for a screened out prior to termios2digi_c + returning. Since CLOCAL isn't used by the board this can be + ignored as long as the returned value is used only by Digi hardware. + ----------------------------------------------------------------- */ + + if (cflag & CBAUDEX) + { + /* ------------------------------------------------------------- + The below code is trying to guarantee that only baud rates + 115200 and 230400 are remapped. We use exclusive or because + the various baud rates share common bit positions and therefore + can't be tested for easily. + ----------------------------------------------------------------- */ + + + if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) || + (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX)))) + { + res += 1; + } + } + + return res; + +} /* End termios2digi_c */ + +/* --------------------- Begin epcaparam ----------------------- */ + +static void epcaparam(struct tty_struct *tty, struct channel *ch) +{ /* Begin epcaparam */ + + unsigned int cmdHead; + struct termios *ts; + volatile struct board_chan *bc; + unsigned mval, hflow, cflag, iflag; + + bc = ch->brdchan; + epcaassert(bc !=0, "bc out of range"); + + assertgwinon(ch); + + ts = tty->termios; + + if ((ts->c_cflag & CBAUD) == 0) + { /* Begin CBAUD detected */ + + cmdHead = bc->rin; + bc->rout = cmdHead; + cmdHead = bc->tin; + + /* Changing baud in mid-stream transmission can be wonderful */ + /* --------------------------------------------------------------- + Flush current transmit buffer by setting cmdTail pointer (tout) + to cmdHead pointer (tin). Hopefully the transmit buffer is empty. + ----------------------------------------------------------------- */ + + fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0); + mval = 0; + + } /* End CBAUD detected */ + else + { /* Begin CBAUD not detected */ + + /* ------------------------------------------------------------------- + c_cflags have changed but that change had nothing to do with BAUD. + Propagate the change to the card. + ---------------------------------------------------------------------- */ + + cflag = termios2digi_c(ch, ts->c_cflag); + + if (cflag != ch->fepcflag) + { + ch->fepcflag = cflag; + /* Set baud rate, char size, stop bits, parity */ + fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0); + } + + + /* ---------------------------------------------------------------- + If the user has not forced CLOCAL and if the device is not a + CALLOUT device (Which is always CLOCAL) we set flags such that + the driver will wait on carrier detect. + ------------------------------------------------------------------- */ + + if ((ts->c_cflag & CLOCAL) || (tty->driver.subtype == SERIAL_TYPE_CALLOUT)) + { /* Begin it is a cud device or a ttyD device with CLOCAL on */ + ch->asyncflags &= ~ASYNC_CHECK_CD; + } /* End it is a cud device or a ttyD device with CLOCAL on */ + else + { /* Begin it is a ttyD device */ + ch->asyncflags |= ASYNC_CHECK_CD; + } /* End it is a ttyD device */ + + mval = ch->m_dtr | ch->m_rts; + + } /* End CBAUD not detected */ + + iflag = termios2digi_i(ch, ts->c_iflag); + + /* Check input mode flags */ + + if (iflag != ch->fepiflag) + { + ch->fepiflag = iflag; + + /* --------------------------------------------------------------- + Command sets channels iflag structure on the board. Such things + as input soft flow control, handeling of parity errors, and + break handeling are all set here. + ------------------------------------------------------------------- */ + + /* break handeling, parity handeling, input stripping, flow control chars */ + fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0); + } + + /* --------------------------------------------------------------- + Set the board mint value for this channel. This will cause hardware + events to be generated each time the DCD signal (Described in mint) + changes. + ------------------------------------------------------------------- */ + bc->mint = ch->dcd; + + if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD)) + if (ch->digiext.digi_flags & DIGI_FORCEDCD) + bc->mint = 0; + + ch->imodem = bc->mstat; + + hflow = termios2digi_h(ch, ts->c_cflag); + + if (hflow != ch->hflow) + { + ch->hflow = hflow; + + /* -------------------------------------------------------------- + Hard flow control has been selected but the board is not + using it. Activate hard flow control now. + ----------------------------------------------------------------- */ + + fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1); + } + + + mval ^= ch->modemfake & (mval ^ ch->modem); + + if (ch->omodem ^ mval) + { + ch->omodem = mval; + + /* -------------------------------------------------------------- + The below command sets the DTR and RTS mstat structure. If + hard flow control is NOT active these changes will drive the + output of the actual DTR and RTS lines. If hard flow control + is active, the changes will be saved in the mstat structure and + only asserted when hard flow control is turned off. + ----------------------------------------------------------------- */ + + /* First reset DTR & RTS; then set them */ + fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1); + fepcmd(ch, SETMODEM, mval, 0, 0, 1); + + } + + if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) + { + ch->fepstartc = ch->startc; + ch->fepstopc = ch->stopc; + + /* ------------------------------------------------------------ + The XON / XOFF characters have changed; propogate these + changes to the card. + --------------------------------------------------------------- */ + + fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); + } + + if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) + { + ch->fepstartca = ch->startca; + ch->fepstopca = ch->stopca; + + /* --------------------------------------------------------------- + Similar to the above, this time the auxilarly XON / XOFF + characters have changed; propogate these changes to the card. + ------------------------------------------------------------------ */ + + fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); + } + +} /* End epcaparam */ + +/* --------------------- Begin receive_data ----------------------- */ + +static void receive_data(struct channel *ch) +{ /* Begin receive_data */ + + unchar *rptr; + struct termios *ts = 0; + struct tty_struct *tty; + volatile struct board_chan *bc; + register int dataToRead, wrapgap, bytesAvailable; + register unsigned int tail, head; + unsigned int wrapmask; + int rc; + + + /* --------------------------------------------------------------- + This routine is called by doint when a receive data event + has taken place. + ------------------------------------------------------------------- */ + + globalwinon(ch); + + if (ch->statusflags & RXSTOPPED) + return; + + tty = ch->tty; + if (tty) + ts = tty->termios; + + bc = ch->brdchan; + + if (!bc) + { + printk(KERN_ERR " - bc is NULL in receive_data!\n"); + return; + } + + wrapmask = ch->rxbufsize - 1; + + /* --------------------------------------------------------------------- + Get the head and tail pointers to the receiver queue. Wrap the + head pointer if it has reached the end of the buffer. + ------------------------------------------------------------------------ */ + + head = bc->rin; + head &= wrapmask; + tail = bc->rout & wrapmask; + + bytesAvailable = (head - tail) & wrapmask; + + if (bytesAvailable == 0) + return; + + /* ------------------------------------------------------------------ + If CREAD bit is off or device not open, set TX tail to head + --------------------------------------------------------------------- */ + + if (!tty || !ts || !(ts->c_cflag & CREAD)) + { + bc->rout = head; + return; + } + + if (tty->flip.count == TTY_FLIPBUF_SIZE) + return; + + if (bc->orun) + { + bc->orun = 0; + printk(KERN_WARNING "overrun! DigiBoard device minor = %d\n",MINOR(tty->device)); + } + + rxwinon(ch); + rptr = tty->flip.char_buf_ptr; + rc = tty->flip.count; + + while (bytesAvailable > 0) + { /* Begin while there is data on the card */ + + wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; + + /* --------------------------------------------------------------- + Even if head has wrapped around only report the amount of + data to be equal to the size - tail. Remember memcpy can't + automaticly wrap around the receive buffer. + ----------------------------------------------------------------- */ + + dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable; + + /* -------------------------------------------------------------- + Make sure we don't overflow the buffer + ----------------------------------------------------------------- */ + + if ((rc + dataToRead) > TTY_FLIPBUF_SIZE) + dataToRead = TTY_FLIPBUF_SIZE - rc; + + if (dataToRead == 0) + break; + + /* --------------------------------------------------------------- + Move data read from our card into the line disciplines buffer + for translation if necessary. + ------------------------------------------------------------------ */ + + if ((memcpy(rptr, ch->rxptr + tail, dataToRead)) != rptr) + printk(KERN_ERR " - receive_data : memcpy failed\n"); + + rc += dataToRead; + rptr += dataToRead; + tail = (tail + dataToRead) & wrapmask; + bytesAvailable -= dataToRead; + + } /* End while there is data on the card */ + + + tty->flip.count = rc; + tty->flip.char_buf_ptr = rptr; + globalwinon(ch); + bc->rout = tail; + + /* Must be called with global data */ + tty_schedule_flip(ch->tty); + return; + +} /* End receive_data */ + +/* --------------------- Begin pc_ioctl ----------------------- */ + +static int pc_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ /* Begin pc_ioctl */ + + digiflow_t dflow; + int retval, error; + unsigned long flags; + unsigned int mflag, mstat; + unsigned char startc, stopc; + volatile struct board_chan *bc; + struct channel *ch = (struct channel *) tty->driver_data; + + /* The control device has it's own set of commands */ + if (tty->driver.subtype == SERIAL_TYPE_INFO) + { /* Begin if subtype is the control device */ + + switch (cmd) + { /* Begin switch cmd */ + + case DIGI_GETINFO: + { /* Begin case DIGI_GETINFO */ + + struct digi_info di ; + int brd; + + getUser(brd, (unsigned int *)arg); + + if ((error = verify_area(VERIFY_WRITE, (char*)arg, sizeof(di)))) + { + printk(KERN_ERR "DIGI_GETINFO : verify area size 0x%x failed\n",sizeof(di)); + return(error); + } + + if ((brd < 0) || (brd >= num_cards) || (num_cards == 0)) + return (-ENODEV); + + memset(&di, 0, sizeof(di)); + + di.board = brd ; + di.status = boards[brd].status; + di.type = boards[brd].type ; + di.numports = boards[brd].numports ; + di.port = boards[brd].port ; + di.membase = boards[brd].membase ; + + copy_to_user((char *)arg, &di, sizeof (di)); + break; + + } /* End case DIGI_GETINFO */ + + case DIGI_POLLER: + { /* Begin case DIGI_POLLER */ + + int brd = arg & 0xff000000 >> 16 ; + unsigned char state = arg & 0xff ; + + if ((brd < 0) || (brd >= num_cards)) + { + printk(KERN_ERR " - DIGI POLLER : brd not valid!\n"); + return (-ENODEV); + } + + digi_poller_inhibited = state ; + break ; + + } /* End case DIGI_POLLER */ + + case DIGI_INIT: + { /* Begin case DIGI_INIT */ + + /* ------------------------------------------------------------ + This call is made by the apps to complete the initilization + of the board(s). This routine is responsible for setting + the card to its initial state and setting the drivers control + fields to the sutianle settings for the card in question. + ---------------------------------------------------------------- */ + + int crd ; + for (crd = 0; crd < num_cards; crd++) + post_fep_init (crd); + + break ; + + } /* End case DIGI_INIT */ + + + default: + return -ENOIOCTLCMD; + + } /* End switch cmd */ + return (0) ; + + } /* End if subtype is the control device */ + + if (ch) + bc = ch->brdchan; + else + { + printk(KERN_ERR " - ch is NULL in pc_ioctl!\n"); + return(-EINVAL); + } + + save_flags(flags); + + /* ------------------------------------------------------------------- + For POSIX compliance we need to add more ioctls. See tty_ioctl.c + in /usr/src/linux/drivers/char for a good example. In particular + think about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS. + ---------------------------------------------------------------------- */ + + switch (cmd) + { /* Begin switch cmd */ + + case TCGETS: + retval = verify_area(VERIFY_WRITE, (void *)arg, + sizeof(struct termios)); + + if (retval) + return(retval); + + copy_to_user((struct termios *)arg, + tty->termios, sizeof(struct termios)); + return(0); + + case TCGETA: + return get_termio(tty, (struct termio *)arg); + + case TCSBRK: /* SVID version: non-zero arg --> no break */ + + retval = tty_check_change(tty); + if (retval) + return retval; + + /* Setup an event to indicate when the transmit buffer empties */ + + setup_empty_event(tty,ch); + tty_wait_until_sent(tty, 0); + if (!arg) + digi_send_break(ch, HZ/4); /* 1/4 second */ + return 0; + + case TCSBRKP: /* support for POSIX tcsendbreak() */ + + retval = tty_check_change(tty); + if (retval) + return retval; + + /* Setup an event to indicate when the transmit buffer empties */ + + setup_empty_event(tty,ch); + tty_wait_until_sent(tty, 0); + digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4); + return 0; + + case TIOCGSOFTCAR: + + error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long)); + if (error) + return error; + + putUser(C_CLOCAL(tty) ? 1 : 0, + (unsigned long *) arg); + return 0; + + case TIOCSSOFTCAR: + /*RONNIE PUT VERIFY_READ (See above) check here */ + { + unsigned int value; + + getUser(value, (unsigned int *)arg); + tty->termios->c_cflag = + ((tty->termios->c_cflag & ~CLOCAL) | + (value ? CLOCAL : 0)); + return 0; + } + + case TIOCMODG: + case TIOCMGET: + + mflag = 0; + + cli(); + globalwinon(ch); + mstat = bc->mstat; + memoff(ch); + restore_flags(flags); + + if (mstat & ch->m_dtr) + mflag |= TIOCM_DTR; + + if (mstat & ch->m_rts) + mflag |= TIOCM_RTS; + + if (mstat & ch->m_cts) + mflag |= TIOCM_CTS; + + if (mstat & ch->dsr) + mflag |= TIOCM_DSR; + + if (mstat & ch->m_ri) + mflag |= TIOCM_RI; + + if (mstat & ch->dcd) + mflag |= TIOCM_CD; + + error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long)); + + if (error) + return error; + + putUser(mflag, (unsigned long *) arg); + + break; + + case TIOCMBIS: + case TIOCMBIC: + case TIOCMODS: + case TIOCMSET: + + getUser(mstat, (unsigned int *)arg); + + mflag = 0; + if (mstat & TIOCM_DTR) + mflag |= ch->m_dtr; + + if (mstat & TIOCM_RTS) + mflag |= ch->m_rts; + + switch (cmd) + { /* Begin switch cmd */ + + case TIOCMODS: + case TIOCMSET: + ch->modemfake = ch->m_dtr|ch->m_rts; + ch->modem = mflag; + break; + + case TIOCMBIS: + ch->modemfake |= mflag; + ch->modem |= mflag; + break; + + case TIOCMBIC: + ch->modemfake |= mflag; + ch->modem &= ~mflag; + break; + + } /* End switch cmd */ + + cli(); + globalwinon(ch); + + /* -------------------------------------------------------------- + The below routine generally sets up parity, baud, flow control + issues, etc.... It effect both control flags and input flags. + ------------------------------------------------------------------ */ + + epcaparam(tty,ch); + memoff(ch); + restore_flags(flags); + break; + + case TIOCSDTR: + ch->omodem |= ch->m_dtr; + cli(); + globalwinon(ch); + fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1); + memoff(ch); + restore_flags(flags); + break; + + case TIOCCDTR: + ch->omodem &= ~ch->m_dtr; + cli(); + globalwinon(ch); + fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1); + memoff(ch); + restore_flags(flags); + break; + + case DIGI_GETA: + if ((error= + verify_area(VERIFY_WRITE, (char*)arg, sizeof(digi_t)))) + { + printk(KERN_ERR " - Digi GETA failed\n"); + return(error); + } + + copy_to_user((char*)arg, &ch->digiext, sizeof(digi_t)); + break; + + case DIGI_SETAW: + case DIGI_SETAF: + if ((cmd) == (DIGI_SETAW)) + { + /* Setup an event to indicate when the transmit buffer empties */ + + setup_empty_event(tty,ch); + tty_wait_until_sent(tty, 0); + } + else + { + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + } + + /* Fall Thru */ + + case DIGI_SETA: + if ((error = + verify_area(VERIFY_READ, (char*)arg,sizeof(digi_t)))) + return(error); + + copy_from_user(&ch->digiext, (char*)arg, sizeof(digi_t)); + + if (ch->digiext.digi_flags & DIGI_ALTPIN) + { + ch->dcd = ch->m_dsr; + ch->dsr = ch->m_dcd; + } + else + { + ch->dcd = ch->m_dcd; + ch->dsr = ch->m_dsr; + } + + cli(); + globalwinon(ch); + + /* ----------------------------------------------------------------- + The below routine generally sets up parity, baud, flow control + issues, etc.... It effect both control flags and input flags. + ------------------------------------------------------------------- */ + + epcaparam(tty,ch); + memoff(ch); + restore_flags(flags); + break; + + case DIGI_GETFLOW: + case DIGI_GETAFLOW: + cli(); + globalwinon(ch); + if ((cmd) == (DIGI_GETFLOW)) + { + dflow.startc = bc->startc; + dflow.stopc = bc->stopc; + } + else + { + dflow.startc = bc->startca; + dflow.stopc = bc->stopca; + } + memoff(ch); + restore_flags(flags); + + if ((error = verify_area(VERIFY_WRITE, (char*)arg,sizeof(dflow)))) + return(error); + + copy_to_user((char*)arg, &dflow, sizeof(dflow)); + break; + + case DIGI_SETAFLOW: + case DIGI_SETFLOW: + if ((cmd) == (DIGI_SETFLOW)) + { + startc = ch->startc; + stopc = ch->stopc; + } + else + { + startc = ch->startca; + stopc = ch->stopca; + } + + if ((error = verify_area(VERIFY_READ, (char*)arg,sizeof(dflow)))) + return(error); + + copy_from_user(&dflow, (char*)arg, sizeof(dflow)); + + if (dflow.startc != startc || dflow.stopc != stopc) + { /* Begin if setflow toggled */ + cli(); + globalwinon(ch); + + if ((cmd) == (DIGI_SETFLOW)) + { + ch->fepstartc = ch->startc = dflow.startc; + ch->fepstopc = ch->stopc = dflow.stopc; + fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); + } + else + { + ch->fepstartca = ch->startca = dflow.startc; + ch->fepstopca = ch->stopca = dflow.stopc; + fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); + } + + if (ch->statusflags & TXSTOPPED) + pc_start(tty); + + memoff(ch); + restore_flags(flags); + + } /* End if setflow toggled */ + break; + + default: + return -ENOIOCTLCMD; + + } /* End switch cmd */ + + return 0; + +} /* End pc_ioctl */ + +/* --------------------- Begin pc_set_termios ----------------------- */ + +static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ /* Begin pc_set_termios */ + + struct channel *ch; + unsigned long flags; + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { /* Begin if channel valid */ + + save_flags(flags); + cli(); + globalwinon(ch); + epcaparam(tty, ch); + memoff(ch); + + if ((old_termios->c_cflag & CRTSCTS) && + ((tty->termios->c_cflag & CRTSCTS) == 0)) + tty->hw_stopped = 0; + + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&ch->open_wait); + + restore_flags(flags); + + } /* End if channel valid */ + +} /* End pc_set_termios */ + +/* --------------------- Begin do_softint ----------------------- */ + +static void do_softint(void *private_) +{ /* Begin do_softint */ + + struct channel *ch = (struct channel *) private_; + + + /* Called in response to a modem change event */ + + if (ch && ch->magic == EPCA_MAGIC) + { /* Begin EPCA_MAGIC */ + + struct tty_struct *tty = ch->tty; + + if (tty && tty->driver_data) + { + if (clear_bit(EPCA_EVENT_HANGUP, &ch->event)) + { /* Begin if clear_bit */ + + tty_hangup(tty); + wake_up_interruptible(&ch->open_wait); + ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE); + + } /* End if clear_bit */ + } + + } /* End EPCA_MAGIC */ + +} /* End do_softint */ + +/* ------------------------------------------------------------ + pc_stop and pc_start provide software flow control to the + routine and the pc_ioctl routine. +---------------------------------------------------------------- */ + +/* --------------------- Begin pc_stop ----------------------- */ + +static void pc_stop(struct tty_struct *tty) +{ /* Begin pc_stop */ + + struct channel *ch; + unsigned long flags; + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { /* Begin if valid channel */ + + save_flags(flags); + cli(); + + if ((ch->statusflags & TXSTOPPED) == 0) + { /* Begin if transmit stop requested */ + + globalwinon(ch); + + /* STOP transmitting now !! */ + + fepcmd(ch, PAUSETX, 0, 0, 0, 0); + + ch->statusflags |= TXSTOPPED; + memoff(ch); + + } /* End if transmit stop requested */ + + restore_flags(flags); + + } /* End if valid channel */ + +} /* End pc_stop */ + +/* --------------------- Begin pc_start ----------------------- */ + +static void pc_start(struct tty_struct *tty) +{ /* Begin pc_start */ + + struct channel *ch; + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { /* Begin if channel valid */ + + unsigned long flags; + + save_flags(flags); + cli(); + + /* Just in case output was resumed because of a change in Digi-flow */ + if (ch->statusflags & TXSTOPPED) + { /* Begin transmit resume requested */ + + volatile struct board_chan *bc; + + globalwinon(ch); + bc = ch->brdchan; + if (ch->statusflags & LOWWAIT) + bc->ilow = 1; + + /* Okay, you can start transmitting again... */ + + fepcmd(ch, RESUMETX, 0, 0, 0, 0); + + ch->statusflags &= ~TXSTOPPED; + memoff(ch); + + } /* End transmit resume requested */ + + restore_flags(flags); + + } /* End if channel valid */ + +} /* End pc_start */ + +/* ------------------------------------------------------------------ + The below routines pc_throttle and pc_unthrottle are used + to slow (And resume) the receipt of data into the kernels + receive buffers. The exact occurence of this depends on the + size of the kernels receive buffer and what the 'watermarks' + are set to for that buffer. See the n_ttys.c file for more + details. +______________________________________________________________________ */ +/* --------------------- Begin throttle ----------------------- */ + +static void pc_throttle(struct tty_struct * tty) +{ /* Begin pc_throttle */ + + struct channel *ch; + unsigned long flags; + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { /* Begin if channel valid */ + + + save_flags(flags); + cli(); + + if ((ch->statusflags & RXSTOPPED) == 0) + { + globalwinon(ch); + fepcmd(ch, PAUSERX, 0, 0, 0, 0); + + ch->statusflags |= RXSTOPPED; + memoff(ch); + } + restore_flags(flags); + + } /* End if channel valid */ + +} /* End pc_throttle */ + +/* --------------------- Begin unthrottle ----------------------- */ + +static void pc_unthrottle(struct tty_struct *tty) +{ /* Begin pc_unthrottle */ + + struct channel *ch; + unsigned long flags; + volatile struct board_chan *bc; + + + /* --------------------------------------------------------- + verifyChannel returns the channel from the tty struct + if it is valid. This serves as a sanity check. + ------------------------------------------------------------- */ + + if ((ch = verifyChannel(tty)) != NULL) + { /* Begin if channel valid */ + + + /* Just in case output was resumed because of a change in Digi-flow */ + save_flags(flags); + cli(); + + if (ch->statusflags & RXSTOPPED) + { + + globalwinon(ch); + bc = ch->brdchan; + fepcmd(ch, RESUMERX, 0, 0, 0, 0); + + ch->statusflags &= ~RXSTOPPED; + memoff(ch); + } + restore_flags(flags); + + } /* End if channel valid */ + +} /* End pc_unthrottle */ + +/* --------------------- Begin digi_send_break ----------------------- */ + +void digi_send_break(struct channel *ch, int msec) +{ /* Begin digi_send_break */ + + unsigned long flags; + + save_flags(flags); + cli(); + globalwinon(ch); + + /* -------------------------------------------------------------------- + Maybe I should send an infinite break here, schedule() for + msec amount of time, and then stop the break. This way, + the user can't screw up the FEP by causing digi_send_break() + to be called (i.e. via an ioctl()) more than once in msec amount + of time. Try this for now... + ------------------------------------------------------------------------ */ + + fepcmd(ch, SENDBREAK, msec, 0, 10, 0); + memoff(ch); + + restore_flags(flags); + +} /* End digi_send_break */ + +/* --------------------- Begin setup_empty_event ----------------------- */ + +static void setup_empty_event(struct tty_struct *tty, struct channel *ch) +{ /* Begin setup_empty_event */ + + volatile struct board_chan *bc = ch->brdchan; + unsigned long int flags; + + save_flags(flags); + cli(); + globalwinon(ch); + ch->statusflags |= EMPTYWAIT; + + /* ------------------------------------------------------------------ + When set the iempty flag request a event to be generated when the + transmit buffer is empty (If there is no BREAK in progress). + --------------------------------------------------------------------- */ + + bc->iempty = 1; + memoff(ch); + restore_flags(flags); + +} /* End setup_empty_event */ + +/* --------------------- Begin get_termio ----------------------- */ + +static int get_termio(struct tty_struct * tty, struct termio * termio) +{ /* Begin get_termio */ + int error; + + error = verify_area(VERIFY_WRITE, termio, sizeof (struct termio)); + if (error) + return error; + + kernel_termios_to_user_termio(termio, tty->termios); + + return 0; +} /* End get_termio */ +/* ---------------------- Begin epca_setup -------------------------- */ +void epca_setup(char *str, int *ints) +{ /* Begin epca_setup */ + + struct board_info board; + int index, loop, last; + char *temp, *t2; + unsigned len; + + /* ---------------------------------------------------------------------- + If this routine looks a little strange it is because it is only called + if a LILO append command is given to boot the kernel with parameters. + In this way, we can provide the user a method of changing his board + configuration without rebuilding the kernel. + ----------------------------------------------------------------------- */ + if (!liloconfig) + liloconfig = 1; + + memset(&board, 0, sizeof(board)); + + /* Assume the data is int first, later we can change it */ + /* I think that array position 0 of ints holds the number of args */ + for (last = 0, index = 1; index <= ints[0]; index++) + switch(index) + { /* Begin parse switch */ + + case 1: + board.status = ints[index]; + + /* --------------------------------------------------------- + We check for 2 (As opposed to 1; because 2 is a flag + instructing the driver to ignore epcaconfig.) For this + reason we check for 2. + ------------------------------------------------------------ */ + if (board.status == 2) + { /* Begin ignore epcaconfig as well as lilo cmd line */ + nbdevs = 0; + num_cards = 0; + return; + } /* End ignore epcaconfig as well as lilo cmd line */ + + if (board.status > 2) + { + printk(KERN_ERR " - epca_setup: Invalid board status 0x%x\n", board.status); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_STATUS; + return; + } + last = index; + break; + + case 2: + board.type = ints[index]; + if (board.type >= PCIXEM) + { + printk(KERN_ERR " - epca_setup: Invalid board type 0x%x\n", board.type); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_TYPE; + return; + } + last = index; + break; + + case 3: + board.altpin = ints[index]; + if (board.altpin > 1) + { + printk(KERN_ERR " - epca_setup: Invalid board altpin 0x%x\n", board.altpin); + invalid_lilo_config = 1; + setup_error_code |= INVALID_ALTPIN; + return; + } + last = index; + break; + + case 4: + board.numports = ints[index]; + if ((board.numports < 2) || (board.numports > 256)) + { + printk(KERN_ERR " - epca_setup: Invalid board numports 0x%x\n", board.numports); + invalid_lilo_config = 1; + setup_error_code |= INVALID_NUM_PORTS; + return; + } + nbdevs += board.numports; + last = index; + break; + + case 5: + board.port = (unsigned char *)ints[index]; + if (board.port <= 0) + { + printk(KERN_ERR " - epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port); + invalid_lilo_config = 1; + setup_error_code |= INVALID_PORT_BASE; + return; + } + last = index; + break; + + case 6: + board.membase = (unsigned char *)ints[index]; + if (board.membase <= 0) + { + printk(KERN_ERR " - epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase); + invalid_lilo_config = 1; + setup_error_code |= INVALID_MEM_BASE; + return; + } + last = index; + break; + + default: + printk(KERN_ERR " - epca_setup: Too many integer parms\n"); + return; + + } /* End parse switch */ + + while (str && *str) + { /* Begin while there is a string arg */ + + /* find the next comma or terminator */ + temp = str; + + /* While string is not null, and a comma hasn't been found */ + while (*temp && (*temp != ',')) + temp++; + + if (!*temp) + temp = NULL; + else + *temp++ = 0; + + /* Set index to the number of args + 1 */ + index = last + 1; + + switch(index) + { + case 1: + len = strlen(str); + if (strncmp("Disable", str, len) == 0) + board.status = 0; + else + if (strncmp("Enable", str, len) == 0) + board.status = 1; + else + { + printk(KERN_ERR " - epca_setup: Invalid status %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_STATUS; + return; + } + last = index; + break; + + case 2: + + for(loop = 0; loop < EPCA_NUM_TYPES; loop++) + if (strcmp(board_desc[loop], str) == 0) + break; + + + /* --------------------------------------------------------------- + If the index incremented above refers to a legitamate board + type set it here. + ------------------------------------------------------------------*/ + + if (index < EPCA_NUM_TYPES) + board.type = loop; + else + { + printk(KERN_ERR " - epca_setup: Invalid board type: %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_TYPE; + return; + } + last = index; + break; + + case 3: + len = strlen(str); + if (strncmp("Disable", str, len) == 0) + board.altpin = 0; + else + if (strncmp("Enable", str, len) == 0) + board.altpin = 1; + else + { + printk(KERN_ERR " - epca_setup: Invalid altpin %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_ALTPIN; + return; + } + last = index; + break; + + case 4: + t2 = str; + while (isdigit(*t2)) + t2++; + + if (*t2) + { + printk(KERN_ERR " - epca_setup: Invalid port count %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_NUM_PORTS; + return; + } + + /* ------------------------------------------------------------ + There is not a man page for simple_strtoul but the code can be + found in vsprintf.c. The first argument is the string to + translate (To an unsigned long obviously), the second argument + can be the address of any character variable or a NULL. If a + variable is given, the end pointer of the string will be stored + in that variable; if a NULL is given the the end pointer will + not be returned. The last argument is the base to use. If + a 0 is indicated, the routine will attempt to determine the + proper base by looking at the values prefix (A '0' for octal, + a 'x' for hex, etc ... If a value is given it will use that + value as the base. + ---------------------------------------------------------------- */ + board.numports = simple_strtoul(str, NULL, 0); + nbdevs += board.numports; + last = index; + break; + + case 5: + t2 = str; + while (isxdigit(*t2)) + t2++; + + if (*t2) + { + printk(KERN_ERR " - epca_setup: Invalid i/o address %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_PORT_BASE; + return; + } + + board.port = (unsigned char *)simple_strtoul(str, NULL, 16); + last = index; + break; + + case 6: + t2 = str; + while (isxdigit(*t2)) + t2++; + + if (*t2) + { + printk(KERN_ERR " - epca_setup: Invalid memory base %s\n",str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_MEM_BASE; + return; + } + + board.membase = (unsigned char *)simple_strtoul(str, NULL, 16); + last = index; + break; + + default: + printk(KERN_ERR "PC/Xx: Too many string parms\n"); + return; + } + str = temp; + + } /* End while there is a string arg */ + + + if (last < 6) + { + printk(KERN_ERR "PC/Xx: Insufficient parms specified\n"); + return; + } + + /* I should REALLY validate the stuff here */ + + /* Copies our local copy of board into boards */ + memcpy((void *)&boards[num_cards],(void *)&board, sizeof(board)); + + + /* Does this get called once per lilo arg are what ? */ + + printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", + num_cards, board_desc[board.type], + board.numports, (int)board.port, (unsigned int) board.membase); + + num_cards++; + +} /* End epca_setup */ + + + +#ifdef ENABLE_PCI +/* --------------------- Begin get_PCI_configuration ---------------------- */ + +int get_PCI_configuration(char bus, char device_fn, + unsigned int *base_addr0, unsigned int *base_addr1, + unsigned int *base_addr2, unsigned int *base_addr3, + unsigned int *base_addr4, unsigned int *base_addr5) +{ /* Begin get_PCI_configuration */ + + int error; + + error = pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_0, + base_addr0); + + error |= pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_1, + base_addr1); + + error |= pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_2, + base_addr2); + + error |= pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_3, + base_addr3); + + error |= pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_4, + base_addr4); + + error |= pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_5, + base_addr5); + + /* ------------------------------------------------------------------------ + NOTE - The code below mask out either the 2 or 4 bits dependant on the + space being addressed. (base_addr value reflecting io space, have their + first 2 bits mask out, while base_addr value reflecting mem space, have + their first 4 bits mask out.) These bits are flag bits and should always + be 0 when used as an address. + ---------------------------------------------------------------------------- */ + + if ((*base_addr0) & PCI_BASE_ADDRESS_SPACE_IO) /* Is this an io address ? */ + (*base_addr0) &= PCI_BASE_ADDRESS_IO_MASK; + else + (*base_addr0) &= PCI_BASE_ADDRESS_MEM_MASK; + + if ((*base_addr1) & PCI_BASE_ADDRESS_SPACE_IO) /* Is this an io address ? */ + (*base_addr1) &= PCI_BASE_ADDRESS_IO_MASK; + else + (*base_addr1) &= PCI_BASE_ADDRESS_MEM_MASK; + + if ((*base_addr2) & PCI_BASE_ADDRESS_SPACE_IO) /* Is this an io address ? */ + (*base_addr2) &= PCI_BASE_ADDRESS_IO_MASK; + else + (*base_addr2) &= PCI_BASE_ADDRESS_MEM_MASK; + + if ((*base_addr3) & PCI_BASE_ADDRESS_SPACE_IO) /* Is this an io address ? */ + (*base_addr3) &= PCI_BASE_ADDRESS_IO_MASK; + else + (*base_addr3) &= PCI_BASE_ADDRESS_MEM_MASK; + + if ((*base_addr4) & PCI_BASE_ADDRESS_SPACE_IO) /* Is this an io address ? */ + (*base_addr4) &= PCI_BASE_ADDRESS_IO_MASK; + else + (*base_addr4) &= PCI_BASE_ADDRESS_MEM_MASK; + + if ((*base_addr5) & PCI_BASE_ADDRESS_SPACE_IO) /* Is this an io address ? */ + (*base_addr5) &= PCI_BASE_ADDRESS_IO_MASK; + else + (*base_addr5) &= PCI_BASE_ADDRESS_MEM_MASK; + + if (error) + { + printk(KERN_ERR " - DIGI PCI error: board not initializing due to error\n"); + return(0); + } + return(1); +} /* End get_PCI_configuration */ + +/* ------------------------ Begin init_PCI --------------------------- */ + +int init_PCI(int boards_found) +{ /* Begin init_PCI */ + + unsigned char bus, device_fn; + int i, pci_count = 0; + unsigned int base_addr0, base_addr1, base_addr2, + base_addr3, base_addr4, base_addr5; + + base_addr0 = base_addr1 = base_addr2 = 0; + base_addr3 = base_addr4 = base_addr5 = 0; + + for(i = 0; i < (MAXBOARDS - boards_found); i++) + { /* Begin for each POSSIBLE remaining board */ + + if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XR, + i, &bus, &device_fn)) + { /* Begin found XR */ + if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, + &base_addr2, &base_addr3, + &base_addr4, &base_addr5)) + { /* Store a PCI/XR into the boards structure */ + + + boards[boards_found + pci_count].status = ENABLED; + boards[boards_found + pci_count].type = PCIXR; + + boards[boards_found + pci_count].numports = 0x0; + + boards[boards_found + pci_count].port = (unsigned char *)((char *)base_addr0 + PCI_IO_OFFSET); + /* Most cards use base_addr0, but some use base_addr2 */ + boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; + + if (base_addr0 >= 0x100000) + { + /* ------------------------------------------------------------ + Standard physical addresses are valid to the kernel as long + as they aren't above RAM. Higher addresses (Such as are + typical of a PCI system) need to be mapped in with the + ioremap command. For boards using such high addresses the + driver will store both addresses. One address (The physical) + will be held for the apps use (And mmap) and the other (The + ioremapped address) will be used in the kernel. + + ---------------------------------------------------------------- */ + boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); + boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); + } + + pci_count++; + + /* -------------------------------------------------------------- + I don't know what the below does, but the hardware guys say + its required on everything except PLX (In this case XRJ). + ---------------------------------------------------------------- */ + pcibios_write_config_byte(bus, device_fn, 0x40, 0); + pcibios_write_config_byte(bus, device_fn, 0x46, 0); + + } /* End store a PCI/XR into the board structure */ + + } /* End found XR */ + + if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XEM, + i, &bus, &device_fn)) + { /* Begin found XEM */ + + if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, + &base_addr2, &base_addr3, + &base_addr4, &base_addr5)) + { /* Begin store a PCI/XEM into the boards structure */ + + boards[boards_found + pci_count].status = ENABLED; + boards[boards_found + pci_count].type = PCIXEM; + + boards[boards_found + pci_count].numports = 0x0; + boards[boards_found + pci_count].port = (char *)((char *)base_addr0 + PCI_IO_OFFSET); + /* Most cards use base_addr0, but some use base_addr2 */ + boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; + + if (base_addr0 >= 0x100000) + { + /* ------------------------------------------------------------ + Standard physical addresses are valid to the kernel as long + as they aren't above RAM. Higher addresses (Such as are + typical of a PCI system) need to be mapped in with the + ioremap command. For boards using such high addresses the + driver will store both addresses. One address (The physical) + will be held for the apps use (And mmap) and the other (The + vremapped address) will be used in the kernel. + + ---------------------------------------------------------------- */ + boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); + boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); + } + + pci_count++; + /* -------------------------------------------------------------- + I don't know what the below does, but the hardware guys say + its required on everything except PLX (In this case XRJ). + ---------------------------------------------------------------- */ + pcibios_write_config_byte(bus, device_fn, 0x40, 0); + pcibios_write_config_byte(bus, device_fn, 0x46, 0); + + } /* End store a PCI/XEM into the boards structure */ + + } /* End found XEM */ + + + if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_CX, + i, &bus, &device_fn)) + { /* Begin found CX */ + + if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, + &base_addr2, &base_addr3, + &base_addr4, &base_addr5)) + { /* Begin store a PCI/CX into the boards structure */ + + boards[boards_found + pci_count].status = ENABLED; + boards[boards_found + pci_count].type = PCICX; + + boards[boards_found + pci_count].numports = 0x0; + boards[boards_found + pci_count].port = (char *)((char *)base_addr0 + PCI_IO_OFFSET); + /* Most cards use base_addr0, but some use base_addr2 */ + boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; + + if (base_addr0 >= 0x100000) + { + /* ------------------------------------------------------------ + Standard physical addresses are valid to the kernel as long + as they aren't above RAM. Higher addresses (Such as are + typical of a PCI system) need to be mapped in with the + ioremap command. For boards using such high addresses the + driver will store both addresses. One address (The physical) + will be held for the apps use (And mmap) and the other (The + vremapped address) will be used in the kernel. + + ---------------------------------------------------------------- */ + boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); + boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); + } + + pci_count++; + /* -------------------------------------------------------------- + I don't know what the below does, but the hardware guys say + its required on everything except PLX (In this case XRJ). + ---------------------------------------------------------------- */ + pcibios_write_config_byte(bus, device_fn, 0x40, 0); + pcibios_write_config_byte(bus, device_fn, 0x46, 0); + + } /* End store a PCI/CX into the boards structure */ + + } /* End found CX */ + + if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, + i, &bus, &device_fn)) + { /* Begin found XRJ */ + + if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, + &base_addr2, &base_addr3, + &base_addr4, &base_addr5)) + { /* Begin store a PCI/XRJ into the boards structure */ + + boards[boards_found + pci_count].status = ENABLED; + boards[boards_found + pci_count].type = PCIXRJ; + + boards[boards_found + pci_count].numports = 0x0; + boards[boards_found + pci_count].port = (unsigned char *)(base_addr2 + PCI_IO_OFFSET); + /* Most cards use base_addr0, but some use base_addr2 */ + boards[boards_found + pci_count].membase = (unsigned char *)base_addr2; + + if (base_addr2 >= 0x100000) + { + /* ------------------------------------------------------------ + Standard physical addresses are valid to the kernel as long + as they aren't above RAM. Higher addresses (Such as are + typical of a PCI system) need to be mapped in with the + ioremap command. For boards using such high addresses the + driver will store both addresses. One address (The physical) + will be held for the apps use (And mmap) and the other (The + vremapped address) will be used in the kernel. + + ---------------------------------------------------------------- */ + boards[boards_found + pci_count].re_map_port = ioremap((base_addr2 + PCI_IO_OFFSET),0x200000); + boards[boards_found + pci_count].re_map_membase = ioremap(base_addr2, 0x200000); + } + + pci_count++; + + } /* End store a PCI/XRJ into the boards structure */ + + } /* End found XRJ */ + + } /* End for each POSSIBLE remaining board */ + + return(pci_count); + +} /* End init_PCI */ + +#endif /* ENABLE_PCI */ + + diff -u --recursive --new-file v2.1.36/linux/drivers/char/random.c linux/drivers/char/random.c --- v2.1.36/linux/drivers/char/random.c Wed Apr 23 19:01:17 1997 +++ linux/drivers/char/random.c Sat Apr 26 10:31:36 1997 @@ -1,7 +1,7 @@ /* * random.c -- A strong random number generator * - * Version 1.01, last modified 13-Feb-97 + * Version 1.02, last modified 15-Apr-97 * * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997. All rights reserved. * @@ -839,6 +839,18 @@ digest[ 4 ] += E; } +#undef ROTL +#undef f1 +#undef f2 +#undef f3 +#undef f4 +#undef K1 +#undef K2 +#undef K3 +#undef K4 +#undef expand +#undef subRound + #else #define HASH_BUFFER_SIZE 4 #define HASH_TRANSFORM MD5Transform @@ -1324,22 +1336,90 @@ * attacks which rely on guessing the initial TCP sequence number. * This algorithm was suggested by Steve Bellovin. */ + +/* F, G and H are basic MD4 functions: selection, majority, parity */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) ) + +/* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s) \ + {(a) += F ((b), (c), (d)) + (x); \ + (a) = ROTL ((s), (a));} +#define GG(a, b, c, d, x, s) \ + {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \ + (a) = ROTL ((s), (a));} +#define HH(a, b, c, d, x, s) \ + {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \ + (a) = ROTL ((s), (a));} + +/* + * Basic cut-down MD4 transform + */ +static void halfMD4Transform (__u32 buf[4], __u32 in[8]) +{ + __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ + FF (a, b, c, d, in[ 0], 3); + FF (d, a, b, c, in[ 1], 7); + FF (c, d, a, b, in[ 2], 11); + FF (b, c, d, a, in[ 3], 19); + FF (a, b, c, d, in[ 4], 3); + FF (d, a, b, c, in[ 5], 7); + FF (c, d, a, b, in[ 6], 11); + FF (b, c, d, a, in[ 7], 19); + + /* Round 2 */ + GG (a, b, c, d, in[ 0], 3); + GG (d, a, b, c, in[ 4], 5); + GG (a, b, c, d, in[ 1], 9); + GG (d, a, b, c, in[ 5], 13); + GG (a, b, c, d, in[ 2], 3); + GG (d, a, b, c, in[ 6], 5); + GG (a, b, c, d, in[ 3], 9); + GG (d, a, b, c, in[ 7], 13); + + /* Round 3 */ + HH (a, b, c, d, in[ 0], 3); + HH (c, d, a, b, in[ 4], 9); + HH (a, b, c, d, in[ 2], 11); + HH (c, d, a, b, in[ 6], 15); + HH (a, b, c, d, in[ 1], 3); + HH (c, d, a, b, in[ 5], 9); + HH (a, b, c, d, in[ 3], 11); + HH (c, d, a, b, in[ 7], 15); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#define REKEY_INTERVAL 300 + __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport) { - static int is_init = 0; - static __u32 secret[16]; + static __u32 rekey_time = 0; + static __u32 secret[12]; + static char count = 0; struct timeval tv; - __u32 tmp[16]; + __u32 tmp[12]; __u32 seq; /* - * Pick a random secret the first time we open a TCP - * connection. + * Pick a random secret every REKEY_INTERVAL seconds */ - if (is_init == 0) { + do_gettimeofday(&tv); + if (!rekey_time || + (tv.tv_sec - rekey_time) > REKEY_INTERVAL) { get_random_bytes(&secret, sizeof(secret)); - is_init = 1; + rekey_time = tv.tv_sec; + count++; } memcpy(tmp, secret, sizeof(tmp)); @@ -1350,7 +1430,7 @@ tmp[8]=saddr; tmp[9]=daddr; tmp[10]=(sport << 16) + dport; - HASH_TRANSFORM(tmp, tmp); + halfMD4Transform(tmp, tmp+4); /* * As close as possible to RFC 793, which @@ -1359,8 +1439,8 @@ * For 10MB/s ethernet, a 1MHz clock is appropriate. * That's funny, Linux has one built in! Use it! */ - do_gettimeofday(&tv); - seq = tmp[1] + tv.tv_usec+tv.tv_sec*1000000; + seq = (tmp[1]&0xFFFFFF) + (tv.tv_usec+tv.tv_sec*1000000) + + (count << 24); #if 0 printk("init_seq(%lx, %lx, %d, %d) = %d\n", saddr, daddr, sport, dport, seq); diff -u --recursive --new-file v2.1.36/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.1.36/linux/drivers/char/tty_io.c Wed Apr 23 19:01:18 1997 +++ linux/drivers/char/tty_io.c Tue Apr 29 11:45:43 1997 @@ -166,14 +166,11 @@ { #ifdef CHECK_TTY_COUNT struct file *f; - int i, count = 0; + int count = 0; - for (f = first_file, i=0; if_next) { - if (!f->f_count) - continue; - if (f->private_data == tty) { + for(f = inuse_filps; f; f = f->f_next) { + if(f->private_data == tty) count++; - } } if (tty->driver.type == TTY_DRIVER_TYPE_PTY && tty->driver.subtype == PTY_TYPE_SLAVE && @@ -363,16 +360,14 @@ void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops) { - int i; + struct file * filp; struct task_struct *p; if (!tty) return; check_tty_count(tty, "do_tty_hangup"); - for (filp = first_file, i=0; if_next) { - if (!filp->f_count) - continue; + for (filp = inuse_filps; filp; filp = filp->f_next) { if (filp->private_data != tty) continue; if (!filp->f_inode) @@ -405,13 +400,14 @@ tty->ldisc = ldiscs[N_TTY]; tty->termios->c_line = N_TTY; if (tty->ldisc.open) { - i = (tty->ldisc.open)(tty); + int i = (tty->ldisc.open)(tty); if (i < 0) printk("do_tty_hangup: N_TTY open: error %d\n", -i); } } + read_lock(&tasklist_lock); for_each_task(p) { if ((tty->session > 0) && (p->session == tty->session) && p->leader) { @@ -423,6 +419,8 @@ if (p->tty == tty) p->tty = NULL; } + read_unlock(&tasklist_lock); + tty->flags = 0; tty->session = 0; tty->pgrp = -1; @@ -494,9 +492,11 @@ tty->session = 0; tty->pgrp = -1; + read_lock(&tasklist_lock); for_each_task(p) if (p->session == current->session) p->tty = NULL; + read_unlock(&tasklist_lock); } void wait_for_keypress(void) @@ -1338,9 +1338,11 @@ */ struct task_struct *p; + read_lock(&tasklist_lock); for_each_task(p) if (p->tty == tty) p->tty = NULL; + read_unlock(&tasklist_lock); } else return -EPERM; } @@ -1760,6 +1762,9 @@ #endif #ifdef CONFIG_DIGI pcxe_init(); +#endif +#ifdef CONFIG_DIGIEPCA + pc_init(); #endif #ifdef CONFIG_RISCOM8 riscom8_init(); diff -u --recursive --new-file v2.1.36/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.1.36/linux/drivers/char/vt.c Wed Apr 23 19:01:18 1997 +++ linux/drivers/char/vt.c Sun Apr 27 15:08:01 1997 @@ -123,6 +123,7 @@ } } + read_lock(&tasklist_lock); for_each_task(p) { if ( p->tty && MAJOR(p->tty->device) == TTY_MAJOR && @@ -131,6 +132,7 @@ send_sig(SIGWINCH, p, 1); } } + read_unlock(&tasklist_lock); return 0; } diff -u --recursive --new-file v2.1.36/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c --- v2.1.36/linux/drivers/net/ltpc.c Wed Apr 23 19:01:19 1997 +++ linux/drivers/net/ltpc.c Fri Apr 25 15:25:56 1997 @@ -1259,7 +1259,7 @@ if(debug&DEBUG_VERBOSE) printk("waiting\n"); /* if it's in process, wait a bit for it to finish */ timeout = jiffies+HZ; - add_timer(<pc_timer) + add_timer(<pc_timer); while(del_timer(<pc_timer) && (timeout > jiffies)) { add_timer(<pc_timer); diff -u --recursive --new-file v2.1.36/linux/drivers/sbus/char/creator.c linux/drivers/sbus/char/creator.c --- v2.1.36/linux/drivers/sbus/char/creator.c Wed Apr 23 19:01:21 1997 +++ linux/drivers/sbus/char/creator.c Sun Apr 27 15:13:50 1997 @@ -47,52 +47,3 @@ 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.36/linux/drivers/sbus/char/sunserial.c linux/drivers/sbus/char/sunserial.c --- v2.1.36/linux/drivers/sbus/char/sunserial.c Wed Apr 23 19:01:21 1997 +++ linux/drivers/sbus/char/sunserial.c Sun Apr 27 15:08:01 1997 @@ -1,4 +1,4 @@ -/* $Id: sunserial.c,v 1.38 1997/04/14 17:05:00 jj Exp $ +/* $Id: sunserial.c,v 1.39 1997/04/23 07:45:26 ecd Exp $ * serial.c: Serial port driver for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -866,10 +866,10 @@ i = cflag & CBAUD; if (cflag & CBAUDEX) { i &= ~CBAUDEX; - if (i != 1) + if (i != 5) info->tty->termios->c_cflag &= ~CBAUDEX; else - i += 15; + i = 16; } if (i == 15) { if ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_HI) @@ -1857,7 +1857,7 @@ static void show_serial_version(void) { - char *revision = "$Revision: 1.38 $"; + char *revision = "$Revision: 1.39 $"; char *version, *p; version = strchr(revision, ' '); diff -u --recursive --new-file v2.1.36/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- v2.1.36/linux/fs/binfmt_elf.c Wed Apr 23 19:01:22 1997 +++ linux/fs/binfmt_elf.c Sun Apr 27 18:13:35 1997 @@ -210,14 +210,16 @@ /* Now read in all of the header information */ - if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE) + if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE) { return ~0UL; + } elf_phdata = (struct elf_phdr *) kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL); - if (!elf_phdata) + if (!elf_phdata) { return ~0UL; + } /* * If the size of this structure has changed, then punt, since @@ -278,6 +280,7 @@ /* Real error */ sys_close(elf_exec_fileno); kfree(elf_phdata); +printk("%d", error); return ~0UL; } @@ -359,7 +362,9 @@ interp_ex->a_bss, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0); - if (retval < 0) return ~0UL; + if (retval < 0) { + return ~0UL; + } return elf_entry; } diff -u --recursive --new-file v2.1.36/linux/fs/dcache.c linux/fs/dcache.c --- v2.1.36/linux/fs/dcache.c Wed Apr 23 19:01:22 1997 +++ linux/fs/dcache.c Wed Apr 23 21:06:52 1997 @@ -153,17 +153,24 @@ /* * 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 dir_cache_entry ** hash) +static inline struct dir_cache_entry * find_entry(struct inode * dir, const char * name, unsigned char len, struct dir_cache_entry ** hash) { struct dir_cache_entry *de; - for(de = *hash; de; de = de->next) + de = *hash; + goto inside; + for (;;) { + de = de->next; +inside: + if (!de) + break; 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; + } return de; } @@ -195,7 +202,7 @@ struct dir_cache_entry *de; spin_lock(&dcache_lock); - de = find_entry(dir, name, len, hash); + de = find_entry(dir, name, (unsigned char) len, hash); if(de) { *ino = de->ino; move_to_level2(de, hash); @@ -213,7 +220,7 @@ struct dir_cache_entry *de; spin_lock(&dcache_lock); - de = find_entry(dir, name, len, hash); + de = find_entry(dir, name, (unsigned char) len, hash); if (de) { de->ino = ino; update_lru(de); diff -u --recursive --new-file v2.1.36/linux/fs/dquot.c linux/fs/dquot.c --- v2.1.36/linux/fs/dquot.c Sun Jan 26 02:07:30 1997 +++ linux/fs/dquot.c Sun Apr 27 15:08:01 1997 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -989,7 +990,7 @@ } } else error = -EIO; - filp->f_count--; + put_filp(filp); } else error = -EMFILE; iput(inode); diff -u --recursive --new-file v2.1.36/linux/fs/exec.c linux/fs/exec.c --- v2.1.36/linux/fs/exec.c Wed Apr 23 19:01:22 1997 +++ linux/fs/exec.c Sun Apr 27 18:32:17 1997 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -148,7 +148,7 @@ if (f->f_op->open) { int error = f->f_op->open(inode,f); if (error) { - f->f_count--; + put_filp(f); put_unused_fd(fd); return error; } @@ -384,7 +384,7 @@ * (the oom is wrong there, too, IMHO) */ if (current->mm->count > 1) { - struct mm_struct *mm = kmalloc(sizeof(*mm), GFP_KERNEL); + struct mm_struct *mm = kmem_cache_alloc(mm_cachep, SLAB_KERNEL); if (!mm) { /* this is wrong, I think. */ oom(current); @@ -394,8 +394,7 @@ init_new_context(mm); mm->def_flags = 0; /* should future lockings be kept? */ mm->count = 1; - mm->mmap = NULL; - mm->mmap_avl = NULL; + mm->mmap = mm->mmap_cache = NULL; mm->total_vm = 0; mm->rss = 0; current->mm->count--; diff -u --recursive --new-file v2.1.36/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c --- v2.1.36/linux/fs/ext2/balloc.c Thu Nov 14 00:27:37 1996 +++ linux/fs/ext2/balloc.c Sat Apr 26 12:35:58 1997 @@ -177,6 +177,7 @@ unsigned long bit; unsigned long i; int bitmap_nr; + unsigned long overflow; struct super_block * sb; struct ext2_group_desc * gdp; struct ext2_super_block * es; @@ -199,14 +200,20 @@ ext2_debug ("freeing block %lu\n", block); +do_more: + overflow = 0; block_group = (block - le32_to_cpu(es->s_first_data_block)) / EXT2_BLOCKS_PER_GROUP(sb); - bit = (block - le32_to_cpu(es->s_first_data_block)) % EXT2_BLOCKS_PER_GROUP(sb); - if (bit + count > EXT2_BLOCKS_PER_GROUP(sb)) - ext2_panic (sb, "ext2_free_blocks", - "Freeing blocks across group boundary - " - "Block = %lu, count = %lu", - block, count); + bit = (block - le32_to_cpu(es->s_first_data_block)) % + EXT2_BLOCKS_PER_GROUP(sb); + /* + * Check to see if we are freeing blocks across a group + * boundary. + */ + if (bit + count > EXT2_BLOCKS_PER_GROUP(sb)) { + overflow = bit + count - EXT2_BLOCKS_PER_GROUP(sb); + count -= overflow; + } bitmap_nr = load_block_bitmap (sb, block_group); bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr]; gdp = get_group_desc (sb, block_group, &bh2); @@ -246,6 +253,11 @@ ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } + if (overflow) { + block += count; + count = overflow; + goto do_more; + } sb->s_dirt = 1; unlock_super (sb); return; @@ -546,6 +558,19 @@ EXT2_BLOCKS_PER_GROUP(sb), map); } +static int test_root(int a, int b) +{ + if (a == 0) + return 1; + while (1) { + if (a == 1) + return 1; + if (a % b) + return 0; + a = a / b; + } +} + void ext2_check_blocks_bitmap (struct super_block * sb) { struct buffer_head * bh; @@ -569,15 +594,21 @@ bitmap_nr = load_block_bitmap (sb, i); bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr]; - if (!ext2_test_bit (0, bh->b_data)) - ext2_error (sb, "ext2_check_blocks_bitmap", - "Superblock in group %d is marked free", i); - - for (j = 0; j < desc_blocks; j++) - if (!ext2_test_bit (j + 1, bh->b_data)) + if (!(sb->u.ext2_sb.s_feature_ro_compat & + EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) || + (test_root(i, 3) || test_root(i, 5) || test_root(i, 7))) { + if (!ext2_test_bit (0, bh->b_data)) ext2_error (sb, "ext2_check_blocks_bitmap", + "Superblock in group %d " + "is marked free", i); + + for (j = 0; j < desc_blocks; j++) + if (!ext2_test_bit (j + 1, bh->b_data)) + ext2_error (sb, + "ext2_check_blocks_bitmap", "Descriptor block #%d in group " "%d is marked free", j, i); + } if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap), sb, bh->b_data)) ext2_error (sb, "ext2_check_blocks_bitmap", diff -u --recursive --new-file v2.1.36/linux/fs/ext2/inode.c linux/fs/ext2/inode.c --- v2.1.36/linux/fs/ext2/inode.c Sun Dec 22 06:16:53 1996 +++ linux/fs/ext2/inode.c Sat Apr 26 12:35:58 1997 @@ -503,12 +503,23 @@ inode->i_op = &blkdev_inode_operations; else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); - if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) + inode->i_attr_flags = 0; + if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) { + inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; inode->i_flags |= MS_SYNCHRONOUS; - if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL) + } + if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL) { + inode->i_attr_flags |= ATTR_FLAG_APPEND; inode->i_flags |= S_APPEND; - if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL) + } + if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL) { + inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE; inode->i_flags |= S_IMMUTABLE; + } + if (inode->u.ext2_i.i_flags & EXT2_NOATIME_FL) { + inode->i_attr_flags |= ATTR_FLAG_NOATIME; + inode->i_flags |= MS_NOATIME; + } } static int ext2_update_inode(struct inode * inode, int do_sync) @@ -597,11 +608,71 @@ void ext2_write_inode (struct inode * inode) { +#if 0 + printk("ext2_write(%04x:%06d)...", inode->i_dev, inode->i_ino); +#endif ext2_update_inode (inode, 0); } int ext2_sync_inode (struct inode *inode) { +#if 0 + printk("ext2_sync(%04x:%06d)...", inode->i_dev, inode->i_ino); +#endif return ext2_update_inode (inode, 1); +} + +int ext2_notify_change(struct inode *inode, struct iattr *iattr) +{ + int retval; + unsigned int flags; + + if ((iattr->ia_attr_flags & + (ATTR_FLAG_APPEND | ATTR_FLAG_IMMUTABLE)) ^ + (inode->u.ext2_i.i_flags & + (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL))) { + if (!fsuser() || securelevel > 0) + return -EPERM; + } else + if ((current->fsuid != inode->i_uid) && !fsuser()) + return -EPERM; + + if ((retval = inode_change_ok(inode, iattr)) != 0) + return retval; + + inode_setattr(inode, iattr); + + flags = iattr->ia_attr_flags; + if (flags & ATTR_FLAG_SYNCRONOUS) { + inode->i_flags |= MS_SYNCHRONOUS; + inode->u.ext2_i.i_flags = EXT2_SYNC_FL; + } else { + inode->i_flags &= ~MS_SYNCHRONOUS; + inode->u.ext2_i.i_flags &= ~EXT2_SYNC_FL; + } + if (flags & ATTR_FLAG_NOATIME) { + inode->i_flags |= MS_NOATIME; + inode->u.ext2_i.i_flags = EXT2_NOATIME_FL; + } else { + inode->i_flags &= ~MS_NOATIME; + inode->u.ext2_i.i_flags &= ~EXT2_NOATIME_FL; + } + if (flags & ATTR_FLAG_APPEND) { + inode->i_flags |= S_APPEND; + inode->u.ext2_i.i_flags = EXT2_APPEND_FL; + } else { + inode->i_flags &= ~S_APPEND; + inode->u.ext2_i.i_flags &= ~EXT2_APPEND_FL; + } + if (flags & ATTR_FLAG_IMMUTABLE) { + inode->i_flags |= S_IMMUTABLE; + inode->u.ext2_i.i_flags = EXT2_IMMUTABLE_FL; + } else { + inode->i_flags &= ~S_IMMUTABLE; + inode->u.ext2_i.i_flags &= ~EXT2_IMMUTABLE_FL; + } + inode->i_dirt = 1; + + return 0; } diff -u --recursive --new-file v2.1.36/linux/fs/ext2/ioctl.c linux/fs/ext2/ioctl.c --- v2.1.36/linux/fs/ext2/ioctl.c Tue Dec 31 11:19:32 1996 +++ linux/fs/ext2/ioctl.c Sat Apr 26 12:35:58 1997 @@ -45,6 +45,10 @@ if (IS_RDONLY(inode)) return -EROFS; inode->u.ext2_i.i_flags = flags; + if (flags & EXT2_SYNC_FL) + inode->i_flags |= MS_SYNCHRONOUS; + else + inode->i_flags &= ~MS_SYNCHRONOUS; if (flags & EXT2_APPEND_FL) inode->i_flags |= S_APPEND; else @@ -53,6 +57,10 @@ inode->i_flags |= S_IMMUTABLE; else inode->i_flags &= ~S_IMMUTABLE; + if (flags & EXT2_NOATIME_FL) + inode->i_flags |= MS_NOATIME; + else + inode->i_flags &= ~MS_NOATIME; inode->i_ctime = CURRENT_TIME; inode->i_dirt = 1; return 0; diff -u --recursive --new-file v2.1.36/linux/fs/ext2/namei.c linux/fs/ext2/namei.c --- v2.1.36/linux/fs/ext2/namei.c Sat Nov 30 02:24:01 1996 +++ linux/fs/ext2/namei.c Sun Apr 27 15:08:01 1997 @@ -583,7 +583,7 @@ offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len); de = (struct ext2_dir_entry *) ((char *) de1 + le16_to_cpu(de1->rec_len)); while (offset < inode->i_size ) { - if ((void *) de >= (void *) (bh->b_data + sb->s_blocksize)) { + if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) { brelse (bh); bh = ext2_bread (inode, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, &err); if (!bh) { diff -u --recursive --new-file v2.1.36/linux/fs/ext2/super.c linux/fs/ext2/super.c --- v2.1.36/linux/fs/ext2/super.c Wed Apr 23 19:01:22 1997 +++ linux/fs/ext2/super.c Sat Apr 26 12:35:58 1997 @@ -508,6 +508,9 @@ goto failed_mount; } } + sb->u.ext2_sb.s_feature_compat = es->s_feature_compat; + sb->u.ext2_sb.s_feature_incompat = es->s_feature_incompat; + sb->u.ext2_sb.s_feature_ro_compat = es->s_feature_ro_compat; sb->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE << (__s32) le32_to_cpu(es->s_log_frag_size); if (sb->u.ext2_sb.s_frag_size) diff -u --recursive --new-file v2.1.36/linux/fs/fcntl.c linux/fs/fcntl.c --- v2.1.36/linux/fs/fcntl.c Sun Jan 26 02:07:44 1997 +++ linux/fs/fcntl.c Sun Apr 27 15:08:01 1997 @@ -163,6 +163,7 @@ if (current->pgrp == -arg || current->pid == arg) goto fasync_ok; + read_lock(&tasklist_lock); for_each_task(p) { if ((p->pid == arg) || (p->pid == -arg) || (p->pgrp == -arg)) { @@ -171,11 +172,14 @@ if ((p->session != current->session) && (p->uid != current->uid) && (p->euid != current->euid) && - !suser()) + !suser()) { + read_unlock(&tasklist_lock); goto out; + } break; } } + read_unlock(&tasklist_lock); err = -EINVAL; if ((task_found == 0) && !suser()) break; diff -u --recursive --new-file v2.1.36/linux/fs/file_table.c linux/fs/file_table.c --- v2.1.36/linux/fs/file_table.c Sat Aug 3 00:43:18 1996 +++ linux/fs/file_table.c Sun Apr 27 15:08:01 1997 @@ -2,143 +2,104 @@ * linux/fs/file_table.c * * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */ #include +#include +#include #include +#include #include #include +#include -/* - * first_file points to a doubly linked list of all file structures in - * the system. - * nr_files holds the length of this list. - */ -struct file * first_file = NULL; +/* SLAB cache for filp's. */ +static kmem_cache_t *filp_cache; + +/* sysctl tunables... */ int nr_files = 0; int max_files = NR_FILE; -/* - * Insert a new file structure at the head of the list of available ones. - */ -static inline void insert_file_free(struct file *file) -{ - struct file *next, *prev; +/* Free list management, if you are here you must have f_count == 0 */ +static struct file * free_filps = NULL; - next = first_file; - first_file = file; - file->f_count = 0; - prev = next->f_prev; - file->f_next = next; - next->f_prev = file; - file->f_prev = prev; - prev->f_next = file; -} - -/* - * Remove a file structure from the list of available ones. - */ -static inline void remove_file_free(struct file *file) +void insert_file_free(struct file *file) { - struct file *next, *prev; - - next = file->f_next; - prev = file->f_prev; - file->f_next = file->f_prev = NULL; - if (first_file == file) - first_file = next; - next->f_prev = prev; - prev->f_next = next; + if((file->f_next = free_filps) != NULL) + free_filps->f_pprev = &file->f_next; + free_filps = file; + file->f_pprev = &free_filps; } -/* - * Insert a file structure at the end of the list of available ones. - */ -static inline void put_last_free(struct file *file) +/* The list of in-use filp's must be exported (ugh...) */ +struct file *inuse_filps = NULL; + +static inline void put_inuse(struct file *file) { - struct file *next, *prev; + if((file->f_next = inuse_filps) != NULL) + inuse_filps->f_pprev = &file->f_next; + inuse_filps = file; + file->f_pprev = &inuse_filps; +} - next = first_file; - file->f_next = next; - prev = next->f_prev; - next->f_prev = file; - file->f_prev = prev; - prev->f_next = file; -} - -/* - * Allocate a new memory page for file structures and - * insert the new structures into the global list. - * Returns 0, if there is no more memory, 1 otherwise. - */ +/* Get more free filp's. */ static int grow_files(void) { - struct file * file; - int i; - - /* - * We don't have to clear the page because we only look into - * f_count, f_prev and f_next and they get initialized in - * insert_file_free. The rest of the file structure is cleared - * by get_empty_filp before it is returned. - */ - file = (struct file *) __get_free_page(GFP_KERNEL); - - if (!file) - return 0; - - nr_files += i = PAGE_SIZE/sizeof(struct file); - - if (!first_file) - file->f_count = 0, - file->f_next = file->f_prev = first_file = file++, - i--; + int i = 16; - for (; i ; i--) - insert_file_free(file++); + while(i--) { + struct file * file = kmem_cache_alloc(filp_cache, SLAB_KERNEL); + if(!file) { + if(i == 15) + return 0; + goto got_some; + } + insert_file_free(file); + nr_files++; + } +got_some: return 1; } -unsigned long file_table_init(unsigned long start, unsigned long end) +void file_table_init(void) { - return start; + filp_cache = kmem_cache_create("filp", sizeof(struct file), + sizeof(unsigned long) * 8, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if(!filp_cache) + panic("VFS: Cannot alloc filp SLAB cache."); } -/* - * Find an unused file structure and return a pointer to it. +/* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or * we run out of memory. */ struct file * get_empty_filp(void) { - int i; - int max = max_files; struct file * f; - /* - * Reserve a few files for the super-user.. - */ - if (current->euid) - max -= 10; - - /* if the return is taken, we are in deep trouble */ - if (!first_file && !grow_files()) - return NULL; - - do { - for (f = first_file, i=0; i < nr_files; i++, f = f->f_next) - if (!f->f_count) { - remove_file_free(f); - memset(f,0,sizeof(*f)); - put_last_free(f); - f->f_count = 1; - f->f_version = ++event; - return f; - } - } while (nr_files < max && grow_files()); +again: + if((f = free_filps) != NULL) { + remove_filp(f); + memset(f, 0, sizeof(*f)); + f->f_count = 1; + f->f_version = ++event; + put_inuse(f); + } else { + int max = max_files; + + /* Reserve a few files for the super-user.. */ + if (current->euid) + max -= 10; - return NULL; + if (nr_files < max && grow_files()) + goto again; + + /* Big problems... */ + } + return f; } #ifdef CONFIG_QUOTA @@ -146,10 +107,9 @@ void add_dquot_ref(kdev_t dev, short type) { struct file *filp; - int cnt; - for (filp = first_file, cnt = 0; cnt < nr_files; cnt++, filp = filp->f_next) { - if (!filp->f_count || !filp->f_inode || filp->f_inode->i_dev != dev) + for (filp = inuse_filps; filp; filp = filp->f_next) { + if (!filp->f_inode || filp->f_inode->i_dev != dev) continue; if (filp->f_mode & FMODE_WRITE && filp->f_inode->i_sb->dq_op) { filp->f_inode->i_sb->dq_op->initialize(filp->f_inode, type); @@ -161,10 +121,9 @@ void reset_dquot_ptrs(kdev_t dev, short type) { struct file *filp; - int cnt; - for (filp = first_file, cnt = 0; cnt < nr_files; cnt++, filp = filp->f_next) { - if (!filp->f_count || !filp->f_inode || filp->f_inode->i_dev != dev) + for (filp = inuse_filps; filp; filp = filp->f_next) { + if (!filp->f_inode || filp->f_inode->i_dev != dev) continue; if (IS_WRITABLE(filp->f_inode)) { filp->f_inode->i_dquot[type] = NODQUOT; diff -u --recursive --new-file v2.1.36/linux/fs/inode.c linux/fs/inode.c --- v2.1.36/linux/fs/inode.c Wed Apr 23 19:01:24 1997 +++ linux/fs/inode.c Sun Apr 27 15:08:01 1997 @@ -232,12 +232,10 @@ int fs_may_remount_ro(kdev_t dev) { struct file * file; - int i; /* Check that no files are currently opened for writing. */ - for (file = first_file, i=0; if_next) { - if (!file->f_count || !file->f_inode || - file->f_inode->i_dev != dev) + for (file = inuse_filps; file; file = file->f_next) { + if (!file->f_inode || file->f_inode->i_dev != dev) continue; if (S_ISREG(file->f_inode->i_mode) && (file->f_mode & 2)) return 0; @@ -288,7 +286,7 @@ ((attr->ia_valid & ATTR_GID) && (!in_group_p(attr->ia_gid) && - (attr->ia_gid != inode->i_gid))) || + (attr->ia_gid != inode->i_gid)) && not_fsuser) || ((attr->ia_valid & (ATTR_ATIME_SET | ATTR_MTIME_SET)) && (fsuid != iuid) && not_fsuser)) @@ -325,6 +323,8 @@ if (!fsuser() && !in_group_p(inode->i_gid)) inode->i_mode &= ~S_ISGID; } + if (attr->ia_valid & ATTR_ATTR_FLAG) + inode->i_attr_flags = attr->ia_attr_flags; inode->i_dirt = 1; } diff -u --recursive --new-file v2.1.36/linux/fs/lockd/svcsubs.c linux/fs/lockd/svcsubs.c --- v2.1.36/linux/fs/lockd/svcsubs.c Mon Apr 7 11:35:30 1997 +++ linux/fs/lockd/svcsubs.c Sun Apr 27 15:08:02 1997 @@ -228,12 +228,12 @@ down(&nlm_file_sema); /* If there are no more locks etc, delete the file */ - if (--(file->f_count) == 0 - && !nlm_inspect_file(NULL, file, NLM_ACT_CHECK)) - nlm_delete_file(file); + if(--file->f_count == 0) { + if(!nlm_inspect_file(NULL, file, NLM_ACT_CHECK)) + nlm_delete_file(file); + } up(&nlm_file_sema); - return; } /* diff -u --recursive --new-file v2.1.36/linux/fs/msdos/msdosfs_syms.c linux/fs/msdos/msdosfs_syms.c --- v2.1.36/linux/fs/msdos/msdosfs_syms.c Wed Apr 23 19:01:26 1997 +++ linux/fs/msdos/msdosfs_syms.c Fri Apr 25 15:25:56 1997 @@ -30,7 +30,7 @@ EXPORT_SYMBOL(msdos_put_super); -static struct file_system_type msdos_fs_type = { +struct file_system_type msdos_fs_type = { msdos_read_super, "msdos", 1, NULL }; diff -u --recursive --new-file v2.1.36/linux/fs/namei.c linux/fs/namei.c --- v2.1.36/linux/fs/namei.c Thu Mar 27 14:40:06 1997 +++ linux/fs/namei.c Sun Apr 27 18:32:50 1997 @@ -124,24 +124,16 @@ * put_write_access() releases this write permission. * This is used for regular files. * We cannot support write (and maybe mmap read-write shared) accesses and - * MAP_DENYWRITE mmappings simultaneously. + * MAP_DENYWRITE mmappings simultaneously. The i_writecount field of an inode + * can have the following values: + * 0: no writers, no VM_DENYWRITE mappings + * < 0: (-i_writecount) vm_area_structs with VM_DENYWRITE set exist + * > 0: (i_writecount) users are writing to the file. */ int get_write_access(struct inode * inode) { - struct task_struct * p; - - if ((inode->i_count > 1) && S_ISREG(inode->i_mode)) /* shortcut */ - for_each_task(p) { - struct vm_area_struct * mpnt; - if (!p->mm) - continue; - for(mpnt = p->mm->mmap; mpnt; mpnt = mpnt->vm_next) { - if (inode != mpnt->vm_inode) - continue; - if (mpnt->vm_flags & VM_DENYWRITE) - return -ETXTBSY; - } - } + if (inode->i_writecount < 0) + return -ETXTBSY; inode->i_writecount++; return 0; } diff -u --recursive --new-file v2.1.36/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.1.36/linux/fs/ncpfs/inode.c Wed Apr 23 19:01:26 1997 +++ linux/fs/ncpfs/inode.c Sun Apr 27 15:08:02 1997 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -177,7 +178,7 @@ printk("ncp_read_super: could not alloc ncp_server\n"); return NULL; } - ncp_filp->f_count += 1; + ncp_filp->f_count++; lock_super(sb); @@ -256,7 +257,7 @@ ncp_unlock_server(server); ncp_kfree_s(server->packet, server->packet_size); fail: - ncp_filp->f_count -= 1; + put_filp(ncp_filp); ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); return NULL; } diff -u --recursive --new-file v2.1.36/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c --- v2.1.36/linux/fs/nfsd/vfs.c Wed Apr 23 19:01:27 1997 +++ linux/fs/nfsd/vfs.c Sun Apr 27 15:08:02 1997 @@ -285,6 +285,10 @@ if (err) { if (wflag) put_write_access(inode); + + /* I nearly added put_filp() call here, but this filp + * is really on callers stack frame. -DaveM + */ filp->f_count--; return nfserrno(-err); } diff -u --recursive --new-file v2.1.36/linux/fs/open.c linux/fs/open.c --- v2.1.36/linux/fs/open.c Fri Apr 4 08:52:24 1997 +++ linux/fs/open.c Sun Apr 27 15:08:02 1997 @@ -605,7 +605,7 @@ cleanup_inode: iput(inode); cleanup_file: - f->f_count--; + put_filp(f); return error; } diff -u --recursive --new-file v2.1.36/linux/fs/pipe.c linux/fs/pipe.c --- v2.1.36/linux/fs/pipe.c Fri Apr 4 08:52:24 1997 +++ linux/fs/pipe.c Sun Apr 27 15:08:02 1997 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -74,7 +75,10 @@ PIPE_LOCK(*inode)--; wake_up_interruptible(&PIPE_WAIT(*inode)); if (read) { - inode->i_atime = CURRENT_TIME; + if (DO_UPDATE_ATIME(inode)) { + inode->i_atime = CURRENT_TIME; + inode->i_dirt = 1; + } return read; } if (PIPE_WRITERS(*inode)) @@ -128,6 +132,7 @@ free = 1; } inode->i_ctime = inode->i_mtime = CURRENT_TIME; + inode->i_dirt = 1; return written; } @@ -440,9 +445,9 @@ inode->i_count--; iput(inode); close_f12: - f2->f_count--; + put_filp(f2); close_f1: - f1->f_count--; + put_filp(f1); no_files: return error; } diff -u --recursive --new-file v2.1.36/linux/fs/proc/array.c linux/fs/proc/array.c --- v2.1.36/linux/fs/proc/array.c Mon Apr 14 16:28:18 1997 +++ linux/fs/proc/array.c Mon Apr 28 20:58:40 1997 @@ -154,9 +154,7 @@ return read; } -#ifdef __SMP__ -extern int setup_profiling_timer (unsigned int multiplier); /* * Writing to /proc/profile resets the counters @@ -168,6 +166,8 @@ const char * buf, unsigned long count) { int i=prof_len; +#ifdef __SMP__ + extern int setup_profiling_timer (unsigned int multiplier); if (count==sizeof(int)) { unsigned int multiplier; @@ -178,14 +178,12 @@ if (setup_profiling_timer(multiplier)) return -EINVAL; } +#endif while (i--) prof_buffer[i]=0UL; return count; } -#else -#define write_profile NULL -#endif static struct file_operations proc_profile_operations = { NULL, /* lseek */ @@ -344,18 +342,6 @@ return sprintf(buffer, "%s\n", saved_command_line); } -static struct task_struct ** get_task(pid_t pid) -{ - struct task_struct ** p; - - p = task; - while (++p < task+NR_TASKS) { - if (*p && (*p)->pid == pid) - return p; - } - return NULL; -} - static unsigned long get_phys_addr(struct task_struct * p, unsigned long ptr) { pgd_t *page_dir; @@ -386,7 +372,7 @@ return pte_page(pte) + (ptr & ~PAGE_MASK); } -static int get_array(struct task_struct ** p, unsigned long start, unsigned long end, char * buffer) +static int get_array(struct task_struct *p, unsigned long start, unsigned long end, char * buffer) { unsigned long addr; int size = 0, result = 0; @@ -395,7 +381,7 @@ if (start >= end) return result; for (;;) { - addr = get_phys_addr(*p, start); + addr = get_phys_addr(p, start); if (!addr) return result; do { @@ -417,20 +403,20 @@ static int get_env(int pid, char * buffer) { - struct task_struct ** p = get_task(pid); + struct task_struct *p = find_task_by_pid(pid); - if (!p || !*p || !(*p)->mm) + if (!p || !p->mm) return 0; - return get_array(p, (*p)->mm->env_start, (*p)->mm->env_end, buffer); + return get_array(p, p->mm->env_start, p->mm->env_end, buffer); } static int get_arg(int pid, char * buffer) { - struct task_struct ** p = get_task(pid); + struct task_struct *p = find_task_by_pid(pid); - if (!p || !*p || !(*p)->mm) + if (!p || !p->mm) return 0; - return get_array(p, (*p)->mm->arg_start, (*p)->mm->arg_end, buffer); + return get_array(p, p->mm->arg_start, p->mm->arg_end, buffer); } static unsigned long get_wchan(struct task_struct *p) @@ -443,7 +429,7 @@ unsigned long stack_page; int count = 0; - stack_page = p->kernel_stack_page; + stack_page = 4096 + (unsigned long)p; if (!stack_page) return 0; ebp = p->tss.ebp; @@ -507,8 +493,8 @@ } #if defined(__i386__) -# define KSTK_EIP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1019]) -# define KSTK_ESP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1022]) +# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) +# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) #elif defined(__alpha__) /* * See arch/alpha/kernel/ptrace.c for details. @@ -681,9 +667,9 @@ static int get_status(int pid, char * buffer) { char * orig = buffer; - struct task_struct ** p = get_task(pid), *tsk; + struct task_struct *tsk = find_task_by_pid(pid); - if (!p || (tsk = *p) == NULL) + if (!tsk) return 0; buffer = task_name(tsk, buffer); buffer = task_state(tsk, buffer); @@ -694,14 +680,14 @@ static int get_stat(int pid, char * buffer) { - struct task_struct ** p = get_task(pid), *tsk; + struct task_struct *tsk = find_task_by_pid(pid); unsigned long sigignore=0, sigcatch=0, wchan; unsigned long vsize, eip, esp; long priority, nice; int i,tty_pgrp; char state; - if (!p || (tsk = *p) == NULL) + if (!tsk) return 0; if (tsk->state < 0 || tsk->state > 5) state = '.'; @@ -714,10 +700,8 @@ vsize += vma->vm_end - vma->vm_start; vma = vma->vm_next; } - if (tsk->kernel_stack_page) { - eip = KSTK_EIP(tsk); - esp = KSTK_ESP(tsk); - } + eip = KSTK_EIP(tsk); + esp = KSTK_ESP(tsk); } wchan = get_wchan(tsk); if (tsk->sig) { @@ -864,10 +848,10 @@ static int get_statm(int pid, char * buffer) { - struct task_struct ** p = get_task(pid), *tsk; + struct task_struct *tsk = find_task_by_pid(pid); int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0; - if (!p || (tsk = *p) == NULL) + if (!tsk) return 0; if (tsk->mm && tsk->mm != &init_mm) { struct vm_area_struct * vma = tsk->mm->mmap; @@ -932,17 +916,17 @@ static long read_maps (int pid, struct file * file, char * buf, unsigned long count) { - struct task_struct ** p = get_task(pid); + struct task_struct *p = find_task_by_pid(pid); char * destptr; loff_t lineno; int column; struct vm_area_struct * map; int i; - if (!p || !*p) + if (!p) return -EINVAL; - if (!(*p)->mm || (*p)->mm == &init_mm || count == 0) + if (!p->mm || p->mm == &init_mm || count == 0) return 0; /* decode f_pos */ @@ -950,7 +934,7 @@ column = file->f_pos & (MAPS_LINE_LENGTH-1); /* quickly go to line lineno */ - for (map = (*p)->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) + for (map = p->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) continue; destptr = buf; @@ -1011,7 +995,7 @@ /* By writing to user space, we might have slept. * Stop the loop, to avoid a race condition. */ - if (*p != current) + if (p != current) break; } diff -u --recursive --new-file v2.1.36/linux/fs/proc/base.c linux/fs/proc/base.c --- v2.1.36/linux/fs/proc/base.c Sun Jan 26 02:07:45 1997 +++ linux/fs/proc/base.c Sun Apr 27 15:08:02 1997 @@ -52,17 +52,14 @@ static void proc_pid_fill_inode(struct inode * inode) { - struct task_struct * p; + struct task_struct *p; int pid = inode->i_ino >> 16; int ino = inode->i_ino & 0xffff; - for_each_task(p) { - if (p->pid == pid) { - if (p->dumpable || ino == PROC_PID_INO) { - inode->i_uid = p->euid; - inode->i_gid = p->gid; - } - return; + if ((p = find_task_by_pid(pid)) != NULL) { + if (p->dumpable || ino == PROC_PID_INO) { + inode->i_uid = p->euid; + inode->i_gid = p->gid; } } } diff -u --recursive --new-file v2.1.36/linux/fs/proc/fd.c linux/fs/proc/fd.c --- v2.1.36/linux/fs/proc/fd.c Thu Mar 27 14:40:06 1997 +++ linux/fs/proc/fd.c Sun Apr 27 15:08:02 1997 @@ -58,7 +58,6 @@ unsigned int ino, pid, fd, c; struct task_struct * p; struct super_block * sb; - int i; *result = NULL; ino = dir->i_ino; @@ -100,10 +99,8 @@ break; } } - for (i = 0 ; i < NR_TASKS ; i++) - if ((p = task[i]) && p->pid == pid) - break; - if (!pid || i >= NR_TASKS) + p = find_task_by_pid(pid); + if (!pid || !p) return -ENOENT; /* @@ -112,8 +109,11 @@ * is NULL */ - if (fd >= NR_OPEN || !p->files || !p->files->fd[fd] || !p->files->fd[fd]->f_inode) - return -ENOENT; + if (fd >= NR_OPEN || + !p->files || + !p->files->fd[fd] || + !p->files->fd[fd]->f_inode) + return -ENOENT; ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd; @@ -128,8 +128,7 @@ void * dirent, filldir_t filldir) { char buf[NUMBUF]; - int task_nr; - struct task_struct * p; + struct task_struct * p, **tarrayp; unsigned int fd, pid, ino; unsigned long i,j; @@ -149,13 +148,10 @@ return 0; } - task_nr = 1; - for (;;) { - if ((p = task[task_nr]) && p->pid == pid) - break; - if (++task_nr >= NR_TASKS) - return 0; - } + p = find_task_by_pid(pid); + if(!p) + return 0; + tarrayp = p->tarray_ptr; for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) { if (!p->files) @@ -176,7 +172,7 @@ break; /* filldir() might have slept, so we must re-validate "p" */ - if (p != task[task_nr] || p->pid != pid) + if (p != *tarrayp || p->pid != pid) break; } return 0; diff -u --recursive --new-file v2.1.36/linux/fs/proc/inode.c linux/fs/proc/inode.c --- v2.1.36/linux/fs/proc/inode.c Mon Mar 17 14:54:30 1997 +++ linux/fs/proc/inode.c Sun Apr 27 15:08:02 1997 @@ -81,7 +81,6 @@ struct inode * proc_get_inode(struct super_block * s, int ino, struct proc_dir_entry * de) { struct inode * inode = iget(s, ino); - struct task_struct *p; #ifdef CONFIG_SUN_OPENPROMFS_MODULE if ((inode->i_ino >= PROC_OPENPROM_FIRST) @@ -111,9 +110,14 @@ * Fixup the root inode's nlink value */ if (inode->i_ino == PROC_ROOT_INO) { - for_each_task(p) - if (p && p->pid) + struct task_struct *p; + + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pid) inode->i_nlink++; + } + read_unlock(&tasklist_lock); } return inode; } @@ -155,7 +159,6 @@ { unsigned long ino, pid; struct task_struct * p; - int i; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_blocks = 0; @@ -170,13 +173,8 @@ inode->i_nlink = 1; inode->i_size = 0; pid = ino >> 16; - if (!pid) - return; - p = task[0]; - for (i = 0; i < NR_TASKS ; i++) - if ((p = task[i]) && (p->pid == pid)) - break; - if (!p || i >= NR_TASKS) + + if (!pid || ((p = find_task_by_pid(pid)) == NULL)) return; ino &= 0x0000ffff; @@ -198,7 +196,6 @@ inode->i_mode |= S_IWUSR | S_IXUSR; return; } - return; } void proc_write_inode(struct inode * inode) diff -u --recursive --new-file v2.1.36/linux/fs/proc/link.c linux/fs/proc/link.c --- v2.1.36/linux/fs/proc/link.c Sun Jan 26 02:07:45 1997 +++ linux/fs/proc/link.c Sun Apr 27 15:08:02 1997 @@ -68,7 +68,7 @@ unsigned int pid, ino; struct task_struct * p; struct inode * new_inode; - int i, error; + int error; *res_inode = NULL; if (dir) @@ -82,10 +82,9 @@ ino = inode->i_ino; pid = ino >> 16; ino &= 0x0000ffff; - for (i = 0 ; i < NR_TASKS ; i++) - if ((p = task[i]) && p->pid == pid) - break; - if (i >= NR_TASKS) { + + p = find_task_by_pid(pid); + if (!p) { iput(inode); return -ENOENT; } diff -u --recursive --new-file v2.1.36/linux/fs/proc/mem.c linux/fs/proc/mem.c --- v2.1.36/linux/fs/proc/mem.c Mon Apr 14 16:28:18 1997 +++ linux/fs/proc/mem.c Sun Apr 27 15:08:02 1997 @@ -55,16 +55,10 @@ struct task_struct * tsk = current; if (pid != tsk->pid) { - int i; - tsk = NULL; - for (i = 1 ; i < NR_TASKS ; i++) - if (task[i] && task[i]->pid == pid) { - tsk = task[i]; - break; - } - /* - * allow accesses only under the same circumstances - * that we would allow ptrace to work + tsk = find_task_by_pid(pid); + + /* Allow accesses only under the same circumstances + * that we would allow ptrace to work. */ if (tsk) { if (!(tsk->flags & PF_PTRACED) diff -u --recursive --new-file v2.1.36/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.1.36/linux/fs/proc/root.c Wed Apr 23 19:01:27 1997 +++ linux/fs/proc/root.c Sun Apr 27 15:08:02 1997 @@ -683,16 +683,20 @@ struct inode ** result) { unsigned int pid, c; - int i, ino, retval; + int ino, retval; struct task_struct *p; dir->i_count++; if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */ dir->i_nlink = proc_root.nlink; - for_each_task(p) - if (p && p->pid) + + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pid) dir->i_nlink++; + } + read_unlock(&tasklist_lock); } retval = proc_lookup(dir, name, len, result); @@ -716,10 +720,8 @@ break; } } - for (i = 0 ; i < NR_TASKS ; i++) - if (task[i] && task[i]->pid == pid) - break; - if (!pid || i >= NR_TASKS) { + p = find_task_by_pid(pid); + if (!pid || !p) { iput(dir); return -ENOENT; } @@ -796,34 +798,40 @@ static int proc_root_readdir(struct inode * inode, struct file * filp, void * dirent, filldir_t filldir) { + struct task_struct *p; char buf[NUMBUF]; - unsigned int nr,pid; - unsigned long i,j; + unsigned int nr = filp->f_pos; - nr = filp->f_pos; if (nr < FIRST_PROCESS_ENTRY) { int error = proc_readdir(inode, filp, dirent, filldir); if (error <= 0) return error; - filp->f_pos = nr = FIRST_PROCESS_ENTRY; + filp->f_pos = FIRST_PROCESS_ENTRY; } + nr = FIRST_PROCESS_ENTRY; - for (nr -= FIRST_PROCESS_ENTRY; nr < NR_TASKS; nr++, filp->f_pos++) { - struct task_struct * p = task[nr]; + read_lock(&tasklist_lock); + for_each_task(p) { + unsigned int pid; - if (!p || !(pid = p->pid)) + if(nr++ < filp->f_pos) continue; - j = NUMBUF; - i = pid; - do { - j--; - buf[j] = '0' + (i % 10); - i /= 10; - } while (i); + if((pid = p->pid) != 0) { + unsigned long j = NUMBUF, i = pid; - if (filldir(dirent, buf+j, NUMBUF-j, filp->f_pos, (pid << 16) + PROC_PID_INO) < 0) - break; + do { + j--; + buf[j] = '0' + (i % 10); + i /= 10; + } while (i); + + if (filldir(dirent, buf+j, NUMBUF-j, + filp->f_pos, (pid << 16) + PROC_PID_INO) < 0) + break; + } + filp->f_pos++; } + read_unlock(&tasklist_lock); return 0; } diff -u --recursive --new-file v2.1.36/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.1.36/linux/fs/smbfs/inode.c Wed Apr 23 19:01:27 1997 +++ linux/fs/smbfs/inode.c Sun Apr 27 15:08:02 1997 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -242,7 +243,7 @@ printk("smb_read_super: could not alloc smb_sb_info\n"); return NULL; } - filp->f_count += 1; + filp->f_count++; lock_super(sb); @@ -319,7 +320,7 @@ smb_vfree(server->packet); server->packet = NULL; } - filp->f_count -= 1; + put_filp(filp); smb_dont_catch_keepalive(server); smb_kfree_s(SMB_SBP(sb), sizeof(struct smb_sb_info)); return NULL; diff -u --recursive --new-file v2.1.36/linux/fs/umsdos/namei.c linux/fs/umsdos/namei.c --- v2.1.36/linux/fs/umsdos/namei.c Sat Nov 30 02:24:02 1996 +++ linux/fs/umsdos/namei.c Sun Apr 27 10:48:43 1997 @@ -301,6 +301,9 @@ ,*(unsigned long *)current->kernel_stack_page \ ,__LINE__); \ } + +#undef chkstk +#define chkstk() do { } while (0) /* Rename a file (move) in the file system. diff -u --recursive --new-file v2.1.36/linux/fs/vfat/namei.c linux/fs/vfat/namei.c --- v2.1.36/linux/fs/vfat/namei.c Wed Apr 23 19:01:27 1997 +++ linux/fs/vfat/namei.c Sun Apr 27 10:49:01 1997 @@ -174,10 +174,12 @@ printk("------- vfat kstack ok in %s line %d: SL=%d\n", fname, lineno, stack_level); #endif +#if 0 if (*(unsigned long *) current->kernel_stack_page != STACK_MAGIC) { printk("******* vfat stack corruption detected in %s at line %d\n", fname, lineno); } +#endif } static int debug = 0; diff -u --recursive --new-file v2.1.36/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v2.1.36/linux/include/asm-alpha/processor.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-alpha/processor.h Sun Apr 27 15:08:02 1997 @@ -49,7 +49,7 @@ }; #define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \ - PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } + PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ 0, 0, 0, \ diff -u --recursive --new-file v2.1.36/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h --- v2.1.36/linux/include/asm-alpha/spinlock.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-alpha/spinlock.h Sun Apr 27 15:08:02 1997 @@ -39,10 +39,10 @@ #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) +#define read_lock_irqsave(lock, flags) swpipl(flags,7) +#define read_unlock_irqrestore(lock, flags) setipl(flags) +#define write_lock_irqsave(lock, flags) swpipl(flags,7) +#define write_unlock_irqrestore(lock, flags) setipl(flags) #else diff -u --recursive --new-file v2.1.36/linux/include/asm-i386/current.h linux/include/asm-i386/current.h --- v2.1.36/linux/include/asm-i386/current.h Mon Dec 30 01:58:34 1996 +++ linux/include/asm-i386/current.h Sun Apr 27 20:14:39 1997 @@ -7,6 +7,15 @@ * entire register is hard locked to contain the value of current. */ extern struct task_struct *current_set[NR_CPUS]; -#define current (current_set[smp_processor_id()]) /* Current on this processor */ + +static inline unsigned long get_esp(void) +{ + unsigned long esp; + __asm__("movl %%esp,%0":"=r" (esp)); + return esp; +} + +#define current ((struct task_struct *)(get_esp() & ~8191UL)) + #endif /* !(_I386_CURRENT_H) */ diff -u --recursive --new-file v2.1.36/linux/include/asm-i386/delay.h linux/include/asm-i386/delay.h --- v2.1.36/linux/include/asm-i386/delay.h Sun Jan 26 05:36:05 1997 +++ linux/include/asm-i386/delay.h Mon Apr 28 13:57:56 1997 @@ -36,7 +36,7 @@ __asm__("mull %0" :"=d" (usecs) #ifdef __SMP__ - :"a" (usecs),"0" (cpu_data[smp_processor_id()].udelay_val) + :"a" (usecs),"0" (cpu_data[hard_smp_processor_id()].udelay_val) #else :"a" (usecs),"0" (loops_per_sec) #endif diff -u --recursive --new-file v2.1.36/linux/include/asm-i386/hardirq.h linux/include/asm-i386/hardirq.h --- v2.1.36/linux/include/asm-i386/hardirq.h Mon Apr 14 16:28:18 1997 +++ linux/include/asm-i386/hardirq.h Sun Apr 27 19:59:03 1997 @@ -4,7 +4,7 @@ #include extern unsigned int local_irq_count[NR_CPUS]; -#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) +#define in_interrupt() (local_irq_count[hard_smp_processor_id()] != 0) #ifndef __SMP__ diff -u --recursive --new-file v2.1.36/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v2.1.36/linux/include/asm-i386/processor.h Sun Jan 26 02:07:46 1997 +++ linux/include/asm-i386/processor.h Mon Apr 28 20:49:32 1997 @@ -119,14 +119,15 @@ /* virtual 86 mode info */ struct vm86_struct * vm86_info; unsigned long screen_bitmap; - unsigned long v86flags, v86mask, v86mode; + unsigned long v86flags, v86mask, v86mode, saved_esp0; }; -#define INIT_MMAP { &init_mm, 0xC0000000, 0xFFFFF000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } +#define INIT_MMAP \ +{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ 0,0, \ - sizeof(init_kernel_stack) + (long) &init_kernel_stack, \ + sizeof(init_stack) + (long) &init_stack, \ KERNEL_DS, 0, \ 0,0,0,0,0,0, \ (long) &swapper_pg_dir - PAGE_OFFSET, \ @@ -137,7 +138,7 @@ {~0, }, /* ioperm */ \ _TSS(0), 0, 0, 0, KERNEL_DS, \ { { 0, }, }, /* 387 state */ \ - NULL, 0, 0, 0, 0 /* vm86_info */, \ + NULL, 0, 0, 0, 0, 0 /* vm86_info */, \ } #define start_thread(regs, new_eip, new_esp) do {\ @@ -164,9 +165,14 @@ } /* Allocation and freeing of basic task resources. */ -#define alloc_task_struct() kmalloc(sizeof(struct task_struct), GFP_KERNEL) -#define alloc_kernel_stack(p) __get_free_page(GFP_KERNEL) -#define free_task_struct(p) kfree(p) -#define free_kernel_stack(page) free_page((page)) +/* + * NOTE! The task struct and the stack go together + */ +#define alloc_task_struct() \ + ((struct task_struct *) __get_free_pages(GFP_KERNEL,1,0)) +#define free_task_struct(p) free_pages((unsigned long)(p),1) + +#define init_task (init_task_union.task) +#define init_stack (init_task_union.stack) #endif /* __ASM_I386_PROCESSOR_H */ diff -u --recursive --new-file v2.1.36/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h --- v2.1.36/linux/include/asm-i386/smp.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-i386/smp.h Mon Apr 28 13:46:56 1997 @@ -178,7 +178,6 @@ extern int smp_scan_config(unsigned long, unsigned long); extern unsigned long smp_alloc_memory(unsigned long mem_base); extern unsigned char *apic_reg; -extern unsigned char *kernel_stacks[NR_CPUS]; extern unsigned char boot_cpu_id; extern unsigned long cpu_present_map; extern volatile int cpu_number_map[NR_CPUS]; @@ -192,6 +191,9 @@ extern void smp_reschedule_irq(int cpl, struct pt_regs *regs); extern unsigned long ipi_count; extern void smp_invalidate_rcv(void); /* Process an NMI */ +extern void smp_local_timer_interrupt(struct pt_regs * regs); +extern void setup_APIC_clock (void); + /* * General functions that each host system must provide. @@ -228,7 +230,9 @@ * the apic we get the right answer). Hopefully other processors are more sensible 8) */ -extern __inline int smp_processor_id(void) +#define smp_processor_id() (current->processor) + +extern __inline int hard_smp_processor_id(void) { /* we don't want to mark this access volatile - bad code generation */ return GET_APIC_ID(*(unsigned long *)(apic_reg+APIC_ID)); diff -u --recursive --new-file v2.1.36/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h --- v2.1.36/linux/include/asm-i386/spinlock.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-i386/spinlock.h Wed Apr 23 20:04:56 1997 @@ -77,45 +77,21 @@ #define spin_lock(lock) \ __asm__ __volatile__( \ - "jmp 2f\n" \ - "1:\t" \ - "testb $1,%0\n\t" \ - "jne 1b\n" \ - "2:\t" \ + "\n1:\t" \ "lock ; btsl $0,%0\n\t" \ - "jc 1b" \ + "jc 2f\n" \ + ".text 2\n" \ + "2:\t" \ + "testb $1,%0\n\t" \ + "jne 2b\n\t" \ + "jmp 1b\n" \ + ".text" \ :"=m" (__dummy_lock(lock))) #define spin_unlock(lock) \ __asm__ __volatile__( \ "lock ; btrl $0,%0" \ :"=m" (__dummy_lock(lock))) - -#undef spin_lock -static inline void spin_lock(spinlock_t * lock) -{ - __label__ l1; - int stuck = 10000000; -l1: - __asm__ __volatile__( - "jmp 2f\n" - "1:\t" - "decl %1\n\t" - "je 3f\n\t" - "testb $1,%0\n\t" - "jne 1b\n" - "2:\t" - "lock ; btsl $0,%0\n\t" - "jc 1b\n" - "3:" - :"=m" (__dummy_lock(lock)), - "=r" (stuck) - :"1" (stuck)); - if (!stuck) { - printk("spinlock stuck at %p (%lx)\n",&&l1,lock->previous); - } else - lock->previous = (unsigned long) &&l1; -} #define spin_trylock(lock) (!set_bit(0,(lock))) diff -u --recursive --new-file v2.1.36/linux/include/asm-m68k/dsp56k.h linux/include/asm-m68k/dsp56k.h --- v2.1.36/linux/include/asm-m68k/dsp56k.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-m68k/dsp56k.h Sun Apr 27 15:13:50 1997 @@ -33,38 +33,3 @@ #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.36/linux/include/asm-m68k/namei.h linux/include/asm-m68k/namei.h --- v2.1.36/linux/include/asm-m68k/namei.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-m68k/namei.h Sun Apr 27 15:13:50 1997 @@ -19,24 +19,3 @@ 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.36/linux/include/asm-m68k/poll.h linux/include/asm-m68k/poll.h --- v2.1.36/linux/include/asm-m68k/poll.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-m68k/poll.h Sun Apr 27 15:13:50 1997 @@ -19,24 +19,3 @@ }; #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.36/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h --- v2.1.36/linux/include/asm-m68k/processor.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-m68k/processor.h Sun Apr 27 15:08:02 1997 @@ -44,7 +44,7 @@ unsigned char fpstate[FPSTATESIZE]; /* floating point state */ }; -#define INIT_MMAP { &init_mm, 0, 0x40000000, __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED), VM_READ | VM_WRITE | VM_EXEC } +#define INIT_MMAP { &init_mm, 0, 0x40000000, __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED), VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ sizeof(init_kernel_stack) + (long) init_kernel_stack, 0, \ diff -u --recursive --new-file v2.1.36/linux/include/asm-m68k/smp_lock.h linux/include/asm-m68k/smp_lock.h --- v2.1.36/linux/include/asm-m68k/smp_lock.h Wed Apr 23 19:01:28 1997 +++ linux/include/asm-m68k/smp_lock.h Sun Apr 27 15:13:50 1997 @@ -12,17 +12,3 @@ #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.36/linux/include/asm-m68k/softirq.h linux/include/asm-m68k/softirq.h --- v2.1.36/linux/include/asm-m68k/softirq.h Wed Apr 23 19:01:28 1997 +++ linux/include/asm-m68k/softirq.h Sun Apr 27 15:13:50 1997 @@ -60,59 +60,3 @@ #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.36/linux/include/asm-m68k/spinlock.h linux/include/asm-m68k/spinlock.h --- v2.1.36/linux/include/asm-m68k/spinlock.h Wed Apr 23 19:01:28 1997 +++ linux/include/asm-m68k/spinlock.h Sun Apr 27 15:13:50 1997 @@ -49,26 +49,3 @@ #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.36/linux/include/asm-mips/processor.h linux/include/asm-mips/processor.h --- v2.1.36/linux/include/asm-mips/processor.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-mips/processor.h Sun Apr 27 15:08:02 1997 @@ -139,7 +139,7 @@ #if !defined (__LANGUAGE_ASSEMBLY__) #define INIT_MMAP { &init_mm, KSEG0, KSEG1, PAGE_SHARED, \ - VM_READ | VM_WRITE | VM_EXEC } + VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ /* \ diff -u --recursive --new-file v2.1.36/linux/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h --- v2.1.36/linux/include/asm-mips/unistd.h Fri Apr 4 08:52:25 1997 +++ linux/include/asm-mips/unistd.h Sun Apr 27 15:08:02 1997 @@ -1149,7 +1149,7 @@ /* * Offset of the last Linux flavoured syscall */ -#define __NR_Linux_syscalls 157 +#define __NR_Linux_syscalls 158 #ifndef __LANGUAGE_ASSEMBLY__ diff -u --recursive --new-file v2.1.36/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h --- v2.1.36/linux/include/asm-ppc/processor.h Sun Jan 26 02:07:47 1997 +++ linux/include/asm-ppc/processor.h Sun Apr 27 15:08:02 1997 @@ -116,7 +116,7 @@ } #define INIT_MMAP { &init_mm, 0, 0x40000000, \ - PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } + PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); diff -u --recursive --new-file v2.1.36/linux/include/asm-sparc/asm_offsets.h linux/include/asm-sparc/asm_offsets.h --- v2.1.36/linux/include/asm-sparc/asm_offsets.h Thu Mar 27 14:40:07 1997 +++ linux/include/asm-sparc/asm_offsets.h Sun Apr 27 15:08:02 1997 @@ -64,150 +64,158 @@ #define ASIZ_task_p_ysptr 0x00000004 #define AOFF_task_p_osptr 0x000000d4 #define ASIZ_task_p_osptr 0x00000004 -#define AOFF_task_wait_chldexit 0x000000d8 +#define AOFF_task_pidhash_next 0x000000d8 +#define ASIZ_task_pidhash_next 0x00000004 +#define AOFF_task_pidhash_pprev 0x000000dc +#define ASIZ_task_pidhash_pprev 0x00000004 +#define AOFF_task_tarray_ptr 0x000000e0 +#define ASIZ_task_tarray_ptr 0x00000004 +#define AOFF_task_wait_chldexit 0x000000e4 #define ASIZ_task_wait_chldexit 0x00000004 -#define AOFF_task_uid 0x000000dc +#define AOFF_task_uid 0x000000e8 #define ASIZ_task_uid 0x00000002 -#define AOFF_task_euid 0x000000de +#define AOFF_task_euid 0x000000ea #define ASIZ_task_euid 0x00000002 -#define AOFF_task_suid 0x000000e0 +#define AOFF_task_suid 0x000000ec #define ASIZ_task_suid 0x00000002 -#define AOFF_task_fsuid 0x000000e2 +#define AOFF_task_fsuid 0x000000ee #define ASIZ_task_fsuid 0x00000002 -#define AOFF_task_gid 0x000000e4 +#define AOFF_task_gid 0x000000f0 #define ASIZ_task_gid 0x00000002 -#define AOFF_task_egid 0x000000e6 +#define AOFF_task_egid 0x000000f2 #define ASIZ_task_egid 0x00000002 -#define AOFF_task_sgid 0x000000e8 +#define AOFF_task_sgid 0x000000f4 #define ASIZ_task_sgid 0x00000002 -#define AOFF_task_fsgid 0x000000ea +#define AOFF_task_fsgid 0x000000f6 #define ASIZ_task_fsgid 0x00000002 -#define AOFF_task_timeout 0x000000ec +#define AOFF_task_timeout 0x000000f8 #define ASIZ_task_timeout 0x00000004 -#define AOFF_task_policy 0x000000f0 +#define AOFF_task_policy 0x000000fc #define ASIZ_task_policy 0x00000004 -#define AOFF_task_rt_priority 0x000000f4 +#define AOFF_task_rt_priority 0x00000100 #define ASIZ_task_rt_priority 0x00000004 -#define AOFF_task_it_real_value 0x000000f8 +#define AOFF_task_it_real_value 0x00000104 #define ASIZ_task_it_real_value 0x00000004 -#define AOFF_task_it_prof_value 0x000000fc +#define AOFF_task_it_prof_value 0x00000108 #define ASIZ_task_it_prof_value 0x00000004 -#define AOFF_task_it_virt_value 0x00000100 +#define AOFF_task_it_virt_value 0x0000010c #define ASIZ_task_it_virt_value 0x00000004 -#define AOFF_task_it_real_incr 0x00000104 +#define AOFF_task_it_real_incr 0x00000110 #define ASIZ_task_it_real_incr 0x00000004 -#define AOFF_task_it_prof_incr 0x00000108 +#define AOFF_task_it_prof_incr 0x00000114 #define ASIZ_task_it_prof_incr 0x00000004 -#define AOFF_task_it_virt_incr 0x0000010c +#define AOFF_task_it_virt_incr 0x00000118 #define ASIZ_task_it_virt_incr 0x00000004 -#define AOFF_task_real_timer 0x00000110 +#define AOFF_task_real_timer 0x0000011c #define ASIZ_task_real_timer 0x00000014 -#define AOFF_task_utime 0x00000124 +#define AOFF_task_utime 0x00000130 #define ASIZ_task_utime 0x00000004 -#define AOFF_task_stime 0x00000128 +#define AOFF_task_stime 0x00000134 #define ASIZ_task_stime 0x00000004 -#define AOFF_task_cutime 0x0000012c +#define AOFF_task_cutime 0x00000138 #define ASIZ_task_cutime 0x00000004 -#define AOFF_task_cstime 0x00000130 +#define AOFF_task_cstime 0x0000013c #define ASIZ_task_cstime 0x00000004 -#define AOFF_task_start_time 0x00000134 +#define AOFF_task_start_time 0x00000140 #define ASIZ_task_start_time 0x00000004 -#define AOFF_task_min_flt 0x00000138 +#define AOFF_task_min_flt 0x00000144 #define ASIZ_task_min_flt 0x00000004 -#define AOFF_task_maj_flt 0x0000013c +#define AOFF_task_maj_flt 0x00000148 #define ASIZ_task_maj_flt 0x00000004 -#define AOFF_task_nswap 0x00000140 +#define AOFF_task_nswap 0x0000014c #define ASIZ_task_nswap 0x00000004 -#define AOFF_task_cmin_flt 0x00000144 +#define AOFF_task_cmin_flt 0x00000150 #define ASIZ_task_cmin_flt 0x00000004 -#define AOFF_task_cmaj_flt 0x00000148 +#define AOFF_task_cmaj_flt 0x00000154 #define ASIZ_task_cmaj_flt 0x00000004 -#define AOFF_task_cnswap 0x0000014c +#define AOFF_task_cnswap 0x00000158 #define ASIZ_task_cnswap 0x00000004 -#define AOFF_task_swap_address 0x00000154 +#define AOFF_task_swap_address 0x00000160 #define ASIZ_task_swap_address 0x00000004 -#define AOFF_task_old_maj_flt 0x00000158 +#define AOFF_task_old_maj_flt 0x00000164 #define ASIZ_task_old_maj_flt 0x00000004 -#define AOFF_task_dec_flt 0x0000015c +#define AOFF_task_dec_flt 0x00000168 #define ASIZ_task_dec_flt 0x00000004 -#define AOFF_task_swap_cnt 0x00000160 +#define AOFF_task_swap_cnt 0x0000016c #define ASIZ_task_swap_cnt 0x00000004 -#define AOFF_task_rlim 0x00000164 +#define AOFF_task_rlim 0x00000170 #define ASIZ_task_rlim 0x00000050 -#define AOFF_task_used_math 0x000001b4 +#define AOFF_task_used_math 0x000001c0 #define ASIZ_task_used_math 0x00000002 -#define AOFF_task_comm 0x000001b6 +#define AOFF_task_comm 0x000001c2 #define ASIZ_task_comm 0x00000010 -#define AOFF_task_link_count 0x000001c8 +#define AOFF_task_link_count 0x000001d4 #define ASIZ_task_link_count 0x00000004 -#define AOFF_task_tty 0x000001cc +#define AOFF_task_tty 0x000001d8 #define ASIZ_task_tty 0x00000004 -#define AOFF_task_semundo 0x000001d0 +#define AOFF_task_semundo 0x000001dc #define ASIZ_task_semundo 0x00000004 -#define AOFF_task_semsleeping 0x000001d4 +#define AOFF_task_semsleeping 0x000001e0 #define ASIZ_task_semsleeping 0x00000004 -#define AOFF_task_ldt 0x000001d8 +#define AOFF_task_ldt 0x000001e4 #define ASIZ_task_ldt 0x00000004 -#define AOFF_task_tss 0x000001e0 +#define AOFF_task_tss 0x000001e8 #define ASIZ_task_tss 0x00000390 -#define AOFF_task_fs 0x00000570 +#define AOFF_task_fs 0x00000578 #define ASIZ_task_fs 0x00000004 -#define AOFF_task_files 0x00000574 +#define AOFF_task_files 0x0000057c #define ASIZ_task_files 0x00000004 -#define AOFF_task_mm 0x00000578 +#define AOFF_task_mm 0x00000580 #define ASIZ_task_mm 0x00000004 -#define AOFF_task_sig 0x0000057c +#define AOFF_task_sig 0x00000584 #define ASIZ_task_sig 0x00000004 -#define AOFF_task_processor 0x00000580 +#define AOFF_task_processor 0x00000588 #define ASIZ_task_processor 0x00000004 -#define AOFF_task_last_processor 0x00000584 +#define AOFF_task_last_processor 0x0000058c #define ASIZ_task_last_processor 0x00000004 -#define AOFF_task_lock_depth 0x00000588 +#define AOFF_task_lock_depth 0x00000590 #define ASIZ_task_lock_depth 0x00000004 -#define AOFF_mm_count 0x00000000 -#define ASIZ_mm_count 0x00000004 -#define AOFF_mm_pgd 0x00000004 +#define AOFF_task_sigmask_lock 0x00000594 +#define ASIZ_task_sigmask_lock 0x00000001 +#define AOFF_mm_mmap 0x00000000 +#define ASIZ_mm_mmap 0x00000004 +#define AOFF_mm_mmap_cache 0x00000004 +#define ASIZ_mm_mmap_cache 0x00000004 +#define AOFF_mm_pgd 0x00000008 #define ASIZ_mm_pgd 0x00000004 -#define AOFF_mm_context 0x00000008 +#define AOFF_mm_count 0x0000000c +#define ASIZ_mm_count 0x00000004 +#define AOFF_mm_mmap_sem 0x00000010 +#define ASIZ_mm_mmap_sem 0x0000000c +#define AOFF_mm_context 0x0000001c #define ASIZ_mm_context 0x00000004 -#define AOFF_mm_start_code 0x0000000c +#define AOFF_mm_start_code 0x00000020 #define ASIZ_mm_start_code 0x00000004 -#define AOFF_mm_end_code 0x00000010 +#define AOFF_mm_end_code 0x00000024 #define ASIZ_mm_end_code 0x00000004 -#define AOFF_mm_start_data 0x00000014 +#define AOFF_mm_start_data 0x00000028 #define ASIZ_mm_start_data 0x00000004 -#define AOFF_mm_end_data 0x00000018 +#define AOFF_mm_end_data 0x0000002c #define ASIZ_mm_end_data 0x00000004 -#define AOFF_mm_start_brk 0x0000001c +#define AOFF_mm_start_brk 0x00000030 #define ASIZ_mm_start_brk 0x00000004 -#define AOFF_mm_brk 0x00000020 +#define AOFF_mm_brk 0x00000034 #define ASIZ_mm_brk 0x00000004 -#define AOFF_mm_start_stack 0x00000024 +#define AOFF_mm_start_stack 0x00000038 #define ASIZ_mm_start_stack 0x00000004 -#define AOFF_mm_start_mmap 0x00000028 +#define AOFF_mm_start_mmap 0x0000003c #define ASIZ_mm_start_mmap 0x00000004 -#define AOFF_mm_arg_start 0x0000002c +#define AOFF_mm_arg_start 0x00000040 #define ASIZ_mm_arg_start 0x00000004 -#define AOFF_mm_arg_end 0x00000030 +#define AOFF_mm_arg_end 0x00000044 #define ASIZ_mm_arg_end 0x00000004 -#define AOFF_mm_env_start 0x00000034 +#define AOFF_mm_env_start 0x00000048 #define ASIZ_mm_env_start 0x00000004 -#define AOFF_mm_env_end 0x00000038 +#define AOFF_mm_env_end 0x0000004c #define ASIZ_mm_env_end 0x00000004 -#define AOFF_mm_rss 0x0000003c +#define AOFF_mm_rss 0x00000050 #define ASIZ_mm_rss 0x00000004 -#define AOFF_mm_total_vm 0x00000040 +#define AOFF_mm_total_vm 0x00000054 #define ASIZ_mm_total_vm 0x00000004 -#define AOFF_mm_locked_vm 0x00000044 +#define AOFF_mm_locked_vm 0x00000058 #define ASIZ_mm_locked_vm 0x00000004 -#define AOFF_mm_def_flags 0x00000048 +#define AOFF_mm_def_flags 0x0000005c #define ASIZ_mm_def_flags 0x00000004 -#define AOFF_mm_mmap 0x0000004c -#define ASIZ_mm_mmap 0x00000004 -#define AOFF_mm_mmap_avl 0x00000050 -#define ASIZ_mm_mmap_avl 0x00000004 -#define AOFF_mm_mmap_sem 0x00000054 -#define ASIZ_mm_mmap_sem 0x0000000c #define AOFF_thread_uwinmask 0x00000000 #define ASIZ_thread_uwinmask 0x00000004 #define AOFF_thread_kregs 0x00000004 diff -u --recursive --new-file v2.1.36/linux/include/asm-sparc/linux_logo.h linux/include/asm-sparc/linux_logo.h --- v2.1.36/linux/include/asm-sparc/linux_logo.h Wed Apr 23 19:01:28 1997 +++ linux/include/asm-sparc/linux_logo.h Sun Apr 27 15:13:50 1997 @@ -1043,1048 +1043,3 @@ "'!!!!!!!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.36/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h --- v2.1.36/linux/include/asm-sparc/processor.h Mon Mar 17 14:54:31 1997 +++ linux/include/asm-sparc/processor.h Sun Apr 27 15:08:02 1997 @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.57 1997/03/04 16:27:22 jj Exp $ +/* $Id: processor.h,v 1.58 1997/04/25 03:13:16 davem Exp $ * include/asm-sparc/processor.h * * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) @@ -83,7 +83,7 @@ #define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */ #define INIT_MMAP { &init_mm, (0), (0), \ - __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC } + __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ /* uwinmask, kregs, sig_address, sig_desc, ksp, kpc, kpsr, kwim */ \ diff -u --recursive --new-file v2.1.36/linux/include/asm-sparc/termbits.h linux/include/asm-sparc/termbits.h --- v2.1.36/linux/include/asm-sparc/termbits.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/termbits.h Sun Apr 27 15:08:02 1997 @@ -146,7 +146,13 @@ #define HUPCL 0x00000400 #define CLOCAL 0x00000800 #define CBAUDEX 0x00001000 -#define B76800 0x00001001 +/* We'll never see these speeds with the Zilogs, but for completeness... */ +#define B57600 0x00001001 +#define B115200 0x00001002 +#define B230400 0x00001003 +#define B460800 0x00001004 +/* This is what we can do with the Zilogs. */ +#define B76800 0x00001005 #define CIBAUD 0x100f0000 /* input baud rate (not used) */ #define CMSPAR 0x40000000 /* mark or space (stick) parity */ #define CRTSCTS 0x80000000 /* flow control */ diff -u --recursive --new-file v2.1.36/linux/include/asm-sparc64/fs_mount.h linux/include/asm-sparc64/fs_mount.h --- v2.1.36/linux/include/asm-sparc64/fs_mount.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-sparc64/fs_mount.h Sun Apr 27 15:08:02 1997 @@ -0,0 +1,44 @@ +/* $Id: fs_mount.h,v 1.2 1997/04/18 14:34:46 jj Exp $ + * fs_mount.h: Definitions for mount structure conversions. + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#ifndef __ASM_FS_MOUNT_H +#define __ASM_FS_MOUNT_H + +#if defined(CONFIG_SPARC32_COMPAT) || defined(CONFIG_SPARC32_COMPAT_MODULE) + +#include + +/* We need this to convert 32bit mount structures to 64bit */ + +extern void *do_ncp_super_data_conv(void *raw_data); +extern void *do_smb_super_data_conv(void *raw_data); + +extern __inline__ void *ncp_super_data_conv(void *raw_data) +{ + if (current->tss.flags & SPARC_FLAG_32BIT) + return do_ncp_super_data_conv(raw_data); + else + return raw_data; +} + +extern __inline__ void *smb_super_data_conv(void *raw_data) +{ + if (current->tss.flags & SPARC_FLAG_32BIT) + return do_smb_super_data_conv(raw_data); + else + return raw_data; +} + +#else /* CONFIG_SPARC32_COMPAT* */ + +#define ncp_super_data_conv(__x) __x +#define smb_super_data_conv(__x) __x + +#endif /* CONFIG_SPARC32_COMPAT* */ + +#define nfs_super_data_conv(__x) __x + +#endif /* __ASM_FS_MOUNT_H */ diff -u --recursive --new-file v2.1.36/linux/include/asm-sparc64/linux_logo.h linux/include/asm-sparc64/linux_logo.h --- v2.1.36/linux/include/asm-sparc64/linux_logo.h Wed Apr 23 19:01:28 1997 +++ linux/include/asm-sparc64/linux_logo.h Sun Apr 27 15:13:50 1997 @@ -1040,1045 +1040,3 @@ "'!!!!!!!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.36/linux/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h --- v2.1.36/linux/include/asm-sparc64/processor.h Wed Apr 23 19:01:28 1997 +++ linux/include/asm-sparc64/processor.h Sun Apr 27 15:08:03 1997 @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.21 1997/04/14 17:05:18 jj Exp $ +/* $Id: processor.h,v 1.23 1997/04/26 22:52:34 davem Exp $ * include/asm-sparc64/processor.h * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -71,7 +71,7 @@ #define SPARC_FLAG_32BIT 0x8 /* task is older 32-bit binary */ #define INIT_MMAP { &init_mm, 0xfffff80000000000, 0xfffff80001000000, \ - PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC } + PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ /* FPU regs */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ diff -u --recursive --new-file v2.1.36/linux/include/asm-sparc64/termbits.h linux/include/asm-sparc64/termbits.h --- v2.1.36/linux/include/asm-sparc64/termbits.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/termbits.h Sun Apr 27 15:08:03 1997 @@ -148,7 +148,13 @@ #define HUPCL 0x00000400 #define CLOCAL 0x00000800 #define CBAUDEX 0x00001000 +/* We'll never see these speeds with the Zilogs, but for completeness... */ #define B57600 0x00001001 +#define B115200 0x00001002 +#define B230400 0x00001003 +#define B460800 0x00001004 +/* This is what we can do with the Zilogs. */ +#define B76800 0x00001005 #define CIBAUD 0x100f0000 /* input baud rate (not used) */ #define CMSPAR 0x40000000 /* mark or space (stick) parity */ #define CRTSCTS 0x80000000 /* flow control */ diff -u --recursive --new-file v2.1.36/linux/include/linux/digi1.h linux/include/linux/digi1.h --- v2.1.36/linux/include/linux/digi1.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/digi1.h Tue Apr 29 11:45:43 1997 @@ -0,0 +1,100 @@ +/* Definitions for DigiBoard ditty(1) command. */ + +#if !defined(TIOCMODG) +#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */ +#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */ +#endif + +#if !defined(TIOCMSET) +#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */ +#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */ +#endif + +#if !defined(TIOCMBIC) +#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */ +#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */ +#endif + +#if !defined(TIOCSDTR) +#define TIOCSDTR ('e'<<8) | 0 /* set DTR */ +#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */ +#endif + +/************************************************************************ + * Ioctl command arguments for DIGI parameters. + ************************************************************************/ +#define DIGI_GETA ('e'<<8) | 94 /* Read params */ + +#define DIGI_SETA ('e'<<8) | 95 /* Set params */ +#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */ +#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */ + +#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */ + /* control characters */ +#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */ + /* control characters */ +#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */ + /* flow control chars */ +#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */ + /* flow control chars */ + +#define DIGI_GETINFO ('e'<<8) | 103 /* Fill in digi_info */ +#define DIGI_POLLER ('e'<<8) | 104 /* Turn on/off poller */ +#define DIGI_INIT ('e'<<8) | 105 /* Allow things to run. */ + +struct digiflow_struct +{ + unsigned char startc; /* flow cntl start char */ + unsigned char stopc; /* flow cntl stop char */ +}; + +typedef struct digiflow_struct digiflow_t; + + +/************************************************************************ + * Values for digi_flags + ************************************************************************/ +#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ +#define DIGI_FAST 0x0002 /* Fast baud rates */ +#define RTSPACE 0x0004 /* RTS input flow control */ +#define CTSPACE 0x0008 /* CTS output flow control */ +#define DSRPACE 0x0010 /* DSR output flow control */ +#define DCDPACE 0x0020 /* DCD output flow control */ +#define DTRPACE 0x0040 /* DTR input flow control */ +#define DIGI_FORCEDCD 0x0100 /* Force carrier */ +#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ +#define DIGI_AIXON 0x0400 /* Aux flow control in fep */ + + +/************************************************************************ + * Values for digiDload + ************************************************************************/ +#define NORMAL 0 +#define PCI_CTL 1 + +#define SIZE8 0 +#define SIZE16 1 +#define SIZE32 2 + +/************************************************************************ + * Structure used with ioctl commands for DIGI parameters. + ************************************************************************/ +struct digi_struct +{ + unsigned short digi_flags; /* Flags (see above) */ +}; + +typedef struct digi_struct digi_t; + +struct digi_info +{ + unsigned long board; /* Which board is this ? */ + unsigned char status; /* Alive or dead */ + unsigned char type; /* see epca.h */ + unsigned char subtype; /* For future XEM, XR, etc ... */ + unsigned short numports; /* Number of ports configured */ + unsigned char *port; /* I/O Address */ + unsigned char *membase; /* DPR Address */ + unsigned char *version; /* For future ... */ + unsigned short windowData; /* For future ... */ +} ; diff -u --recursive --new-file v2.1.36/linux/include/linux/digiFep1.h linux/include/linux/digiFep1.h --- v2.1.36/linux/include/linux/digiFep1.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/digiFep1.h Tue Apr 29 11:45:43 1997 @@ -0,0 +1,136 @@ + +#define CSTART 0x400L +#define CMAX 0x800L +#define ISTART 0x800L +#define IMAX 0xC00L +#define CIN 0xD10L +#define GLOBAL 0xD10L +#define EIN 0xD18L +#define FEPSTAT 0xD20L +#define CHANSTRUCT 0x1000L +#define RXTXBUF 0x4000L + + +struct global_data +{ + volatile ushort cin; + volatile ushort cout; + volatile ushort cstart; + volatile ushort cmax; + volatile ushort ein; + volatile ushort eout; + volatile ushort istart; + volatile ushort imax; +}; + + +struct board_chan +{ + int filler1; + int filler2; + volatile ushort tseg; + volatile ushort tin; + volatile ushort tout; + volatile ushort tmax; + + volatile ushort rseg; + volatile ushort rin; + volatile ushort rout; + volatile ushort rmax; + + volatile ushort tlow; + volatile ushort rlow; + volatile ushort rhigh; + volatile ushort incr; + + volatile ushort etime; + volatile ushort edelay; + volatile unchar *dev; + + volatile ushort iflag; + volatile ushort oflag; + volatile ushort cflag; + volatile ushort gmask; + + volatile ushort col; + volatile ushort delay; + volatile ushort imask; + volatile ushort tflush; + + int filler3; + int filler4; + int filler5; + int filler6; + + volatile unchar num; + volatile unchar ract; + volatile unchar bstat; + volatile unchar tbusy; + volatile unchar iempty; + volatile unchar ilow; + volatile unchar idata; + volatile unchar eflag; + + volatile unchar tflag; + volatile unchar rflag; + volatile unchar xmask; + volatile unchar xval; + volatile unchar mstat; + volatile unchar mchange; + volatile unchar mint; + volatile unchar lstat; + + volatile unchar mtran; + volatile unchar orun; + volatile unchar startca; + volatile unchar stopca; + volatile unchar startc; + volatile unchar stopc; + volatile unchar vnext; + volatile unchar hflow; + + volatile unchar fillc; + volatile unchar ochar; + volatile unchar omask; + + unchar filler7; + unchar filler8[28]; +}; + + +#define SRXLWATER 0xE0 +#define SRXHWATER 0xE1 +#define STOUT 0xE2 +#define PAUSETX 0xE3 +#define RESUMETX 0xE4 +#define SAUXONOFFC 0xE6 +#define SENDBREAK 0xE8 +#define SETMODEM 0xE9 +#define SETIFLAGS 0xEA +#define SONOFFC 0xEB +#define STXLWATER 0xEC +#define PAUSERX 0xEE +#define RESUMERX 0xEF +#define SETBUFFER 0xF2 +#define SETCOOKED 0xF3 +#define SETHFLOW 0xF4 +#define SETCTRLFLAGS 0xF5 +#define SETVNEXT 0xF6 + + + +#define BREAK_IND 0x01 +#define LOWTX_IND 0x02 +#define EMPTYTX_IND 0x04 +#define DATA_IND 0x08 +#define MODEMCHG_IND 0x20 + +#define FEP_HUPCL 0002000 +#if 0 +#define RTS 0x02 +#define CD 0x08 +#define DSR 0x10 +#define CTS 0x20 +#define RI 0x40 +#define DTR 0x80 +#endif diff -u --recursive --new-file v2.1.36/linux/include/linux/digiPCI.h linux/include/linux/digiPCI.h --- v2.1.36/linux/include/linux/digiPCI.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/digiPCI.h Tue Apr 29 11:45:43 1997 @@ -0,0 +1,42 @@ +/************************************************************************* + * Defines and structure definitions for PCI BIOS Interface + *************************************************************************/ +#define PCIMAX 32 /* maximum number of PCI boards */ + + +#define PCI_VENDOR_DIGI 0x114F +#define PCI_DEVICE_EPC 0x0002 +#define PCI_DEVICE_RIGHTSWITCH 0x0003 /* For testing */ +#define PCI_DEVICE_XEM 0x0004 +#define PCI_DEVICE_XR 0x0005 +#define PCI_DEVICE_CX 0x0006 +#define PCI_DEVICE_XRJ 0x0009 /* Jupiter boards with */ +#define PCI_DEVICE_EPCJ 0x000a /* PLX 9060 chip for PCI */ + + +/* + * On the PCI boards, there is no IO space allocated + * The I/O registers will be in the first 3 bytes of the + * upper 2MB of the 4MB memory space. The board memory + * will be mapped into the low 2MB of the 4MB memory space + */ + +/* Potential location of PCI Bios from E0000 to FFFFF*/ +#define PCI_BIOS_SIZE 0x00020000 + +/* Size of Memory and I/O for PCI (4MB) */ +#define PCI_RAM_SIZE 0x00400000 + +/* Size of Memory (2MB) */ +#define PCI_MEM_SIZE 0x00200000 + +/* Offset of I/0 in Memory (2MB) */ +#define PCI_IO_OFFSET 0x00200000 + +#define MEMOUTB(basemem, pnum, setmemval) *(caddr_t)((basemem) + ( PCI_IO_OFFSET | pnum << 4 | pnum )) = (setmemval) +#define MEMINB(basemem, pnum) *(caddr_t)((basemem) + (PCI_IO_OFFSET | pnum << 4 | pnum )) /* for PCI I/O */ + + + + + diff -u --recursive --new-file v2.1.36/linux/include/linux/epca.h linux/include/linux/epca.h --- v2.1.36/linux/include/linux/epca.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/epca.h Tue Apr 29 11:45:43 1997 @@ -0,0 +1,170 @@ +#define XEMPORTS 0xC02 +#define XEPORTS 0xC22 + +#define MAX_ALLOC 0x100 + +#define MAXBOARDS 12 +#define FEPCODESEG 0x0200L +#define FEPCODE 0x2000L +#define BIOSCODE 0xf800L + +#define MISCGLOBAL 0x0C00L +#define NPORT 0x0C22L +#define MBOX 0x0C40L +#define PORTBASE 0x0C90L + +/* Begin code defines used for epca_setup */ + +#define INVALID_BOARD_TYPE 0x1 +#define INVALID_NUM_PORTS 0x2 +#define INVALID_MEM_BASE 0x4 +#define INVALID_PORT_BASE 0x8 +#define INVALID_BOARD_STATUS 0x10 +#define INVALID_ALTPIN 0x20 + +/* End code defines used for epca_setup */ + + +#define FEPCLR 0x00 +#define FEPMEM 0x02 +#define FEPRST 0x04 +#define FEPINT 0x08 +#define FEPMASK 0x0e +#define FEPWIN 0x80 + +#define PCXE 0 +#define PCXEVE 1 +#define PCXEM 2 +#define EISAXEM 3 +#define PC64XE 4 +#define PCXI 5 +#define PCIXEM 7 +#define PCICX 8 +#define PCIXR 9 +#define PCIXRJ 10 +#define EPCA_NUM_TYPES 6 + + +static char *board_desc[] = +{ + "PC/Xe", + "PC/Xeve", + "PC/Xem", + "EISA/Xem", + "PC/64Xe", + "PC/Xi", + "unknown", + "PCI/Xem", + "PCI/CX", + "PCI/Xr", + "PCI/Xrj", +}; + +#define STARTC 021 +#define STOPC 023 +#define IAIXON 0x2000 + + +#define TXSTOPPED 0x1 +#define LOWWAIT 0x2 +#define EMPTYWAIT 0x4 +#define RXSTOPPED 0x8 +#define TXBUSY 0x10 + +#define DISABLED 0 +#define ENABLED 1 +#define OFF 0 +#define ON 1 + +#define FEPTIMEOUT 200000 +#define SERIAL_TYPE_NORMAL 1 +#define SERIAL_TYPE_CALLOUT 2 +#define SERIAL_TYPE_INFO 3 +#define EPCA_EVENT_HANGUP 1 +#define EPCA_MAGIC 0x5c6df104L + +struct channel +{ + long magic; + unchar boardnum; + unchar channelnum; + unchar omodem; /* FEP output modem status */ + unchar imodem; /* FEP input modem status */ + unchar modemfake; /* Modem values to be forced */ + unchar modem; /* Force values */ + unchar hflow; + unchar dsr; + unchar dcd; + unchar m_rts ; /* The bits used in whatever FEP */ + unchar m_dcd ; /* is indiginous to this board to */ + unchar m_dsr ; /* represent each of the physical */ + unchar m_cts ; /* handshake lines */ + unchar m_ri ; + unchar m_dtr ; + unchar stopc; + unchar startc; + unchar stopca; + unchar startca; + unchar fepstopc; + unchar fepstartc; + unchar fepstopca; + unchar fepstartca; + unchar txwin; + unchar rxwin; + ushort fepiflag; + ushort fepcflag; + ushort fepoflag; + ushort txbufhead; + ushort txbufsize; + ushort rxbufhead; + ushort rxbufsize; + int close_delay; + int count; + int blocked_open; + int event; + int asyncflags; + uint dev; + long session; + long pgrp; + ulong statusflags; + ulong c_iflag; + ulong c_cflag; + ulong c_lflag; + ulong c_oflag; + unchar *txptr; + unchar *rxptr; + unchar *tmp_buf; + struct board_info *board; + volatile struct board_chan *brdchan; + struct digi_struct digiext; + struct tty_struct *tty; + struct termios normal_termios; + struct termios callout_termios; + struct wait_queue *open_wait; + struct wait_queue *close_wait; + struct tq_struct tqueue; + volatile struct global_data *mailbox; +}; + +struct board_info +{ + unchar status; + unchar type; + unchar altpin; + ushort numports; + unchar *port; + unchar *membase; + unchar *re_map_port; + unchar *re_map_membase; + ulong memory_seg; + void ( * memwinon ) (struct board_info *, unsigned int) ; + void ( * memwinoff ) (struct board_info *, unsigned int) ; + void ( * globalwinon ) (struct channel *) ; + void ( * txwinon ) (struct channel *) ; + void ( * rxwinon ) (struct channel *) ; + void ( * memoff ) (struct channel *) ; + void ( * assertgwinon ) (struct channel *) ; + void ( * assertmemoff ) (struct channel *) ; + unchar poller_inhibited ; +}; + diff -u --recursive --new-file v2.1.36/linux/include/linux/epcaconfig.h linux/include/linux/epcaconfig.h --- v2.1.36/linux/include/linux/epcaconfig.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/epcaconfig.h Tue Apr 29 11:45:43 1997 @@ -0,0 +1,8 @@ +#define NUMCARDS 1 +#define NBDEVS 2 + +struct board_info static_boards[NUMCARDS]={ + { ENABLED, 0, OFF, 2, (unchar*) 0x320, (unchar*) 0xd0000 }, +}; + +/* DO NOT HAND EDIT THIS FILE! */ diff -u --recursive --new-file v2.1.36/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h --- v2.1.36/linux/include/linux/ext2_fs.h Thu Feb 6 02:53:33 1997 +++ linux/include/linux/ext2_fs.h Sat Apr 26 12:35:58 1997 @@ -189,6 +189,7 @@ #define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */ #define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */ #define EXT2_NODUMP_FL 0x00000040 /* do not dump file */ +#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */ #define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ /* @@ -363,7 +364,10 @@ __u32 s_feature_compat; /* compatible feature set */ __u32 s_feature_incompat; /* incompatible feature set */ __u32 s_feature_ro_compat; /* readonly-compatible feature set */ - __u32 s_reserved[230]; /* Padding to the end of the block */ + __u8 s_uuid[16]; /* 128-bit uuid for volume */ + char s_volume_name[16]; /* volume name */ + char s_last_mounted[64]; /* directory where last mounted */ + __u32 s_reserved[206]; /* Padding to the end of the block */ }; /* @@ -387,6 +391,16 @@ #define EXT2_GOOD_OLD_INODE_SIZE 128 /* + * Feature set definitions + */ + +#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 + +#define EXT2_FEATURE_COMPAT_SUPP 0 +#define EXT2_FEATURE_INCOMPAT_SUPP 0 +#define EXT2_FEATURE_RO_COMPAT_SUPP EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER + +/* * Default values for user and/or group using reserved blocks */ #define EXT2_DEF_RESUID 0 @@ -413,13 +427,6 @@ #define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ ~EXT2_DIR_ROUND) - -/* - * Feature set definitions --- none are defined as of now - */ -#define EXT2_FEATURE_COMPAT_SUPP 0 -#define EXT2_FEATURE_INCOMPAT_SUPP 0 -#define EXT2_FEATURE_RO_COMPAT_SUPP 0 #ifdef __KERNEL__ /* diff -u --recursive --new-file v2.1.36/linux/include/linux/ext2_fs_sb.h linux/include/linux/ext2_fs_sb.h --- v2.1.36/linux/include/linux/ext2_fs_sb.h Thu Feb 6 02:53:33 1997 +++ linux/include/linux/ext2_fs_sb.h Sat Apr 26 12:35:58 1997 @@ -60,6 +60,9 @@ int s_desc_per_block_bits; int s_inode_size; int s_first_ino; + int s_feature_compat; + int s_feature_incompat; + int s_feature_ro_compat; }; #endif /* _LINUX_EXT2_FS_SB */ diff -u --recursive --new-file v2.1.36/linux/include/linux/file.h linux/include/linux/file.h --- v2.1.36/linux/include/linux/file.h Fri Apr 4 08:52:25 1997 +++ linux/include/linux/file.h Sun Apr 27 15:08:03 1997 @@ -13,16 +13,37 @@ } extern int __fput(struct file *, struct inode *); +extern void insert_file_free(struct file *file); + +/* It does not matter which list it is on. */ +extern inline void remove_filp(struct file *file) +{ + if(file->f_next) + file->f_next->f_pprev = file->f_pprev; + *file->f_pprev = file->f_next; +} extern inline int fput(struct file *file, struct inode *inode) { int count = file->f_count-1; int error = 0; - if (!count) + if (!count) { error = __fput(file, inode); - file->f_count = count; + file->f_count = 0; + remove_filp(file); + insert_file_free(file); + } else + file->f_count = count; return error; +} + +extern inline void put_filp(struct file *file) +{ + if(--file->f_count == 0) { + remove_filp(file); + insert_file_free(file); + } } #endif diff -u --recursive --new-file v2.1.36/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.36/linux/include/linux/fs.h Wed Apr 23 19:01:28 1997 +++ linux/include/linux/fs.h Tue Apr 29 11:52:58 1997 @@ -95,7 +95,6 @@ * Exception: MS_RDONLY is always applied to the entire file system. */ #define IS_RDONLY(inode) (((inode)->i_sb) && ((inode)->i_sb->s_flags & MS_RDONLY)) -#define DO_UPDATE_ATIME(inode) (!((inode)->i_flags & MS_NOATIME) && !IS_RDONLY(inode)) #define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID) #define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV) #define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC) @@ -105,6 +104,8 @@ #define IS_WRITABLE(inode) ((inode)->i_flags & S_WRITE) #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) +#define IS_NOATIME(inode) ((inode)->i_flags & MS_NOATIME) +#define DO_UPDATE_ATIME(inode) (!IS_NOATIME(inode) && !IS_RDONLY(inode)) /* the read-only stuff doesn't really belong here, but any other place is probably as bad and I don't want to create yet another include file. */ @@ -129,7 +130,7 @@ extern void buffer_init(void); extern void inode_init(void); -extern unsigned long file_table_init(unsigned long start, unsigned long end); +extern void file_table_init(void); extern unsigned long name_cache_init(unsigned long start, unsigned long end); typedef char buffer_block[BLOCK_SIZE]; @@ -246,6 +247,7 @@ #define ATTR_ATIME_SET 128 #define ATTR_MTIME_SET 256 #define ATTR_FORCE 512 /* Not a change, but a change it */ +#define ATTR_ATTR_FLAG 1024 /* * This is the Inode Attributes structure, used for notify_change(). It @@ -265,8 +267,17 @@ time_t ia_atime; time_t ia_mtime; time_t ia_ctime; + unsigned int ia_attr_flags; }; +/* + * This is the inode attributes flag definitions + */ +#define ATTR_FLAG_SYNCRONOUS 1 /* Syncronous write */ +#define ATTR_FLAG_NOATIME 2 /* Don't update atime */ +#define ATTR_FLAG_APPEND 4 /* Append-only file */ +#define ATTR_FLAG_IMMUTABLE 8 /* Immutable file */ + #include struct inode { @@ -305,9 +316,8 @@ unsigned char i_dirt; unsigned char i_pipe; unsigned char i_sock; - unsigned char i_seek; - unsigned char i_update; - unsigned short i_writecount; + int i_writecount; + unsigned int i_attr_flags; union { struct pipe_inode_info pipe_i; struct minix_inode_info minix_i; @@ -327,17 +337,21 @@ }; struct file { - mode_t f_mode; - loff_t f_pos; - unsigned short f_flags; - unsigned short f_count; - unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin; - struct file *f_next, *f_prev; - int f_owner; /* pid or -pgrp where SIGIO should be sent */ - struct inode * f_inode; - struct file_operations * f_op; - unsigned long f_version; - void *private_data; /* needed for tty driver, and maybe others */ + struct file *f_next, **f_pprev; + struct inode *f_inode; + struct file_operations *f_op; + mode_t f_mode; + loff_t f_pos; + unsigned short f_count, f_flags; + unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin; + + /* pid or -pgrp where SIGIO should be sent */ + int f_owner; + + unsigned long f_version; + + /* needed for tty driver, and maybe others */ + void *private_data; }; #define FL_POSIX 1 @@ -584,7 +598,7 @@ extern int fs_may_umount(kdev_t dev, struct inode * mount_root); extern int fs_may_remount_ro(kdev_t dev); -extern struct file *first_file; +extern struct file *inuse_filps; extern struct super_block super_blocks[NR_SUPER]; extern void refile_buffer(struct buffer_head * buf); diff -u --recursive --new-file v2.1.36/linux/include/linux/mm.h linux/include/linux/mm.h --- v2.1.36/linux/include/linux/mm.h Wed Apr 23 19:01:29 1997 +++ linux/include/linux/mm.h Tue Apr 29 11:52:58 1997 @@ -37,18 +37,15 @@ unsigned long vm_end; pgprot_t vm_page_prot; unsigned short vm_flags; -/* AVL tree of VM areas per task, sorted by address */ - short vm_avl_height; - struct vm_area_struct * vm_avl_left; - struct vm_area_struct * vm_avl_right; -/* linked list of VM areas per task, sorted by address */ - struct vm_area_struct * vm_next; -/* for areas with inode, the circular list inode->i_mmap */ -/* for shm areas, the circular list of attaches */ -/* otherwise unused */ - struct vm_area_struct * vm_next_share; - struct vm_area_struct * vm_prev_share; -/* more */ + struct vm_area_struct *vm_next; + struct vm_area_struct **vm_pprev; + + /* For areas with inode, the list inode->i_mmap, for shm areas, + * the list of attaches, otherwise unused. + */ + struct vm_area_struct *vm_next_share; + struct vm_area_struct **vm_pprev_share; + struct vm_operations_struct * vm_ops; unsigned long vm_offset; struct inode * vm_inode; @@ -279,8 +276,6 @@ unsigned long prot, unsigned long flags, unsigned long off); extern void merge_segments(struct mm_struct *, unsigned long, unsigned long); extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); -extern void remove_shared_vm_struct(struct vm_area_struct *); -extern void build_mmap_avl(struct mm_struct *); extern void exit_mmap(struct mm_struct *); extern int do_munmap(unsigned long, size_t); extern unsigned long get_unmapped_area(unsigned long, unsigned long); @@ -325,38 +320,30 @@ return 0; } -#define avl_empty (struct vm_area_struct *) NULL - /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ static inline struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) { - struct vm_area_struct * result = NULL; + struct vm_area_struct *vma = NULL; if (mm) { - struct vm_area_struct ** next = &mm->mmap_avl; - for (;;) { - struct vm_area_struct *tree = *next; - if (tree == avl_empty) - break; - next = &tree->vm_avl_right; - if (tree->vm_end <= addr) - continue; - next = &tree->vm_avl_left; - result = tree; - if (tree->vm_start <= addr) - break; + /* Check the cache first. */ + vma = mm->mmap_cache; + if(!vma || (vma->vm_end <= addr) || (vma->vm_start > addr)) { + vma = mm->mmap; + while(vma && vma->vm_end <= addr) + vma = vma->vm_next; + mm->mmap_cache = vma; } } - return result; + return vma; } /* Look up the first VMA which intersects the interval start_addr..end_addr-1, NULL if none. Assume start_addr < end_addr. */ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) { - struct vm_area_struct * vma; + struct vm_area_struct * vma = find_vma(mm,start_addr); - vma = find_vma(mm,start_addr); if (vma && end_addr <= vma->vm_start) vma = NULL; return vma; diff -u --recursive --new-file v2.1.36/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.1.36/linux/include/linux/sched.h Wed Apr 23 19:01:29 1997 +++ linux/include/linux/sched.h Tue Apr 29 11:52:58 1997 @@ -1,14 +1,6 @@ #ifndef _LINUX_SCHED_H #define _LINUX_SCHED_H -/* - * define DEBUG if you want the wait-queues to have some extra - * debugging code. It's not normally used, but might catch some - * wait-queue coding errors. - * - * #define DEBUG - */ - #include /* for HZ */ extern unsigned long event; @@ -149,29 +141,27 @@ } struct mm_struct { - int count; + struct vm_area_struct *mmap, *mmap_cache; pgd_t * pgd; + int count; + struct semaphore mmap_sem; unsigned long context; unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack, start_mmap; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; unsigned long def_flags; - struct vm_area_struct * mmap; - struct vm_area_struct * mmap_avl; - struct semaphore mmap_sem; }; -#define INIT_MM { \ - 1, \ - swapper_pg_dir, \ - 0, \ - 0, 0, 0, 0, \ - 0, 0, 0, 0, \ - 0, 0, 0, 0, \ - 0, 0, 0, \ - 0, \ - &init_mmap, &init_mmap, MUTEX } +#define INIT_MM { \ + &init_mmap, NULL, swapper_pg_dir, 1, \ + MUTEX, \ + 0, \ + 0, 0, 0, 0, \ + 0, 0, 0, 0, \ + 0, 0, 0, 0, \ + 0, 0, 0, \ + 0 } struct signal_struct { atomic_t count; @@ -200,8 +190,6 @@ struct linux_binfmt *binfmt; struct task_struct *next_task, *prev_task; struct task_struct *next_run, *prev_run; - unsigned long saved_kernel_stack; - unsigned long kernel_stack_page; int exit_code, exit_signal; /* ??? */ unsigned long personality; @@ -222,6 +210,14 @@ * p->p_pptr->pid) */ struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; + + /* PID hash table linkage. */ + struct task_struct *pidhash_next; + struct task_struct **pidhash_pprev; + + /* Pointer to task[] array linkage. */ + struct task_struct **tarray_ptr; + struct wait_queue *wait_chldexit; /* for wait4() */ unsigned short uid,euid,suid,fsuid; unsigned short gid,egid,sgid,fsgid; @@ -260,6 +256,7 @@ /* signal handlers */ struct signal_struct *sig; /* SMP state */ + int has_cpu; int processor; int last_processor; int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */ @@ -304,11 +301,13 @@ /* exec domain */&default_exec_domain, \ /* binfmt */ NULL, \ /* schedlink */ &init_task,&init_task, &init_task, &init_task, \ -/* stack */ 0,(unsigned long) &init_kernel_stack, \ /* ec,brk... */ 0,0,0,0,0, \ /* pid etc.. */ 0,0,0,0,0, \ /* suppl grps*/ 0, {0,}, \ -/* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \ +/* proc links*/ &init_task,&init_task,NULL,NULL,NULL, \ +/* pidhash */ NULL, NULL, \ +/* tarray */ &task[0], \ +/* chld wait */ NULL, \ /* uid etc */ 0,0,0,0,0,0,0,0, \ /* timeout */ 0,SCHED_OTHER,0,0,0,0,0,0,0, \ /* timer */ { NULL, NULL, 0, 0, it_real_fn }, \ @@ -326,14 +325,85 @@ /* files */ &init_files, \ /* mm */ &init_mm, \ /* signals */ &init_signals, \ -/* SMP */ 0,0,0, \ +/* SMP */ 0,0,0,0, \ +/* lock */ SPIN_LOCK_UNLOCKED \ } +union task_union { + struct task_struct task; + unsigned long stack[2048]; +}; + +extern union task_union init_task_union; + extern struct mm_struct init_mm; -extern struct task_struct init_task; extern struct task_struct *task[NR_TASKS]; extern struct task_struct *last_task_used_math; +extern struct task_struct **tarray_freelist; +extern spinlock_t taskslot_lock; + +extern __inline__ void add_free_taskslot(struct task_struct **t) +{ + spin_lock(&taskslot_lock); + *t = (struct task_struct *) tarray_freelist; + tarray_freelist = t; + spin_unlock(&taskslot_lock); +} + +extern __inline__ struct task_struct **get_free_taskslot(void) +{ + struct task_struct **tslot; + + spin_lock(&taskslot_lock); + if((tslot = tarray_freelist) != NULL) + tarray_freelist = (struct task_struct **) *tslot; + spin_unlock(&taskslot_lock); + + return tslot; +} + +/* PID hashing. */ +#define PIDHASH_SZ (NR_TASKS >> 2) +extern struct task_struct *pidhash[PIDHASH_SZ]; +extern spinlock_t pidhash_lock; + +#define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1)) + +extern __inline__ void hash_pid(struct task_struct *p) +{ + struct task_struct **htable = &pidhash[pid_hashfn(p->pid)]; + + spin_lock(&pidhash_lock); + if((p->pidhash_next = *htable) != NULL) + (*htable)->pidhash_pprev = &p->pidhash_next; + *htable = p; + p->pidhash_pprev = htable; + spin_unlock(&pidhash_lock); +} + +extern __inline__ void unhash_pid(struct task_struct *p) +{ + spin_lock(&pidhash_lock); + if(p->pidhash_next) + p->pidhash_next->pidhash_pprev = p->pidhash_pprev; + *p->pidhash_pprev = p->pidhash_next; + spin_unlock(&pidhash_lock); +} + +extern __inline__ struct task_struct *find_task_by_pid(int pid) +{ + struct task_struct **htable = &pidhash[pid_hashfn(pid)]; + struct task_struct *p; + + spin_lock(&pidhash_lock); + for(p = *htable; p && p->pid != pid; p = p->pidhash_next) + ; + spin_unlock(&pidhash_lock); + + return p; +} + #include extern unsigned long volatile jiffies; @@ -425,15 +495,15 @@ wait->next = next; } -extern spinlock_t waitqueue_lock; +extern rwlock_t waitqueue_lock; extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) { unsigned long flags; - spin_lock_irqsave(&waitqueue_lock, flags); + write_lock_irqsave(&waitqueue_lock, flags); __add_wait_queue(p, wait); - spin_unlock_irqrestore(&waitqueue_lock, flags); + write_unlock_irqrestore(&waitqueue_lock, flags); } extern inline void __remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) @@ -454,9 +524,9 @@ { unsigned long flags; - spin_lock_irqsave(&waitqueue_lock, flags); + write_lock_irqsave(&waitqueue_lock, flags); __remove_wait_queue(p, wait); - spin_unlock_irqrestore(&waitqueue_lock, flags); + write_unlock_irqrestore(&waitqueue_lock, flags); } extern inline void poll_wait(struct wait_queue ** wait_address, poll_table * p) diff -u --recursive --new-file v2.1.36/linux/include/linux/slab.h linux/include/linux/slab.h --- v2.1.36/linux/include/linux/slab.h Thu Feb 6 02:53:33 1997 +++ linux/include/linux/slab.h Tue Apr 29 11:52:59 1997 @@ -54,6 +54,7 @@ /* System wide slabs. */ extern kmem_cache_t *vm_area_cachep; +extern kmem_cache_t *mm_cachep; #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.1.36/linux/include/linux/tty.h linux/include/linux/tty.h --- v2.1.36/linux/include/linux/tty.h Fri Apr 4 08:52:26 1997 +++ linux/include/linux/tty.h Tue Apr 29 11:52:58 1997 @@ -288,6 +288,7 @@ extern int pty_init(void); extern int tty_init(void); extern int pcxe_init(void); +extern int pc_init(void); extern int vcs_init(void); extern int cy_init(void); extern int stl_init(void); @@ -330,10 +331,14 @@ /* serial.c */ extern long serial_console_init(long kmem_start, long kmem_end); - + /* pcxx.c */ extern int pcxe_open(struct tty_struct *tty, struct file *filp); + +/* epca.c */ + +extern int pc_open(struct tty_struct *tty, struct file *filp); /* console.c */ diff -u --recursive --new-file v2.1.36/linux/include/linux/zorro.h linux/include/linux/zorro.h --- v2.1.36/linux/include/linux/zorro.h Wed Apr 23 19:01:29 1997 +++ linux/include/linux/zorro.h Sun Apr 27 15:13:50 1997 @@ -637,642 +637,3 @@ #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.36/linux/init/main.c linux/init/main.c --- v2.1.36/linux/init/main.c Wed Apr 23 19:01:29 1997 +++ linux/init/main.c Tue Apr 29 11:45:43 1997 @@ -175,6 +175,9 @@ #ifdef CONFIG_ISDN_DRV_HISAX extern void HiSax_setup(char *str, int *ints); #endif +#ifdef CONFIG_DIGIEPCA +extern void epca_setup(char *str, int *ints); +#endif #ifdef CONFIG_ISDN_DRV_PCBIT extern void pcbit_setup(char *str, int *ints); #endif @@ -257,7 +260,7 @@ static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; -__initfunc(char *get_options(char *str, int *ints)) +char *get_options(char *str, int *ints) { char *cur = str; int i=1; @@ -481,6 +484,9 @@ #ifdef CONFIG_DIGI { "digi=", pcxx_setup }, #endif +#ifdef CONFIG_DIGIEPCA + { "digiepca=", epca_setup }, +#endif #ifdef CONFIG_RISCOM8 { "riscom8=", riscom8_setup }, #endif @@ -779,43 +785,11 @@ extern int cpu_idle(void * unused); -/* - * Activate a secondary processor. - */ - -__initfunc(asmlinkage void start_secondary(void)) -{ - trap_init(); - init_IRQ(); - smp_callin(); - cpu_idle(NULL); -} - - - /* Called by boot processor to activate the rest. */ __initfunc(static void smp_init(void)) { - int i, j; - /* Get other processors into their bootup holding patterns. */ smp_boot_cpus(); - - /* Create the slave init tasks as sharing pid 0. This should only - * happen if we have virtual CPU numbers higher than 0. - */ - for (i=1; iprocessor=j; - } } /* @@ -832,6 +806,8 @@ #endif +extern void initialize_secondary(void); + /* * Activate the first processor. */ @@ -840,18 +816,14 @@ { char * command_line; -/* - * This little check will move. - */ - #ifdef __SMP__ - static int first_cpu=1; - - if(!first_cpu) - start_secondary(); - first_cpu=0; - -#endif + static int boot_cpu = 1; + /* "current" has been set up, we need to load it now */ + if (!boot_cpu) + initialize_secondary(); + boot_cpu = 0; +#endif + /* * Interrupts are still disabled. Do necessary setups, then * enable them @@ -896,7 +868,6 @@ memory_start = kmem_cache_init(memory_start, memory_end); sti(); calibrate_delay(); - memory_start = file_table_init(memory_start,memory_end); memory_start = name_cache_init(memory_start,memory_end); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) { @@ -913,6 +884,7 @@ vma_init(); buffer_init(); inode_init(); + file_table_init(); sock_init(); #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD) ipc_init(); diff -u --recursive --new-file v2.1.36/linux/ipc/shm.c linux/ipc/shm.c --- v2.1.36/linux/ipc/shm.c Mon Apr 14 16:28:26 1997 +++ linux/ipc/shm.c Sun Apr 27 15:08:03 1997 @@ -402,42 +402,21 @@ shm_swap_in /* swapin */ }; -/* Insert shmd into the circular list shp->attaches */ +/* Insert shmd into the list shp->attaches */ static inline void insert_attach (struct shmid_ds * shp, struct vm_area_struct * shmd) { - struct vm_area_struct * attaches; - - if ((attaches = shp->attaches)) { - shmd->vm_next_share = attaches; - shmd->vm_prev_share = attaches->vm_prev_share; - shmd->vm_prev_share->vm_next_share = shmd; - attaches->vm_prev_share = shmd; - } else - shp->attaches = shmd->vm_next_share = shmd->vm_prev_share = shmd; + if((shmd->vm_next_share = shp->attaches) != NULL) + shp->attaches->vm_pprev_share = &shmd->vm_next_share; + shp->attaches = shmd; + shmd->vm_pprev_share = &shp->attaches; } -/* Remove shmd from circular list shp->attaches */ +/* Remove shmd from list shp->attaches */ static inline void remove_attach (struct shmid_ds * shp, struct vm_area_struct * shmd) { - if (shmd->vm_next_share == shmd) { - if (shp->attaches != shmd) { - printk("shm_close: shm segment (id=%ld) attach list inconsistent\n", - SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK); - printk("shm_close: %08lx-%08lx %c%c%c%c %08lx %08lx\n", - shmd->vm_start, shmd->vm_end, - shmd->vm_flags & VM_READ ? 'r' : '-', - shmd->vm_flags & VM_WRITE ? 'w' : '-', - shmd->vm_flags & VM_EXEC ? 'x' : '-', - shmd->vm_flags & VM_MAYSHARE ? 's' : 'p', - shmd->vm_offset, shmd->vm_pte); - } - shp->attaches = NULL; - } else { - if (shp->attaches == shmd) - shp->attaches = shmd->vm_next_share; - shmd->vm_prev_share->vm_next_share = shmd->vm_next_share; - shmd->vm_next_share->vm_prev_share = shmd->vm_prev_share; - } + if(shmd->vm_next_share) + shmd->vm_next_share->vm_pprev_share = shmd->vm_pprev_share; + *shmd->vm_pprev_share = shmd->vm_next_share; } /* @@ -575,7 +554,6 @@ shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE); - shmd->vm_next_share = shmd->vm_prev_share = NULL; shmd->vm_inode = NULL; shmd->vm_offset = 0; shmd->vm_ops = &shm_vm_ops; diff -u --recursive --new-file v2.1.36/linux/kernel/exit.c linux/kernel/exit.c --- v2.1.36/linux/kernel/exit.c Wed Apr 23 19:01:29 1997 +++ linux/kernel/exit.c Tue Apr 29 11:18:20 1997 @@ -4,8 +4,6 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ -#undef DEBUG_PROC_TREE - #include #include #include @@ -16,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -124,132 +123,28 @@ wake_up_interruptible(&tsk->p_pptr->wait_chldexit); } -void release(struct task_struct * p) +static void release(struct task_struct * p) { - int i; - - if (!p) - return; - if (p == current) { - printk("task releasing itself\n"); - return; - } - for (i=1 ; iprocessor != NO_PROC_ID) - barrier(); - spin_unlock_wait(&scheduler_lock); + /* FIXME! Cheesy, but kills the window... -DaveM */ + while (p->has_cpu) + barrier(); + spin_unlock_wait(&scheduler_lock); #endif - nr_tasks--; - task[i] = NULL; - REMOVE_LINKS(p); - release_thread(p); - if (STACK_MAGIC != *(unsigned long *)p->kernel_stack_page) - printk(KERN_ALERT "release: %s kernel stack corruption. Aiee\n", p->comm); - free_kernel_stack(p->kernel_stack_page); - current->cmin_flt += p->min_flt + p->cmin_flt; - current->cmaj_flt += p->maj_flt + p->cmaj_flt; - current->cnswap += p->nswap + p->cnswap; - free_task_struct(p); - return; - } - panic("trying to release non-existent task"); -} - -#ifdef DEBUG_PROC_TREE -/* - * Check to see if a task_struct pointer is present in the task[] array - * Return 0 if found, and 1 if not found. - */ -int bad_task_ptr(struct task_struct *p) -{ - int i; - - if (!p) - return 0; - for (i=0 ; ip_pptr)) - printk("Warning, pid %d's parent link is bad\n", - task[i]->pid); - if (bad_task_ptr(task[i]->p_cptr)) - printk("Warning, pid %d's child link is bad\n", - task[i]->pid); - if (bad_task_ptr(task[i]->p_ysptr)) - printk("Warning, pid %d's ys link is bad\n", - task[i]->pid); - if (bad_task_ptr(task[i]->p_osptr)) - printk("Warning, pid %d's os link is bad\n", - task[i]->pid); - if (task[i]->p_pptr == task[i]) - printk("Warning, pid %d parent link points to self\n", - task[i]->pid); - if (task[i]->p_cptr == task[i]) - printk("Warning, pid %d child link points to self\n", - task[i]->pid); - if (task[i]->p_ysptr == task[i]) - printk("Warning, pid %d ys link points to self\n", - task[i]->pid); - if (task[i]->p_osptr == task[i]) - printk("Warning, pid %d os link points to self\n", - task[i]->pid); - if (task[i]->p_osptr) { - if (task[i]->p_pptr != task[i]->p_osptr->p_pptr) - printk( - "Warning, pid %d older sibling %d parent is %d\n", - task[i]->pid, task[i]->p_osptr->pid, - task[i]->p_osptr->p_pptr->pid); - if (task[i]->p_osptr->p_ysptr != task[i]) - printk( - "Warning, pid %d older sibling %d has mismatched ys link\n", - task[i]->pid, task[i]->p_osptr->pid); - } - if (task[i]->p_ysptr) { - if (task[i]->p_pptr != task[i]->p_ysptr->p_pptr) - printk( - "Warning, pid %d younger sibling %d parent is %d\n", - task[i]->pid, task[i]->p_osptr->pid, - task[i]->p_osptr->p_pptr->pid); - if (task[i]->p_ysptr->p_osptr != task[i]) - printk( - "Warning, pid %d younger sibling %d has mismatched os link\n", - task[i]->pid, task[i]->p_ysptr->pid); - } - if (task[i]->p_cptr) { - if (task[i]->p_cptr->p_pptr != task[i]) - printk( - "Warning, pid %d youngest child %d has mismatched parent link\n", - task[i]->pid, task[i]->p_cptr->pid); - if (task[i]->p_cptr->p_ysptr) - printk( - "Warning, pid %d youngest child %d has non-NULL ys link\n", - task[i]->pid, task[i]->p_cptr->pid); - } + nr_tasks--; + add_free_taskslot(p->tarray_ptr); + unhash_pid(p); + REMOVE_LINKS(p); + release_thread(p); + current->cmin_flt += p->min_flt + p->cmin_flt; + current->cmaj_flt += p->maj_flt + p->cmaj_flt; + current->cnswap += p->nswap + p->cnswap; + free_task_struct(p); + } else { + printk("task releasing itself\n"); } } -#endif /* DEBUG_PROC_TREE */ /* * This checks not only the pgrp, but falls back on the pid if no @@ -347,17 +242,12 @@ retval = -EINVAL; if (sig >= 0 && sig <= 32) { - struct task_struct *p; + struct task_struct *p = find_task_by_pid(pid); - 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); + if(p) + retval = send_sig(sig, p, priv); + else + retval = -ESRCH; } return retval; } @@ -550,7 +440,7 @@ if (!--mm->count) { exit_mmap(mm); free_page_tables(mm); - kfree(mm); + kmem_cache_free(mm_cachep, mm); } } } diff -u --recursive --new-file v2.1.36/linux/kernel/fork.c linux/kernel/fork.c --- v2.1.36/linux/kernel/fork.c Wed Apr 23 19:01:29 1997 +++ linux/kernel/fork.c Mon Apr 28 20:40:48 1997 @@ -33,9 +33,18 @@ unsigned long int total_forks=0; /* Handle normal Linux uptimes. */ int last_pid=0; +/* SLAB cache for mm_struct's. */ +kmem_cache_t *mm_cachep; + +struct task_struct *pidhash[PIDHASH_SZ]; +spinlock_t pidhash_lock = SPIN_LOCK_UNLOCKED; + +struct task_struct **tarray_freelist = NULL; +spinlock_t taskslot_lock = SPIN_LOCK_UNLOCKED; + static inline int find_empty_process(void) { - int i; + struct task_struct **tslot; if (nr_tasks >= NR_TASKS - MIN_TASKS_LEFT_FOR_ROOT) { if (current->uid) @@ -47,6 +56,7 @@ 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) @@ -58,10 +68,9 @@ read_unlock(&tasklist_lock); } } - for (i = 0 ; i < NR_TASKS ; i++) { - if (!task[i]) - return i; - } + tslot = get_free_taskslot(); + if(tslot) + return tslot - &task[0]; return -EAGAIN; } @@ -89,12 +98,14 @@ static inline int dup_mmap(struct mm_struct * mm) { - struct vm_area_struct * mpnt, **p, *tmp; + struct vm_area_struct * mpnt, *tmp, **pprev; - mm->mmap = NULL; - p = &mm->mmap; + mm->mmap = mm->mmap_cache = NULL; flush_cache_mm(current->mm); + pprev = &mm->mmap; for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) { + struct inode *inode; + tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!tmp) { exit_mmap(mm); @@ -105,12 +116,18 @@ tmp->vm_flags &= ~VM_LOCKED; tmp->vm_mm = mm; tmp->vm_next = NULL; - if (tmp->vm_inode) { - tmp->vm_inode->i_count++; + inode = tmp->vm_inode; + if (inode) { + inode->i_count++; + if (tmp->vm_flags & VM_DENYWRITE) + inode->i_writecount--; + /* insert tmp into the share list, just after mpnt */ - tmp->vm_next_share->vm_prev_share = tmp; + if((tmp->vm_next_share = mpnt->vm_next_share) != NULL) + mpnt->vm_next_share->vm_pprev_share = + &tmp->vm_next_share; mpnt->vm_next_share = tmp; - tmp->vm_prev_share = mpnt; + tmp->vm_pprev_share = &mpnt->vm_next_share; } if (copy_page_range(mm, current->mm, tmp)) { exit_mmap(mm); @@ -119,18 +136,23 @@ } if (tmp->vm_ops && tmp->vm_ops->open) tmp->vm_ops->open(tmp); - *p = tmp; - p = &tmp->vm_next; + + /* Ok, finally safe to link it in. */ + if((tmp->vm_next = *pprev) != NULL) + (*pprev)->vm_pprev = &tmp->vm_next; + *pprev = tmp; + tmp->vm_pprev = pprev; + + pprev = &tmp->vm_next; } flush_tlb_mm(current->mm); - build_mmap_avl(mm); return 0; } static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk) { if (!(clone_flags & CLONE_VM)) { - struct mm_struct * mm = kmalloc(sizeof(*tsk->mm), GFP_KERNEL); + struct mm_struct * mm = kmem_cache_alloc(mm_cachep, SLAB_KERNEL); if (!mm) return -1; *mm = *current->mm; @@ -146,7 +168,7 @@ if (dup_mmap(mm)) { free_page_tables(mm); free_mm: - kfree(mm); + kmem_cache_free(mm_cachep, mm); return -1; } return 0; @@ -232,20 +254,17 @@ { int nr; int error = -ENOMEM; - unsigned long new_stack; struct task_struct *p; lock_kernel(); p = alloc_task_struct(); if (!p) goto bad_fork; - new_stack = alloc_kernel_stack(p); - if (!new_stack) - goto bad_fork_free_p; + error = -EAGAIN; nr = find_empty_process(); if (nr < 0) - goto bad_fork_free_stack; + goto bad_fork_free; *p = *current; @@ -256,8 +275,6 @@ p->did_exec = 0; p->swappable = 0; - p->kernel_stack_page = new_stack; - *(unsigned long *) p->kernel_stack_page = STACK_MAGIC; p->state = TASK_UNINTERRUPTIBLE; p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPRIV); p->flags |= PF_FORKNOEXEC; @@ -277,12 +294,15 @@ p->utime = p->stime = 0; p->cutime = p->cstime = 0; #ifdef __SMP__ + p->has_cpu = 0; p->processor = NO_PROC_ID; #endif p->lock_depth = 0; p->start_time = jiffies; - task[nr] = p; + p->tarray_ptr = &task[nr]; + *p->tarray_ptr = p; SET_LINKS(p); + hash_pid(p); nr_tasks++; error = -ENOMEM; @@ -334,12 +354,11 @@ __MOD_DEC_USE_COUNT(p->exec_domain->module); if (p->binfmt && p->binfmt->module) __MOD_DEC_USE_COUNT(p->binfmt->module); - task[nr] = NULL; + add_free_taskslot(p->tarray_ptr); + unhash_pid(p); REMOVE_LINKS(p); nr_tasks--; -bad_fork_free_stack: - free_kernel_stack(new_stack); -bad_fork_free_p: +bad_fork_free: free_task_struct(p); bad_fork: fork_out: diff -u --recursive --new-file v2.1.36/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.36/linux/kernel/ksyms.c Wed Apr 23 19:01:29 1997 +++ linux/kernel/ksyms.c Sun Apr 27 15:08:03 1997 @@ -150,6 +150,7 @@ EXPORT_SYMBOL(open_namei); EXPORT_SYMBOL(sys_close); EXPORT_SYMBOL(close_fp); +EXPORT_SYMBOL(insert_file_free); EXPORT_SYMBOL(check_disk_change); EXPORT_SYMBOL(invalidate_buffers); EXPORT_SYMBOL(invalidate_inodes); diff -u --recursive --new-file v2.1.36/linux/kernel/sched.c linux/kernel/sched.c --- v2.1.36/linux/kernel/sched.c Wed Apr 23 19:01:29 1997 +++ linux/kernel/sched.c Mon Apr 28 20:41:48 1997 @@ -88,16 +88,6 @@ extern void mem_use(void); -static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, }; -unsigned long init_user_stack[1024] = { STACK_MAGIC, }; -static struct vm_area_struct init_mmap = INIT_MMAP; -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; -static struct signal_struct init_signals = INIT_SIGNALS; - -struct mm_struct init_mm = INIT_MM; -struct task_struct init_task = INIT_TASK; - unsigned long volatile jiffies=0; /* @@ -250,7 +240,7 @@ #ifdef __SMP__ /* Give a largish advantage to the same processor... */ /* (this is equivalent to penalizing other processors) */ - if (p->last_processor == this_cpu) + if (p->processor == this_cpu) weight += PROC_CHANGE_PENALTY; #endif @@ -265,7 +255,7 @@ #ifdef __SMP__ #define idle_task (task[cpu_number_map[this_cpu]]) -#define can_schedule(p) ((p)->processor == NO_PROC_ID) +#define can_schedule(p) (!(p)->has_cpu) #else @@ -292,12 +282,12 @@ int this_cpu; need_resched = 0; + prev = current; this_cpu = smp_processor_id(); if (local_irq_count[this_cpu]) { printk("Scheduling in interrupt\n"); *(char *)0 = 0; } - prev = current; release_kernel_lock(prev, this_cpu, lock_depth); if (bh_active & bh_mask) do_bottom_half(); @@ -348,9 +338,7 @@ * the scheduler lock */ spin_unlock_irq(&runqueue_lock); -#ifdef __SMP__ - prev->processor = NO_PROC_ID; -#endif + prev->has_cpu = 0; /* * Note! there may appear new tasks on the run-queue during this, as @@ -381,8 +369,8 @@ } } + next->has_cpu = 1; next->processor = this_cpu; - next->last_processor = this_cpu; if (prev != next) { struct timer_list timer; @@ -421,19 +409,22 @@ #endif -spinlock_t waitqueue_lock; +rwlock_t waitqueue_lock; /* * wake_up doesn't wake up stopped processes - they have to be awakened * with signals or similar. + * + * Note that we only need a read lock for the wait queue (and thus do not + * have to protect against interrupts), as the actual removal from the + * queue is handled by the process itself. */ void wake_up(struct wait_queue **q) { - unsigned long flags; struct wait_queue *next; struct wait_queue *head; - spin_lock_irqsave(&waitqueue_lock, flags); + read_lock(&waitqueue_lock); if (q && (next = *q)) { head = WAIT_QUEUE_HEAD(q); while (next != head) { @@ -453,16 +444,15 @@ break; } } - spin_unlock_irqrestore(&waitqueue_lock, flags); + read_unlock(&waitqueue_lock); } void wake_up_interruptible(struct wait_queue **q) { - unsigned long flags; struct wait_queue *next; struct wait_queue *head; - spin_lock_irqsave(&waitqueue_lock, flags); + read_lock(&waitqueue_lock); if (q && (next = *q)) { head = WAIT_QUEUE_HEAD(q); while (next != head) { @@ -481,7 +471,7 @@ break; } } - spin_unlock_irqrestore(&waitqueue_lock, flags); + read_unlock(&waitqueue_lock); } /* @@ -603,14 +593,14 @@ if (current == task[0]) panic("task[0] trying to sleep"); current->state = state; - spin_lock_irqsave(&waitqueue_lock, flags); + write_lock_irqsave(&waitqueue_lock, flags); __add_wait_queue(p, &wait); - spin_unlock(&waitqueue_lock); + write_unlock(&waitqueue_lock); sti(); schedule(); - spin_lock_irq(&waitqueue_lock); + write_lock_irq(&waitqueue_lock); __remove_wait_queue(p, &wait); - spin_unlock_irqrestore(&waitqueue_lock, flags); + write_unlock_irqrestore(&waitqueue_lock, flags); } void interruptible_sleep_on(struct wait_queue **p) @@ -1338,22 +1328,12 @@ #endif -static struct task_struct *find_process_by_pid(pid_t pid) +static inline struct task_struct *find_process_by_pid(pid_t pid) { - struct task_struct *p; - - 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; + if (pid) + return find_task_by_pid(pid); + else + return current; } static int setscheduler(pid_t pid, int policy, @@ -1566,7 +1546,7 @@ static void show_task(int nr,struct task_struct * p) { - unsigned long free; + unsigned long free = 0; static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" }; printk("%-8s %3d ", p->comm, (p == current) ? -nr : nr); @@ -1585,10 +1565,12 @@ else printk(" %016lx ", thread_saved_pc(&p->tss)); #endif +#if 0 for (free = 1; free < PAGE_SIZE/sizeof(long) ; free++) { if (((unsigned long *)p->kernel_stack_page)[free]) break; } +#endif printk("%5lu %5d %6d ", free*sizeof(long), p->pid, p->p_pptr->pid); if (p->p_cptr) printk("%5d ", p->p_cptr->pid); @@ -1606,7 +1588,7 @@ void show_state(void) { - int i; + struct task_struct *p; #if ((~0UL) == 0xffffffff) printk("\n" @@ -1617,9 +1599,10 @@ " free sibling\n"); printk(" task PC stack pid father child younger older\n"); #endif - for (i=0 ; itarray_ptr - &task[0]),p); + read_unlock(&tasklist_lock); } void sched_init(void) @@ -1628,14 +1611,28 @@ * We have to do a little magic to get the first * process right in SMP mode. */ - int cpu=smp_processor_id(); + int cpu=hard_smp_processor_id(); + int nr = NR_TASKS; + #ifndef __SMP__ current_set[cpu]=&init_task; #else init_task.processor=cpu; + /* + * This looks strange, but we don't necessarily know which CPU + * we're booting on yet, so do them all.. + */ for(cpu = 0; cpu < NR_CPUS; cpu++) current_set[cpu] = &init_task; #endif + + /* Init task array free list and pidhash table. */ + while(--nr > 0) + add_free_taskslot(&task[nr]); + + for(nr = 0; nr < PIDHASH_SZ; nr++) + pidhash[nr] = NULL; + init_bh(TIMER_BH, timer_bh); init_bh(TQUEUE_BH, tqueue_bh); init_bh(IMMEDIATE_BH, immediate_bh); diff -u --recursive --new-file v2.1.36/linux/kernel/sys.c linux/kernel/sys.c --- v2.1.36/linux/kernel/sys.c Wed Apr 23 19:01:29 1997 +++ linux/kernel/sys.c Sun Apr 27 15:08:03 1997 @@ -709,22 +709,13 @@ if (pgid < 0) return -EINVAL; - read_lock(&tasklist_lock); - for_each_task(p) { - if (p->pid == pid) { - /* NOTE: I haven't dropped tasklist_lock, this is - * on purpose. -DaveM - */ - goto found_task; - } - } - read_unlock(&tasklist_lock); - return -ESRCH; + if((p = find_task_by_pid(pid)) == NULL) + 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 */ + read_lock(&tasklist_lock); err = -ESRCH; if (p->p_pptr == current || p->p_opptr == current) { err = -EPERM; @@ -762,18 +753,12 @@ if (!pid) { return current->pgrp; } else { - struct task_struct *p; - int ret = -ESRCH; + struct task_struct *p = find_task_by_pid(pid); - read_lock(&tasklist_lock); - for_each_task(p) { - if (p->pid == pid) { - ret = p->pgrp; - break; - } - } - read_unlock(&tasklist_lock); - return ret; + if(p) + return p->pgrp; + else + return -ESRCH; } } @@ -785,25 +770,16 @@ asmlinkage int sys_getsid(pid_t pid) { - struct task_struct * p; - int ret; - - /* SMP: The 'self' case requires no lock */ if (!pid) { - ret = current->session; + return current->session; } else { - ret = -ESRCH; + struct task_struct *p = find_task_by_pid(pid); - read_lock(&tasklist_lock); - for_each_task(p) { - if (p->pid == pid) { - ret = p->session; - break; - } - } - read_unlock(&tasklist_lock); + if(p) + return p->session; + else + return -ESRCH; } - return ret; } asmlinkage int sys_setsid(void) diff -u --recursive --new-file v2.1.36/linux/mm/mmap.c linux/mm/mmap.c --- v2.1.36/linux/mm/mmap.c Thu Feb 27 10:57:31 1997 +++ linux/mm/mmap.c Sun Apr 27 18:32:36 1997 @@ -21,8 +21,7 @@ #include #include -/* - * description of effects of mapping type and prot in current implementation. +/* description of effects of mapping type and prot in current implementation. * this is due to the limited x86 page protection hardware. The expected * behavior is in parens: * @@ -37,7 +36,6 @@ * x: (no) no x: (no) yes x: (no) yes x: (yes) yes * */ - pgprot_t protection_map[16] = { __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111 @@ -48,20 +46,18 @@ int sysctl_overcommit_memory; -/* - * Check that a process has enough memory to allocate a +/* Check that a process has enough memory to allocate a * new virtual mapping. */ static inline int vm_enough_memory(long pages) { - /* - * stupid algorithm to decide if we have enough memory: while + /* Stupid algorithm to decide if we have enough memory: while * simple, it hopefully works in most obvious cases.. Easy to * fool it, but this should catch most mistakes. */ long freepages; - /* sometimes we want to use more memory than we have. */ + /* Sometimes we want to use more memory than we have. */ if (sysctl_overcommit_memory) return 1; @@ -74,6 +70,20 @@ return freepages > pages; } +/* Remove one vm structure from the inode's i_mmap ring. */ +static inline void remove_shared_vm_struct(struct vm_area_struct *vma) +{ + struct inode * inode = vma->vm_inode; + + if (inode) { + if (vma->vm_flags & VM_DENYWRITE) + inode->i_writecount++; + if(vma->vm_next_share) + vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share; + *vma->vm_pprev_share = vma->vm_next_share; + } +} + asmlinkage unsigned long sys_brk(unsigned long brk) { unsigned long rlim, retval; @@ -91,17 +101,14 @@ goto out; } - /* - * Always allow shrinking brk - */ + /* Always allow shrinking brk. */ if (brk <= mm->brk) { retval = mm->brk = brk; do_munmap(newbrk, oldbrk-newbrk); goto out; } - /* - * Check against rlimit and stack.. - */ + + /* Check against rlimit and stack.. */ retval = mm->brk; rlim = current->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) @@ -109,21 +116,15 @@ if (brk - mm->end_code > rlim) goto out; - /* - * Check against existing mmap mappings. - */ + /* Check against existing mmap mappings. */ if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) goto out; - /* - * Check if we have enough memory.. - */ + /* Check if we have enough memory.. */ if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) goto out; - /* - * Ok, looks good - let it rip. - */ + /* Ok, looks good - let it rip. */ if(do_mmap(NULL, oldbrk, newbrk-oldbrk, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0) == oldbrk) @@ -134,8 +135,7 @@ return retval; } -/* - * Combine the mmap "prot" and "flags" argument into one "vm_flags" used +/* Combine the mmap "prot" and "flags" argument into one "vm_flags" used * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits * into "VM_xxx". */ @@ -162,6 +162,7 @@ { struct mm_struct * mm = current->mm; struct vm_area_struct * vma; + int correct_wcount = 0; if ((len = PAGE_ALIGN(len)) == 0) return addr; @@ -181,20 +182,17 @@ return -EAGAIN; } - /* - * do simple checking here so the lower-level routines won't have + /* Do simple checking here so the lower-level routines won't have * to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */ - if (file != NULL) { switch (flags & MAP_TYPE) { case MAP_SHARED: if ((prot & PROT_WRITE) && !(file->f_mode & 2)) return -EACCES; - /* - * make sure there are no mandatory locks on the file. - */ + + /* make sure there are no mandatory locks on the file. */ if (locks_verify_locked(file->f_inode)) return -EAGAIN; /* fall through */ @@ -206,18 +204,12 @@ default: return -EINVAL; } - if (flags & MAP_DENYWRITE) { - if (file->f_inode->i_writecount > 0) - return -ETXTBSY; - } } else if ((flags & MAP_TYPE) != MAP_PRIVATE) return -EINVAL; - /* - * obtain the address to map to. we verify (or select) it and ensure + /* Obtain the address to map to. we verify (or select) it and ensure * that it represents a valid section of the address space. */ - if (flags & MAP_FIXED) { if (addr & ~PAGE_MASK) return -EINVAL; @@ -227,8 +219,7 @@ return -ENOMEM; } - /* - * determine the object being mapped and call the appropriate + /* Determine the object being mapped and call the appropriate * specific mapper. the address has already been validated, but * not unmapped, but the maps are removed from the list. */ @@ -249,8 +240,8 @@ vma->vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; if (flags & MAP_SHARED) { vma->vm_flags |= VM_SHARED | VM_MAYSHARE; - /* - * This looks strange, but when we don't have the file open + + /* This looks strange, but when we don't have the file open * for writing, we can demote the shared mapping to a simpler * private mapping. That also takes care of a security hole * with ptrace() writing to a shared mapping without write @@ -289,9 +280,26 @@ } if (file) { - int error = file->f_op->mmap(file->f_inode, file, vma); + int error = 0; + if (vma->vm_flags & VM_DENYWRITE) { + if (file->f_inode->i_writecount > 0) + error = -ETXTBSY; + else { + /* f_op->mmap might possibly sleep + * (generic_file_mmap doesn't, but other code + * might). In any case, this takes care of any + * race that this might cause. + */ + file->f_inode->i_writecount--; + correct_wcount = 1; + } + } + if (!error) + error = file->f_op->mmap(file->f_inode, file, vma); if (error) { + if (correct_wcount) + file->f_inode->i_writecount++; kmem_cache_free(vm_area_cachep, vma); return error; } @@ -299,6 +307,8 @@ flags = vma->vm_flags; insert_vm_struct(mm, vma); + if (correct_wcount) + file->f_inode->i_writecount++; merge_segments(mm, vma->vm_start, vma->vm_end); /* merge_segments might have merged our vma, so we can't use it any more */ @@ -317,8 +327,7 @@ return addr; } -/* - * Get an address range which is currently unmapped. +/* Get an address range which is currently unmapped. * For mmap() without MAP_FIXED and shmat() with addr=0. * Return value 0 means ENOMEM. */ @@ -342,376 +351,7 @@ } } -/* - * Searching a VMA in the linear list task->mm->mmap is horribly slow. - * Use an AVL (Adelson-Velskii and Landis) tree to speed up this search - * from O(n) to O(log n), where n is the number of VMAs of the task - * (typically around 6, but may reach 3000 in some cases). - * Written by Bruno Haible . - */ - -/* We keep the list and tree sorted by address. */ -#define vm_avl_key vm_end -#define vm_avl_key_t unsigned long /* typeof(vma->avl_key) */ - -/* - * task->mm->mmap_avl is the AVL tree corresponding to task->mm->mmap - * or, more exactly, its root. - * A vm_area_struct has the following fields: - * vm_avl_left left son of a tree node - * vm_avl_right right son of a tree node - * vm_avl_height 1+max(heightof(left),heightof(right)) - * The empty tree is represented as NULL. - */ - -/* Since the trees are balanced, their height will never be large. */ -#define avl_maxheight 41 /* why this? a small exercise */ -#define heightof(tree) ((tree) == avl_empty ? 0 : (tree)->vm_avl_height) -/* - * Consistency and balancing rules: - * 1. tree->vm_avl_height == 1+max(heightof(tree->vm_avl_left),heightof(tree->vm_avl_right)) - * 2. abs( heightof(tree->vm_avl_left) - heightof(tree->vm_avl_right) ) <= 1 - * 3. foreach node in tree->vm_avl_left: node->vm_avl_key <= tree->vm_avl_key, - * foreach node in tree->vm_avl_right: node->vm_avl_key >= tree->vm_avl_key. - */ - -/* Look up the nodes at the left and at the right of a given node. */ -static inline void avl_neighbours (struct vm_area_struct * node, struct vm_area_struct * tree, struct vm_area_struct ** to_the_left, struct vm_area_struct ** to_the_right) -{ - vm_avl_key_t key = node->vm_avl_key; - - *to_the_left = *to_the_right = NULL; - for (;;) { - if (tree == avl_empty) { - printk("avl_neighbours: node not found in the tree\n"); - return; - } - if (key == tree->vm_avl_key) - break; - if (key < tree->vm_avl_key) { - *to_the_right = tree; - tree = tree->vm_avl_left; - } else { - *to_the_left = tree; - tree = tree->vm_avl_right; - } - } - if (tree != node) { - printk("avl_neighbours: node not exactly found in the tree\n"); - return; - } - if (tree->vm_avl_left != avl_empty) { - struct vm_area_struct * node; - for (node = tree->vm_avl_left; node->vm_avl_right != avl_empty; node = node->vm_avl_right) - continue; - *to_the_left = node; - } - if (tree->vm_avl_right != avl_empty) { - struct vm_area_struct * node; - for (node = tree->vm_avl_right; node->vm_avl_left != avl_empty; node = node->vm_avl_left) - continue; - *to_the_right = node; - } - if ((*to_the_left && ((*to_the_left)->vm_next != node)) || (node->vm_next != *to_the_right)) - printk("avl_neighbours: tree inconsistent with list\n"); -} - -/* - * Rebalance a tree. - * After inserting or deleting a node of a tree we have a sequence of subtrees - * nodes[0]..nodes[k-1] such that - * nodes[0] is the root and nodes[i+1] = nodes[i]->{vm_avl_left|vm_avl_right}. - */ -static inline void avl_rebalance (struct vm_area_struct *** nodeplaces_ptr, int count) -{ - for ( ; count > 0 ; count--) { - struct vm_area_struct ** nodeplace = *--nodeplaces_ptr; - struct vm_area_struct * node = *nodeplace; - struct vm_area_struct * nodeleft = node->vm_avl_left; - struct vm_area_struct * noderight = node->vm_avl_right; - int heightleft = heightof(nodeleft); - int heightright = heightof(noderight); - if (heightright + 1 < heightleft) { - /* */ - /* * */ - /* / \ */ - /* n+2 n */ - /* */ - struct vm_area_struct * nodeleftleft = nodeleft->vm_avl_left; - struct vm_area_struct * nodeleftright = nodeleft->vm_avl_right; - int heightleftright = heightof(nodeleftright); - if (heightof(nodeleftleft) >= heightleftright) { - /* */ - /* * n+2|n+3 */ - /* / \ / \ */ - /* n+2 n --> / n+1|n+2 */ - /* / \ | / \ */ - /* n+1 n|n+1 n+1 n|n+1 n */ - /* */ - node->vm_avl_left = nodeleftright; nodeleft->vm_avl_right = node; - nodeleft->vm_avl_height = 1 + (node->vm_avl_height = 1 + heightleftright); - *nodeplace = nodeleft; - } else { - /* */ - /* * n+2 */ - /* / \ / \ */ - /* n+2 n --> n+1 n+1 */ - /* / \ / \ / \ */ - /* n n+1 n L R n */ - /* / \ */ - /* L R */ - /* */ - nodeleft->vm_avl_right = nodeleftright->vm_avl_left; - node->vm_avl_left = nodeleftright->vm_avl_right; - nodeleftright->vm_avl_left = nodeleft; - nodeleftright->vm_avl_right = node; - nodeleft->vm_avl_height = node->vm_avl_height = heightleftright; - nodeleftright->vm_avl_height = heightleft; - *nodeplace = nodeleftright; - } - } - else if (heightleft + 1 < heightright) { - /* similar to the above, just interchange 'left' <--> 'right' */ - struct vm_area_struct * noderightright = noderight->vm_avl_right; - struct vm_area_struct * noderightleft = noderight->vm_avl_left; - int heightrightleft = heightof(noderightleft); - if (heightof(noderightright) >= heightrightleft) { - node->vm_avl_right = noderightleft; noderight->vm_avl_left = node; - noderight->vm_avl_height = 1 + (node->vm_avl_height = 1 + heightrightleft); - *nodeplace = noderight; - } else { - noderight->vm_avl_left = noderightleft->vm_avl_right; - node->vm_avl_right = noderightleft->vm_avl_left; - noderightleft->vm_avl_right = noderight; - noderightleft->vm_avl_left = node; - noderight->vm_avl_height = node->vm_avl_height = heightrightleft; - noderightleft->vm_avl_height = heightright; - *nodeplace = noderightleft; - } - } - else { - int height = (heightleftvm_avl_height) - break; - node->vm_avl_height = height; - } - } -} - -/* Insert a node into a tree. */ -static inline void avl_insert (struct vm_area_struct * new_node, struct vm_area_struct ** ptree) -{ - vm_avl_key_t key = new_node->vm_avl_key; - struct vm_area_struct ** nodeplace = ptree; - struct vm_area_struct ** stack[avl_maxheight]; - int stack_count = 0; - struct vm_area_struct *** stack_ptr = &stack[0]; /* = &stack[stackcount] */ - for (;;) { - struct vm_area_struct * node = *nodeplace; - if (node == avl_empty) - break; - *stack_ptr++ = nodeplace; stack_count++; - if (key < node->vm_avl_key) - nodeplace = &node->vm_avl_left; - else - nodeplace = &node->vm_avl_right; - } - new_node->vm_avl_left = avl_empty; - new_node->vm_avl_right = avl_empty; - new_node->vm_avl_height = 1; - *nodeplace = new_node; - avl_rebalance(stack_ptr,stack_count); -} - -/* Insert a node into a tree, and - * return the node to the left of it and the node to the right of it. - */ -static inline void avl_insert_neighbours (struct vm_area_struct * new_node, struct vm_area_struct ** ptree, - struct vm_area_struct ** to_the_left, struct vm_area_struct ** to_the_right) -{ - vm_avl_key_t key = new_node->vm_avl_key; - struct vm_area_struct ** nodeplace = ptree; - struct vm_area_struct ** stack[avl_maxheight]; - int stack_count = 0; - struct vm_area_struct *** stack_ptr = &stack[0]; /* = &stack[stackcount] */ - *to_the_left = *to_the_right = NULL; - for (;;) { - struct vm_area_struct * node = *nodeplace; - if (node == avl_empty) - break; - *stack_ptr++ = nodeplace; stack_count++; - if (key < node->vm_avl_key) { - *to_the_right = node; - nodeplace = &node->vm_avl_left; - } else { - *to_the_left = node; - nodeplace = &node->vm_avl_right; - } - } - new_node->vm_avl_left = avl_empty; - new_node->vm_avl_right = avl_empty; - new_node->vm_avl_height = 1; - *nodeplace = new_node; - avl_rebalance(stack_ptr,stack_count); -} - -/* Removes a node out of a tree. */ -static inline void avl_remove (struct vm_area_struct * node_to_delete, struct vm_area_struct ** ptree) -{ - vm_avl_key_t key = node_to_delete->vm_avl_key; - struct vm_area_struct ** nodeplace = ptree; - struct vm_area_struct ** stack[avl_maxheight]; - int stack_count = 0; - struct vm_area_struct *** stack_ptr = &stack[0]; /* = &stack[stackcount] */ - struct vm_area_struct ** nodeplace_to_delete; - for (;;) { - struct vm_area_struct * node = *nodeplace; - if (node == avl_empty) { - /* what? node_to_delete not found in tree? */ - printk("avl_remove: node to delete not found in tree\n"); - return; - } - *stack_ptr++ = nodeplace; stack_count++; - if (key == node->vm_avl_key) - break; - if (key < node->vm_avl_key) - nodeplace = &node->vm_avl_left; - else - nodeplace = &node->vm_avl_right; - } - nodeplace_to_delete = nodeplace; - /* Have to remove node_to_delete = *nodeplace_to_delete. */ - if (node_to_delete->vm_avl_left == avl_empty) { - *nodeplace_to_delete = node_to_delete->vm_avl_right; - stack_ptr--; stack_count--; - } else { - struct vm_area_struct *** stack_ptr_to_delete = stack_ptr; - struct vm_area_struct ** nodeplace = &node_to_delete->vm_avl_left; - struct vm_area_struct * node; - for (;;) { - node = *nodeplace; - if (node->vm_avl_right == avl_empty) - break; - *stack_ptr++ = nodeplace; stack_count++; - nodeplace = &node->vm_avl_right; - } - *nodeplace = node->vm_avl_left; - /* node replaces node_to_delete */ - node->vm_avl_left = node_to_delete->vm_avl_left; - node->vm_avl_right = node_to_delete->vm_avl_right; - node->vm_avl_height = node_to_delete->vm_avl_height; - *nodeplace_to_delete = node; /* replace node_to_delete */ - *stack_ptr_to_delete = &node->vm_avl_left; /* replace &node_to_delete->vm_avl_left */ - } - avl_rebalance(stack_ptr,stack_count); -} - -#ifdef DEBUG_AVL - -/* print a list */ -static void printk_list (struct vm_area_struct * vma) -{ - printk("["); - while (vma) { - printk("%08lX-%08lX", vma->vm_start, vma->vm_end); - vma = vma->vm_next; - if (!vma) - break; - printk(" "); - } - printk("]"); -} - -/* print a tree */ -static void printk_avl (struct vm_area_struct * tree) -{ - if (tree != avl_empty) { - printk("("); - if (tree->vm_avl_left != avl_empty) { - printk_avl(tree->vm_avl_left); - printk("<"); - } - printk("%08lX-%08lX", tree->vm_start, tree->vm_end); - if (tree->vm_avl_right != avl_empty) { - printk(">"); - printk_avl(tree->vm_avl_right); - } - printk(")"); - } -} - -static char *avl_check_point = "somewhere"; - -/* check a tree's consistency and balancing */ -static void avl_checkheights (struct vm_area_struct * tree) -{ - int h, hl, hr; - - if (tree == avl_empty) - return; - avl_checkheights(tree->vm_avl_left); - avl_checkheights(tree->vm_avl_right); - h = tree->vm_avl_height; - hl = heightof(tree->vm_avl_left); - hr = heightof(tree->vm_avl_right); - if ((h == hl+1) && (hr <= hl) && (hl <= hr+1)) - return; - if ((h == hr+1) && (hl <= hr) && (hr <= hl+1)) - return; - printk("%s: avl_checkheights: heights inconsistent\n",avl_check_point); -} - -/* check that all values stored in a tree are < key */ -static void avl_checkleft (struct vm_area_struct * tree, vm_avl_key_t key) -{ - if (tree == avl_empty) - return; - avl_checkleft(tree->vm_avl_left,key); - avl_checkleft(tree->vm_avl_right,key); - if (tree->vm_avl_key < key) - return; - printk("%s: avl_checkleft: left key %lu >= top key %lu\n",avl_check_point,tree->vm_avl_key,key); -} - -/* check that all values stored in a tree are > key */ -static void avl_checkright (struct vm_area_struct * tree, vm_avl_key_t key) -{ - if (tree == avl_empty) - return; - avl_checkright(tree->vm_avl_left,key); - avl_checkright(tree->vm_avl_right,key); - if (tree->vm_avl_key > key) - return; - printk("%s: avl_checkright: right key %lu <= top key %lu\n",avl_check_point,tree->vm_avl_key,key); -} - -/* check that all values are properly increasing */ -static void avl_checkorder (struct vm_area_struct * tree) -{ - if (tree == avl_empty) - return; - avl_checkorder(tree->vm_avl_left); - avl_checkorder(tree->vm_avl_right); - avl_checkleft(tree->vm_avl_left,tree->vm_avl_key); - avl_checkright(tree->vm_avl_right,tree->vm_avl_key); -} - -/* all checks */ -static void avl_check (struct task_struct * task, char *caller) -{ - avl_check_point = caller; -/* printk("task \"%s\", %s\n",task->comm,caller); */ -/* printk("task \"%s\" list: ",task->comm); printk_list(task->mm->mmap); printk("\n"); */ -/* printk("task \"%s\" tree: ",task->comm); printk_avl(task->mm->mmap_avl); printk("\n"); */ - avl_checkheights(task->mm->mmap_avl); - avl_checkorder(task->mm->mmap_avl); -} - -#endif - - -/* - * Normal function to fix up a mapping +/* Normal function to fix up a mapping * This function is the default for when an area has no specific * function. This may be used as part of a more specific routine. * This function works out what part of an area is affected and @@ -738,19 +378,11 @@ struct vm_area_struct *mpnt; unsigned long end = addr + len; - if (addr < area->vm_start || addr >= area->vm_end || - end <= area->vm_start || end > area->vm_end || - end < addr) - { - printk("unmap_fixup: area=%lx-%lx, unmap %lx-%lx!!\n", - area->vm_start, area->vm_end, addr, end); - return; - } area->vm_mm->total_vm -= len >> PAGE_SHIFT; if (area->vm_flags & VM_LOCKED) area->vm_mm->locked_vm -= len >> PAGE_SHIFT; - /* Unmapping the whole area */ + /* Unmapping the whole area. */ if (addr == area->vm_start && end == area->vm_end) { if (area->vm_ops && area->vm_ops->close) area->vm_ops->close(area); @@ -759,15 +391,13 @@ return; } - /* Work out to one of the ends */ + /* Work out to one of the ends. */ if (end == area->vm_end) area->vm_end = addr; - else - if (addr == area->vm_start) { + else if (addr == area->vm_start) { area->vm_offset += (end - area->vm_start); area->vm_start = end; - } - else { + } else { /* Unmapping a hole: area->vm_start < addr <= end < area->vm_end */ /* Add end mapping -- leave beginning for below */ mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); @@ -785,7 +415,7 @@ insert_vm_struct(current->mm, mpnt); } - /* construct whatever mapping is needed */ + /* Construct whatever mapping is needed. */ mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!mpnt) return; @@ -809,15 +439,14 @@ return ret; } -/* - * Munmap is split into 2 main parts -- this part which finds +/* Munmap is split into 2 main parts -- this part which finds * what needs doing, and the areas themselves, which do the * work. This now handles partial unmappings. * Jeremy Fitzhardine */ int do_munmap(unsigned long addr, size_t len) { - struct vm_area_struct *mpnt, *prev, *next, **npp, *free; + struct vm_area_struct *mpnt, *next, *free; if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr) return -EINVAL; @@ -825,33 +454,36 @@ if ((len = PAGE_ALIGN(len)) == 0) return 0; - /* - * Check if this memory area is ok - put it on the temporary + /* Check if this memory area is ok - put it on the temporary * list if so.. The checks here are pretty simple -- * every area affected in some way (by any overlap) is put * on the list. If nothing is put on, nothing is affected. */ - mpnt = find_vma(current->mm, addr); + mpnt = current->mm->mmap; + while(mpnt && mpnt->vm_end <= addr) + mpnt = mpnt->vm_next; if (!mpnt) return 0; - avl_neighbours(mpnt, current->mm->mmap_avl, &prev, &next); - /* we have prev->vm_next == mpnt && mpnt->vm_next = next */ - /* and addr < mpnt->vm_end */ - npp = (prev ? &prev->vm_next : ¤t->mm->mmap); + next = mpnt->vm_next; + + /* we have mpnt->vm_next = next and addr < mpnt->vm_end */ free = NULL; - for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) { - *npp = mpnt->vm_next; + for ( ; mpnt && mpnt->vm_start < addr+len; ) { + struct vm_area_struct *next = mpnt->vm_next; + + if(mpnt->vm_next) + mpnt->vm_next->vm_pprev = mpnt->vm_pprev; + *mpnt->vm_pprev = mpnt->vm_next; + mpnt->vm_next = free; free = mpnt; - avl_remove(mpnt, ¤t->mm->mmap_avl); + mpnt = next; } - if (free == NULL) return 0; - /* - * Ok - we have the memory areas we should free on the 'free' list, + /* Ok - we have the memory areas we should free on the 'free' list, * so release them, and unmap the page range.. * If the one of the segments is only being partially unmapped, * it will put new vm_area_struct(s) into the address space. @@ -871,36 +503,27 @@ if (mpnt->vm_ops && mpnt->vm_ops->unmap) mpnt->vm_ops->unmap(mpnt, st, size); + flush_cache_range(current->mm, st, end); zap_page_range(current->mm, st, size); flush_tlb_range(current->mm, st, end); + unmap_fixup(mpnt, st, size); + kmem_cache_free(vm_area_cachep, mpnt); } while (free); - /* we could zap the page tables here too.. */ - + current->mm->mmap_cache = NULL; /* Kill the cache. */ return 0; } -/* Build the AVL tree corresponding to the VMA list. */ -void build_mmap_avl(struct mm_struct * mm) -{ - struct vm_area_struct * vma; - - mm->mmap_avl = NULL; - for (vma = mm->mmap; vma; vma = vma->vm_next) - avl_insert(vma, &mm->mmap_avl); -} - /* Release all mmaps. */ void exit_mmap(struct mm_struct * mm) { struct vm_area_struct * mpnt; mpnt = mm->mmap; - mm->mmap = NULL; - mm->mmap_avl = NULL; + mm->mmap = mm->mmap_cache = NULL; mm->rss = 0; mm->total_vm = 0; mm->locked_vm = 0; @@ -925,81 +548,38 @@ } } -/* - * Insert vm structure into process list sorted by address +/* Insert vm structure into process list sorted by address * and into the inode's i_mmap ring. */ void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) { - struct vm_area_struct *share; + struct vm_area_struct **pprev = &mm->mmap; struct inode * inode; -#if 0 /* equivalent, but slow */ - struct vm_area_struct **p, *mpnt; - - p = &mm->mmap; - while ((mpnt = *p) != NULL) { - if (mpnt->vm_start > vmp->vm_start) - break; - if (mpnt->vm_end > vmp->vm_start) - printk("insert_vm_struct: overlapping memory areas\n"); - p = &mpnt->vm_next; - } - vmp->vm_next = mpnt; - *p = vmp; -#else - struct vm_area_struct * prev, * next; - - avl_insert_neighbours(vmp, &mm->mmap_avl, &prev, &next); - if ((prev ? prev->vm_next : mm->mmap) != next) - printk("insert_vm_struct: tree inconsistent with list\n"); - if (prev) - prev->vm_next = vmp; - else - mm->mmap = vmp; - vmp->vm_next = next; -#endif + /* Find where to link it in. */ + while(*pprev && (*pprev)->vm_start <= vmp->vm_start) + pprev = &(*pprev)->vm_next; + + /* Insert it. */ + if((vmp->vm_next = *pprev) != NULL) + (*pprev)->vm_pprev = &vmp->vm_next; + *pprev = vmp; + vmp->vm_pprev = pprev; inode = vmp->vm_inode; - if (!inode) - return; - - /* insert vmp into inode's circular share list */ - if ((share = inode->i_mmap)) { - vmp->vm_next_share = share->vm_next_share; - vmp->vm_next_share->vm_prev_share = vmp; - share->vm_next_share = vmp; - vmp->vm_prev_share = share; - } else - inode->i_mmap = vmp->vm_next_share = vmp->vm_prev_share = vmp; -} - -/* - * Remove one vm structure from the inode's i_mmap ring. - */ -void remove_shared_vm_struct(struct vm_area_struct *mpnt) -{ - struct inode * inode = mpnt->vm_inode; - - if (!inode) - return; - - if (mpnt->vm_next_share == mpnt) { - if (inode->i_mmap != mpnt) - printk("Inode i_mmap ring corrupted\n"); - inode->i_mmap = NULL; - return; + if (inode) { + if (vmp->vm_flags & VM_DENYWRITE) + inode->i_writecount--; + + /* insert vmp into inode's share list */ + if((vmp->vm_next_share = inode->i_mmap) != NULL) + inode->i_mmap->vm_pprev_share = &vmp->vm_next_share; + inode->i_mmap = vmp; + vmp->vm_pprev_share = &inode->i_mmap; } - - if (inode->i_mmap == mpnt) - inode->i_mmap = mpnt->vm_next_share; - - mpnt->vm_prev_share->vm_next_share = mpnt->vm_next_share; - mpnt->vm_next_share->vm_prev_share = mpnt->vm_prev_share; } -/* - * Merge the list of memory segments if possible. +/* Merge the list of memory segments if possible. * Redundant vm_area_structs are freed. * This assumes that the list is ordered by address. * We don't need to traverse the entire list, only those segments @@ -1010,13 +590,19 @@ struct vm_area_struct *prev, *mpnt, *next; down(&mm->mmap_sem); - mpnt = find_vma(mm, start_addr); + + prev = NULL; + mpnt = mm->mmap; + while(mpnt && mpnt->vm_end <= start_addr) { + prev = mpnt; + mpnt = mpnt->vm_next; + } if (!mpnt) goto no_vma; - avl_neighbours(mpnt, mm->mmap_avl, &prev, &next); - /* we have prev->vm_next == mpnt && mpnt->vm_next = next */ + next = mpnt->vm_next; + /* we have prev->vm_next == mpnt && mpnt->vm_next = next */ if (!prev) { prev = mpnt; mpnt = next; @@ -1026,41 +612,32 @@ * start_addr < mpnt->vm_end && prev->vm_start < end_addr */ for ( ; mpnt && prev->vm_start < end_addr ; prev = mpnt, mpnt = next) { -#if 0 - printk("looping in merge_segments, mpnt=0x%lX\n", (unsigned long) mpnt); -#endif - next = mpnt->vm_next; - /* - * To share, we must have the same inode, operations.. - */ - if (mpnt->vm_inode != prev->vm_inode) - continue; - if (mpnt->vm_pte != prev->vm_pte) - continue; - if (mpnt->vm_ops != prev->vm_ops) - continue; - if (mpnt->vm_flags != prev->vm_flags) + /* To share, we must have the same inode, operations.. */ + if ((mpnt->vm_inode != prev->vm_inode) || + (mpnt->vm_pte != prev->vm_pte) || + (mpnt->vm_ops != prev->vm_ops) || + (mpnt->vm_flags != prev->vm_flags) || + (prev->vm_end != mpnt->vm_start)) continue; - if (prev->vm_end != mpnt->vm_start) - continue; - /* - * and if we have an inode, the offsets must be contiguous.. - */ + + /* and if we have an inode, the offsets must be contiguous.. */ if ((mpnt->vm_inode != NULL) || (mpnt->vm_flags & VM_SHM)) { - if (prev->vm_offset + prev->vm_end - prev->vm_start != mpnt->vm_offset) + unsigned long off = prev->vm_offset+prev->vm_end-prev->vm_start; + if (off != mpnt->vm_offset) continue; } - /* - * merge prev with mpnt and set up pointers so the new + /* merge prev with mpnt and set up pointers so the new * big segment can possibly merge with the next one. * The old unused mpnt is freed. */ - avl_remove(mpnt, &mm->mmap_avl); + if(mpnt->vm_next) + mpnt->vm_next->vm_pprev = mpnt->vm_pprev; + *mpnt->vm_pprev = mpnt->vm_next; + prev->vm_end = mpnt->vm_end; - prev->vm_next = mpnt->vm_next; if (mpnt->vm_ops && mpnt->vm_ops->close) { mpnt->vm_offset += mpnt->vm_end - mpnt->vm_start; mpnt->vm_start = mpnt->vm_end; @@ -1072,6 +649,7 @@ kmem_cache_free(vm_area_cachep, mpnt); mpnt = prev; } + mm->mmap_cache = NULL; /* Kill the cache. */ no_vma: up(&mm->mmap_sem); } @@ -1084,4 +662,11 @@ NULL, NULL); if(!vm_area_cachep) panic("vma_init: Cannot alloc vm_area_struct cache."); + + mm_cachep = kmem_cache_create("mm_struct", + sizeof(struct mm_struct), + sizeof(long) * 4, SLAB_HWCACHE_ALIGN, + NULL, NULL); + if(!mm_cachep) + panic("vma_init: Cannot alloc mm_struct cache."); } diff -u --recursive --new-file v2.1.36/linux/mm/swapfile.c linux/mm/swapfile.c --- v2.1.36/linux/mm/swapfile.c Tue Jan 28 00:02:45 1997 +++ linux/mm/swapfile.c Sun Apr 27 15:08:03 1997 @@ -298,24 +298,25 @@ */ static int try_to_unuse(unsigned int type) { - int nr; unsigned long page = get_free_page(GFP_KERNEL); + struct task_struct *p; if (!page) return -ENOMEM; - nr = 0; - while (nr < NR_TASKS) { - struct task_struct * p = task[nr]; - if (p) { - if (unuse_process(p->mm, type, page)) { - page = get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - continue; - } +again: + read_lock(&tasklist_lock); + for_each_task(p) { + read_unlock(&tasklist_lock); + if(unuse_process(p->mm, type, page)) { + page = get_free_page(GFP_KERNEL); + if(!page) + return -ENOMEM; + goto again; } - nr++; + read_lock(&tasklist_lock); } + read_unlock(&tasklist_lock); + free_page(page); return 0; } diff -u --recursive --new-file v2.1.36/linux/mm/vmscan.c linux/mm/vmscan.c --- v2.1.36/linux/mm/vmscan.c Mon Apr 14 16:28:27 1997 +++ linux/mm/vmscan.c Sun Apr 27 15:08:03 1997 @@ -271,54 +271,72 @@ static int swap_out(unsigned int priority, int dma, int wait) { - static int swap_task; - int loop, counter; + static int skip_factor = 0; + int limit = nr_tasks - 1; + int loop, counter, i; struct task_struct *p; counter = ((PAGEOUT_WEIGHT * nr_tasks) >> 10) >> priority; + if(skip_factor > nr_tasks) + skip_factor = 0; + + read_lock(&tasklist_lock); + p = init_task.next_task; + i = skip_factor; + while(i--) + p = p->next_task; for(; counter >= 0; counter--) { - /* - * Check that swap_task is suitable for swapping. If not, look for - * the next suitable process. - */ + /* Check if task is suitable for swapping. */ loop = 0; while(1) { - if (swap_task >= NR_TASKS) { - swap_task = 1; + if(!--limit) { + limit = nr_tasks - 1; + /* See if all processes are unswappable or + * already swapped out. + */ if (loop) - /* all processes are unswappable or already swapped out */ - return 0; + goto out; loop = 1; } - - p = task[swap_task]; - if (p && p->swappable && p->mm->rss) + if (p->swappable && p->mm->rss) break; - - swap_task++; + if((p = p->next_task) == &init_task) + p = p->next_task; } + skip_factor++; - /* - * Determine the number of pages to swap from this process. - */ + /* Determine the number of pages to swap from this process. */ if (!p->swap_cnt) { - /* Normalise the number of pages swapped by + /* Normalise the number of pages swapped by multiplying by (RSS / 1MB) */ p->swap_cnt = AGE_CLUSTER_SIZE(p->mm->rss); } if (!--p->swap_cnt) - swap_task++; + skip_factor++; + read_unlock(&tasklist_lock); + switch (swap_out_process(p, dma, wait)) { - case 0: - if (p->swap_cnt) - swap_task++; - break; - case 1: - return 1; - default: - break; - } + case 0: + if (p->swap_cnt) + skip_factor++; + break; + case 1: + return 1; + default: + break; + }; + + /* Whoever we swapped may not even exist now, in fact we cannot + * assume anything about the list we were searching previously. + */ + read_lock(&tasklist_lock); + p = init_task.next_task; + i = skip_factor; + while(i--) + p = p->next_task; } +out: + read_unlock(&tasklist_lock); return 0; } diff -u --recursive --new-file v2.1.36/linux/net/socket.c linux/net/socket.c --- v2.1.36/linux/net/socket.c Fri Apr 4 08:52:29 1997 +++ linux/net/socket.c Sun Apr 27 15:08:03 1997 @@ -207,7 +207,6 @@ file->f_op = &socket_file_ops; file->f_mode = 3; file->f_flags = O_RDWR; - file->f_count = 1; file->f_inode = inode; if (inode) inode->i_count++;