diff -u --recursive --new-file v1.3.5/linux/Makefile linux/Makefile
--- v1.3.5/linux/Makefile	Thu Jun 29 19:02:38 1995
+++ linux/Makefile	Thu Jun 29 18:26:57 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 5
+SUBLEVEL = 6
 
 ARCH = i386
 
@@ -113,7 +113,7 @@
 .c.o:
 	$(CC) $(CFLAGS) -c -o $*.o $<
 .S.s:
-	$(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $<
+	$(CC) -D__ASSEMBLY__ -traditional -E -o $*.s $<
 .S.o:
 	$(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $<
 
diff -u --recursive --new-file v1.3.5/linux/arch/i386/config.in linux/arch/i386/config.in
--- v1.3.5/linux/arch/i386/config.in	Thu Jun 29 19:02:39 1995
+++ linux/arch/i386/config.in	Thu Jun 29 20:34:50 1995
@@ -168,15 +168,15 @@
 		bool 'EtherExpress support' CONFIG_EEXPRESS n
 		bool 'NI5210 support' CONFIG_NI52 n
 		bool 'NI6510 support' CONFIG_NI65 n
+		if [ "$CONFIG_AX25" = "y" ]; then
+			bool 'Ottawa PI and PI/2 support' CONFIG_PI y
+		fi
 		bool 'WaveLAN support' CONFIG_WAVELAN n
 	fi
 	bool 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS n
 	bool 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN n
 	bool 'HP 10/100VG PCLAN (257X series) support' CONFIG_HP100 y
 	bool 'NE2000/NE1000 support' CONFIG_NE2000 y
-	if [ "$CONFIG_AX25" = "y" ]; then
-		bool 'Ottawa PI and PI/2 support' CONFIG_PI y
-	fi
 	bool 'SK_G16 support' CONFIG_SK_G16 n
 fi
 bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
diff -u --recursive --new-file v1.3.5/linux/arch/i386/lib/checksum.c linux/arch/i386/lib/checksum.c
--- v1.3.5/linux/arch/i386/lib/checksum.c	Fri Jun 16 22:02:54 1995
+++ linux/arch/i386/lib/checksum.c	Thu Jun 29 19:18:49 1995
@@ -7,6 +7,7 @@
  *
  * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
  *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
  *		Lots of code moved from tcp.c and ip.c; see those files
  *		for more names.
  *
@@ -23,62 +24,74 @@
  */
 
 unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum) {
-#ifdef __i386__
+	  /*
+	   * Experiments with ethernet and slip connections show that buff
+	   * is aligned on either a 2-byte or 4-byte boundary.  We get at
+	   * least a 2x speedup on 486 and Pentium if it is 4-byte aligned.
+	   * Fortunately, it is easy to convert 2-byte alignment to 4-byte
+	   * alignment for the unrolled loop.
+	   */
 	__asm__("
+	    testl $2, %%esi		# Check alignment.
+	    jz 2f			# Jump if alignment is ok.
+	    subl $2, %%ecx		# Alignment uses up two bytes.
+	    jae 1f			# Jump if we had at least two bytes.
+	    addl $2, %%ecx		# ecx was < 2.  Deal with it.
+	    jmp 4f
+1:	    movw (%%esi), %%bx
+	    addl $2, %%esi
+	    addw %%bx, %%ax
+	    adcl $0, %%eax
+2:
 	    movl %%ecx, %%edx
-	    cld
 	    shrl $5, %%ecx
 	    jz 2f
-	    orl %%ecx, %%ecx
-1:	    movl (%%esi), %%eax
-	    adcl %%eax, %%ebx
-	    movl 4(%%esi), %%eax
-	    adcl %%eax, %%ebx
-	    movl 8(%%esi), %%eax
-	    adcl %%eax, %%ebx
-	    movl 12(%%esi), %%eax
-	    adcl %%eax, %%ebx
-	    movl 16(%%esi), %%eax
-	    adcl %%eax, %%ebx
-	    movl 20(%%esi), %%eax
-	    adcl %%eax, %%ebx
-	    movl 24(%%esi), %%eax
-	    adcl %%eax, %%ebx
-	    movl 28(%%esi), %%eax
-	    adcl %%eax, %%ebx
+	    testl %%esi, %%esi
+1:	    movl (%%esi), %%ebx
+	    adcl %%ebx, %%eax
+	    movl 4(%%esi), %%ebx
+	    adcl %%ebx, %%eax
+	    movl 8(%%esi), %%ebx
+	    adcl %%ebx, %%eax
+	    movl 12(%%esi), %%ebx
+	    adcl %%ebx, %%eax
+	    movl 16(%%esi), %%ebx
+	    adcl %%ebx, %%eax
+	    movl 20(%%esi), %%ebx
+	    adcl %%ebx, %%eax
+	    movl 24(%%esi), %%ebx
+	    adcl %%ebx, %%eax
+	    movl 28(%%esi), %%ebx
+	    adcl %%ebx, %%eax
 	    lea 32(%%esi), %%esi
 	    dec %%ecx
 	    jne 1b
-	    adcl $0, %%ebx
+	    adcl $0, %%eax
 2:	    movl %%edx, %%ecx
-	    andl $28, %%ecx
+	    andl $0x1c, %%edx
 	    je 4f
-	    shrl $2, %%ecx
-	    orl %%ecx, %%ecx
-3:	    adcl (%%esi), %%ebx
+	    shrl $2, %%edx
+	    testl %%esi, %%esi
+3:	    adcl (%%esi), %%eax
 	    lea 4(%%esi), %%esi
-	    dec %%ecx
+	    dec %%edx
 	    jne 3b
-	    adcl $0, %%ebx
-4:	    movl $0, %%eax
-	    testw $2, %%dx
-	    je 5f
-	    lodsw
-	    addl %%eax, %%ebx
-	    adcl $0, %%ebx
-	    movw $0, %%ax
-5:	    test $1, %%edx
+	    adcl $0, %%eax
+4:	    andl $3, %%ecx
+	    jz 7f
+	    cmpl $2, %%ecx
+	    jb 5f
+	    movw (%%esi),%%cx
+	    leal 2(%%esi),%%esi
 	    je 6f
-	    lodsb
-	    addl %%eax, %%ebx
-	    adcl $0, %%ebx
-6:	    "
-	: "=b"(sum)
+	    shll $16,%%ecx
+5:	    movb (%%esi),%%cl
+6:	    addl %%ecx,%%eax
+	    adcl $0, %%eax
+7:	    "
+	: "=a"(sum)
 	: "0"(sum), "c"(len), "S"(buff)
-	: "ax", "bx", "cx", "dx", "si" );
-#else
-#error Not implemented for this CPU
-#endif
+	: "bx", "cx", "dx", "si");
 	return(sum);
 }
 
