diff -u --recursive --new-file v2.1.11/linux/CREDITS linux/CREDITS
--- v2.1.11/linux/CREDITS	Fri Nov 15 23:49:05 1996
+++ linux/CREDITS	Tue Nov 19 16:21:51 1996
@@ -68,7 +68,7 @@
 N: Dario Ballabio
 E: dario@milano.europe.dg.com
 D: Author and maintainer of the Ultrastor 14F/34F SCSI driver
-D: Author and maintainer of the EATA ISA/EISA SCSI driver
+D: Author and maintainer of the EATA ISA/EISA/PCI SCSI driver
 S: Data General Corporation
 S: Milano
 S: Italy
diff -u --recursive --new-file v2.1.11/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.11/linux/Documentation/Configure.help	Tue Nov 19 15:53:52 1996
+++ linux/Documentation/Configure.help	Tue Nov 19 16:21:51 1996
@@ -1395,14 +1395,14 @@
 
 UltraStor 14F/34F support
 CONFIG_SCSI_U14_34F
-  This is support for the UltraStor 14F, 24F and 34F SCSI-2 host
-  adaptor family. The source at drivers/scsi/u14-34f.c contains some
-  information about this hardware. If the driver doesn't work out of
-  the box, you may have to change some settings in
-  drivers/scsi/u14-34f.h. Read the SCSI-HOWTO, available via ftp
-  (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note
-  that there is also another driver for the same hardware: "UltraStor
-  SCSI support", below. You should only enable one of them. This
+  This is support for the UltraStor 14F and 34F SCSI-2 host adapters.
+  The source at drivers/scsi/u14-34f.c contains some information about 
+  this hardware. If the driver doesn't work out of the box, you may have 
+  to change some settings in drivers/scsi/u14-34f.c.
+  Read the SCSI-HOWTO, available via ftp (user: anonymous) at 
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that there is also another
+  driver for the same hardware: "UltraStor SCSI support", below.
+  You should enable both only if you want 24F support as well. This
   driver is also available as a module ( = code which can be inserted
   in and removed from the running kernel whenever you want). If you
   want to compile it as a module, say M here and read
@@ -1649,9 +1649,8 @@
   drivers/scsi/ultrastor.h. If you want to compile this as a module (
   = code which can be inserted in and removed from the running kernel
   whenever you want), say M here and read Documentation/modules.txt.
-  Note that there is also another driver for the same hardware:
-  "UltraStor 14F/34F support", above. You should only enable one of
-  them.
+  Note that there is also another driver for UltraStor hardware:
+  "UltraStor 14F/34F support", above.
  
 7000FASST SCSI support
 CONFIG_SCSI_7000FASST
@@ -1662,12 +1661,16 @@
   want to compile it as a module, say M here and read
   Documentation/modules.txt.
 
-EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support
+EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support
 CONFIG_SCSI_EATA
-  This driver supports all the DPT SCSI host adapters, such as
-  PM2011B/9X, PM2021A/9X, PM2012A, PM1012B, PM2022A/9X, PM2122A/9X and
-  PM2322A/9X. Note that the PM2001 is not supported by this
-  driver. You want to read the start of drivers/scsi/eata.c and the
+  This driver supports all the EATA/DMA-compliant SCSI host adapters
+  and does not need any BIOS32 or PCI BIOS service.
+  Only ISA (0x1F0, 0x170, 0x230, 0x330) and EISA (0x1C88 through 0xFC88)
+  addresses are probed. In order to detect a generic EATA PCI board you
+  can force on it any unused EISA address.
+  Note that there is also another driver for the same hardware:
+  "EATA-DMA support". You should enable only one of them.
+  You want to read the start of drivers/scsi/eata.c and the
   SCSI-HOWTO, available via ftp (user: anonymous) at
   sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to compile this
   as a module ( = code which can be inserted in and removed from the
diff -u --recursive --new-file v2.1.11/linux/Documentation/java.txt linux/Documentation/java.txt
--- v2.1.11/linux/Documentation/java.txt	Mon May 13 07:17:23 1996
+++ linux/Documentation/java.txt	Thu Nov 21 11:00:33 1996
@@ -1,4 +1,4 @@
-               Java(tm) Binary Kernel Support for Linux v1.01
+               Java(tm) Binary Kernel Support for Linux v1.02
                ----------------------------------------------
 
 Linux beats them ALL! While all other OS's are TALKING about direct
@@ -13,9 +13,9 @@
 
 		ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO
 
-	   If you install the JDK in a location other than the suggested
-	   directory of /usr/local/java, then you will need to tell the
-	   kernel where you put the Java interpreter.  
+	   If you install the JDK in a location other than /usr/bin/java,
+	   then you will need to tell the kernel where you put the Java
+	   interpreter.  
            There are two ways to do this.
            One, edit fs/binfmt_java.c file and make the needed change to 
 	   the _PATH_JAVA definition at the top of that file.  
@@ -36,6 +36,14 @@
 	   as a loadable module. If a module, load it with insmod or
 	   kerneld.
 
+	5) A caveat.  When executing a java file, the java interpreter is
+	   invoked only with the class name, not with the complete file path.
+	   Therefore it is possible that the file the shell finds with PATH
+	   is not the same file the java interpreter finds with CLASSPATH.
+	   The recommended solution is to make symbolic links from a directory
+	   in PATH to the actual class file in CLASSPATH, e.g.,
+	   /usr/local/bin/myapp -> /usr/local/java/classes/myapp.class.
+
 To test your new setup, enter in the following simple Java app, and name
 it "HelloWorld.java":
 
@@ -79,8 +87,8 @@
 	   Java Applet support, so the modified file can still be used
 	   with all known browsers.
 
-	2) If you install the JDK in a location other than the suggested
-	   directory of /usr/local/java, then you will need to tell the
+	2) If you install the applet viewer in a location other than
+	   /usr/bin/appletviewer, then you will need to tell the
 	   kernel where you put the Java appletviewer.  
            There are two ways to do this.
            One, edit fs/binfmt_java.c file and make the needed change to 
diff -u --recursive --new-file v2.1.11/linux/MAINTAINERS linux/MAINTAINERS
--- v2.1.11/linux/MAINTAINERS	Tue Nov 12 15:56:02 1996
+++ linux/MAINTAINERS	Tue Nov 19 16:21:51 1996
@@ -147,16 +147,16 @@
 W:	http://www.cyclades.com/
 S:	Supported
 
-EATA ISA/EISA SCSI DRIVER
+EATA ISA/EISA/PCI SCSI DRIVER
 P:	Dario Ballabio
 M:	dario@milano.europe.dg.com
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-scsi@vger.rutgers.edu
 S:	Maintained
 
 U14-34F SCSI DRIVER
 P:	Dario Ballabio
 M:	dario@milano.europe.dg.com
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-scsi@vger.rutgers.edu
 S:	Maintained
 
 EATA-DMA SCSI DRIVER
diff -u --recursive --new-file v2.1.11/linux/Makefile linux/Makefile
--- v2.1.11/linux/Makefile	Tue Nov 19 15:53:53 1996
+++ linux/Makefile	Fri Nov 22 17:57:58 1996
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 11
+SUBLEVEL = 12
 
 ARCH = i386
 
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/Makefile linux/arch/m68k/Makefile
--- v2.1.11/linux/arch/m68k/Makefile	Wed Sep 25 10:47:37 1996
+++ linux/arch/m68k/Makefile	Fri Nov 22 15:56:33 1996
@@ -13,26 +13,23 @@
 # Copyright (C) 1994 by Hamish Macdonald
 #
 
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
 # override top level makefile
+AS += -m68020
 ifdef CONFIG_KERNEL_ELF
-AS	= as -m68020
-LD	= ld -m m68kelf
-CC	:= $(CC)
-# set up for cross compiling
-COMPILE_ARCH = $(shell uname -m)
+LD += -m m68kelf
 ifneq ($(COMPILE_ARCH),$(ARCH))
-	CROSSDIR=/usr/$(ARCH)-linux/bin
-	CC := $(CROSSDIR)/$(CC)
-	AS := $(CROSSDIR)/$(AS)
-	LD := $(CROSSDIR)/$(LD)
-	AR := $(CROSSDIR)/$(AR)
-	NM := $(CROSSDIR)/$(NM)
-	STRIP := $(CROSSDIR)/$(STRIP)
+	# prefix for cross-compiling binaries
+	CROSS_COMPILE = m68k-linux-
 endif
 else
-AS	= /usr/m68k-linuxaout/bin/as -m68020 
-CC	:= $(CC) -pipe -b m68k-linuxaout
-LD	= ld -m m68klinux
+LD += -m m68klinux
+ifneq ($(COMPILE_ARCH),$(ARCH))
+	# prefix for cross-compiling binaries
+	CROSS_COMPILE = m68k-linuxaout-
+endif
 endif
 
 #
@@ -55,6 +52,10 @@
 
 ifdef CONFIG_OPTIMIZE_040
 CFLAGS := $(CFLAGS) -m68040
+endif
+
+ifdef CONFIG_OPTIMIZE_060
+CFLAGS := $(CFLAGS) -m68020-40 -Wa,-m68060
 endif
 
 HEAD := arch/m68k/kernel/head.o
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/amiga/amifb.c linux/arch/m68k/amiga/amifb.c
--- v2.1.11/linux/arch/m68k/amiga/amifb.c	Wed Sep 25 10:47:37 1996
+++ linux/arch/m68k/amiga/amifb.c	Fri Nov 22 15:56:33 1996
@@ -51,7 +51,7 @@
 #include <linux/config.h>
 #include <linux/interrupt.h>
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/amigahw.h>
@@ -144,7 +144,7 @@
       - hsstop:   End of horizontal synchronization pulse
       - htotal:   Last value on the line (i.e. line length = htotal+1)
       - vsstrt:   Start of vertical synchronization pulse
-      - vsstop:   Start of vertical synchronization pulse
+      - vsstop:   End of vertical synchronization pulse
       - vtotal:   Last line value (i.e. number of lines = vtotal+1)
       - hcenter:  Start of vertical retrace for interlace
 
@@ -154,7 +154,7 @@
       - hbstrt:   Start of horizontal blank
       - hbstop:   End of horizontal blank
       - vbstrt:   Start of vertical blank
-      - vbstop:   Start of vertical blank
+      - vbstop:   End of vertical blank
 
    Horizontal values are in color clock cycles (280 ns), vertical values are in
    scanlines.
@@ -1679,7 +1679,7 @@
 			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrfix));
 			if (!i) {
 				i = amiga_fb_get_fix_cursorinfo(&crsrfix, con);
-				memcpy_tofs((void *)arg, &crsrfix, sizeof(crsrfix));
+				copy_to_user((void *)arg, &crsrfix, sizeof(crsrfix));
 			}
 			return i;
 		}
@@ -1690,7 +1690,7 @@
 			if (!i) {
 				i = amiga_fb_get_var_cursorinfo(&crsrvar,
 					((struct fb_var_cursorinfo *)arg)->data, con);
-				memcpy_tofs((void *)arg, &crsrvar, sizeof(crsrvar));
+				copy_to_user((void *)arg, &crsrvar, sizeof(crsrvar));
 			}
 			return i;
 		}
@@ -1699,7 +1699,7 @@
 
 			i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrvar));
 			if (!i) {
-				memcpy_fromfs(&crsrvar, (void *)arg, sizeof(crsrvar));
+				copy_from_user(&crsrvar, (void *)arg, sizeof(crsrvar));
 				i = amiga_fb_set_var_cursorinfo(&crsrvar,
 					((struct fb_var_cursorinfo *)arg)->data, con);
 			}
@@ -1711,7 +1711,7 @@
 			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrstate));
 			if (!i) {
 				i = amiga_fb_get_cursorstate(&crsrstate, con);
-				memcpy_tofs((void *)arg, &crsrstate, sizeof(crsrstate));
+				copy_to_user((void *)arg, &crsrstate, sizeof(crsrstate));
 			}
 			return i;
 		}
@@ -1720,7 +1720,7 @@
 
 			i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrstate));
 			if (!i) {
-				memcpy_fromfs(&crsrstate, (void *)arg, sizeof(crsrstate));
+				copy_from_user(&crsrstate, (void *)arg, sizeof(crsrstate));
 				i = amiga_fb_set_cursorstate(&crsrstate, con);
 			}
 			return i;
@@ -1732,7 +1732,7 @@
 			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct amiga_fb_par));
 			if (!i) {
 				ami_get_par(&par);
-				memcpy_tofs((void *)arg, &par, sizeof(struct amiga_fb_par));
+				copy_to_user((void *)arg, &par, sizeof(struct amiga_fb_par));
 			}
 			return i;
 		}
@@ -1741,7 +1741,7 @@
 
 			i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct amiga_fb_par));
 			if (!i) {
-				memcpy_fromfs(&par, (void *)arg, sizeof(struct amiga_fb_par));
+				copy_from_user(&par, (void *)arg, sizeof(struct amiga_fb_par));
 				ami_set_par(&par);
 			}
 			return i;
@@ -2044,11 +2044,11 @@
 			if (transp)
 				*transp = htransp;
 		} else {
-			put_fs_word(hred, red);
-			put_fs_word(hgreen, green);
-			put_fs_word(hblue, blue);
+			put_user(hred, red);
+			put_user(hgreen, green);
+			put_user(hblue, blue);
 			if (transp)
-				put_fs_word(htransp, transp);
+				put_user(htransp, transp);
 		}
 		red++;
 		green++;
@@ -2081,10 +2081,13 @@
 			hblue = *blue;
 			htransp = transp ? *transp : 0;
 		} else {
-			hred = get_fs_word(red);
-			hgreen = get_fs_word(green);
-			hblue = get_fs_word(blue);
-			htransp = transp ? get_fs_word(transp) : 0;
+			get_user(hred, red);
+			get_user(hgreen, green);
+			get_user(hblue, blue);
+			if (transp)
+				get_user(htransp, transp);
+			else
+				htransp = 0;
 		}
 		hred = CNVT_TOHW(hred, var->red.length);
 		hgreen = CNVT_TOHW(hgreen, var->green.length);
@@ -2119,10 +2122,10 @@
 			memcpy(to, from, len);
 			return;
 		case 1:
-			memcpy_fromfs(to, from, len);
+			copy_from_user(to, from, len);
 			return;
 		case 2:
-			memcpy_tofs(to, from, len);
+			copy_to_user(to, from, len);
 			return;
 	}
 }
@@ -2256,7 +2259,7 @@
 }
 
 	/*
-	 * Get a Video Modes
+	 * Get a Video Mode
 	 */
 
 static void get_video_mode(const char *name)
@@ -3212,7 +3215,7 @@
 				"clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; "
 				"swap %1 ; lslw #1,%1 ; roxlb #1,%0"
 				: "=d" (color), "=d" (datawords) : "1" (datawords));
-			put_fs_byte(color, data++);
+			put_user(color, data++);
 		}
 		if (bits > 0) {
 			--words; ++lspr;
@@ -3269,10 +3272,14 @@
 	for (height = (short)var->height-1; height >= 0; height--) {
 		bits = 16; words = delta; datawords = 0;
 		for (width = (short)var->width-1; width >= 0; width--) {
+			unsigned long tdata = 0;
+			get_user(tdata, (char *)data);
+			data++;
 			asm volatile (
 				"lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; "
 				"lsrb #1,%2 ; roxlw #1,%0 ; swap %0"
-				: "=d" (datawords) : "0" (datawords), "d" ((u_long)(get_fs_byte(data++))));
+				: "=d" (datawords)
+				: "0" (datawords), "d" (tdata));
 			if (--bits == 0) {
 				bits = 16; --words;
 				asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/amiga/amiints.c linux/arch/m68k/amiga/amiints.c
--- v2.1.11/linux/arch/m68k/amiga/amiints.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/amiga/amiints.c	Fri Nov 22 15:56:33 1996
@@ -209,7 +209,7 @@
 	}
 
 	/* enable the interrupt */
-	if (irq < IRQ_IDX(IRQ_AMIGA_PORTS)) 
+	if (irq < IRQ_IDX(IRQ_AMIGA_PORTS) && !ami_ablecount[irq])
 		custom.intena = IF_SETCLR | ami_intena_vals[irq];
 
 	return 0;
@@ -264,7 +264,7 @@
 		return;
 	}
 
-	if (ami_ablecount[irq]++)
+	if (--ami_ablecount[irq])
 		return;
 
 	if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
@@ -290,7 +290,7 @@
 		return;
 	}
 
-	if (--ami_ablecount[irq])
+	if (ami_ablecount[irq]++)
 		return;
 
 	if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/amiga/cia.c linux/arch/m68k/amiga/cia.c
--- v2.1.11/linux/arch/m68k/amiga/cia.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/amiga/cia.c	Fri Nov 22 15:56:33 1996
@@ -55,7 +55,7 @@
 		base->icr_data &= ~mask;
 	if (base->icr_data & base->icr_mask)
 		custom.intreq = IF_SETCLR | base->int_mask;
-	return (old & base->icr_mask);
+	return old & base->icr_mask;
 }
 
 /*
@@ -77,12 +77,14 @@
 		base->icr_mask &= ~mask;
 	base->icr_mask &= CIA_ICR_ALL;
 	for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) {
-		if ((tmp & base->icr_mask) && !base->irq_list[i].handler)
+		if ((tmp & base->icr_mask) && !base->irq_list[i].handler) {
 			base->icr_mask &= ~tmp;
- 	}
+			base->cia->icr = tmp;
+		}
+	}
 	if (base->icr_data & base->icr_mask)
 		custom.intreq = IF_SETCLR | base->int_mask;
-	return (old);
+	return old;
 }
 
 int cia_request_irq(struct ciabase *base, unsigned int irq,
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c
--- v2.1.11/linux/arch/m68k/amiga/config.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/amiga/config.c	Fri Nov 22 15:56:33 1996
@@ -271,23 +271,21 @@
   mach_gettimeoffset   = amiga_gettimeoffset;
   if (AMIGAHW_PRESENT(A3000_CLK)){
     mach_gettod  = a3000_gettod;
-    mach_max_dma_address = 0xffffffff; /*
-					* default MAX_DMA 0xffffffff
-					* on Z3 machines - we should
-					* consider adding something
-					* like a dma_mask in kmalloc
-					* later on, so people using Z2
-					* boards in Z3 machines won't
-					* get into trouble - Jes
-					*/
   }
   else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
     mach_gettod  = a2000_gettod;
-    mach_max_dma_address = 0x00ffffff; /*
-					* default MAX_DMA 0x00ffffff
-					* on Z2 machines.
-					*/
   }
+
+  mach_max_dma_address = 0xffffffff; /*
+				      * default MAX_DMA=0xffffffff
+				      * on all machines. If we don't
+				      * do so, the SCSI code will not
+				      * be able to allocate any mem
+				      * for transfers, unless we are
+				      * dealing with a Z2 mem only
+				      * system.                  /Jes
+				      */
+
   mach_hwclk           = amiga_hwclk;
   mach_set_clock_mmss  = amiga_set_clock_mmss;
   mach_mksound         = amiga_mksound;
@@ -421,7 +419,7 @@
 	*yearp = tod->year1       * 10 + tod->year2;
 
 	if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
