diff -u --recursive --new-file v1.3.12/linux/CREDITS linux/CREDITS
--- v1.3.12/linux/CREDITS	Tue Jul 18 16:28:55 1995
+++ linux/CREDITS	Wed Jul 26 09:19:23 1995
@@ -15,6 +15,14 @@
 E: almesber@bernina.ethz.ch
 D: dosfs, LILO, some fd features, various other hacks here and there
 
+N: H. Peter Anvin
+E: Peter.Anvin@linux.org 
+D: Author of the SYSLINUX boot loader, maintainer of the linux.* news
+D: hierarchy, responsible for various console and other hacks
+S: 4390 Albany Dr. #46
+S: San Jose CA 95129
+S: USA
+
 N: Derek Atkins
 E: warlord@MIT.EDU
 D: Linux-AFS Port, random kernel hacker,
diff -u --recursive --new-file v1.3.12/linux/Makefile linux/Makefile
--- v1.3.12/linux/Makefile	Tue Jul 25 18:21:20 1995
+++ linux/Makefile	Tue Jul 25 17:50:39 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 12
+SUBLEVEL = 13
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.12/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- v1.3.12/linux/arch/alpha/kernel/osf_sys.c	Tue Jul 25 18:21:20 1995
+++ linux/arch/alpha/kernel/osf_sys.c	Tue Jul 25 18:24:10 1995
@@ -160,7 +160,7 @@
 	struct file * file = NULL;
 
 	if (flags & (MAP_HASSEMAPHORE | MAP_INHERIT | MAP_UNALIGNED))
-		printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, osf_flags);
+		printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, flags);
 	if (!(flags & MAP_ANONYMOUS)) {
 		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
 			return -EBADF;
diff -u --recursive --new-file v1.3.12/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v1.3.12/linux/arch/alpha/kernel/traps.c	Tue Jul 25 18:21:20 1995
+++ linux/arch/alpha/kernel/traps.c	Tue Jul 25 20:18:19 1995
@@ -142,7 +142,7 @@
 
 /*
  * Handle user-level unaligned fault.  For now, simply send a
- * SIGSEGV---there should be little reason for users not wanting to
+ * SIGBUS---there should be little reason for users not wanting to
  * fix their code instead.  Notice that we have the regular kernel
  * stack layout here, so finding the appropriate registers is a little
  * more difficult than in the kernel case.  Also, we'd need to do
@@ -153,7 +153,7 @@
 			      struct pt_regs regs)
 {
 	regs.pc -= 4;	/* make pc point to faulting insn */
-	send_sig(SIGSEGV, current, 1);
+	send_sig(SIGBUS, current, 1);
 }
 
 /*
diff -u --recursive --new-file v1.3.12/linux/drivers/char/psaux.c linux/drivers/char/psaux.c
--- v1.3.12/linux/drivers/char/psaux.c	Thu Jun 29 19:02:40 1995
+++ linux/drivers/char/psaux.c	Wed Jul 26 08:53:53 1995
@@ -12,13 +12,13 @@
  * Changed to prevent keyboard lockups on AST Power Exec.
  * 28Jul93  Brad Bosch - brad@lachman.com
  *
- * Modified by Johan Myreen (jem@cs.hut.fi) 04Aug93
+ * Modified by Johan Myreen (jempandora.pp.fi) 04Aug93
  *   to include support for QuickPort mouse.
  *
  * Changed references to "QuickPort" with "82C710" since "QuickPort"
  * is not what this driver is all about -- QuickPort is just a
  * connector type, and this driver is for the mouse port on the Chips
- * & Technologies 82C710 interface chip. 15Nov93 jem@cs.hut.fi
+ * & Technologies 82C710 interface chip. 15Nov93 jem@pandora.pp.fi
  */
 
 /* Uncomment the following line if your mouse needs initialization. */
@@ -103,6 +103,7 @@
 static int aux_busy = 0;
 static int aux_present = 0;
 static int poll_aux_status(void);
+static int poll_aux_status_nosleep(void);
 
 #ifdef CONFIG_82C710_MOUSE
 static int qp_present = 0;
@@ -121,9 +122,9 @@
 
 static void aux_write_dev(int val)
 {
-	poll_aux_status();
+	poll_aux_status_nosleep();
 	outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);	/* write magic cookie */
-	poll_aux_status();
+	poll_aux_status_nosleep();
 	outb_p(val,AUX_OUTPUT_PORT);		/* write data */
 }
 
@@ -137,13 +138,7 @@
         int retries = 0;
 
 	aux_write_dev(val);		/* write the value to the device */
-	while ((inb(AUX_STATUS) & AUX_OBUF_FULL) != AUX_OBUF_FULL
-	            && retries < MAX_RETRIES) {          /* wait for ack */
-       		current->state = TASK_INTERRUPTIBLE;
-		current->timeout = jiffies + (5*HZ + 99) / 100;
-		schedule();
-		retries++;
-        }
+	poll_aux_status_nosleep();
 
 	if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
 	{
@@ -451,14 +446,12 @@
 		psaux_fops.write = write_qp;
 		psaux_fops.open = open_qp;
 		psaux_fops.release = release_qp;
-		poll_qp_status();
 	} else
 #endif
 	if (aux_device_present == 0xaa) {
 	        printk("PS/2 auxiliary pointing device detected -- driver installed.\n");
          	aux_present = 1;
 		kbd_read_mask = AUX_OBUF_FULL;
-	        poll_aux_status();
 	} else {
 		return kmem_start;              /* No mouse at all */
 	}
@@ -474,11 +467,10 @@
 	        aux_write_ack(AUX_SET_RES);
 	        aux_write_ack(3);			/* 8 counts per mm */
 	        aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
-	        poll_aux_status();
+	        poll_aux_status_nosleep();
 #endif /* INITIALIZE_DEVICE */
         	outb_p(AUX_DISABLE,AUX_COMMAND);   /* Disable Aux device */
 	        aux_write_cmd(AUX_INTS_OFF);    /* disable controller ints */
-		poll_aux_status();
 	}
 	return kmem_start;
 }
@@ -496,6 +488,18 @@
 		retries++;
 	}
 	return !(retries==MAX_RETRIES);
+}
+
+static int poll_aux_status_nosleep(void)
+{
+	int retries = 0;
+
+	while ((inb(AUX_STATUS)&0x03) && retries < 1000000) {
+ 		if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
+			inb_p(AUX_INPUT_PORT);
+		retries++;
+	}
+	return !(retries == 1000000);
 }
 
 #ifdef CONFIG_82C710_MOUSE
diff -u --recursive --new-file v1.3.12/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v1.3.12/linux/drivers/net/ppp.c	Thu Jul 13 16:20:20 1995
+++ linux/drivers/net/ppp.c	Thu Jul 27 09:09:02 1995
@@ -1268,6 +1268,12 @@
         } else goto wait;
       }
 
+      i = verify_area (VERIFY_WRITE,buf,nr);
+      if (i != 0) {
+	ppp->us_rbuff_lock = 0;
+	return i;
+      }
+
       /* reset the time of the last read operation */
       ppp->ddinfo.nip_rjiffies = jiffies;
 
@@ -1309,6 +1315,12 @@
     current->timeout = 0;
     PRINTKN (3,(KERN_DEBUG "ppp_read: sleeping\n"));
     interruptible_sleep_on (&ppp->read_wait);
