diff -u --recursive --new-file v1.3.42/linux/CREDITS linux/CREDITS
--- v1.3.42/linux/CREDITS	Fri Nov 17 08:42:23 1995
+++ linux/CREDITS	Tue Nov 21 08:34:54 1995
@@ -593,6 +593,15 @@
 S: Victoria Park 6100
 S: Australia
 
+N: Martin Mares
+E: mj@k332.feld.cvut.cz
+D: BIOS video mode handling code
+D: Miscellaneous kernel fixes
+D: MOXA C-218 serial board driver
+S: Kankovskeho 1241
+S: 182 00 Praha 8
+S: Czech Republic 
+
 N: John A. Martin
 E: jam@acm.org
 D: FSSTND contributor
diff -u --recursive --new-file v1.3.42/linux/Documentation/devices.tex linux/Documentation/devices.tex
--- v1.3.42/linux/Documentation/devices.tex	Mon Sep 25 12:26:20 1995
+++ linux/Documentation/devices.tex	Sat Nov 18 12:08:28 1995
@@ -41,8 +41,8 @@
  {\end{tabbing}}
 %
 \title{{\bf Linux Allocated Devices}}
-\author{Maintained by H. Peter Anvin $<$Peter.Anvin@linux.org$>$}
-\date{Last revised: September 20, 1995}
+\author{Maintained by H. Peter Anvin $<$hpa@storm.net$>$}
+\date{Last revised: November 17, 1995}
 \maketitle
 %
 \noindent
@@ -140,9 +140,13 @@
 \major{  }{}{block}{Fourth IDE hard disk/CD-ROM interface}
 \major{35}{}{char }{tclmidi MIDI driver}
 \major{  }{}{block}{Modular RAM disk}
-\major{36}{}{block}{MCA ESDI hard disk}
-\major{37--223}{}{}{Unallocated}
-\major{224--254}{}{}{Local use}
+\major{36}{}{char }{Netlink support}
+\major{  }{}{block}{MCA ESDI hard disk}
+\major{37}{--41}{}{Unallocated}
+\major{42}{}{}{Demo/sample use}
+\major{43}{--223}{}{Unallocated}
+\major{224}{--239}{}{SEE NOTE}
+\major{240}{--254}{}{Local use}
 \major{255}{}{}{Reserved}
 \end{devicelist}
 
@@ -770,7 +774,11 @@
 \end{devicelist}
 
 \begin{devicelist}
-\major{36}{}{block}{MCA ESDI hard disk}
+\major{36}{}{char }{Netlink support}
+	\minor{0}{/dev/route}{Routing, device updates (kernel to user)}
+	\minor{1}{/dev/skip}{enSKIP security cache control}
+\\
+\major{  }{}{block}{MCA ESDI hard disk}
 	\minor{0}{/dev/eda}{First ESDI disk whole disk}
 	\minor{64}{/dev/edb}{Second ESDI disk whole disk}
 	\minordots
@@ -781,11 +789,40 @@
 3).
 
 \begin{devicelist}
-\major{37}{--223}{}{Unallocated}
+\major{37}{--41}{}{Unallocated}
+\end{devicelist}
+
+\begin{devicelist}
+\major{42}{}{}{Demo/sample use}
+\end{devicelist}
+
+\noindent
+This number is indended for use in sample code, as well as a general
+``example'' device number.  It should never be used for a device
+driver that is being distributed; either obtain an official number or
+use the local/experimental range.  The sudden addition or removal of a
+driver with this number should not cause ill effects to the system
+(bugs excepted.)
+
+\begin{devicelist}
+\major{43}{--223}{}{Unallocated}
 \end{devicelist}
 
 \begin{devicelist}
-\major{224}{--254}{}{Local/experimental use}
+\major{224}{--239}{}{SEE NOTE}
+\end{devicelist}
+
+\noindent
+This range is currently assigned as part of the local/experimental
+range.  However, because of the Linux way of setting a limit on the
+highest device number in the system, currently set at 63 by default, I
+am considering changing the local/experimental use to 60--63,
+120--127, 240--254.  If you are currently using the range 224--239 and
+such a change would pose a problem for you, please contact
+$<$hpa@storm.net$>$ as soon as possible.
+
+\begin{devicelist}
+\major{240}{--254}{}{Local/experimental use}
 \end{devicelist}
 
 \noindent
@@ -846,6 +883,8 @@
 \vlink{/dev/mouse}{mouse port}{symbolic}{Current mouse device}
 \vlink{/dev/tape}{tape device}{symbolic}{Current tape device}
 \vlink{/dev/cdrom}{CD-ROM device}{symbolic}{Current CD-ROM device}
+\vlink{/dev/cdwriter}{CD-writer}{symbolic}{Current CD-writer device}
+\vlink{/dev/scanner}{scanner device}{symbolic}{Current scanner device}
 \vlink{/dev/modem}{modem port}{symbolic}{Current dialout device}
 \vlink{/dev/root}{root device}{symbolic}{Current root filesystem}
 \vlink{/dev/swap}{swap device}{symbolic}{Current swap device}
@@ -857,6 +896,15 @@
 If it exists, {\file /dev/modem} should point to the appropriate
 dialout (alternate) device.
 
+For SCSI devices, {\file /dev/tape} and {\file /dev/cdrom} should
+point to the ``cooked'' devices ({\file /dev/st*} and {\file
+/dev/sr*}, respectively), whereas {\file /dev/cdwriter} and {\file
+/dev/scanner} should point to the appropriate generic SCSI devices
+({\file /dev/sg*}.)
+
+{\file /dev/mouse} may point to a dialout (alternate) TTY device, a
+hardware mouse device, or a socket for a mouse driver program.
+
 \subsection{Sockets and pipes}
 
 Non-transient sockets or named pipes may exist in {\file /dev}.
@@ -868,3 +916,4 @@
 \end{nodelist}
 
 \end{document}
+
diff -u --recursive --new-file v1.3.42/linux/Documentation/devices.txt linux/Documentation/devices.txt
--- v1.3.42/linux/Documentation/devices.txt	Mon Sep 25 12:26:20 1995
+++ linux/Documentation/devices.txt	Sat Nov 18 12:08:28 1995
@@ -522,7 +522,10 @@
 		      ...
 		255 = /dev/ram255	256th modular RAM disk
 
- 36 block	MCA ESDI hard disk
+ 36 char	Netlink support
+		  0 = /dev/route	Routing, device updates, kernel to user
+		  1 = /dev/skip		enSKIP security cache control
+    block	MCA ESDI hard disk
 		  0 = /dev/eda		First ESDI disk whole disk
 		 64 = /dev/edb		Second ESDI disk whole disk
 		      ...
@@ -530,9 +533,33 @@
 		Partitions are handled in the same way as IDE disks
 		(see major number 3).
 
- 37-223		UNALLOCATED
+ 37-41		UNALLOCATED
 
-224-254		LOCAL USE
+ 42		Demo/sample use
+
+		This number is indended for use in sample code, as
+		well as a general "example" device number.  It
+		should never be used for a device driver that is being
+		distributed; either obtain an official number or use
+		the local/experimental range.  The sudden addition or
+		removal of a driver with this number should not cause
+		ill effects to the system (bugs excepted.)
+
+ 43-223		UNALLOCATED
+
+224-239		SEE NOTE
+
+		This range is currently assigned as part of the
+		local/experimental range.  However, because of the
+		Linux way of setting a limit on the highest device
+		number in the system, currently set at 63 by default,
+		I am considering changing the local/experimental use
+		to 60-63, 120-127, 240-254.  If you are currently
+		using the range 224-239 and such a change would pose a
+		problem for you, please contact <hpa@storm.net> as
+		soon as possible.
+
+240-254		LOCAL USE
 		Allocated for local/experimental use
 
 		Please note that MAX_CHRDEV and MAX_BLKDEV in
@@ -586,6 +613,8 @@
 /dev/mouse	mouse port	symbolic	Current mouse device
 /dev/tape	tape device	symbolic	Current tape device
 /dev/cdrom	CD-ROM device	symbolic	Current CD-ROM device
+/dev/cdwriter	CD-writer	symbolic	Current CD-writer device
+/dev/scanner	scanner		symbolic	Current scanner device
 /dev/modem	modem port	symbolic	Current dialout device
 /dev/root	root device	symbolic	Current root filesystem
 /dev/swap	swap device	symbolic	Current swap device
@@ -595,6 +624,13 @@
 exists, /dev/modem shold point to the appropriate dialout (alternate)
 device.
 
+For SCSI devices, /dev/tape and /dev/cdrom should point to the
+``cooked'' devices (/dev/st* and /dev/sr*, respectively), whereas
+/dev/cdwriter and /dev/scanner should point to the appropriate generic
+SCSI devices (/dev/sg*).
+
+/dev/mouse may point to a dialout (alternate) TTY device, a hardware
+mouse device, or a socket for a mouse driver program.
 
 	Sockets and pipes
 
diff -u --recursive --new-file v1.3.42/linux/Documentation/unicode.txt linux/Documentation/unicode.txt
--- v1.3.42/linux/Documentation/unicode.txt	Sun Sep  3 12:26:48 1995
+++ linux/Documentation/unicode.txt	Sat Nov 18 12:08:28 1995
@@ -30,6 +30,9 @@
 user-defined map now defaults to U+F000 to U+F1FF, emulating the
 previous behaviour.
 
+Actual characters assigned in the Corporate Zone
+------------------------------------------------
+
 In addition, the following characters not present in Unicode 1.1.4 (at
 least, I have not found them!) have been defined; these are used by
 the DEC VT graphics map:
@@ -45,5 +48,79 @@
 character, and hence has been coded as U+2500 FORMS LIGHT HORIZONTAL.
 However, I left U+F802 blank should the need arise.  
 
-	H. Peter Anvin <Peter.Anvin@linux.org>
-	Yggdrasil Computing, Inc.
+Klingon language support
+------------------------
+
+Unfortunately, Unicode/ISO 10646 does not allocate code points for the
+language Klingon, probably fearing the potential code point explosion
+if many fictional lanugages were submitted for inclusion.  There are
+also political reasons (the Japanese, for example, are not too happy
+about the whole 16-bit concept to begin with.)  However, with Linux
+being a hacker-driven OS it seems this is a brilliant linguistic hack
+worth supporting.  Hence I have chosen to add it to the list in the
+Linux "Corporate" Zone.
+
+Several glyph forms for the Klingon alphabet has been proposed.
+However, since the set of symbols appear to be consistent throughout,
+with only the actual shapes being different, in keeping with standard
+Unicode practice these differences are considered font variants.
+
+Klingon has an alphabet of 26 characters, a positional numeric writing
+system with 10 digits, and is written left-to-right, top-to-bottom.
+Punctuation appears to be only used in Latin transliteration; it is
+appears customary to write each sentence on its own line, and
+centered.  Space has been reserved for punctuation should it prove
+necessary.
+
+This encoding has been endorsed by the Klingon Language Institute.
+For more information, contact them at:
+
+	http://www.kli.org/
+
+Since the characters in the beginning of the Linux CZ have been more
+of the dingbats/symbols/forms type and this is a language, I have
+located it at the end, on a 16-cell boundary in keeping with standard
+Unicode practice.
+
+U+F8D0	KLINGON LETTER A
+U+F8D1	KLINGON LETTER B
+U+F8D2	KLINGON LETTER CH
+U+F8D3	KLINGON LETTER D
+U+F8D4	KLINGON LETTER E
+U+F8D5	KLINGON LETTER GH
+U+F8D6	KLINGON LETTER H
+U+F8D7	KLINGON LETTER I
+U+F8D8	KLINGON LETTER J
+U+F8D9	KLINGON LETTER L
+U+F8DA	KLINGON LETTER M
+U+F8DB	KLINGON LETTER N
+U+F8DC	KLINGON LETTER NG
+U+F8DD	KLINGON LETTER O
+U+F8DE	KLINGON LETTER P
+U+F8DF	KLINGON LETTER Q
+	- Written <q> in standard Okrand Latin transliteration
+U+F8E0	KLINGON LETTER QH
+	- Written <Q> in standard Okrand Latin transliteration
+U+F8E1	KLINGON LETTER R
+U+F8E2	KLINGON LETTER S
+U+F8E3	KLINGON LETTER T
+U+F8E4	KLINGON LETTER TLH
+U+F8E5	KLINGON LETTER U
+U+F8E6	KLINGON LETTER V
+U+F8E7	KLINGON LETTER W
+U+F8E8	KLINGON LETTER Y
+U+F8E9	KLINGON LETTER GLOTTAL STOP
+
+U+F8F0	KLINGON DIGIT ZERO
+U+F8F1	KLINGON DIGIT ONE
+U+F8F2	KLINGON DIGIT TWO
+U+F8F3	KLINGON DIGIT THREE
+U+F8F4	KLINGON DIGIT FOUR
+U+F8F5	KLINGON DIGIT FIVE
+U+F8F6	KLINGON DIGIT SIX
+U+F8F7	KLINGON DIGIT SEVEN
+U+F8F8	KLINGON DIGIT EIGHT
+U+F8F9	KLINGON DIGIT NINE
+
+
+	H. Peter Anvin <hpa@storm.net>
diff -u --recursive --new-file v1.3.42/linux/Makefile linux/Makefile
--- v1.3.42/linux/Makefile	Fri Nov 17 08:42:24 1995
+++ linux/Makefile	Fri Nov 17 17:21:14 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 42
+SUBLEVEL = 43
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.42/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v1.3.42/linux/arch/alpha/kernel/process.c	Tue Oct 10 18:46:30 1995
+++ linux/arch/alpha/kernel/process.c	Sat Nov 18 12:23:19 1995
@@ -57,8 +57,8 @@
 
 void show_regs(struct pt_regs * regs)
 {
-	printk("\nps: %04lx pc: %016lx\n", regs->ps, regs->pc);
-	printk("rp: %016lx sp: %p\n", regs->r26, regs+1);
+	printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
+	printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
 	printk(" r0: %016lx  r1: %016lx  r2: %016lx  r3: %016lx\n",
 	       regs->r0, regs->r1, regs->r2, regs->r3);
 	printk(" r4: %016lx  r5: %016lx  r6: %016lx  r7: %016lx\n",
diff -u --recursive --new-file v1.3.42/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v1.3.42/linux/arch/alpha/kernel/traps.c	Wed Sep 27 15:59:56 1995
+++ linux/arch/alpha/kernel/traps.c	Sat Nov 18 12:22:52 1995
@@ -25,8 +25,8 @@
 		return;
 	printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
 	sp = (unsigned long) (regs+1);
-	printk("pc = %lx ps = %04lx\n", regs->pc, regs->ps);
-	printk("rp = %lx sp = %lx\n", regs->r26, sp);
+	printk("pc = [<%lx>] ps = %04lx\n", regs->pc, regs->ps);
+	printk("rp = [<%lx>] sp = %lx\n", regs->r26, sp);
 	printk("r0=%lx r1=%lx r2=%lx r3=%lx\n",
 		regs->r0, regs->r1, regs->r2, regs->r3);
 	printk("r8=%lx\n", regs->r8);
diff -u --recursive --new-file v1.3.42/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c
--- v1.3.42/linux/arch/alpha/mm/fault.c	Mon Nov 13 12:36:42 1995
+++ linux/arch/alpha/mm/fault.c	Sun Nov 19 12:47:11 1995
@@ -54,10 +54,8 @@
 		goto good_area;
 	if (!(vma->vm_flags & VM_GROWSDOWN))
 		goto bad_area;
-	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
+	if (expand_stack(vma, address))
 		goto bad_area;
-	vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
-	vma->vm_start = (address & PAGE_MASK);
 /*
  * Ok, we have a good vm_area for this memory access, so
  * we can handle it..
diff -u --recursive --new-file v1.3.42/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c
--- v1.3.42/linux/arch/i386/boot/compressed/misc.c	Tue Jun 20 09:10:31 1995
+++ linux/arch/i386/boot/compressed/misc.c	Tue Nov 21 08:34:54 1995
@@ -5,13 +5,14 @@
  * adapted for Linux.
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- * puts by Nick Holloway 1993
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
  */
 
 #include "gzip.h"
 #include "lzw.h"
 
 #include <asm/segment.h>
+#include <asm/io.h>
 
 /*
  * These are set up by the setup-routine at boot-time:
@@ -24,9 +25,9 @@
 	unsigned short orig_video_page;
 	unsigned char  orig_video_mode;
 	unsigned char  orig_video_cols;
-	unsigned short orig_video_ega_ax;
+	unsigned short unused2;
 	unsigned short orig_video_ega_bx;
-	unsigned short orig_video_ega_cx;
+	unsigned short unused3;
 	unsigned char  orig_video_lines;
 	unsigned char  orig_video_isVGA;
 };
@@ -77,6 +78,7 @@
 local int get_method(int);
 
 char *vidmem = (char *)0xb8000;
+int vidport;
 int lines, cols;
 
 static void puts(const char *);
@@ -128,7 +130,7 @@
 
 static void puts(const char *s)
 {
-	int x,y;
+	int x,y,pos;
 	char c;
 
 	x = SCREEN_INFO.orig_x;
@@ -155,6 +157,12 @@
 
 	SCREEN_INFO.orig_x = x;
 	SCREEN_INFO.orig_y = y;
+
+	pos = (x + cols * y) * 2;	/* Update cursor position */
+	outb_p(14, vidport);
+	outb_p(0xff & (pos >> 9), vidport+1);
+	outb_p(15, vidport);
+	outb_p(0xff & (pos >> 1), vidport+1);
 }
 
 __ptr_t memset(__ptr_t s, int c, size_t n)
@@ -315,10 +323,13 @@
 
 void decompress_kernel()
 {
-	if (SCREEN_INFO.orig_video_mode == 7)
+	if (SCREEN_INFO.orig_video_mode == 7) {
 		vidmem = (char *) 0xb0000;
-	else
+		vidport = 0x3b4;
+	} else {
 		vidmem = (char *) 0xb8000;
+		vidport = 0x3d4;
+	}
 
 	lines = SCREEN_INFO.orig_video_lines;
 	cols = SCREEN_INFO.orig_video_cols;
diff -u --recursive --new-file v1.3.42/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v1.3.42/linux/arch/i386/kernel/entry.S	Wed Nov  8 07:11:29 1995
+++ linux/arch/i386/kernel/entry.S	Sun Nov 19 21:11:42 1995
@@ -343,10 +343,6 @@
 #endif
 	cmpl SYMBOL_NAME(task),%eax	# task[0] cannot have signals
 	je 2f
-	cmpl $0,state(%eax)		# state
-	jne reschedule
-	cmpl $0,counter(%eax)		# counter
-	je reschedule
 	movl blocked(%eax),%ecx
 	movl %ecx,%ebx			# save blocked in %ebx for signal handling
 	notl %ecx
@@ -660,4 +656,11 @@
 	.long SYMBOL_NAME(sys_msync)
 	.long SYMBOL_NAME(sys_readv)		/* 145 */
 	.long SYMBOL_NAME(sys_writev)
-	.space (NR_syscalls-146)*4
+	.long 0
+	.long 0
+	.long 0
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.space (NR_syscalls-154)*4
diff -u --recursive --new-file v1.3.42/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v1.3.42/linux/arch/i386/kernel/process.c	Wed Nov  8 07:11:29 1995
+++ linux/arch/i386/kernel/process.c	Sat Nov 18 12:08:28 1995
@@ -124,7 +124,7 @@
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
-	printk("EIP: %04x:%08lx",0xffff & regs->cs,regs->eip);
+	printk("EIP: %04x:[<%08lx>]",0xffff & regs->cs,regs->eip);
 	if (regs->cs & 3)
 		printk(" ESP: %04x:%08lx",0xffff & regs->ss,regs->esp);
 	printk(" EFLAGS: %08lx\n",regs->eflags);
diff -u --recursive --new-file v1.3.42/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v1.3.42/linux/arch/i386/kernel/setup.c	Fri Nov 17 08:42:24 1995
+++ linux/arch/i386/kernel/setup.c	Tue Nov 21 09:42:32 1995
@@ -5,7 +5,7 @@
  */
 
 /*
- * This file handles the architecture-dependent parts of process handling..
+ * This file handles the architecture-dependent parts of initialization
  */
 
 #include <linux/errno.h>
@@ -152,12 +152,39 @@
 	request_region(0xf0,0x10,"npu");
 }
 
+static const char * i486model(unsigned int nr)
+{
+	static const char *model[] = {
+		"0", "DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4"
+	};
+	if (nr < sizeof(model)/sizeof(char *))
+		return model[nr];
+	return "Unknown";
+}
+
+static const char * i586model(unsigned int nr)
+{
+	static const char *model[] = {
+		"0", "Pentium 60/66","Pentium 75+"
+	};
+	if (nr < sizeof(model)/sizeof(char *))
+		return model[nr];
+	return "Unknown";
+}
+
+static const char * getmodel(int x86, int model)
+{
+	switch (x86) {
+		case 4:
+			return i486model(model);
+		case 5:
+			return i586model(model);
+	}
+	return "Unknown";
+}
+
 int get_cpuinfo(char * buffer)
 {
-	static const char *model[2][9]={{"DX","SX","DX/2","4","SX/2","6",
-				"DX/2-WB","DX/4"},
-			{"Pentium 60/66","Pentium 75+","3",
-				"4","5","6","7","8"}};
 	char mask[2];
 #ifndef __SMP__	
 	mask[0] = x86_mask+'@';
@@ -180,7 +207,7 @@
 			      "CMPXCHGB8B\t: %s\n"
 		              "BogoMips\t: %lu.%02lu\n",
 			      x86+'0', 
-			      x86_model ? model[x86-4][x86_model-1] : "Unknown",
+			      getmodel(x86, x86_model),
 			      x86_mask ? mask : "Unknown",
 			      x86_vendor_id,
 			      fdiv_bug ? "yes" : "no",
@@ -207,8 +234,7 @@
 	bp+=sprintf(bp,"\nmodel\t\t: ");
 	for(i=0;i<32;i++)
 		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s",cpu_data[i].x86_model?
-					model[cpu_data[i].x86-4][cpu_data[i].x86_model-1]:"Unknown");
+			bp+=sprintf(bp,"%-16s",getmodel(cpu_data[i].x86,cpu_data[i].x86_model));
 	bp+=sprintf(bp,"\nmask\t\t: ");
 	for(i=0;i<32;i++)
 		if(cpu_present_map&(1<<i))
diff -u --recursive --new-file v1.3.42/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v1.3.42/linux/arch/i386/kernel/traps.c	Wed Nov  8 07:11:30 1995
+++ linux/arch/i386/kernel/traps.c	Tue Nov 21 08:34:54 1995
@@ -27,7 +27,7 @@
 
 asmlinkage int system_call(void);
 asmlinkage void lcall7(void);
-struct desc_struct default_ldt;
+struct desc_struct default_ldt = { 0, 0 };
 
 static inline void console_verbose(void)
 {
@@ -113,7 +113,7 @@
 	console_verbose();
 	printk("%s: %04lx\n", str, err & 0xffff);
 	printk("CPU:    %d\n", smp_processor_id());
-	printk("EIP:    %04x:%08lx\nEFLAGS: %08lx\n", 0xffff & regs->cs,regs->eip,regs->eflags);
+	printk("EIP:    %04x:[<%08lx>]\nEFLAGS: %08lx\n", 0xffff & regs->cs,regs->eip,regs->eflags);
 	printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
 		regs->eax, regs->ebx, regs->ecx, regs->edx);
 	printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
@@ -153,7 +153,7 @@
 		    ((addr >= module_start) && (addr <= module_end))) {
 			if (i && ((i % 8) == 0))
 				printk("\n       ");
-			printk("%08lx ", addr);
+			printk("[<%08lx>] ", addr);
 			i++;
 		}
 	}
