FreeBSD/Linux Kernel Cross Reference
sys/pc/sd53c8xx.n
1 // NCR 53c8xx driver for Plan 9
2 // Nigel Roles (nigel@9fs.org)
3 //
4 // Microcode
5 //
6 // 27/5/02 Fixed problems with transfers >= 256 * 512
7 //
8 // 13/3/01 Fixed microcode to support targets > 7
9 //
10
11 extern scsi_id_buf
12 extern msg_out_buf
13 extern cmd_buf
14 extern data_buf
15 extern status_buf
16 extern msgin_buf
17 extern dsa_0
18 extern dsa_1
19 extern dsa_head
20 extern ssid_mask
21
22 SIR_MSG_IO_COMPLETE = 0
23 error_not_cmd_complete = 1
24 error_disconnected = 2
25 error_reselected = 3
26 error_unexpected_phase = 4
27 error_weird_message = 5
28 SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT = 6
29 error_not_identify_after_reselect = 7
30 error_too_much_data = 8
31 error_too_little_data = 9
32 SIR_MSG_REJECT = 10
33 SIR_MSG_SDTR = 11
34 SIR_EV_RESPONSE_OK = 12
35 error_sigp_set = 13
36 SIR_EV_PHASE_SWITCH_AFTER_ID = 14
37 SIR_MSG_WDTR = 15
38 SIR_MSG_IGNORE_WIDE_RESIDUE = 16
39 SIR_NOTIFY_DISC = 100
40 SIR_NOTIFY_RESELECT = 101
41 SIR_NOTIFY_MSG_IN = 102
42 SIR_NOTIFY_STATUS = 103
43 SIR_NOTIFY_DUMP = 104
44 SIR_NOTIFY_DUMP2 = 105
45 SIR_NOTIFY_SIGP = 106
46 SIR_NOTIFY_ISSUE = 107
47 SIR_NOTIFY_WAIT_RESELECT = 108
48 SIR_NOTIFY_ISSUE_CHECK = 109
49 SIR_NOTIFY_DUMP_NEXT_CODE = 110
50 SIR_NOTIFY_COMMAND = 111
51 SIR_NOTIFY_DATA_IN = 112
52 SIR_NOTIFY_DATA_OUT = 113
53 SIR_NOTIFY_BLOCK_DATA_IN = 114
54 SIR_NOTIFY_WSR = 115
55 SIR_NOTIFY_LOAD_SYNC = 116
56 SIR_NOTIFY_RESELECTED_ON_SELECT = 117
57 SIR_NOTIFY_LOAD_STATE = 118
58
59 STATE_FREE = 0
60 STATE_ALLOCATED = 1
61 STATE_ISSUE = 2
62 STATE_DISCONNECTED = 3
63 STATE_DONE = 4
64 STATE_END = 5
65
66 RESULT_OK = 0
67
68 MSG_IDENTIFY = 0x80
69 MSG_DISCONNECT = 0x04
70 MSG_SAVE_DATA_POINTER = 0x02
71 MSG_RESTORE_POINTERS = 0x03
72 MSG_IGNORE_WIDE_RESIDUE = 0x23
73 X_MSG = 0x01
74 X_MSG_SDTR = 0x01
75 X_MSG_WDTR = 0x03
76 MSG_REJECT = 0x07
77
78 BSIZE = 512
79 //BSIZE=4096
80
81 // idle:
82 jump wait_for_reselection
83 start:
84 call load_sync
85 // move 13 to ctest0
86 // int SIR_NOTIFY_ISSUE
87 clear target
88 select atn from scsi_id_buf, reselected_on_select // do I need to clear ATN here?
89 jump start1, when msg_in // why is this here?
90 start1:
91 // move 14 to ctest0
92 move from msg_out_buf, when msg_out
93 id_out_mismatch:
94 jump start1, when msg_out // repeat on parity grounds
95 jump to_decisions, when not cmd
96 cmd_phase:
97 // int SIR_NOTIFY_COMMAND
98 clear atn
99 move from cmd_buf, when cmd
100 cmd_out_mismatch:
101 jump to_decisions, when not data_in
102 data_in_phase:
103 move memory 4, state, scratcha
104 move memory 4, dmaaddr, scratchb
105 // int SIR_NOTIFY_DATA_IN
106 data_in_block_loop:
107 move scratcha2 to sfbr
108 jump data_in_normal, if 0
109 // int SIR_NOTIFY_BLOCK_DATA_IN
110 move BSIZE, ptr dmaaddr, when data_in // transfer BSIZE bytes
111 data_in_block_mismatch:
112 move scratchb1 + BSIZE / 256 to scratchb1 // add BSIZE to scratchb
113 move scratchb2 + 0 to scratchb2 with carry
114 move scratchb3 + 0 to scratchb3 with carry
115 move scratcha2 + 255 to scratcha2 // sub one from block count
116 move memory 4, scratchb, dmaaddr // save latest dmaddr
117 jump data_in_block_loop, when data_in
118 move memory 4, scratcha, state // save latest state
119 call save_state
120 jump to_decisions
121 data_block_mismatch_recover:
122 move memory 4, scratchb, dmaaddr // save latest dmaddr
123 data_mismatch_recover:
124 move memory 4, scratcha, state // save latest state
125 jump to_decisions // no need to save
126 // as interrupt routine
127 // did this
128 data_in_normal:
129 move scratcha3 to sfbr
130 int error_too_much_data, if not 0
131 move from data_buf, when data_in
132 data_in_mismatch:
133 move 2 to scratcha3
134 move memory 4, scratcha, state
135 call save_state
136 jump post_data_to_decisions
137 data_out_phase:
138 // int SIR_NOTIFY_DATA_OUT
139 move memory 4, state, scratcha
140 move memory 4, dmaaddr, scratchb
141 data_out_block_loop:
142 move scratcha2 to sfbr
143 jump data_out_normal, if 0
144 move memory 4, dmaaddr, scratchb
145 move BSIZE, ptr dmaaddr, when data_out // transfer BSIZE bytes
146 data_out_block_mismatch:
147 move scratchb1 + BSIZE / 256 to scratchb1 // add BSIZE to scratchb
148 move scratchb2 + 0 to scratchb2 with carry
149 move scratchb3 + 0 to scratchb3 with carry
150 move scratcha2 + 255 to scratcha2 // sub one from block count
151 move memory 4, scratchb, dmaaddr // save latest dmaddr
152 jump data_out_block_loop, when data_out
153 move memory 4, scratcha, state // save latest state
154 jump to_decisions
155 data_out_normal:
156 move scratcha3 to sfbr
157 int error_too_little_data, if not 0
158 move from data_buf, when data_out
159 data_out_mismatch:
160 move 2 to scratcha3
161 move memory 4, scratcha, state
162 call save_state
163 jump post_data_to_decisions
164 status_phase:
165 move from status_buf, when status
166 // int SIR_NOTIFY_STATUS
167 int error_unexpected_phase, when not msg_in
168 msg_in_phase:
169 move 1, scratcha, when msg_in
170 // int SIR_NOTIFY_MSG_IN
171 jump rejected, if MSG_REJECT
172 msg_in_not_reject:
173 jump disconnected, if MSG_DISCONNECT
174 jump msg_in_skip, if MSG_SAVE_DATA_POINTER
175 jump msg_in_skip, if MSG_RESTORE_POINTERS
176 jump ignore_wide, if MSG_IGNORE_WIDE_RESIDUE
177 jump extended, if X_MSG
178 int error_not_cmd_complete, if not 0
179 move scntl2&0x7e to scntl2 // take care not to clear WSR
180 clear ack
181 wait disconnect
182 // update state
183 move memory 4, state, scratcha
184 move STATE_DONE to scratcha0
185 move RESULT_OK to scratcha1
186 move memory 4, scratcha, state
187 call save_state
188 // int SIR_MSG_IO_COMPLETE
189 intfly 0
190 jump issue_check
191
192 rejected:
193 int SIR_MSG_REJECT
194 clear ack
195 jump to_decisions
196 msg_in_skip:
197 clear ack
198 jump to_decisions
199
200 extended:
201 clear ack
202 int error_unexpected_phase, when not msg_in
203 move 1, scratcha1, when msg_in
204 jump ext_3, if 3
205 jump ext_2, if 2
206 int error_weird_message, if not 1
207 ext_1:
208 clear ack
209 int error_unexpected_phase, when not msg_in
210 move 1, scratcha1, when msg_in
211 jump ext_done
212
213 ext_3: clear ack
214 int error_unexpected_phase, when not msg_in
215 move 1, scratcha1, when msg_in
216 clear ack
217 int error_unexpected_phase, when not msg_in
218 move 1, scratcha2, when msg_in
219 clear ack
220 int error_unexpected_phase, when not msg_in
221 move 1, scratcha3, when msg_in
222 move scratcha1 to sfbr
223 jump ext_done, if not X_MSG_SDTR
224
225 // the target sent SDTR - leave ACK asserted and signal kernel
226 // kernel will either restart at reject, or continue
227 sdtr: int SIR_MSG_SDTR
228 clear ack
229 jump to_decisions
230
231 ext_2: clear ack
232 int error_unexpected_phase, when not msg_in
233 move 1, scratcha1, when msg_in
234 clear ack
235 int error_unexpected_phase, when not msg_in
236 move 1, scratcha2, when msg_in
237 move scratcha1 to sfbr
238 jump ext_done, if not X_MSG_WDTR
239
240 wdtr: int SIR_MSG_WDTR
241 clear ack
242 jump to_decisions
243
244 ext_done:
245 // ought to check message here, but instead reject all
246 // NB ATN set
247 reject:
248 set atn // get target's ATN
249 clear ack // finish ACK
250 move MSG_REJECT to scratcha // prepare message
251 int error_unexpected_phase, when not msg_out// didn't get ATN
252 clear atn // last byte coming
253 move 1, scratcha, when msg_out // send byte
254 clear ack // finish ACK
255 jump reject, when msg_out // parity error
256 jump to_decisions
257
258 ignore_wide:
259 clear ack
260 int error_unexpected_phase, when not msg_in
261 move 1, scratcha1, when msg_in
262 int SIR_MSG_IGNORE_WIDE_RESIDUE
263 clear ack
264 jump to_decisions
265
266 // sends a response to a message
267 response:
268 set atn
269 clear ack
270 int error_unexpected_phase, when not msg_out
271 response_repeat:
272 move from msg_out_buf, when msg_out
273 jump response_repeat, when msg_out // repeat on parity grounds
274 // now look for response
275 // msg_in could be a REJECT
276 // anything other message is something else so signal kernel first
277 jump response_msg_in, when msg_in
278 int SIR_EV_RESPONSE_OK // not a MSG_IN so OK
279 jump to_decisions
280
281 response_msg_in:
282 move 1, scratcha, when msg_in
283 jump rejected, if MSG_REJECT // go and generate rej interrupt
284 int SIR_EV_RESPONSE_OK // not a REJECT so OK
285 jump msg_in_not_reject // try others
286
287 disconnected:
288 // move 5 to ctest0
289 move scntl2&0x7e to scntl2 // don't clear WSR
290 clear ack
291 wait disconnect
292 // UPDATE state to disconnected
293 move memory 4, state, scratcha
294 move STATE_DISCONNECTED to scratcha0
295 move memory 4, scratcha, state
296 call save_state
297 wsr_check:
298 move scntl2&0x01 to sfbr
299 int SIR_NOTIFY_WSR, if not 0
300 // int SIR_NOTIFY_DISC
301 jump issue_check
302
303 reselected_on_select:
304 int SIR_NOTIFY_RESELECTED_ON_SELECT
305 jump reselected
306
307 wait_for_reselection:
308 // move 11 to ctest0
309 // int SIR_NOTIFY_WAIT_RESELECT
310 wait reselect sigp_set
311 reselected:
312 // move 12 to ctest0
313 clear target
314 int SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT, when not msg_in
315 move 1, scratchb, when msg_in
316 int error_not_identify_after_reselect, if not MSG_IDENTIFY and mask 0x1f
317 // int SIR_NOTIFY_RESELECT
318 // now locate the right DSA - note do not clear ACK, so target doesn't start
319 // synchronous transfer until we are ready
320 find_dsa:
321 // move 6 to ctest0
322 move memory 4, dsa_head, dsa
323 find_dsa_loop:
324 // move 7 to ctest0
325 // move 8 to ctest0
326 // load state from DSA into dsa_copy
327 call load_state
328 move memory 4, state, scratcha // get dsastate in scratcha
329 move scratcha0 to sfbr // and state variable in sfbr
330 jump find_dsa_next, if not STATE_DISCONNECTED // wrong state
331 int error_reselected, if STATE_END
332 move ssid & ssid_mask to sfbr // get target ID
333 move memory 1, targ, find_dsa_smc1 // forge target comparison instruction
334 find_dsa_smc1:
335 jump find_dsa_next, if not 255 // jump if not matched
336 move memory 1, lun, find_dsa_smc2 // forge lun comparison instruction
337 move scratchb0 to sfbr // recover IDENTIFY message
338 find_dsa_smc2:
339 jump reload_sync, if 255 and mask ~7 // off we jolly well go
340 find_dsa_next:
341 move memory 4, next, dsa // find next
342 jump find_dsa_loop
343
344 // id_out terminated early
345 // most likely the message wasn't recognised
346 // clear ATN and accept the message in
347 // called from sd53c8xx.c directly
348 id_out_mismatch_recover:
349 clear atn
350 jump msg_in_phase, when msg_in
351 int SIR_MSG_REJECT
352 jump to_decisions
353
354 // Reload synchronous registers after a reconnect. If the transfer is a synchronous read, then
355 // as soon as we clear ACK, the target will switch to data_in and start blasting data into the
356 // fifo. We need to be executing the 'jump when data_in' instruction before the target stops REQing
357 // since it is the REQ which latches the 'when'. The target will do 16 REQs before stopping, so
358 // we have 16 bytes (160uS) plus delays to do this after clearing ACK. Once the jump is executing,
359 // the target will wait, so as much debugging as you like can happen in data_in_phase, just don't
360 // stick any delays between 'clear ack' and 'jump data_in_phase, when data_in'.
361
362 reload_sync:
363 call load_sync
364 clear ack
365 to_decisions:
366 jump data_in_phase, when data_in
367 jump cmd_phase, if cmd
368 jump data_out_phase, if data_out
369 jump status_phase, if status
370 jump msg_in_phase, if msg_in
371 int error_unexpected_phase
372
373 post_data_to_decisions:
374 jump status_phase, when status
375 jump msg_in_phase, if msg_in
376 int error_unexpected_phase
377
378 //
379 // MULTI_TARGET
380 //
381 // following must mirror top of dsa structure
382 // the first section is loaded and saved, the
383 // second section loaded only
384 dsa_copy:
385 state: defw 0 // a0 is state, a1 result, a2 dma block count
386 dmaaddr: defw 0 // dma address for block moves
387 dsa_save_end:
388 targ: defw 0 // lsb is target
389 lun: defw 0 // lsb is lun
390 sync: defw 0 // lsb is scntl3, sxfer
391 next: defw 0
392 dsa_load_end:
393 dsa_load_len = dsa_load_end - dsa_copy
394 dsa_save_len = dsa_save_end - dsa_copy
395
396 load_state:
397 // int SIR_NOTIFY_LOAD_STATE
398 jump load_state_okay
399
400 move dsa0 to sfbr
401 jump load_state_okay, if not 0
402 move dsa1 to sfbr
403 jump load_state_okay, if not 0
404 move dsa2 to sfbr
405 jump load_state_okay, if not 0
406 move dsa3 to sfbr
407 jump load_state_okay, if not 0
408 // dsa is 0
409 move memory 4, dsa, dmaaddr
410 move memory 4, dsa, targ
411 move memory 4, dsa, lun
412 move memory 4, dsa, sync
413 move memory 4, dsa, next
414 move memory 4, dsa, scratcha
415 move STATE_END to sfbr
416 move sfbr to scratcha0
417 move memory 4, scratcha, state
418 return
419
420 load_state_okay:
421 // load state from DSA into dsa_copy
422 // move 9 to ctest0
423 move memory 4, dsa, load_state_smc0 + 4
424 load_state_smc0:
425 move memory dsa_load_len, 0, dsa_copy
426 // move 20 to ctest0
427 return
428 save_state:
429 move memory 4, dsa, save_state_smc0 + 8
430 save_state_smc0:
431 move memory dsa_save_len, dsa_copy, 0
432 return
433
434 sigp_set:
435 // int SIR_NOTIFY_SIGP
436 move ctest2 to sfbr // clear SIGP
437 issue_check:
438 // int SIR_NOTIFY_ISSUE_CHECK
439 // move 1 to ctest0
440 move memory 4, dsa_head, dsa
441 issue_check_loop:
442 call load_state
443 move memory 4, state, scratcha // get dsastate in scratcha
444 move scratcha0 to sfbr // and state variable in sfbr
445 jump start, if STATE_ISSUE // right state
446 jump wait_for_reselection, if STATE_END
447 // move 4 to ctest0
448 move memory 4, next, dsa // find next
449 jump issue_check_loop
450
451
452 load_sync:
453 move memory 4, sync, scratcha // load the sync stuff
454 move scratcha0 to sfbr // assuming load_state has been called
455 move sfbr to scntl3
456 move scratcha1 to sfbr
457 move sfbr to sxfer
458 // int SIR_NOTIFY_LOAD_SYNC
459 return
Cache object: 2d565a3165e540724b47b2e2a122ce6a
|