@@ -90,90 +103,93 @@
 
 unsigned int csum_partial_copyffs( char *src, char *dst, 
 				  int len, int sum) {
-#ifdef __i386__
     __asm__("
-	push %%ds
-	push %%es
-	movw %%ds, %%dx
-	movw %%dx, %%es
-	movw %%fs, %%dx
-	movw %%dx, %%ds
-	cld
-	cmpl $32, %%ecx
-	jb 2f
-	pushl %%ecx
+	testl $2, %%edi		# Check alignment.
+	jz 2f			# Jump if alignment is ok.
+	subl $2, %%ecx		# Alignment uses up two bytes.
+	jae 1f			# Jump if we had at least two bytes.
+	addl $2, %%ecx		# ecx was < 2.  Deal with it.
+	jmp 4f
+1:	movw %%fs:(%%esi), %%bx
+	addl $2, %%esi
+	movw %%bx, (%%edi)
+	addl $2, %%edi
+	addw %%bx, %%ax
+	adcl $0, %%eax
+2:
+	movl %%ecx, %%edx
 	shrl $5, %%ecx
-	orl %%ecx, %%ecx
-1:	movl (%%esi), %%eax
-	movl 4(%%esi), %%edx
-	adcl %%eax, %%ebx
-	movl %%eax, %%es:(%%edi)
-	adcl %%edx, %%ebx
-	movl %%edx, %%es:4(%%edi)
-
-	movl 8(%%esi), %%eax
-	movl 12(%%esi), %%edx
-	adcl %%eax, %%ebx
-	movl %%eax, %%es:8(%%edi)
-	adcl %%edx, %%ebx
-	movl %%edx, %%es:12(%%edi)
-
-	movl 16(%%esi), %%eax
-	movl 20(%%esi), %%edx
-	adcl %%eax, %%ebx
-	movl %%eax, %%es:16(%%edi)
-	adcl %%edx, %%ebx
-	movl %%edx, %%es:20(%%edi)
-
-	movl 24(%%esi), %%eax
-	movl 28(%%esi), %%edx
-	adcl %%eax, %%ebx
-	movl %%eax, %%es:24(%%edi)
-	adcl %%edx, %%ebx
-	movl %%edx, %%es:28(%%edi)
+	jz 2f
+	testl %%esi, %%esi
+1:	movl %%fs:(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, (%%edi)
+
+	movl %%fs:4(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 4(%%edi)
+
+	movl %%fs:8(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 8(%%edi)
+
+	movl %%fs:12(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 12(%%edi)
+
+	movl %%fs:16(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 16(%%edi)
+
+	movl %%fs:20(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 20(%%edi)
+
+	movl %%fs:24(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 24(%%edi)
+
+	movl %%fs:28(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 28(%%edi)
 
 	lea 32(%%esi), %%esi
 	lea 32(%%edi), %%edi
 	dec %%ecx
 	jne 1b
-	adcl $0, %%ebx
-	popl %%ecx
-2:	movl %%ecx, %%edx
-	andl $28, %%ecx
+	adcl $0, %%eax
+2:	movl %%edx, %%ecx
+	andl $28, %%edx
 	je 4f
-	shrl $2, %%ecx
-	orl %%ecx, %%ecx
-3:	movl (%%esi), %%eax
-	adcl %%eax, %%ebx
-	movl %%eax, %%es:(%%edi)
+	shrl $2, %%edx
+	testl %%esi, %%esi
+3:	movl %%fs:(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, (%%edi)
 	lea 4(%%esi), %%esi
 	lea 4(%%edi), %%edi
-	dec %%ecx
+	dec %%edx
 	jne 3b
-	adcl $0, %%ebx
-4:	movl $0, %%eax
-	testl $2, %%edx
-	je 5f
-	lodsw
-	stosw
-	addl %%eax, %%ebx
-	movw $0, %%ax
-	adcl %%eax, %%ebx
-5:	test $1, %%edx
+	adcl $0, %%eax
+4:	andl $3, %%ecx
+	jz 7f
+	cmpl $2, %%ecx
+	jb 5f
+	movw %%fs:(%%esi), %%dx
+	leal 2(%%esi), %%esi
+	movw %%dx, (%%edi)
+	leal 2(%%edi), %%edi
 	je 6f
-	lodsb
-	stosb
-	addl %%eax, %%ebx
-	adcl $0, %%ebx
-6:	pop %%es
-	pop %%ds
+	shll $16,%%edx
+5:	movb %%fs:(%%esi), %%dl
+	movb %%dl, (%%edi)
+6:	addl %%edx, %%eax
+	adcl $0, %%eax
+7:
 	"
-	: "=b"(sum)
-	: "0"(sum), "c"(len), "S"(src), "D"(dst)
-	: "ax", "bx", "cx", "dx", "si", "di" );
-#else
-#error Not implemented for this CPU
-#endif
+	: "=a" (sum)
+	: "0"(sum), "c"(len), "S"(src), "D" (dst)
+	: "bx", "cx", "dx", "si", "di" );
     return(sum);
 }
 
diff -u --recursive --new-file v1.3.5/linux/arch/i386/math-emu/Makefile linux/arch/i386/math-emu/Makefile
--- v1.3.5/linux/arch/i386/math-emu/Makefile	Mon Jan  9 09:19:01 1995
+++ linux/arch/i386/math-emu/Makefile	Thu Jun 29 18:24:30 1995
@@ -11,7 +11,7 @@
 	$(CC) $(CFLAGS) $(MATH_EMULATION) -c $<
 
 .S.o:
-	$(CC) -D__ASSEMBLER__ $(PARANOID) -c $<
+	$(CC) -D__ASSEMBLY__ $(PARANOID) -c $<
 
 .s.o:
 	$(CC) -c $<
@@ -35,7 +35,7 @@
 
 dep:
 	$(CPP) -M *.c > .depend
-	$(CPP) -D__ASSEMBLER__ -M *.S >> .depend
+	$(CPP) -D__ASSEMBLY__ -M *.S >> .depend
 
 proto:
 	cproto -e -DMAKING_PROTO *.c >fpu_proto.h
diff -u --recursive --new-file v1.3.5/linux/arch/i386/math-emu/control_w.h linux/arch/i386/math-emu/control_w.h
--- v1.3.5/linux/arch/i386/math-emu/control_w.h	Wed Feb 16 13:07:55 1994
+++ linux/arch/i386/math-emu/control_w.h	Thu Jun 29 18:25:27 1995
@@ -10,7 +10,7 @@
 #ifndef _CONTROLW_H_
 #define _CONTROLW_H_
 
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
 #define	_Const_(x)	$##x
 #else
 #define	_Const_(x)	x
diff -u --recursive --new-file v1.3.5/linux/arch/i386/math-emu/exception.h linux/arch/i386/math-emu/exception.h
--- v1.3.5/linux/arch/i386/math-emu/exception.h	Wed Dec  1 14:44:16 1993
+++ linux/arch/i386/math-emu/exception.h	Thu Jun 29 18:25:27 1995
@@ -10,7 +10,7 @@
 #define _EXCEPTION_H_
 
 
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
 #define	Const_(x)	$##x
 #else
 #define	Const_(x)	x
@@ -39,7 +39,7 @@
 #define PRECISION_LOST_DOWN  Const_(EX_Precision)
 
 
-#ifndef __ASSEMBLER__
+#ifndef __ASSEMBLY__
 
 #ifdef DEBUG
 #define	EXCEPTION(x)	{ printk("exception in %s at line %d\n", \
@@ -48,6 +48,6 @@
 #define	EXCEPTION(x)	exception(x)
 #endif
 
-#endif __ASSEMBLER__
+#endif __ASSEMBLY__
 
 #endif _EXCEPTION_H_
diff -u --recursive --new-file v1.3.5/linux/arch/i386/math-emu/fpu_emu.h linux/arch/i386/math-emu/fpu_emu.h
--- v1.3.5/linux/arch/i386/math-emu/fpu_emu.h	Mon Aug  1 08:19:13 1994
+++ linux/arch/i386/math-emu/fpu_emu.h	Thu Jun 29 18:25:27 1995
@@ -28,7 +28,7 @@
  */
 #define PECULIAR_486
 
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
 #include "fpu_asm.h"
 #define	Const(x)	$##x
 #else
@@ -55,7 +55,7 @@
 #define TW_Empty	Const(7)	/* empty */
 
 
-#ifndef __ASSEMBLER__
+#ifndef __ASSEMBLY__
 
 #include <linux/math_emu.h>
 #include <linux/linkage.h>
@@ -166,6 +166,6 @@
 #include "fpu_proto.h"
 #endif
 
-#endif __ASSEMBLER__
+#endif __ASSEMBLY__
 
 #endif _FPU_EMU_H_
diff -u --recursive --new-file v1.3.5/linux/arch/i386/math-emu/status_w.h linux/arch/i386/math-emu/status_w.h
--- v1.3.5/linux/arch/i386/math-emu/status_w.h	Wed Dec  1 14:44:16 1993
+++ linux/arch/i386/math-emu/status_w.h	Thu Jun 29 18:25:27 1995
@@ -12,7 +12,7 @@
 
 #include "fpu_emu.h"    /* for definition of PECULIAR_486 */
 
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
 #define	Const__(x)	$##x
 #else
 #define	Const__(x)	x
@@ -36,7 +36,7 @@
 
 #define SW_Exc_Mask     Const__(0x27f)  /* Status word exception bit mask */
 
-#ifndef __ASSEMBLER__
+#ifndef __ASSEMBLY__
 
 #define COMP_A_gt_B	1
 #define COMP_A_eq_B	2
@@ -60,6 +60,6 @@
 #  define clear_C1()
 #endif PECULIAR_486
 
-#endif __ASSEMBLER__
+#endif __ASSEMBLY__
 
 #endif _STATUS_H_
diff -u --recursive --new-file v1.3.5/linux/drivers/char/console.c linux/drivers/char/console.c
--- v1.3.5/linux/drivers/char/console.c	Thu Jun 29 19:02:40 1995
+++ linux/drivers/char/console.c	Thu Jun 29 19:01:17 1995
@@ -2089,7 +2089,8 @@
 				outb_p (6, 0x3cf) ;
 #endif
 
-				/* normalise the palette registers, to point the                                 * 16 screen colours to the first 16 DAC entries */
+				/* normalise the palette registers, to point the
+				 * 16 screen colours to the first 16 DAC entries */
 
 				for (i=0; i<16; i++) {
 					inb_p (0x3da) ;
@@ -2400,7 +2401,11 @@
 
 	if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_VGAC) {
 		charmap = colourmap;
-		beg = (video_type == VIDEO_TYPE_VGAC ? 0x06 : 0x0e) ;
+		beg = 0x0e;
+#ifdef VGA_CAN_DO_64KB
+		if (video_type == VIDEO_TYPE_VGAC)
+			beg = 0x06;
+#endif
 	} else if (video_type == VIDEO_TYPE_EGAM) {
 		charmap = blackwmap;
 		beg = 0x0a;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/3c501.c linux/drivers/net/3c501.c
--- v1.3.5/linux/drivers/net/3c501.c	Tue Jun  6 11:22:06 1995
+++ linux/drivers/net/3c501.c	Thu Jun 29 19:18:49 1995
@@ -572,7 +572,7 @@
      
     outb(AX_SYS, AX_CMD);
 
-    skb = alloc_skb(pkt_len, GFP_ATOMIC);
+    skb = dev_alloc_skb(pkt_len);
     /*
      *	Start of frame
      */
@@ -582,7 +582,6 @@
 	lp->stats.rx_dropped++;
 	return;
     } else {
-	skb->len = pkt_len;
 	skb->dev = dev;
 
 	/*
@@ -591,7 +590,7 @@
 	 *	receive mode.
 	 */
 	 
-	insb(DATAPORT, skb->data, pkt_len);
+	insb(DATAPORT, skb_put(skb,pkt_len), pkt_len);
 	skb->protocol=eth_type_trans(skb,dev);
 	netif_rx(skb);
 	lp->stats.rx_packets++;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v1.3.5/linux/drivers/net/3c505.c	Thu Jun 29 19:02:41 1995
+++ linux/drivers/net/3c505.c	Thu Jun 29 19:18:49 1995
@@ -560,7 +560,7 @@
 
 	rlen = (len+1) & ~1;
 
-	skb = alloc_skb(rlen, GFP_ATOMIC);
+	skb = dev_alloc_skb(rlen);
 
 	/*
 	 * make sure the data register is going the right way
@@ -587,13 +587,12 @@
 		adapter->stats.rx_dropped++;
 
 	} else {
-		skb->len = rlen;
 		skb->dev = dev;
 
 		/*
 		 * now read the data from the adapter
 		 */
-		ptr = (unsigned short *)(skb->data);
+		ptr = (unsigned short *)skb_put(skb,len);
 		for (i = 0; i < (rlen/2); i++) { 
 			timeout = 0;
 			while ((inb_status(dev->base_addr)&HRDY) == 0 && timeout++ < 20000) 
diff -u --recursive --new-file v1.3.5/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v1.3.5/linux/drivers/net/3c507.c	Tue Jun  6 11:22:07 1995
+++ linux/drivers/net/3c507.c	Thu Jun 29 19:18:50 1995
@@ -835,7 +835,7 @@
 			struct sk_buff *skb;
 
 			pkt_len &= 0x3fff;
-			skb = alloc_skb(pkt_len, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
@@ -845,7 +845,7 @@
 			skb->dev = dev;
 
 			/* 'skb->data' points to the start of sk_buff data area. */
-			memcpy(skb->data, data_frame + 5, pkt_len);
+			memcpy(skb_put(skb,pkt_len), data_frame + 5, pkt_len);
 		
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v1.3.5/linux/drivers/net/3c509.c	Tue Jun  6 11:22:07 1995
+++ linux/drivers/net/3c509.c	Thu Jun 29 19:18:50 1995
@@ -591,16 +591,15 @@
 			short pkt_len = rx_status & 0x7ff;
 			struct sk_buff *skb;
 
-			skb = alloc_skb(pkt_len+3, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len+3);
 			if (el3_debug > 4)
 				printk("Receiving packet size %d status %4.4x.\n",
 					   pkt_len, rx_status);
 			if (skb != NULL) {
-				skb->len = pkt_len;
 				skb->dev = dev;
 
 				/* 'skb->data' points to the start of sk_buff data area. */
-				insl(ioaddr+RX_FIFO, skb->data,
+				insl(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
 							(pkt_len + 3) >> 2);
 
 				skb->protocol=eth_type_trans(skb,dev);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/8390.c linux/drivers/net/8390.c
--- v1.3.5/linux/drivers/net/8390.c	Tue Jun 20 09:10:32 1995
+++ linux/drivers/net/8390.c	Thu Jun 29 19:18:50 1995
@@ -455,7 +455,7 @@
 		} else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) {
 			struct sk_buff *skb;
 			
-			skb = alloc_skb(pkt_len, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len);
 			if (skb == NULL) {
 				if (ei_debug > 1)
 					printk("%s: Couldn't allocate a sk_buff of size %d.\n",
@@ -463,10 +463,9 @@
 				ei_local->stat.rx_dropped++;
 				break;
 			} else {
-				skb->len = pkt_len;
 				skb->dev = dev;
 				
-				ei_block_input(dev, pkt_len, (char *) skb->data,
+				ei_block_input(dev, pkt_len, skb_put(skb,pkt_len),
 							   current_offset + sizeof(rx_frame));
 				skb->protocol=eth_type_trans(skb,dev);
 				netif_rx(skb);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/apricot.c linux/drivers/net/apricot.c
--- v1.3.5/linux/drivers/net/apricot.c	Tue Jun  6 11:22:07 1995
+++ linux/drivers/net/apricot.c	Thu Jun 29 19:18:50 1995
@@ -342,7 +342,7 @@
 	{
 	    /* a good frame */
 	    int pkt_len = lp->scb.rfd->count & 0x3fff;
-	    struct sk_buff *skb = alloc_skb(pkt_len, GFP_ATOMIC);
+	    struct sk_buff *skb = dev_alloc_skb(pkt_len);
 
 	    frames++;
 
@@ -353,9 +353,8 @@
 		break;
 	    }
 
-	    skb->len = pkt_len;
   	    skb->dev = dev;		
-	    memcpy(skb->data, lp->scb.rfd->data, pkt_len);
+	    memcpy(skb_put(skb,pkt_len), lp->scb.rfd->data, pkt_len);
 
 	    skb->protocol=eth_type_trans(skb,dev);
 	    netif_rx(skb);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- v1.3.5/linux/drivers/net/arcnet.c	Tue Jun 27 14:11:35 1995
+++ linux/drivers/net/arcnet.c	Thu Jun 29 19:18:50 1995
@@ -383,8 +383,8 @@
 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
 
 	/* annoying functions for header/arp/etc building */
-int arc_header(unsigned char *buff,struct device *dev,unsigned short type,
-		void *daddr,void *saddr,unsigned len,struct sk_buff *skb);
+int arc_header(struct sk_buff *skb,struct device *dev,unsigned short type,
+		void *daddr,void *saddr,unsigned len);
 int arc_rebuild_header(void *eth,struct device *dev,unsigned long raddr,
 		struct sk_buff *skb);
 unsigned short arc_type_trans(struct sk_buff *skb,struct device *dev);
@@ -1597,16 +1597,15 @@
         	
         	in->sequence=arcsoft->sequence;
 
-         	skb = alloc_skb(length, GFP_ATOMIC);
+         	skb = dev_alloc_skb(length);
          	if (skb == NULL) {
          		printk("%s: Memory squeeze, dropping packet.\n", 
          			dev->name);
          		lp->stats.rx_dropped++;
          		return;
          	}
-         	soft=(struct ClientData *)skb->data;
+         	soft=(struct ClientData *)skb_put(skb,length);
          	
-         	skb->len = length;
          	skb->dev = dev;
          	
          	memcpy((u_char *)soft+EXTRA_CLIENTDATA,
@@ -1731,9 +1730,8 @@
 	        		return;
 	        	}
 	        
-                	in->skb=skb=alloc_skb(508*in->numpackets
-                			+ sizeof(struct ClientData),
-	                		GFP_ATOMIC);
+                	in->skb=skb=dev_alloc_skb(508*in->numpackets
+                			+ sizeof(struct ClientData));
                 	if (skb == NULL) {
                 		printk("%s: (split) memory squeeze, dropping packet.\n", 
                 			dev->name);
@@ -1746,9 +1744,8 @@
 	                 */
 	                skb->free=1;
 	                
-                	soft=(struct ClientData *)skb->data;
+                	soft=(struct ClientData *)skb_put(skb,sizeof(struct ClientData));
                 	
-                	skb->len=sizeof(struct ClientData);
                 	skb->dev=dev;
 
 	         	memcpy((u_char *)soft+EXTRA_CLIENTDATA,
@@ -1791,17 +1788,15 @@
 	        		return;
 	        	}
 
-	               	soft=(struct ClientData *)in->skb->data;
+	               	soft=(struct ClientData *)skb->data;
 	        }
 	        
 	        skb=in->skb;
 	        
-	        memcpy(skb->data+skb->len,
+	        memcpy(skb_put(skb,length-sizeof(struct ClientData)),
 	               (u_char *)arcsoft+sizeof(struct ClientData),
 	               length-sizeof(struct ClientData));
 
-         	skb->len+=length-sizeof(struct ClientData);
-         	
          	soft->daddr=daddr;
          	soft->saddr=saddr;
          	
@@ -1974,10 +1969,11 @@
  *	saddr=NULL	means use device source address (always will anyway)
  *	daddr=NULL	means leave destination address (eg unresolved arp)
  */
-int arc_header(unsigned char *buff,struct device *dev,unsigned short type,
-		void *daddr,void *saddr,unsigned len,struct sk_buff *skb)
+int arc_header(struct sk_buff *skb,struct device *dev,unsigned short type,
+		void *daddr,void *saddr,unsigned len)
 {
-	struct ClientData *head = (struct ClientData *)buff;
+	struct ClientData *head = (struct ClientData *)
+		skb_push(skb,dev->hard_header_len);
 	struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);
 
 	/* set the protocol ID according to RFC-1201 */
diff -u --recursive --new-file v1.3.5/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v1.3.5/linux/drivers/net/at1700.c	Tue Jun  6 11:22:07 1995
+++ linux/drivers/net/at1700.c	Thu Jun 29 19:18:50 1995
@@ -527,7 +527,7 @@
 				lp->stats.rx_errors++;
 				break;
 			}
-			skb = alloc_skb(pkt_len+1, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len+1);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, dropping packet (len %d).\n",
 					   dev->name, pkt_len);
@@ -540,7 +540,7 @@
 			skb->len = pkt_len;
 			skb->dev = dev;
 
-			insw(ioaddr + DATAPORT, skb->data, (pkt_len + 1) >> 1);
+			insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
 			skb->protocol=eth_type_trans(skb, dev);
 			netif_rx(skb);
 			lp->stats.rx_packets++;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v1.3.5/linux/drivers/net/atp.c	Tue Jun  6 11:22:08 1995
+++ linux/drivers/net/atp.c	Thu Jun 29 19:18:50 1995
@@ -670,16 +670,15 @@
 		int pkt_len = (rx_head.rx_count & 0x7ff) - 4; 		/* The "-4" is omits the FCS (CRC). */
 		struct sk_buff *skb;
 		
-		skb = alloc_skb(pkt_len, GFP_ATOMIC);
+		skb = dev_alloc_skb(pkt_len);
 		if (skb == NULL) {
 			printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 			lp->stats.rx_dropped++;
 			goto done;
 		}
-		skb->len = pkt_len;
 		skb->dev = dev;
 		
-		read_block(ioaddr, pkt_len, skb->data, dev->if_port);
+		read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port);
 
 		if (net_debug > 6) {
 			unsigned char *data = skb->data;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v1.3.5/linux/drivers/net/de4x5.c	Thu Jun 29 19:02:41 1995
+++ linux/drivers/net/de4x5.c	Thu Jun 29 20:50:33 1995
@@ -1153,16 +1153,15 @@
 	struct sk_buff *skb;
 	short pkt_len = (short)(lp->rx_ring[entry].status >> 16) - 4;
 
-	if ((skb = alloc_skb(pkt_len, GFP_ATOMIC)) != NULL) {
-	  skb->len = pkt_len;
+	if ((skb = dev_alloc_skb(pkt_len)) != NULL) {
 	  skb->dev = dev;
 	
 	  if (entry < lp->rx_old) {         /* Wrapped buffer */
 	    short len = (lp->rxRingSize - lp->rx_old) * RX_BUFF_SZ;
-	    memcpy(skb->data, bus_to_virt(lp->rx_ring[lp->rx_old].buf), len);
-	    memcpy(skb->data + len, bus_to_virt(lp->rx_ring[0].buf), pkt_len - len);
+	    memcpy(skb_put(skb,len), bus_to_virt(lp->rx_ring[lp->rx_old].buf), len);
+	    memcpy(skb_put(skb,pkt_len-len), bus_to_virt(lp->rx_ring[0].buf), pkt_len - len);
 	  } else {                          /* Linear buffer */
-	    memcpy(skb->data, bus_to_virt(lp->rx_ring[lp->rx_old].buf), pkt_len);
+	    memcpy(skb_put(skb,pkt_len), bus_to_virt(lp->rx_ring[lp->rx_old].buf), pkt_len);
 	  }
 
 	  /* Push up the protocol stack */
@@ -2498,39 +2497,41 @@
 
   switch(ioc->cmd) {
   case DE4X5_GET_HWADDR:             /* Get the hardware address */
+    ioc->len = ETH_ALEN;
+    status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len);
+    if (status)
+      break;
     for (i=0; i<ETH_ALEN; i++) {
       tmp.addr[i] = dev->dev_addr[i];
     }
-    ioc->len = ETH_ALEN;
-    if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {
-      memcpy_tofs(ioc->data, tmp.addr, ioc->len);
-    }
-
+    memcpy_tofs(ioc->data, tmp.addr, ioc->len);
+    
     break;
   case DE4X5_SET_HWADDR:             /* Set the hardware address */
-    if (suser()) {
-      if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN))) {
-	memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN);
-	for (i=0; i<ETH_ALEN; i++) {
-	  dev->dev_addr[i] = tmp.addr[i];
-	}
-	build_setup_frame(dev, PHYS_ADDR_ONLY);
-	/* Set up the descriptor and give ownership to the card */
-	while (set_bit(0, (void *)&dev->tbusy) != 0);/* Wait for lock to free*/
-	if (lp->setup_f == HASH_PERF) {
-	  load_packet(dev, lp->setup_frame, TD_IC | HASH_F | TD_SET | 
-		                                        SETUP_FRAME_LEN, NULL);
-	} else {
-	  load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | 
-		                                        SETUP_FRAME_LEN, NULL);
-	}
-	lp->tx_new = (++lp->tx_new) % lp->txRingSize;
-	outl(POLL_DEMAND, DE4X5_TPD);                /* Start the TX */
-	dev->tbusy = 0;                              /* Unlock the TX ring */
-      }
+    status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN);
+    if (status)
+      break;
+    status = -EPERM;
+    if (!suser())
+      break;
+    status = 0;
+    memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN);
+    for (i=0; i<ETH_ALEN; i++) {
+      dev->dev_addr[i] = tmp.addr[i];
+    }
+    build_setup_frame(dev, PHYS_ADDR_ONLY);
+    /* Set up the descriptor and give ownership to the card */
+    while (set_bit(0, (void *)&dev->tbusy) != 0);/* Wait for lock to free*/
+    if (lp->setup_f == HASH_PERF) {
+      load_packet(dev, lp->setup_frame, TD_IC | HASH_F | TD_SET | 
+    	                                        SETUP_FRAME_LEN, NULL);
     } else {
-      status = -EPERM;
+      load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | 
+    	                                        SETUP_FRAME_LEN, NULL);
     }
+    lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+    outl(POLL_DEMAND, DE4X5_TPD);                /* Start the TX */
+    dev->tbusy = 0;                              /* Unlock the TX ring */
 
     break;
   case DE4X5_SET_PROM:               /* Set Promiscuous Mode */
@@ -2559,9 +2560,10 @@
     break;
   case DE4X5_GET_MCA:                /* Get the multicast address table */
     ioc->len = (HASH_TABLE_LEN >> 3);
-    if (!(status = verify_area(VERIFY_WRITE, ioc->data, 192))) {
-      memcpy_tofs(ioc->data, lp->setup_frame, 192); 
-    }
+    status = verify_area(VERIFY_WRITE, ioc->data, ioc->len);
+    if (status)
+      break;
+    memcpy_tofs(ioc->data, lp->setup_frame, ioc->len); 
 
     break;
   case DE4X5_SET_MCA:                /* Set a multicast address */
@@ -2598,11 +2600,13 @@
 
     break;
   case DE4X5_GET_STATS:              /* Get the driver statistics */
-    cli();
     ioc->len = sizeof(lp->pktStats);
-    if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, sizeof(lp->pktStats)))) {
-      memcpy_tofs(ioc->data, &lp->pktStats, ioc->len); 
-    }
+    status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len);
+    if (status)
+      break;
+
+    cli();
+    memcpy_tofs(ioc->data, &lp->pktStats, ioc->len); 
     sti();
 
     break;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v1.3.5/linux/drivers/net/de600.c	Tue Jun  6 12:23:16 1995
+++ linux/drivers/net/de600.c	Thu Jun 29 19:18:50 1995
@@ -609,7 +609,7 @@
 		return;
 	}
 
-	skb = alloc_skb(size, GFP_ATOMIC);
+	skb = dev_alloc_skb(size);
 	sti();
 	if (skb == NULL) {
 		printk("%s: Couldn't allocate a sk_buff of size %d.\n",
@@ -618,9 +618,10 @@
 	}
 	/* else */
 
-	skb->lock = 0;
+	skb->dev = dev;
+	
 	/* 'skb->data' points to the start of sk_buff data area. */
-	buffer = skb->data;
+	buffer = skb_put(skb,size);
 
 	/* copy the packet into the buffer */
 	de600_setup_address(read_from, RW_ADDR);
@@ -630,10 +631,10 @@
 	((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
 
 	skb->protocol=eth_type_trans(skb,dev);
-	if (dev_rint((unsigned char *)skb, size, IN_SKBUFF, dev))
-		printk("%s: receive buffers full.\n", dev->name);
+	
+	netif_rx(skb);
 	/*
-	 * If any worth-while packets have been received, dev_rint()
+	 * If any worth-while packets have been received, netif_rx()
 	 * has done a mark_bh(INET_BH) for us and will work on them
 	 * when we get to the bottom-half routine.
 	 */
diff -u --recursive --new-file v1.3.5/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v1.3.5/linux/drivers/net/de620.c	Tue Jun  6 11:22:08 1995
+++ linux/drivers/net/de620.c	Thu Jun 29 19:18:50 1995
@@ -678,16 +678,17 @@
 		printk("%s: Illegal packet size: %d!\n", dev->name, size);
 	}
 	else { /* Good packet? */
-		skb = alloc_skb(size, GFP_ATOMIC);
+		skb = dev_alloc_skb(size);
 		if (skb == NULL) { /* Yeah, but no place to put it... */
 			printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 				dev->name, size);
 			((struct netstats *)(dev->priv))->rx_dropped++;
 		}
 		else { /* Yep! Go get it! */
-			skb->len = size; skb->dev = dev; skb->free = 1;
+			skb->dev = dev;
+			skb->free = 1;
 			/* skb->data points to the start of sk_buff data area */
-			buffer = skb->data;
+			buffer = skb_put(skb,size);
 			/* copy the packet into the buffer */
 			de620_read_block(buffer, size);
 			PRINTK(("Read %d bytes\n", size));
diff -u --recursive --new-file v1.3.5/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v1.3.5/linux/drivers/net/depca.c	Thu Jun 29 19:02:42 1995
+++ linux/drivers/net/depca.c	Thu Jun 29 20:36:47 1995
@@ -924,7 +924,6 @@
   struct depca_private *lp = (struct depca_private *)dev->priv;
   int i, entry;
   s32 status;
-  char *buf;
 
   for (entry=lp->rx_new; 
        !(readl(&lp->rx_ring[entry].base) & R_OWN);
@@ -944,16 +943,16 @@
 	short len, pkt_len = readw(&lp->rx_ring[entry].msg_length);
 	struct sk_buff *skb;
 
-	skb = alloc_skb(pkt_len, GFP_ATOMIC);
+	skb = dev_alloc_skb(pkt_len);
 	if (skb != NULL) {
-	  skb->len = pkt_len;
+	  unsigned char * buf = skb_put(skb,pkt_len);
 	  skb->dev = dev;
 	  if (entry < lp->rx_old) {         /* Wrapped buffer */
 	    len = (lp->rxRingMask - lp->rx_old + 1) * RX_BUFF_SZ;
-	    memcpy_fromio(skb->data, lp->rx_memcpy[lp->rx_old], len);
-	    memcpy_fromio(skb->data+len, lp->rx_memcpy[0], pkt_len-len);
+	    memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], len);
+	    memcpy_fromio(buf + len, lp->rx_memcpy[0], pkt_len-len);
 	  } else {                          /* Linear buffer */
-	    memcpy_fromio(skb->data, lp->rx_memcpy[lp->rx_old], pkt_len);
+	    memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], pkt_len);
 	  }
 
 	  /* 
@@ -973,7 +972,6 @@
 	      i = DEPCA_PKT_STAT_SZ;
 	    }
 	  }
-	  buf = skb->data;                  /* Look at the dest addr */
 	  if (buf[0] & 0x01) {              /* Multicast/Broadcast */
 	    if ((*(s32 *)&buf[0] == -1) && (*(s16 *)&buf[4] == -1)) {
 	      lp->pktStats.broadcast++;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/eepro.c linux/drivers/net/eepro.c
--- v1.3.5/linux/drivers/net/eepro.c	Tue Jun 27 14:11:35 1995
+++ linux/drivers/net/eepro.c	Thu Jun 29 19:18:50 1995
@@ -1046,16 +1046,15 @@
 			struct sk_buff *skb;
 
 			rcv_size &= 0x3fff;
-			skb = alloc_skb(rcv_size, GFP_ATOMIC);
+			skb = dev_alloc_skb(rcv_size);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
 				break;
 			}
-			skb->len = rcv_size;
 			skb->dev = dev;
 
-			insw(ioaddr+IO_PORT, skb->data, (rcv_size + 1) >> 1);
+			insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 1) >> 1);
 	
 			skb->protocol = eth_type_trans(skb,dev);	
 			netif_rx(skb);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v1.3.5/linux/drivers/net/eexpress.c	Tue Jun  6 11:22:08 1995
+++ linux/drivers/net/eexpress.c	Thu Jun 29 19:18:50 1995
@@ -941,18 +941,17 @@
 			struct sk_buff *skb;
 
 			pkt_len &= 0x3fff;
-			skb = alloc_skb(pkt_len, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
 				break;
 			}
-			skb->len = pkt_len;
 			skb->dev = dev;
 
 			outw(data_buffer_addr + 10, ioaddr + READ_PTR);
 
-			insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
+			insw(ioaddr, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
 		
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/eql.c linux/drivers/net/eql.c
--- v1.3.5/linux/drivers/net/eql.c	Tue Jun 27 14:11:36 1995
+++ linux/drivers/net/eql.c	Thu Jun 29 19:18:50 1995
@@ -144,9 +144,9 @@
 static int eql_slave_xmit(struct sk_buff *skb, struct device *dev); /*  */
 
 static struct enet_statistics *eql_get_stats(struct device *dev); /*  */
-static int eql_header(unsigned char *buff, struct device *dev, 
+static int eql_header(struct sk_buff *skb, struct device *dev, 
 		      unsigned short type, void *daddr, void *saddr, 
-		      unsigned len, struct sk_buff *skb); /*  */
+		      unsigned len); /*  */
 static int eql_rebuild_header(void *buff, struct device *dev, 
 			      unsigned long raddr, struct sk_buff *skb); /*  */
 
@@ -395,9 +395,9 @@
 
 static 
 int 
-eql_header(unsigned char *buff, struct device *dev, 
+eql_header(struct sk_buff *skb, struct device *dev, 
 	   unsigned short type, void *daddr, void *saddr, 
-	   unsigned len, struct sk_buff *skb)
+	   unsigned len)
 {
   return 0;
 }
@@ -424,6 +424,10 @@
   struct device *master_dev;
   struct device *slave_dev;
   slaving_request_t srq;
+  int err;
+
+  err = verify_area(VERIFY_READ, (void *)srqp, sizeof (slaving_request_t));
+  if (err) return err;
 
   memcpy_fromfs (&srq, srqp, sizeof (slaving_request_t));
 
@@ -469,6 +473,10 @@
   struct device *master_dev;
   struct device *slave_dev;
   slaving_request_t srq;
+  int err;
+
+  err = verify_area(VERIFY_READ, (void *)srqp, sizeof (slaving_request_t));
+  if (err) return err;
 
   memcpy_fromfs (&srq, srqp, sizeof (slaving_request_t));
 
@@ -502,6 +510,10 @@
   equalizer_t *eql;
   struct device *slave_dev;
   slave_config_t sc;
+  int err;
+
+  err = verify_area(VERIFY_READ, (void *)scp, sizeof (slave_config_t));
+  if (err) return err;
 
   memcpy_fromfs (&sc, scp, sizeof (slave_config_t));
 
@@ -519,6 +531,10 @@
       if (slave != 0)
 	{
 	  sc.priority = slave->priority;
+
+          err = verify_area(VERIFY_WRITE, (void *)scp, sizeof (slave_config_t));
+          if (err) return err;
+
 	  memcpy_tofs (scp, &sc, sizeof (slave_config_t));
 	  return 0;
 	}
@@ -535,6 +551,10 @@
   equalizer_t *eql;
   struct device *slave_dev;
   slave_config_t sc;
+  int err;
+
+  err = verify_area(VERIFY_READ, (void *)scp, sizeof (slave_config_t));
+  if (err) return err;
 
 #ifdef EQL_DEBUG
   if (eql_debug >= 20)
@@ -575,6 +595,11 @@
 
   if ( eql_is_master (dev) )
     {
+      int err;
+
+      err = verify_area(VERIFY_WRITE, (void *)mcp, sizeof (master_config_t));
+      if (err) return err;
+
       eql = (equalizer_t *) dev->priv;
       mc.max_slaves = eql->max_slaves;
       mc.min_slaves = eql->min_slaves;
@@ -591,6 +616,10 @@
 {
   equalizer_t *eql;
   master_config_t mc;
+ int err;
+
+ err = verify_area(VERIFY_READ, (void *)mcp, sizeof (master_config_t));
+ if (err) return err;
 
 #if EQL_DEBUG
   if (eql_debug >= 20)
diff -u --recursive --new-file v1.3.5/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v1.3.5/linux/drivers/net/ewrk3.c	Tue Jun  6 11:22:08 1995
+++ linux/drivers/net/ewrk3.c	Thu Jun 29 19:18:50 1995
@@ -1035,12 +1035,11 @@
 	} else {
 	  struct sk_buff *skb;
 
-          if ((skb = alloc_skb(pkt_len, GFP_ATOMIC)) != NULL) {
-	    skb->len = pkt_len;
+          if ((skb = dev_alloc_skb(pkt_len)) != NULL) {
 	    skb->dev = dev;
 
 	    if (lp->shmem_length == IO_ONLY) {
-	      unsigned char *p = skb->data;
+	      unsigned char *p = skb_put(skb,pkt_len);
 
 	      *p = inb(EWRK3_DATA);         /* dummy read */
 	      for (i=0; i<skb->len; i++) {
@@ -1618,6 +1617,7 @@
     unsigned char addr[HASH_TABLE_LEN * ETH_ALEN];
     unsigned short val[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
   } tmp;
+  int err;
 
   switch(ioc->cmd) {
   case EWRK3_GET_HWADDR:             /* Get the hardware address */
@@ -1625,6 +1625,9 @@
       tmp.addr[i] = dev->dev_addr[i];
     }
     ioc->len = ETH_ALEN;
+
+    err = verify_area(VERIFY_WRITE, (void *)ioc->data, ETH_ALEN);
+    if (err) return err;
     memcpy_tofs(ioc->data, tmp.addr, ioc->len);
 
     break;
@@ -1634,6 +1637,8 @@
       csr |= (TXD|RXD);
       outb(csr, EWRK3_CSR);                  /* Disable the TX and RX */
 
+      err = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN);
+      if (err) return err;
       memcpy_fromfs(tmp.addr,ioc->data,ETH_ALEN);
       for (i=0; i<ETH_ALEN; i++) {
 	dev->dev_addr[i] = tmp.addr[i];
@@ -1673,6 +1678,9 @@
 
     break;
   case EWRK3_GET_MCA:                /* Get the multicast address table */
+    err = verify_area(VERIFY_WRITE, (void *)ioc->data, HASH_TABLE_LEN >> 3);
+    if (err) return err;
+
     while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
     if (lp->shmem_length == IO_ONLY) {
       outb(0, EWRK3_IOPR);
@@ -1691,6 +1699,9 @@
     break;
   case EWRK3_SET_MCA:                /* Set a multicast address */
     if (suser()) {
+      err = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN * ioc->len);
+      if (err) return err;
+
       if (ioc->len != HASH_TABLE_LEN) {         /* MCA changes */
 	memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
       }
@@ -1720,6 +1731,9 @@
 
     break;
   case EWRK3_GET_STATS:              /* Get the driver statistics */
+    err = verify_area(VERIFY_WRITE, (void *)ioc->data, sizeof(lp->pktStats)));
+    if (err) return err;
+
     cli();
     memcpy_tofs(ioc->data, &lp->pktStats, sizeof(lp->pktStats)); 
     ioc->len = EWRK3_PKT_STAT_SZ;
@@ -1737,11 +1751,17 @@
 
     break;
   case EWRK3_GET_CSR:                /* Get the CSR Register contents */
+    err = verify_area(VERIFY_WRITE, (void *)ioc->data, 1);
+    if (err) return err;
+
     tmp.addr[0] = inb(EWRK3_CSR);
     memcpy_tofs(ioc->data, tmp.addr, 1);
 
     break;
   case EWRK3_SET_CSR:                /* Set the CSR Register contents */
+    err = verify_area(VERIFY_READ, (void *)ioc->data, 1);
+    if (err) return err;
+
     if (suser()) {
       memcpy_fromfs(tmp.addr, ioc->data, 1);
       outb(tmp.addr[0], EWRK3_CSR);
@@ -1752,6 +1772,9 @@
     break;
   case EWRK3_GET_EEPROM:             /* Get the EEPROM contents */
     if (suser()) {
+      err = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len);
+      if (err) return err;
+
       for (i=0; i<(EEPROM_MAX>>1); i++) {
 	tmp.val[i] = (short)Read_EEPROM(iobase, i);
       }
@@ -1769,6 +1792,9 @@
     break;
   case EWRK3_SET_EEPROM:             /* Set the EEPROM contents */
     if (suser()) {
+      err = verify_area(VERIFY_READ, (void *)ioc->data, EEPROM_MAX);
+      if (err) return err;
+
       memcpy_fromfs(tmp.addr, ioc->data, EEPROM_MAX);
       for (i=0; i<(EEPROM_MAX>>1); i++) {
 	Write_EEPROM(tmp.val[i], iobase, i);
@@ -1779,6 +1805,9 @@
 
     break;
   case EWRK3_GET_CMR:                /* Get the CMR Register contents */
+    err = verify_area(VERIFY_WRITE, (void *)ioc->data, 1);
+    if (err) return err;
+
     tmp.addr[0] = inb(EWRK3_CMR);
     memcpy_tofs(ioc->data, tmp.addr, 1);
 
diff -u --recursive --new-file v1.3.5/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v1.3.5/linux/drivers/net/hp100.c	Thu Jun 29 19:02:42 1995
+++ linux/drivers/net/hp100.c	Thu Jun 29 21:38:43 1995
@@ -585,7 +585,12 @@
       printk( "hp100_rx: new packet - length = %d, errors = 0x%x, dest = 0x%x\n",
       	header & HP100_PKT_LEN_MASK, ( header >> 16 ) & 0xfff8, ( header >> 16 ) & 7 );
 #endif
-      skb = alloc_skb( ( pkt_len + 3 ) & ~3, GFP_ATOMIC );
+      /*
+       * NOTE! This (and the skb_put() below) depends on the skb-functions
+       * allocating more than asked (notably, aligning the request up to
+       * the next 16-byte length).
+       */
+      skb = dev_alloc_skb(pkt_len);
       if ( skb == NULL )
         {
 #ifdef HP100_DEBUG
@@ -595,9 +600,8 @@
         }
        else
         {
-          skb -> len = pkt_len;
           skb -> dev = dev;
-          insl( ioaddr + HP100_REG_DATA32, skb -> data, ( pkt_len + 3 ) >> 2 );
+          insl( ioaddr + HP100_REG_DATA32, skb_put(pkt_len), ( pkt_len + 3 ) >> 2 );
           skb->protocol=eth_type_trans(skb,dev);
           netif_rx( skb );
           lp -> stats.rx_packets++;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v1.3.5/linux/drivers/net/ibmtr.c	Tue Jun  6 11:22:09 1995
+++ linux/drivers/net/ibmtr.c	Thu Jun 29 19:18:50 1995
@@ -1073,7 +1073,7 @@
 #endif
 
 
-	if(!(skb=alloc_skb(ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr), GFP_ATOMIC))) {
+	if(!(skb=dev_alloc_skb(ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr)))) {
 		DPRINTK("out of memory. frame dropped.\n");	
 		ti->tr_stats.rx_dropped++;
 		rec_resp->ret_code=DATA_LOST;
@@ -1081,7 +1081,7 @@
 		return;
 	}
 
-	skb->len=ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr);
+	skb_put(skb,ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr));
 	skb->dev=dev;
 
 #if 0
diff -u --recursive --new-file v1.3.5/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v1.3.5/linux/drivers/net/lance.c	Tue Jun  6 11:22:09 1995
+++ linux/drivers/net/lance.c	Thu Jun 29 19:18:50 1995
@@ -984,7 +984,7 @@
 			short pkt_len = (lp->rx_ring[entry].msg_length & 0xfff)-4;
 			struct sk_buff *skb;
 
-			skb = alloc_skb(pkt_len, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, deferring packet.\n", dev->name);
 				for (i=0; i < RX_RING_SIZE; i++)
@@ -998,9 +998,8 @@
 				}
 				break;
 			}
-			skb->len = pkt_len;
 			skb->dev = dev;
-			memcpy(skb->data,
+			memcpy(skb_put(skb,pkt_len),
 				   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
 				   pkt_len);
 			skb->protocol=eth_type_trans(skb,dev);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- v1.3.5/linux/drivers/net/loopback.c	Tue Jun  6 12:23:16 1995
+++ linux/drivers/net/loopback.c	Thu Jun 29 19:18:50 1995
@@ -86,7 +86,7 @@
 	  	 */
 		save_flags(flags);
 	  	cli();
-	  	skb->sk->wmem_alloc-=skb->mem_len;
+	  	skb->sk->wmem_alloc-=skb->truesize;
 	  	skb->sk->write_space(skb->sk);
 	  	restore_flags(flags);
 	}
diff -u --recursive --new-file v1.3.5/linux/drivers/net/net_init.c linux/drivers/net/net_init.c
--- v1.3.5/linux/drivers/net/net_init.c	Tue Jun  6 11:22:09 1995
+++ linux/drivers/net/net_init.c	Thu Jun 29 21:07:28 1995
@@ -159,6 +159,17 @@
 	return dev;
 }
 
+
+static int eth_mac_addr(struct device *dev, void * addr)
+{
+	struct ifreq * ifr = (struct ifreq *) addr;
+
+	if(dev->start)
+		return -EBUSY;
+	memcpy(dev->dev_addr, ifr->ifr_hwaddr.sa_data,dev->hard_header_len);
+	return 0;
+}
+
 void ether_setup(struct device *dev)
 {
 	int i;
@@ -182,6 +193,7 @@
 
 	dev->hard_header	= eth_header;
 	dev->rebuild_header = eth_rebuild_header;
+	dev->set_mac_address = eth_mac_addr;
 
 	dev->type		= ARPHRD_ETHER;
 	dev->hard_header_len = ETH_HLEN;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v1.3.5/linux/drivers/net/ni52.c	Tue Jun  6 11:22:09 1995
+++ linux/drivers/net/ni52.c	Thu Jun 29 19:18:51 1995
@@ -803,12 +803,11 @@
         {
           totlen &= RBD_MASK; /* length of this frame */
           rbd->status = 0;
-          skb = (struct sk_buff *) alloc_skb(totlen, GFP_ATOMIC);
+          skb = (struct sk_buff *) dev_alloc_skb(totlen);
           if(skb != NULL)
           {
-            skb->len = totlen;
             skb->dev = dev;
-            memcpy( (char *) skb->data,(char *) p->base+(unsigned long) rbd->buffer, totlen);
+            memcpy(skb_put(skb,totlen),(char *) p->base+(unsigned long) rbd->buffer, totlen);
             skb->protocol=eth_type_trans(skb,dev);
             netif_rx(skb);
             p->stats.rx_packets++;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v1.3.5/linux/drivers/net/ni65.c	Tue Jun  6 11:22:09 1995
+++ linux/drivers/net/ni65.c	Thu Jun 29 19:18:51 1995
@@ -287,7 +287,7 @@
 
    for(i=0;i<RMDNUM;i++)
    {
-     if( (p->recv_skb[i] = (struct sk_buff *) alloc_skb(R_BUF_SIZE,GFP_ATOMIC)) == NULL) {
+     if( (p->recv_skb[i] = dev_alloc_skb(R_BUF_SIZE)) == NULL) {
        printk("%s: unable to alloc recv-mem\n",dev->name);
        return EAGAIN;
      }
@@ -526,21 +526,20 @@
     else
     {
       len = (rmdp->mlen & 0x0fff) - 4; /* -4: ignore FCS */
-      skb = alloc_skb(R_BUF_SIZE,GFP_ATOMIC);
+      skb = dev_alloc_skb(R_BUF_SIZE);
       if(skb != NULL)
       {
         if( (unsigned long) (skb->data + R_BUF_SIZE) & 0xff000000) {
-          memcpy(skb->data,p->recv_skb[p->rmdnum]->data,len);
+          memcpy(skb_put(skb,len),p->recv_skb[p->rmdnum]->data,len);
 	  skb1 = skb;
         }
         else {
           skb1 = p->recv_skb[p->rmdnum];
           p->recv_skb[p->rmdnum] = skb;
-          rmdp->u.buffer = (unsigned long) (skb->data);
+          rmdp->u.buffer = (unsigned long) skb_put(skb1,len);
         }
         rmdp->u.s.status = RCV_OWN;
         rmdp->mlen = 0;   /* not necc ???? */
-        skb1->len = len;
         skb1->dev = dev;
         p->stats.rx_packets++;
         skb1->protocol=eth_type_trans(skb1,dev);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/pi2.c linux/drivers/net/pi2.c
--- v1.3.5/linux/drivers/net/pi2.c	Fri Jun 16 22:02:55 1995
+++ linux/drivers/net/pi2.c	Thu Jun 29 19:18:51 1995
@@ -510,6 +510,7 @@
     struct sk_buff *skb;
     int sksize, pkt_len;
     struct mbuf *cur_buf;
+    unsigned char *cfix;
 
     save_flags(flags);
     cli();			/* disable interrupts */
@@ -550,22 +551,23 @@
 	    /* Malloc up new buffer. */
 	    sksize = pkt_len;
 
-	    skb = alloc_skb(sksize, GFP_ATOMIC);
+	    skb = dev_alloc_skb(sksize);
 	    if (skb == NULL) {
 		printk("PI: %s: Memory squeeze, dropping packet.\n", dev->name);
 		lp->stats.rx_dropped++;
 		restore_flags(flags);
 		return;
 	    }
-	    skb->len = (unsigned long) pkt_len;
 	    skb->dev = dev;
 
 	    /* KISS kludge -  prefix with a 0 byte */
-	    skb->data[0] = 0;
+	    cfix=skb_put(skb,pkt_len);
+	    *cfix++=0;
 	    /* 'skb->data' points to the start of sk_buff data area. */
-	    memcpy(&skb->data[1], (char *) cur_buf->data,
+	    memcpy(cfix, (char *) cur_buf->data,
 		   pkt_len - 1);
-	    skb->protocol=ntohs(ETH_P_AX25);
+	    skb->protocol=htons(ETH_P_AX25);
+	    IS_SKB(skb);
 	    netif_rx(skb);
 	    lp->stats.rx_packets++;
 	}			/* end good frame */
@@ -582,6 +584,7 @@
     struct sk_buff *skb;
     int sksize;
     int pkt_len;
+    unsigned char *cfix;
 
     save_flags(flags);
     cli();			/* disable interrupts */
@@ -636,21 +639,22 @@
 
 		/* Malloc up new buffer. */
 		sksize = pkt_len;
-		skb = alloc_skb(sksize, GFP_ATOMIC);
+		skb = dev_alloc_skb(sksize);
 		if (skb == NULL) {
 		    printk("PI: %s: Memory squeeze, dropping packet.\n", dev->name);
 		    lp->stats.rx_dropped++;
 		    restore_flags(flags);
 		    return;
 		}
-		skb->len = pkt_len;
 		skb->dev = dev;
 
 		/* KISS kludge -  prefix with a 0 byte */
-		skb->data[0] = 0;
+		cfix=skb_put(skb,pkt_len);
+		*cfix++=0;
 		/* 'skb->data' points to the start of sk_buff data area. */
-		memcpy(&skb->data[1], lp->rcvbuf->data, pkt_len - 1);
+		memcpy(cfix, lp->rcvbuf->data, pkt_len - 1);
 		skb->protocol=ntohs(ETH_P_AX25);
+		IS_SKB(skb);
 		netif_rx(skb);
 		lp->stats.rx_packets++;
 		/* packet queued - initialize buffer for next frame */
@@ -1068,10 +1072,10 @@
 }
 
 /* Fill in the MAC-level header. */
-static int pi_header(unsigned char *buff, struct device *dev, unsigned short type,
-	     void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
+static int pi_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+	     void *daddr, void *saddr, unsigned len)
 {
-    return ax25_encapsulate(buff, dev, type, daddr, saddr, len, skb);
+    return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
 }
 
 /* Rebuild the MAC-level header. */
@@ -1424,13 +1428,10 @@
     dev->rebuild_header = pi_rebuild_header;
     dev->set_mac_address = pi_set_mac_address;
 
-    dev->type = AF_AX25;	/* AF_AX25 device */
+    dev->type = ARPHRD_AX25;	/* AF_AX25 device */
     dev->hard_header_len = 17;	/* We don't do digipeaters */
     dev->mtu = 1500;		/* eth_mtu is the default */
     dev->addr_len = 7;		/* sizeof an ax.25 address */
-    for (i = 0; i < ETH_ALEN; i++) {
-	dev->broadcast[i] = 0xff;
-    }
     memcpy(dev->broadcast, ax25_bcast, 7);
     memcpy(dev->dev_addr, ax25_test, 7);
 
diff -u --recursive --new-file v1.3.5/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v1.3.5/linux/drivers/net/plip.c	Tue Jun  6 11:22:10 1995
+++ linux/drivers/net/plip.c	Thu Jun 29 19:18:51 1995
@@ -522,12 +522,12 @@
 			return ERROR;
 		}
 		/* Malloc up new buffer. */
-		rcv->skb = alloc_skb(rcv->length.h, GFP_ATOMIC);
+		rcv->skb = dev_alloc_skb(rcv->length.h);
 		if (rcv->skb == NULL) {
 			printk("%s: Memory squeeze.\n", dev->name);
 			return ERROR;
 		}
-		rcv->skb->len = rcv->length.h;
+		skb_put(rcv->skb,rcv->length.h);
 		rcv->skb->dev = dev;
 		rcv->state = PLIP_PK_DATA;
 		rcv->byte = 0;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v1.3.5/linux/drivers/net/ppp.c	Thu Jun 29 19:02:42 1995
+++ linux/drivers/net/ppp.c	Thu Jun 29 19:18:51 1995
@@ -1,5 +1,4 @@
-/*
-   PPP for Linux
+/* PPP for Linux
 */
 
 /*
@@ -116,7 +115,6 @@
 static int ppp_do_ip(struct ppp *, unsigned short, unsigned char *, int);
 static int ppp_us_queue(struct ppp *, unsigned short, unsigned char *, int);
 static int ppp_xmit(struct sk_buff *, struct device *);
-static unsigned short ppp_type_trans(struct sk_buff *, struct device *);
 
 #ifdef NET02D
 static int ppp_header(unsigned char *buff, struct device *dev,
@@ -126,8 +124,8 @@
 static void ppp_add_arp(unsigned long addr, struct sk_buff *skb,
 			struct device *dev);
 #else
-static int ppp_header(unsigned char *, struct device *, unsigned short,
-		      void *, void *, unsigned, struct sk_buff *);
+static int ppp_header(struct sk_buff *, struct device *, unsigned short,
+		      void *, void *, unsigned);
 static int ppp_rebuild_header(void *, struct device *, unsigned long,
 			      struct sk_buff *);
 #endif
@@ -630,7 +628,7 @@
     struct slcompress slhc;
   } *result;
 
-  error = verify_area (VERIFY_READ,
+  error = verify_area (VERIFY_WRITE,
 		       ifr->ifr_ifru.ifru_data,
 		       sizeof (struct stats));
 
@@ -1152,10 +1150,10 @@
 
   /* receive the frame through the network software */
   
-  skb=alloc_skb(count, GFP_ATOMIC);
+  skb=dev_alloc_skb(count);
   if(skb)
   {
-  	memcpy(skb->data, c,count);
+  	memcpy(skb_put(skb,count), c,count);
   	skb->protocol=htons(ETH_P_IP);
   	skb->dev=ppp->dev;
   	skb->len=count;
@@ -1866,8 +1864,8 @@
 #else
 
 static int
-ppp_header(unsigned char *buff, struct device *dev, unsigned short type,
-	   void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
+ppp_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+	   void *daddr, void *saddr, unsigned len)
 {
   return(0);
 }
diff -u --recursive --new-file v1.3.5/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v1.3.5/linux/drivers/net/sk_g16.c	Tue Jun 27 14:11:36 1995
+++ linux/drivers/net/sk_g16.c	Thu Jun 29 19:18:51 1995
@@ -1570,7 +1570,7 @@
 	    int len = (rmdp->mlen & 0x0fff);  /* extract message length from receive buffer */
 	    struct sk_buff *skb;
 
-	    skb = alloc_skb(len, GFP_ATOMIC); /* allocate socket buffer */ 
+	    skb = dev_alloc_skb(len); /* allocate socket buffer */ 
 
 	    if (skb == NULL)                /* Could not get mem ? */
 	    {
@@ -1590,7 +1590,6 @@
 	    
 	    /* Prepare sk_buff to queue for upper layers */
 
-            skb->len = len;
 	    skb->dev = dev;
 	    
 	    /* 
@@ -1600,7 +1599,7 @@
 	     * ignore status fields) 
 	     */
 
-	    memcpy(skb->data, (unsigned char *) (rmdp->u.buffer & 0x00ffffff),
+	    memcpy(skb_put(skb,len), (unsigned char *) (rmdp->u.buffer & 0x00ffffff),
 		   len);
 
 
diff -u --recursive --new-file v1.3.5/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c
--- v1.3.5/linux/drivers/net/skeleton.c	Mon Jan 16 07:17:36 1995
+++ linux/drivers/net/skeleton.c	Thu Jun 29 19:18:51 1995
@@ -416,17 +416,16 @@
 			/* Malloc up new buffer. */
 			struct sk_buff *skb;
 
-			skb = alloc_skb(pkt_len, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
 				break;
 			}
-			skb->len = pkt_len;
 			skb->dev = dev;
 
 			/* 'skb->data' points to the start of sk_buff data area. */
-			memcpy(skb->data, (void*)dev->rmem_start,
+			memcpy(skb_put(skb,pkt_len), (void*)dev->rmem_start,
 				   pkt_len);
 			/* or */
 			insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v1.3.5/linux/drivers/net/slip.c	Tue Jun 27 14:11:36 1995
+++ linux/drivers/net/slip.c	Thu Jun 29 19:18:51 1995
@@ -313,15 +313,14 @@
 	}
 #endif  /* SL_INCLUDE_CSLIP */
 
-	skb = alloc_skb(count, GFP_ATOMIC);
+	skb = dev_alloc_skb(count);
 	if (skb == NULL)  {
 		printk("%s: memory squeeze, dropping packet.\n", sl->dev->name);
 		sl->rx_dropped++;
 		return;
 	}
-	skb->len = count;
 	skb->dev = sl->dev;
-	memcpy(skb->data, sl->rbuff, count);
+	memcpy(skb_put(skb,count), sl->rbuff, count);
 	if(sl->mode&(SL_MODE_AX25|SL_MODE_AX25VC))
 		skb->protocol=htons(ETH_P_AX25);
 	else
@@ -493,15 +492,15 @@
 
 /* Fill in the MAC-level header. Not used by SLIP. */
 static int
-sl_header(unsigned char *buff, struct device *dev, unsigned short type,
-	  void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
+sl_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+	  void *daddr, void *saddr, unsigned len)
 {
 #ifdef CONFIG_AX25
 #ifdef CONFIG_INET
 	struct slip *sl = &sl_ctrl[dev->base_addr];
 
 	if (((sl->mode & SL_MODE_AX25) || (sl->mode & SL_MODE_AX25VC)) && type != htons(ETH_P_AX25))  {
-		return ax25_encapsulate(buff, dev, type, daddr, saddr, len, skb);
+		return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
 	}
 #endif
 #endif
@@ -988,7 +987,7 @@
 
 	switch(cmd) {
 	 case SIOCGIFNAME:
-		err = verify_area(VERIFY_WRITE, arg, 16);
+		err = verify_area(VERIFY_WRITE, arg, strlen(sl->dev->name) + 1);
 		if (err)  {
 			return -err;
 		}
diff -u --recursive --new-file v1.3.5/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v1.3.5/linux/drivers/net/tulip.c	Tue Jun  6 11:22:10 1995
+++ linux/drivers/net/tulip.c	Thu Jun 29 19:18:51 1995
@@ -600,7 +600,7 @@
 			short pkt_len = lp->rx_ring[entry].status >> 16;
 			struct sk_buff *skb;
 
-			skb = alloc_skb(pkt_len, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, deferring packet.\n", dev->name);
 				/* Check that at least two ring entries are free.
@@ -616,9 +616,8 @@
 				}
 				break;
 			}
-			skb->len = pkt_len;
 			skb->dev = dev;
-			memcpy(skb->data, lp->rx_ring[entry].buffer1, pkt_len);
+			memcpy(skb_put(skb,pkt_len), lp->rx_ring[entry].buffer1, pkt_len);
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
 			lp->stats.rx_packets++;
diff -u --recursive --new-file v1.3.5/linux/drivers/net/tunnel.c linux/drivers/net/tunnel.c
--- v1.3.5/linux/drivers/net/tunnel.c	Tue Jun  6 12:23:16 1995
+++ linux/drivers/net/tunnel.c	Thu Jun 29 19:18:51 1995
@@ -204,7 +204,7 @@
 	 */
 
 	newlen = (skb->len + ip_header_len);
-	if ( !(skb2 = alloc_skb(newlen, GFP_ATOMIC)) ) 
+	if ( !(skb2 = dev_alloc_skb(newlen)) ) 
 	{
 		printk("%s: No free memory.\n",dev->name);
   		dev_kfree_skb(skb, FREE_WRITE);
@@ -215,7 +215,7 @@
 
 	/* Copy the packet to a new buffer, adding a new ip header */
 	skb2->free=1;
-	skb2->len=newlen;
+	skb_put(skb2,newlen);
 	iph=skb2->h.iph=(struct iphdr *)skb2->data;
 	memcpy(skb2->h.iph, skb->data, ip_header_len );
 	memcpy(skb2->data + ip_header_len, skb->data, skb->len);
diff -u --recursive --new-file v1.3.5/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v1.3.5/linux/drivers/net/wavelan.c	Tue Jun  6 11:22:11 1995
+++ linux/drivers/net/wavelan.c	Thu Jun 29 19:18:51 1995
@@ -1561,17 +1561,16 @@
 
 			sksize = pkt_len;
 
-			if ((skb = alloc_skb(sksize, GFP_ATOMIC)) == (struct sk_buff *)0)
+			if ((skb = dev_alloc_skb(sksize)) == (struct sk_buff *)0)
 			{
 				printk("%s: could not alloc_skb(%d, GFP_ATOMIC).\n", dev->name, sksize);
 				lp->stats.rx_dropped++;
 			}
 			else
 			{
-				skb->len = pkt_len;
 				skb->dev = dev;
 
-				obram_read(ioaddr, rbd.rbd_bufl, skb->data, pkt_len);
+				obram_read(ioaddr, rbd.rbd_bufl, skb_put(skb,pkt_len), pkt_len);
 
 				if (wavelan_debug > 5)
 				{
diff -u --recursive --new-file v1.3.5/linux/drivers/net/znet.c linux/drivers/net/znet.c
--- v1.3.5/linux/drivers/net/znet.c	Tue Jun  6 11:22:11 1995
+++ linux/drivers/net/znet.c	Thu Jun 29 19:18:51 1995
@@ -548,23 +548,22 @@
 			/* Malloc up new buffer. */
 			struct sk_buff *skb;
 
-			skb = alloc_skb(pkt_len, GFP_ATOMIC);
+			skb = dev_alloc_skb(pkt_len);
 			if (skb == NULL) {
 				if (znet_debug)
 				  printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
 				break;
 			}
-			skb->len = pkt_len;
 			skb->dev = dev;
 
 			if (&zn.rx_cur[(pkt_len+1)>>1] > zn.rx_end) {
 				int semi_cnt = (zn.rx_end - zn.rx_cur)<<1;
-				memcpy((unsigned char *) (skb + 1), zn.rx_cur, semi_cnt);
-				memcpy((unsigned char *) (skb + 1) + semi_cnt, zn.rx_start,
+				memcpy(skb_put(skb,semi_cnt), zn.rx_cur, semi_cnt);
+				memcpy(skb_put(skb,pkt_len-semi_cnt), zn.rx_start,
 					   pkt_len - semi_cnt);
 			} else {
-				memcpy((unsigned char *) (skb + 1), zn.rx_cur, pkt_len);
+				memcpy(skb_put(skb,pkt_len), zn.rx_cur, pkt_len);
 				if (znet_debug > 6) {
 					unsigned int *packet = (unsigned int *) (skb + 1);
 					printk(KERN_DEBUG "Packet data is %08x %08x %08x %08x.\n", packet[0],
Binary files v1.3.5/linux/drivers/scsi/aic7770 and linux/drivers/scsi/aic7770 differ
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v1.3.5/linux/drivers/scsi/eata_dma.c	Thu Jun 29 19:02:49 1995
+++ linux/drivers/scsi/eata_dma.c	Fri Jun 30 15:30:56 1995
@@ -1086,7 +1086,7 @@
 {
 
 #ifndef CONFIG_PCI
-    printk("Kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
+    printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
 #else
     
     u8 pci_bus, pci_device_fn;
@@ -1175,8 +1175,9 @@
 		       "PCI_BASE_ADDRESS_0\n", error);
 	}
     } else
-	printk("No BIOS32 extensions present. This eata_dma release "
-	       "still depends on it.\nSkipping scan for PCI HBAs. Sorry.\n");
+	printk("eata_dma: No BIOS32 extensions present. This driver release "
+	       "still depends on it.\n"
+               "          Skipping scan for PCI HBAs. \n");
 #endif /* #ifndef CONFIG_PCI */
     return;
 }
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/eata_dma.h linux/drivers/scsi/eata_dma.h
--- v1.3.5/linux/drivers/scsi/eata_dma.h	Thu Jun 29 19:02:49 1995
+++ linux/drivers/scsi/eata_dma.h	Fri Jun 30 15:30:56 1995
@@ -112,6 +112,6 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/eata_dma_proc.h linux/drivers/scsi/eata_dma_proc.h
--- v1.3.5/linux/drivers/scsi/eata_dma_proc.h	Thu Jun 29 19:02:49 1995
+++ linux/drivers/scsi/eata_dma_proc.h	Fri Jun 30 15:30:56 1995
@@ -1,22 +1,22 @@
 
 struct lun_map {
     __u8   id:5,
-	 chan:3;
+     chan:3;
     __u8 lun;
 };
 
 typedef struct emul_pp {
     __u8 p_code:6,
-	   null:1,
-	 p_save:1;
+       null:1,
+     p_save:1;
     __u8 p_length;
     __u16 cylinder;
     __u8 heads;
     __u8 sectors;
     __u8 null2;
     __u8 s_lunmap:4,
-	      ems:1;
-    __u16 drive_type;   /* In Little Endian ! */
+	  ems:1;
+    __u16 drive_type;	/* In Little Endian ! */
     struct lun_map lunmap[4];
 }emulpp;
 
@@ -25,7 +25,7 @@
 
 typedef struct log_sheader {
     __u8 page_code,
-	 reserved;
+     reserved;
     __u16 length;
 }logsh;
 
@@ -33,210 +33,210 @@
 /* Log Sense Statistics */
 
 typedef struct read_command_statistics {
-    __u16 code;        /* 0x01 */
+    __u16 code;	       /* 0x01 */
     __u8  flags;
     __u8  length;      /* 0x24 */
     __u32 h_commands,
-	  uncached,
-	  la_cmds,
-	  la_blks,
-	  la_hits,
-	  missed,
-	  hits,
-	  seq_la_blks,
-	  seq_la_hits;
+      uncached,
+      la_cmds,
+      la_blks,
+      la_hits,
+      missed,
+      hits,
+      seq_la_blks,
+      seq_la_hits;
 }r_cmd_stat;
 
 typedef struct write_command_statistics {
-    __u16 code;        /* 0x03 */
+    __u16 code;	       /* 0x03 */
     __u8  flags;
     __u8  length;      /* 0x28 */
     __u32 h_commands,
-	  uncached,
-	  thru,
-	  bypass,
-	  soft_err,
-	  hits,
-	  b_idle,
-	  b_activ,
-	  b_blks,
-	  b_blks_clean;
+      uncached,
+      thru,
+      bypass,
+      soft_err,
+      hits,
+      b_idle,
+      b_activ,
+      b_blks,
+      b_blks_clean;
 }w_cmd_stat;
 
 typedef struct host_command_statistics {
-    __u16 code;          /* 0x02, 0x04 */
+    __u16 code;		 /* 0x02, 0x04 */
     __u8  flags;
-    __u8  length;        /* 0x30 */
+    __u8  length;	 /* 0x30 */
     __u32 sizes[12];
 }hst_cmd_stat;
 
 typedef struct physical_command_statistics {
-    __u16 code;          /* 0x06, 0x07 */ 
+    __u16 code;		 /* 0x06, 0x07 */ 
     __u8  flags;
-    __u8  length;        /* 0x34 */
+    __u8  length;	 /* 0x34 */
     __u32 sizes[13]; 
 }phy_cmd_stat;
 
 typedef struct misc_device_statistics {
-    __u16 code;           /* 0x05 */
+    __u16 code;		  /* 0x05 */
     __u8  flags;
-    __u8  length;         /* 0x10 */
+    __u8  length;	  /* 0x10 */
     __u32 disconnect,
-	  pass_thru,
-	  sg_commands,
-	  stripe_boundary_crosses;
+      pass_thru,
+      sg_commands,
+      stripe_boundary_crosses;
 }msc_stats;
  
 /* Configuration Pages */
 
 typedef struct controller_configuration {
-    __u16 code;           /* 0x01 */
+    __u16 code;		  /* 0x01 */
     __u8  flags;
-    __u8  length;         /* 0x02 */
+    __u8  length;	  /* 0x02 */
     __u8  intt:1,
-	   sec:1,
-	   csh:1,
-	   key:1,
-	   tmr:1,
-	   srs:1,
-	   nvr:1;
+       sec:1,
+       csh:1,
+       key:1,
+       tmr:1,
+       srs:1,
+       nvr:1;
     __u8  interrupt;
 }coco;
 
 typedef struct controller_hardware_errors {
-    __u16 code;           /* 0x02 */
+    __u16 code;		  /* 0x02 */
     __u8  flags;
-    __u8  length;         /* 0x02 */
+    __u8  length;	  /* 0x02 */
     __u8  unused:1,
-	     per:1;
+	 per:1;
     __u8  interrupt;
 }coher;
 
 typedef struct memory_map {
-    __u16 code;           /* 0x03, 0x04 */
+    __u16 code;		  /* 0x03, 0x04 */
     __u8  flags;
-    __u8  length;         /* 0x04 */
+    __u8  length;	  /* 0x04 */
     __u32 memory_map;
 }mema;
 
 typedef struct scsi_transfer {
-    __u16 code;           /* 0x05 */
+    __u16 code;		  /* 0x05 */
     __u8  flags;
-    __u8  length;         /* 0x04 */
+    __u8  length;	  /* 0x04 */
     __u8  offset,
-	  period;
+      period;
     __u16 speed;
 }scsitrans;
 
 typedef struct scsi_modes {
-    __u16 code;           /* 0x06 */
+    __u16 code;		  /* 0x06 */
     __u8  flags;
-    __u8  length;         /* 0x02 */
+    __u8  length;	  /* 0x02 */
     __u8  que:1,
-	 cdis:1,
-	 wtru:1,
-	 dasd:1,
-	  ncr:1,
-	 awre:1;
+     cdis:1,
+     wtru:1,
+     dasd:1,
+      ncr:1,
+     awre:1;
     __u8  reserved;
 }scsimod;
 
 typedef struct host_bus {
-    __u16 code;           /* 0x07 */
+    __u16 code;		  /* 0x07 */
     __u8  flags;
-    __u8  length;         /* 0x02 */
+    __u8  length;	  /* 0x02 */
     __u8  speed:6,
-	    pci:1,
-	   eisa:1;
+	pci:1,
+       eisa:1;
     __u8  reserved;
 }hobu;
 
 typedef struct scsi_bus {
-    __u16 code;           /* 0x08 */
+    __u16 code;		  /* 0x08 */
     __u8  flags;
-    __u8  length;         /* 0x02 */
+    __u8  length;	  /* 0x02 */
     __u8  speed:4,
-	    res:1,
-	    ext:1,
-	   wide:1,
-	    dif:1;
+	res:1,
+	ext:1,
+       wide:1,
+	dif:1;
     __u8 busnum;
 }scbu;
 
 typedef struct board_type {
-    __u16 code;           /* 0x09 */
+    __u16 code;		  /* 0x09 */
     __u8  flags;
-    __u8  length;         /* 0x04 */
+    __u8  length;	  /* 0x04 */
     __u8  unused:1,
-	     cmi:1,
-	     dmi:1,
-	    cm4k:1,
-	     cm4:1,
-	    dm4k:1,
-	     dm4:1,
-	     hba:1;
+	 cmi:1,
+	 dmi:1,
+	cm4k:1,
+	 cm4:1,
+	dm4k:1,
+	 dm4:1,
+	 hba:1;
     __u8  cpu_type,
-	  cpu_speed;
+      cpu_speed;
     __u8    sx1:1,
-	    sx2:1,
-	unused2:4,
-	   alrm:1,
-	   srom:1;
+	sx2:1,
+    unused2:4,
+       alrm:1,
+       srom:1;
 }boty;
 
 typedef struct memory_config {
-    __u16 code;           /* 0x0a */
+    __u16 code;		  /* 0x0a */
     __u8  flags;
-    __u8  length;         /* 0x04 */
+    __u8  length;	  /* 0x04 */
     __u8  banksize[4];
 }memco;
 
 typedef struct firmware_info {
-    __u16 code;           /* 0x0b */
+    __u16 code;		  /* 0x0b */
     __u8  flags;
-    __u8  length;         /* 0x04 */
+    __u8  length;	  /* 0x04 */
     __u8  dnld:1,
-	 bs528:1,
-	   fmt:1,
-	 fw528:1;
+     bs528:1,
+       fmt:1,
+     fw528:1;
     __u8  unused1,
-	  fw_type,
-	  unused;
+      fw_type,
+      unused;
 }firm;
 
 typedef struct subsystem_info {
-    __u16 code;           /* 0x0c */
+    __u16 code;		  /* 0x0c */
     __u8  flags;
-    __u8  length;         /* 0x02 */
+    __u8  length;	  /* 0x02 */
     __u8  shlf:1,
-	  swap:1,
-	  noss:1;
+      swap:1,
+      noss:1;
     __u8  reserved;
 }subinf;
 
 typedef struct per_channel_info {
-    __u16 code;           /* 0x0d */
+    __u16 code;		  /* 0x0d */
     __u8  flags;
-    __u8  length;         /* 0x02 */
+    __u8  length;	  /* 0x02 */
     __u8  channel;
     __u8  shlf:1,
-	  swap:1,
-	  noss:1,
-	   srs:1,
-	   que:1,
-	   ext:1,
-	  wide:1,
-	  diff:1;
+      swap:1,
+      noss:1,
+       srs:1,
+       que:1,
+       ext:1,
+      wide:1,
+      diff:1;
 }pcinf;
 
 typedef struct array_limits {
-    __u16 code;           /* 0x0e */
+    __u16 code;		  /* 0x0e */
     __u8  flags;
-    __u8  length;         /* 0x04 */
+    __u8  length;	  /* 0x04 */
     __u8  max_groups,
-	  raid0_drv,
-	  raid35_drv,
-	  unused;
+      raid0_drv,
+      raid35_drv,
+      unused;
 }arrlim;
 
 /*
@@ -254,7 +254,7 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
 
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/eata_generic.h linux/drivers/scsi/eata_generic.h
--- v1.3.5/linux/drivers/scsi/eata_generic.h	Thu Jun 29 19:02:49 1995
+++ linux/drivers/scsi/eata_generic.h	Fri Jun 30 15:30:56 1995
@@ -1,9 +1,9 @@
 /********************************************************
-* Header file for eata_dma.c and eata_pio.c             *
-* Linux EATA SCSI drivers                               *
-* (c) 1993,94,95 Michael Neuffer                        *
+* Header file for eata_dma.c and eata_pio.c		*
+* Linux EATA SCSI drivers				*
+* (c) 1993,94,95 Michael Neuffer			*
 *********************************************************
-* last change: 95/06/20                                 *
+* last change: 95/06/20					*
 ********************************************************/
 
 
@@ -13,7 +13,7 @@
 
 
 /*********************************************
- * Misc. definitions                         *
+ * Misc. definitions			     *
  *********************************************/
 
 #ifndef TRUE
@@ -27,84 +27,84 @@
 
 #define R_LIMIT 0x20000
 
-#define MAXISA     4
-#define MAXEISA   16  
-#define MAXPCI    16
-#define MAXIRQ    16 
+#define MAXISA	   4
+#define MAXEISA	  16  
+#define MAXPCI	  16
+#define MAXIRQ	  16 
 #define MAXTARGET 16
 #define MAXCHANNEL 3
 
-#define IS_ISA     'I'
-#define IS_EISA    'E'
-#define IS_PCI     'P'
-
-#define BROKEN_INQUIRY  1
-
-#define EATA_SIGNATURE  0x45415441     /* BIG ENDIAN coded "EATA" sig.   */
-#define EATA_CP_SIZE    44
-
-#define MAX_PCI_DEVICES 32             /* Maximum # Of Devices Per Bus   */
-#define MAX_METHOD_2    16             /* Max Devices For Method 2       */
-#define MAX_PCI_BUS     16             /* Maximum # Of Busses Allowed    */
-
-#define SG_SIZE         64 
-#define SG_SIZE_BIG     509            /* max. 509 */
-
-#define C_P_L_DIV       2 /* 1 <= C_P_L_DIV <= 8            
-			   * You can use this parameter to fine-tune
-			   * the driver. Depending on the number of 
-			   * devices and their speed and ability to queue 
-			   * commands, you will get the best results with a
-			   * value
-			   * ~= numdevices-(devices_unable_to_queue_commands/2)
-			   * The reason for this is that the disk driver 
-			   * tends to flood the queue, so that other 
-			   * drivers have problems to queue commands 
-			   * themselves. This can for example result in 
-			   * the effect that the tape stops during disk 
-			   * accesses. 
-			   */
+#define IS_ISA	   'I'
+#define IS_EISA	   'E'
+#define IS_PCI	   'P'
+
+#define BROKEN_INQUIRY	1
+
+#define EATA_SIGNATURE	0x45415441     /* BIG ENDIAN coded "EATA" sig.	 */
+#define EATA_CP_SIZE	44
+
+#define MAX_PCI_DEVICES 32	       /* Maximum # Of Devices Per Bus	 */
+#define MAX_METHOD_2	16	       /* Max Devices For Method 2	 */
+#define MAX_PCI_BUS	16	       /* Maximum # Of Busses Allowed	 */
+
+#define SG_SIZE		64 
+#define SG_SIZE_BIG	509	       /* max. 509 */
+
+#define C_P_L_DIV	2 /* 1 <= C_P_L_DIV <= 8	    
+	       * You can use this parameter to fine-tune
+	       * the driver. Depending on the number of 
+	       * devices and their speed and ability to queue 
+	       * commands, you will get the best results with a
+	       * value
+	       * ~= numdevices-(devices_unable_to_queue_commands/2)
+	       * The reason for this is that the disk driver 
+	       * tends to flood the queue, so that other 
+	       * drivers have problems to queue commands 
+	       * themselves. This can for example result in 
+	       * the effect that the tape stops during disk 
+	       * accesses. 
+	       */
 
-#define FREE       0
-#define OK         0
+#define FREE	   0
+#define OK	   0
 #define NO_TIMEOUT 0
-#define USED       1
-#define TIMEOUT    2
-#define RESET      4
-#define LOCKED     8
+#define USED	   1
+#define TIMEOUT	   2
+#define RESET	   4
+#define LOCKED	   8
 
-#define HD(cmd)  ((hostdata *)&(cmd->host->hostdata))
-#define CD(cmd)  ((struct eata_ccb *)(cmd->host_scribble))
+#define HD(cmd)	 ((hostdata *)&(cmd->host->hostdata))
+#define CD(cmd)	 ((struct eata_ccb *)(cmd->host_scribble))
 #define SD(host) ((hostdata *)&(host->hostdata))
 
 #define DELAY(x) { __u32 i; i = jiffies + x; while (jiffies < i); }
-#define DEL2(x)  { __u32 i; for (i = 0; i < 0xffff * x; i++); }
+#define DEL2(x)	 { __u32 i; for (i = 0; i < 0xffff * x; i++); }
 
 /***********************************************
  *    EATA Command & Register definitions      *
  ***********************************************/
-#define PCI_REG_DPTconfig        0x40    
-#define PCI_REG_PumpModeAddress  0x44    
-#define PCI_REG_PumpModeData     0x48    
-#define PCI_REG_ConfigParam1     0x50    
-#define PCI_REG_ConfigParam2     0x54    
+#define PCI_REG_DPTconfig	 0x40	 
+#define PCI_REG_PumpModeAddress	 0x44	 
+#define PCI_REG_PumpModeData	 0x48	 
+#define PCI_REG_ConfigParam1	 0x50	 
+#define PCI_REG_ConfigParam2	 0x54	 
 
 
-#define EATA_CMD_PIO_SETUPTEST   0xc6
+#define EATA_CMD_PIO_SETUPTEST	 0xc6
 #define EATA_CMD_PIO_READ_CONFIG 0xf0
-#define EATA_CMD_PIO_SET_CONFIG  0xf1
-#define EATA_CMD_PIO_SEND_CP     0xf2
-#define EATA_CMD_PIO_RECEIVE_SP  0xf3
-#define EATA_CMD_PIO_TRUNC       0xf4
+#define EATA_CMD_PIO_SET_CONFIG	 0xf1
+#define EATA_CMD_PIO_SEND_CP	 0xf2
+#define EATA_CMD_PIO_RECEIVE_SP	 0xf3
+#define EATA_CMD_PIO_TRUNC	 0xf4
 
-#define EATA_CMD_RESET           0xf9
-#define EATA_CMD_IMMEDIATE       0xfa
+#define EATA_CMD_RESET		 0xf9
+#define EATA_CMD_IMMEDIATE	 0xfa
 
 #define EATA_CMD_DMA_READ_CONFIG 0xfd
-#define EATA_CMD_DMA_SET_CONFIG  0xfe
-#define EATA_CMD_DMA_SEND_CP     0xff
+#define EATA_CMD_DMA_SET_CONFIG	 0xfe
+#define EATA_CMD_DMA_SEND_CP	 0xff
 
-#define ECS_EMULATE_SENSE        0xd4
+#define ECS_EMULATE_SENSE	 0xd4
 
 
 #define GENERIC_ABORT  0x00 
@@ -112,136 +112,136 @@
 #define BUS_RESET      0x02
 #define SPECIFIC_ABORT 0x03
 #define QUIET_INTR     0x04
-#define COLD_BOOT_HBA  0x06        /* Only as a last resort     */
+#define COLD_BOOT_HBA  0x06	   /* Only as a last resort	*/
 #define FORCE_IO       0x07
 
 
-#define HA_WCOMMAND    0x07        /* command register offset   */
-#define HA_WCOMMAND2   0x06        /* immediate command offset  */
+#define HA_WCOMMAND    0x07	   /* command register offset	*/
+#define HA_WCOMMAND2   0x06	   /* immediate command offset	*/
 #define HA_WSUBCODE    0x05 
 #define HA_WSUBLUN     0x04 
-#define HA_WDMAADDR    0x02        /* DMA address LSB offset    */  
-#define HA_RAUXSTAT    0x08        /* aux status register offset*/
-#define HA_RSTATUS     0x07        /* status register offset    */
-#define HA_RDATA       0x00        /* data register (16bit)     */
-
-#define HA_ABUSY       0x01        /* aux busy bit              */
-#define HA_AIRQ        0x02        /* aux IRQ pending bit       */
-#define HA_SERROR      0x01        /* pr. command ended in error*/
-#define HA_SMORE       0x02        /* more data soon to come    */
-#define HA_SCORR       0x04        /* data corrected            */
-#define HA_SDRQ        0x08        /* data request active       */
-#define HA_SSC         0x10        /* seek complete             */
-#define HA_SFAULT      0x20        /* write fault               */
-#define HA_SREADY      0x40        /* drive ready               */
-#define HA_SBUSY       0x80        /* drive busy                */
+#define HA_WDMAADDR    0x02	   /* DMA address LSB offset	*/  
+#define HA_RAUXSTAT    0x08	   /* aux status register offset*/
+#define HA_RSTATUS     0x07	   /* status register offset	*/
+#define HA_RDATA       0x00	   /* data register (16bit)	*/
+
+#define HA_ABUSY       0x01	   /* aux busy bit		*/
+#define HA_AIRQ	       0x02	   /* aux IRQ pending bit	*/
+#define HA_SERROR      0x01	   /* pr. command ended in error*/
+#define HA_SMORE       0x02	   /* more data soon to come	*/
+#define HA_SCORR       0x04	   /* data corrected		*/
+#define HA_SDRQ	       0x08	   /* data request active	*/
+#define HA_SSC	       0x10	   /* seek complete		*/
+#define HA_SFAULT      0x20	   /* write fault		*/
+#define HA_SREADY      0x40	   /* drive ready		*/
+#define HA_SBUSY       0x80	   /* drive busy		*/
 #define HA_SDRDY       HA_SSC+HA_SREADY+HA_SDRQ 
 
 /**********************************************
- * Message definitions                        *
+ * Message definitions			      *
  **********************************************/
 
-#define HA_NO_ERROR      0x00   /* No Error                             */
-#define HA_ERR_SEL_TO    0x01   /* Selection Timeout                    */
-#define HA_ERR_CMD_TO    0x02   /* Command Timeout                      */
-#define HA_ERR_RESET     0x03   /* SCSI Bus Reset Received              */
-#define HA_INIT_POWERUP  0x04   /* Initial Controller Power-up          */
-#define HA_UNX_BUSPHASE  0x05   /* Unexpected Bus Phase                 */
-#define HA_UNX_BUS_FREE  0x06   /* Unexpected Bus Free                  */
-#define HA_BUS_PARITY    0x07   /* Bus Parity Error                     */
-#define HA_SCSI_HUNG     0x08   /* SCSI Hung                            */
-#define HA_UNX_MSGRJCT   0x09   /* Unexpected Message Rejected          */
-#define HA_RESET_STUCK   0x0a   /* SCSI Bus Reset Stuck                 */
-#define HA_RSENSE_FAIL   0x0b   /* Auto Request-Sense Failed            */
-#define HA_PARITY_ERR    0x0c   /* Controller Ram Parity Error          */
-#define HA_CP_ABORT_NA   0x0d   /* Abort Message sent to non-active cmd */
-#define HA_CP_ABORTED    0x0e   /* Abort Message sent to active cmd     */
-#define HA_CP_RESET_NA   0x0f   /* Reset Message sent to non-active cmd */
-#define HA_CP_RESET      0x10   /* Reset Message sent to active cmd     */
-#define HA_ECC_ERR       0x11   /* Controller Ram ECC Error             */
-#define HA_PCI_PARITY    0x12   /* PCI Parity Error                     */
-#define HA_PCI_MABORT    0x13   /* PCI Master Abort                     */
-#define HA_PCI_TABORT    0x14   /* PCI Target Abort                     */
-#define HA_PCI_STABORT   0x15   /* PCI Signaled Target Abort            */
+#define HA_NO_ERROR	 0x00	/* No Error				*/
+#define HA_ERR_SEL_TO	 0x01	/* Selection Timeout			*/
+#define HA_ERR_CMD_TO	 0x02	/* Command Timeout			*/
+#define HA_ERR_RESET	 0x03	/* SCSI Bus Reset Received		*/
+#define HA_INIT_POWERUP	 0x04	/* Initial Controller Power-up		*/
+#define HA_UNX_BUSPHASE	 0x05	/* Unexpected Bus Phase			*/
+#define HA_UNX_BUS_FREE	 0x06	/* Unexpected Bus Free			*/
+#define HA_BUS_PARITY	 0x07	/* Bus Parity Error			*/
+#define HA_SCSI_HUNG	 0x08	/* SCSI Hung				*/
+#define HA_UNX_MSGRJCT	 0x09	/* Unexpected Message Rejected		*/
+#define HA_RESET_STUCK	 0x0a	/* SCSI Bus Reset Stuck			*/
+#define HA_RSENSE_FAIL	 0x0b	/* Auto Request-Sense Failed		*/
+#define HA_PARITY_ERR	 0x0c	/* Controller Ram Parity Error		*/
+#define HA_CP_ABORT_NA	 0x0d	/* Abort Message sent to non-active cmd */
+#define HA_CP_ABORTED	 0x0e	/* Abort Message sent to active cmd	*/
+#define HA_CP_RESET_NA	 0x0f	/* Reset Message sent to non-active cmd */
+#define HA_CP_RESET	 0x10	/* Reset Message sent to active cmd	*/
+#define HA_ECC_ERR	 0x11	/* Controller Ram ECC Error		*/
+#define HA_PCI_PARITY	 0x12	/* PCI Parity Error			*/
+#define HA_PCI_MABORT	 0x13	/* PCI Master Abort			*/
+#define HA_PCI_TABORT	 0x14	/* PCI Target Abort			*/
+#define HA_PCI_STABORT	 0x15	/* PCI Signaled Target Abort		*/
 
 /**********************************************
- *  Other  definitions                        *
+ *  Other  definitions			      *
  **********************************************/
 
 struct reg_bit {      /* reading this one will clear the interrupt    */
-    __u8 error:1;     /* previous command ended in an error           */
+    __u8 error:1;     /* previous command ended in an error	      */
     __u8 more:1;      /* more DATA coming soon, poll BSY & DRQ (PIO)  */
     __u8 corr:1;      /* data read was successfully corrected with ECC*/
-    __u8 drq:1;       /* data request active  */     
-    __u8 sc:1;        /* seek complete        */
-    __u8 fault:1;     /* write fault          */
-    __u8 ready:1;     /* drive ready          */
+    __u8 drq:1;	      /* data request active  */     
+    __u8 sc:1;	      /* seek complete	      */
+    __u8 fault:1;     /* write fault	      */
+    __u8 ready:1;     /* drive ready	      */
     __u8 busy:1;      /* controller busy      */
 };
 
 struct reg_abit {     /* reading this won't clear the interrupt */
-    __u8 abusy:1;     /* auxiliary busy                         */
-    __u8 irq:1;       /* set when drive interrupt is asserted   */
+    __u8 abusy:1;     /* auxiliary busy				*/
+    __u8 irq:1;	      /* set when drive interrupt is asserted	*/
     __u8 dummy:6;
 };
 
-struct eata_register {      /* EATA register set */
-    __u8 data_reg[2];       /* R, couldn't figure this one out          */
-    __u8 cp_addr[4];        /* W, CP address register                   */
+struct eata_register {	    /* EATA register set */
+    __u8 data_reg[2];	    /* R, couldn't figure this one out		*/
+    __u8 cp_addr[4];	    /* W, CP address register			*/
     union { 
-	__u8 command;       /* W, command code: [read|set] conf, send CP*/
-	struct reg_bit status;  /* R, see register_bit1                 */
-	__u8 statusbyte;
+    __u8 command;	/* W, command code: [read|set] conf, send CP*/
+    struct reg_bit status;  /* R, see register_bit1		    */
+    __u8 statusbyte;
     } ovr;   
-    struct reg_abit aux_stat; /* R, see register_bit2                   */
+    struct reg_abit aux_stat; /* R, see register_bit2			*/
 };
 
-struct get_conf {             /* Read Configuration Array               */
-    __u32  len;               /* Should return 0x22, 0x24, etc          */
-    __u32 signature;          /* Signature MUST be "EATA"               */
+struct get_conf {	      /* Read Configuration Array		*/
+    __u32  len;		      /* Should return 0x22, 0x24, etc		*/
+    __u32 signature;	      /* Signature MUST be "EATA"		*/
     __u8    version2:4,
-	     version:4;       /* EATA Version level                     */
-    __u8 OCS_enabled:1,       /* Overlap Command Support enabled        */
-	 TAR_support:1,       /* SCSI Target Mode supported             */
-	      TRNXFR:1,       /* Truncate Transfer Cmd not necessary    */
-			      /* Only used in PIO Mode                  */
-	MORE_support:1,       /* MORE supported (only PIO Mode)         */
-	 DMA_support:1,       /* DMA supported Driver uses only         */
-			      /* this mode                              */
-	   DMA_valid:1,       /* DRQ value in Byte 30 is valid          */
-		 ATA:1,       /* ATA device connected (not supported)   */
-	   HAA_valid:1;       /* Hostadapter Address is valid           */
-
-    __u16 cppadlen;           /* Number of pad bytes send after CD data */
-			      /* set to zero for DMA commands           */
-    __u8 scsi_id[4];          /* SCSI ID of controller 2-0 Byte 0 res.  */
-			      /* if not, zero is returned               */
-    __u32  cplen;             /* CP length: number of valid cp bytes    */
-    __u32  splen;             /* Number of bytes returned after         */ 
-			      /* Receive SP command                     */
-    __u16 queuesiz;           /* max number of queueable CPs            */
+	 version:4;	  /* EATA Version level			    */
+    __u8 OCS_enabled:1,	      /* Overlap Command Support enabled	*/
+     TAR_support:1,	  /* SCSI Target Mode supported		    */
+	  TRNXFR:1,	  /* Truncate Transfer Cmd not necessary    */
+		  /* Only used in PIO Mode		    */
+    MORE_support:1,	  /* MORE supported (only PIO Mode)	    */
+     DMA_support:1,	  /* DMA supported Driver uses only	    */
+		  /* this mode				    */
+       DMA_valid:1,	  /* DRQ value in Byte 30 is valid	    */
+	 ATA:1,	      /* ATA device connected (not supported)	*/
+       HAA_valid:1;	  /* Hostadapter Address is valid	    */
+
+    __u16 cppadlen;	      /* Number of pad bytes send after CD data */
+		  /* set to zero for DMA commands	    */
+    __u8 scsi_id[4];	      /* SCSI ID of controller 2-0 Byte 0 res.	*/
+		  /* if not, zero is returned		    */
+    __u32  cplen;	      /* CP length: number of valid cp bytes	*/
+    __u32  splen;	      /* Number of bytes returned after		*/ 
+		  /* Receive SP command			    */
+    __u16 queuesiz;	      /* max number of queueable CPs		*/
     __u16 dummy;
-    __u16 SGsiz;              /* max number of SG table entries         */
-    __u8    IRQ:4,            /* IRQ used this HA                       */
-	 IRQ_TR:1,            /* IRQ Trigger: 0=edge, 1=level           */
-	 SECOND:1,            /* This is a secondary controller         */  
-    DMA_channel:2;            /* DRQ index, DRQ is 2comp of DRQX        */
-    __u8 sync;                /* device at ID 7 tru 0 is running in     */
-			      /* synchronous mode, this will disappear  */
-    __u8   DSBLE:1,           /* ISA i/o addressing is disabled         */
-	 FORCADR:1,           /* i/o address has been forced            */
-	  SG_64K:1,
-	  SG_UAE:1,
-		:4;
-    __u8  MAX_ID:5,           /* Max number of SCSI target IDs          */
-	MAX_CHAN:3;           /* Number of SCSI busses on HBA           */
-    __u8 MAX_LUN;             /* Max number of LUNs                     */
-    __u8        :3,
-	 AUTOTRM:1,
-	 M1_inst:1,
-	 ID_qest:1,           /* Raidnum ID is questionable             */
-	  is_PCI:1,           /* HBA is PCI                             */
-	 is_EISA:1;           /* HBA is EISA                            */
+    __u16 SGsiz;	      /* max number of SG table entries		*/
+    __u8    IRQ:4,	      /* IRQ used this HA			*/
+     IRQ_TR:1,		  /* IRQ Trigger: 0=edge, 1=level	    */
+     SECOND:1,		  /* This is a secondary controller	    */	
+    DMA_channel:2;	      /* DRQ index, DRQ is 2comp of DRQX	*/
+    __u8 sync;		      /* device at ID 7 tru 0 is running in	*/
+		  /* synchronous mode, this will disappear  */
+    __u8   DSBLE:1,	      /* ISA i/o addressing is disabled		*/
+     FORCADR:1,		  /* i/o address has been forced	    */
+      SG_64K:1,
+      SG_UAE:1,
+	:4;
+    __u8  MAX_ID:5,	      /* Max number of SCSI target IDs		*/
+    MAX_CHAN:3;		  /* Number of SCSI busses on HBA	    */
+    __u8 MAX_LUN;	      /* Max number of LUNs			*/
+    __u8	:3,
+     AUTOTRM:1,
+     M1_inst:1,
+     ID_qest:1,		  /* Raidnum ID is questionable		    */
+      is_PCI:1,		  /* HBA is PCI				    */
+     is_EISA:1;		  /* HBA is EISA			    */
     __u8 unused[478]; 
 };
 
@@ -251,62 +251,62 @@
     __u32 len;
 };
 
-struct eata_ccb {             /* Send Command Packet structure      */
+struct eata_ccb {	      /* Send Command Packet structure	    */
  
-    __u8 SCSI_Reset:1,        /* Cause a SCSI Bus reset on the cmd  */
-	   HBA_Init:1,        /* Cause Controller to reinitialize   */
-       Auto_Req_Sen:1,        /* Do Auto Request Sense on errors    */
-	    scatter:1,        /* Data Ptr points to a SG Packet     */
-	     Resrvd:1,        /* RFU                                */
-	  Interpret:1,        /* Interpret the SCSI cdb of own use  */
-	    DataOut:1,        /* Data Out phase with command        */
-	     DataIn:1;        /* Data In phase with command         */
-    __u8 reqlen;              /* Request Sense Length               */ 
-			      /* Valid if Auto_Req_Sen=1            */
+    __u8 SCSI_Reset:1,	      /* Cause a SCSI Bus reset on the cmd  */
+       HBA_Init:1,	  /* Cause Controller to reinitialize	*/
+       Auto_Req_Sen:1,	      /* Do Auto Request Sense on errors    */
+	scatter:1,	  /* Data Ptr points to a SG Packet	*/
+	 Resrvd:1,	  /* RFU				*/
+      Interpret:1,	  /* Interpret the SCSI cdb of own use	*/
+	DataOut:1,	  /* Data Out phase with command	*/
+	 DataIn:1;	  /* Data In phase with command		*/
+    __u8 reqlen;	      /* Request Sense Length		    */ 
+		  /* Valid if Auto_Req_Sen=1		*/
     __u8 unused[3];
-    __u8  FWNEST:1,           /* send cmd to phys RAID component*/
-	 unused2:7;
-    __u8 Phsunit:1,           /* physical unit on mirrored pair */
-	    I_AT:1,           /* inhibit address translation    */
-	 I_HBA_C:1,           /* HBA inhibit caching            */
-	 unused3:5;
+    __u8  FWNEST:1,	      /* send cmd to phys RAID component*/
+     unused2:7;
+    __u8 Phsunit:1,	      /* physical unit on mirrored pair */
+	I_AT:1,		  /* inhibit address translation    */
+     I_HBA_C:1,		  /* HBA inhibit caching	    */
+     unused3:5;
 
-    __u8     cp_id:5,         /* SCSI Device ID of target       */ 
-	cp_channel:3;         /* SCSI Channel # of HBA          */
+    __u8     cp_id:5,	      /* SCSI Device ID of target	*/ 
+    cp_channel:3;	  /* SCSI Channel # of HBA	    */
     __u8    cp_lun:3,
-		  :2,
-	 cp_luntar:1,         /* CP is for target ROUTINE       */
-	 cp_dispri:1,         /* Grant disconnect privilege     */
-       cp_identify:1;         /* Always TRUE                    */         
-    __u8 cp_msg1;             /* Message bytes 0-3              */
+	  :2,
+     cp_luntar:1,	  /* CP is for target ROUTINE	    */
+     cp_dispri:1,	  /* Grant disconnect privilege	    */
+       cp_identify:1;	      /* Always TRUE			*/	   
+    __u8 cp_msg1;	      /* Message bytes 0-3		*/
     __u8 cp_msg2;
     __u8 cp_msg3;
-    __u8 cp_cdb[12];          /* Command Descriptor Block       */
-    __u32 cp_datalen;         /* Data Transfer Length           */
-			      /* If scatter=1 len of sg package */
-    void *cp_viraddr;         /* address of this ccb            */
-    __u32 cp_dataDMA;         /* Data Address, if scatter=1     *
-			       * address of scatter packet      */  
-    __u32 cp_statDMA;         /* address for Status Packet      */ 
-    __u32 cp_reqDMA;          /* Request Sense Address, used if */
-			      /* CP command ends with error     */
-			      /* Additional CP info begins here */
+    __u8 cp_cdb[12];	      /* Command Descriptor Block	*/
+    __u32 cp_datalen;	      /* Data Transfer Length		*/
+		  /* If scatter=1 len of sg package */
+    void *cp_viraddr;	      /* address of this ccb		*/
+    __u32 cp_dataDMA;	      /* Data Address, if scatter=1	*
+		   * address of scatter packet	    */	
+    __u32 cp_statDMA;	      /* address for Status Packet	*/ 
+    __u32 cp_reqDMA;	      /* Request Sense Address, used if */
+		  /* CP command ends with error	    */
+		  /* Additional CP info begins here */
     __u32 timeout;
     __u8 retries;
-    __u8 status;              /* status of this queueslot       */
+    __u8 status;	      /* status of this queueslot	*/
 
-    Scsi_Cmnd *cmd;           /* address of cmd                 */
+    Scsi_Cmnd *cmd;	      /* address of cmd			*/
     struct eata_sg_list *sg_list;
 };
 
 
 struct eata_sp {
-    __u8 hba_stat:7,          /* HBA status                     */
-	      EOC:1;          /* True if command finished       */
-    __u8 scsi_stat;           /* Target SCSI status             */       
+    __u8 hba_stat:7,	      /* HBA status			*/
+	  EOC:1;	  /* True if command finished	    */
+    __u8 scsi_stat;	      /* Target SCSI status		*/	 
     __u8 reserved[2];
-    __u32  residue_len;       /* Number of bytes not transferred */
-    struct eata_ccb *ccb;     /* Address set in COMMAND PACKET  */
+    __u32  residue_len;	      /* Number of bytes not transferred */
+    struct eata_ccb *ccb;     /* Address set in COMMAND PACKET	*/
     __u8 msg[12];
 };
 
@@ -315,45 +315,45 @@
     __u8   name[18];
     __u8   revision[6];
     __u8   EATA_revision;
-    __u8   bustype;              /* bustype of HBA             */
-    __u8   channel;              /* # of avail. scsi channels  */
-    __u8   state;                /* state of HBA               */
-    __u8   primary;              /* true if primary            */
-    __u8   broken_INQUIRY:1;     /* This is an EISA HBA with   *
-				  * broken INQUIRY             */
+    __u8   bustype;		 /* bustype of HBA	       */
+    __u8   channel;		 /* # of avail. scsi channels  */
+    __u8   state;		 /* state of HBA	       */
+    __u8   primary;		 /* true if primary	       */
+    __u8   broken_INQUIRY:1;	 /* This is an EISA HBA with   *
+		  * broken INQUIRY	       */
     __u32  reads[13];
     __u32  writes[13];
-				 /* state of Target (RESET,..) */
+		 /* state of Target (RESET,..) */
     __u8   t_state[MAXCHANNEL][MAXTARGET];   
-				 /* timeouts on target         */
+		 /* timeouts on target	       */
     __u32  t_timeout[MAXCHANNEL][MAXTARGET]; 
-    __u32  last_ccb;             /* Last used ccb              */
-    __u32  cplen;                /* size of CP in words        */
-    __u16  cppadlen;             /* pad length of cp in words  */
-    __u8   hostid;               /* SCSI ID of HBA             */
-    __u8   devflags;             /* bits set for detected devices */
-    __u8   moresupport;          /* HBA supports MORE flag     */
-    struct Scsi_Host *next;         
+    __u32  last_ccb;		 /* Last used ccb	       */
+    __u32  cplen;		 /* size of CP in words	       */
+    __u16  cppadlen;		 /* pad length of cp in words  */
+    __u8   hostid;		 /* SCSI ID of HBA	       */
+    __u8   devflags;		 /* bits set for detected devices */
+    __u8   moresupport;		 /* HBA supports MORE flag     */
+    struct Scsi_Host *next;	    
     struct Scsi_Host *prev;
-    struct eata_sp sp;           /* status packet              */ 
-    struct eata_ccb ccb[0];      /* ccb array begins here      */
+    struct eata_sp sp;		 /* status packet	       */ 
+    struct eata_ccb ccb[0];	 /* ccb array begins here      */
 }hostdata;
 
 /* structure for max. 2 emulated drives */
 struct drive_geom_emul {
-    __u8  trans;                 /* translation flag 1=transl */
-    __u8  channel;               /* SCSI channel number       */
-    __u8  HBA;                   /* HBA number (prim/sec)     */
-    __u8  id;                    /* drive id                  */
-    __u8  lun;                   /* drive lun                 */
-    __u32 heads;                 /* number of heads           */
-    __u32 sectors;               /* number of sectors         */
-    __u32 cylinder;              /* number of cylinders       */
+    __u8  trans;		 /* translation flag 1=transl */
+    __u8  channel;		 /* SCSI channel number	      */
+    __u8  HBA;			 /* HBA number (prim/sec)     */
+    __u8  id;			 /* drive id		      */
+    __u8  lun;			 /* drive lun		      */
+    __u32 heads;		 /* number of heads	      */
+    __u32 sectors;		 /* number of sectors	      */
+    __u32 cylinder;		 /* number of cylinders	      */
 };
 
 struct geom_emul {
-    __u8 bios_drives;            /* number of emulated drives */
-    struct drive_geom_emul drv[2]; /* drive structures        */
+    __u8 bios_drives;		 /* number of emulated drives */
+    struct drive_geom_emul drv[2]; /* drive structures	      */
 };
 
 #endif /* _EATA_GENERIC_H */
@@ -373,6 +373,6 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c
--- v1.3.5/linux/drivers/scsi/eata_pio.c	Thu Jun 29 19:02:49 1995
+++ linux/drivers/scsi/eata_pio.c	Fri Jun 30 15:30:56 1995
@@ -878,7 +878,7 @@
 {
 
 #ifndef CONFIG_PCI
-    printk("Kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
+    printk("eata_pio: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
 #else
     
     u8 pci_bus, pci_device_fn;
@@ -964,9 +964,9 @@
 		       "PCI_BASE_ADDRESS_0\n", error);
 	}
     } else
-	printk("No BIOS32 extensions present. This eata_pio release "
+	printk("eata_pio: No BIOS32 extensions present. This driver release "
 	       "still depends on it.\n"
-	       "Skipping scan for PCI HBAs. Sorry.\n");
+	       "          Skipping scan for PCI HBAs.\n");
 #endif /* #ifndef CONFIG_PCI */
     return;
 }
@@ -981,11 +981,6 @@
     DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG,
 	printk("Using lots of delays to let you read the debugging output\n"));
     
-#ifndef DBG_EISA
-
-printk("DBG_EISA not defined !!!\n");
-
-#endif
 
     find_pio_PCI(&gc, tpnt);
 
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/eata_pio.h linux/drivers/scsi/eata_pio.h
--- v1.3.5/linux/drivers/scsi/eata_pio.h	Thu Jun 29 19:02:49 1995
+++ linux/drivers/scsi/eata_pio.h	Fri Jun 30 15:30:56 1995
@@ -1,8 +1,8 @@
 /********************************************************
 * Header file for eata_pio.c Linux EATA-PIO SCSI driver *
-* (c) 1993,94,95 Michael Neuffer                        *
+* (c) 1993,94,95 Michael Neuffer			*
 *********************************************************
-* last change: 95/06/21                                 *
+* last change: 95/06/21					*
 ********************************************************/
 
 
@@ -19,38 +19,38 @@
 
 #define VER_MAJOR 0
 #define VER_MINOR 0
-#define VER_SUB   "1a"
+#define VER_SUB	  "1a"
 
 /************************************************************************
- * Here you can switch parts of the code on and of                      *
+ * Here you can switch parts of the code on and of			*
  ************************************************************************/
 
-#define VERBOSE_SETUP                   /* show startup screen of 2001 */
-#define ALLOW_DMA_BOARDS 1
+#define VERBOSE_SETUP			/* show startup screen of 2001 */
+#define ALLOW_DMA_BOARDS 0
 
 /************************************************************************
- * Debug options.                                                       * 
- * Enable DEBUG and whichever options you require.                      *
+ * Debug options.							* 
+ * Enable DEBUG and whichever options you require.			*
  ************************************************************************/
-#define DEBUG_EATA      1   /* Enable debug code.                       */
-#define DPT_DEBUG       0   /* Bobs special                             */
-#define DBG_DELAY       0   /* Build in delays so debug messages can be
-			     * be read before they vanish of the top of
-			     * the screen!
-			     */
-#define DBG_PROBE       0   /* Debug probe routines.                    */
-#define DBG_ISA         0   /* Trace ISA routines                       */ 
-#define DBG_EISA        0   /* Trace EISA routines                      */ 
-#define DBG_PCI         0   /* Trace PCI routines                       */ 
-#define DBG_PIO         0   /* Trace get_config_PIO                     */
-#define DBG_COM         0   /* Trace command call                       */
-#define DBG_QUEUE       0   /* Trace command queueing.                  */
-#define DBG_INTR        0   /* Trace interrupt service routine.         */
-#define DBG_INTR2       0   /* Trace interrupt service routine.         */
-#define DBG_PROC        0   /* Debug proc-fs related statistics         */
-#define DBG_PROC_WRITE  0
-#define DBG_REGISTER    0   /* */
-#define DBG_ABNORM      1   /* Debug abnormal actions (reset, abort)    */
+#define DEBUG_EATA	1   /* Enable debug code.			*/
+#define DPT_DEBUG	0   /* Bobs special				*/
+#define DBG_DELAY	0   /* Build in delays so debug messages can be
+                             * be read before they vanish of the top of
+                             * the screen!
+                             */
+#define DBG_PROBE	0   /* Debug probe routines.			*/
+#define DBG_ISA		0   /* Trace ISA routines			*/ 
+#define DBG_EISA	0   /* Trace EISA routines			*/ 
+#define DBG_PCI		0   /* Trace PCI routines			*/ 
+#define DBG_PIO		0   /* Trace get_config_PIO			*/
+#define DBG_COM		0   /* Trace command call			*/
+#define DBG_QUEUE	0   /* Trace command queueing.			*/
+#define DBG_INTR	0   /* Trace interrupt service routine.		*/
+#define DBG_INTR2	0   /* Trace interrupt service routine.		*/
+#define DBG_PROC	0   /* Debug proc-fs related statistics		*/
+#define DBG_PROC_WRITE	0
+#define DBG_REGISTER	0   /* */
+#define DBG_ABNORM	1   /* Debug abnormal actions (reset, abort)	*/
 
 #if DEBUG_EATA 
 #define DBG(x, y)   if ((x)) {y;} 
@@ -76,27 +76,27 @@
 extern int generic_proc_info(char *, char **, off_t, int, int, int);
 
 
-#define EATA_PIO {                   \
-	NULL, NULL,                  \
-	eata_pio_proc_info,/* procinfo       */  \
-	"eata_pio",        /* proc dir entry */  \
-	PROC_SCSI_EATA_PIO,/* proc dir inode */  \
-	 "EATA (Extended Attachment) PIO driver",\
-	eata_pio_detect,             \
-	eata_pio_release,            \
-	NULL, NULL,                  \
-	eata_pio_queue,              \
-	eata_pio_abort,              \
-	eata_pio_reset,              \
-	NULL,   /* Slave attach */   \
-	scsicam_bios_param,          \
-	0,      /* Canqueue     */   \
-	0,      /* this_id      */   \
-	0,      /* sg_tablesize */   \
-	0,      /* cmd_per_lun  */   \
-	0,      /* present      */   \
-	1,      /* True if ISA  */   \
-	ENABLE_CLUSTERING }
+#define EATA_PIO {		     \
+    NULL, NULL,			 \
+    eata_pio_proc_info,/* procinfo	 */  \
+    "eata_pio",	       /* proc dir entry */  \
+    PROC_SCSI_EATA_PIO,/* proc dir inode */  \
+     "EATA (Extended Attachment) PIO driver",\
+    eata_pio_detect,		 \
+    eata_pio_release,		 \
+    NULL, NULL,			 \
+    eata_pio_queue,		 \
+    eata_pio_abort,		 \
+    eata_pio_reset,		 \
+    NULL,   /* Slave attach */	 \
+    scsicam_bios_param,		 \
+    0,	    /* Canqueue	    */	 \
+    0,	    /* this_id	    */	 \
+    0,	    /* sg_tablesize */	 \
+    0,	    /* cmd_per_lun  */	 \
+    0,	    /* present	    */	 \
+    1,	    /* True if ISA  */	 \
+    ENABLE_CLUSTERING }
 
 #endif /* _EATA_PIO_H */
 
@@ -115,6 +115,6 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
--- v1.3.5/linux/drivers/scsi/hosts.h	Thu Jun 29 19:02:50 1995
+++ linux/drivers/scsi/hosts.h	Fri Jun 30 15:30:56 1995
@@ -1,13 +1,13 @@
 /*
  *  hosts.h Copyright (C) 1992 Drew Eckhardt 
- *  mid to low-level SCSI driver interface header by    
- *      Drew Eckhardt 
+ *  mid to low-level SCSI driver interface header by	
+ *	Drew Eckhardt 
  *
  *  <drew@colorado.edu>
  *
- *       Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
- *       add scatter-gather, multiple outstanding request, and other
- *       enhancements.
+ *	 Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
+ *	 add scatter-gather, multiple outstanding request, and other
+ *	 enhancements.
  * 
  *  Further modified by Eric Youngdale to support multiple host adapters
  *  of the same type.
@@ -31,23 +31,23 @@
 #define ENABLE_CLUSTERING 1
 
 /* The various choices mean:
- * NONE: Self evident.  Host adapter is not capable of scatter-gather.
- * ALL:  Means that the host adapter module can do scatter-gather,
- *       and that there is no limit to the size of the table to which
- *       we scatter/gather data.
+ * NONE: Self evident.	Host adapter is not capable of scatter-gather.
+ * ALL:	 Means that the host adapter module can do scatter-gather,
+ *	 and that there is no limit to the size of the table to which
+ *	 we scatter/gather data.
  * Anything else:  Indicates the maximum number of chains that can be
- *       used in one scatter-gather request.
+ *	 used in one scatter-gather request.
  */
 
 /*
  * The Scsi_Host_Template type has all that is needed to interface with a SCSI
- * host in a device independent matter.  There is one entry for each different
+ * host in a device independent matter.	 There is one entry for each different
  * type of host adapter that is supported on the system.
  */
 
 typedef struct scsi_disk Disk;
 
-typedef struct  SHT
+typedef struct	SHT
 {
     
     /* Used with loadable modules so we can construct a linked list. */
@@ -78,7 +78,7 @@
     /*
      * The detect function shall return non zero on detection,
      * indicating the number of host adapters of this particular
-     * type were found.  It should also
+     * type were found.	 It should also
      * initialize all data necessary for this particular
      * SCSI driver.  It is passed the host number, so this host
      * knows where the first entry is in the scsi_hosts[] array.
@@ -121,9 +121,9 @@
 
     /*
      * The QueueCommand function works in a similar manner
-     * to the command function.  It takes an additional parameter,
+     * to the command function.	 It takes an additional parameter,
      * void (* done)(int host, int code) which is passed the host 
-     * # and exit result when the command is complete.  
+     * # and exit result when the command is complete.	
      * Host number is the POSITION IN THE hosts array of THIS
      * host adapter.
      */
@@ -132,7 +132,7 @@
     /*
      * Since the mid level driver handles time outs, etc, we want to 
      * be able to abort the current command.  Abort returns 0 if the 
-     * abortion was successful.  The field SCpnt->abort reason
+     * abortion was successful.	 The field SCpnt->abort reason
      * can be filled in with the appropriate reason why we wanted
      * the abort in the first place, and this will be used
      * in the mid-level code instead of the host_byte().
@@ -141,7 +141,7 @@
      * DID_ABORT  should be returned.
      * 
      * Note that the scsi driver should "clean up" after itself, 
-     * resetting the bus, etc.  if necessary. 
+     * resetting the bus, etc.	if necessary. 
      */
     int (* abort)(Scsi_Cmnd *);
 
@@ -151,7 +151,7 @@
      * The Scsi_Cmnd  is passed so that the reset routine can figure
      * out which host adapter should be reset, and also which command
      * within the command block was responsible for the reset in
-     * the first place.  Some hosts do not implement a reset function,
+     * the first place.	 Some hosts do not implement a reset function,
      * and these hosts must call scsi_request_sense(SCpnt) to keep
      * the command alive.
      */ 
@@ -249,10 +249,10 @@
     Scsi_Host_Template * hostt;
     
     /*
-     *  These three parameters can be used to allow for wide scsi,
-     *  and for host adapters that support multiple busses 
-     *  The first two should be set to 1 more than the actual max id
-     *  or lun (i.e. 8 for normal systems).
+     *	These three parameters can be used to allow for wide scsi,
+     *	and for host adapters that support multiple busses 
+     *	The first two should be set to 1 more than the actual max id
+     *	or lun (i.e. 8 for normal systems).
      */
     unsigned int max_id;
     unsigned int max_lun;
@@ -311,7 +311,7 @@
 
 /* 
  * We use these goofy things because the MM is not set up when we init
- * the scsi subsystem.  By using these functions we can write code that
+ * the scsi subsystem.	By using these functions we can write code that
  * looks normal.  Also, it makes it possible to use the same code for a
  * loadable module. 
  */
@@ -320,7 +320,7 @@
 extern void scsi_init_free(char * ptr, unsigned int size);
 
 void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded,
-		 unchar hchannel, unchar hid, unchar hlun);
+	 unchar hchannel, unchar hid, unchar hlun);
 
 extern int next_scsi_host;
 
@@ -337,17 +337,17 @@
     struct Scsi_Device_Template * next;
     char * name;
     char * tag;
-    int * usage_count;            /* Used for loadable modules */
+    int * usage_count;		  /* Used for loadable modules */
     unsigned char scsi_type;
     unsigned char major;
-    unsigned char nr_dev;         /* Number currently attached */
-    unsigned char dev_noticed;    /* Number of devices detected. */
-    unsigned char dev_max;        /* Current size of arrays */
-    unsigned blk:1;               /* 0 if character device */
+    unsigned char nr_dev;	  /* Number currently attached */
+    unsigned char dev_noticed;	  /* Number of devices detected. */
+    unsigned char dev_max;	  /* Current size of arrays */
+    unsigned blk:1;		  /* 0 if character device */
     int (*detect)(Scsi_Device *); /* Returns 1 if we can attach this device */
-    void (*init)(void);           /* Sizes arrays based upon number of devices
-				   *  detected */
-    void (*finish)(void);         /* Perform initialization after attachment */
+    void (*init)(void);		  /* Sizes arrays based upon number of devices
+		   *  detected */
+    void (*finish)(void);	  /* Perform initialization after attachment */
     int (*attach)(Scsi_Device *); /* Attach devices to arrays */
     void (*detach)(Scsi_Device *);
 };
@@ -372,7 +372,7 @@
 
 /*
  * This is an ugly hack.  If we expect to be able to load devices at run time,
- * we need to leave extra room in some of the data structures.  Doing a 
+ * we need to leave extra room in some of the data structures.	Doing a 
  * realloc to enlarge the structures would be riddled with race conditions, 
  * so until a better solution is discovered, we use this crude approach
  */
@@ -397,6 +397,6 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.3.5/linux/drivers/scsi/scsi.h	Thu Jun 29 19:02:51 1995
+++ linux/drivers/scsi/scsi.h	Fri Jun 30 15:30:56 1995
@@ -454,30 +454,30 @@
     
     /* These elements define the operation we are about to perform */
     unsigned char cmnd[12];
-    unsigned request_bufflen;   /* Actual request size */
+    unsigned request_bufflen;	/* Actual request size */
     
-    void * request_buffer;      /* Actual requested buffer */
+    void * request_buffer;	/* Actual requested buffer */
     
     /* These elements define the operation we ultimately want to perform */
     unsigned char data_cmnd[12];
-    unsigned short old_use_sg;  /* We save  use_sg here when requesting
+    unsigned short old_use_sg;	/* We save  use_sg here when requesting
 				 * sense info */
-    unsigned short use_sg;      /* Number of pieces of scatter-gather */
-    unsigned short sglist_len;  /* size of malloc'd scatter-gather list */
+    unsigned short use_sg;	/* Number of pieces of scatter-gather */
+    unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
     unsigned short abort_reason;/* If the mid-level code requests an
 				 * abort, this is the reason. */
-    unsigned bufflen;           /* Size of data buffer */
-    void *buffer;               /* Data buffer */
+    unsigned bufflen;		/* Size of data buffer */
+    void *buffer;		/* Data buffer */
     
-    unsigned underflow;         /* Return error if less than this amount is 
+    unsigned underflow;		/* Return error if less than this amount is 
 				 * transfered */
     
-    unsigned transfersize;      /* How much we are guaranteed to transfer with
+    unsigned transfersize;	/* How much we are guaranteed to transfer with
 				 * each SCSI transfer (ie, between disconnect /
-				 * reconnects.   Probably == sector size */
+				 * reconnects.	 Probably == sector size */
     
     
-    struct request request;     /* A copy of the command we are working on */
+    struct request request;	/* A copy of the command we are working on */
 
     unsigned char sense_buffer[16];  /* Sense for this command, if needed */
 
@@ -487,8 +487,8 @@
     int timeout_per_command, timeout_total, timeout;
 
     /*
-     *  We handle the timeout differently if it happens when a reset, 
-     *  abort, etc are in process. 
+     *	We handle the timeout differently if it happens when a reset, 
+     *	abort, etc are in process. 
      */
     unsigned volatile char internal_timeout;
     
@@ -500,7 +500,7 @@
     /* End of special cdrom variables */
     
     /* Low-level done function - can be used by low-level driver to point
-     *  to completion function.  Not used by mid/upper level code. */
+     *	to completion function.	 Not used by mid/upper level code. */
     void (*scsi_done)(struct scsi_cmnd *);  
     void (*done)(struct scsi_cmnd *);  /* Mid-level done function */
     
@@ -509,21 +509,21 @@
      * Everything else should be left alone. 
      */
     
-    Scsi_Pointer SCp;   /* Scratchpad used by some host adapters */
+    Scsi_Pointer SCp;	/* Scratchpad used by some host adapters */
     
     unsigned char * host_scribble; /* The host adapter is allowed to
 				    * call scsi_malloc and get some memory
-				    * and hang it here.  The host adapter
+				    * and hang it here.	 The host adapter
 				    * is also expected to call scsi_free
 				    * to release this memory.  (The memory
 				    * obtained by scsi_malloc is guaranteed
 				    * to be at an address < 16Mb). */
     
-    int result;                    /* Status code from lower level driver */
+    int result;			   /* Status code from lower level driver */
     
-    unsigned char tag;             /* SCSI-II queued command tag */
-    unsigned long pid;             /* Process ID, starts at 0 */
-} Scsi_Cmnd;         
+    unsigned char tag;		   /* SCSI-II queued command tag */
+    unsigned long pid;		   /* Process ID, starts at 0 */
+} Scsi_Cmnd;	     
 
 /*
  *  scsi_abort aborts the current command that is executing on host host.
@@ -549,9 +549,9 @@
 extern void build_proc_dir_entries(void);
 
 extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
-extern int        scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
+extern int	  scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
 extern void print_command(unsigned char *);
-extern void print_sense(char *,  Scsi_Cmnd *);
+extern void print_sense(char *,	 Scsi_Cmnd *);
 
 
 #if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR)
@@ -618,7 +618,7 @@
 #define INIT_SCSI_REQUEST \
     if (!CURRENT) {\
 	CLEAR_INTR; \
-	restore_flags(flags);   \
+	restore_flags(flags);	\
 	return; \
     } \
     if (MAJOR(CURRENT->dev) != MAJOR_NR) \
@@ -629,23 +629,23 @@
     }
 #endif
 
-#define SCSI_SLEEP(QUEUE, CONDITION) {              \
-    if (CONDITION) {                    \
+#define SCSI_SLEEP(QUEUE, CONDITION) {		    \
+    if (CONDITION) {			\
 	struct wait_queue wait = { current, NULL};  \
-	add_wait_queue(QUEUE, &wait);           \
-	for(;;) {                           \
-	current->state = TASK_UNINTERRUPTIBLE;      \
-	if (CONDITION) {                \
-		   if (intr_count)                              \
+	add_wait_queue(QUEUE, &wait);		\
+	for(;;) {			    \
+	current->state = TASK_UNINTERRUPTIBLE;	    \
+	if (CONDITION) {		\
+		   if (intr_count)				\
 		      panic("scsi: trying to call schedule() in interrupt" \
 			    ", file %s, line %d.\n", __FILE__, __LINE__);  \
-	   schedule();                  \
-	   }                            \
-	    else                        \
-		   break;                                       \
-	}                       \
-	remove_wait_queue(QUEUE, &wait);        \
-	current->state = TASK_RUNNING;          \
+	   schedule();			\
+	   }				\
+	    else			\
+		   break;					\
+	}			\
+	remove_wait_queue(QUEUE, &wait);	\
+	current->state = TASK_RUNNING;		\
     }; }
 
 #endif
@@ -665,6 +665,6 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.5/linux/drivers/scsi/sd.h linux/drivers/scsi/sd.h
--- v1.3.5/linux/drivers/scsi/sd.h	Thu Jun 29 19:02:53 1995
+++ linux/drivers/scsi/sd.h	Fri Jun 30 15:30:56 1995
@@ -1,18 +1,18 @@
 /*
- *      sd.h Copyright (C) 1992 Drew Eckhardt 
- *      SCSI disk driver header file by
- *              Drew Eckhardt 
+ *	sd.h Copyright (C) 1992 Drew Eckhardt 
+ *	SCSI disk driver header file by
+ *		Drew Eckhardt 
  *
- *      <drew@colorado.edu>
+ *	<drew@colorado.edu>
  *
- *       Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
- *       add scatter-gather, multiple outstanding request, and other
- *       enhancements.
+ *	 Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
+ *	 add scatter-gather, multiple outstanding request, and other
+ *	 enhancements.
  */
 #ifndef _SD_H
 #define _SD_H
 /*
-	$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/07/24 06:27:38 root Exp root $
+    $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/07/24 06:27:38 root Exp root $
 */
 
 #ifndef _SCSI_H
@@ -32,14 +32,14 @@
 extern struct hd_struct * sd;
 
 typedef struct scsi_disk {
-    unsigned capacity;              /* size in blocks */
-    unsigned sector_size;           /* size in bytes */
-    Scsi_Device  *device;           
+    unsigned capacity;		    /* size in blocks */
+    unsigned sector_size;	    /* size in bytes */
+    Scsi_Device	 *device;	    
     unsigned char sector_bit_size;  /* sector_size = 2 to the  bit size power */
     unsigned char sector_bit_shift; /* power of 2 sectors per FS block */
-    unsigned ten:1;                 /* support ten byte read / write */
-    unsigned remap:1;               /* support remapping  */
-    unsigned has_part_table:1;      /* has partition table */
+    unsigned ten:1;		    /* support ten byte read / write */
+    unsigned remap:1;		    /* support remapping  */
+    unsigned has_part_table:1;	    /* has partition table */
 } Scsi_Disk;
 
 extern Scsi_Disk * rscsi_disks;
@@ -61,7 +61,7 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
 
diff -u --recursive --new-file v1.3.5/linux/fs/proc/net.c linux/fs/proc/net.c
--- v1.3.5/linux/fs/proc/net.c	Sat Jun 10 19:29:27 1995
+++ linux/fs/proc/net.c	Thu Jun 29 19:18:51 1995
@@ -77,6 +77,7 @@
 #ifdef CONFIG_AX25
 extern int ax25_get_info(char *, char **, off_t, int);
 extern int ax25_rt_get_info(char *, char **, off_t, int);
+extern int ax25_cs_get_info(char *, char **, off_t, int);
 #ifdef CONFIG_NETROM
 extern int nr_get_info(char *, char **, off_t, int);
 extern int nr_nodes_get_info(char *, char **, off_t, int);
@@ -165,6 +166,7 @@
 #ifdef CONFIG_AX25
 	{ PROC_NET_AX25_ROUTE,	10, "ax25_route" },
 	{ PROC_NET_AX25,	4, "ax25" },
+	{ PROC_NET_AX25_CALLS,	10, "ax25_calls" },
 #ifdef CONFIG_NETROM
 	{ PROC_NET_NR_NODES,	8, "nr_nodes" },
 	{ PROC_NET_NR_NEIGH,	8, "nr_neigh" },
@@ -345,6 +347,9 @@
 				break;
 			case PROC_NET_AX25:
 				length = ax25_get_info(page,&start,file->f_pos,thistime);
+				break;
+			case PROC_NET_AX25_CALLS:
+				length = ax25_cs_get_info(page,&start,file->f_pos,thistime);
 				break;
 #ifdef CONFIG_NETROM
 			case PROC_NET_NR_NODES:
diff -u --recursive --new-file v1.3.5/linux/fs/proc/scsi.c linux/fs/proc/scsi.c
--- v1.3.5/linux/fs/proc/scsi.c	Thu Jun 29 19:02:54 1995
+++ linux/fs/proc/scsi.c	Fri Jun 30 15:30:56 1995
@@ -12,12 +12,12 @@
  *
  *  Initial version: March '95
  *  95/15/05 Added subdirectories for each driver and show every
- *           registered HBA as a single file. 
+ *	     registered HBA as a single file. 
  *  95/30/05 Added rudimentary write support for parameter passing
  *
  *  TODO: Improve support to write to the driver files
- *        Optimize directory handling 
- *        Add some more comments
+ *	  Optimize directory handling 
+ *	  Add some more comments
  */
 #include <linux/autoconf.h>
 #include <asm/segment.h>
@@ -30,11 +30,11 @@
 
 /* forward references */
 static int proc_readscsi(struct inode * inode, struct file * file,
-                         char * buf, int count);
+			 char * buf, int count);
 static int proc_writescsi(struct inode * inode, struct file * file,
-                         char * buf, int count);
+			 char * buf, int count);
 static int proc_readscsidir(struct inode *, struct file *, 
-                            void *, filldir_t filldir);
+			    void *, filldir_t filldir);
 static int proc_lookupscsi(struct inode *,const char *,int,struct inode **);
 static int proc_scsilseek(struct inode *, struct file *, off_t, int);
 
@@ -46,16 +46,16 @@
     
     
 static struct file_operations proc_scsi_operations = {
-    proc_scsilseek,     /* lseek   */
-    proc_readscsi,      /* read    */
-    proc_writescsi,     /* write   */
-    proc_readscsidir,   /* readdir */
-    NULL,               /* select  */
-    NULL,               /* ioctl   */
-    NULL,               /* mmap    */
-    NULL,               /* no special open code    */
-    NULL,               /* no special release code */
-    NULL                /* can't fsync */
+    proc_scsilseek,	/* lseek   */
+    proc_readscsi,	/* read	   */
+    proc_writescsi,	/* write   */
+    proc_readscsidir,	/* readdir */
+    NULL,		/* select  */
+    NULL,		/* ioctl   */
+    NULL,		/* mmap	   */
+    NULL,		/* no special open code	   */
+    NULL,		/* no special release code */
+    NULL		/* can't fsync */
 };
 
 /*
@@ -63,29 +63,29 @@
  */
 struct inode_operations proc_scsi_inode_operations = {
     &proc_scsi_operations,  /* default scsi directory file-ops */
-    NULL,           /* create      */
-    proc_lookupscsi,/* lookup      */
-    NULL,           /* link        */
-    NULL,           /* unlink      */
-    NULL,           /* symlink     */
-    NULL,           /* mkdir       */
-    NULL,           /* rmdir       */
-    NULL,           /* mknod       */
-    NULL,           /* rename      */
-    NULL,           /* readlink    */
-    NULL,           /* follow_link */
-    NULL,           /* bmap        */
-    NULL,           /* truncate    */
-    NULL            /* permission  */
+    NULL,	    /* create	   */
+    proc_lookupscsi,/* lookup	   */
+    NULL,	    /* link	   */
+    NULL,	    /* unlink	   */
+    NULL,	    /* symlink	   */
+    NULL,	    /* mkdir	   */
+    NULL,	    /* rmdir	   */
+    NULL,	    /* mknod	   */
+    NULL,	    /* rename	   */
+    NULL,	    /* readlink	   */
+    NULL,	    /* follow_link */
+    NULL,	    /* bmap	   */
+    NULL,	    /* truncate	   */
+    NULL	    /* permission  */
 };
 
 struct proc_dir_entry scsi_dir[PROC_SCSI_FILE - PROC_SCSI_SCSI + 3]; 
 struct proc_dir_entry scsi_hba_dir[(PROC_SCSI_LAST - PROC_SCSI_FILE) * 4]; 
 
 static struct proc_dir_entry scsi_dir2[] = {
-    { PROC_SCSI,                 1, "." },
-    { PROC_ROOT_INO,             2, ".." },
-    { PROC_SCSI_NOT_PRESENT,    11, "not.present" },
+    { PROC_SCSI,		 1, "." },
+    { PROC_ROOT_INO,		 2, ".." },
+    { PROC_SCSI_NOT_PRESENT,	11, "not.present" },
     { 0, 0, NULL }
 };
 
@@ -96,72 +96,72 @@
     
     
     if(dispatch_scsi_info_ptr)
-        if (inode <= PROC_SCSI_SCSI_DEBUG)
-            dir = scsi_dir;
-        else
-            dir = scsi_hba_dir;
+	if (inode <= PROC_SCSI_SCSI_DEBUG)
+	    dir = scsi_dir;
+	else
+	    dir = scsi_hba_dir;
     else dir = scsi_dir2;
     
     while(dir[i].low_ino)
-        i++;
+	i++;
     
     return(i);
 }
 
 static int proc_lookupscsi(struct inode * dir, const char * name, int len,
-                           struct inode ** result)
+			   struct inode ** result)
 {
     struct proc_dir_entry *de = NULL;
     
     *result = NULL;
     if (!dir)
-        return(-ENOENT);
+	return(-ENOENT);
     if (!S_ISDIR(dir->i_mode)) {
-        iput(dir);
-        return(-ENOENT);
+	iput(dir);
+	return(-ENOENT);
     }
     if (dispatch_scsi_info_ptr != NULL)
-        if (dir->i_ino <= PROC_SCSI_SCSI)
-            de = scsi_dir;
-        else {
-            de = &scsi_hba_dir[dispatch_scsi_info_ptr(dir->i_ino, 0, 0, 0, 0, 2)];
-        }
+	if (dir->i_ino <= PROC_SCSI_SCSI)
+	    de = scsi_dir;
+	else {
+	    de = &scsi_hba_dir[dispatch_scsi_info_ptr(dir->i_ino, 0, 0, 0, 0, 2)];
+	}
     else
-        de = scsi_dir2;
+	de = scsi_dir2;
     
     for (; de->name ; de++) {
-        if (!proc_match(len, name, de))
-            continue;
-        *result = iget(dir->i_sb, de->low_ino);
-        iput(dir);
-        if (!*result)
-            return(-ENOENT);
-        return(0);
+	if (!proc_match(len, name, de))
+	    continue;
+	*result = iget(dir->i_sb, de->low_ino);
+	iput(dir);
+	if (!*result)
+	    return(-ENOENT);
+	return(0);
     }
     iput(dir);
     return(-ENOENT);
 }
 
 static int proc_readscsidir(struct inode * inode, struct file * filp,
-                            void * dirent, filldir_t filldir)
+			    void * dirent, filldir_t filldir)
 {
     struct proc_dir_entry * de;
     unsigned int ino;
     
     if (!inode || !S_ISDIR(inode->i_mode))
-        return(-EBADF);
+	return(-EBADF);
     ino = inode->i_ino;
-	while (((unsigned) filp->f_pos) < count_dir_entries(ino)) {
-        if (dispatch_scsi_info_ptr)
-            if (ino <= PROC_SCSI_SCSI)
-                de = scsi_dir + filp->f_pos;
-            else
-                de = scsi_hba_dir + filp->f_pos;
-        else
-            de = scsi_dir2 + filp->f_pos;
-        if (filldir(dirent, de->name, de->namelen, filp->f_pos, de->low_ino)<0)
-            break;
-        filp->f_pos++;
+    while (((unsigned) filp->f_pos) < count_dir_entries(ino)) {
+	if (dispatch_scsi_info_ptr)
+	    if (ino <= PROC_SCSI_SCSI)
+		de = scsi_dir + filp->f_pos;
+	    else
+		de = scsi_hba_dir + filp->f_pos;
+	else
+	    de = scsi_dir2 + filp->f_pos;
+	if (filldir(dirent, de->name, de->namelen, filp->f_pos, de->low_ino)<0)
+	    break;
+	filp->f_pos++;
     }
     return(0);
 }
@@ -172,26 +172,26 @@
     
     begin = 0;
     pos = len = sprintf(buffer, 
-                        "The scsi core module is currently not present\n");
+			"The scsi core module is currently not present\n");
     if(pos < offset) {
-        len = 0;
-        begin = pos;
+	len = 0;
+	begin = pos;
     }
     
-    *start = buffer + (offset - begin);   /* Start of wanted data */
+    *start = buffer + (offset - begin);	  /* Start of wanted data */
     len -= (offset - begin);
     if(len > length)
-        len = length;
+	len = length;
     
     return(len);
 }
 
 #define PROC_BLOCK_SIZE (3*1024)     /* 4K page size, but our output routines 
-                                      * use some slack for overruns 
-                                      */
+				      * use some slack for overruns 
+				      */
 
 static int proc_readscsi(struct inode * inode, struct file * file,
-                         char * buf, int count)
+			 char * buf, int count)
 {
     uint ino;
     int length;
@@ -201,52 +201,52 @@
     char * page;
     char * start;
     
-    if (count < -1)               /* Normally I wouldn't do this, */ 
-        return(-EINVAL);          /* but it saves some redundant code.
-                                   * Now it is possible to seek to the 
-                                   * end of the file */
+    if (count < -1)		  /* Normally I wouldn't do this, */ 
+	return(-EINVAL);	  /* but it saves some redundant code.
+				   * Now it is possible to seek to the 
+				   * end of the file */
     if (!(page = (char *) __get_free_page(GFP_KERNEL)))
-        return(-ENOMEM);
+	return(-ENOMEM);
     ino = inode->i_ino;
     
     
     while(bytes > 0 || count == -1)
     {
-        
-        thistime = bytes;
-        if(bytes > PROC_BLOCK_SIZE || count == -1)
-            thistime = PROC_BLOCK_SIZE;
-        
-        if(dispatch_scsi_info_ptr)
-            length = dispatch_scsi_info_ptr(ino, page, &start, 
-                                            file->f_pos, thistime, 0);
-        else
-            length = get_not_present_info(page, &start, file->f_pos, thistime);
-        if(length < 0) {
-            free_page((ulong) page);
-            return(length);
-        }
-        
-        /*
-         *  We have been given a non page aligned block of
-         *  the data we asked for + a bit. We have been given
-         *  the start pointer and we know the length.. 
-         */
-        if (length <= 0)
-            break;
-        /*
-         *  Copy the bytes, if we're not doing a seek to 
-         *      the end of the file 
-         */
-        if (count != -1)
-            memcpy_tofs(buf + copied, start, length);
-        file->f_pos += length;  /* Move down the file */
-        bytes -= length;
-        copied += length;
-        
-        if(length < thistime)
-            break;  /* End of file */
-        
+	
+	thistime = bytes;
+	if(bytes > PROC_BLOCK_SIZE || count == -1)
+	    thistime = PROC_BLOCK_SIZE;
+	
+	if(dispatch_scsi_info_ptr)
+	    length = dispatch_scsi_info_ptr(ino, page, &start, 
+					    file->f_pos, thistime, 0);
+	else
+	    length = get_not_present_info(page, &start, file->f_pos, thistime);
+	if(length < 0) {
+	    free_page((ulong) page);
+	    return(length);
+	}
+	
+	/*
+	 *  We have been given a non page aligned block of
+	 *  the data we asked for + a bit. We have been given
+	 *  the start pointer and we know the length.. 
+	 */
+	if (length <= 0)
+	    break;
+	/*
+	 *  Copy the bytes, if we're not doing a seek to 
+	 *	the end of the file 
+	 */
+	if (count != -1)
+	    memcpy_tofs(buf + copied, start, length);
+	file->f_pos += length;	/* Move down the file */
+	bytes -= length;
+	copied += length;
+	
+	if(length < thistime)
+	    break;  /* End of file */
+	
     }
     
     free_page((ulong) page);
@@ -255,27 +255,27 @@
 
 
 static int proc_writescsi(struct inode * inode, struct file * file,
-                         char * buf, int count)
+			 char * buf, int count)
 {
     uint ino;
     int ret = 0;
     char * page;
     
     if (!(page = (char *) __get_free_page(GFP_KERNEL)))
-        return(-ENOMEM);
+	return(-ENOMEM);
 
     if(count > PROC_BLOCK_SIZE) {
-        return(-EOVERFLOW);
+	return(-EOVERFLOW);
     }
 
     ino = inode->i_ino;
     
     if(dispatch_scsi_info_ptr != NULL) {
-        memcpy_fromfs(page, buf, count);
-        ret = dispatch_scsi_info_ptr(ino, page, 0, 0, count, 1);
+	memcpy_fromfs(page, buf, count);
+	ret = dispatch_scsi_info_ptr(ino, page, 0, 0, count, 1);
     } else {
-        free_page((ulong) page);   
-        return(-ENOPKG);          /* Nothing here */
+	free_page((ulong) page);   
+	return(-ENOPKG);	  /* Nothing here */
     }
     
     free_page((ulong) page);
@@ -284,22 +284,22 @@
 
 
 static int proc_scsilseek(struct inode * inode, struct file * file, 
-                          off_t offset, int orig)
+			  off_t offset, int orig)
 {
     switch (orig) {
     case 0:
-        file->f_pos = offset;
-        return(file->f_pos);
+	file->f_pos = offset;
+	return(file->f_pos);
     case 1:
-        file->f_pos += offset;
-        return(file->f_pos);
-    case 2:                  /* This ugly hack allows us to    */
-        if (offset)          /* to determine the length of the */
-            return(-EINVAL); /* file and then later savely to  */ 
-        proc_readscsi(inode, file, 0, -1); /* seek in it       */ 
-        return(file->f_pos);
+	file->f_pos += offset;
+	return(file->f_pos);
+    case 2:		     /* This ugly hack allows us to    */
+	if (offset)	     /* to determine the length of the */
+	    return(-EINVAL); /* file and then later savely to  */ 
+	proc_readscsi(inode, file, 0, -1); /* seek in it       */ 
+	return(file->f_pos);
     default:
-        return(-EINVAL);
+	return(-EINVAL);
     }
 }
 
@@ -318,6 +318,6 @@
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
- * tab-width: 4
+ * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.5/linux/include/asm-i386/checksum.h linux/include/asm-i386/checksum.h
--- v1.3.5/linux/include/asm-i386/checksum.h	Fri Jun 16 22:02:55 1995
+++ linux/include/asm-i386/checksum.h	Thu Jun 29 19:18:51 1995
@@ -35,32 +35,29 @@
  */
 static inline unsigned short ip_fast_csum(unsigned char * iph,
 					  unsigned int ihl) {
-	unsigned short int sum;
+	unsigned int sum;
 
 	__asm__("
-	    movl (%%esi), %%eax
-	    andl $15, %%ecx
-	    subl $4, %%ecx
+	    movl (%1), %0
+	    subl $4, %2
 	    jbe 2f
-	    addl 4(%%esi), %%eax
-	    adcl 8(%%esi), %%eax
-	    adcl 12(%%esi), %%eax
-1:	    adcl 16(%%esi), %%eax
-	    lea 4(%%esi), %%esi
-	    decl %%ecx
+	    addl 4(%1), %0
+	    adcl 8(%1), %0
+	    adcl 12(%1), %0
+1:	    adcl 16(%1), %0
+	    lea 4(%1), %1
+	    decl %2
 	    jne	1b
-	    adcl $0, %%eax
-	    movl %%eax, %%ecx
-	    shrl $16, %%eax
-	    addw %%ecx, %%eax
-	    adcl $0, %%eax
-	    notl %%eax
-	    andl $65535, %%eax
+	    adcl $0, %0
+	    movl %0, %2
+	    shrl $16, %0
+	    addw %w2, %w0
+	    adcl $0, %0
+	    notl %0
 2:
 	    "
-	: "=a" (sum)
-	: "S" (iph), "c"(ihl)
-	: "ax", "cx", "si");
+	: "=&r" (sum), "=&r" (iph), "=&r" (ihl)
+	: "1" (iph), "2" (ihl));
 	return(sum);
 }
 
@@ -78,20 +75,18 @@
 						   unsigned short proto,
 						   unsigned int sum) {
     __asm__("
-	addl %2, %0
-	adcl %3, %0
+	addl %1, %0
 	adcl %4, %0
+	adcl %5, %0
 	adcl $0, %0
-	movl %0, %2
-	shrl $16, %2
-	addw %2, %0
+	movl %0, %1
+	shrl $16, %1
+	addw %w1, %w0
 	adcl $0, %0
 	notl %0
-	andl $65535, %0
 	"
-	: "=r" (sum)
-	: "0" (daddr), "S"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum)
-	: "si" );
+	: "=&r" (sum), "=&r" (saddr)
+	: "0" (daddr), "1"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum));
 	return((unsigned short)sum);
 }
 
@@ -101,19 +96,18 @@
  */
 
 static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
-    unsigned short int sum;
+    unsigned int sum;
 
+    unsigned int scratch;
     __asm__("
-	movl %%eax, %%ecx
-	shrl $16, %%ecx
-	addw %%cx, %%ax
-	adcl $0, %%eax
-	notl %%eax
-	andl $65535, %%eax
+	movl %0, %1
+	shrl $16, %1
+	addw %w1, %w0
+	adcl $0, %0
+	notl %0
 	"
-	: "=a"(sum)
-	: "a" (csum_partial(buff, len, 0))
-	: "cx");
+	: "=a"(sum), "=r" (scratch)
+	: "0" (csum_partial(buff, len, 0)));
 	return(sum);
 }
 
diff -u --recursive --new-file v1.3.5/linux/include/linux/ax25.h linux/include/linux/ax25.h
--- v1.3.5/linux/include/linux/ax25.h	Tue Jun  6 11:22:11 1995
+++ linux/include/linux/ax25.h	Thu Jun 29 19:18:51 1995
@@ -29,6 +29,7 @@
 #define AX25_N2		3
 #define AX25_T3		4
 #define AX25_T2		5
+#define	AX25_BACKOFF	6
 
 #define SIOCAX25GETUID		(SIOCPROTOPRIVATE)
 #define SIOCAX25ADDUID		(SIOCPROTOPRIVATE+1)
diff -u --recursive --new-file v1.3.5/linux/include/linux/etherdevice.h linux/include/linux/etherdevice.h
--- v1.3.5/linux/include/linux/etherdevice.h	Mon Apr 18 11:38:38 1994
+++ linux/include/linux/etherdevice.h	Thu Jun 29 19:18:51 1995
@@ -28,12 +28,11 @@
 #include <linux/if_ether.h>
 
 #ifdef __KERNEL__
-extern int		eth_header(unsigned char *buff, struct device *dev,
+extern int		eth_header(struct sk_buff *skb, struct device *dev,
 				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len,
-				   struct sk_buff *skb);
+				   void *saddr, unsigned len);
 extern int		eth_rebuild_header(void *buff, struct device *dev,
-			unsigned long raddr, struct sk_buff *skb);
+			unsigned long dst, struct sk_buff *skb);
 extern unsigned short	eth_type_trans(struct sk_buff *skb, struct device *dev);
 
 #endif
diff -u --recursive --new-file v1.3.5/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v1.3.5/linux/include/linux/netdevice.h	Tue Jun  6 11:22:11 1995
+++ linux/include/linux/netdevice.h	Thu Jun 29 19:18:51 1995
@@ -139,13 +139,12 @@
   int			  (*stop)(struct device *dev);
   int			  (*hard_start_xmit) (struct sk_buff *skb,
 					      struct device *dev);
-  int			  (*hard_header) (unsigned char *buff,
+  int			  (*hard_header) (struct sk_buff *skb,
 					  struct device *dev,
 					  unsigned short type,
 					  void *daddr,
 					  void *saddr,
-					  unsigned len,
-					  struct sk_buff *skb);
+					  unsigned len);
   int			  (*rebuild_header)(void *eth, struct device *dev,
 				unsigned long raddr, struct sk_buff *skb);
 #define HAVE_MULTICAST			 
diff -u --recursive --new-file v1.3.5/linux/include/linux/netrom.h linux/include/linux/netrom.h
--- v1.3.5/linux/include/linux/netrom.h	Tue Jun  6 11:22:11 1995
+++ linux/include/linux/netrom.h	Thu Jun 29 19:18:51 1995
@@ -5,27 +5,20 @@
 #define NETROM_T2	2
 #define NETROM_N2	3
 
-#define SIOCNRADDNODE		(SIOCPROTOPRIVATE)
-#define SIOCNRDELNODE		(SIOCPROTOPRIVATE+1)
-#define	SIOCNRADDNEIGH		(SIOCPROTOPRIVATE+2)
-#define	SIOCNRDELNEIGH		(SIOCPROTOPRIVATE+3)
-#define	SIOCNRGETPARMS		(SIOCPROTOPRIVATE+4)
-#define	SIOCNRSETPARMS		(SIOCPROTOPRIVATE+5)
-#define	SIOCNRDECOBS		(SIOCPROTOPRIVATE+6)
+#define	SIOCNRGETPARMS		(SIOCPROTOPRIVATE+0)
+#define	SIOCNRSETPARMS		(SIOCPROTOPRIVATE+1)
+#define	SIOCNRDECOBS		(SIOCPROTOPRIVATE+2)
 
-struct nr_node_struct {
+struct nr_route_struct {
+#define	NETROM_NEIGH	0
+#define	NETROM_NODE	1
+	int type;
 	ax25_address callsign;
-	char mnemonic[7];
-	ax25_address neighbour;
 	char device[16];
 	unsigned int quality;
+	char mnemonic[7];
+	ax25_address neighbour;
 	unsigned int obs_count;
-};
-
-struct nr_neigh_struct {
-	ax25_address callsign;
-	char device[16];
-	unsigned int quality;
 };
 
 struct nr_parms_struct {
diff -u --recursive --new-file v1.3.5/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v1.3.5/linux/include/linux/proc_fs.h	Thu Jun 29 19:02:55 1995
+++ linux/include/linux/proc_fs.h	Thu Jun 29 19:18:51 1995
@@ -96,6 +96,7 @@
 #ifdef CONFIG_AX25
 	PROC_NET_AX25_ROUTE,
 	PROC_NET_AX25,
+	PROC_NET_AX25_CALLS,
 #ifdef CONFIG_NETROM
 	PROC_NET_NR_NODES,
 	PROC_NET_NR_NEIGH,
diff -u --recursive --new-file v1.3.5/linux/include/linux/skbuff.h linux/include/linux/skbuff.h
--- v1.3.5/linux/include/linux/skbuff.h	Tue Jun  6 11:22:12 1995
+++ linux/include/linux/skbuff.h	Thu Jun 29 22:36:57 1995
@@ -18,7 +18,7 @@
 #include <linux/time.h>
 #include <linux/config.h>
 
-#undef CONFIG_SKB_CHECK
+/* #define CONFIG_SKB_CHECK 1 */
 
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
 
@@ -47,7 +47,6 @@
   volatile unsigned long	when;			/* used to compute rtt's			*/
   struct timeval		stamp;			/* Time we arrived				*/
   struct device			*dev;			/* Device we arrived on/are leaving by		*/
-  struct sk_buff		*mem_addr;		/* Self reference (obsolete)			*/
   union {
 	struct tcphdr	*th;
 	struct ethhdr	*eth;
@@ -57,11 +56,7 @@
 	unsigned long	seq;
   } h;
   struct iphdr			*ip_hdr;		/* For IPPROTO_RAW 				*/
-  unsigned long			mem_len;		/* Length of allocated memory			*/
   unsigned long 		len;			/* Length of actual data			*/
-  unsigned long			fraglen;		/* Unused (yet)					*/
-  struct sk_buff		*fraglist;		/* Fragment list 				*/
-  unsigned long			truesize;		/* True buffer size (obsolete)			*/
   unsigned long 		saddr;			/* IP source address				*/
   unsigned long 		daddr;			/* IP target address				*/
   unsigned long			raddr;			/* IP next hop address				*/
@@ -79,11 +74,11 @@
 #define PACKET_OTHERHOST	3			/* To someone else 				*/
   unsigned short		users;			/* User count - see datagram.c,tcp.c 		*/
   unsigned short		protocol;		/* Packet protocol from driver. 		*/
-#ifdef CONFIG_SLAVE_BALANCING
-  unsigned short		in_dev_queue;
-#endif  
-  unsigned long			padding[0];		/* Force long word alignment			*/
-  unsigned char			data[0];		/* Data follows					*/
+  unsigned short		truesize;		/* Buffer size 					*/
+  unsigned char			*head;			/* Head of buffer 				*/
+  unsigned char			*data;			/* Data head pointer				*/
+  unsigned char			*tail;			/* Tail pointer					*/
+  unsigned char 		*end;			/* End pointer					*/
 };
 
 #define SK_WMEM_MAX	32767
@@ -115,12 +110,21 @@
 extern void			skb_unlink(struct sk_buff *buf);
 extern struct sk_buff *		skb_peek_copy(struct sk_buff_head *list);
 extern struct sk_buff *		alloc_skb(unsigned int size, int priority);
-extern void			kfree_skbmem(struct sk_buff *skb, unsigned size);
+extern struct sk_buff *		dev_alloc_skb(unsigned int size);
+extern void			kfree_skbmem(struct sk_buff *skb);
 extern struct sk_buff *		skb_clone(struct sk_buff *skb, int priority);
 extern void			skb_device_lock(struct sk_buff *skb);
 extern void			skb_device_unlock(struct sk_buff *skb);
 extern void			dev_kfree_skb(struct sk_buff *skb, int mode);
 extern int			skb_device_locked(struct sk_buff *skb);
+extern unsigned char *		skb_put(struct sk_buff *skb, int len);
+extern unsigned char *		skb_push(struct sk_buff *skb, int len);
+extern int			skb_pull(struct sk_buff *skb, int len);
+extern int			skb_headroom(struct sk_buff *skb);
+extern int			skb_tailroom(struct sk_buff *skb);
+extern void			skb_reserve(struct sk_buff *skb, int len);
+extern void 			skb_trim(struct sk_buff *skb, int len);
+
 /*
  *	Peek an sk_buff. Unlike most other operations you _MUST_
  *	be careful with this one. A peek leaves the buffer on the
@@ -281,6 +285,63 @@
 		skb->prev = NULL;
 	}
 	restore_flags(flags);
+}
+
+/*
+ *	Add data to an sk_buff
+ */
+ 
+extern __inline__ unsigned char *skb_put(struct sk_buff *skb, int len)
+{
+	unsigned char *tmp=skb->tail;
+	skb->tail+=len;
+	skb->len+=len;
+	if(skb->tail>skb->end)
+		panic("skput:over: %p:%d", __builtin_return_address(0),len);
+	return tmp;
+}
+
+extern __inline__ unsigned char *skb_push(struct sk_buff *skb, int len)
+{
+	skb->data-=len;
+	skb->len+=len;
+	if(skb->data<skb->head)
+		panic("skpush:under: %p:%d", __builtin_return_address(0),len);
+	return skb->data;
+}
+
+extern __inline__ int skb_pull(struct sk_buff *skb, int len)
+{
+	if(len>skb->len)
+		len=skb->len;
+	skb->data+=len;
+	skb->len-=len;
+	return len;
+}
+
+extern __inline__ int skb_headroom(struct sk_buff *skb)
+{
+	return skb->data-skb->head;
+}
+
+extern __inline__ int skb_tailroom(struct sk_buff *skb)
+{
+	return skb->end-skb->tail;
+}
+
+extern __inline__ void skb_reserve(struct sk_buff *skb, int len)
+{
+	skb->data+=len;
+	skb->tail+=len;
+}
+
+extern __inline__ void skb_trim(struct sk_buff *skb, int len)
+{
+	if(skb->len>len)
+	{
+		skb->len=len;
+		skb->tail=skb->data+len;
+	}
 }
 
 #endif
diff -u --recursive --new-file v1.3.5/linux/include/linux/trdevice.h linux/include/linux/trdevice.h
--- v1.3.5/linux/include/linux/trdevice.h	Tue Jun  6 11:22:12 1995
+++ linux/include/linux/trdevice.h	Thu Jun 29 19:18:51 1995
@@ -28,10 +28,9 @@
 #include <linux/if_tr.h>
 
 #ifdef __KERNEL__
-extern int		tr_header(unsigned char *buff, struct device *dev,
+extern int		tr_header(struct sk_buff *skb, struct device *dev,
 				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len,
-				   struct sk_buff *skb);
+				   void *saddr, unsigned len);
 extern int		tr_rebuild_header(void *buff, struct device *dev,
 			unsigned long raddr, struct sk_buff *skb);
 extern unsigned short	tr_type_trans(struct sk_buff *skb, struct device *dev);
diff -u --recursive --new-file v1.3.5/linux/include/net/ax25.h linux/include/net/ax25.h
--- v1.3.5/linux/include/net/ax25.h	Tue Jun  6 11:22:17 1995
+++ linux/include/net/ax25.h	Thu Jun 29 19:18:51 1995
@@ -114,7 +114,7 @@
 	struct device		*device;
 	unsigned char		state;
 	unsigned short		vs, vr, va;
-	unsigned char		condition;
+	unsigned char		condition, backoff;
 	unsigned char		n2, n2count;
 	unsigned short		t1, t2, t3, rtt;
 	unsigned short		t1timer, t2timer, t3timer;
@@ -133,8 +133,8 @@
 extern int  ax25_rcv(struct sk_buff *,struct device *,struct packet_type *);
 extern void ax25_destroy_socket(ax25_cb *);
 extern struct device *ax25rtr_get_dev(ax25_address *);
-extern int  ax25_encapsulate(unsigned char *, struct device *, unsigned short,
-	void *, void *, unsigned int, struct sk_buff *);
+extern int  ax25_encapsulate(struct sk_buff *, struct device *, unsigned short,
+	void *, void *, unsigned int);
 extern int  ax25_rebuild_header(unsigned char *, struct device *, unsigned long, struct sk_buff *);
 extern int  ax25_get_info(char *, char **, off_t, int);
 extern ax25_uid_assoc *ax25_uid_list;
diff -u --recursive --new-file v1.3.5/linux/include/net/eth.h linux/include/net/eth.h
--- v1.3.5/linux/include/net/eth.h	Tue Jun  6 11:22:17 1995
+++ linux/include/net/eth.h	Thu Jun 29 19:18:51 1995
@@ -24,10 +24,11 @@
 
 extern char		*eth_print(unsigned char *ptr);
 extern void		eth_dump(struct ethhdr *eth);
-extern int		eth_header(unsigned char *buff, struct device *dev,
-				   unsigned short type, unsigned long daddr,
-				   unsigned long saddr, unsigned len);
-extern int		eth_rebuild_header(void *buff, struct device *dev);
+extern int		eth_header(struct sk_buff *skb, struct device *dev,
+				   unsigned short type, void *daddr,
+				   void *saddr, unsigned len);
+extern int		eth_rebuild_header(void *buff, struct device *dev,
+				   unsigned long dst, struct sk_buff *skb);
 extern void		eth_add_arp(unsigned long addr, struct sk_buff *skb,
 				    struct device *dev);
 extern unsigned short	eth_type_trans(struct sk_buff *skb, struct device *dev);
diff -u --recursive --new-file v1.3.5/linux/include/net/netrom.h linux/include/net/netrom.h
--- v1.3.5/linux/include/net/netrom.h	Tue Jun  6 11:22:17 1995
+++ linux/include/net/netrom.h	Thu Jun 29 19:18:51 1995
@@ -44,7 +44,7 @@
 	ax25_address		user_addr, source_addr, dest_addr;
 	unsigned char		my_index,    my_id;
 	unsigned char		your_index,  your_id;
-	unsigned char		state;
+	unsigned char		state, bpqext;
 	unsigned short		vs, vr, va, vl;
 	unsigned char		condition;
 	unsigned char		n2, n2count;
diff -u --recursive --new-file v1.3.5/linux/include/net/route.h linux/include/net/route.h
--- v1.3.5/linux/include/net/route.h	Tue Jun  6 11:22:18 1995
+++ linux/include/net/route.h	Thu Jun 29 19:18:51 1995
@@ -45,7 +45,7 @@
 
 extern void		ip_rt_flush(struct device *dev);
 extern void		ip_rt_add(short flags, unsigned long addr, unsigned long mask,
-			       unsigned long gw, struct device *dev, unsigned short mss, unsigned long window, unsigned short irtt);
+			       unsigned long gw, struct device *dev, unsigned short mss, unsigned long window, unsigned short irtt, unsigned char metric);
 extern struct rtable	*ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr);
 extern struct rtable 	*ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr);
 extern int		rt_get_info(char * buffer, char **start, off_t offset, int length);
diff -u --recursive --new-file v1.3.5/linux/include/net/sock.h linux/include/net/sock.h
--- v1.3.5/linux/include/net/sock.h	Tue Jun 27 14:11:47 1995
+++ linux/include/net/sock.h	Thu Jun 29 19:18:51 1995
@@ -213,10 +213,8 @@
   struct sk_buff *	(*rmalloc)(struct sock *sk,
 				    unsigned long size, int force,
 				    int priority);
-  void			(*wfree)(struct sock *sk, struct sk_buff *skb,
-				 unsigned long size);
-  void			(*rfree)(struct sock *sk, struct sk_buff *skb,
-				 unsigned long size);
+  void			(*wfree)(struct sock *sk, struct sk_buff *skb);
+  void			(*rfree)(struct sock *sk, struct sk_buff *skb);
   unsigned long		(*rspace)(struct sock *sk);
   unsigned long		(*wspace)(struct sock *sk);
   void			(*close)(struct sock *sk, int timeout);
@@ -303,10 +301,8 @@
 extern struct sk_buff		*sock_rmalloc(struct sock *sk,
 					      unsigned long size, int force,
 					      int priority);
-extern void			sock_wfree(struct sock *sk, struct sk_buff *skb,
-					   unsigned long size);
-extern void			sock_rfree(struct sock *sk, struct sk_buff *skb,
-					   unsigned long size);
+extern void			sock_wfree(struct sock *sk, struct sk_buff *skb);
+extern void			sock_rfree(struct sock *sk, struct sk_buff *skb);
 extern unsigned long		sock_rspace(struct sock *sk);
 extern unsigned long		sock_wspace(struct sock *sk);
 
@@ -326,11 +322,11 @@
 extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
 	unsigned long flags;
-	if(sk->rmem_alloc + skb->mem_len >= sk->rcvbuf)
+	if(sk->rmem_alloc + skb->truesize >= sk->rcvbuf)
 		return -ENOMEM;
 	save_flags(flags);
 	cli();
-	sk->rmem_alloc+=skb->mem_len;
+	sk->rmem_alloc+=skb->truesize;
 	skb->sk=sk;
 	restore_flags(flags);
 	skb_queue_tail(&sk->receive_queue,skb);
diff -u --recursive --new-file v1.3.5/linux/kernel/exit.c linux/kernel/exit.c
--- v1.3.5/linux/kernel/exit.c	Tue Jun 27 14:11:47 1995
+++ linux/kernel/exit.c	Fri Jun 30 10:13:05 1995
@@ -486,7 +486,7 @@
 	struct task_struct *p;
 
 	if (stat_addr) {
-		flag = verify_area(VERIFY_WRITE, stat_addr, 4);
+		flag = verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr));
 		if (flag)
 			return flag;
 	}
