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

Next file: linux/drivers/scsi/aic7xxx_proc.c
Previous file: linux/drivers/scsi/aha152x.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.48/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
@@ -41,7 +41,7 @@
  *
  *    -- Daniel M. Eischen, deischen@iworks.InterWorks.org, 04/03/95
  *
- *  $Id: aic7xxx.c,v 2.10 1995/11/10 10:49:14 deang Exp $
+ *  $Id: aic7xxx.c,v 2.15 1995/12/17 19:43:20 deang Exp $
  *-M*************************************************************************/
 
 #ifdef MODULE
@@ -73,7 +73,7 @@
     S_IFDIR | S_IRUGO | S_IXUGO, 2
 };
 
-#define AIC7XXX_C_VERSION  "$Revision: 2.10 $"
+#define AIC7XXX_C_VERSION  "$Revision: 2.15 $"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        ((a < b) ? a : b)
@@ -160,26 +160,44 @@
 /* #define AIC7XXX_PROC_STATS */
 
 /*
- * Define this to use polling rather than using kernel support for waking
- * up a waiting process.
+ * For debugging the abort/reset code.
  */
-#define AIC7XXX_POLL
+/* #define AIC7XXX_DEBUG_ABORT */
+
+/*
+ * For general debug messages
+ */
+#define AIC7XXX_DEBUG
 
 /*
  * Controller type and options
  */
 typedef enum {
   AIC_NONE,
-  AIC_274x,    /* EISA aic7770 */
-  AIC_284x,    /* VLB  aic7770 */
-  AIC_7870,    /* PCI  aic7870/aic7871 motherboard or 294x */
-  AIC_7850,    /* PCI  aic7850 */
-  AIC_7872,    /* PCI  aic7870 on 394x */
-  AIC_7880,    /* PCI  aic7880/aic7881 motherboard or 294x Ultra */
-  AIC_7882,    /* PCI  aic7870 on 394x Ultra */
+  AIC_7770,	/* EISA aic7770 on motherboard */
+  AIC_7771,	/* EISA aic7771 on 274x */
+  AIC_284x,	/* VLB  aic7770 on 284x */
+  AIC_7850,	/* PCI  aic7850 */
+  AIC_7870,	/* PCI  aic7870 on motherboard */
+  AIC_7871,	/* PCI  aic7871 on 294x */
+  AIC_7872,	/* PCI  aic7872 on 3940 */
+  AIC_7873,	/* PCI  aic7873 on 3985 */
+  AIC_7874,	/* PCI  aic7874 on 294x Differential */
+  AIC_7880,	/* PCI  aic7880 on motherboard */
+  AIC_7881,	/* PCI  aic7881 on 294x Ultra */
+  AIC_7882,	/* PCI  aic7882 on 3940 Ultra */
+  AIC_7883,	/* PCI  aic7883 on 3985 Ultra */
+  AIC_7884	/* PCI  aic7884 on 294x Ultra Differential */
 } aha_type;
 
 typedef enum {
+  AIC_777x,	/* AIC-7770 based */
+  AIC_785x,	/* AIC-7850 based */
+  AIC_787x,	/* AIC-7870 based */
+  AIC_788x	/* AIC-7880 based */
+} aha_chip_type;
+
+typedef enum {
   AIC_SINGLE,  /* Single Channel */
   AIC_TWIN,    /* Twin Channel */
   AIC_WIDE     /* Wide Channel */
@@ -197,6 +215,34 @@
   LIST_TAIL
 } insert_type;
 
+typedef enum {
+  ABORT_RESET_INACTIVE,
+  ABORT_RESET_PENDING,
+  ABORT_RESET_SUCCESS
+} aha_abort_reset_type;
+
+/*
+ * Define an array of board names that can be indexed by aha_type.
+ * Don't forget to change this when changing the types!
+ */
+static const char * board_names[] = {
+  "<AIC-7xxx Unknown>",		/* AIC_NONE */
+  "AIC-7770",			/* AIC_7770 */
+  "AHA-2740",			/* AIC_7771 */
+  "AHA-2840",			/* AIC_284x */
+  "AIC-7850",			/* AIC_7850 */
+  "AIC-7870",			/* AIC_7870 */
+  "AHA-2940",			/* AIC_7871 */
+  "AHA-3940",			/* AIC_7872 */
+  "AHA-3985",			/* AIC_7873 */
+  "AHA-2940 Differential",	/* AIC_7874 */
+  "AIC-7880 Ultra",		/* AIC_7880 */
+  "AHA-2940 Ultra",		/* AIC_7881 */
+  "AHA-3940 Ultra",		/* AIC_7882 */
+  "AHA-3985 Ultra",		/* AIC_7883 */
+  "AHA-2940 Ultra Differential"	/* AIC_7884 */
+};
+
 /*
  * There should be a specific return value for this in scsi.h, but
  * it seems that most drivers ignore it.
@@ -753,7 +799,7 @@
 #define CFXFER		0x0007		/* synchronous transfer rate */
 #define CFSYNCH		0x0008		/* enable synchronous transfer */
 #define CFDISC		0x0010		/* enable disconnection */
-#define CFWIDEB		0x0020		/* wide bus device */
+#define CFWIDEB		0x0020		/* wide bus device (wide card) */
 /* UNUSED		0x00C0 */
 #define CFSTART		0x0100		/* send start unit SCSI command */
 #define CFINCBIOS	0x0200		/* include in BIOS scan */
@@ -769,7 +815,8 @@
 #define CFBIOSEN	0x0004		/* BIOS enabled */
 /* UNUSED		0x0008 */
 #define CFSM2DRV	0x0010		/* support more than two drives */
-/* UNUSED		0x0060 */
+#define CF284XEXTEND	0x0020		/* extended translation (284x cards) */
+/* UNUSED		0x0040 */
 #define CFEXTEND	0x0080		/* extended translation enabled */
 /* UNUSED		0xFF00 */
   unsigned short bios_control;		/* word 16 */
@@ -779,10 +826,12 @@
  */
 /* UNUSED               0x0001 */
 #define CFULTRAEN       0x0002          /* Ultra SCSI speed enable (Ultra cards) */
+#define CF284XSELTO     0x0003          /* Selection timeout (284x cards) */
+#define CF284XFIFO      0x000C          /* FIFO Threshold (284x cards) */
 #define CFSTERM         0x0004          /* SCSI low byte termination (non-wide cards) */
 #define CFWSTERM        0x0008          /* SCSI high byte termination (wide card) */
 #define CFSPARITY	0x0010		/* SCSI parity */
-/* UNUSED		0x0020 */
+#define CF284XSTERM	0x0020		/* SCSI low byte termination (284x cards) */
 #define CFRESETB	0x0040		/* reset SCSI bus at IC initialization */
 /* UNUSED		0xFF80 */
   unsigned short adapter_control;	/* word 17 */
@@ -807,9 +856,6 @@
 
 };
 
-
-#define AIC7XXX_DEBUG
-
 /*
  * Pause the sequencer and wait for it to actually stop - this
  * is important since the sequencer can disable pausing for critical
@@ -968,15 +1014,6 @@
 	struct scatterlist  sg;
 	struct scatterlist  sense_sg;
 	unsigned char       sense_cmd[6];   /* Allocate 6 characters for sense command */
-#define TIMER_ENABLED		0x01
-#define TIMER_EXPIRED		0x02
-#define TIMED_CMD_DONE		0x04
-        volatile unsigned char timer_status;
-#ifndef AIC7XXX_POLL
-	struct wait_queue   *waiting;       /* wait queue for device reset command */
-        struct wait_queue   waitq;          /* waiting points to this */
-	struct timer_list   timer;          /* timeout for device reset command */
-#endif
 };
 
 typedef void (*timeout_fn)(unsigned long);
@@ -1010,6 +1047,7 @@
   int                      numscb;           /* current number of scbs */
   int                      extended;         /* extended xlate? */
   aha_type                 type;             /* card type */
+  aha_chip_type            chip_type;        /* chip base type */
   int                      ultra_enabled;    /* Ultra SCSI speed enabled */
   int                      chan_num;         /* for 3940/3985, channel number */
   aha_bus_type             bus_type;         /* normal/twin/wide bus */
@@ -1066,6 +1104,7 @@
   int              busrtime;   /* bus release time */
   int              walk_scbs;  /* external SCB RAM detected; walk the scb array */
   aha_type         type;       /* card type */
+  aha_chip_type    chip_type;  /* chip base type */
   int              ultra_enabled;    /* Ultra SCSI speed enabled */
   int              chan_num;   /* for 3940/3985, channel number */
   aha_bus_type     bus_type;   /* normal/twin/wide bus */
@@ -1103,7 +1142,7 @@
 static int num_aic7xxx_syncrates =
     sizeof(aic7xxx_syncrates) / sizeof(aic7xxx_syncrates[0]);
 
-static int number_of_3940s = 0;
+static int number_of_39xxs = 0;
 
 #ifdef AIC7XXX_DEBUG
 
@@ -1140,7 +1179,7 @@
    * release time and data FIFO threshold from the scsi_conf and
    * host_conf registers respectively.
    */
-  if ((p->type == AIC_274x) || (p->type == AIC_284x))
+  if (p->chip_type == AIC_777x)
   {
     dfthresh = (host_conf >> 6);
   }
