[BACK]Return to asc_vsbus.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / vsa

Annotation of sys/arch/vax/vsa/asc_vsbus.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: asc_vsbus.c,v 1.8 2007/08/01 16:32:30 miod Exp $      */
        !             2: /*     $NetBSD: asc_vsbus.c,v 1.22 2001/02/04 20:36:32 ragge 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 Charles M. Hannum.
        !            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/cdefs.h>                 /* RCS ID & Copyright macro defns */
        !            41:
        !            42: #include <sys/types.h>
        !            43: #include <sys/param.h>
        !            44: #include <sys/systm.h>
        !            45: #include <sys/kernel.h>
        !            46: #include <sys/errno.h>
        !            47: #include <sys/ioctl.h>
        !            48: #include <sys/device.h>
        !            49: #include <sys/buf.h>
        !            50: #include <sys/proc.h>
        !            51: #include <sys/user.h>
        !            52: #include <sys/reboot.h>
        !            53: #include <sys/queue.h>
        !            54:
        !            55: #include <scsi/scsi_all.h>
        !            56: #include <scsi/scsiconf.h>
        !            57: #include <scsi/scsi_message.h>
        !            58:
        !            59: #include <machine/bus.h>
        !            60: #include <machine/vmparam.h>
        !            61:
        !            62: #include <dev/ic/ncr53c9xreg.h>
        !            63: #include <dev/ic/ncr53c9xvar.h>
        !            64:
        !            65: #include <machine/cpu.h>
        !            66: #include <machine/sid.h>
        !            67: #include <machine/scb.h>
        !            68: #include <machine/vsbus.h>
        !            69: #include <machine/clock.h>     /* for SCSI ctlr ID# XXX */
        !            70:
        !            71: struct asc_vsbus_softc {
        !            72:        struct ncr53c9x_softc sc_ncr53c9x;      /* Must be first */
        !            73:        struct evcount sc_intrcnt;              /* count interrupts */
        !            74:        int     sc_cvec;                        /* vector */
        !            75:        bus_space_tag_t sc_bst;                 /* bus space tag */
        !            76:        bus_space_handle_t sc_bsh;              /* bus space handle */
        !            77:        bus_space_handle_t sc_dirh;             /* scsi direction handle */
        !            78:        bus_space_handle_t sc_adrh;             /* scsi address handle */
        !            79:        bus_space_handle_t sc_ncrh;             /* ncr bus space handle */
        !            80:        bus_dma_tag_t sc_dmat;                  /* bus dma tag */
        !            81:        bus_dmamap_t sc_dmamap;
        !            82:        caddr_t *sc_dmaaddr;
        !            83:        size_t *sc_dmalen;
        !            84:        size_t sc_dmasize;
        !            85:        unsigned int sc_flags;
        !            86: #define        ASC_FROMMEMORY          0x0001          /* Must be 1 */
        !            87: #define        ASC_DMAACTIVE           0x0002
        !            88: #define        ASC_MAPLOADED           0x0004
        !            89:        unsigned long sc_xfers;
        !            90: };
        !            91:
        !            92: #define        ASC_REG_KA46_ADR        0x0000
        !            93: #define        ASC_REG_KA46_DIR        0x000C
        !            94: #define        ASC_REG_KA49_ADR        0x0000
        !            95: #define        ASC_REG_KA49_DIR        0x0004
        !            96: #define        ASC_REG_NCR             0x0080
        !            97: #define        ASC_REG_END             0x00B0
        !            98:
        !            99: #define        ASC_MAXXFERSIZE         65536
        !           100: #define        ASC_FREQUENCY           25000000
        !           101:
        !           102: extern struct cfdriver sd_cd;
        !           103:
        !           104: int asc_vsbus_match(struct device *, void *, void *);
        !           105: void asc_vsbus_attach(struct device *, struct device *, void *);
        !           106:
        !           107: struct cfattach asc_vsbus_ca = {
        !           108:        sizeof(struct asc_vsbus_softc), asc_vsbus_match, asc_vsbus_attach
        !           109: };
        !           110:
        !           111: struct cfdriver asc_cd = {
        !           112:        NULL, "asc", DV_DULL
        !           113: };
        !           114:
        !           115: struct scsi_adapter    asc_vsbus_ops = {
        !           116:        ncr53c9x_scsi_cmd,
        !           117:        minphys,
        !           118:        NULL,
        !           119:        NULL
        !           120: };
        !           121:
        !           122: static struct scsi_device asc_vsbus_dev = {
        !           123:        NULL,                   /* Use the default error handler */
        !           124:        NULL,                   /* have a queue, served by this */
        !           125:        NULL,                   /* have no async handler */
        !           126:        NULL,                   /* use the default done handler */
        !           127: };
        !           128:
        !           129:
        !           130: /*
        !           131:  * Functions and the switch for the MI code
        !           132:  */
        !           133: u_char asc_vsbus_read_reg(struct ncr53c9x_softc *, int);
        !           134: void   asc_vsbus_write_reg(struct ncr53c9x_softc *, int, u_char);
        !           135: int    asc_vsbus_dma_isintr(struct ncr53c9x_softc *);
        !           136: void   asc_vsbus_dma_reset(struct ncr53c9x_softc *);
        !           137: int    asc_vsbus_dma_intr(struct ncr53c9x_softc *);
        !           138: int    asc_vsbus_dma_setup(struct ncr53c9x_softc *, caddr_t *,
        !           139:            size_t *, int, size_t *);
        !           140: void   asc_vsbus_dma_go(struct ncr53c9x_softc *);
        !           141: void   asc_vsbus_dma_stop(struct ncr53c9x_softc *);
        !           142: int    asc_vsbus_dma_isactive(struct ncr53c9x_softc *);
        !           143: int    asc_vsbus_controller_id(void);
        !           144:
        !           145: static struct ncr53c9x_glue asc_vsbus_glue = {
        !           146:        asc_vsbus_read_reg,
        !           147:        asc_vsbus_write_reg,
        !           148:        asc_vsbus_dma_isintr,
        !           149:        asc_vsbus_dma_reset,
        !           150:        asc_vsbus_dma_intr,
        !           151:        asc_vsbus_dma_setup,
        !           152:        asc_vsbus_dma_go,
        !           153:        asc_vsbus_dma_stop,
        !           154:        asc_vsbus_dma_isactive,
        !           155:        NULL,
        !           156: };
        !           157:
        !           158: static u_int8_t asc_attached;          /* can't have more than one asc */
        !           159:
        !           160: int
        !           161: asc_vsbus_match(struct device *parent, void *conf, void *aux)
        !           162: {
        !           163:        struct vsbus_attach_args *va = aux;
        !           164:        struct cfdata *cf = conf;
        !           165:        volatile u_int8_t *ncr_regs;
        !           166:        volatile int dummy;
        !           167:
        !           168:        if (asc_attached)
        !           169:                return 0;
        !           170:
        !           171:        if (vax_boardtype == VAX_BTYP_46 || vax_boardtype == VAX_BTYP_48) {
        !           172:                if (cf->cf_loc[0] != 0x200c0080)
        !           173:                        return 0;
        !           174:        } else if (vax_boardtype == VAX_BTYP_49 ||
        !           175:            vax_boardtype == VAX_BTYP_1303) {
        !           176:                if (cf->cf_loc[0] != 0x26000080)
        !           177:                        return 0;
        !           178:        } else {
        !           179:                return 0;
        !           180:        }
        !           181:
        !           182:        ncr_regs = (volatile u_int8_t *) va->va_addr;
        !           183:
        !           184:        /*  *** need to generate an interrupt here
        !           185:         * From trial and error, I've determined that an INT is generated
        !           186:         * only when the following sequence of events occurs:
        !           187:         *   1) The interrupt status register (0x05) must be read.
        !           188:         *   2) SCSI bus reset interrupt must be enabled
        !           189:         *   3) SCSI bus reset command must be sent
        !           190:         *   4) NOP command must be sent
        !           191:         */
        !           192:
        !           193:        dummy = ncr_regs[NCR_INTR << 2] & 0xFF;
        !           194:         ncr_regs[NCR_CFG1 << 2] = asc_vsbus_controller_id(); /* turn on INT
        !           195:                                                           for SCSI reset */
        !           196:         ncr_regs[NCR_CMD << 2] = NCRCMD_RSTSCSI;       /* send the reset */
        !           197:         ncr_regs[NCR_CMD << 2] = NCRCMD_NOP;           /* send a NOP */
        !           198:        DELAY(10000);
        !           199:
        !           200:        dummy = ncr_regs[NCR_INTR << 2] & 0xFF;
        !           201:        return (dummy & NCRINTR_SBR) != 0;
        !           202: }
        !           203:
        !           204:
        !           205: /*
        !           206:  * Attach this instance, and then all the sub-devices
        !           207:  */
        !           208: void
        !           209: asc_vsbus_attach(struct device *parent, struct device *self, void *aux)
        !           210: {
        !           211:        struct vsbus_attach_args *va = aux;
        !           212:        struct asc_vsbus_softc *asc = (void *)self;
        !           213:        struct ncr53c9x_softc *sc = &asc->sc_ncr53c9x;
        !           214:        int error;
        !           215:
        !           216:        asc_attached = 1;
        !           217:        /*
        !           218:         * Set up glue for MI code early; we use some of it here.
        !           219:         */
        !           220:        sc->sc_glue = &asc_vsbus_glue;
        !           221:
        !           222:        asc->sc_bst = va->va_iot;
        !           223:        asc->sc_dmat = va->va_dmat;
        !           224:
        !           225:        error = bus_space_map(asc->sc_bst, va->va_paddr - ASC_REG_NCR,
        !           226:            ASC_REG_END, 0, &asc->sc_bsh);
        !           227:        if (error) {
        !           228:                printf(": failed to map registers: error=%d\n", error);
        !           229:                return;
        !           230:        }
        !           231:        error = bus_space_subregion(asc->sc_bst, asc->sc_bsh, ASC_REG_NCR,
        !           232:            ASC_REG_END - ASC_REG_NCR, &asc->sc_ncrh);
        !           233:        if (error) {
        !           234:                printf(": failed to map ncr registers: error=%d\n", error);
        !           235:                return;
        !           236:        }
        !           237:        if (vax_boardtype == VAX_BTYP_46 || vax_boardtype == VAX_BTYP_48) {
        !           238:                error = bus_space_subregion(asc->sc_bst, asc->sc_bsh,
        !           239:                    ASC_REG_KA46_ADR, sizeof(u_int32_t), &asc->sc_adrh);
        !           240:                if (error) {
        !           241:                        printf(": failed to map adr register: error=%d\n",
        !           242:                             error);
        !           243:                        return;
        !           244:                }
        !           245:                error = bus_space_subregion(asc->sc_bst, asc->sc_bsh,
        !           246:                    ASC_REG_KA46_DIR, sizeof(u_int32_t), &asc->sc_dirh);
        !           247:                if (error) {
        !           248:                        printf(": failed to map dir register: error=%d\n",
        !           249:                             error);
        !           250:                        return;
        !           251:                }
        !           252:        } else {
        !           253:                /* This is a gross and disgusting kludge but it'll
        !           254:                 * save a bunch of ugly code.  Unlike the VS4000/60,
        !           255:                 * the SCSI Address and direction registers are not
        !           256:                 * near the SCSI NCR registers and are inside the
        !           257:                 * block of general VAXstation registers.  So we grab
        !           258:                 * them from there and knowing the internals of the
        !           259:                 * bus_space implementation, we cast to bus_space_handles.
        !           260:                 */
        !           261:                struct vsbus_softc *vsc = (struct vsbus_softc *) parent;
        !           262:                asc->sc_adrh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_ADR);
        !           263:                asc->sc_dirh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_DIR);
        !           264: #if 0
        !           265:                printf("\n%s: adrh=0x%08lx dirh=0x%08lx", self->dv_xname,
        !           266:                       asc->sc_adrh, asc->sc_dirh);
        !           267:                ncr53c9x_debug = NCR_SHOWDMA|NCR_SHOWINTS|NCR_SHOWCMDS|NCR_SHOWPHASE|NCR_SHOWSTART|NCR_SHOWMSGS;
        !           268: #endif
        !           269:        }
        !           270:        error = bus_dmamap_create(asc->sc_dmat, ASC_MAXXFERSIZE, 1,
        !           271:            ASC_MAXXFERSIZE, 0, BUS_DMA_NOWAIT, &asc->sc_dmamap);
        !           272:
        !           273:        sc->sc_id = asc_vsbus_controller_id();
        !           274:        sc->sc_freq = ASC_FREQUENCY;
        !           275:
        !           276:        /* gimme MHz */
        !           277:        sc->sc_freq /= 1000000;
        !           278:
        !           279:        scb_vecalloc(va->va_cvec, (void (*)(void *)) ncr53c9x_intr,
        !           280:            &asc->sc_ncr53c9x, SCB_ISTACK, &asc->sc_intrcnt);
        !           281:        asc->sc_cvec = va->va_cvec;
        !           282:        evcount_attach(&asc->sc_intrcnt, self->dv_xname,
        !           283:            (void *)&asc->sc_cvec, &evcount_intr);
        !           284:
        !           285:        /*
        !           286:         * XXX More of this should be in ncr53c9x_attach(), but
        !           287:         * XXX should we really poke around the chip that much in
        !           288:         * XXX the MI code?  Think about this more...
        !           289:         */
        !           290:
        !           291:        /*
        !           292:         * Set up static configuration info.
        !           293:         */
        !           294:        sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
        !           295:        sc->sc_cfg2 = NCRCFG2_SCSI2;
        !           296:        sc->sc_cfg3 = 0;
        !           297:        sc->sc_rev = NCR_VARIANT_NCR53C94;
        !           298:
        !           299:        /*
        !           300:         * XXX minsync and maxxfer _should_ be set up in MI code,
        !           301:         * XXX but it appears to have some dependency on what sort
        !           302:         * XXX of DMA we're hooked up to, etc.
        !           303:         */
        !           304:
        !           305:        /*
        !           306:         * This is the value used to start sync negotiations
        !           307:         * Note that the NCR register "SYNCTP" is programmed
        !           308:         * in "clocks per byte", and has a minimum value of 4.
        !           309:         * The SCSI period used in negotiation is one-fourth
        !           310:         * of the time (in nanoseconds) needed to transfer one byte.
        !           311:         * Since the chip's clock is given in MHz, we have the following
        !           312:         * formula: 4 * period = (1000 / freq) * 4
        !           313:         */
        !           314:        sc->sc_minsync = (1000 / sc->sc_freq);
        !           315:        sc->sc_maxxfer = 64 * 1024;
        !           316:
        !           317:        /* Do the common parts of attachment. */
        !           318:        ncr53c9x_attach(sc, &asc_vsbus_ops, &asc_vsbus_dev);
        !           319: }
        !           320:
        !           321: /*
        !           322:  * Return the host controllers SCSI ID.
        !           323:  * The factory default is 6 (unlike most vendors who use 7), but this can
        !           324:  * be changed in the prom.
        !           325:  */
        !           326: int
        !           327: asc_vsbus_controller_id()
        !           328: {
        !           329:        switch (vax_boardtype) {
        !           330: #if defined(VAX46) || defined(VAX48) || defined(VAX49)
        !           331:        case VAX_BTYP_46:
        !           332:        case VAX_BTYP_48:
        !           333:        case VAX_BTYP_49:
        !           334:                return (clk_page[0xbc / 2] >> clk_tweak) & 7;
        !           335: #endif
        !           336:        default:
        !           337:                return 6;       /* XXX need to get this from VMB */
        !           338:        }
        !           339: }
        !           340:
        !           341: /*
        !           342:  * Glue functions.
        !           343:  */
        !           344:
        !           345: u_char
        !           346: asc_vsbus_read_reg(struct ncr53c9x_softc *sc, int reg)
        !           347: {
        !           348:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           349:
        !           350:        return bus_space_read_1(asc->sc_bst, asc->sc_ncrh,
        !           351:            reg * sizeof(u_int32_t));
        !           352: }
        !           353:
        !           354: void
        !           355: asc_vsbus_write_reg(struct ncr53c9x_softc *sc, int reg, u_char val)
        !           356: {
        !           357:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           358:
        !           359:        bus_space_write_1(asc->sc_bst, asc->sc_ncrh,
        !           360:            reg * sizeof(u_int32_t), val);
        !           361: }
        !           362:
        !           363: int
        !           364: asc_vsbus_dma_isintr(struct ncr53c9x_softc *sc)
        !           365: {
        !           366:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           367:        return bus_space_read_1(asc->sc_bst, asc->sc_ncrh,
        !           368:            NCR_STAT * sizeof(u_int32_t)) & NCRSTAT_INT;
        !           369: }
        !           370:
        !           371: void
        !           372: asc_vsbus_dma_reset(struct ncr53c9x_softc *sc)
        !           373: {
        !           374:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           375:
        !           376:        if (asc->sc_flags & ASC_MAPLOADED)
        !           377:                bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap);
        !           378:        asc->sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
        !           379: }
        !           380:
        !           381: int
        !           382: asc_vsbus_dma_intr(struct ncr53c9x_softc *sc)
        !           383: {
        !           384:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           385:        u_int tcl, tcm;
        !           386:        int trans, resid;
        !           387:
        !           388:        if ((asc->sc_flags & ASC_DMAACTIVE) == 0)
        !           389:                panic("asc_vsbus_dma_intr: DMA wasn't active");
        !           390:
        !           391:        asc->sc_flags &= ~ASC_DMAACTIVE;
        !           392:
        !           393:        if (asc->sc_dmasize == 0) {
        !           394:                /* A "Transfer Pad" operation completed */
        !           395:                tcl = NCR_READ_REG(sc, NCR_TCL);
        !           396:                tcm = NCR_READ_REG(sc, NCR_TCM);
        !           397:                NCR_DMA(("asc_vsbus_intr: discarded %d bytes (tcl=%d, tcm=%d)\n",
        !           398:                    tcl | (tcm << 8), tcl, tcm));
        !           399:                return 0;
        !           400:        }
        !           401:
        !           402:        resid = 0;
        !           403:        if ((resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
        !           404:                NCR_DMA(("asc_vsbus_intr: empty FIFO of %d ", resid));
        !           405:                DELAY(1);
        !           406:        }
        !           407:        if (asc->sc_flags & ASC_MAPLOADED) {
        !           408:                bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
        !           409:                                0, asc->sc_dmasize,
        !           410:                                asc->sc_flags & ASC_FROMMEMORY
        !           411:                                        ? BUS_DMASYNC_POSTWRITE
        !           412:                                        : BUS_DMASYNC_POSTREAD);
        !           413:                bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap);
        !           414:        }
        !           415:        asc->sc_flags &= ~ASC_MAPLOADED;
        !           416:
        !           417:        resid += (tcl = NCR_READ_REG(sc, NCR_TCL));
        !           418:        resid += (tcm = NCR_READ_REG(sc, NCR_TCM)) << 8;
        !           419:
        !           420:        trans = asc->sc_dmasize - resid;
        !           421:        if (trans < 0) {                        /* transferred < 0 ? */
        !           422:                printf("%s: xfer (%d) > req (%lu)\n",
        !           423:                    __func__, trans, (u_long) asc->sc_dmasize);
        !           424:                trans = asc->sc_dmasize;
        !           425:        }
        !           426:        NCR_DMA(("asc_vsbus_intr: tcl=%d, tcm=%d; trans=%d, resid=%d\n",
        !           427:            tcl, tcm, trans, resid));
        !           428:
        !           429:        *asc->sc_dmalen -= trans;
        !           430:        *asc->sc_dmaaddr += trans;
        !           431:
        !           432:        asc->sc_xfers++;
        !           433:        return 0;
        !           434: }
        !           435:
        !           436: int
        !           437: asc_vsbus_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len,
        !           438:                    int datain, size_t *dmasize)
        !           439: {
        !           440:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           441:
        !           442:        asc->sc_dmaaddr = addr;
        !           443:        asc->sc_dmalen = len;
        !           444:        if (datain) {
        !           445:                asc->sc_flags &= ~ASC_FROMMEMORY;
        !           446:        } else {
        !           447:                asc->sc_flags |= ASC_FROMMEMORY;
        !           448:        }
        !           449:        if ((vaddr_t) *asc->sc_dmaaddr < VM_MIN_KERNEL_ADDRESS)
        !           450:                panic("asc_vsbus_dma_setup: dma address (%p) outside of kernel",
        !           451:                    *asc->sc_dmaaddr);
        !           452:
        !           453:         NCR_DMA(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
        !           454:                 (int)*asc->sc_dmalen, *asc->sc_dmaaddr, (asc->sc_flags & ASC_FROMMEMORY)));
        !           455:        *dmasize = asc->sc_dmasize = min(*dmasize, ASC_MAXXFERSIZE);
        !           456:
        !           457:        if (asc->sc_dmasize) {
        !           458:                if (bus_dmamap_load(asc->sc_dmat, asc->sc_dmamap,
        !           459:                                *asc->sc_dmaaddr, asc->sc_dmasize,
        !           460:                                NULL /* kernel address */,
        !           461:                                BUS_DMA_NOWAIT|VAX_BUS_DMA_SPILLPAGE))
        !           462:                        panic("%s: cannot load dma map", sc->sc_dev.dv_xname);
        !           463:                bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
        !           464:                                0, asc->sc_dmasize,
        !           465:                                asc->sc_flags & ASC_FROMMEMORY
        !           466:                                        ? BUS_DMASYNC_PREWRITE
        !           467:                                        : BUS_DMASYNC_PREREAD);
        !           468:                bus_space_write_4(asc->sc_bst, asc->sc_adrh, 0,
        !           469:                                  asc->sc_dmamap->dm_segs[0].ds_addr);
        !           470:                bus_space_write_4(asc->sc_bst, asc->sc_dirh, 0,
        !           471:                                  asc->sc_flags & ASC_FROMMEMORY);
        !           472:                NCR_DMA(("%s: dma-load %lu@0x%08lx\n", sc->sc_dev.dv_xname,
        !           473:                        asc->sc_dmamap->dm_segs[0].ds_len,
        !           474:                        asc->sc_dmamap->dm_segs[0].ds_addr));
        !           475:                asc->sc_flags |= ASC_MAPLOADED;
        !           476:        }
        !           477:
        !           478:        return 0;
        !           479: }
        !           480:
        !           481: void
        !           482: asc_vsbus_dma_go(struct ncr53c9x_softc *sc)
        !           483: {
        !           484:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           485:
        !           486:        asc->sc_flags |= ASC_DMAACTIVE;
        !           487: }
        !           488:
        !           489: void
        !           490: asc_vsbus_dma_stop(struct ncr53c9x_softc *sc)
        !           491: {
        !           492:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           493:
        !           494:        if (asc->sc_flags & ASC_MAPLOADED) {
        !           495:                bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
        !           496:                                0, asc->sc_dmasize,
        !           497:                                asc->sc_flags & ASC_FROMMEMORY
        !           498:                                        ? BUS_DMASYNC_POSTWRITE
        !           499:                                        : BUS_DMASYNC_POSTREAD);
        !           500:                bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap);
        !           501:        }
        !           502:
        !           503:        asc->sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
        !           504: }
        !           505:
        !           506: int
        !           507: asc_vsbus_dma_isactive(struct ncr53c9x_softc *sc)
        !           508: {
        !           509:        struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
        !           510:
        !           511:        return (asc->sc_flags & ASC_DMAACTIVE) != 0;
        !           512: }

CVSweb