+
+    /* Ensure that the ppp device is still attached. */
+    ppp = ppp_find(tty);
+    if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse)
+      return 0;
+      
     if (current->signal & ~current->blocked)
       return -EINTR;
   } while (1);
@@ -1360,6 +1372,10 @@
     nr = ppp->mtu;
   }
 
+  i = verify_area (VERIFY_READ,buf,nr);
+  if (i != 0)
+    return i;
+
   if (ppp_debug >= 3)
     ppp_print_buffer ("write frame", buf, nr, USER_DS);
 
@@ -1369,6 +1385,12 @@
     current->timeout = 0;
     PRINTKN (3,(KERN_DEBUG "ppp_write: sleeping\n"));
     interruptible_sleep_on(&ppp->write_wait);
+
+    /* Ensure that the ppp device is still attached. */
+    ppp = ppp_find(tty);
+    if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse)
+      return 0;
+
     if (current->signal & ~current->blocked)
       return -EINTR;
   }
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog
--- v1.3.12/linux/drivers/scsi/ChangeLog	Thu Jun 29 19:02:44 1995
+++ linux/drivers/scsi/ChangeLog	Tue Jul 25 17:50:13 1995
@@ -1,4 +1,83 @@
+Wed Jul 19 10:43:15 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+        * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all
+	attached devices.
+
+	* scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and
+	eata_dma_proc.c to produce some device info for /proc/scsi.
+
+	* eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done):
+	Changed handling of internal SCSI commands send to the HBA.
+
+
+Wed Jul 19 10:09:17 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.11 released.
+
+	* eata_dma.c (eata_queue)(eata_int_handler): Added code to do
+	command latency measurements if requested by root through
+	/proc/scsi interface. 
+	Throughout Use HZ constant for time references.
+
+	* eata_pio.c: Use HZ constant for time references. 
+
+	* aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD
+	to GNU style.
+
+	* scsi.h: Added READ_12 command opcode constant
+
+Wed Jul 19 09:25:30 1995  Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.10 released.
+
+	* scsi_proc.c (dispatch_scsi_info): Removed unused variable.	
+
+Wed Jul 19 09:25:30 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.9 released.
+
+	* scsi.c Blacklist concept expanded to 'support' more device
+	deficiencies. blacklist[] renamed to device_list[]
+	(scan_scsis): Code cleanup.  
+	
+	* scsi_debug.c (scsi_debug_proc_info): Added support to control
+	device lockup simulation via /proc/scsi interface.  
+	
+
+Wed Jul 19 09:22:34 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.7 released.
+
+	* scsi_proc.c: Fixed a number of bugs in directory handling
+
+Wed Jul 19 09:18:28 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.5 released.
+
+	* Native wide, multichannel and /proc/scsi support now in official
+	kernel distibution.
+ 
+        * scsi.c/h, hosts.c/h et al reindended to increase readability
+	(especially on 80 column wide terminals).
+
+	* scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added
+	/proc/scsi/scsi which allows root to scan for hotplugged devices.
+
+	* scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi.
+	(scan_scsis): Added some 'spagetti' code to allow scanning for
+	single devices.
+	
+
+Thu Jun 20 15:20:27 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+        * proc.c: Renamed to scsi_proc.c 
+
+Mon Jun 12 20:32:45 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.0 released.
+
 Mon May 15 19:33:14 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
 	* scsi.c: Added native multichannel and wide scsi support. 
 
 	* proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries): 
@@ -6,13 +85,13 @@
 
 Thu May  4 17:58:48 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
 
-	* sd.c (requeue_sd_request): zero out the scatterlist only if
+	* sd.c (requeue_sd_request): Zero out the scatterlist only if
 	scsi_malloc returned memory for it.	
 
-	* eata_dma.c (register_HBA) (eata_queue): add support for
+	* eata_dma.c (register_HBA) (eata_queue): Add support for
 	large scatter/gatter tables and set use_clustering accordingly
 
-	* hosts.c: make use_clustering changable in the Scsi_Host structure.
+	* hosts.c: Make use_clustering changable in the Scsi_Host structure.
 
 Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
 
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v1.3.12/linux/drivers/scsi/eata_dma.c	Tue Jul 18 16:28:58 1995
+++ linux/drivers/scsi/eata_dma.c	Tue Jul 25 17:50:13 1995
@@ -48,7 +48,7 @@
  * Thanks also to Greg Hosler who did a lot of testing and  *
  * found quite a number of bugs during the development.	    *
  ************************************************************
- *  last change: 95/07/11		   OS: Linux 1.3.9  *
+ *  last change: 95/07/18                 OS: Linux 1.3.10  *
  ************************************************************/
 
 /* Look in eata_dma.h for configuration and revision information */
@@ -94,22 +94,27 @@
 static struct eata_sp *status = 0;   /* Statuspacket array   */
 static void *dma_scratch = 0;
 
-static uint internal_command_finished = TRUE;
-static unchar HBA_interpret = FALSE;
 static u32 fake_int_base;
-static u32 fake_int_result;
+static int fake_int_result;
+static int fake_int_happened;
 
 static ulong int_counter = 0;
 static ulong queue_counter = 0;
 
-void eata_scsi_done (Scsi_Cmnd * SCpnt)
+void eata_scsi_done (Scsi_Cmnd * scmd)
 {
+    scmd->request.dev = 0xfffe;
+
+    if (scmd->request.sem != NULL)
+	up(scmd->request.sem);
+    
     return;
 }   
 
 void eata_fake_int_handler(s32 irq, struct pt_regs * regs)
 {
     fake_int_result = inb(fake_int_base + HA_RSTATUS);
+    fake_int_happened = TRUE;
     DBG(DBG_INTR3, printk("eata_fake_int_handler called irq%d base %#x"
 			  " res %#x\n", irq, fake_int_base, fake_int_result));
     return;
@@ -141,11 +146,6 @@
 }
 #endif
 
-const char *eata_info(struct Scsi_Host *host)
-{
-    static char *information = "EATA SCSI HBA Driver";
-    return information;
-}
 
 void eata_int_handler(int irq, struct pt_regs * regs)
 {
@@ -172,7 +172,7 @@
 	
 	sp=&SD(sh)->sp;
 	
-	cp = sp->ccb;
+	cp = sp->ccb; /* Has been passed thru, no conversion needed */
 	cmd = cp->cmd;
 	base = (uint) cmd->host->base;
 	
@@ -290,15 +290,7 @@
 #endif
 	
 	cp->status = FREE;	    /* now we can release the slot  */
-	
-	restore_flags(flags);
-	if(cmd->scsi_done != eata_scsi_done) cmd->scsi_done(cmd);
-	else {
-	    internal_command_finished = TRUE;
-	    HBA_interpret = FALSE;
-	}
-	save_flags(flags);
-	cli();
+	cmd->scsi_done(cmd);
     }
     restore_flags(flags);
     
@@ -312,7 +304,8 @@
     while (inb(base + HA_RAUXSTAT) & HA_ABUSY)
 	if (--loop == 0)
 	    return(FALSE);
-    
+
+    /* And now the address in nice little byte chunks */
     outb( addr & 0x000000ff,	    base + HA_WDMAADDR);
     outb((addr & 0x0000ff00) >> 8,  base + HA_WDMAADDR + 1);
     outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
@@ -321,7 +314,7 @@
     return(TRUE);
 }
 
