]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.28 1.1.28
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:33 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:33 +0000 (15:09 -0500)
44 files changed:
Makefile
drivers/block/cdu31a.c
drivers/char/lp.c
drivers/char/tty_io.c
drivers/scsi/ChangeLog
drivers/scsi/NCR5380.c
drivers/scsi/aha152x.c
drivers/scsi/aha152x.h
drivers/scsi/aha1542.c
drivers/scsi/aha1542.h
drivers/scsi/aha1740.c
drivers/scsi/aha1740.h
drivers/scsi/buslogic.c
drivers/scsi/buslogic.h
drivers/scsi/fdomain.c
drivers/scsi/fdomain.h
drivers/scsi/g_NCR5380.c
drivers/scsi/g_NCR5380.h
drivers/scsi/hosts.c
drivers/scsi/hosts.h
drivers/scsi/pas16.c
drivers/scsi/pas16.h
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_debug.h
drivers/scsi/scsi_ioctl.c
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/seagate.h
drivers/scsi/sg.c
drivers/scsi/sr.c
drivers/scsi/sr_ioctl.c
drivers/scsi/st.c
drivers/scsi/t128.c
drivers/scsi/t128.h
drivers/scsi/ultrastor.c
drivers/scsi/ultrastor.h
drivers/scsi/wd7000.c
drivers/scsi/wd7000.h
fs/isofs/inode.c
include/linux/nfs_fs.h
net/inet/proc.c
net/inet/tcp.c

index ef491711f06eaa008bb388c1add05be7b6fde9ff..ed9d87fe135fe421a985d345061292b876c1be5b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 27
+SUBLEVEL = 28
 
 all:   Version zImage
 
index eab81b0786a47488621c0ada24c5713c38105f00..55f248b3924987631870417d3b598aef641a3650 100644 (file)
@@ -254,39 +254,9 @@ static struct wait_queue *cdu31a_irq_wait = NULL;
 
 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)
index 8ad58884ab4becc8e5c9c8bd0a51ab2f30eab696..7d420a83a11ec6c8413b5c157400f18534e72255 100644 (file)
@@ -235,7 +235,7 @@ static int lp_write_polled(struct inode * inode, struct file * file,
                        } 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;
index 9787aebe3efd0648994be1e28675505df40abfe6..1fad5d82fb48ac1eec3f9dff1f6937a405ad3252 100644 (file)
@@ -853,6 +853,7 @@ repeat:
                if (driver->subtype == PTY_TYPE_MASTER)
                        (*o_tty_loc)->count++;
        }
+       (*tty_loc)->driver = *driver;
        *ret_tty = *tty_loc;
        retval = 0;
 end_init:
index 521570414a6f428270886a7e17ec2db327bd332c..67326123d1cf332c1c4c3f0ca67cf25b47d2aa99 100644 (file)
@@ -1,7 +1,61 @@
+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.
 
index d1dd048b91dd21620d912d7f2d316c2738d38ad7..a7e7ff04109194b0f835e11a8f8f79ba1da57155 100644 (file)
@@ -1184,7 +1184,7 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
        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 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
 #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 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
     /* 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 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) {
 
 #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 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) {
                         */ 
                        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 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) {
                    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;
index 8a8a7e4745c6a94aa513be75d6323a458ab2d4e7..48d2ba2f0c52681ccb7d5c9e11d81eb0c2e75a99 100644 (file)
@@ -503,7 +503,7 @@ static int aha152x_porttest(int port_base)
   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 @@ int aha152x_detect(int hostno)
     }
 
   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 );
index eda630864f6d66526a6f4ca45f1ca827fb44dd4e..eea476732ed45a505dcd7e6e07278ad4d1c061b1 100644 (file)
@@ -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 @@ int        aha152x_biosparam(Disk *, int, int*);
 #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,              \
index e78f76c6fa0556bde4d86d531301f74dede49889..c890aad0999e69582d951d19af455f425e275763 100644 (file)
@@ -780,7 +780,7 @@ static int aha1542_query(int base_io, int * transl)
 
 
 /* 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 @@ int aha1542_detect(int hostnum)
     
     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 @@ int aha1542_detect(int hostnum)
                    count++;
                    continue;
            unregister:
-                   scsi_unregister(shpnt, sizeof(struct aha1542_hostdata));
+                   scsi_unregister(shpnt);
                    continue;
                    
            };
index c818618262bfd55ccdab27886a8d8552ec5e0d55..69440afe1c44c2602d700b294a9a76affa56f3bc 100644 (file)
@@ -128,7 +128,7 @@ struct ccb {                        /* Command Control Block 5.3 */
                                /* 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 @@ int aha1542_biosparam(Disk *, int, int*);
        #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
index 0160dab39ba2b4b6eed5ee8296e7721d7acf6c2c..a60280bf204bd57bc3aad894beef38ae2b189459 100644 (file)
@@ -425,7 +425,7 @@ void aha1740_getconfig(void)
   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"));
index efc61b0a6d031ff59fe7f9e39067497bf81da494..cb96ee4c18aa36e9031e8fa0d6b96ffcc62173b1 100644 (file)
@@ -152,7 +152,7 @@ struct ecb {                        /* Enhanced Control Block 6.1 */
 #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 @@ int aha1740_biosparam(Disk *, int, int*);
 #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
 