@@ -1157,36 +1196,33 @@
 
   switch (p->type)
   {
-    case AIC_274x:
-      printk("AIC7770%s AT EISA SLOT %d:\n", BUSW[p->bus_type], p->base >> 12);
+    case AIC_7770:
+    case AIC_7771:
+      printk("%s%s AT EISA SLOT %d:\n", board_names[p->type], BUSW[p->bus_type],
+             p->base >> 12);
       break;
 
     case AIC_284x:
-      printk("AIC7770%s AT VLB SLOT %d:\n", BUSW[p->bus_type], p->base >> 12);
-      break;
-
-    case AIC_7870:
-      printk("AIC7870/7871%s (PCI-bus):\n", BUSW[p->bus_type]);
+      printk("%s%s AT VLB SLOT %d:\n", board_names[p->type], BUSW[p->bus_type],
+             p->base >> 12);
       break;
 
     case AIC_7850:
-      printk("AIC7850%s (PCI-bus):\n", BUSW[p->bus_type]);
-      break;
-
+    case AIC_7870:
+    case AIC_7871:
     case AIC_7872:
-      printk("AIC7872%s (PCI-bus):\n", BUSW[p->bus_type]);
-      break;
-
+    case AIC_7873:
+    case AIC_7874:
     case AIC_7880:
-      printk("AIC7880/7881%s (PCI-bus):\n", BUSW[p->bus_type]);
-      break;
-
+    case AIC_7881:
     case AIC_7882:
-      printk("AIC7882%s (PCI-bus):\n", BUSW[p->bus_type]);
+    case AIC_7883:
+    case AIC_7884:
+      printk("%s%s (PCI-bus):\n", board_names[p->type], BUSW[p->bus_type]);
       break;
 
     default:
-      panic("aic7xxx debug_config: internal error\n");
+      panic("aic7xxx: (debug_config) internal error.\n");
   }
 
   printk("    irq %d\n"
@@ -1204,7 +1240,7 @@
 	 SST[(scsi_conf >> 3) & 0x03],
 	 (scsi_conf & 0x40) ? "en" : "dis");
 
-  if (((p->type == AIC_274x) || (p->type == AIC_284x)) && p->parity == AIC_UNKNOWN)
+  if ((p->chip_type == AIC_777x) && (p->parity == AIC_UNKNOWN))
   {
     /*
      * Set the parity for 7770 based cards.
@@ -1217,7 +1253,7 @@
 	   (p->parity == AIC_ENABLED) ? "en" : "dis");
   }
 
-  if (p->type == AIC_274x)
+  if ((p->type == AIC_7770) || (p->type == AIC_7771))
   {
     p->low_term = (scsi_conf & 0x80) ? AIC_ENABLED : AIC_DISABLED;
   }
@@ -1398,109 +1434,6 @@
   }
 }
 
-#ifdef AIC7XXX_POLL
-/*+F*************************************************************************
- * Function:
- *   aic7xxx_poll_scb
- *
- * Description:
- *   Function to poll for command completion when in aborting an SCB.
- *-F*************************************************************************/
-static void
-aic7xxx_poll_scb(struct aic7xxx_host *p,
-                 struct aic7xxx_scb  *scb,
-                 unsigned long       timeout_ticks)
-{
-  unsigned long timer_expiration = jiffies + timeout_ticks;
-
-  while ((jiffies < timer_expiration) && !(scb->timer_status & TIMED_CMD_DONE))
-  {
-    udelay(1000);  /* delay for 1 msec. */
-  }
-}
-
-#else
-/*+F*************************************************************************
- * Function:
- *   aic7xxx_scb_timeout
- *
- * Description:
- *   Called when a SCB reset command times out.  The input is actually
- *   a pointer to the SCB.
- *-F*************************************************************************/
-static void
-aic7xxx_scb_timeout(unsigned long data)
-{
-  struct aic7xxx_scb *scb = (struct aic7xxx_scb *) data;
-
-  scb->timer_status |= TIMER_EXPIRED;
-  wake_up(&(scb->waiting));
-}
-
-/*+F*************************************************************************
- * Function:
- *   aic7xxx_scb_untimeout
- *
- * Description:
- *   This function clears the timeout and wakes up a waiting SCB.
- *-F*************************************************************************/
-static void
-aic7xxx_scb_untimeout(struct aic7xxx_scb *scb)
-{
-  if (scb->timer_status & TIMER_ENABLED)
-  {
-    scb->timer_status = TIMED_CMD_DONE;
-    wake_up(&(scb->waiting));
-  }
-}
-#endif
-
-/*+F*************************************************************************
- * Function:
- *   aic7xxx_scb_tsleep
- *
- * Description:
- *   Emulates a BSD tsleep where a process can sleep for a specified
- *   amount of time, but may be awakened before that.  Linux provides
- *   a sleep_on, wake_up, add_timer, and del_timer which can be used to
- *   emulate tsleep, but there's not enough information available on
- *   how to use them.  For now, we'll just poll for SCB completion.
- *
- *   The parameter ticks is the number of clock ticks
- *   to wait before a timeout.  A 0 is returned if the scb does not
- *   timeout, 1 is returned for a timeout.
- *-F*************************************************************************/
-static int
-aic7xxx_scb_tsleep(struct aic7xxx_host *p,
-                   struct aic7xxx_scb  *scb,
-                   unsigned long        ticks)
-{
-  scb->timer_status = TIMER_ENABLED;
-#ifdef AIC7XXX_POLL
-  UNPAUSE_SEQUENCER(p);
-  aic7xxx_poll_scb(p, scb, ticks);
-#else
-  scb->waiting = &(scb->waitq);
-  scb->timer.expires = jiffies + ticks;
-  scb->timer.data = (unsigned long) scb;
-  scb->timer.function = (timeout_fn) aic7xxx_scb_timeout;
-  add_timer(&scb->timer);
-  UNPAUSE_SEQUENCER(p);
-  sleep_on(&(scb->waiting));
-  del_timer(&scb->timer);
-#endif
-  if (!(scb->timer_status & TIMED_CMD_DONE))
-  {
-    scb->timer_status = 0x0;
-    return (1);
-  }
-  else
-  {
-    scb->timer_status = 0x0;
-    return (0);
-  }
-}
-
 /*+F*************************************************************************
  * Function:
  *   rcs_version
@@ -1633,9 +1566,9 @@
        */
       if (p->ultra_enabled)
       {
-        if (! (aic7xxx_syncrates[i].rate & ULTRA_SXFR))
+        if (!(aic7xxx_syncrates[i].rate & ULTRA_SXFR))
         {
-          printk ("aic7xxx: target %d, channel %c, requests %sMB/s transfers, "
+          printk ("aic7xxx: Target %d, channel %c, requests %sMB/s transfers, "
                   "but adapter in Ultra mode can only sync at 10MB/s or "
                   "above.\n", target, channel, aic7xxx_syncrates[i].english);
           break;  /* Use asynchronous transfers. */
@@ -1658,18 +1591,18 @@
         }
       }
       *scsirate = (aic7xxx_syncrates[i].rate) | (offset & 0x0F);
-      printk("aic7xxx: target %d, channel %c, now synchronous at %sMB/s, "
-             "offset = 0x%x\n",
+      printk("aic7xxx: Target %d, channel %c, now synchronous at %sMB/s, "
+             "offset(0x%x).\n",
 	     target, channel, aic7xxx_syncrates[i].english, offset);
       return;
     }
   }
 
   /*
-   * Default to asyncronous transfer
+   * Default to asynchronous transfer
    */
   *scsirate = 0;
-  printk("aic7xxx: target %d, channel %c, using asynchronous transfers\n",
+  printk("aic7xxx: Target %d, channel %c, using asynchronous transfers.\n",
          target, channel);
 }
 
@@ -1760,6 +1693,10 @@
   int targ = (scb->target_channel_lun >> 4) & 0x0F;
   char chan = (scb->target_channel_lun & SELBUSB) ? 'B' : 'A';
 
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (match_scb) comparing target/channel %d/%c to scb %d/%c\n",
+          target, channel, targ, chan);
+#endif
   if (target == ALL_TARGETS)
   {
     return (chan == channel);
@@ -1783,6 +1720,10 @@
   unsigned char active;
   unsigned long active_port = HA_ACTIVE0(base);
 
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (unbusy_target) target/channel %d/%c\n",
+          target, channel);
+#endif
   if ((target > 0x07) || (channel == 'B'))
   {
     /*
@@ -1809,36 +1750,29 @@
   long flags;
   Scsi_Cmnd *cmd = scb->cmd;
 
-  if (scb->timer_status & TIMER_ENABLED)
-  {
-#ifdef AIC7XXX_POLL
-    scb->timer_status |= TIMED_CMD_DONE;
-#else
-    aic7xxx_scb_untimeout(scb);
+#ifdef 0
+  printk ("aic7xxx: (done) target/channel %d/%d\n",
+          cmd->target, cmd->channel);
 #endif
-  }
-  else
-  {
-    /*
-     * This is a critical section, since we don't want the
-     * queue routine mucking with the host data.
-     */
-    save_flags(flags);
-    cli();
+  /*
+   * This is a critical section, since we don't want the
+   * queue routine mucking with the host data.
+   */
+  save_flags(flags);
+  cli();
 
-    /*
-     * Process the command after marking the scb as free
-     * and adding it to the free list.
-     */
-    scb->state = SCB_FREE;
-    scb->next = p->free_scb;
-    p->free_scb = &(p->scb_array[scb->position]);
-    scb->cmd = NULL;
+  /*
+   * Process the command after marking the scb as free
+   * and adding it to the free list.
+   */
+  scb->state = SCB_FREE;
+  scb->next = p->free_scb;
+  p->free_scb = &(p->scb_array[scb->position]);
+  scb->cmd = NULL;
 
-    restore_flags(flags);
+  restore_flags(flags);
 
-    cmd->scsi_done(cmd);
-  }
+  cmd->scsi_done(cmd);
 }
 
 /*+F*************************************************************************
@@ -1980,6 +1914,10 @@
   scb->cmd->result = (DID_RESET << 16);
   aic7xxx_done(p, scb);
 
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (abort_waiting_scb) target/channel %d/%c, prev %d, "
+          "to_scb %d, next %d\n", target, channel, prev, timedout_scb, next);
+#endif
   return (next);
 }
 
@@ -2006,6 +1944,10 @@
    */
   active_scb = inb(SCBPTR(base));
 
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (reset_device) target/channel %d/%c, to_scb %d, "
+          "active_scb %d\n", target, channel, timedout_scb, active_scb);
+#endif
   /*
    * Search the QINFIFO.
    */