-#if 0
+#if 0 
 inline int eata_send_immediate(u32 addr, u32 base, u8 cmnd, u8 cmnd2, u8 id, 
 			       u8 lun)
 {
@@ -354,14 +347,7 @@
     cli();
     
     queue_counter++;
-    
-    if (done == (void *)eata_scsi_done) { 
-	if (internal_command_finished == TRUE)
-	    internal_command_finished = FALSE;
-	else 
-	    cmd->result = (DID_ERROR << 16) + QUEUE_FULL;
-    }
-    
+
     hd = HD(cmd);
     sh = cmd->host;
     
@@ -448,35 +434,37 @@
     default:
 	cp->DataIn = TRUE;	/* Input mode  */
     }
-    
-    if ((done == (void *) eata_scsi_done && HBA_interpret == TRUE) 
-	|| cmd->target == sh->this_id) 
+
+    /* FIXME: This will will have to be changed once the midlevel driver 
+     *        allows different HBA IDs on every channel.
+     */
+    if (cmd->target == sh->this_id) 
 	cp->Interpret = TRUE;	/* Interpret command */
-    
+
     if (cmd->use_sg) {
 	cp->scatter = TRUE;	/* SG mode     */
 	if (cp->sg_list == NULL) {
 	    cp->sg_list = kmalloc(SG_SIZE_BIG*sizeof(struct eata_sg_list),
 				  GFP_ATOMIC | GFP_DMA);
 	}
-	cp->cp_dataDMA = htonl((ulong)cp->sg_list); 
-	if (cp->cp_dataDMA == 0)
+	if (cp->sg_list == NULL)
 	    panic("eata_dma: Run out of DMA memory for SG lists !\n");
+	cp->cp_dataDMA = htonl(virt_to_bus(cp->sg_list)); 
 	
 	cp->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list));
 	sl=(struct scatterlist *)cmd->request_buffer;
 	for(i = 0; i < cmd->use_sg; i++, sl++){
-	    cp->sg_list[i].data = htonl((u32) sl->address);
+	    cp->sg_list[i].data = htonl(virt_to_bus(sl->address));
 	    cp->sg_list[i].len = htonl((u32) sl->length);
 	}
     } else {
 	cp->scatter = FALSE;
 	cp->cp_datalen = htonl(cmd->request_bufflen);
-	cp->cp_dataDMA = htonl((u32)cmd->request_buffer);
+	cp->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer));
     }
     
     cp->Auto_Req_Sen = TRUE;
-    cp->cp_reqDMA = htonl((u32) cmd->sense_buffer);
+    cp->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer));
     cp->reqlen = sizeof(cmd->sense_buffer);
     
     cp->cp_id = cmd->target;
@@ -486,9 +474,9 @@
     cp->cp_identify = TRUE;
     memcpy(cp->cp_cdb, cmd->cmnd, cmd->cmd_len);
     
-    cp->cp_statDMA = htonl((u32) &(hd->sp));
+    cp->cp_statDMA = htonl(virt_to_bus(&(hd->sp)));
     
-    cp->cp_viraddr = cp;
+    cp->cp_viraddr = cp; /* This will be passed thru, so we don't need to convert it */
     cp->cmd = cmd;
     cmd->host_scribble = (char *)&hd->ccb[y];	
     
@@ -496,16 +484,17 @@
 	cmd->result = DID_ERROR << 16;
 	printk("eata_queue target %d, pid %ld, HBA busy, returning DID_ERROR,"
 	       " done.\n", cmd->target, cmd->pid);
+
 	restore_flags(flags);
-	if(done != (void *)eata_scsi_done) done(cmd);
-	return (0);
+	done(cmd);
+	return(0);
     }
     DBG(DBG_QUEUE,printk("Queued base %#.4x pid: %ld target: %x lun: %x "
 			 "slot %d irq %d\n", (s32)sh->base, cmd->pid, 
 			 cmd->target, cmd->lun, y, sh->irq));
     DBG(DBG_QUEUE && DBG_DELAY, DEL2(200));
     restore_flags(flags);
-    return (0);
+    return(0);
 }
 
 
@@ -626,8 +615,8 @@
     restore_flags(flags);
     
     time = jiffies;
-    while (jiffies < (time + (3 * HZ)) && limit++ < 10000000)
-	/* nothing */;
+    while (jiffies < (time + (3 * HZ)) || limit++ < 10000000)
+	/* As time goes by... */;
     
     save_flags(flags);
     cli();
@@ -691,9 +680,12 @@
 
     cp->DataIn = TRUE;	   
     cp->Interpret = TRUE;   /* Interpret command */
+    cp->cp_dispri = TRUE;
+    cp->cp_identify = TRUE;
  
-    cp->cp_datalen = htonl(255);  
-    cp->cp_dataDMA = htonl((s32)buff);
+    cp->cp_datalen = htonl(56);  
+    cp->cp_dataDMA = htonl(virt_to_bus(buff));
+    cp->cp_statDMA = htonl(virt_to_bus(sp));
     cp->cp_viraddr = cp;
     
     cp->cp_id = id;
@@ -703,23 +695,22 @@
     cp->cp_cdb[1] = 0;
     cp->cp_cdb[2] = 0;
     cp->cp_cdb[3] = 0;
-    cp->cp_cdb[4] = 255;
+    cp->cp_cdb[4] = 56;
     cp->cp_cdb[5] = 0;
 
-    cp->cp_statDMA = htonl((ulong) sp);
-
     fake_int_base = base;
-    fake_int_result = 0;
+    fake_int_result = FALSE;
+    fake_int_happened = FALSE;
 
     eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP);
     
-    i = jiffies + (3 * HZ) ;
-    while (fake_int_result == FALSE && jiffies <= i) 
+    i = jiffies + (3 * HZ);
+    while (fake_int_happened == FALSE && jiffies <= i) 
 	barrier();
     
     DBG(DBG_INTR3, printk("fake_int_result: %#x hbastat %#x scsistat %#x,"
 			  " buff %p sp %p\n",
-			  fake_int_result, (u32) (sp->hba_stat & 0x7f), 
+			  fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/), 
 			  (u32) sp->scsi_stat, buff, sp));
 
     scsi_init_free((void *)cp, sizeof(struct eata_ccb));
@@ -730,7 +721,7 @@
 	inb((u32) (base) + HA_RSTATUS);
 	eata_send_command(0, base, EATA_CMD_RESET);
 	i = jiffies;
-	while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
+	while (jiffies < (i + (3 * HZ)) && limit++ < 10000000) 
 	    barrier();
 	return (NULL);
     } else
@@ -881,13 +872,17 @@
 	}
     }
  
-    if (bustype != IS_EISA)
+#if !(NEWSTUFF)
+    if (bustype != IS_EISA && bustype != IS_ISA)
+#endif
 	buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]);
 
     if (buff == NULL) {
-	if (bustype == IS_EISA) {
+#if !(NEWSTUFF)
+	if (bustype == IS_EISA || bustype == IS_ISA) {
 	    bugs = bugs || BROKEN_INQUIRY;
 	} else {
+#endif
 	    if (gc->DMA_support == FALSE)
 		printk("HBA at %#.4x doesn't support DMA. Sorry\n", base);
 	    else
@@ -901,7 +896,9 @@
 	    if (gc->IRQ_TR == FALSE)
 		reg_IRQL[gc->IRQ] = FALSE; 
 	    return (FALSE);
+#if !(NEWSTUFF)
 	}
+#endif
     }
     
     if (gc->DMA_support == FALSE && buff != NULL)  
@@ -916,7 +913,7 @@
     if(ntohs(gc->queuesiz) == 0) {
 	gc->queuesiz = ntohs(64);
 	printk("Warning: Queue size has to be corrected. Assuming 64 queueslots\n"
-	       "	 This might be a PM2012B with a defective Firmware\n");
+	       "         This might be a PM2012B with a defective Firmware\n");
     }
 
     size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long)) 
