diff -u --recursive --new-file v1.1.92/linux/Makefile linux/Makefile
--- v1.1.92/linux/Makefile	Fri Feb 17 11:20:10 1995
+++ linux/Makefile	Mon Feb 20 08:57:17 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 92
+SUBLEVEL = 93
 
 ARCH = i386
 
diff -u --recursive --new-file v1.1.92/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c
--- v1.1.92/linux/arch/i386/boot/compressed/misc.c	Thu Dec 29 19:58:41 1994
+++ linux/arch/i386/boot/compressed/misc.c	Sun Feb 19 11:15:16 1995
@@ -107,7 +107,7 @@
 	}
 	if (free_mem_ptr < 0x90000)
 	return p;
-	puts("memory is tight...");
+	puts("large kernel, low 1M tight...");
 	free_mem_ptr = (long)input_data;
 	}
 }
diff -u --recursive --new-file v1.1.92/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v1.1.92/linux/arch/i386/kernel/bios32.c	Thu Jan 26 07:49:02 1995
+++ linux/arch/i386/kernel/bios32.c	Fri Feb 17 18:18:46 1995
@@ -765,8 +765,12 @@
 		}
 		printk ("bios32_init : BIOS32 Service Directory structure at 0x%p\n", check);
 		if (!bios32_entry) {
-			bios32_indirect.address = bios32_entry = check->fields.entry;
-			printk ("bios32_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
+			if (check->fields.entry >= 0x100000) {
+				printk("bios32_init: entry in high memory, unable to access\n");
+			} else {
+				bios32_indirect.address = bios32_entry = check->fields.entry;
+				printk ("bios32_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
+			}
 		} else {
 			printk ("bios32_init : multiple entries, mail drew@colorado.edu\n");
 			/*
diff -u --recursive --new-file v1.1.92/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v1.1.92/linux/arch/sparc/kernel/entry.S	Sun Feb  5 19:31:51 1995
+++ linux/arch/sparc/kernel/entry.S	Mon Feb 20 08:59:51 1995
@@ -10,7 +10,9 @@
 
 #include <asm/head.h>
 #include <asm/asi.h>
+#include <asm/psr.h>
 #include <asm/cprefix.h>
+#include <asm/vaddrs.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
@@ -179,12 +181,15 @@
 	andcc	%l0, 0x40, %g0; \
 	bz	1f; \
 	andcc	%l4, %l5, %g0; \
-	bz,a	0f; \
 	sethi	%hi( C_LABEL(eintstack) ), %l7; \
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7; \
+	bz	0f; \
+	nop; \
 	TRAP_WIN_CLEAN \
 	sethi	%hi( C_LABEL(eintstack) ), %l7; \
-0:	cmp	%fp, %l7; \
-	bge,a	3f; \
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7; \
+0:	subcc	%fp, %l7, %g0; \
+	bg,a	3f; \
 	sub	%l7, 0xb0, %sp; \
 	b	3f; \
 	sub	%fp, 0xb0, %sp; \
@@ -204,12 +209,13 @@
 5:	st	%l5, [%l6 + THREAD_UWINDOWS]; \
 	bz,a	2f; \
 	sethi	%hi( C_LABEL(eintstack) ), %l7; \
-	TRAP_WIN_CLEAN; \
+	TRAP_WIN_CLEAN \
 	sethi	%hi( C_LABEL(eintstack) ), %l7; \
 2: \
 	sub	%l7, 0xb0, %sp; \
 3:
 
+
 	.text
 	.align 4
 
@@ -240,15 +246,257 @@
 		rett %l2
 #endif /* bogon */
 	
+	.align 4
 	.globl sparc_timer
 sparc_timer:
-	ENTER_IRQ
-	or	%g0, 0x10, %o0	
-	call	C_LABEL(do_IRQ)
+	sethi	%hi(TIMER_VADDR), %l4
+	or	%l4, %lo(TIMER_VADDR), %l4	! read the limit register
+	ld	[%l4 + 0xc], %l4		! to clear the interrupt
+	rd	%wim, %l4
+	or	%g0, 0x1, %l5
+	sll	%l5, %l0, %l5
+	andcc	%l0, 0x40, %g0
+	bz	st1
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	andcc	%l4, %l5, %g0
+	bz	st0
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+	TRAP_WIN_CLEAN
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+st0:	subcc	%fp, %l7, %g0
+	bg,a	st3
+	sub	%l7, 0xb0, %sp
+	b	st3
+	sub	%fp, 0xb0, %sp
+st1: 	sethi	%hi( C_LABEL(current) ), %l6
+	ld	[%l6 + %lo( C_LABEL(current) )], %l6
+	ld	[%l6 + THREAD_WIM], %l5
+	and	%l0, 0x1f, %l7
+	cmp	%l5, %l7
+	ble,a	st4
+	sethi	%hi( C_LABEL(nwindowsm1) ), %l4
+	sub	%l5, %l7, %l7
+	b	st5
+	sub	%l7, 0x1, %l5
+st4:	ld	[%l4 + %lo( C_LABEL(nwindowsm1) )], %l4
+	sub	%l4, %l7, %l4
+	add	%l5, %l4, %l5
+st5:	st	%l5, [%l6 + THREAD_UWINDOWS]
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	bz,a	st2
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+	TRAP_WIN_CLEAN
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+st2:	sub	%l7, 0xb0, %sp
+
+st3:	std	%g2, [%sp + 96 + 24]
+	or	%g0, %g1, %l7
+	rd	%y, %l6
+	std	%g4, [%sp + 96 + 32]
+	andn	%l0, PSR_PIL, %l4
+	sll	%l3, 0x8, %l5
+	std	%g6, [%sp + 96 + 40]
+	or	%l5, %l4, %l4
+
+	wr	%l4, 0x0, %psr
+	wr	%l4, PSR_ET, %psr
+
+	std	%l0, [%sp + 96 + 0]
+	std	%l2, [%sp + 96 + 8]
+	st	%fp, [%sp + 96 + 16]
+	
+	or	%g0, 14, %o0	
+	or	%g0, %g0, %o1
+	call	C_LABEL(do_sparc_timer)
+	nop
+
+	or	%g0, %l7, %g1
+	wr	%l6, 0x0, %y
+	ldd	[%sp + 96 + 24], %g2
+	ldd	[%sp + 96 + 32], %g4
+	ldd	[%sp + 96 + 40], %g6
+	wr	%l0, 0x0, %psr
+	nop
+	nop
+	nop
+
+	and	%l0, 31, %l5
+	sethi	%hi(lnx_winmask), %l6
+	or	%l6, %lo(lnx_winmask), %l6
+	ldub	[%l6 + %l5], %l5
+	andcc	%l0, PSR_PS, %g0
+	bnz	1f
+	rd	%wim, %l4
+
+1:	andcc	%l5, %l4, %g0
+	bnz	2f
+	wr	%l0, 0x0, %psr
+	nop
+	nop
+	nop
+
+	jmp	%l1
+	rett	%l2
+
+2:	wr	%g0, 0x0, %wim
+	nop
+	nop
+	nop
+
+	restore
+	restore	%g0, 0x1, %l1
+	rd	%psr, %l0
+	and	%l0, 31, %l0
+	sll	%l1, %l0, %l1
+	wr	%l1, 0x0, %wim
+	sethi	%hi( C_LABEL(current) ), %l1
+	ld	[%l1 + %lo( C_LABEL(current) ) ], %l1
+	st	%l0, [%l1 + THREAD_WIM]
+	save	%g0, %g0, %g0
+	
+	ldd	[%sp], %l0
+	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
+	
+	jmp	%l1
+	rett	%l2
+
+
+/* For now all IRQ's not registered get sent here so I can see
+ * what is poking the chip.
+ */
+
+	.align 4
+	.globl stray_irq_entry
+stray_irq_entry:
+	rd	%wim, %l4
+	or	%g0, 0x1, %l5
+	sll	%l5, %l0, %l5
+	andcc	%l0, 0x40, %g0
+	bz	tt1
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	andcc	%l4, %l5, %g0
+	bz	tt0
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+	TRAP_WIN_CLEAN
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+tt0:	subcc	%fp, %l7, %g0
+	bg,a	tt3
+	sub	%l7, 0xb0, %sp
+	b	tt3
+	sub	%fp, 0xb0, %sp
+tt1: 	sethi	%hi( C_LABEL(current) ), %l6
+	ld	[%l6 + %lo( C_LABEL(current) )], %l6
+	ld	[%l6 + THREAD_WIM], %l5
+	and	%l0, 0x1f, %l7
+	cmp	%l5, %l7
+	ble,a	tt4
+	sethi	%hi( C_LABEL(nwindowsm1) ), %l4
+	sub	%l5, %l7, %l7
+	b	tt5
+	sub	%l7, 0x1, %l5
+tt4:	ld	[%l4 + %lo( C_LABEL(nwindowsm1) )], %l4
+	sub	%l4, %l7, %l4
+	add	%l5, %l4, %l5
+tt5:	st	%l5, [%l6 + THREAD_UWINDOWS]
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	bz,a	tt2
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+	TRAP_WIN_CLEAN
+	sethi	%hi( C_LABEL(eintstack) ), %l7
+	or	%l7, %lo( C_LABEL(eintstack) ), %l7
+tt2:	sub	%l7, 0xb0, %sp
+
+tt3:	std	%g2, [%sp + 96 + 24]
+	or	%g0, %g1, %l7
+	rd	%y, %l6
+	std	%g4, [%sp + 96 + 32]
+	andn	%l0, PSR_PIL, %l4
+	sll	%l3, 0x8, %l5
+	std	%g6, [%sp + 96 + 40]
+	or	%l5, %l4, %l4
+
+	wr	%l4, 0x0, %psr
+	wr	%l4, PSR_ET, %psr
+
+	std	%l0, [%sp + 96 + 0]
+	std	%l2, [%sp + 96 + 8]
+	st	%fp, [%sp + 96 + 16]
+	
+	or	%g0, %l3, %o0	
 	or	%g0, %g0, %o1
+	call	C_LABEL(unexpected_irq)
+	nop
+
+	or	%g0, %l7, %g1
+	wr	%l6, 0x0, %y
+	ldd	[%sp + 96 + 24], %g2
+	ldd	[%sp + 96 + 32], %g4
+	ldd	[%sp + 96 + 40], %g6
+	wr	%l0, 0x0, %psr
+	nop
+	nop
+	nop
+
+	and	%l0, 31, %l5
+	sethi	%hi(lnx_winmask), %l6
+	or	%l6, %lo(lnx_winmask), %l6
+	ldub	[%l6 + %l5], %l5
+	andcc	%l0, PSR_PS, %g0
+	bnz	1f
+	rd	%wim, %l4
+
+1:	andcc	%l5, %l4, %g0
+	bnz	2f
+	wr	%l0, 0x0, %psr
+	nop
+	nop
+	nop
+
 	jmp	%l1
 	rett	%l2
-	nop	
+
+2:	wr	%g0, 0x0, %wim
+	nop
+	nop
+	nop
+
+	restore
+	restore	%g0, 0x1, %l1
+	rd	%psr, %l0
+	and	%l0, 31, %l0
+	sll	%l1, %l0, %l1
+	wr	%l1, 0x0, %wim
+	sethi	%hi( C_LABEL(current) ), %l1
+	ld	[%l1 + %lo( C_LABEL(current) ) ], %l1
+	st	%l0, [%l1 + THREAD_WIM]
+	save	%g0, %g0, %g0
+	
+	ldd	[%sp], %l0
+	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
+	
+	jmp	%l1
+	rett	%l2
+
+
 
 /* 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.
@@ -529,7 +777,7 @@
 
 		.data
 		.align 4
-lnx_winmask:	.byte	2, 4, 8, 16, 32, 64, 128,1  ! lnx_winmask[0..7]
+lnx_winmask:	.byte	2, 4, 8, 16, 32, 64, 128, 1  ! lnx_winmask[0..7]
 
 	
 		.align 4
diff -u --recursive --new-file v1.1.92/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
--- v1.1.92/linux/arch/sparc/kernel/head.S	Sun Feb  5 19:31:51 1995
+++ linux/arch/sparc/kernel/head.S	Mon Feb 20 08:59:51 1995
@@ -263,7 +263,7 @@
         TRAP_ENTRY_INTERRUPT(11)            /* Interrupt Level 11 */
         TRAP_ENTRY_INTERRUPT(12)            /* Interrupt Level 12 */
         TRAP_ENTRY_INTERRUPT(13)            /* Interrupt Level 13 */
-        TRAP_ENTRY(0x27, sparc_timer)       /* Interrupt Level 14 */
+        TRAP_ENTRY_TIMER                    /* Interrupt Level 14 */
         TRAP_ENTRY_INTERRUPT_NMI(15, linux_trap_nmi) /* Level 15 (nmi) */
 
 	TRAP_ENTRY(0x20, my_trap_handler)   /* General Register Access Error */
@@ -370,7 +370,7 @@
 	TRAP_ENTRY(0x85, my_trap_handler)   /* Software Trap                 */
 	TRAP_ENTRY(0x86, my_trap_handler)   /* Fix Unaligned Access Trap XXX */
 	TRAP_ENTRY(0x87, my_trap_handler)   /* Integer Overflow Trap XXX     */
-	TRAP_ENTRY(0x88, my_trap_handler)   /* Software Trap                 */
+	TRAP_ENTRY(0x88, my_trap_handler)   /* Slowaris System Call          */
 	TRAP_ENTRY(0x89, my_trap_handler)   /* NetBSD System Call            */
 	TRAP_ENTRY(0x8a, my_trap_handler)   /* Software Trap                 */
 	TRAP_ENTRY(0x8b, my_trap_handler)   /* Software Trap                 */
@@ -725,10 +725,7 @@
 
 		sta	%l1, [%l0] ASI_PTE
 	
-		or	%g0, INTS_ENAB, %l1
-		nop
-		nop
-
+		or	%g0, 0x1, %l1
 		stb	%l1, [%l0]
 	
 
diff -u --recursive --new-file v1.1.92/linux/arch/sparc/kernel/ioport.c linux/arch/sparc/kernel/ioport.c
--- v1.1.92/linux/arch/sparc/kernel/ioport.c	Thu Feb  9 10:18:49 1995
+++ linux/arch/sparc/kernel/ioport.c	Mon Feb 20 08:59:51 1995
@@ -1,6 +1,6 @@
 /* ioport.c:  I/O access on the Sparc. Work in progress.. Most of the things
  *            in this file are for the sole purpose of getting the kernel
- *	      through the compiler. :-)
+ *            through the compiler. :-)
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  */
diff -u --recursive --new-file v1.1.92/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- v1.1.92/linux/arch/sparc/kernel/irq.c	Sun Feb  5 19:31:51 1995
+++ linux/arch/sparc/kernel/irq.c	Mon Feb 20 08:59:52 1995
@@ -30,6 +30,11 @@
 #include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/psr.h>
+#include <asm/vaddrs.h>
+#include <asm/clock.h>
+#include <asm/openprom.h>
+
+#define DEBUG_IRQ
 
 void disable_irq(unsigned int irq_nr)
 {
@@ -43,7 +48,7 @@
    * have to do here is frob the bits.
    */
 
-  int_reg = (char *) IRQ_ENA_ADR;
+  int_reg = (unsigned char *) IRQ_ENA_ADR;
 
   switch(irq_nr)
     {
@@ -78,7 +83,7 @@
 void enable_irq(unsigned int irq_nr)
 {
   unsigned long flags;
-  unsigned int *int_reg;
+  unsigned char *int_reg;
   
   save_flags(flags);
   cli();
@@ -87,8 +92,12 @@
    * have to do here is frob the bits.
    */
 
-  int_reg = (unsigned int *) IRQ_ENA_ADR;
+  int_reg = (unsigned char *) IRQ_ENA_ADR;
   
+#ifdef DEBUG_IRQ
+  printk(" --- Enabling IRQ level %d ---\n", irq_nr);
+#endif
+
   switch(irq_nr)
     {
     case 1:
@@ -116,6 +125,7 @@
     };
 
   restore_flags(flags);
+
   return;
 }
 
@@ -163,7 +173,7 @@
         unsigned long flags;
 
         if (irq > 14) {  /* 14 irq levels on the sparc */
-                printk("Trying to free IRQ%d\n", irq);
+                printk("Trying to free IRQ %d\n", irq);
                 return;
         }
         if (!action->handler) {
@@ -188,7 +198,7 @@
 }
 #endif
 
-static void unexpected_irq(int irq, struct pt_regs * regs)
+void unexpected_irq(int irq, struct pt_regs * regs)
 {
         int i;
 
@@ -230,6 +240,28 @@
 }
 
 /*
+ * Since we need to special things to clear up the clock chip around
+ * the do_timer() call we have a special version of do_IRQ for the
+ * level 14 interrupt which does these things.
+ */
+
+asmlinkage void do_sparc_timer(int irq, struct pt_regs * regs)
+{
+  struct irqaction *action = irq + irq_action;
+  register volatile int clear;
+
+  kstat.interrupts[irq]++;
+
+  /* I do the following already in the entry code, better safe than
+   * sorry for now. Reading the limit register clears the interrupt.
+   */
+  clear = TIMER_STRUCT->timer_limit14;
+
+  action->handler(irq, regs);
+  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.
@@ -241,6 +273,8 @@
   return;
 }
 
+extern int first_descent;
+extern void probe_clock(int);
 		
 int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
 	unsigned long irqflags, const char * devname)
@@ -252,7 +286,10 @@
     return -EINVAL;
 
   if(irq == 0)  /* sched_init() requesting the timer IRQ */
-    irq = 14;
+    {
+      irq = 14;
+      probe_clock(first_descent);
+    }
 
   action = irq + irq_action;
 
@@ -263,6 +300,7 @@
     return -EINVAL;
 
   save_flags(flags);
+
   cli();
 
   action->handler = handler;
@@ -273,6 +311,7 @@
   enable_irq(irq);
 
   restore_flags(flags);
+
   return 0;
 }
 
diff -u --recursive --new-file v1.1.92/linux/arch/sparc/kernel/probe.c linux/arch/sparc/kernel/probe.c
--- v1.1.92/linux/arch/sparc/kernel/probe.c	Sun Feb  5 19:31:51 1995
+++ linux/arch/sparc/kernel/probe.c	Mon Feb 20 08:59:52 1995
@@ -23,6 +23,8 @@
 extern char* get_str_from_prom(int node, char* name, char* value);
 extern unsigned int* get_int_from_prom(int node, char* name, unsigned int *value);
 
+int first_descent;
+
 /* Cpu-type information and manufacturer strings */
 
 
@@ -275,13 +277,12 @@
 
   printk("%s\n", node_str);
   printk("At OBIO address: 0x%x Virtual address: 0x%x\n",
-	 (unsigned int) 0xf3000000, (unsigned int) TIMER_STRUCT);
+	 (unsigned int) TIMER_PHYSADDR, (unsigned int) TIMER_STRUCT);
 
-  mapioaddr((unsigned long) 0xf3000000,
+  mapioaddr((unsigned long) TIMER_PHYSADDR,
 	    (unsigned long) TIMER_STRUCT);
 
-  TIMER_STRUCT->timer_limit14=(((10000) << 10) | 0x80000000);
-  TIMER_STRUCT->timer_limit10=(((10000) << 10) | 0x80000000);
+  TIMER_STRUCT->timer_limit14=(((1000000/HZ) << 10) | 0x80000000);
 
   return;
 }
@@ -390,7 +391,7 @@
 void
 probe_devices(void)
 {
-  register int nd, first_descent;
+  register int nd;
   register char* str;
 
   nd = prom_node_root;
@@ -427,7 +428,6 @@
   probe_cpu();
   probe_vac();
   probe_mmu();
-  probe_clock(first_descent);
 
 /*
   printk("PROM Root Child Node: 0x%x Name: %s \n", nd,
diff -u --recursive --new-file v1.1.92/linux/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c
--- v1.1.92/linux/arch/sparc/kernel/setup.c	Sun Feb  5 19:31:51 1995
+++ linux/arch/sparc/kernel/setup.c	Mon Feb 20 08:59:52 1995
@@ -92,8 +92,6 @@
 	printk("calling probe_devices...\n");
 	probe_devices();  /* cpu/fpu, mmu probes */
 
-	swpipl(13);
-
 	*memory_start_p = (((unsigned long) &end));
 }
 
diff -u --recursive --new-file v1.1.92/linux/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c
--- v1.1.92/linux/arch/sparc/mm/init.c	Thu Feb  9 10:18:50 1995
+++ linux/arch/sparc/mm/init.c	Mon Feb 20 08:59:52 1995
@@ -156,7 +156,7 @@
 	 */
 
 	/* Make the kernel text unwritable and cacheable, the prom
-	 * loaded out text as writable, only sneaky sunos kernels need
+	 * loaded our text as writable, only sneaky sunos kernels need
 	 * self-modifying code.
 	 */
 
diff -u --recursive --new-file v1.1.92/linux/drivers/block/README.ide linux/drivers/block/README.ide
--- v1.1.92/linux/drivers/block/README.ide	Wed Feb  1 09:23:04 1995
+++ linux/drivers/block/README.ide	Mon Feb 20 09:31:06 1995
@@ -1,4 +1,4 @@
-README.ide -- Information regarding ide.c and ide-cd.c
+README.ide -- Information regarding ide.c and ide-cd.c (IDE driver in 1.1.93)
 ================================================================================
 Supported by:  mlord@bnr.ca           -- disks, interfaces, probing
                snyder@fnald0.fnal.gov -- cdroms, ATAPI, audio
@@ -12,13 +12,13 @@
 	- support for reading IDE ATAPI cdrom drives (NEC, MITSUMI, VERSA, SONY)
 	- support for audio functions on FX400,NEC-260 cdrom drives (others?)
 	- auto-detection of interfaces, drives, IRQs, and disk geometries
+	  -- "single" drives should be jumpered as "master", not "slave"
 	- support for BIOSs which report "more than 16 heads" on disk drives
 	- uses LBA (slightly faster) on disk drives which support it
 	- support for lots of fancy (E)IDE drive functions with hdparm utility
 	- optional (compile time) support for 32-bit VLB data transfers
 	- support for IDE multiple (block) mode (same as hd.c)
 	- support for interrupt unmasking during I/O (better than hd.c)
-	- compile flag for auto detection/use of multiple mode setting from BIOS
 	- improved handshaking and error detection/recovery
 	- can co-exist with hd.c to control only the secondary interface
 
@@ -65,6 +65,11 @@
 or
 	hdc=768,16,32
 	hdc=noprobe
+
+Note that when only one IDE device is attached to an interface,
+it must be jumpered as "single" or "master", *not* "slave".
+Many folks have had "trouble" with cdroms because of this requirement
+of the ATA (IDE) standard.
 
 Courtesy of Scott Snyder, the driver now supports ATAPI cdrom drives
 such as the NEC-260 and the new MITSUMI triple/quad speed drives.
diff -u --recursive --new-file v1.1.92/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.1.92/linux/drivers/block/ide.c	Mon Jan 30 06:41:56 1995
+++ linux/drivers/block/ide.c	Mon Feb 20 09:31:06 1995
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide.c	Version 3.11  January 25, 1995
+ *  linux/drivers/block/ide.c	Version 3.12  February 19, 1995
  *
  *  Copyright (C) 1994, 1995  Linus Torvalds & authors (see below)
  */
@@ -101,6 +101,8 @@
  *			fix byte-ordering for some NEC cdrom drives
  *  Version 3.10	disable multiple mode by default; was causing trouble
  *  Version 3.11	fix mis-identification of old WD disks as cdroms
+ *  Version 3,12	simplify logic for selecting initial mult_count
+ *			  (fixes problems with buggy WD drives)
  *
  *  To do:
  *	- special 32-bit controller-type detection & support
@@ -136,8 +138,7 @@
 #include <asm/io.h>
 
 #undef	REALLY_FAST_IO			/* define if ide ports are perfect */
-#define INITIAL_MULT_COUNT	0	/* undef to use BIOS setting on entry */
-					/*   or non-zero to enable block mode */
+#define INITIAL_MULT_COUNT	0	/* use zero to disable block mode */
 #ifndef VLB_32BIT_IDE			/* 0 for safety, 1 for 32-bit chipset:*/
 #define VLB_32BIT_IDE		0	/*   Winbond 83759F or OPTi 82C621 */
 #endif
@@ -903,8 +904,7 @@
 		if (dev->type == disk) {
 			if (dev->id && dev->mult_req > dev->id->max_multsect)
 				dev->mult_req = dev->id->max_multsect;
-			if (dev->mult_req != dev->mult_count)
-				ide_cmd(dev,WIN_SETMULT,dev->mult_req,&set_multmode_intr);
+			ide_cmd(dev,WIN_SETMULT,dev->mult_req,&set_multmode_intr);
 		} else {
 			dev->mult_req = 0;
 			printk("%s: multmode not supported by this device\n", dev->name);
@@ -1696,24 +1696,13 @@
 	 dev->select.b.lba ? "LBA, " : "",
 	 dev->bios_cyl, dev->bios_head, dev->bios_sect);
 
-	/* Keep current multiplemode setting, if any (from DOS/BIOS) */
+	dev->mult_count = 0;
 	if (id->max_multsect) {
-		if ((id->multsect_valid & 1) && id->multsect)
-			dev->mult_count = id->multsect;	/* current setting */
-#ifdef INITIAL_MULT_COUNT
 		dev->mult_req = INITIAL_MULT_COUNT;
-#if INITIAL_MULT_COUNT
-		/* use specified value, or maximum, whichever is less */
-		if (INITIAL_MULT_COUNT > id->max_multsect)
+		if (dev->mult_req > id->max_multsect)
 			dev->mult_req = id->max_multsect;
-#endif
-#else	/* use existing setting from DOS/BIOS: */
-		if (dev->mult_count <= id->max_multsect) /* valid? */
-			dev->mult_req = dev->mult_count; /* keep it */
-#endif	/* INITIAL_MULT_COUNT */
-		if (dev->mult_req != dev->mult_count)
-			dev->special.b.set_multmode = 1;
-		printk(", Mult=%d/%d", dev->mult_req, id->max_multsect);
+		dev->special.b.set_multmode = 1;
+		printk(", MaxMult=%d", id->max_multsect);
 	}
 	printk("\n");
 }
diff -u --recursive --new-file v1.1.92/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v1.1.92/linux/drivers/net/plip.c	Wed Feb 15 10:36:38 1995
+++ linux/drivers/net/plip.c	Mon Feb 20 08:59:52 1995
@@ -171,6 +171,9 @@
 #elif defined(__mc68000__)
 			unsigned char msb;
 			unsigned char lsb;
+#elif defined(__sparc__)
+			unsigned char msb;
+			unsigned char lsb;
 #elif defined(__MIPSEL__)
 			unsigned char lsb;
 			unsigned char msb;
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v1.1.92/linux/drivers/scsi/53c7,8xx.c	Thu Jan 26 07:49:06 1995
+++ linux/drivers/scsi/53c7,8xx.c	Sun Feb 19 11:22:43 1995
@@ -2810,7 +2810,7 @@
 
     /* 250ms selection timeout */
     if ((((hostdata->chip / 100) == 8) && (sist1 & SIST1_800_STO)) || 
-        (((hostdata->chip / 100) != 8) && sstat0_sist0 && SSTAT0_700_STO)) {
+        (((hostdata->chip / 100) != 8) && (sstat0_sist0 & SSTAT0_700_STO))) {
 	fatal = 1;
 	if (hostdata->options & OPTION_DEBUG_INTR) {
 	    printk ("scsi%d : Selection Timeout\n", host->host_no);
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v1.1.92/linux/drivers/scsi/hosts.c	Fri Feb 17 11:20:14 1995
+++ linux/drivers/scsi/hosts.c	Sun Feb 19 11:33:14 1995
@@ -387,3 +387,20 @@
 	continue;
     }
 }
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
--- v1.1.92/linux/drivers/scsi/hosts.h	Wed Feb 15 10:36:39 1995
+++ linux/drivers/scsi/hosts.h	Sun Feb 19 11:42:34 1995
@@ -247,7 +247,7 @@
 
 		/* These parameters should be set by the detect routine */
 		unsigned char *base;
-		short unsigned int io_port;
+		unsigned int io_port;
 		unsigned char n_io_port;
 		unsigned char irq;
 		unsigned char dma_channel;
@@ -356,3 +356,19 @@
 #define SG_EXTRA_DEVS (SD_EXTRA_DEVS + SR_EXTRA_DEVS + ST_EXTRA_DEVS)
 
 #endif
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/qlogic.c linux/drivers/scsi/qlogic.c
--- v1.1.92/linux/drivers/scsi/qlogic.c	Sun Feb  5 19:31:54 1995
+++ linux/drivers/scsi/qlogic.c	Sun Feb 19 11:33:13 1995
@@ -18,7 +18,7 @@
    Reference Qlogic FAS408 Technical Manual, 53408-510-00A, May 10, 1994
    (you can reference it, but it is incomplete and inaccurate in places)
 
-   Version 0.39a
+   Version 0.40a
 
    Functions as standalone, loadable, and PCMCIA driver, the latter from
    Dave Hind's PCMCIA package.
@@ -29,14 +29,6 @@
 /*----------------------------------------------------------------*/
 /* Configuration */
 
-/* The following option is normally left alone.  PCMCIA support needs to
-   change this to adapt to the different way the interrupt pin works.
-   
-   Set the following to 2 to use normal interrupt (active high/totempole-
-   tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open
-   drain */
-#define QL_INT_ACTIVE_HIGH 2
-
 /* Set the following to 1 to enable the use of interrupts.  Note that 0 tends
    to be more stable, but slower (or ties up the system more) */
 #define QL_USE_IRQ 1
@@ -51,21 +43,36 @@
    without requiring a cold boot.  It does take some time to recover from a
    reset, so it is slower, and I have seen timeouts so that devices weren't
    recognized when this was set. */
-#define QL_RESET_AT_START 1
+#define QL_RESET_AT_START 0
+
+/* crystal frequency in megahertz (for offset 5 and 9) */
+#define XTALFREQ	40
 
-/* This will set fast (10Mhz) synchronous timing, FASTCLK must also be 1 */
+/*****/
+/* offset 0xc */
+/* This will set fast (10Mhz) synchronous timing when set to 1
+   FASTCLK must also be 0 */
 #define FASTSCSI  0
 
-/* This will set a faster sync transfer rate */
+/* This when set to 1 will set a faster sync transfer rate */
 #define FASTCLK   0
 
-/* This bit needs to be set to 1 if your cabling is long or noisy */
+/*****/
+/* config register 1 (offset 8) options */
+/* This needs to be set to 1 if your cabling is long or noisy */
 #define SLOWCABLE 0
 
+/* This should be 1 to enable parity detection */
+#define QL_ENABLE_PARITY 1
+
+/*****/
+/* offset 6 */
 /* This is the sync transfer divisor, 40Mhz/X will be the data rate
 	The power on default is 5, the maximum normal value is 5 */
 #define SYNCXFRPD 4
 
+/*****/
+/* offset 7 */
 /* This is the count of how many synchronous transfers can take place
 	i.e. how many reqs can occur before an ack is given.
 	The maximum value for this is 15, the upper bits can modify
@@ -77,15 +84,9 @@
 	cause the deassertion to be early by 1/2 clock.  Bits 5&4 control
 	the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */
 
-/* PCMCIA option adjustment */
-#ifdef PCMCIA
-#undef QL_INT_ACTIVE_HIGH
-#define QL_INT_ACTIVE_HIGH 0
-#endif
-
 /*----------------------------------------------------------------*/
-
-#ifdef MODULE
+#if defined(MODULE) || defined(PCMCIA)
+#include <linux/config.h>
 #include <linux/module.h>
 #endif
 
@@ -103,17 +104,24 @@
 
 /*----------------------------------------------------------------*/
 /* driver state info, local to driver */
-static int	    qbase;	/* Port */
+static int	    qbase = 0;	/* Port */
 static int	    qinitid;	/* initiator ID */
 static int	    qabort;	/* Flag to cause an abort */
-static int	    qlirq;	/* IRQ being used */
+static int	    qlirq = -1;	/* IRQ being used */
 static char	    qinfo[80];	/* description */
 static Scsi_Cmnd   *qlcmd;	/* current command being processed */
 
+static int	    qlcfg5 = ( XTALFREQ << 5 );	/* 15625/512 */
+static int	    qlcfg6 = SYNCXFRPD;
+static int	    qlcfg7 = SYNCOFFST;
+static int	    qlcfg8 = ( SLOWCABLE << 7 ) | ( QL_ENABLE_PARITY << 4 );
+static int	    qlcfg9 = ( ( XTALFREQ + 4 ) / 5 );
+static int	    qlcfgc = ( FASTCLK << 3 ) | ( FASTSCSI << 4 );
+
 /*----------------------------------------------------------------*/
 /* The qlogic card uses two register maps - These macros select which one */
 #define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd ))
-#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd ))
+#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb6 , qbase + 0xd ))
 
 /* following is watchdog timeout in microseconds */
 #define WATCHDOG 5000000
@@ -270,27 +278,15 @@
 	outb(0x40, qbase + 0xb);		/* enable features */
 
 /* configurables */
-#if FASTSCSI
-#if FASTCLK
-	outb(0x18, qbase + 0xc);
-#else
-	outb(0x10, qbase + 0xc);
-#endif
-#else
-#if FASTCLK
-	outb(8, qbase + 0xc);
-#endif
-#endif
-
-#if SLOWCABLE
-	outb(0xd0 | qinitid, qbase + 8);	/* (initiator) bus id */
-#else
-	outb(0x50 | qinitid, qbase + 8);	/* (initiator) bus id */
-#endif
-	outb( SYNCOFFST , qbase + 7 );
-	outb( SYNCXFRPD , qbase + 6 );
+	outb( qlcfgc , qbase + 0xc);
+/* config: no reset interrupt, (initiator) bus id */
+	outb( 0x40 | qlcfg8 | qinitid, qbase + 8);
+	outb( qlcfg7 , qbase + 7 );
+	outb( qlcfg6 , qbase + 6 );
 /**/
-	outb(0x99, qbase + 5);	/* timer */
+	outb(qlcfg5, qbase + 5);		/* select timer */
+	outb(qlcfg9 & 7, qbase + 9);			/* prescaler */
+/*	outb(0x99, qbase + 5);	*/
 	outb(cmd->target, qbase + 4);
 
 	for (i = 0; i < cmd->cmd_len; i++)
@@ -482,6 +478,17 @@
 }
 #endif
 
