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