diff -u --recursive --new-file v1.3.5/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.5/linux/kernel/ksyms.c	Thu Jun 29 19:02:55 1995
+++ linux/kernel/ksyms.c	Thu Jun 29 19:18:51 1995
@@ -37,6 +37,7 @@
 #ifdef CONFIG_NET
 #include <linux/net.h>
 #include <linux/netdevice.h>
+#include <net/eth.h>
 #ifdef CONFIG_INET
 #include <linux/ip.h>
 #include <linux/etherdevice.h>
@@ -315,6 +316,7 @@
 	X(eth_type_trans),
 	X(alloc_skb),
 	X(kfree_skb),
+	X(dev_alloc_skb),
 	X(dev_kfree_skb),
 	X(netif_rx),
 	X(dev_rint),
diff -u --recursive --new-file v1.3.5/linux/kernel/signal.c linux/kernel/signal.c
--- v1.3.5/linux/kernel/signal.c	Tue Jun 27 14:11:47 1995
+++ linux/kernel/signal.c	Fri Jun 30 10:07:30 1995
@@ -69,7 +69,7 @@
 {
 	int error;
 	/* fill in "set" with signals pending but blocked. */
-	error = verify_area(VERIFY_WRITE, set, 4);
+	error = verify_area(VERIFY_WRITE, set, sizeof(sigset_t));
 	if (!error)
 		put_user(current->blocked & current->signal, set);
 	return error;
diff -u --recursive --new-file v1.3.5/linux/kernel/sys.c linux/kernel/sys.c
--- v1.3.5/linux/kernel/sys.c	Tue Jun 27 14:11:47 1995
+++ linux/kernel/sys.c	Fri Jun 30 10:11:52 1995
@@ -553,6 +553,9 @@
 		return -EPERM;
 	if (gidsetsize > NGROUPS)
 		return -EINVAL;
+	i = verify_area(VERIFY_READ, grouplist, sizeof(gid_t) * gidsetsize);
+	if (i)
+		return i;
 	for (i = 0; i < gidsetsize; i++, grouplist++) {
 		current->groups[i] = get_user(grouplist);
 	}
@@ -669,17 +672,17 @@
  */
 asmlinkage int sys_setdomainname(char *name, int len)
 {
-	int	i;
+	int error;
 	
 	if (!suser())
 		return -EPERM;
 	if (len > __NEW_UTS_LEN)
 		return -EINVAL;
-	for (i=0; i < len; i++) {
-		if ((system_utsname.domainname[i] = get_user(name+i)) == 0)
-			return 0;
-	}
-	system_utsname.domainname[i] = 0;
+	error = verify_area(VERIFY_READ, name, len);
+	if (error)
+		return error;
+	memcpy_fromfs(system_utsname.domainname, name, len);
+	system_utsname.domainname[len] = 0;
 	return 0;
 }
 
diff -u --recursive --new-file v1.3.5/linux/mm/swap.c linux/mm/swap.c
--- v1.3.5/linux/mm/swap.c	Tue Jun 27 14:11:47 1995
+++ linux/mm/swap.c	Thu Jun 29 21:11:27 1995
@@ -1229,6 +1229,8 @@
 	return;
 }
 
