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

Annotation of sys/arch/sparc/dev/bpp.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: bpp.c,v 1.4 2003/06/03 21:09:02 deraadt Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1997, Jason Downs.  All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  *
        !            15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
        !            16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            18:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
        !            19:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            20:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        !            22:  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            25:  * SUCH DAMAGE.
        !            26:  */
        !            27:
        !            28: #include <sys/param.h>
        !            29: #include <sys/buf.h>
        !            30: #include <sys/kernel.h>
        !            31: #include <sys/uio.h>
        !            32: #include <sys/device.h>
        !            33: #include <sys/conf.h>
        !            34: #include <sys/systm.h>
        !            35:
        !            36: #include <machine/autoconf.h>
        !            37: #include <machine/conf.h>
        !            38:
        !            39: #include <sparc/dev/bppreg.h>
        !            40:
        !            41: #define BPP_BSIZE      1024
        !            42:
        !            43: #define LONG_TIMEOUT   30              /* XXX */
        !            44: #define SHORT_TIMEOUT  3               /* XXX */
        !            45:
        !            46: struct bpp_softc {
        !            47:        struct device sc_dev;
        !            48:
        !            49:        size_t sc_count;
        !            50:        struct buf *sc_inbuf;
        !            51:        u_int8_t *sc_cp;
        !            52:
        !            53:        char sc_open;
        !            54:
        !            55:        volatile struct bppregs *sc_regs;
        !            56: };
        !            57:
        !            58: static int bppmatch(struct device *, void *, void *);
        !            59: static void bppattach(struct device *, struct device *, void *);
        !            60:
        !            61: #define BPPUNIT(s)     minor(s)
        !            62:
        !            63: struct cfattach bpp_ca = {
        !            64:        sizeof(struct bpp_softc), bppmatch, bppattach
        !            65: };
        !            66:
        !            67: struct cfdriver bpp_cd = {
        !            68:        NULL, "bpp", DV_DULL
        !            69: };
        !            70:
        !            71: static __inline__ void bpp_outb(struct bpp_softc *, u_int8_t);
        !            72: static __inline__ u_int8_t bpp_inb(struct bpp_softc *);
        !            73: static void bppreset(struct bpp_softc *, int);
        !            74: static void bppresetmode(struct bpp_softc *);
        !            75: static int bpppushbytes(struct bpp_softc *);
        !            76:
        !            77: static int
        !            78: bppmatch(parent, vcf, aux)
        !            79:        struct device *parent;
        !            80:        void *aux, *vcf;
        !            81: {
        !            82:        register struct confargs *ca = aux;
        !            83:
        !            84:        if (strcmp(ca->ca_ra.ra_name, "SUNW,bpp"))
        !            85:                return (0);
        !            86:
        !            87:        return (1);
        !            88: }
        !            89:
        !            90: static void
        !            91: bppattach(parent, self, aux)
        !            92:        struct device *parent, *self;
        !            93:        void *aux;
        !            94: {
        !            95:        struct confargs *ca = aux;
        !            96:        struct romaux *ra = &ca->ca_ra;
        !            97:        struct bpp_softc *bpp = (void *)self;
        !            98:
        !            99:        bpp->sc_regs = mapiodev(ra->ra_reg, 0, ra->ra_len);
        !           100:
        !           101:        bppreset(bpp, 0);
        !           102:
        !           103:        switch (bpp->sc_regs->bpp_csr & BPP_DEV_ID_MASK) {
        !           104:        case BPP_DEV_ID_ZEBRA:
        !           105:                printf(": Zebra\n");
        !           106:                break;
        !           107:        case BPP_DEV_ID_L64854:
        !           108:                printf(": DMA2\n");
        !           109:                break;
        !           110:        default:
        !           111:                printf(": Unknown type\n");
        !           112:                break;
        !           113:        }
        !           114:
        !           115:        bppresetmode(bpp);
        !           116: }
        !           117:
        !           118: static void
        !           119: bppreset(bpp, verbose)
        !           120:        struct bpp_softc *bpp;
        !           121:        int verbose;
        !           122: {
        !           123:        volatile u_int32_t bpp_csr;
        !           124:
        !           125:        /* Reset hardware. */
        !           126:        bpp_csr = bpp->sc_regs->bpp_csr;
        !           127:        if ((bpp_csr & BPP_DRAINING) && !(bpp_csr & BPP_ERR_PEND)) {
        !           128:                delay(20);
        !           129:
        !           130:                bpp_csr = bpp->sc_regs->bpp_csr;
        !           131:                if (verbose && (bpp_csr & BPP_DRAINING) &&
        !           132:                    !(bpp_csr & BPP_ERR_PEND))
        !           133:                        printf("%s: draining still active (0x%08x)\n",
        !           134:                            bpp->sc_dev.dv_xname, bpp_csr);
        !           135:        }
        !           136:        bpp->sc_regs->bpp_csr = (bpp_csr | BPP_RESET) & ~BPP_INT_EN;
        !           137:        delay(500);
        !           138:        bpp->sc_regs->bpp_csr &= ~BPP_RESET;
        !           139: }
        !           140:
        !           141: static void
        !           142: bppresetmode(bpp)
        !           143:        struct bpp_softc *bpp;
        !           144: {
        !           145:        bpp->sc_regs->bpp_or = BPP_OR_AFXN|BPP_OR_SLCT_IN;
        !           146:        bpp->sc_regs->bpp_tcr = BPP_TCR_DS;
        !           147: }
        !           148:
        !           149: static __inline__ void
        !           150: bpp_outb(bpp, byte)
        !           151:        struct bpp_softc *bpp;
        !           152:        u_int8_t byte;
        !           153: {
        !           154:        bpp->sc_regs->bpp_dr = byte;
        !           155: }
        !           156:
        !           157: static __inline__ u_int8_t
        !           158: bpp_inb(bpp)
        !           159:        struct bpp_softc *bpp;
        !           160: {
        !           161:        return (bpp->sc_regs->bpp_dr);
        !           162: }
        !           163:
        !           164: int
        !           165: bppopen(dev, flag, mode, p)
        !           166:        dev_t dev;
        !           167:        int flag, mode;
        !           168:        struct proc *p;
        !           169: {
        !           170:        int unit = BPPUNIT(dev);
        !           171:        struct bpp_softc *bpp;
        !           172:
        !           173:        if (unit >= bpp_cd.cd_ndevs)
        !           174:                return (ENXIO);
        !           175:        bpp = bpp_cd.cd_devs[unit];
        !           176:        if (!bpp)
        !           177:                return (ENXIO);
        !           178:
        !           179:        if (bpp->sc_open)
        !           180:                return (EBUSY);
        !           181:
        !           182:        bpp->sc_inbuf = geteblk(BPP_BSIZE);
        !           183:        bpp->sc_count = 0;
        !           184:        bpp->sc_open = 1;
        !           185:
        !           186:        /* bppreset(bpp, 1); */
        !           187:        bppresetmode(bpp);
        !           188:
        !           189:        return (0);
        !           190: }
        !           191:
        !           192: int
        !           193: bppclose(dev, flag, mode, p)
        !           194:        dev_t dev;
        !           195:        int flag, mode;
        !           196:        struct proc *p;
        !           197: {
        !           198:        struct bpp_softc *bpp = bpp_cd.cd_devs[BPPUNIT(dev)];
        !           199:        int error = 0;
        !           200:
        !           201:        if (bpp->sc_count)
        !           202:                (void) bpppushbytes(bpp);
        !           203:
        !           204:        /* XXX */
        !           205:        bppresetmode(bpp);
        !           206:        delay(100);
        !           207:        bppreset(bpp, 1);
        !           208:        delay(100);
        !           209:        bppresetmode(bpp);
        !           210:
        !           211:        brelse(bpp->sc_inbuf);
        !           212:
        !           213:        bpp->sc_open = 0;
        !           214:        return (error);
        !           215: }
        !           216:
        !           217: int
        !           218: bpppushbytes(bpp)
        !           219:        struct bpp_softc *bpp;
        !           220: {
        !           221:        int spin, error;
        !           222:
        !           223:        while (bpp->sc_count > 0) {
        !           224:                error = 0;
        !           225:
        !           226:                /* Wait for BPP_TCR_ACK and BPP_TCR_BUSY to clear. */
        !           227:                spin = 0;
        !           228:                while ((bpp->sc_regs->bpp_tcr & BPP_TCR_ACK) ||
        !           229:                    (bpp->sc_regs->bpp_tcr & BPP_TCR_BUSY)) {
        !           230:                        delay(1000);
        !           231:                        if (++spin >= LONG_TIMEOUT)
        !           232:                                break;
        !           233:                }
        !           234:
        !           235:                if ((bpp->sc_regs->bpp_tcr & BPP_TCR_ACK) ||
        !           236:                    (bpp->sc_regs->bpp_tcr & BPP_TCR_BUSY))
        !           237:                        return (EBUSY);
        !           238:
        !           239:                bpp_outb(bpp, *bpp->sc_cp++);
        !           240:
        !           241:                /* Clear BPP_TCR_DS. */
        !           242:                bpp->sc_regs->bpp_tcr &= ~BPP_TCR_DS;
        !           243:
        !           244:                /* Short wait for BPP_TCR_BUSY. */
        !           245:                spin = 0;
        !           246:                while (!(bpp->sc_regs->bpp_tcr & BPP_TCR_BUSY)) {
        !           247:                        delay(1000);
        !           248:                        if (++spin >= SHORT_TIMEOUT)
        !           249:                                break;
        !           250:                }
        !           251:                if (!(bpp->sc_regs->bpp_tcr & BPP_TCR_BUSY))
        !           252:                        error = EIO;
        !           253:
        !           254:                /* Set BPP_TCR_DS. */
        !           255:                bpp->sc_regs->bpp_tcr |= BPP_TCR_DS;
        !           256:
        !           257:                if (error)
        !           258:                        return (error);
        !           259:
        !           260:                bpp->sc_count--;
        !           261:        }
        !           262:        return (error);
        !           263: }
        !           264:
        !           265: int
        !           266: bppwrite(dev, uio, flags)
        !           267:        dev_t dev;
        !           268:        struct uio *uio;
        !           269:        int flags;
        !           270: {
        !           271:        struct bpp_softc *bpp = bpp_cd.cd_devs[BPPUNIT(dev)];
        !           272:        size_t n;
        !           273:        int error = 0;
        !           274:
        !           275:        while ((n = min(BPP_BSIZE, uio->uio_resid)) != 0) {
        !           276:                uiomove(bpp->sc_cp = bpp->sc_inbuf->b_data, n, uio);
        !           277:                bpp->sc_count = n;
        !           278:                error = bpppushbytes(bpp);
        !           279:                if (error) {
        !           280:                        /*
        !           281:                         * Return accurate residual if interrupted or timed
        !           282:                         * out.
        !           283:                         */
        !           284:                        uio->uio_resid += bpp->sc_count;
        !           285:                        bpp->sc_count = 0;
        !           286:                        return (error);
        !           287:                }
        !           288:        }
        !           289:        return (0);
        !           290: }
        !           291:
        !           292: int
        !           293: bppioctl(dev, cmd, data, flag, p)
        !           294:        dev_t dev;
        !           295:        u_long cmd;
        !           296:        caddr_t data;
        !           297:        int flag;
        !           298:        struct proc *p;
        !           299: {
        !           300:        return (ENODEV);
        !           301: }

CVSweb