diff -u --recursive --new-file v1.1.27/linux/Makefile linux/Makefile
--- v1.1.27/linux/Makefile	Wed Jul 13 01:09:43 1994
+++ linux/Makefile	Sun Jul 10 09:10:06 1994
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 27
+SUBLEVEL = 28
 
 all:	Version zImage
 
diff -u --recursive --new-file v1.1.27/linux/drivers/block/cdu31a.c linux/drivers/block/cdu31a.c
--- v1.1.27/linux/drivers/block/cdu31a.c	Fri Jul  8 13:26:32 1994
+++ linux/drivers/block/cdu31a.c	Sun Jul 10 09:28:08 1994
@@ -254,39 +254,9 @@
 
 static int curr_control_reg = 0; /* Current value of the control register */
 
-
-#if 1 /* This will go away as soon as the isofs code is fixed
-         to use the fops struct. */
 /*
  * This routine returns 1 if the disk has been changed since the last
- * check or 0 if it hasn't.  Setting flag to 0 resets the changed flag.
- */
-int
-check_cdu31a_media_change(int full_dev, int flag)
-{
-   int retval, target;
-
-
-   target = MINOR(full_dev);
-
-   if (target > 0) {
-      printk("Sony CD-ROM request error: invalid device.\n");
-      return 0;
-   }
-
-   retval = sony_disc_changed;
-   if (!flag)
-   {
-      sony_disc_changed = 0;
-   }
-
-   return retval;
-}
-#endif
-
-/*
- * This routine returns 1 if the disk has been changed since the last
- * check or 0 if it hasn't.  Setting flag to 0 resets the changed flag.
+ * check or 0 if it hasn't.
  */
 static int
 scd_disk_change(dev_t full_dev)
diff -u --recursive --new-file v1.1.27/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v1.1.27/linux/drivers/char/lp.c	Mon Mar 21 16:26:07 1994
+++ linux/drivers/char/lp.c	Wed Jul 13 01:01:48 1994
@@ -235,7 +235,7 @@
 			} else
 	                /* not offline or out of paper. on fire? */
 			if (!(status & LP_PERRORP)) {
-				printk("lp%d on fire\n", minor);
+				printk("lp%d reported invalid error status (on fire, eh?)\n", minor);
 				if(LP_F(minor) & LP_ABORT)
 					return temp-buf?temp-buf:-EFAULT;
 				current->state = TASK_INTERRUPTIBLE;
diff -u --recursive --new-file v1.1.27/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v1.1.27/linux/drivers/char/tty_io.c	Sat Jul  9 16:30:46 1994
+++ linux/drivers/char/tty_io.c	Mon Jul 11 12:14:34 1994
@@ -853,6 +853,7 @@
 		if (driver->subtype == PTY_TYPE_MASTER)
 			(*o_tty_loc)->count++;
 	}
+	(*tty_loc)->driver = *driver;
 	*ret_tty = *tty_loc;
 	retval = 0;
 end_init:
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog
--- v1.1.27/linux/drivers/scsi/ChangeLog	Fri Jul  8 13:26:35 1994
+++ linux/drivers/scsi/ChangeLog	Sun Jul 10 09:09:40 1994
@@ -1,6 +1,60 @@
+Sat Jul  9 15:01:03 1994  Eric Youngdale  (eric@esp22)
+
+	More changes to eventually support loadable modules.  Mainly
+	we want to use linked lists instead of arrays because it is easier
+	to dynamically add and remove things this way.
+
+	Quite a bit more work is needed before loadable modules are
+	possible (and usable) with scsi, but this is most of the grunge
+	work.
+
+	* Linux 1.1.28 released.
+
+	* scsi.c, scsi.h (allocate_device, request_queueable): Change
+	argument from index into scsi_devices to a pointer to the
+	Scsi_Device struct.
+
+	* Throughout: Change all calls to allocate_device,
+	request_queueable to use new calling sequence.
+
+	* Throughout: Use SCpnt->device instead of
+	scsi_devices[SCpnt->index].  Ugh - the pointer was there all along
+	- much cleaner this way.
+
+	* scsi.c (scsi_init_malloc, scsi_free_malloc): New functions -
+	allow us to pretend that we have a working malloc when we
+	initialize.  Use this instead of passing memory_start, memory_end
+	around all over the place.
+
+	* scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use
+	scsi_init_malloc, remove all arguments, no return value.
+
+	* scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd
+	structs.
+
+	* scsi.c (scsi_dev_init): Set up for scsi_init_malloc.
+	(scan_scsis): Get SDpnt from scsi_init_malloc, and refresh
+	when we discover a device.  Free pointer before returning.
+	Change scsi_devices into a linked list.
+
+	* scsi.c (scan_scsis): Change to only scan one host. 
+	(scsi_dev_init): Loop over all detected hosts, and scan them.
+
+	* hosts.c  (scsi_init_free): Change so that  number of extra bytes
+	is stored in struct, and we do not have to pass it each time.
+
+	* hosts.h: Change Scsi_Host_Template struct to include "next" and
+	"release" functions.  Initialize to NULL in all low level
+	adapters.
+
+	* hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked
+	list scsi_hosts, linked together with the new "next" field.
+
 Wed Jul  6 05:45:02 1994  Eric Youngdale  (eric@esp22)
 
 	* Linux 1.1.25 released.
+
+	* aha152x.c: Changes from Juergen - cleanups and updates.
 
 	* sd.c, sr.c: Use new check_media_change and revalidate
 	file_operations fields.
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c
--- v1.1.27/linux/drivers/scsi/NCR5380.c	Fri May 27 10:49:06 1994
+++ linux/drivers/scsi/NCR5380.c	Wed Jul 13 01:02:49 1994
@@ -1184,7 +1184,7 @@
 	ICR_ASSERT_ATN | ICR_ASSERT_SEL));
 
     /* 
-     * Something wierd happens when we cease to drive BSY - looks
+     * Something weird happens when we cease to drive BSY - looks
      * like the board/chip is letting us do another read before the 
      * appropriate propogation delay has expired, and we're confusing
      * a BSY signal from ourselves as the target's response to SELECTION.
@@ -1256,15 +1256,15 @@
 #endif
     tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
 #ifdef SCSI2
-    if (scsi_devices[cmd->index].tagged_queue && (tag != TAG_NONE)) {
+    if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
 	tmp[1] = SIMPLE_QUEUE_TAG;
 	if (tag == TAG_NEXT) {
 	    /* 0 is TAG_NONE, used to imply no tag for this command */
-	    if (scsi_devices[cmd->index].current_tag == 0)
-		scsi_devices[cmd->index].current_tag = 1;
+	    if (cmd->device->current_tag == 0)
+		cmd->device->current_tag = 1;
 
-	    cmd->tag = scsi_devices[cmd->index].current_tag;
-	    scsi_devices[cmd->index].current_tag++;
+	    cmd->tag = cmd->device->current_tag;
+	    cmd->device->current_tag++;
 	} else  
 	    cmd->tag = (unsigned char) tag;
 
@@ -1288,7 +1288,7 @@
     /* XXX need to handle errors here */
     hostdata->connected = cmd;
 #ifdef SCSI2
-    if (!scsi_devices[cmd->index].tagged_queue)
+    if (!cmd->device->tagged_queue)
 #endif    
 	hostdata->busy[cmd->target] |= (1 << cmd->lun);
 
@@ -1794,10 +1794,10 @@
 
 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
 #ifdef NCR5380_dma_xfer_len
-		if (!scsi_devices[cmd->index].borken &&
+		if (!cmd->device->borken &&
 		    (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
 #else
-		if (!scsi_devices[cmd->index].borken && 
+		if (!cmd->device->borken && 
 		    (transfersize = cmd->transfersize) && 
 		    cmd->SCp.this_residual && !(cmd->SCp.this_residual % 
 		    transfersize)) {
@@ -1811,7 +1811,7 @@
 			 */ 
 			printk("scsi%d : switching target %d lun %d to slow handshake\n",
 			    instance->host_no, cmd->target, cmd->lun);
-			scsi_devices[cmd->index].borken = 1;
+			cmd->device->borken = 1;
 			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
 			    ICR_ASSERT_ATN);
 			msgout = ABORT;
@@ -1951,14 +1951,14 @@
 		    case HEAD_OF_QUEUE_TAG:
 		    case ORDERED_QUEUE_TAG:
 		    case SIMPLE_QUEUE_TAG:
-			scsi_devices[cmd->index].tagged_queue = 0;
+			cmd->device->tagged_queue = 0;
 			hostdata->busy[cmd->target] |= (1 << cmd->lun);
 			break;
 		    default:
 			break;
 		    }
 		case DISCONNECT:
-		    scsi_devices[cmd->index].disconnect = 1;
+		    cmd->device->disconnect = 1;
 		    cli();
 		    cmd->host_scribble = (unsigned char *) 
 			hostdata->disconnected_queue;
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v1.1.27/linux/drivers/scsi/aha152x.c	Fri Jul  8 13:26:36 1994
+++ linux/drivers/scsi/aha152x.c	Sun Jul 10 09:09:39 1994
@@ -503,7 +503,7 @@
   return(i==16);
 }
 
-int aha152x_detect(int hostno)
+int aha152x_detect(Scsi_Host_Template * tpnt)
 {
   int                 i, j,  ok;
   aha152x_config      conf;
@@ -653,10 +653,10 @@
     }
 
   SETPORT( SCSIID, this_host << 4 );
-  scsi_hosts[hostno].this_id=this_host;
+  tpnt->this_id=this_host;
   
   if(can_disconnect)
-    scsi_hosts[hostno].can_queue=AHA152X_MAXQUEUE;
+    tpnt->can_queue=AHA152X_MAXQUEUE;
 
   /* RESET OUT */
   SETBITS(SCSISEQ, SCSIRSTO );
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h
--- v1.1.27/linux/drivers/scsi/aha152x.h	Fri Jul  8 13:26:36 1994
+++ linux/drivers/scsi/aha152x.h	Sun Jul 10 09:09:39 1994
@@ -10,7 +10,7 @@
 #if defined(__KERNEL__)
 #include <asm/io.h>
 
-int        aha152x_detect(int);
+int        aha152x_detect(Scsi_Host_Template *);
 const char *aha152x_info(void);
 int        aha152x_command(Scsi_Cmnd *);
 int        aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
@@ -25,8 +25,10 @@
 #define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.2 $"
 
 /* Initial value of Scsi_Host entry */
-#define AHA152X       { /* name */		AHA152X_REVID, \
+#define AHA152X       { /* next */		NULL,			    \
+			/* name */		AHA152X_REVID, 		    \
 			/* detect */		aha152x_detect,             \
+			/* release */		NULL,			    \
 			/* info */		aha152x_info,               \
 			/* command */		aha152x_command,            \
 			/* queuecommand */	aha152x_queue,              \
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v1.1.27/linux/drivers/scsi/aha1542.c	Fri Jul  8 13:26:36 1994
+++ linux/drivers/scsi/aha1542.c	Sun Jul 10 09:09:38 1994
@@ -780,7 +780,7 @@
 
 
 /* return non-zero on detection */
-int aha1542_detect(int hostnum)
+int aha1542_detect(Scsi_Host_Template * tpnt)
 {
     unsigned char dma_chan;
     unsigned char irq_level;
@@ -794,7 +794,7 @@
     
     for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
 	    if(!check_region(bases[indx], 4)) { 
-		    shpnt = scsi_register(hostnum,
+		    shpnt = scsi_register(tpnt,
 					  sizeof(struct aha1542_hostdata));
 
 		    if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
@@ -900,7 +900,7 @@
 		    count++;
 		    continue;
 	    unregister:
-		    scsi_unregister(shpnt, sizeof(struct aha1542_hostdata));
+		    scsi_unregister(shpnt);
 		    continue;
 		    
 	    };
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/aha1542.h linux/drivers/scsi/aha1542.h
--- v1.1.27/linux/drivers/scsi/aha1542.h	Fri Jul  8 13:26:36 1994
+++ linux/drivers/scsi/aha1542.h	Sun Jul 10 09:09:39 1994
@@ -128,7 +128,7 @@
 				/* REQUEST SENSE */
 };
 
-int aha1542_detect(int);
+int aha1542_detect(Scsi_Host_Template *);
 int aha1542_command(Scsi_Cmnd *);
 int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int aha1542_abort(Scsi_Cmnd *);
@@ -144,14 +144,23 @@
 	#define NULL 0
 #endif
 
-#define AHA1542 {"Adaptec 1542", aha1542_detect,	\
-		aha1542_info, aha1542_command,		\
-		aha1542_queuecommand,			\
-		aha1542_abort,				\
-		aha1542_reset,				\
-	        NULL,		                        \
-		aha1542_biosparam,                      \
-		AHA1542_MAILBOXES, 7, AHA1542_SCATTER, AHA1542_CMDLUN \
-		  , 0, 1, ENABLE_CLUSTERING}
+#define AHA1542 {  NULL,				\
+		     "Adaptec 1542", 			\
+		     aha1542_detect,			\
+		     NULL,				\
+		     aha1542_info, 			\
+		     aha1542_command,			\
+		     aha1542_queuecommand,		\
+		     aha1542_abort,			\
+		     aha1542_reset,			\
+		     NULL,		                \
+		     aha1542_biosparam,                 \
+		     AHA1542_MAILBOXES, 		\
+		     7, 				\
+		     AHA1542_SCATTER, 			\
+		     AHA1542_CMDLUN, 			\
+		     0, 				\
+		     1, 				\
+		     ENABLE_CLUSTERING}
 
 #endif
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- v1.1.27/linux/drivers/scsi/aha1740.c	Fri Jul  8 13:26:36 1994
+++ linux/drivers/scsi/aha1740.c	Sun Jul 10 09:09:39 1994
@@ -425,7 +425,7 @@
   irq_level = intab [ inb(INTDEF)&0x7 ];
 }
 
