Back to home page

OSCL-LXR

 
 

    


0001 ; Script for the NCR (or symbios) 53c700 and 53c700-66 chip
0002 ;
0003 ; Copyright (C) 2001 James.Bottomley@HansenPartnership.com
0004 ;;-----------------------------------------------------------------------------
0005 ;;  
0006 ;;  This program is free software; you can redistribute it and/or modify
0007 ;;  it under the terms of the GNU General Public License as published by
0008 ;;  the Free Software Foundation; either version 2 of the License, or
0009 ;;  (at your option) any later version.
0010 ;;
0011 ;;  This program is distributed in the hope that it will be useful,
0012 ;;  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 ;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 ;;  GNU General Public License for more details.
0015 ;;
0016 ;;  You should have received a copy of the GNU General Public License
0017 ;;  along with this program; if not, write to the Free Software
0018 ;;  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
0019 ;;
0020 ;;-----------------------------------------------------------------------------
0021 ;
0022 ; This script is designed to be modified for the particular command in
0023 ; operation.  The particular variables pertaining to the commands are:
0024 ;
0025 ABSOLUTE        Device_ID = 0           ; ID of target for command
0026 ABSOLUTE        MessageCount = 0        ; Number of bytes in message
0027 ABSOLUTE        MessageLocation = 0     ; Addr of message
0028 ABSOLUTE        CommandCount = 0        ; Number of bytes in command
0029 ABSOLUTE        CommandAddress = 0      ; Addr of Command
0030 ABSOLUTE        StatusAddress = 0       ; Addr to receive status return
0031 ABSOLUTE        ReceiveMsgAddress = 0   ; Addr to receive msg
0032 ;
0033 ; This is the magic component for handling scatter-gather.  Each of the
0034 ; SG components is preceded by a script fragment which moves the
0035 ; necessary amount of data and jumps to the next SG segment.  The final
0036 ; SG segment jumps back to .  However, this address is the first SG script
0037 ; segment.
0038 ;
0039 ABSOLUTE        SGScriptStartAddress = 0
0040 
0041 ; The following represent status interrupts we use 3 hex digits for
0042 ; this: 0xPRS where 
0043 
0044 ; P:
0045 ABSOLUTE        AFTER_SELECTION         = 0x100
0046 ABSOLUTE        BEFORE_CMD              = 0x200
0047 ABSOLUTE        AFTER_CMD               = 0x300
0048 ABSOLUTE        AFTER_STATUS            = 0x400
0049 ABSOLUTE        AFTER_DATA_IN           = 0x500
0050 ABSOLUTE        AFTER_DATA_OUT          = 0x600
0051 ABSOLUTE        DURING_DATA_IN          = 0x700
0052 
0053 ; R:
0054 ABSOLUTE        NOT_MSG_OUT             = 0x10
0055 ABSOLUTE        UNEXPECTED_PHASE        = 0x20
0056 ABSOLUTE        NOT_MSG_IN              = 0x30
0057 ABSOLUTE        UNEXPECTED_MSG          = 0x40
0058 ABSOLUTE        MSG_IN                  = 0x50
0059 ABSOLUTE        SDTR_MSG_R              = 0x60
0060 ABSOLUTE        REJECT_MSG_R            = 0x70
0061 ABSOLUTE        DISCONNECT              = 0x80
0062 ABSOLUTE        MSG_OUT                 = 0x90
0063 ABSOLUTE        WDTR_MSG_R              = 0xA0
0064 
0065 ; S:
0066 ABSOLUTE        GOOD_STATUS             = 0x1
0067 
0068 ; Combinations, since the script assembler can't process |
0069 ABSOLUTE        NOT_MSG_OUT_AFTER_SELECTION = 0x110
0070 ABSOLUTE        UNEXPECTED_PHASE_BEFORE_CMD = 0x220
0071 ABSOLUTE        UNEXPECTED_PHASE_AFTER_CMD = 0x320
0072 ABSOLUTE        NOT_MSG_IN_AFTER_STATUS = 0x430
0073 ABSOLUTE        GOOD_STATUS_AFTER_STATUS = 0x401
0074 ABSOLUTE        UNEXPECTED_PHASE_AFTER_DATA_IN = 0x520
0075 ABSOLUTE        UNEXPECTED_PHASE_AFTER_DATA_OUT = 0x620
0076 ABSOLUTE        UNEXPECTED_MSG_BEFORE_CMD = 0x240
0077 ABSOLUTE        MSG_IN_BEFORE_CMD = 0x250
0078 ABSOLUTE        MSG_IN_AFTER_CMD = 0x350
0079 ABSOLUTE        SDTR_MSG_BEFORE_CMD = 0x260
0080 ABSOLUTE        REJECT_MSG_BEFORE_CMD = 0x270
0081 ABSOLUTE        DISCONNECT_AFTER_CMD = 0x380
0082 ABSOLUTE        SDTR_MSG_AFTER_CMD = 0x360
0083 ABSOLUTE        WDTR_MSG_AFTER_CMD = 0x3A0
0084 ABSOLUTE        MSG_IN_AFTER_STATUS = 0x440
0085 ABSOLUTE        DISCONNECT_AFTER_DATA = 0x580
0086 ABSOLUTE        MSG_IN_AFTER_DATA_IN = 0x550
0087 ABSOLUTE        MSG_IN_AFTER_DATA_OUT = 0x650
0088 ABSOLUTE        MSG_OUT_AFTER_DATA_IN = 0x590
0089 ABSOLUTE        DATA_IN_AFTER_DATA_IN = 0x5a0
0090 ABSOLUTE        MSG_IN_DURING_DATA_IN = 0x750
0091 ABSOLUTE        DISCONNECT_DURING_DATA = 0x780
0092 
0093 ;
0094 ; Other interrupt conditions
0095 ; 
0096 ABSOLUTE        RESELECTED_DURING_SELECTION = 0x1000
0097 ABSOLUTE        COMPLETED_SELECTION_AS_TARGET = 0x1001
0098 ABSOLUTE        RESELECTION_IDENTIFIED = 0x1003
0099 ;
0100 ; Fatal interrupt conditions.  If you add to this, also add to the
0101 ; array of corresponding messages
0102 ;
0103 ABSOLUTE        FATAL = 0x2000
0104 ABSOLUTE        FATAL_UNEXPECTED_RESELECTION_MSG = 0x2000
0105 ABSOLUTE        FATAL_SEND_MSG = 0x2001
0106 ABSOLUTE        FATAL_NOT_MSG_IN_AFTER_SELECTION = 0x2002
0107 ABSOLUTE        FATAL_ILLEGAL_MSG_LENGTH = 0x2003
0108 
0109 ABSOLUTE        DEBUG_INTERRUPT = 0x3000
0110 ABSOLUTE        DEBUG_INTERRUPT1 = 0x3001
0111 ABSOLUTE        DEBUG_INTERRUPT2 = 0x3002
0112 ABSOLUTE        DEBUG_INTERRUPT3 = 0x3003
0113 ABSOLUTE        DEBUG_INTERRUPT4 = 0x3004
0114 ABSOLUTE        DEBUG_INTERRUPT5 = 0x3005
0115 ABSOLUTE        DEBUG_INTERRUPT6 = 0x3006
0116 
0117 
0118 ;
0119 ; SCSI Messages we interpret in the script
0120 ;
0121 ABSOLUTE        COMMAND_COMPLETE_MSG    = 0x00
0122 ABSOLUTE        EXTENDED_MSG            = 0x01
0123 ABSOLUTE        SDTR_MSG                = 0x01
0124 ABSOLUTE        SAVE_DATA_PTRS_MSG      = 0x02
0125 ABSOLUTE        RESTORE_DATA_PTRS_MSG   = 0x03
0126 ABSOLUTE        WDTR_MSG                = 0x03
0127 ABSOLUTE        DISCONNECT_MSG          = 0x04
0128 ABSOLUTE        REJECT_MSG              = 0x07
0129 ABSOLUTE        PARITY_ERROR_MSG        = 0x09
0130 ABSOLUTE        SIMPLE_TAG_MSG          = 0x20
0131 ABSOLUTE        IDENTIFY_MSG            = 0x80
0132 ABSOLUTE        IDENTIFY_MSG_MASK       = 0x7F
0133 ABSOLUTE        TWO_BYTE_MSG            = 0x20
0134 ABSOLUTE        TWO_BYTE_MSG_MASK       = 0x0F
0135 
0136 ; This is where the script begins
0137 
0138 ENTRY   StartUp
0139 
0140 StartUp:
0141         SELECT  ATN Device_ID, Reselect
0142         JUMP    Finish, WHEN STATUS
0143         JUMP    SendIdentifyMsg, IF MSG_OUT
0144         INT     NOT_MSG_OUT_AFTER_SELECTION
0145 
0146 Reselect:
0147         WAIT    RESELECT SelectedAsTarget
0148         INT     RESELECTED_DURING_SELECTION, WHEN MSG_IN
0149         INT     FATAL_NOT_MSG_IN_AFTER_SELECTION
0150 
0151         ENTRY   GetReselectionData
0152 GetReselectionData:
0153         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0154         INT     RESELECTION_IDENTIFIED
0155 
0156         ENTRY   GetReselectionWithTag
0157 GetReselectionWithTag:
0158         MOVE    3, ReceiveMsgAddress, WHEN MSG_IN
0159         INT     RESELECTION_IDENTIFIED
0160         
0161         ENTRY   SelectedAsTarget
0162 SelectedAsTarget:
0163 ; Basically tell the selecting device that there's nothing here
0164         SET     TARGET
0165         DISCONNECT
0166         CLEAR   TARGET
0167         INT     COMPLETED_SELECTION_AS_TARGET
0168 ;
0169 ; These are the messaging entries
0170 ;
0171 ; Send a message.  Message count should be correctly patched
0172         ENTRY   SendMessage
0173 SendMessage:
0174         MOVE    MessageCount, MessageLocation, WHEN MSG_OUT
0175 ResumeSendMessage:
0176         RETURN, WHEN NOT MSG_OUT
0177         INT     FATAL_SEND_MSG
0178 
0179         ENTRY   SendMessagePhaseMismatch
0180 SendMessagePhaseMismatch:
0181         CLEAR   ACK
0182         JUMP    ResumeSendMessage
0183 ;
0184 ; Receive a message.  Need to identify the message to
0185 ; receive it correctly
0186         ENTRY   ReceiveMessage
0187 ReceiveMessage:
0188         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0189 ;
0190 ; Use this entry if we've just tried to look at the first byte
0191 ; of the message and want to process it further
0192 ProcessReceiveMessage:
0193         JUMP    ReceiveExtendedMessage, IF EXTENDED_MSG
0194         RETURN, IF NOT TWO_BYTE_MSG, AND MASK TWO_BYTE_MSG_MASK
0195         CLEAR   ACK
0196         MOVE    1, ReceiveMsgAddress + 1, WHEN MSG_IN
0197         RETURN
0198 ReceiveExtendedMessage:
0199         CLEAR   ACK
0200         MOVE    1, ReceiveMsgAddress + 1, WHEN MSG_IN
0201         JUMP    Receive1Byte, IF 0x01
0202         JUMP    Receive2Byte, IF 0x02
0203         JUMP    Receive3Byte, IF 0x03
0204         JUMP    Receive4Byte, IF 0x04
0205         JUMP    Receive5Byte, IF 0x05
0206         INT     FATAL_ILLEGAL_MSG_LENGTH
0207 Receive1Byte:
0208         CLEAR   ACK
0209         MOVE    1, ReceiveMsgAddress + 2, WHEN MSG_IN
0210         RETURN
0211 Receive2Byte:
0212         CLEAR   ACK
0213         MOVE    2, ReceiveMsgAddress + 2, WHEN MSG_IN
0214         RETURN
0215 Receive3Byte:
0216         CLEAR   ACK
0217         MOVE    3, ReceiveMsgAddress + 2, WHEN MSG_IN
0218         RETURN
0219 Receive4Byte:
0220         CLEAR   ACK
0221         MOVE    4, ReceiveMsgAddress + 2, WHEN MSG_IN
0222         RETURN
0223 Receive5Byte:
0224         CLEAR   ACK
0225         MOVE    5, ReceiveMsgAddress + 2, WHEN MSG_IN
0226         RETURN
0227 ;
0228 ; Come here from the message processor to ignore the message
0229 ;
0230         ENTRY   IgnoreMessage
0231 IgnoreMessage:
0232         CLEAR   ACK
0233         RETURN
0234 ;
0235 ; Come here to send a reply to a message
0236 ;
0237         ENTRY   SendMessageWithATN
0238 SendMessageWithATN:
0239         SET     ATN
0240         CLEAR   ACK
0241         JUMP    SendMessage
0242 
0243 SendIdentifyMsg:
0244         CALL    SendMessage
0245         CLEAR   ATN
0246 
0247 IgnoreMsgBeforeCommand:
0248         CLEAR   ACK
0249         ENTRY   SendCommand
0250 SendCommand:
0251         JUMP    Finish, WHEN STATUS
0252         JUMP    MsgInBeforeCommand, IF MSG_IN
0253         INT     UNEXPECTED_PHASE_BEFORE_CMD, IF NOT CMD
0254         MOVE    CommandCount, CommandAddress, WHEN CMD
0255 ResumeSendCommand:
0256         JUMP    Finish, WHEN STATUS
0257         JUMP    MsgInAfterCmd, IF MSG_IN
0258         JUMP    DataIn, IF DATA_IN
0259         JUMP    DataOut, IF DATA_OUT
0260         INT     UNEXPECTED_PHASE_AFTER_CMD
0261 
0262 IgnoreMsgDuringData:
0263         CLEAR   ACK
0264         ; fall through to MsgInDuringData
0265 
0266 Entry MsgInDuringData
0267 MsgInDuringData:
0268 ;
0269 ; Could be we have nothing more to transfer
0270 ;
0271         JUMP    Finish, WHEN STATUS
0272         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0273         JUMP    DisconnectDuringDataIn, IF DISCONNECT_MSG
0274         JUMP    IgnoreMsgDuringData, IF SAVE_DATA_PTRS_MSG
0275         JUMP    IgnoreMsgDuringData, IF RESTORE_DATA_PTRS_MSG
0276         INT     MSG_IN_DURING_DATA_IN
0277 
0278 MsgInAfterCmd:
0279         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0280         JUMP    DisconnectAfterCmd, IF DISCONNECT_MSG
0281         JUMP    IgnoreMsgInAfterCmd, IF SAVE_DATA_PTRS_MSG
0282         JUMP    IgnoreMsgInAfterCmd, IF RESTORE_DATA_PTRS_MSG
0283         CALL    ProcessReceiveMessage
0284         INT     MSG_IN_AFTER_CMD
0285         CLEAR   ACK
0286         JUMP    ResumeSendCommand
0287 
0288 IgnoreMsgInAfterCmd:
0289         CLEAR   ACK
0290         JUMP    ResumeSendCommand
0291 
0292 DisconnectAfterCmd:
0293         CLEAR   ACK
0294         WAIT    DISCONNECT
0295         ENTRY   Disconnect1
0296 Disconnect1:
0297         INT     DISCONNECT_AFTER_CMD
0298         ENTRY   Disconnect2
0299 Disconnect2:
0300 ; We return here after a reselection
0301         CLEAR   ACK
0302         JUMP    ResumeSendCommand
0303 
0304 MsgInBeforeCommand:
0305         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0306         JUMP    IgnoreMsgBeforeCommand, IF SAVE_DATA_PTRS_MSG
0307         JUMP    IgnoreMsgBeforeCommand, IF RESTORE_DATA_PTRS_MSG
0308         CALL    ProcessReceiveMessage
0309         INT     MSG_IN_BEFORE_CMD
0310         CLEAR   ACK
0311         JUMP    SendCommand
0312 
0313 DataIn:
0314         CALL    SGScriptStartAddress
0315 ResumeDataIn:
0316         JUMP    Finish, WHEN STATUS
0317         JUMP    MsgInAfterDataIn, IF MSG_IN
0318         JUMP    DataInAfterDataIn, if DATA_IN
0319         INT     MSG_OUT_AFTER_DATA_IN, if MSG_OUT
0320         INT     UNEXPECTED_PHASE_AFTER_DATA_IN
0321 
0322 DataInAfterDataIn:
0323         INT     DATA_IN_AFTER_DATA_IN
0324         JUMP    ResumeDataIn
0325 
0326 DataOut:
0327         CALL    SGScriptStartAddress
0328 ResumeDataOut:
0329         JUMP    Finish, WHEN STATUS
0330         JUMP    MsgInAfterDataOut, IF MSG_IN
0331         INT     UNEXPECTED_PHASE_AFTER_DATA_OUT
0332 
0333 MsgInAfterDataIn:
0334         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0335         JUMP    DisconnectAfterDataIn, IF DISCONNECT_MSG
0336         JUMP    IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG
0337         JUMP    IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG
0338         CALL    ProcessReceiveMessage
0339         INT     MSG_IN_AFTER_DATA_IN
0340         CLEAR   ACK
0341         JUMP    ResumeDataIn
0342 
0343 DisconnectDuringDataIn:
0344         CLEAR   ACK
0345         WAIT    DISCONNECT
0346         ENTRY   Disconnect3
0347 Disconnect3:
0348         INT     DISCONNECT_DURING_DATA
0349         ENTRY   Disconnect4
0350 Disconnect4:
0351 ; we return here after a reselection
0352         CLEAR   ACK
0353         JUMP    ResumeSendCommand
0354 
0355 
0356 DisconnectAfterDataIn:
0357         CLEAR   ACK
0358         WAIT    DISCONNECT
0359         ENTRY   Disconnect5
0360 Disconnect5:
0361         INT     DISCONNECT_AFTER_DATA
0362         ENTRY   Disconnect6
0363 Disconnect6:
0364 ; we return here after a reselection
0365         CLEAR   ACK
0366         JUMP    ResumeDataIn
0367 
0368 MsgInAfterDataOut:
0369         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0370         JUMP    DisconnectAfterDataOut, if DISCONNECT_MSG
0371         JUMP    IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG
0372         JUMP    IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG
0373         CALL    ProcessReceiveMessage
0374         INT     MSG_IN_AFTER_DATA_OUT
0375         CLEAR   ACK
0376         JUMP    ResumeDataOut
0377 
0378 IgnoreMsgAfterData:
0379         CLEAR   ACK
0380 ; Data in and out do the same thing on resume, so pick one
0381         JUMP    ResumeDataIn
0382 
0383 DisconnectAfterDataOut:
0384         CLEAR   ACK
0385         WAIT    DISCONNECT
0386         ENTRY   Disconnect7
0387 Disconnect7:
0388         INT     DISCONNECT_AFTER_DATA
0389         ENTRY   Disconnect8
0390 Disconnect8:
0391 ; we return here after a reselection
0392         CLEAR   ACK
0393         JUMP    ResumeDataOut
0394 
0395 Finish:
0396         MOVE    1, StatusAddress, WHEN STATUS
0397         INT     NOT_MSG_IN_AFTER_STATUS, WHEN NOT MSG_IN
0398         MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
0399         JUMP    FinishCommandComplete, IF COMMAND_COMPLETE_MSG
0400         CALL    ProcessReceiveMessage
0401         INT     MSG_IN_AFTER_STATUS
0402         ENTRY   FinishCommandComplete
0403 FinishCommandComplete:
0404         CLEAR   ACK
0405         WAIT    DISCONNECT
0406         ENTRY   Finish1
0407 Finish1:
0408         INT     GOOD_STATUS_AFTER_STATUS
0409         ENTRY   Finish2
0410 Finish2:
0411