diff -u --recursive --new-file v1.1.77/linux/CREDITS linux/CREDITS
--- v1.1.77/linux/CREDITS	Sun Jan  1 19:49:18 1995
+++ linux/CREDITS	Mon Jan  9 06:40:59 1995
@@ -478,6 +478,10 @@
 E: Kai.Makisara@vtt.fi
 D: SCSI Tape Driver
 
+N: Peter MacDonald
+D: SLS distribution
+D: Initial implementation of VC's, pty's and select()
+
 N: James B. MacLean
 E: jmaclean@fox.nstn.ns.ca
 D: Coordinator of DOSEMU releases
diff -u --recursive --new-file v1.1.77/linux/Makefile linux/Makefile
--- v1.1.77/linux/Makefile	Mon Jan  9 07:21:55 1995
+++ linux/Makefile	Mon Jan  9 10:01:37 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 77
+SUBLEVEL = 78
 
 ARCH = i386
 
@@ -193,7 +193,7 @@
 	$(MAKE) linuxsubdirs SUBDIRS=net
 
 modules: dummy
-	@set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i modules; done
+	@set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i CFLAGS="$(CFLAGS) -DMODULE" modules; done
 	
 
 clean:	archclean
diff -u --recursive --new-file v1.1.77/linux/arch/alpha/Makefile linux/arch/alpha/Makefile
--- v1.1.77/linux/arch/alpha/Makefile	Mon Jan  9 07:21:55 1995
+++ linux/arch/alpha/Makefile	Mon Jan  9 08:17:06 1995
@@ -13,8 +13,9 @@
 
 HEAD := arch/alpha/kernel/head.o
 
-SUBDIRS := $(SUBDIRS) arch/alpha/kernel
+SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/lib
 ARCHIVES := arch/alpha/kernel/kernel.o $(ARCHIVES)
+LIBS := arch/alpha/lib/lib.a $(LIBS)
 
 archclean:
 
diff -u --recursive --new-file v1.1.77/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v1.1.77/linux/arch/alpha/config.in	Thu Dec 29 19:58:40 1994
+++ linux/arch/alpha/config.in	Mon Jan  9 08:17:06 1995
@@ -14,7 +14,7 @@
 
 if [ "$CONFIG_NET" = "y" ]; then
 comment 'Networking options'
-bool 'TCP/IP networking' CONFIG_INET y
+bool 'TCP/IP networking' CONFIG_INET n
 if [ "$CONFIG_INET" "=" "y" ]; then
 bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD n
 bool 'IP multicasting (ALPHA)' CONFIG_IP_MULTICAST n
@@ -32,7 +32,7 @@
 
 comment 'SCSI support'
 
-bool 'SCSI support?' CONFIG_SCSI y
+bool 'SCSI support?' CONFIG_SCSI n
 
 if [ "$CONFIG_SCSI" = "n" ]; then
 
@@ -109,7 +109,7 @@
 	fi
 	bool '3c509/3c579 support' CONFIG_EL3 y
 fi
-bool 'Other ISA cards' CONFIG_NET_ISA y
+bool 'Other ISA cards' CONFIG_NET_ISA n
 if [ "$CONFIG_NET_ISA" = "y" ]; then
 	bool 'Cabletron E21xx support' CONFIG_E2100 n
 	bool 'DEPCA support' CONFIG_DEPCA y
diff -u --recursive --new-file v1.1.77/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v1.1.77/linux/arch/alpha/kernel/entry.S	Mon Jan  9 07:21:55 1995
+++ linux/arch/alpha/kernel/entry.S	Mon Jan  9 08:17:06 1995
@@ -7,7 +7,7 @@
 #include <asm/system.h>
 
 #define halt	.long PAL_halt
-#define rti	.long RAL_rti
+#define rti	.long PAL_rti
 
 .text
 	.set noat
diff -u --recursive --new-file v1.1.77/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- v1.1.77/linux/arch/alpha/lib/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/alpha/lib/Makefile	Mon Jan  9 08:17:06 1995
@@ -0,0 +1,39 @@
+#
+# Makefile for alpha-specific library files..
+#
+
+.c.s:
+	$(CC) $(CFLAGS) -S $<
+.s.o:
+	$(AS) -c -o $*.o $<
+.c.o:
+	$(CC) $(CFLAGS) -c $<
+
+OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o
+
+lib.a: $(OBJS)
+	$(AR) rcs lib.a $(OBJS)
+	sync
+
+__divqu.o: divide.S
+	$(CC) -DDIV -c -o __divqu.o divide.S
+
+__remqu.o: divide.S
+	$(CC) -DREM -c -o __remqu.o divide.S
+
+__divlu.o: divide.S
+	$(CC) -DDIV -DINTSIZE -c -o __divlu.o divide.S
+
+__remlu.o: divide.S
+	$(CC) -DREM -DINTSIZE -c -o __remlu.o divide.S
+
+dep:
+	$(CPP) -M *.c > .depend
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
diff -u --recursive --new-file v1.1.77/linux/arch/alpha/lib/divide.S linux/arch/alpha/lib/divide.S
--- v1.1.77/linux/arch/alpha/lib/divide.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/alpha/lib/divide.S	Mon Jan  9 08:17:07 1995
@@ -0,0 +1,98 @@
+/*
+ * arch/alpha/lib/divide.S
+ *
+ * (C) 1995 Linus Torvalds
+ *
+ * Alpha division..
+ */
+
+/*
+ * The alpha chip doesn't provide hardware division, so we have to do it
+ * by hand.  The compiler expects the functions
+ *
+ *	__divqu: 64-bit unsigned long divide
+ *	__remqu: 64-bit unsigned long reminder
+ *	__divqs/__remqs: signed 64-bit
+ *	__divlu/__remlu: unsigned 32-bit
+ *	__divls/__remls: signed 32-bit
+ *
+ * These are not normal C functions: instead of the normal
+ * calling sequence, these expect their arguments in registers
+ * $24 and $25, and return the result in $27. Register $28 may
+ * be clobbered (assembly temprary), anything else must be saved. 
+ *
+ * In short: painful. I'm not going to try to be clever about it:
+ * let somebody else optimize it if they will.
+ */
+
+/*
+ * My temporaries:
+ *	$0 - current bit
+ *	$1 - shifted divisor
+ *	$2 - rest
+ *	$3 - compare status
+ *
+ *	$23 - return address
+ *	$24 - dividend
+ *	$25 - divisor
+ */
+
+/*
+ * Select function type and registers
+ */
+#ifdef DIV
+#define func(x) __div##x
+#define modulus $2
+#define quotient $27
+#else
+#define func(x) __rem##x
+#define modulus $27
+#define quotient $2
+#endif
+
+/*
+ * For 32-bit operations, we need to extend to 64-bit
+ */
+#ifdef INTSIZE
+#define function func(lu)
+#define LONGIFY(x) zapnot x,15,x
+#else
+#define function func(qu)
+#define LONGIFY(x)
+#endif
+
+.globl	function
+.ent	function
+function:
+	lda	$30,-32($30)
+	stq	$0, 0($30)
+	stq	$1, 8($30)
+	stq	$2,16($30)
+	stq	$3,24($30)
+	bis	$25,$25,$1
+	bis	$24,$24,modulus
+	bis	$31,$31,quotient
+	LONGIFY($1)
+	LONGIFY(modulus)
+	beq	$1, 9f			/* div by zero */
+	bis	$31,1,$0
+	blt	$1, 2f			/* high bit set */
+1:	cmpult	modulus,$1,$3
+	bne	$3,3f
+	addq	$1,$1,$1
+	addq	$0,$0,$0
+	bge	$1,1b
+2:	cmpult	modulus,$1,$3
+	bne	$3,3f
+	subq	modulus,$1,modulus
+	addq	$0,quotient,quotient
+3:	srl	$0,1,$0
+	srl	$1,1,$1
+	bne	$0,2b
+9:	ldq	$0, 0($30)
+	ldq	$1, 8($30)
+	ldq	$2, 16($30)
+	ldq	$3, 32($30)
+	lda	$30,32($30)
+	ret	$31,($23),1
+	.end	function
diff -u --recursive --new-file v1.1.77/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile
--- v1.1.77/linux/arch/i386/kernel/Makefile	Mon Jan  9 07:21:56 1995
+++ linux/arch/i386/kernel/Makefile	Mon Jan  9 09:18:33 1995
@@ -34,6 +34,8 @@
 dep:
 	$(CPP) -M *.c > .depend
 
+modules:
+
 dummy:
 
 #
diff -u --recursive --new-file v1.1.77/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v1.1.77/linux/arch/i386/kernel/bios32.c	Mon Jan  9 07:21:56 1995
+++ linux/arch/i386/kernel/bios32.c	Mon Jan  9 07:03:56 1995
@@ -451,7 +451,7 @@
 	unsigned char   	revision;
        		pcibios_read_config_byte(
 			bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &revision);
-		return revision;
+		return (int) revision;
 }
 
 
@@ -484,7 +484,8 @@
 			bus, dev_fn, (unsigned char) PCI_DEVICE_ID, &device);
 		for (i=0;i<PCI_DEVICE_NUM;i++) 
 			if ((device==pci_device[i].device_id) 
-			 && (vendor==pci_device[i].vendor_id)) break;
+			 && (vendor==pci_device[i].vendor_id)) return i;
+		printk("Device id=%x ",device);
 		return i;
 }
 
@@ -503,6 +504,7 @@
 			bus, dev_fn, (unsigned char) PCI_VENDOR_ID, &vendor);
 		for (i=0;i<PCI_VENDOR_NUM;i++) 
 			if (vendor==pci_vendor[i].vendor_id) return i;
+		printk("Vendor id=%x ",vendor);
 		return i;
 }
 
diff -u --recursive --new-file v1.1.77/linux/arch/i386/kernel/ioport.c linux/arch/i386/kernel/ioport.c
--- v1.1.77/linux/arch/i386/kernel/ioport.c	Mon Jan  9 07:21:56 1995
+++ linux/arch/i386/kernel/ioport.c	Mon Jan  9 07:56:31 1995
@@ -11,14 +11,18 @@
 #include <linux/types.h>
 #include <linux/ioport.h>
 
-static unsigned long ioport_registrar[IO_BITMAP_SIZE] = {0, /* ... */};
-#define IOPORTNAMES_NUM 32
-#define IOPORTNAMES_LEN 26
-struct { int from;
-	 int num;	
-	 int flags;
-	 char name[IOPORTNAMES_LEN];
-	} ioportnames[IOPORTNAMES_NUM];
+#define IOTABLE_SIZE 32
+#define STR(x) #x
+
+typedef struct resource_entry_t {
+	u_long from, num;
+	const char *name;
+	struct resource_entry_t *next;
+} resource_entry_t;
+
+static resource_entry_t iolist = { 0, 0, "", NULL };
+
+static resource_entry_t iotable[IOTABLE_SIZE];
 
 #define _IODEBUG
 
@@ -84,52 +88,20 @@
 	}
 }
 
-/* Check for set bits in BITMAP starting at BASE, going to EXTENT. */
-asmlinkage int check_bitmap(unsigned long *bitmap, short base, short extent)
-{
-	int mask;
-	unsigned long *bitmap_base = bitmap + (base >> 5);
-	unsigned short low_index = base & 0x1f;
-	int length = low_index + extent;
-
-	if (low_index != 0) {
-		mask = (~0 << low_index);
-		if (length < 32)
-				mask &= ~(~0 << length);
-		if (*bitmap_base++ & mask)
-			return 1;
-		length -= 32;
-	}
-	while (length >= 32) {
-		if (*bitmap_base++ != 0)
-			return 1;
-		length -= 32;
-	}
-
-	if (length > 0) {
-		mask = ~(~0 << length);
-		if (*bitmap_base++ & mask)
-			return 1;
-	}
-	return 0;
-}
-
 /*
  * This generates the report for /proc/ioports
  */
 int get_ioport_list(char *buf)
