diff options
author | gibbs <gibbs@FreeBSD.org> | 1996-10-28 06:01:08 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 1996-10-28 06:01:08 +0000 |
commit | 3e530ea93e84a0577d83fa0e2f98bf0ef85d939e (patch) | |
tree | 5dc6ec5acb97f0621f91df402579eed044ff984f | |
parent | 63862d7113ea254b01cdef46ea0e45a82469a8d7 (diff) | |
download | FreeBSD-src-3e530ea93e84a0577d83fa0e2f98bf0ef85d939e.zip FreeBSD-src-3e530ea93e84a0577d83fa0e2f98bf0ef85d939e.tar.gz |
Fix problems dealing with non-tagged devices when SCB paging is enabled.
Mostly this involved changing the semantics of the findSCB routine so that
it could be used at times other than handling a reconnection.
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.seq | 96 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_reg.h | 5 |
2 files changed, 53 insertions, 48 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq index cbdd497..912b5c8 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.42.2.2 1996/10/06 01:24:09 gibbs Exp $" +VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.44 1996/10/25 06:34:56 gibbs Exp $" #if defined(__NetBSD__) #include "../../../../dev/ic/aic7xxxreg.h" @@ -153,7 +153,7 @@ dma_queued_scb: test_busy: test SCB_CONTROL, TAG_ENB jnz start_scb mov SAVED_SCBPTR, SCBPTR - call index_untagged_scb + mov SCB_TCL call index_untagged_scb mov ARG_1, SINDIR /* * ARG_1 should * now have the SCB ID of @@ -167,9 +167,18 @@ test_busy: * may be necessary to satisfy the search for * the active SCB. */ + mov SCBPTR, SAVED_SCBPTR call add_scb_to_free_list /* Find the active SCB */ mov ALLZEROS call findSCB + /* + * If we couldn't find it, tell the kernel. This should + * only happen if the parent SCB was aborted and this + * one was already here at the time of the abort. + */ + cmp SINDEX, SCB_LIST_NULL jne paged_busy_link + mvi INTSTAT, NO_MATCH_BUSY +paged_busy_link: /* Link us in */ mov SCB_LINKED_NEXT, CUR_SCBID /* Put it back on the disconnected list */ @@ -345,9 +354,8 @@ p_dataout: * STCNT may have been cleared, so restore it from the residual field. */ data_phase_reinit: - mov STCNT0,SCB_RESID_DCNT0 - mov STCNT1,SCB_RESID_DCNT1 - mov STCNT2,SCB_RESID_DCNT2 + mov DINDEX, STCNT0 + mov SCB_RESID_DCNT0 call bcopy_3 jmp data_phase_loop p_datain: @@ -634,7 +642,7 @@ status_ok: */ mov SAVED_SCBPTR, SCBPTR mov SAVED_LINKPTR, SCB_LINKED_NEXT - call index_untagged_scb + mov SCB_TCL call index_untagged_scb mov DINDIR, SAVED_LINKPTR mov SCBPTR, SAVED_SCBPTR @@ -648,11 +656,6 @@ test_immediate: mvi INTSTAT,IMMEDDONE jmp dma_next_scb complete: - test FLAGS, PAGESCBS jz complete_post - /* Wait for a free slot - we may need to wait only in the paging case */ - mov A, QOUTCNT - cmp QFULLCNT, A je complete -complete_post: /* Post the SCB and issue an interrupt */ mov QOUTFIFO,SCB_TAG mvi INTSTAT,CMDCMPLT @@ -667,7 +670,7 @@ dma_next_scb: jmp add_to_waiting_list dma_next_scb2: mvi DMAPARAMS, 0xd /* HDMAEN|DIRECTION|FIFORESET */ - mov SCB_TAG call dma_scb + mov SCB_LINKED_NEXT call dma_scb add_to_waiting_list: mov SCB_NEXT,WAITING_SCBH mov WAITING_SCBH, SCBPTR @@ -775,6 +778,7 @@ snoop_tag_loop: mvi A call inb_first cmp A,MSG_SIMPLE_Q_TAG jne use_findSCB get_tag: + or FLAGS, TAGGED_SCB mvi ARG_1 call inb_next /* tag value */ /* * See if the tag is in range. The tag is < SCBCOUNT if we add @@ -783,7 +787,7 @@ get_tag: */ mov A,COMP_SCBCOUNT add SINDEX,A,ARG_1 - jc abort_tag + jc send_abort_msg /* * Ensure that the SCB the tag points to is for an SCB transaction @@ -792,6 +796,7 @@ get_tag: test FLAGS, PAGESCBS jz index_by_tag use_findSCB: mov ALLZEROS call findSCB /* Have to search */ + cmp SINDEX, SCB_LIST_NULL, je not_found setup_SCB: and SCB_CONTROL,0xfb /* clear disconnect bit in SCB */ or FLAGS,IDENTIFY_SEEN /* make note of IDENTIFY */ @@ -799,13 +804,18 @@ setup_SCB: jmp ITloop index_by_tag: mov SCBPTR,ARG_1 - mov A,SAVED_TCL - cmp SCB_TCL,A jne abort_tag - test SCB_CONTROL,TAG_ENB jz abort_tag + mov A, SAVED_TCL + cmp SCB_TCL,A jne send_abort_msg + test SCB_CONTROL,TAG_ENB jz send_abort_msg jmp setup_SCB -abort_tag: +not_found: + mvi INTSTAT, NO_MATCH +send_abort_msg: or SCSISIGO,ATNO /* turn on ATNO */ + test FLAGS, TAGGED_SCB jnz abort_tag_msg + mvi MSG_ABORT call mk_mesg + jmp mesgin_done abort_tag_msg: mvi MSG_ABORT_TAG call mk_mesg /* ABORT TAG message */ jmp mesgin_done @@ -966,19 +976,17 @@ assert: mvi INTSTAT,NO_IDENT ret /* no - tell the kernel */ /* - * Locate the SCB matching the target ID/channel/lun in SAVED_TCL, and the tag - * value in ARG_1. If ARG_1 == SCB_LIST_NULL, we're looking for a non-tagged - * SCB. Have the kernel print a warning message if it can't be found, and - * generate an ABORT/ABORT_TAG message to the target. SINDEX should be - * cleared on call. + * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL) + * or by the SCBIDn ARG_1. The search begins at the SCB index passed in + * via SINDEX. If the SCB cannot be found, SINDEX will be SCB_LIST_NULL, + * otherwise, SCBPTR is set to the proper SCB. */ findSCB: - mov A,SAVED_TCL mov SCBPTR,SINDEX /* switch to next SCB */ - cmp SCB_TCL,A jne findSCB1 /* target ID/channel/lun match? */ test SCB_CONTROL,DISCONNECTED jz findSCB1 /*should be disconnected*/ - test SCB_CONTROL,TAG_ENB jnz findTaggedSCB - cmp ARG_1,SCB_LIST_NULL je foundSCB + cmp ARG_1, SCB_LIST_NULL jne findBySCBID + mov A, SAVED_TCL + cmp SCB_TCL,A je foundSCB /* target ID/channel/lun match? */ findSCB1: inc SINDEX mov A,SCBCOUNT @@ -986,29 +994,24 @@ findSCB1: /* * We didn't find it. If we're paging, pull an SCB and DMA down the * one we want. If we aren't paging or the SCB we dma down has the - * abort flag set, alert the kernel and send an abort message. + * abort flag set, return not found. */ - test FLAGS, PAGESCBS jz find_abort + test FLAGS, PAGESCBS jz find_error call get_free_or_disc_scb - mov CUR_SCBID, ARG_1 - cmp CUR_SCBID, SCB_LIST_NULL jne find_dma_scb - call index_untagged_scb - mov CUR_SCBID, SINDIR + cmp ARG_1, SCB_LIST_NULL jne find_dma_scb + mov SAVED_TCL call index_untagged_scb + mov ARG_1, SINDIR /* SCBID of SCB to fetch */ find_dma_scb: mvi DMAPARAMS, 0xd /* HDMAEN|DIRECTION|FIFORESET */ - mov CUR_SCBID call dma_scb + mov ARG_1 call dma_scb test SCB_CONTROL, ABORT_SCB jz return -find_abort: - mvi INTSTAT,NO_MATCH /* not found - signal kernel */ - or SCSISIGO,ATNO /* assert ATNO */ - cmp ARG_1,SCB_LIST_NULL jne abort_tag_msg - mvi MSG_ABORT call mk_mesg - jmp ITloop -findTaggedSCB: +find_error: + mvi SINDEX, SCB_LIST_NULL ret +findBySCBID: mov A, ARG_1 /* Tag passed in ARG_1 */ cmp SCB_TAG,A jne findSCB1 /* Found it? */ foundSCB: - test SCB_CONTROL, ABORT_SCB jnz find_abort + test SCB_CONTROL, ABORT_SCB jnz find_error test FLAGS,PAGESCBS jz return rem_scb_from_disc_list: /* Remove this SCB from the disconnection list */ @@ -1110,10 +1113,11 @@ dma_finish2: ret index_untagged_scb: - shr SINDEX, SCB_TCL, 4 - and SINDEX, 0x03 /* Bottom two bits of tid */ - add SINDEX, SCB_ACTIVE0 - shr A, SCB_TCL, 6 /* Target ID divided by 4 */ + mov DINDEX, SINDEX + shr DINDEX, 4 + and DINDEX, 0x03 /* Bottom two bits of tid */ + add DINDEX, SCB_ACTIVE0 + shr A, SINDEX, 6 /* Target ID divided by 4 */ test SCB_TCL, SELBUSB jz index_untagged_scb2 or A, 2 /* Add 2 positions */ index_untagged_scb2: @@ -1121,7 +1125,7 @@ index_untagged_scb2: * Select the SCB with this * target's information. */ - mov DINDEX, SINDEX ret + mov SINDEX, DINDEX ret get_free_or_disc_scb: diff --git a/sys/dev/aic7xxx/aic7xxx_reg.h b/sys/dev/aic7xxx/aic7xxx_reg.h index c48a49a..cd91c9e 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.12.2.2 1996/10/06 01:24:13 gibbs Exp $ + * $Id: aic7xxx_reg.h,v 1.14 1996/10/25 06:34:59 gibbs Exp $ */ /* @@ -408,7 +408,7 @@ #define NO_IDENT 0x21 /* no IDENTIFY after reconnect*/ #define NO_MATCH 0x31 /* no cmd match for reconnect */ #define EXTENDED_MSG 0x41 /* Extended message received */ -#define DMA_UP_SCB 0x51 +#define NO_MATCH_BUSY 0x51 /* Couldn't find BUSY SCB */ #define REJECT_MSG 0x61 /* Reject message received */ #define BAD_STATUS 0x71 /* Bad status from target */ #define RESIDUAL 0x81 /* Residual byte count != 0 */ @@ -706,6 +706,7 @@ #define PAGESCBS 0x04 #define SCB_LISTED 0x08 #define DPHASE 0x10 +#define TAGGED_SCB 0x20 #define IDENTIFY_SEEN 0x40 #define RESELECTED 0x80 |