Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Mar 2001 19:43:29 -0700
From:      "Justin T. Gibbs" <gibbs@scsiguy.com>
To:        John Polstra <jdp@polstra.com>
Cc:        stable@freebsd.org
Subject:   Re: Repeatable panic copying ATAPI audio CD to SCSI disk 
Message-ID:  <200103120243.f2C2hT600664@aslan.scsiguy.com>
In-Reply-To: Your message of "Sun, 11 Mar 2001 17:57:49 PST." <XFMail.010311175749.jdp@polstra.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
>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 majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103120243.f2C2hT600664>