-{       int i=0,len=0;
-	while(i<IOPORTNAMES_LEN && len<4000)
-	{	if(ioportnames[i].flags)
-			len+=sprintf(buf+len,"%04x-%04x : %s\n",
-				ioportnames[i].from,
-				ioportnames[i].from+ioportnames[i].num-1,
-				ioportnames[i].name);
-		i++;
-	}
-        if(len>=4000) 
-		len+=sprintf(buf+len,"4k-Limit reached!\n");
-        return len;
+{
+	resource_entry_t *p;
+	int len = 0;
+
+	for (p = iolist.next; (p) && (len < 4000); p = p->next)
+		len += sprintf(buf+len, "%04lx-%04lx : %s\n",
+			   p->from, p->from+p->num-1, p->name);
+	if (p)
+		len += sprintf(buf+len, "4K limit reached!\n");
+	return len;
 }
 
 /*
@@ -179,37 +151,54 @@
 }
 
 /*
- * This is the 'old' snarfing worker function
+ * The workhorse function: find where to put a new entry
  */
-void do_snarf_region(unsigned int from, unsigned int num)
+static resource_entry_t *find_gap(resource_entry_t *root,
+				  u_long from, u_long num)
 {
-        if (from > IO_BITMAP_SIZE*32)
-                return;
-        if (from + num > IO_BITMAP_SIZE*32)
-                num = IO_BITMAP_SIZE*32 - from;
-        set_bitmap(ioport_registrar, from, num, 1);
-        return;
+	unsigned long flags;
+	resource_entry_t *p;
+	
+	if (from > from+num-1)
+		return NULL;
+	save_flags(flags);
+	cli();
+	for (p = root; ; p = p->next) {
+		if ((p != root) && (p->from+p->num-1 >= from)) {
+			p = NULL;
+			break;
+		}
+		if ((p->next == NULL) || (p->next->from > from+num-1))
+			break;
+	}
+	restore_flags(flags);
+	return p;
 }
 
 /*
  * Call this from the device driver to register the ioport region.
  */
-void register_iomem(unsigned int from, unsigned int num, char *name)
-{	
-	int i=0;
-	while(ioportnames[i].flags && i<IOPORTNAMES_NUM)
-	 i++;
-	if(i==IOPORTNAMES_NUM)
-		printk("warning:ioportname-table is full");
-	else
-	{	
-	 	strncpy(ioportnames[i].name,name,IOPORTNAMES_LEN);
-		ioportnames[i].name[IOPORTNAMES_LEN-1]=(char)0;
-		ioportnames[i].from=from;
-		ioportnames[i].num=num;
-		ioportnames[i].flags=1;
+void request_region(unsigned int from, unsigned int num, const char *name)
+{
+	resource_entry_t *p;
+	int i;
+
+	for (i = 0; i < IOTABLE_SIZE; i++)
+		if (iotable[i].num == 0)
+			break;
+	if (i == IOTABLE_SIZE)
+		printk("warning: ioport table is full\n");
+	else {
+		p = find_gap(&iolist, from, num);
+		if (p == NULL)
+			return;
+		iotable[i].name = name;
+		iotable[i].from = from;
+		iotable[i].num = num;
+		iotable[i].next = p->next;
+		p->next = &iotable[i];
+		return;
 	}
-	do_snarf_region(from,num);
 }
 
 /*
@@ -217,33 +206,27 @@
  * It can be removed when all driver call the new function.
  */
 void snarf_region(unsigned int from, unsigned int num)
-{	register_iomem(from,num,"No name given.");
-}
-
-/*
- * The worker for releasing
- */
-void do_release_region(unsigned int from, unsigned int num)
 {
-        if (from > IO_BITMAP_SIZE*32)
-                return;
-        if (from + num > IO_BITMAP_SIZE*32)
-                num = IO_BITMAP_SIZE*32 - from;
-        set_bitmap(ioport_registrar, from, num, 0);
-        return;
+	request_region(from,num,"No name given.");
 }
 
 /* 
  * Call this when the device driver is unloaded
  */
 void release_region(unsigned int from, unsigned int num)
-{	int i=0;
-	while(i<IOPORTNAMES_NUM)
-	{	if(ioportnames[i].from==from && ioportnames[i].num==num)
-			ioportnames[i].flags=0;	
-		i++;
+{
+	resource_entry_t *p, *q;
+
+	for (p = &iolist; ; p = q) {
+		q = p->next;
+		if (q == NULL)
+			break;
+		if ((q->from == from) && (q->num == num)) {
+			q->num = 0;
+			p->next = q->next;
+			return;
+		}
 	}
-	do_release_region(from,num);
 }
 
 /*
@@ -251,11 +234,7 @@
  */
 int check_region(unsigned int from, unsigned int num)
 {
-	if (from > IO_BITMAP_SIZE*32)
-		return 0;
-	if (from + num > IO_BITMAP_SIZE*32)
-		num = IO_BITMAP_SIZE*32 - from;
-	return check_bitmap(ioport_registrar, from, num);
+	return (find_gap(&iolist, from, num) == NULL) ? -EBUSY : 0;
 }
 
 /* Called from init/main.c to reserve IO ports. */
@@ -264,5 +243,5 @@
 	int i;
 
 	for (i = 1; i < ints[0]; i += 2)
-		register_iomem(ints[i], ints[i+1],"reserved");
+		request_region(ints[i], ints[i+1], "reserved");
 }
diff -u --recursive --new-file v1.1.77/linux/arch/i386/math-emu/Makefile linux/arch/i386/math-emu/Makefile
--- v1.1.77/linux/arch/i386/math-emu/Makefile	Mon Jan  9 07:21:56 1995
+++ linux/arch/i386/math-emu/Makefile	Mon Jan  9 09:19:01 1995
@@ -40,6 +40,8 @@
 proto:
 	cproto -e -DMAKING_PROTO *.c >fpu_proto.h
 
+modules:
+
 dummy:
 
 #
diff -u --recursive --new-file v1.1.77/linux/arch/sparc/kernel/Makefile linux/arch/sparc/kernel/Makefile
--- v1.1.77/linux/arch/sparc/kernel/Makefile	Mon Jan  9 07:21:58 1995
+++ linux/arch/sparc/kernel/Makefile	Mon Jan  9 06:48:47 1995
@@ -18,7 +18,7 @@
 .S.o:
 	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
 
-OBJS  = entry.o traps.o
+OBJS  = entry.o traps.o irq.o process.o
 
 all: kernel.o head.o
 
diff -u --recursive --new-file v1.1.77/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v1.1.77/linux/arch/sparc/kernel/entry.S	Mon Jan  9 07:21:58 1995
+++ linux/arch/sparc/kernel/entry.S	Mon Jan  9 06:48:47 1995
@@ -10,6 +10,205 @@
 
 #include <asm/head.h>
 
+/* Here are macros for routines we do often, this allows me to inline this
+ * without making the code look real ugly. Well, the macro looks ugly too but
+ * makes the trap entry code easier to understand.
+ */
+
+/* I really don't like synthetic instructions. So I avoid them like the
+ * plague.
+ */
+
+/* Note that when I have to write a window out, and it is a user's window, I
+ * have to check that the pages of memory that I am going to throw the window(s)
+ * onto are valid and are writable by the user (this is %sp to %sp + 64) before
+ * I start dumping stuff there. We always assume that kernels stack is ok.
+ *
+ * If we have to save a kernel window, only one branch is taken. This should
+ * make trap handlers quicker in this scenario.
+ *
+ * Once 'current' is loaded into %g6, it stays there until we leave
+ * this macro.
+ *
+ * XXX must do some checking on the assumption that kernel stack is always ok
+ */
+
+/* I will document how this works real soon. TODO */
+
+#define TRAP_WIN_CLEAN \
+	or	%g0, %g5, %l5;    /* we need the globals to do our work */ \
+	or	%g0, %g6, %l6;    /* and %l0 to %l4 are loaded with important */ \
+	or	%g0, %g7, %l7;	  /* information like the psr and pc's to return to */ \
+	sethi	%hi(_current), %g6; \
+	ld	[%g6 + %lo(_current)], %g6; \
+	ld	[%g6 + THREAD_UWINDOWS], %g7; /* how many user wins are active? */ \
+	subcc	%g7, 0x0, %g0
+	bne	2f;                            /* If there are any, branch. */ \
+	save	%g0, %g0, %g0;                 /* Save into that window either way. */ \
+	std	%l0, [%sp];                    /* If above shows only kernel windows */ \
+1:	std	%l2, [%sp + 0x8];              /* then we get here. */ \
+	std	%l4, [%sp + 0x10]; \
+	std	%l6, [%sp + 0x18]; \
+	std	%i0, [%sp + 0x20]; \
+	std	%i2, [%sp + 0x28]; \
+	std	%i4, [%sp + 0x30]; \
+	std	%i6, [%sp + 0x38]; \
+	or	%g0, 0x1, %g5; \
+	rd	%psr, %g7; \
+	sll	%g5, %g7, %g5; \
+	wr	%g5, 0x0, %wim;                 /* update %wim to 'now' invalid */ \
+	and	%g7, 0x1f, %g7; \
+	st	%g7, [%g6 + THREAD_WIM];        /* save 'this' threads mask */ \
+	restore	%g0, %g0, %g0; \
+	or	%g0, %l5, %g5;                  /* restore the globals we used */ \
+	or	%g0, %l6, %g6; \
+	b	8f;                             /* we are done */ \
+	or	%g0, %l7, %g7; \
+2:	sub	%g7, 0x1, %g7; \
+	st	%g7, [%g6 + THREAD_UWINDOWS];   /* There are user windows if we */ \
+	andcc	%sp, 0x7, %g0;                  /* get here. Check for stack alignment. */ \
+	bne	5f;                             /* Stack is unaligned, yuck. */ \
+	sra	%sp, 0x1e, %g7;                 /* This stuff checks to see if top 3-bits */ \
+	subcc	%g7, 0x0, %g0;                  /* of stack pointer address are ok. */ \
+	be,a    3f; \
+	andn	%sp, 0xfff, %g7; \
+	subcc	%g7, -1, %g0; \
+	bne	5f; 				/* bad stack pointer, ugh */ \
+	andn	%sp, 0xfff, %g7; \
+3:	lda	[%g7] ASI_PTE, %g7;             /* Ok, user stack is a valid address */ \
+	srl	%g7, 0x1d, %g7; \
+	subcc	%g7, 0x6, %g0;                  /* Can the user write to it? */ \
+	bne	5f; \
+	and	%sp, 0xfff, %g7; \
+	subcc	%g7, 0xfc1, %g0;                /* Is our save area on one page? */ \
+	bl,a	1b; \
+	std	%l0, [%sp]; \
+	add	%sp, 0x38, %g5;                 /* Nope, have to check both pages */ \
+	sra	%g5, 0x1e, %g7; \
+	subcc	%g7, 0x0, %g0; \
+	be,a	4f; \
+	andn	%g5, 0xfff, %g7; \
+	subcc	%g7, -1, %g0; \
+	bne	5f; \
+	andn	%g5, 0xfff, %g7; \
+4:	lda	[%g7] ASI_PTE, %g7;             /* Stack space in 2nd page is valid */ \
+	srl	%g7, 0x1d, %g7; \
+	subcc	%g7, 0x6, %g0;                  /* Can user write here too? */ \
+	be,a	1b; \
+	std	%l0, [%sp]; \
+5:	ld	[%g6 + THREAD_UWINDOWS], %g7;   /* This is due to either bad page perms */ \
+	add	%g6, THREAD_REG_WINDOW, %g5;    /* for the users stack area, or the stack */ \
+6:	std	%l0, [%g5];                     /* pointer is misaligned. See above. */ \
+	std	%l2, [%g5 + 0x8]; \
+	std	%l4, [%g5 + 0x10]; \
+	std	%l6, [%g5 + 0x18]; \
+	std	%i0, [%g5 + 0x20]; \
+	std	%i2, [%g5 + 0x28]; \
+	std	%i4, [%g5 + 0x30]; \
+	std	%i6, [%g5 + 0x38]; \
+	subcc	%g7, 0x1, %g7; \
+	bge,a	6b;                             /* while(uwindows>=0) { write_win(); */ \
+	save	%g5, 0x40, %g5;                 /*     uwindows--; } */ \
+	st	%sp, [%g6 + THREAD_USP]; \
+	or	%g0, 0x1, %g5; \
+	rd	%psr, %g7; \
+	sll	%g5, %g7, %g5; \
+	wr	%g5, 0x0, %wim; \
+	and	%g7, 0x1f, %g7; \
+	st	%g7, [%g6 + THREAD_WIM];        /* Update thread_struct fields */ \
+	ld	[%g6 + THREAD_UWINDOWS], %g7; \
+	add	%g7, 0x1, %g5; \
+	st	%g5, [%g6 + THREAD_W_SAVED]; \
+	st	%g0, [%g6 + THREAD_UWINDOWS]; \
+7:	subcc	%g7, 0x1, %g7;                  /* Restore back to where we started. */ \
+	bge	7b; \
+	restore	%g0, %g0, %g0; \
+	or	%g0, %l5, %g5;                  /* Restore the globals. */ \
+	or	%g0, %l6, %g6; \
+	or	%g0, %l7, %g7; \
+8:                                              /* We are done when we get here. */ \
+
+
+/* As if the last macro wasn't enough, we have to go through a very similar routine
+ * upon entry to most traps and interrupts. This is save away the current window
+ * if it is the trap window, clean it, and adjust the stack for the handler c-code
+ * to work.
+ */
+
+#define ENTER_TRAP \
+	rd	%wim, %l4; \
+	or	%g0, 0x1, %l5; \
+	sll	%l5, %l0, %l5; \
+	andcc	%l0, 0x40, %g0; \
+	bz	1f; \
+	andcc	%l4, %l5, %g0; \
+	bz,a	3f; \
+	sub	%fp, 0xb0, %sp; \
+	TRAP_WIN_CLEAN \
+	b	3f; \
+	sub	%fp, 0xb0, %sp; \
+1:	sethi	%hi(_current), %l6; \
+	ld	[%l6 + %lo(_current)], %l6; \
+	ld	[%l6 + THREAD_WIM], %l5; \
+	and	%l0, 0x1f, %l4; \
+	cmp	%l5, %l3; \
+	ble,a	4f; \
+	sethi	%hi(_nwindowsm1), %l4; \
+	sub	%l5, %l3, %l3; \
+	b	5f; \
+	sub	%l3, 0x1, %l5; \
+4:	ld	[%l4 + %lo(_nwindowsm1)], %l4; \
+	sub	%l4, %l3, %l4; \
+	add	%l5, %l4, %l5; \
+5:	st	%l5, [%l6 + THREAD_UWINDOWS]; \
+	bz,a	2f; \
+	sethi	%hi(TASK_SIZE-176), %l5; \
+	TRAP_WIN_CLEAN; \
+	sethi	%hi(_current), %l6; \
+	ld	[%l6 + %lo(_current)], %l6; \
+	sethi	%hi(TASK_SIZE-176), %l5; \
+2:	or	%l5, %lo(TASK_SIZE-176), %l5; \
+	add	%l6, %l5, %sp; \
+3: \
+
+#define ENTER_IRQ \
+	rd	%wim, %l4; \
+	or	%g0, 0x1, %l5; \
+	sll	%l5, %l0, %l5; \
+	andcc	%l0, 0x40, %g0; \
+	bz	1f; \
+	andcc	%l4, %l5, %g0; \
+	bz,a	0f; \
+	sethi	%hi(_eintstack), %l7; \
+	TRAP_WIN_CLEAN \
+	sethi	%hi(_eintstack), %l7; \
+0:	cmp	%fp, %l7; \
+	bge,a	3f; \
+	sub	%l7, 0xb0, %sp; \
+	b	3f; \
+	sub	%fp, 0xb0, %sp; \
+1: 	sethi	%hi(_current), %l6; \
+	ld	[%l6 + %lo(_current)], %l6; \
+	ld	[%l6 + PCB_WIM], %l5; \
+	and	%l0, 0x1f, %l7; \
+	cmp	%l5, %l7; \
+	ble,a	4f; \
+	sethi	%hi(_nwindowsm1), %l4; \
+	sub	%l5, %l7, %l7; \
+	b	5f; \
+	sub	%l7, 0x1, %l5; \
+4:	ld	[%l4 + %lo(_nwindowsm1)], %l4; \
+	sub	%l4, %l7, %l4; \
+	add	%l5, %l4, %l5; \
+5:	st	%l5, [%l6 + THREAD_UWINDOWS]; \
+	bz,a	2f; \
+	sethi	%hi(_eintstack), %l7; \
+	TRAP_WIN_CLEAN; \
+	sethi	%hi(_eintstack), %l7; \
+2: \
+	sub	%l7, 0xb0, %sp; \
+3: \
+
 	.text
 	.align 4
 
@@ -19,11 +218,9 @@
 		rd %wim, %l4
 		or %g0, 0x1, %l5
 		sll %l5, %l0, %l5
-		cmp %l4, %l5        ! are we in the invalid register?
+		cmp %l4, %l5        ! are we in the invalid window?
 	
-#if 0 /* work in progress */
-		be wash_trap_win
-#endif
+		TRAP_WIN_CLEAN
 
 		nop
 		or %%g0, %l3, %o0
@@ -36,136 +233,255 @@
 		jmp %l1
 		rett %l2
 	
-/* This is cheese and only works reliably if not coming from userland. */
+/* This routine is optimized for kernel window fills. User fills take about two
+ * or three extra jumps on the average. We'll see how this works out.
+ */
+
+/* Don't use local labels, or if you do be REAL CAREFUL. TRAP_WIN_CLEAN is
+ * full of them! If you think this routine is hairy, window spills are worse,
+ * see below.
+ */
+
 	.globl fill_window_entry
 fill_window_entry:
-	wr 	%g0, 0, %wim		! let us into the invalid window
-					! without inducing another trap
-	restore
+	andcc	%l0, 0x40, %g0		! see if this is a user window fill
+	bz,a	fill_from_user
 	nop
-	nop				! no guarentees until 3 insns later
-	restore
-	restore	%g0, 1, %l1
-	rd	%psr, %l0
-	sll	%l1, %l0, %l0
-	wr	%l0, 0, %wim
-	save	%g0, %g0, %g0
 
-/* load up the window */
-	ldd	[%sp], %l0
-	ldd	[%sp + 8], %l2
-	ldd	[%sp + 16], %l4
-	ldd	[%sp + 24], %l6
-	ldd	[%sp + 32], %i0
-	ldd	[%sp + 40], %i2
-	ldd	[%sp + 48], %i4
-	ldd	[%sp + 56], %i6
-
-	save	%g0, %g0, %g0
-	save	%g0, %g0, %g0
+	TRAP_WIN_CLEAN			/* danger, danger... */
+	wr	%l0, 0x0, %psr	
+	nop
 	jmp	%l1
 	rett	%l2
 
-/* Cheese number two, give this a bad stack pointer and get scared. */
+fill_from_user:
+	sethi	%hi(_current), %l6
+	ld	[%l6 + %lo(_current)], %l6
+	ld	[%l6 + THREAD_WIM], %l5
+	and	%l0, 0x1f, %l3
+
+/* I don't know whats worse, the extra comparison here, or an extra load
+ * from a lookup table, we'll see.
+ */
+	cmp	%l5, %l3
+	ble,a	1f
+	sethi	%hi(_nwindowsm1), %l4
+	sub	%l5, %l3, %l3
+	b	2f
+	sub	%l3, 0x1, %l5
+1:	ld	[%l4 + %lo(_nwindowsm1)], %l4
+	sub	%l4, %l3, %l4
+	add	%l5, %l4, %l5
+2:	st	%l5, [%l6 + THREAD_UWINDOWS]
+
+	TRAP_WIN_CLEAN		   /* danger, danger... */
+	sethi	%hi(_current), %l6
+	ld	[%l6 + %lo(_current)], %l6
+	ld	[%l6 + THREAD_KSP], %sp
+	and	%l0, 0x1f, %l3
+	sethi	%hi(lnx_winmask), %l6
+	or	%l6, %lo(lnx_winmask), %l6
+	ldub	[%l6 + %l3], %l5
+	b	back_to_userland_safety		! may need a sched()
+	rd	%wim, %l4
+
+/* A window spill has occurred.  This presents a weird situation, a restore
+ * was attempted and a trap occurred. Therefore the restore attempt had no
+ * effect on window movement and the trap saved, which means it went in the
+ * other direction. :-( We are in a trap window which is two restores away
+ * from the window we want to un-invalidate sorta speak and three away from
+ * the one which will become invalid after this routine. There are probably
+ * bugs already this routine. Bugs suck.
+ */
+
+/* This is a very complicated and hairy routine, don't expect to understand
+ * it the first time. :>
+ */
+
 	.globl spill_window_entry
 spill_window_entry:
-	save	%g0, %g0, %g0  ! save into next 'valid' window
-	std	%l0, [%sp]     ! acquire some scratch registers
-	rd	%psr, %l0
-	or	%g0, 0x1, %l1
-	sll	%l1, %l0, %l0
-	wr	%l0, 0, %wim   ! make window we are saving the 'invalid' one
-	std	%l2, [%sp + 8]
-	std	%l4, [%sp + 16]
-	std	%l6, [%sp + 24]
-	std	%i0, [%sp + 32]
-	std	%i2, [%sp + 40]
-	std	%i4, [%sp + 48]
-	std	%i6, [%sp + 56]
-	restore                ! restore back into the window we want to use
+	wr	%g0, 0, %wim		! Can not enter invalid register without this.
+	andcc	%l0, 0x40, %g0          ! From user?
+	restore				! restore to where trap occurred
+	bz	spill_from_user
+	restore				! enter invalid register, whee...
+	restore %g0, 0x1, %l1		! enter one-past invalid register
+	rd	%psr, %l0		! this is the window we need to save
+	and	%l0, 0x1f, %l0
+	sll	%l1, %l0, %l1
+	wr	%l1, 0x0, %wim
+	sethi	%hi(_current), %l1
+	ld	[%l1 + %lo(_current)], %l1
+	st	%l0, [%l1 + THREAD_WIM]
+	save	%g0, %g0, %g0		! back to invalid register
+	ldd	%l0, [%sp]		! load the window from stack
+	ldd	%l2, [%sp + 8]
+	ldd	%l4, [%sp + 16]
+	ldd	%l6, [%sp + 24]
+	ldd	%i0, [%sp + 32]
+	ldd	%i2, [%sp + 40]
+	ldd	%i4, [%sp + 48]
+	ldd	%i6, [%sp + 56]
+	save	%g0, %g0, %g0		! to window where trap happened
+	save	%g0, %g0, %g0		! back to trap window, so rett works
+	wr	%l0, 0x0, %psr		! load condition codes
+	nop
 	jmp	%l1
-	rett	%l2            ! return from spill handler
-
+	rett	%l2			! are you as confused as I am?
 
-/* This is where most generic traps enter, the registers should be:
-	%l0 == %psr
-	%l1 == %pc
-	%l2 == %npc
-	%l4 == trap_type
-	%l7 == trap_handler
-*/
-
-trap_entry:
-	srl	%l0, 0x6, %l5	! shift over to previous priv bit
-	andcc	%l5, 0x1, %g0   ! 1 == from kernel 0 == from user
-	bz	2f
-	nop			! we dont handle users yet ;-(
-	
-	or	%g0, 0x1, %l5
-	sll	%l5, %l0, %l5	! a trick, only least 5 bits are
-				! significant in a register shift
-				! count.
-	rd	%wim, %l6
-	andcc	%l6, %l5, %g0   ! if (((1<<CWP)&(%wim))==1) we are
-				! in an 'invalid' window
-	bz,a	3f
-	sub	%fp, C_STACK+80, %sp ! cool, just set stack and go
-				     ! this window is valid to use
-	
-/* we aparently need to clean the trap window, inline this for speed */	
-	or	%g0, %g7, %l7	! set up g6 and g7 for scratch
-	or	%g0, %g6, %l6	
+spill_from_user:
+	andcc	%sp, 0x7, %g0		! check for alignment of user stack
+	bne	spill_bad_stack
+	sra	%sp, 0x1e, %l7
+	cmp	%l7, 0x0
+	be,a	1f
+	andn	%sp, 0xfff, %l7
+	cmp	%l7, -1
+	bne	spill_bad_stack
+	andn	%sp, 0xfff, %l7
+1:	lda	[%l7] ASI_PTE, %l7
+	srl	%l7, 0x1d, %l7
+	andn	%l7, 0x2, %l7
+	cmp	%l7, 0x4
+	bne	spill_bad_stack
+	and	%sp, 0xfff, %l7
+	cmp	%l7, 0xfc1
+	bl,a	spill_stack_ok
+	restore	%g0, 1, %l1
+	add	%sp, 0x38, %l5
+	sra	%sp, 0x1e, %l7
+	cmp	%l7, 0x0
+	be,a	1f
+	andn	%sp, 0xfff, %l7
+	cmp	%l7, -1
+	bne	spill_bad_stack
+	andn	%sp, 0xfff, %l7
+1:	lda	[%l7] ASI_PTE, %l7
+	srl	%l7, 0x1d, %l7
+	andn	%l7, 0x2, %l7
+	cmp	%l7, 0x4
+	be,a	spill_stack_ok
+	restore	%g0, 0x1, %l1
+
+spill_bad_stack:
+	save	%g0, %g0, %g0			! save to where restore happened
+	save	%g0, 0x1, %l4			! save is an add remember? to trap window
+	sethi	%hi(_current), %l6
+	ld	[%l6 + %lo(_current)], %l6
+	st	%l4, [%l6 + THREAD_UWINDOWS]	! update current->tss values
+	ld	[%l6 + THREAD_WIN], %l5
+	sll	%l4, %l5, %l4
+	wr	%l4, 0x0, %wim
+	ld	[%l6 + THREAD_KSP], %sp		! set to kernel stack pointer
+	wr	%l0, 0x20, %psr			! turn off traps
+	std	%l0, [%sp + C_STACK]		! set up thread_frame on stack
+	rd	%y, %l3
+	std	%l2, [%sp + C_STACK + 0x8]
+	or	%g0, 0x6, %o0			! so _sparc_trap knows what to do
+	st	%g1, [%sp + C_STACK + 0x14]	! no need to save %g0, always zero
+	or	%g0, %l0, %o1
+	std	%g2, [%sp + C_STACK + 0x18]
+	or	%g0, %l1, %o2
+	std	%g4, [%sp + C_STACK + 0x20]
+	add	%sp, C_STACK, %o3
+	std	%g6, [%sp + C_STACK + 0x28]
+	std	%i0, [%sp + C_STACK + 0x30]
+	std	%i2, [%sp + C_STACK + 0x38]
+	std	%i4, [%sp + C_STACK + 0x40]
+	call	_sparc_trap
+	std	%i6, [%sp + C_STACK + 0x48]
 	
-	save	%g0, %g0, %g0   ! enter next window after the invalid one
-	std	%l0, [%sp]      ! and store it on the stack for later
-	std	%l2, [%sp + 8]  ! retrieval
-	std	%l4, [%sp + 16]
-	std	%l6, [%sp + 24]
-	std	%i0, [%sp + 32]
-	std	%i2, [%sp + 40]
-	std	%i4, [%sp + 48]
-	std	%i6, [%sp + 56]
-
-	rd	%psr, %g7       ! read the current window pointer
-	or	%g0, 0x1, %g6   ! and mask it over into the %wim
-	sll	%g6, %g7, %g6   ! value
-	wr	%g6, 0, %wim    ! make this window the now 'invalid' one
-	and	%g6, 31, %g6
-	restore			! re-enter the trap window, it is ok now
-
-	or	%g0, %l6, %g6	! bring back in the old temporaries
-	or	%g0, %l7, %g7   ! to the locals they were in
+	ldd	[%sp + C_STACK], %l0
+	ldd	[%sp + C_STACK + 0x8], %l2
+	wr	%l3, 0, %y
+	ld	[%sp + C_STACK + 0x14], %g1
+	ldd	[%sp + C_STACK + 0x18], %g2
+	ldd	[%sp + C_STACK + 0x20], %g4
+	ldd	[%sp + C_STACK + 0x28], %g6
+	ldd	[%sp + C_STACK + 0x30], %i0
+	ldd	[%sp + C_STACK + 0x38], %i2
+	ldd	[%sp + C_STACK + 0x40], %i4
+	wr	%l0, 0, %psr			! disable traps again
+	ldd	[%sp + C_STACK + 0x48], %i6
+	sethi	%hi(_current), %l6
+	ld	[%l6 + %lo(_current)], %l6
+	ld	[%l6 + THREAD_W_SAVED], %l7
+	cmp	%l7, 0x0
+	bl,a	1f
+	wr	%g0, 0x0, %wim
+	b,a	leave_trap
+
+1:	or	%g0, %g6, %l3
+	or	%g0, %l6, %g6
+	st	%g0, [%g6 + THREAD_W_SAVED]
+	restore	%g0, %g0, %g0
+	restore	%g0, %g0, %g0
+	restore	%g0, 0x1, %l1
+	rd	%psr, %l0
+	sll	%l1, %l0, %l1
+	wr	%l1, 0x0, %wim
+	and	%l0, 0x1f, %l0
+	st	%l0, [%g6 + THREAD_WIM]
+	nop
+	save	%g0, %g0, %g0
+	ldd	[%sp], %l0			! load number one
+	ldd	[%sp + 0x8], %l2
+	ldd	[%sp + 0x10], %l4
+	ldd	[%sp + 0x18], %l6
+	ldd	[%sp + 0x20], %i0
+	ldd	[%sp + 0x28], %i2
+	ldd	[%sp + 0x30], %i4
+	ldd	[%sp + 0x38], %i6
+	save	%g0, %g0, %g0
+	ldd	[%sp], %l0			! load number two
+	ldd	[%sp + 0x8], %l2	
+	ldd	[%sp + 0x10], %l4
+	ldd	[%sp + 0x18], %l6
+	ldd	[%sp + 0x20], %i0
+	ldd	[%sp + 0x28], %i2
+	ldd	[%sp + 0x30], %i4
+	ldd	[%sp + 0x38], %i6
+	save	%g0, %g0, %g0			! re-enter trap window
+	wr	%l0, 0x0, %psr			! restore condition codes
+	or	%g0, %l3, %g6			! restore scratch register
+	jmp	%l1
+	rett	%l2
 
-	b	3f
-	sub	%fp, C_STACK+80, %sp ! fix stack pointer
+spill_stack_ok:
+	rd	%psr, %l0
+	sll	%l1, %l0, %l1
+	wr	%l1, 0x0, %wim
+	sethi	%hi(_current), %l2
+	ld	[%l2 + %lo(_current)], %l2
+	and	%l0, 0x1f, %l0
+	st	%l0, [%l2 + THREAD_WIM]
+	save	%g0, %g0, %g0
+	ldd	[%sp], %l0			! only one load necessary
+	ldd	[%sp + 0x8], %l2
+	ldd	[%sp + 0x10], %l4
+	ldd	[%sp + 0x18], %l6
+	ldd	[%sp + 0x20], %i0
+	ldd	[%sp + 0x28], %i2
+	ldd	[%sp + 0x30], %i4
+	ldd	[%sp + 0x38], %i6
+	save	%g0, %g0, %g0
+	save	%g0, %g0, %g0			! save into trap window
+	wr	%l0, 0x0, %psr			! local number 0 here has cond codes
+	nop
+	jmp	%l1
+	rett	%l2
 
-	
-/* for now if we get a from-user trap you lose... */
+/* The following two things point to window management tables. The first
+   one is used to quickly look up how many user windows there are from
+   trap-land. The second is used in a trap handler to determine if a rett
+   instruction will land us smack inside the invalid window that possibly
+   the trap was called to fix-up.
+*/
 
-	.data
-	.align 4
+/* For now these are static tables geared for a 7 window sparc. */
 
-tfu_youlose:	.asciz "trap from userland, you lose...\n"
-	
-	.align 4
-	.text
+		.data
+		.align 4
+lnx_winmask:	.byte	2, 4, 8, 16, 32, 64, 128,1  ! lnx_winmask[0..7]
 
-2:	
-	sethi	%hi(tfu_youlose), %o0
-	sethi	%hi(prom_printf), %o1
-	ld	[%o1 + %lo(prom_printf)], %o1
-	call	%o1	
-	or	%o0, %lo(tfu_youlose), %o0
-	
-	sethi	%hi(prom_halt), %o1
-	ld	[%o1 + %lo(prom_halt)], %o1
-	call	%o1				! its over
-	nop
 	
-/* nop and just return, here is where I would jump to the
- * appropriate handler.
- */
-
-	jmp %1
-	rett %l2
-	nop
diff -u --recursive --new-file v1.1.77/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
--- v1.1.77/linux/arch/sparc/kernel/head.S	Mon Jan  9 07:21:58 1995
+++ linux/arch/sparc/kernel/head.S	Mon Jan  9 06:48:47 1995
@@ -488,20 +488,6 @@
         .word   1
 
 
-/* The following two things point to window management tables. The first
-   one is used to quickly look up how many user windows there are from
-   trap-land. The second is used in a trap handler to determine if a rett
-   instruction will land us smack inside the invalid window that possibly
-   the trap was called to fix-up.
-*/
-
-          .data
-          .skip   32                      ! alignment byte & negative indices
-lnx_uw:       .skip   32                      ! u_char uwtab[-31..31];
-lnx_winmask:  .skip   32                      ! u_char wmask[0..31];
-
-        .text
-	
 
 /* Cool, here we go. Pick up the romvec pointer in %o0 and stash it in
    %g7 and at _prom_vector_p. And also quickly check whether we are on
@@ -567,18 +553,18 @@
 not_v2:
 
 /* Get the machine type via the mysterious romvec node operations.
-   Here we can find out whether we are on a sun4 sun4c, sun4m, or
-   a sun4m. The "nodes" are set up as a bunch of n-ary trees which
-   you can traverse to get information about devices and such. The
-   information acquisition happens via the node-ops which are defined
-   in the linux_openprom.h header file. Of particular interest is the
-   'nextnode(int node)' function as it does the smart thing when
-   presented with a value of '0', it gives you the first node in the
-   tree. These node integers probably offset into some internal prom
-   pointer table the openboot has. It's completely undocumented, so
-   I'm not about to go sifting through the prom address space, but may
-   do so if I get suspicious enough. :-)
-*/
+ * Here we can find out whether we are on a sun4 sun4c, sun4m, or
+ * a sun4m. The "nodes" are set up as a bunch of n-ary trees which
+ * you can traverse to get information about devices and such. The
+ * information acquisition happens via the node-ops which are defined
+ * in the linux_openprom.h header file. Of particular interest is the
+ * 'nextnode(int node)' function as it does the smart thing when
+ * presented with a value of '0', it gives you the first node in the
+ * tree. These node integers probably offset into some internal prom
+ * pointer table the openboot has. It's completely undocumented, so
+ * I'm not about to go sifting through the prom address space, but may
+ * do so if I get suspicious enough. :-)
+ */
 
 		or	%g0, %g7, %l1
 		add	%l1, 0x1c, %l1		
@@ -648,10 +634,10 @@
 
 
 /* That was easy, now lets try to print some message on the screen.
-   We don't have to worry about bad address translations when the prom
-   addresses our pointers because our pointers are at 0x0-kern_size
-   as the prom expects.
-*/
+ * We don't have to worry about bad address translations when the prom
+ * addresses our pointers because our pointers are at 0x0-kern_size
+ * as the prom expects.
+ */
 
 		set	boot_msg, %o0	
 		ld	[prom_printf], %o1
@@ -703,11 +689,11 @@
  */
 
 /* Uh, oh, interrupt time. This crap is real confusing. What I want to do is
-   clear all interrupts, map the interrupt enable register which in effect
-   enables non-maskable interrupts (or NMI's). Actuall we take no interrupts
-   until we frob with the %tbr (trap base register) which the prom has set 
-   to all its routines which allows some sanity during bootup.
-*/
+ * clear all interrupts, map the interrupt enable register which in effect
+ * enables non-maskable interrupts (or NMI's). Actuall we take no interrupts
+ * until we frob with the %tbr (trap base register) which the prom has set 
+ * to all its routines which allows some sanity during bootup.
+ */
 
 #if 0 /* paranoid, need to fix this routine now */
 		sethi	%hi(IE_reg_addr), %l0
@@ -722,8 +708,8 @@
 #endif /* paranoid, see above */
 	
 /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
-   show-time!
-*/
+ * show-time!
+ */
 
 		set	1f, %g1
 		jmp	%g1
@@ -779,9 +765,9 @@
 
 
 /*
-   Maybe the prom zero's out our BSS section, maybe it doesn't. I certainly 
-   don't know, do you?
-*/
+ * Maybe the prom zero's out our BSS section, maybe it doesn't. I certainly 
+ * don't know, do you?
+ */
 
 		set	_edata, %o0
 		set	_end, %o1
@@ -831,6 +817,9 @@
 		add	%g3, 0x1, %g3
 		sethi	%hi(_nwindows), %g4
 		st	%g3, [%g4 + %lo(_nwindows)]	! store final value
+		sub	%g3, 0x1, %g3
+		sethi	%hi(_nwindowsm1), %g4
+		st	%g3, [%g4 + %lo(_nwindowsm1)]
 
 
 /* Here we go */
@@ -893,10 +882,10 @@
 	.align 4
 
 /*
-   Fill up the prom vector, note in particular the kind first element,
-   no joke. I don't need all of them in here as the entire prom vector
-   gets initialized in c-code so all routines can use it.
-*/
+ * Fill up the prom vector, note in particular the kind first element,
+ * no joke. I don't need all of them in here as the entire prom vector
+ * gets initialized in c-code so all routines can use it.
+ */
 
 			.globl _prom_vector_p
 
@@ -913,24 +902,34 @@
 prom_printf:		.skip 4			! minimal printf()
 
 /* The prom_abort pointer MUST be mapped in all contexts, because if you
-   don't then if a user process is running when you press the abort key
-   sequence, all sorts of bad things can happen
-*/
+ * don't then if a user process is running when you press the abort key
+ * sequence, all sorts of bad things can happen
+ */
 
 prom_abort:		.skip 4		! "L1-A" magic cookie
 					! must be mapped in ALL contexts
 
 /* prom_sync is a place where the kernel should place a pointer to a kernel
-   function that when called will sync all pending information to the drives
-   and then promptly return. If the kernel gets aborted with 'L1-A' one can
-   give the 'sync' command to the boot prompt and this magic cookie gets
-   executed. Nice feature eh?
-*/
+ * function that when called will sync all pending information to the drives
+ * and then promptly return. If the kernel gets aborted with 'L1-A' one can
+ * give the 'sync' command to the boot prompt and this magic cookie gets
+ * executed. Nice feature eh?
+ */
 
 prom_sync:		.skip 4			! hook in prom for "sync" func
 
 	.align 4
 
+/* We calculate the following at boot time, window fills/spills and trap entry
+ * code uses these to keep track of the register windows.
+ */
+
+	.globl _nwindows
+	.globl _nwindowsm1
+_nwindows:	.skip 4
+_nwindowsm1:	.skip 4
+
+	.align 4
 /* Boot time priviledged register values, plus magic %o2 value */
 
 	.globl _boot_wim
diff -u --recursive --new-file v1.1.77/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- v1.1.77/linux/arch/sparc/kernel/irq.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc/kernel/irq.c	Mon Jan  9 06:48:47 1995
@@ -0,0 +1,131 @@
+/*  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
+ *                            Sparc the IRQ's are basically 'cast in stone'
+ *                            and you are supposed to probe the prom's device
+ *                            node trees to find out who's got which IRQ.
+ *
+ *  Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ *
+ */
+
+/*
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * The same sigaction struct is used, and with similar semantics (ie there
+ * is a SA_INTERRUPT flag etc). Naturally it's not a 1:1 relation, but there
+ * are similarities.
+ *
+ * sa_handler(int irq_NR) is the default function called (0 if no).
+ * sa_mask is horribly ugly (I won't even mention it)
+ * sa_flags contains various info: SA_INTERRUPT etc
+ * sa_restorer is the unused
+ */
+
+
+void disable_irq(unsigned int irq_nr)
+{
+  unsigned long flags;
+
+  save_flags(flags);
+  restore_flags(flags);
+  return;
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+  unsigned long flags;
+
+  save_flags(flags);
+  restore_flags(flags);
+  return;
+}
+
+int get_irq_list(char *buf)
+{
+  int len = 0;
+
+  return len;
+}
+
+/*
+ * do_IRQ handles IRQ's that have been installed without the
+ * SA_INTERRUPT flag: it uses the full signal-handling return
+ * and runs with other interrupts enabled. All relatively slow
+ * IRQ's should use this format: notably the keyboard/timer
+ * routines.
+ */
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+  kstat.interrupts[irq]++;
+  return;
+}
+
+/*
+ * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
+ * stuff - the handler is also running with interrupts disabled unless
+ * it explicitly enables them later.
+ */
+asmlinkage void do_fast_IRQ(int irq)
+{
+  kstat.interrupts[irq]++;
+  return;
+}
+
+#define SA_PROBE SA_ONESHOT
+
+/*
+ * Using "struct sigaction" is slightly silly, but there
+ * are historical reasons and it works well, so..
+ */
+static int irqaction(unsigned int irq, struct sigaction * new_sa)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	restore_flags(flags);
+	return 0;
+}
+		
+int request_irq(unsigned int irq, void (*handler)(int),
+	unsigned long flags, const char * devname)
+{
+	return irqaction(irq,&sa);
+}
+
+void free_irq(unsigned int irq)
+{
+  unsigned long flags;
+
+  save_flags(flags);
+  restore_flags(flags);
+  return;
+}
+
+static void math_error_irq(int cpl)
+{
+  return;
+}
+
+static void no_action(int cpl) { }
+
+unsigned int probe_irq_on (void)
+{
+  unsigned int irqs = 0;
+
+  return irqs;
+}
+
+int probe_irq_off (unsigned int irqs)
+{
+  unsigned int i = 0;
+
+  return i;
+}
+
+void init_IRQ(void)
+{
+  int i;
+
+  for (i = 0; i < 16 ; i++)
+    set_intr_gate(0x20+i,bad_interrupt[i]);
+
+  return;
+}
diff -u --recursive --new-file v1.1.77/linux/drivers/block/cdu31a.c linux/drivers/block/cdu31a.c
--- v1.1.77/linux/drivers/block/cdu31a.c	Mon Jan  9 07:22:00 1995
+++ linux/drivers/block/cdu31a.c	Mon Jan  9 07:56:30 1995
@@ -2863,7 +2863,7 @@
 
    if (drive_found)
    {
-      register_iomem(sony_cd_base_io, 4,"cdu31a");
+      request_region(sony_cd_base_io, 4,"cdu31a");
       
       if (register_blkdev(MAJOR_NR,"cdu31a",&scd_fops))
       {
diff -u --recursive --new-file v1.1.77/linux/drivers/block/hd.c linux/drivers/block/hd.c
--- v1.1.77/linux/drivers/block/hd.c	Mon Jan  9 07:22:01 1995
+++ linux/drivers/block/hd.c	Mon Jan  9 10:05:54 1995
@@ -33,6 +33,7 @@
 #include <linux/genhd.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/ioport.h>
 
 #define REALLY_SLOW_IO
 #include <asm/system.h>
@@ -1023,6 +1024,9 @@
 		if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) {
 			printk("hd: unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
 			NR_HD = 0;
+		} else {
+			request_region(HD_DATA, 8, "hd");
+			request_region(HD_CMD, 1, "hd(cmd)");
 		}
 	}
 	hd_gendisk.nr_real = NR_HD;
diff -u --recursive --new-file v1.1.77/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.1.77/linux/drivers/block/ide.c	Mon Jan  9 07:22:01 1995
+++ linux/drivers/block/ide.c	Mon Jan  9 07:56:30 1995
@@ -1885,8 +1885,8 @@
 		(void) probe_irq_off(probe_irq_on()); /* clear dangling irqs */
 #endif	/* PROBE_FOR_IRQS */
 		if (devs[0].present || devs[1].present) {
-			register_iomem(IDE_PORT(HD_DATA,HWIF),8,"ide");
-			register_iomem(IDE_PORT(HD_CMD,HWIF),1,"ide");
+			request_region(IDE_PORT(HD_DATA,HWIF),8,"ide");
+			request_region(IDE_PORT(HD_CMD,HWIF),1,"ide");
 		}
 		restore_flags(flags);
 	}
diff -u --recursive --new-file v1.1.77/linux/drivers/block/mcd.c linux/drivers/block/mcd.c
--- v1.1.77/linux/drivers/block/mcd.c	Mon Jan  9 07:22:01 1995
+++ linux/drivers/block/mcd.c	Mon Jan  9 07:56:30 1995
@@ -1168,7 +1168,7 @@
 		printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
 		return mem_start;
 	}
-	register_iomem(mcd_port, 4,"mcd");
+	request_region(mcd_port, 4,"mcd");
 
 	outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
 	outb(0x02,MCDPORT(0));
diff -u --recursive --new-file v1.1.77/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c
--- v1.1.77/linux/drivers/block/sbpcd.c	Mon Jan  9 07:22:01 1995
+++ linux/drivers/block/sbpcd.c	Mon Jan  9 07:56:30 1995
@@ -4228,7 +4228,7 @@
   blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
   read_ahead[MAJOR_NR] = SBP_BUFFER_FRAMES * (CD_FRAMESIZE / 512);
   
-  register_iomem(CDo_command,4,"sbpcd");
+  request_region(CDo_command,4,"sbpcd");
 
   for (j=0;j<NR_SBPCD;j++)
     {
diff -u --recursive --new-file v1.1.77/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v1.1.77/linux/drivers/char/Makefile	Mon Jan  9 07:22:01 1995
+++ linux/drivers/char/Makefile	Mon Jan  9 09:19:29 1995
@@ -75,7 +75,7 @@
 
 MODULES := lp.o
 
-all: char.a modules
+all: char.a
 
 char.a: $(OBJS)
 	$(AR) rcs char.a $(OBJS)
@@ -83,8 +83,7 @@
 
 ifdef MODULES
 
-modules:
-	$(MAKE) CFLAGS="$(CFLAGS) -DMODULE" $(MODULES)
+modules: $(MODULES)
 	(cd ../../modules;for i in $(MODULES); do ln -sf ../drivers/char/$$i .; done)
 
 else
diff -u --recursive --new-file v1.1.77/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v1.1.77/linux/drivers/char/lp.c	Mon Jan  9 07:22:02 1995
+++ linux/drivers/char/lp.c	Mon Jan  9 07:56:30 1995
@@ -494,7 +494,6 @@
 	int offset = 0;
 	unsigned int testvalue = 0;
 	int count = 0;
-	char buf[5];
 
 	if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) {
 		printk("unable to get major %d for line printer\n", LP_MAJOR);
@@ -513,8 +512,7 @@
 			LP_F(offset) |= LP_EXIST;
 			lp_reset(offset);
 			printk("lp%d at 0x%04x, ", offset,LP_B(offset));
-			sprintf(buf,"lp%d",offset);
-			register_iomem(LP_B(offset), 3,buf);
+			request_region(LP_B(offset), 3, "lp");
 			if (LP_IRQ(offset))
 				printk("using IRQ%d\n", LP_IRQ(offset));
 			else
@@ -536,7 +534,6 @@
 	int offset = 0;
 	unsigned int testvalue = 0;
 	int count = 0;
-	char buf[5];
 
 	if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) {
 		printk("unable to get major %d for line printer\n", LP_MAJOR);
@@ -553,8 +550,7 @@
 			LP_F(offset) |= LP_EXIST;
 			lp_reset(offset);
 			printk("lp%d at 0x%04x, ", offset,LP_B(offset));
-			sprintf(buf,"lp%d",offset);
-			register_iomem(LP_B(offset),3,buf);
+			request_region(LP_B(offset),3,"lp");
 			if (LP_IRQ(offset))
 				printk("using IRQ%d\n", LP_IRQ(offset));
 			else
diff -u --recursive --new-file v1.1.77/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v1.1.77/linux/drivers/char/serial.c	Mon Jan  9 07:22:02 1995
+++ linux/drivers/char/serial.c	Mon Jan  9 07:56:30 1995
@@ -1479,7 +1479,7 @@
 		info->hub6 = new_serial.hub6;
 	}
 	if(info->type != PORT_UNKNOWN)
-		register_iomem(info->port,8,"serial(set)");
+		request_region(info->port,8,"serial(set)");
 
 	
 check_and_exit:
@@ -2353,7 +2353,7 @@
 		if ((status1 != 0xa5) || (status2 != 0x5a))
 			info->type = PORT_8250;
 	}
-	register_iomem(info->port,8,"serial(auto)");
+	request_region(info->port,8,"serial(auto)");
 
 	/*
 	 * Reset the UART.
diff -u --recursive --new-file v1.1.77/linux/drivers/char/vesa_blank.c linux/drivers/char/vesa_blank.c
--- v1.1.77/linux/drivers/char/vesa_blank.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/char/vesa_blank.c	Mon Jan  9 08:17:07 1995
@@ -40,6 +40,8 @@
 
 #include <asm/io.h>
 #include <asm/system.h>
+#include <asm/segment.h>
+
 extern unsigned short video_port_reg, video_port_val;
 
 /*
@@ -236,7 +238,8 @@
 	vesa_blanked = 0;
 }
 
-void set_vesa_blanking(const unsigned long arg) {
+void set_vesa_blanking(const unsigned long arg)
+{
 	char *argp = (char *)(arg + 1);
 	unsigned int mode = get_fs_byte(argp);
 	vesa_blanking_mode = ((mode < 3) ? mode : 0);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/3c501.c linux/drivers/net/3c501.c
--- v1.1.77/linux/drivers/net/3c501.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/3c501.c	Mon Jan  9 07:56:28 1995
@@ -81,6 +81,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/errno.h>
+#include <linux/config.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -229,7 +230,7 @@
 	return ENODEV;
 
     /* Grab the region so we can find the another board if autoIRQ fails. */
-    register_iomem(ioaddr, EL1_IO_EXTENT,"3c501");
+    request_region(ioaddr, EL1_IO_EXTENT,"3c501");
 
     if (dev == NULL)
 	dev = init_etherdev(0, sizeof(struct net_local), 0);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/3c503.c linux/drivers/net/3c503.c
--- v1.1.77/linux/drivers/net/3c503.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/3c503.c	Mon Jan  9 07:56:29 1995
@@ -172,7 +172,7 @@
 	return ENODEV;
     }
 
