]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.3 2.1.3
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:12:33 +0000 (15:12 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:12:33 +0000 (15:12 -0500)
58 files changed:
CREDITS
Makefile
arch/alpha/kernel/ksyms.c
arch/alpha/kernel/lca.c
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/process.c
arch/alpha/kernel/setup.c
arch/i386/kernel/ksyms.c
arch/i386/math-emu/errors.c
arch/i386/math-emu/exception.h
arch/i386/math-emu/fpu_asm.h
arch/i386/math-emu/fpu_proto.h
arch/i386/math-emu/reg_norm.S
arch/i386/math-emu/reg_round.S
arch/i386/mm/fault.c
drivers/block/md.c
drivers/char/misc.c
drivers/char/tpqic02.c
drivers/net/Config.in
drivers/net/Makefile
drivers/net/Space.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/ni65.h
drivers/net/ppp.c
drivers/net/tulip.c
fs/buffer.c
fs/namei.c
fs/proc/base.c
fs/proc/root.c
include/asm-alpha/jensen.h
include/asm-alpha/processor.h
include/asm-alpha/segment.h
include/asm-i386/io.h
include/asm-i386/processor.h
include/asm-i386/segment.h
include/asm-i386/user.h
include/linux/mm.h
include/net/sock.h
kernel/ksyms.c
mm/memory.c
net/appletalk/ddp.c
net/ax25/af_ax25.c
net/core/dev.c
net/core/net_alias.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/ip_forward.c
net/ipv4/ip_fw.c
net/ipv4/ip_masq.c
net/ipv4/ip_masq_app.c
net/ipv4/ip_output.c
net/ipv4/ipmr.c
net/ipv4/rarp.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/netrom/af_netrom.c
net/unix/af_unix.c

diff --git a/CREDITS b/CREDITS
index bf5d5539de16ecd134a2ebba3cca4dca5768dfd9..88ee58ac4cf9ed41efcb0fa32ff9d42cc99cdc94 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -285,6 +285,7 @@ S: United Kingdom
 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
index 8a45dad1f69392ca956c6a2917b5e0b9ac8361ff..3da7404746b1994b580936cbffdfc39f3016db0e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 2
+SUBLEVEL = 3
 
 ARCH = i386
 
index 78d22e669fe8d164795e05514b3638c0a35e5b81..9b9e19e46a38902a9705513cf935ecf72aced8c4 100644 (file)
@@ -54,10 +54,12 @@ static struct symbol_table arch_symbol_table = {
        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),
index 2030efc4c4b0e3dd6eb864296cfb5ddd55a94c18..7dcc5506fb21b4e9adc4f7fb7a44c3f91712bda4 100644 (file)
@@ -429,7 +429,7 @@ void lca_machine_check (unsigned long vector, unsigned long la, struct pt_regs *
        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);
index 0f09b52239751e04d0bf581e109e010f41c0da4b..7494dbc1195151de0b27ebcd1a815ea148d453b9 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
 #include <linux/malloc.h>
-#include <linux/ldt.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
 #include <linux/utsname.h>
index 47fdf8e8b93ba6621890ceb85db70777a9d45600..371afdaa51409ae2ae21d6503fe37cf1b6ff15fa 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
 #include <linux/malloc.h>
-#include <linux/ldt.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
 #include <linux/utsname.h>
index 7ad7c41ab0817557ee01012cd41cf37b9744e78e..7ffde4a197f642aa2548c261009ec75abd23d83d 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
 #include <linux/malloc.h>
-#include <linux/ldt.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
 #include <linux/tty.h>
index 4b1cc1c7ab89d6f3e8d2e7f0f9f1c2930ea3eda6..bda62566b5f1394ef26587945bc6687bafca3866 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/elfcore.h>
 
 #include <asm/semaphore.h>
+#include <asm/processor.h>
 #include <asm/io.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
@@ -12,6 +13,8 @@ extern int dump_fpu(elf_fpregset_t *);
 static struct symbol_table arch_symbol_table = {
 #include <linux/symtab_begin.h>
        /* platform dependent support */
+       X(EISA_bus),
+       X(wp_works_ok),
        X(dump_thread),
        X(dump_fpu),
        X(ioremap),
index 37c5be76971c959b37dd53877150b457a35f8288..a01048a04e16efc2218ebf51fc21c41bf87a9c03 100644 (file)
@@ -292,7 +292,7 @@ static struct {
              0x242  in div_Xsig.S
  */
 
-void exception(int n)
+void FPU_exception(int n)
 {
   int i, int_type;
 
@@ -482,7 +482,7 @@ int set_precision_flag(int flags)
     }
   else
     {
-      exception(flags);
+      EXCEPTION(flags);
       return 1;
     }
 }
@@ -494,7 +494,7 @@ asmlinkage void set_precision_flag_up(void)
   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 @@ asmlinkage void set_precision_flag_down(void)
       partial_status |= SW_Precision;
     }
   else
-    exception(EX_Precision);
+    EXCEPTION(EX_Precision);
 }
 
 
