Deleted Added
full compact
aic7xxx.seq (7562) aic7xxx.seq (7700)
1# @(#)aic7xxx.seq 1.32 94/11/29 jda
2#
3# Adaptec 274x/284x/294x device driver for Linux and FreeBSD.
4# Copyright (c) 1994 The University of Calgary Department of Computer Science.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or

--- 8 unchanged lines hidden (view full) ---

17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19#
20
21# FreeBSD, Twin, Wide, 2 command per target support, tagged queuing and other
22# optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org)
23#
24
1# @(#)aic7xxx.seq 1.32 94/11/29 jda
2#
3# Adaptec 274x/284x/294x device driver for Linux and FreeBSD.
4# Copyright (c) 1994 The University of Calgary Department of Computer Science.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or

--- 8 unchanged lines hidden (view full) ---

17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19#
20
21# FreeBSD, Twin, Wide, 2 command per target support, tagged queuing and other
22# optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org)
23#
24
25VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.11 1995/03/31 14:06:02 gibbs Exp $"
25VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.12 1995/04/01 19:51:40 gibbs Exp $"
26
27SCBMASK = 0x1f
28
29SCSISEQ = 0x00
30SXFRCTL0 = 0x01
31SXFRCTL1 = 0x02
32SCSISIGI = 0x03
33SCSISIGO = 0x03

--- 482 unchanged lines hidden (view full) ---

516 jmp ITloop
517
518# Status phase. Wait for the data byte to appear, then read it
519# and store it into the SCB.
520#
521p_status:
522 mvi 0xc0 call scsisig # CDO|IOO|!MSGO
523
26
27SCBMASK = 0x1f
28
29SCSISEQ = 0x00
30SXFRCTL0 = 0x01
31SXFRCTL1 = 0x02
32SCSISIGI = 0x03
33SCSISIGO = 0x03

--- 482 unchanged lines hidden (view full) ---

516 jmp ITloop
517
518# Status phase. Wait for the data byte to appear, then read it
519# and store it into the SCB.
520#
521p_status:
522 mvi 0xc0 call scsisig # CDO|IOO|!MSGO
523
524 mvi SCBARRAY+14 call inb
525 jmp ITloop
524 mvi SCBARRAY+14 call inb_first
525 jmp p_mesgin_done
526
527# Message out phase. If there is no active message, but the target
528# took us into this phase anyway, build a no-op message and send it.
529#
530p_mesgout:
531 mvi 0xa0 call scsisig # CDO|!IOO|MSGO
532 mvi 0x8 call mk_mesg # build NOP message
533
526
527# Message out phase. If there is no active message, but the target
528# took us into this phase anyway, build a no-op message and send it.
529#
530p_mesgout:
531 mvi 0xa0 call scsisig # CDO|!IOO|MSGO
532 mvi 0x8 call mk_mesg # build NOP message
533
534 clr STCNT+2
535 clr STCNT+1
536
534# Set up automatic PIO transfer from MSG_START. Bit 3 in
535# SXFRCTL0 (SPIOEN) is already on.
536#
537 mvi SINDEX,MSG_START+0
538 mov DINDEX,MSG_LEN
537# Set up automatic PIO transfer from MSG_START. Bit 3 in
538# SXFRCTL0 (SPIOEN) is already on.
539#
540 mvi SINDEX,MSG_START+0
541 mov DINDEX,MSG_LEN
539 clr A
540
541# When target asks for a byte, drop ATN if it's the last one in
542# the message. Otherwise, keep going until the message is exhausted.
543# (We can't use outb for this since it wants the input in SINDEX.)
544#
545# Keep an eye out for a phase change, in case the target issues
546# a MESSAGE REJECT.
547#

--- 16 unchanged lines hidden (view full) ---

564# if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is
565# polled for transfer completion - for both output _and_ input. The
566# only theory I have is that SPIORDY doesn't drop right away when SCSIDATL
567# is accessed (like the documentation says it does), and that on a longer
568# cable run, the sequencer code was fast enough to loop back and see
569# an SPIORDY that hadn't dropped yet.
570#
571p_mesgout3:
542
543# When target asks for a byte, drop ATN if it's the last one in
544# the message. Otherwise, keep going until the message is exhausted.
545# (We can't use outb for this since it wants the input in SINDEX.)
546#
547# Keep an eye out for a phase change, in case the target issues
548# a MESSAGE REJECT.
549#

--- 16 unchanged lines hidden (view full) ---

