>With a 4.3-BETA kernel from today (and also with one from a month or
>two ago) I can easily induce a panic by trying to copy an audio CD
>from an ATAPI drive to a SCSI disk on an ahc controller using this
>command:

The panic looks familiar, but I can't quite recall what the bug was.
Can you try the attached patch and see if the problem persists?
This will bring you up to date with what is in -current.

--
Justin

Index: ahc_eisa.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/ahc_eisa.c,v
retrieving revision 1.15.2.3
diff -u -r1.15.2.3 ahc_eisa.c
--- ahc_eisa.c  2001/01/27 20:56:22     1.15.2.3
+++ ahc_eisa.c  2001/03/11 04:26:23
@@ -180,7 +180,7 @@
 }
 
 int
-aic7770_map_int(struct ahc_softc *ahc)
+aic7770_map_int(struct ahc_softc *ahc, int irq)
 {
        int zero;
 
Index: ahc_pci.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/ahc_pci.c,v
retrieving revision 1.29.2.5
diff -u -r1.29.2.5 ahc_pci.c
--- ahc_pci.c   2001/01/27 20:56:22     1.29.2.5
+++ ahc_pci.c   2001/03/08 22:52:10
@@ -213,3 +213,38 @@
        ahc->platform_data->irq_res_type = SYS_RES_IRQ;
        return (0);
 }
+
+void
+ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state)
+{
+       uint32_t cap;
+       u_int cap_offset;
+
+       /*
+        * Traverse the capability list looking for
+        * the power management capability.
+        */
+       cap = 0;
+       cap_offset = ahc_pci_read_config(ahc->dev_softc,
+                                        PCIR_CAP_PTR, /*bytes*/1);
+       while (cap_offset != 0) {
+
+               cap = ahc_pci_read_config(ahc->dev_softc,
+                                         cap_offset, /*bytes*/4);
+               if ((cap & 0xFF) == 1
+                && ((cap >> 16) & 0x3) > 0) {
+                       uint32_t pm_control;
+
+                       pm_control = ahc_pci_read_config(ahc->dev_softc,
+                                                        cap_offset + 4,
+                                                        /*bytes*/4);
+                       pm_control &= ~0x3;
+                       pm_control |= new_state;
+                       ahc_pci_write_config(ahc->dev_softc,
+                                            cap_offset + 4,
+                                            pm_control, /*bytes*/2);
+                       break;
+               }
+               cap_offset = (cap >> 8) & 0xFF;
+       }
+}
Index: aic7770.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7770.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 aic7770.c
--- aic7770.c   2001/01/27 20:56:23     1.1.2.2
+++ aic7770.c   2001/03/11 04:27:13
@@ -29,7 +29,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7770.c#4 $
+ * $Id: //depot/src/aic7xxx/aic7770.c#8 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1.2.2 2001/01/27 20:56:23 gibbs Exp $
  */
@@ -101,6 +101,8 @@
        struct  ahc_probe_config probe_config;
        int     error;
        u_int   hostconf;
+       u_int   irq;
+       u_int   intdef;
 
        ahc_init_probe_config(&probe_config);
        error = entry->setup(ahc->dev_softc, &probe_config);
@@ -114,11 +116,30 @@
        probe_config.description = entry->name;
        error = ahc_softc_init(ahc, &probe_config);
 
-       error = aic7770_map_int(ahc);
+       error = ahc_reset(ahc);
        if (error != 0)
                return (error);
 
-       error = ahc_reset(ahc);
+       /* Make sure we have a valid interrupt vector */
+       intdef = ahc_inb(ahc, INTDEF);
+       irq = intdef & VECTOR;
+       switch (irq) {
+       case 9:
+       case 10:
+       case 11:
+       case 12:
+       case 14:
+       case 15:
+               break;
+       default:
+               printf("aic7770_config: illegal irq setting %d\n", intdef);
+               return (ENXIO);
+       }
+
+       if ((intdef & EDGE_TRIG) != 0)
+               ahc->flags |= AHC_EDGE_INTERRUPT;
+
+       error = aic7770_map_int(ahc, irq);
        if (error != 0)
                return (error);
 
@@ -135,7 +156,7 @@
 
                /* Get the primary channel information */
                if ((biosctrl & CHANNEL_B_PRIMARY) != 0)
-                       ahc->flags |= AHC_CHANNEL_B_PRIMARY;
+                       ahc->flags |= 1;
 
                if ((biosctrl & BIOSMODE) == BIOSDISABLED) {
                        ahc->flags |= AHC_USEDEFAULTS;
Index: aic7xxx.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx.c,v
retrieving revision 1.41.2.16
diff -u -r1.41.2.16 aic7xxx.c
--- aic7xxx.c   2001/02/21 20:51:22     1.41.2.16
+++ aic7xxx.c   2001/03/11 04:53:43
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7xxx.c#30 $
+ * $Id: //depot/src/aic7xxx/aic7xxx.c#34 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.41.2.16 2001/02/21 20:51:22 gibbs Exp $
  */
@@ -66,9 +66,17 @@
        "aic7892",
        "aic7899"
 };
-const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names);
+static const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names);
 
-struct hard_error_entry hard_error[] = {
+/*
+ * Hardware error codes.
+ */
+struct ahc_hard_error_entry {
+        uint8_t errno;
+       char *errmesg;
+};
+
+static struct ahc_hard_error_entry ahc_hard_errors[] = {
        { ILLHADDR,     "Illegal Host Access" },
        { ILLSADDR,     "Illegal Sequencer Address referrenced" },
        { ILLOPCODE,    "Illegal Opcode in sequencer program" },
@@ -78,9 +86,9 @@
        { PCIERRSTAT,   "PCI Error detected" },
        { CIOPARERR,    "CIOBUS Parity Error" },
 };
-const u_int num_errors = NUM_ELEMENTS(hard_error);
+static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
 
-struct phase_table_entry phase_table[] =
+static struct ahc_phase_table_entry ahc_phase_table[] =
 {
        { P_DATAOUT,    MSG_NOOP,               "in Data-out phase"     },
        { P_DATAIN,     MSG_INITIATOR_DET_ERR,  "in Data-in phase"      },
@@ -98,14 +106,14 @@
  * In most cases we only wish to itterate over real phases, so
  * exclude the last element from the count.
  */
-const u_int num_phases = NUM_ELEMENTS(phase_table) - 1;
+static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
 
 /*
  * Valid SCSIRATE values.  (p. 3-17)
  * Provides a mapping of tranfer periods in ns to the proper value to
  * stick in the scsixfer reg.
  */
-struct ahc_syncrate ahc_syncrates[] =
+static struct ahc_syncrate ahc_syncrates[] =
 {
       /* ultra2    fast/ultra  period     rate */
        { 0x42,      0x000,      9,      "80.0" },
@@ -226,10 +234,11 @@
  * Restart the sequencer program from address zero
  */
 void
-restart_sequencer(struct ahc_softc *ahc)
+ahc_restart(struct ahc_softc *ahc)
 {
+
+       ahc_pause(ahc);
 
-       pause_sequencer(ahc);
        ahc_outb(ahc, SCSISIGO, 0);             /* De-assert BSY */
        ahc_outb(ahc, MSG_OUT, MSG_NOOP);       /* No message to send */
        ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
@@ -252,11 +261,21 @@
                ahc_outb(ahc, CCSGCTL, 0);
                ahc_outb(ahc, CCSCBCTL, 0);
        }
+       /*
+        * If we were in the process of DMA'ing SCB data into
+        * an SCB, replace that SCB on the free list.  This prevents
+        * an SCB leak.
+        */
+       if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
+               ahc_add_curscb_to_free_list(ahc);
+               ahc_outb(ahc, SEQ_FLAGS2,
+                        ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
+       }
        ahc_outb(ahc, MWI_RESIDUAL, 0);
        ahc_outb(ahc, SEQCTL, FASTMODE);
        ahc_outb(ahc, SEQADDR0, 0);
        ahc_outb(ahc, SEQADDR1, 0);
-       unpause_sequencer(ahc);
+       ahc_unpause(ahc);
 }
 
 /************************* Input/Output Queues ********************************/
@@ -337,14 +356,14 @@
         * We upset the sequencer :-(
         * Lookup the error message
         */
-       int i, error, num_errors;
+       int i;
+       int error;
 
        error = ahc_inb(ahc, ERROR);
-       num_errors =  sizeof(hard_error)/sizeof(hard_error[0]);
        for (i = 0; error != 1 && i < num_errors; i++)
                error >>= 1;
        printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
-              ahc_name(ahc), hard_error[i].errmesg,
+              ahc_name(ahc), ahc_hard_errors[i].errmesg,
               ahc_inb(ahc, SEQADDR0) |
               (ahc_inb(ahc, SEQADDR1) << 8));
 
@@ -630,7 +649,7 @@
                       "Lastphase = 0x%x, Curphase = 0x%x\n",
                       ahc_name(ahc), devinfo.channel, devinfo.target,
                       lastphase, ahc_inb(ahc, SCSISIGI));
-               restart_sequencer(ahc);
+               ahc_restart(ahc);
                return;
        }
        case HOST_MSG_LOOP:
@@ -660,7 +679,7 @@
                                 * we got here.  Just punt the message.
                                 */
                                ahc_clear_intstat(ahc);
-                               restart_sequencer(ahc);
+                               ahc_restart(ahc);
                                return;
                        }
 
@@ -746,13 +765,13 @@
 
                scb = ahc_lookup_scb(ahc, scbindex);
                for (i = 0; i < num_phases; i++) {
-                       if (lastphase == phase_table[i].phase)
+                       if (lastphase == ahc_phase_table[i].phase)
                                break;
                }
                ahc_print_path(ahc, scb);
                printf("data overrun detected %s."
                       "  Tag == 0x%x.\n",
-                      phase_table[i].phasemsg,
+                      ahc_phase_table[i].phasemsg,
                       scb->hscb->tag);
                ahc_print_path(ahc, scb);
                printf("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
@@ -855,7 +874,7 @@
         *  a SEQINT, so we should restart it when
         *  we're done.
         */
-       unpause_sequencer(ahc);
+       ahc_unpause(ahc);
 }
 
 void
@@ -894,7 +913,7 @@
                if (status == 0) {
                        printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
                        ahc_outb(ahc, CLRINT, CLRSCSIINT);
-                       unpause_sequencer(ahc);
+                       ahc_unpause(ahc);
                        return;
                }
        }
@@ -972,10 +991,10 @@
                        errorphase = lastphase;
 
                for (i = 0; i < num_phases; i++) {
-                       if (errorphase == phase_table[i].phase)
+                       if (errorphase == ahc_phase_table[i].phase)
                                break;
                }
-               mesg_out = phase_table[i].mesg_out;
+               mesg_out = ahc_phase_table[i].mesg_out;
                if (scb != NULL)
                        ahc_print_path(ahc, scb);
                else
@@ -984,7 +1003,7 @@
                scsirate = ahc_inb(ahc, SCSIRATE);
                printf("parity error detected %s. "
                       "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
-                      phase_table[i].phasemsg,
+                      ahc_phase_table[i].phasemsg,
                       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8),
                       scsirate);
 
@@ -1015,7 +1034,7 @@
                                ahc_outb(ahc, MSG_OUT, mesg_out);
                }
                ahc_outb(ahc, CLRINT, CLRSCSIINT);
-               unpause_sequencer(ahc);
+               ahc_unpause(ahc);
        } else if ((status & BUSFREE) != 0
                && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
                u_int lastphase;
@@ -1171,17 +1190,18 @@
                                printf("%s: ", ahc_name(ahc));
                        }
                        for (i = 0; i < num_phases; i++) {
-                               if (lastphase == phase_table[i].phase)
+                               if (lastphase == ahc_phase_table[i].phase)
                                        break;
                        }
                        printf("Unexpected busfree %s\n"
                               "SEQADDR == 0x%x\n",
-                              phase_table[i].phasemsg, ahc_inb(ahc, SEQADDR0)
+                              ahc_phase_table[i].phasemsg,
+                              ahc_inb(ahc, SEQADDR0)
                                | (ahc_inb(ahc, SEQADDR1) << 8));
                }
                ahc_clear_msg_state(ahc);
                ahc_outb(ahc, CLRINT, CLRSCSIINT);
-               restart_sequencer(ahc);
+               ahc_restart(ahc);
        } else if ((status & SELTO) != 0) {
                u_int scbptr;
 
@@ -1218,7 +1238,7 @@
                        ahc_freeze_devq(ahc, scb);
                }
                ahc_outb(ahc, CLRINT, CLRSCSIINT);
-               restart_sequencer(ahc);
+               ahc_restart(ahc);
        } else {
                printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
                       ahc_name(ahc), status);
@@ -1287,7 +1307,7 @@
                ahc_outb(ahc, HCNTRL, ahc->unpause);
                do {
                        ahc_delay(200);
-               } while (!sequencer_paused(ahc));
+               } while (!ahc_is_paused(ahc));
        }
        if (stepping) {
                ahc_outb(ahc, SIMODE0, simode0);
@@ -1450,7 +1470,8 @@
                        /* Can't do DT on an SE bus */
                        *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
                }
-       } else if ((ahc->features & AHC_ULTRA) != 0) {
+       } else if ((ahc->features & AHC_ULTRA) != 0
+               && (ahc->flags & AHC_ULTRA_DISABLED) == 0) {
                maxsync = AHC_SYNCRATE_ULTRA;
        } else {
                maxsync = AHC_SYNCRATE_FAST;
@@ -1667,7 +1688,7 @@
        if (ahc->targ_msg_req != targ_msg_req_orig) {
                /* Update the message request bit for this target */
                if (!paused)
-                       pause_sequencer(ahc);
+                       ahc_pause(ahc);
 
                ahc_outb(ahc, TARGET_MSG_REQUEST,
                         ahc->targ_msg_req & 0xFF);
@@ -1675,7 +1696,7 @@
                         (ahc->targ_msg_req >> 8) & 0xFF);
 
                if (!paused)
-                       unpause_sequencer(ahc);
+                       ahc_unpause(ahc);
        }
 }
 
@@ -1981,6 +2002,23 @@
                            role);
 }
 
+struct ahc_phase_table_entry*
+ahc_lookup_phase_entry(int phase)
+{
+       struct ahc_phase_table_entry *entry;
+       int i;
+
+       /*
+        * num_phases doesn't include the default entry which
+        * will be returned if the phase doesn't match.
+        */
+       for (i = 0, entry = ahc_phase_table; i < num_phases; i++) {
+               if (phase == entry->phase)
+                       break;
+       }
+       return (entry);
+}
+
 void
 ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
                    u_int lun, char channel, role_t role)
@@ -2254,7 +2292,7 @@
        ahc->msgout_len = 0;
        ahc->msgin_index = 0;
        ahc->msg_type = MSG_TYPE_NONE;
-       if ((ahc_inb(ahc, SCSISIGI) & ATNI) == 0) {
+       if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
                /*
                 * The target didn't care to respond to our
                 * message request, so clear ATN.
@@ -2875,7 +2913,7 @@
                                       "offset %x, options %x\n",
                                       ahc_name(ahc), devinfo->channel,
                                       devinfo->target, devinfo->lun,
-                                      ahc->msgin_buf[3], saved_width,
+                                      saved_width, ahc->msgin_buf[3],
                                       saved_offset, saved_ppr_options,
                                       bus_width, period, offset, ppr_options);
                        }
@@ -2902,7 +2940,7 @@
                                    CAM_BDR_SENT,
                                    "Bus Device Reset Received",
                                    /*verbose_level*/0);
-               restart_sequencer(ahc);
+               ahc_restart(ahc);
                done = MSGLOOP_TERMINATED;
                break;
        case MSG_ABORT_TAG:
@@ -3356,29 +3394,37 @@
 {
        struct ahc_softc *list_ahc;
 
-#ifdef AHC_SUPPORT_PCI
+#if AHC_PCI_CONFIG > 0
        /*
         * Second Function PCI devices need to inherit some
-        * settings from function 0.  We assume that function 0
-        * will always be found prior to function 1.
+        * settings from function 0.
         */
        if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
-        && ahc_get_pci_function(ahc->dev_softc) == 1) {
+        && (ahc->features & AHC_MULTI_FUNC) != 0) {
                TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
                        ahc_dev_softc_t list_pci;
                        ahc_dev_softc_t pci;
 
                        list_pci = list_ahc->dev_softc;
                        pci = ahc->dev_softc;
-                       if (ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)
-                        && ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
-                        && ahc_get_pci_function(list_pci) == 0) {
-                               ahc->flags &= ~AHC_BIOS_ENABLED; 
-                               ahc->flags |=
-                                   list_ahc->flags & AHC_BIOS_ENABLED;
-                               ahc->flags &= ~AHC_CHANNEL_B_PRIMARY; 
-                               ahc->flags |=
-                                   list_ahc->flags & AHC_CHANNEL_B_PRIMARY;
+                       if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
+                        && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
+                               struct ahc_softc *master;
+                               struct ahc_softc *slave;
+
+                               if (ahc_get_pci_function(list_pci) == 0) {
+                                       master = list_ahc;
+                                       slave = ahc;
+                               } else {
+                                       master = ahc;
+                                       slave = list_ahc;
+                               }
+                               slave->flags &= ~AHC_BIOS_ENABLED; 
+                               slave->flags |=
+                                   master->flags & AHC_BIOS_ENABLED;
+                               slave->flags &= ~AHC_PRIMARY_CHANNEL; 
+                               slave->flags |=
+                                   master->flags & AHC_PRIMARY_CHANNEL;
                                break;
                        }
                }
@@ -3519,7 +3565,7 @@
         * It contains settings that affect termination and we don't want
         * to disturb the integrity of the bus.
         */
-       pause_sequencer(ahc);
+       ahc_pause(ahc);
        sxfrctl1_b = 0;
        if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
                u_int sblkctl;
