1 /* $NetBSD: scsi_1185.c,v 1.20 2011/02/20 07:56:31 matt 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.20 2011/02/20 07:56:31 matt 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 DMAC_WAIT0; 572 cmonr = sc_cmonr; 573 sc->int_stat2 &= ~R3_SPE; 574 sc->perr_flag[sc->ip->chan_num] = 1; 575 } 576 } 577 578 if (sc->int_stat2 & R3_DCNT) { 579 /* 580 * Bus Free 581 */ 582 sc_discon(sc); 583 sc->int_stat2 &= ~R3_DCNT; 584 } 585 586 if ((sc->ipc >= 0) && (sc->sel_stat[sc->ipc] == SEL_RSL_WAIT)) { 587 sc->sel_stat[sc->ipc] = SEL_RSLD; 588 sc->ipc = -1; 589 sc->int_stat1 |= R2_RSL; 590 } 591 if (sc->int_stat1 & R2_RSL) { 592 /* 593 * Reselection 594 */ 595 sc_resel(sc); 596 sc->int_stat1 &= ~R2_RSL; 597 if (sc->sel_stat[sc->ipc] == SEL_RSL_WAIT) 598 goto scintr_exit; 599 } 600 601 602 if ((sc->ipc >= 0) && (sc->ipc != SC_OWNID) && 603 (sc->sel_stat[sc->ipc] == SEL_SUCCESS)) { 604 if (sc->int_stat2 & R3_PHC) { 605 /* 606 * Phase change 607 */ 608 sc->int_stat2 &= ~(R3_PHC|R3_RMSG); 609 sc_pmatch(sc); 610 } else if (sc->int_stat2 & R3_RMSG) { 611 /* 612 * message Phase 613 */ 614 if (sc->min_flag > 0) { 615 sc->int_stat2 &= ~(R3_PHC|R3_RMSG); 616 sc_pmatch(sc); 617 } 618 } 619 else if (sc->dma_stat != OFF) { 620 dummy = sc_cmonr; 621 DMAC_WAIT0; 622 if ((dummy & (R4_MMSG|R4_MCD|R4_MREQ)) == R4_MREQ) { 623 /* 624 * still DATA transfer phase 625 */ 626 sc_dio_pad(sc, sc->ip); 627 } 628 } 629 else if (sc->ip->comflg == CF_SEND) { 630 dummy = sc_cmonr; 631 DMAC_WAIT0; 632 if ((dummy & SC_PMASK) == COM_OUT) { 633 /* 634 * command out phase 635 */ 636 sc_cout(sc, sc->ip); 637 } 638 } 639 } else { 640 if (sc->int_stat2 & (R3_PHC|R3_RMSG)) 641 goto scintr_exit; 642 } 643 644 if ((sc->int_stat1 & (R2_STO|R2_RSL|R2_ARBF)) 645 || (sc->int_stat2 & (R3_DCNT|R3_SRST|R3_PHC|R3_SPE))) { 646 /* 647 * still remain intrq 648 */ 649 goto scintr_loop; 650 } 651 652 scintr_exit: 653 return 1; 654 } 655 656 /* 657 * SCSI bus reset routine 658 * scsi_hardreset() is occered a reset interrupt. 659 * And call scsi_softreset(). 660 */ 661 void 662 scsi_hardreset(void) 663 { 664 int s; 665 #ifdef DMAC_MAP_INIT 666 int i; 667 #endif 668 struct sc_softc *sc; 669 670 sc = device_lookup_private(&sc_cd, 0); /* XXX */ 671 s = splscsi(); 672 673 scsi_chipreset(sc); 674 DMAC_WAIT0; 675 sc->int_stat1 = 0; 676 sc->int_stat2 = 0; 677 SET_CMD(sc, SCMD_AST_RST); /* assert RST signal */ 678 679 #ifdef DMAC_MAP_INIT 680 if (dmac_map_init == 0) { 681 dmac_map_init++; 682 for (i = 0; i < NDMACMAP; i++) { 683 # if defined(__mips__) && defined(CPU_SINGLE) 684 dmac_gsel = CH_SCSI; 685 dmac_ctag = (uint8_t)i; 686 dmac_cmap = (uint16_t)0; 687 # endif 688 } 689 } 690 #endif 691 /*cxd1185_init();*/ 692 splx(s); 693 } 694 695 /* 696 * I/O port (sc_ioptr) bit assign 697 * 698 * Rf_PRT3 - <reserved> 699 * Rf_PRT2 - <reserved> 700 * Rf_PRT1 out Floppy Disk Density control 701 * Rf_PRT0 out Floppy Disk Eject control 702 */ 703 704 void 705 scsi_chipreset(struct sc_softc *sc) 706 { 707 int s; 708 uint8_t save_ioptr; 709 710 s = splscsi(); 711 712 #if defined(__mips__) && defined(CPU_SINGLE) 713 dmac_gsel = CH_SCSI; 714 dmac_cwid = 4; /* initialize DMAC SCSI chan */ 715 *(volatile uint8_t *)PINTEN |= DMA_INTEN; 716 dma_reset(CH_SCSI); 717 #endif 718 sc_envir = 0; /* 1/4 clock */ 719 DMAC_WAIT0; 720 save_ioptr = sc_ioptr; 721 DMAC_WAIT0; 722 sc->lastcmd = SCMD_CHIP_RST; 723 sc_comr = SCMD_CHIP_RST; /* reset chip */ 724 DMAC_WAIT; 725 (void)WAIT_STATR_BITCLR(R0_CIP); 726 /* 727 * SCMD_CHIP_RST command reset all register 728 * except sc_statr<7:6> & sc_cmonr. 729 * So, bit R0_MIRQ & R3_FNC will be not set. 730 */ 731 sc_idenr = SC_OWNID; 732 DMAC_WAIT0; 733 734 sc_intok1 = Ra_STO|Ra_RSL|Ra_ARBF; 735 DMAC_WAIT0; 736 sc_intok2 = Rb_FNC|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG; 737 DMAC_WAIT0; 738 739 sc_ioptr = save_ioptr; 740 DMAC_WAIT; 741 742 sc_moder = Rc_TMSL; /* RST drive time = 25.5 us */ 743 DMAC_WAIT0; 744 sc_timer = 0x2; 745 DMAC_WAIT0; 746 747 sc_moder = Rc_SPHI; /* selection timeout = 252 ms */ 748 DMAC_WAIT0; 749 sc_timer = SEL_TIMEOUT_VALUE; 750 DMAC_WAIT0; 751 752 #ifdef SCSI_1185AQ 753 if (sc->scsi_1185AQ) 754 SET_CMD(sc, SCMD_ENB_SEL); /* enable reselection */ 755 #endif 756 757 sc->int_stat1 &= ~R2_RSL; /* ignore RSL inter request */ 758 759 splx(s); 760 } 761 762 void 763 scsi_softreset(struct sc_softc *sc) 764 { 765 struct sc_chan_stat *cs; 766 int i; 767 /* int (*handler)(); */ 768 769 sc->wbq_actf = NULL; 770 sc->wbq_actl = NULL; 771 sc->wbc = 0; 772 sc->wrc = 0; 773 sc->ip = NULL; 774 sc->ipc = -1; 775 sc->dma_stat = OFF; 776 sc->pad_start = 0; 777 778 for (i = 0; i < NTARGET; ++i) { 779 if (i == SC_OWNID) 780 continue; 781 cs = &sc->chan_stat[i]; 782 cs->wb_next = NULL; 783 #ifndef NOT_SUPPORT_SYNCTR 784 sc->sync_tr[i] = 0; /* asynchronous mode */ 785 #endif 786 sc->sel_stat[i] = SEL_WAIT; 787 if (cs->scb != NULL) { 788 struct sc_scb *scb = cs->scb; 789 790 if ((cs->scb->istatus & INST_EP) == 0) 791 cs->scb->istatus = (INST_EP|INST_HE); 792 cs->scb = NULL; 793 #ifdef __mips__ 794 clean_k2dcache(scb); 795 #endif 796 if (cs->intr_flg == SCSI_INTEN) { 797 intrcnt[SCSI_INTR]++; 798 #if 0 799 handler = scintsw[i].sci_inthandler; 800 if (handler) 801 (*handler)(scintsw[i].sci_ctlr); 802 #endif 803 } 804 sc_done(scb); 805 } 806 } 807 } 808 809 /* 810 * RESELECTION interrupt service routine 811 * ( RESELECTION phase ) 812 */ 813 void 814 sc_resel(struct sc_softc *sc) 815 { 816 struct sc_chan_stat *cs; 817 uint8_t chan; 818 uint8_t statr; 819 int iloop; 820 821 sc->min_flag = 0; 822 chan = (sc_idenr & R6_SID_MASK) >> SC_TG_SHIFT; 823 824 if (chan == SC_OWNID) 825 return; 826 827 statr = sc_statr; 828 DMAC_WAIT0; 829 if (statr & R0_CIP) { 830 if (sc->lastcmd == SCMD_SEL_ATN) { 831 /* 832 * SELECTION command dead lock ? 833 * save interrupt request 834 */ 835 while (sc_statr & R0_MIRQ) { 836 DMAC_WAIT0; 837 sc->int_stat1 |= sc_intrq1; 838 DMAC_WAIT0; 839 sc->int_stat2 |= sc_intrq2; 840 DMAC_WAIT0; 841 } 842 scsi_chipreset(sc); 843 } 844 } 845 846 cs = &sc->chan_stat[chan]; 847 if (cs->scb == NULL) { 848 scsi_hardreset(); 849 return; 850 } 851 if ((cs->scb->istatus & INST_WR) == 0) { 852 scsi_hardreset(); 853 return; 854 } 855 856 if (sc->ipc >= 0) { 857 scsi_hardreset(); 858 return; 859 } 860 861 sc->ip = cs; 862 sc->ipc = chan; 863 864 sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE; 865 DMAC_WAIT0; 866 867 iloop = 0; 868 while ((sc->int_stat2 & R3_FNC) == 0) { 869 /* 870 * Max 6 usec wait 871 */ 872 if (iloop++ > RSL_LOOP_CNT) { 873 sc->sel_stat[chan] = SEL_RSL_WAIT; 874 return; 875 } 876 GET_INTR(&sc->int_stat1, &sc->int_stat2); 877 } 878 sc->int_stat2 &= ~R3_FNC; 879 880 sc->sel_stat[chan] = SEL_SUCCESS; 881 882 sc->wrc--; 883 sc->dma_stat = OFF; 884 sc->pad_start = 0; 885 cs->scb->istatus |= INST_IP; 886 cs->scb->istatus &= ~INST_WR; 887 888 #ifndef NOT_SUPPORT_SYNCTR 889 sc_syncr = sc->sync_tr[chan]; 890 DMAC_WAIT0; 891 #endif 892 } 893 894 /* 895 * DISCONNECT interrupt service routine 896 * ( Target disconnect / job done ) 897 */ 898 void 899 sc_discon(struct sc_softc *sc) 900 { 901 struct sc_chan_stat *cs; 902 /* int (*handler)(); */ 903 uint8_t dummy; 904 905 /* 906 * Signal reflection on BSY has occurred. 907 * Not Bus Free Phase, ignore. 908 * 909 * But, CXD1185Q reset INIT bit of sc_statr. 910 * So, can't issue Transfer Information command. 911 * 912 * What shall we do ? Bus reset ? 913 */ 914 if ((sc->int_stat2 & R3_DCNT) && ((sc_intok2 & Rb_DCNT) == 0)) 915 return; 916 917 sc_intok2 = Rb_FNC|Rb_SRST|Rb_PHC|Rb_SPE; 918 DMAC_WAIT0; 919 920 sc->min_flag = 0; 921 dummy = sc_cmonr; 922 DMAC_WAIT0; 923 if (dummy & R4_MATN) { 924 SET_CMD(sc, SCMD_NGT_ATN); 925 (void) WAIT_STATR_BITSET(R0_MIRQ); 926 GET_INTR(&sc->int_stat1, &sc->int_stat2); /* clear interrupt */ 927 } 928 929 if ((sc->int_stat1 & R2_RSL) == 0) 930 sc->int_stat2 &= ~R3_FNC; 931 932 cs = sc->ip; 933 if ((cs == NULL) || (sc->ipc < 0)) 934 goto sc_discon_exit; 935 936 if ((sc->sel_stat[cs->chan_num] != SEL_SUCCESS) 937 && (sc->sel_stat[cs->chan_num] != SEL_TIMEOUT)) 938 printf("%s: eh!\n", __func__); 939 940 /* 941 * indicate abnormal terminate 942 */ 943 if ((cs->scb->istatus & (INST_EP|INST_WR)) == 0) 944 cs->scb->istatus |= (INST_EP|INST_PRE|INST_LB); 945 946 cs->scb->istatus &= ~INST_IP; 947 sc->dma_stat = OFF; 948 sc->pad_start = 0; 949 sc->ip = NULL; 950 sc->ipc = -1; 951 952 if ((cs->scb->istatus & INST_WR) == 0) { 953 struct sc_scb *scb = cs->scb; 954 955 if (sc->perr_flag[cs->chan_num] > 0) 956 cs->scb->istatus |= INST_EP|INST_PRE; 957 cs->scb = NULL; 958 #ifdef __mips__ 959 clean_k2dcache(scb); 960 #endif 961 if (cs->intr_flg == SCSI_INTEN) { 962 intrcnt[SCSI_INTR]++; 963 #if 0 964 handler = scintsw[cs->chan_num].sci_inthandler; 965 if (handler) 966 (*handler)(scintsw[cs->chan_num].sci_ctlr); 967 #endif 968 } 969 sc_done(scb); 970 } 971 972 sc_discon_exit: 973 sc_start(sc); 974 } 975 976 /* 977 * SCSI phase match interrupt service routine 978 */ 979 void 980 sc_pmatch(struct sc_softc *sc) 981 { 982 struct sc_chan_stat *cs; 983 uint8_t phase; 984 uint8_t phase2; 985 uint8_t cmonr; 986 987 sc->int_stat2 &= ~R3_FNC; /* XXXXXXXX */ 988 989 cs = sc->ip; 990 if (cs == NULL) 991 return; 992 993 #if defined(__mips__) && defined(CPU_SINGLE) 994 dma_reset(CH_SCSI); 995 #endif 996 phase = sc_cmonr & SC_PMASK; 997 DMAC_WAIT0; 998 for (;;) { 999 phase2 = phase; 1000 cmonr = sc_cmonr; 1001 DMAC_WAIT0; 1002 phase = cmonr & SC_PMASK; 1003 if (phase == phase2) { 1004 if ((phase == DAT_IN) || (phase == DAT_OUT)) 1005 break; 1006 else if (cmonr & R4_MREQ) 1007 break; 1008 } 1009 } 1010 1011 1012 sc->dma_stat = OFF; 1013 sc->pad_start = 0; 1014 1015 if (phase == COM_OUT) { 1016 sc->min_flag = 0; 1017 if (cs->comflg != CF_SEND) 1018 cs->comflg = CF_SET; 1019 sc_cout(sc, cs); 1020 } else { 1021 cs->comflg = CF_ENOUGH; 1022 sc_intok2 &= ~Rb_FNC; 1023 if (phase == MES_IN) { 1024 sc->min_flag++; 1025 sc_min(sc, cs); 1026 } else { 1027 sc->min_flag = 0; 1028 1029 switch (phase) { 1030 1031 case MES_OUT: 1032 sc_mout(sc, cs); 1033 break; 1034 1035 case DAT_IN: 1036 case DAT_OUT: 1037 sc_dio(sc, cs); 1038 break; 1039 1040 case STAT_IN: 1041 sc_sin(sc, cs); 1042 break; 1043 1044 default: 1045 printf("SCSI%d: unknown phase\n", cs->chan_num); 1046 break; 1047 } 1048 } 1049 } 1050 } 1051 1052 1053 void 1054 flush_fifo(struct sc_softc *sc) 1055 { 1056 uint8_t dummy; 1057 uint8_t tmp; 1058 uint8_t tmp0; 1059 1060 dummy = sc_ffstr; 1061 DMAC_WAIT0; 1062 if (dummy & R5_FIFOREM) { 1063 /* 1064 * flush FIFO 1065 */ 1066 SET_CMD(sc, SCMD_FLSH_FIFO); 1067 tmp = 0; 1068 do { 1069 do { 1070 dummy = sc_statr; 1071 DMAC_WAIT0; 1072 } while (dummy & R0_CIP); 1073 GET_INTR(&tmp0, &tmp); /* clear interrupt */ 1074 } while ((tmp & R3_FNC) == 0); 1075 } 1076 } 1077 1078 /* 1079 * SCSI command send routine 1080 */ 1081 void 1082 sc_cout(struct sc_softc *sc, struct sc_chan_stat *cs) 1083 { 1084 int iloop; 1085 int cdb_bytes; 1086 uint8_t dummy; 1087 uint8_t statr; 1088 struct scsipi_xfer *xs; 1089 1090 if (cs->comflg == CF_SET) { 1091 struct sc_scb *scb = cs->scb; 1092 1093 cs->comflg = CF_SEND; 1094 1095 flush_fifo(sc); 1096 1097 xs = scb->xs; 1098 cdb_bytes = xs->cmdlen; 1099 1100 switch (xs->cmd->opcode & CMD_TYPEMASK) { 1101 case CMD_T0: 1102 case CMD_T1: 1103 case CMD_T5: 1104 break; 1105 1106 default: 1107 cdb_bytes = 6; 1108 sc_intok2 |= Rb_FNC; 1109 break; 1110 } 1111 1112 /* 1113 * set Active pointers 1114 */ 1115 sc->act_cmd_pointer = (char *)xs->cmd; 1116 cs->act_trcnt = scb->sc_ctrnscnt; 1117 cs->act_point = scb->sc_cpoint; 1118 cs->act_tag = scb->sc_ctag; 1119 cs->act_offset = scb->sc_coffset; 1120 1121 } else { 1122 cdb_bytes = 1; 1123 iloop = 0; 1124 do { 1125 dummy = sc_cmonr; 1126 DMAC_WAIT0; 1127 if ((dummy & SC_PMASK) != COM_OUT) 1128 return; 1129 statr = sc_statr; 1130 DMAC_WAIT0; 1131 if (statr & R0_MIRQ) 1132 return; 1133 } while ((dummy & R4_MREQ) == 0); 1134 statr = sc_statr; 1135 DMAC_WAIT0; 1136 if (statr & R0_MIRQ) 1137 return; 1138 } 1139 1140 1141 SET_CNT(cdb_bytes); 1142 SET_CMD(sc, SCMD_TR_INFO|R0_TRBE); 1143 1144 for (iloop = 0; iloop < cdb_bytes; iloop++) { 1145 do { 1146 dummy = sc_cmonr; 1147 DMAC_WAIT0; 1148 if ((dummy & SC_PMASK) != COM_OUT) 1149 return; 1150 } while ((dummy & R4_MREQ) == 0); 1151 statr = sc_statr; 1152 DMAC_WAIT0; 1153 if (statr & R0_MIRQ) 1154 return; 1155 sc_datr = *sc->act_cmd_pointer++; 1156 do { 1157 dummy = sc_cmonr; 1158 DMAC_WAIT0; 1159 } while ((dummy & R4_MACK) != 0); 1160 } 1161 } 1162 1163 #define GET_MIN_COUNT 127 1164 1165 /* 1166 * SCSI message accept routine 1167 */ 1168 void 1169 sc_min(struct sc_softc *sc, struct sc_chan_stat *cs) 1170 { 1171 struct sc_scb *scb = cs->scb; 1172 struct scsipi_xfer *xs = scb->xs; 1173 uint8_t dummy; 1174 1175 sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG; 1176 DMAC_WAIT0; 1177 1178 if (sc->min_flag == 1) 1179 flush_fifo(sc); 1180 1181 dummy = sc_cmonr; 1182 DMAC_WAIT0; 1183 if ((dummy & R4_MREQ) == 0) { 1184 printf("sc_min: !REQ cmonr=%x\n", dummy); 1185 print_scsi_stat(sc); 1186 scsi_hardreset(); 1187 return; 1188 } 1189 1190 /* retry_cmd_issue: */ 1191 sc->int_stat2 &= ~R3_FNC; 1192 SET_CMD(sc, SCMD_TR_INFO); 1193 do { 1194 do { 1195 dummy = sc_statr; 1196 DMAC_WAIT0; 1197 } while (dummy & R0_CIP); 1198 GET_INTR(&sc->int_stat1, &sc->int_stat2); /* clear interrupt */ 1199 } while ((sc->int_stat2 & R3_FNC) == 0); 1200 sc->int_stat2 &= ~R3_FNC; 1201 1202 dummy = sc_ffstr; 1203 if (dummy & R5_FIE) { 1204 DMAC_WAIT; 1205 dummy = sc_ffstr; 1206 DMAC_WAIT0; 1207 if (dummy & R5_FIE) { 1208 dummy = sc_statr; 1209 DMAC_WAIT0; 1210 if ((dummy & R0_INIT) == 0) { 1211 /* 1212 * CXD1185 detect BSY false 1213 */ 1214 scsi_hardreset(); 1215 return; 1216 } 1217 } 1218 } 1219 dummy = sc_datr; /* get message byte */ 1220 DMAC_WAIT0; 1221 1222 if (sc->min_cnt[cs->chan_num] == 0) { 1223 scb->message = scb->identify; 1224 if (dummy == MSG_EXTND) { 1225 /* Extended Message */ 1226 sc->min_cnt[cs->chan_num] = GET_MIN_COUNT; 1227 sc->min_point[cs->chan_num] = scb->msgbuf; 1228 memset(scb->msgbuf, 0, 8); 1229 *sc->min_point[cs->chan_num]++ = dummy; 1230 } else { 1231 switch ((dummy & MSG_IDENT)? MSG_IDENT : dummy) { 1232 1233 case MSG_CCOMP: 1234 scb->istatus |= INST_EP; 1235 break; 1236 1237 case MSG_MREJ: 1238 #ifndef NOT_SUPPORT_SYNCTR 1239 if (sc->mout_flag[cs->chan_num] == MOUT_SYNC_TR) 1240 sc->sync_tr[cs->chan_num] = 0; 1241 #endif 1242 break; 1243 1244 case MSG_IDENT: 1245 case MSG_RDP: 1246 1247 sc->dma_stat = OFF; 1248 sc->pad_start = 0; 1249 cs->comflg = OFF; 1250 /* 1251 * restore the saved value to Active pointers 1252 */ 1253 sc->act_cmd_pointer = (char *)xs->cmd; 1254 cs->act_trcnt = scb->sc_ctrnscnt; 1255 cs->act_point = scb->sc_cpoint; 1256 cs->act_tag = scb->sc_ctag; 1257 cs->act_offset = scb->sc_coffset; 1258 break; 1259 1260 case MSG_SDP: 1261 /* 1262 * save Active pointers 1263 */ 1264 scb->sc_ctrnscnt = cs->act_trcnt; 1265 scb->sc_ctag = cs->act_tag; 1266 scb->sc_coffset = cs->act_offset; 1267 scb->sc_cpoint = cs->act_point; 1268 break; 1269 1270 case MSG_DCNT: 1271 scb->istatus |= INST_WR; 1272 sc->wrc++; 1273 break; 1274 1275 default: 1276 scb->message = MSG_MREJ; 1277 SET_CMD(sc, SCMD_AST_ATN); 1278 printf("SCSI%d:sc_min() Unknown mes=0x%x, \n", 1279 cs->chan_num, dummy); 1280 } 1281 } 1282 } else { 1283 *sc->min_point[cs->chan_num]++ = dummy; 1284 if (sc->min_cnt[cs->chan_num] == GET_MIN_COUNT) 1285 sc->min_cnt[cs->chan_num] = dummy; 1286 else 1287 sc->min_cnt[cs->chan_num]--; 1288 if (sc->min_cnt[cs->chan_num] <= 0) { 1289 #ifdef ABORT_SYNCTR_MES_FROM_TARGET 1290 if ((scb->msgbuf[2] == 0x01) && 1291 (sc->mout_flag[cs->chan_num] == MOUT_SYNC_TR)) { 1292 #else 1293 if (scb->msgbuf[2] == 0x01) { 1294 #endif 1295 int i; 1296 /* 1297 * receive Synchronous transfer message reply 1298 * calculate transfer period val 1299 * tpm * 4/1000 us = 4/16 * (tpv + 1) 1300 */ 1301 #define TPM2TPV(tpm) (((tpm)*16 + 999) / 1000 - 1) 1302 #ifndef NOT_SUPPORT_SYNCTR 1303 i = scb->msgbuf[3]; /* get tpm */ 1304 i = TPM2TPV(i) << 4; 1305 if (scb->msgbuf[4] == 0) 1306 sc->sync_tr[cs->chan_num] = 0; 1307 else 1308 sc->sync_tr[cs->chan_num] = 1309 i | scb->msgbuf[4]; 1310 #endif /* !NOT_SUPPORT_SYNCTR */ 1311 } else { 1312 scb->message = MSG_MREJ; 1313 SET_CMD(sc, SCMD_AST_ATN); /* assert ATN */ 1314 } 1315 } 1316 } 1317 SET_CMD(sc, SCMD_NGT_ACK); 1318 } 1319 1320 /* 1321 * SCSI message send routine 1322 */ 1323 void 1324 sc_mout(struct sc_softc *sc, struct sc_chan_stat *cs) 1325 { 1326 struct sc_scb *scb = cs->scb; 1327 u_char *mp; 1328 int cnt; 1329 int iloop; 1330 uint8_t dummy; 1331 uint8_t tmp; 1332 uint8_t tmp0; 1333 1334 flush_fifo(sc); 1335 1336 if (sc->mout_flag[cs->chan_num] == 0) { 1337 sc->mout_flag[cs->chan_num] = MOUT_IDENTIFY; 1338 if (scb->message != 0) { 1339 sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG; 1340 DMAC_WAIT0; 1341 if ((scb->message == MSG_EXTND) 1342 && (scb->msgbuf[2] == 0x01)) { 1343 cnt = 5; 1344 mp = scb->msgbuf; 1345 scb->msgbuf[3] = MIN_TP; 1346 if (scb->msgbuf[4] > MAX_OFFSET_BYTES) 1347 scb->msgbuf[4] = MAX_OFFSET_BYTES; 1348 sc->mout_flag[cs->chan_num] = MOUT_SYNC_TR; 1349 } else { 1350 cnt = 1; 1351 mp = &scb->message; 1352 } 1353 1354 SET_CNT(cnt); 1355 SET_CMD(sc, SCMD_TR_INFO|R0_TRBE); 1356 sc_datr = scb->identify; 1357 DMAC_WAIT0; 1358 for (iloop = 1; iloop < cnt; iloop++) { 1359 sc_datr = *mp++; 1360 DMAC_WAIT; 1361 } 1362 do { 1363 dummy = sc_cmonr; 1364 DMAC_WAIT0; 1365 if ((dummy & R4_MBSY) == 0) 1366 return; 1367 dummy = sc_statr; 1368 DMAC_WAIT0; 1369 } while (dummy & R0_CIP); 1370 1371 tmp = 0; 1372 GET_INTR(&tmp0, &tmp); /* clear interrupt */ 1373 if ((tmp & R3_FNC) == 0) { 1374 (void) WAIT_STATR_BITSET(R0_MIRQ); 1375 GET_INTR(&tmp0, &tmp); /* clear interrupt */ 1376 } 1377 1378 do { 1379 dummy = sc_cmonr; 1380 DMAC_WAIT0; 1381 if ((dummy & R4_MBSY) == 0) 1382 return; 1383 } while ((dummy & R4_MREQ) == 0); 1384 SET_CMD(sc, SCMD_NGT_ATN); 1385 (void)WAIT_STATR_BITCLR(R0_CIP); 1386 GET_INTR(&tmp0, &tmp); /* clear interrupt */ 1387 1388 dummy = sc_cmonr; 1389 DMAC_WAIT0; 1390 if ((dummy & R4_MREQ) == 0) { 1391 printf("sc_mout: !REQ cmonr=%x\n", dummy); 1392 print_scsi_stat(sc); 1393 scsi_hardreset(); 1394 return; 1395 } 1396 1397 SET_CMD(sc, SCMD_TR_INFO); 1398 sc_datr = *mp++; 1399 DMAC_WAIT0; 1400 } else { 1401 dummy = sc_cmonr; 1402 DMAC_WAIT0; 1403 if (dummy & R4_MATN) { 1404 SET_CMD(sc, SCMD_NGT_ATN); 1405 (void) WAIT_STATR_BITCLR(R0_CIP); 1406 GET_INTR(&tmp0, &tmp); /* clear interrupt */ 1407 } 1408 1409 iloop = 0; 1410 do { 1411 dummy = sc_cmonr; 1412 DMAC_WAIT0; 1413 if (iloop++ > CHECK_LOOP_CNT) 1414 break; 1415 } while ((dummy & R4_MREQ) == 0); 1416 SET_CMD(sc, SCMD_TR_INFO); 1417 sc_datr = scb->identify; 1418 DMAC_WAIT0; 1419 } 1420 } else { 1421 dummy = sc_cmonr; 1422 DMAC_WAIT0; 1423 if (dummy & R4_MATN) { 1424 SET_CMD(sc, SCMD_NGT_ATN); 1425 (void) WAIT_STATR_BITCLR(R0_CIP); 1426 GET_INTR(&tmp0, &tmp); /* clear interrupt */ 1427 } 1428 1429 dummy = sc_cmonr; 1430 DMAC_WAIT0; 1431 if ((dummy & R4_MREQ) == 0) { 1432 printf("sc_mout: !REQ cmonr=%x\n", dummy); 1433 print_scsi_stat(sc); 1434 scsi_hardreset(); 1435 return; 1436 } 1437 1438 SET_CMD(sc, SCMD_TR_INFO); 1439 sc_datr = scb->message; 1440 DMAC_WAIT0; 1441 } 1442 } 1443 1444 /* 1445 * SCSI status accept routine 1446 */ 1447 void 1448 sc_sin(struct sc_softc *sc, volatile struct sc_chan_stat *cs) 1449 { 1450 uint8_t dummy; 1451 int iloop; 1452 1453 flush_fifo(sc); 1454 1455 dummy = sc_cmonr; 1456 DMAC_WAIT0; 1457 if ((dummy & R4_MREQ) == 0) { 1458 printf("sc_sin: !REQ cmonr=%x\n", dummy); 1459 print_scsi_stat(sc); 1460 scsi_hardreset(); 1461 return; 1462 } 1463 1464 sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE|Rb_RMSG; 1465 DMAC_WAIT0; 1466 1467 SET_CMD(sc, SCMD_TR_INFO); 1468 1469 (void)WAIT_STATR_BITCLR(R0_CIP); 1470 1471 sc->int_stat2 &= ~R3_FNC; 1472 iloop = 0; 1473 do { 1474 if (iloop++ > CHECK_LOOP_CNT) 1475 break; 1476 GET_INTR(&sc->int_stat1, &sc->int_stat2); /* clear interrupt */ 1477 } while ((sc->int_stat2 & R3_FNC) == 0); 1478 sc->int_stat2 &= ~R3_FNC; 1479 1480 cs->scb->tstatus = sc_datr; /* get status byte */ 1481 DMAC_WAIT0; 1482 } 1483 1484 /* 1485 * SCSI data in/out routine 1486 */ 1487 void 1488 sc_dio(struct sc_softc *sc, volatile struct sc_chan_stat *cs) 1489 { 1490 struct sc_scb *scb; 1491 int i; 1492 int pages; 1493 uint8_t tag; 1494 uint32_t pfn; 1495 uint8_t phase; 1496 struct scsipi_xfer *xs; 1497 1498 scb = cs->scb; 1499 xs = scb->xs; 1500 1501 sc_intok2 = Rb_FNC|Rb_DCNT|Rb_SRST|Rb_PHC|Rb_SPE; 1502 DMAC_WAIT0; 1503 1504 if (cs->act_trcnt <= 0) { 1505 sc_dio_pad(sc, cs); 1506 return; 1507 } 1508 1509 switch (xs->cmd->opcode) { 1510 1511 case SCOP_READ: 1512 case SCOP_WRITE: 1513 case SCOP_EREAD: 1514 case SCOP_EWRITE: 1515 i = (cs->act_trcnt + DEV_BSIZE -1) / DEV_BSIZE; 1516 i *= DEV_BSIZE; 1517 break; 1518 1519 default: 1520 i = cs->act_trcnt; 1521 break; 1522 } 1523 1524 SET_CNT(i); 1525 sc->pad_cnt[cs->chan_num] = i - cs->act_trcnt; 1526 1527 phase = sc_cmonr & SC_PMASK; 1528 DMAC_WAIT0; 1529 if (phase == DAT_IN) { 1530 if (sc_syncr == OFF) { 1531 DMAC_WAIT0; 1532 flush_fifo(sc); 1533 } 1534 } 1535 1536 #if defined(__mips__) && defined(CPU_SINGLE) 1537 SET_CMD(sc, SCMD_TR_INFO|R0_DMA|R0_TRBE); 1538 #endif 1539 1540 #if defined(__mips__) && defined(CPU_SINGLE) 1541 dmac_gsel = CH_SCSI; 1542 dmac_ctrcl = (uint8_t)(cs->act_trcnt & 0xff); 1543 dmac_ctrcm = (uint8_t)((cs->act_trcnt >> 8) & 0xff); 1544 dmac_ctrch = (uint8_t)((cs->act_trcnt >> 16) & 0x0f); 1545 dmac_cofsh = (uint8_t)((cs->act_offset >> 8) & 0xf); 1546 dmac_cofsl = (uint8_t)(cs->act_offset & 0xff); 1547 #endif 1548 tag = 0; 1549 1550 if (scb->sc_map && (scb->sc_map->mp_pages > 0)) { 1551 /* 1552 * Set DMAC map entry from map table 1553 */ 1554 pages = scb->sc_map->mp_pages; 1555 for (i = cs->act_tag; i < pages; i++) { 1556 if ((pfn = scb->sc_map->mp_addr[i]) == 0) 1557 panic("SCSI:sc_dma() zero entry"); 1558 #if defined(__mips__) && defined(CPU_SINGLE) 1559 dmac_gsel = CH_SCSI; 1560 dmac_ctag = (uint8_t)tag++; 1561 dmac_cmap = (uint16_t)pfn; 1562 #endif 1563 } 1564 #ifdef MAP_OVER_ACCESS 1565 # if defined(__mips__) && defined(CPU_SINGLE) 1566 dmac_gsel = CH_SCSI; 1567 dmac_ctag = (uint8_t)tag++; 1568 dmac_cmap = (uint16_t)pfn; 1569 # endif 1570 #endif 1571 } else { 1572 /* 1573 * Set DMAC map entry from logical address 1574 */ 1575 pfn = kvtophys((vaddr_t)cs->act_point) >> PGSHIFT; 1576 pages = (cs->act_trcnt >> PGSHIFT) + 2; 1577 for (i = 0; i < pages; i++) { 1578 #if defined(__mips__) && defined(CPU_SINGLE) 1579 dmac_gsel = CH_SCSI; 1580 dmac_ctag = (uint8_t)tag++; 1581 dmac_cmap = (uint8_t)pfn + i; 1582 #endif 1583 } 1584 } 1585 1586 #if defined(__mips__) && defined(CPU_SINGLE) 1587 dmac_gsel = CH_SCSI; 1588 dmac_ctag = 0; 1589 #endif 1590 1591 if (phase == DAT_IN) { 1592 sc->dma_stat = SC_DMAC_RD; 1593 #if defined(__mips__) && defined(CPU_SINGLE) 1594 /* 1595 * auto pad flag is always on 1596 */ 1597 dmac_gsel = CH_SCSI; 1598 dmac_cctl = DM_MODE|DM_APAD; 1599 DMAC_WAIT; 1600 dmac_cctl = DM_MODE|DM_APAD|DM_ENABLE; 1601 DMAC_WAIT0; 1602 #endif 1603 } 1604 else if (phase == DAT_OUT) { 1605 sc->dma_stat = SC_DMAC_WR; 1606 #if defined(__mips__) && defined(CPU_SINGLE) 1607 dmac_gsel = CH_SCSI; 1608 dmac_cctl = DM_APAD; 1609 DMAC_WAIT; 1610 dmac_cctl = DM_APAD|DM_ENABLE; 1611 DMAC_WAIT0; 1612 #endif 1613 /* DMAC start on mem->I/O */ 1614 } 1615 } 1616 1617 #define MAX_TR_CNT24 ((1 << 24) -1) 1618 void 1619 sc_dio_pad(struct sc_softc *sc, volatile struct sc_chan_stat *cs) 1620 { 1621 uint8_t dummy; 1622 1623 if (cs->act_trcnt >= 0) 1624 return; 1625 sc->pad_start = 1; 1626 1627 SET_CNT(MAX_TR_CNT24); 1628 SET_CMD(sc, SCMD_TR_PAD|R0_TRBE); 1629 dummy = sc_cmonr & SC_PMASK; 1630 DMAC_WAIT0; 1631 if (dummy == DAT_IN) 1632 dummy = sc_datr; /* get data */ 1633 else 1634 sc_datr = 0; /* send data */ 1635 } 1636 1637 void 1638 print_scsi_stat(struct sc_softc *sc) 1639 { 1640 1641 printf("ipc=%d wrc=%d wbc=%d\n", sc->ipc, sc->wrc, sc->wbc); 1642 } 1643 1644 /* 1645 * return 0 if it was done. Or retun TRUE if it is busy. 1646 */ 1647 int 1648 sc_busy(struct sc_softc *sc, int chan) 1649 { 1650 1651 return (int)sc->chan_stat[chan].scb; 1652 } 1653 1654 1655 /* 1656 * append channel into Waiting Bus_free queue 1657 */ 1658 void 1659 append_wb(struct sc_softc *sc, struct sc_chan_stat *cs) 1660 { 1661 int s; 1662 1663 s = splclock(); /* inhibit process switch */ 1664 if (sc->wbq_actf == NULL) 1665 sc->wbq_actf = cs; 1666 else 1667 sc->wbq_actl->wb_next = cs; 1668 sc->wbq_actl = cs; 1669 cs->scb->istatus = INST_WAIT; 1670 sc->wbc++; 1671 splx(s); 1672 } 1673 1674 /* 1675 * get channel from Waiting Bus_free queue 1676 */ 1677 struct sc_chan_stat * 1678 get_wb_chan(struct sc_softc *sc) 1679 { 1680 struct sc_chan_stat *cs; 1681 int s; 1682 1683 s = splclock(); /* inhibit process switch */ 1684 cs = sc->wbq_actf; 1685 if (cs && cs->chan_num == SC_OWNID) /* needed? */ 1686 cs = NULL; 1687 splx(s); 1688 return cs; 1689 } 1690 1691 /* 1692 * release channel from Waiting Bus_free queue 1693 */ 1694 int 1695 release_wb(struct sc_softc *sc) 1696 { 1697 struct sc_chan_stat *cs; 1698 int error = 0; 1699 int s; 1700 1701 s = splclock(); /* inhibit process switch */ 1702 if (sc->wbq_actf == NULL) { 1703 error = -1; 1704 } else { 1705 cs = sc->wbq_actf; 1706 sc->wbq_actf = cs->wb_next; 1707 cs->wb_next = NULL; 1708 if (sc->wbq_actl == cs) 1709 sc->wbq_actl = NULL; 1710 cs->scb->istatus &= ~INST_WAIT; 1711 sc->wbc--; 1712 } 1713 splx(s); 1714 return error; 1715 } 1716 1717 void 1718 adjust_transfer(struct sc_softc *sc, struct sc_chan_stat *cs) 1719 { 1720 struct sc_scb *scb = cs->scb; 1721 u_int remain_cnt; 1722 u_int offset, sent_byte; 1723 1724 if (sc->pad_start) { 1725 sc->pad_start = 0; 1726 remain_cnt = 0; 1727 } else { 1728 # if defined(__mips__) && defined(CPU_SINGLE) 1729 remain_cnt = GET_CNT(); 1730 remain_cnt -= sc->pad_cnt[cs->chan_num]; 1731 if (sc->dma_stat == SC_DMAC_WR) { 1732 /* 1733 * adjust counter in the FIFO 1734 */ 1735 remain_cnt += sc_ffstr & R5_FIFOREM; 1736 } 1737 # endif 1738 } 1739 1740 sent_byte = scb->sc_ctrnscnt - remain_cnt; 1741 cs->act_trcnt = remain_cnt; 1742 1743 offset = scb->sc_coffset + sent_byte; 1744 cs->act_tag += (offset >> PGSHIFT); 1745 cs->act_offset = offset & PGOFSET; 1746 if ((scb->sc_map == NULL) || (scb->sc_map->mp_pages <= 0)) 1747 cs->act_point += sent_byte; 1748 } 1749 1750 #ifdef __mips__ 1751 static void 1752 clean_k2dcache(struct sc_scb *scb) 1753 { 1754 struct sc_map *sc_map = scb->sc_map; 1755 paddr_t pa; 1756 int i, pages; 1757 1758 pa = kvtophys((vaddr_t)scb->msgbuf); 1759 mips_dcache_wbinv_range_index(MIPS_PHYS_TO_KSEG0(pa), 1760 sizeof(scb->msgbuf)); 1761 1762 if (MACH_IS_USPACE(scb->sc_cpoint)) 1763 panic("clean_k2dcache: user address is not supported"); 1764 1765 if (MACH_IS_CACHED(scb->sc_cpoint)) { 1766 mips_dcache_wbinv_range_index((vaddr_t)scb->sc_cpoint, 1767 scb->sc_ctrnscnt); 1768 return; 1769 } 1770 1771 if (sc_map) { 1772 pages = sc_map->mp_pages; 1773 for (i = 0; i < pages; i++) { 1774 pa = sc_map->mp_addr[i] << PGSHIFT; 1775 mips_dcache_wbinv_range_index(MIPS_PHYS_TO_KSEG0(pa), 1776 PAGE_SIZE); 1777 } 1778 } 1779 } 1780 #endif 1781