-    register_iomem(ioaddr, EL2_IO_EXTENT,"3c503");
+    request_region(ioaddr, EL2_IO_EXTENT,"3c503");
 
     if (dev == NULL)
 	dev = init_etherdev(0, sizeof(struct ei_device), 0);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v1.1.77/linux/drivers/net/3c507.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/3c507.c	Mon Jan  9 07:56:29 1995
@@ -370,7 +370,7 @@
 	}
 	
 	/* We've committed to using the board, and can start filling in *dev. */
-	register_iomem(ioaddr, EL16_IO_EXTENT,"3c507");
+	request_region(ioaddr, EL16_IO_EXTENT,"3c507");
 	dev->base_addr = ioaddr;
 
 	outb(0x01, ioaddr + MISC_CTRL);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v1.1.77/linux/drivers/net/3c509.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/3c509.c	Mon Jan  9 07:56:28 1995
@@ -224,7 +224,7 @@
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
 	dev->if_port = if_port;
-	register_iomem(dev->base_addr, 16,"3c509");
+	request_region(dev->base_addr, 16,"3c509");
 
 	{
 		char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
diff -u --recursive --new-file v1.1.77/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v1.1.77/linux/drivers/net/Makefile	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/Makefile	Mon Jan  9 09:20:28 1995
@@ -192,16 +192,10 @@
 
 ifdef MODULES
 
-modules:
+modules: $(MODULES)
 	echo $(MODULES) > ../../modules/NET_MODULES
-	@(cd ../../modules; \
-		for i in $(MODULES:.o=.c); \
-			do ln -sf ../drivers/net/$$i .; \
-			done ; \
-		ln -sf ../drivers/net/CONFIG . ; \
-		$(MAKE) -f../drivers/net/Makefile -I../drivers/net \
-			CFLAGS="$(CFLAGS) -I../net/inet -I../drivers/net -DMODULE" $(MODULES); \
-		rm $(MODULES:.o=.c) CONFIG)
+	cd ../../modules; \
+		for i in $(MODULES); do ln -sf ../drivers/net/$$i .; done
 
 else
 
diff -u --recursive --new-file v1.1.77/linux/drivers/net/apricot.c linux/drivers/net/apricot.c
--- v1.1.77/linux/drivers/net/apricot.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/apricot.c	Mon Jan  9 07:56:29 1995
@@ -44,7 +44,7 @@
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(addr, size)	0
-#define register_iomem(addr, size,name)	do ; while(0)
+#define request_region(addr, size,name)	do ; while(0)
 #endif
 
 #ifndef HAVE_ALLOC_SKB
@@ -714,7 +714,7 @@
     if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
     	return ENODEV;
 
-    register_iomem(ioaddr, APRICOT_TOTAL_SIZE,"apricot");
+    request_region(ioaddr, APRICOT_TOTAL_SIZE,"apricot");
 
     dev->base_addr = ioaddr;
     ether_setup(dev);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v1.1.77/linux/drivers/net/at1700.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/at1700.c	Mon Jan  9 07:56:29 1995
@@ -207,7 +207,7 @@
 
 	/* Grab the region so that we can find another board if the IRQ request
 	   fails. */
-	register_iomem(ioaddr, AT1700_IO_EXTENT,"at1700");
+	request_region(ioaddr, AT1700_IO_EXTENT,"at1700");
 
 	printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
 		   ioaddr, irq);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v1.1.77/linux/drivers/net/atp.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/atp.c	Mon Jan  9 07:56:29 1995
