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:
parent
4a2d33f6d0
commit
f4da8ee753
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user