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