patch-2.3.10 linux/drivers/scsi/aic7xxx.c

Next file: linux/drivers/scsi/aic7xxx_reg.h
Previous file: linux/drivers/scsi/aic7xxx/aic7xxx.reg
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
@@ -270,7 +270,7 @@
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.1.17"
+#define AIC7XXX_C_VERSION  "5.1.18"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
@@ -7186,7 +7186,7 @@
 static int
 acquire_seeprom(struct aic7xxx_host *p)
 {
-  int wait;
+  int count=0;
 
   /*
    * Request access of the memory port.  When access is
@@ -7196,11 +7196,10 @@
    * 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 */
+  while( ((aic_inb(p, SEECTL) & SEERDY) == 0) && count < 1000) {
+    mb();
+    udelay(1);
+    count++;
   }
   if ((aic_inb(p, SEECTL) & SEERDY) == 0)
   {
@@ -7412,73 +7411,78 @@
 
 /*+F*************************************************************************
  * Function:
- *   write_brdctl
+ *   read_brdctl
  *
  * Description:
- *   Writes a value to the BRDCTL register.
+ *   Reads the BRDCTL register.
  *-F*************************************************************************/
-static void
-write_brdctl(struct aic7xxx_host *p, unsigned char value)
+static unsigned char
+read_brdctl(struct aic7xxx_host *p)
 {
   unsigned char brdctl;
 
   if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
   {
-    brdctl = BRDSTB;
+    brdctl = BRDRW;
     if (p->flags & AHC_CHNLB)
       brdctl |= BRDCS;
   }
   else if (p->features & AHC_ULTRA2)
-    brdctl = 0;
-  else
-    brdctl = BRDSTB | BRDCS;
-  aic_outb(p, brdctl, BRDCTL);
-  udelay(1);
-  brdctl |= value;
-  aic_outb(p, brdctl, BRDCTL);
-  udelay(1);
-  if (p->features & AHC_ULTRA2)
-    brdctl |= BRDSTB_ULTRA2;
-  else
-    brdctl &= ~BRDSTB;
-  aic_outb(p, brdctl, BRDCTL);
-  udelay(1);
-  if (p->features & AHC_ULTRA2)
-    brdctl = 0;
+    brdctl = BRDRW_ULTRA2;
   else
-    brdctl &= ~BRDCS;
+    brdctl = BRDRW | BRDCS;
   aic_outb(p, brdctl, BRDCTL);
-  udelay(1);
+  udelay(10);
+  return (aic_inb(p, BRDCTL));
 }
 
 /*+F*************************************************************************
  * Function:
- *   read_brdctl
+ *   write_brdctl
  *
  * Description:
- *   Reads the BRDCTL register.
+ *   Writes a value to the BRDCTL register.
  *-F*************************************************************************/
-static unsigned char
-read_brdctl(struct aic7xxx_host *p)
+static void
+write_brdctl(struct aic7xxx_host *p, unsigned char value)
 {
-  unsigned char brdctl, value;
+  unsigned char brdctl;
 
   if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
   {
-    brdctl = BRDRW;
+    brdctl = BRDSTB;
     if (p->flags & AHC_CHNLB)
       brdctl |= BRDCS;
+    aic_outb(p, brdctl, BRDCTL);
+    udelay(4);
+    brdctl |= value;
   }
   else if (p->features & AHC_ULTRA2)
-    brdctl = BRDRW_ULTRA2;
+  {
+    brdctl = value;
+  }
   else
-    brdctl = BRDRW | BRDCS;
+  {
+    brdctl = BRDSTB | BRDCS;
+    aic_outb(p, brdctl, BRDCTL);
+    udelay(4);
+    brdctl |= value;
+  }
   aic_outb(p, brdctl, BRDCTL);
-  udelay(1);
-  value = aic_inb(p, BRDCTL);
-  aic_outb(p, 0, BRDCTL);
-  udelay(1);
-  return (value);
+  udelay(4);
+  if (p->features & AHC_ULTRA2)
+    brdctl |= BRDSTB_ULTRA2;
+  else
+    brdctl &= ~BRDSTB;
+  aic_outb(p, brdctl, BRDCTL);
+  udelay(4);
+  if (p->features & AHC_ULTRA2)
+    brdctl &= ~BRDSTB_ULTRA2;
+  else
+    brdctl &= ~BRDCS;
+  aic_outb(p, brdctl, BRDCTL);
+  udelay(4);
+  read_brdctl(p);
 }
 
 /*+F*************************************************************************
@@ -7495,11 +7499,10 @@
   unsigned char brdctl;
 
   aic_outb(p, BRDRW | BRDCS, BRDCTL);
-  udelay(1);
+  udelay(4);
   aic_outb(p, 0, BRDCTL);
-  udelay(1);
+  udelay(4);
   brdctl = aic_inb(p, BRDCTL);
-  udelay(1);
   *int_50 = !(brdctl & BRDDAT5);
   *ext_present = !(brdctl & BRDDAT6);
   *eeprom = (aic_inb(p, SPIOCAP) & EEPROM);
@@ -7608,6 +7611,7 @@
     else
       max_target = 8;
     aic_outb(p, SEEMS | SEECS, SEECTL);
+    udelay(4);
     sxfrctl1 &= ~STPWEN;
     if ( (p->adapter_control & CFAUTOTERM) ||
          (p->features & AHC_ULTRA2) )
@@ -7732,25 +7736,33 @@
                  p->host_no);
       }
 
-      if (enableLVD_low != 0)
+      if (enableLVD_high != 0)
       {
-        sxfrctl1 |= STPWEN;
-        p->flags |= AHC_TERM_ENB_LVD;
+        brddat |= BRDDAT4;
         if (aic7xxx_verbose & VERBOSE_PROBE2)
-          printk(KERN_INFO "(scsi%d) LVD Low byte termination Enabled\n",
+          printk(KERN_INFO "(scsi%d) LVD High byte termination Enabled\n",
                  p->host_no);
       }
           
-      if (enableLVD_high != 0)
+      if (enableLVD_low != 0)
       {
-        brddat |= BRDDAT4;
+        sxfrctl1 |= STPWEN;
+        p->flags |= AHC_TERM_ENB_LVD;
         if (aic7xxx_verbose & VERBOSE_PROBE2)
-          printk(KERN_INFO "(scsi%d) LVD High byte termination Enabled\n",
+          printk(KERN_INFO "(scsi%d) LVD Low byte termination Enabled\n",
                  p->host_no);
       }
     }
     else
     {
+      if (p->adapter_control & CFWSTERM)
+      {
+        brddat |= BRDDAT6;
+        if (aic7xxx_verbose & VERBOSE_PROBE2)
+          printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n",
+                 p->host_no);
+      }
+
       if (p->adapter_control & CFSTERM)
       {
         if (p->features & AHC_ULTRA2)
@@ -7761,18 +7773,10 @@
           printk(KERN_INFO "(scsi%d) SE Low byte termination Enabled\n",
                  p->host_no);
       }
-
-      if (p->adapter_control & CFWSTERM)
-      {
-        brddat |= BRDDAT6;
-        if (aic7xxx_verbose & VERBOSE_PROBE2)
-          printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n",
-                 p->host_no);
-      }
     }
+    aic_outb(p, sxfrctl1, SXFRCTL1);
     write_brdctl(p, brddat);
     release_seeprom(p);
-    aic_outb(p, sxfrctl1, SXFRCTL1);
   }
 }
 
@@ -8086,7 +8090,7 @@
     /* Select channel B */
     aic_outb(p, aic_inb(p, SBLKCTL) | SELBUSB, SBLKCTL);
 
-    term = ((p->flags & AHC_TERM_ENB_B) != 0) ? STPWEN : 0;
+    term = (aic_inb(p, SXFRCTL1) & STPWEN);
     aic_outb(p, p->scsi_id_b, SCSIID);
     scsi_conf = aic_inb(p, SCSICONF + 1);
     aic_outb(p, DFON | SPIOEN, SXFRCTL0);
@@ -8100,11 +8104,15 @@
     aic_outb(p, aic_inb(p, SBLKCTL) & ~SELBUSB, SBLKCTL);
   }
 
-  term = ((p->flags & AHC_TERM_ENB_SE_LOW) != 0) ? STPWEN : 0;
   if (p->features & AHC_ULTRA2)
+  {
     aic_outb(p, p->scsi_id, SCSIID_ULTRA2);
+  }
   else
+  {
     aic_outb(p, p->scsi_id, SCSIID);
+  }
+  term = (aic_inb(p, SXFRCTL1) & STPWEN);
   scsi_conf = aic_inb(p, SCSICONF);
   aic_outb(p, DFON | SPIOEN, SXFRCTL0);
   aic_outb(p, (scsi_conf & ENSPCHK) | STIMESEL | term | 
@@ -8794,27 +8802,33 @@
     }
     if (p->flags & AHC_NEWEEPROM_FMT)
     {
-      if ( (sc->device_flags[i] & CFNEWULTRAFORMAT) &&
-          !(p->features & AHC_ULTRA2) )
+      if ( !(p->features & AHC_ULTRA2) )
       {
         /*
          * I know of two different Ultra BIOSes that do this differently.
          * One on the Gigabyte 6BXU mb that wants flags[i] & CFXFER to
-         * be == to 0x03 and SYNCISULTRA to be true to mean 40MByte/s
+         * be == to 0x03 and SYNCHISULTRA to be true to mean 40MByte/s
          * while on the IBM Netfinity 5000 they want the same thing
          * to be something else, while flags[i] & CFXFER == 0x03 and
-         * SYNCISULTRA false should be 40MByte/s.  So, we set both to
+         * SYNCHISULTRA false should be 40MByte/s.  So, we set both to
          * 40MByte/s and the lower speeds be damned.  People will have
          * to select around the conversely mapped lower speeds in order
          * to select lower speeds on these boards.
          */
-        if ((sc->device_flags[i] & (CFXFER)) == 0x03)
+        if ( (sc->device_flags[i] & CFNEWULTRAFORMAT) &&
+            ((sc->device_flags[i] & CFXFER) == 0x03) )
         {
           sc->device_flags[i] &= ~CFXFER;
           sc->device_flags[i] |= CFSYNCHISULTRA;
         }
+        if (sc->device_flags[i] & CFSYNCHISULTRA)
+        {
+          p->ultraenb |= mask;
+        }
       }
-      if (sc->device_flags[i] & CFSYNCHISULTRA)
+      else if ( !(sc->device_flags[i] & CFNEWULTRAFORMAT) &&
+                 (p->features & AHC_ULTRA2) &&
+		 (sc->device_flags[i] & CFSYNCHISULTRA) )
       {
         p->ultraenb |= mask;
       }
@@ -9290,6 +9304,10 @@
        AHC_AIC7860_FE,                                       7,
        32, C46 },
       {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_3860, AHC_AIC7860,
+       AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+       AHC_AIC7860_FE,                                       7,
+       32, C46 },
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_38602, AHC_AIC7860,
        AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
        AHC_AIC7860_FE,                                       7,
        32, C46 },

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)