[BACK]Return to esp.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / dev

Annotation of sys/arch/sparc/dev/esp.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: esp.c,v 1.24 2006/06/02 20:00:54 miod Exp $   */
                      2: /*     $NetBSD: esp.c,v 1.69 1997/08/27 11:24:18 bouyer Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (c) 1997 Jason R. Thorpe.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed for the NetBSD Project
                     19:  *     by Jason R. Thorpe.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
                     36:  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
                     37:  *
                     38:  * Redistribution and use in source and binary forms, with or without
                     39:  * modification, are permitted provided that the following conditions
                     40:  * are met:
                     41:  * 1. Redistributions of source code must retain the above copyright
                     42:  *    notice, this list of conditions and the following disclaimer.
                     43:  * 2. Redistributions in binary form must reproduce the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer in the
                     45:  *    documentation and/or other materials provided with the distribution.
                     46:  * 3. All advertising materials mentioning features or use of this software
                     47:  *    must display the following acknowledgement:
                     48:  *     This product includes software developed by Charles M. Hannum.
                     49:  * 4. The name of the author may not be used to endorse or promote products
                     50:  *    derived from this software without specific prior written permission.
                     51:  *
                     52:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     53:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     54:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     55:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     56:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     57:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     58:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     59:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     60:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     61:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     62:  */
                     63:
                     64: /*
                     65:  * Copyright (c) 1994 Peter Galbavy
                     66:  * Copyright (c) 1995 Paul Kranenburg
                     67:  * All rights reserved.
                     68:  *
                     69:  * Redistribution and use in source and binary forms, with or without
                     70:  * modification, are permitted provided that the following conditions
                     71:  * are met:
                     72:  * 1. Redistributions of source code must retain the above copyright
                     73:  *    notice, this list of conditions and the following disclaimer.
                     74:  * 2. Redistributions in binary form must reproduce the above copyright
                     75:  *    notice, this list of conditions and the following disclaimer in the
                     76:  *    documentation and/or other materials provided with the distribution.
                     77:  *
                     78:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     79:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     80:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     81:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     82:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     83:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     84:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     85:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     86:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     87:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     88:  * POSSIBILITY OF SUCH DAMAGE.
                     89:  */
                     90:
                     91: /*
                     92:  * Based on aic6360 by Jarle Greipsland
                     93:  *
                     94:  * Acknowledgements: Many of the algorithms used in this driver are
                     95:  * inspired by the work of Julian Elischer (julian@tfs.com) and
                     96:  * Charles Hannum (mycroft@duality.gnu.ai.mit.edu).  Thanks a million!
                     97:  */
                     98:
                     99: #include <sys/types.h>
                    100: #include <sys/param.h>
                    101: #include <sys/systm.h>
                    102: #include <sys/kernel.h>
                    103: #include <sys/errno.h>
                    104: #include <sys/ioctl.h>
                    105: #include <sys/device.h>
                    106: #include <sys/buf.h>
                    107: #include <sys/proc.h>
                    108: #include <sys/user.h>
                    109: #include <sys/queue.h>
                    110: #include <sys/malloc.h>
                    111:
                    112: #include <scsi/scsi_all.h>
                    113: #include <scsi/scsiconf.h>
                    114: #include <scsi/scsi_message.h>
                    115:
                    116: #include <machine/cpu.h>
                    117: #include <machine/autoconf.h>
                    118:
                    119: #include <dev/ic/ncr53c9xreg.h>
                    120: #include <dev/ic/ncr53c9xvar.h>
                    121:
                    122: #include <sparc/dev/sbusvar.h>
                    123: #include <sparc/dev/dmareg.h>
                    124: #include <sparc/dev/dmavar.h>
                    125: #include <sparc/dev/espvar.h>
                    126:
                    127: void   espattach(struct device *, struct device *, void *);
                    128: int    espmatch(struct device *, void *, void *);
                    129:
                    130: /* Linkup to the rest of the kernel */
                    131: struct cfattach esp_ca = {
                    132:        sizeof(struct esp_softc), espmatch, espattach
                    133: };
                    134:
                    135: struct scsi_adapter esp_switch = {
                    136:        ncr53c9x_scsi_cmd,
                    137:        minphys,                /* no max at this level; handled by DMA code */
                    138:        NULL,
                    139:        NULL,
                    140: };
                    141:
                    142: struct scsi_device esp_dev = {
                    143:        NULL,                   /* Use default error handler */
                    144:        NULL,                   /* have a queue, served by this */
                    145:        NULL,                   /* have no async handler */
                    146:        NULL,                   /* Use default 'done' routine */
                    147: };
                    148:
                    149: /*
                    150:  * Functions and the switch for the MI code.
                    151:  */
                    152: u_char esp_read_reg(struct ncr53c9x_softc *, int);
                    153: void   esp_write_reg(struct ncr53c9x_softc *, int, u_char);
                    154: u_char esp_rdreg1(struct ncr53c9x_softc *, int);
                    155: void   esp_wrreg1(struct ncr53c9x_softc *, int, u_char);
                    156: int    esp_dma_isintr(struct ncr53c9x_softc *);
                    157: void   esp_dma_reset(struct ncr53c9x_softc *);
                    158: int    esp_dma_intr(struct ncr53c9x_softc *);
                    159: int    esp_dma_setup(struct ncr53c9x_softc *, caddr_t *,
                    160:            size_t *, int, size_t *);
                    161: void   esp_dma_go(struct ncr53c9x_softc *);
                    162: void   esp_dma_stop(struct ncr53c9x_softc *);
                    163: int    esp_dma_isactive(struct ncr53c9x_softc *);
                    164:
                    165: struct ncr53c9x_glue esp_glue = {
                    166:        esp_read_reg,
                    167:        esp_write_reg,
                    168:        esp_dma_isintr,
                    169:        esp_dma_reset,
                    170:        esp_dma_intr,
                    171:        esp_dma_setup,
                    172:        esp_dma_go,
                    173:        esp_dma_stop,
                    174:        esp_dma_isactive,
                    175:        NULL,                   /* gl_clear_latched_intr */
                    176: };
                    177:
                    178: #if defined(SUN4C) || defined(SUN4M)
                    179: struct ncr53c9x_glue esp_glue1 = {
                    180:        esp_rdreg1,
                    181:        esp_wrreg1,
                    182:        esp_dma_isintr,
                    183:        esp_dma_reset,
                    184:        esp_dma_intr,
                    185:        esp_dma_setup,
                    186:        esp_dma_go,
                    187:        esp_dma_stop,
                    188:        esp_dma_isactive,
                    189:        NULL,                   /* gl_clear_latched_intr */
                    190: };
                    191: #endif
                    192:
                    193: int
                    194: espmatch(parent, vcf, aux)
                    195:        struct device *parent;
                    196:        void *vcf, *aux;
                    197: {
                    198:        register struct cfdata *cf = vcf;
                    199:        register struct confargs *ca = aux;
                    200:        register struct romaux *ra = &ca->ca_ra;
                    201:
                    202: #if defined(SUN4C) || defined(SUN4M)
                    203:        if (ca->ca_bustype == BUS_SBUS) {
                    204:                if (strcmp("SUNW,fas", ra->ra_name) == 0 ||
                    205:                    strcmp("ptscII", ra->ra_name) == 0)
                    206:                        return (1);
                    207:        }
                    208: #endif
                    209:
                    210:        if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
                    211:                return (0);
                    212: #if defined(SUN4C) || defined(SUN4M)
                    213:        if (ca->ca_bustype == BUS_SBUS) {
                    214:                if (!sbus_testdma((struct sbus_softc *)parent, ca))
                    215:                        return (0);
                    216:                return (1);
                    217:        }
                    218: #endif
                    219:        ra->ra_len = NBPG;
                    220:        return (probeget(ra->ra_vaddr, 1) != -1);
                    221: }
                    222:
                    223: /*
                    224:  * Attach this instance, and then all the sub-devices
                    225:  */
                    226: void
                    227: espattach(parent, self, aux)
                    228:        struct device *parent, *self;
                    229:        void *aux;
                    230: {
                    231:        register struct confargs *ca = aux;
                    232:        struct esp_softc *esc = (void *)self;
                    233:        struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
                    234:        struct bootpath *bp;
                    235:        int dmachild;
                    236:        unsigned int uid = 0;
                    237:
                    238:        /*
                    239:         * If no interrupts properties, bail out: this might happen
                    240:         * on the Sparc X terminal.
                    241:         */
                    242:        if (ca->ca_ra.ra_nintr != 1) {
                    243:                printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
                    244:                return;
                    245:        }
                    246:
                    247:        esc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
                    248:        printf(" pri %d", esc->sc_pri);
                    249:
                    250:        /* Other settings */
                    251:        esc->sc_node = ca->ca_ra.ra_node;
                    252:        if (ca->ca_bustype == BUS_SBUS) {
                    253:                sc->sc_id = getpropint(esc->sc_node, "initiator-id", 7);
                    254:                sc->sc_freq = getpropint(esc->sc_node, "clock-frequency", -1);
                    255:        } else {
                    256:                sc->sc_id = 7;
                    257:                sc->sc_freq = 24000000;
                    258:        }
                    259:        if (sc->sc_freq < 0)
                    260:                sc->sc_freq = ((struct sbus_softc *)
                    261:                    sc->sc_dev.dv_parent)->sc_clockfreq;
                    262:
                    263:        /* gimme MHz */
                    264:        sc->sc_freq /= 1000000;
                    265:
                    266: #if defined(SUN4C) || defined(SUN4M)
                    267:        if (ca->ca_bustype == BUS_SBUS &&
                    268:            strcmp("SUNW,fas", ca->ca_ra.ra_name) == 0) {
                    269:                struct dma_softc *dsc;
                    270:
                    271:                /*
                    272:                 * fas has 2 register spaces: DMA (lsi64854) and SCSI core
                    273:                 * (ncr53c9x).
                    274:                 */
                    275:                if (ca->ca_ra.ra_nreg != 2) {
                    276:                        printf(": expected 2 register spaces, found %d\n",
                    277:                            ca->ca_ra.ra_nreg);
                    278:                        return;
                    279:                }
                    280:
                    281:                /*
                    282:                 * Allocate a softc for the DMA companion, which will not
                    283:                 * get a regular attachment.
                    284:                 */
                    285:                dsc = malloc(sizeof(struct dma_softc), M_DEVBUF, M_NOWAIT);
                    286:                if (dsc == NULL) {
                    287:                        printf(": could not allocate dma softc\n");
                    288:                        return;
                    289:                }
                    290:                bzero(dsc, sizeof(struct dma_softc));
                    291:                strlcpy(dsc->sc_dev.dv_xname, sc->sc_dev.dv_xname,
                    292:                    sizeof(dsc->sc_dev.dv_xname));
                    293:                esc->sc_dma = dsc;
                    294:
                    295:                /*
                    296:                 * Map DMA registers
                    297:                 */
                    298:                dsc->sc_regs = (struct dma_regs *)mapiodev(&ca->ca_ra.ra_reg[0],
                    299:                    0, ca->ca_ra.ra_reg[0].rr_len);
                    300:                if (dsc->sc_regs == NULL) {
                    301:                        printf(": could not map DMA registers\n");
                    302:                        return;
                    303:                }
                    304:                dsc->sc_rev = dsc->sc_regs->csr & D_DEV_ID;
                    305:                dsc->sc_esp = esc;
                    306:
                    307: #ifdef SUN4M
                    308:                /*
                    309:                 * Get transfer burst size from PROM and plug it into the
                    310:                 * controller registers. This is needed on the Sun4m; do
                    311:                 * others need it too?
                    312:                 */
                    313:                if (CPU_ISSUN4M) {
                    314:                        int sbusburst;
                    315:
                    316:                        sbusburst = ((struct sbus_softc *)parent)->sc_burst;
                    317:                        if (sbusburst == 0)
                    318:                                sbusburst = SBUS_BURST_32 - 1;  /* 1 -> 16 */
                    319:
                    320:                        dsc->sc_burst =
                    321:                            getpropint(ca->ca_ra.ra_node, "burst-sizes", -1);
                    322:                        if (dsc->sc_burst == -1)
                    323:                                /* take SBus burst sizes */
                    324:                                dsc->sc_burst = sbusburst;
                    325:
                    326:                        /* Clamp at parent's burst sizes */
                    327:                        dsc->sc_burst &= sbusburst;
                    328:                }
                    329: #endif /* SUN4M */
                    330:
                    331:                /* indirect functions */
                    332:                dma_setuphandlers(dsc);
                    333:
                    334:                /*
                    335:                 * Map SCSI core registers
                    336:                 */
                    337:                esc->sc_reg = (volatile u_char *)mapiodev(&ca->ca_ra.ra_reg[1],
                    338:                    0, ca->ca_ra.ra_reg[1].rr_len);
                    339:                if (esc->sc_reg == NULL) {
                    340:                        printf(": could not map SCSI core registers\n");
                    341:                        return;
                    342:                }
                    343:
                    344:                dmachild = 0;
                    345:        } else
                    346: #endif
                    347:        {
                    348:                /*
                    349:                 * Map my registers in, if they aren't already in virtual
                    350:                 * address space.
                    351:                 */
                    352:                if (ca->ca_ra.ra_vaddr)
                    353:                        esc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
                    354:                else {
                    355:                        esc->sc_reg = (volatile u_char *)
                    356:                            mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
                    357:                }
                    358:
                    359:                dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
                    360:                if (dmachild) {
                    361:                        esc->sc_dma = (struct dma_softc *)parent;
                    362:                        esc->sc_dma->sc_esp = esc;
                    363:                } else {
                    364:                        /*
                    365:                         * Find the DMA by poking around the DMA device
                    366:                         * structures.
                    367:                         *
                    368:                         * What happens here is that if the DMA driver has
                    369:                         * not been configured, then this returns a NULL
                    370:                         * pointer. Then when the DMA actually gets configured,
                    371:                         * it does the opposite test, and if the sc->sc_esp
                    372:                         * field in its softc is NULL, then tries to find the
                    373:                         * matching esp driver.
                    374:                         */
                    375:                        esc->sc_dma = (struct dma_softc *)
                    376:                            getdevunit("dma", sc->sc_dev.dv_unit);
                    377:
                    378:                        /*
                    379:                         * ...and a back pointer to us, for DMA.
                    380:                         */
                    381:                        if (esc->sc_dma)
                    382:                                esc->sc_dma->sc_esp = esc;
                    383:                        else {
                    384:                                printf("\n");
                    385:                                panic("espattach: no dma found");
                    386:                        }
                    387:                }
                    388:        }
                    389:
                    390:        /*
                    391:         * Set up glue for MI code.
                    392:         */
                    393: #if defined(SUN4C) || defined(SUN4M)
                    394:        if (ca->ca_bustype == BUS_SBUS &&
                    395:            strcmp("ptscII", ca->ca_ra.ra_name) == 0) {
                    396:                sc->sc_glue = &esp_glue1;
                    397:        } else
                    398: #endif
                    399:                sc->sc_glue = &esp_glue;
                    400:
                    401:        /*
                    402:         * XXX More of this should be in ncr53c9x_attach(), but
                    403:         * XXX should we really poke around the chip that much in
                    404:         * XXX the MI code?  Think about this more...
                    405:         */
                    406:
                    407:        /*
                    408:         * It is necessary to try to load the 2nd config register here,
                    409:         * to find out what rev the esp chip is, else the ncr53c9x_reset
                    410:         * will not set up the defaults correctly.
                    411:         */
                    412:        sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
                    413:        sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
                    414:        sc->sc_cfg3 = NCRCFG3_CDB;
                    415:        NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
                    416:
                    417:        if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
                    418:            (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
                    419:                sc->sc_rev = NCR_VARIANT_ESP100;
                    420:        } else {
                    421:                sc->sc_cfg2 = NCRCFG2_SCSI2;
                    422:                NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
                    423:                sc->sc_cfg3 = 0;
                    424:                NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
                    425:                sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
                    426:                NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
                    427:                if (NCR_READ_REG(sc, NCR_CFG3) !=
                    428:                    (NCRCFG3_CDB | NCRCFG3_FCLK)) {
                    429:                        sc->sc_rev = NCR_VARIANT_ESP100A;
                    430:                } else {
                    431:                        /* NCRCFG2_FE enables > 64K transfers */
                    432:                        sc->sc_cfg2 |= NCRCFG2_FE;
                    433:                        sc->sc_cfg3 = 0;
                    434:                        NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
                    435:                        sc->sc_rev = NCR_VARIANT_ESP200;
                    436:
                    437:                        /* XXX spec says it's valid after power up or chip reset */
                    438:                        uid = NCR_READ_REG(sc, NCR_UID);
                    439:                        if (((uid & 0xf8) >> 3) == 0x0a) /* XXX */
                    440:                                sc->sc_rev = NCR_VARIANT_FAS366;
                    441:                }
                    442:        }
                    443:
                    444:        /*
                    445:         * XXX minsync and maxxfer _should_ be set up in MI code,
                    446:         * XXX but it appears to have some dependency on what sort
                    447:         * XXX of DMA we're hooked up to, etc.
                    448:         */
                    449:
                    450:        /*
                    451:         * This is the value used to start sync negotiations
                    452:         * Note that the NCR register "SYNCTP" is programmed
                    453:         * in "clocks per byte", and has a minimum value of 4.
                    454:         * The SCSI period used in negotiation is one-fourth
                    455:         * of the time (in nanoseconds) needed to transfer one byte.
                    456:         * Since the chip's clock is given in MHz, we have the following
                    457:         * formula: 4 * period = (1000 / freq) * 4
                    458:         */
                    459:        sc->sc_minsync = 1000 / sc->sc_freq;
                    460:
                    461:        /*
                    462:         * Alas, we must now modify the value a bit, because it's
                    463:         * only valid when can switch on FASTCLK and FASTSCSI bits
                    464:         * in config register 3...
                    465:         */
                    466:        switch (sc->sc_rev) {
                    467:        case NCR_VARIANT_ESP100:
                    468:                sc->sc_maxxfer = 64 * 1024;
                    469:                sc->sc_minsync = 0;     /* No synch on old chip? */
                    470:                break;
                    471:
                    472:        case NCR_VARIANT_ESP100A:
                    473:                sc->sc_maxxfer = 64 * 1024;
                    474:                /* Min clocks/byte is 5 */
                    475:                sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
                    476:                break;
                    477:
                    478:        case NCR_VARIANT_ESP200:
                    479:        case NCR_VARIANT_FAS366:
                    480:                sc->sc_maxxfer = 16 * 1024 * 1024;
                    481:                /* XXX - do actually set FAST* bits */
                    482:                break;
                    483:        }
                    484:
                    485:        /* and the interrupts */
                    486:        esc->sc_ih.ih_fun = (void *) ncr53c9x_intr;
                    487:        esc->sc_ih.ih_arg = sc;
                    488:        intr_establish(esc->sc_pri, &esc->sc_ih, IPL_BIO, self->dv_xname);
                    489:
                    490:        /*
                    491:         * If the boot path is "esp" at the moment and it's me, then
                    492:         * walk our pointer to the sub-device, ready for the config
                    493:         * below.
                    494:         */
                    495:        bp = ca->ca_ra.ra_bp;
                    496:        switch (ca->ca_bustype) {
                    497:        case BUS_SBUS:
                    498:                if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
                    499:                    SAME_ESP(sc, bp, ca))
                    500:                        bootpath_store(1, bp + 1);
                    501:                break;
                    502:        default:
                    503:                if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
                    504:                        bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit)
                    505:                        bootpath_store(1, bp + 1);
                    506:                break;
                    507:        }
                    508:
                    509:        /* Turn on target selection using the `dma' method */
                    510:        if (sc->sc_rev != NCR_VARIANT_FAS366)
                    511:                sc->sc_features |= NCR_F_DMASELECT;
                    512:
                    513:        /* Do the common parts of attachment. */
                    514:        ncr53c9x_attach(sc, &esp_switch, &esp_dev);
                    515:
                    516:        bootpath_store(1, NULL);
                    517: }
                    518:
                    519: /*
                    520:  * Glue functions.
                    521:  */
                    522:
                    523: u_char
                    524: esp_read_reg(sc, reg)
                    525:        struct ncr53c9x_softc *sc;
                    526:        int reg;
                    527: {
                    528:        struct esp_softc *esc = (struct esp_softc *)sc;
                    529:
                    530:        return (esc->sc_reg[reg * 4]);
                    531: }
                    532:
                    533: void
                    534: esp_write_reg(sc, reg, val)
                    535:        struct ncr53c9x_softc *sc;
                    536:        int reg;
                    537:        u_char val;
                    538: {
                    539:        struct esp_softc *esc = (struct esp_softc *)sc;
                    540:        u_char v = val;
                    541:
                    542:        esc->sc_reg[reg * 4] = v;
                    543: }
                    544:
                    545: #if defined(SUN4C) || defined(SUN4M)
                    546: u_char
                    547: esp_rdreg1(sc, reg)
                    548:        struct ncr53c9x_softc *sc;
                    549:        int reg;
                    550: {
                    551:        struct esp_softc *esc = (struct esp_softc *)sc;
                    552:
                    553:        return (esc->sc_reg[reg]);
                    554: }
                    555:
                    556: void
                    557: esp_wrreg1(sc, reg, val)
                    558:        struct ncr53c9x_softc *sc;
                    559:        int reg;
                    560:        u_char val;
                    561: {
                    562:        struct esp_softc *esc = (struct esp_softc *)sc;
                    563:        u_char v = val;
                    564:
                    565:        esc->sc_reg[reg] = v;
                    566: }
                    567: #endif
                    568:
                    569: int
                    570: esp_dma_isintr(sc)
                    571:        struct ncr53c9x_softc *sc;
                    572: {
                    573:        struct esp_softc *esc = (struct esp_softc *)sc;
                    574:
                    575:        return (DMA_ISINTR(esc->sc_dma));
                    576: }
                    577:
                    578: void
                    579: esp_dma_reset(sc)
                    580:        struct ncr53c9x_softc *sc;
                    581: {
                    582:        struct esp_softc *esc = (struct esp_softc *)sc;
                    583:
                    584:        DMA_RESET(esc->sc_dma);
                    585: }
                    586:
                    587: int
                    588: esp_dma_intr(sc)
                    589:        struct ncr53c9x_softc *sc;
                    590: {
                    591:        struct esp_softc *esc = (struct esp_softc *)sc;
                    592:
                    593:        return (DMA_INTR(esc->sc_dma));
                    594: }
                    595:
                    596: int
                    597: esp_dma_setup(sc, addr, len, datain, dmasize)
                    598:        struct ncr53c9x_softc *sc;
                    599:        caddr_t *addr;
                    600:        size_t *len;
                    601:        int datain;
                    602:        size_t *dmasize;
                    603: {
                    604:        struct esp_softc *esc = (struct esp_softc *)sc;
                    605:
                    606:        return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
                    607: }
                    608:
                    609: void
                    610: esp_dma_go(sc)
                    611:        struct ncr53c9x_softc *sc;
                    612: {
                    613:        struct esp_softc *esc = (struct esp_softc *)sc;
                    614:
                    615:        DMA_GO(esc->sc_dma);
                    616: }
                    617:
                    618: void
                    619: esp_dma_stop(sc)
                    620:        struct ncr53c9x_softc *sc;
                    621: {
                    622:        struct esp_softc *esc = (struct esp_softc *)sc;
                    623:
                    624:        DMACSR(esc->sc_dma) &= ~D_EN_DMA;
                    625: }
                    626:
                    627: int
                    628: esp_dma_isactive(sc)
                    629:        struct ncr53c9x_softc *sc;
                    630: {
                    631:        struct esp_softc *esc = (struct esp_softc *)sc;
                    632:
                    633:        return (DMA_ISACTIVE(esc->sc_dma));
                    634: }

CVSweb