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