-		if ((!tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
+		if (!(tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
 			*hourp = 0;
 		else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12)
 			*hourp += 12;
@@ -480,7 +478,7 @@
 			t->year = tod->year1       * 10 + tod->year2;
 
 			if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
-				if ((!tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
+				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
 					t->hour = 0;
 				else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
 					t->hour += 12;
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/amiga/cyberfb.c linux/arch/m68k/amiga/cyberfb.c
--- v2.1.11/linux/arch/m68k/amiga/cyberfb.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/amiga/cyberfb.c	Fri Nov 22 15:56:34 1996
@@ -29,7 +29,7 @@
 #include <linux/tty.h>
 #include <linux/malloc.h>
 #include <linux/delay.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/zorro.h>
@@ -815,11 +815,11 @@
          if (transp)
             *transp = htransp;
       } else {
-         put_fs_word(hred, red);
-         put_fs_word(hgreen, green);
-         put_fs_word(hblue, blue);
+         put_user(hred, red);
+         put_user(hgreen, green);
+         put_user(hblue, blue);
          if (transp)
-            put_fs_word(htransp, transp);
+            put_user(htransp, transp);
       }
       red++;
       green++;
@@ -853,10 +853,13 @@
          hblue = *blue;
          htransp = transp ? *transp : 0;
       } else {
-         hred = get_fs_word(red);
-         hgreen = get_fs_word(green);
-         hblue = get_fs_word(blue);
-         htransp = transp ? get_fs_word(transp) : 0;
+         get_user(hred, red);
+         get_user(hgreen, green);
+         get_user(hblue, blue);
+	 if (transp)
+		 get_user(htransp, transp);
+	 else
+		 htransp = 0;
       }
       hred = CNVT_TOHW(hred, var->red.length);
       hgreen = CNVT_TOHW(hgreen, var->green.length);
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/amiga/ksyms.c linux/arch/m68k/amiga/ksyms.c
--- v2.1.11/linux/arch/m68k/amiga/ksyms.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/amiga/ksyms.c	Fri Nov 22 15:56:34 1996
@@ -2,6 +2,10 @@
 #include <asm/zorro.h>
 #include <asm/amigatypes.h>
 #include <asm/amigahw.h>
+#include <asm/amigatypes.h>
+
+extern volatile u_short amiga_audio_min_period;
+extern u_short amiga_audio_period;
 
 static struct symbol_table mach_amiga_symbol_table = {
 #include <linux/symtab_begin.h>
@@ -13,6 +17,8 @@
   X(amiga_chip_alloc),
   X(amiga_chip_free),
   X(amiga_chip_avail),
+  X(amiga_audio_period),
+  X(amiga_audio_min_period),
 
   X(zorro_find),
   X(zorro_get_board),
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/amiga/zorro.c linux/arch/m68k/amiga/zorro.c
--- v2.1.11/linux/arch/m68k/amiga/zorro.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/amiga/zorro.c	Fri Nov 22 15:56:34 1996
@@ -477,7 +477,7 @@
    PROD("Blizzard 1230-III Turbo Board", BLIZZARD_1230_III)
    PROD("Blizzard 1230-IV/1260 Turbo Board", BLIZZARD_1230_IV)
    PROD("Blizzard 2060 SCSI Controller", BLIZZARD_2060SCSI)
-   PROD("CyberStorm", CYBERSTORM)
+   PROD("CyberStorm Mk II", CYBERSTORM_II)
    PROD("CyberVision64 Graphics Board", CYBERVISION)
 END
 
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/atari/atafb.c linux/arch/m68k/atari/atafb.c
--- v2.1.11/linux/arch/m68k/atari/atafb.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/atari/atafb.c	Fri Nov 22 15:56:34 1996
@@ -48,7 +48,7 @@
 #include <linux/delay.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 
@@ -86,7 +86,7 @@
 
 static struct atari_fb_par {
 	unsigned long screen_base;
-	int vyres;
+	int yres_virtual;
 	union {
 		struct {
 			int mode;
@@ -366,57 +366,60 @@
 };
 
 struct fb_var_screeninfo atari_fb_predefined[] = {
+ 	/*
+ 	 * yres_virtual==0 means use hw-scrolling if possible, else yres
+ 	 */
  	{ /* autodetect */
 	  0, 0, 0, 0, 0, 0, 0, 0,   		/* xres-grayscale */
 	  {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, 	/* red green blue tran*/
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
  	{ /* st low */
-	  320, 200, 320, 200, 0, 0, 4, 0,   		/* xres-grayscale */
-	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  320, 200, 320, 0, 0, 0, 4, 0,
+	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* st mid */
-	  640, 200, 640, 200, 0, 0, 2, 0,		/* xres-grayscale */
-	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  640, 200, 640, 0, 0, 0, 2, 0,
+	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* st high */
-	  640, 400, 640, 400, 0, 0, 1, 0,		/* xres-grayscale */
-	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  640, 400, 640, 0, 0, 0, 1, 0,
+	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* tt low */
-	  320, 480, 320, 480, 0, 0, 8, 0,		/* xres-grayscale */
-	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  320, 480, 320, 0, 0, 0, 8, 0,
+	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* tt mid */
-	  640, 480, 640, 480, 0, 0, 4, 0,		/* xres-grayscale */
-	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  640, 480, 640, 0, 0, 0, 4, 0,
+	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* tt high */
-	  1280, 960, 1280, 960, 0, 0, 1, 0,		/* xres-grayscale */
-	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  1280, 960, 1280, 0, 0, 0, 1, 0,
+	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* vga2 */
-	  640, 480, 640, 480, 0, 0, 1, 0,   		/* xres-grayscale */
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  640, 480, 640, 0, 0, 0, 1, 0,
+	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* vga4 */
-	  640, 480, 640, 480, 0, 0, 2, 0,		/* xres-grayscale */
-	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  640, 480, 640, 0, 0, 0, 2, 0,
+	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* vga16 */
-	  640, 480, 640, 480, 0, 0, 4, 0,		/* xres-grayscale */
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  640, 480, 640, 0, 0, 0, 4, 0,
+	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* vga256 */
-	  640, 480, 640, 480, 0, 0, 8, 0,		/* xres-grayscale */
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  640, 480, 640, 0, 0, 0, 8, 0,
+	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* falh2 */
-	  896, 608, 896, 608, 0, 0, 1, 0,		/* xres-grayscale */
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  896, 608, 896, 0, 0, 0, 1, 0,
+	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ /* falh16 */
-	  896, 608, 896, 608, 0, 0, 4, 0,		/* xres-grayscale */
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 	/* red green blue tran*/
+	  896, 608, 896, 0, 0, 0, 4, 0,
+	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	/* Minor 14..23 free for more standard video modes */
 	{ 0, },
@@ -598,7 +601,7 @@
 		return -EINVAL;
 	if (var->yoffset + yres > yres_virtual && yres_virtual)
 		return -EINVAL;
-	par->vyres = yres_virtual;
+	par->yres_virtual = yres_virtual;
 	par->screen_base = screen_base + var->yoffset * linelen;
 	return 0;
 }
@@ -675,10 +678,10 @@
 	if (! use_hwscroll)
 		var->yres_virtual=var->yres;
 	else if (screen_len)
-		if (par->vyres)
-			var->yres_virtual = par->vyres;
+		if (par->yres_virtual)
+			var->yres_virtual = par->yres_virtual;
 		else
-			/* vyres==0 means use maximum */
+			/* yres_virtual==0 means use maximum */
 			var->yres_virtual = screen_len / linelen;
 	else {
 		if (hwscroll < 0)
@@ -811,7 +814,7 @@
 static int vdl_prescale[4][3] = {{4,2,1}, {4,2,1}, {4,2,2}, {4,2,1}};
 
 /* Default hsync timing [mon_type] in picoseconds */
-static long h_syncs[4] = {3000000, 4700000, 4000000, 4700000};
+static long h_syncs[4] = {3000000, 4875000, 4000000, 4875000};
 
 
 static inline int hxx_prescale(struct falcon_hw *hw)
@@ -929,8 +932,8 @@
 		return -EINVAL;
 	par->hw.falcon.bpp = bpp;
 
-	if (mon_type != F_MON_VGA || DontCalcRes) {
-		/* Skip all calculations, VGA multisync only yet */
+	if (mon_type == F_MON_SM || DontCalcRes) {
+		/* Skip all calculations. VGA/TV/SC1224 only supported. */
 		struct fb_var_screeninfo *myvar = &atari_fb_predefined[0];
 		
 		if (bpp > myvar->bits_per_pixel ||
@@ -941,7 +944,7 @@
 		goto set_screen_base;	/* Don't forget this */
 	}
 
-	/* Only some fixed resolutions < 640x480 */
+	/* Only some fixed resolutions < 640x400 */
 	if (xres <= 320)
 		xres = 320;
 	else if (xres <= 640 && bpp != 16)
@@ -952,8 +955,6 @@
 		yres = 240;
 	else if (yres <= 400)
 		yres = 400;
-	else if (yres <= 480)
-		yres = 480;
 
 	/* 2 planes must use STE compatibility mode */
 	par->hw.falcon.ste_mode = bpp==2;
@@ -962,6 +963,7 @@
 	/* Total and visible scanline length must be a multiple of one longword,
 	 * this and the console fontwidth yields the alignment for xres and
 	 * xres_virtual.
+	 * TODO: this way "odd" fontheights are not supported
 	 *
 	 * Special case in STE mode: blank and graphic positions don't align,
 	 * avoid trash at right margin
@@ -997,9 +999,9 @@
 	par->hw.falcon.line_offset = bpp * (xres_virtual - xres) / 16;
 
 	/* single or double pixel width */
-	xstretch = (xres == 320) ? 2 : 1;
+	xstretch = (xres < 640) ? 2 : 1;
 
-#if 0 /* currently unused */
+#if 0 /* SM124 supports only 640x400, this is rejected above */
 	if (mon_type == F_MON_SM) {
 		if (xres != 640 && yres != 400)
 			return -EINVAL;
@@ -1013,19 +1015,45 @@
 		right_margin = 0;
 		/* TODO set all margins */
 	}
-	else if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
+	else
+#endif
+	if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
 		plen = 2 * xstretch;
+		if (var->pixclock > f32.t * plen)
+			return -EINVAL;
 		pclock = &f32;
-		hsync_len = 150 / plen;
 		if (yres > 240)
 			interlace = 1;
-		/* TODO set margins */
+		if (var->pixclock == 0) {
+			/* set some minimal margins which center the screen */
+			left_margin = 32;
+			right_margin = 18;
+			hsync_len = pclock->hsync / plen;
+			upper_margin = 31;
+			lower_margin = 14;
+			vsync_len = interlace ? 3 : 4;
+		} else {
+			left_margin = var->left_margin;
+			right_margin = var->right_margin;
+			hsync_len = var->hsync_len;
+			upper_margin = var->upper_margin;
+			lower_margin = var->lower_margin;
+			vsync_len = var->vsync_len;
+			if (var->vmode & FB_VMODE_INTERLACED) {
+				upper_margin = (upper_margin + 1) / 2;
+				lower_margin = (lower_margin + 1) / 2;
+				vsync_len = (vsync_len + 1) / 2;
+			} else if (var->vmode & FB_VMODE_DOUBLE) {
+				upper_margin *= 2;
+				lower_margin *= 2;
+				vsync_len *= 2;
+			}
+		}
 	}
 	else
-#endif
 	{	/* F_MON_VGA */
 		if (bpp == 16)
-			xstretch = 2; /* hicolor only double pixel width */
+			xstretch = 2; /* Double pixel width only for hicolor */
 		/* Default values are used for vert./hor. timing if no pixelclock given. */
 		if (var->pixclock == 0) {
 			int linesize;
@@ -1079,12 +1107,20 @@
 			upper_margin = var->upper_margin;
 			lower_margin = var->lower_margin;
 			vsync_len = var->vsync_len;
+			/* Internal unit is [single lines per (half-)frame] */
 			if (var->vmode & FB_VMODE_INTERLACED) {
 				/* # lines in half frame */
+				/* External unit is [lines per full frame] */
 				upper_margin = (upper_margin + 1) / 2;
 				lower_margin = (lower_margin + 1) / 2;
 				vsync_len = (vsync_len + 1) / 2;
 			}
+			else if (var->vmode & FB_VMODE_DOUBLE) {
+				/* External unit is [double lines per frame] */
+				upper_margin *= 2;
+				lower_margin *= 2;
+				vsync_len *= 2;
+			}
 		}
 		if (pclock == &fext)
 			longoffset = 1; /* VIDEL doesn't synchronize on short offset */
@@ -1257,6 +1293,15 @@
 		lower_margin += lines;
 		goto again;
 	}
+	else if (vfreq > vfmax && doubleline) {
+		/* Doubleline too high -> enlarge margins */
+		int lines;
+		for (lines=0; (hfreq*2)/(par->VFT+1+4*lines)>vfmax; lines+=2)
+			;
+		upper_margin += lines;
+		lower_margin += lines;
+		goto again;
+	}
 	else if (vfreq > vfmax && interlace) {
 		/* Interlace, too high -> enlarge margins */
 		int lines;
@@ -1277,7 +1322,7 @@
 		return -EINVAL;
 	if (var->yoffset + yres > yres_virtual && yres_virtual)
 		return -EINVAL;
-	par->vyres = yres_virtual;
+	par->yres_virtual = yres_virtual;
 	par->screen_base = screen_base + var->yoffset * linelen;
 	par->hw.falcon.xoffset = 0;
 
@@ -1372,10 +1417,10 @@
 
 	linelen = var->xres_virtual * var->bits_per_pixel / 8;
 	if (screen_len)
-		if (par->vyres)
-			var->yres_virtual = par->vyres;
+		if (par->yres_virtual)
+			var->yres_virtual = par->yres_virtual;
 		else
-			/* vyres==0 means use maximum */
+			/* yres_virtual==0 means use maximum */
 			var->yres_virtual = screen_len / linelen;
 	else {
 		if (hwscroll < 0)
@@ -1422,6 +1467,11 @@
 		var->lower_margin *= 2;
 		var->vsync_len *= 2;
 	}
+	else if (var->vmode & FB_VMODE_DOUBLE) {
+		var->upper_margin = (var->upper_margin + 1) / 2;
+		var->lower_margin = (var->lower_margin + 1) / 2;
+		var->vsync_len = (var->vsync_len + 1) / 2;
+	}
 
 	var->pixclock *= plen;
 	var->left_margin /= plen;
@@ -1694,10 +1744,11 @@
 		break;
 	case F_MON_SC:
 	case F_MON_TV:
-		vfmin = 50;
+		/* PAL...NTSC */
+		vfmin = 49; /* not 50, since TOS defaults to 49.9x Hz */
 		vfmax = 60;
-		hfmin = 15624;
-		hfmax = 15626;
+		hfmin = 15620;
+		hfmax = 15755;
 		break;
 	}
 	/* initialize hsync-len */
@@ -1805,7 +1856,7 @@
 		return -EINVAL;
 	if (var->yoffset + yres > yres_virtual && yres_virtual)
 		return -EINVAL;
-	par->vyres = yres_virtual;
+	par->yres_virtual = yres_virtual;
 	par->screen_base=screen_base+ var->yoffset*linelen;
 	return 0;
 }
@@ -1863,10 +1914,10 @@
 	if (! use_hwscroll)
 		var->yres_virtual=var->yres;
 	else if (screen_len)
-		if (par->vyres)
-			var->yres_virtual = par->vyres;
+		if (par->yres_virtual)
+			var->yres_virtual = par->yres_virtual;
 		else
-			/* vyres==0 means use maximum */
+			/* yres_virtual==0 means use maximum */
 			var->yres_virtual = screen_len / linelen;
 	else {
 		if (hwscroll < 0)
@@ -2458,10 +2509,10 @@
 			if (transp) *transp=htransp;
 		}
 		else {
-			put_fs_word(hred, red);
-			put_fs_word(hgreen, green);
-			put_fs_word(hblue, blue);
-			if (transp) put_fs_word(htransp, transp);
+			put_user(hred, red);
+			put_user(hgreen, green);
+			put_user(hblue, blue);
+			if (transp) put_user(htransp, transp);
 		}
 		red++;
 		green++;
@@ -2494,10 +2545,13 @@
 			htransp=(transp) ? *transp : 0;
 		}
 		else {
-			hred=get_fs_word(red);
-			hgreen=get_fs_word(green);
-			hblue=get_fs_word(blue);
-			htransp=(transp)?get_fs_word(transp):0;
+			get_user(hred, red);
+			get_user(hgreen, green);
+			get_user(hblue, blue);
+			if (transp)
+				get_user(htransp, transp);
+			else
+				htransp = 0;
 		}
 		hred=CNVT_TOHW(hred,var->red.length);
 		hgreen=CNVT_TOHW(hgreen,var->green.length);
@@ -2533,10 +2587,10 @@
 		memcpy(to,from,len);
 		return;
 	case 1:
-		memcpy_fromfs(to,from,len);
+		copy_from_user(to,from,len);
 		return;
 	case 2:
-		memcpy_tofs(to,from,len);
+		copy_to_user(to,from,len);
 		return;
 	}
 }
@@ -2738,25 +2792,19 @@
 atari_fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	       unsigned long arg, int con)
 {
-	int i;
-
 	switch (cmd) {
 #ifdef FBCMD_GET_CURRENTPAR
 	case FBCMD_GET_CURRENTPAR:
-		if ((i = verify_area(VERIFY_WRITE, (void *)arg,
-							 sizeof(struct atari_fb_par))))
-			return i;
-		memcpy_tofs((void *)arg, (void *)&current_par,
-					sizeof(struct atari_fb_par));
+		if (copy_to_user((void *)arg, (void *)&current_par,
+				 sizeof(struct atari_fb_par)))
+			return -EFAULT;
 		return 0;
 #endif
 #ifdef FBCMD_SET_CURRENTPAR
 	case FBCMD_SET_CURRENTPAR:
-		if ((i = verify_area(VERIFY_READ, (void *)arg,
-							 sizeof(struct atari_fb_par))))
-			return i;
-		memcpy_fromfs((void *)&current_par, (void *)arg,
-					sizeof(struct atari_fb_par));
+		if (copy_from_user((void *)&current_par, (void *)arg,
+				   sizeof(struct atari_fb_par)))
+			return -EFAULT;
 		atari_fb_set_par(&current_par);
 		return 0;
 #endif
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/atari/ataints.c linux/arch/m68k/atari/ataints.c
--- v2.1.11/linux/arch/m68k/atari/ataints.c	Wed Oct  9 08:55:18 1996
+++ linux/arch/m68k/atari/ataints.c	Fri Nov 22 15:56:34 1996
@@ -626,7 +626,7 @@
 			for( p = (irq_node_t *)irq_handler[i].dev_id; p; p = p->next ) {
 				len += sprintf(buf+len, "%s\n", p->devname);
 				if (p->next)
-					len += sprintf( buf+len, "                  " );
+					len += sprintf( buf+len, "                    " );
 			}
 		}
 	}
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/atari/config.c linux/arch/m68k/atari/config.c
--- v2.1.11/linux/arch/m68k/atari/config.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/atari/config.c	Fri Nov 22 15:56:34 1996
@@ -514,7 +514,7 @@
 void atari_mste_gettod (int *yearp, int *monp, int *dayp,
 			int *hourp, int *minp, int *secp)
 {
-    int hr24=0;
+    int hr24=0, hour;
     struct MSTE_RTC val;
 
     mste_rtc.mode=(mste_rtc.mode | 1);
@@ -524,13 +524,14 @@
     mste_read(&val);
     *secp = val.sec_ones + val.sec_tens * 10;
     *minp = val.min_ones + val.min_tens * 10;
-    if (hr24)
-        *hourp = val.hr_ones + val.hr_tens * 10;
-    else {
-        *hourp = val.hr_ones + (val.hr_tens & 1) * 10;
-        if (val.hr_tens & 2)
-            *hourp += 12;
+    hour = val.hr_ones + val.hr_tens * 10;
+    if (!hr24) {
+        if (hour == 12 || hour == 12 + 20)
+	    hour -= 12;
+	if (hour >= 20)
+	    hour += 12 - 20;
     }
+    *hourp = hour;
     *dayp = val.day_ones + val.day_tens * 10;
     *monp = val.mon_ones + val.mon_tens * 10;
     *yearp = val.year_ones + val.year_tens * 10 + 80;	
@@ -542,33 +543,38 @@
 {
     unsigned char	ctrl;
     unsigned short tos_version;
-		
+    int hour, pm;
+
     while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ;
     while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ;
 
     *secp  = RTC_READ(RTC_SECONDS);
     *minp  = RTC_READ(RTC_MINUTES);
-    *hourp = RTC_READ(RTC_HOURS);
+    hour = RTC_READ(RTC_HOURS);
     *dayp  = RTC_READ(RTC_DAY_OF_MONTH);
     *monp  = RTC_READ(RTC_MONTH);
     *yearp = RTC_READ(RTC_YEAR);
+    pm = hour & 0x80;
+    hour &= ~0x80;
 
     ctrl = RTC_READ(RTC_CONTROL); 
 
     if (!(ctrl & RTC_DM_BINARY)) {
         BCD_TO_BIN(*secp);
         BCD_TO_BIN(*minp);
-        BCD_TO_BIN(*hourp);
+        BCD_TO_BIN(hour);
         BCD_TO_BIN(*dayp);
         BCD_TO_BIN(*monp);
         BCD_TO_BIN(*yearp);
     }
     if (!(ctrl & RTC_24H)) {
-        if (*hourp & 0x80) {
-            *hourp &= ~0x80;
-            *hourp += 12;
-        }
+	if (!pm && hour == 12)
+	    hour = 0;
+	else if (pm && hour != 12)
+            hour += 12;
     }
+    *hourp = hour;
+
     /* Adjust values (let the setup valid) */
 
     /* Fetch tos version at Physical 2 */
@@ -603,13 +609,14 @@
         val.min_ones = t->min % 10;
         val.min_tens = t->min / 10;
         hour = t->hour;
+        if (!hr24) {
+	    if (hour > 11)
+		hour += 20 - 12;
+	    if (hour == 0 || hour == 20)
+		hour += 12;
+        }
         val.hr_ones = hour % 10;
         val.hr_tens = hour / 10;
-        if (!hr24  && hour > 11) {
-            hour -= 12;
-            val.hr_ones = hour % 10;
-            val.hr_tens = (hour / 10) | 2;
-        }
         val.day_ones = t->day % 10;
         val.day_tens = t->day / 10;
         val.mon_ones = (t->mon+1) % 10;
@@ -627,13 +634,14 @@
         mste_read(&val);
         t->sec = val.sec_ones + val.sec_tens * 10;
         t->min = val.min_ones + val.min_tens * 10;
-        if (hr24)
-            t->hour = val.hr_ones + val.hr_tens * 10;
-        else {
-            t->hour = val.hr_ones + (val.hr_tens & 1) * 10;
-            if (val.hr_tens & 2)
-                t->hour += 12;
+        hour = val.hr_ones + val.hr_tens * 10;
+	if (!hr24) {
+	    if (hour == 12 || hour == 12 + 20)
+		hour -= 12;
+	    if (hour >= 20)
+                hour += 12 - 20;
         }
+	t->hour = hour;
 	t->day = val.day_ones + val.day_tens * 10;
         t->mon = val.mon_ones + val.mon_tens * 10 - 1;
         t->year = val.year_ones + val.year_tens * 10 + 80;
@@ -648,6 +656,7 @@
     unsigned long 	flags;
     unsigned short	tos_version;
     unsigned char	ctrl;
+    int pm = 0;
 
     /* Tos version at Physical 2.  See above for explanation why we
        cannot use PTOV(2).  */
@@ -667,9 +676,14 @@
         year = t->year - ((tos_version < 0x306) ? 70 : 68);
         wday = t->wday + (t->wday >= 0);
         
-        if (!(ctrl & RTC_24H) && hour > 11) {
-            hour -= 12;
-            hour |= 0x80;
+        if (!(ctrl & RTC_24H)) {
+	    if (hour > 11) {
+		pm = 0x80;
+		if (hour != 12)
+		    hour -= 12;
+	    }
+	    else if (hour == 0)
+		hour = 12;
         }
         
         if (!(ctrl & RTC_DM_BINARY)) {
@@ -716,7 +730,7 @@
     else {
         RTC_WRITE( RTC_SECONDS, sec );
         RTC_WRITE( RTC_MINUTES, min );
-        RTC_WRITE( RTC_HOURS, hour );
+        RTC_WRITE( RTC_HOURS, hour + pm);
         RTC_WRITE( RTC_DAY_OF_MONTH, day );
         RTC_WRITE( RTC_MONTH, mon );
         RTC_WRITE( RTC_YEAR, year );
@@ -728,7 +742,12 @@
     if (!op) {
         /* read: adjust values */
         
-        if (!(ctrl & RTC_DM_BINARY)) {
+        if (hour & 0x80) {
+	    hour &= ~0x80;
+	    pm = 1;
+	}
+
+	if (!(ctrl & RTC_DM_BINARY)) {
             BCD_TO_BIN(sec);
             BCD_TO_BIN(min);
             BCD_TO_BIN(hour);
@@ -739,10 +758,10 @@
         }
 
         if (!(ctrl & RTC_24H)) {
-            if (hour & 0x80) {
-                hour &= ~0x80;
-                hour += 12;
-            }
+	    if (!pm && hour == 12)
+		hour = 0;
+	    else if (pm && hour != 12)
+		hour += 12;
         }
 
         t->sec  = sec;
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/atari/joystick.c linux/arch/m68k/atari/joystick.c
--- v2.1.11/linux/arch/m68k/atari/joystick.c	Sat Mar 30 14:11:04 1996
+++ linux/arch/m68k/atari/joystick.c	Fri Nov 22 15:56:34 1996
@@ -14,7 +14,7 @@
 #include <asm/atarikb.h>
 #include <asm/atari_joystick.h>
 #include <asm/atari_mouse.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 
 #define MAJOR_NR    JOYSTICK_MAJOR
 
@@ -79,14 +79,14 @@
     return 0;
 }
 
-static int write_joystick(struct inode *inode, struct file *file,
-			  const char *buffer, int count)
+static long write_joystick(struct inode *inode, struct file *file,
+			   const char *buffer, unsigned long count)
 {
     return -EINVAL;
 }
 
-static int read_joystick(struct inode *inode, struct file *file,
-			 char *buffer, int count)
+static long read_joystick(struct inode *inode, struct file *file,
+			  char *buffer, unsigned long count)
 {
     int minor = DEVICE_NR(inode->i_rdev);
     int i;
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/atari/ksyms.c linux/arch/m68k/atari/ksyms.c
--- v2.1.11/linux/arch/m68k/atari/ksyms.c	Wed Sep 25 10:47:38 1996
+++ linux/arch/m68k/atari/ksyms.c	Fri Nov 22 15:56:34 1996
@@ -7,6 +7,8 @@
 #include <asm/atari_joystick.h>
 #include <asm/atari_stdma.h>
 
+extern void atari_microwire_cmd( int cmd );
+
 static struct symbol_table mach_atari_symbol_table = {
 #include <linux/symtab_begin.h>
 
@@ -27,6 +29,8 @@
 	X(ikbd_mouse_rel_pos),
 	X(ikbd_mouse_disable),
 
+	X(atari_microwire_cmd),
+	
 #include <linux/symtab_end.h>
 };
 
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.1.11/linux/arch/m68k/config.in	Sun Nov 10 20:12:08 1996
+++ linux/arch/m68k/config.in	Fri Nov 22 15:56:34 1996
@@ -29,12 +29,14 @@
 bool '68020 support' CONFIG_M68020
 bool '68030 support' CONFIG_M68030
 bool '68040 support' CONFIG_M68040
-if [ "$CONFIG_M68040" = "y" ]; then
-  bool 'Use 68040 specific optimizations' CONFIG_OPTIMIZE_040
-fi
 bool '68060 support' CONFIG_M68060
-if [ "$CONFIG_M68060" = "y" ]; then
-  bool 'Use 68060 specific optimizations' CONFIG_OPTIMIZE_060
+if [ "$CONFIG_M68020" = "n" -a "$CONFIG_M68030" = "n" ]; then
+  if [ "$CONFIG_M68040" = "y" -a "$CONFIG_M68060" = "n" ]; then
+    bool 'Use 68040 specific optimizations' CONFIG_OPTIMIZE_040
+  fi
+  if [ "$CONFIG_M68040" = "n" -a "$CONFIG_M68060" = "y" ]; then
+    bool 'Use 68060 specific optimizations' CONFIG_OPTIMIZE_060
+  fi
 fi
 bool 'Advanced processor options' CONFIG_ADVANCED_CPU
 if [ "$CONFIG_ADVANCED_CPU" = "y" ]; then
@@ -56,11 +58,11 @@
   bool 'Amiga ECS chipset support' CONFIG_AMIFB_ECS
   bool 'Amiga AGA chipset support' CONFIG_AMIFB_AGA
   bool 'Amiga Cybervision support' CONFIG_FB_CYBER
-  bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP
-  if [ "$CONFIG_AMIGA_GSP" = "y" ]; then
-    bool 'DMI Resolver support' CONFIG_GSP_RESOLVER
+#  bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP
+#  if [ "$CONFIG_AMIGA_GSP" = "y" ]; then
+#    bool 'DMI Resolver support' CONFIG_GSP_RESOLVER
 #    bool 'A2410 support' CONFIG_GSP_A2410
-  fi
+#  fi
 fi
 endmenu
 
@@ -82,11 +84,11 @@
 tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
-bool 'Atari ACSI support' CONFIG_ATARI_ACSI
-if [ "$CONFIG_ATARI_ACSI" = "y" ]; then
+tristate 'Atari ACSI support' CONFIG_ATARI_ACSI
+if [ "$CONFIG_ATARI_ACSI" != "n" ]; then
 comment 'Some devices (e.g. CD jukebox) support multiple LUNs'
 bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN
-bool 'Atari SLM laser printer support' CONFIG_ATARI_SLM
+dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
 fi
 fi
 
@@ -132,10 +134,13 @@
 comment 'SCSI low-level drivers'
 
 if [ "$CONFIG_AMIGA" = "y" ]; then
-bool 'A3000 WD33C93A support' CONFIG_A3000_SCSI
-bool 'A2091 WD33C93A support' CONFIG_A2091_SCSI
-bool 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
+tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI
+tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI
+tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
 bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI
+bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI
+bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI
+bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
 dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI
@@ -191,8 +196,9 @@
 mainmenu_option next_comment
 comment 'Character devices'
 
-bool 'Parallel printer support' CONFIG_PRINTER
+tristate 'Parallel printer support' CONFIG_PRINTER
 if [ "$CONFIG_AMIGA" = "y" ]; then
+  dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER
   tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
@@ -220,9 +226,9 @@
 mainmenu_option next_comment
 comment 'Sound support'
 
-bool 'Sound support' CONFIG_SOUND y
+tristate 'Sound support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
-  bool 'Amiga or Atari DMA sound support' CONFIG_DMASOUND y
+  dep_tristate 'Amiga or Atari DMA sound support' CONFIG_DMASOUND $CONFIG_SOUND
 fi
 endmenu
 
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/console/fbcon.c linux/arch/m68k/console/fbcon.c
--- v2.1.11/linux/arch/m68k/console/fbcon.c	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/console/fbcon.c	Fri Nov 22 15:56:35 1996
@@ -67,6 +67,7 @@
 #include <asm/machdep.h>
 
 #include <asm/system.h>
+#include <asm/uaccess.h>
 
 #include "../../../drivers/char/vt_kern.h"   /* vt_cons and vc_resize_con() */
 
@@ -244,7 +245,7 @@
     *    Internal routines
     */
 
-static void fbcon_setup(int con, int setcol, int cls);
+static void fbcon_setup(int con, int setcol, int init);
 static __inline__ void *mymemclear_small(void *s, size_t count);
 static __inline__ void *mymemclear(void *s, size_t count);
 static __inline__ void *mymemset(void *s, size_t count);
@@ -547,7 +548,7 @@
    if (unit)
       disp[unit] = disp[0];
    disp[unit].conp = conp;
-   fbcon_setup(unit, 1, 0);
+   fbcon_setup(unit, 1, 1);
 }
 
 
@@ -560,15 +561,16 @@
 
 static int fbcon_changevar(int con)
 {
-   fbcon_setup(con, 1, 1);
+   fbcon_setup(con, 1, 0);
    return(0);
 }
 
 
-static void fbcon_setup(int con, int setcol, int cls)
+static void fbcon_setup(int con, int setcol, int init)
 {
    struct display *p = &disp[con];
    struct vc_data *conp = p->conp;
+   int nr_rows, nr_cols;
 
    p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
 
@@ -588,8 +590,15 @@
    else
       p->scrollmode = SCROLL_YMOVE;
 
-   conp->vc_cols = p->var.xres/p->fontwidth;
-   conp->vc_rows = p->var.yres/p->fontheight;
+   nr_cols = p->var.xres/p->fontwidth;
+   nr_rows = p->var.yres/p->fontheight;
+   /* ++guenther: console.c:vc_allocate() relies on initializing vc_{cols,rows},
+    * but we must not set those if we are only resizing the console.
+    */
+   if (init) {
+      conp->vc_cols = nr_cols;
+      conp->vc_rows = nr_rows;
+   }
    p->vrows = p->var.yres_virtual/p->fontheight;
    conp->vc_can_do_color = p->var.bits_per_pixel != 1;
 
@@ -701,8 +710,8 @@
       p->bgcol = 0;
    }
 
-   if (cls)
-      vc_resize_con(conp->vc_rows, conp->vc_cols, con);
+   if (!init)
+      vc_resize_con(nr_rows, nr_cols, con);
 }
 
 
@@ -1467,6 +1476,10 @@
    int unit = conp->vc_num;
    struct display *p = &disp[unit];
 
+   /* Avoid flickering if there's no real change. */
+   if (p->cursor_x == conp->vc_x && p->cursor_y == conp->vc_y &&
+       (mode == CM_ERASE) == !cursor_on)
+      return 0;
    if (CURSOR_UNDRAWN ())
       p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
    p->cursor_x = conp->vc_x;
@@ -1752,7 +1765,7 @@
 	   
 		if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))
 			return i;
-		memcpy_fromfs( name, data, MAX_FONT_NAME );
+		copy_from_user( name, data, MAX_FONT_NAME );
 		name[sizeof(name)-1] = 0;
 		
 		if (!findsoftfont( name, &w, &h, (u_char **)&data ))
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/defconfig linux/arch/m68k/defconfig
--- v2.1.11/linux/arch/m68k/defconfig	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/defconfig	Fri Nov 22 15:56:35 1996
@@ -27,8 +27,8 @@
 CONFIG_M68020=y
 CONFIG_M68030=y
 CONFIG_M68040=y
-# CONFIG_OPTIMIZE_040 is not set
 # CONFIG_M68060 is not set
+# CONFIG_OPTIMIZE_040 is not set
 # CONFIG_OPTIMIZE_060 is not set
 # CONFIG_ADVANCED_CPU is not set
 # CONFIG_RMW_INSNS is not set
@@ -56,6 +56,10 @@
 CONFIG_BLK_DEV_FD=y
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_IDE is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_AMIGA_Z2RAM is not set
 # CONFIG_ATARI_ACSI is not set
 # CONFIG_ACSI_MULTI_LUN is not set
@@ -87,6 +91,7 @@
 # CONFIG_TCP_NAGLE_OFF is not set
 CONFIG_IP_NOSR=y
 # CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
 
 #
 #  
@@ -122,7 +127,10 @@
 # CONFIG_A2091_SCSI is not set
 # CONFIG_GVP11_SCSI is not set
 # CONFIG_CYBERSTORM_SCSI is not set
-# CONFIG_ATARI_SCSI is not set
+# CONFIG_CYBERSTORMII_SCSI is not set
+# CONFIG_BLZ2060_SCSI is not set
+# CONFIG_BLZ1230_SCSI is not set
+CONFIG_ATARI_SCSI=y
 
 #
 # Network device support
@@ -142,7 +150,6 @@
 # Filesystems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_LOCK_MANDATORY is not set
 CONFIG_MINIX_FS=y
 # CONFIG_EXT_FS is not set
 CONFIG_EXT2_FS=y
@@ -151,6 +158,7 @@
 CONFIG_MSDOS_FS=y
 # CONFIG_VFAT_FS is not set
 # CONFIG_UMSDOS_FS is not set
+# CONFIG_MSDOS_PARTITION is not set
 CONFIG_PROC_FS=y
 CONFIG_NFS_FS=y
 # CONFIG_ROOT_NFS is not set
@@ -166,7 +174,7 @@
 #
 # CONFIG_PRINTER is not set
 CONFIG_AMIGAMOUSE=y
-# CONFIG_ATARIMOUSE is not set
+CONFIG_ATARIMOUSE=y
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 # CONFIG_GVPIOEXT is not set
 # CONFIG_MULTIFACE_III_TTY is not set
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/console.c linux/arch/m68k/kernel/console.c
--- v2.1.11/linux/arch/m68k/kernel/console.c	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/console.c	Fri Nov 22 15:56:35 1996
@@ -119,7 +119,7 @@
 #include <linux/ioport.h>
 
 #include <asm/io.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 
@@ -1134,7 +1134,7 @@
 				if (on_off)
 					set_kbd(decckm);
 				else
-					clr_kbd(decckm); 
+					clr_kbd(decckm);
 				break;
 			case 3:	/* 80/132 mode switch unimplemented */
 				deccolm = on_off;
@@ -1371,7 +1371,7 @@
 	need_wrap = 0;
 }
 
-enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, 
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
 	EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
 	ESpalette };
 
@@ -1457,8 +1457,18 @@
 	set_leds();
 }
 
-static int con_write(struct tty_struct * tty, int from_user,
-		     const unsigned char *buf, int count)
+static void con_flush_chars(struct tty_struct *tty)
+{
+	unsigned int currcons;
+	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+	currcons = vt->vc_num;
+	if (vcmode != KD_GRAPHICS)
+		set_cursor(currcons);
+}	
+
+static int do_con_write(struct tty_struct * tty, int from_user,
+			const unsigned char *buf, int count)
 {
 	int c, tc, ok, n = 0;
 	unsigned int currcons;
@@ -1486,7 +1496,10 @@
         disable_bh(CONSOLE_BH);
 	while (count) {
 		enable_bh(CONSOLE_BH);
-		c = from_user ? get_user(buf) : *buf;
+		if (from_user)
+			get_user(c, buf);
+		else
+			c = *buf;
 		buf++; n++; count--;
 		disable_bh(CONSOLE_BH);
 
@@ -1541,7 +1554,8 @@
                 ok = tc && (c >= 32 ||
                             (!utf && !(((disp_ctrl ? CTRL_ALWAYS
                                          : CTRL_ACTION) >> c) & 1)))
-                        && (c != 127 || disp_ctrl);
+                        && (c != 127 || disp_ctrl)
+			&& (c != 128+27);
 
 		if (vc_state == ESnormal && ok) {
 			/* Now try to find out how to display it */
@@ -1561,7 +1575,7 @@
 				cr(currcons);
 				lf(currcons);
 			}
-			
+
 #if 1 /* XXX */
                         /* DPC: 1994-04-12
                          *   Speed up overstrike mode, using new putcs.
@@ -1581,7 +1595,7 @@
 
 				*p++ = tc;
 				*pos++ = tc | (attr << 8);
-				
+
 				if (nextx == cols) {
 					sw->con_putc(vc_cons[currcons].d,
 						     *putcs_buf, y, x);
@@ -1591,11 +1605,14 @@
 				}
 				
 				/* TAB TAB TAB - Arghh!!!! */
-				
+
 				while (count)
 				{
 					enable_bh(CONSOLE_BH);
-					c = from_user ? get_user(buf) : *buf;
+					if (from_user)
+						get_user(c, buf);
+					else
+						c = *buf;
 					disable_bh(CONSOLE_BH);
 					tc = translate[toggle_meta ? (c|0x80) : c];
 					if (!tc ||
@@ -1655,6 +1672,8 @@
 		 *  of an escape sequence.
 		 */
 		switch (c) {
+		    case 0:
+			continue;
 		    case 7:
 			if (bell_duration)
 			    kd_mksound(bell_pitch, bell_duration);
@@ -2000,12 +2019,26 @@
 			vc_state = ESnormal;
 		}
 	}
-	if (vcmode != KD_GRAPHICS)
-		set_cursor(currcons);
 	enable_bh(CONSOLE_BH);
 	return n;
 }
 
+static int con_write(struct tty_struct * tty, int from_user,
+		     const unsigned char *buf, int count)
+{
+	int	retval;
+	
+	retval = do_con_write(tty, from_user, buf, count);
+	con_flush_chars(tty);
+	
+	return retval;
+}
+
+static void con_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	do_con_write(tty, 0, &ch, 1);
+}
+
 static int con_write_room(struct tty_struct *tty)
 {
 	if (tty->stopped)
@@ -2208,6 +2241,8 @@
 	console_driver.open = con_open;
 	console_driver.write = con_write;
 	console_driver.write_room = con_write_room;
+	console_driver.put_char = con_put_char;
+	console_driver.flush_chars = con_flush_chars;
 	console_driver.chars_in_buffer = con_chars_in_buffer;
 	console_driver.ioctl = vt_ioctl;
 	console_driver.stop = con_stop;
@@ -2474,12 +2509,7 @@
 	int i, unit, size;
 	char *charmap;
 
-	if (arg){
-		i = verify_area(set ? VERIFY_READ : VERIFY_WRITE,
-				(void *)arg, ch512 ? 2*cmapsz : cmapsz);
-		if (i)
-			return i;
-	}else
+	if (!arg)
 		return -EINVAL;
 
 
@@ -2488,7 +2518,10 @@
 	charmap = (char *)kmalloc(size, GFP_USER);
 
 	if (set){
-		memcpy_fromfs(charmap, arg, size);
+		if (copy_from_user(charmap, arg, size)) {
+			kfree(charmap);
+			return -EFAULT;
+		}
 
 		for (unit = 32; unit > 0; unit--)
 			for (i = 0; i < (ch512 ? 512 : 256); i++)
@@ -2501,7 +2534,8 @@
 		memset(charmap, 0, size);
 		i = conswitchp->con_get_font(vc_cons[fg_console].d,
 					     &unit, &unit, charmap);
-		memcpy_tofs(arg, charmap, size);
+		if (i == 0 && copy_to_user(arg, charmap, size))
+			i = -EFAULT;
 	}
 	kfree(charmap);
 
@@ -2572,7 +2606,8 @@
 void set_vesa_blanking(int arg)
 {
 	char *argp = (char *)arg + 1;
-	unsigned int mode = get_fs_byte(argp);
+	unsigned int mode;
+	get_user(mode, argp);
 	vesa_blank_mode = (mode < 4) ? mode : 0;
 }
 
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S
--- v2.1.11/linux/arch/m68k/kernel/entry.S	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/entry.S	Fri Nov 22 15:56:35 1996
@@ -319,8 +319,8 @@
 LTSS_USP	= 4
 LTSS_SR		= 8
 LTSS_FS		= 10
-LTSS_CRP	= 20
-LTSS_FPCTXT	= 32
+LTSS_CRP	= 12
+LTSS_FPCTXT	= 24
 
 SYMBOL_NAME_LABEL(resume)
 	/*
@@ -401,7 +401,7 @@
 	movec	%cacr,%d0
 	oriw	#LFLUSH_I_AND_D,%d0
 	movec	%d0,%cacr
-
+	
 	/* switch the root pointer */
 	pmove	%a1@(LTSS_CRP),%crp
 #endif
@@ -643,4 +643,6 @@
 	.long SYMBOL_NAME(sys_sched_rr_get_interval)
 	.long SYMBOL_NAME(sys_nanosleep)
 	.long SYMBOL_NAME(sys_mremap)
-	.space (NR_syscalls-163)*4
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.space (NR_syscalls-165)*4
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/head.S linux/arch/m68k/kernel/head.S
--- v2.1.11/linux/arch/m68k/kernel/head.S	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/head.S	Fri Nov 22 15:56:35 1996
@@ -319,7 +319,7 @@
 	lea	%pc@(SYMBOL_NAME(kpt)),%a1
 	movel	%a3,%a1@		/* save address of page table */
 	movel	%a3,%a1
-	addql	#_PAGE_TABLE,%a1	/* descriptor type */
+	addw	#_PAGE_TABLE+_PAGE_ACCESSED,%a1	/* descriptor type */
 	movel	#PAGE_TABLE_SIZE<<2,%d2 /* increment */
 
 2:	movel	%a1,%a0@+
@@ -341,7 +341,7 @@
 
 	movel	%a3,%a0
 	movel	%d5,%a1
-	addw	#_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT,%a1
+	addw	#_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
 	movew	#(PAGE_TABLE_SIZE*TABLENR_4MB)-1,%d1
 	movel	#PAGESIZE,%d2
 1:	movel	%a1,%a0@+
@@ -404,7 +404,7 @@
 
 	putc('I')
 
-	moveq	#_PAGE_NOCACHE030+_PAGE_PRESENT,%d0
+	movel	#_PAGE_NOCACHE030+_PAGE_PRESENT+_PAGE_ACCESSED,%d0
 	movel	%d0,%a5@(0x40<<2)
 
 	jra	Lmapphys
@@ -431,7 +431,7 @@
 	/* initialize the pointer table */
 	movel	%a4,%a0
 	movel	%a3,%a1
-	addql	#_PAGE_TABLE,%a1	/* base descriptor */
+	addw	#_PAGE_TABLE+_PAGE_ACCESSED,%a1	/* base descriptor */
 	movel	#PAGE_TABLE_SIZE<<2,%d2 /* increment */
 	moveq	#TABLENR_16MB-1,%d1
 
@@ -441,7 +441,7 @@
 
 	/* ensure that the root table points to the pointer table */
 	movel	%a4,%a0
-	addql	#_PAGE_TABLE,%a0
+	addw	#_PAGE_TABLE+_PAGE_ACCESSED,%a0
 	movel	%a0,%a5@(0x40<<2)
 
 	/*
@@ -449,7 +449,7 @@
 	 * descriptor bits include noncachable/serialized and global bits.
 	 */
 	movel	%a3,%a0
-	movew	#_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT,%a1
+	movew	#_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
 	movel	#PAGESIZE,%d2
 	movew	#(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
 
@@ -518,7 +518,7 @@
 	/* Let the root table point to the new pointer table */
 	lea	%a4@(PTR_TABLE_SIZE<<2),%a4
 	movel	%a4,%a0
-	addl	#_PAGE_TABLE,%a0
+	addw	#_PAGE_TABLE+_PAGE_ACCESSED,%a0
 	movel	%a0,%a5@(0x7f<<2)       /* 0xFE000000 - 0xFFFFFFFF */
 
 	/* clear lower half of the pointer table (0xfexxxxxx) */
@@ -534,7 +534,7 @@
 	movel	#PAGE_TABLE_SIZE*PAGESIZE,%d1
 	movel	#(PTR_TABLE_SIZE/2)-1,%d2
 	movel	%d3,%d0
-	addl	#_PAGE_PRESENT,%d0
+	orw	#_PAGE_PRESENT+_PAGE_ACCESSED,%d0
 1:	movel	%d0,%a0@+
 	addl	%d1,%d0
 	dbra	%d2,1b
@@ -552,7 +552,7 @@
 
 	/* Initialize the upper half of the pointer table (a0 is still valid) */
 	movel	%a3,%a1
-	addql	#_PAGE_TABLE,%a1
+	addw	#_PAGE_TABLE+_PAGE_ACCESSED,%a1
 	movel	#PAGE_TABLE_SIZE<<2,%d2
 	moveq	#TABLENR_16MB-1,%d1
 1:	movel	%a1,%a0@+
@@ -562,7 +562,7 @@
 	/* Initialize the page tables as noncacheable/serialized! */
 	movel	%a3,%a0
 	movel	%d3,%a1
-	addw	#_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT,%a1
+	addw	#_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
 	movel	#PAGESIZE,%d2
 	movew	#(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
 1:	movel	%a1,%a0@+
@@ -629,7 +629,7 @@
 	lsrl	%d2,%d0
 	movel	%d0,%d1
 	lsll	%d2,%d1
-	addql	#_PAGE_PRESENT,%d1
+	orw	#_PAGE_PRESENT+_PAGE_ACCESSED,%d1
 	lsll	#2,%d0
 	movel	%a5@(%d0:w),%d2
 	movel	%d1,%a5@(%d0:w)
@@ -722,7 +722,7 @@
 	lsrl	%d0,%d1
 	lea	%a1@(%d1:l:4),%a1
 	movel	%d5,%d1
-	addql	#_PAGE_PRESENT,%d1
+	orw	#_PAGE_PRESENT+_PAGE_ACCESSED,%d1
 	movel	%a1@,%d2
 	movel	%d1,%a1@
 	lea	5f:w,%a0
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/ksyms.c linux/arch/m68k/kernel/ksyms.c
--- v2.1.11/linux/arch/m68k/kernel/ksyms.c	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/ksyms.c	Fri Nov 22 15:56:35 1996
@@ -40,12 +40,14 @@
 	X(cache_clear),
 	X(mm_vtop),
 	X(mm_ptov),
+	X(mm_end_of_chunk),
 	X(m68k_debug_device),
 	X(request_irq),
 	X(free_irq),
 	X(dump_fpu),
 	X(dump_thread),
 	X(strnlen),
+	X(strrchr),
 
 	/* The following are special because they're not called
 	   explicitly (the C compiler generates them).  Fortunately,
@@ -55,8 +57,8 @@
 	XNOVERS(memcpy),
 	XNOVERS(memset),
 
-	XNOVERS(down_failed),
-	XNOVERS(up_wakeup),
+	XNOVERS(__down_failed),
+	XNOVERS(__up_wakeup),
 
 #include <linux/symtab_end.h>
 };
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- v2.1.11/linux/arch/m68k/kernel/process.c	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/process.c	Fri Nov 22 15:56:35 1996
@@ -21,7 +21,7 @@
 #include <linux/user.h>
 #include <linux/a.out.h>
 
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/machdep.h>
@@ -172,6 +172,8 @@
  */
 void dump_thread(struct pt_regs * regs, struct user * dump)
 {
+	struct switch_stack *sw;
+
 /* changed the size calculations - should hopefully work better. lbt */
 	dump->magic = CMAGIC;
 	dump->start_code = 0;
@@ -186,8 +188,27 @@
 		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
 
 	dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump)));
-	dump->regs = *regs;
-	dump->regs2 = ((struct switch_stack *)regs)[-1];
+	sw = ((struct switch_stack *)regs) - 1;
+	dump->regs.d1 = regs->d1;
+	dump->regs.d2 = regs->d2;
+	dump->regs.d3 = regs->d3;
+	dump->regs.d4 = regs->d4;
+	dump->regs.d5 = regs->d5;
+	dump->regs.d6 = sw->d6;
+	dump->regs.d7 = sw->d7;
+	dump->regs.a0 = regs->a0;
+	dump->regs.a1 = regs->a1;
+	dump->regs.a2 = sw->a2;
+	dump->regs.a3 = sw->a3;
+	dump->regs.a4 = sw->a4;
+	dump->regs.a5 = sw->a5;
+	dump->regs.a6 = sw->a6;
+	dump->regs.d0 = regs->d0;
+	dump->regs.orig_d0 = regs->orig_d0;
+	dump->regs.stkadj = regs->stkadj;
+	dump->regs.sr = regs->sr;
+	dump->regs.pc = regs->pc;
+	dump->regs.fmtvec = (regs->format << 12) | regs->vector;
 	/* dump floating point stuff */
 	dump->u_fpvalid = dump_fpu (&dump->m68kfp);
 }
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- v2.1.11/linux/arch/m68k/kernel/ptrace.c	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/ptrace.c	Fri Nov 22 15:56:35 1996
@@ -18,7 +18,7 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -140,7 +140,7 @@
 	}
 	page = pte_page(*pgtable);
 /* this is a hack for non-kernel-mapped video buffers and similar */
-	if (page >= high_memory)
+	if (MAP_NR(page) >= max_mapnr)
 		return 0;
 	page += addr & ~PAGE_MASK;
 	return *(unsigned long *) page;
@@ -196,7 +196,7 @@
 		goto repeat;
 	}
 /* this is a hack for non-kernel-mapped video buffers and similar */
-	if (page < high_memory) {
+	if (MAP_NR(page) < max_mapnr) {
 		*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
 		flush_page_to_ram (page);
 	}
@@ -380,24 +380,16 @@
 			res = read_long(child, addr, &tmp);
 			if (res < 0)
 				return res;
-			res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
-			if (!res)
-				put_user(tmp, (unsigned long *) data);
-			return res;
+			return put_user(tmp, (unsigned long *) data);
 		}
 
 	/* read the word at location addr in the USER area. */
 		case PTRACE_PEEKUSR: {
 			unsigned long tmp;
-			int res;
 			
 			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
 				return -EIO;
 			
-			res = verify_area(VERIFY_WRITE, (void *) data,
-					  sizeof(long));
-			if (res)
-				return res;
 			tmp = 0;  /* Default return condition */
 			addr = addr >> 2; /* temporary hack. */
 			if (addr < 19) {
@@ -409,8 +401,7 @@
 				tmp = child->tss.fp[addr - 21];
 			else
 				return -EIO;
-			put_user(tmp,(unsigned long *) data);
-			return 0;
+			return put_user(tmp,(unsigned long *) data);
 		}
 
       /* when I and D space are separate, this will have to be fixed. */
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/signal.c linux/arch/m68k/kernel/signal.c
--- v2.1.11/linux/arch/m68k/kernel/signal.c	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/signal.c	Fri Nov 22 15:56:35 1996
@@ -32,7 +32,7 @@
 #include <linux/unistd.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/traps.h>
 
@@ -45,7 +45,7 @@
 asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
 asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs);
 
-static const int extra_sizes[16] = {
+const int frame_extra_sizes[16] = {
   0,
   -1, /* sizeof(((struct frame *)0)->un.fmt1), */
   sizeof(((struct frame *)0)->un.fmt2),
@@ -86,7 +86,7 @@
 
 asmlinkage int do_sigreturn(unsigned long __unused)
 {
-	struct sigcontext_struct context;
+	struct sigcontext context;
 	struct pt_regs *regs;
 	struct switch_stack *sw;
 	int fsize = 0;
@@ -103,10 +103,8 @@
 	regs = (struct pt_regs *) (sw + 1);
 
 	/* get previous context (including pointer to possible extra junk) */
-        if (verify_area(VERIFY_READ, (void *)usp, sizeof(context)))
-                goto badframe;
-
-	memcpy_fromfs(&context,(void *)usp, sizeof(context));
+	if (copy_from_user(&context,(void *)usp, sizeof(context)))
+		goto badframe;
 
 	fp = usp + sizeof (context);
 
@@ -163,7 +161,7 @@
 	  }
 	__asm__ volatile ("frestore %0" : : "m" (*context.sc_fpstate));
 
-	fsize = extra_sizes[regs->format];
+	fsize = frame_extra_sizes[regs->format];
 	if (fsize < 0) {
 		/*
 		 * user process trying to return with weird frame format
@@ -182,31 +180,37 @@
 	 */
 
 	if (fsize) {
-		if (verify_area(VERIFY_READ, (void *)fp, fsize))
-                        goto badframe;
-
 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
 		__asm__ __volatile__
-			("movel %0,%/a0\n\t"
-			 "subl %1,%/a0\n\t"     /* make room on stack */
-			 "movel %/a0,%/sp\n\t"  /* set stack pointer */
+			("   movel %0,%/a0\n\t"
+			 "   subl %1,%/a0\n\t"     /* make room on stack */
+			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
 			 /* move switch_stack and pt_regs */
 			 "1: movel %0@+,%/a0@+\n\t"
 			 "   dbra %2,1b\n\t"
-			 "lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt stuff */
-			 "lsrl  #2,%1\n\t"
-			 "subql #1,%1\n\t"
+			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+			 "   lsrl  #2,%1\n\t"
+			 "   subql #1,%1\n\t"
 			 "2: movesl %4@+,%2\n\t"
-			 "   movel %2,%/a0@+\n\t"
+			 "3: movel %2,%/a0@+\n\t"
 			 "   dbra %1,2b\n\t"
-			 "bral " SYMBOL_NAME_STR(ret_from_signal)
+			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
+			 "4:\n"
+			 ".section __ex_table,\"a\"\n"
+			 "   .align 4\n"
+			 "   .long 2b,4b\n"
+			 "   .long 3b,4b\n"
+			 ".text"
 			 : /* no outputs, it doesn't ever return */
 			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
 			   "n" (frame_offset), "a" (fp)
 			 : "a0");
 #undef frame_offset
+		/*
+		 * If we ever get here an exception occured while
+		 * building the above stack-frame.
+		 */
 		goto badframe;
-		/* NOTREACHED */
 	}
 
 	return regs->d0;
@@ -255,14 +259,14 @@
  * longwords for format "B".
  */
 
-#define UFRAME_SIZE(fs) (sizeof(struct sigcontext_struct)/4 + 6 + fs/4)
+#define UFRAME_SIZE(fs) (sizeof(struct sigcontext)/4 + 6 + fs/4)
 
 static void setup_frame (struct sigaction * sa, struct pt_regs *regs,
 			 int signr, unsigned long oldmask)
 {
-	struct sigcontext_struct context;
+	struct sigcontext context;
 	unsigned long *frame, *tframe;
-	int fsize = extra_sizes[regs->format];
+	int fsize = frame_extra_sizes[regs->format];
 
 	if (fsize < 0) {
 		printk ("setup_frame: Unknown frame format %#x\n",
@@ -277,10 +281,9 @@
 	}
 	frame -= UFRAME_SIZE(fsize);
 
-	if (verify_area(VERIFY_WRITE,frame,UFRAME_SIZE(fsize)*4))
-		do_exit(SIGSEGV);
 	if (fsize) {
-		memcpy_tofs (frame + UFRAME_SIZE(0), regs + 1, fsize);
+		if (copy_to_user (frame + UFRAME_SIZE(0), regs + 1, fsize))
+			do_exit(SIGSEGV);
 		regs->stkadj = fsize;
 	}
 
@@ -326,7 +329,8 @@
 				  "m" (*context.sc_fpcntl)
 				  : "memory");
 	}
-	memcpy_tofs (tframe, &context, sizeof(context));
+	if (copy_to_user (tframe, &context, sizeof(context)))
+		do_exit(SIGSEGV);
 
 	/*
 	 * no matter what frame format we were using before, we
@@ -440,7 +444,7 @@
 			       isn't restarted (only needed on the
 			       68030).  */
 			    if (regs->format == 10 || regs->format == 11) {
-				regs->stkadj = extra_sizes[regs->format];
+				regs->stkadj = frame_extra_sizes[regs->format];
 				regs->format = 0;
 			    }
 			    continue;
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/sys_m68k.c linux/arch/m68k/kernel/sys_m68k.c
--- v2.1.11/linux/arch/m68k/kernel/sys_m68k.c	Wed Sep 25 10:47:39 1996
+++ linux/arch/m68k/kernel/sys_m68k.c	Fri Nov 22 15:56:35 1996
@@ -14,11 +14,13 @@
 #include <linux/shm.h>
 #include <linux/stat.h>
 #include <linux/mman.h>
+#include <linux/file.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/cachectl.h>
 #include <asm/traps.h>
+#include <asm/ipc.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -47,47 +49,50 @@
  * used a memory block for parameter passing..
  */
 
-asmlinkage int old_mmap(unsigned long *buffer)
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
 {
 	int error;
-	unsigned long flags;
 	struct file * file = NULL;
+	struct mmap_arg_struct a;
 
-	error = verify_area(VERIFY_READ, buffer, 6*sizeof(long));
+	error = verify_area(VERIFY_READ, arg, sizeof(*arg));
 	if (error)
 		return error;
-	flags = get_user(buffer+3);
-	if (!(flags & MAP_ANONYMOUS)) {
-		unsigned long fd = get_user(buffer+4);
-		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+	copy_from_user(&a, arg, sizeof(a));
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd]))
 			return -EBADF;
 	}
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	return do_mmap(file, get_user(buffer), get_user(buffer+1),
-		       get_user(buffer+2), flags, get_user(buffer+5));
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+	return error;
 }
 
 
 extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 
-asmlinkage int old_select(unsigned long *buffer)
-{
-	int n;
-	fd_set *inp;
-	fd_set *outp;
-	fd_set *exp;
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
 	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
 
-	n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
-	if (n)
-	  return n;
-
-	n = get_user(buffer);
-	inp = (fd_set *) get_user(buffer+1);
-	outp = (fd_set *) get_user(buffer+2);
-	exp = (fd_set *) get_user(buffer+3);
-	tvp = (struct timeval *) get_user(buffer+4);
-	return sys_select(n, inp, outp, exp, tvp);
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
 }
 
 /*
@@ -115,7 +120,7 @@
 				return -EINVAL;
 			if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
 				return err;
-			fourth.__pad = get_user((void **)ptr);
+			get_user(fourth.__pad, (void **)ptr);
 			return sys_semctl (first, second, third, fourth);
 			}
 		default:
@@ -130,13 +135,10 @@
 			switch (version) {
 			case 0: {
 				struct ipc_kludge tmp;
-				int err;
 				if (!ptr)
 					return -EINVAL;
-				if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
-					return err;
-				memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
-					       sizeof (tmp));
+				if (copy_from_user (&tmp, ptr, sizeof (tmp)))
+					return -EFAULT;
 				return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
 				}
 			case 1: default:
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/time.c linux/arch/m68k/kernel/time.c
--- v2.1.11/linux/arch/m68k/kernel/time.c	Wed Sep 25 10:47:40 1996
+++ linux/arch/m68k/kernel/time.c	Fri Nov 22 15:56:35 1996
@@ -15,7 +15,6 @@
 #include <linux/mm.h>
 
 #include <asm/machdep.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 
 #include <linux/timex.h>
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/kernel/traps.c linux/arch/m68k/kernel/traps.c
--- v2.1.11/linux/arch/m68k/kernel/traps.c	Wed Sep 25 10:47:40 1996
+++ linux/arch/m68k/kernel/traps.c	Fri Nov 22 15:56:35 1996
@@ -30,7 +30,7 @@
 
 #include <asm/setup.h>
 #include <asm/system.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/traps.h>
 #include <asm/pgtable.h>
 #include <asm/machdep.h>
@@ -96,7 +96,6 @@
 		vectors[VEC_FPNAN] = snan_vec;
 		vectors[VEC_FPOE] = operr_vec;
 		vectors[VEC_FPBRUC] = bsun_vec;
-		vectors[VEC_FPBRUC] = bsun_vec;
 		vectors[VEC_LINE11] = fline_vec;
 		vectors[VEC_FPUNSUP] = unsupp_vec;
 	}
@@ -159,7 +158,11 @@
 	"SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
 	"TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
 	"TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
-	"TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15"
+	"TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
+	"FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
+	"FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
+	"FPCP UNSUPPORTED OPERATION",
+	"MMU CONFIGUATION ERROR"
 	};
 
 char *space_names[] = {
@@ -205,7 +208,7 @@
 #endif
 		if (fslw & MMU060_MA)
 			addr = PAGE_ALIGN(addr);
-		do_page_fault( (struct pt_regs *)fp, addr, errorcode );
+		do_page_fault(&fp->ptregs, addr, errorcode);
 	}
 	else {
 		printk( "68060 access error, fslw=%lx\n", fslw );
@@ -263,20 +266,20 @@
 
 	mmusr = probe040 (1, wbs & WBTM_040,  wba);
 	errorcode = (mmusr & MMU_R_040) ? 3 : 2;
-	if (do_page_fault ((struct pt_regs *)fp, wba, errorcode))
+	if (do_page_fault (&fp->ptregs, wba, errorcode))
 	  /* just return if we can't perform the writeback */
 	  return;
 
 	set_fs (wbs & WBTM_040);
 	switch (wbs & WBSIZ_040) {
 	    case BA_SIZE_BYTE:
-		put_fs_byte (wbd & 0xff, (char *)wba);
+		put_user (wbd & 0xff, (char *)wba);
 		break;
 	    case BA_SIZE_WORD:
-		put_fs_word (wbd & 0xffff, (short *)wba);
+		put_user (wbd & 0xffff, (short *)wba);
 		break;
 	    case BA_SIZE_LONG:
-		put_fs_long (wbd, (int *)wba);
+		put_user (wbd, (int *)wba);
 		break;
 	}
 	set_fs (fs);
@@ -317,7 +320,7 @@
 */
 		errorcode = ((mmusr & MMU_R_040) ? 1 : 0) |
 			((ssw & RW_040) ? 0 : 2);
-		do_page_fault ((struct pt_regs *)fp, addr, errorcode);
+		do_page_fault (&fp->ptregs, addr, errorcode);
 	} else {
 		printk ("68040 access error, ssw=%x\n", ssw);
 		trap_c (fp);
@@ -394,8 +397,8 @@
 			}
 			printk ("BAD KERNEL BUSERR\n");
 			die_if_kernel("Oops",&fp->ptregs,0);
-			force_sig(SIGSEGV, current);
-			user_space_fault = 0;
+			force_sig(SIGKILL, current);
+			return;
 		}
 	} else {
 		/* user fault */
@@ -442,9 +445,12 @@
 	    if (!(ssw & RW) || ssw & RM)
 		    errorcode |= 2;
 
-	    if (mmusr & (MMU_I | MMU_WP))
-		    do_page_fault ((struct pt_regs *)fp, addr, errorcode);
-	    else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
+	    if (mmusr & (MMU_I | MMU_WP)) {
+		/* Don't try to do anything further if an exception was
+		   handled. */
+		if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
+			return;
+	    } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
 		    printk ("invalid %s access at %#lx from pc %#lx\n",
 			    !(ssw & RW) ? "write" : "read", addr,
 			    fp->ptregs.pc);
@@ -572,7 +578,7 @@
 #endif
 
 	if (mmusr & MMU_I)
-		do_page_fault ((struct pt_regs *)fp, addr, 0);
+		do_page_fault (&fp->ptregs, addr, 0);
 	else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
 		printk ("invalid insn access at %#lx from pc %#lx\n",
 			addr, fp->ptregs.pc);
@@ -733,18 +739,18 @@
 	stack = (unsigned long *)addr;
 	endstack = (unsigned long *)PAGE_ALIGN(addr);
 
-	printk("Stack from %08lx:\n       ", (unsigned long)stack);
+	printk("Stack from %08lx:", (unsigned long)stack);
 	for (i = 0; i < kstack_depth_to_print; i++) {
 		if (stack + 1 > endstack)
 			break;
-		if (i && ((i % 8) == 0))
+		if (i % 8 == 0)
 			printk("\n       ");
-		printk("%08lx ", *stack++);
+		printk(" %08lx", *stack++);
 	}
 
-	printk ("\nCall Trace: ");
+	printk ("\nCall Trace:");
 	stack = (unsigned long *) addr;
-	i = 1;
+	i = 0;
 	module_start = VMALLOC_START;
 	module_end = module_start + MODULE_RANGE;
 	while (stack + 1 <= endstack) {
@@ -760,9 +766,9 @@
 		if (((addr >= (unsigned long) &_start) &&
 		     (addr <= (unsigned long) &_etext)) ||
 		    ((addr >= module_start) && (addr <= module_end))) {
-			if (i && ((i % 8) == 0))
+			if (i % 4 == 0)
 				printk("\n       ");
-			printk("[<%08lx>] ", addr);
+			printk(" [<%08lx>]", addr);
 			i++;
 		}
 	}
@@ -775,7 +781,7 @@
 void bad_super_trap (struct frame *fp)
 {
 	console_verbose();
-	if ((fp->ptregs.vector) < 48*4)
+	if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
 		printk ("*** %s ***   FORMAT=%X\n",
 			vec_names[(fp->ptregs.vector) >> 2],
 			fp->ptregs.format);
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/lib/checksum.c linux/arch/m68k/lib/checksum.c
--- v2.1.11/linux/arch/m68k/lib/checksum.c	Sat Apr  6 01:40:19 1996
+++ linux/arch/m68k/lib/checksum.c	Fri Nov 22 15:56:35 1996
@@ -124,7 +124,7 @@
 
 
 /*
- * copy from fs while checksumming, otherwise like csum_partial
+ * copy from user space while checksumming, otherwise like csum_partial
  */
 
 unsigned int
@@ -138,7 +138,8 @@
 		"jgt 1f\n\t"
 		"addql #2,%1\n\t"	/* len was == 2, treat only rest */
 		"jra 4f\n"
-	     "1:\t"
+	     "1:\n"
+	     "10:\t"
 		"movesw %2@+,%4\n\t"	/* add first word to sum */
 		"addw %4,%0\n\t"
 		"movew %4,%3@+\n\t"
@@ -150,28 +151,36 @@
 		"lsrl #5,%1\n\t"	/* len/32 */
 		"jeq 2f\n\t"		/* not enough... */
 		"subql #1,%1\n"
-	     "1:\t"
+	     "1:\n"
+	     "11:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
+	     "12:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
+	     "13:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
+	     "14:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
+	     "15:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
+	     "16:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
+	     "17:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
+	     "18:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
@@ -187,8 +196,9 @@
 		"jeq 4f\n\t"
 		"lsrw #2,%4\n\t"
 		"subqw #1,%4\n"
-	     "3:\t"
+	     "3:\n"
 		/* loop for rest longs */
+	     "19:\t"
 		"movesl %2@+,%5\n\t"
 		"addxl %5,%0\n\t"
 		"movel %5,%3@+\n\t"
@@ -202,12 +212,14 @@
 		"clrl %5\n\t"		/* clear tmp2 for rest bytes */
 		"subqw #2,%1\n\t"
 		"jlt 5f\n\t"
+	     "20:\t"
 		"movesw %2@+,%5\n\t"	/* have rest >= 2: get word */
 		"movew %5,%3@+\n\t"
 		"swap %5\n\t"		/* into bits 16..31 */
 		"tstw %1\n\t"		/* another byte? */
 		"jeq 6f\n"
-	     "5:\t"
+	     "5:\n"
+	     "21:\t"
 		"movesb %2@,%5\n\t"	/* have odd rest: get byte */
 		"moveb %5,%3@+\n\t"
 		"lslw #8,%5\n\t"	/* into bits 8..15; 16..31 untouched */
@@ -215,7 +227,21 @@
 		"addl %5,%0\n\t"	/* now add rest long to sum */
 		"clrl %5\n\t"
 		"addxl %5,%0\n"		/* add X bit */
-	     "7:\t"
+	     "7:\n"
+		".section __ex_table,\"a\"\n"
+		".long 10b,7b\n"
+		".long 11b,7b\n"
+		".long 12b,7b\n"
+		".long 13b,7b\n"
+		".long 14b,7b\n"
+		".long 15b,7b\n"
+		".long 16b,7b\n"
+		".long 17b,7b\n"
+		".long 18b,7b\n"
+		".long 19b,7b\n"
+		".long 20b,7b\n"
+		".long 21b,7b\n"
+		".text"
 		: "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
 		  "=&d" (tmp1), "=&d" (tmp2)
 		: "0" (sum), "1" (len), "2" (src), "3" (dst)
@@ -223,7 +249,7 @@
 	return(sum);
 }
 /*
- * copy from ds while checksumming, otherwise like csum_partial
+ * copy from kernel space while checksumming, otherwise like csum_partial
  */
 
 unsigned int
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/lib/semaphore.S linux/arch/m68k/lib/semaphore.S
--- v2.1.11/linux/arch/m68k/lib/semaphore.S	Wed Sep 25 10:47:40 1996
+++ linux/arch/m68k/lib/semaphore.S	Fri Nov 22 15:56:35 1996
@@ -11,19 +11,24 @@
 /*
  * "down_failed" is called with the eventual return address
  * in %a0, and the address of the semaphore in %a1. We need
- * to increment the number of waiters on the semaphore,
- * call "__down()", and then eventually return to try again.
+ * to call "__down()", and then re-try until we succeed..
  */
-ENTRY(down_failed)
-	movel %a0,-(%sp)
-	movel %a1,-(%sp)
+ENTRY(__down_failed)
+	moveml %a0/%d0/%d1,-(%sp)
+1:	movel %a1,-(%sp)
 	jbsr SYMBOL_NAME(__down)
 	movel (%sp)+,%a1
+	subql #1,(%a1)
+	jmi 1b
+	movel (%sp)+,%d0
+	movel (%sp)+,%d1
 	rts
 
-ENTRY(up_wakeup)
-	movel %a0,-(%sp)
+ENTRY(__up_wakeup)
+	moveml %a0/%d0/%d1,-(%sp)
 	movel %a1,-(%sp)
 	jbsr SYMBOL_NAME(__up)
 	movel (%sp)+,%a1
+	movel (%sp)+,%d0
+	movel (%sp)+,%d1
 	rts
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/mm/Makefile linux/arch/m68k/mm/Makefile
--- v2.1.11/linux/arch/m68k/mm/Makefile	Wed Dec 27 22:46:36 1995
+++ linux/arch/m68k/mm/Makefile	Fri Nov 22 15:56:35 1996
@@ -8,6 +8,6 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS	 := init.o fault.o memory.o
+O_OBJS	 := init.o fault.o memory.o extable.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/mm/extable.c linux/arch/m68k/mm/extable.c
--- v2.1.11/linux/arch/m68k/mm/extable.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/m68k/mm/extable.c	Fri Nov 22 15:56:35 1996
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/m68k/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+		 const struct exception_table_entry *last,
+		 unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = value - mid->insn;
+		if (diff >= 0 && diff <= 2)
+			return mid->fixup;
+		else if (diff > 0)
+			first = mid+1;
+		else
+			last = mid-1;
+	}
+	return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+	unsigned long ret;
+#ifdef CONFIG_MODULES
+	struct module *mp;
+#endif
+
+	/* Search the kernel's table first.  */
+	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_MODULES
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->exceptinfo.start != NULL) {
+			ret = search_one_table(mp->exceptinfo.start,
+				mp->exceptinfo.stop-1, addr);
+			if (ret)
+				return ret;
+		}
+	}
+#endif
+	return 0;
+}
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/mm/fault.c linux/arch/m68k/mm/fault.c
--- v2.1.11/linux/arch/m68k/mm/fault.c	Wed Sep 25 10:47:40 1996
+++ linux/arch/m68k/mm/fault.c	Fri Nov 22 15:56:35 1996
@@ -9,10 +9,14 @@
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 
+#include <asm/setup.h>
+#include <asm/traps.h>
 #include <asm/system.h>