@@ -3957,7 +4003,7 @@
                len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
                              "B SCSI Id=%d, primary %c, ",
                              ahc->our_id, ahc->our_id_b,
-                             ahc->flags & AHC_CHANNEL_B_PRIMARY ? 'B': 'A');
+                             (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
        else {
                const char *type;
 
@@ -4134,6 +4180,7 @@
        }
 
        ahc_outb(ahc, SEQ_FLAGS, 0);
+       ahc_outb(ahc, SEQ_FLAGS2, 0);
 
        if (ahc->scb_data->maxhscbs < AHC_SCB_MAX) {
                ahc->flags |= AHC_PAGESCBS;
@@ -4218,6 +4265,8 @@
                        ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
                                      | ahc_inb(ahc, ULTRA_ENB);
        }
+       if ((ahc->flags & AHC_ULTRA_DISABLED) != 0)
+               ultraenb = 0;
 
        if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
                max_targ = 7;
@@ -4274,6 +4323,9 @@
                                        offset = MAX_OFFSET_ULTRA2;
                                } else
                                        offset = ahc_inb(ahc, TARG_OFFSET + i);
+                               if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
+                                       /* Set to the lowest sync rate, 5MHz */
+                                       scsirate |= 0x1c;
                                maxsync = AHC_SYNCRATE_ULTRA2;
                                if ((ahc->features & AHC_DT) != 0)
                                        maxsync = AHC_SYNCRATE_DT;
@@ -4302,6 +4354,8 @@
                                if (tinfo->user.period != 0)
                                        tinfo->user.offset = ~0;
                        }
+                       if (tinfo->user.period == 0)
+                               tinfo->user.offset = 0;
                        if ((scsirate & WIDEXFER) != 0
                         && (ahc->features & AHC_WIDE) != 0)
                                tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
@@ -4438,12 +4492,12 @@
                 * never settle, so don't complain if we
                 * fail here.
                 */
-               pause_sequencer(ahc);
+               ahc_pause(ahc);
                for (wait = 5000;
                     (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
                     wait--)
                        ahc_delay(100);
-               unpause_sequencer(ahc);
+               ahc_unpause(ahc);
        }
        return (0);
 }
@@ -4466,7 +4520,7 @@
        intstat = 0;
        do {
                ahc_intr(ahc);
-               pause_sequencer(ahc);
+               ahc_pause(ahc);
                ahc_clear_critical_section(ahc);
                if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)
                        break;
@@ -5397,7 +5451,7 @@
                            CAM_TARGET_WILDCARD,
                            CAM_LUN_WILDCARD,
                            channel, ROLE_UNKNOWN);
-       pause_sequencer(ahc);
+       ahc_pause(ahc);
 
        /* Make sure the sequencer is in a safe location. */
        ahc_clear_critical_section(ahc);
@@ -5512,9 +5566,9 @@
        }
 
        if (restart_needed)
-               restart_sequencer(ahc);
+               ahc_restart(ahc);
        else
-               unpause_sequencer(ahc);
+               ahc_unpause(ahc);
        return found;
 }
 
@@ -5813,7 +5867,7 @@
                memcpy(ahc->critical_sections, cs_table, cs_count);
        }
        ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
-       restart_sequencer(ahc);
+       ahc_restart(ahc);
 
        if (bootverbose)
                printf(" %d instructions downloaded\n", downloaded);
@@ -6215,7 +6269,7 @@
                ahc->flags |= AHC_TARGETROLE;
                if ((ahc->features & AHC_MULTIROLE) == 0)
                        ahc->flags &= ~AHC_INITIATORROLE;
-               pause_sequencer(ahc);
+               ahc_pause(ahc);
                ahc_loadseq(ahc);
                ahc_unlock(ahc, &s);
        }
@@ -6284,7 +6338,7 @@
                SLIST_INIT(&lstate->accept_tios);
                SLIST_INIT(&lstate->immed_notifies);
                ahc_lock(ahc, &s);
-               pause_sequencer(ahc);
+               ahc_pause(ahc);
                if (target != CAM_TARGET_WILDCARD) {
                        tstate->enabled_luns[lun] = lstate;
                        ahc->enabled_luns++;
@@ -6348,7 +6402,7 @@
                        scsiseq |= ENSELI;
                        ahc_outb(ahc, SCSISEQ, scsiseq);
                }
-               unpause_sequencer(ahc);
+               ahc_unpause(ahc);
                ahc_unlock(ahc, &s);
                ccb->ccb_h.status = CAM_REQ_CMP;
                xpt_print_path(ccb->ccb_h.path);
@@ -6398,7 +6452,7 @@
                xpt_free_path(lstate->path);
                free(lstate, M_DEVBUF);
 
-               pause_sequencer(ahc);
+               ahc_pause(ahc);
                /* Can we clean up the target too? */
                if (target != CAM_TARGET_WILDCARD) {
                        tstate->enabled_luns[lun] = NULL;
@@ -6451,11 +6505,11 @@
                                printf("Configuring Initiator Mode\n");
                                ahc->flags &= ~AHC_TARGETROLE;
                                ahc->flags |= AHC_INITIATORROLE;
-                               pause_sequencer(ahc);
+                               ahc_pause(ahc);
                                ahc_loadseq(ahc);
                        }
                }
-               unpause_sequencer(ahc);
+               ahc_unpause(ahc);
                ahc_unlock(ahc, &s);
        }
 }
@@ -6537,11 +6591,11 @@
                                ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
                        } else {
                                if (!paused)
-                                       pause_sequencer(ahc);   
+                                       ahc_pause(ahc); 
                                ahc_outb(ahc, KERNEL_TQINPOS,
                                         ahc->tqinfifonext & HOST_TQINPOS);
                                if (!paused)
-                                       unpause_sequencer(ahc);
+                                       ahc_unpause(ahc);
                        }
                }
        }
Index: aic7xxx.h
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx.h,v
retrieving revision 1.16.2.9
diff -u -r1.16.2.9 aic7xxx.h
--- aic7xxx.h   2001/02/10 18:11:35     1.16.2.9
+++ aic7xxx.h   2001/03/11 04:54:19
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7xxx.h#18 $
+ * $Id: //depot/src/aic7xxx/aic7xxx.h#22 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.16.2.9 2001/02/10 18:11:35 gibbs Exp $
  */
@@ -286,50 +286,56 @@
  * chip/controller's configuration.
  */
 typedef enum {
-       AHC_FNONE               = 0x000,
-       AHC_PAGESCBS            = 0x001,/* Enable SCB paging */
-       AHC_CHANNEL_B_PRIMARY   = 0x002,/*
-                                        * On twin channel adapters, probe
-                                        * channel B first since it is the
-                                        * primary bus.
+       AHC_FNONE             = 0x000,
+       AHC_PRIMARY_CHANNEL   = 0x003,/*
+                                        * The channel that should
+                                        * be probed first.
                                         */
-       AHC_USEDEFAULTS         = 0x004,/*
+       AHC_USEDEFAULTS       = 0x004,/*
                                         * For cards without an seeprom
                                         * or a BIOS to initialize the chip's
                                         * SRAM, we use the default target
                                         * settings.
                                         */
-       AHC_SEQUENCER_DEBUG     = 0x008,
-       AHC_SHARED_SRAM         = 0x010,
-       AHC_LARGE_SEEPROM       = 0x020,/* Uses C56_66 not C46 */
-       AHC_RESET_BUS_A         = 0x040,
-       AHC_RESET_BUS_B         = 0x080,
-       AHC_EXTENDED_TRANS_A    = 0x100,
-       AHC_EXTENDED_TRANS_B    = 0x200,
-       AHC_TERM_ENB_A          = 0x400,
-       AHC_TERM_ENB_B          = 0x800,
-       AHC_INITIATORROLE       = 0x1000,/*
+       AHC_SEQUENCER_DEBUG   = 0x008,
+       AHC_SHARED_SRAM       = 0x010,
+       AHC_LARGE_SEEPROM     = 0x020,/* Uses C56_66 not C46 */
+       AHC_RESET_BUS_A       = 0x040,
+       AHC_RESET_BUS_B       = 0x080,
+       AHC_EXTENDED_TRANS_A  = 0x100,
+       AHC_EXTENDED_TRANS_B  = 0x200,
+       AHC_TERM_ENB_A        = 0x400,
+       AHC_TERM_ENB_B        = 0x800,
+       AHC_INITIATORROLE     = 0x1000,/*
                                          * Allow initiator operations on
                                          * this controller.
                                          */
-       AHC_TARGETROLE          = 0x2000,/*
+       AHC_TARGETROLE        = 0x2000,/*
                                          * Allow target operations on this
                                          * controller.
                                          */
-       AHC_NEWEEPROM_FMT       = 0x4000,
-       AHC_RESOURCE_SHORTAGE   = 0x8000,
-       AHC_TQINFIFO_BLOCKED    = 0x10000,/* Blocked waiting for ATIOs */
-       AHC_INT50_SPEEDFLEX     = 0x20000,/*
+       AHC_NEWEEPROM_FMT     = 0x4000,
+       AHC_RESOURCE_SHORTAGE = 0x8000,
+       AHC_TQINFIFO_BLOCKED  = 0x10000,/* Blocked waiting for ATIOs */
+       AHC_INT50_SPEEDFLEX   = 0x20000,/*
                                           * Internal 50pin connector
                                           * sits behind an aic3860
                                           */
-       AHC_SCB_BTT             = 0x40000,/*
+       AHC_SCB_BTT           = 0x40000,/*
                                           * The busy targets table is
                                           * stored in SCB space rather
                                           * than SRAM.
                                           */
-       AHC_BIOS_ENABLED        = 0x80000,
-       AHC_ALL_INTERRUPTS      = 0x100000
+       AHC_BIOS_ENABLED      = 0x80000,
+       AHC_ALL_INTERRUPTS    = 0x100000,
+       AHC_ULTRA_DISABLED    = 0x200000, /*
+                                          * The precision resistor for
+                                          * ultra transmission speeds is
+                                          * missing, so we must limit
+                                          * ourselves to fast SCSI.
+                                          */
+       AHC_PAGESCBS          = 0x400000, /* Enable SCB paging */
+       AHC_EDGE_INTERRUPT    = 0x800000  /* Device uses edge triggered ints */
 } ahc_flag;
 
 /*
@@ -705,32 +711,14 @@
 
 /***************************** Lookup Tables **********************************/
 /*
- * Textual descriptions of the different chips indexed by chip type.
- */
-extern char *ahc_chip_names[];
-extern const u_int num_chip_names;
-
-/*
- * Hardware error codes.
- */
-struct hard_error_entry {
-        uint8_t errno;
-       char *errmesg;
-};
-extern struct hard_error_entry hard_error[];
-extern const u_int num_errors;
-
-/*
  * Phase -> name and message out response
  * to parity errors in each phase table. 
  */