+#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
+
 /*
  * set up the free-area data structures:
  *   - mark all pages MAP_PAGE_RESERVED
@@ -1252,7 +1254,7 @@
 	start_mem = init_swap_cache(start_mem, end_mem);
 	mem_map = (mem_map_t *) start_mem;
 	p = mem_map + MAP_NR(end_mem);
-	start_mem = (unsigned long) p;
+	start_mem = LONG_ALIGN((unsigned long) p);
 	while (p > mem_map)
 		*--p = MAP_PAGE_RESERVED;
 
@@ -1263,7 +1265,7 @@
 		end_mem = (end_mem + ~mask) & mask;
 		bitmap_size = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT + i);
 		bitmap_size = (bitmap_size + 7) >> 3;
-		bitmap_size = (bitmap_size + sizeof(unsigned long) - 1) & ~(sizeof(unsigned long)-1);
+		bitmap_size = LONG_ALIGN(bitmap_size);
 		free_area_map[i] = (unsigned char *) start_mem;
 		memset((void *) start_mem, 0, bitmap_size);
 		start_mem += bitmap_size;
diff -u --recursive --new-file v1.3.5/linux/net/802/p8022.c linux/net/802/p8022.c
--- v1.3.5/linux/net/802/p8022.c	Tue Jun  6 12:16:42 1995
+++ linux/net/802/p8022.c	Thu Jun 29 19:18:52 1995
@@ -27,7 +27,7 @@
 	proto = find_8022_client(*(skb->h.raw));
 	if (proto != NULL) {
 		skb->h.raw += 3;
-		skb->len -= 3;
+		skb_pull(skb,3);
 		return proto->rcvfunc(skb, dev, pt);
 	}
 
@@ -45,9 +45,9 @@
 	unsigned long	hard_len = dev->hard_header_len;
 	unsigned char	*rawp;
 
-	dev->hard_header(skb->data, dev, len - hard_len,
-			dest_node, NULL, len - hard_len, skb);
-	rawp = skb->data + hard_len;
+	dev->hard_header(skb, dev, len - hard_len,
+			dest_node, NULL, len - hard_len);
+	rawp = skb_push(skb,3);
 	*rawp = dl->type[0];
 	rawp++;
 	*rawp = dl->type[0];
diff -u --recursive --new-file v1.3.5/linux/net/802/p8023.c linux/net/802/p8023.c
--- v1.3.5/linux/net/802/p8023.c	Tue Jun  6 12:16:42 1995
+++ linux/net/802/p8023.c	Thu Jun 29 19:18:52 1995
@@ -12,8 +12,8 @@
 	unsigned long	len = skb->len;
 	unsigned long	hard_len = dev->hard_header_len;
 
-	dev->hard_header(skb->data, dev, len - hard_len,
-			dest_node, NULL, len - hard_len, skb);
+	dev->hard_header(skb, dev, len - hard_len,
+			dest_node, NULL, len - hard_len);
 	skb->h.raw = skb->data + hard_len;
 }
 
diff -u --recursive --new-file v1.3.5/linux/net/802/psnap.c linux/net/802/psnap.c
--- v1.3.5/linux/net/802/psnap.c	Tue Jun  6 12:16:42 1995
+++ linux/net/802/psnap.c	Thu Jun 29 19:18:52 1995
@@ -58,7 +58,7 @@
 		 */
 		 
 		skb->h.raw += 5;
