xref: /original-bsd/sys/news3400/hbdev/scsi_1185.c (revision 3705696b)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: scsi_1185.c,v 4.300 91/06/09 06:22:20 root Rel41 $ SONY
11  *
12  *	@(#)scsi_1185.c	8.1 (Berkeley) 06/11/93
13  */
14 
15 /*
16  * Copyright (c) 1989- by SONY Corporation.
17  */
18 /*
19  *	scsi_1185.c
20  *
21  *	CXD1185Q
22  *	SCSI bus low level common routines
23  *				for one cpu machine
24  */
25 /*
26  * MODIFY HISTORY:
27  *
28  *	DMAC_WAIT	--- DMAC_0266 wo tukau-baai, DMAC mata-wa SCSI-chip ni
29  *				tuzukete access suru-baai,
30  *				kanarazu wait wo ireru-beshi !
31  *
32  */
33 
34 #include <sys/types.h>
35 #include <machine/pte.h>
36 #include <machine/cpu.h>
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/map.h>
41 #include <sys/buf.h>
42 #include <vm/vm.h>
43 #include <sys/proc.h>
44 #include <sys/user.h>
45 #include <sys/conf.h>
46 #include <sys/dkstat.h>
47 #include <sys/kernel.h>
48 
49 #include <news3400/hbdev/hbvar.h>
50 #include <news3400/hbdev/screg_1185.h>
51 #include <news3400/hbdev/scsic.h>
52 
53 #ifdef news3400
54 # include <news3400/hbdev/dmac_0448.h>
55 # ifndef NDMACMAP
56 # define NDMACMAP	144
57 # endif
58 #endif
59 
60 #include <news3400/iodev/scsireg.h>
61 
62 #ifdef mips
63 #define	VOLATILE	volatile
64 #else
65 #define	VOLATILE
66 #endif
67 
68 #define ABORT_SYNCTR_MES_FROM_TARGET
69 #define SCSI_1185AQ
70 #define RESET_RECOVER
71 
72 #define DMAC_MAP_INIT			/* for nws-3700 parity error */
73 
74 #define APAD_ALWAYS_ON
75 
76 # define	CHECK_LOOP_CNT	60
77 # define	RSL_LOOP_CNT	60
78 
79 #ifndef DMAC_MAP_INIT
80 # define MAP_OVER_ACCESS		/* for nws-3700 parity error */
81 #endif
82 
83 #undef	CHECK_MRQ
84 
85 #ifdef NOT_SUPPORT_SYNCTR
86 # define	MAX_OFFSET_BYTES	0
87 #else
88 # define	MAX_OFFSET_BYTES	MAX_OFFSET
89 #endif
90 
91 #define	NTARGET		8
92 
93 #define	act_point	spoint
94 #define	act_trcnt	stcnt
95 #define	act_tag		stag
96 #define	act_offset	soffset
97 
98 #define	splscsi		splsc
99 
100 #if defined(mips) && defined(CPU_SINGLE)
101 #define nops(x)		{ int i; for (i = 0; i < (x); i++) ; }
102 #define	vtophys(v)	MACH_UNMAPPED_TO_PHYS(v)
103 #define	DMAC_WAIT0	;
104 #else
105 #define	DMAC_WAIT0	DMAC_WAIT
106 #endif
107 
108 int	perr_flag[NTARGET];
109 
110 #ifndef NOT_SUPPORT_SYNCTR
111 VOLATILE char sync_tr[NTARGET];
112 #endif
113 
114 #ifdef DMAC_MAP_INIT
115 int	dmac_map_init = 0;
116 #endif
117 
118 #ifdef SCSI_1185AQ
119 int	scsi_1185AQ = 0;
120 #endif
121 
122 struct sc_chan_stat chan_stat[NTARGET];	/* SCSI channel status */
123 int	sel_stat[NTARGET];		/* target select status */
124 #define	SEL_WAIT	0
125 #define	SEL_START	1
126 #define	SEL_TIMEOUT	2
127 #define	SEL_ARBF	3
128 #define	SEL_SUCCESS	4
129 #define	SEL_RSLD	5
130 #define	SEL_RSL_WAIT	6
131 
132 /*
133  *	command flag status
134  */
135 #define	CF_SET		1
136 #define	CF_SEND		2
137 #define	CF_ENOUGH	3
138 #define	CF_EXEC		4
139 
140 #define	SEL_TIMEOUT_VALUE	0x7a
141 
142 VOLATILE int int_stat1;
143 VOLATILE int int_stat2;
144 
145 VOLATILE int min_flag;
146 
147 VOLATILE char mout_flag[NTARGET];
148 #define MOUT_IDENTIFY	1
149 #define MOUT_SYNC_TR	2
150 
151 VOLATILE int	last_cmd;
152 VOLATILE char	min_cnt[NTARGET];
153 VOLATILE u_char	*min_point[NTARGET];
154 VOLATILE int	pad_cnt[NTARGET];
155 
156 VOLATILE static u_char *act_cmd_pointer;
157 static VOLATILE struct sc_chan_stat *wbq_actf = 0; /* forword active pointer */
158 static VOLATILE struct sc_chan_stat *wbq_actl = 0; /* last active pointer */
159 static char ScsiSoftError[] = "SCSI soft error";
160 
161 static int pad_start;
162 
163 #if defined(mips) && defined(CPU_SINGLE)
164 #define dma_reset(x) { \
165 	int s = splscsi(); \
166 	dmac_gsel = (x); dmac_cctl = DM_RST; dmac_cctl = 0; \
167 	splx(s); \
168 }
169 #endif
170 
171 WAIT_STATR_BITCLR(bitmask)
172 	register int bitmask;
173 {
174 	register int iloop;
175 	register VOLATILE int dummy;
176 
177 	iloop = 0;
178 	do {
179 		dummy = sc_statr;
180 		DMAC_WAIT0;
181 		if (iloop++ > CHECK_LOOP_CNT)
182 			return (-1);
183 	} while (dummy & bitmask);
184 	return (0);
185 }
186 
187 WAIT_STATR_BITSET(bitmask)
188 	register int bitmask;
189 {
190 	register int iloop;
191 	register VOLATILE int dummy;
192 
193 	iloop = 0;
194 	do {
195 		dummy = sc_statr;
196 		DMAC_WAIT0;
197 		if (iloop++ > CHECK_LOOP_CNT)
198 			return (-1);
199 	} while ((dummy & bitmask) == 0);
200 	return (0);
201 }
202 
203 SET_CMD(CMD)
204 	register int CMD;
205 {
206 
207 	(void) WAIT_STATR_BITCLR(R0_CIP);
208 	last_cmd = (CMD);
209 	sc_comr = (CMD);
210 	DMAC_WAIT0;
211 }
212 
213 SET_CNT(COUNT)
214 	register int COUNT;
215 {
216 
217 	sc_tclow = (COUNT) & 0xff;
218 	DMAC_WAIT0;
219 	sc_tcmid = ((COUNT) >> 8) & 0xff;
220 	DMAC_WAIT0;
221 	sc_tchi = ((COUNT) >> 16) & 0xff;
222 	DMAC_WAIT0;
223 }
224 
225 GET_CNT()
226 {
227 	register VOLATILE int COUNT;
228 
229 	COUNT = sc_tclow;
230 	DMAC_WAIT0;
231 	COUNT += (sc_tcmid << 8) & 0xff00;
232 	DMAC_WAIT0;
233 	COUNT += (sc_tchi << 16) & 0xff0000;
234 	DMAC_WAIT0;
235 	return (COUNT);
236 }
237 
238 GET_INTR(DATA1, DATA2)
239 	register VOLATILE int *DATA1;
240 	register VOLATILE int *DATA2;
241 {
242 	register VOLATILE int dummy;
243 
244 	(void) WAIT_STATR_BITCLR(R0_CIP);
245 	while (sc_statr & R0_MIRQ) {
246 		DMAC_WAIT0;
247 		*DATA1 |= sc_intrq1;
248 		DMAC_WAIT0;
249 		*DATA2 |= sc_intrq2;
250 		DMAC_WAIT0;
251 	}
252 }
253 
254 
255 sc_send(chan, ie, sc)
256 	register int chan;
257 	register int ie;
258 	register struct scsi *sc;
259 {
260 	register VOLATILE struct sc_chan_stat *cs;
261 	register struct scsi_stat *ss;
262 	register int i;
263 
264 	cs = &chan_stat[chan];
265 	ss = &scsi_stat;
266 
267 	if (sc == NULL || cs->sc != NULL) {
268 		printf("SCSI%d:sc_send() NULL sc or NOT NULL cs->sc\n", chan);
269 		printf("ie=0x%x sc=0x%x cs->sc=0x%x\n", ie, sc, cs->sc);
270 		if (sc) {
271 			printf("cdb=");
272 			for (i = 0; i < 6; i++)
273 				printf("0x%x ", sc->sc_cdb.un_reserved[i]);
274 			printf("\n");
275 		}
276 		panic(ScsiSoftError);
277 		/*NOTREACHED*/
278 	}
279 
280 	if ((sc->sc_cdb.un_reserved[0] == SCOP_RESET)
281 			&& (sc->sc_cdb.un_reserved[1] == SCOP_RESET)) {
282 		/*
283 		 * SCSI bus reset command procedure
284 		 *	(vender unique by Sony Corp.)
285 		 */
286 #ifdef SCSI_1185AQ
287 		if (sc_idenr & 0x08) {
288 			scsi_1185AQ = 1;
289 		}
290 #endif
291 		cs->sc = sc;
292 		scsi_hardreset();
293 		sc->sc_istatus = INST_EP;
294 		cs->sc = NULL;
295 		return;
296 	}
297 
298 	if (sc->sc_map && (sc->sc_map->mp_pages > 0)) {
299 		/*
300 		 * use map table
301 		 */
302 		sc->sc_coffset = sc->sc_map->mp_offset & PGOFSET;
303 		if (sc->sc_map->mp_pages > NSCMAP) {
304 			printf("SCSI%d: map table overflow\n", chan);
305 			sc->sc_istatus = INST_EP|INST_LB|INST_PRE;
306 			return;
307 		}
308 	} else {
309 		/*
310 		 * no use map table
311 		 */
312 		sc->sc_coffset = (u_int)sc->sc_cpoint & PGOFSET;
313 	}
314 	sc->sc_ctag = 0;
315 
316 	cs->sc = sc;
317 	cs->comflg = OFF;
318 
319 	cs->intr_flg = ie;
320 	cs->chan_num = chan;
321 	perr_flag[chan] = 0;
322 	mout_flag[chan] = 0;
323 	min_cnt[chan] = 0;
324 
325 	sel_stat[chan] = SEL_WAIT;
326 	append_wb(cs);
327 	sc_start();
328 }
329 
330 /*
331  *	SCSI start up routine
332  */
333 sc_start()
334 {
335 	register VOLATILE struct sc_chan_stat *cs;
336 	register struct scsi_stat *ss;
337 	register int s;
338 	register VOLATILE int chan;
339 	register VOLATILE int dummy;
340 
341 	ss = &scsi_stat;
342 
343 	s = splclock();
344 	chan = get_wb_chan();
345 	if ((chan < 0) || (ss->ipc >= 0))
346 		goto sc_start_exit;
347 	if (sel_stat[chan] != SEL_WAIT) {
348 		/*
349 		 * already started
350 		 */
351 		goto sc_start_exit;
352 	}
353 	sel_stat[chan] = SEL_START;
354 	(void) splscsi();
355 
356 	cs = &chan_stat[chan];
357 
358 	dummy = sc_cmonr;
359 	DMAC_WAIT0;
360 	if (dummy & (R4_MBSY|R4_MSEL)) {
361 		sel_stat[chan] = SEL_WAIT;
362 		goto sc_start_exit;
363 	}
364 
365 	/*
366 	 *	send SELECT with ATN command
367 	 */
368 	ss->dma_stat = OFF;
369 	pad_start = 0;
370 	dummy = sc_statr;
371 	DMAC_WAIT0;
372 	if (dummy & R0_CIP) {
373 		sel_stat[chan] = SEL_WAIT;
374 		goto sc_start_exit;
375 	}
376 	sc_idenr = (chan << SC_TG_SHIFT) | SC_OWNID;
377 	DMAC_WAIT0;
378 #ifdef SCSI_1185AQ
379 	if (scsi_1185AQ)
380 		sc_intok1 = Ra_STO|Ra_ARBF;
381 	else
382 		sc_intok1 = Ra_STO|Ra_RSL|Ra_ARBF;
383 #else
384 	sc_intok1 = Ra_STO|Ra_RSL|Ra_ARBF;
385 #endif
386 	DMAC_WAIT0;
387 	/*
388 	 * BUGFIX for signal reflection on BSY
389 	 *	!Rb_DCNT
390 	 */
391 	sc_intok2 = Rb_FNC|Rb_SRST|Rb_PHC|Rb_SPE;
392 	DMAC_WAIT0;
393 
394 	dummy = sc_cmonr;
395 	DMAC_WAIT0;
396 	if (dummy & (R4_MBSY|R4_MSEL)) {
397 		sel_stat[chan] = SEL_WAIT;
398 		goto sc_start_exit;
399 	}
400 	SET_CMD(SCMD_SEL_ATN);
401 
402 sc_start_exit:
403 	splx(s);
404 }
405 
406 /*
407  *	SCSI interrupt service routine
408  */
409 scintr()
410 {
411 	register struct scsi_stat *ss;
412 	register int iloop;
413 	register VOLATILE int chan;
414 	register VOLATILE int dummy;
415 	int s_int1, s_int2;
416 
417 scintr_loop:
418 
419 #if defined(CHECK_MRQ) && defined(news3400)
420 	while (dmac_gstat & CH_MRQ(CH_SCSI))
421 		DMAC_WAIT;
422 #endif
423 
424 	for (iloop = 0; iloop < 100; iloop++) {
425 		dummy = sc_statr;
426 		DMAC_WAIT;
427 		if ((dummy & R0_CIP) == 0)
428 			break;
429 	}
430 
431 	/*
432 	 * get SCSI interrupt request
433 	 */
434 	while (sc_statr & R0_MIRQ) {
435 		DMAC_WAIT0;
436 		s_int1 = sc_intrq1;
437 		DMAC_WAIT0;
438 		s_int2 = sc_intrq2;
439 		DMAC_WAIT0;
440 		int_stat1 |= s_int1;
441 		int_stat2 |= s_int2;
442 	}
443 
444 	if (int_stat2 & R3_SRST) {
445 		/*
446 		 * RST signal is drived
447 		 */
448 		int_stat2 &= ~R3_SRST;
449 		scsi_softreset();
450 		goto scintr_exit;
451 	}
452 
453 	ss = &scsi_stat;
454 	if ((ss->ipc < 0) && (ss->wrc <= 0) && (ss->wbc <= 0)) {
455 		int_stat1 = 0;
456 		int_stat2 = 0;
457 		goto scintr_exit;
458 	}
459 
460 	chan = get_wb_chan();
461 	if ((chan >= 0) && (sel_stat[chan] == SEL_START) &&
462 		(last_cmd == SCMD_SEL_ATN)) {
463 		/*
464 		 *	Check the result of SELECTION command
465 		 */
466 		if (int_stat1 & R2_RSL) {
467 			/*
468 			 * RESELECTION occur
469 			 */
470 			if (ss->wrc > 0) {
471 				sel_stat[chan] = SEL_RSLD;
472 			} else {
473 				/*
474 				 * Ghost RESELECTION ???
475 				 */
476 				int_stat1 &= ~R2_RSL;
477 			}
478 		}
479 		if (int_stat1 & R2_ARBF) {
480 			/*
481 			 * ARBITRATION fault
482 			 */
483 			int_stat1 &= ~R2_ARBF;
484 			sel_stat[chan] = SEL_ARBF;
485 		}
486 		if (int_stat1 & R2_STO) {
487 			/*
488 			 * SELECTION timeout
489 			 */
490 			int_stat1 &= ~R2_STO;
491 			if ((int_stat2&(R3_PHC|R3_RMSG)) != (R3_PHC|R3_RMSG)) {
492 				ss->ipc = chan;
493 				ss->ip = &chan_stat[chan];
494 				sel_stat[chan] = SEL_TIMEOUT;
495 				chan_stat[chan].sc->sc_istatus
496 					= INST_EP|INST_TO;
497 				release_wb();
498 			}
499 		}
500 
501 		/*
502 		 *	SELECTION command done
503 		 */
504 		switch (sel_stat[chan]) {
505 
506 		case SEL_START:
507 			if ((int_stat2 & R3_FNC) == 0)
508 				break;
509 			/*
510 			 * SELECTION success
511 			 */
512 			sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE;
513 			ss->ipc = chan;
514 			ss->ip = &chan_stat[chan];
515 			ss->ip->sc->sc_istatus |= INST_IP;
516 			ss->dma_stat = OFF;
517 			pad_start = 0;
518 			sel_stat[chan] = SEL_SUCCESS;
519 			release_wb();
520 #ifndef NOT_SUPPORT_SYNCTR
521 			sc_syncr = sync_tr[chan];
522 			DMAC_WAIT0;
523 #endif
524 			DMAC_WAIT0;
525 			break;
526 
527 		case SEL_TIMEOUT:
528 			/*
529 			 * SELECTION time out
530 			 */
531 			sc_discon();
532 			goto scintr_exit;
533 
534 		/* case SEL_RSLD: */
535 		/* case SEL_ARBF: */
536 		default:
537 			/*
538 			 * SELECTION failed
539 			 */
540 			sel_stat[chan] = SEL_WAIT;
541 			break;
542 		}
543 		if ((int_stat1 & R2_RSL) == 0)
544 			int_stat2 &= ~R3_FNC;
545 	}
546 
547 	if (ss->ip != NULL) {
548 		/*
549 		 * check In Process channel's request
550 		 */
551 		if (ss->dma_stat != OFF) {
552 			/*
553 			 * adjust pointer & counter
554 			 */
555 			adjust_transfer(ss->ip);
556 		}
557 		if (int_stat2 & R3_SPE) {
558 			register int VOLATILE statr;
559 			register int VOLATILE cmonr;
560 
561 			statr = sc_statr;
562 			DMAC_WAIT0;
563 			cmonr = sc_cmonr;
564 			int_stat2 &= ~R3_SPE;
565 			perr_flag[ss->ip->chan_num] = 1;
566 		}
567 	}
568 
569 	if (int_stat2 & R3_DCNT) {
570 		/*
571 		 * Bus Free
572 		 */
573 		sc_discon();
574 		int_stat2 &= ~R3_DCNT;
575 	}
576 
577 	if ((ss->ipc >= 0) && (sel_stat[ss->ipc] == SEL_RSL_WAIT)) {
578 		sel_stat[ss->ipc] = SEL_RSLD;
579 		ss->ipc = -1;
580 		int_stat1 |= R2_RSL;
581 	}
582 	if (int_stat1 & R2_RSL) {
583 		/*
584 		 * Reselection
585 		 */
586 		sc_resel();
587 		int_stat1 &= ~R2_RSL;
588 		if (sel_stat[ss->ipc] == SEL_RSL_WAIT)
589 			goto scintr_exit;
590 	}
591 
592 
593 	if ((ss->ipc >= 0) && (ss->ipc != SC_OWNID) &&
594 	    (sel_stat[ss->ipc] == SEL_SUCCESS)) {
595 		if (int_stat2 & R3_PHC) {
596 			/*
597 			 * Phase change
598 			 */
599 			int_stat2 &= ~(R3_PHC|R3_RMSG);
600 			sc_pmatch();
601 		} else if (int_stat2 & R3_RMSG) {
602 			/*
603 			 * message Phase
604 			 */
605 			if (min_flag > 0) {
606 				int_stat2 &= ~(R3_PHC|R3_RMSG);
607 				sc_pmatch();
608 			}
609 		}
610 		else if (ss->dma_stat != OFF) {
611 			dummy = sc_cmonr;
612 			DMAC_WAIT0;
613 			if ((dummy & (R4_MMSG|R4_MCD|R4_MREQ)) == R4_MREQ) {
614 				/*
615 				 * still DATA transfer phase
616 				 */
617 				sc_dio_pad(ss->ip);
618 			}
619 		}
620 		else if (ss->ip->comflg == CF_SEND) {
621 			dummy = sc_cmonr;
622 			DMAC_WAIT0;
623 			if ((dummy & SC_PMASK) == COM_OUT) {
624 				/*
625 				 * command out phase
626 				 */
627 				sc_cout(ss->ip);
628 			}
629 		}
630 	} else {
631 		if (int_stat2 & (R3_PHC|R3_RMSG))
632 			goto scintr_exit;
633 	}
634 
635 	if ((int_stat1 & (R2_STO|R2_RSL|R2_ARBF))
636 	    || (int_stat2 & (R3_DCNT|R3_SRST|R3_PHC|R3_SPE))) {
637 		/*
638 		 * still remain intrq
639 		 */
640 		goto scintr_loop;
641 	}
642 
643 scintr_exit:
644 	return (1);
645 }
646 
647 /*
648  *	SCSI bus reset routine
649  *		scsi_hardreset() is occered a reset interrupt.
650  *		And call scsi_softreset().
651  */
652 scsi_hardreset()
653 {
654 	register int s;
655 #ifdef DMAC_MAP_INIT
656 	register int i;
657 #endif
658 
659 	s = splscsi();
660 
661 	scsi_chipreset();
662 	DMAC_WAIT0;
663 	int_stat1 = 0;
664 	int_stat2 = 0;
665 	SET_CMD(SCMD_AST_RST);			/* assert RST signal */
666 
667 #ifdef DMAC_MAP_INIT
668 	if (dmac_map_init == 0) {
669 		dmac_map_init++;
670 		for (i = 0; i < NDMACMAP; i++) {
671 # if defined(mips) && defined(CPU_SINGLE)
672 			dmac_gsel = CH_SCSI;
673 			dmac_ctag = (u_char)i;
674 			dmac_cmap = (u_short)0;
675 # endif
676 		}
677 	}
678 #endif
679 	splx(s);
680 }
681 
682 /*
683  * I/O port (sc_ioptr) bit assign
684  *
685  *	Rf_PRT3		-	<reserved>
686  *	Rf_PRT2		-	<reserved>
687  *	Rf_PRT1		out	Floppy Disk Density control
688  *	Rf_PRT0		out	Floppy Disk Eject control
689  */
690 
691 scsi_chipreset()
692 {
693 	register int s;
694 	register int iloop;
695 	register VOLATILE int save_ioptr;
696 	register VOLATILE int dummy;
697 	int s_int1, s_int2;
698 
699 	s = splscsi();
700 
701 #if defined(mips) && defined(CPU_SINGLE)
702 	dmac_gsel = CH_SCSI;
703 	dmac_cwid = 4;				/* initialize DMAC SCSI chan */
704 	*(unsigned VOLATILE char *)PINTEN |= DMA_INTEN;
705 	dma_reset(CH_SCSI);
706 #endif
707 	sc_envir = 0;				/* 1/4 clock */
708 	DMAC_WAIT0;
709 	save_ioptr = sc_ioptr;
710 	DMAC_WAIT0;
711 	last_cmd = SCMD_CHIP_RST;
712 	sc_comr = SCMD_CHIP_RST;		/* reset chip */
713 	DMAC_WAIT;
714 	(void) WAIT_STATR_BITCLR(R0_CIP);
715 	/*
716 	 * SCMD_CHIP_RST command reset all register
717 	 *				except sc_statr<7:6> & sc_cmonr.
718 	 * So, bit R0_MIRQ & R3_FNC will be not set.
719 	 */
720 	sc_idenr = SC_OWNID;
721 	DMAC_WAIT0;
722 
723 	sc_intok1 = Ra_STO|Ra_RSL|Ra_ARBF;
724 	DMAC_WAIT0;
725 	sc_intok2 = Rb_FNC|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG;
726 	DMAC_WAIT0;
727 
728 	sc_ioptr = save_ioptr;
729 	DMAC_WAIT;
730 
731 	sc_moder = Rc_TMSL;			/* RST drive time = 25.5 us */
732 	DMAC_WAIT0;
733 	sc_timer = 0x2;
734 	DMAC_WAIT0;
735 
736 	sc_moder = Rc_SPHI;			/* selection timeout = 252 ms */
737 	DMAC_WAIT0;
738 	sc_timer = SEL_TIMEOUT_VALUE;
739 	DMAC_WAIT0;
740 
741 #ifdef SCSI_1185AQ
742 	if (scsi_1185AQ)
743 		SET_CMD(SCMD_ENB_SEL);		/* enable reselection */
744 #endif
745 
746 	int_stat1 &= ~R2_RSL;			/* ignore RSL inter request */
747 
748 	splx(s);
749 }
750 
751 scsi_softreset()
752 {
753 	register VOLATILE struct sc_chan_stat *cs;
754 	register struct scsi_stat *ss;
755 	register int (*handler)();
756 	register int i;
757 #ifdef mips
758 	extern struct sc_data sc_data[];
759 	register struct sc_data *scdp;
760 #endif
761 
762 	wbq_actf = NULL;
763 	wbq_actl = NULL;
764 	ss = &scsi_stat;
765 	ss->wbc = 0;
766 	ss->wrc = 0;
767 	ss->ip = NULL;
768 	ss->ipc = -1;
769 	ss->dma_stat = OFF;
770 	pad_start = 0;
771 
772 	for (i = 0; i < NTARGET; ++i) {
773 		if (i == SC_OWNID)
774 			continue;
775 		cs = &chan_stat[i];
776 		cs->wb_next = NULL;
777 #ifndef NOT_SUPPORT_SYNCTR
778 		sync_tr[i] = 0;			/* asynchronous mode */
779 #endif
780 		sel_stat[i] = SEL_WAIT;
781 		if (cs->sc != NULL) {
782 			if ((cs->sc->sc_istatus & INST_EP) == 0)
783 				cs->sc->sc_istatus = (INST_EP|INST_HE);
784 			cs->sc = NULL;
785 #ifdef mips
786 			scdp = &sc_data[cs->chan_num];
787 			MachFlushDCache(scdp->scd_scaddr, sizeof(struct scsi));
788 
789 			if (MACH_IS_USPACE(scdp->scd_vaddr)) {
790 				panic("scsi_softreset: user address is not supported");
791 			} else if (MACH_IS_CACHED(scdp->scd_vaddr)) {
792 			    MachFlushDCache(scdp->scd_vaddr, scdp->scd_count);
793 			} else if (MACH_IS_MAPPED(scdp->scd_vaddr)) {
794 #ifdef notyet /* KU:XXX */
795 				clean_k2dcache(scdp->scd_vaddr, scdp->scd_count);
796 #else
797 				MachFlushCache();
798 #endif
799 			}
800 #endif /* mips */
801 			if ((cs->intr_flg == SCSI_INTEN)
802 				    && (handler = scintsw[i].sci_inthandler)) {
803 #ifdef noyet /* KU:XXX */
804 				intrcnt[INTR_SCSI00 + i]++;
805 #endif
806 				(*handler)(scintsw[i].sci_ctlr);
807 			}
808 		}
809 	}
810 }
811 
812 /*
813  *	RESELECTION interrupt service routine
814  *		( RESELECTION phase )
815  */
816 sc_resel()
817 {
818 	register struct sc_chan_stat *cs;
819 	register struct scsi_stat *ss;
820 	register VOLATILE int chan;
821 	register VOLATILE int statr;
822 	register int iloop;
823 
824 	min_flag = 0;
825 	chan = (sc_idenr & R6_SID_MASK) >> SC_TG_SHIFT;
826 
827 	if (chan == SC_OWNID)
828 		return;
829 
830 	statr = sc_statr;
831 	DMAC_WAIT0;
832 	if (statr & R0_CIP) {
833 		if (last_cmd == SCMD_SEL_ATN) {
834 			/*
835 			 * SELECTION command dead lock ?
836 			 *	save interrupt request
837 			 */
838 			while (sc_statr & R0_MIRQ) {
839 				DMAC_WAIT0;
840 				int_stat1 |= sc_intrq1;
841 				DMAC_WAIT0;
842 				int_stat2 |= sc_intrq2;
843 				DMAC_WAIT0;
844 			}
845 			scsi_chipreset();
846 		}
847 	}
848 
849 	cs = &chan_stat[chan];
850 	if (cs->sc == NULL) {
851 		scsi_hardreset();
852 		return;
853 	}
854 	if ((cs->sc->sc_istatus & INST_WR) == 0) {
855 		scsi_hardreset();
856 		return;
857 	}
858 
859 	ss = &scsi_stat;
860 	if (ss->ipc >= 0) {
861 		scsi_hardreset();
862 		return;
863 	}
864 
865 	ss->ip = cs;
866 	ss->ipc = chan;
867 
868 	sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE;
869 	DMAC_WAIT0;
870 
871 	iloop = 0;
872 	while ((int_stat2 & R3_FNC) == 0) {
873 		/*
874 		 * Max 6 usec wait
875 		 */
876 		if (iloop++ > RSL_LOOP_CNT) {
877 			sel_stat[chan] = SEL_RSL_WAIT;
878 			return;
879 		}
880 		GET_INTR(&int_stat1, &int_stat2);
881 	}
882 	int_stat2 &= ~R3_FNC;
883 
884 	sel_stat[chan] = SEL_SUCCESS;
885 
886 	ss->wrc--;
887 	ss->dma_stat = OFF;
888 	pad_start = 0;
889 	cs->sc->sc_istatus |= INST_IP;
890 	cs->sc->sc_istatus &= ~INST_WR;
891 
892 #ifndef NOT_SUPPORT_SYNCTR
893 	sc_syncr = sync_tr[chan];
894 	DMAC_WAIT0;
895 #endif
896 }
897 
898 /*
899  *	DISCONNECT interrupt service routine
900  *		( Target disconnect / job done )
901  */
902 sc_discon()
903 {
904 	register VOLATILE struct sc_chan_stat *cs;
905 	register struct scsi_stat *ss;
906 	register int (*handler)();
907 	register VOLATILE int dummy;
908 #ifdef mips
909 	extern struct sc_data sc_data[];
910 	register struct sc_data *scdp;
911 #endif
912 
913 	/*
914 	 * Signal reflection on BSY is occured.
915 	 *	Not Bus Free Phase, ignore.
916 	 *
917 	 *	But, CXD1185Q reset INIT bit of sc_statr.
918 	 *	So, can't issue Transfer Information command.
919 	 *
920 	 *	What shall we do ?  Bus reset ?
921 	 */
922 	if ((int_stat2 & R3_DCNT) && ((sc_intok2 & Rb_DCNT) == 0))
923 		return;
924 
925 	sc_intok2 = Rb_FNC|Rb_SRST|Rb_PHC|Rb_SPE;
926 	DMAC_WAIT0;
927 
928 	min_flag = 0;
929 	dummy = sc_cmonr;
930 	DMAC_WAIT0;
931 	if (dummy & R4_MATN) {
932 		SET_CMD(SCMD_NGT_ATN);
933 		(void) WAIT_STATR_BITSET(R0_MIRQ);
934 		GET_INTR(&int_stat1, &int_stat2);	/* clear interrupt */
935 	}
936 
937 	if ((int_stat1 & R2_RSL) == 0)
938 		int_stat2 &= ~R3_FNC;
939 
940 	ss = &scsi_stat;
941 	cs = ss->ip;
942 	if ((cs == NULL) || (ss->ipc < 0))
943 		goto sc_discon_exit;
944 
945 	if ((sel_stat[cs->chan_num] != SEL_SUCCESS)
946 			&& (sel_stat[cs->chan_num] != SEL_TIMEOUT))
947 		printf("sc_discon: eh!\n");
948 
949 	/*
950 	 * indicate abnormal terminate
951 	 */
952 	if ((cs->sc->sc_istatus & (INST_EP|INST_WR)) == 0)
953 		cs->sc->sc_istatus |= (INST_EP|INST_PRE|INST_LB);
954 
955 	cs->sc->sc_istatus &= ~INST_IP;
956 	ss->dma_stat = OFF;
957 	pad_start = 0;
958 	ss->ip = NULL;
959 	ss->ipc = -1;
960 
961 	if ((cs->sc->sc_istatus & INST_WR) == 0) {
962 		if (perr_flag[cs->chan_num] > 0)
963 			cs->sc->sc_istatus |= INST_EP|INST_PRE;
964 		cs->sc = NULL;
965 #ifdef mips
966 		scdp = &sc_data[cs->chan_num];
967 		MachFlushDCache(scdp->scd_scaddr, sizeof(struct scsi));
968 
969 		if (MACH_IS_USPACE(scdp->scd_vaddr)) {
970 			panic("sc_discon: user address is not supported");
971 		} else if (MACH_IS_CACHED(scdp->scd_vaddr)) {
972 			MachFlushDCache(scdp->scd_vaddr, scdp->scd_count);
973 		} else if (MACH_IS_MAPPED(scdp->scd_vaddr)) {
974 #ifdef notyet /* KU:XXX */
975 			clean_k2dcache(scdp->scd_vaddr, scdp->scd_count);
976 #else
977 			MachFlushCache();
978 #endif
979 		}
980 #endif /* mips */
981 		if ((cs->intr_flg == SCSI_INTEN)
982 		    && (handler = scintsw[cs->chan_num].sci_inthandler)) {
983 #ifdef notyet /* KU:XXX */
984 			intrcnt[INTR_SCSI00 + cs->chan_num]++;
985 #endif
986 			(*handler)(scintsw[cs->chan_num].sci_ctlr);
987 		}
988 	}
989 
990 sc_discon_exit:
991 	sc_start();
992 }
993 
994 /*
995  *	SCSI phase match interrupt service routine
996  */
997 sc_pmatch()
998 {
999 	register VOLATILE struct sc_chan_stat *cs;
1000 	register VOLATILE int phase;
1001 	register VOLATILE int phase2;
1002 	register VOLATILE int cmonr;
1003 
1004 	int_stat2 &= ~R3_FNC;			/* XXXXXXXX */
1005 
1006 	cs = scsi_stat.ip;
1007 	if (cs == NULL)
1008 		return;
1009 
1010 # if defined(mips) && defined(CPU_SINGLE)
1011 	dma_reset(CH_SCSI);
1012 # endif
1013 	phase = sc_cmonr & SC_PMASK;
1014 	DMAC_WAIT0;
1015 	for (;;) {
1016 		phase2 = phase;
1017 		cmonr = sc_cmonr;
1018 		DMAC_WAIT0;
1019 		phase = cmonr & SC_PMASK;
1020 		if (phase == phase2) {
1021 			if ((phase == DAT_IN) || (phase == DAT_OUT))
1022 				break;
1023 			else if (cmonr & R4_MREQ)
1024 				break;
1025 		}
1026 	}
1027 
1028 
1029 	scsi_stat.dma_stat = OFF;
1030 	pad_start = 0;
1031 
1032 	if (phase == COM_OUT) {
1033 		min_flag = 0;
1034 		if (cs->comflg != CF_SEND)
1035 			cs->comflg = CF_SET;
1036 		sc_cout(cs);
1037 	} else {
1038 		cs->comflg = CF_ENOUGH;
1039 		sc_intok2 &= ~Rb_FNC;
1040 		if (phase == MES_IN) {
1041 			min_flag++;
1042 			sc_min(cs);
1043 		} else {
1044 			min_flag = 0;
1045 
1046 			switch (phase) {
1047 
1048 			case MES_OUT:
1049 				sc_mout(cs);
1050 				break;
1051 
1052 			case DAT_IN:
1053 			case DAT_OUT:
1054 				sc_dio(cs);
1055 				break;
1056 
1057 			case STAT_IN:
1058 				sc_sin(cs);
1059 				break;
1060 
1061 			default:
1062 				printf("SCSI%d: unknown phase\n", cs->chan_num);
1063 				break;
1064 			}
1065 		}
1066 	}
1067 }
1068 
1069 
1070 flush_fifo()
1071 {
1072 	register VOLATILE int dummy;
1073 	VOLATILE int tmp;
1074 	VOLATILE int tmp0;
1075 
1076 	dummy = sc_ffstr;
1077 	DMAC_WAIT0;
1078 	if (dummy & R5_FIFOREM) {
1079 		/*
1080 		 * flush FIFO
1081 		 */
1082 		SET_CMD(SCMD_FLSH_FIFO);
1083 		tmp = 0;
1084 		do {
1085 			do {
1086 				dummy = sc_statr;
1087 				DMAC_WAIT0;
1088 			} while (dummy & R0_CIP);
1089 			GET_INTR(&tmp0, &tmp); /* clear interrupt */
1090 		} while ((tmp & R3_FNC) == 0);
1091 	}
1092 }
1093 
1094 /*
1095  *	SCSI command send routine
1096  */
1097 int
1098 sc_cout(cs)
1099 	register struct sc_chan_stat *cs;
1100 {
1101 	register struct scsi *sc;
1102 	register int iloop;
1103 	register int cdb_bytes;
1104 	register VOLATILE int dummy;
1105 	register VOLATILE int statr;
1106 
1107 	if (cs->comflg == CF_SET) {
1108 		cs->comflg = CF_SEND;
1109 
1110 		flush_fifo();
1111 
1112 		sc = cs->sc;
1113 		switch (sc->sc_opcode & CMD_TYPEMASK) {
1114 		case CMD_T0:
1115 			cdb_bytes = 6;
1116 			break;
1117 
1118 		case CMD_T1:
1119 			cdb_bytes = 10;
1120 			break;
1121 
1122 		case CMD_T5:
1123 			cdb_bytes = 12;
1124 			break;
1125 
1126 		default:
1127 			cdb_bytes = 6;
1128 			sc_intok2 |= Rb_FNC;
1129 			break;
1130 		}
1131 
1132 		/*
1133 		 * set Active pointers
1134 		 */
1135 		act_cmd_pointer = sc->sc_cdb.un_reserved;
1136 		cs->act_trcnt = sc->sc_ctrnscnt;
1137 		cs->act_point = sc->sc_cpoint;
1138 		cs->act_tag = sc->sc_ctag;
1139 		cs->act_offset = sc->sc_coffset;
1140 
1141 	} else {
1142 		cdb_bytes = 1;
1143 		iloop = 0;
1144 		do {
1145 			dummy = sc_cmonr;
1146 			DMAC_WAIT0;
1147 			if ((dummy & SC_PMASK) != COM_OUT)
1148 				return;
1149 			statr = sc_statr;
1150 			DMAC_WAIT0;
1151 			if (statr & R0_MIRQ)
1152 				return;
1153 		} while ((dummy & R4_MREQ) == 0);
1154 		statr = sc_statr;
1155 		DMAC_WAIT0;
1156 		if (statr & R0_MIRQ)
1157 			return;
1158 	}
1159 
1160 
1161 	SET_CNT(cdb_bytes);
1162 	SET_CMD(SCMD_TR_INFO|R0_TRBE);
1163 
1164 	for (iloop = 0; iloop < cdb_bytes; iloop++) {
1165 		do {
1166 			dummy = sc_cmonr;
1167 			DMAC_WAIT0;
1168 			if ((dummy & SC_PMASK) != COM_OUT)
1169 				return;
1170 		} while ((dummy & R4_MREQ) == 0);
1171 		statr = sc_statr;
1172 		DMAC_WAIT0;
1173 		if (statr & R0_MIRQ)
1174 			return;
1175 		sc_datr = *act_cmd_pointer++;
1176 		do {
1177 			dummy = sc_cmonr;
1178 			DMAC_WAIT0;
1179 		} while ((dummy & R4_MACK) != 0);
1180 	}
1181 }
1182 
1183 #define GET_MIN_COUNT	127
1184 
1185 /*
1186  *	SCSI message accept routine
1187  */
1188 sc_min(cs)
1189 	register struct sc_chan_stat *cs;
1190 {
1191 	register struct scsi *sc;
1192 	register struct scsi_stat *ss;
1193 	register VOLATILE int dummy;
1194 
1195 	sc = cs->sc;
1196 	ss = &scsi_stat;
1197 
1198 	sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG;
1199 	DMAC_WAIT0;
1200 
1201 	if (min_flag == 1)
1202 		flush_fifo();
1203 
1204 	dummy = sc_cmonr;
1205 	DMAC_WAIT0;
1206 	if ((dummy & R4_MREQ) == 0) {
1207 		printf("sc_min: !REQ cmonr=%x\n", dummy);
1208 		print_scsi_stat();
1209 		scsi_hardreset();
1210 		return;
1211 	}
1212 
1213     retry_cmd_issue:
1214 	int_stat2 &= ~R3_FNC;
1215 	SET_CMD(SCMD_TR_INFO);
1216 	do {
1217 		do {
1218 			dummy = sc_statr;
1219 			DMAC_WAIT0;
1220 		} while (dummy & R0_CIP);
1221 		GET_INTR(&int_stat1, &int_stat2);	/* clear interrupt */
1222 	} while ((int_stat2 & R3_FNC) == 0);
1223 	int_stat2 &= ~R3_FNC;
1224 
1225 	dummy = sc_ffstr;
1226 	if (dummy & R5_FIE) {
1227 		DMAC_WAIT;
1228 		dummy = sc_ffstr;
1229 		DMAC_WAIT0;
1230 		if (dummy & R5_FIE) {
1231 			dummy = sc_statr;
1232 			DMAC_WAIT0;
1233 			if ((dummy & R0_INIT) == 0) {
1234 				/*
1235 				 * CXD1185 detect BSY false
1236 				 */
1237 				scsi_hardreset();
1238 				return;
1239 			}
1240 		}
1241 	}
1242 	dummy = sc_datr;				/* get message byte */
1243 	DMAC_WAIT0;
1244 
1245 	if (min_cnt[cs->chan_num] == 0) {
1246 		sc->sc_message = sc->sc_identify;
1247 		if (dummy == MSG_EXTND) {
1248 			/* Extended Message */
1249 			min_cnt[cs->chan_num] = GET_MIN_COUNT;
1250 			min_point[cs->chan_num] = sc->sc_param;
1251 			bzero((caddr_t)sc->sc_param, 8);
1252 			*min_point[cs->chan_num]++ = dummy;
1253 		} else {
1254 			switch ((dummy & MSG_IDENT)? MSG_IDENT : dummy) {
1255 
1256 			case MSG_CCOMP:
1257 				sc->sc_istatus |= INST_EP;
1258 				break;
1259 
1260 			case MSG_MREJ:
1261 #ifndef NOT_SUPPORT_SYNCTR
1262 				if (mout_flag[cs->chan_num] == MOUT_SYNC_TR)
1263 					sync_tr[cs->chan_num] = 0;
1264 #endif
1265 				break;
1266 
1267 			case MSG_IDENT:
1268 			case MSG_RDP:
1269 	ss->dma_stat = OFF;
1270 	pad_start = 0;
1271 				cs->comflg = OFF;
1272 				/*
1273 				 * restore the saved value to Active pointers
1274 				 */
1275 				act_cmd_pointer = sc->sc_cdb.un_reserved;
1276 				cs->act_trcnt = sc->sc_ctrnscnt;
1277 				cs->act_point = sc->sc_cpoint;
1278 				cs->act_tag = sc->sc_ctag;
1279 				cs->act_offset = sc->sc_coffset;
1280 				break;
1281 
1282 			case MSG_SDP:
1283 				/*
1284 				 * save Active pointers
1285 				 */
1286 				sc->sc_ctrnscnt = cs->act_trcnt;
1287 				sc->sc_ctag = cs->act_tag;
1288 				sc->sc_coffset = cs->act_offset;
1289 				sc->sc_cpoint = cs->act_point;
1290 				break;
1291 
1292 			case MSG_DCNT:
1293 				sc->sc_istatus |= INST_WR;
1294 				ss->wrc++;
1295 				break;
1296 
1297 			default:
1298 				sc->sc_message = MSG_MREJ;
1299 				SET_CMD(SCMD_AST_ATN);
1300 				printf("SCSI%d:sc_min() Unknown mes=0x%x, \n",
1301 					cs->chan_num, dummy);
1302 			}
1303 		}
1304 	} else {
1305 		*min_point[cs->chan_num]++ = dummy;
1306 		if (min_cnt[cs->chan_num] == GET_MIN_COUNT)
1307 			min_cnt[cs->chan_num] = dummy;
1308 		else
1309 			min_cnt[cs->chan_num]--;
1310 		if (min_cnt[cs->chan_num] <= 0) {
1311 #ifdef ABORT_SYNCTR_MES_FROM_TARGET
1312 			if ((sc->sc_param[2] == 0x01)
1313 			    && (mout_flag[cs->chan_num] == MOUT_SYNC_TR)) {
1314 #else
1315 			if (sc->sc_param[2] == 0x01) { /*}*/
1316 #endif
1317 				register int i;
1318 				/*
1319 				 * receive Synchronous transfer message reply
1320 				 *	calculate transfer period val
1321 				 *	tpm * 4/1000 us = 4/16 * (tpv + 1)
1322 				 */
1323 #define	TPM2TPV(tpm)	(((tpm)*16 + 999) / 1000 - 1)
1324 #ifndef NOT_SUPPORT_SYNCTR
1325 				i = sc->sc_param[3];	/* get tpm */
1326 				i = TPM2TPV(i) << 4;
1327 				if (sc->sc_param[4] == 0)
1328 					sync_tr[cs->chan_num] = 0;
1329 				else
1330 					sync_tr[cs->chan_num] = i | sc->sc_param[4];
1331 #endif /* !NOT_SUPPORT_SYNCTR */
1332 			} else {
1333 				sc->sc_message = MSG_MREJ;
1334 				SET_CMD(SCMD_AST_ATN);	/* assert ATN */
1335 			}
1336 		}
1337 	}
1338 	SET_CMD(SCMD_NGT_ACK);
1339 }
1340 
1341 /*
1342  *	SCSI message send routine
1343  */
1344 int
1345 sc_mout(cs)
1346 	register struct sc_chan_stat *cs;
1347 {
1348 	register struct scsi *sc = cs->sc;
1349 	register u_char *mp;
1350 	register int cnt;
1351 	register int iloop;
1352 	register VOLATILE int dummy;
1353 	VOLATILE int tmp;
1354 	VOLATILE int tmp0;
1355 
1356 	flush_fifo();
1357 
1358 	if (mout_flag[cs->chan_num] == 0) {
1359 		mout_flag[cs->chan_num] = MOUT_IDENTIFY;
1360 		if (sc->sc_message != 0) {
1361 			sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG;
1362 			DMAC_WAIT0;
1363 			if ((sc->sc_message == MSG_EXTND)
1364 					&& (sc->sc_param[2] == 0x01)) {
1365 				cnt = 5;
1366 				mp = sc->sc_param;
1367 				sc->sc_param[3] = MIN_TP;
1368 				if (sc->sc_param[4] > MAX_OFFSET_BYTES)
1369 					sc->sc_param[4] = MAX_OFFSET_BYTES;
1370 				mout_flag[cs->chan_num] = MOUT_SYNC_TR;
1371 			} else {
1372 				cnt = 1;
1373 				mp = &sc->sc_message;
1374 			}
1375 
1376 			SET_CNT(cnt);
1377 			SET_CMD(SCMD_TR_INFO|R0_TRBE);
1378 			sc_datr = sc->sc_identify;
1379 			DMAC_WAIT0;
1380 			for (iloop = 1; iloop < cnt; iloop++) {
1381 				sc_datr = *mp++;
1382 				DMAC_WAIT;
1383 			}
1384 			do {
1385 				dummy = sc_cmonr;
1386 				DMAC_WAIT0;
1387 				if ((dummy & R4_MBSY) == 0)
1388 					return;
1389 				dummy = sc_statr;
1390 				DMAC_WAIT0;
1391 			} while (dummy & R0_CIP);
1392 
1393 			tmp = 0;
1394 			GET_INTR(&tmp0, &tmp);		/* clear interrupt */
1395 			if ((tmp & R3_FNC) == 0) {
1396 				(void) WAIT_STATR_BITSET(R0_MIRQ);
1397 				GET_INTR(&tmp0, &tmp);	/* clear interrupt */
1398 			}
1399 
1400 			do {
1401 				dummy = sc_cmonr;
1402 				DMAC_WAIT0;
1403 				if ((dummy & R4_MBSY) == 0)
1404 					return;
1405 			} while ((dummy & R4_MREQ) == 0);
1406 			SET_CMD(SCMD_NGT_ATN);
1407 			(void) WAIT_STATR_BITCLR(R0_CIP);
1408 			GET_INTR(&tmp0, &tmp);		/* clear interrupt */
1409 
1410 			dummy = sc_cmonr;
1411 			DMAC_WAIT0;
1412 			if ((dummy & R4_MREQ) == 0) {
1413 				printf("sc_mout: !REQ cmonr=%x\n", dummy);
1414 				print_scsi_stat();
1415 				scsi_hardreset();
1416 				return;
1417 			}
1418 
1419 			SET_CMD(SCMD_TR_INFO);
1420 			sc_datr = *mp++;
1421 			DMAC_WAIT0;
1422 		} else {
1423 			dummy = sc_cmonr;
1424 			DMAC_WAIT0;
1425 			if (dummy & R4_MATN) {
1426 				SET_CMD(SCMD_NGT_ATN);
1427 				(void) WAIT_STATR_BITCLR(R0_CIP);
1428 				GET_INTR(&tmp0, &tmp);	/* clear interrupt */
1429 			}
1430 
1431 			iloop = 0;
1432 			do {
1433 				dummy = sc_cmonr;
1434 				DMAC_WAIT0;
1435 				if (iloop++ > CHECK_LOOP_CNT)
1436 					break;
1437 			} while ((dummy & R4_MREQ) == 0);
1438 			SET_CMD(SCMD_TR_INFO);
1439 			sc_datr = sc->sc_identify;
1440 			DMAC_WAIT0;
1441 		}
1442 	} else {
1443 		dummy = sc_cmonr;
1444 		DMAC_WAIT0;
1445 		if (dummy & R4_MATN) {
1446 			SET_CMD(SCMD_NGT_ATN);
1447 			(void) WAIT_STATR_BITCLR(R0_CIP);
1448 			GET_INTR(&tmp0, &tmp);		/* clear interrupt */
1449 		}
1450 
1451 		dummy = sc_cmonr;
1452 		DMAC_WAIT0;
1453 		if ((dummy & R4_MREQ) == 0) {
1454 			printf("sc_mout: !REQ cmonr=%x\n", dummy);
1455 			print_scsi_stat();
1456 			scsi_hardreset();
1457 			return;
1458 		}
1459 
1460 		SET_CMD(SCMD_TR_INFO);
1461 		sc_datr = sc->sc_message;
1462 		DMAC_WAIT0;
1463 	}
1464 }
1465 
1466 /*
1467  *	SCSI status accept routine
1468  */
1469 sc_sin(cs)
1470 	register VOLATILE struct sc_chan_stat *cs;
1471 {
1472 	register VOLATILE int dummy;
1473 	register int iloop;
1474 
1475 	flush_fifo();
1476 
1477 	dummy = sc_cmonr;
1478 	DMAC_WAIT0;
1479 	if ((dummy & R4_MREQ) == 0) {
1480 		printf("sc_sin: !REQ cmonr=%x\n", dummy);
1481 		print_scsi_stat();
1482 		scsi_hardreset();
1483 		return;
1484 	}
1485 
1486 	sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG;
1487 	DMAC_WAIT0;
1488 
1489 	SET_CMD(SCMD_TR_INFO);
1490 
1491 	(void) WAIT_STATR_BITCLR(R0_CIP);
1492 
1493 	int_stat2 &= ~R3_FNC;
1494 	iloop = 0;
1495 	do {
1496 		if (iloop++ > CHECK_LOOP_CNT)
1497 			break;
1498 		GET_INTR(&int_stat1, &int_stat2);	/* clear interrupt */
1499 	} while ((int_stat2 & R3_FNC) == 0);
1500 	int_stat2 &= ~R3_FNC;
1501 
1502 	cs->sc->sc_tstatus = sc_datr;		/* get status byte */
1503 	DMAC_WAIT0;
1504 }
1505 
1506 /*
1507  *	SCSI data in/out routine
1508  */
1509 sc_dio(cs)
1510 	register VOLATILE struct sc_chan_stat *cs;
1511 {
1512 	register VOLATILE struct scsi *sc;
1513 	register struct scsi_stat *ss;
1514 	register int i;
1515 	register int pages;
1516 	register u_int tag;
1517 	register u_int pfn;
1518 	VOLATILE int phase;
1519 
1520 	sc = cs->sc;
1521 	ss = &scsi_stat;
1522 
1523 	sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE;
1524 	DMAC_WAIT0;
1525 
1526 	if (cs->act_trcnt <= 0) {
1527 		sc_dio_pad(cs);
1528 		return;
1529 	}
1530 
1531 	switch (sc->sc_opcode) {
1532 
1533 	case SCOP_READ:
1534 	case SCOP_WRITE:
1535 	case SCOP_EREAD:
1536 	case SCOP_EWRITE:
1537 		i = (cs->act_trcnt + sc->sc_bytesec -1) / sc->sc_bytesec;
1538 		i *= sc->sc_bytesec;
1539 		break;
1540 
1541 	default:
1542 		i = cs->act_trcnt;
1543 		break;
1544 	}
1545 
1546 	SET_CNT(i);
1547 	pad_cnt[cs->chan_num] = i - cs->act_trcnt;
1548 
1549 	phase = sc_cmonr & SC_PMASK;
1550 	DMAC_WAIT0;
1551 	if (phase == DAT_IN) {
1552 		if (sc_syncr == OFF) {
1553 			DMAC_WAIT0;
1554 			flush_fifo();
1555 		}
1556 	}
1557 
1558 #if defined(mips) && defined(CPU_SINGLE)
1559 	SET_CMD(SCMD_TR_INFO|R0_DMA|R0_TRBE);
1560 #endif
1561 
1562 #if defined(mips) && defined(CPU_SINGLE)
1563 	dmac_gsel = CH_SCSI;
1564 	dmac_ctrcl = (u_char)(cs->act_trcnt & 0xff);
1565 	dmac_ctrcm = (u_char)((cs->act_trcnt >> 8) & 0xff);
1566 	dmac_ctrch = (u_char)((cs->act_trcnt >> 16) & 0x0f);
1567 	dmac_cofsh = (u_char)((cs->act_offset >> 8) & 0xf);
1568 	dmac_cofsl = (u_char)(cs->act_offset & 0xff);
1569 #endif
1570 	tag = 0;
1571 
1572 	if (sc->sc_map && (sc->sc_map->mp_pages > 0)) {
1573 		/*
1574 		 * Set DMAC map entry from map table
1575 		 */
1576 		pages = sc->sc_map->mp_pages;
1577 		for (i = cs->act_tag; i < pages; i++) {
1578 			if ((pfn = sc->sc_map->mp_addr[i]) == 0)
1579 				panic("SCSI:sc_dma() zero entry");
1580 #if defined(mips) && defined(CPU_SINGLE)
1581 			dmac_gsel = CH_SCSI;
1582 			dmac_ctag = (u_char)tag++;
1583 			dmac_cmap = (u_short)pfn;
1584 #endif
1585 		}
1586 #ifdef MAP_OVER_ACCESS
1587 # if defined(mips) && defined(CPU_SINGLE)
1588 		dmac_gsel = CH_SCSI;
1589 		dmac_ctag = (u_char)tag++;
1590 		dmac_cmap = (u_short)pfn;
1591 # endif
1592 #endif
1593 	} else {
1594 		/*
1595 		 * Set DMAC map entry from logical address
1596 		 */
1597 		pfn = (u_int)vtophys(cs->act_point) >> PGSHIFT;
1598 		pages = (cs->act_trcnt >> PGSHIFT) + 2;
1599 		for (i = 0; i < pages; i++) {
1600 #if defined(mips) && defined(CPU_SINGLE)
1601 			dmac_gsel = CH_SCSI;
1602 			dmac_ctag = (u_char)tag++;
1603 			dmac_cmap = (u_short)pfn + i;
1604 #endif
1605 		}
1606 	}
1607 
1608 #if defined(mips) && defined(CPU_SINGLE)
1609 	dmac_gsel = CH_SCSI;
1610 	dmac_ctag = 0;
1611 #endif
1612 
1613 	if (phase == DAT_IN) {
1614 		ss->dma_stat = SC_DMAC_RD;
1615 #if defined(mips) && defined(CPU_SINGLE)
1616 		/*
1617 		 * auto pad flag is always on
1618 		 */
1619 		dmac_gsel = CH_SCSI;
1620 		dmac_cctl = DM_MODE|DM_APAD;
1621 		DMAC_WAIT;
1622 		dmac_cctl = DM_MODE|DM_APAD|DM_ENABLE;
1623 		DMAC_WAIT0;
1624 #endif
1625 	}
1626 	else if (phase == DAT_OUT) {
1627 		ss->dma_stat = SC_DMAC_WR;
1628 #if defined(mips) && defined(CPU_SINGLE)
1629 		dmac_gsel = CH_SCSI;
1630 		dmac_cctl = DM_APAD;
1631 		DMAC_WAIT;
1632 		dmac_cctl = DM_APAD|DM_ENABLE;
1633 		DMAC_WAIT0;
1634 #endif
1635 						/* DMAC start on mem->I/O */
1636 	}
1637 }
1638 
1639 #define MAX_TR_CNT24	((1 << 24) -1)
1640 sc_dio_pad(cs)
1641 	register VOLATILE struct sc_chan_stat *cs;
1642 {
1643 	register VOLATILE int phase;
1644 	register int dummy;
1645 
1646 	if (cs->act_trcnt >= 0)
1647 		return;
1648 	pad_start = 1;
1649 
1650 	SET_CNT(MAX_TR_CNT24);
1651 	SET_CMD(SCMD_TR_PAD|R0_TRBE);
1652 	dummy = sc_cmonr & SC_PMASK;
1653 	DMAC_WAIT0;
1654 	if (dummy == DAT_IN)
1655 		dummy = sc_datr;		/* get data */
1656 	else
1657 		sc_datr = 0;			/* send data */
1658 }
1659 
1660 print_scsi_stat()
1661 {
1662 	register struct scsi_stat *ss;
1663 	register VOLATILE int i;
1664 	int dummy;
1665 
1666 	ss = &scsi_stat;
1667 	printf("ipc=%d wrc=%d wbc=%d\n", ss->ipc, ss->wrc, ss->wbc);
1668 }
1669 
1670 /*
1671  *	return 0 if it was done.  Or retun TRUE if it is busy.
1672  */
1673 sc_busy(chan)
1674 	register int chan;
1675 {
1676 	return ((int)chan_stat[chan].sc);
1677 }
1678 
1679 
1680 /*
1681  *	append channel into Waiting Bus_free queue
1682  */
1683 append_wb(cs)
1684 	register VOLATILE struct sc_chan_stat *cs;
1685 {
1686 	register int s;
1687 
1688 	s = splclock();			/* inhibit process switch */
1689 	if (wbq_actf == NULL)
1690 		wbq_actf = cs;
1691 	else
1692 		wbq_actl->wb_next = cs;
1693 	wbq_actl = cs;
1694 	cs->sc->sc_istatus = INST_WAIT;
1695 	scsi_stat.wbc++;
1696 	splx(s);
1697 }
1698 
1699 /*
1700  *	get channel from Waiting Bus_free queue
1701  */
1702 get_wb_chan()
1703 {
1704 	register int s;
1705 	register int chan;
1706 
1707 	s = splclock();			/* inhibit process switch */
1708 	if (wbq_actf == NULL) {
1709 		chan = -1;
1710 	} else {
1711 		chan = wbq_actf->chan_num;
1712 		if ((chan < 0) || (chan >= NTARGET) || (chan == SC_OWNID))
1713 			chan = -1;
1714 	}
1715 	splx(s);
1716 	return (chan);
1717 }
1718 
1719 /*
1720  *	release channel from Waiting Bus_free queue
1721  */
1722 release_wb()
1723 {
1724 	register VOLATILE struct sc_chan_stat *cs;
1725 	register int s;
1726 	int error;
1727 
1728 	s = splclock();			/* inhibit process switch */
1729 	error = 0;
1730 	if (wbq_actf == NULL) {
1731 		error = -1;
1732 	} else {
1733 		cs = wbq_actf;
1734 		wbq_actf = cs->wb_next;
1735 		cs->wb_next = NULL;
1736 		if (wbq_actl == cs)
1737 			wbq_actl = NULL;
1738 		cs->sc->sc_istatus &= ~INST_WAIT;
1739 		scsi_stat.wbc--;
1740 	}
1741 	splx(s);
1742 	return (error);
1743 }
1744 
1745 adjust_transfer(cs)
1746 	register struct sc_chan_stat *cs;
1747 {
1748 	register struct scsi *sc;
1749 	register struct scsi_stat *ss;
1750 	register VOLATILE u_int remain_cnt;
1751 	register u_int offset;
1752 	u_int sent_byte;
1753 
1754 	sc = cs->sc;
1755 	ss = &scsi_stat;
1756 
1757 	if (pad_start) {
1758 		pad_start = 0;
1759 		remain_cnt = 0;
1760 	} else {
1761 # if defined(mips) && defined(CPU_SINGLE)
1762 		remain_cnt = GET_CNT();
1763 		remain_cnt -= pad_cnt[cs->chan_num];
1764 		if (ss->dma_stat == SC_DMAC_WR) {
1765 			/*
1766 			 * adjust counter in the FIFO
1767 			 */
1768 			remain_cnt += sc_ffstr & R5_FIFOREM;
1769 		}
1770 # endif
1771 	}
1772 
1773 	sent_byte = sc->sc_ctrnscnt - remain_cnt;
1774 	cs->act_trcnt = remain_cnt;
1775 
1776 	offset = sc->sc_coffset + sent_byte;
1777 	cs->act_tag += (offset >> PGSHIFT);
1778 	cs->act_offset = offset & PGOFSET;
1779 	if ((sc->sc_map == NULL) || (sc->sc_map->mp_pages <= 0))
1780 		cs->act_point += sent_byte;
1781 }
1782