@@ -113,7 +113,7 @@
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(ioaddr, size)		0
-#define register_iomem(ioaddr, size,name);		do ; while (0)
+#define request_region(ioaddr, size,name);		do ; while (0)
 #endif
 
 /* use 0 for production, 1 for verification, >2 for debug */
diff -u --recursive --new-file v1.1.77/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v1.1.77/linux/drivers/net/depca.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/depca.c	Mon Jan  9 07:56:29 1995
@@ -480,7 +480,7 @@
 	}
 
 #ifdef HAVE_PORTRESERVE
-	register_iomem(ioaddr, DEPCA_TOTAL_SIZE,"depca");
+	request_region(ioaddr, DEPCA_TOTAL_SIZE,"depca");
 #endif
 
 	/*
diff -u --recursive --new-file v1.1.77/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v1.1.77/linux/drivers/net/e2100.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/e2100.c	Mon Jan  9 07:56:29 1995
@@ -147,7 +147,7 @@
 		return ENODEV;
 
 	/* Grab the region so we can find a different board if IRQ select fails. */
-	register_iomem(ioaddr, E21_IO_EXTENT,"e2100");
+	request_region(ioaddr, E21_IO_EXTENT,"e2100");
 
 	/* Read the station address PROM.  */
 	for (i = 0; i < 6; i++)
