diff -u --recursive --new-file v1.3.10/linux/CREDITS linux/CREDITS
--- v1.3.10/linux/CREDITS	Thu Jul 13 16:20:19 1995
+++ linux/CREDITS	Sun Jul 16 21:44:59 1995
@@ -688,7 +688,9 @@
 
 N: Michael Neuffer
 E: neuffer@goofy.zdv.uni-mainz.de
-D: developer and maintainer of the eata_dma SCSI driver 
+D: Developer and maintainer of the EATA-DMA SCSI driver
+D: Co-developer EATA-PIO SCSI driver
+D: Assorted other snippets 
 S: Zum Schiersteiner Grund 2
 S: 55127 Mainz
 S: Germany
diff -u --recursive --new-file v1.3.10/linux/Makefile linux/Makefile
--- v1.3.10/linux/Makefile	Thu Jul 13 16:20:19 1995
+++ linux/Makefile	Thu Jul 13 17:39:27 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 10
+SUBLEVEL = 11
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.10/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v1.3.10/linux/arch/alpha/kernel/entry.S	Thu Jul 13 16:20:19 1995
+++ linux/arch/alpha/kernel/entry.S	Sun Jul 16 22:58:10 1995
@@ -9,7 +9,7 @@
 #define halt	.long PAL_halt
 #define rti	.long PAL_rti
 
-#define NR_SYSCALLS 310
+#define NR_SYSCALLS 320
 #define osf_vfork sys_fork
 
 /*
@@ -565,3 +565,6 @@
 /* linux-specific system calls start at 300 */
 /*300*/	.quad sys_bdflush, sys_sethae, sys_mount, sys_adjtimex, sys_swapoff
 	.quad sys_getdents, sys_create_module, sys_init_module, sys_delete_module, sys_get_kernel_syms
+	.quad sys_syslog, do_entSys, do_entSys, do_entSys, do_entSys
+	.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
+
diff -u --recursive --new-file v1.3.10/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c
--- v1.3.10/linux/arch/alpha/kernel/ptrace.c	Thu Jul 13 16:20:19 1995
+++ linux/arch/alpha/kernel/ptrace.c	Mon Jul 17 12:12:38 1995
@@ -693,7 +693,7 @@
 			else
 				child->flags &= ~PF_TRACESYS;
 			child->exit_code = data;
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			ptrace_cancel_bpt(child);
 			set_success(&regs,data);
 			return 0;
@@ -705,7 +705,7 @@
  * exit.
  */
 		case PTRACE_KILL: {
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = SIGKILL;
 			ptrace_cancel_bpt(child);
 			return 0;
@@ -721,7 +721,7 @@
 				return res;
 			}
 			child->flags &= ~PF_TRACESYS;
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = data;
 			/* give it a chance to run. */
 			return 0;
@@ -733,7 +733,7 @@
 			   return -EIO;
 			}
 			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = data;
 			REMOVE_LINKS(child);
 			child->p_pptr = child->p_opptr;
diff -u --recursive --new-file v1.3.10/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- v1.3.10/linux/arch/alpha/lib/Makefile	Tue Jul 11 10:02:47 1995
+++ linux/arch/alpha/lib/Makefile	Mon Jul 17 09:23:48 1995
@@ -8,7 +8,7 @@
 	$(CC) $(CFLAGS) -c $<
 
 OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
-	checksum.o
+	checksum.o strlen.o
 
 lib.a: $(OBJS)
 	$(AR) rcs lib.a $(OBJS)
diff -u --recursive --new-file v1.3.10/linux/arch/alpha/lib/strlen.S linux/arch/alpha/lib/strlen.S
--- v1.3.10/linux/arch/alpha/lib/strlen.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/alpha/lib/strlen.S	Mon Jul 17 08:50:12 1995
@@ -0,0 +1,57 @@
+/*
+ * strlen.S (c) 1995 David Mosberger (davidm@cs.arizona.edu)
+ *
+ * Finds length of a 0-terminated string.  Optimized for the
+ * Alpha architecture:
+ *
+ *	- memory accessed as aligned quadwords only
+ *	- uses bcmpge to compare 8 bytes in parallel
+ *	- does binary search to find 0 byte in last
+ *	  quadword (HAKMEM needed 12 instructions to
+ *	  do this instead of the 9 instructions that
+ *	  binary search needs).
+ */
+
+	.set noreorder
+	.set noat
+
+	.align 3
+
+	.globl	strlen
+	.ent	strlen
+
+strlen:
+	ldq_u	$1, 0($16)	# load first quadword ($16  may be misaligned)
+	lda	$2, -1($31)
+	insqh	$2, $16, $2
+	andnot	$16, 7, $0
+	or	$2, $1, $1
+	cmpbge	$31, $1, $2	# $2  <- bitmask: bit i == 1 <==> i-th byte == 0
+	bne	$2, found
+
+loop:	ldq	$1, 8($0)
+	addq	$0, 8, $0	# addr += 8
+	nop			# helps dual issue last two insns
+	cmpbge	$31, $1, $2
+	beq	$2, loop
+
+found:	blbs	$2, done	# make aligned case fast
+	negq	$2, $3
+	and	$2, $3, $2
+
+	and	$2, 0x0f, $1
+	addq	$0, 4, $3
+	cmoveq	$1, $3, $0
+
+	and	$2, 0x33, $1
+	addq	$0, 2, $3
+	cmoveq	$1, $3, $0
+
+	and	$2, 0x55, $1
+	addq	$0, 1, $3
+	cmoveq	$1, $3, $0
+
+done:	subq	$0, $16, $0
+	ret	$31, ($26)
+
+	.end	strlen
diff -u --recursive --new-file v1.3.10/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- v1.3.10/linux/arch/i386/kernel/ptrace.c	Tue May 30 12:17:18 1995
+++ linux/arch/i386/kernel/ptrace.c	Mon Jul 17 12:11:59 1995
@@ -466,7 +466,7 @@
 			else
 				child->flags &= ~PF_TRACESYS;
 			child->exit_code = data;
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 	/* make sure the single step bit is not set. */
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
 			put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
@@ -481,7 +481,7 @@
 		case PTRACE_KILL: {
 			long tmp;
 
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = SIGKILL;
 	/* make sure the single step bit is not set. */
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
@@ -497,7 +497,7 @@
 			child->flags &= ~PF_TRACESYS;
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG;
 			put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = data;
 	/* give it a chance to run. */
 			return 0;
@@ -509,7 +509,7 @@
 			if ((unsigned long) data > NSIG)
 				return -EIO;
 			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = data;
 			REMOVE_LINKS(child);
 			child->p_pptr = child->p_opptr;
diff -u --recursive --new-file v1.3.10/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- v1.3.10/linux/arch/mips/kernel/ptrace.c	Wed Jan 25 08:54:22 1995
+++ linux/arch/mips/kernel/ptrace.c	Mon Jul 17 12:13:20 1995
@@ -448,7 +448,7 @@
 			else
 				child->flags &= ~PF_TRACESYS;
 			child->exit_code = data;
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 	/* make sure the single step bit is not set. */
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
 			put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
@@ -463,7 +463,7 @@
 		case PTRACE_KILL: {
 			long tmp;
 
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = SIGKILL;
 	/* make sure the single step bit is not set. */
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
@@ -479,7 +479,7 @@
 			child->flags &= ~PF_TRACESYS;
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG;
 			put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = data;
 	/* give it a chance to run. */
 			return 0;
@@ -491,7 +491,7 @@
 			if ((unsigned long) data > NSIG)
 				return -EIO;
 			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
-			child->state = TASK_RUNNING;
+			wake_up_process(child);
 			child->exit_code = data;
 			REMOVE_LINKS(child);
 			child->p_pptr = child->p_opptr;
diff -u --recursive --new-file v1.3.10/linux/drivers/Makefile linux/drivers/Makefile
--- v1.3.10/linux/drivers/Makefile	Tue Jul 11 10:02:48 1995
+++ linux/drivers/Makefile	Sun Jul 16 21:58:49 1995
@@ -15,7 +15,6 @@
 	$(CC) $(CFLAGS) -c $<
 
 SUBDIRS	= block char net #streams
-ALL_SUBDIRS = block char net scsi #streams
 
 ifdef CONFIG_PCI
 SUBDIRS := $(SUBDIRS) pci
@@ -35,9 +34,9 @@
 	set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done
 
 modules: dummy
-	set -e; for i in $(ALL_SUBDIRS); do $(MAKE) -C $$i modules; done
+	set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i modules; done
 
 dep:
-	set -e; for i in $(ALL_SUBDIRS); do $(MAKE) -C $$i dep; done
+	set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i dep; done
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v1.3.10/linux/drivers/block/README.sjcd linux/drivers/block/README.sjcd
--- v1.3.10/linux/drivers/block/README.sjcd	Fri Jul  7 08:54:44 1995
+++ linux/drivers/block/README.sjcd	Sun Jul 16 21:47:22 1995
@@ -1,3 +1,4 @@
+ -- README.sjcd
 				80% of the work takes 20% of the time,
 				20% of the work takes 80% of the time...
 						(Murphy law)
@@ -5,21 +6,36 @@
 				Once started, training can not be stopped...
 						(StarWars)
 
+This is the README for the sjcd cdrom driver, version 1.3.
+
 This file is meant as a tips & tricks edge for the usage of the SANYO CDR-H94A
 cdrom drive. It will grow as the questions arise. ;-)
+Since the drive often comes with an ISP16 soundcard, which can be used
+as cdrom interface, this is also the place for ISP16 related issues.
 
 The driver should work with any SoundBlaster/Panasonic style CDROM interface,
 including the "soft configurable" MediaMagic sound card.
 To make this sound card (and others like "Mozart") working, it has to get 
 "configured" by software.
-So, you should boot DOS once (and by this, run the "configuration driver")
+The suggestion to configure the ISP16 soundcard by booting DOS and 
+a warm reboot to boot Linux somehow doesn't work, at least not
+on Eric's machine (IPC P90), with the version of the ISP16
+card he has (there appear to be at least two versions: Eric's card with
+no jumpered IDE support and Vadim's version with a jumper to enable
+IDE support).
+Therefore detection and configuration of the ISP16 interfaces is included
+in the driver.
+If we should support any other interfaces (which cannot be configured
+through DOS) or if there are any more ISP16 types, please let us
+know (maarel@marin.nl) and we'll see.
+
+Otherwise, you should boot DOS once (and by this, run the "configuration driver")
 and then switch to Linux by use of CTL-ALT-DEL. Each use of the RESET
 button or the power switch makes this procedure necessary again.
+If no ISP16 is detected, there's no harm done; a card configured trough DOS
+may still work as expected.
 
-Vadim has implemented a Linux "configuration driver" to set up the
-registers of the MediaMagic (ISP-16) sound card. These routines have to get
-integrated into the related CDROM and sound drivers directly at a later
-time. Currently, they reside at Vadim's server
+ISP16 configuration routines reside at Vadim's server
       rbrf.msk.su:/linux/mediamagic/
 and at Eberhard's mirror
       ftp.gwdg.de:/pub/linux/cdrom/drivers/sanyo/
@@ -28,6 +44,26 @@
       dutette.et.tudelft.nl:/pub/linux/
 and at Eberhard's mirror
       ftp.gwdg.de:/pub/linux/cdrom/drivers/optics/
+
+Eric van der Maarel's routines are included in sjcd.c.
+This, and any related stuff may be found by anonymous ftp at
+      ftp.gwdg.de:/pub/linux/cdrom/drivers/sanyo/
+
+The device major for sjcd is 18, and minor is 0. Create a block special
+file in your /dev directory (e.g., /dev/sjcd) with these numbers.
+(For those who don't know, being root and the following should do the trick:
+  mknod -m 644 /dev/sjcd b 18 0
+and mount the cdrom by /dev/sjcd).
+
+The default configuration parameters are:
+  base address 0x340
+  irq 10
+  no dma
+As of version 1.2, setting base address, irq and dma at boot time is supported
+through the use of command line options: type at the "boot:" prompt:
+  linux sjcd=<base address>,<irq>,<dma>
+(where your kernel is assumed to be called by saying "linux" to
+the boot manager).
 
 If something is wrong, e-mail to		vadim@rbrf.msk.su
 					or 	vadim@ipsun.ras.ru
diff -u --recursive --new-file v1.3.10/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.3.10/linux/drivers/block/ide.c	Tue Jul 11 10:02:49 1995
+++ linux/drivers/block/ide.c	Mon Jul 17 17:00:30 1995
@@ -1358,7 +1358,7 @@
 		sleep_on(&dev->wqueue);
 	dev->usage++;
 	restore_flags(flags);
-	if (dev->id->config & (1<<7))	/* for removeable disks */
+	if (dev->id && (dev->id->config & (1<<7)))	/* for removeable disks */
 		check_disk_change(inode->i_rdev);
 #ifdef CONFIG_BLK_DEV_IDECD
 	if (dev->type == cdrom)
@@ -1654,7 +1654,7 @@
 	if (dev->type == cdrom)
 		return cdrom_check_media_change (dev);
 #endif	/* CONFIG_BLK_DEV_IDECD */
-	if (dev->id->config & (1<<7))	/* for removeable disks */
+	if (dev->id && (dev->id->config & (1<<7))) /* for removeable disks */
 		return 1;	/* always assume it was changed */
 	return 0;
 }
diff -u --recursive --new-file v1.3.10/linux/drivers/block/sjcd.c linux/drivers/block/sjcd.c
--- v1.3.10/linux/drivers/block/sjcd.c	Fri Jul  7 08:54:45 1995
+++ linux/drivers/block/sjcd.c	Sun Jul 16 21:47:22 1995
@@ -1,15 +1,24 @@
-/*
- *   Sanyo CD-ROM device driver implementation.
+/* -- sjcd.c
  *
+ *   Sanyo CD-ROM device driver implementation, Version 1.3
  *   Copyright (C) 1995  Vadim V. Model
  *
  *   model@cecmow.enet.dec.com
  *   vadim@rbrf.msk.su
  *   vadim@ipsun.ras.ru
  *
+ *   ISP16 detection and configuration.
+ *   Copyright (C) 1995  Eric van der Maarel (maarel@marin.nl)
+ *
+ *
  *  This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de);
  *  it was developed under use of mcd.c from Martin Harriss, with help of
- *  E. van der Maarel (maarel@marin.nl).
+ *  Eric van der Maarel (maarel@marin.nl).
+ *
+ *  ISP16 detection and configuration by Eric van der Maarel (maarel@marin.nl),
+ *  with some data communicated by Vadim V. Model (vadim@rbrf.msk.su)
+ *  and Leo Spiekman (spiekman@et.tudelft.nl)
+ *
  *
  *  It is planned to include these routines into sbpcd.c later - to make
  *  a "mixed use" on one cable possible for all kinds of drives which use
@@ -29,6 +38,15 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  History:
+ *  1.1 First public release with kernel version 1.3.7.
+ *      Written by Vadim Model.
+ *  1.2 Added detection and configuration of cdrom interface
+ *      on ISP16 soundcard.
+ *      Allow for command line options: sjcd=<io_base>,<irq>,<dma>
+ *  1.3 Some minor changes to README.sjcd.
+ *
  */
 
 #include <linux/errno.h>
@@ -49,11 +67,60 @@
 
 #define MAJOR_NR SANYO_CDROM_MAJOR
 #include "blk.h"
-#ifdef CONFIG_ISP_16
-#include <linux/isp16.h>
-#endif
 #include <linux/sjcd.h>
 
+/* Some (Media)Magic */
+/* define types of drive the interface on an ISP16 card may be looking at */
+#define ISP16_DRIVE_X 0x00
+#define ISP16_SONY  0x02
+#define ISP16_PANASONIC0 0x02
+#define ISP16_SANYO0 0x02
+#define ISP16_MITSUMI  0x04
+#define ISP16_PANASONIC1 0x06
+#define ISP16_SANYO1 0x06
+#define ISP16_DRIVE_NOT_USED 0x08  /* not used */
+#define ISP16_DRIVE_SET_MASK 0xF1  /* don't change 0-bit or 4-7-bits*/
+/* ...for port */
+#define ISP16_DRIVE_SET_PORT 0xF8D
+/* set io parameters */
+#define ISP16_BASE_340  0x00
+#define ISP16_BASE_330  0x40
+#define ISP16_BASE_360  0x80
+#define ISP16_BASE_320  0xC0
+#define ISP16_IRQ_X  0x00
+#define ISP16_IRQ_5  0x04  /* shouldn't be used due to soundcard conflicts */
+#define ISP16_IRQ_7  0x08  /* shouldn't be used due to soundcard conflicts */
+#define ISP16_IRQ_3  0x0C
+#define ISP16_IRQ_9  0x10
+#define ISP16_IRQ_10  0x14
+#define ISP16_IRQ_11  0x18
+#define ISP16_DMA_X  0x03
+#define ISP16_DMA_3  0x00
+#define ISP16_DMA_5  0x00
+#define ISP16_DMA_6  0x01
+#define ISP16_DMA_7  0x02
+#define ISP16_IO_SET_MASK  0x20  /* don't change 5-bit */
+/* ...for port */
+#define ISP16_IO_SET_PORT  0xF8E
+/* enable the drive */
+#define ISP16_NO_IDE__ENABLE_CDROM_PORT  0xF90  /* ISP16 without IDE interface */
+#define ISP16_IDE__ENABLE_CDROM_PORT  0xF91  /* ISP16 with IDE interface */
+#define ISP16_ENABLE_CDROM  0x80  /* seven bit */
+
+/* the magic stuff */
+#define ISP16_CTRL_PORT  0xF8F
+#define ISP16_NO_IDE__CTRL  0xE2  /* ISP16 without IDE interface */
+#define ISP16_IDE__CTRL  0xE3  /* ISP16 with IDE interface */
+
+static short isp16_detect(void);
+static short isp16_no_ide__detect(void);
+static short isp16_with_ide__detect(void);
+static short isp16_config( int base, u_char drive_type, int irq, int dma );
+static short isp16_type; /* dependent on type of interface card */
+static u_char isp16_ctrl;
+static u_short isp16_enable_cdrom_port;
+
+
 static int sjcd_present = 0;
 
 #define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
@@ -86,6 +153,7 @@
 
 static short    sjcd_port = SJCD_BASE_ADDR;
 static int      sjcd_irq  = SJCD_INTR_NR;
+static int      sjcd_dma  = SJCD_DMA;
 
 static struct wait_queue *sjcd_waitq = NULL;
 
@@ -131,10 +199,17 @@
 #define CLEAR_TIMER del_timer( &sjcd_delay_timer )
 
 /*
- * Set up device. Not yet implemented.
+ * Set up device, i.e., use command line data to set
+ * base address, irq and dma.
  */
 void sjcd_setup( char *str, int *ints ){
-    printk( "Sanyo CDR-H94A device driver setup is called (%s).\n", str );
+
+   if (ints[0] > 0)
+      sjcd_port = ints[1];
+   if (ints[0] > 1)      
+      sjcd_irq = ints[2];
+   if (ints[0] > 2)      
+      sjcd_dma = ints[3];
 }
 
 /*
@@ -1266,7 +1341,7 @@
 };
 
 /*
- * Following staff is intended for initialization of the cdrom. It
+ * Following stuff is intended for initialization of the cdrom. It
  * first looks for presence of device. If the device is present, it
  * will be reset. Then read the version of the drive and load status.
  */
