From be407614c4ab21df5c8409b65edf262bf1dc662c Mon Sep 17 00:00:00 2001 From: gibbs Date: Fri, 14 May 1999 05:07:25 +0000 Subject: 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. --- sys/dev/aic7xxx/aic7xxx.c | 37 ++++++++++++++++++++++++++----------- sys/dev/aic7xxx/aic7xxx.h | 7 ++++--- sys/dev/aic7xxx/aic7xxx.reg | 13 ++++++++++++- sys/dev/aic7xxx/aic7xxx.seq | 14 +++++++++++++- 4 files changed, 55 insertions(+), 16 deletions(-) (limited to 'sys/dev/aic7xxx') 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 @@ -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; -- cgit v1.1