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