@@ -2075,7 +2017,7 @@
    * are other (most likely tagged) commands that
    * were disconnected when the reset occured.
    */
-  for(i = 0; i < p->numscb; i++)
+  for (i = 0; i < p->numscb; i++)
   {
     scb = &(p->scb_array[i]);
     if ((scb->state & SCB_ACTIVE) && aic7xxx_match_scb(scb, target, channel))
@@ -2107,6 +2049,9 @@
 static void
 aic7xxx_reset_current_bus(int base)
 {
+#ifdef AIC7XXX_DEBUG_ABORT
+    printk ("aic7xxx: (reset_current_bus)\n");
+#endif
   outb(SCSIRSTO, SCSISEQ(base));
   udelay(1000);
   outb(0, SCSISEQ(base));
@@ -2129,6 +2074,10 @@
   unsigned long offset, offset_max;
   int found;
 
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (reset_channel) channel %c, to_scb %d\n",
+          channel, timedout_scb);
+#endif
   /*
    * Clean up all the state information for the
    * pending transactions on this bus.
@@ -2189,6 +2138,10 @@
   cur_channel = (sblkctl & SELBUSB) ? 'B' : 'A';
   if (cur_channel != channel)
   {
+#ifdef AIC7XXX_DEBUG_ABORT
+    printk ("aic7xxx: (reset_channel) Stealthily resetting channel %c\n",
+            channel);
+#endif
     /*
      * Stealthily reset the other bus without upsetting the current bus
      */
@@ -2203,6 +2156,10 @@
    */
   else
   {
+#ifdef AIC7XXX_DEBUG_ABORT
+    printk ("aic7xxx: (reset_channel) Resetting current channel %c\n",
+            channel);
+#endif
     aic7xxx_reset_current_bus(base);
     RESTART_SEQUENCER(p);
   }
@@ -2260,7 +2217,7 @@
     if (aic7xxx_spurious_count == 1)
     {
       aic7xxx_spurious_count = 2;
-      printk("aic7xxx_isr: Encountered spurious interrupt.\n");
+      printk("aic7xxx: (aic7xxx_isr) Encountered spurious interrupt.\n");
       return;
     }
     else
@@ -2286,7 +2243,7 @@
      * It is sufficient that we check isr_count and not the spurious
      * interrupt count.
      */
-    printk("aic7xxx_isr: Encountered spurious interrupt.\n");
+    printk("aic7xxx: (aic7xxx_isr) Encountered spurious interrupt.\n");
     return;
   }
 
@@ -2302,7 +2259,7 @@
     int i;
     unsigned char errno = inb(ERROR(base));
 
-    printk("aic7xxx_isr: brkadrint (0x%x):\n", errno);
+    printk("aic7xxx: (aic7xxx_isr) BRKADRINT error(0x%x):\n", errno);
     for (i = 0; i < NUMBER(hard_error); i++)
     {
       if (errno & hard_error[i].errno)
@@ -2311,7 +2268,7 @@
       }
     }
 
-    panic("aic7xxx_isr: brkadrint, error = 0x%x, seqaddr = 0x%x\n",
+    panic("aic7xxx: (aic7xxx_isr) BRKADRINT, error(0x%x) seqaddr(0x%x).\n",
 	  inb(ERROR(base)), (inb(SEQADDR1(base)) << 8) | inb(SEQADDR0(base)));
   }
 