diff -u --recursive --new-file v1.3.42/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- v1.3.42/linux/arch/i386/mm/fault.c	Wed Nov  8 07:11:30 1995
+++ linux/arch/i386/mm/fault.c	Sun Nov 19 12:46:20 1995
@@ -46,8 +46,6 @@
 		goto good_area;
 	if (!(vma->vm_flags & VM_GROWSDOWN))
 		goto bad_area;
-	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
-		goto bad_area;
 	if (error_code & 4) {
 		/*
 		 * accessing the stack below %esp is always a bug.
@@ -58,8 +56,8 @@
 		if (address + 32 < regs->esp)
 			goto bad_area;
 	}
-	vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
-	vma->vm_start = (address & PAGE_MASK);
+	if (expand_stack(vma, address))
+		goto bad_area;
 /*
  * Ok, we have a good vm_area for this memory access, so
  * we can handle it..
diff -u --recursive --new-file v1.3.42/linux/drivers/block/README.ide linux/drivers/block/README.ide
--- v1.3.42/linux/drivers/block/README.ide	Mon Oct 23 18:02:01 1995
+++ linux/drivers/block/README.ide	Fri Nov 17 08:33:07 1995
@@ -34,6 +34,8 @@
 		- PCI support is automatic
 		- for VLB, use kernel command line option:   ide0=cmd640_vlb
 		- this support also enables the secondary i/f on most cards
+		- experimental interface timing parameter support
+NEW!	- experimental support for UMC 8672 interfaces
 NEW!	- support for secondary interface on the FGI/Holtek HT-6560B VLB i/f
 		- use kernel command line option:   ide1=ht6560
 NEW!	- experimental "fast" speed support for QD6580 interfaces
@@ -45,7 +47,10 @@
 NEW!	- transparent support for DiskManager 6.0x and "Dynamic Disk Overlay"
 	- works with Linux fdisk, LILO, loadlin, bootln, etc..
 NEW!	- mostly transparent support for EZ-Drive
-		- LILO is incompatible (also harmless) with EZ-Drive
+NEW!		- to use LILO with EZ, install LILO on the linux partition
+		  rather than on the master boot record, and then mark the
+		  linux partition as "bootable" or "active" using fdisk.
+		  (courtesy of Juha Laiho <jlaiho@ichaos.nullnet.fi>).
 NEW!	- ide-cd.c now compiles separate from ide.c
 NEW!	- Bus-Master DMA support for Intel PCI Triton chipset IDE interfaces
 		- for details, see comments at top of triton.c
@@ -466,24 +471,62 @@
 
 ================================================================================
 
- from:       'delman@mipg.upenn.edu'
- subject:    rz1000
+ 1995 Nov 16 at 08:25  EST
+ from:       'dwhysong@dolphin.physics.ucsb.edu' (BNR400)
 
-Hi Mark! Looks like you managed to get the info from Intel to disable
-the read-ahead feature of the RZ1000. My encounter with
-Zeos (subsidiary of Micron which owns PCTech) has not been as
-successful --- one guy needs to ask his supervisors about NDA, another
-guy thinks that there is too much of a performance hit with read-ahead
-disabled.
-
-Did the following benchmark to see how true the claim is.
-With Linux 1.2.13, average of 10 "hdparm -t" in MB/s:
-
-                       hdparm -c0        hdparm -c1
-read-ahead enabled        4.28              4.25
-read-ahead disabled       3.58              4.30
+[I'm cc'ing this to Mark Lord: FYI, I've got at DTC2278S VLB EIDE
+controller with a Connor CFA850A as /dev/hda and a Maxtor 7213A as
+/dev/hdb using Linux 1.2.13 w/patches for assembly strcpy and the kswap
+patches. I'm getting strange behavior and an unstable system when I try to
+use 32 bit VLB data transfer to the interface card. However, hdparm
+reports that the Connor is extremely fast when I can get the 32 bit mode
+enabled using hdparm -c1 /dev/hd(a|b). However, if I don't do hdparm -c1
+on both /dev/hda and /dev/hdb, then when I run "hdparm -t /dev/hda" the
+disk subsystem locks up... the disk LED comes on and stays on, and no
+other programs are able to get disk access (I can switch VC's, but I can't
+get past the username prompt). I thought you should know about this. I'm
+not sure if it's a problem with the support for the DTC cards, or a
+peculiarity with my hardware configuration. I doubt that my hardware
+itself is flaky, though that's always a possibility.]
+
+On Wed, 15 Nov 1995, Michael Faurot wrote:
+
+> > The trick is setting BOTH drives to use the 32 bit interface.
+>
+> Congrats on getting it going.  Those are some great transfer
+> rates.  I noticed you did switch on the unmasking.  Noticed any
+> problems with things under extreme load or with serial transfers?
+
+I've never had any problems which I could trace to interrupt unmasking.
+Of course, my system usually doesn't have a really heavy load, either.
+These numbers seem way too high for a disk with something like 3500 (?)
+RPM.
+
+Sleepy# hdparm -t /dev/hda
+
+/dev/hda:
+ Timing buffer-cache reads:   32 MB in  2.24 seconds =14.29 MB/sec
+ Timing buffered disk reads:  16 MB in  3.63 seconds = 4.41 MB/sec
+ Estimating raw driver speed: 16 MB in  2.51 seconds = 6.37 MB/sec
+
+> Not sure I was much help to you, but I'm glad to hear you got it
+> working--and pretty impressivly at that. :-)
+
+Mmm, well, about that... I've found that my Connor drive (/dev/hda) is
+pretty fast when I have my system configured like this. I'm still not
+sure I trust the "hdparm -t"  results, though. However, when I try
+"hdparm -t /dev/hdb" (/dev/hdb is an older Maxtor 7213A) I have the same
+problem I had before with my disk subsystem locking up.
+
+I've tried just about every possible combination of flags in ide.c and
+hdparm, and I can't get decent performance out of this drive/controller
+combination without some kind of instability creeping in. I'm living with
+the situation now only because /dev/hdb is a DOS-only drive, and I don't
+need it under Linux. However, I don't really like the situation.
 
-Maybe -c1 should be the default for the RZ1000, or as a suggestion in
-the README for people with the RZ1000.
+-Dave
+dwhysong@physics.ucsb.edu
+
+(Why can't this stuff be simple? Plug the card in, and it works? Every
+hardware manufacturer has to have their own way of doing things...)
 
-Cheers, Delman.
diff -u --recursive --new-file v1.3.42/linux/drivers/block/cmd640.c linux/drivers/block/cmd640.c
--- v1.3.42/linux/drivers/block/cmd640.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/block/cmd640.c	Fri Nov 17 08:33:07 1995
@@ -0,0 +1,444 @@
+/*
+ *  linux/drivers/block/cmd640.c	Version 0.01  Nov 16, 1995
+ *
+ *  Copyright (C) 1995  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Principal Author/Maintainer:  abramov@cecmow.enet.dec.com (Igor)
+ *
+ *  This file provides support for the advanced features and bugs
+ *  of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
+ *
+ *  Version 0.01	Initial version, hacked out of ide.c,
+ *			and #include'd rather than compiled separately.
+ *			This will get cleaned up in a subsequent release.
+ */
+
+/* Interface to access cmd640x registers */
+static void (*put_cmd640_reg)(int key, int reg_no, int val);
+static byte (*get_cmd640_reg)(int key, int reg_no);
+
+enum { none, vlb, pci1, pci2 };
+static int	bus_type = none;
+static int	cmd640_chip_version;
+static int	cmd640_key;
+static byte	is_cmd640[MAX_HWIFS];
+
+/*
+ * For some unknown reasons pcibios functions which read and write registers
+ * do not work with cmd640. We use direct io instead.
+ */
+
+/* PCI method 1 access */
+
+static void put_cmd640_reg_pci1(int key, int reg_no, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outl_p((reg_no & 0xfc) | key, 0xcf8);
+	outb_p(val, (reg_no & 3) + 0xcfc);
+	restore_flags(flags);
+}
+
+static byte get_cmd640_reg_pci1(int key, int reg_no)
+{
+	byte b;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outl_p((reg_no & 0xfc) | key, 0xcf8);
+	b = inb(0xcfc + (reg_no & 3));
+	restore_flags(flags);
+	return b;
+}
+
+/* PCI method 2 access (from CMD datasheet) */
+
+static void put_cmd640_reg_pci2(int key, int reg_no, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb_p(0x10, 0xcf8);
+	outb_p(val, key + reg_no);
+	outb_p(0, 0xcf8);
+	restore_flags(flags);
+}
+
+static byte get_cmd640_reg_pci2(int key, int reg_no)
+{
+	byte b;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb_p(0x10, 0xcf8);
+	b = inb(key + reg_no);
+	outb_p(0, 0xcf8);
+	restore_flags(flags);
+	return b;
+}
+
+/* VLB access */
+
+static void put_cmd640_reg_vlb(int key, int reg_no, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb(reg_no, key + 8);
+	outb(val, key + 0xc);
+	restore_flags(flags);
+}
+
+static byte get_cmd640_reg_vlb(int key, int reg_no)
+{
+	byte b;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb(reg_no, key + 8);
+	b = inb(key + 0xc);
+	restore_flags(flags);
+	return b;
+}
+
+/*
+ * Probe for CMD640x -- pci method 1
+ */
+
+static int probe_for_cmd640_pci1(void)
+{
+	long id;
+	int	k;
+
+	for (k = 0x80000000; k <= 0x8000f800; k += 0x800) {
+		outl(k, 0xcf8);
+		id = inl(0xcfc);
+		if (id != 0x06401095)
+			continue;
+		put_cmd640_reg = put_cmd640_reg_pci1;
+		get_cmd640_reg = get_cmd640_reg_pci1;
+		cmd640_key = k;
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Probe for CMD640x -- pci method 2
+ */
+
+static int probe_for_cmd640_pci2(void)
+{
+	int i;
+	int v_id;
+	int d_id;
+
+	for (i = 0xc000; i <= 0xcf00; i += 0x100) {
+		outb(0x10, 0xcf8);
+		v_id = inw(i);
+		d_id = inw(i + 2);
+		outb(0, 0xcf8);
+		if (v_id != 0x1095 || d_id != 0x640)
+			continue;
+		put_cmd640_reg = put_cmd640_reg_pci2;
+		get_cmd640_reg = get_cmd640_reg_pci2;
+		cmd640_key = i;
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Probe for CMD640x -- vlb
+ */
+
+static int probe_for_cmd640_vlb(void) {
+	byte b;
+
+	outb(0x50, 0x178);
+	b = inb(0x17c);
+	if (b == 0xff || b == 0 || (b & 0x20)) {
+		outb(0x50, 0xc78);
+		b = inb(0x7c);
+		if (b == 0xff || b == 0 || !(b & 0x20))
+			return 0;
+		cmd640_key = 0x70;
+	} else {
+		cmd640_key = 0x170;
+	}
+	put_cmd640_reg = put_cmd640_reg_vlb;
+	get_cmd640_reg = get_cmd640_reg_vlb;
+	return 1;
+}
+
+/*
+ * Probe for Cmd640x and initialize it if found
+ */
+
+int ide_probe_for_cmd640x(void)
+{
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; i++)
+		is_cmd640[i] = 0;
+
+	if (probe_for_cmd640_pci1()) {
+		bus_type = pci1;
+	} else if (probe_for_cmd640_pci2()) {
+		bus_type = pci2;
+	} else if (cmd640_vlb && probe_for_cmd640_vlb()) {
+		/* May be remove cmd640_vlb at all, and probe in any case */
+		bus_type = vlb;
+	} else {
+		return 0;
+	}
+
+	/*
+	 * Undocumented magic. (There is no 0x5b port in specs)
+	 */
+
+	put_cmd640_reg(cmd640_key, 0x5b, 0xbd);
+	if (get_cmd640_reg(cmd640_key, 0x5b) != 0xbd) {
+		printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
+		return 0;
+	}
+	put_cmd640_reg(cmd640_key, 0x5b, 0);
+
+	/*
+	 * Documented magic.
+	 */
+
+	cmd640_chip_version = get_cmd640_reg(cmd640_key, 0x50) & 3;
+	if (cmd640_chip_version == 0) {
+		printk ("ide: wrong CMD640 version -- 0\n");
+		return 0;
+	}
+
+	put_cmd640_reg(cmd640_key, 0x51, get_cmd640_reg(cmd640_key, 0x51) | 0xc8);
+	put_cmd640_reg(cmd640_key, 0x57, 0);
+	put_cmd640_reg(cmd640_key, 0x57, get_cmd640_reg(cmd640_key, 0x57) | 0x0c);
+
+	serialized = 1;
+
+	printk("ide: buggy CMD640 interface at ");
+	switch (bus_type) {
+		case vlb :
+			printk("local bus, port 0x%x", cmd640_key);
+			break;
+		case pci1:
+			printk("pci, (0x%x)", cmd640_key);
+			break;
+		case pci2:
+			printk("pci,(access method 2) (0x%x)", cmd640_key);
+			break;
+	}
+
+	is_cmd640[0] = is_cmd640[1] = 1;
+
+	/*
+	 * Reset interface timings
+	 */
+
+	put_cmd640_reg(cmd640_key, 0x58, 0);
+	put_cmd640_reg(cmd640_key, 0x52, 0);
+
+	printk("\n ... serialized, disabled read-ahead, secondary interface enabled\n");
+
+	return 1;
+}
+
+static int as_clocks(int a) {
+	switch (a & 0xf0) {
+		case 0 :	return 4;
+		case 0x40 :	return 2;
+		case 0x80 :	return 3;
+		case 0xc0 :	return 5;
+		default :	return -1;
+	}
+}
+
+/*
+ * Tuning of drive parameters
+ */
+
+static void cmd640_set_timing(int if_num, int dr_num, int r1, int r2) {
+	int  b_reg;
+	byte b;
+	int  r52;
+
+	b_reg = if_num ? 0x57 : dr_num ? 0x55 : 0x53;
+
+	if (if_num == 0) {
+		put_cmd640_reg(cmd640_key, b_reg, r1);
+		put_cmd640_reg(cmd640_key, b_reg + 1, r2);
+	} else {
+		b = get_cmd640_reg(cmd640_key, b_reg);
+		if ((b&1) == 0) {
+			put_cmd640_reg(cmd640_key, b_reg, r1);
+		} else {
+			if (as_clocks(b) < as_clocks(r1))
+				put_cmd640_reg(cmd640_key, b_reg, r1);
+		}
+		b = get_cmd640_reg(cmd640_key, b_reg + 1);
+		if (b == 0) {
+			put_cmd640_reg(cmd640_key, b_reg + 1, r2);
+		} else {
+			r52 = (b&0xf) < (r2&0xf) ? (r2&0xf) : (b&0xf);
+			r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
+			put_cmd640_reg(cmd640_key, b_reg+1, r52);
+		}
+	}
+
+	b = get_cmd640_reg(cmd640_key, 0x52);
+	if (b == 0) {
+		put_cmd640_reg(cmd640_key, 0x52, r2);
+	} else {
+		r52 = (b&0xf) < (r2&0xf) ? (r2&0xf) : (b&0xf);
+		r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
+		put_cmd640_reg(cmd640_key, 0x52, r52);
+	}
+}
+
+static int bus_speed = 33; /* MHz */
+
+struct pio_timing {
+	int	mc_time;	/* Minimal cycle time (ns) */
+	int	av_time;	/* Address valid to DIOR-/DIOW- setup (ns) */
+	int	ds_time;	/* DIOR data setup	(ns) */
+} pio_timings[6] = {
+	{ 70,	165,	600 },	/* PIO Mode 0 */
+	{ 50,	125,	383 },	/* PIO Mode 1 */
+	{ 30,	100,	240 },	/* PIO Mode 2 */
+	{ 30,	80,	180 },	/* PIO Mode 3 */
+	{ 25,	70,	125 },	/* PIO Mode 4 */
+	{ 20,	50,	100 }	/* PIO Mode ? */
+};
+
+struct drive_pio_info {
+	const char	*name;
+	int		pio;
+} drive_pios[] = {
+	{ "Maxtor 7131 AT", 1 },
+	{ "Maxtor 7171 AT", 1 },
+	{ "Maxtor 7213 AT", 1 },
+	{ "Maxtor 7245 AT", 1 },
+	{ "SAMSUNG SHD-3122A", 1 },
+	{ "QUANTUM ELS127A", 0 },
+	{ "QUANTUM LPS240A", 0 },
+	{ "QUANTUM LPS270A", 3 },
+	{ "QUANTUM LPS540A", 3 },
+	{ NULL,	0 }
+};
+
+static int known_drive_pio(char* name) {
+	struct drive_pio_info* pi;
+
+	for (pi = drive_pios; pi->name != NULL; pi++) {
+		if (strcmp(pi->name, name) == 0)
+			return pi->pio;
+	}
+	return -1;
+}
+
+static void cmd640_timings_to_regvals(int mc_time, int av_time, int ds_time,
+				int clock_time,
+				int* r1, int* r2)
+{
+	int a, b;
+
+	a = (mc_time + clock_time - 1)/clock_time;
+	if (a <= 2) *r1 = 0x40;
+	else if (a == 3) *r1 = 0x80;
+	else if (a == 4) *r1 = 0;
+	else *r1 = 0xc0;
+
+	a = (av_time + clock_time - 1)/clock_time;
+	if (a < 2)
+		a = 2;
+	b = (ds_time + clock_time - 1)/clock_time - a;
+	if (b < 2)
+		b = 2;
+	if (b > 0x11) {
+		a += b - 0x11;
+		b = 0x11;
+	}
+	if (a > 0xf)
+		a = 0;
+	if (cmd640_chip_version > 1)
+		b -= 1;
+	if (b > 0xf)
+		b = 0;
+	*r2 = (a << 4) | b;
+}
+
+static void set_pio_mode(int if_num, int drv_num, int mode_num) {
+	int p_base;
+	int i;
+
+	p_base = if_num ? 0x170 : 0x1f0;
+	outb(3, p_base + 1);
+	outb(mode_num | 8, p_base + 2);
+	outb((drv_num | 0xa) << 4, p_base + 6);
+	outb(0xef, p_base + 7);
+	for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
+		delay_10ms();
+}
+
+void cmd640_tune_drive(ide_drive_t* drive) {
+	int interface_number;
+	int drive_number;
+	int clock_time; /* ns */
+	int max_pio;
+	int mc_time, av_time, ds_time;
+	struct hd_driveid* id;
+	int r1, r2;
+
+	/*
+	 * Determine if drive is under cmd640 control
+	 */
+	interface_number = HWIF(drive) - ide_hwifs;
+	if (!is_cmd640[interface_number])
+		return;
+
+	drive_number = drive - HWIF(drive)->drives;
+	clock_time = 1000/bus_speed;
+	id = drive->id;
+	if ((max_pio = known_drive_pio(id->model)) != -1) {
+		mc_time = pio_timings[max_pio].mc_time;
+		av_time = pio_timings[max_pio].av_time;
+		ds_time = pio_timings[max_pio].ds_time;
+	} else {
+		max_pio = id->tPIO;
+		mc_time = pio_timings[max_pio].mc_time;
+		av_time = pio_timings[max_pio].av_time;
+		ds_time = pio_timings[max_pio].ds_time;
+		if (id->field_valid & 2) {
+			if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
+				if (id->eide_pio_modes & 4) max_pio = 5;
+				else if (id->eide_pio_modes & 2) max_pio = 4;
+				else max_pio = 3;
+				ds_time = id->eide_pio_iordy;
+				mc_time = pio_timings[max_pio].mc_time;
+				av_time = pio_timings[max_pio].av_time;
+			} else {
+				ds_time = id->eide_pio;
+			}
+			if (ds_time == 0)
+				ds_time = pio_timings[max_pio].ds_time;
+		}
+	}
+	cmd640_timings_to_regvals(mc_time, av_time, ds_time, clock_time,
+				&r1, &r2);
+	set_pio_mode(interface_number, drive_number, max_pio);
+	cmd640_set_timing(interface_number, drive_number, r1, r2);
+	printk ("Mode and Timing set to PIO%d (0x%x 0x%x)\n", max_pio, r1, r2);
+}
diff -u --recursive --new-file v1.3.42/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v1.3.42/linux/drivers/block/floppy.c	Fri Nov 17 08:42:24 1995
+++ linux/drivers/block/floppy.c	Sun Nov 19 17:54:31 1995
@@ -1089,10 +1089,8 @@
 {
 	unsigned char perp_mode;
 
-	if (!floppy)
-		return;
-	if (floppy->rate & 0x40){
-		switch(raw_cmd->rate){
+	if (raw_cmd->rate & 0x40){
+		switch(raw_cmd->rate & 3){
 			case 0:
 				perp_mode=2;
 				break;
@@ -1222,18 +1220,18 @@
 static int fdc_dtr(void)
 {
 	/* If data rate not already set to desired value, set it. */
-	if (raw_cmd->rate == FDCS->dtr)
+	if ((raw_cmd->rate & 3) == FDCS->dtr)
 		return 0;
 
 	/* Set dtr */
-	fd_outb(raw_cmd->rate, FD_DCR);
+	fd_outb(raw_cmd->rate & 3, FD_DCR);
 
 	/* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB)
 	 * need a stabilization period of several milliseconds to be
 	 * enforced after data rate changes before R/W operations.
 	 * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
 	 */
-	FDCS->dtr = raw_cmd->rate;
+	FDCS->dtr = raw_cmd->rate & 3;
 	return(wait_for_completion(jiffies+2*HZ/100,
 				   (timeout_fn) floppy_ready));
 } /* fdc_dtr */
@@ -1979,7 +1977,7 @@
 
 	raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
 		/*FD_RAW_NEED_DISK |*/ FD_RAW_NEED_SEEK;
-	raw_cmd->rate = floppy->rate & 0x3;
+	raw_cmd->rate = floppy->rate & 0x43;
 	raw_cmd->cmd_count = NR_F;
 	COMMAND = FM_MODE(floppy,FD_FORMAT);
 	DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,format_req.head);
@@ -2385,7 +2383,7 @@
 		SIZECODE = 2;
 	} else
 		SIZECODE = FD_SIZECODE(floppy);
-	raw_cmd->rate = floppy->rate & 3;
+	raw_cmd->rate = floppy->rate & 0x43;
 	if ((floppy->rate & FD_2M) &&
 	    (TRACK || HEAD) &&
 	    raw_cmd->rate == 2)
@@ -2951,7 +2949,7 @@
 		rcmd = & (ptr->next);
 		if (!(ptr->flags & FD_RAW_MORE))
 			return 0;
-		ptr->rate &= 0x03;
+		ptr->rate &= 0x43;
 	}
 }
 
diff -u --recursive --new-file v1.3.42/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.3.42/linux/drivers/block/ide.c	Wed Nov  8 07:11:30 1995
+++ linux/drivers/block/ide.c	Fri Nov 17 08:33:07 1995
@@ -1,11 +1,11 @@
 /*
- *  linux/drivers/block/ide.c	Version 5.17  Nov 3, 1995
+ *  linux/drivers/block/ide.c	Version 5.18  Nov 16, 1995
  *
  *  Copyright (C) 1994, 1995  Linus Torvalds & authors (see below)
  */
 
 /*
- * This is the multiple IDE interface driver, as evolved from hd.c.  
+ * This is the multiple IDE interface driver, as evolved from hd.c.
  * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
  * There can be up to two drives per interface, as per the ATA-2 spec.
  *
@@ -13,17 +13,17 @@
  * Secondary i/f:  ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64
  * Tertiary i/f:   ide2: major=33; (hde)         minor=0; (hdf)         minor=64
  * Quaternary i/f: ide3: major=34; (hdg)         minor=0; (hdh)         minor=64
- * 
+ *
  * It is easy to extend ide.c to handle more than four interfaces:
  *
  *	Change the MAX_HWIFS constant in ide.h.
- * 
+ *
  *	Define some new major numbers (in major.h), and insert them into
  *	the ide_hwif_to_major table in ide.c.
- * 
+ *
  *	Fill in the extra values for the new interfaces into the two tables
  *	inside ide.c:  default_io_base[]  and  default_irqs[].
- * 
+ *
  *	Create the new request handlers by cloning "do_ide3_request()"
  *	for each new interface, and add them to the switch statement
  *	in the ide_init() function in ide.c.
@@ -56,7 +56,7 @@
  *  Maintained by Mark Lord (mlord@bnr.ca):  ide.c, ide.h, triton.c, hd.c, ..
  *
  *  This was a rewrite of just about everything from hd.c, though some original
- *  code is still sprinkled about.  Think of it as a major evolution, with 
+ *  code is still sprinkled about.  Think of it as a major evolution, with
  *  inspiration from lots of linux users, esp.  hamish@zot.apana.org.au
  *
  *  Version 1.0 ALPHA	initial code, primary i/f working okay
@@ -167,15 +167,18 @@
  *			remove "Huh?" from cmd640 code
  *			added qd6580 interface speed select from Colten Edwards
  *  Version 5.17	kludge around bug in BIOS32 on Intel triton motherboards
+ *  Version 5.18	new CMD640 code, moved to cmd640.c, #include'd for now
+ *			new UMC8672 code, moved to umc8672.c, #include'd for now
+ *			disallow turning on DMA when h/w not capable of DMA
  *
  *  Driver compile-time options are in ide.h
  *
  *  To do, in likely order of completion:
+ *	- make cmd640.c and umc8672.c compile separately from ide.c
  *	- add ALI M1443/1445 chipset support from derekn@vw.ece.cmu.edu
- *	- add Promise Caching controller support from peterd@pnd-pc.demon.co.uk
  *	- add ioctls to get/set interface timings on various interfaces
+ *	- add Promise Caching controller support from peterd@pnd-pc.demon.co.uk
  *	- modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f
- *	- improved CMD support:  handed this off to someone else
  *	- find someone to work on IDE *tape drive* support
  */
 
@@ -209,9 +212,14 @@
 
 #include "ide.h"
 
+#ifdef SUPPORT_CMD640
+void cmd640_tune_drive(ide_drive_t *);
+static int cmd640_vlb = 0;
+#endif
+
        ide_hwif_t	ide_hwifs[MAX_HWIFS];		/* hwif info */
 static ide_hwgroup_t	*irq_to_hwgroup [16];
-static const byte	ide_hwif_to_major[MAX_HWIFS]   = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
+static const byte	ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
 
 static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
 static const byte	default_irqs[MAX_HWIFS]     = {14, 15, 11, 10};
@@ -999,7 +1007,7 @@
 
 /*
  * multwrite() transfers a block of one or more sectors of data to a drive
- * as part of a disk multwrite operation.  
+ * as part of a disk multwrite operation.
  */
 static void multwrite (ide_drive_t *drive)
 {
@@ -1232,7 +1240,7 @@
 	if (drive->select.b.lba) {
 #ifdef DEBUG
 		printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
-			drive->name, (rq->cmd==READ)?"read":"writ", 
+			drive->name, (rq->cmd==READ)?"read":"writ",
 			block, rq->nr_sectors, (unsigned long) rq->buffer);
 #endif
 		OUT_BYTE(block,io_base+IDE_SECTOR_OFFSET);
@@ -1495,7 +1503,7 @@
 		printk("%s: marginal timeout\n", drive->name);
 	} else {				 /* drive not responding */
 		hwgroup->handler = NULL;
-		if (hwgroup->hwif->dmaproc) 
+		if (hwgroup->hwif->dmaproc)
 			(void) hwgroup->hwif->dmaproc (ide_dma_abort, drive);
 		if (!ide_error(drive, "irq timeout", GET_STAT()))
 			do_hwgroup_request (hwgroup);
@@ -1522,7 +1530,7 @@
  * In reality, this is a non-issue.  The new command is not sent unless the
  * drive is ready to accept one, in which case we know the drive is not
  * trying to interrupt us.  And ide_set_handler() is always invoked before
- * completing the issuance of any new drive command, so we will not be 
+ * completing the issuance of any new drive command, so we will not be
  * accidently invoked as a result of any valid command completion interrupt.
  *
  */
@@ -1806,24 +1814,24 @@
 		case BLKRAGET:
 			return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)]);
 
-         	case BLKGETSIZE:   /* Return device size */
+	 	case BLKGETSIZE:   /* Return device size */
 			return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects);
 		case BLKRRPART: /* Re-read partition tables */
 			return revalidate_disk(inode->i_rdev);
 
-                case HDIO_GET_KEEPSETTINGS:
+		case HDIO_GET_KEEPSETTINGS:
 			return write_fs_long(arg, drive->keep_settings);
 
-                case HDIO_GET_UNMASKINTR:
+		case HDIO_GET_UNMASKINTR:
 			return write_fs_long(arg, drive->unmask);
 
-                case HDIO_GET_DMA:
+		case HDIO_GET_DMA:
 			return write_fs_long(arg, drive->using_dma);
 
-                case HDIO_GET_CHIPSET:
+		case HDIO_GET_CHIPSET:
 			return write_fs_long(arg, drive->chipset);
 
-                case HDIO_GET_MULTCOUNT:
+		case HDIO_GET_MULTCOUNT:
 			return write_fs_long(arg, drive->mult_count);
 
 		case HDIO_GET_IDENTITY:
@@ -1858,6 +1866,10 @@
 			cli();
 			switch (cmd) {
 				case HDIO_SET_DMA:
+					if (!(HWIF(drive)->dmaproc)) {
+						restore_flags(flags);
+						return -EPERM;
+					}
 					drive->using_dma = arg;
 					break;
 				case HDIO_SET_KEEPSETTINGS:
@@ -2046,7 +2058,7 @@
 		drive->present = 1;
 		drive->cyl     = drive->bios_cyl  = id->cyls;
 		drive->head    = drive->bios_head = id->heads;
-		drive->sect    = drive->bios_sect = id->sectors; 
+		drive->sect    = drive->bios_sect = id->sectors;
 	}
 	/* Handle logical geometry translation by the drive */
 	if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads
@@ -2055,7 +2067,7 @@
 		/*
 		 * Extract the physical drive geometry for our use.
 		 * Note that we purposely do *not* update the bios info.
-		 * This way, programs that use it (like fdisk) will 
+		 * This way, programs that use it (like fdisk) will
 		 * still have the same logical view as the BIOS does,
 		 * which keeps the partition table from being screwed.
 		 *
@@ -2079,7 +2091,7 @@
 	if ((!drive->head || drive->head > 16) && id->heads && id->heads <= 16) {
 		drive->cyl  = id->cyls;
 		drive->head = id->heads;
-		drive->sect = id->sectors; 
+		drive->sect = id->sectors;
 	}
 	/* Correct the number of cyls if the bios value is too small */
 	if (drive->sect == drive->bios_sect && drive->head == drive->bios_head) {
@@ -2107,6 +2119,9 @@
 			printk(", DMA");
 	}
 	printk("\n");
+#ifdef SUPPORT_CMD640
+	cmd640_tune_drive(drive);	/* but can we tune a fish? */
+#endif
 }
 
 /*
@@ -2336,8 +2351,8 @@
  * The code enables the secondary IDE controller and the PIO4 (3?) timings on
  * the primary (EIDE). You may probably have to enable the 32-bit support to
  * get the full speed. You better get the disk interrupts disabled ( hdparm -u0
- * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my 
- * filesystem  corrupted with -u1, but under heavy disk load only :-)  
+ * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my
+ * filesystem  corrupted with -u1, but under heavy disk load only :-)
  *
  * From: mlord@bnr.ca -- this chipset is now forced to use the "serialize" feature,
  * which hopefully will make it more reliable to use.. maybe it has the same bugs
@@ -2417,59 +2432,13 @@
 }
 #endif /* SUPPORT_QD6580 */
 
