diff -u --recursive --new-file v1.3.11/linux/Makefile linux/Makefile
--- v1.3.11/linux/Makefile	Tue Jul 18 16:28:55 1995
+++ linux/Makefile	Thu Jul 20 09:22:10 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 11
+SUBLEVEL = 12
 
 ARCH = i386
 
@@ -239,10 +239,8 @@
 	rm -f .version .config* config.in config.old
 	rm -f include/asm
 	rm -f .depend `find . -name .depend -print`
-ifdef CONFIG_MODVERSIONS
 	rm -f $(TOPDIR)/include/linux/modversions.h
 	rm -f $(TOPDIR)/include/linux/modules/*
-endif
 
 distclean: mrproper
 	rm -f core `find . -name '*.orig' -print`
diff -u --recursive --new-file v1.3.11/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v1.3.11/linux/arch/alpha/kernel/entry.S	Tue Jul 18 16:28:56 1995
+++ linux/arch/alpha/kernel/entry.S	Mon Jul 24 17:38:25 1995
@@ -300,10 +300,13 @@
 entUna:
 	lda $30,-256($30)
 	stq $0,0($30)
+	ldq $0,256($30)		/* get PS */
 	stq $1,8($30)
 	stq $2,16($30)
 	stq $3,24($30)
+	and $0,8,$0		/* user mode? */
 	stq $4,32($30)
+	bne $0,entUnaUser	/* yup -> do user-level unaligned fault */
 	stq $5,40($30)
 	stq $6,48($30)
 	stq $7,56($30)
@@ -363,6 +366,17 @@
 	lda $30,256($30)
 	rti
 .end entUna
+
+.align 3
+.ent	entUnaUser
+entUnaUser:
+	ldq $0,0($30)			/* restore original $0 */
+	lda $30,256($30)		/* pop entUna's stack frame */
+	SAVE_ALL			/* setup normal kernel stack */
+	lda $27,do_entUnaUser
+	lda $26,ret_from_sys_call
+	jsr $31,($27),do_entUnaUser
+.end	entUnaUser
 
 .align 3
 .globl	sys_fork
diff -u --recursive --new-file v1.3.11/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- v1.3.11/linux/arch/alpha/kernel/osf_sys.c	Tue Jun 27 14:11:30 1995
+++ linux/arch/alpha/kernel/osf_sys.c	Tue Jul 25 10:39:23 1995
@@ -153,26 +153,15 @@
 	return current->pid;
 }
 
-#define OSF_MAP_ANONYMOUS	0x0010
-#define OSF_MAP_FIXED		0x0100
-#define OSF_MAP_HASSEMAPHORE	0x0200
-#define OSF_MAP_INHERIT		0x0400
-#define OSF_MAP_UNALIGNED	0x0800
-
 asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long osf_flags, unsigned long fd,
+	unsigned long prot, unsigned long flags, unsigned long fd,
 	unsigned long off)
 {
 	struct file * file = NULL;
-	unsigned long flags = osf_flags & 0x0f;
 
-	if (osf_flags & (OSF_MAP_HASSEMAPHORE | OSF_MAP_INHERIT | OSF_MAP_UNALIGNED))
+	if (flags & (MAP_HASSEMAPHORE | MAP_INHERIT | MAP_UNALIGNED))
 		printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, osf_flags);
-	if (osf_flags & OSF_MAP_FIXED)
-		flags |= MAP_FIXED;
-	if (osf_flags & OSF_MAP_ANONYMOUS)
-		flags |= MAP_ANONYMOUS;
-	else {
+	if (!(flags & MAP_ANONYMOUS)) {
 		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
 			return -EBADF;
 	}
diff -u --recursive --new-file v1.3.11/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c
--- v1.3.11/linux/arch/alpha/kernel/ptrace.c	Tue Jul 18 16:28:56 1995
+++ linux/arch/alpha/kernel/ptrace.c	Mon Jul 24 17:38:25 1995
@@ -531,6 +531,12 @@
 	int i, nsaved = child->debugreg[4];
 
 	child->debugreg[4] = 0;
+
+	if (nsaved > 2) {
+	    printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
+	    nsaved = 2;
+	}
+
 	for (i = 0; i < nsaved; ++i) {
 		write_int(child, child->debugreg[i], child->debugreg[i + 2]);
 	}
@@ -550,65 +556,65 @@
 	set_success(&regs,0);
 	if (request == PTRACE_TRACEME) {
 		/* are we already being traced? */
-	   if (current->flags & PF_PTRACED) {
-	      set_failure(&regs,-EPERM);
-	      return -EPERM;
-	   }
-	   /* set the ptrace bit in the process flags. */
-	   current->flags |= PF_PTRACED;
-	   return 0;
-	}
-	if (pid == 1) {
-	   set_failure(&regs,-EPERM);
-	   return -EPERM;
+		if (current->flags & PF_PTRACED) {
+			set_failure(&regs,-EPERM);
+			return -EPERM;
+		}
+		/* set the ptrace bit in the process flags. */
+		current->flags |= PF_PTRACED;
+		return 0;
+	}
+	if (pid == 1) {		/* you may not mess with init */
+		set_failure(&regs,-EPERM);
+		return -EPERM;
 	}
 	if (!(child = get_task(pid))) {
-	   set_failure(&regs,-ESRCH);
-	   return -ESRCH;
+		set_failure(&regs,-ESRCH);
+		return -ESRCH;
 	}
 	if (request == PTRACE_ATTACH) {
-	   if (child == current) {
-	      set_failure(&regs,-EPERM);
-	      return -EPERM;
-	   }
-	   if ((!child->dumpable ||
-		(current->uid != child->euid) ||
-		(current->uid != child->uid) ||
-		(current->gid != child->egid) ||
-		(current->gid != child->gid)) && !suser()) {
-	      set_failure(&regs,-EPERM);
-	      return -EPERM;
-	   }
-	   /* the same process cannot be attached many times */
-	   if (child->flags & PF_PTRACED) {
-	      set_failure(&regs,-EPERM);
-	      return -EPERM;
-	   }
-	   child->flags |= PF_PTRACED;
-	   if (child->p_pptr != current) {
-	      REMOVE_LINKS(child);
-	      child->p_pptr = current;
-	      SET_LINKS(child);
-	   }
-	   send_sig(SIGSTOP, child, 1);
-	   return 0;
+		if (child == current) {
+			set_failure(&regs,-EPERM);
+			return -EPERM;
+		}
+		if ((!child->dumpable ||
+		     (current->uid != child->euid) ||
+		     (current->uid != child->uid) ||
+		     (current->gid != child->egid) ||
+		     (current->gid != child->gid)) && !suser()) {
+			set_failure(&regs,-EPERM);
+			return -EPERM;
+		}
+		/* the same process cannot be attached many times */
+		if (child->flags & PF_PTRACED) {
+			set_failure(&regs,-EPERM);
+			return -EPERM;
+		}
+		child->flags |= PF_PTRACED;
+		if (child->p_pptr != current) {
+			REMOVE_LINKS(child);
+			child->p_pptr = current;
+			SET_LINKS(child);
+		}
+		send_sig(SIGSTOP, child, 1);
+		return 0;
 	}
 	if (!(child->flags & PF_PTRACED)) {
-	    DBG(DBG_MEM, ("child not traced\n"));
-	    set_failure(&regs,-ESRCH);
-	    return -ESRCH;
+		DBG(DBG_MEM, ("child not traced\n"));
+		set_failure(&regs,-ESRCH);
+		return -ESRCH;
 	}
 	if (child->state != TASK_STOPPED) {
-	   DBG(DBG_MEM, ("child process not stopped\n"));
-	   if (request != PTRACE_KILL) {
-	      set_failure(&regs,-ESRCH);
-	      return -ESRCH;
-	   }
+		DBG(DBG_MEM, ("child process not stopped\n"));
+		if (request != PTRACE_KILL) {
+			set_failure(&regs,-ESRCH);
+			return -ESRCH;
+		}
 	}
 	if (child->p_pptr != current) {
-	   DBG(DBG_MEM, ("child not parent of this process\n"));
-	   set_failure(&regs,-ESRCH);
-	   return -ESRCH;
+		DBG(DBG_MEM, ("child not parent of this process\n"));
+		set_failure(&regs,-ESRCH);
+		return -ESRCH;
 	}
 
 	switch (request) {
@@ -621,12 +627,11 @@
 			DBG(DBG_MEM, ("doing request at addr 0x%lx\n",addr));
 			res = read_long(child, addr, &tmp);
 			if (res < 0) {
-			   set_failure(&regs,res);
-			   return res;
-			}
-			else {
-			   set_success(&regs,tmp);
-			   return 0;
+				set_failure(&regs,res);
+				return res;
+			} else {
+				set_success(&regs,tmp);
+				return 0;
 			}
 		}
 
@@ -636,21 +641,20 @@
 			unsigned long tmp;
 
 			tmp = 0;  /* Default return condition */
-			if(addr==30) {
-			   /* stack pointer */
-			   tmp=child->tss.usp;
-			}
-			else {
+			if (addr == 30) {
+				/* stack pointer */
+				tmp=child->tss.usp;
+			} else {
 #ifdef DEBUG
-			   int reg=addr;
+				int reg = addr;
 #endif
-			   addr = offset_of_register(addr);
-			   if (addr < 0) {
-			      set_failure(&regs, -EIO);
-			      return -EIO;
-			   }
-			   tmp = get_stack_long(child, addr);
-			   DBG(DBG_MEM, ("%d = reg 0x%lx=tmp\n",reg,tmp));
+				addr = offset_of_register(addr);
+				if (addr < 0) {
+					set_failure(&regs, -EIO);
+					return -EIO;
+				}
+				tmp = get_stack_long(child, addr);
+				DBG(DBG_MEM, ("%d = reg 0x%lx=tmp\n",reg,tmp));
 			}
 			set_success(&regs,tmp);
 			return 0;
@@ -659,34 +663,34 @@
       /* when I and D space are separate, this will have to be fixed. */
 		case PTRACE_POKETEXT: /* write the word at location addr. */
 		case PTRACE_POKEDATA: {
-			long res=write_long(child,addr,data);
-			if(res) {
-			   set_failure(&regs,res);
+			long res = write_long(child,addr,data);
+			if (res) {
+				set_failure(&regs,res);
 			}
 			return res;
 		}
 
 		case PTRACE_POKEUSR: /* write the specified register */
-		{
-		   long res;
-		   addr= offset_of_register(addr);
-		   if(addr < 0) {
-		      set_failure(&regs,-EIO);
-		      return -EIO;
-		   }
-		   res=put_stack_long(child,addr,data);
-		   if(res) {
-		      set_failure(&regs,res);
-		   }
-		   return res;
-		}
+		  {
+			  long res;
+			  addr = offset_of_register(addr);
+			  if(addr < 0) {
+				  set_failure(&regs,-EIO);
+				  return -EIO;
+			  }
+			  res = put_stack_long(child, addr, data);
+			  if (res) {
+				  set_failure(&regs,res);
+			  }
+			  return res;
+		  }
 
 		case PTRACE_SYSCALL: /* continue and stop at next 
 					(return from) syscall */
 		case PTRACE_CONT: { /* restart after signal. */
 			if ((unsigned long) data > NSIG) {
-			   set_failure(&regs,-EIO);
-			   return -EIO;
+				set_failure(&regs,-EIO);
+				return -EIO;
 			}
 			if (request == PTRACE_SYSCALL)
 				child->flags |= PF_TRACESYS;
@@ -694,12 +698,13 @@
 				child->flags &= ~PF_TRACESYS;
 			child->exit_code = data;
 			wake_up_process(child);
+        /* make sure single-step breakpoint is gone. */
 			ptrace_cancel_bpt(child);
 			set_success(&regs,data);
 			return 0;
 		}
 
- /*
+/*
  * make the child exit.  Best I can do is send it a sigkill. 
  * perhaps it should be put in the status that it wants to 
  * exit.
@@ -707,14 +712,15 @@
 		case PTRACE_KILL: {
 			wake_up_process(child);
 			child->exit_code = SIGKILL;
+        /* make sure single-step breakpoint is gone. */
 			ptrace_cancel_bpt(child);
 			return 0;
 		}
 
-		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+		case PTRACE_SINGLESTEP: {  /* execute signle instruction. */
 			if ((unsigned long) data > NSIG) {
-			   set_failure(&regs,-EIO);
-			   return -EIO;
+				set_failure(&regs,-EIO);
+				return -EIO;
 			}
 			res = set_bpt(child);
 			if (res < 0) {
@@ -723,14 +729,14 @@
 			child->flags &= ~PF_TRACESYS;
 			wake_up_process(child);
 			child->exit_code = data;
-			/* give it a chance to run. */
+	/* give it a chance to run. */
 			return 0;
 		}
 
 		case PTRACE_DETACH: { /* detach a process that was attached. */
 			if ((unsigned long) data > NSIG) {
-			   set_failure(&regs,-EIO);
-			   return -EIO;
+				set_failure(&regs,-EIO);
+				return -EIO;
 			}
 			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
 			wake_up_process(child);
@@ -738,17 +744,15 @@
 			REMOVE_LINKS(child);
 			child->p_pptr = child->p_opptr;
 			SET_LINKS(child);
-			/* make sure the single step bit is not set. */
+        /* make sure single-step breakpoint is gone. */
 			ptrace_cancel_bpt(child);
 			return 0;
 		}
 
 		default:
-		{
-		   set_failure(&regs,-EIO);
-		   return -EIO;
-		}
-	}
+		  set_failure(&regs,-EIO);
+		  return -EIO;
+	  }
 }
 
 asmlinkage void syscall_trace(void)
