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

Annotation of sys/arch/luna88k/dev/siotty.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: siotty.c,v 1.5 2007/02/14 01:12:16 jsg Exp $ */
        !             2: /* $NetBSD: siotty.c,v 1.9 2002/03/17 19:40:43 atatat Exp $ */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 2000 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Tohru Nishimura.
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  * 2. Redistributions in binary form must reproduce the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer in the
        !            18:  *    documentation and/or other materials provided with the distribution.
        !            19:  * 3. All advertising materials mentioning features or use of this software
        !            20:  *    must display the following acknowledgement:
        !            21:  *     This product includes software developed by the NetBSD
        !            22:  *     Foundation, Inc. and its contributors.
        !            23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            24:  *    contributors may be used to endorse or promote products derived
        !            25:  *    from this software without specific prior written permission.
        !            26:  *
        !            27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            37:  * POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: #include <sys/param.h>
        !            41: #include <sys/systm.h>
        !            42: #include <sys/device.h>
        !            43: #include <sys/conf.h>
        !            44: #include <sys/ioctl.h>
        !            45: #include <sys/proc.h>
        !            46: #include <sys/user.h>
        !            47: #include <sys/tty.h>
        !            48: #include <sys/uio.h>
        !            49: #include <sys/fcntl.h>
        !            50: #include <dev/cons.h>
        !            51:
        !            52: #include <machine/cpu.h>
        !            53:
        !            54: #include <luna88k/dev/sioreg.h>
        !            55: #include <luna88k/dev/siovar.h>
        !            56:
        !            57: #define        TIOCM_BREAK 01000 /* non standard use */
        !            58:
        !            59: static const u_int8_t ch0_regs[6] = {
        !            60:        WR0_RSTINT,                             /* reset E/S interrupt */
        !            61:        WR1_RXALLS | WR1_TXENBL,                /* Rx per char, Tx */
        !            62:        0,                                      /* */
        !            63:        WR3_RX8BIT | WR3_RXENBL,                /* Rx */
        !            64:        WR4_BAUD96 | WR4_STOP1,                 /* Tx/Rx */
        !            65:        WR5_TX8BIT | WR5_TXENBL | WR5_DTR | WR5_RTS, /* Tx */
        !            66: };
        !            67:
        !            68: static const struct speedtab siospeedtab[] = {
        !            69:        { 2400, WR4_BAUD24, },
        !            70:        { 4800, WR4_BAUD48, },
        !            71:        { 9600, WR4_BAUD96, },
        !            72:        { -1,   0, },
        !            73: };
        !            74:
        !            75: struct siotty_softc {
        !            76:        struct device   sc_dev;
        !            77:        struct tty      *sc_tty;
        !            78:        struct sioreg   *sc_ctl;
        !            79:        u_int           sc_flags;
        !            80:        u_int8_t        sc_wr[6];
        !            81: };
        !            82:
        !            83: cdev_decl(sio);
        !            84: void siostart(struct tty *);
        !            85: int  sioparam(struct tty *, struct termios *);
        !            86: void siottyintr(int);
        !            87: int  siomctl(struct siotty_softc *, int, int);
        !            88:
        !            89: int  siotty_match(struct device *, void *, void *);
        !            90: void siotty_attach(struct device *, struct device *, void *);
        !            91:
        !            92: const struct cfattach siotty_ca = {
        !            93:        sizeof(struct siotty_softc), siotty_match, siotty_attach
        !            94: };
        !            95:
        !            96: struct cfdriver siotty_cd = {
        !            97:         NULL, "siotty", DV_TTY
        !            98: };
        !            99:
        !           100: int
        !           101: siotty_match(parent, cf, aux)
        !           102:        struct device *parent;
        !           103:        void *cf, *aux;
        !           104: {
        !           105:        struct sio_attach_args *args = aux;
        !           106:
        !           107:        if (args->channel != 0) /* XXX allow tty on Ch.B XXX */
        !           108:                return 0;
        !           109:        return 1;
        !           110: }
        !           111:
        !           112: void
        !           113: siotty_attach(parent, self, aux)
        !           114:        struct device *parent, *self;
        !           115:        void *aux;
        !           116: {
        !           117:        struct sio_softc *scp = (void *)parent;
        !           118:        struct siotty_softc *sc = (void *)self;
        !           119:        struct sio_attach_args *args = aux;
        !           120:
        !           121:        sc->sc_ctl = (struct sioreg *)scp->scp_ctl + args->channel;
        !           122:        bcopy(ch0_regs, sc->sc_wr, sizeof(ch0_regs));
        !           123:        scp->scp_intr[args->channel] = siottyintr;
        !           124:
        !           125:        if (args->hwflags == 1) {
        !           126:                printf(" (console)");
        !           127:                sc->sc_flags = TIOCFLAG_SOFTCAR;
        !           128:        }
        !           129:        else {
        !           130:                setsioreg(sc->sc_ctl, WR0, WR0_CHANRST);
        !           131:                setsioreg(sc->sc_ctl, WR2A, WR2_VEC86 | WR2_INTR_1);
        !           132:                setsioreg(sc->sc_ctl, WR2B, 0);
        !           133:                setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
        !           134:                setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
        !           135:                setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
        !           136:                setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
        !           137:                setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
        !           138:        }
        !           139:        setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); /* now interrupt driven */
        !           140:
        !           141:        printf("\n");
        !           142: }
        !           143:
        !           144: /*--------------------  low level routine --------------------*/
        !           145:
        !           146: void
        !           147: siottyintr(chan)
        !           148:        int chan;
        !           149: {
        !           150:        struct siotty_softc *sc;
        !           151:        struct sioreg *sio;
        !           152:        struct tty *tp;
        !           153:        unsigned int code;
        !           154:        int rr;
        !           155:
        !           156:        if (chan >= siotty_cd.cd_ndevs)
        !           157:                return;
        !           158:        sc = siotty_cd.cd_devs[chan];
        !           159:        tp = sc->sc_tty;
        !           160:        sio = sc->sc_ctl;
        !           161:        rr = getsiocsr(sio);
        !           162:        if (rr & RR_RXRDY) {
        !           163:                do {
        !           164:                        code = sio->sio_data;
        !           165:                        if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) {
        !           166:                                sio->sio_cmd = WR0_ERRRST;
        !           167:                                if (sio->sio_stat & RR_FRAMING)
        !           168:                                        code |= TTY_FE;
        !           169:                                else if (sio->sio_stat & RR_PARITY)
        !           170:                                        code |= TTY_PE;
        !           171:                        }
        !           172:                        if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
        !           173:                                continue;
        !           174: #if 0 && defined(DDB) /* ?!?! fails to resume ?!?! */
        !           175:                        if ((rr & RR_BREAK) && tp->t_dev == cn_tab->cn_dev) {
        !           176:                                if (db_console)
        !           177:                                        Debugger();
        !           178:                                return;
        !           179:                        }
        !           180: #endif
        !           181: /*
        !           182:                        (*tp->t_linesw->l_rint)(code, tp);
        !           183: */
        !           184:                        (*linesw[tp->t_line].l_rint)(code, tp);
        !           185:                } while ((rr = getsiocsr(sio)) & RR_RXRDY);
        !           186:        }
        !           187:        if (rr & RR_TXRDY) {
        !           188:                sio->sio_cmd = WR0_RSTPEND;
        !           189:                if (tp != NULL) {
        !           190:                        tp->t_state &= ~(TS_BUSY|TS_FLUSH);
        !           191: /*
        !           192:                        (*tp->t_linesw->l_start)(tp);
        !           193: */
        !           194:                        (*linesw[tp->t_line].l_start)(tp);
        !           195:                }
        !           196:        }
        !           197: }
        !           198:
        !           199: void
        !           200: siostart(tp)
        !           201:        struct tty *tp;
        !           202: {
        !           203:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(tp->t_dev)];
        !           204:        int s, c;
        !           205:
        !           206:        s = spltty();
        !           207:        if (tp->t_state & (TS_BUSY|TS_TIMEOUT|TS_TTSTOP))
        !           208:                goto out;
        !           209:        if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           210:                if (tp->t_state & TS_ASLEEP) {
        !           211:                        tp->t_state &= ~TS_ASLEEP;
        !           212:                        wakeup((caddr_t)&tp->t_outq);
        !           213:                }
        !           214:                selwakeup(&tp->t_wsel);
        !           215:        }
        !           216:        if (tp->t_outq.c_cc == 0)
        !           217:                goto out;
        !           218:
        !           219:        tp->t_state |= TS_BUSY;
        !           220:        while (getsiocsr(sc->sc_ctl) & RR_TXRDY) {
        !           221:                if ((c = getc(&tp->t_outq)) == -1)
        !           222:                        break;
        !           223:                sc->sc_ctl->sio_data = c;
        !           224:        }
        !           225: out:
        !           226:        splx(s);
        !           227: }
        !           228:
        !           229: int
        !           230: siostop(tp, flag)
        !           231:        struct tty *tp;
        !           232:        int flag;
        !           233: {
        !           234:        int s;
        !           235:
        !           236:         s = spltty();
        !           237:         if (TS_BUSY == (tp->t_state & (TS_BUSY|TS_TTSTOP))) {
        !           238:                 /*
        !           239:                  * Device is transmitting; must stop it.
        !           240:                  */
        !           241:                tp->t_state |= TS_FLUSH;
        !           242:         }
        !           243:         splx(s);
        !           244:        return (0);
        !           245: }
        !           246:
        !           247: int
        !           248: sioparam(tp, t)
        !           249:        struct tty *tp;
        !           250:        struct termios *t;
        !           251: {
        !           252:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(tp->t_dev)];
        !           253:        int wr4, s;
        !           254:
        !           255:        if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
        !           256:                return EINVAL;
        !           257:        wr4 = ttspeedtab(t->c_ospeed, siospeedtab);
        !           258:        if (wr4 < 0)
        !           259:                return EINVAL;
        !           260:
        !           261:        if (sc->sc_flags & TIOCFLAG_SOFTCAR) {
        !           262:                t->c_cflag |= CLOCAL;
        !           263:                t->c_cflag &= ~HUPCL;
        !           264:        }
        !           265:        if (sc->sc_flags & TIOCFLAG_CLOCAL)
        !           266:                t->c_cflag |= CLOCAL;
        !           267:
        !           268:        /*
        !           269:         * If there were no changes, don't do anything.  This avoids dropping
        !           270:         * input and improves performance when all we did was frob things like
        !           271:         * VMIN and VTIME.
        !           272:         */
        !           273:        if (tp->t_ospeed == t->c_ospeed && tp->t_cflag == t->c_cflag)
        !           274:                return 0;
        !           275:
        !           276:        tp->t_ispeed = t->c_ispeed;
        !           277:        tp->t_ospeed = t->c_ospeed;
        !           278:        tp->t_cflag = t->c_cflag;
        !           279:
        !           280:        sc->sc_wr[WR3] &= 0x3f;
        !           281:        sc->sc_wr[WR5] &= 0x9f;
        !           282:        switch (tp->t_cflag & CSIZE) {
        !           283:        case CS7:
        !           284:                sc->sc_wr[WR3] |= WR3_RX7BIT; sc->sc_wr[WR5] |= WR5_TX7BIT;
        !           285:                break;
        !           286:        case CS8:
        !           287:                sc->sc_wr[WR3] |= WR3_RX8BIT; sc->sc_wr[WR5] |= WR5_TX8BIT;
        !           288:                break;
        !           289:        }
        !           290:        if (tp->t_cflag & PARENB) {
        !           291:                wr4 |= WR4_PARENAB;
        !           292:                if ((tp->t_cflag & PARODD) == 0)
        !           293:                        wr4 |= WR4_EPARITY;
        !           294:        }
        !           295:        wr4 |= (tp->t_cflag & CSTOPB) ? WR4_STOP2 : WR4_STOP1;
        !           296:        sc->sc_wr[WR4] = wr4;
        !           297:
        !           298:        s = spltty();
        !           299:        setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
        !           300:        setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
        !           301:        setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
        !           302:        splx(s);
        !           303:
        !           304:        return 0;
        !           305: }
        !           306:
        !           307: int
        !           308: siomctl(sc, control, op)
        !           309:        struct siotty_softc *sc;
        !           310:        int control, op;
        !           311: {
        !           312:        int val, s, wr5, rr;
        !           313:
        !           314:        val = 0;
        !           315:        if (control & TIOCM_BREAK)
        !           316:                val |= WR5_BREAK;
        !           317:        if (control & TIOCM_DTR)
        !           318:                val |= WR5_DTR;
        !           319:        if (control & TIOCM_RTS)
        !           320:                val |= WR5_RTS;
        !           321:        s = spltty();
        !           322:        wr5 = sc->sc_wr[WR5];
        !           323:        switch (op) {
        !           324:        case DMSET:
        !           325:                wr5 &= ~(WR5_BREAK|WR5_DTR|WR5_RTS);
        !           326:                /* FALLTHROUGH */
        !           327:        case DMBIS:
        !           328:                wr5 |= val;
        !           329:                break;
        !           330:        case DMBIC:
        !           331:                wr5 &= ~val;
        !           332:                break;
        !           333:        case DMGET:
        !           334:                val = 0;
        !           335:                rr = getsiocsr(sc->sc_ctl);
        !           336:                if (wr5 & WR5_DTR)
        !           337:                        val |= TIOCM_DTR;
        !           338:                if (wr5 & WR5_RTS)
        !           339:                        val |= TIOCM_RTS;
        !           340:                if (rr & RR_CTS)
        !           341:                        val |= TIOCM_CTS;
        !           342:                if (rr & RR_DCD)
        !           343:                        val |= TIOCM_CD;
        !           344:                goto done;
        !           345:        }
        !           346:        sc->sc_wr[WR5] = wr5;
        !           347:        setsioreg(sc->sc_ctl, WR5, wr5);
        !           348:        val = 0;
        !           349:   done:
        !           350:        splx(s);
        !           351:        return val;
        !           352: }
        !           353:
        !           354: /*--------------------  cdevsw[] interface --------------------*/
        !           355:
        !           356: int
        !           357: sioopen(dev, flag, mode, p)
        !           358:        dev_t dev;
        !           359:        int flag, mode;
        !           360:        struct proc *p;
        !           361: {
        !           362:        struct siotty_softc *sc;
        !           363:        struct tty *tp;
        !           364:        int error;
        !           365:
        !           366:        if ((sc = siotty_cd.cd_devs[minor(dev)]) == NULL)
        !           367:                return ENXIO;
        !           368:        if ((tp = sc->sc_tty) == NULL) {
        !           369:                tp = sc->sc_tty = ttymalloc();
        !           370:        }
        !           371:        else if ((tp->t_state & TS_ISOPEN) && (tp->t_state & TS_XCLUDE)
        !           372:            && p->p_ucred->cr_uid != 0)
        !           373:                return EBUSY;
        !           374:
        !           375:        tp->t_oproc = siostart;
        !           376:        tp->t_param = sioparam;
        !           377:        tp->t_hwiflow = NULL /* XXX siohwiflow XXX */;
        !           378:        tp->t_dev = dev;
        !           379:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           380:                struct termios t;
        !           381:
        !           382:                t.c_ispeed = t.c_ospeed = TTYDEF_SPEED;
        !           383:                t.c_cflag = TTYDEF_CFLAG;
        !           384:                tp->t_ospeed = 0; /* force register update */
        !           385:                (void)sioparam(tp, &t);
        !           386:                tp->t_iflag = TTYDEF_IFLAG;
        !           387:                tp->t_oflag = TTYDEF_OFLAG;
        !           388:                tp->t_lflag = TTYDEF_LFLAG;
        !           389:                ttychars(tp);
        !           390:                ttsetwater(tp);
        !           391:                /* raise RTS and DTR here; but, DTR lead is not wired */
        !           392:                /* then check DCD condition; but, DCD lead is not wired */
        !           393:                tp->t_state |= TS_CARR_ON; /* assume detected all the time */
        !           394: #if 0
        !           395:                if ((sc->sc_flags & TIOCFLAG_SOFTCAR)
        !           396:                    || (tp->t_cflag & MDMBUF)
        !           397:                    || (getsiocsr(sc->sc_ctl) & RR_DCD))
        !           398:                        tp->t_state |= TS_CARR_ON;
        !           399:                else
        !           400:                        tp->t_state &= ~TS_CARR_ON;
        !           401: #endif
        !           402:        }
        !           403:
        !           404:        error = ttyopen(dev, tp);
        !           405:        if (error > 0)
        !           406:                return error;
        !           407: /*
        !           408:        return (*tp->t_linesw->l_open)(dev, tp);
        !           409: */
        !           410:        return (*linesw[tp->t_line].l_open)(dev, tp);
        !           411: }
        !           412:
        !           413: int
        !           414: sioclose(dev, flag, mode, p)
        !           415:        dev_t dev;
        !           416:        int flag, mode;
        !           417:        struct proc *p;
        !           418: {
        !           419:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
        !           420:        struct tty *tp = sc->sc_tty;
        !           421:        int s;
        !           422:
        !           423: /*
        !           424:        (*tp->t_linesw->l_close)(tp, flag);
        !           425: */
        !           426:        (*linesw[tp->t_line].l_close)(tp, flag);
        !           427:
        !           428:        s = spltty();
        !           429:        siomctl(sc, TIOCM_BREAK, DMBIC);
        !           430: #if 0 /* because unable to feed DTR signal */
        !           431:        if ((tp->t_cflag & HUPCL)
        !           432:            || tp->t_wopen || (tp->t_state & TS_ISOPEN) == 0) {
        !           433:                siomctl(sc, TIOCM_DTR, DMBIC);
        !           434:                /* Yield CPU time to others for 1 second, then ... */
        !           435:                siomctl(sc, TIOCM_DTR, DMBIS);
        !           436:        }
        !           437: #endif
        !           438:        splx(s);
        !           439:        return ttyclose(tp);
        !           440: }
        !           441:
        !           442: int
        !           443: sioread(dev, uio, flag)
        !           444:        dev_t dev;
        !           445:        struct uio *uio;
        !           446:        int flag;
        !           447: {
        !           448:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
        !           449:        struct tty *tp = sc->sc_tty;
        !           450:
        !           451: /*
        !           452:        return (*tp->t_linesw->l_read)(tp, uio, flag);
        !           453: */
        !           454:        return (*linesw[tp->t_line].l_read)(tp, uio, flag);
        !           455: }
        !           456:
        !           457: int
        !           458: siowrite(dev, uio, flag)
        !           459:        dev_t dev;
        !           460:        struct uio *uio;
        !           461:        int flag;
        !           462: {
        !           463:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
        !           464:        struct tty *tp = sc->sc_tty;
        !           465:
        !           466: /*
        !           467:        return (*tp->t_linesw->l_write)(tp, uio, flag);
        !           468: */
        !           469:        return (*linesw[tp->t_line].l_write)(tp, uio, flag);
        !           470: }
        !           471:
        !           472: #if 0
        !           473: int
        !           474: sioselect(dev, events, p)
        !           475:        dev_t dev;
        !           476:        int events;
        !           477:        struct proc *p;
        !           478: {
        !           479:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
        !           480:        struct tty *tp = sc->sc_tty;
        !           481:
        !           482: /*
        !           483:        return ((*tp->t_linesw->l_poll)(tp, events, p));
        !           484: */
        !           485:        return ((*linesw[tp->t_line].l_select)(tp, events, p));
        !           486:
        !           487: }
        !           488: #endif
        !           489:
        !           490: int
        !           491: sioioctl(dev, cmd, data, flag, p)
        !           492:        dev_t dev;
        !           493:        u_long cmd;
        !           494:        caddr_t data;
        !           495:        int flag;
        !           496:        struct proc *p;
        !           497: {
        !           498:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
        !           499:        struct tty *tp = sc->sc_tty;
        !           500:        int error;
        !           501:
        !           502: /*
        !           503:        error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
        !           504: */
        !           505:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
        !           506:        if (error >= 0)
        !           507:                return error;
        !           508:
        !           509:        error = ttioctl(tp, cmd, data, flag, p);
        !           510:        if (error >= 0)
        !           511:                return error;
        !           512:
        !           513:        /* the last resort for TIOC ioctl tranversing */
        !           514:        switch (cmd) {
        !           515:        case TIOCSBRK: /* Set the hardware into BREAK condition */
        !           516:                siomctl(sc, TIOCM_BREAK, DMBIS);
        !           517:                break;
        !           518:        case TIOCCBRK: /* Clear the hardware BREAK condition */
        !           519:                siomctl(sc, TIOCM_BREAK, DMBIC);
        !           520:                break;
        !           521:        case TIOCSDTR: /* Assert DTR signal */
        !           522:                siomctl(sc, TIOCM_DTR|TIOCM_RTS, DMBIS);
        !           523:                break;
        !           524:        case TIOCCDTR: /* Clear DTR signal */
        !           525:                siomctl(sc, TIOCM_DTR|TIOCM_RTS, DMBIC);
        !           526:                break;
        !           527:        case TIOCMSET: /* Set modem state replacing current one */
        !           528:                siomctl(sc, *(int *)data, DMSET);
        !           529:                break;
        !           530:        case TIOCMGET: /* Return current modem state */
        !           531:                *(int *)data = siomctl(sc, 0, DMGET);
        !           532:                break;
        !           533:        case TIOCMBIS: /* Set individual bits of modem state */
        !           534:                siomctl(sc, *(int *)data, DMBIS);
        !           535:                break;
        !           536:        case TIOCMBIC: /* Clear individual bits of modem state */
        !           537:                siomctl(sc, *(int *)data, DMBIC);
        !           538:                break;
        !           539:        case TIOCSFLAGS: /* Instruct how serial port behaves */
        !           540:                error = suser(p, 0);
        !           541:                if (error != 0)
        !           542:                        return EPERM;
        !           543:                sc->sc_flags = *(int *)data;
        !           544:                break;
        !           545:        case TIOCGFLAGS: /* Return current serial port state */
        !           546:                *(int *)data = sc->sc_flags;
        !           547:                break;
        !           548:        default:
        !           549: /*
        !           550:                return EPASSTHROUGH;
        !           551: */
        !           552:                return ENOTTY;
        !           553:        }
        !           554:        return 0;
        !           555: }
        !           556:
        !           557: /* ARSGUSED */
        !           558: struct tty *
        !           559: siotty(dev)
        !           560:        dev_t dev;
        !           561: {
        !           562:        struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
        !           563:
        !           564:        return sc->sc_tty;
        !           565: }
        !           566:
        !           567: /*--------------------  miscellaneous routines --------------------*/
        !           568:
        !           569: /* EXPORT */ void
        !           570: setsioreg(sio, regno, val)
        !           571:        struct sioreg *sio;
        !           572:        int regno, val;
        !           573: {
        !           574:        if (regno != 0)
        !           575:                sio->sio_cmd = regno;   /* DELAY(); */
        !           576:        sio->sio_cmd = val;             /* DELAY(); */
        !           577: }
        !           578:
        !           579: /* EXPORT */ int
        !           580: getsiocsr(sio)
        !           581:        struct sioreg *sio;
        !           582: {
        !           583:        int val;
        !           584:
        !           585:        val = sio->sio_stat << 8;       /* DELAY(); */
        !           586:        sio->sio_cmd = 1;               /* DELAY(); */
        !           587:        val |= sio->sio_stat;           /* DELAY(); */
        !           588:        return val;
        !           589: }
        !           590:
        !           591: /*---------------------  console interface ----------------------*/
        !           592:
        !           593: void syscnattach(int);
        !           594: int  syscngetc(dev_t);
        !           595: void syscnputc(dev_t, int);
        !           596:
        !           597: struct consdev syscons = {
        !           598:        NULL,
        !           599:        NULL,
        !           600:        syscngetc,
        !           601:        syscnputc,
        !           602:        nullcnpollc,
        !           603:        NULL,
        !           604:        NODEV,
        !           605:        CN_REMOTE,
        !           606: };
        !           607:
        !           608: /* EXPORT */ void
        !           609: syscnattach(channel)
        !           610:        int channel;
        !           611: {
        !           612: /*
        !           613:  * Channel A is immediately initialized with 9600N1 right after cold
        !           614:  * boot/reset/poweron.  ROM monitor emits one line message on CH.A.
        !           615:  */
        !           616:        struct sioreg *sio;
        !           617:        sio = (struct sioreg *)0x51000000 + channel;
        !           618:
        !           619: /*     syscons.cn_dev = makedev(7, channel); */
        !           620:        syscons.cn_dev = makedev(12, channel);
        !           621:        cn_tab = &syscons;
        !           622:
        !           623: #if 0
        !           624:        setsioreg(sio, WR0, WR0_CHANRST);
        !           625:        setsioreg(sio, WR2A, WR2_VEC86 | WR2_INTR_1);
        !           626:        setsioreg(sio, WR2B, 0);
        !           627:        setsioreg(sio, WR0, ch0_regs[WR0]);
        !           628:        setsioreg(sio, WR4, ch0_regs[WR4]);
        !           629:        setsioreg(sio, WR3, ch0_regs[WR3]);
        !           630:        setsioreg(sio, WR5, ch0_regs[WR5]);
        !           631:        setsioreg(sio, WR0, ch0_regs[WR0]);
        !           632: #endif
        !           633: }
        !           634:
        !           635: /* EXPORT */ int
        !           636: syscngetc(dev)
        !           637:        dev_t dev;
        !           638: {
        !           639:        struct sioreg *sio;
        !           640:        int s, c;
        !           641:
        !           642:        sio = (struct sioreg *)0x51000000 + ((int)dev & 0x1);
        !           643:        s = splhigh();
        !           644:        while ((getsiocsr(sio) & RR_RXRDY) == 0)
        !           645:                ;
        !           646:        c = sio->sio_data;
        !           647:        splx(s);
        !           648:
        !           649:        return c;
        !           650: }
        !           651:
        !           652: /* EXPORT */ void
        !           653: syscnputc(dev, c)
        !           654:        dev_t dev;
        !           655:        int c;
        !           656: {
        !           657:        struct sioreg *sio;
        !           658:        int s;
        !           659:
        !           660:        sio = (struct sioreg *)0x51000000 + ((int)dev & 0x1);
        !           661:        s = splhigh();
        !           662:        while ((getsiocsr(sio) & RR_TXRDY) == 0)
        !           663:                ;
        !           664:        sio->sio_cmd = WR0_RSTPEND;
        !           665:        sio->sio_data = c;
        !           666:        splx(s);
        !           667: }

CVSweb