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