+#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
 extern void die_if_kernel(char *, struct pt_regs *, long);
+extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */
 
 /*
  * This routine handles page faults.  It determines the problem, and
@@ -28,14 +32,20 @@
 asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
 			      unsigned long error_code)
 {
-	struct vm_area_struct * vma;
+	void (*handler)(struct task_struct *,
+			struct vm_area_struct *,
+			unsigned long,
+			int);
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
+	struct vm_area_struct * vma;
+	unsigned long fixup, fault_pc;
+	int write;
 
 #ifdef DEBUG
 	printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
 		regs->sr, regs->pc, address, error_code,
-		tsk->tss.pagedir_v);
+		tsk->mm->pgd);
 #endif
 
 	down(&mm->mmap_sem);
@@ -62,25 +72,24 @@
  * we can handle it..
  */
 good_area:
-	/*
-	 * was it a write?
-	 */
-	if (error_code & 2) {
-	  if (!(vma->vm_flags & VM_WRITE))
-	    goto bad_area;
-	} else {
-		/* read with protection fault? */
-	  if (error_code & 1)
-	    goto bad_area;
-	  if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
-	    goto bad_area;
-	}
-	if (error_code & 1) {
-		do_wp_page(tsk, vma, address, error_code & 2);
-		up(&mm->mmap_sem);
-		return 0;
+	write = 0;
+	handler = do_no_page;
+	switch (error_code & 3) {
+		default:	/* 3: write, present */
+			handler = do_wp_page;
+			/* fall through */
+		case 2:		/* write, not present */
+			if (!(vma->vm_flags & VM_WRITE))
+				goto bad_area;
+			write++;
+			break;
+		case 1:		/* read, present */
+			goto bad_area;
+		case 0:		/* read, not present */
+			if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+				goto bad_area;
 	}
-	do_no_page(tsk, vma, address, error_code & 2);
+	handler(tsk, vma, address, write);
 	up(&mm->mmap_sem);
 
 	/* There seems to be a missing invalidate somewhere in do_no_page.
@@ -96,6 +105,26 @@
  */
 bad_area:
 	up(&mm->mmap_sem);
+
+	/* Are we prepared to handle this fault?  */
+	if (CPU_IS_060 && regs->format == 4)
+		fault_pc = ((struct frame *)regs)->un.fmt4.pc;
+	else
+		fault_pc = regs->pc;
+	if ((fixup = search_exception_table(fault_pc)) != 0) {
+		struct pt_regs *tregs;
+		printk("Exception at %lx (%lx)\n", fault_pc, fixup);
+		/* Create a new four word stack frame, discarding the old
+		   one.  */
+		regs->stkadj = frame_extra_sizes[regs->format];
+		tregs =	(struct pt_regs *)((ulong)regs + regs->stkadj);
+		tregs->vector = regs->vector;
+		tregs->format = 0;
+		tregs->pc = fixup;
+		tregs->sr = regs->sr;
+		return -1;
+	}
+
 	if (user_mode(regs)) {
 		/* User memory access */
 		force_sig (SIGSEGV, tsk);
@@ -116,4 +145,3 @@
 
 	return 1;
 }
-
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/mm/init.c linux/arch/m68k/mm/init.c
--- v2.1.11/linux/arch/m68k/mm/init.c	Wed Oct  9 08:55:18 1996
+++ linux/arch/m68k/mm/init.c	Fri Nov 22 15:56:36 1996
@@ -17,7 +17,7 @@
 #endif
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -66,7 +66,7 @@
     printk("\nMem-info:\n");
     show_free_areas();
     printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
-    i = high_memory >> PAGE_SHIFT;
+    i = max_mapnr;
     while (i-- > 0) {
 	total++;
 	if (PageReserved(mem_map+i))
@@ -89,12 +89,14 @@
 #endif
 }
 
+#ifndef mm_cachebits
 /*
  * Bits to add to page descriptors for "normal" caching mode.
  * For 68020/030 this is 0.
  * For 68040, this is _PAGE_CACHE040 (cachable, copyback)
  */
 unsigned long mm_cachebits = 0;
+#endif
 
 pte_t *kernel_page_table (unsigned long *memavailp)
 {
@@ -216,7 +218,8 @@
 			 */
 			for (i = 0; i < 64; i++) {
 				pte_val(ktablep[i]) = physaddr | _PAGE_PRESENT
-					| _PAGE_CACHE040 | _PAGE_GLOBAL040;
+					| _PAGE_CACHE040 | _PAGE_GLOBAL040
+					| _PAGE_ACCESSED;
 				physaddr += PAGE_SIZE;
 			}
 			ktablep += 64;
@@ -227,7 +230,7 @@
 			 * 64 entry section of the page table.
 			 */
 
-			kpointerp[pindex++] = ktable | _PAGE_TABLE;
+			kpointerp[pindex++] = ktable | _PAGE_TABLE | _PAGE_ACCESSED;
 		} else {
 			/*
 			 * 68030, use early termination page descriptors.
@@ -247,16 +250,16 @@
 				
 				tbl = (unsigned long *)get_kpointer_table();
 
-				kpointerp[pindex++] = VTOP(tbl) | _PAGE_TABLE;
+				kpointerp[pindex++] = VTOP(tbl) | _PAGE_TABLE |_PAGE_ACCESSED;
 
 				for (i = 0; i < 64; i++, physaddr += PAGE_SIZE)
-					tbl[i] = physaddr | _PAGE_PRESENT;
+					tbl[i] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
 				
 				/* unmap the zero page */
 				tbl[0] = 0;
 			} else {
 				/* not the first 256K */
-				kpointerp[pindex++] = physaddr | _PAGE_PRESENT;
+				kpointerp[pindex++] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
 #ifdef DEBUG
 				printk ("%lx=%lx ", VTOP(&kpointerp[pindex-1]),
 					kpointerp[pindex-1]);
@@ -302,7 +305,9 @@
 	/* Fix the cache mode in the page descriptors for the 680[46]0.  */
 	if (CPU_IS_040_OR_060) {
 		int i;
+#ifndef mm_cachebits
 		mm_cachebits = _PAGE_CACHE040;
+#endif
 		for (i = 0; i < 16; i++)
 			pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
 	}
@@ -358,18 +363,16 @@
 #endif
 
 	memset (swapper_pg_dir, 0, sizeof(pgd_t)*PTRS_PER_PGD);
-	task[0]->tss.pagedir_v = (unsigned long *)swapper_pg_dir;
-	task[0]->tss.pagedir_p = VTOP (swapper_pg_dir);
+
+	/* setup CPU root pointer for swapper task */
+	task[0]->tss.crp[0] = 0x80000000 | _PAGE_TABLE;
+	task[0]->tss.crp[1] = VTOP (swapper_pg_dir);
 
 #ifdef DEBUG
 	printk ("task 0 pagedir at %p virt, %#lx phys\n",
-		task[0]->tss.pagedir_v, task[0]->tss.pagedir_p);
+		swapper_pg_dir, task[0]->tss.crp[1]);
 #endif
 
-	/* setup CPU root pointer for swapper task */
-	task[0]->tss.crp[0] = 0x80000000 | _PAGE_SHORT;
-	task[0]->tss.crp[1] = task[0]->tss.pagedir_p;
-
 	if (CPU_IS_040_OR_060)
 		asm __volatile__ ("movel %0,%/d0\n\t"
 				  ".long 0x4e7b0806" /* movec d0,urp */
@@ -406,10 +409,11 @@
 	extern int _etext;
 
 	end_mem &= PAGE_MASK;
-	high_memory = end_mem;
+	high_memory = (void *) end_mem;
+	max_mapnr = MAP_NR(end_mem);
 
 	start_mem = PAGE_ALIGN(start_mem);
-	while (start_mem < high_memory) {
+	while (start_mem < end_mem) {
 		clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
 		start_mem += PAGE_SIZE;
 	}
@@ -445,9 +449,6 @@
 	}
 	
 #endif
-#ifdef DEBUG
-	printk ("task[0] root table is %p\n", task[0]->tss.pagedir_v);
-#endif
 
 	for (tmp = 0 ; tmp < end_mem ; tmp += PAGE_SIZE) {
 		if (VTOP (tmp) >= mach_max_dma_address)
@@ -466,10 +467,9 @@
 #endif
 			free_page(tmp);
 	}
-	tmp = nr_free_pages << PAGE_SHIFT;
 	printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
-	       tmp >> 10,
-	       high_memory >> 10,
+	       (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+	       max_mapnr << (PAGE_SHIFT-10),
 	       codepages << (PAGE_SHIFT-10),
 	       datapages << (PAGE_SHIFT-10));
 }
@@ -478,7 +478,7 @@
 {
     unsigned long i;
 
-    i = high_memory >> PAGE_SHIFT;
+    i = max_mapnr;
     val->totalram = 0;
     val->sharedram = 0;
     val->freeram = nr_free_pages << PAGE_SHIFT;
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/tools/amiga/Makefile linux/arch/m68k/tools/amiga/Makefile
--- v2.1.11/linux/arch/m68k/tools/amiga/Makefile	Wed Sep 25 10:47:40 1996
+++ linux/arch/m68k/tools/amiga/Makefile	Fri Nov 22 15:56:36 1996
@@ -9,14 +9,3 @@
 dmesg:		dmesg.c
 		$(CC) $(CFLAGS) -o dmesg dmesg.c -noixemul
 
-
-CC =		m68k-cbm-amigados-gcc
-CFLAGS =	-Wall -O2
-
-
-All:		dmesg
-
-
-dmesg:		dmesg.c
-		$(CC) $(CFLAGS) -o dmesg dmesg.c -noixemul
-
diff -u --recursive --new-file v2.1.11/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c
--- v2.1.11/linux/drivers/block/ide-probe.c	Sun Nov 10 20:12:09 1996
+++ linux/drivers/block/ide-probe.c	Tue Nov 19 16:21:52 1996
@@ -75,7 +75,7 @@
 	sti();
 	ide_fix_driveid(id);
 
-#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO)
+#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
 	/*
 	 * EATA SCSI controllers do a hardware ATA emulation:
 	 * Ignore them if there is a driver for them available.
diff -u --recursive --new-file v2.1.11/linux/drivers/block/linear.c linux/drivers/block/linear.c
--- v2.1.11/linux/drivers/block/linear.c	Mon May 20 07:50:46 1996
+++ linux/drivers/block/linear.c	Fri Nov 22 16:07:23 1996
@@ -20,8 +20,9 @@
 #include <linux/module.h>
 
 #include <linux/md.h>
-#include <linux/linear.h>
 #include <linux/malloc.h>
+
+#include "linear.h"
 
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
diff -u --recursive --new-file v2.1.11/linux/drivers/block/linear.h linux/drivers/block/linear.h
--- v2.1.11/linux/drivers/block/linear.h	Thu Jan  1 02:00:00 1970
+++ linux/drivers/block/linear.h	Fri Nov 22 16:07:23 1996
@@ -0,0 +1,16 @@
+#ifndef _LINEAR_H
+#define _LINEAR_H
+
+struct linear_hash
+{
+  struct real_dev *dev0, *dev1;
+};
+
+struct linear_data
+{
+  struct linear_hash *hash_table; /* Dynamically allocated */
+  struct real_dev *smallest;
+  int nr_zones;
+};
+
+#endif
diff -u --recursive --new-file v2.1.11/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.1.11/linux/drivers/char/Makefile	Tue Oct 29 19:58:05 1996
+++ linux/drivers/char/Makefile	Fri Nov 22 12:03:43 1996
@@ -196,14 +196,6 @@
   endif
 endif
   
-ifeq ($(CONFIG_BAYCOM),y)
-L_OBJS += baycom.o
-else
-  ifeq ($(CONFIG_BAYCOM),m)
-  M_OBJS += baycom.o
-  endif
-endif  
-
 ifdef CONFIG_TGA_CONSOLE
 L_OBJS += tga.o
 else
diff -u --recursive --new-file v2.1.11/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v2.1.11/linux/drivers/net/tulip.c	Fri Nov 15 23:49:08 1996
+++ linux/drivers/net/tulip.c	Thu Nov 21 10:58:23 1996
@@ -1002,7 +1002,8 @@
 			if (status & TRING_RxFIFO) lp->stats.rx_fifo_errors++;
 		} else {
 			/* Malloc up new buffer, compatible with net-2e. */
-			short pkt_len = lp->rx_ring[entry].status >> 16;
+			/* Omit the four octet CRC from the length. */
+			short pkt_len = (lp->rx_ring[entry].status >> 16) - 4;
 			struct sk_buff *skb;
 
 			skb = dev_alloc_skb(pkt_len + 2);
diff -u --recursive --new-file v2.1.11/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.1.11/linux/drivers/pci/pci.c	Tue Nov 12 15:56:07 1996
+++ linux/drivers/pci/pci.c	Tue Nov 19 15:51:16 1996
@@ -211,6 +211,8 @@
 	DEVICE( AVANCE,		AVANCE_2302,	"ALG-2302"),
 	DEVICE( S3,		S3_ViRGE,	"ViRGE"),
 	DEVICE( S3,		S3_TRIO,	"Trio32/Trio64"),
+	DEVICE( S3,		S3_AURORA64VP,	"Aurora64V+"),
+	DEVICE( S3,		S3_TRIO64UVP,	"Trio64UV+"),
 	DEVICE( S3,		S3_ViRGE_VX,	"ViRGE/VX"),
 	DEVICE( S3,		S3_868,	"Vision 868"),
 	DEVICE( S3,		S3_928,		"Vision 928-P"),
diff -u --recursive --new-file v2.1.11/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.1.11/linux/drivers/scsi/Config.in	Fri Nov 15 23:49:08 1996
+++ linux/drivers/scsi/Config.in	Tue Nov 19 16:21:52 1996
@@ -29,7 +29,7 @@
 dep_tristate 'DTC3180/3280 SCSI support' CONFIG_SCSI_DTC3280 $CONFIG_SCSI
 dep_tristate 'EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI
 dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI
-dep_tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA $CONFIG_SCSI
+dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI
 dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN $CONFIG_SCSI
 dep_tristate 'Generic NCR5380/53c400 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 $CONFIG_SCSI
 if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
diff -u --recursive --new-file v2.1.11/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v2.1.11/linux/drivers/scsi/eata.c	Sat Oct  5 16:58:35 1996
+++ linux/drivers/scsi/eata.c	Tue Nov 19 16:21:52 1996
@@ -1,6 +1,9 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25
+ *          Added support for EATA 2.0C, PCI, multichannel and wide SCSI.
+ *
  *      27 Sep 1996 rev. 2.12 for linux 2.1.0
  *          Portability cleanups (virtual/bus addressing, little/big endian
  *          support).
@@ -82,7 +85,8 @@
  *
  *  Here is a brief description of the DPT SCSI host adapters.
  *  All these boards provide an EATA/DMA compatible programming interface
- *  and are fully supported by this driver:
+ *  and are fully supported by this driver in any configuration, including
+ *  multiple SCSI channels:
  *
  *  PM2011B/9X -  Entry Level ISA
  *  PM2021A/9X -  High Performance ISA
@@ -91,30 +95,39 @@
  *  PM2022A/9X -  Entry Level EISA
  *  PM2122A/9X -  High Performance EISA
  *  PM2322A/9X -  Extra High Performance EISA
+ *  PM3021     -  SmartRAID Adapter for ISA
+ *  PM3222     -  SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI)
+ *  PM3224     -  SmartRAID Adapter for PCI  (PM3224W is 16-bit wide SCSI)
  *
  *  The DPT PM2001 provides only the EATA/PIO interface and hence is not
  *  supported by this driver.
  *
  *  This code has been tested with up to 3 Distributed Processing Technology 
  *  PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) eisa controllers,
