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

Annotation of sys/arch/mvme68k/dev/zs.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: zs.c,v 1.25 2006/06/11 20:46:50 miod Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2000 Steve Murphree, Jr.
        !             5:  * Copyright (c) 1995 Theo de Raadt
        !             6:  * Copyright (c) 1993 Paul Mackerras.
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            27:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            28:  */
        !            29: /*
        !            30:  * Serial I/O via an SCC,
        !            31:  */
        !            32: #include <sys/param.h>
        !            33: #include <sys/ioctl.h>
        !            34: #include <sys/proc.h>
        !            35: #include <sys/user.h>
        !            36: #include <sys/tty.h>
        !            37: #include <sys/uio.h>
        !            38: #include <sys/systm.h>
        !            39: #include <sys/kernel.h>
        !            40: #include <sys/syslog.h>
        !            41: #include <sys/fcntl.h>
        !            42: #include <sys/device.h>
        !            43:
        !            44: #include <machine/autoconf.h>
        !            45: #include <machine/conf.h>
        !            46: #include <machine/cpu.h>
        !            47:
        !            48: #ifdef DDB
        !            49: #include <ddb/db_var.h>
        !            50: #endif
        !            51:
        !            52: #include <dev/cons.h>
        !            53:
        !            54: #include <mvme68k/dev/scc.h>
        !            55:
        !            56: #include "pcc.h"
        !            57: #include "mc.h"
        !            58:
        !            59: #if NPCC > 0
        !            60: #include <mvme68k/dev/pccreg.h>
        !            61: #endif
        !            62: #if NMC > 0
        !            63: #include <mvme68k/dev/mcreg.h>
        !            64: #endif
        !            65:
        !            66: #include "zs.h"
        !            67:
        !            68: #define NZSLINE                (NZS*2)
        !            69:
        !            70: #define RECV_BUF       512
        !            71: #define ERROR_DET      0xed
        !            72:
        !            73: #define TS_DRAIN       TS_FLUSH /* waiting for output to drain */
        !            74:
        !            75: #define splzs()                _splraise(PSL_S | PSL_IPL4)
        !            76:
        !            77: struct zs {
        !            78:        short    flags;         /* see below */
        !            79:        char     rr0;           /* holds previous CTS, DCD state */
        !            80:        u_char      imask;              /* mask for input chars */
        !            81:        int      nzs_open;      /* # opens as /dev/zsn */
        !            82:        struct tty  *tty;               /* link to tty structure */
        !            83:        struct sccregs scc;             /* SCC shadow registers */
        !            84:        u_char      *rcv_get;
        !            85:        u_char      *rcv_put;
        !            86:        u_char      *rcv_end;
        !            87:        volatile int   rcv_count;
        !            88:        int      rcv_len;
        !            89:        char     *send_ptr;
        !            90:        int      send_count;
        !            91:        int      sent_count;
        !            92:        volatile char  modem_state;
        !            93:        volatile char  modem_change;
        !            94:        volatile short hflags;
        !            95:        char     rcv_buf[RECV_BUF];
        !            96: };
        !            97:
        !            98: /* Bits in flags */
        !            99: #define ZS_SIDEA       1
        !           100: #define ZS_INITED      2
        !           101: #define ZS_INTEN       4
        !           102: #define ZS_RESET       8
        !           103: #define ZS_CONSOLE     0x20
        !           104:
        !           105: /* Bits in hflags */
        !           106: #define ZH_OBLOCK      1       /* output blocked by CTS */
        !           107: #define ZH_SIRQ                2       /* soft interrupt request */
        !           108: #define ZH_TXING       4       /* transmitter active */
        !           109: #define ZH_RXOVF       8       /* receiver buffer overflow */
        !           110:
        !           111: struct zssoftc {
        !           112:        struct device  sc_dev;
        !           113:        struct zs   sc_zs[2];
        !           114:        struct intrhand   sc_ih;
        !           115:        int      sc_flags;
        !           116: };
        !           117: #define ZSSF_85230     1
        !           118:
        !           119: struct tty *zs_tty[NZSLINE];
        !           120:
        !           121: struct   termios zs_cons_termios;
        !           122: int   zs_cons_unit = 0;
        !           123: int   zs_is_console = 0;
        !           124: struct   sccregs *zs_cons_scc;
        !           125:
        !           126: void  zsstart(struct tty *);
        !           127: int   zsparam(struct tty *, struct termios *);
        !           128: int   zsirq(void *);
        !           129: int   zsregs(vaddr_t, int, volatile u_char **, volatile u_char **);
        !           130: int   zspclk(void);
        !           131:
        !           132: u_int8_t sir_zs;
        !           133: void  zs_softint(void *);
        !           134:
        !           135: #define zsunit(dev)    (minor(dev) >> 1)
        !           136: #define zsside(dev)    (minor(dev) & 1)
        !           137:
        !           138: /*
        !           139:  * Autoconfiguration stuff.
        !           140:  */
        !           141: void  zsattach(struct device *, struct device *, void *);
        !           142: int   zsmatch(struct device *, void *, void *);
        !           143:
        !           144: struct cfattach zs_ca = {
        !           145:        sizeof(struct zssoftc), zsmatch, zsattach
        !           146: };
        !           147:
        !           148: struct cfdriver zs_cd = {
        !           149:        NULL, "zs", DV_TTY
        !           150: };
        !           151:
        !           152: void   zs_ttydef(struct zs *);
        !           153: struct tty *zstty(dev_t);
        !           154: void   zs_init(struct zs *);
        !           155: void   zscc_init(struct zs *, struct termios *);
        !           156: int    zscc_params(struct sccregs *, struct termios *);
        !           157: int    zscc_mget(struct sccregs *);
        !           158: void   zscc_mset(struct sccregs *, int);
        !           159: void   zscc_mclr(struct sccregs *, int);
        !           160: void   zs_drain(struct zs *);
        !           161: void   zs_unblock(struct tty *);
        !           162: void   zs_txint(struct zs *);
        !           163: void   zs_rxint(struct zs *);
        !           164: void   zs_extint(struct zs *);
        !           165: cons_decl(zs);
        !           166:
        !           167: int
        !           168: zsmatch(parent, vcf, args)
        !           169:        struct device *parent;
        !           170:        void  *vcf, *args;
        !           171: {
        !           172:        struct confargs *ca = args;
        !           173:        unsigned char *zstest = (unsigned char *)ca->ca_vaddr;
        !           174:        /*
        !           175:         * If zs1 is in the config, we must test to see if it really exists.
        !           176:         * Some 162s only have one scc device, but the memory location for
        !           177:         * the second scc still checks valid and every byte contains 0xFF. So
        !           178:         * this is what we test with for now. XXX - smurph
        !           179:         */
        !           180:        if (!badvaddr((vaddr_t)ca->ca_vaddr, 1))
        !           181:                if (*zstest == 0xFF)
        !           182:                        return (0);
        !           183:                else
        !           184:                        return (1);
        !           185:        else
        !           186:                return (0);
        !           187: }
        !           188:
        !           189: void
        !           190: zsattach(parent, self, args)
        !           191:        struct device *parent, *self;
        !           192:        void  *args;
        !           193: {
        !           194:        struct zssoftc *sc;
        !           195:        struct zs *zp, *zc;
        !           196:        u_char  ir;
        !           197:        volatile struct scc *scc;
        !           198:        volatile u_char *scc_cr, *scc_dr;
        !           199:        struct confargs *ca = args;
        !           200:        int     zs_level = ca->ca_ipl;
        !           201:        int   size;
        !           202:        static int initirq = 0;
        !           203:
        !           204:        sc = (struct zssoftc *) self;
        !           205:
        !           206:        /* connect the interrupt */
        !           207:        sc->sc_ih.ih_fn = zsirq;
        !           208:        sc->sc_ih.ih_arg = (void *)self->dv_unit;
        !           209:        sc->sc_ih.ih_ipl = zs_level;
        !           210:        sc->sc_ih.ih_wantframe = 0;
        !           211:
        !           212:        switch (ca->ca_bustype) {
        !           213: #if NPCC > 0
        !           214:        case BUS_PCC:
        !           215:                pccintr_establish(PCCV_ZS, &sc->sc_ih, self->dv_xname);
        !           216:                break;
        !           217: #endif
        !           218: #if NMC > 0
        !           219:        case BUS_MC:
        !           220:                if (sys_mc->mc_chiprev == 0x01)
        !           221:                        /*
        !           222:                         * MC rev 0x01 has a bug and can not access scc regs directly.
        !           223:                         * Macros will do the right thing based on the value of
        !           224:                         * mc_rev1_bug - XXX smurph
        !           225:                         */
        !           226:                        mc_rev1_bug = 1; /* defined in scc.h */
        !           227:                mcintr_establish(MCV_ZS, &sc->sc_ih, self->dv_xname);
        !           228:                break;
        !           229: #endif
        !           230:        }
        !           231:
        !           232:        zp = &sc->sc_zs[0];
        !           233:        scc = (volatile struct scc *)ca->ca_vaddr;
        !           234:
        !           235:        /*
        !           236:         * the locations of the control and data register move around
        !           237:         * on different MVME models, so we generate independent pointers
        !           238:         * to them.
        !           239:         */
        !           240:        size = zsregs(ca->ca_vaddr, 0, &scc_cr, &scc_dr);
        !           241:
        !           242:        if (zs_is_console && self->dv_unit == zs_cons_unit) {
        !           243:                /* SCC is the console - it's already reset */
        !           244:                zc = zp + zsside(zs_cons_unit);
        !           245:                zc->scc = *zs_cons_scc;
        !           246:                zs_cons_scc = &zc->scc;
        !           247:                zc->flags |= ZS_CONSOLE;
        !           248:        } else {
        !           249:                /* reset the SCC */
        !           250:                *(scc_cr + size) = 0;
        !           251:                *(scc_cr + size) = 9;
        !           252:                *(scc_cr + size) = 0xC0;        /* hardware reset of SCC, both sides */
        !           253:        }
        !           254:
        !           255:        /* side A */
        !           256:        zp->scc.s_cr = scc_cr + size;
        !           257:        zp->scc.s_dr = scc_dr + size;
        !           258:        zp->flags |= ZS_SIDEA | ZS_RESET;
        !           259:
        !           260:        /* side B */
        !           261:        ++zp;
        !           262:        zp->scc.s_cr = scc_cr;
        !           263:        zp->scc.s_dr = scc_dr;
        !           264:        zp->flags |= ZS_RESET;
        !           265:
        !           266:        if (sir_zs == 0)
        !           267:                sir_zs = allocate_sir(zs_softint, 0);
        !           268:
        !           269:        printf("\n");
        !           270:
        !           271:        /*
        !           272:         * XXX we end up doing this twice... once for
        !           273:         * each ZS chip. We should really not turn interrupts on until
        !           274:         * we have initialized the last of the two chips. But then we
        !           275:         * will need to search the config system to see if we will be
        !           276:         * called for the 2nd chip... otherwise, a config without a zs1
        !           277:         * would never enable interrupts!
        !           278:         */
        !           279:        switch (ca->ca_bustype) {
        !           280: #if NPCC > 0
        !           281:                case BUS_PCC:
        !           282:                        ir = sys_pcc->pcc_zsirq;
        !           283:                        if ((ir & PCC_IRQ_IPL) != 0 && (ir & PCC_IRQ_IPL) != zs_level)
        !           284:                                panic("zs configured at different IPLs");
        !           285:                        if (initirq)
        !           286:                                break;
        !           287:                        sys_pcc->pcc_zsirq = zs_level | PCC_IRQ_IEN | PCC_ZS_PCCVEC;
        !           288:                        break;
        !           289: #endif
        !           290: #if NMC > 0
        !           291:                case BUS_MC:
        !           292:                        ir = sys_mc->mc_zsirq;
        !           293:                        if ((ir & MC_IRQ_IPL) != 0 && (ir & MC_IRQ_IPL) != zs_level)
        !           294:                                panic("zs configured at different IPLs");
        !           295:                        if (initirq)
        !           296:                                break;
        !           297:                        sys_mc->mc_zsirq = zs_level | MC_IRQ_IEN;
        !           298:                        break;
        !           299: #endif
        !           300:        }
        !           301:        initirq = 1;
        !           302: }
        !           303:
        !           304: void
        !           305: zs_ttydef(zp)
        !           306:        struct zs *zp;
        !           307: {
        !           308:        struct tty *tp = zp->tty;
        !           309:
        !           310:        if ((zp->flags & ZS_CONSOLE) == 0) {
        !           311:                tp->t_iflag = TTYDEF_IFLAG;
        !           312:                tp->t_oflag = TTYDEF_OFLAG;
        !           313:                tp->t_cflag = TTYDEF_CFLAG;
        !           314:                tp->t_lflag = TTYDEF_LFLAG;
        !           315:                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
        !           316:        } else
        !           317:                tp->t_termios = zs_cons_termios;
        !           318:        ttychars(tp);
        !           319:        ttsetwater(tp);
        !           320:        tp->t_oproc = zsstart;
        !           321:        tp->t_param = zsparam;
        !           322:
        !           323:        zp->rcv_get = zp->rcv_buf;
        !           324:        zp->rcv_put = zp->rcv_buf;
        !           325:        zp->rcv_end = zp->rcv_buf + sizeof(zp->rcv_buf);
        !           326:        zp->rcv_len = sizeof(zp->rcv_buf) / 2;
        !           327: }
        !           328:
        !           329: struct tty *
        !           330: zstty(dev)
        !           331:        dev_t   dev;
        !           332: {
        !           333:        if (minor(dev) < NZSLINE)
        !           334:                return (zs_tty[minor(dev)]);
        !           335:        return (NULL);
        !           336: }
        !           337:
        !           338: /* ARGSUSED */
        !           339: int
        !           340: zsopen(dev, flag, mode, p)
        !           341:        dev_t dev;
        !           342:        int flag, mode;
        !           343:        struct proc *p;
        !           344: {
        !           345:        register struct tty *tp;
        !           346:        int     error;
        !           347:        struct zs *zp;
        !           348:        struct zssoftc *sc;
        !           349:
        !           350:        if (zsunit(dev) >= zs_cd.cd_ndevs ||
        !           351:                 (sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(dev)]) == NULL)
        !           352:                return (ENODEV);
        !           353:
        !           354:        zp = &sc->sc_zs[zsside(dev)];
        !           355:        if (zp->tty == NULL) {
        !           356:                zp->tty = ttymalloc();
        !           357:                zs_ttydef(zp);
        !           358:                if (minor(dev) < NZSLINE)
        !           359:                        zs_tty[minor(dev)] = zp->tty;
        !           360:        }
        !           361:        tp = zp->tty;
        !           362:        tp->t_dev = dev;
        !           363:
        !           364:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           365:                tp->t_state |= TS_WOPEN;
        !           366:                zs_init(zp);
        !           367:                if ((zp->modem_state & SCC_DCD) != 0)
        !           368:                        tp->t_state |= TS_CARR_ON;
        !           369:        } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
        !           370:                return (EBUSY);
        !           371:
        !           372:        error = ((*linesw[tp->t_line].l_open) (dev, tp));
        !           373:
        !           374:        if (error == 0)
        !           375:                ++zp->nzs_open;
        !           376:        return (error);
        !           377: }
        !           378:
        !           379: int
        !           380: zsclose(dev, flag, mode, p)
        !           381:        dev_t   dev;
        !           382:        int     flag, mode;
        !           383:        struct proc *p;
        !           384: {
        !           385:        struct zs *zp;
        !           386:        struct tty *tp;
        !           387:        struct zssoftc *sc;
        !           388:        int s;
        !           389:
        !           390:        if (zsunit(dev) >= zs_cd.cd_ndevs ||
        !           391:                 (sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(dev)]) == NULL)
        !           392:                return (ENODEV);
        !           393:        zp = &sc->sc_zs[zsside(dev)];
        !           394:        tp = zp->tty;
        !           395:
        !           396:        (*linesw[tp->t_line].l_close) (tp, flag);
        !           397:        s = splzs();
        !           398:        if ((zp->flags & ZS_CONSOLE) == 0 && (tp->t_cflag & HUPCL) != 0)
        !           399:                ZBIC(&zp->scc, 5, 0x82);                  /* drop DTR, RTS */
        !           400:        ZBIC(&zp->scc, 3, 1);   /* disable receiver */
        !           401:        splx(s);
        !           402:        ttyclose(tp);
        !           403:        zp->nzs_open = 0;
        !           404:        return (0);
        !           405: }
        !           406:
        !           407: /*ARGSUSED*/
        !           408: int
        !           409: zsread(dev, uio, flag)
        !           410:        dev_t dev;
        !           411:        struct uio *uio;
        !           412:        int   flag;
        !           413: {
        !           414:        struct zssoftc *sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(dev)];
        !           415:        struct zs *zp = &sc->sc_zs[zsside(dev)];
        !           416:        struct tty *tp = zp->tty;
        !           417:
        !           418:        return ((*linesw[tp->t_line].l_read) (tp, uio, flag));
        !           419: }
        !           420:
        !           421: /*ARGSUSED*/
        !           422: int
        !           423: zswrite(dev, uio, flag)
        !           424:        dev_t   dev;
        !           425:        struct uio *uio;
        !           426:        int     flag;
        !           427: {
        !           428:        struct zssoftc *sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(dev)];
        !           429:        struct zs *zp = &sc->sc_zs[zsside(dev)];
        !           430:        struct tty *tp = zp->tty;
        !           431:
        !           432:        return ((*linesw[tp->t_line].l_write) (tp, uio, flag));
        !           433: }
        !           434:
        !           435: int
        !           436: zsioctl(dev, cmd, data, flag, p)
        !           437:        dev_t dev;
        !           438:        u_long cmd;
        !           439:        caddr_t data;
        !           440:        int flag;
        !           441:        struct proc *p;
        !           442: {
        !           443:        struct zssoftc *sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(dev)];
        !           444:        struct zs *zp = &sc->sc_zs[zsside(dev)];
        !           445:        struct tty *tp = zp->tty;
        !           446:        register struct sccregs *scc = &zp->scc;
        !           447:        register int error, s;
        !           448:
        !           449:        error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, data, flag, p);
        !           450:        if (error >= 0)
        !           451:                return (error);
        !           452:        error = ttioctl(tp, cmd, data, flag, p);
        !           453:        if (error >= 0)
        !           454:                return (error);
        !           455:        error = 0;
        !           456:        s = splzs();
        !           457:        switch (cmd) {
        !           458:                case TIOCSDTR:
        !           459:                        ZBIS(scc, 5, 0x80);
        !           460:                        break;
        !           461:                case TIOCCDTR:
        !           462:                        ZBIC(scc, 5, 0x80);
        !           463:                        break;
        !           464:                case TIOCSBRK:
        !           465:                        splx(s);
        !           466:                        zs_drain(zp);
        !           467:                        s = splzs();
        !           468:                        ZBIS(scc, 5, 0x10);
        !           469:                        spltty();
        !           470:                        zs_unblock(tp);
        !           471:                        break;
        !           472:                case TIOCCBRK:
        !           473:                        ZBIC(scc, 5, 0x10);
        !           474:                        break;
        !           475:                case TIOCMGET:
        !           476:                        *(int *) data = zscc_mget(scc);
        !           477:                        break;
        !           478:                case TIOCMSET:
        !           479:                        zscc_mset(scc, *(int *) data);
        !           480:                        zscc_mclr(scc, ~*(int *) data);
        !           481:                        break;
        !           482:                case TIOCMBIS:
        !           483:                        zscc_mset(scc, *(int *) data);
        !           484:                        break;
        !           485:                case TIOCMBIC:
        !           486:                        zscc_mclr(scc, *(int *) data);
        !           487:                        break;
        !           488:                default:
        !           489:                        error = ENOTTY;
        !           490:        }
        !           491:        splx(s);
        !           492:        return (error);
        !           493: }
        !           494:
        !           495: int
        !           496: zsparam(tp, t)
        !           497:        struct tty *tp;
        !           498:        struct termios *t;
        !           499: {
        !           500:        struct zssoftc *sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(tp->t_dev)];
        !           501:        struct zs *zp = &sc->sc_zs[zsside(tp->t_dev)];
        !           502:        register int s;
        !           503:
        !           504:        zs_drain(zp);
        !           505:        s = splzs();
        !           506:        zp->imask = zscc_params(&zp->scc, t);
        !           507:        tp->t_ispeed = t->c_ispeed;
        !           508:        tp->t_ospeed = t->c_ospeed;
        !           509:        tp->t_cflag = t->c_cflag;
        !           510:        if ((tp->t_cflag & CCTS_OFLOW) == 0)
        !           511:                zp->hflags &= ~ZH_OBLOCK;
        !           512:        else if ((zp->modem_state & 0x20) == 0)
        !           513:                zp->hflags |= ZH_OBLOCK;
        !           514:        spltty();
        !           515:        zs_unblock(tp);
        !           516:        splx(s);
        !           517:        return (0);
        !           518: }
        !           519:
        !           520: void
        !           521: zsstart(tp)
        !           522:        struct tty *tp;
        !           523: {
        !           524:        struct zssoftc *sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(tp->t_dev)];
        !           525:        struct zs *zp = &sc->sc_zs[zsside(tp->t_dev)];
        !           526:        register int s, n;
        !           527:
        !           528:        s = spltty();
        !           529:        if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP | TS_DRAIN)) == 0) {
        !           530:                n = ndqb(&tp->t_outq, 0);
        !           531:                if (n > 0) {
        !           532:                        tp->t_state |= TS_BUSY;
        !           533:                        splzs();
        !           534:                        zp->hflags |= ZH_TXING;
        !           535:                        zp->send_ptr = tp->t_outq.c_cf;
        !           536:                        zp->send_count = n;
        !           537:                        zp->sent_count = 0;
        !           538:                        zs_txint(zp);
        !           539:                        spltty();
        !           540:                }
        !           541:        }
        !           542:        splx(s);
        !           543: }
        !           544:
        !           545: int
        !           546: zsstop(tp, flag)
        !           547:        struct tty *tp;
        !           548:        int flag;
        !           549: {
        !           550:        struct zssoftc *sc = (struct zssoftc *) zs_cd.cd_devs[zsunit(tp->t_dev)];
        !           551:        struct zs *zp = &sc->sc_zs[zsside(tp->t_dev)];
        !           552:        int     s, n;
        !           553:
        !           554:        s = splzs();
        !           555:        zp->send_count = 0;
        !           556:        n = zp->sent_count;
        !           557:        zp->sent_count = 0;
        !           558:        if ((tp->t_state & TS_BUSY) != 0 && (flag & FWRITE) == 0) {
        !           559:                tp->t_state &= ~TS_BUSY;
        !           560:                spltty();
        !           561:                ndflush(&tp->t_outq, n);
        !           562:                if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           563:                        if (tp->t_state & TS_ASLEEP) {
        !           564:                                tp->t_state &= ~TS_ASLEEP;
        !           565:                                wakeup((caddr_t) & tp->t_outq);
        !           566:                        }
        !           567:                        selwakeup(&tp->t_wsel);
        !           568:                }
        !           569:        }
        !           570:        splx(s);
        !           571:        return (0);
        !           572: }
        !           573:
        !           574: void
        !           575: zs_init(zp)
        !           576:        struct zs *zp;
        !           577: {
        !           578:        register int s;
        !           579:
        !           580:        s = splzs();
        !           581:        zscc_init(zp, &zp->tty->t_termios);
        !           582:        zp->rr0 = zp->modem_state = ZREAD0(&zp->scc);
        !           583:        ZBIS(&zp->scc, 1, 0x13);/* ints on tx, rx and ext/status */
        !           584:        ZBIS(&zp->scc, 9, 8);   /* enable ints */
        !           585:        zp->flags |= ZS_INTEN;
        !           586:        splx(s);
        !           587: }
        !           588:
        !           589: void
        !           590: zscc_init(zp, par)
        !           591:        struct zs *zp;
        !           592:        struct termios *par;
        !           593: {
        !           594:        struct sccregs *scc;
        !           595:
        !           596:        scc = &zp->scc;
        !           597: #if defined(MVME162) || defined(MVME172)
        !           598:        if (cputyp == CPU_162 || cputyp == CPU_172)
        !           599:                ZWRITE(scc, 2, MC_VECBASE+MCV_ZS);
        !           600: #endif
        !           601:        ZWRITE(scc, 10, 0);
        !           602:        ZWRITE(scc, 11, 0x50);  /* rx & tx clock = brgen */
        !           603:        ZWRITE(scc, 14, 3);     /* brgen enabled, from pclk */
        !           604:        zp->imask = zscc_params(scc, par);
        !           605:        ZBIS(scc, 5, 0x82);     /* set DTR and RTS */
        !           606:        zp->flags |= ZS_INITED;
        !           607: }
        !           608:
        !           609: int
        !           610: zscc_params(scc, par)
        !           611:        struct sccregs *scc;
        !           612:        struct termios *par;
        !           613: {
        !           614:        unsigned divisor, speed;
        !           615:        int     spd, imask, ints;
        !           616:
        !           617:        speed = par->c_ospeed;
        !           618:        if (speed == 0) {
        !           619:                /* disconnect - drop DTR & RTS, disable receiver */
        !           620:                ZBIC(scc, 5, 0x82);
        !           621:                ZBIC(scc, 3, 1);
        !           622:                return (0xFF);
        !           623:        }
        !           624:        if ((par->c_cflag & CREAD) == 0)
        !           625:                ZBIC(scc, 3, 1);/* disable receiver */
        !           626:        divisor = (zspclk() / 32 + (speed >> 1)) / speed - 2;
        !           627:        ZWRITE(scc, 12, divisor);
        !           628:        ZWRITE(scc, 13, divisor >> 8);
        !           629:        switch (par->c_cflag & CSIZE) {
        !           630:                case CS5:
        !           631:                        spd = 0;
        !           632:                        imask = 0x1F;
        !           633:                        break;
        !           634:                case CS6:
        !           635:                        spd = 0x40;
        !           636:                        imask = 0x3F;
        !           637:                        break;
        !           638:                case CS7:
        !           639:                        spd = 0x20;
        !           640:                        imask = 0x7F;
        !           641:                        break;
        !           642:                default:
        !           643:                        spd = 0x60;
        !           644:                        imask = 0xFF;
        !           645:        }
        !           646:        ZWRITE(scc, 5, (scc->s_val[5] & ~0x60) | spd);
        !           647:        ZWRITE(scc, 3, (scc->s_val[3] & ~0xC0) | (spd << 1));
        !           648:        spd = par->c_cflag & CSTOPB ? 8 : 0;
        !           649:        spd |= par->c_cflag & PARENB ? par->c_cflag & PARODD ? 1 : 3 : 0;
        !           650:        ZWRITE(scc, 4, 0x44 | spd);
        !           651:        ZBIS(scc, 5, 8);        /* enable transmitter */
        !           652:        if ((par->c_cflag & CREAD) != 0)
        !           653:                ZBIS(scc, 3, 1);/* enable receiver */
        !           654:        ints = 0;
        !           655:        if ((par->c_cflag & CLOCAL) == 0)
        !           656:                ints |= SCC_DCD;
        !           657:        if ((par->c_cflag & CCTS_OFLOW) != 0)
        !           658:                ints |= SCC_CTS;
        !           659: #if 0
        !           660:        if (cputyp == CPU_162 || cputyp == CPU_172) {
        !           661:                ZWRITE(scc, 15, ints | 1);
        !           662:                /*
        !           663:                 * now.. register 7 has become register 7': disable all
        !           664:                 * 82530-only features for now
        !           665:                 */
        !           666:                ZWRITE(scc, 7, 0x20);
        !           667:        }
        !           668: #endif
        !           669:        ZWRITE(scc, 15, ints);
        !           670:        return (imask);
        !           671: }
        !           672:
        !           673: int
        !           674: zscc_mget(scc)
        !           675:        register struct sccregs *scc;
        !           676: {
        !           677:        int     bits = 0, rr0;
        !           678:
        !           679:        if ((scc->s_val[3] & SCC_RCVEN) != 0)
        !           680:                bits |= TIOCM_LE;
        !           681:        if ((scc->s_val[5] & SCC_DTR) != 0)
        !           682:                bits |= TIOCM_DTR;
        !           683:        if ((scc->s_val[5] & SCC_RTS) != 0)
        !           684:                bits |= TIOCM_RTS;
        !           685:        rr0 = ZREAD0(scc);
        !           686:        if ((rr0 & SCC_CTS) != 0)
        !           687:                bits |= TIOCM_CTS;
        !           688:        if ((rr0 & SCC_DCD) != 0)
        !           689:                bits |= TIOCM_CAR;
        !           690:        return (bits);
        !           691: }
        !           692:
        !           693: void
        !           694: zscc_mset(scc, bits)
        !           695:        register struct sccregs *scc;
        !           696:        int bits;
        !           697: {
        !           698:        if ((bits & TIOCM_LE) != 0)
        !           699:                ZBIS(scc, 3, SCC_RCVEN);
        !           700:        if ((bits & TIOCM_DTR) != 0)
        !           701:                ZBIS(scc, 5, SCC_DTR);
        !           702:        if ((bits & TIOCM_RTS) != 0)
        !           703:                ZBIS(scc, 5, SCC_RTS);
        !           704: }
        !           705:
        !           706: void
        !           707: zscc_mclr(scc, bits)
        !           708:        register struct sccregs *scc;
        !           709:        int bits;
        !           710: {
        !           711:        if ((bits & TIOCM_LE) != 0)
        !           712:                ZBIC(scc, 3, SCC_RCVEN);
        !           713:        if ((bits & TIOCM_DTR) != 0)
        !           714:                ZBIC(scc, 5, TIOCM_DTR);
        !           715:        if ((bits & TIOCM_RTS) != 0)
        !           716:                ZBIC(scc, 5, SCC_RTS);
        !           717: }
        !           718:
        !           719: void
        !           720: zs_drain(zp)
        !           721:        register struct zs *zp;
        !           722: {
        !           723:        register int s;
        !           724:
        !           725:        zp->tty->t_state |= TS_DRAIN;
        !           726:        /* wait for Tx buffer empty and All sent bits to be set */
        !           727:        s = splzs();
        !           728:        while ((ZREAD0(&zp->scc) & SCC_TXRDY) == 0 ||
        !           729:                         (ZREAD(&zp->scc, 1) & 1) == 0) {
        !           730:                splx(s);
        !           731:                DELAY(100);
        !           732:                s = splzs();
        !           733:        }
        !           734:        splx(s);
        !           735: }
        !           736:
        !           737: void
        !           738: zs_unblock(tp)
        !           739:        register struct tty *tp;
        !           740: {
        !           741:        tp->t_state &= ~TS_DRAIN;
        !           742:        if (tp->t_outq.c_cc != 0)
        !           743:                zsstart(tp);
        !           744: }
        !           745:
        !           746: /*
        !           747:  * Hardware interrupt from an SCC.
        !           748:  */
        !           749: int
        !           750: zsirq(arg)
        !           751:        void *arg;
        !           752: {
        !           753:        int unit = (int)arg;
        !           754:        struct zssoftc *sc = (struct zssoftc *) zs_cd.cd_devs[unit];
        !           755:        struct zs *zp = &sc->sc_zs[0];
        !           756:        int ipend;
        !           757:
        !           758:        ipend = ZREAD(&zp->scc, 3);     /* read int pending from A side */
        !           759:        if (ipend == 0)
        !           760:                return (0);
        !           761:        if ((ipend & 0x20) != 0)
        !           762:                zs_rxint(zp);
        !           763:        if ((ipend & 0x10) != 0)
        !           764:                zs_txint(zp);
        !           765:        if ((ipend & 0x8) != 0)
        !           766:                zs_extint(zp);
        !           767:        ++zp;                           /* now look for B side ints */
        !           768:        if ((ipend & 0x4) != 0)
        !           769:                zs_rxint(zp);
        !           770:        if ((ipend & 0x2) != 0)
        !           771:                zs_txint(zp);
        !           772:        if ((ipend & 0x1) != 0)
        !           773:                zs_extint(zp);
        !           774:        ZWRITE0(&zp->scc, 0x38);        /* reset highest IUS */
        !           775:
        !           776:        return (1);
        !           777: }
        !           778:
        !           779: void
        !           780: zs_txint(zp)
        !           781:        register struct zs *zp;
        !           782: {
        !           783:        struct sccregs *scc;
        !           784:        int     c;
        !           785:        u_char *get;
        !           786:
        !           787:        scc = &zp->scc;
        !           788:        ZWRITE0(scc, 0x28);     /* reset Tx interrupt */
        !           789:        if ((zp->hflags & ZH_OBLOCK) == 0) {
        !           790:                get = zp->send_ptr;
        !           791:                while ((ZREAD0(scc) & SCC_TXRDY) != 0 && zp->send_count > 0) {
        !           792:                        c = *get++;
        !           793:                        ZWRITED(scc, c);
        !           794:                        --zp->send_count;
        !           795:                        ++zp->sent_count;
        !           796:                }
        !           797:                zp->send_ptr = get;
        !           798:                if (zp->send_count == 0 && (zp->hflags & ZH_TXING) != 0) {
        !           799:                        zp->hflags &= ~ZH_TXING;
        !           800:                        zp->hflags |= ZH_SIRQ;
        !           801:                        setsoftint(sir_zs);
        !           802:                }
        !           803:        }
        !           804: }
        !           805:
        !           806: void
        !           807: zs_rxint(zp)
        !           808:        register struct zs *zp;
        !           809: {
        !           810:        register int stat, c, n, extra;
        !           811:        u_char *put;
        !           812:
        !           813:        put = zp->rcv_put;
        !           814:        n = zp->rcv_count;
        !           815:        for (;;) {
        !           816:                if ((ZREAD0(&zp->scc) & SCC_RXFULL) == 0)       /* check Rx full */
        !           817:                        break;
        !           818:                stat = ZREAD(&zp->scc, 1) & 0x70;
        !           819:                c = ZREADD(&zp->scc) & zp->imask;
        !           820:                /* stat encodes parity, overrun, framing errors */
        !           821:                if (stat != 0)
        !           822:                        ZWRITE0(&zp->scc, 0x30);        /* reset error */
        !           823:                if ((zp->hflags & ZH_RXOVF) != 0) {
        !           824:                        zp->hflags &= ~ZH_RXOVF;
        !           825:                        stat |= 0x20;
        !           826:                }
        !           827:                extra = (stat != 0 || c == ERROR_DET) ? 2 : 0;
        !           828:                if (n + extra + 1 < zp->rcv_len) {
        !           829:                        if (extra != 0) {
        !           830:                                *put++ = ERROR_DET;
        !           831:                                if (put >= zp->rcv_end)
        !           832:                                        put = zp->rcv_buf;
        !           833:                                *put++ = stat;
        !           834:                                if (put >= zp->rcv_end)
        !           835:                                        put = zp->rcv_buf;
        !           836:                                n += 2;
        !           837:                        }
        !           838:                        *put++ = c;
        !           839:                        if (put >= zp->rcv_end)
        !           840:                                put = zp->rcv_buf;
        !           841:                        ++n;
        !           842:                } else
        !           843:                        zp->hflags |= ZH_RXOVF;
        !           844:        }
        !           845:        if (n > zp->rcv_count) {
        !           846:                zp->rcv_put = put;
        !           847:                zp->rcv_count = n;
        !           848:                zp->hflags |= ZH_SIRQ;
        !           849:                setsoftint(sir_zs);
        !           850:        }
        !           851: }
        !           852:
        !           853: /* Ext/status interrupt */
        !           854: void
        !           855: zs_extint(zp)
        !           856:        register struct zs *zp;
        !           857: {
        !           858:        int     rr0;
        !           859:        struct tty *tp = zp->tty;
        !           860:
        !           861:        rr0 = ZREAD0(&zp->scc);
        !           862:        ZWRITE0(&zp->scc, 0x10);/* reset ext/status int */
        !           863:
        !           864:        /* Handle break */
        !           865:        if (rr0 & 0x80) {
        !           866: #ifdef DDB
        !           867:                if (ISSET(zp->flags, ZS_CONSOLE) && db_console != 0)
        !           868:                        Debugger();
        !           869: #endif
        !           870:        }
        !           871:
        !           872:        if ((tp->t_cflag & CCTS_OFLOW) != 0) {
        !           873:                if ((rr0 & 0x20) == 0)
        !           874:                        zp->hflags |= ZH_OBLOCK;
        !           875:                else {
        !           876:                        zp->hflags &= ~ZH_OBLOCK;
        !           877:                        if ((rr0 & SCC_TXRDY) != 0)
        !           878:                                zs_txint(zp);
        !           879:                }
        !           880:        }
        !           881:        zp->modem_change |= rr0 ^ zp->modem_state;
        !           882:        zp->modem_state = rr0;
        !           883:        zp->hflags |= ZH_SIRQ;
        !           884:        setsoftint(sir_zs);
        !           885: }
        !           886:
        !           887: /* ARGSUSED */
        !           888: void
        !           889: zs_softint(arg)
        !           890:        void *arg;
        !           891: {
        !           892:        int     s, c, stat, rr0;
        !           893:        struct zs *zp;
        !           894:        struct tty *tp;
        !           895:        u_char *get;
        !           896:        int     unit, side;
        !           897:
        !           898:        s = splzs();
        !           899:        for (unit = 0; unit < zs_cd.cd_ndevs; ++unit) {
        !           900:                if (zs_cd.cd_devs[unit] == NULL)
        !           901:                        continue;
        !           902:                zp = &((struct zssoftc *) zs_cd.cd_devs[unit])->sc_zs[0];
        !           903:                for (side = 0; side < 2; ++side, ++zp) {
        !           904:                        if ((zp->hflags & ZH_SIRQ) == 0)
        !           905:                                continue;
        !           906:                        zp->hflags &= ~ZH_SIRQ;
        !           907:                        tp = zp->tty;
        !           908:
        !           909:                        /* check for tx done */
        !           910:                        spltty();
        !           911:                        if (tp != NULL && zp->send_count == 0
        !           912:                                 && (tp->t_state & TS_BUSY) != 0) {
        !           913:                                tp->t_state &= ~(TS_BUSY | TS_FLUSH);
        !           914:                                ndflush(&tp->t_outq, zp->sent_count);
        !           915:                                if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           916:                                        if (tp->t_state & TS_ASLEEP) {
        !           917:                                                tp->t_state &= ~TS_ASLEEP;
        !           918:                                                wakeup((caddr_t) & tp->t_outq);
        !           919:                                        }
        !           920:                                        selwakeup(&tp->t_wsel);
        !           921:                                }
        !           922:                                if (tp->t_line != 0)
        !           923:                                        (*linesw[tp->t_line].l_start) (tp);
        !           924:                                else
        !           925:                                        zsstart(tp);
        !           926:                        }
        !           927:                        splzs();
        !           928:
        !           929:                        /* check for received characters */
        !           930:                        get = zp->rcv_get;
        !           931:                        while (zp->rcv_count > 0) {
        !           932:                                c = *get++;
        !           933:                                if (get >= zp->rcv_end)
        !           934:                                        get = zp->rcv_buf;
        !           935:                                if (c == ERROR_DET) {
        !           936:                                        stat = *get++;
        !           937:                                        if (get >= zp->rcv_end)
        !           938:                                                get = zp->rcv_buf;
        !           939:                                        c = *get++;
        !           940:                                        if (get >= zp->rcv_end)
        !           941:                                                get = zp->rcv_buf;
        !           942:                                        zp->rcv_count -= 3;
        !           943:                                } else {
        !           944:                                        stat = 0;
        !           945:                                        --zp->rcv_count;
        !           946:                                }
        !           947:                                spltty();
        !           948:                                if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
        !           949:                                        continue;
        !           950:                                if (zp->nzs_open == 0) {
        !           951:
        !           952:                                } else {
        !           953:                                        if ((stat & 0x10) != 0)
        !           954:                                                c |= TTY_PE;
        !           955:                                        if ((stat & 0x20) != 0) {
        !           956:                                                log(LOG_WARNING, "zs: fifo overflow\n");
        !           957:                                                c |= TTY_FE;    /* need some error for
        !           958:                                                                 * slip stuff */
        !           959:                                        }
        !           960:                                        if ((stat & 0x40) != 0)
        !           961:                                                c |= TTY_FE;
        !           962:                                        (*linesw[tp->t_line].l_rint) (c, tp);
        !           963:                                }
        !           964:                                splzs();
        !           965:                        }
        !           966:                        zp->rcv_get = get;
        !           967:
        !           968:                        /* check for modem lines changing */
        !           969:                        while (zp->modem_change != 0 || zp->modem_state != zp->rr0) {
        !           970:                                rr0 = zp->rr0 ^ zp->modem_change;
        !           971:                                zp->modem_change = rr0 ^ zp->modem_state;
        !           972:
        !           973:                                /* Check if DCD (carrier detect) has changed */
        !           974:                                if (tp != NULL && (rr0 & 8) != (zp->rr0 & 8)) {
        !           975:                                        spltty();
        !           976:                                        ttymodem(tp, rr0 & 8);
        !           977:                                        /* XXX possibly should disable line if
        !           978:                                         * return value is 0 */
        !           979:                                        splzs();
        !           980:                                }
        !           981:                                zp->rr0 = rr0;
        !           982:                        }
        !           983:                }
        !           984:        }
        !           985:        splx(s);
        !           986: }
        !           987:
        !           988: /*
        !           989:  * Routines for using side A of the first SCC as a console.
        !           990:  */
        !           991:
        !           992: /* probe for the SCC; should check hardware */
        !           993: void
        !           994: zscnprobe(cp)
        !           995:        struct consdev *cp;
        !           996: {
        !           997:        int maj;
        !           998:
        !           999:        switch (cputyp) {
        !          1000:        case CPU_147:
        !          1001:        case CPU_162:
        !          1002:        case CPU_172:
        !          1003:                break;
        !          1004:        default:
        !          1005:                return;
        !          1006:        }
        !          1007:
        !          1008:        /* locate the major number */
        !          1009:        for (maj = 0; maj < nchrdev; maj++)
        !          1010:                if (cdevsw[maj].d_open == zsopen)
        !          1011:                        break;
        !          1012:
        !          1013:        cp->cn_dev = makedev(maj, 0);
        !          1014:        cp->cn_pri = CN_NORMAL;
        !          1015: }
        !          1016:
        !          1017: /* initialize the keyboard for use as the console */
        !          1018: struct termios zscn_termios = {
        !          1019:        TTYDEF_IFLAG,
        !          1020:        TTYDEF_OFLAG,
        !          1021:        (CREAD | CS8 | HUPCL),
        !          1022:        TTYDEF_LFLAG,
        !          1023:        {0},
        !          1024:        TTYDEF_SPEED,
        !          1025:        TTYDEF_SPEED
        !          1026: };
        !          1027:
        !          1028: struct sccregs zs_cons_sccregs;
        !          1029: int     zs_cons_imask;
        !          1030:
        !          1031: /* Polling routine for console input from a serial port. */
        !          1032: int
        !          1033: zscngetc(dev)
        !          1034:        dev_t dev;
        !          1035: {
        !          1036:        register struct sccregs *scc = zs_cons_scc;
        !          1037:        int     c, s, stat;
        !          1038:
        !          1039:        s = splhigh();  /* XXX was splzs() */
        !          1040:        for (;;) {
        !          1041:                while ((ZREAD0(scc) & SCC_RXFULL) == 0) /* wait for Rx full */
        !          1042:                        ;
        !          1043:                stat = ZREAD(scc, 1) & 0x70;
        !          1044:                c = ZREADD(scc) & zs_cons_imask;
        !          1045:                /* stat encodes parity, overrun, framing errors */
        !          1046:                if (stat == 0)
        !          1047:                        break;
        !          1048:                ZWRITE0(scc, 0x30);     /* reset error */
        !          1049:        }
        !          1050:        splx(s);
        !          1051:        return (c);
        !          1052: }
        !          1053:
        !          1054: void
        !          1055: zscnputc(dev, c)
        !          1056:        dev_t dev;
        !          1057:        int c;
        !          1058: {
        !          1059:        register struct sccregs *scc = zs_cons_scc;
        !          1060:        int     s;
        !          1061:
        !          1062:        s = splhigh();  /* XXX was splzs() */
        !          1063:        while ((ZREAD0(scc) & SCC_TXRDY) == 0)
        !          1064:                ;
        !          1065:        ZWRITED(scc, c);
        !          1066:        splx(s);
        !          1067: }
        !          1068:
        !          1069: void
        !          1070: zscninit(cp)
        !          1071:        struct consdev *cp;
        !          1072: {
        !          1073:        int unit = 0;
        !          1074:        struct termios *tiop = &zscn_termios;
        !          1075:        volatile u_char *scc_cr, *scc_dr;
        !          1076:        struct sccregs *scc;
        !          1077:        int size;
        !          1078:
        !          1079:        zs_cons_unit = unit;
        !          1080:        zs_is_console = 1;
        !          1081:        zs_cons_scc = scc = &zs_cons_sccregs;
        !          1082:
        !          1083:        /*
        !          1084:         * the locations of the control and data register move around
        !          1085:         * on different MVME models, so we generate independent pointers
        !          1086:         * to them.
        !          1087:         */
        !          1088:        size = zsregs(0, unit, &scc_cr, &scc_dr);
        !          1089:
        !          1090:        *(scc_cr + size) = 0;
        !          1091:        *(scc_cr + size) = 9;
        !          1092:        *(scc_cr + size) = 0xC0;        /* hardware reset of SCC, both sides */
        !          1093:        if (!zsside(unit)) {
        !          1094:                scc_cr += size;
        !          1095:                scc_dr += size;
        !          1096:        }
        !          1097:
        !          1098:        scc->s_cr = scc_cr;
        !          1099:        scc->s_dr = scc_dr;
        !          1100: #if defined(MVME162) || defined(MVME172)
        !          1101:        if (cputyp == CPU_162 || cputyp == CPU_172)
        !          1102:                ZWRITE(scc, 2, MC_VECBASE+MCV_ZS);
        !          1103: #endif
        !          1104:        ZWRITE(scc, 10, 0);
        !          1105:        ZWRITE(scc, 11, 0x50);  /* rx & tx clock = brgen */
        !          1106:        ZWRITE(scc, 14, 3);     /* brgen enabled, from pclk */
        !          1107:        zs_cons_imask = zscc_params(scc, tiop);
        !          1108:        ZBIS(scc, 5, 0x82);     /* set DTR and RTS */
        !          1109:
        !          1110:        zs_cons_termios = *tiop;/* save for later */
        !          1111: }
        !          1112:
        !          1113: #ifdef MVME147
        !          1114: u_long zs_cons_addrs_147[] = { ZS0_PHYS_147, ZS1_PHYS_147};
        !          1115: #endif
        !          1116: #if defined(MVME162) || defined(MVME172)
        !          1117: u_long zs_cons_addrs_162[] = { ZS0_PHYS_162, ZS1_PHYS_162};
        !          1118: #endif
        !          1119:
        !          1120: /*
        !          1121:  * fills in pointers to the registers and returns how far apart
        !          1122:  * the two halves of the chip are.
        !          1123:  *
        !          1124:  * it vaddr == NULL, it tries to determine the hardware address in
        !          1125:  * an intelligent fashion from the unit number.
        !          1126:  */
        !          1127: int
        !          1128: zsregs(va, unit, crp, drp)
        !          1129:        vaddr_t va;
        !          1130:        int unit;
        !          1131:        volatile u_char **crp, **drp;
        !          1132: {
        !          1133: #ifdef MVME147
        !          1134:        volatile struct scc_147 *scc_adr_147;
        !          1135: #endif
        !          1136: #if defined(MVME162) || defined(MVME172)
        !          1137:        volatile struct scc_162 *scc_adr_162;
        !          1138: #endif
        !          1139:        volatile u_char *scc_cr, *scc_dr;
        !          1140:        int size;
        !          1141:
        !          1142:        switch (cputyp) {
        !          1143: #ifdef MVME147
        !          1144:                case CPU_147:
        !          1145:                        if (va == 0)
        !          1146:                                va = IIOV(zs_cons_addrs_147[unit]);
        !          1147:                        scc_adr_147 = (volatile struct scc_147 *)va;
        !          1148:                        scc_cr = &scc_adr_147->cr;
        !          1149:                        scc_dr = &scc_adr_147->dr;
        !          1150:                        size = sizeof(struct scc_147);
        !          1151:                        break;
        !          1152: #endif
        !          1153: #if defined(MVME162) || defined(MVME172)
        !          1154:                case CPU_162:
        !          1155:                case CPU_172:
        !          1156:                        if (va == 0)
        !          1157:                                va = IIOV(zs_cons_addrs_162[unit]);
        !          1158:                        scc_adr_162 = (volatile struct scc_162 *)va;
        !          1159:                        scc_cr = &scc_adr_162->cr;
        !          1160:                        scc_dr = &scc_adr_162->dr;
        !          1161:                        size = sizeof(struct scc_162);
        !          1162:                        break;
        !          1163: #endif
        !          1164:        }
        !          1165:
        !          1166:        *crp = scc_cr;
        !          1167:        *drp = scc_dr;
        !          1168:        return (size);
        !          1169: }
        !          1170:
        !          1171: int
        !          1172: zspclk()
        !          1173: {
        !          1174:        switch (cputyp) {
        !          1175: #ifdef MVME147
        !          1176:                case CPU_147:
        !          1177:                        return (PCLK_FREQ_147);
        !          1178: #endif
        !          1179: #if defined(MVME162) || defined(MVME172)
        !          1180:                case CPU_162:
        !          1181:                case CPU_172:
        !          1182:                        return (PCLK_FREQ_162);
        !          1183: #endif
        !          1184:                default:
        !          1185:                        return 0;
        !          1186:        }
        !          1187: }

CVSweb