-		skb->len -= 5;
+		skb_pull(skb,5);
 		if (psnap_packet_type.type == 0)
 			psnap_packet_type.type=htons(ETH_P_SNAP);
 		return proto->rcvfunc(skb, dev, &psnap_packet_type);
@@ -74,10 +74,9 @@
  
 static void snap_datalink_header(struct datalink_proto *dl, struct sk_buff *skb, unsigned char *dest_node)
 {
-	struct device	*dev = skb->dev;
 	unsigned char	*rawp;
 
-	rawp = skb->data + snap_dl->header_length+dev->hard_header_len;
+	rawp = skb_push(skb,5);
 	memcpy(rawp,dl->type,5);
 	skb->h.raw = rawp+5;
 	snap_dl->datalink_header(snap_dl, skb, dest_node);
diff -u --recursive --new-file v1.3.5/linux/net/802/tr.c linux/net/802/tr.c
--- v1.3.5/linux/net/802/tr.c	Tue Jun  6 12:16:42 1995
+++ linux/net/802/tr.c	Thu Jun 29 19:18:52 1995
@@ -41,9 +41,9 @@
 int tr_header(unsigned char *buff, struct device *dev, unsigned short type,
               void *daddr, void *saddr, unsigned len, struct sk_buff *skb) {
 
-	struct trh_hdr *trh=(struct trh_hdr *)buff;
+	struct trh_hdr *trh=(struct trh_hdr *)skb_push(skb,dev->hard_header_len);
 	struct trllc *trllc=(struct trllc *)(buff+sizeof(struct trh_hdr));
-	
+
 	trh->ac=AC;
 	trh->fc=LLC_FRAME;
 
diff -u --recursive --new-file v1.3.5/linux/net/Changes linux/net/Changes
--- v1.3.5/linux/net/Changes	Tue Jun  6 11:22:14 1995
+++ linux/net/Changes	Thu Jun 29 19:18:52 1995
@@ -81,7 +81,24 @@
 o	SCC driver from Joerg Reuter			[IN]
 o	IP Firewall accounting zero bug			[IN]
 
-////////////////////////////1.3.0/////////////////////////// ??
+////////////////////////////1.3.0/////////////////////////// 
+
+
+o	Merged loadable firewall code			[NOT INCLUDED YET]
+o	New buffers used totally non optimally		[SEEMS OK]
+o	Fast ip_forwarding (needs changing)		[NOT INCLUDED YET]
+o	Fixed connection hang bug in new SWS code	[TESTED]
+o	Buffer management hack putting skbuff control
+	after data in the frame because kmalloc is
+	totally cache non-optimal			[TESTED]
+o	Faster checksum [Tom May]			[IN]
+o	Appletalk router fixes [Michael Callahan]	[IN]
+o	TCP state error fixes [Mark Tamsky]		[IN]
+o	Verify area fixes [Heiko Eissfeldt]		[IN]
+o	Routes use metric field	[John Naylor]		[IN]
+o	Major AX.25/NetROM fixes [John Nalor]		[IN]
+
+------->>>>>  NET3 030  <<<<<----------
 
 o	Finish merging the bridge code
 o	Device locking
@@ -89,17 +106,19 @@
 o	SIOCSLEEPRT patch
 o	Options support in ip_build_xmit		[PENDING]
 o	Fast checksum/copy on outgoing TCP
-o	New buffers. Used totally non-optimally
-o	Long word align ethernet IP headers (64byte align for pentium)
+o	Long word align ethernet IP headers (64byte align for pentium) [TESTING - EMAIL FOR INFO]
 o	Explode/implode headers for alpha,mips etc.
 o	Fast dev_grab_next() transmit reload function
 	and dev_push_failed() ??
 o	Faster ip_forward
 o	Faster loopback frame forwarding.
 o	Forwarding queue control (+ fairness algorithms ??)
-o	Merge loadable firewall code.
 o	IP forward flow control.
 o	Infinite PPP/SLIP devices.
+o	PI2 card doesn't do AX.25 VC yet
+o	AX.25 set protocol type
+o	Clean up RAW AX.25 sockets.
+o	Finish 802.2 Class I code to be compliant to the oddities of 802.2
 
 0.2
 ---
@@ -111,7 +130,7 @@
 o	PPP for Sonix ISDN.
 o	Loadable firewall extensions.
 o	Screend loadable firewall module
-o	LZ SLIP
+o	LZ SLIP				[Done, resolving patent issues]
 
 0.3
 ---
diff -u --recursive --new-file v1.3.5/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c
--- v1.3.5/linux/net/appletalk/aarp.c	Tue Jun  6 12:16:42 1995
+++ linux/net/appletalk/aarp.c	Thu Jun 29 19:18:52 1995
@@ -115,7 +115,7 @@
 	 
 	skb->arp	=	1;
 	skb->free	=	1;
-	skb->len	=	len;
+	skb_put(skb,len);
 	skb->dev	=	a->dev;
 	
 	/*
@@ -175,7 +175,7 @@
 	 
 	skb->arp	=	1;
 	skb->free	=	1;
-	skb->len	=	len;
+	skb_put(skb,len);
 	skb->dev	=	dev;
 	
 	/*
@@ -237,7 +237,7 @@
 	 
 	skb->arp	=	1;
 	skb->free	=	1;
-	skb->len	=	len;
+	skb_put(skb,len);
 	skb->dev	=	dev;
 	
 	/*
@@ -576,11 +576,13 @@
 		return 0;
 	}
 	
+	skb_pull(skb,dev->hard_header_len);
+	
 	/*
 	 *	Frame size ok ?
 	 */
 	 
-	if(skb->len<sizeof(*ea))
+	if(skb_pull(skb,sizeof(*ea))<sizeof(*ea))
 	{
 		kfree_skb(skb, FREE_READ);
 		return 0;
diff -u --recursive --new-file v1.3.5/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v1.3.5/linux/net/appletalk/ddp.c	Tue Jun 27 14:11:48 1995
+++ linux/net/appletalk/ddp.c	Thu Jun 29 19:18:52 1995
@@ -9,6 +9,9 @@
  *	
  *		Wesley Craig <netatalk@umich.edu>
  *
+ *	Fixes:
+ *		Michael Callahan	:	Made routing work
+ *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
  *		as published by the Free Software Foundation; either version
@@ -16,7 +19,6 @@
  *
  *	TODO
  *		ASYNC I/O
- *		Testing.
  */
  
 #include <asm/segment.h>
@@ -1330,6 +1332,11 @@
 	struct ddpehdr *ddp=(void *)skb->h.raw;
 	struct atalk_iface *atif;
 	struct sockaddr_at tosat;
+        int origlen;
+	
+	/* First strip the MAC header */
+	
+	skb_pull(skb,dev->hard_header_len);
 	
 	/* Size check */
 	if(skb->len<sizeof(*ddp))
@@ -1351,7 +1358,9 @@
 	 *	Trim buffer in case of stray trailing data
 	 */
 	   
-	skb->len=min(skb->len,ddp->deh_len);
+	origlen = skb->len;
+	
+	skb_trim(skb,min(skb->len,ddp->deh_len));
 
 	/*
 	 *	Size check to see if ddp->deh_len was crap
@@ -1389,8 +1398,18 @@
 	{
 		struct atalk_route *rt;
 		struct at_addr ta;
+
+		/* Don't route multicast, etc., packets, or packets
+		   sent to "this network" */
+		if (skb->pkt_type != PACKET_HOST || ddp->deh_dnet == 0) 
+		{
+			kfree_skb(skb, FREE_READ);
+			return(0);
+		}
+
 		ta.s_net=ddp->deh_dnet;
 		ta.s_node=ddp->deh_dnode;
+
 		/* Route the packet */
 		rt=atrtr_find(&ta);
 		if(rt==NULL || ddp->deh_hops==15)
@@ -1399,11 +1418,16 @@
 			return(0);
 		}
 		ddp->deh_hops++;
+
+                /* Fix up skb->len field */
+                skb_trim(skb,min(origlen, rt->dev->hard_header_len + 
+			ddp_dl->header_length + ddp->deh_len));
+
 		*((__u16 *)ddp)=ntohs(*((__u16 *)ddp));		/* Mend the byte order */
 		/*
 		 *	Send the buffer onwards
 		 */
-		if(aarp_send_ddp(dev,skb, &ta, NULL)==-1)
+		if(aarp_send_ddp(rt->dev, skb, &ta, NULL)==-1)
 			kfree_skb(skb, FREE_READ);
 		return 0;
 	}
@@ -1523,14 +1547,16 @@
 	skb->sk=sk;
 	skb->free=1;
 	skb->arp=1;
-	skb->len=size;
+	skb_reserve(skb,ddp_dl->header_length);
+	skb_reserve(skb,dev->hard_header_len);
+	skb_put(skb,size);
 
 	skb->dev=dev;
 	
 	if(sk->debug)
 		printk("SK %p: Begin build.\n", sk);
 	
-	skb->h.raw=skb->data+ddp_dl->header_length+dev->hard_header_len;	
+	skb->h.raw=skb->data;	
 	
 	ddp=(struct ddpehdr *)skb->h.raw;
 	ddp->deh_pad=0;
@@ -1587,12 +1613,12 @@
 		if(sk->debug)
 			printk("SK %p: Loop back.\n", sk);
 		/* loop back */
-		sk->wmem_alloc-=skb->mem_len;
+		sk->wmem_alloc-=skb->truesize;
 		ddp_dl->datalink_header(ddp_dl, skb, dev->dev_addr);
 		skb->sk = NULL;
 		skb->h.raw = skb->data + ddp_dl->header_length + dev->hard_header_len;
-		skb->len -= ddp_dl->header_length ;
-		skb->len -= dev->hard_header_len ;
+		skb_pull(skb,dev->hard_header_len);
+		skb_pull(skb,ddp_dl->header_length);
 		atalk_rcv(skb,dev,NULL);
 	}
 	else 