diff -u --recursive --new-file v1.1.77/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v1.1.77/linux/drivers/net/eexpress.c	Mon Jan  9 07:22:05 1995
+++ linux/drivers/net/eexpress.c	Mon Jan  9 07:56:29 1995
@@ -363,7 +363,7 @@
 	}
 
 	/* We've committed to using the board, and can start filling in *dev. */
-	register_iomem(ioaddr, 16,"eexpress");
+	request_region(ioaddr, 16,"eexpress");
 	dev->base_addr = ioaddr;
 
 	for (i = 0; i < 6; i++) {
diff -u --recursive --new-file v1.1.77/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v1.1.77/linux/drivers/net/ewrk3.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/ewrk3.c	Mon Jan  9 07:56:30 1995
@@ -352,7 +352,7 @@
       if (!check_region(base_addr, EWRK3_IOP_INC)) {
 	if (((mem_chkd >> ((base_addr - EWRK3_IO_BASE)/ EWRK3_IOP_INC))&0x01)==1) {
 	  if (DevicePresent(base_addr) == 0) {      /* Is EWRK3 really here? */
-	    register_iomem(base_addr, EWRK3_IOP_INC,"ewrk3"); /* Register I/O region */
+	    request_region(base_addr, EWRK3_IOP_INC,"ewrk3"); /* Register I/O region */
 	    status = ewrk3_hw_init(dev, base_addr);
 	  } else {
 	    printk("ewrk3_probe(): No device found\n");
@@ -1344,7 +1344,7 @@
 ** Device found. Mark its (I/O) location for future reference. Only 24
 ** EtherWORKS devices can exist between 0x100 and 0x3e0.
 */
-	  register_iomem(iobase, EWRK3_IOP_INC,"ewrk3");
+	  request_region(iobase, EWRK3_IOP_INC,"ewrk3");
 	  if (num_ewrk3s > 0) {        /* only gets here in autoprobe */
 	    dev = alloc_device(dev, iobase);
 	  } else {
@@ -1387,7 +1387,7 @@
 ** EtherWORKS devices can exist in EISA space....
 */
 	mem_chkd |= (0x01 << (i + 24));
-	register_iomem(iobase, EWRK3_IOP_INC,"ewrk3");
+	request_region(iobase, EWRK3_IOP_INC,"ewrk3");
 	if (num_ewrk3s > 0) {        /* only gets here in autoprobe */
 	  dev = alloc_device(dev, iobase);
 	} else {
diff -u --recursive --new-file v1.1.77/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- v1.1.77/linux/drivers/net/hp-plus.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/hp-plus.c	Mon Jan  9 07:56:29 1995
@@ -178,7 +178,7 @@
 	}
 
 	/* Grab the region so we can find another board if something fails. */
-	register_iomem(ioaddr, HP_IO_EXTENT,"hp-plus");
+	request_region(ioaddr, HP_IO_EXTENT,"hp-plus");
 
 	/* Read the IRQ line. */
 	outw(HW_Page, ioaddr + HP_PAGING);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/hp.c linux/drivers/net/hp.c
--- v1.1.77/linux/drivers/net/hp.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/hp.c	Mon Jan  9 07:56:28 1995
@@ -125,7 +125,7 @@
 		dev = init_etherdev(0, sizeof(struct ei_device), 0);
 
 	/* Grab the region so we can find another board if something fails. */
-	register_iomem(ioaddr, HP_IO_EXTENT,"hp");
+	request_region(ioaddr, HP_IO_EXTENT,"hp");
 
 	printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
 
diff -u --recursive --new-file v1.1.77/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v1.1.77/linux/drivers/net/lance.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/lance.c	Mon Jan  9 07:56:28 1995
@@ -365,7 +365,7 @@
 		printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
 
 	dev->base_addr = ioaddr;
-	register_iomem(ioaddr, LANCE_TOTAL_SIZE,"lance");
+	request_region(ioaddr, LANCE_TOTAL_SIZE,"lance");
 
 	/* Make certain the data structures used by the LANCE are aligned. */
 	dev->priv = (void *)(((int)dev->priv + 7) & ~7);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v1.1.77/linux/drivers/net/ne.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/ne.c	Mon Jan  9 07:56:28 1995
@@ -259,7 +259,7 @@
 
     dev->base_addr = ioaddr;
 
-    register_iomem(ioaddr, NE_IO_EXTENT,"ne2000");
+    request_region(ioaddr, NE_IO_EXTENT,"ne2000");
 
     for(i = 0; i < ETHER_ADDR_LEN; i++)
 	dev->dev_addr[i] = SA_prom[i];
diff -u --recursive --new-file v1.1.77/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v1.1.77/linux/drivers/net/ni52.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/ni52.c	Mon Jan  9 07:56:29 1995
@@ -181,7 +181,7 @@
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(ioaddr, size) 		0
-#define	register_iomem(ioaddr, size,name);		do ; while (0)
+#define	request_region(ioaddr, size,name);		do ; while (0)
 #endif
 
 #define NI52_TOTAL_SIZE 16
@@ -388,7 +388,7 @@
 
   printk("%s: Ni52 found at %#3x, ",dev->name,dev->base_addr);
 
-  register_iomem(ioaddr,NI52_TOTAL_SIZE,"ni52");
+  request_region(ioaddr,NI52_TOTAL_SIZE,"ni52");
 
   dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
                                   /* warning: we don't free it on errors */
diff -u --recursive --new-file v1.1.77/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v1.1.77/linux/drivers/net/ni65.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/ni65.c	Mon Jan  9 07:56:30 1995
@@ -54,7 +54,7 @@
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(ioaddr, size)              0
-#define register_iomem(ioaddr, size,name);             do ; while (0)
+#define request_region(ioaddr, size,name);             do ; while (0)
 #endif
 
 #ifndef NET_DEBUG
@@ -243,7 +243,7 @@
   irq2dev_map[dev->irq] = dev;
 
   /* Grab the region so we can find another board if autoIRQ fails. */
-        register_iomem(ioaddr,NI65_TOTAL_SIZE,"ni65");
+        request_region(ioaddr,NI65_TOTAL_SIZE,"ni65");
 
   p = dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
   memset((char *) dev->priv,0,sizeof(struct priv));
diff -u --recursive --new-file v1.1.77/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v1.1.77/linux/drivers/net/plip.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/plip.c	Mon Jan  9 07:56:28 1995
@@ -225,7 +225,7 @@
 	}
     }
 
-    register_iomem(PAR_DATA(dev), 3,"plip");
+    request_region(PAR_DATA(dev), 3,"plip");
 
     /* Fill in the generic fields of the device structure. */
     ether_setup(dev);
diff -u --recursive --new-file v1.1.77/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v1.1.77/linux/drivers/net/sk_g16.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/sk_g16.c	Mon Jan  9 07:56:29 1995
@@ -329,7 +329,7 @@
 #ifndef HAVE_PORTRESERVE
 
 #define check_region(ioaddr, size)              0
-#define register_iomem(ioaddr, size,name);             do ; while (0)
+#define request_region(ioaddr, size,name);             do ; while (0)
 
 #endif
 
@@ -782,7 +782,7 @@
 	    dev->dev_addr[5]);
 
     /* Grab the I/O Port region */
-    register_iomem(ioaddr, ETHERCARD_TOTAL_SIZE,"sk_g16");
+    request_region(ioaddr, ETHERCARD_TOTAL_SIZE,"sk_g16");
 
     /* Initialize device structure */
 
diff -u --recursive --new-file v1.1.77/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c
--- v1.1.77/linux/drivers/net/skeleton.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/skeleton.c	Mon Jan  9 07:56:29 1995
@@ -247,7 +247,7 @@
 #endif	/* jumpered DMA */
 
 	/* Grab the region so we can find another board if autoIRQ fails. */
-	register_iomem(ioaddr, NETCARD_IO_EXTENT,"skeleton");
+	request_region(ioaddr, NETCARD_IO_EXTENT,"skeleton");
 
 	/* Initialize the device structure. */
 	if (dev->priv == NULL)
diff -u --recursive --new-file v1.1.77/linux/drivers/net/slip.h linux/drivers/net/slip.h
--- v1.1.77/linux/drivers/net/slip.h	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/slip.h	Mon Jan  9 07:35:23 1995
@@ -71,6 +71,11 @@
   unsigned long         rx_dropped;     /* No memory for skb            */
   unsigned long         tx_dropped;     /* When MTU change              */
   unsigned long         rx_over_errors; /* Frame bigger then SLIP buf.  */
+#ifdef SL_INCLUDE_CSLIP
+  unsigned long		tx_compressed;
+  unsigned long		rx_compressed;
+  unsigned long		tx_misses;
+#endif
   /* Detailed SLIP statistics. */
 
   int			mtu;		/* Our mtu (to spot changes!)   */
diff -u --recursive --new-file v1.1.77/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- v1.1.77/linux/drivers/net/smc-ultra.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/smc-ultra.c	Mon Jan  9 07:56:29 1995
@@ -147,7 +147,7 @@
 
 
 	/* OK, were are certain this is going to work.  Setup the device. */
-	register_iomem(ioaddr, 32,"smc-ultra");
+	request_region(ioaddr, 32,"smc-ultra");
 
 	/* The 8390 isn't at the base address, so fake the offset */
 	dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
diff -u --recursive --new-file v1.1.77/linux/drivers/net/wd.c linux/drivers/net/wd.c
--- v1.1.77/linux/drivers/net/wd.c	Mon Jan  9 07:22:06 1995
+++ linux/drivers/net/wd.c	Mon Jan  9 07:56:29 1995
@@ -235,7 +235,7 @@
 	}
 
 	/* OK, were are certain this is going to work.  Setup the device. */
-	register_iomem(ioaddr, WD_IO_EXTENT,"wd");
+	request_region(ioaddr, WD_IO_EXTENT,"wd");
 	ethdev_init(dev);
 
 	ei_status.name = model_name;
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v1.1.77/linux/drivers/scsi/Makefile	Mon Jan  9 07:22:06 1995
+++ linux/drivers/scsi/Makefile	Mon Jan  9 09:21:00 1995
@@ -189,6 +189,7 @@
 
 endif
 
+modules:
 
 #
 # include a dependency file if one exists
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v1.1.77/linux/drivers/scsi/aha152x.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/aha152x.c	Mon Jan  9 07:56:31 1995
@@ -722,7 +722,7 @@
          can_disconnect ? "enabled" : "disabled",
          can_doparity ? "enabled" : "disabled");
 