+#ifdef PCMCIA
+/*----------------------------------------------------------------*/
+/* allow PCMCIA code to preset the port */
+/* port should be 0 and irq to -1 respectively for autoprobing */
+void	qlogic_preset(int port, int irq)
+{
+	qbase=port;
+	qlirq=irq;
+}
+#endif
+
 /*----------------------------------------------------------------*/
 /* look for qlogic card and init if found */
 int	qlogic_detect(Scsi_Host_Template * host)
@@ -499,16 +506,20 @@
    card, but I haven't tested this.
 */
 
-	for (qbase = 0x230; qbase < 0x430; qbase += 0x100) {
-		if( check_region( qbase , 0x10 ) )
-			continue;
-		REG1;
-		if ( ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 )
-		  && ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 ) )
-			break;
+	if( !qbase ) {
+		for (qbase = 0x230; qbase < 0x430; qbase += 0x100) {
+			if( check_region( qbase , 0x10 ) )
+				continue;
+			REG1;
+			if ( ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 )
+			  && ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 ) )
+				break;
+		}
+		if (qbase == 0x430)
+			return 0;
 	}
-	if (qbase == 0x430)
-		return 0;
+	else
+		printk( "Ql: Using preset base address of %03x\n", qbase );
 
 	qltyp = inb(qbase + 0xe) & 0xf8;
 	qinitid = host->this_id;