@@ -1837,7 +1863,7 @@
 		printk("Unable to register DDP with SNAP.\n");
 	register_netdevice_notifier(&ddp_notifier);
 	aarp_proto_init();
-	printk("Appletalk ALPHA 0.08 for Linux NET3.029\n");
+	printk("Appletalk BETA 0.11 for Linux NET3.030\n");
 	
 }
 #endif
diff -u --recursive --new-file v1.3.5/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- v1.3.5/linux/net/ax25/af_ax25.c	Tue Jun 27 14:11:48 1995
+++ linux/net/ax25/af_ax25.c	Thu Jun 29 19:18:52 1995
@@ -56,6 +56,7 @@
  *			Jonathan(G4KLX)		and removed all the old Berkeley, added IP mode registration.
  *			Darryl(G7LED)		stuff. Cross-port digipeating. Minor fixes and enhancements.
  *			Alan(GW4PTS)		Missed suser() on axassociate checks
+ *	AX.25 030	Alan(GW4PTS)		Switched to new buffers. Not tested netrom/new buffers yet.
  *
  *	To do:
  *		Support use as digipeater, including an on/off ioctl
@@ -63,6 +64,8 @@
  *		copy only when needed.
  *		Consider better arbitary protocol support.
  *		Fix non-blocking connect failure.
+ *		VC mode doesnt work on the PI card.
+ *		Settable protocol id for SEQPACKET sockets
  */
  
 #include <linux/config.h>
@@ -343,10 +346,10 @@
 				return;
 
 			copy->sk = sk;
-			sk->rmem_alloc += copy->mem_len;
+			sk->rmem_alloc += copy->truesize;
 			skb_queue_tail(&sk->receive_queue, copy);
 			if (!sk->dead)
-				sk->data_ready(sk, skb->len - 2);
+				sk->data_ready(sk, skb->len);
 		}
 
 		sk = sk->next;
@@ -507,6 +510,7 @@
 	ax25->n2      = DEFAULT_N2;
 	ax25->t3      = DEFAULT_T3;
 
+	ax25->backoff   = 1;
 	ax25->condition = 0x00;
 	ax25->t1timer   = 0;
 	ax25->t2timer   = 0;
@@ -639,7 +643,7 @@
 		case AX25_T1:
 			if (opt < 1)
 				return -EINVAL;
-			sk->ax25->t1 = opt * PR_SLOWHZ;
+			sk->ax25->rtt = (opt * PR_SLOWHZ) / 2;
 			return 0;
 
 		case AX25_T2:
@@ -660,6 +664,10 @@
 			sk->ax25->t3 = opt * PR_SLOWHZ;
 			return 0;
 	
+		case AX25_BACKOFF:
+			sk->ax25->backoff = opt ? 1 : 0;
+			return 0;
+	
 		default:
 			return -ENOPROTOOPT;
 	}
@@ -701,6 +709,10 @@
 			val = sk->ax25->t3 / PR_SLOWHZ;
 			break;
 	
+		case AX25_BACKOFF:
+			val = sk->ax25->backoff;
+			break;
+	
 		default:
 			return -ENOPROTOOPT;
 	}
@@ -874,14 +886,15 @@
 	sk->write_space  = def_callback1;
 	sk->error_report = def_callback1;
 
-	ax25->rtt    = osk->ax25->rtt;
-	ax25->t1     = osk->ax25->t1;
-	ax25->t2     = osk->ax25->t2;
-	ax25->t3     = osk->ax25->t3;
-	ax25->n2     = osk->ax25->n2;
+	ax25->backoff = osk->ax25->backoff;
+	ax25->rtt     = osk->ax25->rtt;
+	ax25->t1      = osk->ax25->t1;
+	ax25->t2      = osk->ax25->t2;
+	ax25->t3      = osk->ax25->t3;
+	ax25->n2      = osk->ax25->n2;
 
-	ax25->window = osk->ax25->window;
-	ax25->device = dev;
+	ax25->window  = osk->ax25->window;
+	ax25->device  = dev;
 
 	memcpy(&ax25->source_addr, &osk->ax25->source_addr, sizeof(ax25_address));
 	
@@ -1227,7 +1240,7 @@
  
 int ax25_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *ptype)
 {
-	unsigned char *data = skb->data;
+	unsigned char *data;
 	struct sock *make;
 	struct sock *sk;
 	int type = 0;
@@ -1236,6 +1249,12 @@
 	ax25_address src, dest;
 	struct sock *raw;
 	int mine = 0;
+	
+	data=skb->data;
+	
+	/*
+	 *	Process the AX.25/LAPB frame.
+	 */
 
 	skb->sk = NULL;		/* Initially we don't know who its for */
 	
@@ -1279,7 +1298,6 @@
 			}
 #endif
 			build_ax25_addr(skb->data + 1, &src, &dest, &dp, type);
-			skb->len += dev->hard_header_len;
 			skb->arp = 1;
 			dev_queue_xmit(skb, dev, SOPRI_NORMAL);			
 		} else {
@@ -1289,11 +1307,7 @@
 		return 0;
 	}
 
-	/*
-	 *	Adjust the lengths for digipeated input
-	 */
-	skb->len -= sizeof(ax25_address) * dp.ndigi;
-	
+	 
 	/* For our port addreses ? */
 	if (ax25cmp(&dest, (ax25_address *)dev->dev_addr) == 0)
 		mine = 1;
@@ -1311,7 +1325,8 @@
 		if ((raw = ax25_addr_match(&dest)) != NULL)
 			ax25_send_to_raw(raw, skb, (int)*data);
 
-		if (!mine && ax25cmp(&dest, (ax25_address *)dev->broadcast) != 0) {
+		if (!mine && ax25cmp(&dest, (ax25_address *)dev->broadcast) != 0) 
+		{
 			kfree_skb(skb, FREE_READ);
 			return 0;
 		}
@@ -1334,11 +1349,15 @@
 					if (sk->rmem_alloc >= sk->rcvbuf) {
 						kfree_skb(skb, FREE_READ);
 					} else {
+						/*
+						 *	Remove kiss/headers
+						 */
+						skb_pull(skb,3+size_ax25_addr(&dp));
 						skb_queue_tail(&sk->receive_queue, skb);
 						skb->sk = sk;
-						sk->rmem_alloc += skb->mem_len;
+						sk->rmem_alloc += skb->truesize;
 						if (!sk->dead)
-							sk->data_ready(sk, skb->len - 2);
+							sk->data_ready(sk, skb->len);
 					}
 				} else {
 					kfree_skb(skb, FREE_READ);
@@ -1354,6 +1373,12 @@
 	}
 	
 	/* LAPB */
+	
+	/*
+	 *	Pull of the AX.25 headers leaving the CTRL/PID bytes
+	 */
+	skb_pull(skb, 1+size_ax25_addr(&dp));
+	
 	if ((ax25 = ax25_find_cb(&dest, &src, dev)) != NULL) {
 		skb->h.raw = data;
 		/* Process the frame. If it is queued up internally it returns one otherwise we 
@@ -1457,7 +1482,7 @@
 
 	if (sk != NULL) {
 		if (!sk->dead)
-			sk->data_ready(sk, skb->len - 2);
+			sk->data_ready(sk, skb->len );
 	} else {
 		kfree_skb(skb, FREE_READ);
 	}
@@ -1559,9 +1584,8 @@
 	skb->sk   = sk;
 	skb->free = 1;
 	skb->arp  = 1;
-	skb->len  = size;
-	
-	asmptr = skb->data;
+	skb_reserve(skb, 3+size_ax25_addr(dp));
+	asmptr = skb_push(skb,3+size_ax25_addr(dp));
 	if (sk->debug) {
 		printk("Building AX.25 Header (dp=%p).\n", dp);
 		if (dp != 0)
@@ -1584,7 +1608,7 @@
 		printk("AX.25: Appending user data\n");
 
 	/* User data follows immediately after the AX.25 data */
-	memcpy_fromfs(asmptr, ubuf, len);
+	memcpy_fromfs(skb_put(skb,len), ubuf, len);
 	if (sk->debug)
 		printk("AX.25: Transmitting buffer\n");
 	if (sk->type == SOCK_SEQPACKET) {
@@ -1621,6 +1645,7 @@
 	int copied = 0;
 	struct sk_buff *skb;
 	int er;
+	int bias=0;
 
 	if (sk->err) {
 		er      = -sk->err;
@@ -1632,15 +1657,19 @@
 		*addr_len = sizeof(*sax);
 
 	/* This works for seqpacket too. The receiver has ordered the queue for us! We do one quick check first though */
-	if (sk->type == SOCK_SEQPACKET && sk->state != TCP_ESTABLISHED)
-		return -ENOTCONN;
+	if (sk->type == SOCK_SEQPACKET)
+	{
+		if(sk->state != TCP_ESTABLISHED)
+			return -ENOTCONN;
+		bias=2;
+	}
 
 	/* Now we can treat all alike */
 	if ((skb = skb_recv_datagram(sk, flags, noblock, &er)) == NULL)
 		return er;
 
-	copied= (size < skb->len) ? size : skb->len;
-	skb_copy_datagram(skb, sk->type == SOCK_SEQPACKET ? 2 : 0, ubuf, copied);
+	copied= (size < skb->len-bias) ? size : skb->len-bias;
+	skb_copy_datagram(skb, bias, ubuf, copied);
 	
 	if (sax) {
 		struct sockaddr_ax25 addr;
@@ -1907,10 +1936,11 @@
 
 #ifdef CONFIG_INET
  
-int ax25_encapsulate(unsigned char *buff, struct device *dev, unsigned short type, void *daddr,
-		void *saddr, unsigned len, struct sk_buff *skb)
+int ax25_encapsulate(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr,
+		void *saddr, unsigned len)
 {
   	/* header is an AX.25 UI frame from us to them */
+ 	unsigned char *buff=skb_push(skb,17);
   	*buff++ = 0;	/* KISS DATA */
   	
 	if (daddr != NULL)
diff -u --recursive --new-file v1.3.5/linux/net/ax25/ax25_in.c linux/net/ax25/ax25_in.c
--- v1.3.5/linux/net/ax25/ax25_in.c	Tue Jun  6 12:16:43 1995
+++ linux/net/ax25/ax25_in.c	Thu Jun 29 19:18:52 1995
@@ -72,8 +72,7 @@
 #ifdef CONFIG_INET
 		case AX25_P_IP:
 			ax25_ip_mode_set(&ax25->dest_addr, ax25->device, 'V');
-			skb->h.raw = ((char *)(iframe)) + 2;
-			skb->len  -= 2;
+			skb->h.raw = skb->data;
 			ip_rcv(skb, skb->dev, NULL);	/* Wrong ptype */
 			queued = 1;
 			break;
@@ -559,6 +558,12 @@
 	int queued = 0, frametype;
 	unsigned char *frame;
 
+	if (ax25->state != AX25_STATE_1 && ax25->state != AX25_STATE_2 &&
+	    ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4) {
+		printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
+		return queued;
+	}
+
 	del_timer(&ax25->timer);
 
 	frame = skb->h.raw;
@@ -578,14 +583,11 @@
 		case AX25_STATE_4:
 			queued = ax25_state4_machine(ax25, skb, frame, frametype, type);
 			break;
-		default:
-			printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
-			break;
 	}
 
 	ax25_set_timer(ax25);
 
-	return(queued);
+	return queued;
 }
 
 #endif
diff -u --recursive --new-file v1.3.5/linux/net/ax25/ax25_route.c linux/net/ax25/ax25_route.c
--- v1.3.5/linux/net/ax25/ax25_route.c	Tue Jun  6 12:16:43 1995
+++ linux/net/ax25/ax25_route.c	Thu Jun 29 19:18:52 1995
@@ -148,7 +148,7 @@
 	len += sprintf(buffer, "callsign  dev count      time mode\n");
 
 	for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-		len += sprintf(buffer + len, "%-9s %-3s %5d %9ld",
+		len += sprintf(buffer + len, "%-9s %-3s %5d %9d",
 			ax2asc(&ax25_rt->callsign),
 			ax25_rt->dev ? ax25_rt->dev->name : "???",
 			ax25_rt->n,
diff -u --recursive --new-file v1.3.5/linux/net/ax25/ax25_subr.c linux/net/ax25/ax25_subr.c
--- v1.3.5/linux/net/ax25/ax25_subr.c	Tue Jun  6 12:16:43 1995
+++ linux/net/ax25/ax25_subr.c	Thu Jun 29 19:18:52 1995
@@ -46,6 +46,8 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
+/* #define	NO_BACKOFF	*/
+
 /*
  * This routine purges the input queue of frames.
  */
@@ -140,26 +142,26 @@
 {
 	struct sk_buff *skb;
 	unsigned char  *dptr;
-	int len;
 	struct device *dev;
+	int asize;
 	
 	if ((dev = ax25->device) == NULL)
 		return;	/* Route died */
 
-	if ((skb = alloc_skb(16 + 1 + size_ax25_addr(ax25->digipeat), GFP_ATOMIC)) == NULL)
+	asize= 1+size_ax25_addr(ax25->digipeat);
+	
+	if ((skb = alloc_skb(16 + asize, GFP_ATOMIC)) == NULL)
 		return;
-
+	skb_reserve(skb, asize);
+	
 	if (ax25->sk != NULL) {
 		skb->sk = ax25->sk;
-        	ax25->sk->wmem_alloc += skb->mem_len;
+        	ax25->sk->wmem_alloc += skb->truesize;
 	}
 
-	dptr = skb->data;
-	
-	dptr += 1 + size_ax25_addr(ax25->digipeat);	/* KISS byte & 2 calls */
-
 	/* Assume a response - address structure for DTE */
-	len = 1;		/* Normal size */
+	dptr = skb_put(skb,1);
+	
 	
 	if ((frametype & U) == S)		/* S frames carry NR */
 		frametype |= (ax25->vr << 5);
@@ -167,8 +169,7 @@
 	*dptr = frametype;
 
 	skb->free = 1;
-	skb->len  = len + size_ax25_addr(ax25->digipeat) + 1;
-
+	skb_push(skb,asize);
 	ax25_transmit_buffer(ax25, skb, type);
 }
 
@@ -187,19 +188,23 @@
 	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
 		return;	/* Next SABM will get DM'd */
 
-	skb->len = len;
+	skb_reserve(skb,len-1);
 
 	ax25_digi_invert(digi, &retdigi);
 
-	dptr = skb->data + 1 + size_ax25_addr(digi);
+	dptr = skb_put(skb,1);
 	skb->sk = NULL;
 
-	*dptr = DM;
+	*dptr = DM | PF;
 
 	if (dev == NULL)
 		return;
 
-	dptr    = skb->data;
+	/*
+	 *	Do the address ourselves.
+	 */
+
+	dptr    = skb_push(skb, len-1);
 	*dptr++ = 0;
 	dptr   += build_ax25_addr(dptr, dest, src, &retdigi, C_RESPONSE);
 
@@ -214,12 +219,17 @@
  */
 unsigned short ax25_calculate_t1(ax25_cb *ax25)
 {
-	int t, n;
-	
-	for (t = 2, n = 0; n < ax25->n2count; n++)
-		t *= 2;
-		
+#ifndef NO_BACKOFF
+	int n, t = 2;
+
+	if (ax25->backoff)
+		for (n = 0; n < ax25->n2count; n++)
+			t *= 2;
+
 	return t * ax25->rtt;
+#else
+	return 2 * ax25->rtt;
+#endif
 }
 
 /*
@@ -227,7 +237,7 @@
  */
 void ax25_calculate_rtt(ax25_cb *ax25)
 {
-	if (ax25->n2count == 0)
+	if (ax25->t1timer > 0 && ax25->n2count == 0)
 		ax25->rtt = (9 * ax25->rtt + ax25->t1 - ax25->t1timer) / 10;
 
 	/* Don't go below one second */
diff -u --recursive --new-file v1.3.5/linux/net/core/dev.c linux/net/core/dev.c
--- v1.3.5/linux/net/core/dev.c	Tue Jun  6 12:16:43 1995
+++ linux/net/core/dev.c	Fri Jun 30 15:08:53 1995
@@ -380,11 +380,7 @@
 				struct sk_buff *skb2;
 				if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL)
 					break;
-				/*
-				 *	The protocol knows this has (for other paths) been taken off
-				 *	and adds it back.
-				 */
-				skb2->len-=skb->dev->hard_header_len;
+				skb2->h.raw = skb2->data + dev->hard_header_len;
 				ptype->func(skb2, skb->dev, ptype);
 				nitcount--;
 			}
@@ -521,7 +517,7 @@
 		 *	in effect handle the incoming data as if it were from a circular buffer
 		 */
 
-		to = skb->data;
+		to = skb_put(skb,len);
 		left = len;
 
 		len2 = len;
@@ -543,7 +539,6 @@
 	 *	Tag the frame and kick it to the proper receive routine
 	 */
 	 
-	skb->len = len;
 	skb->dev = dev;
 	skb->free = 1;
 
@@ -647,13 +642,12 @@
 		
 	       /*
 		*	Bump the pointer to the next structure.
-		*	This assumes that the basic 'skb' pointer points to
-		*	the MAC header, if any (as indicated by its "length"
-		*	field).  Take care now!
+		*
+		*	On entry to the protocol layer. skb->data and
+		*	skb->h.raw point to the MAC and encapsulated data
 		*/
 
-		skb->h.raw = skb->data + skb->dev->hard_header_len;
-		skb->len -= skb->dev->hard_header_len;
+		skb->h.raw = skb->data+skb->dev->hard_header_len;
 
 	       /*
 		* 	Fetch the packet protocol ID. 
@@ -841,19 +835,19 @@
 		(*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
 
 		/*
-		 *	Write this block to the caller's space. 
-		 */
-		 
-		memcpy_tofs(pos, &ifr, sizeof(struct ifreq));
-		pos += sizeof(struct ifreq);
-		len -= sizeof(struct ifreq);
-		
-		/*
 		 *	Have we run out of space here ?
 		 */
 	
 		if (len < sizeof(struct ifreq)) 
 			break;
+
+		/*
+		 *	Write this block to the caller's space. 
+		 */
+		 
+		memcpy_tofs(pos, &ifr, sizeof(struct ifreq));
+		pos += sizeof(struct ifreq);
+		len -= sizeof(struct ifreq);		
   	}
 
 	/*
@@ -1065,9 +1059,6 @@
 			(*(struct sockaddr_in *)
 				&ifr.ifr_broadaddr).sin_port = 0;
 			goto rarok;
-			memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
-			ret = 0;
-			break;
 
 		case SIOCSIFBRDADDR:	/* Set the broadcast address */
 			dev->pa_brdaddr = (*(struct sockaddr_in *)
@@ -1082,9 +1073,7 @@
 				&ifr.ifr_dstaddr).sin_family = dev->family;
 			(*(struct sockaddr_in *)
 				&ifr.ifr_dstaddr).sin_port = 0;
-				memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
-			ret = 0;
-			break;
+			goto rarok;
 	
 		case SIOCSIFDSTADDR:	/* Set the destination address (for point-to-point links) */
 			dev->pa_dstaddr = (*(struct sockaddr_in *)
@@ -1175,9 +1164,7 @@
 			ifr.ifr_map.irq=dev->irq;
 			ifr.ifr_map.dma=dev->dma;
 			ifr.ifr_map.port=dev->if_port;
-			memcpy_tofs(arg,&ifr,sizeof(struct ifreq));
-			ret=0;
-			break;
+			goto rarok;
 			
 		case SIOCSIFMAP:
 			if(dev->set_config==NULL)
diff -u --recursive --new-file v1.3.5/linux/net/core/skbuff.c linux/net/core/skbuff.c
--- v1.3.5/linux/net/core/skbuff.c	Tue Jun  6 12:16:43 1995
+++ linux/net/core/skbuff.c	Thu Jun 29 21:26:15 1995
@@ -6,8 +6,9 @@
  *
  *	Fixes:	
  *		Alan Cox	:	Fixed the worst of the load balancer bugs.
- *		Dave Platt	:	Interrupt stacking fix
+ *		Dave Platt	:	Interrupt stacking fix.
  *	Richard Kooijman	:	Timestamp fixes.
+ *		Alan Cox	:	Changed buffer format.
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -46,7 +47,6 @@
  *	Resource tracking variables
  */
 
-volatile unsigned long net_memory = 0;
 volatile unsigned long net_skbcount = 0;
 volatile unsigned long net_locked = 0;
 volatile unsigned long net_allocs = 0;
@@ -56,7 +56,6 @@
 void show_net_buffers(void)
 {
 	printk("Networking buffers in use          : %lu\n",net_skbcount);
-	printk("Memory committed to network buffers: %lu\n",net_memory);
 	printk("Network buffers locked by drivers  : %lu\n",net_locked);
 	printk("Total network buffer allocations   : %lu\n",net_allocs);
 	printk("Total failed network buffer allocs : %lu\n",net_fails);
@@ -127,24 +126,53 @@
 	{
 		printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n",
 			file,line);
-		printk("skb=%p, real size=%ld, claimed size=%ld, free=%d\n",
-			skb,skb->truesize,skb->mem_len,skb->free);
+		printk("skb=%p, real size=%d, free=%d\n",
+			skb,skb->truesize,skb->free);
 		return -1;
 	}
 	if(skb->magic_debug_cookie!=SK_GOOD_SKB)
 	{
 		printk("File: %s Line %d, passed a non skb!\n", file,line);
-		printk("skb=%p, real size=%ld, claimed size=%ld, free=%d\n",
-			skb,skb->truesize,skb->mem_len,skb->free);
+		printk("skb=%p, real size=%d, free=%d\n",
+			skb,skb->truesize,skb->free);
 		return -1;
 	}
-	if(skb->mem_len!=skb->truesize)
+	if(skb->head>skb->data)
 	{
-		printk("File: %s Line %d, Dubious size setting!\n",file,line);
-		printk("skb=%p, real size=%ld, claimed size=%ld\n",
-			skb,skb->truesize,skb->mem_len);
+		printk("File: %s Line %d, head > data !\n", file,line);
+		printk("skb=%p, head=%p, data=%p\n",
+			skb,skb->head,skb->data);
 		return -1;
 	}
+	if(skb->tail>skb->end)
+	{
+		printk("File: %s Line %d, tail > end!\n", file,line);
+		printk("skb=%p, tail=%p, end=%p\n",
+			skb,skb->tail,skb->end);
+		return -1;
+	}
+	if(skb->data>skb->tail)
+	{
+		printk("File: %s Line %d, data > tail!\n", file,line);
+		printk("skb=%p, data=%p, tail=%p\n",
+			skb,skb->data,skb->tail);
+		return -1;
+	}
+	if(skb->tail-skb->data!=skb->len)
+	{
+		printk("File: %s Line %d, wrong length\n", file,line);
+		printk("skb=%p, data=%p, end=%p len=%ld\n",
+			skb,skb->data,skb->end,skb->len);
+		return -1;
+	}
+	if((unsigned long) skb->end > (unsigned long) skb)
+	{
+		printk("File: %s Line %d, control overrun\n", file,line);
+		printk("skb=%p, end=%p\n",
+			skb,skb->end);
+		return -1;
+	}
+
 	/* Guess it might be acceptable then */
 	return 0;
 }
@@ -324,6 +352,79 @@
 	restore_flags(flags);
 }
 
+/*
+ *	Add data to an sk_buff
+ */
+ 
+unsigned char *skb_put(struct sk_buff *skb, int len)
+{
+	unsigned char *tmp=skb->tail;
+	IS_SKB(skb);
+	skb->tail+=len;
+	skb->len+=len;
+	IS_SKB(skb);
+	if(skb->tail>skb->end)
+		panic("skput:over: %p:%d", __builtin_return_address(0),len);
+	return tmp;
+}
+
+unsigned char *skb_push(struct sk_buff *skb, int len)
+{
+	IS_SKB(skb);
+	skb->data-=len;
+	skb->len+=len;
+	IS_SKB(skb);
+	if(skb->data<skb->head)
+		panic("skpush:under: %p:%d", __builtin_return_address(0),len);
+	return skb->data;
+}
+
+int skb_pull(struct sk_buff *skb, int len)
+{
+	IS_SKB(skb);
+	if(len>skb->len)
+		len=skb->len;
+	skb->data+=len;
+	skb->len-=len;
+	return len;
+}
+
+int skb_headroom(struct sk_buff *skb)
+{
+	IS_SKB(skb);
+	return skb->data-skb->head;
+}
+
+int skb_tailroom(struct sk_buff *skb)
+{
+	IS_SKB(skb);
+	return skb->end-skb->tail;
+}
+
+void skb_reserve(struct sk_buff *skb, int len)
+{
+	IS_SKB(skb);
+	skb->data+=len;
+	skb->tail+=len;
+	if(skb->tail>skb->end)
+		panic("sk_res: over");
+	if(skb->data<skb->head)
+		panic("sk_res: under");
+	IS_SKB(skb);
+}
+
+void skb_trim(struct sk_buff *skb, int len)
+{
+	IS_SKB(skb);
+	if(skb->len>len)
+	{
+		skb->len=len;
+		skb->tail=skb->data+len;
+	}
+}
+
+
+
 #endif
 
 /*
@@ -359,9 +460,9 @@
 	        if(skb->sk->prot!=NULL)
 		{
 			if (rw)
-		     		skb->sk->prot->rfree(skb->sk, skb, skb->mem_len);
+		     		skb->sk->prot->rfree(skb->sk, skb);
 		     	else
-		     		skb->sk->prot->wfree(skb->sk, skb, skb->mem_len);
+		     		skb->sk->prot->wfree(skb->sk, skb);
 
 		}
 		else
@@ -371,17 +472,17 @@
 			save_flags(flags);
 			cli();
 			if (rw)
-				skb->sk->rmem_alloc-=skb->mem_len;
+				skb->sk->rmem_alloc-=skb->truesize;
 			else
-				skb->sk->wmem_alloc-=skb->mem_len;
+				skb->sk->wmem_alloc-=skb->truesize;
 			restore_flags(flags);
 			if(!skb->sk->dead)
 				skb->sk->write_space(skb->sk);
-			kfree_skbmem(skb,skb->mem_len);
+			kfree_skbmem(skb);
 		}
 	}
 	else
-		kfree_skbmem(skb, skb->mem_len);
+		kfree_skbmem(skb);
 }
 
 /*
@@ -392,8 +493,11 @@
 {
 	struct sk_buff *skb;
 	unsigned long flags;
+	int len=size;
+	unsigned char *bptr;
 
-	if (intr_count && priority!=GFP_ATOMIC) {
+	if (intr_count && priority!=GFP_ATOMIC) 
+	{
 		static int count = 0;
 		if (++count < 5) {
 			printk("alloc_skb called nonatomically from interrupt %p\n",
@@ -402,9 +506,15 @@
 		}
 	}
 
-	size+=sizeof(struct sk_buff);
-	skb=(struct sk_buff *)kmalloc(size,priority);
-	if (skb == NULL)
+	size=(size+15)&~15;		/* Allow for alignments. Make a multiple of 16 bytes */
+	size+=sizeof(struct sk_buff);	/* And stick the control itself on the end */
+	
+	/*
+	 *	Allocate some space
+	 */
+	 
+	bptr=(unsigned char *)kmalloc(size,priority);
+	if (bptr == NULL)
 	{
 		net_fails++;
 		return NULL;
@@ -413,34 +523,41 @@
 	if(skb->magic_debug_cookie == SK_GOOD_SKB)
 		printk("Kernel kmalloc handed us an existing skb (%p)\n",skb);
 #endif
-
+	/*
+	 *	Now we play a little game with the caches. Linux kmalloc is
+	 *	a bit cache dumb, in fact its just about maximally non 
+	 *	optimal for typical kernel buffers. We actually run faster
+	 *	by doing the following. Which is to deliberately put the
+	 *	skb at the _end_ not the start of the memory block.
+	 */
 	net_allocs++;
+	
+	skb=(struct sk_buff *)(bptr+size)-1;
 
 	skb->free = 2;	/* Invalid so we pick up forgetful users */
 	skb->lock = 0;
 	skb->pkt_type = PACKET_HOST;	/* Default type */
-	skb->truesize = size;
-	skb->mem_len = size;
-	skb->mem_addr = skb;
-#ifdef CONFIG_SLAVE_BALANCING
-	skb->in_dev_queue = 0;
-#endif
-	skb->fraglist = NULL;
 	skb->prev = skb->next = NULL;
 	skb->link3 = NULL;
 	skb->sk = NULL;
+	skb->truesize=size;
 	skb->localroute=0;
 	skb->stamp.tv_sec=0;	/* No idea about time */
 	skb->localroute = 0;
 	save_flags(flags);
 	cli();
-	net_memory += size;
 	net_skbcount++;
 	restore_flags(flags);
 #if CONFIG_SKB_CHECK
 	skb->magic_debug_cookie = SK_GOOD_SKB;
 #endif
 	skb->users = 0;
+	/* Load the data pointers */
+	skb->head=bptr;
+	skb->data=bptr;
+	skb->tail=bptr;
+	skb->end=bptr+len;
+	skb->len=0;
 	return skb;
 }
 
@@ -448,42 +565,14 @@
  *	Free an skbuff by memory
  */
 
-void kfree_skbmem(struct sk_buff *skb,unsigned size)
+void kfree_skbmem(struct sk_buff *skb)
 {
 	unsigned long flags;
-#ifdef CONFIG_SLAVE_BALANCING
-	save_flags(flags);
-	cli();
-	if(skb->in_dev_queue && skb->dev!=NULL)
-		skb->dev->pkt_queue--;
-	restore_flags(flags);
-#endif
-#ifdef CONFIG_SKB_CHECK
-	IS_SKB(skb);
-	if(size!=skb->truesize)
-		printk("kfree_skbmem: size mismatch.\n");
-
-	if(skb->magic_debug_cookie == SK_GOOD_SKB)
-	{
-		save_flags(flags);
-		cli();
-		IS_SKB(skb);
-		skb->magic_debug_cookie = SK_FREED_SKB;
-		kfree_s((void *)skb,size);
-		net_skbcount--;
-		net_memory -= size;
-		restore_flags(flags);
-	}
-	else
-		printk("kfree_skbmem: bad magic cookie\n");
-#else
 	save_flags(flags);
 	cli();
-	kfree_s((void *)skb,size);
+	kfree((void *)skb->head);
 	net_skbcount--;
-	net_memory -= size;
 	restore_flags(flags);
-#endif
 }
 
 /*
@@ -496,22 +585,34 @@
 	struct sk_buff *n;
 	unsigned long offset;
 
-	n=alloc_skb(skb->mem_len-sizeof(struct sk_buff),priority);
+	/*
+	 *	Allocate the copy buffer
+	 */
+	 
+	IS_SKB(skb);
+	
+	n=alloc_skb(skb->truesize-sizeof(struct sk_buff),priority);
 	if(n==NULL)
 		return NULL;
 
-	offset=((char *)n)-((char *)skb);
-
-	memcpy(n->data,skb->data,skb->mem_len-sizeof(struct sk_buff));
-	n->len=skb->len;
+	/*
+	 *	Shift between the two data areas in bytes
+	 */
+	 
+	offset=n->head-skb->head;
+
+	/* Set the data pointer */
+	skb_reserve(n,skb->data-skb->head);
+	/* Set the tail pointer and length */
+	skb_put(n,skb->len);
+	/* Copy the bytes */
+	memcpy(n->head,skb->head,skb->end-skb->head);
 	n->link3=NULL;
 	n->sk=NULL;
 	n->when=skb->when;
 	n->dev=skb->dev;
 	n->h.raw=skb->h.raw+offset;
 	n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
-	n->fraglen=skb->fraglen;
-	n->fraglist=skb->fraglist;
 	n->saddr=skb->saddr;
 	n->daddr=skb->daddr;
 	n->raddr=skb->raddr;
@@ -524,6 +625,8 @@
 	n->users=0;
 	n->pkt_type=skb->pkt_type;
 	n->stamp=skb->stamp;
+	
+	IS_SKB(n);
 	return n;
 }
 
@@ -566,6 +669,13 @@
 	}
 	else
 		restore_flags(flags);
+}
+
+struct sk_buff *dev_alloc_skb(unsigned int length)
+{
+	struct sk_buff *skb=alloc_skb(length+16, GFP_ATOMIC);
+	skb_reserve(skb,16);
+	return skb;
 }
 
 int skb_device_locked(struct sk_buff *skb)
diff -u --recursive --new-file v1.3.5/linux/net/core/sock.c linux/net/core/sock.c
--- v1.3.5/linux/net/core/sock.c	Tue Jun  6 12:16:43 1995
+++ linux/net/core/sock.c	Thu Jun 29 19:18:52 1995
@@ -314,7 +314,7 @@
 				unsigned long flags;
 				save_flags(flags);
 				cli();
-				sk->wmem_alloc+= c->mem_len;
+				sk->wmem_alloc+= c->truesize;
 				restore_flags(flags); /* was sti(); */
 			}
 			return c;
@@ -337,7 +337,7 @@
 				unsigned long flags;
 				save_flags(flags);
 				cli();
-				sk->rmem_alloc += c->mem_len;
+				sk->rmem_alloc += c->truesize;
 				restore_flags(flags); /* was sti(); */
 			}
 			return(c);
@@ -379,18 +379,19 @@
 }
 
 