-#if SUPPORT_CMD640
-/*
- * ??? fixme: 
- */
-byte read_cmd640_vlb (byte port, byte reg)
-{
-	byte val;
-
-	unsigned long flags;
-	save_flags(flags);
-	cli();
-	outw(reg, port);
-	val = inb(port+4);
-	restore_flags(flags);
-	return val;
-}
-
-void write_cmd640_vlb (byte port, byte reg, byte val)
-{
-	unsigned long flags;
-	save_flags(flags);
-	cli();
-	outw(reg, port);
-	outw(val, port+4);
-	restore_flags(flags);
-}
-
-void init_cmd640_vlb (void)
-{
-	byte reg;
-	unsigned short port = 0x178;
-
-	serialized = 1;
- 	printk("ide: buggy CMD640 interface: serialized, ");
-	reg = read_cmd640_vlb(port, 0x50);
-	if (reg == 0xff || (reg & 0x90) != 0x90) {
-#if TRY_CMD640_VLB_AT_0x78
-		port = 0x78;
-		reg = read_cmd640_vlb(port, 0x50);
-		if (reg == 0xff || (reg & 0x90) != 0x90)
+#ifdef SUPPORT_UMC8672
+#include "umc8672.c"	/* until we tidy up the interface some more */
 #endif
-		{
-			disallow_unmask = 1;
-			printk("(probe failed) disabled unmasking\n");
-			return;
-		}
-	}
-	write_cmd640_vlb(port, 0x51, read_cmd640_vlb(port, 0x51)|0xc8);
-	write_cmd640_vlb(port, 0x57, read_cmd640_vlb(port, 0x57)|0x0c);
-	printk("disabled read-ahead, enabled secondary\n");
 
-}
-#endif /* SUPPORT_CMD640 */
+#ifdef SUPPORT_CMD640
+#include "cmd640.c"	/* until we tidy up the interface some more */
+#endif
 
 /*
  * stridx() returns the offset of c within s,
@@ -2488,7 +2457,7 @@
  * 2. if the remainder matches one of the supplied keywords,
  *     the index (1 based) of the keyword is negated and returned.
  * 3. if the remainder is a series of no more than max_vals numbers
- *     separated by commas, the numbers are saved in vals[] and a 
+ *     separated by commas, the numbers are saved in vals[] and a
  *     count of how many were saved is returned.  Base10 is assumed,
  *     and base16 is allowed when prefixed with "0x".
  * 4. otherwise, zero is returned.
@@ -2511,7 +2480,7 @@
 		/*
 		 * Look for a series of no more than "max_vals"
 		 * numeric values separated by commas, in base10,
-		 * or base16 when prefixed with "0x".  
+		 * or base16 when prefixed with "0x".
 		 * Return a count of how many were found.
 		 */
 		for (n = 0; (i = stridx(decimal, *s)) >= 0;) {
@@ -2621,11 +2590,18 @@
 	 * Look for interface options:  "idex="
 	 */
 	if (s[0] == 'i' && s[1] == 'd' && s[2] == 'e' && s[3] >= '0' && s[3] <= max_hwif) {
-		const char *ide_words[] = {"noprobe", "serialize", "dtc2278", "ht6560b", "cmd640_vlb", "qd6580", NULL};
+		const char *ide_words[] = {"noprobe", "serialize", "dtc2278", "ht6560b",
+					"cmd640_vlb", "qd6580", "umc8672", NULL};
 		hw = s[3] - '0';
 		hwif = &ide_hwifs[hw];
 
 		switch (match_parm(&s[4], ide_words, vals, 3)) {
+#if SUPPORT_UMC8672
+			case -7: /* "umc8672" */
+				if (hw != 0) goto bad_hwif;
+				init_umc8672();
+				goto done;
+#endif /* SUPPORT_UMC8672 */
 #if SUPPORT_QD6580
 			case -6: /* "qd6580" */
 				if (hw != 0) goto bad_hwif;
@@ -2635,8 +2611,7 @@
 #if SUPPORT_CMD640
 			case -5: /* "cmd640_vlb" */
 				if (hw > 1) goto bad_hwif;
-				init_cmd640_vlb();
-				goto do_serialize; /* not necessary once we implement the above */
+				cmd640_vlb = 1;
 				break;
 #endif /* SUPPORT_CMD640 */
 #if SUPPORT_HT6560B
@@ -2709,7 +2684,7 @@
 
 	drive->cyl  = drive->bios_cyl  = drive->id->cyls;
 	drive->head = drive->bios_head = drive->id->heads;
-	drive->sect = drive->bios_sect = drive->id->sectors; 
+	drive->sect = drive->bios_sect = drive->id->sectors;
 	drive->special.b.set_geometry = 1;
 
 	tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63;
@@ -2745,7 +2720,7 @@
  * drives in the system -- the ones reflected as drive 1 or 2.  The first
  * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
  * nibble.  This will be either a 4 bit drive type or 0xf indicating use byte
- * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value 
+ * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value
  * means we have an AT controller hard disk for that drive.
  *
  * Of course, there is no guarantee that either drive is actually on the
@@ -2905,45 +2880,6 @@
 }
 #endif /* SUPPORT_RZ1000 */
 
-#if SUPPORT_CMD640
-void init_cmd640 (byte bus, byte fn)
-{
-	int rc;
-	unsigned char reg;
-
-	serialized = 1;
-	printk("ide: buggy CMD640 interface: ");
-
-#if 0	/* funny.. the cmd640b I tried this on claimed to not be enabled.. */
-	unsigned short sreg;
-	if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &sreg))) {
-		ide_pci_access_error (rc);
-	} else if (!(sreg & 1)) {
-		printk("not enabled\n");
-	} else {
-
-	/*
-	 * The first part is undocumented magic from the DOS driver.
-	 * According to the datasheet, there is no port 0x5b on the cmd640.
-	 */
-	(void) pcibios_write_config_byte(bus, fn, 0x5b, 0xbd);
-	if (pcibios_write_config_byte(bus, fn, 0x5b, 0xbd) != 0xbd)
-		printk("init_cmd640: huh? 0x5b read back wrong\n");
-	(void) pcibios_write_config_byte(bus, fn, 0x5b, 0);
-#endif /* 0 */
-	/*
-	 * The rest is from the cmd640b datasheet.
-	 */
-	if ((rc = pcibios_read_config_byte(bus, fn, 0x51, &reg))
-	 || (rc =  pcibios_write_config_byte(bus, fn, 0x51, reg | 0xc0)) /* 0xc8 to enable 2nd i/f */
-	 || (rc =  pcibios_read_config_byte(bus, fn, 0x57, &reg))
-	 || (rc =  pcibios_write_config_byte(bus, fn, 0x57, reg | 0x0c)))
-		buggy_interface_fallback (rc);
-	else
-		printk("serialized, disabled read-ahead\n");
-}
-#endif /* SUPPORT_CMD640 */
-
 typedef void (ide_pci_init_proc_t)(byte, byte);
 
 /*
@@ -2966,7 +2902,7 @@
 
 /*
  * ide_init_pci() finds/initializes "known" PCI IDE interfaces
- * 
+ *
  * This routine should ideally be using pcibios_find_class() to find
  * all IDE interfaces, but that function causes some systems to "go weird".
  */
