summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq254
1 files changed, 173 insertions, 81 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq
index a112033..d1ed1e1 100644
--- a/sys/dev/aic7xxx/aic7xxx.seq
+++ b/sys/dev/aic7xxx/aic7xxx.seq
@@ -1,6 +1,6 @@
-# @(#)aic7xxx.seq 1.31 94/11/25 jda
+# @(#)aic7xxx.seq 1.32 94/11/29 jda
#
-# Adaptec 274x device driver for Linux.
+# Adaptec 274x/284x/294x device driver for Linux.
# Copyright (c) 1994 The University of Calgary Department of Computer Science.
#
# This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-VERSION AIC7XXX_SEQ_VERSION 1.31
+VERSION AIC7XXX_SEQ_VERSION 1.32
SCBMASK = 0x1f
@@ -97,6 +97,7 @@ SIGNAL_2 = 0x21 # no IDENTIFY after reconnect
SIGNAL_3 = 0x31 # no cmd match for reconnect
SIGNAL_4 = 0x41 # SDTR -> SCSIRATE conversion
STATUS_ERROR = 0x51
+SIGNAL_WDTR = 0x61
# The host adapter card (at least the BIOS) uses 20-2f for SCSI
# device information, 32-33 and 5a-5f as well. As it turns out, the
@@ -116,7 +117,7 @@ STATUS_ERROR = 0x51
# message, so the driver can report an intelligible error if a message is
# rejected.
#
-# RESELECT's high bit is true if we are currently handling a reselect;
+# FLAGS's high bit is true if we are currently handling a reselect;
# its next-highest bit is true ONLY IF we've seen an IDENTIFY message
# from the reselecting target. If we haven't had IDENTIFY, then we have
# no idea what the lun is, and we can't select the right SCB register
@@ -131,9 +132,10 @@ DROPATN = 0x30
REJBYTE = 0x31
DISC_DSB_A = 0x32
DISC_DSB_B = 0x33
-RESELECT = 0x34
-MSG_FLAGS = 0x35
+NEEDWDTR_A = 0x34
+NEEDWDTR_B = 0x35
+
MSG_LEN = 0x36
MSG_START+0 = 0x37
MSG_START+1 = 0x38
@@ -163,6 +165,11 @@ SCBCOUNT = 0x56 # the actual number of SCBs
FLAGS = 0x57 # Device configuration flags
TWIN_BUS = 0x01
WIDE_BUS = 0x02
+CHECK_DTR = 0x08
+SENSE = 0x10
+ACTIVE_MSG = 0x20
+IDENTIFY_SEEN = 0x40
+RESELECTED = 0x80
ACTIVE_A = 0x58
ACTIVE_B = 0x59
@@ -171,6 +178,7 @@ ACTIVE_B = 0x59
# the number of entries in the Queue In FIFO.
#
start:
+ test FLAGS,SENSE jnz start_sense
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.
@@ -205,6 +213,11 @@ start2:
or ACTIVE_B,A # Mark the current target as busy
jmp start_scb
+start_sense:
+# Clear the SENSE flag first, then do a normal start_scb
+ and FLAGS,0xef
+ jmp start_scb
+
# Place the currently active back on the queue for later processing
requeue:
mov QINFIFO, SCBPTR
@@ -215,11 +228,13 @@ test_a:
or ACTIVE_A,A # Mark the current target as busy
start_scb:
- and A,0x08,SCBARRAY+1
- mov SBLKCTL,A # select channel, !wide
+ and SINDEX,0x08,SCBARRAY+1
+ and A,WIDE_BUS,FLAGS # Wide bus?
+ or SINDEX,A
+ mov SBLKCTL,SINDEX # select channel, bus width
mov SCBARRAY+1 call initialize
clr SG_NOLOAD
- clr RESELECT
+ and FLAGS,0x3f # !RESELECTING
# As soon as we get a successful selection, the target should go
# into the message out phase since we have ATN asserted. Prepare
@@ -238,7 +253,8 @@ start_scb:
mov A,SINDEX
cmp MSG_START+0,A jne !message # did driver beat us?
- mvi MSG_START+1 call mk_sdtr # build SDTR message if needed
+ test FLAGS,CHECK_DTR jz !message # Don't even bother with DTR?
+ mvi MSG_START+1 call mk_dtr # build DTR message if needed
!message:
@@ -286,7 +302,8 @@ reselect1:
test SSTAT0,0x20 jz reselect1 # SELDI
mov SELID call initialize
- mvi RESELECT,0x80 # reselected, no IDENTIFY
+ and FLAGS,0x3f # reselected, no IDENTIFY
+ or FLAGS,RESELECTED
# After the [re]selection, make sure that the [re]selection enable
# bit is off. This chip is flaky enough without extra things
@@ -495,7 +512,7 @@ p_mesgout5:
p_mesgout6:
mvi CLRSINT1,0x40 # CLRATNO - in case of PHASEMIS
- clr MSG_FLAGS # no active msg
+ and FLAGS,0xdf # no active msg
jmp ITloop
# Message in phase. Bytes are read using Automatic PIO mode, but not
@@ -528,9 +545,9 @@ p_mesgin:
# before the command complete code tried processing it.
test SCBARRAY+14,0xff jz status_ok # 0 Status?
- call inb_last # ack & turn auto PIO back on
mvi INTSTAT,STATUS_ERROR # let driver know
- jmp start_scb
+ test FLAGS,SENSE jz status_ok
+ jmp p_mesgin_done
status_ok:
@@ -549,50 +566,48 @@ complete:
mvi INTSTAT,0x02 # CMDCMPLT
jmp p_mesgin_done
-# Is it an extended message? We only support the synchronous data
-# transfer request message, which will probably be in response to
-# an SDTR message out from us. If it's not an SDTR, reject it -
+# Is it an extended message? We only support the synchronous and wide data
+# transfer request messages, which will probably be in response to
+# WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it -
# apparently this can be done after any message in byte, according
# to the SCSI-2 spec.
#
-# XXX - we should really reject this if we didn't initiate the SDTR
-# negotiation; this may cause problems with unusual devices.
-#
p_mesgin1:
cmp A,1 jne p_mesgin2 # extended message code?
- mvi A call inb_next
- cmp A,3 jne p_mesginN # extended mesg length = 3
- mvi A call inb_next
- cmp A,1 jne p_mesginN # SDTR code
+ mvi ARG_1 call inb_next # extended message length
+ mvi A call inb_next # extended message code
+
+ cmp A,1 je p_mesginSDTR # Syncronous negotiation message
+ cmp A,3 je p_mesginWDTR # Wide negotiation message
+ jmp p_mesginN
+
+p_mesginWDTR:
+ cmp ARG_1,2 jne p_mesginN # extended mesg length = 2
+ mvi A call inb_next # Width of bus
+ mvi INTSTAT,SIGNAL_WDTR # let driver know
+ test RETURN_1,0x80 jz p_mesgin_done# Do we need to send WDTR?
+
+# We didn't initiate the wide negotiation, so we must respond to the request
+ and RETURN_1,0x7f # Clear the SEND_WDTR Flag
+ or FLAGS,ACTIVE_MSG
+ mvi MSG_START+0 call mk_wdtr # build WDTR message
+ or SINDEX,0x10,SIGSTATE # turn on ATNO
+ call scsisig
+ jmp p_mesgin_done
+p_mesginSDTR:
+ cmp ARG_1,3 jne p_mesginN # extended mesg length = 3
mvi ARG_1 call inb_next # xfer period
mvi A call inb_next # REQ/ACK offset
mvi INTSTAT,SIGNAL_4 # call driver to convert
- call ndx_sdtr # index sync config for target
- mov DINDEX,SINDEX
- not A # turn off "need sdtr" flag
- test SBLKCTL,0x08 jnz p_mesgin1_b
- test SCSIID,0x80 jnz p_mesgin1_b
- and NEEDSDTR_A,A
- jmp p_mesgin1_save
+ test RETURN_1,0x80 jz p_mesgin_done# Do we need to mk_sdtr?
-p_mesgin1_b:
- and NEEDSDTR_B,A
-
-p_mesgin1_save:
- and A,0x80,SINDIR # get the WIDEXFER flag
- or RETURN_1,A # Set WIDEXFER if necessary
- mov DINDIR,RETURN_1 # save returned value
-
-# Even though the SCSI-2 specification says that a device responding
-# to our SDTR message should honor our parameters for transmitting
-# to us, it doesn't seem to work too well in real life. In particular,
-# a lot of CD-ROM and tape units don't function: try using the SDTR
-# parameters the device sent us for both transmitting and receiving.
-#
- mov SCSIRATE,RETURN_1
+ or FLAGS,ACTIVE_MSG
+ mvi MSG_START+0 call mk_sdtr
+ or SINDEX,0x10,SIGSTATE # turn on ATNO
+ call scsisig
jmp p_mesgin_done
# Is it a disconnect message? Set a flag in the SCB to remind us
@@ -638,17 +653,17 @@ p_mesgin5:
# or the driver is trying to abort the command. Either way, something
# untoward has happened and we should just leave it alone.
#
- test MSG_FLAGS,0x80 jnz p_mesgin_done
+ test FLAGS,ACTIVE_MSG jnz p_mesgin_done
and SCBARRAY+0,0xfb # clear disconnect bit in SCB
- mvi RESELECT,0xc0 # make note of IDENTIFY
+ or FLAGS,0xc0 # make note of IDENTIFY
call sg_scb2ram # implied restore pointers
# required on reselect
jmp p_mesgin_done
-# Message reject? If we have an outstanding SDTR negotiation, assume
-# that it's a response from the target selecting asynchronous transfer,
+# Message reject? If we have an outstanding WDTR or SDTR negotiation, assume
+# that it's a response from the target selecting 8bit or asynchronous transfer,
# otherwise just ignore it since we have no clue what it pertains to.
#
# XXX - I don't have a device that responds this way. Does this code
@@ -662,27 +677,55 @@ p_mesgin6:
test SBLKCTL,0x08 jnz p_mesgin6_b
test SCSIID,0x80 jnz p_mesgin6_b
- test NEEDSDTR_A,A jz p_mesgin_done # no - ignore rejection
- call ndx_sdtr # note use of asynch xfer
+ test NEEDWDTR_A,A jnz clear_wdtr_a
+ test NEEDSDTR_A,A jnz clear_sdtr_a
+ jmp p_mesgin_done # no - ignore rejection
+
+clear_sdtr_a:
+ call ndx_dtr # note use of asynch xfer
mov DINDEX,SINDEX
- clr DINDIR
+ and DINDIR,0x80,SINDIR
not A
and NEEDSDTR_A,A
- jmp p_mesgin6_done
+ jmp clear_sdtr_done
+
+clear_wdtr_a:
+ call ndx_dtr # note use of 8bit xfer
+ mov DINDEX,SINDEX
+ and DINDIR,0x7f,SINDIR
+
+ not A
+ and NEEDWDTR_A,A
+ jmp clear_wdtr_done
p_mesgin6_b:
- test NEEDSDTR_B,A jz p_mesgin_done # no - ignore rejection
- call ndx_sdtr # note use of asynch xfer
+ test NEEDWDTR_B,A jnz clear_wdtr_b
+ test NEEDSDTR_B,A jnz clear_sdtr_b
+ jmp p_mesgin_done # no - ignore rejection
+
+clear_wdtr_b:
+ call ndx_dtr # note use of 8bit xfer
mov DINDEX,SINDEX
- clr DINDIR
+ and DINDIR,0x7f,SINDIR
+
+ not A
+ and NEEDWDTR_B,A
+
+clear_wdtr_done:
+ and SCSIRATE,0x7f # select 8bit xfer
+ jmp p_mesgin_done
+
+clear_sdtr_b:
+ call ndx_dtr # note use of asynch xfer
+ mov DINDEX,SINDEX
+ and DINDIR,0x80,SINDIR
not A
and NEEDSDTR_B,A
-p_mesgin6_done:
-
- clr SCSIRATE # select asynch xfer
+clear_sdtr_done:
+ and SCSIRATE,0xf0 # select asynch xfer
jmp p_mesgin_done
# [ ADD MORE MESSAGE HANDLING HERE ]
@@ -731,9 +774,9 @@ bcopy:
#
mk_mesg:
mvi SEQCTL,0x50 # PAUSEDIS|FASTMODE
- test MSG_FLAGS,0x80 jnz mk_mesg1 # active message?
+ test FLAGS,ACTIVE_MSG jnz mk_mesg1 # active message?
- mvi MSG_FLAGS,0x80 # if not, there is now
+ or FLAGS,ACTIVE_MSG # if not, there is now
mvi MSG_LEN,1 # length = 1
mov MSG_START+0,SINDEX # 1-byte message
@@ -839,7 +882,7 @@ dma2:
dma3:
test SINDEX,0x4 jnz dma5 # DIRECTION
dma4:
- test DFSTATUS,0x1 jz dma4 # FIFOEMP
+ test DFSTATUS,0x1 jz dma4 # !FIFOEMP
# Now shut the DMA enables off, and copy STCNT (ie. the underrun
# amount, if any) to the SCB registers; SG_COUNT will get copied to
@@ -873,7 +916,7 @@ initialize_b:
mvi SCSICONF_B jmp initialize_2
initialize_wide:
- and A, 0xf,SCSICONF_B
+ and A,0x0f,SCSICONF_B # SCSI_ID_B[210]
initialize_2:
or SCSIID,A
@@ -900,7 +943,7 @@ initialize_2:
# STPWEN is 7870-specific, enabling an external termination power source.
#
and A,0x38,SINDIR # PARITY_ENB|SEL_TIM[10]
- or SXFRCTL1,0x7,A # ENSTIMER|ACTNEGEN|STPWEN
+ or SXFRCTL1,0x7,A # ENSTIMER|ACTBEGEB|STPWEN
mvi SIMODE1,0x84 # ENSELTIMO|ENSCSIPERR
# Initialize scatter-gather pointers by setting up the working copy
@@ -910,7 +953,7 @@ initialize_2:
# Initialize SCSIRATE with the appropriate value for this target.
#
- call ndx_sdtr
+ call ndx_dtr
mov SCSIRATE,SINDIR
ret
@@ -918,8 +961,8 @@ initialize_2:
# message.
#
assert:
- test RESELECT,0x80 jz assert1 # reselected?
- test RESELECT,0x40 jnz assert1 # seen IDENTIFY?
+ test FLAGS,RESELECTED jz assert1 # reselected?
+ test FLAGS,IDENTIFY_SEEN jnz assert1 # seen IDENTIFY?
mvi INTSTAT,SIGNAL_2 # no - cause a kernel panic
@@ -1111,40 +1154,74 @@ sg_advance2:
# is in SCSIID), and return the result in SINDEX. The accumulator
# contains the 3->8 decoding of the target ID on return.
#
-ndx_sdtr:
+ndx_dtr:
shr A,SCSIID,4
- test SBLKCTL,0x08 jz ndx_sdtr_2
+ test SBLKCTL,0x08 jz ndx_dtr_2
or A,0x08 # Channel B entries add 8
-ndx_sdtr_2:
+ndx_dtr_2:
add SINDEX,SYNCNEG,A
and FUNCTION1,0x70,SCSIID # 3-bit target address decode
mov A,FUNCTION1 ret
-# If we need to negotiate transfer parameters, build the SDTR message
+# If we need to negotiate transfer parameters, build the WDTR or SDTR message
# starting at the address passed in SINDEX. DINDEX is modified on return.
+# The SCSI-II spec requires that Wide negotiation occur first and you can
+# only negotiat one or the other at a time otherwise in the event of a message
+# reject, you wouldn't be able to tell which message was the culpret.
#
-mk_sdtr:
+mk_dtr:
mov DINDEX,SINDEX # save SINDEX
- call ndx_sdtr
- test SCBARRAY+1,0x88 jz mk_sdtr1_a
- test NEEDSDTR_B,A jnz mk_sdtr1 # do we need negotiation?
+ call ndx_dtr
+ test SCBARRAY+1,0x88 jz mk_dtr_a
+ test NEEDWDTR_B,A jnz mk_wdtr_16 # do we need negotiation?
+ test NEEDSDTR_B,A jnz mk_sdtr
ret
-mk_sdtr1_a:
- test NEEDSDTR_A,A jnz mk_sdtr1 # do we need negotiation?
+mk_dtr_a:
+ test NEEDWDTR_A,A jnz mk_wdtr_16 # do we need negotiation?
+ test NEEDSDTR_A,A jnz mk_sdtr
ret
-mk_sdtr1:
+mk_wdtr_16:
+ mvi ARG_1,1 # 16bit wide bus
+
+mk_wdtr:
+ mvi DINDIR,1 # extended message
+ mvi DINDIR,2 # extended message length = 2
+ mvi DINDIR,3 # WDTR code
+ mov DINDIR,ARG_1 # bus width
+
+ add MSG_LEN,-MSG_START+0,DINDEX # update message length
+ ret
+
+mk_sdtr:
mvi DINDIR,1 # extended message
mvi DINDIR,3 # extended message length = 3
mvi DINDIR,1 # SDTR code
- mvi DINDIR,25 # REQ/ACK transfer period
- mvi DINDIR,15 # REQ/ACK offset
+ call sdtr_to_rate
+ mov DINDIR,RETURN_1 # REQ/ACK transfer period
+ and DINDIR,0xf,SINDIR # Sync Offset
add MSG_LEN,-MSG_START+0,DINDEX # update message length
ret
+# Tag Message if Tag enabled in SCB control block. Use SCBPTR as the tag
+# value
+
+#mk_tag:
+# test SCBARRAY+0,0x10 jz mk_tag_done # Tag Enabled?
+# and A,0x03,SCBARRYA+0
+# or A,0x20
+# mov DINDIR,A
+# mov DINDIR,SCBPTR
+#
+# add MSG_LEN,-MSG_START+0,DINDEX # update message length
+
+#mk_tag_done:
+# ret
+
+
# Set SCSI bus control signal state. This also saves the last-written
# value into a location where the higher-level driver can read it - if
# it has to send an ABORT or RESET message, then it needs to know this
@@ -1155,3 +1232,18 @@ mk_sdtr1:
scsisig:
mov SIGSTATE,SINDEX
mov SCSISIGO,SINDEX ret
+
+sdtr_to_rate:
+ call ndx_dtr # index scratch space for target
+ shr A,SINDIR,0x4
+ dec SINDEX #Preserve SINDEX
+ and A,0x7
+ clr RETURN_1
+sdtr_to_rate_loop:
+ test A,0x0f jz sdtr_to_rate_done
+ add RETURN_1,0x18
+ dec A
+ jmp sdtr_to_rate_loop
+sdtr_to_rate_done:
+ shr RETURN_1,0x2
+ add RETURN_1,0x18 ret
OpenPOWER on IntegriCloud