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