diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/aic7xxx/aic79xx.seq |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx.seq')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx.seq | 2058 |
1 files changed, 2058 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq new file mode 100644 index 000000000000..65339bc1ca99 --- /dev/null +++ b/drivers/scsi/aic7xxx/aic79xx.seq | |||
@@ -0,0 +1,2058 @@ | |||
1 | /* | ||
2 | * Adaptec U320 device driver firmware for Linux and FreeBSD. | ||
3 | * | ||
4 | * Copyright (c) 1994-2001 Justin T. Gibbs. | ||
5 | * Copyright (c) 2000-2002 Adaptec Inc. | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions, and the following disclaimer, | ||
13 | * without modification. | ||
14 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
15 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
16 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
17 | * including a substantially similar Disclaimer requirement for further | ||
18 | * binary redistribution. | ||
19 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
20 | * of any contributors may be used to endorse or promote products derived | ||
21 | * from this software without specific prior written permission. | ||
22 | * | ||
23 | * Alternatively, this software may be distributed under the terms of the | ||
24 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
25 | * Software Foundation. | ||
26 | * | ||
27 | * NO WARRANTY | ||
28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
32 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
37 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
38 | * POSSIBILITY OF SUCH DAMAGES. | ||
39 | * | ||
40 | * $FreeBSD$ | ||
41 | */ | ||
42 | |||
43 | VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#99 $" | ||
44 | PATCH_ARG_LIST = "struct ahd_softc *ahd" | ||
45 | PREFIX = "ahd_" | ||
46 | |||
47 | #include "aic79xx.reg" | ||
48 | #include "scsi_message.h" | ||
49 | |||
50 | restart: | ||
51 | if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { | ||
52 | test SEQINTCODE, 0xFF jz idle_loop; | ||
53 | SET_SEQINTCODE(NO_SEQINT) | ||
54 | } | ||
55 | |||
56 | idle_loop: | ||
57 | |||
58 | if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { | ||
59 | /* | ||
60 | * Convert ERROR status into a sequencer | ||
61 | * interrupt to handle the case of an | ||
62 | * interrupt collision on the hardware | ||
63 | * setting of HWERR. | ||
64 | */ | ||
65 | test ERROR, 0xFF jz no_error_set; | ||
66 | SET_SEQINTCODE(SAW_HWERR) | ||
67 | no_error_set: | ||
68 | } | ||
69 | SET_MODE(M_SCSI, M_SCSI) | ||
70 | test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus; | ||
71 | test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus; | ||
72 | cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus; | ||
73 | /* | ||
74 | * ENSELO is cleared by a SELDO, so we must test for SELDO | ||
75 | * one last time. | ||
76 | */ | ||
77 | BEGIN_CRITICAL; | ||
78 | test SSTAT0, SELDO jnz select_out; | ||
79 | END_CRITICAL; | ||
80 | call start_selection; | ||
81 | idle_loop_checkbus: | ||
82 | BEGIN_CRITICAL; | ||
83 | test SSTAT0, SELDO jnz select_out; | ||
84 | END_CRITICAL; | ||
85 | test SSTAT0, SELDI jnz select_in; | ||
86 | test SCSIPHASE, ~DATA_PHASE_MASK jz idle_loop_check_nonpackreq; | ||
87 | test SCSISIGO, ATNO jz idle_loop_check_nonpackreq; | ||
88 | call unexpected_nonpkt_phase_find_ctxt; | ||
89 | idle_loop_check_nonpackreq: | ||
90 | test SSTAT2, NONPACKREQ jz . + 2; | ||
91 | call unexpected_nonpkt_phase_find_ctxt; | ||
92 | if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) { | ||
93 | and A, FIFO0FREE|FIFO1FREE, DFFSTAT; | ||
94 | cmp A, FIFO0FREE|FIFO1FREE jne . + 3; | ||
95 | and SBLKCTL, ~DIAGLEDEN|DIAGLEDON; | ||
96 | jmp . + 2; | ||
97 | or SBLKCTL, DIAGLEDEN|DIAGLEDON; | ||
98 | } | ||
99 | call idle_loop_gsfifo_in_scsi_mode; | ||
100 | call idle_loop_service_fifos; | ||
101 | call idle_loop_cchan; | ||
102 | jmp idle_loop; | ||
103 | |||
104 | BEGIN_CRITICAL; | ||
105 | idle_loop_gsfifo: | ||
106 | SET_MODE(M_SCSI, M_SCSI) | ||
107 | idle_loop_gsfifo_in_scsi_mode: | ||
108 | test LQISTAT2, LQIGSAVAIL jz return; | ||
109 | /* | ||
110 | * We have received good status for this transaction. There may | ||
111 | * still be data in our FIFOs draining to the host. Complete | ||
112 | * the SCB only if all data has transferred to the host. | ||
113 | */ | ||
114 | good_status_IU_done: | ||
115 | bmov SCBPTR, GSFIFO, 2; | ||
116 | clr SCB_SCSI_STATUS; | ||
117 | /* | ||
118 | * If a command completed before an attempted task management | ||
119 | * function completed, notify the host after disabling any | ||
120 | * pending select-outs. | ||
121 | */ | ||
122 | test SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally; | ||
123 | test SSTAT0, SELDO|SELINGO jnz . + 2; | ||
124 | and SCSISEQ0, ~ENSELO; | ||
125 | SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) | ||
126 | gsfifo_complete_normally: | ||
127 | or SCB_CONTROL, STATUS_RCVD; | ||
128 | |||
129 | /* | ||
130 | * Since this status did not consume a FIFO, we have to | ||
131 | * be a bit more dilligent in how we check for FIFOs pertaining | ||
132 | * to this transaction. There are two states that a FIFO still | ||
133 | * transferring data may be in. | ||
134 | * | ||
135 | * 1) Configured and draining to the host, with a FIFO handler. | ||
136 | * 2) Pending cfg4data, fifo not empty. | ||
137 | * | ||
138 | * Case 1 can be detected by noticing a non-zero FIFO active | ||
139 | * count in the SCB. In this case, we allow the routine servicing | ||
140 | * the FIFO to complete the SCB. | ||
141 | * | ||
142 | * Case 2 implies either a pending or yet to occur save data | ||
143 | * pointers for this same context in the other FIFO. So, if | ||
144 | * we detect case 1, we will properly defer the post of the SCB | ||
145 | * and achieve the desired result. The pending cfg4data will | ||
146 | * notice that status has been received and complete the SCB. | ||
147 | */ | ||
148 | test SCB_FIFO_USE_COUNT, 0xFF jnz idle_loop_gsfifo_in_scsi_mode; | ||
149 | call complete; | ||
150 | END_CRITICAL; | ||
151 | jmp idle_loop_gsfifo_in_scsi_mode; | ||
152 | |||
153 | idle_loop_service_fifos: | ||
154 | SET_MODE(M_DFF0, M_DFF0) | ||
155 | test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo; | ||
156 | call longjmp; | ||
157 | idle_loop_next_fifo: | ||
158 | SET_MODE(M_DFF1, M_DFF1) | ||
159 | test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp; | ||
160 | return: | ||
161 | ret; | ||
162 | |||
163 | idle_loop_cchan: | ||
164 | SET_MODE(M_CCHAN, M_CCHAN) | ||
165 | test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty; | ||
166 | or QOFF_CTLSTA, HS_MAILBOX_ACT; | ||
167 | mov LOCAL_HS_MAILBOX, HS_MAILBOX; | ||
168 | hs_mailbox_empty: | ||
169 | BEGIN_CRITICAL; | ||
170 | test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle; | ||
171 | test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog; | ||
172 | test CCSCBCTL, CCSCBDONE jz return; | ||
173 | END_CRITICAL; | ||
174 | /* FALLTHROUGH */ | ||
175 | scbdma_tohost_done: | ||
176 | test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone; | ||
177 | /* | ||
178 | * An SCB has been succesfully uploaded to the host. | ||
179 | * If the SCB was uploaded for some reason other than | ||
180 | * bad SCSI status (currently only for underruns), we | ||
181 | * queue the SCB for normal completion. Otherwise, we | ||
182 | * wait until any select-out activity has halted, and | ||
183 | * then notify the host so that the transaction can be | ||
184 | * dealt with. | ||
185 | */ | ||
186 | test SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host; | ||
187 | and CCSCBCTL, ~(CCARREN|CCSCBEN); | ||
188 | bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2; | ||
189 | bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; | ||
190 | bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; | ||
191 | scbdma_notify_host: | ||
192 | SET_MODE(M_SCSI, M_SCSI) | ||
193 | test SCSISEQ0, ENSELO jnz return; | ||
194 | test SSTAT0, (SELDO|SELINGO) jnz return; | ||
195 | SET_MODE(M_CCHAN, M_CCHAN) | ||
196 | /* | ||
197 | * Remove SCB and notify host. | ||
198 | */ | ||
199 | and CCSCBCTL, ~(CCARREN|CCSCBEN); | ||
200 | bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2; | ||
201 | SET_SEQINTCODE(BAD_SCB_STATUS) | ||
202 | ret; | ||
203 | fill_qoutfifo_dmadone: | ||
204 | and CCSCBCTL, ~(CCARREN|CCSCBEN); | ||
205 | call qoutfifo_updated; | ||
206 | mvi COMPLETE_SCB_DMAINPROG_HEAD[1], SCB_LIST_NULL; | ||
207 | bmov QOUTFIFO_NEXT_ADDR, SCBHADDR, 4; | ||
208 | test QOFF_CTLSTA, SDSCB_ROLLOVR jz return; | ||
209 | bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4; | ||
210 | xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret; | ||
211 | |||
212 | qoutfifo_updated: | ||
213 | /* | ||
214 | * If there are more commands waiting to be dma'ed | ||
215 | * to the host, always coalesce. Otherwise honor the | ||
216 | * host's wishes. | ||
217 | */ | ||
218 | cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count; | ||
219 | cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count; | ||
220 | test LOCAL_HS_MAILBOX, ENINT_COALESCE jz issue_cmdcmplt; | ||
221 | |||
222 | /* | ||
223 | * If we have relatively few commands outstanding, don't | ||
224 | * bother waiting for another command to complete. | ||
225 | */ | ||
226 | test CMDS_PENDING[1], 0xFF jnz coalesce_by_count; | ||
227 | /* Add -1 so that jnc means <= not just < */ | ||
228 | add A, -1, INT_COALESCING_MINCMDS; | ||
229 | add NONE, A, CMDS_PENDING; | ||
230 | jnc issue_cmdcmplt; | ||
231 | |||
232 | /* | ||
233 | * If coalescing, only coalesce up to the limit | ||
234 | * provided by the host driver. | ||
235 | */ | ||
236 | coalesce_by_count: | ||
237 | mov A, INT_COALESCING_MAXCMDS; | ||
238 | add NONE, A, INT_COALESCING_CMDCOUNT; | ||
239 | jc issue_cmdcmplt; | ||
240 | /* | ||
241 | * If the timer is not currently active, | ||
242 | * fire it up. | ||
243 | */ | ||
244 | test INTCTL, SWTMINTMASK jz return; | ||
245 | bmov SWTIMER, INT_COALESCING_TIMER, 2; | ||
246 | mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; | ||
247 | or INTCTL, SWTMINTEN|SWTIMER_START; | ||
248 | and INTCTL, ~SWTMINTMASK ret; | ||
249 | |||
250 | issue_cmdcmplt: | ||
251 | mvi INTSTAT, CMDCMPLT; | ||
252 | clr INT_COALESCING_CMDCOUNT; | ||
253 | or INTCTL, SWTMINTMASK ret; | ||
254 | |||
255 | BEGIN_CRITICAL; | ||
256 | fetch_new_scb_inprog: | ||
257 | test CCSCBCTL, ARRDONE jz return; | ||
258 | fetch_new_scb_done: | ||
259 | and CCSCBCTL, ~(CCARREN|CCSCBEN); | ||
260 | bmov REG0, SCBPTR, 2; | ||
261 | clr A; | ||
262 | add CMDS_PENDING, 1; | ||
263 | adc CMDS_PENDING[1], A; | ||
264 | if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { | ||
265 | /* | ||
266 | * "Short Luns" are not placed into outgoing LQ | ||
267 | * packets in the correct byte order. Use a full | ||
268 | * sized lun field instead and fill it with the | ||
269 | * one byte of lun information we support. | ||
270 | */ | ||
271 | mov SCB_PKT_LUN[6], SCB_LUN; | ||
272 | } | ||
273 | /* | ||
274 | * The FIFO use count field is shared with the | ||
275 | * tag set by the host so that our SCB dma engine | ||
276 | * knows the correct location to store the SCB. | ||
277 | * Set it to zero before processing the SCB. | ||
278 | */ | ||
279 | clr SCB_FIFO_USE_COUNT; | ||
280 | /* Update the next SCB address to download. */ | ||
281 | bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4; | ||
282 | mvi SCB_NEXT[1], SCB_LIST_NULL; | ||
283 | mvi SCB_NEXT2[1], SCB_LIST_NULL; | ||
284 | /* Increment our position in the QINFIFO. */ | ||
285 | mov NONE, SNSCB_QOFF; | ||
286 | /* | ||
287 | * SCBs that want to send messages are always | ||
288 | * queued independently. This ensures that they | ||
289 | * are at the head of the SCB list to select out | ||
290 | * to a target and we will see the MK_MESSAGE flag. | ||
291 | */ | ||
292 | test SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb; | ||
293 | shr SINDEX, 3, SCB_SCSIID; | ||
294 | and SINDEX, ~0x1; | ||
295 | mvi SINDEX[1], (WAITING_SCB_TAILS >> 8); | ||
296 | bmov DINDEX, SINDEX, 2; | ||
297 | bmov SCBPTR, SINDIR, 2; | ||
298 | bmov DINDIR, REG0, 2; | ||
299 | cmp SCBPTR[1], SCB_LIST_NULL je first_new_target_scb; | ||
300 | bmov SCB_NEXT, REG0, 2 ret; | ||
301 | first_new_target_scb: | ||
302 | cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb; | ||
303 | bmov SCBPTR, WAITING_TID_TAIL, 2; | ||
304 | bmov SCB_NEXT2, REG0, 2; | ||
305 | bmov WAITING_TID_TAIL, REG0, 2 ret; | ||
306 | first_new_scb: | ||
307 | bmov WAITING_TID_HEAD, REG0, 2; | ||
308 | bmov WAITING_TID_TAIL, REG0, 2 ret; | ||
309 | END_CRITICAL; | ||
310 | |||
311 | scbdma_idle: | ||
312 | /* | ||
313 | * Give precedence to downloading new SCBs to execute | ||
314 | * unless select-outs are currently frozen. | ||
315 | */ | ||
316 | test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2; | ||
317 | BEGIN_CRITICAL; | ||
318 | test QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb; | ||
319 | cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb; | ||
320 | cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return; | ||
321 | /* FALLTHROUGH */ | ||
322 | fill_qoutfifo: | ||
323 | /* | ||
324 | * Keep track of the SCBs we are dmaing just | ||
325 | * in case the DMA fails or is aborted. | ||
326 | */ | ||
327 | mov A, QOUTFIFO_ENTRY_VALID_TAG; | ||
328 | bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2; | ||
329 | mvi CCSCBCTL, CCSCBRESET; | ||
330 | bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4; | ||
331 | bmov SCBPTR, COMPLETE_SCB_HEAD, 2; | ||
332 | fill_qoutfifo_loop: | ||
333 | mov CCSCBRAM, SCBPTR; | ||
334 | or CCSCBRAM, A, SCBPTR[1]; | ||
335 | mov NONE, SDSCB_QOFF; | ||
336 | inc INT_COALESCING_CMDCOUNT; | ||
337 | add CMDS_PENDING, -1; | ||
338 | adc CMDS_PENDING[1], -1; | ||
339 | cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done; | ||
340 | cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done; | ||
341 | test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done; | ||
342 | bmov SCBPTR, SCB_NEXT_COMPLETE, 2; | ||
343 | jmp fill_qoutfifo_loop; | ||
344 | fill_qoutfifo_done: | ||
345 | mov SCBHCNT, CCSCBADDR; | ||
346 | mvi CCSCBCTL, CCSCBEN|CCSCBRESET; | ||
347 | bmov COMPLETE_SCB_HEAD, SCB_NEXT_COMPLETE, 2; | ||
348 | mvi SCB_NEXT_COMPLETE[1], SCB_LIST_NULL ret; | ||
349 | |||
350 | fetch_new_scb: | ||
351 | bmov SCBHADDR, NEXT_QUEUED_SCB_ADDR, 4; | ||
352 | mvi CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET jmp dma_scb; | ||
353 | dma_complete_scb: | ||
354 | bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2; | ||
355 | bmov SCBHADDR, SCB_BUSADDR, 4; | ||
356 | mvi CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb; | ||
357 | END_CRITICAL; | ||
358 | |||
359 | /* | ||
360 | * Either post or fetch an SCB from host memory. The caller | ||
361 | * is responsible for polling for transfer completion. | ||
362 | * | ||
363 | * Prerequisits: Mode == M_CCHAN | ||
364 | * SINDEX contains CCSCBCTL flags | ||
365 | * SCBHADDR set to Host SCB address | ||
366 | * SCBPTR set to SCB src location on "push" operations | ||
367 | */ | ||
368 | SET_SRC_MODE M_CCHAN; | ||
369 | SET_DST_MODE M_CCHAN; | ||
370 | dma_scb: | ||
371 | mvi SCBHCNT, SCB_TRANSFER_SIZE; | ||
372 | mov CCSCBCTL, SINDEX ret; | ||
373 | |||
374 | BEGIN_CRITICAL; | ||
375 | setjmp: | ||
376 | bmov LONGJMP_ADDR, STACK, 2 ret; | ||
377 | setjmp_inline: | ||
378 | bmov LONGJMP_ADDR, STACK, 2; | ||
379 | longjmp: | ||
380 | bmov STACK, LONGJMP_ADDR, 2 ret; | ||
381 | END_CRITICAL; | ||
382 | |||
383 | /*************************** Chip Bug Work Arounds ****************************/ | ||
384 | /* | ||
385 | * Must disable interrupts when setting the mode pointer | ||
386 | * register as an interrupt occurring mid update will | ||
387 | * fail to store the new mode value for restoration on | ||
388 | * an iret. | ||
389 | */ | ||
390 | if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { | ||
391 | set_mode_work_around: | ||
392 | mvi SEQINTCTL, INTVEC1DSL; | ||
393 | mov MODE_PTR, SINDEX; | ||
394 | clr SEQINTCTL ret; | ||
395 | |||
396 | toggle_dff_mode_work_around: | ||
397 | mvi SEQINTCTL, INTVEC1DSL; | ||
398 | xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); | ||
399 | clr SEQINTCTL ret; | ||
400 | } | ||
401 | |||
402 | |||
403 | if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { | ||
404 | set_seqint_work_around: | ||
405 | mov SEQINTCODE, SINDEX; | ||
406 | mvi SEQINTCODE, NO_SEQINT ret; | ||
407 | } | ||
408 | |||
409 | /************************ Packetized LongJmp Routines *************************/ | ||
410 | SET_SRC_MODE M_SCSI; | ||
411 | SET_DST_MODE M_SCSI; | ||
412 | start_selection: | ||
413 | BEGIN_CRITICAL; | ||
414 | if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { | ||
415 | /* | ||
416 | * Razor #494 | ||
417 | * Rev A hardware fails to update LAST/CURR/NEXTSCB | ||
418 | * correctly after a packetized selection in several | ||
419 | * situations: | ||
420 | * | ||
421 | * 1) If only one command existed in the queue, the | ||
422 | * LAST/CURR/NEXTSCB are unchanged. | ||
423 | * | ||
424 | * 2) In a non QAS, protocol allowed phase change, | ||
425 | * the queue is shifted 1 too far. LASTSCB is | ||
426 | * the last SCB that was correctly processed. | ||
427 | * | ||
428 | * 3) In the QAS case, if the full list of commands | ||
429 | * was successfully sent, NEXTSCB is NULL and neither | ||
430 | * CURRSCB nor LASTSCB can be trusted. We must | ||
431 | * manually walk the list counting MAXCMDCNT elements | ||
432 | * to find the last SCB that was sent correctly. | ||
433 | * | ||
434 | * To simplify the workaround for this bug in SELDO | ||
435 | * handling, we initialize LASTSCB prior to enabling | ||
436 | * selection so we can rely on it even for case #1 above. | ||
437 | */ | ||
438 | bmov LASTSCB, WAITING_TID_HEAD, 2; | ||
439 | } | ||
440 | bmov CURRSCB, WAITING_TID_HEAD, 2; | ||
441 | bmov SCBPTR, WAITING_TID_HEAD, 2; | ||
442 | shr SELOID, 4, SCB_SCSIID; | ||
443 | /* | ||
444 | * If we want to send a message to the device, ensure | ||
445 | * we are selecting with atn irregardless of our packetized | ||
446 | * agreement. Since SPI4 only allows target reset or PPR | ||
447 | * messages if this is a packetized connection, the change | ||
448 | * to our negotiation table entry for this selection will | ||
449 | * be cleared when the message is acted on. | ||
450 | */ | ||
451 | test SCB_CONTROL, MK_MESSAGE jz . + 3; | ||
452 | mov NEGOADDR, SELOID; | ||
453 | or NEGCONOPTS, ENAUTOATNO; | ||
454 | or SCSISEQ0, ENSELO ret; | ||
455 | END_CRITICAL; | ||
456 | |||
457 | /* | ||
458 | * Allocate a FIFO for a non-packetized transaction. | ||
459 | * In RevA hardware, both FIFOs must be free before we | ||
460 | * can allocate a FIFO for a non-packetized transaction. | ||
461 | */ | ||
462 | allocate_fifo_loop: | ||
463 | /* | ||
464 | * Do whatever work is required to free a FIFO. | ||
465 | */ | ||
466 | call idle_loop_service_fifos; | ||
467 | SET_MODE(M_SCSI, M_SCSI) | ||
468 | allocate_fifo: | ||
469 | if ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0) { | ||
470 | and A, FIFO0FREE|FIFO1FREE, DFFSTAT; | ||
471 | cmp A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop; | ||
472 | } else { | ||
473 | test DFFSTAT, FIFO1FREE jnz allocate_fifo1; | ||
474 | test DFFSTAT, FIFO0FREE jz allocate_fifo_loop; | ||
475 | mvi DFFSTAT, B_CURRFIFO_0; | ||
476 | SET_MODE(M_DFF0, M_DFF0) | ||
477 | bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; | ||
478 | } | ||
479 | SET_SRC_MODE M_SCSI; | ||
480 | SET_DST_MODE M_SCSI; | ||
481 | allocate_fifo1: | ||
482 | mvi DFFSTAT, CURRFIFO_1; | ||
483 | SET_MODE(M_DFF1, M_DFF1) | ||
484 | bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; | ||
485 | |||
486 | /* | ||
487 | * We have been reselected as an initiator | ||
488 | * or selected as a target. | ||
489 | */ | ||
490 | SET_SRC_MODE M_SCSI; | ||
491 | SET_DST_MODE M_SCSI; | ||
492 | select_in: | ||
493 | if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { | ||
494 | /* | ||
495 | * Test to ensure that the bus has not | ||
496 | * already gone free prior to clearing | ||
497 | * any stale busfree status. This avoids | ||
498 | * a window whereby a busfree just after | ||
499 | * a selection could be missed. | ||
500 | */ | ||
501 | test SCSISIGI, BSYI jz . + 2; | ||
502 | mvi CLRSINT1,CLRBUSFREE; | ||
503 | or SIMODE1, ENBUSFREE; | ||
504 | } | ||
505 | or SXFRCTL0, SPIOEN; | ||
506 | and SAVED_SCSIID, SELID_MASK, SELID; | ||
507 | and A, OID, IOWNID; | ||
508 | or SAVED_SCSIID, A; | ||
509 | mvi CLRSINT0, CLRSELDI; | ||
510 | jmp ITloop; | ||
511 | |||
512 | /* | ||
513 | * We have successfully selected out. | ||
514 | * | ||
515 | * Clear SELDO. | ||
516 | * Dequeue all SCBs sent from the waiting queue | ||
517 | * Requeue all SCBs *not* sent to the tail of the waiting queue | ||
518 | * Take Razor #494 into account for above. | ||
519 | * | ||
520 | * In Packetized Mode: | ||
521 | * Return to the idle loop. Our interrupt handler will take | ||
522 | * care of any incoming L_Qs. | ||
523 | * | ||
524 | * In Non-Packetize Mode: | ||
525 | * Continue to our normal state machine. | ||
526 | */ | ||
527 | SET_SRC_MODE M_SCSI; | ||
528 | SET_DST_MODE M_SCSI; | ||
529 | select_out: | ||
530 | BEGIN_CRITICAL; | ||
531 | /* Clear out all SCBs that have been successfully sent. */ | ||
532 | if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { | ||
533 | /* | ||
534 | * For packetized, the LQO manager clears ENSELO on | ||
535 | * the assertion of SELDO. If we are non-packetized, | ||
536 | * LASTSCB and CURRSCB are accurate. | ||
537 | */ | ||
538 | test SCSISEQ0, ENSELO jnz use_lastscb; | ||
539 | |||
540 | /* | ||
541 | * The update is correct for LQOSTAT1 errors. All | ||
542 | * but LQOBUSFREE are handled by kernel interrupts. | ||
543 | * If we see LQOBUSFREE, return to the idle loop. | ||
544 | * Once we are out of the select_out critical section, | ||
545 | * the kernel will cleanup the LQOBUSFREE and we will | ||
546 | * eventually restart the selection if appropriate. | ||
547 | */ | ||
548 | test LQOSTAT1, LQOBUSFREE jnz idle_loop; | ||
549 | |||
550 | /* | ||
551 | * On a phase change oustside of packet boundaries, | ||
552 | * LASTSCB points to the currently active SCB context | ||
553 | * on the bus. | ||
554 | */ | ||
555 | test LQOSTAT2, LQOPHACHGOUTPKT jnz use_lastscb; | ||
556 | |||
557 | /* | ||
558 | * If the hardware has traversed the whole list, NEXTSCB | ||
559 | * will be NULL, CURRSCB and LASTSCB cannot be trusted, | ||
560 | * but MAXCMDCNT is accurate. If we stop part way through | ||
561 | * the list or only had one command to issue, NEXTSCB[1] is | ||
562 | * not NULL and LASTSCB is the last command to go out. | ||
563 | */ | ||
564 | cmp NEXTSCB[1], SCB_LIST_NULL jne use_lastscb; | ||
565 | |||
566 | /* | ||
567 | * Brute force walk. | ||
568 | */ | ||
569 | bmov SCBPTR, WAITING_TID_HEAD, 2; | ||
570 | mvi SEQINTCTL, INTVEC1DSL; | ||
571 | mvi MODE_PTR, MK_MODE(M_CFG, M_CFG); | ||
572 | mov A, MAXCMDCNT; | ||
573 | mvi MODE_PTR, MK_MODE(M_SCSI, M_SCSI); | ||
574 | clr SEQINTCTL; | ||
575 | find_lastscb_loop: | ||
576 | dec A; | ||
577 | test A, 0xFF jz found_last_sent_scb; | ||
578 | bmov SCBPTR, SCB_NEXT, 2; | ||
579 | jmp find_lastscb_loop; | ||
580 | use_lastscb: | ||
581 | bmov SCBPTR, LASTSCB, 2; | ||
582 | found_last_sent_scb: | ||
583 | bmov CURRSCB, SCBPTR, 2; | ||
584 | curscb_ww_done: | ||
585 | } else { | ||
586 | bmov SCBPTR, CURRSCB, 2; | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * Requeue any SCBs not sent, to the tail of the waiting Q. | ||
591 | */ | ||
592 | cmp SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done; | ||
593 | |||
594 | /* | ||
595 | * We know that neither the per-TID list nor the list of | ||
596 | * TIDs is empty. Use this knowledge to our advantage. | ||
597 | */ | ||
598 | bmov REG0, SCB_NEXT, 2; | ||
599 | bmov SCBPTR, WAITING_TID_TAIL, 2; | ||
600 | bmov SCB_NEXT2, REG0, 2; | ||
601 | bmov WAITING_TID_TAIL, REG0, 2; | ||
602 | jmp select_out_inc_tid_q; | ||
603 | |||
604 | select_out_list_done: | ||
605 | /* | ||
606 | * The whole list made it. Just clear our TID's tail pointer | ||
607 | * unless we were queued independently due to our need to | ||
608 | * send a message. | ||
609 | */ | ||
610 | test SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q; | ||
611 | shr DINDEX, 3, SCB_SCSIID; | ||
612 | or DINDEX, 1; /* Want only the second byte */ | ||
613 | mvi DINDEX[1], ((WAITING_SCB_TAILS) >> 8); | ||
614 | mvi DINDIR, SCB_LIST_NULL; | ||
615 | select_out_inc_tid_q: | ||
616 | bmov SCBPTR, WAITING_TID_HEAD, 2; | ||
617 | bmov WAITING_TID_HEAD, SCB_NEXT2, 2; | ||
618 | cmp WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2; | ||
619 | mvi WAITING_TID_TAIL[1], SCB_LIST_NULL; | ||
620 | bmov SCBPTR, CURRSCB, 2; | ||
621 | mvi CLRSINT0, CLRSELDO; | ||
622 | test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase; | ||
623 | test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase; | ||
624 | |||
625 | /* | ||
626 | * If this is a packetized connection, return to our | ||
627 | * idle_loop and let our interrupt handler deal with | ||
628 | * any connection setup/teardown issues. The only | ||
629 | * exceptions are the case of MK_MESSAGE and task management | ||
630 | * SCBs. | ||
631 | */ | ||
632 | if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) { | ||
633 | /* | ||
634 | * In the A, the LQO manager transitions to LQOSTOP0 even if | ||
635 | * we have selected out with ATN asserted and the target | ||
636 | * REQs in a non-packet phase. | ||
637 | */ | ||
638 | test SCB_CONTROL, MK_MESSAGE jz select_out_no_message; | ||
639 | test SCSISIGO, ATNO jnz select_out_non_packetized; | ||
640 | select_out_no_message: | ||
641 | } | ||
642 | test LQOSTAT2, LQOSTOP0 jz select_out_non_packetized; | ||
643 | test SCB_TASK_MANAGEMENT, 0xFF jz idle_loop; | ||
644 | SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE) | ||
645 | jmp idle_loop; | ||
646 | |||
647 | select_out_non_packetized: | ||
648 | /* Non packetized request. */ | ||
649 | and SCSISEQ0, ~ENSELO; | ||
650 | if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { | ||
651 | /* | ||
652 | * Test to ensure that the bus has not | ||
653 | * already gone free prior to clearing | ||
654 | * any stale busfree status. This avoids | ||
655 | * a window whereby a busfree just after | ||
656 | * a selection could be missed. | ||
657 | */ | ||
658 | test SCSISIGI, BSYI jz . + 2; | ||
659 | mvi CLRSINT1,CLRBUSFREE; | ||
660 | or SIMODE1, ENBUSFREE; | ||
661 | } | ||
662 | mov SAVED_SCSIID, SCB_SCSIID; | ||
663 | mov SAVED_LUN, SCB_LUN; | ||
664 | mvi SEQ_FLAGS, NO_CDB_SENT; | ||
665 | END_CRITICAL; | ||
666 | or SXFRCTL0, SPIOEN; | ||
667 | |||
668 | /* | ||
669 | * As soon as we get a successful selection, the target | ||
670 | * should go into the message out phase since we have ATN | ||
671 | * asserted. | ||
672 | */ | ||
673 | mvi MSG_OUT, MSG_IDENTIFYFLAG; | ||
674 | |||
675 | /* | ||
676 | * Main loop for information transfer phases. Wait for the | ||
677 | * target to assert REQ before checking MSG, C/D and I/O for | ||
678 | * the bus phase. | ||
679 | */ | ||
680 | mesgin_phasemis: | ||
681 | ITloop: | ||
682 | call phase_lock; | ||
683 | |||
684 | mov A, LASTPHASE; | ||
685 | |||
686 | test A, ~P_DATAIN_DT jz p_data; | ||
687 | cmp A,P_COMMAND je p_command; | ||
688 | cmp A,P_MESGOUT je p_mesgout; | ||
689 | cmp A,P_STATUS je p_status; | ||
690 | cmp A,P_MESGIN je p_mesgin; | ||
691 | |||
692 | SET_SEQINTCODE(BAD_PHASE) | ||
693 | jmp ITloop; /* Try reading the bus again. */ | ||
694 | |||
695 | /* | ||
696 | * Command phase. Set up the DMA registers and let 'er rip. | ||
697 | */ | ||
698 | p_command: | ||
699 | test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay; | ||
700 | SET_SEQINTCODE(PROTO_VIOLATION) | ||
701 | p_command_okay: | ||
702 | test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) | ||
703 | jnz p_command_allocate_fifo; | ||
704 | /* | ||
705 | * Command retry. Free our current FIFO and | ||
706 | * re-allocate a FIFO so transfer state is | ||
707 | * reset. | ||
708 | */ | ||
709 | SET_SRC_MODE M_DFF1; | ||
710 | SET_DST_MODE M_DFF1; | ||
711 | mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; | ||
712 | SET_MODE(M_SCSI, M_SCSI) | ||
713 | p_command_allocate_fifo: | ||
714 | bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; | ||
715 | call allocate_fifo; | ||
716 | SET_SRC_MODE M_DFF1; | ||
717 | SET_DST_MODE M_DFF1; | ||
718 | add NONE, -17, SCB_CDB_LEN; | ||
719 | jnc p_command_embedded; | ||
720 | p_command_from_host: | ||
721 | bmov HADDR[0], SCB_HOST_CDB_PTR, 9; | ||
722 | mvi SG_CACHE_PRE, LAST_SEG; | ||
723 | mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); | ||
724 | jmp p_command_xfer; | ||
725 | p_command_embedded: | ||
726 | bmov SHCNT[0], SCB_CDB_LEN, 1; | ||
727 | bmov DFDAT, SCB_CDB_STORE, 16; | ||
728 | mvi DFCNTRL, SCSIEN; | ||
729 | p_command_xfer: | ||
730 | and SEQ_FLAGS, ~NO_CDB_SENT; | ||
731 | if ((ahd->features & AHD_FAST_CDB_DELIVERY) != 0) { | ||
732 | /* | ||
733 | * To speed up CDB delivery in Rev B, all CDB acks | ||
734 | * are "released" to the output sync as soon as the | ||
735 | * command phase starts. There is only one problem | ||
736 | * with this approach. If the target changes phase | ||
737 | * before all data are sent, we have left over acks | ||
738 | * that can go out on the bus in a data phase. Due | ||
739 | * to other chip contraints, this only happens if | ||
740 | * the target goes to data-in, but if the acks go | ||
741 | * out before we can test SDONE, we'll think that | ||
742 | * the transfer has completed successfully. Work | ||
743 | * around this by taking advantage of the 400ns or | ||
744 | * 800ns dead time between command phase and the REQ | ||
745 | * of the new phase. If the transfer has completed | ||
746 | * successfully, SCSIEN should fall *long* before we | ||
747 | * see a phase change. We thus treat any phasemiss | ||
748 | * that occurs before SCSIEN falls as an incomplete | ||
749 | * transfer. | ||
750 | */ | ||
751 | test SSTAT1, PHASEMIS jnz p_command_xfer_failed; | ||
752 | test DFCNTRL, SCSIEN jnz . - 1; | ||
753 | } else { | ||
754 | test DFCNTRL, SCSIEN jnz .; | ||
755 | } | ||
756 | /* | ||
757 | * DMA Channel automatically disabled. | ||
758 | * Don't allow a data phase if the command | ||
759 | * was not fully transferred. | ||
760 | */ | ||
761 | test SSTAT2, SDONE jnz ITloop; | ||
762 | p_command_xfer_failed: | ||
763 | or SEQ_FLAGS, NO_CDB_SENT; | ||
764 | jmp ITloop; | ||
765 | |||
766 | |||
767 | /* | ||
768 | * Status phase. Wait for the data byte to appear, then read it | ||
769 | * and store it into the SCB. | ||
770 | */ | ||
771 | SET_SRC_MODE M_SCSI; | ||
772 | SET_DST_MODE M_SCSI; | ||
773 | p_status: | ||
774 | test SEQ_FLAGS,NOT_IDENTIFIED jnz mesgin_proto_violation; | ||
775 | p_status_okay: | ||
776 | mov SCB_SCSI_STATUS, SCSIDAT; | ||
777 | or SCB_CONTROL, STATUS_RCVD; | ||
778 | jmp ITloop; | ||
779 | |||
780 | /* | ||
781 | * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full | ||
782 | * indentify message sequence and send it to the target. The host may | ||
783 | * override this behavior by setting the MK_MESSAGE bit in the SCB | ||
784 | * control byte. This will cause us to interrupt the host and allow | ||
785 | * it to handle the message phase completely on its own. If the bit | ||
786 | * associated with this target is set, we will also interrupt the host, | ||
787 | * thereby allowing it to send a message on the next selection regardless | ||
788 | * of the transaction being sent. | ||
789 | * | ||
790 | * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. | ||
791 | * This is done to allow the host to send messages outside of an identify | ||
792 | * sequence while protecting the seqencer from testing the MK_MESSAGE bit | ||
793 | * on an SCB that might not be for the current nexus. (For example, a | ||
794 | * BDR message in responce to a bad reselection would leave us pointed to | ||
795 | * an SCB that doesn't have anything to do with the current target). | ||
796 | * | ||
797 | * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, | ||
798 | * bus device reset). | ||
799 | * | ||
800 | * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, | ||
801 | * in case the target decides to put us in this phase for some strange | ||
802 | * reason. | ||
803 | */ | ||
804 | p_mesgout_retry: | ||
805 | /* Turn on ATN for the retry */ | ||
806 | mvi SCSISIGO, ATNO; | ||
807 | p_mesgout: | ||
808 | mov SINDEX, MSG_OUT; | ||
809 | cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; | ||
810 | test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; | ||
811 | p_mesgout_identify: | ||
812 | or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN; | ||
813 | test SCB_CONTROL, DISCENB jnz . + 2; | ||
814 | and SINDEX, ~DISCENB; | ||
815 | /* | ||
816 | * Send a tag message if TAG_ENB is set in the SCB control block. | ||
817 | * Use SCB_NONPACKET_TAG as the tag value. | ||
818 | */ | ||
819 | p_mesgout_tag: | ||
820 | test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; | ||
821 | mov SCSIDAT, SINDEX; /* Send the identify message */ | ||
822 | call phase_lock; | ||
823 | cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; | ||
824 | and SCSIDAT,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; | ||
825 | call phase_lock; | ||
826 | cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; | ||
827 | mov SCBPTR jmp p_mesgout_onebyte; | ||
828 | /* | ||
829 | * Interrupt the driver, and allow it to handle this message | ||
830 | * phase and any required retries. | ||
831 | */ | ||
832 | p_mesgout_from_host: | ||
833 | cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; | ||
834 | jmp host_message_loop; | ||
835 | |||
836 | p_mesgout_onebyte: | ||
837 | mvi CLRSINT1, CLRATNO; | ||
838 | mov SCSIDAT, SINDEX; | ||
839 | |||
840 | /* | ||
841 | * If the next bus phase after ATN drops is message out, it means | ||
842 | * that the target is requesting that the last message(s) be resent. | ||
843 | */ | ||
844 | call phase_lock; | ||
845 | cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; | ||
846 | |||
847 | p_mesgout_done: | ||
848 | mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ | ||
849 | mov LAST_MSG, MSG_OUT; | ||
850 | mvi MSG_OUT, MSG_NOOP; /* No message left */ | ||
851 | jmp ITloop; | ||
852 | |||
853 | /* | ||
854 | * Message in phase. Bytes are read using Automatic PIO mode. | ||
855 | */ | ||
856 | p_mesgin: | ||
857 | /* read the 1st message byte */ | ||
858 | mvi ACCUM call inb_first; | ||
859 | |||
860 | test A,MSG_IDENTIFYFLAG jnz mesgin_identify; | ||
861 | cmp A,MSG_DISCONNECT je mesgin_disconnect; | ||
862 | cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; | ||
863 | cmp ALLZEROS,A je mesgin_complete; | ||
864 | cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; | ||
865 | cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue; | ||
866 | cmp A,MSG_NOOP je mesgin_done; | ||
867 | |||
868 | /* | ||
869 | * Pushed message loop to allow the kernel to | ||
870 | * run it's own message state engine. To avoid an | ||
871 | * extra nop instruction after signaling the kernel, | ||
872 | * we perform the phase_lock before checking to see | ||
873 | * if we should exit the loop and skip the phase_lock | ||
874 | * in the ITloop. Performing back to back phase_locks | ||
875 | * shouldn't hurt, but why do it twice... | ||
876 | */ | ||
877 | host_message_loop: | ||
878 | call phase_lock; /* Benign the first time through. */ | ||
879 | SET_SEQINTCODE(HOST_MSG_LOOP) | ||
880 | cmp RETURN_1, EXIT_MSG_LOOP je ITloop; | ||
881 | cmp RETURN_1, CONT_MSG_LOOP_WRITE jne . + 3; | ||
882 | mov SCSIDAT, RETURN_2; | ||
883 | jmp host_message_loop; | ||
884 | /* Must be CONT_MSG_LOOP_READ */ | ||
885 | mov NONE, SCSIDAT; /* ACK Byte */ | ||
886 | jmp host_message_loop; | ||
887 | |||
888 | mesgin_ign_wide_residue: | ||
889 | mov SAVED_MODE, MODE_PTR; | ||
890 | SET_MODE(M_SCSI, M_SCSI) | ||
891 | shr NEGOADDR, 4, SAVED_SCSIID; | ||
892 | mov A, NEGCONOPTS; | ||
893 | RESTORE_MODE(SAVED_MODE) | ||
894 | test A, WIDEXFER jz mesgin_reject; | ||
895 | /* Pull the residue byte */ | ||
896 | mvi REG0 call inb_next; | ||
897 | cmp REG0, 0x01 jne mesgin_reject; | ||
898 | test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; | ||
899 | test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jnz mesgin_done; | ||
900 | SET_SEQINTCODE(IGN_WIDE_RES) | ||
901 | jmp mesgin_done; | ||
902 | |||
903 | mesgin_proto_violation: | ||
904 | SET_SEQINTCODE(PROTO_VIOLATION) | ||
905 | jmp mesgin_done; | ||
906 | mesgin_reject: | ||
907 | mvi MSG_MESSAGE_REJECT call mk_mesg; | ||
908 | mesgin_done: | ||
909 | mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ | ||
910 | jmp ITloop; | ||
911 | |||
912 | #define INDEX_DISC_LIST(scsiid, lun) \ | ||
913 | and A, 0xC0, scsiid; \ | ||
914 | or SCBPTR, A, lun; \ | ||
915 | clr SCBPTR[1]; \ | ||
916 | and SINDEX, 0x30, scsiid; \ | ||
917 | shr SINDEX, 3; /* Multiply by 2 */ \ | ||
918 | add SINDEX, (SCB_DISCONNECTED_LISTS & 0xFF); \ | ||
919 | mvi SINDEX[1], ((SCB_DISCONNECTED_LISTS >> 8) & 0xFF) | ||
920 | |||
921 | mesgin_identify: | ||
922 | /* | ||
923 | * Determine whether a target is using tagged or non-tagged | ||
924 | * transactions by first looking at the transaction stored in | ||
925 | * the per-device, disconnected array. If there is no untagged | ||
926 | * transaction for this target, this must be a tagged transaction. | ||
927 | */ | ||
928 | and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; | ||
929 | INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); | ||
930 | bmov DINDEX, SINDEX, 2; | ||
931 | bmov REG0, SINDIR, 2; | ||
932 | cmp REG0[1], SCB_LIST_NULL je snoop_tag; | ||
933 | /* Untagged. Clear the busy table entry and setup the SCB. */ | ||
934 | bmov DINDIR, ALLONES, 2; | ||
935 | bmov SCBPTR, REG0, 2; | ||
936 | jmp setup_SCB; | ||
937 | |||
938 | /* | ||
939 | * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. | ||
940 | * If we get one, we use the tag returned to find the proper | ||
941 | * SCB. After receiving the tag, look for the SCB at SCB locations tag and | ||
942 | * tag + 256. | ||
943 | */ | ||
944 | snoop_tag: | ||
945 | if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { | ||
946 | or SEQ_FLAGS, 0x80; | ||
947 | } | ||
948 | mov NONE, SCSIDAT; /* ACK Identify MSG */ | ||
949 | call phase_lock; | ||
950 | if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { | ||
951 | or SEQ_FLAGS, 0x1; | ||
952 | } | ||
953 | cmp LASTPHASE, P_MESGIN jne not_found_ITloop; | ||
954 | if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { | ||
955 | or SEQ_FLAGS, 0x2; | ||
956 | } | ||
957 | cmp SCSIBUS, MSG_SIMPLE_Q_TAG jne not_found; | ||
958 | get_tag: | ||
959 | clr SCBPTR[1]; | ||
960 | mvi SCBPTR call inb_next; /* tag value */ | ||
961 | verify_scb: | ||
962 | test SCB_CONTROL,DISCONNECTED jz verify_other_scb; | ||
963 | mov A, SAVED_SCSIID; | ||
964 | cmp SCB_SCSIID, A jne verify_other_scb; | ||
965 | mov A, SAVED_LUN; | ||
966 | cmp SCB_LUN, A je setup_SCB_disconnected; | ||
967 | verify_other_scb: | ||
968 | xor SCBPTR[1], 1; | ||
969 | test SCBPTR[1], 0xFF jnz verify_scb; | ||
970 | jmp not_found; | ||
971 | |||
972 | /* | ||
973 | * Ensure that the SCB the tag points to is for | ||
974 | * an SCB transaction to the reconnecting target. | ||
975 | */ | ||
976 | setup_SCB: | ||
977 | if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { | ||
978 | or SEQ_FLAGS, 0x10; | ||
979 | } | ||
980 | test SCB_CONTROL,DISCONNECTED jz not_found; | ||
981 | setup_SCB_disconnected: | ||
982 | and SCB_CONTROL,~DISCONNECTED; | ||
983 | clr SEQ_FLAGS; /* make note of IDENTIFY */ | ||
984 | test SCB_SGPTR, SG_LIST_NULL jnz . + 3; | ||
985 | bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; | ||
986 | call allocate_fifo; | ||
987 | /* See if the host wants to send a message upon reconnection */ | ||
988 | test SCB_CONTROL, MK_MESSAGE jz mesgin_done; | ||
989 | mvi HOST_MSG call mk_mesg; | ||
990 | jmp mesgin_done; | ||
991 | |||
992 | not_found: | ||
993 | SET_SEQINTCODE(NO_MATCH) | ||
994 | jmp mesgin_done; | ||
995 | |||
996 | not_found_ITloop: | ||
997 | SET_SEQINTCODE(NO_MATCH) | ||
998 | jmp ITloop; | ||
999 | |||
1000 | /* | ||
1001 | * We received a "command complete" message. Put the SCB on the complete | ||
1002 | * queue and trigger a completion interrupt via the idle loop. Before doing | ||
1003 | * so, check to see if there | ||
1004 | * is a residual or the status byte is something other than STATUS_GOOD (0). | ||
1005 | * In either of these conditions, we upload the SCB back to the host so it can | ||
1006 | * process this information. In the case of a non zero status byte, we | ||
1007 | * additionally interrupt the kernel driver synchronously, allowing it to | ||
1008 | * decide if sense should be retrieved. If the kernel driver wishes to request | ||
1009 | * sense, it will fill the kernel SCB with a request sense command, requeue | ||
1010 | * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting | ||
1011 | * RETURN_1 to SEND_SENSE. | ||
1012 | */ | ||
1013 | mesgin_complete: | ||
1014 | |||
1015 | /* | ||
1016 | * If ATN is raised, we still want to give the target a message. | ||
1017 | * Perhaps there was a parity error on this last message byte. | ||
1018 | * Either way, the target should take us to message out phase | ||
1019 | * and then attempt to complete the command again. We should use a | ||
1020 | * critical section here to guard against a timeout triggering | ||
1021 | * for this command and setting ATN while we are still processing | ||
1022 | * the completion. | ||
1023 | test SCSISIGI, ATNI jnz mesgin_done; | ||
1024 | */ | ||
1025 | |||
1026 | /* | ||
1027 | * If we are identified and have successfully sent the CDB, | ||
1028 | * any status will do. Optimize this fast path. | ||
1029 | */ | ||
1030 | test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation; | ||
1031 | test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; | ||
1032 | |||
1033 | /* | ||
1034 | * If the target never sent an identify message but instead went | ||
1035 | * to mesgin to give an invalid message, let the host abort us. | ||
1036 | */ | ||
1037 | test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; | ||
1038 | |||
1039 | /* | ||
1040 | * If we recevied good status but never successfully sent the | ||
1041 | * cdb, abort the command. | ||
1042 | */ | ||
1043 | test SCB_SCSI_STATUS,0xff jnz complete_accepted; | ||
1044 | test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation; | ||
1045 | complete_accepted: | ||
1046 | |||
1047 | /* | ||
1048 | * See if we attempted to deliver a message but the target ingnored us. | ||
1049 | */ | ||
1050 | test SCB_CONTROL, MK_MESSAGE jz complete_nomsg; | ||
1051 | SET_SEQINTCODE(MKMSG_FAILED) | ||
1052 | complete_nomsg: | ||
1053 | call queue_scb_completion; | ||
1054 | jmp await_busfree; | ||
1055 | |||
1056 | freeze_queue: | ||
1057 | /* Cancel any pending select-out. */ | ||
1058 | test SSTAT0, SELDO|SELINGO jnz . + 2; | ||
1059 | and SCSISEQ0, ~ENSELO; | ||
1060 | mov ACCUM_SAVE, A; | ||
1061 | clr A; | ||
1062 | add QFREEZE_COUNT, 1; | ||
1063 | adc QFREEZE_COUNT[1], A; | ||
1064 | or SEQ_FLAGS2, SELECTOUT_QFROZEN; | ||
1065 | mov A, ACCUM_SAVE ret; | ||
1066 | |||
1067 | /* | ||
1068 | * Complete the current FIFO's SCB if data for this same | ||
1069 | * SCB is not transferring in the other FIFO. | ||
1070 | */ | ||
1071 | SET_SRC_MODE M_DFF1; | ||
1072 | SET_DST_MODE M_DFF1; | ||
1073 | pkt_complete_scb_if_fifos_idle: | ||
1074 | bmov ARG_1, SCBPTR, 2; | ||
1075 | mvi DFFSXFRCTL, CLRCHN; | ||
1076 | SET_MODE(M_SCSI, M_SCSI) | ||
1077 | bmov SCBPTR, ARG_1, 2; | ||
1078 | test SCB_FIFO_USE_COUNT, 0xFF jnz return; | ||
1079 | queue_scb_completion: | ||
1080 | test SCB_SCSI_STATUS,0xff jnz bad_status; | ||
1081 | /* | ||
1082 | * Check for residuals | ||
1083 | */ | ||
1084 | test SCB_SGPTR, SG_LIST_NULL jnz complete; /* No xfer */ | ||
1085 | test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ | ||
1086 | test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; | ||
1087 | complete: | ||
1088 | bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; | ||
1089 | bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; | ||
1090 | bad_status: | ||
1091 | cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb; | ||
1092 | call freeze_queue; | ||
1093 | upload_scb: | ||
1094 | /* | ||
1095 | * Restore SCB TAG since we reuse this field | ||
1096 | * in the sequencer. We don't want to corrupt | ||
1097 | * it on the host. | ||
1098 | */ | ||
1099 | bmov SCB_TAG, SCBPTR, 2; | ||
1100 | bmov SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2; | ||
1101 | bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2; | ||
1102 | or SCB_SGPTR, SG_STATUS_VALID ret; | ||
1103 | |||
1104 | /* | ||
1105 | * Is it a disconnect message? Set a flag in the SCB to remind us | ||
1106 | * and await the bus going free. If this is an untagged transaction | ||
1107 | * store the SCB id for it in our untagged target table for lookup on | ||
1108 | * a reselction. | ||
1109 | */ | ||
1110 | mesgin_disconnect: | ||
1111 | /* | ||
1112 | * If ATN is raised, we still want to give the target a message. | ||
1113 | * Perhaps there was a parity error on this last message byte | ||
1114 | * or we want to abort this command. Either way, the target | ||
1115 | * should take us to message out phase and then attempt to | ||
1116 | * disconnect again. | ||
1117 | * XXX - Wait for more testing. | ||
1118 | test SCSISIGI, ATNI jnz mesgin_done; | ||
1119 | */ | ||
1120 | test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT | ||
1121 | jnz mesgin_proto_violation; | ||
1122 | or SCB_CONTROL,DISCONNECTED; | ||
1123 | test SCB_CONTROL, TAG_ENB jnz await_busfree; | ||
1124 | queue_disc_scb: | ||
1125 | bmov REG0, SCBPTR, 2; | ||
1126 | INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); | ||
1127 | bmov DINDEX, SINDEX, 2; | ||
1128 | bmov DINDIR, REG0, 2; | ||
1129 | bmov SCBPTR, REG0, 2; | ||
1130 | /* FALLTHROUGH */ | ||
1131 | await_busfree: | ||
1132 | and SIMODE1, ~ENBUSFREE; | ||
1133 | if ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0) { | ||
1134 | /* | ||
1135 | * In the BUSFREEREV_BUG case, the | ||
1136 | * busfree status was cleared at the | ||
1137 | * beginning of the connection. | ||
1138 | */ | ||
1139 | mvi CLRSINT1,CLRBUSFREE; | ||
1140 | } | ||
1141 | mov NONE, SCSIDAT; /* Ack the last byte */ | ||
1142 | test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) | ||
1143 | jnz await_busfree_not_m_dff; | ||
1144 | SET_SRC_MODE M_DFF1; | ||
1145 | SET_DST_MODE M_DFF1; | ||
1146 | await_busfree_clrchn: | ||
1147 | mvi DFFSXFRCTL, CLRCHN; | ||
1148 | await_busfree_not_m_dff: | ||
1149 | call clear_target_state; | ||
1150 | test SSTAT1,REQINIT|BUSFREE jz .; | ||
1151 | test SSTAT1, BUSFREE jnz idle_loop; | ||
1152 | SET_SEQINTCODE(MISSED_BUSFREE) | ||
1153 | |||
1154 | |||
1155 | /* | ||
1156 | * Save data pointers message: | ||
1157 | * Copying RAM values back to SCB, for Save Data Pointers message, but | ||
1158 | * only if we've actually been into a data phase to change them. This | ||
1159 | * protects against bogus data in scratch ram and the residual counts | ||
1160 | * since they are only initialized when we go into data_in or data_out. | ||
1161 | * Ack the message as soon as possible. | ||
1162 | */ | ||
1163 | SET_SRC_MODE M_DFF1; | ||
1164 | SET_DST_MODE M_DFF1; | ||
1165 | mesgin_sdptrs: | ||
1166 | mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ | ||
1167 | test SEQ_FLAGS, DPHASE jz ITloop; | ||
1168 | call save_pointers; | ||
1169 | jmp ITloop; | ||
1170 | |||
1171 | save_pointers: | ||
1172 | /* | ||
1173 | * If we are asked to save our position at the end of the | ||
1174 | * transfer, just mark us at the end rather than perform a | ||
1175 | * full save. | ||
1176 | */ | ||
1177 | test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz save_pointers_full; | ||
1178 | or SCB_SGPTR, SG_LIST_NULL ret; | ||
1179 | |||
1180 | save_pointers_full: | ||
1181 | /* | ||
1182 | * The SCB_DATAPTR becomes the current SHADDR. | ||
1183 | * All other information comes directly from our residual | ||
1184 | * state. | ||
1185 | */ | ||
1186 | bmov SCB_DATAPTR, SHADDR, 8; | ||
1187 | bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8 ret; | ||
1188 | |||
1189 | /* | ||
1190 | * Restore pointers message? Data pointers are recopied from the | ||
1191 | * SCB anytime we enter a data phase for the first time, so all | ||
1192 | * we need to do is clear the DPHASE flag and let the data phase | ||
1193 | * code do the rest. We also reset/reallocate the FIFO to make | ||
1194 | * sure we have a clean start for the next data or command phase. | ||
1195 | */ | ||
1196 | mesgin_rdptrs: | ||
1197 | and SEQ_FLAGS, ~DPHASE; | ||
1198 | test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz msgin_rdptrs_get_fifo; | ||
1199 | mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; | ||
1200 | SET_MODE(M_SCSI, M_SCSI) | ||
1201 | msgin_rdptrs_get_fifo: | ||
1202 | call allocate_fifo; | ||
1203 | jmp mesgin_done; | ||
1204 | |||
1205 | clear_target_state: | ||
1206 | mvi LASTPHASE, P_BUSFREE; | ||
1207 | /* clear target specific flags */ | ||
1208 | mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret; | ||
1209 | |||
1210 | phase_lock: | ||
1211 | if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) { | ||
1212 | /* | ||
1213 | * Don't ignore persistent REQ assertions just because | ||
1214 | * they were asserted within the bus settle delay window. | ||
1215 | * This allows us to tolerate devices like the GEM318 | ||
1216 | * that violate the SCSI spec. We are careful not to | ||
1217 | * count REQ while we are waiting for it to fall during | ||
1218 | * an async phase due to our asserted ACK. Each | ||
1219 | * sequencer instruction takes ~25ns, so the REQ must | ||
1220 | * last at least 100ns in order to be counted as a true | ||
1221 | * REQ. | ||
1222 | */ | ||
1223 | test SCSIPHASE, 0xFF jnz phase_locked; | ||
1224 | test SCSISIGI, ACKI jnz phase_lock; | ||
1225 | test SCSISIGI, REQI jz phase_lock; | ||
1226 | test SCSIPHASE, 0xFF jnz phase_locked; | ||
1227 | test SCSISIGI, ACKI jnz phase_lock; | ||
1228 | test SCSISIGI, REQI jz phase_lock; | ||
1229 | phase_locked: | ||
1230 | } else { | ||
1231 | test SCSIPHASE, 0xFF jz .; | ||
1232 | } | ||
1233 | test SSTAT1, SCSIPERR jnz phase_lock; | ||
1234 | phase_lock_latch_phase: | ||
1235 | and LASTPHASE, PHASE_MASK, SCSISIGI ret; | ||
1236 | |||
1237 | /* | ||
1238 | * Functions to read data in Automatic PIO mode. | ||
1239 | * | ||
1240 | * An ACK is not sent on input from the target until SCSIDATL is read from. | ||
1241 | * So we wait until SCSIDATL is latched (the usual way), then read the data | ||
1242 | * byte directly off the bus using SCSIBUSL. When we have pulled the ATN | ||
1243 | * line, or we just want to acknowledge the byte, then we do a dummy read | ||
1244 | * from SCISDATL. The SCSI spec guarantees that the target will hold the | ||
1245 | * data byte on the bus until we send our ACK. | ||
1246 | * | ||
1247 | * The assumption here is that these are called in a particular sequence, | ||
1248 | * and that REQ is already set when inb_first is called. inb_{first,next} | ||
1249 | * use the same calling convention as inb. | ||
1250 | */ | ||
1251 | inb_next: | ||
1252 | mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ | ||
1253 | inb_next_wait: | ||
1254 | /* | ||
1255 | * If there is a parity error, wait for the kernel to | ||
1256 | * see the interrupt and prepare our message response | ||
1257 | * before continuing. | ||
1258 | */ | ||
1259 | test SCSIPHASE, 0xFF jz .; | ||
1260 | test SSTAT1, SCSIPERR jnz inb_next_wait; | ||
1261 | inb_next_check_phase: | ||
1262 | and LASTPHASE, PHASE_MASK, SCSISIGI; | ||
1263 | cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; | ||
1264 | inb_first: | ||
1265 | clr DINDEX[1]; | ||
1266 | mov DINDEX,SINDEX; | ||
1267 | mov DINDIR,SCSIBUS ret; /*read byte directly from bus*/ | ||
1268 | inb_last: | ||
1269 | mov NONE,SCSIDAT ret; /*dummy read from latch to ACK*/ | ||
1270 | |||
1271 | mk_mesg: | ||
1272 | mvi SCSISIGO, ATNO; | ||
1273 | mov MSG_OUT,SINDEX ret; | ||
1274 | |||
1275 | SET_SRC_MODE M_DFF1; | ||
1276 | SET_DST_MODE M_DFF1; | ||
1277 | disable_ccsgen: | ||
1278 | test SG_STATE, FETCH_INPROG jz disable_ccsgen_fetch_done; | ||
1279 | clr CCSGCTL; | ||
1280 | disable_ccsgen_fetch_done: | ||
1281 | clr SG_STATE ret; | ||
1282 | |||
1283 | service_fifo: | ||
1284 | /* | ||
1285 | * Do we have any prefetch left??? | ||
1286 | */ | ||
1287 | test SG_STATE, SEGS_AVAIL jnz idle_sg_avail; | ||
1288 | |||
1289 | /* | ||
1290 | * Can this FIFO have access to the S/G cache yet? | ||
1291 | */ | ||
1292 | test CCSGCTL, SG_CACHE_AVAIL jz return; | ||
1293 | |||
1294 | /* Did we just finish fetching segs? */ | ||
1295 | test CCSGCTL, CCSGDONE jnz idle_sgfetch_complete; | ||
1296 | |||
1297 | /* Are we actively fetching segments? */ | ||
1298 | test CCSGCTL, CCSGENACK jnz return; | ||
1299 | |||
1300 | /* | ||
1301 | * We fetch a "cacheline aligned" and sized amount of data | ||
1302 | * so we don't end up referencing a non-existant page. | ||
1303 | * Cacheline aligned is in quotes because the kernel will | ||
1304 | * set the prefetch amount to a reasonable level if the | ||
1305 | * cacheline size is unknown. | ||
1306 | */ | ||
1307 | bmov SGHADDR, SCB_RESIDUAL_SGPTR, 4; | ||
1308 | mvi SGHCNT, SG_PREFETCH_CNT; | ||
1309 | if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) { | ||
1310 | /* | ||
1311 | * Need two instruction between "touches" of SGHADDR. | ||
1312 | */ | ||
1313 | nop; | ||
1314 | } | ||
1315 | and SGHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR; | ||
1316 | mvi CCSGCTL, CCSGEN|CCSGRESET; | ||
1317 | or SG_STATE, FETCH_INPROG ret; | ||
1318 | idle_sgfetch_complete: | ||
1319 | /* | ||
1320 | * Guard against SG_CACHE_AVAIL activating during sg fetch | ||
1321 | * request in the other FIFO. | ||
1322 | */ | ||
1323 | test SG_STATE, FETCH_INPROG jz return; | ||
1324 | clr CCSGCTL; | ||
1325 | and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR; | ||
1326 | mvi SG_STATE, SEGS_AVAIL|LOADING_NEEDED; | ||
1327 | idle_sg_avail: | ||
1328 | /* Does the hardware have space for another SG entry? */ | ||
1329 | test DFSTATUS, PRELOAD_AVAIL jz return; | ||
1330 | /* | ||
1331 | * On the A, preloading a segment before HDMAENACK | ||
1332 | * comes true can clobber the shaddow address of the | ||
1333 | * first segment in the S/G FIFO. Wait until it is | ||
1334 | * safe to proceed. | ||
1335 | */ | ||
1336 | if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0) { | ||
1337 | test DFCNTRL, HDMAENACK jz return; | ||
1338 | } | ||
1339 | if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { | ||
1340 | bmov HADDR, CCSGRAM, 8; | ||
1341 | } else { | ||
1342 | bmov HADDR, CCSGRAM, 4; | ||
1343 | } | ||
1344 | bmov HCNT, CCSGRAM, 3; | ||
1345 | bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; | ||
1346 | if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { | ||
1347 | and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3]; | ||
1348 | } | ||
1349 | if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { | ||
1350 | /* Skip 4 bytes of pad. */ | ||
1351 | add CCSGADDR, 4; | ||
1352 | } | ||
1353 | sg_advance: | ||
1354 | clr A; /* add sizeof(struct scatter) */ | ||
1355 | add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF; | ||
1356 | adc SCB_RESIDUAL_SGPTR[1],A; | ||
1357 | adc SCB_RESIDUAL_SGPTR[2],A; | ||
1358 | adc SCB_RESIDUAL_SGPTR[3],A; | ||
1359 | mov SINDEX, SCB_RESIDUAL_SGPTR[0]; | ||
1360 | test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3; | ||
1361 | or SINDEX, LAST_SEG; | ||
1362 | clr SG_STATE; | ||
1363 | mov SG_CACHE_PRE, SINDEX; | ||
1364 | if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) { | ||
1365 | /* | ||
1366 | * Use SCSIENWRDIS so that SCSIEN is never | ||
1367 | * modified by this operation. | ||
1368 | */ | ||
1369 | or DFCNTRL, PRELOADEN|HDMAEN|SCSIENWRDIS; | ||
1370 | } else { | ||
1371 | or DFCNTRL, PRELOADEN|HDMAEN; | ||
1372 | } | ||
1373 | /* | ||
1374 | * Do we have another segment in the cache? | ||
1375 | */ | ||
1376 | add NONE, SG_PREFETCH_CNT_LIMIT, CCSGADDR; | ||
1377 | jnc return; | ||
1378 | and SG_STATE, ~SEGS_AVAIL ret; | ||
1379 | |||
1380 | /* | ||
1381 | * Initialize the DMA address and counter from the SCB. | ||
1382 | */ | ||
1383 | load_first_seg: | ||
1384 | bmov HADDR, SCB_DATAPTR, 11; | ||
1385 | and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0]; | ||
1386 | test SCB_DATACNT[3], SG_LAST_SEG jz . + 2; | ||
1387 | or REG_ISR, LAST_SEG; | ||
1388 | mov SG_CACHE_PRE, REG_ISR; | ||
1389 | mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); | ||
1390 | /* | ||
1391 | * Since we've are entering a data phase, we will | ||
1392 | * rely on the SCB_RESID* fields. Initialize the | ||
1393 | * residual and clear the full residual flag. | ||
1394 | */ | ||
1395 | and SCB_SGPTR[0], ~SG_FULL_RESID; | ||
1396 | bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5; | ||
1397 | /* If we need more S/G elements, tell the idle loop */ | ||
1398 | test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz . + 2; | ||
1399 | mvi SG_STATE, LOADING_NEEDED ret; | ||
1400 | clr SG_STATE ret; | ||
1401 | |||
1402 | p_data_handle_xfer: | ||
1403 | call setjmp; | ||
1404 | test SG_STATE, LOADING_NEEDED jnz service_fifo; | ||
1405 | p_data_clear_handler: | ||
1406 | or LONGJMP_ADDR[1], INVALID_ADDR ret; | ||
1407 | |||
1408 | p_data: | ||
1409 | test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed; | ||
1410 | SET_SEQINTCODE(PROTO_VIOLATION) | ||
1411 | p_data_allowed: | ||
1412 | |||
1413 | test SEQ_FLAGS, DPHASE jz data_phase_initialize; | ||
1414 | |||
1415 | /* | ||
1416 | * If we re-enter the data phase after going through another | ||
1417 | * phase, our transfer location has almost certainly been | ||
1418 | * corrupted by the interveining, non-data, transfers. Ask | ||
1419 | * the host driver to fix us up based on the transfer residual | ||
1420 | * unless we already know that we should be bitbucketing. | ||
1421 | */ | ||
1422 | test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; | ||
1423 | SET_SEQINTCODE(PDATA_REINIT) | ||
1424 | jmp data_phase_inbounds; | ||
1425 | |||
1426 | p_data_bitbucket: | ||
1427 | /* | ||
1428 | * Turn on `Bit Bucket' mode, wait until the target takes | ||
1429 | * us to another phase, and then notify the host. | ||
1430 | */ | ||
1431 | mov SAVED_MODE, MODE_PTR; | ||
1432 | test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) | ||
1433 | jnz bitbucket_not_m_dff; | ||
1434 | /* | ||
1435 | * Ensure that any FIFO contents are cleared out and the | ||
1436 | * FIFO free'd prior to starting the BITBUCKET. BITBUCKET | ||
1437 | * doesn't discard data already in the FIFO. | ||
1438 | */ | ||
1439 | mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; | ||
1440 | SET_MODE(M_SCSI, M_SCSI) | ||
1441 | bitbucket_not_m_dff: | ||
1442 | or SXFRCTL1,BITBUCKET; | ||
1443 | /* Wait for non-data phase. */ | ||
1444 | test SCSIPHASE, ~DATA_PHASE_MASK jz .; | ||
1445 | and SXFRCTL1, ~BITBUCKET; | ||
1446 | RESTORE_MODE(SAVED_MODE) | ||
1447 | SET_SRC_MODE M_DFF1; | ||
1448 | SET_DST_MODE M_DFF1; | ||
1449 | SET_SEQINTCODE(DATA_OVERRUN) | ||
1450 | jmp ITloop; | ||
1451 | |||
1452 | data_phase_initialize: | ||
1453 | test SCB_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; | ||
1454 | call load_first_seg; | ||
1455 | data_phase_inbounds: | ||
1456 | /* We have seen a data phase at least once. */ | ||
1457 | or SEQ_FLAGS, DPHASE; | ||
1458 | mov SAVED_MODE, MODE_PTR; | ||
1459 | test SG_STATE, LOADING_NEEDED jz data_group_dma_loop; | ||
1460 | call p_data_handle_xfer; | ||
1461 | data_group_dma_loop: | ||
1462 | /* | ||
1463 | * The transfer is complete if either the last segment | ||
1464 | * completes or the target changes phase. Both conditions | ||
1465 | * will clear SCSIEN. | ||
1466 | */ | ||
1467 | call idle_loop_service_fifos; | ||
1468 | call idle_loop_cchan; | ||
1469 | call idle_loop_gsfifo; | ||
1470 | RESTORE_MODE(SAVED_MODE) | ||
1471 | test DFCNTRL, SCSIEN jnz data_group_dma_loop; | ||
1472 | |||
1473 | data_group_dmafinish: | ||
1474 | /* | ||
1475 | * The transfer has terminated either due to a phase | ||
1476 | * change, and/or the completion of the last segment. | ||
1477 | * We have two goals here. Do as much other work | ||
1478 | * as possible while the data fifo drains on a read | ||
1479 | * and respond as quickly as possible to the standard | ||
1480 | * messages (save data pointers/disconnect and command | ||
1481 | * complete) that usually follow a data phase. | ||
1482 | */ | ||
1483 | call calc_residual; | ||
1484 | |||
1485 | /* | ||
1486 | * Go ahead and shut down the DMA engine now. | ||
1487 | */ | ||
1488 | test DFCNTRL, DIRECTION jnz data_phase_finish; | ||
1489 | data_group_fifoflush: | ||
1490 | if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { | ||
1491 | or DFCNTRL, FIFOFLUSH; | ||
1492 | } | ||
1493 | /* | ||
1494 | * We have enabled the auto-ack feature. This means | ||
1495 | * that the controller may have already transferred | ||
1496 | * some overrun bytes into the data FIFO and acked them | ||
1497 | * on the bus. The only way to detect this situation is | ||
1498 | * to wait for LAST_SEG_DONE to come true on a completed | ||
1499 | * transfer and then test to see if the data FIFO is | ||
1500 | * non-empty. We know there is more data yet to transfer | ||
1501 | * if SG_LIST_NULL is not yet set, thus there cannot be | ||
1502 | * an overrun. | ||
1503 | */ | ||
1504 | test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_finish; | ||
1505 | test SG_CACHE_SHADOW, LAST_SEG_DONE jz .; | ||
1506 | test DFSTATUS, FIFOEMP jnz data_phase_finish; | ||
1507 | /* Overrun */ | ||
1508 | jmp p_data; | ||
1509 | data_phase_finish: | ||
1510 | /* | ||
1511 | * If the target has left us in data phase, loop through | ||
1512 | * the dma code again. We will only loop if there is a | ||
1513 | * data overrun. | ||
1514 | */ | ||
1515 | if ((ahd->flags & AHD_TARGETROLE) != 0) { | ||
1516 | test SSTAT0, TARGET jnz data_phase_done; | ||
1517 | } | ||
1518 | if ((ahd->flags & AHD_INITIATORROLE) != 0) { | ||
1519 | test SSTAT1, REQINIT jz .; | ||
1520 | test SCSIPHASE, DATA_PHASE_MASK jnz p_data; | ||
1521 | } | ||
1522 | |||
1523 | data_phase_done: | ||
1524 | /* Kill off any pending prefetch */ | ||
1525 | call disable_ccsgen; | ||
1526 | or LONGJMP_ADDR[1], INVALID_ADDR; | ||
1527 | |||
1528 | if ((ahd->flags & AHD_TARGETROLE) != 0) { | ||
1529 | test SEQ_FLAGS, DPHASE_PENDING jz ITloop; | ||
1530 | /* | ||
1531 | and SEQ_FLAGS, ~DPHASE_PENDING; | ||
1532 | * For data-in phases, wait for any pending acks from the | ||
1533 | * initiator before changing phase. We only need to | ||
1534 | * send Ignore Wide Residue messages for data-in phases. | ||
1535 | test DFCNTRL, DIRECTION jz target_ITloop; | ||
1536 | test SSTAT1, REQINIT jnz .; | ||
1537 | test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jz target_ITloop; | ||
1538 | SET_MODE(M_SCSI, M_SCSI) | ||
1539 | test NEGCONOPTS, WIDEXFER jz target_ITloop; | ||
1540 | */ | ||
1541 | /* | ||
1542 | * Issue an Ignore Wide Residue Message. | ||
1543 | mvi P_MESGIN|BSYO call change_phase; | ||
1544 | mvi MSG_IGN_WIDE_RESIDUE call target_outb; | ||
1545 | mvi 1 call target_outb; | ||
1546 | jmp target_ITloop; | ||
1547 | */ | ||
1548 | } else { | ||
1549 | jmp ITloop; | ||
1550 | } | ||
1551 | |||
1552 | /* | ||
1553 | * We assume that, even though data may still be | ||
1554 | * transferring to the host, that the SCSI side of | ||
1555 | * the DMA engine is now in a static state. This | ||
1556 | * allows us to update our notion of where we are | ||
1557 | * in this transfer. | ||
1558 | * | ||
1559 | * If, by chance, we stopped before being able | ||
1560 | * to fetch additional segments for this transfer, | ||
1561 | * yet the last S/G was completely exhausted, | ||
1562 | * call our idle loop until it is able to load | ||
1563 | * another segment. This will allow us to immediately | ||
1564 | * pickup on the next segment on the next data phase. | ||
1565 | * | ||
1566 | * If we happened to stop on the last segment, then | ||
1567 | * our residual information is still correct from | ||
1568 | * the idle loop and there is no need to perform | ||
1569 | * any fixups. | ||
1570 | */ | ||
1571 | residual_before_last_seg: | ||
1572 | test MDFFSTAT, SHVALID jnz sgptr_fixup; | ||
1573 | /* | ||
1574 | * Can never happen from an interrupt as the packetized | ||
1575 | * hardware will only interrupt us once SHVALID or | ||
1576 | * LAST_SEG_DONE. | ||
1577 | */ | ||
1578 | call idle_loop_service_fifos; | ||
1579 | RESTORE_MODE(SAVED_MODE) | ||
1580 | /* FALLTHROUGH */ | ||
1581 | calc_residual: | ||
1582 | test SG_CACHE_SHADOW, LAST_SEG jz residual_before_last_seg; | ||
1583 | /* Record if we've consumed all S/G entries */ | ||
1584 | test MDFFSTAT, SHVALID jz . + 2; | ||
1585 | bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; | ||
1586 | or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL ret; | ||
1587 | |||
1588 | sgptr_fixup: | ||
1589 | /* | ||
1590 | * Fixup the residual next S/G pointer. The S/G preload | ||
1591 | * feature of the chip allows us to load two elements | ||
1592 | * in addition to the currently active element. We | ||
1593 | * store the bottom byte of the next S/G pointer in | ||
1594 | * the SG_CACHE_PTR register so we can restore the | ||
1595 | * correct value when the DMA completes. If the next | ||
1596 | * sg ptr value has advanced to the point where higher | ||
1597 | * bytes in the address have been affected, fix them | ||
1598 | * too. | ||
1599 | */ | ||
1600 | test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done; | ||
1601 | test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done; | ||
1602 | add SCB_RESIDUAL_SGPTR[1], -1; | ||
1603 | adc SCB_RESIDUAL_SGPTR[2], -1; | ||
1604 | adc SCB_RESIDUAL_SGPTR[3], -1; | ||
1605 | sgptr_fixup_done: | ||
1606 | and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; | ||
1607 | clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */ | ||
1608 | bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; | ||
1609 | |||
1610 | export timer_isr: | ||
1611 | call issue_cmdcmplt; | ||
1612 | mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; | ||
1613 | if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { | ||
1614 | /* | ||
1615 | * In H2A4, the mode pointer is not saved | ||
1616 | * for intvec2, but is restored on iret. | ||
1617 | * This can lead to the restoration of a | ||
1618 | * bogus mode ptr. Manually clear the | ||
1619 | * intmask bits and do a normal return | ||
1620 | * to compensate. | ||
1621 | */ | ||
1622 | and SEQINTCTL, ~(INTMASK2|INTMASK1) ret; | ||
1623 | } else { | ||
1624 | or SEQINTCTL, IRET ret; | ||
1625 | } | ||
1626 | |||
1627 | export seq_isr: | ||
1628 | if ((ahd->features & AHD_RTI) == 0) { | ||
1629 | /* | ||
1630 | * On RevA Silicon, if the target returns us to data-out | ||
1631 | * after we have already trained for data-out, it is | ||
1632 | * possible for us to transition the free running clock to | ||
1633 | * data-valid before the required 100ns P1 setup time (8 P1 | ||
1634 | * assertions in fast-160 mode). This will only happen if | ||
1635 | * this L-Q is a continuation of a data transfer for which | ||
1636 | * we have already prefetched data into our FIFO (LQ/Data | ||
1637 | * followed by LQ/Data for the same write transaction). | ||
1638 | * This can cause some target implementations to miss the | ||
1639 | * first few data transfers on the bus. We detect this | ||
1640 | * situation by noticing that this is the first data transfer | ||
1641 | * after an LQ (LQIWORKONLQ true), that the data transfer is | ||
1642 | * a continuation of a transfer already setup in our FIFO | ||
1643 | * (SAVEPTRS interrupt), and that the transaction is a write | ||
1644 | * (DIRECTION set in DFCNTRL). The delay is performed by | ||
1645 | * disabling SCSIEN until we see the first REQ from the | ||
1646 | * target. | ||
1647 | * | ||
1648 | * First instruction in an ISR cannot be a branch on | ||
1649 | * Rev A. Snapshot LQISTAT2 so the status is not missed | ||
1650 | * and deffer the test by one instruction. | ||
1651 | */ | ||
1652 | mov REG_ISR, LQISTAT2; | ||
1653 | test REG_ISR, LQIWORKONLQ jz main_isr; | ||
1654 | test SEQINTSRC, SAVEPTRS jz main_isr; | ||
1655 | test LONGJMP_ADDR[1], INVALID_ADDR jz saveptr_active_fifo; | ||
1656 | /* | ||
1657 | * Switch to the active FIFO after clearing the snapshot | ||
1658 | * savepointer in the current FIFO. We do this so that | ||
1659 | * a pending CTXTDONE or SAVEPTR is visible in the active | ||
1660 | * FIFO. This status is the only way we can detect if we | ||
1661 | * have lost the race (e.g. host paused us) and our attepts | ||
1662 | * to disable the channel occurred after all REQs were | ||
1663 | * already seen and acked (REQINIT never comes true). | ||
1664 | */ | ||
1665 | mvi DFFSXFRCTL, CLRCHN; | ||
1666 | xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); | ||
1667 | test DFCNTRL, DIRECTION jz interrupt_return; | ||
1668 | and DFCNTRL, ~SCSIEN; | ||
1669 | snapshot_wait_data_valid: | ||
1670 | test SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz snapshot_data_valid; | ||
1671 | test SSTAT1, REQINIT jz snapshot_wait_data_valid; | ||
1672 | snapshot_data_valid: | ||
1673 | or DFCNTRL, SCSIEN; | ||
1674 | or SEQINTCTL, IRET ret; | ||
1675 | snapshot_saveptr: | ||
1676 | mvi DFFSXFRCTL, CLRCHN; | ||
1677 | or SEQINTCTL, IRET ret; | ||
1678 | main_isr: | ||
1679 | } | ||
1680 | test SEQINTSRC, CFG4DATA jnz cfg4data_intr; | ||
1681 | test SEQINTSRC, CFG4ISTAT jnz cfg4istat_intr; | ||
1682 | test SEQINTSRC, SAVEPTRS jnz saveptr_intr; | ||
1683 | test SEQINTSRC, CFG4ICMD jnz cfg4icmd_intr; | ||
1684 | SET_SEQINTCODE(INVALID_SEQINT) | ||
1685 | |||
1686 | /* | ||
1687 | * There are two types of save pointers interrupts: | ||
1688 | * The first is a snapshot save pointers where the current FIFO is not | ||
1689 | * active and contains a snapshot of the current poniter information. | ||
1690 | * This happens between packets in a stream for a single L_Q. Since we | ||
1691 | * are not performing a pointer save, we can safely clear the channel | ||
1692 | * so it can be used for other transactions. On RTI capable controllers, | ||
1693 | * where snapshots can, and are, disabled, the code to handle this type | ||
1694 | * of snapshot is not active. | ||
1695 | * | ||
1696 | * The second case is a save pointers on an active FIFO which occurs | ||
1697 | * if the target changes to a new L_Q or busfrees/QASes and the transfer | ||
1698 | * has a residual. This should occur coincident with a ctxtdone. We | ||
1699 | * disable the interrupt and allow our active routine to handle the | ||
1700 | * save. | ||
1701 | */ | ||
1702 | saveptr_intr: | ||
1703 | if ((ahd->features & AHD_RTI) == 0) { | ||
1704 | test LONGJMP_ADDR[1], INVALID_ADDR jnz snapshot_saveptr; | ||
1705 | } | ||
1706 | saveptr_active_fifo: | ||
1707 | and SEQIMODE, ~ENSAVEPTRS; | ||
1708 | or SEQINTCTL, IRET ret; | ||
1709 | |||
1710 | cfg4data_intr: | ||
1711 | test SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun_inc_use_count; | ||
1712 | call load_first_seg; | ||
1713 | call pkt_handle_xfer; | ||
1714 | inc SCB_FIFO_USE_COUNT; | ||
1715 | interrupt_return: | ||
1716 | or SEQINTCTL, IRET ret; | ||
1717 | |||
1718 | cfg4istat_intr: | ||
1719 | call freeze_queue; | ||
1720 | add NONE, -13, SCB_CDB_LEN; | ||
1721 | jnc cfg4istat_have_sense_addr; | ||
1722 | test SCB_CDB_LEN, SCB_CDB_LEN_PTR jnz cfg4istat_have_sense_addr; | ||
1723 | /* | ||
1724 | * Host sets up address/count and enables transfer. | ||
1725 | */ | ||
1726 | SET_SEQINTCODE(CFG4ISTAT_INTR) | ||
1727 | jmp cfg4istat_setup_handler; | ||
1728 | cfg4istat_have_sense_addr: | ||
1729 | bmov HADDR, SCB_SENSE_BUSADDR, 4; | ||
1730 | mvi HCNT[1], (AHD_SENSE_BUFSIZE >> 8); | ||
1731 | mvi SG_CACHE_PRE, LAST_SEG; | ||
1732 | mvi DFCNTRL, PRELOADEN|SCSIEN|HDMAEN; | ||
1733 | cfg4istat_setup_handler: | ||
1734 | /* | ||
1735 | * Status pkt is transferring to host. | ||
1736 | * Wait in idle loop for transfer to complete. | ||
1737 | * If a command completed before an attempted | ||
1738 | * task management function completed, notify the host. | ||
1739 | */ | ||
1740 | test SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func; | ||
1741 | SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) | ||
1742 | cfg4istat_no_taskmgmt_func: | ||
1743 | call pkt_handle_status; | ||
1744 | or SEQINTCTL, IRET ret; | ||
1745 | |||
1746 | cfg4icmd_intr: | ||
1747 | /* | ||
1748 | * In the case of DMAing a CDB from the host, the normal | ||
1749 | * CDB buffer is formatted with an 8 byte address followed | ||
1750 | * by a 1 byte count. | ||
1751 | */ | ||
1752 | bmov HADDR[0], SCB_HOST_CDB_PTR, 9; | ||
1753 | mvi SG_CACHE_PRE, LAST_SEG; | ||
1754 | mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); | ||
1755 | call pkt_handle_cdb; | ||
1756 | or SEQINTCTL, IRET ret; | ||
1757 | |||
1758 | /* | ||
1759 | * See if the target has gone on in this context creating an | ||
1760 | * overrun condition. For the write case, the hardware cannot | ||
1761 | * ack bytes until data are provided. So, if the target begins | ||
1762 | * another packet without changing contexts, implying we are | ||
1763 | * not sitting on a packet boundary, we are in an overrun | ||
1764 | * situation. For the read case, the hardware will continue to | ||
1765 | * ack bytes into the FIFO, and may even ack the last overrun packet | ||
1766 | * into the FIFO. If the FIFO should become non-empty, we are in | ||
1767 | * a read overrun case. | ||
1768 | */ | ||
1769 | #define check_overrun \ | ||
1770 | /* Not on a packet boundary. */ \ | ||
1771 | test MDFFSTAT, DLZERO jz pkt_handle_overrun; \ | ||
1772 | test DFSTATUS, FIFOEMP jz pkt_handle_overrun | ||
1773 | |||
1774 | pkt_handle_xfer: | ||
1775 | test SG_STATE, LOADING_NEEDED jz pkt_last_seg; | ||
1776 | call setjmp; | ||
1777 | test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; | ||
1778 | test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; | ||
1779 | test SCSISIGO, ATNO jnz . + 2; | ||
1780 | test SSTAT2, NONPACKREQ jz pkt_service_fifo; | ||
1781 | /* | ||
1782 | * Defer handling of this NONPACKREQ until we | ||
1783 | * can be sure it pertains to this FIFO. SAVEPTRS | ||
1784 | * will not be asserted if the NONPACKREQ is for us, | ||
1785 | * so we must simulate it if shaddow is valid. If | ||
1786 | * shaddow is not valid, keep running this FIFO until we | ||
1787 | * have satisfied the transfer by loading segments and | ||
1788 | * waiting for either shaddow valid or last_seg_done. | ||
1789 | */ | ||
1790 | test MDFFSTAT, SHVALID jnz pkt_saveptrs; | ||
1791 | pkt_service_fifo: | ||
1792 | test SG_STATE, LOADING_NEEDED jnz service_fifo; | ||
1793 | pkt_last_seg: | ||
1794 | call setjmp; | ||
1795 | test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; | ||
1796 | test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_last_seg_done; | ||
1797 | test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; | ||
1798 | test SCSISIGO, ATNO jnz . + 2; | ||
1799 | test SSTAT2, NONPACKREQ jz return; | ||
1800 | test MDFFSTAT, SHVALID jz return; | ||
1801 | /* FALLTHROUGH */ | ||
1802 | |||
1803 | /* | ||
1804 | * Either a SAVEPTRS interrupt condition is pending for this FIFO | ||
1805 | * or we have a pending NONPACKREQ for this FIFO. We differentiate | ||
1806 | * between the two by capturing the state of the SAVEPTRS interrupt | ||
1807 | * prior to clearing this status and executing the common code for | ||
1808 | * these two cases. | ||
1809 | */ | ||
1810 | pkt_saveptrs: | ||
1811 | BEGIN_CRITICAL; | ||
1812 | if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { | ||
1813 | or DFCNTRL, FIFOFLUSH; | ||
1814 | } | ||
1815 | mov REG0, SEQINTSRC; | ||
1816 | call calc_residual; | ||
1817 | call save_pointers; | ||
1818 | mvi CLRSEQINTSRC, CLRSAVEPTRS; | ||
1819 | call disable_ccsgen; | ||
1820 | or SEQIMODE, ENSAVEPTRS; | ||
1821 | test DFCNTRL, DIRECTION jnz pkt_saveptrs_check_status; | ||
1822 | test DFSTATUS, FIFOEMP jnz pkt_saveptrs_check_status; | ||
1823 | /* | ||
1824 | * Keep a handler around for this FIFO until it drains | ||
1825 | * to the host to guarantee that we don't complete the | ||
1826 | * command to the host before the data arrives. | ||
1827 | */ | ||
1828 | pkt_saveptrs_wait_fifoemp: | ||
1829 | call setjmp; | ||
1830 | test DFSTATUS, FIFOEMP jz return; | ||
1831 | pkt_saveptrs_check_status: | ||
1832 | or LONGJMP_ADDR[1], INVALID_ADDR; | ||
1833 | test REG0, SAVEPTRS jz unexpected_nonpkt_phase; | ||
1834 | dec SCB_FIFO_USE_COUNT; | ||
1835 | test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle; | ||
1836 | mvi DFFSXFRCTL, CLRCHN ret; | ||
1837 | END_CRITICAL; | ||
1838 | |||
1839 | /* | ||
1840 | * LAST_SEG_DONE status has been seen in the current FIFO. | ||
1841 | * This indicates that all of the allowed data for this | ||
1842 | * command has transferred across the SCSI and host buses. | ||
1843 | * Check for overrun and see if we can complete this command. | ||
1844 | */ | ||
1845 | pkt_last_seg_done: | ||
1846 | BEGIN_CRITICAL; | ||
1847 | /* | ||
1848 | * Mark transfer as completed. | ||
1849 | */ | ||
1850 | or SCB_SGPTR, SG_LIST_NULL; | ||
1851 | |||
1852 | /* | ||
1853 | * Wait for the current context to finish to verify that | ||
1854 | * no overrun condition has occurred. | ||
1855 | */ | ||
1856 | test SEQINTSRC, CTXTDONE jnz pkt_ctxt_done; | ||
1857 | call setjmp; | ||
1858 | pkt_wait_ctxt_done_loop: | ||
1859 | test SEQINTSRC, CTXTDONE jnz pkt_ctxt_done; | ||
1860 | /* | ||
1861 | * A sufficiently large overrun or a NONPACKREQ may | ||
1862 | * prevent CTXTDONE from ever asserting, so we must | ||
1863 | * poll for these statuses too. | ||
1864 | */ | ||
1865 | check_overrun; | ||
1866 | test SSTAT2, NONPACKREQ jz return; | ||
1867 | test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; | ||
1868 | /* FALLTHROUGH */ | ||
1869 | |||
1870 | pkt_ctxt_done: | ||
1871 | check_overrun; | ||
1872 | or LONGJMP_ADDR[1], INVALID_ADDR; | ||
1873 | /* | ||
1874 | * If status has been received, it is safe to skip | ||
1875 | * the check to see if another FIFO is active because | ||
1876 | * LAST_SEG_DONE has been observed. However, we check | ||
1877 | * the FIFO anyway since it costs us only one extra | ||
1878 | * instruction to leverage common code to perform the | ||
1879 | * SCB completion. | ||
1880 | */ | ||
1881 | dec SCB_FIFO_USE_COUNT; | ||
1882 | test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle; | ||
1883 | mvi DFFSXFRCTL, CLRCHN ret; | ||
1884 | END_CRITICAL; | ||
1885 | |||
1886 | /* | ||
1887 | * Must wait until CDB xfer is over before issuing the | ||
1888 | * clear channel. | ||
1889 | */ | ||
1890 | pkt_handle_cdb: | ||
1891 | call setjmp; | ||
1892 | test SG_CACHE_SHADOW, LAST_SEG_DONE jz return; | ||
1893 | or LONGJMP_ADDR[1], INVALID_ADDR; | ||
1894 | mvi DFFSXFRCTL, CLRCHN ret; | ||
1895 | |||
1896 | /* | ||
1897 | * Watch over the status transfer. Our host sense buffer is | ||
1898 | * large enough to take the maximum allowed status packet. | ||
1899 | * None-the-less, we must still catch and report overruns to | ||
1900 | * the host. Additionally, properly catch unexpected non-packet | ||
1901 | * phases that are typically caused by CRC errors in status packet | ||
1902 | * transmission. | ||
1903 | */ | ||
1904 | pkt_handle_status: | ||
1905 | call setjmp; | ||
1906 | test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun; | ||
1907 | test SEQINTSRC, CTXTDONE jz pkt_status_check_nonpackreq; | ||
1908 | test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun; | ||
1909 | pkt_status_IU_done: | ||
1910 | if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { | ||
1911 | or DFCNTRL, FIFOFLUSH; | ||
1912 | } | ||
1913 | test DFSTATUS, FIFOEMP jz return; | ||
1914 | BEGIN_CRITICAL; | ||
1915 | or LONGJMP_ADDR[1], INVALID_ADDR; | ||
1916 | mvi SCB_SCSI_STATUS, STATUS_PKT_SENSE; | ||
1917 | or SCB_CONTROL, STATUS_RCVD; | ||
1918 | jmp pkt_complete_scb_if_fifos_idle; | ||
1919 | END_CRITICAL; | ||
1920 | pkt_status_check_overrun: | ||
1921 | /* | ||
1922 | * Status PKT overruns are uncerimoniously recovered with a | ||
1923 | * bus reset. If we've overrun, let the host know so that | ||
1924 | * recovery can be performed. | ||
1925 | * | ||
1926 | * LAST_SEG_DONE has been observed. If either CTXTDONE or | ||
1927 | * a NONPACKREQ phase change have occurred and the FIFO is | ||
1928 | * empty, there is no overrun. | ||
1929 | */ | ||
1930 | test DFSTATUS, FIFOEMP jz pkt_status_report_overrun; | ||
1931 | test SEQINTSRC, CTXTDONE jz . + 2; | ||
1932 | test DFSTATUS, FIFOEMP jnz pkt_status_IU_done; | ||
1933 | test SCSIPHASE, ~DATA_PHASE_MASK jz return; | ||
1934 | test DFSTATUS, FIFOEMP jnz pkt_status_check_nonpackreq; | ||
1935 | pkt_status_report_overrun: | ||
1936 | SET_SEQINTCODE(STATUS_OVERRUN) | ||
1937 | /* SEQUENCER RESTARTED */ | ||
1938 | pkt_status_check_nonpackreq: | ||
1939 | /* | ||
1940 | * CTXTDONE may be held off if a NONPACKREQ is associated with | ||
1941 | * the current context. If a NONPACKREQ is observed, decide | ||
1942 | * if it is for the current context. If it is for the current | ||
1943 | * context, we must defer NONPACKREQ processing until all data | ||
1944 | * has transferred to the host. | ||
1945 | */ | ||
1946 | test SCSIPHASE, ~DATA_PHASE_MASK jz return; | ||
1947 | test SCSISIGO, ATNO jnz . + 2; | ||
1948 | test SSTAT2, NONPACKREQ jz return; | ||
1949 | test SEQINTSRC, CTXTDONE jnz pkt_status_IU_done; | ||
1950 | test DFSTATUS, FIFOEMP jz return; | ||
1951 | /* | ||
1952 | * The unexpected nonpkt phase handler assumes that any | ||
1953 | * data channel use will have a FIFO reference count. It | ||
1954 | * turns out that the status handler doesn't need a refernce | ||
1955 | * count since the status received flag, and thus completion | ||
1956 | * processing, cannot be set until the handler is finished. | ||
1957 | * We increment the count here to make the nonpkt handler | ||
1958 | * happy. | ||
1959 | */ | ||
1960 | inc SCB_FIFO_USE_COUNT; | ||
1961 | /* FALLTHROUGH */ | ||
1962 | |||
1963 | /* | ||
1964 | * Nonpackreq is a polled status. It can come true in three situations: | ||
1965 | * we have received an L_Q, we have sent one or more L_Qs, or there is no | ||
1966 | * L_Q context associated with this REQ (REQ occurs immediately after a | ||
1967 | * (re)selection). Routines that know that the context responsible for this | ||
1968 | * nonpackreq call directly into unexpected_nonpkt_phase. In the case of the | ||
1969 | * top level idle loop, we exhaust all active contexts prior to determining that | ||
1970 | * we simply do not have the full I_T_L_Q for this phase. | ||
1971 | */ | ||
1972 | unexpected_nonpkt_phase_find_ctxt: | ||
1973 | /* | ||
1974 | * This nonpackreq is most likely associated with one of the tags | ||
1975 | * in a FIFO or an outgoing LQ. Only treat it as an I_T only | ||
1976 | * nonpackreq if we've cleared out the FIFOs and handled any | ||
1977 | * pending SELDO. | ||
1978 | */ | ||
1979 | SET_SRC_MODE M_SCSI; | ||
1980 | SET_DST_MODE M_SCSI; | ||
1981 | and A, FIFO1FREE|FIFO0FREE, DFFSTAT; | ||
1982 | cmp A, FIFO1FREE|FIFO0FREE jne return; | ||
1983 | test SSTAT0, SELDO jnz return; | ||
1984 | mvi SCBPTR[1], SCB_LIST_NULL; | ||
1985 | unexpected_nonpkt_phase: | ||
1986 | test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) | ||
1987 | jnz unexpected_nonpkt_mode_cleared; | ||
1988 | SET_SRC_MODE M_DFF0; | ||
1989 | SET_DST_MODE M_DFF0; | ||
1990 | or LONGJMP_ADDR[1], INVALID_ADDR; | ||
1991 | dec SCB_FIFO_USE_COUNT; | ||
1992 | mvi DFFSXFRCTL, CLRCHN; | ||
1993 | unexpected_nonpkt_mode_cleared: | ||
1994 | mvi CLRSINT2, CLRNONPACKREQ; | ||
1995 | test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase; | ||
1996 | SET_SEQINTCODE(ENTERING_NONPACK) | ||
1997 | jmp ITloop; | ||
1998 | |||
1999 | illegal_phase: | ||
2000 | SET_SEQINTCODE(ILLEGAL_PHASE) | ||
2001 | jmp ITloop; | ||
2002 | |||
2003 | /* | ||
2004 | * We have entered an overrun situation. If we have working | ||
2005 | * BITBUCKET, flip that on and let the hardware eat any overrun | ||
2006 | * data. Otherwise use an overrun buffer in the host to simulate | ||
2007 | * BITBUCKET. | ||
2008 | */ | ||
2009 | pkt_handle_overrun_inc_use_count: | ||
2010 | inc SCB_FIFO_USE_COUNT; | ||
2011 | pkt_handle_overrun: | ||
2012 | SET_SEQINTCODE(CFG4OVERRUN) | ||
2013 | call freeze_queue; | ||
2014 | if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) { | ||
2015 | or DFFSXFRCTL, DFFBITBUCKET; | ||
2016 | SET_SRC_MODE M_DFF1; | ||
2017 | SET_DST_MODE M_DFF1; | ||
2018 | } else { | ||
2019 | call load_overrun_buf; | ||
2020 | mvi DFCNTRL, (HDMAEN|SCSIEN|PRELOADEN); | ||
2021 | } | ||
2022 | call setjmp; | ||
2023 | if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { | ||
2024 | test DFSTATUS, PRELOAD_AVAIL jz overrun_load_done; | ||
2025 | call load_overrun_buf; | ||
2026 | or DFCNTRL, PRELOADEN; | ||
2027 | overrun_load_done: | ||
2028 | test SEQINTSRC, CTXTDONE jnz pkt_overrun_end; | ||
2029 | } else { | ||
2030 | test DFFSXFRCTL, DFFBITBUCKET jz pkt_overrun_end; | ||
2031 | } | ||
2032 | test SSTAT2, NONPACKREQ jz return; | ||
2033 | pkt_overrun_end: | ||
2034 | or SCB_RESIDUAL_SGPTR, SG_OVERRUN_RESID; | ||
2035 | test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; | ||
2036 | dec SCB_FIFO_USE_COUNT; | ||
2037 | or LONGJMP_ADDR[1], INVALID_ADDR; | ||
2038 | test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle; | ||
2039 | mvi DFFSXFRCTL, CLRCHN ret; | ||
2040 | |||
2041 | if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { | ||
2042 | load_overrun_buf: | ||
2043 | /* | ||
2044 | * Load a dummy segment if preload space is available. | ||
2045 | */ | ||
2046 | mov HADDR[0], SHARED_DATA_ADDR; | ||
2047 | add HADDR[1], PKT_OVERRUN_BUFOFFSET, SHARED_DATA_ADDR[1]; | ||
2048 | mov ACCUM_SAVE, A; | ||
2049 | clr A; | ||
2050 | adc HADDR[2], A, SHARED_DATA_ADDR[2]; | ||
2051 | adc HADDR[3], A, SHARED_DATA_ADDR[3]; | ||
2052 | mov A, ACCUM_SAVE; | ||
2053 | bmov HADDR[4], ALLZEROS, 4; | ||
2054 | /* PKT_OVERRUN_BUFSIZE is a multiple of 256 */ | ||
2055 | clr HCNT[0]; | ||
2056 | mvi HCNT[1], ((PKT_OVERRUN_BUFSIZE >> 8) & 0xFF); | ||
2057 | clr HCNT[2] ret; | ||
2058 | } | ||