@@ -2975,9 +2911,6 @@
 #if SUPPORT_RZ1000
 	ide_probe_pci (PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, &init_rz1000, 0);
 #endif
-#if SUPPORT_CMD640
-	ide_probe_pci (PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, &init_cmd640, 0);
-#endif
 #ifdef CONFIG_BLK_DEV_TRITON
 	/*
 	 * Apparently the BIOS32 services on Intel motherboards are buggy,
@@ -3008,6 +2941,9 @@
 	if (pcibios_present())
 		ide_init_pci ();
 #endif /* CONFIG_PCI */
+#ifdef SUPPORT_CMD640
+	ide_probe_for_cmd640x();
+#endif
 
 	/*
 	 * Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
diff -u --recursive --new-file v1.3.42/linux/drivers/block/ide.h linux/drivers/block/ide.h
--- v1.3.42/linux/drivers/block/ide.h	Wed Nov  8 07:11:30 1995
+++ linux/drivers/block/ide.h	Tue Nov 21 12:09:33 1995
@@ -40,6 +40,9 @@
 #ifndef SUPPORT_CMD640			/* 1 to support CMD640 chipset */
 #define SUPPORT_CMD640		1	/* 0 to reduce kernel size */
 #endif
+#ifndef SUPPORT_UMC8672			/* 1 to support UMC8672 chipset */
+#define SUPPORT_UMC8672		1	/* 0 to reduce kernel size */
+#endif
 #ifndef SUPPORT_HT6560B			/* 1 to support HT6560B chipset */
 #define SUPPORT_HT6560B		1	/* 0 to reduce kernel size */
 #endif
diff -u --recursive --new-file v1.3.42/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v1.3.42/linux/drivers/block/ll_rw_blk.c	Fri Nov 17 08:42:24 1995
+++ linux/drivers/block/ll_rw_blk.c	Tue Nov 21 08:34:54 1995
@@ -229,6 +229,19 @@
 	else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
 }
 
+static inline void drive_stat_acct(int cmd, unsigned long nr_sectors, short disk_index)
+{
+	kstat.dk_drive[disk_index]++;
+	if (cmd == READ || cmd == READA) {
+		kstat.dk_drive_rio[disk_index]++;
+		kstat.dk_drive_rblk[disk_index] += nr_sectors;
+	}
+	else if (cmd == WRITE || cmd == WRITEA) {
+		kstat.dk_drive_wio[disk_index]++;
+		kstat.dk_drive_wblk[disk_index] += nr_sectors;
+	}
+}
+
 /*
  * add-request adds a request to the linked list.
  * It disables interrupts so that it can muck with the
@@ -243,16 +256,16 @@
 		case SCSI_DISK_MAJOR:
 			disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4;
 			if (disk_index < 4)
-				kstat.dk_drive[disk_index]++;
+				drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
 			break;
 		case IDE0_MAJOR:	/* same as HD_MAJOR */
 		case XT_DISK_MAJOR:
 			disk_index = (MINOR(req->rq_dev) & 0x0040) >> 6;
-			kstat.dk_drive[disk_index]++;
+			drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
 			break;
 		case IDE1_MAJOR:
 			disk_index = ((MINOR(req->rq_dev) & 0x0040) >> 6) + 2;
-			kstat.dk_drive[disk_index]++;
+			drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
 		default:
 			break;
 	}
diff -u --recursive --new-file v1.3.42/linux/drivers/block/triton.c linux/drivers/block/triton.c
--- v1.3.42/linux/drivers/block/triton.c	Mon Oct 16 18:38:22 1995
+++ linux/drivers/block/triton.c	Fri Nov 17 08:33:07 1995
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/triton.c	Version 1.02  Oct 13, 1995
+ *  linux/drivers/block/triton.c	Version 1.03  Nov 16, 1995
  *
  *  Copyright (c) 1995  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
@@ -64,8 +64,12 @@
  *	  the observation that WRITEs work most of the time, depending on
  *	  cache-buffer occupancy, but multi-sector reads seldom work.
  *
- * Drives like the AC31000H could likely be made to work if all DMA were done
- * one sector at a time, but that would likely negate any advantage over PIO.
+ * Testing was done with a Gigabyte GA-586 ATE system and the following drive:
+ * (Uwe Bonnes - bon@elektron.ikp.physik.th-darmstadt.de)
+ *
+ *   Western Digital AC31600H (1.6Gig w/128kB buffer), DMA mode2, PIO mode4.
+ *	- much better than its 1Gig cousin, this drive is reported to work
+ *	  very well with DMA (7.3MB/sec).
  *
  * If you have any drive models to add, email your results to:  mlord@bnr.ca
  * Keep an eye on /var/adm/messages for "DMA disabled" messages.
