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