@@ -521,7 +521,7 @@ asmlinkage int denormal_operand(void)
     }
   else
     {
-      exception(EX_Denormal);
+      EXCEPTION(EX_Denormal);
       return 1;
     }
 }
index b4e6fe07a97ed1014c7a001882505731848bd47a..b90e5e9c3bd490912b80802d9e676526773e781f 100644 (file)
@@ -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__
index de85ce66dfc48846ddabcc40456b7a6af76c72e5..d08fbc874bc7d61434722babd4e1c596b65dcf94 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/linkage.h>
 
-#define        EXCEPTION       SYMBOL_NAME(exception)
+#define        EXCEPTION       SYMBOL_NAME(FPU_exception)
 
 
 #define PARAM1 8(%ebp)
index b4392fe57de70085683089739547a52c2fe86bea..d0e58ed0ea093fca803df1f910a86658755ab969 100644 (file)
@@ -7,7 +7,7 @@ extern void stack_underflow(void);
 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);
index d2bd59cffd912a9caef212c91157373c7ae19879..781a2d4669ee89e58e7fe0dbfe563f8894a19a2d 100644 (file)
@@ -30,7 +30,7 @@ ENTRY(normalize)
        je      L_ok
 
        pushl   $0x220
-       call    SYMBOL_NAME(exception)
+       call    SYMBOL_NAME(FPU_exception)
        addl    $4,%esp
 
 L_ok:
@@ -107,7 +107,7 @@ ENTRY(normalize_nuo)
        je      L_ok_nuo
 
        pushl   $0x221
-       call    SYMBOL_NAME(exception)
+       call    SYMBOL_NAME(FPU_exception)
        addl    $4,%esp
 
 L_ok_nuo:
