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