diff -u --recursive --new-file v1.3.42/linux/drivers/block/umc8672.c linux/drivers/block/umc8672.c
--- v1.3.42/linux/drivers/block/umc8672.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/block/umc8672.c	Fri Nov 17 08:33:07 1995
@@ -0,0 +1,108 @@
+/*
+ *  linux/drivers/block/umc8672.c	Version 0.01  Nov 16, 1995
+ *
+ *  Copyright (C) 1995  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Principal Author/Maintainer:  PODIEN@hml2.atlas.de (Wolfram Podien)
+ *
+ *  This file provides support for the advanced features
+ *  of the UMC 8672 IDE interface.
+ *
+ *  Version 0.01	Initial version, hacked out of ide.c,
+ *			and #include'd rather than compiled separately.
+ *			This will get cleaned up in a subsequent release.
+ */
+
+/*
+ * VLB Controller Support from 
+ * Wolfram Podien
+ * Rohoefe 3
+ * D28832 Achim
+ * Germany
+ *
+ * To enable UMC8672 support there must a lilo line like
+ * append="hd=umc8672"...
+ * To set the speed according to the abilities of the hardware there must be a
+ * line like
+ * #define UMC_DRIVE0 11
+ * in the beginning of the driver, which sets the speed of drive 0 to 11 (there
+ * are some lines present). 0 - 11 are allowed speed values. These values are
+ * the results from the DOS speed test programm supplied from UMC. 11 is the 
+ * highest speed (about PIO mode 3)
+ */
+
+/*
+ * The speeds will eventually become selectable using hdparm via ioctl's,
+ * but for now they are coded here:
+ */
+#define UMC_DRIVE0      11              /* DOS messured drive Speeds */
+#define UMC_DRIVE1      11              /* 0 - 11 allowed */
+#define UMC_DRIVE2      11              /* 11 = Highest Speed */
+#define UMC_DRIVE3      11              /* In case of crash reduce speed */
+
+void out_umc (char port,char wert)
+{
+	outb_p (port,0x108);
+	outb_p (wert,0x109);
+}
+
+byte in_umc (char port)
+{
+	outb_p (port,0x108);
+	return inb_p (0x109);
+}
+
+void init_umc8672(void)
+{
+	int i,tmp;
+	int speed [4];
+/*      0    1    2    3    4    5    6    7    8    9    10   11      */
+	char speedtab [3][12] = {
+	{0xf ,0xb ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
+	{0x3 ,0x2 ,0x2 ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
+	{0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
+
+	cli ();
+	outb_p (0x5A,0x108); /* enable umc */
+	if (in_umc (0xd5) != 0xa0)
+	{
+		sti ();
+		printk ("UMC8672 not found\n");
+		return;  
+	}
+	speed[0] = UMC_DRIVE0;
+	speed[1] = UMC_DRIVE1;
+	speed[2] = UMC_DRIVE2;
+	speed[3] = UMC_DRIVE3;
+	for (i = 0;i < 4;i++)
+	{
+		if ((speed[i] < 0) || (speed[i] > 11))
+		{
+			sti ();
+			printk ("UMC 8672 drive speed out of range. Drive %d Speed %d\n",
+				i, speed[i]);
+			printk ("UMC support aborted\n");
+			return; 
+		}
+	}
+	out_umc (0xd7,(speedtab[0][speed[2]] | (speedtab[0][speed[3]]<<4)));
+	out_umc (0xd6,(speedtab[0][speed[0]] | (speedtab[0][speed[1]]<<4)));
+	tmp = 0;
+	for (i = 3; i >= 0; i--)
+	{
+		tmp = (tmp << 2) | speedtab[1][speed[i]];
+	}
+	out_umc (0xdc,tmp);
+	for (i = 0;i < 4; i++)
+	{
+		out_umc (0xd0+i,speedtab[2][speed[i]]);
+		out_umc (0xd8+i,speedtab[2][speed[i]]);
+	}
+	outb_p (0xa5,0x108); /* disable umc */
+	sti ();
+	printk ("Speeds for UMC8672 \n");
+	for (i = 0;i < 4;i++)
+		 printk ("Drive %d speed %d\n",i,speed[i]);
+}
diff -u --recursive --new-file v1.3.42/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v1.3.42/linux/drivers/cdrom/mcd.c	Fri Nov 17 08:42:25 1995
+++ linux/drivers/cdrom/mcd.c	Tue Nov 21 10:14:17 1995
@@ -62,13 +62,8 @@
 
 */
 
-
 #include <linux/module.h>
 
-#ifdef MODULE
-#define mcd_init init_module
-#endif
-
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
@@ -88,6 +83,7 @@
 
 #define MAJOR_NR MITSUMI_CDROM_MAJOR
 #include <linux/blk.h>
+
 #define mcd_port mcd    /* for compatible parameter passing with "insmod" */
 #include <linux/mcd.h>
 
@@ -132,15 +128,10 @@
 #endif
 /* #define DOUBLE_QUICK_ONLY */
 
-#if LINUX_VERSION_CODE < 66338
-    #define CURRENT_VALID \
-    (CURRENT && MAJOR(CURRENT -> dev) == MAJOR_NR && CURRENT -> cmd == READ \
-    && CURRENT -> sector != -1)
-#else
-    #define CURRENT_VALID \
-    (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
-    && CURRENT -> sector != -1)
-#endif
+#define CURRENT_VALID \
+(CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
+&& CURRENT -> sector != -1)
+
 #define MFL_STATUSorDATA (MFL_STATUS | MFL_DATA)
 #define MCD_BUF_SIZ 16
 static volatile int mcd_transfer_is_active;
@@ -213,11 +204,7 @@
 
  
 static int
-#if LINUX_VERSION_CODE < 66338
-check_mcd_change(dev_t full_dev)
-#else
 check_mcd_change(kdev_t full_dev)
-#endif
 {
    int retval, target;
 
@@ -1173,8 +1160,7 @@
  * Test for presence of drive and initialize it.  Called at boot time.
  */
 
-int
-mcd_init(void)
+int mcd_init(void)
 {
 	int count;
 	unsigned char result[3];
@@ -1619,6 +1605,11 @@
 }
 
 #ifdef MODULE
+int init_module(void)
+{
+	return mcd_init();
+}
+
 void cleanup_module(void)
 { if (MOD_IN_USE)
      { printk("mcd module in use - can't remove it.\n");
diff -u --recursive --new-file v1.3.42/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- v1.3.42/linux/drivers/cdrom/mcdx.c	Fri Nov 17 08:42:25 1995
+++ linux/drivers/cdrom/mcdx.c	Tue Nov 21 10:15:15 1995
@@ -1,7 +1,7 @@
 /*
  * The Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.3
+ * VERSION: 1.5
  * 
  * 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
@@ -34,9 +34,10 @@
 
 #if RCS
 static const char *mcdx_c_version
-		= "mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp";
+		= "mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp";
 #endif
 
+#include <linux/version.h>
 #include <linux/module.h>
 
 #include <linux/errno.h>
@@ -55,19 +56,6 @@
 
 
 #include <linux/major.h>
-
-/* old kernel (doesn't know about MCDX) */
-#ifndef MITSUMI_X_CDROM_MAJOR
-#define MITSUMI_X_CDROM_MAJOR 20
-#define DEVICE_NAME "mcdx"
-
-/* #define DEVICE_INTR do_mcdx */
-#define DEVICE_REQUEST do_mcdx_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-#endif
-
 #define MAJOR_NR MITSUMI_X_CDROM_MAJOR
 #include <linux/blk.h>
 
@@ -191,18 +179,9 @@
 	changed elsewhere. */
 
 /* declared in blk.h */
-#if LINUX_VERSION_CODE < 66338
-unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end);
-#else
 int mcdx_init(void);
-#endif
 void do_mcdx_request(void);
-
-#if LINUX_VERSION_CODE < 66338
-int check_mcdx_media_change(dev_t);
-#else
 int check_mcdx_media_change(kdev_t);
-#endif
 
 /* already declared in init/main */
 void mcdx_setup(char *, int *);
@@ -561,36 +540,20 @@
 
 	TRACE((REQUEST, "do_request()\n"));
 
-#if LINUX_VERSION_CODE < 66338
-	if ((CURRENT == NULL) || (CURRENT->dev < 0))  {
-#else
 	if ((CURRENT == NULL) || (CURRENT->rq_status == RQ_INACTIVE))  {
-#endif
 		TRACE((REQUEST, "do_request() done\n"));
 		return;
 	}
 
-#if LINUX_VERSION_CODE < 66338
-    stuffp = mcdx_stuffp[MINOR(CURRENT->dev)];
-#else
     stuffp = mcdx_stuffp[MINOR(CURRENT->rq_dev)];
-#endif
 	TRACE((REQUEST, "do_request() stuffp = %p\n", stuffp));
 
     INIT_REQUEST;
-#if LINUX_VERSION_CODE < 66338
-    dev = MINOR(CURRENT->dev);
-#else
     dev = MINOR(CURRENT->rq_dev);
-#endif
 
 	if ((dev < 0) || (dev >= MCDX_NDRIVES) || (!stuffp->present)) {
-#if LINUX_VERSION_CODE < 66338
-		WARN(("do_request(): bad device: 0x%04x\n", CURRENT->dev));
-#else
 		WARN(("do_request(): bad device: %s\n", 
             kdevname(CURRENT->rq_dev)));
-#endif
 		end_request(0);
 		goto again;
     }
@@ -817,24 +780,15 @@
     return;
 }
 
-#if LINUX_VERSION_CODE < 66338
-int check_mcdx_media_change(dev_t full_dev)
-#else
 int check_mcdx_media_change(kdev_t full_dev)
-#endif
 /*	Return: 1 if media changed since last call to 
 			  this function
 			0 else
 	Setting flag to 0 resets the changed state. */
 
 {
-#if LINUX_VERSION_CODE < 66338
-    INFO(("check_mcdx_media_change called for device %x\n",
-	  full_dev));
-#else
     INFO(("check_mcdx_media_change called for device %s\n",
 	  kdevname(full_dev)));
-#endif
     return 0;
 }
 
@@ -1021,11 +975,7 @@
 	int i;
 	int drives = 0;
 
-#if LINUX_VERSION_CODE < 66338
-	mcdx_init(0, 0);
-#else
 	mcdx_init();
-#endif
 	for (i = 0; i < MCDX_NDRIVES; i++)  {
 		if (mcdx_stuffp[i]) {
 		TRACE((INIT, "init_module() drive %d stuff @ %p\n",
@@ -1097,18 +1047,14 @@
 }
 
 
-#if LINUX_VERSION_CODE < 66338
-unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end)
-#else
 int mcdx_init(void)
-#endif
 {
 	int drive;
 
-	WARN(("Version 1.3 "
-			"mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp\n"));
-	INFO((": Version 1.3 "
-			"mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp\n"));
+	WARN(("Version 1.5 "
+			"mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp\n"));
+	INFO((": Version 1.5 "
+			"mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp\n"));
 
 	/* zero the pointer array */
 	for (drive = 0; drive < MCDX_NDRIVES; drive++)
@@ -1124,18 +1070,12 @@
 		
 		TRACE((INIT, "init() try drive %d\n", drive));
 
-#if defined(MODULE) || LINUX_VERSION_CODE > 66338
         TRACE((INIT, "kmalloc space for stuffpt's\n"));
 		TRACE((MALLOC, "init() malloc %d bytes\n", size));
 		if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
 			WARN(("init() malloc failed\n"));
 			break; 
 		}
-#else
-        TRACE((INIT, "adjust mem_start\n"));
-        stuffp = (struct s_drive_stuff *) mem_start;
-        mem_start += size;
-#endif
 
 		TRACE((INIT, "init() got %d bytes for drive stuff @ %p\n", sizeof(*stuffp), stuffp));
 
@@ -1267,11 +1207,7 @@
 		TRACE((INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp));
 	}
 
-#if MODULE || LINUX_VERSION_CODE > 66338
 	return 0;
-#else
-	return mem_start;
-#endif
 }
 
 
diff -u --recursive --new-file v1.3.42/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v1.3.42/linux/drivers/cdrom/sbpcd.c	Thu Nov  9 11:23:48 1995
+++ linux/drivers/cdrom/sbpcd.c	Sun Nov 19 18:21:44 1995
@@ -12,7 +12,26 @@
  *            Not for Sanyo drives (but sjcd is there...).
  *            Not for any other Funai drives than E2550UA (="CD200" with "F").
  *
- *  NOTE:     This is release 3.9.
+ *  NOTE:     This is release 4.0
+ *
+ *   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
+ *
+ *                  If you change this software, you should mail a .diff
+ *                  file with some description lines to emoenke@gwdg.de.
+ *                  I want to know about it.
+ *
+ *                  If you are the editor of a Linux CD, you should
+ *                  enable sbpcd.c within your boot floppy kernel and
+ *                  send me one of your CDs for free.
+ *
+ *   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.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   (for example /usr/src/linux/COPYING); if not, write to the Free
+ *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  VERSION HISTORY
  *
@@ -222,6 +241,13 @@
  *       Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
  *       the config_spea() routine into their drivers. ;-)
  *
+ *  4.0  No "big step" - normal version increment.
+ *       Adapted the benefits from 1.3.33.
+ *       Fiddled with CDROMREADAUDIO flaws.
+ *       Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
+ *       seems not to support it).
+ *       Fulfilled "read audio" for CD200 drives, with help of Pete Heist
+ *       (heistp@rpi.edu).
  *
  *  TODO
  *
@@ -236,25 +262,6 @@
  *     the "push" towards load-free wait loops, and for the extensive mail
  *     thread which brought additional hints and bug fixes.
  *
- *   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
- *
- *                  If you change this software, you should mail a .diff
- *                  file with some description lines to emoenke@gwdg.de.
- *                  I want to know about it.
- *
- *                  If you are the editor of a Linux CD, you should
- *                  enable sbpcd.c within your boot floppy kernel and
- *                  send me one of your CDs for free.
- *
- *   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.
- *
- *   You should have received a copy of the GNU General Public License
- *   (for example /usr/src/linux/COPYING); if not, write to the Free
- *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef SBPCD_ISSUE
@@ -294,7 +301,7 @@
 
 #include <linux/blk.h>
 
-#define VERSION "v3.9 Eberhard Moenkeberg <emoenke@gwdg.de>"
+#define VERSION "v4.0 Eberhard Moenkeberg <emoenke@gwdg.de>"
 
 /*==========================================================================*/
 /*
@@ -468,6 +475,7 @@
 static int sbpcd_debug = ((1<<DBG_INF) |
 			  (1<<DBG_TOC) |
 			  (1<<DBG_MUL) |
+			  (1<<DBG_AUD) |
 			  (1<<DBG_UPC));
 #endif DISTRIBUTION
 
@@ -522,9 +530,9 @@
 #define SBP_BUFFER_FRAMES 8 /* driver's own read_ahead, data mode */
 /*==========================================================================*/
 
-static u_char family0[]="MATSHITA"; /* MKE CR-52x */
-static u_char family1[]="CR-56";    /* MKE CR-56x */
-static u_char family2[]="CD200";    /* MKE CD200 */
+static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
+static u_char family1[]="CR-56";    /* MKE CR-562, CR-563 */
+static u_char family2[]="CD200";    /* MKE CD200, Funai CD200F */
 static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
 static u_char familyT[]="CD-55";    /* TEAC CD-55A */
 
@@ -756,17 +764,6 @@
  */
 static void sbp_sleep(u_int time)
 {
-#ifndef MODULE
-	if (current == task[0]) 
-	{
-		del_timer(&delay_timer);
-		delay_timer.expires=jiffies+time;
-		timed_out_delay=0;
-		add_timer(&delay_timer);
-		while (!timed_out_delay) ;
-		return;
-	}
-#endif MODULE
 	sti();
 	current->state = TASK_INTERRUPTIBLE;
 	current->timeout = jiffies + time;
@@ -904,25 +901,14 @@
 {
 	int i;
 	
-#ifdef MODULE
 	sbp_sleep(15*HZ/10);
 	for (i=maxtim_data;i!=0;i--) inb(CDi_status);
-#else
-	if (current == task[0])
-		for (i=maxtim02;i!=0;i--) inb(CDi_status);
-	else 
-	{
-		sbp_sleep(15*HZ/10);
-		for (i=maxtim_data;i!=0;i--) inb(CDi_status);
-	}
-#endif MODULE
 }
 /*==========================================================================*/
 static int CDi_stat_loop(void)
 {
 	int i,j;
 	
-#ifdef MODULE
 	for(timeout = jiffies + 10*HZ, i=maxtim_data; timeout > jiffies; )
 	{
 		for ( ;i!=0;i--)
@@ -935,29 +921,6 @@
 		sbp_sleep(1);
 		i = 1;
 	}
-#else
-	if (current == task[0])
-		for(i=maxtim16;i!=0;i--)
-		{
-			j=inb(CDi_status);
-			if (!(j&s_not_data_ready)) return (j);
-			if (!(j&s_not_result_ready)) return (j);
-			if (fam0L_drive) if (j&s_attention) return (j);
-		}
-	else
-		for(timeout = jiffies + 10*HZ, i=maxtim_data; timeout > jiffies; )
-		{
-			for ( ;i!=0;i--)
-			{
-				j=inb(CDi_status);
-				if (!(j&s_not_data_ready)) return (j);
-				if (!(j&s_not_result_ready)) return (j);
-				if (fam0L_drive) if (j&s_attention) return (j);
-			}
-			sbp_sleep(1);
-			i = 1;
-		}
-#endif MODULE
 	msg(DBG_LCS,"CDi_stat_loop failed\n");
 	return (-1);
 }
@@ -998,43 +961,21 @@
 	int i,j,st=0;
 	u_long timeout;
 	
-#ifdef MODULE
-	if (0)
-#else
-	if (current == task[0])
-#endif MODULE
-		for (i=0;i<response_count;i++)
+	for (i=0,timeout=jiffies+HZ;i<response_count;i++) 
+	{
+		for (j=maxtim_data; ; )
 		{
-			for (j=maxtim_8;j!=0;j--)
+			for ( ;j!=0;j-- )
 			{
 				st=inb(CDi_status);
 				if (!(st&s_not_result_ready)) break;
 			}
-			if (j==0) 
-			{
-				msg(DBG_SEQ,"ResponseInfo: not_result_ready (got %d of %d bytes).\n", i, response_count);
-				break;
-			}
-			infobuf[i]=inb(CDi_info);
-		}
-	else 
-	{
-		for (i=0,timeout=jiffies+HZ;i<response_count;i++) 
-		{
-			for (j=maxtim_data; ; )
-			{
-				for ( ;j!=0;j-- )
-				{
-					st=inb(CDi_status);
-					if (!(st&s_not_result_ready)) break;
-				}
-				if ((j!=0)||(timeout<=jiffies)) break;
-				sbp_sleep(1);
-				j = 1;
-			}
-			if (timeout<=jiffies) break;
-			infobuf[i]=inb(CDi_info);
+			if ((j!=0)||(timeout<=jiffies)) break;
+			sbp_sleep(1);
+			j = 1;
 		}
+		if (timeout<=jiffies) break;
+		infobuf[i]=inb(CDi_info);
 	}
 #if 000
 	while (!(inb(CDi_status)&s_not_result_ready))
@@ -1156,40 +1097,22 @@
 	
 	msg(DBG_STA,"doing ResponseStatus...\n");
 	if (famT_drive) return (get_state_T());
-#ifdef MODULE
-	if (0)
-#else
-	if (current == task[0])
-#endif MODULE
+	if (flags_cmd_out & f_respo3) timeout = jiffies;
+	else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
+	else timeout = jiffies + 4*HZ;
+	j=maxtim_8;
+	do
 	{
-		if (flags_cmd_out & f_respo3) j = maxtim_8;
-		else if (flags_cmd_out&f_respo2) j=maxtim16;
-		else j=maxtim04;
-		for (;j!=0;j--)
-		{
+		for ( ;j!=0;j--)
+		{ 
 			i=inb(CDi_status);
 			if (!(i&s_not_result_ready)) break;
 		}
+		if ((j!=0)||(timeout<jiffies)) break;
+		sbp_sleep(1);
+		j = 1;
 	}
-	else
-	{
-		if (flags_cmd_out & f_respo3) timeout = jiffies;
-		else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
-		else timeout = jiffies + 4*HZ;
-		j=maxtim_8;
-		do
-		{
-			for ( ;j!=0;j--)
-			{ 
-				i=inb(CDi_status);
-				if (!(i&s_not_result_ready)) break;
-			}
-			if ((j!=0)||(timeout<jiffies)) break;
-			sbp_sleep(1);
-			j = 1;
-		}
-		while (1);
-	}
+	while (1);
 	if (j==0) 
 	{
 		if ((flags_cmd_out & f_respo3) == 0)
@@ -1200,15 +1123,8 @@
 	i=inb(CDi_info);
 	msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
 	EvaluateStatus(i);
-#if 0
-	if (fam0_drive)
-#endif
-		msg(DBG_STA,"status_bits=%02X, i=%02X\n",D_S[d].status_bits,i);
-#if 1
+	msg(DBG_STA,"status_bits=%02X, i=%02X\n",D_S[d].status_bits,i);
 	return (D_S[d].status_bits);
-#else
-	return (i);
-#endif 0
 }
 /*==========================================================================*/
 static void cc_ReadStatus(void)
@@ -2463,6 +2379,7 @@
 {
 	int i, j;
 	
+	if (fam2_drive) return (0); /* some firmware lacks this command */
 	if (famL_drive) return (0); /* some firmware lacks this command */
 	if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
 	D_S[d].diskstate_flags &= ~cd_size_bit;
@@ -2475,12 +2392,14 @@
 			response_count=5;
 			flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
 		}
+#if 00
 		else if (fam2_drive)
 		{
 			drvcmd[0]=CMD2_CAPACITY;
 			response_count=8;
 			flags_cmd_out=f_putcmd;
 		}
+#endif
 		else if (fam0_drive)
 		{
 			drvcmd[0]=CMD0_CAPACITY;
@@ -2495,7 +2414,9 @@
 	if (j==0) return (i);
 	if (fam1_drive) D_S[d].CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
 	else if (fam0_drive) D_S[d].CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
+#if 00
 	else if (fam2_drive) D_S[d].CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
+#endif
 	D_S[d].diskstate_flags |= cd_size_bit;
 	msg(DBG_000,"cc_ReadCapacity: %d frames.\n", D_S[d].CDsize_frm);
 	return (0);
@@ -2589,6 +2510,7 @@
 		if (i<0) return (i);
 		D_S[d].size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
 		D_S[d].size_blk=msf2blk(D_S[d].size_msf);
+		D_S[d].CDsize_frm=D_S[d].size_blk+1;
 	}
 	else if (famT_drive)
 	{
@@ -3032,7 +2954,7 @@
 	response_count=9;
 	flags_cmd_out=f_putcmd;
 	i=cmd_out();
-	if (i<0) msg(DBG_INI,"CMD0_READERR returns %d (ok anyway).\n",i);
+	if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i);
 	/* read drive version */
 	clr_cmdbuf();
 	for (i=0;i<12;i++) infobuf[i]=0;
@@ -3270,9 +3192,15 @@
 		}
 		else if (fam2_drive)
 		{
-			msg(DBG_INF,"new drive CD200 (%s)detected.\n", D_S[d].firmware_version);
-			msg(DBG_INF,"CD200 is not fully supported yet - CD200F should work.\n");
-			if ((j!=1)&&(j!=101)&&(j!=35)) ask_mail(); /* unknown version at time */
+			if (D_S[d].drive_model[5]=='F')
+			{
+				if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210)) ask_mail(); /* unknown version at time */
+			}
+			else
+			{
+				msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n");
+				if ((j!=101)&&(j!=35)) ask_mail(); /* unknown version at time */
+			}
 		}
 	}
 	msg(DBG_LCS,"drive type %02X\n",D_S[d].drv_type);
@@ -4090,10 +4018,7 @@
 		
 	case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
 		msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
-#ifdef MODULE
-		if (D_S[d].sbp_audsiz>0)
-			vfree(D_S[d].aud_buf);
-#endif MODULE
+		if (D_S[d].sbp_audsiz>0) vfree(D_S[d].aud_buf);
 		D_S[d].aud_buf=NULL;
 		D_S[d].sbp_audsiz=arg;
 		if (D_S[d].sbp_audsiz>0)
@@ -4123,7 +4048,6 @@
 		msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
 		if (fam0_drive) return (-EINVAL);
 		if (famL_drive) return (-EINVAL);
-		if (fam2_drive) return (-EINVAL);
 		if (famT_drive) return (-EINVAL);
 		if (D_S[d].aud_buf==NULL) return (-EINVAL);
 		i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
@@ -4139,8 +4063,10 @@
 		else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
 			block=read_audio.addr.lba;
 		else return (-EINVAL);
+#if 000
 		i=cc_SetSpeed(speed_150,0,0);
 		if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
+#endif
 		msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
 		    block, blk2msf(block));
 		msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
@@ -4158,6 +4084,7 @@
 				flags_cmd_out |= f_respo3;
 				cc_ReadStatus();
 				if (sbp_status() != 0) break;
+				if (st_check) cc_ReadError();
 				sbp_sleep(1);    /* wait a bit, try again */
 			}
 			if (status_tries == 0)
@@ -4188,8 +4115,13 @@
 				drvcmd[5]=0;
 				drvcmd[6]=read_audio.nframes; /* # of frames */
 			}
-			else if (fam2_drive) /* CD200: not tested yet */
+			else if (fam2_drive)
 			{
+				drvcmd[0]=CMD2_READ_XA2;
+				lba2msf(block,&drvcmd[1]); /* msf-bin format required */
+				drvcmd[4]=0;
+				drvcmd[5]=read_audio.nframes; /* # of frames */
+				drvcmd[6]=0x11; /* raw mode */
 			}
 			else if (famT_drive) /* CD-55A: not tested yet */
 			{
@@ -5080,7 +5012,8 @@
 }
 /*==========================================================================*/
 /*
- *  Test for presence of drive and initialize it.  Called at boot time.
+ *  Test for presence of drive and initialize it.
+ *  Called once at boot or load time.
  */
 #ifdef MODULE
 int init_module(void)
@@ -5183,13 +5116,10 @@
 		D_S[d].sbp_current = 0;       /* Frame being currently read */
 		D_S[d].CD_changed=1;
 		D_S[d].frame_size=CD_FRAMESIZE;
+		D_S[d].f_eject=0;
 #if EJECT
 		if (!fam0_drive) D_S[d].f_eject=1;
-		else D_S[d].f_eject=0;
-#else
-		D_S[d].f_eject=0;
-#endif
-		
+#endif EJECT
 		cc_ReadStatus();
 		i=ResponseStatus();  /* returns orig. status or p_busy_new */
 		if (famT_drive) i=ResponseStatus();  /* returns orig. status or p_busy_new */
@@ -5274,7 +5204,9 @@
 			msg(DBG_INF,"data buffer (%d frames) not available.\n",D_S[j].sbp_bufsiz);
 			return -EIO;
 		}
+#ifdef MODULE
 		msg(DBG_INF,"data buffer size: %d frames.\n",SBP_BUFFER_FRAMES);
+#endif MODULE
 		if (D_S[j].sbp_audsiz>0)
 		{
 			D_S[j].aud_buf=(u_char *) vmalloc(D_S[j].sbp_audsiz*CD_FRAMESIZE_RAW);
@@ -5288,23 +5220,21 @@
 	}
 	blksize_size[MAJOR_NR]=sbpcd_blocksizes;
 	
-#ifdef MODULE
-	return (0);
-#else
  init_done:
+#ifndef MODULE
 #if !(SBPCD_ISSUE-1)
 #ifdef CONFIG_SBPCD2
 	sbpcd2_init();
-#endif
+#endif CONFIG_SBPCD2
 #ifdef CONFIG_SBPCD3
 	sbpcd3_init();
-#endif
+#endif CONFIG_SBPCD3
 #ifdef CONFIG_SBPCD4
 	sbpcd4_init();
-#endif
-#endif
-	return 0;
+#endif CONFIG_SBPCD4
+#endif !(SBPCD_ISSUE-1)
 #endif MODULE
+	return 0;
 }
 /*==========================================================================*/
 #ifdef MODULE
@@ -5328,8 +5258,7 @@
 	{
 		if (D_S[j].drv_id==-1) continue;
 		vfree(D_S[j].sbp_buf);
-		if (D_S[j].sbp_audsiz>0)
-			vfree(D_S[j].aud_buf);
+		if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
 	}
 	msg(DBG_INF, "%s module released.\n", major_name);
 }
diff -u --recursive --new-file v1.3.42/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c
--- v1.3.42/linux/drivers/char/busmouse.c	Thu Nov  9 11:23:48 1995
+++ linux/drivers/char/busmouse.c	Sun Nov 19 13:37:26 1995
@@ -26,6 +26,10 @@
  *   added fasync support
  *
  * Modularised 6-Sep-95 Philip Blundell <pjb27@cam.ac.uk> 
+ *
+ * Replaced dumb busy loop with udelay()  16 Nov 95
+ *   Nathan Laredo <laredo@gnu.ai.mit.edu>
+ *
  */
 
 #include <linux/module.h>
@@ -38,6 +42,7 @@
 #include <linux/mm.h>
 #include <linux/mouse.h>
 #include <linux/random.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/segment.h>
@@ -241,8 +246,7 @@
 
 	outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
 	outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
-	for (i = 0; i < 100000; i++)
-		/* busy loop */;
+	udelay(100L);	/* wait for reply from mouse */
 	if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
 		mouse.present = 0;
 		return -EIO;
diff -u --recursive --new-file v1.3.42/linux/drivers/char/console.c linux/drivers/char/console.c
--- v1.3.42/linux/drivers/char/console.c	Sat Nov 11 17:41:32 1995
+++ linux/drivers/char/console.c	Tue Nov 21 08:34:54 1995
@@ -57,6 +57,9 @@
  * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
  * <poe@daimi.aau.dk>
  *
+ * User-defined bell sound, new setterm control sequences and printk
+ * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
+ *
  */
 
 #define BLANK 0x0020
@@ -134,7 +137,7 @@
 extern void compute_shiftstate(void);
 extern void reset_palette(int currcons);
 extern void set_palette(void);
-extern unsigned long con_type_init(unsigned long, char *);
+extern unsigned long con_type_init(unsigned long, const char **);
 extern int set_get_cmap(unsigned char *, int);
 extern int set_get_font(unsigned char *, int, int);
 
@@ -1126,6 +1129,27 @@
 			blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
 			poke_blanked_console();
 			break;
+		case 10: /* set bell frequency in Hz */
+			if (npar >= 1)
+				bell_pitch = (par[1] < 20 || par[1] > 32767) ?
+					0 : 1193180 / par[1];
+			else
+				bell_pitch = 0x637;
+			break;
+		case 11: /* set bell duration in msec */
+			if (npar >= 1)
+				bell_duration = (par[1] < 2000) ?
+					par[1]*HZ/1000 : 0;
+			else
+				bell_duration = HZ/8;
+			break;
+		case 12: /* bring specified console to the front */
+			if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
+				update_screen(par[1]-1);
+			break;
+		case 13: /* unblank the screen */
+			unblank_screen();
+			break;
 	}
 }
 
@@ -1286,6 +1310,9 @@
 	tab_stop[3]	=
 	tab_stop[4]	= 0x01010101;
 
+	bell_pitch = 0x637;
+	bell_duration = HZ/8;
+
 	gotoxy(currcons,0,0);
 	save_cur(currcons);
 	if (do_clear)