566# if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is
567# polled for transfer completion - for both output _and_ input. The
568# only theory I have is that SPIORDY doesn't drop right away when SCSIDATL
569# is accessed (like the documentation says it does), and that on a longer
570# cable run, the sequencer code was fast enough to loop back and see
571# an SPIORDY that hadn't dropped yet.
572#
573p_mesgout3:
572 call one_stcnt
574 mvi STCNT+0, 0x01
573 mov SCSIDATL,SINDIR
574
575p_mesgout4:
576 test SSTAT0,0x4 jz p_mesgout4 # SDONE
577 dec DINDEX
575 mov SCSIDATL,SINDIR
576
577p_mesgout4:
578 test SSTAT0,0x4 jz p_mesgout4 # SDONE
579 dec DINDEX
578 inc A
579 cmp MSG_LEN,A jne p_mesgout2
580 test DINDEX,0xff jnz p_mesgout2
580
581# If the next bus phase after ATN drops is a message out, it means
582# that the target is requesting that the last message(s) be resent.
583#
584p_mesgout5:
585 test SSTAT1,0x8 jnz p_mesgout6 # BUSFREE
586 test SSTAT1,0x1 jz p_mesgout5 # REQINIT
587

--- 32 unchanged lines hidden (view full) ---

620# the old one and set the SENSE sequencer flag. If the sense flag is
621# set, the sequencer imediately jumps to start working on the sense
622# command. If the kernel driver does not wish to request sense, it need
623# do nothing, and the command is allowed to complete. We don't
624# bother to post to the QOUTFIFO in the error case since it would require
625# extra work in the kernel driver to ensure that the entry was removed
626# before the command complete code tried processing it.
627
581
582# If the next bus phase after ATN drops is a message out, it means
583# that the target is requesting that the last message(s) be resent.
584#
585p_mesgout5:
586 test SSTAT1,0x8 jnz p_mesgout6 # BUSFREE
587 test SSTAT1,0x1 jz p_mesgout5 # REQINIT
588

--- 32 unchanged lines hidden (view full) ---

621# the old one and set the SENSE sequencer flag. If the sense flag is
622# set, the sequencer imediately jumps to start working on the sense
623# command. If the kernel driver does not wish to request sense, it need
624# do nothing, and the command is allowed to complete. We don't
625# bother to post to the QOUTFIFO in the error case since it would require
626# extra work in the kernel driver to ensure that the entry was removed
627# before the command complete code tried processing it.
628
629# First check for residuals
628 test SCBARRAY+15,0xff jnz resid
629 test SCBARRAY+16,0xff jnz resid
630 test SCBARRAY+17,0xff jnz resid
631
632check_status:
633 test SCBARRAY+14,0xff jz status_ok # 0 Status?
634 mvi INTSTAT,BAD_STATUS # let driver know
635 test FLAGS,SENSE jz status_ok

--- 16 unchanged lines hidden (view full) ---

652 mvi INTSTAT,CMDCMPLT
653 jmp p_mesgin_done
654
655# If we have a residual count, interrupt and tell the host. Other
656# alternatives are to pause the sequencer on all command completes (yuck),
657# dma the resid directly to the host (slick, but a ton of instructions), or
658# have the sequencer pause itself when it encounters a non-zero resid
659# (unecessary pause just to flag the command -- yuck, but takes few instructions
630 test SCBARRAY+15,0xff jnz resid
631 test SCBARRAY+16,0xff jnz resid
632 test SCBARRAY+17,0xff jnz resid
633
634check_status:
635 test SCBARRAY+14,0xff jz status_ok # 0 Status?
636 mvi INTSTAT,BAD_STATUS # let driver know
637 test FLAGS,SENSE jz status_ok

--- 16 unchanged lines hidden (view full) ---

654 mvi INTSTAT,CMDCMPLT
655 jmp p_mesgin_done
656
657# If we have a residual count, interrupt and tell the host. Other
658# alternatives are to pause the sequencer on all command completes (yuck),
659# dma the resid directly to the host (slick, but a ton of instructions), or
660# have the sequencer pause itself when it encounters a non-zero resid
661# (unecessary pause just to flag the command -- yuck, but takes few instructions
660# and since it shouldn't happen that offten is good enough for our purposes).
662# and since it shouldn't happen that often is good enough for our purposes).
661
662resid:
663 mvi INTSTAT,RESIDUAL
664 jmp check_status
665
666# Is it an extended message? We only support the synchronous and wide data
667# transfer request messages, which will probably be in response to
668# WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it -