-struct phase_table_entry {
+struct ahc_phase_table_entry {
         uint8_t phase;
         uint8_t mesg_out; /* Message response to parity errors */
        char *phasemsg;
 };
-extern struct phase_table_entry phase_table[];
-extern const u_int num_phases;
 
 /************************** Serial EEPROM Format ******************************/
 
@@ -782,7 +770,8 @@
 #define                CFMULTILUN      0x0020  /* SCSI low byte term (284x cards) */  
 
 #define                CFRESETB        0x0040  /* reset SCSI bus at boot */
 #define                CFCLUSTERENB    0x0080  /* Cluster Enable */
-#define                CFCHNLBPRIMARY  0x0100  /* aic7895 probe B channel first */
+#define                CFBOOTCHAN      0x0300  /* probe this channel first */
+#define                CFBOOTCHANSHIFT 8
 #define                CFSEAUTOTERM    0x0400  /* Ultra2 Perform secondary Auto Term*/
 #define                CFSELOWTERM     0x0800  /* Ultra2 secondary low term */
 #define                CFSEHIGHTERM    0x1000  /* Ultra2 secondary high term */
@@ -1137,8 +1126,10 @@
 void                   ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
 int                    ahc_reset_channel(struct ahc_softc *ahc, char channel,
                                          int initiate_reset);
-void                   restart_sequencer(struct ahc_softc *ahc);
+void                   ahc_restart(struct ahc_softc *ahc);
 /*************************** Utility Functions ********************************/
+struct ahc_phase_table_entry*
+                       ahc_lookup_phase_entry(int phase);
 void                   ahc_compile_devinfo(struct ahc_devinfo *devinfo,
                                            u_int our_id, u_int target,
                                            u_int lun, char channel,
Index: aic7xxx.reg
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx.reg,v
retrieving revision 1.20.2.7
diff -u -r1.20.2.7 aic7xxx.reg
--- aic7xxx.reg 2001/02/10 18:11:36     1.20.2.7
+++ aic7xxx.reg 2001/03/11 04:54:37
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7xxx.reg#12 $
+ * $Id: //depot/src/aic7xxx/aic7xxx.reg#14 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.reg,v 1.20.2.7 2001/02/10 18:11:36 gibbs Exp 
$
  */
@@ -877,6 +877,7 @@
        address                 0x094
        access_mode RO
        bit     PRELOAD_AVAIL   0x80
+       bit     DFCACHETH       0x40
        bit     DWORDEMP        0x20
        bit     MREQPEND        0x10
        bit     HDONE           0x08
@@ -1456,6 +1457,10 @@
                size            1
        }
 
+       SEQ_FLAGS2 {
+               size            1
+               bit     SCB_DMA         0x01
+       }
        /*
         * These are reserved registers in the card's scratch ram.  Some of
         * the values are specified in the AHA2742 technical reference manual
Index: aic7xxx.seq
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx.seq,v
retrieving revision 1.94.2.10
diff -u -r1.94.2.10 aic7xxx.seq
--- aic7xxx.seq 2001/02/21 20:51:25     1.94.2.10
+++ aic7xxx.seq 2001/03/11 04:54:55
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7xxx.seq#20 $
+ * $Id: //depot/src/aic7xxx/aic7xxx.seq#23 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.94.2.10 2001/02/21 20:51:25 gibbs 
Exp $
  */
@@ -88,7 +88,6 @@
                cmp     KERNEL_QINPOS, A je poll_for_work_loop;
        }
        mov     ARG_1, NEXT_QUEUED_SCB;
-END_CRITICAL
 
        /*
         * We have at least one queued SCB now and we don't have any 
@@ -101,6 +100,8 @@
                /* In the non-paging case, the SCBID == hardware SCB index */
                mov     SCBPTR, ARG_1;
        }
+       or      SEQ_FLAGS2, SCB_DMA;
+END_CRITICAL
 dma_queued_scb:
        /*
         * DMA the SCB from host ram into the current SCB location.
@@ -128,6 +129,7 @@
        } else {
                inc     QINPOS;
        }
+       and     SEQ_FLAGS2, ~SCB_DMA;
 END_CRITICAL
 start_waiting:
        /*
@@ -692,69 +694,75 @@
        adc     SCB_RESIDUAL_SGPTR[2],A;
        adc     SCB_RESIDUAL_SGPTR[3],A ret;
 
+if ((ahc->features & AHC_CMD_CHAN) != 0) {
+disable_ccsgen:
+       test    CCSGCTL, CCSGEN jz return;
+       test    CCSGCTL, CCSGDONE jz .;
+disable_ccsgen_fetch_done:
+       clr     CCSGCTL;
+       test    CCSGCTL, CCSGEN jnz .;
+       ret;
 idle_loop:
-       if ((ahc->features & AHC_CMD_CHAN) != 0) {
-               /* Did we just finish fetching segs? */
-               cmp     CCSGCTL, CCSGEN|CCSGDONE je idle_sgfetch_complete;
+       /* Did we just finish fetching segs? */
+       cmp     CCSGCTL, CCSGEN|CCSGDONE je idle_sgfetch_complete;
 
-               /* Are we actively fetching segments? */
-               test    CCSGCTL, CCSGEN jnz return;
+       /* Are we actively fetching segments? */
+       test    CCSGCTL, CCSGEN jnz return;
 
-               /*
-                * Do we need any more segments?
-                */
-               test    SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return;
+       /*
+        * Do we need any more segments?
+        */
+       test    SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return;
 
-               /*
-                * Do we have any prefetch left???
-                */
-               cmp     CCSGADDR, SG_PREFETCH_CNT jne idle_sg_avail;
+       /*
+        * Do we have any prefetch left???
+        */
+       cmp     CCSGADDR, SG_PREFETCH_CNT jne idle_sg_avail;
 
-               /*
-                * Need to fetch segments, but we can only do that
-                * if the command channel is completely idle.  Make
-                * sure we don't have an SCB prefetch going on.
-                */
-               test    CCSCBCTL, CCSCBEN jnz return;
+       /*
+        * Need to fetch segments, but we can only do that
+        * if the command channel is completely idle.  Make
+        * sure we don't have an SCB prefetch going on.
+        */
+       test    CCSCBCTL, CCSCBEN jnz return;
 
-               /*
-                * We fetch a "cacheline aligned" and sized amount of data
-                * so we don't end up referencing a non-existant page.
-                * Cacheline aligned is in quotes because the kernel will
-                * set the prefetch amount to a reasonable level if the
-                * cacheline size is unknown.
-                */
-               mvi     CCHCNT, SG_PREFETCH_CNT;
-               and     CCHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR;
-               bmov    CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3;
-               mvi     CCSGCTL, CCSGEN|CCSGRESET ret;
+       /*
+        * We fetch a "cacheline aligned" and sized amount of data
+        * so we don't end up referencing a non-existant page.
+        * Cacheline aligned is in quotes because the kernel will
+        * set the prefetch amount to a reasonable level if the
+        * cacheline size is unknown.
+        */
+       mvi     CCHCNT, SG_PREFETCH_CNT;
+       and     CCHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR;
+       bmov    CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3;
+       mvi     CCSGCTL, CCSGEN|CCSGRESET ret;
 idle_sgfetch_complete:
-               clr     CCSGCTL;
-               test    CCSGCTL, CCSGEN jnz .;
-               and     CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR;
+       call    disable_ccsgen_fetch_done;
+       and     CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR;
 idle_sg_avail:
-               if ((ahc->features & AHC_ULTRA2) != 0) {
-                       /* Does the hardware have space for another SG entry? */
-                       test    DFSTATUS, PRELOAD_AVAIL jz return;
-                       bmov    HADDR, CCSGRAM, 4;
-                       bmov    SINDEX, CCSGRAM, 1;
-                       test    SINDEX, 0x1 jz . + 2;
-                       xor     DATA_COUNT_ODD, 0x1;
-                       bmov    HCNT[0], SINDEX, 1;
-                       bmov    HCNT[1], CCSGRAM, 2;
-                       bmov    SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
-                       call    sg_advance;
-                       mov     SINDEX, SCB_RESIDUAL_SGPTR[0];
-                       test    DATA_COUNT_ODD, 0x1 jz . + 2;
-                       or      SINDEX, ODD_SEG;
-                       test    SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
-                       or      SINDEX, LAST_SEG;
-                       mov     SG_CACHE_PRE, SINDEX;
-                       /* Load the segment by writing DFCNTRL again */
-                       mov     DFCNTRL, DMAPARAMS;
-               }
-               ret;
+       if ((ahc->features & AHC_ULTRA2) != 0) {
+               /* Does the hardware have space for another SG entry? */
+               test    DFSTATUS, PRELOAD_AVAIL jz return;
+               bmov    HADDR, CCSGRAM, 4;
+               bmov    SINDEX, CCSGRAM, 1;
+               test    SINDEX, 0x1 jz . + 2;
+               xor     DATA_COUNT_ODD, 0x1;
+               bmov    HCNT[0], SINDEX, 1;
+               bmov    HCNT[1], CCSGRAM, 2;
+               bmov    SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
+               call    sg_advance;
+               mov     SINDEX, SCB_RESIDUAL_SGPTR[0];
+               test    DATA_COUNT_ODD, 0x1 jz . + 2;
+               or      SINDEX, ODD_SEG;
+               test    SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
+               or      SINDEX, LAST_SEG;
+               mov     SG_CACHE_PRE, SINDEX;
+               /* Load the segment by writing DFCNTRL again */
+               mov     DFCNTRL, DMAPARAMS;
        }
+       ret;
+}
 
 if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0) {
 /*
@@ -1149,12 +1157,6 @@
        if ((ahc->flags & AHC_INITIATORROLE) != 0) {
                test    SSTAT1, REQINIT jz .;
                test    SSTAT1,PHASEMIS jz data_phase_loop;
-       
-               if ((ahc->features & AHC_CMD_CHAN) != 0) {
-                       /* Kill off any pending prefetch */
-                       clr     CCSGCTL;
-                       test    CCSGCTL, CCSGEN jnz .;
-               }
        }
 
 data_phase_done:
@@ -1166,8 +1168,7 @@
         */
        if ((ahc->features & AHC_CMD_CHAN) != 0) {
                /* Kill off any pending prefetch */
-               clr     CCSGCTL;
-               test    CCSGCTL, CCSGEN jnz .;
+               call    disable_ccsgen;
        }
 
        if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0
@@ -1648,12 +1649,27 @@
        if ((ahc->flags & AHC_PAGESCBS) != 0) {
                mov     ARG_1 call findSCB;
        } else {
-               mov     SCBPTR, RETURN_1;
+               mov     SCBPTR, ARG_1;
        }
        if ((ahc->flags & AHC_SCB_BTT) != 0) {
                jmp setup_SCB_id_lun_okay;
        } else {
-               jmp     setup_SCB_id_okay;
+               /*
+                * We only allow one untagged command per-target
+                * at a time.  So, if the lun doesn't match, look
+                * for a tag message.
+                */
+               mov     A, SCB_LUN;
+               cmp     SAVED_LUN, A    je setup_SCB_id_lun_okay;
+               if ((ahc->flags & AHC_PAGESCBS) != 0) {
+                       /*
+                        * findSCB removes the SCB from the
+                        * disconnected list, so we must replace
+                        * it there should this SCB be for another
+                        * lun.
+                        */
+                       call    cleanup_scb;
+               }
        }
 
 /*
@@ -1710,10 +1726,14 @@
        test    SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb;
        and     SCB_CONTROL,~DISCONNECTED;
        test    SCB_CONTROL, TAG_ENB    jnz setup_SCB_tagged;
-       mov     A, SCBPTR;
+       if ((ahc->flags & AHC_SCB_BTT) != 0) {
+               mov     A, SCBPTR;
+       }
        mvi     ARG_1, SCB_LIST_NULL;
        mov     SAVED_SCSIID    call    set_busy_target;
-       mov     SCBPTR, A;
+       if ((ahc->flags & AHC_SCB_BTT) != 0) {
+               mov     SCBPTR, A;
+       }
 setup_SCB_tagged:
        mvi     SEQ_FLAGS,IDENTIFY_SEEN;        /* make note of IDENTIFY */
        call    set_transfer_settings;
@@ -1724,7 +1744,7 @@
 
 not_found_cleanup_scb:
        if ((ahc->flags & AHC_PAGESCBS) != 0) {
-               call    add_scb_to_free_list;
+               call    cleanup_scb;
        }
 not_found:
        mvi     NO_MATCH call set_seqint;
@@ -2056,6 +2076,7 @@
                        test    DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
                        test    DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
                        test    DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
+                       test    DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
                        /*
                         * The PCI module no longer intends to perform
                         * a PCI transaction and HDONE has not come true.
@@ -2131,6 +2152,16 @@
        test    DFCNTRL, HDMAEN jnz .;
        ret;
 
+/*
+ * Restore an SCB that failed to match an incoming reselection
+ * to the correct/safe state.  If the SCB is for a disconnected
+ * transaction, it must be returned to the disconnected list.
+ * If it is not in the disconnected state, it must be free.
+ */
+cleanup_scb:
+       if ((ahc->flags & AHC_PAGESCBS) != 0) {
+               test    SCB_CONTROL,DISCONNECTED jnz add_scb_to_disc_list;
+       }
 add_scb_to_free_list:
        if ((ahc->flags & AHC_PAGESCBS) != 0) {
 BEGIN_CRITICAL
Index: aic7xxx_93cx6.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v
retrieving revision 1.8.2.2
diff -u -r1.8.2.2 aic7xxx_93cx6.c
--- aic7xxx_93cx6.c     2001/01/07 22:50:47     1.8.2.2
+++ aic7xxx_93cx6.c     2001/03/01 17:42:43
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7xxx_93cx6.c#5 $
+ * $Id: //depot/src/aic7xxx/aic7xxx_93cx6.c#7 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.8.2.2 2001/01/07 22:50:47 gibbs 
Exp $
  */
Index: aic7xxx_freebsd.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx_freebsd.c,v
retrieving revision 1.3.2.16
diff -u -r1.3.2.16 aic7xxx_freebsd.c
--- aic7xxx_freebsd.c   2001/02/21 20:51:27     1.3.2.16
+++ aic7xxx_freebsd.c   2001/03/09 19:59:21
@@ -123,7 +123,7 @@
         * declared it the primary channel.
         */
        if ((ahc->features & AHC_TWIN) != 0
-        && (ahc->flags & AHC_CHANNEL_B_PRIMARY) != 0) {
+        && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) {
                bus_id = 1;
                bus_id2 = 0;
        } else {
@@ -214,7 +214,7 @@
 
 fail:
        if ((ahc->features & AHC_TWIN) != 0
-        && (ahc->flags & AHC_CHANNEL_B_PRIMARY) != 0) {
+        && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) {
                ahc->platform_data->sim_b = sim;
                ahc->platform_data->path_b = path;
                ahc->platform_data->sim = sim2;
@@ -1239,12 +1239,12 @@
        scb->flags |= SCB_ACTIVE;
 
        if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
-               pause_sequencer(ahc);
+               ahc_pause(ahc);
                if ((ahc->flags & AHC_PAGESCBS) == 0)
                        ahc_outb(ahc, SCBPTR, scb->hscb->tag);
                ahc_outb(ahc, SCB_TAG, scb->hscb->tag);
                ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
-               unpause_sequencer(ahc);
+               ahc_unpause(ahc);
        } else {
                ahc_queue_scb(ahc, scb);
        }
@@ -1423,7 +1423,7 @@
                /* Previous timeout took care of me already */
                printf("%s: Timedout SCB already complete. "
                       "Interrupts may not be functioning.\n", ahc_name(ahc));
-               unpause_sequencer(ahc);
+               ahc_unpause(ahc);
                ahc_unlock(ahc, &s);
                return;
        }
@@ -1440,11 +1440,7 @@
         */
        last_phase = ahc_inb(ahc, LASTPHASE);
 
-       for (i = 0; i < num_phases; i++) {
-               if (last_phase == phase_table[i].phase)
-                       break;
-       }
-       printf("%s", phase_table[i].phasemsg);
+       printf("%s", ahc_lookup_phase_entry(last_phase)->phasemsg);
 
        printf(", SEQADDR == 0x%x\n",
               ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
@@ -1534,6 +1530,7 @@
                                ccbh = &scb->io_ctx->ccb_h;
                                scb->io_ctx->ccb_h.timeout_ch =
                                    timeout(ahc_timeout, scb, newtimeout);
+                               ahc_unpause(ahc);
                                ahc_unlock(ahc, &s);
                                return;
                        } 
@@ -1552,7 +1549,7 @@
                                ahc_done(ahc, scb);
 
                                /* Will clear us from the bus */
-                               restart_sequencer(ahc);
+                               ahc_restart(ahc);
                                ahc_unlock(ahc, &s);
                                return;
                        }
