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