@@ -1281,22 +1356,21 @@
 unsigned long sjcd_init( unsigned long mem_start, unsigned long mem_end ){
   int i;
 
-  if( sjcd_port != 0x340 || sjcd_irq != 0x0A /* 10 */ ){
-    printk( "skip sjcd_init\n" );
-    return( mem_start );
+  if ( (isp16_type=isp16_detect()) < 0 )
+    printk( "No ISP16 cdrom interface found.\n" );
+  else {
+    u_char expected_drive;
+
+    printk( "ISP16 cdrom interface (%s optional IDE) detected.\n",
+      (isp16_type==2)?"with":"without" );
+
+    expected_drive = (isp16_type?ISP16_SANYO1:ISP16_SANYO0);
+
+    if ( isp16_config( sjcd_port, expected_drive, sjcd_irq, sjcd_dma ) < 0 ) {
+      printk( "ISP16 cdrom interface has not been properly configured.\n" );
+      return(mem_start);
+    }
   }
-  
-#ifdef CONFIG_ISP_16
-  /*
-   * Initialize the CDROM interface of the card.
-   */
-  isp16_cdi_setup( ISP_CDROM_SANYO, ISP_CDROM_IRQ_10,
-		  ISP_CDROM_DMA_DISABLED, ISP_CDROM_PORT_340 );
-#endif
-
-#if 0
-  printk( "sjcd=0x%x,%d: ", sjcd_port, sjcd_irq );
-#endif  
 
   if( register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){
     printk( "Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR );
@@ -1356,3 +1430,189 @@
   return( mem_start );
 }
 
+/*
+ * -- ISP16 detection and configuration
+ *
+ *    Copyright (c) 1995, Eric van der Maarel <maarel@marin.nl>
+ *
+ *    Version 0.5
+ *
+ *    Detect cdrom interface on ISP16 soundcard.
+ *    Configure cdrom interface.
+ *
+ *    Algorithm for the card with no IDE support option taken
+ *    from the CDSETUP.SYS driver for MSDOS,
+ *    by OPTi Computers, version 2.03.
+ *    Algorithm for the IDE supporting ISP16 as communicated
+ *    to me by Vadim Model and Leo Spiekman.
+ *
+ *    Use, modifification or redistribution of this software is
+ *    allowed under the terms of the GPL.
+ *
+ */
+
+
+#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
+#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
+
+static short
+isp16_detect(void)
+{
+
+  if ( !( isp16_with_ide__detect() < 0 ) )
+    return(2);
+  else
+    return( isp16_no_ide__detect() );
+}
+
+static short
+isp16_no_ide__detect(void)
+{
+  u_char ctrl;
+  u_char enable_cdrom;
+  u_char io;
+  short i = -1;
+
+  isp16_ctrl = ISP16_NO_IDE__CTRL;
+  isp16_enable_cdrom_port = ISP16_NO_IDE__ENABLE_CDROM_PORT;
+
+  /* read' and write' are a special read and write, respectively */
+
+  /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
+  ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
+  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
+
+  /* read' 3,4 and 5-bit from the cdrom enable port */
+  enable_cdrom = ISP16_IN( ISP16_NO_IDE__ENABLE_CDROM_PORT ) & 0x38;
+
+  if ( !(enable_cdrom & 0x20) ) {  /* 5-bit not set */
+    /* read' last 2 bits of ISP16_IO_SET_PORT */
+    io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
+    if ( ((io&0x01)<<1) == (io&0x02) ) {  /* bits are the same */
+      if ( io == 0 ) {  /* ...the same and 0 */
+        i = 0;
+        enable_cdrom |= 0x20;
+      }
+      else {  /* ...the same and 1 */  /* my card, first time 'round */
+        i = 1;
+        enable_cdrom |= 0x28;
+      }
+      ISP16_OUT( ISP16_NO_IDE__ENABLE_CDROM_PORT, enable_cdrom );
+    }
+    else {  /* bits are not the same */
+      ISP16_OUT( ISP16_CTRL_PORT, ctrl );
+      return(i); /* -> not detected: possibly incorrect conclusion */
+    }
+  }
+  else if ( enable_cdrom == 0x20 )
+    i = 0;
+  else if ( enable_cdrom == 0x28 )  /* my card, already initialised */
+    i = 1;
+
+  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
+
+  return(i);
+}
+
+static short
+isp16_with_ide__detect(void)
+{
+  u_char ctrl;
+  u_char tmp;
+
+  isp16_ctrl = ISP16_IDE__CTRL;
+  isp16_enable_cdrom_port = ISP16_IDE__ENABLE_CDROM_PORT;
+
+  /* read' and write' are a special read and write, respectively */
+
+  /* read' ISP16_CTRL_PORT and save */
+  ctrl = ISP16_IN( ISP16_CTRL_PORT );
+
+  /* write' zero to the ctrl port and get response */
+  ISP16_OUT( ISP16_CTRL_PORT, 0 );
+  tmp = ISP16_IN( ISP16_CTRL_PORT );
+
+  if ( tmp != 2 )  /* isp16 with ide option not detected */
+    return(-1);
+
+  /* restore ctrl port value */
+  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
+  
+  return(2);
+}
+
+static short
+isp16_config( int base, u_char drive_type, int irq, int dma )
+{
+  u_char base_code;
+  u_char irq_code;
+  u_char dma_code;
+  u_char i;
+
+  if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
+    printk( "Mitsumi cdrom drive has no dma support.\n" );
+
+  switch (base) {
+  case 0x340: base_code = ISP16_BASE_340; break;
+  case 0x330: base_code = ISP16_BASE_330; break;
+  case 0x360: base_code = ISP16_BASE_360; break;
+  case 0x320: base_code = ISP16_BASE_320; break;
+  default:
+    printk( "Base address 0x%03X not supported by cdrom interface on ISP16.\n", base );
+    return(-1);
+  }
+  switch (irq) {
+  case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
+  case 5: irq_code = ISP16_IRQ_5;
+          printk( "Irq 5 shouldn't be used by cdrom interface on ISP16,"
+            " due to possible conflicts with the soundcard.\n");
+          break;
+  case 7: irq_code = ISP16_IRQ_7;
+          printk( "Irq 7 shouldn't be used by cdrom interface on ISP16,"
+            " due to possible conflicts with the soundcard.\n");
+          break;
+  case 3: irq_code = ISP16_IRQ_3; break;
+  case 9: irq_code = ISP16_IRQ_9; break;
+  case 10: irq_code = ISP16_IRQ_10; break;
+  case 11: irq_code = ISP16_IRQ_11; break;
+  default:
+    printk( "Irq %d not supported by cdrom interface on ISP16.\n", irq );
+    return(-1);
+  }
+  switch (dma) {
+  case 0: dma_code = ISP16_DMA_X; break;  /* disable dma */
+  case 1: printk( "Dma 1 cannot be used by cdrom interface on ISP16,"
+            " due to conflict with the soundcard.\n");
+          return(-1); break;
+  case 3: dma_code = ISP16_DMA_3; break;
+  case 5: dma_code = ISP16_DMA_5; break;
+  case 6: dma_code = ISP16_DMA_6; break;
+  case 7: dma_code = ISP16_DMA_7; break;
+  default:
+    printk( "Dma %d not supported by cdrom interface on ISP16.\n", dma );
+    return(-1);
+  }
+
+  if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
+    drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
+    drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
+    drive_type != ISP16_DRIVE_X ) {
+    printk( "Drive type (code 0x%02X) not supported by cdrom"
+     " interface on ISP16.\n", drive_type );
+    return(-1);
+  }
+
+  /* set type of interface */
+  i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;  /* clear some bits */
+  ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
+
+  /* enable cdrom on interface with ide support */
+  if ( isp16_type > 1 )
+    ISP16_OUT( isp16_enable_cdrom_port, ISP16_ENABLE_CDROM );
+
+  /* set base address, irq and dma */
+  i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;  /* keep some bits */
+  ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
+
+  return(0);
+}
diff -u --recursive --new-file v1.3.10/linux/drivers/char/scc.c linux/drivers/char/scc.c
--- v1.3.10/linux/drivers/char/scc.c	Tue Jun 27 14:11:34 1995
+++ linux/drivers/char/scc.c	Mon Jul 17 14:49:30 1995
@@ -1,9 +1,8 @@
 #include <linux/autoconf.h>	/* fastest method */
 #ifdef CONFIG_SCC
 
-#define RCS_ID "$Id: scc.c,v 1.17 1995/03/15 23:28:12 JReuter Exp JReuter $"
 
-#define BANNER "Z8530 SCC driver v1.8.dl1bke (beta) by dl1bke\n"
+#define BANNER "Z8530 SCC driver v1.8.17test.17.7.95 PE1AYX (c)\n"
 
 /* ******************************************************************** */
 /* *   SCC.C - Linux driver for Z8530 based HDLC cards for AX.25      *	*/ 
@@ -11,34 +10,45 @@
 
 /* ********************************************************************
 
-	(c) 1995 by Joerg Reuter DL1BKE
+	(c) Hans Alblas PE1AYX 1993,1994,1995
+	          Released for GNU
+	portions (c) 1995 by Joerg Reuter DL1BKE
+	         (c) 1993 Guido ten Dolle PE1NNZ
 
-	portions (c) 1994 Hans Alblas PE1AYX 
-	and      (c) 1993 Guido ten Dolle PE1NNZ
-
-	for the complete copyright notice see >> Copying.Z8530DRV <<
 
    ********************************************************************	*/   
 
 /*
 
-   940913	- started to rewrite the drive
-   950131	- changed copyright notice to GPL without limitations.
+
+   931100	- started with the projekt pe1ayx
+   9406??	- KISS-parameter setting and BayCom USCC support dl1bke
+   940613	- fixed memory leak ,main memory fragmentation problem,
+                  speeded up the interupt routines ,has now its own
+                  memory buffer pool and source cleanup. pe1ayx
+   940620	- bug fixed in line disipline change ,local ringbuf
+   		  reorganisation ,and some little bugfixes.
+   940715	- first release to the public (scc15b.tgz) pe1ayx		                
    950228	- (hopefully) fixed the reason for kernel panics in
-                  chk_rcv_queue() [stupid error]
-   950304       - fixed underrun/zcount handling
-   950305	- the driver registers port addresses now
-   950314	- fixed underrun interrupt handling again
+                  chk_rcv_queue() [stupid error] dl1bke
+   950229       - buffer timeout for vergotten buffer :-( pe1ayx                
+   950304       - fixed underrun/zcount handling dl1bke
+   950305	- the driver registers port addresses now dl1bke
+   950314	- fixed underrun interrupt handling again dl1bke
+   950514	- fixed slip tty wakeup (it wil now work again with kernel ax25)pe1ayx
+   950703	- rewrote the 8530 init/reset routines pe1ayx
+   950712	- rewrote the RXirq + buffering routines pe1ayx
+   950716	- It can now handle ax25 rx frame info > 256
+   O		- rewrite TX + buffering (there is a little mem leak ,but
+                  wil not be dangerous since my buffer timeout routine
+                  wil put back vergotten buffers in the queue pe1ayx
+   O		- change the tty i/o so that the tty wakeup is handled properly
+           	  pe1ayx
    
    Thanks to:
-   
+   DL1BKE Joerg - for some good ideas
    PE1CHL Rob	- for a lot of good ideas from his SCC driver for DOS
    PE1NNZ Guido - for his port of the original driver to Linux
-   KA9Q   Phil  - from whom we stole the mbuf-structure
-   PA3AYX Hans  - who rewrote the memory management and some minor,
-                  but nevertheless useful changes
-   DL8MBT Flori - for support
-   DG0FT  Rene  - for the BayCom USCC support
    PA3AOU Harry - for ESCC testing, information supply and support
    
    PE1KOX Rob, DG1RTF Thomas, ON5QK Roland, 
@@ -46,13 +56,7 @@
    and all who sent me bug reports and ideas... 
    
    
-   NB -- if you find errors, change something, please let me know
-      	 first before you distribute it... And please don't touch
-   	 the version number. Just replace my callsign in
-   	 "v1.8.dl1bke" with your own. Just to avoid confusion...
-   	  
-   Jörg Reuter DL1BKE
-   
+      
 */
 
 
@@ -110,8 +114,6 @@
 static void z8530_init(void);
 
 static void scc_change_speed(struct scc_channel *scc);
-static void kiss_encode(struct scc_channel *scc);
-
 static void init_channel(struct scc_channel *scc);
 static void scc_key_trx (struct scc_channel *scc, char tx);
 static void scc_txint(register struct scc_channel *scc);
@@ -124,6 +126,14 @@
 
 /* from serial.c */
 
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+static unsigned char *tmp_buf = 0;
+static struct semaphore tmp_buf_sem = MUTEX;
+static unsigned int start_controle;
+
 static int baud_table[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 	9600, 19200, 38400, 57600, 115200, 0 };
@@ -142,6 +152,8 @@
 static struct sccbuf *sccfreelist[MAX_IBUFS] = {0};
 static int allocated_ibufs = 0;
 
+#define SERIAL_TYPE_NORMAL	1
+
 
 /* ******************************************************************** */
 /* *			Port Access Functions			      * */
@@ -197,10 +209,6 @@
 /* * 			Memory Buffer Management			*/
 /* ******************************************************************** */
 
-/* mbuf concept lent from KA9Q. Tnx PE1AYX for the buffer pool concept	*/
-/* (sorry, do you have any better ideas?) */
-
-
 /* allocate memory for the interrupt buffer pool */
 
 void scc_alloc_buffer_pool(void)
@@ -209,6 +217,8 @@
 	struct sccbuf *sccb;
 	struct mbuf   *bp;
 	
+	start_controle = 0;
+	
    	for (i = 0 ; i < MAX_IBUFS ; i++)
    	{
    		sccb = (struct sccbuf *)kmalloc(sizeof(struct sccbuf), GFP_ATOMIC);
@@ -286,6 +296,7 @@
 			sccfreelist[i]->bp->refcnt = 1;
 			sccfreelist[i]->bp->cnt = 0;
 			sccfreelist[i]->bp->in_use = 0;
+			sccfreelist[i]->bp->time_out = CURRENT_TIME + 300;
 		
 			restore_flags(flags);
 			return sccfreelist[i]->bp;
@@ -314,7 +325,33 @@
 		
 	save_flags(flags); cli();
 	bpnext = bp->next;
-	
+/*=========================================================================*/	
+/*==      THIS IS A LITTLE ROUTINE TO FIX THE TX MEM LEAK                ==*/
+/*==             UNTIL I HAVE REWRITE THE TX ROUTINES                    ==*/
+/*==                 PE1AYX@PI8HRL.AMPR.ORG                              ==*/
+/*=========================================================================*/
+
+	 start_controle++;
+	 if(start_controle > 100){
+	  if(bp->type == BT_TRANSMIT){
+	    start_controle = 0;
+	    for(i = 0 ; i < allocated_ibufs ; i++)
+	    {
+	       if(sccfreelist[i]->inuse == 1)
+	        if(sccfreelist[i]->bp->type == BT_TRANSMIT)
+	         if(sccfreelist[i]->bp->time_out < CURRENT_TIME)
+		    {
+			sccfreelist[i]->bp->cnt = 0;
+			sccfreelist[i]->bp->refcnt = 0;
+			sccfreelist[i]->inuse = 0;
+		    }
+ 	     }
+           } 
+	 }
+/*=========================================================================*/
+/*==                END OF THAT SILLY STUPID ROUTINE                     ==*/
+/*=========================================================================*/	 
+
 	if (bp->dup)
 	{
 		for(i = 0 ; i < allocated_ibufs ; i++)
@@ -481,13 +518,13 @@
 	
 	if (Vector_Latch)
 	{
-	    	while(1)			   /* forever...? */
+	    	while(1)
     		{ 
 			Outb(Vector_Latch, 0);      /* Generate INTACK */
         
 			/* Read the vector */
-			if((vector=Inb(Vector_Latch)) >= 16 * Nchips) break; 
-						/* ...not forever! */
+			if((vector=Inb(Vector_Latch)) >= 16 * Nchips)
+				break; 
           
 			/* Extract channel number and status from vector. */
 			/* Isolate channel nummer */
@@ -619,39 +656,20 @@
 /* Throw away received mbuf(s) when an error occurred */
 
 static inline void
-scc_toss_buffer(register struct scc_channel *scc)
-{
-	register struct mbuf *bp;
-	
-	if((bp = scc->rbp) != NULLBUF)
-	{
-		scc_free_chain(bp->next, BT_RECEIVE);
-		bp->next = NULLBUF;
-		scc->rbp1 = bp;         /* Don't throw this one away */
-		bp->cnt = 0;            /* Simply rewind it */
-		bp->in_use = 0;
-	}
-}
-
-static inline void
 flush_FIFO(register struct scc_channel *scc)
 {
 	register int k;
 	
 	for (k=0; k<3; k++)
 		Inb(scc->data);
-		
-	if(scc->rbp != NULLBUF)	/* did we receive something? */
+
+	if(scc->rxbufcnt > 0)
 	{
-		if(scc->rbp->next != NULLBUF || scc->rbp->cnt > 0)
-			scc->stat.rxerrs++;  /* then count it as an error */
-			
-		scc_toss_buffer(scc);         /* throw away buffer */
+		scc->stat.rxerrs++;
+		scc->rxbufcnt = 0;         /* throw away frame */
 	}
 }
 
-
-
 /* External/Status interrupt handler */
 static void
 scc_exint(register struct scc_channel *scc)
@@ -729,7 +747,7 @@
 static void
 scc_rxint(register struct scc_channel *scc)
 {
-	register struct mbuf *bp;
+	unsigned char ch;
 
 	scc->stat.rxints++;
 
@@ -740,32 +758,36 @@
 		return;
 	}
 
-	if ((bp = scc->rbp1) == NULLBUF || bp->cnt >= bp->size)	
-	{ 				/* no buffer available or buffer full */
-		if (scc->rbp == NULLBUF)
-		{
-			if ((bp = scc_get_buffer(BT_RECEIVE)) != NULLBUF)
-				scc->rbp = scc->rbp1 = bp;
-				
-		}
-		else if ((bp = scc_get_buffer(BT_RECEIVE)))
-		{
-			scc_append_to_chain(&scc->rbp, bp);
-			scc->rbp1 = bp;
-		}
-		
-		if (bp == NULLBUF)		/* no buffer available? */
-		{
-			Inb(scc->data);		/* discard character */
-			or(scc,R3,ENT_HM);      /* enter hunt mode */
-			scc_toss_buffer(scc);	/* throw away buffers */
-			scc->stat.nospace++;    /* and count this error */
-			return;
-		}
+	if (scc->rxbufcnt > 2044)		/* no buffer available? */
+	{
+		Inb(scc->data);		/* discard character */
+		or(scc,R3,ENT_HM);      /* enter hunt mode */
+		scc->rxbufcnt = 0;	/* throw away frame */
+		scc->stat.nospace++;    /* and count this error */
+		return;
+	}
+
+	if(scc->rxbufcnt == 0) /* make begin of kissframe */
+	{
+		scc->rxbuf[scc->rxbufcnt++] = FEND;
+		if (scc->kiss.not_slip)
+			scc->rxbuf[scc->rxbufcnt++] = 0;
+	}
+
+	switch( ch = Inb(scc->data) )
+	{
+		case FEND:
+			scc->rxbuf[scc->rxbufcnt++] = FESC;
+			scc->rxbuf[scc->rxbufcnt++] = TFEND;
+			break;
+		case FESC:
+			scc->rxbuf[scc->rxbufcnt++] = FESC;
+			scc->rxbuf[scc->rxbufcnt++] = TFESC;
+			break;
+		default:
+			scc->rxbuf[scc->rxbufcnt++] = ch;
 	}
 
-	/* now, we have a buffer. read character and store it */
-	bp->data[bp->cnt++] = Inb(scc->data);
 }
 
 
@@ -774,42 +796,82 @@
 scc_spint(register struct scc_channel *scc)
 {
 	register unsigned char status;
-	register struct mbuf *bp;
+	int i;
+	unsigned char	*cp;
+	char		*fp;
+	int		count;
+
 
 	scc->stat.spints++;
 
-	status = InReg(scc->ctrl,R1);		/* read receiver status */
+	status = InReg(scc->ctrl,R1);		/* read Special Receive Condition status */
 	
-	Inb(scc->data);				/* throw away Rx byte */
+	Inb(scc->data);				/* read byte */
 
-	if(status & Rx_OVR)			/* receiver overrun */
+	if(status & Rx_OVR)			/* RX_OVerRrun? */
 	{
-		scc->stat.rx_over++;                /* count them */
-		or(scc,R3,ENT_HM);              /* enter hunt mode for next flag */
-		scc_toss_buffer(scc);                 /* rewind the buffer and toss */
+		scc->stat.rx_over++;
+		or(scc,R3,ENT_HM);              /* enter hunt mode */
+		scc->rxbufcnt = 0;              /* rewind the buffer */
 	}
 	
-	if(status & END_FR && scc->rbp != NULLBUF)	/* end of frame */
+	if(status & END_FR && scc->rxbufcnt != 0)	/* END of FRame */
 	{
-		/* CRC okay, frame ends on 8 bit boundary and received something ? */
-		
-		if (!(status & CRC_ERR) && (status & 0xe) == RES8 && scc->rbp->cnt)
+		if (!(status & CRC_ERR) && (status & 0xe) == RES8 && scc->rxbufcnt > 0)
 		{
-			/* ignore last received byte (first of the CRC bytes) */
+		   scc->rxbufcnt--;	/*strip the CRC */
+  		   scc->rxbuf[scc->rxbufcnt++] = FEND;
+
+		   for(i = 0 ; i < scc->rxbufcnt ; i++)
+			{
+			if((scc->tty->flip.count + 1) < TTY_FLIPBUF_SIZE)
+				tty_insert_flip_char(scc->tty, scc->rxbuf[i], 0);
+			else    {
+				if (scc->tty->flip.buf_num) {
+					cp = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
+					fp = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+					scc->tty->flip.buf_num = 0;
+					scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf;
+					scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf;
+				} else {
+					cp = scc->tty->flip.char_buf;
+					fp = scc->tty->flip.flag_buf;
+					scc->tty->flip.buf_num = 1;
+					scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
+					scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+					}
+				count = scc->tty->flip.count;
+				scc->tty->flip.count = 0;
+				scc->tty->ldisc.receive_buf(scc->tty, cp, fp, count);
+				tty_insert_flip_char(scc->tty, scc->rxbuf[i], 0);
+				}
+			}
+
+		if (scc->tty->flip.buf_num) {
+			cp = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
+			fp = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+			scc->tty->flip.buf_num = 0;
+			scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf;
+			scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf;
+		} else {
+			cp = scc->tty->flip.char_buf;
+			fp = scc->tty->flip.flag_buf;
+			scc->tty->flip.buf_num = 1;
+			scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
+			scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+			}
+		count = scc->tty->flip.count;
+		scc->tty->flip.count = 0;
+		scc->tty->ldisc.receive_buf(scc->tty, cp, fp, count);
+		scc->stat.rxframes++;
+
+		scc->rxbufcnt = 0;
 			
-			for (bp = scc->rbp; bp->next != NULLBUF; bp = bp->next) ;
-				bp->cnt--;              /* last byte is first CRC byte */
-				
-			scc_enqueue(&scc->rcvq,scc->rbp);
-			scc->rbp = scc->rbp1 = NULLBUF;
-			scc->stat.rxframes++;
-			scc->stat.rx_queued++;
-		} else {				/* a bad frame */
-			scc_toss_buffer(scc);		/* throw away frame */
+		} else {
+			scc->rxbufcnt = 0;		/* frame is not good */
 			scc->stat.rxerrs++;
-		}
+	  		}		
 	}
-	
 	Outb(scc->ctrl,ERR_RES);
 }
 
@@ -934,7 +996,7 @@
 	Outb(scc->ctrl,RES_EXT_INT);	/* must be done twice */
 	
 	scc->status = InReg(scc->ctrl,R0);	/* read initial status */
-
+	scc->rxbufcnt = 0;
 	or(scc,R1,INT_ALL_Rx|TxINT_ENAB|EXT_INT_ENAB); /* enable interrupts */
 	or(scc,R9,MIE);			/* master interrupt enable */
 			
@@ -1142,42 +1204,13 @@
 	scc->t_tail = scc->kiss.tailtime;
 }
 
-static inline void check_rcv_queue(register struct scc_channel *scc)
-{
-	register struct mbuf *bp;
-	
-	if (scc->stat.rx_queued > QUEUE_THRES)
-	{
-		if (scc->rcvq == NULLBUF)
-		{
-			printk("z8530drv: Warning - scc->stat.rx_queued shows overflow"
-			       " (%d) but queue is empty\n", scc->stat.rx_queued);
-			       
-			scc->stat.rx_queued = 0;	/* correct it */
-			scc->stat.nospace = 12345;	/* draw attention to it */
-			return;
-		}
-			
-		bp = scc->rcvq->anext;	/* don't use the one we currently use */
-		
-		while (bp && (scc->stat.rx_queued > QUEUE_HYST))
-		{
-			bp = scc_free_chain(bp, BT_RECEIVE);
-			scc->stat.rx_queued--;
-			scc->stat.nospace++;
-		}
-		
-		scc->rcvq->anext = bp;
-	}
-}
-
 static void
 scc_timer(void)
 {
 	register struct scc_channel *scc;
 	register int chan;
 	unsigned long flags;
-		
+
 	save_flags(flags); cli();
 	
 	for (chan = 0; chan < (Nchips * 2); chan++)
@@ -1186,11 +1219,7 @@
 		
 		if (scc->tty && scc->init)
 		{
-			kiss_encode(scc);
-			check_rcv_queue(scc);
-			
 			/* KISS-TNC emulation */
-			
 			if (Expired(t_dwait)) dw_slot_timeout(scc)	; else
 			if (Expired(t_slot))  dw_slot_timeout(scc)	; else
 			if (Expired(t_txdel)) txdel_timeout(scc)   	; else
@@ -1201,8 +1230,10 @@
 			if (Expired(t_mbusy)) busy_timeout(scc);
 			if (Expired(t_maxk))  maxk_idle_timeout(scc);
 			if (Expired(t_idle))  maxk_idle_timeout(scc);
+
 		}
 	}
+
 	
 	timer_table[SCC_TIMER].fn = scc_timer;
 	timer_table[SCC_TIMER].expires = jiffies + HZ/TPS;
@@ -1259,7 +1290,7 @@
 	case PARAM_TXTAIL:
 		scc->kiss.tailtime = VAL; break;
 	case PARAM_FULLDUP:
-		scc->kiss.fulldup = val; break;
+		scc->kiss.fulldup = val; break; 
 	case PARAM_WAIT:
 		scc->kiss.waittime = VAL; break;
 	case PARAM_MAXKEY:
@@ -1423,97 +1454,6 @@
 	
 }
 
-/* ----> Encode received data and write it to the flip-buffer  <---- */
-
-/* receive raw frame from SCC. used for AX.25 */
-static void
-kiss_encode(register struct scc_channel *scc)
-{
-	struct mbuf *bp,*bp2;
-	struct tty_struct * tty = scc->tty;
-	unsigned long flags; 
-	unsigned char ch;
-
-	if(!scc->rcvq)
-	{
-		scc->stat.rx_kiss_state = KISS_IDLE;
-		return;
-	}
-	
-	/* worst case: FEND 0 FESC TFEND -> 4 bytes */
-	
-	while(tty->flip.count < TTY_FLIPBUF_SIZE-3)
-	{ 
-		if (scc->rcvq->cnt)
-		{
-			bp = scc->rcvq;
-			
-			if (scc->stat.rx_kiss_state == KISS_IDLE)
-			{
-				tty_insert_flip_char(tty, FEND, 0);
-				
-				if (scc->kiss.not_slip)
-					tty_insert_flip_char(tty, 0, 0);
-					
-				scc->stat.rx_kiss_state = KISS_RXFRAME;
-			}
-				
-			switch(ch = bp->data[bp->in_use++])
-			{
-				case FEND:
-					tty_insert_flip_char(tty, FESC, 0);
-					tty_insert_flip_char(tty, TFEND, 0);
-					break;
-				case FESC:
-					tty_insert_flip_char(tty, FESC, 0);
-					tty_insert_flip_char(tty, TFESC, 0);
-					break;
-				default:
-					tty_insert_flip_char(tty, ch, 0);
-			}
-			
-			bp->cnt--;
-			
- 		} else {
-			save_flags(flags); cli();
-			
-			while (!scc->rcvq->cnt)
-	 		{				 /* buffer empty? */
-				bp  = scc->rcvq->next;  /* next buffer */
-				bp2 = scc->rcvq->anext; /* next packet */
-				
-				
-				scc_return_buffer(scc->rcvq, BT_RECEIVE);
-				
-				if (!bp)	/* end of frame ? */
-				{
-					scc->rcvq = bp2;
-					
-					if (--scc->stat.rx_queued < 0)
-						scc->stat.rx_queued = 0;
-					
-					if (scc->stat.rx_kiss_state == KISS_RXFRAME)	/* new packet? */
-					{
-						tty_insert_flip_char(tty, FEND, 0); /* send FEND for old frame */
-						scc->stat.rx_kiss_state = KISS_IDLE; /* generate FEND for new frame */
-					}
-					
-					restore_flags(flags);
-					queue_task(&tty->flip.tqueue, &tq_timer);
-					return;
-					
-				} else scc->rcvq = bp; /* next buffer */
-			}
-			
-			restore_flags(flags);
-		}						
-		
-	}
-	
- 	queue_task(&tty->flip.tqueue, &tq_timer); /* kick it... */
-}
-
-
 /* ******************************************************************* */
 /* *		Init channel structures, special HW, etc...	     * */
 /* ******************************************************************* */
@@ -1523,11 +1463,10 @@
 z8530_init(void)
 {
 	struct scc_channel *scc;
-	int chip,chan;
+	int chip;
 	unsigned long flags;
-    	int k;
 
-	/* reset and pre-init all chips in the system */
+	/* reset all scc chips */
 	for (chip = 0; chip < Nchips; chip++)
 	{
 		/* Special SCC cards */
@@ -1538,30 +1477,25 @@
 		if(Board & (PC100 | PRIMUS))		/* this is a PC100/EAGLE card */
 			Outb(Special_Port,Option);	/* set the MODEM mode (22H normally) */
 			
-		/* Init SCC */
-		
 		scc=&SCC_Info[2*chip];
 		if (!scc->ctrl) continue;
 		
 		save_flags(flags); cli();
 		
-		Outb(scc->ctrl, 0);
-		OutReg(scc->ctrl,R9,FHWRES);		/* force hardware reset */
-		for (k=1; k < 1000; k++) ;
-		
-		for (chan = 0; chan < 2; chan++)
-		{
-			scc=&SCC_Info[2*chip+chan];
-			
-			wr(scc,R1, 0);
-			wr(scc,R2, chip*16);		/* No of chip is vector */
-			wr(scc,R9,VIS);			/* vector includes status */
-		}
+		OutReg(scc->ctrl,R9,FHWRES);	/* force hardware reset */
+		OutReg(scc->ctrl,R9,0);		/* end hardware reset */
+		OutReg(scc->ctrl,R9,CHRA);	/* reset channel A */
+		OutReg(scc->ctrl,R9,CHRB);	/* reset channel B */
+		OutReg(scc->ctrl,R1, 0);	/* No Rx irq from channel A */
+		scc=&SCC_Info[2*chip+1];
+		OutReg(scc->ctrl,R1, 0);	/* No Rx irq from channel B */
+		scc=&SCC_Info[2*chip];
+		OutReg(scc->ctrl,R2, chip*16);	/* Set Interrupt vector */
  
         	restore_flags(flags);
         }
 
-	if (Ivec == 2) Ivec = 9;			/* this f... IBM AT-design! */
+	if (Ivec == 2) Ivec = 9;
 	request_irq(Ivec, scc_isr,   SA_INTERRUPT, "AX.25 SCC");
  
 	Driver_Initialized = 1;
@@ -1613,6 +1547,9 @@
  	scc = &SCC_Info[chan];
  	
 	tty->driver_data = scc;
+        tty->termios->c_iflag = IGNBRK | IGNPAR;
+        tty->termios->c_cflag = B9600 | CS8 | CLOCAL;
+
  	tty->termios->c_cflag &= ~CBAUD; 
  	
 	if (!Driver_Initialized)
@@ -1643,7 +1580,28 @@
 	timer_table[SCC_TIMER].fn = scc_timer;
 	timer_table[SCC_TIMER].expires = 0;	/* now! */
 	timer_active |= 1 << SCC_TIMER;
-	
+
+/*====================new pe1ayx====================
+planed for the new TX routines
+
+	if (!scc->xmit_buf) {
+		scc->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!scc->xmit_buf)
+			return -ENOMEM;
+	}
+
+	scc->xmit_cnt = scc->xmit_head = scc->xmit_tail = 0;
+
+
+====================new pe1ayx end================*/
+
+	if (!tmp_buf) {
+		tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!tmp_buf)
+			return -ENOMEM;
+	}
+
+
 	return 0;
 }
 
@@ -1796,7 +1754,7 @@
 				scc->kiss.softdcd = 0;		   /* hardware dcd */
 			}
 			
-			scc->init = 1;			
+			scc->init = 1;
 			
 			return 0;
 		}