@@ -1565,7 +1562,7 @@
                        active_scb->flags |= SCB_DEVICE_RESET;
                        active_scb->io_ctx->ccb_h.timeout_ch =
                            timeout(ahc_timeout, (caddr_t)active_scb, 2 * hz);
-                       unpause_sequencer(ahc);
+                       ahc_unpause(ahc);
                } else {
                        int      disconnected;
 
@@ -1579,7 +1576,7 @@
                                /* Hung target selection.  Goto busfree */
                                printf("%s: Hung target selection\n",
                                       ahc_name(ahc));
-                               restart_sequencer(ahc);
+                               ahc_restart(ahc);
                                ahc_unlock(ahc, &s);
                                return;
                        }
@@ -1659,7 +1656,7 @@
                                ahc_outb(ahc, SCBPTR, saved_scbptr);
                                scb->io_ctx->ccb_h.timeout_ch =
                                    timeout(ahc_timeout, (caddr_t)scb, 2 * hz);
-                               unpause_sequencer(ahc);
+                               ahc_unpause(ahc);
                        } else {
                                /* Go "immediatly" to the bus reset */
                                /* This shouldn't happen */
Index: aic7xxx_freebsd.h
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx_freebsd.h,v
retrieving revision 1.2.2.4
diff -u -r1.2.2.4 aic7xxx_freebsd.h
--- aic7xxx_freebsd.h   2001/01/27 20:56:28     1.2.2.4
+++ aic7xxx_freebsd.h   2001/03/11 04:27:43
@@ -49,7 +49,7 @@
 #include <sys/queue.h>
 
 #if NPCI > 0
-#define AHC_SUPPORT_PCI 1
+#define AHC_PCI_CONFIG 1
 #ifdef AHC_ALLOW_MEMIO
 #include <machine/bus_memio.h>
 #endif
@@ -407,7 +407,7 @@
 }
 
 /********************************** PCI ***************************************/
-#ifdef AHC_SUPPORT_PCI
+#ifdef AHC_PCI_CONFIG
 static __inline uint32_t ahc_pci_read_config(ahc_dev_softc_t pci,
                                             int reg, int width);
 static __inline void    ahc_pci_write_config(ahc_dev_softc_t pci,
@@ -449,10 +449,21 @@
 {
        return (pci_get_bus(pci));
 }
+
+typedef enum
+{
+       AHC_POWER_STATE_D0,
+       AHC_POWER_STATE_D1,
+       AHC_POWER_STATE_D2,
+       AHC_POWER_STATE_D3
+} ahc_power_state;
+
+void ahc_power_state_change(struct ahc_softc *ahc,
+                           ahc_power_state new_state);
 #endif
 /******************************** VL/EISA *************************************/
 int aic7770_map_registers(struct ahc_softc *ahc);
-int aic7770_map_int(struct ahc_softc *ahc);
+int aic7770_map_int(struct ahc_softc *ahc, int irq);
 
 /********************************* Debug **************************************/
 static __inline void   ahc_print_path(struct ahc_softc *, struct scb *);
Index: aic7xxx_inline.h
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx_inline.h,v
retrieving revision 1.2.2.8
diff -u -r1.2.2.8 aic7xxx_inline.h
--- aic7xxx_inline.h    2001/02/21 20:51:28     1.2.2.8
+++ aic7xxx_inline.h    2001/03/11 04:55:27
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#15 $
+ * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#17 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_inline.h,v 1.2.2.8 2001/02/21 20:51:28 gibbs 
Exp $
  */
@@ -37,10 +37,10 @@
 #define _AIC7XXX_INLINE_H_
 
 /************************* Sequencer Execution Control ************************/
-static __inline int  sequencer_paused(struct ahc_softc *ahc);
+static __inline int  ahc_is_paused(struct ahc_softc *ahc);
 static __inline void ahc_pause_bug_fix(struct ahc_softc *ahc);
-static __inline void pause_sequencer(struct ahc_softc *ahc);
-static __inline void unpause_sequencer(struct ahc_softc *ahc);
+static __inline void ahc_pause(struct ahc_softc *ahc);
+static __inline void ahc_unpause(struct ahc_softc *ahc);
 
 /*
  * Work around any chip bugs related to halting sequencer execution.
@@ -62,7 +62,7 @@
  * Returns non-zero status if the sequencer is stopped.
  */
 static __inline int
-sequencer_paused(struct ahc_softc *ahc)
+ahc_is_paused(struct ahc_softc *ahc)
 {
        return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
 }
@@ -75,7 +75,7 @@
  * for critical sections.
  */
 static __inline void
-pause_sequencer(struct ahc_softc *ahc)
+ahc_pause(struct ahc_softc *ahc)
 {
        ahc_outb(ahc, HCNTRL, ahc->pause);
 
@@ -83,7 +83,7 @@
         * Since the sequencer can disable pausing in a critical section, we
         * must loop until it actually stops.
         */
-       while (sequencer_paused(ahc) == 0)
+       while (ahc_is_paused(ahc) == 0)
                ;
 
        ahc_pause_bug_fix(ahc);
@@ -100,7 +100,7 @@
  * condition.
  */
 static __inline void
-unpause_sequencer(struct ahc_softc *ahc)
+ahc_unpause(struct ahc_softc *ahc)
 {
        if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
                ahc_outb(ahc, HCNTRL, ahc->unpause);
@@ -345,10 +345,10 @@
                ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
        } else {
                if ((ahc->features & AHC_AUTOPAUSE) == 0)
-                       pause_sequencer(ahc);
+                       ahc_pause(ahc);
                ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
                if ((ahc->features & AHC_AUTOPAUSE) == 0)
-                       unpause_sequencer(ahc);
+                       ahc_unpause(ahc);
        }
 }
 
@@ -412,14 +412,23 @@
         * completion queues.  This avoids a costly PCI bus read in
         * most cases.
         */
-       intstat = 0;
-       if ((queuestat = ahc_check_cmdcmpltqueues(ahc)) != 0)
+       if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0
+        && (queuestat = ahc_check_cmdcmpltqueues(ahc)) != 0)
                intstat = CMDCMPLT;