@@ -996,8 +993,8 @@
 	hd->bustype = bustype;
     
     if(ntohl(gc->len) >= 0x22) {
-	sh->max_id = gc->MAX_ID;
-	sh->max_lun = gc->MAX_LUN;
+	sh->max_id = gc->MAX_ID + 1;
+	sh->max_lun = gc->MAX_LUN + 1;
     } else {
 	sh->max_id = 8;
 	sh->max_lun = 8;
@@ -1015,14 +1012,15 @@
      * SCSI midlevel code should support different HBA ids on every channel
      */
     sh->this_id = gc->scsi_id[3];
-    sh->can_queue = ntohs(gc->queuesiz) - 1; /* Keep one free for internals */
+    sh->can_queue = ntohs(gc->queuesiz);
     
-    if (gc->OCS_enabled == TRUE) 
+    if (gc->OCS_enabled == TRUE) {
 	if(hd->bustype != IS_ISA)
 	    sh->cmd_per_lun = sh->can_queue/C_P_L_DIV; 
 	else
-	    sh->cmd_per_lun = 8;
-    else 
+	    sh->cmd_per_lun = 8; /* We artificially limit this to conserve memory, 
+				  * which would be needed for ISA bounce buffers */
+    } else 
 	sh->cmd_per_lun = 1;
     
     /* FIXME:
@@ -1175,14 +1173,15 @@
 					       (u16 *) & com_adr))) {
 			if (!((com_adr & PCI_COMMAND_IO) && 
 			      (com_adr & PCI_COMMAND_MASTER))) {
-			    printk("HBA has IO or BUSMASTER mode disabled\n");
+			    printk("eata_dma: HBA has IO or BUSMASTER mode disabled\n");
 			    continue;
 			}
 		    } else
 			printk("eata_dma: error %x while reading "
 			       "PCI_COMMAND\n", error);
 		} else
-		    printk("DEVICECLASSID %x didn't match\n", rev_device);
+		    printk("eata_dma: DEVICECLASSID %x didn't match\n", 
+			   rev_device);
 	    } else {
 		printk("eata_dma: error %x while reading PCI_CLASS_BASE\n", 
 		       error);
@@ -1219,10 +1218,8 @@
 					break;
 				    }
 				}
-			    } else if ((base & 0x0fff) == 0x0c88) {
-				x = (base >> 12) & 0x0f;
-				EISAbases[x] = 0;
-			    }
+			    } else if ((base & 0x0fff) == 0x0c88) 
+				EISAbases[(base >> 12) & 0x0f] = 0;
 			    continue;  /* break; */
 			} else if (check_blink_state(base) == TRUE) {
 			    printk("eata_dma: HBA is in BLINK state.\n"
@@ -1230,14 +1227,16 @@
 			}
 		    }
 		}
-	    } else
+	    } else {
 		printk("eata_dma: error %x while reading "
 		       "PCI_BASE_ADDRESS_0\n", error);
+	    }
 	}
-    } else
+    } else {
 	printk("eata_dma: No BIOS32 extensions present. This driver release "
 	       "still depends on it.\n"
 	       "	  Skipping scan for PCI HBAs. \n");
+    }
 #endif /* #ifndef CONFIG_PCI */
     return;
 }
@@ -1254,18 +1253,23 @@
     status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
     dma_scratch = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
 
+    if(status == NULL || dma_scratch == NULL) {
+	printk("eata_dma: can't allocate enough memory to probe for hosts !\n");
+	return(0);
+    }
+
     find_PCI(&gc, tpnt);
     
     find_EISA(&gc, tpnt);
     
     find_ISA(&gc, tpnt);
     
-    for (i = 0; i <= MAXIRQ; i++)
-	if (reg_IRQ[i]){
-	    free_irq(i);
+    for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we     */
+	if (reg_IRQ[i]){            /* exchange the interrupt handler which  */
+	    free_irq(i);            /* we used for probing with the real one */
 	    request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma");
 	}
-    
+    }
     HBA_ptr = first_HBA;
     
     if (registered_HBAs != 0) {
@@ -1277,7 +1281,7 @@
 	printk("\nHBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: DMA: Ch: "
 	       "ID: Pr: QS: SG: CPL:\n");
 	for (i = 1; i <= registered_HBAs; i++) {
-	    printk("scsi%-2d: %.10s v%s 2.0%c  %s %#.4x	  %2d",
+	    printk("scsi%-2d: %.10s v%s 2.0%c  %s %#.4x   %2d",
 		   HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
 		   SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? 
 		   "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
@@ -1286,7 +1290,7 @@
 		printk("   %2x ", HBA_ptr->dma_channel);
 	    else
 		printk("  %s", "BMST");
-	    printk("  %d   %d	%c  %2d	 %2d   %2d\n", SD(HBA_ptr)->channel, 
+	    printk("  %d   %d   %c  %2d  %2d   %2d\n", SD(HBA_ptr)->channel, 
 		   HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N', 
 		   HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
 	    HBA_ptr = SD(HBA_ptr)->next;
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/eata_dma.h linux/drivers/scsi/eata_dma.h
--- v1.3.12/linux/drivers/scsi/eata_dma.h	Tue Jul 18 16:28:58 1995
+++ linux/drivers/scsi/eata_dma.h	Tue Jul 25 17:50:13 1995
@@ -2,7 +2,7 @@
 * Header file for eata_dma.c Linux EATA-DMA SCSI driver *
 * (c) 1993,94,95 Michael Neuffer                        *
 *********************************************************
-* last change: 95/06/20                                 *
+* last change: 95/07/18                                 *
 ********************************************************/
 
 
@@ -16,7 +16,7 @@
 
 #define VER_MAJOR 2
 #define VER_MINOR 5
-#define VER_SUB   "7a"
+#define VER_SUB   "7b"
 
 
 /************************************************************************
@@ -24,6 +24,7 @@
  ************************************************************************/
 
 #define CHECKPAL        0        /* EISA pal checking on/off            */
+#define NEWSTUFF        1        /* Some changes for ISA/EISA boards    */
 
 /************************************************************************
  * Debug options.                                                       * 
@@ -74,10 +75,10 @@
 
 #define EATA_DMA {                   \
 	NULL, NULL,                  \
-	eata_proc_info,/* procinfo */        \
-	"eata_dma",    /* proc dir entry */  \
-	PROC_SCSI_EATA,/* proc dir inode */  \
-	"EATA (Extended Attachment) driver", \
+	eata_proc_info,/* procinfo       */      \
+	"eata_dma",    /* proc dir entry */      \
+	PROC_SCSI_EATA,/* proc dir inode */      \
+	"EATA (Extended Attachment) HBA driver", \
 	eata_detect,                 \
 	eata_release,                \
 	NULL, NULL,                  \
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/eata_dma_proc.c linux/drivers/scsi/eata_dma_proc.c
--- v1.3.12/linux/drivers/scsi/eata_dma_proc.c	Tue Jul 18 16:28:58 1995
+++ linux/drivers/scsi/eata_dma_proc.c	Tue Jul 25 17:50:13 1995
@@ -1,18 +1,5 @@
-
-#define MAX_SCSI_DEVICE_CODE 10
-const char *const scsi_dev_types[MAX_SCSI_DEVICE_CODE] =
-{
-    "Direct-Access    ",
-    "Sequential-Access",
-    "Printer	      ",
-    "Processor	      ",
-    "WORM	      ",
-    "CD-ROM	      ",
-    "Scanner	      ",
-    "Optical Device   ",
-    "Medium Changer   ",
-    "Communications   "
-};
+extern void proc_print_scsidevice(Scsi_Device *scd, char *buffer, 
+				  int *size, int len);
 
 
 void swap_statistics(u8 *p)
@@ -47,22 +34,24 @@
  */
 int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr)
 {
+    int orig_length = length;
+
     if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) {
-        buffer += 9;
-        length -= 9;
-        if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
-            SD(HBA_ptr)->do_latency = TRUE;
-            return(length+9);
-        } 
-        
-        if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
-            SD(HBA_ptr)->do_latency = FALSE;
-            return(length+9);
-        } 
-        
-        printk("Unknown command:%s length: %d\n", buffer, length);
+	buffer += 9;
+	length -= 9;
+	if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
+	    SD(HBA_ptr)->do_latency = TRUE;
+	    return(orig_length);
+	} 
+	
+	if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
+	    SD(HBA_ptr)->do_latency = FALSE;
+	    return(orig_length);
+	} 
+	
+	printk("Unknown command:%s length: %d\n", buffer, length);
     } else 
-        printk("Wrong Signature:%10s\n", (char *) ((ulong)buffer-9));
+	printk("Wrong Signature:%10s\n", buffer);
     
     return(-EINVAL);
 }