@@ -516,8 +527,9 @@
 		qinitid = 7;			/* if no ID, use 7 */
 	outb(1, qbase + 8);			/* set for PIO pseudo DMA */
 	REG0;
-	outb(0xd0 | qinitid, qbase + 8);	/* (ini) bus id, disable scsi rst */
-	outb(0x99, qbase + 5);			/* select timer */
+	outb(0x40 | qlcfg8 | qinitid, qbase + 8);	/* (ini) bus id, disable scsi rst */
+	outb(qlcfg5, qbase + 5);		/* select timer */
+	outb(qlcfg9, qbase + 9);			/* prescaler */
 	qlirq = -1;
 #if QL_RESET_AT_START
 	outb( 3 , qbase + 3 );
@@ -527,27 +539,31 @@
 #endif
 #if QL_USE_IRQ
 /* IRQ probe - toggle pin and check request pending */
-	save_flags( flags );
-	cli();
-	i = 0xffff;
-	j = 3;
-	outb(0x90, qbase + 3);	/* illegal command - cause interrupt */
-	REG1;
-	outb(10, 0x20); /* access pending interrupt map */
-	outb(10, 0xa0);
-	while (j--) {
-		outb(0xb0 | QL_INT_ACTIVE_HIGH , qbase + 0xd);		/* int pin off */
-		i &= ~(inb(0x20) | (inb(0xa0) << 8));	/* find IRQ off */
-		outb(0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd);		/* int pin on */
-		i &= inb(0x20) | (inb(0xa0) << 8);	/* find IRQ on */
+	if( qlirq == -1 ) {
+		save_flags( flags );
+		cli();
+		i = 0xffff;
+		j = 3;
+		outb(0x90, qbase + 3);	/* illegal command - cause interrupt */
+		REG1;
+		outb(10, 0x20); /* access pending interrupt map */
+		outb(10, 0xa0);
+		while (j--) {
+			outb(0xb2 , qbase + 0xd);		/* int pin off */
+			i &= ~(inb(0x20) | (inb(0xa0) << 8));	/* find IRQ off */
+			outb(0xb6 , qbase + 0xd);		/* int pin on */
+			i &= inb(0x20) | (inb(0xa0) << 8);	/* find IRQ on */
+		}
+		REG0;
+		while (inb(qbase + 5)); 			/* purge int */
+		while (i)					/* find on bit */
+			i >>= 1, qlirq++;	/* should check for exactly 1 on */
+		if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic"))
+			host->can_queue = 1;
+		restore_flags( flags );
 	}
-	REG0;
-	while (inb(qbase + 5)); 			/* purge int */
-	while (i)					/* find on bit */
-		i >>= 1, qlirq++;	/* should check for exactly 1 on */
-	if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic"))
-		host->can_queue = 1;
-	restore_flags( flags );
+	else
+		printk( "Ql: Using preset IRQ of %d\n", qlirq );
 #endif
 	request_region( qbase , 0x10 ,"qlogic");
 	hreg = scsi_register( host , 0 );	/* no host data */
@@ -557,8 +573,8 @@
 	if( qlirq != -1 )
 		hreg->irq = qlirq;
 
-	sprintf(qinfo, "Qlogic Driver version 0.39a, chip %02X at %03X, IRQ %d, Opts:%d%d",
-	    qltyp, qbase, qlirq, QL_INT_ACTIVE_HIGH, QL_TURBO_PDMA );
+	sprintf(qinfo, "Qlogic Driver version 0.40a, chip %02X at %03X, IRQ %d, TPdma:%d",
+	    qltyp, qbase, qlirq, QL_TURBO_PDMA );
 	host->name = qinfo;
 
 	return 1;
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.1.92/linux/drivers/scsi/scsi.c	Fri Feb 17 11:20:14 1995
+++ linux/drivers/scsi/scsi.c	Mon Feb 20 10:57:10 1995
@@ -32,6 +32,8 @@
 #include "hosts.h"
 #include "constants.h"
 
+#undef USE_STATIC_SCSI_MEMORY
+
 /*
 static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.5 1993/09/24 12:45:18 drew Exp drew $";
 */
@@ -148,6 +150,7 @@
    {"CHINON","CD-ROM CDS-431","H42"},  /* Locks up if polled for lun != 0 */
    {"CHINON","CD-ROM CDS-535","Q14"}, /* Lockup if polled for lun != 0 */
    {"DENON","DRD-25X","V"},   /* A cdrom that locks up when probed at lun != 0 */
+   {"HITACHI","DK312C","CM81"},   /* Responds to all lun - dtg */
    {"HITACHI","DK314C","CR21" }, /* responds to all lun */
    {"IMS", "CDD521/10","2.06"},   /* Locks-up when LUN>0 polled. */
    {"MAXTOR","XT-3280","PR02"},   /* Locks-up when LUN>0 polled. */
@@ -190,8 +193,8 @@
     if(memcmp(blacklist[i].model, pnt,
 	       strlen(blacklist[i].model))) continue;
     return 1;
-  };
-};
+  }
+}
 
 /*
  *	As the actual SCSI command runs in the background, we must set up a
@@ -305,43 +308,39 @@
   unsigned char * scsi_result;
   Scsi_Device * SDpnt, *SDtail;
   struct Scsi_Device_Template * sdtpnt;
-  Scsi_Cmnd  SCmd;
+  Scsi_Cmnd  *SCpnt;
 
-  memset(&SCmd, 0,  sizeof(SCmd));
   ++in_scan_scsis;
   lun = 0;
   type = -1;
-  SCmd.next = NULL;
-  SCmd.prev = NULL;
+  SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd), GFP_ATOMIC|GFP_DMA);
   SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof (Scsi_Device), GFP_ATOMIC);
-  SCmd.device = SDpnt;  /* This was really needed! (DB) */
-  memset(SDpnt, 0, sizeof(Scsi_Device));
   SDtail = scsi_devices;