diff -u --recursive --new-file v1.3.11/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v1.3.11/linux/arch/alpha/kernel/setup.c	Tue Jun 27 14:11:30 1995
+++ linux/arch/alpha/kernel/setup.c	Mon Jul 24 17:38:25 1995
@@ -130,6 +130,9 @@
 	};
 	struct percpu_struct *cpu;
 	unsigned int cpu_index, system_index;
+	extern struct unaligned_stat {
+		unsigned long count, va, pc;
+	} unaligned;
 #	define N(a)	(sizeof(a)/sizeof(a[0]))
 
 	cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
@@ -151,7 +154,8 @@
 		       "page size [bytes]\t: %ld\n"
 		       "phys. address bits\t: %ld\n"
 		       "max. addr. space #\t: %ld\n"
-		       "BogoMIPS\t\t: %lu.%02lu\n",
+		       "BogoMIPS\t\t: %lu.%02lu\n"
+		       "unaligned accesses\t: %ld (pc=%lx,va=%lx)\n",
 
 		       (cpu_index < N(cpu_name) ? cpu_name[cpu_index] : "Unknown"),
 		       cpu->variation, cpu->revision, (char*)cpu->serial_no,
@@ -164,6 +168,7 @@
 		       hwrpb->pagesize,
 		       hwrpb->pa_bits,
 		       hwrpb->max_asn,
-		       loops_per_sec / 500000, (loops_per_sec / 5000) % 100);
+		       loops_per_sec / 500000, (loops_per_sec / 5000) % 100,
+		       unaligned.count, unaligned.pc, unaligned.va);
 #       undef N
 }
diff -u --recursive --new-file v1.3.11/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c
--- v1.3.11/linux/arch/alpha/kernel/signal.c	Thu Jun  1 13:22:06 1995
+++ linux/arch/alpha/kernel/signal.c	Mon Jul 24 17:38:25 1995
@@ -214,6 +214,9 @@
 	unsigned long pc = 0;
 	unsigned long signr;
 	struct sigaction * sa;
+	extern ptrace_cancel_bpt (struct task_struct *child);
+
+	ptrace_cancel_bpt(current);	/* make sure single-step bpt is gone */
 
 	while ((signr = current->signal & mask) != 0) {
 		signr = ffz(~signr);
diff -u --recursive --new-file v1.3.11/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v1.3.11/linux/arch/alpha/kernel/traps.c	Thu Jul 13 16:20:19 1995
+++ linux/arch/alpha/kernel/traps.c	Mon Jul 24 17:38:25 1995
@@ -67,8 +67,6 @@
 		if (ptrace_cancel_bpt(current)) {
 			regs.pc -= 4;	/* make pc point to former bpt */
 		}
-		if (current->flags & PF_PTRACED)
-		  current->blocked &= ~(1 << (SIGTRAP - 1));
 		send_sig(SIGTRAP, current, 1);
 		break;
 
@@ -90,9 +88,8 @@
  * fp-regs), and it needs to have them in order for simpler access.
  *
  * Due to the non-standard register layout (and because we don't want
- * to handle floating-point regs), we disallow user-mode unaligned
- * accesses (we'd need to do "verify_area()" checking, as well as
- * do a full "ret_from_sys_call" return).
+ * to handle floating-point regs), user-mode unaligned accesses are
+ * handled separately by do_entUnaUser below.
  *
  * Oh, btw, we don't handle the "gp" register correctly, but if we fault
  * on a gp-register unaligned load/store, something is _very_ wrong
@@ -103,17 +100,24 @@
 	unsigned long ps, pc, gp, a0, a1, a2;
 };
 
+struct unaligned_stat {
+	unsigned long count, va, pc;
+} unaligned;
+
 asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg,
 	unsigned long a3, unsigned long a4, unsigned long a5,
 	struct allregs regs)
 {
 	static int cnt = 0;
 
-	if (regs.ps & 8)
-		do_exit(SIGSEGV);
 	if (++cnt < 5)
 		printk("Unaligned trap at %016lx: %p %lx %ld\n",
 			regs.pc, va, opcode, reg);
+
+	++unaligned.count;
+	unaligned.va = (unsigned long) va - 4;
+	unaligned.pc = regs.pc;
+
 	/* $16-$18 are PAL-saved, and are offset by 19 entries */
 	if (reg >= 16 && reg <= 18)
 		reg += 19;
@@ -134,6 +138,22 @@
 	printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
 		regs.pc, va, opcode, reg);
 	do_exit(SIGSEGV);
+}
+
+/*
+ * Handle user-level unaligned fault.  For now, simply send a
+ * SIGSEGV---there should be little reason for users not wanting to
+ * fix their code instead.  Notice that we have the regular kernel
+ * stack layout here, so finding the appropriate registers is a little
+ * more difficult than in the kernel case.  Also, we'd need to do
+ * a "verify_area()" before accessing memory on behalf of the user.
+ */
+asmlinkage void do_entUnaUser(void *va, unsigned long opcode, unsigned long reg,
+			      unsigned long a3, unsigned long a4, unsigned long a5,
+			      struct pt_regs regs)
+{
+	regs.pc -= 4;	/* make pc point to faulting insn */
+	send_sig(SIGSEGV, current, 1);
 }
 
 /*
diff -u --recursive --new-file v1.3.11/linux/drivers/block/README.aztcd linux/drivers/block/README.aztcd
--- v1.3.11/linux/drivers/block/README.aztcd	Tue Jul 11 10:02:48 1995
+++ linux/drivers/block/README.aztcd	Tue Jul 25 10:17:15 1995
@@ -1,7 +1,7 @@
                        Readme-File README.aztcd
    for Aztech CD-ROM CDA268-01A, ORCHID CD-3110, OKANO/WEARNES CDD110 
                           CD-ROM  Driver 
-                       Version 1.2 and newer
+                       Version 1.4 and newer
                    (for other drives see 6.-8.)
 
 NOTE: THIS DRIVER WILL WORK WITH THE CD-ROM DRIVES LISTED, WHICH HAVE
@@ -104,6 +104,8 @@
   have to set up. If you have a soundcard, read chapter 4.2.
   Users of other drives should read chapter OTHER DRIVES of this file.
   You also can configure that address by LILO boot parameter aztcd=... 
+- There are some other points, which may be configured, e.g. auto-eject the
+  CD when umounting a drive, tray locking etc., see aztcd.h for details.
 - Build a new kernel, configure it for 'Aztech/Orchid/Okano/Wearnes support' 
   (if you want aztcd to be part of the kernel). Do not configure it for
   'Aztech... support', if you want to use aztcd as a run time loadable module. 
@@ -139,7 +141,9 @@
 kernel, if necessary. 
 
 Now edit the base address of your AZTECH interface card in
-/usr/src/linux/include/linux/aztcd.h to the appropriate value. Then change
+/usr/src/linux/include/linux/aztcd.h to the appropriate value. There are
+also some special features which may be configured, e.g. auto-eject a CD
+when unmounting the drive etc; see aztcd.h for details. Then change
 to /usr/src/linux and do a 
                     make modules  
 	            make modules_install
@@ -175,11 +179,12 @@
 
 5. KNOWN PROBLEMS, FUTURE DEVELOPMENTS
 5.1 MULTISESSION SUPPORT
-The driver does not support applications such as photo CD, multi session CD
-etc.. I do not plan to include the support for that in the driver, because I
-do not use such applications. If you are interested in that stuff and would
-like to extend the drivers capability on your own, please contact me, I'll
-support you as far as I can. 
+I have now (July 1995) started support of multisession CDs. Unfortunately I
+do neither have a multisession CD nor use appropriate applications, so I can
+program, but will not test it :-(. If you'd like to help me, please contact
+me. As of version 1.4 you can enable the multisession support in aztcd.h by
+setting AZT_MULTISESSION to 1. As I have not tested it, I don't know, if it
+works ...
 
 5.2 STATUS RECOGNITION
 The drive status recognition does not work correctly in all cases. Changing
@@ -210,7 +215,10 @@
 in combination with aztcd :-) ! Unfortunately up to now, I could not locate
 the root cause of that problem. It seems to be somewhere in the interaction
 of the kernel with dosemu's and aztcd's buffers. I appreciate any help on
-this subject !
+this subject ! 
+This problem has now (July 1995) been fixed by a modification to dosemu's
+CD-ROM driver, but it is unclear, with which version of dosemu this modi-
+fication will officially be included.
 
 6. BUG REPORTS
 Please send detailed bug reports and bug fixes via EMail to
diff -u --recursive --new-file v1.3.11/linux/drivers/block/README.cm206 linux/drivers/block/README.cm206
--- v1.3.11/linux/drivers/block/README.cm206	Fri Jul  7 08:54:44 1995
+++ linux/drivers/block/README.cm206	Wed Jul 19 10:15:42 1995
@@ -6,7 +6,8 @@
 Features as of version 0.33
 ---------------------------
 - Full audio support, that is, both  workman, workbone and cdp work
-  now reasonably. Reading TOC still takes some time. 
+  now reasonably. Reading TOC still takes some time. xmcd has been
+  reported to run successfully. 
 - Made auto-probe code a little better, i hope
 
 Features as of version 0.28
@@ -41,12 +42,6 @@
    autoprobing, which is the default. In that case you can move on to
    the next step.
 
-   If autoprobing does not work, you can hard-wire the default values
-   of the base port address (CM206_BASE) and interrupt request line
-   (CM206_IRQ) into the file ./linux/drivers/block/cm206.c. Uncomment
-   the defines of CM206_IRQ and CM206_BASE, and change there meaning
-   to the appropriate values, if necessary.
-
 Compiling the kernel
 --------------------
 1) move to /usr/src/linux and do a 
@@ -54,14 +49,14 @@
 	make config
 
    If you have chosen for option (a), answer yes to CONFIG_CM206 and
-   CONFIG_ISO9660_FS (should be default).
+   CONFIG_ISO9660_FS.
 
    If you have chosen for option (b), answer yes to CONFIG_MODVERSIONS
    and no (!) to CONFIG_CM206 and CONFIG_ISO9660_FS. 
 
 2) then do a 
 	
-	make dep; make zImage; make modules
+	make dep; make clean; make zImage; make modules
 
 3) do the usual things to install a new image (backup the old one, run
    `rdev -R zImage 1', copy the new image in place, run lilo).  Might
@@ -82,8 +77,10 @@
 
 	insmod /usr/src/linux/modules/cm206.o cm206=0x300,11
 
-You may also have to install the file-system module `iso9660.o', if you
-didn't compile that into the kernel. If you use `tcsh' as shell, you
+The order of base port and irq line don't matter; you may specify only
+one, the other will have the value of the compiled-in default.  You
+may also have to install the file-system module `iso9660.o', if you
+didn't compile that into the kernel. (If you use `tcsh' as shell, you
 might consider defining
 
 	alias listinstalledmodules 'cat /proc/modules | awk \{print\$1\}'
@@ -92,7 +89,7 @@
 	alias insmod		'insmod /usr/src/linux/modules/\!:1 \!:2*'
 	complete insmod		'p/1/`listcompiledmodules`/'
 
-which makes typing insmod and rmmod somewhat easier. 
+which makes typing insmod and rmmod somewhat easier.)
 
 Using the driver as part of the kernel
 --------------------------------------
@@ -105,6 +102,15 @@
 If you may specify either IRQ (3--11) or base port (0x300--0x370),
 auto probing is turned off for both settings, thus setting the 
 other value to the compiled-in default.
+
+If module parameters and LILO config options don't work
+-------------------------------------------------------
+If autoprobing does not work, you can hard-wire the default values
+of the base port address (CM206_BASE) and interrupt request line
+(CM206_IRQ) into the file ./include/linux/cm206.h. Change
+the defines of CM206_IRQ and CM206_BASE.
+
+
 
 Mounting the cdrom
 ------------------
diff -u --recursive --new-file v1.3.11/linux/drivers/block/aztcd.c linux/drivers/block/aztcd.c
--- v1.3.11/linux/drivers/block/aztcd.c	Tue Jul 11 10:02:49 1995
+++ linux/drivers/block/aztcd.c	Tue Jul 25 10:17:15 1995
@@ -1,5 +1,5 @@
-#define AZT_VERSION "1.30"
-/*      $Id: aztcd.c,v 1.30 1995/07/04 08:28:06 root Exp $
+#define AZT_VERSION "1.40"
+/*      $Id: aztcd.c,v 1.40 1995/07/15 20:35:15 root Exp root $
 	linux/drivers/block/aztcd.c - AztechCD268 CDROM driver
 
 	Copyright (C) 1994,1995 Werner Zimmermann (zimmerma@rz.fht-esslingen.de)
@@ -116,6 +116,10 @@
                 Werner Zimmermann, May 22, 95
 	V1.30   Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
 	        Werner Zimmermann, July 4, 95
+	V1.40   Started multisession support. Implementation copied from mcdx.c
+	        by Heiko Schlittermann. Not tested, as I do not have a multi-
+	        session CD. If you can test it, please contact me.
+	        Werner Zimmermann, July 15, 95
 	NOTE: 
 	Points marked with ??? are questionable !
 */
