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