summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1995-08-05 06:59:17 +0000
committergibbs <gibbs@FreeBSD.org>1995-08-05 06:59:17 +0000
commit1df678461b6db6efcb1cef97367cc24bb226406b (patch)
tree0b3bad3d5365bd2b280988bdb88a8d64f44557b8
parent5e2d56d556d82e5810424fb54b41cdc56395c970 (diff)
downloadFreeBSD-src-1df678461b6db6efcb1cef97367cc24bb226406b.zip
FreeBSD-src-1df678461b6db6efcb1cef97367cc24bb226406b.tar.gz
Fix two race conditions.
The first could occur because the original code would continue to reset the SCSIID register while waiting for a selection. This could potentially conflict with a reconnect since a successfull reconnect will also set the SCSIID register. The fix is to use a separate wait loop after starting a selection (as was done a few revisions ago). The second probably never happens, but it was possible for a target to reconnect while there was a pending SCB on the waiting list and not get noticed. The fix was to remove a supurflous check of the scb waiting list.
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq17
1 files changed, 8 insertions, 9 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq
index 053ba48..38c2663 100644
--- a/sys/dev/aic7xxx/aic7xxx.seq
+++ b/sys/dev/aic7xxx/aic7xxx.seq
@@ -41,7 +41,7 @@
#
##-M#########################################################################
-VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.17 1995/07/04 20:58:57 gibbs Exp $"
+VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.18 1995/07/31 08:21:59 gibbs Exp $"
SCBMASK = 0x1f
@@ -268,19 +268,15 @@ SCB_LIST_NULL = 0xff
# Poll QINCNT for work - the lower bits contain
# the number of entries in the Queue In FIFO.
#
-start:
- cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting
poll_for_work:
test FLAGS,TWIN_BUS jz start2 # Are we a twin channel device?
# For fairness, we check the other bus first, since we just finished a
# transaction on the current channel.
xor SBLKCTL,0x08 # Toggle to the other bus
test SSTAT0,SELDI jnz reselect
- test SSTAT0,SELDO jnz select
xor SBLKCTL,0x08 # Toggle to the original bus
start2:
test SSTAT0,SELDI jnz reselect
- test SSTAT0,SELDO jnz select
cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting
test QINCNT,SCBMASK jz poll_for_work
@@ -388,7 +384,7 @@ start_selection:
# so we interrupt the driver, allow it to fill the message buffer, and
# then go back into the arbitration loop
mvi INTSTAT,AWAITING_MSG
- jmp poll_for_work
+ jmp wait_for_selection
identify:
mov SCBARRAY+1 call disconnect # disconnect ok?
@@ -418,7 +414,10 @@ mk_tag_done:
mov DINDEX call mk_dtr # build DTR message if needed
!message:
- jmp poll_for_work
+wait_for_selection:
+ test SSTAT0,SELDI jnz reselect
+ test SSTAT0,SELDO jnz select
+ jmp wait_for_selection
# Reselection has been initiated by a target. Make a note that we've been
# reselected, but haven't seen an IDENTIFY message from the target
@@ -706,7 +705,7 @@ clear_a:
# complete. This is so that any action that might require carefull timing
# with the completion of this command can occur.
mvi INTSTAT,IMMEDDONE
- jmp start
+ jmp poll_for_work
complete:
mov QOUTFIFO,SCBPTR
mvi INTSTAT,CMDCMPLT
@@ -883,7 +882,7 @@ p_busfree:
# if this is an immediate command, perform a psuedo command complete to
# notify the driver.
test SCBARRAY+11,0xff jz status_ok
- jmp start
+ jmp poll_for_work
# Instead of a generic bcopy routine that requires an argument, we unroll
# the two cases that are actually used, and call them explicitly. This
OpenPOWER on IntegriCloud