--- 77 unchanged lines hidden (view full) ---

746
747 test A,0x78 jnz p_mesginN # !DiscPriv|!LUNTAR|!Reserved
748
749 and A,0x07 # lun in lower three bits
750 or SAVED_TCL,A,SELID
751 and SAVED_TCL,0xf7
752 and A,0x08,SBLKCTL # B Channel??
753 or SAVED_TCL,A
663
664resid:
665 mvi INTSTAT,RESIDUAL
666 jmp check_status
667
668# Is it an extended message? We only support the synchronous and wide data
669# transfer request messages, which will probably be in response to
670# WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it -

--- 77 unchanged lines hidden (view full) ---

748
749 test A,0x78 jnz p_mesginN # !DiscPriv|!LUNTAR|!Reserved
750
751 and A,0x07 # lun in lower three bits
752 or SAVED_TCL,A,SELID
753 and SAVED_TCL,0xf7
754 and A,0x08,SBLKCTL # B Channel??
755 or SAVED_TCL,A
754 call inb_last # Ack
755
756# Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
757# If we get one, we use the tag returned to switch to the proper
758# SCB. Otherwise, we just use the findSCB method.
759p_mesgin5_loop:
760 test SSTAT1,0x08 jnz use_findSCB # BUSFREE
761 test SSTAT1,0x01 jz p_mesgin5_loop # REQINIT
762 and A,0xe0,SCSISIGI # CDI|IOI|MSGI
763 cmp A,0xe0 jne use_findSCB # Still p_mesgin?
764 mvi A call inb_first
765 cmp A,0x20 je get_tag # Simple Tag message?
766use_findSCB:
767 mov ALLZEROS call findSCB # Have to search
768
769# If a active message is present after calling findSCB, then either it
770# or the driver is trying to abort the command. Either way, something
771# untoward has happened and we should just leave it alone.
772#
756 call inb_last # ACK
757 mov ALLZEROS call findSCB
773setup_SCB:
774 and SCBARRAY+0,0xfb # clear disconnect bit in SCB
758setup_SCB:
759 and SCBARRAY+0,0xfb # clear disconnect bit in SCB
775 or FLAGS,0xc0 # make note of IDENTIFY
760 or FLAGS,IDENTIFY_SEEN # make note of IDENTIFY
776
777 call sg_scb2ram # implied restore pointers
778 # required on reselect
779 jmp ITloop
761
762 call sg_scb2ram # implied restore pointers
763 # required on reselect
764 jmp ITloop
780
781get_tag:
765get_tag:
766 mvi A call inb_first
767 cmp A,0x20 jne return # Simple Tag message?
782 mvi A call inb_next
768 mvi A call inb_next
769 call inb_last
783 test A,0xf0 jnz abort_tag # Tag in range?
784 mov SCBPTR,A
785 mov A,SAVED_TCL
786 cmp SCBARRAY+1,A jne abort_tag
787 test SCBARRAY+0,TAG_ENB jz abort_tag
770 test A,0xf0 jnz abort_tag # Tag in range?
771 mov SCBPTR,A
772 mov A,SAVED_TCL
773 cmp SCBARRAY+1,A jne abort_tag
774 test SCBARRAY+0,TAG_ENB jz abort_tag
788 call inb_last # ACK
789 jmp setup_SCB
775 ret
776abort_tag:
777 or SINDEX,0x10,SIGSTATE # turn on ATNO
778 call scsisig
779 mvi INTSTAT,ABORT_TAG # let driver know
780 mvi 0xd call mk_mesg # ABORT TAG message
781 ret
790
791# Message reject? Let the kernel driver handle this. If we have an
792# outstanding WDTR or SDTR negotiation, assume that it's a response from
793# the target selecting 8bit or asynchronous transfer, otherwise just ignore
794# it since we have no clue what it pertains to.
795#
796p_mesgin6:
797 cmp A,7 jne p_mesgin7 # message reject code?

--- 18 unchanged lines hidden (view full) ---

816 mvi INTSTAT,SEND_REJECT # let driver know
817
818 mvi 0x7 call mk_mesg # MESSAGE REJECT message
819
820p_mesgin_done:
821 call inb_last # ack & turn auto PIO back on
822 jmp ITloop
823
782
783# Message reject? Let the kernel driver handle this. If we have an
784# outstanding WDTR or SDTR negotiation, assume that it's a response from
785# the target selecting 8bit or asynchronous transfer, otherwise just ignore
786# it since we have no clue what it pertains to.
787#
788p_mesgin6:
789 cmp A,7 jne p_mesgin7 # message reject code?