@@ -70,21 +59,22 @@
 /*
  * eata_proc_info
  * inout : decides on the direction of the dataflow and the meaning of the 
- *         variables
+ *	   variables
  * buffer: If inout==FALSE data is beeing written to it else read from it
  * *start: If inout==FALSE start of the valid data in the buffer
  * offset: If inout==FALSE offset from the beginning of the imaginary file 
- *         from which we start writing into the buffer
+ *	   from which we start writing into the buffer
  * length: If inout==FALSE max number of bytes to be written into the buffer 
- *         else number of bytes in the buffer
+ *	   else number of bytes in the buffer
  */
 int eata_proc_info(char *buffer, char **start, off_t offset, int length, 
-                   int hostno, int inout)
+		   int hostno, int inout)
 {
 
-    Scsi_Device *scd;
+    Scsi_Device *scd, SDev;
     struct Scsi_Host *HBA_ptr;
     Scsi_Cmnd scmd;
+    char cmnd[10];
     static u8 buff[512];
     static u8 buff2[512];
     hst_cmd_stat *rhcs, *whcs;
@@ -162,34 +152,59 @@
 	size = sprintf(buffer + len, "Host Bus: EISA\n"); 
 	len += size; 
 	pos = begin + len;
+
     } else {
+	memset(&SDev, 0, sizeof(Scsi_Device));
+	memset(&scmd, 0, sizeof(Scsi_Cmnd));
+
+	SDev.host = HBA_ptr;
+	SDev.id = HBA_ptr->this_id;
+	SDev.lun = 0;
+	SDev.channel = 0;
+
+	cmnd[0] = LOG_SENSE;
+	cmnd[1] = 0;
+	cmnd[2] = 0x33 + (3<<6);
+	cmnd[3] = 0;
+	cmnd[4] = 0;
+	cmnd[5] = 0;
+        cmnd[6] = 0;
+	cmnd[7] = 0x00;
+	cmnd[8] = 0x66;
+	cmnd[9] = 0;
 
-	scmd.cmnd[0] = LOG_SENSE;
-	scmd.cmnd[1] = 0;
-	scmd.cmnd[2] = 0x33 + (3<<6);
-	scmd.cmnd[3] = 0;
-	scmd.cmnd[4] = 0;
-	scmd.cmnd[5] = 0;
-	scmd.cmnd[6] = 0;
-	scmd.cmnd[7] = 0x00;
-	scmd.cmnd[8] = 0x66;
-	scmd.cmnd[9] = 0;
 	scmd.cmd_len = 10;
 	
 	scmd.host = HBA_ptr; 
+	scmd.device = &SDev;
 	scmd.target = HBA_ptr->this_id; 
 	scmd.lun = 0; 
 	scmd.channel = 0;
-	
 	scmd.use_sg = 0;
-	scmd.request_bufflen = 0x66;
-	scmd.request_buffer = buff + 0x144;
-	HBA_interpret = TRUE;
-	
-	eata_queue(&scmd, (void *) eata_scsi_done);
-	while (internal_command_finished == FALSE)
-	    barrier();
-	
+
+	/* Used for mutex if loading devices after boot */
+	scmd.request.sem = NULL;
+	scmd.request.dev = 0xffff; /* Mark busy */
+	
+	scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66,  
+		     eata_scsi_done, 1 * HZ, 1);
+	/*
+	 * Wait for command to finish. Use simple wait if we are
+	 * booting, else do it right and use a mutex
+	 */	
+	if (current->pid == 0) {
+	    while (scmd.request.dev != 0xfffe)
+		barrier();
+	} else if (scmd.request.dev != 0xfffe) {
+	    struct semaphore sem = MUTEX_LOCKED;
+	    
+	    scmd.request.sem = &sem;
+	    down(&sem);
+	    
+	    /* Hmm.. Have to ask about this one */
+	    while (scmd.request.dev != 0xfffe) schedule();
+	}
+
 	size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt,
 		       (cc->intt == TRUE)?"level":"edge");
 	len += size; 
@@ -220,7 +235,7 @@
 		       (sb->ext == TRUE)?"With external cable detection":"");
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "SCSI channel expansion Module: %s installed\n",
+	size = sprintf(buffer + len, "SCSI channel expansion Module: %s present\n",
 		       (bt->sx1 == TRUE)?"SX1 (one channel)":
 		       ((bt->sx2 == TRUE)?"SX2 (two channels)":"not"));
 	len += size; 