-  if(scsi_devices) {
-    while(SDtail->next) SDtail = SDtail->next;
-  }
+
+  if(scsi_devices) while(SDtail->next) SDtail = SDtail->next;
 
   /* Make sure we have something that is valid for DMA purposes */
   scsi_result = ((current == task[0]  || !shpnt->unchecked_isa_dma)
 		 ?  &scsi_result0[0] : scsi_malloc(512));
 
 
-  shpnt->host_queue = &SCmd;  /* We need this so that
-					 commands can time out */
+  shpnt->host_queue = SCpnt;  /* We need this so that commands can time out */
+
   for (dev = 0; dev < 8; ++dev)
     if (shpnt->this_id != dev)
+
 /*
  * We need the for so our continue, etc. work fine.
  */
-
       for (lun = 0; lun < max_scsi_luns; ++lun)
 	{
+	  memset(SDpnt, 0, sizeof(Scsi_Device));
 	  SDpnt->host = shpnt;
 	  SDpnt->id = dev;
 	  SDpnt->lun = lun;
-	  SDpnt->device_wait = NULL;
-	  SDpnt->next = NULL;
-	  SDpnt->attached = 0;
+
+	  /* Some low level driver could use device->type (DB) */
+	  SDpnt->type = -1;
 /*
  * Assume that the device will have handshaking problems, and then
  * fix this field later if it turns out it doesn't.
@@ -350,59 +349,55 @@
 
 	  scsi_cmd[0] = TEST_UNIT_READY;
 	  scsi_cmd[1] = lun << 5;
-	  scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
-	  scsi_cmd[4] = 0;
+	  scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0;
 
-	  SCmd.host = shpnt;
-	  SCmd.target = dev;
-	  SCmd.lun = lun;
-
-	  SCmd.request.sem = NULL;  /* Used for mutex if loading devices after boot */
-	  SCmd.request.dev = 0xffff; /* Mark not busy */
-	  SCmd.use_sg  = 0;
-	  SCmd.cmd_len = 0;
-	  SCmd.old_use_sg  = 0;
-	  SCmd.transfersize = 0;
-	  SCmd.underflow = 0;
-
-	  scsi_do_cmd (&SCmd,
-		       (void *)  scsi_cmd, (void *)
-		       scsi_result, 256,  scan_scsis_done,
-		       SCSI_TIMEOUT + 400, 5);
+	  memset(SCpnt, 0,  sizeof(Scsi_Cmnd));
+	  SCpnt->host = SDpnt->host;
+	  SCpnt->device = SDpnt;
+	  SCpnt->target = SDpnt->id;
+	  SCpnt->lun = SDpnt->lun;
 
-	  /* Wait for command to finish.  Use simple wait if we are booting, else
+	  /* Used for mutex if loading devices after boot */
+	  SCpnt->request.sem = NULL;
+
+	  SCpnt->request.dev = 0xffff; /* Mark not busy */
+
+	  scsi_do_cmd (SCpnt, (void *)  scsi_cmd, (void *) scsi_result,
+		       256,  scan_scsis_done, SCSI_TIMEOUT + 400, 5);
+
+	  /* Wait for command to finish. Use simple wait if we are booting, else
 	     do it right and use a mutex */
 
-	  if (current == task[0]){
-	    while (SCmd.request.dev != 0xfffe);
-	  } else {
-	    if (SCmd.request.dev != 0xfffe){
+	  if (current == task[0])
+	      while (SCpnt->request.dev != 0xfffe);
+	  else if (SCpnt->request.dev != 0xfffe) {
 	      struct semaphore sem = MUTEX_LOCKED;
-	      SCmd.request.sem = &sem;
+
+	      SCpnt->request.sem = &sem;
 	      down(&sem);
+
 	      /* Hmm.. Have to ask about this one */
-	      while (SCmd.request.dev != 0xfffe) schedule();
-	    }
-	  }
+	      while (SCpnt->request.dev != 0xfffe) schedule();
+	      }
 
 #if defined(DEBUG) || defined(DEBUG_INIT)
 	  printk("scsi: scan SCSIS id %d lun %d\n", dev, lun);
-	  printk("scsi: return code %08x\n", SCmd.result);
+	  printk("scsi: return code %08x\n", SCpnt->result);
 #endif
 
 
-	  if(SCmd.result) {
-	    if ((driver_byte(SCmd.result)  & DRIVER_SENSE) &&
-		((SCmd.sense_buffer[0] & 0x70) >> 4) == 7) {
-	      if (SCmd.sense_buffer[2] &0xe0)
+	  if(SCpnt->result) {
+	    if ((driver_byte(SCpnt->result)  & DRIVER_SENSE) &&
+		((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
+	      if (SCpnt->sense_buffer[2] &0xe0)
 		continue; /* No devices here... */
-	      if(((SCmd.sense_buffer[2] & 0xf) != NOT_READY) &&
-		 ((SCmd.sense_buffer[2] & 0xf) != UNIT_ATTENTION))
+	      if(((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) &&
+		 ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION))
 		continue;
 	    }
 	    else
 	      break;
-	  };
+	  }
 
 #if defined (DEBUG) || defined(DEBUG_INIT)
 	  printk("scsi: performing INQUIRY\n");
@@ -411,7 +406,6 @@
 	  /*
 	   * Build an INQUIRY command block.
 	   */
-
 	  scsi_cmd[0] = INQUIRY;
 	  scsi_cmd[1] = (lun << 5) & 0xe0;
 	  scsi_cmd[2] = 0;
@@ -419,27 +413,25 @@
 	  scsi_cmd[4] = 255;
 	  scsi_cmd[5] = 0;
 
-	  SCmd.request.dev = 0xffff; /* Mark not busy */
-	  SCmd.cmd_len = 0;
+	  SCpnt->request.dev = 0xffff; /* Mark not busy */
+	  SCpnt->cmd_len = 0;
+
+	  scsi_do_cmd (SCpnt, (void *)  scsi_cmd, (void *) scsi_result,
+		       256,  scan_scsis_done, SCSI_TIMEOUT, 3);
 
-	  scsi_do_cmd (&SCmd,
-		       (void *)  scsi_cmd, (void *)
-		       scsi_result, 256,  scan_scsis_done,
-		       SCSI_TIMEOUT, 3);
-
-	  if (current == task[0]){
-	    while (SCmd.request.dev != 0xfffe);
-	  } else {
-	    if (SCmd.request.dev != 0xfffe){
+	  if (current == task[0])
+	      while (SCpnt->request.dev != 0xfffe);
+	  else if (SCpnt->request.dev != 0xfffe) {
 	      struct semaphore sem = MUTEX_LOCKED;
-	      SCmd.request.sem = &sem;
+
+	      SCpnt->request.sem = &sem;
 	      down(&sem);
+
 	      /* Hmm.. Have to ask about this one */
-	      while (SCmd.request.dev != 0xfffe) schedule();
-	    }
-	  }
+	      while (SCpnt->request.dev != 0xfffe) schedule();
+	      }
 
-	  the_result = SCmd.result;
+	  the_result = SCpnt->result;
 
 #if defined(DEBUG) || defined(DEBUG_INIT)
 	  if (!the_result)
@@ -578,25 +570,24 @@
 		    scsi_cmd[4] = 0x2a;
 		    scsi_cmd[5] = 0;
 
-		    SCmd.request.dev = 0xffff; /* Mark not busy */
-		    SCmd.cmd_len = 0;
+		    SCpnt->request.dev = 0xffff; /* Mark not busy */
+		    SCpnt->cmd_len = 0;
 
-		    scsi_do_cmd (&SCmd,
-				 (void *)  scsi_cmd, (void *)
-				 scsi_result, 0x2a,  scan_scsis_done,
+		    scsi_do_cmd (SCpnt, (void *)  scsi_cmd,
+				 (void *) scsi_result, 0x2a,  scan_scsis_done,
 				 SCSI_TIMEOUT, 3);
 
-		    if (current == task[0]){
-		      while (SCmd.request.dev != 0xfffe);
-		    } else {
-		      if (SCmd.request.dev != 0xfffe){
+		    if (current == task[0])
+			while (SCpnt->request.dev != 0xfffe);
+		    else if (SCpnt->request.dev != 0xfffe) {
 			struct semaphore sem = MUTEX_LOCKED;
-			SCmd.request.sem = &sem;
+
+			SCpnt->request.sem = &sem;
 			down(&sem);
+
 			/* Hmm.. Have to ask about this one */
-			while (SCmd.request.dev != 0xfffe) schedule();
-		      }
-		    }
+			while (SCpnt->request.dev != 0xfffe) schedule();
+			}
 		  }
 		  /* Add this device to the linked list at the end */
 		  if(SDtail)
@@ -619,11 +610,14 @@
 		}
 	    }       /* if result == DID_OK ends */
 	}       /* for lun ends */
+
   shpnt->host_queue = NULL;  /* No longer needed here */
 
   /* Last device block does not exist.  Free memory. */
   scsi_init_free((char *) SDpnt, sizeof(Scsi_Device));
 
+  scsi_init_free((char *) SCpnt, sizeof(Scsi_Cmnd));
+
 
   /* If we allocated a buffer so we could do DMA, free it now */
   if (scsi_result != &scsi_result0[0]) scsi_free(scsi_result, 512);
@@ -703,7 +697,7 @@
 	 SCpnt->lun == device->lun)
 	if(SCpnt->request.dev < 0) break;
       SCpnt = SCpnt->next;