@@ -2337,21 +2294,21 @@
     switch (intstat & SEQINT_MASK)
     {
       case BAD_PHASE:
-	panic("aic7xxx_isr: unknown scsi bus phase\n");
+	panic("aic7xxx: (aic7xxx_isr) Unknown scsi bus phase.\n");
 	break;
 
       case SEND_REJECT:
         rej_byte = inb(HA_REJBYTE(base));
         if (rej_byte != 0x20)
         {
-          debug("aic7xxx_isr warning: issuing message reject, 1st byte 0x%x\n",
+          debug("aic7xxx: Warning - Issuing message reject, 1st byte(0x%x)\n",
                 rej_byte);
         }
         else
         {
           scb_index = inb(SCBPTR(base));
           scb = &(p->scb_array[scb_index]);
-          printk("aic7xxx_isr warning: Tagged message rejected for target %d,"
+          printk("aic7xxx: Warning - Tagged message rejected for target %d,"
                  " channel %c.\n", scsi_id, channel);
           scb->cmd->device->tagged_supported = 0;
           scb->cmd->device->tagged_queue = 0;
@@ -2359,15 +2316,15 @@
 	break;
 
       case NO_IDENT:
-	panic("aic7xxx_isr: Target %d, channel %c, did not send an IDENTIFY "
-	      "message.  SAVED_TCL = 0x%x\n",
+	panic("aic7xxx: Target %d, channel %c, did not send an IDENTIFY "
+	      "message. SAVED_TCL(0x%x).\n",
               scsi_id, channel, inb(SAVED_TCL(base)));
 	break;
 
       case NO_MATCH:
-	printk("aic7xxx_isr: No active SCB for reconnecting target %d, "
-	      "channel %c - issuing ABORT\n", scsi_id, channel);
-        printk("SAVED_TCL = 0x%x\n", inb(SAVED_TCL(base)));
+	printk("aic7xxx: No active SCB for reconnecting target %d, "
+	      "channel %c - Issuing ABORT. SAVED_TCL(0x%x).\n",
+              scsi_id, channel, inb(SAVED_TCL(base)));
         aic7xxx_unbusy_target(scsi_id, channel, base);
         outb(SCB_NEEDDMA, SCBARRAY(base));
 
@@ -2430,7 +2387,7 @@
 	    /*
 	     * Send our own SDTR in reply.
 	     */
-	    printk("aic7xxx_isr: Sending SDTR!!\n");
+	    printk("aic7xxx: Sending SDTR!!\n");
 	    outb(SEND_SDTR, HA_RETURN_1(base));
 	  }
 	}
@@ -2450,8 +2407,8 @@
       case MSG_WDTR:
       {
 	bus_width = inb(ACCUM(base));
-	printk("aic7xxx_isr: Received MSG_WDTR, scsi_id %d, channel %c "
-	       "needwdtr = 0x%x\n", scsi_id, channel, p->needwdtr);
+	printk("aic7xxx: Received MSG_WDTR, Target %d, channel %c "
+	       "needwdtr(0x%x).\n", scsi_id, channel, p->needwdtr);
 	scratch = inb(HA_TARG_SCRATCH(base) + scratch_offset);
 
 	if (p->wdtr_pending & target_mask)
@@ -2467,8 +2424,8 @@
 	      break;
 
 	    case BUS_16_BIT:
-	      printk("aic7xxx_isr: target %d, channel %c, using 16 bit transfers\n",
-		     scsi_id, channel);
+	      printk("aic7xxx: Target %d, channel %c, using 16 bit "
+                     "transfers.\n", scsi_id, channel);
 	      scratch |= 0x80;
 	      break;
 	  }
@@ -2478,7 +2435,7 @@
 	  /*
 	   * Send our own WDTR in reply.
 	   */
-	  printk("aic7xxx_isr: Will send WDTR!!\n");
+	  printk("aic7xxx: Will send WDTR!!\n");
 	  switch (bus_width)
 	  {
 	    case BUS_8_BIT:
@@ -2493,8 +2450,8 @@
 	      /* Yes, we mean to fall thru here. */
 
 	    case BUS_16_BIT:
-	      printk("aic7xxx_isr: target %d, channel %c, using 16 bit transfers\n",
-		     scsi_id, channel);
+	      printk("aic7xxx: Target %d, channel %c, using 16 bit "
+                     "transfers.\n", scsi_id, channel);
 	      scratch |= 0x80;
 	      break;
 	  }
@@ -2527,8 +2484,8 @@
 	  p->needwdtr &= ~target_mask;
 	  p->wdtr_pending &= ~target_mask;
 	  outb(scratch, HA_TARG_SCRATCH(base) + scratch_offset);
-	  printk("aic7xxx: target %d, channel %c, refusing WIDE negotiation. "
-                 "Using 8 bit transfers\n", scsi_id, channel);
+	  printk("aic7xxx: Target %d, channel %c, refusing WIDE negotiation. "
+                 "Using 8 bit transfers.\n", scsi_id, channel);
 	}
 	else
 	{
@@ -2541,8 +2498,9 @@
 	    p->needsdtr &= ~target_mask;
 	    p->sdtr_pending &= ~target_mask;
 	    outb(scratch, HA_TARG_SCRATCH(base) + scratch_offset);
-	    printk("aic7xxx: target %d, channel %c, refusing syncronous negotiation. "
-                   "Using asyncronous transfers\n", scsi_id, channel);
+	    printk("aic7xxx: Target %d, channel %c, refusing synchronous "
+                   "negotiation. Using asynchronous transfers.\n",
+                   scsi_id, channel);
 	  }
 	  /*
 	   * Otherwise, we ignore it.
@@ -2559,8 +2517,8 @@
 	outb(0, HA_RETURN_1(base));   /* CHECK_CONDITION may change this */
 	if ((scb->state != SCB_ACTIVE) || (scb->cmd == NULL))
 	{
-	  printk("aic7xxx_isr: referenced scb not valid "
-		 "during seqint 0x%x scb(%d) state(%x), cmd(%x)\n",
+	  printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
+		 "scb(%d) state(0x%x) cmd(0x%x).\n",
 		 intstat, scb_index, scb->state, (unsigned int) scb->cmd);
 	}
 	else
@@ -2574,7 +2532,7 @@
 	  switch (status_byte(scb->target_status))
 	  {
 	    case GOOD:
-              printk("aic7xxx_isr: Interrupted for status of 0???\n");
+              printk("aic7xxx: Interrupted for status of GOOD???\n");
 	      break;
 
 	    case CHECK_CONDITION:
@@ -2648,7 +2606,7 @@
 	      break;
 
 	    case BUSY:
-	      printk("aic7xxx_isr: Target busy\n");
+	      printk("aic7xxx: Target busy.\n");
 	      if (!aic7xxx_error(cmd))
 	      {
 		aic7xxx_error(cmd) = DID_BUS_BUSY;
@@ -2656,7 +2614,7 @@
 	      break;
 
 	    case QUEUE_FULL:
-	      printk("aic7xxx_isr: Queue full\n");
+	      printk("aic7xxx: Queue full.\n");
 	      if (!aic7xxx_error(cmd))
 	      {
 		aic7xxx_error(cmd) = DID_RETRY_COMMAND;
@@ -2664,7 +2622,7 @@
 	      break;
 
 	    default:
-	      printk("aic7xxx_isr: Unexpected target status 0x%x\n",
+	      printk("aic7xxx: Unexpected target status(0x%x).\n",
 		     scb->target_status);
 	      if (!aic7xxx_error(cmd))
 	      {
@@ -2680,8 +2638,8 @@
 	scb = &(p->scb_array[scb_index]);
 	if ((scb->state != SCB_ACTIVE) || (scb->cmd == NULL))
 	{
-	  printk("aic7xxx_isr: referenced scb not valid "
-		 "during seqint 0x%x scb(%d) state(%x), cmd(%x)\n",
+	  printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
+		 "scb(%d) state(0x%x) cmd(0x%x).\n",
 		 intstat, scb_index, scb->state, (unsigned int) scb->cmd);
 	}
 	else
@@ -2707,9 +2665,10 @@
 
 	    if (actual < cmd->underflow)
 	    {
-	      printk("aic7xxx: target %d underflow - "
-		     "wanted (at least) %u, got %u, count=%d\n",
-		     cmd->target, cmd->underflow, actual, inb(SCBARRAY(base + 18)));
+	      printk("aic7xxx: Target %d underflow - "
+		     "Wanted (at least) (%u) got(%u) count(%d).\n",
+		     cmd->target, cmd->underflow, actual,
+                     inb(SCBARRAY(base + 18)));
 	      aic7xxx_error(cmd) = DID_RETRY_COMMAND;
 	      aic7xxx_status(cmd) = scb->target_status;
 	    }
@@ -2722,20 +2681,20 @@
 	scb = &(p->scb_array[scb_index]);
 	if ((scb->state != SCB_ACTIVE) || (scb->cmd == NULL))
 	{
-	  printk("aic7xxx_isr: referenced scb not valid "
-		 "during seqint 0x%x scb(%d) state(%x), cmd(%x)\n",
+	  printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
+		 "scb(%d) state(0x%x) cmd(0x%x)\n",
 		 intstat, scb_index, scb->state, (unsigned int) scb->cmd);
 	}
 	else
 	{
 	  cmd = scb->cmd;
 	  /*
-	   * We didn't recieve a valid tag back from the target
+	   * We didn't receive a valid tag back from the target
 	   * on a reconnect.
 	   */
-	  printk("aic7xxx_isr: invalid tag recieved on channel %c "
-		 "target %d, lun %d -- sending ABORT_TAG\n",
-		  channel, scsi_id, cmd->lun & 0x07);
+	  printk("aic7xxx: Invalid tag received on target %d, channel %c, "
+                 "lun %d - Sending ABORT_TAG.\n",
+		  scsi_id, channel, cmd->lun & 0x07);
 
 	  cmd->result = (DID_RETRY_COMMAND << 16);
           aic7xxx_done(p, scb);
@@ -2747,8 +2706,8 @@
 	scb = &(p->scb_array[scb_index]);
 	if ((scb->state != SCB_ACTIVE) || (scb->cmd == NULL))
 	{
-	  printk("aic7xxx_isr: referenced scb not valid "
-		 "during seqint 0x%x scb(%d) state(%x), cmd(%x)\n",
+	  printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
+		 "scb(%d) state(0x%x) cmd(0x%x).\n",
 		 intstat, scb_index, scb->state, (unsigned int) scb->cmd);
 	}
 	else
@@ -2760,13 +2719,17 @@
 	   */
 	   if (scb->state & SCB_DEVICE_RESET)
 	   {
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (isr) sending bus device reset to target %d\n",
+          scsi_id);
+#endif
 	     outb(MSG_BUS_DEVICE_RESET, HA_MSG_START(base));
 	     outb(1, HA_MSG_LEN(base));
 	   }
 	   else
 	   {
-	     panic("aic7xxx_isr: AWAITING_SCB for an SCB that does "
-		   "not have a waiting message");
+	     panic("aic7xxx: AWAITING_SCB for an SCB that does "
+		   "not have a waiting message.\n");
 	   }
 	}
 	break;
@@ -2774,6 +2737,10 @@
       case IMMEDDONE:
         scb_index = inb(SCBPTR(base));
 	scb = &(p->scb_array[scb_index]);
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (isr) received IMMEDDONE for target %d, scb %d, state %d\n",
+          scsi_id, scb_index, scb->state);
+#endif
         if (scb->state & SCB_DEVICE_RESET)
         {
           int found;
@@ -2793,12 +2760,12 @@
         }
         else
         {
-          panic("aic7xxx_isr: Immediate complete for unknown operation.\n");
+          panic("aic7xxx: Immediate complete for unknown operation.\n");
         }
         break;
 
       default:               /* unknown */
-	debug("aic7xxx_isr: seqint, intstat = 0x%x, scsisigi = 0x%x\n",
+	debug("aic7xxx: SEQINT, INTSTAT(0x%x) SCSISIGI(0x%x).\n",
 	      intstat, inb(SCSISIGI(base)));
 	break;
     }
@@ -2814,7 +2781,7 @@
     scb = &(p->scb_array[scb_index]);
     if ((scb->state != SCB_ACTIVE) || (scb->cmd == NULL))
     {
-      printk("aic7xxx_isr: no command for scb (scsiint)\n");
+      printk("aic7xxx: No command for SCB (SCSIINT).\n");
       /*
        * Turn off the interrupt and set status
        * to zero, so that it falls through the
@@ -2900,7 +2867,7 @@
 	RESTART_SEQUENCER(p);
         aic7xxx_done(p, scb);
 #if 0
-  printk("aic7xxx_isr: SELTO scb(%d) state(%x), cmd(%x)\n",
+  printk("aic7xxx: SELTO SCB(%d) state(0x%x) cmd(0x%x).\n",
 	 scb->position, scb->state, (unsigned int) scb->cmd);
 #endif
       }
@@ -2912,11 +2879,8 @@
 	   * A parity error has occurred during a data
 	   * transfer phase. Flag it and continue.
 	   */
-	  printk("aic7xxx: parity error on target %d, "
-		 "channel %d, lun %d\n",
-		 cmd->target,
-		 cmd->channel & 0x01,
-		 cmd->lun & 0x07);
+	  printk("aic7xxx: Parity error on target %d, channel %d, lun %d.\n",
+		 cmd->target, cmd->channel & 0x01, cmd->lun & 0x07);
 	  aic7xxx_error(cmd) = DID_PARITY;
 
 	  /*
@@ -2936,7 +2900,7 @@
 	      * We don't know what's going on. Turn off the
 	      * interrupt source and try to continue.
 	      */
-	     printk("aic7xxx_isr: sstat1 = 0x%x\n", status);
+	     printk("aic7xxx: SSTAT1(0x%x).\n", status);
 	     outb(status, CLRSINT1(base));
 	     UNPAUSE_SEQUENCER(p);
 	     outb(CLRSCSIINT, CLRINT(base));
@@ -2962,9 +2926,8 @@
       scb = &(p->scb_array[complete]);
       if ((scb->state != SCB_ACTIVE) || (scb->cmd == NULL))
       {
-	printk("aic7xxx warning: "
-	       "no command for scb %d (cmdcmplt)\n"
-	       "QOUTCNT = %d, SCB state = 0x%x, CMD = 0x%x, pos = %d\n",
+	printk("aic7xxx: Warning - No command for SCB %d (CMDCMPLT).\n"
+	       "         QOUTCNT(%d) SCB state(0x%x) cmd(0x%x) pos(%d).\n",
 	       complete, inb(QOUTFIFO(base)),
 	       scb->state, (unsigned int) scb->cmd, scb->position);
 	outb(CLRCMDINT, CLRINT(base));
@@ -2981,7 +2944,7 @@
 	cmd->flags &= ASKED_FOR_SENSE;
       }
 #if 0
-      printk("aic7xxx_intr: (complete) state = %d, cmd = 0x%x, free = 0x%x\n",
+      printk("aic7xxx: (complete) State(%d) cmd(0x%x) free(0x%x).\n",
 	     scb->state, (unsigned int) scb->cmd, (unsigned int) p->free_scb);
 #endif
 
@@ -2999,9 +2962,9 @@
 #if 0
   if (scb != &p->scb_array[scb->position])
   {
-    printk("aic7xxx_isr: (complete) address mismatch, pos %d\n", scb->position);
+    printk("aic7xxx: (complete) Address mismatch, pos(%d).\n", scb->position);
   }
-  printk("aic7xxx_isr: (complete) state = %d, cmd = 0x%x, free = 0x%x\n",
+  printk("aic7xxx: (complete) State(%d) cmd(0x%x) free(0x%x).\n",
 	 scb->state, (unsigned int) scb->cmd, (unsigned int) p->free_scb);
 #endif
 
@@ -3084,8 +3047,8 @@
     unsigned char signature[sizeof(buf)];
     aha_type type;
   } AIC7xxx[] = {
-    { 4, { 0x04, 0x90, 0x77, 0x71 }, AIC_274x },  /* host adapter 274x */
-    { 4, { 0x04, 0x90, 0x77, 0x70 }, AIC_274x },  /* motherboard 274x  */
+    { 4, { 0x04, 0x90, 0x77, 0x71 }, AIC_7771 },  /* host adapter 274x */
+    { 4, { 0x04, 0x90, 0x77, 0x70 }, AIC_7770 },  /* motherboard 7770  */
     { 4, { 0x04, 0x90, 0x77, 0x56 }, AIC_284x },  /* 284x, BIOS enabled */
     { 4, { 0x04, 0x90, 0x77, 0x57 }, AIC_284x }   /* 284x, BIOS disabled */
   };
@@ -3112,7 +3075,7 @@
 	return (AIC7xxx[i].type);
       }
 
-      printk("aic7xxx disabled at slot %d, ignored\n", slot);
+      printk("aic7xxx: Disabled at slot %d, ignored.\n", slot);
     }
   }
 
@@ -3478,7 +3441,8 @@
 
   switch (type)
   {
-    case AIC_274x:
+    case AIC_7770:
+    case AIC_7771:
     case AIC_284x:
       /*
        * Check for Rev C or E boards. Rev E boards can supposedly have
@@ -3496,13 +3460,13 @@
         /*
          * We detected a Rev E board.
          */
-	printk("aic7770: Rev E and subsequent; using 4 SCB's\n");
+	printk("aic7770: Rev E and subsequent; using 4 SCB's.\n");
 	outb(sblkctl_reg ^ AUTOFLUSHDIS, SBLKCTL(base));
 	maxscb = 4;
       }
       else
       {
-	printk("aic7770: Rev C and previous; using 4 SCB's\n");
+	printk("aic7770: Rev C and previous; using 4 SCB's.\n");
 	maxscb = 4;
       }
       break;
@@ -3512,12 +3476,18 @@
       break;
 
     case AIC_7870:
+    case AIC_7871:
+    case AIC_7874:
     case AIC_7880:
+    case AIC_7881:
+    case AIC_7884:
       maxscb = 16;
       break;
 
     case AIC_7872:
+    case AIC_7873:
     case AIC_7882:
+    case AIC_7883:
       /*
        * Is suppose to have 255 SCBs, but we'll walk the SCBs
        * looking for more if external RAM is detected.
@@ -3549,7 +3519,7 @@
       }
       i++;
     }
-    maxscb = i;		
+    maxscb = i;
   }
 
   return (maxscb);
@@ -3566,8 +3536,6 @@
 aic7xxx_register(Scsi_Host_Template *template,
                  struct aic7xxx_host_config *config)
 {
-  static const char * board_name[] = {"", "274x", "284x", "7870", "7850",
-                                      "7872", "7881"};
   int i;
   unsigned char sblkctl;
   int max_targets;
@@ -3589,10 +3557,8 @@
 
   switch (config->type)
   {
-    case AIC_274x:
-#if 0
-      printk("aha274x: HCNTRL:0x%x\n", inb(HCNTRL(base)));
-#endif
+    case AIC_7770:
+    case AIC_7771:
       /*
        * For some 274x boards, we must clear the CHIPRST bit
        * and pause the sequencer. For some reason, this makes
@@ -3611,7 +3577,7 @@
       aic7xxx_delay(1);
       if (inb(HCNTRL(base)) & CHIPRST)
       {
-	printk("aic7xxx_register: Chip reset not cleared; clearing manually.\n");
+	printk("aic7xxx: Chip reset not cleared; clearing manually.\n");
       }
       outb(config->pause, HCNTRL(base));
 
@@ -3634,14 +3600,11 @@
       /*
        * A reminder until this can be detected automatically.
        */
-      printk("aha274x: Extended translation %sabled\n",
+      printk("aic7xxx: Extended translation %sabled.\n",
 	     config->extended ? "en" : "dis");
       break;
 
     case AIC_284x:
-#if 0
-      printk("aha284x: HCNTRL:0x%x\n", inb(HCNTRL(base)));
-#endif
       outb(CHIPRST, HCNTRL(base));
       config->unpause = UNPAUSE_284X;
       config->pause = REQ_PAUSE; /* DWG would like to be like the rest */
@@ -3656,22 +3619,28 @@
       }
       host_conf = inb(HA_HOSTCONF(base));
 
-      printk("aha284x: Reading SEEPROM...");
+      printk("aic7xxx: Reading SEEPROM...");
       have_seeprom = read_2840_seeprom(base, &sc);
       if (!have_seeprom)
       {
-	printk("aha284x: Unable to read SEEPROM\n");
+	printk("aic7xxx: Unable to read SEEPROM.\n");
         config->busrtime = host_conf & 0x3C;
       }
       else
       {
 	printk("done.\n");
-	config->extended = ((sc.bios_control & CFEXTEND) >> 7);
+	config->extended = ((sc.bios_control & CF284XEXTEND) >> 5);
 	config->scsi_id = (sc.brtime_id & CFSCSIID);
 	config->parity = (sc.adapter_control & CFSPARITY) ?
 			 AIC_ENABLED : AIC_DISABLED;
-	config->low_term = (sc.adapter_control & CFSTERM) ?
+	config->low_term = (sc.adapter_control & CF284XSTERM) ?
 			      AIC_ENABLED : AIC_DISABLED;
+	/*
+	 * XXX - Adaptec *does* make 284x wide controllers, but the
+	 *       documents do not say where the high byte termination
+	 *       enable bit is located.  For now, we'll just assume
+	 *       that it's in the same place as for the 2940 card.
+	 */
 	config->high_term = (sc.adapter_control & CFWSTERM) ?
 			      AIC_ENABLED : AIC_DISABLED;
 	config->busrtime = ((sc.brtime_id & CFBRTIME) >> 8);
@@ -3681,19 +3650,21 @@
       outb(host_conf & DFTHRSH, BUSSPD(base));
       outb((host_conf << 2) & BOFF, BUSTIME(base));
 
-      printk("aha284x: Extended translation %sabled\n",
+      printk("aic7xxx: Extended translation %sabled.\n",
 	     config->extended ? "en" : "dis");
       break;
 
     case AIC_7850:
     case AIC_7870:
+    case AIC_7871:
     case AIC_7872:
+    case AIC_7873:
+    case AIC_7874:
     case AIC_7880:
+    case AIC_7881:
     case AIC_7882:
-#if 0
-      printk("aic%s HCNTRL:0x%x\n", board_name[config->type], inb(HCNTRL(base)));
-#endif
-
+    case AIC_7883:
+    case AIC_7884:
       outb(CHIPRST, HCNTRL(base));
       config->unpause = UNPAUSE_294X;
       config->pause = config->unpause | PAUSE;
@@ -3703,11 +3674,11 @@
       config->extended = aic7xxx_extended;
       config->scsi_id = 7;
 
-      printk("aic78xx: Reading SEEPROM...");
+      printk("aic7xxx: Reading SEEPROM...");
       have_seeprom = read_seeprom(base, config->chan_num * (sizeof(sc) / 2), &sc);
       if (!have_seeprom)
       {
-	printk("aic78xx: Unable to read SEEPROM\n");
+	printk("aic7xxx: Unable to read SEEPROM.\n");
       }
       else
       {
@@ -3721,7 +3692,8 @@
 	config->high_term = (sc.adapter_control & CFWSTERM) ?
 			      AIC_ENABLED : AIC_DISABLED;
 	config->busrtime = ((sc.brtime_id & CFBRTIME) >> 8);
-        if (((config->type == AIC_7880) || (config->type == AIC_7882)) &&
+        if (((config->type == AIC_7880) || (config->type == AIC_7882) ||
+             (config->type == AIC_7883) || (config->type == AIC_7884)) &&
             (sc.adapter_control & CFULTRAEN))
         {
           printk ("aic7xxx: Enabling support for Ultra SCSI speed.\n");
@@ -3741,25 +3713,25 @@
        */
       outb(config->scsi_id, (HA_SCSICONF(base) + 1));
 
-      printk("aic%s: Extended translation %sabled\n", board_name[config->type],
+      printk("aic7xxx: Extended translation %sabled.\n",
 	     config->extended ? "en" : "dis");
       break;
 
     default:
-      panic("aic7xxx_register: internal error\n");
+      panic("aic7xxx: (aic7xxx_register) Internal error.\n");
   }
 
   config->maxscb = detect_maxscb(config->type, base, config->walk_scbs);
 
-  if ((config->type == AIC_274x) || (config->type == AIC_284x))
+  if (config->chip_type == AIC_777x)
   {
     if (config->pause & IRQMS)
     {
-      printk("aic7xxx: Using Level Sensitive Interrupts\n");
+      printk("aic7xxx: Using level sensitive interrupts.\n");
     }
     else
     {
-      printk("aic7xxx: Using Edge Triggered Interrupts\n");
+      printk("aic7xxx: Using edge triggered interrupts.\n");
     }
   }
 
@@ -3779,8 +3751,8 @@
     case SELWIDE:     /* Wide bus */
       config->scsi_id = inb(HA_SCSICONF(base) + 1) & 0x0F;
       config->bus_type = AIC_WIDE;
-      printk("aic7xxx: Enabling wide channel of %s-Wide\n",
-	     board_name[config->type]);
+      printk("aic7xxx: Enabling wide channel of %s-Wide.\n",
+	     board_names[config->type]);
       outb(WIDE_BUS, HA_FLAGS(base));
       break;
 
@@ -3789,19 +3761,19 @@
 #ifdef AIC7XXX_TWIN_SUPPORT
       config->scsi_id_b = inb(HA_SCSICONF(base) + 1) & 0x07;
       config->bus_type = AIC_TWIN;
-      printk("aic7xxx: Enabled channel B of %s-Twin\n",
-	     board_name[config->type]);
+      printk("aic7xxx: Enabled channel B of %s-Twin.\n",
+	     board_names[config->type]);
       outb(TWIN_BUS, HA_FLAGS(base));
 #else
       config->bus_type = AIC_SINGLE;
-      printk("aic7xxx: Channel B of %s-Twin will be ignored\n",
-	     board_name[config->type]);
+      printk("aic7xxx: Channel B of %s-Twin will be ignored.\n",
+	     board_names[config->type]);
       outb(0, HA_FLAGS(base));
 #endif
       break;
 
     default:
-      printk("aic7xxx is an unsupported type 0x%x, please "
+      printk("aic7xxx: Unsupported type 0x%x, please "
 	     "mail deang@ims.com\n", inb(SBLKCTL(base)));
       outb(0, HA_FLAGS(base));
       return (0);
@@ -3822,12 +3794,11 @@
    *     in the lower four bits; the ECU information shows the
    *     high bit being used as well. Which is correct?
    *
-   * The 294x cards (PCI) get their interrupt from PCI BIOS.
+   * The PCI cards get their interrupt from PCI BIOS.
    */
-  if (((config->type == AIC_274x) || (config->type == AIC_284x)) &&
-      (config->irq < 9 || config->irq > 15))
+  if ((config->chip_type == AIC_777x) && ((config->irq < 9) || (config->irq > 15)))
   {
-    printk("aic7xxx uses unsupported IRQ level, ignoring.\n");
+    printk("aic7xxx: Host adapter uses unsupported IRQ level, ignoring.\n");
     return (0);
   }
 
@@ -3841,7 +3812,7 @@
 #ifndef AIC7XXX_SHARE_IRQS
    if (aic7xxx_boards[config->irq] != NULL)
    {
-     printk("aic7xxx_register: Sharing of IRQs is not configured.\n");
+     printk("aic7xxx: Sharing of IRQ's is not configured.\n");
      return (0);
    }
 #endif
@@ -3866,8 +3837,8 @@
 
     if (SG_STRUCT_CHECK(sg))
     {
-      printk("aic7xxx warning: kernel scatter-gather "
-	     "structures changed, disabling it.\n");
+      printk("aic7xxx: Warning - Kernel scatter-gather structures changed, "
+             "disabling it.\n");
       template->sg_tablesize = SG_NONE;
     }
   }
@@ -3914,6 +3885,7 @@
   p->numscb = 0;
   p->extended = config->extended;
   p->type = config->type;
+  p->chip_type = config->chip_type;
   p->ultra_enabled = config->ultra_enabled;
   p->chan_num = config->chan_num;
   p->bus_type = config->bus_type;
@@ -3941,7 +3913,7 @@
      */
     if (request_irq(config->irq, aic7xxx_isr, SA_INTERRUPT, "aic7xxx"))
     {
-      printk("aic7xxx couldn't register irq %d, ignoring\n", config->irq);
+      printk("aic7xxx: Couldn't register IRQ %d, ignoring.\n", config->irq);
       aic7xxx_boards[config->irq] = NULL;
       return (0);
     }
@@ -3972,7 +3944,7 @@
    */
   outb(FASTMODE, SEQCTL(base));
 
-  if ((p->type == AIC_274x) || (p->type == AIC_284x))
+  if (p->chip_type == AIC_777x)
   {
     outb(ENABLE, BCTL(base));
   }
@@ -4044,13 +4016,13 @@
   {
     if (bios_disabled)
     {
-      printk("aic7xxx : Host Adapter Bios disabled. Using default SCSI "
-             "device parameters\n");
+      printk("aic7xxx : Host adapter BIOS disabled. Using default SCSI "
+             "device parameters.\n");
       p->discenable = 0xFFFF;
     }
     else
     {
-      p->discenable = ~((inb(HA_DISC_DSB(base + 1)) << 8) |
+      p->discenable = ~((inb(HA_DISC_DSB(base) + 1) << 8) |
           inb(HA_DISC_DSB(base)));
     }
   }
@@ -4194,7 +4166,6 @@
 int
 aic7xxx_detect(Scsi_Host_Template *template)
 {
-  aha_type type = AIC_NONE;
   int found = 0, slot, base;
   unsigned char irq = 0;
   int i;
@@ -4236,25 +4207,20 @@
       continue;
     }
 
-    type = aic7xxx_probe(slot, HID0(base));
-    if (type != AIC_NONE)
+    config.type = aic7xxx_probe(slot, HID0(base));
+    if (config.type != AIC_NONE)
     {
       /*
        * We found a card, allow 1 spurious interrupt.
        */
       aic7xxx_spurious_count = 1;
 
-#if 0
-      printk("aic7xxx: HCNTRL:0x%x\n", inb(HCNTRL(base)));
-      outb(inb(HCNTRL(base)) | CHIPRST, HCNTRL(base));
-#endif
-
       /*
        * We "find" a AIC-7770 if we locate the card
        * signature and we can set it up and register
        * it with the kernel without incident.
        */
-      config.type = type;
+      config.chip_type = AIC_777x;
       config.base = base;
       config.irq = irq;
       config.parity = AIC_UNKNOWN;
@@ -4273,12 +4239,31 @@
   }
 
 #ifdef CONFIG_PCI
-
   /*
    * PCI-bus probe.
    */
   if (pcibios_present())
   {
+    struct
+    {
+      unsigned short vendor_id;
+      unsigned short device_id;
+      aha_type       card_type;
+      aha_chip_type  chip_type;
+    } const aic7xxx_pci_devices[] = {
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7850, AIC_7850, AIC_785x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7870, AIC_7870, AIC_787x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7871, AIC_7871, AIC_787x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7872, AIC_7872, AIC_787x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7873, AIC_7873, AIC_787x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7874, AIC_7874, AIC_787x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7880, AIC_7880, AIC_788x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7881, AIC_7881, AIC_788x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7882, AIC_7882, AIC_788x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7883, AIC_7883, AIC_788x},
+      {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7884, AIC_7884, AIC_788x}
+    };
+
     int error;
     int done = 0;
     unsigned int io_port;
@@ -4287,146 +4272,132 @@
     unsigned char devrevid, devconfig, devstatus;
     char rev_id[] = {'B', 'C', 'D'};
 
-    while (!done)
+    for (i = 0; i < NUMBER(aic7xxx_pci_devices); i++)
     {
-      if ((!pcibios_find_device(PCI_VENDOR_ID_ADAPTEC,
-				PCI_DEVICE_ID_ADAPTEC_7870,
-				index, &pci_bus, &pci_device_fn)) ||
-	   (!pcibios_find_device(PCI_VENDOR_ID_ADAPTEC,
-				PCI_DEVICE_ID_ADAPTEC_7871,
-				index, &pci_bus, &pci_device_fn)))
-      {
-	type = AIC_7870;
-      }
-      else
+      done = FALSE;
+      while (!done)
       {
-	if (!pcibios_find_device(PCI_VENDOR_ID_ADAPTEC,
-				PCI_DEVICE_ID_ADAPTEC_7850,
-				index, &pci_bus, &pci_device_fn))
-	{
-	  type = AIC_7850;
-	}
-	else
-	{
-	  if (!pcibios_find_device(PCI_VENDOR_ID_ADAPTEC,
-				  PCI_DEVICE_ID_ADAPTEC_7872,
-				  index, &pci_bus, &pci_device_fn))
-	  {
-	    type = AIC_7872;
-            config.chan_num = number_of_3940s & 0x1;
-            number_of_3940s++;
-	  }
-	  else
-	  {
-            if ((!pcibios_find_device(PCI_VENDOR_ID_ADAPTEC,
-                                     PCI_DEVICE_ID_ADAPTEC_7881,
-                                     index, &pci_bus, &pci_device_fn)) ||
-                (!pcibios_find_device(PCI_VENDOR_ID_ADAPTEC,
-                                     PCI_DEVICE_ID_ADAPTEC_7880,
-                                     index, &pci_bus, &pci_device_fn)))
-	    {
-	      type = AIC_7880;
-	    }
-            else
-            {
-	      if (!pcibios_find_device(PCI_VENDOR_ID_ADAPTEC,
-				      PCI_DEVICE_ID_ADAPTEC_7882,
-				      index, &pci_bus, &pci_device_fn))
-	      {
-	        type = AIC_7882;
+        if (pcibios_find_device(aic7xxx_pci_devices[i].vendor_id,
+                                aic7xxx_pci_devices[i].device_id,
+                                index, &pci_bus, &pci_device_fn))
+        {
+          done = TRUE;
+        }
+        else  /* Found an Adaptec PCI device. */
+        {
+          config.type = aic7xxx_pci_devices[i].card_type;
+          config.chip_type = aic7xxx_pci_devices[i].chip_type;
+          switch (config.type)
+          {
+            case AIC_7872:  /* 3940 */
+            case AIC_7882:  /* 3940-Ultra */
+              config.chan_num = number_of_39xxs & 0x1;  /* Has 2 controllers */
+              number_of_39xxs++;
+              if (number_of_39xxs == 2)
+              {
+                number_of_39xxs = 0;  /* To be consistent with 3985. */
               }
-              else
+              break;
+
+            case AIC_7873:  /* 3985 */
+            case AIC_7883:  /* 3985-Ultra */
+              config.chan_num = number_of_39xxs & 0x3;  /* Has 3 controllers */
+              number_of_39xxs++;
+              if (number_of_39xxs == 3)
               {
-	        type = AIC_NONE;
-	        done = 1;
+                number_of_39xxs = 0;
               }
-            }
+              break;
+
+            default:
+              break;
           }
-	}
-      }
 
-      if (!done)
-      {
-	/*
-	 * Read esundry information from PCI BIOS.
-	 */
-	error = pcibios_read_config_dword(pci_bus, pci_device_fn,
-					  PCI_BASE_ADDRESS_0, &io_port);
-	if (error)
-	{
-	  panic("aic7xxx_detect: error 0x%x reading i/o port.\n", error);
-	}
+	  /*
+	   * Read esundry information from PCI BIOS.
+	   */
+	  error = pcibios_read_config_dword(pci_bus, pci_device_fn,
+					    PCI_BASE_ADDRESS_0, &io_port);
+	  if (error)
+	  {
+	    panic("aic7xxx: (aic7xxx_detect) Error %d reading I/O port.\n",
+                  error);
+	  }
 
-	error = pcibios_read_config_byte(pci_bus, pci_device_fn,
-					 PCI_INTERRUPT_LINE, &irq);
-	if (error)
-	{
-	  panic("aic7xxx_detect: error %d reading irq.\n", error);
-	}
+	  error = pcibios_read_config_byte(pci_bus, pci_device_fn,
+					   PCI_INTERRUPT_LINE, &irq);
+	  if (error)
+	  {
+	    panic("aic7xxx: (aic7xxx_detect) Error %d reading IRQ.\n",
+                   error);
+	  }
 
-	error = pcibios_read_config_byte(pci_bus, pci_device_fn,
-					 DEVREVID, &devrevid);
-	if (error)
-	{
-	  panic("aic7xxx_detect: error %d reading device revision id.\n", error);
-	}
+	  error = pcibios_read_config_byte(pci_bus, pci_device_fn,
+					   DEVREVID, &devrevid);
+	  if (error)
+	  {
+	    panic("aic7xxx: (aic7xxx_detect) Error %d reading device "
+                  "revision ID.\n", error);
+	  }
 
-	if (devrevid < 3)
-	{
-	  printk("aic7xxx_detect: AIC-7870 Rev %c\n", rev_id[devrevid]);
-	}
+	  if (devrevid < 3)
+	  {
+	    printk("aic7xxx: %s Rev %c.\n", board_names[config.type],
+                   rev_id[devrevid]);
+	  }
 
-	error = pcibios_read_config_byte(pci_bus, pci_device_fn,
-					 DEVCONFIG, &devconfig);
-	if (error)
-	{
-	  panic("aic7xxx_detect: error %d reading device configuration.\n", error);
-	}
+	  error = pcibios_read_config_byte(pci_bus, pci_device_fn,
+					   DEVCONFIG, &devconfig);
+	  if (error)
+	  {
+	    panic("aic7xxx: (aic7xxx_detect) Error %d reading device "
+                  "configuration.\n", error);
+	  }
 
-	error = pcibios_read_config_byte(pci_bus, pci_device_fn,
-					 DEVSTATUS, &devstatus);
-	if (error)
-	{
-	  panic("aic7xxx_detect: error %d reading device status.\n", error);
-	}
+	  error = pcibios_read_config_byte(pci_bus, pci_device_fn,
+					   DEVSTATUS, &devstatus);
+	  if (error)
+	  {
+	    panic("aic7xxx: (aic7xxx_detect) Error %d reading device status.\n",
+                  error);
+	  }
 
-	printk("aic7xxx_detect: devconfig 0x%x, devstatus 0x%x\n",
-	       devconfig, devstatus);
+	  printk("aic7xxx: devconfig(0x%x) devstatus(0x%x).\n",
+	         devconfig, devstatus);
 
-	/*
-	 * Make the base I/O register look like EISA and VL-bus.
-	 */
-	base = io_port - 0xC01;
+	  /*
+	   * Make the base I/O register look like EISA and VL-bus.
+	   */
+	  base = io_port - 0xC01;
 
-	/*
-	 * I don't think we need to bother with allowing
-	 * spurious interrupts for the 787x/7850, but what
-	 * the hey.
-	 */
-	aic7xxx_spurious_count = 1;
+	  /*
+	   * I don't think we need to bother with allowing
+	   * spurious interrupts for the 787x/7850, but what
+	   * the hey.
+	   */
+	  aic7xxx_spurious_count = 1;
 
-        config.type = type;
-        config.base = base;
-        config.irq = irq;
-        config.parity = AIC_UNKNOWN;
-        config.low_term = AIC_UNKNOWN;
-        config.high_term = AIC_UNKNOWN;
-        config.busrtime = 0;
-        config.walk_scbs = FALSE;
-        config.ultra_enabled = FALSE;
-	if ((devstatus & RAMPSM) || (devconfig & SCBRAMSEL) ||
-            (type == AIC_7872))
-	{
-          config.walk_scbs = TRUE;
-	}
-	found += aic7xxx_register(template, &config);
+          config.base = base;
+          config.irq = irq;
+          config.parity = AIC_UNKNOWN;
+          config.low_term = AIC_UNKNOWN;
+          config.high_term = AIC_UNKNOWN;
+          config.busrtime = 0;
+          config.walk_scbs = FALSE;
+          config.ultra_enabled = FALSE;
+	  if ((devstatus & RAMPSM) || (devconfig & SCBRAMSEL))
+	  {
+            config.walk_scbs = TRUE;
+	  }
+	  found += aic7xxx_register(template, &config);
 
-	/*
-	 * Disable spurious interrupts.
-	 */
-	aic7xxx_spurious_count = 0;
+	  /*
+	   * Disable spurious interrupts.
+	   */
+	  aic7xxx_spurious_count = 0;
 
-	index++;
+	  index++;
+        }  /* Found an Adaptec PCI device. */
       }
     }
   }
@@ -4462,8 +4433,8 @@
   {
     if (cmd->device->tagged_queue == 0)
     {
-      printk("aic7xxx_buildscb: Enabling tagged queuing for target %d, "
-	     "channel %d\n", cmd->target, cmd->channel);
+      printk("aic7xxx: Enabling tagged queuing for target %d, "
+	     "channel %d.\n", cmd->target, cmd->channel);
       cmd->device->tagged_queue = 1;
       cmd->device->current_tag = 1;  /* enable tagging */
     }
@@ -4482,7 +4453,7 @@
     p->wdtr_pending |= mask;
     scb->control |= SCB_NEEDWDTR;
 #if 0
-    printk("Sending WDTR request to target %d.\n", cmd->target);
+    printk("aic7xxx: Sending WDTR request to target %d.\n", cmd->target);
 #endif
   }
   else
@@ -4492,13 +4463,14 @@
       p->sdtr_pending |= mask;
       scb->control |= SCB_NEEDSDTR;
 #if 0
-      printk("Sending SDTR request to target %d.\n", cmd->target);
+      printk("aic7xxx: Sending SDTR request to target %d.\n", cmd->target);
 #endif
     }
   }
 
 #if 0
-  printk("aic7xxx_queue: target %d, cmd 0x%x (size %u), wdtr 0x%x, mask 0x%x\n",
+  printk("aic7xxx: (build_scb) Target %d, cmd(0x%x) size(%u) wdtr(0x%x) "
+         "mask(0x%x).\n",
 	 cmd->target, cmd->cmnd[0], cmd->cmd_len, p->needwdtr, mask);
 #endif
   scb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
@@ -4522,7 +4494,7 @@
   if (cmd->use_sg)
   {
 #if 0
-    debug("aic7xxx_buildscb: SG used, %d segments, length %u\n",
+    debug("aic7xxx: (build_scb) SG used, %d segments, length(%u).\n",
            cmd->use_sg, length);
 #endif
     scb->SG_segment_count = cmd->use_sg;
@@ -4537,7 +4509,7 @@
   else
   {
 #if 0
-  debug("aic7xxx_buildscb: Creating scatterlist, addr=0x%lx, length=%d.\n",
+  debug("aic7xxx: (build_scb) Creating scatterlist, addr(0x%lx) length(%d).\n",
 	(unsigned long) cmd->request_buffer, cmd->request_bufflen);
 #endif
     if (cmd->request_bufflen == 0)
@@ -4602,7 +4574,7 @@
   }
 
 #if 0
-  debug("aic7xxx_queue: cmd 0x%x (size %u), target %d, channel %d, lun %d\n",
+  debug("aic7xxx_queue: cmd(0x%x) size(%u), target %d, channel %d, lun %d.\n",
 	cmd->cmnd[0], cmd->cmd_len, cmd->target, cmd->channel,
 	cmd->lun & 0x07);
 #endif
@@ -4645,7 +4617,7 @@
   {
     if (p->numscb >= p->maxscb)
     {
-      panic("aic7xxx_queue: couldn't find a free scb\n");
+      panic("aic7xxx: (aic7xxx_queue) Couldn't find a free SCB.\n");
     }
     else
     {
@@ -4688,9 +4660,10 @@
 #if 0
   if (scb != &p->scb_array[scb->position])
   {
-    printk("aic7xxx_queue: address of scb by position does not match scb address\n");
+    printk("aic7xxx: (queue) Address of SCB by position does not match SCB "
+           "address.\n");
   }
-  printk("aic7xxx_queue: SCB pos=%d, cmdptr=0x%x, state=%d, freescb=0x%x\n",
+  printk("aic7xxx: (queue) SCB pos(%d) cmdptr(0x%x) state(%d) freescb(0x%x)\n",
 	 scb->position, (unsigned int) scb->cmd,
 	 scb->state, (unsigned int) p->free_scb);
 #endif
@@ -4719,13 +4692,12 @@
   cmd->scsi_done = fn;
   aic7xxx_error(cmd) = DID_OK;
   aic7xxx_status(cmd) = 0;
-  scb->timer_status = 0x0;
   cmd->result = 0;
   memset(&cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
 
   UNPAUSE_SEQUENCER(p);
 #if 0
-  printk("aic7xxx_queue: After - cmd = 0x%lx, scb->cmd = 0x%lx, pos = %d\n",
+  printk("aic7xxx: (queue) After - cmd(0x%lx) scb->cmd(0x%lx) pos(%d).\n",
          (long) cmd, (long) scb->cmd, scb->position);
 #endif;
   restore_flags(flags);
@@ -4740,13 +4712,16 @@
  *   Abort an scb.  If the scb has not previously been aborted, then
  *   we attempt to send a BUS_DEVICE_RESET message to the target.  If
  *   the scb has previously been unsuccessfully aborted, then we will
- *   reset the channel and have all devices renegotiate.
+ *   reset the channel and have all devices renegotiate.  Returns an
+ *   enumerated type that indicates the status of the operation.
  *-F*************************************************************************/
-static void
-aic7xxx_abort_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
+static aha_abort_reset_type
+aic7xxx_abort_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb,
+                  unsigned char errcode)
 {
   int base = p->base;
   int found = 0;
+  aha_abort_reset_type scb_status = ABORT_RESET_SUCCESS;
   char channel = scb->target_channel_lun & SELBUSB ? 'B': 'A';
 
   /*
@@ -4755,6 +4730,10 @@
    */
   PAUSE_SEQUENCER(p);
 
+#ifdef AIC7XXX_DEBUG_ABORT 
+  printk ("aic7xxx: (abort_scb) scb %d, scb_aborted 0x%x\n",
+          scb->position, (scb->state & SCB_ABORTED));
+#endif
   /*
    * First, determine if we want to do a bus reset or simply a bus device
    * reset.  If this is the first time that a transaction has timed out,
@@ -4796,6 +4775,9 @@
     outb(scb->position, SCBPTR(base));
     if (inb(SCBARRAY(base)) & SCB_DIS)
     {
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (abort_scb) scb %d is disconnected.\n", scb->position);
+#endif
       scb->state |= (SCB_DEVICE_RESET | SCB_ABORTED);
       scb->SG_segment_count = 0;
       memset(scb->SG_list_pointer, 0, sizeof(scb->SG_list_pointer));
@@ -4809,8 +4791,10 @@
                    :"S" (scb), "c" (SCB_DOWNLOAD_SIZE), "d" (SCBARRAY(base))
                    :"si", "cx", "dx");
       outb(0, SCBCNT(base));
+      aic7xxx_error(scb->cmd) = errcode;
+      scb_status = ABORT_RESET_PENDING;
       aic7xxx_add_waiting_scb(base, scb, LIST_SECOND);
-      aic7xxx_scb_tsleep(p, scb, 2 * HZ);  /* unpauses the sequencer */
+      UNPAUSE_SEQUENCER(p);
     }
     else
     {
@@ -4822,6 +4806,10 @@
         unsigned char flags = inb(HA_FLAGS(base));
         if (flags & ACTIVE_MSG)
         {
+#ifdef AIC7XXX_DEBUG_ABORT
+          printk ("aic7xxx: (abort_scb) scb is active, needs DMA, "
+                  "ha_flags active.\n");
+#endif
           /*
            * If we're in a message phase, tacking on another message
            * may confuse the target totally. The bus is probably wedged,
@@ -4832,6 +4820,10 @@
         }
         else
         {
+#ifdef AIC7XXX_DEBUG_ABORT
+          printk ("aic7xxx: (abort_scb) scb is active, needs DMA, "
+                  "ha_flags inactive.\n");
+#endif
           /*
            * Load the message buffer and assert attention.
            */
@@ -4849,11 +4841,16 @@
              */
             ;
           }
-          aic7xxx_scb_tsleep(p, active_scbp, 2 * HZ);
+          aic7xxx_error(scb->cmd) = errcode;
+          scb_status = ABORT_RESET_PENDING;
+          UNPAUSE_SEQUENCER(p);
         }
       }
       else
       {
+#ifdef AIC7XXX_DEBUG_ABORT
+          printk ("aic7xxx: (abort_scb) no active command.\n");
+#endif
         /*
          * No active command to single out, so reset
          * the bus for the timed out target.
@@ -4862,21 +4859,24 @@
       }
     }
   }
+  return (scb_status);
 }
 
 /*+F*************************************************************************
  * Function:
- *   aic7xxx_abort
+ *   aic7xxx_abort_reset
  *
  * Description:
- *   Abort the current SCSI command(s).
+ *   Abort or reset the current SCSI command(s).  Returns an enumerated
+ *   type that indicates the status of the operation.
  *-F*************************************************************************/
-int
-aic7xxx_abort(Scsi_Cmnd *cmd)
+static aha_abort_reset_type
+aic7xxx_abort_reset(Scsi_Cmnd *cmd, unsigned char errcode)
 {
   struct aic7xxx_scb  *scb;
   struct aic7xxx_host *p;
   long flags;
+  aha_abort_reset_type scb_status = ABORT_RESET_SUCCESS;
 
   p = (struct aic7xxx_host *) cmd->host->hostdata;
   scb = &(p->scb_array[aic7xxx_position(cmd)]);
@@ -4884,6 +4884,10 @@
   save_flags(flags);
   cli();
 
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (abort_reset) scb state 0x%x\n", scb->state);
+#endif
+
   if (scb->state & SCB_ACTIVE)
   {
     if (scb->state & SCB_IMMED)
@@ -4892,6 +4896,7 @@
        * Don't know how set the number of retries to 0.
        */
       /* cmd->retries = 0; */
+      aic7xxx_error(cmd) = errcode;
       aic7xxx_done (p, scb);
     }
     else
@@ -4899,11 +4904,65 @@
       /*
        * Abort the operation.
        */
-      aic7xxx_abort_scb(p, scb);
+      scb_status = aic7xxx_abort_scb(p, scb, errcode);
     }
   }
+  else
+  {
+    /*
+     * The scb is not active and must have completed after the timeout
+     * check in scsi.c and before we check the scb state above.  For
+     * this case we return SCSI_ABORT_NOT_RUNNING (if abort was called)
+     * or SCSI_RESET_SUCCESS (if reset was called).
+     */
+#ifdef AIC7XXX_DEBUG_ABORT
+    printk ("aic7xxx: (abort_reset) called with no active scb, errcode 0x%x\n",
+            errcode);
+#endif
+    scb_status = ABORT_RESET_INACTIVE;
+    /*
+     * According to the comments in scsi.h and Michael Neuffer, if we do not
+     * have an active command for abort or reset, we should not call the
+     * command done function.  Unfortunately, this hangs the system for me
+     * unless we *do* call the done function.
+     *
+     * XXX - Revisit this sometime!
+     */
+    cmd->result = errcode << 16;
+    cmd->scsi_done(cmd);
+  }
   restore_flags(flags);
-  return (0);
+  return (scb_status);
+}
+
+
+/*+F*************************************************************************
+ * Function:
+ *   aic7xxx_abort
+ *
+ * Description:
+ *   Abort the current SCSI command(s).
+ *-F*************************************************************************/
+int
+aic7xxx_abort(Scsi_Cmnd *cmd)
+{
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (abort) target/channel %d/%d\n", cmd->target, cmd->channel);
+#endif
+
+  switch (aic7xxx_abort_reset(cmd, DID_ABORT))
+  {
+    case ABORT_RESET_INACTIVE:
+      return (SCSI_ABORT_NOT_RUNNING);
+      break;
+    case ABORT_RESET_PENDING:
+      return (SCSI_ABORT_PENDING);
+      break;
+    case ABORT_RESET_SUCCESS:
+    default:
+      return (SCSI_ABORT_SUCCESS);
+      break;
+  }
 }
 
 /*+F*************************************************************************
@@ -4919,7 +4978,21 @@
 int
 aic7xxx_reset(Scsi_Cmnd *cmd)
 {
-  return (aic7xxx_abort(cmd));
+#ifdef AIC7XXX_DEBUG_ABORT
+  printk ("aic7xxx: (reset) target/channel %d/%d\n", cmd->target, cmd->channel);
+#endif
+
+  switch (aic7xxx_abort_reset(cmd, DID_RESET))
+  {
+    case ABORT_RESET_PENDING:
+      return (SCSI_RESET_PENDING);
+      break;
+    case ABORT_RESET_INACTIVE:
+    case ABORT_RESET_SUCCESS:
+    default:
+      return (SCSI_RESET_SUCCESS);
+      break;
+  }
 }
 
 /*+F*************************************************************************

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this