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