blob: ec822e3b7a27b1e6df94338aa87f08a0426b4c75 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001; 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
Lucas De Marchi25985ed2011-03-30 22:57:33 -030034; SG components is preceded by a script fragment which moves the
Linus Torvalds1da177e2005-04-16 15:20:36 -070035; 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