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 --- |