diff -u --recursive --new-file v2.1.2/linux/CREDITS linux/CREDITS --- v2.1.2/linux/CREDITS Wed Oct 9 08:55:16 1996 +++ linux/CREDITS Thu Oct 10 11:36:39 1996 @@ -285,6 +285,7 @@ N: Ray Dassen E: jdassen@wi.LeidenUniv.nl W: http://www.wi.leidenuniv.nl/~jdassen/ +P: 1024/672D05C1 DD 60 32 60 F7 90 64 80 E7 6F D4 E4 F8 C9 4A 58 D: Debian GNU/Linux: www.debian.org maintainer, FAQ co-maintainer, D: packages testing, nit-picking & fixing. Enjoying BugFree (TM) kernels. S: Zuidsingel 10A diff -u --recursive --new-file v2.1.2/linux/Makefile linux/Makefile --- v2.1.2/linux/Makefile Wed Oct 9 08:55:16 1996 +++ linux/Makefile Wed Oct 9 08:54:36 1996 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 2 +SUBLEVEL = 3 ARCH = i386 diff -u --recursive --new-file v2.1.2/linux/arch/alpha/kernel/ksyms.c linux/arch/alpha/kernel/ksyms.c --- v2.1.2/linux/arch/alpha/kernel/ksyms.c Sun Aug 4 13:37:59 1996 +++ linux/arch/alpha/kernel/ksyms.c Thu Oct 10 16:19:17 1996 @@ -54,10 +54,12 @@ X(__remlu), X(__divqu), X(__remqu), - X(insl), + X(insb), X(insw), - X(outsl), + X(insl), + X(outsb), X(outsw), + X(outsl), X(strcat), X(strcmp), X(strcpy), diff -u --recursive --new-file v2.1.2/linux/arch/alpha/kernel/lca.c linux/arch/alpha/kernel/lca.c --- v2.1.2/linux/arch/alpha/kernel/lca.c Wed Oct 9 08:55:16 1996 +++ linux/arch/alpha/kernel/lca.c Thu Oct 10 08:54:43 1996 @@ -429,7 +429,7 @@ switch (el.c->size) { case sizeof(struct el_lca_mcheck_short): printk(KERN_CRIT - " Reason: %s (short frame%s, dc_stat=%lx):\pn", + " Reason: %s (short frame%s, dc_stat=%lx):\n", reason, el.c->retry ? ", retryable" : "", el.s->dc_stat); if (el.s->esr & ESR_EAV) { mem_error(el.s->esr, el.s->ear); diff -u --recursive --new-file v2.1.2/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- v2.1.2/linux/arch/alpha/kernel/osf_sys.c Sun Aug 18 10:42:02 1996 +++ linux/arch/alpha/kernel/osf_sys.c Thu Oct 10 08:48:47 1996 @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.2/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.1.2/linux/arch/alpha/kernel/process.c Mon Sep 9 13:06:24 1996 +++ linux/arch/alpha/kernel/process.c Wed Oct 9 07:58:02 1996 @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.2/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v2.1.2/linux/arch/alpha/kernel/setup.c Sun Aug 18 10:37:57 1996 +++ linux/arch/alpha/kernel/setup.c Thu Oct 10 08:48:54 1996 @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.2/linux/arch/i386/kernel/ksyms.c linux/arch/i386/kernel/ksyms.c --- v2.1.2/linux/arch/i386/kernel/ksyms.c Sat Oct 5 16:58:34 1996 +++ linux/arch/i386/kernel/ksyms.c Thu Oct 10 17:23:20 1996 @@ -4,6 +4,7 @@ #include #include +#include #include extern void dump_thread(struct pt_regs *, struct user *); @@ -12,6 +13,8 @@ static struct symbol_table arch_symbol_table = { #include /* platform dependent support */ + X(EISA_bus), + X(wp_works_ok), X(dump_thread), X(dump_fpu), X(ioremap), diff -u --recursive --new-file v2.1.2/linux/arch/i386/math-emu/errors.c linux/arch/i386/math-emu/errors.c --- v2.1.2/linux/arch/i386/math-emu/errors.c Mon May 6 16:31:17 1996 +++ linux/arch/i386/math-emu/errors.c Thu Oct 10 16:01:11 1996 @@ -292,7 +292,7 @@ 0x242 in div_Xsig.S */ -void exception(int n) +void FPU_exception(int n) { int i, int_type; @@ -482,7 +482,7 @@ } else { - exception(flags); + EXCEPTION(flags); return 1; } } @@ -494,7 +494,7 @@ if ( control_word & CW_Precision ) partial_status |= (SW_Precision | SW_C1); /* The masked response */ else - exception(EX_Precision | SW_C1); + EXCEPTION(EX_Precision | SW_C1); } @@ -508,7 +508,7 @@ partial_status |= SW_Precision; } else - exception(EX_Precision); + EXCEPTION(EX_Precision); } @@ -521,7 +521,7 @@ } else { - exception(EX_Denormal); + EXCEPTION(EX_Denormal); return 1; } } diff -u --recursive --new-file v2.1.2/linux/arch/i386/math-emu/exception.h linux/arch/i386/math-emu/exception.h --- v2.1.2/linux/arch/i386/math-emu/exception.h Thu Jun 29 18:25:27 1995 +++ linux/arch/i386/math-emu/exception.h Thu Oct 10 16:01:12 1996 @@ -43,9 +43,9 @@ #ifdef DEBUG #define EXCEPTION(x) { printk("exception in %s at line %d\n", \ - __FILE__, __LINE__); exception(x); } + __FILE__, __LINE__); FPU_exception(x); } #else -#define EXCEPTION(x) exception(x) +#define EXCEPTION(x) FPU_exception(x) #endif #endif __ASSEMBLY__ diff -u --recursive --new-file v2.1.2/linux/arch/i386/math-emu/fpu_asm.h linux/arch/i386/math-emu/fpu_asm.h --- v2.1.2/linux/arch/i386/math-emu/fpu_asm.h Thu Oct 5 15:30:43 1995 +++ linux/arch/i386/math-emu/fpu_asm.h Thu Oct 10 16:01:12 1996 @@ -12,7 +12,7 @@ #include -#define EXCEPTION SYMBOL_NAME(exception) +#define EXCEPTION SYMBOL_NAME(FPU_exception) #define PARAM1 8(%ebp) diff -u --recursive --new-file v2.1.2/linux/arch/i386/math-emu/fpu_proto.h linux/arch/i386/math-emu/fpu_proto.h --- v2.1.2/linux/arch/i386/math-emu/fpu_proto.h Mon Aug 1 08:19:13 1994 +++ linux/arch/i386/math-emu/fpu_proto.h Thu Oct 10 16:01:12 1996 @@ -7,7 +7,7 @@ extern void stack_underflow_i(int i); extern void stack_underflow_pop(int i); extern int set_precision_flag(int flags); -asmlinkage void exception(int n); +asmlinkage void FPU_exception(int n); asmlinkage int real_2op_NaN(FPU_REG const *a, FPU_REG const *b, FPU_REG *dest); asmlinkage int arith_invalid(FPU_REG *dest); asmlinkage int divide_by_zero(int sign, FPU_REG *dest); diff -u --recursive --new-file v2.1.2/linux/arch/i386/math-emu/reg_norm.S linux/arch/i386/math-emu/reg_norm.S --- v2.1.2/linux/arch/i386/math-emu/reg_norm.S Thu Oct 5 15:30:43 1995 +++ linux/arch/i386/math-emu/reg_norm.S Thu Oct 10 16:01:12 1996 @@ -30,7 +30,7 @@ je L_ok pushl $0x220 - call SYMBOL_NAME(exception) + call SYMBOL_NAME(FPU_exception) addl $4,%esp L_ok: @@ -107,7 +107,7 @@ je L_ok_nuo pushl $0x221 - call SYMBOL_NAME(exception) + call SYMBOL_NAME(FPU_exception) addl $4,%esp L_ok_nuo: diff -u --recursive --new-file v2.1.2/linux/arch/i386/math-emu/reg_round.S linux/arch/i386/math-emu/reg_round.S --- v2.1.2/linux/arch/i386/math-emu/reg_round.S Thu Oct 5 15:30:43 1995 +++ linux/arch/i386/math-emu/reg_round.S Thu Oct 10 16:01:12 1996 @@ -596,7 +596,7 @@ /* There must be a masked underflow */ push %eax pushl EX_Underflow - call SYMBOL_NAME(exception) + call SYMBOL_NAME(FPU_exception) popl %eax popl %eax jmp xL_Normalised @@ -613,7 +613,7 @@ push %eax pushl EX_Underflow - call SYMBOL_NAME(exception) + call SYMBOL_NAME(FPU_exception) popl %eax popl %eax diff -u --recursive --new-file v2.1.2/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c --- v2.1.2/linux/arch/i386/mm/fault.c Wed Oct 9 08:55:17 1996 +++ linux/arch/i386/mm/fault.c Thu Oct 10 17:09:51 1996 @@ -22,6 +22,57 @@ extern void die_if_kernel(const char *,struct pt_regs *,long); /* + * Ugly, ugly, but the goto's result in better assembly.. + */ +int __verify_write(const void * addr, unsigned long size) +{ + struct vm_area_struct * vma; + unsigned long start = (unsigned long) addr; + + if (!size) + return 0; + + vma = find_vma(current->mm, start); + if (!vma) + goto bad_area; + if (vma->vm_start > start) + goto check_stack; + +good_area: + if (!(vma->vm_flags & VM_WRITE)) + goto bad_area; + size--; + size += start & ~PAGE_MASK; + size >>= PAGE_SHIFT; + start &= PAGE_MASK; + + for (;;) { + do_wp_page(current, vma, start, 1); + if (!size) + break; + size--; + start += PAGE_SIZE; + if (start < vma->vm_end) + continue; + vma = vma->vm_next; + if (!vma || vma->vm_start != start) + goto bad_area; + if (!(vma->vm_flags & VM_WRITE)) + goto bad_area;; + } + return 0; + +check_stack: + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto bad_area; + if (expand_stack(vma, start) == 0) + goto good_area; + +bad_area: + return -EFAULT; +} + +/* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate * routines. diff -u --recursive --new-file v2.1.2/linux/drivers/block/md.c linux/drivers/block/md.c --- v2.1.2/linux/drivers/block/md.c Sun Jun 30 00:04:00 1996 +++ linux/drivers/block/md.c Wed Oct 9 20:11:11 1996 @@ -439,6 +439,10 @@ #include }; +static struct proc_dir_entry proc_md = { + PROC_MD, 6, "mdstat", + S_IFREG | S_IRUGO, 1, 0, 0, +}; static void md_geninit (struct gendisk *gdisk) { @@ -455,12 +459,7 @@ blksize_size[MAJOR_NR] = md_blocksizes; register_symtab (&md_symbol_table); - proc_register(&proc_root, - &(struct proc_dir_entry) - { - PROC_MD, 6, "mdstat", - S_IFREG | S_IRUGO, 1, 0, 0, - }); + proc_register(&proc_root, &proc_md); } diff -u --recursive --new-file v2.1.2/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v2.1.2/linux/drivers/char/misc.c Thu Aug 22 18:45:56 1996 +++ linux/drivers/char/misc.c Wed Oct 9 20:11:11 1996 @@ -184,16 +184,18 @@ #include }; +static struct proc_dir_entry proc_misc = { + 0, 4, "misc", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, NULL /* ops -- default to array */, + &proc_misc_read /* get_info */, +}; + int misc_init(void) { #ifndef MODULE #ifdef CONFIG_PROC_FS - proc_register_dynamic(&proc_root, &(struct proc_dir_entry) { - 0, 4, "misc", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, NULL /* ops -- default to array */, - &proc_misc_read /* get_info */, - }); + proc_register_dynamic(&proc_root, &proc_misc); #endif /* PROC_FS */ #ifdef CONFIG_BUSMOUSE bus_mouse_init(); diff -u --recursive --new-file v2.1.2/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.1.2/linux/drivers/char/tpqic02.c Mon Sep 30 10:38:10 1996 +++ linux/drivers/char/tpqic02.c Thu Oct 10 08:14:23 1996 @@ -471,12 +471,12 @@ } /* ifc_init */ -static void report_exception(unsigned n) +static void report_qic_exception(unsigned n) { - if (n >= NR_OF_EXC) { tpqputs(TPQD_ALWAYS, "Oops -- report_exception"); n = 0; } + if (n >= NR_OF_EXC) { tpqputs(TPQD_ALWAYS, "Oops -- report_qic_exception"); n = 0; } if (TPQDBG(SENSE_TEXT) || n==0) printk(TPQIC02_NAME ": sense: %s\n", exception_list[n].msg); -} /* report_exception */ +} /* report_qic_exception */ /* Try to map the drive-exception bits `s' to a predefined "exception number", @@ -484,7 +484,7 @@ * exception table (`exception_list[]'). * It is assumed that s!=0. */ -static int decode_exception_nr(unsigned s) +static int decode_qic_exception_nr(unsigned s) { int i; @@ -492,9 +492,9 @@ if ((s & exception_list[i].mask)==exception_list[i].code) return i; } - printk(TPQIC02_NAME ": decode_exception_nr: exception(%x) not recognized\n", s); + printk(TPQIC02_NAME ": decode_qic_exception_nr: exception(%x) not recognized\n", s); return 0; -} /* decode_exception_nr */ +} /* decode_qic_exception_nr */ #ifdef OBSOLETE @@ -576,7 +576,7 @@ /* Perform appropriate action for certain exceptions. * should return a value to indicate stop/continue (in case of bad blocks) */ -static void handle_exception(int exnr, int exbits) +static void handle_qic_exception(int exnr, int exbits) { if (exnr==EXC_NCART) { /* Cartridge was changed. Redo sense(). @@ -600,7 +600,7 @@ doing_read = NO; } else if (exnr==EXC_FM) doing_read = NO; -} /* handle_exception */ +} /* handle_qic_exception */ static inline int is_exception(void) @@ -1035,9 +1035,9 @@ if (err & (TP_ST0|TP_ST1)) { /* My Wangtek occasionally reports `status' 1212 which should be ignored. */ - exnr = decode_exception_nr(err); - handle_exception(exnr, err); /* update driver state wrt drive status */ - report_exception(exnr); + exnr = decode_qic_exception_nr(err); + handle_qic_exception(exnr, err); /* update driver state wrt drive status */ + report_qic_exception(exnr); } err &= ~ignore; /* mask unwanted errors -- not the correct way, use exception nrs?? */ if (((err & TP_ST0) && (err & REPORT_ERR0)) || diff -u --recursive --new-file v2.1.2/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.2/linux/drivers/net/Config.in Mon May 20 08:08:36 1996 +++ linux/drivers/net/Config.in Wed Oct 9 09:57:20 1996 @@ -82,10 +82,8 @@ tristate 'ICL EtherTeam 16i/32 support' CONFIG_ETH16I fi tristate 'NE2000/NE1000 support' CONFIG_NE2000 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'NI5210 support' CONFIG_NI52 - bool 'NI6510 support' CONFIG_NI65 - fi + tristate 'NI5210 support' CONFIG_NI52 + tristate 'NI6510 support' CONFIG_NI65 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005 fi diff -u --recursive --new-file v2.1.2/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.1.2/linux/drivers/net/Makefile Mon May 6 12:44:31 1996 +++ linux/drivers/net/Makefile Wed Oct 9 09:57:20 1996 @@ -360,6 +360,10 @@ ifeq ($(CONFIG_NI65),y) L_OBJS += ni65.o +else + ifeq ($(CONFIG_NI65),m) + M_OBJS += ni65.o + endif endif ifeq ($(CONFIG_ELPLUS),y) diff -u --recursive --new-file v2.1.2/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.1.2/linux/drivers/net/Space.c Mon Jun 3 12:42:41 1996 +++ linux/drivers/net/Space.c Wed Oct 9 09:57:20 1996 @@ -195,6 +195,9 @@ #ifdef CONFIG_NI52 && ni52_probe(dev) #endif +#ifdef CONFIG_NI65 + && ni65_probe(dev) +#endif #ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */ && atarilance_probe(dev) #endif diff -u --recursive --new-file v2.1.2/linux/drivers/net/ni52.c linux/drivers/net/ni52.c --- v2.1.2/linux/drivers/net/ni52.c Fri Apr 12 09:49:38 1996 +++ linux/drivers/net/ni52.c Wed Oct 9 09:57:20 1996 @@ -4,13 +4,15 @@ * This is an extension to the Linux operating system, and is covered by the * same Gnu Public License that covers that work. * - * Alphacode 0.80 (96/02/19) for Linux 1.3.66 (or later) + * Alphacode 0.82 (96/09/29) for Linux 2.0.0 (or later) * Copyrights (c) 1994,1995,1996 by M.Hipp (Michael.Hipp@student.uni-tuebingen.de) * [feel free to mail ....] * * when using as module: (no autoprobing!) - * compile with: gcc -D__KERNEL__ -DMODULE -O2 -c ni52.c - * run with e.g: insmod ni52.o io=0x360 irq=9 memstart=0xd0000 memend=0xd4000 + * compile with: + * gcc -O2 -fomit-frame-pointer -m486 -D__KERNEL__ -DMODULE -c ni52.c + * run with e.g: + * insmod ni52.o io=0x360 irq=9 memstart=0xd0000 memend=0xd4000 * * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!. * @@ -62,6 +64,7 @@ */ /* + * 29.Sept.96: virt_to_bus changes for new memory scheme * 19.Feb.96: more Mcast changes, module support (MH) * * 18.Nov.95: Mcast changes (AC). @@ -129,8 +132,8 @@ #define ni_enaint() {outb(0,dev->base_addr+NI52_INTENA);} #define make32(ptr16) (p->memtop + (short) (ptr16) ) -#define make24(ptr32) ((char *) (ptr32) - p->base) -#define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop )) +#define make24(ptr32) ( ((char *) (ptr32)) - p->base) +#define make16(ptr32) ((unsigned short) ((unsigned long)(ptr32) - (unsigned long) p->memtop )) /******************* how to calculate the buffers ***************************** @@ -285,8 +288,8 @@ char *iscp_addrs[2]; int i; - p->base = (unsigned long) where + size - 0x01000000; - p->memtop = where + size; + p->base = (unsigned long) bus_to_virt((unsigned long)where) + size - 0x01000000; + p->memtop = bus_to_virt((unsigned long)where) + size; p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS); memset((char *)p->scp,0, sizeof(struct scp_struct)); for(i=0;iscp->sysbus != SYSBUSVAL) return 0; - iscp_addrs[0] = where; + iscp_addrs[0] = bus_to_virt((unsigned long)where); iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct); for(i=0;i<2;i++) @@ -328,7 +331,7 @@ DELAY(1); p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS); - p->scb = (struct scb_struct *) (dev->mem_start); + p->scb = (struct scb_struct *) bus_to_virt(dev->mem_start); p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct)); memset((char *) p->iscp,0,sizeof(struct iscp_struct)); @@ -479,8 +482,8 @@ /* warning: we don't free it on errors */ memset((char *) dev->priv,0,sizeof(struct priv)); - ((struct priv *) (dev->priv))->memtop = (char *) dev->mem_start + size; - ((struct priv *) (dev->priv))->base = dev->mem_start + size - 0x01000000; + ((struct priv *) (dev->priv))->memtop = bus_to_virt(dev->mem_start) + size; + ((struct priv *) (dev->priv))->base = (unsigned long) bus_to_virt(dev->mem_start) + size - 0x01000000; alloc586(dev); /* set number of receive-buffs according to memsize */ diff -u --recursive --new-file v2.1.2/linux/drivers/net/ni65.c linux/drivers/net/ni65.c --- v2.1.2/linux/drivers/net/ni65.c Fri Apr 12 09:49:38 1996 +++ linux/drivers/net/ni65.c Wed Oct 9 09:57:20 1996 @@ -1,8 +1,15 @@ /* - * ni6510 (am7990 'lance' chip) driver for Linux-net-3 by MH - * Alphacode v0.51 (96/02/20) for 1.3.66 (or later) + * ni6510 (am7990 'lance' chip) driver for Linux-net-3 + * BETAcode v0.71 (96/09/29) for 2.0.0 (or later) + * copyrights (c) 1994,1995,1996 by M.Hipp + * + * This driver can handle the old ni6510 board and the newer ni6510 + * EtherBlaster. (probably it also works with every full NE2100 + * compatible card) * - * copyright (c) 1994,1995,1996 by M.Hipp + * To compile as module, type: + * gcc -O2 -fomit-frame-pointer -m486 -D__KERNEL__ -DMODULE -c ni65.c + * driver probes: io: 0x360,0x300,0x320,0x340 / dma: 3,5,6,7 * * This is an extension to the Linux operating system, and is covered by the * same Gnu Public License that covers the Linux-kernel. @@ -16,27 +23,41 @@ * and from the original drivers by D.Becker * * known problems: - * on some PCI boards (including my own) the card/board/ISA-bridge has - * problems with bus master DMA. This results in lotsa overruns. - * It may help to '#define RCV_PARANOIA_CHECK' - * or just play with your BIOS options to optimize ISA-DMA access. + * - on some PCI boards (including my own) the card/board/ISA-bridge has + * problems with bus master DMA. This results in lotsa overruns. + * It may help to '#define RCV_PARANOIA_CHECK' or try to #undef + * the XMT and RCV_VIA_SKB option .. this reduces driver performance. + * Or just play with your BIOS options to optimize ISA-DMA access. + * Maybe you also wanna play with the LOW_PERFORAMCE and MID_PERFORMANCE + * defines -> please report me your experience then + * - Harald reported for ASUS SP3G mainboards, that you should use + * the 'optimal settings' from the user's manual on page 3-12! * * credits: * thanx to Jason Sullivan for sending me a ni6510 card! + * lot of debug runs with ASUS SP3G Boards (Intel Saturn) by Harald Koenig * - * simple performance test: - * 8.1 seconds for getting a 8MB file via FTP -> near 1MB/s + * simple performance test: (486DX-33/Ni6510-EB receives from 486DX4-100/Ni6510-EB) + * average: FTP -> 8384421 bytes received in 8.5 seconds + * (no RCV_VIA_SKB,no XMT_VIA_SKB,PARANOIA_CHECK,4 XMIT BUFS, 8 RCV_BUFFS) + * peak: FTP -> 8384421 bytes received in 7.5 seconds + * (RCV_VIA_SKB,XMT_VIA_SKB,no PARANOIA_CHECK,1(!) XMIT BUF, 16 RCV BUFFS) */ /* - * 96.Feb.19: fixed a few bugs .. cleanups .. tested for 1.3.66 + * 96.Sept.29: virt_to_bus stuff added for new memory modell + * 96.April.29: Added Harald Koenig's Patches (MH) + * 96.April.13: enhanced error handling .. more tests (MH) + * 96.April.5/6: a lot of performance tests. Got it stable now (hopefully) (MH) + * 96.April.1: (no joke ;) .. added EtherBlaster and Module support (MH) + * 96.Feb.19: fixed a few bugs .. cleanups .. tested for 1.3.66 (MH) * hopefully no more 16MB limit * * 95.Nov.18: multicast tweaked (AC). * * 94.Aug.22: changes in xmit_intr (ack more than one xmitted-packet), ni65_send_packet (p->lock) (MH) * - * 94,July.16: fixed bugs in recv_skb and skb-alloc stuff (MH) + * 94.July.16: fixed bugs in recv_skb and skb-alloc stuff (MH) */ #include @@ -56,75 +77,121 @@ #include #include +#include +#include + #include "ni65.h" /* - * the current setting allows max. performance + * the current setting allows an acceptable performance * for 'RCV_PARANOIA_CHECK' read the 'known problems' part in * the header of this file + * 'invert' the defines for max. performance. This may cause DMA problems + * on some boards (e.g on my ASUS SP3G) */ -#define RCV_VIA_SKB -#undef RCV_PARANOIA_CHECK -#define XMT_VIA_SKB +#undef XMT_VIA_SKB +#undef RCV_VIA_SKB +#define RCV_PARANOIA_CHECK + +#define MID_PERFORMANCE + +#if defined( LOW_PERFORMANCE ) + static int isa0=7,isa1=7,csr80=0x0c10; +#elif defined( MID_PERFORMANCE ) + static int isa0=5,isa1=5,csr80=0x2810; +#else /* high performance */ + static int isa0=4,isa1=4,csr80=0x0017; +#endif /* - * a few card specific defines + * a few card/vendor specific defines */ -#define NI65_TOTAL_SIZE 16 -#define NI65_ADDR0 0x02 -#define NI65_ADDR1 0x07 -#define NI65_ADDR2 0x01 -#define NI65_ID0 0x00 -#define NI65_ID1 0x55 +#define NI65_ID0 0x00 +#define NI65_ID1 0x55 +#define NI65_EB_ID0 0x52 +#define NI65_EB_ID1 0x44 +#define NE2100_ID0 0x57 +#define NE2100_ID1 0x57 -#define PORT dev->base_addr +#define PORT p->cmdr_addr /* * buffer configuration */ +#if 1 +#define RMDNUM 16 +#define RMDNUMMASK 0x80000000 +#else #define RMDNUM 8 #define RMDNUMMASK 0x60000000 /* log2(RMDNUM)<<29 */ +#endif + +#if 0 +#define TMDNUM 1 +#define TMDNUMMASK 0x00000000 +#else #define TMDNUM 4 #define TMDNUMMASK 0x40000000 /* log2(TMDNUM)<<29 */ +#endif -#define R_BUF_SIZE 1536 -#define T_BUF_SIZE 1536 +/* slightly oversized */ +#define R_BUF_SIZE 1544 +#define T_BUF_SIZE 1544 /* * lance register defines */ #define L_DATAREG 0x00 #define L_ADDRREG 0x02 - #define L_RESET 0x04 #define L_CONFIG 0x05 -#define L_EBASE 0x08 +#define L_BUSIF 0x06 /* - * to access the am7990-regs, you have to write + * to access the lance/am7990-regs, you have to write * reg-number into L_ADDRREG, then you can access it using L_DATAREG */ -#define CSR0 0x00 -#define CSR1 0x01 -#define CSR2 0x02 -#define CSR3 0x03 +#define CSR0 0x00 +#define CSR1 0x01 +#define CSR2 0x02 +#define CSR3 0x03 + +#define INIT_RING_BEFORE_START 0x1 +#define FULL_RESET_ON_ERROR 0x2 +#if 0 #define writereg(val,reg) {outw(reg,PORT+L_ADDRREG);inw(PORT+L_ADDRREG); \ outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);} #define readreg(reg) (outw(reg,PORT+L_ADDRREG),inw(PORT+L_ADDRREG),\ inw(PORT+L_DATAREG)) +#if 0 #define writedatareg(val) {outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);} +#else +#define writedatareg(val) { writereg(val,CSR0); } +#endif +#else +#define writereg(val,reg) {outw(reg,PORT+L_ADDRREG);outw(val,PORT+L_DATAREG);} +#define readreg(reg) (outw(reg,PORT+L_ADDRREG),inw(PORT+L_DATAREG)) +#define writedatareg(val) { writereg(val,CSR0); } +#endif -static int ni65_probe1(struct device **dev,int); -static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs); -static void ni65_recv_intr(struct device *dev,int); -static void ni65_xmit_intr(struct device *dev,int); -static int ni65_open(struct device *dev); -static int ni65_am7990_reinit(struct device *dev); -static int ni65_send_packet(struct sk_buff *skb, struct device *dev); -static int ni65_close(struct device *dev); -static struct enet_statistics *ni65_get_stats(struct device *); -static void set_multicast_list(struct device *dev); +static unsigned char ni_vendor[] = { 0x02,0x07,0x01 }; + +static struct card { + unsigned char id0,id1; + short id_offset; + short total_size; + short cmd_offset; + short addr_offset; + unsigned char *vendor_id; + char *cardname; + unsigned char config; +} cards[] = { + { NI65_ID0,NI65_ID1,0x0e,0x10,0x0,0x8,ni_vendor,"ni6510", 0x1 } , + { NI65_EB_ID0,NI65_EB_ID1,0x0e,0x18,0x10,0x0,ni_vendor,"ni6510 EtherBlaster", 0x2 } , + { NE2100_ID0,NE2100_ID1,0x0e,0x18,0x10,0x0,NULL,"generic NE2100", 0x0 } +}; +#define NUM_CARDS 3 struct priv { @@ -142,132 +209,267 @@ struct sk_buff *tmd_skb[TMDNUM]; #endif void *tmdbounce[TMDNUM]; + int tmdbouncenum; int lock,xmit_queued; struct enet_statistics stats; + void *self; + int cmdr_addr; + int cardno; + int features; }; +static int ni65_probe1(struct device *dev,int); +static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs); +static void ni65_recv_intr(struct device *dev,int); +static void ni65_xmit_intr(struct device *dev,int); +static int ni65_open(struct device *dev); +static int ni65_lance_reinit(struct device *dev); +static void ni65_init_lance(struct priv *p,unsigned char*,int,int); +static int ni65_send_packet(struct sk_buff *skb, struct device *dev); +static int ni65_close(struct device *dev); +static int ni65_alloc_buffer(struct device *dev); +static void ni65_free_buffer(struct priv *p); +static struct enet_statistics *ni65_get_stats(struct device *); +static void set_multicast_list(struct device *dev); + static int irqtab[] = { 9,12,15,5 }; /* irq config-translate */ -static int dmatab[] = { 0,3,5,6 }; /* dma config-translate */ -static int debuglevel = 0; +static int dmatab[] = { 0,3,5,6,7 }; /* dma config-translate and autodetect */ + +static int debuglevel = 1; /* - * open (most done by init) + * set 'performance' registers .. we must STOP lance for that + */ +static void ni65_set_performance(struct priv *p) +{ + writereg(CSR0_STOP | CSR0_CLRALL,CSR0); /* STOP */ + + if( !(cards[p->cardno].config & 0x02) ) + return; + + outw(80,PORT+L_ADDRREG); + if(inw(PORT+L_ADDRREG) != 80) + return; + + writereg( (csr80 & 0x3fff) ,80); /* FIFO watermarks */ + outw(0,PORT+L_ADDRREG); + outw((short)isa0,PORT+L_BUSIF); /* write ISA 0: DMA_R : isa0 * 50ns */ + outw(1,PORT+L_ADDRREG); + outw((short)isa1,PORT+L_BUSIF); /* write ISA 1: DMA_W : isa1 * 50ns */ + + outw(CSR0,PORT+L_ADDRREG); /* switch back to CSR0 */ +} + +/* + * open interface (up) */ static int ni65_open(struct device *dev) { - if(ni65_am7990_reinit(dev)) + struct priv *p = (struct priv *) dev->priv; + int irqval = request_irq(dev->irq, &ni65_interrupt,0, + cards[p->cardno].cardname,NULL); + if (irqval) { + printk ("%s: unable to get IRQ %d (irqval=%d).\n", + dev->name,dev->irq, irqval); + return -EAGAIN; + } + irq2dev_map[dev->irq] = dev; + + if(ni65_lance_reinit(dev)) { dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; + MOD_INC_USE_COUNT; return 0; } else { + irq2dev_map[dev->irq] = NULL; + free_irq(dev->irq,NULL); dev->start = 0; return -EAGAIN; } } +/* + * close interface (down) + */ static int ni65_close(struct device *dev) { - outw(0,PORT+L_RESET); /* that's the hard way */ + struct priv *p = (struct priv *) dev->priv; + + outw(inw(PORT+L_RESET),PORT+L_RESET); /* that's the hard way */ + +#ifdef XMT_VIA_SKB + { + int i; + for(i=0;itmd_skb[i]) { + dev_kfree_skb(p->tmd_skb[i],FREE_WRITE); + p->tmd_skb[i] = NULL; + } + } + } +#endif + irq2dev_map[dev->irq] = NULL; + free_irq(dev->irq,NULL); dev->tbusy = 1; dev->start = 0; + MOD_DEC_USE_COUNT; return 0; } /* * Probe The Card (not the lance-chip) - * and set hardaddress */ +#ifdef MODULE +static +#endif int ni65_probe(struct device *dev) { int *port; - static int ports[] = {0x300,0x320,0x340,0x360, 0}; + static int ports[] = {0x360,0x300,0x320,0x340, 0}; - if(dev) { - int base_addr = dev->base_addr; - if (base_addr > 0x1ff) /* Check a single specified location. */ - return ni65_probe1(&dev, base_addr); - else if (base_addr > 0) /* Don't probe at all. */ - return -ENXIO; - dev->base_addr = base_addr; - } + if (dev->base_addr > 0x1ff) /* Check a single specified location. */ + return ni65_probe1(dev, dev->base_addr); + else if (dev->base_addr > 0) /* Don't probe at all. */ + return -ENXIO; for (port = ports; *port; port++) { - int ioaddr = *port; - - if (check_region(ioaddr, NI65_TOTAL_SIZE)) - continue; - if( !(inb(ioaddr+L_EBASE+6) == NI65_ID0) || - !(inb(ioaddr+L_EBASE+7) == NI65_ID1) ) - continue; - if (ni65_probe1(&dev, ioaddr) == 0) + if (ni65_probe1(dev, *port) == 0) return 0; } return -ENODEV; } -int ni65_init(void) -{ - ni65_probe(NULL); - return 0; -} - -static int ni65_probe1(struct device **dev1,int ioaddr) +/* + * this is the real card probe .. + */ +static int ni65_probe1(struct device *dev,int ioaddr) { - int i; - unsigned char *ptr; + int i,j; struct priv *p; - struct device *dev = *dev1; - if(inb(ioaddr+L_EBASE+0) != NI65_ADDR0 || inb(ioaddr+L_EBASE+1) != NI65_ADDR1 - || inb(ioaddr+L_EBASE+2) != NI65_ADDR2) - { - printk("%s: wrong Hardaddress \n",dev ? dev->name : "ni6510" ); - return -ENODEV; - } - - if(!dev) { - dev = init_etherdev(0,0); - *dev1 = dev; + for(i=0;i= 0) { + if(inb(ioaddr+cards[i].id_offset+0) != cards[i].id0 || + inb(ioaddr+cards[i].id_offset+1) != cards[i].id1) { + continue; + } + } + if(cards[i].vendor_id) { + for(j=0;j<3;j++) + if(inb(ioaddr+cards[i].addr_offset+j) != cards[i].vendor_id[j]) + continue; + } + break; } - dev->base_addr = ioaddr; + if(i == NUM_CARDS) + return -ENODEV; - for(i=0;i<6;i++) - dev->dev_addr[i] = inb(PORT+L_EBASE+i); + for(j=0;j<6;j++) + dev->dev_addr[j] = inb(ioaddr+cards[i].addr_offset+j); - if(dev->irq == 0) - dev->irq = irqtab[(inw(PORT+L_CONFIG)>>2)&3]; - if(dev->dma == 0) - dev->dma = dmatab[inw(PORT+L_CONFIG)&3]; - - printk("%s: %s found at %#3lx, IRQ %d DMA %d.\n", dev->name, - "ni6510", dev->base_addr, dev->irq,dev->dma); - - { - int irqval = request_irq(dev->irq, &ni65_interrupt,0,"ni6510",NULL); - if (irqval) { - printk ("%s: unable to get IRQ %d (irqval=%d).\n", - dev->name,dev->irq, irqval); - return -EAGAIN; + if( (j=ni65_alloc_buffer(dev)) < 0) + return j; + p = (struct priv *) dev->priv; + p->cmdr_addr = ioaddr + cards[i].cmd_offset; + p->cardno = i; + + printk("%s: %s found at %#3x, ", dev->name, cards[p->cardno].cardname , ioaddr); + + outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */ + if( (j=readreg(CSR0)) != 0x4) { + printk(KERN_ERR "can't RESET card: %04x\n",j); + ni65_free_buffer(p); + return -EAGAIN; + } + + outw(88,PORT+L_ADDRREG); + if(inw(PORT+L_ADDRREG) == 88) { + unsigned long v; + v = inw(PORT+L_DATAREG); + v <<= 16; + outw(89,PORT+L_ADDRREG); + v |= inw(PORT+L_DATAREG); + printk("Version %#08lx, ",v); + p->features = INIT_RING_BEFORE_START; + } + else { + printk("ancient LANCE, "); + p->features = 0x0; + } + + if(test_bit(0,&cards[i].config)) { + dev->irq = irqtab[(inw(ioaddr+L_CONFIG)>>2)&3]; + dev->dma = dmatab[inw(ioaddr+L_CONFIG)&3]; + printk("IRQ %d (from card), DMA %d (from card).\n",dev->irq,dev->dma); + } + else { + if(dev->dma == 0) { + /* 'stuck test' from lance.c */ + int dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) | (inb(DMA2_STAT_REG) & 0xf0); + for(i=1;i<5;i++) { + int dma = dmatab[i]; + if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510")) + continue; + disable_dma(dma); + set_dma_mode(dma,DMA_MODE_CASCADE); + enable_dma(dma); + ni65_init_lance(p,dev->dev_addr,0,0); /* trigger memory access */ + disable_dma(dma); + free_dma(dma); + if(readreg(CSR0) & CSR0_IDON) + break; + } + if(i == 5) { + printk("Can't detect DMA channel!\n"); + ni65_free_buffer(p); + return -EAGAIN; + } + dev->dma = dmatab[i]; + printk("DMA %d (autodetected), ",dev->dma); } - if(request_dma(dev->dma, "ni6510") != 0) + else + printk("DMA %d (assigned), ",dev->dma); + + if(dev->irq < 2) { - printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma); - free_irq(dev->irq,NULL); - return -EAGAIN; + ni65_init_lance(p,dev->dev_addr,0,0); + autoirq_setup(0); + writereg(CSR0_INIT|CSR0_INEA,CSR0); /* trigger interrupt */ + + if(!(dev->irq = autoirq_report(2))) + { + printk("Failed to detect IRQ line!\n"); + ni65_free_buffer(p); + return -EAGAIN; + } + printk("IRQ %d (autodetected).\n",dev->irq); } + else + printk("IRQ %d (assigned).\n",dev->irq); + } + + if(request_dma(dev->dma, cards[p->cardno].cardname ) != 0) + { + printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma); + ni65_free_buffer(p); + return -EAGAIN; } - irq2dev_map[dev->irq] = dev; /* - * Grab the region so we can find another board if autoIRQ fails. + * Grab the region so we can find another board. */ - request_region(ioaddr,NI65_TOTAL_SIZE,"ni6510"); + request_region(ioaddr,cards[p->cardno].total_size,cards[p->cardno].cardname); + + dev->base_addr = ioaddr; dev->open = ni65_open; dev->stop = ni65_close; @@ -281,75 +483,240 @@ dev->tbusy = 0; dev->start = 0; + return 0; /* everything is OK */ +} + +/* + * set lance register and trigger init + */ +static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int mode) +{ + int i; + u32 pib; + + writereg(CSR0_CLRALL|CSR0_STOP,CSR0); + + for(i=0;i<6;i++) + p->ib.eaddr[i] = daddr[i]; + + for(i=0;i<8;i++) + p->ib.filter[i] = filter; + p->ib.mode = mode; + + p->ib.trp = (u32) virt_to_bus(p->tmdhead) | TMDNUMMASK; + p->ib.rrp = (u32) virt_to_bus(p->rmdhead) | RMDNUMMASK; + writereg(0,CSR3); /* busmaster/no word-swap */ + pib = (u32) virt_to_bus(&p->ib); + writereg(pib & 0xffff,CSR1); + writereg(pib >> 16,CSR2); + + writereg(CSR0_INIT,CSR0); /* this changes L_ADDRREG to CSR0 */ + + for(i=0;i<32;i++) + { + udelay(4000); + if(inw(PORT+L_DATAREG) & (CSR0_IDON | CSR0_MERR) ) + break; /* init ok ? */ + } +} + +/* + * allocate memory area and check the 16MB border + */ +static void *ni65_alloc_mem(struct device *dev,char *what,int size,int type) +{ + struct sk_buff *skb=NULL; + unsigned char *ptr; + void *ret; + + if(type) { + ret = skb = alloc_skb(2+16+size,GFP_KERNEL|GFP_DMA); + if(!skb) { + printk("%s: unable to allocate %s memory.\n",dev->name,what); + return NULL; + } + skb->dev = dev; + skb_reserve(skb,2+16); + skb_put(skb,R_BUF_SIZE); /* grab the whole space .. (not necessary) */ + ptr = skb->data; + } + else { + ret = ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA); + if(!ret) { + printk("%s: unable to allocate %s memory.\n",dev->name,what); + return NULL; + } + } + if( (u32) virt_to_bus(ptr+size) > 0x1000000) { + printk("%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what); + if(type) + kfree_skb(skb,FREE_WRITE); + else + kfree(ptr); + return NULL; + } + return ret; +} + +/* + * allocate all memory structures .. send/recv buffers etc ... + */ +static int ni65_alloc_buffer(struct device *dev) +{ + unsigned char *ptr; + struct priv *p; + int i; + /* * we need 8-aligned memory .. */ - ptr = kmalloc(sizeof(struct priv)+8,GFP_KERNEL|GFP_DMA); + ptr = ni65_alloc_mem(dev,"BUFFER",sizeof(struct priv)+8,0); if(!ptr) return -ENOMEM; - ptr = (unsigned char *) (((unsigned long) ptr + 7) & ~0x7); - if( (unsigned long) ptr + sizeof(struct priv) > 0x1000000) { - printk("%s: Can't alloc buffer in lower 16MB!\n",dev->name); - return -EAGAIN; - } - p = dev->priv = (struct priv *) ptr; + + p = dev->priv = (struct priv *) (((unsigned long) ptr + 7) & ~0x7); memset((char *) dev->priv,0,sizeof(struct priv)); + p->self = ptr; for(i=0;iname); +#ifdef XMT_VIA_SKB + p->tmd_skb[i] = NULL; +#endif + p->tmdbounce[i] = ni65_alloc_mem(dev,"XMIT",T_BUF_SIZE,0); + if(!p->tmdbounce[i]) { + ni65_free_buffer(p); + return -ENOMEM; + } + } + + for(i=0;irecv_skb[i] = ni65_alloc_mem(dev,"RECV",R_BUF_SIZE,1); + if(!p->recv_skb[i]) { + ni65_free_buffer(p); return -ENOMEM; } - if( (unsigned long) (ptr+T_BUF_SIZE) > 0x1000000) { - printk("%s: Can't alloc Xmit-Mem in lower 16MB!\n",dev->name); - return -EAGAIN; +#else + p->recvbounce[i] = ni65_alloc_mem(dev,"RECV",R_BUF_SIZE,0); + if(!p->recvbounce[i]) { + ni65_free_buffer(p); + return -ENOMEM; } - p->tmdbounce[i] = ptr; +#endif + } + + return 0; /* everything is OK */ +} + +/* + * free buffers and private struct + */ +static void ni65_free_buffer(struct priv *p) +{ + int i; + + if(!p) + return; + + for(i=0;itmdbounce[i]) + kfree(p->tmdbounce[i]); #ifdef XMT_VIA_SKB - p->tmd_skb[i] = NULL; + if(p->tmd_skb[i]) + dev_kfree_skb(p->tmd_skb[i],FREE_WRITE); #endif } + for(i=0;iname); - return -ENOMEM; - } - skb->dev = dev; - skb_reserve(skb,2); - skb_put(skb,R_BUF_SIZE); /* grab the whole space .. (not necessary) */ - if( (unsigned long) (skb->data + R_BUF_SIZE) > 0x1000000 ) { - printk("%s: unable to alloc receive-memory in lower 16MB!\n",dev->name); - return -EAGAIN; - } - p->recv_skb[i] = skb; - } + if(p->recv_skb[i]) + dev_kfree_skb(p->recv_skb[i],FREE_WRITE); #else - for(i=0;irecvbounce[i] = kmalloc(R_BUF_SIZE,GFP_KERNEL | GFP_DMA )) ) { - printk("%s: unable to alloc recv-mem\n",dev->name); - return -ENOMEM; - } - if( (unsigned long) p->recvbounce[i] + R_BUF_SIZE > 0x1000000 ) { - printk("%s: unable to alloc receive-memory in lower 16MB!\n",dev->name); - return -EAGAIN; - } - } + if(p->recvbounce[i]) + kfree(p->recvbounce[i]); +#endif + } + if(p->self) + kfree(p->self); +} + + +/* + * stop and (re)start lance .. e.g after an error + */ +static void ni65_stop_start(struct device *dev,struct priv *p) +{ + int csr0 = CSR0_INEA; + + writedatareg(CSR0_STOP); + + if(debuglevel > 1) + printk("ni65_stop_start\n"); + + if(p->features & INIT_RING_BEFORE_START) { + int i; +#ifdef XMT_VIA_SKB + struct sk_buff *skb_save[TMDNUM]; #endif + unsigned long buffer[TMDNUM]; + short blen[TMDNUM]; - return 0; /* we've found everything */ + if(p->xmit_queued) { + while(1) { + if((p->tmdhead[p->tmdlast].u.s.status & XMIT_OWN)) + break; + p->tmdlast = (p->tmdlast + 1) & (TMDNUM-1); + if(p->tmdlast == p->tmdnum) + break; + } + } + + for(i=0;itmdhead + i; +#ifdef XMT_VIA_SKB + skb_save[i] = p->tmd_skb[i]; +#endif + buffer[i] = (u32) bus_to_virt(tmdp->u.buffer); + blen[i] = tmdp->blen; + tmdp->u.s.status = 0x0; + } + + for(i=0;irmdhead + i; + rmdp->u.s.status = RCV_OWN; + } + p->tmdnum = p->xmit_queued = 0; + writedatareg(CSR0_STRT | csr0); + + for(i=0;itmdlast) & (TMDNUM-1); + p->tmdhead[i].u.buffer = (u32) virt_to_bus((char *)buffer[num]); /* status is part of buffer field */ + p->tmdhead[i].blen = blen[num]; + if(p->tmdhead[i].u.s.status & XMIT_OWN) { + p->tmdnum = (p->tmdnum + 1) & (TMDNUM-1); + p->xmit_queued = 1; + writedatareg(CSR0_TDMD | CSR0_INEA | csr0); + } +#ifdef XMT_VIA_SKB + p->tmd_skb[i] = skb_save[num]; +#endif + } + p->rmdnum = p->tmdlast = 0; + if(!p->lock) + dev->tbusy = (p->tmdnum || !p->xmit_queued) ? 0 : 1; + dev->trans_start = jiffies; + } + else + writedatareg(CSR0_STRT | csr0); } /* * init lance (write init-values .. init-buffers) (open-helper) */ - -static int ni65_am7990_reinit(struct device *dev) +static int ni65_lance_reinit(struct device *dev) { int i; struct priv *p = (struct priv *) dev->priv; @@ -361,17 +728,16 @@ set_dma_mode(dev->dma,DMA_MODE_CASCADE); enable_dma(dev->dma); - outw(0,PORT+L_RESET); /* first: reset the card */ - if(inw(PORT+L_DATAREG) != 0x4) + outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */ + if( (i=readreg(CSR0) ) != 0x4) { - printk(KERN_ERR "%s: can't RESET ni6510 card: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); + printk(KERN_ERR "%s: can't RESET %s card: %04x\n",dev->name, + cards[p->cardno].cardname,(int) i); disable_dma(dev->dma); - free_dma(dev->dma); - free_irq(dev->irq, NULL); return 0; } - p->tmdnum = 0; p->tmdlast = 0; + p->rmdnum = p->tmdnum = p->tmdlast = p->tmdbouncenum = 0; for(i=0;itmdhead + i; @@ -386,66 +752,40 @@ tmdp->blen = tmdp->status2 = 0; } - p->rmdnum = 0; for(i=0;irmdhead + i; #ifdef RCV_VIA_SKB - rmdp->u.buffer = (unsigned long) p->recv_skb[i]->data; + rmdp->u.buffer = (u32) virt_to_bus(p->recv_skb[i]->data); #else - rmdp->u.buffer = (unsigned long) p->recvbounce[i]; + rmdp->u.buffer = (u32) virt_to_bus(p->recvbounce[i]); #endif rmdp->blen = -(R_BUF_SIZE-8); rmdp->mlen = 0; rmdp->u.s.status = RCV_OWN; } - for(i=0;i<6;i++) - p->ib.eaddr[i] = dev->dev_addr[i]; - - for(i=0;i<8;i++) - p->ib.filter[i] = 0x0; - p->ib.mode = 0x0; - - if(dev->flags & IFF_PROMISC) { - p->ib.mode = M_PROM; - } - else if(dev->mc_count || dev->flags & IFF_ALLMULTI) { - for(i=0;i<8;i++) - p->ib.filter[i] = 0xff; - } - - p->ib.trp = (unsigned long) p->tmdhead | TMDNUMMASK; - p->ib.rrp = (unsigned long) p->rmdhead | RMDNUMMASK; - - writereg(0,CSR3); /* busmaster/no word-swap */ - writereg((unsigned short) (((unsigned long) &(p->ib)) & 0xffff),CSR1); - writereg((unsigned short) (((unsigned long) &(p->ib))>>16),CSR2); - - writereg(CSR0_INIT,CSR0); /* this changes L_ADDRREG to CSR0 */ + if(dev->flags & IFF_PROMISC) + ni65_init_lance(p,dev->dev_addr,0x00,M_PROM); + else if(dev->mc_count || dev->flags & IFF_ALLMULTI) + ni65_init_lance(p,dev->dev_addr,0xff,0x0); + else + ni65_init_lance(p,dev->dev_addr,0x00,0x00); /* + * ni65_set_lance_mem() sets L_ADDRREG to CSR0 * NOW, WE WILL NEVER CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED */ - for(i=0;i<32;i++) - { - __delay((loops_per_sec>>8)); /* wait a while */ - if(inw(PORT+L_DATAREG) & CSR0_IDON) - break; /* init ok ? */ - } - if(i == 32) - { - printk(KERN_ERR "%s: can't init am7990/lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); - disable_dma(dev->dma); - free_dma(dev->dma); - free_irq(dev->irq, NULL); - return 0; /* false */ - } - - writedatareg(CSR0_CLRALL | CSR0_INEA | CSR0_STRT); /* start lance , enable interrupts */ - - return 1; /* OK */ + if(inw(PORT+L_DATAREG) & CSR0_IDON) { + ni65_set_performance(p); + /* init OK: start lance , enable interrupts */ + writedatareg(CSR0_CLRALL | CSR0_INEA | CSR0_STRT); + return 1; /* ->OK */ + } + printk(KERN_ERR "%s: can't init lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); + disable_dma(dev->dma); + return 0; /* ->Error */ } /* @@ -455,6 +795,7 @@ { int csr0; struct device *dev = (struct device *) irq2dev_map[irq]; + struct priv *p; int bcnt = 32; if (dev == NULL) { @@ -462,62 +803,104 @@ return; } - dev->interrupt = 1; + if(set_bit(0,(int *) &dev->interrupt)) { + printk("ni65: oops .. interrupt while proceeding interrupt\n"); + return; + } + p = (struct priv *) dev->priv; while(--bcnt) { - csr0 = inw(PORT+L_DATAREG); - writedatareg(csr0 & CSR0_CLRALL); /* ack interrupts, disable int. */ + +#if 0 + writedatareg( (csr0 & CSR0_CLRALL) ); /* ack interrupts, disable int. */ +#else + writedatareg( (csr0 & CSR0_CLRALL) | CSR0_INEA ); /* ack interrupts, interrupts enabled */ +#endif if(!(csr0 & (CSR0_ERR | CSR0_RINT | CSR0_TINT))) break; + if(csr0 & CSR0_RINT) /* RECV-int? */ + ni65_recv_intr(dev,csr0); + if(csr0 & CSR0_TINT) /* XMIT-int? */ + ni65_xmit_intr(dev,csr0); + if(csr0 & CSR0_ERR) { struct priv *p = (struct priv *) dev->priv; - + if(debuglevel > 1) + printk("%s: general error: %04x.\n",dev->name,csr0); if(csr0 & CSR0_BABL) p->stats.tx_errors++; - if(csr0 & CSR0_MISS) + if(csr0 & CSR0_MISS) { + int i; + for(i=0;irmdhead[i].u.s.status); + printk("\n"); p->stats.rx_errors++; + } if(csr0 & CSR0_MERR) { - writedatareg(CSR0_STOP); - writedatareg(CSR0_STRT); + if(debuglevel > 1) + printk("%s: Ooops .. memory error: %04x.\n",dev->name,csr0); + ni65_stop_start(dev,p); } } - if(csr0 & CSR0_RINT) /* RECV-int? */ - ni65_recv_intr(dev,csr0); - if(csr0 & CSR0_TINT) /* XMIT-int? */ - ni65_xmit_intr(dev,csr0); } #ifdef RCV_PARANOIA_CHECK { + int j; + for(j=0;jpriv; - int i,f=0; - for(i=0;irmdhead + ((p->rmdnum - i - 1) & (RMDNUM-1)); - if(! (rmdp->u.s.status & RCV_OWN) ) - f = 1; - else if(f) + int i,k,num1,num2; + for(i=RMDNUM-1;i>0;i--) { + num2 = (p->rmdnum + i) & (RMDNUM-1); + if(!(p->rmdhead[num2].u.s.status & RCV_OWN)) break; } - if(i < RMDNUM) { - p->rmdnum = (p->rmdnum + 8 - i) & (RMDNUM - 1); - printk(KERN_ERR "%s: Ooops, receive ring corrupted\n",dev->name); + if(i) { + for(k=0;krmdnum + k) & (RMDNUM-1); + if(!(p->rmdhead[num1].u.s.status & RCV_OWN)) + break; + } + if(!k) + break; + + if(debuglevel > 0) + { + char buf[256],*buf1; + int k; + buf1 = buf; + for(k=0;krmdhead[k].u.s.status)); /* & RCV_OWN) ); */ + buf1 += 3; + } + *buf1 = 0; + printk(KERN_ERR "%s: Ooops, receive ring corrupted %2d %2d | %s\n",dev->name,p->rmdnum,i,buf); + } + p->rmdnum = num1; ni65_recv_intr(dev,csr0); + if((p->rmdhead[num2].u.s.status & RCV_OWN)) + break; /* ok, we are 'in sync' again */ } + else + break; + } } #endif - if(csr0 & (CSR0_RXON | CSR0_TXON) != (CSR0_RXON | CSR0_TXON) ) { - writedatareg(CSR0_STOP); - writedatareg(CSR0_STRT | CSR0_INEA); + if( (csr0 & (CSR0_RXON | CSR0_TXON)) != (CSR0_RXON | CSR0_TXON) ) { + printk("%s: RX or TX was offline -> restart\n",dev->name); + ni65_stop_start(dev,p); } else writedatareg(CSR0_INEA); + dev->interrupt = 0; return; @@ -539,13 +922,6 @@ if(tmdstat & XMIT_OWN) break; -#ifdef XMT_VIA_SKB - if(p->tmd_skb[p->tmdlast]) { - dev_kfree_skb(p->tmd_skb[p->tmdlast],FREE_WRITE); - p->tmd_skb[p->tmdlast] = NULL; - } -#endif - if(tmdstat & XMIT_ERR) { #if 0 @@ -558,20 +934,34 @@ if(tmdp->status2 & XMIT_LCAR) p->stats.tx_carrier_errors++; if(tmdp->status2 & (XMIT_BUFF | XMIT_UFLO )) { + /* this stops the xmitter */ p->stats.tx_fifo_errors++; - writedatareg(CSR0_STOP); - writedatareg(CSR0_STRT); - if(debuglevel > 1) + if(debuglevel > 0) printk(KERN_ERR "%s: Xmit FIFO/BUFF error\n",dev->name); + if(p->features & INIT_RING_BEFORE_START) { + tmdp->u.s.status = XMIT_OWN | XMIT_START | XMIT_END; /* test: resend this frame */ + ni65_stop_start(dev,p); + break; /* no more Xmit processing .. */ + } + else + ni65_stop_start(dev,p); } if(debuglevel > 2) printk(KERN_ERR "%s: xmit-error: %04x %02x-%04x\n",dev->name,csr0,(int) tmdstat,(int) tmdp->status2); - p->stats.tx_errors++; + if(!(csr0 & CSR0_BABL)) /* don't count errors twice */ + p->stats.tx_errors++; tmdp->status2 = 0; } else p->stats.tx_packets++; +#ifdef XMT_VIA_SKB + if(p->tmd_skb[p->tmdlast]) { + dev_kfree_skb(p->tmd_skb[p->tmdlast],FREE_WRITE); + p->tmd_skb[p->tmdlast] = NULL; + } +#endif + p->tmdlast = (p->tmdlast + 1) & (TMDNUM-1); if(p->tmdlast == p->tmdnum) p->xmit_queued = 0; @@ -583,16 +973,17 @@ /* * We have received a packet */ - static void ni65_recv_intr(struct device *dev,int csr0) { struct rmd *rmdp; int rmdstat,len; + int cnt=0; struct priv *p = (struct priv *) dev->priv; rmdp = p->rmdhead + p->rmdnum; while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN)) { + cnt++; if( (rmdstat & (RCV_START | RCV_END | RCV_ERR)) != (RCV_START | RCV_END) ) /* error or oversized? */ { if(!(rmdstat & RCV_ERR)) { @@ -603,27 +994,27 @@ } } else { - printk(KERN_ERR "%s: receive-error: %04x, lance-status: %04x/%04x\n", - dev->name,(int) rmdstat,csr0,(int) inw(PORT+L_DATAREG) ); + if(debuglevel > 2) + printk(KERN_ERR "%s: receive-error: %04x, lance-status: %04x/%04x\n", + dev->name,(int) rmdstat,csr0,(int) inw(PORT+L_DATAREG) ); if(rmdstat & RCV_FRAM) p->stats.rx_frame_errors++; if(rmdstat & RCV_OFLO) p->stats.rx_over_errors++; - if(rmdstat & (RCV_OFLO | RCV_BUF_ERR) ) { - writedatareg(CSR0_STOP); - writedatareg(CSR0_STRT); - if(debuglevel > 1) - printk(KERN_ERR "%s: Rcv FIFO/BUFF error.\n",dev->name); - } - if(rmdstat & RCV_CRC) p->stats.rx_crc_errors++; + if(rmdstat & RCV_CRC) + p->stats.rx_crc_errors++; + if(rmdstat & RCV_BUF_ERR) + p->stats.rx_fifo_errors++; } - rmdp->u.s.status = RCV_OWN; /* change owner */ - p->stats.rx_errors++; + if(!(csr0 & CSR0_MISS)) /* don't count errors twice */ + p->stats.rx_errors++; } else if( (len = (rmdp->mlen & 0x0fff) - 4) >= 60) { #ifdef RCV_VIA_SKB - struct sk_buff *skb = dev_alloc_skb(R_BUF_SIZE+2); + struct sk_buff *skb = alloc_skb(R_BUF_SIZE+2+16,GFP_ATOMIC); + if (skb) + skb_reserve(skb,16); #else struct sk_buff *skb = dev_alloc_skb(len+2); #endif @@ -640,7 +1031,7 @@ struct sk_buff *skb1 = p->recv_skb[p->rmdnum]; skb_put(skb,R_BUF_SIZE); p->recv_skb[p->rmdnum] = skb; - rmdp->u.buffer = (unsigned long) skb->data; + rmdp->u.buffer = (u32) virt_to_bus(skb->data); skb = skb1; skb_trim(skb,len); } @@ -648,23 +1039,23 @@ skb_put(skb,len); eth_copy_and_sum(skb, (unsigned char *) p->recvbounce[p->rmdnum],len,0); #endif - rmdp->u.s.status = RCV_OWN; p->stats.rx_packets++; skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } else { - rmdp->u.s.status = RCV_OWN; printk(KERN_ERR "%s: can't alloc new sk_buff\n",dev->name); p->stats.rx_dropped++; } } else { - rmdp->u.s.status = RCV_OWN; printk(KERN_INFO "%s: received runt packet\n",dev->name); p->stats.rx_errors++; } + rmdp->blen = -(R_BUF_SIZE-8); + rmdp->mlen = 0; + rmdp->u.s.status = RCV_OWN; /* change owner */ p->rmdnum = (p->rmdnum + 1) & (RMDNUM-1); rmdp = p->rmdhead + p->rmdnum; } @@ -680,11 +1071,17 @@ if(dev->tbusy) { int tickssofar = jiffies - dev->trans_start; - if (tickssofar < 5) + if (tickssofar < 50) return 1; printk(KERN_ERR "%s: xmitter timed out, try to restart!\n",dev->name); - ni65_am7990_reinit(dev); +{ + int i; + for(i=0;itmdhead[i].u.s.status); + printk("\n"); +} + ni65_lance_reinit(dev); dev->tbusy=0; dev->trans_start = jiffies; } @@ -708,28 +1105,37 @@ { short len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - struct tmd *tmdp = p->tmdhead + p->tmdnum; + struct tmd *tmdp; long flags; #ifdef XMT_VIA_SKB if( (unsigned long) (skb->data + skb->len) > 0x1000000) { #endif - tmdp->u.buffer = (unsigned long ) p->tmdbounce[p->tmdnum]; - memcpy((char *) tmdp->u.buffer,(char *)skb->data, + + memcpy((char *) p->tmdbounce[p->tmdbouncenum] ,(char *)skb->data, (skb->len > T_BUF_SIZE) ? T_BUF_SIZE : skb->len); dev_kfree_skb (skb, FREE_WRITE); + + save_flags(flags); + cli(); + + tmdp = p->tmdhead + p->tmdnum; + tmdp->u.buffer = (u32) virt_to_bus(p->tmdbounce[p->tmdbouncenum]); + p->tmdbouncenum = (p->tmdbouncenum + 1) & (TMDNUM - 1); + #ifdef XMT_VIA_SKB } else { - tmdp->u.buffer = (unsigned long) skb->data; + save_flags(flags); + cli(); + + tmdp = p->tmdhead + p->tmdnum; + tmdp->u.buffer = (u32) virt_to_bus(skb->data); p->tmd_skb[p->tmdnum] = skb; } #endif tmdp->blen = -len; - save_flags(flags); - cli(); - tmdp->u.s.status = XMIT_OWN | XMIT_START | XMIT_END; writedatareg(CSR0_TDMD | CSR0_INEA); /* enable xmit & interrupt */ @@ -748,17 +1154,75 @@ static struct enet_statistics *ni65_get_stats(struct device *dev) { + +#if 0 + int i; + struct priv *p = (struct priv *) dev->priv; + for(i=0;irmdhead + ((p->rmdnum + i) & (RMDNUM-1)); + printk("%02x ",rmdp->u.s.status); + } + printk("\n"); +#endif + return &((struct priv *) dev->priv)->stats; } static void set_multicast_list(struct device *dev) { - if(!ni65_am7990_reinit(dev)) + if(!ni65_lance_reinit(dev)) printk(KERN_ERR "%s: Can't switch card into MC mode!\n",dev->name); dev->tbusy = 0; } +#ifdef MODULE +static struct device dev_ni65 = { + " ", /* "ni6510": device name inserted by net_init.c */ + 0, 0, 0, 0, + 0x360, 9, /* I/O address, IRQ */ + 0, 0, 0, NULL, ni65_probe }; + +/* set: io,irq,dma or set it when calling insmod */ +static int irq=0; +static int io=0; +static int dma=0; + +int init_module(void) +{ +#if 0 + if(io <= 0x0 || irq < 2) { + printk("ni65: Autoprobing not allowed for modules.\n"); + printk("ni65: Set symbols 'io' 'irq' and 'dma'\n"); + return -ENODEV; + } +#endif + dev_ni65.irq = irq; + dev_ni65.dma = dma; + dev_ni65.base_addr = io; + if (register_netdev(&dev_ni65) != 0) + return -EIO; + return 0; +} + +void cleanup_module(void) +{ + struct priv *p; + p = (struct priv *) dev_ni65.priv; + if(!p) { + printk("Ooops .. no privat struct\n"); + return; + } + disable_dma(dev_ni65.dma); + free_dma(dev_ni65.dma); + release_region(dev_ni65.base_addr,cards[p->cardno].total_size); + ni65_free_buffer(p); + dev_ni65.priv = NULL; + unregister_netdev(&dev_ni65); +} +#endif /* MODULE */ + /* * END of ni65.c */ + diff -u --recursive --new-file v2.1.2/linux/drivers/net/ni65.h linux/drivers/net/ni65.h --- v2.1.2/linux/drivers/net/ni65.h Wed Oct 9 08:55:20 1996 +++ linux/drivers/net/ni65.h Wed Oct 9 09:57:20 1996 @@ -92,23 +92,23 @@ unsigned char eaddr[6]; unsigned char filter[8]; /* bit 29-31: number of rmd's (power of 2) */ - unsigned long rrp; /* receive ring pointer (align 8) */ + u32 rrp; /* receive ring pointer (align 8) */ /* bit 29-31: number of tmd's (power of 2) */ - unsigned long trp; /* transmit ring pointer (align 8) */ + u32 trp; /* transmit ring pointer (align 8) */ }; struct rmd /* Receive Message Descriptor */ { union { - volatile unsigned long buffer; + volatile u32 buffer; struct { volatile unsigned char dummy[3]; volatile unsigned char status; } s; } u; - short blen; + volatile short blen; volatile unsigned short mlen; }; @@ -116,14 +116,14 @@ { union { - volatile unsigned long buffer; + volatile u32 buffer; struct { volatile unsigned char dummy[3]; volatile unsigned char status; } s; } u; - unsigned short blen; + volatile unsigned short blen; volatile unsigned short status2; }; diff -u --recursive --new-file v2.1.2/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v2.1.2/linux/drivers/net/ppp.c Wed Jul 17 07:17:30 1996 +++ linux/drivers/net/ppp.c Tue Oct 8 21:21:23 1996 @@ -3081,6 +3081,14 @@ len = skb->len; data = skb_data(skb); /* + * Bug trap for null data. Release the skb and bail out. + */ + if(data == NULL) { + printk("ppp_dev_xmit: data=NULL before ppp_dev_xmit_ip.\n"); + dev_kfree_skb (skb, FREE_WRITE); + return 0; + } +/* * Look at the protocol in the skb to determine the difference between * an IP frame and an IPX frame. */ diff -u --recursive --new-file v2.1.2/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v2.1.2/linux/drivers/net/tulip.c Wed Apr 17 09:31:21 1996 +++ linux/drivers/net/tulip.c Tue Oct 8 21:21:46 1996 @@ -1096,7 +1096,7 @@ /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); } - else if (dev->mc_count > 15 || (dev->flags&IFF_ALLMULTI)) + else if (dev->mc_count > 14 || (dev->flags&IFF_ALLMULTI)) { /* Too many to filter perfectly -- accept all multicasts. */ tio_write(csr6 | TCMOD_ALLMCAST, CSR6); @@ -1109,7 +1109,7 @@ unsigned short *eaddrs; int i; - /* We have <= 15 addresses that we can use the wonderful + /* We have < 15 addresses that we can use the wonderful 16 address perfect filtering of the Tulip. Note that only the low shortword of setup_frame[] is valid. */ tio_write(csr6 | 0x0000, CSR6); @@ -1122,11 +1122,15 @@ } /* Fill the rest of the table with our physical address. */ eaddrs = (unsigned short *)dev->dev_addr; + /* Always accept broadcast packets */ + *setup_frm++ = 0xffff; + *setup_frm++ = 0xffff; + *setup_frm++ = 0xffff; do { *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[2]; - } while (++i < 16); + } while (++i < 15); /* Now add this frame to the Tx list. */ } diff -u --recursive --new-file v2.1.2/linux/fs/buffer.c linux/fs/buffer.c --- v2.1.2/linux/fs/buffer.c Wed Sep 25 12:15:57 1996 +++ linux/fs/buffer.c Wed Oct 9 11:30:47 1996 @@ -156,77 +156,66 @@ static int sync_buffers(kdev_t dev, int wait) { int i, retry, pass = 0, err = 0; - int nlist, ncount; struct buffer_head * bh, *next; /* One pass for no-wait, three for wait: 0) write out all dirty, unlocked buffers; 1) write out all dirty buffers, waiting if locked; 2) wait for completion by waiting for all buffers to unlock. */ - repeat: - retry = 0; - repeat2: - ncount = 0; + do { + retry = 0; +repeat: /* We search all lists as a failsafe mechanism, not because we expect there to be dirty buffers on any of the other lists. */ - for(nlist = 0; nlist < NR_LIST; nlist++) - { - repeat1: - bh = lru_list[nlist]; - if(!bh) continue; - for (i = nr_buffers_type[nlist]*2 ; i-- > 0 ; bh = next) { - if(bh->b_list != nlist) goto repeat1; - next = bh->b_next_free; - if(!lru_list[nlist]) break; - if (dev && bh->b_dev != dev) - continue; - if (buffer_locked(bh)) - { - /* Buffer is locked; skip it unless wait is - requested AND pass > 0. */ - if (!wait || !pass) { - retry = 1; - continue; - } - wait_on_buffer (bh); - goto repeat2; - } - /* If an unlocked buffer is not uptodate, there has - been an IO error. Skip it. */ - if (wait && buffer_req(bh) && !buffer_locked(bh) && - !buffer_dirty(bh) && !buffer_uptodate(bh)) { - err = 1; - continue; - } - /* Don't write clean buffers. Don't write ANY buffers - on the third pass. */ - if (!buffer_dirty(bh) || pass>=2) - continue; - /* don't bother about locked buffers */ - if (buffer_locked(bh)) - continue; - bh->b_count++; - bh->b_flushtime = 0; - ll_rw_block(WRITE, 1, &bh); - - if(nlist != BUF_DIRTY) { - printk("[%d %s %ld] ", nlist, - kdevname(bh->b_dev), bh->b_blocknr); - ncount++; - } - bh->b_count--; - retry = 1; - } - } - if (ncount) - printk("sys_sync: %d dirty buffers not on dirty list\n", ncount); + bh = lru_list[BUF_DIRTY]; + if (!bh) + break; + for (i = nr_buffers_type[BUF_DIRTY]*2 ; i-- > 0 ; bh = next) { + if (bh->b_list != BUF_DIRTY) + goto repeat; + next = bh->b_next_free; + if (!lru_list[BUF_DIRTY]) + break; + if (dev && bh->b_dev != dev) + continue; + if (buffer_locked(bh)) { + /* Buffer is locked; skip it unless wait is + requested AND pass > 0. */ + if (!wait || !pass) { + retry = 1; + continue; + } + wait_on_buffer (bh); + goto repeat; + } + /* If an unlocked buffer is not uptodate, there has + been an IO error. Skip it. */ + if (wait && buffer_req(bh) && !buffer_locked(bh) && + !buffer_dirty(bh) && !buffer_uptodate(bh)) { + err = 1; + continue; + } + /* Don't write clean buffers. Don't write ANY buffers + on the third pass. */ + if (!buffer_dirty(bh) || pass >= 2) + continue; + /* don't bother about locked buffers */ + if (buffer_locked(bh)) + continue; + bh->b_count++; + next->b_count++; + bh->b_flushtime = 0; + ll_rw_block(WRITE, 1, &bh); + bh->b_count--; + next->b_count--; + retry = 1; + } /* If we are waiting for the sync to succeed, and if any dirty blocks were written, then repeat; on the second pass, only wait for buffers being written (do not pass to write any more buffers on the second pass). */ - if (wait && retry && ++pass<=2) - goto repeat; + } while (wait && retry && ++pass<=2); return err; } diff -u --recursive --new-file v2.1.2/linux/fs/namei.c linux/fs/namei.c --- v2.1.2/linux/fs/namei.c Fri Sep 20 13:17:18 1996 +++ linux/fs/namei.c Wed Oct 9 10:43:24 1996 @@ -21,68 +21,66 @@ #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) /* - * How long a filename can we get from user space? - * -EFAULT if invalid area - * 0 if ok (ENAMETOOLONG before EFAULT) - * >0 EFAULT after xx bytes - */ -static inline int get_max_filename(unsigned long address) -{ - struct vm_area_struct * vma; - - if (get_fs() == KERNEL_DS) - return 0; - vma = find_vma(current->mm, address); - if (!vma || vma->vm_start > address || !(vma->vm_flags & VM_READ)) - return -EFAULT; - address = vma->vm_end - address; - if (address > PAGE_SIZE) - return 0; - if (vma->vm_next && vma->vm_next->vm_start == vma->vm_end && - (vma->vm_next->vm_flags & VM_READ)) - return 0; - return address; -} - -/* * In order to reduce some races, while at the same time doing additional * checking and hopefully speeding things up, we copy filenames to the * kernel data space before using them.. * * POSIX.1 2.4: an empty pathname is invalid (ENOENT). */ -int getname(const char * filename, char **result) +static inline int do_getname(const char * filename, char *buf) { - int i, error; - unsigned long page; - char * tmp, c; + int error, maxlen = PAGE_SIZE; + int c; - i = get_max_filename((unsigned long) filename); - if (i < 0) - return i; - error = -EFAULT; - if (!i) { - error = -ENAMETOOLONG; - i = PAGE_SIZE; + error = -ENAMETOOLONG; + if (get_fs() != KERNEL_DS) { + error = -EFAULT; + if (TASK_SIZE <= (unsigned long) filename) + return error; + maxlen = TASK_SIZE - (unsigned long) filename; + if (maxlen >= PAGE_SIZE) { + maxlen = PAGE_SIZE; + error = -ENAMETOOLONG; + } } - c = get_user(filename++); + + c = (unsigned char) get_user(filename++); if (!c) return -ENOENT; - if(!(page = __get_free_page(GFP_KERNEL))) - return -ENOMEM; - *result = tmp = (char *) page; - while (--i) { - *(tmp++) = c; + + while (--maxlen) { + *(buf++) = c; c = get_user(filename++); if (!c) { - *tmp = '\0'; + *buf = '\0'; return 0; } } - free_page(page); return error; } +int getname(const char *filename, char **result) +{ + int error; + unsigned long page = __get_free_page(GFP_KERNEL); + + error = -ENOMEM; + if (page) { + error = -EFAULT; + if (!exception()) { + int retval = do_getname(filename, (char *) page); + end_exception(); + if (!retval) { + *result = (char *) page; + return 0; + } + error = retval; + } + free_page(page); + } + return error; +} + void putname(char * name) { free_page((unsigned long) name); diff -u --recursive --new-file v2.1.2/linux/fs/proc/base.c linux/fs/proc/base.c --- v2.1.2/linux/fs/proc/base.c Wed Feb 21 11:26:09 1996 +++ linux/fs/proc/base.c Wed Oct 9 20:10:26 1996 @@ -80,72 +80,83 @@ NULL, &proc_root, NULL }; +static struct proc_dir_entry proc_pid_status = { + PROC_PID_STATUS, 6, "status", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_mem = { + PROC_PID_MEM, 3, "mem", + S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0, + 0, &proc_mem_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_cwd = { + PROC_PID_CWD, 3, "cwd", + S_IFLNK | S_IRWXU, 1, 0, 0, + 0, &proc_link_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_root = { + PROC_PID_ROOT, 4, "root", + S_IFLNK | S_IRWXU, 1, 0, 0, + 0, &proc_link_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_exe = { + PROC_PID_EXE, 3, "exe", + S_IFLNK | S_IRWXU, 1, 0, 0, + 0, &proc_link_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_fd = { + PROC_PID_FD, 2, "fd", + S_IFDIR | S_IRUSR | S_IXUSR, 1, 0, 0, + 0, &proc_fd_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_environ = { + PROC_PID_ENVIRON, 7, "environ", + S_IFREG | S_IRUSR, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_cmdline = { + PROC_PID_CMDLINE, 7, "cmdline", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_stat = { + PROC_PID_STAT, 4, "stat", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_statm = { + PROC_PID_STATM, 5, "statm", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, +}; +static struct proc_dir_entry proc_pid_maps = { + PROC_PID_MAPS, 4, "maps", + S_IFIFO | S_IRUGO, 1, 0, 0, + 0, &proc_arraylong_inode_operations, + NULL, proc_pid_fill_inode, +}; void proc_base_init(void) { - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_STATUS, 6, "status", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_MEM, 3, "mem", - S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0, - 0, &proc_mem_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_CWD, 3, "cwd", - S_IFLNK | S_IRWXU, 1, 0, 0, - 0, &proc_link_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_ROOT, 4, "root", - S_IFLNK | S_IRWXU, 1, 0, 0, - 0, &proc_link_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_EXE, 3, "exe", - S_IFLNK | S_IRWXU, 1, 0, 0, - 0, &proc_link_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_FD, 2, "fd", - S_IFDIR | S_IRUSR | S_IXUSR, 1, 0, 0, - 0, &proc_fd_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_ENVIRON, 7, "environ", - S_IFREG | S_IRUSR, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_CMDLINE, 7, "cmdline", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_STAT, 4, "stat", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_STATM, 5, "statm", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, - }); - proc_register(&proc_pid, &(struct proc_dir_entry) { - PROC_PID_MAPS, 4, "maps", - S_IFIFO | S_IRUGO, 1, 0, 0, - 0, &proc_arraylong_inode_operations, - NULL, proc_pid_fill_inode, - }); + proc_register(&proc_pid, &proc_pid_status); + proc_register(&proc_pid, &proc_pid_mem); + proc_register(&proc_pid, &proc_pid_cwd); + proc_register(&proc_pid, &proc_pid_root); + proc_register(&proc_pid, &proc_pid_exe); + proc_register(&proc_pid, &proc_pid_fd); + proc_register(&proc_pid, &proc_pid_environ); + proc_register(&proc_pid, &proc_pid_cmdline); + proc_register(&proc_pid, &proc_pid_stat); + proc_register(&proc_pid, &proc_pid_statm); + proc_register(&proc_pid, &proc_pid_maps); }; diff -u --recursive --new-file v2.1.2/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.1.2/linux/fs/proc/root.c Tue Apr 30 13:09:45 1996 +++ linux/fs/proc/root.c Wed Oct 9 20:10:26 1996 @@ -250,6 +250,114 @@ NULL /* permission */ }; +static struct proc_dir_entry proc_root_loadavg = { + PROC_LOADAVG, 7, "loadavg", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_uptime = { + PROC_UPTIME, 6, "uptime", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_meminfo = { + PROC_MEMINFO, 7, "meminfo", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_kmsg = { + PROC_KMSG, 4, "kmsg", + S_IFREG | S_IRUSR, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_version = { + PROC_VERSION, 7, "version", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#ifdef CONFIG_PCI +static struct proc_dir_entry proc_root_pci = { + PROC_PCI, 3, "pci", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#endif +static struct proc_dir_entry proc_root_cpuinfo = { + PROC_CPUINFO, 7, "cpuinfo", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_self = { + PROC_SELF, 4, "self", + S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0, + 64, &proc_self_inode_operations, +}; +#ifdef CONFIG_DEBUG_MALLOC +static struct proc_dir_entry proc_root_malloc = { + PROC_MALLOC, 6, "malloc", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#endif +static struct proc_dir_entry proc_root_kcore = { + PROC_KCORE, 5, "kcore", + S_IFREG | S_IRUSR, 1, 0, 0, +}; +#ifdef CONFIG_MODULES +static struct proc_dir_entry proc_root_modules = { + PROC_MODULES, 7, "modules", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_ksyms = { + PROC_KSYMS, 5, "ksyms", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#endif +static struct proc_dir_entry proc_root_stat = { + PROC_STAT, 4, "stat", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_devices = { + PROC_DEVICES, 7, "devices", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_interrupts = { + PROC_INTERRUPTS, 10,"interrupts", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#ifdef __SMP_PROF__ +static struct proc_dir_entry proc_root_smp = { + PROC_SMP_PROF, 3,"smp", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#endif +static struct proc_dir_entry proc_root_filesystems = { + PROC_FILESYSTEMS, 11,"filesystems", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_dma = { + PROC_DMA, 3, "dma", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_ioports = { + PROC_IOPORTS, 7, "ioports", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_cmdline = { + PROC_CMDLINE, 7, "cmdline", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#ifdef CONFIG_RTC +static struct proc_dir_entry proc_root_rtc = { + PROC_RTC, 3, "rtc", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +#endif +static struct proc_dir_entry proc_root_locks = { + PROC_LOCKS, 5, "locks", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_mounts = { + PROC_MTAB, 6, "mounts", + S_IFREG | S_IRUGO, 1, 0, 0, +}; +static struct proc_dir_entry proc_root_profile = { + PROC_PROFILE, 7, "profile", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, +}; + void proc_root_init(void) { static int done = 0; @@ -258,119 +366,48 @@ return; done = 1; proc_base_init(); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_LOADAVG, 7, "loadavg", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_UPTIME, 6, "uptime", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_MEMINFO, 7, "meminfo", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_KMSG, 4, "kmsg", - S_IFREG | S_IRUSR, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_VERSION, 7, "version", - S_IFREG | S_IRUGO, 1, 0, 0, - }); + proc_register(&proc_root, &proc_root_loadavg); + proc_register(&proc_root, &proc_root_uptime); + proc_register(&proc_root, &proc_root_meminfo); + proc_register(&proc_root, &proc_root_kmsg); + proc_register(&proc_root, &proc_root_version); #ifdef CONFIG_PCI - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_PCI, 3, "pci", - S_IFREG | S_IRUGO, 1, 0, 0, - }); -#endif - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_CPUINFO, 7, "cpuinfo", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_SELF, 4, "self", - S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0, - 64, &proc_self_inode_operations, - }); + proc_register(&proc_root, &proc_root_pci); +#endif + proc_register(&proc_root, &proc_root_cpuinfo); + proc_register(&proc_root, &proc_root_self); proc_register(&proc_root, &proc_net); proc_register(&proc_root, &proc_scsi); proc_register(&proc_root, &proc_sys_root); #ifdef CONFIG_DEBUG_MALLOC - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_MALLOC, 6, "malloc", - S_IFREG | S_IRUGO, 1, 0, 0, - }); -#endif - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_KCORE, 5, "kcore", - S_IFREG | S_IRUSR, 1, 0, 0, - }); + proc_register(&proc_root, &proc_root_malloc); +#endif + proc_register(&proc_root, &proc_root_kcore); #ifdef CONFIG_MODULES - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_MODULES, 7, "modules", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_KSYMS, 5, "ksyms", - S_IFREG | S_IRUGO, 1, 0, 0, - }); -#endif - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_STAT, 4, "stat", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_DEVICES, 7, "devices", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_INTERRUPTS, 10,"interrupts", - S_IFREG | S_IRUGO, 1, 0, 0, - }); + proc_register(&proc_root, &proc_root_modules); + proc_register(&proc_root, &proc_root_ksyms); +#endif + proc_register(&proc_root, &proc_root_stat); + proc_register(&proc_root, &proc_root_devices); + proc_register(&proc_root, &proc_root_interrupts); #ifdef __SMP_PROF__ - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_SMP_PROF, 3,"smp", - S_IFREG | S_IRUGO, 1, 0, 0, - }); + proc_register(&proc_root, &proc_root_smp); #endif - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_FILESYSTEMS, 11,"filesystems", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_DMA, 3, "dma", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_IOPORTS, 7, "ioports", - S_IFREG | S_IRUGO, 1, 0, 0, - }); - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_CMDLINE, 7, "cmdline", - S_IFREG | S_IRUGO, 1, 0, 0, - }); + proc_register(&proc_root, &proc_root_filesystems); + proc_register(&proc_root, &proc_root_dma); + proc_register(&proc_root, &proc_root_ioports); + proc_register(&proc_root, &proc_root_cmdline); #ifdef CONFIG_RTC - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_RTC, 3, "rtc", - S_IFREG | S_IRUGO, 1, 0, 0, - }); -#endif - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_LOCKS, 5, "locks", - S_IFREG | S_IRUGO, 1, 0, 0, - }); + proc_register(&proc_root, &proc_root_rtc); +#endif + proc_register(&proc_root, &proc_root_locks); - proc_register( &proc_root, &(struct proc_dir_entry) - { PROC_MTAB, 6, "mounts", S_IFREG | S_IRUGO, 1, 0, 0, } ); + proc_register(&proc_root, &proc_root_mounts); if (prof_shift) { - proc_register(&proc_root, &(struct proc_dir_entry) { - PROC_PROFILE, 7, "profile", - S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, - }); + proc_register(&proc_root, &proc_root_profile); } } diff -u --recursive --new-file v2.1.2/linux/include/asm-alpha/jensen.h linux/include/asm-alpha/jensen.h --- v2.1.2/linux/include/asm-alpha/jensen.h Tue Nov 7 09:18:36 1995 +++ linux/include/asm-alpha/jensen.h Wed Oct 9 09:54:05 1996 @@ -95,6 +95,8 @@ set_hae(addr); } +#ifdef __KERNEL__ + /* * IO functions * @@ -258,6 +260,8 @@ #define outb(x, port) \ (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#endif /* __KERNEL__ */ /* * The Alpha Jensen hardware for some rather strange reason puts diff -u --recursive --new-file v2.1.2/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v2.1.2/linux/include/asm-alpha/processor.h Wed Oct 9 08:55:22 1996 +++ linux/include/asm-alpha/processor.h Thu Oct 10 17:07:16 1996 @@ -21,12 +21,6 @@ #define MCA_bus__is_a_macro /* for versions in ksyms.c */ /* - * The alpha has no problems with write protection - */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ - -/* * The VM exception save area. We need to save * return address (r26) * PC (r30) diff -u --recursive --new-file v2.1.2/linux/include/asm-alpha/segment.h linux/include/asm-alpha/segment.h --- v2.1.2/linux/include/asm-alpha/segment.h Mon Sep 23 17:44:17 1996 +++ linux/include/asm-alpha/segment.h Thu Oct 10 17:14:32 1996 @@ -51,4 +51,7 @@ return 0; } +/* Hardware write protection */ +#define verify_write(type, addr, size) 0 + #endif /* _ASM_SEGMENT_H */ diff -u --recursive --new-file v2.1.2/linux/include/asm-i386/io.h linux/include/asm-i386/io.h --- v2.1.2/linux/include/asm-i386/io.h Wed Oct 9 08:55:22 1996 +++ linux/include/asm-i386/io.h Wed Oct 9 09:31:45 1996 @@ -37,58 +37,6 @@ #define SLOW_DOWN_IO __SLOW_DOWN_IO #endif -#include - -#define __io_virt(x) ((void *)(PAGE_OFFSET | (unsigned long)(x))) -#define __io_phys(x) ((unsigned long)(x) & ~PAGE_OFFSET) -/* - * Change virtual addresses to physical addresses and vv. - * These are pretty trivial - */ -extern inline unsigned long virt_to_phys(volatile void * address) -{ - return __io_phys(address); -} - -extern inline void * phys_to_virt(unsigned long address) -{ - return __io_virt(address); -} - -extern void * ioremap(unsigned long offset, unsigned long size); -extern void iounmap(void *addr); - -/* - * IO bus memory addresses are also 1:1 with the physical address - */ -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - -/* - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the x86 architecture, we just read/write the - * memory location directly. - */ - -#define readb(addr) (*(volatile unsigned char *) __io_virt(addr)) -#define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) -#define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) - -#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) -#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) -#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) - -#define memset_io(a,b,c) memset(__io_virt(a),(b),(c)) -#define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c)) -#define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c)) - -/* - * Again, i386 does not require mem IO specific function. - */ - -#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d)) - /* * Talk about misusing macros.. */ @@ -216,6 +164,60 @@ __inlc_p(port) : \ __inl_p(port)) +#ifdef __KERNEL__ + +#include + +#define __io_virt(x) ((void *)(PAGE_OFFSET | (unsigned long)(x))) +#define __io_phys(x) ((unsigned long)(x) & ~PAGE_OFFSET) +/* + * Change virtual addresses to physical addresses and vv. + * These are pretty trivial + */ +extern inline unsigned long virt_to_phys(volatile void * address) +{ + return __io_phys(address); +} + +extern inline void * phys_to_virt(unsigned long address) +{ + return __io_virt(address); +} + +extern void * ioremap(unsigned long offset, unsigned long size); +extern void iounmap(void *addr); + +/* + * IO bus memory addresses are also 1:1 with the physical address + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ + +#define readb(addr) (*(volatile unsigned char *) __io_virt(addr)) +#define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) +#define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) + +#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) +#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) +#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) + +#define memset_io(a,b,c) memset(__io_virt(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c)) +#define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c)) + +/* + * Again, i386 does not require mem IO specific function. + */ + +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d)) + static inline int check_signature(unsigned long io_addr, const unsigned char *signature, int length) { @@ -231,5 +233,7 @@ out: return retval; } + +#endif /* __KERNEL__ */ #endif diff -u --recursive --new-file v2.1.2/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v2.1.2/linux/include/asm-i386/processor.h Wed Oct 9 08:55:22 1996 +++ linux/include/asm-i386/processor.h Thu Oct 10 17:08:35 1996 @@ -33,7 +33,6 @@ */ extern int EISA_bus; #define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ /* * User space process size: 3GB. This is hardcoded into a few places, diff -u --recursive --new-file v2.1.2/linux/include/asm-i386/segment.h linux/include/asm-i386/segment.h --- v2.1.2/linux/include/asm-i386/segment.h Sat Oct 5 16:58:36 1996 +++ linux/include/asm-i386/segment.h Thu Oct 10 17:13:14 1996 @@ -48,6 +48,23 @@ #define set_fs(x) (current->tss.segment = (x)) #define get_ds() (KERNEL_DS) +extern int __verify_write(const void *addr, unsigned long size); + +#if CPU > 386 + +#define verify_write(type,addr,size) 0 + +#else + +/* + * The intel i386 CPU needs to check writability by hand, as the + * CPU does not honour the write protect bit in supervisor mode + */ +#define verify_write(type,addr,size) \ +(((type) && !wp_works_ok)?__verify_write((addr),(size)):0) + +#endif + #endif /* __ASSEMBLY__ */ #endif /* _ASM_SEGMENT_H */ diff -u --recursive --new-file v2.1.2/linux/include/asm-i386/user.h linux/include/asm-i386/user.h --- v2.1.2/linux/include/asm-i386/user.h Wed Oct 9 08:55:23 1996 +++ linux/include/asm-i386/user.h Thu Oct 10 11:35:12 1996 @@ -43,7 +43,7 @@ /* * This is the old layout of "struct pt_regs", and - * is still the layout used by user more (the new + * is still the layout used by user mode (the new * pt_regs doesn't have all registers as the kernel * doesn't use the extra segment registers) */ diff -u --recursive --new-file v2.1.2/linux/include/linux/mm.h linux/include/linux/mm.h --- v2.1.2/linux/include/linux/mm.h Wed Oct 9 08:55:23 1996 +++ linux/include/linux/mm.h Thu Oct 10 17:15:49 1996 @@ -19,11 +19,6 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -extern int __verify_write(const void *, unsigned long); - -#define verify_write(type,addr,size) \ -(((type) && !wp_works_ok)?__verify_write((addr),(size)):0) - extern inline int verify_area(int type, const void * addr, unsigned long size) { int retval = 0; diff -u --recursive --new-file v2.1.2/linux/include/net/sock.h linux/include/net/sock.h --- v2.1.2/linux/include/net/sock.h Mon Sep 30 11:21:33 1996 +++ linux/include/net/sock.h Thu Oct 10 17:17:56 1996 @@ -167,6 +167,7 @@ unsigned short rcv_ack_cnt; /* count of same ack */ __u32 window_seq; __u32 fin_seq; + __u32 syn_seq; __u32 urg_seq; __u32 urg_data; int users; /* user count */ diff -u --recursive --new-file v2.1.2/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.2/linux/kernel/ksyms.c Wed Oct 9 08:55:24 1996 +++ linux/kernel/ksyms.c Thu Oct 10 17:08:09 1996 @@ -92,18 +92,6 @@ #endif X(get_options), - /* system info variables */ - /* These check that they aren't defines (0/1) */ -#ifndef EISA_bus__is_a_macro - X(EISA_bus), -#endif -#ifndef MCA_bus__is_a_macro - X(MCA_bus), -#endif -#ifndef wp_works_ok__is_a_macro - X(wp_works_ok), -#endif - #ifdef CONFIG_PCI /* PCI BIOS support */ X(pcibios_present), diff -u --recursive --new-file v2.1.2/linux/mm/memory.c linux/mm/memory.c --- v2.1.2/linux/mm/memory.c Wed Oct 9 08:55:24 1996 +++ linux/mm/memory.c Thu Oct 10 17:09:51 1996 @@ -676,57 +676,6 @@ } /* - * Ugly, ugly, but the goto's result in better assembly.. - */ -int __verify_write(const void * addr, unsigned long size) -{ - struct vm_area_struct * vma; - unsigned long start = (unsigned long) addr; - - if (!size) - return 0; - - vma = find_vma(current->mm, start); - if (!vma) - goto bad_area; - if (vma->vm_start > start) - goto check_stack; - -good_area: - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - size--; - size += start & ~PAGE_MASK; - size >>= PAGE_SHIFT; - start &= PAGE_MASK; - - for (;;) { - do_wp_page(current, vma, start, 1); - if (!size) - break; - size--; - start += PAGE_SIZE; - if (start < vma->vm_end) - continue; - vma = vma->vm_next; - if (!vma || vma->vm_start != start) - goto bad_area; - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area;; - } - return 0; - -check_stack: - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - if (expand_stack(vma, start) == 0) - goto good_area; - -bad_area: - return -EFAULT; -} - -/* * This function zeroes out partial mmap'ed pages at truncation time.. */ static void partial_clear(struct vm_area_struct *vma, unsigned long address) diff -u --recursive --new-file v2.1.2/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c --- v2.1.2/linux/net/appletalk/ddp.c Fri May 31 13:46:27 1996 +++ linux/net/appletalk/ddp.c Wed Oct 9 20:10:26 1996 @@ -2006,6 +2006,26 @@ static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B}; +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_appletalk = { + PROC_NET_ATALK, 9, "appletalk", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + atalk_get_info +}; +static struct proc_dir_entry proc_atalk_route = { + PROC_NET_AT_ROUTE, 11,"atalk_route", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + atalk_rt_get_info +}; +static struct proc_dir_entry proc_atalk_iface = { + PROC_NET_ATIF, 11,"atalk_iface", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + atalk_if_get_info +}; +#endif /* Called by proto.c on kernel start up */ @@ -2025,24 +2045,9 @@ aarp_proto_init(); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_ATALK, 9, "appletalk", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - atalk_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_AT_ROUTE, 11,"atalk_route", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - atalk_rt_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_ATIF, 11,"atalk_iface", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - atalk_if_get_info - }); + proc_net_register(&proc_appletalk); + proc_net_register(&proc_atalk_route); + proc_net_register(&proc_atalk_iface); #endif printk(KERN_INFO "Appletalk 0.17 for Linux NET3.035\n"); diff -u --recursive --new-file v2.1.2/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c --- v2.1.2/linux/net/ax25/af_ax25.c Wed Aug 7 08:41:57 1996 +++ linux/net/ax25/af_ax25.c Wed Oct 9 20:11:11 1996 @@ -2365,6 +2365,35 @@ 0 }; +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_ax25_route = { + PROC_NET_AX25_ROUTE, 10, "ax25_route", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ax25_rt_get_info +}; +static struct proc_dir_entry proc_ax25 = { + PROC_NET_AX25, 4, "ax25", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ax25_get_info +}; +static struct proc_dir_entry proc_ax25_calls = { + PROC_NET_AX25_CALLS, 10, "ax25_calls", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ax25_cs_get_info +}; +#endif +#ifdef CONFIG_BPQETHER +static struct proc_dir_entry proc_ax25_bpqether = { + PROC_NET_AX25_BPQETHER, 13, "ax25_bpqether", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ax25_bpq_get_info +}; +#endif + void ax25_proto_init(struct net_proto *pro) { sock_register(ax25_proto_ops.family, &ax25_proto_ops); @@ -2376,35 +2405,15 @@ #endif register_netdevice_notifier(&ax25_dev_notifier); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_AX25_ROUTE, 10, "ax25_route", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ax25_rt_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_AX25, 4, "ax25", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ax25_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_AX25_CALLS, 10, "ax25_calls", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ax25_cs_get_info - }); + proc_net_register(&proc_ax25_route); + proc_net_register(&proc_ax25); + proc_net_register(&proc_ax25_calls); #endif printk(KERN_INFO "G4KLX/GW4PTS AX.25 for Linux. Version 0.32 for Linux NET3.035 (Linux 2.0)\n"); #ifdef CONFIG_BPQETHER - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_AX25_BPQETHER, 13, "ax25_bpqether", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ax25_bpq_get_info - }); + proc_net_register(&proc_ax25_bpqether); printk(KERN_INFO "G8BPQ Encapsulation of AX.25 frames enabled\n"); #endif diff -u --recursive --new-file v2.1.2/linux/net/core/dev.c linux/net/core/dev.c --- v2.1.2/linux/net/core/dev.c Thu Aug 1 15:43:04 1996 +++ linux/net/core/dev.c Wed Oct 9 20:11:11 1996 @@ -1369,6 +1369,15 @@ extern void sdla_setup(void); extern void dlci_setup(void); +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_dev = { + PROC_NET_DEV, 3, "dev", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + dev_get_info +}; +#endif + int net_dev_init(void) { struct device *dev, **dp; @@ -1395,9 +1404,6 @@ #if defined(CONFIG_LANCE) lance_init(); #endif -#if defined(CONFIG_NI65) - ni65_init(); -#endif #if defined(CONFIG_PI) pi_init(); #endif @@ -1449,12 +1455,7 @@ } #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_DEV, 3, "dev", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - dev_get_info - }); + proc_net_register(&proc_net_dev); #endif /* diff -u --recursive --new-file v2.1.2/linux/net/core/net_alias.c linux/net/core/net_alias.c --- v2.1.2/linux/net/core/net_alias.c Sat Aug 31 19:39:10 1996 +++ linux/net/core/net_alias.c Wed Oct 9 20:11:11 1996 @@ -1278,6 +1278,22 @@ 0 }; +#ifndef ALIAS_USER_LAND_DEBUG +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_alias_types = { + PROC_NET_ALIAS_TYPES, 11, "alias_types", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + net_alias_types_getinfo +}; +static struct proc_dir_entry proc_net_aliases = { + PROC_NET_ALIASES, 7, "aliases", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + net_alias_getinfo +}; +#endif +#endif /* * net_alias initialisation @@ -1299,18 +1315,8 @@ #ifndef ALIAS_USER_LAND_DEBUG #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_ALIAS_TYPES, 11, "alias_types", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - net_alias_types_getinfo - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_ALIASES, 7, "aliases", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - net_alias_getinfo - }); + proc_net_register(&proc_net_alias_types); + proc_net_register(&proc_net_aliases); #endif #endif diff -u --recursive --new-file v2.1.2/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c --- v2.1.2/linux/net/ipv4/af_inet.c Sun Aug 4 12:56:25 1996 +++ linux/net/ipv4/af_inet.c Wed Oct 9 20:11:11 1996 @@ -1593,6 +1593,59 @@ extern unsigned long seq_offset; +#ifdef CONFIG_PROC_FS +#ifdef CONFIG_INET_RARP +static struct proc_dir_entry proc_net_rarp = { + PROC_NET_RARP, 4, "rarp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rarp_get_info +}; +#endif /* RARP */ +static struct proc_dir_entry proc_net_raw = { + PROC_NET_RAW, 3, "raw", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + raw_get_info +}; +static struct proc_dir_entry proc_net_snmp = { + PROC_NET_SNMP, 4, "snmp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + snmp_get_info +}; +static struct proc_dir_entry proc_net_sockstat = { + PROC_NET_SOCKSTAT, 8, "sockstat", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + afinet_get_info +}; +static struct proc_dir_entry proc_net_tcp = { + PROC_NET_TCP, 3, "tcp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + tcp_get_info +}; +static struct proc_dir_entry proc_net_udp = { + PROC_NET_UDP, 3, "udp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + udp_get_info +}; +static struct proc_dir_entry proc_net_route = { + PROC_NET_ROUTE, 5, "route", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rt_get_info +}; +static struct proc_dir_entry proc_net_rtcache = { + PROC_NET_RTCACHE, 8, "rt_cache", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rt_cache_get_info +}; +#endif /* CONFIG_PROC_FS */ + /* * Called by socket.c on kernel startup. */ @@ -1683,55 +1736,15 @@ #ifdef CONFIG_PROC_FS #ifdef CONFIG_INET_RARP - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_RARP, 4, "rarp", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - rarp_get_info - }); + proc_net_register(&proc_net_rarp); #endif /* RARP */ - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_RAW, 3, "raw", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - raw_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_SNMP, 4, "snmp", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - snmp_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_SOCKSTAT, 8, "sockstat", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - afinet_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_TCP, 3, "tcp", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - tcp_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_UDP, 3, "udp", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - udp_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_ROUTE, 5, "route", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - rt_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_RTCACHE, 8, "rt_cache", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - rt_cache_get_info - }); + proc_net_register(&proc_net_raw); + proc_net_register(&proc_net_snmp); + proc_net_register(&proc_net_sockstat); + proc_net_register(&proc_net_tcp); + proc_net_register(&proc_net_udp); + proc_net_register(&proc_net_route); + proc_net_register(&proc_net_rtcache); #endif /* CONFIG_PROC_FS */ } diff -u --recursive --new-file v2.1.2/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.1.2/linux/net/ipv4/arp.c Sat Oct 5 16:58:36 1996 +++ linux/net/ipv4/arp.c Wed Oct 9 20:11:11 1996 @@ -2389,6 +2389,15 @@ 0 }; +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_arp = { + PROC_NET_ARP, 3, "arp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + arp_get_info +}; +#endif + void arp_init (void) { /* Register the packet type */ @@ -2400,12 +2409,7 @@ register_netdevice_notifier(&arp_dev_notifier); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_ARP, 3, "arp", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - arp_get_info - }); + proc_net_register(&proc_net_arp); #endif #ifdef CONFIG_ARPD diff -u --recursive --new-file v2.1.2/linux/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c --- v2.1.2/linux/net/ipv4/ip_forward.c Wed Aug 7 13:59:29 1996 +++ linux/net/ipv4/ip_forward.c Thu Oct 10 16:04:10 1996 @@ -264,8 +264,12 @@ if (iph->protocol == IPPROTO_ICMP) { if ((fw_res = ip_fw_masq_icmp(&skb, dev2)) < 0) + { + if (rt) + ip_rt_put(rt); /* Problem - ie bad checksum */ return -1; + } if (fw_res) /* ICMP matched - skip firewall */ diff -u --recursive --new-file v2.1.2/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c --- v2.1.2/linux/net/ipv4/ip_fw.c Wed Aug 21 08:33:37 1996 +++ linux/net/ipv4/ip_fw.c Wed Oct 9 20:11:11 1996 @@ -1244,16 +1244,45 @@ #endif +#ifdef CONFIG_PROC_FS +#ifdef CONFIG_IP_ACCT +static struct proc_dir_entry proc_net_ipacct = { + PROC_NET_IPACCT, 7, "ip_acct", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_acct_procinfo +}; +#endif +#endif + +#ifdef CONFIG_IP_FIREWALL +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_ipfwin = { + PROC_NET_IPFWIN, 8, "ip_input", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_fw_in_procinfo +}; +static struct proc_dir_entry proc_net_ipfwout = { + PROC_NET_IPFWOUT, 9, "ip_output", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_fw_out_procinfo +}; +static struct proc_dir_entry proc_net_ipfwfwd = { + PROC_NET_IPFWFWD, 10, "ip_forward", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_fw_fwd_procinfo +}; +#endif +#endif + void ip_fw_init(void) { #ifdef CONFIG_PROC_FS #ifdef CONFIG_IP_ACCT - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPACCT, 7, "ip_acct", - S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, - 0, &proc_net_inode_operations, - ip_acct_procinfo - }); + proc_net_register(&proc_net_ipacct); #endif #endif #ifdef CONFIG_IP_FIREWALL @@ -1262,24 +1291,9 @@ panic("Unable to register IP firewall.\n"); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPFWIN, 8, "ip_input", - S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, - 0, &proc_net_inode_operations, - ip_fw_in_procinfo - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPFWOUT, 9, "ip_output", - S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, - 0, &proc_net_inode_operations, - ip_fw_out_procinfo - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPFWFWD, 10, "ip_forward", - S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, - 0, &proc_net_inode_operations, - ip_fw_fwd_procinfo - }); + proc_net_register(&proc_net_ipfwin); + proc_net_register(&proc_net_ipfwout); + proc_net_register(&proc_net_ipfwfwd); #endif #endif #ifdef CONFIG_IP_MASQUERADE diff -u --recursive --new-file v2.1.2/linux/net/ipv4/ip_masq.c linux/net/ipv4/ip_masq.c --- v2.1.2/linux/net/ipv4/ip_masq.c Thu Jun 6 16:23:49 1996 +++ linux/net/ipv4/ip_masq.c Wed Oct 9 20:11:11 1996 @@ -994,6 +994,15 @@ return len; } +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_ipmsqhst = { + PROC_NET_IPMSQHST, 13, "ip_masquerade", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_msqhst_procinfo +}; +#endif + /* * Initialize ip masquerading */ @@ -1001,12 +1010,7 @@ { register_symtab (&ip_masq_syms); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPMSQHST, 13, "ip_masquerade", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ip_msqhst_procinfo - }); + proc_net_register(&proc_net_ipmsqhst); #endif ip_masq_app_init(); diff -u --recursive --new-file v2.1.2/linux/net/ipv4/ip_masq_app.c linux/net/ipv4/ip_masq_app.c --- v2.1.2/linux/net/ipv4/ip_masq_app.c Fri Jun 28 18:49:55 1996 +++ linux/net/ipv4/ip_masq_app.c Wed Oct 9 20:11:11 1996 @@ -473,6 +473,15 @@ } +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_ip_masq_app = { + PROC_NET_IP_MASQ_APP, 11, "ip_masq_app", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_masq_app_getinfo +}; +#endif + /* * Initialization routine */ @@ -482,12 +491,7 @@ register_symtab (&ip_masq_app_syms); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IP_MASQ_APP, 11, "ip_masq_app", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ip_masq_app_getinfo - }); + proc_net_register(&proc_net_ip_masq_app); #endif return 0; } diff -u --recursive --new-file v2.1.2/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c --- v2.1.2/linux/net/ipv4/ip_output.c Tue Jul 9 14:28:32 1996 +++ linux/net/ipv4/ip_output.c Wed Oct 9 20:11:11 1996 @@ -1086,6 +1086,17 @@ 0 }; +#ifdef CONFIG_IP_MULTICAST +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_igmp = { + PROC_NET_IGMP, 4, "igmp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_mc_procinfo +}; +#endif +#endif + /* * IP registers the packet type and then calls the subprotocol initialisers */ @@ -1105,12 +1116,7 @@ #ifdef CONFIG_IP_MULTICAST #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IGMP, 4, "igmp", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ip_mc_procinfo - }); + proc_net_register(&proc_net_igmp); #endif #endif } diff -u --recursive --new-file v2.1.2/linux/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c --- v2.1.2/linux/net/ipv4/ipmr.c Fri Jul 19 08:24:05 1996 +++ linux/net/ipv4/ipmr.c Wed Oct 9 20:11:11 1996 @@ -913,6 +913,21 @@ return len; } +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_ipmr_vif = { + PROC_NET_IPMR_VIF, 9 ,"ip_mr_vif", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ipmr_vif_info +}; +static struct proc_dir_entry proc_net_ipmr_mfc = { + PROC_NET_IPMR_MFC, 11 ,"ip_mr_cache", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ipmr_mfc_info +}; +#endif + /* * Setup for IP multicast routing */ @@ -922,17 +937,7 @@ printk(KERN_INFO "Linux IP multicast router 0.06.\n"); register_netdevice_notifier(&ip_mr_notifier); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPMR_VIF, 9 ,"ip_mr_vif", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ipmr_vif_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPMR_MFC, 11 ,"ip_mr_cache", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ipmr_mfc_info - }); + proc_net_register(&proc_net_ipmr_vif); + proc_net_register(&proc_net_ipmr_mfc); #endif } diff -u --recursive --new-file v2.1.2/linux/net/ipv4/rarp.c linux/net/ipv4/rarp.c --- v2.1.2/linux/net/ipv4/rarp.c Thu Aug 1 15:43:04 1996 +++ linux/net/ipv4/rarp.c Wed Oct 9 20:11:11 1996 @@ -544,15 +544,17 @@ return len; } +struct proc_dir_entry proc_net_rarp = { + PROC_NET_RARP, 4, "rarp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rarp_get_info +}; + void rarp_init(void) { - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_RARP, 4, "rarp", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - rarp_get_info - }); + proc_net_register(&proc_net_rarp); rarp_ioctl_hook = rarp_ioctl; } diff -u --recursive --new-file v2.1.2/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- v2.1.2/linux/net/ipv4/tcp.c Wed Oct 9 08:55:24 1996 +++ linux/net/ipv4/tcp.c Thu Oct 10 08:51:22 1996 @@ -873,6 +873,8 @@ sk->socket->flags &= ~SO_NOSPACE; add_wait_queue(sk->sleep, &wait); for (;;) { + if (current->signal & ~current->blocked) + break; current->state = TASK_INTERRUPTIBLE; if (tcp_memory_free(sk)) break; @@ -930,6 +932,7 @@ skb->tail += copy; skb->len += copy; skb->csum = csum_partial(skb->tail - tcp_size, tcp_size, 0); + sk->write_seq += copy; if (!sk->packets_out) send = tcp_send_skb; send(sk, skb); @@ -1064,7 +1067,6 @@ from += retval; copied += retval; len -= retval; - sk->write_seq += retval; continue; } tcp_send_skb(sk, skb); diff -u --recursive --new-file v2.1.2/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c --- v2.1.2/linux/net/ipv4/tcp_input.c Wed Oct 9 08:55:24 1996 +++ linux/net/ipv4/tcp_input.c Thu Oct 10 16:19:56 1996 @@ -470,6 +470,7 @@ newsk->delay_acks = 1; newsk->copied_seq = skb->seq+1; newsk->fin_seq = skb->seq; + newsk->syn_seq = skb->seq; newsk->state = TCP_SYN_RECV; newsk->timeout = 0; newsk->ip_xmit_timeout = 0; @@ -1587,6 +1588,9 @@ * moved inline now as tcp_urg is only called from one * place. We handle URGent data wrong. We have to - as * BSD still doesn't use the correction from RFC961. + * + * For 1003.1g we should support a new option TCP_STDURG to permit + * either form. */ static void tcp_check_urg(struct sock * sk, struct tcphdr * th) @@ -1613,6 +1617,15 @@ kill_pg(-sk->proc, SIGURG, 1); } } + /* + * We may be adding urgent data when the last byte read was + * urgent. To do this requires some care. We cannot just ignore + * sk->copied_seq since we would read the last urgent byte again + * as data, nor can we alter copied_seq until this data arrives + * or we break the sematics of SIOCATMARK (and thus sockatmark()) + */ + if (sk->urg_seq == sk->copied_seq) + sk->copied_seq++; /* Move the copied sequence on correctly */ sk->urg_data = URG_NOTYET; sk->urg_seq = ptr; } @@ -1735,7 +1748,6 @@ { struct tcphdr *th; struct sock *sk; - int syn_ok=0; __u32 seq; #ifdef CONFIG_IP_TRANSPARENT_PROXY int r; @@ -1959,7 +1971,6 @@ * Ok.. it's good. Set up sequence numbers and * move to established. */ - syn_ok=1; /* Don't reset this connection for the syn */ sk->acked_seq = skb->seq+1; sk->lastwin_seq = skb->seq+1; sk->fin_seq = skb->seq; @@ -2074,10 +2085,21 @@ return tcp_reset(sk,skb); /* - * !syn_ok is effectively the state test in RFC793. + * Check for a SYN, and ensure it matches the SYN we were + * first sent. We have to handle the rather unusual (but valid) + * sequence that KA9Q derived products may generate of + * + * SYN + * SYN|ACK Data + * ACK (lost) + * SYN|ACK Data + More Data + * .. we must ACK not RST... + * + * We keep syn_seq as the sequence space occupied by the + * original syn. */ - if(th->syn && !syn_ok) + if(th->syn && skb->seq!=sk->syn_seq) { tcp_send_reset(daddr,saddr,th, &tcp_prot, opt, dev, skb->ip_hdr->tos, 255); return tcp_reset(sk,skb); diff -u --recursive --new-file v2.1.2/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c --- v2.1.2/linux/net/netrom/af_netrom.c Wed Aug 7 08:41:57 1996 +++ linux/net/netrom/af_netrom.c Wed Oct 9 20:11:11 1996 @@ -1401,6 +1401,27 @@ 0 }; +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_nr = { + PROC_NET_NR, 2, "nr", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + nr_get_info +}; +static struct proc_dir_entry proc_net_nr_neigh = { + PROC_NET_NR_NEIGH, 8, "nr_neigh", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + nr_neigh_get_info +}; +static struct proc_dir_entry proc_net_nr_nodes = { + PROC_NET_NR_NODES, 8, "nr_nodes", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + nr_nodes_get_info +}; +#endif + void nr_proto_init(struct net_proto *pro) { sock_register(nr_proto_ops.family, &nr_proto_ops); @@ -1418,24 +1439,9 @@ nr_default.paclen = NR_DEFAULT_PACLEN; #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_NR, 2, "nr", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - nr_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_NR_NEIGH, 8, "nr_neigh", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - nr_neigh_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_NR_NODES, 8, "nr_nodes", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - nr_nodes_get_info - }); + proc_net_register(&proc_net_nr); + proc_net_register(&proc_net_nr_neigh); + proc_net_register(&proc_net_nr_nodes); #endif } diff -u --recursive --new-file v2.1.2/linux/net/unix/af_unix.c linux/net/unix/af_unix.c --- v2.1.2/linux/net/unix/af_unix.c Wed Oct 9 08:55:24 1996 +++ linux/net/unix/af_unix.c Wed Oct 9 20:10:26 1996 @@ -1294,18 +1294,21 @@ unix_recvmsg }; +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry proc_net_unix = { + PROC_NET_UNIX, 4, "unix", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + unix_get_info +}; +#endif void unix_proto_init(struct net_proto *pro) { printk(KERN_INFO "NET3: Unix domain sockets 0.12 for Linux NET3.035.\n"); sock_register(unix_proto_ops.family, &unix_proto_ops); #ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_UNIX, 4, "unix", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - unix_get_info - }); + proc_net_register(&proc_net_unix); #endif } /*