- *  no on board cache and no RAID option. 
- *  BIOS must be enabled on the first board and must be disabled for all other 
- *  boards. 
- *  Support is provided for any number of DPT PM2122 eisa boards.
- *  All boards should be configured at the same IRQ level.
- *  Multiple IRQ configurations are supported too.
- *  Boards can be located in any eisa slot (1-15) and are named EATA0, 
- *  EATA1,... in increasing eisa slot number. ISA boards are detected
- *  after the eisa slot probes.
- *
- *  The IRQ for EISA boards should be _level_ triggered (not _edge_ triggered).
- *  This is a requirement in order to support multiple boards on the same IRQ.
- *
- *  Other eisa configuration parameters are:
- *
- *  COMMAND QUEUING   : ENABLED
- *  COMMAND TIMEOUT   : ENABLED
- *  CACHE             : DISABLED
+ *  in any combination of private and shared IRQ.
+ *  PCI support has been tested using a DPT PM3224W (firmware v07G.0).
+ *
+ *  Multiple ISA, EISA and PCI boards can be configured in the same system.
+ *  It is suggested to put all the EISA boards on the same IRQ level, all
+ *  the PCI  boards on another IRQ level, while ISA boards cannot share 
+ *  interrupts.
+ *
+ *  If you configure multiple boards on the same IRQ, the interrupt must
+ *  be _level_ triggered (not _edge_ triggered).
+ *
+ *  This driver detects EATA boards by probes at fixed port addresses,
+ *  so no BIOS32 or PCI BIOS support is used or required.
+ *  The suggested way to detect a generic EATA PCI board is to force on it
+ *  any unused EISA address, even if there are other controllers on the EISA
+ *  bus, or even if you system has no EISA bus at all.
+ *  Do not force any ISA address on EATA PCI boards.
+ *
+ *  The sequence of detection probes is:
+ *  - ISA 0x1F0; 
+ *  - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15);
+ *  - ISA  0x170, 0x230, 0x330.
+ *
+ *  The boards are named EATA0, EATA1,... according to the detection order.
  *
  *  In order to support multiple ISA boards in a reliable way,
  *  the driver sets host->wish_block = TRUE for all ISA boards.
@@ -159,11 +172,14 @@
 #undef  DEBUG_STATISTICS
 #undef  DEBUG_RESET
 
-#define MAX_TARGET 8
+#define MAX_CHANNEL 4
+#define MAX_LUN 32
+#define MAX_TARGET 32
 #define MAX_IRQ 16
 #define MAX_BOARDS 18
 #define MAX_MAILBOXES 64
 #define MAX_SGLIST 64
+#define MAX_LARGE_SGLIST 252
 #define MAX_INTERNAL_RETRIES 64
 #define MAX_CMD_PER_LUN 2
 
@@ -189,7 +205,7 @@
 #define REG_MID         4
 #define REG_MSB         5
 #define REGION_SIZE     9
-#define EISA_RANGE      0xf000
+#define EISA_RANGE      0x1000
 #define BSY_ASSERTED      0x80
 #define DRQ_ASSERTED      0x08
 #define ABSY_ASSERTED     0x01
@@ -214,6 +230,7 @@
 /* Number of valid bytes in the board config structure for EATA 2.0x */
 #define EATA_2_0A_SIZE 28
 #define EATA_2_0B_SIZE 30
+#define EATA_2_0C_SIZE 34
 
 /* Board info structure */
 struct eata_info {
@@ -229,8 +246,7 @@
 	      ata:1,    /* This is an ATA device */
 	   haaval:1;    /* Host Adapter Address Valid */
    ushort cp_pad_len;   /* Number of pad bytes after cp_len */
-   unchar host_addr[3]; /* Host Adapter SCSI ID for channels 2, 1, 0 */
-   unchar reserved;
+   unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
    ulong  cp_len;       /* Number of valid bytes in cp */
    ulong  sp_len;       /* Number of valid bytes in sp */
    ushort queue_size;   /* Max number of cp that can be queued */
@@ -246,10 +262,14 @@
    unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */
 	 forcaddr:1,    /* Port address has been forced */
 		 :6;
-   unchar  max_id:5,    /* Max number of SCSI target IDs */
+   unchar  max_id:5,    /* Max SCSI target ID number */
 	 max_chan:3;    /* Max SCSI channel number on this board */
 
-   ushort ipad[249];
+   /* Structure extension defined in EATA 2.0C */
+   unchar   max_lun;    /* Max SCSI LUN number */
+   unchar   notused[3];
+
+   ushort ipad[247];
    };
 
 /* Board config structure */
@@ -288,9 +308,9 @@
    unchar unused[4];
    unchar phsunit:1,     /* Send to Target Physical Unit (bypass RAID) */
 	  notused:7;
-   unchar target;        /* SCSI Target ID */
-   unchar     lun:3,     /* LUN */
-		 :2,
+   unchar  target:5,     /* SCSI target ID */
+          channel:3;     /* SCSI channel number */
+   unchar     lun:5,     /* SCSI logical unit number */
 	   luntar:1,     /* This cp is for Target (not LUN) */
 	   dispri:1,     /* Disconnect Privilege granted */
 	      one:1;     /* 1 */
@@ -320,17 +340,17 @@
    char board_name[16];                 /* Name of this board */
    char board_id[256];                  /* data from INQUIRY on this board */
    int in_reset;                        /* True if board is doing a reset */
-   int target_time_out[MAX_TARGET];     /* N. of timeout errors on target */
-   int target_reset[MAX_TARGET];        /* If TRUE redo operation on target */
+   int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
+   int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
    unsigned int retries;                /* Number of internal retries */
    unsigned long last_retried_pid;      /* Pid of last retried command */
-   unsigned char subversion;            /* Bus type, either ISA or ESA */
+   unsigned char subversion;            /* Bus type, either ISA or EISA/PCI */
    unsigned char protocol_rev;          /* EATA 2.0 rev., 'A' or 'B' or 'C' */
    struct mssp sp[MAX_MAILBOXES];       /* Returned status for this board */
    };
 
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const char* driver_name = "EATA";
+static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static const char *driver_name = "EATA";
 static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
 
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
@@ -344,7 +364,7 @@
 static void eata2x_interrupt_handler(int, void *, struct pt_regs *);
 static int do_trace = FALSE;
 
-static inline unchar wait_on_busy(ushort iobase) {
+static inline int wait_on_busy(unsigned int iobase) {
    unsigned int loop = MAXLOOP;
 
    while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED)
@@ -353,7 +373,7 @@
    return FALSE;
 }
 
-static inline unchar do_dma (ushort iobase, unsigned int addr, unchar cmd) {
+static inline int do_dma(unsigned int iobase, unsigned int addr, unchar cmd) {
 
    if (wait_on_busy(iobase)) return TRUE;
 
@@ -368,7 +388,7 @@
    return FALSE;
 }
 
-static inline unchar read_pio (ushort iobase, ushort *start, ushort *end) {
+static inline int read_pio(unsigned int iobase, ushort *start, ushort *end) {
    unsigned int loop = MAXLOOP;
    ushort *p;
 
@@ -384,12 +404,11 @@
    return FALSE;
 }
 
-static inline int port_detect(ushort *port_base, unsigned int j, 
-			      Scsi_Host_Template * tpnt) {
-   unsigned char irq, dma_channel, subversion;
+static inline int port_detect(unsigned int *port_base, unsigned int j, 
+			      Scsi_Host_Template *tpnt) {
+   unsigned char irq, dma_channel, subversion, c;
    unsigned char protocol_rev;
    struct eata_info info;
-   const char *board_status;
 
    /* Allowed DMA channels for ISA (0 indicates reserved) */
    unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
@@ -425,15 +444,12 @@
    else
       protocol_rev = 'C';
 
-   if (protocol_rev != 'A' && info.max_chan > 0)
-      printk("%s: warning, only scsi channel 0 is supported.\n", name);
-
    irq = info.irq;
 
-   if (*port_base & EISA_RANGE) {
+   if (*port_base >= EISA_RANGE) {
 
       if (!info.haaval || info.ata || info.drqvld) {
-	 printk("%s: unusable EISA board found (%d%d%d), detaching.\n", 
+	 printk("%s: unusable EISA/PCI board found (%d%d%d), detaching.\n", 
 		name, info.haaval, info.ata, info.drqvld);
 	 return FALSE;
 	 }
@@ -460,11 +476,6 @@
       printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
 	     name, irq);
 
-   if (info.second)
-      board_status = "Sec.";
-   else
-      board_status = "Prim.";
-
    /* Board detected, allocate its IRQ if not already done */
    if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
        (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name, NULL))) {
@@ -508,6 +519,7 @@
       }
 
    sh[j]->io_port = *port_base;
+   sh[j]->unique_id = *port_base;
    sh[j]->n_io_port = REGION_SIZE;
    sh[j]->dma_channel = dma_channel;
    sh[j]->irq = irq;
@@ -536,11 +548,20 @@
       enable_dma(dma_channel);
       }
 
+   if (protocol_rev != 'A' && info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
+      sh[j]->max_channel = info.max_chan;
+
+   if (protocol_rev != 'A' && info.max_id > 7 && info.max_id < MAX_TARGET)
+      sh[j]->max_id = info.max_id + 1;
+
+   if (protocol_rev == 'C' && info.max_lun > 7 && info.max_lun < MAX_LUN)
+      sh[j]->max_lun = info.max_lun + 1;
+
    strcpy(BN(j), name);
 
-   printk("%s: 2.0%c, %s, ID %d, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
-	  "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev, board_status, 
-	   sh[j]->this_id, sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
+   printk("%s: rev. 2.0%c, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
+	  "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev,
+	   sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
 	   sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun);
 
    /* DPT PM2012 does not allow to detect sg_tablesize correctly */
@@ -555,30 +576,38 @@
       sh[j]->can_queue = MAX_MAILBOXES;
       }
 
+   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
+      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+             BN(j), sh[j]->max_id, sh[j]->max_lun);
+
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      printk("%s: SCSI channel %u enabled, host target ID %u.\n",
+             BN(j), c, info.host_addr[3 - c]);
+
 #if defined (DEBUG_DETECT)
    if (protocol_rev != 'A')
       printk("%s: EATA 2.0%c, isaena %u, forcaddr %u, max_id %u,"\
-	     " max_chan %u.\n", name, protocol_rev, info.isaena, 
-	     info.forcaddr, info.max_id, info.max_chan);
+	     " max_chan %u, max_lun %u.\n", name, protocol_rev, info.isaena, 
+	     info.forcaddr, info.max_id, info.max_chan, info.max_lun);
 
-   printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n", 
-	  name, info.version, info.sync, DEV2H(info.data_len), 
+   printk("%s: Vers. 0x%x, SYNC 0x%x, sec. %u, infol %ld, cpl %ld spl %ld.\n", 
+	  name, info.version, info.sync, info.second, DEV2H(info.data_len), 
 	  DEV2H(info.cp_len), DEV2H(info.sp_len));
 #endif
 
    return TRUE;
 }
 
-int eata2x_detect (Scsi_Host_Template * tpnt) {
+int eata2x_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k, flags;
 
-   ushort io_port[] = { 
-      0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
-      0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, 
-      0x1f0,  0x170,  0x330,  0x230,  0x0
+   unsigned int io_port[] = { 
+      0x1f0,  0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88,
+      0x8c88, 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, 
+      0x170,  0x230,  0x330,  0x0
       };
 
-   ushort *port_base = io_port;
+   unsigned int *port_base = io_port;
 
    tpnt->proc_dir = &proc_scsi_eata2x;
 
@@ -608,7 +637,7 @@
 
 static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
    unsigned int k;
-   struct scatterlist * sgpnt;
+   struct scatterlist *sgpnt;
 
    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
 
@@ -621,7 +650,7 @@
    cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
 }
 
-int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
+int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    unsigned int i, j, k, flags;
    struct mscp *cpp;
    struct mssp *spp;
@@ -687,8 +716,9 @@
    cpp->index = i;
    SCpnt->host_scribble = (unsigned char *) &cpp->index;
 
-   if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
-			BN(j), i, SCpnt->target, SCpnt->pid);
+   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+			BN(j), i, SCpnt->channel, SCpnt->target,
+                        SCpnt->lun, SCpnt->pid);
 
    for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
@@ -700,6 +730,7 @@
    cpp->reqsen = TRUE;
    cpp->dispri = TRUE;
    cpp->one = TRUE;
+   cpp->channel = SCpnt->channel;
    cpp->target = SCpnt->target;
    cpp->lun = SCpnt->lun;  
    cpp->SCpnt = SCpnt;
@@ -721,8 +752,9 @@
    if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
       SCpnt->result = DID_ERROR << 16; 
       SCpnt->host_scribble = NULL;
-      printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n", 
-	     BN(j), SCpnt->target, SCpnt->pid);
+      printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy, DID_ERROR,"\
+             " done.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun,
+             SCpnt->pid);
       restore_flags(flags);
       done(SCpnt);    
       return 0;
@@ -733,7 +765,7 @@
    return 0;
 }
 
-int eata2x_abort (Scsi_Cmnd *SCarg) {
+int eata2x_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j, flags;
 
    save_flags(flags);
@@ -741,15 +773,15 @@
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
 
    if (SCarg->host_scribble == NULL) {
-      printk("%s: abort, target %d, pid %ld inactive.\n",
-	     BN(j), SCarg->target, SCarg->pid);
+      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+	     BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
       restore_flags(flags);
       return SCSI_ABORT_NOT_RUNNING;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d, pid %ld.\n", 
-	  BN(j), i, SCarg->target, SCarg->pid);
+   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", 
+	  BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -792,16 +824,17 @@
    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
 }
 
-int eata2x_reset (Scsi_Cmnd *SCarg, unsigned int reset_flags) {
-   unsigned int i, j, flags, time, k, limit = 0;
+int eata2x_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
+   unsigned int i, j, flags, time, k, c, limit = 0;
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
 
    save_flags(flags);
    cli();
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n", 
-	  BN(j), SCarg->target, SCarg->pid, reset_flags);
+   printk("%s: reset, enter, target %d.%d:%d, pid %ld, reset_flags %u.\n", 
+	  BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid,
+          reset_flags);
 
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
@@ -820,9 +853,11 @@
 
    HD(j)->retries = 0;
 
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      for (k = 0; k < sh[j]->max_id; k++) {
+         HD(j)->target_redo[k][c] = TRUE;
+         HD(j)->target_to[k][c] = 0;
+         }
 
    for (i = 0; i < sh[j]->can_queue; i++) {
 
@@ -906,9 +941,10 @@
       }
 }
 
-static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
+static void eata2x_interrupt_handler(int irq, void *dev_id,
+                                     struct pt_regs *regs) {
    Scsi_Cmnd *SCpnt;
-   unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
+   unsigned int i, j, k, c, flags, status, tstatus, loops, total_loops = 0;
    struct mssp *spp;
    struct mscp *cpp;
 
@@ -1001,9 +1037,8 @@
 		     status = DID_ERROR << 16;
    
 		  /* If there was a bus reset, redo operation on each target */
-		  else if (tstatus != GOOD
-			   && SCpnt->device->type == TYPE_DISK
-			   && HD(j)->target_reset[SCpnt->target])
+		  else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+     		           && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
 		     status = DID_BUS_BUSY << 16;
    
 		  /* Works around a flaw in scsi.c */
@@ -1016,15 +1051,16 @@
 		     status = DID_OK << 16;
    
 		  if (tstatus == GOOD)
-		     HD(j)->target_reset[SCpnt->target] = FALSE;
+		     HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
    
 		  if (spp->target_status && SCpnt->device->type == TYPE_DISK)
-		     printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
-			    "0x%x, sense key 0x%x.\n", BN(j), 
-			    SCpnt->target, SCpnt->lun, SCpnt->pid,
-			    spp->target_status, SCpnt->sense_buffer[2]);
+		     printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
+                            "target_status 0x%x, sense key 0x%x.\n", BN(j), 
+			    SCpnt->channel, SCpnt->target, SCpnt->lun, 
+                            SCpnt->pid, spp->target_status, 
+                            SCpnt->sense_buffer[2]);
    
-		  HD(j)->target_time_out[SCpnt->target] = 0;
+		  HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
    
                   if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
 
@@ -1032,11 +1068,11 @@
 	       case ASST:     /* Selection Time Out */
 	       case 0x02:     /* Command Time Out   */
    
-		  if (HD(j)->target_time_out[SCpnt->target] > 1)
+		  if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
 		     status = DID_ERROR << 16;
 		  else {
 		     status = DID_TIME_OUT << 16;
-		     HD(j)->target_time_out[SCpnt->target]++;
+		     HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
 		     }
    
 		  break;
@@ -1045,8 +1081,9 @@
 	       case 0x03:     /* SCSI Bus Reset Received */
 	       case 0x04:     /* Initial Controller Power-up */
    
-		  for (k = 0; k < MAX_TARGET; k++) 
-		     HD(j)->target_reset[k] = TRUE;
+		  for (c = 0; c <= sh[j]->max_channel; c++) 
+		     for (k = 0; k < sh[j]->max_id; k++) 
+		        HD(j)->target_redo[k][c] = TRUE;
    
 	          if (SCpnt->device->type != TYPE_TAPE
                       && HD(j)->retries < MAX_INTERNAL_RETRIES) {
@@ -1085,9 +1122,10 @@
 		do_trace)
 #endif
 	       printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
-		      " target %d:%d, pid %ld, count %d.\n",
+		      " target %d.%d:%d, pid %ld, count %d.\n",
 		      BN(j), i, spp->adapter_status, spp->target_status,
-		      SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
+		      SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+                      HD(j)->iocount);
    
 	    /* Set the command state to inactive */
 	    SCpnt->host_scribble = NULL;
diff -u --recursive --new-file v2.1.11/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h
--- v2.1.11/linux/drivers/scsi/eata.h	Sat Oct  5 16:58:35 1996
+++ linux/drivers/scsi/eata.h	Tue Nov 19 16:21:52 1996
@@ -11,7 +11,7 @@
 int eata2x_abort(Scsi_Cmnd *);
 int eata2x_reset(Scsi_Cmnd *, unsigned int);
 
-#define EATA_VERSION "2.12.00"
+#define EATA_VERSION "2.20.00"
 
 
 #define EATA {                                                 \
diff -u --recursive --new-file v2.1.11/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- v2.1.11/linux/drivers/scsi/g_NCR5380.c	Wed Apr 17 09:01:18 1996
+++ linux/drivers/scsi/g_NCR5380.c	Fri Nov 22 12:06:21 1996
@@ -386,14 +386,15 @@
 	blocks--;
     }
 
+    if (blocks) {
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    printk("53C400r: EXTRA: Waiting for buffer\n");
+	printk("53C400r: EXTRA: Waiting for buffer\n");
 #endif
-    while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-	;
+	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+	    ;
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    printk("53C400r: Transferring EXTRA 128 bytes\n");
+	printk("53C400r: Transferring EXTRA 128 bytes\n");
 #endif
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
 	for (i=0; i<128; i++)
@@ -402,8 +403,13 @@
 	/* implies CONFIG_SCSI_G_NCR5380_MEM */
 	memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
 #endif
-    start+=128;
-    blocks--;
+	start+=128;
+	blocks--;
+    }
+#if (NDEBUG & NDEBUG_C400_PREAD)
+    else
+	printk("53C400r: No EXTRA required\n");
+#endif
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
     printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
diff -u --recursive --new-file v2.1.11/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.1.11/linux/drivers/scsi/sr_ioctl.c	Fri Nov 15 23:49:09 1996
+++ linux/drivers/scsi/sr_ioctl.c	Thu Nov 21 13:46:11 1996
@@ -246,17 +246,22 @@
 	
     case CDROMPLAYMSF:
     {
-	struct cdrom_msf* msf = (struct cdrom_msf*)arg;
+	struct cdrom_msf msf;
+
+	if (copy_from_user(&msf, (void *) arg, sizeof(msf))) {
+		result = -EFAULT;
+		break;
+	}
 
 	sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
 	sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 	sr_cmd[2] = 0;
-	sr_cmd[3] = msf->cdmsf_min0;
-	sr_cmd[4] = msf->cdmsf_sec0;
-	sr_cmd[5] = msf->cdmsf_frame0;
-	sr_cmd[6] = msf->cdmsf_min1;
-	sr_cmd[7] = msf->cdmsf_sec1;
-	sr_cmd[8] = msf->cdmsf_frame1;
+	sr_cmd[3] = msf.cdmsf_min0;
+	sr_cmd[4] = msf.cdmsf_sec0;
+	sr_cmd[5] = msf.cdmsf_frame0;
+	sr_cmd[6] = msf.cdmsf_min1;
+	sr_cmd[7] = msf.cdmsf_sec1;
+	sr_cmd[8] = msf.cdmsf_frame1;
 	sr_cmd[9] = 0;
 	
 	result = sr_do_ioctl(target, sr_cmd, NULL, 255);
@@ -265,17 +270,22 @@
 
     case CDROMPLAYBLK:
     {
-	struct cdrom_blk* blk = (struct cdrom_blk*)arg;
+	struct cdrom_blk blk;
+
+	if (copy_from_user(&blk, (void *) arg, sizeof(blk))) {
+		result = -EFAULT;
+		break;
+	}
 
 	sr_cmd[0] = SCMD_PLAYAUDIO10;
 	sr_cmd[1] = scsi_CDs[target].device->lun << 5;
-	sr_cmd[2] = blk->from >> 24;
-	sr_cmd[3] = blk->from >> 16;
-	sr_cmd[4] = blk->from >> 8;
-	sr_cmd[5] = blk->from;
+	sr_cmd[2] = blk.from >> 24;
+	sr_cmd[3] = blk.from >> 16;
+	sr_cmd[4] = blk.from >> 8;
+	sr_cmd[5] = blk.from;
 	sr_cmd[6] = 0;
-	sr_cmd[7] = blk->len >> 8;
-	sr_cmd[8] = blk->len;
+	sr_cmd[7] = blk.len >> 8;
+	sr_cmd[8] = blk.len;
 	sr_cmd[9] = 0;
 	
 	result = sr_do_ioctl(target, sr_cmd, NULL, 255);
@@ -284,17 +294,22 @@
 		
     case CDROMPLAYTRKIND:
     {
-	struct cdrom_ti* ti = (struct cdrom_ti*)arg;
+	struct cdrom_ti ti;
+
+	if (copy_from_user(&ti, (void *) arg, sizeof(ti))) {
+		result = -EFAULT;
+		break;
+	}
 
 	sr_cmd[0] = SCMD_PLAYAUDIO_TI;
 	sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 	sr_cmd[2] = 0;
 	sr_cmd[3] = 0;
-	sr_cmd[4] = ti->cdti_trk0;
-	sr_cmd[5] = ti->cdti_ind0;
+	sr_cmd[4] = ti.cdti_trk0;
+	sr_cmd[5] = ti.cdti_ind0;
 	sr_cmd[6] = 0;
-	sr_cmd[7] = ti->cdti_trk1;
-	sr_cmd[8] = ti->cdti_ind1;
+	sr_cmd[7] = ti.cdti_trk1;
+	sr_cmd[8] = ti.cdti_ind1;
 	sr_cmd[9] = 0;
 	
 	result = sr_do_ioctl(target, sr_cmd, NULL, 255);
@@ -303,7 +318,7 @@
 	
     case CDROMREADTOCHDR:
     {
-	struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
+	struct cdrom_tochdr tochdr;
 	char * buffer;
 	
 	sr_cmd[0] = SCMD_READ_TOC;
@@ -319,23 +334,31 @@
 	
 	result = sr_do_ioctl(target, sr_cmd, buffer, 12);
 	
-	tochdr->cdth_trk0 = buffer[2];
-	tochdr->cdth_trk1 = buffer[3];
+	tochdr.cdth_trk0 = buffer[2];
+	tochdr.cdth_trk1 = buffer[3];
 	
 	scsi_free(buffer, 512);
+
+	if (copy_to_user ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr)))
+		result = -EFAULT;
         break;
     }
 	
     case CDROMREADTOCENTRY:
     {
-	struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
+	struct cdrom_tocentry tocentry;
 	unsigned char * buffer;
 	
+	if (copy_from_user (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry))) {
+		result = -EFAULT;
+		break;
+	}
+
 	sr_cmd[0] = SCMD_READ_TOC;
 	sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) |
-          (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
+          (tocentry.cdte_format == CDROM_MSF ? 0x02 : 0);
 	sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
-	sr_cmd[6] = tocentry->cdte_track;
+	sr_cmd[6] = tocentry.cdte_track;
 	sr_cmd[7] = 0;             /* MSB of length (12)  */
 	sr_cmd[8] = 12;            /* LSB of length */
 	sr_cmd[9] = 0;
@@ -345,18 +368,21 @@
 	
 	result = sr_do_ioctl (target, sr_cmd, buffer, 12);
 	
-        tocentry->cdte_ctrl = buffer[5] & 0xf;	
-        tocentry->cdte_adr = buffer[5] >> 4;
-        tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
-	if (tocentry->cdte_format == CDROM_MSF) {
-	    tocentry->cdte_addr.msf.minute = buffer[9];
-	    tocentry->cdte_addr.msf.second = buffer[10];
-	    tocentry->cdte_addr.msf.frame = buffer[11];
+        tocentry.cdte_ctrl = buffer[5] & 0xf;	
+        tocentry.cdte_adr = buffer[5] >> 4;
+        tocentry.cdte_datamode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0;
+	if (tocentry.cdte_format == CDROM_MSF) {
+	    tocentry.cdte_addr.msf.minute = buffer[9];
+	    tocentry.cdte_addr.msf.second = buffer[10];
+	    tocentry.cdte_addr.msf.frame = buffer[11];
 	} else
-	    tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
+	    tocentry.cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
                                        + buffer[10]) << 8) + buffer[11];
 	
 	scsi_free(buffer, 512);
+
+	if (copy_to_user ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry)))
+		result = -EFAULT;
         break;
     }
 	
@@ -381,8 +407,13 @@
     case CDROMVOLCTRL:
     {
 	char * buffer, * mask;
-	struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+	struct cdrom_volctrl volctrl;
 	
+	if (copy_from_user (&volctrl, (void *) arg, sizeof (struct cdrom_volctrl))) {
+		result = -EFAULT;
+		break;
+	}
+
 	/* First we get the current params so we can just twiddle the volume */
 	
 	sr_cmd[0] = MODE_SENSE;
@@ -425,10 +456,10 @@
 	/* Now mask and substitute our own volume and reuse the rest */
 	buffer[0] = 0;  /* Clear reserved field */
 	
-	buffer[21] = volctrl->channel0 & mask[21];
-	buffer[23] = volctrl->channel1 & mask[23];
-	buffer[25] = volctrl->channel2 & mask[25];
-	buffer[27] = volctrl->channel3 & mask[27];
+	buffer[21] = volctrl.channel0 & mask[21];
+	buffer[23] = volctrl.channel1 & mask[23];
+	buffer[25] = volctrl.channel2 & mask[25];
+	buffer[27] = volctrl.channel3 & mask[27];
 	
 	sr_cmd[0] = MODE_SELECT;
 	sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10;    /* Params are SCSI-2 */
@@ -445,7 +476,7 @@
     case CDROMVOLREAD:
     {
 	char * buffer;
-	struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+	struct cdrom_volctrl volctrl;
 	
 	/* Get the current params */
 	
@@ -465,18 +496,21 @@
             break;
 	}
 
-	volctrl->channel0 = buffer[21];
-	volctrl->channel1 = buffer[23];
-	volctrl->channel2 = buffer[25];
-	volctrl->channel3 = buffer[27];
+	volctrl.channel0 = buffer[21];
+	volctrl.channel1 = buffer[23];
+	volctrl.channel2 = buffer[25];
+	volctrl.channel3 = buffer[27];
 
 	scsi_free(buffer, 512);
+
+	if (copy_to_user ((void *) arg, &volctrl, sizeof (struct cdrom_volctrl)))
+		result = -EFAULT;
         break;
     }
 	
     case CDROMSUBCHNL:
     {
-	struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg;
+	struct cdrom_subchnl subchnl;
 	char * buffer;
 	
 	sr_cmd[0] = SCMD_READ_SUBCHANNEL;
@@ -494,20 +528,23 @@
 	
 	result = sr_do_ioctl(target, sr_cmd, buffer, 16);
 	
-	subchnl->cdsc_audiostatus = buffer[1];
-	subchnl->cdsc_format = CDROM_MSF;
-	subchnl->cdsc_ctrl = buffer[5] & 0xf;
-	subchnl->cdsc_trk = buffer[6];
-	subchnl->cdsc_ind = buffer[7];
-	
-	subchnl->cdsc_reladdr.msf.minute = buffer[13];
-	subchnl->cdsc_reladdr.msf.second = buffer[14];
-	subchnl->cdsc_reladdr.msf.frame = buffer[15];
-	subchnl->cdsc_absaddr.msf.minute = buffer[9];
-	subchnl->cdsc_absaddr.msf.second = buffer[10];
-	subchnl->cdsc_absaddr.msf.frame = buffer[11];
+	subchnl.cdsc_audiostatus = buffer[1];
+	subchnl.cdsc_format = CDROM_MSF;
+	subchnl.cdsc_ctrl = buffer[5] & 0xf;
+	subchnl.cdsc_trk = buffer[6];
+	subchnl.cdsc_ind = buffer[7];
+	
+	subchnl.cdsc_reladdr.msf.minute = buffer[13];
+	subchnl.cdsc_reladdr.msf.second = buffer[14];
+	subchnl.cdsc_reladdr.msf.frame = buffer[15];
+	subchnl.cdsc_absaddr.msf.minute = buffer[9];
+	subchnl.cdsc_absaddr.msf.second = buffer[10];
+	subchnl.cdsc_absaddr.msf.frame = buffer[11];
 	
 	scsi_free(buffer, 512);
+
+	if (copy_to_user ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl)))
+		result = -EFAULT;
         break;
     }
     default:
diff -u --recursive --new-file v2.1.11/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v2.1.11/linux/drivers/scsi/u14-34f.c	Sat Oct  5 16:58:35 1996
+++ linux/drivers/scsi/u14-34f.c	Tue Nov 19 16:21:52 1996
@@ -1,6 +1,9 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25
+ *          Added multichannel support.
+ *
  *      27 Sep 1996 rev. 2.12 for linux 2.1.0
  *          Portability cleanups (virtual/bus addressing, little/big endian
  *          support).
@@ -202,6 +205,8 @@
 #undef  DEBUG_STATISTICS
 #undef  DEBUG_RESET
 
+#define MAX_CHANNEL 1
+#define MAX_LUN 8
 #define MAX_TARGET 8
 #define MAX_IRQ 16
 #define MAX_BOARDS 4
@@ -253,9 +258,9 @@
    unsigned char dcn: 1;                /* disable disconnect */
    unsigned char ca: 1;                 /* use cache (if available) */
    unsigned char sg: 1;                 /* scatter/gather operation */
-   unsigned char target: 3;             /* target SCSI id */
-   unsigned char ch_no: 2;              /* SCSI channel (always 0 for 14f) */
-   unsigned char lun: 3;                /* logical unit number */
+   unsigned char target: 3;             /* SCSI target id */
+   unsigned char channel: 2;            /* SCSI channel number */
+   unsigned char lun: 3;                /* SCSI logical unit number */
    unsigned int data_address PACKED;    /* transfer data pointer */
    unsigned int data_len PACKED;        /* length in bytes */
    unsigned int command_link PACKED;    /* for linking command chains */
@@ -288,8 +293,8 @@
    char board_name[16];                 /* Name of this board */
    char board_id[256];                  /* data from INQUIRY on this board */
    int in_reset;                        /* True if board is doing a reset */
-   int target_time_out[MAX_TARGET];     /* N. of timeout errors on target */
-   int target_reset[MAX_TARGET];        /* If TRUE redo operation on target */
+   int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
+   int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
    unsigned int retries;                /* Number of internal retries */
    unsigned long last_retried_pid;      /* Pid of last retried command */
    unsigned char subversion;            /* Bus type, either ISA or ESA */
@@ -300,8 +305,8 @@
    unsigned char slot;
    };
 
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const char* driver_name = "Ux4F";
+static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static const char *driver_name = "Ux4F";
 static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
 
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
@@ -324,7 +329,7 @@
 static void u14_34f_interrupt_handler(int, void *, struct pt_regs *);
 static int do_trace = FALSE;
 
-static inline unchar wait_on_busy(ushort iobase) {
+static inline int wait_on_busy(unsigned int iobase) {
    unsigned int loop = MAXLOOP;
 
    while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED)
@@ -376,9 +381,9 @@
    return FALSE;
 }
 
-static inline int port_detect(ushort *port_base, unsigned int j, 
-			      Scsi_Host_Template * tpnt) {
-   unsigned char irq, dma_channel, subversion;
+static inline int port_detect(unsigned int *port_base, unsigned int j, 
+			      Scsi_Host_Template *tpnt) {
+   unsigned char irq, dma_channel, subversion, c;
    unsigned char in_byte;
 
    /* Allowed BIOS base addresses (NULL indicates reserved) */
@@ -466,6 +471,7 @@
       }
 
    sh[j]->io_port = *port_base;
+   sh[j]->unique_id = *port_base;
    sh[j]->n_io_port = REGION_SIZE;
    sh[j]->base = bios_segment_table[config_1.bios_segment];
    sh[j]->irq = irq;
@@ -524,6 +530,10 @@
       enable_dma(dma_channel);
       }
 
+   sh[j]->max_channel = MAX_CHANNEL - 1;
+   sh[j]->max_id = MAX_TARGET;
+   sh[j]->max_lun = MAX_LUN;
+
    if (HD(j)->subversion == ISA && !board_inquiry(j)) {
       HD(j)->board_id[40] = 0;
 
@@ -538,21 +548,29 @@
 
    printk("%s: PORT 0x%03x, BIOS 0x%05x, IRQ %u, DMA %u, SG %d, "\
 	  "Mbox %d, CmdLun %d, C%d.\n", BN(j), sh[j]->io_port, 
-	  (int)sh[j]->base, sh[j]->irq, 
-	  sh[j]->dma_channel, sh[j]->sg_tablesize, 
-	  sh[j]->can_queue, sh[j]->cmd_per_lun,
+	  (int)sh[j]->base, sh[j]->irq, sh[j]->dma_channel,
+          sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun,
 	  sh[j]->hostt->use_clustering);
+
+   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
+      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+             BN(j), sh[j]->max_id, sh[j]->max_lun);
+
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      printk("%s: SCSI channel %u enabled, host target ID %u.\n",
+             BN(j), c, sh[j]->this_id);
+
    return TRUE;
 }
 
-int u14_34f_detect (Scsi_Host_Template * tpnt) {
+int u14_34f_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k, flags;
 
-   ushort io_port[] = {
+   unsigned int io_port[] = {
       0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140, 0x0
       };
 
-   ushort *port_base = io_port;
+   unsigned int *port_base = io_port;
 
    tpnt->proc_dir = &proc_scsi_u14_34f;
 
@@ -582,7 +600,7 @@
 
 static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
    unsigned int k, data_len = 0;
-   struct scatterlist * sgpnt;
+   struct scatterlist *sgpnt;
 
    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
 
@@ -653,8 +671,9 @@
    cpp->index = i;
    SCpnt->host_scribble = (unsigned char *) &cpp->index;
 
-   if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
-			BN(j), i, SCpnt->target, SCpnt->pid);
+   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+			BN(j), i, SCpnt->channel, SCpnt->target, 
+                        SCpnt->lun, SCpnt->pid);
 
    cpp->xdir = DTD_IN;
 
@@ -665,6 +684,7 @@
 	}
 
    cpp->opcode = OP_SCSI;
+   cpp->channel = SCpnt->channel;
    cpp->target = SCpnt->target;
    cpp->lun = SCpnt->lun;
    cpp->SCpnt = SCpnt;
@@ -686,8 +706,9 @@
    if (wait_on_busy(sh[j]->io_port)) {
       SCpnt->result = DID_ERROR << 16;
       SCpnt->host_scribble = NULL;
-      printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n", 
-	     BN(j), SCpnt->target, SCpnt->pid);
+      printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy, DID_ERROR,"\
+             " done.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun,
+             SCpnt->pid);
       restore_flags(flags);
       done(SCpnt);
       return 0;
@@ -712,15 +733,15 @@
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
 
    if (SCarg->host_scribble == NULL) {
-      printk("%s: abort, target %d, pid %ld inactive.\n",
-	     BN(j), SCarg->target, SCarg->pid);
+      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+	     BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
       restore_flags(flags);
       return SCSI_ABORT_NOT_RUNNING;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d, pid %ld.\n",
-	  BN(j), i, SCarg->target, SCarg->pid);
+   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
+	  BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -763,16 +784,17 @@
    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
 }
 
-int u14_34f_reset(Scsi_Cmnd * SCarg, unsigned int reset_flags) {
-   unsigned int i, j, flags, time, k, limit = 0;
+int u14_34f_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
+   unsigned int i, j, flags, time, k, c, limit = 0;
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
 
    save_flags(flags);
    cli();
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n", 
-	  BN(j), SCarg->target, SCarg->pid, reset_flags);
+   printk("%s: reset, enter, target %d.%d:%d, pid %ld, reset_flags %u.\n", 
+	  BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid,
+          reset_flags);
 
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
@@ -791,9 +813,11 @@
 
    HD(j)->retries = 0;
 
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      for (k = 0; k < sh[j]->max_id; k++) {
+         HD(j)->target_redo[k][c] = TRUE;
+         HD(j)->target_to[k][c] = 0;
+         }
 
    for (i = 0; i < sh[j]->can_queue; i++) {
 
@@ -878,7 +902,7 @@
       }
 }
 
-int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) {
+int u14_34f_biosparam(Disk *disk, kdev_t dev, int *dkinfo) {
    unsigned int j = 0;
    int size = disk->capacity;
 
@@ -888,9 +912,10 @@
    return 0;
 }
 
-static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
+static void u14_34f_interrupt_handler(int irq, void *dev_id,
+                                      struct pt_regs *regs) {
    Scsi_Cmnd *SCpnt;
-   unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
+   unsigned int i, j, k, c, flags, status, tstatus, loops, total_loops = 0;
    struct mscp *spp;
 
    save_flags(flags);
@@ -975,9 +1000,8 @@
 		  status = DID_ERROR << 16;
 
 	       /* If there was a bus reset, redo operation on each target */
-	       else if (tstatus != GOOD
-			&& SCpnt->device->type == TYPE_DISK
-			&& HD(j)->target_reset[SCpnt->target])
+	       else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+		        && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
 		  status = DID_BUS_BUSY << 16;
 
 	       /* Works around a flaw in scsi.c */
@@ -990,26 +1014,27 @@
 		  status = DID_OK << 16;
 
 	       if (tstatus == GOOD)
-		  HD(j)->target_reset[SCpnt->target] = FALSE;
+		  HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
 
 	       if (spp->target_status && SCpnt->device->type == TYPE_DISK)
-		  printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
-			 "0x%x, sense key 0x%x.\n", BN(j), 
-			 SCpnt->target, SCpnt->lun, SCpnt->pid,
-			 spp->target_status, SCpnt->sense_buffer[2]);
+		  printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
+                         "target_status 0x%x, sense key 0x%x.\n", BN(j), 
+			 SCpnt->channel, SCpnt->target, SCpnt->lun,
+                         SCpnt->pid, spp->target_status,
+                         SCpnt->sense_buffer[2]);
 
-	       HD(j)->target_time_out[SCpnt->target] = 0;
+	       HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
 
                if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
 
 	       break;
 	    case ASST:     /* Selection Time Out */
 
-	       if (HD(j)->target_time_out[SCpnt->target] > 1)
+	       if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
 		  status = DID_ERROR << 16;
 	       else {
 		  status = DID_TIME_OUT << 16;
-		  HD(j)->target_time_out[SCpnt->target]++;
+		  HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
 		  }
 
 	       break;
@@ -1020,8 +1045,10 @@
 	    case 0x96:     /* Illegal SCSI command */
 	    case 0xa3:     /* SCSI bus reset error */
 
-	       for (k = 0; k < MAX_TARGET; k++) 
-		  HD(j)->target_reset[k] = TRUE;
+	       for (c = 0; c <= sh[j]->max_channel; c++) 
+	          for (k = 0; k < sh[j]->max_id; k++) 
+	             HD(j)->target_redo[k][c] = TRUE;
+   
 
 	    case 0x92:     /* Data over/under-run */
 
@@ -1061,9 +1088,10 @@
 	     do_trace)
 #endif
 	    printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
-		   " target %d:%d, pid %ld, count %d.\n",
+		   " target %d.%d:%d, pid %ld, count %d.\n",
 		   BN(j), i, spp->adapter_status, spp->target_status,
-		   SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
+		   SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+                   HD(j)->iocount);
 
 	 /* Set the command state to inactive */
 	 SCpnt->host_scribble = NULL;
diff -u --recursive --new-file v2.1.11/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h
--- v2.1.11/linux/drivers/scsi/u14-34f.h	Sat Oct  5 16:58:35 1996
+++ linux/drivers/scsi/u14-34f.h	Tue Nov 19 16:21:52 1996
@@ -10,7 +10,7 @@
 int u14_34f_reset(Scsi_Cmnd *, unsigned int);
 int u14_34f_biosparam(Disk *, kdev_t, int *);
 
-#define U14_34F_VERSION "2.12.00"
+#define U14_34F_VERSION "2.20.00"
 
 #define ULTRASTOR_14_34F {                                            \
 		NULL, /* Ptr for modules */                           \
diff -u --recursive --new-file v2.1.11/linux/fs/binfmt_java.c linux/fs/binfmt_java.c
--- v2.1.11/linux/fs/binfmt_java.c	Sat Sep 14 11:08:07 1996
+++ linux/fs/binfmt_java.c	Thu Nov 21 11:00:33 1996
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 1996  Brian A. Lantz
  *  derived from binfmt_script.c
+ *
+ *  Simplified and modified to support binary java interpreters
+ *  by Tom May <ftom@netcom.com>.
  */
 
 #include <linux/module.h>
@@ -13,35 +16,50 @@
 
 #define _PATH_JAVA	"/usr/bin/java"
 #define _PATH_APPLET	"/usr/bin/appletviewer"
-#define _PATH_SH	"/bin/bash"
+
+/*  These paths can be modified with sysctl().  */
 
 char binfmt_java_interpreter[65] = _PATH_JAVA;
 char binfmt_java_appletviewer[65] = _PATH_APPLET;
 
-static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+static int do_load_java(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-	char *cp, *interp, *i_name;
+	char *i_name;
+	int len;
 	int retval;
 	unsigned char *ucp = (unsigned char *) bprm->buf;
 	if ((ucp[0] != 0xca) || (ucp[1] != 0xfe) || (ucp[2] != 0xba) || (ucp[3] != 0xbe)) 
 		return -ENOEXEC;
 
+	/*
+	 * Fail if we're called recursively, e.g., the Java interpreter
+	 * is a java binary.
+	 */
+
+	if (bprm->java)
+		return -ENOEXEC;
+
+	bprm->java = 1;
+
 	iput(bprm->inode);
 	bprm->dont_iput=1;
 
 	/*
-	 * OK, we've set the interpreter name
-	 * Splice in (1) the interpreter's name for argv[0] (_PATH_SH)
-	 *           (2) the name of the java wrapper for argv[1] (_PATH_JAVA)
-	 *           (3) filename of Java class (replace argv[0])
-	 *               without leading path or trailing '.class'
+	 * Set args: [0] the name of the java interpreter
+	 *           [1] name of java class to execute, which is the
+	 *		 filename without the path and without trailing
+	 *		 ".class".  Note that the interpreter will use
+	 *		 its own way to found the class file (typically using
+	 *		 environment variable CLASSPATH), and may in fact
+	 *		 execute a different file from the one we want.
 	 *
 	 * This is done in reverse order, because of how the
 	 * user environment and arguments are stored.
 	 */
 	remove_arg_zero(bprm);
-	if ((cp = strstr (bprm->filename, ".class")) != NULL)
-		*cp = 0;
+	len = strlen (bprm->filename);
+	if (len >= 6 && !strcmp (bprm->filename + len - 6, ".class"))
+		bprm->filename[len - 6] = 0;
 	if ((i_name = strrchr (bprm->filename, '/')) != NULL)
 		i_name++;
 	else
@@ -49,27 +67,17 @@
 	bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
 	bprm->argc++;
 
-	strcpy (bprm->buf, binfmt_java_interpreter);
-	cp = bprm->buf;
-	bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
-	bprm->argc++;
-
-	strcpy (bprm->buf, _PATH_SH);
-	interp = bprm->buf;
-	if ((i_name = strrchr (bprm->buf, '/')) != NULL)
-		i_name++;
-	else
-		i_name = bprm->buf;
+	i_name = binfmt_java_interpreter;
 	bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
 	bprm->argc++;
+
 	if (!bprm->p) 
 		return -E2BIG;
 	/*
 	 * OK, now restart the process with the interpreter's inode.
-	 * Note that we use open_namei() as the name is now in kernel
-	 * space, and we don't need to copy it.
 	 */
-	retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
+	bprm->filename = binfmt_java_interpreter;
+	retval = open_namei(binfmt_java_interpreter, 0, 0, &bprm->inode, NULL);
 	if (retval)
 		return retval;
 	bprm->dont_iput=0;
@@ -82,7 +90,7 @@
 
 static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-	char *cp, *interp, *i_name;
+	char *i_name;
 	int retval;
 	if (strncmp (bprm->buf, "<!--applet", 10))
 		return -ENOEXEC;
@@ -91,10 +99,8 @@
 	bprm->dont_iput=1;
 
 	/*
-	 * OK, we've set the interpreter name
-	 * Splice in (1) the interpreter's name for argv[0] (_PATH_SH)
-	 *           (2) the name of the appletviewer wrapper for argv[1] (_PATH_APPLET)
-	 *           (3) filename of html file (replace argv[0])
+	 * Set args: [0] the name of the appletviewer
+	 *           [1] filename of html file
 	 *
 	 * This is done in reverse order, because of how the
 	 * user environment and arguments are stored.
@@ -104,27 +110,17 @@
 	bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
 	bprm->argc++;
 
-	strcpy (bprm->buf, binfmt_java_appletviewer);
-	cp = bprm->buf;
-	bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
-	bprm->argc++;
-
-	strcpy (bprm->buf, _PATH_SH);
-	interp = bprm->buf;
-	if ((i_name = strrchr (bprm->buf, '/')) != NULL)
-		i_name++;
-	else
-		i_name = bprm->buf;
+	i_name = binfmt_java_appletviewer;
 	bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
 	bprm->argc++;
+
 	if (!bprm->p) 
 		return -E2BIG;
 	/*
 	 * OK, now restart the process with the interpreter's inode.
-	 * Note that we use open_namei() as the name is now in kernel
-	 * space, and we don't need to copy it.
 	 */
-	retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
+	bprm->filename = binfmt_java_appletviewer;
+	retval = open_namei(binfmt_java_appletviewer, 0, 0, &bprm->inode, NULL);
 	if (retval)
 		return retval;
 	bprm->dont_iput=0;
@@ -135,20 +131,20 @@
 	return search_binary_handler(bprm,regs);
 }
 
-static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+static int load_java(struct linux_binprm *bprm,struct pt_regs *regs)
 {
 	int retval;
 	MOD_INC_USE_COUNT;
-	retval = do_load_script(bprm,regs);
+	retval = do_load_java(bprm,regs);
 	MOD_DEC_USE_COUNT;
 	return retval;
 }
 
-struct linux_binfmt java_format = {
+static struct linux_binfmt java_format = {
 #ifndef MODULE
-	NULL, 0, load_script, NULL, NULL
+	NULL, 0, load_java, NULL, NULL
 #else
-	NULL, &mod_use_count_, load_script, NULL, NULL
+	NULL, &mod_use_count_, load_java, NULL, NULL
 #endif
 };
 
@@ -161,7 +157,7 @@
 	return retval;
 }
 
-struct linux_binfmt applet_format = {
+static struct linux_binfmt applet_format = {
 #ifndef MODULE
 	NULL, 0, load_applet, NULL, NULL
 #else
@@ -170,7 +166,6 @@
 };
 
 int init_java_binfmt(void) {
-	printk(KERN_INFO "JAVA Binary support v1.01 for Linux 1.3.98 (C)1996 Brian A. Lantz\n");
 	register_binfmt(&java_format);
 	return register_binfmt(&applet_format);
 }
@@ -182,7 +177,6 @@
 }
 
 void cleanup_module( void) {
-	printk(KERN_INFO "Removing JAVA Binary support...\n");
 	unregister_binfmt(&java_format);
 	unregister_binfmt(&applet_format);
 }
diff -u --recursive --new-file v2.1.11/linux/fs/binfmt_script.c linux/fs/binfmt_script.c
--- v2.1.11/linux/fs/binfmt_script.c	Sat Mar 23 14:46:40 1996
+++ linux/fs/binfmt_script.c	Thu Nov 21 11:02:27 1996
@@ -13,7 +13,8 @@
 
 static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-	char *cp, *interp, *i_name, *i_arg;
+	char *cp, *i_name, *i_arg;
+	char interp[128];
 	int retval;
 	if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
 		return -ENOEXEC;
@@ -38,9 +39,10 @@
 			break;
 	}
 	for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
-	if (!cp || *cp == '\0') 
+	if (cp == '\0') 
 		return -ENOEXEC; /* No interpreter name found */
-	interp = i_name = cp;
+	strcpy (interp, cp);
+	i_name = cp;
 	i_arg = 0;
 	for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
  		if (*cp == '/')
@@ -73,9 +75,8 @@
 		return -E2BIG;
 	/*
 	 * OK, now restart the process with the interpreter's inode.
-	 * Note that we use open_namei() as the name is now in kernel
-	 * space, and we don't need to copy it.
 	 */
+	bprm->filename = interp;
 	retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
 	if (retval)
 		return retval;
diff -u --recursive --new-file v2.1.11/linux/fs/exec.c linux/fs/exec.c
--- v2.1.11/linux/fs/exec.c	Fri Nov 15 23:49:09 1996
+++ linux/fs/exec.c	Thu Nov 21 11:00:33 1996
@@ -629,6 +629,7 @@
 		return retval;
 	bprm.filename = filename;
 	bprm.sh_bang = 0;
+	bprm.java = 0;
 	bprm.loader = 0;
 	bprm.exec = 0;
 	bprm.dont_iput = 0;
diff -u --recursive --new-file v2.1.11/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
--- v2.1.11/linux/fs/nfs/nfsroot.c	Tue Nov 12 15:56:11 1996
+++ linux/fs/nfs/nfsroot.c	Fri Nov 22 12:32:12 1996
@@ -1560,7 +1560,7 @@
  */
 static int *root_nfs_header(int proc, int program, int version)
 {
-	int groups[] = { 0, NOGROUP };
+	gid_t groups[] = { 0 };
 
 	if (rpc_packet == NULL) {
 		if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
@@ -1568,7 +1568,7 @@
 			return NULL;
 		}
 	}
-	return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
+	return rpc_header(rpc_packet, proc, program, version, 0, 0, 1, groups);
 }
 
 
diff -u --recursive --new-file v2.1.11/linux/fs/nfs/proc.c linux/fs/nfs/proc.c
--- v2.1.11/linux/fs/nfs/proc.c	Tue Oct 29 19:58:44 1996
+++ linux/fs/nfs/proc.c	Fri Nov 22 12:33:29 1996
@@ -904,10 +904,10 @@
  */
 
 int *rpc_header(int *p, int procedure, int program, int version,
-					int uid, int gid, int *groups)
+					int uid, int gid,
+					int ngroup, gid_t *groups)
 {
-	int *p1, *p2;
-	int i;
+	int *p1;
 	static int xid = 0;
 	unsigned char *sys = (unsigned char *) system_utsname.nodename;
 
@@ -927,10 +927,14 @@
 	p = xdr_encode_string(p, (char *) sys);
 	*p++ = htonl(uid);
 	*p++ = htonl(gid);
-	p2 = p++;
-	for (i = 0; i < 16 && i < NGROUPS && groups[i] != NOGROUP; i++)
-		*p++ = htonl(groups[i]);
-	*p2 = htonl(i);
+	if (ngroup > 16)
+		ngroup = 16;
+	*p++ = htonl(ngroup);
+	while (ngroup) {
+		*p++ = htonl(*groups);
+		groups++;
+		ngroup--;
+	}
 	*p1 = htonl((p - (p1 + 1)) << 2);
 	*p++ = htonl(RPC_AUTH_NULL);
 	*p++ = htonl(0);
@@ -942,7 +946,7 @@
 {
 	return rpc_header(p, procedure, NFS_PROGRAM, NFS_VERSION,
 			(ruid ? current->uid : current->fsuid),
-			current->egid, current->groups);
+			current->egid, current->ngroups, current->groups);
 }
 
 
diff -u --recursive --new-file v2.1.11/linux/include/asm-i386/uaccess.h linux/include/asm-i386/uaccess.h
--- v2.1.11/linux/include/asm-i386/uaccess.h	Tue Nov 19 15:53:56 1996
+++ linux/include/asm-i386/uaccess.h	Fri Nov 22 12:35:01 1996
@@ -408,7 +408,7 @@
 		"	.align 4\n"					   \
 		"	.long 0b,3b\n"					   \
 		".text"							   \
-		: "=r"(res), "=r"(count)				   \
+		: "=d"(res), "=c"(count)				   \
 		: "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \
 		: "si", "di", "ax", "memory")
 
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/atari_SLM.h linux/include/asm-m68k/atari_SLM.h
--- v2.1.11/linux/include/asm-m68k/atari_SLM.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-m68k/atari_SLM.h	Fri Nov 22 15:56:36 1996
@@ -0,0 +1,28 @@
+
+#ifndef _ATARI_SLM_H
+#define _ATARI_SLM_H
+
+/* Atari SLM laser printer specific ioctls */
+
+#define	SLMIOGSTAT	0xa100
+#define	SLMIOGPSIZE	0xa101
+#define	SLMIOGMFEED	0xa102
+
+#define	SLMIORESET	0xa140
+
+#define	SLMIOSPSIZE	0xa181
+#define	SLMIOSMFEED	0xa182
+
+/* Status returning structure (SLMIOGSTAT) */
+struct SLM_status {
+	int		stat;		/* numeric status code */
+	char	str[40];	/* status string */
+};
+
+/* Paper size structure (SLMIO[GS]PSIZE) */
+struct SLM_paper_size {
+	int		width;
+	int		height;
+};
+
+#endif /* _ATARI_SLM_H */
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/byteorder.h linux/include/asm-m68k/byteorder.h
--- v2.1.11/linux/include/asm-m68k/byteorder.h	Wed Sep 25 10:47:41 1996
+++ linux/include/asm-m68k/byteorder.h	Fri Nov 22 15:56:36 1996
@@ -9,6 +9,38 @@
 #define __BIG_ENDIAN_BITFIELD
 #endif
 
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <asm/types.h>
+
+/*
+ * In-kernel byte order macros to handle stuff like
+ * byte-order-dependent filesystems etc.
+ */
+
+#define le16_to_cpu(__val) __swab16(__val)
+#define le32_to_cpu(__val) __swab32(__val)
+#define cpu_to_le32(__val) __swab32(__val)
+#define cpu_to_le16(__val) __swab16(__val)
+
+extern __inline__ __u16 __swab16 (__u16 val)
+{
+	return (val << 8) | (val >> 8);
+}
+
+extern __inline__ __u32 __swab32 (__u32 val)
+{
+	__asm__ ("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
+	return val;
+}
+
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
+
+#endif
+
 #undef ntohl
 #undef ntohs
 #undef htonl
@@ -36,6 +68,11 @@
 
 #define __htonl(x) __ntohl(x)
 #define __htons(x) __ntohs(x)
+
+#define __constant_htonl(x) (x)
+#define __constant_htons(x) (x)
+#define __constant_ntohl(x) (x)
+#define __constant_ntohs(x) (x)
 
 #ifdef __OPTIMIZE__
 #define ntohl(x) __ntohl(x)
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/elf.h linux/include/asm-m68k/elf.h
--- v2.1.11/linux/include/asm-m68k/elf.h	Thu Aug  8 12:25:46 1996
+++ linux/include/asm-m68k/elf.h	Fri Nov 22 15:56:36 1996
@@ -6,10 +6,11 @@
  */
 
 #include <asm/ptrace.h>
+#include <asm/user.h>
 
 typedef unsigned long elf_greg_t;
 
-#define ELF_NGREG 20 /* d1-d7/a0-a6/d0/usp/orig_d0/sr/pc/fmtvec */
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef struct user_m68kfp_struct elf_fpregset_t;
@@ -45,9 +46,10 @@
 	pr_reg[8] = regs->a1;						\
 	pr_reg[14] = regs->d0;						\
 	pr_reg[15] = rdusp();						\
-	pr_reg[16] = 0; /* orig_d0 */					\
+	pr_reg[16] = regs->orig_d0;					\
 	pr_reg[17] = regs->sr;						\
 	pr_reg[18] = regs->pc;						\
+	pr_reg[19] = (regs->format << 12) | regs->vector;		\
 	{								\
 	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
 	  pr_reg[5] = sw->d6;						\
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/io.h linux/include/asm-m68k/io.h
--- v2.1.11/linux/include/asm-m68k/io.h	Wed Dec 27 22:46:55 1995
+++ linux/include/asm-m68k/io.h	Fri Nov 22 15:56:36 1996
@@ -1,38 +1,41 @@
 #ifndef _M68K_IO_H
 #define _M68K_IO_H
 
-static inline unsigned char get_user_byte_io(const char * addr)
-{
-	register unsigned char _v;
+#ifdef __KERNEL__
 
-	__asm__ __volatile__ ("moveb %1,%0":"=dm" (_v):"m" (*addr));
-	return _v;
-}
-#define inb_p(addr) get_user_byte_io((char *)(addr))
-#define inb(addr) get_user_byte_io((char *)(addr))
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
-static inline void put_user_byte_io(char val,char *addr)
-{
-	__asm__ __volatile__ ("moveb %0,%1"
-			      : /* no outputs */
-			      :"idm" (val),"m" (*addr)
-			      : "memory");
-}
-#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr))
-#define outb(x,addr) put_user_byte_io((x),(char *)(addr))
+#define inb_p(addr) readb(addr)
+#define inb(addr) readb(addr)
+
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outb_p(x,addr) outb(x,addr)
 
 /*
  * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/i386 mapping (but if we ever
- * make the kernel segment mapped at 0, we need to do translation
- * on the i386 as well)
  */
-extern unsigned long mm_vtop(unsigned long addr);
-extern unsigned long mm_ptov(unsigned long addr);
+extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
+extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
 
 extern inline unsigned long virt_to_phys(volatile void * address)
 {
-	return (unsigned long) mm_vtop((unsigned long)address);
+	return mm_vtop((unsigned long)address);
 }
 
 extern inline void * phys_to_virt(unsigned long address)
@@ -41,10 +44,11 @@
 }
 
 /*
- * IO bus memory addresses are also 1:1 with the physical address
+ * IO bus memory addresses are 1:1 with the physical address
  */
 #define virt_to_bus virt_to_phys
 #define bus_to_virt phys_to_virt
 
+#endif /* __KERNEL__ */
 
 #endif /* _M68K_IO_H */
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/ipc.h linux/include/asm-m68k/ipc.h
--- v2.1.11/linux/include/asm-m68k/ipc.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-m68k/ipc.h	Fri Nov 22 15:56:36 1996
@@ -0,0 +1,28 @@
+#ifndef __m68k_IPC_H__
+#define __m68k_IPC_H__
+
+/* 
+ * These are used to wrap system calls on m68k.
+ *
+ * See arch/m68k/kernel/sys_m68k.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/mman.h linux/include/asm-m68k/mman.h
--- v2.1.11/linux/include/asm-m68k/mman.h	Wed Oct  9 08:55:23 1996
+++ linux/include/asm-m68k/mman.h	Fri Nov 22 15:56:36 1996
@@ -16,6 +16,7 @@
 #define MAP_DENYWRITE	0x0800		/* ETXTBSY */
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 #define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/page.h linux/include/asm-m68k/page.h
--- v2.1.11/linux/include/asm-m68k/page.h	Wed Sep 25 10:47:41 1996
+++ linux/include/asm-m68k/page.h	Fri Nov 22 15:56:36 1996
@@ -10,6 +10,9 @@
 
 #define STRICT_MM_TYPECHECKS
 
+#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
 #ifdef STRICT_MM_TYPECHECKS
 /*
  * These are used to make use of C type-checking..
@@ -50,18 +53,14 @@
 
 #endif
 
-/* This is the cache mode to be used for pages containing page descriptors for
- * processors >= '040. It is in pte_mknocache(), and the variable is defined
- * and initialized in head.S */
-extern int m68k_pgtable_cachemode;
-
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 /* This handles the memory map.. */
 #define PAGE_OFFSET		0
-#define MAP_NR(addr)		(((unsigned long)(addr)) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED	(1<<15)
+#define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
+#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define MAP_NR(addr)		(__pa(addr) >> PAGE_SHIFT)
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/pgtable.h linux/include/asm-m68k/pgtable.h
--- v2.1.11/linux/include/asm-m68k/pgtable.h	Wed Sep 25 10:47:41 1996
+++ linux/include/asm-m68k/pgtable.h	Fri Nov 22 15:56:36 1996
@@ -116,7 +116,7 @@
  * area for the same reason. ;)
  */
 #define VMALLOC_OFFSET	(8*1024*1024)
-#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 
 #endif /* __ASSEMBLY__ */
@@ -147,7 +147,18 @@
 
 #ifndef __ASSEMBLY__
 
+/* This is the cache mode to be used for pages containing page descriptors for
+ * processors >= '040. It is in pte_mknocache(), and the variable is defined
+ * and initialized in head.S */
+extern int m68k_pgtable_cachemode;
+
+#if defined(CONFIG_M68040_OR_M68060_ONLY)
+#define mm_cachebits _PAGE_CACHE040
+#elif defined(CONFIG_M68020_OR_M68030_ONLY)
+#define mm_cachebits 0
+#else
 extern unsigned long mm_cachebits;
+#endif
 
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits)
@@ -215,8 +226,6 @@
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-extern unsigned long high_memory;
-
 /* For virtual address to physical address conversion */
 extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
 extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
@@ -227,8 +236,10 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = VTOP(page) | pgprot_val(pgprot); return pte; }
+#define mk_pte(page, pgprot) \
+({ pte_t __pte; pte_val(__pte) = VTOP(page) + pgprot_val(pgprot); __pte; })
+#define mk_pte_phys(physpage, pgprot) \
+({ pte_t __pte; pte_val(__pte) = VTOP(physpage) + pgprot_val(pgprot); __pte; })
 
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
@@ -239,7 +250,7 @@
 
 	ptep = (pte_t *) VTOP(ptep);
 	for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
-		pmdp->pmd[i] = _PAGE_TABLE | (unsigned long)ptep;
+		pmdp->pmd[i] = _PAGE_TABLE | _PAGE_ACCESSED | (unsigned long)ptep;
 }
 
 /* early termination version of the above */
@@ -249,11 +260,11 @@
 
 	ptep = (pte_t *) VTOP(ptep);
 	for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
-		pmdp->pmd[i] = _PAGE_PRESENT | (unsigned long)ptep;
+		pmdp->pmd[i] = _PAGE_PRESENT | _PAGE_ACCESSED | (unsigned long)ptep;
 }
 
 extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | VTOP(pmdp); }
+{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | VTOP(pmdp); }
 
 extern inline unsigned long pte_page(pte_t pte)
 { return PTOV(pte_val(pte) & PAGE_MASK); }
@@ -271,7 +282,7 @@
 
 extern inline int pmd_none2(pmd_t *pmd)		{ return !pmd_val(*pmd); }
 #define pmd_none(pmd) pmd_none2(&(pmd))
