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