aic7xxx.seq revision 1.11.6.2 1 /* $NetBSD: aic7xxx.seq,v 1.11.6.2 2001/08/24 00:09:54 nathanw Exp $ */
2
3 /*
4 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
5 *
6 * Copyright (c) 1994-2000 Justin Gibbs.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * Alternatively, this software may be distributed under the terms of the
19 * the GNU Public License ("GPL").
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.94 2000/02/09 21:25:00 gibbs Exp $
34 */
35
36 /*
37 * #ifdef __NetBSD__
38 */
39 #include <dev/microcode/aic7xxx/aic7xxx.reg>
40 #include <dev/scsipi/scsi_message.h>
41 /*
42 * Assembler can't handle ifdef.
43 *
44 * #else
45 * #include <dev/aic7xxx/aic7xxx.reg>
46 * #include <cam/scsi/scsi_message.h>
47 * #endif
48 */
49
50 /*
51 * A few words on the waiting SCB list:
52 * After starting the selection hardware, we check for reconnecting targets
53 * as well as for our selection to complete just in case the reselection wins
54 * bus arbitration. The problem with this is that we must keep track of the
55 * SCB that we've already pulled from the QINFIFO and started the selection
56 * on just in case the reselection wins so that we can retry the selection at
57 * a later time. This problem cannot be resolved by holding a single entry
58 * in scratch ram since a reconnecting target can request sense and this will
59 * create yet another SCB waiting for selection. The solution used here is to
60 * use byte 27 of the SCB as a psuedo-next pointer and to thread a list
61 * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes,
62 * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to
63 * this list everytime a request sense occurs or after completing a non-tagged
64 * command for which a second SCB has been queued. The sequencer will
65 * automatically consume the entries.
66 */
67
68 reset:
69 clr SCSISIGO; /* De-assert BSY */
70 mvi MSG_OUT, MSG_NOOP; /* No message to send */
71 and SXFRCTL1, ~BITBUCKET;
72 /* Always allow reselection */
73 and SCSISEQ, ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ_TEMPLATE;
74 if ((ahc->features & AHC_CMD_CHAN) != 0) {
75 /* Ensure that no DMA operations are in progress */
76 clr CCSGCTL;
77 clr CCSCBCTL;
78 }
79
80 poll_for_work:
81 call clear_target_state;
82 and SXFRCTL0, ~SPIOEN;
83 if ((ahc->features & AHC_QUEUE_REGS) == 0) {
84 mov A, QINPOS;
85 }
86 poll_for_work_loop:
87 if ((ahc->features & AHC_QUEUE_REGS) == 0) {
88 and SEQCTL, ~PAUSEDIS;
89 }
90 test SSTAT0, SELDO|SELDI jnz selection;
91 test SCSISEQ, ENSELO jnz poll_for_work;
92 if ((ahc->features & AHC_TWIN) != 0) {
93 /*
94 * Twin channel devices cannot handle things like SELTO
95 * interrupts on the "background" channel. So, if we
96 * are selecting, keep polling the current channel util
97 * either a selection or reselection occurs.
98 */
99 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
100 test SSTAT0, SELDO|SELDI jnz selection;
101 test SCSISEQ, ENSELO jnz poll_for_work;
102 xor SBLKCTL,SELBUSB; /* Toggle back */
103 }
104 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting;
105 test_queue:
106 /* Has the driver posted any work for us? */
107 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
108 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
109 mov NONE, SNSCB_QOFF;
110 inc QINPOS;
111 } else {
112 or SEQCTL, PAUSEDIS;
113 cmp KERNEL_QINPOS, A je poll_for_work_loop;
114 inc QINPOS;
115 and SEQCTL, ~PAUSEDIS;
116 }
117
118 /*
119 * We have at least one queued SCB now and we don't have any
120 * SCBs in the list of SCBs awaiting selection. If we have
121 * any SCBs available for use, pull the tag from the QINFIFO
122 * and get to work on it.
123 */
124 if ((ahc->flags & AHC_PAGESCBS) != 0) {
125 mov ALLZEROS call get_free_or_disc_scb;
126 }
127
128 dequeue_scb:
129 add A, -1, QINPOS;
130 mvi QINFIFO_OFFSET call fetch_byte;
131
132 if ((ahc->flags & AHC_PAGESCBS) == 0) {
133 /* In the non-paging case, the SCBID == hardware SCB index */
134 mov SCBPTR, RETURN_2;
135 }
136 dma_queued_scb:
137 /*
138 * DMA the SCB from host ram into the current SCB location.
139 */
140 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
141 mov RETURN_2 call dma_scb;
142
143 /*
144 * Preset the residual fields in case we never go through a data phase.
145 * This isn't done by the host so we can avoid a DMA to clear these
146 * fields for the normal case of I/O that completes without underrun
147 * or overrun conditions.
148 */
149 if ((ahc->features & AHC_CMD_CHAN) != 0) {
150 bmov SCB_RESID_DCNT, SCB_DATACNT, 3;
151 } else {
152 mov SCB_RESID_DCNT[0],SCB_DATACNT[0];
153 mov SCB_RESID_DCNT[1],SCB_DATACNT[1];
154 mov SCB_RESID_DCNT[2],SCB_DATACNT[2];
155 }
156 mov SCB_RESID_SGCNT, SCB_SGCOUNT;
157
158 start_scb:
159 /*
160 * Place us on the waiting list in case our selection
161 * doesn't win during bus arbitration.
162 */
163 mov SCB_NEXT,WAITING_SCBH;
164 mov WAITING_SCBH, SCBPTR;
165 start_waiting:
166 /*
167 * Pull the first entry off of the waiting SCB list.
168 */
169 mov SCBPTR, WAITING_SCBH;
170 call start_selection;
171 jmp poll_for_work;
172
173 start_selection:
174 if ((ahc->features & AHC_TWIN) != 0) {
175 and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
176 and A,SELBUSB,SCB_TCL; /* Get new channel bit */
177 or SINDEX,A;
178 mov SBLKCTL,SINDEX; /* select channel */
179 }
180 initialize_scsiid:
181 mov SINDEX, SCSISEQ_TEMPLATE;
182 if ((ahc->flags & AHC_TARGETMODE) != 0) {
183 test SCB_CONTROL, TARGET_SCB jz . + 4;
184 if ((ahc->features & AHC_ULTRA2) != 0) {
185 mov SCSIID_ULTRA2, SCB_CMDPTR[2];
186 } else {
187 mov SCSIID, SCB_CMDPTR[2];
188 }
189 or SINDEX, TEMODE;
190 jmp initialize_scsiid_fini;
191 }
192 if ((ahc->features & AHC_ULTRA2) != 0) {
193 and A, TID, SCB_TCL; /* Get target ID */
194 and SCSIID_ULTRA2, OID; /* Clear old target */
195 or SCSIID_ULTRA2, A;
196 } else {
197 and A, TID, SCB_TCL; /* Get target ID */
198 and SCSIID, OID; /* Clear old target */
199 or SCSIID, A;
200 }
201 initialize_scsiid_fini:
202 mov SCSISEQ, SINDEX ret;
203
204 /*
205 * Initialize transfer settings and clear the SCSI channel.
206 * SINDEX should contain any additional bit's the client wants
207 * set in SXFRCTL0. We also assume that the current SCB is
208 * a valid SCB for the target we wish to talk to.
209 */
210 initialize_channel:
211 or SXFRCTL0, CLRSTCNT|CLRCHN, SINDEX;
212 set_transfer_settings:
213 if ((ahc->features & AHC_ULTRA) != 0) {
214 test SCB_CONTROL, ULTRAENB jz . + 2;
215 or SXFRCTL0, FAST20;
216 }
217 /*
218 * Initialize SCSIRATE with the appropriate value for this target.
219 */
220 if ((ahc->features & AHC_ULTRA2) != 0) {
221 bmov SCSIRATE, SCB_SCSIRATE, 2 ret;
222 } else {
223 mov SCSIRATE, SCB_SCSIRATE ret;
224 }
225
226 selection:
227 test SSTAT0,SELDO jnz select_out;
228 mvi CLRSINT0, CLRSELDI;
229 select_in:
230 if ((ahc->flags & AHC_TARGETMODE) != 0) {
231 if ((ahc->flags & AHC_INITIATORMODE) != 0) {
232 test SSTAT0, TARGET jz initiator_reselect;
233 }
234
235 /*
236 * We've just been selected. Assert BSY and
237 * setup the phase for receiving messages
238 * from the target.
239 */
240 mvi SCSISIGO, P_MESGOUT|BSYO;
241 mvi CLRSINT1, CLRBUSFREE;
242
243 /*
244 * Setup the DMA for sending the identify and
245 * command information.
246 */
247 or SEQ_FLAGS, CMDPHASE_PENDING;
248
249 mov A, TQINPOS;
250 if ((ahc->features & AHC_CMD_CHAN) != 0) {
251 mvi DINDEX, CCHADDR;
252 mvi TMODE_CMDADDR call set_32byte_addr;
253 mvi CCSCBCTL, CCSCBRESET;
254 } else {
255 mvi DINDEX, HADDR;
256 mvi TMODE_CMDADDR call set_32byte_addr;
257 mvi DFCNTRL, FIFORESET;
258 }
259
260 /* Initiator that selected us */
261 and SAVED_TCL, SELID_MASK, SELID;
262 if ((ahc->features & AHC_CMD_CHAN) != 0) {
263 mov CCSCBRAM, SAVED_TCL;
264 } else {
265 mov DFDAT, SAVED_TCL;
266 }
267
268 /* The Target ID we were selected at */
269 if ((ahc->features & AHC_CMD_CHAN) != 0) {
270 if ((ahc->features & AHC_MULTI_TID) != 0) {
271 and CCSCBRAM, OID, TARGIDIN;
272 } else if ((ahc->features & AHC_ULTRA2) != 0) {
273 and CCSCBRAM, OID, SCSIID_ULTRA2;
274 } else {
275 and CCSCBRAM, OID, SCSIID;
276 }
277 } else {
278 if ((ahc->features & AHC_MULTI_TID) != 0) {
279 and DFDAT, OID, TARGIDIN;
280 } else if ((ahc->features & AHC_ULTRA2) != 0) {
281 and DFDAT, OID, SCSIID_ULTRA2;
282 } else {
283 and DFDAT, OID, SCSIID;
284 }
285 }
286
287 /* No tag yet */
288 mvi INITIATOR_TAG, SCB_LIST_NULL;
289
290 /*
291 * If ATN isn't asserted, the target isn't interested
292 * in talking to us. Go directly to bus free.
293 */
294 test SCSISIGI, ATNI jz target_busfree;
295
296 /*
297 * Watch ATN closely now as we pull in messages from the
298 * initiator. We follow the guidlines from section 6.5
299 * of the SCSI-2 spec for what messages are allowed when.
300 */
301 call target_inb;
302
303 /*
304 * Our first message must be one of IDENTIFY, ABORT, or
305 * BUS_DEVICE_RESET.
306 */
307 /* XXX May need to be more lax here for older initiators... */
308 test DINDEX, MSG_IDENTIFYFLAG jz host_target_message_loop;
309 /* Store for host */
310 if ((ahc->features & AHC_CMD_CHAN) != 0) {
311 mov CCSCBRAM, DINDEX;
312 } else {
313 mov DFDAT, DINDEX;
314 }
315
316 /* Remember for disconnection decision */
317 test DINDEX, MSG_IDENTIFY_DISCFLAG jnz . + 2;
318 /* XXX Honor per target settings too */
319 or SEQ_FLAGS, NO_DISCONNECT;
320
321 test SCSISIGI, ATNI jz ident_messages_done;
322 call target_inb;
323 /*
324 * If this is a tagged request, the tagged message must
325 * immediately follow the identify. We test for a valid
326 * tag message by seeing if it is >= MSG_SIMPLE_Q_TAG and
327 * < MSG_IGN_WIDE_RESIDUE.
328 */
329 add A, -MSG_SIMPLE_Q_TAG, DINDEX;
330 jnc ident_messages_done;
331 add A, -MSG_IGN_WIDE_RESIDUE, DINDEX;
332 jc ident_messages_done;
333 /* Store for host */
334 if ((ahc->features & AHC_CMD_CHAN) != 0) {
335 mov CCSCBRAM, DINDEX;
336 } else {
337 mov DFDAT, DINDEX;
338 }
339
340 /*
341 * If the initiator doesn't feel like providing a tag number,
342 * we've got a failed selection and must transition to bus
343 * free.
344 */
345 test SCSISIGI, ATNI jz target_busfree;
346
347 /*
348 * Store the tag for the host.
349 */
350 call target_inb;
351 if ((ahc->features & AHC_CMD_CHAN) != 0) {
352 mov CCSCBRAM, DINDEX;
353 } else {
354 mov DFDAT, DINDEX;
355 }
356 mov INITIATOR_TAG, DINDEX;
357 jmp ident_messages_done;
358
359 /*
360 * Pushed message loop to allow the kernel to
361 * run it's own target mode message state engine.
362 */
363 host_target_message_loop:
364 mvi INTSTAT, HOST_MSG_LOOP;
365 nop;
366 cmp RETURN_1, EXIT_MSG_LOOP je target_ITloop;
367 test SSTAT0, SPIORDY jz .;
368 jmp host_target_message_loop;
369
370 ident_messages_done:
371 /* If ring buffer is full, return busy or queue full */
372 mov A, KERNEL_TQINPOS;
373 cmp TQINPOS, A jne tqinfifo_has_space;
374 mvi P_STATUS|BSYO call change_phase;
375 cmp INITIATOR_TAG, SCB_LIST_NULL je . + 3;
376 mvi STATUS_QUEUE_FULL call target_outb;
377 jmp target_busfree_wait;
378 mvi STATUS_BUSY call target_outb;
379 jmp target_busfree_wait;
380 tqinfifo_has_space:
381 /* Terminate the ident list */
382 if ((ahc->features & AHC_CMD_CHAN) != 0) {
383 mvi CCSCBRAM, SCB_LIST_NULL;
384 } else {
385 mvi DFDAT, SCB_LIST_NULL;
386 }
387 or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN;
388 test SCSISIGI, ATNI jnz target_mesgout_pending_msg;
389 jmp target_ITloop;
390
391 /*
392 * We carefully toggle SPIOEN to allow us to return the
393 * message byte we receive so it can be checked prior to
394 * driving REQ on the bus for the next byte.
395 */
396 target_inb:
397 /*
398 * Drive REQ on the bus by enabling SCSI PIO.
399 */
400 or SXFRCTL0, SPIOEN;
401 /* Wait for the byte */
402 test SSTAT0, SPIORDY jz .;
403 /* Prevent our read from triggering another REQ */
404 and SXFRCTL0, ~SPIOEN;
405 /* Save latched contents */
406 mov DINDEX, SCSIDATL ret;
407 }
408
409 if ((ahc->flags & AHC_INITIATORMODE) != 0) {
410 /*
411 * Reselection has been initiated by a target. Make a note that we've been
412 * reselected, but haven't seen an IDENTIFY message from the target yet.
413 */
414 initiator_reselect:
415 /* XXX test for and handle ONE BIT condition */
416 and SAVED_TCL, SELID_MASK, SELID;
417 if ((ahc->features & AHC_TWIN) != 0) {
418 test SBLKCTL, SELBUSB jz . + 2;
419 or SAVED_TCL, SELBUSB;
420 }
421 or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN;
422 mvi CLRSINT1,CLRBUSFREE;
423 or SIMODE1, ENBUSFREE; /*
424 * We aren't expecting a
425 * bus free, so interrupt
426 * the kernel driver if it
427 * happens.
428 */
429 jmp ITloop;
430 }
431
432 /*
433 * After the selection, remove this SCB from the "waiting SCB"
434 * list. This is achieved by simply moving our "next" pointer into
435 * WAITING_SCBH. Our next pointer will be set to null the next time this
436 * SCB is used, so don't bother with it now.
437 */
438 select_out:
439 /* Turn off the selection hardware */
440 and SCSISEQ, ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ_TEMPLATE;
441 mvi CLRSINT0, CLRSELDO;
442 mov SCBPTR, WAITING_SCBH;
443 mov WAITING_SCBH,SCB_NEXT;
444 mov SAVED_TCL, SCB_TCL;
445 if ((ahc->flags & AHC_TARGETMODE) != 0) {
446 test SSTAT0, TARGET jz initiator_select;
447
448 /*
449 * We've just re-selected an initiator.
450 * Assert BSY and setup the phase for
451 * sending our identify messages.
452 */
453 mvi P_MESGIN|BSYO call change_phase;
454 mvi CLRSINT1,CLRBUSFREE;
455
456 /*
457 * Start out with a simple identify message.
458 */
459 and A, LID, SCB_TCL;
460 or A, MSG_IDENTIFYFLAG call target_outb;
461
462 /*
463 * If we are the result of a tagged command, send
464 * a simple Q tag and the tag id.
465 */
466 test SCB_CONTROL, TAG_ENB jz . + 3;
467 mvi MSG_SIMPLE_Q_TAG call target_outb;
468 mov SCB_INITIATOR_TAG call target_outb;
469 mov INITIATOR_TAG, SCB_INITIATOR_TAG;
470 target_synccmd:
471 /*
472 * Now determine what phases the host wants us
473 * to go through.
474 */
475 mov SEQ_FLAGS, SCB_TARGET_PHASES;
476
477
478 target_ITloop:
479 /*
480 * Start honoring ATN signals now that
481 * we properly identified ourselves.
482 */
483 test SCSISIGI, ATNI jnz target_mesgout;
484 test SEQ_FLAGS, CMDPHASE_PENDING jnz target_cmdphase;
485 test SEQ_FLAGS, DPHASE_PENDING jnz target_dphase;
486 test SEQ_FLAGS, SPHASE_PENDING jnz target_sphase;
487
488 /*
489 * No more work to do. Either disconnect or not depending
490 * on the state of NO_DISCONNECT.
491 */
492 test SEQ_FLAGS, NO_DISCONNECT jz target_disconnect;
493 if ((ahc->flags & AHC_PAGESCBS) != 0) {
494 mov ALLZEROS call get_free_or_disc_scb;
495 }
496 mov RETURN_1, ALLZEROS;
497 call complete_target_cmd;
498 cmp RETURN_1, CONT_MSG_LOOP jne .;
499 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
500 mov SCB_TAG call dma_scb;
501 jmp target_synccmd;
502
503 target_mesgout:
504 mvi SCSISIGO, P_MESGOUT|BSYO;
505 call target_inb;
506 /* Local Processing goes here... */
507 target_mesgout_pending_msg:
508 jmp host_target_message_loop;
509
510 target_disconnect:
511 mvi P_MESGIN|BSYO call change_phase;
512 test SEQ_FLAGS, DPHASE jz . + 2;
513 mvi MSG_SAVEDATAPOINTER call target_outb;
514 mvi MSG_DISCONNECT call target_outb;
515
516 target_busfree_wait:
517 /* Wait for preceding I/O session to complete. */
518 test SCSISIGI, ACKI jnz .;
519 target_busfree:
520 clr SCSISIGO;
521 mvi LASTPHASE, P_BUSFREE;
522 call complete_target_cmd;
523 jmp poll_for_work;
524
525 target_cmdphase:
526 mvi P_COMMAND|BSYO call change_phase;
527 call target_inb;
528 mov A, DINDEX;
529 /* Store for host */
530 if ((ahc->features & AHC_CMD_CHAN) != 0) {
531 mov CCSCBRAM, A;
532 } else {
533 mov DFDAT, A;
534 }
535
536 /*
537 * Determine the number of bytes to read
538 * based on the command group code via table lookup.
539 * We reuse the first 8 bytes of the TARG_SCSIRATE
540 * BIOS array for this table. Count is one less than
541 * the total for the command since we've already fetched
542 * the first byte.
543 */
544 shr A, CMD_GROUP_CODE_SHIFT;
545 add SINDEX, TARG_SCSIRATE, A;
546 mov A, SINDIR;
547
548 test A, 0xFF jz command_phase_done;
549 command_loop:
550 or SXFRCTL0, SPIOEN;
551 test SSTAT0, SPIORDY jz .;
552 cmp A, 1 jne . + 2;
553 and SXFRCTL0, ~SPIOEN; /* Last Byte */
554 if ((ahc->features & AHC_CMD_CHAN) != 0) {
555 mov CCSCBRAM, SCSIDATL;
556 } else {
557 mov DFDAT, SCSIDATL;
558 }
559 dec A;
560 test A, 0xFF jnz command_loop;
561
562 command_phase_done:
563 and SEQ_FLAGS, ~CMDPHASE_PENDING;
564 jmp target_ITloop;
565
566 target_dphase:
567 /*
568 * Data direction flags are from the
569 * perspective of the initiator.
570 */
571 test SCB_TARGET_PHASES[1], TARGET_DATA_IN jz . + 4;
572 mvi LASTPHASE, P_DATAOUT;
573 mvi P_DATAIN|BSYO call change_phase;
574 jmp . + 3;
575 mvi LASTPHASE, P_DATAIN;
576 mvi P_DATAOUT|BSYO call change_phase;
577 mov ALLZEROS call initialize_channel;
578 jmp p_data;
579
580 target_sphase:
581 mvi P_STATUS|BSYO call change_phase;
582 mvi LASTPHASE, P_STATUS;
583 mov SCB_TARGET_STATUS call target_outb;
584 /* XXX Watch for ATN or parity errors??? */
585 mvi SCSISIGO, P_MESGIN|BSYO;
586 /* MSG_CMDCMPLT is 0, but we can't do an immediate of 0 */
587 mov ALLZEROS call target_outb;
588 jmp target_busfree_wait;
589
590 complete_target_cmd:
591 test SEQ_FLAGS, TARG_CMD_PENDING jnz . + 2;
592 mov SCB_TAG jmp complete_post;
593 if ((ahc->features & AHC_CMD_CHAN) != 0) {
594 /* Set the valid byte */
595 mvi CCSCBADDR, 24;
596 mov CCSCBRAM, ALLONES;
597 mvi CCHCNT, 28;
598 or CCSCBCTL, CCSCBEN|CCSCBRESET;
599 test CCSCBCTL, CCSCBDONE jz .;
600 clr CCSCBCTL;
601 } else {
602 /* Set the valid byte */
603 or DFCNTRL, FIFORESET;
604 mvi DFWADDR, 3; /* Third 64bit word or byte 24 */
605 mov DFDAT, ALLONES;
606 mvi HCNT[0], 28;
607 clr HCNT[1];
608 clr HCNT[2];
609 or DFCNTRL, HDMAEN|FIFOFLUSH;
610 call dma_finish;
611 }
612 inc TQINPOS;
613 mvi INTSTAT,CMDCMPLT ret;
614 }
615
616 if ((ahc->flags & AHC_INITIATORMODE) != 0) {
617 initiator_select:
618 mvi SPIOEN call initialize_channel;
619
620 /*
621 * We aren't expecting a bus free, so interrupt
622 * the kernel driver if it happens.
623 */
624 mvi CLRSINT1,CLRBUSFREE;
625 or SIMODE1, ENBUSFREE;
626
627 /*
628 * As soon as we get a successful selection, the target
629 * should go into the message out phase since we have ATN
630 * asserted.
631 */
632 mvi MSG_OUT, MSG_IDENTIFYFLAG;
633 or SEQ_FLAGS, IDENTIFY_SEEN;
634
635 /*
636 * Main loop for information transfer phases. Wait for the
637 * target to assert REQ before checking MSG, C/D and I/O for
638 * the bus phase.
639 */
640 ITloop:
641 call phase_lock;
642
643 mov A, LASTPHASE;
644
645 test A, ~P_DATAIN jz p_data;
646 cmp A,P_COMMAND je p_command;
647 cmp A,P_MESGOUT je p_mesgout;
648 cmp A,P_STATUS je p_status;
649 cmp A,P_MESGIN je p_mesgin;
650
651 mvi INTSTAT,BAD_PHASE;
652 jmp ITloop; /* Try reading the bus again. */
653
654 await_busfree:
655 and SIMODE1, ~ENBUSFREE;
656 mov NONE, SCSIDATL; /* Ack the last byte */
657 and SXFRCTL0, ~SPIOEN;
658 test SSTAT1,REQINIT|BUSFREE jz .;
659 test SSTAT1, BUSFREE jnz poll_for_work;
660 mvi INTSTAT, BAD_PHASE;
661 }
662
663 clear_target_state:
664 /*
665 * We assume that the kernel driver may reset us
666 * at any time, even in the middle of a DMA, so
667 * clear DFCNTRL too.
668 */
669 clr DFCNTRL;
670
671 /*
672 * We don't know the target we will connect to,
673 * so default to narrow transfers to avoid
674 * parity problems.
675 */
676 if ((ahc->features & AHC_ULTRA2) != 0) {
677 bmov SCSIRATE, ALLZEROS, 2;
678 } else {
679 clr SCSIRATE;
680 and SXFRCTL0, ~(FAST20);
681 }
682 mvi LASTPHASE, P_BUSFREE;
683 /* clear target specific flags */
684 clr SEQ_FLAGS ret;
685
686 /*
687 * If we re-enter the data phase after going through another phase, the
688 * STCNT may have been cleared, so restore it from the residual field.
689 */
690 data_phase_reinit:
691 if ((ahc->features & AHC_ULTRA2) != 0) {
692 /*
693 * The preload circuitry requires us to
694 * reload the address too, so pull it from
695 * the shaddow address.
696 */
697 bmov HADDR, SHADDR, 4;
698 bmov HCNT, SCB_RESID_DCNT, 3;
699 } else if ((ahc->features & AHC_CMD_CHAN) != 0) {
700 bmov STCNT, SCB_RESID_DCNT, 3;
701 } else {
702 mvi DINDEX, STCNT;
703 mvi SCB_RESID_DCNT call bcopy_3;
704 }
705 and DATA_COUNT_ODD, 0x1, SCB_RESID_DCNT[0];
706 jmp data_phase_loop;
707
708 p_data:
709 if ((ahc->features & AHC_ULTRA2) != 0) {
710 mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN;
711 } else {
712 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET;
713 }
714 test LASTPHASE, IOI jnz . + 2;
715 or DMAPARAMS, DIRECTION;
716 call assert; /*
717 * Ensure entering a data
718 * phase is okay - seen identify, etc.
719 */
720 if ((ahc->features & AHC_CMD_CHAN) != 0) {
721 mvi CCSGADDR, CCSGADDR_MAX;
722 }
723 test SEQ_FLAGS, DPHASE jnz data_phase_reinit;
724
725 /* We have seen a data phase */
726 or SEQ_FLAGS, DPHASE;
727
728 /*
729 * Initialize the DMA address and counter from the SCB.
730 * Also set SG_COUNT and SG_NEXT in memory since we cannot
731 * modify the values in the SCB itself until we see a
732 * save data pointers message.
733 */
734 if ((ahc->features & AHC_CMD_CHAN) != 0) {
735 bmov HADDR, SCB_DATAPTR, 7;
736 } else {
737 mvi DINDEX, HADDR;
738 mvi SCB_DATAPTR call bcopy_7;
739 }
740 and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0];
741
742 if ((ahc->features & AHC_ULTRA2) == 0) {
743 if ((ahc->features & AHC_CMD_CHAN) != 0) {
744 bmov STCNT, HCNT, 3;
745 } else {
746 call set_stcnt_from_hcnt;
747 }
748 }
749
750 if ((ahc->features & AHC_CMD_CHAN) != 0) {
751 bmov SG_COUNT, SCB_SGCOUNT, 5;
752 } else {
753 mvi DINDEX, SG_COUNT;
754 mvi SCB_SGCOUNT call bcopy_5;
755 }
756
757 data_phase_loop:
758 /* Guard against overruns */
759 test SG_COUNT, 0xff jnz data_phase_inbounds;
760 /*
761 * Turn on 'Bit Bucket' mode, set the transfer count to
762 * 16meg and let the target run until it changes phase.
763 * When the transfer completes, notify the host that we
764 * had an overrun.
765 */
766 or SXFRCTL1,BITBUCKET;
767 and DMAPARAMS, ~(HDMAEN|SDMAEN);
768 if ((ahc->features & AHC_ULTRA2) != 0) {
769 bmov HCNT, ALLONES, 3;
770 } else if ((ahc->features & AHC_CMD_CHAN) != 0) {
771 bmov STCNT, ALLONES, 3;
772 } else {
773 mvi STCNT[0], 0xFF;
774 mvi STCNT[1], 0xFF;
775 mvi STCNT[2], 0xFF;
776 }
777 data_phase_inbounds:
778 /* If we are the last SG block, tell the hardware. */
779 cmp SG_COUNT,0x01 jne data_phase_wideodd;
780 if ((ahc->features & AHC_ULTRA2) != 0) {
781 or SG_CACHEPTR, LAST_SEG;
782 } else {
783 if ((ahc->flags & AHC_TARGETMODE) != 0) {
784 test SSTAT0, TARGET jz . + 2;
785 test DMAPARAMS, DIRECTION jz data_phase_wideodd;
786 }
787 and DMAPARAMS, ~WIDEODD;
788 }
789 data_phase_wideodd:
790 if ((ahc->features & AHC_ULTRA2) != 0) {
791 mov SINDEX, ALLONES;
792 mov DFCNTRL, DMAPARAMS;
793 test SSTAT0, SDONE jnz .;/* Wait for preload to complete */
794 data_phase_dma_loop:
795 test SSTAT0, SDONE jnz data_phase_dma_done;
796 test SSTAT1,PHASEMIS jz data_phase_dma_loop; /* ie. underrun */
797 } else {
798 mov DMAPARAMS call dma;
799 }
800
801 data_phase_dma_done:
802 /* Go tell the host about any overruns */
803 test SXFRCTL1,BITBUCKET jnz data_phase_overrun;
804
805 /* See if we completed this segment */
806 test STCNT[0], 0xff jnz data_phase_finish;
807 test STCNT[1], 0xff jnz data_phase_finish;
808 test STCNT[2], 0xff jnz data_phase_finish;
809
810 /*
811 * Advance the scatter-gather pointers if needed
812 */
813 sg_advance:
814 dec SG_COUNT; /* one less segment to go */
815
816 test SG_COUNT, 0xff jz data_phase_finish; /* Are we done? */
817 /*
818 * Load a struct scatter and set up the data address and length.
819 * If the working value of the SG count is nonzero, then
820 * we need to load a new set of values.
821 *
822 * This, like all DMA's, assumes little-endian host data storage.
823 */
824 sg_load:
825 if ((ahc->features & AHC_CMD_CHAN) != 0) {
826 /*
827 * Do we have any prefetch left???
828 */
829 cmp CCSGADDR, CCSGADDR_MAX jne prefetched_segs_avail;
830
831 /*
832 * Fetch MIN(CCSGADDR_MAX, (SG_COUNT * 8)) bytes.
833 */
834 add A, -(CCSGRAM_MAXSEGS + 1), SG_COUNT;
835 mvi A, CCSGADDR_MAX;
836 jc . + 2;
837 shl A, 3, SG_COUNT;
838 mov CCHCNT, A;
839 bmov CCHADDR, SG_NEXT, 4;
840 mvi CCSGCTL, CCSGEN|CCSGRESET;
841 test CCSGCTL, CCSGDONE jz .;
842 and CCSGCTL, ~CCSGEN;
843 test CCSGCTL, CCSGEN jnz .;
844 mvi CCSGCTL, CCSGRESET;
845 prefetched_segs_avail:
846 bmov HADDR, CCSGRAM, 8;
847 } else {
848 mvi DINDEX, HADDR;
849 mvi SG_NEXT call bcopy_4;
850
851 mvi HCNT[0],SG_SIZEOF;
852 clr HCNT[1];
853 clr HCNT[2];
854
855 or DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
856
857 call dma_finish;
858
859 /*
860 * Copy data from FIFO into SCB data pointer and data count.
861 * This assumes that the SG segments are of the form:
862 * struct ahc_dma_seg {
863 * u_int32_t addr; four bytes, little-endian order
864 * u_int32_t len; four bytes, little endian order
865 * };
866 */
867 mvi HADDR call dfdat_in_7;
868 }
869
870 /* Track odd'ness */
871 test HCNT[0], 0x1 jz . + 2;
872 xor DATA_COUNT_ODD, 0x1;
873
874 if ((ahc->features & AHC_ULTRA2) == 0) {
875 /* Load STCNT as well. It is a mirror of HCNT */
876 if ((ahc->features & AHC_CMD_CHAN) != 0) {
877 bmov STCNT, HCNT, 3;
878 } else {
879 call set_stcnt_from_hcnt;
880 }
881 }
882
883 /* Advance the SG pointer */
884 clr A; /* add sizeof(struct scatter) */
885 add SG_NEXT[0],SG_SIZEOF;
886 adc SG_NEXT[1],A;
887
888 if ((ahc->flags & AHC_TARGETMODE) != 0) {
889 test SSTAT0, TARGET jnz data_phase_loop;
890 }
891 test SSTAT1, REQINIT jz .;
892 test SSTAT1,PHASEMIS jz data_phase_loop;
893
894 /* Ensure the last seg is visable at the shaddow layer */
895 if ((ahc->features & AHC_ULTRA2) != 0) {
896 mov DFCNTRL, DMAPARAMS;
897 test SSTAT0, SDONE jnz .;/* Wait for preload to complete */
898 }
899
900 data_phase_finish:
901 if ((ahc->features & AHC_ULTRA2) != 0) {
902 call ultra2_dmafinish;
903 }
904 /*
905 * After a DMA finishes, save the SG and STCNT residuals back into the SCB
906 * We use STCNT instead of HCNT, since it's a reflection of how many bytes
907 * were transferred on the SCSI (as opposed to the host) bus.
908 */
909 if ((ahc->features & AHC_CMD_CHAN) != 0) {
910 bmov SCB_RESID_DCNT, STCNT, 3;
911 } else {
912 mov SCB_RESID_DCNT[0],STCNT[0];
913 mov SCB_RESID_DCNT[1],STCNT[1];
914 mov SCB_RESID_DCNT[2],STCNT[2];
915 }
916 mov SCB_RESID_SGCNT, SG_COUNT;
917
918 if ((ahc->features & AHC_ULTRA2) != 0) {
919 or SXFRCTL0, CLRSTCNT|CLRCHN;
920 }
921
922 if ((ahc->flags & AHC_TARGETMODE) != 0) {
923 test SEQ_FLAGS, DPHASE_PENDING jz ITloop;
924 and SEQ_FLAGS, ~DPHASE_PENDING;
925 /*
926 * For data-in phases, wait for any pending acks from the
927 * initiator before changing phase.
928 */
929 test DFCNTRL, DIRECTION jz target_ITloop;
930 test SSTAT1, REQINIT jnz .;
931 jmp target_ITloop;
932 }
933 jmp ITloop;
934
935 data_phase_overrun:
936 if ((ahc->features & AHC_ULTRA2) != 0) {
937 call ultra2_dmafinish;
938 or SXFRCTL0, CLRSTCNT|CLRCHN;
939 }
940 /*
941 * Turn off BITBUCKET mode and notify the host
942 */
943 and SXFRCTL1, ~BITBUCKET;
944 mvi INTSTAT,DATA_OVERRUN;
945 jmp ITloop;
946
947 ultra2_dmafinish:
948 if ((ahc->features & AHC_ULTRA2) != 0) {
949 test DFCNTRL, DIRECTION jnz ultra2_dmafifoempty;
950 and DFCNTRL, ~SCSIEN;
951 test DFCNTRL, SCSIEN jnz .;
952 ultra2_dmafifoflush:
953 or DFCNTRL, FIFOFLUSH;
954 /*
955 * The FIFOEMP status bit on the Ultra2 class
956 * of controllers seems to be a bit flaky.
957 * It appears that if the FIFO is full and the
958 * transfer ends with some data in the REQ/ACK
959 * FIFO, FIFOEMP will fall temporarily
960 * as the data is transferred to the PCI bus.
961 * This glitch lasts for fewer than 5 clock cycles,
962 * so we work around the problem by ensuring the
963 * status bit stays false through a full glitch
964 * window.
965 */
966 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
967 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
968 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
969 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
970 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
971
972 ultra2_dmafifoempty:
973 /* Don't clobber an inprogress host data transfer */
974 test DFSTATUS, MREQPEND jnz ultra2_dmafifoempty;
975
976 ultra2_dmahalt:
977 and DFCNTRL, ~(SCSIEN|HDMAEN);
978 test DFCNTRL, HDMAEN jnz .;
979 ret;
980 }
981
982 if ((ahc->flags & AHC_INITIATORMODE) != 0) {
983 /*
984 * Command phase. Set up the DMA registers and let 'er rip.
985 */
986 p_command:
987 call assert;
988
989 if ((ahc->features & AHC_CMD_CHAN) != 0) {
990 mov HCNT[0], SCB_CMDLEN;
991 bmov HCNT[1], ALLZEROS, 2;
992 if ((ahc->features & AHC_ULTRA2) == 0) {
993 bmov STCNT, HCNT, 3;
994 }
995 add NONE, -17, SCB_CMDLEN;
996 jc dma_cmd_data;
997 /*
998 * The data fifo seems to require 4 byte alligned
999 * transfers from the sequencer. Force this to
1000 * be the case by clearing HADDR[0] even though
1001 * we aren't going to touch host memeory.
1002 */
1003 bmov HADDR[0], ALLZEROS, 1;
1004 if ((ahc->features & AHC_ULTRA2) != 0) {
1005 mvi DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION);
1006 } else {
1007 mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET);
1008 }
1009 bmov DFDAT, SCB_CMDSTORE, 16;
1010 jmp cmd_loop;
1011 dma_cmd_data:
1012 bmov HADDR, SCB_CMDPTR, 4;
1013 } else {
1014 mvi DINDEX, HADDR;
1015 mvi SCB_CMDPTR call bcopy_5;
1016 clr HCNT[1];
1017 clr HCNT[2];
1018 }
1019
1020 if ((ahc->features & AHC_ULTRA2) == 0) {
1021 if ((ahc->features & AHC_CMD_CHAN) == 0) {
1022 call set_stcnt_from_hcnt;
1023 }
1024 mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET);
1025 } else {
1026 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION);
1027 }
1028 cmd_loop:
1029 test SSTAT0, SDONE jnz . + 2;
1030 test SSTAT1, PHASEMIS jz cmd_loop;
1031 /*
1032 * Wait for our ACK to go-away on it's own
1033 * instead of being killed by SCSIEN getting cleared.
1034 */
1035 test SCSISIGI, ACKI jnz .;
1036 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);
1037 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .;
1038 jmp ITloop;
1039
1040 /*
1041 * Status phase. Wait for the data byte to appear, then read it
1042 * and store it into the SCB.
1043 */
1044 p_status:
1045 call assert;
1046
1047 mov SCB_TARGET_STATUS, SCSIDATL;
1048 jmp ITloop;
1049
1050 /*
1051 * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full
1052 * indentify message sequence and send it to the target. The host may
1053 * override this behavior by setting the MK_MESSAGE bit in the SCB
1054 * control byte. This will cause us to interrupt the host and allow
1055 * it to handle the message phase completely on its own. If the bit
1056 * associated with this target is set, we will also interrupt the host,
1057 * thereby allowing it to send a message on the next selection regardless
1058 * of the transaction being sent.
1059 *
1060 * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message.
1061 * This is done to allow the host to send messages outside of an identify
1062 * sequence while protecting the seqencer from testing the MK_MESSAGE bit
1063 * on an SCB that might not be for the current nexus. (For example, a
1064 * BDR message in response to a bad reselection would leave us pointed to
1065 * an SCB that doesn't have anything to do with the current target).
1066 *
1067 * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag,
1068 * bus device reset).
1069 *
1070 * When there are no messages to send, MSG_OUT should be set to MSG_NOOP,
1071 * in case the target decides to put us in this phase for some strange
1072 * reason.
1073 */
1074 p_mesgout_retry:
1075 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */
1076 p_mesgout:
1077 mov SINDEX, MSG_OUT;
1078 cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;
1079 test SCB_CONTROL,MK_MESSAGE jnz host_message_loop;
1080 mov FUNCTION1, SCB_TCL;
1081 mov A, FUNCTION1;
1082 if ((ahc->features & AHC_HS_MAILBOX) != 0) {
1083 /*
1084 * Work around a pausing bug in at least the aic7890.
1085 * If the host needs to update the TARGET_MSG_REQUEST
1086 * bit field, it will set the HS_MAILBOX to 1. In
1087 * response, we pause with a specific interrupt code
1088 * asking for the mask to be updated before we continue.
1089 * Ugh.
1090 */
1091 test HS_MAILBOX, 0xF0 jz . + 2;
1092 mvi INTSTAT, UPDATE_TMSG_REQ;
1093 nop;
1094 }
1095 mov SINDEX, TARGET_MSG_REQUEST[0];
1096 if ((ahc->features & AHC_TWIN) != 0) {
1097 /* Second Channel uses high byte bits */
1098 test SCB_TCL, SELBUSB jz . + 2;
1099 mov SINDEX, TARGET_MSG_REQUEST[1];
1100 } else if ((ahc->features & AHC_WIDE) != 0) {
1101 test SCB_TCL, 0x80 jz . + 2; /* target > 7 */
1102 mov SINDEX, TARGET_MSG_REQUEST[1];
1103 }
1104 test SINDEX, A jnz host_message_loop;
1105 p_mesgout_identify:
1106 and SINDEX,LID,SCB_TCL; /* lun */
1107 and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */
1108 or SINDEX,A; /* or in disconnect privledge */
1109 or SINDEX,MSG_IDENTIFYFLAG;
1110 /*
1111 * Send a tag message if TAG_ENB is set in the SCB control block.
1112 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value.
1113 */
1114 p_mesgout_tag:
1115 test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte;
1116 mov SCSIDATL, SINDEX; /* Send the identify message */
1117 call phase_lock;
1118 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
1119 and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL;
1120 call phase_lock;
1121 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
1122 mov SCB_TAG jmp p_mesgout_onebyte;
1123 /*
1124 * Interrupt the driver, and allow it to handle this message
1125 * phase and any required retries.
1126 */
1127 p_mesgout_from_host:
1128 cmp SINDEX, HOST_MSG jne p_mesgout_onebyte;
1129 jmp host_message_loop;
1130
1131 p_mesgout_onebyte:
1132 mvi CLRSINT1, CLRATNO;
1133 mov SCSIDATL, SINDEX;
1134
1135 /*
1136 * If the next bus phase after ATN drops is message out, it means
1137 * that the target is requesting that the last message(s) be resent.
1138 */
1139 call phase_lock;
1140 cmp LASTPHASE, P_MESGOUT je p_mesgout_retry;
1141
1142 p_mesgout_done:
1143 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */
1144 mov LAST_MSG, MSG_OUT;
1145 mvi MSG_OUT, MSG_NOOP; /* No message left */
1146 jmp ITloop;
1147
1148 /*
1149 * Message in phase. Bytes are read using Automatic PIO mode.
1150 */
1151 p_mesgin:
1152 mvi ACCUM call inb_first; /* read the 1st message byte */
1153
1154 test A,MSG_IDENTIFYFLAG jnz mesgin_identify;
1155 cmp A,MSG_DISCONNECT je mesgin_disconnect;
1156 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs;
1157 cmp ALLZEROS,A je mesgin_complete;
1158 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs;
1159 cmp A,MSG_NOOP je mesgin_done;
1160
1161 /*
1162 * Pushed message loop to allow the kernel to
1163 * run it's own message state engine. To avoid an
1164 * extra nop instruction after signaling the kernel,
1165 * we perform the phase_lock before checking to see
1166 * if we should exit the loop and skip the phase_lock
1167 * in the ITloop. Performing back to back phase_locks
1168 * shouldn't hurt, but why do it twice...
1169 */
1170 host_message_loop:
1171 mvi INTSTAT, HOST_MSG_LOOP;
1172 call phase_lock;
1173 cmp RETURN_1, EXIT_MSG_LOOP je ITloop + 1;
1174 jmp host_message_loop;
1175
1176 mesgin_done:
1177 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
1178 jmp ITloop;
1179
1180
1181 mesgin_complete:
1182 /*
1183 * We got a "command complete" message, so put the SCB_TAG into the QOUTFIFO,
1184 * and trigger a completion interrupt. Before doing so, check to see if there
1185 * is a residual or the status byte is something other than STATUS_GOOD (0).
1186 * In either of these conditions, we upload the SCB back to the host so it can
1187 * process this information. In the case of a non zero status byte, we
1188 * additionally interrupt the kernel driver synchronously, allowing it to
1189 * decide if sense should be retrieved. If the kernel driver wishes to request
1190 * sense, it will fill the kernel SCB with a request sense command and set
1191 * RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE we redownload
1192 * the SCB, and process it as the next command by adding it to the waiting list.
1193 * If the kernel driver does not wish to request sense, it need only clear
1194 * RETURN_1, and the command is allowed to complete normally. We don't bother
1195 * to post to the QOUTFIFO in the error cases since it would require extra
1196 * work in the kernel driver to ensure that the entry was removed before the
1197 * command complete code tried processing it.
1198 */
1199
1200 /*
1201 * First check for residuals
1202 */
1203 test SCB_RESID_SGCNT,0xff jnz upload_scb;
1204 test SCB_TARGET_STATUS,0xff jz complete; /* Good Status? */
1205 upload_scb:
1206 mvi DMAPARAMS, FIFORESET;
1207 mov SCB_TAG call dma_scb;
1208 check_status:
1209 test SCB_TARGET_STATUS,0xff jz complete; /* Just a residual? */
1210 mvi INTSTAT,BAD_STATUS; /* let driver know */
1211 nop;
1212 cmp RETURN_1, SEND_SENSE jne complete;
1213 /* This SCB becomes the next to execute as it will retrieve sense */
1214 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
1215 mov SCB_TAG call dma_scb;
1216 add_to_waiting_list:
1217 mov SCB_NEXT,WAITING_SCBH;
1218 mov WAITING_SCBH, SCBPTR;
1219 /*
1220 * Prepare our selection hardware before the busfree so we have a
1221 * high probability of winning arbitration.
1222 */
1223 call start_selection;
1224 jmp await_busfree;
1225
1226 complete:
1227 /* If we are untagged, clear our address up in host ram */
1228 test SCB_CONTROL, TAG_ENB jnz complete_queue;
1229 mov A, SAVED_TCL;
1230 /* fvdl - let ahc_intr clear this to avoid race conditions */
1231 /* mvi UNTAGGEDSCB_OFFSET call post_byte_setup; */
1232 /* mvi SCB_LIST_NULL call post_byte; */
1233
1234 complete_queue:
1235 mov SCB_TAG call complete_post;
1236 jmp await_busfree;
1237 }
1238
1239 complete_post:
1240 /* Post the SCBID in SINDEX and issue an interrupt */
1241 call add_scb_to_free_list;
1242 mov ARG_1, SINDEX;
1243 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
1244 mov A, SDSCB_QOFF;
1245 } else {
1246 mov A, QOUTPOS;
1247 }
1248 mvi QOUTFIFO_OFFSET call post_byte_setup;
1249 mov ARG_1 call post_byte;
1250 if ((ahc->features & AHC_QUEUE_REGS) == 0) {
1251 inc QOUTPOS;
1252 }
1253 mvi INTSTAT,CMDCMPLT ret;
1254
1255 if ((ahc->flags & AHC_INITIATORMODE) != 0) {
1256 /*
1257 * Is it a disconnect message? Set a flag in the SCB to remind us
1258 * and await the bus going free.
1259 */
1260 mesgin_disconnect:
1261 or SCB_CONTROL,DISCONNECTED;
1262 call add_scb_to_disc_list;
1263 jmp await_busfree;
1264
1265 /*
1266 * Save data pointers message:
1267 * Copying RAM values back to SCB, for Save Data Pointers message, but
1268 * only if we've actually been into a data phase to change them. This
1269 * protects against bogus data in scratch ram and the residual counts
1270 * since they are only initialized when we go into data_in or data_out.
1271 */
1272 mesgin_sdptrs:
1273 test SEQ_FLAGS, DPHASE jz mesgin_done;
1274
1275 /*
1276 * The SCB SGPTR becomes the next one we'll download,
1277 * and the SCB DATAPTR becomes the current SHADDR.
1278 * Use the residual number since STCNT is corrupted by
1279 * any message transfer.
1280 */
1281 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1282 bmov SCB_SGCOUNT, SG_COUNT, 5;
1283 bmov SCB_DATAPTR, SHADDR, 4;
1284 bmov SCB_DATACNT, SCB_RESID_DCNT, 3;
1285 } else {
1286 mvi DINDEX, SCB_SGCOUNT;
1287 mvi SG_COUNT call bcopy_5;
1288
1289 mvi DINDEX, SCB_DATAPTR;
1290 mvi SHADDR call bcopy_4;
1291 mvi SCB_RESID_DCNT call bcopy_3;
1292 }
1293 jmp mesgin_done;
1294
1295 /*
1296 * Restore pointers message? Data pointers are recopied from the
1297 * SCB anytime we enter a data phase for the first time, so all
1298 * we need to do is clear the DPHASE flag and let the data phase
1299 * code do the rest.
1300 */
1301 mesgin_rdptrs:
1302 and SEQ_FLAGS, ~DPHASE; /*
1303 * We'll reload them
1304 * the next time through
1305 * the dataphase.
1306 */
1307 jmp mesgin_done;
1308
1309 /*
1310 * Identify message? For a reconnecting target, this tells us the lun
1311 * that the reconnection is for - find the correct SCB and switch to it,
1312 * clearing the "disconnected" bit so we don't "find" it by accident later.
1313 */
1314 mesgin_identify:
1315 if ((ahc->features & AHC_WIDE) != 0) {
1316 and A,0x0f; /* lun in lower four bits */
1317 } else {
1318 and A,0x07; /* lun in lower three bits */
1319 }
1320 or SAVED_TCL,A; /* SAVED_TCL should be complete now */
1321
1322 mvi ARG_2, SCB_LIST_NULL; /* SCBID of prev SCB in disc List */
1323 call get_untagged_SCBID;
1324 cmp ARG_1, SCB_LIST_NULL je snoop_tag;
1325 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1326 test SEQ_FLAGS, SCBPTR_VALID jz use_retrieveSCB;
1327 }
1328 /*
1329 * If the SCB was found in the disconnected list (as is
1330 * always the case in non-paging scenarios), SCBPTR is already
1331 * set to the correct SCB. So, simply setup the SCB and get
1332 * on with things.
1333 */
1334 call rem_scb_from_disc_list;
1335 jmp setup_SCB;
1336 /*
1337 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
1338 * If we get one, we use the tag returned to find the proper
1339 * SCB. With SCB paging, this requires using search for both tagged
1340 * and non-tagged transactions since the SCB may exist in any slot.
1341 * If we're not using SCB paging, we can use the tag as the direct
1342 * index to the SCB.
1343 */
1344 snoop_tag:
1345 mov NONE,SCSIDATL; /* ACK Identify MSG */
1346 snoop_tag_loop:
1347 call phase_lock;
1348 cmp LASTPHASE, P_MESGIN jne not_found;
1349 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found;
1350 get_tag:
1351 mvi ARG_1 call inb_next; /* tag value */
1352
1353 /*
1354 * Ensure that the SCB the tag points to is for
1355 * an SCB transaction to the reconnecting target.
1356 */
1357 use_retrieveSCB:
1358 call retrieveSCB;
1359 setup_SCB:
1360 mov A, SAVED_TCL;
1361 cmp SCB_TCL, A jne not_found_cleanup_scb;
1362 test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb;
1363 and SCB_CONTROL,~DISCONNECTED;
1364 or SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */
1365 call set_transfer_settings;
1366 /* See if the host wants to send a message upon reconnection */
1367 test SCB_CONTROL, MK_MESSAGE jz mesgin_done;
1368 and SCB_CONTROL, ~MK_MESSAGE;
1369 mvi HOST_MSG call mk_mesg;
1370 jmp mesgin_done;
1371
1372 not_found_cleanup_scb:
1373 test SCB_CONTROL, DISCONNECTED jz . + 3;
1374 call add_scb_to_disc_list;
1375 jmp not_found;
1376 call add_scb_to_free_list;
1377 not_found:
1378 mvi INTSTAT, NO_MATCH;
1379 jmp mesgin_done;
1380
1381 /*
1382 * [ ADD MORE MESSAGE HANDLING HERE ]
1383 */
1384
1385 /*
1386 * Locking the driver out, build a one-byte message passed in SINDEX
1387 * if there is no active message already. SINDEX is returned intact.
1388 */
1389 mk_mesg:
1390 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */
1391 mov MSG_OUT,SINDEX ret;
1392
1393 /*
1394 * Functions to read data in Automatic PIO mode.
1395 *
1396 * According to Adaptec's documentation, an ACK is not sent on input from
1397 * the target until SCSIDATL is read from. So we wait until SCSIDATL is
1398 * latched (the usual way), then read the data byte directly off the bus
1399 * using SCSIBUSL. When we have pulled the ATN line, or we just want to
1400 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI
1401 * spec guarantees that the target will hold the data byte on the bus until
1402 * we send our ACK.
1403 *
1404 * The assumption here is that these are called in a particular sequence,
1405 * and that REQ is already set when inb_first is called. inb_{first,next}
1406 * use the same calling convention as inb.
1407 */
1408 inb_next_wait_perr:
1409 mvi INTSTAT, PERR_DETECTED;
1410 jmp inb_next_wait;
1411 inb_next:
1412 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
1413 inb_next_wait:
1414 /*
1415 * If there is a parity error, wait for the kernel to
1416 * see the interrupt and prepare our message response
1417 * before continuing.
1418 */
1419 test SSTAT1, REQINIT jz inb_next_wait;
1420 test SSTAT1, SCSIPERR jnz inb_next_wait_perr;
1421 inb_next_check_phase:
1422 and LASTPHASE, PHASE_MASK, SCSISIGI;
1423 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis;
1424 inb_first:
1425 mov DINDEX,SINDEX;
1426 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/
1427 inb_last:
1428 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/
1429 }
1430
1431 if ((ahc->flags & AHC_TARGETMODE) != 0) {
1432 /*
1433 * Change to a new phase. If we are changing the state of the I/O signal,
1434 * from out to in, wait an additional data release delay before continuing.
1435 */
1436 change_phase:
1437 /* Wait for preceeding I/O session to complete. */
1438 test SCSISIGI, ACKI jnz .;
1439
1440 /* Change the phase */
1441 and DINDEX, IOI, SCSISIGI;
1442 mov SCSISIGO, SINDEX;
1443 and A, IOI, SINDEX;
1444
1445 /*
1446 * If the data direction has changed, from
1447 * out (initiator driving) to in (target driving),
1448 * we must waitat least a data release delay plus
1449 * the normal bus settle delay. [SCSI III SPI 10.11.0]
1450 */
1451 cmp DINDEX, A je change_phase_wait;
1452 test SINDEX, IOI jz change_phase_wait;
1453 call change_phase_wait;
1454 change_phase_wait:
1455 nop;
1456 nop;
1457 nop;
1458 nop ret;
1459
1460 /*
1461 * Send a byte to an initiator in Automatic PIO mode.
1462 */
1463 target_outb:
1464 or SXFRCTL0, SPIOEN;
1465 test SSTAT0, SPIORDY jz .;
1466 mov SCSIDATL, SINDEX;
1467 test SSTAT0, SPIORDY jz .;
1468 and SXFRCTL0, ~SPIOEN ret;
1469 }
1470
1471 mesgin_phasemis:
1472 /*
1473 * We expected to receive another byte, but the target changed phase
1474 */
1475 mvi INTSTAT, MSGIN_PHASEMIS;
1476 jmp ITloop;
1477
1478 /*
1479 * DMA data transfer. HADDR and HCNT must be loaded first, and
1480 * SINDEX should contain the value to load DFCNTRL with - 0x3d for
1481 * host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared
1482 * during initialization.
1483 */
1484 dma:
1485 mov DFCNTRL,SINDEX;
1486 dma_loop:
1487 test SSTAT0,DMADONE jnz dma_dmadone;
1488 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */
1489 dma_phasemis:
1490
1491 /*
1492 * We will be "done" DMAing when the transfer count goes to zero, or
1493 * the target changes the phase (in light of this, it makes sense that
1494 * the DMA circuitry doesn't ACK when PHASEMIS is active). If we are
1495 * doing a SCSI->Host transfer, the data FIFO should be flushed auto-
1496 * magically on STCNT=0 or a phase change, so just wait for FIFO empty
1497 * status.
1498 */
1499 dma_checkfifo:
1500 test DFCNTRL,DIRECTION jnz dma_fifoempty;
1501 dma_fifoflush:
1502 test DFSTATUS,FIFOEMP jz dma_fifoflush;
1503
1504 dma_fifoempty:
1505 /* Don't clobber an inprogress host data transfer */
1506 test DFSTATUS, MREQPEND jnz dma_fifoempty;
1507 /*
1508 * Now shut the DMA enables off and make sure that the DMA enables are
1509 * actually off first lest we get an ILLSADDR.
1510 */
1511 dma_dmadone:
1512 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);
1513 dma_halt:
1514 /*
1515 * Some revisions of the aic7880 have a problem where, if the
1516 * data fifo is full, but the PCI input latch is not empty,
1517 * HDMAEN cannot be cleared. The fix used here is to attempt
1518 * to drain the data fifo until there is space for the input
1519 * latch to drain and HDMAEN de-asserts.
1520 */
1521 if ((ahc->features & AHC_ULTRA2) == 0) {
1522 mov NONE, DFDAT;
1523 }
1524 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt;
1525 return:
1526 ret;
1527
1528 /*
1529 * Assert that if we've been reselected, then we've seen an IDENTIFY
1530 * message.
1531 */
1532 assert:
1533 test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */
1534
1535 mvi INTSTAT,NO_IDENT ret; /* no - tell the kernel */
1536
1537 /*
1538 * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL)
1539 * or by the SCBID ARG_1. The search begins at the SCB index passed in
1540 * via SINDEX which is an SCB that must be on the disconnected list. If
1541 * the SCB cannot be found, SINDEX will be SCB_LIST_NULL, otherwise, SCBPTR
1542 * is set to the proper SCB.
1543 */
1544 findSCB:
1545 mov SCBPTR,SINDEX; /* Initialize SCBPTR */
1546 cmp ARG_1, SCB_LIST_NULL jne findSCB_by_SCBID;
1547 mov A, SAVED_TCL;
1548 mvi SCB_TCL jmp findSCB_loop; /* &SCB_TCL -> SINDEX */
1549 findSCB_by_SCBID:
1550 mov A, ARG_1; /* Tag passed in ARG_1 */
1551 mvi SCB_TAG jmp findSCB_loop; /* &SCB_TAG -> SINDEX */
1552 findSCB_next:
1553 mov ARG_2, SCBPTR;
1554 cmp SCB_NEXT, SCB_LIST_NULL je notFound;
1555 mov SCBPTR,SCB_NEXT;
1556 dec SINDEX; /* Last comparison moved us too far */
1557 findSCB_loop:
1558 cmp SINDIR, A jne findSCB_next;
1559 mov SINDEX, SCBPTR ret;
1560 notFound:
1561 mvi SINDEX, SCB_LIST_NULL ret;
1562
1563 /*
1564 * Retrieve an SCB by SCBID first searching the disconnected list falling
1565 * back to DMA'ing the SCB down from the host. This routine assumes that
1566 * ARG_1 is the SCBID of interrest and that SINDEX is the position in the
1567 * disconnected list to start the search from. If SINDEX is SCB_LIST_NULL,
1568 * we go directly to the host for the SCB.
1569 */
1570 retrieveSCB:
1571 test SEQ_FLAGS, SCBPTR_VALID jz retrieve_from_host;
1572 mov SCBPTR call findSCB; /* Continue the search */
1573 cmp SINDEX, SCB_LIST_NULL je retrieve_from_host;
1574
1575 /*
1576 * This routine expects SINDEX to contain the index of the SCB to be
1577 * removed, SCBPTR to be pointing to that SCB, and ARG_2 to be the
1578 * SCBID of the SCB just previous to this one in the list or SCB_LIST_NULL
1579 * if it is at the head.
1580 */
1581 rem_scb_from_disc_list:
1582 /* Remove this SCB from the disconnection list */
1583 cmp ARG_2, SCB_LIST_NULL je rHead;
1584 mov DINDEX, SCB_NEXT;
1585 mov SCBPTR, ARG_2;
1586 mov SCB_NEXT, DINDEX;
1587 mov SCBPTR, SINDEX ret;
1588 rHead:
1589 mov DISCONNECTED_SCBH,SCB_NEXT ret;
1590
1591 retrieve_from_host:
1592 /*
1593 * We didn't find it. Pull an SCB and DMA down the one we want.
1594 * We should never get here in the non-paging case.
1595 */
1596 mov ALLZEROS call get_free_or_disc_scb;
1597 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
1598 /* Jump instead of call as we want to return anyway */
1599 mov ARG_1 jmp dma_scb;
1600
1601 /*
1602 * Determine whether a target is using tagged or non-tagged transactions
1603 * by first looking for a matching transaction based on the TCL and if
1604 * that fails, looking up this device in the host's untagged SCB array.
1605 * The TCL to search for is assumed to be in SAVED_TCL. The value is
1606 * returned in ARG_1 (SCB_LIST_NULL for tagged, SCBID for non-tagged).
1607 * The SCBPTR_VALID bit is set in SEQ_FLAGS if we found the information
1608 * in an SCB instead of having to go to the host.
1609 */
1610 get_untagged_SCBID:
1611 cmp DISCONNECTED_SCBH, SCB_LIST_NULL je get_SCBID_from_host;
1612 mvi ARG_1, SCB_LIST_NULL;
1613 mov DISCONNECTED_SCBH call findSCB;
1614 cmp SINDEX, SCB_LIST_NULL je get_SCBID_from_host;
1615 or SEQ_FLAGS, SCBPTR_VALID;/* Was in disconnected list */
1616 test SCB_CONTROL, TAG_ENB jnz . + 2;
1617 mov ARG_1, SCB_TAG ret;
1618 mvi ARG_1, SCB_LIST_NULL ret;
1619
1620 /*
1621 * Fetch a byte from host memory given an index of (A + (256 * SINDEX))
1622 * and a base address of SCBID_ADDR. The byte is returned in RETURN_2.
1623 */
1624 fetch_byte:
1625 mov ARG_2, SINDEX;
1626 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1627 mvi DINDEX, CCHADDR;
1628 mvi SCBID_ADDR call set_1byte_addr;
1629 mvi CCHCNT, 1;
1630 mvi CCSGCTL, CCSGEN|CCSGRESET;
1631 test CCSGCTL, CCSGDONE jz .;
1632 mvi CCSGCTL, CCSGRESET;
1633 bmov RETURN_2, CCSGRAM, 1 ret;
1634 } else {
1635 mvi DINDEX, HADDR;
1636 mvi SCBID_ADDR call set_1byte_addr;
1637 mvi HCNT[0], 1;
1638 clr HCNT[1];
1639 clr HCNT[2];
1640 mvi DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
1641 call dma_finish;
1642 mov RETURN_2, DFDAT ret;
1643 }
1644
1645 /*
1646 * Prepare the hardware to post a byte to host memory given an
1647 * index of (A + (256 * SINDEX)) and a base address of SCBID_ADDR.
1648 */
1649 post_byte_setup:
1650 mov ARG_2, SINDEX;
1651 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1652 mvi DINDEX, CCHADDR;
1653 mvi SCBID_ADDR call set_1byte_addr;
1654 mvi CCHCNT, 1;
1655 mvi CCSCBCTL, CCSCBRESET ret;
1656 } else {
1657 mvi DINDEX, HADDR;
1658 mvi SCBID_ADDR call set_1byte_addr;
1659 mvi HCNT[0], 1;
1660 clr HCNT[1];
1661 clr HCNT[2];
1662 mvi DFCNTRL, FIFORESET ret;
1663 }
1664
1665 post_byte:
1666 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1667 bmov CCSCBRAM, SINDEX, 1;
1668 or CCSCBCTL, CCSCBEN|CCSCBRESET;
1669 test CCSCBCTL, CCSCBDONE jz .;
1670 clr CCSCBCTL ret;
1671 } else {
1672 mov DFDAT, SINDEX;
1673 or DFCNTRL, HDMAEN|FIFOFLUSH;
1674 jmp dma_finish;
1675 }
1676
1677 get_SCBID_from_host:
1678 mov A, SAVED_TCL;
1679 mvi UNTAGGEDSCB_OFFSET call fetch_byte;
1680 mov RETURN_1, RETURN_2 ret;
1681
1682 phase_lock_perr:
1683 mvi INTSTAT, PERR_DETECTED;
1684 phase_lock:
1685 /*
1686 * If there is a parity error, wait for the kernel to
1687 * see the interrupt and prepare our message response
1688 * before continuing.
1689 */
1690 test SSTAT1, REQINIT jz phase_lock;
1691 test SSTAT1, SCSIPERR jnz phase_lock_perr;
1692 phase_lock_latch_phase:
1693 and SCSISIGO, PHASE_MASK, SCSISIGI;
1694 and LASTPHASE, PHASE_MASK, SCSISIGI ret;
1695
1696 if ((ahc->features & AHC_CMD_CHAN) == 0) {
1697 set_stcnt_from_hcnt:
1698 mov STCNT[0], HCNT[0];
1699 mov STCNT[1], HCNT[1];
1700 mov STCNT[2], HCNT[2] ret;
1701
1702 bcopy_7:
1703 mov DINDIR, SINDIR;
1704 mov DINDIR, SINDIR;
1705 bcopy_5:
1706 mov DINDIR, SINDIR;
1707 bcopy_4:
1708 mov DINDIR, SINDIR;
1709 bcopy_3:
1710 mov DINDIR, SINDIR;
1711 mov DINDIR, SINDIR;
1712 mov DINDIR, SINDIR ret;
1713 }
1714
1715 if ((ahc->flags & AHC_TARGETMODE) != 0) {
1716 /*
1717 * Setup addr assuming that A is an index into
1718 * an array of 32byte objects, SINDEX contains
1719 * the base address of that array, and DINDEX
1720 * contains the base address of the location
1721 * to store the indexed address.
1722 */
1723 set_32byte_addr:
1724 shr ARG_2, 3, A;
1725 shl A, 5;
1726 jmp set_1byte_addr;
1727 }
1728
1729 /*
1730 * Setup addr assuming that A is an index into
1731 * an array of 64byte objects, SINDEX contains
1732 * the base address of that array, and DINDEX
1733 * contains the base address of the location
1734 * to store the indexed address.
1735 */
1736 set_64byte_addr:
1737 shr ARG_2, 2, A;
1738 shl A, 6;
1739
1740 /*
1741 * Setup addr assuming that A + (ARG_1 * 256) is an
1742 * index into an array of 1byte objects, SINDEX contains
1743 * the base address of that array, and DINDEX contains
1744 * the base address of the location to store the computed
1745 * address.
1746 */
1747 set_1byte_addr:
1748 add DINDIR, A, SINDIR;
1749 mov A, ARG_2;
1750 adc DINDIR, A, SINDIR;
1751 clr A;
1752 adc DINDIR, A, SINDIR;
1753 adc DINDIR, A, SINDIR ret;
1754
1755 /*
1756 * Either post or fetch and SCB from host memory based on the
1757 * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX.
1758 */
1759 dma_scb:
1760 mov A, SINDEX;
1761 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1762 mvi DINDEX, CCHADDR;
1763 mvi HSCB_ADDR call set_64byte_addr;
1764 mov CCSCBPTR, SCBPTR;
1765 test DMAPARAMS, DIRECTION jz dma_scb_tohost;
1766 mvi CCHCNT, SCB_64BYTE_SIZE;
1767 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET;
1768 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .;
1769 jmp dma_scb_finish;
1770 dma_scb_tohost:
1771 mvi CCHCNT, SCB_32BYTE_SIZE;
1772 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
1773 mvi CCSCBCTL, CCSCBRESET;
1774 bmov CCSCBRAM, SCB_CONTROL, SCB_32BYTE_SIZE;
1775 or CCSCBCTL, CCSCBEN|CCSCBRESET;
1776 test CCSCBCTL, CCSCBDONE jz .;
1777 } else {
1778 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET;
1779 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .;
1780 }
1781 dma_scb_finish:
1782 clr CCSCBCTL;
1783 test CCSCBCTL, CCARREN|CCSCBEN jnz .;
1784 ret;
1785 } else {
1786 mvi DINDEX, HADDR;
1787 mvi HSCB_ADDR call set_64byte_addr;
1788 mvi HCNT[0], SCB_32BYTE_SIZE;
1789 clr HCNT[1];
1790 clr HCNT[2];
1791 mov DFCNTRL, DMAPARAMS;
1792 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost;
1793 /* Fill it with the SCB data */
1794 copy_scb_tofifo:
1795 mvi SINDEX, SCB_CONTROL;
1796 add A, SCB_32BYTE_SIZE, SINDEX;
1797 copy_scb_tofifo_loop:
1798 mov DFDAT,SINDIR;
1799 mov DFDAT,SINDIR;
1800 mov DFDAT,SINDIR;
1801 mov DFDAT,SINDIR;
1802 mov DFDAT,SINDIR;
1803 mov DFDAT,SINDIR;
1804 mov DFDAT,SINDIR;
1805 cmp SINDEX, A jne copy_scb_tofifo_loop;
1806 or DFCNTRL, HDMAEN|FIFOFLUSH;
1807 dma_scb_fromhost:
1808 call dma_finish;
1809 /* If we were putting the SCB, we are done */
1810 test DMAPARAMS, DIRECTION jz return;
1811 mvi SCB_CONTROL call dfdat_in_7;
1812 call dfdat_in_7_continued;
1813 call dfdat_in_7_continued;
1814 jmp dfdat_in_7_continued;
1815 dfdat_in_7:
1816 mov DINDEX,SINDEX;
1817 dfdat_in_7_continued:
1818 mov DINDIR,DFDAT;
1819 mov DINDIR,DFDAT;
1820 mov DINDIR,DFDAT;
1821 mov DINDIR,DFDAT;
1822 mov DINDIR,DFDAT;
1823 mov DINDIR,DFDAT;
1824 mov DINDIR,DFDAT ret;
1825 }
1826
1827
1828 /*
1829 * Wait for DMA from host memory to data FIFO to complete, then disable
1830 * DMA and wait for it to acknowledge that it's off.
1831 */
1832 dma_finish:
1833 test DFSTATUS,HDONE jz dma_finish;
1834 /* Turn off DMA */
1835 and DFCNTRL, ~HDMAEN;
1836 test DFCNTRL, HDMAEN jnz .;
1837 ret;
1838
1839 add_scb_to_free_list:
1840 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1841 mov SCB_NEXT, FREE_SCBH;
1842 mvi SCB_TAG, SCB_LIST_NULL;
1843 mov FREE_SCBH, SCBPTR ret;
1844 } else {
1845 mvi SCB_TAG, SCB_LIST_NULL ret;
1846 }
1847
1848 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1849 get_free_or_disc_scb:
1850 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
1851 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;
1852 return_error:
1853 mvi SINDEX, SCB_LIST_NULL ret;
1854 dequeue_disc_scb:
1855 mov SCBPTR, DISCONNECTED_SCBH;
1856 dma_up_scb:
1857 mvi DMAPARAMS, FIFORESET;
1858 mov SCB_TAG call dma_scb;
1859 unlink_disc_scb:
1860 mov DISCONNECTED_SCBH, SCB_NEXT ret;
1861 dequeue_free_scb:
1862 mov SCBPTR, FREE_SCBH;
1863 mov FREE_SCBH, SCB_NEXT ret;
1864 }
1865
1866 add_scb_to_disc_list:
1867 /*
1868 * Link this SCB into the DISCONNECTED list. This list holds the
1869 * candidates for paging out an SCB if one is needed for a new command.
1870 * Modifying the disconnected list is a critical(pause dissabled) section.
1871 */
1872 mov SCB_NEXT, DISCONNECTED_SCBH;
1873 mov DISCONNECTED_SCBH, SCBPTR ret;
1874