1/* $NetBSD: scsi_1185.c,v 1.19.22.1 2010/12/29 08:14:43 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.19.22.1 2010/12/29 08:14:43 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 124static 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 137void sc_send(struct sc_scb *, int, int); 138int scintr(void); 139void scsi_hardreset(void); 140void scsi_chipreset(struct sc_softc *); 141void scsi_softreset(struct sc_softc *); 142int sc_busy(struct sc_softc *, int); 143 144static int WAIT_STATR_BITCLR(int); 145static int WAIT_STATR_BITSET(int); 146static void SET_CMD(struct sc_softc *, int); 147static void SET_CNT(int); 148static int GET_CNT(void); 149static void GET_INTR(uint8_t *, uint8_t *); 150static void sc_start(struct sc_softc *); 151static void sc_resel(struct sc_softc *); 152static void sc_discon(struct sc_softc *); 153static void sc_pmatch(struct sc_softc *); 154static void flush_fifo(struct sc_softc *); 155static void sc_cout(struct sc_softc *, struct sc_chan_stat *); 156static void sc_min(struct sc_softc *, struct sc_chan_stat *); 157static void sc_mout(struct sc_softc *, struct sc_chan_stat *); 158static void sc_sin(struct sc_softc *, volatile struct sc_chan_stat *); 159static void sc_dio(struct sc_softc *, volatile struct sc_chan_stat *); 160static void sc_dio_pad(struct sc_softc *, volatile struct sc_chan_stat *); 161static void print_scsi_stat(struct sc_softc *); 162static void append_wb(struct sc_softc *, struct sc_chan_stat *); 163static struct sc_chan_stat *get_wb_chan(struct sc_softc *); 164static int release_wb(struct sc_softc *); 165static void adjust_transfer(struct sc_softc *, struct sc_chan_stat *); 166static void clean_k2dcache(struct sc_scb *); 167 168extern void sc_done(struct sc_scb *); 169extern 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 179int 180WAIT_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 195int 196WAIT_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 211void 212SET_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 221void 222SET_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 233int 234GET_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 247void 248GET_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 262void 263sc_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 */ 340void 341sc_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 404sc_start_exit: 405 splx(s); 406} 407 408/* 409 * SCSI interrupt service routine 410 */ 411int 412scintr(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 423scintr_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 652scintr_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 */ 661void 662scsi_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 704void 705scsi_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 762void 763scsi_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 */ 813void 814sc_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 */ 898void 899sc_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 972sc_discon_exit: 973 sc_start(sc); 974} 975 976/* 977 * SCSI phase match interrupt service routine 978 */ 979void 980sc_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 1053void 1054flush_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 */ 1081void 1082sc_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 */ 1168void 1169sc_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 */ 1323void 1324sc_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 */ 1447void 1448sc_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 */ 1487void 1488sc_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) 1618void 1619sc_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 1637void 1638print_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 */ 1647int 1648sc_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 */ 1658void 1659append_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 */ 1677struct sc_chan_stat * 1678get_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 */ 1694int 1695release_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 1717void 1718adjust_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__ 1751static void 1752clean_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