@@ -1440,7 +1467,8 @@
 		 */
 		switch (c) {
 			case 7:
-				kd_mksound(0x637, HZ/8);
+				if (bell_pitch && bell_duration)
+					kd_mksound(bell_pitch, bell_duration);
 				continue;
 			case 8:
 				bs(currcons);
@@ -1816,6 +1844,9 @@
 		return;	 /* console not yet initialized */
 	printing = 1;
 
+	if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
+		currcons = kmsg_redirect - 1;
+
 	if (!vc_cons_allocated(currcons)) {
 		/* impossible */
 		printk("console_print: tty %d not allocated ??\n", currcons+1);
@@ -1909,7 +1940,7 @@
  */
 unsigned long con_init(unsigned long kmem_start)
 {
-	char display_desc[] = "????";
+	const char *display_desc = "????";
 	int currcons = 0;
 	int orig_x = ORIG_X;
 	int orig_y = ORIG_Y;
@@ -1954,7 +1985,7 @@
 		timer_active |= 1<<BLANK_TIMER;
 	}
 
-	kmem_start = con_type_init(kmem_start, display_desc);
+	kmem_start = con_type_init(kmem_start, &display_desc);
 
 	/* Initialize the variables used for scrolling (mostly EGA/VGA)	*/
 
diff -u --recursive --new-file v1.3.42/linux/drivers/char/console_struct.h linux/drivers/char/console_struct.h
--- v1.3.42/linux/drivers/char/console_struct.h	Thu Nov  9 11:23:48 1995
+++ linux/drivers/char/console_struct.h	Tue Nov 21 08:34:54 1995
@@ -62,6 +62,8 @@
 	unsigned char 	vc_G1_charset;
 	unsigned char 	vc_saved_G0;
 	unsigned char 	vc_saved_G1;
+	unsigned int	vc_bell_pitch;		/* Console bell pitch */
+	unsigned int	vc_bell_duration;	/* Console bell duration */
 	/* additional information is in vt_kern.h */
 };
 
@@ -132,6 +134,8 @@
 #define	halfcolor	(vc_cons[currcons].d->vc_halfcolor)
 #define tab_stop	(vc_cons[currcons].d->vc_tab_stop)
 #define palette		(vc_cons[currcons].d->vc_palette)
+#define bell_pitch	(vc_cons[currcons].d->vc_bell_pitch)
+#define bell_duration	(vc_cons[currcons].d->vc_bell_duration)
 
 #define vcmode		(vt_cons[currcons]->vc_mode)
 #define structsize	(sizeof(struct vc_data) + sizeof(struct vt_struct))
diff -u --recursive --new-file v1.3.42/linux/drivers/char/tga.c linux/drivers/char/tga.c
--- v1.3.42/linux/drivers/char/tga.c	Wed Nov  8 07:11:31 1995
+++ linux/drivers/char/tga.c	Tue Nov 21 08:34:54 1995
@@ -301,7 +301,7 @@
 }
 
 unsigned long
-con_type_init(unsigned long kmem_start, char *display_desc)
+con_type_init(unsigned long kmem_start, const char **display_desc)
 {
         can_do_color = 1;
 
@@ -314,7 +314,7 @@
 
         video_type = VIDEO_TYPE_TGAC;
 
-        strcpy(display_desc,"TGA");
+        *display_desc = "TGA";
 
 	return kmem_start;
 }
@@ -830,17 +830,20 @@
 
     for ( j = 0; j < TGA_F_HEIGHT_PADDED; j++ ) {
       if (j < TGA_F_HEIGHT) {
-	rowbits = *font_row++;
-	data = fontmask_bits[(rowbits>>4)&0xf];
-	data = (data & fgmask) | (~data & bgmask);
-	writel(data, dst);
-	data = fontmask_bits[rowbits&0xf];
-	data = (data & fgmask) | (~data & bgmask);
-	writel(data, (dst+1));
+	rowbits = font_row[j];
       } else {
-	writel(bgmask, dst);
-	writel(bgmask, (dst+1));
+	/* dup the last n rows only if char > 0x7f */
+	if (c & 0x80)
+	  rowbits = font_row[j-(TGA_F_HEIGHT_PADDED-TGA_F_HEIGHT)];
+	else
+	  rowbits = 0;
       }
+      data = fontmask_bits[(rowbits>>4)&0xf];
+      data = (data & fgmask) | (~data & bgmask);
+      writel(data, dst);
+      data = fontmask_bits[rowbits&0xf];
+      data = (data & fgmask) | (~data & bgmask);
+      writel(data, (dst+1));
       dst += stride;
     }
   } else { /* 24-plane */
@@ -854,18 +857,20 @@
 
     for ( i = 0; i < TGA_F_HEIGHT_PADDED; i++ ) {
       if (i < TGA_F_HEIGHT) {
-	rowbits = *font_row++;
-	data = 1 << (TGA_F_WIDTH - 1);
-	for (j = 0; j < TGA_F_WIDTH; j++, data >>= 1) {
-	  if (rowbits & data)
-	    writel(fgmask, (dst+j));
-	  else
-	    writel(bgmask, (dst+j));
-	}
+	rowbits = font_row[i];
       } else {
-	for (j = 0; j < TGA_F_WIDTH; j++) {
+	/* dup the last n rows only if char > 0x7f */
+	if (c & 0x80)
+	  rowbits = font_row[i-(TGA_F_HEIGHT_PADDED-TGA_F_HEIGHT)];
+	else
+	  rowbits = 0;
+      }
+      data = 1 << (TGA_F_WIDTH - 1);
+      for (j = 0; j < TGA_F_WIDTH; j++, data >>= 1) {
+	if (rowbits & data)
+	  writel(fgmask, (dst+j));
+	else
 	  writel(bgmask, (dst+j));
-	}
       }
       dst += stride;
     }
diff -u --recursive --new-file v1.3.42/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- v1.3.42/linux/drivers/char/tpqic02.c	Tue Oct 10 18:46:34 1995
+++ linux/drivers/char/tpqic02.c	Mon Nov 20 07:50:03 1995
@@ -220,6 +220,9 @@
 #include <asm/io.h>
 #include <asm/segment.h>
 
+/* We really shouldn't be using this define.. */
+#define IOCCMD_MASK 0x0000ffff
+
 /* check existence of required configuration parameters */
 #if !defined(QIC02_CMD_PORT) || \
     !defined(QIC02_TAPE_IRQ) || \
diff -u --recursive --new-file v1.3.42/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v1.3.42/linux/drivers/char/tty_io.c	Thu Nov  9 11:23:49 1995
+++ linux/drivers/char/tty_io.c	Tue Nov 21 08:34:54 1995
@@ -38,6 +38,9 @@
  *
  * Reorganized FASYNC support so mouse code can share it.
  *	-- ctm@ardi.com, 9Sep95
+ *
+ * New TIOCLINUX variants added.
+ *	-- mj@k332.feld.cvut.cz, 19-Nov-95
  */
 
 #include <linux/config.h>
@@ -84,12 +87,14 @@
 
 /*
  * fg_console is the current virtual console,
- * last_console is the last used one
+ * last_console is the last used one,
+ * kmsg_redirect is the console for kernel messages,
  * redirect is the pseudo-tty that console output
  * is redirected to if asked by TIOCCONS.
  */
 int fg_console = 0;
 int last_console = 0;
+int kmsg_redirect = 0;
 struct tty_struct * redirect = NULL;
 struct wait_queue * keypress_wait = NULL;
 
@@ -1542,6 +1547,17 @@
 				case 10:
 					set_vesa_blanking(arg);
 					return 0;
+				case 11:	/* set kmsg redirect */
+					if (!suser())
+						return -EPERM;
+					retval = verify_area(VERIFY_READ,
+						(void *) arg+1, 1);
+					if (retval)
+						return retval;
+					kmsg_redirect = get_user((char *)arg+1);
+					return 0;
+				case 12:	/* get fg_console */
+					return fg_console;
 				default: 
 					return -EINVAL;
 			}
diff -u --recursive --new-file v1.3.42/linux/drivers/char/vga.c linux/drivers/char/vga.c
--- v1.3.42/linux/drivers/char/vga.c	Sat Nov 11 17:41:32 1995
+++ linux/drivers/char/vga.c	Fri Nov 17 08:33:07 1995
@@ -133,7 +133,7 @@
 }
 
 unsigned long
