[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

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