@@ -229,7 +244,7 @@
 		       (cc->srs == TRUE)?"":"not ");
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "	  Type: %s\n",
+	size = sprintf(buffer + len, "    Type: %s\n",
 		       ((cc->key == TRUE)?((bt->dmi == TRUE)?"integrated"
 					   :((bt->dm4 == TRUE)?"DM401X"
 					   :(bt->dm4k == TRUE)?"DM4000"
@@ -238,23 +253,23 @@
 	len += size; 
 	pos = begin + len;
 	
-	size = sprintf(buffer + len, "	  Max array groups:		 %d\n",
+	size = sprintf(buffer + len, "    Max array groups:              %d\n",
 		       (al->code == 0x0e)?al->max_groups:7);
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "	  Max drives per RAID 0 array:	 %d\n",
+	size = sprintf(buffer + len, "    Max drives per RAID 0 array:   %d\n",
 		       (al->code == 0x0e)?al->raid0_drv:7);
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "	  Max drives per RAID 3/5 array: %d\n",
+	size = sprintf(buffer + len, "    Max drives per RAID 3/5 array: %d\n",
 		       (al->code == 0x0e)?al->raid35_drv:7);
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "Cache Module: %sinstalled.\n",
+	size = sprintf(buffer + len, "Cache Module: %spresent.\n",
 		       (cc->csh)?"":"not ");
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "	  Type: %s\n",
+	size = sprintf(buffer + len, "    Type: %s\n",
 		       ((cc->csh == TRUE)?((bt->cmi == TRUE)?"integrated"
 					 :((bt->cm4 == TRUE)?"CM401X"
 					 :((bt->cm4k == TRUE)?"CM4000"
@@ -269,20 +284,20 @@
 	    len += size; 
 	    pos = begin + len;	    
 	}   
-	size = sprintf(buffer + len, "Timer Modification: %sinstalled\n",
+	size = sprintf(buffer + len, "Timer Mod.: %spresent\n",
 		       (cc->tmr == TRUE)?"":"not ");
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "NVRAM: %spresent\n",
+	size = sprintf(buffer + len, "NVRAM     : %spresent\n",
 		       (cc->nvr == TRUE)?"":"not ");
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "SmartROM: %senabled\n",
-		       (bt->srom == TRUE)?"not ":"");
+	size = sprintf(buffer + len, "SmartROM  : %sabled\n",
+		       (bt->srom == TRUE)?"dis":"en");
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer + len, "HBA indicates %salarm.\n",
-		       (bt->alrm == TRUE)?"":"no ");
+	size = sprintf(buffer + len, "Alarm     : %s\n",
+		       (bt->alrm == TRUE)?"on":"off");
 	len += size; 
 	pos = begin + len;
 	
@@ -293,29 +308,41 @@
 	if (pos > offset + length)
 	    goto stop_output; 
 	
-	scmd.cmnd[0] = LOG_SENSE;
-	scmd.cmnd[1] = 0;
-	scmd.cmnd[2] = 0x32 + (3<<6); 
-	scmd.cmnd[3] = 0;
-	scmd.cmnd[4] = 0;
-	scmd.cmnd[5] = 0;
-	scmd.cmnd[6] = 0;
-	scmd.cmnd[7] = 0x01;
-	scmd.cmnd[8] = 0x44;
-	scmd.cmnd[9] = 0;
+	cmnd[0] = LOG_SENSE;
+	cmnd[1] = 0;
+	cmnd[2] = 0x32 + (3<<6); 
+	cmnd[3] = 0;
+	cmnd[4] = 0;
+	cmnd[5] = 0;
+	cmnd[6] = 0;
+	cmnd[7] = 0x01;
+	cmnd[8] = 0x44;
+	cmnd[9] = 0;
+ 
 	scmd.cmd_len = 10;
-	scmd.host = HBA_ptr; 
-	scmd.target = HBA_ptr->this_id; 
-	scmd.lun = 0; 
-	scmd.channel = 0;
-	scmd.use_sg = 0;
-	scmd.request_bufflen = 0x144;
-	scmd.request_buffer = buff2;
-	HBA_interpret = TRUE;
-	
-	eata_queue(&scmd, (void *) eata_scsi_done);
-	while (internal_command_finished == FALSE)
-	    barrier();
+
+	/* Used for mutex if loading devices after boot */
+	scmd.request.sem = NULL;
+	scmd.request.dev = 0xffff; /* Mark busy */
+	
+	scsi_do_cmd (&scmd, cmnd, buff2, 0x144,  
+		     eata_scsi_done, 1 * HZ, 1);
+	/*
+	 * Wait for command to finish. Use simple wait if we are
+	 * booting, else do it right and use a mutex
+	 */	
+	if (current->pid == 0)
+	    while (scmd.request.dev != 0xfffe)
+		barrier();
+	else if (scmd.request.dev != 0xfffe) {
+	    struct semaphore sem = MUTEX_LOCKED;
+	    
+	    scmd.request.sem = &sem;
+	    down(&sem);
+	    
+	    /* Hmm.. Have to ask about this one */
+	    while (scmd.request.dev != 0xfffe) schedule();
+	}
 	
 	swap_statistics(buff2);
 	rhcs = (hst_cmd_stat *)(buff2 + 0x2c); 
@@ -327,8 +354,8 @@
 	    SD(HBA_ptr)->reads[12] += rhcs->sizes[x];
 	    SD(HBA_ptr)->writes[12] += whcs->sizes[x];
 	}
-	size = sprintf(buffer + len, "Host Disk Command Statistics:\n"
-		       "	 Reads:	     Writes:\n");
+	size = sprintf(buffer + len, "Host<->Disk command statistics:\n"
+		       "         Reads:	     Writes:\n");
 	len += size; 
 	pos = begin + len;
 	for (x = 0; x <= 10; x++) {
@@ -359,75 +386,75 @@
 
     if(SD(HBA_ptr)->do_latency == TRUE) {
 	size = sprintf(buffer + len, "Host Latency Command Statistics:\n"
-                       "Current timer resolution: 10ms\n"
-		       "	 Reads:	      Min:(ms)     Max:(ms)     Ave:(ms)\n");
+		       "Current timer resolution: 10ms\n"
+		       "         Reads:	      Min:(ms)     Max:(ms)     Ave:(ms)\n");
 	len += size; 
 	pos = begin + len;
 	for (x = 0; x <= 10; x++) {
 	    size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
-                           1 << x,
+			   1 << x,
 			   SD(HBA_ptr)->reads_lat[x][0], 
 			   (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff) 
-                           ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10), 
+			   ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10), 
 			   SD(HBA_ptr)->reads_lat[x][2] * 10, 
 			   SD(HBA_ptr)->reads_lat[x][3] * 10 /
-                           ((SD(HBA_ptr)->reads_lat[x][0])
-                            ? SD(HBA_ptr)->reads_lat[x][0]:1));
+			   ((SD(HBA_ptr)->reads_lat[x][0])
+			    ? SD(HBA_ptr)->reads_lat[x][0]:1));
 	    len += size; 
 	    pos = begin + len;
 	}
 	size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
 			   SD(HBA_ptr)->reads_lat[11][0], 
 			   (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
-                           ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10), 
+			   ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10), 
 			   SD(HBA_ptr)->reads_lat[11][2] * 10, 
 			   SD(HBA_ptr)->reads_lat[11][3] * 10 /
-                           ((SD(HBA_ptr)->reads_lat[x][0])
-                            ? SD(HBA_ptr)->reads_lat[x][0]:1));
+			   ((SD(HBA_ptr)->reads_lat[x][0])
+			    ? SD(HBA_ptr)->reads_lat[x][0]:1));
 	len += size; 
 	pos = begin + len;
 
-        if (pos < offset) {
-            len = 0;
-            begin = pos;
-        }
-        if (pos > offset + length)
-            goto stop_output;
+	if (pos < offset) {
+	    len = 0;
+	    begin = pos;
+	}
+	if (pos > offset + length)
+	    goto stop_output;
 
 	size = sprintf(buffer + len,
-		       "	 Writes:      Min:(ms)     Max:(ms)     Ave:(ms)\n");
+		       "         Writes:      Min:(ms)     Max:(ms)     Ave:(ms)\n");
 	len += size; 
 	pos = begin + len;
 	for (x = 0; x <= 10; x++) {
 	    size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
-                           1 << x,
+			   1 << x,
 			   SD(HBA_ptr)->writes_lat[x][0], 
 			   (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
-                           ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
+			   ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
 			   SD(HBA_ptr)->writes_lat[x][2] * 10, 
 			   SD(HBA_ptr)->writes_lat[x][3] * 10 /
-                           ((SD(HBA_ptr)->writes_lat[x][0])
-                            ? SD(HBA_ptr)->writes_lat[x][0]:1));
+			   ((SD(HBA_ptr)->writes_lat[x][0])
+			    ? SD(HBA_ptr)->writes_lat[x][0]:1));
 	    len += size; 
 	    pos = begin + len;
 	}
 	size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
 			   SD(HBA_ptr)->writes_lat[11][0], 
 			   (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
-                           ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
+			   ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
 			   SD(HBA_ptr)->writes_lat[11][2] * 10, 
 			   SD(HBA_ptr)->writes_lat[11][3] * 10/
-                           ((SD(HBA_ptr)->writes_lat[x][0])
-                            ? SD(HBA_ptr)->writes_lat[x][0]:1));
+			   ((SD(HBA_ptr)->writes_lat[x][0])
+			    ? SD(HBA_ptr)->writes_lat[x][0]:1));
 	len += size; 
 	pos = begin + len;
 
