412 lines · plain
1; Script for the NCR (or symbios) 53c700 and 53c700-66 chip2;3; Copyright (C) 2001 James.Bottomley@HansenPartnership.com4;;-----------------------------------------------------------------------------5;; 6;; This program is free software; you can redistribute it and/or modify7;; it under the terms of the GNU General Public License as published by8;; the Free Software Foundation; either version 2 of the License, or9;; (at your option) any later version.10;;11;; This program is distributed in the hope that it will be useful,12;; but WITHOUT ANY WARRANTY; without even the implied warranty of13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14;; GNU General Public License for more details.15;;16;; You should have received a copy of the GNU General Public License17;; along with this program; if not, write to the Free Software18;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.19;;20;;-----------------------------------------------------------------------------21;22; This script is designed to be modified for the particular command in23; operation. The particular variables pertaining to the commands are:24;25ABSOLUTE Device_ID = 0 ; ID of target for command26ABSOLUTE MessageCount = 0 ; Number of bytes in message27ABSOLUTE MessageLocation = 0 ; Addr of message28ABSOLUTE CommandCount = 0 ; Number of bytes in command29ABSOLUTE CommandAddress = 0 ; Addr of Command30ABSOLUTE StatusAddress = 0 ; Addr to receive status return31ABSOLUTE ReceiveMsgAddress = 0 ; Addr to receive msg32;33; This is the magic component for handling scatter-gather. Each of the34; SG components is preceded by a script fragment which moves the35; necessary amount of data and jumps to the next SG segment. The final36; SG segment jumps back to . However, this address is the first SG script37; segment.38;39ABSOLUTE SGScriptStartAddress = 040 41; The following represent status interrupts we use 3 hex digits for42; this: 0xPRS where 43 44; P:45ABSOLUTE AFTER_SELECTION = 0x10046ABSOLUTE BEFORE_CMD = 0x20047ABSOLUTE AFTER_CMD = 0x30048ABSOLUTE AFTER_STATUS = 0x40049ABSOLUTE AFTER_DATA_IN = 0x50050ABSOLUTE AFTER_DATA_OUT = 0x60051ABSOLUTE DURING_DATA_IN = 0x70052 53; R:54ABSOLUTE NOT_MSG_OUT = 0x1055ABSOLUTE UNEXPECTED_PHASE = 0x2056ABSOLUTE NOT_MSG_IN = 0x3057ABSOLUTE UNEXPECTED_MSG = 0x4058ABSOLUTE MSG_IN = 0x5059ABSOLUTE SDTR_MSG_R = 0x6060ABSOLUTE REJECT_MSG_R = 0x7061ABSOLUTE DISCONNECT = 0x8062ABSOLUTE MSG_OUT = 0x9063ABSOLUTE WDTR_MSG_R = 0xA064 65; S:66ABSOLUTE GOOD_STATUS = 0x167 68; Combinations, since the script assembler can't process |69ABSOLUTE NOT_MSG_OUT_AFTER_SELECTION = 0x11070ABSOLUTE UNEXPECTED_PHASE_BEFORE_CMD = 0x22071ABSOLUTE UNEXPECTED_PHASE_AFTER_CMD = 0x32072ABSOLUTE NOT_MSG_IN_AFTER_STATUS = 0x43073ABSOLUTE GOOD_STATUS_AFTER_STATUS = 0x40174ABSOLUTE UNEXPECTED_PHASE_AFTER_DATA_IN = 0x52075ABSOLUTE UNEXPECTED_PHASE_AFTER_DATA_OUT = 0x62076ABSOLUTE UNEXPECTED_MSG_BEFORE_CMD = 0x24077ABSOLUTE MSG_IN_BEFORE_CMD = 0x25078ABSOLUTE MSG_IN_AFTER_CMD = 0x35079ABSOLUTE SDTR_MSG_BEFORE_CMD = 0x26080ABSOLUTE REJECT_MSG_BEFORE_CMD = 0x27081ABSOLUTE DISCONNECT_AFTER_CMD = 0x38082ABSOLUTE SDTR_MSG_AFTER_CMD = 0x36083ABSOLUTE WDTR_MSG_AFTER_CMD = 0x3A084ABSOLUTE MSG_IN_AFTER_STATUS = 0x44085ABSOLUTE DISCONNECT_AFTER_DATA = 0x58086ABSOLUTE MSG_IN_AFTER_DATA_IN = 0x55087ABSOLUTE MSG_IN_AFTER_DATA_OUT = 0x65088ABSOLUTE MSG_OUT_AFTER_DATA_IN = 0x59089ABSOLUTE DATA_IN_AFTER_DATA_IN = 0x5a090ABSOLUTE MSG_IN_DURING_DATA_IN = 0x75091ABSOLUTE DISCONNECT_DURING_DATA = 0x78092 93;94; Other interrupt conditions95; 96ABSOLUTE RESELECTED_DURING_SELECTION = 0x100097ABSOLUTE COMPLETED_SELECTION_AS_TARGET = 0x100198ABSOLUTE RESELECTION_IDENTIFIED = 0x100399;100; Fatal interrupt conditions. If you add to this, also add to the101; array of corresponding messages102;103ABSOLUTE FATAL = 0x2000104ABSOLUTE FATAL_UNEXPECTED_RESELECTION_MSG = 0x2000105ABSOLUTE FATAL_SEND_MSG = 0x2001106ABSOLUTE FATAL_NOT_MSG_IN_AFTER_SELECTION = 0x2002107ABSOLUTE FATAL_ILLEGAL_MSG_LENGTH = 0x2003108 109ABSOLUTE DEBUG_INTERRUPT = 0x3000110ABSOLUTE DEBUG_INTERRUPT1 = 0x3001111ABSOLUTE DEBUG_INTERRUPT2 = 0x3002112ABSOLUTE DEBUG_INTERRUPT3 = 0x3003113ABSOLUTE DEBUG_INTERRUPT4 = 0x3004114ABSOLUTE DEBUG_INTERRUPT5 = 0x3005115ABSOLUTE DEBUG_INTERRUPT6 = 0x3006116 117 118;119; SCSI Messages we interpret in the script120;121ABSOLUTE COMMAND_COMPLETE_MSG = 0x00122ABSOLUTE EXTENDED_MSG = 0x01123ABSOLUTE SDTR_MSG = 0x01124ABSOLUTE SAVE_DATA_PTRS_MSG = 0x02125ABSOLUTE RESTORE_DATA_PTRS_MSG = 0x03126ABSOLUTE WDTR_MSG = 0x03127ABSOLUTE DISCONNECT_MSG = 0x04128ABSOLUTE REJECT_MSG = 0x07129ABSOLUTE PARITY_ERROR_MSG = 0x09130ABSOLUTE SIMPLE_TAG_MSG = 0x20131ABSOLUTE IDENTIFY_MSG = 0x80132ABSOLUTE IDENTIFY_MSG_MASK = 0x7F133ABSOLUTE TWO_BYTE_MSG = 0x20134ABSOLUTE TWO_BYTE_MSG_MASK = 0x0F135 136; This is where the script begins137 138ENTRY StartUp139 140StartUp:141 SELECT ATN Device_ID, Reselect142 JUMP Finish, WHEN STATUS143 JUMP SendIdentifyMsg, IF MSG_OUT144 INT NOT_MSG_OUT_AFTER_SELECTION145 146Reselect:147 WAIT RESELECT SelectedAsTarget148 INT RESELECTED_DURING_SELECTION, WHEN MSG_IN149 INT FATAL_NOT_MSG_IN_AFTER_SELECTION150 151 ENTRY GetReselectionData152GetReselectionData:153 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN154 INT RESELECTION_IDENTIFIED155 156 ENTRY GetReselectionWithTag157GetReselectionWithTag:158 MOVE 3, ReceiveMsgAddress, WHEN MSG_IN159 INT RESELECTION_IDENTIFIED160 161 ENTRY SelectedAsTarget162SelectedAsTarget:163; Basically tell the selecting device that there's nothing here164 SET TARGET165 DISCONNECT166 CLEAR TARGET167 INT COMPLETED_SELECTION_AS_TARGET168;169; These are the messaging entries170;171; Send a message. Message count should be correctly patched172 ENTRY SendMessage173SendMessage:174 MOVE MessageCount, MessageLocation, WHEN MSG_OUT175ResumeSendMessage:176 RETURN, WHEN NOT MSG_OUT177 INT FATAL_SEND_MSG178 179 ENTRY SendMessagePhaseMismatch180SendMessagePhaseMismatch:181 CLEAR ACK182 JUMP ResumeSendMessage183;184; Receive a message. Need to identify the message to185; receive it correctly186 ENTRY ReceiveMessage187ReceiveMessage:188 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN189;190; Use this entry if we've just tried to look at the first byte191; of the message and want to process it further192ProcessReceiveMessage:193 JUMP ReceiveExtendedMessage, IF EXTENDED_MSG194 RETURN, IF NOT TWO_BYTE_MSG, AND MASK TWO_BYTE_MSG_MASK195 CLEAR ACK196 MOVE 1, ReceiveMsgAddress + 1, WHEN MSG_IN197 RETURN198ReceiveExtendedMessage:199 CLEAR ACK200 MOVE 1, ReceiveMsgAddress + 1, WHEN MSG_IN201 JUMP Receive1Byte, IF 0x01202 JUMP Receive2Byte, IF 0x02203 JUMP Receive3Byte, IF 0x03204 JUMP Receive4Byte, IF 0x04205 JUMP Receive5Byte, IF 0x05206 INT FATAL_ILLEGAL_MSG_LENGTH207Receive1Byte:208 CLEAR ACK209 MOVE 1, ReceiveMsgAddress + 2, WHEN MSG_IN210 RETURN211Receive2Byte:212 CLEAR ACK213 MOVE 2, ReceiveMsgAddress + 2, WHEN MSG_IN214 RETURN215Receive3Byte:216 CLEAR ACK217 MOVE 3, ReceiveMsgAddress + 2, WHEN MSG_IN218 RETURN219Receive4Byte:220 CLEAR ACK221 MOVE 4, ReceiveMsgAddress + 2, WHEN MSG_IN222 RETURN223Receive5Byte:224 CLEAR ACK225 MOVE 5, ReceiveMsgAddress + 2, WHEN MSG_IN226 RETURN227;228; Come here from the message processor to ignore the message229;230 ENTRY IgnoreMessage231IgnoreMessage:232 CLEAR ACK233 RETURN234;235; Come here to send a reply to a message236;237 ENTRY SendMessageWithATN238SendMessageWithATN:239 SET ATN240 CLEAR ACK241 JUMP SendMessage242 243SendIdentifyMsg:244 CALL SendMessage245 CLEAR ATN246 247IgnoreMsgBeforeCommand:248 CLEAR ACK249 ENTRY SendCommand250SendCommand:251 JUMP Finish, WHEN STATUS252 JUMP MsgInBeforeCommand, IF MSG_IN253 INT UNEXPECTED_PHASE_BEFORE_CMD, IF NOT CMD254 MOVE CommandCount, CommandAddress, WHEN CMD255ResumeSendCommand:256 JUMP Finish, WHEN STATUS257 JUMP MsgInAfterCmd, IF MSG_IN258 JUMP DataIn, IF DATA_IN259 JUMP DataOut, IF DATA_OUT260 INT UNEXPECTED_PHASE_AFTER_CMD261 262IgnoreMsgDuringData:263 CLEAR ACK264 ; fall through to MsgInDuringData265 266Entry MsgInDuringData267MsgInDuringData:268;269; Could be we have nothing more to transfer270;271 JUMP Finish, WHEN STATUS272 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN273 JUMP DisconnectDuringDataIn, IF DISCONNECT_MSG274 JUMP IgnoreMsgDuringData, IF SAVE_DATA_PTRS_MSG275 JUMP IgnoreMsgDuringData, IF RESTORE_DATA_PTRS_MSG276 INT MSG_IN_DURING_DATA_IN277 278MsgInAfterCmd:279 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN280 JUMP DisconnectAfterCmd, IF DISCONNECT_MSG281 JUMP IgnoreMsgInAfterCmd, IF SAVE_DATA_PTRS_MSG282 JUMP IgnoreMsgInAfterCmd, IF RESTORE_DATA_PTRS_MSG283 CALL ProcessReceiveMessage284 INT MSG_IN_AFTER_CMD285 CLEAR ACK286 JUMP ResumeSendCommand287 288IgnoreMsgInAfterCmd:289 CLEAR ACK290 JUMP ResumeSendCommand291 292DisconnectAfterCmd:293 CLEAR ACK294 WAIT DISCONNECT295 ENTRY Disconnect1296Disconnect1:297 INT DISCONNECT_AFTER_CMD298 ENTRY Disconnect2299Disconnect2:300; We return here after a reselection301 CLEAR ACK302 JUMP ResumeSendCommand303 304MsgInBeforeCommand:305 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN306 JUMP IgnoreMsgBeforeCommand, IF SAVE_DATA_PTRS_MSG307 JUMP IgnoreMsgBeforeCommand, IF RESTORE_DATA_PTRS_MSG308 CALL ProcessReceiveMessage309 INT MSG_IN_BEFORE_CMD310 CLEAR ACK311 JUMP SendCommand312 313DataIn:314 CALL SGScriptStartAddress315ResumeDataIn:316 JUMP Finish, WHEN STATUS317 JUMP MsgInAfterDataIn, IF MSG_IN318 JUMP DataInAfterDataIn, if DATA_IN319 INT MSG_OUT_AFTER_DATA_IN, if MSG_OUT320 INT UNEXPECTED_PHASE_AFTER_DATA_IN321 322DataInAfterDataIn:323 INT DATA_IN_AFTER_DATA_IN324 JUMP ResumeDataIn325 326DataOut:327 CALL SGScriptStartAddress328ResumeDataOut:329 JUMP Finish, WHEN STATUS330 JUMP MsgInAfterDataOut, IF MSG_IN331 INT UNEXPECTED_PHASE_AFTER_DATA_OUT332 333MsgInAfterDataIn:334 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN335 JUMP DisconnectAfterDataIn, IF DISCONNECT_MSG336 JUMP IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG337 JUMP IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG338 CALL ProcessReceiveMessage339 INT MSG_IN_AFTER_DATA_IN340 CLEAR ACK341 JUMP ResumeDataIn342 343DisconnectDuringDataIn:344 CLEAR ACK345 WAIT DISCONNECT346 ENTRY Disconnect3347Disconnect3:348 INT DISCONNECT_DURING_DATA349 ENTRY Disconnect4350Disconnect4:351; we return here after a reselection352 CLEAR ACK353 JUMP ResumeSendCommand354 355 356DisconnectAfterDataIn:357 CLEAR ACK358 WAIT DISCONNECT359 ENTRY Disconnect5360Disconnect5:361 INT DISCONNECT_AFTER_DATA362 ENTRY Disconnect6363Disconnect6:364; we return here after a reselection365 CLEAR ACK366 JUMP ResumeDataIn367 368MsgInAfterDataOut:369 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN370 JUMP DisconnectAfterDataOut, if DISCONNECT_MSG371 JUMP IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG372 JUMP IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG373 CALL ProcessReceiveMessage374 INT MSG_IN_AFTER_DATA_OUT375 CLEAR ACK376 JUMP ResumeDataOut377 378IgnoreMsgAfterData:379 CLEAR ACK380; Data in and out do the same thing on resume, so pick one381 JUMP ResumeDataIn382 383DisconnectAfterDataOut:384 CLEAR ACK385 WAIT DISCONNECT386 ENTRY Disconnect7387Disconnect7:388 INT DISCONNECT_AFTER_DATA389 ENTRY Disconnect8390Disconnect8:391; we return here after a reselection392 CLEAR ACK393 JUMP ResumeDataOut394 395Finish:396 MOVE 1, StatusAddress, WHEN STATUS397 INT NOT_MSG_IN_AFTER_STATUS, WHEN NOT MSG_IN398 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN399 JUMP FinishCommandComplete, IF COMMAND_COMPLETE_MSG400 CALL ProcessReceiveMessage401 INT MSG_IN_AFTER_STATUS402 ENTRY FinishCommandComplete403FinishCommandComplete:404 CLEAR ACK405 WAIT DISCONNECT406 ENTRY Finish1407Finish1:408 INT GOOD_STATUS_AFTER_STATUS409 ENTRY Finish2410Finish2:411 412