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