[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

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