summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1999-05-14 05:07:25 +0000
committergibbs <gibbs@FreeBSD.org>1999-05-14 05:07:25 +0000
commitbe407614c4ab21df5c8409b65edf262bf1dc662c (patch)
tree5ef3a902b06386ffc77fea41381daf82690a95d7 /sys
parent04cdde2f41757fd9ef3c46f072d790585422fa94 (diff)
downloadFreeBSD-src-be407614c4ab21df5c8409b65edf262bf1dc662c.zip
FreeBSD-src-be407614c4ab21df5c8409b65edf262bf1dc662c.tar.gz
Better workaround for aic7890 chip bug. Use the HS_MAILBOX register to
tell the sequencer to pause itself for a target msg variable update. This avoids the pause race entirely as HS_MAILBOX can be accessed without pausing the chip. 3.2 Merge candidate.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/aic7xxx/aic7xxx.c37
-rw-r--r--sys/dev/aic7xxx/aic7xxx.h7
-rw-r--r--sys/dev/aic7xxx/aic7xxx.reg13
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq14
4 files changed, 55 insertions, 16 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c
index cc68263..a1095a2 100644
--- a/sys/dev/aic7xxx/aic7xxx.c
+++ b/sys/dev/aic7xxx/aic7xxx.c
@@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx.c,v 1.25 1999/05/06 20:16:17 ken Exp $
+ * $Id: aic7xxx.c,v 1.26 1999/05/08 21:58:56 dfr Exp $
*/
/*
* A few notes on features of the driver.
@@ -1107,18 +1107,27 @@ ahc_update_target_msg_request(struct ahc_softc *ahc,
if (ahc->targ_msg_req != targ_msg_req_orig) {
/* Update the message request bit for this target */
- if (!paused) {
- pause_sequencer(ahc);
- DELAY(1000);
- }
+ if ((ahc->features & AHC_HS_MAILBOX) != 0) {
+ if (paused) {
+ ahc_outb(ahc, TARGET_MSG_REQUEST,
+ ahc->targ_msg_req & 0xFF);
+ ahc_outb(ahc, TARGET_MSG_REQUEST + 1,
+ (ahc->targ_msg_req >> 8) & 0xFF);
+ } else {
+ ahc_outb(ahc, HS_MAILBOX,
+ 0x01 << HOST_MAILBOX_SHIFT);
+ }
+ } else {
+ if (!paused)
+ pause_sequencer(ahc);
- ahc_outb(ahc, TARGET_MSG_REQUEST, ahc->targ_msg_req & 0xFF);
- ahc_outb(ahc, TARGET_MSG_REQUEST + 1,
- (ahc->targ_msg_req >> 8) & 0xFF);
+ ahc_outb(ahc, TARGET_MSG_REQUEST,
+ ahc->targ_msg_req & 0xFF);
+ ahc_outb(ahc, TARGET_MSG_REQUEST + 1,
+ (ahc->targ_msg_req >> 8) & 0xFF);
- if (!paused) {
- unpause_sequencer(ahc, /*unpause always*/FALSE);
- DELAY(1000);
+ if (!paused)
+ unpause_sequencer(ahc, /*unpause always*/FALSE);
}
}
}
@@ -2086,6 +2095,12 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, LASTPHASE) | ATNO);
break;
}
+ case UPDATE_TMSG_REQ:
+ ahc_outb(ahc, TARGET_MSG_REQUEST, ahc->targ_msg_req & 0xFF);
+ ahc_outb(ahc, TARGET_MSG_REQUEST + 1,
+ (ahc->targ_msg_req >> 8) & 0xFF);
+ ahc_outb(ahc, HS_MAILBOX, 0);
+ break;
case SEND_REJECT:
{
u_int rejbyte = ahc_inb(ahc, ACCUM);
diff --git a/sys/dev/aic7xxx/aic7xxx.h b/sys/dev/aic7xxx/aic7xxx.h
index 5f1bb86..f4776d0 100644
--- a/sys/dev/aic7xxx/aic7xxx.h
+++ b/sys/dev/aic7xxx/aic7xxx.h
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx.h,v 1.6 1999/03/05 23:35:47 gibbs Exp $
+ * $Id: aic7xxx.h,v 1.7 1999/04/23 23:27:30 gibbs Exp $
*/
#ifndef _AIC7XXX_H_
@@ -117,16 +117,17 @@ typedef enum {
AHC_SG_PRELOAD = 0x0080, /* Can perform auto-SG preload */
AHC_SPIOCAP = 0x0100, /* Has a Serial Port I/O Cap Register */
AHC_MULTI_TID = 0x0200, /* Has bitmask of TIDs for select-in */
+ AHC_HS_MAILBOX = 0x0400, /* Has HS_MAILBOX register */
AHC_AIC7770_FE = AHC_FENONE,
AHC_AIC7850_FE = AHC_FENONE|AHC_SPIOCAP,
AHC_AIC7860_FE = AHC_ULTRA|AHC_SPIOCAP,
AHC_AIC7870_FE = AHC_FENONE,
AHC_AIC7880_FE = AHC_ULTRA,
AHC_AIC7890_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2|AHC_QUEUE_REGS
- |AHC_SG_PRELOAD|AHC_MULTI_TID,
+ |AHC_SG_PRELOAD|AHC_MULTI_TID|AHC_HS_MAILBOX,
AHC_AIC7895_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA,
AHC_AIC7896_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2|AHC_QUEUE_REGS
- |AHC_SG_PRELOAD|AHC_MULTI_TID,
+ |AHC_SG_PRELOAD|AHC_MULTI_TID|AHC_HS_MAILBOX,
} ahc_feature;
typedef enum {
diff --git a/sys/dev/aic7xxx/aic7xxx.reg b/sys/dev/aic7xxx/aic7xxx.reg
index 885d3d1..4fbff1a 100644
--- a/sys/dev/aic7xxx/aic7xxx.reg
+++ b/sys/dev/aic7xxx/aic7xxx.reg
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx.reg,v 1.12 1999/01/14 06:14:15 gibbs Exp $
+ * $Id: aic7xxx.reg,v 1.14 1999/03/08 22:43:23 gibbs Exp $
*/
/*
@@ -669,6 +669,16 @@ register DSPCISTATUS {
mask DFTHRSH_100 0xc0
}
+/* aic7890/91/96/97 only */
+register HS_MAILBOX {
+ address 0x086
+ mask HOST_MAILBOX 0xF0
+ mask SEQ_MAILBOX 0x0F
+}
+
+const HOST_MAILBOX_SHIFT 4
+const SEQ_MAILBOX_SHIFT 0
+
/*
* Host Control (p. 3-47) R/W
* Overall host control of the device.
@@ -727,6 +737,7 @@ register INTSTAT {
mask NO_IDENT 0x20|SEQINT /* no IDENTIFY after reconnect*/
mask NO_MATCH 0x30|SEQINT /* no cmd match for reconnect */
mask ABORT_REQUESTED 0x50|SEQINT /* Reconect of aborted SCB */
+ mask UPDATE_TMSG_REQ 0x60|SEQINT /* Update TMSG_REQ values */
mask BAD_STATUS 0x70|SEQINT /* Bad status from target */
mask RESIDUAL 0x80|SEQINT /* Residual byte count != 0 */
mask TRACE_POINT 0x90|SEQINT
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq
index dd177da..1d89027 100644
--- a/sys/dev/aic7xxx/aic7xxx.seq
+++ b/sys/dev/aic7xxx/aic7xxx.seq
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx.seq,v 1.86 1999/03/05 23:35:48 gibbs Exp $
+ * $Id: aic7xxx.seq,v 1.87 1999/03/23 07:24:28 gibbs Exp $
*/
#include <dev/aic7xxx/aic7xxx.reg>
@@ -1025,6 +1025,18 @@ p_mesgout:
mov FUNCTION1, SCB_TCL;
mov A, FUNCTION1;
mov SINDEX, TARGET_MSG_REQUEST[0];
+ if ((ahc->features & AHC_HS_MAILBOX) != 0) {
+ /*
+ * Work around a pausing bug in at least the aic7890.
+ * If the host needs to update the TARGET_MSG_REQUEST
+ * bit field, it will set the HS_MAILBOX to 1. In
+ * response, we pause with a specific interrupt code
+ * asking for the mask to be updated before we continue.
+ * Ugh.
+ */
+ test HS_MAILBOX, 0xF0 jz . + 2;
+ mvi INTSTAT, UPDATE_TMSG_REQ;
+ }
if ((ahc->features & AHC_TWIN) != 0) {
/* Second Channel uses high byte bits */
test SCB_TCL, SELBUSB jz . + 2;
OpenPOWER on IntegriCloud