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