summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1996-11-22 08:25:23 +0000
committergibbs <gibbs@FreeBSD.org>1996-11-22 08:25:23 +0000
commitf4da8ee753f95bd3e4884ab15f233dc72ad4c2d5 (patch)
tree37a92b29c2365dbf92bdb4ab6b12ec9af4b9e5d0 /sys/dev/aic7xxx
parent4a2d33f6d0a82da1bc1282c463d5633d14e76792 (diff)
downloadFreeBSD-src-f4da8ee753f95bd3e4884ab15f233dc72ad4c2d5.zip
FreeBSD-src-f4da8ee753f95bd3e4884ab15f233dc72ad4c2d5.tar.gz
Conditionally enable the busfree interrupt to catch unexpected busfrees.
Immediate SCBs, since they always send messages that tell the target to transition to bus free now rely on the busfree interrupt instead of the IMMEDDONE sequencer interrupt that was generated before. Rearrange some code in the message out loop to give ATN a little more time to drop before we ACK the last byte. Use SPIORDY instead of REQINIT when snooping for a tag message on a reconnect. This is done for the same reasons we use SPIORDY in the inb functions. When going into BITBUCKET mode, turn off HDMAEN in the DFCNTRL register so that we can "not care" what the value of HCNT is. If HCNT is 0, BITBUCKET mode won't transfer any data if HDMAEN is set. Seeing as we don't want the transfer to even think about touching the host, this seems more sane anyway. Thanks to "Dan Willis" <dan@plutotech.com> for pointing out that this was a problem.
Diffstat (limited to 'sys/dev/aic7xxx')
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq74
-rw-r--r--sys/dev/aic7xxx/aic7xxx_reg.h11
2 files changed, 29 insertions, 56 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq
index f25e8ea..56a4adb 100644
--- a/sys/dev/aic7xxx/aic7xxx.seq
+++ b/sys/dev/aic7xxx/aic7xxx.seq
@@ -39,7 +39,7 @@
*
*-M************************************************************************/
-VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.49 1996/11/16 01:07:34 gibbs Exp $"
+VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.50 1996/11/21 06:18:33 gibbs Exp $"
#if defined(__NetBSD__)
#include "../../../../dev/ic/aic7xxxreg.h"
@@ -82,9 +82,10 @@ A = ACCUM
reset:
clr DFCNTRL
clr SCSISIGO /* De-assert BSY */
-/*
- * We jump to start after every bus free.
- */
+
+p_busfree:
+ mvi LASTPHASE, P_BUSFREE
+
start:
and FLAGS,0x07 /* clear target specific flags */
mvi SCSISEQ,ENRSELI /* Always allow reselection */
@@ -146,7 +147,7 @@ dma_queued_scb:
* locks out on a per target basis instead of target/lun. Although this
* is not ideal for devices that have multiple luns active at the same
* time, it is faster than looping through all SCB's looking for active
- * commands. We also don't have enough spare SCB space for to store the
+ * commands. We also don't have enough spare SCB space for us to store the
* SCBID of the currently busy transaction for each target/lun making it
* impossible to link up the SCBs.
*/
@@ -317,6 +318,12 @@ set_sxfrctl0:
*/
mvi CLRSINT1,CLRBUSFREE
mvi CLRSINT0,0x60 /* CLRSELDI|CLRSELDO */
+ or SIMODE1, ENBUSFREE /*
+ * We aren't expecting a
+ * bus free, so interrupt
+ * the kernel driver if it
+ * happens.
+ */
/*
* Main loop for information transfer phases. If BSY is false, then
* we have a bus free condition, expected or not. Otherwise, wait
@@ -400,6 +407,7 @@ data_phase_loop:
* had an overrun.
*/
or SXFRCTL1,BITBUCKET
+ and DMAPARAMS, 0xf7 /* Turn off HDMAEN */
mvi STCNT0,0xff
mvi STCNT1,0xff
mvi STCNT2,0xff
@@ -536,20 +544,20 @@ p_mesgout_start:
* a MESSAGE REJECT.
*/
p_mesgout_loop:
- test SSTAT1,BUSFREE jnz p_mesgout_done
test SSTAT0,SPIORDY jz p_mesgout_loop
test SSTAT1,PHASEMIS jnz p_mesgout_done
/*
* If the next bus phase after ATN drops is a message out, it means
* that the target is requesting that the last message(s) be resent.
*/
+p_mesgout_dropatn:
+ cmp DINDEX,1 jne p_mesgout_testretry /* last byte? */
+ mvi CLRSINT1,CLRATNO /* drop ATN */
+p_mesgout_testretry:
test DINDEX,0xff jnz p_mesgout_outb
or SCSISIGO,ATNO /* turn on ATN for the retry */
jmp p_mesgout_start
p_mesgout_outb:
- cmp DINDEX,1 jne p_mesgout_outb2 /* last byte? */
- mvi CLRSINT1,CLRATNO /* drop ATN */
-p_mesgout_outb2:
dec DINDEX
mvi CLRSINT0, CLRSPIORDY
mov SCSIDATL,SINDIR
@@ -610,6 +618,10 @@ mesgin_complete:
*/
/*
+ * We expect to go to bus free after this message.
+ */
+ and SIMODE1, 0xf7 /* ~ENBUSFREE */
+/*
* First check for residuals
*/
test SCB_RESID_SGCNT,0xff jnz upload_scb
@@ -627,7 +639,7 @@ check_status:
status_ok:
/* First, mark this target as free. */
- test SCB_CONTROL,TAG_ENB jnz test_immediate /*
+ test SCB_CONTROL,TAG_ENB jnz complete /*
* Tagged commands
* don't busy the
* target.
@@ -638,15 +650,6 @@ status_ok:
mov DINDIR, SAVED_LINKPTR
mov SCBPTR, SAVED_SCBPTR
-test_immediate:
- test SCB_CMDLEN,0xff jnz complete /* Immediate message complete */
-/*
- * Pause the sequencer until the driver gets around to handling the command
- * complete. This is so that any action that might require carefull timing
- * with the completion of this command can occur.
- */
- mvi INTSTAT,IMMEDDONE
- jmp dma_next_scb
complete:
test FLAGS, PAGESCBS jz complete_post
mov A, QFULLCNT
@@ -661,7 +664,7 @@ complete_post:
mvi INTSTAT,CMDCMPLT
dma_next_scb:
- cmp SCB_LINKED_NEXT, SCB_LIST_NULL je mesgin_done
+ cmp SCB_LINKED_NEXT, SCB_LIST_NULL je add_to_free_list
test FLAGS, PAGESCBS jnz dma_next_scb2
/* Only DMA on top of ourselves if we are the SCB to download */
mov A, SCB_LINKED_NEXT
@@ -674,7 +677,9 @@ dma_next_scb2:
add_to_waiting_list:
mov SCB_NEXT,WAITING_SCBH
mov WAITING_SCBH, SCBPTR
- or FLAGS, SCB_LISTED
+ jmp mesgin_done
+add_to_free_list:
+ call add_scb_to_free_list
jmp mesgin_done
/*
@@ -706,10 +711,10 @@ mesgin_extended_intr:
* and await the bus going free.
*/
mesgin_disconnect:
+ and SIMODE1, 0xf7 /* ~ENBUSFREE */
or SCB_CONTROL,DISCONNECTED
test FLAGS, PAGESCBS jz mesgin_done
call add_scb_to_disc_list
- or FLAGS, SCB_LISTED
jmp mesgin_done
/*
@@ -772,8 +777,7 @@ mesgin_identify:
*/
mvi ARG_1,SCB_LIST_NULL /* Default to no-tag */
snoop_tag_loop:
- test SSTAT1,BUSFREE jnz use_findSCB
- test SSTAT1,REQINIT jz snoop_tag_loop
+ test SSTAT0,SPIORDY jz snoop_tag_loop
test SSTAT1,PHASEMIS jnz use_findSCB
mvi A call inb_first
cmp A,MSG_SIMPLE_Q_TAG jne use_findSCB
@@ -834,28 +838,6 @@ mesgin_reject:
*/
/*
- * Bus free phase. It might be useful to interrupt the device
- * driver if we aren't expecting this.
- */
-p_busfree:
- mvi LASTPHASE, P_BUSFREE
-
-/*
- * if this is an immediate command, perform a psuedo command complete to
- * notify the driver.
- */
- test SCB_CMDLEN,0xff jz status_ok
- test FLAGS, SCB_LISTED jnz start
- /*
- * This SCB didn't disconnect or have a command complete,
- * so put it on the free queue. It was probably the
- * result of an abort of some sort. This prevents us
- * from "leaking" SCBs.
- */
- call add_scb_to_free_list
- jmp start
-
-/*
* Locking the driver out, build a one-byte message passed in SINDEX
* if there is no active message already. SINDEX is returned intact.
*/
diff --git a/sys/dev/aic7xxx/aic7xxx_reg.h b/sys/dev/aic7xxx/aic7xxx_reg.h
index 841abbf..0657b72 100644
--- a/sys/dev/aic7xxx/aic7xxx_reg.h
+++ b/sys/dev/aic7xxx/aic7xxx_reg.h
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx_reg.h,v 1.16 1996/11/11 05:16:41 gibbs Exp $
+ * $Id: aic7xxx_reg.h,v 1.17 1996/11/16 01:07:35 gibbs Exp $
*/
/*
@@ -420,10 +420,6 @@
* it that it can fill the
* message buffer.
*/
-#define IMMEDDONE 0xb1 /*
- * An immediate command has
- * completed
- */
#define MSG_BUFFER_BUSY 0xc1 /*
* Sequencer wants to use the
* message buffer, but it
@@ -571,11 +567,7 @@
#define SCB_ACTIVE2 0x0be
#define SCB_ACTIVE3 0x0bf
-#ifdef __linux__
-#define SG_SIZEOF 0x0c /* sizeof(struct scatterlist) */
-#else
#define SG_SIZEOF 0x08 /* sizeof(struct ahc_dma) */
-#endif
/* --------------------- AHA-2840-only definitions -------------------- */
@@ -711,7 +703,6 @@
#define TWIN_BUS 0x01
#define WIDE_BUS 0x02
#define PAGESCBS 0x04
-#define SCB_LISTED 0x08
#define DPHASE 0x10
#define TAGGED_SCB 0x20
#define IDENTIFY_SEEN 0x40
OpenPOWER on IntegriCloud