index e739fd0e33e9655e80838487d870607a22ab7439..c65b82c1c614fdb513637ee1c5beaddc751c031b 100644 (file)
@@ -912,7 +912,7 @@ static int buslogic_query(unsigned int base, int *trans)
 }
 
 /* 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 @@ int buslogic_detect(int hostnum)
 
     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 @@ int buslogic_detect(int hostnum)
            count++;
            continue;
          unregister:
-           scsi_unregister(SHpnt, sizeof (struct hostdata));
+           scsi_unregister(SHpnt);
        }
     return count;
 }
index fb9bbe3eb65dcf8a55dd020a12593a0a9284180f..c745c19f7c90e79fc8663e45caa36dbf31eb3d3d 100644 (file)
@@ -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 @@ int buslogic_biosparam(Disk *, int, int *);
 
 #define BUSLOGIC_CMDLUN 1      /* ??? */
 
-#define BUSLOGIC { "BusLogic",                 \
+#define BUSLOGIC { NULL,                       \
+                  "BusLogic",                  \
                   buslogic_detect,             \
+                  NULL,                        \
                   buslogic_info,               \
                   0,   /* no command func */   \
                   buslogic_queuecommand,       \
index 9c0f5672a18bfa2c4b659c384a8885b9c8018f8a..edd1e987ba60b167c334b7931c90473030e013d2 100644 (file)
@@ -258,7 +258,6 @@ static void              *bios_base        = NULL;
 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 @@ static int fdomain_test_loopback( void )
    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 @@ int fdomain_16x0_detect( int hostnum )
       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 @@ int fdomain_16x0_detect( int hostnum )
 
    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 @@ int fdomain_16x0_detect( int hostnum )
    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);
index ee9ddcb79a1cc46521cedb9f9988b2439d0bfc0a..1a34172edc62a4ac0006fb8100b5c130dcde3699 100644 (file)
@@ -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_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
 
 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 @@ int        fdomain_16x0_biosparam(Disk *, int, int * );
                        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
