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