1 /* $NetBSD: esp.c,v 1.25 2000/06/05 07:59:52 nisimura Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Jason R. Thorpe. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed for the NetBSD Project 18 * by Jason R. Thorpe. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1994 Peter Galbavy 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by Peter Galbavy 49 * 4. The name of the author may not be used to endorse or promote products 50 * derived from this software without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 54 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 55 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 56 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 57 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 58 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 60 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 61 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 62 * POSSIBILITY OF SUCH DAMAGE. 63 */ 64 65 /* 66 * Based on aic6360 by Jarle Greipsland 67 * 68 * Acknowledgements: Many of the algorithms used in this driver are 69 * inspired by the work of Julian Elischer (julian@tfs.com) and 70 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million! 71 */ 72 73 /* 74 * Initial m68k mac support from Allen Briggs <briggs@macbsd.com> 75 * (basically consisting of the match, a bit of the attach, and the 76 * "DMA" glue functions). 77 */ 78 79 #include <sys/types.h> 80 #include <sys/param.h> 81 #include <sys/systm.h> 82 #include <sys/kernel.h> 83 #include <sys/errno.h> 84 #include <sys/ioctl.h> 85 #include <sys/device.h> 86 #include <sys/buf.h> 87 #include <sys/proc.h> 88 #include <sys/user.h> 89 #include <sys/queue.h> 90 91 #include <dev/scsipi/scsi_all.h> 92 #include <dev/scsipi/scsipi_all.h> 93 #include <dev/scsipi/scsiconf.h> 94 #include <dev/scsipi/scsi_message.h> 95 96 #include <machine/cpu.h> 97 #include <machine/bus.h> 98 #include <machine/param.h> 99 100 #include <dev/ic/ncr53c9xreg.h> 101 #include <dev/ic/ncr53c9xvar.h> 102 103 #include <machine/viareg.h> 104 105 #include <mac68k/obio/espvar.h> 106 #include <mac68k/obio/obiovar.h> 107 108 void espattach __P((struct device *, struct device *, void *)); 109 int espmatch __P((struct device *, struct cfdata *, void *)); 110 111 /* Linkup to the rest of the kernel */ 112 struct cfattach esp_ca = { 113 sizeof(struct esp_softc), espmatch, espattach 114 }; 115 116 /* 117 * Functions and the switch for the MI code. 118 */ 119 u_char esp_read_reg __P((struct ncr53c9x_softc *, int)); 120 void esp_write_reg __P((struct ncr53c9x_softc *, int, u_char)); 121 int esp_dma_isintr __P((struct ncr53c9x_softc *)); 122 void esp_dma_reset __P((struct ncr53c9x_softc *)); 123 int esp_dma_intr __P((struct ncr53c9x_softc *)); 124 int esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *, 125 size_t *, int, size_t *)); 126 void esp_dma_go __P((struct ncr53c9x_softc *)); 127 void esp_dma_stop __P((struct ncr53c9x_softc *)); 128 int esp_dma_isactive __P((struct ncr53c9x_softc *)); 129 void esp_quick_write_reg __P((struct ncr53c9x_softc *, int, u_char)); 130 int esp_quick_dma_intr __P((struct ncr53c9x_softc *)); 131 int esp_quick_dma_setup __P((struct ncr53c9x_softc *, caddr_t *, 132 size_t *, int, size_t *)); 133 void esp_quick_dma_go __P((struct ncr53c9x_softc *)); 134 135 void esp_intr __P((void *sc)); 136 void esp_dualbus_intr __P((void *sc)); 137 static struct esp_softc *esp0 = NULL, *esp1 = NULL; 138 139 static __inline__ int esp_dafb_have_dreq __P((struct esp_softc *esc)); 140 static __inline__ int esp_iosb_have_dreq __P((struct esp_softc *esc)); 141 int (*esp_have_dreq) __P((struct esp_softc *esc)); 142 143 struct ncr53c9x_glue esp_glue = { 144 esp_read_reg, 145 esp_write_reg, 146 esp_dma_isintr, 147 esp_dma_reset, 148 esp_dma_intr, 149 esp_dma_setup, 150 esp_dma_go, 151 esp_dma_stop, 152 esp_dma_isactive, 153 NULL, /* gl_clear_latched_intr */ 154 }; 155 156 int 157 espmatch(parent, cf, aux) 158 struct device *parent; 159 struct cfdata *cf; 160 void *aux; 161 { 162 int found = 0; 163 164 if ((cf->cf_unit == 0) && mac68k_machine.scsi96) { 165 found = 1; 166 } 167 if ((cf->cf_unit == 1) && mac68k_machine.scsi96_2) { 168 found = 1; 169 } 170 171 return found; 172 } 173 174 /* 175 * Attach this instance, and then all the sub-devices 176 */ 177 void 178 espattach(parent, self, aux) 179 struct device *parent, *self; 180 void *aux; 181 { 182 struct obio_attach_args *oa = (struct obio_attach_args *)aux; 183 extern vaddr_t SCSIBase; 184 struct esp_softc *esc = (void *)self; 185 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 186 int quick = 0; 187 unsigned long reg_offset; 188 189 reg_offset = SCSIBase - IOBase; 190 esc->sc_tag = oa->oa_tag; 191 /* 192 * For Wombat, Primus and Optimus motherboards, DREQ is 193 * visible on bit 0 of the IOSB's emulated VIA2 vIFR (and 194 * the scsi registers are offset 0x1000 bytes from IOBase). 195 * 196 * For the Q700/900/950 it's at f9800024 for bus 0 and 197 * f9800028 for bus 1 (900/950). For these machines, that is also 198 * a (12-bit) configuration register for DAFB's control of the 199 * pseudo-DMA timing. The default value is 0x1d1. 200 */ 201 esp_have_dreq = esp_dafb_have_dreq; 202 if (sc->sc_dev.dv_unit == 0) { 203 if (reg_offset == 0x10000) { 204 quick = 1; 205 esp_have_dreq = esp_iosb_have_dreq; 206 } else if (reg_offset == 0x18000) { 207 quick = 0; 208 } else { 209 if (bus_space_map(esc->sc_tag, 0xf9800024, 210 4, 0, &esc->sc_bsh)) { 211 printf("failed to map 4 at 0xf9800024.\n"); 212 } else { 213 quick = 1; 214 bus_space_write_4(esc->sc_tag, 215 esc->sc_bsh, 0, 0x1d1); 216 } 217 } 218 } else { 219 if (bus_space_map(esc->sc_tag, 0xf9800028, 220 4, 0, &esc->sc_bsh)) { 221 printf("failed to map 4 at 0xf9800028.\n"); 222 } else { 223 quick = 1; 224 bus_space_write_4(esc->sc_tag, esc->sc_bsh, 0, 0x1d1); 225 } 226 } 227 if (quick) { 228 esp_glue.gl_write_reg = esp_quick_write_reg; 229 esp_glue.gl_dma_intr = esp_quick_dma_intr; 230 esp_glue.gl_dma_setup = esp_quick_dma_setup; 231 esp_glue.gl_dma_go = esp_quick_dma_go; 232 } 233 234 /* 235 * Set up the glue for MI code early; we use some of it here. 236 */ 237 sc->sc_glue = &esp_glue; 238 239 /* 240 * Save the regs 241 */ 242 if (sc->sc_dev.dv_unit == 0) { 243 esp0 = esc; 244 245 esc->sc_reg = (volatile u_char *) SCSIBase; 246 via2_register_irq(VIA2_SCSIIRQ, esp_intr, esc); 247 esc->irq_mask = V2IF_SCSIIRQ; 248 if (reg_offset == 0x10000) { 249 sc->sc_freq = 16500000; 250 } else { 251 sc->sc_freq = 25000000; 252 } 253 254 if (esp_glue.gl_dma_go == esp_quick_dma_go) { 255 printf(" (quick)"); 256 } 257 } else { 258 esp1 = esc; 259 260 esc->sc_reg = (volatile u_char *) SCSIBase + 0x402; 261 via2_register_irq(VIA2_SCSIIRQ, esp_dualbus_intr, NULL); 262 esc->irq_mask = 0; 263 sc->sc_freq = 25000000; 264 265 if (esp_glue.gl_dma_go == esp_quick_dma_go) { 266 printf(" (quick)"); 267 } 268 } 269 270 printf(": address %p", esc->sc_reg); 271 272 sc->sc_id = 7; 273 274 /* gimme Mhz */ 275 sc->sc_freq /= 1000000; 276 277 /* 278 * It is necessary to try to load the 2nd config register here, 279 * to find out what rev the esp chip is, else the esp_reset 280 * will not set up the defaults correctly. 281 */ 282 sc->sc_cfg1 = sc->sc_id; /* | NCRCFG1_PARENB; */ 283 sc->sc_cfg2 = NCRCFG2_SCSI2; 284 sc->sc_cfg3 = 0; 285 sc->sc_rev = NCR_VARIANT_NCR53C96; 286 287 /* 288 * This is the value used to start sync negotiations 289 * Note that the NCR register "SYNCTP" is programmed 290 * in "clocks per byte", and has a minimum value of 4. 291 * The SCSI period used in negotiation is one-fourth 292 * of the time (in nanoseconds) needed to transfer one byte. 293 * Since the chip's clock is given in MHz, we have the following 294 * formula: 4 * period = (1000 / freq) * 4 295 */ 296 sc->sc_minsync = 1000 / sc->sc_freq; 297 298 sc->sc_minsync = 0; /* No synchronous xfers w/o DMA */ 299 /* Really no limit, but since we want to fit into the TCR... */ 300 sc->sc_maxxfer = 8 * 1024; /*64 * 1024; XXX */ 301 302 /* 303 * Configure interrupts. 304 */ 305 if (esc->irq_mask) { 306 via2_reg(vPCR) = 0x22; 307 via2_reg(vIFR) = esc->irq_mask; 308 via2_reg(vIER) = 0x80 | esc->irq_mask; 309 } 310 311 /* 312 * Now try to attach all the sub-devices 313 */ 314 ncr53c9x_attach(sc, NULL, NULL); 315 } 316 317 /* 318 * Glue functions. 319 */ 320 321 u_char 322 esp_read_reg(sc, reg) 323 struct ncr53c9x_softc *sc; 324 int reg; 325 { 326 struct esp_softc *esc = (struct esp_softc *)sc; 327 328 return esc->sc_reg[reg * 16]; 329 } 330 331 void 332 esp_write_reg(sc, reg, val) 333 struct ncr53c9x_softc *sc; 334 int reg; 335 u_char val; 336 { 337 struct esp_softc *esc = (struct esp_softc *)sc; 338 u_char v = val; 339 340 if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) { 341 v = NCRCMD_TRANS; 342 } 343 esc->sc_reg[reg * 16] = v; 344 } 345 346 void 347 esp_dma_stop(sc) 348 struct ncr53c9x_softc *sc; 349 { 350 } 351 352 int 353 esp_dma_isactive(sc) 354 struct ncr53c9x_softc *sc; 355 { 356 struct esp_softc *esc = (struct esp_softc *)sc; 357 358 return esc->sc_active; 359 } 360 361 int 362 esp_dma_isintr(sc) 363 struct ncr53c9x_softc *sc; 364 { 365 struct esp_softc *esc = (struct esp_softc *)sc; 366 367 return esc->sc_reg[NCR_STAT * 16] & 0x80; 368 } 369 370 void 371 esp_dma_reset(sc) 372 struct ncr53c9x_softc *sc; 373 { 374 struct esp_softc *esc = (struct esp_softc *)sc; 375 376 esc->sc_active = 0; 377 esc->sc_tc = 0; 378 } 379 380 int 381 esp_dma_intr(sc) 382 struct ncr53c9x_softc *sc; 383 { 384 struct esp_softc *esc = (struct esp_softc *)sc; 385 volatile u_char *cmdreg, *intrreg, *statreg, *fiforeg; 386 u_char *p; 387 u_int espphase, espstat, espintr; 388 int cnt, s; 389 390 if (esc->sc_active == 0) { 391 printf("dma_intr--inactive DMA\n"); 392 return -1; 393 } 394 395 if ((sc->sc_espintr & NCRINTR_BS) == 0) { 396 esc->sc_active = 0; 397 return 0; 398 } 399 400 cnt = *esc->sc_dmalen; 401 if (*esc->sc_dmalen == 0) { 402 printf("data interrupt, but no count left."); 403 } 404 405 p = *esc->sc_dmaaddr; 406 espphase = sc->sc_phase; 407 espstat = (u_int) sc->sc_espstat; 408 espintr = (u_int) sc->sc_espintr; 409 cmdreg = esc->sc_reg + NCR_CMD * 16; 410 fiforeg = esc->sc_reg + NCR_FIFO * 16; 411 statreg = esc->sc_reg + NCR_STAT * 16; 412 intrreg = esc->sc_reg + NCR_INTR * 16; 413 do { 414 if (esc->sc_datain) { 415 *p++ = *fiforeg; 416 cnt--; 417 if (espphase == DATA_IN_PHASE) { 418 *cmdreg = NCRCMD_TRANS; 419 } else { 420 esc->sc_active = 0; 421 } 422 } else { 423 if ( (espphase == DATA_OUT_PHASE) 424 || (espphase == MESSAGE_OUT_PHASE)) { 425 *fiforeg = *p++; 426 cnt--; 427 *cmdreg = NCRCMD_TRANS; 428 } else { 429 esc->sc_active = 0; 430 } 431 } 432 433 if (esc->sc_active) { 434 while (!(*statreg & 0x80)); 435 s = splhigh(); 436 espstat = *statreg; 437 espintr = *intrreg; 438 espphase = (espintr & NCRINTR_DIS) 439 ? /* Disconnected */ BUSFREE_PHASE 440 : espstat & PHASE_MASK; 441 splx(s); 442 } 443 } while (esc->sc_active && (espintr & NCRINTR_BS)); 444 sc->sc_phase = espphase; 445 sc->sc_espstat = (u_char) espstat; 446 sc->sc_espintr = (u_char) espintr; 447 *esc->sc_dmaaddr = p; 448 *esc->sc_dmalen = cnt; 449 450 if (*esc->sc_dmalen == 0) { 451 esc->sc_tc = NCRSTAT_TC; 452 } 453 sc->sc_espstat |= esc->sc_tc; 454 return 0; 455 } 456 457 int 458 esp_dma_setup(sc, addr, len, datain, dmasize) 459 struct ncr53c9x_softc *sc; 460 caddr_t *addr; 461 size_t *len; 462 int datain; 463 size_t *dmasize; 464 { 465 struct esp_softc *esc = (struct esp_softc *)sc; 466 467 esc->sc_dmaaddr = addr; 468 esc->sc_dmalen = len; 469 esc->sc_datain = datain; 470 esc->sc_dmasize = *dmasize; 471 esc->sc_tc = 0; 472 473 return 0; 474 } 475 476 void 477 esp_dma_go(sc) 478 struct ncr53c9x_softc *sc; 479 { 480 struct esp_softc *esc = (struct esp_softc *)sc; 481 482 if (esc->sc_datain == 0) { 483 esc->sc_reg[NCR_FIFO * 16] = **esc->sc_dmaaddr; 484 (*esc->sc_dmalen)--; 485 (*esc->sc_dmaaddr)++; 486 } 487 esc->sc_active = 1; 488 } 489 490 void 491 esp_quick_write_reg(sc, reg, val) 492 struct ncr53c9x_softc *sc; 493 int reg; 494 u_char val; 495 { 496 struct esp_softc *esc = (struct esp_softc *)sc; 497 498 esc->sc_reg[reg * 16] = val; 499 } 500 501 int 502 esp_quick_dma_intr(sc) 503 struct ncr53c9x_softc *sc; 504 { 505 struct esp_softc *esc = (struct esp_softc *)sc; 506 int trans=0, resid=0; 507 508 if (esc->sc_active == 0) 509 panic("dma_intr--inactive DMA\n"); 510 511 esc->sc_active = 0; 512 513 if (esc->sc_dmasize == 0) { 514 int res; 515 516 res = 65536; 517 res -= NCR_READ_REG(sc, NCR_TCL); 518 res -= NCR_READ_REG(sc, NCR_TCM) << 8; 519 printf("dmaintr: discarded %d b (last transfer was %d b).\n", 520 res, esc->sc_prevdmasize); 521 return 0; 522 } 523 524 if (esc->sc_datain && 525 (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) { 526 printf("dmaintr: empty FIFO of %d\n", resid); 527 DELAY(1); 528 } 529 530 if ((sc->sc_espstat & NCRSTAT_TC) == 0) { 531 resid += NCR_READ_REG(sc, NCR_TCL); 532 resid += NCR_READ_REG(sc, NCR_TCM) << 8; 533 534 if (resid == 0) 535 resid = 65536; 536 } 537 538 trans = esc->sc_dmasize - resid; 539 if (trans < 0) { 540 printf("dmaintr: trans < 0????"); 541 trans = esc->sc_dmasize; 542 } 543 544 NCR_DMA(("dmaintr: trans %d, resid %d.\n", trans, resid)); 545 *esc->sc_dmaaddr += trans; 546 *esc->sc_dmalen -= trans; 547 548 return 0; 549 } 550 551 int 552 esp_quick_dma_setup(sc, addr, len, datain, dmasize) 553 struct ncr53c9x_softc *sc; 554 caddr_t *addr; 555 size_t *len; 556 int datain; 557 size_t *dmasize; 558 { 559 struct esp_softc *esc = (struct esp_softc *)sc; 560 561 esc->sc_dmaaddr = addr; 562 esc->sc_dmalen = len; 563 564 esc->sc_pdmaddr = (u_int16_t *) *addr; 565 esc->sc_pdmalen = *len; 566 if (esc->sc_pdmalen & 1) { 567 esc->sc_pdmalen--; 568 esc->sc_pad = 1; 569 } else { 570 esc->sc_pad = 0; 571 } 572 573 esc->sc_datain = datain; 574 esc->sc_prevdmasize = esc->sc_dmasize; 575 esc->sc_dmasize = *dmasize; 576 577 return 0; 578 } 579 580 static __inline__ int 581 esp_dafb_have_dreq(esc) 582 struct esp_softc *esc; 583 { 584 u_int32_t r; 585 586 r = bus_space_read_4(esc->sc_tag, esc->sc_bsh, 0); 587 return (r & 0x200); 588 } 589 590 static __inline__ int 591 esp_iosb_have_dreq(esc) 592 struct esp_softc *esc; 593 { 594 return (via2_reg(vIFR) & V2IF_SCSIDRQ); 595 } 596 597 static int espspl=-1; 598 #define __splx(s) __asm __volatile ("movew %0,sr" : : "di" (s)); 599 #define __spl2() __splx(PSL_S|PSL_IPL2) 600 #define __spl6() __splx(PSL_S|PSL_IPL6) 601 602 void 603 esp_quick_dma_go(sc) 604 struct ncr53c9x_softc *sc; 605 { 606 struct esp_softc *esc = (struct esp_softc *)sc; 607 extern int *nofault; 608 label_t faultbuf; 609 u_int16_t volatile *pdma; 610 u_char volatile *statreg; 611 612 esc->sc_active = 1; 613 614 espspl = spl2(); 615 616 restart_dmago: 617 nofault = (int *) &faultbuf; 618 if (setjmp((label_t *) nofault)) { 619 int i=0; 620 621 nofault = (int *) 0; 622 statreg = esc->sc_reg + NCR_STAT * 16; 623 for (;;) { 624 if (*statreg & 0x80) { 625 goto gotintr; 626 } 627 628 if (esp_have_dreq(esc)) { 629 break; 630 } 631 632 DELAY(1); 633 if (i++ > 10000) 634 panic("esp_dma_go: Argh!"); 635 } 636 goto restart_dmago; 637 } 638 639 statreg = esc->sc_reg + NCR_STAT * 16; 640 pdma = (u_int16_t *) (esc->sc_reg + 0x100); 641 642 #define WAIT while (!esp_have_dreq(esc)) if (*statreg & 0x80) goto gotintr 643 644 if (esc->sc_datain == 0) { 645 while (esc->sc_pdmalen) { 646 WAIT; 647 __spl6(); *pdma = *(esc->sc_pdmaddr)++; __spl2() 648 esc->sc_pdmalen -= 2; 649 } 650 if (esc->sc_pad) { 651 unsigned short us; 652 unsigned char *c; 653 c = (unsigned char *) esc->sc_pdmaddr; 654 us = *c; 655 WAIT; 656 __spl6(); *pdma = us; __spl2() 657 } 658 } else { 659 while (esc->sc_pdmalen) { 660 WAIT; 661 __spl6(); *(esc->sc_pdmaddr)++ = *pdma; __spl2() 662 esc->sc_pdmalen -= 2; 663 } 664 if (esc->sc_pad) { 665 unsigned short us; 666 unsigned char *c; 667 WAIT; 668 __spl6(); us = *pdma; __spl2() 669 c = (unsigned char *) esc->sc_pdmaddr; 670 *c = us & 0xff; 671 } 672 } 673 #undef WAIT 674 675 nofault = (int *) 0; 676 677 if ((*statreg & 0x80) == 0) { 678 if (espspl != -1) splx(espspl); espspl = -1; 679 return; 680 } 681 682 gotintr: 683 ncr53c9x_intr(sc); 684 if (espspl != -1) splx(espspl); espspl = -1; 685 } 686 687 void 688 esp_intr(sc) 689 void *sc; 690 { 691 struct esp_softc *esc = (struct esp_softc *)sc; 692 int i = 0; 693 694 do { 695 if (esc->sc_reg[NCR_STAT * 16] & 0x80) { 696 ncr53c9x_intr((struct ncr53c9x_softc *) esp0); 697 i++; 698 } 699 700 if (!i) { 701 delay(10000); 702 } 703 } while (!i++); 704 } 705 706 void 707 esp_dualbus_intr(sc) 708 void *sc; 709 { 710 int i = 0; 711 712 do { 713 if (esp0 && (esp0->sc_reg[NCR_STAT * 16] & 0x80)) { 714 ncr53c9x_intr((struct ncr53c9x_softc *) esp0); 715 i++; 716 } 717 718 if (esp1 && (esp1->sc_reg[NCR_STAT * 16] & 0x80)) { 719 ncr53c9x_intr((struct ncr53c9x_softc *) esp1); 720 i++; 721 } 722 723 if (!i) { 724 delay(10000); 725 } 726 } while (!i++); 727 } 728