Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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