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