-int aha1740_detect(int hostnum)
+int aha1740_detect(Scsi_Host_Template * tpnt)
 {
     memset(&ecb, 0, sizeof(struct ecb));
     DEB(printk("aha1740_detect: \n"));
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/aha1740.h linux/drivers/scsi/aha1740.h
--- v1.1.27/linux/drivers/scsi/aha1740.h	Fri Jul  8 13:26:36 1994
+++ linux/drivers/scsi/aha1740.h	Sun Jul 10 09:09:39 1994
@@ -152,7 +152,7 @@
 #define AHA1740CMD_RINQ  0x0a	/* Read Host Adapter Inquiry Data */
 #define AHA1740CMD_TARG  0x10	/* Target SCSI Command */
 
-int aha1740_detect(int);
+int aha1740_detect(Scsi_Host_Template *);
 int aha1740_command(Scsi_Cmnd *);
 int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int aha1740_abort(Scsi_Cmnd *);
@@ -167,14 +167,24 @@
 #define NULL 0
 #endif
 
-#define AHA1740 {"Adaptec 1740", aha1740_detect,	\
-		aha1740_info, aha1740_command,		\
-		aha1740_queuecommand,			\
-		aha1740_abort,				\
-		aha1740_reset,				\
-	        NULL,		                        \
-		aha1740_biosparam,                      \
-		AHA1740_ECBS, 7, AHA1740_SCATTER, 1, 0, 0, ENABLE_CLUSTERING}
+#define AHA1740 {NULL,					\
+		   "Adaptec 1740", 			\
+		   aha1740_detect,			\
+		   NULL,				\
+		   aha1740_info, 			\
+		   aha1740_command,			\
+		   aha1740_queuecommand,		\
+		   aha1740_abort,			\
+		   aha1740_reset,			\
+		   NULL,		                \
+		   aha1740_biosparam,                   \
+		   AHA1740_ECBS, 			\
+		   7, 					\
+		   AHA1740_SCATTER, 			\
+		   1, 					\
+		   0, 					\
+		   0, 					\
+		   ENABLE_CLUSTERING}
 
 #endif
 
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/buslogic.c linux/drivers/scsi/buslogic.c
--- v1.1.27/linux/drivers/scsi/buslogic.c	Fri Jul  8 13:26:36 1994
+++ linux/drivers/scsi/buslogic.c	Sun Jul 10 09:09:39 1994
@@ -912,7 +912,7 @@
 }
 
 /* return non-zero on detection */
-int buslogic_detect(int hostnum)
+int buslogic_detect(Scsi_Host_Template * tpnt)
 {
     unsigned char dma;
     unsigned char irq;
@@ -932,7 +932,7 @@
 
     for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
 	if (!check_region(bases[indx], 3)) {
-	    SHpnt = scsi_register(hostnum, sizeof (struct hostdata));
+	    SHpnt = scsi_register(tpnt, sizeof (struct hostdata));
 
 	    base = bases[indx];
 
@@ -1085,7 +1085,7 @@
 	    count++;
 	    continue;
 	  unregister:
-	    scsi_unregister(SHpnt, sizeof (struct hostdata));
+	    scsi_unregister(SHpnt);
 	}
     return count;
 }
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/buslogic.h linux/drivers/scsi/buslogic.h
--- v1.1.27/linux/drivers/scsi/buslogic.h	Fri Jul  8 13:26:37 1994
+++ linux/drivers/scsi/buslogic.h	Sun Jul 10 09:09:40 1994
@@ -12,7 +12,7 @@
 
 #ifndef _BUSLOGIC_H
 
-int buslogic_detect(int);
+int buslogic_detect(Scsi_Host_Template *);
 int buslogic_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int buslogic_abort(Scsi_Cmnd *);
 const char *buslogic_info(void);
@@ -21,8 +21,10 @@
 
 #define BUSLOGIC_CMDLUN 1	/* ??? */
 
-#define BUSLOGIC { "BusLogic",			\
+#define BUSLOGIC { NULL, 			\
+		   "BusLogic",			\
 		   buslogic_detect,		\
+		   NULL,			\
 		   buslogic_info,		\
 		   0,	/* no command func */	\
 		   buslogic_queuecommand,	\
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v1.1.27/linux/drivers/scsi/fdomain.c	Fri Jul  8 13:26:37 1994
+++ linux/drivers/scsi/fdomain.c	Sun Jul 10 09:09:39 1994
@@ -258,7 +258,6 @@
 static int               bios_major        = 0;
 static int               bios_minor        = 0;
 static int               interrupt_level   = 0;
-static int               this_host         = 0;
 static volatile int      in_command        = 0;
 static Scsi_Cmnd         *current_SC       = NULL;
 static enum chip_type    chip              = unknown;
@@ -480,7 +479,7 @@
    return 0;
 }
 
-int fdomain_16x0_detect( int hostnum )
+int fdomain_16x0_detect(Scsi_Host_Template * tpnt)
 {
    int              i, j;
    int              flag = 0;
@@ -614,11 +613,7 @@
       printk( "Future Domain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
 #endif
       return 0;
-   }
-
-   this_host = hostnum;
-
-				/* Log IRQ with kernel */
+   }				/* Log IRQ with kernel */
    
    if (!interrupt_level) {
       panic( "Future Domain: *NO* interrupt level selected!\n" );
@@ -659,7 +654,7 @@
 
    if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
       adapter_mask = 0x80;
-      scsi_hosts[this_host].this_id = 7;
+      tpnt->this_id = 7;
    }
    
 #if DO_DETECT
@@ -679,7 +674,7 @@
    printk( "Future Domain detection routine scanning for devices:\n" );
    for (i = 0; i < 8; i++) {
       SCinit.target = i;
-      if (i == scsi_hosts[this_host].this_id) /* Skip host adapter */
+      if (i == tpnt->this_id) /* Skip host adapter */
 	    continue;
       memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
       retcode = fdomain_16x0_command(&SCinit);
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/fdomain.h linux/drivers/scsi/fdomain.h
--- v1.1.27/linux/drivers/scsi/fdomain.h	Fri Jul  8 13:26:37 1994
+++ linux/drivers/scsi/fdomain.h	Sun Jul 10 09:09:39 1994
@@ -25,7 +25,7 @@
 #ifndef _FDOMAIN_H
 #define _FDOMAIN_H
 
-int        fdomain_16x0_detect( int );
+int        fdomain_16x0_detect( Scsi_Host_Template * );
 int        fdomain_16x0_command( Scsi_Cmnd * );
 int        fdomain_16x0_abort( Scsi_Cmnd *);
 const char *fdomain_16x0_info( void );
@@ -34,8 +34,10 @@
 
 int        fdomain_16x0_biosparam(Disk *, int, int * );
 
-#define FDOMAIN_16X0 { "Future Domain TMC-16x0",          \
+#define FDOMAIN_16X0 { NULL,				  \
+			 "Future Domain TMC-16x0",        \
 			fdomain_16x0_detect,              \
+			NULL,				  \
 		        fdomain_16x0_info,                \
 		        fdomain_16x0_command,             \
 		        fdomain_16x0_queue,               \
@@ -43,5 +45,11 @@
 		        fdomain_16x0_reset,               \
 		        NULL,                             \
 		        fdomain_16x0_biosparam,           \
-		        1, 6, 64 /* SG_NONE */, 1 ,0, 0, DISABLE_CLUSTERING}
+		        1, 				  \
+			6, 				  \
+			64 /* SG_NONE */, 		  \
+			1, 				  \
+			0, 				  \
+			0, 				  \
+			 DISABLE_CLUSTERING}
 #endif
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- v1.1.27/linux/drivers/scsi/g_NCR5380.c	Wed Dec  1 14:44:16 1993
+++ linux/drivers/scsi/g_NCR5380.c	Sun Jul 10 09:09:39 1994
@@ -111,18 +111,18 @@
     SA_INTERRUPT , NULL };
 
 /* 
- * Function : int generic_NCR5380_detect(int hostno)
+ * Function : int generic_NCR5380_detect(Scsi_Host_Templace * tpnt)
  *
  * Purpose : initializes generic NCR5380 driver based on the 
  *	command line / compile time port and irq definitions.
  *
- * Inputs : hostno - id of this SCSI adapter.
+ * Inputs : tpnt - template for this SCSI adapter.
  * 
  * Returns : 1 if a host adapter was found, 0 if not.
  *
  */
 
-int generic_NCR5380_detect(int hostno) {
+int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
     static int current_override = 0;
     int count;
     struct Scsi_Host *instance;
@@ -131,7 +131,7 @@
 	if (!(overrides[current_override].port))
 	    continue;
 
-	instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
+	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
 	instance->io_port = overrides[current_override].port;
 
 	NCR5380_init(instance);
@@ -144,13 +144,13 @@
 	if (instance->irq != IRQ_NONE) 
 	    if (irqaction (instance->irq, &sa)) {
 		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
-		    hostno, instance->irq);
+		    instance->host_no, instance->irq);
 		instance->irq = IRQ_NONE;
 	    } 
 
 	if (instance->irq == IRQ_NONE) {
-	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", hostno);
-	    printk("scsi%d : please jumper the board for a free IRQ.\n", hostno);
+	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+	    printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 	}
 
 	printk("scsi%d : at port %d", instance->host_no, instance->io_port);
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/g_NCR5380.h linux/drivers/scsi/g_NCR5380.h
--- v1.1.27/linux/drivers/scsi/g_NCR5380.h	Fri May 27 10:49:09 1994
+++ linux/drivers/scsi/g_NCR5380.h	Sun Jul 10 09:09:40 1994
@@ -34,7 +34,7 @@
 
 #ifndef ASM
 int generic_NCR5380_abort(Scsi_Cmnd *);
-int generic_NCR5380_detect(int);
+int generic_NCR5380_detect(Scsi_Host_Template *);
 const char *generic_NCR5380_info(void);
 int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int generic_NCR5380_reset(Scsi_Cmnd *);
@@ -54,8 +54,8 @@
 
 #ifdef HOSTS_C
 
-#define GENERIC_NCR5380 {"Trantor T128/T128F/T228", 			\
-	generic_NCR5380_detect, generic_NCR5380_info, NULL, 		\
+#define GENERIC_NCR5380 {NULL, "Trantor T128/T128F/T228", 		\
+	generic_NCR5380_detect, NULL, generic_NCR5380_info, NULL, 	\
 	generic_NCR5380_queue_command, generic_NCR5380_abort, 		\
 	generic_NCR5380_reset, NULL, 					\
 	NULL, /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,		\
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v1.1.27/linux/drivers/scsi/hosts.c	Fri Jun 17 15:20:06 1994
+++ linux/drivers/scsi/hosts.c	Sun Jul 10 09:09:38 1994
@@ -108,7 +108,9 @@
  *	idiocy.
  */
 
-Scsi_Host_Template scsi_hosts[] =
+Scsi_Host_Template * scsi_hosts = NULL;
+
+static Scsi_Host_Template builtin_scsi_hosts[] =
 	{
 #ifdef CONFIG_SCSI_ULTRASTOR
 	ULTRASTOR_14F,
@@ -152,7 +154,7 @@
 #endif
 	};
 
-#define MAX_SCSI_HOSTS (sizeof(scsi_hosts) / sizeof(Scsi_Host_Template))
+#define MAX_SCSI_HOSTS (sizeof(builtin_scsi_hosts) / sizeof(Scsi_Host_Template))
 
 /*
  *	Our semaphores and timeout counters, where size depends on MAX_SCSI_HOSTS here. 
@@ -160,44 +162,44 @@
 
 struct Scsi_Host * scsi_hostlist = NULL;
 
-static int scsi_init_memory_start = 0;
-
 int max_scsi_hosts = 0;
 static int next_host = 0;
 
 void
-scsi_unregister(struct Scsi_Host * sh, int j){
+scsi_unregister(struct Scsi_Host * sh){
 	struct Scsi_Host * shpnt;
+	int j;
+
+	j = sh->extra_bytes;
 
-	if(((unsigned int) sh) + sizeof(struct Scsi_Host) + j != scsi_init_memory_start)
-		panic("Unable to unregister scsi host");
 	if(scsi_hostlist == sh)
 		scsi_hostlist = NULL;
 	else {
 		shpnt = scsi_hostlist;
 		while(shpnt->next != sh) shpnt = shpnt->next;
 		shpnt->next = shpnt->next->next;
-
 	};
 	next_host--;
-	scsi_init_memory_start = (unsigned int) sh;
+	scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + j);
 }
 
 /* We call this when we come across a new host adapter. We only do this
    once we are 100% sure that we want to use this host adapter -  it is a
    pain to reverse this, so we try and avoid it */
 
-struct Scsi_Host * scsi_register(int i, int j){
+struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
 	struct Scsi_Host * retval, *shpnt;
-	retval = (struct Scsi_Host*) scsi_init_memory_start;
-	scsi_init_memory_start += sizeof(struct Scsi_Host) + j;
+	retval = scsi_init_malloc(sizeof(struct Scsi_Host) + j);
 	retval->host_busy = 0;
+	if(j > 0xffff) panic("Too many extra bytes requested\n");
+	retval->extra_bytes = j;
+	retval->loaded_as_module = scsi_loadable_module_flag;
 	retval->host_no = next_host++;
 	retval->host_queue = NULL;	
 	retval->host_wait = NULL;	
 	retval->last_reset = 0;	
 	retval->irq = 0;
-	retval->hostt = &scsi_hosts[i];	
+	retval->hostt = tpnt;	
 	retval->next = NULL;
 #ifdef DEBUG
 	printk("Register %x %x: %d %d\n", retval, retval->hostt, i, j);
@@ -205,9 +207,9 @@
 
 	/* The next three are the default values which can be overridden
 	   if need be */
-	retval->this_id = scsi_hosts[i].this_id;
-	retval->sg_tablesize = scsi_hosts[i].sg_tablesize;
-	retval->unchecked_isa_dma = scsi_hosts[i].unchecked_isa_dma;
+	retval->this_id = tpnt->this_id;
+	retval->sg_tablesize = tpnt->sg_tablesize;
+	retval->unchecked_isa_dma = tpnt->unchecked_isa_dma;
 
 	if(!scsi_hostlist)
 		scsi_hostlist = retval;
@@ -221,19 +223,17 @@
 	return retval;
 }
 
-unsigned int
-scsi_init(unsigned long memory_start,unsigned long memory_end)
+unsigned int scsi_init()
 {
 	static int called = 0;
 	int i, j, count, pcount;
-
+	Scsi_Host_Template * tpnt;
 	count = 0;
 
-	if(called) return memory_start;
+	if(called) return 0;
 
-	scsi_init_memory_start = memory_start;
 	called = 1;	
-	for (i = 0; i < MAX_SCSI_HOSTS; ++i)
+	for (tpnt = &builtin_scsi_hosts[0], i = 0; i < MAX_SCSI_HOSTS; ++i, tpnt++)
 	{
 		/*
 		 * Initialize our semaphores.  -1 is interpreted to mean 
@@ -241,36 +241,38 @@
 		 */ 
 		
 		pcount = next_host;
-		if ((scsi_hosts[i].detect) && 
-		    (scsi_hosts[i].present = 
-		     scsi_hosts[i].detect(i)))
+		if ((tpnt->detect) && 
+		    (tpnt->present = 
+		     tpnt->detect(tpnt)))
 		{		
 			/* The only time this should come up is when people use
 			   some kind of patched driver of some kind or another. */
 			if(pcount == next_host) {
-				if(scsi_hosts[i].present > 1)
+				if(tpnt->present > 1)
 					panic("Failure to register low-level scsi driver");
 				/* The low-level driver failed to register a driver.  We
 				   can do this now. */
-				scsi_register(i,0);
+				scsi_register(tpnt,0);
 			};
-			for(j = 0; j < scsi_hosts[i].present; j++)
+			tpnt->next = scsi_hosts;
+			scsi_hosts = tpnt;
+			for(j = 0; j < tpnt->present; j++)
 				printk ("scsi%d : %s\n",
-					count++, scsi_hosts[i].name);
+					count++, tpnt->name);
 		}
 	}
 	printk ("scsi : %d hosts.\n", count);
 	
 	max_scsi_hosts = count;