@@ -189,7 +193,7 @@
 static volatile int azt_transfer_is_active=0;
 
 static char azt_buf[2048*AZT_BUF_SIZ];  /*buffer for block size conversion*/
-#ifdef AZT_PRIVATE_IOCTLS
+#if AZT_PRIVATE_IOCTLS
 static char buf[2336];                  /*separate buffer for the ioctls*/
 #endif
 
@@ -364,7 +368,7 @@
 
 static void aztLockDoor(void)
 {
-#ifdef AZT_ALLOW_TRAY_LOCK
+#if AZT_ALLOW_TRAY_LOCK
   aztSendCmd(ACMD_LOCK);
   STEN_LOW;
 #endif
@@ -373,7 +377,7 @@
 
 static void aztUnlockDoor(void)
 {
-#ifdef AZT_ALLOW_TRAY_LOCK
+#if AZT_ALLOW_TRAY_LOCK
   aztSendCmd(ACMD_UNLOCK);
   STEN_LOW;
 #endif
@@ -523,7 +527,7 @@
 
 long azt_msf2hsg(struct msf *mp)
 { return azt_bcd2bin(mp -> frame) + azt_bcd2bin(mp -> sec) * 75
-		                  + azt_bcd2bin(mp -> min) * 4500 - 150;
+		                  + azt_bcd2bin(mp -> min) * 4500 - CD_BLOCK_OFFSET;
 }
 
 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
@@ -550,7 +554,7 @@
 	{
 	case CDROMSTART:     /* Spin up the drive. Don't know, what to do,
 	                        at least close the tray */
-#ifdef AZT_PRIVATE_IOCTLS 
+#if AZT_PRIVATE_IOCTLS 
 	        if (aztSendCmd(ACMD_CLOSE)) RETURNM("aztcd_ioctl 4",-1);
 	        STEN_LOW_WAIT;
 #endif
@@ -585,6 +589,47 @@
 		}
 		aztAudioStatus = CDROM_AUDIO_PLAY;
 		break;
+#if AZT_MULTISESSION
+	case CDROMMULTISESSION: /*multisession support -- not tested ???*/
+	        { struct cdrom_multisession ms;
+#ifdef AZT_DEBUG
+   		  printk("aztcd ioctl MULTISESSION\n");
+#endif
+		  st = verify_area(VERIFY_READ, (void*) arg, sizeof(struct cdrom_multisession));
+		  if (st) return st;
+		  memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession));
+		  if (ms.addr_format == CDROM_MSF) 
+		     { ms.addr.msf.minute = azt_bcd2bin(DiskInfo.lastTrack.min);
+		       ms.addr.msf.second = azt_bcd2bin(DiskInfo.lastTrack.sec);
+		       ms.addr.msf.frame  = azt_bcd2bin(DiskInfo.lastTrack.frame);
+		     } 
+		  else if (ms.addr_format == CDROM_LBA)
+		       ms.addr.lba = azt_msf2hsg(&DiskInfo.lastTrack);
+		  else
+		       return -EINVAL;
+		  if (DiskInfo.type == CD_XA) 
+		     { ms.xa_flag = 0x01;   	/*XA-Disk*/
+		     }
+		  else
+		     { ms.xa_flag = 0x00;   
+		     }
+ 		  st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession));
+		  if (st) return st;
+	  	  memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));
+#ifdef AZT_DEBUG 
+ 		  if (ms.addr_format == CDROM_MSF) 
+                      printk("aztcd multisession %d, %02x:%02x.%02x [%02x:%02x.%02x])\n",
+			      ms.xa_flag, ms.addr.msf.minute, ms.addr.msf.second, 
+			      ms.addr.msf.frame, DiskInfo.lastTrack.min,
+			      DiskInfo.lastTrack.sec, DiskInfo.lastTrack.frame);
+		  else
+		      printk("atzcd multisession %d, 0x%08x [%02x:%02x.%02x])\n",
+			      ms.xa_flag, ms.addr.lba, DiskInfo.lastTrack.min,
+			      DiskInfo.lastTrack.sec, DiskInfo.lastTrack.frame);
+#endif
+   		  return 0;
+		}
+#endif
 	case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
 		st = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
 		if (st) return st;
@@ -595,7 +640,7 @@
 		{ return -EINVAL;
 		}
 		if (ti.cdti_trk1 > DiskInfo.last)
-		   ti. cdti_trk1 = DiskInfo.last;
+		    ti.cdti_trk1 = DiskInfo.last;
 		azt_Play.start = Toc[ti.cdti_trk0].diskTime;
 		azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
 #ifdef AZT_DEBUG
@@ -758,10 +803,10 @@
 	case CDROMREADMODE1: /*read data in mode 1 (2048 Bytes)*/
 	case CDROMREADMODE2: /*read data in mode 2 (2336 Bytes)*/
 /*Take care, the following code is not compatible with other CD-ROM drivers,
-  use it at your own risk with cdplay.c. Normally it is not activated, as 
-  AZT_PRIVATE_IOCTLS is not defined
+  use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
+  if you do not want to use it!
 */                  
-#ifdef AZT_PRIVATE_IOCTLS 
+#if AZT_PRIVATE_IOCTLS 
 		{ st = verify_area(VERIFY_READ,  (void *) arg, sizeof msf);
 		  if (st) return st;
 		  st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf);
@@ -1653,12 +1698,12 @@
   for (limit=300;limit>0;limit--)
    {  if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetDiskInfo 2",-1);
       if (qInfo.pointIndex==0xA0)   /*Number of FirstTrack*/
-	{ DiskInfo.first=qInfo.diskTime.min;
+	{ DiskInfo.first = qInfo.diskTime.min;
 	  DiskInfo.first = azt_bcd2bin(DiskInfo.first);
 	  test=test|0x01;
 	}
       if (qInfo.pointIndex==0xA1)   /*Number of LastTrack*/
-	{ DiskInfo.last=qInfo.diskTime.min;
+	{ DiskInfo.last  = qInfo.diskTime.min;
 	  DiskInfo.last  = azt_bcd2bin(DiskInfo.last);
 	  test=test|0x02;
 	}
@@ -1692,7 +1737,6 @@
   return 0;
 }
 
-
 /*
  * Read the table of contents (TOC)
  */
@@ -1737,6 +1781,18 @@
 
 	Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
 
+        DiskInfo.lastTrack.sec=2;
+        DiskInfo.type = 0; 
+        for (i=0;i<=DiskInfo.last;i++) /*Unterscheidung zw. Audio- und Datendisk???*/
+          { if ((Toc[i].ctrl_addr)==0x01)      
+                DiskInfo.type=DiskInfo.type|CD_AUDIO; 
+            if ((Toc[i].ctrl_addr)==0x41)
+                DiskInfo.type=DiskInfo.type|CD_DATA;     
+          }
+        DiskInfo.lastTrack.min  =Toc[DiskInfo.last].diskTime.min;
+	DiskInfo.lastTrack.sec  =Toc[DiskInfo.last].diskTime.sec;
+        DiskInfo.lastTrack.frame=Toc[DiskInfo.last].diskTime.frame;
+
 #ifdef AZT_DEBUG
 printk("aztcd: exiting aztGetToc  Time:%li\n",jiffies);
 for (i = 1; i <= DiskInfo.last+1; i++)
@@ -1749,6 +1805,19 @@
 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
 Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
 Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+printk("\nDisk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x last %02x:%02x.%02x type %02x\n",
+	DiskInfo.first,
+	DiskInfo.last,
+	DiskInfo.diskLength.min,
+	DiskInfo.diskLength.sec,
+	DiskInfo.diskLength.frame,
+	DiskInfo.firstTrack.min,
+	DiskInfo.firstTrack.sec,
+	DiskInfo.firstTrack.frame,
+	DiskInfo.lastTrack.min,
+	DiskInfo.lastTrack.sec,
+	DiskInfo.lastTrack.frame,
+        DiskInfo.type);
 #endif
 
 	return limit > 0 ? 0 : -1;
diff -u --recursive --new-file v1.3.11/linux/drivers/block/cdu31a.c linux/drivers/block/cdu31a.c
--- v1.3.11/linux/drivers/block/cdu31a.c	Thu Jul 13 16:20:20 1995
+++ linux/drivers/block/cdu31a.c	Wed Jul 19 08:40:50 1995
@@ -325,6 +325,11 @@
 static int readahead_dataleft = 0;
 static int readahead_bad = 0;
 
+/* Used to time a short period to abort an operation after the
+   drive has been idle for a while.  This keeps the light on
+   the drive from flashing for very long. */
+static struct timer_list cdu31a_abort_timer;
+
 
 /*
  * This routine returns 1 if the disk has been changed since the last
@@ -1096,6 +1101,14 @@
    readahead_bad = 0;
 }
 
+/* Called when the timer times out.  This will abort the
+   pending read operation. */
+static void
+handle_abort_timeout(unsigned long data)
+{
+   abort_read();
+}
+
 /* Actually get data and status from the drive. */
 static void
 input_data(char         *buffer,
@@ -1392,17 +1405,24 @@
          {
             end_request(0);
          }
+         restore_flags(flags);
          return;
       }
    }
    sony_inuse = 1;
    has_cd_task = current;
-   restore_flags(flags);
+   sti();
 
    /* Get drive status before doing anything. */
    while (handle_sony_cd_attention())
       ;
 
+   /* If the timer is running, cancel it. */
+   if (cdu31a_abort_timer.next != NULL)
+   {
+      del_timer(&cdu31a_abort_timer);
+   }
+
    while (1)
    {
 cdu31a_request_startover:
@@ -1573,14 +1593,20 @@
    }
 
 end_do_cdu31a_request:
-#if 1
+#if 0
    /* After finished, cancel any pending operations. */
    abort_read();
+#else
+   /* Start a timer to time out after a while to disable
+      the read. */
+   cdu31a_abort_timer.expires = 200; /* Wait 2 seconds */
+   add_timer(&cdu31a_abort_timer);
 #endif
 
    has_cd_task = NULL;
    sony_inuse = 0;
    wake_up_interruptible(&sony_wait);
+   restore_flags(flags);
 }
 
 /* Copy overlapping buffers. */
@@ -2969,6 +2995,10 @@
       mem_start += CD_FRAMESIZE_RAW;
       sony_toc = (struct s_sony_session_toc *) mem_start;
       mem_start += sizeof(struct s_sony_session_toc);
+
+      cdu31a_abort_timer.next = NULL;
+      cdu31a_abort_timer.prev = NULL;
+      cdu31a_abort_timer.function = handle_abort_timeout;
    }
 
 
diff -u --recursive --new-file v1.3.11/linux/drivers/block/cm206.c linux/drivers/block/cm206.c
--- v1.3.11/linux/drivers/block/cm206.c	Fri Jul  7 08:54:44 1995
+++ linux/drivers/block/cm206.c	Wed Jul 19 10:15:42 1995
@@ -53,6 +53,12 @@
   1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
  10 jun 1995: 0.33 Workman still behaves funny, but you should be
               able to eject and substitute another disc.
+
+ An adaption of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
+
+ 18 jul 1996: 0.34 Patch by Heiko Eissfeldt included, mainly considering 
+              verify_area's in the ioctls. Some bugs introduced by 
+	      EM considering the base port and irq fixed. 
  * 
  * Parts of the code are based upon lmscd.c written by Kai Petzke,
  * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
@@ -73,7 +79,7 @@
  * - Philips/LMS cm260 product specification
  *
  *                       David van Leeuwen, david@tm.tno.nl.  */
-#define VERSION "0.33"
+#define VERSION "0.34"
 
 #ifdef MODULE			/* OK, so some of this is stolen */
 #include <linux/module.h>	
@@ -95,6 +101,7 @@
 #include <linux/timer.h>
 #include <linux/cdrom.h>
 #include <linux/ioport.h>
