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