index 91ebdda4f1d15e16313243e7e43a84aa5d8ad2ea..f923474eab8088561c2c2520868e7574f8919cfc 100644 (file)
@@ -111,18 +111,18 @@ static struct sigaction sa =  { generic_NCR5380_intr, 0,
     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 @@ int generic_NCR5380_detect(int hostno) {
        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 @@ int generic_NCR5380_detect(int hostno) {
        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);
index 9417ad63c30e28484f34c08ee15eb75676b5baf8..ce5b7951d88096a63403399951a9d6ab7116098d 100644 (file)
@@ -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 @@ int generic_NCR5380_reset(Scsi_Cmnd *);
 
 #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,            \
index a4600282f91effe27693525e0f25c7c31c44a563..7a16c50b431248de4180c90a97d28a4d30581907 100644 (file)
@@ -108,7 +108,9 @@ static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hos
  *     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 @@ Scsi_Host_Template scsi_hosts[] =
 #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 @@ Scsi_Host_Template scsi_hosts[] =
 
 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 @@ struct Scsi_Host * scsi_register(int i, int j){
 
        /* 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 @@ struct Scsi_Host * scsi_register(int i, int j){
        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 @@ scsi_init(unsigned long memory_start,unsigned long memory_end)
                 */ 
                
                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 @@ int MAX_SD=0;
 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 @@ int MAX_SR=0;
 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 @@ int MAX_ST=0;
 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){
 };
index 442df859f8da2218d9155c2ce47ea0a86035457c..a960ebcd1177d7f837ce7c839d15b75bcbcaf0e0 100644 (file)
 
 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 @@ typedef struct
                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 @@ typedef struct
 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 @@ struct Scsi_Host
                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
index b57e8cbba9124ed6f38019650a2122103f1798c7..8cfbf8c38e6fdc9a3987049e2b224685b4622ef5 100644 (file)
@@ -278,19 +278,19 @@ void pas16_setup(char *str, int *ints) {
 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 @@ int pas16_detect(int hostno) {
        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 @@ int pas16_detect(int hostno) {
        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 @@ int pas16_detect(int hostno) {
 
        ++current_override;
        ++count;
-       ++hostno;
     }
     return count;
 }
index 223316f551744964937d15ad1d24e2eab05849ba..ed4b34d744db915e4803fac5145aff4606406ad5 100644 (file)
 #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 @@ int pas16_reset(Scsi_Cmnd *);
 
 #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,                  \
index 621bdd9862515edb421219c63104c3fb9a429276..4462abd8990c707893d5adf746748c7a0e94c44d 100644 (file)
@@ -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 @@ Scsi_Device * scsi_devices = NULL;
 
 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 @@ void scsi_luns_setup(char *str, int *ints) {
  *     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 @@ static void scan_scsis (void)
  * 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 @@ static void scan_scsis (void)
  */
 
 #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 @@ something else to finish.  This routine assumes that interrupts are
 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 @@ guarantee that the host remain not busy.  Keep in mind the
 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 * allocate_device (struct request ** reqp, int index, int wait)
   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 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
        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 @@ static int check_sense (Scsi_Cmnd * SCpnt)
                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 @@ int scsi_free(void *obj, unsigned int len)
   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 @@ int scsi_free(void *obj, unsigned int len)
 
 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 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
        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 @@ static void
 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 @@ scsi_dump_status(void)
               (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 @@ scsi_dump_status(void)
       }
 }
 #endif
+
+
index b386f35270b55644406b42549269309ceda161f3..c7cfdccdd3822316629af423a571605b647f9be6 100644 (file)
@@ -258,7 +258,8 @@ extern const unsigned char scsi_command_size[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_pointer {
 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 @@ extern void scsi_do_cmd (Scsi_Cmnd *, const void *cmnd ,
                   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 @@ static void end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
                        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 @@ static void end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
 #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
index 4a9469537d635154ff149e69186dfa4b3c0dca0b..b564f81f0b29a9a73473659d736d2dc0a30d3e59 100644 (file)
@@ -100,7 +100,6 @@ static int npart = 0;
 #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 @@ static void scsi_debug_intr_handle(void)
 }
 
 
-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 scsi_debug_abort(Scsi_Cmnd * SCpnt)
     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];
index 93031b615608a433b54ac46ee8753a83b2b8e6ed..cdaca4006aa4f25eff149fd10aa2983e860ea87d 100644 (file)
@@ -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 @@ int scsi_debug_reset(Scsi_Cmnd *);
 
 #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,                               \
index 7a985e8fab1487c863d4a05e8570751d3239e551..4766b9aca54622b0fcbdf54fdabd80f452cacfb6 100644 (file)
@@ -91,7 +91,7 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
        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 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
 
        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 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
 
 #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 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
        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 @@ int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
 {
         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:
index 7cc3b0159f10b83b54807c054e066c1300e63c89..c2d71b9b0c2740ea3e6c027a3335d0332e33e447 100644 (file)
@@ -42,7 +42,7 @@ static const char RCSid[] = "$Header:";
 #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 @@ static void do_sd_request (void)
 
     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 @@ static void do_sd_request (void)
       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 @@ repeat:
        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 @@ static int sd_init_onedisk(int i)
      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 @@ static int sd_init_onedisk(int i)
        };
 
        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 @@ static int sd_init_onedisk(int i)
 
   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 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
        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){
index 6ccf90f611ccee611e70c83f71489152558eed9e..4a23d334b377234435b497dececa6e5bb8d2f589 100644 (file)
@@ -272,8 +272,9 @@ static inline void borken_wait(void) {
 
 #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 @@ static struct sigaction seagate_sigaction = {
 #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 @@ static struct sigaction seagate_sigaction = {
  *     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 @@ static int internal_command(unsigned char target, unsigned char lun, const void
        st0x_aborted = 0;
 
 #ifdef SLOW_HANDSHAKE
-       borken = (int) scsi_devices[SCint->index].borken;
+       borken = (int) SCint->device->borken;
 #endif
 
 #if (DEBUG & PRINT_COMMAND)
index 66537f245ebe2148629333c52ca9cb1ef16f4581..5abfd663679bf98d47ab7be0c2c5d60bace2a74d 100644 (file)
@@ -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_reset(Scsi_Cmnd *);
 
 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, \
index 73eeb0249b50e4ad4e3c811180e60a0b1a24dded..def2b32caf48bdd79cd37e24530dc8022a344521 100644 (file)
@@ -252,7 +252,7 @@ static int sg_write(struct inode *inode,struct file *filp,char *buf,int count)
 #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 @@ unsigned long sg_init(unsigned long mem_start, unsigned long mem_end)
   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)
index 6e40a8dcd7e4eafaa90f789dd48b9371e59113c5..72166dc45e551b1f3859e09066ce20fdc89203aa 100644 (file)
@@ -307,7 +307,7 @@ static void do_sr_request (void)
 
     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 @@ static void do_sr_request (void)
       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 @@ are any multiple of 512 bytes long.  */
                     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 @@ static void get_sectorsize(int i){
   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 @@ static void get_sectorsize(int i){
   
   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;
index 5b3c8df5a8a0651c1d5163445b2c6b153ed6d12b..3ebd6ca5a7dfeb610a206334c2690a4fb0cead5b 100644 (file)
@@ -43,7 +43,7 @@ static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned
        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 @@ static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned
 
        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;
 }
index 21c3c530cb87474f71eb836c2ffc2e33b109f83c..6d50fd7d1034faec25e70e7d8c996613037c47b7 100644 (file)
@@ -230,7 +230,7 @@ back_over_eof(int dev)
   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 @@ flush_write_buffer(int dev)
 
   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 @@ scsi_tape_open(struct inode * inode, struct file * filp)
     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 @@ scsi_tape_close(struct inode * inode, struct file * filp)
 #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 @@ st_write(struct inode * inode, struct file * filp, char * buf, int count)
     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 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count)
 
     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 @@ st_int_ioctl(struct inode * inode,struct file * file,
        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 @@ st_ioctl(struct inode * inode,struct file * file,
      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 @@ void st_attach(Scsi_Device * SDp){
   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 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
         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 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
     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 */
index 0f50cf3cc075feb8c9c6496522aa3b942a20508c..6d8c1f4ddc1a9a99d266111ca2fa292a35ded1fc 100644 (file)
@@ -181,19 +181,19 @@ void t128_setup(char *str, int *ints) {
 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 @@ int t128_detect(int hostno) {
        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 @@ int t128_detect(int hostno) {
                        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 @@ int t128_detect(int hostno) {
        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 @@ int t128_detect(int hostno) {
 
        ++current_override;
        ++count;
-       ++hostno;
     }
     return count;
 }
index 54020dab44036933210a29d5d93fb6bc2c488119..c37a90a44b44cecd80a8a52d8c47ea93a91e1d78 100644 (file)
@@ -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 @@ int t128_reset(Scsi_Cmnd *);
 
 #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,                  \
index 79924c06dc9d38c7cdd34118e78ea427e4aadf7d..a3addd9e99c60e6eeab0be6c7d71e39977f6e3f0 100644 (file)
@@ -241,9 +241,6 @@ static struct ultrastor_config
   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 @@ static void log_ultrastor_abort(register struct ultrastor_config *config,
 }
 #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 @@ static int ultrastor_14f_detect(int hostnum)
           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 @@ static int ultrastor_14f_detect(int hostnum)
        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 @@ static int ultrastor_24f_detect(int hostnum)
             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 @@ static int ultrastor_24f_detect(int hostnum)
       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 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        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;
index 583eabb8c1e69a599ccec9eb876e87d3342f8a94..6df818fb19e4395e0c27210a92a8f3b748f3a281 100644 (file)
@@ -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 @@ int ultrastor_biosparam(Disk *, int, int *);
 #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
index 6cb49b91603c6a5575c0a51047fef7ce8709c42c..7c98636d52e95194273e07f4b6c859bc50eb586f 100644 (file)
@@ -156,7 +156,6 @@ typedef volatile struct mailbox{
  *
  */
 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 @@ void wd7000_revision(Adapter *host)
 }
 
 
-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 @@ int wd7000_detect(int hostnum)
                 *  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;
                }
 
index f120a94628bfcba3b4adba378653b1cf3fca517f..8c727d5685561046c0459c0f3eb49c6f60f9f22d 100644 (file)
@@ -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 @@ int wd7000_biosparam(Disk *, int, int*);
 #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,            \
index 9e836d19bef82b77fcd6072f95826b9bd4811fab..89f11d5ed3f4cbaae6836a47ae9c690a23fae3f3 100644 (file)
@@ -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>
 #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;
 static int check_bread = 0;
index 902d5f269498f2d713c3be8631d544b5d9904e34..358456007326b1b9d1f58504221e7328de4841dd 100644 (file)
@@ -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
 
 /*
index 98819d306f6e66a779ffb031226af19eaf7a80a9..1565bdf8b28bb851cfcb8666eee3e25ecc4ccefb 100644 (file)
@@ -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
 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 raw_get_info(char *buffer, char **start, off_t offset, int length)
  
 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,
+               "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,
-       "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 + 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;
 }
 
index d680abcada429ee4c1250eb6b23eb33027ae22e6..313f3889fc3f61ac379c9ef60c9e952596ce7fd1 100644 (file)
 #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 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
                                }
                                if(!sk->dead)
                                        sk->data_ready(sk,0);
+                               release_sock(sk);
                                return 0;
                        }
                }