-void sock_wfree(struct sock *sk, struct sk_buff *skb, unsigned long size)
+void sock_wfree(struct sock *sk, struct sk_buff *skb)
 {
+	int s=skb->truesize;
 #ifdef CONFIG_SKB_CHECK
 	IS_SKB(skb);
 #endif
-	kfree_skbmem(skb, size);
+	kfree_skbmem(skb);
 	if (sk) 
 	{
 		unsigned long flags;
 		save_flags(flags);
 		cli();
-		sk->wmem_alloc -= size;
+		sk->wmem_alloc -= s;
 		restore_flags(flags);
 		/* In case it might be waiting for more memory. */
 		sk->write_space(sk);
@@ -399,18 +400,19 @@
 }
 
 
-void sock_rfree(struct sock *sk, struct sk_buff *skb, unsigned long size)
+void sock_rfree(struct sock *sk, struct sk_buff *skb)
 {
+	int s=skb->truesize;
 #ifdef CONFIG_SKB_CHECK
 	IS_SKB(skb);
 #endif	
-	kfree_skbmem(skb, size);
+	kfree_skbmem(skb);
 	if (sk) 
 	{
 		unsigned long flags;
 		save_flags(flags);
 		cli();
-		sk->rmem_alloc -= size;
+		sk->rmem_alloc -= s;
 		restore_flags(flags);
 	}
 }
diff -u --recursive --new-file v1.3.5/linux/net/ethernet/eth.c linux/net/ethernet/eth.c
--- v1.3.5/linux/net/ethernet/eth.c	Tue Jun  6 12:16:43 1995
+++ linux/net/ethernet/eth.c	Thu Jun 29 19:18:52 1995
@@ -81,11 +81,10 @@
  *	daddr=NULL	means leave destination address (eg unresolved arp)
  */
 
-int eth_header(unsigned char *buff, struct device *dev, unsigned short type,
-	   void *daddr, void *saddr, unsigned len,
-	   struct sk_buff *skb)
+int eth_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+	   void *daddr, void *saddr, unsigned len)
 {
-	struct ethhdr *eth = (struct ethhdr *)buff;
+	struct ethhdr *eth = (struct ethhdr *)skb_push(skb,14);
 
 	/* 
 	 *	Set the protocol type. For a packet of type ETH_P_802_3 we put the length
diff -u --recursive --new-file v1.3.5/linux/net/ethernet/pe2.c linux/net/ethernet/pe2.c
--- v1.3.5/linux/net/ethernet/pe2.c	Tue Jun  6 12:16:43 1995
+++ linux/net/ethernet/pe2.c	Thu Jun 29 19:18:52 1995
@@ -12,8 +12,8 @@
 	unsigned long	len = skb->len;
 	unsigned long	hard_len = dev->hard_header_len;
 
-	dev->hard_header(skb->data, dev, ETH_P_IPX,
-			dest_node, NULL, len - hard_len, skb);
+	dev->hard_header(skb, dev, ETH_P_IPX,
+			dest_node, NULL, len - hard_len);
 	skb->h.raw = skb->data + hard_len;
 }
 
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v1.3.5/linux/net/ipv4/af_inet.c	Fri Jun 16 22:02:56 1995
+++ linux/net/ipv4/af_inet.c	Thu Jun 29 19:18:52 1995
@@ -39,6 +39,7 @@
  *		Alan Cox	:	Allow large numbers of pending sockets
  *					(eg for big web sites), but only if
  *					specifically application requested.
+ *		Alan Cox	:	New buffering throughout IP. Used dumbly.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -1539,7 +1540,7 @@
 	int i;
 
 
-	printk("Swansea University Computer Society TCP/IP for NET3.029 (Snapshot #6)\n");
+	printk("Swansea University Computer Society TCP/IP for NET3.030 (Snapshot #1)\n");
 
 	/*
 	 *	Tell SOCKET that we are alive... 
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v1.3.5/linux/net/ipv4/arp.c	Tue Jun  6 12:16:43 1995
+++ linux/net/ipv4/arp.c	Thu Jun 29 19:18:52 1995
@@ -333,7 +333,8 @@
 		printk("ARP: no memory to send an arp packet\n");
 		return;
 	}
-	skb->len = sizeof(struct arphdr) + dev->hard_header_len + 2*(dev->addr_len+4);
+	skb_reserve(skb, dev->hard_header_len);
+	arp = (struct arphdr *) skb_put(skb,sizeof(struct arphdr) + 2*(dev->addr_len+4));
 	skb->arp = 1;
 	skb->dev = dev;
 	skb->free = 1;
@@ -342,10 +343,9 @@
 	 *	Fill the device header for the ARP frame
 	 */
 
-	dev->hard_header(skb->data,dev,ptype,dest_hw?dest_hw:dev->broadcast,src_hw?src_hw:NULL,skb->len,skb);
+	dev->hard_header(skb,dev,ptype,dest_hw?dest_hw:dev->broadcast,src_hw?src_hw:NULL,skb->len);
 
 	/* Fill out the arp protocol part. */
-	arp = (struct arphdr *) (skb->data + dev->hard_header_len);
 	arp->ar_hrd = htons(dev->type);
 #ifdef CONFIG_AX25
 #ifdef CONFIG_NETROM
@@ -573,7 +573,12 @@
 	unsigned char ha[MAX_ADDR_LEN];	/* So we can enable ints again. */
 	long sip,tip;
 	unsigned char *sha,*tha;
-
+	
+/*
+ *	ARP carries the MAC addresses wrapped in the packet. We can't sanity
+ *	check this as proxy arp has them different.
+ */
+	skb_pull(skb,dev->hard_header_len);
 /*
  *	The hardware length of the packet should match the hardware length
  *	of the device.  Similarly, the hardware types should match.  The
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- v1.3.5/linux/net/ipv4/icmp.c	Fri Jun 16 22:02:56 1995
+++ linux/net/ipv4/icmp.c	Fri Jun 30 15:05:40 1995
@@ -112,7 +112,7 @@
 	 *	Find the original IP header.
 	 */
 	 
-	iph = (struct iphdr *) (skb_in->data + dev->hard_header_len);
+	iph = (struct iphdr *) skb_in->data;
 	
 	/*
 	 *	No replies to MAC multicast
@@ -243,7 +243,7 @@
 	 *	Re-adjust length according to actual IP header size. 
 	 */
 
-	skb->len = offset + sizeof(struct icmphdr) + sizeof(struct iphdr) + 8;
+	skb_put(skb,sizeof(struct icmphdr) + sizeof(struct iphdr) + 8);
 	
 	/*
 	 *	Fill in the frame
@@ -350,7 +350,9 @@
 static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb,
 	struct device *dev, unsigned long source)
 {
+#ifndef CONFIG_IP_FORWARD
 	struct rtable *rt;
+#endif
 	struct iphdr *iph;
 	unsigned long ip;
 
@@ -377,7 +379,7 @@
 			 */
 #ifdef not_a_good_idea
 			ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
-				ip, 0, icmph->un.gateway, dev,0, 0);
+				ip, 0, icmph->un.gateway, dev,0, 0, 0);
 			break;
 #endif
 		case ICMP_REDIR_HOST:
@@ -398,7 +400,7 @@
 				break;
 			printk("ICMP redirect from %s\n", in_ntoa(source));
 			ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_HOST | RTF_GATEWAY),
-				ip, 0, icmph->un.gateway, dev,0, 0, 0);
+				ip, 0, icmph->un.gateway, dev,0, 0, 0, 0);
 			break;
 		case ICMP_REDIR_NETTOS:
 		case ICMP_REDIR_HOSTTOS:
@@ -459,7 +461,7 @@
 	 *	Re-adjust length according to actual IP header size. 
 	 */
 	 
-	skb2->len = offset + len;
+	skb_put(skb2,len);
 
 	/*
 	 *	Build ICMP_ECHO Response message. 
@@ -497,15 +499,13 @@
 	unsigned long *timeptr, midtime;
 	struct device *ndev=NULL;
 
-        if (len != 20)
+        if (len < 12)
 	{
 		printk(
 		  "ICMP: Size (%d) of ICMP_TIMESTAMP request should be 20!\n",
 		  len);
 		icmp_statistics.IcmpInErrors++;		
                 /* correct answers are possible for everything >= 12 */
-	  	if (len < 12)
-			return;
 	}
 
 	size = dev->hard_header_len + 84;
@@ -537,7 +537,7 @@
 	/*
 	 *	Re-adjust length according to actual IP header size. 
 	 */
-	skb2->len = offset + 20;
+	skb_put(skb2,20);
  
 	/*
 	 *	Build ICMP_TIMESTAMP Response message. 
@@ -628,7 +628,7 @@
 	 *	Re-adjust length according to actual IP header size. 
 	 */
 
-	skb2->len = offset + len;
+	skb_put(skb2,len);
 
 	/*
 	 *	Build ICMP ADDRESS MASK Response message. 
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/igmp.c linux/net/ipv4/igmp.c
--- v1.3.5/linux/net/ipv4/igmp.c	Tue Jun  6 12:16:44 1995
+++ linux/net/ipv4/igmp.c	Thu Jun 29 19:18:52 1995
@@ -89,14 +89,14 @@
 	if(skb==NULL)
 		return;
 	tmp=ip_build_header(skb, INADDR_ANY, address, &dev, IPPROTO_IGMP, NULL,
-				skb->mem_len, 0, 1);
+				skb->truesize, 0, 1);
 	if(tmp<0)
 	{
 		kfree_skb(skb, FREE_WRITE);
 		return;
 	}
 	dp=skb->data+tmp;
-	skb->len=tmp+sizeof(struct igmphdr);
+	skb_put(skb,sizeof(struct igmphdr));
 	
 	*dp++=type;
 	*dp++=0;
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/ip.c linux/net/ipv4/ip.c
--- v1.3.5/linux/net/ipv4/ip.c	Fri Jun 16 22:02:56 1995
+++ linux/net/ipv4/ip.c	Fri Jun 30 13:53:31 1995
@@ -185,7 +185,8 @@
 		 *	Build a hardware header. Source address is our mac, destination unknown
 		 *  	(rebuild header will sort this out)
 		 */
-		mac = dev->hard_header(skb->data, dev, ETH_P_IP, NULL, NULL, len, skb);
+		skb_reserve(skb,dev->hard_header_len);
+		mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
 		if (mac < 0)
 		{
 			mac = -mac;
@@ -208,14 +209,11 @@
 		struct device **dev, int type, struct options *opt, int len, int tos, int ttl)
 {
 	struct rtable *rt;
-	unsigned char *buff;
 	unsigned long raddr;
 	int tmp;
 	unsigned long src;
 	struct iphdr *iph;
 
-	buff = skb->data;
-
 	/*
 	 *	See if we need to look up the device.
 	 */
@@ -282,8 +280,6 @@
 	 */
 
 	tmp = ip_send(skb, raddr, len, *dev, saddr);
-	buff += tmp;
-	len -= tmp;
 
 	/*
 	 *	Book keeping
@@ -310,7 +306,7 @@
 	 *	Build the IP addresses
 	 */
 	 
-	iph=(struct iphdr *)buff;
+	iph=(struct iphdr *)skb_put(skb,sizeof(struct iphdr));
 	
 	iph->version  = 4;
 	iph->tos      = tos;
@@ -444,9 +440,6 @@
 		fp = xp;
 	}
 
-	/* Release the MAC header. */
-	kfree_s(qp->mac, qp->maclen);
-
 	/* Release the IP header. */
 	kfree_s(qp->iph, 64 + 8);
 
@@ -494,7 +487,6 @@
 static struct ipq *ip_create(struct sk_buff *skb, struct iphdr *iph, struct device *dev)
 {
 	struct ipq *qp;
-	int maclen;
 	int ihlen;
 
 	qp = (struct ipq *) kmalloc(sizeof(struct ipq), GFP_ATOMIC);
@@ -507,22 +499,6 @@
 	memset(qp, 0, sizeof(struct ipq));
 
 	/*
-	 *	Allocate memory for the MAC header.
-	 *
-	 *	FIXME: We have a maximum MAC address size limit and define
-	 *	elsewhere. We should use it here and avoid the 3 kmalloc() calls
-	 */
-
-	maclen = ((unsigned long) iph) - ((unsigned long) skb->data);
-	qp->mac = (unsigned char *) kmalloc(maclen, GFP_ATOMIC);
-	if (qp->mac == NULL)
-	{
-		NETDEBUG(printk("IP: create: no memory left !\n"));
-		kfree_s(qp, sizeof(struct ipq));
-		return(NULL);
-	}
-
-	/*
 	 *	Allocate memory for the IP header (plus 8 octets for ICMP).
 	 */
 
@@ -531,17 +507,13 @@
 	if (qp->iph == NULL)
 	{
 		NETDEBUG(printk("IP: create: no memory left !\n"));
-		kfree_s(qp->mac, maclen);
 		kfree_s(qp, sizeof(struct ipq));
 		return(NULL);
 	}
 
-	/* Fill in the structure. */
-	memcpy(qp->mac, skb->data, maclen);
 	memcpy(qp->iph, iph, ihlen + 8);
 	qp->len = 0;
 	qp->ihlen = ihlen;
-	qp->maclen = maclen;
 	qp->fragments = NULL;
 	qp->dev = dev;
 
@@ -597,8 +569,7 @@
  *
  *	FIXME: We copy here because we lack an effective way of handling lists
  *	of bits on input. Until the new skb data handling is in I'm not going
- *	to touch this with a bargepole. This also causes a 4Kish limit on
- *	packet sizes.
+ *	to touch this with a bargepole. 
  */
 
 static struct sk_buff *ip_glue(struct ipq *qp)
@@ -612,10 +583,9 @@
 	/*
 	 *	Allocate a new buffer for the datagram.
 	 */
+	len = qp->ihlen + qp->len;
 
-	len = qp->maclen + qp->ihlen + qp->len;
-
-	if ((skb = alloc_skb(len,GFP_ATOMIC)) == NULL)
+	if ((skb = dev_alloc_skb(len)) == NULL)
 	{
 		ip_statistics.IpReasmFails++;
 		NETDEBUG(printk("IP: queue_glue: no memory for gluing queue %p\n", qp));
@@ -624,17 +594,14 @@
 	}
 
 	/* Fill in the basic details. */
-	skb->len = (len - qp->maclen);
+	skb_put(skb,len);
 	skb->h.raw = skb->data;
 	skb->free = 1;
 
-	/* Copy the original MAC and IP headers into the new buffer. */
+	/* Copy the original IP headers into the new buffer. */
 	ptr = (unsigned char *) skb->h.raw;
-	memcpy(ptr, ((unsigned char *) qp->mac), qp->maclen);
-	ptr += qp->maclen;
 	memcpy(ptr, ((unsigned char *) qp->iph), qp->ihlen);
 	ptr += qp->ihlen;
-	skb->h.raw += qp->maclen;
 
 	count = 0;
 
@@ -740,7 +707,7 @@
 	 *	Point into the IP datagram 'data' part.
 	 */
 
-	ptr = skb->data + dev->hard_header_len + ihl;
+	ptr = skb->data + ihl;
 
 	/*
 	 *	Is this the final fragment?
@@ -866,6 +833,7 @@
  *	**Protocol Violation**
  *	We copy all the options to each fragment. !FIXME!
  */
+ 
 void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int is_frag)
 {
 	struct iphdr *iph;
@@ -974,7 +942,7 @@
 		if(skb->free==0)
 			printk("IP fragmenter: BUG free!=1 in fragmenter\n");
 		skb2->free = 1;
-		skb2->len = len + hlen;
+		skb_put(skb2,len + hlen);
 		skb2->h.raw=(char *) skb2->data;
 		/*
 		 *	Charge the memory for the fragment to any owner
@@ -985,7 +953,7 @@
 		if (sk)
 		{
 			cli();
-			sk->wmem_alloc += skb2->mem_len;
+			sk->wmem_alloc += skb2->truesize;
 			skb2->sk=sk;
 		}
 		restore_flags(flags);
@@ -1193,27 +1161,31 @@
 		 */
 
 		skb2 = alloc_skb(dev2->hard_header_len + skb->len, GFP_ATOMIC);
+		
 		/*
 		 *	This is rare and since IP is tolerant of network failures
 		 *	quite harmless.
 		 */
+		
 		if (skb2 == NULL)
 		{
 			NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
 			return;
 		}
-		ptr = skb2->data;
+		
+
+		/* Now build the MAC header. */
+		(void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);
+
+		ptr = skb_put(skb2,skb->len);
 		skb2->free = 1;
-		skb2->len = skb->len + dev2->hard_header_len;
 		skb2->h.raw = ptr;
 
 		/*
 		 *	Copy the packet data into the new buffer.
 		 */
-		memcpy(ptr + dev2->hard_header_len, skb->h.raw, skb->len);
+		memcpy(ptr, skb->h.raw, skb->len);
 
-		/* Now build the MAC header. */
-		(void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);
 
 		ip_statistics.IpForwDatagrams++;
 
@@ -1258,6 +1230,9 @@
 
 /*
  *	This function receives all incoming IP datagrams.
+ *
+ *	On entry skb->data points to the start of the IP header and
+ *	the MAC header has been removed.
  */
 
 int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
@@ -1275,6 +1250,13 @@
 	int err;
 #endif	
 
+	/*
+	 *	IP is layered, throw away the
+	 *	MAC addresses.
+	 */
+	 
+	skb_pull(skb,dev->hard_header_len);
+	
 	ip_statistics.IpInReceives++;
 
 	/*
@@ -1309,7 +1291,7 @@
 	 *	is IP we can trim to the true length of the frame.
 	 */
 
-	skb->len=ntohs(iph->tot_len);
+	skb_trim(skb,ntohs(iph->tot_len));
 	
 	/*
 	 *	See if the firewall wants to dispose of the packet. 
@@ -1683,7 +1665,7 @@
 	extern struct device loopback_dev;
 	struct device *dev=&loopback_dev;
 	int len=skb->len-old_dev->hard_header_len;
-	struct sk_buff *newskb=alloc_skb(len+dev->hard_header_len, GFP_ATOMIC);
+	struct sk_buff *newskb=dev_alloc_skb(len+dev->hard_header_len);
 	
 	if(newskb==NULL)
 		return;
@@ -1698,10 +1680,18 @@
 	newskb->lock=0;
 	newskb->users=0;
 	newskb->pkt_type=skb->pkt_type;
-	newskb->len=len+dev->hard_header_len;
-	
 	
-	newskb->ip_hdr=(struct iphdr *)(newskb->data+ip_send(newskb, skb->ip_hdr->daddr, len, dev, skb->ip_hdr->saddr));
+	/*
+	 *	Put a MAC header on the packet
+	 */
+	ip_send(newskb, skb->ip_hdr->daddr, len, dev, skb->ip_hdr->saddr);
+	/*
+	 *	Add the rest of the data space.	
+	 */
+	newskb->ip_hdr=(struct iphdr *)skb_put(skb, len);
+	/*
+	 *	Copy the data
+	 */
 	memcpy(newskb->ip_hdr,skb->ip_hdr,len);
 
 	/* Recurse. The device check against IFF_LOOPBACK will stop infinite recursion */
@@ -2504,7 +2494,8 @@
 		skb->arp = 0;
 		skb->saddr = saddr;
 		skb->raddr = (rt&&rt->rt_gateway) ? rt->rt_gateway : daddr;
-		skb->len = fraglen;
+		skb_reserve(skb,dev->hard_header_len);
+		data = skb_put(skb, fraglen-dev->hard_header_len);
 
 		/*
 		 *	Save us ARP and stuff. In the optimal case we do no route lookup (route cache ok)
@@ -2520,8 +2511,8 @@
 		}
 		else if (dev->hard_header)
 		{
-			if(dev->hard_header(skb->data, dev, ETH_P_IP, 
-						NULL, NULL, 0,  NULL)>0)
+			if(dev->hard_header(skb, dev, ETH_P_IP, 
+						NULL, NULL, 0)>0)
 				skb->arp=1;
 		}
 		
@@ -2529,7 +2520,6 @@
 		 *	Find where to start putting bytes.
 		 */
 		 
-		data = (char *)skb->data + dev->hard_header_len;
 		iph = (struct iphdr *)data;
 
 		/*
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- v1.3.5/linux/net/ipv4/ip_fw.c	Sun Jun 11 19:46:25 1995
+++ linux/net/ipv4/ip_fw.c	Thu Jun 29 19:18:52 1995
@@ -612,13 +612,13 @@
  		if (!ftp->init_seq)
  			ftp->init_seq = th->seq;
  
-		skb2 = alloc_skb(skb->mem_len-sizeof(struct sk_buff)+ftp->delta, GFP_ATOMIC);
+		skb2 = alloc_skb(skb->len+ftp->delta, GFP_ATOMIC);
  		if (skb2 == NULL) {
  			printk("MASQUERADE: No memory available\n");
  			return skb;
  		}
  		skb2->free = skb->free;
- 		skb2->len = skb->len + ftp->delta;
+ 		skb_put(skb2,skb->len + ftp->delta);
  		skb2->h.raw = &skb2->data[skb->h.raw - skb->data];
  
  		/*
@@ -628,7 +628,7 @@
  		memcpy(skb2->data, skb->data, (p - (char *)skb->data));
  		memcpy(&skb2->data[(p - (char *)skb->data)], buf, strlen(buf));
 		memcpy(&skb2->data[(p - (char *)skb->data) + strlen(buf)], data,
-			skb->mem_len - sizeof(struct sk_buff) - ((char *)skb->h.raw - data));
+			skb->len - ((char *)skb->h.raw - data));
 
 		/*
 		 * Problem, how to replace the new skb with old one,
@@ -648,7 +648,7 @@
 	uh->check=csum_tcpudp_magic(saddr,daddr,len,
 		IPPROTO_UDP, csum_partial((char *)uh,len,0));
 	if(uh->check==0)
-		uh->check=-0xFFFF;
+		uh->check=0xFFFF;
 }
 	
 void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/packet.c linux/net/ipv4/packet.c
--- v1.3.5/linux/net/ipv4/packet.c	Tue Jun  6 12:16:44 1995
+++ linux/net/ipv4/packet.c	Thu Jun 29 19:18:52 1995
@@ -82,13 +82,10 @@
 	sk = (struct sock *) pt->data;	
 
 	/*
-	 *	The SOCK_PACKET socket receives _all_ frames, and as such 
-	 *	therefore needs to put the header back onto the buffer.
-	 *	(it was removed by inet_bh()).
+	 *	The SOCK_PACKET socket receives _all_ frames.
 	 */
 	 
 	skb->dev = dev;
-	skb->len += dev->hard_header_len;
 
 	/*
 	 *	Charge the memory to the socket. This is done specifically
@@ -100,9 +97,9 @@
 		sk->rmem_alloc = 0;
 	}
 
-	if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) 
+	if (sk->rmem_alloc + skb->truesize >= sk->rcvbuf) 
 	{
-/*	        printk("packet_rcv: drop, %d+%d>%d\n", sk->rmem_alloc, skb->mem_len, sk->rcvbuf); */
+/*	        printk("packet_rcv: drop, %d+%d>%d\n", sk->rmem_alloc, skb->truesize, sk->rcvbuf); */
 		skb->sk = NULL;
 		kfree_skb(skb, FREE_READ);
 		return(0);
@@ -112,7 +109,7 @@
 	cli();
 
 	skb->sk = sk;
-	sk->rmem_alloc += skb->mem_len;	
+	sk->rmem_alloc += skb->truesize;	
 
 	/*
 	 *	Queue the packet up, and wake anyone waiting for it.
@@ -201,8 +198,7 @@
 	 
 	skb->sk = sk;
 	skb->free = 1;
-	memcpy_fromfs(skb->data, from, len);
-	skb->len = len;
+	memcpy_fromfs(skb_put(skb,len), from, len);
 	skb->arp = 1;		/* No ARP needs doing on this (complete) frame */
 
 	/*
@@ -289,7 +285,6 @@
 	struct sk_buff *skb;
 	struct sockaddr *saddr;
 	int err;
-	int truesize;
 
 	saddr = (struct sockaddr *)sin;
 
@@ -326,8 +321,7 @@
 	 *	user program they can ask the device for its MTU anyway.
 	 */
 	 
-	truesize = skb->len;
-	copied = min(len, truesize);
+	copied = min(len, skb->len);
 
 	memcpy_tofs(to, skb->data, copied);	/* We can't use skb_copy_datagram here */
 	sk->stamp=skb->stamp;
@@ -354,7 +348,7 @@
 	 */
 	 
 	release_sock(sk);
-	return(truesize);
+	return(copied);
 }
 
 
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/rarp.c linux/net/ipv4/rarp.c
--- v1.3.5/linux/net/ipv4/rarp.c	Tue Jun  6 12:16:44 1995
+++ linux/net/ipv4/rarp.c	Thu Jun 29 19:18:52 1995
@@ -150,6 +150,8 @@
 	struct rarp_table *entry;
 	long sip,tip;
 	unsigned char *sha,*tha;            /* s for "source", t for "target" */
+	
+	skb_pull(skb,dev->hard_header_len);
   
 /*
  *	If this test doesn't pass, it's not IP, or we should ignore it anyway
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- v1.3.5/linux/net/ipv4/raw.c	Tue Jun 27 14:11:48 1995
+++ linux/net/ipv4/raw.c	Thu Jun 29 19:18:52 1995
@@ -98,7 +98,7 @@
 {
 	/* Now we need to copy this into memory. */
 	skb->sk = sk;
-	skb->len = ntohs(skb->ip_hdr->tot_len);
+	skb_trim(skb,ntohs(skb->ip_hdr->tot_len));
 	skb->h.raw = (unsigned char *) skb->ip_hdr;
 	skb->dev = dev;
 	skb->saddr = daddr;
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v1.3.5/linux/net/ipv4/route.c	Tue Jun  6 12:16:44 1995
+++ linux/net/ipv4/route.c	Thu Jun 29 19:18:52 1995
@@ -28,6 +28,7 @@
  *		Alan Cox	:	Removed compatibility cruft.
  *		Alan Cox	:	RTF_REJECT support.
  *		Alan Cox	:	TCP irtt support.
+ *		Jonathan Naylor	:	Added Metric support.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -209,7 +210,7 @@
  */
  
 void ip_rt_add(short flags, unsigned long dst, unsigned long mask,
-	unsigned long gw, struct device *dev, unsigned short mtu, unsigned long window, unsigned short irtt)
+	unsigned long gw, struct device *dev, unsigned short mtu, unsigned long window, unsigned short irtt, unsigned char metric)
 {
 	struct rtable *r, *rt;
 	struct rtable **rp;
@@ -282,6 +283,7 @@
 	rt->rt_gateway = gw;
 	rt->rt_mask = mask;
 	rt->rt_mss = dev->mtu - HEADER_SIZE;
+	rt->rt_metric = metric;
 	rt->rt_window = 0;	/* Default is no clamping */
 
 	/* Are the MSS/Window valid ? */
@@ -312,7 +314,8 @@
 	while ((r = *rp) != NULL) 
 	{
 		if (r->rt_dst != dst || 
-		    r->rt_mask != mask) 
+		    r->rt_mask != mask ||
+		    r->rt_metric < metric)
 		{
 			rp = &r->rt_next;
 			continue;
@@ -472,7 +475,7 @@
 	 *	Add the route
 	 */
 	 
-	ip_rt_add(flags, daddr, mask, gw, dev, r->rt_mss, r->rt_window, r->rt_irtt);
+	ip_rt_add(flags, daddr, mask, gw, dev, r->rt_mss, r->rt_window, r->rt_irtt, r->rt_metric);
 	return 0;
 }
 
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v1.3.5/linux/net/ipv4/tcp.c	Tue Jun 27 14:11:48 1995
+++ linux/net/ipv4/tcp.c	Thu Jun 29 19:18:53 1995
@@ -140,6 +140,11 @@
  *		Alan Cox	:	Cache last socket.
  *		Alan Cox	:	Per route irtt.
  *		Matt Day	:	Select() match BSD precisely on error
+ *		Alan Cox	:	New buffers
+ *		Mark Tamsky	:	Various sk->prot->retransmits and 
+ *					sk->retransmits misupdating fixed.
+ *					Fixed tcp_write_timeout: stuck close,
+ *					and TCP syn retries gets used now.
  *
  *
  * To Fix:
@@ -517,6 +522,8 @@
 		 
 		ct++;
 		sk->prot->retransmits ++;
+		tcp_statistics.TcpRetransSegs++;
+		
 
 		/*
 		 *	Only one retransmit requested.
@@ -582,6 +589,7 @@
 	 */
 
 	sk->retransmits++;
+	sk->prot->retransmits++;
 	sk->backoff++;
 	sk->rto = min(sk->rto << 1, 120*HZ);
 	reset_xmit_timer(sk, TIME_WRITE, sk->rto);
@@ -632,6 +640,22 @@
 		arp_destroy (sk->daddr, 0);
 		/*ip_route_check (sk->daddr);*/
 	}
+	
+	/*
+	 *	Have we tried to SYN too many times (repent repent 8))
+	 */
+	 
+	if(sk->retransmits > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT)
+	{
+		sk->err=ETIMEDOUT;
+		sk->error_report(sk);
+		del_timer(&sk->retransmit_timer);
+		tcp_statistics.TcpAttemptFails++;	/* Is this right ??? - FIXME - */
+		tcp_set_state(sk,TCP_CLOSE);
+		/* Don't FIN, we got nothing back */
+		release_sock(sk);
+		return 0;
+	}
 	/*
 	 *	Has it gone just too far ?
 	 */
@@ -654,6 +678,7 @@
 			 *	Clean up time.
 			 */
 			tcp_set_state(sk, TCP_CLOSE);
+			release_sock(sk);
 			return 0;
 		}
 	}
@@ -759,6 +784,7 @@
 			if (sk->prot->write_wakeup)
 				  sk->prot->write_wakeup (sk);
 			sk->retransmits++;
+			sk->prot->retransmits++;
 			tcp_write_timeout(sk);
 			break;
 		default:
@@ -1291,10 +1317,8 @@
 	 *	Assemble a suitable TCP frame
 	 */
 	 
-	buff->len = sizeof(struct tcphdr);
 	buff->sk = sk;
 	buff->localroute = sk->localroute;
-	t1 =(struct tcphdr *) buff->data;
 
 	/* 
 	 *	Put in the IP header and routing stuff. 
@@ -1305,11 +1329,10 @@
 	if (tmp < 0) 
 	{
   		buff->free = 1;
-		sk->prot->wfree(sk, buff->mem_addr, buff->mem_len);
+		sk->prot->wfree(sk, buff);
 		return;
 	}
-	buff->len += tmp;
-	t1 =(struct tcphdr *)((char *)t1 +tmp);
+	t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
 
 	memcpy(t1, th, sizeof(*t1));
 
@@ -1403,7 +1426,6 @@
 	int tmp;
 	struct sk_buff *skb;
 	struct sk_buff *send_tmp;
-	unsigned char *buff;
 	struct proto *prot;
 	struct device *dev = NULL;
 
@@ -1533,8 +1555,7 @@
 			  		copy = 0;
 				}
 	  
-				memcpy_fromfs(skb->data + skb->len, from, copy);
-				skb->len += copy;
+				memcpy_fromfs(skb_put(skb,copy), from, copy);
 				from += copy;
 				copied += copy;
 				len -= copy;
@@ -1639,36 +1660,31 @@
 			continue;
 		}
 
-		skb->len = 0;
 		skb->sk = sk;
 		skb->free = 0;
 		skb->localroute = sk->localroute|(flags&MSG_DONTROUTE);
 	
-		buff = skb->data;
-	
 		/*
 		 * FIXME: we need to optimize this.
 		 * Perhaps some hints here would be good.
 		 */
 		
 		tmp = prot->build_header(skb, sk->saddr, sk->daddr, &dev,
-				 IPPROTO_TCP, sk->opt, skb->mem_len,sk->ip_tos,sk->ip_ttl);
+				 IPPROTO_TCP, sk->opt, skb->truesize,sk->ip_tos,sk->ip_ttl);
 		if (tmp < 0 ) 
 		{
-			prot->wfree(sk, skb->mem_addr, skb->mem_len);
+			prot->wfree(sk, skb);
 			release_sock(sk);
 			if (copied) 
 				return(copied);
 			return(tmp);
 		}
-		skb->len += tmp;
 		skb->dev = dev;
-		buff += tmp;
-		skb->h.th =(struct tcphdr *) buff;
-		tmp = tcp_build_header((struct tcphdr *)buff, sk, len-copy);
+		skb->h.th =(struct tcphdr *)skb_put(skb,sizeof(struct tcphdr));
+		tmp = tcp_build_header(skb->h.th, sk, len-copy);
 		if (tmp < 0) 
 		{
-			prot->wfree(sk, skb->mem_addr, skb->mem_len);
+			prot->wfree(sk, skb);
 			release_sock(sk);
 			if (copied) 
 				return(copied);
@@ -1677,16 +1693,15 @@
 
 		if (flags & MSG_OOB) 
 		{
-			((struct tcphdr *)buff)->urg = 1;
-			((struct tcphdr *)buff)->urg_ptr = ntohs(copy);
+			skb->h.th->urg = 1;
+			skb->h.th->urg_ptr = ntohs(copy);
 		}
-		skb->len += tmp;
-		memcpy_fromfs(buff+tmp, from, copy);
 
+		memcpy_fromfs(skb_put(skb,copy), from, copy);
+		
 		from += copy;
 		copied += copy;
 		len -= copy;
-		skb->len += copy;
 		skb->free = 0;
 		sk->write_seq += copy;
 	
@@ -1778,7 +1793,6 @@
 		return;
  	}
 
-	buff->len = sizeof(struct tcphdr);
 	buff->sk = sk;
 	buff->localroute = sk->localroute;
 	
@@ -1791,12 +1805,11 @@
 	if (tmp < 0) 
 	{
   		buff->free = 1;
-		sk->prot->wfree(sk, buff->mem_addr, buff->mem_len);
+		sk->prot->wfree(sk, buff);
 		return;
 	}
 
-	buff->len += tmp;
-	t1 =(struct tcphdr *)(buff->data +tmp);
+	t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
 
 	memcpy(t1,(void *) &sk->dummy_th, sizeof(*t1));
 	t1->seq = htonl(sk->sent_seq);
@@ -2285,9 +2298,7 @@
 	 */
 	 
 	buff->sk = sk;
-	buff->len = sizeof(*t1);
 	buff->localroute = sk->localroute;
-	t1 =(struct tcphdr *) buff->data;
 
 	/*
 	 *	Put in the IP header and routing stuff. 
@@ -2305,7 +2316,7 @@
   		 */
   		 
 	  	buff->free = 1;
-		prot->wfree(sk,buff->mem_addr, buff->mem_len);
+		prot->wfree(sk,buff);
 		sk->write_seq++;
 		t=del_timer(&sk->timer);
 		if(t)
@@ -2320,8 +2331,7 @@
 	 *	if so simply add the fin to that buffer, not send it ahead.
 	 */
 
-	t1 =(struct tcphdr *)((char *)t1 +tmp);
-	buff->len += tmp;
+	t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
 	buff->dev = dev;
 	memcpy(t1, th, sizeof(*t1));
 	t1->seq = ntohl(sk->write_seq);
@@ -2473,13 +2483,10 @@
 	if (buff == NULL) 
 	  	return;
 
-	buff->len = sizeof(*t1);
 	buff->sk = NULL;
 	buff->dev = dev;
 	buff->localroute = 0;
 
-	t1 =(struct tcphdr *) buff->data;
-
 	/*
 	 *	Put in the IP header and routing stuff. 
 	 */
@@ -2489,12 +2496,11 @@
 	if (tmp < 0) 
 	{
   		buff->free = 1;
-		prot->wfree(NULL, buff->mem_addr, buff->mem_len);
+		prot->wfree(NULL, buff);
 		return;
 	}
 
-	t1 =(struct tcphdr *)((char *)t1 +tmp);
-	buff->len += tmp;
+	t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
 	memcpy(t1, th, sizeof(*t1));
 
 	/*
@@ -2825,12 +2831,9 @@
 		return;
 	}
   
-	buff->len = sizeof(struct tcphdr)+4;
 	buff->sk = newsk;
 	buff->localroute = newsk->localroute;
 
-	t1 =(struct tcphdr *) buff->data;
-
 	/*
 	 *	Put in the IP header and routing stuff. 
 	 */
@@ -2856,8 +2859,7 @@
 		return;
 	}
 
-	buff->len += tmp;
-	t1 =(struct tcphdr *)((char *)t1 +tmp);
+	t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
   
 	memcpy(t1, skb->h.th, sizeof(*t1));
 	buff->h.seq = newsk->write_seq;
@@ -2879,7 +2881,7 @@
 	t1->syn = 1;
 	t1->ack_seq = ntohl(skb->h.th->seq+1);
 	t1->doff = sizeof(*t1)/4+1;
-	ptr =(unsigned char *)(t1+1);
+	ptr = skb_put(buff,4);
 	ptr[0] = 2;
 	ptr[1] = 4;
 	ptr[2] = ((newsk->mtu) >> 8) & 0xff;
@@ -2894,8 +2896,8 @@
 	 *	Charge the sock_buff to newsk. 
 	 */
 	 
-	sk->rmem_alloc -= skb->mem_len;
-	newsk->rmem_alloc += skb->mem_len;
+	sk->rmem_alloc -= skb->truesize;
+	newsk->rmem_alloc += skb->truesize;
 	
 	skb_queue_tail(&sk->receive_queue,skb);
 	sk->ack_backlog++;
@@ -3766,7 +3768,8 @@
 	u32 new_seq, shut_seq;
 
 	th = skb->h.th;
