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