More code optimizations. Use a slightly different approach to decide

whether a reconnecting target is a tagged device or not.
This commit is contained in:
gibbs 1995-04-09 06:40:16 +00:00
parent 59da37e6eb
commit ff034bb17f
2 changed files with 56 additions and 152 deletions

View File

@ -22,7 +22,7 @@
# optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org)
#
VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.11 1995/03/31 14:06:02 gibbs Exp $"
VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.12 1995/04/01 19:51:40 gibbs Exp $"
SCBMASK = 0x1f
@ -521,8 +521,8 @@ p_command:
p_status:
mvi 0xc0 call scsisig # CDO|IOO|!MSGO
mvi SCBARRAY+14 call inb
jmp ITloop
mvi SCBARRAY+14 call inb_first
jmp p_mesgin_done
# Message out phase. If there is no active message, but the target
# took us into this phase anyway, build a no-op message and send it.
@ -531,12 +531,14 @@ p_mesgout:
mvi 0xa0 call scsisig # CDO|!IOO|MSGO
mvi 0x8 call mk_mesg # build NOP message
clr STCNT+2
clr STCNT+1
# Set up automatic PIO transfer from MSG_START. Bit 3 in
# SXFRCTL0 (SPIOEN) is already on.
#
mvi SINDEX,MSG_START+0
mov DINDEX,MSG_LEN
clr A
# When target asks for a byte, drop ATN if it's the last one in
# the message. Otherwise, keep going until the message is exhausted.
@ -569,14 +571,13 @@ p_mesgout2:
# an SPIORDY that hadn't dropped yet.
#
p_mesgout3:
call one_stcnt
mvi STCNT+0, 0x01
mov SCSIDATL,SINDIR
p_mesgout4:
test SSTAT0,0x4 jz p_mesgout4 # SDONE
dec DINDEX
inc A
cmp MSG_LEN,A jne p_mesgout2
test DINDEX,0xff jnz p_mesgout2
# 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.
@ -625,6 +626,7 @@ p_mesgin:
# extra work in the kernel driver to ensure that the entry was removed
# before the command complete code tried processing it.
# First check for residuals
test SCBARRAY+15,0xff jnz resid
test SCBARRAY+16,0xff jnz resid
test SCBARRAY+17,0xff jnz resid
@ -657,7 +659,7 @@ complete:
# dma the resid directly to the host (slick, but a ton of instructions), or
# have the sequencer pause itself when it encounters a non-zero resid
# (unecessary pause just to flag the command -- yuck, but takes few instructions
# and since it shouldn't happen that offten is good enough for our purposes).
# and since it shouldn't happen that often is good enough for our purposes).
resid:
mvi INTSTAT,RESIDUAL
@ -751,42 +753,32 @@ p_mesgin5:
and SAVED_TCL,0xf7
and A,0x08,SBLKCTL # B Channel??
or SAVED_TCL,A
call inb_last # Ack
# Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
# If we get one, we use the tag returned to switch to the proper
# SCB. Otherwise, we just use the findSCB method.
p_mesgin5_loop:
test SSTAT1,0x08 jnz use_findSCB # BUSFREE
test SSTAT1,0x01 jz p_mesgin5_loop # REQINIT
and A,0xe0,SCSISIGI # CDI|IOI|MSGI
cmp A,0xe0 jne use_findSCB # Still p_mesgin?
mvi A call inb_first
cmp A,0x20 je get_tag # Simple Tag message?
use_findSCB:
mov ALLZEROS call findSCB # Have to search
# If a active message is present after calling findSCB, then either it
# or the driver is trying to abort the command. Either way, something
# untoward has happened and we should just leave it alone.
#
call inb_last # ACK
mov ALLZEROS call findSCB
setup_SCB:
and SCBARRAY+0,0xfb # clear disconnect bit in SCB
or FLAGS,0xc0 # make note of IDENTIFY
or FLAGS,IDENTIFY_SEEN # make note of IDENTIFY
call sg_scb2ram # implied restore pointers
# required on reselect
jmp ITloop
get_tag:
mvi A call inb_first
cmp A,0x20 jne return # Simple Tag message?
mvi A call inb_next
call inb_last
test A,0xf0 jnz abort_tag # Tag in range?
mov SCBPTR,A
mov A,SAVED_TCL
cmp SCBARRAY+1,A jne abort_tag
test SCBARRAY+0,TAG_ENB jz abort_tag
call inb_last # ACK
jmp setup_SCB
ret
abort_tag:
or SINDEX,0x10,SIGSTATE # turn on ATNO
call scsisig
mvi INTSTAT,ABORT_TAG # let driver know
mvi 0xd call mk_mesg # ABORT TAG message
ret
# Message reject? Let the kernel driver handle this. If we have an
# outstanding WDTR or SDTR negotiation, assume that it's a response from
@ -821,12 +813,6 @@ p_mesgin_done:
call inb_last # ack & turn auto PIO back on
jmp ITloop
abort_tag:
or SINDEX,0x10,SIGSTATE # turn on ATNO
call scsisig
mvi INTSTAT,ABORT_TAG # let driver know
mvi 0xd call mk_mesg # ABORT TAG message
jmp p_mesgin_done
# Bus free phase. It might be useful to interrupt the device
# driver if we aren't expecting this. For now, make sure that
@ -880,18 +866,6 @@ mk_mesg:
mk_mesg1:
mvi SEQCTL,0x10 ret # !PAUSEDIS|FASTMODE
# Input byte in Automatic PIO mode. The address to store the byte
# in should be in SINDEX. DINDEX will be used by this routine.
#
inb:
test SSTAT0,0x2 jz inb # SPIORDY
mov DINDEX,SINDEX
call one_stcnt # xfer one byte
mov DINDIR,SCSIDATL
inb1:
test SSTAT0,0x4 jz inb1 # SDONE - wait to "finish"
ret
# Carefully read data in Automatic PIO mode. I first tried this using
# Manual PIO mode, but it gave me continual underrun errors, probably
# indicating that I did something wrong, but I feel more secure leaving
@ -910,13 +884,15 @@ inb1:
# use the same calling convention as inb.
#
inb_first:
clr STCNT+2
clr STCNT+1
mov DINDEX,SINDEX
mov DINDIR,SCSIBUSL ret # read byte directly from bus
inb_next:
mov DINDEX,SINDEX # save SINDEX
call one_stcnt # xfer one byte
mvi STCNT+0,1 # xfer one byte
mov NONE,SCSIDATL # dummy read from latch to ACK
inb_next1:
test SSTAT0,0x4 jz inb_next1 # SDONE
@ -925,37 +901,12 @@ inb_next2:
mov DINDIR,SCSIBUSL ret # read byte directly from bus
inb_last:
call one_stcnt # ACK with dummy read
mvi STCNT+0,1 # ACK with dummy read
mov NONE,SCSIDATL
inb_last1:
test SSTAT0,0x4 jz inb_last1 # wait for completion
ret
# Output byte in Automatic PIO mode. The byte to output should be
# in SINDEX. If DROPATN's high bit is set, then ATN will be dropped
# before the byte is output.
#
outb:
test SSTAT0,0x2 jz outb # SPIORDY
call one_stcnt # xfer one byte
test DROPATN,0x80 jz outb1
mvi CLRSINT1,0x40 # CLRATNO
clr DROPATN
outb1:
mov SCSIDATL,SINDEX
outb2:
test SSTAT0,0x4 jz outb2 # SDONE
ret
# Write the value "1" into the STCNT registers, for Automatic PIO
# transfers.
#
one_stcnt:
clr STCNT+2
clr STCNT+1
mvi STCNT+0,1 ret
# DMA data transfer. HADDR and HCNT must be loaded first, and
# SINDEX should contain the value to load DFCNTRL with - 0x3d for
# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared
@ -1078,6 +1029,7 @@ findSCB:
mov SCBPTR,SINDEX # switch to new SCB
cmp SCBARRAY+1,A jne findSCB1 # target ID/channel/lun match?
test SCBARRAY+0,0x4 jz findSCB1 # should be disconnected
test SCBARRAY+0,TAG_ENB jnz get_tag
ret
findSCB1:

View File

@ -22,7 +22,7 @@
# optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org)
#
VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.11 1995/03/31 14:06:02 gibbs Exp $"
VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.12 1995/04/01 19:51:40 gibbs Exp $"
SCBMASK = 0x1f
@ -521,8 +521,8 @@ p_command:
p_status:
mvi 0xc0 call scsisig # CDO|IOO|!MSGO
mvi SCBARRAY+14 call inb
jmp ITloop
mvi SCBARRAY+14 call inb_first
jmp p_mesgin_done
# Message out phase. If there is no active message, but the target
# took us into this phase anyway, build a no-op message and send it.
@ -531,12 +531,14 @@ p_mesgout:
mvi 0xa0 call scsisig # CDO|!IOO|MSGO
mvi 0x8 call mk_mesg # build NOP message
clr STCNT+2
clr STCNT+1
# Set up automatic PIO transfer from MSG_START. Bit 3 in
# SXFRCTL0 (SPIOEN) is already on.
#
mvi SINDEX,MSG_START+0
mov DINDEX,MSG_LEN
clr A
# When target asks for a byte, drop ATN if it's the last one in
# the message. Otherwise, keep going until the message is exhausted.
@ -569,14 +571,13 @@ p_mesgout2:
# an SPIORDY that hadn't dropped yet.
#
p_mesgout3:
call one_stcnt
mvi STCNT+0, 0x01
mov SCSIDATL,SINDIR
p_mesgout4:
test SSTAT0,0x4 jz p_mesgout4 # SDONE
dec DINDEX
inc A
cmp MSG_LEN,A jne p_mesgout2
test DINDEX,0xff jnz p_mesgout2
# 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.
@ -625,6 +626,7 @@ p_mesgin:
# extra work in the kernel driver to ensure that the entry was removed
# before the command complete code tried processing it.
# First check for residuals
test SCBARRAY+15,0xff jnz resid
test SCBARRAY+16,0xff jnz resid
test SCBARRAY+17,0xff jnz resid
@ -657,7 +659,7 @@ complete:
# dma the resid directly to the host (slick, but a ton of instructions), or
# have the sequencer pause itself when it encounters a non-zero resid
# (unecessary pause just to flag the command -- yuck, but takes few instructions
# and since it shouldn't happen that offten is good enough for our purposes).
# and since it shouldn't happen that often is good enough for our purposes).
resid:
mvi INTSTAT,RESIDUAL
@ -751,42 +753,32 @@ p_mesgin5:
and SAVED_TCL,0xf7
and A,0x08,SBLKCTL # B Channel??
or SAVED_TCL,A
call inb_last # Ack
# Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
# If we get one, we use the tag returned to switch to the proper
# SCB. Otherwise, we just use the findSCB method.
p_mesgin5_loop:
test SSTAT1,0x08 jnz use_findSCB # BUSFREE
test SSTAT1,0x01 jz p_mesgin5_loop # REQINIT
and A,0xe0,SCSISIGI # CDI|IOI|MSGI
cmp A,0xe0 jne use_findSCB # Still p_mesgin?
mvi A call inb_first
cmp A,0x20 je get_tag # Simple Tag message?
use_findSCB:
mov ALLZEROS call findSCB # Have to search
# If a active message is present after calling findSCB, then either it
# or the driver is trying to abort the command. Either way, something
# untoward has happened and we should just leave it alone.
#
call inb_last # ACK
mov ALLZEROS call findSCB
setup_SCB:
and SCBARRAY+0,0xfb # clear disconnect bit in SCB
or FLAGS,0xc0 # make note of IDENTIFY
or FLAGS,IDENTIFY_SEEN # make note of IDENTIFY
call sg_scb2ram # implied restore pointers
# required on reselect
jmp ITloop
get_tag:
mvi A call inb_first
cmp A,0x20 jne return # Simple Tag message?
mvi A call inb_next
call inb_last
test A,0xf0 jnz abort_tag # Tag in range?
mov SCBPTR,A
mov A,SAVED_TCL
cmp SCBARRAY+1,A jne abort_tag
test SCBARRAY+0,TAG_ENB jz abort_tag
call inb_last # ACK
jmp setup_SCB
ret
abort_tag:
or SINDEX,0x10,SIGSTATE # turn on ATNO
call scsisig
mvi INTSTAT,ABORT_TAG # let driver know
mvi 0xd call mk_mesg # ABORT TAG message
ret
# Message reject? Let the kernel driver handle this. If we have an
# outstanding WDTR or SDTR negotiation, assume that it's a response from
@ -821,12 +813,6 @@ p_mesgin_done:
call inb_last # ack & turn auto PIO back on
jmp ITloop
abort_tag:
or SINDEX,0x10,SIGSTATE # turn on ATNO
call scsisig
mvi INTSTAT,ABORT_TAG # let driver know
mvi 0xd call mk_mesg # ABORT TAG message
jmp p_mesgin_done
# Bus free phase. It might be useful to interrupt the device
# driver if we aren't expecting this. For now, make sure that
@ -880,18 +866,6 @@ mk_mesg:
mk_mesg1:
mvi SEQCTL,0x10 ret # !PAUSEDIS|FASTMODE
# Input byte in Automatic PIO mode. The address to store the byte
# in should be in SINDEX. DINDEX will be used by this routine.
#
inb:
test SSTAT0,0x2 jz inb # SPIORDY
mov DINDEX,SINDEX
call one_stcnt # xfer one byte
mov DINDIR,SCSIDATL
inb1:
test SSTAT0,0x4 jz inb1 # SDONE - wait to "finish"
ret
# Carefully read data in Automatic PIO mode. I first tried this using
# Manual PIO mode, but it gave me continual underrun errors, probably
# indicating that I did something wrong, but I feel more secure leaving
@ -910,13 +884,15 @@ inb1:
# use the same calling convention as inb.
#
inb_first:
clr STCNT+2
clr STCNT+1
mov DINDEX,SINDEX
mov DINDIR,SCSIBUSL ret # read byte directly from bus
inb_next:
mov DINDEX,SINDEX # save SINDEX
call one_stcnt # xfer one byte
mvi STCNT+0,1 # xfer one byte
mov NONE,SCSIDATL # dummy read from latch to ACK
inb_next1:
test SSTAT0,0x4 jz inb_next1 # SDONE
@ -925,37 +901,12 @@ inb_next2:
mov DINDIR,SCSIBUSL ret # read byte directly from bus
inb_last:
call one_stcnt # ACK with dummy read
mvi STCNT+0,1 # ACK with dummy read
mov NONE,SCSIDATL
inb_last1:
test SSTAT0,0x4 jz inb_last1 # wait for completion
ret
# Output byte in Automatic PIO mode. The byte to output should be
# in SINDEX. If DROPATN's high bit is set, then ATN will be dropped
# before the byte is output.
#
outb:
test SSTAT0,0x2 jz outb # SPIORDY
call one_stcnt # xfer one byte
test DROPATN,0x80 jz outb1
mvi CLRSINT1,0x40 # CLRATNO
clr DROPATN
outb1:
mov SCSIDATL,SINDEX
outb2:
test SSTAT0,0x4 jz outb2 # SDONE
ret
# Write the value "1" into the STCNT registers, for Automatic PIO
# transfers.
#
one_stcnt:
clr STCNT+2
clr STCNT+1
mvi STCNT+0,1 ret
# DMA data transfer. HADDR and HCNT must be loaded first, and
# SINDEX should contain the value to load DFCNTRL with - 0x3d for
# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared
@ -1078,6 +1029,7 @@ findSCB:
mov SCBPTR,SINDEX # switch to new SCB
cmp SCBARRAY+1,A jne findSCB1 # target ID/channel/lun match?
test SCBARRAY+0,0x4 jz findSCB1 # should be disconnected
test SCBARRAY+0,TAG_ENB jnz get_tag
ret
findSCB1: