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

Annotation of sys/dev/sbus/spif.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: spif.c,v 1.13 2006/03/04 13:00:55 miod Exp $  */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1999-2002 Jason L. Wright (jason@thought.net)
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  *
        !            16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            19:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            22:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            25:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            26:  * POSSIBILITY OF SUCH DAMAGE.
        !            27:  *
        !            28:  * Effort sponsored in part by the Defense Advanced Research Projects
        !            29:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
        !            30:  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
        !            31:  *
        !            32:  */
        !            33:
        !            34: /*
        !            35:  * Driver for the SUNW,spif: 8 serial, 1 parallel sbus board
        !            36:  * based heavily on Iain Hibbert's driver for the MAGMA cards
        !            37:  */
        !            38:
        !            39: #include <sys/param.h>
        !            40: #include <sys/systm.h>
        !            41: #include <sys/proc.h>
        !            42: #include <sys/device.h>
        !            43: #include <sys/kernel.h>
        !            44: #include <sys/file.h>
        !            45: #include <sys/errno.h>
        !            46: #include <sys/ioctl.h>
        !            47: #include <sys/mbuf.h>
        !            48: #include <sys/socket.h>
        !            49: #include <sys/syslog.h>
        !            50: #include <sys/malloc.h>
        !            51: #include <sys/tty.h>
        !            52: #include <sys/conf.h>
        !            53:
        !            54: #include <machine/autoconf.h>
        !            55: #include <dev/sbus/sbusvar.h>
        !            56: #include <dev/sbus/spifreg.h>
        !            57: #include <dev/sbus/spifvar.h>
        !            58:
        !            59: int    spifmatch(struct device *, void *, void *);
        !            60: void   spifattach(struct device *, struct device *, void *);
        !            61:
        !            62: int    sttymatch(struct device *, void *, void *);
        !            63: void   sttyattach(struct device *, struct device *, void *);
        !            64: int    sttyopen(dev_t, int, int, struct proc *);
        !            65: int    sttyclose(dev_t, int, int, struct proc *);
        !            66: int    sttyread(dev_t, struct uio *, int);
        !            67: int    sttywrite(dev_t, struct uio *, int);
        !            68: int    sttyioctl(dev_t, u_long, caddr_t, int, struct proc *);
        !            69: int    sttystop(struct tty *, int);
        !            70:
        !            71: int    spifstcintr(void *);
        !            72: int    spifstcintr_mx(struct spif_softc *, int *);
        !            73: int    spifstcintr_tx(struct spif_softc *, int *);
        !            74: int    spifstcintr_rx(struct spif_softc *, int *);
        !            75: int    spifstcintr_rxexception(struct spif_softc *, int *);
        !            76: void   spifsoftintr(void *);
        !            77:
        !            78: int    stty_param(struct tty *, struct termios *);
        !            79: struct tty *sttytty(dev_t);
        !            80: int    stty_modem_control(struct stty_port *, int, int);
        !            81: void   stty_write_ccr(struct spif_softc *, u_int8_t);
        !            82: int    stty_compute_baud(speed_t, int, u_int8_t *, u_int8_t *);
        !            83: void   stty_start(struct tty *);
        !            84:
        !            85: int    sbppmatch(struct device *, void *, void *);
        !            86: void   sbppattach(struct device *, struct device *, void *);
        !            87: int    sbppopen(dev_t, int, int, struct proc *);
        !            88: int    sbppclose(dev_t, int, int, struct proc *);
        !            89: int    sbppread(dev_t, struct uio *, int);
        !            90: int    sbppwrite(dev_t, struct uio *, int);
        !            91: int    sbpp_rw(dev_t, struct uio *);
        !            92: int    spifppcintr(void *);
        !            93: int    sbpppoll(dev_t, int, struct proc *);
        !            94: int    sbppioctl(dev_t, u_long, caddr_t, int, struct proc *);
        !            95:
        !            96: struct cfattach spif_ca = {
        !            97:        sizeof (struct spif_softc), spifmatch, spifattach
        !            98: };
        !            99:
        !           100: struct cfdriver spif_cd = {
        !           101:        NULL, "spif", DV_DULL
        !           102: };
        !           103:
        !           104: struct cfattach stty_ca = {
        !           105:        sizeof(struct stty_softc), sttymatch, sttyattach
        !           106: };
        !           107:
        !           108: struct cfdriver stty_cd = {
        !           109:        NULL, "stty", DV_TTY
        !           110: };
        !           111:
        !           112: struct cfattach sbpp_ca = {
        !           113:        sizeof(struct sbpp_softc), sbppmatch, sbppattach
        !           114: };
        !           115:
        !           116: struct cfdriver sbpp_cd = {
        !           117:        NULL, "sbpp", DV_DULL
        !           118: };
        !           119:
        !           120: /* normal STC access */
        !           121: #define        STC_WRITE(sc,r,v)       \
        !           122:     bus_space_write_1((sc)->sc_bustag, (sc)->sc_stch, (r), (v))
        !           123: #define        STC_READ(sc,r)          \
        !           124:     bus_space_read_1((sc)->sc_bustag, (sc)->sc_stch, (r))
        !           125:
        !           126: /* IACK STC access */
        !           127: #define        ISTC_WRITE(sc,r,v)      \
        !           128:     bus_space_write_1((sc)->sc_bustag, (sc)->sc_istch, (r), (v))
        !           129: #define        ISTC_READ(sc,r)         \
        !           130:     bus_space_read_1((sc)->sc_bustag, (sc)->sc_istch, (r))
        !           131:
        !           132: /* PPC access */
        !           133: #define        PPC_WRITE(sc,r,v)       \
        !           134:     bus_space_write_1((sc)->sc_bustag, (sc)->sc_ppch, (r), (v))
        !           135: #define        PPC_READ(sc,r)          \
        !           136:     bus_space_read_1((sc)->sc_bustag, (sc)->sc_ppch, (r))
        !           137:
        !           138: #define        DTR_WRITE(sc,port,v)                                            \
        !           139:     do {                                                               \
        !           140:        sc->sc_ttys->sc_port[(port)].sp_dtr = v;                        \
        !           141:        bus_space_write_1((sc)->sc_bustag,                              \
        !           142:            sc->sc_dtrh, port, (v == 0) ? 1 : 0);                       \
        !           143:     } while (0)
        !           144:
        !           145: #define        DTR_READ(sc,port)       ((sc)->sc_ttys->sc_port[(port)].sp_dtr)
        !           146:
        !           147: int
        !           148: spifmatch(parent, vcf, aux)
        !           149:        struct device *parent;
        !           150:        void *vcf, *aux;
        !           151: {
        !           152:        struct cfdata *cf = vcf;
        !           153:        struct sbus_attach_args *sa = aux;
        !           154:
        !           155:        if (strcmp(cf->cf_driver->cd_name, sa->sa_name) &&
        !           156:            strcmp("SUNW,spif", sa->sa_name))
        !           157:                return (0);
        !           158:        return (1);
        !           159: }
        !           160:
        !           161: void
        !           162: spifattach(parent, self, aux)
        !           163:        struct device *parent, *self;
        !           164:        void *aux;
        !           165: {
        !           166:        struct spif_softc *sc = (struct spif_softc *)self;
        !           167:        struct sbus_attach_args *sa = aux;
        !           168:
        !           169:        if (sa->sa_nintr != 2) {
        !           170:                printf(": expected %d interrupts, got %d\n", 2, sa->sa_nintr);
        !           171:                return;
        !           172:        }
        !           173:
        !           174:        if (sa->sa_nreg != 1) {
        !           175:                printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
        !           176:                return;
        !           177:        }
        !           178:
        !           179:        sc->sc_bustag = sa->sa_bustag;
        !           180:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           181:            sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size,
        !           182:            0, 0, &sc->sc_regh) != 0) {
        !           183:                printf(": can't map registers\n");
        !           184:                return;
        !           185:        }
        !           186:
        !           187:        if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
        !           188:            DTR_REG_OFFSET, DTR_REG_LEN, &sc->sc_dtrh) != 0) {
        !           189:                printf(": can't map dtr regs\n");
        !           190:                goto fail_unmapregs;
        !           191:        }
        !           192:
        !           193:        if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
        !           194:            STC_REG_OFFSET, STC_REG_LEN, &sc->sc_stch) != 0) {
        !           195:                printf(": can't map dtr regs\n");
        !           196:                goto fail_unmapregs;
        !           197:        }
        !           198:
        !           199:        if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
        !           200:            ISTC_REG_OFFSET, ISTC_REG_LEN, &sc->sc_istch) != 0) {
        !           201:                printf(": can't map dtr regs\n");
        !           202:                goto fail_unmapregs;
        !           203:        }
        !           204:
        !           205:        if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
        !           206:            PPC_REG_OFFSET, PPC_REG_LEN, &sc->sc_ppch) != 0) {
        !           207:                printf(": can't map dtr regs\n");
        !           208:                goto fail_unmapregs;
        !           209:        }
        !           210:
        !           211:        sc->sc_ppcih = bus_intr_establish(sa->sa_bustag,
        !           212:            sa->sa_intr[PARALLEL_INTR].sbi_pri, IPL_TTY, 0, spifppcintr, sc,
        !           213:            self->dv_xname);
        !           214:        if (sc->sc_ppcih == NULL) {
        !           215:                printf(": failed to establish ppc interrupt\n");
        !           216:                goto fail_unmapregs;
        !           217:        }
        !           218:
        !           219:        sc->sc_stcih = bus_intr_establish(sa->sa_bustag,
        !           220:            sa->sa_intr[SERIAL_INTR].sbi_pri, IPL_TTY, 0, spifstcintr, sc,
        !           221:            self->dv_xname);
        !           222:        if (sc->sc_stcih == NULL) {
        !           223:                printf(": failed to establish stc interrupt\n");
        !           224:                goto fail_unmapregs;
        !           225:        }
        !           226:
        !           227:        sc->sc_softih = softintr_establish(IPL_TTY, spifsoftintr, sc);
        !           228:        if (sc->sc_softih == NULL) {
        !           229:                printf(": can't get soft intr\n");
        !           230:                goto fail_unmapregs;
        !           231:        }
        !           232:
        !           233:        sc->sc_node = sa->sa_node;
        !           234:
        !           235:        sc->sc_rev = getpropint(sc->sc_node, "revlev", 0);
        !           236:
        !           237:        sc->sc_osc = getpropint(sc->sc_node, "verosc", 0);
        !           238:        switch (sc->sc_osc) {
        !           239:        case SPIF_OSC10:
        !           240:                sc->sc_osc = 10000000;
        !           241:                break;
        !           242:        case SPIF_OSC9:
        !           243:        default:
        !           244:                sc->sc_osc = 9830400;
        !           245:                break;
        !           246:        }
        !           247:
        !           248:        sc->sc_nser = 8;
        !           249:        sc->sc_npar = 1;
        !           250:
        !           251:        sc->sc_rev2 = STC_READ(sc, STC_GFRCR);
        !           252:        STC_WRITE(sc, STC_GSVR, 0);
        !           253:
        !           254:        stty_write_ccr(sc, CD180_CCR_CMD_RESET | CD180_CCR_RESETALL);
        !           255:        while (STC_READ(sc, STC_GSVR) != 0xff);
        !           256:        while (STC_READ(sc, STC_GFRCR) != sc->sc_rev2);
        !           257:
        !           258:        STC_WRITE(sc, STC_PPRH, CD180_PPRH);
        !           259:        STC_WRITE(sc, STC_PPRL, CD180_PPRL);
        !           260:        STC_WRITE(sc, STC_MSMR, SPIF_MSMR);
        !           261:        STC_WRITE(sc, STC_TSMR, SPIF_TSMR);
        !           262:        STC_WRITE(sc, STC_RSMR, SPIF_RSMR);
        !           263:        STC_WRITE(sc, STC_GSVR, 0);
        !           264:        STC_WRITE(sc, STC_GSCR1, 0);
        !           265:        STC_WRITE(sc, STC_GSCR2, 0);
        !           266:        STC_WRITE(sc, STC_GSCR3, 0);
        !           267:
        !           268:        printf(": rev %x chiprev %x osc %sMHz\n",
        !           269:            sc->sc_rev, sc->sc_rev2, clockfreq(sc->sc_osc));
        !           270:
        !           271:        (void)config_found(self, sttymatch, NULL);
        !           272:        (void)config_found(self, sbppmatch, NULL);
        !           273:
        !           274:        return;
        !           275:
        !           276: fail_unmapregs:
        !           277:        bus_space_unmap(sa->sa_bustag, sc->sc_regh, sa->sa_reg[0].sbr_size);
        !           278: }
        !           279:
        !           280: int
        !           281: sttymatch(parent, vcf, aux)
        !           282:        struct device *parent;
        !           283:        void *vcf, *aux;
        !           284: {
        !           285:        struct spif_softc *sc = (struct spif_softc *)parent;
        !           286:
        !           287:        return (aux == sttymatch && sc->sc_ttys == NULL);
        !           288: }
        !           289:
        !           290: void
        !           291: sttyattach(parent, dev, aux)
        !           292:        struct device *parent, *dev;
        !           293:        void *aux;
        !           294: {
        !           295:        struct spif_softc *sc = (struct spif_softc *)parent;
        !           296:        struct stty_softc *ssc = (struct stty_softc *)dev;
        !           297:        int port;
        !           298:
        !           299:        sc->sc_ttys = ssc;
        !           300:
        !           301:        for (port = 0; port < sc->sc_nser; port++) {
        !           302:                struct stty_port *sp = &ssc->sc_port[port];
        !           303:                struct tty *tp;
        !           304:
        !           305:                DTR_WRITE(sc, port, 0);
        !           306:
        !           307:                tp = ttymalloc();
        !           308:
        !           309:                tp->t_oproc = stty_start;
        !           310:                tp->t_param = stty_param;
        !           311:
        !           312:                sp->sp_tty = tp;
        !           313:                sp->sp_sc = sc;
        !           314:                sp->sp_channel = port;
        !           315:
        !           316:                sp->sp_rbuf = malloc(STTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT);
        !           317:                if(sp->sp_rbuf == NULL)
        !           318:                        break;
        !           319:
        !           320:                sp->sp_rend = sp->sp_rbuf + STTY_RBUF_SIZE;
        !           321:        }
        !           322:
        !           323:        ssc->sc_nports = port;
        !           324:
        !           325:        printf(": %d tty%s\n", port, port == 1 ? "" : "s");
        !           326: }
        !           327:
        !           328: int
        !           329: sttyopen(dev, flags, mode, p)
        !           330:        dev_t dev;
        !           331:        int flags;
        !           332:        int mode;
        !           333:        struct proc *p;
        !           334: {
        !           335:        struct spif_softc *csc;
        !           336:        struct stty_softc *sc;
        !           337:        struct stty_port *sp;
        !           338:        struct tty *tp;
        !           339:        int card = SPIF_CARD(dev);
        !           340:        int port = SPIF_PORT(dev);
        !           341:        int s;
        !           342:
        !           343:        if (card >= stty_cd.cd_ndevs || card >= spif_cd.cd_ndevs)
        !           344:                return (ENXIO);
        !           345:
        !           346:        sc = stty_cd.cd_devs[card];
        !           347:        csc = spif_cd.cd_devs[card];
        !           348:        if (sc == NULL || csc == NULL)
        !           349:                return (ENXIO);
        !           350:
        !           351:        if (port >= sc->sc_nports)
        !           352:                return (ENXIO);
        !           353:
        !           354:        sp = &sc->sc_port[port];
        !           355:        tp = sp->sp_tty;
        !           356:        tp->t_dev = dev;
        !           357:
        !           358:        if (!ISSET(tp->t_state, TS_ISOPEN)) {
        !           359:                SET(tp->t_state, TS_WOPEN);
        !           360:
        !           361:                ttychars(tp);
        !           362:                tp->t_iflag = TTYDEF_IFLAG;
        !           363:                tp->t_oflag = TTYDEF_OFLAG;
        !           364:                tp->t_cflag = TTYDEF_CFLAG;
        !           365:                if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL))
        !           366:                        SET(tp->t_cflag, CLOCAL);
        !           367:                if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS))
        !           368:                        SET(tp->t_cflag, CRTSCTS);
        !           369:                if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF))
        !           370:                        SET(tp->t_cflag, MDMBUF);
        !           371:                tp->t_lflag = TTYDEF_LFLAG;
        !           372:                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
        !           373:
        !           374:                sp->sp_rput = sp->sp_rget = sp->sp_rbuf;
        !           375:
        !           376:                s = spltty();
        !           377:
        !           378:                STC_WRITE(csc, STC_CAR, sp->sp_channel);
        !           379:                stty_write_ccr(csc, CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN);
        !           380:                STC_WRITE(csc, STC_CAR, sp->sp_channel);
        !           381:
        !           382:                stty_param(tp, &tp->t_termios);
        !           383:
        !           384:                ttsetwater(tp);
        !           385:
        !           386:                STC_WRITE(csc, STC_SRER, CD180_SRER_CD | CD180_SRER_RXD);
        !           387:
        !           388:                if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier)
        !           389:                        SET(tp->t_state, TS_CARR_ON);
        !           390:                else
        !           391:                        CLR(tp->t_state, TS_CARR_ON);
        !           392:        }
        !           393:        else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) {
        !           394:                return (EBUSY);
        !           395:        } else {
        !           396:                s = spltty();
        !           397:        }
        !           398:
        !           399:        if (!ISSET(flags, O_NONBLOCK)) {
        !           400:                while (!ISSET(tp->t_cflag, CLOCAL) &&
        !           401:                    !ISSET(tp->t_state, TS_CARR_ON)) {
        !           402:                        int error;
        !           403:
        !           404:                        SET(tp->t_state, TS_WOPEN);
        !           405:                        error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
        !           406:                            "sttycd", 0);
        !           407:                        if (error != 0) {
        !           408:                                splx(s);
        !           409:                                CLR(tp->t_state, TS_WOPEN);
        !           410:                                return (error);
        !           411:                        }
        !           412:                }
        !           413:        }
        !           414:
        !           415:        splx(s);
        !           416:
        !           417:        return ((*linesw[tp->t_line].l_open)(dev, tp));
        !           418: }
        !           419:
        !           420: int
        !           421: sttyclose(dev, flags, mode, p)
        !           422:        dev_t dev;
        !           423:        int flags;
        !           424:        int mode;
        !           425:        struct proc *p;
        !           426: {
        !           427:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           428:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           429:        struct spif_softc *csc = sp->sp_sc;
        !           430:        struct tty *tp = sp->sp_tty;
        !           431:        int port = SPIF_PORT(dev);
        !           432:        int s;
        !           433:
        !           434:        (*linesw[tp->t_line].l_close)(tp, flags);
        !           435:        s = spltty();
        !           436:
        !           437:        if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) {
        !           438:                stty_modem_control(sp, 0, DMSET);
        !           439:                STC_WRITE(csc, STC_CAR, port);
        !           440:                STC_WRITE(csc, STC_CCR,
        !           441:                    CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN);
        !           442:        }
        !           443:
        !           444:        splx(s);
        !           445:        ttyclose(tp);
        !           446:        return (0);
        !           447: }
        !           448:
        !           449: int
        !           450: sttyioctl(dev, cmd, data, flags, p)
        !           451:        dev_t dev;
        !           452:        u_long cmd;
        !           453:        caddr_t data;
        !           454:        int flags;
        !           455:        struct proc *p;
        !           456: {
        !           457:        struct stty_softc *stc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           458:        struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)];
        !           459:        struct spif_softc *sc = sp->sp_sc;
        !           460:        struct tty *tp = sp->sp_tty;
        !           461:        int error;
        !           462:
        !           463:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p);
        !           464:        if (error >= 0)
        !           465:                return (error);
        !           466:
        !           467:        error = ttioctl(tp, cmd, data, flags, p);
        !           468:        if (error >= 0)
        !           469:                return (error);
        !           470:
        !           471:        error = 0;
        !           472:
        !           473:        switch (cmd) {
        !           474:        case TIOCSBRK:
        !           475:                SET(sp->sp_flags, STTYF_SET_BREAK);
        !           476:                STC_WRITE(sc, STC_CAR, sp->sp_channel);
        !           477:                STC_WRITE(sc, STC_SRER,
        !           478:                    STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
        !           479:                break;
        !           480:        case TIOCCBRK:
        !           481:                SET(sp->sp_flags, STTYF_CLR_BREAK);
        !           482:                STC_WRITE(sc, STC_CAR, sp->sp_channel);
        !           483:                STC_WRITE(sc, STC_SRER,
        !           484:                    STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
        !           485:                break;
        !           486:        case TIOCSDTR:
        !           487:                stty_modem_control(sp, TIOCM_DTR, DMBIS);
        !           488:                break;
        !           489:        case TIOCCDTR:
        !           490:                stty_modem_control(sp, TIOCM_DTR, DMBIC);
        !           491:                break;
        !           492:        case TIOCMBIS:
        !           493:                stty_modem_control(sp, *((int *)data), DMBIS);
        !           494:                break;
        !           495:        case TIOCMBIC:
        !           496:                stty_modem_control(sp, *((int *)data), DMBIC);
        !           497:                break;
        !           498:        case TIOCMGET:
        !           499:                *((int *)data) = stty_modem_control(sp, 0, DMGET);
        !           500:                break;
        !           501:        case TIOCMSET:
        !           502:                stty_modem_control(sp, *((int *)data), DMSET);
        !           503:                break;
        !           504:        case TIOCGFLAGS:
        !           505:                *((int *)data) = sp->sp_openflags;
        !           506:                break;
        !           507:        case TIOCSFLAGS:
        !           508:                if (suser(p, 0))
        !           509:                        error = EPERM;
        !           510:                else
        !           511:                        sp->sp_openflags = *((int *)data) &
        !           512:                            (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
        !           513:                             TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
        !           514:                break;
        !           515:        default:
        !           516:                error = ENOTTY;
        !           517:        }
        !           518:
        !           519:        return (error);
        !           520: }
        !           521:
        !           522: int
        !           523: stty_modem_control(sp, bits, how)
        !           524:        struct stty_port *sp;
        !           525:        int bits, how;
        !           526: {
        !           527:        struct spif_softc *csc = sp->sp_sc;
        !           528:        struct tty *tp = sp->sp_tty;
        !           529:        int s, msvr;
        !           530:
        !           531:        s = spltty();
        !           532:        STC_WRITE(csc, STC_CAR, sp->sp_channel);
        !           533:
        !           534:        switch (how) {
        !           535:        case DMGET:
        !           536:                bits = TIOCM_LE;
        !           537:                if (DTR_READ(csc, sp->sp_channel))
        !           538:                        bits |= TIOCM_DTR;
        !           539:                msvr = STC_READ(csc, STC_MSVR);
        !           540:                if (ISSET(msvr, CD180_MSVR_DSR))
        !           541:                        bits |= TIOCM_DSR;
        !           542:                if (ISSET(msvr, CD180_MSVR_CD))
        !           543:                        bits |= TIOCM_CD;
        !           544:                if (ISSET(msvr, CD180_MSVR_CTS))
        !           545:                        bits |= TIOCM_CTS;
        !           546:                if (ISSET(msvr, CD180_MSVR_RTS))
        !           547:                        bits |= TIOCM_RTS;
        !           548:                break;
        !           549:        case DMSET:
        !           550:                DTR_WRITE(csc, sp->sp_channel, ISSET(bits, TIOCM_DTR) ? 1 : 0);
        !           551:                if (ISSET(bits, TIOCM_RTS))
        !           552:                        STC_WRITE(csc, STC_MSVR,
        !           553:                            STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS));
        !           554:                else
        !           555:                        STC_WRITE(csc, STC_MSVR,
        !           556:                            STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS);
        !           557:                break;
        !           558:        case DMBIS:
        !           559:                if (ISSET(bits, TIOCM_DTR))
        !           560:                        DTR_WRITE(csc, sp->sp_channel, 1);
        !           561:                if (ISSET(bits, TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS))
        !           562:                        STC_WRITE(csc, STC_MSVR,
        !           563:                            STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS));
        !           564:                break;
        !           565:        case DMBIC:
        !           566:                if (ISSET(bits, TIOCM_DTR))
        !           567:                        DTR_WRITE(csc, sp->sp_channel, 0);
        !           568:                if (ISSET(bits, TIOCM_RTS))
        !           569:                        STC_WRITE(csc, STC_MSVR,
        !           570:                            STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS);
        !           571:                break;
        !           572:        }
        !           573:
        !           574:        splx(s);
        !           575:        return (bits);
        !           576: }
        !           577:
        !           578: int
        !           579: stty_param(tp, t)
        !           580:        struct tty *tp;
        !           581:        struct termios *t;
        !           582: {
        !           583:        struct stty_softc *st = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
        !           584:        struct stty_port *sp = &st->sc_port[SPIF_PORT(tp->t_dev)];
        !           585:        struct spif_softc *sc = sp->sp_sc;
        !           586:        u_int8_t rbprl, rbprh, tbprl, tbprh;
        !           587:        int s, opt;
        !           588:
        !           589:        if (t->c_ospeed &&
        !           590:            stty_compute_baud(t->c_ospeed, sc->sc_osc, &tbprl, &tbprh))
        !           591:                return (EINVAL);
        !           592:
        !           593:        if (t->c_ispeed &&
        !           594:            stty_compute_baud(t->c_ispeed, sc->sc_osc, &rbprl, &rbprh))
        !           595:                return (EINVAL);
        !           596:
        !           597:        s = spltty();
        !           598:
        !           599:        /* hang up line if ospeed is zero, otherwise raise DTR */
        !           600:        stty_modem_control(sp, TIOCM_DTR,
        !           601:            (t->c_ospeed == 0 ? DMBIC : DMBIS));
        !           602:
        !           603:        STC_WRITE(sc, STC_CAR, sp->sp_channel);
        !           604:
        !           605:        opt = 0;
        !           606:        if (ISSET(t->c_cflag, PARENB)) {
        !           607:                opt |= CD180_COR1_PARMODE_NORMAL;
        !           608:                opt |= (ISSET(t->c_cflag, PARODD) ?
        !           609:                                CD180_COR1_ODDPAR :
        !           610:                                CD180_COR1_EVENPAR);
        !           611:        }
        !           612:        else
        !           613:                opt |= CD180_COR1_PARMODE_NO;
        !           614:
        !           615:        if (!ISSET(t->c_iflag, INPCK))
        !           616:                opt |= CD180_COR1_IGNPAR;
        !           617:
        !           618:        if (ISSET(t->c_cflag, CSTOPB))
        !           619:                opt |= CD180_COR1_STOP2;
        !           620:
        !           621:        switch (t->c_cflag & CSIZE) {
        !           622:        case CS5:
        !           623:                opt |= CD180_COR1_CS5;
        !           624:                break;
        !           625:        case CS6:
        !           626:                opt |= CD180_COR1_CS6;
        !           627:                break;
        !           628:        case CS7:
        !           629:                opt |= CD180_COR1_CS7;
        !           630:                break;
        !           631:        default:
        !           632:                opt |= CD180_COR1_CS8;
        !           633:                break;
        !           634:        }
        !           635:        STC_WRITE(sc, STC_COR1, opt);
        !           636:        stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG1);
        !           637:
        !           638:        opt = CD180_COR2_ETC;
        !           639:        if (ISSET(t->c_cflag, CRTSCTS))
        !           640:                opt |= CD180_COR2_CTSAE;
        !           641:        STC_WRITE(sc, STC_COR2, opt);
        !           642:        stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG2);
        !           643:
        !           644:        STC_WRITE(sc, STC_COR3, STTY_RX_FIFO_THRESHOLD);
        !           645:        stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG3);
        !           646:
        !           647:        STC_WRITE(sc, STC_SCHR1, 0x11);
        !           648:        STC_WRITE(sc, STC_SCHR2, 0x13);
        !           649:        STC_WRITE(sc, STC_SCHR3, 0x11);
        !           650:        STC_WRITE(sc, STC_SCHR4, 0x13);
        !           651:        STC_WRITE(sc, STC_RTPR, 0x12);
        !           652:
        !           653:        STC_WRITE(sc, STC_MCOR1, CD180_MCOR1_CDZD | STTY_RX_DTR_THRESHOLD);
        !           654:        STC_WRITE(sc, STC_MCOR2, CD180_MCOR2_CDOD);
        !           655:        STC_WRITE(sc, STC_MCR, 0);
        !           656:
        !           657:        if (t->c_ospeed) {
        !           658:                STC_WRITE(sc, STC_TBPRH, tbprh);
        !           659:                STC_WRITE(sc, STC_TBPRL, tbprl);
        !           660:        }
        !           661:
        !           662:        if (t->c_ispeed) {
        !           663:                STC_WRITE(sc, STC_RBPRH, rbprh);
        !           664:                STC_WRITE(sc, STC_RBPRL, rbprl);
        !           665:        }
        !           666:
        !           667:        stty_write_ccr(sc, CD180_CCR_CMD_CHAN |
        !           668:            CD180_CCR_CHAN_TXEN | CD180_CCR_CHAN_RXEN);
        !           669:
        !           670:        sp->sp_carrier = STC_READ(sc, STC_MSVR) & CD180_MSVR_CD;
        !           671:
        !           672:        splx(s);
        !           673:        return (0);
        !           674: }
        !           675:
        !           676: int
        !           677: sttyread(dev, uio, flags)
        !           678:        dev_t dev;
        !           679:        struct uio *uio;
        !           680:        int flags;
        !           681: {
        !           682:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           683:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           684:        struct tty *tp = sp->sp_tty;
        !           685:
        !           686:        return ((*linesw[tp->t_line].l_read)(tp, uio, flags));
        !           687: }
        !           688:
        !           689: int
        !           690: sttywrite(dev, uio, flags)
        !           691:        dev_t dev;
        !           692:        struct uio *uio;
        !           693:        int flags;
        !           694: {
        !           695:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           696:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           697:        struct tty *tp = sp->sp_tty;
        !           698:
        !           699:        return ((*linesw[tp->t_line].l_write)(tp, uio, flags));
        !           700: }
        !           701:
        !           702: struct tty *
        !           703: sttytty(dev)
        !           704:        dev_t dev;
        !           705: {
        !           706:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           707:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           708:
        !           709:        return (sp->sp_tty);
        !           710: }
        !           711:
        !           712: int
        !           713: sttystop(tp, flags)
        !           714:        struct tty *tp;
        !           715:        int flags;
        !           716: {
        !           717:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
        !           718:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)];
        !           719:        int s;
        !           720:
        !           721:        s = spltty();
        !           722:        if (ISSET(tp->t_state, TS_BUSY)) {
        !           723:                if (!ISSET(tp->t_state, TS_TTSTOP))
        !           724:                        SET(tp->t_state, TS_FLUSH);
        !           725:                SET(sp->sp_flags, STTYF_STOP);
        !           726:        }
        !           727:        splx(s);
        !           728:        return (0);
        !           729: }
        !           730:
        !           731: void
        !           732: stty_start(tp)
        !           733:        struct tty *tp;
        !           734: {
        !           735:        struct stty_softc *stc = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
        !           736:        struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)];
        !           737:        struct spif_softc *sc = sp->sp_sc;
        !           738:        int s;
        !           739:
        !           740:        s = spltty();
        !           741:
        !           742:        if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
        !           743:                if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           744:                        if (ISSET(tp->t_state, TS_ASLEEP)) {
        !           745:                                CLR(tp->t_state, TS_ASLEEP);
        !           746:                                wakeup(&tp->t_outq);
        !           747:                        }
        !           748:                        selwakeup(&tp->t_wsel);
        !           749:                }
        !           750:                if (tp->t_outq.c_cc) {
        !           751:                        sp->sp_txc = ndqb(&tp->t_outq, 0);
        !           752:                        sp->sp_txp = tp->t_outq.c_cf;
        !           753:                        SET(tp->t_state, TS_BUSY);
        !           754:                        STC_WRITE(sc, STC_CAR, sp->sp_channel);
        !           755:                        STC_WRITE(sc, STC_SRER,
        !           756:                            STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
        !           757:                }
        !           758:        }
        !           759:
        !           760:        splx(s);
        !           761: }
        !           762:
        !           763: int
        !           764: spifstcintr_rxexception(sc, needsoftp)
        !           765:        struct spif_softc *sc;
        !           766:        int *needsoftp;
        !           767: {
        !           768:        struct stty_port *sp;
        !           769:        u_int8_t channel, *ptr;
        !           770:
        !           771:        channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
        !           772:        sp = &sc->sc_ttys->sc_port[channel];
        !           773:        ptr = sp->sp_rput;
        !           774:        *ptr++ = STC_READ(sc, STC_RCSR);
        !           775:        *ptr++ = STC_READ(sc, STC_RDR);
        !           776:        if (ptr == sp->sp_rend)
        !           777:                ptr = sp->sp_rbuf;
        !           778:        if (ptr == sp->sp_rget) {
        !           779:                if (ptr == sp->sp_rbuf)
        !           780:                        ptr = sp->sp_rend;
        !           781:                ptr -= 2;
        !           782:                SET(sp->sp_flags, STTYF_RING_OVERFLOW);
        !           783:        }
        !           784:        STC_WRITE(sc, STC_EOSRR, 0);
        !           785:        *needsoftp = 1;
        !           786:        sp->sp_rput = ptr;
        !           787:        return (1);
        !           788: }
        !           789:
        !           790: int
        !           791: spifstcintr_rx(sc, needsoftp)
        !           792:        struct spif_softc *sc;
        !           793:        int *needsoftp;
        !           794: {
        !           795:        struct stty_port *sp;
        !           796:        u_int8_t channel, *ptr, cnt, rcsr;
        !           797:        int i;
        !           798:
        !           799:        channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
        !           800:        sp = &sc->sc_ttys->sc_port[channel];
        !           801:        ptr = sp->sp_rput;
        !           802:        cnt = STC_READ(sc, STC_RDCR);
        !           803:        for (i = 0; i < cnt; i++) {
        !           804:                *ptr++ = 0;
        !           805:                rcsr = STC_READ(sc, STC_RCSR);
        !           806:                *ptr++ = STC_READ(sc, STC_RDR);
        !           807:                if (ptr == sp->sp_rend)
        !           808:                        ptr = sp->sp_rbuf;
        !           809:                if (ptr == sp->sp_rget) {
        !           810:                        if (ptr == sp->sp_rbuf)
        !           811:                                ptr = sp->sp_rend;
        !           812:                        ptr -= 2;
        !           813:                        SET(sp->sp_flags, STTYF_RING_OVERFLOW);
        !           814:                        break;
        !           815:                }
        !           816:        }
        !           817:        STC_WRITE(sc, STC_EOSRR, 0);
        !           818:        if (cnt) {
        !           819:                *needsoftp = 1;
        !           820:                sp->sp_rput = ptr;
        !           821:        }
        !           822:        return (1);
        !           823: }
        !           824:
        !           825: int
        !           826: spifstcintr_tx(sc, needsoftp)
        !           827:        struct spif_softc *sc;
        !           828:        int *needsoftp;
        !           829: {
        !           830:        struct stty_port *sp;
        !           831:        u_int8_t channel, ch;
        !           832:        int cnt = 0;
        !           833:
        !           834:        channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
        !           835:        sp = &sc->sc_ttys->sc_port[channel];
        !           836:        if (!ISSET(sp->sp_flags, STTYF_STOP)) {
        !           837:                if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) {
        !           838:                        STC_WRITE(sc, STC_TDR, 0);
        !           839:                        STC_WRITE(sc, STC_TDR, 0x81);
        !           840:                        CLR(sp->sp_flags, STTYF_SET_BREAK);
        !           841:                        cnt += 2;
        !           842:                }
        !           843:                if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) {
        !           844:                        STC_WRITE(sc, STC_TDR, 0);
        !           845:                        STC_WRITE(sc, STC_TDR, 0x83);
        !           846:                        CLR(sp->sp_flags, STTYF_CLR_BREAK);
        !           847:                        cnt += 2;
        !           848:                }
        !           849:
        !           850:                while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) {
        !           851:                        ch = *sp->sp_txp;
        !           852:                        sp->sp_txc--;
        !           853:                        sp->sp_txp++;
        !           854:
        !           855:                        if (ch == 0) {
        !           856:                                STC_WRITE(sc, STC_TDR, ch);
        !           857:                                cnt++;
        !           858:                        }
        !           859:                        STC_WRITE(sc, STC_TDR, ch);
        !           860:                        cnt++;
        !           861:                }
        !           862:        }
        !           863:
        !           864:        if (sp->sp_txc == 0 ||
        !           865:            ISSET(sp->sp_flags, STTYF_STOP)) {
        !           866:                STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) &
        !           867:                    (~CD180_SRER_TXD));
        !           868:                CLR(sp->sp_flags, STTYF_STOP);
        !           869:                SET(sp->sp_flags, STTYF_DONE);
        !           870:                *needsoftp = 1;
        !           871:        }
        !           872:
        !           873:        STC_WRITE(sc, STC_EOSRR, 0);
        !           874:
        !           875:        return (1);
        !           876: }
        !           877:
        !           878: int
        !           879: spifstcintr_mx(sc, needsoftp)
        !           880:        struct spif_softc *sc;
        !           881:        int *needsoftp;
        !           882: {
        !           883:        struct stty_port *sp;
        !           884:        u_int8_t channel, mcr;
        !           885:
        !           886:        channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
        !           887:        sp = &sc->sc_ttys->sc_port[channel];
        !           888:        mcr = STC_READ(sc, STC_MCR);
        !           889:        if (mcr & CD180_MCR_CD) {
        !           890:                SET(sp->sp_flags, STTYF_CDCHG);
        !           891:                *needsoftp = 1;
        !           892:        }
        !           893:        STC_WRITE(sc, STC_MCR, 0);
        !           894:        STC_WRITE(sc, STC_EOSRR, 0);
        !           895:        return (1);
        !           896: }
        !           897:
        !           898: int
        !           899: spifstcintr(vsc)
        !           900:        void *vsc;
        !           901: {
        !           902:        struct spif_softc *sc = (struct spif_softc *)vsc;
        !           903:        int needsoft = 0, r = 0, i;
        !           904:        u_int8_t ar;
        !           905:
        !           906:        for (i = 0; i < 8; i++) {
        !           907:                ar = ISTC_READ(sc, STC_RRAR) & CD180_GSVR_IMASK;
        !           908:                if (ar == CD180_GSVR_RXGOOD)
        !           909:                        r |= spifstcintr_rx(sc, &needsoft);
        !           910:                else if (ar == CD180_GSVR_RXEXCEPTION)
        !           911:                        r |= spifstcintr_rxexception(sc, &needsoft);
        !           912:        }
        !           913:
        !           914:        for (i = 0; i < 8; i++) {
        !           915:                ar = ISTC_READ(sc, STC_TRAR) & CD180_GSVR_IMASK;
        !           916:                if (ar == CD180_GSVR_TXDATA)
        !           917:                        r |= spifstcintr_tx(sc, &needsoft);
        !           918:        }
        !           919:
        !           920:        for (i = 0; i < 8; i++) {
        !           921:                ar = ISTC_READ(sc, STC_MRAR) & CD180_GSVR_IMASK;
        !           922:                if (ar == CD180_GSVR_STATCHG)
        !           923:                        r |= spifstcintr_mx(sc, &needsoft);
        !           924:        }
        !           925:
        !           926:        if (needsoft)
        !           927:                softintr_schedule(sc->sc_softih);
        !           928:        return (r);
        !           929: }
        !           930:
        !           931: void
        !           932: spifsoftintr(vsc)
        !           933:        void *vsc;
        !           934: {
        !           935:        struct spif_softc *sc = (struct spif_softc *)vsc;
        !           936:        struct stty_softc *stc = sc->sc_ttys;
        !           937:        int r = 0, i, data, s, flags;
        !           938:        u_int8_t stat, msvr;
        !           939:        struct stty_port *sp;
        !           940:        struct tty *tp;
        !           941:
        !           942:        if (stc != NULL) {
        !           943:                for (i = 0; i < stc->sc_nports; i++) {
        !           944:                        sp = &stc->sc_port[i];
        !           945:                        tp = sp->sp_tty;
        !           946:
        !           947:                        if (!ISSET(tp->t_state, TS_ISOPEN))
        !           948:                                continue;
        !           949:
        !           950:                        while (sp->sp_rget != sp->sp_rput) {
        !           951:                                stat = sp->sp_rget[0];
        !           952:                                data = sp->sp_rget[1];
        !           953:                                sp->sp_rget += 2;
        !           954:                                if (sp->sp_rget == sp->sp_rend)
        !           955:                                        sp->sp_rget = sp->sp_rbuf;
        !           956:
        !           957:                                if (stat & (CD180_RCSR_BE | CD180_RCSR_FE))
        !           958:                                        data |= TTY_FE;
        !           959:
        !           960:                                if (stat & CD180_RCSR_PE)
        !           961:                                        data |= TTY_PE;
        !           962:
        !           963:                                (*linesw[tp->t_line].l_rint)(data, tp);
        !           964:                                r = 1;
        !           965:                        }
        !           966:
        !           967:                        s = splhigh();
        !           968:                        flags = sp->sp_flags;
        !           969:                        CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG |
        !           970:                            STTYF_RING_OVERFLOW);
        !           971:                        splx(s);
        !           972:
        !           973:                        if (ISSET(flags, STTYF_CDCHG)) {
        !           974:                                s = spltty();
        !           975:                                STC_WRITE(sc, STC_CAR, i);
        !           976:                                msvr = STC_READ(sc, STC_MSVR);
        !           977:                                splx(s);
        !           978:
        !           979:                                sp->sp_carrier = msvr & CD180_MSVR_CD;
        !           980:                                (*linesw[tp->t_line].l_modem)(tp,
        !           981:                                    sp->sp_carrier);
        !           982:                                r = 1;
        !           983:                        }
        !           984:
        !           985:                        if (ISSET(flags, STTYF_RING_OVERFLOW)) {
        !           986:                                log(LOG_WARNING, "%s-%x: ring overflow\n",
        !           987:                                        stc->sc_dev.dv_xname, i);
        !           988:                                r = 1;
        !           989:                        }
        !           990:
        !           991:                        if (ISSET(flags, STTYF_DONE)) {
        !           992:                                ndflush(&tp->t_outq,
        !           993:                                    sp->sp_txp - tp->t_outq.c_cf);
        !           994:                                CLR(tp->t_state, TS_BUSY);
        !           995:                                (*linesw[tp->t_line].l_start)(tp);
        !           996:                                r = 1;
        !           997:                        }
        !           998:                }
        !           999:        }
        !          1000: }
        !          1001:
        !          1002: void
        !          1003: stty_write_ccr(sc, val)
        !          1004:        struct spif_softc *sc;
        !          1005:        u_int8_t val;
        !          1006: {
        !          1007:        int tries = 100000;
        !          1008:
        !          1009:        while (STC_READ(sc, STC_CCR) && tries--)
        !          1010:                /*EMPTY*/;
        !          1011:        if (tries == 0)
        !          1012:                printf("%s: ccr timeout\n", sc->sc_dev.dv_xname);
        !          1013:        STC_WRITE(sc, STC_CCR, val);
        !          1014: }
        !          1015:
        !          1016: int
        !          1017: stty_compute_baud(speed, clock, bprlp, bprhp)
        !          1018:        speed_t speed;
        !          1019:        int clock;
        !          1020:        u_int8_t *bprlp, *bprhp;
        !          1021: {
        !          1022:        u_int32_t rate;
        !          1023:
        !          1024:        rate = (2 * clock) / (16 * speed);
        !          1025:        if (rate & 1)
        !          1026:                rate = (rate >> 1) + 1;
        !          1027:        else
        !          1028:                rate = rate >> 1;
        !          1029:
        !          1030:        if (rate > 0xffff || rate == 0)
        !          1031:                return (1);
        !          1032:
        !          1033:        *bprlp = rate & 0xff;
        !          1034:        *bprhp = (rate >> 8) & 0xff;
        !          1035:        return (0);
        !          1036: }
        !          1037:
        !          1038: int
        !          1039: sbppmatch(parent, vcf, aux)
        !          1040:        struct device *parent;
        !          1041:        void *vcf, *aux;
        !          1042: {
        !          1043:        struct spif_softc *sc = (struct spif_softc *)parent;
        !          1044:
        !          1045:        return (aux == sbppmatch && sc->sc_bpps == NULL);
        !          1046: }
        !          1047:
        !          1048: void
        !          1049: sbppattach(parent, dev, aux)
        !          1050:        struct device *parent, *dev;
        !          1051:        void *aux;
        !          1052: {
        !          1053:        struct spif_softc *sc = (struct spif_softc *)parent;
        !          1054:        struct sbpp_softc *psc = (struct sbpp_softc *)dev;
        !          1055:        int port;
        !          1056:
        !          1057:        sc->sc_bpps = psc;
        !          1058:
        !          1059:        for (port = 0; port < sc->sc_npar; port++) {
        !          1060:        }
        !          1061:
        !          1062:        psc->sc_nports = port;
        !          1063:        printf(": %d port%s\n", port, port == 1 ? "" : "s");
        !          1064: }
        !          1065:
        !          1066: int
        !          1067: sbppopen(dev, flags, mode, p)
        !          1068:        dev_t dev;
        !          1069:        int flags;
        !          1070:        int mode;
        !          1071:        struct proc *p;
        !          1072: {
        !          1073:        return (ENXIO);
        !          1074: }
        !          1075:
        !          1076: int
        !          1077: sbppclose(dev, flags, mode, p)
        !          1078:        dev_t dev;
        !          1079:        int flags;
        !          1080:        int mode;
        !          1081:        struct proc *p;
        !          1082: {
        !          1083:        return (ENXIO);
        !          1084: }
        !          1085:
        !          1086: int
        !          1087: spifppcintr(v)
        !          1088:        void *v;
        !          1089: {
        !          1090:        return (0);
        !          1091: }
        !          1092:
        !          1093: int
        !          1094: sbppread(dev, uio, flags)
        !          1095:        dev_t dev;
        !          1096:        struct uio *uio;
        !          1097:        int flags;
        !          1098: {
        !          1099:        return (sbpp_rw(dev, uio));
        !          1100: }
        !          1101:
        !          1102: int
        !          1103: sbppwrite(dev, uio, flags)
        !          1104:        dev_t dev;
        !          1105:        struct uio *uio;
        !          1106:        int flags;
        !          1107: {
        !          1108:        return (sbpp_rw(dev, uio));
        !          1109: }
        !          1110:
        !          1111: int
        !          1112: sbpp_rw(dev, uio)
        !          1113:        dev_t dev;
        !          1114:        struct uio *uio;
        !          1115: {
        !          1116:        return (ENXIO);
        !          1117: }
        !          1118:
        !          1119: int
        !          1120: sbpppoll(dev, events, p)
        !          1121:        dev_t dev;
        !          1122:        int events;
        !          1123:        struct proc *p;
        !          1124: {
        !          1125:        return (seltrue(dev, events, p));
        !          1126: }
        !          1127:
        !          1128: int
        !          1129: sbppioctl(dev, cmd, data, flags, p)
        !          1130:        dev_t dev;
        !          1131:        u_long cmd;
        !          1132:        caddr_t data;
        !          1133:        int flags;
        !          1134:        struct proc *p;
        !          1135: {
        !          1136:        int error;
        !          1137:
        !          1138:        error = ENOTTY;
        !          1139:
        !          1140:        return (error);
        !          1141: }

CVSweb