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