1 ; Script for the NCR (or symbios) 53c700 and 53c700-66 chip
3 ; Copyright (C) 2001 James.Bottomley@HansenPartnership.com
4 ;;-----------------------------------------------------------------------------
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.
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.
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.
20 ;;-----------------------------------------------------------------------------
22 ; This script is designed to be modified for the particular command in
23 ; operation. The particular variables pertaining to the commands are:
25 ABSOLUTE Device_ID = 0 ; ID of target for command
26 ABSOLUTE MessageCount = 0 ; Number of bytes in message
27 ABSOLUTE MessageLocation = 0 ; Addr of message
28 ABSOLUTE CommandCount = 0 ; Number of bytes in command
29 ABSOLUTE CommandAddress = 0 ; Addr of Command
30 ABSOLUTE StatusAddress = 0 ; Addr to receive status return
31 ABSOLUTE ReceiveMsgAddress = 0 ; Addr to receive msg
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
39 ABSOLUTE SGScriptStartAddress = 0
41 ; The following represent status interrupts we use 3 hex digits for
45 ABSOLUTE AFTER_SELECTION = 0x100
46 ABSOLUTE BEFORE_CMD = 0x200
47 ABSOLUTE AFTER_CMD = 0x300
48 ABSOLUTE AFTER_STATUS = 0x400
49 ABSOLUTE AFTER_DATA_IN = 0x500
50 ABSOLUTE AFTER_DATA_OUT = 0x600
51 ABSOLUTE DURING_DATA_IN = 0x700
54 ABSOLUTE NOT_MSG_OUT = 0x10
55 ABSOLUTE UNEXPECTED_PHASE = 0x20
56 ABSOLUTE NOT_MSG_IN = 0x30
57 ABSOLUTE UNEXPECTED_MSG = 0x40
58 ABSOLUTE MSG_IN = 0x50
59 ABSOLUTE SDTR_MSG_R = 0x60
60 ABSOLUTE REJECT_MSG_R = 0x70
61 ABSOLUTE DISCONNECT = 0x80
62 ABSOLUTE MSG_OUT = 0x90
63 ABSOLUTE WDTR_MSG_R = 0xA0
66 ABSOLUTE GOOD_STATUS = 0x1
68 ; Combinations, since the script assembler can't process |
69 ABSOLUTE NOT_MSG_OUT_AFTER_SELECTION = 0x110
70 ABSOLUTE UNEXPECTED_PHASE_BEFORE_CMD = 0x220
71 ABSOLUTE UNEXPECTED_PHASE_AFTER_CMD = 0x320
72 ABSOLUTE NOT_MSG_IN_AFTER_STATUS = 0x430
73 ABSOLUTE GOOD_STATUS_AFTER_STATUS = 0x401
74 ABSOLUTE UNEXPECTED_PHASE_AFTER_DATA_IN = 0x520
75 ABSOLUTE UNEXPECTED_PHASE_AFTER_DATA_OUT = 0x620
76 ABSOLUTE UNEXPECTED_MSG_BEFORE_CMD = 0x240
77 ABSOLUTE MSG_IN_BEFORE_CMD = 0x250
78 ABSOLUTE MSG_IN_AFTER_CMD = 0x350
79 ABSOLUTE SDTR_MSG_BEFORE_CMD = 0x260
80 ABSOLUTE REJECT_MSG_BEFORE_CMD = 0x270
81 ABSOLUTE DISCONNECT_AFTER_CMD = 0x380
82 ABSOLUTE SDTR_MSG_AFTER_CMD = 0x360
83 ABSOLUTE WDTR_MSG_AFTER_CMD = 0x3A0
84 ABSOLUTE MSG_IN_AFTER_STATUS = 0x440
85 ABSOLUTE DISCONNECT_AFTER_DATA = 0x580
86 ABSOLUTE MSG_IN_AFTER_DATA_IN = 0x550
87 ABSOLUTE MSG_IN_AFTER_DATA_OUT = 0x650
88 ABSOLUTE MSG_OUT_AFTER_DATA_IN = 0x590
89 ABSOLUTE DATA_IN_AFTER_DATA_IN = 0x5a0
90 ABSOLUTE MSG_IN_DURING_DATA_IN = 0x750
91 ABSOLUTE DISCONNECT_DURING_DATA = 0x780
94 ; Other interrupt conditions
96 ABSOLUTE RESELECTED_DURING_SELECTION = 0x1000
97 ABSOLUTE COMPLETED_SELECTION_AS_TARGET = 0x1001
98 ABSOLUTE RESELECTION_IDENTIFIED = 0x1003
100 ; Fatal interrupt conditions. If you add to this, also add to the
101 ; array of corresponding messages
103 ABSOLUTE FATAL = 0x2000
104 ABSOLUTE FATAL_UNEXPECTED_RESELECTION_MSG = 0x2000
105 ABSOLUTE FATAL_SEND_MSG = 0x2001
106 ABSOLUTE FATAL_NOT_MSG_IN_AFTER_SELECTION = 0x2002
107 ABSOLUTE FATAL_ILLEGAL_MSG_LENGTH = 0x2003
109 ABSOLUTE DEBUG_INTERRUPT = 0x3000
110 ABSOLUTE DEBUG_INTERRUPT1 = 0x3001
111 ABSOLUTE DEBUG_INTERRUPT2 = 0x3002
112 ABSOLUTE DEBUG_INTERRUPT3 = 0x3003
113 ABSOLUTE DEBUG_INTERRUPT4 = 0x3004
114 ABSOLUTE DEBUG_INTERRUPT5 = 0x3005
115 ABSOLUTE DEBUG_INTERRUPT6 = 0x3006
119 ; SCSI Messages we interpret in the script
121 ABSOLUTE COMMAND_COMPLETE_MSG = 0x00
122 ABSOLUTE EXTENDED_MSG = 0x01
123 ABSOLUTE SDTR_MSG = 0x01
124 ABSOLUTE SAVE_DATA_PTRS_MSG = 0x02
125 ABSOLUTE RESTORE_DATA_PTRS_MSG = 0x03
126 ABSOLUTE WDTR_MSG = 0x03
127 ABSOLUTE DISCONNECT_MSG = 0x04
128 ABSOLUTE REJECT_MSG = 0x07
129 ABSOLUTE PARITY_ERROR_MSG = 0x09
130 ABSOLUTE SIMPLE_TAG_MSG = 0x20
131 ABSOLUTE IDENTIFY_MSG = 0x80
132 ABSOLUTE IDENTIFY_MSG_MASK = 0x7F
133 ABSOLUTE TWO_BYTE_MSG = 0x20
134 ABSOLUTE TWO_BYTE_MSG_MASK = 0x0F
136 ; This is where the script begins
141 SELECT ATN Device_ID, Reselect
142 JUMP Finish, WHEN STATUS
143 JUMP SendIdentifyMsg, IF MSG_OUT
144 INT NOT_MSG_OUT_AFTER_SELECTION
147 WAIT RESELECT SelectedAsTarget
148 INT RESELECTED_DURING_SELECTION, WHEN MSG_IN
149 INT FATAL_NOT_MSG_IN_AFTER_SELECTION
151 ENTRY GetReselectionData
153 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN
154 INT RESELECTION_IDENTIFIED
156 ENTRY GetReselectionWithTag
157 GetReselectionWithTag:
158 MOVE 3, ReceiveMsgAddress, WHEN MSG_IN
159 INT RESELECTION_IDENTIFIED
161 ENTRY SelectedAsTarget
163 ; Basically tell the selecting device that there's nothing here
167 INT COMPLETED_SELECTION_AS_TARGET
169 ; These are the messaging entries
171 ; Send a message. Message count should be correctly patched
174 MOVE MessageCount, MessageLocation, WHEN MSG_OUT
176 RETURN, WHEN NOT MSG_OUT
179 ENTRY SendMessagePhaseMismatch
180 SendMessagePhaseMismatch:
182 JUMP ResumeSendMessage
184 ; Receive a message. Need to identify the message to
185 ; receive it correctly
188 MOVE 1, ReceiveMsgAddress, WHEN MSG_IN
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
192 ProcessReceiveMessage:
193 JUMP ReceiveExtendedMessage, IF EXTENDED_MSG
194 RETURN, IF NOT TWO_BYTE_MSG, AND MASK TWO_BYTE_MSG_MASK
196 MOVE 1, ReceiveMsgAddress + 1, WHEN MSG_IN
198 ReceiveExtendedMessage:
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
209 MOVE 1, ReceiveMsgAddress + 2, WHEN MSG_IN
213 MOVE 2, ReceiveMsgAddress + 2, WHEN MSG_IN
217 MOVE 3, ReceiveMsgAddress + 2, WHEN MSG_IN
221 MOVE 4, ReceiveMsgAddress + 2, WHEN MSG_IN
225 MOVE 5, ReceiveMsgAddress + 2, WHEN MSG_IN
228 ; Come here from the message processor to ignore the message
235 ; Come here to send a reply to a message
237 ENTRY SendMessageWithATN
247 IgnoreMsgBeforeCommand:
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
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
264 ; fall through to MsgInDuringData
266 Entry MsgInDuringData
269 ; Could be we have nothing more to transfer
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
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
286 JUMP ResumeSendCommand
290 JUMP ResumeSendCommand
297 INT DISCONNECT_AFTER_CMD
300 ; We return here after a reselection
302 JUMP ResumeSendCommand
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
314 CALL SGScriptStartAddress
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
323 INT DATA_IN_AFTER_DATA_IN
327 CALL SGScriptStartAddress
329 JUMP Finish, WHEN STATUS
330 JUMP MsgInAfterDataOut, IF MSG_IN
331 INT UNEXPECTED_PHASE_AFTER_DATA_OUT
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
343 DisconnectDuringDataIn:
348 INT DISCONNECT_DURING_DATA
351 ; we return here after a reselection
353 JUMP ResumeSendCommand
356 DisconnectAfterDataIn:
361 INT DISCONNECT_AFTER_DATA
364 ; we return here after a reselection
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
380 ; Data in and out do the same thing on resume, so pick one
383 DisconnectAfterDataOut:
388 INT DISCONNECT_AFTER_DATA
391 ; we return here after a reselection
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
403 FinishCommandComplete:
408 INT GOOD_STATUS_AFTER_STATUS