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

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

1.1     ! nbrk        1: /*     $OpenBSD: spif.c,v 1.20 2006/06/02 20:00:54 miod Exp $  */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1999 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:
        !            29: /*
        !            30:  * Driver for the SUNW,spif: 8 serial, 1 parallel sbus board
        !            31:  * based heavily on Iain Hibbert's driver for the MAGMA cards
        !            32:  */
        !            33:
        !            34: #include <sys/param.h>
        !            35: #include <sys/systm.h>
        !            36: #include <sys/proc.h>
        !            37: #include <sys/device.h>
        !            38: #include <sys/kernel.h>
        !            39: #include <sys/file.h>
        !            40: #include <sys/errno.h>
        !            41: #include <sys/ioctl.h>
        !            42: #include <sys/mbuf.h>
        !            43: #include <sys/socket.h>
        !            44: #include <sys/syslog.h>
        !            45: #include <sys/malloc.h>
        !            46: #include <sys/tty.h>
        !            47: #include <sys/conf.h>
        !            48:
        !            49: #include <machine/autoconf.h>
        !            50: #include <sparc/cpu.h>
        !            51: #include <sparc/sparc/cpuvar.h>
        !            52: #include <sparc/dev/sbusvar.h>
        !            53: #include <sparc/dev/spifreg.h>
        !            54: #include <sparc/dev/spifvar.h>
        !            55:
        !            56: #if IPL_TTY == 1
        !            57: # define IE_MSOFT IE_L1
        !            58: #elif IPL_TTY == 4
        !            59: # define IE_MSOFT IE_L4
        !            60: #elif IPL_TTY == 6
        !            61: # define IE_MSOFT IE_L6
        !            62: #else
        !            63: # error "no suitable software interrupt bit"
        !            64: #endif
        !            65:
        !            66: int    spifmatch(struct device *, void *, void *);
        !            67: void   spifattach(struct device *, struct device *, void *);
        !            68:
        !            69: int    sttymatch(struct device *, void *, void *);
        !            70: void   sttyattach(struct device *, struct device *, void *);
        !            71: int    sttyopen(dev_t, int, int, struct proc *);
        !            72: int    sttyclose(dev_t, int, int, struct proc *);
        !            73: int    sttyread(dev_t, struct uio *, int);
        !            74: int    sttywrite(dev_t, struct uio *, int);
        !            75: int    sttyioctl(dev_t, u_long, caddr_t, int, struct proc *);
        !            76: int    sttystop(struct tty *, int);
        !            77:
        !            78: int    spifstcintr(void *);
        !            79: int    spifstcintr_mx(struct spif_softc *, int *);
        !            80: int    spifstcintr_tx(struct spif_softc *, int *);
        !            81: int    spifstcintr_rx(struct spif_softc *, int *);
        !            82: int    spifstcintr_rxexception(struct spif_softc *, int *);
        !            83: int    spifsoftintr(void *);
        !            84:
        !            85: int    stty_param(struct tty *, struct termios *);
        !            86: struct tty *sttytty(dev_t);
        !            87: int    stty_modem_control(struct stty_port *, int, int);
        !            88: static __inline        void    stty_write_ccr(struct stcregs *, u_int8_t);
        !            89: int    stty_compute_baud(speed_t, int, u_int8_t *, u_int8_t *);
        !            90: void   stty_start(struct tty *);
        !            91:
        !            92: int    sbppmatch(struct device *, void *, void *);
        !            93: void   sbppattach(struct device *, struct device *, void *);
        !            94: int    sbppopen(dev_t, int, int, struct proc *);
        !            95: int    sbppclose(dev_t, int, int, struct proc *);
        !            96: int    sbppread(dev_t, struct uio *, int);
        !            97: int    sbppwrite(dev_t, struct uio *, int);
        !            98: int    sbpp_rw(dev_t, struct uio *);
        !            99: int    spifppcintr(void *);
        !           100: int    sbpppoll(dev_t, int, struct proc *);
        !           101: int    sbppioctl(dev_t, u_long, caddr_t, int, struct proc *);
        !           102:
        !           103: struct cfattach spif_ca = {
        !           104:        sizeof (struct spif_softc), spifmatch, spifattach
        !           105: };
        !           106:
        !           107: struct cfdriver spif_cd = {
        !           108:        NULL, "spif", DV_DULL
        !           109: };
        !           110:
        !           111: struct cfattach stty_ca = {
        !           112:        sizeof(struct stty_softc), sttymatch, sttyattach
        !           113: };
        !           114:
        !           115: struct cfdriver stty_cd = {
        !           116:        NULL, "stty", DV_TTY
        !           117: };
        !           118:
        !           119: struct cfattach sbpp_ca = {
        !           120:        sizeof(struct sbpp_softc), sbppmatch, sbppattach
        !           121: };
        !           122:
        !           123: struct cfdriver sbpp_cd = {
        !           124:        NULL, "sbpp", DV_DULL
        !           125: };
        !           126:
        !           127: int
        !           128: spifmatch(parent, vcf, aux)
        !           129:        struct device *parent;
        !           130:        void *vcf, *aux;
        !           131: {
        !           132:        struct cfdata *cf = vcf;
        !           133:        struct confargs *ca = aux;
        !           134:        register struct romaux *ra = &ca->ca_ra;
        !           135:
        !           136:        if (strcmp(cf->cf_driver->cd_name, ra->ra_name) &&
        !           137:            strcmp("SUNW,spif", ra->ra_name))
        !           138:                return (0);
        !           139:        return (1);
        !           140: }
        !           141:
        !           142: void
        !           143: spifattach(parent, self, aux)
        !           144:        struct device *parent, *self;
        !           145:        void *aux;
        !           146: {
        !           147:        struct spif_softc *sc = (struct spif_softc *)self;
        !           148:        struct confargs *ca = aux;
        !           149:        int stcpri, ppcpri;
        !           150:
        !           151:        if (ca->ca_ra.ra_nintr != 2) {
        !           152:                printf(": expected 2 interrupts, got %d\n",
        !           153:                    ca->ca_ra.ra_nintr);
        !           154:                return;
        !           155:        }
        !           156:        stcpri = ca->ca_ra.ra_intr[SERIAL_INTR].int_pri;
        !           157:        ppcpri = ca->ca_ra.ra_intr[PARALLEL_INTR].int_pri;
        !           158:
        !           159:        if (ca->ca_ra.ra_nreg != 1) {
        !           160:                printf(": expected %d registers, got %d\n",
        !           161:                    1, ca->ca_ra.ra_nreg);
        !           162:                return;
        !           163:        }
        !           164:        sc->sc_regs = mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
        !           165:
        !           166:        sc->sc_node = ca->ca_ra.ra_node;
        !           167:
        !           168:        sc->sc_rev = getpropint(sc->sc_node, "revlev", 0);
        !           169:
        !           170:        sc->sc_osc = getpropint(sc->sc_node, "verosc", 0);
        !           171:        switch (sc->sc_osc) {
        !           172:        case SPIF_OSC10:
        !           173:                sc->sc_osc = 10000000;
        !           174:                break;
        !           175:        case SPIF_OSC9:
        !           176:        default:
        !           177:                sc->sc_osc = 9830400;
        !           178:                break;
        !           179:        }
        !           180:
        !           181:        sc->sc_nser = 8;
        !           182:        sc->sc_npar = 1;
        !           183:
        !           184:        sc->sc_rev2 = sc->sc_regs->stc.gfrcr;
        !           185:        sc->sc_regs->stc.gsvr = 0;
        !           186:
        !           187:        stty_write_ccr(&sc->sc_regs->stc,
        !           188:            CD180_CCR_CMD_RESET | CD180_CCR_RESETALL);
        !           189:        while (sc->sc_regs->stc.gsvr != 0xff);
        !           190:        while (sc->sc_regs->stc.gfrcr != sc->sc_rev2);
        !           191:
        !           192:        sc->sc_regs->stc.pprh = CD180_PPRH;
        !           193:        sc->sc_regs->stc.pprl = CD180_PPRL;
        !           194:        sc->sc_regs->stc.msmr = SPIF_MSMR;
        !           195:        sc->sc_regs->stc.tsmr = SPIF_TSMR;
        !           196:        sc->sc_regs->stc.rsmr = SPIF_RSMR;
        !           197:        sc->sc_regs->stc.gsvr = 0;
        !           198:        sc->sc_regs->stc.gscr1 = 0;
        !           199:        sc->sc_regs->stc.gscr2 = 0;
        !           200:        sc->sc_regs->stc.gscr3 = 0;
        !           201:        printf(": rev %x chiprev %x osc %sMHz stcpri %d ppcpri %d softpri %d\n",
        !           202:            sc->sc_rev, sc->sc_rev2, clockfreq(sc->sc_osc),
        !           203:            stcpri, ppcpri, IPL_TTY);
        !           204:
        !           205:        (void)config_found(self, sttymatch, NULL);
        !           206:        (void)config_found(self, sbppmatch, NULL);
        !           207:
        !           208:        sc->sc_ppcih.ih_fun = spifppcintr;
        !           209:        sc->sc_ppcih.ih_arg = sc;
        !           210:        intr_establish(ppcpri, &sc->sc_ppcih, -1, self->dv_xname);
        !           211:
        !           212:        sc->sc_stcih.ih_fun = spifstcintr;
        !           213:        sc->sc_stcih.ih_arg = sc;
        !           214:        intr_establish(stcpri, &sc->sc_stcih, -1, self->dv_xname);
        !           215:
        !           216:        sc->sc_softih.ih_fun = spifsoftintr;
        !           217:        sc->sc_softih.ih_arg = sc;
        !           218:        intr_establish(IPL_TTY, &sc->sc_softih, IPL_TTY, self->dv_xname);
        !           219: }
        !           220:
        !           221: int
        !           222: sttymatch(parent, vcf, aux)
        !           223:        struct device *parent;
        !           224:        void *vcf, *aux;
        !           225: {
        !           226:        struct spif_softc *sc = (struct spif_softc *)parent;
        !           227:
        !           228:        return (aux == sttymatch && sc->sc_ttys == NULL);
        !           229: }
        !           230:
        !           231: void
        !           232: sttyattach(parent, dev, aux)
        !           233:        struct device *parent, *dev;
        !           234:        void *aux;
        !           235: {
        !           236:        struct spif_softc *sc = (struct spif_softc *)parent;
        !           237:        struct stty_softc *ssc = (struct stty_softc *)dev;
        !           238:        int port;
        !           239:
        !           240:        sc->sc_ttys = ssc;
        !           241:
        !           242:        for (port = 0; port < sc->sc_nser; port++) {
        !           243:                struct stty_port *sp = &ssc->sc_port[port];
        !           244:                struct tty *tp;
        !           245:
        !           246:                sp->sp_dtr = 0;
        !           247:                sc->sc_regs->dtrlatch[port] = 1;
        !           248:
        !           249:                tp = ttymalloc();
        !           250:
        !           251:                tp->t_oproc = stty_start;
        !           252:                tp->t_param = stty_param;
        !           253:
        !           254:                sp->sp_tty = tp;
        !           255:                sp->sp_sc = sc;
        !           256:                sp->sp_channel = port;
        !           257:
        !           258:                sp->sp_rbuf = malloc(STTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT);
        !           259:                if(sp->sp_rbuf == NULL)
        !           260:                        break;
        !           261:
        !           262:                sp->sp_rend = sp->sp_rbuf + STTY_RBUF_SIZE;
        !           263:        }
        !           264:
        !           265:        ssc->sc_nports = port;
        !           266:
        !           267:        printf(": %d tty%s\n", port, port == 1 ? "" : "s");
        !           268: }
        !           269:
        !           270: int
        !           271: sttyopen(dev, flags, mode, p)
        !           272:        dev_t dev;
        !           273:        int flags;
        !           274:        int mode;
        !           275:        struct proc *p;
        !           276: {
        !           277:        struct spif_softc *csc;
        !           278:        struct stty_softc *sc;
        !           279:        struct stty_port *sp;
        !           280:        struct tty *tp;
        !           281:        int card = SPIF_CARD(dev);
        !           282:        int port = SPIF_PORT(dev);
        !           283:        int s;
        !           284:
        !           285:        if (card >= stty_cd.cd_ndevs || card >= spif_cd.cd_ndevs)
        !           286:                return (ENXIO);
        !           287:
        !           288:        sc = stty_cd.cd_devs[card];
        !           289:        csc = spif_cd.cd_devs[card];
        !           290:        if (sc == NULL)
        !           291:                return (ENXIO);
        !           292:
        !           293:        if (port >= sc->sc_nports)
        !           294:                return (ENXIO);
        !           295:
        !           296:        sp = &sc->sc_port[port];
        !           297:        tp = sp->sp_tty;
        !           298:        tp->t_dev = dev;
        !           299:
        !           300:        if (!ISSET(tp->t_state, TS_ISOPEN)) {
        !           301:                SET(tp->t_state, TS_WOPEN);
        !           302:
        !           303:                ttychars(tp);
        !           304:                tp->t_iflag = TTYDEF_IFLAG;
        !           305:                tp->t_oflag = TTYDEF_OFLAG;
        !           306:                tp->t_cflag = TTYDEF_CFLAG;
        !           307:                if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL))
        !           308:                        SET(tp->t_cflag, CLOCAL);
        !           309:                if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS))
        !           310:                        SET(tp->t_cflag, CRTSCTS);
        !           311:                if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF))
        !           312:                        SET(tp->t_cflag, MDMBUF);
        !           313:                tp->t_lflag = TTYDEF_LFLAG;
        !           314:                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
        !           315:
        !           316:                sp->sp_rput = sp->sp_rget = sp->sp_rbuf;
        !           317:
        !           318:                s = spltty();
        !           319:
        !           320:                csc->sc_regs->stc.car = sp->sp_channel;
        !           321:                stty_write_ccr(&csc->sc_regs->stc,
        !           322:                    CD180_CCR_CMD_RESET | CD180_CCR_RESETCHAN);
        !           323:                csc->sc_regs->stc.car = sp->sp_channel;
        !           324:
        !           325:                stty_param(tp, &tp->t_termios);
        !           326:
        !           327:                ttsetwater(tp);
        !           328:
        !           329:                csc->sc_regs->stc.srer = CD180_SRER_CD | CD180_SRER_RXD;
        !           330:
        !           331:                if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier)
        !           332:                        SET(tp->t_state, TS_CARR_ON);
        !           333:                else
        !           334:                        CLR(tp->t_state, TS_CARR_ON);
        !           335:        }
        !           336:        else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) {
        !           337:                return (EBUSY);
        !           338:        } else {
        !           339:                s = spltty();
        !           340:        }
        !           341:
        !           342:        if (!ISSET(flags, O_NONBLOCK)) {
        !           343:                while (!ISSET(tp->t_cflag, CLOCAL) &&
        !           344:                    !ISSET(tp->t_state, TS_CARR_ON)) {
        !           345:                        int error;
        !           346:
        !           347:                        SET(tp->t_state, TS_WOPEN);
        !           348:                        error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
        !           349:                            "sttycd", 0);
        !           350:                        if (error != 0) {
        !           351:                                splx(s);
        !           352:                                CLR(tp->t_state, TS_WOPEN);
        !           353:                                return (error);
        !           354:                        }
        !           355:                }
        !           356:        }
        !           357:
        !           358:        splx(s);
        !           359:
        !           360:        return ((*linesw[tp->t_line].l_open)(dev, tp));
        !           361: }
        !           362:
        !           363: int
        !           364: sttyclose(dev, flags, mode, p)
        !           365:        dev_t dev;
        !           366:        int flags;
        !           367:        int mode;
        !           368:        struct proc *p;
        !           369: {
        !           370:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           371:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           372:        struct spif_softc *csc = sp->sp_sc;
        !           373:        struct tty *tp = sp->sp_tty;
        !           374:        int port = SPIF_PORT(dev);
        !           375:        int s;
        !           376:
        !           377:        (*linesw[tp->t_line].l_close)(tp, flags);
        !           378:        s = spltty();
        !           379:
        !           380:        if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) {
        !           381:                stty_modem_control(sp, 0, DMSET);
        !           382:                csc->sc_regs->stc.car = port;
        !           383:                csc->sc_regs->stc.ccr =
        !           384:                    CD180_CCR_CMD_RESET | CD180_CCR_RESETCHAN;
        !           385:        }
        !           386:
        !           387:        splx(s);
        !           388:        ttyclose(tp);
        !           389:        return (0);
        !           390: }
        !           391:
        !           392: int
        !           393: sttyioctl(dev, cmd, data, flags, p)
        !           394:        dev_t dev;
        !           395:        u_long cmd;
        !           396:        caddr_t data;
        !           397:        int flags;
        !           398:        struct proc *p;
        !           399: {
        !           400:        struct stty_softc *stc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           401:        struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)];
        !           402:        struct spif_softc *sc = sp->sp_sc;
        !           403:        struct tty *tp = sp->sp_tty;
        !           404:        int error;
        !           405:
        !           406:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p);
        !           407:        if (error >= 0)
        !           408:                return (error);
        !           409:
        !           410:        error = ttioctl(tp, cmd, data, flags, p);
        !           411:        if (error >= 0)
        !           412:                return (error);
        !           413:
        !           414:        error = 0;
        !           415:
        !           416:        switch (cmd) {
        !           417:        case TIOCSBRK:
        !           418:                SET(sp->sp_flags, STTYF_SET_BREAK);
        !           419:                sc->sc_regs->stc.car = sp->sp_channel;
        !           420:                sc->sc_regs->stc.srer |= CD180_SRER_TXD;
        !           421:                break;
        !           422:        case TIOCCBRK:
        !           423:                SET(sp->sp_flags, STTYF_CLR_BREAK);
        !           424:                sc->sc_regs->stc.car = sp->sp_channel;
        !           425:                sc->sc_regs->stc.srer |= CD180_SRER_TXD;
        !           426:                break;
        !           427:        case TIOCSDTR:
        !           428:                stty_modem_control(sp, TIOCM_DTR, DMBIS);
        !           429:                break;
        !           430:        case TIOCCDTR:
        !           431:                stty_modem_control(sp, TIOCM_DTR, DMBIC);
        !           432:                break;
        !           433:        case TIOCMBIS:
        !           434:                stty_modem_control(sp, *((int *)data), DMBIS);
        !           435:                break;
        !           436:        case TIOCMBIC:
        !           437:                stty_modem_control(sp, *((int *)data), DMBIC);
        !           438:                break;
        !           439:        case TIOCMGET:
        !           440:                *((int *)data) = stty_modem_control(sp, 0, DMGET);
        !           441:                break;
        !           442:        case TIOCMSET:
        !           443:                stty_modem_control(sp, *((int *)data), DMSET);
        !           444:                break;
        !           445:        case TIOCGFLAGS:
        !           446:                *((int *)data) = sp->sp_openflags;
        !           447:                break;
        !           448:        case TIOCSFLAGS:
        !           449:                if (suser(p, 0))
        !           450:                        error = EPERM;
        !           451:                else
        !           452:                        sp->sp_openflags = *((int *)data) &
        !           453:                            (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
        !           454:                             TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
        !           455:                break;
        !           456:        default:
        !           457:                error = ENOTTY;
        !           458:        }
        !           459:
        !           460:        return (error);
        !           461: }
        !           462:
        !           463: int
        !           464: stty_modem_control(sp, bits, how)
        !           465:        struct stty_port *sp;
        !           466:        int bits, how;
        !           467: {
        !           468:        struct spif_softc *csc = sp->sp_sc;
        !           469:        struct tty *tp = sp->sp_tty;
        !           470:        int s, msvr;
        !           471:
        !           472:        s = spltty();
        !           473:        csc->sc_regs->stc.car = sp->sp_channel;
        !           474:
        !           475:        switch (how) {
        !           476:        case DMGET:
        !           477:                bits = TIOCM_LE;
        !           478:                if (sp->sp_dtr)
        !           479:                        bits |= TIOCM_DTR;
        !           480:                msvr = csc->sc_regs->stc.msvr;
        !           481:                if (ISSET(msvr, CD180_MSVR_DSR))
        !           482:                        bits |= TIOCM_DSR;
        !           483:                if (ISSET(msvr, CD180_MSVR_CD))
        !           484:                        bits |= TIOCM_CD;
        !           485:                if (ISSET(msvr, CD180_MSVR_CTS))
        !           486:                        bits |= TIOCM_CTS;
        !           487:                if (ISSET(msvr, CD180_MSVR_RTS))
        !           488:                        bits |= TIOCM_RTS;
        !           489:                break;
        !           490:        case DMSET:
        !           491:                if (ISSET(bits, TIOCM_DTR)) {
        !           492:                        sp->sp_dtr = 1;
        !           493:                        csc->sc_regs->dtrlatch[sp->sp_channel] = 0;
        !           494:                }
        !           495:                else {
        !           496:                        sp->sp_dtr = 0;
        !           497:                        csc->sc_regs->dtrlatch[sp->sp_channel] = 1;
        !           498:                }
        !           499:                if (ISSET(bits, TIOCM_RTS))
        !           500:                        csc->sc_regs->stc.msvr &= ~CD180_MSVR_RTS;
        !           501:                else
        !           502:                        csc->sc_regs->stc.msvr |= CD180_MSVR_RTS;
        !           503:                break;
        !           504:        case DMBIS:
        !           505:                if (ISSET(bits, TIOCM_DTR)) {
        !           506:                        sp->sp_dtr = 1;
        !           507:                        csc->sc_regs->dtrlatch[sp->sp_channel] = 0;
        !           508:                }
        !           509:                if (ISSET(bits, TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS))
        !           510:                        csc->sc_regs->stc.msvr &= ~CD180_MSVR_RTS;
        !           511:                break;
        !           512:        case DMBIC:
        !           513:                if (ISSET(bits, TIOCM_DTR)) {
        !           514:                        sp->sp_dtr = 0;
        !           515:                        csc->sc_regs->dtrlatch[sp->sp_channel] = 1;
        !           516:                }
        !           517:                if (ISSET(bits, TIOCM_RTS))
        !           518:                        csc->sc_regs->stc.msvr |= CD180_MSVR_RTS;
        !           519:                break;
        !           520:        }
        !           521:
        !           522:        splx(s);
        !           523:        return (bits);
        !           524: }
        !           525:
        !           526: int
        !           527: stty_param(tp, t)
        !           528:        struct tty *tp;
        !           529:        struct termios *t;
        !           530: {
        !           531:        struct stty_softc *st = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
        !           532:        struct stty_port *sp = &st->sc_port[SPIF_PORT(tp->t_dev)];
        !           533:        struct spif_softc *sc = sp->sp_sc;
        !           534:        u_int8_t rbprl, rbprh, tbprl, tbprh;
        !           535:        int s, opt;
        !           536:
        !           537:        if (t->c_ospeed &&
        !           538:            stty_compute_baud(t->c_ospeed, sc->sc_osc, &tbprl, &tbprh))
        !           539:                return (EINVAL);
        !           540:
        !           541:        if (t->c_ispeed &&
        !           542:            stty_compute_baud(t->c_ispeed, sc->sc_osc, &rbprl, &rbprh))
        !           543:                return (EINVAL);
        !           544:
        !           545:        s = spltty();
        !           546:
        !           547:        /* hang up line if ospeed is zero, otherwise raise DTR */
        !           548:        stty_modem_control(sp, TIOCM_DTR,
        !           549:            (t->c_ospeed == 0 ? DMBIC : DMBIS));
        !           550:
        !           551:        sc->sc_regs->stc.car = sp->sp_channel;
        !           552:
        !           553:        opt = 0;
        !           554:        if (ISSET(t->c_cflag, PARENB)) {
        !           555:                opt |= CD180_COR1_PARMODE_NORMAL;
        !           556:                opt |= (ISSET(t->c_cflag, PARODD) ?
        !           557:                                CD180_COR1_ODDPAR :
        !           558:                                CD180_COR1_EVENPAR);
        !           559:        }
        !           560:        else
        !           561:                opt |= CD180_COR1_PARMODE_NO;
        !           562:
        !           563:        if (!ISSET(t->c_iflag, INPCK))
        !           564:                opt |= CD180_COR1_IGNPAR;
        !           565:
        !           566:        if (ISSET(t->c_cflag, CSTOPB))
        !           567:                opt |= CD180_COR1_STOP2;
        !           568:
        !           569:        switch (t->c_cflag & CSIZE) {
        !           570:        case CS5:
        !           571:                opt |= CD180_COR1_CS5;
        !           572:                break;
        !           573:        case CS6:
        !           574:                opt |= CD180_COR1_CS6;
        !           575:                break;
        !           576:        case CS7:
        !           577:                opt |= CD180_COR1_CS7;
        !           578:                break;
        !           579:        default:
        !           580:                opt |= CD180_COR1_CS8;
        !           581:                break;
        !           582:        }
        !           583:        sc->sc_regs->stc.cor1 = opt;
        !           584:        stty_write_ccr(&sc->sc_regs->stc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG1);
        !           585:
        !           586:        opt = CD180_COR2_ETC;
        !           587:        if (ISSET(t->c_cflag, CRTSCTS))
        !           588:                opt |= CD180_COR2_CTSAE;
        !           589:        sc->sc_regs->stc.cor2 = opt;
        !           590:        stty_write_ccr(&sc->sc_regs->stc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG2);
        !           591:
        !           592:        sc->sc_regs->stc.cor3 = STTY_RX_FIFO_THRESHOLD;
        !           593:        stty_write_ccr(&sc->sc_regs->stc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG3);
        !           594:
        !           595:        sc->sc_regs->stc.schr1 = 0x11;
        !           596:        sc->sc_regs->stc.schr2 = 0x13;
        !           597:        sc->sc_regs->stc.schr3 = 0x11;
        !           598:        sc->sc_regs->stc.schr4 = 0x13;
        !           599:        sc->sc_regs->stc.rtpr = 0x12;
        !           600:
        !           601:        sc->sc_regs->stc.mcor1 = CD180_MCOR1_CDZD | STTY_RX_DTR_THRESHOLD;
        !           602:        sc->sc_regs->stc.mcor2 = CD180_MCOR2_CDOD;
        !           603:        sc->sc_regs->stc.mcr = 0;
        !           604:
        !           605:        if (t->c_ospeed) {
        !           606:                sc->sc_regs->stc.tbprh = tbprh;
        !           607:                sc->sc_regs->stc.tbprl = tbprl;
        !           608:        }
        !           609:
        !           610:        if (t->c_ispeed) {
        !           611:                sc->sc_regs->stc.rbprh = rbprh;
        !           612:                sc->sc_regs->stc.rbprl = rbprl;
        !           613:        }
        !           614:
        !           615:        stty_write_ccr(&sc->sc_regs->stc, CD180_CCR_CMD_CHAN |
        !           616:            CD180_CCR_CHAN_TXEN | CD180_CCR_CHAN_RXEN);
        !           617:
        !           618:        sp->sp_carrier = sc->sc_regs->stc.msvr & CD180_MSVR_CD;
        !           619:
        !           620:        splx(s);
        !           621:        return (0);
        !           622: }
        !           623:
        !           624: int
        !           625: sttyread(dev, uio, flags)
        !           626:        dev_t dev;
        !           627:        struct uio *uio;
        !           628:        int flags;
        !           629: {
        !           630:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           631:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           632:        struct tty *tp = sp->sp_tty;
        !           633:
        !           634:        return ((*linesw[tp->t_line].l_read)(tp, uio, flags));
        !           635: }
        !           636:
        !           637: int
        !           638: sttywrite(dev, uio, flags)
        !           639:        dev_t dev;
        !           640:        struct uio *uio;
        !           641:        int flags;
        !           642: {
        !           643:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           644:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           645:        struct tty *tp = sp->sp_tty;
        !           646:
        !           647:        return ((*linesw[tp->t_line].l_write)(tp, uio, flags));
        !           648: }
        !           649:
        !           650: struct tty *
        !           651: sttytty(dev)
        !           652:        dev_t dev;
        !           653: {
        !           654:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
        !           655:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
        !           656:
        !           657:        return (sp->sp_tty);
        !           658: }
        !           659:
        !           660: int
        !           661: sttystop(tp, flags)
        !           662:        struct tty *tp;
        !           663:        int flags;
        !           664: {
        !           665:        struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
        !           666:        struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)];
        !           667:        int s;
        !           668:
        !           669:        s = spltty();
        !           670:        if (ISSET(tp->t_state, TS_BUSY)) {
        !           671:                if (!ISSET(tp->t_state, TS_TTSTOP))
        !           672:                        SET(tp->t_state, TS_FLUSH);
        !           673:                SET(sp->sp_flags, STTYF_STOP);
        !           674:        }
        !           675:        splx(s);
        !           676:        return (0);
        !           677: }
        !           678:
        !           679: void
        !           680: stty_start(tp)
        !           681:        struct tty *tp;
        !           682: {
        !           683:        struct stty_softc *stc = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
        !           684:        struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)];
        !           685:        struct spif_softc *sc = sp->sp_sc;
        !           686:        int s;
        !           687:
        !           688:        s = spltty();
        !           689:
        !           690:        if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
        !           691:                if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           692:                        if (ISSET(tp->t_state, TS_ASLEEP)) {
        !           693:                                CLR(tp->t_state, TS_ASLEEP);
        !           694:                                wakeup(&tp->t_outq);
        !           695:                        }
        !           696:                        selwakeup(&tp->t_wsel);
        !           697:                }
        !           698:                if (tp->t_outq.c_cc) {
        !           699:                        sp->sp_txc = ndqb(&tp->t_outq, 0);
        !           700:                        sp->sp_txp = tp->t_outq.c_cf;
        !           701:                        SET(tp->t_state, TS_BUSY);
        !           702:                        sc->sc_regs->stc.car = sp->sp_channel;
        !           703:                        sc->sc_regs->stc.srer |= CD180_SRER_TXD;
        !           704:                }
        !           705:        }
        !           706:
        !           707:        splx(s);
        !           708: }
        !           709:
        !           710: int
        !           711: spifstcintr_rxexception(sc, needsoftp)
        !           712:        struct spif_softc *sc;
        !           713:        int *needsoftp;
        !           714: {
        !           715:        struct stty_port *sp;
        !           716:        u_int8_t channel, *ptr;
        !           717:
        !           718:        channel = CD180_GSCR_CHANNEL(sc->sc_regs->stc.gscr1);
        !           719:        sp = &sc->sc_ttys->sc_port[channel];
        !           720:        ptr = sp->sp_rput;
        !           721:        *ptr++ = sc->sc_regs->stc.rcsr;
        !           722:        *ptr++ = sc->sc_regs->stc.rdr;
        !           723:        if (ptr == sp->sp_rend)
        !           724:                ptr = sp->sp_rbuf;
        !           725:        if (ptr == sp->sp_rget) {
        !           726:                if (ptr == sp->sp_rbuf)
        !           727:                        ptr = sp->sp_rend;
        !           728:                ptr -= 2;
        !           729:                SET(sp->sp_flags, STTYF_RING_OVERFLOW);
        !           730:        }
        !           731:        sc->sc_regs->stc.eosrr = 0;
        !           732:        *needsoftp = 1;
        !           733:        sp->sp_rput = ptr;
        !           734:        return (1);
        !           735: }
        !           736:
        !           737: int
        !           738: spifstcintr_rx(sc, needsoftp)
        !           739:        struct spif_softc *sc;
        !           740:        int *needsoftp;
        !           741: {
        !           742:        struct stty_port *sp;
        !           743:        u_int8_t channel, *ptr, cnt, rcsr;
        !           744:        int i;
        !           745:
        !           746:        channel = CD180_GSCR_CHANNEL(sc->sc_regs->stc.gscr1);
        !           747:        sp = &sc->sc_ttys->sc_port[channel];
        !           748:        ptr = sp->sp_rput;
        !           749:        cnt = sc->sc_regs->stc.rdcr;
        !           750:        for (i = 0; i < cnt; i++) {
        !           751:                *ptr++ = 0;
        !           752:                rcsr = sc->sc_regs->stc.rcsr;
        !           753:                *ptr++ = sc->sc_regs->stc.rdr;
        !           754:                if (ptr == sp->sp_rend)
        !           755:                        ptr = sp->sp_rbuf;
        !           756:                if (ptr == sp->sp_rget) {
        !           757:                        if (ptr == sp->sp_rbuf)
        !           758:                                ptr = sp->sp_rend;
        !           759:                        ptr -= 2;
        !           760:                        SET(sp->sp_flags, STTYF_RING_OVERFLOW);
        !           761:                        break;
        !           762:                }
        !           763:        }
        !           764:        sc->sc_regs->stc.eosrr = 0;
        !           765:        if (cnt) {
        !           766:                *needsoftp = 1;
        !           767:                sp->sp_rput = ptr;
        !           768:        }
        !           769:        return (1);
        !           770: }
        !           771:
        !           772: int
        !           773: spifstcintr_tx(sc, needsoftp)
        !           774:        struct spif_softc *sc;
        !           775:        int *needsoftp;
        !           776: {
        !           777:        struct stty_port *sp;
        !           778:        u_int8_t channel, ch;
        !           779:        int cnt = 0;
        !           780:
        !           781:        channel = CD180_GSCR_CHANNEL(sc->sc_regs->stc.gscr1);
        !           782:        sp = &sc->sc_ttys->sc_port[channel];
        !           783:        if (!ISSET(sp->sp_flags, STTYF_STOP)) {
        !           784:                if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) {
        !           785:                        sc->sc_regs->stc.tdr = 0;
        !           786:                        sc->sc_regs->stc.tdr = 0x81;
        !           787:                        CLR(sp->sp_flags, STTYF_SET_BREAK);
        !           788:                        cnt += 2;
        !           789:                }
        !           790:                if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) {
        !           791:                        sc->sc_regs->stc.tdr = 0;
        !           792:                        sc->sc_regs->stc.tdr = 0x83;
        !           793:                        CLR(sp->sp_flags, STTYF_CLR_BREAK);
        !           794:                        cnt += 2;
        !           795:                }
        !           796:
        !           797:                while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) {
        !           798:                        ch = *sp->sp_txp;
        !           799:                        sp->sp_txc--;
        !           800:                        sp->sp_txp++;
        !           801:
        !           802:                        if (ch == 0) {
        !           803:                                sc->sc_regs->stc.tdr = ch;
        !           804:                                cnt++;
        !           805:                        }
        !           806:                        sc->sc_regs->stc.tdr = ch;
        !           807:                        cnt++;
        !           808:                }
        !           809:        }
        !           810:
        !           811:        if (sp->sp_txc == 0 ||
        !           812:            ISSET(sp->sp_flags, STTYF_STOP)) {
        !           813:                sc->sc_regs->stc.srer &= ~CD180_SRER_TXD;
        !           814:                CLR(sp->sp_flags, STTYF_STOP);
        !           815:                SET(sp->sp_flags, STTYF_DONE);
        !           816:                *needsoftp = 1;
        !           817:        }
        !           818:
        !           819:        sc->sc_regs->stc.eosrr = 0;
        !           820:
        !           821:        return (1);
        !           822: }
        !           823:
        !           824: int
        !           825: spifstcintr_mx(sc, needsoftp)
        !           826:        struct spif_softc *sc;
        !           827:        int *needsoftp;
        !           828: {
        !           829:        struct stty_port *sp;
        !           830:        u_int8_t channel, mcr;
        !           831:
        !           832:        channel = CD180_GSCR_CHANNEL(sc->sc_regs->stc.gscr1);
        !           833:        sp = &sc->sc_ttys->sc_port[channel];
        !           834:        mcr = sc->sc_regs->stc.mcr;
        !           835:        if (mcr & CD180_MCR_CD) {
        !           836:                SET(sp->sp_flags, STTYF_CDCHG);
        !           837:                *needsoftp = 1;
        !           838:        }
        !           839:        sc->sc_regs->stc.mcr = 0;
        !           840:        sc->sc_regs->stc.eosrr = 0;
        !           841:        return (1);
        !           842: }
        !           843:
        !           844: int
        !           845: spifstcintr(vsc)
        !           846:        void *vsc;
        !           847: {
        !           848:        struct spif_softc *sc = (struct spif_softc *)vsc;
        !           849:        int needsoft = 0, r = 0, i;
        !           850:        u_int8_t ar;
        !           851:
        !           852:        for (i = 0; i < 8; i++) {
        !           853:                ar = sc->sc_regs->istc.rrar & CD180_GSVR_IMASK;
        !           854:                if (ar == CD180_GSVR_RXGOOD)
        !           855:                        r |= spifstcintr_rx(sc, &needsoft);
        !           856:                else if (ar == CD180_GSVR_RXEXCEPTION)
        !           857:                        r |= spifstcintr_rxexception(sc, &needsoft);
        !           858:        }
        !           859:
        !           860:        for (i = 0; i < 8; i++) {
        !           861:                ar = sc->sc_regs->istc.trar & CD180_GSVR_IMASK;
        !           862:                if (ar == CD180_GSVR_TXDATA)
        !           863:                        r |= spifstcintr_tx(sc, &needsoft);
        !           864:        }
        !           865:
        !           866:        for (i = 0; i < 8; i++) {
        !           867:                ar = sc->sc_regs->istc.mrar & CD180_GSVR_IMASK;
        !           868:                if (ar == CD180_GSVR_STATCHG)
        !           869:                        r |= spifstcintr_mx(sc, &needsoft);
        !           870:        }
        !           871:
        !           872:        if (needsoft) {
        !           873: #if defined(SUN4M)
        !           874:                if (CPU_ISSUN4M)
        !           875:                        raise(0, IPL_TTY);
        !           876:                else
        !           877: #endif
        !           878:                        ienab_bis(IE_MSOFT);
        !           879:        }
        !           880:        return (r);
        !           881: }
        !           882:
        !           883: int
        !           884: spifsoftintr(vsc)
        !           885:        void *vsc;
        !           886: {
        !           887:        struct spif_softc *sc = (struct spif_softc *)vsc;
        !           888:        struct stty_softc *stc = sc->sc_ttys;
        !           889:        int r = 0, i, data, s, flags;
        !           890:        u_int8_t stat, msvr;
        !           891:        struct stty_port *sp;
        !           892:        struct tty *tp;
        !           893:
        !           894:        if (stc != NULL) {
        !           895:                for (i = 0; i < stc->sc_nports; i++) {
        !           896:                        sp = &stc->sc_port[i];
        !           897:                        tp = sp->sp_tty;
        !           898:
        !           899:                        if (!ISSET(tp->t_state, TS_ISOPEN))
        !           900:                                continue;
        !           901:
        !           902:                        while (sp->sp_rget != sp->sp_rput) {
        !           903:                                stat = sp->sp_rget[0];
        !           904:                                data = sp->sp_rget[1];
        !           905:                                sp->sp_rget += 2;
        !           906:                                if (sp->sp_rget == sp->sp_rend)
        !           907:                                        sp->sp_rget = sp->sp_rbuf;
        !           908:
        !           909:                                if (stat & (CD180_RCSR_BE | CD180_RCSR_FE))
        !           910:                                        data |= TTY_FE;
        !           911:
        !           912:                                if (stat & CD180_RCSR_PE)
        !           913:                                        data |= TTY_PE;
        !           914:
        !           915:                                (*linesw[tp->t_line].l_rint)(data, tp);
        !           916:                                r = 1;
        !           917:                        }
        !           918:
        !           919:                        s = splhigh();
        !           920:                        flags = sp->sp_flags;
        !           921:                        CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG |
        !           922:                            STTYF_RING_OVERFLOW);
        !           923:                        splx(s);
        !           924:
        !           925:                        if (ISSET(flags, STTYF_CDCHG)) {
        !           926:                                s = spltty();
        !           927:                                sc->sc_regs->stc.car = i;
        !           928:                                msvr = sc->sc_regs->stc.msvr;
        !           929:                                splx(s);
        !           930:
        !           931:                                sp->sp_carrier = msvr & CD180_MSVR_CD;
        !           932:                                (*linesw[tp->t_line].l_modem)(tp,
        !           933:                                    sp->sp_carrier);
        !           934:                                r = 1;
        !           935:                        }
        !           936:
        !           937:                        if (ISSET(flags, STTYF_RING_OVERFLOW)) {
        !           938:                                log(LOG_WARNING, "%s-%x: ring overflow\n",
        !           939:                                        stc->sc_dev.dv_xname, i);
        !           940:                                r = 1;
        !           941:                        }
        !           942:
        !           943:                        if (ISSET(flags, STTYF_DONE)) {
        !           944:                                ndflush(&tp->t_outq,
        !           945:                                    sp->sp_txp - tp->t_outq.c_cf);
        !           946:                                CLR(tp->t_state, TS_BUSY);
        !           947:                                (*linesw[tp->t_line].l_start)(tp);
        !           948:                                r = 1;
        !           949:                        }
        !           950:                }
        !           951:        }
        !           952:
        !           953:        return (r);
        !           954: }
        !           955:
        !           956: static __inline        void
        !           957: stty_write_ccr(stc, val)
        !           958:        struct stcregs *stc;
        !           959:        u_int8_t val;
        !           960: {
        !           961:        int tries = 100000;
        !           962:
        !           963:        while (stc->ccr && tries--);
        !           964:        if (tries == 0)
        !           965:                printf("CCR: timeout\n");
        !           966:        stc->ccr = val;
        !           967: }
        !           968:
        !           969: int
        !           970: stty_compute_baud(speed, clock, bprlp, bprhp)
        !           971:        speed_t speed;
        !           972:        int clock;
        !           973:        u_int8_t *bprlp, *bprhp;
        !           974: {
        !           975:        u_int32_t rate;
        !           976:
        !           977:        rate = (2 * clock) / (16 * speed);
        !           978:        if (rate & 1)
        !           979:                rate = (rate >> 1) + 1;
        !           980:        else
        !           981:                rate = rate >> 1;
        !           982:
        !           983:        if (rate > 0xffff || rate == 0)
        !           984:                return (1);
        !           985:
        !           986:        *bprlp = rate & 0xff;
        !           987:        *bprhp = (rate >> 8) & 0xff;
        !           988:        return (0);
        !           989: }
        !           990:
        !           991: int
        !           992: sbppmatch(parent, vcf, aux)
        !           993:        struct device *parent;
        !           994:        void *vcf, *aux;
        !           995: {
        !           996:        struct spif_softc *sc = (struct spif_softc *)parent;
        !           997:
        !           998:        return (aux == sbppmatch && sc->sc_bpps == NULL);
        !           999: }
        !          1000:
        !          1001: void
        !          1002: sbppattach(parent, dev, aux)
        !          1003:        struct device *parent, *dev;
        !          1004:        void *aux;
        !          1005: {
        !          1006:        struct spif_softc *sc = (struct spif_softc *)parent;
        !          1007:        struct sbpp_softc *psc = (struct sbpp_softc *)dev;
        !          1008:        int port;
        !          1009:
        !          1010:        sc->sc_bpps = psc;
        !          1011:
        !          1012:        for (port = 0; port < sc->sc_npar; port++) {
        !          1013:        }
        !          1014:
        !          1015:        psc->sc_nports = port;
        !          1016:        printf(": %d port%s\n", port, port == 1 ? "" : "s");
        !          1017: }
        !          1018:
        !          1019: int
        !          1020: sbppopen(dev, flags, mode, p)
        !          1021:        dev_t dev;
        !          1022:        int flags;
        !          1023:        int mode;
        !          1024:        struct proc *p;
        !          1025: {
        !          1026:        return (ENXIO);
        !          1027: }
        !          1028:
        !          1029: int
        !          1030: sbppclose(dev, flags, mode, p)
        !          1031:        dev_t dev;
        !          1032:        int flags;
        !          1033:        int mode;
        !          1034:        struct proc *p;
        !          1035: {
        !          1036:        return (ENXIO);
        !          1037: }
        !          1038:
        !          1039: int
        !          1040: spifppcintr(v)
        !          1041:        void *v;
        !          1042: {
        !          1043:        return (0);
        !          1044: }
        !          1045:
        !          1046: int
        !          1047: sbppread(dev, uio, flags)
        !          1048:        dev_t dev;
        !          1049:        struct uio *uio;
        !          1050:        int flags;
        !          1051: {
        !          1052:        return (sbpp_rw(dev, uio));
        !          1053: }
        !          1054:
        !          1055: int
        !          1056: sbppwrite(dev, uio, flags)
        !          1057:        dev_t dev;
        !          1058:        struct uio *uio;
        !          1059:        int flags;
        !          1060: {
        !          1061:        return (sbpp_rw(dev, uio));
        !          1062: }
        !          1063:
        !          1064: int
        !          1065: sbpp_rw(dev, uio)
        !          1066:        dev_t dev;
        !          1067:        struct uio *uio;
        !          1068: {
        !          1069:        return (ENXIO);
        !          1070: }
        !          1071:
        !          1072: int
        !          1073: sbpppoll(dev, events, p)
        !          1074:        dev_t dev;
        !          1075:        int events;
        !          1076:        struct proc *p;
        !          1077: {
        !          1078:        return (seltrue(dev, events, p));
        !          1079: }
        !          1080:
        !          1081: int
        !          1082: sbppioctl(dev, cmd, data, flags, p)
        !          1083:        dev_t dev;
        !          1084:        u_long cmd;
        !          1085:        caddr_t data;
        !          1086:        int flags;
        !          1087:        struct proc *p;
        !          1088: {
        !          1089:        int error;
        !          1090:
        !          1091:        error = ENOTTY;
        !          1092:
        !          1093:        return (error);
        !          1094: }

CVSweb