1; Script for the NCR (or symbios) 53c700 and 53c700-66 chip 2; 3; Copyright (C) 2001 James.Bottomley@HansenPartnership.com 4;;----------------------------------------------------------------------------- 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 9;; (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 of 13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14;; GNU General Public License for more details. 15;; 16;; You should have received a copy of the GNU General Public License 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; 22; This script is designed to be modified for the particular command in 23; operation. The particular variables pertaining to the commands are: 24; 25ABSOLUTE Device_ID = 0 ; ID of target for command 26ABSOLUTE MessageCount = 0 ; Number of bytes in message 27ABSOLUTE MessageLocation = 0 ; Addr of message 28ABSOLUTE CommandCount = 0 ; Number of bytes in command 29ABSOLUTE CommandAddress = 0 ; Addr of Command 30ABSOLUTE StatusAddress = 0 ; Addr to receive status return 31ABSOLUTE ReceiveMsgAddress = 0 ; Addr to receive msg 32; 33; This is the magic component for handling scatter-gather. Each of the 34; SG components is preceded by a script fragment which moves the 35; necessary amount of data and jumps to the next SG segment. The final 36; SG segment jumps back to . However, this address is the first SG script 37; segment. 38; 39ABSOLUTE SGScriptStartAddress = 0 40 41; The following represent status interrupts we use 3 hex digits for 42; this: 0xPRS where 43 44; P: 45ABSOLUTE AFTER_SELECTION = 0x100 46ABSOLUTE BEFORE_CMD = 0x200 47ABSOLUTE AFTER_CMD = 0x300 48ABSOLUTE AFTER_STATUS = 0x400 49ABSOLUTE AFTER_DATA_IN = 0x500 50ABSOLUTE AFTER_DATA_OUT = 0x600 51ABSOLUTE DURING_DATA_IN = 0x700 52 53; R: 54ABSOLUTE NOT_MSG_OUT = 0x10 55ABSOLUTE UNEXPECTED_PHASE = 0x20 56ABSOLUTE NOT_MSG_IN = 0x30 57ABSOLUTE UNEXPECTED_MSG = 0x40 58ABSOLUTE MSG_IN = 0x50 59ABSOLUTE SDTR_MSG_R = 0x60 60ABSOLUTE REJECT_MSG_R = 0x70 61ABSOLUTE DISCONNECT = 0x80 62ABSOLUTE MSG_OUT = 0x90 63ABSOLUTE WDTR_MSG_R = 0xA0 64 65; S: 66ABSOLUTE GOOD_STATUS = 0x1 67 68; Combinations, since the script assembler can't process | 69ABSOLUTE NOT_MSG_OUT_AFTER_SELECTION = 0x110 70ABSOLUTE UNEXPECTED_PHASE_BEFORE_CMD = 0x220 71ABSOLUTE UNEXPECTED_PHASE_AFTER_CMD = 0x320 72ABSOLUTE NOT_MSG_IN_AFTER_STATUS = 0x430 73ABSOLUTE GOOD_STATUS_AFTER_STATUS = 0x401 74ABSOLUTE UNEXPECTED_PHASE_AFTER_DATA_IN = 0x520 75ABSOLUTE UNEXPECTED_PHASE_AFTER_DATA_OUT = 0x620 76ABSOLUTE UNEXPECTED_MSG_BEFORE_CMD = 0x240 77ABSOLUTE MSG_IN_BEFORE_CMD = 0x250 78ABSOLUTE MSG_IN_AFTER_CMD = 0x350 79ABSOLUTE SDTR_MSG_BEFORE_CMD = 0x260 80ABSOLUTE REJECT_MSG_BEFORE_CMD = 0x270 81ABSOLUTE DISCONNECT_AFTER_CMD = 0x380 82ABSOLUTE SDTR_MSG_AFTER_CMD = 0x360 83ABSOLUTE WDTR_MSG_AFTER_CMD = 0x3A0 84ABSOLUTE MSG_IN_AFTER_STATUS = 0x440 85ABSOLUTE DISCONNECT_AFTER_DATA = 0x580 86ABSOLUTE MSG_IN_AFTER_DATA_IN = 0x550 87ABSOLUTE MSG_IN_AFTER_DATA_OUT = 0x650 88ABSOLUTE MSG_OUT_AFTER_DATA_IN = 0x590 89ABSOLUTE DATA_IN_AFTER_DATA_IN = 0x5a0 90ABSOLUTE MSG_IN_DURING_DATA_IN = 0x750 91ABSOLUTE DISCONNECT_DURING_DATA = 0x780 92 93; 94; Other interrupt conditions 95; 96ABSOLUTE RESELECTED_DURING_SELECTION = 0x1000 97ABSOLUTE COMPLETED_SELECTION_AS_TARGET = 0x1001 98ABSOLUTE RESELECTION_IDENTIFIED = 0x1003 99; 100; Fatal interrupt conditions. If you add to this, also add to the 101; array of corresponding messages 102; 103ABSOLUTE FATAL = 0x2000 104ABSOLUTE FATAL_UNEXPECTED_RESELECTION_MSG = 0x2000 105ABSOLUTE FATAL_SEND_MSG = 0x2001 106ABSOLUTE FATAL_NOT_MSG_IN_AFTER_SELECTION = 0x2002 107ABSOLUTE FATAL_ILLEGAL_MSG_LENGTH = 0x2003 108 109ABSOLUTE DEBUG_INTERRUPT = 0x3000 110ABSOLUTE DEBUG_INTERRUPT1 = 0x3001 111ABSOLUTE DEBUG_INTERRUPT2 = 0x3002 112ABSOLUTE DEBUG_INTERRUPT3 = 0x3003 113ABSOLUTE DEBUG_INTERRUPT4 = 0x3004 114ABSOLUTE DEBUG_INTERRUPT5 = 0x3005 115ABSOLUTE DEBUG_INTERRUPT6 = 0x3006 116 117 118; 119; SCSI Messages we interpret in the script 120; 121ABSOLUTE COMMAND_COMPLETE_MSG = 0x00 122ABSOLUTE EXTENDED_MSG = 0x01 123ABSOLUTE SDTR_MSG = 0x01 124ABSOLUTE SAVE_DATA_PTRS_MSG = 0x02 125ABSOLUTE RESTORE_DATA_PTRS_MSG = 0x03 126ABSOLUTE WDTR_MSG = 0x03 127ABSOLUTE DISCONNECT_MSG = 0x04 128ABSOLUTE REJECT_MSG = 0x07 129ABSOLUTE PARITY_ERROR_MSG = 0x09 130ABSOLUTE SIMPLE_TAG_MSG = 0x20 131ABSOLUTE IDENTIFY_MSG = 0x80 132ABSOLUTE IDENTIFY_MSG_MASK = 0x7F 133ABSOLUTE TWO_BYTE_MSG = 0x20 134ABSOLUTE TWO_BYTE_MSG_MASK = 0x0F 135 136; This is where the script begins 137 138ENTRY StartUp 139 140StartUp: 141 SELECT ATN Device_ID, Reselect 142 JUMP Finish, WHEN STATUS 143 JUMP SendIdentifyMsg, IF MSG_OUT 144 INT NOT_MSG_OUT_AFTER_SELECTION 145 146Reselect: 147 WAIT RESELECT SelectedAsTarget 148 INT RESELECTED_DURING_SELECTION, WHEN MSG_IN 149 INT FATAL_NOT_MSG_IN_AFTER_SELECTION 150 151 ENTRY GetReselectionData 152GetReselectionData: 153 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 154 INT RESELECTION_IDENTIFIED 155 156 ENTRY GetReselectionWithTag 157GetReselectionWithTag: 158 MOVE 3, ReceiveMsgAddress, WHEN MSG_IN 159 INT RESELECTION_IDENTIFIED 160 161 ENTRY SelectedAsTarget 162SelectedAsTarget: 163; Basically tell the selecting device that there's nothing here 164 SET TARGET 165 DISCONNECT 166 CLEAR TARGET 167 INT COMPLETED_SELECTION_AS_TARGET 168; 169; These are the messaging entries 170; 171; Send a message. Message count should be correctly patched 172 ENTRY SendMessage 173SendMessage: 174 MOVE MessageCount, MessageLocation, WHEN MSG_OUT 175ResumeSendMessage: 176 RETURN, WHEN NOT MSG_OUT 177 INT FATAL_SEND_MSG 178 179 ENTRY SendMessagePhaseMismatch 180SendMessagePhaseMismatch: 181 CLEAR ACK 182 JUMP ResumeSendMessage 183; 184; Receive a message. Need to identify the message to 185; receive it correctly 186 ENTRY ReceiveMessage 187ReceiveMessage: 188 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 189; 190; Use this entry if we've just tried to look at the first byte 191; of the message and want to process it further 192ProcessReceiveMessage: 193 JUMP ReceiveExtendedMessage, IF EXTENDED_MSG 194 RETURN, IF NOT TWO_BYTE_MSG, AND MASK TWO_BYTE_MSG_MASK 195 CLEAR ACK 196 MOVE 1, ReceiveMsgAddress + 1, WHEN MSG_IN 197 RETURN 198ReceiveExtendedMessage: 199 CLEAR ACK 200 MOVE 1, ReceiveMsgAddress + 1, WHEN MSG_IN 201 JUMP Receive1Byte, IF 0x01 202 JUMP Receive2Byte, IF 0x02 203 JUMP Receive3Byte, IF 0x03 204 JUMP Receive4Byte, IF 0x04 205 JUMP Receive5Byte, IF 0x05 206 INT FATAL_ILLEGAL_MSG_LENGTH 207Receive1Byte: 208 CLEAR ACK 209 MOVE 1, ReceiveMsgAddress + 2, WHEN MSG_IN 210 RETURN 211Receive2Byte: 212 CLEAR ACK 213 MOVE 2, ReceiveMsgAddress + 2, WHEN MSG_IN 214 RETURN 215Receive3Byte: 216 CLEAR ACK 217 MOVE 3, ReceiveMsgAddress + 2, WHEN MSG_IN 218 RETURN 219Receive4Byte: 220 CLEAR ACK 221 MOVE 4, ReceiveMsgAddress + 2, WHEN MSG_IN 222 RETURN 223Receive5Byte: 224 CLEAR ACK 225 MOVE 5, ReceiveMsgAddress + 2, WHEN MSG_IN 226 RETURN 227; 228; Come here from the message processor to ignore the message 229; 230 ENTRY IgnoreMessage 231IgnoreMessage: 232 CLEAR ACK 233 RETURN 234; 235; Come here to send a reply to a message 236; 237 ENTRY SendMessageWithATN 238SendMessageWithATN: 239 SET ATN 240 CLEAR ACK 241 JUMP SendMessage 242 243SendIdentifyMsg: 244 CALL SendMessage 245 CLEAR ATN 246 247IgnoreMsgBeforeCommand: 248 CLEAR ACK 249 ENTRY SendCommand 250SendCommand: 251 JUMP Finish, WHEN STATUS 252 JUMP MsgInBeforeCommand, IF MSG_IN 253 INT UNEXPECTED_PHASE_BEFORE_CMD, IF NOT CMD 254 MOVE CommandCount, CommandAddress, WHEN CMD 255ResumeSendCommand: 256 JUMP Finish, WHEN STATUS 257 JUMP MsgInAfterCmd, IF MSG_IN 258 JUMP DataIn, IF DATA_IN 259 JUMP DataOut, IF DATA_OUT 260 INT UNEXPECTED_PHASE_AFTER_CMD 261 262IgnoreMsgDuringData: 263 CLEAR ACK 264 ; fall through to MsgInDuringData 265 266Entry MsgInDuringData 267MsgInDuringData: 268; 269; Could be we have nothing more to transfer 270; 271 JUMP Finish, WHEN STATUS 272 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 273 JUMP DisconnectDuringDataIn, IF DISCONNECT_MSG 274 JUMP IgnoreMsgDuringData, IF SAVE_DATA_PTRS_MSG 275 JUMP IgnoreMsgDuringData, IF RESTORE_DATA_PTRS_MSG 276 INT MSG_IN_DURING_DATA_IN 277 278MsgInAfterCmd: 279 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 280 JUMP DisconnectAfterCmd, IF DISCONNECT_MSG 281 JUMP IgnoreMsgInAfterCmd, IF SAVE_DATA_PTRS_MSG 282 JUMP IgnoreMsgInAfterCmd, IF RESTORE_DATA_PTRS_MSG 283 CALL ProcessReceiveMessage 284 INT MSG_IN_AFTER_CMD 285 CLEAR ACK 286 JUMP ResumeSendCommand 287 288IgnoreMsgInAfterCmd: 289 CLEAR ACK 290 JUMP ResumeSendCommand 291 292DisconnectAfterCmd: 293 CLEAR ACK 294 WAIT DISCONNECT 295 ENTRY Disconnect1 296Disconnect1: 297 INT DISCONNECT_AFTER_CMD 298 ENTRY Disconnect2 299Disconnect2: 300; We return here after a reselection 301 CLEAR ACK 302 JUMP ResumeSendCommand 303 304MsgInBeforeCommand: 305 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 306 JUMP IgnoreMsgBeforeCommand, IF SAVE_DATA_PTRS_MSG 307 JUMP IgnoreMsgBeforeCommand, IF RESTORE_DATA_PTRS_MSG 308 CALL ProcessReceiveMessage 309 INT MSG_IN_BEFORE_CMD 310 CLEAR ACK 311 JUMP SendCommand 312 313DataIn: 314 CALL SGScriptStartAddress 315ResumeDataIn: 316 JUMP Finish, WHEN STATUS 317 JUMP MsgInAfterDataIn, IF MSG_IN 318 JUMP DataInAfterDataIn, if DATA_IN 319 INT MSG_OUT_AFTER_DATA_IN, if MSG_OUT 320 INT UNEXPECTED_PHASE_AFTER_DATA_IN 321 322DataInAfterDataIn: 323 INT DATA_IN_AFTER_DATA_IN 324 JUMP ResumeDataIn 325 326DataOut: 327 CALL SGScriptStartAddress 328ResumeDataOut: 329 JUMP Finish, WHEN STATUS 330 JUMP MsgInAfterDataOut, IF MSG_IN 331 INT UNEXPECTED_PHASE_AFTER_DATA_OUT 332 333MsgInAfterDataIn: 334 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 335 JUMP DisconnectAfterDataIn, IF DISCONNECT_MSG 336 JUMP IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG 337 JUMP IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG 338 CALL ProcessReceiveMessage 339 INT MSG_IN_AFTER_DATA_IN 340 CLEAR ACK 341 JUMP ResumeDataIn 342 343DisconnectDuringDataIn: 344 CLEAR ACK 345 WAIT DISCONNECT 346 ENTRY Disconnect3 347Disconnect3: 348 INT DISCONNECT_DURING_DATA 349 ENTRY Disconnect4 350Disconnect4: 351; we return here after a reselection 352 CLEAR ACK 353 JUMP ResumeSendCommand 354 355 356DisconnectAfterDataIn: 357 CLEAR ACK 358 WAIT DISCONNECT 359 ENTRY Disconnect5 360Disconnect5: 361 INT DISCONNECT_AFTER_DATA 362 ENTRY Disconnect6 363Disconnect6: 364; we return here after a reselection 365 CLEAR ACK 366 JUMP ResumeDataIn 367 368MsgInAfterDataOut: 369 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 370 JUMP DisconnectAfterDataOut, if DISCONNECT_MSG 371 JUMP IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG 372 JUMP IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG 373 CALL ProcessReceiveMessage 374 INT MSG_IN_AFTER_DATA_OUT 375 CLEAR ACK 376 JUMP ResumeDataOut 377 378IgnoreMsgAfterData: 379 CLEAR ACK 380; Data in and out do the same thing on resume, so pick one 381 JUMP ResumeDataIn 382 383DisconnectAfterDataOut: 384 CLEAR ACK 385 WAIT DISCONNECT 386 ENTRY Disconnect7 387Disconnect7: 388 INT DISCONNECT_AFTER_DATA 389 ENTRY Disconnect8 390Disconnect8: 391; we return here after a reselection 392 CLEAR ACK 393 JUMP ResumeDataOut 394 395Finish: 396 MOVE 1, StatusAddress, WHEN STATUS 397 INT NOT_MSG_IN_AFTER_STATUS, WHEN NOT MSG_IN 398 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN 399 JUMP FinishCommandComplete, IF COMMAND_COMPLETE_MSG 400 CALL ProcessReceiveMessage 401 INT MSG_IN_AFTER_STATUS 402 ENTRY FinishCommandComplete 403FinishCommandComplete: 404 CLEAR ACK 405 WAIT DISCONNECT 406 ENTRY Finish1 407Finish1: 408 INT GOOD_STATUS_AFTER_STATUS 409 ENTRY Finish2 410Finish2: 411 412