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