@@ -1821,7 +1779,7 @@
 		
 		restore_flags(flags);
 			
-		put_user(result,(unsigned int *) arg);
+		put_fs_long(result,(unsigned long *) arg);
 		return 0;
 	case TIOCMBIS:
 	case TIOCMBIC:
@@ -1836,7 +1794,7 @@
 			scc->wreg[R5] &= ~RTS;
 			break;
 		case TIOCMSET:
-			value = get_user((unsigned int *) arg);
+			value = get_fs_long((unsigned long *) arg);
 			
 			if(value & TIOCM_DTR)
 				scc->wreg[R5] |= DTR;
@@ -2022,6 +1980,7 @@
 		
 		scc->sndq1->anext = bp;
 	}
+	
 }
 
 
@@ -2031,12 +1990,14 @@
 /* send raw frame to SCC. used for AX.25 */
 int scc_write(struct tty_struct *tty, int from_user, unsigned char *buf, int count)
 {
+	unsigned long flags;
+	static unsigned char *p;
 	struct scc_channel * scc = tty->driver_data;
-	unsigned char tbuf[BUFSIZE], *p;
 	int cnt, cnt2;
-	
-	if (!tty) return count;
-	
+
+	if (!tty || !tmp_buf)
+		return 0;
+		
 	if (scc_paranoia_check(scc, tty->device, "scc_write"))
 		return 0;
 
@@ -2044,31 +2005,43 @@
 	
 	check_tx_queue(scc);
 
+	save_flags(flags);
+
 	cnt2 = count;
 	
 	while (cnt2)
 	{
-		cnt   = cnt2 > BUFSIZE? BUFSIZE:cnt2;
+		cli();
+		cnt   = cnt2 > SERIAL_XMIT_SIZE? SERIAL_XMIT_SIZE:cnt2;
 		cnt2 -= cnt;
 		
-		if (from_user)
-			memcpy_fromfs(tbuf, buf, cnt);
+		if (from_user){
+			down(&tmp_buf_sem);
+			memcpy_fromfs(tmp_buf, buf, cnt);
+			up(&tmp_buf_sem);
+			}
 		else
-			memcpy(tbuf, buf, cnt);
+			memcpy(tmp_buf, buf, cnt);
 		
 		buf += cnt;
 			
-		p=tbuf;
+		p=tmp_buf;
 		
 		while(cnt--) 
 		  if (kiss_decode(scc, *p++))
 		  {
 		  	scc->stat.nospace++;
+		  	restore_flags(flags);
 		  	return 0;
 		  }
 		  	
 	} /* while cnt2 */
-	
+		
+	if ((scc->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) 
+	     && scc->tty->ldisc.write_wakeup)
+		(scc->tty->ldisc.write_wakeup)(scc->tty);
+
+	restore_flags(flags);
 	return count;
 }
 				
@@ -2092,7 +2065,7 @@
 	struct scc_channel *scc = tty->driver_data;
 	
 	scc_paranoia_check(scc, tty->device, "scc_flush_chars"); /* just to annoy the user... */
-	
+
 	return;	/* no flush needed */
 }
 
@@ -2101,7 +2074,7 @@
 static int scc_write_room(struct tty_struct *tty)
 {
 	struct scc_channel *scc = tty->driver_data;
-	
+
 	if (scc_paranoia_check(scc, tty->device, "scc_write_room"))
 		return 0;
 	
@@ -2117,7 +2090,7 @@
 static int scc_chars_in_buffer(struct tty_struct *tty)
 {
 	struct scc_channel *scc = tty->driver_data;
-	
+
 	if (scc && scc->sndq2)
 		return scc->sndq2->cnt;
 	else
@@ -2127,37 +2100,35 @@
 static void scc_flush_buffer(struct tty_struct *tty)
 {
 	struct scc_channel *scc = tty->driver_data;
-	
+
 	if (scc_paranoia_check(scc, tty->device, "scc_flush_buffer"))
 		return;
 		
 	scc->stat.tx_kiss_state = KISS_IDLE;
-	
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+
 }
 
 static void scc_throttle(struct tty_struct *tty)
 {
 	struct scc_channel *scc = tty->driver_data;
-	
+
 	if (scc_paranoia_check(scc, tty->device, "scc_throttle"))
 		return;
 		
 		
 	/* dummy */
+	
 }
 
 static void scc_unthrottle(struct tty_struct *tty)
 {
 	struct scc_channel *scc = tty->driver_data;
-	
+
 	if (scc_paranoia_check(scc, tty->device, "scc_unthrottle"))
 		return;
 		
 	/* dummy */
+	
 }
 
 static void scc_start(struct tty_struct *tty)
@@ -2181,6 +2152,14 @@
 	/* dummy */
 }
 
+void scc_hangup(struct tty_struct *tty)
+{
+	struct scc_channel *scc = tty->driver_data;
+	
+	if (scc_paranoia_check(scc, tty->device, "scc_hangup"))
+		return;
+}
+
 
 /* ******************************************************************** */
 /* * 			Init SCC driver 			      * */
@@ -2188,7 +2167,11 @@
 
 long scc_init (long kmem_start)
 {
-	int chip, chan;
+
+	int chip;
+#ifdef VERBOSE_BOOTMSG
+	int chan;
+#endif	
 	register io_port ctrl;
 	long flags;
 	
@@ -2200,31 +2183,31 @@
         scc_driver.minor_start = 96;
         scc_driver.num = Nchips*2;
         scc_driver.type = TTY_DRIVER_TYPE_SERIAL;
-        scc_driver.subtype = 0;			/* not needed */
+        scc_driver.subtype = SERIAL_TYPE_NORMAL;			/* not needed */
         scc_driver.init_termios = tty_std_termios;
-        scc_driver.init_termios.c_cflag = B9600	| CS8 | CREAD | HUPCL | CLOCAL;
+        scc_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
+        scc_driver.init_termios.c_cflag = B9600	| CS8 | CLOCAL;
         scc_driver.flags = TTY_DRIVER_REAL_RAW;
         scc_driver.refcount = &scc_refcount;	/* not needed yet */
         scc_driver.table = scc_table;
         scc_driver.termios = (struct termios **) scc_termios;
         scc_driver.termios_locked = (struct termios **) scc_termios_locked;
+
         scc_driver.open = scc_open;
         scc_driver.close = scc_close;
         scc_driver.write = scc_write;
-        scc_driver.start = scc_start;
-        scc_driver.stop = scc_stop;
-        
         scc_driver.put_char = scc_put_char;
         scc_driver.flush_chars = scc_flush_chars;        
 	scc_driver.write_room = scc_write_room;
 	scc_driver.chars_in_buffer = scc_chars_in_buffer;
 	scc_driver.flush_buffer = scc_flush_buffer;
-	
+        scc_driver.ioctl = scc_ioctl;
 	scc_driver.throttle = scc_throttle;
 	scc_driver.unthrottle = scc_unthrottle;
-        
-        scc_driver.ioctl = scc_ioctl;
         scc_driver.set_termios = scc_set_termios;
+        scc_driver.stop = scc_stop;
+        scc_driver.start = scc_start;
+        scc_driver.hangup = scc_hangup;
         
         if (tty_register_driver(&scc_driver))
            panic("Couldn't register Z8530 SCC driver\n");
diff -u --recursive --new-file v1.3.10/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v1.3.10/linux/drivers/net/Makefile	Tue Jul 11 10:02:49 1995
+++ linux/drivers/net/Makefile	Fri Jul 14 07:24:58 1995
@@ -42,6 +42,8 @@
 
 ifdef CONFIG_HP100
 NETDRV_OBJS := $(NETDRV_OBJS) hp100.o
+else
+MODULES := $(MODULES) hp100.o
 endif
 
 ifdef CONFIG_WD80x3
diff -u --recursive --new-file v1.3.10/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v1.3.10/linux/drivers/net/hp100.c	Fri Jul  7 08:54:47 1995
+++ linux/drivers/net/hp100.c	Fri Jul 14 07:24:58 1995
@@ -65,6 +65,7 @@
  *      0.11    14-Jun-95   Reset interface bug fixed?
  *			    Little bug in hp100_close function fixed.
  *                          100Mb/s connection debugged.
+ *      0.12    14-Jul-95   Link down is now handled better.
  *
  */
 
@@ -350,12 +351,6 @@
   int ioaddr = dev -> base_addr;
   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 
-  if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) < 0 )
-    {
-      printk( "%s: no connection found - check wire\n", dev -> name );
-      return -EIO;
-    }
-
   if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) )
     {
       printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq );
@@ -372,6 +367,7 @@
   dev -> interrupt = 0;
   dev -> start = 1;
 
+  lp -> lan_type = hp100_sense_lan( dev );
   lp -> mac1_mode = HP100_MAC1MODE3;
   lp -> mac2_mode = HP100_MAC2MODE3;
   
@@ -424,11 +420,11 @@
   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 
   hp100_page( PERFORMANCE );
-  hp100_outw( 0xfefe, IRQ_MASK );		/* mask off all ints */
+  hp100_outw( 0xfefe, IRQ_MASK );		/* mask off all IRQs */
 
-  hp100_stop_interface( dev );			/* relogin */
+  hp100_stop_interface( dev );
 
-  if ( lp -> lan_type == HP100_LAN_100 )
+  if ( lp -> lan_type == HP100_LAN_100 )	/* relogin */
     hp100_login_to_vg_hub( dev );
 
   dev -> tbusy = 1;
@@ -452,6 +448,20 @@
   int ioaddr = dev -> base_addr;
   u_short val;
   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
+
+  if ( lp -> lan_type < 0 )
+    {
+      hp100_stop_interface( dev );
+      if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) < 0 )
+        {
+          printk( "%s: no connection found - check wire\n", dev -> name );
+          hp100_start_interface( dev );	/* 10Mb/s RX packets maybe handled */
+          return -EIO;
+        }
+      if ( lp -> lan_type == HP100_LAN_100 )
+        lp -> hub_status = hp100_login_to_vg_hub( dev );
+      hp100_start_interface( dev );
+    }
   
   if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 )
     {
@@ -463,11 +473,9 @@
  				/* 100Mb/s adapter isn't connected to hub */
         {
           printk( "%s: login to 100Mb/s hub retry\n", dev -> name );
-          hp100_ints_off();
           hp100_stop_interface( dev );
           lp -> hub_status = hp100_login_to_vg_hub( dev );
           hp100_start_interface( dev );
-          hp100_ints_on();
         }
        else
         {
@@ -483,20 +491,16 @@
               /* it's very heavy - all network setting must be changed!!! */
               printk( "%s: cable change 10Mb/s <-> 100Mb/s detected\n", dev -> name );
               lp -> lan_type = i;
-              hp100_ints_off();
               hp100_stop_interface( dev );
               if ( lp -> lan_type == HP100_LAN_100 )
                 lp -> hub_status = hp100_login_to_vg_hub( dev );
               hp100_start_interface( dev );
-              hp100_ints_on();
             }
            else
             {
               printk( "%s: interface reset\n", dev -> name );
-              hp100_ints_off();
               hp100_stop_interface( dev );
               hp100_start_interface( dev );
-              hp100_ints_on();
             }
         }
       dev -> trans_start = jiffies;
@@ -566,6 +570,15 @@
   u_int header;
   struct sk_buff *skb;
 
+#if 0
+  if ( lp -> lan_type < 0 )
+    {
+      if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) == HP100_LAN_100 )
+        lp -> hub_status = hp100_login_to_vg_hub( dev );
+      hp100_page( PERFORMANCE );
+    }
+#endif
+  
   packets = hp100_inb( RX_PKT_CNT );
 #ifdef HP100_DEBUG
   if ( packets > 1 )
@@ -730,6 +743,7 @@
     printk( "%s: re-entering the interrupt handler\n", dev -> name );
   hp100_ints_off();
   dev -> interrupt = 1;
+  hp100_page( PERFORMANCE );
   val = hp100_inw( IRQ_STATUS );
 #ifdef HP100_DEBUG_IRQ
   printk( "hp100_interrupt: irq_status = 0x%x\n", val );
diff -u --recursive --new-file v1.3.10/linux/drivers/net/pi2.c linux/drivers/net/pi2.c
--- v1.3.10/linux/drivers/net/pi2.c	Thu Jul 13 16:20:20 1995
+++ linux/drivers/net/pi2.c	Tue Jul 18 14:53:05 1995
@@ -49,6 +49,7 @@
    April 23, 1995 (dp) Fixed ioctl so it works properly with piconfig program
                        when changing the baud rate or clock mode.
                        version 0.8 ALPHA
+   July 17, 1995 (ac)  Finally polishing of AX25.030+ support
          
 */
 
@@ -59,7 +60,7 @@
    of each transmitted packet. If this causes you to lose sleep, #undefine it.
 */
 
-#define STUFF2 1
+/*#define STUFF2 1*/
 
 /* The default configuration */
 #define PI_DMA 3
@@ -1429,10 +1430,10 @@
     dev->rebuild_header = pi_rebuild_header;
     dev->set_mac_address = pi_set_mac_address;
 
-    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 */
+    dev->type = ARPHRD_AX25;			/* AF_AX25 device */
+    dev->hard_header_len = 73;			/* We do digipeaters now */
+    dev->mtu = 1500;				/* eth_mtu is the default */
+    dev->addr_len = 7;				/* sizeof an ax.25 address */
     memcpy(dev->broadcast, ax25_bcast, 7);
     memcpy(dev->dev_addr, ax25_test, 7);
 
diff -u --recursive --new-file v1.3.10/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v1.3.10/linux/drivers/net/slip.c	Thu Jul 13 16:20:21 1995
+++ linux/drivers/net/slip.c	Tue Jul 18 14:53:05 1995
@@ -36,6 +36,7 @@
  *                                      statistics. Include CSLIP code only
  *                                      if it really needed.
  *		Alan Cox	:	Free slhc buffers in the right place.
+ *		Alan Cox	:	Allow for digipeated IP over AX.25
  *
  *
  *