-
-       if ((intstat & INT_PEND) == 0
-        || (ahc->flags & AHC_ALL_INTERRUPTS) != 0) {
-
+       else {
                intstat = ahc_inb(ahc, INTSTAT);
+               /*
+                * We can't generate queuestat once above
+                * or we are exposed to a race when our
+                * interrupt is shared with another device.
+                * if instat showed a command complete interrupt,
+                * but our first generation of queue stat
+                * "just missed" the delivery of this transaction,
+                * we would clear the command complete interrupt
+                * below without ever servicing the completed
+                * command.
+                */
+               queuestat = ahc_check_cmdcmpltqueues(ahc);
 #if AHC_PCI_CONFIG > 0
                if (ahc->unsolicited_ints > 500
                 && (ahc->chip & AHC_PCI) != 0
Index: aic7xxx_pci.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/aic7xxx/aic7xxx_pci.c,v
retrieving revision 1.2.2.8
diff -u -r1.2.2.8 aic7xxx_pci.c
--- aic7xxx_pci.c       2001/02/21 20:51:28     1.2.2.8
+++ aic7xxx_pci.c       2001/03/11 04:55:50
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#16 $
+ * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#19 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.2.2.8 2001/02/21 20:51:28 gibbs 
Exp $
  */
@@ -63,84 +63,84 @@
        return (id);
 }
 
-#define ID_ALL_MASK            0xFFFFFFFFFFFFFFFFull
-#define ID_DEV_VENDOR_MASK     0xFFFFFFFF00000000ull
-#define ID_9005_GENERIC_MASK   0xFFF0FFFF00000000ull
-#define ID_9005_SISL_MASK      0x000FFFFF00000000ull
-#define ID_9005_SISL_ID                0x0005900500000000ull
-#define ID_AIC7850             0x5078900400000000ull
-#define ID_AHA_2910_15_20_30C  0x5078900478509004ull
-#define ID_AIC7855             0x5578900400000000ull
-#define ID_AIC7859             0x3860900400000000ull
-#define ID_AHA_2930CU          0x3860900438699004ull
-#define ID_AIC7860             0x6078900400000000ull
-#define ID_AIC7860C            0x6078900478609004ull
-#define ID_AHA_1480A           0x6075900400000000ull
-#define ID_AHA_2940AU_0                0x6178900400000000ull
-#define ID_AHA_2940AU_1                0x6178900478619004ull
-#define ID_AHA_2940AU_CN       0x2178900478219004ull
-#define ID_AHA_2930C_VAR       0x6038900438689004ull
-
-#define ID_AIC7870             0x7078900400000000ull
-#define ID_AHA_2940            0x7178900400000000ull
-#define ID_AHA_3940            0x7278900400000000ull
-#define ID_AHA_398X            0x7378900400000000ull
-#define ID_AHA_2944            0x7478900400000000ull
-#define ID_AHA_3944            0x7578900400000000ull
-#define ID_AHA_4944            0x7678900400000000ull
-
-#define ID_AIC7880             0x8078900400000000ull
-#define ID_AIC7880_B           0x8078900478809004ull
-#define ID_AHA_2940U           0x8178900400000000ull
-#define ID_AHA_3940U           0x8278900400000000ull
-#define ID_AHA_2944U           0x8478900400000000ull
-#define ID_AHA_3944U           0x8578900400000000ull
-#define ID_AHA_398XU           0x8378900400000000ull
-#define ID_AHA_4944U           0x8678900400000000ull
-#define ID_AHA_2940UB          0x8178900478819004ull
-#define ID_AHA_2930U           0x8878900478889004ull
-#define ID_AHA_2940U_PRO       0x8778900478879004ull
-#define ID_AHA_2940U_CN                0x0078900478009004ull
-
-#define ID_AIC7895             0x7895900478959004ull
-#define ID_AIC7895_ARO         0x7890900478939004ull
-#define ID_AIC7895_ARO_MASK    0xFFF0FFFFFFFFFFFFull
-#define ID_AHA_2940U_DUAL      0x7895900478919004ull
-#define ID_AHA_3940AU          0x7895900478929004ull
-#define ID_AHA_3944AU          0x7895900478949004ull
-
-#define ID_AIC7890             0x001F9005000F9005ull
-#define ID_AIC7890_ARO         0x00139005000F9005ull
-#define ID_AAA_131U2           0x0013900500039005ull
-#define ID_AHA_2930U2          0x0011900501819005ull
-#define ID_AHA_2940U2B         0x00109005A1009005ull
-#define ID_AHA_2940U2_OEM      0x0010900521809005ull
-#define ID_AHA_2940U2          0x00109005A1809005ull
-#define ID_AHA_2950U2B         0x00109005E1009005ull
-
-#define ID_AIC7892             0x008F9005FFFF9005ull
-#define ID_AIC7892_ARO         0x00839005FFFF9005ull
-#define ID_AHA_29160           0x00809005E2A09005ull
-#define ID_AHA_29160_CPQ       0x00809005E2A00E11ull
-#define ID_AHA_29160N          0x0080900562A09005ull
-#define ID_AHA_29160C          0x0080900562209005ull
-#define ID_AHA_29160B          0x00809005E2209005ull
-#define ID_AHA_19160B          0x0081900562A19005ull
-
-#define ID_AIC7896             0x005F9005FFFF9005ull
-#define ID_AIC7896_ARO         0x00539005FFFF9005ull
-#define ID_AHA_3950U2B_0       0x00509005FFFF9005ull
-#define ID_AHA_3950U2B_1       0x00509005F5009005ull
-#define ID_AHA_3950U2D_0       0x00519005FFFF9005ull
-#define ID_AHA_3950U2D_1       0x00519005B5009005ull
-
-#define ID_AIC7899             0x00CF9005FFFF9005ull
-#define ID_AIC7899_ARO         0x00C39005FFFF9005ull
-#define ID_AHA_3960D           0x00C09005F6209005ull /* AKA AHA-39160 */
-#define ID_AHA_3960D_CPQ       0x00C09005F6200E11ull
+#define ID_ALL_MASK                    0xFFFFFFFFFFFFFFFFull
+#define ID_DEV_VENDOR_MASK             0xFFFFFFFF00000000ull
+#define ID_9005_GENERIC_MASK           0xFFF0FFFF00000000ull
+#define ID_9005_SISL_MASK              0x000FFFFF00000000ull
+#define ID_9005_SISL_ID                        0x0005900500000000ull
+#define ID_AIC7850                     0x5078900400000000ull
+#define ID_AHA_2902_04_10_15_20_30C    0x5078900478509004ull
+#define ID_AIC7855                     0x5578900400000000ull
+#define ID_AIC7859                     0x3860900400000000ull
+#define ID_AHA_2930CU                  0x3860900438699004ull
+#define ID_AIC7860                     0x6078900400000000ull
+#define ID_AIC7860C                    0x6078900478609004ull
+#define ID_AHA_1480A                   0x6075900400000000ull
+#define ID_AHA_2940AU_0                        0x6178900400000000ull
+#define ID_AHA_2940AU_1                        0x6178900478619004ull
+#define ID_AHA_2940AU_CN               0x2178900478219004ull
+#define ID_AHA_2930C_VAR               0x6038900438689004ull
+
+#define ID_AIC7870                     0x7078900400000000ull
+#define ID_AHA_2940                    0x7178900400000000ull
+#define ID_AHA_3940                    0x7278900400000000ull
+#define ID_AHA_398X                    0x7378900400000000ull
+#define ID_AHA_2944                    0x7478900400000000ull
+#define ID_AHA_3944                    0x7578900400000000ull
+#define ID_AHA_4944                    0x7678900400000000ull
+
+#define ID_AIC7880                     0x8078900400000000ull
+#define ID_AIC7880_B                   0x8078900478809004ull
+#define ID_AHA_2940U                   0x8178900400000000ull
+#define ID_AHA_3940U                   0x8278900400000000ull
+#define ID_AHA_2944U                   0x8478900400000000ull
+#define ID_AHA_3944U                   0x8578900400000000ull
+#define ID_AHA_398XU                   0x8378900400000000ull
+#define ID_AHA_4944U                   0x8678900400000000ull
+#define ID_AHA_2940UB                  0x8178900478819004ull
+#define ID_AHA_2930U                   0x8878900478889004ull
+#define ID_AHA_2940U_PRO               0x8778900478879004ull
+#define ID_AHA_2940U_CN                        0x0078900478009004ull
+
+#define ID_AIC7895                     0x7895900478959004ull
+#define ID_AIC7895_ARO                 0x7890900478939004ull
+#define ID_AIC7895_ARO_MASK            0xFFF0FFFFFFFFFFFFull
+#define ID_AHA_2940U_DUAL              0x7895900478919004ull
+#define ID_AHA_3940AU                  0x7895900478929004ull
+#define ID_AHA_3944AU                  0x7895900478949004ull
+
+#define ID_AIC7890                     0x001F9005000F9005ull
+#define ID_AIC7890_ARO                 0x00139005000F9005ull
+#define ID_AAA_131U2                   0x0013900500039005ull
+#define ID_AHA_2930U2                  0x0011900501819005ull
+#define ID_AHA_2940U2B                 0x00109005A1009005ull
+#define ID_AHA_2940U2_OEM              0x0010900521809005ull
+#define ID_AHA_2940U2                  0x00109005A1809005ull
+#define ID_AHA_2950U2B                 0x00109005E1009005ull
+
+#define ID_AIC7892                     0x008F9005FFFF9005ull
+#define ID_AIC7892_ARO                 0x00839005FFFF9005ull
+#define ID_AHA_29160                   0x00809005E2A09005ull
+#define ID_AHA_29160_CPQ               0x00809005E2A00E11ull
+#define ID_AHA_29160N                  0x0080900562A09005ull
+#define ID_AHA_29160C                  0x0080900562209005ull
+#define ID_AHA_29160B                  0x00809005E2209005ull
+#define ID_AHA_19160B                  0x0081900562A19005ull
+
+#define ID_AIC7896                     0x005F9005FFFF9005ull
+#define ID_AIC7896_ARO                 0x00539005FFFF9005ull
+#define ID_AHA_3950U2B_0               0x00509005FFFF9005ull
+#define ID_AHA_3950U2B_1               0x00509005F5009005ull
+#define ID_AHA_3950U2D_0               0x00519005FFFF9005ull
+#define ID_AHA_3950U2D_1               0x00519005B5009005ull
+
+#define ID_AIC7899                     0x00CF9005FFFF9005ull
+#define ID_AIC7899_ARO                 0x00C39005FFFF9005ull
+#define ID_AHA_3960D                   0x00C09005F6209005ull
+#define ID_AHA_3960D_CPQ               0x00C09005F6200E11ull
 
-#define ID_AIC7810             0x1078900400000000ull
-#define ID_AIC7815             0x7815900400000000ull
+#define ID_AIC7810                     0x1078900400000000ull
+#define ID_AIC7815                     0x7815900400000000ull
 
 #define DEVID_9005_TYPE(id) ((id) & 0xF)
 #define                DEVID_9005_TYPE_HBA             0x0     /* Standard Card */
@@ -212,8 +212,7 @@
 #define SUBID_9005_CARD_PCIWIDTH_MASK  0x4000
 #define SUBID_9005_CARD_SEDIFF_MASK    0x8000
 
-static ahc_device_setup_t ahc_aic7850_setup;
-static ahc_device_setup_t ahc_aic7855_setup;
+static ahc_device_setup_t ahc_aic785X_setup;
 static ahc_device_setup_t ahc_aic7860_setup;
 static ahc_device_setup_t ahc_apa1480_setup;
 static ahc_device_setup_t ahc_aic7870_setup;
@@ -239,10 +238,10 @@
 {
        /* aic7850 based controllers */
        {
-               ID_AHA_2910_15_20_30C,
+               ID_AHA_2902_04_10_15_20_30C,
                ID_ALL_MASK,
-               "Adaptec 2910/15/20/30C SCSI adapter",
-               ahc_aic7850_setup
+               "Adaptec 2902/04/10/15/20/30C SCSI adapter",
+               ahc_aic785X_setup
        },
        /* aic7860 based controllers */
        {
@@ -544,13 +543,13 @@
                ID_AIC7850 & ID_DEV_VENDOR_MASK,
                ID_DEV_VENDOR_MASK,
                "Adaptec aic7850 SCSI adapter",
-               ahc_aic7850_setup
+               ahc_aic785X_setup
        },
        {
                ID_AIC7855 & ID_DEV_VENDOR_MASK,
                ID_DEV_VENDOR_MASK,
                "Adaptec aic7855 SCSI adapter",
-               ahc_aic7855_setup
+               ahc_aic785X_setup
        },
        {
                ID_AIC7859 & ID_DEV_VENDOR_MASK,
@@ -636,6 +635,7 @@
 
 #define        DEVCONFIG               0x40
 #define                SCBSIZE32       0x00010000ul    /* aic789X only */
+#define                REXTVALID       0x00001000ul    /* ultra cards only */
 #define                MPORTMODE       0x00000400ul    /* aic7870 only */
 #define                RAMPSM          0x00000200ul    /* aic7870 only */
 #define                VOLSENSE        0x00000100ul
@@ -652,16 +652,6 @@
 #define                CACHESIZE       0x0000003ful    /* only 5 bits */
 #define                LATTIME         0x0000ff00ul
 
-typedef enum
-{
-       AHC_POWER_STATE_D0,
-       AHC_POWER_STATE_D1,
-       AHC_POWER_STATE_D2,
-       AHC_POWER_STATE_D3
-} ahc_power_state;
-
-static void ahc_power_state_change(struct ahc_softc *ahc,
-                                  ahc_power_state new_state);
 static int ahc_ext_scbram_present(struct ahc_softc *ahc);
 static void ahc_scbram_config(struct ahc_softc *ahc, int enable,
                                  int pcheck, int fast, int large);
@@ -771,7 +761,7 @@
 
        /* Remeber how the card was setup in case there is no SEEPROM */
        if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
-               pause_sequencer(ahc);
+               ahc_pause(ahc);
                if ((ahc->features & AHC_ULTRA2) != 0)
                        our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
                else
@@ -887,6 +877,20 @@
        if ((sxfrctl1 & STPWEN) != 0)
                ahc->flags |= AHC_TERM_ENB_A;
 
+       /*
+        * We cannot perform ULTRA speeds without
+        * the presense of the external precision
+        * resistor.
+        */
+       if ((ahc->features & AHC_ULTRA) != 0) {
+               uint32_t devconfig;
+
+               devconfig = ahc_pci_read_config(ahc->dev_softc,
+                                               DEVCONFIG, /*bytes*/4);
+               if ((devconfig & REXTVALID) == 0)
+                       ahc->flags |= AHC_ULTRA_DISABLED;
+       }
+
        /* Core initialization */
        error = ahc_init(ahc);
        if (error != 0)
@@ -900,41 +904,6 @@
        return (0);
 }
 
-static void
-ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state)
-{
-       uint32_t cap;
-       u_int cap_offset;
-
-       /*
-        * Traverse the capability list looking for
-        * the power management capability.
-        */
-       cap = 0;
-       cap_offset = ahc_pci_read_config(ahc->dev_softc,
-                                        PCIR_CAP_PTR, /*bytes*/1);
-       while (cap_offset != 0) {
-
-               cap = ahc_pci_read_config(ahc->dev_softc,
-                                         cap_offset, /*bytes*/4);
-               if ((cap & 0xFF) == 1
-                && ((cap >> 16) & 0x3) > 0) {
-                       uint32_t pm_control;
-
-                       pm_control = ahc_pci_read_config(ahc->dev_softc,
-                                                        cap_offset + 4,
-                                                        /*bytes*/4);
-                       pm_control &= ~0x3;
-                       pm_control |= new_state;
-                       ahc_pci_write_config(ahc->dev_softc,
-                                            cap_offset + 4,
-                                            pm_control, /*bytes*/2);
-                       break;
-               }
-               cap_offset = (cap >> 8) & 0xFF;
-       }
-}
-
 /*
  * Test for the presense of external sram in an
  * "unshared" configuration.
@@ -1184,32 +1153,37 @@
                        }
                        sd.sd_chip = C56_66;
                }
+               release_seeprom(&sd);
        }
 
-#if 0
        if (!have_seeprom) {
                /*
                 * Pull scratch ram settings and treat them as
                 * if they are the contents of an seeprom if
                 * the 'ADPT' signature is found in SCB2.
+                * We manually compose the data as 16bit values
+                * to avoid endian issues.
                 */
                ahc_outb(ahc, SCBPTR, 2);
                if (ahc_inb(ahc, SCB_BASE) == 'A'
                 && ahc_inb(ahc, SCB_BASE + 1) == 'D'
                 && ahc_inb(ahc, SCB_BASE + 2) == 'P'
                 && ahc_inb(ahc, SCB_BASE + 3) == 'T') {
-                       uint8_t *sc_bytes;
+                       uint16_t *sc_data;
                        int       i;
 
-                       sc_bytes = (uint8_t *)&sc;
-                       for (i = 0; i < 64; i++)
-                               sc_bytes[i] = ahc_inb(ahc, TARG_SCSIRATE + i);
-                       /* Byte 0x1c is stored in byte 4 of SCB2 */
-                       sc_bytes[0x1c] = ahc_inb(ahc, SCB_BASE + 4);
+                       sc_data = (uint16_t *)&sc;
+                       for (i = 0; i < 32; i++) {
+                               uint16_t val;
+                               int      j;
+
+                               j = i * 2;
+                               val = ahc_inb(ahc, SRAM_BASE + j)
+                                   | ahc_inb(ahc, SRAM_BASE + j + 1) << 8;
+                       }
                        have_seeprom = verify_cksum(&sc);
                }
        }
-#endif
 
        if (!have_seeprom) {
                if (bootverbose)
@@ -1295,9 +1269,8 @@
                if (sc.adapter_control & CFRESETB)
                        scsi_conf |= RESET_SCSI;
 
-               if ((sc.adapter_control & CFCHNLBPRIMARY) != 0
-                && (ahc->features & AHC_MULTI_FUNC) != 0)
-                       ahc->flags |= AHC_CHANNEL_B_PRIMARY;
+               ahc->flags |=
+                   (sc.adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT;
 
                if (sc.bios_control & CFEXTEND)
                        ahc->flags |= AHC_EXTENDED_TRANS_A;
@@ -1312,7 +1285,7 @@
                                ultraenb = 0;
                }
 
-               if (sc.signature == CFSIGNATURE) {
+               if (sc.signature >= CFSIGNATURE) {
                        uint32_t devconfig;
 
                        /* Honor the STPWLEVEL settings */
@@ -1356,10 +1329,11 @@
                        have_autoterm = FALSE;
        }
 
-       if (have_autoterm)
+       if (have_autoterm) {
+               acquire_seeprom(ahc, &sd);
                configure_termination(ahc, &sd, adapter_control, sxfrctl1);
-
-       release_seeprom(&sd);
+               release_seeprom(&sd);
+       }
 }
 
 static void
@@ -1800,28 +1774,22 @@
                ahc_outb(ahc, CLRINT, CLRPARERR);
        }
 
-       unpause_sequencer(ahc);
+       ahc_unpause(ahc);
 }
 
 static int
-ahc_aic7850_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config)
+ahc_aic785X_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config)
 {
+       uint8_t rev;
+
        probe_config->channel = 'A';
        probe_config->chip = AHC_AIC7850;
        probe_config->features = AHC_AIC7850_FE;
        probe_config->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG
-                          |  AHC_PCI_MWI_BUG;
-       return (0);
-}
-
-static int
-ahc_aic7855_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config)
-{
-       probe_config->channel = 'A';
-       probe_config->chip = AHC_AIC7855;
-       probe_config->features = AHC_AIC7855_FE;
-       probe_config->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG
                           |  AHC_PCI_MWI_BUG;
+       rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
+       if (rev >= 1)
+               probe_config->bugs |= AHC_PCI_2_1_RETRY_BUG;
        return (0);
 }
 

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-stable" in the body of the message

Reply via email to