index 2cbb26780fb1123a5e27cc2a6ed343202a0b14fb..4aac507a10640ac95fe054cd05f70efeda5ca60a 100644 (file)
@@ -596,7 +596,7 @@ LNormalise_shift_done:
        /* 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 @@ L_underflow_to_zero:
 
        push    %eax
        pushl   EX_Underflow
-       call    SYMBOL_NAME(exception)
+       call    SYMBOL_NAME(FPU_exception)
        popl    %eax
        popl    %eax
 
index 34cb13c2ae05278f224aef0d8accf003f11d5d56..77dd31bbf9719e275a98ac81b8c8138d9f0ff0ad 100644 (file)
 
 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
index e4352de7c40f9a72f8ba22acfc04e914c5e93f0a..2243256b9586223942daa5bdaacad4c0f0ed32c0 100644 (file)
@@ -439,6 +439,10 @@ static struct symbol_table md_symbol_table=
 #include <linux/symtab_end.h>
 };
 
+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 @@ static void md_geninit (struct gendisk *gdisk)
   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);
 }
 
 
index d44c30e77f33f125b97ddab72ce348b897a30624..3614ee4ae172ac24856fb0c6ebe6d67b1629d062 100644 (file)
@@ -184,16 +184,18 @@ static struct symbol_table misc_syms = {
 #include <linux/symtab_end.h>
 };
 
+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();
index ddc22562e7060870594a26b124c499865e9af952..49234d8cba7570b47484dedb91ac7b12aaf7c531 100644 (file)
@@ -471,12 +471,12 @@ static void ifc_init(void)
 } /* 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 @@ static void report_exception(unsigned n)
  * 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 @@ static int decode_exception_nr(unsigned s)
                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 @@ static void report_error(int s)
 /* 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 @@ static void handle_exception(int exnr, int exbits)
                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 @@ static int tp_sense(int ignore)
 
        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)) ||
index 5aa7516c8e7ae050aaf99719c998f1e3d2b42589..d508a3c612c77e8982cf8660ac46c037a5dec8cc 100644 (file)
@@ -82,10 +82,8 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
       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
index 7967de6b86700efb28ffe02cd2cd2555b1c69951..e1fca14c470e5cd138ee5069a4316571380e902d 100644 (file)
@@ -360,6 +360,10 @@ endif
 
 ifeq ($(CONFIG_NI65),y)
 L_OBJS += ni65.o
+else
+  ifeq ($(CONFIG_NI65),m)
+  M_OBJS += ni65.o
+  endif
 endif
 
 ifeq ($(CONFIG_ELPLUS),y)
index c28bec6c034b29108e61db5f9725d5d37353f05c..6237c609efd8955262697ba18a139d12ebb37f62 100644 (file)
@@ -195,6 +195,9 @@ ethif_probe(struct device *dev)
 #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
index ecd11c1fba4b97256477578ba656d6f71c049abf..18ef6949fc0740f8ec461b6ad3d2f1c76a92aa0e 100644 (file)
@@ -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 @@ static int fifo=0x8;        /* don't change */
 #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 @@ static int check586(struct device *dev,char *where,unsigned size)
   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;i<sizeof(struct scp_struct);i++) /* memory was writeable? */
@@ -296,7 +299,7 @@ static int check586(struct device *dev,char *where,unsigned size)
   if(p->scp->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 @@ void alloc586(struct device *dev)
   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 @@ static int ni52_probe1(struct device *dev,int ioaddr)
                                   /* 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 */
index 725162adb942c571cfcdf12d75e296d033bbdccf..75e891477d228beb4c7afddbc47549dd9b1d9205 100644 (file)
@@ -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.
  *   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 <linux/kernel.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <linux/version.h>
+#include <linux/module.h>
+
 #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 priv
   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;i<TMDNUM;i++)