-	return scsi_init_memory_start;
+	return 0;
 }
 
 #ifndef CONFIG_BLK_DEV_SD
 unsigned long sd_init(unsigned long memory_start, unsigned long memory_end){
   return memory_start;
 };
-unsigned long sd_init1(unsigned long memory_start, unsigned long memory_end){
-  return memory_start;
+void sd_init1(){
+  return;
 };
 void sd_attach(Scsi_Device * SDp){
 };
@@ -283,8 +285,8 @@
 unsigned long sr_init(unsigned long memory_start, unsigned long memory_end){
   return memory_start;
 };
-unsigned long sr_init1(unsigned long memory_start, unsigned long memory_end){
-  return memory_start;
+void sr_init1(){
+  return;
 };
 void sr_attach(Scsi_Device * SDp){
 };
@@ -297,8 +299,8 @@
 unsigned long st_init(unsigned long memory_start, unsigned long memory_end){
   return memory_start;
 };
-unsigned long st_init1(unsigned long memory_start, unsigned long memory_end){
-  return memory_start;
+void st_init1(){
+  return;
 };
 void st_attach(Scsi_Device * SDp){
 };
@@ -310,8 +312,8 @@
 unsigned long sg_init(unsigned long memory_start, unsigned long memory_end){
   return memory_start;
 };
-unsigned long sg_init1(unsigned long memory_start, unsigned long memory_end){
-  return memory_start;
+void sg_init1(){
+  return;
 };
 void sg_attach(Scsi_Device * SDp){
 };
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
--- v1.1.27/linux/drivers/scsi/hosts.h	Fri Jul  8 13:26:37 1994
+++ linux/drivers/scsi/hosts.h	Sun Jul 10 09:09:37 1994
@@ -46,8 +46,12 @@
 
 typedef struct scsi_disk Disk;
 
-typedef struct     
+typedef struct  SHT
 	{
+
+	  /* Used with loadable modules so we can construct a linked list. */
+	  struct SHT * next;
+
 	/*
 		The name pointer is a pointer to the name of the SCSI
 		device detected.
@@ -71,8 +75,10 @@
 		especially that scsi_malloc/scsi_free must not be called.
 	*/
 
-	int (* detect)(int); 
+	int (* detect)(struct SHT *); 
 
+	  /* Used with loadable modules to unload the host structures */
+	int (*release)(struct Scsi_Host *);
 	/*
 		The info function will return whatever useful
 		information the developer sees fit.              
@@ -218,6 +224,7 @@
 struct Scsi_Host
 	{
 		struct Scsi_Host * next;
+		unsigned short extra_bytes;
 		volatile unsigned char host_busy;
 		char host_no;  /* Used for IOCTL_GET_IDLUN */
 		int last_reset;
@@ -238,21 +245,36 @@
 		int this_id;
 		short unsigned int sg_tablesize;
 		unsigned unchecked_isa_dma:1;
+		/*
+		   True if this host was loaded as a loadable module
+		   */
+		unsigned loaded_as_module:1;
+		
 		int hostdata[0];  /* Used for storage of host specific stuff */
 	};
 
 extern struct Scsi_Host * scsi_hostlist;
 
-extern Scsi_Host_Template scsi_hosts[];
+extern Scsi_Host_Template * scsi_hosts;
 
 /*
 	scsi_init initializes the scsi hosts.
 */
 
 
-unsigned int scsi_init(unsigned long memory_start,unsigned long memory_end);
-extern struct Scsi_Host * scsi_register(int i, int j);
-extern void scsi_unregister(struct Scsi_Host * i, int j);
+/* We use these goofy things because the MM is not set up when we init
+   the scsi subsystem.  By using these functions we can write code that
+   looks normal.  Also, it makes it possible to use the same code for a
+   loadable module. */
+
+extern void * scsi_init_malloc(unsigned int size);
+extern void scsi_init_free(char * ptr, unsigned int size);
+
+
+extern int scsi_loadable_module_flag;
+unsigned int scsi_init(void);
+extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int j);
+extern void scsi_unregister(struct Scsi_Host * i);
 
 #define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 #endif
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c
--- v1.1.27/linux/drivers/scsi/pas16.c	Fri Jul  8 13:26:37 1994
+++ linux/drivers/scsi/pas16.c	Sun Jul 10 09:09:38 1994
@@ -278,19 +278,19 @@
 static struct sigaction pas16_sigaction =  { pas16_intr, 0, SA_INTERRUPT , NULL };
 
 /* 
- * Function : int pas16_detect(int hostno)
+ * Function : int pas16_detect(Scsi_Host_Template * tpnt)
  *
  * Purpose : detects and initializes PAS16 controllers
  *	that were autoprobed, overriden on the LILO command line, 
  *	or specified at compile time.
  *
- * Inputs : hostno - id of this SCSI adapter.
+ * Inputs : tpnt - template for this SCSI adapter.
  * 
  * Returns : 1 if a host adapter was found, 0 if not.
  *
  */
 
-int pas16_detect(int hostno) {
+int pas16_detect(Scsi_Host_Template * tpnt) {
     static int current_override = 0;
     static unsigned short current_base = 0;
     struct Scsi_Host *instance;
@@ -309,27 +309,27 @@
 	else
 	    for (; !io_port && (current_base < NO_BASES); ++current_base) {
 #if (PDEBUG & PDEBUG_INIT)
-    printk("scsi%d : probing io_port %04x\n", hostno, (unsigned int) bases[current_base].io_port);
+    printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
 #endif
 	        if ( !bases[current_base].noauto &&
 		     pas16_hw_detect( current_base ) ){
 		        io_port = bases[current_base].io_port;
 			init_board( io_port, default_irqs[ current_base ] ); 
 #if (PDEBUG & PDEBUG_INIT)
-		        printk("scsi%d : detected board.\n", hostno);
+		        printk("scsi-pas16 : detected board.\n");
 #endif
 		}
     }
 
 
 #if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-	printk("scsi%d : io_port = %04x\n", hostno, (unsigned int) io_port);
+	printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
 #endif
 
 	if (!io_port)
 	    break;
 
-	instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
+	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
 	instance->io_port = io_port;
 
 	NCR5380_init(instance);
@@ -342,17 +342,17 @@
 	if (instance->irq != IRQ_NONE) 
 	    if (irqaction (instance->irq, &pas16_sigaction)) {
 		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
-		    hostno, instance->irq);
+		    instance->host_no, instance->irq);
 		instance->irq = IRQ_NONE;
 	    } 
 
 	if (instance->irq == IRQ_NONE) {
-	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", hostno);
-	    printk("scsi%d : please jumper the board for a free IRQ.\n", hostno);
+	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+	    printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 	}
 
 #if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-	printk("scsi%d : irq = %d\n", hostno, instance->irq);
+	printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
 #endif
 
 	printk("scsi%d : at 0x%04x", instance->host_no, (int) 
@@ -368,7 +368,6 @@
 
 	++current_override;
 	++count;
-	++hostno;
     }
     return count;
 }
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/pas16.h linux/drivers/scsi/pas16.h
--- v1.1.27/linux/drivers/scsi/pas16.h	Fri Jul  8 13:26:37 1994
+++ linux/drivers/scsi/pas16.h	Sun Jul 10 09:09:38 1994
@@ -116,7 +116,7 @@
 #ifndef ASM
 int pas16_abort(Scsi_Cmnd *);
 int pas16_biosparam(Disk *, int, int*);
-int pas16_detect(int);
+int pas16_detect(Scsi_Host_Template *);
 const char *pas16_info(void);
 int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int pas16_reset(Scsi_Cmnd *);
@@ -141,7 +141,8 @@
 
 #ifdef HOSTS_C
 
-#define MV_PAS16 {"Pro Audio Spectrum-16 SCSI", pas16_detect, pas16_info,\
+#define MV_PAS16 {NULL, "Pro Audio Spectrum-16 SCSI", 			\
+	pas16_detect, NULL, pas16_info,					\
 	NULL, pas16_queue_command, pas16_abort, pas16_reset, NULL, 	\
 	pas16_biosparam, 						\
 	/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,			\
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.1.27/linux/drivers/scsi/scsi.c	Fri Jul  8 13:26:37 1994
+++ linux/drivers/scsi/scsi.c	Sun Jul 10 09:09:36 1994
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/string.h>
+#include <linux/malloc.h>
 #include <asm/irq.h>
 
 #include "../block/blk.h"
@@ -74,8 +75,8 @@
 
 static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};
 
-/* We make this not static so that we can read the array with gdb. */
-/* static */ Scsi_Cmnd * last_cmnd = NULL;
+/* This variable is merely a hook so that we can debug the kernel with gdb. */
+Scsi_Cmnd * last_cmnd = NULL;
 
 /*
  *	As the scsi do command functions are inteligent, and may need to 
@@ -214,217 +215,209 @@
  *	devices to the disk driver.
  */
 
-static void scan_scsis (void)
+static void scan_scsis (struct Scsi_Host * shpnt)
 {
   int dev, lun, type;
   unsigned char scsi_cmd [12];
   unsigned char scsi_result [256];
-  struct Scsi_Host * shpnt;
+  Scsi_Device * SDpnt;
   Scsi_Cmnd  SCmd;
   
   ++in_scan;
   lun = 0;
-  
+  type = -1;
   SCmd.next = NULL;
   SCmd.prev = NULL;
-  for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
-      {
-	shpnt->host_queue = &SCmd;  /* We need this so that
+  SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof (Scsi_Device));
+
+  shpnt->host_queue = &SCmd;  /* We need this so that
 					 commands can time out */
-	for (dev = 0; dev < 8; ++dev)
-	  if (shpnt->this_id != dev)
+  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)
-	      {
-		scsi_devices[NR_SCSI_DEVICES].host = shpnt;
-		scsi_devices[NR_SCSI_DEVICES].id = dev;
-		scsi_devices[NR_SCSI_DEVICES].lun = lun;
-		scsi_devices[NR_SCSI_DEVICES].index = NR_SCSI_DEVICES;
-		scsi_devices[NR_SCSI_DEVICES].device_wait = NULL;
+      for (lun = 0; lun < max_scsi_luns; ++lun)
+	{
+	  SDpnt->host = shpnt;
+	  SDpnt->id = dev;
+	  SDpnt->lun = lun;
+	  SDpnt->device_wait = NULL;
+	  SDpnt->next = NULL;
 /*
  * Assume that the device will have handshaking problems, and then 
  * fix this field later if it turns out it doesn't.
  */
-		scsi_devices[NR_SCSI_DEVICES].borken = 1;
-		
-		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;
-
-		SCmd.host = shpnt;
-		SCmd.target = dev;
-		SCmd.lun = lun;
-
-		SCmd.request.dev = 0xffff; /* Mark not busy */
-		SCmd.use_sg  = 0;
-		SCmd.old_use_sg  = 0;
-		SCmd.transfersize = 0;
-		SCmd.underflow = 0;
-		SCmd.index = NR_SCSI_DEVICES;
-
-		scsi_do_cmd (&SCmd,
-			     (void *)  scsi_cmd, (void *) 
-			     scsi_result, 256,  scan_scsis_done, 
-			     SCSI_TIMEOUT + 400, 5);
-		
-		while (SCmd.request.dev != 0xfffe);
+	  SDpnt->borken = 1;
+	  
+	  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;
+	  
+	  SCmd.host = shpnt;
+	  SCmd.target = dev;
+	  SCmd.lun = lun;
+
+	  SCmd.request.dev = 0xffff; /* Mark not busy */
+	  SCmd.use_sg  = 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);
+	  
+	  while (SCmd.request.dev != 0xfffe);
 #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: scan SCSIS id %d lun %d\n", dev, lun);
+	  printk("scsi: return code %08x\n", SCmd.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)
-		      continue; /* No devices here... */
-		    if(((SCmd.sense_buffer[2] & 0xf) != NOT_READY) &&
-		       ((SCmd.sense_buffer[2] & 0xf) != UNIT_ATTENTION))
-		      continue;
-		  }
-		  else
-		    break;
-		};
-
+	  
+	  
+	  if(SCmd.result) {
+	    if ((driver_byte(SCmd.result)  & DRIVER_SENSE) &&
+		((SCmd.sense_buffer[0] & 0x70) >> 4) == 7) {
+	      if (SCmd.sense_buffer[2] &0xe0)
+		continue; /* No devices here... */
+	      if(((SCmd.sense_buffer[2] & 0xf) != NOT_READY) &&
+		 ((SCmd.sense_buffer[2] & 0xf) != UNIT_ATTENTION))
+		continue;
+	    }
+	    else
+	      break;
+	  };
+	  
 #if defined (DEBUG) || defined(DEBUG_INIT)
-		printk("scsi: performing INQUIRY\n");
+	  printk("scsi: performing INQUIRY\n");
 #endif
-
-		/*
-		 * Build an INQUIRY command block.  
-		 */
-		
-		scsi_cmd[0] = INQUIRY;
-		scsi_cmd[1] = (lun << 5) & 0xe0;
-		scsi_cmd[2] = 0;
-		scsi_cmd[3] = 0;
-		scsi_cmd[4] = 255;
-		scsi_cmd[5] = 0;
-		
-		SCmd.request.dev = 0xffff; /* Mark not busy */
-		
-		scsi_do_cmd (&SCmd,
-			     (void *)  scsi_cmd, (void *) 
-			     scsi_result, 256,  scan_scsis_done, 
-			     SCSI_TIMEOUT, 3);
-		
-		while (SCmd.request.dev != 0xfffe);
-		
-		the_result = SCmd.result;
-		
+	  
+	  /*
+	   * Build an INQUIRY command block.  
+	   */
+	  
+	  scsi_cmd[0] = INQUIRY;
+	  scsi_cmd[1] = (lun << 5) & 0xe0;
+	  scsi_cmd[2] = 0;
+	  scsi_cmd[3] = 0;
+	  scsi_cmd[4] = 255;
+	  scsi_cmd[5] = 0;
+	  
+	  SCmd.request.dev = 0xffff; /* Mark not busy */
+	  
+	  scsi_do_cmd (&SCmd,
+		       (void *)  scsi_cmd, (void *) 
+		       scsi_result, 256,  scan_scsis_done, 
+		       SCSI_TIMEOUT, 3);
+	  
+	  while (SCmd.request.dev != 0xfffe);
+	  
+	  the_result = SCmd.result;
+	  
 #if defined(DEBUG) || defined(DEBUG_INIT)
-		if (!the_result)
-			printk("scsi: INQUIRY successful\n");
-		else
-			printk("scsi: INQUIRY failed with code %08x\n");
+	  if (!the_result)
+	    printk("scsi: INQUIRY successful\n");
+	  else
+	    printk("scsi: INQUIRY failed with code %08x\n");
 #endif
-
-		if(the_result) break; 
-
-		/* skip other luns on this device */
-		
-		if (!the_result)
-		  {
-		    scsi_devices[NR_SCSI_DEVICES].
-		      removable = (0x80 & 
-				   scsi_result[1]) >> 7;
-		    scsi_devices[NR_SCSI_DEVICES].lockable =
-		      scsi_devices[NR_SCSI_DEVICES].removable;
-		    scsi_devices[NR_SCSI_DEVICES].
-		      changed = 0;
-		    scsi_devices[NR_SCSI_DEVICES].
-		      access_count = 0;
-		    scsi_devices[NR_SCSI_DEVICES].
-		      busy = 0;
+	  
+	  if(the_result) break; 
+	  
+	  /* skip other luns on this device */
+	  
+	  if (!the_result)
+	    {
+	      SDpnt->removable = (0x80 & 
+				  scsi_result[1]) >> 7;
+	      SDpnt->lockable = SDpnt->removable;
+	      SDpnt->changed = 0;
+	      SDpnt->access_count = 0;
+	      SDpnt->busy = 0;
 /* 
  *	Currently, all sequential devices are assumed to be tapes,
  *	all random devices disk, with the appropriate read only 
  *	flags set for ROM / WORM treated as RO.
  */ 
 
-		    switch (type = scsi_result[0])
-		      {
-		      case TYPE_TAPE :
-		      case TYPE_DISK :
-		      case TYPE_MOD :
-			scsi_devices[NR_SCSI_DEVICES].writeable = 1;
-			break;
-		      case TYPE_WORM :
-		      case TYPE_ROM :
-			scsi_devices[NR_SCSI_DEVICES].writeable = 0;
-			break;
-			default :
+	      switch (type = scsi_result[0])
+		{
+		case TYPE_TAPE :
+		case TYPE_DISK :
+		case TYPE_MOD :
+		  SDpnt->writeable = 1;
+		  break;
+		case TYPE_WORM :
+		case TYPE_ROM :
+		  SDpnt->writeable = 0;
+		  break;
+		default :
 #if 0
 #ifdef DEBUG
-			printk("scsi: unknown type %d\n", type);
-			print_inquiry(scsi_result);
+		  printk("scsi: unknown type %d\n", type);
+		  print_inquiry(scsi_result);
 #endif
 #endif
-			  type = -1;
-		      }
-
-		    scsi_devices[NR_SCSI_DEVICES].soft_reset = 
-		      (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2);
-		    scsi_devices[NR_SCSI_DEVICES].random = 
-		      (type == TYPE_TAPE) ? 0 : 1;
-		    scsi_devices[NR_SCSI_DEVICES].type = type;
-
-		    if (type != -1)
-		      {
-			print_inquiry(scsi_result);
-			switch(type){
-			case TYPE_TAPE:
-			  printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n", MAX_ST,
-				 shpnt->host_no , dev, lun); 
-			  if(NR_ST != -1) ++MAX_ST;
-			  break;
-			case TYPE_ROM:
-			  printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", MAX_SR,
-				 shpnt->host_no , dev, lun); 
-			  if(NR_SR != -1) ++MAX_SR;
-			  break;
-			case TYPE_DISK:
-			case TYPE_MOD:
-			  printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n", 'a'+MAX_SD,
-				 shpnt->host_no , dev, lun); 
-			  if(NR_SD != -1) ++MAX_SD;
-			  break;
-			default:
-			  break;
-			};
-
-			if(NR_SG != -1) ++MAX_SG;
-
-			scsi_devices[NR_SCSI_DEVICES].scsi_level =
-			  scsi_result[2] & 0x07;
-			if (scsi_devices[NR_SCSI_DEVICES].scsi_level >= 2 ||
-			    (scsi_devices[NR_SCSI_DEVICES].scsi_level == 1 &&
-			     (scsi_result[3] & 0x0f) == 1))
-			  scsi_devices[NR_SCSI_DEVICES].scsi_level++;
+		  type = -1;
+		}
+	      
+	      SDpnt->soft_reset = 
+		(scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2);
+	      SDpnt->random = (type == TYPE_TAPE) ? 0 : 1;
+	      SDpnt->type = type;
+	      
+	      if (type != -1)
+		{
+		  print_inquiry(scsi_result);
+		  switch(type){
+		  case TYPE_TAPE:
+		    printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n", MAX_ST,
+			   shpnt->host_no , dev, lun); 
+		    if(NR_ST != -1) ++MAX_ST;
+		    break;
+		  case TYPE_ROM:
+		    printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", MAX_SR,
+			   shpnt->host_no , dev, lun); 
+		    if(NR_SR != -1) ++MAX_SR;
+		    break;
+		  case TYPE_DISK:
+		  case TYPE_MOD:
+		    printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n", 'a'+MAX_SD,
+			   shpnt->host_no , dev, lun); 
+		    if(NR_SD != -1) ++MAX_SD;
+		    break;
+		  default:
+		    break;
+		  };
+		  
+		  if(NR_SG != -1) ++MAX_SG;
+		  
+		  SDpnt->scsi_level = scsi_result[2] & 0x07;
+		  if (SDpnt->scsi_level >= 2 ||
+		      (SDpnt->scsi_level == 1 &&
+		       (scsi_result[3] & 0x0f) == 1))
+		    SDpnt->scsi_level++;
 /* 
  * Set the tagged_queue flag for SCSI-II devices that purport to support
  * tagged queuing in the INQUIRY data.
  */