-  register_iomem(port_base, TEST-SCSISEQ,"aha152x");        /* Register */
+  request_region(port_base, TEST-SCSISEQ,"aha152x");        /* Register */
   
   /* not expecting any interrupts */
   SETPORT(SIMODE0, 0);
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v1.1.77/linux/drivers/scsi/aha1542.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/aha1542.c	Mon Jan  9 07:56:30 1995
@@ -1053,7 +1053,7 @@
 			    aha1542_command(0, cmd, buffer, 512);
 		    }
 #endif    
-		    register_iomem(bases[indx], 4,"aha1542");  /* Register the IO ports that we use */
+		    request_region(bases[indx], 4,"aha1542");  /* Register the IO ports that we use */
 		    count++;
 		    continue;
 	    unregister:
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- v1.1.77/linux/drivers/scsi/aha1740.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/aha1740.c	Mon Jan  9 07:56:31 1995
@@ -471,7 +471,7 @@
         printk("Unable to allocate IRQ for adaptec controller.\n");
         return 0;
     }
-    register_iomem(base, 0x5c,"aha1740");  /* Reserve the space that we need to use */
+    request_region(base, 0x5c,"aha1740");  /* Reserve the space that we need to use */
     return 1;
 }
 
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/buslogic.c linux/drivers/scsi/buslogic.c
--- v1.1.77/linux/drivers/scsi/buslogic.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/buslogic.c	Mon Jan  9 07:56:31 1995
@@ -1336,7 +1336,7 @@
 	    }
 #endif
 
-	    register_iomem(bases[indx], 4,"buslogic");
+	    request_region(bases[indx], 4,"buslogic");
 	    /* Register the IO ports that we use */
 	    count++;
 	    continue;
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v1.1.77/linux/drivers/scsi/eata.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/eata.c	Mon Jan  9 07:56:31 1995
@@ -385,7 +385,7 @@
    sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
 
    /* Register the I/O space that we use */
-   register_iomem(sh[j]->io_port, REG_REGION,"eata");
+   request_region(sh[j]->io_port, REG_REGION,"eata");
 
    memset(HD(j), 0, sizeof(struct hostdata));
    HD(j)->subversion = subversion;
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v1.1.77/linux/drivers/scsi/fdomain.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/fdomain.c	Mon Jan  9 07:56:31 1995
@@ -704,7 +704,7 @@
 
 				/* Log I/O ports with kernel */
 
-   register_iomem( port_base, 0x10 ,"fdomain");
+   request_region( port_base, 0x10 ,"fdomain");
 
    if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
       adapter_mask = 0x80;
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c
--- v1.1.77/linux/drivers/scsi/in2000.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/in2000.c	Mon Jan  9 07:56:31 1995
@@ -46,6 +46,9 @@
  */
 /* Changes for 1.1.43+ kernels made 8/25/94, code added to check for
  * new BIOS version, derived by jshiffle@netcom.com. (WDE)
+ *
+ * 1/7/95 Fix from Peter Lu (swift@world.std.com) for datalen vs. dataptr
+ * logic, much more stable under load.
  */
 
 #include <linux/kernel.h>
@@ -195,10 +198,9 @@
 #endif
     } while((in2000_datalen > 0) && ((infcnt = (inb(INFCNT)) & 0xfe) >= 0x20) );
     /* If scatter-gather, go on to next segment */
-    if( !in2000_datalen && in2000_current_segment < in2000_nsegment)
+    if( !in2000_datalen && ++in2000_current_segment < in2000_nsegment)
       {
       in2000_scatter++;
-      in2000_current_segment++;
       in2000_datalen = in2000_scatter->length;
       in2000_dataptr = (unsigned short*)in2000_scatter->address;
       }
@@ -253,10 +255,9 @@
 DEB(printk("FIer:%d %02x %08x\n", in2000_datalen,fic,(unsigned int )in2000_dataptr));
 /*    while ( count-- )
     	inw(INFIFO);*/	/* Throw away some extra stuff */
-    if( !in2000_datalen && in2000_current_segment < in2000_nsegment)
+    if( !in2000_datalen && ++in2000_current_segment < in2000_nsegment)
       {
       in2000_scatter++;
-      in2000_current_segment++;
       in2000_datalen = in2000_scatter->length;
       in2000_dataptr = (unsigned short*)in2000_scatter->address;
       }
@@ -288,13 +289,16 @@
 		scsistatus,cmdphase,scsibyte));
 
 	/* Why do we assume that we need to send more data here??? ERY */
-   	if ( in2000_datalen && in2000_dataptr )	/* data xfer pending */
+   	if ( in2000_datalen )	/* data xfer pending */
    	    {
-   	    if ( in2000_datawrite )
+   	    if ( in2000_dataptr == NULL )
+		printk("int2000: dataptr=NULL datalen=%d\n",
+			in2000_datalen);
+	    else if ( in2000_datawrite )
 		in2000_fifo_out();
 	    else
 		in2000_fifo_in();
-   	    } else ficmsk = 0;
+   	    } 
 	if ( (auxstatus & 0x8c) == 0x80 )
 	    {	/* There is a WD Chip interrupt & register read good */
 	    outb(2,ININTR);	/* Disable fifo interrupts */
@@ -630,7 +634,7 @@
     shpnt->io_port = base;
     shpnt->n_io_port = 12;
     shpnt->irq = irq_level;
-    register_iomem(base, 12,"in2000");  /* Prevent other drivers from using this space */
+    request_region(base, 12,"in2000");  /* Prevent other drivers from using this space */
     return 1;
 }
 
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/qlogic.c linux/drivers/scsi/qlogic.c
--- v1.1.77/linux/drivers/scsi/qlogic.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/qlogic.c	Mon Jan  9 07:56:31 1995
@@ -527,7 +527,7 @@
 		host->can_queue = 1;
 	sti();
 #endif
-	register_iomem( qbase , 0x10 ,"qlogic");
+	request_region( qbase , 0x10 ,"qlogic");
 
 	hreg = scsi_register( host , 0 );	/* no host data */
 	hreg->io_port = qbase;
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v1.1.77/linux/drivers/scsi/u14-34f.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/u14-34f.c	Mon Jan  9 07:56:31 1995
@@ -352,7 +352,7 @@
    if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK);
 
    /* Register the I/O space that we use */
-   register_iomem(sh[j]->io_port, REG_REGION,"u14-34f");
+   request_region(sh[j]->io_port, REG_REGION,"u14-34f");
 
    memset(HD(j), 0, sizeof(struct hostdata));
    HD(j)->heads = mapping_table[config_2.mapping_mode].heads;
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- v1.1.77/linux/drivers/scsi/ultrastor.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/ultrastor.c	Mon Jan  9 07:56:31 1995
@@ -438,7 +438,7 @@
     /* All above tests passed, must be the right thing.  Get some useful
        info. */
 
-    register_iomem(config.port_address, 0x0c,"ultrastor"); 
+    request_region(config.port_address, 0x0c,"ultrastor"); 
     /* Register the I/O space that we use */
 
     *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/ultrastor.h linux/drivers/scsi/ultrastor.h
--- v1.1.77/linux/drivers/scsi/ultrastor.h	Tue Nov 29 10:07:11 1994
+++ linux/drivers/scsi/ultrastor.h	Sun Jan  8 01:38:39 1995
@@ -30,7 +30,7 @@
 
 
 #define ULTRASTOR_14F { NULL, NULL, /* Ptr for modules*/ \
-			  NULL,			 	\
+			  "UltraStor 14F/24F/34F", 	\
 			  ultrastor_detect, 		\
 			  NULL,	/* Release */		\
 			  ultrastor_info, 		\
diff -u --recursive --new-file v1.1.77/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c
--- v1.1.77/linux/drivers/scsi/wd7000.c	Mon Jan  9 07:22:07 1995
+++ linux/drivers/scsi/wd7000.c	Mon Jan  9 07:56:31 1995
@@ -1162,7 +1162,7 @@
                 printk("using IO %xh IRQ %d DMA %d.\n",
 		       host->iobase, host->irq, host->dma);
 
-		register_iomem(host->iobase, 4,"wd7000"); /* Register our ports */
+		request_region(host->iobase, 4,"wd7000"); /* Register our ports */
 		/*
 		 *  For boards before rev 6.0, scatter/gather isn't supported.
 		 */
diff -u --recursive --new-file v1.1.77/linux/fs/Makefile linux/fs/Makefile
--- v1.1.77/linux/fs/Makefile	Mon Jan  9 07:22:08 1995
+++ linux/fs/Makefile	Mon Jan  9 09:22:18 1995
@@ -41,6 +41,8 @@
 
 ifdef CONFIG_NFS_FS
 FS_SUBDIRS := $(FS_SUBDIRS) nfs
+else
+MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) nfs
 endif
 
 ifdef CONFIG_XIA_FS
@@ -93,8 +95,10 @@
 	  test ! -d $$i || \
 	    { $(MAKE) -C $$i; $(AR) rcs filesystems.a $$i/$$i.o; }; done
 
-modules:
-	set -e; for i in $(MODULE_FS_SUBDIRS); do $(MAKE) -C $$i modules; done
+modules: $(MODULE_OBJS)
+	for i in $(MODULE_FS_SUBDIRS); do $(MAKE) -C $$i modules; done
+	cd ../modules;for i in $(MODULE_OBJS); do ln -sf ../fs/$$i .; done
+	cd ../modules;for i in $(MODULE_FS_SUBDIRS); do ln -sf ../fs/$$i/$$i.o .; done
 
 depend dep:
 	$(CPP) -M *.c > .depend
diff -u --recursive --new-file v1.1.77/linux/fs/isofs/Makefile linux/fs/isofs/Makefile
--- v1.1.77/linux/fs/isofs/Makefile	Mon Jan  9 07:22:08 1995
+++ linux/fs/isofs/Makefile	Mon Jan  9 09:22:31 1995
@@ -7,10 +7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_ISO9660_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
 	$(CC) $(CFLAGS) -S $<
 .c.o:
diff -u --recursive --new-file v1.1.77/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
--- v1.1.77/linux/fs/isofs/inode.c	Mon Jan  9 07:22:08 1995
+++ linux/fs/isofs/inode.c	Mon Jan  9 09:47:16 1995
@@ -251,7 +251,7 @@
 
 		brelse(bh);
 	      }
