[BACK]Return to lsi64854.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/lsi64854.c, Revision 1.1.1.1

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

CVSweb