--- 18 unchanged lines hidden (view full) ---

808 mvi INTSTAT,SEND_REJECT # let driver know
809
810 mvi 0x7 call mk_mesg # MESSAGE REJECT message
811
812p_mesgin_done:
813 call inb_last # ack & turn auto PIO back on
814 jmp ITloop
815
824abort_tag:
825 or SINDEX,0x10,SIGSTATE # turn on ATNO
826 call scsisig
827 mvi INTSTAT,ABORT_TAG # let driver know
828 mvi 0xd call mk_mesg # ABORT TAG message
829 jmp p_mesgin_done
830
831# Bus free phase. It might be useful to interrupt the device
832# driver if we aren't expecting this. For now, make sure that
833# ATN isn't being asserted and look for a new command.
834#
835p_busfree:
836 mvi CLRSINT1,0x40 # CLRATNO
837 clr SIGSTATE

--- 37 unchanged lines hidden (view full) ---

875
876 or FLAGS,ACTIVE_MSG # if not, there is now
877 mvi MSG_LEN,1 # length = 1
878 mov MSG_START+0,SINDEX # 1-byte message
879
880mk_mesg1:
881 mvi SEQCTL,0x10 ret # !PAUSEDIS|FASTMODE
882
816
817# Bus free phase. It might be useful to interrupt the device
818# driver if we aren't expecting this. For now, make sure that
819# ATN isn't being asserted and look for a new command.
820#
821p_busfree:
822 mvi CLRSINT1,0x40 # CLRATNO
823 clr SIGSTATE

--- 37 unchanged lines hidden (view full) ---