-	skb->len = len -(th->doff*4);
+	skb_pull(skb,th->doff*4);
+	skb_trim(skb,len-(th->doff*4));
 
 	/*
 	 *	The bytes in the receive read/assembly queue has increased. Needed for the
@@ -4265,12 +4268,10 @@
 		return(-ENOMEM);
 	}
 	sk->inuse = 1;
-	buff->len = 24;
 	buff->sk = sk;
 	buff->free = 0;
 	buff->localroute = sk->localroute;
 	
-	t1 = (struct tcphdr *) buff->data;
 
 	/*
 	 *	Put in the IP header and routing stuff. 
@@ -4287,13 +4288,12 @@
 					IPPROTO_TCP, NULL, MAX_SYN_SIZE,sk->ip_tos,sk->ip_ttl);
 	if (tmp < 0) 
 	{
-		sk->prot->wfree(sk, buff->mem_addr, buff->mem_len);
+		sk->prot->wfree(sk, buff);
 		release_sock(sk);
 		return(-ENETUNREACH);
 	}
 
-	buff->len += tmp;
-	t1 = (struct tcphdr *)((char *)t1 +tmp);
+	t1 = (struct tcphdr *) skb_put(buff,sizeof(struct tcphdr));
 
 	memcpy(t1,(void *)&(sk->dummy_th), sizeof(*t1));
 	t1->seq = ntohl(sk->write_seq++);
@@ -4344,7 +4344,7 @@
 	 *	Put in the TCP options to say MTU. 
 	 */
 
-	ptr = (unsigned char *)(t1+1);
+	ptr = skb_put(buff,4);
 	ptr[0] = 2;
 	ptr[1] = 4;
 	ptr[2] = (sk->mtu) >> 8;
@@ -4365,7 +4365,7 @@
 	sk->retransmit_timer.function=&retransmit_timer;
 	sk->retransmit_timer.data = (unsigned long)sk;
 	reset_xmit_timer(sk, TIME_WRITE, sk->rto);	/* Timer for repeating the SYN until an answer */
-	sk->retransmits = TCP_SYN_RETRIES;
+	sk->retransmits = 0;	/* Now works the right way instead of a hacked initial setting */
 
 	sk->prot->queue_xmit(sk, dev, buff, 0);  
 	reset_xmit_timer(sk, TIME_WRITE, sk->rto);
@@ -4464,6 +4464,7 @@
 
 /*
  *	A TCP packet has arrived.
+ *		skb->h.raw is the TCP header.
  */
  
 int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
@@ -4514,6 +4515,10 @@
 
 	if (!redo) 
 	{
+		/*
+		 *	Pull up the IP header.
+		 */
+		skb_pull(skb, skb->h.raw-skb->data);
 		if (tcp_check(th, len, saddr, daddr )) 
 		{
 			skb->sk = NULL;
@@ -4541,7 +4546,7 @@
 			return(0);
 		}
 
-		skb->len = len;
+/*		skb->len = len;*/
 		skb->acked = 0;
 		skb->used = 0;
 		skb->free = 0;
@@ -4582,7 +4587,7 @@
 	 *	Charge the memory to the socket. 
 	 */
 	 
-	if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) 
+	if (sk->rmem_alloc + skb->truesize >= sk->rcvbuf) 
 	{
 		kfree_skb(skb, FREE_READ);
 		release_sock(sk);
@@ -4590,7 +4595,7 @@
 	}
 
 	skb->sk=sk;
-	sk->rmem_alloc += skb->mem_len;
+	sk->rmem_alloc += skb->truesize;
 
 	/*
 	 *	This basically follows the flow suggested by RFC793, with the corrections in RFC1122. We
@@ -4754,7 +4759,7 @@
 			if(sk->debug)
 				printk("Doing a BSD time wait\n");
 			tcp_statistics.TcpEstabResets++;	   
-			sk->rmem_alloc -= skb->mem_len;
+			sk->rmem_alloc -= skb->truesize;
 			skb->sk = NULL;
 			sk->err=ECONNRESET;
 			tcp_set_state(sk, TCP_CLOSE);
@@ -4765,7 +4770,7 @@
 			{
 				sk->inuse=1;
 				skb->sk = sk;
-				sk->rmem_alloc += skb->mem_len;
+				sk->rmem_alloc += skb->truesize;
 				tcp_conn_request(sk, skb, daddr, saddr,opt, dev,seq+128000);
 				release_sock(sk);
 				return 0;
@@ -4885,8 +4890,7 @@
 	{
 		return;
 	}
-
-	if (before(sk->sent_seq, sk->window_seq) && 
+	if ( before(sk->sent_seq, sk->window_seq) && 
 	    (skb=skb_peek(&sk->write_queue)))
 	{
 		/*
@@ -4901,11 +4905,23 @@
 	    	unsigned long win_size, ow_size;
 	    	void * tcp_data_start;
 	
+		/*
+		 *	How many bytes can we send ?
+		 */
+		 
 		win_size = sk->window_seq - sk->sent_seq;
 
+		/*
+		 *	Recover the buffer pointers
+		 */
+		 
 	    	iph = (struct iphdr *)(skb->data + skb->dev->hard_header_len);
 	    	th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2));
 
+		/*
+		 *	Grab the data for a temporary frame
+		 */
+		 
 	    	buff = sk->prot->wmalloc(sk, win_size + th->doff * 4 + 
 				     (iph->ihl << 2) +
 				     skb->dev->hard_header_len, 
@@ -4913,46 +4929,67 @@
 	    	if ( buff == NULL )
 	    		return;
 
-	    	buff->len = 0;
-
 	 	/* 
 	 	 *	If we strip the packet on the write queue we must
 	 	 *	be ready to retransmit this one 
 	 	 */
 	    
-	    	buff->free = 0;
+	    	buff->free = /*0*/1;
 
 	    	buff->sk = sk;
 	    	buff->localroute = sk->localroute;
+	    	
+	    	/*
+	    	 *	Put headers on the new packet
+	    	 */
 
 	    	tmp = sk->prot->build_header(buff, sk->saddr, sk->daddr, &dev,
-					 IPPROTO_TCP, sk->opt, buff->mem_len,
+					 IPPROTO_TCP, sk->opt, buff->truesize,
 					 sk->ip_tos,sk->ip_ttl);
 	    	if (tmp < 0) 
 	    	{
-			sk->prot->wfree(sk, buff->mem_addr, buff->mem_len);
+			sk->prot->wfree(sk, buff);
 			return;
 		}
+		
+		/*
+		 *	Move the TCP header over
+		 */
 
-		buff->len += tmp;
 		buff->dev = dev;
 
-		nth = (struct tcphdr *) (buff->data + buff->len);
-		buff->len += th->doff * 4;
+		nth = (struct tcphdr *) skb_put(buff,th->doff*4);
 
 		memcpy(nth, th, th->doff * 4);
-
+		
+		/*
+		 *	Correct the new header
+		 */
+		 
 		nth->ack = 1; 
 		nth->ack_seq = ntohl(sk->acked_seq);
 		nth->window = ntohs(tcp_select_window(sk));
 		nth->check = 0;
 
+		/*
+		 *	Find the first data byte.
+		 */
+		 
 		tcp_data_start = skb->data + skb->dev->hard_header_len + 
 				(iph->ihl << 2) + th->doff * 4;
 
-		memcpy(buff->data + buff->len, tcp_data_start, win_size);
-		buff->len += win_size;
+		/*
+		 *	Add it to our new buffer
+		 */
+		memcpy(skb_put(buff,win_size), tcp_data_start, win_size);
+		
+		/*
+		 *	Remember our right edge sequence number.
+		 */
+		 
 	    	buff->h.seq = sk->sent_seq + win_size;
+	    	sk->sent_seq = buff->h.seq;		/* Hack */
+#if 0
 
 	    	/*
 	    	 *	now: shrink the queue head segment 
@@ -4963,10 +5000,9 @@
 	    		((unsigned long) (tcp_data_start - (void *) skb->data));
 
 		memmove(tcp_data_start, tcp_data_start + win_size, ow_size);
-	    	skb->len -= win_size;
+	    	skb_trim(skb,skb->len-win_size);
 	    	sk->sent_seq += win_size;
 	    	th->seq = htonl(sk->sent_seq);
-
 	    	if (th->urg)
 	    	{
 			unsigned short urg_ptr;
@@ -4981,23 +5017,28 @@
 		    		nth->urg_ptr = htons(win_size);
 		  	}
 	      	}
+#else
+		if(th->urg && ntohs(th->urg_ptr) < win_size)
+			nth->urg = 0;
+#endif	      	
 
+		/*
+		 *	Checksum the split buffer
+		 */
+		 
 	    	tcp_send_check(nth, sk->saddr, sk->daddr, 
 			   nth->doff * 4 + win_size , sk);
 	}
 	else
-	{
+	{	
 		buff = sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
 		if (buff == NULL) 
 			return;
 
-		buff->len = sizeof(struct tcphdr);
 		buff->free = 1;
 		buff->sk = sk;
 		buff->localroute = sk->localroute;
 
-		t1 = (struct tcphdr *) buff->data;
-
 		/*
 		 *	Put in the IP header and routing stuff. 
 		 */
@@ -5006,13 +5047,11 @@
 				IPPROTO_TCP, sk->opt, MAX_ACK_SIZE,sk->ip_tos,sk->ip_ttl);
 		if (tmp < 0) 
 		{
-			sk->prot->wfree(sk, buff->mem_addr, buff->mem_len);
+			sk->prot->wfree(sk, buff);
 			return;
 		}
 
-		buff->len += tmp;
-		t1 = (struct tcphdr *)((char *)t1 +tmp);
-
+		t1 = (struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
 		memcpy(t1,(void *) &sk->dummy_th, sizeof(*t1));
 
 		/*
diff -u --recursive --new-file v1.3.5/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- v1.3.5/linux/net/ipv4/udp.c	Tue Jun 27 14:11:48 1995
+++ linux/net/ipv4/udp.c	Thu Jun 29 19:18:53 1995
@@ -428,7 +428,7 @@
 	if(skb==NULL)
   		return er;
   
-  	truesize = skb->len;
+  	truesize = skb->len - sizeof(struct udphdr);
   	copied = min(len, truesize);
 
   	/*
@@ -448,7 +448,7 @@
   
   	skb_free_datagram(skb);
   	release_sock(sk);
-  	return(truesize);
+  	return(copied);
 }
 
 /*
@@ -623,7 +623,7 @@
 {
 	skb->sk = sk;
 	skb->dev = dev;
-	skb->len = len;
+	skb_trim(skb,len);
 
 	/*
 	 *	These are supposed to be switched. 
@@ -637,8 +637,6 @@
 	 *	Charge it to the socket, dropping if the queue is full.
 	 */
 
-	skb->len = len - sizeof(*uh);  
-	 
 	if (sock_queue_rcv_skb(sk,skb)<0) 
 	{
 		udp_statistics.UdpInErrors++;
diff -u --recursive --new-file v1.3.5/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v1.3.5/linux/net/ipx/af_ipx.c	Tue Jun  6 12:16:45 1995
+++ linux/net/ipx/af_ipx.c	Thu Jun 29 19:18:53 1995
@@ -33,9 +33,10 @@
  *			Asynchronous I/O support.
  *			Changed to use notifiers and the newer packet_type stuff.
  *			Assorted major fixes <Alejandro Liu>
- *	Revision 0.30:	Moved to net/ipx/...
+ *	Revision 0.30:	Moved to net/ipx/...	<Alan Cox>
  *			Don't set address length on recvfrom that errors.
  *			Incorrect verify_area.
+ *	Revision 0.31:	New sk_buffs. This still needs a lot of testing. <Alan Cox>
  *
  *	TODO:	use sock_alloc_send_skb to allocate sending buffers. Check with Caldera first
  *
@@ -344,7 +345,6 @@
 	ipx_packet	*ipx = (ipx_packet *)(skb->h.raw);
 	ipx_socket	*sock1 = NULL, *sock2 = NULL;
 	struct sk_buff	*skb1 = NULL, *skb2 = NULL;
-	int		ipx_offset;
 
 	sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
 
@@ -381,8 +381,6 @@
 		return 0;
 	}
 
-	ipx_offset = (char *)(skb->h.raw) - (char *)(skb->data);
-
 	/* This next segment of code is a little awkward, but it sets it up
 	 * so that the appropriate number of copies of the SKB are made and 
 	 * that skb1 and skb2 point to it (them) so that it (they) can be 
@@ -392,7 +390,6 @@
 	if (copy) {
 		skb1 = skb_clone(skb, GFP_ATOMIC);
 		if (skb1 != NULL) {
-			skb1->h.raw = (unsigned char *)&(skb1->data[ipx_offset]);
 			skb1->arp = skb1->free = 1;
 		}
 	} else {
@@ -405,7 +402,6 @@
 	if (sock1 && sock2) {
 		skb2 = skb_clone(skb1, GFP_ATOMIC);
 		if (skb2 != NULL) {
-			skb2->h.raw = (unsigned char *)&(skb2->data[ipx_offset]);
 			skb2->arp = skb2->free = 1;
 		}
 	} else {
@@ -431,16 +427,19 @@
 	struct sk_buff	*skb2;
 	int	in_offset = skb->h.raw - skb->data;
 	int	out_offset = intrfc->if_ipx_offset;
+#if 0
 	char	*oldraw;
+#endif	
 	int	len;
 
 	/* Hopefully, most cases */
-	if (in_offset == out_offset) {
-		skb->len += out_offset;
+	if (in_offset >= out_offset) {
+/*		skb_push(skb,out_offset);*/
 		skb->arp = skb->free = 1;
 		return skb;
 	}
 
+#if 0
 	/* Existing SKB will work, just need to move things around a little */
 	if (in_offset > out_offset) {
 		oldraw = skb->h.raw;
@@ -450,13 +449,14 @@
 		skb->arp = skb->free = 1;
 		return skb;
 	}
+#endif	
 
 	/* Need new SKB */
 	len = skb->len + out_offset;
 	skb2 = alloc_skb(len, GFP_ATOMIC);
 	if (skb2 != NULL) {
-		skb2->h.raw = &(skb2->data[out_offset]);
-		skb2->len = len;
+		skb_reserve(skb2,out_offset);
+		skb2->h.raw=skb_put(skb2,skb->len);
 		skb2->free=1;
 		skb2->arp=1;
 		memcpy(skb2->h.raw, skb->h.raw, skb->len);
@@ -530,7 +530,7 @@
 		/* This is an outbound packet from this host.  We need to 
 		 * increment the write count.
 		 */
-		skb->sk->wmem_alloc += skb->mem_len;
+		skb->sk->wmem_alloc += skb->truesize;
 	}
 
 	/* Send it out */
@@ -1011,12 +1011,12 @@
 	if(skb==NULL) return -ENOMEM;
 		
 	skb->sk=sk;
-	skb->len=size;
+	skb_reserve(skb,ipx_offset);
 	skb->free=1;
 	skb->arp=1;
 
 	/* Fill in IPX header */
-	ipx=(ipx_packet *)&(skb->data[ipx_offset]);
+	ipx=(ipx_packet *)skb_put(skb,sizeof(ipx_packet));
 	ipx->ipx_checksum=0xFFFF;
 	ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
 	ipx->ipx_tctrl=0;
@@ -1030,7 +1030,7 @@
 	memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN);
 	ipx->ipx_dest.sock=usipx->sipx_port;
 
-	memcpy_fromfs((char *)(ipx+1),ubuf,len);
+	memcpy_fromfs(skb_put(skb,len),ubuf,len);
 	return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? 
 				rt->ir_router_node : ipx->ipx_dest.node);
 }
@@ -1634,6 +1634,13 @@
 	ipx_interface	*intrfc;
 	ipx_packet *ipx;
 	
+	
+	/*
+	 *	Throw away the MAC layer
+	 */
+	 
+	skb_pull(skb,dev->hard_header_len);
+	
 	ipx=(ipx_packet *)skb->h.raw;
 	
 	if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) {
@@ -1947,7 +1954,7 @@
 	
 	register_netdevice_notifier(&ipx_dev_notifier);
 		
-	printk("Swansea University Computer Society IPX 0.30 for NET3.029\n");
+	printk("Swansea University Computer Society IPX 0.31 for NET3.030\n");
 	printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
 }
 #endif
diff -u --recursive --new-file v1.3.5/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- v1.3.5/linux/net/netrom/af_netrom.c	Tue Jun  6 12:16:45 1995
+++ linux/net/netrom/af_netrom.c	Thu Jun 29 19:18:53 1995
@@ -17,10 +17,10 @@
  *	NET/ROM 002	Darryl(G7LED)	Fixes and address enhancement.
  *			Jonathan(G4KLX)	Complete bind re-think.
  *			Alan(GW4PTS)	Trivial tweaks into new format.
+ *	NET/ROM	003	Jonathan(G4KLX)	Added G8BPQ extensions.
  *
  *	To do:
  *		Fix non-blocking connect failure.
- *		Make it use normal SIOCADDRT/DELRT not funny node ioctl() calls.
  */
   
 #include <linux/config.h>
@@ -290,7 +290,7 @@
 		case NETROM_T1:
 			if (opt < 1)
 				return -EINVAL;
-			sk->nr->t1 = opt * PR_SLOWHZ;
+			sk->nr->rtt = (opt * PR_SLOWHZ) / 2;
 			return 0;
 
 		case NETROM_T2:
@@ -470,6 +470,7 @@
 	nr->my_index   = 0;
 	nr->my_id      = 0;
 
+	nr->bpqext     = 1;
 	nr->state      = NR_STATE_0;
 
 	memset(&nr->source_addr, '\0', sizeof(ax25_address));
@@ -550,6 +551,8 @@
 	nr->t2       = osk->nr->t2;
 	nr->n2       = osk->nr->n2;
 
+	nr->bpqext   = osk->nr->bpqext;
+
 	nr->t1timer  = 0;
 	nr->t2timer  = 0;
 	nr->t4timer  = 0;
@@ -864,23 +867,27 @@
 	struct sock *make;	
 	ax25_address *src, *dest, *user;
 	unsigned short circuit_index, circuit_id;
-	unsigned short frametype, window;
+	unsigned short frametype, window, timeout;
 
 	skb->sk = NULL;		/* Initially we don't know who its for */
 	
-	src  = (ax25_address *)(skb->data + 17);
-	dest = (ax25_address *)(skb->data + 24);
-
-	circuit_index = skb->data[32];
-	circuit_id    = skb->data[33];
-	frametype     = skb->data[36];
+	/*
+	 *	skb->data points to the netrom frame start
+	 */
+	 
+	src  = (ax25_address *)(skb->data);
+	dest = (ax25_address *)(skb->data + 7);
+
+	circuit_index = skb->data[15];
+	circuit_id    = skb->data[16];
+	frametype     = skb->data[19];
 
 #ifdef CONFIG_INET
 	/*
 	 * Check for an incoming IP over NET/ROM frame.
 	 */
 	 if ((frametype & 0x0F) == NR_PROTOEXT && circuit_index == NR_PROTO_IP && circuit_id == NR_PROTO_IP) {
-	 	skb->h.raw = skb->data + 37;
+	 	skb->h.raw = skb->data + 20;
 
 		return nr_rx_ip(skb, dev);
 	 }
@@ -891,10 +898,12 @@
 	 * a Connect Request base it on their circuit ID.
 	 */
 	if (((frametype & 0x0F) != NR_CONNREQ && (sk = nr_find_socket(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL) ||
-	    ((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL)) {
-		skb->h.raw = skb->data + 37;
-		skb->len  -= 20;
-
+	    ((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL)) 
+	{
+		if((frametype & 0x0F) == NR_CONNACK && skb->len == 39)	/* ??? size check --FIXME-- */
+			sk->nr->bpqext = 1;
+		else
+			sk->nr->bpqext = 0;
 		return nr_process_rx_frame(sk, skb);
 	}
 
@@ -908,8 +917,8 @@
 		return 0;
 	}
 
-	user   = (ax25_address *)(skb->data + 38);
-	window = skb->data[37];
+	user   = (ax25_address *)(skb->data + 11);
+	window = skb->data[20];
 
 	skb->sk             = make;
 	make->state         = TCP_ESTABLISHED;
@@ -931,6 +940,16 @@
 	if (window < make->window)
 		make->window = window;
 
+	/* L4 timeout negotiation */
+	if (skb->len == 37) {
+		timeout = skb->data[53] * 256 + skb->data[52];
+		if (timeout * PR_SLOWHZ < make->nr->rtt * 2)
+			make->nr->rtt = (timeout * PR_SLOWHZ) / 2;
+		make->nr->bpqext = 1;
+	} else {
+		make->nr->bpqext = 0;
+	}
+
 	nr_write_internal(make, NR_CONNACK);
 
 	make->nr->condition = 0x00;
@@ -1007,9 +1026,13 @@
 	skb->sk   = sk;
 	skb->free = 1;
 	skb->arp  = 1;
-	skb->len  = size;
+	skb_reserve(skb,37);
 	
-	asmptr = skb->data + 16;
+	/*
+	 *	Push down the NetROM header
+	 */
+	 
+	asmptr = skb_push(skb,20);
 
 	if (sk->debug)
 		printk("Building NET/ROM Header.\n");
@@ -1043,7 +1066,12 @@
 	if (sk->debug)
 		printk("Built header.\n");
 
-	skb->h.raw = asmptr;
+	/*
+	 *	Put the data on the end.
+	 */
+	 
+	skb->h.raw = skb_put(skb,len);
+	asmptr=skb->h.raw;
 	
 	if (sk->debug)
 		printk("NET/ROM: Appending user data\n");
@@ -1100,15 +1128,16 @@
 	if ((skb = skb_recv_datagram(sk, flags, noblock, &er)) == NULL)
 		return er;
 
-	copied = (size < skb->len) ? size : skb->len;
+	/* Allow for the 20 byte netrom header */
+	copied = (size < skb->len-20) ? size : skb->len-20;
 
-	skb_copy_datagram(skb, 0, ubuf, copied);
+	skb_copy_datagram(skb, 20, ubuf, copied);
 	
 	if (sax != NULL) {
 		struct sockaddr_ax25 addr;
 		
 		addr.sax25_family = AF_NETROM;
-		memcpy(&addr.sax25_call, skb->data + 24, sizeof(ax25_address));
+		memcpy(&addr.sax25_call, skb->data + 7, sizeof(ax25_address));
 
 		memcpy(sax, &addr, sizeof(*sax));
 
@@ -1169,7 +1198,7 @@
 			struct sk_buff *skb;
 			/* These two are safe on a single CPU system as only user tasks fiddle here */
 			if ((skb = skb_peek(&sk->receive_queue)) != NULL)
-				amount = skb->len;
+				amount = skb->len-20;
 			if ((err = verify_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned long))) != 0)
 				return err;
 			put_fs_long(amount, (unsigned long *)arg);
@@ -1199,10 +1228,8 @@
 		case SIOCSIFMETRIC:
 			return -EINVAL;
 
-		case SIOCNRADDNODE:
-		case SIOCNRDELNODE:
-		case SIOCNRADDNEIGH:
-		case SIOCNRDELNEIGH:
+		case SIOCADDRT:
+		case SIOCDELRT:
 		case SIOCNRDECOBS:
 			if (!suser()) return -EPERM;
 			return nr_rt_ioctl(cmd, (void *)arg);
@@ -1324,7 +1351,7 @@
 {
 	sock_register(nr_proto_ops.family, &nr_proto_ops);
 	register_netdevice_notifier(&nr_dev_notifier);
-	printk("G4KLX NET/ROM for Linux. Version 0.2 ALPHA for AX.25 029 for Linux 1.3.0\n");
+	printk("G4KLX NET/ROM for Linux. Version 0.3 ALPHA for AX25 029 Linux 1.3.0\n");
 
 	nr_default.quality    = NR_DEFAULT_QUAL;
 	nr_default.obs_count  = NR_DEFAULT_OBS;
diff -u --recursive --new-file v1.3.5/linux/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c
--- v1.3.5/linux/net/netrom/nr_dev.c	Tue Jun  6 12:16:45 1995
+++ linux/net/netrom/nr_dev.c	Thu Jun 29 19:18:53 1995
@@ -1,5 +1,5 @@
 /*
- *	NET/ROM release 002
+ *	NET/ROM release 003
  *
  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  *	releases, misbehave and/or generally screw up. It might even work. 
@@ -73,9 +73,10 @@
  * packet so that the transmit routine can identify it, and throw it away.
  */
 
-static int nr_header(unsigned char *buff, struct device *dev, unsigned short type,
-	void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
+static int nr_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+	void *daddr, void *saddr, unsigned len)
 {
+	unsigned char *buff=skb_push(skb,37);
 	if (type == ETH_P_ARP) {
 		*buff++ = 0xFF;		/* Mark it */
 		*buff++ = 0xFE;
diff -u --recursive --new-file v1.3.5/linux/net/netrom/nr_in.c linux/net/netrom/nr_in.c
--- v1.3.5/linux/net/netrom/nr_in.c	Tue Jun  6 12:16:45 1995
+++ linux/net/netrom/nr_in.c	Thu Jun 29 19:18:53 1995
@@ -1,5 +1,5 @@
 /*
- *	NET/ROM release 002
+ *	NET/ROM release 003
  *
  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  *	releases, misbehave and/or generally screw up. It might even work. 
@@ -135,8 +135,8 @@
 	unsigned short nr, ns;
 	int queued = 0;
 
-	nr = skb->data[35];
-	ns = skb->data[34];
+	nr = skb->data[18];
+	ns = skb->data[17];
 
 	switch (frametype) {
 
@@ -241,7 +241,7 @@
 			do {
 				save_vr = sk->nr->vr;
 				while ((skbn = skb_dequeue(&sk->nr->reseq_queue)) != NULL) {
-					ns = skbn->data[34];
+					ns = skbn->data[17];
 					if (ns == sk->nr->vr) {
 						if (sock_queue_rcv_skb(sk, skbn) == 0) {
 							sk->nr->vr = (sk->nr->vr + 1) % NR_MODULUS;
@@ -285,9 +285,15 @@
 {
 	int queued = 0, frametype;
 
+	if (sk->nr->state != NR_STATE_1 && sk->nr->state != NR_STATE_2 &&
+	    sk->nr->state != NR_STATE_3) {
+		printk("nr_process_rx_frame: frame received - state: %d\n", sk->nr->state);
+		return queued;
+	}
+
 	del_timer(&sk->timer);
 
-	frametype = skb->data[36];
+	frametype = skb->data[19];
 
 	switch (sk->nr->state)
 	{
@@ -300,14 +306,11 @@
 		case NR_STATE_3:
 			queued = nr_state3_machine(sk, skb, frametype);
 			break;
-		default:
-			printk("nr_process_rx_frame: frame received - state: %d\n", sk->nr->state);
-			break;
 	}
 
 	nr_set_timer(sk);
 
-	return(queued);
+	return queued;
 }
 
 #endif
diff -u --recursive --new-file v1.3.5/linux/net/netrom/nr_out.c linux/net/netrom/nr_out.c
--- v1.3.5/linux/net/netrom/nr_out.c	Tue Jun  6 12:16:45 1995
+++ linux/net/netrom/nr_out.c	Thu Jun 29 19:18:53 1995
@@ -1,5 +1,5 @@
 /*
- *	NET/ROM release 002
+ *	NET/ROM release 003
  *
  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  *	releases, misbehave and/or generally screw up. It might even work. 
@@ -61,7 +61,7 @@
 	if (skb == NULL)
 		return;
 
-	dptr = skb->data + 34;
+	dptr = skb->data + 17;
 	
 	*dptr++ = sk->nr->vs;
 	*dptr++ = sk->nr->vr;
@@ -150,7 +150,11 @@
 {
 	unsigned char *dptr;
 
-	dptr = skb->data + 16;
+	/*
+	 *	Add the protocol byte
+	 */
+	 
+	dptr = skb_push(skb,1);
 
 	*dptr++ = AX25_P_NETROM;
 	
diff -u --recursive --new-file v1.3.5/linux/net/netrom/nr_route.c linux/net/netrom/nr_route.c
--- v1.3.5/linux/net/netrom/nr_route.c	Tue Jun  6 12:16:45 1995
+++ linux/net/netrom/nr_route.c	Thu Jun 29 19:18:53 1995
@@ -1,5 +1,5 @@
 /*
- *	NET/ROM release 002
+ *	NET/ROM release 003
  *
  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  *	releases, misbehave and/or generally screw up. It might even work. 
@@ -14,6 +14,8 @@
  *
  *	History
  *	NET/ROM 001	Jonathan(G4KLX)	First attempt.
+ *	NET/ROM	003	Jonathan(G4KLX)	Use SIOCADDRT/SIOCDELRT ioctl values
+ *					for NET/ROM routes.
  *
  *	TO DO
  *	Sort out the which pointer when shuffling entries in the routes
@@ -538,45 +540,48 @@
  */
 int nr_rt_ioctl(unsigned int cmd, void *arg)
 {
-	struct nr_node_struct  nr_node;
-	struct nr_neigh_struct nr_neigh;
+	struct nr_route_struct nr_route;
 	struct device *dev;
 	int err;
 
 	switch (cmd) {
 
-		case SIOCNRADDNODE:
-			if ((err = verify_area(VERIFY_READ, arg, sizeof(struct nr_node_struct))) != 0)
+		case SIOCADDRT:
+			if ((err = verify_area(VERIFY_READ, arg, sizeof(struct nr_route_struct))) != 0)
 				return err;
-			memcpy_fromfs(&nr_node, arg, sizeof(struct nr_node_struct));
-			if ((dev = nr_ax25_dev_get(nr_node.device)) == NULL)
+			memcpy_fromfs(&nr_route, arg, sizeof(struct nr_route_struct));
+			if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
 				return -EINVAL;
-			return nr_add_node(&nr_node.callsign, nr_node.mnemonic,
-					   &nr_node.neighbour, dev, nr_node.quality, nr_node.obs_count);
-
-		case SIOCNRDELNODE:
-			if ((err = verify_area(VERIFY_READ, arg, sizeof(struct nr_node_struct))) != 0)
-				return err;
-			memcpy_fromfs(&nr_node, arg, sizeof(struct nr_node_struct));
-			if ((dev = nr_ax25_dev_get(nr_node.device)) == NULL)
-				return -EINVAL;
-			return nr_del_node(&nr_node.callsign, &nr_node.neighbour, dev);
-
-		case SIOCNRADDNEIGH:
-			if ((err = verify_area(VERIFY_READ, arg, sizeof(struct nr_neigh_struct))) != 0)
-				return err;
-			memcpy_fromfs(&nr_neigh, arg, sizeof(struct nr_neigh_struct));
-			if ((dev = nr_ax25_dev_get(nr_neigh.device)) == NULL)
-				return -EINVAL;
-			return nr_add_neigh(&nr_neigh.callsign, dev, nr_neigh.quality);
+			switch (nr_route.type) {
+				case NETROM_NODE:
+					return nr_add_node(&nr_route.callsign,
+						nr_route.mnemonic,
+						&nr_route.neighbour,
+						dev, nr_route.quality,
+						nr_route.obs_count);
+				case NETROM_NEIGH:
+					return nr_add_neigh(&nr_route.callsign,
+						dev, nr_route.quality);
+				default:
+					return -EINVAL;
+			}
 
-		case SIOCNRDELNEIGH:
-			if ((err = verify_area(VERIFY_READ, arg, sizeof(struct nr_neigh_struct))) != 0)
+		case SIOCDELRT:
+			if ((err = verify_area(VERIFY_READ, arg, sizeof(struct nr_route_struct))) != 0)
 				return err;
-			memcpy_fromfs(&nr_neigh, arg, sizeof(struct nr_neigh_struct));
-			if ((dev = nr_ax25_dev_get(nr_neigh.device)) == NULL)
+			memcpy_fromfs(&nr_route, arg, sizeof(struct nr_route_struct));
+			if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
 				return -EINVAL;
-			return nr_del_neigh(&nr_neigh.callsign, dev, nr_neigh.quality);
+			switch (nr_route.type) {
+				case NETROM_NODE:
+					return nr_del_node(&nr_route.callsign,
+						&nr_route.neighbour, dev);
+				case NETROM_NEIGH:
+					return nr_del_neigh(&nr_route.callsign,
+						dev, nr_route.quality);
+				default:
+					return -EINVAL;
+			}
 
 		case SIOCNRDECOBS:
 			return nr_dec_obs();
@@ -649,9 +654,10 @@
 	if ((dev = nr_dev_first()) == NULL)
 		return 0;
 
-	if (device != NULL)
-		skb->len += dev->hard_header_len;
+/*	if (device != NULL)
+		skb->len += dev->hard_header_len;*/
 
+	skb_push(skb,17);
 	ax25_send_frame(skb, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->dev);
 
 	return 1;
diff -u --recursive --new-file v1.3.5/linux/net/netrom/nr_subr.c linux/net/netrom/nr_subr.c
--- v1.3.5/linux/net/netrom/nr_subr.c	Tue Jun  6 12:16:45 1995
+++ linux/net/netrom/nr_subr.c	Thu Jun 29 19:18:53 1995
@@ -1,5 +1,5 @@
 /*
- *	NET/ROM release 002
+ *	NET/ROM release 003
  *
  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  *	releases, misbehave and/or generally screw up. It might even work. 
@@ -14,6 +14,7 @@
  *
  *	History
  *	NET/ROM 001	Jonathan(G4KLX)	Cloned from ax25_subr.c
+ *	NET/ROM	003	Jonathan(G4KLX)	Added G8BPQ NET/ROM extensions.
  */
  
 #include <linux/config.h>
@@ -150,11 +151,11 @@
 {
 	struct sk_buff *skb;
 	unsigned char  *dptr;
-	int len;
+	int len, timeout;
 	
 	switch (frametype & 0x0F) {
-		case NR_CONNREQ: len = 52; break;
-		case NR_CONNACK: len = 38; break;
+		case NR_CONNREQ: len = 54; break;
+		case NR_CONNACK: len = (sk->nr->bpqext) ? 39 : 38; break;
 		case NR_DISCREQ: len = 37; break;
 		case NR_DISCACK: len = 37; break;
 		case NR_INFOACK: len = 37; break;
@@ -166,11 +167,17 @@
 	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
 		return;
 
-	dptr = skb->data + 32;
+	/*
+	 *	Space for AX.25
+	 */
+	skb_reserve(skb,17);
+	
+	dptr = skb_put(skb,len-17);
 
 	switch (frametype & 0x0F) {
 
 		case NR_CONNREQ:
+			timeout = (sk->nr->rtt / PR_SLOWHZ) * 2;
 			*dptr++ = sk->nr->my_index;
 			*dptr++ = sk->nr->my_id;
 			*dptr++ = 0;
@@ -186,6 +193,9 @@
 			dptr[6] &= ~LAPB_C;
 			dptr[6] &= ~LAPB_E;
 			dptr[6] |= SSID_SPARE;
+			dptr += 7;
+			*dptr++ = timeout % 256;
+			*dptr++ = timeout / 256;
 			break;
 
 		case NR_CONNACK:
@@ -195,6 +205,7 @@
 			*dptr++ = sk->nr->my_id;
 			*dptr++ = frametype;
 			*dptr++ = sk->window;
+			if (sk->nr->bpqext) *dptr++ = nr_default.ttl;
 			break;
 
 		case NR_DISCREQ:
@@ -216,7 +227,6 @@
 	}
 
 	skb->free = 1;
-	skb->len  = len;
 
 	nr_transmit_buffer(sk, skb);
 }
@@ -233,7 +243,8 @@
 	if ((skbn = alloc_skb(38, GFP_ATOMIC)) == NULL)
 		return;
 
-	dptr = skbn->data + 16;
+	skb_reserve(skbn,17);
+	dptr = skb_put(skbn,21);
 
 	*dptr++ = AX25_P_NETROM;
 	
@@ -259,7 +270,6 @@
 	*dptr++ = 0;
 
 	skbn->free = 1;
-	skbn->len  = 38;
 	skbn->sk   = NULL;
 
 	if (!nr_route_frame(skbn, NULL))
@@ -284,7 +294,7 @@
  */
 void nr_calculate_rtt(struct sock *sk)
 {
-	if (sk->nr->n2count == 0)
+	if (sk->nr->t1timer > 0 && sk->nr->n2count == 0)
 		sk->nr->rtt = (9 * sk->nr->rtt + sk->nr->t1 - sk->nr->t1timer) / 10;
 
 	/* Don't go below one second */
diff -u --recursive --new-file v1.3.5/linux/net/netrom/nr_timer.c linux/net/netrom/nr_timer.c
--- v1.3.5/linux/net/netrom/nr_timer.c	Tue Jun  6 12:16:45 1995
+++ linux/net/netrom/nr_timer.c	Thu Jun 29 19:18:53 1995
@@ -1,5 +1,5 @@
 /*
- *	NET/ROM release 002
+ *	NET/ROM release 003
  *
  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  *	releases, misbehave and/or generally screw up. It might even work. 
diff -u --recursive --new-file v1.3.5/linux/net/socket.c linux/net/socket.c
--- v1.3.5/linux/net/socket.c	Tue Jun 27 14:11:48 1995
+++ linux/net/socket.c	Thu Jun 29 19:18:53 1995
@@ -1272,7 +1272,7 @@
 {
 	int i;
 
-	printk("Swansea University Computer Society NET3.029 Snap #6 for Linux 1.3.0\n");
+	printk("Swansea University Computer Society NET3.030 Snap #1 for Linux 1.3.4\n");
 
 	/*
 	 *	Initialize all address (protocol) families. 