-    };
+    }
 
   if (!SCpnt) return NULL;
 
@@ -723,7 +717,7 @@
 	    req->sector += bh->b_size >> 9;
 	    if(!tablesize) break;
 	    bh = bhp;
-    };
+    }
     if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
       SCpnt->request.bhtail = bh;
       req->bh = bh->b_reqnext; /* Divide request */
@@ -738,11 +732,11 @@
     } else {
       req->dev = -1;
       wake_up(&wait_for_request);
-    };
+    }
   } else {
     SCpnt->request.dev = 0xffff; /* Busy, but no request */
     SCpnt->request.sem = NULL;  /* And no one is waiting for the device either */
-  };
+  }
 
   SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
   SCpnt->old_use_sg  = 0;
@@ -792,16 +786,16 @@
 	 SCpnt->lun == device->lun) {
 	SCwait = SCpnt;
 	if(SCpnt->request.dev < 0) break;
-      };
+      }
       SCpnt = SCpnt->next;
-    };
+    }
     save_flags(flags);
     cli();
     /* See if this request has already been queued by an interrupt routine */
     if (req && ((req->dev < 0) || (req->dev != dev))) {
       restore_flags(flags);
       return NULL;
-    };
+    }
     if (!SCpnt || SCpnt->request.dev >= 0)  /* Might have changed */
       {
 	restore_flags(flags);
@@ -810,7 +804,7 @@
 	  printk("Attempt to allocate device target %d, lun %d\n",
 		 device->id ,device->lun);
 	  panic("No device found in allocate_device\n");
-	};
+	}
 	SCSI_SLEEP(&device->device_wait,
 		   (SCwait->request.dev > 0));
       } else {
@@ -828,7 +822,7 @@
 	    req->sector += bh->b_size >> 9;
 	    if(!tablesize) break;
 	    bh = bhp;
-	  };
+	  }
 	  if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
 	    SCpnt->request.bhtail = bh;
 	    req->bh = bh->b_reqnext; /* Divide request */
@@ -845,15 +839,15 @@
 	      req->dev = -1;
 	      *reqp = req->next;
 	      wake_up(&wait_for_request);
-	    };
+	    }
 	} else {
 	  SCpnt->request.dev = 0xffff; /* Busy */
 	  SCpnt->request.sem = NULL;  /* And no one is waiting for this to complete */
-	};
+	}
 	restore_flags(flags);
 	break;
-      };
-  };
+      }
+  }
 
   SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
   SCpnt->old_use_sg  = 0;
@@ -935,7 +929,7 @@
 #ifdef DEBUG_DELAY
 	clock = jiffies + 400;
 	while (jiffies < clock);
-	printk("done(host = %d, result = %04x) : routine at %08x\n", host->host_no, temp, done);
+	printk("done(host = %d, result = %04x) : routine at %08x\n", host->host_no, temp);
 #endif
 		scsi_done(SCpnt);
 		}
@@ -995,7 +989,7 @@
 	for (i = 0; i < 10; ++i)
 		printk ("%02x  ", ((unsigned char *) cmnd)[i]);
 	printk("\n");
-      };
+      }
 #endif
 
 	if (!host)
@@ -1096,7 +1090,7 @@
 	if(SCpnt->flags & NEEDS_JUMPSTART) {
 	  SCpnt->flags &= ~NEEDS_JUMPSTART;
 	  scsi_request_sense (SCpnt);
-	};
+	}
 #endif
 }
 
@@ -1472,7 +1466,7 @@
 			    SCpnt->use_sg = SCpnt->old_use_sg;
 			    SCpnt->cmd_len = SCpnt->old_cmd_len;
 			    internal_cmnd (SCpnt);
-			  };
+			  }
 			break;
 		default:
 			INTERNAL_ERROR;
@@ -1665,7 +1659,7 @@
 				    SCpnt1->flags |= IS_RESETTING;
 				  }
 				  SCpnt1 = SCpnt1->next;
-				};
+				}
 
 				host->last_reset = jiffies;
 				temp = host->hostt->reset(SCpnt);
@@ -1755,7 +1749,7 @@
 			save_flags(flags);
 			cli();
 		      }
-		};
+		}
 	      } while (timed_out);
 	restore_flags(flags);
       }
@@ -1796,7 +1790,7 @@
 	if(SCset){
 	  oldto = SCset->timeout - used;
 	  SCset->timeout = timeout + used;
-	};
+	}
 
 	least = 0xffffffff;
 
@@ -1807,7 +1801,7 @@
 	      if(SCpnt->timeout <= 0) SCpnt->timeout = -1;
 	      if(SCpnt->timeout > 0 && SCpnt->timeout < least)
 		least = SCpnt->timeout;
-	    };
+	    }
 
 /*
 	If something is due to timeout again, then we will set the next timeout
@@ -1864,8 +1858,8 @@
 	printk("SMalloc: %d %x ",len, dma_malloc_pages[i] + (j << 9));
 #endif
 	return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
-      };
-    };
+      }
+    }
   restore_flags(flags);
   return NULL;  /* Nope.  No more */
 }
@@ -1923,7 +1917,9 @@
 void * scsi_init_malloc(unsigned int size, int priority)
 {
   unsigned long retval;
-#if 0 /* Use the statically allocated memory instead of kmalloc  (DB) */
+
+/* Use the statically allocated memory instead of kmalloc  (DB) */
+#if defined(USE_STATIC_SCSI_MEMORY)
   if(scsi_loadable_module_flag && !(priority & GFP_DMA))
 #else
   if(scsi_loadable_module_flag)
@@ -1946,6 +1942,7 @@
        scsi_init_memory_start += size;
        }
     }
+  memset((void *) retval, 0, size);
   return (void *) retval;
 }
 
@@ -2035,9 +2032,9 @@
 	      SCpnt->next = host->host_queue;
 	      SCpnt->prev = NULL;
 	      host->host_queue = SCpnt;