-extern inline int pmd_bad2(pmd_t *pmd)		{ return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE || pmd_page(*pmd) > high_memory; }
+extern inline int pmd_bad2(pmd_t *pmd)		{ return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
 #define pmd_bad(pmd) pmd_bad2(&(pmd))
 extern inline int pmd_present2(pmd_t *pmd)	{ return pmd_val(*pmd) & _PAGE_TABLE; }
 #define pmd_present(pmd) pmd_present2(&(pmd))
@@ -284,7 +295,7 @@
 }
 
 extern inline int pgd_none(pgd_t pgd)		{ return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
+extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
 extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd) & _PAGE_TABLE; }
 
 extern inline void pgd_clear(pgd_t * pgdp)	{ pgd_val(*pgdp) = 0; }
@@ -319,10 +330,8 @@
 /* to set the page-dir */
 extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
 {
-	tsk->tss.pagedir_v = (unsigned long *)pgdir;
-	tsk->tss.pagedir_p = VTOP(pgdir);
-	tsk->tss.crp[0] = 0x80000000 | _PAGE_SHORT;
-	tsk->tss.crp[1] = tsk->tss.pagedir_p;
+	tsk->tss.crp[0] = 0x80000000 | _PAGE_TABLE;
+	tsk->tss.crp[1] = VTOP(pgdir);
 	if (tsk == current) {
 		if (CPU_IS_040_OR_060)
 			__asm__ __volatile__ ("movel %0@,%/d0\n\t"
@@ -425,9 +434,10 @@
 {
 	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
 	if (pmd_none(*pmd)) {
-		pte_t * page = (pte_t *)get_free_page(GFP_KERNEL);
+		pte_t * page = (pte_t *)__get_free_page(GFP_KERNEL);
 		if (pmd_none(*pmd)) {
 			if (page) {
+				memset((void *) page, 0, PAGE_SIZE);
 				nocache_page((unsigned long)page);
 				pmd_set(pmd,page);
 				return page + address;
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/posix_types.h linux/include/asm-m68k/posix_types.h
--- v2.1.11/linux/include/asm-m68k/posix_types.h	Wed Sep 25 10:47:41 1996
+++ linux/include/asm-m68k/posix_types.h	Fri Nov 22 15:56:36 1996
@@ -13,6 +13,7 @@
 typedef unsigned short	__kernel_nlink_t;
 typedef long		__kernel_off_t;
 typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
 typedef unsigned int	__kernel_size_t;
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h
--- v2.1.11/linux/include/asm-m68k/processor.h	Wed Sep 25 10:47:42 1996
+++ linux/include/asm-m68k/processor.h	Fri Nov 22 15:56:36 1996
@@ -18,17 +18,9 @@
 /*
  * Bus types
  */
-#define EISA_bus__is_a_macro	1
 #define EISA_bus 0
-#define MCA_bus__is_a_macro	1
 #define MCA_bus 0
 
-/*
- * The m68k has no problems with write protection
- */
-#define wp_works_ok__is_a_macro	1
-#define wp_works_ok 1
-
 /* MAX floating point unit state size (FSAVE/FRESTORE) */
 #define FPSTATESIZE   (216/sizeof(unsigned char))
 
@@ -42,8 +34,6 @@
 	unsigned long  usp;		/* user stack pointer */
 	unsigned short sr;		/* saved status register */
 	unsigned short fs;		/* saved fs (sfc, dfc) */
-	unsigned long  *pagedir_v;	/* root page table virtual addr */
-	unsigned long  pagedir_p;	/* root page table physaddr */
 	unsigned long  crp[2];		/* cpu root pointer */
 	unsigned long  esp0;		/* points to SR of stack frame */
 	unsigned long  fp[8*3];
@@ -56,7 +46,7 @@
 #define INIT_TSS  { \
 	sizeof(init_kernel_stack) + (long) init_kernel_stack, 0, \
 	PS_S, KERNEL_DS, \
-	NULL, 0, {0, 0}, 0 \
+	{0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \
 }
 
 #define alloc_kernel_stack()    __get_free_page(GFP_KERNEL)
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/segment.h linux/include/asm-m68k/segment.h
--- v2.1.11/linux/include/asm-m68k/segment.h	Wed Sep 25 10:47:42 1996
+++ linux/include/asm-m68k/segment.h	Fri Nov 22 15:56:36 1996
@@ -18,322 +18,6 @@
 #ifndef __ASSEMBLY__
 
 /*
- * Uh, these should become the main single-value transfer routines..
- * They automatically use the right size if we just have the right
- * pointer type..
- */
-#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
-#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
-
-/*
- * This is a silly but good way to make sure that
- * the __put_user function is indeed always optimized,
- * and that we use the correct sizes..
- */
-extern int bad_user_access_length(void);
-
-#define __ptr(x) ((unsigned long *)(x))
-
-static inline void __put_user(unsigned long x, void * y, int size)
-{
-	switch (size) {
-		case 1:
-			__asm__ ("movesb %0,%1"
-				: /* no outputs */
-				:"r" (x),"m" (*__ptr(y)) : "memory");
-			break;
-		case 2:
-			__asm__ ("movesw %0,%1"
-				: /* no outputs */
-				:"r" (x),"m" (*__ptr(y)) : "memory");
-			break;
-		case 4:
-			__asm__ ("movesl %0,%1"
-				: /* no outputs */
-				:"r" (x),"m" (*__ptr(y)) : "memory");
-			break;
-		default:
-			bad_user_access_length();
-	}
-}
-
-static inline unsigned long __get_user(const void * y, int size)
-{
-	unsigned long result;
-
-	switch (size) {
-		case 1:
-			__asm__ ("movesb %1,%0"
-				 :"=r" (result)
-				 :"m" (*__ptr(y)));
-			return (unsigned char) result;
-		case 2:
-			__asm__ ("movesw %1,%0"
-				 :"=r" (result)
-				 :"m" (*__ptr(y)));
-			return (unsigned short) result;
-		case 4:
-			__asm__ ("movesl %1,%0"
-				 :"=r" (result)
-				 :"m" (*__ptr(y)));
-			return result;
-		default:
-			return bad_user_access_length();
-	}
-}
-#undef __ptr
-
-/*
- * These are deprecated..
- *
- * Use "put_user()" and "get_user()" with the proper pointer types instead.
- */
-
-#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
-#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
-#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
-
-#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
-#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
-#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
-
-#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
-
-static inline unsigned char get_user_byte(const char * addr)
-{
-	return __get_user(addr,1);
-}
-
-static inline unsigned short get_user_word(const short *addr)
-{
-	return __get_user(addr,2);
-}
-
-static inline unsigned long get_user_long(const int *addr)
-{
-	return __get_user(addr,4);
-}
-
-static inline void put_user_byte(char val,char *addr)
-{
-	__put_user(val, addr, 1);
-}
-
-static inline void put_user_word(short val,short * addr)
-{
-	__put_user(val, addr, 2);
-}
-
-static inline void put_user_long(unsigned long val,int * addr)
-{
-	__put_user(val, addr, 4);
-}
-
-#endif
-
-static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
-	unsigned long tmp;
-	if (n == 0) return;
-	tmp = n;
-	n >>= 2;
-	if (n != 0)
-		__asm__ __volatile__ ("1:\t"
-			 "movel %1@+,%/d0\n\t"
-			 "movesl %/d0,%2@+\n\t"
-			 "dbra %0,1b\n\t"
-			 "clrw %0\n\t"
-			 "subql #1,%0\n\t"
-			 "bccs 1b\n\t"
-			 : "=d" (n), "=a" (from), "=a" (to)
-			 : "0" (n-1), "1" (from), "2" (to)
-			 : "d0", "memory");
-	if (tmp & 2)
-		__asm__ __volatile__ ("movew %0@+,%/d0\n\t"
-			 "movesw %/d0,%1@+\n\t"
-			 : "=a" (from), "=a" (to)
-			 : "0" (from), "1" (to)
-			 : "d0", "memory");
-	if (tmp & 1)
-		__asm__ __volatile__ ("moveb %0@,%/d0\n\t"
-			 "movesb %/d0,%1@\n\t"
-			 : /* no outputs */
-			 : "a" (from), "a" (to)
-			 : "d0", "memory");
-}
-
-static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
-	switch (n) {
-		case 0:
-			return;
-		case 1:
-			__put_user(*(const char *) from, (char *) to, 1);
-			return;
-		case 2:
-			__put_user(*(const short *) from, (short *) to, 2);
-			return;
-		case 3:
-			__put_user(*(const short *) from, (short *) to, 2);
-			__put_user(*(2+(const char *) from), 2+(char *) to, 1);
-			return;
-		case 4:
-			__put_user(*(const int *) from, (int *) to, 4);
-			return;
-		case 8:
-			__put_user(*(const int *) from, (int *) to, 4);
-			__put_user(*(1+(const int *) from), 1+(int *) to, 4);
-			return;
-		case 12:
-			__put_user(*(const int *) from, (int *) to, 4);
-			__put_user(*(1+(const int *) from), 1+(int *) to, 4);
-			__put_user(*(2+(const int *) from), 2+(int *) to, 4);
-			return;
-		case 16:
-			__put_user(*(const int *) from, (int *) to, 4);
-			__put_user(*(1+(const int *) from), 1+(int *) to, 4);
-			__put_user(*(2+(const int *) from), 2+(int *) to, 4);
-			__put_user(*(3+(const int *) from), 3+(int *) to, 4);
-			return;
-	}
-#define COMMON(x)                     \
-__asm__ __volatile__ ("1:\n\t"        \
-            "movel %1@+,%/d0\n\t"     \
-            "movesl %/d0,%2@+\n\t"    \
-            "dbra %0,1b\n\t"          \
-            "clrw %0\n\t"             \
-            "subql #1,%0\n\t"         \
-            "bccs 1b\n\t"             \
-            x                     \
-            : "=d" (n), "=a" (from), "=a" (to)    \
-            : "1" (from), "2" (to), "0" (n/4-1)   \
-            : "d0", "memory");
-
-  switch (n % 4) {
-      case 0:
-          COMMON("");
-          return;
-      case 1:
-          COMMON("moveb %1@+,%/d0; movesb %/d0,%2@+");
-          return;
-      case 2:
-          COMMON("movew %1@+,%/d0; movesw %/d0,%2@+");
-          return;
-      case 3:
-          COMMON("movew %1@+,%/d0; movesw %/d0,%2@+\n\t"
-                 "moveb %1@+,%/d0; movesb %/d0,%2@+");
-          return;
-  }
-#undef COMMON
-}
-
-static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
-	unsigned long tmp;
-	if (n == 0) return;
-	tmp = n;
-	n >>= 2;
-	if (n != 0)
-		__asm__ __volatile__ ("1:\t"
-			 "movesl %1@+,%/d0\n\t"
-			 "movel %/d0,%2@+\n\t"
-			 "dbra %0,1b\n\t"
-			 "clrw %0\n\t"
-			 "subql #1,%0\n\t"
-			 "bccs 1b\n\t"
-			 : "=d" (n), "=a" (from), "=a" (to)
-			 : "0" (n-1), "1" (from), "2" (to)
-			 : "d0", "memory");
-	if (tmp & 2)
-		__asm__ __volatile__ ("movesw %0@+,%/d0\n\t"
-			 "movew %/d0,%1@+\n\t"
-			 : "=a" (from), "=a" (to)
-			 : "0" (from), "1" (to)
-			 : "d0", "memory");
-	if (tmp & 1)
-		__asm__ __volatile__ ("movesb %0@,%/d0\n\t"
-			 "moveb %/d0,%1@\n\t"
-			 : /* no outputs */
-			 : "a" (from), "a" (to)
-			 : "d0", "memory");
-}
-
-static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
-	switch (n) {
-		case 0:
-			return;
-		case 1:
-			*(char *)to = __get_user((const char *) from, 1);
-			return;
-		case 2:
-			*(short *)to = __get_user((const short *) from, 2);
-			return;
-		case 3:
-			*(short *) to = __get_user((const short *) from, 2);
-			*((char *) to + 2) = __get_user(2+(const char *) from, 1);
-			return;
-		case 4:
-			*(int *) to = __get_user((const int *) from, 4);
-			return;
-		case 8:
-			*(int *) to = __get_user((const int *) from, 4);
-			*(1+(int *) to) = __get_user(1+(const int *) from, 4);
-			return;
-		case 12:
-			*(int *) to = __get_user((const int *) from, 4);
-			*(1+(int *) to) = __get_user(1+(const int *) from, 4);
-			*(2+(int *) to) = __get_user(2+(const int *) from, 4);
-			return;
-		case 16:
-			*(int *) to = __get_user((const int *) from, 4);
-			*(1+(int *) to) = __get_user(1+(const int *) from, 4);
-			*(2+(int *) to) = __get_user(2+(const int *) from, 4);
-			*(3+(int *) to) = __get_user(3+(const int *) from, 4);
-			return;
-	}
-#define COMMON(x)                     \
-__asm__ __volatile__ ("1:\n\t"        \
-            "movesl %1@+,%/d0\n\t"    \
-            "movel %/d0,%2@+\n\t"     \
-            "dbra %0,1b\n\t"          \
-            "clrw %0\n\t"             \
-            "subql #1,%0\n\t"         \
-            "bccs 1b\n\t"             \
-            x                         \
-            : "=d" (n), "=a" (from), "=a" (to)    \
-            : "1" (from), "2" (to), "0" (n/4-1)   \
-            : "d0", "memory");
-
-  switch (n % 4) {
-      case 0:
-          COMMON("");
-          return;
-      case 1:
-          COMMON("movesb %1@+,%/d0; moveb %/d0,%2@+");
-          return;
-      case 2:
-          COMMON("movesw %1@+,%/d0; movew %/d0,%2@+");
-          return;
-      case 3:
-          COMMON("movesw %1@+,%/d0; movew %/d0,%2@+\n\t"
-                 "movesb %1@+,%/d0; moveb %/d0,%2@+");
-          return;
-  }
-#undef COMMON
-}
-
-#define memcpy_fromfs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_fromfs((to),(from),(n)) : \
- __generic_memcpy_fromfs((to),(from),(n)))
-
-#define memcpy_tofs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_tofs((to),(from),(n)) : \
- __generic_memcpy_tofs((to),(from),(n)))
-
-/*
  * Get/set the SFC/DFC registers for MOVES instructions
  */
 
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/semaphore.h linux/include/asm-m68k/semaphore.h
--- v2.1.11/linux/include/asm-m68k/semaphore.h	Wed Sep 25 10:47:42 1996
+++ linux/include/asm-m68k/semaphore.h	Fri Nov 22 15:56:36 1996
@@ -20,8 +20,8 @@
 #define MUTEX ((struct semaphore) { 1, 0, NULL })
 #define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL })
 
-asmlinkage void down_failed(void /* special register calling convention */);
-asmlinkage void up_wakeup(void /* special register calling convention */);
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
 
 extern void __down(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
@@ -35,14 +35,14 @@
 {
 	register struct semaphore *sem1 __asm__ ("%a1") = sem;
 	__asm__ __volatile__(
-		"# atomic down operation\n"
-		"1:\n\t"
-		"lea %%pc@(1b),%%a0\n\t"
+		"| atomic down operation\n\t"
+		"lea %%pc@(1f),%%a0\n\t"
 		"subql #1,%0\n\t"
-		"jmi " SYMBOL_NAME_STR(down_failed)
+		"jmi " SYMBOL_NAME_STR(__down_failed) "\n"
+		"1:"
 		: /* no outputs */
 		: "m" (sem->count), "a" (sem1)
-		: "%a0", "%d0", "%d1", "memory");
+		: "%a0", "memory");
 }
 
 /*
@@ -55,14 +55,14 @@
 {
 	register struct semaphore *sem1 __asm__ ("%a1") = sem;
 	__asm__ __volatile__(
-		"# atomic up operation\n\t"
+		"| atomic up operation\n\t"
 		"lea %%pc@(1f),%%a0\n\t"
 		"addql #1,%0\n\t"
-		"jls " SYMBOL_NAME_STR(up_wakeup) "\n"
+		"jle " SYMBOL_NAME_STR(__up_wakeup) "\n"
 		"1:"
 		: /* no outputs */
 		: "m" (sem->count), "a" (sem1)
-		: "%a0", "%d0", "%d1", "memory");
+		: "%a0", "memory");
 }
 
 #endif
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/sigcontext.h linux/include/asm-m68k/sigcontext.h
--- v2.1.11/linux/include/asm-m68k/sigcontext.h	Thu Mar  7 20:28:49 1996
+++ linux/include/asm-m68k/sigcontext.h	Fri Nov 22 15:56:36 1996
@@ -1,7 +1,7 @@
-#ifndef _ASMm68k_SIGCONTEXT_H
-#define _ASMm68k_SIGCONTEXT_H
+#ifndef _ASM_M68k_SIGCONTEXT_H
+#define _ASM_M68k_SIGCONTEXT_H
 
