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