861
862 or FLAGS,ACTIVE_MSG # if not, there is now
863 mvi MSG_LEN,1 # length = 1
864 mov MSG_START+0,SINDEX # 1-byte message
865
866mk_mesg1:
867 mvi SEQCTL,0x10 ret # !PAUSEDIS|FASTMODE
868
883# Input byte in Automatic PIO mode. The address to store the byte
884# in should be in SINDEX. DINDEX will be used by this routine.
885#
886inb:
887 test SSTAT0,0x2 jz inb # SPIORDY
888 mov DINDEX,SINDEX
889 call one_stcnt # xfer one byte
890 mov DINDIR,SCSIDATL
891inb1:
892 test SSTAT0,0x4 jz inb1 # SDONE - wait to "finish"
893 ret
894
895# Carefully read data in Automatic PIO mode. I first tried this using
896# Manual PIO mode, but it gave me continual underrun errors, probably
897# indicating that I did something wrong, but I feel more secure leaving
898# Automatic PIO on all the time.
899#
900# According to Adaptec's documentation, an ACK is not sent on input from
901# the target until SCSIDATL is read from. So we wait until SCSIDATL is
902# latched (the usual way), then read the data byte directly off the bus
903# using SCSIBUSL. When we have pulled the ATN line, or we just want to
904# acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI
905# spec guarantees that the target will hold the data byte on the bus until
906# we send our ACK.
907#
908# The assumption here is that these are called in a particular sequence,
909# and that REQ is already set when inb_first is called. inb_{first,next}
910# use the same calling convention as inb.
911#
912inb_first:
869# Carefully read data in Automatic PIO mode. I first tried this using
870# Manual PIO mode, but it gave me continual underrun errors, probably
871# indicating that I did something wrong, but I feel more secure leaving
872# Automatic PIO on all the time.
873#
874# According to Adaptec's documentation, an ACK is not sent on input from
875# the target until SCSIDATL is read from. So we wait until SCSIDATL is
876# latched (the usual way), then read the data byte directly off the bus
877# using SCSIBUSL. When we have pulled the ATN line, or we just want to
878# acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI
879# spec guarantees that the target will hold the data byte on the bus until
880# we send our ACK.
881#
882# The assumption here is that these are called in a particular sequence,
883# and that REQ is already set when inb_first is called. inb_{first,next}
884# use the same calling convention as inb.
885#
886inb_first:
887 clr STCNT+2
888 clr STCNT+1
913 mov DINDEX,SINDEX
914 mov DINDIR,SCSIBUSL ret # read byte directly from bus
915
916inb_next:
917 mov DINDEX,SINDEX # save SINDEX
918
889 mov DINDEX,SINDEX
890 mov DINDIR,SCSIBUSL ret # read byte directly from bus
891
892inb_next:
893 mov DINDEX,SINDEX # save SINDEX
894
919 call one_stcnt # xfer one byte
895 mvi STCNT+0,1 # xfer one byte
920 mov NONE,SCSIDATL # dummy read from latch to ACK
921inb_next1:
922 test SSTAT0,0x4 jz inb_next1 # SDONE
923inb_next2:
924 test SSTAT0,0x2 jz inb_next2 # SPIORDY - wait for next byte
925 mov DINDIR,SCSIBUSL ret # read byte directly from bus
926
927inb_last:
896 mov NONE,SCSIDATL # dummy read from latch to ACK
897inb_next1:
898 test SSTAT0,0x4 jz inb_next1 # SDONE
899inb_next2:
900 test SSTAT0,0x2 jz inb_next2 # SPIORDY - wait for next byte
901 mov DINDIR,SCSIBUSL ret # read byte directly from bus
902
903inb_last:
928 call one_stcnt # ACK with dummy read
904 mvi STCNT+0,1 # ACK with dummy read
929 mov NONE,SCSIDATL
930inb_last1:
931 test SSTAT0,0x4 jz inb_last1 # wait for completion
932 ret
933
905 mov NONE,SCSIDATL
906inb_last1:
907 test SSTAT0,0x4 jz inb_last1 # wait for completion
908 ret
909
934# Output byte in Automatic PIO mode. The byte to output should be
935# in SINDEX. If DROPATN's high bit is set, then ATN will be dropped
936# before the byte is output.
937#
938outb:
939 test SSTAT0,0x2 jz outb # SPIORDY
940 call one_stcnt # xfer one byte
941
942 test DROPATN,0x80 jz outb1
943 mvi CLRSINT1,0x40 # CLRATNO
944 clr DROPATN
945outb1:
946 mov SCSIDATL,SINDEX
947outb2:
948 test SSTAT0,0x4 jz outb2 # SDONE
949 ret
950
951# Write the value "1" into the STCNT registers, for Automatic PIO
952# transfers.
953#
954one_stcnt:
955 clr STCNT+2
956 clr STCNT+1
957 mvi STCNT+0,1 ret
958
959# DMA data transfer. HADDR and HCNT must be loaded first, and
960# SINDEX should contain the value to load DFCNTRL with - 0x3d for
961# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared
962# during initialization.
963#
964dma:
965 mov DFCNTRL,SINDEX
966dma1:

--- 106 unchanged lines hidden (view full) ---

1073# found, and generate an ABORT message to the target. SINDEX should be
1074# cleared on call.
1075#
1076findSCB:
1077 mov A,SAVED_TCL
1078 mov SCBPTR,SINDEX # switch to new SCB
1079 cmp SCBARRAY+1,A jne findSCB1 # target ID/channel/lun match?
1080 test SCBARRAY+0,0x4 jz findSCB1 # should be disconnected
910# DMA data transfer. HADDR and HCNT must be loaded first, and
911# SINDEX should contain the value to load DFCNTRL with - 0x3d for
912# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared
913# during initialization.
914#
915dma:
916 mov DFCNTRL,SINDEX
917dma1:

--- 106 unchanged lines hidden (view full) ---

1024# found, and generate an ABORT message to the target. SINDEX should be
1025# cleared on call.
1026#
1027findSCB:
1028 mov A,SAVED_TCL
1029 mov SCBPTR,SINDEX # switch to new SCB
1030 cmp SCBARRAY+1,A jne findSCB1 # target ID/channel/lun match?
1031 test SCBARRAY+0,0x4 jz findSCB1 # should be disconnected
1032 test SCBARRAY+0,TAG_ENB jnz get_tag
1081 ret
1082
1083findSCB1:
1084 inc SINDEX
1085 mov A,SCBCOUNT
1086 cmp SINDEX,A jne findSCB
1087
1088 mvi INTSTAT,NO_MATCH # not found - signal kernel

--- 194 unchanged lines hidden ---
1033 ret
1034
1035findSCB1:
1036 inc SINDEX
1037 mov A,SCBCOUNT
1038 cmp SINDEX,A jne findSCB
1039
1040 mvi INTSTAT,NO_MATCH # not found - signal kernel

--- 194 unchanged lines hidden ---