+    {
+      if(p->tmd_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" );
+  for(i=0;i<NUM_CARDS;i++) {
+    if(check_region(ioaddr, cards[i].total_size))
+      continue;
+    if(cards[i].id_offset >= 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;
+  }
+  if(i == NUM_CARDS)
     return -ENODEV;
+
+  for(j=0;j<6;j++)
+    dev->dev_addr[j] = inb(ioaddr+cards[i].addr_offset+j);
+
+  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;
   }
 
-  if(!dev) {
-    dev = init_etherdev(0,0);
-    *dev1 = dev;
+  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;
   }
-  dev->base_addr = ioaddr;
 
-  for(i=0;i<6;i++)
-    dev->dev_addr[i] = inb(PORT+L_EBASE+i);
-
-  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(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 @@ static int ni65_probe1(struct device **dev1,int ioaddr)
   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;i<TMDNUM;i++)
   {
-    if( (ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA )) == NULL) {
-      printk("%s: Can't alloc Xmit-Mem.\n",dev->name);
+#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;i<RMDNUM;i++)
+  {
+#ifdef RCV_VIA_SKB
+    p->recv_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;i<TMDNUM;i++) {
+    if(p->tmdbounce[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;i<RMDNUM;i++)
+  {
 #ifdef RCV_VIA_SKB
-   for(i=0;i<RMDNUM;i++)
-   {
-     struct sk_buff *skb;
-     if( !(skb = dev_alloc_skb(R_BUF_SIZE+2)) ) {
-       printk("%s: unable to alloc recv-mem\n",dev->name);
-       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;i<RMDNUM;i++)
-   {
-     if( !(p->recvbounce[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);
+}
+
 
-  return 0; /* we've found everything */
+/*
+ * 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];
+
+    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;i<TMDNUM;i++) {
+      struct tmd *tmdp = p->tmdhead + 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;i<RMDNUM;i++) {
+      struct rmd *rmdp = p->rmdhead + i;
+      rmdp->u.s.status = RCV_OWN;
+    }
+    p->tmdnum = p->xmit_queued = 0;
+    writedatareg(CSR0_STRT | csr0);
+
+    for(i=0;i<TMDNUM;i++) {
+      int num = (i + p->tmdlast) & (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 @@ static int ni65_am7990_reinit(struct device *dev)
    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;i<TMDNUM;i++)
    {
      struct tmd *tmdp = p->tmdhead + i;
@@ -386,66 +752,40 @@ static int ni65_am7990_reinit(struct device *dev)
      tmdp->blen = tmdp->status2 = 0;
    }
 
-   p->rmdnum = 0;
    for(i=0;i<RMDNUM;i++)
    {
      struct rmd *rmdp = p->rmdhead + 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 @@ static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
   int csr0;
   struct device *dev = (struct device *) irq2dev_map[irq];
+  struct priv *p;
   int bcnt = 32;
 
   if (dev == NULL) {
@@ -462,62 +803,104 @@ static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs)
     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;i<RMDNUM;i++)
+          printk("%02x ",p->rmdhead[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;j<RMDNUM;j++)
+ {
   struct priv *p = (struct priv *) dev->priv;
-  int i,f=0;
-  for(i=0;i<RMDNUM;i++) {
-     struct rmd *rmdp = p->rmdhead + ((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;k<RMDNUM;k++) {
+      num1 = (p->rmdnum + 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;k<RMDNUM;k++) {
+        sprintf(buf1,"%02x ",(p->rmdhead[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 @@ static void ni65_xmit_intr(struct device *dev,int csr0)
     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 @@ static void ni65_xmit_intr(struct device *dev,int csr0)
       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 @@ static void ni65_xmit_intr(struct device *dev,int csr0)
 /*
  * 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 @@ static void ni65_recv_intr(struct device *dev,int csr0)
         }
       }
       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 @@ static void ni65_recv_intr(struct device *dev,int csr0)
           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 @@ static void ni65_recv_intr(struct device *dev,int csr0)
         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 @@ static int ni65_send_packet(struct sk_buff *skb, struct device *dev)
   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;i<TMDNUM;i++)
+    printk("%02x ",p->tmdhead[i].u.s.status);
+  printk("\n");
+}
+    ni65_lance_reinit(dev);
     dev->tbusy=0;
     dev->trans_start = jiffies;
   }
@@ -708,28 +1105,37 @@ static int ni65_send_packet(struct sk_buff *skb, struct device *dev)
 
   {
     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 int ni65_send_packet(struct sk_buff *skb, struct device *dev)
 
 static struct enet_statistics *ni65_get_stats(struct device *dev)
 {
+
+#if 0
+ int i;
+ struct priv *p = (struct priv *) dev->priv;
+ for(i=0;i<RMDNUM;i++) {
+   struct rmd *rmdp = p->rmdhead + ((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 
  */
 
+
index 37e2fe0167b4e7314789685e2d4f9035510af19c..64380951e5aff70aad804dba47c0a139253df4ca 100644 (file)
@@ -92,23 +92,23 @@ struct init_block
   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 @@ struct tmd
 {
   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;
 };
 
index ca6a789e94d6dd20c052c79a57f84496ed912734..7f2b1583eaa5f3a22181cc04597d1dfdb5f535c4 100644 (file)
@@ -3080,6 +3080,14 @@ ppp_dev_xmit (sk_buff *skb, struct device *dev)
  */
        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.
index 6ba513daeb3dd05d85579bbe089cd64a0e9b6012..822bf129e79fae8df374e8468749d0df8a889252 100644 (file)
@@ -1096,7 +1096,7 @@ static void set_multicast_list(struct device *dev)
                /* 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 @@ static void set_multicast_list(struct device *dev)
                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 @@ static void set_multicast_list(struct device *dev)
                }
                /* 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. */
        }
index d482b0ebd6757d9b4734aea1a7fcb7c6f5d68443..7aca6472de66d0b0277d8ee9a824f07b85c362bf 100644 (file)
@@ -156,77 +156,66 @@ repeat:
 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;
 }
 
index cb02d2c4fe734a9bab839bc34d745ee2d7811740..ec19c99ef5a4f6c9330d680c293eef069ce3ebe3 100644 (file)
 
 #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
@@ -51,38 +27,60 @@ static inline int get_max_filename(unsigned long address)
  *
  * 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;
-
-       i = get_max_filename((unsigned long) filename);
-       if (i < 0)
-               return i;
-       error = -EFAULT;
-       if (!i) {
-               error = -ENAMETOOLONG;
-               i = PAGE_SIZE;
-       }
-       c = get_user(filename++);
+       int error, maxlen = PAGE_SIZE;
+       int c;
+
+       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 = (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);
index a2a933f78844722a0eb44537b2f90926dcb04bed..dc781cbb526d42bc33b9a629819fa2b18651edcf 100644 (file)
@@ -80,72 +80,83 @@ struct proc_dir_entry proc_pid = {
        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);
 };
index 962f428a0a1648ab65448b660639eb5a42efce1e..d2ff1671d1e60ca8c08b93446a710304311af0ff 100644 (file)
@@ -250,6 +250,114 @@ static struct inode_operations proc_self_inode_operations = {
        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 @@ void proc_root_init(void)
                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,
-       });
+       proc_register(&proc_root, &proc_root_pci);
 #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_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,
-       });
+       proc_register(&proc_root, &proc_root_malloc);
 #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_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,
-       });
+       proc_register(&proc_root, &proc_root_modules);
+       proc_register(&proc_root, &proc_root_ksyms);
 #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_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,
-       });
+       proc_register(&proc_root, &proc_root_rtc);
 #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_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);
        }
 }
 
index 55236faccecb9b8e630fe1b8cded1f7b36c101be..7a3b0785143ef53207eba8c26447a596b8b1e667 100644 (file)
@@ -95,6 +95,8 @@ extern inline void __set_hae(unsigned long addr)
                set_hae(addr);
 }
 
+#ifdef __KERNEL__
+
 /*
  * IO functions
  *
@@ -259,6 +261,8 @@ extern inline void __writel(unsigned int b, unsigned long addr)
 #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
  * the RTC clock at 0x170 instead of 0x70. Probably due to some
index 4cc21418ecd316e8d91d847a1188faebb869b2bd..abed5d2a197849e913aa77a3d4e8a70970ac7a2d 100644 (file)
 #define MCA_bus 0
 #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)
index ac7d1a376effd4940358883361e3b8056250deed..d0fd86f1c88b35727989766918bf96acc2aab090 100644 (file)
@@ -51,4 +51,7 @@ static inline unsigned long get_ds(void)
        return 0;
 }
 
+/* Hardware write protection */
+#define verify_write(type, addr, size) 0
+
 #endif /* _ASM_SEGMENT_H */
index 5e75e8ab99d8cab573159fc05ff933b20b54f7ad..142662e94278e99ddf868c71f546cb177f9dca89 100644 (file)
 #define SLOW_DOWN_IO __SLOW_DOWN_IO
 #endif
 
-#include <asm/page.h>
-
-#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 @@ __OUTS(l)
        __inlc_p(port) : \
        __inl_p(port))
 
+#ifdef __KERNEL__
+
+#include <asm/page.h>
+
+#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)
 {
@@ -232,4 +234,6 @@ out:
        return retval;
 }
 
+#endif /* __KERNEL__ */
+
 #endif
index 0080c8e529beb51f742408a374033809ae750963..b82fb6a14da67d01b9f0fde99c815e14eb5e7049 100644 (file)
@@ -33,7 +33,6 @@ extern int  have_cpuid;               /* We have a CPUID */
  */
 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,
index 8cd7fdebed8ddf25c025c834116933f671f1810f..ee9612f2e94c7100fe4fc020218e63478a1434ce 100644 (file)
 #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 */
index f0e1f886b0049510db94a7c83038f5772921ab3a..b5acf0e745c7af24bb25675376f33d68f9b0d318 100644 (file)
@@ -43,7 +43,7 @@ struct user_i387_struct {
 
 /*
  * 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)
  */
index 4a0f401b00ae7eed6b09d74d9e51f559291eac03..338c68e95906d1a271bff75bef97674258c5a8b7 100644 (file)
@@ -19,11 +19,6 @@ extern void * high_memory;
 #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;
index b4bed7c3bd0c935b930f3fdb4a2f320d81fe86ad..8a7c602f700271043a66453c6a36e6fdcaff8857 100644 (file)
@@ -167,6 +167,7 @@ struct sock
        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 */
index 38d01794f6bff4f9699e0737c52dcef223ab325a..0d7ada27a6c952f5fdef48e6cd14524fbd3d17c8 100644 (file)
@@ -92,18 +92,6 @@ struct symbol_table symbol_table = {
 #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),
index e50d8e79141a522f802ab4c25275ed96b9dcfbea..17c5f1c42e1fb03ff9d91aa2cee359eeeb6f0a2e 100644 (file)
@@ -675,57 +675,6 @@ end_wp_page:
        return;
 }
 
-/*
- * 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..
  */
index f212a182c2e0cc66c317d895fbdfd36796fc5a9a..8acef20ed2c4538d6bb4adaec16dd7656e58de62 100644 (file)
@@ -2006,6 +2006,26 @@ struct packet_type ppptalk_packet_type=
 
 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 @@ void atalk_proto_init(struct net_proto *pro)
        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");
index ece3534f461baf8a51b7c5e0e0ab3e238cc74ea8..34f17f8ae004e8435bad5157eb3f65e37125c106 100644 (file)
@@ -2365,6 +2365,35 @@ static struct notifier_block ax25_dev_notifier = {
        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 @@ void ax25_proto_init(struct net_proto *pro)
 #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
index deff3f01a96d97da4c0264df1351adc2062e0690..b803c6130dc08b3e7cc64930937f30b388911342 100644 (file)
@@ -1369,6 +1369,15 @@ extern int pi_init(void);
 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 @@ int net_dev_init(void)
 #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 @@ int net_dev_init(void)
        }
 
 #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
 
        /*      
index 03095567f73a0ce3a8105ee6c4d33258f78db8b0..35830370544de7e85465dd7ae4a4fa9322c467c9 100644 (file)
@@ -1278,6 +1278,22 @@ static struct notifier_block net_alias_dev_notifier = {
   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 @@ void net_alias_init(void)
   
 #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
   
index 4dd4be0552a85c6c2eea17a272c03414922a343c..5621ac3d30a11bee44447a1ad741909cd3d2c6bd 100644 (file)
@@ -1593,6 +1593,59 @@ static struct proto_ops inet_proto_ops = {
 
 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 @@ void inet_proto_init(struct net_proto *pro)
 #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 */
 }
