1/* $NetBSD: lsi64854.c,v 1.40 2022/09/25 18:43:32 thorpej Exp $ */ 2 3/*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Paul Kranenburg. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33__KERNEL_RCSID(0, "$NetBSD: lsi64854.c,v 1.40 2022/09/25 18:43:32 thorpej Exp $"); 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/errno.h> 39#include <sys/device.h> 40 41#include <sys/bus.h> 42#include <machine/autoconf.h> 43#include <sys/cpu.h> 44 45#include <dev/scsipi/scsi_all.h> 46#include <dev/scsipi/scsipi_all.h> 47#include <dev/scsipi/scsiconf.h> 48 49#include <dev/ic/lsi64854reg.h> 50#include <dev/ic/lsi64854var.h> 51 52#include <dev/ic/ncr53c9xreg.h> 53#include <dev/ic/ncr53c9xvar.h> 54 55void lsi64854_reset(struct lsi64854_softc *); 56int lsi64854_setup(struct lsi64854_softc *, uint8_t **, size_t *, 57 int, size_t *); 58int lsi64854_setup_pp(struct lsi64854_softc *, uint8_t **, size_t *, 59 int, size_t *); 60 61#ifdef DEBUG 62#define LDB_SCSI 1 63#define LDB_ENET 2 64#define LDB_PP 4 65#define LDB_ANY 0xff 66int lsi64854debug = 0; 67#define DPRINTF(a,x) do { if (lsi64854debug & (a)) printf x ; } while (0) 68#else 69#define DPRINTF(a,x) 70#endif 71 72#define MAX_DMA_SZ (16 * 1024 * 1024) 73 74/* 75 * Finish attaching this DMA device. 76 * Front-end must fill in these fields: 77 * sc_bustag 78 * sc_dmatag 79 * sc_regs 80 * sc_burst 81 * sc_channel (one of SCSI, ENET, PP) 82 * sc_client (one of SCSI, ENET, PP `soft_c' pointers) 83 */ 84void 85lsi64854_attach(struct lsi64854_softc *sc) 86{ 87 uint32_t csr; 88 89 /* Indirect functions */ 90 switch (sc->sc_channel) { 91 case L64854_CHANNEL_SCSI: 92 sc->intr = lsi64854_scsi_intr; 93 sc->setup = lsi64854_setup; 94 break; 95 case L64854_CHANNEL_ENET: 96 sc->intr = lsi64854_enet_intr; 97 break; 98 case L64854_CHANNEL_PP: 99 sc->setup = lsi64854_setup_pp; 100 break; 101 default: 102 aprint_error(": unknown channel"); 103 } 104 sc->reset = lsi64854_reset; 105 106 /* Allocate a dmamap */ 107 if (bus_dmamap_create(sc->sc_dmatag, MAX_DMA_SZ, 1, MAX_DMA_SZ, 108 0, BUS_DMA_WAITOK, &sc->sc_dmamap) != 0) { 109 aprint_error(": DMA map create failed\n"); 110 return; 111 } 112 113 csr = L64854_GCSR(sc); 114 sc->sc_rev = csr & L64854_DEVID; 115 if (sc->sc_rev == DMAREV_HME) { 116 return; 117 } 118 aprint_normal(": DMA rev "); 119 switch (sc->sc_rev) { 120 case DMAREV_0: 121 aprint_normal("0"); 122 break; 123 case DMAREV_ESC: 124 aprint_normal("esc"); 125 break; 126 case DMAREV_1: 127 aprint_normal("1"); 128 break; 129 case DMAREV_PLUS: 130 aprint_normal("1+"); 131 break; 132 case DMAREV_2: 133 aprint_normal("2"); 134 break; 135 default: 136 aprint_normal("unknown (0x%x)", sc->sc_rev); 137 } 138 139 DPRINTF(LDB_ANY, (", burst 0x%x, csr 0x%x", sc->sc_burst, csr)); 140 aprint_normal("\n"); 141} 142 143/* 144 * DMAWAIT waits while condition is true 145 */ 146#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \ 147 int count = 500000; \ 148 while ((COND) && --count > 0) DELAY(1); \ 149 if (count == 0) { \ 150 printf("%s: line %d: CSR = 0x%lx\n", __FILE__, __LINE__, \ 151 (u_long)L64854_GCSR(SC)); \ 152 if (DONTPANIC) \ 153 printf(MSG); \ 154 else \ 155 panic(MSG); \ 156 } \ 157} while (/* CONSTCOND */ 0) 158 159#define DMA_DRAIN(sc, dontpanic) do { \ 160 uint32_t _csr; \ 161 /* \ 162 * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \ 163 * and "drain" bits while it is still thinking about a \ 164 * request. \ 165 * other revs: D_ESC_R_PEND bit reads as 0 \ 166 */ \ 167 DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\ 168 if (sc->sc_rev != DMAREV_HME) { \ 169 /* \ 170 * Select drain bit based on revision \ 171 * also clears errors and D_TC flag \ 172 */ \ 173 _csr = L64854_GCSR(sc); \ 174 if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0) \ 175 _csr |= D_ESC_DRAIN; \ 176 else \ 177 _csr |= L64854_INVALIDATE; \ 178 \ 179 L64854_SCSR(sc,_csr); \ 180 } \ 181 /* \ 182 * Wait for draining to finish \ 183 * rev0 & rev1 call this PACKCNT \ 184 */ \ 185 DMAWAIT(sc, L64854_GCSR(sc) & L64854_DRAINING, "DRAINING", dontpanic);\ 186} while (/* CONSTCOND */ 0) 187 188#define DMA_FLUSH(sc, dontpanic) do { \ 189 uint32_t _csr; \ 190 /* \ 191 * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \ 192 * and "drain" bits while it is still thinking about a \ 193 * request. \ 194 * other revs: D_ESC_R_PEND bit reads as 0 \ 195 */ \ 196 DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\ 197 _csr = L64854_GCSR(sc); \ 198 _csr &= ~(L64854_WRITE | L64854_EN_DMA); /* no-ops on ENET */ \ 199 _csr |= L64854_INVALIDATE; /* XXX FAS ? */ \ 200 L64854_SCSR(sc,_csr); \ 201} while (/* CONSTCOND */ 0) 202 203void 204lsi64854_reset(struct lsi64854_softc *sc) 205{ 206 uint32_t csr; 207 208 DMA_FLUSH(sc, 1); 209 csr = L64854_GCSR(sc); 210 211 DPRINTF(LDB_ANY, ("%s: csr 0x%x\n", __func__, csr)); 212 213 /* 214 * XXX is sync needed? 215 */ 216 if (sc->sc_dmamap->dm_nsegs > 0) 217 bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap); 218 219 if (sc->sc_rev == DMAREV_HME) 220 L64854_SCSR(sc, csr | D_HW_RESET_FAS366); 221 222 223 csr |= L64854_RESET; /* reset DMA */ 224 L64854_SCSR(sc, csr); 225 DELAY(200); /* > 10 Sbus clocks(?) */ 226 227 /*DMAWAIT1(sc); why was this here? */ 228 csr = L64854_GCSR(sc); 229 csr &= ~L64854_RESET; /* de-assert reset line */ 230 L64854_SCSR(sc, csr); 231 DELAY(5); /* allow a few ticks to settle */ 232 233 csr = L64854_GCSR(sc); 234 csr |= L64854_INT_EN; /* enable interrupts */ 235 if (sc->sc_rev > DMAREV_1 && sc->sc_channel == L64854_CHANNEL_SCSI) { 236 if (sc->sc_rev == DMAREV_HME) 237 csr |= D_TWO_CYCLE; 238 else 239 csr |= D_FASTER; 240 } 241 242 /* Set burst */ 243 switch (sc->sc_rev) { 244 case DMAREV_HME: 245 case DMAREV_2: 246 csr &= ~L64854_BURST_SIZE; 247 if (sc->sc_burst == 32) { 248 csr |= L64854_BURST_32; 249 } else if (sc->sc_burst == 16) { 250 csr |= L64854_BURST_16; 251 } else { 252 csr |= L64854_BURST_0; 253 } 254 break; 255 case DMAREV_ESC: 256 csr |= D_ESC_AUTODRAIN; /* Auto-drain */ 257 if (sc->sc_burst == 32) { 258 csr &= ~D_ESC_BURST; 259 } else 260 csr |= D_ESC_BURST; 261 break; 262 default: 263 break; 264 } 265 L64854_SCSR(sc, csr); 266 267 if (sc->sc_rev == DMAREV_HME) { 268 bus_space_write_4(sc->sc_bustag, sc->sc_regs, 269 L64854_REG_ADDR, 0); 270 sc->sc_dmactl = csr; 271 } 272 sc->sc_active = 0; 273 274 DPRINTF(LDB_ANY, ("%s: done, csr 0x%x\n", __func__, csr)); 275} 276 277 278#define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ-1))) 279/* 280 * setup a DMA transfer 281 */ 282int 283lsi64854_setup(struct lsi64854_softc *sc, uint8_t **addr, size_t *len, 284 int datain, size_t *dmasize) 285{ 286 uint32_t csr; 287 288 DMA_FLUSH(sc, 0); 289 290#if 0 291 DMACSR(sc) &= ~D_INT_EN; 292#endif 293 sc->sc_dmaaddr = addr; 294 sc->sc_dmalen = len; 295 296 /* 297 * the rules say we cannot transfer more than the limit 298 * of this DMA chip (64k for old and 16Mb for new), 299 * and we cannot cross a 16Mb boundary. 300 */ 301 *dmasize = sc->sc_dmasize = 302 uimin(*dmasize, DMAMAX((size_t)*sc->sc_dmaaddr)); 303 304 DPRINTF(LDB_ANY, ("%s: dmasize = %ld\n", 305 __func__, (long)sc->sc_dmasize)); 306 307 /* 308 * XXX what length? 309 */ 310 if (sc->sc_rev == DMAREV_HME) { 311 312 L64854_SCSR(sc, sc->sc_dmactl | L64854_RESET); 313 L64854_SCSR(sc, sc->sc_dmactl); 314 315 bus_space_write_4(sc->sc_bustag, sc->sc_regs, 316 L64854_REG_CNT, *dmasize); 317 } 318 319 /* Program the DMA address */ 320 if (sc->sc_dmasize) { 321 sc->sc_dvmaaddr = *sc->sc_dmaaddr; 322 if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, 323 *sc->sc_dmaaddr, sc->sc_dmasize, 324 NULL /* kernel address */, 325 BUS_DMA_NOWAIT | BUS_DMA_STREAMING)) 326 panic("%s: cannot allocate DVMA address", 327 device_xname(sc->sc_dev)); 328 bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize, 329 datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 330 bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR, 331 sc->sc_dmamap->dm_segs[0].ds_addr); 332 } 333 334 if (sc->sc_rev == DMAREV_ESC) { 335 /* DMA ESC chip bug work-around */ 336 long bcnt = sc->sc_dmasize; 337 long eaddr = bcnt + (long)*sc->sc_dmaaddr; 338 339 if ((eaddr & PGOFSET) != 0) 340 bcnt = roundup(bcnt, PAGE_SIZE); 341 bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_CNT, 342 bcnt); 343 } 344 345 /* Setup DMA control register */ 346 csr = L64854_GCSR(sc); 347 348 if (datain) 349 csr |= L64854_WRITE; 350 else 351 csr &= ~L64854_WRITE; 352 csr |= L64854_INT_EN; 353 354 if (sc->sc_rev == DMAREV_HME) { 355 csr |= (D_DSBL_SCSI_DRN | D_EN_DMA); 356 } 357 358 L64854_SCSR(sc, csr); 359 360 return 0; 361} 362 363/* 364 * Pseudo (chained) interrupt from the esp driver to kick the 365 * current running DMA transfer. Called from ncr53c9x_intr() 366 * for now. 367 * 368 * return 1 if it was a DMA continue. 369 */ 370int 371lsi64854_scsi_intr(void *arg) 372{ 373 struct lsi64854_softc *sc = arg; 374 struct ncr53c9x_softc *nsc = sc->sc_client; 375 char bits[64]; 376 int trans, resid; 377 uint32_t csr; 378 379 csr = L64854_GCSR(sc); 380#ifdef DEBUG 381 snprintb(bits, sizeof(bits), DDMACSR_BITS, csr); 382#endif 383 DPRINTF(LDB_SCSI, ("%s: %s: addr 0x%x, csr %s\n", 384 device_xname(sc->sc_dev), __func__, 385 bus_space_read_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR), 386 bits)); 387 388 389 if (csr & (D_ERR_PEND|D_SLAVE_ERR)) { 390 snprintb(bits, sizeof(bits), DDMACSR_BITS, csr); 391 printf("%s: error: csr=%s\n", device_xname(sc->sc_dev), bits); 392 csr &= ~D_EN_DMA; /* Stop DMA */ 393 /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */ 394 csr |= D_INVALIDATE|D_SLAVE_ERR; 395 L64854_SCSR(sc, csr); 396 return -1; 397 } 398 399 /* This is an "assertion" :) */ 400 if (sc->sc_active == 0) 401 panic("%s: DMA wasn't active", __func__); 402 403 DMA_DRAIN(sc, 0); 404 405 /* DMA has stopped */ 406 csr &= ~D_EN_DMA; 407 L64854_SCSR(sc, csr); 408 sc->sc_active = 0; 409 410 if (sc->sc_dmasize == 0) { 411 /* A "Transfer Pad" operation completed */ 412 DPRINTF(LDB_SCSI, ("%s: discarded %d bytes (tcl=%d, tcm=%d)\n", 413 __func__, 414 NCR_READ_REG(nsc, NCR_TCL) | 415 (NCR_READ_REG(nsc, NCR_TCM) << 8), 416 NCR_READ_REG(nsc, NCR_TCL), 417 NCR_READ_REG(nsc, NCR_TCM))); 418 return 0; 419 } 420 421 resid = 0; 422 /* 423 * If a transfer onto the SCSI bus gets interrupted by the device 424 * (e.g. for a SAVEPOINTER message), the data in the FIFO counts 425 * as residual since the NCR53C9X counter registers get decremented 426 * as bytes are clocked into the FIFO. 427 */ 428 if (!(csr & D_WRITE) && 429 (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) { 430 DPRINTF(LDB_SCSI, ("%s: empty esp FIFO of %d ", 431 __func__, resid)); 432 if (nsc->sc_rev == NCR_VARIANT_FAS366 && 433 (NCR_READ_REG(nsc, NCR_CFG3) & NCRFASCFG3_EWIDE)) 434 resid <<= 1; 435 } 436 437 if ((nsc->sc_espstat & NCRSTAT_TC) == 0) { 438 /* 439 * `Terminal count' is off, so read the residue 440 * out of the NCR53C9X counter registers. 441 */ 442 resid += (NCR_READ_REG(nsc, NCR_TCL) | 443 (NCR_READ_REG(nsc, NCR_TCM) << 8) | 444 ((nsc->sc_cfg2 & NCRCFG2_FE) ? 445 (NCR_READ_REG(nsc, NCR_TCH) << 16) : 0)); 446 447 if (resid == 0 && sc->sc_dmasize == 65536 && 448 (nsc->sc_cfg2 & NCRCFG2_FE) == 0) 449 /* A transfer of 64K is encoded as `TCL=TCM=0' */ 450 resid = 65536; 451 } 452 453 trans = sc->sc_dmasize - resid; 454 if (trans < 0) { /* transferred < 0 ? */ 455#if 0 456 /* 457 * This situation can happen in perfectly normal operation 458 * if the ESP is reselected while using DMA to select 459 * another target. As such, don't print the warning. 460 */ 461 printf("%s: xfer (%d) > req (%d)\n", 462 device_xname(sc->sc_dev), trans, sc->sc_dmasize); 463#endif 464 trans = sc->sc_dmasize; 465 } 466 467 DPRINTF(LDB_SCSI, ("%s: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n", 468 __func__, 469 NCR_READ_REG(nsc, NCR_TCL), 470 NCR_READ_REG(nsc, NCR_TCM), 471 (nsc->sc_cfg2 & NCRCFG2_FE) ? 472 NCR_READ_REG(nsc, NCR_TCH) : 0, 473 trans, resid)); 474 475 if (sc->sc_dmamap->dm_nsegs > 0) { 476 bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize, 477 (csr & D_WRITE) != 0 ? 478 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 479 bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap); 480 } 481 482 *sc->sc_dmalen -= trans; 483 *sc->sc_dmaaddr += trans; 484 485#if 0 /* this is not normal operation just yet */ 486 if (*sc->sc_dmalen == 0 || 487 nsc->sc_phase != nsc->sc_prevphase) 488 return 0; 489 490 /* and again */ 491 dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMACSR(sc) & D_WRITE); 492 return 1; 493#endif 494 return 0; 495} 496 497/* 498 * Pseudo (chained) interrupt to le driver to handle DMA errors. 499 */ 500int 501lsi64854_enet_intr(void *arg) 502{ 503 struct lsi64854_softc *sc = arg; 504 char bits[64]; 505 uint32_t csr; 506 static int dodrain = 0; 507 int rv; 508 509 csr = L64854_GCSR(sc); 510 511 /* If the DMA logic shows an interrupt, claim it */ 512 rv = ((csr & E_INT_PEND) != 0) ? 1 : 0; 513 514 if (csr & (E_ERR_PEND|E_SLAVE_ERR)) { 515 snprintb(bits, sizeof(bits), EDMACSR_BITS, csr); 516 printf("%s: error: csr=%s\n", device_xname(sc->sc_dev), bits); 517 csr &= ~L64854_EN_DMA; /* Stop DMA */ 518 /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */ 519 csr |= E_INVALIDATE|E_SLAVE_ERR; 520 L64854_SCSR(sc, csr); 521 DMA_RESET(sc); 522 dodrain = 1; 523 return 1; 524 } 525 526 if (dodrain) { /* XXX - is this necessary with D_DSBL_WRINVAL on? */ 527 int i = 10; 528 csr |= E_DRAIN; 529 L64854_SCSR(sc, csr); 530 while (i-- > 0 && (L64854_GCSR(sc) & D_DRAINING)) 531 delay(1); 532 } 533 534 return rv | (*sc->sc_intrchain)(sc->sc_intrchainarg); 535} 536 537/* 538 * setup a DMA transfer 539 */ 540int 541lsi64854_setup_pp(struct lsi64854_softc *sc, uint8_t **addr, size_t *len, 542 int datain, size_t *dmasize) 543{ 544 uint32_t csr; 545 546 DMA_FLUSH(sc, 0); 547 548 sc->sc_dmaaddr = addr; 549 sc->sc_dmalen = len; 550 551 DPRINTF(LDB_PP, ("%s: pp start %ld@%p,%d\n", device_xname(sc->sc_dev), 552 (long)*sc->sc_dmalen, *sc->sc_dmaaddr, datain ? 1 : 0)); 553 554 /* 555 * the rules say we cannot transfer more than the limit 556 * of this DMA chip (64k for old and 16Mb for new), 557 * and we cannot cross a 16Mb boundary. 558 */ 559 *dmasize = sc->sc_dmasize = 560 uimin(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr)); 561 562 DPRINTF(LDB_PP, ("%s: dmasize = %ld\n", 563 __func__, (long)sc->sc_dmasize)); 564 565 /* Program the DMA address */ 566 if (sc->sc_dmasize) { 567 sc->sc_dvmaaddr = *sc->sc_dmaaddr; 568 if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, 569 *sc->sc_dmaaddr, sc->sc_dmasize, 570 NULL /* kernel address */, 571 BUS_DMA_NOWAIT/*|BUS_DMA_COHERENT*/)) 572 panic("%s: pp cannot allocate DVMA address", 573 device_xname(sc->sc_dev)); 574 bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize, 575 datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 576 bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR, 577 sc->sc_dmamap->dm_segs[0].ds_addr); 578 579 bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_CNT, 580 sc->sc_dmasize); 581 } 582 583 /* Setup DMA control register */ 584 csr = L64854_GCSR(sc); 585 csr &= ~L64854_BURST_SIZE; 586 if (sc->sc_burst == 32) { 587 csr |= L64854_BURST_32; 588 } else if (sc->sc_burst == 16) { 589 csr |= L64854_BURST_16; 590 } else { 591 csr |= L64854_BURST_0; 592 } 593 csr |= P_EN_DMA|P_INT_EN|P_EN_CNT; 594#if 0 595 /* This bit is read-only in PP csr register */ 596 if (datain) 597 csr |= P_WRITE; 598 else 599 csr &= ~P_WRITE; 600#endif 601 L64854_SCSR(sc, csr); 602 603 return 0; 604} 605/* 606 * Parallel port DMA interrupt. 607 */ 608int 609lsi64854_pp_intr(void *arg) 610{ 611 struct lsi64854_softc *sc = arg; 612 char bits[64]; 613 int ret, trans, resid = 0; 614 uint32_t csr; 615 616 csr = L64854_GCSR(sc); 617 618#ifdef DEBUG 619 snprintb(bits, sizeof(bits), PDMACSR_BITS, csr); 620#endif 621 DPRINTF(LDB_PP, ("%s: pp intr: addr 0x%x, csr %s\n", 622 device_xname(sc->sc_dev), 623 bus_space_read_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR), 624 bits)); 625 626 if (csr & (P_ERR_PEND|P_SLAVE_ERR)) { 627 resid = bus_space_read_4(sc->sc_bustag, sc->sc_regs, 628 L64854_REG_CNT); 629 snprintb(bits, sizeof(bits), PDMACSR_BITS, csr); 630 printf("%s: pp error: resid %d csr=%s\n", 631 device_xname(sc->sc_dev), resid, bits); 632 csr &= ~P_EN_DMA; /* Stop DMA */ 633 /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */ 634 csr |= P_INVALIDATE|P_SLAVE_ERR; 635 L64854_SCSR(sc, csr); 636 return 1; 637 } 638 639 ret = (csr & P_INT_PEND) != 0; 640 641 if (sc->sc_active != 0) { 642 DMA_DRAIN(sc, 0); 643 resid = bus_space_read_4(sc->sc_bustag, sc->sc_regs, 644 L64854_REG_CNT); 645 } 646 647 /* DMA has stopped */ 648 csr &= ~D_EN_DMA; 649 L64854_SCSR(sc, csr); 650 sc->sc_active = 0; 651 652 trans = sc->sc_dmasize - resid; 653 if (trans < 0) { /* transferred < 0 ? */ 654 trans = sc->sc_dmasize; 655 } 656 *sc->sc_dmalen -= trans; 657 *sc->sc_dmaaddr += trans; 658 659 if (sc->sc_dmamap->dm_nsegs > 0) { 660 bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize, 661 (csr & D_WRITE) != 0 ? 662 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 663 bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap); 664 } 665 666 return ret != 0; 667} 668