-con_type_init(unsigned long kmem_start, char *display_desc)
+con_type_init(unsigned long kmem_start, const char **display_desc)
 {
 	if (ORIG_VIDEO_MODE == 7)	/* Is this a monochrome display? */
 	{
@@ -144,14 +144,14 @@
 		{
 			video_type = VIDEO_TYPE_EGAM;
 			video_mem_term = 0xb8000;
-			strcpy(display_desc, "EGA+");
+			*display_desc = "EGA+";
 			request_region(0x3b0,16,"ega");
 		}
 		else
 		{
 			video_type = VIDEO_TYPE_MDA;
 			video_mem_term = 0xb2000;
-			strcpy(display_desc, "*MDA");
+			*display_desc = "*MDA";
 			request_region(0x3b0,12,"mda");
 			request_region(0x3bf, 1,"mda");
 		}
@@ -170,11 +170,11 @@
 
 			if (!ORIG_VIDEO_ISVGA) {
 				video_type = VIDEO_TYPE_EGAC;
-				strcpy(display_desc, "EGA");
+				*display_desc = "EGA";
 				request_region(0x3c0,32,"ega");
 			} else {
 				video_type = VIDEO_TYPE_VGAC;
-				strcpy(display_desc, "VGA+");
+				*display_desc = "VGA+";
 				request_region(0x3c0,32,"vga+");
 
 #ifdef VGA_CAN_DO_64KB
@@ -215,7 +215,7 @@
 		{
 			video_type = VIDEO_TYPE_CGA;
 			video_mem_term = 0xba000;
-			strcpy(display_desc, "*CGA");
+			*display_desc = "*CGA";
 			request_region(0x3d4,2,"cga");
 		}
 	}
diff -u --recursive --new-file v1.3.42/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.3.42/linux/drivers/scsi/scsi.c	Mon Nov 13 12:36:45 1995
+++ linux/drivers/scsi/scsi.c	Tue Nov 21 08:54:39 1995
@@ -478,8 +478,6 @@
 			if (((driver_byte(SCpnt->result) & DRIVER_SENSE) ||
 			     (status_byte(SCpnt->result) & CHECK_CONDITION)) &&
 			    ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
-			    if (SCpnt->sense_buffer[2] &0xe0)
-				continue; /* No devices here... */
 			    if(((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) &&
 			       ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION))
 				continue;
@@ -2313,7 +2311,7 @@
     timer_table[SCSI_TIMER].expires = 0;
 
 
-    /* Register the core /proc/scsi entry */
+    /* Register the /proc/scsi/scsi entry */
 #if CONFIG_PROC_FS 
     proc_scsi_register(0, &proc_scsi_scsi);    
 #endif
@@ -3094,6 +3092,12 @@
     timer_table[SCSI_TIMER].expires = 0;
     register_symtab(&scsi_symbol_table);
     scsi_loadable_module_flag = 1;
+
+    /* Register the /proc/scsi/scsi entry */
+#if CONFIG_PROC_FS
+    proc_scsi_register(0, &proc_scsi_scsi);
+#endif
+
     
     dma_sectors = PAGE_SIZE / 512;
     dma_free_sectors= dma_sectors;
@@ -3117,11 +3121,10 @@
 
 void cleanup_module( void) 
 {
-    if (MOD_IN_USE) {
-	printk(KERN_INFO __FILE__ ": module is in use, remove rejected\n");
-	return;
-    }
-    
+#if CONFIG_PROC_FS
+    proc_scsi_unregister(0, PROC_SCSI_SCSI);
+#endif
+
     /* No, we're not here anymore. Don't show the /proc/scsi files. */
     dispatch_scsi_info_ptr = 0L;
 
diff -u --recursive --new-file v1.3.42/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- v1.3.42/linux/drivers/scsi/seagate.c	Fri Nov 17 08:42:27 1995
+++ linux/drivers/scsi/seagate.c	Fri Nov 17 08:20:52 1995
@@ -46,9 +46,7 @@
  *	transfer rate if handshaking isn't working correctly.
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <asm/io.h>
 #include <asm/system.h>
diff -u --recursive --new-file v1.3.42/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v1.3.42/linux/drivers/scsi/sg.c	Thu Nov  9 11:23:50 1995
+++ linux/drivers/scsi/sg.c	Tue Nov 21 08:34:53 1995
@@ -509,7 +509,19 @@
 
 
 static int sg_detect(Scsi_Device * SDp){
-    ++sg_template.dev_noticed;
+
+    switch (SDp->type) {
+	case TYPE_DISK:
+	case TYPE_MOD:
+	case TYPE_ROM:
+	case TYPE_WORM:
+	case TYPE_TAPE: break;
+	default: 
+	printk("Detected scsi generic sg%c at scsi%d, channel %d, id %d, lun %d\n",
+           'a'+sg_template.dev_noticed,
+           SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+    }
+    sg_template.dev_noticed++;
     return 1;
 }
 
diff -u --recursive --new-file v1.3.42/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v1.3.42/linux/fs/binfmt_elf.c	Fri Nov 17 08:42:27 1995
+++ linux/fs/binfmt_elf.c	Sun Nov 19 13:09:00 1995
@@ -95,22 +95,13 @@
 		mpnt->vm_start = PAGE_MASK & (unsigned long) p;
 		mpnt->vm_end = TASK_SIZE;
 		mpnt->vm_page_prot = PAGE_COPY;
-#ifdef VM_STACK_FLAGS
 		mpnt->vm_flags = VM_STACK_FLAGS;
 		mpnt->vm_pte = 0;
-#else
-#  ifdef VM_GROWSDOWN
-		mpnt->vm_flags = VM_GROWSDOWN;
-#  endif
-#endif
 		mpnt->vm_inode = NULL;
 		mpnt->vm_offset = 0;
 		mpnt->vm_ops = NULL;
 		insert_vm_struct(current, mpnt);
-#ifndef VM_GROWSDOWN
-		current->mm->stk_vma = mpnt;
-#endif
-
+		current->mm->total_vm += (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 	}
 	sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
 	sp -= exec ? DLINFO_ITEMS*2 : 2;
@@ -792,7 +783,6 @@
 	k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
 	if(k > elf_bss) elf_bss = k;
 	
-	SYS(close)(fd);
 	if (error != (elf_phdata->p_vaddr & 0xfffff000)) {
 		kfree(elf_phdata);
 		return error;
diff -u --recursive --new-file v1.3.42/linux/fs/exec.c linux/fs/exec.c
--- v1.3.42/linux/fs/exec.c	Fri Nov 17 08:42:27 1995
+++ linux/fs/exec.c	Fri Nov 17 16:44:48 1995
@@ -328,6 +328,7 @@
 		mpnt->vm_inode = NULL;
 		mpnt->vm_pte = 0;
 		insert_vm_struct(current, mpnt);
+		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 	}
 	sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
 #ifdef __alpha__
@@ -541,9 +542,12 @@
 			return;
 		}
 		*mm = *current->mm;
+		mm->def_flags = 0;	/* should future lockings be kept? */
 		mm->count = 1;
 		mm->mmap = NULL;
 		mm->mmap_avl = NULL;
+		mm->total_vm = 0;
+		mm->rss = 0;
 		current->mm->count--;
 		current->mm = mm;
 		new_page_tables(current);
@@ -814,6 +818,7 @@
 	unsigned long error;
 	unsigned long p = bprm->p;
 	unsigned long fd_offset;
+	unsigned long rlim;
 
 	ex = *((struct exec *) bprm->buf);		/* exec-header */
 	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
@@ -838,6 +843,16 @@
 		return -ENOEXEC;
 	}
 #endif
+
+	/* Check initial limits. This avoids letting people circumvent
+	 * size limits imposed on them by creating programs with large
+	 * arrays in the data or bss.
+	 */
+	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	if (rlim >= RLIM_INFINITY)
+		rlim = ~0;
+	if (ex.a_data + ex.a_bss > rlim)
+		return -ENOMEM;
 
 	/* OK, This is the point of no return */
 	flush_old_exec(bprm);
diff -u --recursive --new-file v1.3.42/linux/fs/filesystems.c linux/fs/filesystems.c
--- v1.3.42/linux/fs/filesystems.c	Fri Nov 17 08:42:27 1995
+++ linux/fs/filesystems.c	Sun Nov 19 13:39:02 1995
@@ -41,11 +41,6 @@
 
 	device_setup();
 
-#ifdef CONFIG_MINIX_FS
-	register_filesystem(&(struct file_system_type)
-		{minix_read_super, "minix", 1, NULL});
-#endif
-
 #ifdef CONFIG_EXT_FS
 	register_filesystem(&(struct file_system_type)
 		{ext_read_super, "ext", 1, NULL});
@@ -60,6 +55,12 @@
 	register_filesystem(&(struct file_system_type)
 		{xiafs_read_super, "xiafs", 1, NULL});
 #endif
+
+#ifdef CONFIG_MINIX_FS
+	register_filesystem(&(struct file_system_type)
+		{minix_read_super, "minix", 1, NULL});
+#endif
+
 #ifdef CONFIG_UMSDOS_FS
 	register_filesystem(&(struct file_system_type)
 	{UMSDOS_read_super,	"umsdos",	1, NULL});
diff -u --recursive --new-file v1.3.42/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
--- v1.3.42/linux/fs/nfs/nfsroot.c	Fri Nov 17 08:42:27 1995
+++ linux/fs/nfs/nfsroot.c	Fri Nov 17 08:40:03 1995
@@ -349,7 +349,7 @@
 	{ NULL,		0,			0 }};
 
 
-unsigned long get_address (char **str)
+static unsigned long get_address (char **str)
 {
    unsigned long l;
    unsigned int val;
@@ -490,7 +490,7 @@
   sin=(struct sockaddr_in *)&server_route.rt_genmask;
   sin->sin_family=AF_INET;
   sin->sin_addr.s_addr= root_dev->pa_mask;
-  server_route.rt_dev[0]=0;
+  server_route.rt_dev=NULL;
   server_route.rt_flags=RTF_HOST|RTF_UP;
   
   /* Now add a route to the server */
diff -u --recursive --new-file v1.3.42/linux/fs/proc/array.c linux/fs/proc/array.c
--- v1.3.42/linux/fs/proc/array.c	Sat Nov 11 17:41:34 1995
+++ linux/fs/proc/array.c	Tue Nov 21 08:34:54 1995
@@ -198,6 +198,10 @@
 	len = sprintf(buffer,
 		"cpu  %u %u %u %lu\n"
 		"disk %u %u %u %u\n"
+		"disk_rio %u %u %u %u\n"
+		"disk_wio %u %u %u %u\n"
+		"disk_rblk %u %u %u %u\n"
+		"disk_wblk %u %u %u %u\n"
 		"page %u %u\n"
 		"swap %u %u\n"
 		"intr %u",
@@ -205,10 +209,16 @@
 		kstat.cpu_nice,
 		kstat.cpu_system,
 		jiffies - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system),
-		kstat.dk_drive[0],
-		kstat.dk_drive[1],
-		kstat.dk_drive[2],
-		kstat.dk_drive[3],
+		kstat.dk_drive[0], kstat.dk_drive[1],
+		kstat.dk_drive[2], kstat.dk_drive[3],
+		kstat.dk_drive_rio[0], kstat.dk_drive_rio[1],
+		kstat.dk_drive_rio[2], kstat.dk_drive_rio[3],
+		kstat.dk_drive_wio[0], kstat.dk_drive_wio[1],
+		kstat.dk_drive_wio[2], kstat.dk_drive_wio[3],
+		kstat.dk_drive_rblk[0], kstat.dk_drive_rblk[1],
+		kstat.dk_drive_rblk[2], kstat.dk_drive_rblk[3],
+		kstat.dk_drive_wblk[0], kstat.dk_drive_wblk[1],
+		kstat.dk_drive_wblk[2], kstat.dk_drive_wblk[3],
 		kstat.pgpgin,
 		kstat.pgpgout,
 		kstat.pswpin,
diff -u --recursive --new-file v1.3.42/linux/include/asm-alpha/mman.h linux/include/asm-alpha/mman.h
--- v1.3.42/linux/include/asm-alpha/mman.h	Tue Jul 25 18:21:22 1995
+++ linux/include/asm-alpha/mman.h	Fri Nov 17 10:15:29 1995
@@ -21,9 +21,13 @@
 #define MAP_GROWSDOWN	0x1000		/* stack-like segment */
 #define MAP_DENYWRITE	0x2000		/* ETXTBSY */
 #define MAP_EXECUTABLE	0x4000		/* mark it as a executable */
+#define MAP_LOCKED	0x8000		/* lock the mapping */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_SYNC		2		/* synchronous memory sync */
 #define MS_INVALIDATE	4		/* invalidate the caches */
+
+#define MCL_CURRENT	 8192		/* lock all currently mapped pages */
+#define MCL_FUTURE	16384		/* lock all additions to address space */
 
 #endif /* __ALPHA_MMAN_H__ */
diff -u --recursive --new-file v1.3.42/linux/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- v1.3.42/linux/include/asm-alpha/page.h	Wed Nov  8 07:11:41 1995
+++ linux/include/asm-alpha/page.h	Fri Nov 17 09:11:13 1995
@@ -72,14 +72,6 @@
 #define PAGE_OFFSET		0xFFFFFC0000000000
 #define MAP_NR(addr)		((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
 
-typedef struct {
-	unsigned count:24,
-		 age:6,
-		 dirty:1,
-		 reserved:1;
-} mem_map_t;
-
-
 #endif /* __KERNEL__ */
 
 #endif /* _ALPHA_PAGE_H */
diff -u --recursive --new-file v1.3.42/linux/include/asm-alpha/resource.h linux/include/asm-alpha/resource.h
--- v1.3.42/linux/include/asm-alpha/resource.h	Thu Nov  9 11:23:52 1995
+++ linux/include/asm-alpha/resource.h	Fri Nov 17 15:21:01 1995
@@ -14,12 +14,9 @@
 #define RLIMIT_NOFILE	6		/* max number of open files */
 #define RLIMIT_AS	7		/* address space limit(?) */
 #define RLIMIT_NPROC	8		/* max number of processes */
+#define RLIMIT_MEMLOCK	9		/* max locked-in-memory address space */
 
-#ifdef notdef
-#define RLIMIT_MEMLOCK	9		/* max locked-in-memory address space*/
-#endif
-
-#define RLIM_NLIMITS	9
+#define RLIM_NLIMITS	10
 
 #ifdef __KERNEL__
 
@@ -34,6 +31,7 @@
     { NR_OPEN,  NR_OPEN},			/* RLIMIT_NOFILE */	\
     {LONG_MAX, LONG_MAX},			/* RLIMIT_AS */		\
     {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER},	/* RLIMIT_NPROC */	\
+    {LONG_MAX, LONG_MAX},			/* RLIMIT_MEMLOCK */	\
 }
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v1.3.42/linux/include/asm-i386/mman.h linux/include/asm-i386/mman.h
--- v1.3.42/linux/include/asm-i386/mman.h	Tue Jul 25 18:21:23 1995
+++ linux/include/asm-i386/mman.h	Fri Nov 17 09:39:51 1995
@@ -15,9 +15,13 @@
 #define MAP_GROWSDOWN	0x0100		/* stack-like segment */
 #define MAP_DENYWRITE	0x0800		/* ETXTBSY */
 #define MAP_EXECUTABLE	0x1000		/* mark it as a executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
 #define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
 
 #endif /* __I386_MMAN_H__ */
diff -u --recursive --new-file v1.3.42/linux/include/asm-i386/page.h linux/include/asm-i386/page.h
--- v1.3.42/linux/include/asm-i386/page.h	Wed Nov  8 07:11:41 1995
+++ linux/include/asm-i386/page.h	Fri Nov 17 09:10:58 1995
@@ -92,13 +92,6 @@
 #define PAGE_OFFSET		0
 #define MAP_NR(addr)		(((unsigned long)(addr)) >> PAGE_SHIFT)
 
-typedef struct {
-	unsigned count:24,
-		 age:6,
-		 dirty:1,
-		 reserved:1;
-} mem_map_t;
-
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
diff -u --recursive --new-file v1.3.42/linux/include/asm-i386/resource.h linux/include/asm-i386/resource.h
--- v1.3.42/linux/include/asm-i386/resource.h	Thu Nov  9 11:23:52 1995
+++ linux/include/asm-i386/resource.h	Fri Nov 17 16:05:40 1995
@@ -13,21 +13,23 @@
 #define RLIMIT_RSS	5		/* max resident set size */
 #define RLIMIT_NPROC	6		/* max number of processes */
 #define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
 
-#ifdef notdef
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space*/
-#endif
-
-#define RLIM_NLIMITS	8
+#define RLIM_NLIMITS	9
 
 #ifdef __KERNEL__
 
-#define INIT_RLIMITS							\
-{									\
-    {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX},				\
-    {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM},				\
-    {       0, LONG_MAX}, {LONG_MAX, LONG_MAX},				\
-    {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, {NR_OPEN, NR_OPEN}	\
+#define INIT_RLIMITS					\
+{							\
+	{ LONG_MAX, LONG_MAX },				\
+	{ LONG_MAX, LONG_MAX },				\
+	{ LONG_MAX, LONG_MAX },				\
+	{ _STK_LIM, _STK_LIM },				\
+	{        0, LONG_MAX },				\
+	{ LONG_MAX, LONG_MAX },				\
+	{ MAX_TASKS_PER_USER, MAX_TASKS_PER_USER },	\
+	{ NR_OPEN, NR_OPEN },				\
+	{ LONG_MAX, LONG_MAX },				\
 }
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v1.3.42/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v1.3.42/linux/include/asm-i386/unistd.h	Fri Oct 13 14:44:45 1995
+++ linux/include/asm-i386/unistd.h	Fri Nov 17 09:00:43 1995
@@ -153,6 +153,11 @@
 #define __NR_readv		145
 #define __NR_writev		146
 
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+
 /* 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.42/linux/include/linux/busmouse.h linux/include/linux/busmouse.h
--- v1.3.42/linux/include/linux/busmouse.h	Fri Sep 15 11:13:02 1995
+++ linux/include/linux/busmouse.h	Tue Nov 21 08:34:54 1995
@@ -2,7 +2,7 @@
 #define _LINUX_BUSMOUSE_H
 
 /*
- * linux/include/linux/mouse.h: header file for Logitech Bus Mouse driver
+ * linux/include/linux/busmouse.h: header file for Logitech Bus Mouse driver
  * by James Banks
  *
  * based on information gleamed from various mouse drivers on the net
diff -u --recursive --new-file v1.3.42/linux/include/linux/cdrom.h linux/include/linux/cdrom.h
--- v1.3.42/linux/include/linux/cdrom.h	Wed Oct  4 14:14:34 1995
+++ linux/include/linux/cdrom.h	Sun Nov 19 18:21:44 1995
@@ -20,7 +20,7 @@
 #define CD_HEAD_SIZE         4 /* header (address) bytes per raw data frame */
 #define CD_SUBHEAD_SIZE      8 /* subheader bytes per raw XA data frame */
 #define CD_XA_HEAD        (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
-#define CD_XA_SYNC_HEAD   (CD_XA_HEAD+12)/* sync bytes + header of XA frame */
+#define CD_XA_SYNC_HEAD   (CD_SYNC_SIZE+CD_XA_HEAD)/* sync bytes + header of XA frame */
 
 #define CD_FRAMESIZE      2048 /* bytes per frame, "cooked" mode */
 #define CD_FRAMESIZE_RAW  2352 /* bytes per frame, "raw" mode */
@@ -258,7 +258,7 @@
 #define CDROMSUBCHNL		0x530b	/* (struct cdrom_subchnl) */
 
 #define CDROMREADMODE2		0x530c	/* (struct cdrom_read) */
-                                          /* read type-2 data (not suppt) */
+                                          /* read type-2 data */
 
 #define CDROMREADMODE1		0x530d	/* (struct cdrom_read) */
                                           /* read type-1 data */
@@ -290,12 +290,13 @@
  */
 #define CDROMREADRAW		0x5314	/* read data in raw mode */
 #define CDROMREADCOOKED		0x5315	/* read data in cooked mode */
-#define CDROMSEEK		0x5316  /*seek msf address*/
+#define CDROMSEEK		0x5316  /* seek msf address */
   
 /*
  * for playing audio in logical block addressing mode
  */
 #define CDROMPLAYBLK		0x5317	/* (struct cdrom_blk) */
+
 
 /*
  * CD-ROM-specific SCSI command opcodes
diff -u --recursive --new-file v1.3.42/linux/include/linux/debugreg.h linux/include/linux/debugreg.h
--- v1.3.42/linux/include/linux/debugreg.h	Wed Dec  8 14:34:44 1993
+++ linux/include/linux/debugreg.h	Tue Nov 21 08:34:54 1995
@@ -21,7 +21,7 @@
 
 /* Now define a bunch of things for manipulating the control register.
    The top two bytes of the control register consist of 4 fields of 4
-   bytes - each field corresponds to one of the four debug registers,
+   bits - each field corresponds to one of the four debug registers,
    and indicates what types of access we trap on, and how large the data
    field is that we are looking at */
 
diff -u --recursive --new-file v1.3.42/linux/include/linux/kernel_stat.h linux/include/linux/kernel_stat.h
--- v1.3.42/linux/include/linux/kernel_stat.h	Mon Sep 18 14:54:09 1995
+++ linux/include/linux/kernel_stat.h	Tue Nov 21 08:34:54 1995
@@ -14,6 +14,10 @@
 struct kernel_stat {
 	unsigned int cpu_user, cpu_nice, cpu_system;
 	unsigned int dk_drive[DK_NDRIVE];
+	unsigned int dk_drive_rio[DK_NDRIVE];
+	unsigned int dk_drive_wio[DK_NDRIVE];
+	unsigned int dk_drive_rblk[DK_NDRIVE];
+	unsigned int dk_drive_wblk[DK_NDRIVE];
 	unsigned int pgpgin, pgpgout;
 	unsigned int pswpin, pswpout;
 	unsigned int interrupts[NR_IRQS];
diff -u --recursive --new-file v1.3.42/linux/include/linux/ldt.h linux/include/linux/ldt.h
--- v1.3.42/linux/include/linux/ldt.h	Fri Jun 17 08:34:41 1994
+++ linux/include/linux/ldt.h	Tue Nov 21 08:34:54 1995
@@ -26,9 +26,4 @@
 #define MODIFY_LDT_CONTENTS_STACK	1
 #define MODIFY_LDT_CONTENTS_CODE	2
 
-extern int get_ldt(void *buffer);
-extern int set_ldt_entry(int entry, unsigned long base, unsigned int limit,
-			 int seg_32bit_flag, int contents, int read_only_flag,
-			 int limit_in_pages_flag);
-
 #endif
diff -u --recursive --new-file v1.3.42/linux/include/linux/mcdx.h linux/include/linux/mcdx.h
--- v1.3.42/linux/include/linux/mcdx.h	Mon Nov 13 12:36:46 1995
+++ linux/include/linux/mcdx.h	Tue Nov 21 09:50:14 1995
@@ -1,7 +1,7 @@
 /*
  * Definitions for the Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.3
+ * VERSION: 1.5
  * 
  * 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
diff -u --recursive --new-file v1.3.42/linux/include/linux/mm.h linux/include/linux/mm.h
--- v1.3.42/linux/include/linux/mm.h	Fri Nov 17 08:42:28 1995
+++ linux/include/linux/mm.h	Tue Nov 21 08:20:45 1995
@@ -71,12 +71,11 @@
 
 #define VM_GROWSDOWN	0x0100	/* general info on the segment */
 #define VM_GROWSUP	0x0200
-#define VM_SHM		0x0400
+#define VM_SHM		0x0400	/* shared memory area, don't swap out */
 #define VM_DENYWRITE	0x0800	/* ETXTBSY on write attempts.. */
 
 #define VM_EXECUTABLE	0x1000
-#define VM_DONTSWAP	0x2000  /* Some vm types have their own
-				 * hard-coded swap mechanism */
+#define VM_LOCKED	0x2000
 
 #define VM_STACK_FLAGS	0x0177
 
@@ -107,27 +106,14 @@
 	pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
 };
 
-extern mem_map_t * mem_map;
-extern unsigned char *age_map;
+typedef struct {
+	unsigned count:24,
+		 age:6,
+		 dirty:1,
+		 reserved:1;
+} mem_map_t;
 
-/* planning stage.. */
-#define P_DIRTY		0x0001
-#define P_LOCKED	0x0002
-#define P_UPTODATE	0x0004
-#define P_RESERVED	0x8000
-
-struct page_info {
-	unsigned short flags;
-	unsigned short count;
-	struct inode * inode;
-	unsigned long offset;
-	struct page_info * next_same_inode;
-	struct page_info * prev_same_inode;
-	struct page_info * next_hash;
-	struct page_info * prev_hash;
-	struct wait_queue *wait;
-};
-/* end of planning stage */
+extern mem_map_t * mem_map;
 
 /*
  * Free area management
@@ -243,6 +229,22 @@
 #define GFP_LEVEL_MASK 0xf
 
 #define avl_empty	(struct vm_area_struct *) NULL
+
+static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
+{
+	unsigned long grow;
+
+	address &= PAGE_MASK;
+	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
+		return -ENOMEM;
+	grow = vma->vm_start - address;
+	vma->vm_start = address;
+	vma->vm_offset -= grow;
+	vma->vm_mm->total_vm += grow >> PAGE_SHIFT;
+	if (vma->vm_flags & VM_LOCKED)
+		vma->vm_mm->locked_vm += grow >> PAGE_SHIFT;
+	return 0;
+}
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 static inline struct vm_area_struct * find_vma (struct task_struct * task, unsigned long addr)
diff -u --recursive --new-file v1.3.42/linux/include/linux/sbpcd.h linux/include/linux/sbpcd.h
--- v1.3.42/linux/include/linux/sbpcd.h	Fri Sep 15 11:13:02 1995
+++ linux/include/linux/sbpcd.h	Sun Nov 19 18:21:44 1995
@@ -104,17 +104,21 @@
 /* Set this to 0 after you have configured your interface definitions right. */
 #define DISTRIBUTION 1
 
+#if DISTRIBUTION
+#define READ_AUDIO 0
+#else
 /* max. number of audio frames to read with one     */
 /* request (allocates n* 2352 bytes kernel memory!) */
 /* may be freely adjusted, f.e. 75 (= 1 sec.), at   */
 /* runtime by use of the CDROMAUDIOBUFSIZ ioctl.    */
-#define READ_AUDIO 0 
+#define READ_AUDIO 75
 
 /* tray control: eject tray if no disk is in (0 or 1) */
 #define JUKEBOX 1
 
 /* tray control: eject tray after last use (0 or 1) */
 #define EJECT 1
+#endif DISTRIBUTION
 
 /*==========================================================================*/
 /*==========================================================================*/
@@ -641,6 +645,7 @@
 
 #define CMD0_READ_XA	0x03
 #define CMD2_READ_XA	0xd4
+#define CMD2_READ_XA2	0xd5
 #define CMDL_READ_XA	CMD0_READ_XA /* really ?? */
 
 #define CMD0_READ_HEAD	0x04
@@ -683,6 +688,7 @@
 #define CMD2_STATUS	0x00
 #define CMDT_STATUS	CMD2_STATUS
 #define CMDL_STATUS	CMD0_STATUS
+#define CMD2_SEEK_LEADIN 0x00
 
 #define CMD0_READ_ERR	0x82
 #define CMD1_READ_ERR	CMD0_READ_ERR
diff -u --recursive --new-file v1.3.42/linux/include/linux/sched.h linux/include/linux/sched.h
--- v1.3.42/linux/include/linux/sched.h	Thu Nov  9 11:23:54 1995
+++ linux/include/linux/sched.h	Mon Nov 20 14:11:15 1995
@@ -85,6 +85,13 @@
 #define TASK_STOPPED		4
 #define TASK_SWAPPING		5
 
+/*
+ * Scheduling policies
+ */
+#define SCHED_OTHER		0
+#define SCHED_FIFO		1
+#define SCHED_RR		2
+
 #ifndef NULL
 #define NULL ((void *) 0)
 #endif
@@ -129,7 +136,8 @@
 	unsigned long start_code, end_code, start_data, end_data;
 	unsigned long start_brk, brk, start_stack, start_mmap;
 	unsigned long arg_start, arg_end, env_start, env_end;
-	unsigned long rss;
+	unsigned long rss, total_vm, locked_vm;
+	unsigned long def_flags;
 	struct vm_area_struct * mmap;
 	struct vm_area_struct * mmap_avl;
 };
@@ -140,6 +148,7 @@
 		0, 0, 0, 0, \
 		0, 0, 0, 0, \
 		0, 0, 0, 0, \
+		0, 0, 0, \
 		0, \
 		&init_mmap, &init_mmap }
 
@@ -184,7 +193,7 @@
 	struct wait_queue *wait_chldexit;	/* for wait4() */
 	unsigned short uid,euid,suid,fsuid;
 	unsigned short gid,egid,sgid,fsgid;
-	unsigned long timeout;
+	unsigned long timeout, policy;
 	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;
@@ -244,7 +253,7 @@
  */
 #define _STK_LIM	(8*1024*1024)
 
-#define DEF_PRIORITY	(15*HZ/100)	/* 150 ms time slices */
+#define DEF_PRIORITY	(20*HZ/100)	/* 200 ms time slices */
 
 /*
  *  INIT_TASK is used to set up the first task table, touch at
@@ -262,7 +271,7 @@
 /* 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, \
+/* timeout */	0,SCHED_OTHER,0,0,0,0,0,0, \
 /* timer */	{ NULL, NULL, 0, 0, it_real_fn }, \
 /* utime */	0,0,0,0,0, \
 /* flt */	0,0,0,0,0,0, \
diff -u --recursive --new-file v1.3.42/linux/include/linux/tty.h linux/include/linux/tty.h
--- v1.3.42/linux/include/linux/tty.h	Mon Nov 13 12:36:46 1995
+++ linux/include/linux/tty.h	Tue Nov 21 08:34:54 1995
@@ -40,9 +40,9 @@
 	unsigned short orig_video_page;
 	unsigned char  orig_video_mode;
 	unsigned char  orig_video_cols;
-	unsigned short orig_video_ega_ax;
+	unsigned short unused2;
 	unsigned short orig_video_ega_bx;
-	unsigned short orig_video_ega_cx;
+	unsigned short unused3;
 	unsigned char  orig_video_lines;
 	unsigned char  orig_video_isVGA;
 	unsigned short orig_video_points;
@@ -55,9 +55,7 @@
 #define ORIG_VIDEO_PAGE		(screen_info.orig_video_page)
 #define ORIG_VIDEO_MODE		(screen_info.orig_video_mode)
 #define ORIG_VIDEO_COLS 	(screen_info.orig_video_cols)
-#define ORIG_VIDEO_EGA_AX	(screen_info.orig_video_ega_ax)
 #define ORIG_VIDEO_EGA_BX	(screen_info.orig_video_ega_bx)
-#define ORIG_VIDEO_EGA_CX	(screen_info.orig_video_ega_cx)
 #define ORIG_VIDEO_LINES	(screen_info.orig_video_lines)
 #define ORIG_VIDEO_ISVGA	(screen_info.orig_video_isVGA)
 #define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
@@ -272,6 +270,7 @@
 extern struct tty_struct * redirect;
 extern struct tty_ldisc ldiscs[];
 extern int fg_console;
+extern int kmsg_redirect;
 extern struct wait_queue * keypress_wait;
 
 extern unsigned long con_init(unsigned long);
diff -u --recursive --new-file v1.3.42/linux/init/main.c linux/init/main.c
--- v1.3.42/linux/init/main.c	Fri Nov 17 08:42:29 1995
+++ linux/init/main.c	Tue Nov 21 08:34:54 1995
@@ -120,6 +120,7 @@
 
 int ramdisk_size;
 int root_mountflags = MS_RDONLY;
+char *execute_command = 0;
 
 #ifdef CONFIG_ROOT_NFS
 char nfs_root_name[256] = { 0, };
@@ -421,6 +422,11 @@
 			console_loglevel = 10;
 			continue;
 		}
+		if (!strncmp(line,"init=",5)) {
+			line += 5;
+			execute_command = line;
+			continue;
+		}
 		if (checksetup(line))
 			continue;
 		/*
@@ -651,17 +657,22 @@
 	(void) dup(0);
 	(void) dup(0);
 
-	execve("/etc/init",argv_init,envp_init);
-	execve("/bin/init",argv_init,envp_init);
-	execve("/sbin/init",argv_init,envp_init);
-	/* if this fails, fall through to original stuff */
-
-	pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);
-	if (pid>0)
-		while (pid != wait(&i))
-			/* nothing */;
+	if (!execute_command) {
+		execve("/etc/init",argv_init,envp_init);
+		execve("/bin/init",argv_init,envp_init);
+		execve("/sbin/init",argv_init,envp_init);
+		/* if this fails, fall through to original stuff */
+
+		pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);
+		if (pid>0)
+			while (pid != wait(&i))
+				/* nothing */;
+		}
+
 	while (1) {
-		pid = kernel_thread(do_shell, "/bin/sh", SIGCHLD);
+		pid = kernel_thread(do_shell,
+			execute_command ? execute_command : "/bin/sh",
+			SIGCHLD);
 		if (pid < 0) {
 			printf("Fork failed in init\n\r");
 			continue;
diff -u --recursive --new-file v1.3.42/linux/init/version.c linux/init/version.c
--- v1.3.42/linux/init/version.c	Wed Nov  8 07:11:43 1995
+++ linux/init/version.c	Sun Nov 19 17:45:02 1995
@@ -15,6 +15,11 @@
 #ifdef CONFIG_BOGUS
 #endif
 
+#define version(a) Version_ ## a
+#define version_string(a) version(a)
+
+int version_string(LINUX_VERSION_CODE) = 0;
+
 struct new_utsname system_utsname = {
 	UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION,
 	UTS_MACHINE, UTS_DOMAINNAME
diff -u --recursive --new-file v1.3.42/linux/ipc/shm.c linux/ipc/shm.c
--- v1.3.42/linux/ipc/shm.c	Thu Nov  9 11:23:56 1995
+++ linux/ipc/shm.c	Fri Nov 17 16:11:41 1995
@@ -425,6 +425,7 @@
 	do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
 
 	/* add new mapping */
+	current->mm->total_vm += (shmd->vm_end - shmd->vm_start) >> PAGE_SHIFT;
 	insert_vm_struct(current, shmd);
 	merge_segments(current, shmd->vm_start, shmd->vm_end);
 
@@ -516,7 +517,7 @@
 	shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
 	shmd->vm_mm = current->mm;
 	shmd->vm_page_prot = (shmflg & SHM_RDONLY) ? PAGE_READONLY : PAGE_SHARED;
-	shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED | VM_DONTSWAP
+	shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED
 			 | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC
 			 | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE);
 	shmd->vm_next_share = shmd->vm_prev_share = NULL;
diff -u --recursive --new-file v1.3.42/linux/kernel/fork.c linux/kernel/fork.c
--- v1.3.42/linux/kernel/fork.c	Fri Nov 17 08:42:29 1995
+++ linux/kernel/fork.c	Fri Nov 17 09:47:34 1995
@@ -88,6 +88,7 @@
 			return -ENOMEM;
 		}
 		*tmp = *mpnt;
+		tmp->vm_flags &= ~VM_LOCKED;
 		tmp->vm_mm = mm;
 		tmp->vm_next = NULL;
 		if (tmp->vm_inode) {
@@ -122,6 +123,7 @@
 		return -1;
 	*tsk->mm = *current->mm;
 	tsk->mm->count = 1;
+	tsk->mm->def_flags = 0;
 	tsk->min_flt = tsk->maj_flt = 0;
 	tsk->cmin_flt = tsk->cmaj_flt = 0;
 	tsk->nswap = tsk->cnswap = 0;
diff -u --recursive --new-file v1.3.42/linux/kernel/sched.c linux/kernel/sched.c
--- v1.3.42/linux/kernel/sched.c	Wed Nov  8 07:11:43 1995
+++ linux/kernel/sched.c	Tue Nov 21 11:57:37 1995
@@ -106,9 +106,9 @@
 	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;
+	(p->prev_run = init_task.prev_run)->next_run = p;
+	p->next_run = &init_task;
+	init_task.prev_run = p;
 }
 
 static inline void del_from_runqueue(struct task_struct * p)
@@ -137,6 +137,18 @@
 	p->prev_run = NULL;
 }
 
