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