-        if (pos < offset) {
-            len = 0;
-            begin = pos;
-        }
-        if (pos > offset + length)
-            goto stop_output;
+	if (pos < offset) {
+	    len = 0;
+	    begin = pos;
+	}
+	if (pos > offset + length)
+	    goto stop_output;
     }
 
     scd = scsi_devices;
@@ -438,41 +465,7 @@
     
     while (scd) {
 	if (scd->host == HBA_ptr) {
-	    
-	    size = sprintf(buffer + len, 
-                           "Channel: %02d Id: %02d Lun: %02d\n  Vendor: ",
-			   scd->channel, scd->id, scd->lun);
-	    for (x = 0; x < 8; x++) {
-		if (scd->vendor[x] >= 0x20)
-		    size += sprintf(buffer + len + size, "%c", scd->vendor[x]);
-		else
-		    size += sprintf(buffer + len + size," ");
-	    }
-	    size += sprintf(buffer + len + size, " Model: ");
-	    for (x = 0; x < 16; x++) {
-		if (scd->model[x] >= 0x20)
-		    size +=  sprintf(buffer + len + size, "%c", scd->model[x]);
-		else
-		    size += sprintf(buffer + len + size, " ");
-	    }
-	    size += sprintf(buffer + len + size, " Rev: ");
-	    for (x = 0; x < 4; x++) {
-		if (scd->rev[x] >= 0x20)
-		    size += sprintf(buffer + len + size, "%c", scd->rev[x]);
-		else
-		    size += sprintf(buffer + len + size, " ");
-	    }
-	    size += sprintf(buffer + len + size, "\n");
-	    
-	    size += sprintf(buffer + len + size, "  Type:   %s ",
-			    scd->type < MAX_SCSI_DEVICE_CODE ? 
-			    scsi_dev_types[(int)scd->type] : "Unknown	       " );
-	    size += sprintf(buffer + len + size, "		 ANSI"
-			    " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
-	    if (scd->scsi_level == 2)
-		size += sprintf(buffer + len + size, " CCS\n");
-	    else
-		size += sprintf(buffer + len + size, "\n");
+	    proc_print_scsidevice(scd, buffer, &size, len);
 	    len += size; 
 	    pos = begin + len;
 	    
@@ -511,7 +504,6 @@
  * c-label-offset: -4
  * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
  * tab-width: 8
  * End:
  */
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.3.12/linux/drivers/scsi/scsi.c	Tue Jul 25 18:21:22 1995
+++ linux/drivers/scsi/scsi.c	Tue Jul 25 17:50:13 1995
@@ -106,8 +106,13 @@
 /* This is the pointer to the /proc/scsi code. 
  * It is only initialized to !=0 if the scsi code is present 
  */ 
-extern int (* dispatch_scsi_info_ptr)(int ino, char *buffer, char **start, off_t offset, int length, int inout); 
-extern int dispatch_scsi_info(int ino, char *buffer, char **start, off_t offset, int length, int inout); 
+extern int (* dispatch_scsi_info_ptr)(int ino, char *buffer, char **start, 
+                                      off_t offset, int length, int inout); 
+extern int dispatch_scsi_info(int ino, char *buffer, char **start, 
+                              off_t offset, int length, int inout); 
+
+extern void proc_print_scsidevice(Scsi_Device *scd, char *buffer, 
+                                  int *size, int len);
 
 /*
  *  As the scsi do command functions are intelligent, and may need to
@@ -977,6 +982,7 @@
             while(SCpnt){
                 if(SCpnt->target == device->id &&
                    SCpnt->lun == device->lun) {
+                   SCwait = SCpnt;
                     if(SCpnt->request.dev < 0) break;
                 }
                 SCpnt = SCpnt->next;
@@ -985,6 +991,7 @@
             while(SCpnt){
                 if(SCpnt->target == device->id) {
                     if (SCpnt->lun == device->lun) {
+                        SCwait = SCpnt;
                         if(found == NULL 
                            && SCpnt->request.dev < 0) 
                         {
@@ -2427,12 +2434,49 @@
     struct Scsi_Host *HBA_ptr;
     int  parameter[4];
     char *p;
+    int	  size, len = 0;
+    off_t begin = 0;
+    off_t pos = 0;
 
     scd = scsi_devices;
     HBA_ptr = scsi_hostlist;
 
-    if(inout == 0)    /* We can only write to this file right now */
-	return(-ENOSYS);  /* This is still a no-op */
+    if(inout == 0) { 
+        size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
+        len += size; 
+        pos = begin + len;
+        while (HBA_ptr) {
+#if 0
+            size += sprintf(buffer+len,"scsi%2d: %s\n", (int) HBA_ptr->host_no, HBA_ptr->hostt->procname);
+            len += size; 
+            pos = begin + len;
+#endif
+            scd = scsi_devices;
+            while (scd) {
+                if (scd->host == HBA_ptr) {
+                    proc_print_scsidevice(scd, buffer, &size, len);
+                    len += size; 
+                    pos = begin + len;
+                    
+                    if (pos < offset) {
+                        len = 0;
+                        begin = pos;
+                    }
+                    if (pos > offset + length)
+                        goto stop_output;
+                }
+                scd = scd->next;
+            }
+	    HBA_ptr = HBA_ptr->next;
+        }
+        
+    stop_output:
+        *start=buffer+(offset-begin);   /* Start of wanted data */
+        len-=(offset-begin);	    /* Start slop */
+        if(len>length)
+            len = length;		    /* Ending slop */
+        return (len);     
+    }
 
     if(!buffer || length < 25 || strncmp("scsi", buffer, 4))
 	return(-EINVAL);
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.3.12/linux/drivers/scsi/scsi.h	Tue Jul 18 16:28:58 1995
+++ linux/drivers/scsi/scsi.h	Tue Jul 25 17:50:13 1995
@@ -552,6 +552,8 @@
 extern int max_scsi_hosts;
 
 extern void build_proc_dir_entries(void);
+extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
+
 
 extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
 extern int	  scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/scsi_proc.c linux/drivers/scsi/scsi_proc.c
--- v1.3.12/linux/drivers/scsi/scsi_proc.c	Thu Jul 13 16:20:21 1995
+++ linux/drivers/scsi/scsi_proc.c	Tue Jul 25 17:50:13 1995
@@ -7,7 +7,7 @@
  * information directly to the lowlevel driver.
  *
  * (c) 1995 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de 
- * Version: 0.99.6   last change: 95/07/04
+ * Version: 0.99.7   last change: 95/07/18
  * 
  * generic command parser provided by: 
  * Andreas Heilwagen <crashcar@informatik.uni-koblenz.de>
@@ -330,6 +330,63 @@
     return(cmdIndex);
 }
 
+#define MAX_SCSI_DEVICE_CODE 10
+const char *const scsi_dev_types[MAX_SCSI_DEVICE_CODE] =
+{
+    "Direct-Access    ",
+    "Sequential-Access",
+    "Printer          ",
+    "Processor        ",
+    "WORM             ",
+    "CD-ROM           ",
+    "Scanner          ",
+    "Optical Device   ",
+    "Medium Changer   ",
+    "Communications   "
+};
+
+void proc_print_scsidevice(Scsi_Device *scd, char *buffer, int *size, int len)
+{	    
+    int x, y = *size;
+    
+    y = sprintf(buffer + len, 
+		    "Channel: %02d Id: %02d Lun: %02d\n  Vendor: ",
+		    scd->channel, scd->id, scd->lun);
+    for (x = 0; x < 8; x++) {
+	if (scd->vendor[x] >= 0x20)
+	    y += sprintf(buffer + len + y, "%c", scd->vendor[x]);
+	else
+	    y += sprintf(buffer + len + y," ");
+    }
+    y += sprintf(buffer + len + y, " Model: ");
+    for (x = 0; x < 16; x++) {
+	if (scd->model[x] >= 0x20)
+	    y +=  sprintf(buffer + len + y, "%c", scd->model[x]);
+	else
+	    y += sprintf(buffer + len + y, " ");
+    }
+    y += sprintf(buffer + len + y, " Rev: ");
+    for (x = 0; x < 4; x++) {
+	if (scd->rev[x] >= 0x20)
+	    y += sprintf(buffer + len + y, "%c", scd->rev[x]);
+	else
+	    y += sprintf(buffer + len + y, " ");
+    }
+    y += sprintf(buffer + len + y, "\n");
+    
+    y += sprintf(buffer + len + y, "  Type:   %s ",
+		     scd->type < MAX_SCSI_DEVICE_CODE ? 
+		     scsi_dev_types[(int)scd->type] : "Unknown          " );
+    y += sprintf(buffer + len + y, "               ANSI"
+		     " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
+    if (scd->scsi_level == 2)
+	y += sprintf(buffer + len + y, " CCS\n");
+    else
+	y += sprintf(buffer + len + y, "\n");
+
+    *size = y; 
+    return;
+}
 
 /*
  * Overrides for Emacs so that we get a uniform tabbing style.
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c
--- v1.3.12/linux/drivers/scsi/scsi_syms.c	Fri Jul  7 08:54:50 1995
+++ linux/drivers/scsi/scsi_syms.c	Tue Jul 25 17:50:14 1995
@@ -68,6 +68,9 @@
     X(kernel_scsi_ioctl),
     X(need_isa_buffer),
     X(request_queueable),
+#if defined(CONFIG_PROC_FS)
+    X(proc_print_scsidevice),
+#endif
 /*
  * These are here only while I debug the rest of the scsi stuff.
  */
diff -u --recursive --new-file v1.3.12/linux/fs/hpfs/hpfs_fs.c linux/fs/hpfs/hpfs_fs.c
--- v1.3.12/linux/fs/hpfs/hpfs_fs.c	Tue Jun 27 14:11:39 1995
+++ linux/fs/hpfs/hpfs_fs.c	Wed Jul 26 09:38:20 1995
@@ -1293,7 +1293,7 @@
 	/*
 	 * name not found.
 	 */
-
+	brelse4(qbh);
 	return 0;
 }
 
diff -u --recursive --new-file v1.3.12/linux/fs/proc/inode.c linux/fs/proc/inode.c
--- v1.3.12/linux/fs/proc/inode.c	Fri Jul  7 08:54:52 1995
+++ linux/fs/proc/inode.c	Tue Jul 25 17:50:14 1995
@@ -166,7 +166,7 @@
 	}
 
 	if (ino == PROC_SCSI_SCSI) {
-		inode->i_mode = S_IFREG | S_IWUSR;
+		inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
 		inode->i_op = &proc_scsi_inode_operations;
 		return;
 	}
diff -u --recursive --new-file v1.3.12/linux/kernel/itimer.c linux/kernel/itimer.c
--- v1.3.12/linux/kernel/itimer.c	Tue Jul 18 16:28:59 1995
+++ linux/kernel/itimer.c	Wed Jul 26 15:33:31 1995
@@ -29,14 +29,20 @@
 	return;
 }
 
