esp.c revision 1.18
1/* $NetBSD: esp.c,v 1.18 1998/10/10 00:28:30 thorpej 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 108void espattach __P((struct device *, struct device *, void *)); 109int espmatch __P((struct device *, struct cfdata *, void *)); 110 111/* Linkup to the rest of the kernel */ 112struct cfattach esp_ca = { 113 sizeof(struct esp_softc), espmatch, espattach 114}; 115 116struct scsipi_adapter esp_switch = { 117 ncr53c9x_scsi_cmd, 118 minphys, /* no max at this level; handled by DMA code */ 119 NULL, /* scsipi_ioctl */ 120}; 121 122struct scsipi_device esp_dev = { 123 NULL, /* Use default error handler */ 124 NULL, /* have a queue, served by this */ 125 NULL, /* have no async handler */ 126 NULL, /* Use default 'done' routine */ 127}; 128 129/* 130 * Functions and the switch for the MI code. 131 */ 132u_char esp_read_reg __P((struct ncr53c9x_softc *, int)); 133void esp_write_reg __P((struct ncr53c9x_softc *, int, u_char)); 134int esp_dma_isintr __P((struct ncr53c9x_softc *)); 135void esp_dma_reset __P((struct ncr53c9x_softc *)); 136int esp_dma_intr __P((struct ncr53c9x_softc *)); 137int esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *, 138 size_t *, int, size_t *)); 139void esp_dma_go __P((struct ncr53c9x_softc *)); 140void esp_dma_stop __P((struct ncr53c9x_softc *)); 141int esp_dma_isactive __P((struct ncr53c9x_softc *)); 142void esp_quick_write_reg __P((struct ncr53c9x_softc *, int, u_char)); 143int esp_quick_dma_intr __P((struct ncr53c9x_softc *)); 144int esp_quick_dma_setup __P((struct ncr53c9x_softc *, caddr_t *, 145 size_t *, int, size_t *)); 146void esp_quick_dma_go __P((struct ncr53c9x_softc *)); 147 148int esp_dualbus_intr __P((register struct ncr53c9x_softc *sc)); 149static struct esp_softc *esp0 = NULL, *esp1 = NULL; 150 151static __inline__ int esp_dafb_have_dreq __P((struct esp_softc *esc)); 152static __inline__ int esp_iosb_have_dreq __P((struct esp_softc *esc)); 153int (*esp_have_dreq) __P((struct esp_softc *esc)); 154 155struct ncr53c9x_glue esp_glue = { 156 esp_read_reg, 157 esp_write_reg, 158 esp_dma_isintr, 159 esp_dma_reset, 160 esp_dma_intr, 161 esp_dma_setup, 162 esp_dma_go, 163 esp_dma_stop, 164 esp_dma_isactive, 165 NULL, /* gl_clear_latched_intr */ 166}; 167 168int 169espmatch(parent, cf, aux) 170 struct device *parent; 171 struct cfdata *cf; 172 void *aux; 173{ 174 int found = 0; 175 176 if ((cf->cf_unit == 0) && mac68k_machine.scsi96) { 177 found = 1; 178 } 179 if ((cf->cf_unit == 1) && mac68k_machine.scsi96_2) { 180 found = 1; 181 } 182 183 return found; 184} 185 186/* 187 * Attach this instance, and then all the sub-devices 188 */ 189void 190espattach(parent, self, aux) 191 struct device *parent, *self; 192 void *aux; 193{ 194 struct obio_attach_args *oa = (struct obio_attach_args *)aux; 195 extern vm_offset_t SCSIBase; 196 struct esp_softc *esc = (void *)self; 197 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 198 int quick = 0; 199 unsigned long reg_offset; 200 201 reg_offset = SCSIBase - IOBase; 202 esc->sc_tag = oa->oa_tag; 203 /* 204 * For Wombat, Primus and Optimus motherboards, DREQ is 205 * visible on bit 0 of the IOSB's emulated VIA2 vIFR (and 206 * the scsi registers are offset 0x1000 bytes from IOBase). 207 * 208 * For the Q700/900/950 it's at f9800024 for bus 0 and 209 * f9800028 for bus 1 (900/950). For these machines, that is also 210 * a (12-bit) configuration register for DAFB's control of the 211 * pseudo-DMA timing. The default value is 0x1d1. 212 */ 213 esp_have_dreq = esp_dafb_have_dreq; 214 if (sc->sc_dev.dv_unit == 0) { 215 if (reg_offset == 0x10000) { 216 quick = 1; 217 esp_have_dreq = esp_iosb_have_dreq; 218 } else if (reg_offset == 0x18000) { 219 quick = 0; 220 } else { 221 if (bus_space_map(esc->sc_tag, 0xf9800024, 222 4, 0, &esc->sc_bsh)) { 223 printf("failed to map 4 at 0xf9800024.\n"); 224 } else { 225 quick = 1; 226 bus_space_write_4(esc->sc_tag, 227 esc->sc_bsh, 0, 0x1d1); 228 } 229 } 230 } else { 231 if (bus_space_map(esc->sc_tag, 0xf9800028, 232 4, 0, &esc->sc_bsh)) { 233 printf("failed to map 4 at 0xf9800028.\n"); 234 } else { 235 quick = 1; 236 bus_space_write_4(esc->sc_tag, esc->sc_bsh, 0, 0x1d1); 237 } 238 } 239 if (quick) { 240 esp_glue.gl_write_reg = esp_quick_write_reg; 241 esp_glue.gl_dma_intr = esp_quick_dma_intr; 242 esp_glue.gl_dma_setup = esp_quick_dma_setup; 243 esp_glue.gl_dma_go = esp_quick_dma_go; 244 } 245 246 /* 247 * Set up the glue for MI code early; we use some of it here. 248 */ 249 sc->sc_glue = &esp_glue; 250 251 /* 252 * Save the regs 253 */ 254 if (sc->sc_dev.dv_unit == 0) { 255 esp0 = esc; 256 257 esc->sc_reg = (volatile u_char *) SCSIBase; 258 via2_register_irq(VIA2_SCSIIRQ, 259 (void (*)(void *))ncr53c9x_intr, esc); 260 esc->irq_mask = V2IF_SCSIIRQ; 261 if (reg_offset == 0x10000) { 262 sc->sc_freq = 16500000; 263 } else { 264 sc->sc_freq = 25000000; 265 } 266 267 if (esp_glue.gl_dma_go == esp_quick_dma_go) { 268 printf(" (quick)"); 269 } 270 } else { 271 esp1 = esc; 272 273 esc->sc_reg = (volatile u_char *) SCSIBase + 0x402; 274 via2_register_irq(VIA2_SCSIIRQ, 275 (void (*)(void *))esp_dualbus_intr, NULL); 276 esc->irq_mask = 0; 277 sc->sc_freq = 25000000; 278 279 if (esp_glue.gl_dma_go == esp_quick_dma_go) { 280 printf(" (quick)"); 281 } 282 } 283 284 printf(": address %p", esc->sc_reg); 285 286 sc->sc_id = 7; 287 288 /* gimme Mhz */ 289 sc->sc_freq /= 1000000; 290 291 /* 292 * It is necessary to try to load the 2nd config register here, 293 * to find out what rev the esp chip is, else the esp_reset 294 * will not set up the defaults correctly. 295 */ 296 sc->sc_cfg1 = sc->sc_id; /* | NCRCFG1_PARENB; */ 297 sc->sc_cfg2 = NCRCFG2_SCSI2; 298 sc->sc_cfg3 = 0; 299 sc->sc_rev = NCR_VARIANT_NCR53C96; 300 301 /* 302 * This is the value used to start sync negotiations 303 * Note that the NCR register "SYNCTP" is programmed 304 * in "clocks per byte", and has a minimum value of 4. 305 * The SCSI period used in negotiation is one-fourth 306 * of the time (in nanoseconds) needed to transfer one byte. 307 * Since the chip's clock is given in MHz, we have the following 308 * formula: 4 * period = (1000 / freq) * 4 309 */ 310 sc->sc_minsync = 1000 / sc->sc_freq; 311 312 sc->sc_minsync = 0; /* No synchronous xfers w/o DMA */ 313 /* Really no limit, but since we want to fit into the TCR... */ 314 sc->sc_maxxfer = 8 * 1024; /*64 * 1024; XXX */ 315 316 /* 317 * Now try to attach all the sub-devices 318 */ 319 ncr53c9x_attach(sc, &esp_switch, &esp_dev); 320 321 /* 322 * Configure interrupts. 323 */ 324 if (esc->irq_mask) { 325 via2_reg(vPCR) = 0x22; 326 via2_reg(vIFR) = esc->irq_mask; 327 via2_reg(vIER) = 0x80 | esc->irq_mask; 328 } 329} 330 331/* 332 * Glue functions. 333 */ 334 335u_char 336esp_read_reg(sc, reg) 337 struct ncr53c9x_softc *sc; 338 int reg; 339{ 340 struct esp_softc *esc = (struct esp_softc *)sc; 341 342 return esc->sc_reg[reg * 16]; 343} 344 345void 346esp_write_reg(sc, reg, val) 347 struct ncr53c9x_softc *sc; 348 int reg; 349 u_char val; 350{ 351 struct esp_softc *esc = (struct esp_softc *)sc; 352 u_char v = val; 353 354 if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) { 355 v = NCRCMD_TRANS; 356 } 357 esc->sc_reg[reg * 16] = v; 358} 359 360void 361esp_dma_stop(sc) 362 struct ncr53c9x_softc *sc; 363{ 364} 365 366int 367esp_dma_isactive(sc) 368 struct ncr53c9x_softc *sc; 369{ 370 struct esp_softc *esc = (struct esp_softc *)sc; 371 372 return esc->sc_active; 373} 374 375int 376esp_dma_isintr(sc) 377 struct ncr53c9x_softc *sc; 378{ 379 struct esp_softc *esc = (struct esp_softc *)sc; 380 381 return esc->sc_reg[NCR_STAT * 16] & 0x80; 382} 383 384void 385esp_dma_reset(sc) 386 struct ncr53c9x_softc *sc; 387{ 388 struct esp_softc *esc = (struct esp_softc *)sc; 389 390 esc->sc_active = 0; 391 esc->sc_tc = 0; 392} 393 394int 395esp_dma_intr(sc) 396 struct ncr53c9x_softc *sc; 397{ 398 register struct esp_softc *esc = (struct esp_softc *)sc; 399 register u_char *p; 400 volatile u_char *cmdreg, *intrreg, *statreg, *fiforeg; 401 register u_int espphase, espstat, espintr; 402 register int cnt; 403 404 if (esc->sc_active == 0) { 405 printf("dma_intr--inactive DMA\n"); 406 return -1; 407 } 408 409 if ((sc->sc_espintr & NCRINTR_BS) == 0) { 410 esc->sc_active = 0; 411 return 0; 412 } 413 414 cnt = *esc->sc_dmalen; 415 if (*esc->sc_dmalen == 0) { 416 printf("data interrupt, but no count left."); 417 } 418 419 p = *esc->sc_dmaaddr; 420 espphase = sc->sc_phase; 421 espstat = (u_int) sc->sc_espstat; 422 espintr = (u_int) sc->sc_espintr; 423 cmdreg = esc->sc_reg + NCR_CMD * 16; 424 fiforeg = esc->sc_reg + NCR_FIFO * 16; 425 statreg = esc->sc_reg + NCR_STAT * 16; 426 intrreg = esc->sc_reg + NCR_INTR * 16; 427 do { 428 if (esc->sc_datain) { 429 *p++ = *fiforeg; 430 cnt--; 431 if (espphase == DATA_IN_PHASE) { 432 *cmdreg = NCRCMD_TRANS; 433 } else { 434 esc->sc_active = 0; 435 } 436 } else { 437 if ( (espphase == DATA_OUT_PHASE) 438 || (espphase == MESSAGE_OUT_PHASE)) { 439 *fiforeg = *p++; 440 cnt--; 441 *cmdreg = NCRCMD_TRANS; 442 } else { 443 esc->sc_active = 0; 444 } 445 } 446 447 if (esc->sc_active) { 448 while (!(*statreg & 0x80)); 449 espstat = *statreg; 450 espintr = *intrreg; 451 espphase = (espintr & NCRINTR_DIS) 452 ? /* Disconnected */ BUSFREE_PHASE 453 : espstat & PHASE_MASK; 454 } 455 } while (esc->sc_active && (espintr & NCRINTR_BS)); 456 sc->sc_phase = espphase; 457 sc->sc_espstat = (u_char) espstat; 458 sc->sc_espintr = (u_char) espintr; 459 *esc->sc_dmaaddr = p; 460 *esc->sc_dmalen = cnt; 461 462 if (*esc->sc_dmalen == 0) { 463 esc->sc_tc = NCRSTAT_TC; 464 } 465 sc->sc_espstat |= esc->sc_tc; 466 return 0; 467} 468 469int 470esp_dma_setup(sc, addr, len, datain, dmasize) 471 struct ncr53c9x_softc *sc; 472 caddr_t *addr; 473 size_t *len; 474 int datain; 475 size_t *dmasize; 476{ 477 struct esp_softc *esc = (struct esp_softc *)sc; 478 479 esc->sc_dmaaddr = addr; 480 esc->sc_dmalen = len; 481 esc->sc_datain = datain; 482 esc->sc_dmasize = *dmasize; 483 esc->sc_tc = 0; 484 485 return 0; 486} 487 488void 489esp_dma_go(sc) 490 struct ncr53c9x_softc *sc; 491{ 492 struct esp_softc *esc = (struct esp_softc *)sc; 493 494 if (esc->sc_datain == 0) { 495 esc->sc_reg[NCR_FIFO * 16] = **esc->sc_dmaaddr; 496 (*esc->sc_dmalen)--; 497 (*esc->sc_dmaaddr)++; 498 } 499 esc->sc_active = 1; 500} 501 502void 503esp_quick_write_reg(sc, reg, val) 504 struct ncr53c9x_softc *sc; 505 int reg; 506 u_char val; 507{ 508 struct esp_softc *esc = (struct esp_softc *)sc; 509 u_char v = val; 510 511 esc->sc_reg[reg * 16] = v; 512} 513 514int 515esp_quick_dma_intr(sc) 516 struct ncr53c9x_softc *sc; 517{ 518 struct esp_softc *esc = (struct esp_softc *)sc; 519 int trans=0, resid=0; 520 521 if (esc->sc_active == 0) 522 panic("dma_intr--inactive DMA\n"); 523 524 esc->sc_active = 0; 525 526 if (esc->sc_dmasize == 0) { 527 int res; 528 529 res = 65536; 530 res -= NCR_READ_REG(sc, NCR_TCL); 531 res -= NCR_READ_REG(sc, NCR_TCM) << 8; 532 printf("dmaintr: discarded %d b (last transfer was %d b).\n", 533 res, esc->sc_prevdmasize); 534 return 0; 535 } 536 537 if (esc->sc_datain && 538 (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) { 539 printf("dmaintr: empty FIFO of %d\n", resid); 540 DELAY(1); 541 } 542 543 if ((sc->sc_espstat & NCRSTAT_TC) == 0) { 544 resid += NCR_READ_REG(sc, NCR_TCL); 545 resid += NCR_READ_REG(sc, NCR_TCM) << 8; 546 547 if (resid == 0) 548 resid = 65536; 549 } 550 551 trans = esc->sc_dmasize - resid; 552 if (trans < 0) { 553 printf("dmaintr: trans < 0????"); 554 trans = esc->sc_dmasize; 555 } 556 557 NCR_DMA(("dmaintr: trans %d, resid %d.\n", trans, resid)); 558 *esc->sc_dmaaddr += trans; 559 *esc->sc_dmalen -= trans; 560 561 return 0; 562} 563 564int 565esp_quick_dma_setup(sc, addr, len, datain, dmasize) 566 struct ncr53c9x_softc *sc; 567 caddr_t *addr; 568 size_t *len; 569 int datain; 570 size_t *dmasize; 571{ 572 struct esp_softc *esc = (struct esp_softc *)sc; 573 574 esc->sc_dmaaddr = addr; 575 esc->sc_dmalen = len; 576 577 esc->sc_pdmaddr = (u_int16_t *) *addr; 578 esc->sc_pdmalen = *len; 579 if (esc->sc_pdmalen & 1) { 580 esc->sc_pdmalen--; 581 esc->sc_pad = 1; 582 } else { 583 esc->sc_pad = 0; 584 } 585 586 esc->sc_datain = datain; 587 esc->sc_prevdmasize = esc->sc_dmasize; 588 esc->sc_dmasize = *dmasize; 589 590 return 0; 591} 592 593static __inline__ int 594esp_dafb_have_dreq(esc) 595 struct esp_softc *esc; 596{ 597 u_int32_t r; 598 599 r = bus_space_read_4(esc->sc_tag, esc->sc_bsh, 0); 600 return (r & 0x200); 601} 602 603static __inline__ int 604esp_iosb_have_dreq(esc) 605 struct esp_softc *esc; 606{ 607 return (via2_reg(vIFR) & V2IF_SCSIDRQ); 608} 609 610static int espspl=-1; 611#define __splx(s) __asm __volatile ("movew %0,sr" : : "di" (s)); 612#define __spl2() __splx(PSL_S|PSL_IPL2) 613#define __spl4() __splx(PSL_S|PSL_IPL4) 614 615void 616esp_quick_dma_go(sc) 617 struct ncr53c9x_softc *sc; 618{ 619 struct esp_softc *esc = (struct esp_softc *)sc; 620 extern int *nofault; 621 label_t faultbuf; 622 u_int16_t volatile *pdma; 623 u_char volatile *statreg; 624 625 esc->sc_active = 1; 626 627 espspl = spl2(); 628 629restart_dmago: 630 nofault = (int *) &faultbuf; 631 if (setjmp((label_t *) nofault)) { 632 int i=0; 633 634 nofault = (int *) 0; 635 statreg = esc->sc_reg + NCR_STAT * 16; 636 for (;;) { 637 if (*statreg & 0x80) { 638 goto gotintr; 639 } 640 641 if (esp_have_dreq(esc)) { 642 break; 643 } 644 645 DELAY(1); 646 if (i++ > 10000) 647 panic("esp_dma_go: Argh!"); 648 } 649 goto restart_dmago; 650 } 651 652 statreg = esc->sc_reg + NCR_STAT * 16; 653 pdma = (u_int16_t *) (esc->sc_reg + 0x100); 654 655#define WAIT while (!esp_have_dreq(esc)) if (*statreg & 0x80) goto gotintr 656 657 if (esc->sc_datain == 0) { 658 while (esc->sc_pdmalen) { 659 WAIT; 660 __spl4(); *pdma = *(esc->sc_pdmaddr)++; __spl2() 661 esc->sc_pdmalen -= 2; 662 } 663 if (esc->sc_pad) { 664 unsigned short us; 665 unsigned char *c; 666 c = (unsigned char *) esc->sc_pdmaddr; 667 us = *c; 668 WAIT; 669 __spl4(); *pdma = us; __spl2() 670 } 671 } else { 672 while (esc->sc_pdmalen) { 673 WAIT; 674 __spl4(); *(esc->sc_pdmaddr)++ = *pdma; __spl2() 675 esc->sc_pdmalen -= 2; 676 } 677 if (esc->sc_pad) { 678 unsigned short us; 679 unsigned char *c; 680 WAIT; 681 __spl4(); us = *pdma; __spl2() 682 c = (unsigned char *) esc->sc_pdmaddr; 683 *c = us & 0xff; 684 } 685 } 686#undef WAIT 687 688 nofault = (int *) 0; 689 690 if ((*statreg & 0x80) == 0) { 691 if (espspl != -1) splx(espspl); espspl = -1; 692 return; 693 } 694 695gotintr: 696 ncr53c9x_intr(sc); 697 if (espspl != -1) splx(espspl); espspl = -1; 698} 699 700int 701esp_dualbus_intr(sc) 702 register struct ncr53c9x_softc *sc; 703{ 704 if (esp0 && (esp0->sc_reg[NCR_STAT * 16] & 0x80)) 705 ncr53c9x_intr((struct ncr53c9x_softc *) esp0); 706 707 if (esp1 && (esp1->sc_reg[NCR_STAT * 16] & 0x80)) 708 ncr53c9x_intr((struct ncr53c9x_softc *) esp1); 709 710 return 0; 711} 712