@@ -1014,7 +1015,7 @@
 #else
 		if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) {
 			sl->dev->addr_len=AX25_ADDR_LEN;	  /* sizeof an AX.25 addr */
-			sl->dev->hard_header_len=AX25_HEADER_LEN; /* We don't do digipeaters */
+			sl->dev->hard_header_len=73; /* We don't do digipeaters */
 		} else	{
 			sl->dev->addr_len=0;	/* No mac addr in slip mode */
 			sl->dev->hard_header_len=0;
Binary files v1.3.10/linux/drivers/scsi/aic7770 and linux/drivers/scsi/aic7770 differ
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v1.3.10/linux/drivers/scsi/aic7xxx.c	Thu Jun 29 19:02:48 1995
+++ linux/drivers/scsi/aic7xxx.c	Tue Jul 18 10:22:02 1995
@@ -3,36 +3,24 @@
  *
  * Copyright (c) 1994 John Aycock
  *   The University of Calgary Department of Computer Science.
- *   All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by the University of Calgary
- *      Department of Computer Science and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * An alternate version of this driver with a BSD-style copyright can
+ * be found on XXX.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
  * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F
  * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA
  * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide,
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/aic7xxx.h linux/drivers/scsi/aic7xxx.h
--- v1.3.10/linux/drivers/scsi/aic7xxx.h	Fri Jul  7 08:54:49 1995
+++ linux/drivers/scsi/aic7xxx.h	Tue Jul 18 10:23:11 1995
@@ -3,36 +3,24 @@
  *
  * Copyright (c) 1994 John Aycock
  *   The University of Calgary Department of Computer Science.
- *   All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by the University of Calgary
- *      Department of Computer Science and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  * 
+ * An alternate version of this driver with a BSD-style copyright can
+ * be found on XXX.    
+ *
  * $Id: aic7xxx.h,v 1.18 1995/06/22 04:17:56 deang Exp $
  *-M*************************************************************************/
 #ifndef _aic7xxx_h
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/aic7xxx_asm.c linux/drivers/scsi/aic7xxx_asm.c
--- v1.3.10/linux/drivers/scsi/aic7xxx_asm.c	Thu Jun 29 19:02:48 1995
+++ linux/drivers/scsi/aic7xxx_asm.c	Tue Jul 18 10:23:11 1995
@@ -3,35 +3,23 @@
  *
  * Copyright (c) 1994 John Aycock
  *   The University of Calgary Department of Computer Science.
- *   All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by the University of Calgary
- *      Department of Computer Science and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * An alternate version of this driver with a BSD-style copyright can
+ * be found on XXX.    
  *
  * Comments are started by `#' and continue to the end of the line; lines
  * may be of the form:
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v1.3.10/linux/drivers/scsi/eata_dma.c	Fri Jun 30 16:22:29 1995
+++ linux/drivers/scsi/eata_dma.c	Sun Jul 16 21:45:00 1995
@@ -1,52 +1,54 @@
 /************************************************************
- *                                                          *
- *                  Linux EATA SCSI driver                  *
- *                                                          *
- *  based on the CAM document CAM/89-004 rev. 2.0c,         *
+ *							    *
+ *		    Linux EATA SCSI driver		    *
+ *							    *
+ *  based on the CAM document CAM/89-004 rev. 2.0c,	    *
  *  DPT's driver kit, some internal documents and source,   *
  *  and several other Linux scsi drivers and kernel docs.   *
- *                                                          *
- *  The driver currently:                                   *
- *      -supports all ISA based EATA-DMA boards             *
- *      -supports all EISA based EATA-DMA boards            *
- *      -supports all PCI based EATA-DMA boards             *
- *      -supports multiple HBAs with & without IRQ sharing  *
- *      -supports all SCSI channels on multi channel boards *
- *      -can be loaded as module                            *
- *      -displays statistical and hardware information      *
- *       in /proc/scsi/eata_dma                             *
- *      -needs identical HBA ids on all channels            * 
- *                                                          *
- *  (c)1993,94,95 Michael Neuffer                           *
- *                neuffer@goofy.zdv.uni-mainz.de            *
- *                                                          *
+ *							    *
+ *  The driver currently:				    *
+ *	-supports all ISA based EATA-DMA boards		    *
+ *	-supports all EISA based EATA-DMA boards	    *
+ *	-supports all PCI based EATA-DMA boards		    *
+ *	-supports multiple HBAs with & without IRQ sharing  *
+ *	-supports all SCSI channels on multi channel boards *
+ *	-needs identical IDs on all channels of a HBA	    * 
+ *	-can be loaded as module			    *
+ *	-displays statistical and hardware information	    *
+ *	 in /proc/scsi/eata_dma				    *
+ *      -provides rudimentary latency measurement           * 
+ *       possibilities via /proc/scsi/eata_dma/<hostnum>    *
+ *							    *
+ *  (c)1993,94,95 Michael Neuffer			    *
+ *		  neuffer@goofy.zdv.uni-mainz.de	    *
+ *							    *
  *  This program is free software; you can redistribute it  *
- *  and/or modify it under the terms of the GNU General     *
- *  Public License as published by the Free Software        *
- *  Foundation; either version 2 of the License, or         *
- *  (at your option) any later version.                     *
- *                                                          *
+ *  and/or modify it under the terms of the GNU General	    *
+ *  Public License as published by the Free Software	    *
+ *  Foundation; either version 2 of the License, or	    *
+ *  (at your option) any later version.			    *
+ *							    *
  *  This program is distributed in the hope that it will be *
- *  useful, but WITHOUT ANY WARRANTY; without even the      *
+ *  useful, but WITHOUT ANY WARRANTY; without even the	    *
  *  implied warranty of MERCHANTABILITY or FITNESS FOR A    *
- *  PARTICULAR PURPOSE.  See the GNU General Public License *
- *  for more details.                                       *
- *                                                          *
- *  You should have received a copy of the GNU General      *
+ *  PARTICULAR PURPOSE.	 See the GNU General Public License *
+ *  for more details.					    *
+ *							    *
+ *  You should have received a copy of the GNU General	    *
  *  Public License along with this kernel; if not, write to *
- *  the Free Software Foundation, Inc., 675 Mass Ave,       *
- *  Cambridge, MA 02139, USA.                               *
- *                                                          *
+ *  the Free Software Foundation, Inc., 675 Mass Ave,	    *
+ *  Cambridge, MA 02139, USA.				    *
+ *							    *
  * I have to thank DPT for their excellent support. I took  *
  * me almost a year and a stopover at their HQ, on my first *
  * trip to the USA, to get it, but since then they've been  *
- * very helpful and tried to give me all the infos and      *
- * support I need.                                          *
- *                                                          *
+ * very helpful and tried to give me all the infos and	    *
+ * support I need.					    *
+ *							    *
  * Thanks also to Greg Hosler who did a lot of testing and  *
- * found quite a number of bugs during the development.     *
+ * found quite a number of bugs during the development.	    *
  ************************************************************
- *  last change: 95/06/28 OS: Linux 1.3.4 + pre1.3 SCSI pat.*
+ *  last change: 95/07/11		   OS: Linux 1.3.9  *
  ************************************************************/
 
 /* Look in eata_dma.h for configuration and revision information */
@@ -205,13 +207,33 @@
 			     eata_stat, hba_stat));
 
 	switch (hba_stat) {
-	case HA_NO_ERROR:       /* NO Error */
+	case HA_NO_ERROR:	/* NO Error */
 	    if (scsi_stat == CONDITION_GOOD
 		&& cmd->device->type == TYPE_DISK
 		&& (HD(cmd)->t_state[cp->cp_channel][cp->cp_id] == RESET))
-		result = DID_BUS_BUSY << 16;        
-	    else if (scsi_stat == GOOD)
+		result = DID_BUS_BUSY << 16;	    
+	    else if (scsi_stat == GOOD) {
 		HD(cmd)->t_state[cp->cp_channel][cp->cp_id] = OK;
+		if(HD(cmd)->do_latency == TRUE && cp->timestamp) {
+		    uint time;
+		    time = jiffies - cp->timestamp;
+		    if((cp->rw_latency) == TRUE) { /* was WRITE */
+			if(HD(cmd)->writes_lat[cp->sizeindex][1] > time)
+			    HD(cmd)->writes_lat[cp->sizeindex][1] = time;
+			if(HD(cmd)->writes_lat[cp->sizeindex][2] < time)
+			    HD(cmd)->writes_lat[cp->sizeindex][2] = time;
+			HD(cmd)->writes_lat[cp->sizeindex][3] += time;
+			HD(cmd)->writes_lat[cp->sizeindex][0]++;
+		    } else {
+			if(HD(cmd)->reads_lat[cp->sizeindex][1] > time)
+			    HD(cmd)->reads_lat[cp->sizeindex][1] = time;
+			if(HD(cmd)->reads_lat[cp->sizeindex][2] < time)
+			    HD(cmd)->reads_lat[cp->sizeindex][2] = time;
+			HD(cmd)->reads_lat[cp->sizeindex][3] += time;
+			HD(cmd)->reads_lat[cp->sizeindex][0]++;
+		    }
+		}
+	    }
 	    else if (scsi_stat == CHECK_CONDITION
 		     && cmd->device->type == TYPE_DISK
 		     && (cmd->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
@@ -220,10 +242,10 @@
 		result = DID_OK << 16;
 	    HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] = OK;
 	    break;
-	case HA_ERR_SEL_TO:     /* Selection Timeout */
+	case HA_ERR_SEL_TO:	/* Selection Timeout */
 	    result = DID_BAD_TARGET << 16;  
 	    break;
-	case HA_ERR_CMD_TO:     /* Command Timeout   */
+	case HA_ERR_CMD_TO:	/* Command Timeout   */
 	    if (HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] > 1)
 		result = DID_ERROR << 16;
 	    else {
@@ -231,8 +253,8 @@
 		HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id]++;
 	    }
 	    break;
-	case HA_ERR_RESET:              /* SCSI Bus Reset Received */
-	case HA_INIT_POWERUP:           /* Initial Controller Power-up */
+	case HA_ERR_RESET:		/* SCSI Bus Reset Received */
+	case HA_INIT_POWERUP:		/* Initial Controller Power-up */
 	    if (cmd->device->type != TYPE_TAPE)
 		result = DID_BUS_BUSY << 16;
 	    else
@@ -241,14 +263,14 @@
 	    for (i = 0; i < MAXTARGET; i++)
 		HD(cmd)->t_state[cp->cp_channel][i] = RESET;
 	    break;
-	case HA_UNX_BUSPHASE:       /* Unexpected Bus Phase */
-	case HA_UNX_BUS_FREE:       /* Unexpected Bus Free */
-	case HA_BUS_PARITY:         /* Bus Parity Error */
-	case HA_SCSI_HUNG:          /* SCSI Hung */
-	case HA_UNX_MSGRJCT:        /* Unexpected Message Reject */
-	case HA_RESET_STUCK:        /* SCSI Bus Reset Stuck */
-	case HA_RSENSE_FAIL:        /* Auto Request-Sense Failed */
-	case HA_PARITY_ERR:         /* Controller Ram Parity */
+	case HA_UNX_BUSPHASE:	    /* Unexpected Bus Phase */
+	case HA_UNX_BUS_FREE:	    /* Unexpected Bus Free */
+	case HA_BUS_PARITY:	    /* Bus Parity Error */
+	case HA_SCSI_HUNG:	    /* SCSI Hung */
+	case HA_UNX_MSGRJCT:	    /* Unexpected Message Reject */
+	case HA_RESET_STUCK:	    /* SCSI Bus Reset Stuck */
+	case HA_RSENSE_FAIL:	    /* Auto Request-Sense Failed */
+	case HA_PARITY_ERR:	    /* Controller Ram Parity */
 	default:
 	    result = DID_ERROR << 16;
 	    break;
@@ -267,7 +289,7 @@
 	DBG(DBG_INTR&&DBG_DELAY,DEL2(800));
 #endif
 	
-	cp->status = FREE;          /* now we can release the slot  */
+	cp->status = FREE;	    /* now we can release the slot  */
 	
 	restore_flags(flags);
 	if(cmd->scsi_done != eata_scsi_done) cmd->scsi_done(cmd);
@@ -291,7 +313,7 @@
 	if (--loop == 0)
 	    return(FALSE);
     
-    outb( addr & 0x000000ff,        base + HA_WDMAADDR);
+    outb( addr & 0x000000ff,	    base + HA_WDMAADDR);
     outb((addr & 0x0000ff00) >> 8,  base + HA_WDMAADDR + 1);
     outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
     outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3);
@@ -304,8 +326,8 @@
 			       u8 lun)
 {
     if(addr){
-	outb( addr & 0x000000ff,        base + HA_WDMAADDR);
-	outb((addr & 0x0000ff00) >> 8,  base + HA_WDMAADDR + 1);
+	outb( addr & 0x000000ff,	base + HA_WDMAADDR);
+	outb((addr & 0x0000ff00) >> 8,	base + HA_WDMAADDR + 1);
 	outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
 	outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3);
     } else {
@@ -314,7 +336,7 @@
     }
     
     outb(cmnd2, base + HA_WCOMMAND2);
-    outb(cmnd,  base + HA_WCOMMAND);
+    outb(cmnd,	base + HA_WCOMMAND);
     return(TRUE);
 }
 #endif
@@ -327,10 +349,10 @@
     struct Scsi_Host *sh;
     struct eata_ccb *cp;
     struct scatterlist *sl;
-
+    
     save_flags(flags);
     cli();
-
+    
     queue_counter++;
     
     if (done == (void *)eata_scsi_done) { 
@@ -354,61 +376,93 @@
     hd->last_ccb = y;
     
     if (x == sh->can_queue) { 
-	
 	DBG(DBG_QUEUE, printk("can_queue %d, x %d, y %d\n", 
 			      sh->can_queue, x, y));
-#if DEBUG_EATA
+	
 	panic("eata_dma: run out of queue slots cmdno:%ld intrno: %ld\n", 
 	      queue_counter, int_counter);
-#else
-	panic("eata_dma: run out of queue slots....\n");
-#endif
     }
     
     cp = &hd->ccb[y];
     
     memset(cp, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *));
     
-    cp->status = USED;      /* claim free slot */
+    cp->status = USED;			/* claim free slot */
     
     DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n",
 			  cmd->pid, cmd->target, cmd->lun, y));
     DBG(DBG_QUEUE && DBG_DELAY, DEL2(250));
+    
+    if(hd->do_latency == TRUE) {
+	int x, z;
+	short *sho;
+	long *lon;
+	x = 0;	/* just to keep GCC quiet */ 
+	if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 || 
+	    cmd->cmnd[0] == WRITE_12 || cmd->cmnd[0] == READ_6 || 
+	    cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == READ_12) {
+	    
+	    cp->timestamp = jiffies;	/* For latency measurements */
+	    switch(cmd->cmnd[0]) {
+	    case WRITE_6:   
+	    case READ_6:    
+		x = cmd->cmnd[4]/2; 
+		break;
+	    case WRITE_10:   
+	    case READ_10:
+		sho = (short *) &cmd->cmnd[7];
+		x = ntohs(*sho)/2;	      
+		break;
+	    case WRITE_12:   
+	    case READ_12:
+		lon = (long *) &cmd->cmnd[6];
+		x = ntohl(*lon)/2;	      
+		break;
+	    }
+	    for(z = 0; z <= 11, x > (1 << z); z++) 
+		/* nothing */;
+	    cp->sizeindex = z;
+	    if (cmd->cmnd[0] ==	WRITE_6 || cmd->cmnd[0] == WRITE_10 || 
+		cmd->cmnd[0] ==	WRITE_12){
+		cp->rw_latency = TRUE;
+	    }
+	}
+    }
     cmd->scsi_done = (void *)done;
     
     switch (cmd->cmnd[0]) {
-    case CHANGE_DEFINITION: case COMPARE:         case COPY:
-    case COPY_VERIFY:       case LOG_SELECT:      case MODE_SELECT:
+    case CHANGE_DEFINITION: case COMPARE:	  case COPY:
+    case COPY_VERIFY:	    case LOG_SELECT:	  case MODE_SELECT:
     case MODE_SELECT_10:    case SEND_DIAGNOSTIC: case WRITE_BUFFER:
-    case FORMAT_UNIT:       case REASSIGN_BLOCKS: case RESERVE:
-    case SEARCH_EQUAL:      case SEARCH_HIGH:     case SEARCH_LOW:
-    case WRITE_6:           case WRITE_10:        case WRITE_VERIFY:
-    case UPDATE_BLOCK:      case WRITE_LONG:      case WRITE_SAME:      
+    case FORMAT_UNIT:	    case REASSIGN_BLOCKS: case RESERVE:
+    case SEARCH_EQUAL:	    case SEARCH_HIGH:	  case SEARCH_LOW:
+    case WRITE_6:	    case WRITE_10:	  case WRITE_VERIFY:
+    case UPDATE_BLOCK:	    case WRITE_LONG:	  case WRITE_SAME:	
     case SEARCH_HIGH_12:    case SEARCH_EQUAL_12: case SEARCH_LOW_12:
-    case WRITE_12:          case WRITE_VERIFY_12: case SET_WINDOW: 
-    case MEDIUM_SCAN:       case SEND_VOLUME_TAG:            
-    case 0xea:      /* alternate number for WRITE LONG */
-	cp->DataOut = TRUE;     /* Output mode */
+    case WRITE_12:	    case WRITE_VERIFY_12: case SET_WINDOW: 
+    case MEDIUM_SCAN:	    case SEND_VOLUME_TAG:	     
+    case 0xea:	    /* alternate number for WRITE LONG */
+	cp->DataOut = TRUE;	/* Output mode */
 	break;
     case TEST_UNIT_READY:
     default:
-	cp->DataIn = TRUE;      /* Input mode  */
+	cp->DataIn = TRUE;	/* Input mode  */
     }
     
     if ((done == (void *) eata_scsi_done && HBA_interpret == TRUE) 
 	|| cmd->target == sh->this_id) 
-	cp->Interpret = TRUE;   /* Interpret command */
+	cp->Interpret = TRUE;	/* Interpret command */
     
     if (cmd->use_sg) {
-	cp->scatter = TRUE;     /* SG mode     */
+	cp->scatter = TRUE;	/* SG mode     */
 	if (cp->sg_list == NULL) {
 	    cp->sg_list = kmalloc(SG_SIZE_BIG*sizeof(struct eata_sg_list),
-				     GFP_ATOMIC | GFP_DMA);
+				  GFP_ATOMIC | GFP_DMA);
 	}
 	cp->cp_dataDMA = htonl((ulong)cp->sg_list); 
 	if (cp->cp_dataDMA == 0)
 	    panic("eata_dma: Run out of DMA memory for SG lists !\n");
-
+	
 	cp->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list));
 	sl=(struct scatterlist *)cmd->request_buffer;
 	for(i = 0; i < cmd->use_sg; i++, sl++){
@@ -436,7 +490,7 @@
     
     cp->cp_viraddr = cp;
     cp->cmd = cmd;
-    cmd->host_scribble = (char *)&hd->ccb[y];   
+    cmd->host_scribble = (char *)&hd->ccb[y];	
     
     if(eata_send_command((u32) cp, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) {
 	cmd->result = DID_ERROR << 16;
@@ -563,7 +617,7 @@
     }
     
     /* hard reset the HBA  */
-    inb((u32) (cmd->host->base) + HA_RSTATUS);  /* This might cause trouble */
+    inb((u32) (cmd->host->base) + HA_RSTATUS);	/* This might cause trouble */
     eata_send_command(0, (u32) cmd->host->base, EATA_CMD_RESET);
     
     DBG(DBG_ABNORM, printk("eata_reset: board reset done, enabling interrupts.\n"));
@@ -572,7 +626,7 @@
     restore_flags(flags);
     
     time = jiffies;
-    while (jiffies < (time + 300) && limit++ < 10000000)
+    while (jiffies < (time + (3 * HZ)) && limit++ < 10000000)
 	/* nothing */;
     
     save_flags(flags);
@@ -635,7 +689,7 @@
     memset(sp, 0, sizeof(struct eata_sp));
     memset(buff, 0, 256);
 
-    cp->DataIn = TRUE;     
+    cp->DataIn = TRUE;	   
     cp->Interpret = TRUE;   /* Interpret command */
  
     cp->cp_datalen = htonl(255);  
@@ -659,7 +713,7 @@
 
     eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP);
     
-    i = jiffies + 300;
+    i = jiffies + (3 * HZ) ;
     while (fake_int_result == FALSE && jiffies <= i) 
 	barrier();
     
@@ -676,7 +730,7 @@
 	inb((u32) (base) + HA_RSTATUS);
 	eata_send_command(0, base, EATA_CMD_RESET);
 	i = jiffies;
-	while (jiffies < (i + 300) && limit++ < 10000000)
+	while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
 	    barrier();
 	return (NULL);
     } else
@@ -734,7 +788,7 @@
 	*p = inw(base + HA_RDATA);
     }
 
-    if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {            /* Error ? */
+    if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {	    /* Error ? */
 	if (htonl(EATA_SIGNATURE) == buf->signature) {
 	    DBG(DBG_PIO&&DBG_PROBE, printk("EATA Controller found at %x "
 					   "EATA Level: %x\n", (uint) base, 
@@ -767,7 +821,7 @@
 	   gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN); 
     printk("RIDQ:%d PCI:%d EISA:%d\n",
 	   gc->ID_qest, gc->is_PCI, gc->is_EISA);
-    DBG(DPT_DEBUG, DELAY(1400));
+    DBG(DPT_DEBUG, DELAY(14));
 }
 
 short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, 
@@ -779,6 +833,7 @@
     unchar bugs = 0;
     struct Scsi_Host *sh;
     hostdata *hd;
+    int x;
     
     
     DBG(DBG_REGISTER, print_config(gc));
@@ -792,7 +847,7 @@
     if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22) 
 	gc->MAX_CHAN = 0;
     
-    if (reg_IRQ[gc->IRQ] == FALSE) {    /* Interrupt already registered ? */
+    if (reg_IRQ[gc->IRQ] == FALSE) {	/* Interrupt already registered ? */
 	if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT,
 			 "eata_dma")){
 	    reg_IRQ[gc->IRQ]++;
@@ -802,7 +857,7 @@
 	    printk("Couldn't allocate IRQ %d, Sorry.", gc->IRQ);
 	    return (FALSE);
 	}
-    } else {            /* More than one HBA on this IRQ */
+    } else {		/* More than one HBA on this IRQ */
 	if (reg_IRQL[gc->IRQ] == TRUE) {
 	    printk("Can't support more than one HBA on this IRQ,\n"
 		   "  if the IRQ is edge triggered. Sorry.\n");
@@ -861,7 +916,7 @@
     if(ntohs(gc->queuesiz) == 0) {
 	gc->queuesiz = ntohs(64);
 	printk("Warning: Queue size has to be corrected. Assuming 64 queueslots\n"
-	       "         This might be a PM2012B with a defective Firmware\n");
+	       "	 This might be a PM2012B with a defective Firmware\n");
     }
 
     size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long)) 
@@ -883,7 +938,7 @@
 	return (FALSE);
     }
     
-    hd = SD(sh);                   
+    hd = SD(sh);		   
     
     memset(hd->ccb, 0, sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
     memset(hd->reads, 0, sizeof(u32) * 26); 
@@ -894,7 +949,7 @@
 	strcpy(SD(sh)->vendor, "DPT");
 	strcpy(SD(sh)->name, "??????????");
 	strcpy(SD(sh)->revision, "???.?");
-    } else {    
+    } else {	
 	strncpy(SD(sh)->vendor, &buff[8], 8);
 	SD(sh)->vendor[8] = 0;
 	strncpy(SD(sh)->name, &buff[16], 17);
@@ -918,7 +973,7 @@
 	SD(sh)->EATA_revision = 'c';
 	break;
     case 0x24:
-	SD(sh)->EATA_revision = 'z';            
+	SD(sh)->EATA_revision = 'z';		
     default:
 	SD(sh)->EATA_revision = '?';
     }
@@ -948,7 +1003,7 @@
 	sh->max_lun = 8;
     }
 
-    hd->channel = gc->MAX_CHAN;     
+    hd->channel = gc->MAX_CHAN;	    
     sh->max_channel = gc->MAX_CHAN; 
     sh->base = (char *) base;
     sh->io_port = (u16) base;
@@ -960,7 +1015,7 @@
      * SCSI midlevel code should support different HBA ids on every channel
      */
     sh->this_id = gc->scsi_id[3];
-    sh->can_queue = ntohs(gc->queuesiz);
+    sh->can_queue = ntohs(gc->queuesiz) - 1; /* Keep one free for internals */
     
     if (gc->OCS_enabled == TRUE) 
 	if(hd->bustype != IS_ISA)
@@ -997,15 +1052,20 @@
     else
 	hd->primary = TRUE;
     
-    sh->wish_block = FALSE;        
+    sh->wish_block = FALSE;	   
     
     if (hd->bustype != IS_ISA) {
 	sh->unchecked_isa_dma = FALSE;
     } else {
-	sh->unchecked_isa_dma = TRUE;   /* We're doing ISA DMA */
+	sh->unchecked_isa_dma = TRUE;	/* We're doing ISA DMA */
     }
     
-    hd->next = NULL;    /* build a linked list of all HBAs */
+    for(x = 0; x <= 11; x++){		 /* Initialize min. latency */
+	hd->writes_lat[x][1] = 0xffffffff;
+	hd->reads_lat[x][1] = 0xffffffff;
+    }
+
+    hd->next = NULL;	/* build a linked list of all HBAs */
     hd->prev = last_HBA;
     if(hd->prev != NULL)
 	SD(hd->prev)->next = sh;
@@ -1028,7 +1088,7 @@
 #endif
     
     for (i = 0; i < MAXEISA; i++) {
-	if (EISAbases[i] == TRUE) { /* Still a possibility ?          */
+	if (EISAbases[i] == TRUE) { /* Still a possibility ?	      */
 	    
 	    base = 0x1c88 + (i * 0x1000);
 #if CHECKPAL
@@ -1090,7 +1150,7 @@
 #else
     
     u8 pci_bus, pci_device_fn;
-    static s16 pci_index = 0;   /* Device index to PCI BIOS calls */
+    static s16 pci_index = 0;	/* Device index to PCI BIOS calls */
     u32 base = 0;
     u16 com_adr;
     u16 rev_device;
@@ -1142,8 +1202,8 @@
 		    if (base != 0x1f8) {
 			/* We didn't find it in the primary search */
 			if (get_conf_PIO(base, buf) == TRUE) {
-			    if (buf->FORCADR)   /* If the address is forced */
-				continue;       /* we'll find it later      */
+			    if (buf->FORCADR)	/* If the address is forced */
+				continue;	/* we'll find it later	    */
 			    
 			    /* OK. We made it till here, so we can go now  
 			     * and register it. We  only have to check and 
@@ -1177,7 +1237,7 @@
     } else
 	printk("eata_dma: No BIOS32 extensions present. This driver release "
 	       "still depends on it.\n"
-               "          Skipping scan for PCI HBAs. \n");
+	       "	  Skipping scan for PCI HBAs. \n");
 #endif /* #ifndef CONFIG_PCI */
     return;
 }
@@ -1210,14 +1270,14 @@
     
     if (registered_HBAs != 0) {
 	printk("EATA (Extended Attachment) driver version: %d.%d%s\n"
-	       "developed in co-operation with DPT\n"             
+	       "developed in co-operation with DPT\n"		  
 	       "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n",
 	       VER_MAJOR, VER_MINOR, VER_SUB);
 	printk("Registered HBAs:");
 	printk("\nHBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: DMA: Ch: "
 	       "ID: Pr: QS: SG: CPL:\n");
 	for (i = 1; i <= registered_HBAs; i++) {
-	    printk("scsi%-2d: %.10s v%s 2.0%c  %s %#.4x   %2d",
+	    printk("scsi%-2d: %.10s v%s 2.0%c  %s %#.4x	  %2d",
 		   HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
 		   SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? 
 		   "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
@@ -1226,7 +1286,7 @@
 		printk("   %2x ", HBA_ptr->dma_channel);
 	    else
 		printk("  %s", "BMST");
-	    printk("  %d   %d   %c  %2d  %2d   %2d\n", SD(HBA_ptr)->channel, 
+	    printk("  %d   %d	%c  %2d	 %2d   %2d\n", SD(HBA_ptr)->channel, 
 		   HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N', 
 		   HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
 	    HBA_ptr = SD(HBA_ptr)->next;
@@ -1237,7 +1297,7 @@
 
     scsi_init_free((void *)dma_scratch, 512);
 
-    DBG(DPT_DEBUG, DELAY(1200));
+    DBG(DPT_DEBUG, DELAY(12));
 
     return(registered_HBAs);
 }
@@ -1262,7 +1322,6 @@
  * c-label-offset: -4
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
  * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_dma.h linux/drivers/scsi/eata_dma.h
--- v1.3.10/linux/drivers/scsi/eata_dma.h	Fri Jun 30 16:22:29 1995
+++ linux/drivers/scsi/eata_dma.h	Sun Jul 16 21:45:00 1995
@@ -16,7 +16,7 @@
 
 #define VER_MAJOR 2
 #define VER_MINOR 5
-#define VER_SUB   "6a"
+#define VER_SUB   "7a"
 
 
 /************************************************************************
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_dma_proc.c linux/drivers/scsi/eata_dma_proc.c
--- v1.3.10/linux/drivers/scsi/eata_dma_proc.c	Tue Jul 11 10:02:50 1995
+++ linux/drivers/scsi/eata_dma_proc.c	Sun Jul 16 21:45:00 1995
@@ -4,11 +4,11 @@
 {
     "Direct-Access    ",
     "Sequential-Access",
-    "Printer          ",
-    "Processor        ",
-    "WORM             ",
-    "CD-ROM           ",
-    "Scanner          ",
+    "Printer	      ",
+    "Processor	      ",
+    "WORM	      ",
+    "CD-ROM	      ",
+    "Scanner	      ",
     "Optical Device   ",
     "Medium Changer   ",
     "Communications   "
@@ -47,8 +47,24 @@
  */
 int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr)
 {
-    DBG(DBG_PROC_WRITE, printk("%s\n", buffer));
-    return(-ENOSYS);  /* Currently this is a no-op */
+    if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) {
+        buffer += 9;
+        length -= 9;
+        if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
+            SD(HBA_ptr)->do_latency = TRUE;
+            return(length+9);
+        } 
+        
+        if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
+            SD(HBA_ptr)->do_latency = FALSE;
+            return(length+9);
+        } 
+        
+        printk("Unknown command:%s length: %d\n", buffer, length);
+    } else 
+        printk("Wrong Signature:%10s\n", (char *) ((ulong)buffer-9));
+    
+    return(-EINVAL);
 }
 
 /*
@@ -72,19 +88,19 @@
     static u8 buff[512];
     static u8 buff2[512];
     hst_cmd_stat *rhcs, *whcs;
-    coco         *cc;
-    scsitrans    *st;
-    scsimod      *sm;
-    hobu         *hb;
-    scbu         *sb;
-    boty         *bt;
-    memco        *mc;
-    firm         *fm;
-    subinf       *si; 
-    pcinf        *pi;
-    arrlim       *al;
+    coco	 *cc;
+    scsitrans	 *st;
+    scsimod	 *sm;
+    hobu	 *hb;
+    scbu	 *sb;
+    boty	 *bt;
+    memco	 *mc;
+    firm	 *fm;
+    subinf	 *si; 
+    pcinf	 *pi;
+    arrlim	 *al;
     int i, x; 
-    int   size, len = 0;
+    int	  size, len = 0;
     off_t begin = 0;
     off_t pos = 0;
 
@@ -327,7 +343,7 @@
 		       SD(HBA_ptr)->writes[11]);
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer+len,"Sum	 :%12u %12u\n",
+	size = sprintf(buffer+len,"Sum   : %12u %12u\n",
 		       SD(HBA_ptr)->reads[12], 
 		       SD(HBA_ptr)->writes[12]);
 	len += size; 
@@ -341,6 +357,79 @@
     if (pos > offset + length)
 	goto stop_output;
 
+    if(SD(HBA_ptr)->do_latency == TRUE) {
+	size = sprintf(buffer + len, "Host Latency Command Statistics:\n"
+                       "Current timer resolution: 10ms\n"
+		       "	 Reads:	      Min:(ms)     Max:(ms)     Ave:(ms)\n");
+	len += size; 
+	pos = begin + len;
+	for (x = 0; x <= 10; x++) {
+	    size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
+                           1 << x,
+			   SD(HBA_ptr)->reads_lat[x][0], 
+			   (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff) 
+                           ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10), 
+			   SD(HBA_ptr)->reads_lat[x][2] * 10, 
+			   SD(HBA_ptr)->reads_lat[x][3] * 10 /
+                           ((SD(HBA_ptr)->reads_lat[x][0])
+                            ? SD(HBA_ptr)->reads_lat[x][0]:1));
+	    len += size; 
+	    pos = begin + len;
+	}
+	size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
+			   SD(HBA_ptr)->reads_lat[11][0], 
+			   (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
+                           ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10), 
+			   SD(HBA_ptr)->reads_lat[11][2] * 10, 
+			   SD(HBA_ptr)->reads_lat[11][3] * 10 /
+                           ((SD(HBA_ptr)->reads_lat[x][0])
+                            ? SD(HBA_ptr)->reads_lat[x][0]:1));
+	len += size; 
+	pos = begin + len;
+
+        if (pos < offset) {
+            len = 0;
+            begin = pos;
+        }
+        if (pos > offset + length)
+            goto stop_output;
+
+	size = sprintf(buffer + len,
+		       "	 Writes:      Min:(ms)     Max:(ms)     Ave:(ms)\n");
+	len += size; 
+	pos = begin + len;
+	for (x = 0; x <= 10; x++) {
+	    size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
+                           1 << x,
+			   SD(HBA_ptr)->writes_lat[x][0], 
+			   (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
+                           ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
+			   SD(HBA_ptr)->writes_lat[x][2] * 10, 
+			   SD(HBA_ptr)->writes_lat[x][3] * 10 /
+                           ((SD(HBA_ptr)->writes_lat[x][0])
+                            ? SD(HBA_ptr)->writes_lat[x][0]:1));
+	    len += size; 
+	    pos = begin + len;
+	}
+	size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
+			   SD(HBA_ptr)->writes_lat[11][0], 
+			   (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
+                           ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
+			   SD(HBA_ptr)->writes_lat[11][2] * 10, 
+			   SD(HBA_ptr)->writes_lat[11][3] * 10/
+                           ((SD(HBA_ptr)->writes_lat[x][0])
+                            ? SD(HBA_ptr)->writes_lat[x][0]:1));
+	len += size; 
+	pos = begin + len;
+
+        if (pos < offset) {
+            len = 0;
+            begin = pos;
+        }
+        if (pos > offset + length)
+            goto stop_output;
+    }
+
     scd = scsi_devices;
     
     size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
@@ -350,7 +439,8 @@
     while (scd) {
 	if (scd->host == HBA_ptr) {
 	    
-	    size = sprintf(buffer + len, "Channel: %02d Id: %02d Lun: %02d\n  Vendor: ",
+	    size = sprintf(buffer + len, 
+                           "Channel: %02d Id: %02d Lun: %02d\n  Vendor: ",
 			   scd->channel, scd->id, scd->lun);
 	    for (x = 0; x < 8; x++) {
 		if (scd->vendor[x] >= 0x20)
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_generic.h linux/drivers/scsi/eata_generic.h
--- v1.3.10/linux/drivers/scsi/eata_generic.h	Fri Jun 30 16:22:29 1995
+++ linux/drivers/scsi/eata_generic.h	Sun Jul 16 21:45:00 1995
@@ -51,19 +51,19 @@
 #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. 
-	       */
+			   * 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
@@ -77,7 +77,7 @@
 #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 DELAY(x) { __u32 i; i = jiffies + (x * HZ); while (jiffies < i) barrier(); }
 #define DEL2(x)	 { __u32 i; for (i = 0; i < 0xffff * x; i++); }
 
 /***********************************************
@@ -189,9 +189,9 @@
     __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			*/
 };
@@ -200,48 +200,48 @@
     __u32  len;		      /* Should return 0x22, 0x24, etc		*/
     __u32 signature;	      /* Signature MUST be "EATA"		*/
     __u8    version2:4,
-	 version:4;	  /* EATA Version level			    */
+	     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		    */
+	 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			    */
+    __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	    */	
+	 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 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;
+	 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	    */
+	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			    */
+	 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]; 
 };
 
@@ -253,60 +253,62 @@
 
 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 timestamp;	      /* Needed to measure command latency	*/
     __u32 timeout;
+    __u8 sizeindex;
+    __u8 rw_latency;
     __u8 retries;
-    __u8 status;	      /* status of this queueslot	*/
-
-    Scsi_Cmnd *cmd;	      /* address of cmd			*/
+    __u8 status;	      /* status of this queueslot		*/
+    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];
 };
 
@@ -320,12 +322,15 @@
     __u8   state;		 /* state of HBA	       */
     __u8   primary;		 /* true if primary	       */
     __u8   broken_INQUIRY:1;	 /* This is an EISA HBA with   *
-		  * broken INQUIRY	       */
+				  * broken INQUIRY	       */
+    __u8   do_latency;		 /* Latency measurement flag   */
     __u32  reads[13];
     __u32  writes[13];
-		 /* state of Target (RESET,..) */
+    __u32  reads_lat[12][4];
+    __u32  writes_lat[12][4];
+				 /* 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	       */
@@ -372,7 +377,6 @@
  * c-label-offset: -4
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
  * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c
--- v1.3.10/linux/drivers/scsi/eata_pio.c	Fri Jun 30 16:22:29 1995
+++ linux/drivers/scsi/eata_pio.c	Sun Jul 16 21:45:00 1995
@@ -32,7 +32,7 @@
  *  Cambridge, MA 02139, USA.                               *
  *                                                          *
  ************************************************************
- *  last change: 95/06/20 OS: Linux 1.3.3 + pre1.3 SCSI pat.*
+ *  last change: 95/07/13                  OS: Linux 1.3.9  *
  ************************************************************/
 
 /* Look in eata_pio.h for configuration information */
@@ -504,7 +504,7 @@
     HD(cmd)->state = RESET;
     
     time = jiffies;
-    while (jiffies < (time + 300) && limit++ < 10000000);
+    while (jiffies < (time + (3 * HZ)) && limit++ < 10000000);
     
     DBG(DBG_ABNORM, printk("eata_pio_reset: interrupts disabled, loops %d.\n", limit));
     DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
@@ -650,7 +650,7 @@
     printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n",
 	   gc->IRQ, gc->IRQ_TR, gc->FORCADR, 
 	   gc->MAX_CHAN, gc->ID_qest);
-    DBG(DPT_DEBUG, DELAY(1400));
+    DBG(DPT_DEBUG, DELAY(14));
 }
 
 static uint print_selftest(uint base)
@@ -1014,7 +1014,7 @@
 	    HBA_ptr = SD(HBA_ptr)->next;
 	}
     }
-    DBG(DPT_DEBUG,DELAY(1200));
+    DBG(DPT_DEBUG,DELAY(12));
     
     return (registered_HBAs);
 }
diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.3.10/linux/drivers/scsi/scsi.h	Tue Jul 11 10:02:50 1995
+++ linux/drivers/scsi/scsi.h	Sun Jul 16 21:45:00 1995
@@ -80,6 +80,7 @@
 #define LOG_SENSE             0x4d
 #define MODE_SELECT_10        0x55
 #define MODE_SENSE_10         0x5a
+#define READ_12               0xa8
 #define WRITE_12              0xaa
 #define WRITE_VERIFY_12       0xae
 #define SEARCH_HIGH_12        0xb0
diff -u --recursive --new-file v1.3.10/linux/drivers/sound/ics2101.c linux/drivers/sound/ics2101.c
--- v1.3.10/linux/drivers/sound/ics2101.c	Tue Jul 11 10:02:53 1995
+++ linux/drivers/sound/ics2101.c	Sun Jul 16 21:12:04 1995
@@ -30,7 +30,7 @@
 #include "sound_config.h"
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
 
-#include "ultrasound.h"
+#include <linux/ultrasound.h>
 #include "gus_hw.h"
 
 #define MIX_DEVS	(SOUND_MASK_MIC|SOUND_MASK_LINE| \
diff -u --recursive --new-file v1.3.10/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v1.3.10/linux/fs/nfs/inode.c	Mon Jun 12 16:49:41 1995
+++ linux/fs/nfs/inode.c	Tue Jul 18 14:53:16 1995
@@ -7,6 +7,10 @@
  *
  *  Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some
  *  experimental NFS changes. Modularisation taken straight from SYS5 fs.
+ *
+ *  Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
+ *  J.S.Peatfield@damtp.cam.ac.uk
+ *
  */
 
 #ifdef MODULE
@@ -76,6 +80,7 @@
 	struct nfs_server *server;
 	unsigned int fd;
 	struct file *filp;
+
 	dev_t dev = sb->s_dev;
 
 	MOD_INC_USE_COUNT;
@@ -104,6 +109,7 @@
 	}
 	filp->f_count++;
 	lock_super(sb);
+
 	sb->s_blocksize = 1024; /* XXX */
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = NFS_SUPER_MAGIC;
@@ -131,6 +137,31 @@
 	server->acdirmin = data->acdirmin*HZ;
 	server->acdirmax = data->acdirmax*HZ;
 	strcpy(server->hostname, data->hostname);
+
+	/* Start of JSP NFS patch */
+	/* Check if passed address in data->addr */
+	if (data->addr.sin_addr.s_addr == INADDR_ANY) {  /* No address passed */
+	  if (((struct sockaddr_in *)(&server->toaddr))->sin_addr.s_addr == INADDR_ANY) {
+	    printk("NFS: Error passed unconnected socket and no address\n") ;
+	    return NULL ;
+	  } else {
+	    /* Need access to socket internals  JSP */
+	    struct socket *sock;
+	    int dummylen ;
+
+	 /*   printk("NFS: using socket address\n") ;*/
+
+	    sock = &((filp->f_inode)->u.socket_i);
+
+	    /* extract the other end of the socket into server->toaddr */
+	    sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ;
+	  }
+	} else {
+	/*  printk("NFS: coppying passed addr to server->toaddr\n") ;*/
+	  memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr));
+	}
+	/* End of JSP NFS patch */
+
 	sb->u.nfs_sb.s_root = data->root;
 	unlock_super(sb);
 	if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
diff -u --recursive --new-file v1.3.10/linux/fs/nfs/sock.c linux/fs/nfs/sock.c
--- v1.3.10/linux/fs/nfs/sock.c	Tue Feb  7 11:43:23 1995
+++ linux/fs/nfs/sock.c	Tue Jul 18 14:53:16 1995
@@ -102,7 +102,10 @@
 	fs = get_fs();
 	set_fs(get_ds());
 	for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {
-		result = sock->ops->send(sock, (void *) start, len, 0, 0);
+	  /* JSP 1995-07-01  Use sendto() not send() to cope with multi-homed hosts
+	     as we have set the socket to have INADDR_ANY as it's desination */
+		result = sock->ops->sendto(sock, (void *) start, len, 0, 0,
+					   &(server->toaddr), sizeof((server->toaddr))) ;
 		if (result < 0) {
 			printk("nfs_rpc_call: send error = %d\n", result);
 			break;
diff -u --recursive --new-file v1.3.10/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v1.3.10/linux/include/asm-alpha/system.h	Tue Jun 27 14:11:44 1995
+++ linux/include/asm-alpha/system.h	Tue Jul 18 14:45:58 1995
@@ -85,7 +85,7 @@
 #define save_flags(flags)	do { flags = getipl(); } while (0)
 #define restore_flags(flags)	setipl(flags)
 
-extern inline unsigned long xchg_u32(int * m, unsigned long val)
+extern inline unsigned long xchg_u32(volatile int * m, unsigned long val)
 {
 	unsigned long dummy, dummy2;
 
@@ -100,7 +100,7 @@
 	return val;
 }
 
-extern inline unsigned long xchg_u64(long * m, unsigned long val)
+extern inline unsigned long xchg_u64(volatile long * m, unsigned long val)
 {
 	unsigned long dummy, dummy2;
 
@@ -115,9 +115,19 @@
 	return val;
 }
 
-extern inline void * xchg_ptr(void *m, void *val)
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
-	return (void *) xchg_u64((long *) m, (unsigned long) val);
+	switch (size) {
+		case 4:
+			return xchg_u32(ptr, x);
+		case 8:
+			return xchg_u64(ptr, x);
+	}
+	printk("Argh.. xchg() with unsupported size\n");
+	return x;
 }
 
 #endif /* __ASSEMBLY__ */
diff -u --recursive --new-file v1.3.10/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- v1.3.10/linux/include/asm-alpha/unistd.h	Fri Jun 16 22:02:55 1995
+++ linux/include/asm-alpha/unistd.h	Sun Jul 16 22:57:36 1995
@@ -8,6 +8,123 @@
  * yet. I'll have to see about this later..
  */
 
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_close		  6
+#define __NR_wait4		  7
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_chdir		 12
+#define __NR_fchdir		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_brk		 17
+#define __NR_lseek		 19
+#define __NR_getxpid		 20
+#define __NR_setuid		 23
+#define __NR_getxuid		 24
+#define __NR_ptrace		 26
+#define __NR_access		 33
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_setpgid		 39
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_open		 45
+#define __NR_getxgid		 47
+#define __NR_ioctl		 54
+#define __NR_symlink		 57
+#define __NR_readlink		 58
+#define __NR_execve		 59
+#define __NR_umask		 60
+#define __NR_getpgrp		 63
+#define __NR_getpagesize	 64
+#define __NR_stat		 67
+#define __NR_lstat		 68
+#define __NR_munmap		 73
+#define __NR_mprotect		 74
+#define __NR_madvise		 75
+#define __NR_vhangup		 76
+#define __NR_getgroups		 79
+#define __NR_setgroups		 80
+#define __NR_setpgid		 82
+#define __NR_setitimer		 83
+#define __NR_getitimer		 86
+#define __NR_gethostname	 87
+#define __NR_sethostname	 88
+#define __NR_getdtablesize	 89
+#define __NR_dup2		 90
+#define __NR_fstat		 91
+#define __NR_fcntl		 92
+#define __NR_select		 93
+#define __NR_fsync		 95
+#define __NR_setpriority	 96
+#define __NR_socket		 97
+#define __NR_connect		 98
+#define __NR_accept		 99
+#define __NR_getpriority	100
+#define __NR_send		101
+#define __NR_recv		102
+#define __NR_sigreturn		103
+#define __NR_bind		104
+#define __NR_setsockopt		105
+#define __NR_listen		106
+#define __NR_sigsuspend		111
+#define __NR_gettimeofday	116
+#define __NR_getrusage		117
+#define __NR_getsockopt		118
+#define __NR_settimeofday	122
+#define __NR_fchown		123
+#define __NR_fchmod		124
+#define __NR_recvfrom		125
+#define __NR_setreuid		126
+#define __NR_setregid		127
+#define __NR_rename		128
+#define __NR_truncate		129
+#define __NR_ftruncate		130
+#define __NR_setgid		132
+#define __NR_sendto		133
+#define __NR_shutdown		134
+#define __NR_socketpair		135
+#define __NR_mkdir		136
+#define __NR_rmdir		137
+#define __NR_utimes		138
+#define __NR_getpeername	141
+#define __NR_getrlimit		144
+#define __NR_setrlimit		145
+#define __NR_setsid		147
+#define __NR_getsockname	150
+#define __NR_sigaction		156
+#define __NR_msgctl		200
+#define __NR_msgget		201
+#define __NR_msgrcv		202
+#define __NR_msgsnd		203
+#define __NR_semctl		204
+#define __NR_semget		205
+#define __NR_semop		206
+#define __NR_shmctl		210
+#define __NR_shmdt		211
+#define __NR_shmget		212
+
+/*
+ * Linux-specific system calls begin at 300
+ */
+#define __NR_bdflush		300
+#define __NR_sethae		301
+#define __NR_mount		302
+#define __NR_adjtimex		303
+#define __NR_swapoff		304
+#define __NR_getdents		305
+#define __NR_create_module	306
+#define __NR_init_module	307
+#define __NR_delete_module	308
+#define __NR_get_kernel_syms	309
+#define __NR_syslog		310
+
+
 #ifdef __LIBRARY__
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
diff -u --recursive --new-file v1.3.10/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
--- v1.3.10/linux/include/asm-i386/system.h	Thu Jun 29 19:02:55 1995
+++ linux/include/asm-i386/system.h	Tue Jul 18 14:45:58 1995
@@ -138,32 +138,32 @@
 	:"ax")
 
 
-extern inline unsigned long xchg_u8(char * m, unsigned long val)
-{
-	__asm__("xchgb %b0,%1":"=q" (val),"=m" (*m):"0" (val):"memory");
-	return val;
-}
-
-extern inline unsigned long xchg_u16(short * m, unsigned long val)
-{
-	__asm__("xchgw %w0,%1":"=r" (val),"=m" (*m):"0" (val):"memory");
-	return val;
-}
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
 
-extern inline unsigned long xchg_u32(int * m, unsigned long val)
-{
-	__asm__("xchgl %0,%1":"=r" (val),"=m" (*m):"0" (val):"memory");
-	return val;
-}
-
-extern inline int tas(char * m)
-{
-	return xchg_u8(m,1);
-}
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
 
-extern inline void * xchg_ptr(void * m, void * val)
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
-	return (void *) xchg_u32(m, (unsigned long) val);
+	switch (size) {
+		case 1:
+			__asm__("xchgb %b0,%1"
+				:"=q" (x), "=m" (*__xg(ptr))
+				:"0" (x), "m" (*__xg(ptr)));
+			break;
+		case 2:
+			__asm__("xchgw %w0,%1"
+				:"=r" (x), "=m" (*__xg(ptr))
+				:"0" (x), "m" (*__xg(ptr)));
+			break;
+		case 4:
+			__asm__("xchgl %0,%1"
+				:"=r" (x), "=m" (*__xg(ptr))
+				:"0" (x), "m" (*__xg(ptr)));
+			break;
+	}
+	return x;
 }
 
 #define mb()  __asm__ __volatile__ (""   : : :"memory")
diff -u --recursive --new-file v1.3.10/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v1.3.10/linux/include/asm-i386/unistd.h	Fri Feb 24 16:46:58 1995
+++ linux/include/asm-i386/unistd.h	Sun Jul 16 22:27:12 1995
@@ -1,6 +1,155 @@
 #ifndef _ASM_I386_UNISTD_H_
 #define _ASM_I386_UNISTD_H_
 
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_setup		  0	/* used only by init, to get system going */
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_phys		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_vm86		113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
 type name(void) \
diff -u --recursive --new-file v1.3.10/linux/include/linux/mm.h linux/include/linux/mm.h
--- v1.3.10/linux/include/linux/mm.h	Thu Jun 29 19:02:55 1995
+++ linux/include/linux/mm.h	Mon Jul 17 12:43:26 1995
@@ -275,7 +275,7 @@
 #ifdef SWAP_CACHE_INFO
 	swap_cache_find_total++;
 #endif
-	entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL);
+	entry = xchg(swap_cache + MAP_NR(addr), 0);
 #ifdef SWAP_CACHE_INFO
 	if (entry)
 		swap_cache_find_success++;
@@ -290,7 +290,7 @@
 #ifdef SWAP_CACHE_INFO
 	swap_cache_del_total++;
 #endif	
-	entry= (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL);
+	entry= xchg(swap_cache + MAP_NR(addr), 0);
 	if (entry)  {
 #ifdef SWAP_CACHE_INFO
 		swap_cache_del_success++;
diff -u --recursive --new-file v1.3.10/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v1.3.10/linux/include/linux/netdevice.h	Thu Jul 13 16:20:21 1995
+++ linux/include/linux/netdevice.h	Tue Jul 18 14:53:10 1995
@@ -31,7 +31,11 @@
 /* for future expansion when we will have different priorities. */
 #define DEV_NUMBUFFS	3
 #define MAX_ADDR_LEN	7
-#define MAX_HEADER	38
+#ifndef CONFIG_AX25
+#define MAX_HEADER	32		/* We really need about 18 worst case .. so 32 is aligned */
+#else
+#define MAX_HEADER	96		/* AX.25 + NetROM */
+#endif
 
 #define IS_MYADDR	1		/* address is (one of) our own	*/
 #define IS_LOOPBACK	2		/* address is for LOOPBACK	*/
@@ -73,12 +77,12 @@
   unsigned long		  mem_end;		/* sahared mem end	*/
   unsigned long		  mem_start;		/* shared mem start	*/
   unsigned long		  base_addr;		/* device I/O address	*/
-  unsigned long		  tbusy;		/* transmitter busy must be long for bitops */
   unsigned char		  irq;			/* device IRQ number	*/
 
   /* Low-level status flags. */
   volatile unsigned char  start,		/* start an operation	*/
                           interrupt;		/* interrupt arrived	*/
+  unsigned long		  tbusy;		/* transmitter busy must be long for bitops */
 
   struct device		  *next;
 
diff -u --recursive --new-file v1.3.10/linux/include/linux/nfs_fs_sb.h linux/include/linux/nfs_fs_sb.h
--- v1.3.10/linux/include/linux/nfs_fs_sb.h	Wed Dec  1 14:44:15 1993
+++ linux/include/linux/nfs_fs_sb.h	Tue Jul 18 14:53:16 1995
@@ -5,6 +5,7 @@
 
 struct nfs_server {
 	struct file *file;
+	struct sockaddr toaddr ;  /* Added for change to NFS code to use sendto()  1995-06-02  JSP */
 	int lock;
 	struct wait_queue *wait;
 	int flags;
diff -u --recursive --new-file v1.3.10/linux/include/linux/scc.h linux/include/linux/scc.h
--- v1.3.10/linux/include/linux/scc.h	Tue Jun  6 11:22:12 1995
+++ linux/include/linux/scc.h	Sun Jul 16 18:54:02 1995
@@ -1,4 +1,3 @@
-/* $Id: scc.h,v 1.9 1995/01/12 18:24:40 JReuter Exp JReuter $ */
 
 #ifndef	_SCC_H
 #define	_SCC_H
@@ -15,9 +14,9 @@
 /* Constants */
 
 #define MAXSCC		4	/* number of max. supported chips */
-#define MAX_IBUFS	200	/* change this if you run out of memory */
-#define BUFSIZE	  	128	/* must not exceed 4096 */
-#define TPS		25	/* scc_timer():  Ticks Per Second */
+#define MAX_IBUFS	300	/* change this if you run out of memory */
+#define BUFSIZE	  	64	/* must not exceed 4096 */
+#define TPS		25	/* scc_timer(): 25  Ticks Per Second */
 
 #define SCC_TIMER	3
 
@@ -134,15 +133,13 @@
 
 /* Basic message buffer structure */
 
-/* looks familiar? Hmm, yes... */
-
 struct mbuf {
 	struct mbuf *next;	/* Links mbufs belonging to single packets */
 	struct mbuf *anext;	/* Links packets on queues */
-	
+
 	char type;		/* who allocated this buffer? */
-	int  time_out;		/* unimplemented yet */
-	
+	unsigned long  time_out;/* buffer time out */
+
 	int size;		/* Size of associated data buffer */
 	int refcnt;		/* Reference count */
 	struct mbuf *dup;	/* Pointer to duplicated mbuf */
@@ -240,16 +237,19 @@
         struct scc_stat stat;	/* statistical information */
         struct scc_modem modem; /* modem information */
 
-	struct mbuf *rbp;	/* rx: Head of mbuf chain being filled */
-	struct mbuf *rbp1;	/* rx: Pointer to mbuf currently being written */
-	struct mbuf *rcvq;	/* Pointer to mbuf packets currently received */
-	
+	char rxbuf[2048];	/* Rx frame buffer max framesize * 2 */
+	int rxbufcnt;		/* Rx frame counter */
+
 	struct mbuf *sndq;	/* tx: Packets awaiting transmission */
 	struct mbuf *tbp;	/* tx: Transmit mbuf being sent */
 
 	struct mbuf *sndq1;	/* Pointer to mbuf currently under construction */
 	struct mbuf *sndq2;	/* Pointer to mbuf currently under construction */
 
+/*	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;*/
 	
 	/* Timer */
 
diff -u --recursive --new-file v1.3.10/linux/include/linux/sched.h linux/include/linux/sched.h
--- v1.3.10/linux/include/linux/sched.h	Thu Jul 13 16:20:21 1995
+++ linux/include/linux/sched.h	Mon Jul 17 12:05:15 1995
@@ -61,6 +61,7 @@
 #include <linux/vm86.h>
 #include <linux/math_emu.h>
 #include <linux/ptrace.h>
+#include <linux/timer.h>
 
 #include <asm/processor.h>
 
@@ -174,6 +175,7 @@
 	unsigned long timeout;
 	unsigned long it_real_value, it_prof_value, it_virt_value;
 	unsigned long it_real_incr, it_prof_incr, it_virt_incr;
+	struct timer_list real_timer;
 	long utime, stime, cutime, cstime, start_time;
 	struct rlimit rlim[RLIM_NLIMITS]; 
 	unsigned short used_math;
@@ -237,7 +239,9 @@
 /* suppl grps*/ {NOGROUP,}, \
 /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
 /* uid etc */	0,0,0,0,0,0,0,0, \
-/* timeout */	0,0,0,0,0,0,0,0,0,0,0,0, \
+/* timeout */	0,0,0,0,0,0,0, \
+/* timer */	{ NULL, NULL, 0, 0, it_real_fn }, \
+/* utime */	0,0,0,0,0, \
 /* rlimits */   { {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX},  \
 		  {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM},  \
 		  {       0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \
@@ -271,6 +275,7 @@
 extern void interruptible_sleep_on(struct wait_queue ** p);
 extern void wake_up(struct wait_queue ** p);
 extern void wake_up_interruptible(struct wait_queue ** p);
+extern void wake_up_process(struct task_struct * tsk);
 
 extern void notify_parent(struct task_struct * tsk);
 extern int send_sig(unsigned long sig,struct task_struct * p,int priv);
diff -u --recursive --new-file v1.3.10/linux/include/linux/sjcd.h linux/include/linux/sjcd.h
--- v1.3.10/linux/include/linux/sjcd.h	Fri Jul  7 08:54:54 1995
+++ linux/include/linux/sjcd.h	Sun Jul 16 21:47:22 1995
@@ -1,4 +1,5 @@
-/*
+/* -- sjcd.h
+ *
  * Definitions for a Sanyo CD-ROM interface
  *
  *   Copyright (C) 1995  Vadim V. Model
@@ -21,6 +22,11 @@
  * Change this to set the irq.
  */
 #define SJCD_INTR_NR        10
+
+/*
+ * Change this to set the dma channel.
+ */
+#define SJCD_DMA            0
 
 /*
  * port access macros
diff -u --recursive --new-file v1.3.10/linux/include/linux/timer.h linux/include/linux/timer.h
--- v1.3.10/linux/include/linux/timer.h	Fri Jul  7 08:54:54 1995
+++ linux/include/linux/timer.h	Mon Jul 17 10:52:42 1995
@@ -87,6 +87,8 @@
 extern void add_timer(struct timer_list * timer);
 extern int  del_timer(struct timer_list * timer);
 
+extern void it_real_fn(unsigned long);
+
 extern inline void init_timer(struct timer_list * timer)
 {
 	timer->next = NULL;
diff -u --recursive --new-file v1.3.10/linux/include/linux/tqueue.h linux/include/linux/tqueue.h
--- v1.3.10/linux/include/linux/tqueue.h	Wed Apr 12 21:24:17 1995
+++ linux/include/linux/tqueue.h	Mon Jul 17 12:44:39 1995
@@ -143,7 +143,7 @@
 	void (*f) (void *);
 
 	while(1) {
-		p = xchg_ptr(list,&tq_last);
+		p = xchg(list,&tq_last);
 		if(p == &tq_last)
 			break;
 
diff -u --recursive --new-file v1.3.10/linux/include/linux/trdevice.h linux/include/linux/trdevice.h
--- v1.3.10/linux/include/linux/trdevice.h	Fri Jun 30 16:22:30 1995
+++ linux/include/linux/trdevice.h	Fri Jul 14 06:20:04 1995
@@ -28,9 +28,9 @@
 #include <linux/if_tr.h>
 
 #ifdef __KERNEL__
-extern int		tr_header(struct sk_buff *skb, struct device *dev,
+extern int		tr_header(unsigned char *buff, struct device *dev,
 				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len);
+				   void *saddr, unsigned len, struct sk_buff *skb);
 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.10/linux/include/linux/unistd.h linux/include/linux/unistd.h
--- v1.3.10/linux/include/linux/unistd.h	Sun Jun 11 19:03:07 1995
+++ linux/include/linux/unistd.h	Sun Jul 16 22:27:12 1995
@@ -1,155 +1,6 @@
 #ifndef _LINUX_UNISTD_H_
 #define _LINUX_UNISTD_H_
 
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_setup		  0	/* used only by init, to get system going */
-#define __NR_exit		  1
-#define __NR_fork		  2
-#define __NR_read		  3
-#define __NR_write		  4
-#define __NR_open		  5
-#define __NR_close		  6
-#define __NR_waitpid		  7
-#define __NR_creat		  8
-#define __NR_link		  9
-#define __NR_unlink		 10
-#define __NR_execve		 11
-#define __NR_chdir		 12
-#define __NR_time		 13
-#define __NR_mknod		 14
-#define __NR_chmod		 15
-#define __NR_chown		 16
-#define __NR_break		 17
-#define __NR_oldstat		 18
-#define __NR_lseek		 19
-#define __NR_getpid		 20
-#define __NR_mount		 21
-#define __NR_umount		 22
-#define __NR_setuid		 23
-#define __NR_getuid		 24
-#define __NR_stime		 25
-#define __NR_ptrace		 26
-#define __NR_alarm		 27
-#define __NR_oldfstat		 28
-#define __NR_pause		 29
-#define __NR_utime		 30
-#define __NR_stty		 31
-#define __NR_gtty		 32
-#define __NR_access		 33
-#define __NR_nice		 34
-#define __NR_ftime		 35
-#define __NR_sync		 36
-#define __NR_kill		 37
-#define __NR_rename		 38
-#define __NR_mkdir		 39
-#define __NR_rmdir		 40
-#define __NR_dup		 41
-#define __NR_pipe		 42
-#define __NR_times		 43
-#define __NR_prof		 44
-#define __NR_brk		 45
-#define __NR_setgid		 46
-#define __NR_getgid		 47
-#define __NR_signal		 48
-#define __NR_geteuid		 49
-#define __NR_getegid		 50
-#define __NR_acct		 51
-#define __NR_phys		 52
-#define __NR_lock		 53
-#define __NR_ioctl		 54
-#define __NR_fcntl		 55
-#define __NR_mpx		 56
-#define __NR_setpgid		 57
-#define __NR_ulimit		 58
-#define __NR_oldolduname	 59
-#define __NR_umask		 60
-#define __NR_chroot		 61
-#define __NR_ustat		 62
-#define __NR_dup2		 63
-#define __NR_getppid		 64
-#define __NR_getpgrp		 65
-#define __NR_setsid		 66
-#define __NR_sigaction		 67
-#define __NR_sgetmask		 68
-#define __NR_ssetmask		 69
-#define __NR_setreuid		 70
-#define __NR_setregid		 71
-#define __NR_sigsuspend		 72
-#define __NR_sigpending		 73
-#define __NR_sethostname	 74
-#define __NR_setrlimit		 75
-#define __NR_getrlimit		 76
-#define __NR_getrusage		 77
-#define __NR_gettimeofday	 78
-#define __NR_settimeofday	 79
-#define __NR_getgroups		 80
-#define __NR_setgroups		 81
-#define __NR_select		 82
-#define __NR_symlink		 83
-#define __NR_oldlstat		 84
-#define __NR_readlink		 85
-#define __NR_uselib		 86
-#define __NR_swapon		 87
-#define __NR_reboot		 88
-#define __NR_readdir		 89
-#define __NR_mmap		 90
-#define __NR_munmap		 91
-#define __NR_truncate		 92
-#define __NR_ftruncate		 93
-#define __NR_fchmod		 94
-#define __NR_fchown		 95
-#define __NR_getpriority	 96
-#define __NR_setpriority	 97
-#define __NR_profil		 98
-#define __NR_statfs		 99
-#define __NR_fstatfs		100
-#define __NR_ioperm		101
-#define __NR_socketcall		102
-#define __NR_syslog		103
-#define __NR_setitimer		104
-#define __NR_getitimer		105
-#define __NR_stat		106
-#define __NR_lstat		107
-#define __NR_fstat		108
-#define __NR_olduname		109
-#define __NR_iopl		110
-#define __NR_vhangup		111
-#define __NR_idle		112
-#define __NR_vm86		113
-#define __NR_wait4		114
-#define __NR_swapoff		115
-#define __NR_sysinfo		116
-#define __NR_ipc		117
-#define __NR_fsync		118
-#define __NR_sigreturn		119
-#define __NR_clone		120
-#define __NR_setdomainname	121
-#define __NR_uname		122
-#define __NR_modify_ldt		123
-#define __NR_adjtimex		124
-#define __NR_mprotect		125
-#define __NR_sigprocmask	126
-#define __NR_create_module	127
-#define __NR_init_module	128
-#define __NR_delete_module	129
-#define __NR_get_kernel_syms	130
-#define __NR_quotactl		131
-#define __NR_getpgid		132
-#define __NR_fchdir		133
-#define __NR_bdflush		134
-#define __NR_sysfs		135
-#define __NR_personality	136
-#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
-#define __NR_setfsuid		138
-#define __NR_setfsgid		139
-#define __NR__llseek		140
-#define __NR_getdents		141
-#define __NR__newselect		142
-#define __NR_flock		143
-
 extern int errno;
 
 /*
diff -u --recursive --new-file v1.3.10/linux/kernel/dma.c linux/kernel/dma.c
--- v1.3.10/linux/kernel/dma.c	Wed Jan  4 21:16:06 1995
+++ linux/kernel/dma.c	Mon Jul 17 12:42:06 1995
@@ -74,7 +74,7 @@
 	if (dmanr >= MAX_DMA_CHANNELS)
 		return -EINVAL;
 
-	if (xchg_u32(&dma_chan_busy[dmanr].lock, 1) != 0)
+	if (xchg(&dma_chan_busy[dmanr].lock, 1) != 0)
 		return -EBUSY;
 
 	dma_chan_busy[dmanr].device_id = device_id;
@@ -91,7 +91,7 @@
 		return;
 	}
 
-	if (xchg_u32(&dma_chan_busy[dmanr].lock, 0) == 0) {
+	if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) {
 		printk("Trying to free free DMA%d\n", dmanr);
 		return;
 	}	
diff -u --recursive --new-file v1.3.10/linux/kernel/exit.c linux/kernel/exit.c
--- v1.3.10/linux/kernel/exit.c	Fri Jun 30 16:22:30 1995
+++ linux/kernel/exit.c	Mon Jul 17 12:10:39 1995
@@ -27,18 +27,18 @@
 	struct sigaction * sa = sig + p->sigaction - 1;
 
 	/* always generate signals for traced processes ??? */
-	if (p->flags & PF_PTRACED) {
-		p->signal |= mask;
-		return 1;
+	if (!(p->flags & PF_PTRACED)) {
+		/* don't bother with ignored signals (but SIGCHLD is special) */
+		if (sa->sa_handler == SIG_IGN && sig != SIGCHLD)
+			return 0;
+		/* some signals are ignored by default.. (but SIGCONT already did its deed) */
+		if ((sa->sa_handler == SIG_DFL) &&
+		    (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH))
+			return 0;
 	}
-	/* don't bother with ignored signals (but SIGCHLD is special) */
-	if (sa->sa_handler == SIG_IGN && sig != SIGCHLD)
-		return 0;
-	/* some signals are ignored by default.. (but SIGCONT already did its deed) */
-	if ((sa->sa_handler == SIG_DFL) &&
-	    (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH))
-		return 0;
 	p->signal |= mask;
+	if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked))
+		wake_up_process(p);
 	return 1;
 }
 
@@ -58,7 +58,7 @@
 		return 0;
 	if ((sig == SIGKILL) || (sig == SIGCONT)) {
 		if (p->state == TASK_STOPPED)
-			p->state = TASK_RUNNING;
+			wake_up_process(p);
 		p->exit_code = 0;
 		p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) |
 				(1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) );
@@ -382,6 +382,7 @@
 	}
 fake_volatile:
 	current->flags |= PF_EXITING;
+	del_timer(&current->real_timer);
 	sem_exit();
 	exit_mmap(current);
 	free_page_tables(current);
diff -u --recursive --new-file v1.3.10/linux/kernel/fork.c linux/kernel/fork.c
--- v1.3.10/linux/kernel/fork.c	Mon Jun 12 15:56:40 1995
+++ linux/kernel/fork.c	Mon Jul 17 12:11:07 1995
@@ -197,6 +197,8 @@
 	p->signal = 0;
 	p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
 	p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
+	init_timer(&p->real_timer);
+	p->real_timer.data = (unsigned long) p;
 	p->leader = 0;		/* process leadership doesn't inherit */
 	p->tty_old_pgrp = 0;
 	p->utime = p->stime = 0;
@@ -219,7 +221,7 @@
 	p->mm->swappable = 1;
 	p->exit_signal = clone_flags & CSIGNAL;
 	p->counter = current->counter >> 1;
-	p->state = TASK_RUNNING;	/* do this last, just in case */
+	wake_up_process(p);			/* do this last, just in case */
 	return p->pid;
 bad_fork_cleanup:
 	task[nr] = NULL;
diff -u --recursive --new-file v1.3.10/linux/kernel/itimer.c linux/kernel/itimer.c
--- v1.3.10/linux/kernel/itimer.c	Mon Jan 23 23:04:10 1995
+++ linux/kernel/itimer.c	Mon Jul 17 10:59:51 1995
@@ -71,6 +71,17 @@
 	return 0;
 }
 
+void it_real_fn(unsigned long __data)
+{
+	struct task_struct * p = (struct task_struct *) __data;
+
+	send_sig(SIGALRM, p, 1);
+	if (p->it_real_incr) {
+		p->real_timer.expires = p->it_real_incr;
+		add_timer(&p->real_timer);
+	}
+}
+
 int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
 {
 	register unsigned long i, j;
@@ -82,10 +93,10 @@
 		return k;
 	switch (which) {
 		case ITIMER_REAL:
+			del_timer(&current->real_timer);
 			if (j) {
-				j += 1+itimer_ticks;
-				if (j < itimer_next)
-					itimer_next = j;
+				current->real_timer.expires = j;
+				add_timer(&current->real_timer);
 			}
 			current->it_real_value = j;
 			current->it_real_incr = i;
diff -u --recursive --new-file v1.3.10/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.10/linux/kernel/ksyms.c	Tue Jul 11 10:03:00 1995
+++ linux/kernel/ksyms.c	Sun Jul 16 22:25:19 1995
@@ -151,6 +151,7 @@
 	X(kfree_s),
 	X(vmalloc),
 	X(vfree),
+ 	X(mem_map),
 
 	/* filesystem internal functions */
 	X(getname),
@@ -243,6 +244,7 @@
 	X(tq_last),
 	X(timer_active),
 	X(timer_table),
+ 	X(intr_count),
 
 	/* dma handling */
 	X(request_dma),
@@ -310,6 +312,7 @@
 	X(slhc_remember),
 	X(slhc_compress),
 	X(slhc_uncompress),
+	X(slhc_toss),
 #endif
 #endif
 	/* Device callback registration */
@@ -384,8 +387,6 @@
 	X(generic_proc_info),
  	X(scsi_devices),
  	X(free_pages),
- 	X(intr_count),
- 	X(mem_map),
     	X(print_msg),
 	X(print_status),
 	X(gendisk_head), /* Needed for sd.c */
@@ -395,8 +396,6 @@
 	 * With no scsi configured, we still need to export a few
 	 * symbols so that scsi can be loaded later via insmod.
 	 */
- 	X(intr_count),
- 	X(mem_map),
 	X(gendisk_head),
 	X(resetup_one_dev),
 
diff -u --recursive --new-file v1.3.10/linux/kernel/sched.c linux/kernel/sched.c
--- v1.3.10/linux/kernel/sched.c	Fri Jun 16 22:02:56 1995
+++ linux/kernel/sched.c	Mon Jul 17 17:38:34 1995
@@ -92,8 +92,27 @@
 
 struct kernel_stat kstat = { 0 };
 
-unsigned long itimer_ticks = 0;
-unsigned long itimer_next = ~0;
+/*
+ * Wake up a process. Put it on the run-queue if it's not
+ * already there.  The "current" process is always on the
+ * run-queue, and as such you're allowed to do the simpler
+ * "current->state = TASK_RUNNING" to mark yourself runnable
+ * without the overhead of this.
+ *
+ * (actually, the run-queue isn't implemented yet, so this
+ * function is mostly a dummy one)
+ */
+inline void wake_up_process(struct task_struct * p)
+{
+	long oldstate;
+
+	oldstate = xchg(&p->state, TASK_RUNNING);
+	/* already on run-queue? */
+	if (oldstate == TASK_RUNNING || p == current)
+		return;
+	if (p->counter > current->counter + 3)
+		need_resched = 1;
+}
 
 /*
  *  'schedule()' is the scheduler function. It's a very simple and nice
@@ -103,16 +122,12 @@
  *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other
  * tasks can run. It can not be killed, and it cannot sleep. The 'state'
  * information in task[0] is never used.
- *
- * The "confuse_gcc" goto is used only to get better assembly code..
- * Dijkstra probably hates me.
  */
 asmlinkage void schedule(void)
 {
 	int c;
 	struct task_struct * p;
 	struct task_struct * next;
-	unsigned long ticks;
 
 /* check alarm, wake up any interruptible tasks that have got a signal */
 
@@ -121,69 +136,35 @@
 		intr_count = 0;
 	}
 	run_task_queue(&tq_scheduler);
-	cli();
-	ticks = itimer_ticks;
-	itimer_ticks = 0;
-	itimer_next = ~0;
-	sti();
+
+	if (current->state == TASK_INTERRUPTIBLE) {
+		if (current->signal & ~current->blocked)
+			current->state = TASK_RUNNING;
+	}
 	need_resched = 0;
 	nr_running = 0;
-	p = &init_task;
-	for (;;) {
-		if ((p = p->next_task) == &init_task)
-			goto confuse_gcc1;
-		if (ticks && p->it_real_value) {
-			if (p->it_real_value <= ticks) {
-				send_sig(SIGALRM, p, 1);
-				if (!p->it_real_incr) {
-					p->it_real_value = 0;
-					goto end_itimer;
-				}
-				do {
-					p->it_real_value += p->it_real_incr;
-				} while (p->it_real_value <= ticks);
-			}
-			p->it_real_value -= ticks;
-			if (p->it_real_value < itimer_next)
-				itimer_next = p->it_real_value;
-		}
-end_itimer:
-		if (p->state != TASK_INTERRUPTIBLE)
-			continue;
-		if (p->signal & ~p->blocked) {
-			p->state = TASK_RUNNING;
-			continue;
-		}
-		if (p->timeout && p->timeout <= jiffies) {
-			p->timeout = 0;
-			p->state = TASK_RUNNING;
-		}
-	}
-confuse_gcc1:
 
 /* this is the scheduler proper: */
-#if 0
-	/* give processes that go to sleep a bit higher priority.. */
-	/* This depends on the values for TASK_XXX */
-	/* This gives smoother scheduling for some things, but */
-	/* can be very unfair under some circumstances, so.. */
- 	if (TASK_UNINTERRUPTIBLE >= (unsigned) current->state &&
-	    current->counter < current->priority*2) {
-		++current->counter;
-	}
-#endif
 	c = -1000;
-	next = p = &init_task;
-	for (;;) {
-		if ((p = p->next_task) == &init_task)
-			goto confuse_gcc2;
-		if (p->state == TASK_RUNNING) {
-			nr_running++;
-			if (p->counter > c)
-				c = p->counter, next = p;
+	next = &init_task;
+	for_each_task(p) {
+		switch (p->state) {
+			case TASK_INTERRUPTIBLE:
+				if (!p->timeout)
+					continue;
+				if (p->timeout > jiffies)
+					continue;
+				p->timeout = 0;
+				p->state = TASK_RUNNING;
+			/* fall through */
+			case TASK_RUNNING:
+				nr_running++;
+				if (p->counter > c)
+					c = p->counter, next = p;
 		}
 	}
-confuse_gcc2:
+
+	/* if all runnable processes have "counter == 0", re-calculate counters */
 	if (!c) {
 		for_each_task(p)
 			p->counter = (p->counter >> 1) + p->priority;
@@ -219,11 +200,8 @@
 	do {
 		if ((p = tmp->task) != NULL) {
 			if ((p->state == TASK_UNINTERRUPTIBLE) ||
-			    (p->state == TASK_INTERRUPTIBLE)) {
-				p->state = TASK_RUNNING;
-				if (p->counter > current->counter + 3)
-					need_resched = 1;
-			}
+			    (p->state == TASK_INTERRUPTIBLE))
+				wake_up_process(p);
 		}
 		if (!tmp->next) {
 			printk("wait_queue is bad (eip = %p)\n",
@@ -246,11 +224,8 @@
 		return;
 	do {
 		if ((p = tmp->task) != NULL) {
-			if (p->state == TASK_INTERRUPTIBLE) {
-				p->state = TASK_RUNNING;
-				if (p->counter > current->counter + 3)
-					need_resched = 1;
-			}
+			if (p->state == TASK_INTERRUPTIBLE)
+				wake_up_process(p);
 		}
 		if (!tmp->next) {
 			printk("wait_queue is bad (eip = %p)\n",
@@ -665,9 +640,6 @@
 		mark_bh(TIMER_BH);
 	}
 	cli();
-	itimer_ticks++;
-	if (itimer_ticks > itimer_next)
-		need_resched = 1;
 	if (timer_head.next->expires < jiffies)
 		mark_bh(TIMER_BH);
 	if (tq_timer != &tq_last)
diff -u --recursive --new-file v1.3.10/linux/mm/swap.c linux/mm/swap.c
--- v1.3.10/linux/mm/swap.c	Fri Jun 30 16:22:30 1995
+++ linux/mm/swap.c	Mon Jul 17 12:42:48 1995
@@ -82,7 +82,7 @@
 	swap_cache_add_total++;
 #endif
 	if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
-		entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), (void *) entry);
+		entry = xchg(swap_cache + MAP_NR(addr), entry);
 		if (entry)  {
 			printk("swap_cache: replacing non-NULL entry\n");
 		}
diff -u --recursive --new-file v1.3.10/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c
--- v1.3.10/linux/net/appletalk/aarp.c	Fri Jul  7 08:54:56 1995
+++ linux/net/appletalk/aarp.c	Tue Jul 18 14:53:23 1995
@@ -178,7 +178,6 @@
 	eah		=	(struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));	 
 	skb->arp	=	1;
 	skb->free	=	1;
-	skb_put(skb,len);
 	skb->dev	=	dev;
 	
 	/*
@@ -243,7 +242,6 @@
 	
 	skb->arp	=	1;
 	skb->free	=	1;
-	skb_put(skb,len);
 	skb->dev	=	dev;
 	
 	/*
diff -u --recursive --new-file v1.3.10/linux/net/ethernet/eth.c linux/net/ethernet/eth.c
--- v1.3.10/linux/net/ethernet/eth.c	Tue Jul 11 10:03:00 1995
+++ linux/net/ethernet/eth.c	Tue Jul 18 15:24:15 1995
@@ -26,6 +26,7 @@
  *		Alan Cox	: ARP only when compiled with CONFIG_INET
  *		Greg Page	: 802.2 and SNAP stuff.
  *		Alan Cox	: MAC layer pointers/new format.
+ *		Paul Gortmaker	: eth_copy_and_sum shouldn't csum padding.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -231,11 +232,13 @@
 
 /*
  *	Copy from an ethernet device memory space to an sk_buff while checksumming if IP
+ *	The magic "34" is Rx_addr+Tx_addr+type_field+sizeof(struct iphdr) == 6+6+2+20.
  */
  
 void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int base)
 {
 	struct ethhdr *eth;
+	struct iphdr *iph;
 
 	IS_SKB(dest);
 	eth=(struct ethhdr *)dest->data;
@@ -246,6 +249,14 @@
 		memcpy(dest->data+34,src+34,length);
 		return;
 	}
+	/*
+	 * We have to watch for padded packets. The csum doesn't include the
+	 * padding, and there is no point in copying the padding anyway.
+	 */
+	iph=(struct iphdr*)(src+14);	/* 14 = Rx_addr+Tx_addr+type_field */
+	if (ntohs(iph->tot_len)-sizeof(struct iphdr) <= length)
+		length=ntohs(iph->tot_len)-sizeof(struct iphdr);
+
 	dest->csum=csum_partial_copy(src+34,dest->data+34,length,base);
 	dest->ip_summed=1;
 }
diff -u --recursive --new-file v1.3.10/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- v1.3.10/linux/net/ipv4/ip_fw.c	Fri Jun 30 16:22:32 1995
+++ linux/net/ipv4/ip_fw.c	Tue Jul 18 14:53:16 1995
@@ -733,7 +733,7 @@
  		if (portptr[1]==htons(21)) 
  		{
  			skb = revamp(*skb_ptr, dev, ms);
- 			skb = *skb_ptr;
+ 			*skb_ptr = skb;
  			iph = skb->h.iph;
  			portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
  		}
diff -u --recursive --new-file v1.3.10/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v1.3.10/linux/net/ipv4/tcp.c	Fri Jul  7 13:42:58 1995
+++ linux/net/ipv4/tcp.c	Tue Jul 18 14:54:29 1995
@@ -145,6 +145,11 @@
  *					sk->retransmits misupdating fixed.
  *					Fixed tcp_write_timeout: stuck close,
  *					and TCP syn retries gets used now.
+ *		Mark Yarvis	:	In tcp_read_wakeup(), don't send an
+ *					ack if stat is TCP_CLOSED.
+ *		Alan Cox	:	Look up device on a retransmit - routes may
+ *					change. Doesn't yet cope with MSS shrink right
+ *					but its a start!
  *
  *
  * To Fix:
@@ -439,6 +444,7 @@
 	struct proto *prot;
 	struct device *dev;
 	int ct=0;
+	struct rtable *rt;
 
 	prot = sk->prot;
 	skb = sk->send_head;
@@ -454,6 +460,12 @@
 		skb->when = jiffies;
 
 		/*
+		 *	Discard the surplus MAC header
+		 */
+		 
+		skb_pull(skb,((unsigned char *)skb->ip_hdr)-skb->data);
+
+		/*
 		 * In general it's OK just to use the old packet.  However we
 		 * need to use the current ack and window fields.  Urg and
 		 * urg_ptr could possibly stand to be updated as well, but we
@@ -462,60 +474,89 @@
 		 * changing the packet, we have to issue a new IP identifier.
 		 */
 
-		iph = (struct iphdr *)(skb->data + dev->hard_header_len);
+		iph = (struct iphdr *)skb->data;
 		th = (struct tcphdr *)(((char *)iph) + (iph->ihl << 2));
-		size = skb->len - (((unsigned char *) th) - skb->data);
+		size = ntohs(iph->tot_len) - (iph->ihl<<2);
 		
 		/*
 		 *	Note: We ought to check for window limits here but
 		 *	currently this is done (less efficiently) elsewhere.
-		 *	We do need to check for a route change but can't handle
-		 *	that until we have the new 1.3.x buffers in.
-		 *
 		 */
 
 		iph->id = htons(ip_id_count++);
 		ip_send_check(iph);
-
-		/*
-		 *	This is not the right way to handle this. We have to
-		 *	issue an up to date window and ack report with this 
-		 *	retransmit to keep the odd buggy tcp that relies on 
-		 *	the fact BSD does this happy. 
-		 *	We don't however need to recalculate the entire 
-		 *	checksum, so someone wanting a small problem to play
-		 *	with might like to implement RFC1141/RFC1624 and speed
-		 *	this up by avoiding a full checksum.
-		 */
-		 
-		th->ack_seq = ntohl(sk->acked_seq);
-		th->window = ntohs(tcp_select_window(sk));
-		tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
 		
 		/*
-		 *	If the interface is (still) up and running, kick it.
+		 *	Put a MAC header back on (may cause ARPing)
 		 */
-
-		if (dev->flags & IFF_UP)
+		 
+		if(skb->localroute)
+			rt=ip_rt_local(iph->daddr,NULL,NULL);
+		else
+			rt=ip_rt_route(iph->daddr,NULL,NULL);
+			
+		if(rt==NULL)	/* Deep poo */
+		{
+			if(skb->sk)
+			{
+				skb->sk->err=ENETUNREACH;
+				skb->sk->error_report(skb->sk);
+			}
+		}
+		else
 		{
+			dev=rt->rt_dev;
+			skb->raddr=rt->rt_gateway;
+			if(skb->raddr==0)
+				skb->raddr=iph->daddr;
+			skb->dev=dev;
+			skb->arp=1;
+			if(dev->hard_header)
+			{
+				if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)
+					skb->arp=0;
+			}
+		
 			/*
-			 *	If the packet is still being sent by the device/protocol
-			 *	below then don't retransmit. This is both needed, and good -
-			 *	especially with connected mode AX.25 where it stops resends
-			 *	occurring of an as yet unsent anyway frame!
-			 *	We still add up the counts as the round trip time wants
-			 *	adjusting.
+			 *	This is not the right way to handle this. We have to
+			 *	issue an up to date window and ack report with this 
+			 *	retransmit to keep the odd buggy tcp that relies on 
+			 *	the fact BSD does this happy. 
+			 *	We don't however need to recalculate the entire 
+			 *	checksum, so someone wanting a small problem to play
+			 *	with might like to implement RFC1141/RFC1624 and speed
+			 *	this up by avoiding a full checksum.
 			 */
-			if (sk && !skb_device_locked(skb))
+		 
+			th->ack_seq = ntohl(sk->acked_seq);
+			th->window = ntohs(tcp_select_window(sk));
+			tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
+		
+			/*
+			 *	If the interface is (still) up and running, kick it.
+			 */
+	
+			if (dev->flags & IFF_UP)
 			{
-				/* Remove it from any existing driver queue first! */
-				skb_unlink(skb);
-				/* Now queue it */
-				ip_statistics.IpOutRequests++;
-				dev_queue_xmit(skb, dev, sk->priority);
+				/*
+				 *	If the packet is still being sent by the device/protocol
+				 *	below then don't retransmit. This is both needed, and good -
+				 *	especially with connected mode AX.25 where it stops resends
+				 *	occurring of an as yet unsent anyway frame!
+				 *	We still add up the counts as the round trip time wants
+				 *	adjusting.
+				 */
+				if (sk && !skb_device_locked(skb))
+				{
+					/* Remove it from any existing driver queue first! */
+					skb_unlink(skb);
+					/* Now queue it */
+					ip_statistics.IpOutRequests++;
+					dev_queue_xmit(skb, dev, sk->priority);
+				}
 			}
 		}
-
+		
 		/*
 		 *	Count retransmissions
 		 */
@@ -1772,6 +1813,13 @@
 		return;
 
 	/*
+	 * If we're closed, don't send an ack, or we'll get a RST
+	 * from the closed destination.
+	 */
+	if ((sk->state == TCP_CLOSE) || (sk->state == TCP_TIME_WAIT))
+		return; 
+
+	/*
 	 * FIXME: we need to put code here to prevent this routine from
 	 * being called.  Being called once in a while is ok, so only check
 	 * if this is the second time in a row.
@@ -3034,8 +3082,7 @@
  * Ack and window will in general have changed since this packet was put
  * on the write queue.
  */
-			iph = (struct iphdr *)(skb->data +
-					       skb->dev->hard_header_len);
+			iph = skb->ip_hdr;
 			th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2));
 			size = skb->len - (((unsigned char *) th) - skb->data);
 			
diff -u --recursive --new-file v1.3.10/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- v1.3.10/linux/net/ipv4/udp.c	Thu Jul 13 16:20:22 1995
+++ linux/net/ipv4/udp.c	Tue Jul 18 15:29:26 1995
@@ -45,8 +45,7 @@
  *	Arnt Gulbrandsen 	:	New udp_send and stuff
  *		Alan Cox	:	Cache last socket
  *		Alan Cox	:	Route cache
- *		Alan Cox	:	Checksum precompute is bogus is some lame
- *					software is padding its udp frames in IP!
+ *		Jon Peatfield	:	Minor efficientcy fix to sendto().
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -301,10 +300,9 @@
 	{
 		if (addr_len < sizeof(sin)) 
 			return(-EINVAL);
-		memcpy(&sin,usin,sizeof(sin));
-		if (sin.sin_family && sin.sin_family != AF_INET) 
+		if (usin->sin_family && usin->sin_family != AF_INET) 
 			return(-EINVAL);
-		if (sin.sin_port == 0) 
+		if (usin->sin_port == 0) 
 			return(-EINVAL);
 	} 
 	else 
@@ -314,6 +312,7 @@
 		sin.sin_family = AF_INET;
 		sin.sin_port = sk->dummy_th.dest;
 		sin.sin_addr.s_addr = sk->daddr;
+		usin = &sin;
   	}
   
   	/*
@@ -321,16 +320,16 @@
   	 *	broadcasting of data.
   	 */
   	 
-  	if(sin.sin_addr.s_addr==INADDR_ANY)
-  		sin.sin_addr.s_addr=ip_my_addr();
+  	if(usin->sin_addr.s_addr==INADDR_ANY)
+  		usin->sin_addr.s_addr=ip_my_addr();
   		
-  	if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
+  	if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
 	    	return -EACCES;			/* Must turn broadcast on first */
 
 	sk->inuse = 1;
 
 	/* Send the packet. */
-	tmp = udp_send(sk, &sin, from, len, flags);
+	tmp = udp_send(sk, usin, from, len, flags);
 
 	/* The datagram has been sent off.  Release the socket. */
 	release_sock(sk);
@@ -538,9 +537,6 @@
 	 
 	ulen = ntohs(uh->len);
 	
-	if(ulen!=len)
-		skb->ip_summed=0;	/* Bogoid padded frame */
-
 	if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) 
 	{
 		NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