-int _getitimer(int which, struct itimerval *value)
+static int _getitimer(int which, struct itimerval *value)
 {
-	register unsigned long val, interval;
+	register long val, interval;
 
 	switch (which) {
 	case ITIMER_REAL:
-		val = current->it_real_value;
 		interval = current->it_real_incr;
+		val = 0;
+		if (del_timer(&current->real_timer)) {
+			val = current->real_timer.expires;
+			add_timer(&current->real_timer);
+			if (val <= 0)
+				val = interval;
+		}
 		break;
 	case ITIMER_VIRTUAL:
 		val = current->it_virt_value;
@@ -51,7 +57,7 @@
 	}
 	jiffiestotv(val, &value->it_value);
 	jiffiestotv(interval, &value->it_interval);
-	return(0);
+	return 0;
 }
 
 asmlinkage int sys_getitimer(int which, struct itimerval *value)
diff -u --recursive --new-file v1.3.12/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.12/linux/kernel/ksyms.c	Tue Jul 25 18:21:23 1995
+++ linux/kernel/ksyms.c	Tue Jul 25 17:50:14 1995
@@ -388,6 +388,9 @@
  	X(scsi_devices),
 	X(gendisk_head), /* Needed for sd.c */
 	X(resetup_one_dev), /* Needed for sd.c */
+#if defined(CONFIG_PROC_FS)
+	X(proc_print_scsidevice),
+#endif
 #else
 	/*
 	 * With no scsi configured, we still need to export a few
diff -u --recursive --new-file v1.3.12/linux/kernel/sched.c linux/kernel/sched.c
--- v1.3.12/linux/kernel/sched.c	Tue Jul 25 18:21:23 1995
+++ linux/kernel/sched.c	Thu Jul 27 09:48:45 1995
@@ -120,7 +120,11 @@
 	}
 #endif
 	if (p == &init_task) {
-		printk("idle task may not sleep\n");
+		static int nr = 0;
+		if (nr < 5) {
+			nr++;
+			printk("idle task may not sleep\n");
+		}
 		return;
 	}
 	nr_running--;
diff -u --recursive --new-file v1.3.12/linux/lib/string.c linux/lib/string.c
--- v1.3.12/linux/lib/string.c	Tue Jul 25 18:21:23 1995
+++ linux/lib/string.c	Tue Jul 25 18:24:10 1995
@@ -101,9 +101,9 @@
 #endif
 
 #ifndef __HAVE_ARCH_STRCHR
-char * strchr(const char * s,char c)
+char * strchr(const char * s, int c)
 {
-	for(; *s != c; ++s)
+	for(; *s != (char) c; ++s)
 		if (*s == '\0')
 			return NULL;
 	return (char *) s;
@@ -265,7 +265,7 @@
  * find the first occurrence of byte 'c', or 1 past the area if none
  */
 #ifndef __HAVE_ARCH_MEMSCAN
-void * memscan(void * addr, unsigned char c, size_t size)
+void * memscan(void * addr, int c, size_t size)
 {
 	unsigned char * p = (unsigned char *) addr;
 
