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