+static inline void move_last_runqueue(struct task_struct * p)
+{
+	struct task_struct *next = p->next_run;
+	struct task_struct *prev = p->prev_run;
+
+	next->prev_run = prev;
+	prev->next_run = next;
+	(p->prev_run = init_task.prev_run)->next_run = p;
+	p->next_run = &init_task;
+	init_task.prev_run = p;
+}
+
 /*
  * Wake up a process. Put it on the run-queue if it's not
  * already there.  The "current" process is always on the
@@ -189,6 +201,14 @@
 #endif
 
 	/*
+	 * Realtime process, select the first one on the
+	 * runqueue (taking priorities within processes
+	 * into account).
+	 */
+	if (p->policy != SCHED_OTHER)
+		return 1000 + p->priority;
+
+	/*
 	 * Give the process a first-approximation goodness value
 	 * according to the number of clock-ticks it has left.
 	 *
@@ -197,7 +217,7 @@
 	 */
 	weight = p->counter;
 	if (weight) {
-
+			
 #ifdef __SMP__
 		/* Give a largish advantage to the same processor...   */
 		/* (this is equivalent to penalizing other processors) */
@@ -241,6 +261,11 @@
 
 	need_resched = 0;
 	cli();
+	/* move an exhausted RR process to be last.. */
+	if (!current->counter && current->policy == SCHED_RR) {
+		current->counter = current->priority;
+		move_last_runqueue(current);
+	}
 	switch (current->state) {
 		case TASK_INTERRUPTIBLE:
 			if (current->signal & ~current->blocked)
diff -u --recursive --new-file v1.3.42/linux/mm/Makefile linux/mm/Makefile
--- v1.3.42/linux/mm/Makefile	Tue Aug 15 20:39:05 1995
+++ linux/mm/Makefile	Fri Nov 17 09:36:49 1995
@@ -8,6 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS	 := memory.o swap.o mmap.o filemap.o mprotect.o kmalloc.o vmalloc.o
+O_OBJS	 := memory.o swap.o mmap.o filemap.o mprotect.o mlock.o \
+	    kmalloc.o vmalloc.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v1.3.42/linux/mm/mlock.c linux/mm/mlock.c
--- v1.3.42/linux/mm/mlock.c	Thu Jan  1 02:00:00 1970
+++ linux/mm/mlock.c	Tue Nov 21 09:58:24 1995
@@ -0,0 +1,270 @@
+/*
+ *	linux/mm/mlock.c
+ *
+ *  (C) Copyright 1995 Linus Torvalds
+ */
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+static inline int mlock_fixup_all(struct vm_area_struct * vma, int newflags)
+{
+	vma->vm_flags = newflags;
+	return 0;
+}
+
+static inline int mlock_fixup_start(struct vm_area_struct * vma,
+	unsigned long end, int newflags)
+{
+	struct vm_area_struct * n;
+
+	n = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!n)
+		return -EAGAIN;
+	*n = *vma;
+	vma->vm_start = end;
+	n->vm_end = end;
+	vma->vm_offset += vma->vm_start - n->vm_start;
+	n->vm_flags = newflags;
+	if (n->vm_inode)
+		n->vm_inode->i_count++;
+	if (n->vm_ops && n->vm_ops->open)
+		n->vm_ops->open(n);
+	insert_vm_struct(current, n);
+	return 0;
+}
+
+static inline int mlock_fixup_end(struct vm_area_struct * vma,
+	unsigned long start, int newflags)
+{
+	struct vm_area_struct * n;
+
+	n = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!n)
+		return -EAGAIN;
+	*n = *vma;
+	vma->vm_end = start;
+	n->vm_start = start;
+	n->vm_offset += n->vm_start - vma->vm_start;
+	n->vm_flags = newflags;
+	if (n->vm_inode)
+		n->vm_inode->i_count++;
+	if (n->vm_ops && n->vm_ops->open)
+		n->vm_ops->open(n);
+	insert_vm_struct(current, n);
+	return 0;
+}
+
+static inline int mlock_fixup_middle(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end, int newflags)
+{
+	struct vm_area_struct * left, * right;
+
+	left = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!left)
+		return -EAGAIN;
+	right = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!right) {
+		kfree(left);
+		return -EAGAIN;
+	}
+	*left = *vma;
+	*right = *vma;
+	left->vm_end = start;
+	vma->vm_start = start;
+	vma->vm_end = end;
+	right->vm_start = end;
+	vma->vm_offset += vma->vm_start - left->vm_start;
+	right->vm_offset += right->vm_start - left->vm_start;
+	vma->vm_flags = newflags;
+	if (vma->vm_inode)
+		vma->vm_inode->i_count += 2;
+	if (vma->vm_ops && vma->vm_ops->open) {
+		vma->vm_ops->open(left);
+		vma->vm_ops->open(right);
+	}
+	insert_vm_struct(current, left);
+	insert_vm_struct(current, right);
+	return 0;
+}
+
+static int mlock_fixup(struct vm_area_struct * vma, 
+	unsigned long start, unsigned long end, unsigned int newflags)
+{
+	int pages, retval;
+
+	if (newflags == vma->vm_flags)
+		return 0;
+
+	/* keep track of amount of locked VM */
+	pages = (end - start) >> PAGE_SHIFT;
+	if (!(newflags & VM_LOCKED))
+		pages = -pages;
+	vma->vm_mm->locked_vm += pages;
+
+	if (start == vma->vm_start) {
+		if (end == vma->vm_end)
+			retval = mlock_fixup_all(vma, newflags);
+		else
+			retval = mlock_fixup_start(vma, end, newflags);
+	} else {
+		if (end == vma->vm_end)
+			retval = mlock_fixup_end(vma, start, newflags);
+		else
+			retval = mlock_fixup_middle(vma, start, end, newflags);
+	}
+	if (!retval && (newflags & VM_LOCKED)) {
+		while (start < end) {
+			char c = get_user((char *) start);
+			__asm__ __volatile__("": :"r" (c));
+			start += PAGE_SIZE;
+		}
+	}
+	return retval;
+}
+
+static int do_mlock(unsigned long start, size_t len, int on)
+{
+	unsigned long nstart, end, tmp;
+	struct vm_area_struct * vma, * next;
+	int error;
+
+	if (!suser())
+		return -EPERM;
+	len = (len + ~PAGE_MASK) & PAGE_MASK;
+	end = start + len;
+	if (end < start)
+		return -EINVAL;
+	if (end == start)
+		return 0;
+	vma = find_vma(current, start);
+	if (!vma || vma->vm_start > start)
+		return -ENOMEM;
+
+	for (nstart = start ; ; ) {
+		unsigned int newflags;
+
+		/* Here we know that  vma->vm_start <= nstart < vma->vm_end. */
+
+		newflags = vma->vm_flags | VM_LOCKED;
+		if (!on)
+			newflags &= ~VM_LOCKED;
+
+		if (vma->vm_end >= end) {
+			error = mlock_fixup(vma, nstart, end, newflags);
+			break;
+		}
+
+		tmp = vma->vm_end;
+		next = vma->vm_next;
+		error = mlock_fixup(vma, nstart, tmp, newflags);
+		if (error)
+			break;
+		nstart = tmp;
+		vma = next;
+		if (!vma || vma->vm_start != nstart) {
+			error = -ENOMEM;
+			break;
+		}
+	}
+	merge_segments(current, start, end);
+	return error;
+}
+
+asmlinkage int sys_mlock(unsigned long start, size_t len)
+{
+	unsigned long locked;
+	unsigned long lock_limit;
+
+	len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
+	start &= PAGE_MASK;
+
+	locked = len >> PAGE_SHIFT;
+	locked += current->mm->locked_vm;
+
+	lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+	lock_limit >>= PAGE_SHIFT;
+
+	/* check against resource limits */
+	if (locked > lock_limit)
+		return -ENOMEM;
+
+	/* we may lock at most half of physical memory... */
+	/* (this check is pretty bogus, but doesn't hurt) */
+	if (locked > MAP_NR(high_memory)/2)
+		return -ENOMEM;
+
+	return do_mlock(start, len, 1);
+}
+
+asmlinkage int sys_munlock(unsigned long start, size_t len)
+{
+	len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
+	start &= PAGE_MASK;
+	return do_mlock(start, len, 0);
+}
+
+static int do_mlockall(int flags)
+{
+	int error;
+	unsigned int def_flags;
+	struct vm_area_struct * vma;
+
+	if (!suser())
+		return -EPERM;
+
+	def_flags = 0;
+	if (flags & MCL_FUTURE)
+		def_flags = VM_LOCKED;
+	current->mm->def_flags = def_flags;
+
+	error = 0;
+	for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
+		unsigned int newflags;
+
+		newflags = vma->vm_flags | VM_LOCKED;
+		if (!(flags & MCL_CURRENT))
+			newflags &= ~VM_LOCKED;
+		error = mlock_fixup(vma, vma->vm_start, vma->vm_end, newflags);
+		if (error)
+			break;
+	}
+	merge_segments(current, 0, TASK_SIZE);
+	return error;
+}
+
+asmlinkage int sys_mlockall(int flags)
+{
+	unsigned long lock_limit;
+
+	if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE)))
+		return -EINVAL;
+
+	lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+	lock_limit >>= PAGE_SHIFT;
+
+	if (current->mm->total_vm > lock_limit)
+		return -ENOMEM;
+
+	/* we may lock at most half of physical memory... */
+	/* (this check is pretty bogus, but doesn't hurt) */
+	if (current->mm->total_vm > MAP_NR(high_memory)/2)
+		return -ENOMEM;
+
+	return do_mlockall(flags);
+}
+
+asmlinkage int sys_munlockall(void)
+{
+	return do_mlockall(0);
+}
diff -u --recursive --new-file v1.3.42/linux/mm/mmap.c linux/mm/mmap.c
--- v1.3.42/linux/mm/mmap.c	Fri Nov 17 08:42:29 1995
+++ linux/mm/mmap.c	Sun Nov 19 19:10:52 1995
@@ -66,6 +66,14 @@
 	if (off + len < off)
 		return -EINVAL;
 
+	/* mlock MCL_FUTURE? */
+	if (current->mm->def_flags & VM_LOCKED) {
+		unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+		locked += len;
+		if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+			return -EAGAIN;
+	}
+
 	/*
 	 * do simple checking here so the lower-level routines won't have
 	 * to. we assume access permissions have been handled by the open
@@ -127,6 +135,7 @@
 	vma->vm_end = addr + len;
 	vma->vm_flags = prot & (VM_READ | VM_WRITE | VM_EXEC);
 	vma->vm_flags |= flags & (VM_GROWSDOWN | VM_DENYWRITE | VM_EXECUTABLE);
+	vma->vm_flags |= current->mm->def_flags;
 
 	if (file) {
 		if (file->f_mode & 1)
@@ -167,6 +176,17 @@
 	}
 	insert_vm_struct(current, vma);
 	merge_segments(current, vma->vm_start, vma->vm_end);
+	current->mm->total_vm += len >> PAGE_SHIFT;
+	if (vma->vm_flags & VM_LOCKED) {
+		unsigned long start = vma->vm_start;
+		unsigned long end = vma->vm_end;
+		current->mm->locked_vm += len >> PAGE_SHIFT;
+		while (start < end) {
+			char c = get_user((char *) start);
+			__asm__ __volatile__("": :"r" (c));
+			start += PAGE_SIZE;
+		}
+	}
 	return addr;
 }
 
@@ -604,6 +624,9 @@
 		       area->vm_start, area->vm_end, addr, end);
 		return;
 	}
+	area->vm_mm->total_vm -= len >> PAGE_SHIFT;
+	if (area->vm_flags & VM_LOCKED)
+		area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
 
 	/* Unmapping the whole area */
 	if (addr == area->vm_start && end == area->vm_end) {
@@ -747,6 +770,9 @@
 	mpnt = mm->mmap;
 	mm->mmap = NULL;
 	mm->mmap_avl = NULL;
+	mm->rss = 0;
+	mm->total_vm = 0;
+	mm->locked_vm = 0;
 	while (mpnt) {
 		struct vm_area_struct * next = mpnt->vm_next;
 		if (mpnt->vm_ops) {
diff -u --recursive --new-file v1.3.42/linux/mm/swap.c linux/mm/swap.c
--- v1.3.42/linux/mm/swap.c	Wed Nov  8 07:11:43 1995
+++ linux/mm/swap.c	Fri Nov 17 15:02:45 1995
@@ -566,15 +566,10 @@
 	unsigned long end;
 
 	/* Don't swap out areas like shared memory which have their
-	    own separate swapping mechanism. */
-	if (vma->vm_flags & VM_SHM)
+	    own separate swapping mechanism or areas which are locked down */
+	if (vma->vm_flags & (VM_SHM | VM_LOCKED))
 		return 0;
 
-	/* Don't swap out areas like shared memory which have their
-           own separate swapping mechanism. */
-	if (vma->vm_flags & VM_DONTSWAP)
-		return 0;
-	
 	end = vma->vm_end;
 	while (start < end) {
 		int result = swap_out_pgd(tsk, vma, pgdir, start, end, limit);
diff -u --recursive --new-file v1.3.42/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v1.3.42/linux/net/ipv4/arp.c	Fri Nov 17 08:42:33 1995
+++ linux/net/ipv4/arp.c	Fri Nov 17 10:34:38 1995
@@ -46,6 +46,10 @@
  *		Craig Schlenter :	Don't modify permanent entry 
  *					during arp_rcv.
  *		Russ Nelson	:	Tidied up a few bits.
+ *		Alexey Kuznetsov:	Major changes to caching and behaviour,
+ *					eg intelligent arp probing and generation
+ *					of host down events.
+ *		Alan Cox	:	Missing unlock in device events.
  */
 
 /* RFC1122 Status:
@@ -70,18 +74,19 @@
 #include <linux/if_arp.h>
 #include <linux/in.h>
 #include <linux/mm.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <stdarg.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/trdevice.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+
 #include <net/ip.h>
+#include <net/icmp.h>
 #include <net/route.h>
 #include <net/protocol.h>
 #include <net/tcp.h>
-#include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/arp.h>
 #ifdef CONFIG_AX25
@@ -90,9 +95,11 @@
 #include <net/netrom.h>
 #endif
 #endif
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
 
+#include <asm/system.h>
+#include <asm/segment.h>
+
+#include <stdarg.h>
 
 /*
  *	This structure defines the ARP mapping cache. As long as we make changes
@@ -600,6 +607,7 @@
 				pentry = &entry->next;	/* go to next entry */
 		}
 	}
+	arp_unlock();
 	return NOTIFY_DONE;
 }
 
@@ -1179,6 +1187,7 @@
 				 */
 				else
 				{
+#if 0				
 					/*
 					 * FIXME: ICMP HOST UNREACHABLE should be
 					 *	  sent in this situation. --ANK
@@ -1188,6 +1197,9 @@
 						skb->sk->err = EHOSTDOWN;
 						skb->sk->error_report(skb->sk);
 					}
+#else
+					icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
+#endif										
 					dev_kfree_skb(skb, FREE_WRITE);
 				}
 			}