-	    };
-	  };
-	};
+	    }
+	  }
+	}
 
 	if (scsi_devicelist)
 	  dma_sectors = 16;  /* Base value we use */
@@ -2061,8 +2058,8 @@
 	    dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
 	      host->cmd_per_lun;
 	    need_isa_buffer++;
-	  };
-	};
+	  }
+	}
 
 	dma_sectors = (dma_sectors + 15) & 0xfff0;
 	dma_free_sectors = dma_sectors;  /* This must be a multiple of 16 */
@@ -2088,15 +2085,16 @@
 
 	scsi_loadable_module_flag = 1;
 
-#if 0   /* This allocates statically some extra memory to be used for modules,
-           until the kmalloc problem is fixed (DB) */
 
-        scsi_memory_upper_value = scsi_init_memory_start + 
-                     2 * (scsi_init_memory_start - scsi_memory_lower_value);
-
-        printk ("scsi memory: lower %p, upper %p.\n", 
-             (void *)scsi_memory_lower_value, (void *)scsi_memory_upper_value);
+/* This allocates statically some extra memory to be used for modules,
+   until the kmalloc problem is fixed (DB) */
 
+#if defined(USE_STATIC_SCSI_MEMORY)
+	scsi_memory_upper_value = scsi_init_memory_start + 256 * 1024;
+	printk ("SCSI memory: total %ldKb, used %ldKb, free %ldKb.\n",
+		(scsi_memory_upper_value - scsi_memory_lower_value) / 1024,
+		(scsi_init_memory_start - scsi_memory_lower_value) / 1024,
+		(scsi_memory_upper_value - scsi_init_memory_start) / 1024);
 	return scsi_memory_upper_value;
 #else
 	return scsi_init_memory_start;
@@ -2234,8 +2232,8 @@
 		host->host_queue = SCpnt;
 		if(host->host_queue)
 		  host->host_queue->prev = SCpnt;
-	      };
-	    };
+	      }
+	    }
 	  }
 	/* Next, check to see if we need to extend the DMA buffer pool */
       {
@@ -2261,8 +2259,8 @@
 	      new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
 		host->cmd_per_lun;
 	      new_need_isa_buffer++;
-	    };
-	  };
+	    }
+	  }
 
 	  new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
 
@@ -2303,6 +2301,14 @@
 	if(sdtpnt->finish && sdtpnt->nr_dev)
 	  (*sdtpnt->finish)();
     }
+
+#if defined(USE_STATIC_SCSI_MEMORY)
+  printk ("SCSI memory: total %ldKb, used %ldKb, free %ldKb.\n",
+	  (scsi_memory_upper_value - scsi_memory_lower_value) / 1024,
+	  (scsi_init_memory_start - scsi_memory_lower_value) / 1024,
+	  (scsi_memory_upper_value - scsi_init_memory_start) / 1024);
+#endif
+
   return 0;
 }
 
@@ -2325,7 +2331,7 @@
 
   for(sdpnt = scsi_devices; sdpnt; sdpnt = sdpnt->next)
     if(sdpnt->host->hostt == tpnt && sdpnt->host->hostt->usage_count
-                                 && *sdpnt->host->hostt->usage_count) return;
+				 && *sdpnt->host->hostt->usage_count) return;
 
   for(shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
     {
@@ -2342,6 +2348,7 @@
 	    return;
 	  }
 	  SCpnt->request.dev = 0xffe0;  /* Mark as busy */
+	  restore_flags(flags);
 	}
     }
   /* Next we detach the high level drivers from the Scsi_Device structures */
@@ -2414,6 +2421,13 @@
   printk ("scsi : %d host%s.\n", next_scsi_host,
 	  (next_scsi_host == 1) ? "" : "s");
 
+#if defined(USE_STATIC_SCSI_MEMORY)
+  printk ("SCSI memory: total %ldKb, used %ldKb, free %ldKb.\n",
+	  (scsi_memory_upper_value - scsi_memory_lower_value) / 1024,
+	  (scsi_init_memory_start - scsi_memory_lower_value) / 1024,
+	  (scsi_memory_upper_value - scsi_init_memory_start) / 1024);
+#endif
+
   scsi_make_blocked_list();
 
   /* There were some hosts that were loaded at boot time, so we cannot
@@ -2500,7 +2514,7 @@
 	       SCpnt->cmnd[0],
 	       SCpnt->sense_buffer[2],
 	       SCpnt->result);
-      };
+      }
   printk("wait_for_request = %p\n", wait_for_request);
   /* Now dump the request lists for each block device */
   printk("Dump of pending block device requests\n");
@@ -2523,3 +2537,20 @@
       }
 }
 #endif
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.1.92/linux/drivers/scsi/scsi.h	Thu Feb  9 10:18:52 1995
+++ linux/drivers/scsi/scsi.h	Sun Feb 19 11:33:14 1995
@@ -622,3 +622,20 @@
 	}; }
 
 #endif
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- v1.1.92/linux/drivers/scsi/scsi_ioctl.c	Thu Jan 26 07:49:06 1995
+++ linux/drivers/scsi/scsi_ioctl.c	Sun Feb 19 11:33:14 1995
@@ -311,3 +311,20 @@
   set_fs(oldfs);
   return tmp;
 }
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v1.1.92/linux/drivers/scsi/sd.c	Sun Feb  5 19:31:54 1995
+++ linux/drivers/scsi/sd.c	Sun Feb 19 11:33:13 1995
@@ -384,7 +384,15 @@
       SCpnt = allocate_device(&CURRENT,
 			      rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
     else SCpnt = NULL;
+
+    /*
+     * The following restore_flags leads to latency problems.  FIXME.
+     */
+#if 0
     restore_flags(flags);
+#else
+    sti();
+#endif
 
 /* This is a performance enhancement.  We dig down into the request list and
    try and find a queueable request (i.e. device not busy, and host able to
@@ -1273,3 +1281,20 @@
     }
   return;
 }
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c
--- v1.1.92/linux/drivers/scsi/sd_ioctl.c	Thu Jan 26 07:49:06 1995
+++ linux/drivers/scsi/sd_ioctl.c	Sun Feb 19 11:33:14 1995
@@ -73,3 +73,19 @@
 			return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device , cmd, (void *) arg);
 	}
 }
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- v1.1.92/linux/drivers/scsi/seagate.c	Sun Jan 22 21:39:41 1995
+++ linux/drivers/scsi/seagate.c	Sun Feb 19 11:33:14 1995
@@ -347,7 +347,8 @@
  */
 		instance = scsi_register(tpnt, 0);
 		hostno = instance->host_no;
-		if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT, "seagate")) {
+		if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT,
+		   (controller_type == SEAGATE) ? "seagate" : "tmc-8xx")) {
 			printk("scsi%d : unable to allocate IRQ%d\n",
 				hostno, (int) irq);
 			return 0;
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v1.1.92/linux/drivers/scsi/sg.c	Wed Feb 15 10:36:39 1995
+++ linux/drivers/scsi/sg.c	Sun Feb 19 11:33:14 1995
@@ -422,3 +422,20 @@
     }
   return;
 }
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v1.1.92/linux/drivers/scsi/sr.c	Thu Feb  9 10:18:52 1995
+++ linux/drivers/scsi/sr.c	Mon Feb 20 08:49:05 1995
@@ -305,8 +305,15 @@
   unsigned char   *cmd;       /* the scsi-command */
   unsigned char   *send;      /* the data we send to the drive ... */
   unsigned char   *rec;       /* ... and get back */
-  int             rc,is_xa;
+  int             rc,is_xa,no_multi;
 
+  if (scsi_CDs[MINOR(inode->i_rdev)].xa_flags & 0x02) {
+#ifdef DEBUG
+    printk("sr_photocd: drive does not support multisession CD's");
+#endif
+    return;
+  }
+  
   if (!suser()) {
     /* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND isn't allowed for me.
      * That's why mpcd_sector will be initialized with zero, because I'm not
@@ -314,12 +321,18 @@
      * no disk change happened since the last call of this function and we can
      * keep the old value.
      */
-    if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
+    if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count) {
       scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
+      scsi_CDs[MINOR(inode->i_rdev)].xa_flags &= ~0x01;
+    }
     return;
   }
 
+  sector   = 0;
+  is_xa    = 0;
+  no_multi = 0;
   cmd = rec = &buf[8];
+
   switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
 
   case SCSI_MAN_NEC:
@@ -336,22 +349,23 @@
 			   SCSI_IOCTL_SEND_COMMAND, buf);
     if (rc != 0) {
       printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
-      sector = 0;
-      is_xa = 0;
-    } else {
-      min   = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
-      sec   = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
-      frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
-      /* if rec[14] isn't 0xb0, the drive does not support multisession CD's, use zero */
-      sector = (0xb0 == rec[14]) ? min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame : 0;
-      is_xa = (rec[14] == 0xb0);
+      break;
+    }
+    if (rec[14] != 0 && rec[14] != 0xb0) {
+      printk("sr_photocd: Hmm, seems the CDROM does'nt support multisession CD's\n");
+      no_multi = 1;
+      break;
+    }
+    min   = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
+    sec   = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
+    frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
+    sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
+    is_xa  = (rec[14] == 0xb0);
 #ifdef DEBUG
-      printk("NEC: (%2x) %2li:%02li:%02li = %li\n",buf[8+14],min,sec,frame,sector);
-      if (sector) {
-	printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
-      }
-#endif
+    if (sector) {
+      printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
     }
+#endif
     break;
 
   case SCSI_MAN_TOSHIBA:
@@ -369,15 +383,22 @@
     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 			   SCSI_IOCTL_SEND_COMMAND, buf);
     if (rc != 0) {
-      printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
-      sector = 0;
-      is_xa = 0;
+      if (rc == 0x28000002) {
+	/* Got a "not ready" - error. No chance to find out if this is
+	   becauce there is no CD in the drive or becauce the drive
+	   don't knows multisession CD's. So I need to do an extra check... */
+	if (kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
+			      SCSI_IOCTL_TEST_UNIT_READY, NULL)) {
+	  printk("sr_photocd: drive not ready\n");
+	} else {
+	  printk("sr_photocd: Hmm, seems the CDROM does'nt support multisession CD's\n");
+	  no_multi = 1;
+	}
+      } else
+	printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
       break; /* if the first ioctl fails, we don't call the second one */
     }
     is_xa  = (rec[0] == 0x20);
-#ifdef DEBUG
-    printk("sr_photocd: TOSHIBA %x\n",rec[0]);
-#endif
     min    = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16;
     sec    = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
     frame  = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
@@ -436,12 +457,15 @@
 #ifdef DEBUG
     printk("sr_photocd: unknown drive, no special multisession code\n");
 #endif
-    sector = 0;
-    is_xa = 0;
     break; }
 
   scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
-  scsi_CDs[MINOR(inode->i_rdev)].is_xa = is_xa;
+  if (is_xa)
+    scsi_CDs[MINOR(inode->i_rdev)].xa_flags |= 0x01;
+  else
+    scsi_CDs[MINOR(inode->i_rdev)].xa_flags &= ~0x01;
+  if (no_multi)
+    scsi_CDs[MINOR(inode->i_rdev)].xa_flags |= 0x02;
   return;
 }
 