index b21d84b4e34a183d16765c332ea742d4befd3a93..b6bbf9f14506558d18512319110b9f3e25dba4c4 100644 (file)
@@ -2389,6 +2389,15 @@ static struct notifier_block arp_dev_notifier={
        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 @@ void arp_init (void)
        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
index 1d53c61678d20772180d030aac262dbbd567cede..eaa74a6387d62ded61bc2d09ec75d0ec414a5327 100644 (file)
@@ -264,8 +264,12 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag,
                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 */
index 37092157fa2a29e511d7d84ee3504cd3c89dd943..f2ed0760db315f23b965e32e2c0c1535e7e78c68 100644 (file)
@@ -1244,16 +1244,45 @@ static struct notifier_block ipfw_dev_notifier={
 
 #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 @@ void ip_fw_init(void)
                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
index 5505a6fd5951743e2ff827c5906ed6d39efff698..e33a0dd91ec4840132c4e1e967a564cbd761315e 100644 (file)
@@ -994,6 +994,15 @@ done:
        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 @@ int ip_masq_init(void)
 {
         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();
 
index 340d4ddd4f73507077dc9bb0c6f9f4ec6ed080b7..a3ef3db6490db7ce578601a9d5e491659abfb600 100644 (file)
@@ -473,6 +473,15 @@ done:
 }
 
 
+#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 @@ int ip_masq_app_init(void)
         
         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;
 }
index 5449ada552142bbfcc3258b9677c9640799a7d23..4034846d44180c1e05595fbe42bc8e3148097962 100644 (file)
@@ -1086,6 +1086,17 @@ struct notifier_block ip_rt_notifier={
        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 @@ void ip_init(void)
 
 #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
 }
index fbe02394b0c093983e722df0a9fa0c2c26833cda..6c7b85a8e7d2a5a9674ebb88868133f5bc380250 100644 (file)
@@ -913,6 +913,21 @@ done:
        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 @@ void ip_mr_init(void)
        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 
 }
index 8bffc8cb78175b1b08b7330c7869404ecc6c1748..d0bf56a28c6485542593cdea996919800dd6b931 100644 (file)
@@ -544,15 +544,17 @@ int rarp_get_info(char *buffer, char **start, off_t offset, int length, int dumm
        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;
 }
 
index 06047de205802d0a6410646fc8a3852291c5e5e2..cd38acef8f8d68e7b1e8d401f38066a2ecdb768b 100644 (file)
@@ -873,6 +873,8 @@ static void wait_for_tcp_memory(struct sock * sk)
                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 @@ static int fill_in_partial_skb(struct sock *sk, struct sk_buff *skb,
        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 @@ static int do_tcp_sendmsg(struct sock *sk,
                                        from += retval;
                                        copied += retval;
                                        len -= retval;
-                                       sk->write_seq += retval;
                                        continue;
                                }
                                tcp_send_skb(sk, skb);
index 179559551304c35e54b3b73892275ea71fca4fe7..cb615e001be6a86fc85327ac73fdbf1c6de432a7 100644 (file)
@@ -470,6 +470,7 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
        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 @@ static int tcp_data(struct sk_buff *skb, struct sock *sk,
  *     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 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
                        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 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
 {
        struct tcphdr *th;
        struct sock *sk;
-       int syn_ok=0;
        __u32 seq;
 #ifdef CONFIG_IP_TRANSPARENT_PROXY
        int r;
@@ -1959,7 +1971,6 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
                                 *      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 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
                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);       
index 79976f4e245a3da2b4677b677019fa99b01a088b..918f7d40b5a102b5b800f936cfd45c4393d04d22 100644 (file)
@@ -1401,6 +1401,27 @@ static struct notifier_block nr_dev_notifier = {
        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 @@ void nr_proto_init(struct net_proto *pro)
        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 
 }
 
index 37cf7acb575c7624deb5f6adfda0bb183969c9d3..34d9245d648f7f409a145ca7c3c920ead3e02baa 100644 (file)
@@ -1294,18 +1294,21 @@ struct proto_ops unix_proto_ops = {
        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
 }
 /*