Index: oldkernel/linux/drivers/scsi/aic7xxx.c
diff -u linux/drivers/scsi/aic7xxx.c:1.4 linux/drivers/scsi/aic7xxx.c:1.5
--- linux/drivers/scsi/aic7xxx.c:1.4	Thu Jun  1 15:16:16 2000
+++ linux/drivers/scsi/aic7xxx.c	Thu Jun  1 15:16:51 2000
@@ -270,7 +270,7 @@
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.1.24"
+#define AIC7XXX_C_VERSION  "5.1.25"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
@@ -1478,6 +1478,7 @@
   {
     x = inb(p->base + port);
   }
+  mb();
   return(x);
 #else
   return(inb(p->base + port));
@@ -7388,6 +7389,21 @@
 #undef CLOCK_PULSE
 }
 
+#define CLOCK_PULSE(p)                                               \
+  do {                                                               \
+    int limit = 0;                                                   \
+    do {                                                             \
+      mb();                                                          \
+      pause_sequencer(p);  /* This is just to generate some PCI */   \
+                           /* traffic so the PCI read is flushed */  \
+                           /* it shouldn't be needed, but some */    \
+                           /* chipsets do indeed appear to need */   \
+                           /* something to force PCI reads to get */ \
+                           /* flushed */                             \
+      udelay(1);           /* Do nothing */                          \
+    } while (((aic_inb(p, SEECTL) & SEERDY) == 0) && (++limit < 1000)); \
+  } while(0)
+
 /*+F*************************************************************************
  * Function:
  *   acquire_seeprom
@@ -7398,7 +7414,6 @@
 static int
 acquire_seeprom(struct aic7xxx_host *p)
 {
-  int wait;
 
   /*
    * Request access of the memory port.  When access is
@@ -7408,12 +7423,7 @@
    * should be no contention.
    */
   aic_outb(p, SEEMS, SEECTL);
-  wait = 1000;  /* 1000 msec = 1 second */
-  while ((wait > 0) && ((aic_inb(p, SEECTL) & SEERDY) == 0))
-  {
-    wait--;
-    mdelay(1);  /* 1 msec */
-  }
+  CLOCK_PULSE(p);
   if ((aic_inb(p, SEECTL) & SEERDY) == 0)
   {
     aic_outb(p, 0, SEECTL);
@@ -7432,7 +7442,12 @@
 static void
 release_seeprom(struct aic7xxx_host *p)
 {
+  /*
+   * Make sure the SEEPROM is ready before we release it.
+   */
+  CLOCK_PULSE(p);
   aic_outb(p, 0, SEECTL);
+  CLOCK_PULSE(p);
 }
 
 /*+F*************************************************************************
@@ -7498,18 +7513,6 @@
   };
   struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
 
-#define CLOCK_PULSE(p)                                               \
-  {                                                                  \
-    int limit = 0;                                                   \
-    while (((aic_inb(p, SEECTL) & SEERDY) == 0) && (++limit < 1000)) \
-    {                                                                \
-      mb();                                                          \
-      pause_sequencer(p);  /* This is just to generate some PCI */   \
-                           /* so the PCI read is flushed */          \
-      udelay(10);  /* Do nothing */                                  \
-    }                                                                \
-  }
-
   /*
    * Request access of the memory port.
    */
@@ -7625,7 +7628,6 @@
   }
 
   return (1);
-#undef CLOCK_PULSE
 }
 
 /*+F*************************************************************************
@@ -7640,12 +7642,18 @@
 {
   unsigned char brdctl, value;
 
+  /*
+   * Make sure the SEEPROM is ready before we access it
+   */
+  CLOCK_PULSE(p);
   if (p->features & AHC_ULTRA2)
   {
     brdctl = BRDRW_ULTRA2;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(4);
-    return(aic_inb(p, BRDCTL));
+    CLOCK_PULSE(p);
+    value = aic_inb(p, BRDCTL);
+    CLOCK_PULSE(p);
+    return(value);
   }
   brdctl = BRDRW;
   if ( !((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) ||
@@ -7654,10 +7662,11 @@
     brdctl |= BRDCS;
   }
   aic_outb(p, brdctl, BRDCTL);
-  udelay(1);
+  CLOCK_PULSE(p);
   value = aic_inb(p, BRDCTL);
+  CLOCK_PULSE(p);
   aic_outb(p, 0, BRDCTL);
-  udelay(1);
+  CLOCK_PULSE(p);
   return (value);
 }
 