@@ -1045,3 +1069,20 @@
     }
   return;
 }
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/sr.h linux/drivers/scsi/sr.h
--- v1.1.92/linux/drivers/scsi/sr.h	Thu Feb  9 10:18:52 1995
+++ linux/drivers/scsi/sr.h	Mon Feb 20 08:49:05 1995
@@ -25,7 +25,7 @@
 	unsigned 	sector_size;		/* size in bytes 			*/
 	Scsi_Device  	*device;		
 	unsigned long   mpcd_sector;            /* for reading multisession-CD's        */
-	char            is_xa;                  /* is it an XA-CD ?                     */
+	char            xa_flags;               /* some flags for handling XA-CD's      */
 	unsigned char	sector_bit_size;	/* sector size = 2^sector_bit_size	*/
 	unsigned char	sector_bit_shift;	/* sectors/FS block = 2^sector_bit_shift*/
 	unsigned 	needs_sector_size:1;   	/* needs to get sector size */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v1.1.92/linux/drivers/scsi/sr_ioctl.c	Fri Feb 17 11:20:15 1995
+++ linux/drivers/scsi/sr_ioctl.c	Mon Feb 20 08:49:05 1995
@@ -409,7 +409,7 @@
 			    ms_info.addr.lba=scsi_CDs[target].mpcd_sector;
 			  else return (-EINVAL);
 			
-			  ms_info.xa_flag=scsi_CDs[target].is_xa;
+			  ms_info.xa_flag=scsi_CDs[target].xa_flags & 0x01;
 			 			  
 			  err=verify_area(VERIFY_WRITE,(void *) arg,
 					  sizeof(struct cdrom_multisession));
@@ -430,3 +430,20 @@
 			return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
 		}
 }
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v1.1.92/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v1.1.92/linux/drivers/scsi/st.c	Fri Feb 17 11:20:15 1995
+++ linux/drivers/scsi/st.c	Sun Feb 19 10:27:21 1995
@@ -11,7 +11,7 @@
   Copyright 1992, 1993, 1994, 1995 Kai Makisara
 		 email Kai.Makisara@metla.fi
 
-  Last modified: Mon Jan 30 23:20:07 1995 by root@kai.home
+  Last modified: Sat Feb 18 10:51:25 1995 by root@kai.home
 */
 
 #include <linux/fs.h>
@@ -74,6 +74,7 @@
 #endif
 
 #define MAX_RETRIES 0
+#define MAX_WRITE_RETRIES 0
 #define MAX_READY_RETRIES 5
 #define NO_TAPE  NOT_READY
 
@@ -110,10 +111,10 @@
 {
   int dev = SCpnt->request.dev;
   int result = SCpnt->result;
-  unsigned char * sense = SCpnt->sense_buffer;
+  unsigned char * sense = SCpnt->sense_buffer, scode;
   char *stp;
 
-  if (!result && SCpnt->sense_buffer[0] == 0)
+  if (!result /* && SCpnt->sense_buffer[0] == 0 */ )
     return 0;
 #ifdef DEBUG
   if (debugging) {
@@ -123,13 +124,25 @@
 	   SCpnt->request_bufflen);
     if (driver_byte(result) & DRIVER_SENSE)
       print_sense("st", SCpnt);
-  }
+  } else
 #endif
-/*  if ((sense[0] & 0x70) == 0x70 &&
-       ((sense[2] & 0x80) ))
-    return 0; */
+    scode = sense[2] & 0x0f;
+    if (!(driver_byte(result) & DRIVER_SENSE) ||
+	((sense[0] & 0x70) == 0x70 &&
+	 scode != NO_SENSE &&
+	 scode != RECOVERED_ERROR &&
+	 scode != UNIT_ATTENTION &&
+	 scode != BLANK_CHECK &&
+	 scode != VOLUME_OVERFLOW)) {  /* Abnormal conditions for tape */
+      printk("st%d: Error %x. ", dev, result);
+      if (driver_byte(result) & DRIVER_SENSE)
+	print_sense("st", SCpnt);
+      else
+	printk("\n");
+    }
+
   if ((sense[0] & 0x70) == 0x70 &&
-      sense[2] == RECOVERED_ERROR
+      scode == RECOVERED_ERROR
 #ifdef ST_RECOVERED_WRITE_FATAL
       && SCpnt->cmnd[0] != WRITE_6
       && SCpnt->cmnd[0] != WRITE_FILEMARKS
@@ -312,7 +325,7 @@
     SCpnt->request.dev = dev;
     scsi_do_cmd (SCpnt,
 		 (void *) cmd, (STp->buffer)->b_data, transfer,
-		 st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+		 st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
 
     if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 
@@ -472,7 +485,6 @@
 	printk("st%d: No tape.\n", dev);
 	STp->ready = ST_NO_TAPE;
       } else {
-	printk("st%d: Error %x.\n", dev, SCpnt->result);
         (STp->mt_status)->mt_fileno = STp->drv_block = (-1);
 	STp->ready = ST_NOT_READY;
       }
@@ -484,6 +496,8 @@
       STp->block_size = 0;
       STp->eof = ST_NOEOF;
       (STp->mt_status)->mt_fileno = STp->drv_block = 0;
+      if (scsi_tapes[dev].device->host->hostt->usage_count)
+	(*scsi_tapes[dev].device->host->hostt->usage_count)++;
       return 0;
     }
 
@@ -637,7 +651,7 @@
 	SCpnt->request.dev = dev;
 	scsi_do_cmd( SCpnt,
 		    (void *) cmd, (void *) (STp->buffer)->b_data,
-		    0, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+		    0, st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
 
 	if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 
@@ -797,7 +811,7 @@
       SCpnt->request.dev = dev;
       scsi_do_cmd (SCpnt,
 		   (void *) cmd, (STp->buffer)->b_data, transfer,
-		   st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+		   st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
 
       if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );
 
@@ -910,7 +924,7 @@
       scsi_do_cmd (SCpnt,
 		   (void *) cmd, (STp->buffer)->b_data,
 		   (STp->buffer)->writing,
-		   st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+		   st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
     }
     else
       SCpnt->request.dev = -1;  /* Mark as not busy */
diff -u --recursive --new-file v1.1.92/linux/include/asm-sparc/clock.h linux/include/asm-sparc/clock.h
--- v1.1.92/linux/include/asm-sparc/clock.h	Sun Feb  5 19:31:55 1995
+++ linux/include/asm-sparc/clock.h	Mon Feb 20 08:59:52 1995
@@ -46,6 +46,8 @@
   unsigned char foo[14];
 };
 
+#define TIMER_PHYSADDR   0xf3000000
+
 /* YUCK YUCK YUCK, grrr... */
 #define  TIMER_STRUCT  ((struct sparc_timer_info *)((struct sparc_clock_info *) TIMER_VADDR))
 
diff -u --recursive --new-file v1.1.92/linux/include/asm-sparc/delay.h linux/include/asm-sparc/delay.h
--- v1.1.92/linux/include/asm-sparc/delay.h	Mon Jan  9 07:22:10 1995
+++ linux/include/asm-sparc/delay.h	Mon Feb 20 08:59:52 1995
@@ -14,7 +14,7 @@
 {
   __asm__ __volatile__("\n1:\tcmp %0, 0\n\t"
 		       "bne,a 1b\n\t"
-		       "sub %0, 1, %0\n": "=r" (loops) : "0" (loops));
+		       "sub %0, 1, %0\n": "=&r" (loops) : "0" (loops));
 }
 
 /* udelay(usecs) is used for very short delays up to 1 millisecond. */
diff -u --recursive --new-file v1.1.92/linux/include/asm-sparc/head.h linux/include/asm-sparc/head.h
--- v1.1.92/linux/include/asm-sparc/head.h	Sun Feb  5 19:31:55 1995
+++ linux/include/asm-sparc/head.h	Mon Feb 20 08:59:52 1995
@@ -22,28 +22,36 @@
 /* Generic trap entry. */
 
 #define TRAP_ENTRY(type, label) \
-	mov (type), %l3; b label; mov %psr, %l0; nop;
+	mov (type), %l3; b label; rd %psr, %l0; nop;
 
 /* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
  * gets handled with another macro.
  */
 
 #define TRAP_ENTRY_INTERRUPT(int_level) \
-        mov int_level, %l4; b trap_entry; mov %psr, %l0; nop;
+        mov int_level, %l3; b stray_irq_entry; rd %psr, %l0; nop;
 
 /* Here is the macro for soft interrupts (ie. not as urgent as hard ones)
-   which need to jump to a different handler.
-*/
+ * which need to jump to a different handler.
+ */
 
 #define TRAP_ENTRY_INTERRUPT_SOFT(int_level, ident) \
-        mov int_level, %l4; mov %psr, %l0; b trap_entry; mov ident, %l3;
+        mov int_level, %l3; rd %psr, %l0; b stray_irq_entry; mov ident, %l4;
+
+/* The above two macros are for generic traps. The following is made
+ * especially for timer interrupts at IRQ level 14.
+ */
+
+#define TRAP_ENTRY_TIMER \
+        mov 10, %l3; rd %psr, %l0; b sparc_timer; nop;
 
 /* Non-maskable interrupt entry macro. You have to turn off all interrupts
-   to not receive this. This is usually due to a asynchronous memory error.
-   All we can really do is stop the show. :-(
-*/
+ * to not receive this. This is usually due to a asynchronous memory error.
+ * All we can really do is stop the show. :-(
+ */
+
 #define TRAP_ENTRY_INTERRUPT_NMI(t_type, jmp_to) \
-        mov t_type, %l3; b jmp_to; mov %psr, %l0; nop;
+        mov t_type, %l3; b jmp_to; rd %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.
@@ -53,11 +61,11 @@
  *       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
+#define THREAD_UWINDOWS 0x3bc
+#define THREAD_WIM 0x3c0
+#define THREAD_W_SAVED 0x3c4
+#define THREAD_KSP 0x3c8
+#define THREAD_USP 0x3cc
+#define THREAD_REG_WINDOW 0x3d4
 
 #endif __SPARC_HEAD_H
diff -u --recursive --new-file v1.1.92/linux/include/asm-sparc/io.h linux/include/asm-sparc/io.h
--- v1.1.92/linux/include/asm-sparc/io.h	Sun Feb  5 19:31:55 1995
+++ linux/include/asm-sparc/io.h	Mon Feb 20 08:59:52 1995
@@ -91,9 +91,9 @@
   unsigned long page_entry;
 
   page_entry = physaddr >> PAGE_SHIFT;
-  page_entry |= (PTE_V | PTE_ACC | PTE_W | PTE_P | PTE_IO);  /* kernel io addr */
+  page_entry |= (PTE_V | PTE_ACC | PTE_NC | PTE_IO);  /* kernel io addr */
 
-  put_pte(page_entry, virt_addr);
+  put_pte(virt_addr, page_entry);
   return;
 }
 
diff -u --recursive --new-file v1.1.92/linux/include/asm-sparc/pgtable.h linux/include/asm-sparc/pgtable.h
--- v1.1.92/linux/include/asm-sparc/pgtable.h	Sun Feb  5 19:31:55 1995
+++ linux/include/asm-sparc/pgtable.h	Mon Feb 20 08:59:52 1995
@@ -145,17 +145,31 @@
 
 extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_VALID; }
+extern inline int pte_inuse(pte_t *ptep)        { return mem_map[MAP_NR(ptep)] > 1; }
 extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
+extern inline void pte_reuse(pte_t *ptep)
+{
+  if(!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
+    mem_map[MAP_NR(ptep)]++;
+}
 
 extern inline int pmd_none(pmd_t pmd)		{ return !pmd_val(pmd); }
 extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; }
 extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd) & _PAGE_VALID; }