-
-			scsi_devices[NR_SCSI_DEVICES].tagged_queue = 0;
-
-			if ((scsi_devices[NR_SCSI_DEVICES].scsi_level >= SCSI_2) &&
-			    (scsi_result[7] & 2)) {
-			    scsi_devices[NR_SCSI_DEVICES].tagged_supported = 1;
-			    scsi_devices[NR_SCSI_DEVICES].current_tag = 0;
-			}
-
+		  
+		  SDpnt->tagged_queue = 0;
+		  
+		  if ((SDpnt->scsi_level >= SCSI_2) &&
+		      (scsi_result[7] & 2)) {
+		    SDpnt->tagged_supported = 1;
+		    SDpnt->current_tag = 0;
+		  }
+		  
 /*
  * Accomodate drivers that want to sleep when they should be in a polling
  * loop.
  */
 
-			scsi_devices[NR_SCSI_DEVICES].disconnect = 0;
+		  SDpnt->disconnect = 0;
 
 /*
  * Some revisions of the Texel CD ROM drives have handshaking
@@ -434,8 +427,8 @@
  * a TEXEL drive.
  */
 
-			if(strncmp("TEXEL", (char *) &scsi_result[8], 5) != 0 ||
-			  strncmp("CD-ROM", (char *) &scsi_result[16], 6) != 0 
+		  if(strncmp("TEXEL", (char *) &scsi_result[8], 5) != 0 ||
+		     strncmp("CD-ROM", (char *) &scsi_result[16], 6) != 0 
 /* 
  * XXX 1.06 has problems, some one should figure out the others too so
  * ALL TEXEL drives don't suffer in performance, especially when I finish
@@ -443,64 +436,69 @@
  */
 
 #ifdef notyet
-			   || (strncmp("1.06", (char *) &scsi_result[[, 4) != 0)
+		     || (strncmp("1.06", (char *) &scsi_result[[, 4) != 0)))
 #endif
-			   )
-			   scsi_devices[NR_SCSI_DEVICES].borken = 0;
-
-
-			/* These devices need this "key" to unlock the device
-			   so we can use it */
-			if(memcmp("INSITE", &scsi_result[8], 6) == 0 &&
-			   (memcmp("Floptical   F*8I", &scsi_result[16], 16) == 0
-			    || memcmp("I325VM", &scsi_result[16], 6) == 0)) {
-			  printk("Unlocked floptical drive.\n");
-			  scsi_devices[NR_SCSI_DEVICES].lockable = 0;
-			  scsi_cmd[0] = MODE_SENSE;
-			  scsi_cmd[1] = (lun << 5) & 0xe0;
-			  scsi_cmd[2] = 0x2e;
-			  scsi_cmd[3] = 0;
-			  scsi_cmd[4] = 0x2a;
-			  scsi_cmd[5] = 0;
-		
-			  SCmd.request.dev = 0xffff; /* Mark not busy */
-			  
-			  scsi_do_cmd (&SCmd,
-				       (void *)  scsi_cmd, (void *) 
-				       scsi_result, 0x2a,  scan_scsis_done, 
-				       SCSI_TIMEOUT, 3);
-		
-			  while (SCmd.request.dev != 0xfffe);
-			};
-
-			++NR_SCSI_DEVICES;
-			/* Some scsi devices cannot be polled for lun != 0
-			   due to firmware bugs */
-			if(blacklisted(scsi_result)) break;
-			/* Old drives like the MAXTOR XT-3280 say vers=0 */
-			if ((scsi_result[2] & 0x07) == 0)
-			    break;
-			/* Some scsi-1 peripherals do not handle lun != 0.
-			   I am assuming that scsi-2 peripherals do better */
-			if((scsi_result[2] & 0x07) == 1 && 
-			   (scsi_result[3] & 0x0f) == 0) break;
-			}
-		  }       /* if result == DID_OK ends */
-	      }       /* for lun ends */
-	shpnt->host_queue = NULL;  /* No longer needed here */
-      }      	/* if present */  
+				 )
+		    SDpnt->borken = 0;
+		  
+		  
+		  /* These devices need this "key" to unlock the device
+		     so we can use it */
+		  if(memcmp("INSITE", &scsi_result[8], 6) == 0 &&
+		     (memcmp("Floptical   F*8I", &scsi_result[16], 16) == 0
+		      || memcmp("I325VM", &scsi_result[16], 6) == 0)) {
+		    printk("Unlocked floptical drive.\n");
+		    SDpnt->lockable = 0;
+		    scsi_cmd[0] = MODE_SENSE;
+		    scsi_cmd[1] = (lun << 5) & 0xe0;
+		    scsi_cmd[2] = 0x2e;
+		    scsi_cmd[3] = 0;
+		    scsi_cmd[4] = 0x2a;
+		    scsi_cmd[5] = 0;
+		    
+		    SCmd.request.dev = 0xffff; /* Mark not busy */
+		    
+		    scsi_do_cmd (&SCmd,
+				 (void *)  scsi_cmd, (void *) 
+				 scsi_result, 0x2a,  scan_scsis_done, 
+				 SCSI_TIMEOUT, 3);
+		    
+		    while (SCmd.request.dev != 0xfffe);
+		  };
+		  SDpnt->next = scsi_devices;
+		  scsi_devices = SDpnt;
+		  ++NR_SCSI_DEVICES;
+		  SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof (Scsi_Device));
+		  /* Some scsi devices cannot be polled for lun != 0
+		     due to firmware bugs */
+		  if(blacklisted(scsi_result)) break;
+		  /* Old drives like the MAXTOR XT-3280 say vers=0 */
+		  if ((scsi_result[2] & 0x07) == 0)
+		    break;
+		  /* Some scsi-1 peripherals do not handle lun != 0.
+		     I am assuming that scsi-2 peripherals do better */
+		  if((scsi_result[2] & 0x07) == 1 && 
+		     (scsi_result[3] & 0x0f) == 0) break;
+		}
+	    }       /* if result == DID_OK ends */
+	}       /* for lun ends */
+  shpnt->host_queue = NULL;  /* No longer needed here */
   
   printk("scsi : detected ");
   if(NR_SD != -1)
     printk("%d SCSI disk%s ", MAX_SD, (MAX_SD != 1) ? "s" : "");
-	 
+  
   if(NR_ST != -1)
     printk("%d tape%s ", MAX_ST, (MAX_ST != 1) ? "s" : "");
-
+  
   if(NR_SR != -1)
     printk("%d CD-ROM drive%s ", MAX_SR, (MAX_SR != 1) ? "s" : "");
-
+  
   printk("total.\n");
+  
+  /* Last device block does not exist.  Free memory. */
+  scsi_init_free((char *) SDpnt, sizeof(Scsi_Device));
+  
   in_scan = 0;
 }       /* scan_scsis  ends */
 
@@ -560,34 +558,34 @@
 turned off when entering the routine.  It is the responsibility
 of the calling code to ensure that this is the case. */
 