@@ -7673,18 +7682,23 @@
 {
   unsigned char brdctl;
 
+  /*
+   * Make sure the SEEPROM is ready before we access it
+   */
+  CLOCK_PULSE(p);
   if (p->features & AHC_ULTRA2)
   {
     brdctl = value;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(4);
+    CLOCK_PULSE(p);
     brdctl |= BRDSTB_ULTRA2;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(4);
+    CLOCK_PULSE(p);
     brdctl &= ~BRDSTB_ULTRA2;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(4);
+    CLOCK_PULSE(p);
     read_brdctl(p);
+    CLOCK_PULSE(p);
   }
   else
   {
@@ -7696,19 +7710,21 @@
     }
     brdctl = BRDSTB | BRDCS;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(1);
+    CLOCK_PULSE(p);
     brdctl |= value;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(1);
+    CLOCK_PULSE(p);
     brdctl &= ~BRDSTB;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(1);
+    CLOCK_PULSE(p);
     brdctl &= ~BRDCS;
     aic_outb(p, brdctl, BRDCTL);
-    udelay(1);
+    CLOCK_PULSE(p);
   }
 }
 
+#undef CLOCK_PULSE
+
 /*+F*************************************************************************
  * Function:
  *   aic785x_cable_detect
@@ -8241,15 +8257,15 @@
 #endif
       if ( (aic7xxx_stpwlev >> p->instance) & 0x01 )
       {
-        devconfig |= 0x02;
+        devconfig |= STPWLEVEL;
         if (aic7xxx_verbose & VERBOSE_PROBE2)
-          printk("(scsi%d) Force setting STPWLEV bit\n", p->host_no);
+          printk("(scsi%d) Force setting STPWLEVEL bit\n", p->host_no);
       }
       else
       {
-        devconfig &= ~0x02;
+        devconfig &= ~STPWLEVEL;
         if (aic7xxx_verbose & VERBOSE_PROBE2)
-          printk("(scsi%d) Force clearing STPWLEV bit\n", p->host_no);
+          printk("(scsi%d) Force clearing STPWLEVEL bit\n", p->host_no);
       }
 #if LINUX_KERNEL_VERSION > KERNEL_VERSION(2,1,92)
       pci_write_config_byte(p->pdev, DEVCONFIG, devconfig);
@@ -8665,7 +8681,7 @@
   wait = 1000;  /* 1 second (1000 * 1 msec) */
   while (--wait && !(aic_inb(p, HCNTRL) & CHIPRSTACK))
   {
-    mdelay(1);  /* 1 msec */
+    udelay(1);  /* 1 msec */
   }
 
   pause_sequencer(p);
@@ -9742,7 +9758,7 @@
           /*
            * Get current termination setting
            */
-          sxfrctl1 = aic_inb(temp_p, SXFRCTL1) & STPWEN;
+          sxfrctl1 = aic_inb(temp_p, SXFRCTL1);
 
           if (aic7xxx_chip_reset(temp_p) == -1)
           {
@@ -9751,6 +9767,22 @@
             temp_p = NULL;
             continue;
           }
+          /*
+           * Very quickly put the term setting back into the register since
+           * the chip reset may cause odd things to happen.  This is to keep
+           * LVD busses with lots of drives from draining the power out of
+           * the diffsense line before we get around to running the
+           * configure_termination() function.  Also restore the STPWLEVEL
+           * bit of DEVCONFIG
+           */
+          aic_outb(temp_p, sxfrctl1, SXFRCTL1);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+          pcibios_write_config_dword(temp_p->pci_bus, temp_p->pci_device_fn,
+            DEVCONFIG, devconfig);
+#else
+          pci_write_config_dword(temp_p->pdev, DEVCONFIG, devconfig);
+#endif
+          sxfrctl1 &= STPWEN;
 
           /*
            * We need to set the CHNL? assignments before loading the SEEPROM