-extern inline void pmd_clear(pmd_t * pmdp)	{ pmd_val(*pmdp) = 0; }
+extern inline int pmd_inuse(pmd_t *pmdp)        { return 0; }
+extern inline void pmd_clear(pmd_t *pmdp)	{ pmd_val(*pmdp) = 0; }
+extern inline void pmd_reuse(pmd_t * pmdp)      { }
 
 extern inline int pgd_none(pgd_t pgd)		{ return !pgd_val(pgd); }
 extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & ~PAGE_MASK) != _PAGE_TABLE || pgd_val(pgd) > high_memory; }
 extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd) & _PAGE_VALID; }
+extern inline int pgd_inuse(pgd_t *pgdp)        { return mem_map[MAP_NR(pgdp)] > 1; }
 extern inline void pgd_clear(pgd_t * pgdp)	{ pgd_val(*pgdp) = 0; }
+extern inline void pgd_reuse(pgd_t *pgdp)
+{
+  if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED))
+    mem_map[MAP_NR(pgdp)]++;
+}
 
 /*
  * The following only work if pte_present() is true.
@@ -310,6 +324,15 @@
 extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
 {
 	return (pmd_t *) pgd;
+}
+
+extern inline void pgd_free(pgd_t *pgd)
+{
+  free_page((unsigned long) pgd);
+}
+extern inline pgd_t *pgd_alloc(void)
+{
+  return (pgd_t *) get_free_page(GFP_KERNEL);
 }
 
 extern pgd_t swapper_pg_dir[1024];
diff -u --recursive --new-file v1.1.92/linux/include/asm-sparc/system.h linux/include/asm-sparc/system.h
--- v1.1.92/linux/include/asm-sparc/system.h	Sun Feb  5 19:31:55 1995
+++ linux/include/asm-sparc/system.h	Mon Feb 20 08:59:52 1995
@@ -64,7 +64,7 @@
 retval; })
 
 #define cli()			swpipl(15)  /* 15 = no int's except nmi's */
-#define sti()			swpipl(0)   /* same as alpha */
+#define sti()			swpipl(0)   /* I'm scared */
 #define save_flags(flags)	do { flags = swpipl(15); } while (0)
 #define restore_flags(flags)	swpipl(flags)
 
diff -u --recursive --new-file v1.1.92/linux/include/linux/ip.h linux/include/linux/ip.h
--- v1.1.92/linux/include/linux/ip.h	Mon Jan 30 06:41:58 1995
+++ linux/include/linux/ip.h	Mon Feb 20 08:59:52 1995
@@ -49,6 +49,9 @@
 #elif defined(__alpha__)
 	__u8	flags:4,
 		overflow:4;
+#elif defined(__sparc__)
+	__u8	overflow:4,
+		flags:4;
 #else
 #error	"Adjust this structure to match your CPU"
 #endif						
@@ -96,6 +99,9 @@
 #elif defined(__alpha__)
 	__u8	ihl:4,
 		version:4;
+#elif defined (__sparc__)
+	__u8	version:4,
+  		ihl:4;
 #else
 #error "Adjust this structure to match your CPU"
 #endif
diff -u --recursive --new-file v1.1.92/linux/include/linux/tcp.h linux/include/linux/tcp.h
--- v1.1.92/linux/include/linux/tcp.h	Mon Jan 30 06:41:58 1995
+++ linux/include/linux/tcp.h	Mon Feb 20 08:59:52 1995
@@ -76,6 +76,16 @@
 		ack:1,
 		urg:1,
 		res2:2;
+#elif defined(__sparc__)
+	__u16	res2:2,
+		urg:1,
+		ack:1,
+		psh:1,
+		rst:1,
+		syn:1,
+		fin:1,
+		doff:4,
+		res1:4;
 #else
 #error	"Adjust this structure for your cpu alignment rules"
 #endif	
diff -u --recursive --new-file v1.1.92/linux/mm/kmalloc.c linux/mm/kmalloc.c
--- v1.1.92/linux/mm/kmalloc.c	Sun Feb  5 19:31:56 1995
+++ linux/mm/kmalloc.c	Mon Feb 20 08:49:05 1995
@@ -207,8 +207,11 @@
             page->nfree--;
             if (!page->nfree)
                 {
-                sizes[order].firstfree = page->next;
-                page->next = NULL;
+		  if(dma_flag)
+		    sizes[order].dmafree = page->next;
+		  else
+		    sizes[order].firstfree = page->next;
+		  page->next = NULL;
                 }
             restore_flags(flags);
 
diff -u --recursive --new-file v1.1.92/linux/mm/memory.c linux/mm/memory.c
--- v1.1.92/linux/mm/memory.c	Fri Feb 17 11:20:17 1995
+++ linux/mm/memory.c	Fri Feb 17 18:25:10 1995
@@ -502,7 +502,13 @@
 		end = PMD_SIZE;
 	do {
 		pte_t oldpage = *pte;
-		*pte = mk_pte(offset, prot);
+		pte_clear(pte);
+		if (offset >= high_memory || (mem_map[MAP_NR(offset)] & MAP_PAGE_RESERVED))
+			*pte = mk_pte(offset, prot);
+		else if (mem_map[MAP_NR(offset)]) {
+			mem_map[MAP_NR(offset)]++;
+			*pte = mk_pte(offset, prot);
+		}
 		forget_pte(oldpage);
 		address += PAGE_SIZE;
 		offset += PAGE_SIZE;
diff -u --recursive --new-file v1.1.92/linux/mm/swap.c linux/mm/swap.c
--- v1.1.92/linux/mm/swap.c	Fri Feb 17 11:20:17 1995
+++ linux/mm/swap.c	Mon Feb 20 09:29:10 1995
@@ -389,10 +389,10 @@
 #define SWAP_RATIO	128
 
 static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir,
-	unsigned long address, unsigned long size, unsigned long offset)
+	unsigned long address, unsigned long end)
 {
 	pte_t * pte;
-	unsigned long end;
+	unsigned long pmd_end;
 
 	if (pmd_none(*dir))
 		return 0;
@@ -401,21 +401,22 @@
 		pmd_clear(dir);
 		return 0;
 	}
+	
 	pte = pte_offset(dir, address);
-	offset += address & PMD_MASK;
-	address &= ~PMD_MASK;
-	end = address + size;
-	if (end > PMD_SIZE)
-		end = PMD_SIZE;
+	
+	pmd_end = (address + PMD_SIZE) & PMD_MASK;
+	if (end > pmd_end)
+		end = pmd_end;
+
 	do {
-		switch (try_to_swap_out(vma, offset+address-vma->vm_start, pte)) {
+		switch (try_to_swap_out(vma, address-vma->vm_start, pte)) {
 			case 0:
 				break;
 
 			case 1:
 				vma->vm_task->mm->rss--;
 				/* continue with the following page the next time */
-				vma->vm_task->mm->swap_address = address + offset + PAGE_SIZE;
+				vma->vm_task->mm->swap_address = address + PAGE_SIZE;
 				return 1;
 
 			default:
@@ -429,10 +430,10 @@
 }
 
 static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir,
-	unsigned long address, unsigned long size)
+	unsigned long address, unsigned long end)
 {
 	pmd_t * pmd;
-	unsigned long offset, end;
+	unsigned long pgd_end;
 
 	if (pgd_none(*dir))
 		return 0;
@@ -441,14 +442,15 @@
 		pgd_clear(dir);
 		return 0;
 	}
+
 	pmd = pmd_offset(dir, address);
-	offset = address & PGDIR_MASK;
-	address &= ~PGDIR_MASK;
-	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
+
+	pgd_end = (address + PGDIR_SIZE) & PGDIR_MASK;	
+	if (end > pgd_end)
+		end = pgd_end;
+	
 	do {
-		if (swap_out_pmd(vma, pmd, address, end - address, offset))
+		if (swap_out_pmd(vma, pmd, address, end))
 			return 1;
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
@@ -457,10 +459,13 @@
 }
 
 static int swap_out_vma(struct vm_area_struct * vma, pgd_t *pgdir,
-	unsigned long start, unsigned long end)
+	unsigned long start)
 {
+	unsigned long end;
+
+	end = vma->vm_end;
 	while (start < end) {
-		if (swap_out_pgd(vma, pgdir, start, end - start))
+		if (swap_out_pgd(vma, pgdir, start, end))
 			return 1;
 		start = (start + PGDIR_SIZE) & PGDIR_MASK;
 		pgdir++;
@@ -489,7 +494,7 @@
 		address = vma->vm_start;
 
 	for (;;) {
-		if (swap_out_vma(vma, pgd_offset(p, address), address, vma->vm_end))
+		if (swap_out_vma(vma, pgd_offset(p, address), address))
 			return 1;
 		vma = vma->vm_next;
 		if (!vma)
@@ -554,16 +559,29 @@
 
 static int try_to_free_page(int priority)
 {
+	static int state = 0;
 	int i=6;
 
-	while (i--) {
-		if (priority != GFP_NOBUFFER && shrink_buffers(i))
-			return 1;
-		if (shm_swap(i))
-			return 1;
-		if (swap_out(i))
-			return 1;
+	switch (state) {
+		do {
+		case 0:
+			if (priority != GFP_NOBUFFER && shrink_buffers(i)) {
+				state = 1;
+				return 1;
+			}
+		case 1:
+			if (shm_swap(i)) {
+				state = 2;
+				return 1;
+			}
+		case 2:
+			if (swap_out(i)) {
+				state = 0;
+				return 1;
+			}
+		} while(--i);
 	}
+	state = 2;
 	return 0;
 }
 
diff -u --recursive --new-file v1.1.92/linux/net/inet/af_inet.c linux/net/inet/af_inet.c
--- v1.1.92/linux/net/inet/af_inet.c	Wed Feb 15 10:36:40 1995
+++ linux/net/inet/af_inet.c	Sun Feb 19 11:59:15 1995
@@ -734,6 +734,20 @@
 	return(inet_create(newsock,((struct sock *)(oldsock->data))->protocol));
 }
 
+/*
+ * Return 1 if we still have things to send in our buffers.
+ */
+static inline int closing(struct sock * sk)
+{
+	switch (sk->state) {
+		case TCP_FIN_WAIT1:
+		case TCP_CLOSING:
+		case TCP_LAST_ACK:
+			return 1;
+	}
+	return 0;
+}
+
 
 /*
  *	The peer socket should always be NULL (or else). When we call this
@@ -772,8 +786,7 @@
 		cli();
 		if (sk->lingertime)
 			current->timeout = jiffies + HZ*sk->lingertime;
-		while(sk->state < TCP_LAST_ACK && sk->state!= TCP_FIN_WAIT2 &&
-		     sk->state != TCP_TIME_WAIT && current->timeout>0) 
+		while(closing(sk) && current->timeout>0) 
 		{
 			interruptible_sleep_on(sk->sleep);
 			if (current->signal & ~current->blocked) 
@@ -856,7 +869,7 @@
 			destroy_sock(sk2);
 			goto outside_loop;
 		}
-		if (!sk->reuse || sk2->state==TCP_LISTEN) 
+		if (!sk->reuse)
 		{
 			sti();
 			return(-EADDRINUSE);
@@ -866,7 +879,7 @@
 			continue;		/* more than one */
 		if (sk2->saddr != sk->saddr) 
 			continue;	/* socket per slot ! -FB */
-		if (!sk2->reuse) 
+		if (!sk2->reuse || sk2->state==TCP_LISTEN) 
 		{
 			sti();
 			return(-EADDRINUSE);
