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.
This commit is contained in:
Justin T. Gibbs 1996-11-22 08:25:23 +00:00
parent 2fa4e5a7fc
commit 70f6e5521c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=19921
2 changed files with 29 additions and 56 deletions

View File

@ -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
@ -609,6 +617,10 @@ mesgin_complete:
* command complete code tried processing it.
*/
/*
* We expect to go to bus free after this message.
*/
and SIMODE1, 0xf7 /* ~ENBUSFREE */
/*
* First check for residuals
*/
@ -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
@ -833,28 +837,6 @@ mesgin_reject:
* [ ADD MORE MESSAGE HANDLING HERE ]
*/
/*
* 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.

View File

@ -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