-	if(iso_blknum == 100) {
+	if(iso_blknum == vol_desc_start + 100) {
 		if (!silent)
 			printk("Unable to identify CD-ROM format.\n");
 		s->s_dev = 0;
diff -u --recursive --new-file v1.1.77/linux/fs/minix/Makefile linux/fs/minix/Makefile
--- v1.1.77/linux/fs/minix/Makefile	Mon Jan  9 07:22:08 1995
+++ linux/fs/minix/Makefile	Mon Jan  9 09:23:00 1995
@@ -7,10 +7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_MINIX_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
 	$(CC) $(CFLAGS) -S $<
 .c.o:
@@ -26,6 +22,8 @@
 
 dep:
 	$(CPP) -M *.c > .depend
+
+modules: minix.o
 
 #
 # include a dependency file if one exists
diff -u --recursive --new-file v1.1.77/linux/fs/msdos/Makefile linux/fs/msdos/Makefile
--- v1.1.77/linux/fs/msdos/Makefile	Mon Jan  9 07:22:08 1995
+++ linux/fs/msdos/Makefile	Mon Jan  9 09:23:15 1995
@@ -7,10 +7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_MSDOS_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
 	$(CC) $(CFLAGS) -S $<
 .c.o:
diff -u --recursive --new-file v1.1.77/linux/fs/nfs/Makefile linux/fs/nfs/Makefile
--- v1.1.77/linux/fs/nfs/Makefile	Wed Dec  1 14:44:15 1993
+++ linux/fs/nfs/Makefile	Mon Jan  9 09:23:36 1995
@@ -23,6 +23,8 @@
 dep:
 	$(CPP) -M *.c > .depend
 
+modules: nfs.o
+
 #
 # include a dependency file if one exists
 #
diff -u --recursive --new-file v1.1.77/linux/fs/proc/array.c linux/fs/proc/array.c
--- v1.1.77/linux/fs/proc/array.c	Mon Jan  9 07:22:08 1995
+++ linux/fs/proc/array.c	Mon Jan  9 08:17:07 1995
@@ -19,6 +19,9 @@
  *
  * Alessandro Rubini :  profile extension.
  *                      <rubini@ipvvis.unipv.it>
+ *
+ * Jeff Tranter      :  added BogoMips field to cpuinfo
+ *                      <Jeff_Tranter@Mitel.COM>
  */
 
 #include <linux/types.h>
@@ -34,6 +37,7 @@
 #include <linux/proc_fs.h>
 #include <linux/ioport.h>
 #include <linux/config.h>
+#include <linux/delay.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -262,6 +266,7 @@
 
 static int get_cpuinfo(char * buffer)
 {
+#ifdef __i386__
 	char *model[2][9]={{"DX","SX","DX/2","4","SX/2","6",
 				"7","DX/4"},
 			{"Pentium 60/66","Pentium 90/100","3",
@@ -284,7 +289,8 @@
 			      "TS Counters\t: %s\n"
 			      "Pentium MSR\t: %s\n"
 			      "Mach. Ch. Exep.\t: %s\n"
-			      "CMPXCHGB8B\t: %s\n",
+			      "CMPXCHGB8B\t: %s\n"
+		              "BogoMips\t: %lu.%02lu\n",
 			      x86+'0', 
 			      x86_model ? model[x86-4][x86_model-1] : "Unknown",
 			      x86_mask ? mask : "Unknown",
@@ -300,8 +306,12 @@
 			      x86_capability & 16 ? "yes" : "no",
 			      x86_capability & 32 ? "yes" : "no",
 			      x86_capability & 128 ? "yes" : "no",
-			      x86_capability & 256 ? "yes" : "no"
+			      x86_capability & 256 ? "yes" : "no",
+		              loops_per_sec/500000, (loops_per_sec/5000) % 100
 			      );
+#else
+	return 0;
+#endif
 }
 
 static struct task_struct ** get_task(pid_t pid)
@@ -388,6 +398,7 @@
 
 static unsigned long get_wchan(struct task_struct *p)
 {
+#ifdef __i386__
 	unsigned long ebp, eip;
 	unsigned long stack_page;
 	int count = 0;
@@ -407,6 +418,7 @@
 			return eip;
 		ebp = *(unsigned long *) ebp;
 	} while (count++ < 16);
+#endif
 	return 0;
 }
 
@@ -438,7 +450,7 @@
 	}
 	wchan = get_wchan(*p);
 	for(i=0; i<32; ++i) {
-		switch((int) (*p)->sigaction[i].sa_handler) {
+		switch((unsigned long) (*p)->sigaction[i].sa_handler) {
 		case 1: sigignore |= bit; break;
 		case 0: break;
 		default: sigcatch |= bit;
diff -u --recursive --new-file v1.1.77/linux/fs/proc/net.c linux/fs/proc/net.c
--- v1.1.77/linux/fs/proc/net.c	Mon Jan  9 07:22:08 1995
+++ linux/fs/proc/net.c	Mon Jan  9 06:50:06 1995
@@ -170,6 +170,7 @@
 			return -ENOENT;
 		return 0;
 	}
+	iput(dir);
 	return -ENOENT;
 }
 
diff -u --recursive --new-file v1.1.77/linux/fs/sysv/Makefile linux/fs/sysv/Makefile
--- v1.1.77/linux/fs/sysv/Makefile	Mon Jan  9 07:22:08 1995
+++ linux/fs/sysv/Makefile	Mon Jan  9 09:23:59 1995
@@ -7,10 +7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_SYSV_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
 	$(CC) $(CFLAGS) -S $<
 .c.o:
diff -u --recursive --new-file v1.1.77/linux/fs/sysv/inode.c linux/fs/sysv/inode.c
--- v1.1.77/linux/fs/sysv/inode.c	Mon Jan  9 07:22:08 1995
+++ linux/fs/sysv/inode.c	Sat Jan  7 21:30:10 1995
@@ -334,7 +334,6 @@
 	sb->sv_sb_flc_blocks = &sbd->s_free[0];
 	sb->sv_sb_total_free_blocks = &sbd->s_tfree;
 	sb->sv_sb_time = &sbd->s_time;
-	sb->sv_sb_state = &sbd->s_state;
 	sb->sv_block_base = 0;
 	sb->sv_firstinodezone = 2;
 	sb->sv_firstdatazone = sbd->s_isize;
diff -u --recursive --new-file v1.1.77/linux/fs/umsdos/Makefile linux/fs/umsdos/Makefile
--- v1.1.77/linux/fs/umsdos/Makefile	Mon Jan  9 07:22:08 1995
+++ linux/fs/umsdos/Makefile	Mon Jan  9 09:24:10 1995
@@ -7,10 +7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_UMSDOS_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
 	$(CC) $(CFLAGS) -S $<
 .c.o:
diff -u --recursive --new-file v1.1.77/linux/fs/xiafs/Makefile linux/fs/xiafs/Makefile
--- v1.1.77/linux/fs/xiafs/Makefile	Mon Jan  9 07:22:08 1995
+++ linux/fs/xiafs/Makefile	Mon Jan  9 09:24:22 1995
@@ -7,10 +7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_XIA_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
 	$(CC) $(CFLAGS) -S $<
 .c.o:
diff -u --recursive --new-file v1.1.77/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
--- v1.1.77/linux/include/asm-alpha/processor.h	Mon Jan  9 07:22:09 1995
+++ linux/include/asm-alpha/processor.h	Mon Jan  9 08:17:07 1995
@@ -24,7 +24,7 @@
 struct thread_struct {
 	unsigned long ksp;
 	unsigned long usp;
-	unsigned long cr3;	/* ptbr */
+	unsigned long ptbr;
 	unsigned int pcc;
 	unsigned int asn;
 	unsigned long unique;
diff -u --recursive --new-file v1.1.77/linux/include/asm-i386/string.h linux/include/asm-i386/string.h
--- v1.1.77/linux/include/asm-i386/string.h	Mon Jan  9 07:22:09 1995
+++ linux/include/asm-i386/string.h	Mon Jan  9 06:33:23 1995
@@ -122,7 +122,7 @@
 return __res;
 }
 
-extern inline char * strchr(const char * s,char c)
+extern inline char * strchr(const char * s, int c)
 {
 register char * __res;
 __asm__ __volatile__(
@@ -140,7 +140,7 @@
 return __res;
 }
 
-extern inline char * strrchr(const char * s,char c)
+extern inline char * strrchr(const char * s, int c)
 {
 register char * __res;
 __asm__ __volatile__(
@@ -392,7 +392,7 @@
 		case 0: COMMON(""); return to;
 		case 1: COMMON("\n\tmovsb"); return to;
 		case 2: COMMON("\n\tmovsw"); return to;
-		case 3: COMMON("\n\tmovsw\n\tstosb"); return to;
+		case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
 	}
 #undef COMMON
 }
@@ -442,7 +442,7 @@
 return __res;
 }
 
-extern inline void * memchr(const void * cs,char c,size_t count)
+extern inline void * memchr(const void * cs,int c,size_t count)
 {
 register void * __res;
 if (!count)
@@ -459,7 +459,7 @@
 return __res;
 }
 
-extern inline void * __memset_generic(void * s,char c,size_t count)
+extern inline void * __memset_generic(void * s, char c,size_t count)
 {
 __asm__ __volatile__(
 	"cld\n\t"
@@ -533,7 +533,7 @@
 /*
  * find the first occurrence of byte 'c', or 1 past the area if none
  */
-extern inline void * memscan(void * addr, unsigned char c, size_t size)
+extern inline void * memscan(void * addr, int c, size_t size)
 {
 	if (!size)
 		return addr;
diff -u --recursive --new-file v1.1.77/linux/include/asm-sparc/head.h linux/include/asm-sparc/head.h
--- v1.1.77/linux/include/asm-sparc/head.h	Mon Jan  9 07:22:10 1995
+++ linux/include/asm-sparc/head.h	Mon Jan  9 06:48:24 1995
@@ -43,5 +43,19 @@
 #define TRAP_ENTRY_INTERRUPT_NMI(t_type, jmp_to) \
         mov t_type, %l3; b jmp_to; mov %psr, %l0; nop;
 
+/* Trap entry code in entry.S needs the offsets into task_struct
+ * to get at the thread_struct goodies during window craziness.
+ *
+ * NOTE: We need to keep these values under 0x3ff in order to do
+ *       efficient load/stores in the window fill/spill handlers.
+ *       See TRAP_WIN_CLEAN in entry.S for details.
+ */
+
+#define THREAD_UWINDOWS 0x3a8
+#define THREAD_WIM 0x3ac
+#define THREAD_W_SAVED 0x3b0
+#define THREAD_KSP 0x3b4
+#define THREAD_USP 0x3b8
+#define THREAD_REG_WINDOW 0x3c0
 
 #endif __SPARC_HEAD_H
diff -u --recursive --new-file v1.1.77/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h
--- v1.1.77/linux/include/asm-sparc/processor.h	Mon Jan  9 07:22:10 1995
+++ linux/include/asm-sparc/processor.h	Mon Jan  9 06:48:24 1995
@@ -25,16 +25,25 @@
  */
 #define IO_BITMAP_SIZE	32
 
+/* The first five entries here MUST be the first four. This allows me to
+ * do %lo(offset) loads and stores in entry.S. See TRAP_WIN_CLEAN to see
+ * why.
+ */
+
 struct thread_struct {
+	unsigned long uwindows;       /* how many user windows are in the set */
+	unsigned long wim;            /* user's window invalid mask */
+	unsigned long w_saved;        /* how many windows saved in reg_window[] */
 	unsigned long ksp;          /* kernel stack pointer */
 	unsigned long usp;          /* user's sp, throw reg windows here */
+	unsigned long psr;          /* save for condition codes */
+	unsigned long reg_window[16*24];
 	unsigned long cr3;          /* why changed from ptbr? */
 	unsigned int pcc;
 	unsigned int asn;
 	unsigned long unique;
 	unsigned long flags;
 	unsigned long res1, res2;
-	unsigned long psr;          /* save for condition codes */
 	unsigned long pc;           /* program counter */
 	unsigned long npc;          /* next program counter */
 
@@ -44,9 +53,7 @@
  * in nwindows.
  */
 	unsigned long globl_regs[8];  /* global regs need to be saved too */
-	unsigned long reg_window[16*24];
 	unsigned long yreg;
-	unsigned long uwindows;       /* how many user windows are in the set */
 	unsigned long float_regs[64]; /* V8 and below have 32, V9 has 64 */
 };
 
@@ -77,12 +84,29 @@
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
-	0, 0, \
+	0, 0, 0, 0, \
         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
 }
+
+/* The thread_frame is what needs to be set up in certain circumstances
+ * upon entry to a trap. It is also loaded sometimes during a window
+ * spill if things don't go right (bad user stack pointer). In reality
+ * it is not per-process per se, it just sits in the kernel stack while
+ * the current process is in a handler then it is basically forgotten
+ * about.
+ */
+
+struct thread_frame {
+  unsigned int thr_psr;
+  unsigned int thr_pc;
+  unsigned int thr_npc;
+  unsigned int thr_y;
+  unsigned int thr_globals[8];
+  unsigned int thr_outs[8];
+};
 
 /*
  * These are the "cli()" and "sti()" for software interrupts
diff -u --recursive --new-file v1.1.77/linux/include/linux/ioport.h linux/include/linux/ioport.h
--- v1.1.77/linux/include/linux/ioport.h	Mon Jan  9 07:22:10 1995
+++ linux/include/linux/ioport.h	Mon Jan  9 07:56:28 1995
@@ -19,7 +19,7 @@
 extern void reserve_setup(char *str, int *ints);
 extern int check_region(unsigned int from, unsigned int extent);
 extern void snarf_region(unsigned int from, unsigned int extent);
-extern void register_iomem(unsigned int from, unsigned int extent,char* name);
+extern void request_region(unsigned int from, unsigned int extent,const char *name);
 extern void release_region(unsigned int from, unsigned int extent);
 extern int get_ioport_list(char *);
 
diff -u --recursive --new-file v1.1.77/linux/include/linux/minix_fs.h linux/include/linux/minix_fs.h
--- v1.1.77/linux/include/linux/minix_fs.h	Mon Jan  9 07:22:10 1995
+++ linux/include/linux/minix_fs.h	Mon Jan  9 07:59:23 1995
@@ -32,13 +32,13 @@
  * Note the 8-bit gid and atime and ctime.
  */
 struct minix_inode {
-	u16 i_mode;
-	u16 i_uid;
-	u32 i_size;
-	u32 i_time;
-	u8  i_gid;
-	u8  i_nlinks;
-	u16 i_zone[9];
+	__u16 i_mode;
+	__u16 i_uid;
+	__u32 i_size;
+	__u32 i_time;
+	__u8  i_gid;
+	__u8  i_nlinks;
+	__u16 i_zone[9];
 };
 
 /*
@@ -48,34 +48,34 @@
  * now 16-bit. The inode is now 64 bytes instead of 32.
  */
 struct new_minix_inode {
-	u16 i_mode;
-	u16 i_nlinks;
-	u16 i_uid;
-	u16 i_gid;
-	u32 i_size;
-	u32 i_atime;
-	u32 i_mtime;
-	u32 i_ctime;
-	u32 i_zone[10];
+	__u16 i_mode;
+	__u16 i_nlinks;
+	__u16 i_uid;
+	__u16 i_gid;
+	__u32 i_size;
+	__u32 i_atime;
+	__u32 i_mtime;
+	__u32 i_ctime;
+	__u32 i_zone[10];
 };
 
 /*
  * minix super-block data on disk
  */
 struct minix_super_block {
-	u16 s_ninodes;
-	u16 s_nzones;
-	u16 s_imap_blocks;
-	u16 s_zmap_blocks;
-	u16 s_firstdatazone;
-	u16 s_log_zone_size;
-	u32 s_max_size;
-	u16 s_magic;
-	u16 s_state;
+	__u16 s_ninodes;
+	__u16 s_nzones;
+	__u16 s_imap_blocks;
+	__u16 s_zmap_blocks;
+	__u16 s_firstdatazone;
+	__u16 s_log_zone_size;
+	__u32 s_max_size;
+	__u16 s_magic;
+	__u16 s_state;
 };
 
 struct minix_dir_entry {
-	u16 inode;
+	__u16 inode;
 	char name[0];
 };
 
diff -u --recursive --new-file v1.1.77/linux/include/linux/minix_fs_i.h linux/include/linux/minix_fs_i.h
--- v1.1.77/linux/include/linux/minix_fs_i.h	Mon Jan  9 07:22:10 1995
+++ linux/include/linux/minix_fs_i.h	Mon Jan  9 07:58:38 1995
@@ -5,7 +5,7 @@
  * minix fs inode data in memory
  */
 struct minix_inode_info {
-	u16 i_data[16];
+	__u16 i_data[16];
 };
 
 #endif
diff -u --recursive --new-file v1.1.77/linux/include/linux/pci.h linux/include/linux/pci.h
--- v1.1.77/linux/include/linux/pci.h	Mon Jan  9 07:22:11 1995
+++ linux/include/linux/pci.h	Mon Jan  9 07:04:05 1995
@@ -233,8 +233,9 @@
 #define PCI_DEVICE_ID_ATI_M32		0x4158
 #define PCI_DEVICE_ID_ATI_M64		0x4758
 
-#define PCI_VENDOR_ID_DIAMOND		0x100e
-#define PCI_DEVICE_ID_DIAMOND_VIPER	0x9001
+#define PCI_VENDOR_ID_WEITEK		0x100e
+#define PCI_DEVICE_ID_WEITEK_P9000	0x9001
+#define PCI_DEVICE_ID_WEITEK_P9100	0x9100
 
 #define PCI_VENDOR_ID_CIRRUS		0x1013
 #define PCI_DEVICE_ID_CIRRUS_5434	0x00A4
@@ -251,13 +252,16 @@
 #define PCI_VENDOR_ID_TSENG		0x100c
 #define PCI_DEVICE_ID_TSENG_W32P	0x3205
 
+#define PCI_VENDOR_ID_CMD		0x1095
+#define PCI_DEVICE_ID_CMD_640		0x0640
+
 struct pci_vendor_type {
 	unsigned short vendor_id;
 	char *vendor_name;
 };
 
 
-#define PCI_VENDOR_NUM 16
+#define PCI_VENDOR_NUM 17
 #define PCI_VENDOR_TYPE { \
 	{PCI_VENDOR_ID_NCR,		"NCR"}, \
 	{PCI_VENDOR_ID_ADAPTEC,		"Adaptec"}, \
@@ -269,13 +273,14 @@
 	{PCI_VENDOR_ID_INTEL,		"Intel"}, \
 	{PCI_VENDOR_ID_SMC,		"SMC"}, \
 	{PCI_VENDOR_ID_ATI,		"ATI"}, \
-	{PCI_VENDOR_ID_DIAMOND,		"Diamond"}, \
+	{PCI_VENDOR_ID_WEITEK,		"Weitek"}, \
 	{PCI_VENDOR_ID_CIRRUS,		"Cirrus Logic"}, \
 	{PCI_VENDOR_ID_BUSLOGIC,	"Bus Logic"}, \
 	{PCI_VENDOR_ID_N9,		"Number #9"}, \
 	{PCI_VENDOR_ID_ALI,		"ALI"}, \
 	{PCI_VENDOR_ID_TSENG,		"Tseng'Lab"}, \
-	{0,				"Unknown vendor"} \
+	{PCI_VENDOR_ID_CMD,		"CMD"}, \
+	{0,				""} \
 }
 
 struct pci_device_type {
@@ -284,7 +289,7 @@
 	char *device_name;
 };
 
-#define PCI_DEVICE_NUM 31
+#define PCI_DEVICE_NUM 33
 #define PCI_DEVICE_TYPE { \
 	{PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C810,	"53c810"}, \
 	{PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C815,	"53c815"}, \
@@ -311,12 +316,14 @@
 	{PCI_VENDOR_ID_SMC,	PCI_DEVICE_ID_SMC_37C665,	"FDC 37C665"}, \
 	{PCI_VENDOR_ID_ATI,	PCI_DEVICE_ID_ATI_M32,		"Mach 32"}, \
 	{PCI_VENDOR_ID_ATI,	PCI_DEVICE_ID_ATI_M64,		"Mach 64"}, \
-	{PCI_VENDOR_ID_DIAMOND,	PCI_DEVICE_ID_DIAMOND_VIPER,	"Viper"}, \
+	{PCI_VENDOR_ID_WEITEK,	PCI_DEVICE_ID_WEITEK_P9000,	"P9000"}, \
+	{PCI_VENDOR_ID_WEITEK,	PCI_DEVICE_ID_WEITEK_P9100,	"P9100"}, \
 	{PCI_VENDOR_ID_CIRRUS,	PCI_DEVICE_ID_CIRRUS_5434,	"GD 5434"}, \
 	{PCI_VENDOR_ID_BUSLOGIC,PCI_DEVICE_ID_BUSLOGIC_946C,	"946C"}, \
 	{PCI_VENDOR_ID_N9,	PCI_DEVICE_ID_N9_I128,		"Imagine 128"}, \
 	{PCI_VENDOR_ID_ALI,	PCI_DEVICE_ID_ALI_M1435,	"M1435"}, \
-	{PCI_VENDOR_ID_ALI,	PCI_DEVICE_ID_TSENG_W32P,	"ET4000W32P"}, \
+	{PCI_VENDOR_ID_TSENG,	PCI_DEVICE_ID_TSENG_W32P,	"ET4000W32P"}, \
+	{PCI_VENDOR_ID_CMD,	PCI_DEVICE_ID_CMD_640,		"640A"}, \
 	{0,0,"UNKNOWN DEVICE.PLEASE FIND OUT AND MAIL POTTER@CAO-VLSI.IBP.FR"} \
 }
 
diff -u --recursive --new-file v1.1.77/linux/include/linux/string.h linux/include/linux/string.h
--- v1.1.77/linux/include/linux/string.h	Mon Jan  9 07:22:11 1995
+++ linux/include/linux/string.h	Sat Jan  7 21:41:23 1995
@@ -16,7 +16,7 @@
 extern char * strncpy(char *,const char *,size_t);
 extern char * strcat(char *, const char *);
 extern char * strncat(char *, const char *, size_t);
-extern char * strchr(const char *,char);
+extern char * strchr(const char *,int);
 extern char * strpbrk(const char *,const char *);
 extern char * strtok(char *,const char *);
 extern char * strstr(const char *,const char *);
@@ -25,10 +25,10 @@
 extern int strcmp(const char *,const char *);
 extern int strncmp(const char *,const char *,size_t);
 
-extern void * memset(void *,char,size_t);
+extern void * memset(void *,int,size_t);
 extern void * memcpy(void *,const void *,size_t);
 extern void * memmove(void *,const void *,size_t);
-extern void * memscan(void *, unsigned char, size_t);
+extern void * memscan(void *,int,size_t);
 extern int memcmp(const void *,const void *,size_t);
 
 /*
diff -u --recursive --new-file v1.1.77/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.1.77/linux/kernel/ksyms.c	Mon Jan  9 07:22:11 1995
+++ linux/kernel/ksyms.c	Mon Jan  9 07:56:28 1995
@@ -247,7 +247,7 @@
 	X(kfree_skb),
 	X(dev_kfree_skb),
 	X(snarf_region),
-	X(register_iomem),
+	X(request_region),
 	X(release_region),
 	X(netif_rx),
 	X(dev_rint),
diff -u --recursive --new-file v1.1.77/linux/kernel/signal.c linux/kernel/signal.c
--- v1.1.77/linux/kernel/signal.c	Mon Jan  9 07:22:12 1995
+++ linux/kernel/signal.c	Mon Jan  9 09:28:08 1995
@@ -117,9 +117,11 @@
 		return -EINVAL;
 	if (signum==SIGKILL || signum==SIGSTOP)
 		return -EINVAL;
-	err = verify_area(VERIFY_READ, handler, 1);
-	if (err)
-		return err;
+	if (handler != SIG_DFL && handler != SIG_IGN) {
+		err = verify_area(VERIFY_READ, handler, 1);
+		if (err)
+			return err;
+	}
 	tmp.sa_handler = handler;
 	tmp.sa_mask = 0;
 	tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
@@ -151,9 +153,11 @@
 			new_sa.sa_mask |= _S(signum);
 			new_sa.sa_mask &= _BLOCKABLE;
 		}
-		err = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
-		if (err)
-			return err;
+		if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) {
+			err = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
+			if (err)
+				return err;
+		}
 	}
 	if (oldaction) {
 		int err = verify_area(VERIFY_WRITE, oldaction, sizeof(*oldaction));
diff -u --recursive --new-file v1.1.77/linux/mm/kmalloc.c linux/mm/kmalloc.c
--- v1.1.77/linux/mm/kmalloc.c	Wed Nov 30 22:03:47 1994
+++ linux/mm/kmalloc.c	Mon Jan  9 08:17:07 1995
@@ -137,8 +137,8 @@
         AREASIZE(order)) 
         {
         printk ("Cannot use %d bytes out of %d in order = %d block mallocs\n",
-                NBLOCKS (order) * BLOCKSIZE(order) + 
-                        sizeof (struct page_descriptor),
+                (int) (NBLOCKS (order) * BLOCKSIZE(order) + 
+                        sizeof (struct page_descriptor)),
                 (int) AREASIZE(order),
                 BLOCKSIZE (order));
         panic ("This only happens if someone messes with kmalloc");
@@ -185,7 +185,7 @@
 order = get_order (size);
 if (order < 0)
     {
-    printk ("kmalloc of too large a block (%d bytes).\n",size);
+    printk ("kmalloc of too large a block (%d bytes).\n",(int) size);
     return (NULL);
     }
 
@@ -288,7 +288,7 @@
         "the author of this kmalloc: wolff@dutecai.et.tudelft.nl.\n"
         "(Executive summary: This can't happen)\n", 
                 MAX_GET_FREE_PAGE_TRIES,
-                size);
+                (int) size);
 return NULL;
 }
 
diff -u --recursive --new-file v1.1.77/linux/net/inet/af_inet.c linux/net/inet/af_inet.c
--- v1.1.77/linux/net/inet/af_inet.c	Mon Jan  9 07:22:12 1995
+++ linux/net/inet/af_inet.c	Sat Jan  7 17:15:45 1995
@@ -738,6 +738,10 @@
 
 	/* Start closing the connection.  This may take a while. */
 
+#ifdef CONFIG_IP_MULTICAST
+	/* Applications forget to leave groups before exiting */
+	ip_mc_drop_socket(sk);
+#endif
 	/*
 	 * If linger is set, we don't return until the close
 	 * is complete.  Other wise we return immediately. The
diff -u --recursive --new-file v1.1.77/linux/net/inet/dev_mcast.c linux/net/inet/dev_mcast.c
--- v1.1.77/linux/net/inet/dev_mcast.c	Mon Jan  9 07:22:13 1995
+++ linux/net/inet/dev_mcast.c	Sat Jan  7 17:15:45 1995
@@ -109,7 +109,7 @@
 		if(memcmp((*dmi)->dmi_addr,addr,(*dmi)->dmi_addrlen)==0 && alen==(*dmi)->dmi_addrlen)
 		{
 			struct dev_mc_list *tmp= *dmi;
-			if((*dmi)->dmi_users-- && !all)
+			if(--(*dmi)->dmi_users && !all)
 				return;
 			*dmi=(*dmi)->next;
 			dev->mc_count--;
diff -u --recursive --new-file v1.1.77/linux/net/inet/ip.c linux/net/inet/ip.c
--- v1.1.77/linux/net/inet/ip.c	Mon Jan  9 07:22:13 1995
+++ linux/net/inet/ip.c	Sat Jan  7 17:15:45 1995
@@ -128,12 +128,6 @@
 struct ip_mib ip_statistics={0,64,};	/* Forwarding=No, Default TTL=64 */
 #endif
 
-#ifdef CONFIG_IP_MULTICAST
-
-struct ip_mc_list *ip_mc_head=NULL;
-
-#endif
-
 /*
  *	Handle the issuing of an ioctl() request
  *	for the ip device. This is scheduled to
@@ -2020,26 +2014,34 @@
 	struct ip_mc_list *im;
 	unsigned long flags;
 	int len=0;
+	struct device *dev;
 	
-	
-	len=sprintf(buffer,"Device    : Multicast\n");  
+	len=sprintf(buffer,"Device    : Count\tGroup    Users Timer\n");  
 	save_flags(flags);
 	cli();
 	
-	im=ip_mc_head;
-	
-	while(im!=NULL)
+	for(dev = dev_base; dev; dev = dev->next)
 	{
-		len+=sprintf(buffer+len,"%-10s: %08lX\n", im->interface->name, im->multiaddr);
-		pos=begin+len;
-		if(pos<offset)
-		{
-			len=0;
-			begin=pos;
-		}
-		if(pos>offset+length)
-			break;
-		im=im->next;
+                if((dev->flags&IFF_UP)&&(dev->flags&IFF_MULTICAST))
+                {
+                        len+=sprintf(buffer+len,"%-10s: %5d\n",
+					dev->name, dev->mc_count);
+                        for(im = dev->ip_mc_list; im; im = im->next)
+                        {
+                                len+=sprintf(buffer+len,
+					"\t\t\t%08lX %5d %d:%08lX\n",
+                                        im->multiaddr, im->users,
+					im->tm_running, im->timer.expires);
+                                pos=begin+len;
+                                if(pos<offset)
+                                {
+                                        len=0;
+                                        begin=pos;
+                                }
+                                if(pos>offset+length)
+                                        break;
+                        }
+                }
 	}
 	restore_flags(flags);
 	*start=buffer+(offset-begin);
diff -u --recursive --new-file v1.1.77/linux/net/inet/tcp.c linux/net/inet/tcp.c
--- v1.1.77/linux/net/inet/tcp.c	Mon Jan  9 07:22:13 1995
+++ linux/net/inet/tcp.c	Sat Jan  7 17:26:16 1995
@@ -640,7 +640,7 @@
 			 * this reset_timer() call is a hack, this is not
 			 * how KEEPOPEN is supposed to work.
 			 */
-			reset_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
+			reset_xmit_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
 
 			/* Send something to keep the connection open. */
 			if (sk->prot->write_wakeup)
