[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

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