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