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