diff -u --recursive --new-file v1.1.94/linux/Makefile linux/Makefile --- v1.1.94/linux/Makefile Wed Feb 22 16:53:03 1995 +++ linux/Makefile Thu Feb 23 13:32:28 1995 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 94 +SUBLEVEL = 95 ARCH = i386 diff -u --recursive --new-file v1.1.94/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v1.1.94/linux/arch/alpha/kernel/entry.S Wed Feb 22 16:53:03 1995 +++ linux/arch/alpha/kernel/entry.S Sun Feb 26 20:27:20 1995 @@ -63,7 +63,7 @@ .text .set noat -.align 5 +.align 3 .globl entInt .ent entInt entInt: @@ -74,7 +74,6 @@ addq $1,1,$1 stq $1,0($0) /* set up the arguments to the C interrupt handler */ - bis $30,$30,$19 lda $27,do_entInt jsr $26,($27),do_entInt /* ok, check if we need to do software interrupts */ @@ -91,73 +90,128 @@ 2: stq $1,0($0) RESTORE_ALL rti -.align 5 +.align 3 3: lda $27,do_bottom_half jsr $26,($27),do_bottom_half br $31,1b .end entInt -.align 5 +.align 3 .globl entMM .ent entMM entMM: SAVE_ALL - bis $30,$30,$19 lda $27,do_page_fault jsr $26,($27),do_page_fault RESTORE_ALL rti .end entMM -.align 5 +.align 3 .globl entArith .ent entArith entArith: SAVE_ALL - bis $30,$30,$19 lda $27,do_entArith jsr $26,($27),do_entArith RESTORE_ALL rti .end entArith -.align 5 +.align 3 .globl entIF .ent entIF entIF: SAVE_ALL - bis $30,$30,$19 lda $27,do_entIF jsr $26,($27),do_entIF RESTORE_ALL rti .end entIF -.align 5 +.align 3 .globl entUna .ent entUna entUna: SAVE_ALL - bis $30,$30,$19 lda $27,do_entUna jsr $26,($27),do_entUna RESTORE_ALL rti .end entUna -.align 5 +/* + * Fork() is one of the special system calls: it needs to + * save the callee-saved regs so that the regs can be found + * for the new process.. We save them in the "context switch" + * stack format (see arch/alpha/kernel/process.c). + * + * Also, for the kernel fork, we need to fake the system call + * stack buildup, as we can't do system calls from kernel space. + */ +.align 3 +.globl kernel_fork +.ent kernel_fork +kernel_fork: + subq $30,6*8,$30 + stq $31,0($30) + stq $26,8($30) + stq $29,16($30) + stq $16,24($30) + stq $17,32($30) + stq $18,40($30) + SAVE_ALL + lda $27,sys_fork + jsr $26,($27),sys_fork + br ret_from_sys_call +.end kernel_fork + +.align 3 +.globl sys_fork +.ent sys_fork +sys_fork: + subq $30,64,$30 + stq $9,0($30) + stq $10,8($30) + stq $11,16($30) + stq $12,24($30) + stq $13,32($30) + stq $14,40($30) + stq $15,48($30) + stq $26,56($30) + + bis $30,$30,$16 + lda $27,alpha_fork + jsr $26,($27),alpha_fork + + ldq $9,0($30) + ldq $10,8($30) + ldq $11,16($30) + ldq $12,24($30) + ldq $13,32($30) + ldq $14,40($30) + ldq $15,48($30) + ldq $26,56($30) + ldq $0,64($30) + addq $30,64,$30 + ret $31,($26),1 +.end sys_fork + +.align 3 .globl entSys +.globl ret_from_sys_call .ent entSys entSys: SAVE_ALL - bis $30,$30,$19 lda $27,do_entSys jsr $26,($27),do_entSys + stq $0,0($30) +ret_from_sys_call: RESTORE_ALL rti .end entSys - .align 5 + .align 3 .globl sys_call_table sys_call_table: .quad 0 diff -u --recursive --new-file v1.1.94/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S --- v1.1.94/linux/arch/alpha/kernel/head.S Sun Feb 5 19:31:50 1995 +++ linux/arch/alpha/kernel/head.S Sun Feb 26 16:45:26 1995 @@ -59,7 +59,7 @@ ret ($26) .end rdusp -.align 5 +.align 9 .globl floppy_track_buffer floppy_track_buffer: .space 512*2*MAX_BUFFER_SECTORS,1 diff -u --recursive --new-file v1.1.94/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v1.1.94/linux/arch/alpha/kernel/irq.c Sun Feb 5 19:31:50 1995 +++ linux/arch/alpha/kernel/irq.c Sun Feb 26 20:27:20 1995 @@ -22,6 +22,7 @@ #include #include #include +#include static unsigned char cache_21 = 0xff; static unsigned char cache_A1 = 0xff; @@ -374,8 +375,9 @@ printk("Machine check\n"); } -asmlinkage void do_entInt(unsigned long type, unsigned long vector, - unsigned long la_ptr, struct pt_regs *regs) +asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs regs) { switch (type) { case 0: @@ -383,13 +385,13 @@ break; case 1: /* timer interrupt.. */ - handle_irq(0, regs); + handle_irq(0, ®s); return; case 2: - machine_check(vector, la_ptr, regs); + machine_check(vector, la_ptr, ®s); break; case 3: - device_interrupt(vector, regs); + device_interrupt(vector, ®s); return; case 4: printk("Performance counter interrupt\n"); @@ -397,7 +399,7 @@ default: printk("Hardware intr %ld %lx? Huh?\n", type, vector); } - printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps); + printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps); } extern asmlinkage void entInt(void); @@ -405,4 +407,8 @@ void init_IRQ(void) { wrent(entInt, 0); + dma_outb(0, DMA1_RESET_REG); + dma_outb(0, DMA2_RESET_REG); + dma_outb(0, DMA1_CLR_MASK_REG); + dma_outb(0, DMA2_CLR_MASK_REG); } diff -u --recursive --new-file v1.1.94/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v1.1.94/linux/arch/alpha/kernel/process.c Wed Feb 22 16:53:03 1995 +++ linux/arch/alpha/kernel/process.c Fri Feb 24 16:41:00 1995 @@ -43,7 +43,8 @@ void show_regs(struct pt_regs * regs) { - printk("\nPS: %04lx PC: %016lx\n", regs->ps, regs->pc); + printk("\nps: %04lx pc: %016lx\n", regs->ps, regs->pc); + printk("rp: %04lx sp: %p\n", regs->r26, regs+1); } /* @@ -51,28 +52,88 @@ */ void exit_thread(void) { - halt(); } void flush_thread(void) { - halt(); } +struct alpha_switch_stack { + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; + unsigned long r26; +}; + +/* + * "alpha_switch_to()".. Done completely in assembly, due to the + * fact that we obviously don't returns to the caller directly. + * Also, we have to save the regs that the C compiler expects to be + * saved across a function call.. (9-15) + * + * NOTE! The stack switches from under us when we do the swpctx call: + * this *looks* like it restores the same registers that it just saved, + * but it actually restores the new context regs and return address. + */ +__asm__(".align 3\n\t" + ".globl alpha_switch_to\n\t" + ".ent alpha_switch_to\n" + "alpha_switch_to:\n\t" + "subq $30,64,$30\n\t" + "stq $9,0($30)\n\t" + "stq $10,8($30)\n\t" + "stq $11,16($30)\n\t" + "stq $12,24($30)\n\t" + "stq $13,32($30)\n\t" + "stq $14,40($30)\n\t" + "stq $15,48($30)\n\t" + "stq $26,56($30)\n\t" + "call_pal 48\n\t" + "ldq $9,0($30)\n\t" + "ldq $10,8($30)\n\t" + "ldq $11,16($30)\n\t" + "ldq $12,24($30)\n\t" + "ldq $13,32($30)\n\t" + "ldq $14,40($30)\n\t" + "ldq $15,48($30)\n\t" + "ldq $26,56($30)\n\t" + "addq $30,64,$30\n\t" + "ret $31,($26),1\n\t" + ".end alpha_switch_to"); + /* - * This needs some work still.. + * "alpha_fork()".. By the time we get here, the + * non-volatile registers have also been saved on the + * stack. We do some ugly pointer stuff here.. (see + * also copy_thread) + */ +int alpha_fork(struct alpha_switch_stack * swstack) +{ + return do_fork(COPYVM | SIGCHLD, 0, (struct pt_regs *) (swstack+1)); +} + +/* + * Copy an alpha thread.. */ void copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; + struct alpha_switch_stack * childstack, *stack; - p->tss.usp = usp; childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; *childregs = *regs; - p->tss.ksp = (unsigned long) childregs; -/* p->tss.pc = XXXX; */ - panic("copy_thread not implemented"); + childregs->r0 = 0; + regs->r0 = p->pid; + stack = ((struct alpha_switch_stack *) regs) - 1; + childstack = ((struct alpha_switch_stack *) childregs) - 1; + *childstack = *stack; + p->tss.usp = usp; + p->tss.ksp = (unsigned long) childstack; } /* @@ -108,16 +169,9 @@ } /* - * sys_fork() does the obvious thing, but not the obvious way. - * See sys_execve() above. + * This doesn't actually work correctly like this: we need to do the + * same stack setups that fork() does first. */ -asmlinkage int sys_fork(unsigned long a0, unsigned long a1, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - struct pt_regs regs) -{ - return do_fork(COPYVM | SIGCHLD, rdusp(), ®s); -} - asmlinkage int sys_clone(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) diff -u --recursive --new-file v1.1.94/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v1.1.94/linux/arch/alpha/kernel/setup.c Sun Feb 5 19:31:50 1995 +++ linux/arch/alpha/kernel/setup.c Fri Feb 24 16:41:00 1995 @@ -74,6 +74,7 @@ static char cmdline[] = ""; extern int _end; + ROOT_DEV = 0x0200; /* fd0 */ aux_device_present = 0xaa; *cmdline_p = cmdline; *memory_start_p = (unsigned long) &_end; diff -u --recursive --new-file v1.1.94/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c --- v1.1.94/linux/arch/alpha/kernel/traps.c Wed Feb 22 16:53:03 1995 +++ linux/arch/alpha/kernel/traps.c Sun Feb 26 20:27:20 1995 @@ -15,27 +15,34 @@ unsigned long i; printk("%s %ld\n", str, err); - printk("PC = %016lx PS = %04lx\n", regs->pc, regs->ps); + printk("pc = %016lx ps = %04lx\n", regs->pc, regs->ps); + printk("rp = %016lx sp = %p\n", regs->r26, regs+1); for (i = 0 ; i < 5000000000 ; i++) /* pause */; halt(); } -asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, unsigned long a2, struct pt_regs * regs) +asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, + unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs regs) { printk("Arithmetic trap: %02lx %016lx\n", summary, write_mask); - die_if_kernel("Arithmetic fault", regs, 0); + die_if_kernel("Arithmetic fault", ®s, 0); } -asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2, struct pt_regs * regs) +asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs regs) { - die_if_kernel("Instruction fault", regs, type); + die_if_kernel("Instruction fault", ®s, type); } -asmlinkage void do_entUna(unsigned long va, unsigned long opcode, unsigned long reg, struct pt_regs * regs) +asmlinkage void do_entUna(unsigned long va, unsigned long opcode, unsigned long reg, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs regs) { printk("Unaligned trap: %016lx %ld %ld\n", va, opcode, reg); - die_if_kernel("Unaligned", regs, 0); + die_if_kernel("Unaligned", ®s, 0); } /* @@ -49,10 +56,11 @@ * are a thinko. DEC palcode is strange. The PAL-code designers probably * got terminally tainted by VMS at some point. */ -asmlinkage void do_entSys(unsigned long sysnr, unsigned long arg1, unsigned long arg2, struct pt_regs *regs) +asmlinkage void do_entSys(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { - printk("System call %ld(%ld,%ld)\n", sysnr, arg1, arg2); - die_if_kernel("Syscall", regs, 0); + printk("System call %ld(%ld,%ld)\n", regs.r0, a0, a1); + die_if_kernel("Syscall", ®s, 0); } extern asmlinkage void entMM(void); diff -u --recursive --new-file v1.1.94/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c --- v1.1.94/linux/arch/alpha/mm/fault.c Wed Feb 1 09:23:04 1995 +++ linux/arch/alpha/mm/fault.c Thu Mar 2 09:04:40 1995 @@ -24,12 +24,11 @@ /* * This routine handles page faults. It determines the address, - * and the problem, and then passes it off to one of the appropriate - * routines. + * and the problem, and then passes it off to handle_mm_fault(). * * mmcsr: - * 0 = translation not valid (= do_no_page()) - * 1 = access violation (= user tries to access kernel pages) + * 0 = translation not valid + * 1 = access violation * 2 = fault-on-read * 3 = fault-on-execute * 4 = fault-on-write @@ -39,13 +38,12 @@ * 0 = load * 1 = store */ -asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, - long cause, struct pt_regs * regs) +asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long cause, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs regs) { struct vm_area_struct * vma; - if (mmcsr == 1) - goto bad_area; vma = find_vma(current, address); if (!vma) goto bad_area; @@ -73,11 +71,7 @@ goto bad_area; } - if (mmcsr) { - do_wp_page(vma, address, cause > 0); - return; - } - do_no_page(vma, address, cause > 0); + handle_mm_fault(vma, address, cause > 0); return; /* @@ -85,7 +79,7 @@ * Fix it, but check if it's kernel or user first.. */ bad_area: - if (user_mode(regs)) { + if (user_mode(®s)) { send_sig(SIGSEGV, current, 1); return; } @@ -94,6 +88,6 @@ * terminate things with extreme prejudice. */ printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %08lx\n",address); - die_if_kernel("Oops", regs, cause); + die_if_kernel("Oops", ®s, cause); do_exit(SIGKILL); } diff -u --recursive --new-file v1.1.94/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v1.1.94/linux/arch/i386/Makefile Fri Jan 13 10:12:22 1995 +++ linux/arch/i386/Makefile Sat Feb 25 15:55:27 1995 @@ -52,6 +52,12 @@ DRIVERS := $(DRIVERS) arch/i386/math-emu/math.a endif +arch/i386/kernel: dummy + $(MAKE) linuxsubdirs SUBDIRS=arch/i386/kernel + +arch/i386/mm: dummy + $(MAKE) linuxsubdirs SUBDIRS=arch/i386/mm + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot zImage: vmlinux diff -u --recursive --new-file v1.1.94/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v1.1.94/linux/arch/i386/kernel/irq.c Mon Jan 16 14:18:13 1995 +++ linux/arch/i386/kernel/irq.c Thu Mar 2 08:39:22 1995 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -360,4 +361,6 @@ printk("Unable to get IRQ2 for cascade\n"); if (request_irq(13,math_error_irq, 0, "math error")) printk("Unable to get IRQ13 for math-error handler\n"); -} + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); +} diff -u --recursive --new-file v1.1.94/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v1.1.94/linux/arch/i386/kernel/process.c Wed Feb 22 16:53:03 1995 +++ linux/arch/i386/kernel/process.c Wed Mar 1 08:43:07 1995 @@ -105,7 +105,7 @@ printk(" ESP: %04x:%08lx",0xffff & regs->ss,regs->esp); printk(" EFLAGS: %08lx\n",regs->eflags); printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", - regs->orig_eax,regs->ebx,regs->ecx,regs->edx); + regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", regs->esi, regs->edi, regs->ebp); printk(" DS: %04x ES: %04x FS: %04x GS: %04x\n", @@ -237,6 +237,7 @@ asmlinkage int sys_clone(struct pt_regs regs) { +#ifdef CLONE_ACTUALLY_WORKS_OK unsigned long clone_flags; unsigned long newsp; @@ -247,6 +248,9 @@ if (newsp == regs.esp) clone_flags |= COPYVM; return do_fork(clone_flags, newsp, ®s); +#else + return -ENOSYS; +#endif } /* diff -u --recursive --new-file v1.1.94/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c --- v1.1.94/linux/arch/i386/kernel/ptrace.c Wed Feb 22 16:53:03 1995 +++ linux/arch/i386/kernel/ptrace.c Sat Feb 25 15:36:18 1995 @@ -155,7 +155,7 @@ } pgmiddle = pmd_offset(pgdir, addr); if (pmd_none(*pgmiddle)) { - do_no_page(vma, addr, 0); + do_no_page(vma, addr, 1); goto repeat; } if (pmd_bad(*pgmiddle)) { diff -u --recursive --new-file v1.1.94/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v1.1.94/linux/arch/i386/kernel/setup.c Mon Jan 30 06:41:55 1995 +++ linux/arch/i386/kernel/setup.c Thu Feb 23 13:31:58 1995 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -122,4 +123,12 @@ *cmdline_p = command_line; *memory_start_p = memory_start; *memory_end_p = memory_end; + /* request io space for devices used on all i[345]86 PC'S */ + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x70,0x10,"rtc"); + request_region(0x80,0x20,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + request_region(0xf0,0x2,"npu"); + request_region(0xf8,0x8,"npu"); } diff -u --recursive --new-file v1.1.94/linux/arch/sparc/config.in linux/arch/sparc/config.in --- v1.1.94/linux/arch/sparc/config.in Fri Feb 17 11:20:11 1995 +++ linux/arch/sparc/config.in Sun Feb 26 20:46:20 1995 @@ -13,6 +13,8 @@ bool 'Sparc V8 kernel' CONFIG_SPARC_V8 y bool 'Sparc SMP support' CONFIG_LINUX_SMP n +bool 'Sparc SUN4M support' CONFIG_SUN4M n +bool 'Sparc Reference MMU' CONFIG_SRMMU n bool 'Networking support' CONFIG_NET n bool 'Limit memory to low 16MB' CONFIG_MAX_16M n bool 'System V IPC' CONFIG_SYSVIPC y diff -u --recursive --new-file v1.1.94/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S --- v1.1.94/linux/arch/sparc/kernel/head.S Mon Feb 20 21:34:54 1995 +++ linux/arch/sparc/kernel/head.S Sun Feb 26 20:46:20 1995 @@ -155,13 +155,13 @@ boot_msg: .ascii "Booting Sparc-Linux V0.00PRE-ALPHA " .ascii WHO_COMPILED_ME - .asciz " \n" + .ascii "\r\n" .align 4 .globl boot_msg2 boot_msg2: - .asciz "Booting Sparclinux V0.00 PRE-ALPHA on a (SUN4C)\n\n" + .asciz "Booting Sparclinux V0.00 PRE-ALPHA on a (SUN4C)\r\n\n" .align 4 @@ -250,20 +250,20 @@ /* Level'd interrupt entry points, see macro defs above */ - TRAP_ENTRY_INTERRUPT_SOFT(1, 0x101) /* Interrupt Level 1 */ - TRAP_ENTRY_INTERRUPT(2) /* Interrupt Level 2 */ - TRAP_ENTRY_INTERRUPT(3) /* Interrupt Level 3 */ - TRAP_ENTRY_INTERRUPT_SOFT(4, 0x104) /* Interrupt Level 4 */ - TRAP_ENTRY_INTERRUPT(5) /* Interrupt Level 5 */ - TRAP_ENTRY_INTERRUPT_SOFT(6, 0x106) /* Interrupt Level 6 */ - TRAP_ENTRY_INTERRUPT(7) /* Interrupt Level 7 */ - TRAP_ENTRY_INTERRUPT(8) /* Interrupt Level 8 */ - TRAP_ENTRY_INTERRUPT(9) /* Interrupt Level 9 */ - TRAP_ENTRY_INTERRUPT(10) /* Interrupt Level 10 */ - TRAP_ENTRY_INTERRUPT(11) /* Interrupt Level 11 */ - TRAP_ENTRY_INTERRUPT(12) /* Interrupt Level 12 */ - TRAP_ENTRY_INTERRUPT(13) /* Interrupt Level 13 */ - TRAP_ENTRY_TIMER /* Interrupt Level 14 */ + TRAP_ENTRY_INTERRUPT_SOFT(1, 0x101) /* IRQ Software/SBUS Level 1 */ + TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */ + TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */ + TRAP_ENTRY_INTERRUPT_SOFT(4, 0x104) /* IRQ Software Level 4 */ + TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */ + TRAP_ENTRY_INTERRUPT_SOFT(6, 0x106) /* IRQ Software Level 6 */ + TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */ + TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */ + TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */ + TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 */ + TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */ + TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */ + TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */ + TRAP_ENTRY_TIMER /* IRQ Timer #2 (one we use) */ TRAP_ENTRY_INTERRUPT_NMI(15, linux_trap_nmi) /* Level 15 (nmi) */ TRAP_ENTRY(0x20, my_trap_handler) /* General Register Access Error */ @@ -541,6 +541,15 @@ be found_v2 nop + /* paul@sfe.com.au */ + subcc %o3, 0x3, %g0 ! a v3 prom? + or %g0, 0x3, %o5 + sethi %hi(C_LABEL(prom_iface_vers) ), %g1 + st %o5, [%g1 + %lo( C_LABEL(prom_iface_vers) )] + be not_v2 + nop + + /* Old sun4's pass our load address into %o0 instead of the prom pointer. On sun4's you have to hard code the romvec pointer into your code. Sun probably still does that because they don't even @@ -654,6 +663,15 @@ * as the prom expects. */ +/* paul@sfe.com.au */ +/* V3 doesnt have printf.. And I dont really feel like doing the formatting + * myself.. So we miss out on some messages (for now). + */ + ld [%g7 + 0x4], %o0 + subcc %o3, 0x3, %g0 + be v3_bootmsg + nop + sethi %hi(boot_msg), %o0 or %o0, %lo(boot_msg), %o0 sethi %hi(prom_printf), %o1 @@ -687,6 +705,28 @@ b rest_of_boot nop +v3_bootmsg: + ld [%g7 + 0x94], %o0 + ld [%o0], %o0 + sethi %hi(boot_msg), %o1 + or %o1, %lo(boot_msg), %o1 + mov BOOT_MSG_LEN, %o2 + ld [%g7 + 0xb8], %o4 + call %o4 + nop + + ld [%g7 + 0x94], %o0 + ld [%o0], %o0 + sethi %hi(boot_msg2), %o1 + or %o1, %lo(boot_msg2), %o1 + mov BOOT_MSG2_LEN, %o2 + ld [%g7 + 0xb8], %o4 + call %o4 + nop + b rest_of_boot + nop + + no_sun4_here: ld [%g7 + 0x68], %o1 set sun4_notsup, %o0 @@ -723,7 +763,9 @@ srl %l2, %g5, %l2 or %l2, %l3, %l1 +#ifndef CONFIG_SRMMU sta %l1, [%l0] ASI_PTE +#endif or %g0, 0x1, %l1 stb %l1, [%l0] @@ -856,9 +898,13 @@ /* Here we go */ +#ifndef CONFIG_SUN4M + /* paul@sfe.com.au */ + /* Look into traps later :( */ set C_LABEL(trapbase), %g3 wr %g3, 0x0, %tbr WRITE_PAUSE +#endif /* First we call init_prom() to set up romvec, then off to start_kernel() */ diff -u --recursive --new-file v1.1.94/linux/arch/sparc/kernel/probe.c linux/arch/sparc/kernel/probe.c --- v1.1.94/linux/arch/sparc/kernel/probe.c Mon Feb 20 21:34:54 1995 +++ linux/arch/sparc/kernel/probe.c Wed Mar 1 09:12:33 1995 @@ -4,11 +4,13 @@ */ #include +#include #include #include #include #include #include +#include /* #define DEBUG_PROBING */ @@ -83,7 +85,7 @@ { 2, 0, "Bipolar Integrated Technology - B5010"}, { 3, 0, "LSI Logic Corporation - unknown-type"}, { 4, 0, "Texas Instruments, Inc. - unknown"}, - { 4, 1, "Texas Instruments, Inc. - unknown"}, + { 4, 1, "Texas Instruments, Inc. - Sparc Classic"}, { 4, 2, "Texas Instruments, Inc. - unknown"}, { 4, 3, "Texas Instruments, Inc. - unknown"}, { 4, 4, "Texas Instruments, Inc. - unknown"}, @@ -119,7 +121,10 @@ void probe_cpu(void) { - register int psr_impl, psr_vers, fpu_vers, i; + register int psr_impl=0; + register int psr_vers = 0; + register int fpu_vers = 0; + register int i = 0; unsigned int tmp_fsr; &tmp_fsr; /* GCC grrr... */ @@ -195,6 +200,7 @@ { register unsigned int x,y; +#ifndef CONFIG_SRMMU vac_size = find_vac_size(); vac_linesize = find_vac_linesize(); vac_do_hw_vac_flushes = find_vac_hwflushes(); @@ -223,6 +229,7 @@ x=enable_vac(); printk("ENABLED\n"); +#endif return; } @@ -233,7 +240,7 @@ find_mmu_num_segmaps(); find_mmu_num_contexts(); - printk("\nMMU segmaps: %d MMU contexts: %d\n", num_segmaps, + printk("MMU segmaps: %d MMU contexts: %d\n", num_segmaps, num_contexts); return; @@ -275,7 +282,7 @@ } } - printk("%s\n", node_str); + printk("Mostek %s\n", node_str); printk("At OBIO address: 0x%x Virtual address: 0x%x\n", (unsigned int) TIMER_PHYSADDR, (unsigned int) TIMER_STRUCT); @@ -299,49 +306,13 @@ printk("\nProbing ESP:\n"); lbuf = get_str_from_prom(nd, "name", promstr_buf); - printk("\nProperty length for %s: 0x%x\n", "name", - *get_int_from_prom(nd, "name", promint_buf)); - if(*get_int_from_prom(nd, "name", promint_buf) != 0) - printk("Node: 0x%x Name: %s", nd, lbuf); - - lbuf = get_str_from_prom(nd, "device-type", promstr_buf); - - printk("\nProperty length for %s: 0x%x\n", "device_type", - *get_int_from_prom(nd, "device_type", promint_buf)); - - if(*get_int_from_prom(nd, "device-type", promint_buf) != 0) - printk("Device-Type: %s ", lbuf); - - lbuf = get_str_from_prom(nd, "model", promstr_buf); - - printk("\nProperty length for %s: 0x%x\n", "model", - *get_int_from_prom(nd, "model", promint_buf)); - - if(*get_int_from_prom(nd, "model", promint_buf) != 0) - printk("Model: %s", lbuf); - - printk("\n"); - - while((nd = node_get_sibling(nd)) != 0) - { - lbuf = get_str_from_prom(nd, "name", promstr_buf); - - if(*get_int_from_prom(nd, "name", promint_buf) != 0) - printk("Node: 0x%x Name: %s ", nd, lbuf); - - lbuf = get_str_from_prom(nd, "device-type", promstr_buf); - - if(*get_int_from_prom(nd, "device-type", promint_buf) != 0) - printk("Device-Type: %s ", lbuf); - - lbuf = get_str_from_prom(nd, "model", promstr_buf); - - if(*get_int_from_prom(nd, "model", promint_buf) != 0) - printk("Model: %s", lbuf); + printk("Node: 0x%x Name: %s\n", nd, lbuf); - printk("\n"); - } + while((nd = node_get_sibling(nd)) != 0) { + lbuf = get_str_from_prom(nd, "name", promstr_buf); + printk("Node: 0x%x Name: %s\n", nd, lbuf); + } printk("\n"); @@ -358,40 +329,44 @@ lbuf = (char *) 0; - while((nd = node_get_sibling(nd)) != 0) - { - lbuf = get_str_from_prom(nd, "name", promstr_buf); - if(lbuf[0]=='s' && lbuf[1]=='b' && lbuf[2]=='u' && lbuf[3]=='s') - break; - } + while((nd = node_get_sibling(nd)) != 0) { + lbuf = get_str_from_prom(nd, "name", promstr_buf); + if(strcmp(lbuf, "sbus") == 0) + break; + }; + nd = node_get_child(nd); printk("Node: 0x%x Name: %s\n", nd, get_str_from_prom(nd, "name", promstr_buf)); - if(lbuf[0]=='e' && lbuf[1]=='s' && lbuf[2]=='p') + if(strcmp(lbuf, "esp") == 0) { probe_esp(nd); + }; - while((nd = node_get_sibling(nd)) != 0) - { - printk("Node: 0x%x Name: %s\n", nd, - get_str_from_prom(nd, "name", promstr_buf)); - - if(lbuf[0]=='e' && lbuf[1]=='s' && lbuf[2]=='p') - { - savend = nd; - probe_esp(nd); - nd = savend; - } - } + while((nd = node_get_sibling(nd)) != 0) { + printk("Node: 0x%x Name: %s\n", nd, + lbuf = get_str_from_prom(nd, "name", promstr_buf)); + + if(strcmp(lbuf, "esp") == 0) { + savend = nd; + probe_esp(nd); + nd = savend; + }; + }; + printk("\n"); return; } +extern unsigned long probe_memory(void); +extern struct sparc_phys_banks sp_banks[14]; +unsigned int phys_bytes_of_ram, end_of_phys_memory; + void probe_devices(void) { - register int nd; + register int nd, i; register char* str; nd = prom_node_root; @@ -399,15 +374,18 @@ printk("PROBING DEVICES:\n"); str = get_str_from_prom(nd, "device_type", promstr_buf); - printk("Root Node: 0x%x ", nd); + if(strcmp(str, "cpu") == 0) { + printk("Found CPU root prom device tree node.\n"); + } else { + printk("Root node in device tree was not 'cpu' cannot continue.\n"); + halt(); + }; #ifdef DEBUG_PROBING printk("String address for d_type: 0x%x\n", (unsigned int) str); printk("str[0] = %c str[1] = %c str[2] = %c \n", str[0], str[1], str[2]); #endif - printk("Device Type: %s ", str); - str = get_str_from_prom(nd, "name", promstr_buf); #ifdef DEBUG_PROBING @@ -421,29 +399,34 @@ /* Ok, here will go a call to each specific device probe. We can - call these now that we have the 'root' node and the child of - this node to send to the routines. ORDER IS IMPORTANT! -*/ + * call these now that we have the 'root' node and the child of + * this node to send to the routines. ORDER IS IMPORTANT! + */ probe_cpu(); probe_vac(); probe_mmu(); + phys_bytes_of_ram = probe_memory(); + + printk("Physical Memory: %d bytes\n", (int) phys_bytes_of_ram); + for(i=0; sp_banks[i].num_bytes != 0; i++) { + printk("Bank %d: base 0x%x bytes %d\n", i, + (unsigned int) sp_banks[i].base_addr, + (int) sp_banks[i].num_bytes); + end_of_phys_memory = sp_banks[i].base_addr + sp_banks[i].num_bytes; + } -/* printk("PROM Root Child Node: 0x%x Name: %s \n", nd, get_str_from_prom(nd, "name", promstr_buf)); - while((nd = node_get_sibling(nd)) != 0) - { - - printk("Node: 0x%x Name: %s\n", nd, - get_str_from_prom(nd, "name", promstr_buf)); - - } + while((nd = node_get_sibling(nd)) != 0) { + printk("Node: 0x%x Name: %s", nd, + get_str_from_prom(nd, "name", promstr_buf)); + printk("\n"); + }; printk("\nProbing SBUS:\n"); probe_sbus(first_descent); -*/ return; } diff -u --recursive --new-file v1.1.94/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c --- v1.1.94/linux/arch/sparc/kernel/process.c Sun Feb 5 19:31:51 1995 +++ linux/arch/sparc/kernel/process.c Sun Feb 26 20:46:20 1995 @@ -76,15 +76,16 @@ halt(); } -unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct * p, struct pt_regs * regs) +void copy_thread(int nr, unsigned long clone_flags, unsigned long sp, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; p->tss.usp = (unsigned long) childregs; *childregs = *regs; + childregs->sp = sp; p->tss.psr = regs->psr; /* for condition codes */ - return clone_flags; + return; } /* @@ -93,6 +94,11 @@ void dump_thread(struct pt_regs * regs, struct user * dump) { return; /* solaris does this enough */ +} + +asmlinkage int sys_fork(struct pt_regs regs) +{ + return do_fork(COPYVM | SIGCHLD, regs.sp, ®s); } /* diff -u --recursive --new-file v1.1.94/linux/arch/sparc/kernel/promops.c linux/arch/sparc/kernel/promops.c --- v1.1.94/linux/arch/sparc/kernel/promops.c Sun Feb 5 19:31:51 1995 +++ linux/arch/sparc/kernel/promops.c Sun Feb 26 20:46:20 1995 @@ -9,7 +9,7 @@ #include /* #define DEBUG_PROMOPS */ -#define MAX_PR_LEN 16 /* exotic hardware probably overshoots this */ +#define MAX_PR_LEN 64 /* exotic hardware probably overshoots this */ int prom_node_root; /* initialized in init_prom */ @@ -37,12 +37,14 @@ * the default return value is -1 is the prom has nothing interesting. */ +unsigned int prom_int_null; + unsigned int * get_int_from_prom(int node, char *nd_prop, unsigned int *value) { unsigned int pr_len; - *value = 0; /* duh, I was returning -1 as an unsigned int, prom_panic() */ + *value = &prom_int_null; /* duh, I was returning -1 as an unsigned int, prom_panic() */ pr_len = romvec->pv_nodeops->no_proplen(node, nd_prop); if(pr_len > MAX_PR_LEN) @@ -99,6 +101,7 @@ { romvec = r_ptr; prom_node_root = romvec->pv_nodeops->no_nextnode(0); + prom_int_null = 0; return; } diff -u --recursive --new-file v1.1.94/linux/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c --- v1.1.94/linux/arch/sparc/kernel/setup.c Mon Feb 20 21:34:54 1995 +++ linux/arch/sparc/kernel/setup.c Sun Feb 26 20:46:20 1995 @@ -52,7 +52,8 @@ } /* Lame prom console routines, gets registered below. Thanks for the - * tip Linus. + * tip Linus. First comes the V0 prom routine, then the V3 version + * writen by Paul Hatchman (paul@sfe.com.au). */ void sparc_console_print(const char * p) @@ -69,6 +70,24 @@ } +/* paul@sfe.com.au */ +/* V3 prom console printing routines */ +void sparc_console_print_v3 (const char *p) +{ + unsigned char c; + + while ((c = *(p++)) != 0) + { + if (c == '\n') romvec->pv_v2devops.v2_dev_write + ((*romvec->pv_v2bootargs.fd_stdout), "\r", 1); + romvec->pv_v2devops.v2_dev_write + ((*romvec->pv_v2bootargs.fd_stdout), &c, 1); + } + + return; +} + + /* This routine will in the future do all the nasty prom stuff * to probe for the mmu type and it's parameters, etc. This will * also be where SMP things happen plus the Sparc specific memory @@ -76,23 +95,23 @@ */ extern void register_console(void (*proc)(const char *)); +extern unsigned int prom_iface_vers, end_of_phys_memory; void setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p) { - extern int _end; - - register_console(sparc_console_print); + if(romvec->pv_romvers == 0) { + register_console(sparc_console_print); + } else { + register_console(sparc_console_print_v3); + }; printk("Sparc PROM-Console registered...\n"); - - printk("calling get_idprom...\n"); get_idprom(); /* probe_devices expects this to be done */ - - printk("calling probe_devices...\n"); probe_devices(); /* cpu/fpu, mmu probes */ *memory_start_p = (((unsigned long) &end)); + *memory_end_p = (((unsigned long) end_of_phys_memory)); } asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on) diff -u --recursive --new-file v1.1.94/linux/arch/sparc/mm/fault.c linux/arch/sparc/mm/fault.c --- v1.1.94/linux/arch/sparc/mm/fault.c Wed Feb 22 16:53:03 1995 +++ linux/arch/sparc/mm/fault.c Sun Feb 26 20:46:20 1995 @@ -12,6 +12,8 @@ #include extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */ +extern struct sparc_phys_banks sp_banks[14]; + extern void die_if_kernel(char *,struct pt_regs *,long); struct linux_romvec *romvec; @@ -49,28 +51,30 @@ { register struct linux_romvec *lprom; register struct linux_mlist_v0 *mlist; - register unsigned long bytes, base_paddr; + register unsigned long bytes, base_paddr, tally; register int i; - bytes = 0; + bytes = tally = 0; base_paddr = 0; + i=0; lprom = romvec; switch(lprom->pv_romvers) { case 0: mlist=(*(lprom->pv_v0mem.v0_totphys)); - bytes=mlist->num_bytes; + bytes = tally = mlist->num_bytes; base_paddr = (unsigned long) mlist->start_adr; - printk("Bank 1: starting at 0x%x holding %d bytes\n", - (unsigned int) base_paddr, (int) bytes); - i=1; - if(mlist->theres_more != (void *)0) - { + + sp_banks[0].base_addr = base_paddr; + sp_banks[0].num_bytes = bytes; + + if(mlist->theres_more != (void *)0) { i++; mlist=mlist->theres_more; - bytes+=mlist->num_bytes; - printk("Bank %d: starting at 0x%x holding %d bytes\n", i, - (unsigned int) mlist->start_adr, (int) mlist->num_bytes); + bytes=mlist->num_bytes; + tally += bytes; + sp_banks[i].base_addr = (unsigned long) mlist->start_adr; + sp_banks[i].num_bytes = mlist->num_bytes; } break; case 2: @@ -78,10 +82,12 @@ (*(lprom->pv_halt))(); break; } - printk("Physical memory: %d bytes starting at va 0x%x\n", - (unsigned int) bytes, (int) base_paddr); - return bytes; + i++; + sp_banks[i].base_addr = 0xdeadbeef; + sp_banks[i].num_bytes = 0; + + return tally; } /* Sparc routine to reserve the mapping of the open boot prom */ diff -u --recursive --new-file v1.1.94/linux/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c --- v1.1.94/linux/arch/sparc/mm/init.c Wed Feb 22 16:53:03 1995 +++ linux/arch/sparc/mm/init.c Wed Mar 1 09:12:33 1995 @@ -29,6 +29,8 @@ extern int map_the_prom(int); +struct sparc_phys_banks sp_banks[14]; +unsigned long *sun4c_mmu_table; extern int invalid_segment, num_segmaps, num_contexts; /* @@ -102,8 +104,11 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) { - int pg_segmap = 0; unsigned long i, a, b, mask=0; + unsigned long curseg, curpte, num_inval; + unsigned long address; + pte_t *pg_table; + register int num_segs, num_ctx; register char * c; @@ -113,6 +118,8 @@ num_segs -= 1; invalid_segment = num_segs; + start_mem = free_area_init(start_mem, end_mem); + /* On the sparc we first need to allocate the segmaps for the * PROM's virtual space, and make those segmaps unusable. We * map the PROM in ALL contexts therefore the break key and the @@ -125,11 +132,82 @@ start_mem = PAGE_ALIGN(start_mem); + /* Set up static page tables in kernel space, this will be used + * so that the low-level page fault handler can fill in missing + * TLB entries since all mmu entries cannot be loaded at once + * on the sun4c. + */ + +#if 0 + /* ugly debugging code */ + for(i=0; i<40960; i+=PAGE_SIZE) + printk("address=0x%x vseg=%d pte=0x%x\n", (unsigned int) i, + (int) get_segmap(i), (unsigned int) get_pte(i)); +#endif + + printk("Setting up kernel static mmu table... bounce bounce\n"); + + address = 0; /* ((unsigned long) &end) + 524288; */ + sun4c_mmu_table = (unsigned long *) start_mem; + pg_table = (pte_t *) start_mem; + curseg = curpte = num_inval = 0; + while(address < end_mem) { + if(curpte == 0) + put_segmap((address&PGDIR_MASK), curseg); + for(i=0; sp_banks[i].num_bytes != 0; i++) + if((address >= sp_banks[i].base_addr) && + (address <= (sp_banks[i].base_addr + sp_banks[i].num_bytes))) + goto good_address; + /* No physical memory here, so set the virtual segment to + * the invalid one, and put an invalid pte in the static + * kernel table. + */ + *pg_table = mk_pte((address >> PAGE_SHIFT), PAGE_INVALID); + pg_table++; curpte++; num_inval++; + if(curpte > 63) { + if(curpte == num_inval) { + put_segmap((address&PGDIR_MASK), invalid_segment); + } else { + put_segmap((address&PGDIR_MASK), curseg); + curseg++; + } + curpte = num_inval = 0; + } + address += PAGE_SIZE; + continue; + + good_address: + /* create pte entry */ + if(address < (((unsigned long) &end) + 524288)) { + pte_val(*pg_table) = get_pte(address); + } else { + *pg_table = mk_pte((address >> PAGE_SHIFT), PAGE_KERNEL); + put_pte(address, pte_val(*pg_table)); + } + + pg_table++; curpte++; + if(curpte > 63) { + put_segmap((address&PGDIR_MASK), curseg); + curpte = num_inval = 0; + curseg++; + } + address += PAGE_SIZE; + } + + start_mem = (unsigned long) pg_table; /* ok, allocate the kernel pages, map them in all contexts * (with help from the prom), and lock them. Isn't the sparc * fun kiddies? TODO */ +#if 0 + /* ugly debugging code */ + for(i=0x1a3000; i<(0x1a3000+40960); i+=PAGE_SIZE) + printk("address=0x%x vseg=%d pte=0x%x\n", (unsigned int) i, + (int) get_segmap(i), (unsigned int) get_pte(i)); + halt(); +#endif + b=PGDIR_ALIGN(start_mem)>>18; c= (char *)0x0; @@ -163,9 +241,6 @@ a= (unsigned long) &etext; mask=~(PTE_NC|PTE_W); /* make cacheable + not writable */ - printk("changing kernel text perms...\n"); - - /* must do for every segment since kernel uses all contexts * and unlike some sun kernels I know of, we can't hard wire * context 0 just for the kernel, that is unnecessary. @@ -191,34 +266,79 @@ switch_to_context(i); printk("%d ", (int) i); } + printk("\n"); switch_to_context(0); - /* invalidate all user segmaps for virt addrs 0-KERNBASE */ - - /* WRONG, now I just let the kernel sit in low addresses only - * from 0 -- end_kernel just like i386-linux. This will make - * mem-code a bit easier to cope with. - */ - - printk("\ninvalidating user segmaps\n"); - for(i = 0; i<8; i++) - { - switch_to_context(i); - a=((unsigned long) &end); - for(a+=524288, pg_segmap=0; ++pg_segmap<=3584; a+=(1<<18)) - put_segmap((unsigned long *) a, (invalid_segment&0x7f)); - } - - printk("wheee! have I sold out yet?\n"); - invalidate(); - return free_area_init(start_mem, end_mem); + return start_mem; } void mem_init(unsigned long start_mem, unsigned long end_mem) { - return; + unsigned long start_low_mem = PAGE_SIZE; + int codepages = 0; + int reservedpages = 0; + int datapages = 0; + int i = 0; + unsigned long tmp, limit, tmp2, addr; + extern char etext; + + end_mem &= PAGE_MASK; + high_memory = end_mem; + + start_low_mem = PAGE_ALIGN(start_low_mem); + start_mem = PAGE_ALIGN(start_mem); + + for(i = 0; sp_banks[i].num_bytes != 0; i++) { + tmp = sp_banks[i].base_addr; + limit = (sp_banks[i].base_addr + sp_banks[i].num_bytes); + if(tmpstart_mem) + tmp = start_mem; + else continue; + } + + while(tmp> 10, + high_memory >> 10, + codepages << (PAGE_SHIFT-10), + reservedpages << (PAGE_SHIFT-10), + datapages << (PAGE_SHIFT-10)); + + invalidate(); + return; } void si_meminfo(struct sysinfo *val) diff -u --recursive --new-file v1.1.94/linux/drivers/block/README.ide linux/drivers/block/README.ide --- v1.1.94/linux/drivers/block/README.ide Mon Feb 20 21:34:54 1995 +++ linux/drivers/block/README.ide Fri Feb 24 21:38:27 1995 @@ -1,4 +1,4 @@ -README.ide -- Information regarding ide.c and ide-cd.c (IDE driver in 1.1.93) +README.ide -- Information regarding ide.c and ide-cd.c (IDE driver in 1.1.95) ================================================================================ Supported by: mlord@bnr.ca -- disks, interfaces, probing snyder@fnald0.fnal.gov -- cdroms, ATAPI, audio @@ -26,6 +26,7 @@ - support for interface speed selection on jumperless interfaces - improved detection of non-standard IDE ATAPI cdrom drives + - support for non-standard 3rd/4th drive interface on Promise cards To access devices on the second interface, device entries must first be created in /dev for them. To create such entries, simply run the included diff -u --recursive --new-file v1.1.94/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v1.1.94/linux/drivers/block/floppy.c Wed Feb 15 10:36:37 1995 +++ linux/drivers/block/floppy.c Sun Feb 26 16:45:26 1995 @@ -240,6 +240,8 @@ #define R_SECTOR (reply_buffer[5]) #define R_SIZECODE (reply_buffer[6]) +#define SEL_DLY (2*HZ/100) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof( (x)[0] )) /* * this struct defines the different floppy drive types. @@ -254,38 +256,38 @@ | | Head load time, msec | | | Head unload time, msec (not used) | | | | Step rate interval, usec - | | | | | Time needed for spinup time (jiffies) - | | | | | | Timeout for spinning down (jiffies) - | | | | | | | Spindown offset (where disk stops) - | | | | | | | | Select delay - | | | | | | | | | RPS - | | | | | | | | | | Max number of tracks - | | | | | | | | | | | Interrupt timeout - | | | | | | | | | | | | Max nonintlv. sectors - | | | | | | | | | | | | | -Max Errors- flags */ -{{0, 500, 16, 16, 8000, 100, 300, 0, 2, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0, - 0, { 7, 4, 8, 2, 1, 5, 3,10}, 150, 0 }, "unknown" }, - -{{1, 300, 16, 16, 8000, 100, 300, 0, 2, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0, - 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 150, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/ - -{{2, 500, 16, 16, 6000, 40, 300, 14, 2, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0, - 0, { 2, 5, 6,23,10,20,11, 0}, 150, 2 }, "1.2M" }, /*5 1/4 HD AT*/ - -{{3, 250, 16, 16, 3000, 100, 300, 0, 2, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, - 0, { 4,22,21,30, 3, 0, 0, 0}, 150, 4 }, "720k" }, /*3 1/2 DD*/ - -{{4, 500, 16, 16, 4000, 40, 300, 10, 2, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, - 0, { 7, 4,25,22,31,21,29,11}, 150, 7 }, "1.44M" }, /*3 1/2 HD*/ - -{{5, 1000, 15, 8, 3000, 40, 300, 10, 2, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0, - 0, { 7, 8, 4,25,28,22,31,21}, 150, 8 }, "2.88M AMI BIOS" }, /*3 1/2 ED*/ - -{{6, 1000, 15, 8, 3000, 40, 300, 10, 2, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0, - 0, { 7, 8, 4,25,28,22,31,21}, 150, 8 }, "2.88M" } /*3 1/2 ED*/ -/* | ---autodetected formats-- | | | - read_track | | Name printed when booting - | Native format + | | | | | Time needed for spinup time (jiffies) + | | | | | | Timeout for spinning down (jiffies) + | | | | | | | Spindown offset (where disk stops) + | | | | | | | | Select delay + | | | | | | | | | RPS + | | | | | | | | | | Max number of tracks + | | | | | | | | | | | Interrupt timeout + | | | | | | | | | | | | Max nonintlv. sectors + | | | | | | | | | | | | | -Max Errors- flags */ +{{0, 500, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0, + 0, { 7, 4, 8, 2, 1, 5, 3,10}, 3*HZ/2, 0 }, "unknown" }, + +{{1, 300, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0, + 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/ + +{{2, 500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0, + 0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/ + +{{3, 250, 16, 16, 3000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, + 0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/ + +{{4, 500, 16, 16, 4000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, + 0, { 7, 4,25,22,31,21,29,11}, 3*HZ/2, 7 }, "1.44M" }, /*3 1/2 HD*/ + +{{5, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0, + 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M AMI BIOS" }, /*3 1/2 ED*/ + +{{6, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0, + 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M" } /*3 1/2 ED*/ +/* | ---autodetected formats-- | | | + read_track | | Name printed when booting + | Native format Frequency of disk change checks */ }; @@ -3228,7 +3230,7 @@ default_drive_params[i].params.select_delay = 0; default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR; } else { - default_drive_params[i].params.select_delay = 2; + default_drive_params[i].params.select_delay = 2*HZ/100; default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR; } } diff -u --recursive --new-file v1.1.94/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v1.1.94/linux/drivers/block/ide.c Mon Feb 20 21:34:54 1995 +++ linux/drivers/block/ide.c Fri Feb 24 21:38:28 1995 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide.c Version 3.12 February 19, 1995 + * linux/drivers/block/ide.c Version 3.13 February 23, 1995 * * Copyright (C) 1994, 1995 Linus Torvalds & authors (see below) */ @@ -103,11 +103,12 @@ * Version 3.11 fix mis-identification of old WD disks as cdroms * Version 3,12 simplify logic for selecting initial mult_count * (fixes problems with buggy WD drives) + * Version 3.13 remove excess "multiple mode disabled" messages * * To do: * - special 32-bit controller-type detection & support - * - figure out why two WD drives on one i/f sometimes don't identify * - figure out how to support oddball "intelligent" caching cards + * - reverse-engineer 3/4 drive support on fancy "Promise" cards */ #include @@ -1701,7 +1702,8 @@ dev->mult_req = INITIAL_MULT_COUNT; if (dev->mult_req > id->max_multsect) dev->mult_req = id->max_multsect; - dev->special.b.set_multmode = 1; + if (dev->mult_req || ((id->multsect_valid & 1) && id->multsect)) + dev->special.b.set_multmode = 1; printk(", MaxMult=%d", id->max_multsect); } printk("\n"); diff -u --recursive --new-file v1.1.94/linux/drivers/block/sonycd535.c linux/drivers/block/sonycd535.c --- v1.1.94/linux/drivers/block/sonycd535.c Wed Feb 22 16:53:04 1995 +++ linux/drivers/block/sonycd535.c Thu Feb 23 13:31:40 1995 @@ -1556,7 +1556,7 @@ sony535_irq_used = tmp_irq; #ifndef MODULE /* This code is not in MODULEs by default, since the autoirq stuff might - * not be in the module-accessable symbol table. + * not be in the module-accessible symbol table. */ /* A negative sony535_irq_used will attempt an autoirq. */ if (sony535_irq_used < 0) { diff -u --recursive --new-file v1.1.94/linux/drivers/char/ChangeLog linux/drivers/char/ChangeLog --- v1.1.94/linux/drivers/char/ChangeLog Wed Feb 22 16:53:04 1995 +++ linux/drivers/char/ChangeLog Thu Feb 23 13:31:41 1995 @@ -13,7 +13,7 @@ * serial.c (rs_init, set_serial_info, get_serial_info, rs_close): Remove support for closing_wait2. Instead, set - tty->closing and rely on the line dispcline to prevent + tty->closing and rely on the line discipline to prevent echo wars. * n_tty.c (n_tty_receive_char): IEXTEN does not need to be @@ -30,7 +30,7 @@ * serial.c (rs_interrupt_multi, startup, shutdown, rs_ioctl, set_multiport_struct, get_multiport_struct): Add - provisions for a new type of interrutp service routine, + provisions for a new type of interrupt service routine, which better supports multiple serial ports on a single IRQ. @@ -61,7 +61,7 @@ The default is to wait 30 seconds; in the case of a very slow device, the close_wait timeout should be - lengthed. If it is set to 0, the kernel will wait + lengthened. If it is set to 0, the kernel will wait forever for all of the data to be transmitted. Thu Jan 17 01:17:20 1995 Theodore Y. Ts'o (tytso@rt-11) diff -u --recursive --new-file v1.1.94/linux/drivers/char/console.c linux/drivers/char/console.c --- v1.1.94/linux/drivers/char/console.c Fri Feb 17 11:20:12 1995 +++ linux/drivers/char/console.c Thu Mar 2 09:31:10 1995 @@ -96,6 +96,7 @@ #include #include #include +#include #include #include @@ -1002,7 +1003,7 @@ else while (count--) { unsigned short old = scr_readw(p); - scr_writew(old ^ ((old & 0x0700 == 0x0100) + scr_writew(old ^ (((old & 0x0700) == 0x0100) ? 0x7000 : 0x7700), p); } } @@ -1915,12 +1916,16 @@ video_type = VIDEO_TYPE_EGAM; video_mem_term = 0xb8000; display_desc = "EGA+"; + request_region(0x3b4,2,"ega+"); } else { video_type = VIDEO_TYPE_MDA; video_mem_term = 0xb2000; display_desc = "*MDA"; + request_region(0x3b4,2,"mda"); + request_region(0x3b8,1,"mda"); + request_region(0x3bf,1,"mda"); } } else /* If not, it is color. */ @@ -1934,12 +1939,14 @@ video_type = VIDEO_TYPE_EGAC; video_mem_term = 0xc0000; display_desc = "EGA+"; + request_region(0x3d4,2,"ega+"); } else { video_type = VIDEO_TYPE_CGA; video_mem_term = 0xba000; display_desc = "*CGA"; + request_region(0x3d4,2,"cga"); } } diff -u --recursive --new-file v1.1.94/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c --- v1.1.94/linux/drivers/char/cyclades.c Thu Feb 9 10:18:50 1995 +++ linux/drivers/char/cyclades.c Thu Feb 23 13:31:40 1995 @@ -2457,7 +2457,7 @@ memset(&cy_serial_driver, 0, sizeof(struct tty_driver)); cy_serial_driver.magic = TTY_DRIVER_MAGIC; cy_serial_driver.name = "ttyC"; - cy_serial_driver.major = 19 /* TTY_MAJOR */; + cy_serial_driver.major = CYCLADES_MAJOR; cy_serial_driver.minor_start = 32; cy_serial_driver.num = NR_PORTS; cy_serial_driver.type = TTY_DRIVER_TYPE_SERIAL; @@ -2492,7 +2492,7 @@ */ cy_callout_driver = cy_serial_driver; cy_callout_driver.name = "cub"; - cy_callout_driver.major = 20 /* TTYAUX_MAJOR */; + cy_callout_driver.major = CYCLADESAUX_MAJOR; cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT; if (tty_register_driver(&cy_serial_driver)) diff -u --recursive --new-file v1.1.94/linux/drivers/char/defkeymap.c linux/drivers/char/defkeymap.c --- v1.1.94/linux/drivers/char/defkeymap.c Thu Oct 13 14:07:05 1994 +++ linux/drivers/char/defkeymap.c Fri Feb 24 21:38:27 1995 @@ -33,7 +33,7 @@ 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, - 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf208, 0xf203, 0xf307, + 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, diff -u --recursive --new-file v1.1.94/linux/drivers/char/defkeymap.map linux/drivers/char/defkeymap.map --- v1.1.94/linux/drivers/char/defkeymap.map Thu Oct 13 14:07:05 1994 +++ linux/drivers/char/defkeymap.map Fri Feb 24 21:38:27 1995 @@ -160,7 +160,8 @@ control keycode 68 = F10 alt keycode 68 = Console_10 control alt keycode 68 = Console_10 -keycode 69 = Num_Lock +keycode 69 = Num_Lock + shift keycode 69 = Bare_Num_Lock keycode 70 = Scroll_Lock Show_Memory Show_Registers control keycode 70 = Show_State alt keycode 70 = Scroll_Lock diff -u --recursive --new-file v1.1.94/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v1.1.94/linux/drivers/char/keyboard.c Fri Feb 17 11:20:12 1995 +++ linux/drivers/char/keyboard.c Thu Mar 2 08:38:43 1995 @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -136,14 +137,14 @@ static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle, num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose, - SAK, decr_console, incr_console, spawn_console; + SAK, decr_console, incr_console, spawn_console, bare_num; static void_fnp spec_fn_table[] = { do_null, enter, show_ptregs, show_mem, show_state, send_intr, lastcons, caps_toggle, num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose, SAK, - decr_console, incr_console, spawn_console + decr_console, incr_console, spawn_console, bare_num }; /* maximum values each key_handler can handle */ @@ -643,11 +644,21 @@ static void num(void) { - if (vc_kbd_mode(kbd,VC_APPLIC)) { + if (vc_kbd_mode(kbd,VC_APPLIC)) applkey('P', 1); - return; - } - if (!rep) /* no autorepeat for numlock, ChN */ + else + bare_num(); +} + +/* + * Bind this to Shift-NumLock if you work in application keypad mode + * but want to be able to change the NumLock flag. + * Bind this to NumLock if you prefer that the NumLock key always + * changes the NumLock flag. + */ +static void bare_num(void) +{ + if (!rep) chg_vc_kbd_led(kbd,VC_NUMLOCK); } @@ -1170,6 +1181,8 @@ bh_base[KEYBOARD_BH].routine = kbd_bh; request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard"); + request_region(0x60,1,"kbd"); + request_region(0x64,1,"kbd"); #ifdef __alpha__ /* enable keyboard interrupts, PC/AT mode */ kb_wait(); diff -u --recursive --new-file v1.1.94/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v1.1.94/linux/drivers/char/serial.c Wed Feb 22 16:53:04 1995 +++ linux/drivers/char/serial.c Thu Feb 23 13:31:40 1995 @@ -2003,8 +2003,8 @@ if (info->flags & ASYNC_CALLOUT_ACTIVE) info->callout_termios = *tty->termios; /* - * Now we wait for the trnasmit buffer to clear; and we notify - * the line discpline only process XON/XOFF characters. + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) diff -u --recursive --new-file v1.1.94/linux/drivers/net/3c503.c linux/drivers/net/3c503.c --- v1.1.94/linux/drivers/net/3c503.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/3c503.c Mon Feb 27 11:06:24 1995 @@ -330,7 +330,7 @@ { if (ei_debug > 1) { printk("%s: Resetting the 3c503 board...", dev->name); - printk("%#x=%#02x %#x=%#02x %#x=%#02x...", E33G_IDCFR, inb(E33G_IDCFR), + printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR), E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR)); } outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL); diff -u --recursive --new-file v1.1.94/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v1.1.94/linux/drivers/net/Makefile Wed Feb 15 10:36:38 1995 +++ linux/drivers/net/Makefile Thu Feb 23 13:51:27 1995 @@ -231,6 +231,8 @@ ifdef CONFIG_ARCNET NETDRV_OBJS := $(NETDRV_OBJS) arcnet.o +else +MODULES := $(MODULES) arcnet.o endif ifdef CONFIG_PI diff -u --recursive --new-file v1.1.94/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c --- v1.1.94/linux/drivers/net/arcnet.c Mon Jan 16 14:18:19 1995 +++ linux/drivers/net/arcnet.c Thu Feb 23 13:53:58 1995 @@ -1,47 +1,64 @@ -/* - arcnet.c written 1994 by Avery Pennarun, derived from skeleton.c - by Donald Becker. - +/* arcnet.c + Written 1994-95 by Avery Pennarun, derived from skeleton.c by + Donald Becker. + Contact Avery at: apenwarr@tourism.807-city.on.ca or RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9 - !!! This is a dangerous alpha version !!! - ********************** skeleton.c Written 1993 by Donald Becker. - Copyright 1993 United States Government as represented by the Director, - National Security Agency. This software may only be used and distributed - according to the terms of the GNU Public License as modified by SRC, - incorporated herein by reference. - - The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O - Center of Excellence in Space Data and Information Sciences - Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 + Copyright 1993 United States Government as represented by the + Director, National Security Agency. This software may only be used + and distributed according to the terms of the GNU Public License as + modified by SRC, incorporated herein by reference. ********************** + + + v1.0 (95/02/15) + - Initial non-alpha release. TO DO: - - Polled transmits probably take a lot more CPU time than needed. - Perhaps use the system timer? A better solution would be to - just figure out how to get both xmit and receive IRQ's working - at the same time. No luck yet... - - I'd also like to get ping-pong TX buffers working. - Test in systems with NON-ARCnet network cards, just to see if autoprobe kills anything. With any luck, it won't. (It's pretty - strict and careful.) + careful.) + - Except some unfriendly NE2000's die. (0.40) - cards with shared memory that can be "turned off?" - - examine TRXNET for information about this + - NFS mount freezes after several megabytes to SOSS for DOS. + unmount/remount works. Is this arcnet-specific? I don't know. + - Add support for the various stupid bugs ("I didn't read the RFC" + syndrome) in MS Windows for Workgroups and LanMan. + + - get the net people to probe last for arcnet, and first for ne2000 + in Space.c... */ /**************************************************************************/ + +/* define this if you want to use the new but possibly dangerous ioprobe + * If you get lockups right after status5, you probably need + * to undefine this. It should make more cards probe correctly, + * I hope. + */ +#define DANGER_PROBE + +/* define this if you want to use the "extra delays" which were removed + * in 0.41 since they seemed needless. + */ +#undef EXTRA_DELAYS + +/* undefine this if you want to use the non-IRQ-driven transmitter. (possibly + * safer, although it takes more CPU time and IRQ_XMIT seems fine right now) + */ +#define IRQ_XMIT /* define this for "careful" transmitting. Try with and without if you have - * problems. + * problems. If you use IRQ_XMIT, do NOT define this. */ -#define CAREFUL_XMIT +#undef CAREFUL_XMIT /* define this for an extra-careful memory detect. This should work all * the time now, but you never know. @@ -70,11 +87,7 @@ /**************************************************************************/ static char *version = - "arcnet.c:v0.32 ALPHA 94/12/26 Avery Pennarun \n"; - -/* Always include 'config.h' first in case the user wants to turn on - or override something. */ -#include + "arcnet.c:v1.00 95/02/15 Avery Pennarun \n"; /* Sources: @@ -86,8 +99,17 @@ ...I sure wish I had the ARCnet data sheets right about now! RFC's 1201 and 1051 (mostly 1201) - re: ARCnet IP packets net/inet/eth.c (from kernel 1.1.50) for header-building info... + Alternate Linux ARCnet source by V.Shergin + Textual information and more alternate source from Joachim Koenig + */ +#include +#ifdef MODULE +#include +#include +#endif /* MODULE */ + #include #include #include @@ -100,6 +122,7 @@ #include #include #include +#include #include #include @@ -111,6 +134,7 @@ #include #include "arp.h" + /* debug levels: * D_OFF production * D_NORMAL verification @@ -143,7 +167,7 @@ #ifndef HAVE_PORTRESERVE #define check_region(ioaddr, size) 0 -#define snarf_region(ioaddr, size); do ; while (0) +#define request_region(ioaddr, size) do ; while (0) #endif /* macro to simplify debug checking */ @@ -162,8 +186,8 @@ /* time needed for various things (in clock ticks, 1/100 sec) */ #define RESETtime 40 /* reset */ -#define XMITtime 10 /* send */ -#define ACKtime 10 /* acknowledge */ +#define XMITtime 10 /* send (?) */ +#define ACKtime 10 /* acknowledge (?) */ /* these are the max/min lengths of packet data. (including * ClientData header) @@ -220,12 +244,15 @@ /* buffers (4 total) used for receive and xmit. */ #define EnableReceiver() outb(RXcmd|(recbuf<<3)|RXbcasts,COMMAND) -#define TXbuf 2 +/*#define TXbuf 2 (Obsoleted by ping-pong xmits) */ /* Protocol ID's */ #define ARC_P_IP 212 /* 0xD4 */ #define ARC_P_ARP 213 /* 0xD5 */ #define ARC_P_RARP 214 /* 0xD6 */ +#define ARC_P_IPX 250 /* 0xFA */ +#define ARC_P_LANSOFT 251 /* 0xFB */ +#define ARC_P_ATALK 0xDD /* Length of time between "stuck" checks */ #define TIMERval (HZ/8) /* about 1/8 second */ @@ -283,39 +310,65 @@ u_short sequence; /* sequence number of assembly */ }; +struct Outgoing +{ + struct sk_buff *skb; /* buffer from upper levels */ + struct ClientData *hdr; /* clientdata of last packet */ + u_char *data; /* pointer to data in packet */ + short length, /* bytes total */ + dataleft, /* bytes left */ + segnum, /* segment being sent */ + numsegs, /* number of segments */ + seglen; /* length of segment */ +}; + /* Information that needs to be kept for each board. */ struct arcnet_local { struct enet_statistics stats; u_char arcnum; /* arcnet number - our 8-bit address */ u_short sequence; /* sequence number (incs with each packet) */ - u_char recbuf; /* receive buffer # (0 or 1) */ - int intx; /* in TX routine? */ + u_char recbuf, /* receive buffer # (0 or 1) */ + txbuf, /* transmit buffer # (2 or 3) */ + txready; /* buffer where a packet is ready to send */ + short intx, /* in TX routine? */ + in_txhandler, /* in TX_IRQ handler? */ + sending; /* transmit in progress? */ + short tx_left; /* segments of split packet left to TX */ struct timer_list timer; /* the timer interrupt struct */ struct Incoming incoming[256]; /* one from each address */ + struct Outgoing outgoing; /* packet currently being sent */ }; /* Index to functions, as function prototypes. */ - extern int arcnet_probe(struct device *dev); +#ifndef MODULE static int arcnet_memprobe(struct device *dev,u_char *addr); static int arcnet_ioprobe(struct device *dev, short ioaddr); +#endif static int arcnet_open(struct device *dev); static int arcnet_close(struct device *dev); static int arcnet_send_packet(struct sk_buff *skb, struct device *dev); -static void careful_xmit_wait(struct device *dev); -static int arcnet_tx(struct device *dev,struct ClientData *hdr,short length, - char *data); +#ifdef CAREFUL_XMIT + static void careful_xmit_wait(struct device *dev); +#else + #define careful_xmit_wait(dev) +#endif +static void arcnet_continue_tx(struct device *dev); +static void arcnet_prepare_tx(struct device *dev,struct ClientData *hdr, + short length,char *data); +static void arcnet_go_tx(struct device *dev); -static void arcnet_interrupt(int irq, struct pt_regs *regs); +static void arcnet_interrupt(int irq,struct pt_regs *regs); static void arcnet_inthandler(struct device *dev); static void arcnet_rx(struct device *dev,int recbuf); - +#ifdef USE_TIMER_HANDLER static void arcnet_timer(unsigned long arg); +#endif static struct enet_statistics *arcnet_get_stats(struct device *dev); static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); @@ -327,10 +380,26 @@ struct sk_buff *skb); unsigned short arc_type_trans(struct sk_buff *skb,struct device *dev); +static int arcnet_reset(struct device *dev); + +#ifdef MODULE +int init_module(void); +void cleanup_module(void); +#endif #define tx_done(dev) 1 -#define JIFFER(time) for (delayval=jiffies+(time); delayval>=jiffies;); -static int arcnet_reset(struct device *dev); + +/* +#define JIFFER(time) for (delayval=jiffies+(time); delayval>jiffies;); +*/ +#define JIFFER(time) for (delayval=0; delayval<(time*10); delayval++) \ + udelay(1000); + +#ifdef EXTRA_DELAYS + #define XJIFFER(time) JIFFER(time) +#else + #define XJIFFER(time) +#endif /* Check for a network adaptor of this type, and return '0' if one exists. @@ -342,6 +411,7 @@ int arcnet_probe(struct device *dev) { +#ifndef MODULE /* I refuse to probe anything less than 0x200, because anyone using * an address like that should probably be shot. */ @@ -351,10 +421,10 @@ 0x200,0x210,0x220,0x230,0x240,0x250,0x260,0x270, 0x280,0x290,0x2a0,0x2b0,0x2c0, 0x310,0x320,0x330,0x340,0x350,0x360,0x370, - 0x380,0x390,0x3a0,0x3b0,0x3c0,0x3d0,0x3e0,0x3f0, + 0x380,0x390,0x3a0,/* video ports, */0x3e0,0x3f0, /* a null ends the list */ 0}; - /* I'm not going to probe under 0xA0000 either, for similar reasons. + /* I'm not going to probe below 0xA0000 either, for similar reasons. */ unsigned long *addr, addrs[] = {0xD0000,0xE0000,0xA0000,0xB0000, 0xC0000,0xF0000, @@ -366,15 +436,24 @@ 0xC9000,0xC8000,0xC5000,0xC4000, /* terminator */ 0}; - int base_addr=dev->base_addr, status=0,delayval; + int base_addr=dev->base_addr, status=0; +#endif /* MODULE */ + int delayval; struct arcnet_local *lp; - if (net_debug) printk(version); + if (net_debug) + { + printk(version); + printk("arcnet: ***\n"); + printk("arcnet: * Read linux/drivers/net/README.arcnet for important release notes!\n"); + printk("arcnet: ***\n"); + } BUGLVL(D_INIT) - printk("arcnet: given: base %Xh, IRQ %Xh, shmem %lXh\n", + printk("arcnet: given: base %lXh, IRQ %Xh, shmem %lXh\n", dev->base_addr,dev->irq,dev->mem_start); - + +#ifndef MODULE if (base_addr > 0x1ff) /* Check a single specified location. */ status=arcnet_ioprobe(dev, base_addr); else if (base_addr > 0) /* Don't probe at all. */ @@ -395,7 +474,7 @@ } if (status) return status; - + /* ioprobe turned out okay. Now give it a couple seconds to finish * initializing... */ @@ -421,21 +500,32 @@ if (status) return status; } - +#else /* MODULE */ + if (!dev->base_addr || !dev->irq || !dev->mem_start + || !dev->rmem_start) + { + printk("arcnet: loadable modules can't autoprobe!\n"); + printk("arcnet: try using io=, irqnum=, and shmem= on the insmod line.\n"); + printk("arcnet: you may also need num= to change the device name. (ie. num=1 for arc1)\n"); + return ENODEV; + } +#endif /* now reserve the irq... */ - { int irqval = request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet"); - if (irqval) { - printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, - dev->irq, irqval); - return EAGAIN; + { + int irqval = request_irq(dev->irq, &arcnet_interrupt, 0, + "arcnet"); + if (irqval) { + printk("%s: unable to get IRQ %d (irqval=%d).\n", + dev->name,dev->irq, irqval); + return EAGAIN; } } /* Grab the region so we can find another board if autoIRQ fails. */ - snarf_region(dev->base_addr, ETHERCARD_TOTAL_SIZE); - - printk("%s: ARCnet card found at %03Xh, IRQ %d, ShMem at %lXh.\n", dev->name, - dev->base_addr, dev->irq, dev->mem_start); + request_region(dev->base_addr, ETHERCARD_TOTAL_SIZE,"arcnet"); + + printk("%s: ARCnet card found at %03lXh, IRQ %d, ShMem at %lXh.\n", + dev->name, dev->base_addr, dev->irq, dev->mem_start); /* Initialize the device structure. */ dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL); @@ -484,13 +574,14 @@ lp->recbuf=0; dev->hard_header = arc_header; -/* dev->add_arp = arc_add_arp; AVE unavailable in 1.1.51?! */ dev->rebuild_header = arc_rebuild_header; dev->type_trans = arc_type_trans; return 0; } +#ifndef MODULE + int arcnet_ioprobe(struct device *dev, short ioaddr) { int delayval,airq; @@ -506,7 +597,7 @@ * no irq, it's not an ARCnet. We can also kill two birds with * one stone because we detect the IRQ at the same time :) */ - + /* reset the card by reading the reset port */ inb(RESET); JIFFER(RESETtime); @@ -545,7 +636,7 @@ /* now we turn the reset bit off so we can IRQ next reset... */ outb(CFLAGScmd|RESETclear|CONFIGclear,COMMAND); - JIFFER(ACKtime); + XJIFFER(ACKtime); if (inb(STATUS) & RESETflag) /* reset flag STILL on */ { BUGLVL(D_INIT) @@ -557,7 +648,7 @@ /* set up automatic IRQ detection */ autoirq_setup(0); - /* enable reset IRQ's (shouldn't be necessary, but hey) */ + /* enable reset IRQ's (shouldn't be necessary, but worth a try) */ outb(RESETflag,INTMASK); /* now reset it again to generate an IRQ */ @@ -567,16 +658,16 @@ BUGLVL(D_INIT) printk("arcnet: status3=%Xh\n",inb(STATUS)); - /* enable reset IRQ's again */ - outb(RESETflag,INTMASK); - /* and turn the reset flag back off */ outb(CFLAGScmd|RESETclear|CONFIGclear,COMMAND); - JIFFER(ACKtime); + XJIFFER(ACKtime); BUGLVL(D_INIT) printk("arcnet: status4=%Xh\n",inb(STATUS)); + /* enable reset IRQ's again */ + outb(RESETflag,INTMASK); + /* now reset it again to generate an IRQ */ inb(RESET); JIFFER(RESETtime); @@ -584,6 +675,23 @@ BUGLVL(D_INIT) printk("arcnet: status5=%Xh\n",inb(STATUS)); + /* if we do this, we're sure to get an IRQ since the card has + * just reset and the NORXflag is on until we tell it to start + * receiving. + * + * However, this could, theoretically, cause a lockup. Maybe I'm just + * not very good at theory! :) + */ +#ifdef DANGER_PROBE + outb(NORXflag,INTMASK); + JIFFER(RESETtime); + outb(0,INTMASK); +#endif + + /* and turn the reset flag back off */ + outb(CFLAGScmd|RESETclear|CONFIGclear,COMMAND); + XJIFFER(ACKtime); + airq = autoirq_report(0); if (net_debug>=D_INIT && airq) printk("arcnet: autoirq is %d\n", airq); @@ -604,7 +712,7 @@ { /* now we turn the reset bit off */ outb(CFLAGScmd|RESETclear|CONFIGclear,COMMAND); - JIFFER(ACKtime); + XJIFFER(ACKtime); } if (inb(STATUS) & RESETflag) /* reset flag STILL on */ @@ -631,11 +739,12 @@ } BUGLVL(D_INIT) - printk("arcnet: irq and base address seem okay. (%Xh, IRQ %d)\n", + printk("arcnet: irq and base address seem okay. (%lXh, IRQ %d)\n", dev->base_addr,dev->irq); return 0; } + /* A memory probe that is called after the card is reset. * It checks for the official TESTvalue in byte 0 and makes sure the buffer * has certain characteristics of an ARCnet... @@ -685,6 +794,8 @@ return 0; } +#endif /* MODULE */ + /* Open/initialize the board. This is called (in the current kernel) sometime after booting when the 'ifconfig' program is run. @@ -699,6 +810,12 @@ struct arcnet_local *lp = (struct arcnet_local *)dev->priv; /* int ioaddr = dev->base_addr;*/ + if (dev->metric>=10) + { + net_debug=dev->metric-10; + dev->metric=1; + } + if (net_debug) printk(version); #if 0 /* Yup, they're hardwired in arcnets */ @@ -713,25 +830,34 @@ /* Reset the hardware here. */ BUGLVL(D_EXTRA) printk("arcnet: arcnet_open: resetting card.\n"); - if (arcnet_reset(dev)) return -ENODEV; + + /* try to reset - twice if it fails the first time */ + if (arcnet_reset(dev) && arcnet_reset(dev)) + return -ENODEV; /* chipset_init(dev, 1);*/ /* outb(0x00, ioaddr);*/ /* lp->open_time = jiffies;*/ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + dev->tbusy=0; + dev->interrupt=0; + dev->start=1; + lp->intx=0; + lp->in_txhandler=0; +#ifdef USE_TIMER_HANDLER /* grab a timer handler to recover from any missed IRQ's */ init_timer(&lp->timer); lp->timer.expires = TIMERval; /* length of time */ lp->timer.data = (unsigned long)dev; /* pointer to "dev" structure */ lp->timer.function = &arcnet_timer; /* timer handler */ -#ifdef USE_TIMER_HANDLER add_timer(&lp->timer); #endif + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif return 0; } @@ -742,7 +868,10 @@ arcnet_close(struct device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int ioaddr = dev->base_addr, delayval; + int ioaddr = dev->base_addr; +#ifdef EXTRA_DELAYS + int delayval; +#endif /* lp->open_time = 0;*/ @@ -758,17 +887,14 @@ outb(0,INTMASK); /* no IRQ's */ outb(NOTXcmd,COMMAND); /* disable transmit */ - JIFFER(ACKtime); + XJIFFER(ACKtime); outb(NORXcmd,COMMAND); /* disable receive */ -#if 0 /* we better not do this - hard wired IRQ's */ - /* If not IRQ jumpered, free up the line. */ - outw(0x00, ioaddr+0); /* Release the physical interrupt line. */ - free_irq(dev->irq); - irq2dev_map[dev->irq] = 0; -#endif - /* Update the statistics here. */ + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif return 0; } @@ -778,16 +904,16 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int ioaddr=dev->base_addr,stat=0; + int ioaddr=dev->base_addr; /* short daddr;*/ lp->intx++; - + BUGLVL(D_DURING) printk("arcnet: transmit requested (status=%Xh, inTX=%d)\n", inb(STATUS),lp->intx); - if (dev->tbusy) + if (dev->tbusy || lp->in_txhandler) { /* If we get here, some higher level has decided we are broken. There should really be a "kick me" function call instead. */ @@ -795,7 +921,28 @@ int recbuf=lp->recbuf; int status=inb(STATUS); - if (tickssofar < 5) return 1; + /* resume any stopped tx's */ +#if 0 + if (lp->txready && (inb(STATUS)&TXFREEflag)) + { + printk("arcnet: kickme: starting a TX (status=%Xh)\n", + inb(STATUS)); + arcnet_go_tx(dev); + lp->intx--; + return 1; + } +#endif + + if (tickssofar < 5) + { + BUGLVL(D_DURING) + printk("arcnet: premature kickme! (status=%Xh ticks=%d o.skb=%ph numsegs=%d segnum=%d\n", + status,tickssofar,lp->outgoing.skb, + lp->outgoing.numsegs, + lp->outgoing.segnum); + lp->intx--; + return 1; + } BUGLVL(D_INIT) printk("arcnet: transmit timed out (status=%Xh, inTX=%d, tickssofar=%d)\n", @@ -806,10 +953,19 @@ if (status&NORXflag) EnableReceiver(); if (!(status&TXFREEflag)) outb(NOTXcmd,COMMAND); + dev->trans_start = jiffies; + + if (lp->outgoing.skb) + dev_kfree_skb(lp->outgoing.skb,FREE_WRITE); + lp->outgoing.skb=NULL; + dev->tbusy=0; mark_bh(NET_BH); - dev->trans_start = jiffies; - lp->intx--; + lp->intx=0; + lp->in_txhandler=0; + lp->txready=0; + lp->sending=0; + return 1; } @@ -824,90 +980,174 @@ lp->intx--; return 0; } + + if (lp->txready) /* transmit already in progress! */ + { + printk("arcnet: trying to start new packet while busy!\n"); + printk("arcnet: marking as not ready.\n"); + lp->txready=0; + return 1; + } /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) { - printk("arcnet: Transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n", + printk("arcnet: transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n", inb(STATUS),lp->intx,jiffies-dev->trans_start); - stat=-EBUSY; + lp->intx--; + return -EBUSY; } else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - struct ClientData *hdr=(struct ClientData*)skb->data; + struct Outgoing *out=&(lp->outgoing); + out->length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + out->hdr=(struct ClientData*)skb->data; + out->skb=skb; + +#ifdef IRQ_XMIT + if (lp->txready && inb(STATUS)&TXFREEflag) + arcnet_go_tx(dev); +#endif + - if (length<=XMTU) /* fits in one packet? */ + if (out->length<=XMTU) /* fits in one packet? */ { BUGLVL(D_TX) printk("arcnet: not splitting %d-byte packet. (split_flag=%d)\n", - length,hdr->split_flag); - BUGLVL(D_INIT) if (hdr->split_flag) + out->length,out->hdr->split_flag); + BUGLVL(D_INIT) if (out->hdr->split_flag) printk("arcnet: short packet has split_flag set?! (split_flag=%d)\n", - hdr->split_flag); - stat=arcnet_tx(dev,hdr, - length-sizeof(struct ClientData), + out->hdr->split_flag); + out->numsegs=1; + out->segnum=1; + arcnet_prepare_tx(dev,out->hdr, + out->length-sizeof(struct ClientData), ((char *)skb->data)+sizeof(struct ClientData)); + careful_xmit_wait(dev); + + /* done right away */ + dev_kfree_skb(out->skb,FREE_WRITE); + out->skb=NULL; + + if (!lp->sending) + { + arcnet_go_tx(dev); + + /* inform upper layers */ + dev->tbusy=0; + mark_bh(NET_BH); + } } else /* too big for one - split it */ { - u_char *data=(u_char *)skb->data + int maxsegsize=XMTU-sizeof(struct ClientData); + + out->data=(u_char *)skb->data + sizeof(struct ClientData); - int dataleft=length-sizeof(struct ClientData), - maxsegsize=XMTU-sizeof(struct ClientData), - numsegs=(dataleft+maxsegsize-1)/maxsegsize, - seglen,segnum=0; + out->dataleft=out->length-sizeof(struct ClientData); + out->numsegs=(out->dataleft+maxsegsize-1)/maxsegsize; + + out->segnum=0; BUGLVL(D_TX) printk("arcnet: packet (%d bytes) split into %d fragments:\n", - length,numsegs); + out->length,out->numsegs); - while (!stat && dataleft) - { - if (!segnum) /* first packet */ - hdr->split_flag=((numsegs-2)<<1)+1; - else - hdr->split_flag=segnum<<1; +#ifdef IRQ_XMIT + /* if a packet waiting, launch it */ + if (lp->txready && inb(STATUS)&TXFREEflag) + arcnet_go_tx(dev); - seglen=maxsegsize; - if (seglen>dataleft) seglen=dataleft; - - BUGLVL(D_TX) printk("arcnet: packet #%d (%d bytes) of %d (%d total), splitflag=%d\n", - segnum+1,seglen,numsegs,length,hdr->split_flag); - - stat=arcnet_tx(dev,hdr,seglen,data); - - dataleft-=seglen; - data+=seglen; - segnum++; - -#if 0 /* sequence # should not update here... I think! */ - /* sequence number goes up on each packet */ - hdr->sequence++; - lp->sequence++; -#endif + if (!lp->txready) + { + /* prepare a packet, launch it and prepare + * another. + */ + arcnet_continue_tx(dev); + if (!lp->sending) + { + arcnet_go_tx(dev); + arcnet_continue_tx(dev); + if (!lp->sending) + arcnet_go_tx(dev); + } } - } - /* I don't know if this should be in or out of these braces, - * but freeing it too often seems worse than too little. - * (maybe?) (v0.30) - */ - if (!stat) dev_kfree_skb(skb, FREE_WRITE); - - /* we're done now */ - if (stat!=-EBUSY) - { - dev->tbusy=0; - mark_bh(NET_BH); /* Inform upper layers. */ - /* this should be on an IRQ, but can't - * because ARCnets (at least mine) are stupid. + /* if segnum==numsegs, the transmission is finished; + * free the skb right away. */ + if (out->segnum==out->numsegs) + { + /* transmit completed */ + out->segnum++; + if (out->skb) + dev_kfree_skb(out->skb,FREE_WRITE); + out->skb=NULL; +#if 0 + /* inform upper layers */ + dev->tbusy=0; + mark_bh(NET_BH); +#endif + } + +#else /* non-irq xmit */ + while (out->segnumnumsegs) + { + arcnet_continue_tx(dev); + careful_xmit_wait(dev); + arcnet_go_tx(dev); + dev->trans_start=jiffies; + } + + dev_kfree_skb(out->skb,FREE_WRITE); + out->skb=NULL; + + /* inform upper layers */ + dev->tbusy = 0; + mark_bh(NET_BH); +#endif } } - + lp->intx--; + lp->stats.tx_packets++; + dev->trans_start=jiffies; + return 0; +} + +static void arcnet_continue_tx(struct device *dev) +{ + struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + int maxsegsize=XMTU-sizeof(struct ClientData); + struct Outgoing *out=&(lp->outgoing); + + if (lp->txready) + { + printk("arcnet: continue_tx: called with packet in buffer!\n"); + return; + } + + if (out->segnum>=out->numsegs) + { + printk("arcnet: continue_tx: building segment %d of %d!\n", + out->segnum+1,out->numsegs); + } + + if (!out->segnum) /* first packet */ + out->hdr->split_flag=((out->numsegs-2)<<1)+1; + else + out->hdr->split_flag=out->segnum<<1; - if (!stat) lp->stats.tx_packets++; - return stat; + out->seglen=maxsegsize; + if (out->seglen>out->dataleft) out->seglen=out->dataleft; + + BUGLVL(D_TX) printk("arcnet: building packet #%d (%d bytes) of %d (%d total), splitflag=%d\n", + out->segnum+1,out->seglen,out->numsegs, + out->length,out->hdr->split_flag); + + arcnet_prepare_tx(dev,out->hdr,out->seglen,out->data); + + out->dataleft-=out->seglen; + out->data+=out->seglen; + out->segnum++; } #ifdef CAREFUL_XMIT @@ -935,49 +1175,30 @@ } #endif -static int -arcnet_tx(struct device *dev,struct ClientData *hdr,short length, +static void +arcnet_prepare_tx(struct device *dev,struct ClientData *hdr,short length, char *data) { - int ioaddr = dev->base_addr; -#if 0 +/* int ioaddr = dev->base_addr;*/ struct arcnet_local *lp = (struct arcnet_local *)dev->priv; -#endif struct ClientData *arcsoft; union ArcPacket *arcpacket = - (union ArcPacket *)(dev->mem_start+512*TXbuf); + (union ArcPacket *)(dev->mem_start+512*(lp->txbuf^1)); u_char pkttype; int offset; short daddr; + lp->txbuf=lp->txbuf^1; /* XOR with 1 to alternate between 2 and 3 */ + length+=sizeof(struct ClientData); BUGLVL(D_TX) - printk("arcnet: arcnet_tx: hdr:%ph, length:%d, data:%ph\n", + printk("arcnet: arcnet_prep_tx: hdr:%ph, length:%d, data:%ph\n", hdr,length,data); -#if 0 - /* make sure transmitter is available before sending */ - if (! (inb(STATUS) & TXFREEflag)) - { - BUGLVL(D_TX) - printk("arcnet: transmitter in use! (status=%Xh)\n", - inb(STATUS)); - return -EBUSY; - } -#endif - /* Gruesome hack because tx+rx irq's don't work at - * the same time (or so it seems to me) - * - * Our transmits just won't be interrupt driven, I guess. (ugh) - */ -#ifdef CAREFUL_XMIT - careful_xmit_wait(dev); -#endif - /* clean out the page to make debugging make more sense :) */ BUGLVL(D_DURING) - memset((void *)dev->mem_start+TXbuf*512,0x42,512); + memset((void *)dev->mem_start+lp->txbuf*512,0x42,512); daddr=arcpacket->hardheader.destination=hdr->daddr; @@ -1051,15 +1272,6 @@ printk("\n"); } - - - /* start sending */ - outb(TXcmd|(TXbuf<<3),COMMAND); - - dev->trans_start = jiffies; - - BUGLVL(D_TX) printk("arcnet: transmit started successfully. (status=%Xh)\n", - inb(STATUS)); #ifdef CAREFUL_XMIT #if 0 careful_xmit_wait(dev); @@ -1078,15 +1290,44 @@ } #endif #endif + lp->txready=lp->txbuf; /* packet is ready for sending */ - return 0; +#if 0 +#ifdef IRQ_XMIT + if (inb(STATUS)&TXFREEflag) arcnet_go_tx(dev); +#endif +#endif +} + +static void +arcnet_go_tx(struct device *dev) +{ + struct arcnet_local *lp=(struct arcnet_local *)dev->priv; + int ioaddr=dev->base_addr; + + BUGLVL(D_DURING) + printk("arcnet: go_tx: status=%Xh\n", + inb(STATUS)); + + if (!(inb(STATUS)&TXFREEflag) || !lp->txready) return; + + /* start sending */ + outb(TXcmd|(lp->txready<<3),COMMAND); + +#ifdef IRQ_XMIT + outb(TXFREEflag|NORXflag,INTMASK); +#endif + + dev->trans_start = jiffies; + lp->txready=0; + lp->sending++; } /* The typical workload of the driver: Handle the network interface interrupts. */ static void -arcnet_interrupt(int irq, struct pt_regs *regs) +arcnet_interrupt(int irq,struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); @@ -1103,12 +1344,17 @@ arcnet_inthandler(struct device *dev) { struct arcnet_local *lp; - int ioaddr, status, boguscount = 20; - + int ioaddr, status, boguscount = 3, didsomething; + dev->interrupt = 1; + sti(); ioaddr = dev->base_addr; lp = (struct arcnet_local *)dev->priv; + +#ifdef IRQ_XMIT + outb(0,INTMASK); +#endif BUGLVL(D_DURING) printk("arcnet: in net_interrupt (status=%Xh)\n",inb(STATUS)); @@ -1116,13 +1362,19 @@ do { status = inb(STATUS); + didsomething=0; if (!dev->start) { BUGLVL(D_EXTRA) printk("arcnet: ARCnet not yet initialized. irq ignored. (status=%Xh)\n", - inb(STATUS)); - break; + status); +#ifdef IRQ_XMIT + if (!(status&NORXflag)) + outb(NORXflag,INTMASK); +#endif + dev->interrupt=0; + return; } /* RESET flag was enabled - card is resetting and if RX @@ -1133,7 +1385,8 @@ BUGLVL(D_INIT) printk("arcnet: reset irq (status=%Xh)\n", status); - break; + dev->interrupt=0; + return; } #if 1 /* yes, it's silly to disable this part but it makes good testing */ @@ -1151,40 +1404,99 @@ /* Got a packet. */ arcnet_rx(dev,!recbuf); + + didsomething++; } #endif - -#if 0 /* this doesn't actually work, and will now zonk everything. leave - * disabled until I fix it. - */ - /* it can only be a xmit-done irq if we're xmitting :) */ - else if (dev->tbusy && status&TXFREEflag) +#ifdef IRQ_XMIT + /* it can only be an xmit-done irq if we're xmitting :) */ + if (status&TXFREEflag && !lp->in_txhandler && lp->sending) { + struct Outgoing *out=&(lp->outgoing); + + lp->in_txhandler++; + lp->sending--; + BUGLVL(D_DURING) - printk("arcnet: transmit IRQ?!? (status=%Xh)\n", - status); + printk("arcnet: TX IRQ (stat=%Xh, numsegs=%d, segnum=%d, skb=%ph)\n", + status,out->numsegs,out->segnum,out->skb); + + /* send packet if there is one */ + if (lp->txready) + { + arcnet_go_tx(dev); + didsomething++; + } + + if (lp->intx) + { + lp->in_txhandler--; + continue; + } + + if (!lp->outgoing.skb) + { + BUGLVL(D_DURING) + printk("arcnet: TX IRQ done: no split to continue.\n"); + + /* inform upper layers */ + if (!lp->txready && dev->tbusy) + { + dev->tbusy=0; + mark_bh(NET_BH); + } + + lp->in_txhandler--; + continue; + } /*lp->stats.tx_packets++;*/ - dev->tbusy = 0; - mark_bh(NET_BH); /* Inform upper layers. */ - break; + /* if more than one segment, and not all segments + * are done, then continue xmit. + */ + if (out->segnumnumsegs) + arcnet_continue_tx(dev); + if (lp->txready && !lp->sending) + arcnet_go_tx(dev); + + /* if segnum==numsegs, the transmission is finished; + * free the skb. + */ + if (out->segnum>=out->numsegs) + { + /* transmit completed */ + out->segnum++; + if (out->skb) + dev_kfree_skb(out->skb,FREE_WRITE); + out->skb=NULL; + + /* inform upper layers */ + if (!lp->txready && dev->tbusy) + { + dev->tbusy=0; + mark_bh(NET_BH); + } + } + didsomething++; + + lp->in_txhandler--; } - else - break; -#endif +#endif /* IRQ_XMIT */ + } while (--boguscount && didsomething); -#if 0 - break; /* delete me */ -#endif - } while (--boguscount); - BUGLVL(D_DURING) printk("arcnet: net_interrupt complete (status=%Xh)\n", inb(STATUS)); - + +#ifdef IRQ_XMIT + if (dev->start && lp->sending ) + outb(NORXflag|TXFREEflag,INTMASK); + else + outb(NORXflag,INTMASK); +#endif + dev->interrupt=0; - return; } /* A packet has arrived; grab it from the buffers and possibly unsplit it. @@ -1350,9 +1662,9 @@ * process should be aborted. * * The RFC also mentions "it is possible for successfully - * received packets to be retransmitted." I'm hoping this - * means only the most recent one, which is the only one - * currently allowed. + * received packets to be retransmitted." As of 0.40 all + * previously received packets are allowed, not just the + * most recent one. * * We allow multiple assembly processes, one for each * ARCnet card possible on the network. Seems rather like @@ -1372,7 +1684,6 @@ kfree_skb(in->skb,FREE_WRITE); in->skb=NULL; in->lastpacket=in->numpackets=0; - return; } if (arcsoft->split_flag & 1) /* first packet in split */ @@ -1449,7 +1760,7 @@ if (packetnum!=in->lastpacket) /* not the right flag! */ { /* harmless duplicate? ignore. */ - if (packetnum==in->lastpacket-1) + if (packetnum<=in->lastpacket-1) { BUGLVL(D_INIT) printk("arcnet: duplicate splitpacket ignored! (splitflag=%d)\n", arcsoft->split_flag); @@ -1519,7 +1830,7 @@ } - +#ifdef USE_TIMER_HANDLER /* this function is called every once in a while to make sure the ARCnet * isn't stuck. * @@ -1553,7 +1864,7 @@ lp->timer.expires=TIMERval; add_timer(&lp->timer); } - +#endif /* Get the current statistics. This may be called with the card open or closed. */ @@ -1601,7 +1912,8 @@ inb(RESET); /* Reset by reading this port */ JIFFER(RESETtime); - outb(CFLAGScmd|RESETclear|CONFIGclear,COMMAND); /* clear flags & end reset */ + outb(CFLAGScmd|RESETclear, COMMAND); /* clear flags & end reset */ + outb(CFLAGScmd|CONFIGclear,COMMAND); /* after a reset, the first byte of shared mem is TESTvalue and the * second byte is our 8-bit ARCnet address @@ -1619,18 +1931,12 @@ /* clear out status variables */ recbuf=lp->recbuf=0; - dev->tbusy=0; - - /* enable IRQ's on completed receive - * I messed around for a long time, but I couldn't get tx and rx - * irq's to work together. It looks like one or the other but not - * both... . The Crynwr driver uses only rx, and so do I now. - */ - outb(NORXflag,INTMASK); + lp->txbuf=2; + /*dev->tbusy=0;*/ /* enable extended (512-byte) packets */ outb(CONFIGcmd|EXTconf,COMMAND); - JIFFER(ACKtime); + XJIFFER(ACKtime); /* clean out all the memory to make debugging make more sense :) */ BUGLVL(D_DURING) @@ -1638,6 +1944,9 @@ /* and enable receive of our first packet to the first buffer */ EnableReceiver(); + + /* re-enable interrupts */ + outb(NORXflag,INTMASK); /* done! return success. */ return 0; @@ -1668,6 +1977,9 @@ case ETH_P_RARP: head->protocol_id=ARC_P_RARP; break; + case ETH_P_IPX: + head->protocol_id=ARC_P_IPX; + break; default: printk("arcnet: I don't understand protocol %d (%Xh)\n", type,type); @@ -1782,12 +2094,12 @@ /* now return the protocol number */ switch (head->protocol_id) { - case ARC_P_IP: return htons(ETH_P_IP); /* what the heck is - an htons, anyway? */ + case ARC_P_IP: return htons(ETH_P_IP); case ARC_P_ARP: return htons(ETH_P_ARP); case ARC_P_RARP: return htons(ETH_P_RARP); - case 0xFA: /* IPX */ - case 0xDD: /* Appletalk */ + case ARC_P_IPX: return htons(ETH_P_IPX); + case ARC_P_LANSOFT: /* don't understand. fall through. */ + case ARC_P_ATALK: /* appletalk - don't understand. fall through. */ default: BUGLVL(D_DURING) printk("arcnet: received packet of unknown protocol id %d (%Xh)\n", @@ -1811,6 +2123,59 @@ return htons(ETH_P_IP); } + +#ifdef MODULE +char kernel_version[] = UTS_RELEASE; +static struct device thisARCnet = { + " ",/* if blank, device name inserted by /linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, /* I/O address, IRQ */ + 0, 0, 0, NULL, arcnet_probe }; + + +int io=0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */ +int irqnum=0; /* or use the insmod io= irq= shmem= options */ +int shmem=0; +int num=0; /* number of device (ie for arc0, arc1, arc2...) */ + +int +init_module(void) +{ + sprintf(thisARCnet.name,"arc%d",num); + + thisARCnet.base_addr=io; + + thisARCnet.irq=irqnum; + if (thisARCnet.irq==2) thisARCnet.irq=9; + + if (shmem) + { + thisARCnet.mem_start=shmem; + thisARCnet.mem_end=thisARCnet.mem_start+512*4-1; + thisARCnet.rmem_start=thisARCnet.mem_start+512*0; + thisARCnet.rmem_end=thisARCnet.mem_start+512*2-1; + } + + if (register_netdev(&thisARCnet) != 0) + return -EIO; + return 0; +} + +void +cleanup_module(void) +{ + if (MOD_IN_USE) { + printk("%s: device busy, remove delayed\n",thisARCnet.name); + } else { + if (thisARCnet.start) arcnet_close(&thisARCnet); + if (thisARCnet.irq) free_irq(thisARCnet.irq); + if (thisARCnet.base_addr) release_region(thisARCnet.base_addr, + ETHERCARD_TOTAL_SIZE); + unregister_netdev(&thisARCnet); + } +} + +#endif /* MODULE */ diff -u --recursive --new-file v1.1.94/linux/drivers/net/depca.c linux/drivers/net/depca.c --- v1.1.94/linux/drivers/net/depca.c Wed Feb 15 10:36:38 1995 +++ linux/drivers/net/depca.c Thu Feb 23 10:51:12 1995 @@ -171,11 +171,13 @@ 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0. 0.381 12-dec-94 Added DE101 recognition, fix multicast bug. 0.382 9-feb-95 Fix recognition bug reported by . + 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by + ========================================================================= */ -static char *version = "depca.c:v0.382 2/9/94 davies@wanton.lkg.dec.com\n"; +static char *version = "depca.c:v0.383 2/22/94 davies@wanton.lkg.dec.com\n"; #include #ifdef MODULE @@ -333,15 +335,16 @@ /* ** Private functions */ -static int depca_probe1(struct device *dev, short ioaddr); +static int depca_probe1(struct device *dev, short ioaddr); static void depca_init_ring(struct device *dev); -static int depca_rx(struct device *dev); -static int depca_tx(struct device *dev); +static int depca_rx(struct device *dev); +static int depca_tx(struct device *dev); static void LoadCSRs(struct device *dev); -static int InitRestartDepca(struct device *dev); +static int InitRestartDepca(struct device *dev); static char *DepcaSignature(unsigned long mem_addr); -static int DevicePresent(short ioaddr); +static int DevicePresent(short ioaddr); +static int EISA_signature(short iobase); #ifdef HAVE_MULTICAST static void SetMulticastFilter(int num_addrs, char *addrs, char *multicast_table); #endif @@ -1346,7 +1349,7 @@ ioaddr+=0x1000; /* get the first slot address */ for (status = -ENODEV, i=1; i 0) { /* only gets here in autoprobe */ dev = alloc_device(dev, ioaddr); } else { @@ -1501,6 +1504,40 @@ } return status; +} + +/* +** Look for a particular board name in the EISA configuration space +*/ +static int EISA_signature(short iobase) +{ + unsigned long i; + int status; + char *signatures[] = DEPCA_SIGNATURE; + char ManCode[8]; + union { + u_long ID; + u_char Id[4]; + } Eisa; + + for (i=0; i<4; i++) { + Eisa.Id[i] = inb(iobase + i); + } + + ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40); + ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40); + ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30); + ManCode[3]=((Eisa.Id[2]&0x0f)+0x30); + ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30); + ManCode[5]='\0'; + + for (status = -ENXIO, i=0;*signatures[i] != '\0' && status;i++) { + if (strstr(ManCode, signatures[i]) != NULL) { + status = 0; + } + } + + return status; /* return the device name string */ } #ifdef MODULE diff -u --recursive --new-file v1.1.94/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v1.1.94/linux/drivers/net/ppp.c Fri Feb 17 11:20:13 1995 +++ linux/drivers/net/ppp.c Thu Feb 23 13:19:17 1995 @@ -1463,7 +1463,6 @@ case PPPIOCSASYNCMAP: error = verify_area (VERIFY_READ, (void *) l, sizeof (temp_i)); if (error == 0) { - memset (ppp->xmit_async_map, 0, sizeof (ppp->xmit_async_map)); ppp->xmit_async_map[0] = get_fs_long (l); bset (ppp->xmit_async_map, PPP_FLAG); bset (ppp->xmit_async_map, PPP_ESC); diff -u --recursive --new-file v1.1.94/linux/drivers/net/slip.c linux/drivers/net/slip.c --- v1.1.94/linux/drivers/net/slip.c Sun Feb 5 19:31:53 1995 +++ linux/drivers/net/slip.c Thu Feb 23 13:27:11 1995 @@ -35,6 +35,7 @@ * Dmitry Gorodchanin : Even more cleanups. Preserve CSLIP * statistics. Include CSLIP code only * if it really needed. + * Alan Cox : Free slhc buffers in the right place. * * * @@ -116,6 +117,32 @@ static inline void sl_free(struct slip *sl) { + /* Free all SLIP frame buffers. */ + if (sl->rbuff) { + kfree(sl->rbuff); + } + sl->rbuff = NULL; + if (sl->xbuff) { + kfree(sl->xbuff); + } + sl->xbuff = NULL; +#ifdef SL_INCLUDE_CSLIP + /* Save CSLIP statistics */ + if (sl->slcomp) { + sl->rx_compressed += sl->slcomp->sls_i_compressed; + sl->rx_dropped += sl->slcomp->sls_i_tossed; + sl->tx_compressed += sl->slcomp->sls_o_compressed; + sl->tx_misses += sl->slcomp->sls_o_misses; + } + if (sl->cbuff) { + kfree(sl->cbuff); + } + sl->cbuff = NULL; + if(sl->slcomp) + slhc_free(sl->slcomp); + sl->slcomp = NULL; +#endif + if (!clear_bit(SLF_INUSE, &sl->flags)) { printk("%s: sl_free for already free unit.\n", sl->dev->name); } @@ -581,30 +608,6 @@ /* dev->flags &= ~IFF_UP; */ - /* Free all SLIP frame buffers. */ - if (sl->rbuff) { - kfree(sl->rbuff); - } - sl->rbuff = NULL; - if (sl->xbuff) { - kfree(sl->xbuff); - } - sl->xbuff = NULL; -#ifdef SL_INCLUDE_CSLIP - /* Save CSLIP statistics */ - if (sl->slcomp) { - sl->rx_compressed += sl->slcomp->sls_i_compressed; - sl->rx_dropped += sl->slcomp->sls_i_tossed; - sl->tx_compressed += sl->slcomp->sls_o_compressed; - sl->tx_misses += sl->slcomp->sls_o_misses; - } - if (sl->cbuff) { - kfree(sl->cbuff); - } - sl->cbuff = NULL; - slhc_free(sl->slcomp); - sl->slcomp = NULL; -#endif return 0; } diff -u --recursive --new-file v1.1.94/linux/drivers/scsi/qlogic.c linux/drivers/scsi/qlogic.c --- v1.1.94/linux/drivers/scsi/qlogic.c Mon Feb 20 21:34:55 1995 +++ linux/drivers/scsi/qlogic.c Thu Feb 23 13:32:05 1995 @@ -18,7 +18,7 @@ Reference Qlogic FAS408 Technical Manual, 53408-510-00A, May 10, 1994 (you can reference it, but it is incomplete and inaccurate in places) - Version 0.40a + Version 0.41 Functions as standalone, loadable, and PCMCIA driver, the latter from Dave Hind's PCMCIA package. @@ -37,6 +37,9 @@ again, 0 tends to be slower, but more stable. */ #define QL_TURBO_PDMA 1 +/* This should be 1 to enable parity detection */ +#define QL_ENABLE_PARITY 1 + /* This will reset all devices when the driver is initialized (during bootup). The other linux drivers don't do this, but the DOS drivers do, and after using DOS or some kind of crash or lockup this will bring things back @@ -45,31 +48,42 @@ recognized when this was set. */ #define QL_RESET_AT_START 0 -/* crystal frequency in megahertz (for offset 5 and 9) */ +/* crystal frequency in megahertz (for offset 5 and 9) + Please set this for your card. Most Qlogic cards are 40 Mhz. The + Control Concepts ISA (not VLB) is 24 Mhz */ #define XTALFREQ 40 -/*****/ -/* offset 0xc */ -/* This will set fast (10Mhz) synchronous timing when set to 1 - FASTCLK must also be 0 */ -#define FASTSCSI 0 - -/* This when set to 1 will set a faster sync transfer rate */ -#define FASTCLK 0 +/**********/ +/* DANGER! modify these at your own risk */ +/* SLOWCABLE can usually be reset to zero if you have a clean setup and + proper termination. The rest are for synchronous transfers and other + advanced features if your device can transfer faster than 5Mb/sec. + If you are really curious, email me for a quick howto until I have + something official */ +/**********/ /*****/ /* config register 1 (offset 8) options */ /* This needs to be set to 1 if your cabling is long or noisy */ -#define SLOWCABLE 0 +#define SLOWCABLE 1 -/* This should be 1 to enable parity detection */ -#define QL_ENABLE_PARITY 1 +/*****/ +/* offset 0xc */ +/* This will set fast (10Mhz) synchronous timing when set to 1 + For this to have an effect, FASTCLK must also be 1 */ +#define FASTSCSI 0 + +/* This when set to 1 will set a faster sync transfer rate */ +#define FASTCLK 0 +/*(XTALFREQ>25?1:0)*/ /*****/ /* offset 6 */ -/* This is the sync transfer divisor, 40Mhz/X will be the data rate - The power on default is 5, the maximum normal value is 5 */ +/* This is the sync transfer divisor, XTALFREQ/X will be the maximum + achievable data rate (assuming the rest of the system is capable + and set properly) */ #define SYNCXFRPD 4 +/*(XTALFREQ/5)*/ /*****/ /* offset 7 */ @@ -164,6 +178,7 @@ j = 0; if (phase & 1) { /* in */ #if QL_TURBO_PDMA +rtrc(4) /* empty fifo in large chunks */ if( reqlen >= 128 && (inb( qbase + 8 ) & 2) ) { /* full */ insl( qbase + 4, request, 32 ); @@ -183,6 +198,7 @@ } #endif /* until both empty and int (or until reclen is 0) */ +rtrc(7) j = 0; while( reqlen && !( (j & 0x10) && (j & 0xc0) ) ) { /* while bytes to receive and not empty */ @@ -198,6 +214,7 @@ } else { /* out */ #if QL_TURBO_PDMA +rtrc(4) if( reqlen >= 128 && inb( qbase + 8 ) & 0x10 ) { /* empty */ outsl(qbase + 4, request, 32 ); reqlen -= 128; @@ -216,6 +233,7 @@ } #endif /* until full and int (or until reclen is 0) */ +rtrc(7) j = 0; while( reqlen && !( (j & 2) && (j & 0xc0) ) ) { /* while bytes to send and not full */ @@ -308,6 +326,7 @@ struct scatterlist *sglist; /* scatter-gather list pointer */ unsigned int sgcount; /* sg counter */ +rtrc(1) j = inb(qbase + 6); i = inb(qbase + 5); if (i == 0x20) { @@ -336,7 +355,7 @@ reqlen = cmd->request_bufflen; /* note that it won't work if transfers > 16M are requested */ if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */ -rtrc(1) +rtrc(2) outb(reqlen, qbase); /* low-mid xfer cnt */ outb(reqlen >> 8, qbase+1); /* low-mid xfer cnt */ outb(reqlen >> 16, qbase + 0xe); /* high xfer cnt */ @@ -367,7 +386,6 @@ } /*** Enter Status (and Message In) Phase ***/ k = jiffies + WATCHDOG; -rtrc(4) while ( k > jiffies && !qabort && !(inb(qbase + 4) & 6)); /* wait for status phase */ if ( k <= jiffies ) { ql_zap(); @@ -389,7 +407,7 @@ result = DID_ERROR; } outb(0x12, qbase + 3); /* done, disconnect */ -rtrc(3) +rtrc(1) if ((k = ql_wai())) return (k << 16); /* should get bus service interrupt and disconnect interrupt */ @@ -573,7 +591,7 @@ if( qlirq != -1 ) hreg->irq = qlirq; - sprintf(qinfo, "Qlogic Driver version 0.40a, chip %02X at %03X, IRQ %d, TPdma:%d", + sprintf(qinfo, "Qlogic Driver version 0.41, chip %02X at %03X, IRQ %d, TPdma:%d", qltyp, qbase, qlirq, QL_TURBO_PDMA ); host->name = qinfo; diff -u --recursive --new-file v1.1.94/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c --- v1.1.94/linux/drivers/scsi/seagate.c Mon Feb 20 21:34:55 1995 +++ linux/drivers/scsi/seagate.c Thu Feb 23 13:31:41 1995 @@ -283,7 +283,7 @@ * First, we try for the manual override. */ #ifdef DEBUG - printk("Autodetecting seagate ST0x\n"); + printk("Autodetecting ST0x / TMC-8xx\n"); #endif if (hostno != -1) @@ -357,39 +357,40 @@ borken_init(); #endif - return 1; - } - else - { -#ifdef DEBUG - printk("ST0x not detected.\n"); -#endif - return 0; - } - } - -const char *seagate_st0x_info(struct Scsi_Host * shpnt) { - static char buffer[256]; - sprintf(buffer, "scsi%d : %s at irq %d address %p options :" + printk("%s options:" #ifdef ARBITRATE -" ARBITRATE" + " ARBITRATE" #endif #ifdef SLOW_HANDSHAKE -" SLOW_HANDSHAKE" + " SLOW_HANDSHAKE" #endif #ifdef FAST #ifdef FAST32 -" FAST32" + " FAST32" #else -" FAST" + " FAST" #endif #endif - #ifdef LINKED -" LINKED" + " LINKED" #endif - "\n", hostno, (controller_type == SEAGATE) ? ST0X_ID_STR : - FD_ID_STR, irq, base_address); + "\n", tpnt->name); + return 1; + } + else + { +#ifdef DEBUG + printk("ST0x / TMC-8xx not detected.\n"); +#endif + return 0; + } + } + +const char *seagate_st0x_info(struct Scsi_Host * shpnt) { + static char buffer[64]; + sprintf(buffer, "%s at irq %d, address 0x%05X", + (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR, + irq, (unsigned int)base_address); return buffer; } diff -u --recursive --new-file v1.1.94/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v1.1.94/linux/drivers/scsi/sr.c Mon Feb 20 21:34:55 1995 +++ linux/drivers/scsi/sr.c Thu Feb 23 13:31:41 1995 @@ -352,7 +352,7 @@ break; } if (rec[14] != 0 && rec[14] != 0xb0) { - printk("sr_photocd: Hmm, seems the CDROM does'nt support multisession CD's\n"); + printk("sr_photocd: Hmm, seems the CDROM doesn't support multisession CD's\n"); no_multi = 1; break; } @@ -385,13 +385,13 @@ if (rc != 0) { if (rc == 0x28000002) { /* Got a "not ready" - error. No chance to find out if this is - becauce there is no CD in the drive or becauce the drive + because there is no CD in the drive or because the drive don't knows multisession CD's. So I need to do an extra check... */ if (kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device, SCSI_IOCTL_TEST_UNIT_READY, NULL)) { printk("sr_photocd: drive not ready\n"); } else { - printk("sr_photocd: Hmm, seems the CDROM does'nt support multisession CD's\n"); + printk("sr_photocd: Hmm, seems the CDROM doesn't support multisession CD's\n"); no_multi = 1; } } else diff -u --recursive --new-file v1.1.94/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c --- v1.1.94/linux/fs/ext2/balloc.c Wed Nov 30 21:47:39 1994 +++ linux/fs/ext2/balloc.c Sun Feb 26 18:52:02 1995 @@ -75,7 +75,7 @@ ext2_panic (sb, "read_block_bitmap", "Cannot read block bitmap - " "block_group = %d, block_bitmap = %lu", - block_group, gdp->bg_block_bitmap); + block_group, (unsigned long) gdp->bg_block_bitmap); sb->u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group; sb->u.ext2_sb.s_block_bitmap[bitmap_nr] = bh; } @@ -249,8 +249,8 @@ * bitmap, and then for any free bit if that fails. */ int ext2_new_block (struct super_block * sb, unsigned long goal, - unsigned long * prealloc_count, - unsigned long * prealloc_block) + u32 * prealloc_count, + u32 * prealloc_block) { struct buffer_head * bh; struct buffer_head * bh2; @@ -577,6 +577,6 @@ ext2_error (sb, "ext2_check_blocks_bitmap", "Wrong free blocks count in super block, " "stored = %lu, counted = %lu", - es->s_free_blocks_count, bitmap_count); + (unsigned long) es->s_free_blocks_count, bitmap_count); unlock_super (sb); } diff -u --recursive --new-file v1.1.94/linux/fs/ext2/dir.c linux/fs/ext2/dir.c --- v1.1.94/linux/fs/ext2/dir.c Fri Oct 21 09:39:35 1994 +++ linux/fs/ext2/dir.c Sun Feb 26 18:52:02 1995 @@ -92,7 +92,7 @@ if (error_msg != NULL) ext2_error (dir->i_sb, function, "bad directory entry: %s\n" "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", - error_msg, offset, de->inode, de->rec_len, + error_msg, offset, (unsigned long) de->inode, de->rec_len, de->name_len); return error_msg == NULL ? 1 : 0; } diff -u --recursive --new-file v1.1.94/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c --- v1.1.94/linux/fs/ext2/fsync.c Fri Dec 31 11:59:48 1993 +++ linux/fs/ext2/fsync.c Sun Feb 26 18:52:02 1995 @@ -27,7 +27,7 @@ #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb)) #define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb)) -static int sync_block (struct inode * inode, unsigned long * block, int wait) +static int sync_block (struct inode * inode, u32 * block, int wait) { struct buffer_head * bh; int tmp; @@ -55,7 +55,7 @@ return 0; } -static int sync_iblock (struct inode * inode, unsigned long * iblock, +static int sync_iblock (struct inode * inode, u32 * iblock, struct buffer_head ** bh, int wait) { int rc, tmp; @@ -94,8 +94,7 @@ return err; } -static int sync_indirect (struct inode * inode, unsigned long * iblock, - int wait) +static int sync_indirect (struct inode * inode, u32 * iblock, int wait) { int i; struct buffer_head * ind_bh; @@ -107,7 +106,7 @@ for (i = 0; i < addr_per_block; i++) { rc = sync_block (inode, - ((unsigned long *) ind_bh->b_data) + i, + ((u32 *) ind_bh->b_data) + i, wait); if (rc > 0) break; @@ -118,8 +117,7 @@ return err; } -static int sync_dindirect (struct inode * inode, unsigned long * diblock, - int wait) +static int sync_dindirect (struct inode * inode, u32 * diblock, int wait) { int i; struct buffer_head * dind_bh; @@ -131,7 +129,7 @@ for (i = 0; i < addr_per_block; i++) { rc = sync_indirect (inode, - ((unsigned long *) dind_bh->b_data) + i, + ((u32 *) dind_bh->b_data) + i, wait); if (rc > 0) break; @@ -142,8 +140,7 @@ return err; } -static int sync_tindirect (struct inode * inode, unsigned long * tiblock, - int wait) +static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait) { int i; struct buffer_head * tind_bh; @@ -155,7 +152,7 @@ for (i = 0; i < addr_per_block; i++) { rc = sync_dindirect (inode, - ((unsigned long *) tind_bh->b_data) + i, + ((u32 *) tind_bh->b_data) + i, wait); if (rc > 0) break; diff -u --recursive --new-file v1.1.94/linux/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c --- v1.1.94/linux/fs/ext2/ialloc.c Wed Nov 30 21:47:39 1994 +++ linux/fs/ext2/ialloc.c Sun Feb 26 18:52:02 1995 @@ -74,7 +74,7 @@ ext2_panic (sb, "read_inode_bitmap", "Cannot read inode bitmap - " "block_group = %lu, inode_bitmap = %lu", - block_group, gdp->bg_inode_bitmap); + block_group, (unsigned long) gdp->bg_inode_bitmap); sb->u.ext2_sb.s_inode_bitmap_number[bitmap_nr] = block_group; sb->u.ext2_sb.s_inode_bitmap[bitmap_nr] = bh; } @@ -549,6 +549,6 @@ ext2_error (sb, "ext2_check_inodes_bitmap", "Wrong free inodes count in super block, " "stored = %lu, counted = %lu", - es->s_free_inodes_count, bitmap_count); + (unsigned long) es->s_free_inodes_count, bitmap_count); unlock_super (sb); } diff -u --recursive --new-file v1.1.94/linux/fs/ext2/inode.c linux/fs/ext2/inode.c --- v1.1.94/linux/fs/ext2/inode.c Thu Jan 26 07:49:07 1995 +++ linux/fs/ext2/inode.c Sun Feb 26 18:52:02 1995 @@ -46,7 +46,7 @@ if (!bh) return 0; - tmp = ((unsigned long *) bh->b_data)[nr]; + tmp = ((u32 *) bh->b_data)[nr]; brelse (bh); return tmp; } @@ -182,8 +182,8 @@ static struct buffer_head * inode_getblk (struct inode * inode, int nr, int create, int new_block, int * err) { + u32 * p; int tmp, goal = 0; - unsigned long * p; struct buffer_head * result; int blocks = inode->i_sb->s_blocksize / 512; @@ -250,7 +250,7 @@ int new_block, int * err) { int tmp, goal = 0; - unsigned long * p; + u32 * p; struct buffer_head * result; int blocks = inode->i_sb->s_blocksize / 512; @@ -264,7 +264,7 @@ return NULL; } } - p = (unsigned long *) bh->b_data + nr; + p = (u32 *) bh->b_data + nr; repeat: tmp = *p; if (tmp) { @@ -287,8 +287,8 @@ goal = inode->u.ext2_i.i_next_alloc_goal; if (!goal) { for (tmp = nr - 1; tmp >= 0; tmp--) { - if (((unsigned long *) bh->b_data)[tmp]) { - goal = ((unsigned long *)bh->b_data)[tmp]; + if (((u32 *) bh->b_data)[tmp]) { + goal = ((u32 *)bh->b_data)[tmp]; break; } } @@ -325,7 +325,7 @@ int nr, int blocksize) { - unsigned long * p; + u32 * p; int firstblock = 0; int result = 0; int i; @@ -338,7 +338,7 @@ if(nr + 3 > EXT2_ADDR_PER_BLOCK(inode->i_sb)) goto out; for(i=0; i< (PAGE_SIZE / inode->i_sb->s_blocksize); i++) { - p = (unsigned long *) bh->b_data + nr + i; + p = (u32 *) bh->b_data + nr + i; /* All blocks in cluster must already be allocated */ if(*p == 0) goto out; @@ -346,9 +346,9 @@ /* See if aligned correctly */ if(i==0) firstblock = *p; else if(*p != firstblock + i) goto out; - }; + } - p = (unsigned long *) bh->b_data + nr; + p = (u32 *) bh->b_data + nr; result = generate_cluster(bh->b_dev, (int *) p, blocksize); out: diff -u --recursive --new-file v1.1.94/linux/fs/ext2/super.c linux/fs/ext2/super.c --- v1.1.94/linux/fs/ext2/super.c Fri Nov 4 12:38:45 1994 +++ linux/fs/ext2/super.c Sun Feb 26 18:52:02 1995 @@ -360,7 +360,7 @@ ext2_error (sb, "ext2_check_descriptors", "Block bitmap for group %d" " not in group (block %lu)!", - i, gdp->bg_block_bitmap); + i, (unsigned long) gdp->bg_block_bitmap); return 0; } if (gdp->bg_inode_bitmap < block || @@ -369,7 +369,7 @@ ext2_error (sb, "ext2_check_descriptors", "Inode bitmap for group %d" " not in group (block %lu)!", - i, gdp->bg_inode_bitmap); + i, (unsigned long) gdp->bg_inode_bitmap); return 0; } if (gdp->bg_inode_table < block || @@ -379,7 +379,7 @@ ext2_error (sb, "ext2_check_descriptors", "Inode table for group %d" " not in group (block %lu)!", - i, gdp->bg_inode_table); + i, (unsigned long) gdp->bg_inode_table); return 0; } block += EXT2_BLOCKS_PER_GROUP(sb); diff -u --recursive --new-file v1.1.94/linux/fs/ext2/truncate.c linux/fs/ext2/truncate.c --- v1.1.94/linux/fs/ext2/truncate.c Fri Aug 19 13:42:54 1994 +++ linux/fs/ext2/truncate.c Sun Feb 26 18:52:02 1995 @@ -45,8 +45,8 @@ static int trunc_direct (struct inode * inode) { + u32 * p; int i, tmp; - unsigned long * p; struct buffer_head * bh; unsigned long block_to_free = 0; unsigned long free_count = 0; @@ -102,12 +102,12 @@ return retry; } -static int trunc_indirect (struct inode * inode, int offset, unsigned long * p) +static int trunc_indirect (struct inode * inode, int offset, u32 * p) { int i, tmp; struct buffer_head * bh; struct buffer_head * ind_bh; - unsigned long * ind; + u32 * ind; unsigned long block_to_free = 0; unsigned long free_count = 0; int retry = 0; @@ -134,7 +134,7 @@ i = 0; if (i < indirect_block) goto repeat; - ind = i + (unsigned long *) ind_bh->b_data; + ind = i + (u32 *) ind_bh->b_data; tmp = *ind; if (!tmp) continue; @@ -176,7 +176,7 @@ } if (free_count > 0) ext2_free_blocks (inode->i_sb, block_to_free, free_count); - ind = (unsigned long *) ind_bh->b_data; + ind = (u32 *) ind_bh->b_data; for (i = 0; i < addr_per_block; i++) if (*(ind++)) break; @@ -199,11 +199,11 @@ } static int trunc_dindirect (struct inode * inode, int offset, - unsigned long * p) + u32 * p) { int i, tmp; struct buffer_head * dind_bh; - unsigned long * dind; + u32 * dind; int retry = 0; int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb); int blocks = inode->i_sb->s_blocksize / 512; @@ -228,7 +228,7 @@ i = 0; if (i < dindirect_block) goto repeat; - dind = i + (unsigned long *) dind_bh->b_data; + dind = i + (u32 *) dind_bh->b_data; tmp = *dind; if (!tmp) continue; @@ -236,7 +236,7 @@ dind); mark_buffer_dirty(dind_bh, 1); } - dind = (unsigned long *) dind_bh->b_data; + dind = (u32 *) dind_bh->b_data; for (i = 0; i < addr_per_block; i++) if (*(dind++)) break; @@ -262,7 +262,7 @@ { int i, tmp; struct buffer_head * tind_bh; - unsigned long * tind, * p; + u32 * tind, * p; int retry = 0; int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb); int blocks = inode->i_sb->s_blocksize / 512; @@ -289,13 +289,13 @@ i = 0; if (i < tindirect_block) goto repeat; - tind = i + (unsigned long *) tind_bh->b_data; + tind = i + (u32 *) tind_bh->b_data; retry |= trunc_dindirect(inode, EXT2_NDIR_BLOCKS + addr_per_block + (i + 1) * addr_per_block * addr_per_block, tind); mark_buffer_dirty(tind_bh, 1); } - tind = (unsigned long *) tind_bh->b_data; + tind = (u32 *) tind_bh->b_data; for (i = 0; i < addr_per_block; i++) if (*(tind++)) break; @@ -331,10 +331,10 @@ down(&inode->i_sem); retry = trunc_direct(inode); retry |= trunc_indirect (inode, EXT2_IND_BLOCK, - (unsigned long *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]); + (u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]); retry |= trunc_dindirect (inode, EXT2_IND_BLOCK + EXT2_ADDR_PER_BLOCK(inode->i_sb), - (unsigned long *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]); + (u32 *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]); retry |= trunc_tindirect (inode); up(&inode->i_sem); if (!retry) diff -u --recursive --new-file v1.1.94/linux/fs/msdos/inode.c linux/fs/msdos/inode.c --- v1.1.94/linux/fs/msdos/inode.c Thu Jan 26 07:49:08 1995 +++ linux/fs/msdos/inode.c Sun Feb 26 18:52:02 1995 @@ -275,7 +275,7 @@ MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start,MSDOS_SB(sb)-> fat_length,MSDOS_SB(sb)->dir_start,MSDOS_SB(sb)->dir_entries, MSDOS_SB(sb)->data_start,CF_LE_W(*(unsigned short *) &b-> - sectors),b->total_sect,logical_sector_size); + sectors),(unsigned long)b->total_sect,logical_sector_size); printk ("Transaction block size = %d\n",blksize); } if (error) { diff -u --recursive --new-file v1.1.94/linux/fs/proc/array.c linux/fs/proc/array.c --- v1.1.94/linux/fs/proc/array.c Fri Feb 17 11:20:16 1995 +++ linux/fs/proc/array.c Thu Feb 23 13:31:41 1995 @@ -277,7 +277,7 @@ { #ifdef __i386__ char *model[2][9]={{"DX","SX","DX/2","4","SX/2","6", - "7","DX/4"}, + "DX/2-WB","DX/4"}, {"Pentium 60/66","Pentium 90/100","3", "4","5","6","7","8"}}; char mask[2]; diff -u --recursive --new-file v1.1.94/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h --- v1.1.94/linux/include/asm-alpha/pgtable.h Wed Feb 22 16:53:05 1995 +++ linux/include/asm-alpha/pgtable.h Thu Mar 2 09:04:40 1995 @@ -22,10 +22,12 @@ /* * entries per page directory level: the alpha is three-level, with * all levels having a one-page page table. + * + * The PGD is special: the last entry is reserved for self-mapping. */ #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) #define PTRS_PER_PMD (1UL << (PAGE_SHIFT-3)) -#define PTRS_PER_PGD (1UL << (PAGE_SHIFT-3)) +#define PTRS_PER_PGD ((1UL << (PAGE_SHIFT-3))-1) /* the no. of pointers that fit on a page: this will go away */ #define PTRS_PER_PAGE (1UL << (PAGE_SHIFT-3)) @@ -158,7 +160,7 @@ extern inline int pte_none(pte_t pte) { return !pte_val(pte); } extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; } -extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] > 1; } +extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; } extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } extern inline void pte_reuse(pte_t * ptep) { @@ -169,7 +171,7 @@ extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || pmd_page(pmd) > high_memory; } extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; } -extern inline int pmd_inuse(pmd_t *pmdp) { return mem_map[MAP_NR(pmdp)] > 1; } +extern inline int pmd_inuse(pmd_t *pmdp) { return mem_map[MAP_NR(pmdp)] != 1; } extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; } extern inline void pmd_reuse(pmd_t * pmdp) { @@ -180,7 +182,7 @@ extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); } extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; } extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; } -extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] > 1; } +extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] != 1; } extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; } extern inline void pgd_reuse(pgd_t * pgdp) { @@ -212,9 +214,10 @@ extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; } -/* to set the page-dir */ +/* to set the page-dir. Note the self-mapping in the last entry */ extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir) { + pgd_val(pgdir[PTRS_PER_PGD]) = pte_val(mk_pte((unsigned long) pgdir, PAGE_KERNEL)); tsk->tss.ptbr = ((unsigned long) pgdir - PAGE_OFFSET) >> PAGE_SHIFT; if (tsk == current) invalidate(); @@ -222,23 +225,23 @@ #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) -/* to find an entry in a page-table-directory */ +/* to find an entry in a page-table-directory. */ extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address) { return (pgd_t *) ((tsk->tss.ptbr << PAGE_SHIFT) + PAGE_OFFSET) + - ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); + ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); } /* Find an entry in the second-level page table.. */ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { - return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); + return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); } /* Find an entry in the third-level page table.. */ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) { - return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); + return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1)); } /* @@ -373,5 +376,14 @@ } extern pgd_t swapper_pg_dir[1024]; + +/* + * The alpha doesn't have any external MMU info: the kernel page + * tables contain all the necessary information. + */ +extern inline void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ +} #endif /* _ALPHA_PGTABLE_H */ diff -u --recursive --new-file v1.1.94/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v1.1.94/linux/include/asm-alpha/processor.h Wed Feb 15 10:36:39 1995 +++ linux/include/asm-alpha/processor.h Fri Feb 24 16:41:01 1995 @@ -8,12 +8,9 @@ #define __ASM_ALPHA_PROCESSOR_H /* - * We have a 8GB user address space to start with: 33 bits of vm - * can be handled with just 2 page table levels. - * - * Eventually, this should be bumped to 40 bits or so.. + * We have a 41-bit user address space: 2TB user VM... */ -#define TASK_SIZE (0x200000000UL) +#define TASK_SIZE (0x20000000000UL) /* * Bus types @@ -39,6 +36,9 @@ unsigned long flags; unsigned long res1, res2; }; + +#define INIT_MMAP { &init_task, 0xfffffc0000300000, 0xfffffc0010000000, \ + PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } #define INIT_TSS { \ 0, 0, 0, \ diff -u --recursive --new-file v1.1.94/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h --- v1.1.94/linux/include/asm-alpha/system.h Fri Feb 17 11:20:16 1995 +++ linux/include/asm-alpha/system.h Fri Feb 24 16:41:01 1995 @@ -81,7 +81,12 @@ #define halt() __asm__ __volatile__(".long 0"); -#define switch_to(x) panic("switch_to() not yet done") +extern void alpha_switch_to(unsigned long pctxp); + +#define switch_to(p) do { \ + current = p; \ + alpha_switch_to((unsigned long) &(p)->tss - 0xfffffc0000000000); \ +} while (0) #ifndef mb #define mb() __asm__ __volatile__("mb": : :"memory") diff -u --recursive --new-file v1.1.94/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h --- v1.1.94/linux/include/asm-alpha/unistd.h Mon Jan 9 07:22:09 1995 +++ linux/include/asm-alpha/unistd.h Thu Mar 2 09:04:40 1995 @@ -46,4 +46,96 @@ return (type) -1; \ } +#ifdef __KERNEL_SYSCALLS__ + +extern unsigned long kernel_fork(void); +static inline unsigned long fork(void) +{ + printk("[%d]fork()\n",current->pid); + return kernel_fork(); +} + +extern void sys_idle(void); +static inline void idle(void) +{ + printk("[%d]idle()\n",current->pid); + sys_idle(); + for(;;); +} + +extern int sys_setup(void); +static inline int setup(void) +{ + int retval; + + printk("[%d]setup()\n",current->pid); + retval = sys_setup(); + printk("[%d]setup() returned %d\n",current->pid, retval); +} + +extern int sys_open(const char *, int, int); +static inline int open(const char * name, int mode, int flags) +{ + int fd; + printk("[%d]open(%s,%d,%d)\n",current->pid, name, mode, flags); + fd = sys_open(name, mode, flags); + printk("[%d]open(%s,%d,%d)=%d\n",current->pid, name, mode, flags, fd); + return fd; +} + +extern int sys_dup(int); +static inline int dup(int fd) +{ + int newfd = sys_dup(fd); + printk("[%d]dup(%d)=%d\n",current->pid, fd, newfd); + return newfd; +} + +static inline int close(int fd) +{ + printk("[%d]close(%d)\n",current->pid,fd); + return sys_close(fd); +} + +extern int sys_exit(int); +static inline int _exit(int value) +{ + printk("[%d]_exit(%d)\n", current->pid, value); + return sys_exit(value); +} + +#define exit(x) _exit(x) + +extern int sys_write(int, const char *, int); +static inline int write(int fd, const char * buf, int nr) +{ + return sys_write(fd, buf, nr); +} + +extern int sys_read(int, char *, int); +static inline int read(int fd, char * buf, int nr) +{ + int res = sys_read(fd, buf, nr); + printk("[%d]read(%d,%s,%d)=%d\n",current->pid, fd, buf, nr, res); + return res; +} + +#define execve(x,y,z) ({ printk("[%d]execve(%s,%p,%p)\n",current->pid, x, y, z); -1; }) +#define waitpid(x,y,z) sys_waitpid(x,y,z) +#define setsid() ({ printk("[%d]setsid()\n",current->pid); -1; }) +#define sync() ({ printk("[%d]sync()\n",current->pid); -1; }) + +extern int sys_waitpid(int, int *, int); +static inline pid_t wait(int * wait_stat) +{ + long retval, i; + printk("[%d]wait(%p)\n", current->pid, wait_stat); + retval = waitpid(-1,wait_stat,0); + printk("[%d]wait(%p) returned %ld\n", current->pid, wait_stat, retval); + for (i = 0; i < 1000000000; i++); + return retval; +} + +#endif + #endif /* _ALPHA_UNISTD_H */ diff -u --recursive --new-file v1.1.94/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h --- v1.1.94/linux/include/asm-i386/pgtable.h Fri Feb 17 11:20:16 1995 +++ linux/include/asm-i386/pgtable.h Thu Mar 2 09:04:40 1995 @@ -130,7 +130,7 @@ extern inline int pte_none(pte_t pte) { return !pte_val(pte); } extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } -extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] > 1; } +extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; } extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } extern inline void pte_reuse(pte_t * ptep) { @@ -154,7 +154,7 @@ extern inline int pgd_none(pgd_t pgd) { return 0; } extern inline int pgd_bad(pgd_t pgd) { return 0; } extern inline int pgd_present(pgd_t pgd) { return 1; } -extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)] > 1; } +extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)] != 1; } extern inline void pgd_clear(pgd_t * pgdp) { } extern inline void pgd_reuse(pgd_t * pgdp) { @@ -345,5 +345,14 @@ } extern pgd_t swapper_pg_dir[1024]; + +/* + * The i386 doesn't have any external MMU info: the kernel page + * tables contain all the necessary information. + */ +extern inline void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ +} #endif /* _I386_PAGE_H */ diff -u --recursive --new-file v1.1.94/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v1.1.94/linux/include/asm-i386/processor.h Wed Feb 15 10:36:40 1995 +++ linux/include/asm-i386/processor.h Fri Feb 24 16:41:01 1995 @@ -112,6 +112,8 @@ unsigned long v86flags, v86mask, v86mode; }; +#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } + #define INIT_TSS { \ 0,0, \ sizeof(init_kernel_stack) + (long) &init_kernel_stack, \ diff -u --recursive --new-file v1.1.94/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- v1.1.94/linux/include/asm-i386/unistd.h Tue Oct 11 09:17:04 1994 +++ linux/include/asm-i386/unistd.h Fri Feb 24 16:46:58 1995 @@ -84,4 +84,40 @@ return -1; \ } +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,idle) +static inline _syscall0(int,fork) +static inline _syscall0(int,pause) +static inline _syscall0(int,setup) +static inline _syscall0(int,sync) +static inline _syscall0(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall1(int,dup,int,fd) +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static inline _syscall3(int,open,const char *,file,int,flag,int,mode) +static inline _syscall1(int,close,int,fd) +static inline _syscall1(int,_exit,int,exitcode) +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +#endif + #endif /* _ASM_I386_UNISTD_H_ */ diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/asi.h linux/include/asm-sparc/asi.h --- v1.1.94/linux/include/asm-sparc/asi.h Mon Jan 9 07:22:10 1995 +++ linux/include/asm-sparc/asi.h Sun Feb 26 20:46:20 1995 @@ -10,6 +10,11 @@ * be similar under regular sun4's. */ +#include +#ifdef CONFIG_SUN4M +#include "asi4m.h" +#else + #define ASI_NULL1 0x0 #define ASI_NULL2 0x1 @@ -34,4 +39,5 @@ #define ASI_FLUSHCTX 0xe +#endif /* CONFIG_SUN4M */ #endif /* _SPARC_ASI_H */ diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/asi4m.h linux/include/asm-sparc/asi4m.h --- v1.1.94/linux/include/asm-sparc/asi4m.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-sparc/asi4m.h Sun Feb 26 20:46:20 1995 @@ -0,0 +1,29 @@ +#ifndef _SPARC_ASI4M_H +#define _SPARC_ASI4M_H + +/* asi4m.h: Address Space Identifier values for sun4m + + Copyright (C) 1995 Paul Hatchman (paul@sfe.com.au) +*/ + +#define ASI_PTE 0x0 + +#define ASI_NULL1 0x0 +#define ASI_NULL2 0x1 +#define ASI_CONTROL 0x4 /* hmm? */ +#define ASI_USERTXT 0x8 /* user text */ +#define ASI_KERNELTXT 0x9 /* kernel text */ +#define ASI_USERDATA 0xA /* user data */ +#define ASI_KERNELDATA 0xB /* kernel data */ + +/* cache flushing */ +#define ASI_FLUSHPG 0x10 +#define ASI_FLUSHSEG 0x11 +#define ASI_FLUSHRGN 0x12 +#define ASI_FLUSHCTX 0x13 + +/* MMU REGS */ +#define SRMMU_CTL 0x000 +#define SRMMU_CTP 0x100 /* set/get context pointer */ +#define SRMMU_CTX 0x200 /* get/set context */ +#endif _SPARC_ASI4M_H diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/head.h linux/include/asm-sparc/head.h --- v1.1.94/linux/include/asm-sparc/head.h Mon Feb 20 21:34:56 1995 +++ linux/include/asm-sparc/head.h Sun Feb 26 20:46:20 1995 @@ -12,6 +12,10 @@ #define INT_ENABLE_REG_PHYSADR 0xf5000000 #define INTS_ENAB 0x01 +#define BOOT_MSG_LEN 61 +#define BOOT_MSG2_LEN 50 + + #define WRITE_PAUSE nop; nop; nop; #define PAGE_SIZE 4096 diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/page.h linux/include/asm-sparc/page.h --- v1.1.94/linux/include/asm-sparc/page.h Sun Feb 5 19:31:55 1995 +++ linux/include/asm-sparc/page.h Wed Mar 1 09:12:33 1995 @@ -20,6 +20,19 @@ #ifdef __KERNEL__ +/* The following structure is used to hold the physical + * memory configuration of the machine. This is filled + * in probe_memory() and is later used by mem_init() to + * set up mem_map[]. We statically allocate 14 of these + * structs, this is arbitrary. The entry after the last + * valid one has num_bytes==0. + */ + +struct sparc_phys_banks { + unsigned long base_addr; + unsigned long num_bytes; +}; + #define CONFIG_STRICT_MM_TYPECHECKS #ifdef CONFIG_STRICT_MM_TYPECHECKS @@ -105,17 +118,17 @@ { register unsigned long entry; - __asm__ __volatile__("lduha [%1] 0x3, %0" : + __asm__ __volatile__("lduba [%1] 0x3, %0" : "=r" (entry) : "r" (addr)); - return entry; + return (entry&0x7f); } -extern __inline__ void put_segmap(unsigned long* addr, unsigned long entry) +extern __inline__ void put_segmap(unsigned long addr, unsigned long entry) { - __asm__ __volatile__("stha %1, [%0] 0x3" : : "r" (addr), "r" (entry)); + __asm__ __volatile__("stba %1, [%0] 0x3" : : "r" (addr), "r" (entry&0x7f)); return; } diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/pgtable.h linux/include/asm-sparc/pgtable.h --- v1.1.94/linux/include/asm-sparc/pgtable.h Mon Feb 20 21:34:56 1995 +++ linux/include/asm-sparc/pgtable.h Wed Mar 1 09:12:33 1995 @@ -8,12 +8,12 @@ */ /* PMD_SHIFT determines the size of the area a second-level page table can map */ -#define PMD_SHIFT 22 +#define PMD_SHIFT 18 #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) /* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT 22 +#define PGDIR_SHIFT 18 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) #define PGDIR_ALIGN(addr) (((addr)+PGDIR_SIZE-1)&PGDIR_MASK) @@ -48,7 +48,8 @@ #define _PAGE_VALID 0x80000000 /* valid page */ #define _PAGE_WRITE 0x40000000 /* can be written to */ #define _PAGE_PRIV 0x20000000 /* bit to signify privileged page */ -#define _PAGE_REF 0x02000000 /* Page had been accessed/referenced */ +#define _PAGE_NOCACHE 0x10000000 /* non-cacheable page */ +#define _PAGE_REF 0x02000000 /* Page has been accessed/referenced */ #define _PAGE_DIRTY 0x01000000 /* Page has been modified, is dirty */ #define _PAGE_COW 0x00800000 /* COW page, hardware ignores this bit (untested) */ @@ -71,7 +72,8 @@ #define PAGE_SHARED __pgprot(_PAGE_VALID | _PAGE_WRITE | _PAGE_REF) #define PAGE_COPY __pgprot(_PAGE_VALID | _PAGE_REF | _PAGE_COW) #define PAGE_READONLY __pgprot(_PAGE_VALID | _PAGE_REF) -#define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_PRIV) +#define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_WRITE | _PAGE_NOCACHE | _PAGE_REF | _PAGE_PRIV) +#define PAGE_INVALID __pgprot(_PAGE_PRIV) #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | _PAGE_REF | (x)) diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h --- v1.1.94/linux/include/asm-sparc/processor.h Wed Feb 15 10:36:40 1995 +++ linux/include/asm-sparc/processor.h Wed Mar 1 09:12:33 1995 @@ -66,6 +66,9 @@ unsigned long float_regs[64]; /* V8 and below have 32, V9 has 64 */ }; +#define INIT_MMAP { &init_task, 0x0, 0x40000000, \ + PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC } + #define INIT_TSS { \ 0, 0, 0, 0, 0, 0, \ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/system.h linux/include/asm-sparc/system.h --- v1.1.94/linux/include/asm-sparc/system.h Wed Feb 22 16:53:06 1995 +++ linux/include/asm-sparc/system.h Sun Feb 26 20:46:20 1995 @@ -110,12 +110,12 @@ unsigned long dummy; __asm__ __volatile__( - "ld [%1],%2\n\t" - "st %0, [%1]\n\t" + "ld %1,%2 ! xchg_u32() is here\n\t" + "st %0, %1\n\t" "or %%g0, %2, %0" - : "=r" (val), "=r" (m), "=r" (dummy) + : "=r" (val), "=m" (*m), "=r" (dummy) : "0" (val)); - return (void *)val; + return (void *) val; } diff -u --recursive --new-file v1.1.94/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h --- v1.1.94/linux/include/asm-sparc/unistd.h Mon Jan 16 14:18:25 1995 +++ linux/include/asm-sparc/unistd.h Wed Mar 1 09:12:33 1995 @@ -124,4 +124,40 @@ return -1; \ } +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,idle) +static inline _syscall0(int,fork) +static inline _syscall0(int,pause) +static inline _syscall0(int,setup) +static inline _syscall0(int,sync) +static inline _syscall0(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall1(int,dup,int,fd) +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static inline _syscall3(int,open,const char *,file,int,flag,int,mode) +static inline _syscall1(int,close,int,fd) +static inline _syscall1(int,_exit,int,exitcode) +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +#endif + #endif /* _SPARC_UNISTD_H */ diff -u --recursive --new-file v1.1.94/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h --- v1.1.94/linux/include/linux/ext2_fs.h Mon Jan 9 07:22:10 1995 +++ linux/include/linux/ext2_fs.h Sun Feb 26 18:52:02 1995 @@ -97,7 +97,7 @@ # define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) #endif #define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry)) -#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (unsigned long)) +#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) #ifdef __KERNEL__ # define EXT2_BLOCK_SIZE_BITS(s) ((s)->u.ext2_sb.s_es->s_log_block_size + 10) #else @@ -124,20 +124,20 @@ */ struct ext2_acl_header /* Header of Access Control Lists */ { - unsigned long aclh_size; - unsigned long aclh_file_count; - unsigned long aclh_acle_count; - unsigned long aclh_first_acle; + __u32 aclh_size; + __u32 aclh_file_count; + __u32 aclh_acle_count; + __u32 aclh_first_acle; }; struct ext2_acl_entry /* Access Control List Entry */ { - unsigned long acle_size; - unsigned short acle_perms; /* Access permissions */ - unsigned short acle_type; /* Type of entry */ - unsigned short acle_tag; /* User or group identity */ - unsigned short acle_pad1; - unsigned long acle_next; /* Pointer on next entry for the */ + __u32 acle_size; + __u16 acle_perms; /* Access permissions */ + __u16 acle_type; /* Type of entry */ + __u16 acle_tag; /* User or group identity */ + __u16 acle_pad1; + __u32 acle_next; /* Pointer on next entry for the */ /* same inode or on next free entry */ }; @@ -146,23 +146,23 @@ */ struct ext2_old_group_desc { - unsigned long bg_block_bitmap; /* Blocks bitmap block */ - unsigned long bg_inode_bitmap; /* Inodes bitmap block */ - unsigned long bg_inode_table; /* Inodes table block */ - unsigned short bg_free_blocks_count; /* Free blocks count */ - unsigned short bg_free_inodes_count; /* Free inodes count */ + __u32 bg_block_bitmap; /* Blocks bitmap block */ + __u32 bg_inode_bitmap; /* Inodes bitmap block */ + __u32 bg_inode_table; /* Inodes table block */ + __u16 bg_free_blocks_count; /* Free blocks count */ + __u16 bg_free_inodes_count; /* Free inodes count */ }; struct ext2_group_desc { - unsigned long bg_block_bitmap; /* Blocks bitmap block */ - unsigned long bg_inode_bitmap; /* Inodes bitmap block */ - unsigned long bg_inode_table; /* Inodes table block */ - unsigned short bg_free_blocks_count; /* Free blocks count */ - unsigned short bg_free_inodes_count; /* Free inodes count */ - unsigned short bg_used_dirs_count; /* Directories count */ - unsigned short bg_pad; - unsigned long bg_reserved[3]; + __u32 bg_block_bitmap; /* Blocks bitmap block */ + __u32 bg_inode_bitmap; /* Inodes bitmap block */ + __u32 bg_inode_table; /* Inodes table block */ + __u16 bg_free_blocks_count; /* Free blocks count */ + __u16 bg_free_inodes_count; /* Free inodes count */ + __u16 bg_used_dirs_count; /* Directories count */ + __u16 bg_pad; + __u32 bg_reserved[3]; }; /* @@ -210,53 +210,53 @@ * Structure of an inode on the disk */ struct ext2_inode { - unsigned short i_mode; /* File mode */ - unsigned short i_uid; /* Owner Uid */ - unsigned long i_size; /* Size in bytes */ - unsigned long i_atime; /* Access time */ - unsigned long i_ctime; /* Creation time */ - unsigned long i_mtime; /* Modification time */ - unsigned long i_dtime; /* Deletion Time */ - unsigned short i_gid; /* Group Id */ - unsigned short i_links_count; /* Links count */ - unsigned long i_blocks; /* Blocks count */ - unsigned long i_flags; /* File flags */ + __u16 i_mode; /* File mode */ + __u16 i_uid; /* Owner Uid */ + __u32 i_size; /* Size in bytes */ + __u32 i_atime; /* Access time */ + __u32 i_ctime; /* Creation time */ + __u32 i_mtime; /* Modification time */ + __u32 i_dtime; /* Deletion Time */ + __u16 i_gid; /* Group Id */ + __u16 i_links_count; /* Links count */ + __u32 i_blocks; /* Blocks count */ + __u32 i_flags; /* File flags */ union { struct { - unsigned long l_i_reserved1; + __u32 l_i_reserved1; } linux1; struct { - unsigned long h_i_translator; + __u32 h_i_translator; } hurd1; struct { - unsigned long m_i_reserved1; + __u32 m_i_reserved1; } masix1; } osd1; /* OS dependent 1 */ - unsigned long i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ - unsigned long i_version; /* File version (for NFS) */ - unsigned long i_file_acl; /* File ACL */ - unsigned long i_dir_acl; /* Directory ACL */ - unsigned long i_faddr; /* Fragment address */ + __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ + __u32 i_version; /* File version (for NFS) */ + __u32 i_file_acl; /* File ACL */ + __u32 i_dir_acl; /* Directory ACL */ + __u32 i_faddr; /* Fragment address */ union { struct { - unsigned char l_i_frag; /* Fragment number */ - unsigned char l_i_fsize; /* Fragment size */ - unsigned short i_pad1; - unsigned long l_i_reserved2[2]; + __u8 l_i_frag; /* Fragment number */ + __u8 l_i_fsize; /* Fragment size */ + __u16 i_pad1; + __u32 l_i_reserved2[2]; } linux2; struct { - unsigned char h_i_frag; /* Fragment number */ - unsigned char h_i_fsize; /* Fragment size */ - unsigned short h_i_mode_high; - unsigned short h_i_uid_high; - unsigned short h_i_gid_high; - unsigned long h_i_author; + __u8 h_i_frag; /* Fragment number */ + __u8 h_i_fsize; /* Fragment size */ + __u16 h_i_mode_high; + __u16 h_i_uid_high; + __u16 h_i_gid_high; + __u32 h_i_author; } hurd2; struct { - unsigned char m_i_frag; /* Fragment number */ - unsigned char m_i_fsize; /* Fragment size */ - unsigned short m_pad1; - unsigned long m_i_reserved2[2]; + __u8 m_i_frag; /* Fragment number */ + __u8 m_i_fsize; /* Fragment size */ + __u16 m_pad1; + __u32 m_i_reserved2[2]; } masix2; } osd2; /* OS dependent 2 */ }; @@ -326,32 +326,32 @@ * Structure of the super block */ struct ext2_super_block { - unsigned long s_inodes_count; /* Inodes count */ - unsigned long s_blocks_count; /* Blocks count */ - unsigned long s_r_blocks_count;/* Reserved blocks count */ - unsigned long s_free_blocks_count;/* Free blocks count */ - unsigned long s_free_inodes_count;/* Free inodes count */ - unsigned long s_first_data_block;/* First Data Block */ - unsigned long s_log_block_size;/* Block size */ - long s_log_frag_size; /* Fragment size */ - unsigned long s_blocks_per_group;/* # Blocks per group */ - unsigned long s_frags_per_group;/* # Fragments per group */ - unsigned long s_inodes_per_group;/* # Inodes per group */ - unsigned long s_mtime; /* Mount time */ - unsigned long s_wtime; /* Write time */ - unsigned short s_mnt_count; /* Mount count */ - short s_max_mnt_count; /* Maximal mount count */ - unsigned short s_magic; /* Magic signature */ - unsigned short s_state; /* File system state */ - unsigned short s_errors; /* Behaviour when detecting errors */ - unsigned short s_pad; - unsigned long s_lastcheck; /* time of last check */ - unsigned long s_checkinterval; /* max. time between checks */ - unsigned long s_creator_os; /* OS */ - unsigned long s_rev_level; /* Revision level */ - unsigned short s_def_resuid; /* Default uid for reserved blocks */ - unsigned short s_def_resgid; /* Default gid for reserved blocks */ - unsigned long s_reserved[235]; /* Padding to the end of the block */ + __u32 s_inodes_count; /* Inodes count */ + __u32 s_blocks_count; /* Blocks count */ + __u32 s_r_blocks_count; /* Reserved blocks count */ + __u32 s_free_blocks_count; /* Free blocks count */ + __u32 s_free_inodes_count; /* Free inodes count */ + __u32 s_first_data_block; /* First Data Block */ + __u32 s_log_block_size; /* Block size */ + __s32 s_log_frag_size; /* Fragment size */ + __u32 s_blocks_per_group; /* # Blocks per group */ + __u32 s_frags_per_group; /* # Fragments per group */ + __u32 s_inodes_per_group; /* # Inodes per group */ + __u32 s_mtime; /* Mount time */ + __u32 s_wtime; /* Write time */ + __u16 s_mnt_count; /* Mount count */ + __s16 s_max_mnt_count; /* Maximal mount count */ + __u16 s_magic; /* Magic signature */ + __u16 s_state; /* File system state */ + __u16 s_errors; /* Behaviour when detecting errors */ + __u16 s_pad; + __u32 s_lastcheck; /* time of last check */ + __u32 s_checkinterval; /* max. time between checks */ + __u32 s_creator_os; /* OS */ + __u32 s_rev_level; /* Revision level */ + __u16 s_def_resuid; /* Default uid for reserved blocks */ + __u16 s_def_resgid; /* Default gid for reserved blocks */ + __u32 s_reserved[235]; /* Padding to the end of the block */ }; #define EXT2_OS_LINUX 0 @@ -369,10 +369,10 @@ #define EXT2_NAME_LEN 255 struct ext2_dir_entry { - unsigned long inode; /* Inode number */ - unsigned short rec_len; /* Directory entry length */ - unsigned short name_len; /* Name length */ - char name[EXT2_NAME_LEN]; /* File name */ + __u32 inode; /* Inode number */ + __u16 rec_len; /* Directory entry length */ + __u16 name_len; /* Name length */ + char name[EXT2_NAME_LEN]; /* File name */ }; /* @@ -409,7 +409,7 @@ /* balloc.c */ extern int ext2_new_block (struct super_block *, unsigned long, - unsigned long *, unsigned long *); + __u32 *, __u32 *); extern void ext2_free_blocks (struct super_block *, unsigned long, unsigned long); extern unsigned long ext2_count_free_blocks (struct super_block *); diff -u --recursive --new-file v1.1.94/linux/include/linux/ext2_fs_i.h linux/include/linux/ext2_fs_i.h --- v1.1.94/linux/include/linux/ext2_fs_i.h Mon Aug 22 21:16:03 1994 +++ linux/include/linux/ext2_fs_i.h Sun Feb 26 18:52:02 1995 @@ -19,21 +19,21 @@ * second extended file system inode data in memory */ struct ext2_inode_info { - unsigned long i_data[15]; - unsigned long i_flags; - unsigned long i_faddr; - unsigned char i_frag_no; - unsigned char i_frag_size; - unsigned short i_osync; - unsigned long i_file_acl; - unsigned long i_dir_acl; - unsigned long i_dtime; - unsigned long i_version; - unsigned long i_block_group; - unsigned long i_next_alloc_block; - unsigned long i_next_alloc_goal; - unsigned long i_prealloc_block; - unsigned long i_prealloc_count; + __u32 i_data[15]; + __u32 i_flags; + __u32 i_faddr; + __u8 i_frag_no; + __u8 i_frag_size; + __u16 i_osync; + __u32 i_file_acl; + __u32 i_dir_acl; + __u32 i_dtime; + __u32 i_version; + __u32 i_block_group; + __u32 i_next_alloc_block; + __u32 i_next_alloc_goal; + __u32 i_prealloc_block; + __u32 i_prealloc_count; }; #endif /* _LINUX_EXT2_FS_I */ diff -u --recursive --new-file v1.1.94/linux/include/linux/fs.h linux/include/linux/fs.h --- v1.1.94/linux/include/linux/fs.h Wed Feb 22 16:53:06 1995 +++ linux/include/linux/fs.h Thu Feb 23 13:32:05 1995 @@ -266,10 +266,10 @@ }; struct file_lock { - struct file_lock *fl_next; /* singly linked list for this inode (or the free list) */ + struct file_lock *fl_next; /* singly linked list for this inode */ struct file_lock *fl_nextlink; /* doubly linked list of all locks */ - struct file_lock *fl_prevlink; /* used to simplify garbage collecting */ - struct task_struct *fl_owner; /* NULL if on free list, for sanity checks */ + struct file_lock *fl_prevlink; /* used to simplify lock removal */ + struct task_struct *fl_owner; struct wait_queue *fl_wait; char fl_type; char fl_whence; diff -u --recursive --new-file v1.1.94/linux/include/linux/in.h linux/include/linux/in.h --- v1.1.94/linux/include/linux/in.h Sun Feb 5 19:31:55 1995 +++ linux/include/linux/in.h Thu Feb 23 13:32:05 1995 @@ -81,7 +81,7 @@ #define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) #define IN_CLASSB_MAX 65536 -#define IN_CLASSC(a) ((((long int) (a)) & 0xc0000000) == 0xc0000000) +#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000) #define IN_CLASSC_NET 0xffffff00 #define IN_CLASSC_NSHIFT 8 #define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) diff -u --recursive --new-file v1.1.94/linux/include/linux/ip_fw.h linux/include/linux/ip_fw.h --- v1.1.94/linux/include/linux/ip_fw.h Sun Feb 5 19:31:55 1995 +++ linux/include/linux/ip_fw.h Thu Feb 23 13:26:22 1995 @@ -7,6 +7,12 @@ * * Ported from BSD to Linux, * Alan Cox 22/Nov/1994. + * Merged and included the FreeBSD-Current changes at Ugen's request + * (but hey its a lot cleaner now). Ugen would prefer in some ways + * we waited for his final product but since Linux 1.2.0 is about to + * appear its not practical - Read: It works, its not clean but please + * don't consider it to be his standard of finished work. + * Alan. * * All the real work was done by ..... */ @@ -38,43 +44,46 @@ struct ip_fw { - struct ip_fw *next; /* Next firewall on chain */ - struct in_addr src, dst; /* Source and destination IP addr */ - struct in_addr src_mask, dst_mask; /* Mask for src and dest IP addr */ - unsigned short flags; /* Flags word */ - unsigned short n_src_p, n_dst_p; /* # of src ports and # of dst ports */ + struct ip_fw *fw_next; /* Next firewall on chain */ + struct in_addr fw_src, fw_dst; /* Source and destination IP addr */ + struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */ + struct in_addr fw_via; /* IP address of interface "via" */ + unsigned short fw_flg; /* Flags word */ + unsigned short fw_nsp, fw_ndp; /* N'of src ports and # of dst ports */ /* in ports array (dst ports follow */ /* src ports; max of 10 ports in all; */ /* count of 0 means match all ports) */ #define IP_FW_MAX_PORTS 10 /* A reasonable maximum */ - unsigned short ports[IP_FW_MAX_PORTS]; /* Array of port numbers to match */ - unsigned long p_cnt,b_cnt; /* Packet and byte counters */ + unsigned short fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */ + unsigned long fw_pcnt,fw_bcnt; /* Packet and byte counters */ }; /* * Values for "flags" field . */ -#define IP_FW_F_ALL 0x00 /* This is a universal packet firewall*/ -#define IP_FW_F_TCP 0x01 /* This is a TCP packet firewall */ -#define IP_FW_F_UDP 0x02 /* This is a UDP packet firewall */ -#define IP_FW_F_ICMP 0x03 /* This is a ICMP packet firewall */ -#define IP_FW_F_KIND 0x03 /* Mask to isolate firewall kind */ -#define IP_FW_F_ACCEPT 0x04 /* This is an accept firewall (as * +#define IP_FW_F_ALL 0x000 /* This is a universal packet firewall*/ +#define IP_FW_F_TCP 0x001 /* This is a TCP packet firewall */ +#define IP_FW_F_UDP 0x002 /* This is a UDP packet firewall */ +#define IP_FW_F_ICMP 0x003 /* This is a ICMP packet firewall */ +#define IP_FW_F_KIND 0x003 /* Mask to isolate firewall kind */ +#define IP_FW_F_ACCEPT 0x004 /* This is an accept firewall (as * * opposed to a deny firewall)* * */ -#define IP_FW_F_SRNG 0x08 /* The first two src ports are a min * +#define IP_FW_F_SRNG 0x008 /* The first two src ports are a min * * and max range (stored in host byte * * order). * * */ -#define IP_FW_F_DRNG 0x10 /* The first two dst ports are a min * +#define IP_FW_F_DRNG 0x010 /* The first two dst ports are a min * * and max range (stored in host byte * * order). * * (ports[0] <= port <= ports[1]) * * */ -#define IP_FW_F_PRN 0x20 /* In verbose mode print this firewall*/ -#define IP_FW_F_BIDIR 0x40 /* For accounting-count two way */ -#define IP_FW_F_MASK 0x7F /* All possible flag bits mask */ +#define IP_FW_F_PRN 0x020 /* In verbose mode print this firewall*/ +#define IP_FW_F_BIDIR 0x040 /* For accounting-count two way */ +#define IP_FW_F_TCPSYN 0x080 /* For tcp packets-check SYN only */ +#define IP_FW_F_ICMPRPL 0x100 /* Send back icmp unreachable packet */ +#define IP_FW_F_MASK 0x1FF /* All possible flag bits mask */ /* * New IP firewall options for [gs]etsockopt at the RAW IP level. @@ -116,14 +125,14 @@ extern struct ip_fw *ip_fw_fwd_chain; extern int ip_fw_blk_policy; extern int ip_fw_fwd_policy; -extern int ip_fw_chk(struct iphdr *, struct ip_fw *, int); extern int ip_fw_ctl(int, void *, int); #endif #ifdef CONFIG_IP_ACCT extern struct ip_fw *ip_acct_chain; -extern void ip_acct_cnt(struct iphdr *, struct ip_fw *); +extern int ip_acct_cnt(struct iphdr *, struct device *, struct ip_fw *); extern int ip_acct_ctl(int, void *, int); #endif +extern int ip_fw_chk(struct iphdr *, struct device *rif,struct ip_fw *, int); #endif /* KERNEL */ #endif /* _IP_FW_H */ diff -u --recursive --new-file v1.1.94/linux/include/linux/keyboard.h linux/include/linux/keyboard.h --- v1.1.94/linux/include/linux/keyboard.h Sun Jan 1 19:49:19 1995 +++ linux/include/linux/keyboard.h Fri Feb 24 21:38:27 1995 @@ -320,6 +320,7 @@ #define K_DECRCONSOLE K(KT_SPEC,16) #define K_INCRCONSOLE K(KT_SPEC,17) #define K_SPAWNCONSOLE K(KT_SPEC,18) +#define K_BARENUMLOCK K(KT_SPEC,19) #define K_ALLOCATED K(KT_SPEC,126) /* dynamically allocated keymap */ #define K_NOSUCHMAP K(KT_SPEC,127) /* returned by KDGKBENT */ diff -u --recursive --new-file v1.1.94/linux/include/linux/major.h linux/include/linux/major.h --- v1.1.94/linux/include/linux/major.h Fri Feb 17 11:20:16 1995 +++ linux/include/linux/major.h Thu Feb 23 13:31:40 1995 @@ -36,8 +36,8 @@ * 16 - sockets * 17 - af_unix * 18 - af_inet - * 19 - UNUSED - * 20 - UNUSED + * 19 - cyclades /dev/ttyC* + * 20 - cyclades /dev/cub* * 21 - scsi generic * 22 - (at2disk) * 23 - mitsumi cdrom @@ -69,7 +69,8 @@ #define SOCKET_MAJOR 16 #define AF_UNIX_MAJOR 17 #define AF_INET_MAJOR 18 -/* unused: 19, 20 */ +#define CYCLADES_MAJOR 19 +#define CYCLADESAUX_MAJOR 20 #define SCSI_GENERIC_MAJOR 21 #define IDE1_MAJOR 22 #define MITSUMI_CDROM_MAJOR 23 diff -u --recursive --new-file v1.1.94/linux/include/linux/mm.h linux/include/linux/mm.h --- v1.1.94/linux/include/linux/mm.h Fri Feb 17 11:20:16 1995 +++ linux/include/linux/mm.h Thu Mar 2 09:04:40 1995 @@ -179,6 +179,7 @@ extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot); extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot); +extern void handle_mm_fault(struct vm_area_struct *vma, unsigned long address, int write_access); extern void do_wp_page(struct vm_area_struct * vma, unsigned long address, int write_access); extern void do_no_page(struct vm_area_struct * vma, unsigned long address, int write_access); @@ -204,7 +205,7 @@ extern void rw_swap_page(int rw, unsigned long nr, char * buf); /* mmap.c */ -extern int do_mmap(struct file * file, unsigned long addr, unsigned long len, +extern unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long off); extern struct vm_area_struct * find_vma (struct task_struct *, unsigned long); extern struct vm_area_struct * find_vma_intersection (struct task_struct *, unsigned long, unsigned long); diff -u --recursive --new-file v1.1.94/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h --- v1.1.94/linux/include/linux/msdos_fs.h Tue Dec 27 08:37:13 1994 +++ linux/include/linux/msdos_fs.h Sun Feb 26 18:52:02 1995 @@ -62,29 +62,29 @@ struct msdos_boot_sector { - char ignored[3]; /* Boot strap short or near jump */ - char system_id[8]; /* Name - can be used to special case - partition manager volumes */ - unsigned char sector_size[2];/* bytes per logical sector */ - unsigned char cluster_size; /* sectors/cluster */ - unsigned short reserved; /* reserved sectors */ - unsigned char fats; /* number of FATs */ - unsigned char dir_entries[2];/* root directory entries */ - unsigned char sectors[2]; /* number of sectors */ - unsigned char media; /* media code (unused) */ - unsigned short fat_length; /* sectors/FAT */ - unsigned short secs_track; /* sectors per track */ - unsigned short heads; /* number of heads */ - unsigned long hidden; /* hidden sectors (unused) */ - unsigned long total_sect; /* number of sectors (if sectors == 0) */ + __s8 ignored[3]; /* Boot strap short or near jump */ + __s8 system_id[8]; /* Name - can be used to special case + partition manager volumes */ + __u8 sector_size[2]; /* bytes per logical sector */ + __u8 cluster_size; /* sectors/cluster */ + __u16 reserved; /* reserved sectors */ + __u8 fats; /* number of FATs */ + __u8 dir_entries[2]; /* root directory entries */ + __u8 sectors[2]; /* number of sectors */ + __u8 media; /* media code (unused) */ + __u16 fat_length; /* sectors/FAT */ + __u16 secs_track; /* sectors per track */ + __u16 heads; /* number of heads */ + __u32 hidden; /* hidden sectors (unused) */ + __u32 total_sect; /* number of sectors (if sectors == 0) */ }; struct msdos_dir_entry { - char name[8],ext[3]; /* name and extension */ - unsigned char attr; /* attribute bits */ - char unused[10]; - unsigned short time,date,start; /* time, date and first cluster */ - unsigned long size; /* file size (in bytes) */ + __s8 name[8],ext[3]; /* name and extension */ + __u8 attr; /* attribute bits */ + __u8 unused[10]; + __u16 time,date,start;/* time, date and first cluster */ + __u32 size; /* file size (in bytes) */ }; struct fat_cache { @@ -119,9 +119,8 @@ extern void lock_fat(struct super_block *sb); extern void unlock_fat(struct super_block *sb); extern int msdos_add_cluster(struct inode *inode); -extern int date_dos2unix(unsigned short time,unsigned short date); -extern void date_unix2dos(int unix_date,unsigned short *time, - unsigned short *date); +extern int date_dos2unix(__u16 time, __u16 date); +extern void date_unix2dos(int unix_date,__u16 *time, __u16 *date); extern int msdos_get_entry(struct inode *dir,loff_t *pos,struct buffer_head **bh, struct msdos_dir_entry **de); extern int msdos_scan(struct inode *dir,char *name,struct buffer_head **res_bh, diff -u --recursive --new-file v1.1.94/linux/include/linux/net.h linux/include/linux/net.h --- v1.1.94/linux/include/linux/net.h Fri Jan 13 16:57:06 1995 +++ linux/include/linux/net.h Thu Feb 23 13:26:54 1995 @@ -135,6 +135,7 @@ extern int sock_wake_async(struct socket *sock, int how); extern int sock_register(int family, struct proto_ops *ops); extern int sock_unregister(int family); - +extern struct socket *sock_alloc(void); +extern void sock_release(struct socket *sock); #endif /* __KERNEL__ */ #endif /* _LINUX_NET_H */ diff -u --recursive --new-file v1.1.94/linux/include/linux/pci.h linux/include/linux/pci.h --- v1.1.94/linux/include/linux/pci.h Thu Feb 9 10:18:53 1995 +++ linux/include/linux/pci.h Fri Feb 24 21:38:37 1995 @@ -229,7 +229,8 @@ #define PCI_DEVICE_ID_DEC_BRD 0x0001 #define PCI_VENDOR_ID_MATROX 0x102B -#define PCI_DEVICE_ID_MATROX_2plus 0x0518 +#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 +#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10 #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82378 0x0484 @@ -255,7 +256,7 @@ #define PCI_DEVICE_ID_CIRRUS_6729 0x1100 #define PCI_VENDOR_ID_BUSLOGIC 0x104B -#define PCI_DEVICE_ID_BUSLOGIC_946C 0x0140 +#define PCI_DEVICE_ID_BUSLOGIC_946C 0x1040 #define PCI_VENDOR_ID_N9 0x105D #define PCI_DEVICE_ID_N9_I128 0x2309 @@ -270,7 +271,8 @@ #define PCI_VENDOR_ID_TSENG 0x100c #define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 #define PCI_DEVICE_ID_TSENG_W32P_b 0x3205 -#define PCI_DEVICE_ID_TSENG_W32P_c 0x3207 +#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206 +#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207 #define PCI_VENDOR_ID_CMD 0x1095 #define PCI_DEVICE_ID_CMD_640 0x0640 @@ -280,6 +282,7 @@ #define PCI_VENDOR_ID_AMD 0x1022 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 +#define PCI_DEVICE_ID_AMD_SCSI 0x2020 #define PCI_VENDOR_ID_VLSI 0x1004 #define PCI_DEVICE_ID_VLSI_82C593 0x0006 @@ -298,6 +301,7 @@ #define PCI_DEVICE_ID_CONTAQ_82C599 0x0600 #define PCI_VENDOR_ID_NS 0x100b +#define PCI_DEVICE_ID_NS_87410 0xd001 #define PCI_VENDOR_ID_VIA 0x1106 #define PCI_DEVICE_ID_VIA_82C505 0x0505 @@ -319,6 +323,8 @@ #define PCI_VENDOR_ID_EF 0x111a #define PCI_DEVICE_ID_EF_ATM 0x0000 +#define PCI_VENDOR_ID_HER 0xedd8 +#define PCI_DEVICE_ID_HER_STING 0xa091 struct pci_vendor_type { unsigned short vendor_id; @@ -326,7 +332,7 @@ }; -#define PCI_VENDOR_NUM 33 +#define PCI_VENDOR_NUM 34 #define PCI_VENDOR_TYPE { \ {PCI_VENDOR_ID_NCR, "NCR"}, \ {PCI_VENDOR_ID_ADAPTEC, "Adaptec"}, \ @@ -360,7 +366,8 @@ {PCI_VENDOR_ID_LEADTEK, "Leadtek Research"}, \ {PCI_VENDOR_ID_IMS, "IMS"}, \ {PCI_VENDOR_ID_ZEINET, "ZeiNet"}, \ - {PCI_VENDOR_ID_EF, "Efficient Networks"} \ + {PCI_VENDOR_ID_EF, "Efficient Networks"}, \ + {PCI_VENDOR_ID_HER, "Hercules"} \ } @@ -379,7 +386,7 @@ char *device_name; }; -#define PCI_DEVICE_NUM 61 +#define PCI_DEVICE_NUM 66 #define PCI_DEVICE_TYPE { \ {0xff, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, "53c810"}, \ {0xff, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C815, "53c815"}, \ @@ -403,7 +410,8 @@ {0xff, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, "DC21040"}, \ {0xff, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, "DEFPA"}, \ {0xff, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_BRD, "DC21050"}, \ - {0xff, PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_2plus, "MGA/2+"}, \ + {0xff, PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MGA_2, "Atlas PX2085"}, \ + {0xff, PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MGA_IMP, "MGA Impression"}, \ {0xff, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, "82378IB"}, \ {0x00, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, "82424ZX Saturn"}, \ {0xff, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, "82375EB"}, \ @@ -425,15 +433,18 @@ {0xff, PCI_VENDOR_ID_TSENG, PCI_DEVICE_ID_TSENG_W32P_2, "ET4000W32P"}, \ {0xff, PCI_VENDOR_ID_TSENG, PCI_DEVICE_ID_TSENG_W32P_b, "ET4000W32P rev B"}, \ {0xff, PCI_VENDOR_ID_TSENG, PCI_DEVICE_ID_TSENG_W32P_c, "ET4000W32P rev C"}, \ + {0xff, PCI_VENDOR_ID_TSENG, PCI_DEVICE_ID_TSENG_W32P_d, "ET4000W32P rev D"}, \ {0xff, PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, "640A"}, \ {0xff, PCI_VENDOR_ID_VISION, PCI_DEVICE_ID_VISION_QD8500, "QD-8500PCI"}, \ {0xff, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, "79C970"}, \ + {0xff, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI, "53C974"}, \ {0xff, PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C593, "82C593-FC1"}, \ {0xff, PCI_VENDOR_ID_ADL, PCI_DEVICE_ID_ADL_2301, "2301"}, \ {0xff, PCI_VENDOR_ID_SYMPHONY, PCI_DEVICE_ID_SYMPHONY_101, "82C101"}, \ {0xff, PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_9420, "TG 9420"}, \ {0xff, PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_9440, "TG 9440"}, \ {0xff, PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C599, "82C599"}, \ + {0xff, PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, "87410"}, \ {0xff, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C505, "VT 82C505"}, \ {0xff, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, "85C496"}, \ {0xff, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_501, "85C501"}, \ @@ -441,7 +452,8 @@ {0xff, PCI_VENDOR_ID_LEADTEK, PCI_DEVICE_ID_LEADTEK_805, "S3 805"}, \ {0xff, PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_8849, "8849"}, \ {0xff, PCI_VENDOR_ID_ZEINET, PCI_DEVICE_ID_ZEINET_1221, "1221"}, \ - {0xff, PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM, "155P-MF1"} \ + {0xff, PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM, "155P-MF1"}, \ + {0xff, PCI_VENDOR_ID_HER, PCI_DEVICE_ID_HER_STING, "Stingray"} \ } /* An item of this structure has the following meaning */ diff -u --recursive --new-file v1.1.94/linux/include/linux/sched.h linux/include/linux/sched.h --- v1.1.94/linux/include/linux/sched.h Wed Feb 22 16:53:06 1995 +++ linux/include/linux/sched.h Fri Feb 24 16:41:01 1995 @@ -123,8 +123,6 @@ struct vm_area_struct * mmap_avl; }; -#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } - #define INIT_MM { \ 0, \ 0, 0, 0, \ diff -u --recursive --new-file v1.1.94/linux/include/linux/string.h linux/include/linux/string.h --- v1.1.94/linux/include/linux/string.h Mon Jan 9 11:24:24 1995 +++ linux/include/linux/string.h Thu Mar 2 09:04:40 1995 @@ -21,6 +21,7 @@ extern char * strtok(char *,const char *); extern char * strstr(const char *,const char *); extern size_t strlen(const char *); +extern size_t strnlen(const char *,size_t); extern size_t strspn(const char *,const char *); extern int strcmp(const char *,const char *); extern int strncmp(const char *,const char *,size_t); diff -u --recursive --new-file v1.1.94/linux/include/linux/tasks.h linux/include/linux/tasks.h --- v1.1.94/linux/include/linux/tasks.h Mon Jan 30 06:41:58 1995 +++ linux/include/linux/tasks.h Mon Feb 27 11:16:24 1995 @@ -4,7 +4,7 @@ /* * This is the maximum nr of tasks - change it if you need to */ -#define NR_TASKS 128 +#define NR_TASKS 512 #define MAX_TASKS_PER_USER (NR_TASKS/2) #define MIN_TASKS_LEFT_FOR_ROOT 4 diff -u --recursive --new-file v1.1.94/linux/include/linux/tty.h linux/include/linux/tty.h --- v1.1.94/linux/include/linux/tty.h Wed Feb 22 16:53:06 1995 +++ linux/include/linux/tty.h Sun Feb 26 16:45:26 1995 @@ -199,7 +199,7 @@ int pgrp; int session; dev_t device; - int flags; + unsigned long flags; int count; struct winsize winsize; unsigned char stopped:1, hw_stopped:1, packet:1; @@ -231,7 +231,7 @@ int read_head; int read_tail; int read_cnt; - int read_flags[N_TTY_BUF_SIZE/32]; + unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))]; int canon_data; unsigned long canon_head; unsigned int canon_column; diff -u --recursive --new-file v1.1.94/linux/init/main.c linux/init/main.c --- v1.1.94/linux/init/main.c Fri Feb 17 11:20:17 1995 +++ linux/init/main.c Fri Feb 24 16:41:01 1995 @@ -4,6 +4,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ +#define __KERNEL_SYSCALLS__ #include #include @@ -33,38 +34,6 @@ extern char etext, end; extern char *linux_banner; -/* - * we need this inline - forking from kernel space will result - * in NO COPY ON WRITE (!!!), until an execve is executed. This - * is no problem, but for the stack. This is handled by not letting - * main() use the stack at all after fork(). Thus, no function - * calls - which means inline code for fork too, as otherwise we - * would use the stack upon exit from 'fork()'. - * - * Actually only pause and fork are needed inline, so that there - * won't be any messing with the stack from main(), but we define - * some others too. - */ -#define __NR__exit __NR_exit -static inline _syscall0(int,idle) -static inline _syscall0(int,fork) -static inline _syscall0(int,pause) -static inline _syscall0(int,setup) -static inline _syscall0(int,sync) -static inline _syscall0(pid_t,setsid) -static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) -static inline _syscall1(int,dup,int,fd) -static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) -static inline _syscall3(int,open,const char *,file,int,flag,int,mode) -static inline _syscall1(int,close,int,fd) -static inline _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) - -static inline pid_t wait(int * wait_stat) -{ - return waitpid(-1,wait_stat,0); -} - static char printbuf[1024]; extern int console_loglevel; @@ -202,16 +171,16 @@ { "ncr5380=", generic_NCR5380_setup }, #endif #ifdef CONFIG_SCSI_AHA152X - { "aha152x=", aha152x_setup}, + { "aha152x=", aha152x_setup}, #endif #ifdef CONFIG_SCSI_AHA1542 - { "aha1542=", aha1542_setup}, + { "aha1542=", aha1542_setup}, #endif #ifdef CONFIG_SCSI_AHA274X - { "aha274x=", aha274x_setup}, + { "aha274x=", aha274x_setup}, #endif #ifdef CONFIG_SCSI_BUSLOGIC - { "buslogic=", buslogic_setup}, + { "buslogic=", buslogic_setup}, #endif #ifdef CONFIG_BLK_DEV_XD { "xd=", xd_setup }, @@ -386,7 +355,7 @@ init_modules(); #ifdef CONFIG_PROFILE prof_buffer = (unsigned long *) memory_start; - /* only text is profiled */ + /* only text is profiled */ prof_len = (unsigned long) &etext; prof_len >>= CONFIG_PROFILE_SHIFT; memory_start += prof_len * sizeof(unsigned long); diff -u --recursive --new-file v1.1.94/linux/ipc/shm.c linux/ipc/shm.c --- v1.1.94/linux/ipc/shm.c Wed Feb 22 16:53:06 1995 +++ linux/ipc/shm.c Sat Feb 25 15:42:57 1995 @@ -421,7 +421,6 @@ pmd_t *page_middle; pte_t *page_table; unsigned long tmp, shm_sgn; - int error; /* clear old mappings */ do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start); @@ -437,10 +436,10 @@ page_dir = pgd_offset(shmd->vm_task,tmp); page_middle = pmd_alloc(page_dir,tmp); if (!page_middle) - break; + return -ENOMEM; page_table = pte_alloc(page_middle,tmp); if (!page_table) - break; + return -ENOMEM; pte_val(*page_table) = shm_sgn; } invalidate(); diff -u --recursive --new-file v1.1.94/linux/kernel/fork.c linux/kernel/fork.c --- v1.1.94/linux/kernel/fork.c Wed Feb 22 16:53:06 1995 +++ linux/kernel/fork.c Wed Mar 1 13:31:54 1995 @@ -137,7 +137,6 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * p) { if (clone_flags & COPYVM) { - p->mm->swappable = 1; p->mm->min_flt = p->mm->maj_flt = 0; p->mm->cmin_flt = p->mm->cmaj_flt = 0; if (copy_page_tables(p)) @@ -193,7 +192,6 @@ p->pid = last_pid; p->p_pptr = p->p_opptr = current; p->p_cptr = NULL; - SET_LINKS(p); p->signal = 0; p->it_real_value = p->it_virt_value = p->it_prof_value = 0; p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0; @@ -202,7 +200,9 @@ p->utime = p->stime = 0; p->cutime = p->cstime = 0; p->start_time = jiffies; + p->mm->swappable = 0; /* don't try to swap it out before it's set up */ task[nr] = p; + SET_LINKS(p); /* copy all the process information */ copy_thread(nr, clone_flags, usp, p, regs); @@ -213,6 +213,7 @@ copy_fs(clone_flags, p); /* ok, now we should be set up.. */ + p->mm->swappable = 1; p->exit_signal = clone_flags & CSIGNAL; p->counter = current->counter >> 1; p->state = TASK_RUNNING; /* do this last, just in case */ diff -u --recursive --new-file v1.1.94/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v1.1.94/linux/kernel/ksyms.c Fri Feb 17 11:20:17 1995 +++ linux/kernel/ksyms.c Thu Feb 23 13:52:40 1995 @@ -39,6 +39,7 @@ #include #include #include "../net/inet/protocol.h" +#include "../net/inet/arp.h" #endif #ifdef CONFIG_PCI #include @@ -299,6 +300,7 @@ X(dev_queue_xmit), X(dev_base), X(dev_close), + X(arp_find), X(n_tty_ioctl), X(tty_register_ldisc), X(kill_fasync), diff -u --recursive --new-file v1.1.94/linux/kernel/sys.c linux/kernel/sys.c --- v1.1.94/linux/kernel/sys.c Wed Feb 22 16:53:06 1995 +++ linux/kernel/sys.c Wed Mar 1 13:31:54 1995 @@ -172,8 +172,12 @@ { if (C_A_D) hard_reset_now(); - else + else { + int i; send_sig(SIGINT,task[1],1); + for (i = 2; i < NR_TASKS; i++) + send_sig(SIGHUP,task[i],1); + } } diff -u --recursive --new-file v1.1.94/linux/lib/string.c linux/lib/string.c --- v1.1.94/linux/lib/string.c Sun Jan 22 23:04:00 1995 +++ linux/lib/string.c Thu Mar 2 09:04:40 1995 @@ -104,6 +104,15 @@ return sc - s; } +size_t strnlen(const char * s, size_t count) +{ + const char *sc; + + for (sc = s; *sc != '\0' && count--; ++sc) + /* nothing */; + return sc - s; +} + size_t strspn(const char *s, const char *accept) { const char *p; diff -u --recursive --new-file v1.1.94/linux/lib/vsprintf.c linux/lib/vsprintf.c --- v1.1.94/linux/lib/vsprintf.c Mon Jan 30 08:53:06 1995 +++ linux/lib/vsprintf.c Thu Mar 2 09:04:40 1995 @@ -217,11 +217,8 @@ s = va_arg(args, char *); if (!s) s = ""; - len = strlen(s); - if (precision < 0) - precision = len; - else if (len > precision) - len = precision; + + len = strnlen(s, precision); if (!(flags & LEFT)) while (len < field_width--) diff -u --recursive --new-file v1.1.94/linux/mm/memory.c linux/mm/memory.c --- v1.1.94/linux/mm/memory.c Mon Feb 20 21:34:56 1995 +++ linux/mm/memory.c Thu Mar 2 09:42:00 1995 @@ -246,7 +246,7 @@ pte = pte_wrprotect(pte); if (delete_from_swap_cache(pte_page(pte))) pte = pte_mkdirty(pte); - *new_pte = pte; + *new_pte = pte_mkold(pte); *old_pte = pte; mem_map[MAP_NR(pte_page(pte))]++; } @@ -288,7 +288,7 @@ if (pgd_none(*old_pgd)) return 0; if (pgd_bad(*old_pgd)) { - printk("copy_one_pgd: bad page table: probable memory corruption\n"); + printk("copy_one_pgd: bad page table (%p: %08lx): probable memory corruption\n", old_pgd, pgd_val(*old_pgd)); pgd_clear(old_pgd); return 0; } @@ -325,8 +325,8 @@ new_pgd = pgd_alloc(); if (!new_pgd) return -ENOMEM; - old_pgd = pgd_offset(current, 0); SET_PAGE_DIR(tsk, new_pgd); + old_pgd = pgd_offset(current, 0); for (i = 0 ; i < PTRS_PER_PGD ; i++) { int errno = copy_one_pgd(old_pgd, new_pgd); if (errno) { @@ -566,7 +566,7 @@ static void put_page(pte_t * page_table, pte_t pte) { if (!pte_none(*page_table)) { - printk("put_page: page already exists\n"); + printk("put_page: page already exists %08lx\n", pte_val(*page_table)); free_page(pte_page(pte)); return; } @@ -590,11 +590,17 @@ printk("mem_map disagrees with %08lx at %08lx\n",page,address); pgd = pgd_offset(tsk,address); pmd = pmd_alloc(pgd, address); - if (!pmd) + if (!pmd) { + free_page(page); + oom(tsk); return 0; + } pte = pte_alloc(pmd, address); - if (!pte) + if (!pte) { + free_page(page); + oom(tsk); return 0; + } if (!pte_none(*pte)) { printk("put_dirty_page: page already exists\n"); pte_clear(pte); @@ -664,9 +670,9 @@ invalidate(); return; } + *page_table = BAD_PAGE; free_page(old_page); oom(vma->vm_task); - *page_table = BAD_PAGE; invalidate(); return; } @@ -809,6 +815,7 @@ return 0; if (pgd_bad(*from_dir)) { printk("try_to_share: bad page directory %08lx\n", pgd_val(*from_dir)); + pgd_clear(from_dir); return 0; } from_middle = pmd_offset(from_dir, from_address); @@ -817,6 +824,7 @@ return 0; if (pmd_bad(*from_middle)) { printk("try_to_share: bad mid directory %08lx\n", pmd_val(*from_middle)); + pmd_clear(from_middle); return 0; } from_table = pte_offset(from_middle, from_address); @@ -967,9 +975,15 @@ pgd = pgd_offset(tsk, address); pmd = pmd_alloc(pgd, address); - if (!pmd) + if (!pmd) { + oom(tsk); return NULL; + } pte = pte_alloc(pmd, address); + if (!pte) { + oom(tsk); + return NULL; + } return pte; } @@ -1065,4 +1079,55 @@ } else if (mem_map[MAP_NR(page)] > 1 && !(vma->vm_flags & VM_SHARED)) entry = pte_wrprotect(entry); put_page(page_table, entry); +} + +/* + * The above separate functions for the no-page and wp-page + * cases will go away (they mostly do the same thing anyway), + * and we'll instead use only a general "handle_mm_fault()". + * + * These routines also need to handle stuff like marking pages dirty + * and/or accessed for architectures that don't do it in hardware (most + * RISC architectures). The early dirtying is also good on the i386. + * + * There is also a hook called "update_mmu_cache()" that architectures + * with external mmu caches can use to update those (ie the Sparc or + * PowerPC hashed page tables that act as extended TLBs). + */ +static inline void handle_pte_fault(struct vm_area_struct * vma, unsigned long address, + int write_access, pte_t * pte) +{ + if (!pte_present(*pte)) { + do_no_page(vma, address, write_access); + return; + } + *pte = pte_mkyoung(*pte); + if (!write_access) + return; + if (pte_write(*pte)) { + *pte = pte_mkdirty(*pte); + return; + } + do_wp_page(vma, address, write_access); +} + +void handle_mm_fault(struct vm_area_struct * vma, unsigned long address, + int write_access) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + + pgd = pgd_offset(vma->vm_task, address); + pmd = pmd_alloc(pgd, address); + if (!pmd) + goto no_memory; + pte = pte_alloc(pmd, address); + if (!pte) + goto no_memory; + handle_pte_fault(vma, address, write_access, pte); + update_mmu_cache(vma, address, *pte); + return; +no_memory: + oom(vma->vm_task); } diff -u --recursive --new-file v1.1.94/linux/mm/mmap.c linux/mm/mmap.c --- v1.1.94/linux/mm/mmap.c Wed Feb 1 09:23:08 1995 +++ linux/mm/mmap.c Thu Mar 2 09:04:40 1995 @@ -41,7 +41,7 @@ __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111 }; -int do_mmap(struct file * file, unsigned long addr, unsigned long len, +unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long off) { int error; diff -u --recursive --new-file v1.1.94/linux/mm/swap.c linux/mm/swap.c --- v1.1.94/linux/mm/swap.c Wed Feb 22 16:53:06 1995 +++ linux/mm/swap.c Wed Mar 1 13:32:36 1995 @@ -194,6 +194,8 @@ for (offset = p->lowest_bit; offset <= p->highest_bit ; offset++) { if (p->swap_map[offset]) continue; + if (test_bit(offset, p->swap_lockmap)) + continue; p->swap_map[offset] = 1; nr_swap_pages--; if (offset == p->highest_bit) @@ -257,8 +259,6 @@ printk("Trying to free swap from unused swap-device\n"); return; } - while (set_bit(offset,p->swap_lockmap)) - sleep_on(&lock_queue); if (offset < p->lowest_bit) p->lowest_bit = offset; if (offset > p->highest_bit) @@ -268,9 +268,6 @@ else if (!--p->swap_map[offset]) nr_swap_pages++; - if (!clear_bit(offset,p->swap_lockmap)) - printk("swap_free: lock already cleared\n"); - wake_up(&lock_queue); } /* @@ -311,7 +308,18 @@ return; } -static inline int try_to_swap_out(struct vm_area_struct* vma, unsigned offset, pte_t * page_table) +/* + * The swap-out functions return 1 of they successfully + * threw something out, and we got a free page. It returns + * zero if it couldn't do anything, and any other value + * indicates it decreased rss, but the page was shared. + * + * NOTE! If it sleeps, it *must* return 1 to make sure we + * don't continue with the swap-out. Otherwise we may be + * using a process that no longer actually exists (it might + * have died while we slept). + */ +static inline int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table) { pte_t pte; unsigned long entry; @@ -332,8 +340,9 @@ if (pte_dirty(pte)) { if (mem_map[MAP_NR(page)] != 1) return 0; + vma->vm_task->mm->rss--; if (vma->vm_ops && vma->vm_ops->swapout) - vma->vm_ops->swapout(vma, offset, page_table); + vma->vm_ops->swapout(vma, address-vma->vm_start, page_table); else { if (!(entry = get_swap_page())) return 0; @@ -342,7 +351,7 @@ write_swap_page(entry, (char *) page); } free_page(page); - return 1 + mem_map[MAP_NR(page)]; + return 1; /* we slept: the process may not exist any more */ } if ((entry = find_in_swap_cache(page))) { if (mem_map[MAP_NR(page)] != 1) { @@ -350,15 +359,18 @@ printk("Aiee.. duplicated cached swap-cache entry\n"); return 0; } + vma->vm_task->mm->rss--; pte_val(*page_table) = entry; invalidate(); free_page(page); return 1; } + vma->vm_task->mm->rss--; pte_clear(page_table); invalidate(); + entry = mem_map[MAP_NR(page)]; free_page(page); - return 1 + mem_map[MAP_NR(page)]; + return entry; } /* @@ -409,20 +421,11 @@ end = pmd_end; do { - switch (try_to_swap_out(vma, address-vma->vm_start, pte)) { - case 0: - break; - - case 1: - vma->vm_task->mm->rss--; - /* continue with the following page the next time */ - vma->vm_task->mm->swap_address = address + PAGE_SIZE; - return 1; - - default: - vma->vm_task->mm->rss--; - break; - } + int result; + vma->vm_task->mm->swap_address = address + PAGE_SIZE; + result = try_to_swap_out(vma, address, pte); + if (result) + return result; address += PAGE_SIZE; pte++; } while (address < end); @@ -450,8 +453,9 @@ end = pgd_end; do { - if (swap_out_pmd(vma, pmd, address, end)) - return 1; + int result = swap_out_pmd(vma, pmd, address, end); + if (result) + return result; address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); @@ -465,8 +469,9 @@ end = vma->vm_end; while (start < end) { - if (swap_out_pgd(vma, pgdir, start, end)) - return 1; + int result = swap_out_pgd(vma, pgdir, start, end); + if (result) + return result; start = (start + PGDIR_SIZE) & PGDIR_MASK; pgdir++; } @@ -494,13 +499,16 @@ address = vma->vm_start; for (;;) { - if (swap_out_vma(vma, pgd_offset(p, address), address)) - return 1; + int result = swap_out_vma(vma, pgd_offset(p, address), address); + if (result) + return result; vma = vma->vm_next; if (!vma) - return 0; + break; address = vma->vm_start; } + p->mm->swap_address = 0; + return 0; } static int swap_out(unsigned int priority) @@ -510,7 +518,7 @@ struct task_struct *p; counter = 2*NR_TASKS >> priority; - for(; counter >= 0; counter--, swap_task++) { + for(; counter >= 0; counter--) { /* * Check that swap_task is suitable for swapping. If not, look for * the next suitable process. @@ -547,10 +555,17 @@ else p->mm->swap_cnt = SWAP_RATIO / p->mm->dec_flt; } - if (swap_out_process(p)) { - if ((--p->mm->swap_cnt) == 0) - swap_task++; - return 1; + if (!--p->mm->swap_cnt) + swap_task++; + switch (swap_out_process(p)) { + case 0: + if (p->mm->swap_cnt) + swap_task++; + break; + case 1: + return 1; + default: + break; } } return 0; @@ -790,8 +805,8 @@ for (tmp = free_area_list[order].next ; tmp != free_area_list + order ; tmp = tmp->next) { nr ++; } - total += nr * (4 << order); - printk("%lu*%ukB ", nr, 4 << order); + total += nr * ((PAGE_SIZE>>10) << order); + printk("%lu*%lukB ", nr, (PAGE_SIZE>>10) << order); } restore_flags(flags); printk("= %lukB)\n", total); diff -u --recursive --new-file v1.1.94/linux/net/inet/af_inet.c linux/net/inet/af_inet.c --- v1.1.94/linux/net/inet/af_inet.c Wed Feb 22 16:53:07 1995 +++ linux/net/inet/af_inet.c Thu Feb 23 14:02:24 1995 @@ -28,6 +28,11 @@ * Niibe Yutaka : 4.4BSD style write async I/O * Alan Cox, * Tony Gale : Fixed reuse semantics. + * Alan Cox : bind() shouldn't abort existing but dead + * sockets. Stops FTP netin:.. I hope. + * Alan Cox : bind() works correctly for RAW sockets. Note + * that FreeBSD at least is broken in this respect + * so be careful with compatibility tests... * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -823,77 +828,76 @@ { struct sockaddr_in *addr=(struct sockaddr_in *)uaddr; struct sock *sk=(struct sock *)sock->data, *sk2; - unsigned short snum; + unsigned short snum = 0 /* Stoopid compiler.. this IS ok */; int chk_addr_ret; /* check this error. */ if (sk->state != TCP_CLOSE) return(-EIO); - if (sk->num != 0) - return(-EINVAL); - if(addr_lentype != SOCK_RAW) + { + if (sk->num != 0) + return(-EINVAL); - snum = ntohs(addr->sin_port); + snum = ntohs(addr->sin_port); - /* - * We can't just leave the socket bound wherever it is, it might - * be bound to a privileged port. However, since there seems to - * be a bug here, we will leave it if the port is not privileged. - */ - if (snum == 0) - { - snum = get_new_socknum(sk->prot, 0); + /* + * We can't just leave the socket bound wherever it is, it might + * be bound to a privileged port. However, since there seems to + * be a bug here, we will leave it if the port is not privileged. + */ + if (snum == 0) + { + snum = get_new_socknum(sk->prot, 0); + } + if (snum < PROT_SOCK && !suser()) + return(-EACCES); } - if (snum < PROT_SOCK && !suser()) - return(-EACCES); - + chk_addr_ret = ip_chk_addr(addr->sin_addr.s_addr); if (addr->sin_addr.s_addr != 0 && chk_addr_ret != IS_MYADDR && chk_addr_ret != IS_MULTICAST) return(-EADDRNOTAVAIL); /* Source address MUST be ours! */ - + if (chk_addr_ret || addr->sin_addr.s_addr == 0) sk->saddr = addr->sin_addr.s_addr; - - /* Make sure we are allowed to bind here. */ - cli(); -outside_loop: - for(sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]; - sk2 != NULL; sk2 = sk2->next) + + if(sock->type != SOCK_RAW) { -/* should be below! */ - if (sk2->num != snum) continue; -#if 0 - if (sk2->dead) - { - destroy_sock(sk2); - goto outside_loop; - } -#endif - if (!sk->reuse) - { - sti(); - return(-EADDRINUSE); - } - - if (sk2->num != snum) - continue; /* more than one */ - if (sk2->saddr != sk->saddr) - continue; /* socket per slot ! -FB */ - if (!sk2->reuse || sk2->state==TCP_LISTEN) + /* Make sure we are allowed to bind here. */ + cli(); + for(sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]; + sk2 != NULL; sk2 = sk2->next) { - sti(); - return(-EADDRINUSE); + /* should be below! */ + if (sk2->num != snum) + continue; + if (!sk->reuse) + { + sti(); + return(-EADDRINUSE); + } + + if (sk2->num != snum) + continue; /* more than one */ + if (sk2->saddr != sk->saddr) + continue; /* socket per slot ! -FB */ + if (!sk2->reuse || sk2->state==TCP_LISTEN) + { + sti(); + return(-EADDRINUSE); + } } - } - sti(); + sti(); - remove_sock(sk); - put_sock(snum, sk); - sk->dummy_th.source = ntohs(sk->num); - sk->daddr = 0; - sk->dummy_th.dest = 0; + remove_sock(sk); + put_sock(snum, sk); + sk->dummy_th.source = ntohs(sk->num); + sk->daddr = 0; + sk->dummy_th.dest = 0; + } return(0); } @@ -1002,7 +1006,7 @@ /* - * FIXME: Get BSD behaviour + * Accept a pending connection. The TCP layer now gives BSD semantics. */ static int inet_accept(struct socket *sock, struct socket *newsock, int flags) diff -u --recursive --new-file v1.1.94/linux/net/inet/arp.c linux/net/inet/arp.c --- v1.1.94/linux/net/inet/arp.c Fri Feb 17 11:20:17 1995 +++ linux/net/inet/arp.c Thu Feb 23 13:26:37 1995 @@ -37,6 +37,7 @@ * re-arranged proxy handling. * Alan Cox : Changed to use notifiers. * Niibe Yutaka : Reply for this device or proxies only. + * Alan Cox : Don't proxy across hardware types! */ #include @@ -680,7 +681,7 @@ having to use a huge number of proxy arp entries and having to keep them uptodate. */ - if (proxy_entry->dev != dev && + if (proxy_entry->dev != dev && proxy_entry->htype == htype && !((proxy_entry->ip^tip)&proxy_entry->mask)) break; diff -u --recursive --new-file v1.1.94/linux/net/inet/dev_mcast.c linux/net/inet/dev_mcast.c --- v1.1.94/linux/net/inet/dev_mcast.c Mon Jan 9 11:24:24 1995 +++ linux/net/inet/dev_mcast.c Thu Feb 23 13:26:57 1995 @@ -8,6 +8,10 @@ * Stir fried together from the IP multicast and CAP patches above * Alan Cox * + * Fixes: + * Alan Cox : Update the device on a real delete + * rather than any time but... + * * 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 @@ -114,10 +118,10 @@ *dmi=(*dmi)->next; dev->mc_count--; kfree_s(tmp,sizeof(*tmp)); + dev_mc_upload(dev); return; } } - dev_mc_upload(dev); } /* diff -u --recursive --new-file v1.1.94/linux/net/inet/ip.c linux/net/inet/ip.c --- v1.1.94/linux/net/inet/ip.c Fri Feb 17 11:20:17 1995 +++ linux/net/inet/ip.c Fri Feb 24 21:40:16 1995 @@ -1262,14 +1262,18 @@ struct rtable *rt; /* Route we use */ unsigned char *ptr; /* Data pointer */ unsigned long raddr; /* Router IP address */ - + /* * See if we are allowed to forward this. */ #ifdef CONFIG_IP_FIREWALL - if(!ip_fw_chk(skb->h.iph, ip_fw_fwd_chain, ip_fw_fwd_policy)) + int err; + + if((err=ip_fw_chk(skb->h.iph, dev, ip_fw_fwd_chain, ip_fw_fwd_policy))!=1) { + if(err==-1) + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev); return; } #endif @@ -1425,7 +1429,7 @@ * Count mapping we shortcut */ - ip_acct_cnt(iph,ip_acct_chain); + ip_acct_cnt(iph,dev,ip_acct_chain); #endif /* @@ -1462,6 +1466,9 @@ take up stack space. */ int brd=IS_MYADDR; int is_frag=0; +#ifdef CONFIG_IP_FIREWALL + int err; +#endif ip_statistics.IpInReceives++; @@ -1493,9 +1500,10 @@ #ifdef CONFIG_IP_FIREWALL - if(!LOOPBACK(iph->daddr) && !ip_fw_chk(iph,ip_fw_blk_chain, - ip_fw_blk_policy)) + if ((err=ip_fw_chk(iph,dev,ip_fw_blk_chain,ip_fw_blk_policy))!=1) { + if(err==-1) + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev); kfree_skb(skb, FREE_WRITE); return 0; } @@ -1609,7 +1617,7 @@ */ #ifdef CONFIG_IP_ACCT - ip_acct_cnt(iph,ip_acct_chain); + ip_acct_cnt(iph,dev, ip_acct_chain); #endif /* @@ -1906,7 +1914,7 @@ ip_statistics.IpOutRequests++; #ifdef CONFIG_IP_ACCT - ip_acct_cnt(iph,ip_acct_chain); + ip_acct_cnt(iph,dev, ip_acct_chain); #endif #ifdef CONFIG_IP_MULTICAST diff -u --recursive --new-file v1.1.94/linux/net/inet/ip_fw.c linux/net/inet/ip_fw.c --- v1.1.94/linux/net/inet/ip_fw.c Wed Feb 15 10:36:41 1995 +++ linux/net/inet/ip_fw.c Thu Feb 23 13:26:12 1995 @@ -4,9 +4,18 @@ * and the licenses thus do not conflict. While this port is subject * to the GPL I also place my modifications under the original * license in recognition of the original copyright. + * -- Alan Cox. * * Ported from BSD to Linux, * Alan Cox 22/Nov/1994. + * Zeroing /proc and other additions + * Jos Vos 4/Feb/1995. + * Merged and included the FreeBSD-Current changes at Ugen's request + * (but hey its a lot cleaner now). Ugen would prefer in some ways + * we waited for his final product but since Linux 1.2.0 is about to + * appear its not practical - Read: It works, its not clean but please + * don't consider it to be his standard of finished work. + * Alan Cox 12/Feb/1995 * * All the real work was done by ..... */ @@ -25,6 +34,7 @@ * This software is provided ``AS IS'' without any warranties of any kind. */ +#include #include #include #include @@ -39,6 +49,8 @@ #include #include #include +#include +#include #include "ip.h" #include "protocol.h" #include "route.h" @@ -52,11 +64,34 @@ * Implement IP packet firewall */ +#ifdef CONFIG_IPFIREWALL_DEBUG +#define dprintf1(a) printk(a) +#define dprintf2(a1,a2) printk(a1,a2) +#define dprintf3(a1,a2,a3) printk(a1,a2,a3) +#define dprintf4(a1,a2,a3,a4) printk(a1,a2,a3,a4) +#else +#define dprintf1(a) +#define dprintf2(a1,a2) +#define dprintf3(a1,a2,a3) +#define dprintf4(a1,a2,a3,a4) +#endif + +#define print_ip(a) printf("%d.%d.%d.%d",(ntohl(a.s_addr)>>24)&0xFF,\ + (ntohl(a.s_addr)>>16)&0xFF,\ + (ntohl(a.s_addr)>>8)&0xFF,\ + (ntohl(a.s_addr))&0xFF); + +#ifdef IPFIREWALL_DEBUG +#define dprint_ip(a) print_ip(a) +#else +#define dprint_ip(a) +#endif + #ifdef CONFIG_IP_FIREWALL struct ip_fw *ip_fw_fwd_chain; struct ip_fw *ip_fw_blk_chain; -int ip_fw_blk_policy=1; -int ip_fw_fwd_policy=1; +int ip_fw_blk_policy=IP_FW_F_ACCEPT; +int ip_fw_fwd_policy=IP_FW_F_ACCEPT; #endif #ifdef CONFIG_IP_ACCT struct ip_fw *ip_acct_chain; @@ -67,16 +102,6 @@ #define IP_INFO_ACCT 2 -extern inline void print_ip(unsigned long xaddr) -{ - unsigned long addr = ntohl(xaddr); - printk("%ld.%ld.%ld.%ld",(addr>>24) & 0xff, - (addr>>16)&0xff, - (addr>>8)&0xff, - addr&0xFF); -} - - /* * Returns 1 if the port is matched by the vector, 0 otherwise */ @@ -104,336 +129,230 @@ return(0); } +#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL) + /* - * Returns 0 if packet should be dropped, 1 or more if it should be accepted + * Returns 0 if packet should be dropped, 1 or more if it should be accepted. + * Also does accounting so you can feed it the accounting chain. */ -#ifdef CONFIG_IP_FIREWALL -int ip_fw_chk(struct iphdr *ip, struct ip_fw *chain, int policy) +int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int policy) { - unsigned long src, dst; - char got_proto=0; - int frwl_proto, proto=0; struct ip_fw *f; - unsigned short src_port=0, dst_port=0; - unsigned short *portptr=(unsigned short *)&(((u_int *)ip)[ip->ihl]); - - if (!chain) - return(policy); /* If no chain, use your policy. */ + struct tcphdr *tcp=(struct tcphdr *)((unsigned long *)ip+ip->ihl); + struct udphdr *udp=(struct udphdr *)((unsigned long *)ip+ip->ihl); + __u32 src, dst; + __u16 src_port=0, dst_port=0; + unsigned short f_prt=0, prt; + char notcpsyn=1; + unsigned short f_flag; + /* + * If the chain is empty follow policy. The BSD one + * accepts anything giving you a time window while + * flushing and rebuilding the tables. + */ + src = ip->saddr; dst = ip->daddr; -#ifdef DEBUG_CONFIG_IP_FIREWALL - { - printk("packet "); - switch(ip->protocol) - { - case IPPROTO_TCP: - printf("TCP "); - break; - case IPPROTO_UDP: - printf("UDP "); - break; - case IPPROTO_ICMP: - printf("ICMP:%d ",((char *)portptr)[0]&0xff); - break; - default: - printf("p=%d ",ip->protocol); - break; - } - print_ip(ip->saddr); - if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP) - { - printf(":%d ",ntohs(portptr[0])); - } - print_ip(ip->daddr); - if ( ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP) - { - printf(":%d ",ntohs(portptr[1])); - } - printf("\n"); - } -#endif - - for (f=chain;f;f=f->next) - { - if ((src&f->src_mask.s_addr)==f->src.s_addr - && (dst&f->dst_mask.s_addr)==f->dst.s_addr) - { - frwl_proto=f->flags&IP_FW_F_KIND; - if (frwl_proto==IP_FW_F_ALL) - { - /* Universal frwl - we've got a match! */ - -#ifdef DEBUG_CONFIG_IP_FIREWALL - printf("universal frwl match\n"); -#endif - f->p_cnt++; - f->b_cnt+=ntohs(ip->tot_len); -#ifdef CONFIG_IP_FIREWALL_VERBOSE - if (!(f->flags & IP_FW_F_ACCEPT)) - goto bad_packet; - return 1; -#else - return( f->flags & IP_FW_F_ACCEPT ); -#endif - } - else - { - /* - * Specific firewall - packet's protocol must match firewall's - */ - if (!got_proto) - { - /* - * We still had not determined the protocol - * of this packet,now the time to do so. - */ - switch(ip->protocol) - { - case IPPROTO_TCP: - /* - * First two shorts in TCP are src/dst ports - */ - proto=IP_FW_F_TCP; - src_port=ntohs(portptr[0]); - dst_port=ntohs(portptr[1]); - break; - case IPPROTO_UDP: - /* - * First two shorts in UDP are src/dst ports - */ - proto = IP_FW_F_UDP; - src_port = ntohs(portptr[0]); - dst_port = ntohs(portptr[1]); - break; - case IPPROTO_ICMP: - proto=IP_FW_F_ICMP; - break; - default: - proto=IP_FW_F_ALL; -#ifdef DEBUG_CONFIG_IP_FIREWALL - printf("non TCP/UDP packet\n"); -#endif - } - got_proto=1; - } - /* - * At this moment we surely know the protocol of this - * packet and we'll check if it matches,then proceed further.. - */ - if (proto==frwl_proto) - { - - if (proto==IP_FW_F_ICMP || (port_match(&f->ports[0],f->n_src_p,src_port, - f->flags&IP_FW_F_SRNG) && - port_match(&f->ports[f->n_src_p],f->n_dst_p,dst_port, - f->flags&IP_FW_F_DRNG))) - { - /* We've got a match! */ - f->p_cnt++; - f->b_cnt+=ntohs(ip->tot_len); -#ifdef CONFIG_IP_FIREWALL_VERBOSE - if (!(f->flags & IP_FW_F_ACCEPT)) - goto bad_packet; - return 1; -#else - return( f->flags & IP_FW_F_ACCEPT); -#endif - } /* Ports match */ - } /* Proto matches */ - } /* ALL/Specific */ - } /* IP addr/mask matches */ - } /* Loop */ - - /* - * If we get here then none of the firewalls matched. - * So now we relay on policy defined by user-unmatched packet can - * be ever accepted or rejected... + /* + * This way we handle fragmented packets. + * we ignore all fragments but the first one + * so the whole packet can't be reassembled. + * This way we relay on the full info which + * stored only in first packet. + * + * Note that this theoretically allows partial packet + * spoofing. Not very dangerous but paranoid people may + * wish to play with this. It also allows the so called + * "fragment bomb" denial of service attack on some types + * of system. */ -#ifdef CONFIG_IP_FIREWALL_VERBOSE - if (!(policy)) - goto bad_packet; - return 1; -#else - return(policy); -#endif - -#ifdef CONFIG_IP_FIREWALL_VERBOSE -bad_packet: - /* - * VERY ugly piece of code which actually - * makes kernel printf for denied packets... - */ - if (f->flags&IP_FW_F_PRN) - { - printf("ip_fw_chk says no to "); - switch(ip->protocol) - { - case IPPROTO_TCP: - printf("TCP "); - break; - case IPPROTO_UDP: - printf("UDP "); - break; - case IPPROTO_ICMP: - printf("ICMP:%d ",((char *)portptr)[0]&0xff); - break; - default: - printf("p=%d ",ip->protocol); - break; - } - print_ip(ip->saddr); - if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP) - { - printf(":%d ",ntohs(portptr[0])); - } - else - { - printf("\n"); - } - print_ip(ip->daddr); - if ( ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP ) - { - printf(":%d ",ntohs(portptr[1])); - } - printf("\n"); - } - return(0); -#endif -} -#endif /* CONFIG_IP_FIREWALL */ - - - - -#ifdef CONFIG_IP_ACCT -void ip_acct_cnt(struct iphdr *ip,struct ip_fw *chain) -{ - unsigned long src, dst; - char got_proto=0,rev=0; - int frwl_proto, proto=0; - struct ip_fw *f; - unsigned short src_port=0, dst_port=0; - unsigned short *portptr=(unsigned short *)&(((u_int *)ip)[ip->ihl]); - - if (!chain) - return; + if (ip->frag_off&IP_OFFSET) + return(1); src = ip->saddr; dst = ip->daddr; - for (f=chain;f;f=f->next) - { - if ((src&f->src_mask.s_addr)==f->src.s_addr - && (dst&f->dst_mask.s_addr)==f->dst.s_addr) - { - rev=0; - goto addr_match; - } - if ((f->flags&IP_FW_F_BIDIR) && - ((src&f->src_mask.s_addr)==f->dst.s_addr - && (dst&f->dst_mask.s_addr)==f->src.s_addr)) - { - rev=1; - goto addr_match; - } - continue; -addr_match: - frwl_proto=f->flags&IP_FW_F_KIND; - if (frwl_proto==IP_FW_F_ALL) + /* + * If we got interface from which packet came + * we can use the address directly. This is unlike + * 4.4BSD derived systems that have an address chain + * per device. We have a device per address with dummy + * devices instead. + */ + + dprintf1("Packet "); + switch(ip->protocol) + { + case IPPROTO_TCP: + dprintf1("TCP "); + src_port=ntohs(tcp->source); + dst_port=ntohs(tcp->dest); + if(tcp->syn) + notcpsyn=0; /* We *DO* have SYN, value FALSE */ + prt=IP_FW_F_TCP; + break; + case IPPROTO_UDP: + dprintf1("UDP "); + src_port=ntohs(udp->source); + dst_port=ntohs(udp->dest); + prt=IP_FW_F_UDP; + break; + case IPPROTO_ICMP: + dprintf2("ICMP:%d ",((char *)portptr)[0]&0xff); + prt=IP_FW_F_ICMP; + break; + default: + dprintf2("p=%d ",ip->protocol); + prt=IP_FW_F_ALL; + break; + } + dprint_ip(ip->saddr); + + if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP) + dprintf2(":%d ", src_port); + dprint_ip(ip->daddr); + if ( ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP) + dprintf2(":%d ",dst_port); + dprintf1("\n"); + + for (f=chain;f;f=f->fw_next) + { + /* + * This is a bit simpler as we don't have to walk + * an interface chain as you do in BSD - same logic + * however. + */ + if ((src&f->fw_smsk.s_addr)==f->fw_src.s_addr + && (dst&f->fw_dmsk.s_addr)==f->fw_dst.s_addr) { - /* Universal frwl - we've got a match! */ - f->p_cnt++; /* Rise packet count */ - /* - * Rise byte count, convert from host to network byte order. - */ - - f->b_cnt+=ntohs(ip->tot_len); + * Look for a VIA match + */ + if(f->fw_via.s_addr && rif) + { + if(rif->pa_addr!=f->fw_via.s_addr) + continue; /* Mismatch */ + } + /* + * Drop through - this is a match + */ } else + continue; + + /* + * Ok the chain addresses match. + */ + + f_prt=f->fw_flg&IP_FW_F_KIND; + if (f_prt!=IP_FW_F_ALL) { /* - * Specific firewall - packet's protocol must match firewall's + * This is actually buggy as if you set SYN flag + * on UDP or ICMP firewall it will never work,but + * actually it is a concern of software which sets + * firewall entries. */ - if (!got_proto) - { - /* - * We still had not determined the protocol - * of this packet,now the time to do so. - */ - switch(ip->protocol) - { - case IPPROTO_TCP: - /* - * First two shorts in TCP are src/dst ports - */ - proto=IP_FW_F_TCP; - src_port=ntohs(portptr[0]); - dst_port=ntohs(portptr[1]); - break; - case IPPROTO_UDP: - /* - * First two shorts in UDP are src/dst ports - */ - proto = IP_FW_F_UDP; - src_port = ntohs(portptr[0]); - dst_port = ntohs(portptr[1]); - break; - case IPPROTO_ICMP: - proto=IP_FW_F_ICMP; - break; - default: - proto=IP_FW_F_ALL; - } - got_proto=1; - } + if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn) + continue; /* - * At this moment we surely know the protocol of this - * packet and we'll check if it matches,then proceed further.. + * Specific firewall - packet's protocol + * must match firewall's. */ - if (proto==frwl_proto) + + if(prt!=f_prt) + continue; + + if(!(prt==IP_FW_F_ICMP ||( + port_match(&f->fw_pts[0], f->fw_nsp, src_port, + f->fw_flg&IP_FW_F_SRNG) && + port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port, + f->fw_flg&IP_FW_F_SRNG)))) { + continue; + } + } +#ifdef CONFIG_IP_FIREWALL_VERBOSE + /* + * VERY ugly piece of code which actually + * makes kernel printf for denied packets... + */ + + if (f->fw_flg & IP_FW_F_PRN) + { + if(f->fw_flg&IP_FW_F_ACCEPT) + printk("Accept "); + else + printk("Deny "); + switch(ip->protocol) + { + case IPPROTO_TCP: + printk("TCP "); + break; + case IPPROTO_UDP: + printk("UDP "); + case IPPROTO_ICMP: + printk("ICMP "); + break; + default: + printk("p=%d ",ip->protocol); + break; + } + print_ip(ip->saddr); + if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP) + printk(":%d", src_port); + printk(" "); + print_ip(ip->daddr); + if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP) + printk(":%d",dst_port); + printk("\n"); + } +#endif + if(f->fw_flg&IP_FW_F_ACCEPT) + { + f->fw_bcnt+=ntohs(ip->tot_len); + f->fw_pcnt++; + return 1; + } + break; + } /* Loop */ + + /* + * If we get here then none of the firewalls matched or one matched + * but was a no. So now we rely on policy defined in the rejecting + * entry or if none was found in the policy variable + */ + + if(f!=NULL) /* A deny match */ + f_flag=f->fw_flg; + else + f_flag=policy; + if(f_flag&IP_FW_F_ACCEPT) + return 1; + if(f_flag&IP_FW_F_ICMPRPL) + return -1; + return 0; +} + + - if ((proto==IP_FW_F_ICMP || - (port_match(&f->ports[0],f->n_src_p,src_port, - f->flags&IP_FW_F_SRNG) && - port_match(&f->ports[f->n_src_p],f->n_dst_p,dst_port, - f->flags&IP_FW_F_DRNG))) - || ((rev) - && (port_match(&f->ports[0],f->n_src_p,dst_port, - f->flags&IP_FW_F_SRNG) - && port_match(&f->ports[f->n_src_p],f->n_dst_p,src_port, - f->flags&IP_FW_F_DRNG)))) - { - f->p_cnt++; /* Rise packet count */ - /* - * Rise byte count, convert from host to network byte order. - */ - f->b_cnt+=ntohs(ip->tot_len); - } /* Ports match */ - } /* Proto matches */ - } /* ALL/Specific */ - } /* IP addr/mask matches */ -} /* End of whole function */ -#endif /* CONFIG_IP_ACCT */ -#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL) static void zero_fw_chain(struct ip_fw *chainptr) { struct ip_fw *ctmp=chainptr; while(ctmp) { - ctmp->p_cnt=0l; - ctmp->b_cnt=0l; - ctmp=ctmp->next; + ctmp->fw_pcnt=0L; + ctmp->fw_bcnt=0L; + ctmp=ctmp->fw_next; } } @@ -446,7 +365,7 @@ { struct ip_fw *ftmp; ftmp = *chainptr; - *chainptr = ftmp->next; + *chainptr = ftmp->fw_next; kfree_s(ftmp,sizeof(*ftmp)); } restore_flags(flags); @@ -475,15 +394,15 @@ #ifdef DEBUG_CONFIG_IP_FIREWALL printf("ip_fw_ctl: malloc said no\n"); #endif - return( ENOSPC ); + return( ENOMEM ); } memcpy(ftmp, frwl, sizeof( struct ip_fw ) ); - ftmp->p_cnt=0L; - ftmp->b_cnt=0L; + ftmp->fw_pcnt=0L; + ftmp->fw_bcnt=0L; - ftmp->next = NULL; + ftmp->fw_next = NULL; cli(); @@ -494,11 +413,11 @@ else { chtmp_prev=NULL; - for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->next) + for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next) { addb4=0; - newkind=ftmp->flags & IP_FW_F_KIND; - oldkind=chtmp->flags & IP_FW_F_KIND; + newkind=ftmp->fw_flg & IP_FW_F_KIND; + oldkind=chtmp->fw_flg & IP_FW_F_KIND; if (newkind!=IP_FW_F_ALL && oldkind!=IP_FW_F_ALL @@ -513,15 +432,15 @@ * Sorry,but i had to do this.... */ - n_sa=ntohl(ftmp->src.s_addr); - n_da=ntohl(ftmp->dst.s_addr); - n_sm=ntohl(ftmp->src_mask.s_addr); - n_dm=ntohl(ftmp->dst_mask.s_addr); - - o_sa=ntohl(chtmp->src.s_addr); - o_da=ntohl(chtmp->dst.s_addr); - o_sm=ntohl(chtmp->src_mask.s_addr); - o_dm=ntohl(chtmp->dst_mask.s_addr); + n_sa=ntohl(ftmp->fw_src.s_addr); + n_da=ntohl(ftmp->fw_dst.s_addr); + n_sm=ntohl(ftmp->fw_smsk.s_addr); + n_dm=ntohl(ftmp->fw_dmsk.s_addr); + + o_sa=ntohl(chtmp->fw_src.s_addr); + o_da=ntohl(chtmp->fw_dst.s_addr); + o_sm=ntohl(chtmp->fw_smsk.s_addr); + o_dm=ntohl(chtmp->fw_dmsk.s_addr); m_src_mask = o_sm & n_sm; m_dst_mask = o_dm & n_dm; @@ -563,23 +482,24 @@ * of ports. */ - if (ftmp->flags & IP_FW_F_SRNG) - n_sr=ftmp->ports[1]-ftmp->ports[0]; + if (ftmp->fw_flg & IP_FW_F_SRNG) + n_sr=ftmp->fw_pts[1]-ftmp->fw_pts[0]; else - n_sr=(ftmp->n_src_p)?ftmp->n_src_p : 0xFFFF; + n_sr=(ftmp->fw_nsp)? + ftmp->fw_nsp : 0xFFFF; - if (chtmp->flags & IP_FW_F_SRNG) - o_sr=chtmp->ports[1]-chtmp->ports[0]; + if (chtmp->fw_flg & IP_FW_F_SRNG) + o_sr=chtmp->fw_pts[1]-chtmp->fw_pts[0]; else - o_sr=(chtmp->n_src_p)?chtmp->n_src_p : 0xFFFF; + o_sr=(chtmp->fw_nsp)?chtmp->fw_nsp : 0xFFFF; if (n_sro_sr) addb4--; - n_n=ftmp->n_src_p; - n_o=chtmp->n_src_p; + n_n=ftmp->fw_nsp; + n_o=chtmp->fw_nsp; /* * Actually this cannot happen as the frwl control @@ -591,15 +511,15 @@ (n_o>(IP_FW_MAX_PORTS-2))) goto skip_check; - if (ftmp->flags & IP_FW_F_DRNG) - n_dr=ftmp->ports[n_n+1]-ftmp->ports[n_n]; + if (ftmp->fw_flg & IP_FW_F_DRNG) + n_dr=ftmp->fw_pts[n_n+1]-ftmp->fw_pts[n_n]; else - n_dr=(ftmp->n_dst_p)? ftmp->n_dst_p : 0xFFFF; + n_dr=(ftmp->fw_ndp)? ftmp->fw_ndp : 0xFFFF; - if (chtmp->flags & IP_FW_F_DRNG) - o_dr=chtmp->ports[n_o+1]-chtmp->ports[n_o]; + if (chtmp->fw_flg & IP_FW_F_DRNG) + o_dr=chtmp->fw_pts[n_o+1]-chtmp->fw_pts[n_o]; else - o_dr=(chtmp->n_dst_p)? chtmp->n_dst_p : 0xFFFF; + o_dr=(chtmp->fw_ndp)? chtmp->fw_ndp : 0xFFFF; if (n_dro_dr) @@ -611,13 +531,13 @@ { if (chtmp_prev) { - chtmp_prev->next=ftmp; - ftmp->next=chtmp; + chtmp_prev->fw_next=ftmp; + ftmp->fw_next=chtmp; } else { *chainptr=ftmp; - ftmp->next=chtmp; + ftmp->fw_next=chtmp; } restore_flags(flags); return 0; @@ -627,7 +547,7 @@ } if (chtmp_prev) - chtmp_prev->next=ftmp; + chtmp_prev->fw_next=ftmp; else *chainptr=ftmp; restore_flags(flags); @@ -649,7 +569,7 @@ if ( ftmp == NULL ) { #ifdef DEBUG_CONFIG_IP_FIREWALL - printf("ip_fw_ctl: chain is empty\n"); + printk("ip_fw_ctl: chain is empty\n"); #endif restore_flags(flags); return( EINVAL ); @@ -661,21 +581,22 @@ while( ftmp != NULL ) { matches=1; - if ((memcmp(&ftmp->src,&frwl->src,sizeof(struct in_addr))) - || (memcmp(&ftmp->src_mask,&frwl->src_mask,sizeof(struct in_addr))) - || (memcmp(&ftmp->dst,&frwl->dst,sizeof(struct in_addr))) - || (memcmp(&ftmp->dst_mask,&frwl->dst_mask,sizeof(struct in_addr))) - || (ftmp->flags!=frwl->flags)) + if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr + || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr + || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr + || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr + || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr + || ftmp->fw_flg!=frwl->fw_flg) matches=0; - tport1=ftmp->n_src_p+ftmp->n_dst_p; - tport2=frwl->n_src_p+frwl->n_dst_p; + tport1=ftmp->fw_nsp+ftmp->fw_ndp; + tport2=frwl->fw_nsp+frwl->fw_ndp; if (tport1!=tport2) matches=0; else if (tport1!=0) { for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++) - if (ftmp->ports[tmpnum]!=frwl->ports[tmpnum]) + if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum]) matches=0; } if(matches) @@ -683,13 +604,13 @@ was_found=1; if (ltmp) { - ltmp->next=ftmp->next; + ltmp->fw_next=ftmp->fw_next; kfree_s(ftmp,sizeof(*ftmp)); - ftmp=ltmp->next; + ftmp=ltmp->fw_next; } else { - *chainptr=ftmp->next; + *chainptr=ftmp->fw_next; kfree_s(ftmp,sizeof(*ftmp)); ftmp=*chainptr; } @@ -697,7 +618,7 @@ else { ltmp = ftmp; - ftmp = ftmp->next; + ftmp = ftmp->fw_next; } } restore_flags(flags); @@ -715,44 +636,44 @@ if ( len != sizeof(struct ip_fw) ) { #ifdef DEBUG_CONFIG_IP_FIREWALL - printf("ip_fw_ctl: len=%d, want %d\n",m->m_len, + printk("ip_fw_ctl: len=%d, want %d\n",m->m_len, sizeof(struct ip_fw)); #endif return(NULL); } - if ( (frwl->flags & ~IP_FW_F_MASK) != 0 ) + if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 ) { #ifdef DEBUG_CONFIG_IP_FIREWALL - printf("ip_fw_ctl: undefined flag bits set (flags=%x)\n", - frwl->flags); + printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n", + frwl->fw_flg); #endif return(NULL); } - if ( (frwl->flags & IP_FW_F_SRNG) && frwl->n_src_p < 2 ) + if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 ) { #ifdef DEBUG_CONFIG_IP_FIREWALL - printf("ip_fw_ctl: src range set but n_src_p=%d\n", - frwl->n_src_p); + printk("ip_fw_ctl: src range set but n_src_p=%d\n", + frwl->fw_nsp); #endif return(NULL); } - if ( (frwl->flags & IP_FW_F_DRNG) && frwl->n_dst_p < 2 ) + if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 ) { #ifdef DEBUG_CONFIG_IP_FIREWALL - printf("ip_fw_ctl: dst range set but n_dst_p=%d\n", - frwl->n_dst_p); + printk("ip_fw_ctl: dst range set but n_dst_p=%d\n", + frwl->fw_ndp); #endif return(NULL); } - if ( frwl->n_src_p + frwl->n_dst_p > IP_FW_MAX_PORTS ) + if ( frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS ) { #ifdef DEBUG_CONFIG_IP_FIREWALL - printf("ip_fw_ctl: too many ports (%d+%d)\n", - frwl->n_src_p,frwl->n_dst_p); + printk("ip_fw_ctl: too many ports (%d+%d)\n", + frwl->fw_nsp,frwl->fw_ndp); #endif return(NULL); } @@ -764,6 +685,12 @@ #ifdef CONFIG_IP_ACCT + +int ip_acct_cnt(struct iphdr *iph, struct device *dev, struct ip_fw *f) +{ + return ip_fw_chk(iph, dev, f, 0); +} + int ip_acct_ctl(int stage, void *m, int len) { if ( stage == IP_ACCT_FLUSH ) @@ -839,8 +766,6 @@ { int *tmp_policy_ptr; tmp_policy_ptr=(int *)m; - if ((*tmp_policy_ptr)!=1 && (*tmp_policy_ptr)!=0) - return (EINVAL); if ( stage == IP_FW_POLICY_BLK ) ip_fw_blk_policy=*tmp_policy_ptr; else @@ -872,7 +797,7 @@ return(EINVAL); } - if ( ip_fw_chk(ip, + if ( ip_fw_chk(ip, NULL, stage == IP_FW_CHK_BLK ? ip_fw_blk_chain : ip_fw_fwd_chain, stage == IP_FW_CHK_BLK ? @@ -912,7 +837,7 @@ * Should be panic but... (Why are BSD people panic obsessed ??) */ #ifdef DEBUG_CONFIG_IP_FIREWALL - printf("ip_fw_ctl: unknown request %d\n",stage); + printk("ip_fw_ctl: unknown request %d\n",stage); #endif return(EINVAL); } @@ -968,16 +893,16 @@ while(i!=NULL) { - len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %X ", - ntohl(i->src.s_addr),ntohl(i->src_mask.s_addr), - ntohl(i->dst.s_addr),ntohl(i->dst_mask.s_addr), - i->flags); + len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %08lX %X ", + ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr), + ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr), + ntohl(i->fw_via.s_addr),i->fw_flg); len+=sprintf(buffer+len,"%u %u %lu %lu ", - i->n_src_p,i->n_dst_p, i->p_cnt,i->b_cnt); + i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt); len+=sprintf(buffer+len,"%u %u %u %u %u %u %u %u %u %u\n", - i->ports[0],i->ports[1],i->ports[2],i->ports[3], - i->ports[4],i->ports[5],i->ports[6],i->ports[7], - i->ports[8],i->ports[9]); + i->fw_pts[0],i->fw_pts[1],i->fw_pts[2],i->fw_pts[3], + i->fw_pts[4],i->fw_pts[5],i->fw_pts[6],i->fw_pts[7], + i->fw_pts[8],i->fw_pts[9]); pos=begin+len; if(posp_cnt=0L; - i->b_cnt=0L; + i->fw_pcnt=0L; + i->fw_bcnt=0L; } if(pos>offset+length) break; - i=i->next; + i=i->fw_next; } restore_flags(flags); *start=buffer+(offset-begin); @@ -1005,23 +930,38 @@ #ifdef CONFIG_IP_ACCT -int ip_acct_procinfo(char *buffer, char **start, off_t offset, int length, int reset) +int ip_acct_procinfo(char *buffer, char **start, off_t offset, int length) { - return ip_chain_procinfo(IP_INFO_ACCT,buffer,start,offset,length,reset); + return ip_chain_procinfo(IP_INFO_ACCT, buffer,start,offset,length,0); +} + +int ip_acct0_procinfo(char *buffer, char **start, off_t offset, int length) +{ + return ip_chain_procinfo(IP_INFO_ACCT, buffer,start,offset,length,1); } #endif #ifdef CONFIG_IP_FIREWALL -int ip_fw_blk_procinfo(char *buffer, char **start, off_t offset, int length, int reset) +int ip_fw_blk_procinfo(char *buffer, char **start, off_t offset, int length) +{ + return ip_chain_procinfo(IP_INFO_BLK, buffer,start,offset,length,0); +} + +int ip_fw_blk0_procinfo(char *buffer, char **start, off_t offset, int length) +{ + return ip_chain_procinfo(IP_INFO_BLK, buffer,start,offset,length,1); +} + +int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset, int length) { - return ip_chain_procinfo(IP_INFO_BLK,buffer,start,offset,length,reset); + return ip_chain_procinfo(IP_INFO_FWD, buffer,start,offset,length,0); } -int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset, int length, int reset) +int ip_fw_fwd0_procinfo(char *buffer, char **start, off_t offset, int length) { - return ip_chain_procinfo(IP_INFO_FWD,buffer,start,offset,length,reset); + return ip_chain_procinfo(IP_INFO_FWD, buffer,start,offset,length,1); } #endif diff -u --recursive --new-file v1.1.94/linux/net/inet/ipx.c linux/net/inet/ipx.c --- v1.1.94/linux/net/inet/ipx.c Wed Feb 15 10:36:41 1995 +++ linux/net/inet/ipx.c Thu Feb 23 13:31:40 1995 @@ -1276,8 +1276,6 @@ switch(optname) { case IPX_TYPE: - if(!suser()) - return(-EPERM); sk->ipx_type=opt; return 0; default: @@ -1681,9 +1679,6 @@ return -EINVAL; if(usipx->sipx_family != AF_IPX) return -EINVAL; - - if(htons(usipx->sipx_port)state!=TCP_ESTABLISHED) return -ENOTCONN; diff -u --recursive --new-file v1.1.94/linux/net/socket.c linux/net/socket.c --- v1.1.94/linux/net/socket.c Sun Feb 5 19:31:56 1995 +++ linux/net/socket.c Thu Feb 23 13:26:45 1995 @@ -1,7 +1,7 @@ /* * NET An implementation of the SOCKET network access protocol. * - * Version: @(#)socket.c 1.0.5 05/25/93 + * Version: @(#)socket.c 1.1.93 18/02/95 * * Authors: Orest Zborowski, * Ross Biro, @@ -29,6 +29,9 @@ * allowed to allocate. * Linus : Argh. removed all the socket allocation * altogether: it's in the inode now. + * Alan Cox : Made sock_alloc()/sock_release() public + * for NetROM and future kernel nfsd type + * stuff. * * * This program is free software; you can redistribute it and/or @@ -225,7 +228,8 @@ /* * Allocate a socket. */ -static struct socket *sock_alloc(void) + +struct socket *sock_alloc(void) { struct inode * inode; struct socket * sock; @@ -265,8 +269,7 @@ sock_wake_async(peer, 1); } - -static void sock_release(struct socket *sock) +void sock_release(struct socket *sock) { int oldstate; struct socket *peersock, *nextsock;