-struct sigcontext_struct {
+struct sigcontext {
 	unsigned long  sc_mask; 	/* old sigmask */
 	unsigned long  sc_usp;		/* old user stack pointer */
 	unsigned long  sc_d0;
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/stat.h linux/include/asm-m68k/stat.h
--- v2.1.11/linux/include/asm-m68k/stat.h	Wed Dec 27 22:47:26 1995
+++ linux/include/asm-m68k/stat.h	Fri Nov 22 15:56:36 1996
@@ -1,7 +1,7 @@
 #ifndef _M68K_STAT_H
 #define _M68K_STAT_H
 
-struct old_stat {
+struct __old_kernel_stat {
 	unsigned short st_dev;
 	unsigned short st_ino;
 	unsigned short st_mode;
@@ -15,7 +15,7 @@
 	unsigned long  st_ctime;
 };
 
-struct new_stat {
+struct stat {
 	unsigned short st_dev;
 	unsigned short __pad1;
 	unsigned long st_ino;
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/uaccess.h linux/include/asm-m68k/uaccess.h
--- v2.1.11/linux/include/asm-m68k/uaccess.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-m68k/uaccess.h	Fri Nov 22 15:56:36 1996
@@ -0,0 +1,799 @@
+#ifndef __M68K_UACCESS_H
+#define __M68K_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/* We let the MMU do all checking */
+#define access_ok(type,addr,size) 1
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr)				\
+({							\
+    int __pu_err;					\
+    typeof(*(ptr)) __pu_val = (x);			\
+    switch (sizeof (*(ptr))) {				\
+    case 1:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, b);	\
+	break;						\
+    case 2:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, w);	\
+	break;						\
+    case 4:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, l);	\
+	break;						\
+    default:						\
+	__pu_err = __put_user_bad();			\
+	break;						\
+    }							\
+    __pu_err;						\
+})
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+#define __put_user_asm(err,x,ptr,bwl)			\
+__asm__ __volatile__					\
+    ("21:moves" #bwl " %2,%1\n"				\
+     "1:\n"						\
+     ".section .fixup,\"ax\"\n"				\
+     "   .even\n"					\
+     "2: movel %3,%0\n"					\
+     "   jra 1b\n"					\
+     ".section __ex_table,\"a\"\n"			\
+     "   .align 4\n"					\
+     "   .long 21b,2b\n"				\
+     "   .long 1b,2b\n"					\
+     ".text"						\
+     : "=d"(err)					\
+     : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
+
+#define get_user(x, ptr)					\
+({								\
+    int __gu_err;						\
+    typeof(*(ptr)) __gu_val;					\
+    switch (sizeof(*(ptr))) {					\
+    case 1:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, b, "=d");	\
+	break;							\
+    case 2:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, w, "=r");	\
+	break;							\
+    case 4:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, l, "=r");	\
+	break;							\
+    default:							\
+	__gu_val = 0;						\
+	__gu_err = __get_user_bad();				\
+	break;							\
+    }								\
+    (x) = __gu_val;						\
+    __gu_err;							\
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+#define __get_user_asm(err,x,ptr,bwl,reg)	\
+__asm__ __volatile__				\
+    ("1: moves" #bwl " %2,%1\n"			\
+     "2:\n"					\
+     ".section .fixup,\"ax\"\n"			\
+     "   .even\n"				\
+     "3: movel %3,%0\n"				\
+     "   sub" #bwl " %1,%1\n"			\
+     "   jra 2b\n"				\
+     ".section __ex_table,\"a\"\n"		\
+     "   .align 4\n"				\
+     "   .long 1b,3b\n"				\
+     ".text"					\
+     : "=d"(err), reg(x)			\
+     : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
+
+static inline unsigned long
+__generic_copy_from_user(void *to, const void *from, unsigned long n)
+{
+    unsigned long tmp;
+    __asm__ __volatile__
+	("   tstl %2\n"
+	 "   jeq 2f\n"
+	 "1: movesl (%1)+,%3\n"
+	 "   movel %3,(%0)+\n"
+	 "   subql #1,%2\n"
+	 "   jne 1b\n"
+	 "2: movel %4,%2\n"
+	 "   bclr #1,%2\n"
+	 "   jeq 4f\n"
+	 "3: movesw (%1)+,%3\n"
+	 "   movew %3,(%0)+\n"
+	 "4: bclr #0,%2\n"
+	 "   jeq 6f\n"
+	 "5: movesb (%1)+,%3\n"
+	 "   moveb %3,(%0)+\n"
+	 "6:\n"
+	 ".section .fixup,\"ax\"\n"
+	 "   .even\n"
+	 "7: lsll #2,%2\n"
+	 "   addl %4,%2\n"
+	 "   jra 6b\n"
+	 "8: addql #2,%2\n"
+	 "   jra 6b\n"
+	 "9: addql #1,%2\n"
+	 "   jra 6b\n"
+	 ".section __ex_table,\"a\"\n"
+	 "   .align 4\n"
+	 "   .long 1b,7b\n"
+	 "   .long 3b,8b\n"
+	 "   .long 5b,9b\n"
+	 ".text"
+	 : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+	 : "r"(n & 3), "0"(to), "1"(from), "2"(n/4)
+	 : "d0", "memory");
+    return n;
+}
+
+static inline unsigned long
+__generic_copy_to_user(void *to, const void *from, unsigned long n)
+{
+    unsigned long tmp;
+    __asm__ __volatile__
+	("   tstl %2\n"
+	 "   jeq 3f\n"
+	 "1: movel (%1)+,%3\n"
+	 "22:movesl %3,(%0)+\n"
+	 "2: subql #1,%2\n"
+	 "   jne 1b\n"
+	 "3: movel %4,%2\n"
+	 "   bclr #1,%2\n"
+	 "   jeq 4f\n"
+	 "   movew (%1)+,%3\n"
+	 "24:movesw %3,(%0)+\n"
+	 "4: bclr #0,%2\n"
+	 "   jeq 5f\n"
+	 "   moveb (%1)+,%3\n"
+	 "25:movesb %3,(%0)+\n"
+	 "5:\n"
+	 ".section .fixup,\"ax\"\n"
+	 "   .even\n"
+	 "6: lsll #2,%2\n"
+	 "   addl %4,%2\n"
+	 "   jra 5b\n"
+	 "7: addql #2,%2\n"
+	 "   jra 5b\n"
+	 "8: addql #1,%2\n"
+	 "   jra 5b\n"
+	 ".section __ex_table,\"a\"\n"
+	 "   .align 4\n"
+	 "   .long 22b,6b\n"
+	 "   .long 2b,6b\n"
+	 "   .long 24b,7b\n"
+	 "   .long 4b,7b\n"
+	 "   .long 25b,8b\n"
+	 "   .long 5b,8b\n"
+	 ".text"
+	 : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+	 : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4));
+    return n;
+}
+
+#define __copy_from_user_big(to, from, n, fixup, copy)	\
+    __asm__ __volatile__				\
+	("10: movesl (%1)+,%%d0\n"			\
+	 "    movel %%d0,(%0)+\n"			\
+	 "    subql #1,%2\n"				\
+	 "    jne 10b\n"				\
+	 ".section .fixup,\"ax\"\n"			\
+	 "    .even\n"					\
+	 "11: lsll #2,%2\n"				\
+	 fixup "\n"					\
+	 "    jra 12f\n"				\
+	 ".section __ex_table,\"a\"\n"			\
+	 "    .align 4\n"				\
+	 "    .long 10b,11b\n"				\
+	 ".text\n"					\
+	 copy "\n"					\
+	 ".text\n"					\
+	 "12:"						\
+	 : "=a"(to), "=a"(from), "=d"(n)		\
+	 : "0"(to), "1"(from), "2"(n/4)			\
+	 : "d0", "memory")
+
+static inline unsigned long
+__constant_copy_from_user(void *to, const void *from, unsigned long n)
+{
+    switch (n) {
+    case 0:
+	break;
+    case 1:
+	__asm__ __volatile__
+	    ("1: movesb (%1)+,%%d0\n"
+	     "   moveb %%d0,(%0)+\n"
+	     "2:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "3: addql #1,%2\n"
+	     "   jra 2b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 1b,3b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 2:
+	__asm__ __volatile__
+	    ("1: movesw (%1)+,%%d0\n"
+	     "   movew %%d0,(%0)+\n"
+	     "2:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "3: addql #2,%2\n"
+	     "   jra 2b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 1b,3b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 3:
+	__asm__ __volatile__
+	    ("1: movesw (%1)+,%%d0\n"
+	     "   movew %%d0,(%0)+\n"
+	     "2: movesb (%1)+,%%d0\n"
+	     "   moveb %%d0,(%0)+\n"
+	     "3:"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "4: addql #2,%2\n"
+	     "5: addql #1,%2\n"
+	     "   jra 3b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 1b,4b\n"
+	     "   .long 2b,5b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 4:
+	__asm__ __volatile__
+	    ("1: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "2:"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "3: addql #4,%2\n"
+	     "   jra 2b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 1b,3b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 8:
+	__asm__ __volatile__
+	    ("1: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "2: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "3:"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "4: addql #4,%2\n"
+	     "5: addql #4,%2\n"
+	     "   jra 3b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 1b,4b\n"
+	     "   .long 2b,5b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 12:
+	__asm__ __volatile__
+	    ("1: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "2: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "3: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "4:"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "5: addql #4,%2\n"
+	     "6: addql #4,%2\n"
+	     "7: addql #4,%2\n"
+	     "   jra 4b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 1b,5b\n"
+	     "   .long 2b,6b\n"
+	     "   .long 3b,7b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 16:
+	__asm__ __volatile__
+	    ("1: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "2: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "3: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "4: movesl (%1)+,%%d0\n"
+	     "   movel %%d0,(%0)+\n"
+	     "5:"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "6: addql #4,%2\n"
+	     "7: addql #4,%2\n"
+	     "8: addql #4,%2\n"
+	     "9: addql #4,%2\n"
+	     "   jra 5b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 1b,6b\n"
+	     "   .long 2b,7b\n"
+	     "   .long 3b,8b\n"
+	     "   .long 4b,9b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    default:
+	switch (n & 3) {
+	case 0:
+	    __copy_from_user_big(to, from, n, "", "");
+	    break;
+	case 1:
+	    __copy_from_user_big(to, from, n,
+				 /* fixup */
+				 "1: addql #1,%2",
+				 /* copy */
+				 "2: movesb (%1)+,%%d0\n"
+				 "   moveb %%d0,(%0)+\n"
+				 ".section __ex_table,\"a\"\n"
+				 "   .long 2b,1b");
+	    break;
+	case 2:
+	    __copy_from_user_big(to, from, n,
+				 /* fixup */
+				 "1: addql #2,%2",
+				 /* copy */
+				 "2: movesw (%1)+,%%d0\n"
+				 "   movew %%d0,(%0)+\n"
+				 ".section __ex_table,\"a\"\n"
+				 "   .long 2b,1b");
+	    break;
+	case 3:
+	    __copy_from_user_big(to, from, n,
+				 /* fixup */
+				 "1: addql #2,%2"
+				 "2: addql #1,%2",
+				 /* copy */
+				 "3: movesw (%1)+,%%d0\n"
+				 "   movew %%d0,(%0)+\n"
+				 "4: movesb (%1)+,%%d0\n"
+				 "   moveb %%d0,(%0)+\n"
+				 ".section __ex_table,\"a\"\n"
+				 "   .long 3b,1b\n"
+				 "   .long 4b,2b");
+	    break;
+	}
+	break;
+    }
+    return n;
+}
+
+#define __copy_to_user_big(to, from, n, fixup, copy)	\
+    __asm__ __volatile__				\
+	("10: movel (%1)+,%%d0\n"			\
+	 "31: movesl %%d0,(%0)+\n"			\
+	 "11: subql #1,%2\n"				\
+	 "    jne 10b\n"				\
+	 ".section .fixup,\"ax\"\n"			\
+	 "   .even\n"					\
+	 "12: lsll #2,%2\n"				\
+	 fixup "\n"					\
+	 "    jra 13f\n"				\
+	 ".section __ex_table,\"a\"\n"			\
+	 "    .align 4\n"				\
+	 "    .long 31b,12b\n"				\
+	 "    .long 11b,12b\n"				\
+	 ".text\n"					\
+	 copy "\n"					\
+	 ".text\n"					\
+	 "13:"						\
+	 : "=a"(to), "=a"(from), "=d"(n)		\
+	 : "0"(to), "1"(from), "2"(n/4)			\
+	 : "d0")
+
+static inline unsigned long
+__constant_copy_to_user(void *to, const void *from, unsigned long n)
+{
+    switch (n) {
+    case 0:
+	break;
+    case 1:
+	__asm__ __volatile__
+	    ("   moveb (%1)+,%%d0\n"
+	     "21:movesb %%d0,(%0)+\n"
+	     "1:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "2: addql #1,%2\n"
+	     "   jra 1b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n  "
+	     "   .long 21b,2b\n"
+	     "   .long 1b,2b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 2:
+	__asm__ __volatile__
+	    ("   movew (%1)+,%%d0\n"
+	     "21:movesw %%d0,(%0)+\n"
+	     "1:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "2: addql #2,%2\n"
+	     "   jra 1b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 21b,2b\n"
+	     "   .long 1b,2b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 3:
+	__asm__ __volatile__
+	    ("   movew (%1)+,%%d0\n"
+	     "21:movesw %%d0,(%0)+\n"
+	     "1: moveb (%1)+,%%d0\n"
+	     "22:movesb %%d0,(%0)+\n"
+	     "2:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "3: addql #2,%2\n"
+	     "4: addql #1,%2\n"
+	     "   jra 2b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 21b,3b\n"
+	     "   .long 1b,3b\n"
+	     "   .long 22b,4b\n"
+	     "   .long 2b,4b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 4:
+	__asm__ __volatile__
+	    ("   movel (%1)+,%%d0\n"
+	     "21:movesl %%d0,(%0)+\n"
+	     "1:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "2: addql #4,%2\n"
+	     "   jra 1b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 21b,2b\n"
+	     "   .long 1b,2b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 8:
+	__asm__ __volatile__
+	    ("   movel (%1)+,%%d0\n"
+	     "21:movesl %%d0,(%0)+\n"
+	     "1: movel (%1)+,%%d0\n"
+	     "22:movesl %%d0,(%0)+\n"
+	     "2:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "3: addql #4,%2\n"
+	     "4: addql #4,%2\n"
+	     "   jra 2b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 21b,3b\n"
+	     "   .long 1b,3b\n"
+	     "   .long 22b,4b\n"
+	     "   .long 2b,4b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 12:
+	__asm__ __volatile__
+	    ("   movel (%1)+,%%d0\n"
+	     "21:movesl %%d0,(%0)+\n"
+	     "1: movel (%1)+,%%d0\n"
+	     "22:movesl %%d0,(%0)+\n"
+	     "2: movel (%1)+,%%d0\n"
+	     "23:movesl %%d0,(%0)+\n"
+	     "3:\n"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "4: addql #4,%2\n"
+	     "5: addql #4,%2\n"
+	     "6: addql #4,%2\n"
+	     "   jra 3b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 21b,4b\n"
+	     "   .long 1b,4b\n"
+	     "   .long 22b,5b\n"
+	     "   .long 2b,5b\n"
+	     "   .long 23b,6b\n"
+	     "   .long 3b,6b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    case 16:
+	__asm__ __volatile__
+	    ("   movel (%1)+,%%d0\n"
+	     "21:movesl %%d0,(%0)+\n"
+	     "1: movel (%1)+,%%d0\n"
+	     "22:movesl %%d0,(%0)+\n"
+	     "2: movel (%1)+,%%d0\n"
+	     "23:movesl %%d0,(%0)+\n"
+	     "3: movel (%1)+,%%d0\n"
+	     "24:movesl %%d0,(%0)+\n"
+	     "4:"
+	     ".section .fixup,\"ax\"\n"
+	     "   .even\n"
+	     "5: addql #4,%2\n"
+	     "6: addql #4,%2\n"
+	     "7: addql #4,%2\n"
+	     "8: addql #4,%2\n"
+	     "   jra 4b\n"
+	     ".section __ex_table,\"a\"\n"
+	     "   .align 4\n"
+	     "   .long 21b,5b\n"
+	     "   .long 1b,5b\n"
+	     "   .long 22b,6b\n"
+	     "   .long 2b,6b\n"
+	     "   .long 23b,7b\n"
+	     "   .long 3b,7b\n"
+	     "   .long 24b,8b\n"
+	     "   .long 4b,8b\n"
+	     ".text"
+	     : "=a"(to), "=a"(from), "=d"(n)
+	     : "0"(to), "1"(from), "2"(0)
+	     : "d0", "memory");
+	break;
+    default:
+	switch (n & 3) {
+	case 0:
+	    __copy_to_user_big(to, from, n, "", "");
+	    break;
+	case 1:
+	    __copy_to_user_big(to, from, n,
+			       /* fixup */
+			       "1: addql #1,%2",
+			       /* copy */
+			       "   moveb (%1)+,%%d0\n"
+			       "22:movesb %%d0,(%0)+\n"
+			       "2:"
+			       ".section __ex_table,\"a\"\n"
+			       "   .long 22b,1b\n"
+			       "   .long 2b,1b");
+	    break;
+	case 2:
+	    __copy_to_user_big(to, from, n,
+			       /* fixup */
+			       "1: addql #2,%2",
+			       /* copy */
+			       "   movew (%1)+,%%d0\n"
+			       "22:movesw %%d0,(%0)+\n"
+			       "2:"
+			       ".section __ex_table,\"a\"\n"
+			       "   .long 22b,1b\n"
+			       "   .long 2b,1b");
+	    break;
+	case 3:
+	    __copy_to_user_big(to, from, n,
+			       /* fixup */
+			       "1: addql #2,%2"
+			       "2: addql #1,%2",
+			       /* copy */
+			       "   movew (%1)+,%%d0\n"
+			       "23:movesw %%d0,(%0)+\n"
+			       "3: moveb (%1)+,%%d0\n"
+			       "24:movesb %%d0,(%0)+\n"
+			       "4:"
+			       ".section __ex_table,\"a\"\n"
+			       "   .long 23b,1b\n"
+			       "   .long 3b,1b\n"
+			       "   .long 24b,2b\n"
+			       "   .long 4b,2b");
+	    break;
+	}
+	break;
+    }
+    return n;
+}
+
+#define copy_from_user(to, from, n)		\
+(__builtin_constant_p(n) ?			\
+ __constant_copy_from_user(to, from, n) :	\
+ __generic_copy_from_user(to, from, n))
+
+#define copy_to_user(to, from, n)		\
+(__builtin_constant_p(n) ?			\
+ __constant_copy_to_user(to, from, n) :		\
+ __generic_copy_to_user(to, from, n))
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+    long res;
+    if (count == 0) return count;
+    __asm__ __volatile__
+	("1: movesb (%2)+,%%d0\n"
+	 "12:moveb %%d0,(%1)+\n"
+	 "   jeq 2f\n"
+	 "   subql #1,%3\n"
+	 "   jne 1b\n"
+	 "2: subl %3,%0\n"
+	 "3:\n"
+	 ".section .fixup,\"ax\"\n"
+	 "   .even\n"
+	 "4: movel %4,%0\n"
+	 "   jra 3b\n"
+	 ".section __ex_table,\"a\"\n"
+	 "   .align 4\n"
+	 "   .long 1b,4b\n"
+	 "   .long 12b,4b\n"
+	 ".text"
+	 : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
+	 : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
+	 : "d0", "memory");
+    return res;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+static inline long strlen_user(const char * src)
+{
+    long res = (long) src;
+    __asm__ __volatile__
+	("1: movesb (%1)+,%%d0\n"
+	 "12:tstb %%d0\n"
+	 "   jne 1b\n"
+	 "   subl %1,%0\n"
+	 "   negl %0\n"
+	 "2:\n"
+	 ".section .fixup,\"ax\"\n"
+	 "   .even\n"
+	 "3: moveq %2,%0\n"
+	 "   jra 2b\n"
+	 ".section __ex_table,\"a\"\n"
+	 "   .align 4\n"
+	 "   .long 1b,3b\n"
+	 "   .long 12b,3b\n"
+	 ".text"
+	 : "=d"(res), "=a"(src)
+	 : "i"(0), "0"(res), "1"(src)
+	 : "d0", "memory");
+    return res;
+}
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+    __asm__ __volatile__
+	("   tstl %1\n"
+	 "   jeq 3f\n"
+	 "1: movesl %3,(%0)+\n"
+	 "2: subql #1,%1\n"
+	 "   jne 1b\n"
+	 "3: movel %2,%1\n"
+	 "   bclr #1,%1\n"
+	 "   jeq 4f\n"
+	 "24:movesw %3,(%0)+\n"
+	 "4: bclr #0,%1\n"
+	 "   jeq 5f\n"
+	 "25:movesb %3,(%0)+\n"
+	 "5:\n"
+	 ".section .fixup,\"ax\"\n"
+	 "   .even\n"
+	 "6: lsll #2,%1\n"
+	 "   addl %2,%1\n"
+	 "   jra 5b\n"
+	 "7: addql #2,%1\n"
+	 "   jra 5b\n"
+	 "8: addql #1,%1\n"
+	 "   jra 5b\n"
+	 ".section __ex_table,\"a\"\n"
+	 "   .align 4\n"
+	 "   .long 1b,6b\n"
+	 "   .long 2b,6b\n"
+	 "   .long 24b,7b\n"
+	 "   .long 4b,7b\n"
+	 "   .long 25b,8b\n"
+	 "   .long 5b,8b\n"
+	 ".text"
+	 : "=a"(to), "=d"(n)
+	 : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
+    return n;
+}
+
+#endif /* _M68K_UACCESS_H */
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h
--- v2.1.11/linux/include/asm-m68k/unistd.h	Wed Sep 25 10:47:42 1996
+++ linux/include/asm-m68k/unistd.h	Fri Nov 22 15:56:36 1996
@@ -169,8 +169,20 @@
 #define __NR_sched_rr_get_interval	161
 #define __NR_nanosleep		162
 #define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
 
-#ifdef __ELF__
+/* user-visible error numbers are in the range -1 - -122: see
+   <asm-m68k/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+		errno = -(res); \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
 
 #define _syscall0(type,name) \
 type name(void) \
@@ -178,223 +190,84 @@
 register long __res __asm__ ("%d0") = __NR_##name; \
 __asm__ __volatile__ ("trap  #0" \
                       : "=g" (__res) \
-                      : "0" (__NR_##name) \
+		      : "0" (__res) \
 		      : "%d0"); \
-if (__res >= 0) \
-	return (type) __res; \
-errno = -__res; \
-return -1; \
+__syscall_return(type,__res); \
 }
 
 #define _syscall1(type,name,atype,a) \
 type name(atype a) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)) \
-                      : "%d0", "%d1"); \
-if (__res >= 0) \
-	return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+__asm__ __volatile__ ("trap  #0" \
+		      : "=d" (__res) \
+		      : "0" (__res), "d" (__a) \
+		      : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall2(type,name,atype,a,btype,b) \
 type name(atype a,btype b) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-		      "movel %3,%/d2\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)) \
-                      : "%d0", "%d1", "%d2"); \
-if (__res >= 0) \
-	return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+__asm__ __volatile__ ("trap  #0" \
+		      : "=d" (__res) \
+                      : "0" (__res), "d" (__a), "d" (__b) \
+		      : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall3(type,name,atype,a,btype,b,ctype,c) \
 type name(atype a,btype b,ctype c) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-		      "movel %3,%/d2\n\t" \
-		      "movel %4,%/d3\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)) \
-                      : "%d0", "%d1", "%d2", "%d3"); \
-if (__res >= 0) \
-	return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+__asm__ __volatile__ ("trap  #0" \
+		      : "=d" (__res) \
+                      : "0" (__res), "d" (__a), "d" (__b), \
+			"d" (__c) \
+		      : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
 type name (atype a, btype b, ctype c, dtype d) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-		      "movel %3,%/d2\n\t" \
-		      "movel %4,%/d3\n\t" \
-		      "movel %5,%/d4\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-					  "g" ((long)(c)), \
-					  "g" ((long)(d))  \
-                      : "%d0", "%d1", "%d2", "%d3", "%d4"); \
-if (__res >= 0) \
-	return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+register long __d __asm__ ("%d4") = (long)(d); \
+__asm__ __volatile__ ("trap  #0" \
+                      : "=d" (__res) \
+                      : "0" (__res), "d" (__a), "d" (__b), \
+			"d" (__c), "d" (__d)  \
+		      : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
 type name (atype a,btype b,ctype c,dtype d,etype e) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-		      "movel %3,%/d2\n\t" \
-		      "movel %4,%/d3\n\t" \
-		      "movel %5,%/d4\n\t" \
-		      "movel %6,%/d5\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-					  "g" ((long)(c)), \
-					  "g" ((long)(d)), \
-					  "g" ((long)(e))  \
-                      : "%d0", "%d1", "%d2", "%d3", "%d4", "%d5"); \
-if (__res >= 0) \
-	return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#else /* not ELF; a.out */
-
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+register long __d __asm__ ("%d4") = (long)(d); \
+register long __e __asm__ ("%d5") = (long)(e); \
 __asm__ __volatile__ ("trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name) \
-		      : "d0"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall1(type,name,atype,a) \
-type name(atype a) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)) \
-                      : "d0", "d1"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall2(type,name,atype,a,btype,b) \
-type name(atype a,btype b) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)) \
-                      : "d0", "d1", "d2"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
-type name(atype a,btype b,ctype c) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "movel %4,d3\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)) \
-                      : "d0", "d1", "d2", "d3"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
+		      : "=d" (__res) \
+		      : "0" (__res), "d" (__a), "d" (__b), \
+			"d" (__c), "d" (__d), "d" (__e)  \
+                      : "%d0"); \
+__syscall_return(type,__res); \
 }
 
-#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
-type name (atype a, btype b, ctype c, dtype d) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "movel %4,d3\n\t" \
-                      "movel %5,d4\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)), \
-                                          "g" ((long)(d))  \
-                      : "d0", "d1", "d2", "d3", "d4"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-type name (atype a,btype b,ctype c,dtype d,etype e) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "movel %4,d3\n\t" \
-                      "movel %5,d4\n\t" \
-                      "movel %6,d5\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)), \
-                                          "g" ((long)(d)), \
-                                          "g" ((long)(e))  \
-                      : "d0", "d1", "d2", "d3", "d4", "d5"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#endif /* ELF or otherwise */
-
 #ifdef __KERNEL_SYSCALLS__
 
 /*
@@ -437,25 +310,25 @@
 {
 	register long retval __asm__ ("d0") = __NR_clone;
 	register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
-	unsigned short fs;
+	unsigned long fs;
 
 	fs = get_fs();
 	set_fs (KERNEL_DS);
 
 	__asm__ __volatile__
-	  ("movel %%sp,%%d2\n\t"
-	   "trap #0\n\t"		/* Linux/m68k system call */
-	   "cmpl %%sp,%%d2\n\t"		/* child or parent */
-	   "jeq 1f\n\t"			/* parent - jump */
+	  ("trap #0\n\t"		/* Linux/m68k system call */
+	   "tstl %0\n\t"		/* child or parent */
+	   "jne 1f\n\t"			/* parent - jump */
 	   "movel %3,%%sp@-\n\t"	/* push argument */
 	   "jsr %4@\n\t"		/* call fn */
+	   "movel %0,%%d1\n\t"		/* pass exit value */
 	   "movel %2,%0\n\t"		/* exit */
 	   "trap #0\n"
 	   "1:"
 	   : "=d" (retval)
 	   : "0" (__NR_clone), "i" (__NR_exit),
 	     "r" (arg), "a" (fn), "d" (clone_arg)
-	   : "d0", "d2");
+	   : "d0");
 
 	set_fs (fs);
 	return retval;
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/user.h linux/include/asm-m68k/user.h
--- v2.1.11/linux/include/asm-m68k/user.h	Wed Mar 13 22:31:42 1996
+++ linux/include/asm-m68k/user.h	Fri Nov 22 15:56:36 1996
@@ -35,14 +35,30 @@
 	unsigned long  fpcntl[3];	/* fp control regs */
 };
 
+/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
+   is still the layout used by user (the new pt_regs doesn't have
+   all registers). */
+struct user_regs_struct {
+	long d1,d2,d3,d4,d5,d6,d7;
+	long a0,a1,a2,a3,a4,a5,a6;
+	long d0;
+	long usp;
+	long orig_d0;
+	short stkadj;
+	short sr;
+	long pc;
+	short fmtvec;
+	short __fill;
+};
+
+	
 /* When the kernel dumps core, it starts by dumping the user struct -
    this will be used by gdb to figure out where the data and stack segments
    are within the file, and what virtual addresses to use. */
 struct user{
 /* We start with the registers, to mimic the way that "memory" is returned
    from the ptrace(3,...) function.  */
-  struct pt_regs regs;		/* Where the registers are actually stored */
-  struct switch_stack regs2;	/* Backward compatibility, sort of */
+  struct user_regs_struct regs;	/* Where the registers are actually stored */
 /* ptrace does not yet supply these.  Someday.... */
   int u_fpvalid;		/* True if math co-processor being used. */
                                 /* for this mess. Not yet used. */
diff -u --recursive --new-file v2.1.11/linux/include/asm-m68k/zorro.h linux/include/asm-m68k/zorro.h
--- v2.1.11/linux/include/asm-m68k/zorro.h	Wed Sep 25 10:47:42 1996
+++ linux/include/asm-m68k/zorro.h	Fri Nov 22 15:56:36 1996
@@ -355,7 +355,7 @@
 #define PROD_BLIZZARD_1230_III (0x0D)	/* Blizzard 1230-III Turbo Board */
 #define PROD_BLIZZARD_1230_IV  (0x11)	/* Blizzard 1230-IV/1260 Turbo Board */
 #define PROD_BLIZZARD_2060SCSI (0x18)	/* Blizzard 2060 SCSI Controller */
-#define PROD_CYBERSTORM        (0x19)	/* CyberStorm */
+#define PROD_CYBERSTORM_II     (0x19)	/* CyberStorm Mk II */
 #define PROD_CYBERVISION       (0x22)	/* CyberVision64 Graphics Board */
 
 #define MANUF_DPS              (0x2169)	/* DPS */
diff -u --recursive --new-file v2.1.11/linux/include/linux/binfmts.h linux/include/linux/binfmts.h
--- v2.1.11/linux/include/linux/binfmts.h	Wed May  8 18:28:01 1996
+++ linux/include/linux/binfmts.h	Thu Nov 21 11:00:32 1996
@@ -18,6 +18,7 @@
 	unsigned long page[MAX_ARG_PAGES];
 	unsigned long p;
 	int sh_bang;
+	int java;		/* Java binary, prevent recursive invocation */
 	struct inode * inode;
 	int e_uid, e_gid;
 	int argc, envc;
diff -u --recursive --new-file v2.1.11/linux/include/linux/linear.h linux/include/linux/linear.h
--- v2.1.11/linux/include/linux/linear.h	Mon Feb 26 13:51:45 1996
+++ linux/include/linux/linear.h	Thu Jan  1 02:00:00 1970
@@ -1,34 +0,0 @@
-
-#ifndef _LINEAR_H
-#define _LINEAR_H
-
-struct linear_hash
-{
-  struct real_dev *dev0, *dev1;
-};
-
-struct linear_data
-{
-  struct linear_hash *hash_table; /* Dynamically allocated */
-  struct real_dev *smallest;
-  int nr_zones;
-};
-
-#endif
-
-#ifndef _LINEAR_H
-#define _LINEAR_H
-
-struct linear_hash
-{
-  struct real_dev *dev0, *dev1;
-};
-
-struct linear_data
-{
-  struct linear_hash *hash_table; /* Dynamically allocated */
-  struct real_dev *smallest;
-  int nr_zones;
-};
-
-#endif
diff -u --recursive --new-file v2.1.11/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.1.11/linux/include/linux/mm.h	Tue Oct 29 19:58:47 1996
+++ linux/include/linux/mm.h	Fri Nov 22 16:23:54 1996
@@ -308,10 +308,12 @@
 	unsigned long grow;
 
 	address &= PAGE_MASK;
+	grow = vma->vm_start - address;
 	if (vma->vm_end - address
-	    > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur)
+	    > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur ||
+	    (vma->vm_mm->total_vm << PAGE_SHIFT) + grow
+	    > (unsigned long) current->rlim[RLIMIT_AS].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;
diff -u --recursive --new-file v2.1.11/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- v2.1.11/linux/include/linux/nfs_fs.h	Mon Sep 30 11:19:00 1996
+++ linux/include/linux/nfs_fs.h	Fri Nov 22 12:34:55 1996
@@ -103,7 +103,7 @@
 				 unsigned long count, __u32 *buf);
 extern int nfs_proc_read_reply(struct rpc_ioreq *, struct nfs_fattr *);
 extern int *rpc_header(int *p, int procedure, int program, int version,
-				int uid, int gid, int *groups);
+				int uid, int gid, int ngroup, gid_t *groups);
 extern int *rpc_verify(int *p);
 
 /* linux/fs/nfs/sock.c */
diff -u --recursive --new-file v2.1.11/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.1.11/linux/include/linux/pci.h	Tue Nov 12 15:56:14 1996
+++ linux/include/linux/pci.h	Tue Nov 19 15:51:16 1996
@@ -532,6 +532,8 @@
 #define PCI_VENDOR_ID_S3		0x5333
 #define PCI_DEVICE_ID_S3_ViRGE		0x5631
 #define PCI_DEVICE_ID_S3_TRIO		0x8811
+#define PCI_DEVICE_ID_S3_AURORA64VP	0x8812
+#define PCI_DEVICE_ID_S3_TRIO64UVP	0x8814
 #define PCI_DEVICE_ID_S3_ViRGE_VX	0x883d
 #define PCI_DEVICE_ID_S3_868		0x8880
 #define PCI_DEVICE_ID_S3_928		0x88b0
diff -u --recursive --new-file v2.1.11/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.1.11/linux/include/linux/sched.h	Tue Nov 19 15:53:57 1996
+++ linux/include/linux/sched.h	Fri Nov 22 12:34:55 1996
@@ -200,7 +200,8 @@
 	int session;
 	/* boolean value for session group leader */
 	int leader;
-	int	groups[NGROUPS];
+	int ngroups;
+	gid_t groups[NGROUPS];
 	/* 
 	 * pointers to (original) parent process, youngest child, younger sibling,
 	 * older sibling, respectively.  (p->father can be replaced with 
@@ -290,7 +291,7 @@
 /* stack */	0,(unsigned long) &init_kernel_stack, \
 /* ec,brk... */	0,0,0,0,0, \
 /* pid etc.. */	0,0,0,0,0, \
-/* suppl grps*/ {NOGROUP,}, \
+/* suppl grps*/ 0, {0,}, \
 /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
 /* uid etc */	0,0,0,0,0,0,0,0, \
 /* timeout */	0,SCHED_OTHER,0,0,0,0,0,0,0, \
diff -u --recursive --new-file v2.1.11/linux/include/linux/socket.h linux/include/linux/socket.h
--- v2.1.11/linux/include/linux/socket.h	Tue Nov 19 15:53:58 1996
+++ linux/include/linux/socket.h	Fri Nov 22 12:03:43 1996
@@ -157,6 +157,7 @@
 #define SOL_NETROM	259
 #define SOL_ROSE	260
 #define SOL_DECNET	261
+#define	SOL_X25		262
 #define SOL_TCP		6
 #define SOL_UDP		17
 
diff -u --recursive --new-file v2.1.11/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.1.11/linux/include/linux/sysctl.h	Tue Nov 12 15:56:14 1996
+++ linux/include/linux/sysctl.h	Fri Nov 22 12:03:43 1996
@@ -134,6 +134,11 @@
 #define	NET_ROSE_ROUTING_CONTROL			6
 
 /* /proc/sys/net/x25 */
+#define	NET_X25_RESTART_REQUEST_TIMEOUT			1
+#define	NET_X25_CALL_REQUEST_TIMEOUT			2
+#define	NET_X25_RESET_REQUEST_TIMEOUT			3
+#define	NET_X25_CLEAR_REQUEST_TIMEOUT			4
+#define	NET_X25_ACK_HOLDBACK_TIMEOUT			5
 
 /* CTL_PROC names: */
 
diff -u --recursive --new-file v2.1.11/linux/include/linux/ucdrom.h linux/include/linux/ucdrom.h
--- v2.1.11/linux/include/linux/ucdrom.h	Tue Nov 12 15:56:14 1996
+++ linux/include/linux/ucdrom.h	Fri Nov 22 12:02:32 1996
@@ -13,8 +13,8 @@
 /* specifications */
         kdev_t dev;	                /* device number */
 	int mask;                       /* mask of capability: disables them */
-	const int speed;                /* maximum speed for reading data */
-	const int capacity;             /* number of discs in jukebox */
+	int speed;			/* maximum speed for reading data */
+	int capacity;			/* number of discs in jukebox */
 /* device-related storage */
 	int options : 30;               /* options flags */
 	unsigned mc_flags : 2;          /* media change buffer flags */
diff -u --recursive --new-file v2.1.11/linux/include/net/sock.h linux/include/net/sock.h
--- v2.1.11/linux/include/net/sock.h	Tue Nov 19 15:53:58 1996
+++ linux/include/net/sock.h	Fri Nov 22 12:36:59 1996
@@ -49,6 +49,9 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>	/* struct sk_buff */
 #include <net/protocol.h>		/* struct inet_protocol */
+#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
+#include <net/x25.h>
+#endif
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 #include <net/ax25.h>
 #if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
@@ -426,6 +429,9 @@
 #ifdef CONFIG_NUTCP		
 		struct tcp_opt		af_tcp;
 #endif		
+#endif
+#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
+		x25_cb			*x25;
 #endif
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 		ax25_cb			*ax25;
diff -u --recursive --new-file v2.1.11/linux/include/net/transp_v6.h linux/include/net/transp_v6.h
--- v2.1.11/linux/include/net/transp_v6.h	Sun Nov 10 20:12:18 1996
+++ linux/include/net/transp_v6.h	Fri Nov 22 12:41:27 1996
@@ -19,7 +19,7 @@
 
 extern int				udpv6_connect(struct sock *sk,
 						      struct sockaddr *uaddr,
-						      int addr_len);
+						      size_t addr_len);
 
 extern int			datagram_recv_ctl(struct sock *sk,
 						  struct msghdr *msg,
diff -u --recursive --new-file v2.1.11/linux/include/net/x25call.h linux/include/net/x25call.h
--- v2.1.11/linux/include/net/x25call.h	Thu Jan  1 02:00:00 1970
+++ linux/include/net/x25call.h	Fri Nov 22 12:03:43 1996
@@ -0,0 +1,2 @@
+/* Separate to keep compilation of protocols.c simpler */
+extern void x25_proto_init(struct net_proto *pro);
diff -u --recursive --new-file v2.1.11/linux/ipc/shm.c linux/ipc/shm.c
--- v2.1.11/linux/ipc/shm.c	Tue Oct 29 19:58:47 1996
+++ linux/ipc/shm.c	Fri Nov 22 16:23:54 1996
@@ -424,7 +424,11 @@
 	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;
+	tmp = shmd->vm_end - shmd->vm_start;
+	if((current->mm->total_vm << PAGE_SHIFT) + tmp
+	   > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur)
+		return -ENOMEM;
+	current->mm->total_vm += tmp >> PAGE_SHIFT;
 	insert_vm_struct(current->mm, shmd);
 	merge_segments(current->mm, shmd->vm_start, shmd->vm_end);
 
diff -u --recursive --new-file v2.1.11/linux/kernel/module.c linux/kernel/module.c
--- v2.1.11/linux/kernel/module.c	Tue Nov 19 15:53:59 1996
+++ linux/kernel/module.c	Tue Nov 19 15:48:50 1996
@@ -106,7 +106,7 @@
 		return -EPERM;
 	if (module_name == NULL || size == 0)
 		return -EINVAL;
-	if ((error = get_mod_name(module_name, name)) != 0)
+	if ((error = get_mod_name(module_name, name)) < 0)
 		return error;
 	if (find_module(name) != NULL) {
 		return -EEXIST;
@@ -168,7 +168,7 @@
 		symtab = NULL;
 	}
 #endif
-	if ((error = get_mod_name(module_name, name)) != 0)
+	if ((error = get_mod_name(module_name, name)) < 0)
 		return error;
 	pr_debug("initializing module `%s', %d (0x%x) bytes\n",
 		name, codesize, codesize);
@@ -292,7 +292,7 @@
 		return -EPERM;
 	/* else */
 	if (module_name != NULL) {
-		if ((error = get_mod_name(module_name, name)) != 0)
+		if ((error = get_mod_name(module_name, name)) < 0)
 			return error;
 		if ((mp = find_module(name)) == NULL)
 			return -ENOENT;
diff -u --recursive --new-file v2.1.11/linux/kernel/sys.c linux/kernel/sys.c
--- v2.1.11/linux/kernel/sys.c	Tue Nov 19 15:53:59 1996
+++ linux/kernel/sys.c	Fri Nov 22 11:49:58 1996
@@ -699,20 +699,15 @@
 asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
 {
 	int i;
-	int * groups;
 
 	if (gidsetsize < 0)
 		return -EINVAL;
-	groups = current->groups;
-	for (i = 0 ; i < NGROUPS ; i++) {
-		if (groups[i] == NOGROUP)
-			break;
-	}
+	i = current->ngroups;
 	if (gidsetsize) {
 		if (i > gidsetsize)
 		        return -EINVAL;
-		if (copy_to_user(grouplist, groups, sizeof(*groups)*i))
-				return -EFAULT;
+		if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
+			return -EFAULT;
 	}
 	return i;
 }
@@ -723,32 +718,34 @@
 
 	if (!suser())
 		return -EPERM;
-	if (gidsetsize > NGROUPS)
+	if ((unsigned) gidsetsize > NGROUPS)
 		return -EINVAL;
 	err = copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t));
 	if (err) {
-		gidsetsize = err/sizeof(gid_t); /* +1? */	
-        err = -EFAULT;
-    } 
-	if (gidsetsize < NGROUPS)
-		current->groups[gidsetsize] = NOGROUP;
+		gidsetsize = 0;
+		err = -EFAULT;
+	} 
+	current->ngroups = gidsetsize;
 	return err;
 }
 
 int in_group_p(gid_t grp)
 {
-	int	i;
-
-	if (grp == current->fsgid)
-		return 1;
-
-	for (i = 0; i < NGROUPS; i++) {
-		if (current->groups[i] == NOGROUP)
-			break;
-		if (current->groups[i] == grp)
-			return 1;
+	if (grp != current->fsgid) {
+		int i = current->ngroups;
+		if (i) {
+			gid_t *groups = current->groups;
+			do {
+				if (*groups == grp)
+					goto out;
+				groups++;
+				i--;
+			} while (i);
+		}
+		return 0;
 	}
-	return 0;
+out:
+	return 1;
 }
 
 asmlinkage int sys_newuname(struct new_utsname * name)
diff -u --recursive --new-file v2.1.11/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.1.11/linux/kernel/sysctl.c	Sun Nov 10 20:12:19 1996
+++ linux/kernel/sysctl.c	Fri Nov 22 11:50:57 1996
@@ -229,19 +229,23 @@
 /* Like in_group_p, but testing against egid, not fsgid */
 static int in_egroup_p(gid_t grp)
 {
-	int	i;
-
-	if (grp == current->euid)
-		return 1;
-
-	for (i = 0; i < NGROUPS; i++) {
-		if (current->groups[i] == NOGROUP)
-			break;
-		if (current->groups[i] == grp)
-			return 1;
+	if (grp != current->egid) {
+		int i = current->ngroups;
+		if (i) {
+			gid_t *groups = current->groups;
+			do {
+				if (*groups == grp)
+					goto out;
+				groups++;
+				i--;
+			} while (i);
+		}
+		return 0;
 	}
-	return 0;
+out:
+	return 1;
 }
+
 /* ctl_perm does NOT grant the superuser all rights automatically, because
    some sysctl variables are readonly even to root. */
 static int test_perm(int mode, int op)
diff -u --recursive --new-file v2.1.11/linux/mm/mmap.c linux/mm/mmap.c
--- v2.1.11/linux/mm/mmap.c	Tue Oct 29 19:58:48 1996
+++ linux/mm/mmap.c	Fri Nov 22 16:23:54 1996
@@ -107,11 +107,11 @@
 	/*
 	 * Ok, looks good - let it rip.
 	 */
-	mm->brk = brk;
-	do_mmap(NULL, oldbrk, newbrk-oldbrk,
+	if(do_mmap(NULL, oldbrk, newbrk-oldbrk,
 		PROT_READ|PROT_WRITE|PROT_EXEC,
-		MAP_FIXED|MAP_PRIVATE, 0);
-	return brk;
+		   MAP_FIXED|MAP_PRIVATE, 0) != oldbrk)
+		return mm->brk;
+	return mm->brk = brk;
 }
 
 /*
@@ -252,6 +252,13 @@
 	vma->vm_pte = 0;
 
 	do_munmap(addr, len);	/* Clear old maps */
+
+	/* Check against address space limit. */
+	if ((mm->total_vm << PAGE_SHIFT) + len
+	    > current->rlim[RLIMIT_AS].rlim_cur) {
+		kfree(vma);
+		return -ENOMEM;
+	}
 
 	/* Private writable mapping? Check memory availability.. */
 	if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE) {
diff -u --recursive --new-file v2.1.11/linux/mm/mremap.c linux/mm/mremap.c
--- v2.1.11/linux/mm/mremap.c	Tue Oct 29 19:58:48 1996
+++ linux/mm/mremap.c	Fri Nov 22 16:23:54 1996
@@ -146,6 +146,7 @@
 			insert_vm_struct(current->mm, new_vma);
 			merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end);
 			do_munmap(addr, old_len);
+			current->mm->total_vm += new_len >> PAGE_SHIFT;
 			return new_addr;
 		}
 		kfree(new_vma);
@@ -192,6 +193,9 @@
 		if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
 			return -EAGAIN;
 	}
+	if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
+	    > current->rlim[RLIMIT_AS].rlim_cur)
+		return -ENOMEM;
 
 	/* old_len exactly to the end of the area.. */
 	if (old_len == vma->vm_end - addr &&
diff -u --recursive --new-file v2.1.11/linux/net/Config.in linux/net/Config.in
--- v2.1.11/linux/net/Config.in	Tue Nov 19 15:53:59 1996
+++ linux/net/Config.in	Fri Nov 22 12:03:43 1996
@@ -30,6 +30,7 @@
   dep_tristate 'Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+# tristate 'CCITT X.25 Packet Layer' CONFIG_X25
   bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE
 fi
 endmenu
diff -u --recursive --new-file v2.1.11/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- v2.1.11/linux/net/ax25/af_ax25.c	Tue Nov 19 15:53:59 1996
+++ linux/net/ax25/af_ax25.c	Fri Nov 22 12:03:43 1996
@@ -279,8 +279,9 @@
 			s->state  = AX25_STATE_0;
 			s->device = NULL;
 			if (s->sk != NULL) {
-				s->sk->state = TCP_CLOSE;
-				s->sk->err   = ENETUNREACH;
+				s->sk->state     = TCP_CLOSE;
+				s->sk->err       = ENETUNREACH;
+				s->sk->shutdown |= SEND_SHUTDOWN;
 				if (!s->sk->dead)
 					s->sk->state_change(s->sk);
 				s->sk->dead  = 1;
@@ -617,8 +618,9 @@
 				
 			ax25->state = AX25_STATE_0;
 			if (ax25->sk != NULL) {
-				ax25->sk->state = TCP_CLOSE;
-				ax25->sk->err   = ENETRESET;
+				ax25->sk->state     = TCP_CLOSE;
+				ax25->sk->err       = ENETRESET;
+				ax25->sk->shutdown |= SEND_SHUTDOWN;
 				if (!ax25->sk->dead)
 					ax25->sk->state_change(ax25->sk);
 				ax25->sk->dead  = 1;
@@ -1295,6 +1297,7 @@
 		switch (sk->protinfo.ax25->state) {
 			case AX25_STATE_0:
 				sk->state       = TCP_CLOSE;
+				sk->shutdown   |= SEND_SHUTDOWN;
 				sk->state_change(sk);
 				sk->dead        = 1;
 				ax25_destroy_socket(sk->protinfo.ax25);
@@ -1304,6 +1307,7 @@
 				ax25_send_control(sk->protinfo.ax25, DISC, POLLON, C_COMMAND);
 				sk->protinfo.ax25->state = AX25_STATE_0;
 				sk->state                = TCP_CLOSE;
+				sk->shutdown            |= SEND_SHUTDOWN;
 				sk->state_change(sk);
 				sk->dead                 = 1;
 				ax25_destroy_socket(sk->protinfo.ax25);
@@ -1316,6 +1320,7 @@
 					ax25_send_control(sk->protinfo.ax25, DM, POLLON, C_RESPONSE);
 				sk->protinfo.ax25->state = AX25_STATE_0;
 				sk->state                = TCP_CLOSE;
+				sk->shutdown            |= SEND_SHUTDOWN;
 				sk->state_change(sk);
 				sk->dead                 = 1;
 				ax25_destroy_socket(sk->protinfo.ax25);
@@ -1334,6 +1339,7 @@
 				sk->protinfo.ax25->t1timer = sk->protinfo.ax25->t1 = ax25_calculate_t1(sk->protinfo.ax25);
 				sk->protinfo.ax25->state   = AX25_STATE_2;
 				sk->state                  = TCP_CLOSE;
+				sk->shutdown              |= SEND_SHUTDOWN;
 				sk->state_change(sk);
 				sk->dead                   = 1;
 				sk->destroy                = 1;
@@ -1344,8 +1350,9 @@
 		}
 	} else {
 		sk->state       = TCP_CLOSE;
+		sk->shutdown   |= SEND_SHUTDOWN;
 		sk->state_change(sk);
-		sk->dead = 1;
+		sk->dead        = 1;
 		ax25_destroy_socket(sk->protinfo.ax25);
 	}
 
@@ -1965,8 +1972,7 @@
 	if (sk->zapped)
 		return -EADDRNOTAVAIL;
 		
-	if (sk->shutdown & SEND_SHUTDOWN)
-	{
+	if (sk->shutdown & SEND_SHUTDOWN) {
 		send_sig(SIGPIPE, current, 0);
 		return -EPIPE;
 	}
@@ -2122,12 +2128,13 @@
 		skb->h.raw = skb->data;
 	}
 
-	copied=size;
-	if(copied>length)
-	{
-		copied = length;
-		msg->msg_flags|=MSG_TRUNC;
+	copied = length;
+
+	if (copied > size) {
+		copied = size;
+		msg->msg_flags |= MSG_TRUNC;
 	}		
+
 	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 	
 	if (sax) {
diff -u --recursive --new-file v2.1.11/linux/net/ax25/ax25_in.c linux/net/ax25/ax25_in.c
--- v2.1.11/linux/net/ax25/ax25_in.c	Tue Nov 19 15:53:59 1996
+++ linux/net/ax25/ax25_in.c	Fri Nov 22 12:03:43 1996
@@ -243,12 +243,12 @@
 					ax25_clear_queues(ax25);
 					ax25->state = AX25_STATE_0;
 					if (ax25->sk != NULL) {
-						ax25->sk->state = TCP_CLOSE;
-						ax25->sk->err   = ECONNREFUSED;
+						ax25->sk->state     = TCP_CLOSE;
+						ax25->sk->err       = ECONNREFUSED;
 						ax25->sk->shutdown |= SEND_SHUTDOWN;
 						if (!ax25->sk->dead)
 							ax25->sk->state_change(ax25->sk);
-						ax25->sk->dead  = 1;
+						ax25->sk->dead      = 1;
 					}
 				} else {
 					ax25->modulus = MODULUS;
@@ -286,14 +286,13 @@
 			if (ax25->dama_slave) {
 				ax25->state = AX25_STATE_0;
 				ax25_dama_off(ax25);
-
 				if (ax25->sk != NULL) {
-					ax25->sk->state = TCP_CLOSE;
-					ax25->sk->err   = 0;
+					ax25->sk->state     = TCP_CLOSE;
+					ax25->sk->err       = 0;
 					ax25->sk->shutdown |= SEND_SHUTDOWN;
 					if (!ax25->sk->dead)
 						ax25->sk->state_change(ax25->sk);
-					ax25->sk->dead  = 1;
+					ax25->sk->dead      = 1;
 				}
 			}
 			break;
@@ -302,14 +301,13 @@
 			if (pf) {
 				ax25->state = AX25_STATE_0;
 				ax25_dama_off(ax25);
-
 				if (ax25->sk != NULL) {
-					ax25->sk->state = TCP_CLOSE;
-					ax25->sk->err   = 0;
+					ax25->sk->state     = TCP_CLOSE;
+					ax25->sk->err       = 0;
 					ax25->sk->shutdown |= SEND_SHUTDOWN;
 					if (!ax25->sk->dead)
 						ax25->sk->state_change(ax25->sk);
-					ax25->sk->dead  = 1;
+					ax25->sk->dead      = 1;
 				}
 			}
 			break;
@@ -318,14 +316,13 @@
 			if (pf) {
 				ax25->state = AX25_STATE_0;
 				ax25_dama_off(ax25);
-					
 				if (ax25->sk != NULL) {
-					ax25->sk->state = TCP_CLOSE;
-					ax25->sk->err   = 0;
-					ax25->sk->shutdown|=SEND_SHUTDOWN;
+					ax25->sk->state     = TCP_CLOSE;
+					ax25->sk->err       = 0;
+					ax25->sk->shutdown |= SEND_SHUTDOWN;
 					if (!ax25->sk->dead)
 						ax25->sk->state_change(ax25->sk);
-					ax25->sk->dead  = 1;
+					ax25->sk->dead      = 1;
 				}
 			}
 			break;
@@ -361,7 +358,6 @@
 	switch (frametype) {
 		case SABM:
 			if (dama) ax25_dama_on(ax25);
-				
 			ax25->modulus   = MODULUS;
 			ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 			ax25_send_control(ax25, UA, pf, C_RESPONSE);
@@ -377,7 +373,6 @@
 
 		case SABME:
 			if (dama) ax25_dama_on(ax25);
-				
 			ax25->modulus   = EMODULUS;
 			ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 			ax25_send_control(ax25, UA, pf, C_RESPONSE);
@@ -397,14 +392,13 @@
 			ax25->t3timer = 0;
 			ax25->state   = AX25_STATE_0;
 			ax25_dama_off(ax25);
-			
 			if (ax25->sk != NULL) {
-				ax25->sk->state = TCP_CLOSE;
-				ax25->sk->err   = 0;
+				ax25->sk->state     = TCP_CLOSE;
+				ax25->sk->err       = 0;
+				ax25->sk->shutdown |= SEND_SHUTDOWN;
 				if (!ax25->sk->dead)
 					ax25->sk->state_change(ax25->sk);
-				ax25->sk->dead  = 1;
-				ax25->sk->shutdown|=SEND_SHUTDOWN;
+				ax25->sk->dead      = 1;
 			}
 			break;
 
@@ -413,13 +407,13 @@
 			ax25->t3timer = 0;
 			ax25->state   = AX25_STATE_0;
 			ax25_dama_off(ax25);
-			if (ax25->sk) {
-				ax25->sk->state = TCP_CLOSE;
-				ax25->sk->err   = ECONNRESET;
+			if (ax25->sk != NULL) {
+				ax25->sk->state     = TCP_CLOSE;
+				ax25->sk->err       = ECONNRESET;
 				ax25->sk->shutdown |= SEND_SHUTDOWN;
 				if (!ax25->sk->dead)
 					ax25->sk->state_change(ax25->sk);
-				ax25->sk->dead         = 1;
+				ax25->sk->dead      = 1;
 			}
 			break;
 
@@ -556,7 +550,6 @@
 	switch (frametype) {
 		case SABM:
 			if (dama) ax25_dama_on(ax25);
-				
 			ax25->dama_slave = dama;
 			ax25->modulus   = MODULUS;
 			ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
@@ -574,7 +567,6 @@
 
 		case SABME:
 			if (dama) ax25_dama_on(ax25);
-				
 			ax25->dama_slave = dama;
 			ax25->modulus   = EMODULUS;
 			ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
@@ -596,14 +588,13 @@
 			ax25->t3timer = 0;
 			ax25->state   = AX25_STATE_0;
 			ax25_dama_off(ax25);
-			
 			if (ax25->sk != NULL) {
-				ax25->sk->state = TCP_CLOSE;
-				ax25->sk->err   = 0;
+				ax25->sk->state     = TCP_CLOSE;
+				ax25->sk->err       = 0;
 				ax25->sk->shutdown |= SEND_SHUTDOWN;
 				if (!ax25->sk->dead)
 					ax25->sk->state_change(ax25->sk);
-				ax25->sk->dead  = 1;
+				ax25->sk->dead      = 1;
 			}
 			break;
 
@@ -612,14 +603,13 @@
 			ax25->t3timer = 0;
 			ax25->state   = AX25_STATE_0;
 			ax25_dama_off(ax25);
-			
 			if (ax25->sk != NULL) {
-				ax25->sk->state = TCP_CLOSE;
-				ax25->sk->err   = ECONNRESET;
+				ax25->sk->state     = TCP_CLOSE;
+				ax25->sk->err       = ECONNRESET;
 				ax25->sk->shutdown |= SEND_SHUTDOWN;
 				if (!ax25->sk->dead)
 					ax25->sk->state_change(ax25->sk);
-				ax25->sk->dead  = 1;
+				ax25->sk->dead      = 1;
 			}
 			break;
 
@@ -804,10 +794,8 @@
 		return queued;
 
 	if (ax25->state != AX25_STATE_1 && ax25->state != AX25_STATE_2 &&
-	    ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4) {
-		printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
+	    ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
 		return queued;
-	}
 
 	del_timer(&ax25->timer);
 
diff -u --recursive --new-file v2.1.11/linux/net/ax25/ax25_out.c linux/net/ax25/ax25_out.c
--- v2.1.11/linux/net/ax25/ax25_out.c	Tue Nov 12 15:56:15 1996
+++ linux/net/ax25/ax25_out.c	Fri Nov 22 12:03:43 1996
@@ -257,11 +257,12 @@
 
 	if (ax25->device == NULL) {
 		if (ax25->sk != NULL) {
-			ax25->sk->state = TCP_CLOSE;
-			ax25->sk->err   = ENETUNREACH;
+			ax25->sk->state     = TCP_CLOSE;
+			ax25->sk->err       = ENETUNREACH;
+			ax25->sk->shutdown |= SEND_SHUTDOWN;
 			if (!ax25->sk->dead)
 				ax25->sk->state_change(ax25->sk);
-			ax25->sk->dead  = 1;
+			ax25->sk->dead      = 1;
 		}
 		return;
 	}
diff -u --recursive --new-file v2.1.11/linux/net/ax25/ax25_route.c linux/net/ax25/ax25_route.c
--- v2.1.11/linux/net/ax25/ax25_route.c	Tue Nov 12 15:56:15 1996
+++ linux/net/ax25/ax25_route.c	Fri Nov 22 12:03:43 1996
@@ -556,10 +556,10 @@
 	ax25_dev->values[AX25_VALUES_CONMODE]   = AX25_DEF_CONMODE;
 	ax25_dev->values[AX25_VALUES_WINDOW]    = AX25_DEF_WINDOW;
 	ax25_dev->values[AX25_VALUES_EWINDOW]   = AX25_DEF_EWINDOW;
-	ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1 * PR_SLOWHZ;
-	ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2 * PR_SLOWHZ;
-	ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3 * PR_SLOWHZ;
-	ax25_dev->values[AX25_VALUES_IDLE]	= AX25_DEF_IDLE * PR_SLOWHZ * 60;
+	ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1;
+	ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2;
+	ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3;
+	ax25_dev->values[AX25_VALUES_IDLE]	= AX25_DEF_IDLE;
 	ax25_dev->values[AX25_VALUES_N2]        = AX25_DEF_N2;
 	ax25_dev->values[AX25_VALUES_DIGI]      = AX25_DEF_DIGI;
 	ax25_dev->values[AX25_VALUES_PACLEN]	= AX25_DEF_PACLEN;
diff -u --recursive --new-file v2.1.11/linux/net/ax25/ax25_timer.c linux/net/ax25/ax25_timer.c
--- v2.1.11/linux/net/ax25/ax25_timer.c	Tue Nov 19 15:53:59 1996
+++ linux/net/ax25/ax25_timer.c	Fri Nov 22 12:03:43 1996
@@ -150,12 +150,12 @@
 			if (ax25->sk != NULL) {
 				if (ax25->sk->debug)
 					printk(KERN_DEBUG "AX.25 T3 Timeout\n");
-				ax25->sk->state = TCP_CLOSE;
-				ax25->sk->err   = ETIMEDOUT;
+				ax25->sk->state     = TCP_CLOSE;
+				ax25->sk->err       = ETIMEDOUT;
 				ax25->sk->shutdown |= SEND_SHUTDOWN;
 				if (!ax25->sk->dead)
 					ax25->sk->state_change(ax25->sk);
-				ax25->sk->dead  = 1;
+				ax25->sk->dead      = 1;
 			}
 
 			ax25_reset_timer(ax25);
@@ -195,13 +195,13 @@
 		ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
 
 		if (ax25->sk != NULL) {
-			ax25->sk->state = TCP_CLOSE;
-			ax25->sk->err = 0;
+			ax25->sk->state     = TCP_CLOSE;
+			ax25->sk->err       = 0;
 			ax25->sk->shutdown |= SEND_SHUTDOWN;
 			if (!ax25->sk->dead)
 				ax25->sk->state_change(ax25->sk);
-			ax25->sk->dead = 1;
-			ax25->sk->destroy = 1;
+			ax25->sk->dead      = 1;
+			ax25->sk->destroy   = 1;
 		}
 	}
 		                                                                                                                                                                                                                                                                                                                                        
@@ -239,12 +239,12 @@
 					ax25_clear_queues(ax25);
 					ax25->state = AX25_STATE_0;
 					if (ax25->sk != NULL) {
-						ax25->sk->state = TCP_CLOSE;
-						ax25->sk->err   = ETIMEDOUT;
+						ax25->sk->state     = TCP_CLOSE;
+						ax25->sk->err       = ETIMEDOUT;
 						ax25->sk->shutdown |= SEND_SHUTDOWN;
 						if (!ax25->sk->dead)
 							ax25->sk->state_change(ax25->sk);
-						ax25->sk->dead  = 1;
+						ax25->sk->dead      = 1;
 					}
 				} else {
 					ax25->modulus = MODULUS;
@@ -270,12 +270,12 @@
 				ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 				
 				if (ax25->sk != NULL) {
-					ax25->sk->state = TCP_CLOSE;
-					ax25->sk->err   = ETIMEDOUT;
+					ax25->sk->state     = TCP_CLOSE;
+					ax25->sk->err       = ETIMEDOUT;
 					ax25->sk->shutdown |= SEND_SHUTDOWN;
 					if (!ax25->sk->dead)
 						ax25->sk->state_change(ax25->sk);
-					ax25->sk->dead  = 1;
+					ax25->sk->dead      = 1;
 				}
 			} else {
 				ax25->n2count++;
@@ -300,12 +300,12 @@
 				if (ax25->sk != NULL) {
 					if (ax25->sk->debug)
 						printk(KERN_DEBUG "AX.25 link Failure\n");
-					ax25->sk->state = TCP_CLOSE;
-					ax25->sk->err   = ETIMEDOUT;
+					ax25->sk->state     = TCP_CLOSE;
+					ax25->sk->err       = ETIMEDOUT;
 					ax25->sk->shutdown |= SEND_SHUTDOWN;
 					if (!ax25->sk->dead)
 						ax25->sk->state_change(ax25->sk);
-					ax25->sk->dead  = 1;
+					ax25->sk->dead      = 1;
 				}
 			} else {
 				ax25->n2count++;
diff -u --recursive --new-file v2.1.11/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- v2.1.11/linux/net/ipv4/ip_output.c	Fri Nov 15 23:49:11 1996
+++ linux/net/ipv4/ip_output.c	Fri Nov 22 11:59:52 1996
@@ -387,7 +387,9 @@
 	 */
 
 	if (tot_len > dev->mtu)
+	{
 		goto fragment;
+	}
 
 	/*
 	 *	Add an IP checksum
@@ -478,6 +480,13 @@
 	goto out;
 
 fragment:
+	if ((iph->frag_off & htons(IP_DF)))
+	{
+		printk(KERN_DEBUG "sending pkt_too_big to self\n");
+		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+			  htonl(dev->mtu), dev);
+		goto out;
+	}
 	ip_fragment(sk,skb,dev,0);
 	goto out;
 }
diff -u --recursive --new-file v2.1.11/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.1.11/linux/net/ipv4/tcp_timer.c	Tue Nov 19 15:54:01 1996
+++ linux/net/ipv4/tcp_timer.c	Fri Nov 22 12:00:40 1996
@@ -500,6 +500,7 @@
 #endif
 						(*conn->class->destructor)(conn);
 						tcp_dec_slow_timer(TCP_SLT_SYNACK);
+						sk->ack_backlog--;
 						kfree(conn);
 
 						if (!tp->syn_wait_queue)
diff -u --recursive --new-file v2.1.11/linux/net/ipv6/addrconf.c linux/net/ipv6/addrconf.c
--- v2.1.11/linux/net/ipv6/addrconf.c	Tue Nov 19 15:54:02 1996
+++ linux/net/ipv6/addrconf.c	Fri Nov 22 11:59:52 1996
@@ -491,11 +491,11 @@
 	}
 	else
 	{
-		rtmsg.rtmsg_prefixlen = 128;
+		rtmsg.rtmsg_prefixlen = 10;
 		rtmsg.rtmsg_dst.s6_addr32[0] = __constant_htonl(0xfe800000);
 		rtmsg.rtmsg_dst.s6_addr32[3] = dev->pa_dstaddr;
 		rtmsg.rtmsg_metric = 1;
-		rtmsg.rtmsg_flags = RTF_HOST|RTF_UP;
+		rtmsg.rtmsg_flags = RTF_NEXTHOP|RTF_UP;
 	}
 
 	strcpy(rtmsg.rtmsg_device, dev->name);
diff -u --recursive --new-file v2.1.11/linux/net/ipv6/ipv6_route.c linux/net/ipv6/ipv6_route.c
--- v2.1.11/linux/net/ipv6/ipv6_route.c	Tue Nov 12 15:56:16 1996
+++ linux/net/ipv6/ipv6_route.c	Fri Nov 22 11:59:52 1996
@@ -11,6 +11,12 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+/*
+ *	Changes:
+ *
+ *	Masaki Hirabaru			:	Fix for /proc info > pagesize
+ *	<masaki@merit.edu>
+ */
 
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -101,7 +107,7 @@
 
 static void	rt6_walk_tree(f_pnode func, void * arg, int filter);
 static void	rt6_rt_timeout(struct fib6_node *fn, void *arg);
-static int	rt6_msgrcv(struct sk_buff *skb);
+static int	rt6_msgrcv(int unit, struct sk_buff *skb);
 
 struct rt6_statistics rt6_stats = {
 	1, 0, 1, 1, 0
@@ -205,7 +211,7 @@
 			return 0;
 	}
 
-	return 1;	
+	return 1;
 }
 
 /*
@@ -374,7 +380,7 @@
 
 		if (addr_match(&fn->leaf->rt_dst, addr, fn->fn_bit))
 		{
-			if (pbit == fn->fn_bit &&
+			if (pbit == fn->fn_bit && pbit &&
 			    addr_bit_equal(addr, &fn->leaf->rt_dst,
 					   rt->rt_prefixlen))
 			{
@@ -396,7 +402,7 @@
 				return 0;
 			}
 
-			if (pbit > fn->fn_bit)
+			if (pbit > fn->fn_bit || pbit == 0)
 			{
 				/* walk down on tree */
 
@@ -625,6 +631,7 @@
 	if (children < 2)
 	{
 		struct fib6_node *child;
+		struct fib6_node *pn;
 
 		child = dir ? fn->right : fn->left;
 
@@ -642,18 +649,22 @@
 			child->parent = fn->parent;
 		}
 
-		/* 
+		/*
 		 *	try to collapse on top
-		 */			
-		if ((fn->parent->fn_flags & (RTN_BACKTRACK | RTN_ROOT)) == 0)
+		 */
+		pn = fn->parent;
+		fn->parent = NULL;
+		
+		if ((pn->fn_flags & (RTN_BACKTRACK | RTN_ROOT)) == 0)
 		{
-			if (fn->leaf)
+			if (pn->leaf)
 			{
-				rt_release(fn->leaf);
-				fn->leaf = NULL;
+				rt_release(pn->leaf);
+				pn->leaf = NULL;
 			}
-			fib6_del_3(fn->parent);
+			fib6_del_3(pn);
 		}
+
 		if (fn->fn_flags & RTN_BACKTRACK)
 		{
 			rt6_stats.fib_route_nodes--;
@@ -667,7 +678,9 @@
 	
 	fn->fn_bit = bit;
 	fn->fn_flags &= ~RTN_BACKTRACK;
+	
 	fn->leaf = fn->left->leaf;
+	atomic_inc(&fn->leaf->rt_ref);
 
 	rt6_stats.fib_route_nodes--;
 }
@@ -726,11 +739,12 @@
 	return NULL;
 }
 
-static struct fib6_node * fib6_del_rt_2(struct in6_addr *addr, __u32 prefixlen,
-					struct rt6_info *rt)
+static struct fib6_node * fib6_del_rt_2(struct rt6_info *rt)
 {
 	struct fib6_node *fn;
-
+	struct in6_addr *addr = &rt->rt_dst;
+	int prefixlen = rt->rt_prefixlen;
+	
 	for (fn = &routing_table; fn;) 
 	{
 		int dir;
@@ -755,24 +769,24 @@
 
 	if (fn)
 	{
-		struct rt6_info *back = NULL;
+		struct rt6_info **back;
 		struct rt6_info *lf;
 
+		back = &fn->leaf;
+		
 		for(lf = fn->leaf; lf; lf=lf->next)
 		{
 			if (rt == lf)
 			{
-				/* delete this entry */
-				if (back == NULL)
-					fn->leaf = lf->next;
-				else
-					back->next = lf->next;
-
-				lf->fib_node = NULL;
+				/*
+				 *	delete this entry
+				 */
+				
+				*back = lf->next;
 				rt_release(lf);
 				return fn;
 			}
-			back = lf;
+			back = &lf->next;
 		}
 	}
 
@@ -801,7 +815,7 @@
 {
 	struct fib6_node *fn;
 
-	fn = fib6_del_rt_2(&rt->rt_dst, rt->rt_prefixlen, rt);
+	fn = fib6_del_rt_2(rt);
 
 	if (fn == NULL)
 		return -ENOENT;
@@ -859,6 +873,12 @@
 		
 	memcpy(&rt->rt_dst, &rtmsg->rtmsg_dst, sizeof(struct in6_addr));
 	rt->rt_prefixlen = rtmsg->rtmsg_prefixlen;
+
+	if (rt->rt_prefixlen == 0)
+	{
+		printk(KERN_DEBUG "ip6_fib: zero length route not allowed\n");
+		return -EINVAL;
+	}
 	
 	if (flags & (RTF_GATEWAY | RTF_NEXTHOP)) 
 	{
@@ -867,7 +887,7 @@
 		{
 			struct rt6_info *gw_rt;
 
-			gw_rt = fibv6_lookup(&rtmsg->rtmsg_gateway, NULL,
+			gw_rt = fibv6_lookup(&rtmsg->rtmsg_gateway, dev,
 					     RTI_GATEWAY);
 
 			if (gw_rt == NULL)
@@ -937,11 +957,44 @@
 int ipv6_route_del(struct in6_rtmsg *rtmsg)
 {
 	struct rt6_info * rt;
-
+	int res = -ENOENT;
+	
+	atomic_inc(&rt6_lock);
+	
 	rt = fib6_lookup_1(&rtmsg->rtmsg_dst, 0);
-	if (!rt || (rt && (rt->rt_prefixlen != rtmsg->rtmsg_prefixlen)))
-		return -ENOENT;
-	return fib6_del_rt(rt);
+	
+	if (rt && (rt->rt_prefixlen == rtmsg->rtmsg_prefixlen))
+	{
+		int test;
+		
+		start_bh_atomic();
+		
+		test = (rt6_lock == 1);
+		
+		if (test)
+		{
+			res = fib6_del_rt(rt);
+		}
+		end_bh_atomic();
+
+		if (!test)
+		{
+			/*
+			 *	This function is called from user
+			 *	context only (at the moment).
+			 *	As we don't sleep we should never see
+			 *	a lock count > 1.
+			 *
+			 *	If this assumptions becomes invalid we'll
+			 *	just have to had a del request to the
+			 *	queue in this case.
+			 */
+			res = -EBUSY;
+		}
+	}
+	
+	atomic_dec(&rt6_lock);
+	return res;
 }
 
 /*
@@ -954,6 +1007,8 @@
 {
 	struct rt6_info *rt;
 
+	atomic_inc(&rt6_lock);
+	
 	if ((rt = fib6_lookup_1(addr, flags)))
 	{
 		if (src_dev)
@@ -963,29 +1018,33 @@
 			for (sprt=rt; sprt; sprt=sprt->next)
 			{
 				if (sprt->rt_dev == src_dev)
-					return sprt;
+				{
+					rt = sprt;
+					goto out;
+				}
 			}
 			
 			if (flags & RTI_DEVRT)
 			{
-				return NULL;
+				rt = NULL;
 			}
 		}
 
-		return rt;
+		goto out;
 	}
 
 	if (!(flags & RTI_GATEWAY))
 	{
 		if ((rt = dflt_rt_lookup()))
 		{
-			return rt;
+			goto out;
 		}
 
-		return last_resort_rt;
+		rt = last_resort_rt;
 	}
-
-	return NULL;
+  out:
+	atomic_dec(&rt6_lock);
+	return rt;
 }
 
 /*
@@ -1713,11 +1772,12 @@
 }
 
 #ifdef CONFIG_PROC_FS
-#define RT6_INFO_LEN (32 + 2 + 32 + 2 + 2 + 2 + 4 + 8 + 7)
+#define RT6_INFO_LEN (32 + 2 + 32 + 2 + 2 + 2 + 4 + 8 + 7 + 1)
 
 struct rt6_proc_arg {
 	char *buffer;
 	int offset;
+	int length;
 	int skip;
 	int len;
 };
@@ -1736,7 +1796,10 @@
 			arg->skip++;
 			continue;
 		}
-	
+
+		if (arg->len >= arg->length)
+			return;
+		
 		for (i=0; i<16; i++)
 		{
 			sprintf(arg->buffer + arg->len, "%02x",
@@ -1775,6 +1838,7 @@
 	struct fib6_node sfn;
 	arg.buffer = buffer;
 	arg.offset = offset;
+	arg.length = length;
 	arg.skip = 0;
 	arg.len = 0;
 
@@ -1865,7 +1929,7 @@
  *	routing socket moral equivalent
  */
 
-static int rt6_msgrcv(struct sk_buff *skb)
+static int rt6_msgrcv(int unit, struct sk_buff *skb)
 {
 	int count = 0;
 	struct in6_rtmsg *rtmsg;
diff -u --recursive --new-file v2.1.11/linux/net/ipv6/sit.c linux/net/ipv6/sit.c
--- v2.1.11/linux/net/ipv6/sit.c	Tue Nov 12 15:56:16 1996
+++ linux/net/ipv6/sit.c	Fri Nov 22 11:59:52 1996
@@ -66,7 +66,8 @@
 static void			sit_err(int type, int code, 
 					unsigned char *buff, __u32 info,
 					__u32 daddr, __u32 saddr,
-					struct inet_protocol *protocol);
+					struct inet_protocol *protocol,
+					int len);
 
 static struct inet_protocol sit_protocol = {
 	sit_rcv,
@@ -349,7 +350,8 @@
  */
 
 static void sit_err(int type, int code, unsigned char *buff, __u32 info,
-		    __u32 daddr, __u32 saddr, struct inet_protocol *protocol)
+		    __u32 daddr, __u32 saddr, struct inet_protocol *protocol,
+		    int len)
 		    
 {
 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
diff -u --recursive --new-file v2.1.11/linux/net/ipv6/udp.c linux/net/ipv6/udp.c
--- v2.1.11/linux/net/ipv6/udp.c	Tue Nov 19 15:54:02 1996
+++ linux/net/ipv6/udp.c	Fri Nov 22 11:59:52 1996
@@ -47,7 +47,7 @@
  *
  */
 
-int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, size_t addr_len)
 {
 	struct sockaddr_in6	*usin = (struct sockaddr_in6 *) uaddr;
 	struct in6_addr		*daddr;
diff -u --recursive --new-file v2.1.11/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- v2.1.11/linux/net/netrom/af_netrom.c	Tue Nov 19 15:54:02 1996
+++ linux/net/netrom/af_netrom.c	Fri Nov 22 12:03:43 1996
@@ -122,6 +122,7 @@
 			s->protinfo.nr->device = NULL;
 			s->state               = TCP_CLOSE;
 			s->err                 = ENETUNREACH;
+			s->shutdown           |= SEND_SHUTDOWN;
 			s->state_change(s);
 			s->dead                = 1;
 		}
@@ -322,6 +323,7 @@
 			sk->protinfo.nr->state = NR_STATE_0;
 			sk->state              = TCP_CLOSE;
 			sk->err                = ENETRESET;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead               = 1;
@@ -728,6 +730,7 @@
 
 		case NR_STATE_0:
 			sk->state     = TCP_CLOSE;
+			sk->shutdown |= SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead      = 1;
 			nr_destroy_socket(sk);
@@ -736,6 +739,7 @@
 		case NR_STATE_1:
 			sk->protinfo.nr->state = NR_STATE_0;
 			sk->state              = TCP_CLOSE;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead               = 1;
 			nr_destroy_socket(sk);
@@ -745,6 +749,7 @@
 			nr_write_internal(sk, NR_DISCACK);
 			sk->protinfo.nr->state = NR_STATE_0;
 			sk->state              = TCP_CLOSE;
+			sk->shutdown           = SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead               = 1;
 			nr_destroy_socket(sk);
@@ -759,6 +764,7 @@
 			sk->protinfo.nr->t4timer = 0;
 			sk->protinfo.nr->state   = NR_STATE_2;
 			sk->state                = TCP_CLOSE;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead                 = 1;
 			sk->destroy              = 1;
@@ -1139,6 +1145,11 @@
 	if (sk->zapped)
 		return -EADDRNOTAVAIL;
 
+	if (sk->shutdown & SEND_SHUTDOWN) {
+		send_sig(SIGPIPE, current, 0);
+		return -EPIPE;
+	}
+
 	if (sk->protinfo.nr->device == NULL)
 		return -ENETUNREACH;
 		
@@ -1253,11 +1264,12 @@
 	}
 
 	copied = skb->len;
-	if(copied>size)
-	{
-		copied=size;
-		msg->msg_flags|=MSG_TRUNC;
+
+	if (copied > size) {
+		copied = size;
+		msg->msg_flags |= MSG_TRUNC;
 	}
+
 	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 	
 	if (sax != NULL) {
diff -u --recursive --new-file v2.1.11/linux/net/netrom/nr_in.c linux/net/netrom/nr_in.c
--- v2.1.11/linux/net/netrom/nr_in.c	Tue Nov 12 15:56:16 1996
+++ linux/net/netrom/nr_in.c	Fri Nov 22 12:03:43 1996
@@ -123,6 +123,7 @@
 			sk->protinfo.nr->state = NR_STATE_0;
 			sk->state              = TCP_CLOSE;
 			sk->err                = ECONNREFUSED;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead               = 1;
@@ -151,6 +152,7 @@
 			sk->protinfo.nr->state = NR_STATE_0;
 			sk->state              = TCP_CLOSE;
 			sk->err                = 0;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead               = 1;
@@ -191,6 +193,7 @@
 			sk->protinfo.nr->state = NR_STATE_0;
 			sk->state              = TCP_CLOSE;
 			sk->err                = 0;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead               = 1;
@@ -201,6 +204,7 @@
 			sk->protinfo.nr->state = NR_STATE_0;
 			sk->state              = TCP_CLOSE;
 			sk->err                = ECONNRESET;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead               = 1;
diff -u --recursive --new-file v2.1.11/linux/net/netrom/nr_out.c linux/net/netrom/nr_out.c
--- v2.1.11/linux/net/netrom/nr_out.c	Tue Nov 12 15:56:16 1996
+++ linux/net/netrom/nr_out.c	Fri Nov 22 12:03:43 1996
@@ -227,11 +227,12 @@
 	if (!nr_route_frame(skb, NULL)) {
 		kfree_skb(skb, FREE_WRITE);
 
-		sk->state = TCP_CLOSE;
-		sk->err   = ENETUNREACH;
+		sk->state     = TCP_CLOSE;
+		sk->err       = ENETUNREACH;
+		sk->shutdown |= SEND_SHUTDOWN;
 		if (!sk->dead)
 			sk->state_change(sk);
-		sk->dead  = 1;
+		sk->dead      = 1;
 	}
 }
 
diff -u --recursive --new-file v2.1.11/linux/net/netrom/nr_timer.c linux/net/netrom/nr_timer.c
--- v2.1.11/linux/net/netrom/nr_timer.c	Tue Nov 12 15:56:16 1996
+++ linux/net/netrom/nr_timer.c	Fri Nov 22 12:03:43 1996
@@ -144,6 +144,7 @@
 				sk->protinfo.nr->state = NR_STATE_0;
 				sk->state              = TCP_CLOSE;
 				sk->err                = ETIMEDOUT;
+				sk->shutdown          |= SEND_SHUTDOWN;
 				if (!sk->dead)
 					sk->state_change(sk);
 				sk->dead               = 1;
@@ -159,6 +160,7 @@
 				sk->protinfo.nr->state = NR_STATE_0;
 				sk->state              = TCP_CLOSE;
 				sk->err                = ETIMEDOUT;
+				sk->shutdown          |= SEND_SHUTDOWN;
 				if (!sk->dead)
 					sk->state_change(sk);
 				sk->dead               = 1;
@@ -174,6 +176,7 @@
 				sk->protinfo.nr->state = NR_STATE_0;
 				sk->state              = TCP_CLOSE;
 				sk->err                = ETIMEDOUT;
+				sk->shutdown          |= SEND_SHUTDOWN;
 				if (!sk->dead)
 					sk->state_change(sk);
 				sk->dead               = 1;
diff -u --recursive --new-file v2.1.11/linux/net/netsyms.c linux/net/netsyms.c
--- v2.1.11/linux/net/netsyms.c	Tue Nov 19 15:54:02 1996
+++ linux/net/netsyms.c	Tue Nov 19 15:48:49 1996
@@ -60,9 +60,15 @@
 extern void destroy_8023_client(struct datalink_proto *);
 #endif
 
+extern char *skb_push_errstr;
+extern char *skb_put_errstr;
 
 static struct symbol_table net_syms = {
 #include <linux/symtab_begin.h>
+
+	/* Skbuff symbols. */
+	X(skb_push_errstr),
+	X(skb_put_errstr),
 
 	/* Socket layer registration */
 	X(sock_register),
diff -u --recursive --new-file v2.1.11/linux/net/protocols.c linux/net/protocols.c
--- v2.1.11/linux/net/protocols.c	Tue Nov 12 15:56:16 1996
+++ linux/net/protocols.c	Fri Nov 22 12:03:43 1996
@@ -28,6 +28,9 @@
 #include <net/p8022call.h>
 #include <net/p8022trcall.h>
 #endif
+#ifdef CONFIG_X25
+#include <net/x25call.h>
+#endif
 #ifdef CONFIG_AX25
 #include <net/ax25call.h>
 #ifdef CONFIG_NETROM
diff -u --recursive --new-file v2.1.11/linux/net/rose/af_rose.c linux/net/rose/af_rose.c
--- v2.1.11/linux/net/rose/af_rose.c	Tue Nov 19 15:54:02 1996
+++ linux/net/rose/af_rose.c	Fri Nov 22 12:03:43 1996
@@ -139,6 +139,7 @@
 			s->protinfo.rose->device = NULL;
 			s->state                 = TCP_CLOSE;
 			s->err                   = ENETUNREACH;
+			s->shutdown             |= SEND_SHUTDOWN;
 			s->state_change(s);
 			s->dead                  = 1;
 		}
@@ -344,6 +345,7 @@
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
 			sk->err                  = ENETRESET;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead                 = 1;
@@ -716,6 +718,7 @@
 
 		case ROSE_STATE_0:
 			sk->state     = TCP_CLOSE;
+			sk->shutdown |= SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead      = 1;
 			rose_destroy_socket(sk);
@@ -724,6 +727,7 @@
 		case ROSE_STATE_1:
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead                 = 1;
 			rose_destroy_socket(sk);
@@ -732,6 +736,7 @@
 		case ROSE_STATE_2:
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead                 = 1;
 			rose_destroy_socket(sk);
@@ -744,6 +749,7 @@
 			sk->protinfo.rose->timer = sk->protinfo.rose->t3;
 			sk->protinfo.rose->state = ROSE_STATE_2;
 			sk->state                = TCP_CLOSE;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			sk->state_change(sk);
 			sk->dead                 = 1;
 			sk->destroy              = 1;
@@ -1077,6 +1083,11 @@
 	if (sk->zapped)
 		return -EADDRNOTAVAIL;
 
+	if (sk->shutdown & SEND_SHUTDOWN) {
+		send_sig(SIGPIPE, current, 0);
+		return -EPIPE;
+	}
+
 	if (sk->protinfo.rose->device == NULL)
 		return -ENETUNREACH;
 		
@@ -1202,10 +1213,9 @@
 
 	copied = skb->len;
 	
-	if(copied>size)
-	{
-		copied=size;
-		msg->msg_flags|=MSG_TRUNC;
+	if (copied > size) {
+		copied = size;
+		msg->msg_flags |= MSG_TRUNC;
 	}
 	
 	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
diff -u --recursive --new-file v2.1.11/linux/net/rose/rose_in.c linux/net/rose/rose_in.c
--- v2.1.11/linux/net/rose/rose_in.c	Tue Nov 12 15:56:17 1996
+++ linux/net/rose/rose_in.c	Fri Nov 22 12:03:43 1996
@@ -112,6 +112,7 @@
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
 			sk->err                  = ECONNREFUSED;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead                 = 1;
@@ -139,6 +140,7 @@
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
 			sk->err                  = 0;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead                 = 1;
@@ -179,6 +181,7 @@
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
 			sk->err                  = 0;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead                 = 1;
@@ -281,6 +284,7 @@
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
 			sk->err                  = 0;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead                 = 1;
diff -u --recursive --new-file v2.1.11/linux/net/rose/rose_timer.c linux/net/rose/rose_timer.c
--- v2.1.11/linux/net/rose/rose_timer.c	Tue Nov 12 15:56:17 1996
+++ linux/net/rose/rose_timer.c	Fri Nov 22 12:03:43 1996
@@ -140,6 +140,7 @@
 			sk->protinfo.rose->state = ROSE_STATE_0;
 			sk->state                = TCP_CLOSE;
 			sk->err                  = ETIMEDOUT;
+			sk->shutdown            |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
 			sk->dead                 = 1;
