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