+#include <linux/mm.h>
 
 #include <asm/io.h>
 
@@ -108,9 +115,8 @@
 */
 static int auto_probe=1;	/* Yes, why not? */
 
-#define cm206_base cm206 /* for compatible "insmod" parameter passing */
 static int cm206_base = CM206_BASE;
-static int cm206_irq = CM206_IRQ; /* must directly follow cm206_base */
+static int cm206_irq = CM206_IRQ; 
 
 #undef DEBUG
 #undef DEBUG_SECTORS
@@ -674,10 +680,19 @@
 int get_multi_session_info(struct cdrom_multisession * mssp)
 {
   if (!FIRST_TRACK) get_disc_status();
-  if (mssp && DISC_STATUS & cds_multi_session) { /* multi-session */
-    mssp->addr.lba = fsm2lba(&cd->disc_status[3]);
-    mssp->xa_flag = 1;		/* don't know */
-    mssp->addr_format = CDROM_LBA; /* too bad if fsm requested! */
+  if (mssp) {
+    if (DISC_STATUS & cds_multi_session) { /* multi-session */
+      if (mssp->addr_format == CDROM_LBA)
+      	mssp->addr.lba = fsm2lba(&cd->disc_status[3]);
+      else {
+      	mssp->addr.msf.frame = cd->disc_status[3];
+      	mssp->addr.msf.second = cd->disc_status[4];
+      	mssp->addr.msf.minute = cd->disc_status[5];
+      }
+      mssp->xa_flag = 1;
+    } else {
+      mssp->xa_flag = 0;
+    }
     return 1;
   }
   return 0;
@@ -889,33 +904,41 @@
 #endif    
   case CDROMMULTISESSION: {
     struct cdrom_multisession ms_info;
+    int st;
     stats(ioctl_multisession);
-    if (get_multi_session_info(&ms_info)) {
-      memcpy_tofs((struct cdrom_multisession *) arg, &ms_info, 
+
+    st=verify_area(VERIFY_WRITE, (void *) arg, 
+		   sizeof(struct cdrom_multisession));
+    if (st) return (st);
+    memcpy_fromfs(&ms_info, (struct cdrom_multisession *) arg,
 		  sizeof(struct cdrom_multisession));
-      return 0;
-    }
-    else return -cmd;
+    get_multi_session_info(&ms_info);
+    memcpy_tofs((struct cdrom_multisession *) arg, &ms_info, 
+		  sizeof(struct cdrom_multisession));
+    return 0;
   }
-  case CM206_RESET_DRIVE:
+  case CDROMRESET:		/* If needed, it's probably too late anyway */
     stop_read();
     reset_cm260();
     outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
     udelay(1000);		/* 750 musec minimum */
     outw(dc_normal | READ_AHEAD, r_data_control);
-    cd->sector_last = -1;		/* flag no data buffered */
+    cd->sector_last = -1;	/* flag no data buffered */
     cd->adapter_last = -1;    
     return 0;
   }
+
   get_drive_status();
   if (cd->dsb & (dsb_drive_not_ready | dsb_tray_not_closed) )
     return -EAGAIN; 
+
   switch (cmd) {
   case CDROMREADTOCHDR: {
     struct cdrom_tochdr header;
-    get_drive_status();
-    if (cd->dsb & (dsb_drive_not_ready | dsb_tray_not_closed) )
-      return -EAGAIN; 
+    int st;
+
+    st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(header));
+    if (st) return (st);
     if (read_toc_header(&header)) {
       memcpy_tofs((struct cdrom_tochdr *) arg, &header, sizeof(header));
       return 0;
@@ -924,6 +947,10 @@
   }
   case CDROMREADTOCENTRY: {	
     struct cdrom_tocentry entry;
+    int st;
+
+    st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(entry));
+    if (st) return (st);
     memcpy_fromfs(&entry, (struct cdrom_tocentry *) arg, sizeof entry);
     get_toc_entry(&entry);
     memcpy_tofs((struct cdrom_tocentry *) arg, &entry, sizeof entry);
@@ -931,12 +958,20 @@
   }
   case CDROMPLAYMSF: {
     struct cdrom_msf msf;
+    int st;
+
+    st=verify_area(VERIFY_READ, (void *) arg, sizeof(msf));
+    if (st) return (st);
     memcpy_fromfs(&msf, (struct cdrom_mdf *) arg, sizeof msf);
     play_from_to_msf(&msf);
     return 0;
   }
   case CDROMPLAYTRKIND: {
     struct cdrom_ti track_index;
+    int st;
+
+    st=verify_area(VERIFY_READ, (void *) arg, sizeof(track_index));
+    if (st) return (st);
     memcpy_fromfs(&track_index, (struct cdrom_ti *) arg, sizeof(track_index));
     play_from_to_track(track_index.cdti_trk0, track_index.cdti_trk1);
     return 0;
@@ -970,6 +1005,10 @@
     return 0;
   case CDROMSUBCHNL: {
     struct cdrom_subchnl q;
+    int st;
+
+    st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(q));
+    if (st) return (st);
     memcpy_fromfs(&q, (struct cdrom_subchnl *) arg, sizeof q);
     if (get_current_q(&q)) {
       memcpy_tofs((struct cdrom_subchnl *) arg, &q, sizeof q);
@@ -979,6 +1018,10 @@
   }
   case CDROM_GET_UPC: {
     uch upc[10];
+    int st;
+
+    st=verify_area(VERIFY_WRITE, (void *) arg, 8);
+    if (st) return (st);
     if (type_1_command(c_read_upc, 10, upc)) return -EIO;
     memcpy_tofs((uch *) arg, &upc[1], 8);
     return 0;
@@ -1081,14 +1124,36 @@
 }
 #endif
 
-/* Wow is this piece of #ifdeffing ugly! */
 #ifdef MODULE
 #define OK  0
 #define ERROR  -EIO
-int init_module(void)
-#else
+
+static int cm206[2] = {0,0};	/* for compatible `insmod' parameter passing */
+void parse_options() 
+{
+  int i;
+  for (i=0; i<2; i++) {
+    if (0x300 <= cm206[i] && i<= 0x370 && cm206[i] % 0x10 == 0) {
+      cm206_base = cm206[i];
+      auto_probe=0;
+    }
+    else if (3 <= cm206[i] && cm206[i] <= 15) {
+      cm206_irq = cm206[i];
+      auto_probe=0;
+    }
+  }
+}
+
+#else MODULE
+
 #define OK  mem_start+size
 #define ERROR  mem_start
+
+#endif MODULE
+
+#ifdef MODULE
+int init_module(void)
+#else 
 unsigned long cm206_init(unsigned long mem_start, unsigned long mem_end)
 #endif
 {
@@ -1096,8 +1161,11 @@
   long int size=sizeof(struct cm206_struct);
 
   printk("cm206: v" VERSION);
-#if defined(MODULE) && !defined(AUTO_PROBE_MODULE)
-  auto_probe=0;
+#if defined(MODULE) 
+  parse_options();
+#if !defined(AUTO_PROBE_MODULE)
+   auto_probe=0;
+#endif
 #endif
   cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
   if (!cm206_base) {
@@ -1173,7 +1241,7 @@
   cleanup(4);
   printk("cm206 removed\n");
 }
-
+      
 #else MODULE
 
 /* This setup function accepts either `auto' or numbers in the range
@@ -1181,9 +1249,7 @@
 void cm206_setup(char *s, int *p)
 {
   int i;
-#ifdef AUTO_PROBE_MODULE
   if (!strcmp(s, "auto")) auto_probe=1;
-#endif
   for(i=1; i<=p[0]; i++) {
     if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) {
       cm206_base = p[i];
diff -u --recursive --new-file v1.3.11/linux/drivers/block/mcd.c linux/drivers/block/mcd.c
--- v1.3.11/linux/drivers/block/mcd.c	Fri Jul  7 08:54:45 1995
+++ linux/drivers/block/mcd.c	Tue Jul 25 10:17:15 1995
@@ -38,9 +38,28 @@
 	November 93 added code for FX001 S,D (single & double speed).
 	February 94 added code for broken M 5/6 series of 16-bit single speed.
 
-        0.4   Added support for loadable MODULEs, so mcd can now also be
-              loaded by insmod and removed by rmmod during runtime.
-              Werner Zimmermann (zimmerma@rz.fht-esslingen.de), Mar. 26, 95
+
+        0.4   
+        Added support for loadable MODULEs, so mcd can now also be loaded by 
+        insmod and removed by rmmod during runtime.
+        Werner Zimmermann (zimmerma@rz.fht-esslingen.de), Mar. 26, 95
+
+	0.5
+	I added code for FX001 D to drop from double speed to single speed 
+	when encountering errors... this helps with some "problematic" CD's
+	that are supposedly "OUT OF TOLERANCE" (but are really shitty presses!)
+	severly scratched, or possibly slightly warped! I have noticed that
+	the Mitsumi 2x/4x drives are just less tolerant and the firmware is 
+	not smart enough to drop speed,	so let's just kludge it with software!
+	****** THE 4X SPEED MITSUMI DRIVES HAVE THE SAME PROBLEM!!!!!! ******
+	Anyone want to "DONATE" one to me?! ;) I hear sometimes they are
+	even WORSE! ;)
+	** HINT... HINT... TAKE NOTES MITSUMI This could save some hassels with
+	certain "large" CD's that have data on the outside edge in your 
+	DOS DRIVERS .... Accuracy counts... speed is secondary ;)
+	17 June 95 Modifications By Andrew J. Kroll <ag784@freenet.buffalo.edu>
+	07 July 1995 Modifications by Andrew J. Kroll
+
 */
 
 #include <linux/config.h>
@@ -82,6 +101,24 @@
 static int mcd_sizes[] = { 0 };
 #endif
 
+/* I know putting defines in this file is probably stupid, but it should be */
+/* the only place that they are really needed... I HOPE! :) */
+
+/* How many sectors to read at 1x when an error at 2x speed occurs. */
+/* You can change this to anything from 2 to 32767, but 30 seems to */
+/* work best for me.  I have found that when the drive has problems */
+/* reading one sector, it will have troubles reading the next few.  */
+#define SINGLE_HOLD_SECTORS 30	
+
+#define MCMD_2X_READ 0xC1	/* Double Speed Read DON'T TOUCH! */
+
+/* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */
+static int mcdDouble = 0; 
+
+/* How many sectors to hold at 1x speed counter */
+static int mcd1xhold = 0;
+
+/* Is the drive connected properly and responding?? */
 static int mcdPresent = 0;
 
 #if 0
@@ -667,35 +704,71 @@
   int st;
 
 
-  if (mcd_error) {
-    if (mcd_error & 0xA5) {
+  if (mcd_error) 
+  {
+    if (mcd_error & 0xA5) 
+    {
       printk("mcd: I/O error 0x%02x", mcd_error);
       if (mcd_error & 0x80)
 	printk(" (Door open)");
       if (mcd_error & 0x20)
 	printk(" (Disk changed)");
       if (mcd_error & 0x04)
-	printk(" (Read error)");
+	{
+	printk(" (Read error)"); /* Bitch about the problem. */
+	
+	/* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */
+	/* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */
+	/* But I find that rather HANDY!!! */
+	/* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */
+	/* AJK [06/17/95] */
+	
+	/* Slap the CD down to single speed! */
+	if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_2X_READ) 
+		{
+		MCMD_DATA_READ = MCMD_PLAY_READ; /* Uhhh, Ummmm, muhuh-huh! */
+		mcd1xhold = SINGLE_HOLD_SECTORS; /* Hey Bevis! */
+		printk(" Speed now 1x");	 /* Pull my finger! */
+		}
+	}
       printk("\n");
       mcd_invalidate_buffers();
 #ifdef WARN_IF_READ_FAILURE
-      if (McdTries == 5)
+      if (McdTries == MCD_RETRY_ATTEMPTS)
 	printk("mcd: read of block %d failed\n", mcd_next_bn);
 #endif
-      if (!McdTries--) {
+      if (!McdTries--) 
+        {
+	/* Nuts! This cd is ready for recycling! */
+	/* When WAS the last time YOU cleaned it CORRECTLY?! */
 	printk("mcd: read of block %d failed, giving up\n", mcd_next_bn);
-	if (mcd_transfer_is_active) {
+	if (mcd_transfer_is_active) 
+	{
 	  McdTries = 0;
 	  goto ret;
 	}
 	if (CURRENT_VALID)
 	  end_request(0);
-	McdTries = 5;
+	McdTries = MCD_RETRY_ATTEMPTS;
       }
     }
     mcd_error = 0;
     mcd_state = MCD_S_STOP;
   }
+	/* Switch back to Double speed if enough GOOD sectors were read! */
+	
+	/* Are we a double speed with a crappy CD?! */
+    if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_PLAY_READ)
+    	{
+	/* We ARE a double speed and we ARE bitching! */
+	if (mcd1xhold == 0) /* Okay, Like are we STILL at single speed? */
+		{ /* We need to switch back to double speed now... */
+		MCMD_DATA_READ = MCMD_2X_READ; /* Uhhh... BACK You GO! */
+		printk("mcd: Switching back to 2X speed!\n"); /* Tell 'em! */
+		}
+	else mcd1xhold--; /* No?! Count down the good reads some more... */
+				/* and try, try again! */
+    	}
 
 
 
@@ -1183,10 +1256,16 @@
 #else
                 return -EIO;
 #endif
-	printk("Mitsumi status, type and version : %02X %c %x\n",
+	printk("Mitsumi status, type and version : %02X %c %x ",
 	       result[0],result[1],result[2]);
 
-	if (result[1] == 'D') MCMD_DATA_READ= 0xC1;
+     if (result[1] == 'D') 
+	{
+	printk("Double Speed CD ROM\n");
+	MCMD_DATA_READ = MCMD_2X_READ;
+        mcdDouble = 1; /* Added flag to drop to 1x speed if too many errors */
+        }
+       else printk("Single Speed CD ROM\n");
 
 	mcdVersion=result[2];
 
diff -u --recursive --new-file v1.3.11/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v1.3.11/linux/drivers/char/Makefile	Tue Jul 11 10:02:49 1995
+++ linux/drivers/char/Makefile	Thu Jul 20 09:19:46 1995
@@ -83,7 +83,7 @@
 endif
  
 
-all: char.a
+all: uni_hash_tbl.h char.a
 
 char.a: $(OBJS)
 	$(AR) rcs char.a $(OBJS)
diff -u --recursive --new-file v1.3.11/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v1.3.11/linux/drivers/net/de4x5.c	Fri Jul  7 08:54:47 1995
+++ linux/drivers/net/de4x5.c	Mon Jul 24 17:38:25 1995
@@ -213,7 +213,7 @@
 #define MIN_DAT_SZ   	1               /* Minimum ethernet data length */
 #define PKT_HDR_LEN     14              /* Addresses and data length info */
 #define FAKE_FRAME_LEN  (MAX_PKT_SZ + 1)
-#define QUEUE_PKT_TIMEOUT (300)         /* Jiffies */
+#define QUEUE_PKT_TIMEOUT (3*HZ)        /* 3 second timeout */
 
 
 #define CRC_POLYNOMIAL_BE 0x04c11db7UL   /* Ethernet CRC, big endian */
@@ -916,7 +916,7 @@
   outl(omr|OMR_ST, DE4X5_OMR);
 
   /* Poll for completion of setup frame (interrupts are disabled for now) */
-  for (j=0, i=jiffies;(i==jiffies) && (j==0);) {
+  for (j=0, i=jiffies;(i<=jiffies+HZ/100) && (j==0);) {
     if (lp->tx_ring[lp->tx_new].status >= 0) j=1;
   }
   outl(omr, DE4X5_OMR);                        /* Stop everything! */
@@ -973,7 +973,7 @@
       status = -1;
     } else {
       if (de4x5_debug >= 1) {
-	printk("%s: transmit timed out, status %08x, tbusy:%d, lostMedia:%d tickssofar:%ld, resetting.\n",dev->name, inl(DE4X5_STS), dev->tbusy, lp->lostMedia, tickssofar);
+	printk("%s: transmit timed out, status %08x, tbusy:%ld, lostMedia:%d tickssofar:%ld, resetting.\n",dev->name, inl(DE4X5_STS), dev->tbusy, lp->lostMedia, tickssofar);
       }
 
       /* Stop and reset the TX and RX... */
diff -u --recursive --new-file v1.3.11/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v1.3.11/linux/drivers/net/depca.c	Fri Jul  7 08:54:47 1995
+++ linux/drivers/net/depca.c	Mon Jul 24 17:38:25 1995
@@ -817,7 +817,7 @@
   /* Transmitter timeout, serious problems. */
   if (dev->tbusy) {
     int tickssofar = jiffies - dev->trans_start;
-    if (tickssofar < 100) {
+    if (tickssofar < 1*HZ) {
       status = -1;
     } else {
       printk("%s: transmit timed out, status %04x, resetting.\n",
diff -u --recursive --new-file v1.3.11/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- v1.3.11/linux/drivers/net/loopback.c	Thu Jul 13 16:20:20 1995
+++ linux/drivers/net/loopback.c	Wed Jul 19 14:36:46 1995
@@ -101,6 +101,7 @@
 	restore_flags(flags);
   
 	stats->tx_packets++;
+	stats->rx_packets++;
 
 	dev->tbusy = 0;
 
diff -u --recursive --new-file v1.3.11/linux/drivers/net/slhc.c linux/drivers/net/slhc.c
--- v1.3.11/linux/drivers/net/slhc.c	Tue Jun  6 12:23:16 1995
+++ linux/drivers/net/slhc.c	Tue Jul 25 10:10:10 1995
@@ -615,8 +615,8 @@
 	cp += 20;
 
 	if (ip->ihl > 5) {
-	  memcpy(cp, cs->cs_ipopt, ((ip->ihl) - 5) * 4);
-	  cp += ((ip->ihl) - 5) * 4;
+	  memcpy(cp, cs->cs_ipopt, (ip->ihl - 5) * 4);
+	  cp += (ip->ihl - 5) * 4;
 	}
 
 	((struct iphdr *)icp)->check = ip_fast_csum(icp, ((struct iphdr*)icp)->ihl);
@@ -640,9 +640,7 @@
 slhc_remember(struct slcompress *comp, unsigned char *icp, int isize)
 {
 	register struct cstate *cs;
-	short ip_len;
-	struct iphdr *ip;
-	struct tcphdr *thp;
+	unsigned ihl;
 
 	unsigned char index;
 
@@ -651,23 +649,21 @@
 		comp->sls_i_runt++;
 		return slhc_toss( comp );
 	}
-	/* Sneak a peek at the IP header's IHL field to find its length */
-	ip_len = (icp[0] & 0xf) << 2;
-	if(ip_len < 20){
+	/* Peek at the IP header's IHL field to find its length */
+	ihl = icp[0] & 0xf;
+	if(ihl < 20 / 4){
 		/* The IP header length field is too small */
 		comp->sls_i_runt++;
 		return slhc_toss( comp );
 	}
 	index = icp[9];
 	icp[9] = IPPROTO_TCP;
-	ip = (struct iphdr *) icp;
 
-	if (ip_fast_csum(icp, ip->ihl)) {
+	if (ip_fast_csum(icp, ihl)) {
 		/* Bad IP header checksum; discard */
 		comp->sls_i_badcheck++;
 		return slhc_toss( comp );
 	}
-	thp = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4);
 	if(index > comp->rslot_limit) {
 		comp->sls_i_error++;
 		return slhc_toss(comp);
@@ -676,13 +672,13 @@
 	/* Update local state */
 	cs = &comp->rstate[comp->recv_current = index];
 	comp->flags &=~ SLF_TOSS;
-	memcpy(&cs->cs_ip,ip,20);
-	memcpy(&cs->cs_tcp,thp,20);
-	if (ip->ihl > 5)
-	  memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4);
-	if (thp->doff > 5)
-	  memcpy(cs->cs_tcpopt, thp+1, ((thp->doff) - 5) * 4);
-	cs->cs_hsize = ip->ihl*2 + thp->doff*2;
+	memcpy(&cs->cs_ip,icp,20);
+	memcpy(&cs->cs_tcp,icp + ihl*4,20);
+	if (ihl > 5)
+	  memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4);
+	if (cs->cs_tcp.doff > 5)
+	  memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
+	cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
 	/* Put headers back on packet
 	 * Neither header checksum is recalculated
 	 */
diff -u --recursive --new-file v1.3.11/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v1.3.11/linux/drivers/scsi/Makefile	Tue Jul 11 10:02:50 1995
+++ linux/drivers/scsi/Makefile	Tue Jul 25 09:57:14 1995
@@ -11,8 +11,10 @@
 .c.o:
 	$(CC) $(CFLAGS) -c $<
 
+ifdef CONFIG_KERNEL_ELF
 # This is used for ELF - it needs to migrate or be moved.
 LD_RFLAG = -m elf_i386
+endif
 
 AHA152X	= -DDEBUG_AHA152X -DAUTOCONF -DSKIP_BIOSTEST -DIRQ=11
 
diff -u --recursive --new-file v1.3.11/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v1.3.11/linux/drivers/scsi/aic7xxx.c	Tue Jul 18 16:28:57 1995
+++ linux/drivers/scsi/aic7xxx.c	Thu Jul 20 09:11:45 1995
@@ -18,9 +18,6 @@
  * 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.
- *
  * 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.11/linux/drivers/scsi/aic7xxx.h linux/drivers/scsi/aic7xxx.h
--- v1.3.11/linux/drivers/scsi/aic7xxx.h	Tue Jul 18 16:28:57 1995
+++ linux/drivers/scsi/aic7xxx.h	Thu Jul 20 09:11:45 1995
@@ -18,9 +18,6 @@
  * 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.11/linux/drivers/scsi/aic7xxx_asm.c linux/drivers/scsi/aic7xxx_asm.c
--- v1.3.11/linux/drivers/scsi/aic7xxx_asm.c	Tue Jul 18 16:28:58 1995
+++ linux/drivers/scsi/aic7xxx_asm.c	Thu Jul 20 09:11:45 1995
@@ -18,9 +18,6 @@
  * 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:
  *      <label>*
diff -u --recursive --new-file v1.3.11/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.3.11/linux/drivers/scsi/scsi.c	Tue Jul 11 10:02:50 1995
+++ linux/drivers/scsi/scsi.c	Tue Jul 25 08:53:44 1995
@@ -757,7 +757,7 @@
     if(SDpnt != NULL)
 	scsi_init_free((char *) SDpnt, sizeof(Scsi_Device));
     
-    if(SDpnt != NULL)
+    if(SCpnt != NULL)
 	scsi_init_free((char *) SCpnt, sizeof(Scsi_Cmnd));
     
     /* If we allocated a buffer so we could do DMA, free it now */
diff -u --recursive --new-file v1.3.11/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v1.3.11/linux/drivers/scsi/sg.c	Tue Jul 11 10:02:51 1995
+++ linux/drivers/scsi/sg.c	Tue Jul 25 09:57:14 1995
@@ -167,7 +167,7 @@
     if (size<=4096)
 	return (char *) scsi_malloc(size);
 #ifdef SG_BIG_BUFF
-    if (size<SG_BIG_BUFF)
+    if (size<=SG_BIG_BUFF)
     {
 	while(big_inuse)
 	{
diff -u --recursive --new-file v1.3.11/linux/drivers/sound/pas2_midi.c linux/drivers/sound/pas2_midi.c
--- v1.3.11/linux/drivers/sound/pas2_midi.c	Tue Jul 11 10:02:53 1995
+++ linux/drivers/sound/pas2_midi.c	Wed Jul 19 07:56:51 1995
@@ -33,7 +33,7 @@
 
 #include "pas.h"
 
-#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI) && defined(EXCLUDE_PRO_MIDI)
+#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI)
 
 static int      midi_busy = 0, input_opened = 0;
 static int      my_dev;
diff -u --recursive --new-file v1.3.11/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h
--- v1.3.11/linux/include/asm-alpha/io.h	Fri Jul  7 08:54:53 1995
+++ linux/include/asm-alpha/io.h	Mon Jul 24 17:38:25 1995
@@ -77,7 +77,7 @@
 # define outl(l,p) _outl((l),(p))
 #endif
 
-#endif /* __KERNEL__ */
+#endif /* !__KERNEL__ */
 
 /*
  * There are different version of the alpha motherboards: the
@@ -90,6 +90,8 @@
 #include <asm/jensen.h>
 #endif
 
+#ifdef __KERNEL__
+
 /*
  * String version of IO memory access ops:
  */
@@ -122,5 +124,7 @@
 #define memset_io(addr,c,len)		(memset_io)((unsigned long)(addr),(c),(len))
 #define memcpy_fromio(to,from,len)	(memcpy_fromio)((to),(unsigned long)(from),(len))
 #define memcpy_toio(to,from,len)	(memcpy_toio)((unsigned long)(to),(from),(len))
+
+#endif /* __KERNEL__ */
 
 #endif
diff -u --recursive --new-file v1.3.11/linux/include/asm-alpha/mman.h linux/include/asm-alpha/mman.h
--- v1.3.11/linux/include/asm-alpha/mman.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/mman.h	Tue Jul 25 10:35:56 1995
@@ -0,0 +1,29 @@
+#ifndef __ALPHA_MMAN_H__
+#define __ALPHA_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping (OSF/1 is _wrong_) */
+#define MAP_FIXED	0x100		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x10		/* don't use a file */
+
+/* not used by linux, but here to make sure we don't clash with OSF/1 defines */
+#define MAP_HASSEMAPHORE 0x0200
+#define MAP_INHERIT	0x0400
+#define MAP_UNALIGNED	0x0800
+
+/* These are linux-specific */
+#define MAP_GROWSDOWN	0x1000		/* stack-like segment */
+#define MAP_DENYWRITE	0x2000		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x4000		/* mark it as a executable */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_SYNC		2		/* synchronous memory sync */
+#define MS_INVALIDATE	4		/* invalidate the caches */
+
+#endif /* __ALPHA_MMAN_H__ */
diff -u --recursive --new-file v1.3.11/linux/include/asm-alpha/sigcontext.h linux/include/asm-alpha/sigcontext.h
--- v1.3.11/linux/include/asm-alpha/sigcontext.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/sigcontext.h	Thu Jul 20 09:14:32 1995
@@ -0,0 +1,34 @@
+#ifndef _ASMAXP_SIGCONTEXT_H
+#define _ASMAXP_SIGCONTEXT_H
+
+struct sigcontext_struct {
+	/*
+	 * what should we have here? I'd probably better use the same
+	 * stack layout as OSF/1, just in case we ever want to try
+	 * running their binaries.. 
+	 *
+	 * This is the basic layout, but I don't know if we'll ever
+	 * actually fill in all the values..
+	 */
+	 long		sc_onstack;
+	 long		sc_mask;
+	 long		sc_pc;
+	 long		sc_ps;
+	 long		sc_regs[32];
+	 long		sc_ownedfp;
+	 long		sc_fpregs[32];
+	 unsigned long	sc_fpcr;
+	 unsigned long	sc_fp_control;
+	 unsigned long	sc_reserved1, sc_reserved2;
+	 unsigned long	sc_ssize;
+	 char *		sc_sbase;
+	 unsigned long	sc_traparg_a0;
+	 unsigned long	sc_traparg_a1;
+	 unsigned long	sc_traparg_a2;
+	 unsigned long	sc_fp_trap_pc;
+	 unsigned long	sc_fp_trigger_sum;
+	 unsigned long	sc_fp_trigger_inst;
+	 unsigned long	sc_retcode[2];
+};
+
+#endif
diff -u --recursive --new-file v1.3.11/linux/include/asm-alpha/signal.h linux/include/asm-alpha/signal.h
--- v1.3.11/linux/include/asm-alpha/signal.h	Fri Jun  2 13:51:17 1995
+++ linux/include/asm-alpha/signal.h	Thu Jul 20 09:14:32 1995
@@ -78,37 +78,7 @@
 };
 
 #ifdef __KERNEL__
-
-struct sigcontext_struct {
-	/*
-	 * what should we have here? I'd probably better use the same
-	 * stack layout as OSF/1, just in case we ever want to try
-	 * running their binaries.. 
-	 *
-	 * This is the basic layout, but I don't know if we'll ever
-	 * actually fill in all the values..
-	 */
-	 long		sc_onstack;
-	 long		sc_mask;
-	 long		sc_pc;
-	 long		sc_ps;
-	 long		sc_regs[32];
-	 long		sc_ownedfp;
-	 long		sc_fpregs[32];
-	 unsigned long	sc_fpcr;
-	 unsigned long	sc_fp_control;
-	 unsigned long	sc_reserved1, sc_reserved2;
-	 unsigned long	sc_ssize;
-	 char *		sc_sbase;
-	 unsigned long	sc_traparg_a0;
-	 unsigned long	sc_traparg_a1;
-	 unsigned long	sc_traparg_a2;
-	 unsigned long	sc_fp_trap_pc;
-	 unsigned long	sc_fp_trigger_sum;
-	 unsigned long	sc_fp_trigger_inst;
-	 unsigned long	sc_retcode[2];
-};
-
+#include <asm/sigcontext.h>
 #endif
 
 #endif
diff -u --recursive --new-file v1.3.11/linux/include/asm-alpha/string.h linux/include/asm-alpha/string.h
--- v1.3.11/linux/include/asm-alpha/string.h	Fri Jul  7 08:54:53 1995
+++ linux/include/asm-alpha/string.h	Thu Jul 20 09:42:29 1995
@@ -5,11 +5,12 @@
 extern void * __memset(void *, char, size_t);
 extern void * __memcpy(void *, const void *, size_t);
 
+#define __HAVE_ARCH_MEMSET
 #define memset(s, c, count) \
 (__builtin_constant_p(c) ? \
  __constant_c_memset((s),(0x0101010101010101UL*(unsigned char)c),(count)) : \
  __memset((s),(c),(count)))
 
-#define memcpy(d,s,count) __memcpy((d),(s),(count))
+#define __HAVE_ARCH_STRLEN
 
 #endif
diff -u --recursive --new-file v1.3.11/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v1.3.11/linux/include/asm-alpha/system.h	Tue Jul 18 16:28:58 1995
+++ linux/include/asm-alpha/system.h	Wed Jul 19 09:24:54 1995
@@ -118,6 +118,16 @@
 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 #define tas(ptr) (xchg((ptr),1))
 
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid xchg().
+ *
+ * This only works if the compiler isn't horribly bad at optimizing.
+ * gcc-2.5.8 reportedly can't handle this, but as that doesn't work
+ * too well on the alpha anyway..
+ */
+extern void __xchg_called_with_bad_pointer(void);
+
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
 	switch (size) {
@@ -126,7 +136,7 @@
 		case 8:
 			return xchg_u64(ptr, x);
 	}
-	printk("Argh.. xchg() with unsupported size\n");
+	__xchg_called_with_bad_pointer();
 	return x;
 }
 
diff -u --recursive --new-file v1.3.11/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- v1.3.11/linux/include/asm-alpha/unistd.h	Tue Jul 18 16:28:58 1995
+++ linux/include/asm-alpha/unistd.h	Wed Jul 19 09:26:21 1995
@@ -50,7 +50,7 @@
 #define __NR_vhangup		 76
 #define __NR_getgroups		 79
 #define __NR_setgroups		 80
-#define __NR_setpgid		 82
+#define __NR_setpgrp		 82
 #define __NR_setitimer		 83
 #define __NR_getitimer		 86
 #define __NR_gethostname	 87
diff -u --recursive --new-file v1.3.11/linux/include/asm-i386/mman.h linux/include/asm-i386/mman.h
--- v1.3.11/linux/include/asm-i386/mman.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/mman.h	Mon Jul 24 17:42:13 1995
@@ -0,0 +1,23 @@
+#ifndef __I386_MMAN_H__
+#define __I386_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as a executable */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#endif /* __I386_MMAN_H__ */
diff -u --recursive --new-file v1.3.11/linux/include/asm-i386/sigcontext.h linux/include/asm-i386/sigcontext.h
--- v1.3.11/linux/include/asm-i386/sigcontext.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/sigcontext.h	Thu Jul 20 09:13:26 1995
@@ -0,0 +1,29 @@
+#ifndef _ASMi386_SIGCONTEXT_H
+#define _ASMi386_SIGCONTEXT_H
+
+struct sigcontext_struct {
+	unsigned short gs, __gsh;
+	unsigned short fs, __fsh;
+	unsigned short es, __esh;
+	unsigned short ds, __dsh;
+	unsigned long edi;
+	unsigned long esi;
+	unsigned long ebp;
+	unsigned long esp;
+	unsigned long ebx;
+	unsigned long edx;
+	unsigned long ecx;
+	unsigned long eax;
+	unsigned long trapno;
+	unsigned long err;
+	unsigned long eip;
+	unsigned short cs, __csh;
+	unsigned long eflags;
+	unsigned long esp_at_signal;
+	unsigned short ss, __ssh;
+	unsigned long i387;
+	unsigned long oldmask;
+	unsigned long cr2;
+};
+
+#endif
diff -u --recursive --new-file v1.3.11/linux/include/asm-i386/signal.h linux/include/asm-i386/signal.h
--- v1.3.11/linux/include/asm-i386/signal.h	Sat Jun 10 18:35:54 1995
+++ linux/include/asm-i386/signal.h	Thu Jul 20 09:13:26 1995
@@ -77,32 +77,7 @@
 };
 
 #ifdef __KERNEL__
-
-struct sigcontext_struct {
-	unsigned short gs, __gsh;
-	unsigned short fs, __fsh;
-	unsigned short es, __esh;
-	unsigned short ds, __dsh;
-	unsigned long edi;
-	unsigned long esi;
-	unsigned long ebp;
-	unsigned long esp;
-	unsigned long ebx;
-	unsigned long edx;
-	unsigned long ecx;
-	unsigned long eax;
-	unsigned long trapno;
-	unsigned long err;
-	unsigned long eip;
-	unsigned short cs, __csh;
-	unsigned long eflags;
-	unsigned long esp_at_signal;
-	unsigned short ss, __ssh;
-	unsigned long i387;
-	unsigned long oldmask;
-	unsigned long cr2;
-};
-
+#include <asm/sigcontext.h>
 #endif
 
 #endif
diff -u --recursive --new-file v1.3.11/linux/include/asm-i386/string.h linux/include/asm-i386/string.h
--- v1.3.11/linux/include/asm-i386/string.h	Fri Jul  7 08:54:53 1995
+++ linux/include/asm-i386/string.h	Thu Jul 20 09:50:29 1995
@@ -12,7 +12,8 @@
  *
  *		Copyright (C) 1991, 1992 Linus Torvalds
  */
- 
+
+#define __HAVE_ARCH_STRCPY
 extern inline char * strcpy(char * dest,const char *src)
 {
 __asm__ __volatile__(
@@ -26,6 +27,7 @@
 return dest;
 }
 
+#define __HAVE_ARCH_STRNCPY
 extern inline char * strncpy(char * dest,const char *src,size_t count)
 {
 __asm__ __volatile__(
@@ -44,6 +46,7 @@
 return dest;
 }
 
+#define __HAVE_ARCH_STRCAT
 extern inline char * strcat(char * dest,const char * src)
 {
 __asm__ __volatile__(
@@ -60,6 +63,7 @@
 return dest;
 }
 
+#define __HAVE_ARCH_STRNCAT
 extern inline char * strncat(char * dest,const char * src,size_t count)
 {
 __asm__ __volatile__(
@@ -82,6 +86,7 @@
 return dest;
 }
 
+#define __HAVE_ARCH_STRCMP
 extern inline int strcmp(const char * cs,const char * ct)
 {
 register int __res;
@@ -101,6 +106,7 @@
 return __res;
 }
 
+#define __HAVE_ARCH_STRNCMP
 extern inline int strncmp(const char * cs,const char * ct,size_t count)
 {
 register int __res;
@@ -122,6 +128,7 @@
 return __res;
 }
 
+#define __HAVE_ARCH_STRCHR
 extern inline char * strchr(const char * s, int c)
 {
 register char * __res;
@@ -140,6 +147,7 @@
 return __res;
 }
 
+#define __HAVE_ARCH_STRRCHR
 extern inline char * strrchr(const char * s, int c)
 {
 register char * __res;
@@ -156,6 +164,7 @@
 return __res;
 }
 
+#define __HAVE_ARCH_STRSPN
 extern inline size_t strspn(const char * cs, const char * ct)
 {
 register char * __res;
@@ -181,6 +190,7 @@
 return __res-cs;
 }
 
+#define __HAVE_ARCH_STRCSPN
 extern inline size_t strcspn(const char * cs, const char * ct)
 {
 register char * __res;
@@ -206,6 +216,7 @@
 return __res-cs;
 }
 
+#define __HAVE_ARCH_STRPBRK
 extern inline char * strpbrk(const char * cs,const char * ct)
 {
 register char * __res;
@@ -234,6 +245,7 @@
 return __res;
 }
 
+#define __HAVE_ARCH_STRSTR
 extern inline char * strstr(const char * cs,const char * ct)
 {
 register char * __res;
@@ -262,6 +274,7 @@
 return __res;
 }
 
+#define __HAVE_ARCH_STRLEN
 extern inline size_t strlen(const char * s)
 {
 register int __res;
@@ -277,6 +290,7 @@
 
 extern char * ___strtok;
 
+#define __HAVE_ARCH_STRTOK
 extern inline char * strtok(char * s,const char * ct)
 {
 register char * __res;
@@ -395,11 +409,13 @@
 #undef COMMON
 }
 
+#define __HAVE_ARCH_MEMCPY
 #define memcpy(t, f, n) \
 (__builtin_constant_p(n) ? \
  __constant_memcpy((t),(f),(n)) : \
  __memcpy((t),(f),(n)))
 
+#define __HAVE_ARCH_MEMMOVE
 extern inline void * memmove(void * dest,const void * src, size_t n)
 {
 if (dest<src)
@@ -426,6 +442,7 @@
 
 #define memcmp __builtin_memcmp
 
+#define __HAVE_ARCH_MEMCHR
 extern inline void * memchr(const void * cs,int c,size_t count)
 {
 register void * __res;
@@ -532,6 +549,7 @@
  __constant_count_memset((s),(c),(count)) : \
  __memset_generic((s),(c),(count)))
 
+#define __HAVE_ARCH_MEMSET
 #define memset(s, c, count) \
 (__builtin_constant_p(c) ? \
  __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
@@ -540,6 +558,7 @@
 /*
  * find the first occurrence of byte 'c', or 1 past the area if none
  */
+#define __HAVE_ARCH_MEMSCAN
 extern inline void * memscan(void * addr, int c, size_t size)
 {
 	if (!size)
diff -u --recursive --new-file v1.3.11/linux/include/linux/aztcd.h linux/include/linux/aztcd.h
--- v1.3.11/linux/include/linux/aztcd.h	Tue Jul 11 10:02:59 1995
+++ linux/include/linux/aztcd.h	Tue Jul 25 10:17:15 1995
@@ -1,4 +1,5 @@
-/* $Id: aztcd.h,v 1.30 1995/07/04 08:28:17 root Exp $
+/* $Id: aztcd.h,v 1.40 1995/07/15 20:35:01 root Exp root $
+ *
  * Definitions for a AztechCD268 CD-ROM interface
  *	Copyright (C) 1994, 1995  Werner Zimmermann
  *
@@ -42,11 +43,17 @@
   don't want the auto-eject feature*/
 #define AZT_AUTO_EJECT          0
 
+/*Set this to 1, if you want multisession support. Be warned, this function has
+not been tested !!!*/
+#define AZT_MULTISESSION        0
+
+/*Set this to 1, if you want to use incompatible ioctls for reading in raw and
+  cooked mode */
+#define AZT_PRIVATE_IOCTLS      1
+
 /*---------------------------------------------------------------------------*/
 /*------------nothing to be configured below this line-----------------------*/
 
-/* use incompatible ioctls for reading in raw and cooked mode */
-#define AZT_PRIVATE_IOCTLS
 
 /* Increase this if you get lots of timeouts; if you get kernel panic, replace
    STEN_LOW_WAIT by STEN_LOW in the source code */
@@ -108,6 +115,10 @@
 
 #define MAX_TRACKS		104
 
+#define CD_DATA			0x01
+#define CD_AUDIO		0x02
+#define CD_XA                   (CD_DATA|CD_AUDIO)
+
 struct msf {
 	unsigned char	min;
 	unsigned char	sec;
@@ -124,6 +135,9 @@
 	unsigned char	last;
 	struct msf	diskLength;
 	struct msf	firstTrack;
+        unsigned char   multi;
+        struct msf      lastTrack;
+        unsigned char   type;
 };
 
 struct azt_Toc {
diff -u --recursive --new-file v1.3.11/linux/include/linux/cm206.h linux/include/linux/cm206.h
--- v1.3.11/linux/include/linux/cm206.h	Fri Jul  7 08:54:53 1995
+++ linux/include/linux/cm206.h	Wed Jul 19 10:15:42 1995
@@ -3,20 +3,23 @@
 */
 
 /* First, the cm260 stuff */
-/* The ports and irq used. If it is not defined, make it variable, 
-   and initialize them at some reasonable value */
+/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined
+   below, the values are not used unless autoprobing is turned off and 
+   no LILO boot options or module command line options are given. Change
+   these values to your own as last resort if autoprobing and options
+   don't work. */
 
 #define CM206_BASE 0x340
 #define CM206_IRQ 11
 
-#define r_data_status (CM206_BASE)
-#define r_uart_receive (CM206_BASE+0x2)
-#define r_fifo_output_buffer (CM206_BASE+0x4)
-#define r_line_status (CM206_BASE+0x6)
-#define r_data_control (CM206_BASE+0x8)
-#define r_uart_transmit (CM206_BASE+0xa)
-#define r_test_clock (CM206_BASE+0xc)
-#define r_test_control (CM206_BASE+0xe)
+#define r_data_status (cm206_base)
+#define r_uart_receive (cm206_base+0x2)
+#define r_fifo_output_buffer (cm206_base+0x4)
+#define r_line_status (cm206_base+0x6)
+#define r_data_control (cm206_base+0x8)
+#define r_uart_transmit (cm206_base+0xa)
+#define r_test_clock (cm206_base+0xc)
+#define r_test_control (cm206_base+0xe)
 
 /* the data_status flags */
 #define ds_ram_size 0x4000
@@ -123,4 +126,3 @@
 
 #define CM206CTL_GET_STAT 0x2000
 #define CM206CTL_GET_LAST_STAT 0x2001
-#define CM206_RESET_DRIVE 0x2002 /* use with care */
diff -u --recursive --new-file v1.3.11/linux/include/linux/if_ppp.h linux/include/linux/if_ppp.h
--- v1.3.11/linux/include/linux/if_ppp.h	Thu Jul 13 16:20:21 1995
+++ linux/include/linux/if_ppp.h	Mon Jul 24 17:38:25 1995
@@ -193,7 +193,7 @@
   struct tty_struct	*tty;		/* ptr to TTY structure		*/
   struct device		*dev;		/* easy for intr handling	*/
   struct slcompress	*slcomp;	/* for header compression	*/
-  __u32			last_xmit;	/* time of last transmission	*/
+  unsigned long		last_xmit;	/* time of last transmission	*/
 
   /* These are pointers to the malloc()ed frame buffers.
      These buffers are used while processing a packet.	If a packet
diff -u --recursive --new-file v1.3.11/linux/include/linux/mman.h linux/include/linux/mman.h
--- v1.3.11/linux/include/linux/mman.h	Mon Jan 23 23:04:10 1995
+++ linux/include/linux/mman.h	Mon Jul 24 17:38:25 1995
@@ -1,23 +1,6 @@
 #ifndef _LINUX_MMAN_H
 #define _LINUX_MMAN_H
 
-#define PROT_READ        0x1       /* page can be read */
-#define PROT_WRITE       0x2       /* page can be written */
-#define PROT_EXEC        0x4       /* page can be executed */
-#define PROT_NONE        0x0       /* page can not be accessed */
-
-#define MAP_SHARED       1         /* Share changes */
-#define MAP_PRIVATE      2         /* Changes are private */
-#define MAP_TYPE         0xf       /* Mask for type of mapping */
-#define MAP_FIXED        0x10      /* Interpret addr exactly */
-#define MAP_ANONYMOUS    0x20      /* don't use a file */
-
-#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
-#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
-#define MAP_EXECUTABLE	0x1000		/* mark it as a executable */
-
-#define MS_ASYNC	1	/* sync memory asynchronously */
-#define MS_INVALIDATE	2	/* invalidate the caches */
-#define MS_SYNC		4	/* synchronous memory sync */
+#include <asm/mman.h>
 
 #endif /* _LINUX_MMAN_H */
diff -u --recursive --new-file v1.3.11/linux/include/linux/trdevice.h linux/include/linux/trdevice.h
--- v1.3.11/linux/include/linux/trdevice.h	Tue Jul 18 16:28:59 1995
+++ linux/include/linux/trdevice.h	Wed Jul 19 14:52:34 1995
@@ -28,9 +28,9 @@
 #include <linux/if_tr.h>
 
 #ifdef __KERNEL__
-extern int		tr_header(unsigned char *buff, struct device *dev,
+extern int		tr_header(struct sk_buff *skb, struct device *dev,
 				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len, struct sk_buff *skb);
+				   void *saddr, unsigned len);
 extern int		tr_rebuild_header(void *buff, struct device *dev,
 			unsigned long raddr, struct sk_buff *skb);
 extern unsigned short	tr_type_trans(struct sk_buff *skb, struct device *dev);
diff -u --recursive --new-file v1.3.11/linux/kernel/fork.c linux/kernel/fork.c
--- v1.3.11/linux/kernel/fork.c	Tue Jul 18 16:28:59 1995
+++ linux/kernel/fork.c	Tue Jul 18 17:15:38 1995
@@ -192,6 +192,8 @@
 	p->state = TASK_UNINTERRUPTIBLE;
 	p->flags &= ~(PF_PTRACED|PF_TRACESYS);
 	p->pid = last_pid;
+	p->next_run = NULL;
+	p->prev_run = NULL;
 	p->p_pptr = p->p_opptr = current;
 	p->p_cptr = NULL;
 	p->signal = 0;
diff -u --recursive --new-file v1.3.11/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.11/linux/kernel/ksyms.c	Tue Jul 18 16:28:59 1995
+++ linux/kernel/ksyms.c	Mon Jul 24 17:38:26 1995
@@ -386,9 +386,6 @@
  	X(dispatch_scsi_info_ptr),
 	X(generic_proc_info),
  	X(scsi_devices),
- 	X(free_pages),
-    	X(print_msg),
-	X(print_status),
 	X(gendisk_head), /* Needed for sd.c */
 	X(resetup_one_dev), /* Needed for sd.c */
 #else
diff -u --recursive --new-file v1.3.11/linux/kernel/sched.c linux/kernel/sched.c
--- v1.3.11/linux/kernel/sched.c	Tue Jul 18 16:28:59 1995
+++ linux/kernel/sched.c	Tue Jul 18 17:56:31 1995
@@ -92,32 +92,77 @@
 
 struct kernel_stat kstat = { 0 };
 
+static inline void add_to_runqueue(struct task_struct * p)
+{
+#if 1	/* sanity tests */
+	if (p->next_run || p->prev_run) {
+		printk("task already on run-queue\n");
+		return;
+	}
+#endif
+	if (p->counter > current->counter + 3)
+		need_resched = 1;
+	nr_running++;
+	(p->next_run = init_task.next_run)->prev_run = p;
+	p->prev_run = &init_task;
+	init_task.next_run = p;
+}
+
+static inline void del_from_runqueue(struct task_struct * p)
+{
+	struct task_struct *next = p->next_run;
+	struct task_struct *prev = p->prev_run;
+
+#if 1	/* sanity tests */
+	if (!next || !prev) {
+		printk("task not on run-queue\n");
+		return;
+	}
+#endif
+	if (p == &init_task) {
+		printk("idle task may not sleep\n");
+		return;
+	}
+	nr_running--;
+	next->prev_run = prev;
+	prev->next_run = next;
+	p->next_run = NULL;
+	p->prev_run = NULL;
+}
+
 /*
  * 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
+ * run-queue (except when the actual re-schedule is in
+ * progress), 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;
+	unsigned long flags;
 
-	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;
+	save_flags(flags);
+	cli();
+	p->state = TASK_RUNNING;
+	if (!p->next_run)
+		add_to_runqueue(p);
+	restore_flags(flags);
+}
+
+static void process_timeout(unsigned long __data)
+{
+	struct task_struct * p = (struct task_struct *) __data;
+
+	p->timeout = 0;
+	wake_up_process(p);
 }
 
 /*
  *  'schedule()' is the scheduler function. It's a very simple and nice
  * scheduler: it's not perfect, but certainly works for most things.
- * The one thing you might take a look at is the signal-handler code here.
+ *
+ * The goto is "interesting".
  *
  *   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'
@@ -128,6 +173,7 @@
 	int c;
 	struct task_struct * p;
 	struct task_struct * next;
+	unsigned long timeout = 0;
 
 /* check alarm, wake up any interruptible tasks that have got a signal */
 
@@ -137,31 +183,39 @@
 	}
 	run_task_queue(&tq_scheduler);
 
-	if (current->state == TASK_INTERRUPTIBLE) {
-		if (current->signal & ~current->blocked)
-			current->state = TASK_RUNNING;
-	}
 	need_resched = 0;
-	nr_running = 0;
+	cli();
+	switch (current->state) {
+		case TASK_INTERRUPTIBLE:
+			if (current->signal & ~current->blocked)
+				goto makerunnable;
+			timeout = current->timeout;
+			if (timeout && (timeout <= jiffies)) {
+				current->timeout = 0;
+				timeout = 0;
+		makerunnable:
+				current->state = TASK_RUNNING;
+				break;
+			}
+		default:
+			del_from_runqueue(current);
+		case TASK_RUNNING:
+	}
+	p = init_task.next_run;
+	sti();
 
+/*
+ * Note! there may appear new tasks on the run-queue during this, as
+ * interrupts are enabled. However, they will be put on front of the
+ * list, so our list starting at "p" is essentially fixed.
+ */
 /* this is the scheduler proper: */
 	c = -1000;
 	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;
-		}
+	while (p != &init_task) {
+		if (p->counter > c)
+			c = p->counter, next = p;
+		p = p->next_run;
 	}
 
 	/* if all runnable processes have "counter == 0", re-calculate counters */
@@ -169,10 +223,21 @@
 		for_each_task(p)
 			p->counter = (p->counter >> 1) + p->priority;
 	}
-	if (current == next)
-		return;
-	kstat.context_swtch++;
-	switch_to(next);
+	if (current != next) {
+		struct timer_list timer;
+
+		kstat.context_swtch++;
+		if (timeout) {
+			init_timer(&timer);
+			timer.expires = timeout - jiffies;
+			timer.data = (unsigned long) current;
+			timer.function = process_timeout;
+			add_timer(&timer);
+		}
+		switch_to(next);
+		if (timeout)
+			del_timer(&timer);
+	}
 }
 
 asmlinkage int sys_pause(void)
diff -u --recursive --new-file v1.3.11/linux/lib/string.c linux/lib/string.c
--- v1.3.11/linux/lib/string.c	Tue Jun  6 18:17:33 1995
+++ linux/lib/string.c	Thu Jul 20 09:48:13 1995
@@ -12,9 +12,11 @@
  */
  
 #include <linux/types.h>
+#include <linux/string.h>
 
 char * ___strtok = NULL;
 
+#ifndef __HAVE_ARCH_STRCPY
 char * strcpy(char * dest,const char *src)
 {
 	char *tmp = dest;
@@ -23,7 +25,9 @@
 		/* nothing */;
 	return tmp;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRNCPY
 char * strncpy(char * dest,const char *src,size_t count)
 {
 	char *tmp = dest;
@@ -33,7 +37,9 @@
 
 	return tmp;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRCAT
 char * strcat(char * dest, const char * src)
 {
 	char *tmp = dest;
@@ -45,7 +51,9 @@
 
 	return tmp;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRNCAT
 char * strncat(char *dest, const char *src, size_t count)
 {
 	char *tmp = dest;
@@ -61,7 +69,9 @@
 
 	return tmp;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRCMP
 int strcmp(const char * cs,const char * ct)
 {
 	register signed char __res;
@@ -73,7 +83,9 @@
 
 	return __res;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRNCMP
 int strncmp(const char * cs,const char * ct,size_t count)
 {
 	register signed char __res = 0;
@@ -86,7 +98,9 @@
 
 	return __res;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRCHR
 char * strchr(const char * s,char c)
 {
 	for(; *s != c; ++s)
@@ -94,7 +108,9 @@
 			return NULL;
 	return (char *) s;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRLEN
 size_t strlen(const char * s)
 {
 	const char *sc;
@@ -103,7 +119,9 @@
 		/* nothing */;
 	return sc - s;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRNLEN
 size_t strnlen(const char * s, size_t count)
 {
 	const char *sc;
@@ -112,7 +130,9 @@
 		/* nothing */;
 	return sc - s;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRSPN
 size_t strspn(const char *s, const char *accept)
 {
 	const char *p;
@@ -131,7 +151,9 @@
 
 	return count;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRPBRK
 char * strpbrk(const char * cs,const char * ct)
 {
 	const char *sc1,*sc2;
@@ -144,7 +166,9 @@
 	}
 	return NULL;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRTOK
 char * strtok(char * s,const char * ct)
 {
 	char *sbegin, *send;
@@ -164,7 +188,9 @@
 	___strtok = send;
 	return (sbegin);
 }
+#endif
 
+#ifndef __HAVE_ARCH_MEMSET
 void * memset(void * s,char c,size_t count)
 {
 	char *xs = (char *) s;
@@ -174,7 +200,9 @@
 
 	return s;
 }
+#endif
 
+#ifndef __HAVE_ARCH_BCOPY
 char * bcopy(const char * src, char * dest, int count)
 {
 	char *tmp = dest;
@@ -184,7 +212,9 @@
 
 	return dest;
 }
+#endif
 
+#ifndef __HAVE_ARCH_MEMCPY
 void * memcpy(void * dest,const void *src,size_t count)
 {
 	char *tmp = (char *) dest, *s = (char *) src;
@@ -194,7 +224,9 @@
 
 	return dest;
 }
+#endif
 
+#ifndef __HAVE_ARCH_MEMMOVE
 void * memmove(void * dest,const void *src,size_t count)
 {
 	char *tmp, *s;
@@ -214,7 +246,9 @@
 
 	return dest;
 }
+#endif
 
+#ifndef __HAVE_ARCH_MEMCMP
 int memcmp(const void * cs,const void * ct,size_t count)
 {
 	const unsigned char *su1, *su2;
@@ -225,10 +259,12 @@
 			break;
 	return res;
 }
+#endif
 
 /*
  * find the first occurrence of byte 'c', or 1 past the area if none
  */
+#ifndef __HAVE_ARCH_MEMSCAN
 void * memscan(void * addr, unsigned char c, size_t size)
 {
 	unsigned char * p = (unsigned char *) addr;
@@ -241,7 +277,9 @@
 	}
   	return (void *) p;
 }
+#endif
 
+#ifndef __HAVE_ARCH_STRSTR
 char * strstr(const char * s1,const char * s2)
 {
 	int l1, l2;
@@ -258,3 +296,4 @@
 	}
 	return NULL;
 }
+#endif
diff -u --recursive --new-file v1.3.11/linux/net/802/tr.c linux/net/802/tr.c
--- v1.3.11/linux/net/802/tr.c	Fri Jul  7 08:54:56 1995
+++ linux/net/802/tr.c	Wed Jul 19 14:52:34 1995
@@ -38,11 +38,12 @@
 #define RIF_CHECK_INTERVAL 60*HZ
 static struct timer_list rif_timer={ NULL,NULL,RIF_CHECK_INTERVAL,0L,rif_check_expire };
 
-int tr_header(unsigned char *buff, struct device *dev, unsigned short type,
-              void *daddr, void *saddr, unsigned len, struct sk_buff *skb) {
+int tr_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+              void *daddr, void *saddr, unsigned len) 
+{
 
 	struct trh_hdr *trh=(struct trh_hdr *)skb_push(skb,dev->hard_header_len);
-	struct trllc *trllc=(struct trllc *)(buff+sizeof(struct trh_hdr));
+	struct trllc *trllc=(struct trllc *)(trh+1);
 
 	trh->ac=AC;
 	trh->fc=LLC_FRAME;
@@ -91,6 +92,8 @@
 
 	struct trh_hdr *trh=(struct trh_hdr *)skb->data;
 	struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr));
+	
+	skb->mac.raw = skb->data;
 	
 	skb_pull(skb,dev->hard_header_len);
 	
diff -u --recursive --new-file v1.3.11/linux/net/core/dev.c linux/net/core/dev.c
--- v1.3.11/linux/net/core/dev.c	Thu Jul 13 16:20:21 1995
+++ linux/net/core/dev.c	Wed Jul 19 14:52:34 1995
@@ -172,6 +172,7 @@
 			return;
 		}
 	}
+	printk("dev_remove_pack: %p not found.\n", pt);
 }
 
 /*****************************************************************************************
diff -u --recursive --new-file v1.3.11/linux/net/ipv4/ip.c linux/net/ipv4/ip.c
--- v1.3.11/linux/net/ipv4/ip.c	Thu Jul 13 16:20:22 1995
+++ linux/net/ipv4/ip.c	Mon Jul 24 17:38:34 1995
@@ -85,6 +85,8 @@
  *	Dave Bonn,Alan Cox	:	Faster IP forwarding whenever possible.
  *		Alan Cox	:	Memory leaks, tramples, misc debugging.
  *		Alan Cox	:	Fixed multicast (by popular demand 8))
+ *		Alan Cox	:	Fixed forwarding (by even more popular demand 8))
+ *		Alan Cox	:	Fixed SNMP statistics [I think]
  *
  *  
  *
@@ -153,7 +155,7 @@
 #ifdef CONFIG_IP_FORWARD
 struct ip_mib ip_statistics={1,64,};	/* Forwarding=Yes, Default TTL=64 */
 #else
-struct ip_mib ip_statistics={0,64,};	/* Forwarding=No, Default TTL=64 */
+struct ip_mib ip_statistics={2,64,};	/* Forwarding=No, Default TTL=64 */
 #endif
 
 /*
@@ -1139,7 +1141,7 @@
 	 */
 
 	dev2 = rt->rt_dev;
-
+	
 	/*
 	 *	In IP you never have to forward a frame on the interface that it 
 	 *	arrived upon. We now generate an ICMP HOST REDIRECT giving the route
@@ -1165,33 +1167,35 @@
 		if (!(is_frag&4) && fw_res==2)
 			ip_fw_masquerade(&skb, dev2);
 #endif
+		IS_SKB(skb);
 
 		if(skb_headroom(skb)<dev2->hard_header_len)
+		{
 			skb2 = alloc_skb(dev2->hard_header_len + skb->len + 15, GFP_ATOMIC);
-		else skb2=skb;
+			IS_SKB(skb2);
 		
-		/*
-		 *	This is rare and since IP is tolerant of network failures
-		 *	quite harmless.
-		 */
+			/*
+			 *	This is rare and since IP is tolerant of network failures
+			 *	quite harmless.
+			 */
 		
-		if (skb2 == NULL)
-		{
-			NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
-			return -1;
-		}
+			if (skb2 == NULL)
+			{
+				NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
+				return -1;
+			}
 		
+			/*
+			 *	Add the physical headers.
+			 */
 
-		/* Now build the MAC header. */
-		(void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);
+		 	ip_send(skb2,raddr,skb->len,dev2,dev2->pa_addr);
 
-		/*
-		 *	We have to copy the bytes over as the new header wouldn't fit
-		 *	the old buffer. This should be very rare.
-		 */
-		 
-		if(skb2!=skb)
-		{
+			/*
+			 *	We have to copy the bytes over as the new header wouldn't fit
+			 *	the old buffer. This should be very rare.
+			 */		 
+		 	
 			ptr = skb_put(skb2,skb->len);
 			skb2->free = 1;
 			skb2->h.raw = ptr;
@@ -1201,9 +1205,23 @@
 			 */
 			memcpy(ptr, skb->h.raw, skb->len);
 		}
+		else
+		{
+			/* 
+			 *	Build a new MAC header. 
+			 */
 
-		ip_statistics.IpForwDatagrams++;
-
+			skb2 = skb;		
+			skb2->dev=dev2;
+			skb->arp=1;
+			skb->raddr=raddr;
+			if(dev2->hard_header)
+			{
+				if(dev2->hard_header(skb, dev2, ETH_P_IP, NULL, NULL, skb->len)<0)
+					skb->arp=0;
+			}
+			ip_statistics.IpForwDatagrams++;
+		}
 		/*
 		 *	See if it needs fragmenting. Note in ip_rcv we tagged
 		 *	the fragment type. This must be right so that
@@ -2347,6 +2365,7 @@
 	struct iphdr *iph;
 	int local=0;
 	struct device *dev;
+	int nfrags=0;
 	
 	ip_statistics.IpOutRequests++;
 
@@ -2437,7 +2456,10 @@
 		int error;
 		struct sk_buff *skb=sock_alloc_send_skb(sk, length+20+15+dev->hard_header_len,0,&error);
 		if(skb==NULL)
+		{
+			ip_statistics.IpOutDiscards++;
 			return error;
+		}
 		skb->dev=dev;
 		skb->free=1;
 		skb->when=jiffies;
@@ -2555,8 +2577,13 @@
 
 		skb = sock_alloc_send_skb(sk, fraglen+15, 0, &error);
 		if (skb == NULL)
+		{
+			ip_statistics.IpOutDiscards++;
+			if(nfrags>1)
+				ip_statistics.IpFragCreates++;			
 			return(error);
-
+		}
+		
 		/*
 		 *	Fill in the control structures
 		 */
@@ -2689,6 +2716,9 @@
 				kfree_skb(skb, FREE_READ);
 		}
 #endif
+
+		nfrags++;
+		
 		/*
 		 *	BSD loops broadcasts
 		 */
@@ -2715,12 +2745,15 @@
 			 */
 			 
 			ip_statistics.IpOutDiscards++;
+			if(nfrags>1)
+				ip_statistics.IpFragCreates+=nfrags;
 			kfree_skb(skb, FREE_WRITE);
 			return(0); /* lose rest of fragments */
 		}
 	} 
 	while (offset >= 0);
-	
+	if(nfrags>1)
+		ip_statistics.IpFragCreates+=nfrags;
 	return(0);
 }
     
diff -u --recursive --new-file v1.3.11/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- v1.3.11/linux/net/ipv4/ip_fw.c	Tue Jul 18 16:28:59 1995
+++ linux/net/ipv4/ip_fw.c	Wed Jul 19 14:52:34 1995
@@ -1483,7 +1483,7 @@
 		int timer_active = del_timer(&ms->timer);
 		if (!timer_active)
 			ms->timer.expires = 0;
-		len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08lX %5d %lu\n",
+		len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %5d %lu\n",
 			strProt[ms->protocol==IPPROTO_TCP],
 			ntohl(ms->src),ntohs(ms->sport),
 			ntohl(ms->dst),ntohs(ms->dport),