-Scsi_Cmnd * request_queueable (struct request * req, int index)
+Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device)
 {
   Scsi_Cmnd * SCpnt = NULL;
   int tablesize;
   struct buffer_head * bh, *bhp;
 
-  if ((index < 0) ||  (index > NR_SCSI_DEVICES))
-    panic ("Index number in allocate_device() is out of range.\n");
+  if (!device)
+    panic ("No device passed to allocate_device().\n");
   
   if (req && req->dev <= 0)
     panic("Invalid device in allocate_device");
   
-  SCpnt =  scsi_devices[index].host->host_queue;
+  SCpnt =  device->host->host_queue;
     while(SCpnt){
-      if(SCpnt->target == scsi_devices[index].id &&
-	 SCpnt->lun == scsi_devices[index].lun)
+      if(SCpnt->target == device->id &&
+	 SCpnt->lun == device->lun)
 	if(SCpnt->request.dev < 0) break;
       SCpnt = SCpnt->next;
     };
 
   if (!SCpnt) return NULL;
 
-  if (scsi_devices[index].host->hostt->can_queue
-      && scsi_devices[index].host->host_busy >= scsi_devices[index].host->hostt->can_queue) return NULL;
+  if (device->host->hostt->can_queue
+      && device->host->host_busy >= device->host->hostt->can_queue) return NULL;
 
   if (req) {
     memcpy(&SCpnt->request, req, sizeof(struct request));
-    tablesize = scsi_devices[index].host->sg_tablesize;
+    tablesize = device->host->sg_tablesize;
     bhp = bh = req->bh;
     if(!tablesize) bh = NULL;
     /* Take a quick look through the table to see how big it is.  We already
@@ -636,7 +634,8 @@
 request_queueable function also knows the internal allocation scheme
 of the packets for each device */
 
-Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
+Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device,
+			     int wait)
 {
   int dev = -1;
   struct request * req = NULL;
@@ -646,21 +645,21 @@
   Scsi_Cmnd * SCpnt = NULL;
   Scsi_Cmnd * SCwait = NULL;
 
-  if ((index < 0) ||  (index > NR_SCSI_DEVICES))
-    panic ("Index number in allocate_device() is out of range.\n");
+  if (!device)
+    panic ("No device passed to allocate_device().\n");
   
   if (reqp) req = *reqp;
 
     /* See if this request has already been queued by an interrupt routine */
   if (req && (dev = req->dev) <= 0) return NULL;
   
-  host = scsi_devices[index].host;
+  host = device->host;
   
   while (1==1){
     SCpnt = host->host_queue;
     while(SCpnt){
-      if(SCpnt->target == scsi_devices[index].id &&
-	 SCpnt->lun == scsi_devices[index].lun) {
+      if(SCpnt->target == device->id &&
+	 SCpnt->lun == device->lun) {
 	SCwait = SCpnt;
 	if(SCpnt->request.dev < 0) break;
       };
@@ -677,16 +676,16 @@
 	sti();
 	if(!wait) return NULL;
 	if (!SCwait) {
-	  printk("Attempt to allocate device index %d, target %d, lun %d\n",
-		 index, scsi_devices[index].id ,scsi_devices[index].lun);
+	  printk("Attempt to allocate device target %d, lun %d\n",
+		 device->id ,device->lun);
 	  panic("No device found in allocate_device\n");
 	};
-	SCSI_SLEEP(&scsi_devices[SCwait->index].device_wait, 
+	SCSI_SLEEP(&device->device_wait, 
 		   (SCwait->request.dev > 0));
       } else {
 	if (req) {
 	  memcpy(&SCpnt->request, req, sizeof(struct request));
-	  tablesize = scsi_devices[index].host->sg_tablesize;
+	  tablesize = device->host->sg_tablesize;
 	  bhp = bh = req->bh;
 	  if(!tablesize) bh = NULL;
 	  /* Take a quick look through the table to see how big it is.  We already
@@ -987,7 +986,7 @@
 		case NO_SENSE:
 			return 0;
 		case RECOVERED_ERROR:
-			if (scsi_devices[SCpnt->index].type == TYPE_TAPE)
+			if (SCpnt->device->type == TYPE_TAPE)
 			  return SUGGEST_IS_OK;
 			else
 			  return 0;
@@ -1698,6 +1697,38 @@
   return 0;
 }
 
+
+/* These are special functions that can be used to obtain memory at boot time.
+   They act line a malloc function, but they simply take memory from the
+   pool */
+
+static unsigned int scsi_init_memory_start = 0;
+int scsi_loadable_module_flag; /* Set after we scan builtin drivers */
+
+void * scsi_init_malloc(unsigned int size)
+{
+  unsigned int retval;
+  if(scsi_loadable_module_flag) {
+    retval = (unsigned int) kmalloc(size, GFP_ATOMIC);
+  } else {
+    retval = scsi_init_memory_start;
+    scsi_init_memory_start += size;
+  }
+  return (void *) retval;
+}
+
+
+void scsi_init_free(char * ptr, unsigned int size)
+{ /* FIXME - not right.  We need to comare addresses to see whether this was
+     kmalloc'd or not */
+  if((unsigned int) ptr < scsi_loadable_module_flag) {
+    kfree(ptr);
+  } else {
+    if(((unsigned int) ptr) + size == scsi_init_memory_start)
+      scsi_init_memory_start = (unsigned int) ptr;
+  }
+}
+
 /*
 	scsi_dev_init() is our initialization routine, which inturn calls host 
 	initialization, bus scanning, and sd/st initialization routines.  It 
@@ -1706,90 +1737,90 @@
 
 unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end)
 	{
-	int i;
-	struct Scsi_Host * host;
+	struct Scsi_Host * host = NULL;
+	Scsi_Device * SDpnt;
+	struct Scsi_Host * shpnt;
 	Scsi_Cmnd * SCpnt;
 #ifdef FOO_ON_YOU
 	return;
 #endif	
+
+	/* Init a few things so we can "malloc" memory. */
+	scsi_loadable_module_flag = 0;
+	scsi_init_memory_start = memory_start;
+
 	timer_table[SCSI_TIMER].fn = scsi_main_timeout;
 	timer_table[SCSI_TIMER].expires = 0;
 
 	/* initialize all hosts */
-	memory_start = scsi_init(memory_start, memory_end); 
+	scsi_init(); 
 				
-	scsi_devices = (Scsi_Device *) memory_start;
-        scan_scsis();           /* scan for scsi devices */
-	memory_start += NR_SCSI_DEVICES * sizeof(Scsi_Device);
-
-	memory_start = sd_init1(memory_start, memory_end);
-        memory_start = st_init1(memory_start, memory_end);
-	memory_start = sr_init1(memory_start, memory_end);
-	memory_start = sg_init1(memory_start, memory_end);
+	scsi_devices = (Scsi_Device *) NULL;
 
-	last_cmnd = (Scsi_Cmnd *) memory_start;
+	for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
+	  scan_scsis(shpnt);           /* scan for scsi devices */
 
-	SCpnt = last_cmnd;
+	sd_init1();
+        st_init1();
+	sr_init1();
+	sg_init1();
 
-	for (i=0; i< NR_SCSI_DEVICES; i++) {
+	for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
 	  int j;
-	  scsi_devices[i].scsi_request_fn = NULL;
-	  switch (scsi_devices[i].type)
+	  SDpnt->scsi_request_fn = NULL;
+	  switch (SDpnt->type)
 	    {
 	    case TYPE_TAPE :
-	      st_attach(&scsi_devices[i]);
+	      st_attach(SDpnt);
 	      break;
 	    case TYPE_ROM:
-	      sr_attach(&scsi_devices[i]);
+	      sr_attach(SDpnt);
 	      break;
 	    case TYPE_DISK:
 	    case TYPE_MOD:
-	      sd_attach(&scsi_devices[i]);
+	      sd_attach(SDpnt);
 	    default:
 	      break;
 	    };
-	  sg_attach(&scsi_devices[i]);
-	  if(scsi_devices[i].type != -1){
-	    for(j=0;j<scsi_devices[i].host->hostt->cmd_per_lun;j++){
-	      SCpnt->host = scsi_devices[i].host;
-	      SCpnt->device = &scsi_devices[i];
-	      SCpnt->target = scsi_devices[i].id;
-	      SCpnt->lun = scsi_devices[i].lun;
-	      SCpnt->index = i;
+	  sg_attach(SDpnt);
+	  if(SDpnt->type != -1){
+	    for(j=0;j<SDpnt->host->hostt->cmd_per_lun;j++){
+	      SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd));
+	      SCpnt->host = SDpnt->host;
+	      SCpnt->device = SDpnt;
+	      SCpnt->target = SDpnt->id;
+	      SCpnt->lun = SDpnt->lun;
 	      SCpnt->request.dev = -1; /* Mark not busy */
 	      SCpnt->use_sg = 0;
 	      SCpnt->old_use_sg = 0;
               SCpnt->underflow = 0;
               SCpnt->transfersize = 0;
 	      SCpnt->host_scribble = NULL;
-	      host = scsi_devices[i].host;
+	      host = SDpnt->host;
 	      if(host->host_queue)
 		host->host_queue->prev = SCpnt;
 	      SCpnt->next = host->host_queue;
 	      SCpnt->prev = NULL;
 	      host->host_queue = SCpnt;
-	      SCpnt++;
 	    };
 	  };
 	};
 
-	memory_start = (int) SCpnt;
-
+	memory_start = scsi_init_memory_start;
 	if (NR_SD > 0 || NR_SR > 0 || NR_ST > 0)
 	  dma_sectors = 16;  /* Base value we use */
 
-	for (i = 0; i < NR_SCSI_DEVICES; ++i) {
-	  struct Scsi_Host * host;
-	  host = scsi_devices[i].host;
+	for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
+	  host = SDpnt->host;
 	  
-	  if(scsi_devices[i].type != TYPE_TAPE)
+	  if(SDpnt->type != TYPE_TAPE)
 	    dma_sectors += ((host->sg_tablesize * 
 			     sizeof(struct scatterlist) + 511) >> 9) * 
 			       host->hostt->cmd_per_lun;
 	  
 	  if(host->unchecked_isa_dma &&
 	     memory_end > ISA_DMA_THRESHOLD &&
-	     scsi_devices[i].type != TYPE_TAPE) {
+	     SDpnt->type != TYPE_TAPE) {
 	    dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
 	      host->hostt->cmd_per_lun;
 	    need_isa_buffer++;
@@ -1814,6 +1845,7 @@
 	memory_start = sr_init(memory_start, memory_end); /* init scsi CDROMs */
 	memory_start = sg_init(memory_start, memory_end); /* init scsi generic */
 	
+	scsi_loadable_module_flag = 1;
 	return memory_start;
 	}
 
@@ -1866,11 +1898,11 @@
 scsi_dump_status(void)
 {
   int i, i1;
+  Scsi_Host * shpnt;
   Scsi_Cmnd * SCpnt;
   printk("Dump of scsi parameters:\n");
-  SCpnt = last_cmnd;
-  for(i=0; i<NR_SCSI_DEVICES; i++)
-    for(i1=0; i1<scsi_devices[i].host->hostt->cmd_per_lun;i1++)
+  for(shpnt = scsi_hosts; shpnt; shpnt = shpnt->next)
+    for(SCpnt=shpnt->host_queue; SCpnt; SCpnt = SCpnt->next)
       {
 	/*  (0) 0:0:0 (802 123434 8 8 0) (3 3 2) (%d %d %d) %d %x      */
 	printk("(%d) %d:%d:%d (%4.4x %d %d %d %d) (%d %d %x) (%d %d %d) %x %x %d %x\n",
@@ -1893,7 +1925,6 @@
 	       (SCpnt->request.waiting ? 
 		SCpnt->request.waiting->pid : 0),
 	       SCpnt->result);
-	SCpnt++;
       };
   printk("wait_for_request = %x\n", wait_for_request);
   /* Now dump the request lists for each block device */
@@ -1919,3 +1950,5 @@
       }
 }
 #endif
+
+
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.1.27/linux/drivers/scsi/scsi.h	Fri Jun 17 15:20:06 1994
+++ linux/drivers/scsi/scsi.h	Wed Jul 13 01:16:06 1994
@@ -258,7 +258,8 @@
 */
 
 typedef struct scsi_device {
-	unsigned char id, lun, index;
+        struct scsi_device * next; /* Used for linked list */
+	unsigned char id, lun;
 	int access_count;	/* Count of open channels/mounts */
 	struct wait_queue * device_wait;  /* Used to wait if device is busy */
 	struct Scsi_Host * host;
@@ -406,7 +407,7 @@
 typedef struct scsi_cmnd {
 	struct Scsi_Host * host;
 	Scsi_Device * device;
-	unsigned char target, lun,  index;
+	unsigned char target, lun;
 	struct scsi_cmnd *next, *prev;	
 
 /* These elements define the operation we are about to perform */
@@ -493,27 +494,27 @@
                   int timeout, int retries);
 
 
-extern Scsi_Cmnd * allocate_device(struct request **, int, int);
+extern Scsi_Cmnd * allocate_device(struct request **, Scsi_Device *, int);
 
-extern Scsi_Cmnd * request_queueable(struct request *, int);
+extern Scsi_Cmnd * request_queueable(struct request *, Scsi_Device *);
 extern int scsi_reset (Scsi_Cmnd *);
 
 extern int max_scsi_hosts;
 extern int MAX_SD, NR_SD, MAX_ST, NR_ST, MAX_SR, NR_SR, NR_SG, MAX_SG;
 extern unsigned long sd_init(unsigned long, unsigned long);
-extern unsigned long sd_init1(unsigned long, unsigned long);
+extern void sd_init1(void);
 extern void sd_attach(Scsi_Device *);
 
 extern unsigned long sr_init(unsigned long, unsigned long);
-extern unsigned long sr_init1(unsigned long, unsigned long);
+extern void sr_init1(void);
 extern void sr_attach(Scsi_Device *);
 
 extern unsigned long st_init(unsigned long, unsigned long);
-extern unsigned long st_init1(unsigned long, unsigned long);
+extern void st_init1(void);
 extern void st_attach(Scsi_Device *);
 
 extern unsigned long sg_init(unsigned long, unsigned long);
-extern unsigned long sg_init1(unsigned long, unsigned long);
+extern void sg_init1(void);
 extern void sg_attach(Scsi_Device *);
 
 #if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR)
@@ -560,7 +561,7 @@
 			need_resched = 1;
 	}
 	req->dev = -1;
-	wake_up(&scsi_devices[SCpnt->index].device_wait);
+	wake_up(&SCpnt->device->device_wait);
 	return;
 }
 
@@ -584,17 +585,20 @@
 #endif
 
 #define SCSI_SLEEP(QUEUE, CONDITION) {				\
+	long old_state;						\
 	if (CONDITION) {					\
-                struct wait_queue wait = { current, NULL};      \
+		struct wait_queue wait = { current, NULL};	\
 		add_wait_queue(QUEUE, &wait);			\
 sleep_repeat:							\
+		old_state = current->state;			\
 		current->state = TASK_UNINTERRUPTIBLE;		\
 		if (CONDITION) {				\
 			schedule();				\
 			goto sleep_repeat;			\
 		}						\
 		remove_wait_queue(QUEUE, &wait);		\
-		current->state = TASK_RUNNING;			\
+		if (current->state == TASK_UNINTERRUPTIBLE)	\
+			current->state = old_state;		\
 	}; }
 
 #endif
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- v1.1.27/linux/drivers/scsi/scsi_debug.c	Fri Jul  8 13:26:38 1994
+++ linux/drivers/scsi/scsi_debug.c	Sun Jul 10 09:09:38 1994
@@ -100,7 +100,6 @@
 #endif
 
 static volatile void (*do_done[SCSI_DEBUG_MAILBOXES])(Scsi_Cmnd *) = {NULL, };
-static int scsi_debug_host = 0;
 extern void scsi_debug_interrupt();
 
 volatile Scsi_Cmnd * SCint[SCSI_DEBUG_MAILBOXES] = {NULL,};
@@ -513,9 +512,8 @@
 }
 
 
-int scsi_debug_detect(int hostnum)
+int scsi_debug_detect(Scsi_Host_Template * tpnt)
 {
-    scsi_debug_host = hostnum;
 #ifndef IMMEDIATE
     timer_table[SCSI_DEBUG_TIMER].fn = scsi_debug_intr_handle;
     timer_table[SCSI_DEBUG_TIMER].expires = 0;
@@ -528,7 +526,7 @@
     int j;
     void (*my_done)(Scsi_Cmnd *);
     DEB(printk("scsi_debug_abort\n"));
-    SCpnt->result = i << 16;
+    SCpnt->result = SCpnt->abort_reason << 16;
     for(j=0;j<SCSI_DEBUG_MAILBOXES; j++) {
       if(SCpnt == SCint[j]) {
 	my_done = do_done[j];
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/scsi_debug.h linux/drivers/scsi/scsi_debug.h
--- v1.1.27/linux/drivers/scsi/scsi_debug.h	Fri Jul  8 13:26:38 1994
+++ linux/drivers/scsi/scsi_debug.h	Sun Jul 10 09:09:38 1994
@@ -2,10 +2,10 @@
 
 #include <linux/types.h>
 
-int scsi_debug_detect(int);
+int scsi_debug_detect(Scsi_Host_Template *);
 int scsi_debug_command(Scsi_Cmnd *);
 int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int scsi_debug_abort(Scsi_Cmnd *, int);
+int scsi_debug_abort(Scsi_Cmnd *);
 int scsi_debug_biosparam(Disk *, int, int[]);
 const char *scsi_debug_info(void);
 int scsi_debug_reset(Scsi_Cmnd *);
@@ -16,7 +16,7 @@
 
 #define SCSI_DEBUG_MAILBOXES 8
 
-#define SCSI_DEBUG {"SCSI DEBUG", scsi_debug_detect,	\
+#define SCSI_DEBUG {NULL, "SCSI DEBUG", scsi_debug_detect, NULL,	\
 		scsi_debug_info, scsi_debug_command,		\
 		scsi_debug_queuecommand,			\
 		scsi_debug_abort,				\
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- v1.1.27/linux/drivers/scsi/scsi_ioctl.c	Tue Jun 21 14:16:23 1994
+++ linux/drivers/scsi/scsi_ioctl.c	Sun Jul 10 09:09:37 1994
@@ -91,7 +91,7 @@
 	int result;
 	Scsi_Cmnd * SCpnt;
 
-	SCpnt = allocate_device(NULL, dev->index, 1);
+	SCpnt = allocate_device(NULL, dev, 1);
 	scsi_do_cmd(SCpnt,  cmd, NULL,  0,
 			scsi_ioctl_done,  MAX_TIMEOUT,
 			MAX_RETRIES);
@@ -135,7 +135,7 @@
 
 	result = SCpnt->result;
 	SCpnt->request.dev = -1;
-	wake_up(&scsi_devices[SCpnt->index].device_wait);
+	wake_up(&SCpnt->device->device_wait);
 	return result;
 }
 
@@ -175,7 +175,7 @@
 
 #ifndef DEBUG_NO_CMD
 	
-	SCpnt = allocate_device(NULL, dev->index, 1);
+	SCpnt = allocate_device(NULL, dev, 1);
 
 	scsi_do_cmd(SCpnt,  cmd,  buf, needed,  scsi_ioctl_done,  MAX_TIMEOUT, 
 			MAX_RETRIES);
@@ -204,10 +204,10 @@
 	SCpnt->request.dev = -1;  /* Mark as not busy */
 	if (buf) scsi_free(buf, buf_needed);
 
-	if(scsi_devices[SCpnt->index].scsi_request_fn)
-	  (*scsi_devices[SCpnt->index].scsi_request_fn)();
+	if(SCpnt->device->scsi_request_fn)
+	  (*SCpnt->device->scsi_request_fn)();
 
-	wake_up(&scsi_devices[SCpnt->index].device_wait);
+	wake_up(&SCpnt->device->device_wait);
 	return result;
 #else
 	{
@@ -236,8 +236,8 @@
 {
         char scsi_cmd[12];
 
-	if ((cmd != 0 && dev->index > NR_SCSI_DEVICES))
-		return -ENXIO;
+	/* No idea how this happens.... */
+	if (!dev) return -ENXIO;
 	
 	switch (cmd) {
 	        case SCSI_IOCTL_GET_IDLUN:
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v1.1.27/linux/drivers/scsi/sd.c	Fri Jul  8 13:26:39 1994
+++ linux/drivers/scsi/sd.c	Wed Jul 13 01:02:07 1994
@@ -42,7 +42,7 @@
 #define SD_MOD_TIMEOUT 750
 
 #define CLUSTERABLE_DEVICE(SC) (SC->host->hostt->use_clustering && \
-			    scsi_devices[SC->index].type != TYPE_MOD)
+			    SC->device->type != TYPE_MOD)
 
 struct hd_struct * sd;
 
@@ -347,7 +347,7 @@
 
     if (flag++ == 0)
       SCpnt = allocate_device(&CURRENT,
-			      rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0); 
+			      rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
     else SCpnt = NULL;
     sti();
 
@@ -365,7 +365,7 @@
       req = CURRENT;
       while(req){
 	SCpnt = request_queueable(req,
-				  rscsi_disks[DEVICE_NR(MINOR(req->dev))].device->index);
+				  rscsi_disks[DEVICE_NR(MINOR(req->dev))].device);
 	if(SCpnt) break;
 	req1 = req;
 	req = req->next;
@@ -734,7 +734,7 @@
 	scsi_do_cmd (SCpnt, (void *) cmd, buff, 
 		     this_count * rscsi_disks[dev].sector_size,
 		     rw_intr, 
-		     (scsi_devices[SCpnt->index].type == TYPE_DISK ? 
+		     (SCpnt->device->type == TYPE_DISK ? 
 		                     SD_TIMEOUT : SD_MOD_TIMEOUT),
 		     MAX_RETRIES);
 }
@@ -801,7 +801,7 @@
      a fatal error, and many devices report such an error just after a scsi
      bus reset. */
 
-  SCpnt = allocate_device(NULL, rscsi_disks[i].device->index, 1);
+  SCpnt = allocate_device(NULL, rscsi_disks[i].device, 1);
   buffer = (unsigned char *) scsi_malloc(512);
 
   spintime = 0;
@@ -852,7 +852,7 @@
 	};
 
 	time1 = jiffies;
-	while(jiffies < time1 + 100); /* Wait 1 second for next try */
+	while(jiffies < time1 + HZ); /* Wait 1 second for next try */
 	printk( "." );
       };
     } while(the_result && spintime && spintime+5000 > jiffies);
@@ -896,7 +896,7 @@
 
   SCpnt->request.dev = -1;  /* Mark as not busy */
 
-  wake_up(&scsi_devices[SCpnt->index].device_wait); 
+  wake_up(&SCpnt->device->device_wait); 
 
   /* Wake up a process waiting for device*/
 
@@ -1031,10 +1031,8 @@
 	return memory_start;
 }
 
-unsigned long sd_init1(unsigned long mem_start, unsigned long mem_end){
-  rscsi_disks = (Scsi_Disk *) mem_start;
-  mem_start += MAX_SD * sizeof(Scsi_Disk);
-  return mem_start;
+void sd_init1(){
+  rscsi_disks = (Scsi_Disk *) scsi_init_malloc(MAX_SD * sizeof(Scsi_Disk));
 };
 
 void sd_attach(Scsi_Device * SDp){
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- v1.1.27/linux/drivers/scsi/seagate.c	Fri Jul  8 13:26:39 1994
+++ linux/drivers/scsi/seagate.c	Sun Jul 10 09:09:37 1994
@@ -272,8 +272,9 @@
 
 #endif /* def SLOW_HANDSHAKE */
 
-int seagate_st0x_detect (int hostnum)
+int seagate_st0x_detect (Scsi_Host_Template * tpnt)
 	{
+     struct Scsi_Host *instance;
 #ifndef OVERRIDE
 	int i,j;
 #endif 
@@ -336,7 +337,7 @@
 #endif /* OVERIDE */
 	} /* (! controller_type) */
  
-	scsi_hosts[hostnum].this_id = (controller_type == SEAGATE) ? 7 : 6;
+	tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
 
 	if (base_address)
 		{
@@ -349,7 +350,8 @@
  *	At all times, we will use IRQ 5.  Should also check for IRQ3 if we 
  * 	loose our first interrupt.
  */
-		hostno = hostnum;
+		instance = scsi_register(tpnt, 0);
+		hostno = instance->host_no;
 		if (irqaction((int) irq, &seagate_sigaction)) {
 			printk("scsi%d : unable to allocate IRQ%d\n",
 				hostno, (int) irq);
@@ -615,7 +617,7 @@
 	st0x_aborted = 0;
 
 #ifdef SLOW_HANDSHAKE
-	borken = (int) scsi_devices[SCint->index].borken;
+	borken = (int) SCint->device->borken;
 #endif
 
 #if (DEBUG & PRINT_COMMAND)
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/seagate.h linux/drivers/scsi/seagate.h
--- v1.1.27/linux/drivers/scsi/seagate.h	Fri Jul  8 13:26:39 1994
+++ linux/drivers/scsi/seagate.h	Sun Jul 10 09:09:38 1994
@@ -12,7 +12,7 @@
 	$Header
 */
 #ifndef ASM
-int seagate_st0x_detect(int);
+int seagate_st0x_detect(Scsi_Host_Template *);
 int seagate_st0x_command(Scsi_Cmnd *);
 int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 
@@ -26,7 +26,8 @@
 
 int seagate_st0x_biosparam(Disk *, int, int*);
 
-#define SEAGATE_ST0X  {"Seagate ST-01/ST-02", seagate_st0x_detect, 	\
+#define SEAGATE_ST0X  {NULL, "Seagate ST-01/ST-02", seagate_st0x_detect, \
+			 NULL, 						\
 			 seagate_st0x_info, seagate_st0x_command,  	\
 			 seagate_st0x_queue_command, seagate_st0x_abort, \
 			 seagate_st0x_reset, NULL, seagate_st0x_biosparam, \
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v1.1.27/linux/drivers/scsi/sg.c	Fri Jun 17 15:20:07 1994
+++ linux/drivers/scsi/sg.c	Sun Jul 10 09:09:37 1994
@@ -252,7 +252,7 @@
 #ifdef DEBUG
   printk("allocating device\n");
 #endif
-  if (!(SCpnt=allocate_device(NULL,device->device->index, !(filp->f_flags & O_NONBLOCK))))
+  if (!(SCpnt=allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
    {
     device->pending=0;
     wake_up(&device->write_wait);
@@ -317,11 +317,10 @@
   return mem_start;
  }
 
-unsigned long sg_init1(unsigned long mem_start, unsigned long mem_end)
+void sg_init1()
  {
-  scsi_generics = (struct scsi_generic *) mem_start;
-  mem_start += MAX_SG * sizeof(struct scsi_generic);
-  return mem_start;
+  scsi_generics = (struct scsi_generic *) 
+    scsi_init_malloc(MAX_SG * sizeof(struct scsi_generic));
  };
 
 void sg_attach(Scsi_Device * SDp)
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v1.1.27/linux/drivers/scsi/sr.c	Fri Jul  8 13:26:39 1994
+++ linux/drivers/scsi/sr.c	Sun Jul 10 09:09:36 1994
@@ -307,7 +307,7 @@
 
     if (flag++ == 0)
       SCpnt = allocate_device(&CURRENT,
-			      scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0); 
+			      scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
     else SCpnt = NULL;
     sti();
 
@@ -325,7 +325,7 @@
       req = CURRENT;
       while(req){
 	SCpnt = request_queueable(req,
-				  scsi_CDs[DEVICE_NR(MINOR(req->dev))].device->index);
+				  scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
 	if(SCpnt) break;
 	req1 = req;
 	req = req->next;
@@ -623,10 +623,8 @@
 		     rw_intr, SR_TIMEOUT, MAX_RETRIES);
 }
 
-unsigned long sr_init1(unsigned long mem_start, unsigned long mem_end){
-  scsi_CDs = (Scsi_CD *) mem_start;
-  mem_start += MAX_SR * sizeof(Scsi_CD);
-  return mem_start;
+void sr_init1(){
+  scsi_CDs = (Scsi_CD *) scsi_init_malloc(MAX_SR * sizeof(Scsi_CD));
 };
 
 void sr_attach(Scsi_Device * SDp){
@@ -657,7 +655,7 @@
   int the_result, retries;
   Scsi_Cmnd * SCpnt;
   
-  SCpnt = allocate_device(NULL, scsi_CDs[i].device->index, 1);
+  SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 
   retries = 3;
   do {
@@ -689,7 +687,7 @@
   
   SCpnt->request.dev = -1;  /* Mark as not busy */
   
-  wake_up(&scsi_devices[SCpnt->index].device_wait); 
+  wake_up(&SCpnt->device->device_wait); 
 
   if (the_result) {
     scsi_CDs[i].capacity = 0x1fffff;
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v1.1.27/linux/drivers/scsi/sr_ioctl.c	Tue Apr 19 10:52:50 1994
+++ linux/drivers/scsi/sr_ioctl.c	Sun Jul 10 09:09:36 1994
@@ -43,7 +43,7 @@
 	Scsi_Cmnd * SCpnt;
 	int result;
 
-	SCpnt = allocate_device(NULL, scsi_CDs[target].device->index, 1);
+	SCpnt = allocate_device(NULL, scsi_CDs[target].device, 1);
 	scsi_do_cmd(SCpnt,
 		    (void *) sr_cmd, buffer, buflength, sr_ioctl_done, 
 		    IOCTL_TIMEOUT, IOCTL_RETRIES);
@@ -85,7 +85,7 @@
 
 	result = SCpnt->result;
 	SCpnt->request.dev = -1; /* Deallocate */
-	wake_up(&scsi_devices[SCpnt->index].device_wait);
+	wake_up(&SCpnt->device->device_wait);
 	/* Wake up a process waiting for device*/
       	return result;
 }
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v1.1.27/linux/drivers/scsi/st.c	Fri Jul  8 13:26:39 1994
+++ linux/drivers/scsi/st.c	Sun Jul 10 09:09:36 1994
@@ -230,7 +230,7 @@
   cmd[2] = cmd[3] = cmd[4] = 0xff;  /* -1 filemarks */
   cmd[5] = 0;
 
-  SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+  SCpnt = allocate_device(NULL, STp->device, 1);
   SCpnt->sense_buffer[0] = 0;
   SCpnt->request.dev = dev;
   scsi_do_cmd(SCpnt,
@@ -275,7 +275,7 @@
 
   result = 0;
   if (STp->dirty == 1) {
-    SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+    SCpnt = allocate_device(NULL, STp->device, 1);
 
     offset = (STp->buffer)->buffer_bytes;
     transfer = ((offset + STp->block_size - 1) /
@@ -411,7 +411,7 @@
     STp->eof_hit = 0;
     STp->recover_count = 0;
 
-    SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+    SCpnt = allocate_device(NULL, STp->device, 1);
     if (!SCpnt) {
       printk("st%d: Tape request not allocated", dev);
       return (-EBUSY);
@@ -597,7 +597,7 @@
 #endif
 
       if (result == 0 || result == (-ENOSPC)) {
-	SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+	SCpnt = allocate_device(NULL, STp->device, 1);
 
 	SCpnt->sense_buffer[0] = 0;
 	memset(cmd, 0, 10);
@@ -718,7 +718,7 @@
     if (!STp->do_async_writes)
       write_threshold--;
 
-    SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+    SCpnt = allocate_device(NULL, STp->device, 1);
 
     total = count;
 
@@ -925,7 +925,7 @@
 
     STp->rw = ST_READING;
 
-    SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+    SCpnt = allocate_device(NULL, STp->device, 1);
 
     for (total = 0; total < count; ) {
 
@@ -1413,7 +1413,7 @@
        return (-ENOSYS);
      }
 
-   SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+   SCpnt = allocate_device(NULL, STp->device, 1);
    SCpnt->sense_buffer[0] = 0;
    SCpnt->request.dev = dev;
    scsi_do_cmd(SCpnt,
@@ -1594,7 +1594,7 @@
      if (i)
        return i;
 
-     SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+     SCpnt = allocate_device(NULL, STp->device, 1);
 
      SCpnt->sense_buffer[0]=0;
      memset (scmd, 0, 10);
@@ -1682,17 +1682,16 @@
   if(NR_ST > MAX_ST) panic ("scsi_devices corrupt (st)");
 };
 
-unsigned long st_init1(unsigned long mem_start, unsigned long mem_end){
-  scsi_tapes = (Scsi_Tape *) mem_start;
-  mem_start += MAX_ST * sizeof(Scsi_Tape);
-  return mem_start;
+void st_init1(){
+  scsi_tapes = (Scsi_Tape *) scsi_init_malloc(MAX_ST * sizeof(Scsi_Tape));
 };
 
 /* Driver initialization */
 unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
 {
-  int i, dev_nbr;
+  int i;
   Scsi_Tape * STp;
+  Scsi_Device * SDp;
 
   if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
     printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
@@ -1705,7 +1704,7 @@
 	 st_buffer_size, st_write_threshold);
 #endif
 
-  for (i=0, dev_nbr=(-1); i < NR_ST; ++i) {
+  for (i=0, SDp = scsi_devices; i < NR_ST; ++i) {
     STp = &(scsi_tapes[i]);
     STp->capacity = 0xfffff;
     STp->dirty = 0;
@@ -1726,17 +1725,18 @@
     mem_start += sizeof(struct mtget);
     /* Initialize status */
     memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
-    for (dev_nbr++; dev_nbr < NR_SCSI_DEVICES; dev_nbr++)
-      if (scsi_devices[dev_nbr].type == TYPE_TAPE)
+    for (; SDp; SDp = SDp->next)
+      if (SDp->type == TYPE_TAPE)
 	break;
-    if (dev_nbr >= NR_SCSI_DEVICES)
+    if (!SDp)
       printk("st%d: ERROR: Not found in scsi chain.\n", i);
     else {
-      if (scsi_devices[dev_nbr].scsi_level <= 2)
+      if (SDp->scsi_level <= 2)
 	STp->mt_status->mt_type = MT_ISSCSI1;
       else
 	STp->mt_status->mt_type = MT_ISSCSI2;
     }
+    SDp = SDp->next;
   }
 
   /* Allocate the buffers */
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c
--- v1.1.27/linux/drivers/scsi/t128.c	Fri Jul  8 13:26:40 1994
+++ linux/drivers/scsi/t128.c	Sun Jul 10 09:09:38 1994
@@ -181,19 +181,19 @@
 static struct sigaction t128_sigaction =  { t128_intr, 0, SA_INTERRUPT , NULL };
 
 /* 
- * Function : int t128_detect(int hostno)
+ * Function : int t128_detect(Scsi_Host_Template * tpnt)
  *
  * Purpose : detects and initializes T128,T128F, or T228 controllers
  *	that were autoprobed, overriden on the LILO command line, 
  *	or specified at compile time.
  *
- * Inputs : hostno - id of this SCSI adapter.
+ * Inputs : tpnt - template for this SCSI adapter.
  * 
  * Returns : 1 if a host adapter was found, 0 if not.
  *
  */
 
-int t128_detect(int hostno) {
+int t128_detect(Scsi_Host_Template * tpnt) {
     static int current_override = 0, current_base = 0;
     struct Scsi_Host *instance;
     unsigned char *base;
@@ -207,7 +207,7 @@
 	else 
 	    for (; !base && (current_base < NO_BASES); ++current_base) {
 #if (TDEBUG & TDEBUG_INIT)
-    printk("scsi%d : probing address %08x\n", hostno, (unsigned int) bases[current_base].address);
+    printk("scsi : probing address %08x\n", (unsigned int) bases[current_base].address);
 #endif
 		for (sig = 0; sig < NO_SIGNATURES; ++sig) 
 		    if (!bases[current_base].noauto && !memcmp 
@@ -215,20 +215,20 @@
 			signatures[sig].string, strlen(signatures[sig].string))) {
 			base = bases[current_base].address;
 #if (TDEBUG & TDEBUG_INIT)
-			printk("scsi%d : detected board.\n", hostno);
+			printk("scsi-t128 : detected board.\n");
 #endif
 			break;
 		    }
 	    }
 
 #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi%d : base = %08x\n", hostno, (unsigned int) base);
+	printk("scsi-t128 : base = %08x\n", (unsigned int) base);
 #endif
 
 	if (!base)
 	    break;
 
-	instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
+	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
 	instance->base = base;
 
 	NCR5380_init(instance);
@@ -241,17 +241,17 @@
 	if (instance->irq != IRQ_NONE) 
 	    if (irqaction (instance->irq, &t128_sigaction)) {
 		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
-		    hostno, instance->irq);
+		    instance->host_no, instance->irq);
 		instance->irq = IRQ_NONE;
 	    } 
 
 	if (instance->irq == IRQ_NONE) {
-	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", hostno);
-	    printk("scsi%d : please jumper the board for a free IRQ.\n", hostno);
+	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+	    printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 	}
 
 #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi%d : irq = %d\n", hostno, instance->irq);
+	printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
 #endif
 
 	printk("scsi%d : at 0x%08x", instance->host_no, (int) 
@@ -267,7 +267,6 @@
 
 	++current_override;
 	++count;
-	++hostno;
     }
     return count;
 }
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/t128.h linux/drivers/scsi/t128.h
--- v1.1.27/linux/drivers/scsi/t128.h	Fri Jul  8 13:26:40 1994
+++ linux/drivers/scsi/t128.h	Sun Jul 10 09:09:38 1994
@@ -93,7 +93,7 @@
 #ifndef ASM
 int t128_abort(Scsi_Cmnd *);
 int t128_biosparam(Disk *, int, int*);
-int t128_detect(int);
+int t128_detect(Scsi_Host_Template *);
 const char *t128_info(void);
 int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int t128_reset(Scsi_Cmnd *);
@@ -118,7 +118,8 @@
 
 #ifdef HOSTS_C
 
-#define TRANTOR_T128 {"Trantor T128/T128F/T228", t128_detect, t128_info,\
+#define TRANTOR_T128 {NULL, "Trantor T128/T128F/T228", t128_detect, NULL,  \
+	t128_info,							\
 	NULL, t128_queue_command, t128_abort, t128_reset, NULL, 	\
 	t128_biosparam, 						\
 	/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,			\
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- v1.1.27/linux/drivers/scsi/ultrastor.c	Fri Jul  8 13:26:40 1994
+++ linux/drivers/scsi/ultrastor.c	Sun Jul 10 09:09:37 1994
@@ -241,9 +241,6 @@
   volatile int csir_done;
 #endif
 
-  /* Our index in the host adapter array maintained by higher-level driver */
-  int host_number;
-
   /* A pool of MSCP structures for this adapter, and a bitmask of
      busy structures.  (If ULTRASTOR_14F_MAX_CMDS == 1, a 1 byte
      busy flag is used instead.)  */
@@ -339,7 +336,7 @@
 }
 #endif
 
-static int ultrastor_14f_detect(int hostnum)
+static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
 {
     size_t i;
     unsigned char in_byte, version_byte = 0;
@@ -486,9 +483,8 @@
 	   config.port_address, config.bios_segment, config.interrupt,
 	   config.dma_channel, config.ha_scsi_id, config.subversion);
 #endif
-    config.host_number = hostnum;
-    scsi_hosts[hostnum].this_id = config.ha_scsi_id;
-    scsi_hosts[hostnum].unchecked_isa_dma = (config.subversion != U34F);
+    tpnt->this_id = config.ha_scsi_id;
+    tpnt->unchecked_isa_dma = (config.subversion != U34F);
 
 #if ULTRASTOR_MAX_CMDS > 1
     config.mscp_free = ~0;
@@ -505,14 +501,14 @@
 	free_irq(config.interrupt);
 	return FALSE;
     }
-    scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_14F_MAX_SG;
+    tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
     printk("UltraStor driver version" VERSION ".  Using %d SG lists.\n",
 	   ULTRASTOR_14F_MAX_SG);
 
     return TRUE;
 }
 
-static int ultrastor_24f_detect(int hostnum)
+static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
 {
   register int i;
   struct Scsi_Host * shpnt = NULL;
@@ -589,12 +585,11 @@
 	     config.port_address, config.bios_segment,
 	     config.interrupt, config.ha_scsi_id);
 #endif
-      config.host_number = hostnum;
-      scsi_hosts[hostnum].this_id = config.ha_scsi_id;
-      scsi_hosts[hostnum].unchecked_isa_dma = 0;
-      scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_24F_MAX_SG;
+      tpnt->this_id = config.ha_scsi_id;
+      tpnt->unchecked_isa_dma = 0;
+      tpnt->sg_tablesize = ULTRASTOR_24F_MAX_SG;
 
-      shpnt = scsi_register(hostnum, 0);
+      shpnt = scsi_register(tpnt, 0);
       shpnt->irq = config.interrupt;
       shpnt->dma_channel = config.dma_channel;
       shpnt->io_port = config.port_address;
@@ -611,15 +606,15 @@
       outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
       outb(0x02, SYS_DOORBELL_MASK(addr+12));
       printk("UltraStor driver version " VERSION ".  Using %d SG lists.\n",
-	     scsi_hosts[hostnum].sg_tablesize);
+	     tpnt->sg_tablesize);
       return TRUE;
     }
   return FALSE;
 }
 
-int ultrastor_detect(int hostnum)
+int ultrastor_detect(Scsi_Host_Template * tpnt)
 {
-  return ultrastor_14f_detect(hostnum) || ultrastor_24f_detect(hostnum);
+  return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
 }
 
 const char *ultrastor_info(void)
@@ -699,7 +694,7 @@
        activity. 
 
        ???  Which other device types should never use the cache?   */
-    my_mscp->ca = scsi_devices[SCpnt->index].type != TYPE_TAPE;
+    my_mscp->ca = SCpnt->device->type != TYPE_TAPE;
     my_mscp->target_id = SCpnt->target;
     my_mscp->ch_no = 0;
     my_mscp->lun = SCpnt->lun;
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/ultrastor.h linux/drivers/scsi/ultrastor.h
--- v1.1.27/linux/drivers/scsi/ultrastor.h	Fri Jul  8 13:26:40 1994
+++ linux/drivers/scsi/ultrastor.h	Sun Jul 10 09:09:36 1994
@@ -13,7 +13,7 @@
 #ifndef _ULTRASTOR_H
 #define _ULTRASTOR_H
 
-int ultrastor_detect(int);
+int ultrastor_detect(Scsi_Host_Template *);
 const char *ultrastor_info(void);
 int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int ultrastor_abort(Scsi_Cmnd *);
@@ -29,12 +29,24 @@
 #define ULTRASTOR_24F_PORT 0xC80
 
 
-#define ULTRASTOR_14F \
-    { "UltraStor 14F/24F/34F", ultrastor_detect, ultrastor_info, 0, \
-      ultrastor_queuecommand, ultrastor_abort, ultrastor_reset, \
-      0, ultrastor_biosparam, ULTRASTOR_MAX_CMDS, 0, \
-      ULTRASTOR_14F_MAX_SG, ULTRASTOR_MAX_CMDS_PER_LUN, 0, 1, \
-	ENABLE_CLUSTERING }
+#define ULTRASTOR_14F { NULL, /* Ptr for modules*/	\
+			  "UltraStor 14F/24F/34F", 	\
+			  ultrastor_detect, 		\
+			  NULL,	/* Release */		\
+			  ultrastor_info, 		\
+			  0, 				\
+			  ultrastor_queuecommand,	\
+			  ultrastor_abort, 		\
+			  ultrastor_reset,		\
+			  0,				\
+			  ultrastor_biosparam, 		\
+			  ULTRASTOR_MAX_CMDS,		\
+			  0, 				\
+			  ULTRASTOR_14F_MAX_SG, 	\
+			  ULTRASTOR_MAX_CMDS_PER_LUN, 	\
+			  0, 				\
+			  1, 				\
+			  ENABLE_CLUSTERING }
 
 
 #ifdef ULTRASTOR_PRIVATE
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c
--- v1.1.27/linux/drivers/scsi/wd7000.c	Fri Jul  8 13:26:40 1994
+++ linux/drivers/scsi/wd7000.c	Sun Jul 10 09:09:38 1994
@@ -156,7 +156,6 @@
  *
  */
 typedef struct adapter {
-  int num;                          /* Index into Scsi_hosts array */
   struct Scsi_Host *sh;             /* Pointer to Scsi_Host structure */
   int iobase;                       /* This adapter's I/O base address */
   int irq;                          /* This adapter's IRQ level */
@@ -1090,7 +1089,7 @@
 }
 
 
-int wd7000_detect(int hostnum)
+int wd7000_detect(Scsi_Host_Template * tpnt)
 /* 
  *  Returns the number of adapters this driver is supporting.
  *
@@ -1137,21 +1136,21 @@
 		 *  Scsi_Host structure (sh), and is located by the empty
 		 *  array hostdata.
 		 */
-		sh = scsi_register( hostnum, sizeof(Adapter) );
+		sh = scsi_register(tpnt, sizeof(Adapter) );
 		host = (Adapter *) sh->hostdata;
 #ifdef DEBUG
 		printk("wd7000_detect: adapter allocated at %06x\n",
 		       (int)host);
 #endif
 		memset( host, 0, sizeof(Adapter) );
-	        host->num = hostnum;  host->sh = sh;
+	        host->sh = sh;
 		host->irq = cfg->irq;
 		host->iobase = cfg->iobase;
 		host->dma = cfg->dma;
 		irq2host[host->irq] = host;
 
 		if (!wd7000_init(host))  {  /* Initialization failed */
-		    scsi_unregister( sh, sizeof(Adapter) );
+		    scsi_unregister (sh);
 		    continue;
 		}
 
diff -u --recursive --new-file v1.1.27/linux/drivers/scsi/wd7000.h linux/drivers/scsi/wd7000.h
--- v1.1.27/linux/drivers/scsi/wd7000.h	Fri Jul  8 13:26:40 1994
+++ linux/drivers/scsi/wd7000.h	Sun Jul 10 09:09:38 1994
@@ -12,7 +12,7 @@
 
 #include <linux/types.h>
 
-int wd7000_detect(int);
+int wd7000_detect(Scsi_Host_Template *);
 int wd7000_command(Scsi_Cmnd *);
 int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int wd7000_abort(Scsi_Cmnd *);
@@ -38,9 +38,10 @@
 #define WD7000_Q    16
 #define WD7000_SG   16
 
-#define WD7000 {\
+#define WD7000 { NULL, \
 	"Western Digital WD-7000",      \
 	wd7000_detect,                  \
+	NULL,				\
 	wd7000_info,                    \
 	wd7000_command,	                \
 	wd7000_queuecommand,	        \
diff -u --recursive --new-file v1.1.27/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
--- v1.1.27/linux/fs/isofs/inode.c	Sat Jul  9 16:30:46 1994
+++ linux/fs/isofs/inode.c	Sun Jul 10 09:09:35 1994
@@ -6,7 +6,6 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 
-#include <linux/config.h>
 #include <linux/stat.h>
 #include <linux/sched.h>
 #include <linux/iso_fs.h>
@@ -20,16 +19,6 @@
 
 #include <asm/system.h>
 #include <asm/segment.h>
-
-#if defined(CONFIG_BLK_DEV_SR)
-extern int check_cdrom_media_change(int, int);
-#endif
-#if defined(CONFIG_CDU31A)
-extern int check_cdu31a_media_change(int, int);
-#endif
-#if defined(CONFIG_MCD)
-extern int check_mcd_media_change(int, int);
-#endif
 
 #ifdef LEAK_CHECK
 static int check_malloc = 0;
diff -u --recursive --new-file v1.1.27/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- v1.1.27/linux/include/linux/nfs_fs.h	Wed Jul 13 01:09:44 1994
+++ linux/include/linux/nfs_fs.h	Sun Jul 10 21:57:10 1994
@@ -22,7 +22,7 @@
 
 #define NFS_READDIR_CACHE_SIZE		64
 
-#define NFS_MAX_FILE_IO_BUFFER_SIZE	16834
+#define NFS_MAX_FILE_IO_BUFFER_SIZE	16384
 #define NFS_DEF_FILE_IO_BUFFER_SIZE	1024
 
 /*
diff -u --recursive --new-file v1.1.27/linux/net/inet/proc.c linux/net/inet/proc.c
--- v1.1.27/linux/net/inet/proc.c	Tue Jun 21 14:16:28 1994
+++ linux/net/inet/proc.c	Wed Jul 13 01:01:40 1994
@@ -20,6 +20,7 @@
  *	Pauline Middelink	:	Pidentd support
  *		Alan Cox	:	Make /proc safer.
  *	Erik Schoenfelder	:	/proc/net/snmp
+ *		Alan Cox	:	Handle dead sockets properly.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -55,90 +56,91 @@
 static int
 get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t offset, int length)
 {
-  struct sock **s_array;
-  struct sock *sp;
-  int i;
-  int timer_active;
-  unsigned long  dest, src;
-  unsigned short destp, srcp;
-  int len=0;
-  off_t pos=0;
-  off_t begin=0;
+	struct sock **s_array;
+	struct sock *sp;
+	int i;
+	int timer_active;
+	unsigned long  dest, src;
+	unsigned short destp, srcp;
+	int len=0;
+	off_t pos=0;
+	off_t begin=0;
   
-
-  s_array = pro->sock_array;
-  len+=sprintf(buffer, "sl  local_address rem_address   st tx_queue rx_queue tr tm->when uid\n");
+	s_array = pro->sock_array;
+	len+=sprintf(buffer, "sl  local_address rem_address   st tx_queue rx_queue tr tm->when uid\n");
 /*
  *	This was very pretty but didn't work when a socket is destroyed at the wrong moment
  *	(eg a syn recv socket getting a reset), or a memory timer destroy. Instead of playing
  *	with timers we just concede defeat and cli().
  */
-  for(i = 0; i < SOCK_ARRAY_SIZE; i++) {
-  	cli();
-	sp = s_array[i];
-	while(sp != NULL) {
-		dest  = sp->daddr;
-		src   = sp->saddr;
-		destp = sp->dummy_th.dest;
-		srcp  = sp->dummy_th.source;
-
-		/* Since we are Little Endian we need to swap the bytes :-( */
-		destp = ntohs(destp);
-		srcp  = ntohs(srcp);
-		timer_active = del_timer(&sp->timer);
-		if (!timer_active)
-			sp->timer.expires = 0;
-		len+=sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d\n",
-			i, src, srcp, dest, destp, sp->state, 
-			format==0?sp->write_seq-sp->rcv_ack_seq:sp->rmem_alloc, 
-			format==0?sp->acked_seq-sp->copied_seq:sp->wmem_alloc,
-			timer_active, sp->timer.expires, (unsigned) sp->retransmits,
-			SOCK_INODE(sp->socket)->i_uid);
-		if (timer_active)
-			add_timer(&sp->timer);
-		/*
-		 * All sockets with (port mod SOCK_ARRAY_SIZE) = i
-		 * are kept in sock_array[i], so we must follow the
-		 * 'next' link to get them all.
-		 */
-		sp = sp->next;
-		pos=begin+len;
-		if(pos<offset)
+	for(i = 0; i < SOCK_ARRAY_SIZE; i++) 
+	{
+	  	cli();
+		sp = s_array[i];
+		while(sp != NULL) 
 		{
-			len=0;
-			begin=pos;
+			dest  = sp->daddr;
+			src   = sp->saddr;
+			destp = sp->dummy_th.dest;
+			srcp  = sp->dummy_th.source;
+
+			/* Since we are Little Endian we need to swap the bytes :-( */
+			destp = ntohs(destp);
+			srcp  = ntohs(srcp);
+			timer_active = del_timer(&sp->timer);
+			if (!timer_active)
+				sp->timer.expires = 0;
+			len+=sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d\n",
+				i, src, srcp, dest, destp, sp->state, 
+				format==0?sp->write_seq-sp->rcv_ack_seq:sp->rmem_alloc, 
+				format==0?sp->acked_seq-sp->copied_seq:sp->wmem_alloc,
+				timer_active, sp->timer.expires, (unsigned) sp->retransmits,
+				sp->dead?0:SOCK_INODE(sp->socket)->i_uid);
+			if (timer_active)
+				add_timer(&sp->timer);
+			/*
+			 * All sockets with (port mod SOCK_ARRAY_SIZE) = i
+			 * are kept in sock_array[i], so we must follow the
+			 * 'next' link to get them all.
+			 */
+			sp = sp->next;
+			pos=begin+len;
+			if(pos<offset)
+			{
+				len=0;
+				begin=pos;
+			}
+			if(pos>offset+length)
+				break;
 		}
+		sti();	/* We only turn interrupts back on for a moment, but because the interrupt queues anything built up
+			   before this will clear before we jump back and cli, so its not as bad as it looks */
 		if(pos>offset+length)
 			break;
 	}
-	sti();	/* We only turn interrupts back on for a moment, but because the interrupt queues anything built up
-		   before this will clear before we jump back and cli, so its not as bad as it looks */
-	if(pos>offset+length)
-		break;
-  }
-  *start=buffer+(offset-begin);
-  len-=(offset-begin);
-  if(len>length)
-  	len=length;
-  return len;
+	*start=buffer+(offset-begin);
+	len-=(offset-begin);
+	if(len>length)
+	  	len=length;
+	return len;
 } 
 
 
 int tcp_get_info(char *buffer, char **start, off_t offset, int length)
 {
-  return get__netinfo(&tcp_prot, buffer,0, start, offset, length);
+	return get__netinfo(&tcp_prot, buffer,0, start, offset, length);
 }
 
 
 int udp_get_info(char *buffer, char **start, off_t offset, int length)
 {
-  return get__netinfo(&udp_prot, buffer,1, start, offset, length);
+	return get__netinfo(&udp_prot, buffer,1, start, offset, length);
 }
 
 
 int raw_get_info(char *buffer, char **start, off_t offset, int length)
 {
-  return get__netinfo(&raw_prot, buffer,1, start, offset, length);
+	return get__netinfo(&raw_prot, buffer,1, start, offset, length);
 }
 
 
@@ -148,74 +150,73 @@
  
 int snmp_get_info(char *buffer, char **start, off_t offset, int length)
 {
-  extern struct tcp_mib tcp_statistics;
-  extern struct udp_mib udp_statistics;
-  int len;
+	extern struct tcp_mib tcp_statistics;
+	extern struct udp_mib udp_statistics;
+	int len;
 /*
   extern unsigned long tcp_rx_miss, tcp_rx_hit1,tcp_rx_hit2;
 */
 
-  len = sprintf (buffer,
-	"Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates\n"
-	"Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
-	    ip_statistics.IpForwarding, ip_statistics.IpDefaultTTL, 
-	    ip_statistics.IpInReceives, ip_statistics.IpInHdrErrors, 
-	    ip_statistics.IpInAddrErrors, ip_statistics.IpForwDatagrams, 
-	    ip_statistics.IpInUnknownProtos, ip_statistics.IpInDiscards, 
-	    ip_statistics.IpInDelivers, ip_statistics.IpOutRequests, 
-	    ip_statistics.IpOutDiscards, ip_statistics.IpOutNoRoutes, 
-	    ip_statistics.IpReasmTimeout, ip_statistics.IpReasmReqds, 
-	    ip_statistics.IpReasmOKs, ip_statistics.IpReasmFails, 
-	    ip_statistics.IpFragOKs, ip_statistics.IpFragFails, 
-	    ip_statistics.IpFragCreates);
-	
-  len += sprintf (buffer + len,
-	"Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps\n"
-	"Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
-	    icmp_statistics.IcmpInMsgs, icmp_statistics.IcmpInErrors,
-	    icmp_statistics.IcmpInDestUnreachs, icmp_statistics.IcmpInTimeExcds,
-	    icmp_statistics.IcmpInParmProbs, icmp_statistics.IcmpInSrcQuenchs,
-	    icmp_statistics.IcmpInRedirects, icmp_statistics.IcmpInEchos,
-	    icmp_statistics.IcmpInEchoReps, icmp_statistics.IcmpInTimestamps,
-	    icmp_statistics.IcmpInTimestampReps, icmp_statistics.IcmpInAddrMasks,
-	    icmp_statistics.IcmpInAddrMaskReps, icmp_statistics.IcmpOutMsgs,
-	    icmp_statistics.IcmpOutErrors, icmp_statistics.IcmpOutDestUnreachs,
-	    icmp_statistics.IcmpOutTimeExcds, icmp_statistics.IcmpOutParmProbs,
-	    icmp_statistics.IcmpOutSrcQuenchs, icmp_statistics.IcmpOutRedirects,
-	    icmp_statistics.IcmpOutEchos, icmp_statistics.IcmpOutEchoReps,
-	    icmp_statistics.IcmpOutTimestamps, icmp_statistics.IcmpOutTimestampReps,
-	    icmp_statistics.IcmpOutAddrMasks, icmp_statistics.IcmpOutAddrMaskReps);
-
-   len += sprintf (buffer + len,
-	"Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs\n"
-	"Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
-	    tcp_statistics.TcpRtoAlgorithm, tcp_statistics.TcpRtoMin,
-	    tcp_statistics.TcpRtoMax, tcp_statistics.TcpMaxConn,
-	    tcp_statistics.TcpActiveOpens, tcp_statistics.TcpPassiveOpens,
-	    tcp_statistics.TcpAttemptFails, tcp_statistics.TcpEstabResets,
-	    tcp_statistics.TcpCurrEstab, tcp_statistics.TcpInSegs,
-	    tcp_statistics.TcpOutSegs, tcp_statistics.TcpRetransSegs);
+	len = sprintf (buffer,
+		"Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates\n"
+		"Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+		    ip_statistics.IpForwarding, ip_statistics.IpDefaultTTL, 
+		    ip_statistics.IpInReceives, ip_statistics.IpInHdrErrors, 
+		    ip_statistics.IpInAddrErrors, ip_statistics.IpForwDatagrams, 
+		    ip_statistics.IpInUnknownProtos, ip_statistics.IpInDiscards, 
+		    ip_statistics.IpInDelivers, ip_statistics.IpOutRequests, 
+		    ip_statistics.IpOutDiscards, ip_statistics.IpOutNoRoutes, 
+		    ip_statistics.IpReasmTimeout, ip_statistics.IpReasmReqds, 
+		    ip_statistics.IpReasmOKs, ip_statistics.IpReasmFails, 
+		    ip_statistics.IpFragOKs, ip_statistics.IpFragFails, 
+		    ip_statistics.IpFragCreates);
+		    		
+	len += sprintf (buffer + len,
+		"Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps\n"
+		"Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+		    icmp_statistics.IcmpInMsgs, icmp_statistics.IcmpInErrors,
+		    icmp_statistics.IcmpInDestUnreachs, icmp_statistics.IcmpInTimeExcds,
+		    icmp_statistics.IcmpInParmProbs, icmp_statistics.IcmpInSrcQuenchs,
+		    icmp_statistics.IcmpInRedirects, icmp_statistics.IcmpInEchos,
+		    icmp_statistics.IcmpInEchoReps, icmp_statistics.IcmpInTimestamps,
+		    icmp_statistics.IcmpInTimestampReps, icmp_statistics.IcmpInAddrMasks,
+		    icmp_statistics.IcmpInAddrMaskReps, icmp_statistics.IcmpOutMsgs,
+		    icmp_statistics.IcmpOutErrors, icmp_statistics.IcmpOutDestUnreachs,
+		    icmp_statistics.IcmpOutTimeExcds, icmp_statistics.IcmpOutParmProbs,
+		    icmp_statistics.IcmpOutSrcQuenchs, icmp_statistics.IcmpOutRedirects,
+		    icmp_statistics.IcmpOutEchos, icmp_statistics.IcmpOutEchoReps,
+		    icmp_statistics.IcmpOutTimestamps, icmp_statistics.IcmpOutTimestampReps,
+		    icmp_statistics.IcmpOutAddrMasks, icmp_statistics.IcmpOutAddrMaskReps);
 	
-	  len += sprintf (buffer + len,
-	"Udp: InDatagrams NoPorts InErrors OutDatagrams\nUdp: %lu %lu %lu %lu\n",
-	    udp_statistics.UdpInDatagrams, udp_statistics.UdpNoPorts,
-	    udp_statistics.UdpInErrors, udp_statistics.UdpOutDatagrams);
-	    
-/*
+	len += sprintf (buffer + len,
+		"Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs\n"
+		"Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+		    tcp_statistics.TcpRtoAlgorithm, tcp_statistics.TcpRtoMin,
+		    tcp_statistics.TcpRtoMax, tcp_statistics.TcpMaxConn,
+		    tcp_statistics.TcpActiveOpens, tcp_statistics.TcpPassiveOpens,
+		    tcp_statistics.TcpAttemptFails, tcp_statistics.TcpEstabResets,
+		    tcp_statistics.TcpCurrEstab, tcp_statistics.TcpInSegs,
+		    tcp_statistics.TcpOutSegs, tcp_statistics.TcpRetransSegs);
+		
+	len += sprintf (buffer + len,
+		"Udp: InDatagrams NoPorts InErrors OutDatagrams\nUdp: %lu %lu %lu %lu\n",
+		    udp_statistics.UdpInDatagrams, udp_statistics.UdpNoPorts,
+		    udp_statistics.UdpInErrors, udp_statistics.UdpOutDatagrams);	    
+/*	
 	  len += sprintf( buffer + len,
 	  	"TCP fast path RX:  H2: %ul H1: %ul L: %ul\n",
 	  		tcp_rx_hit2,tcp_rx_hit1,tcp_rx_miss);
 */
 	
-  if (offset >= len)
-    {
-	      *start = buffer;
-	      return 0;
-    }
-  *start = buffer + offset;
-  len -= offset;
-  if (len > length)
-    len = length;
-  return len;
+	if (offset >= len)
+	{
+		*start = buffer;
+		return 0;
+	}
+	*start = buffer + offset;
+	len -= offset;
+	if (len > length)
+		len = length;
+	return len;
 }
 
diff -u --recursive --new-file v1.1.27/linux/net/inet/tcp.c linux/net/inet/tcp.c
--- v1.1.27/linux/net/inet/tcp.c	Tue Jun 28 22:30:28 1994
+++ linux/net/inet/tcp.c	Wed Jul 13 01:02:26 1994
@@ -155,7 +155,7 @@
 #include <asm/segment.h>
 #include <linux/mm.h>
 
-#undef TCP_FASTPATH
+#define TCP_FASTPATH
 
 #define SEQ_TICK 3
 unsigned long seq_offset;
@@ -3844,6 +3844,7 @@
 				}
 				if(!sk->dead)
 					sk->data_ready(sk,0);
+				release_sock(sk);
 				return 0;
 			}
 		}
